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