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