MagickWand  6.9.12-67
Convert, Edit, Or Compose Bitmap Images
 All Data Structures
magick-wand.c
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
790 WandExport void *MagickRelinquishMemory(void *memory)
791 {
792  if (IsEventLogging() != MagickFalse)
793  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
794  return(RelinquishMagickMemory(memory));
795 }
796 
797 /*
798 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
799 % %
800 % %
801 % %
802 % M a g i c k R e s e t I t e r a t o r %
803 % %
804 % %
805 % %
806 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
807 %
808 % MagickResetIterator() resets the wand iterator.
809 %
810 % It is typically used either before iterating though images, or before
811 % calling specific functions such as MagickAppendImages() to append all
812 % images together.
813 %
814 % Afterward you can use MagickNextImage() to iterate over all the images
815 % in a wand container, starting with the first image.
816 %
817 % Using this before MagickAddImages() or MagickReadImages() will cause
818 % new images to be inserted between the first and second image.
819 %
820 % The format of the MagickResetIterator method is:
821 %
822 % void MagickResetIterator(MagickWand *wand)
823 %
824 % A description of each parameter follows:
825 %
826 % o wand: the magick wand.
827 %
828 */
829 WandExport void MagickResetIterator(MagickWand *wand)
830 {
831  assert(wand != (MagickWand *) NULL);
832  assert(wand->signature == WandSignature);
833  if (wand->debug != MagickFalse)
834  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
835  wand->images=GetFirstImageInList(wand->images);
836  wand->insert_before=MagickFalse; /* Insert/add after current (first) image */
837  wand->image_pending=MagickTrue; /* NextImage will set first image */
838 }
839 
840 /*
841 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
842 % %
843 % %
844 % %
845 % M a g i c k S e t F i r s t I t e r a t o r %
846 % %
847 % %
848 % %
849 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
850 %
851 % MagickSetFirstIterator() sets the wand iterator to the first image.
852 %
853 % After using any images added to the wand using MagickAddImage() or
854 % MagickReadImage() will be prepended before any image in the wand.
855 %
856 % Also the current image has been set to the first image (if any) in the
857 % Magick Wand. Using MagickNextImage() will then set teh current image
858 % to the second image in the list (if present).
859 %
860 % This operation is similar to MagickResetIterator() but differs in how
861 % MagickAddImage(), MagickReadImage(), and MagickNextImage() behaves
862 % afterward.
863 %
864 % The format of the MagickSetFirstIterator method is:
865 %
866 % void MagickSetFirstIterator(MagickWand *wand)
867 %
868 % A description of each parameter follows:
869 %
870 % o wand: the magick wand.
871 %
872 */
873 WandExport void MagickSetFirstIterator(MagickWand *wand)
874 {
875  assert(wand != (MagickWand *) NULL);
876  assert(wand->signature == WandSignature);
877  if (wand->debug != MagickFalse)
878  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
879  wand->images=GetFirstImageInList(wand->images);
880  wand->insert_before=MagickTrue; /* Insert/add before the first image */
881  wand->image_pending=MagickFalse; /* NextImage will set next image */
882 }
883 
884 /*
885 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
886 % %
887 % %
888 % %
889 % M a g i c k S e t I t e r a t o r I n d e x %
890 % %
891 % %
892 % %
893 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
894 %
895 % MagickSetIteratorIndex() set the iterator to the given position in the
896 % image list specified with the index parameter. A zero index will set
897 % the first image as current, and so on. Negative indexes can be used
898 % to specify an image relative to the end of the images in the wand, with
899 % -1 being the last image in the wand.
900 %
901 % If the index is invalid (range too large for number of images in wand)
902 % the function will return MagickFalse, but no 'exception' will be raised,
903 % as it is not actually an error. In that case the current image will not
904 % change.
905 %
906 % After using any images added to the wand using MagickAddImage() or
907 % MagickReadImage() will be added after the image indexed, regardless
908 % of if a zero (first image in list) or negative index (from end) is used.
909 %
910 % Jumping to index 0 is similar to MagickResetIterator() but differs in how
911 % MagickNextImage() behaves afterward.
912 %
913 % The format of the MagickSetIteratorIndex method is:
914 %
915 % MagickBooleanType MagickSetIteratorIndex(MagickWand *wand,
916 % const ssize_t index)
917 %
918 % A description of each parameter follows:
919 %
920 % o wand: the magick wand.
921 %
922 % o index: the scene number.
923 %
924 */
925 WandExport MagickBooleanType MagickSetIteratorIndex(MagickWand *wand,
926  const ssize_t index)
927 {
928  Image
929  *image;
930 
931  assert(wand != (MagickWand *) NULL);
932  assert(wand->signature == WandSignature);
933  if (wand->debug != MagickFalse)
934  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
935  if (wand->images == (Image *) NULL)
936  return(MagickFalse);
937  image=GetImageFromList(wand->images,index);
938  if (image == (Image *) NULL)
939  {
940  InheritException(wand->exception,&wand->images->exception);
941  return(MagickFalse);
942  }
943  wand->images=image;
944  wand->insert_before=MagickFalse; /* Insert/Add after (this) image */
945  wand->image_pending=MagickFalse; /* NextImage will set next image */
946  return(MagickTrue);
947 }
948 /*
949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
950 % %
951 % %
952 % %
953 % M a g i c k S e t L a s t I t e r a t o r %
954 % %
955 % %
956 % %
957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
958 %
959 % MagickSetLastIterator() sets the wand iterator to the last image.
960 %
961 % The last image is actually the current image, and the next use of
962 % MagickPreviousImage() will not change this allowing this function to be
963 % used to iterate over the images in the reverse direction. In this sense it
964 % is more like MagickResetIterator() than MagickSetFirstIterator().
965 %
966 % Typically this function is used before MagickAddImage(), MagickReadImage()
967 % functions to ensure new images are appended to the very end of wand's image
968 % list.
969 %
970 % The format of the MagickSetLastIterator method is:
971 %
972 % void MagickSetLastIterator(MagickWand *wand)
973 %
974 % A description of each parameter follows:
975 %
976 % o wand: the magick wand.
977 %
978 */
979 WandExport void MagickSetLastIterator(MagickWand *wand)
980 {
981  assert(wand != (MagickWand *) NULL);
982  assert(wand->signature == WandSignature);
983  if (wand->debug != MagickFalse)
984  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
985  wand->images=GetLastImageInList(wand->images);
986  wand->insert_before=MagickFalse; /* Insert/add after current (last) image */
987  wand->image_pending=MagickTrue; /* PreviousImage will return last image */
988 }
989 
990 /*
991 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
992 % %
993 % %
994 % %
995 % M a g i c k W a n d G e n e s i s %
996 % %
997 % %
998 % %
999 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1000 %
1001 % MagickWandGenesis() initializes the MagickWand environment.
1002 %
1003 % The format of the MagickWandGenesis method is:
1004 %
1005 % void MagickWandGenesis(void)
1006 %
1007 */
1008 WandExport void MagickWandGenesis(void)
1009 {
1010  if (IsMagickCoreInstantiated() == MagickFalse)
1011  MagickCoreGenesis((char *) NULL,MagickFalse);
1012 }
1013 
1014 /*
1015 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1016 % %
1017 % %
1018 % %
1019 % M a g i c k W a n d T e r m i n u s %
1020 % %
1021 % %
1022 % %
1023 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1024 %
1025 % MagickWandTerminus() terminates the MagickWand environment.
1026 %
1027 % The format of the MagickWandTerminus method is:
1028 %
1029 % void MagickWandTerminus(void)
1030 %
1031 */
1032 WandExport void MagickWandTerminus(void)
1033 {
1034  DestroyWandIds();
1035  MagickCoreTerminus();
1036 }
1037 
1038 /*
1039 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1040 % %
1041 % %
1042 % %
1043 % N e w M a g i c k W a n d %
1044 % %
1045 % %
1046 % %
1047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1048 %
1049 % NewMagickWand() returns a wand required for all other methods in the API.
1050 % A fatal exception is thrown if there is not enough memory to allocate the
1051 % wand. Use DestroyMagickWand() to dispose of the wand when it is no longer
1052 % needed.
1053 %
1054 % The format of the NewMagickWand method is:
1055 %
1056 % MagickWand *NewMagickWand(void)
1057 %
1058 */
1059 WandExport MagickWand *NewMagickWand(void)
1060 {
1061  const char
1062  *quantum;
1063 
1064  MagickWand
1065  *wand;
1066 
1067  size_t
1068  depth;
1069 
1070  depth=MAGICKCORE_QUANTUM_DEPTH;
1071  quantum=GetMagickQuantumDepth(&depth);
1072  if (depth != MAGICKCORE_QUANTUM_DEPTH)
1073  ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
1074  wand=(MagickWand *) AcquireMagickMemory(sizeof(*wand));
1075  if (wand == (MagickWand *) NULL)
1076  ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
1077  GetExceptionMessage(errno));
1078  (void) memset(wand,0,sizeof(*wand));
1079  wand->id=AcquireWandId();
1080  (void) FormatLocaleString(wand->name,MaxTextExtent,"%s-%.20g",MagickWandId,
1081  (double) wand->id);
1082  wand->images=NewImageList();
1083  wand->image_info=AcquireImageInfo();
1084  wand->exception=AcquireExceptionInfo();
1085  wand->quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL);
1086  wand->debug=IsEventLogging();
1087  if (wand->debug != MagickFalse)
1088  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1089  wand->signature=WandSignature;
1090  return(wand);
1091 }
1092 
1093 /*
1094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1095 % %
1096 % %
1097 % %
1098 % N e w M a g i c k W a n d F r o m I m a g e %
1099 % %
1100 % %
1101 % %
1102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1103 %
1104 % NewMagickWandFromImage() returns a wand with an image.
1105 %
1106 % The format of the NewMagickWandFromImage method is:
1107 %
1108 % MagickWand *NewMagickWandFromImage(const Image *image)
1109 %
1110 % A description of each parameter follows:
1111 %
1112 % o image: the image.
1113 %
1114 */
1115 WandExport MagickWand *NewMagickWandFromImage(const Image *image)
1116 {
1117  MagickWand
1118  *wand;
1119 
1120  wand=NewMagickWand();
1121  wand->images=CloneImage(image,0,0,MagickTrue,wand->exception);
1122  return(wand);
1123 }
1124 
1125 /*
1126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1127 % %
1128 % %
1129 % %
1130 % I s M a g i c k W a n d I n s t a n t i a t e d %
1131 % %
1132 % %
1133 % %
1134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1135 %
1136 % IsMagickWandInstantiated() returns MagickTrue if the ImageMagick environment
1137 % is currently instantiated-- that is, MagickWandGenesis() has been called but
1138 % MagickWandTerminus() has not.
1139 %
1140 % The format of the IsMagickWandInstantiated method is:
1141 %
1142 % MagickBooleanType IsMagickWandInstantiated(void)
1143 %
1144 */
1145 MagickExport MagickBooleanType IsMagickWandInstantiated(void)
1146 {
1147  return(IsMagickCoreInstantiated());
1148 }