MagickWand  7.1.1-43
Convert, Edit, Or Compose Bitmap Images
wandcli.c
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 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 methods 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"
45 #include "MagickWand/magick-wand-private.h"
46 #include "MagickWand/wandcli.h"
47 #include "MagickWand/wandcli-private.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 */
73 WandExport MagickCLI *AcquireMagickCLI(ImageInfo *image_info,
74  ExceptionInfo *exception)
75 {
76  MagickCLI
77  *cli_wand;
78 
79  CheckMagickCoreCompatibility();
80  cli_wand=(MagickCLI *) AcquireCriticalMemory(sizeof(*cli_wand));
81  cli_wand->wand.id=AcquireWandId();
82  (void) FormatLocaleString(cli_wand->wand.name,MagickPathExtent,
83  "%s-%.20g","MagickWandCLI", (double) cli_wand->wand.id);
84  cli_wand->wand.images=NewImageList();
85  if ( image_info == (ImageInfo *) NULL)
86  cli_wand->wand.image_info=AcquireImageInfo();
87  else
88  cli_wand->wand.image_info=image_info;
89  if ( exception == (ExceptionInfo *) NULL)
90  cli_wand->wand.exception=AcquireExceptionInfo();
91  else
92  cli_wand->wand.exception=exception;
93  cli_wand->wand.debug=IsEventLogging();
94  cli_wand->wand.signature=MagickWandSignature;
95 
96  /* Initialize CLI Part of MagickCLI */
97  cli_wand->draw_info=CloneDrawInfo(cli_wand->wand.image_info,(DrawInfo *) NULL);
98  cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
99  cli_wand->process_flags=MagickCommandOptionFlags; /* assume "magick" CLI */
100  cli_wand->command=(const OptionInfo *) NULL; /* no option at this time */
101  cli_wand->image_list_stack=(CLIStack *) NULL;
102  cli_wand->image_info_stack=(CLIStack *) NULL;
103 
104  /* default exception location...
105  EG: sprintf(location, filename, line, column);
106  */
107  cli_wand->location="from \"%s\""; /* location format using arguments: */
108  /* filename, line, column */
109  cli_wand->filename="unknown"; /* script filename, unknown source */
110  cli_wand->line=0; /* line from script OR CLI argument */
111  cli_wand->column=0; /* column from script */
112 
113  cli_wand->signature=MagickWandSignature;
114  if (cli_wand->wand.debug != MagickFalse)
115  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
116  return(cli_wand);
117 }
118 
119 /*
120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121 % %
122 % %
123 % %
124 + D e s t r o y W a n d C L I %
125 % %
126 % %
127 % %
128 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
129 %
130 % DestroyMagickCLI() destroys everything in a CLI wand, including image_info
131 % and any exceptions, if still present in the wand.
132 %
133 % The format of the NewMagickWand method is:
134 %
135 % MagickWand *DestroyMagickCLI()
136 % Exception *exception)
137 %
138 */
139 WandExport MagickCLI *DestroyMagickCLI(MagickCLI *cli_wand)
140 {
141  CLIStack
142  *node;
143 
144  assert(cli_wand != (MagickCLI *) NULL);
145  assert(cli_wand->signature == MagickWandSignature);
146  assert(cli_wand->wand.signature == MagickWandSignature);
147  if (cli_wand->wand.debug != MagickFalse)
148  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
149 
150  /* Destroy CLI part of MagickCLI */
151  if (cli_wand->draw_info != (DrawInfo *) NULL )
152  cli_wand->draw_info=DestroyDrawInfo(cli_wand->draw_info);
153  if (cli_wand->quantize_info != (QuantizeInfo *) NULL )
154  cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
155  while(cli_wand->image_list_stack != (CLIStack *) NULL)
156  {
157  node=cli_wand->image_list_stack;
158  cli_wand->image_list_stack=node->next;
159  (void) DestroyImageList((Image *)node->data);
160  (void) RelinquishMagickMemory(node);
161  }
162  while(cli_wand->image_info_stack != (CLIStack *) NULL)
163  {
164  node=cli_wand->image_info_stack;
165  cli_wand->image_info_stack=node->next;
166  (void) DestroyImageInfo((ImageInfo *)node->data);
167  (void) RelinquishMagickMemory(node);
168  }
169  cli_wand->signature=(~MagickWandSignature);
170 
171  /* Destroy Wand part MagickCLI */
172  cli_wand->wand.images=DestroyImageList(cli_wand->wand.images);
173  if (cli_wand->wand.image_info != (ImageInfo *) NULL )
174  cli_wand->wand.image_info=DestroyImageInfo(cli_wand->wand.image_info);
175  if (cli_wand->wand.exception != (ExceptionInfo *) NULL )
176  cli_wand->wand.exception=DestroyExceptionInfo(cli_wand->wand.exception);
177  RelinquishWandId(cli_wand->wand.id);
178  cli_wand->wand.signature=(~MagickWandSignature);
179  cli_wand=(MagickCLI *) RelinquishMagickMemory(cli_wand);
180  return((MagickCLI *) NULL);
181 }
182 
183 /*
184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185 % %
186 % %
187 % %
188 + C L I C a t c h E x c e p t i o n %
189 % %
190 % %
191 % %
192 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
193 %
194 % CLICatchException() will report exceptions, either just non-fatal warnings
195 % only, or all errors, according to 'all_exceptions' boolean argument.
196 %
197 % The function returns true if errors are fatal, in which case the caller
198 % should abort and re-call with an 'all_exceptions' argument of true before
199 % quitting.
200 %
201 % The cut-off level between fatal and non-fatal may be controlled by options
202 % (FUTURE), but defaults to 'Error' exceptions.
203 %
204 % The format of the CLICatchException method is:
205 %
206 % MagickBooleanType CLICatchException(MagickCLI *cli_wand,
207 % const MagickBooleanType all_exceptions );
208 %
209 % Arguments are
210 %
211 % o cli_wand: The Wand CLI that holds the exception Information
212 %
213 % o all_exceptions: Report all exceptions, including the fatal one
214 %
215 */
216 WandExport MagickBooleanType CLICatchException(MagickCLI *cli_wand,
217  const MagickBooleanType all_exceptions)
218 {
219  MagickBooleanType
220  status;
221 
222  assert(cli_wand != (MagickCLI *) NULL);
223  assert(cli_wand->signature == MagickWandSignature);
224  assert(cli_wand->wand.signature == MagickWandSignature);
225  if (cli_wand->wand.debug != MagickFalse)
226  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
227 
228  /*
229  FUTURE: '-regard_warning' should make this more sensitive.
230  Note pipelined options may like more control over this level
231  */
232 
233  status=cli_wand->wand.exception->severity > ErrorException ? MagickTrue :
234  MagickFalse;
235 
236  if ((status == MagickFalse) || (all_exceptions != MagickFalse))
237  CatchException(cli_wand->wand.exception); /* output and clear exceptions */
238 
239  return(status);
240 }
241 
242 /*
243 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244 % %
245 % %
246 % %
247 + C L I L o g E v e n t %
248 % %
249 % %
250 % %
251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252 %
253 % CLILogEvent() is a wrapper around LogMagickEvent(), adding to it the
254 % location of the option that is (about) to be executed.
255 %
256 */
257 WandExport MagickBooleanType CLILogEvent(MagickCLI *cli_wand,
258  const LogEventType type,const char *magick_module,const char *function,
259  const size_t line,const char *format,...)
260 {
261  char
262  new_format[MagickPathExtent];
263 
264  MagickBooleanType
265  status;
266 
267  va_list
268  operands;
269 
270  if (IsEventLogging() == MagickFalse)
271  return(MagickFalse);
272 
273  /* HACK - prepend the CLI location to format string.
274  The better way would be add more arguments to the 'va' operands
275  list, but that does not appear to be possible! So we do some
276  pre-formatting of the location info here.
277  */
278  (void) FormatLocaleString(new_format,MagickPathExtent,cli_wand->location,
279  cli_wand->filename, cli_wand->line, cli_wand->column);
280  (void) ConcatenateMagickString(new_format," ",MagickPathExtent);
281  (void) ConcatenateMagickString(new_format,format,MagickPathExtent);
282 
283  va_start(operands,format);
284  status=LogMagickEventList(type,magick_module,function,line,new_format,
285  operands);
286  va_end(operands);
287 
288  return(status);
289 }
290 
291 /*
292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
293 % %
294 % %
295 % %
296 + C L I T h r o w E x c e p t i o n %
297 % %
298 % %
299 % %
300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
301 %
302 % CLIThrowException() is a wrapper around ThrowMagickException(), adding to
303 % it the location of the option that caused the exception to occur.
304 */
305 WandExport MagickBooleanType CLIThrowException(MagickCLI *cli_wand,
306  const char *magick_module,const char *function,const size_t line,
307  const ExceptionType severity,const char *tag,const char *format,...)
308 {
309  char
310  new_format[MagickPathExtent];
311 
312  size_t
313  len;
314 
315  MagickBooleanType
316  status;
317 
318  va_list
319  operands;
320 
321  /* HACK - append location to format string.
322  The better way would be add more arguments to the 'va' operands
323  list, but that does not appear to be possible! So we do some
324  pre-formatting of the location info here.
325  */
326  (void) CopyMagickString(new_format,format,MagickPathExtent);
327  (void) ConcatenateMagickString(new_format," ",MagickPathExtent);
328 
329  len=strlen(new_format);
330  (void) FormatLocaleString(new_format+len,MagickPathExtent-len,
331  cli_wand->location,cli_wand->filename,cli_wand->line,cli_wand->column);
332 
333  va_start(operands,format);
334  status=ThrowMagickExceptionList(cli_wand->wand.exception,magick_module,
335  function,line,severity,tag,new_format,operands);
336  va_end(operands);
337  return(status);
338 }
_CLIStack
Definition: wandcli-private.h:90
_MagickCLI
Definition: wandcli-private.h:101