MagickWand 6.9.6
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 "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*/
77WandExport 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*/
116WandExport MagickWand *CloneMagickWand(const MagickWand *wand)
117{
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*/
166WandExport 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*/
207WandExport 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*/
240WandExport 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*/
278WandExport 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*/
335WandExport 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*/
367WandExport 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*/
405WandExport 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*/
460WandExport 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*/
519WandExport 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*/
627WandExport 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*/
714WandExport 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*/
755WandExport 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*/
793WandExport 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*/
832WandExport 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*/
876WandExport 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*/
928WandExport 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*/
982WandExport 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*/
1011WandExport 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() is a function in the ImageMagick library that is
1029% used to clean up and release resources when shutting down an application
1030% that uses ImageMagick. This function should be called in the primary thread
1031% of the application's process during the shutdown process. It's crucial that
1032% this function is invoked only after any threads that are using ImageMagick
1033% functions have terminated.
1034%
1035% ImageMagick might internally use threads via OpenMP (a method for parallel
1036% programming). As a result, it's important to ensure that any function calls
1037% into ImageMagick have completed before calling MagickWandTerminus(). This
1038% prevents issues with OpenMP worker threads accessing resources that are
1039% destroyed by this termination function.
1040%
1041% If OpenMP is being used (starting from version 5.0), the OpenMP
1042% implementation itself handles starting and stopping worker threads and
1043% allocating and freeing resources using its own methods. This means that
1044% after calling MagickWandTerminus(), some OpenMP resources and worker
1045% threads might still remain allocated. To address this, the function
1046% omp_pause_resource_all(omp_pause_hard) can be invoked. This function,
1047% introduced in OpenMP version 5.0, ensures that any resources allocated by
1048% OpenMP (such as threads and thread-specific memory) are freed. It's
1049% recommended to call this function after MagickWandTerminus() has completed
1050% its execution.
1051%
1052% The format of the MagickWandTerminus method is:
1053%
1054% void MagickWandTerminus(void)
1055%
1056*/
1057WandExport void MagickWandTerminus(void)
1058{
1059 DestroyWandIds();
1060 MagickCoreTerminus();
1061}
1062
1063/*
1064%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1065% %
1066% %
1067% %
1068% N e w M a g i c k W a n d %
1069% %
1070% %
1071% %
1072%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1073%
1074% NewMagickWand() returns a wand required for all other methods in the API.
1075% A fatal exception is thrown if there is not enough memory to allocate the
1076% wand. Use DestroyMagickWand() to dispose of the wand when it is no longer
1077% needed.
1078%
1079% The format of the NewMagickWand method is:
1080%
1081% MagickWand *NewMagickWand(void)
1082%
1083*/
1084WandExport MagickWand *NewMagickWand(void)
1085{
1086 const char
1087 *quantum;
1088
1090 *wand;
1091
1092 size_t
1093 depth;
1094
1095 depth=MAGICKCORE_QUANTUM_DEPTH;
1096 quantum=GetMagickQuantumDepth(&depth);
1097 if (depth != MAGICKCORE_QUANTUM_DEPTH)
1098 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
1099 wand=(MagickWand *) AcquireMagickMemory(sizeof(*wand));
1100 if (wand == (MagickWand *) NULL)
1101 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
1102 GetExceptionMessage(errno));
1103 (void) memset(wand,0,sizeof(*wand));
1104 wand->id=AcquireWandId();
1105 (void) FormatLocaleString(wand->name,MaxTextExtent,"%s-%.20g",MagickWandId,
1106 (double) wand->id);
1107 wand->images=NewImageList();
1108 wand->image_info=AcquireImageInfo();
1109 wand->exception=AcquireExceptionInfo();
1110 wand->quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL);
1111 wand->debug=IsEventLogging();
1112 if (wand->debug != MagickFalse)
1113 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1114 wand->signature=WandSignature;
1115 return(wand);
1116}
1117
1118/*
1119%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1120% %
1121% %
1122% %
1123% N e w M a g i c k W a n d F r o m I m a g e %
1124% %
1125% %
1126% %
1127%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1128%
1129% NewMagickWandFromImage() returns a wand with an image.
1130%
1131% The format of the NewMagickWandFromImage method is:
1132%
1133% MagickWand *NewMagickWandFromImage(const Image *image)
1134%
1135% A description of each parameter follows:
1136%
1137% o image: the image.
1138%
1139*/
1140WandExport MagickWand *NewMagickWandFromImage(const Image *image)
1141{
1143 *wand;
1144
1145 wand=NewMagickWand();
1146 wand->images=CloneImage(image,0,0,MagickTrue,wand->exception);
1147 return(wand);
1148}
1149
1150/*
1151%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1152% %
1153% %
1154% %
1155% I s M a g i c k W a n d I n s t a n t i a t e d %
1156% %
1157% %
1158% %
1159%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1160%
1161% IsMagickWandInstantiated() returns MagickTrue if the ImageMagick environment
1162% is currently instantiated-- that is, MagickWandGenesis() has been called but
1163% MagickWandTerminus() has not.
1164%
1165% The format of the IsMagickWandInstantiated method is:
1166%
1167% MagickBooleanType IsMagickWandInstantiated(void)
1168%
1169*/
1170MagickExport MagickBooleanType IsMagickWandInstantiated(void)
1171{
1172 return(IsMagickCoreInstantiated());
1173}