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