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