MagickWand 7.1.1
Convert, Edit, Or Compose Bitmap Images
Loading...
Searching...
No Matches
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*/
77WandExport 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*/
114WandExport MagickWand *CloneMagickWand(const MagickWand *wand)
115{
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*/
163WandExport 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*/
202WandExport 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*/
235WandExport 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*/
273WandExport 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*/
330WandExport 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*/
362WandExport 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*/
400WandExport 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*/
454WandExport 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*/
513WandExport 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*/
620WandExport 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*/
706WandExport 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*/
747WandExport 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*/
785WandExport 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*/
824WandExport 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*/
868WandExport 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*/
920WandExport 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*/
971WandExport 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*/
1000WandExport 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*/
1046WandExport 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*/
1073WandExport MagickWand *NewMagickWand(void)
1074{
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*/
1119WandExport MagickWand *NewMagickWandFromImage(const Image *image)
1120{
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*/
1149MagickExport MagickBooleanType IsMagickWandInstantiated(void)
1150{
1151 return(IsMagickCoreInstantiated());
1152}