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