MagickWand 7.1.1
Convert, Edit, Or Compose Bitmap Images
Loading...
Searching...
No Matches
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*/
73WandExport MagickCLI *AcquireMagickCLI(ImageInfo *image_info,
74 ExceptionInfo *exception)
75{
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*/
139WandExport MagickCLI *DestroyMagickCLI(MagickCLI *cli_wand)
140{
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*/
216WandExport 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*/
257WandExport 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*/
305WandExport 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}