MagickWand  7.0.8
Convert, Edit, Or Compose Bitmap Images
wandcli.c
Go to the documentation of this file.
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % W W AA N N DDD CCC L III %
7 % W W A A NN N D D C L I %
8 % W W W AAAA N N N D D C L I %
9 % W W W A A N NN D D C L I %
10 % W W A A N N DDD CCC LLLL III %
11 % %
12 % WandCLI Structure Methods %
13 % %
14 % Dragon Computing %
15 % Anthony Thyssen %
16 % April 2011 %
17 % %
18 % Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization %
19 % dedicated to making software imaging solutions freely available. %
20 % %
21 % You may not use this file except in compliance with the License. You may %
22 % obtain a copy of the License at %
23 % %
24 % https://imagemagick.org/script/license.php %
25 % %
26 % Unless required by applicable law or agreed to in writing, software %
27 % distributed under the License is distributed on an "AS IS" BASIS, %
28 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
29 % See the License for the specific language governing permissions and %
30 % limitations under the License. %
31 % %
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33 %
34 % General methds for handling the WandCLI structure used for Command Line.
35 %
36 % Anthony Thyssen, April 2011
37 */
38 
39 /*
40  Include declarations.
41 */
42 #include "MagickWand/studio.h"
43 #include "MagickWand/MagickWand.h"
44 #include "MagickWand/wand.h"
46 #include "MagickWand/wandcli.h"
48 #include "MagickCore/exception.h"
49 
50 /*
51 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 % %
53 % %
54 % %
55 + A c q u i r e W a n d C L I %
56 % %
57 % %
58 % %
59 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60 %
61 % AcquireMagickCLI() creates a new CLI wand (an expanded form of Magick
62 % Wand). The given image_info and exception is included as is if provided.
63 %
64 % Use DestroyMagickCLI() to dispose of the CLI wand when it is no longer
65 % needed.
66 %
67 % The format of the NewMagickWand method is:
68 %
69 % MagickCLI *AcquireMagickCLI(ImageInfo *image_info,
70 % ExceptionInfo *exception)
71 %
72 */
74  ExceptionInfo *exception)
75 {
76  MagickCLI
77  *cli_wand;
78 
79  /* precaution - as per NewMagickWand() */
80  {
81  size_t depth = MAGICKCORE_QUANTUM_DEPTH;
82  const char *quantum = GetMagickQuantumDepth(&depth);
83  if (depth != MAGICKCORE_QUANTUM_DEPTH)
84  ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
85  }
86 
87  /* allocate memory for MgaickCLI */
88  cli_wand=(MagickCLI *) AcquireMagickMemory(sizeof(*cli_wand));
89  if (cli_wand == (MagickCLI *) NULL)
90  ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
91  GetExceptionMessage(errno));
92 
93  /* Initialize Wand Part of MagickCLI
94  FUTURE: this is a repeat of code from NewMagickWand()
95  However some parts may be given fro man external source!
96  */
97  cli_wand->wand.id=AcquireWandId();
98  (void) FormatLocaleString(cli_wand->wand.name,MagickPathExtent,
99  "%s-%.20g","MagickWandCLI", (double) cli_wand->wand.id);
100  cli_wand->wand.images=NewImageList();
101  if ( image_info == (ImageInfo *) NULL)
102  cli_wand->wand.image_info=AcquireImageInfo();
103  else
104  cli_wand->wand.image_info=image_info;
105  if ( exception == (ExceptionInfo *) NULL)
106  cli_wand->wand.exception=AcquireExceptionInfo();
107  else
108  cli_wand->wand.exception=exception;
109  cli_wand->wand.debug=IsEventLogging();
111 
112  /* Initialize CLI Part of MagickCLI */
113  cli_wand->draw_info=CloneDrawInfo(cli_wand->wand.image_info,(DrawInfo *) NULL);
114  cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
115  cli_wand->process_flags=MagickCommandOptionFlags; /* assume "magick" CLI */
116  cli_wand->command=(const OptionInfo *) NULL; /* no option at this time */
117  cli_wand->image_list_stack=(Stack *) NULL;
118  cli_wand->image_info_stack=(Stack *) NULL;
119 
120  /* default exception location...
121  EG: sprintf(locaiton, filename, line, column);
122  */
123  cli_wand->location="from \"%s\""; /* location format using arguments: */
124  /* filename, line, column */
125  cli_wand->filename="unknown"; /* script filename, unknown source */
126  cli_wand->line=0; /* line from script OR CLI argument */
127  cli_wand->column=0; /* column from script */
128 
129  cli_wand->signature=MagickWandSignature;
130  if (cli_wand->wand.debug != MagickFalse)
131  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
132  return(cli_wand);
133 }
134 
135 /*
136 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
137 % %
138 % %
139 % %
140 + D e s t r o y W a n d C L I %
141 % %
142 % %
143 % %
144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
145 %
146 % DestroyMagickCLI() destorys everything in a CLI wand, including image_info
147 % and any exceptions, if still present in the wand.
148 %
149 % The format of the NewMagickWand method is:
150 %
151 % MagickWand *DestroyMagickCLI()
152 % Exception *exception)
153 %
154 */
156 {
157  Stack
158  *node;
159 
160  assert(cli_wand != (MagickCLI *) NULL);
161  assert(cli_wand->signature == MagickWandSignature);
162  assert(cli_wand->wand.signature == MagickWandSignature);
163  if (cli_wand->wand.debug != MagickFalse)
164  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
165 
166  /* Destroy CLI part of MagickCLI */
167  if (cli_wand->draw_info != (DrawInfo *) NULL )
168  cli_wand->draw_info=DestroyDrawInfo(cli_wand->draw_info);
169  if (cli_wand->quantize_info != (QuantizeInfo *) NULL )
170  cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
171  while(cli_wand->image_list_stack != (Stack *) NULL)
172  {
173  node=cli_wand->image_list_stack;
174  cli_wand->image_list_stack=node->next;
175  (void) DestroyImageList((Image *)node->data);
176  (void) RelinquishMagickMemory(node);
177  }
178  while(cli_wand->image_info_stack != (Stack *) NULL)
179  {
180  node=cli_wand->image_info_stack;
181  cli_wand->image_info_stack=node->next;
182  (void) DestroyImageInfo((ImageInfo *)node->data);
183  (void) RelinquishMagickMemory(node);
184  }
185  cli_wand->signature=(~MagickWandSignature);
186 
187  /* Destroy Wand part MagickCLI */
188  cli_wand->wand.images=DestroyImageList(cli_wand->wand.images);
189  if (cli_wand->wand.image_info != (ImageInfo *) NULL )
190  cli_wand->wand.image_info=DestroyImageInfo(cli_wand->wand.image_info);
191  if (cli_wand->wand.exception != (ExceptionInfo *) NULL )
192  cli_wand->wand.exception=DestroyExceptionInfo(cli_wand->wand.exception);
193  RelinquishWandId(cli_wand->wand.id);
194  cli_wand->wand.signature=(~MagickWandSignature);
195  cli_wand=(MagickCLI *) RelinquishMagickMemory(cli_wand);
196  return((MagickCLI *) NULL);
197 }
198 
199 /*
200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
201 % %
202 % %
203 % %
204 + C L I C a t c h E x c e p t i o n %
205 % %
206 % %
207 % %
208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
209 %
210 % CLICatchException() will report exceptions, either just non-fatal warnings
211 % only, or all errors, according to 'all_execeptions' boolean argument.
212 %
213 % The function returns true if errors are fatal, in which case the caller
214 % should abort and re-call with an 'all_exceptions' argument of true before
215 % quitting.
216 %
217 % The cut-off level between fatal and non-fatal may be controlled by options
218 % (FUTURE), but defaults to 'Error' exceptions.
219 %
220 % The format of the CLICatchException method is:
221 %
222 % MagickBooleanType CLICatchException(MagickCLI *cli_wand,
223 % const MagickBooleanType all_exceptions );
224 %
225 % Arguments are
226 %
227 % o cli_wand: The Wand CLI that holds the exception Information
228 %
229 % o all_exceptions: Report all exceptions, including the fatal one
230 %
231 */
232 WandExport MagickBooleanType CLICatchException(MagickCLI *cli_wand,
233  const MagickBooleanType all_exceptions)
234 {
235  MagickBooleanType
236  status;
237 
238  assert(cli_wand != (MagickCLI *) NULL);
239  assert(cli_wand->signature == MagickWandSignature);
240  assert(cli_wand->wand.signature == MagickWandSignature);
241  if (cli_wand->wand.debug != MagickFalse)
242  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
243 
244  /*
245  FUTURE: '-regard_warning' should make this more sensitive.
246  Note pipelined options may like more control over this level
247  */
248 
249  status=cli_wand->wand.exception->severity > ErrorException ? MagickTrue :
250  MagickFalse;
251 
252  if ((status == MagickFalse) || (all_exceptions != MagickFalse))
253  CatchException(cli_wand->wand.exception); /* output and clear exceptions */
254 
255  return(status);
256 }
257 
258 /*
259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
260 % %
261 % %
262 % %
263 + C L I L o g E v e n t %
264 % %
265 % %
266 % %
267 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
268 %
269 % CLILogEvent() is a wrapper around LogMagickEvent(), adding to it the
270 % location of the option that is (about) to be executed.
271 %
272 */
273 WandExport MagickBooleanType CLILogEvent(MagickCLI *cli_wand,
274  const LogEventType type,const char *module,const char *function,
275  const size_t line,const char *format,...)
276 {
277  char
278  new_format[MagickPathExtent];
279 
280  MagickBooleanType
281  status;
282 
283  va_list
284  operands;
285 
286  if (IsEventLogging() == MagickFalse)
287  return(MagickFalse);
288 
289  /* HACK - prepend the CLI location to format string.
290  The better way would be add more arguments to to the 'va' oparands
291  list, but that does not appear to be possible! So we do some
292  pre-formating of the location info here.
293  */
294  (void) FormatLocaleString(new_format,MagickPathExtent,cli_wand->location,
295  cli_wand->filename, cli_wand->line, cli_wand->column);
296  (void) ConcatenateMagickString(new_format," ",MagickPathExtent);
297  (void) ConcatenateMagickString(new_format,format,MagickPathExtent);
298 
299  va_start(operands,format);
300  status=LogMagickEventList(type,module,function,line,new_format,operands);
301  va_end(operands);
302 
303  return(status);
304 }
305 
306 /*
307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
308 % %
309 % %
310 % %
311 + C L I T h r o w E x c e p t i o n %
312 % %
313 % %
314 % %
315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
316 %
317 % CLIThrowException() is a wrapper around ThrowMagickException(), adding to
318 % it the location of the option that caused the exception to occur.
319 */
320 WandExport MagickBooleanType CLIThrowException(MagickCLI *cli_wand,
321  const char *module,const char *function,const size_t line,
322  const ExceptionType severity,const char *tag,const char *format,...)
323 {
324  char
325  new_format[MagickPathExtent];
326 
327  size_t
328  len;
329 
330  MagickBooleanType
331  status;
332 
333  va_list
334  operands;
335 
336  /* HACK - append location to format string.
337  The better way would be add more arguments to to the 'va' oparands
338  list, but that does not appear to be possible! So we do some
339  pre-formating of the location info here.
340  */
341  (void) CopyMagickString(new_format,format,MagickPathExtent);
342  (void) ConcatenateMagickString(new_format," ",MagickPathExtent);
343 
344  len=strlen(new_format);
345  (void) FormatLocaleString(new_format+len,MagickPathExtent-len,
346  cli_wand->location,cli_wand->filename,cli_wand->line,cli_wand->column);
347 
348  va_start(operands,format);
349  status=ThrowMagickExceptionList(cli_wand->wand.exception,module,function,
350  line,severity,tag,new_format,operands);
351  va_end(operands);
352  return(status);
353 }
#define ThrowWandFatalException(severity, tag, context)
const char * location
QuantizeInfo * quantize_info
#define MagickWandSignature
WandExport size_t AcquireWandId(void)
Definition: wand.c:74
#define WandExport
WandExport MagickBooleanType CLICatchException(MagickCLI *cli_wand, const MagickBooleanType all_exceptions)
Definition: wandcli.c:232
WandExport void RelinquishWandId(const size_t id)
Definition: wand.c:150
MagickBooleanType debug
struct _MagickWand wand
WandExport MagickCLI * DestroyMagickCLI(MagickCLI *cli_wand)
Definition: wandcli.c:155
#define MagickPathExtent
size_t signature
Stack * image_info_stack
const OptionInfo * command
ImageInfo * image_info
char name[MagickPathExtent]
DrawInfo * draw_info
WandExport MagickBooleanType CLIThrowException(MagickCLI *cli_wand, const char *module, const char *function, const size_t line, const ExceptionType severity, const char *tag, const char *format,...)
Definition: wandcli.c:320
void * data
ProcessOptionFlags process_flags
struct _Stack * next
WandExport MagickBooleanType CLILogEvent(MagickCLI *cli_wand, const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition: wandcli.c:273
const char * filename
Stack * image_list_stack
ExceptionInfo * exception
WandExport MagickCLI * AcquireMagickCLI(ImageInfo *image_info, ExceptionInfo *exception)
Definition: wandcli.c:73