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 % %
13 % Methods to Read or List ImageMagick Image formats %
14 % %
15 % Software Design %
16 % Bob Friesenhahn %
17 % Cristy %
18 % November 1998 %
19 % %
20 % %
21 % Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization %
22 % dedicated to making software imaging solutions freely available. %
23 % %
24 % You may not use this file except in compliance with the License. You may %
25 % obtain a copy of the License at %
26 % %
27 % http://www.imagemagick.org/script/license.php %
28 % %
29 % Unless required by applicable law or agreed to in writing, software %
30 % distributed under the License is distributed on an "AS IS" BASIS, %
31 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
32 % See the License for the specific language governing permissions and %
33 % limitations under the License. %
34 % %
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 %
37 %
38 */
39
40 /*
41 Include declarations.
42 */
43 #include "MagickCore/studio.h"
44 #include "MagickCore/annotate-private.h"
45 #include "MagickCore/blob.h"
46 #include "MagickCore/blob-private.h"
47 #include "MagickCore/cache.h"
48 #include "MagickCore/cache-private.h"
49 #include "MagickCore/coder-private.h"
50 #include "MagickCore/client.h"
51 #include "MagickCore/color-private.h"
52 #include "MagickCore/configure-private.h"
53 #include "MagickCore/constitute-private.h"
54 #include "MagickCore/delegate-private.h"
55 #include "MagickCore/draw.h"
56 #include "MagickCore/exception.h"
57 #include "MagickCore/exception-private.h"
58 #include "MagickCore/locale-private.h"
59 #include "MagickCore/log-private.h"
60 #include "MagickCore/magic-private.h"
61 #include "MagickCore/magick.h"
62 #include "MagickCore/magick-private.h"
63 #include "MagickCore/memory_.h"
64 #include "MagickCore/mime-private.h"
65 #include "MagickCore/module.h"
66 #include "MagickCore/module-private.h"
67 #include "MagickCore/nt-base-private.h"
68 #include "MagickCore/nt-feature.h"
69 #include "MagickCore/opencl-private.h"
70 #include "MagickCore/option-private.h"
71 #include "MagickCore/random-private.h"
72 #include "MagickCore/registry.h"
73 #include "MagickCore/registry-private.h"
74 #include "MagickCore/resource_.h"
75 #include "MagickCore/resource-private.h"
76 #include "MagickCore/policy.h"
77 #include "MagickCore/policy-private.h"
78 #include "MagickCore/semaphore.h"
79 #include "MagickCore/semaphore-private.h"
80 #include "MagickCore/signature-private.h"
81 #include "MagickCore/splay-tree.h"
82 #include "MagickCore/string_.h"
83 #include "MagickCore/string-private.h"
84 #include "MagickCore/thread_.h"
85 #include "MagickCore/thread-private.h"
86 #include "MagickCore/type-private.h"
87 #include "MagickCore/token.h"
88 #include "MagickCore/utility.h"
89 #include "MagickCore/utility-private.h"
90 #include "MagickCore/xwindow-private.h"
91
92 /*
93 Define declarations.
94 */
95 #if !defined(MAGICKCORE_RETSIGTYPE)
96 # define MAGICKCORE_RETSIGTYPE void
97 #endif
98 #if !defined(SIG_DFL)
99 # define SIG_DFL ((SignalHandler *) 0)
100 #endif
101 #if !defined(SIG_ERR)
102 # define SIG_ERR ((SignalHandler *) -1)
103 #endif
104 #if !defined(SIGMAX)
105 #define SIGMAX 64
106 #endif
107
108 /*
109 Typedef declarations.
110 */
111 typedef MAGICKCORE_RETSIGTYPE
112 SignalHandler(int);
113
114 /*
115 Global declarations.
116 */
117 static SemaphoreInfo
118 *magick_semaphore = (SemaphoreInfo *) NULL;
119
120 static SignalHandler
121 *signal_handlers[SIGMAX] = { (SignalHandler *) NULL };
122
123 static SplayTreeInfo
124 *magick_list = (SplayTreeInfo *) NULL;
125
126 static volatile MagickBooleanType
127 instantiate_magickcore = MagickFalse,
128 magickcore_signal_in_progress = MagickFalse;
129
130 /*
131 Forward declarations.
132 */
133 static MagickBooleanType
134 IsMagickTreeInstantiated(ExceptionInfo *);
135
136 /*
137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
138 % %
139 % %
140 % %
141 % A c q u i r e M a g i c k I n f o %
142 % %
143 % %
144 % %
145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146 %
147 % AcquireMagickInfo() allocates a MagickInfo structure and initializes the
148 % members to default values.
149 %
150 % The format of the AcquireMagickInfo method is:
151 %
152 % MagickInfo *AcquireMagickInfo(const char *module, const char *name,)
153 %
154 % A description of each parameter follows:
155 %
156 % o module: a character string that represents the module associated
157 % with the MagickInfo structure.
158 %
159 % o name: a character string that represents the image format associated
160 % with the MagickInfo structure.
161 %
162 % o description: a character string that represents the image format
163 % associated with the MagickInfo structure.
164 %
165 */
AcquireMagickInfo(const char * module,const char * name,const char * description)166 MagickExport MagickInfo *AcquireMagickInfo(const char *module,
167 const char *name, const char *description)
168 {
169 MagickInfo
170 *magick_info;
171
172 assert(module != (const char *) NULL);
173 assert(name != (const char *) NULL);
174 assert(description != (const char *) NULL);
175 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
176 magick_info=(MagickInfo *) AcquireMagickMemory(sizeof(*magick_info));
177 if (magick_info == (MagickInfo *) NULL)
178 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
179 (void) ResetMagickMemory(magick_info,0,sizeof(*magick_info));
180 magick_info->module=ConstantString(module);
181 magick_info->name=ConstantString(name);
182 magick_info->description=ConstantString(description);
183 magick_info->flags=CoderAdjoinFlag | CoderBlobSupportFlag |
184 CoderDecoderThreadSupportFlag | CoderEncoderThreadSupportFlag |
185 CoderUseExtensionFlag;
186 magick_info->signature=MagickCoreSignature;
187 return(magick_info);
188 }
189
190 /*
191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
192 % %
193 % %
194 % %
195 + G e t I m a g e D e c o d e r %
196 % %
197 % %
198 % %
199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
200 %
201 % GetImageDecoder() returns the image decoder.
202 %
203 % The format of the GetImageDecoder method is:
204 %
205 % DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
206 %
207 % A description of each parameter follows:
208 %
209 % o magick_info: The magick info.
210 %
211 */
GetImageDecoder(const MagickInfo * magick_info)212 MagickExport DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
213 {
214 assert(magick_info != (MagickInfo *) NULL);
215 assert(magick_info->signature == MagickCoreSignature);
216 return(magick_info->decoder);
217 }
218
219 /*
220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221 % %
222 % %
223 % %
224 + G e t I m a g e E n c o d e r %
225 % %
226 % %
227 % %
228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
229 %
230 % GetImageEncoder() returns the image encoder.
231 %
232 % The format of the GetImageEncoder method is:
233 %
234 % EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
235 %
236 % A description of each parameter follows:
237 %
238 % o magick_info: The magick info.
239 %
240 */
GetImageEncoder(const MagickInfo * magick_info)241 MagickExport EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
242 {
243 assert(magick_info != (MagickInfo *) NULL);
244 assert(magick_info->signature == MagickCoreSignature);
245 return(magick_info->encoder);
246 }
247
248 /*
249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
250 % %
251 % %
252 % %
253 + G e t I m a g e M a g i c k %
254 % %
255 % %
256 % %
257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
258 %
259 % GetImageMagick() searches for an image format that matches the specified
260 % magick string. If one is found, MagickTrue is returned otherwise
261 % MagickFalse.
262 %
263 % The format of the GetImageMagick method is:
264 %
265 % MagickBooleanType GetImageMagick(const unsigned char *magick,
266 % const size_t length,char *format)
267 %
268 % A description of each parameter follows:
269 %
270 % o magick: the image format we are searching for.
271 %
272 % o length: the length of the binary string.
273 %
274 % o format: the image format as determined by the magick bytes.
275 %
276 */
GetImageMagick(const unsigned char * magick,const size_t length,char * format)277 MagickExport MagickBooleanType GetImageMagick(const unsigned char *magick,
278 const size_t length,char *format)
279 {
280 ExceptionInfo
281 *exception;
282
283 MagickBooleanType
284 status;
285
286 register const MagickInfo
287 *p;
288
289 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
290 assert(magick != (const unsigned char *) NULL);
291 exception=AcquireExceptionInfo();
292 p=GetMagickInfo("*",exception);
293 exception=DestroyExceptionInfo(exception);
294 if (p == (const MagickInfo *) NULL)
295 return(MagickFalse);
296 status=MagickFalse;
297 LockSemaphoreInfo(magick_semaphore);
298 ResetSplayTreeIterator(magick_list);
299 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
300 while (p != (const MagickInfo *) NULL)
301 {
302 if ((p->magick != (IsImageFormatHandler *) NULL) &&
303 (p->magick(magick,length) != 0))
304 {
305 status=MagickTrue;
306 (void) CopyMagickString(format,p->name,MagickPathExtent);
307 break;
308 }
309 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
310 }
311 UnlockSemaphoreInfo(magick_semaphore);
312 return(status);
313 }
314
315 /*
316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
317 % %
318 % %
319 % %
320 + G e t M a g i c k A d j o i n %
321 % %
322 % %
323 % %
324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
325 %
326 % GetMagickAdjoin() returns MagickTrue if the magick adjoin is MagickTrue.
327 %
328 % The format of the GetMagickAdjoin method is:
329 %
330 % MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
331 %
332 % A description of each parameter follows:
333 %
334 % o magick_info: The magick info.
335 %
336 */
GetMagickAdjoin(const MagickInfo * magick_info)337 MagickExport MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
338 {
339 assert(magick_info != (MagickInfo *) NULL);
340 assert(magick_info->signature == MagickCoreSignature);
341 return(((magick_info->flags & CoderAdjoinFlag) == 0) ? MagickFalse :
342 MagickTrue);
343 }
344
345 /*
346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
347 % %
348 % %
349 % %
350 + G e t M a g i c k B l o b S u p p o r t %
351 % %
352 % %
353 % %
354 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
355 %
356 % GetMagickBlobSupport() returns MagickTrue if the magick supports blobs.
357 %
358 % The format of the GetMagickBlobSupport method is:
359 %
360 % MagickBooleanType GetMagickBlobSupport(const MagickInfo *magick_info)
361 %
362 % A description of each parameter follows:
363 %
364 % o magick_info: The magick info.
365 %
366 */
GetMagickBlobSupport(const MagickInfo * magick_info)367 MagickExport MagickBooleanType GetMagickBlobSupport(
368 const MagickInfo *magick_info)
369 {
370 assert(magick_info != (MagickInfo *) NULL);
371 assert(magick_info->signature == MagickCoreSignature);
372 return(((magick_info->flags & CoderBlobSupportFlag) == 0) ? MagickFalse :
373 MagickTrue);
374 }
375
376 /*
377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
378 % %
379 % %
380 % %
381 + G e t M a g i c k D e c o d e r T h r e a d S u p p o r t %
382 % %
383 % %
384 % %
385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
386 %
387 % GetMagickDecoderThreadSupport() returns MagickTrue if the decoder supports
388 % threads.
389 %
390 % The format of the GetMagickDecoderThreadSupport method is:
391 %
392 % MagickStatusType GetMagickDecoderThreadSupport(
393 % const MagickInfo *magick_info)
394 %
395 % A description of each parameter follows:
396 %
397 % o magick_info: The magick info.
398 %
399 */
GetMagickDecoderThreadSupport(const MagickInfo * magick_info)400 MagickExport MagickBooleanType GetMagickDecoderThreadSupport(
401 const MagickInfo *magick_info)
402 {
403 assert(magick_info != (MagickInfo *) NULL);
404 assert(magick_info->signature == MagickCoreSignature);
405 return(((magick_info->flags & CoderDecoderThreadSupportFlag) == 0) ?
406 MagickFalse : MagickTrue);
407 }
408
409 /*
410 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
411 % %
412 % %
413 % %
414 + G e t M a g i c k D e s c r i p t i o n %
415 % %
416 % %
417 % %
418 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
419 %
420 % GetMagickDescription() returns the magick description.
421 %
422 % The format of the GetMagickDescription method is:
423 %
424 % const char *GetMagickDescription(const MagickInfo *magick_info)
425 %
426 % A description of each parameter follows:
427 %
428 % o magick_info: The magick info.
429 %
430 */
GetMagickDescription(const MagickInfo * magick_info)431 MagickExport const char *GetMagickDescription(const MagickInfo *magick_info)
432 {
433 assert(magick_info != (MagickInfo *) NULL);
434 assert(magick_info->signature == MagickCoreSignature);
435 return(magick_info->description);
436 }
437
438 /*
439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
440 % %
441 % %
442 % %
443 + G e t M a g i c k E n c o d e r T h r e a d S u p p o r t %
444 % %
445 % %
446 % %
447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
448 %
449 % GetMagickEncoderThreadSupport() returns MagickTrue if the encoder supports
450 % threads.
451 %
452 % The format of the GetMagickEncoderThreadSupport method is:
453 %
454 % MagickStatusType GetMagickEncoderThreadSupport(
455 % const MagickInfo *magick_info)
456 %
457 % A description of each parameter follows:
458 %
459 % o magick_info: The magick info.
460 %
461 */
GetMagickEncoderThreadSupport(const MagickInfo * magick_info)462 MagickExport MagickBooleanType GetMagickEncoderThreadSupport(
463 const MagickInfo *magick_info)
464 {
465 assert(magick_info != (MagickInfo *) NULL);
466 assert(magick_info->signature == MagickCoreSignature);
467 return(((magick_info->flags & CoderDecoderThreadSupportFlag) == 0) ?
468 MagickFalse : MagickTrue);
469 }
470
471 /*
472 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
473 % %
474 % %
475 % %
476 + G e t M a g i c k E n d i a n S u p p o r t %
477 % %
478 % %
479 % %
480 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
481 %
482 % GetMagickEndianSupport() returns the MagickTrue if the coder respects
483 % endianness other than MSBEndian.
484 %
485 % The format of the GetMagickEndianSupport method is:
486 %
487 % MagickBooleanType GetMagickEndianSupport(const MagickInfo *magick_info)
488 %
489 % A description of each parameter follows:
490 %
491 % o magick_info: The magick info.
492 %
493 */
GetMagickEndianSupport(const MagickInfo * magick_info)494 MagickExport MagickBooleanType GetMagickEndianSupport(
495 const MagickInfo *magick_info)
496 {
497 assert(magick_info != (MagickInfo *) NULL);
498 assert(magick_info->signature == MagickCoreSignature);
499 return(((magick_info->flags & CoderEndianSupportFlag) == 0) ? MagickFalse :
500 MagickTrue);
501 }
502
503 /*
504 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
505 % %
506 % %
507 % %
508 + G e t M a g i c k I n f o %
509 % %
510 % %
511 % %
512 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
513 %
514 % GetMagickInfo() returns a pointer MagickInfo structure that matches
515 % the specified name. If name is NULL, the head of the image format list
516 % is returned.
517 %
518 % The format of the GetMagickInfo method is:
519 %
520 % const MagickInfo *GetMagickInfo(const char *name,Exception *exception)
521 %
522 % A description of each parameter follows:
523 %
524 % o name: the image format we are looking for.
525 %
526 % o exception: return any errors or warnings in this structure.
527 %
528 */
GetMagickInfo(const char * name,ExceptionInfo * exception)529 MagickExport const MagickInfo *GetMagickInfo(const char *name,
530 ExceptionInfo *exception)
531 {
532 register const MagickInfo
533 *p;
534
535 assert(exception != (ExceptionInfo *) NULL);
536 if (IsMagickTreeInstantiated(exception) == MagickFalse)
537 return((const MagickInfo *) NULL);
538 #if defined(MAGICKCORE_MODULES_SUPPORT)
539 if ((name != (const char *) NULL) && (LocaleCompare(name,"*") == 0))
540 (void) OpenModules(exception);
541 #endif
542 /*
543 Find name in list.
544 */
545 LockSemaphoreInfo(magick_semaphore);
546 ResetSplayTreeIterator(magick_list);
547 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
548 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
549 {
550 ResetSplayTreeIterator(magick_list);
551 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
552 UnlockSemaphoreInfo(magick_semaphore);
553 return(p);
554 }
555 while (p != (const MagickInfo *) NULL)
556 {
557 if (LocaleCompare(p->name,name) == 0)
558 break;
559 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
560 }
561 #if defined(MAGICKCORE_MODULES_SUPPORT)
562 if (p == (const MagickInfo *) NULL)
563 {
564 if (*name != '\0')
565 (void) OpenModule(name,exception);
566 ResetSplayTreeIterator(magick_list);
567 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
568 while (p != (const MagickInfo *) NULL)
569 {
570 if (LocaleCompare(p->name,name) == 0)
571 break;
572 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
573 }
574 }
575 #endif
576 UnlockSemaphoreInfo(magick_semaphore);
577 return(p);
578 }
579
580 /*
581 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
582 % %
583 % %
584 % %
585 + G e t M a g i c k I n f o L i s t %
586 % %
587 % %
588 % %
589 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
590 %
591 % GetMagickInfoList() returns any image formats that match the specified
592 % pattern.
593 %
594 % The format of the GetMagickInfoList function is:
595 %
596 % const MagickInfo **GetMagickInfoList(const char *pattern,
597 % size_t *number_formats,ExceptionInfo *exception)
598 %
599 % A description of each parameter follows:
600 %
601 % o pattern: Specifies a pointer to a text string containing a pattern.
602 %
603 % o number_formats: This integer returns the number of formats in the list.
604 %
605 % o exception: return any errors or warnings in this structure.
606 %
607 */
608
609 #if defined(__cplusplus) || defined(c_plusplus)
610 extern "C" {
611 #endif
612
MagickInfoCompare(const void * x,const void * y)613 static int MagickInfoCompare(const void *x,const void *y)
614 {
615 const MagickInfo
616 **p,
617 **q;
618
619 p=(const MagickInfo **) x,
620 q=(const MagickInfo **) y;
621 return(LocaleCompare((*p)->name,(*q)->name));
622 }
623
624 #if defined(__cplusplus) || defined(c_plusplus)
625 }
626 #endif
627
GetMagickInfoList(const char * pattern,size_t * number_formats,ExceptionInfo * exception)628 MagickExport const MagickInfo **GetMagickInfoList(const char *pattern,
629 size_t *number_formats,ExceptionInfo *exception)
630 {
631 const MagickInfo
632 **formats;
633
634 register const MagickInfo
635 *p;
636
637 register ssize_t
638 i;
639
640 /*
641 Allocate magick list.
642 */
643 assert(pattern != (char *) NULL);
644 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
645 assert(number_formats != (size_t *) NULL);
646 *number_formats=0;
647 p=GetMagickInfo("*",exception);
648 if (p == (const MagickInfo *) NULL)
649 return((const MagickInfo **) NULL);
650 formats=(const MagickInfo **) AcquireQuantumMemory((size_t)
651 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
652 if (formats == (const MagickInfo **) NULL)
653 return((const MagickInfo **) NULL);
654 /*
655 Generate magick list.
656 */
657 LockSemaphoreInfo(magick_semaphore);
658 ResetSplayTreeIterator(magick_list);
659 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
660 for (i=0; p != (const MagickInfo *) NULL; )
661 {
662 if ((GetMagickStealth(p) == MagickFalse) &&
663 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
664 formats[i++]=p;
665 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
666 }
667 UnlockSemaphoreInfo(magick_semaphore);
668 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickInfoCompare);
669 formats[i]=(MagickInfo *) NULL;
670 *number_formats=(size_t) i;
671 return(formats);
672 }
673
674 /*
675 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
676 % %
677 % %
678 % %
679 + G e t M a g i c k L i s t %
680 % %
681 % %
682 % %
683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
684 %
685 % GetMagickList() returns any image formats that match the specified pattern.
686 %
687 % The format of the GetMagickList function is:
688 %
689 % char **GetMagickList(const char *pattern,size_t *number_formats,
690 % ExceptionInfo *exception)
691 %
692 % A description of each parameter follows:
693 %
694 % o pattern: Specifies a pointer to a text string containing a pattern.
695 %
696 % o number_formats: This integer returns the number of formats in the list.
697 %
698 % o exception: return any errors or warnings in this structure.
699 %
700 */
701
702 #if defined(__cplusplus) || defined(c_plusplus)
703 extern "C" {
704 #endif
705
MagickCompare(const void * x,const void * y)706 static int MagickCompare(const void *x,const void *y)
707 {
708 register const char
709 **p,
710 **q;
711
712 p=(const char **) x;
713 q=(const char **) y;
714 return(LocaleCompare(*p,*q));
715 }
716
717 #if defined(__cplusplus) || defined(c_plusplus)
718 }
719 #endif
720
GetMagickList(const char * pattern,size_t * number_formats,ExceptionInfo * exception)721 MagickExport char **GetMagickList(const char *pattern,
722 size_t *number_formats,ExceptionInfo *exception)
723 {
724 char
725 **formats;
726
727 register const MagickInfo
728 *p;
729
730 register ssize_t
731 i;
732
733 /*
734 Allocate magick list.
735 */
736 assert(pattern != (char *) NULL);
737 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
738 assert(number_formats != (size_t *) NULL);
739 *number_formats=0;
740 p=GetMagickInfo("*",exception);
741 if (p == (const MagickInfo *) NULL)
742 return((char **) NULL);
743 formats=(char **) AcquireQuantumMemory((size_t)
744 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
745 if (formats == (char **) NULL)
746 return((char **) NULL);
747 LockSemaphoreInfo(magick_semaphore);
748 ResetSplayTreeIterator(magick_list);
749 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
750 for (i=0; p != (const MagickInfo *) NULL; )
751 {
752 if ((GetMagickStealth(p) == MagickFalse) &&
753 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
754 formats[i++]=ConstantString(p->name);
755 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
756 }
757 UnlockSemaphoreInfo(magick_semaphore);
758 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickCompare);
759 formats[i]=(char *) NULL;
760 *number_formats=(size_t) i;
761 return(formats);
762 }
763
764 /*
765 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
766 % %
767 % %
768 % %
769 + G e t M a g i c k M i m e T y p e %
770 % %
771 % %
772 % %
773 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
774 %
775 % GetMagickMimeType() returns the magick mime type.
776 %
777 % The format of the GetMagickMimeType method is:
778 %
779 % const char *GetMagickMimeType(const MagickInfo *magick_info)
780 %
781 % A description of each parameter follows:
782 %
783 % o magick_info: The magick info.
784 %
785 */
GetMagickMimeType(const MagickInfo * magick_info)786 MagickExport const char *GetMagickMimeType(const MagickInfo *magick_info)
787 {
788 assert(magick_info != (MagickInfo *) NULL);
789 assert(magick_info->signature == MagickCoreSignature);
790 return(magick_info->mime_type);
791 }
792
793 /*
794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
795 % %
796 % %
797 % %
798 % G e t M a g i c k P r e c i s i o n %
799 % %
800 % %
801 % %
802 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
803 %
804 % GetMagickPrecision() returns the maximum number of significant digits to be
805 % printed.
806 %
807 % The format of the GetMagickPrecision method is:
808 %
809 % int GetMagickPrecision(void)
810 %
811 */
GetMagickPrecision(void)812 MagickExport int GetMagickPrecision(void)
813 {
814 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
815 return(SetMagickPrecision(0));
816 }
817
818 /*
819 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
820 % %
821 % %
822 % %
823 + G e t M a g i c k R a w S u p p o r t %
824 % %
825 % %
826 % %
827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
828 %
829 % GetMagickRawSupport() returns the MagickTrue if the coder is a raw format.
830 %
831 % The format of the GetMagickRawSupport method is:
832 %
833 % MagickBooleanType GetMagickRawSupport(const MagickInfo *magick_info)
834 %
835 % A description of each parameter follows:
836 %
837 % o magick_info: The magick info.
838 %
839 */
GetMagickRawSupport(const MagickInfo * magick_info)840 MagickExport MagickBooleanType GetMagickRawSupport(
841 const MagickInfo *magick_info)
842 {
843 assert(magick_info != (MagickInfo *) NULL);
844 assert(magick_info->signature == MagickCoreSignature);
845 return(((magick_info->flags & CoderRawSupportFlag) == 0) ? MagickFalse :
846 MagickTrue);
847 }
848
849 /*
850 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
851 % %
852 % %
853 % %
854 + G e t M a g i c k S e e k a b l e S t r e a m %
855 % %
856 % %
857 % %
858 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
859 %
860 % GetMagickSeekableStream() returns MagickTrue if the magick supports a
861 % seekable stream.
862 %
863 % The format of the GetMagickSeekableStream method is:
864 %
865 % MagickBooleanType GetMagickSeekableStream(const MagickInfo *magick_info)
866 %
867 % A description of each parameter follows:
868 %
869 % o magick_info: The magick info.
870 %
871 */
GetMagickSeekableStream(const MagickInfo * magick_info)872 MagickExport MagickBooleanType GetMagickSeekableStream(
873 const MagickInfo *magick_info)
874 {
875 assert(magick_info != (MagickInfo *) NULL);
876 assert(magick_info->signature == MagickCoreSignature);
877 return(((magick_info->flags & CoderSeekableStreamFlag) == 0) ? MagickFalse :
878 MagickTrue);
879 }
880
881 /*
882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
883 % %
884 % %
885 % %
886 + G e t M a g i c k S t e a l t h %
887 % %
888 % %
889 % %
890 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
891 %
892 % GetMagickStealth() returns MagickTrue if the magick is a stealth coder.
893 %
894 % The format of the GetMagickStealth method is:
895 %
896 % MagickBooleanType GetMagickStealth(const MagickInfo *magick_info)
897 %
898 % A description of each parameter follows:
899 %
900 % o magick_info: The magick info.
901 %
902 */
GetMagickStealth(const MagickInfo * magick_info)903 MagickExport MagickBooleanType GetMagickStealth(const MagickInfo *magick_info)
904 {
905 assert(magick_info != (MagickInfo *) NULL);
906 assert(magick_info->signature == MagickCoreSignature);
907 return(((magick_info->flags & CoderStealthFlag) == 0) ? MagickFalse :
908 MagickTrue);
909 }
910
911 /*
912 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
913 % %
914 % %
915 % %
916 + G e t M a g i c k U s e E x t e n s i o n %
917 % %
918 % %
919 % %
920 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
921 %
922 % GetMagickUseExtension() returns MagickTrue if the magick can use the
923 % extension of the format if the format return by IsImageFormatHandler uses
924 % the same coder.
925 %
926 % The format of the GetMagickUseExtension method is:
927 %
928 % MagickBooleanType GetMagickUseExtension(const MagickInfo *magick_info)
929 %
930 % A description of each parameter follows:
931 %
932 % o magick_info: The magick info.
933 %
934 */
GetMagickUseExtension(const MagickInfo * magick_info)935 MagickExport MagickBooleanType GetMagickUseExtension(
936 const MagickInfo *magick_info)
937 {
938 assert(magick_info != (MagickInfo *) NULL);
939 assert(magick_info->signature == MagickCoreSignature);
940 return(((magick_info->flags & CoderUseExtensionFlag) == 0) ? MagickFalse :
941 MagickTrue);
942 }
943
944 /*
945 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
946 % %
947 % %
948 % %
949 + I s M a g i c k T r e e I n s t a n t i a t e d %
950 % %
951 % %
952 % %
953 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
954 %
955 % IsMagickTreeInstantiated() determines if the magick tree is instantiated.
956 % If not, it instantiates the tree and returns it.
957 %
958 % The format of the IsMagickTreeInstantiated() method is:
959 %
960 % IsMagickTreeInstantiated(Exceptioninfo *exception)
961 %
962 % A description of each parameter follows.
963 %
964 % o exception: return any errors or warnings in this structure.
965 %
966 */
967
DestroyMagickNode(void * magick_info)968 static void *DestroyMagickNode(void *magick_info)
969 {
970 register MagickInfo
971 *p;
972
973 p=(MagickInfo *) magick_info;
974 if (p->module != (char *) NULL)
975 p->module=DestroyString(p->module);
976 if (p->note != (char *) NULL)
977 p->note=DestroyString(p->note);
978 if (p->mime_type != (char *) NULL)
979 p->mime_type=DestroyString(p->mime_type);
980 if (p->version != (char *) NULL)
981 p->version=DestroyString(p->version);
982 if (p->description != (char *) NULL)
983 p->description=DestroyString(p->description);
984 if (p->name != (char *) NULL)
985 p->name=DestroyString(p->name);
986 if (p->semaphore != (SemaphoreInfo *) NULL)
987 RelinquishSemaphoreInfo(&p->semaphore);
988 return(RelinquishMagickMemory(p));
989 }
990
IsMagickTreeInstantiated(ExceptionInfo * exception)991 static MagickBooleanType IsMagickTreeInstantiated(ExceptionInfo *exception)
992 {
993 (void) exception;
994 if (magick_list == (SplayTreeInfo *) NULL)
995 {
996 if (magick_semaphore == (SemaphoreInfo *) NULL)
997 ActivateSemaphoreInfo(&magick_semaphore);
998 LockSemaphoreInfo(magick_semaphore);
999 if (magick_list == (SplayTreeInfo *) NULL)
1000 {
1001 magick_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *))
1002 NULL,DestroyMagickNode);
1003 if (magick_list == (SplayTreeInfo *) NULL)
1004 ThrowFatalException(ResourceLimitFatalError,
1005 "MemoryAllocationFailed");
1006 #if defined(MAGICKCORE_MODULES_SUPPORT)
1007 (void) GetModuleInfo((char *) NULL,exception);
1008 #endif
1009 #if !defined(MAGICKCORE_BUILD_MODULES)
1010 RegisterStaticModules();
1011 #endif
1012 }
1013 UnlockSemaphoreInfo(magick_semaphore);
1014 }
1015 return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
1016 }
1017
1018 /*
1019 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1020 % %
1021 % %
1022 % %
1023 + I s M a g i c k C o n f l i c t %
1024 % %
1025 % %
1026 % %
1027 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1028 %
1029 % IsMagickConflict() returns MagickTrue if the image format conflicts with a
1030 % logical drive (.e.g. X:).
1031 %
1032 % The format of the IsMagickConflict method is:
1033 %
1034 % MagickBooleanType IsMagickConflict(const char *magick)
1035 %
1036 % A description of each parameter follows:
1037 %
1038 % o magick: Specifies the image format.
1039 %
1040 */
IsMagickConflict(const char * magick)1041 MagickPrivate MagickBooleanType IsMagickConflict(const char *magick)
1042 {
1043 assert(magick != (char *) NULL);
1044 #if defined(macintosh)
1045 return(MACIsMagickConflict(magick));
1046 #elif defined(vms)
1047 return(VMSIsMagickConflict(magick));
1048 #elif defined(MAGICKCORE_WINDOWS_SUPPORT)
1049 return(NTIsMagickConflict(magick));
1050 #else
1051 return(MagickFalse);
1052 #endif
1053 }
1054
1055 /*
1056 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1057 % %
1058 % %
1059 % %
1060 + L i s t M a g i c k I n f o %
1061 % %
1062 % %
1063 % %
1064 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1065 %
1066 % ListMagickInfo() lists the image formats to a file.
1067 %
1068 % The format of the ListMagickInfo method is:
1069 %
1070 % MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
1071 %
1072 % A description of each parameter follows.
1073 %
1074 % o file: A file handle.
1075 %
1076 % o exception: return any errors or warnings in this structure.
1077 %
1078 */
ListMagickInfo(FILE * file,ExceptionInfo * exception)1079 MagickExport MagickBooleanType ListMagickInfo(FILE *file,
1080 ExceptionInfo *exception)
1081 {
1082 const MagickInfo
1083 **magick_info;
1084
1085 register ssize_t
1086 i;
1087
1088 size_t
1089 number_formats;
1090
1091 ssize_t
1092 j;
1093
1094 if (file == (FILE *) NULL)
1095 file=stdout;
1096 magick_info=GetMagickInfoList("*",&number_formats,exception);
1097 if (magick_info == (const MagickInfo **) NULL)
1098 return(MagickFalse);
1099 ClearMagickException(exception);
1100 #if !defined(MAGICKCORE_MODULES_SUPPORT)
1101 (void) FormatLocaleFile(file," Format Mode Description\n");
1102 #else
1103 (void) FormatLocaleFile(file," Format Module Mode Description\n");
1104 #endif
1105 (void) FormatLocaleFile(file,
1106 "--------------------------------------------------------"
1107 "-----------------------\n");
1108 for (i=0; i < (ssize_t) number_formats; i++)
1109 {
1110 if (GetMagickStealth(magick_info[i]) != MagickFalse)
1111 continue;
1112 (void) FormatLocaleFile(file,"%9s%c ",
1113 magick_info[i]->name != (char *) NULL ? magick_info[i]->name : "",
1114 GetMagickBlobSupport(magick_info[i]) != MagickFalse ? '*' : ' ');
1115 #if defined(MAGICKCORE_MODULES_SUPPORT)
1116 {
1117 char
1118 module[MagickPathExtent];
1119
1120 *module='\0';
1121 if (magick_info[i]->module != (char *) NULL)
1122 (void) CopyMagickString(module,magick_info[i]->module,MagickPathExtent);
1123 (void) ConcatenateMagickString(module," ",MagickPathExtent);
1124 module[9]='\0';
1125 (void) FormatLocaleFile(file,"%9s ",module);
1126 }
1127 #endif
1128 (void) FormatLocaleFile(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
1129 magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
1130 GetMagickAdjoin(magick_info[i]) != MagickFalse ? '+' : '-');
1131 if (magick_info[i]->description != (char *) NULL)
1132 (void) FormatLocaleFile(file," %s",magick_info[i]->description);
1133 if (magick_info[i]->version != (char *) NULL)
1134 (void) FormatLocaleFile(file," (%s)",magick_info[i]->version);
1135 (void) FormatLocaleFile(file,"\n");
1136 if (magick_info[i]->note != (char *) NULL)
1137 {
1138 char
1139 **text;
1140
1141 text=StringToList(magick_info[i]->note);
1142 if (text != (char **) NULL)
1143 {
1144 for (j=0; text[j] != (char *) NULL; j++)
1145 {
1146 (void) FormatLocaleFile(file," %s\n",text[j]);
1147 text[j]=DestroyString(text[j]);
1148 }
1149 text=(char **) RelinquishMagickMemory(text);
1150 }
1151 }
1152 }
1153 (void) FormatLocaleFile(file,"\n* native blob support\n");
1154 (void) FormatLocaleFile(file,"r read support\n");
1155 (void) FormatLocaleFile(file,"w write support\n");
1156 (void) FormatLocaleFile(file,"+ support for multiple images\n");
1157 (void) fflush(file);
1158 magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1159 magick_info);
1160 return(MagickTrue);
1161 }
1162
1163 /*
1164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1165 % %
1166 % %
1167 % %
1168 % I s M a g i c k C o r e I n s t a n t i a t e d %
1169 % %
1170 % %
1171 % %
1172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1173 %
1174 % IsMagickCoreInstantiated() returns MagickTrue if the ImageMagick environment
1175 % is currently instantiated: MagickCoreGenesis() has been called but
1176 % MagickDestroy() has not.
1177 %
1178 % The format of the IsMagickCoreInstantiated method is:
1179 %
1180 % MagickBooleanType IsMagickCoreInstantiated(void)
1181 %
1182 */
IsMagickCoreInstantiated(void)1183 MagickExport MagickBooleanType IsMagickCoreInstantiated(void)
1184 {
1185 return(instantiate_magickcore);
1186 }
1187
1188 /*
1189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1190 % %
1191 % %
1192 % %
1193 + M a g i c k C o m p o n e n t G e n e s i s %
1194 % %
1195 % %
1196 % %
1197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1198 %
1199 % MagickComponentGenesis() instantiates the magick component.
1200 %
1201 % The format of the MagickComponentGenesis method is:
1202 %
1203 % MagickBooleanType MagickComponentGenesis(void)
1204 %
1205 */
MagickComponentGenesis(void)1206 MagickPrivate MagickBooleanType MagickComponentGenesis(void)
1207 {
1208 if (magick_semaphore == (SemaphoreInfo *) NULL)
1209 magick_semaphore=AcquireSemaphoreInfo();
1210 return(MagickTrue);
1211 }
1212
1213 /*
1214 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1215 % %
1216 % %
1217 % %
1218 + M a g i c k C o m p o n e n t T e r m i n u s %
1219 % %
1220 % %
1221 % %
1222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1223 %
1224 % MagickComponentTerminus() destroys the magick component.
1225 %
1226 % The format of the MagickComponentTerminus method is:
1227 %
1228 % void MagickComponentTerminus(void)
1229 %
1230 */
MagickComponentTerminus(void)1231 MagickPrivate void MagickComponentTerminus(void)
1232 {
1233 if (magick_semaphore == (SemaphoreInfo *) NULL)
1234 ActivateSemaphoreInfo(&magick_semaphore);
1235 LockSemaphoreInfo(magick_semaphore);
1236 if (magick_list != (SplayTreeInfo *) NULL)
1237 magick_list=DestroySplayTree(magick_list);
1238 UnlockSemaphoreInfo(magick_semaphore);
1239 RelinquishSemaphoreInfo(&magick_semaphore);
1240 }
1241
1242 /*
1243 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1244 % %
1245 % %
1246 % %
1247 % M a g i c k C o r e G e n e s i s %
1248 % %
1249 % %
1250 % %
1251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1252 %
1253 % MagickCoreGenesis() initializes the MagickCore environment.
1254 %
1255 % The format of the MagickCoreGenesis function is:
1256 %
1257 % MagickCoreGenesis(const char *path,
1258 % const MagickBooleanType establish_signal_handlers)
1259 %
1260 % A description of each parameter follows:
1261 %
1262 % o path: the execution path of the current ImageMagick client.
1263 %
1264 % o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1265 % signal handlers for common signals.
1266 %
1267 */
1268
SetMagickSignalHandler(int signal_number,SignalHandler * handler)1269 static SignalHandler *SetMagickSignalHandler(int signal_number,
1270 SignalHandler *handler)
1271 {
1272 #if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1273 int
1274 status;
1275
1276 sigset_t
1277 mask;
1278
1279 struct sigaction
1280 action,
1281 previous_action;
1282
1283 sigemptyset(&mask);
1284 sigaddset(&mask,signal_number);
1285 sigprocmask(SIG_BLOCK,&mask,NULL);
1286 action.sa_mask=mask;
1287 action.sa_handler=handler;
1288 action.sa_flags=0;
1289 #if defined(SA_INTERRUPT)
1290 action.sa_flags|=SA_INTERRUPT;
1291 #endif
1292 status=sigaction(signal_number,&action,&previous_action);
1293 if (status < 0)
1294 return(SIG_ERR);
1295 sigprocmask(SIG_UNBLOCK,&mask,NULL);
1296 return(previous_action.sa_handler);
1297 #else
1298 return(signal(signal_number,handler));
1299 #endif
1300 }
1301
MagickSignalHandler(int signal_number)1302 static void MagickSignalHandler(int signal_number)
1303 {
1304 if (magickcore_signal_in_progress != MagickFalse)
1305 (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
1306 magickcore_signal_in_progress=MagickTrue;
1307 AsynchronousResourceComponentTerminus();
1308 #if defined(SIGQUIT)
1309 if (signal_number == SIGQUIT)
1310 abort();
1311 #endif
1312 #if defined(SIGABRT)
1313 if (signal_number == SIGABRT)
1314 abort();
1315 #endif
1316 #if defined(SIGFPE)
1317 if (signal_number == SIGFPE)
1318 abort();
1319 #endif
1320 #if defined(SIGXCPU)
1321 if (signal_number == SIGXCPU)
1322 abort();
1323 #endif
1324 #if defined(SIGXFSZ)
1325 if (signal_number == SIGXFSZ)
1326 abort();
1327 #endif
1328 #if defined(SIGSEGV)
1329 if (signal_number == SIGSEGV)
1330 abort();
1331 #endif
1332 #if !defined(MAGICKCORE_HAVE__EXIT)
1333 exit(signal_number);
1334 #else
1335 #if defined(SIGHUP)
1336 if (signal_number == SIGHUP)
1337 _exit(signal_number);
1338 #endif
1339 #if defined(SIGINT)
1340 if (signal_number == SIGINT)
1341 _exit(signal_number);
1342 #endif
1343 #if defined(SIGTERM)
1344 if (signal_number == SIGTERM)
1345 _exit(signal_number);
1346 #endif
1347 #if defined(MAGICKCORE_HAVE_RAISE)
1348 if (signal_handlers[signal_number] != MagickSignalHandler)
1349 raise(signal_number);
1350 #endif
1351 _exit(signal_number); /* do not invoke registered atexit() methods */
1352 #endif
1353 }
1354
RegisterMagickSignalHandler(int signal_number)1355 static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1356 {
1357 SignalHandler
1358 *handler;
1359
1360 handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1361 if (handler == SIG_ERR)
1362 return(handler);
1363 if (handler != SIG_DFL)
1364 handler=SetMagickSignalHandler(signal_number,handler);
1365 else
1366 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1367 "Register handler for signal: %d",signal_number);
1368 return(handler);
1369 }
1370
MagickCoreGenesis(const char * path,const MagickBooleanType establish_signal_handlers)1371 MagickExport void MagickCoreGenesis(const char *path,
1372 const MagickBooleanType establish_signal_handlers)
1373 {
1374 char
1375 *events,
1376 execution_path[MagickPathExtent],
1377 filename[MagickPathExtent];
1378
1379 /*
1380 Initialize the Magick environment.
1381 */
1382 InitializeMagickMutex();
1383 LockMagickMutex();
1384 if (instantiate_magickcore != MagickFalse)
1385 {
1386 UnlockMagickMutex();
1387 return;
1388 }
1389 (void) SemaphoreComponentGenesis();
1390 (void) LogComponentGenesis();
1391 (void) LocaleComponentGenesis();
1392 (void) RandomComponentGenesis();
1393 events=GetEnvironmentValue("MAGICK_DEBUG");
1394 if (events != (char *) NULL)
1395 {
1396 (void) SetLogEventMask(events);
1397 events=DestroyString(events);
1398 }
1399 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1400 NTWindowsGenesis();
1401 #endif
1402 /*
1403 Set client name and execution path.
1404 */
1405 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1406 if ((path != (const char *) NULL) && (IsPathAccessible(path) != MagickFalse))
1407 #else
1408 if ((path != (const char *) NULL) && (*path == *DirectorySeparator) &&
1409 (IsPathAccessible(path) != MagickFalse))
1410 #endif
1411 (void) CopyMagickString(execution_path,path,MagickPathExtent);
1412 else
1413 (void) GetExecutionPath(execution_path,MagickPathExtent);
1414 GetPathComponent(execution_path,TailPath,filename);
1415 (void) SetClientName(filename);
1416 GetPathComponent(execution_path,HeadPath,execution_path);
1417 (void) SetClientPath(execution_path);
1418 if (establish_signal_handlers != MagickFalse)
1419 {
1420 /*
1421 Set signal handlers.
1422 */
1423 #if defined(SIGABRT)
1424 if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1425 signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1426 #endif
1427 #if defined(SIGSEGV)
1428 if (signal_handlers[SIGSEGV] == (SignalHandler *) NULL)
1429 signal_handlers[SIGSEGV]=RegisterMagickSignalHandler(SIGSEGV);
1430 #endif
1431 #if defined(SIGFPE)
1432 if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1433 signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1434 #endif
1435 #if defined(SIGHUP)
1436 if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1437 signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1438 #endif
1439 #if defined(SIGINT)
1440 if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1441 signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1442 #endif
1443 #if defined(SIGQUIT)
1444 if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1445 signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1446 #endif
1447 #if defined(SIGTERM)
1448 if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1449 signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1450 #endif
1451 #if defined(SIGXCPU)
1452 if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1453 signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1454 #endif
1455 #if defined(SIGXFSZ)
1456 if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1457 signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1458 #endif
1459 }
1460 /*
1461 Instantiate magick resources.
1462 */
1463 (void) ConfigureComponentGenesis();
1464 (void) PolicyComponentGenesis();
1465 (void) CacheComponentGenesis();
1466 (void) ResourceComponentGenesis();
1467 (void) CoderComponentGenesis();
1468 (void) MagickComponentGenesis();
1469 #if defined(MAGICKCORE_MODULES_SUPPORT)
1470 (void) ModuleComponentGenesis();
1471 #endif
1472 (void) DelegateComponentGenesis();
1473 (void) MagicComponentGenesis();
1474 (void) ColorComponentGenesis();
1475 (void) TypeComponentGenesis();
1476 (void) MimeComponentGenesis();
1477 (void) AnnotateComponentGenesis();
1478 #if defined(MAGICKCORE_X11_DELEGATE)
1479 (void) XComponentGenesis();
1480 #endif
1481 (void) RegistryComponentGenesis();
1482 instantiate_magickcore=MagickTrue;
1483 UnlockMagickMutex();
1484 }
1485
1486 /*
1487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1488 % %
1489 % %
1490 % %
1491 % M a g i c k C o r e T e r m i n u s %
1492 % %
1493 % %
1494 % %
1495 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1496 %
1497 % MagickCoreTerminus() destroys the MagickCore environment.
1498 %
1499 % The format of the MagickCoreTerminus function is:
1500 %
1501 % MagickCoreTerminus(void)
1502 %
1503 */
MagickCoreTerminus(void)1504 MagickExport void MagickCoreTerminus(void)
1505 {
1506 InitializeMagickMutex();
1507 LockMagickMutex();
1508 if (instantiate_magickcore == MagickFalse)
1509 {
1510 UnlockMagickMutex();
1511 return;
1512 }
1513 RegistryComponentTerminus();
1514 #if defined(MAGICKCORE_X11_DELEGATE)
1515 XComponentTerminus();
1516 #endif
1517 AnnotateComponentTerminus();
1518 MimeComponentTerminus();
1519 TypeComponentTerminus();
1520 #if defined(MAGICKCORE_OPENCL_SUPPORT)
1521 OpenCLTerminus();
1522 #endif
1523 ColorComponentTerminus();
1524 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1525 NTWindowsTerminus();
1526 #endif
1527 MagicComponentTerminus();
1528 DelegateComponentTerminus();
1529 MagickComponentTerminus();
1530 #if !defined(MAGICKCORE_BUILD_MODULES)
1531 UnregisterStaticModules();
1532 #endif
1533 #if defined(MAGICKCORE_MODULES_SUPPORT)
1534 ModuleComponentTerminus();
1535 #endif
1536 CoderComponentTerminus();
1537 ResourceComponentTerminus();
1538 CacheComponentTerminus();
1539 PolicyComponentTerminus();
1540 ConfigureComponentTerminus();
1541 RandomComponentTerminus();
1542 LocaleComponentTerminus();
1543 LogComponentTerminus();
1544 instantiate_magickcore=MagickFalse;
1545 UnlockMagickMutex();
1546 SemaphoreComponentTerminus();
1547 }
1548
1549 /*
1550 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1551 % %
1552 % %
1553 % %
1554 + R e g i s t e r M a g i c k I n f o %
1555 % %
1556 % %
1557 % %
1558 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1559 %
1560 % RegisterMagickInfo() adds attributes for a particular image format to the
1561 % list of supported formats. The attributes include the image format name,
1562 % a method to read and/or write the format, whether the format supports the
1563 % saving of more than one frame to the same file or blob, whether the format
1564 % supports native in-memory I/O, and a brief description of the format.
1565 %
1566 % The format of the RegisterMagickInfo method is:
1567 %
1568 % MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1569 %
1570 % A description of each parameter follows:
1571 %
1572 % o magick_info: the magick info.
1573 %
1574 */
RegisterMagickInfo(MagickInfo * magick_info)1575 MagickExport MagickBooleanType RegisterMagickInfo(MagickInfo *magick_info)
1576 {
1577 MagickBooleanType
1578 status;
1579
1580 /*
1581 Register a new image format.
1582 */
1583 assert(magick_info != (MagickInfo *) NULL);
1584 assert(magick_info->signature == MagickCoreSignature);
1585 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
1586 if (magick_list == (SplayTreeInfo *) NULL)
1587 return(MagickFalse);
1588 if ((GetMagickDecoderThreadSupport(magick_info) == MagickFalse) ||
1589 (GetMagickEncoderThreadSupport(magick_info) == MagickFalse))
1590 magick_info->semaphore=AcquireSemaphoreInfo();
1591 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1592 return(status);
1593 }
1594
1595 /*
1596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1597 % %
1598 % %
1599 % %
1600 % S e t M a g i c k P r e c i s i o n %
1601 % %
1602 % %
1603 % %
1604 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1605 %
1606 % SetMagickPrecision() sets the maximum number of significant digits to be
1607 % printed.
1608 %
1609 % An input argument of 0 returns the current precision setting.
1610 %
1611 % A negative value forces the precision to reset to a default value according
1612 % to the environment variable "MAGICK_PRECISION", the current 'policy'
1613 % configuration setting, or the default value of '6', in that order.
1614 %
1615 % The format of the SetMagickPrecision method is:
1616 %
1617 % int SetMagickPrecision(const int precision)
1618 %
1619 % A description of each parameter follows:
1620 %
1621 % o precision: set the maximum number of significant digits to be printed.
1622 %
1623 */
SetMagickPrecision(const int precision)1624 MagickExport int SetMagickPrecision(const int precision)
1625 {
1626 #define MagickPrecision 6
1627
1628 static int
1629 magick_precision = 0;
1630
1631 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1632 if (precision > 0)
1633 magick_precision=precision;
1634 if ((precision < 0) || (magick_precision == 0))
1635 {
1636 char
1637 *limit;
1638
1639 /*
1640 Precision reset, or it has not been set yet
1641 */
1642 magick_precision=MagickPrecision;
1643 limit=GetEnvironmentValue("MAGICK_PRECISION");
1644 if (limit == (char *) NULL)
1645 limit=GetPolicyValue("precision");
1646 if (limit != (char *) NULL)
1647 {
1648 magick_precision=StringToInteger(limit);
1649 limit=DestroyString(limit);
1650 }
1651 }
1652 return(magick_precision);
1653 }
1654
1655 /*
1656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1657 % %
1658 % %
1659 % %
1660 + U n r e g i s t e r M a g i c k I n f o %
1661 % %
1662 % %
1663 % %
1664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1665 %
1666 % UnregisterMagickInfo() removes a name from the magick info list. It returns
1667 % MagickFalse if the name does not exist in the list otherwise MagickTrue.
1668 %
1669 % The format of the UnregisterMagickInfo method is:
1670 %
1671 % MagickBooleanType UnregisterMagickInfo(const char *name)
1672 %
1673 % A description of each parameter follows:
1674 %
1675 % o name: a character string that represents the image format we are
1676 % looking for.
1677 %
1678 */
UnregisterMagickInfo(const char * name)1679 MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1680 {
1681 register const MagickInfo
1682 *p;
1683
1684 MagickBooleanType
1685 status;
1686
1687 assert(name != (const char *) NULL);
1688 if (magick_list == (SplayTreeInfo *) NULL)
1689 return(MagickFalse);
1690 if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1691 return(MagickFalse);
1692 LockSemaphoreInfo(magick_semaphore);
1693 ResetSplayTreeIterator(magick_list);
1694 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1695 while (p != (const MagickInfo *) NULL)
1696 {
1697 if (LocaleCompare(p->name,name) == 0)
1698 break;
1699 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1700 }
1701 status=DeleteNodeByValueFromSplayTree(magick_list,p);
1702 UnlockSemaphoreInfo(magick_semaphore);
1703 return(status);
1704 }
1705