MagickWand  7.0.7
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://www.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  // FUTURE: '-regard_warning' should make this more sensitive.
245  // Note pipelined options may like more control over this level
246 
247  status=cli_wand->wand.exception->severity > ErrorException ? MagickTrue :
248  MagickFalse;
249 
250  if ((status == MagickFalse) || (all_exceptions != MagickFalse))
251  CatchException(cli_wand->wand.exception); /* output and clear exceptions */
252 
253  return(status);
254 }
255 
256 /*
257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
258 % %
259 % %
260 % %
261 + C L I L o g E v e n t %
262 % %
263 % %
264 % %
265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
266 %
267 % CLILogEvent() is a wrapper around LogMagickEvent(), adding to it the
268 % location of the option that is (about) to be executed.
269 %
270 */
271 WandExport MagickBooleanType CLILogEvent(MagickCLI *cli_wand,
272  const LogEventType type,const char *module,const char *function,
273  const size_t line,const char *format,...)
274 {
275  char
276  new_format[MagickPathExtent];
277 
278  MagickBooleanType
279  status;
280 
281  va_list
282  operands;
283 
284  if (IsEventLogging() == MagickFalse)
285  return(MagickFalse);
286 
287  /* HACK - prepend the CLI location to format string.
288  The better way would be add more arguments to to the 'va' oparands
289  list, but that does not appear to be possible! So we do some
290  pre-formating of the location info here.
291  */
292  (void) FormatLocaleString(new_format,MagickPathExtent,cli_wand->location,
293  cli_wand->filename, cli_wand->line, cli_wand->column);
294  (void) ConcatenateMagickString(new_format," ",MagickPathExtent);
295  (void) ConcatenateMagickString(new_format,format,MagickPathExtent);
296 
297  va_start(operands,format);
298  status=LogMagickEventList(type,module,function,line,new_format,operands);
299  va_end(operands);
300 
301  return(status);
302 }
303 
304 /*
305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
306 % %
307 % %
308 % %
309 + C L I T h r o w E x c e p t i o n %
310 % %
311 % %
312 % %
313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
314 %
315 % CLIThrowException() is a wrapper around ThrowMagickException(), adding to
316 % it the location of the option that caused the exception to occur.
317 */
318 WandExport MagickBooleanType CLIThrowException(MagickCLI *cli_wand,
319  const char *module,const char *function,const size_t line,
320  const ExceptionType severity,const char *tag,const char *format,...)
321 {
322  char
323  new_format[MagickPathExtent];
324 
325  size_t
326  len;
327 
328  MagickBooleanType
329  status;
330 
331  va_list
332  operands;
333 
334  /* HACK - append location to format string.
335  The better way would be add more arguments to to the 'va' oparands
336  list, but that does not appear to be possible! So we do some
337  pre-formating of the location info here.
338  */
339  (void) CopyMagickString(new_format,format,MagickPathExtent);
340  (void) ConcatenateMagickString(new_format," ",MagickPathExtent);
341 
342  len=strlen(new_format);
343  (void) FormatLocaleString(new_format+len,MagickPathExtent-len,
344  cli_wand->location,cli_wand->filename,cli_wand->line,cli_wand->column);
345 
346  va_start(operands,format);
347  status=ThrowMagickExceptionList(cli_wand->wand.exception,module,function,
348  line,severity,tag,new_format,operands);
349  va_end(operands);
350  return(status);
351 }
#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:318
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:271
const char * filename
Stack * image_list_stack
ExceptionInfo * exception
WandExport MagickCLI * AcquireMagickCLI(ImageInfo *image_info, ExceptionInfo *exception)
Definition: wandcli.c:73