1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % M M AAA GGGG IIIII CCCC K K %
7 % MM MM A A G I C K K %
8 % M M M AAAAA G GGG I C KKK %
9 % M M A A G G I C K K %
10 % M M A A GGGG IIIII CCCC K K %
11 % %
12 % W W AAA N N DDDD %
13 % W W A A NN N D D %
14 % W W W AAAAA N N N D D %
15 % WW WW A A N NN D D %
16 % W W A A N N DDDD %
17 % %
18 % %
19 % MagickWand Wand Methods %
20 % %
21 % Software Design %
22 % Cristy %
23 % August 2003 %
24 % %
25 % %
26 % Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization %
27 % dedicated to making software imaging solutions freely available. %
28 % %
29 % You may not use this file except in compliance with the License. You may %
30 % obtain a copy of the License at %
31 % %
32 % https://imagemagick.org/script/license.php %
33 % %
34 % Unless required by applicable law or agreed to in writing, software %
35 % distributed under the License is distributed on an "AS IS" BASIS, %
36 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
37 % See the License for the specific language governing permissions and %
38 % limitations under the License. %
39 % %
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 %
42 %
43 %
44 */
45
46 /*
47 Include declarations.
48 */
49 #include "wand/studio.h"
50 #include "wand/MagickWand.h"
51 #include "wand/magick-wand-private.h"
52 #include "wand/wand.h"
53
54 /*
55 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
56 % %
57 % %
58 % %
59 % C l e a r M a g i c k W a n d %
60 % %
61 % %
62 % %
63 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64 %
65 % ClearMagickWand() clears resources associated with the wand, leaving the
66 % wand blank, and ready to be used for a new set of images.
67 %
68 % The format of the ClearMagickWand method is:
69 %
70 % void ClearMagickWand(MagickWand *wand)
71 %
72 % A description of each parameter follows:
73 %
74 % o wand: the magick wand.
75 %
76 */
ClearMagickWand(MagickWand * wand)77 WandExport void ClearMagickWand(MagickWand *wand)
78 {
79 assert(wand != (MagickWand *) NULL);
80 assert(wand->signature == WandSignature);
81 if (wand->debug != MagickFalse)
82 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
83 wand->quantize_info=DestroyQuantizeInfo(wand->quantize_info);
84 wand->image_info=DestroyImageInfo(wand->image_info);
85 wand->images=DestroyImageList(wand->images);
86 wand->image_info=AcquireImageInfo();
87 wand->quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL);
88 wand->insert_before=MagickFalse;
89 wand->image_pending=MagickFalse;
90 ClearMagickException(wand->exception);
91 wand->debug=IsEventLogging();
92 }
93
94 /*
95 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
96 % %
97 % %
98 % %
99 % C l o n e M a g i c k W a n d %
100 % %
101 % %
102 % %
103 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
104 %
105 % CloneMagickWand() makes an exact copy of the specified wand.
106 %
107 % The format of the CloneMagickWand method is:
108 %
109 % MagickWand *CloneMagickWand(const MagickWand *wand)
110 %
111 % A description of each parameter follows:
112 %
113 % o wand: the magick wand.
114 %
115 */
CloneMagickWand(const MagickWand * wand)116 WandExport MagickWand *CloneMagickWand(const MagickWand *wand)
117 {
118 MagickWand
119 *clone_wand;
120
121 assert(wand != (MagickWand *) NULL);
122 assert(wand->signature == WandSignature);
123 if (wand->debug != MagickFalse)
124 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
125 clone_wand=(MagickWand *) AcquireCriticalMemory(sizeof(*clone_wand));
126 (void) memset(clone_wand,0,sizeof(*clone_wand));
127 clone_wand->id=AcquireWandId();
128 (void) FormatLocaleString(clone_wand->name,MaxTextExtent,"%s-%.20g",
129 MagickWandId,(double) clone_wand->id);
130 clone_wand->exception=AcquireExceptionInfo();
131 InheritException(clone_wand->exception,wand->exception);
132 clone_wand->image_info=CloneImageInfo(wand->image_info);
133 clone_wand->quantize_info=CloneQuantizeInfo(wand->quantize_info);
134 clone_wand->images=CloneImageList(wand->images,clone_wand->exception);
135 clone_wand->insert_before=MagickFalse;
136 clone_wand->image_pending=MagickFalse;
137 clone_wand->debug=IsEventLogging();
138 if (clone_wand->debug != MagickFalse)
139 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clone_wand->name);
140 clone_wand->signature=WandSignature;
141 return(clone_wand);
142 }
143
144 /*
145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146 % %
147 % %
148 % %
149 % D e s t r o y M a g i c k W a n d %
150 % %
151 % %
152 % %
153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
154 %
155 % DestroyMagickWand() deallocates memory associated with an MagickWand.
156 %
157 % The format of the DestroyMagickWand method is:
158 %
159 % MagickWand *DestroyMagickWand(MagickWand *wand)
160 %
161 % A description of each parameter follows:
162 %
163 % o wand: the magick wand.
164 %
165 */
DestroyMagickWand(MagickWand * wand)166 WandExport MagickWand *DestroyMagickWand(MagickWand *wand)
167 {
168 assert(wand != (MagickWand *) NULL);
169 assert(wand->signature == WandSignature);
170 if (wand->debug != MagickFalse)
171 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
172 wand->images=DestroyImageList(wand->images);
173 if (wand->quantize_info != (QuantizeInfo *) NULL )
174 wand->quantize_info=DestroyQuantizeInfo(wand->quantize_info);
175 if (wand->image_info != (ImageInfo *) NULL )
176 wand->image_info=DestroyImageInfo(wand->image_info);
177 if (wand->exception != (ExceptionInfo *) NULL )
178 wand->exception=DestroyExceptionInfo(wand->exception);
179 RelinquishWandId(wand->id);
180 wand->signature=(~WandSignature);
181 wand=(MagickWand *) RelinquishMagickMemory(wand);
182 return(wand);
183 }
184
185 /*
186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
187 % %
188 % %
189 % %
190 % I s M a g i c k W a n d %
191 % %
192 % %
193 % %
194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
195 %
196 % IsMagickWand() returns MagickTrue if the wand is verified as a magick wand.
197 %
198 % The format of the IsMagickWand method is:
199 %
200 % MagickBooleanType IsMagickWand(const MagickWand *wand)
201 %
202 % A description of each parameter follows:
203 %
204 % o wand: the magick wand.
205 %
206 */
IsMagickWand(const MagickWand * wand)207 WandExport MagickBooleanType IsMagickWand(const MagickWand *wand)
208 {
209 if (wand == (const MagickWand *) NULL)
210 return(MagickFalse);
211 if (wand->signature != WandSignature)
212 return(MagickFalse);
213 if (LocaleNCompare(wand->name,MagickWandId,strlen(MagickWandId)) != 0)
214 return(MagickFalse);
215 return(MagickTrue);
216 }
217
218 /*
219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
220 % %
221 % %
222 % %
223 % M a g i c k C l e a r E x c e p t i o n %
224 % %
225 % %
226 % %
227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
228 %
229 % MagickClearException() clears any exceptions associated with the wand.
230 %
231 % The format of the MagickClearException method is:
232 %
233 % MagickBooleanType MagickClearException(MagickWand *wand)
234 %
235 % A description of each parameter follows:
236 %
237 % o wand: the magick wand.
238 %
239 */
MagickClearException(MagickWand * wand)240 WandExport MagickBooleanType MagickClearException(MagickWand *wand)
241 {
242 assert(wand != (MagickWand *) NULL);
243 assert(wand->signature == WandSignature);
244 if (wand->debug != MagickFalse)
245 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
246 ClearMagickException(wand->exception);
247 return(MagickTrue);
248 }
249
250 /*
251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252 % %
253 % %
254 % %
255 % M a g i c k G e t E x c e p t i o n %
256 % %
257 % %
258 % %
259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
260 %
261 % MagickGetException() returns the severity, reason, and description of any
262 % error that occurs when using other methods in this API.
263 %
264 % The format of the MagickGetException method is:
265 %
266 % char *MagickGetException(const MagickWand *wand,ExceptionType *severity)
267 %
268 % A description of each parameter follows:
269 %
270 % o wand: the magick wand.
271 %
272 % o severity: the severity of the error is returned here.
273 %
274 */
MagickGetException(const MagickWand * wand,ExceptionType * severity)275 WandExport char *MagickGetException(const MagickWand *wand,
276 ExceptionType *severity)
277 {
278 char
279 *description;
280
281 assert(wand != (const MagickWand *) NULL);
282 assert(wand->signature == WandSignature);
283 if (wand->debug != MagickFalse)
284 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
285 assert(severity != (ExceptionType *) NULL);
286 *severity=wand->exception->severity;
287 description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
288 sizeof(*description));
289 if (description == (char *) NULL)
290 {
291 (void) ThrowMagickException(wand->exception,GetMagickModule(),WandError,
292 "MemoryAllocationFailed","`%s'",wand->name);
293 return((char *) NULL);
294 }
295 *description='\0';
296 if (wand->exception->reason != (char *) NULL)
297 (void) CopyMagickString(description,GetLocaleExceptionMessage(
298 wand->exception->severity,wand->exception->reason),MaxTextExtent);
299 if (wand->exception->description != (char *) NULL)
300 {
301 (void) ConcatenateMagickString(description," (",MaxTextExtent);
302 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
303 wand->exception->severity,wand->exception->description),MaxTextExtent);
304 (void) ConcatenateMagickString(description,")",MaxTextExtent);
305 }
306 return(description);
307 }
308
309 /*
310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311 % %
312 % %
313 % %
314 % M a g i c k G e t E x c e p t i o n T y p e %
315 % %
316 % %
317 % %
318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
319 %
320 % MagickGetExceptionType() returns the exception type associated with the
321 % wand. If no exception has occurred, UndefinedExceptionType is returned.
322 %
323 % The format of the MagickGetExceptionType method is:
324 %
325 % ExceptionType MagickGetExceptionType(const MagickWand *wand)
326 %
327 % A description of each parameter follows:
328 %
329 % o wand: the magick wand.
330 %
331 */
MagickGetExceptionType(const MagickWand * wand)332 WandExport ExceptionType MagickGetExceptionType(const MagickWand *wand)
333 {
334 assert(wand != (MagickWand *) NULL);
335 assert(wand->signature == WandSignature);
336 if (wand->debug != MagickFalse)
337 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
338 return(wand->exception->severity);
339 }
340
341 /*
342 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
343 % %
344 % %
345 % %
346 % M a g i c k G e t I t e r a t o r I n d e x %
347 % %
348 % %
349 % %
350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
351 %
352 % MagickGetIteratorIndex() returns the position of the iterator in the image
353 % list.
354 %
355 % The format of the MagickGetIteratorIndex method is:
356 %
357 % ssize_t MagickGetIteratorIndex(MagickWand *wand)
358 %
359 % A description of each parameter follows:
360 %
361 % o wand: the magick wand.
362 %
363 */
MagickGetIteratorIndex(MagickWand * wand)364 WandExport ssize_t MagickGetIteratorIndex(MagickWand *wand)
365 {
366 assert(wand != (MagickWand *) NULL);
367 assert(wand->signature == WandSignature);
368 if (wand->debug != MagickFalse)
369 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
370 if (wand->images == (Image *) NULL)
371 {
372 (void) ThrowMagickException(wand->exception,GetMagickModule(),WandError,
373 "ContainsNoIterators","`%s'",wand->name);
374 return(-1);
375 }
376 return(GetImageIndexInList(wand->images));
377 }
378
379 /*
380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
381 % %
382 % %
383 % %
384 % M a g i c k Q u e r y C o n f i g u r e O p t i o n %
385 % %
386 % %
387 % %
388 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
389 %
390 % MagickQueryConfigureOption() returns the value associated with the specified
391 % configure option.
392 %
393 % The format of the MagickQueryConfigureOption function is:
394 %
395 % char *MagickQueryConfigureOption(const char *option)
396 %
397 % A description of each parameter follows:
398 %
399 % o option: the option name.
400 %
401 */
MagickQueryConfigureOption(const char * option)402 WandExport char *MagickQueryConfigureOption(const char *option)
403 {
404 char
405 *value;
406
407 const ConfigureInfo
408 **configure_info;
409
410 ExceptionInfo
411 *exception;
412
413 size_t
414 number_options;
415
416 exception=AcquireExceptionInfo();
417 configure_info=GetConfigureInfoList(option,&number_options,exception);
418 exception=DestroyExceptionInfo(exception);
419 if (configure_info == (const ConfigureInfo **) NULL)
420 return((char *) NULL);
421 value=(char *) NULL;
422 if (number_options != 0)
423 value=AcquireString(configure_info[0]->value);
424 configure_info=(const ConfigureInfo **)
425 RelinquishMagickMemory((void *) configure_info);
426 return(value);
427 }
428
429 /*
430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
431 % %
432 % %
433 % %
434 % M a g i c k Q u e r y C o n f i g u r e O p t i o n s %
435 % %
436 % %
437 % %
438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
439 %
440 % MagickQueryConfigureOptions() returns any configure options that match the
441 % specified pattern (e.g. "*" for all). Options include NAME, VERSION,
442 % LIB_VERSION, etc.
443 %
444 % The format of the MagickQueryConfigureOptions function is:
445 %
446 % char **MagickQueryConfigureOptions(const char *pattern,
447 % size_t *number_options)
448 %
449 % A description of each parameter follows:
450 %
451 % o pattern: Specifies a pointer to a text string containing a pattern.
452 %
453 % o number_options: Returns the number of configure options in the list.
454 %
455 %
456 */
MagickQueryConfigureOptions(const char * pattern,size_t * number_options)457 WandExport char **MagickQueryConfigureOptions(const char *pattern,
458 size_t *number_options)
459 {
460 char
461 **options;
462
463 ExceptionInfo
464 *exception;
465
466 exception=AcquireExceptionInfo();
467 options=GetConfigureList(pattern,number_options,exception);
468 exception=DestroyExceptionInfo(exception);
469 return(options);
470 }
471
472 /*
473 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
474 % %
475 % %
476 % %
477 % M a g i c k Q u e r y F o n t M e t r i c s %
478 % %
479 % %
480 % %
481 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
482 %
483 % MagickQueryFontMetrics() returns a 13 element array representing the
484 % following font metrics:
485 %
486 % Element Description
487 % -------------------------------------------------
488 % 0 character width
489 % 1 character height
490 % 2 ascender
491 % 3 descender
492 % 4 text width
493 % 5 text height
494 % 6 maximum horizontal advance
495 % 7 bounding box: x1
496 % 8 bounding box: y1
497 % 9 bounding box: x2
498 % 10 bounding box: y2
499 % 11 origin: x
500 % 12 origin: y
501 %
502 % The format of the MagickQueryFontMetrics method is:
503 %
504 % double *MagickQueryFontMetrics(MagickWand *wand,
505 % const DrawingWand *drawing_wand,const char *text)
506 %
507 % A description of each parameter follows:
508 %
509 % o wand: the Magick wand.
510 %
511 % o drawing_wand: the drawing wand.
512 %
513 % o text: the text.
514 %
515 */
MagickQueryFontMetrics(MagickWand * wand,const DrawingWand * drawing_wand,const char * text)516 WandExport double *MagickQueryFontMetrics(MagickWand *wand,
517 const DrawingWand *drawing_wand,const char *text)
518 {
519 double
520 *font_metrics;
521
522 DrawInfo
523 *draw_info;
524
525 MagickBooleanType
526 status;
527
528 TypeMetric
529 metrics;
530
531 assert(wand != (MagickWand *) NULL);
532 assert(wand->signature == WandSignature);
533 if (wand->debug != MagickFalse)
534 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
535 assert(drawing_wand != (const DrawingWand *) NULL);
536 if (wand->images == (Image *) NULL)
537 {
538 (void) ThrowMagickException(wand->exception,GetMagickModule(),WandError,
539 "ContainsNoImages","`%s'",wand->name);
540 return((double *) NULL);
541 }
542 font_metrics=(double *) AcquireQuantumMemory(13UL,sizeof(*font_metrics));
543 if (font_metrics == (double *) NULL)
544 return((double *) NULL);
545 draw_info=PeekDrawingWand(drawing_wand);
546 if (draw_info == (DrawInfo *) NULL)
547 {
548 font_metrics=(double *) RelinquishMagickMemory(font_metrics);
549 return((double *) NULL);
550 }
551 (void) CloneString(&draw_info->text,text);
552 (void) memset(&metrics,0,sizeof(metrics));
553 status=GetTypeMetrics(wand->images,draw_info,&metrics);
554 draw_info=DestroyDrawInfo(draw_info);
555 if (status == MagickFalse)
556 {
557 InheritException(wand->exception,&wand->images->exception);
558 font_metrics=(double *) RelinquishMagickMemory(font_metrics);
559 return((double *) NULL);
560 }
561 font_metrics[0]=metrics.pixels_per_em.x;
562 font_metrics[1]=metrics.pixels_per_em.y;
563 font_metrics[2]=metrics.ascent;
564 font_metrics[3]=metrics.descent;
565 font_metrics[4]=metrics.width;
566 font_metrics[5]=metrics.height;
567 font_metrics[6]=metrics.max_advance;
568 font_metrics[7]=metrics.bounds.x1;
569 font_metrics[8]=metrics.bounds.y1;
570 font_metrics[9]=metrics.bounds.x2;
571 font_metrics[10]=metrics.bounds.y2;
572 font_metrics[11]=metrics.origin.x;
573 font_metrics[12]=metrics.origin.y;
574 return(font_metrics);
575 }
576
577 /*
578 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
579 % %
580 % %
581 % %
582 % M a g i c k Q u e r y M u l t i l i n e F o n t M e t r i c s %
583 % %
584 % %
585 % %
586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
587 %
588 % MagickQueryMultilineFontMetrics() returns a 13 element array representing the
589 % following font metrics:
590 %
591 % Element Description
592 % -------------------------------------------------
593 % 0 character width
594 % 1 character height
595 % 2 ascender
596 % 3 descender
597 % 4 text width
598 % 5 text height
599 % 6 maximum horizontal advance
600 % 7 bounding box: x1
601 % 8 bounding box: y1
602 % 9 bounding box: x2
603 % 10 bounding box: y2
604 % 11 origin: x
605 % 12 origin: y
606 %
607 % This method is like MagickQueryFontMetrics() but it returns the maximum text
608 % width and height for multiple lines of text.
609 %
610 % The format of the MagickQueryFontMetrics method is:
611 %
612 % double *MagickQueryMultilineFontMetrics(MagickWand *wand,
613 % const DrawingWand *drawing_wand,const char *text)
614 %
615 % A description of each parameter follows:
616 %
617 % o wand: the Magick wand.
618 %
619 % o drawing_wand: the drawing wand.
620 %
621 % o text: the text.
622 %
623 */
MagickQueryMultilineFontMetrics(MagickWand * wand,const DrawingWand * drawing_wand,const char * text)624 WandExport double *MagickQueryMultilineFontMetrics(MagickWand *wand,
625 const DrawingWand *drawing_wand,const char *text)
626 {
627 double
628 *font_metrics;
629
630 DrawInfo
631 *draw_info;
632
633 MagickBooleanType
634 status;
635
636 TypeMetric
637 metrics;
638
639 assert(wand != (MagickWand *) NULL);
640 assert(wand->signature == WandSignature);
641 if (wand->debug != MagickFalse)
642 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
643 assert(drawing_wand != (const DrawingWand *) NULL);
644 if (wand->images == (Image *) NULL)
645 {
646 (void) ThrowMagickException(wand->exception,GetMagickModule(),WandError,
647 "ContainsNoImages","`%s'",wand->name);
648 return((double *) NULL);
649 }
650 font_metrics=(double *) AcquireQuantumMemory(13UL,sizeof(*font_metrics));
651 if (font_metrics == (double *) NULL)
652 return((double *) NULL);
653 draw_info=PeekDrawingWand(drawing_wand);
654 if (draw_info == (DrawInfo *) NULL)
655 {
656 font_metrics=(double *) RelinquishMagickMemory(font_metrics);
657 return((double *) NULL);
658 }
659 (void) CloneString(&draw_info->text,text);
660 (void) memset(&metrics,0,sizeof(metrics));
661 status=GetMultilineTypeMetrics(wand->images,draw_info,&metrics);
662 draw_info=DestroyDrawInfo(draw_info);
663 if (status == MagickFalse)
664 {
665 InheritException(wand->exception,&wand->images->exception);
666 font_metrics=(double *) RelinquishMagickMemory(font_metrics);
667 return((double *) NULL);
668 }
669 font_metrics[0]=metrics.pixels_per_em.x;
670 font_metrics[1]=metrics.pixels_per_em.y;
671 font_metrics[2]=metrics.ascent;
672 font_metrics[3]=metrics.descent;
673 font_metrics[4]=metrics.width;
674 font_metrics[5]=metrics.height;
675 font_metrics[6]=metrics.max_advance;
676 font_metrics[7]=metrics.bounds.x1;
677 font_metrics[8]=metrics.bounds.y1;
678 font_metrics[9]=metrics.bounds.x2;
679 font_metrics[10]=metrics.bounds.y2;
680 font_metrics[11]=metrics.origin.x;
681 font_metrics[12]=metrics.origin.y;
682 return(font_metrics);
683 }
684
685 /*
686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
687 % %
688 % %
689 % %
690 % M a g i c k Q u e r y F o n t s %
691 % %
692 % %
693 % %
694 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
695 %
696 % MagickQueryFonts() returns any font that match the specified pattern (e.g.
697 % "*" for all).
698 %
699 % The format of the MagickQueryFonts function is:
700 %
701 % char **MagickQueryFonts(const char *pattern,size_t *number_fonts)
702 %
703 % A description of each parameter follows:
704 %
705 % o pattern: Specifies a pointer to a text string containing a pattern.
706 %
707 % o number_fonts: Returns the number of fonts in the list.
708 %
709 %
710 */
MagickQueryFonts(const char * pattern,size_t * number_fonts)711 WandExport char **MagickQueryFonts(const char *pattern,
712 size_t *number_fonts)
713 {
714 char
715 **fonts;
716
717 ExceptionInfo
718 *exception;
719
720 exception=AcquireExceptionInfo();
721 fonts=GetTypeList(pattern,number_fonts,exception);
722 exception=DestroyExceptionInfo(exception);
723 return(fonts);
724 }
725
726 /*
727 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
728 % %
729 % %
730 % %
731 % M a g i c k Q u e r y F o r m a t s %
732 % %
733 % %
734 % %
735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
736 %
737 % MagickQueryFormats() returns any image formats that match the specified
738 % pattern (e.g. "*" for all).
739 %
740 % The format of the MagickQueryFormats function is:
741 %
742 % char **MagickQueryFormats(const char *pattern,size_t *number_formats)
743 %
744 % A description of each parameter follows:
745 %
746 % o pattern: Specifies a pointer to a text string containing a pattern.
747 %
748 % o number_formats: This integer returns the number of image formats in the
749 % list.
750 %
751 */
MagickQueryFormats(const char * pattern,size_t * number_formats)752 WandExport char **MagickQueryFormats(const char *pattern,
753 size_t *number_formats)
754 {
755 char
756 **formats;
757
758 ExceptionInfo
759 *exception;
760
761 exception=AcquireExceptionInfo();
762 formats=GetMagickList(pattern,number_formats,exception);
763 exception=DestroyExceptionInfo(exception);
764 return(formats);
765 }
766
767 /*
768 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
769 % %
770 % %
771 % %
772 % M a g i c k R e l i n q u i s h M e m o r y %
773 % %
774 % %
775 % %
776 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
777 %
778 % MagickRelinquishMemory() relinquishes memory resources returned by such
779 % methods as MagickIdentifyImage(), MagickGetException(), etc.
780 %
781 % The format of the MagickRelinquishMemory method is:
782 %
783 % void *MagickRelinquishMemory(void *resource)
784 %
785 % A description of each parameter follows:
786 %
787 % o resource: Relinquish the memory associated with this resource.
788 %
789 */
MagickRelinquishMemory(void * memory)790 WandExport void *MagickRelinquishMemory(void *memory)
791 {
792 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
793 return(RelinquishMagickMemory(memory));
794 }
795
796 /*
797 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
798 % %
799 % %
800 % %
801 % M a g i c k R e s e t I t e r a t o r %
802 % %
803 % %
804 % %
805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
806 %
807 % MagickResetIterator() resets the wand iterator.
808 %
809 % It is typically used either before iterating though images, or before
810 % calling specific functions such as MagickAppendImages() to append all
811 % images together.
812 %
813 % Afterward you can use MagickNextImage() to iterate over all the images
814 % in a wand container, starting with the first image.
815 %
816 % Using this before MagickAddImages() or MagickReadImages() will cause
817 % new images to be inserted between the first and second image.
818 %
819 % The format of the MagickResetIterator method is:
820 %
821 % void MagickResetIterator(MagickWand *wand)
822 %
823 % A description of each parameter follows:
824 %
825 % o wand: the magick wand.
826 %
827 */
MagickResetIterator(MagickWand * wand)828 WandExport void MagickResetIterator(MagickWand *wand)
829 {
830 assert(wand != (MagickWand *) NULL);
831 assert(wand->signature == WandSignature);
832 if (wand->debug != MagickFalse)
833 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
834 wand->images=GetFirstImageInList(wand->images);
835 wand->insert_before=MagickFalse; /* Insert/add after current (first) image */
836 wand->image_pending=MagickTrue; /* NextImage will set first image */
837 }
838
839 /*
840 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
841 % %
842 % %
843 % %
844 % M a g i c k S e t F i r s t I t e r a t o r %
845 % %
846 % %
847 % %
848 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
849 %
850 % MagickSetFirstIterator() sets the wand iterator to the first image.
851 %
852 % After using any images added to the wand using MagickAddImage() or
853 % MagickReadImage() will be prepended before any image in the wand.
854 %
855 % Also the current image has been set to the first image (if any) in the
856 % Magick Wand. Using MagickNextImage() will then set teh current image
857 % to the second image in the list (if present).
858 %
859 % This operation is similar to MagickResetIterator() but differs in how
860 % MagickAddImage(), MagickReadImage(), and MagickNextImage() behaves
861 % afterward.
862 %
863 % The format of the MagickSetFirstIterator method is:
864 %
865 % void MagickSetFirstIterator(MagickWand *wand)
866 %
867 % A description of each parameter follows:
868 %
869 % o wand: the magick wand.
870 %
871 */
MagickSetFirstIterator(MagickWand * wand)872 WandExport void MagickSetFirstIterator(MagickWand *wand)
873 {
874 assert(wand != (MagickWand *) NULL);
875 assert(wand->signature == WandSignature);
876 if (wand->debug != MagickFalse)
877 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
878 wand->images=GetFirstImageInList(wand->images);
879 wand->insert_before=MagickTrue; /* Insert/add before the first image */
880 wand->image_pending=MagickFalse; /* NextImage will set next image */
881 }
882
883 /*
884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
885 % %
886 % %
887 % %
888 % M a g i c k S e t I t e r a t o r I n d e x %
889 % %
890 % %
891 % %
892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
893 %
894 % MagickSetIteratorIndex() set the iterator to the given position in the
895 % image list specified with the index parameter. A zero index will set
896 % the first image as current, and so on. Negative indexes can be used
897 % to specify an image relative to the end of the images in the wand, with
898 % -1 being the last image in the wand.
899 %
900 % If the index is invalid (range too large for number of images in wand)
901 % the function will return MagickFalse, but no 'exception' will be raised,
902 % as it is not actually an error. In that case the current image will not
903 % change.
904 %
905 % After using any images added to the wand using MagickAddImage() or
906 % MagickReadImage() will be added after the image indexed, regardless
907 % of if a zero (first image in list) or negative index (from end) is used.
908 %
909 % Jumping to index 0 is similar to MagickResetIterator() but differs in how
910 % MagickNextImage() behaves afterward.
911 %
912 % The format of the MagickSetIteratorIndex method is:
913 %
914 % MagickBooleanType MagickSetIteratorIndex(MagickWand *wand,
915 % const ssize_t index)
916 %
917 % A description of each parameter follows:
918 %
919 % o wand: the magick wand.
920 %
921 % o index: the scene number.
922 %
923 */
MagickSetIteratorIndex(MagickWand * wand,const ssize_t index)924 WandExport MagickBooleanType MagickSetIteratorIndex(MagickWand *wand,
925 const ssize_t index)
926 {
927 Image
928 *image;
929
930 assert(wand != (MagickWand *) NULL);
931 assert(wand->signature == WandSignature);
932 if (wand->debug != MagickFalse)
933 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
934 if (wand->images == (Image *) NULL)
935 return(MagickFalse);
936 image=GetImageFromList(wand->images,index);
937 if (image == (Image *) NULL)
938 {
939 InheritException(wand->exception,&wand->images->exception);
940 return(MagickFalse);
941 }
942 wand->images=image;
943 wand->insert_before=MagickFalse; /* Insert/Add after (this) image */
944 wand->image_pending=MagickFalse; /* NextImage will set next image */
945 return(MagickTrue);
946 }
947 /*
948 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
949 % %
950 % %
951 % %
952 % M a g i c k S e t L a s t I t e r a t o r %
953 % %
954 % %
955 % %
956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
957 %
958 % MagickSetLastIterator() sets the wand iterator to the last image.
959 %
960 % The last image is actually the current image, and the next use of
961 % MagickPreviousImage() will not change this allowing this function to be
962 % used to iterate over the images in the reverse direction. In this sense it
963 % is more like MagickResetIterator() than MagickSetFirstIterator().
964 %
965 % Typically this function is used before MagickAddImage(), MagickReadImage()
966 % functions to ensure new images are appended to the very end of wand's image
967 % list.
968 %
969 % The format of the MagickSetLastIterator method is:
970 %
971 % void MagickSetLastIterator(MagickWand *wand)
972 %
973 % A description of each parameter follows:
974 %
975 % o wand: the magick wand.
976 %
977 */
MagickSetLastIterator(MagickWand * wand)978 WandExport void MagickSetLastIterator(MagickWand *wand)
979 {
980 assert(wand != (MagickWand *) NULL);
981 assert(wand->signature == WandSignature);
982 if (wand->debug != MagickFalse)
983 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
984 wand->images=GetLastImageInList(wand->images);
985 wand->insert_before=MagickFalse; /* Insert/add after current (last) image */
986 wand->image_pending=MagickTrue; /* PreviousImage will return last image */
987 }
988
989 /*
990 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
991 % %
992 % %
993 % %
994 % M a g i c k W a n d G e n e s i s %
995 % %
996 % %
997 % %
998 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
999 %
1000 % MagickWandGenesis() initializes the MagickWand environment.
1001 %
1002 % The format of the MagickWandGenesis method is:
1003 %
1004 % void MagickWandGenesis(void)
1005 %
1006 */
MagickWandGenesis(void)1007 WandExport void MagickWandGenesis(void)
1008 {
1009 if (IsMagickCoreInstantiated() == MagickFalse)
1010 MagickCoreGenesis((char *) NULL,MagickFalse);
1011 }
1012
1013 /*
1014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1015 % %
1016 % %
1017 % %
1018 % M a g i c k W a n d T e r m i n u s %
1019 % %
1020 % %
1021 % %
1022 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1023 %
1024 % MagickWandTerminus() terminates the MagickWand environment.
1025 %
1026 % The format of the MagickWandTerminus method is:
1027 %
1028 % void MagickWandTerminus(void)
1029 %
1030 */
MagickWandTerminus(void)1031 WandExport void MagickWandTerminus(void)
1032 {
1033 DestroyWandIds();
1034 MagickCoreTerminus();
1035 }
1036
1037 /*
1038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1039 % %
1040 % %
1041 % %
1042 % N e w M a g i c k W a n d %
1043 % %
1044 % %
1045 % %
1046 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1047 %
1048 % NewMagickWand() returns a wand required for all other methods in the API.
1049 % A fatal exception is thrown if there is not enough memory to allocate the
1050 % wand. Use DestroyMagickWand() to dispose of the wand when it is no longer
1051 % needed.
1052 %
1053 % The format of the NewMagickWand method is:
1054 %
1055 % MagickWand *NewMagickWand(void)
1056 %
1057 */
NewMagickWand(void)1058 WandExport MagickWand *NewMagickWand(void)
1059 {
1060 const char
1061 *quantum;
1062
1063 MagickWand
1064 *wand;
1065
1066 size_t
1067 depth;
1068
1069 depth=MAGICKCORE_QUANTUM_DEPTH;
1070 quantum=GetMagickQuantumDepth(&depth);
1071 if (depth != MAGICKCORE_QUANTUM_DEPTH)
1072 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
1073 wand=(MagickWand *) AcquireMagickMemory(sizeof(*wand));
1074 if (wand == (MagickWand *) NULL)
1075 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
1076 GetExceptionMessage(errno));
1077 (void) memset(wand,0,sizeof(*wand));
1078 wand->id=AcquireWandId();
1079 (void) FormatLocaleString(wand->name,MaxTextExtent,"%s-%.20g",MagickWandId,
1080 (double) wand->id);
1081 wand->images=NewImageList();
1082 wand->image_info=AcquireImageInfo();
1083 wand->exception=AcquireExceptionInfo();
1084 wand->quantize_info=CloneQuantizeInfo((QuantizeInfo *) NULL);
1085 wand->debug=IsEventLogging();
1086 if (wand->debug != MagickFalse)
1087 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1088 wand->signature=WandSignature;
1089 return(wand);
1090 }
1091
1092 /*
1093 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1094 % %
1095 % %
1096 % %
1097 % N e w M a g i c k W a n d F r o m I m a g e %
1098 % %
1099 % %
1100 % %
1101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1102 %
1103 % NewMagickWandFromImage() returns a wand with an image.
1104 %
1105 % The format of the NewMagickWandFromImage method is:
1106 %
1107 % MagickWand *NewMagickWandFromImage(const Image *image)
1108 %
1109 % A description of each parameter follows:
1110 %
1111 % o image: the image.
1112 %
1113 */
NewMagickWandFromImage(const Image * image)1114 WandExport MagickWand *NewMagickWandFromImage(const Image *image)
1115 {
1116 MagickWand
1117 *wand;
1118
1119 wand=NewMagickWand();
1120 wand->images=CloneImage(image,0,0,MagickTrue,wand->exception);
1121 return(wand);
1122 }
1123
1124 /*
1125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1126 % %
1127 % %
1128 % %
1129 % I s M a g i c k W a n d I n s t a n t i a t e d %
1130 % %
1131 % %
1132 % %
1133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1134 %
1135 % IsMagickWandInstantiated() returns MagickTrue if the ImageMagick environment
1136 % is currently instantiated-- that is, MagickWandGenesis() has been called but
1137 % MagickWandTerminus() has not.
1138 %
1139 % The format of the IsMagickWandInstantiated method is:
1140 %
1141 % MagickBooleanType IsMagickWandInstantiated(void)
1142 %
1143 */
IsMagickWandInstantiated(void)1144 MagickExport MagickBooleanType IsMagickWandInstantiated(void)
1145 {
1146 return(IsMagickCoreInstantiated());
1147 }
1148