1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                 M   M   AAA    GGGG  IIIII   CCCC  K   K                    %
7 %                 MM MM  A   A  G        I    C      K  K                     %
8 %                 M M M  AAAAA  G GGG    I    C      KKK                      %
9 %                 M   M  A   A  G   G    I    C      K  K                     %
10 %                 M   M  A   A   GGGG  IIIII   CCCC  K   K                    %
11 %                                                                             %
12 %                        W   W   AAA   N   N  DDDD                            %
13 %                        W   W  A   A  NN  N  D   D                           %
14 %                        W W W  AAAAA  N N N  D   D                           %
15 %                        WW WW  A   A  N  NN  D   D                           %
16 %                        W   W  A   A  N   N  DDDD                            %
17 %                                                                             %
18 %                                                                             %
19 %                           MagickWand Wand Methods                           %
20 %                                                                             %
21 %                               Software Design                               %
22 %                                    Cristy                                   %
23 %                                 August 2003                                 %
24 %                                                                             %
25 %                                                                             %
26 %  Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization      %
27 %  dedicated to making software imaging solutions freely available.           %
28 %                                                                             %
29 %  You may not use this file except in compliance with the License.  You may  %
30 %  obtain a copy of the License at                                            %
31 %                                                                             %
32 %    https://imagemagick.org/script/license.php                               %
33 %                                                                             %
34 %  Unless required by applicable law or agreed to in writing, software        %
35 %  distributed under the License is distributed on an "AS IS" BASIS,          %
36 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
37 %  See the License for the specific language governing permissions and        %
38 %  limitations under the License.                                             %
39 %                                                                             %
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 %
42 %
43 %
44 */
45 
46 /*
47   Include declarations.
48 */
49 #include "wand/studio.h"
50 #include "wand/MagickWand.h"
51 #include "wand/magick-wand-private.h"
52 #include "wand/wand.h"
53 
54 /*
55 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
56 %                                                                             %
57 %                                                                             %
58 %                                                                             %
59 %   C l e a r M a g i c k W a n d                                             %
60 %                                                                             %
61 %                                                                             %
62 %                                                                             %
63 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64 %
65 %  ClearMagickWand() clears resources associated with the wand, leaving the
66 %  wand blank, and ready to be used for a new set of images.
67 %
68 %  The format of the ClearMagickWand method is:
69 %
70 %      void ClearMagickWand(MagickWand *wand)
71 %
72 %  A description of each parameter follows:
73 %
74 %    o wand: the magick wand.
75 %
76 */
ClearMagickWand(MagickWand * wand)77 WandExport void ClearMagickWand(MagickWand *wand)
78 {
79   assert(wand != (MagickWand *) NULL);
80   assert(wand->signature == WandSignature);
81   if (wand->debug != MagickFalse)
82     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
83   wand->quantize_info=DestroyQuantizeInfo(wand->quantize_info);
84   wand->image_info=DestroyImageInfo(wand->image_info);
85   wand->images=DestroyImageList(wand->images);
86   wand->image_info=AcquireImageInfo();
87   wand->quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL);
88   wand->insert_before=MagickFalse;
89   wand->image_pending=MagickFalse;
90   ClearMagickException(wand->exception);
91   wand->debug=IsEventLogging();
92 }
93 
94 /*
95 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
96 %                                                                             %
97 %                                                                             %
98 %                                                                             %
99 %   C l o n e M a g i c k W a n d                                             %
100 %                                                                             %
101 %                                                                             %
102 %                                                                             %
103 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
104 %
105 %  CloneMagickWand() makes an exact copy of the specified wand.
106 %
107 %  The format of the CloneMagickWand method is:
108 %
109 %      MagickWand *CloneMagickWand(const MagickWand *wand)
110 %
111 %  A description of each parameter follows:
112 %
113 %    o wand: the magick wand.
114 %
115 */
CloneMagickWand(const MagickWand * wand)116 WandExport MagickWand *CloneMagickWand(const MagickWand *wand)
117 {
118   MagickWand
119     *clone_wand;
120 
121   assert(wand != (MagickWand *) NULL);
122   assert(wand->signature == WandSignature);
123   if (wand->debug != MagickFalse)
124     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
125   clone_wand=(MagickWand *) AcquireCriticalMemory(sizeof(*clone_wand));
126   (void) memset(clone_wand,0,sizeof(*clone_wand));
127   clone_wand->id=AcquireWandId();
128   (void) FormatLocaleString(clone_wand->name,MaxTextExtent,"%s-%.20g",
129     MagickWandId,(double) clone_wand->id);
130   clone_wand->exception=AcquireExceptionInfo();
131   InheritException(clone_wand->exception,wand->exception);
132   clone_wand->image_info=CloneImageInfo(wand->image_info);
133   clone_wand->quantize_info=CloneQuantizeInfo(wand->quantize_info);
134   clone_wand->images=CloneImageList(wand->images,clone_wand->exception);
135   clone_wand->insert_before=MagickFalse;
136   clone_wand->image_pending=MagickFalse;
137   clone_wand->debug=IsEventLogging();
138   if (clone_wand->debug != MagickFalse)
139     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clone_wand->name);
140   clone_wand->signature=WandSignature;
141   return(clone_wand);
142 }
143 
144 /*
145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146 %                                                                             %
147 %                                                                             %
148 %                                                                             %
149 %   D e s t r o y M a g i c k W a n d                                         %
150 %                                                                             %
151 %                                                                             %
152 %                                                                             %
153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
154 %
155 %  DestroyMagickWand() deallocates memory associated with an MagickWand.
156 %
157 %  The format of the DestroyMagickWand method is:
158 %
159 %      MagickWand *DestroyMagickWand(MagickWand *wand)
160 %
161 %  A description of each parameter follows:
162 %
163 %    o wand: the magick wand.
164 %
165 */
DestroyMagickWand(MagickWand * wand)166 WandExport MagickWand *DestroyMagickWand(MagickWand *wand)
167 {
168   assert(wand != (MagickWand *) NULL);
169   assert(wand->signature == WandSignature);
170   if (wand->debug != MagickFalse)
171     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
172   wand->images=DestroyImageList(wand->images);
173   if (wand->quantize_info != (QuantizeInfo *) NULL )
174     wand->quantize_info=DestroyQuantizeInfo(wand->quantize_info);
175   if (wand->image_info != (ImageInfo *) NULL )
176     wand->image_info=DestroyImageInfo(wand->image_info);
177   if (wand->exception != (ExceptionInfo *) NULL )
178     wand->exception=DestroyExceptionInfo(wand->exception);
179   RelinquishWandId(wand->id);
180   wand->signature=(~WandSignature);
181   wand=(MagickWand *) RelinquishMagickMemory(wand);
182   return(wand);
183 }
184 
185 /*
186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
187 %                                                                             %
188 %                                                                             %
189 %                                                                             %
190 %   I s M a g i c k W a n d                                                   %
191 %                                                                             %
192 %                                                                             %
193 %                                                                             %
194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
195 %
196 %  IsMagickWand() returns MagickTrue if the wand is verified as a magick wand.
197 %
198 %  The format of the IsMagickWand method is:
199 %
200 %      MagickBooleanType IsMagickWand(const MagickWand *wand)
201 %
202 %  A description of each parameter follows:
203 %
204 %    o wand: the magick wand.
205 %
206 */
IsMagickWand(const MagickWand * wand)207 WandExport MagickBooleanType IsMagickWand(const MagickWand *wand)
208 {
209   if (wand == (const MagickWand *) NULL)
210     return(MagickFalse);
211   if (wand->signature != WandSignature)
212     return(MagickFalse);
213   if (LocaleNCompare(wand->name,MagickWandId,strlen(MagickWandId)) != 0)
214     return(MagickFalse);
215   return(MagickTrue);
216 }
217 
218 /*
219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
220 %                                                                             %
221 %                                                                             %
222 %                                                                             %
223 %   M a g i c k C l e a r E x c e p t i o n                                   %
224 %                                                                             %
225 %                                                                             %
226 %                                                                             %
227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
228 %
229 %  MagickClearException() clears any exceptions associated with the wand.
230 %
231 %  The format of the MagickClearException method is:
232 %
233 %      MagickBooleanType MagickClearException(MagickWand *wand)
234 %
235 %  A description of each parameter follows:
236 %
237 %    o wand: the magick wand.
238 %
239 */
MagickClearException(MagickWand * wand)240 WandExport MagickBooleanType MagickClearException(MagickWand *wand)
241 {
242   assert(wand != (MagickWand *) NULL);
243   assert(wand->signature == WandSignature);
244   if (wand->debug != MagickFalse)
245     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
246   ClearMagickException(wand->exception);
247   return(MagickTrue);
248 }
249 
250 /*
251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252 %                                                                             %
253 %                                                                             %
254 %                                                                             %
255 %   M a g i c k G e t E x c e p t i o n                                       %
256 %                                                                             %
257 %                                                                             %
258 %                                                                             %
259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
260 %
261 %  MagickGetException() returns the severity, reason, and description of any
262 %  error that occurs when using other methods in this API.
263 %
264 %  The format of the MagickGetException method is:
265 %
266 %      char *MagickGetException(const MagickWand *wand,ExceptionType *severity)
267 %
268 %  A description of each parameter follows:
269 %
270 %    o wand: the magick wand.
271 %
272 %    o severity: the severity of the error is returned here.
273 %
274 */
MagickGetException(const MagickWand * wand,ExceptionType * severity)275 WandExport char *MagickGetException(const MagickWand *wand,
276   ExceptionType *severity)
277 {
278   char
279     *description;
280 
281   assert(wand != (const MagickWand *) NULL);
282   assert(wand->signature == WandSignature);
283   if (wand->debug != MagickFalse)
284     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
285   assert(severity != (ExceptionType *) NULL);
286   *severity=wand->exception->severity;
287   description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
288     sizeof(*description));
289   if (description == (char *) NULL)
290     {
291       (void) ThrowMagickException(wand->exception,GetMagickModule(),WandError,
292         "MemoryAllocationFailed","`%s'",wand->name);
293       return((char *) NULL);
294     }
295   *description='\0';
296   if (wand->exception->reason != (char *) NULL)
297     (void) CopyMagickString(description,GetLocaleExceptionMessage(
298       wand->exception->severity,wand->exception->reason),MaxTextExtent);
299   if (wand->exception->description != (char *) NULL)
300     {
301       (void) ConcatenateMagickString(description," (",MaxTextExtent);
302       (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
303         wand->exception->severity,wand->exception->description),MaxTextExtent);
304       (void) ConcatenateMagickString(description,")",MaxTextExtent);
305     }
306   return(description);
307 }
308 
309 /*
310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311 %                                                                             %
312 %                                                                             %
313 %                                                                             %
314 %   M a g i c k G e t E x c e p t i o n T y p e                               %
315 %                                                                             %
316 %                                                                             %
317 %                                                                             %
318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
319 %
320 %  MagickGetExceptionType() returns the exception type associated with the
321 %  wand.  If no exception has occurred, UndefinedExceptionType is returned.
322 %
323 %  The format of the MagickGetExceptionType method is:
324 %
325 %      ExceptionType MagickGetExceptionType(const MagickWand *wand)
326 %
327 %  A description of each parameter follows:
328 %
329 %    o wand: the magick wand.
330 %
331 */
MagickGetExceptionType(const MagickWand * wand)332 WandExport ExceptionType MagickGetExceptionType(const MagickWand *wand)
333 {
334   assert(wand != (MagickWand *) NULL);
335   assert(wand->signature == WandSignature);
336   if (wand->debug != MagickFalse)
337     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
338   return(wand->exception->severity);
339 }
340 
341 /*
342 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
343 %                                                                             %
344 %                                                                             %
345 %                                                                             %
346 %   M a g i c k G e t I t e r a t o r I n d e x                               %
347 %                                                                             %
348 %                                                                             %
349 %                                                                             %
350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
351 %
352 %  MagickGetIteratorIndex() returns the position of the iterator in the image
353 %  list.
354 %
355 %  The format of the MagickGetIteratorIndex method is:
356 %
357 %      ssize_t MagickGetIteratorIndex(MagickWand *wand)
358 %
359 %  A description of each parameter follows:
360 %
361 %    o wand: the magick wand.
362 %
363 */
MagickGetIteratorIndex(MagickWand * wand)364 WandExport ssize_t MagickGetIteratorIndex(MagickWand *wand)
365 {
366   assert(wand != (MagickWand *) NULL);
367   assert(wand->signature == WandSignature);
368   if (wand->debug != MagickFalse)
369     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
370   if (wand->images == (Image *) NULL)
371     {
372       (void) ThrowMagickException(wand->exception,GetMagickModule(),WandError,
373         "ContainsNoIterators","`%s'",wand->name);
374       return(-1);
375     }
376   return(GetImageIndexInList(wand->images));
377 }
378 
379 /*
380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
381 %                                                                             %
382 %                                                                             %
383 %                                                                             %
384 %   M a g i c k Q u e r y C o n f i g u r e O p t i o n                       %
385 %                                                                             %
386 %                                                                             %
387 %                                                                             %
388 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
389 %
390 %  MagickQueryConfigureOption() returns the value associated with the specified
391 %  configure option.
392 %
393 %  The format of the MagickQueryConfigureOption function is:
394 %
395 %      char *MagickQueryConfigureOption(const char *option)
396 %
397 %  A description of each parameter follows:
398 %
399 %    o option: the option name.
400 %
401 */
MagickQueryConfigureOption(const char * option)402 WandExport char *MagickQueryConfigureOption(const char *option)
403 {
404   char
405     *value;
406 
407   const ConfigureInfo
408     **configure_info;
409 
410   ExceptionInfo
411     *exception;
412 
413   size_t
414     number_options;
415 
416   exception=AcquireExceptionInfo();
417   configure_info=GetConfigureInfoList(option,&number_options,exception);
418   exception=DestroyExceptionInfo(exception);
419   if (configure_info == (const ConfigureInfo **) NULL)
420     return((char *) NULL);
421   value=(char *) NULL;
422   if (number_options != 0)
423     value=AcquireString(configure_info[0]->value);
424   configure_info=(const ConfigureInfo **)
425     RelinquishMagickMemory((void *) configure_info);
426   return(value);
427 }
428 
429 /*
430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
431 %                                                                             %
432 %                                                                             %
433 %                                                                             %
434 %   M a g i c k Q u e r y C o n f i g u r e O p t i o n s                     %
435 %                                                                             %
436 %                                                                             %
437 %                                                                             %
438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
439 %
440 %  MagickQueryConfigureOptions() returns any configure options that match the
441 %  specified pattern (e.g.  "*" for all).  Options include NAME, VERSION,
442 %  LIB_VERSION, etc.
443 %
444 %  The format of the MagickQueryConfigureOptions function is:
445 %
446 %      char **MagickQueryConfigureOptions(const char *pattern,
447 %        size_t *number_options)
448 %
449 %  A description of each parameter follows:
450 %
451 %    o pattern: Specifies a pointer to a text string containing a pattern.
452 %
453 %    o number_options:  Returns the number of configure options in the list.
454 %
455 %
456 */
MagickQueryConfigureOptions(const char * pattern,size_t * number_options)457 WandExport char **MagickQueryConfigureOptions(const char *pattern,
458   size_t *number_options)
459 {
460   char
461     **options;
462 
463   ExceptionInfo
464     *exception;
465 
466   exception=AcquireExceptionInfo();
467   options=GetConfigureList(pattern,number_options,exception);
468   exception=DestroyExceptionInfo(exception);
469   return(options);
470 }
471 
472 /*
473 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
474 %                                                                             %
475 %                                                                             %
476 %                                                                             %
477 %   M a g i c k Q u e r y F o n t M e t r i c s                               %
478 %                                                                             %
479 %                                                                             %
480 %                                                                             %
481 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
482 %
483 %  MagickQueryFontMetrics() returns a 13 element array representing the
484 %  following font metrics:
485 %
486 %    Element Description
487 %    -------------------------------------------------
488 %          0 character width
489 %          1 character height
490 %          2 ascender
491 %          3 descender
492 %          4 text width
493 %          5 text height
494 %          6 maximum horizontal advance
495 %          7 bounding box: x1
496 %          8 bounding box: y1
497 %          9 bounding box: x2
498 %         10 bounding box: y2
499 %         11 origin: x
500 %         12 origin: y
501 %
502 %  The format of the MagickQueryFontMetrics method is:
503 %
504 %      double *MagickQueryFontMetrics(MagickWand *wand,
505 %        const DrawingWand *drawing_wand,const char *text)
506 %
507 %  A description of each parameter follows:
508 %
509 %    o wand: the Magick wand.
510 %
511 %    o drawing_wand: the drawing wand.
512 %
513 %    o text: the text.
514 %
515 */
MagickQueryFontMetrics(MagickWand * wand,const DrawingWand * drawing_wand,const char * text)516 WandExport double *MagickQueryFontMetrics(MagickWand *wand,
517   const DrawingWand *drawing_wand,const char *text)
518 {
519   double
520     *font_metrics;
521 
522   DrawInfo
523     *draw_info;
524 
525   MagickBooleanType
526     status;
527 
528   TypeMetric
529     metrics;
530 
531   assert(wand != (MagickWand *) NULL);
532   assert(wand->signature == WandSignature);
533   if (wand->debug != MagickFalse)
534     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
535   assert(drawing_wand != (const DrawingWand *) NULL);
536   if (wand->images == (Image *) NULL)
537     {
538       (void) ThrowMagickException(wand->exception,GetMagickModule(),WandError,
539         "ContainsNoImages","`%s'",wand->name);
540       return((double *) NULL);
541     }
542   font_metrics=(double *) AcquireQuantumMemory(13UL,sizeof(*font_metrics));
543   if (font_metrics == (double *) NULL)
544     return((double *) NULL);
545   draw_info=PeekDrawingWand(drawing_wand);
546   if (draw_info == (DrawInfo *) NULL)
547     {
548       font_metrics=(double *) RelinquishMagickMemory(font_metrics);
549       return((double *) NULL);
550     }
551   (void) CloneString(&draw_info->text,text);
552   (void) memset(&metrics,0,sizeof(metrics));
553   status=GetTypeMetrics(wand->images,draw_info,&metrics);
554   draw_info=DestroyDrawInfo(draw_info);
555   if (status == MagickFalse)
556     {
557       InheritException(wand->exception,&wand->images->exception);
558       font_metrics=(double *) RelinquishMagickMemory(font_metrics);
559       return((double *) NULL);
560     }
561   font_metrics[0]=metrics.pixels_per_em.x;
562   font_metrics[1]=metrics.pixels_per_em.y;
563   font_metrics[2]=metrics.ascent;
564   font_metrics[3]=metrics.descent;
565   font_metrics[4]=metrics.width;
566   font_metrics[5]=metrics.height;
567   font_metrics[6]=metrics.max_advance;
568   font_metrics[7]=metrics.bounds.x1;
569   font_metrics[8]=metrics.bounds.y1;
570   font_metrics[9]=metrics.bounds.x2;
571   font_metrics[10]=metrics.bounds.y2;
572   font_metrics[11]=metrics.origin.x;
573   font_metrics[12]=metrics.origin.y;
574   return(font_metrics);
575 }
576 
577 /*
578 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
579 %                                                                             %
580 %                                                                             %
581 %                                                                             %
582 %   M a g i c k Q u e r y M u l t i l i n e F o n t M e t r i c s             %
583 %                                                                             %
584 %                                                                             %
585 %                                                                             %
586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
587 %
588 %  MagickQueryMultilineFontMetrics() returns a 13 element array representing the
589 %  following font metrics:
590 %
591 %    Element Description
592 %    -------------------------------------------------
593 %          0 character width
594 %          1 character height
595 %          2 ascender
596 %          3 descender
597 %          4 text width
598 %          5 text height
599 %          6 maximum horizontal advance
600 %          7 bounding box: x1
601 %          8 bounding box: y1
602 %          9 bounding box: x2
603 %         10 bounding box: y2
604 %         11 origin: x
605 %         12 origin: y
606 %
607 %  This method is like MagickQueryFontMetrics() but it returns the maximum text
608 %  width and height for multiple lines of text.
609 %
610 %  The format of the MagickQueryFontMetrics method is:
611 %
612 %      double *MagickQueryMultilineFontMetrics(MagickWand *wand,
613 %        const DrawingWand *drawing_wand,const char *text)
614 %
615 %  A description of each parameter follows:
616 %
617 %    o wand: the Magick wand.
618 %
619 %    o drawing_wand: the drawing wand.
620 %
621 %    o text: the text.
622 %
623 */
MagickQueryMultilineFontMetrics(MagickWand * wand,const DrawingWand * drawing_wand,const char * text)624 WandExport double *MagickQueryMultilineFontMetrics(MagickWand *wand,
625   const DrawingWand *drawing_wand,const char *text)
626 {
627   double
628     *font_metrics;
629 
630   DrawInfo
631     *draw_info;
632 
633   MagickBooleanType
634     status;
635 
636   TypeMetric
637     metrics;
638 
639   assert(wand != (MagickWand *) NULL);
640   assert(wand->signature == WandSignature);
641   if (wand->debug != MagickFalse)
642     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
643   assert(drawing_wand != (const DrawingWand *) NULL);
644   if (wand->images == (Image *) NULL)
645     {
646       (void) ThrowMagickException(wand->exception,GetMagickModule(),WandError,
647         "ContainsNoImages","`%s'",wand->name);
648       return((double *) NULL);
649     }
650   font_metrics=(double *) AcquireQuantumMemory(13UL,sizeof(*font_metrics));
651   if (font_metrics == (double *) NULL)
652     return((double *) NULL);
653   draw_info=PeekDrawingWand(drawing_wand);
654   if (draw_info == (DrawInfo *) NULL)
655     {
656       font_metrics=(double *) RelinquishMagickMemory(font_metrics);
657       return((double *) NULL);
658     }
659   (void) CloneString(&draw_info->text,text);
660   (void) memset(&metrics,0,sizeof(metrics));
661   status=GetMultilineTypeMetrics(wand->images,draw_info,&metrics);
662   draw_info=DestroyDrawInfo(draw_info);
663   if (status == MagickFalse)
664     {
665       InheritException(wand->exception,&wand->images->exception);
666       font_metrics=(double *) RelinquishMagickMemory(font_metrics);
667       return((double *) NULL);
668     }
669   font_metrics[0]=metrics.pixels_per_em.x;
670   font_metrics[1]=metrics.pixels_per_em.y;
671   font_metrics[2]=metrics.ascent;
672   font_metrics[3]=metrics.descent;
673   font_metrics[4]=metrics.width;
674   font_metrics[5]=metrics.height;
675   font_metrics[6]=metrics.max_advance;
676   font_metrics[7]=metrics.bounds.x1;
677   font_metrics[8]=metrics.bounds.y1;
678   font_metrics[9]=metrics.bounds.x2;
679   font_metrics[10]=metrics.bounds.y2;
680   font_metrics[11]=metrics.origin.x;
681   font_metrics[12]=metrics.origin.y;
682   return(font_metrics);
683 }
684 
685 /*
686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
687 %                                                                             %
688 %                                                                             %
689 %                                                                             %
690 %   M a g i c k Q u e r y F o n t s                                           %
691 %                                                                             %
692 %                                                                             %
693 %                                                                             %
694 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
695 %
696 %  MagickQueryFonts() returns any font that match the specified pattern (e.g.
697 %  "*" for all).
698 %
699 %  The format of the MagickQueryFonts function is:
700 %
701 %      char **MagickQueryFonts(const char *pattern,size_t *number_fonts)
702 %
703 %  A description of each parameter follows:
704 %
705 %    o pattern: Specifies a pointer to a text string containing a pattern.
706 %
707 %    o number_fonts:  Returns the number of fonts in the list.
708 %
709 %
710 */
MagickQueryFonts(const char * pattern,size_t * number_fonts)711 WandExport char **MagickQueryFonts(const char *pattern,
712   size_t *number_fonts)
713 {
714   char
715     **fonts;
716 
717   ExceptionInfo
718     *exception;
719 
720   exception=AcquireExceptionInfo();
721   fonts=GetTypeList(pattern,number_fonts,exception);
722   exception=DestroyExceptionInfo(exception);
723   return(fonts);
724 }
725 
726 /*
727 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
728 %                                                                             %
729 %                                                                             %
730 %                                                                             %
731 %   M a g i c k Q u e r y F o r m a t s                                       %
732 %                                                                             %
733 %                                                                             %
734 %                                                                             %
735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
736 %
737 %  MagickQueryFormats() returns any image formats that match the specified
738 %  pattern (e.g.  "*" for all).
739 %
740 %  The format of the MagickQueryFormats function is:
741 %
742 %      char **MagickQueryFormats(const char *pattern,size_t *number_formats)
743 %
744 %  A description of each parameter follows:
745 %
746 %    o pattern: Specifies a pointer to a text string containing a pattern.
747 %
748 %    o number_formats:  This integer returns the number of image formats in the
749 %      list.
750 %
751 */
MagickQueryFormats(const char * pattern,size_t * number_formats)752 WandExport char **MagickQueryFormats(const char *pattern,
753   size_t *number_formats)
754 {
755   char
756     **formats;
757 
758   ExceptionInfo
759     *exception;
760 
761   exception=AcquireExceptionInfo();
762   formats=GetMagickList(pattern,number_formats,exception);
763   exception=DestroyExceptionInfo(exception);
764   return(formats);
765 }
766 
767 /*
768 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
769 %                                                                             %
770 %                                                                             %
771 %                                                                             %
772 %   M a g i c k R e l i n q u i s h M e m o r y                               %
773 %                                                                             %
774 %                                                                             %
775 %                                                                             %
776 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
777 %
778 %  MagickRelinquishMemory() relinquishes memory resources returned by such
779 %  methods as MagickIdentifyImage(), MagickGetException(), etc.
780 %
781 %  The format of the MagickRelinquishMemory method is:
782 %
783 %      void *MagickRelinquishMemory(void *resource)
784 %
785 %  A description of each parameter follows:
786 %
787 %    o resource: Relinquish the memory associated with this resource.
788 %
789 */
MagickRelinquishMemory(void * memory)790 WandExport void *MagickRelinquishMemory(void *memory)
791 {
792   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
793   return(RelinquishMagickMemory(memory));
794 }
795 
796 /*
797 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
798 %                                                                             %
799 %                                                                             %
800 %                                                                             %
801 %   M a g i c k R e s e t I t e r a t o r                                     %
802 %                                                                             %
803 %                                                                             %
804 %                                                                             %
805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
806 %
807 %  MagickResetIterator() resets the wand iterator.
808 %
809 %  It is typically used either before iterating though images, or before
810 %  calling specific functions such as  MagickAppendImages() to append all
811 %  images together.
812 %
813 %  Afterward you can use MagickNextImage() to iterate over all the images
814 %  in a wand container, starting with the first image.
815 %
816 %  Using this before MagickAddImages() or MagickReadImages() will cause
817 %  new images to be inserted between the first and second image.
818 %
819 %  The format of the MagickResetIterator method is:
820 %
821 %      void MagickResetIterator(MagickWand *wand)
822 %
823 %  A description of each parameter follows:
824 %
825 %    o wand: the magick wand.
826 %
827 */
MagickResetIterator(MagickWand * wand)828 WandExport void MagickResetIterator(MagickWand *wand)
829 {
830   assert(wand != (MagickWand *) NULL);
831   assert(wand->signature == WandSignature);
832   if (wand->debug != MagickFalse)
833     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
834   wand->images=GetFirstImageInList(wand->images);
835   wand->insert_before=MagickFalse; /* Insert/add after current (first) image */
836   wand->image_pending=MagickTrue;  /* NextImage will set first image */
837 }
838 
839 /*
840 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
841 %                                                                             %
842 %                                                                             %
843 %                                                                             %
844 %   M a g i c k S e t F i r s t I t e r a t o r                               %
845 %                                                                             %
846 %                                                                             %
847 %                                                                             %
848 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
849 %
850 %  MagickSetFirstIterator() sets the wand iterator to the first image.
851 %
852 %  After using any images added to the wand using MagickAddImage() or
853 %  MagickReadImage() will be prepended before any image in the wand.
854 %
855 %  Also the current image has been set to the first image (if any) in the
856 %  Magick Wand.  Using MagickNextImage() will then set teh current image
857 %  to the second image in the list (if present).
858 %
859 %  This operation is similar to MagickResetIterator() but differs in how
860 %  MagickAddImage(), MagickReadImage(), and MagickNextImage() behaves
861 %  afterward.
862 %
863 %  The format of the MagickSetFirstIterator method is:
864 %
865 %      void MagickSetFirstIterator(MagickWand *wand)
866 %
867 %  A description of each parameter follows:
868 %
869 %    o wand: the magick wand.
870 %
871 */
MagickSetFirstIterator(MagickWand * wand)872 WandExport void MagickSetFirstIterator(MagickWand *wand)
873 {
874   assert(wand != (MagickWand *) NULL);
875   assert(wand->signature == WandSignature);
876   if (wand->debug != MagickFalse)
877     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
878   wand->images=GetFirstImageInList(wand->images);
879   wand->insert_before=MagickTrue;   /* Insert/add before the first image */
880   wand->image_pending=MagickFalse;  /* NextImage will set next image */
881 }
882 
883 /*
884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
885 %                                                                             %
886 %                                                                             %
887 %                                                                             %
888 %   M a g i c k S e t I t e r a t o r I n d e x                               %
889 %                                                                             %
890 %                                                                             %
891 %                                                                             %
892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
893 %
894 %  MagickSetIteratorIndex() set the iterator to the given position in the
895 %  image list specified with the index parameter.  A zero index will set
896 %  the first image as current, and so on.  Negative indexes can be used
897 %  to specify an image relative to the end of the images in the wand, with
898 %  -1 being the last image in the wand.
899 %
900 %  If the index is invalid (range too large for number of images in wand)
901 %  the function will return MagickFalse, but no 'exception' will be raised,
902 %  as it is not actually an error.  In that case the current image will not
903 %  change.
904 %
905 %  After using any images added to the wand using MagickAddImage() or
906 %  MagickReadImage() will be added after the image indexed, regardless
907 %  of if a zero (first image in list) or negative index (from end) is used.
908 %
909 %  Jumping to index 0 is similar to MagickResetIterator() but differs in how
910 %  MagickNextImage() behaves afterward.
911 %
912 %  The format of the MagickSetIteratorIndex method is:
913 %
914 %      MagickBooleanType MagickSetIteratorIndex(MagickWand *wand,
915 %        const ssize_t index)
916 %
917 %  A description of each parameter follows:
918 %
919 %    o wand: the magick wand.
920 %
921 %    o index: the scene number.
922 %
923 */
MagickSetIteratorIndex(MagickWand * wand,const ssize_t index)924 WandExport MagickBooleanType MagickSetIteratorIndex(MagickWand *wand,
925   const ssize_t index)
926 {
927   Image
928     *image;
929 
930   assert(wand != (MagickWand *) NULL);
931   assert(wand->signature == WandSignature);
932   if (wand->debug != MagickFalse)
933     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
934   if (wand->images == (Image *) NULL)
935     return(MagickFalse);
936   image=GetImageFromList(wand->images,index);
937   if (image == (Image *) NULL)
938     {
939       InheritException(wand->exception,&wand->images->exception);
940       return(MagickFalse);
941     }
942   wand->images=image;
943   wand->insert_before=MagickFalse;  /* Insert/Add after (this) image */
944   wand->image_pending=MagickFalse;  /* NextImage will set next image */
945   return(MagickTrue);
946 }
947 /*
948 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
949 %                                                                             %
950 %                                                                             %
951 %                                                                             %
952 %   M a g i c k S e t L a s t I t e r a t o r                                 %
953 %                                                                             %
954 %                                                                             %
955 %                                                                             %
956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
957 %
958 %  MagickSetLastIterator() sets the wand iterator to the last image.
959 %
960 %  The last image is actually the current image, and the next use of
961 %  MagickPreviousImage() will not change this allowing this function to be
962 %  used to iterate over the images in the reverse direction. In this sense it
963 %  is more like  MagickResetIterator() than MagickSetFirstIterator().
964 %
965 %  Typically this function is used before MagickAddImage(), MagickReadImage()
966 %  functions to ensure new images are appended to the very end of wand's image
967 %  list.
968 %
969 %  The format of the MagickSetLastIterator method is:
970 %
971 %      void MagickSetLastIterator(MagickWand *wand)
972 %
973 %  A description of each parameter follows:
974 %
975 %    o wand: the magick wand.
976 %
977 */
MagickSetLastIterator(MagickWand * wand)978 WandExport void MagickSetLastIterator(MagickWand *wand)
979 {
980   assert(wand != (MagickWand *) NULL);
981   assert(wand->signature == WandSignature);
982   if (wand->debug != MagickFalse)
983     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
984   wand->images=GetLastImageInList(wand->images);
985   wand->insert_before=MagickFalse;  /* Insert/add after current (last) image */
986   wand->image_pending=MagickTrue;   /* PreviousImage will return last image */
987 }
988 
989 /*
990 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
991 %                                                                             %
992 %                                                                             %
993 %                                                                             %
994 %   M a g i c k W a n d G e n e s i s                                         %
995 %                                                                             %
996 %                                                                             %
997 %                                                                             %
998 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
999 %
1000 %  MagickWandGenesis() initializes the MagickWand environment.
1001 %
1002 %  The format of the MagickWandGenesis method is:
1003 %
1004 %      void MagickWandGenesis(void)
1005 %
1006 */
MagickWandGenesis(void)1007 WandExport void MagickWandGenesis(void)
1008 {
1009   if (IsMagickCoreInstantiated() == MagickFalse)
1010     MagickCoreGenesis((char *) NULL,MagickFalse);
1011 }
1012 
1013 /*
1014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1015 %                                                                             %
1016 %                                                                             %
1017 %                                                                             %
1018 %   M a g i c k W a n d T e r m i n u s                                       %
1019 %                                                                             %
1020 %                                                                             %
1021 %                                                                             %
1022 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1023 %
1024 %  MagickWandTerminus() terminates the MagickWand environment.
1025 %
1026 %  The format of the MagickWandTerminus method is:
1027 %
1028 %      void MagickWandTerminus(void)
1029 %
1030 */
MagickWandTerminus(void)1031 WandExport void MagickWandTerminus(void)
1032 {
1033   DestroyWandIds();
1034   MagickCoreTerminus();
1035 }
1036 
1037 /*
1038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1039 %                                                                             %
1040 %                                                                             %
1041 %                                                                             %
1042 %   N e w M a g i c k W a n d                                                 %
1043 %                                                                             %
1044 %                                                                             %
1045 %                                                                             %
1046 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1047 %
1048 %  NewMagickWand() returns a wand required for all other methods in the API.
1049 %  A fatal exception is thrown if there is not enough memory to allocate the
1050 %  wand.   Use DestroyMagickWand() to dispose of the wand when it is no longer
1051 %  needed.
1052 %
1053 %  The format of the NewMagickWand method is:
1054 %
1055 %      MagickWand *NewMagickWand(void)
1056 %
1057 */
NewMagickWand(void)1058 WandExport MagickWand *NewMagickWand(void)
1059 {
1060   const char
1061     *quantum;
1062 
1063   MagickWand
1064     *wand;
1065 
1066   size_t
1067     depth;
1068 
1069   depth=MAGICKCORE_QUANTUM_DEPTH;
1070   quantum=GetMagickQuantumDepth(&depth);
1071   if (depth != MAGICKCORE_QUANTUM_DEPTH)
1072     ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
1073   wand=(MagickWand *) AcquireMagickMemory(sizeof(*wand));
1074   if (wand == (MagickWand *) NULL)
1075     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
1076       GetExceptionMessage(errno));
1077   (void) memset(wand,0,sizeof(*wand));
1078   wand->id=AcquireWandId();
1079   (void) FormatLocaleString(wand->name,MaxTextExtent,"%s-%.20g",MagickWandId,
1080     (double) wand->id);
1081   wand->images=NewImageList();
1082   wand->image_info=AcquireImageInfo();
1083   wand->exception=AcquireExceptionInfo();
1084   wand->quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL);
1085   wand->debug=IsEventLogging();
1086   if (wand->debug != MagickFalse)
1087     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1088   wand->signature=WandSignature;
1089   return(wand);
1090 }
1091 
1092 /*
1093 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1094 %                                                                             %
1095 %                                                                             %
1096 %                                                                             %
1097 %   N e w M a g i c k W a n d F r o m I m a g e                               %
1098 %                                                                             %
1099 %                                                                             %
1100 %                                                                             %
1101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1102 %
1103 %  NewMagickWandFromImage() returns a wand with an image.
1104 %
1105 %  The format of the NewMagickWandFromImage method is:
1106 %
1107 %      MagickWand *NewMagickWandFromImage(const Image *image)
1108 %
1109 %  A description of each parameter follows:
1110 %
1111 %    o image: the image.
1112 %
1113 */
NewMagickWandFromImage(const Image * image)1114 WandExport MagickWand *NewMagickWandFromImage(const Image *image)
1115 {
1116   MagickWand
1117     *wand;
1118 
1119   wand=NewMagickWand();
1120   wand->images=CloneImage(image,0,0,MagickTrue,wand->exception);
1121   return(wand);
1122 }
1123 
1124 /*
1125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1126 %                                                                             %
1127 %                                                                             %
1128 %                                                                             %
1129 %  I s M a g i c k W a n d I n s t a n t i a t e d                            %
1130 %                                                                             %
1131 %                                                                             %
1132 %                                                                             %
1133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1134 %
1135 %  IsMagickWandInstantiated() returns MagickTrue if the ImageMagick environment
1136 %  is currently instantiated--  that is, MagickWandGenesis() has been called but
1137 %  MagickWandTerminus() has not.
1138 %
1139 %  The format of the IsMagickWandInstantiated method is:
1140 %
1141 %      MagickBooleanType IsMagickWandInstantiated(void)
1142 %
1143 */
IsMagickWandInstantiated(void)1144 MagickExport MagickBooleanType IsMagickWandInstantiated(void)
1145 {
1146   return(IsMagickCoreInstantiated());
1147 }
1148