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