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