• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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