blob: 9fca3aa66e4884f2fc6d2bf0051c724c681ff45a [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
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 %
cristyde984cd2013-12-01 14:49:27 +000017% Cristy %
cristy3ed852e2009-09-05 21:47:34 +000018% November 1998 %
19% %
20% %
cristyfe676ee2013-11-18 13:03:38 +000021% Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000022% 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*/
cristy4c08aed2011-07-01 19:47:50 +000043#include "MagickCore/studio.h"
cristy5ff4eaf2011-09-03 01:38:02 +000044#include "MagickCore/annotate-private.h"
cristy4c08aed2011-07-01 19:47:50 +000045#include "MagickCore/blob.h"
46#include "MagickCore/blob-private.h"
47#include "MagickCore/cache.h"
cristy5ff4eaf2011-09-03 01:38:02 +000048#include "MagickCore/cache-private.h"
49#include "MagickCore/coder-private.h"
cristy4c08aed2011-07-01 19:47:50 +000050#include "MagickCore/client.h"
cristy5ff4eaf2011-09-03 01:38:02 +000051#include "MagickCore/color-private.h"
52#include "MagickCore/configure-private.h"
53#include "MagickCore/constitute-private.h"
54#include "MagickCore/delegate-private.h"
cristy4c08aed2011-07-01 19:47:50 +000055#include "MagickCore/draw.h"
56#include "MagickCore/exception.h"
57#include "MagickCore/exception-private.h"
cristy5ff4eaf2011-09-03 01:38:02 +000058#include "MagickCore/locale-private.h"
59#include "MagickCore/log-private.h"
60#include "MagickCore/magic-private.h"
cristy4c08aed2011-07-01 19:47:50 +000061#include "MagickCore/magick.h"
cristy5ff4eaf2011-09-03 01:38:02 +000062#include "MagickCore/magick-private.h"
cristy4c08aed2011-07-01 19:47:50 +000063#include "MagickCore/memory_.h"
cristy5ff4eaf2011-09-03 01:38:02 +000064#include "MagickCore/mime-private.h"
cristy4c08aed2011-07-01 19:47:50 +000065#include "MagickCore/module.h"
cristy5ff4eaf2011-09-03 01:38:02 +000066#include "MagickCore/module-private.h"
cristy2c5fc272012-02-22 01:27:46 +000067#include "MagickCore/nt-base-private.h"
cristyb01e49e2014-09-09 22:59:01 +000068#include "MagickCore/option-private.h"
cristy5ff4eaf2011-09-03 01:38:02 +000069#include "MagickCore/random-private.h"
cristy4c08aed2011-07-01 19:47:50 +000070#include "MagickCore/registry.h"
cristy5ff4eaf2011-09-03 01:38:02 +000071#include "MagickCore/registry-private.h"
cristy4c08aed2011-07-01 19:47:50 +000072#include "MagickCore/resource_.h"
cristy0a4d92f2011-08-31 19:25:00 +000073#include "MagickCore/resource-private.h"
cristy4c08aed2011-07-01 19:47:50 +000074#include "MagickCore/policy.h"
cristy5ff4eaf2011-09-03 01:38:02 +000075#include "MagickCore/policy-private.h"
cristy4c08aed2011-07-01 19:47:50 +000076#include "MagickCore/semaphore.h"
77#include "MagickCore/semaphore-private.h"
78#include "MagickCore/signature-private.h"
79#include "MagickCore/splay-tree.h"
80#include "MagickCore/string_.h"
81#include "MagickCore/string-private.h"
82#include "MagickCore/thread_.h"
83#include "MagickCore/thread-private.h"
cristy5ff4eaf2011-09-03 01:38:02 +000084#include "MagickCore/type-private.h"
cristy4c08aed2011-07-01 19:47:50 +000085#include "MagickCore/token.h"
86#include "MagickCore/utility.h"
cristyd1dd6e42011-09-04 01:46:08 +000087#include "MagickCore/utility-private.h"
cristy4c08aed2011-07-01 19:47:50 +000088#include "MagickCore/xwindow-private.h"
cristy3ed852e2009-09-05 21:47:34 +000089
90/*
91 Define declarations.
92*/
93#if !defined(MAGICKCORE_RETSIGTYPE)
94# define MAGICKCORE_RETSIGTYPE void
95#endif
96#if !defined(SIG_DFL)
97# define SIG_DFL ((SignalHandler *) 0)
98#endif
99#if !defined(SIG_ERR)
100# define SIG_ERR ((SignalHandler *) -1)
101#endif
102#if !defined(SIGMAX)
103#define SIGMAX 64
104#endif
105
106/*
107 Typedef declarations.
108*/
109typedef MAGICKCORE_RETSIGTYPE
110 SignalHandler(int);
111
112/*
113 Global declarations.
114*/
115static SemaphoreInfo
116 *magick_semaphore = (SemaphoreInfo *) NULL;
117
118static SignalHandler
119 *signal_handlers[SIGMAX] = { (SignalHandler *) NULL };
120
121static SplayTreeInfo
122 *magick_list = (SplayTreeInfo *) NULL;
123
124static volatile MagickBooleanType
cristyd1ebf4a2010-05-13 01:54:31 +0000125 instantiate_magickcore = MagickFalse;
cristy3ed852e2009-09-05 21:47:34 +0000126
127/*
128 Forward declarations.
129*/
130static MagickBooleanType
cristy904e5912014-03-15 19:53:14 +0000131 IsMagickTreeInstantiated(ExceptionInfo *);
cristy3ed852e2009-09-05 21:47:34 +0000132
133/*
134%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135% %
136% %
137% %
cristy3ed852e2009-09-05 21:47:34 +0000138+ G e t I m a g e D e c o d e r %
139% %
140% %
141% %
142%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143%
144% GetImageDecoder() returns the image decoder.
145%
146% The format of the GetImageDecoder method is:
147%
148% DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
149%
150% A description of each parameter follows:
151%
152% o magick_info: The magick info.
153%
154*/
155MagickExport DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
156{
157 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
158 assert(magick_info != (MagickInfo *) NULL);
159 assert(magick_info->signature == MagickSignature);
160 return(magick_info->decoder);
161}
162
163/*
164%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
165% %
166% %
167% %
168+ G e t I m a g e E n c o d e r %
169% %
170% %
171% %
172%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
173%
174% GetImageEncoder() returns the image encoder.
175%
176% The format of the GetImageEncoder method is:
177%
178% EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
179%
180% A description of each parameter follows:
181%
182% o magick_info: The magick info.
183%
184*/
185MagickExport EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
186{
187 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
188 assert(magick_info != (MagickInfo *) NULL);
189 assert(magick_info->signature == MagickSignature);
190 return(magick_info->encoder);
191}
192
193/*
194%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
195% %
196% %
197% %
198+ G e t I m a g e M a g i c k %
199% %
200% %
201% %
202%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
203%
204% GetImageMagick() searches for an image format that matches the specified
205% magick string. If one is found, MagickTrue is returned otherwise
206% MagickFalse.
207%
208% The format of the GetImageMagick method is:
209%
210% MagickBooleanType GetImageMagick(const unsigned char *magick,
211% const size_t length,char *format)
212%
213% A description of each parameter follows:
214%
215% o magick: the image format we are searching for.
216%
217% o length: the length of the binary string.
218%
219% o format: the image format as determined by the magick bytes.
220%
221*/
222MagickExport MagickBooleanType GetImageMagick(const unsigned char *magick,
223 const size_t length,char *format)
224{
225 ExceptionInfo
226 *exception;
227
228 MagickBooleanType
229 status;
230
231 register const MagickInfo
232 *p;
233
234 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
235 assert(magick != (const unsigned char *) NULL);
236 exception=AcquireExceptionInfo();
237 p=GetMagickInfo("*",exception);
238 exception=DestroyExceptionInfo(exception);
239 if (p == (const MagickInfo *) NULL)
240 return(MagickFalse);
241 status=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +0000242 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000243 ResetSplayTreeIterator(magick_list);
244 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
245 while (p != (const MagickInfo *) NULL)
246 {
247 if ((p->magick != (IsImageFormatHandler *) NULL) &&
248 (p->magick(magick,length) != 0))
249 {
250 status=MagickTrue;
251 (void) CopyMagickString(format,p->name,MaxTextExtent);
252 break;
253 }
254 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
255 }
cristyf84a1932010-01-03 18:00:18 +0000256 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000257 return(status);
258}
259
260/*
261%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
262% %
263% %
264% %
265+ G e t M a g i c k A d j o i n %
266% %
267% %
268% %
269%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
270%
271% GetMagickAdjoin() returns MagickTrue if the magick adjoin is MagickTrue.
272%
273% The format of the GetMagickAdjoin method is:
274%
275% MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
276%
277% A description of each parameter follows:
278%
279% o magick_info: The magick info.
280%
281*/
282MagickExport MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
283{
284 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
285 assert(magick_info != (MagickInfo *) NULL);
286 assert(magick_info->signature == MagickSignature);
287 return(magick_info->adjoin);
288}
289
290/*
291%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
292% %
293% %
294% %
295+ G e t M a g i c k B l o b S u p p o r t %
296% %
297% %
298% %
299%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
300%
301% GetMagickBlobSupport() returns MagickTrue if the magick supports blobs.
302%
303% The format of the GetMagickBlobSupport method is:
304%
305% MagickBooleanType GetMagickBlobSupport(const MagickInfo *magick_info)
306%
307% A description of each parameter follows:
308%
309% o magick_info: The magick info.
310%
311*/
312MagickExport MagickBooleanType GetMagickBlobSupport(
313 const MagickInfo *magick_info)
314{
315 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
316 assert(magick_info != (MagickInfo *) NULL);
317 assert(magick_info->signature == MagickSignature);
318 return(magick_info->blob_support);
319}
320
321/*
322%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
323% %
324% %
325% %
326+ G e t M a g i c k D e s c r i p t i o n %
327% %
328% %
329% %
330%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
331%
332% GetMagickDescription() returns the magick description.
333%
334% The format of the GetMagickDescription method is:
335%
336% const char *GetMagickDescription(const MagickInfo *magick_info)
337%
338% A description of each parameter follows:
339%
340% o magick_info: The magick info.
341%
342*/
343MagickExport const char *GetMagickDescription(const MagickInfo *magick_info)
344{
345 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
346 assert(magick_info != (MagickInfo *) NULL);
347 assert(magick_info->signature == MagickSignature);
348 return(magick_info->description);
349}
350
351/*
352%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353% %
354% %
355% %
356+ G e t M a g i c k E n d i a n S u p p o r t %
357% %
358% %
359% %
360%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
361%
362% GetMagickEndianSupport() returns the MagickTrue if the coder respects
363% endianness other than MSBEndian.
364%
365% The format of the GetMagickEndianSupport method is:
366%
367% MagickBooleanType GetMagickEndianSupport(const MagickInfo *magick_info)
368%
369% A description of each parameter follows:
370%
371% o magick_info: The magick info.
372%
373*/
374MagickExport MagickBooleanType GetMagickEndianSupport(
375 const MagickInfo *magick_info)
376{
377 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
378 assert(magick_info != (MagickInfo *) NULL);
379 assert(magick_info->signature == MagickSignature);
380 return(magick_info->endian_support);
381}
382
383/*
384%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
385% %
386% %
387% %
388+ G e t M a g i c k I n f o %
389% %
390% %
391% %
392%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
393%
394% GetMagickInfo() returns a pointer MagickInfo structure that matches
395% the specified name. If name is NULL, the head of the image format list
396% is returned.
397%
398% The format of the GetMagickInfo method is:
399%
400% const MagickInfo *GetMagickInfo(const char *name,Exception *exception)
401%
402% A description of each parameter follows:
403%
404% o name: the image format we are looking for.
405%
406% o exception: return any errors or warnings in this structure.
407%
408*/
409MagickExport const MagickInfo *GetMagickInfo(const char *name,
410 ExceptionInfo *exception)
411{
412 register const MagickInfo
413 *p;
414
415 assert(exception != (ExceptionInfo *) NULL);
cristy904e5912014-03-15 19:53:14 +0000416 if (IsMagickTreeInstantiated(exception) == MagickFalse)
417 return((const MagickInfo *) NULL);
cristy86e5ac92014-03-16 19:27:39 +0000418#if defined(MAGICKCORE_MODULES_SUPPORT)
419 if ((name != (const char *) NULL) && (LocaleCompare(name,"*") == 0))
420 (void) OpenModules(exception);
421#endif
cristy3ed852e2009-09-05 21:47:34 +0000422 /*
423 Find name in list.
424 */
cristyf84a1932010-01-03 18:00:18 +0000425 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000426 ResetSplayTreeIterator(magick_list);
427 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
cristy49d4d222014-03-16 00:37:58 +0000428 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
429 {
cristy49d4d222014-03-16 00:37:58 +0000430 ResetSplayTreeIterator(magick_list);
431 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
432 UnlockSemaphoreInfo(magick_semaphore);
433 return(p);
434 }
cristy3ed852e2009-09-05 21:47:34 +0000435 while (p != (const MagickInfo *) NULL)
436 {
437 if (LocaleCompare(p->name,name) == 0)
438 break;
439 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
440 }
441#if defined(MAGICKCORE_MODULES_SUPPORT)
442 if (p == (const MagickInfo *) NULL)
443 {
444 if (*name != '\0')
445 (void) OpenModule(name,exception);
446 ResetSplayTreeIterator(magick_list);
447 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
448 while (p != (const MagickInfo *) NULL)
449 {
450 if (LocaleCompare(p->name,name) == 0)
451 break;
452 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
453 }
454 }
455#endif
cristyf84a1932010-01-03 18:00:18 +0000456 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000457 return(p);
458}
459
460/*
461%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
462% %
463% %
464% %
465+ G e t M a g i c k I n f o L i s t %
466% %
467% %
468% %
469%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
470%
471% GetMagickInfoList() returns any image formats that match the specified
472% pattern.
473%
474% The format of the GetMagickInfoList function is:
475%
476% const MagickInfo **GetMagickInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000477% size_t *number_formats,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000478%
479% A description of each parameter follows:
480%
481% o pattern: Specifies a pointer to a text string containing a pattern.
482%
483% o number_formats: This integer returns the number of formats in the list.
484%
485% o exception: return any errors or warnings in this structure.
486%
487*/
488
489#if defined(__cplusplus) || defined(c_plusplus)
490extern "C" {
491#endif
492
493static int MagickInfoCompare(const void *x,const void *y)
494{
495 const MagickInfo
496 **p,
497 **q;
498
499 p=(const MagickInfo **) x,
500 q=(const MagickInfo **) y;
501 return(LocaleCompare((*p)->name,(*q)->name));
502}
503
504#if defined(__cplusplus) || defined(c_plusplus)
505}
506#endif
507
508MagickExport const MagickInfo **GetMagickInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000509 size_t *number_formats,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000510{
511 const MagickInfo
512 **formats;
513
514 register const MagickInfo
515 *p;
516
cristybb503372010-05-27 20:51:26 +0000517 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000518 i;
519
520 /*
521 Allocate magick list.
522 */
523 assert(pattern != (char *) NULL);
524 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000525 assert(number_formats != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000526 *number_formats=0;
527 p=GetMagickInfo("*",exception);
528 if (p == (const MagickInfo *) NULL)
529 return((const MagickInfo **) NULL);
530 formats=(const MagickInfo **) AcquireQuantumMemory((size_t)
531 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
532 if (formats == (const MagickInfo **) NULL)
533 return((const MagickInfo **) NULL);
534 /*
535 Generate magick list.
536 */
cristyf84a1932010-01-03 18:00:18 +0000537 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000538 ResetSplayTreeIterator(magick_list);
539 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
540 for (i=0; p != (const MagickInfo *) NULL; )
541 {
542 if ((p->stealth == MagickFalse) &&
543 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
544 formats[i++]=p;
545 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
546 }
cristyf84a1932010-01-03 18:00:18 +0000547 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000548 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickInfoCompare);
549 formats[i]=(MagickInfo *) NULL;
cristybb503372010-05-27 20:51:26 +0000550 *number_formats=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000551 return(formats);
552}
553
554/*
555%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
556% %
557% %
558% %
559+ G e t M a g i c k L i s t %
560% %
561% %
562% %
563%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
564%
565% GetMagickList() returns any image formats that match the specified pattern.
566%
567% The format of the GetMagickList function is:
568%
cristybb503372010-05-27 20:51:26 +0000569% char **GetMagickList(const char *pattern,size_t *number_formats,
cristy3ed852e2009-09-05 21:47:34 +0000570% ExceptionInfo *exception)
571%
572% A description of each parameter follows:
573%
574% o pattern: Specifies a pointer to a text string containing a pattern.
575%
576% o number_formats: This integer returns the number of formats in the list.
577%
578% o exception: return any errors or warnings in this structure.
579%
580*/
581
582#if defined(__cplusplus) || defined(c_plusplus)
583extern "C" {
584#endif
585
586static int MagickCompare(const void *x,const void *y)
587{
588 register const char
589 **p,
590 **q;
591
592 p=(const char **) x;
593 q=(const char **) y;
594 return(LocaleCompare(*p,*q));
595}
596
597#if defined(__cplusplus) || defined(c_plusplus)
598}
599#endif
600
601MagickExport char **GetMagickList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000602 size_t *number_formats,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000603{
604 char
605 **formats;
606
607 register const MagickInfo
608 *p;
609
cristybb503372010-05-27 20:51:26 +0000610 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000611 i;
612
613 /*
614 Allocate magick list.
615 */
616 assert(pattern != (char *) NULL);
617 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000618 assert(number_formats != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000619 *number_formats=0;
620 p=GetMagickInfo("*",exception);
621 if (p == (const MagickInfo *) NULL)
622 return((char **) NULL);
623 formats=(char **) AcquireQuantumMemory((size_t)
624 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
625 if (formats == (char **) NULL)
626 return((char **) NULL);
cristyf84a1932010-01-03 18:00:18 +0000627 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000628 ResetSplayTreeIterator(magick_list);
629 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
630 for (i=0; p != (const MagickInfo *) NULL; )
631 {
632 if ((p->stealth == MagickFalse) &&
633 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
634 formats[i++]=ConstantString(p->name);
635 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
636 }
cristyf84a1932010-01-03 18:00:18 +0000637 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000638 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickCompare);
639 formats[i]=(char *) NULL;
cristybb503372010-05-27 20:51:26 +0000640 *number_formats=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000641 return(formats);
642}
643
644/*
645%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
646% %
647% %
648% %
cristy4a6ab482013-08-09 01:29:35 +0000649+ G e t M a g i c k M i m e T y p e %
650% %
651% %
652% %
653%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
654%
655% GetMagickMimeType() returns the magick mime type.
656%
657% The format of the GetMagickMimeType method is:
658%
659% const char *GetMagickMimeType(const MagickInfo *magick_info)
660%
661% A description of each parameter follows:
662%
663% o magick_info: The magick info.
664%
665*/
666MagickExport const char *GetMagickMimeType(const MagickInfo *magick_info)
667{
668 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
669 assert(magick_info != (MagickInfo *) NULL);
670 assert(magick_info->signature == MagickSignature);
671 return(magick_info->mime_type);
672}
673
674/*
675%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
676% %
677% %
678% %
cristye7f51092010-01-17 00:39:37 +0000679% G e t M a g i c k P r e c i s i o n %
cristy7ce14bc2010-01-17 00:01:01 +0000680% %
681% %
682% %
683%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
684%
685% GetMagickPrecision() returns the maximum number of significant digits to be
686% printed.
687%
688% The format of the GetMagickPrecision method is:
689%
cristye7f51092010-01-17 00:39:37 +0000690% int GetMagickPrecision(void)
cristy7ce14bc2010-01-17 00:01:01 +0000691%
692*/
cristye7f51092010-01-17 00:39:37 +0000693MagickExport int GetMagickPrecision(void)
cristy7ce14bc2010-01-17 00:01:01 +0000694{
cristy7ce14bc2010-01-17 00:01:01 +0000695 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
cristybf2766a2010-01-17 03:33:23 +0000696 return(SetMagickPrecision(0));
cristy7ce14bc2010-01-17 00:01:01 +0000697}
698
699/*
700%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
701% %
702% %
703% %
704+ G e t M a g i c k R a w S u p p o r t %
cristy3ed852e2009-09-05 21:47:34 +0000705% %
706% %
707% %
708%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
709%
710% GetMagickRawSupport() returns the MagickTrue if the coder is a raw format.
711%
712% The format of the GetMagickRawSupport method is:
713%
714% MagickBooleanType GetMagickRawSupport(const MagickInfo *magick_info)
715%
716% A description of each parameter follows:
717%
718% o magick_info: The magick info.
719%
720*/
721MagickExport MagickBooleanType GetMagickRawSupport(
722 const MagickInfo *magick_info)
723{
724 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
725 assert(magick_info != (MagickInfo *) NULL);
726 assert(magick_info->signature == MagickSignature);
727 return(magick_info->raw);
728}
729
730/*
731%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
732% %
733% %
734% %
735+ G e t M a g i c k S e e k a b l e S t r e a m %
736% %
737% %
738% %
739%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
740%
741% GetMagickSeekableStream() returns MagickTrue if the magick supports a
742% seekable stream.
743%
744% The format of the GetMagickSeekableStream method is:
745%
746% MagickBooleanType GetMagickSeekableStream(const MagickInfo *magick_info)
747%
748% A description of each parameter follows:
749%
750% o magick_info: The magick info.
751%
752*/
753MagickExport MagickBooleanType GetMagickSeekableStream(
754 const MagickInfo *magick_info)
755{
756 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
757 assert(magick_info != (MagickInfo *) NULL);
758 assert(magick_info->signature == MagickSignature);
759 return(magick_info->seekable_stream);
760}
761
762/*
763%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
764% %
765% %
766% %
767+ G e t M a g i c k T h r e a d S u p p o r t %
768% %
769% %
770% %
771%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
772%
773% GetMagickThreadSupport() returns MagickTrue if the magick supports threads.
774%
775% The format of the GetMagickThreadSupport method is:
776%
777% MagickStatusType GetMagickThreadSupport(const MagickInfo *magick_info)
778%
779% A description of each parameter follows:
780%
781% o magick_info: The magick info.
782%
783*/
784MagickExport MagickStatusType GetMagickThreadSupport(
785 const MagickInfo *magick_info)
786{
787 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
788 assert(magick_info != (MagickInfo *) NULL);
789 assert(magick_info->signature == MagickSignature);
790 return(magick_info->thread_support);
791}
792
793/*
794%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
795% %
796% %
797% %
cristy904e5912014-03-15 19:53:14 +0000798+ I s M a g i c k T r e e I n s t a n t i a t e d %
cristy3ed852e2009-09-05 21:47:34 +0000799% %
800% %
801% %
802%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
803%
cristy904e5912014-03-15 19:53:14 +0000804% IsMagickTreeInstantiated() determines if the magick tree is instantiated.
805% If not, it instantiates the tree and returns it.
cristy3ed852e2009-09-05 21:47:34 +0000806%
cristy904e5912014-03-15 19:53:14 +0000807% The format of the IsMagickTreeInstantiated() method is:
cristy3ed852e2009-09-05 21:47:34 +0000808%
cristy904e5912014-03-15 19:53:14 +0000809% IsMagickTreeInstantiated(Exceptioninfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000810%
811% A description of each parameter follows.
812%
813% o exception: return any errors or warnings in this structure.
814%
815*/
816
817static void *DestroyMagickNode(void *magick_info)
818{
819 register MagickInfo
820 *p;
821
822 p=(MagickInfo *) magick_info;
cristy3ed852e2009-09-05 21:47:34 +0000823 if (p->module != (char *) NULL)
824 p->module=DestroyString(p->module);
cristy4a6ab482013-08-09 01:29:35 +0000825 if (p->note != (char *) NULL)
826 p->note=DestroyString(p->note);
827 if (p->mime_type != (char *) NULL)
828 p->mime_type=DestroyString(p->mime_type);
829 if (p->version != (char *) NULL)
830 p->version=DestroyString(p->version);
831 if (p->description != (char *) NULL)
832 p->description=DestroyString(p->description);
833 if (p->name != (char *) NULL)
834 p->name=DestroyString(p->name);
cristy191ba5c2014-03-16 21:26:40 +0000835 if (p->semaphore != (SemaphoreInfo *) NULL)
cristy1d51f832014-03-19 13:20:31 +0000836 RelinquishSemaphoreInfo(&p->semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000837 return(RelinquishMagickMemory(p));
838}
839
cristy904e5912014-03-15 19:53:14 +0000840static MagickBooleanType IsMagickTreeInstantiated(ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000841{
cristyf2e11662009-10-14 01:24:43 +0000842 (void) exception;
cristy1460f262014-03-15 17:38:05 +0000843 if (magick_list == (SplayTreeInfo *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000844 {
cristy86e5ac92014-03-16 19:27:39 +0000845 if (magick_semaphore == (SemaphoreInfo *) NULL)
846 ActivateSemaphoreInfo(&magick_semaphore);
847 LockSemaphoreInfo(magick_semaphore);
cristy1460f262014-03-15 17:38:05 +0000848 if (magick_list == (SplayTreeInfo *) NULL)
cristy86e5ac92014-03-16 19:27:39 +0000849 {
850 MagickBooleanType
851 status;
852
853 MagickInfo
854 *magick_info;
855
856 magick_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *))
cristy0d8101e2014-04-10 00:13:05 +0000857 NULL,DestroyMagickNode);
cristy86e5ac92014-03-16 19:27:39 +0000858 if (magick_list == (SplayTreeInfo *) NULL)
859 ThrowFatalException(ResourceLimitFatalError,
860 "MemoryAllocationFailed");
861 magick_info=SetMagickInfo("ephemeral");
862 magick_info->stealth=MagickTrue;
863 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
864 if (status == MagickFalse)
865 ThrowFatalException(ResourceLimitFatalError,
866 "MemoryAllocationFailed");
867 magick_info=SetMagickInfo("clipmask");
868 magick_info->stealth=MagickTrue;
869 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
870 if (status == MagickFalse)
871 ThrowFatalException(ResourceLimitFatalError,
872 "MemoryAllocationFailed");
cristy3ed852e2009-09-05 21:47:34 +0000873#if defined(MAGICKCORE_MODULES_SUPPORT)
cristy86e5ac92014-03-16 19:27:39 +0000874 (void) GetModuleInfo((char *) NULL,exception);
cristy3ed852e2009-09-05 21:47:34 +0000875#endif
876#if !defined(MAGICKCORE_BUILD_MODULES)
cristy86e5ac92014-03-16 19:27:39 +0000877 RegisterStaticModules();
cristy3ed852e2009-09-05 21:47:34 +0000878#endif
cristy86e5ac92014-03-16 19:27:39 +0000879 }
880 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000881 }
882 return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
883}
884
885/*
886%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
887% %
888% %
889% %
890+ I s M a g i c k C o n f l i c t %
891% %
892% %
893% %
894%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
895%
cristy05a9a622010-03-15 17:26:04 +0000896% IsMagickConflict() returns MagickTrue if the image format conflicts with a
897% logical drive (.e.g. X:).
cristy3ed852e2009-09-05 21:47:34 +0000898%
899% The format of the IsMagickConflict method is:
900%
901% MagickBooleanType IsMagickConflict(const char *magick)
902%
903% A description of each parameter follows:
904%
905% o magick: Specifies the image format.
906%
907*/
cristy7832dc22011-09-05 01:21:53 +0000908MagickPrivate MagickBooleanType IsMagickConflict(const char *magick)
cristy3ed852e2009-09-05 21:47:34 +0000909{
cristy3ed852e2009-09-05 21:47:34 +0000910 assert(magick != (char *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000911#if defined(macintosh)
912 return(MACIsMagickConflict(magick));
913#elif defined(vms)
914 return(VMSIsMagickConflict(magick));
cristy0157aea2010-04-24 21:12:18 +0000915#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000916 return(NTIsMagickConflict(magick));
917#else
918 return(MagickFalse);
919#endif
920}
921
922/*
923%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
924% %
925% %
926% %
927+ L i s t M a g i c k I n f o %
928% %
929% %
930% %
931%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
932%
933% ListMagickInfo() lists the image formats to a file.
934%
935% The format of the ListMagickInfo method is:
936%
937% MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
938%
939% A description of each parameter follows.
940%
941% o file: A file handle.
942%
943% o exception: return any errors or warnings in this structure.
944%
945*/
946MagickExport MagickBooleanType ListMagickInfo(FILE *file,
947 ExceptionInfo *exception)
948{
949 const MagickInfo
950 **magick_info;
951
cristybb503372010-05-27 20:51:26 +0000952 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000953 i;
954
cristybb503372010-05-27 20:51:26 +0000955 size_t
cristy3ed852e2009-09-05 21:47:34 +0000956 number_formats;
957
cristy9d314ff2011-03-09 01:30:28 +0000958 ssize_t
959 j;
960
cristy3ed852e2009-09-05 21:47:34 +0000961 if (file == (FILE *) NULL)
962 file=stdout;
963 magick_info=GetMagickInfoList("*",&number_formats,exception);
964 if (magick_info == (const MagickInfo **) NULL)
965 return(MagickFalse);
966 ClearMagickException(exception);
967#if !defined(MAGICKCORE_MODULES_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000968 (void) FormatLocaleFile(file," Format Mode Description\n");
cristy3ed852e2009-09-05 21:47:34 +0000969#else
cristyb51dff52011-05-19 16:55:47 +0000970 (void) FormatLocaleFile(file," Format Module Mode Description\n");
cristy3ed852e2009-09-05 21:47:34 +0000971#endif
cristy1e604812011-05-19 18:07:50 +0000972 (void) FormatLocaleFile(file,
973 "--------------------------------------------------------"
cristy3ed852e2009-09-05 21:47:34 +0000974 "-----------------------\n");
cristybb503372010-05-27 20:51:26 +0000975 for (i=0; i < (ssize_t) number_formats; i++)
cristy3ed852e2009-09-05 21:47:34 +0000976 {
977 if (magick_info[i]->stealth != MagickFalse)
978 continue;
cristy1e604812011-05-19 18:07:50 +0000979 (void) FormatLocaleFile(file,"%9s%c ",
980 magick_info[i]->name != (char *) NULL ? magick_info[i]->name : "",
cristy3ed852e2009-09-05 21:47:34 +0000981 magick_info[i]->blob_support != MagickFalse ? '*' : ' ');
982#if defined(MAGICKCORE_MODULES_SUPPORT)
983 {
984 char
985 module[MaxTextExtent];
986
987 *module='\0';
988 if (magick_info[i]->module != (char *) NULL)
989 (void) CopyMagickString(module,magick_info[i]->module,MaxTextExtent);
990 (void) ConcatenateMagickString(module," ",MaxTextExtent);
991 module[9]='\0';
cristyb51dff52011-05-19 16:55:47 +0000992 (void) FormatLocaleFile(file,"%9s ",module);
cristy3ed852e2009-09-05 21:47:34 +0000993 }
994#endif
cristyb51dff52011-05-19 16:55:47 +0000995 (void) FormatLocaleFile(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
cristy3ed852e2009-09-05 21:47:34 +0000996 magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
997 magick_info[i]->adjoin != MagickFalse ? '+' : '-');
998 if (magick_info[i]->description != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +0000999 (void) FormatLocaleFile(file," %s",magick_info[i]->description);
cristy3ed852e2009-09-05 21:47:34 +00001000 if (magick_info[i]->version != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +00001001 (void) FormatLocaleFile(file," (%s)",magick_info[i]->version);
1002 (void) FormatLocaleFile(file,"\n");
cristy3ed852e2009-09-05 21:47:34 +00001003 if (magick_info[i]->note != (char *) NULL)
1004 {
1005 char
1006 **text;
1007
1008 text=StringToList(magick_info[i]->note);
1009 if (text != (char **) NULL)
1010 {
1011 for (j=0; text[j] != (char *) NULL; j++)
1012 {
cristyb51dff52011-05-19 16:55:47 +00001013 (void) FormatLocaleFile(file," %s\n",text[j]);
cristy3ed852e2009-09-05 21:47:34 +00001014 text[j]=DestroyString(text[j]);
1015 }
1016 text=(char **) RelinquishMagickMemory(text);
1017 }
1018 }
1019 }
cristyb51dff52011-05-19 16:55:47 +00001020 (void) FormatLocaleFile(file,"\n* native blob support\n");
1021 (void) FormatLocaleFile(file,"r read support\n");
1022 (void) FormatLocaleFile(file,"w write support\n");
1023 (void) FormatLocaleFile(file,"+ support for multiple images\n");
cristy3ed852e2009-09-05 21:47:34 +00001024 (void) fflush(file);
1025 magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1026 magick_info);
1027 return(MagickTrue);
1028}
1029
1030/*
1031%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1032% %
1033% %
1034% %
cristy019459e2014-01-02 23:47:13 +00001035% I s M a g i c k C o r e I n s t a n t i a t e d %
cristy3ed852e2009-09-05 21:47:34 +00001036% %
1037% %
1038% %
1039%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1040%
cristy019459e2014-01-02 23:47:13 +00001041% IsMagickCoreInstantiated() returns MagickTrue if the ImageMagick environment
cristy3ed852e2009-09-05 21:47:34 +00001042% is currently instantiated: MagickCoreGenesis() has been called but
1043% MagickDestroy() has not.
1044%
cristy019459e2014-01-02 23:47:13 +00001045% The format of the IsMagickCoreInstantiated method is:
cristy3ed852e2009-09-05 21:47:34 +00001046%
cristy019459e2014-01-02 23:47:13 +00001047% MagickBooleanType IsMagickCoreInstantiated(void)
cristy3ed852e2009-09-05 21:47:34 +00001048%
1049*/
cristy019459e2014-01-02 23:47:13 +00001050MagickExport MagickBooleanType IsMagickCoreInstantiated(void)
cristy3ed852e2009-09-05 21:47:34 +00001051{
cristy0f86a122014-01-03 18:15:50 +00001052 return(instantiate_magickcore);
cristy3ed852e2009-09-05 21:47:34 +00001053}
1054
1055/*
1056%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1057% %
1058% %
1059% %
cristyf34a1452009-10-24 22:29:27 +00001060+ M a g i c k C o m p o n e n t G e n e s i s %
1061% %
1062% %
1063% %
1064%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1065%
1066% MagickComponentGenesis() instantiates the magick component.
1067%
1068% The format of the MagickComponentGenesis method is:
1069%
1070% MagickBooleanType MagickComponentGenesis(void)
1071%
1072*/
cristy5ff4eaf2011-09-03 01:38:02 +00001073MagickPrivate MagickBooleanType MagickComponentGenesis(void)
cristyf34a1452009-10-24 22:29:27 +00001074{
cristy7c977062014-04-04 14:05:53 +00001075 if (magick_semaphore == (SemaphoreInfo *) NULL)
1076 magick_semaphore=AcquireSemaphoreInfo();
cristyf34a1452009-10-24 22:29:27 +00001077 return(MagickTrue);
1078}
1079
1080/*
1081%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1082% %
1083% %
1084% %
1085+ M a g i c k C o m p o n e n t T e r m i n u s %
1086% %
1087% %
1088% %
1089%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1090%
1091% MagickComponentTerminus() destroys the magick component.
1092%
1093% The format of the MagickComponentTerminus method is:
1094%
1095% void MagickComponentTerminus(void)
1096%
1097*/
cristy5ff4eaf2011-09-03 01:38:02 +00001098MagickPrivate void MagickComponentTerminus(void)
cristyf34a1452009-10-24 22:29:27 +00001099{
cristy18b17442009-10-25 18:36:48 +00001100 if (magick_semaphore == (SemaphoreInfo *) NULL)
cristy04b11db2014-02-16 15:10:39 +00001101 ActivateSemaphoreInfo(&magick_semaphore);
cristyf84a1932010-01-03 18:00:18 +00001102 LockSemaphoreInfo(magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001103 if (magick_list != (SplayTreeInfo *) NULL)
1104 magick_list=DestroySplayTree(magick_list);
cristyf84a1932010-01-03 18:00:18 +00001105 UnlockSemaphoreInfo(magick_semaphore);
cristy3d162a92014-02-16 14:05:06 +00001106 RelinquishSemaphoreInfo(&magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001107}
1108
1109/*
1110%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1111% %
1112% %
1113% %
cristy3ed852e2009-09-05 21:47:34 +00001114% M a g i c k C o r e G e n e s i s %
1115% %
1116% %
1117% %
1118%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1119%
1120% MagickCoreGenesis() initializes the MagickCore environment.
1121%
1122% The format of the MagickCoreGenesis function is:
1123%
1124% MagickCoreGenesis(const char *path,
1125% const MagickBooleanType establish_signal_handlers)
1126%
1127% A description of each parameter follows:
1128%
1129% o path: the execution path of the current ImageMagick client.
1130%
1131% o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1132% signal handlers for common signals.
1133%
1134*/
1135
1136static SignalHandler *SetMagickSignalHandler(int signal_number,
1137 SignalHandler *handler)
1138{
1139#if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1140 int
1141 status;
1142
1143 sigset_t
1144 mask;
1145
1146 struct sigaction
1147 action,
1148 previous_action;
1149
1150 sigemptyset(&mask);
1151 sigaddset(&mask,signal_number);
1152 sigprocmask(SIG_BLOCK,&mask,NULL);
1153 action.sa_mask=mask;
1154 action.sa_handler=handler;
1155 action.sa_flags=0;
1156#if defined(SA_INTERRUPT)
1157 action.sa_flags|=SA_INTERRUPT;
1158#endif
1159 status=sigaction(signal_number,&action,&previous_action);
1160 if (status < 0)
1161 return(SIG_ERR);
1162 sigprocmask(SIG_UNBLOCK,&mask,NULL);
1163 return(previous_action.sa_handler);
1164#else
1165 return(signal(signal_number,handler));
1166#endif
1167}
1168
1169static void MagickSignalHandler(int signal_number)
1170{
1171#if !defined(MAGICKCORE_HAVE_SIGACTION)
1172 (void) signal(signal_number,SIG_IGN);
1173#endif
cristyf34a1452009-10-24 22:29:27 +00001174 AsynchronousResourceComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001175 (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
cristy5f03dab2011-02-20 21:55:17 +00001176#if defined(SIGQUIT)
1177 if (signal_number == SIGQUIT)
1178 abort();
1179#endif
1180#if defined(SIGABRT)
1181 if (signal_number == SIGABRT)
1182 abort();
1183#endif
1184#if defined(SIGFPE)
1185 if (signal_number == SIGFPE)
1186 abort();
1187#endif
1188#if defined(SIGXCPU)
1189 if (signal_number == SIGXCPU)
1190 abort();
1191#endif
1192#if defined(SIGXFSZ)
1193 if (signal_number == SIGXFSZ)
1194 abort();
1195#endif
cristy32a348b2011-04-22 16:03:42 +00001196#if defined(SIGSEGV)
1197 if (signal_number == SIGSEGV)
cristy7ae29582011-04-21 16:10:06 +00001198 abort();
1199#endif
cristy3ed852e2009-09-05 21:47:34 +00001200#if !defined(MAGICKCORE_HAVE__EXIT)
1201 exit(signal_number);
1202#else
1203#if defined(SIGHUP)
1204 if (signal_number == SIGHUP)
1205 exit(signal_number);
1206#endif
cristy0157aea2010-04-24 21:12:18 +00001207#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001208 if (signal_number == SIGINT)
1209 exit(signal_number);
1210#endif
1211#if defined(SIGTERM)
1212 if (signal_number == SIGTERM)
1213 exit(signal_number);
1214#endif
cristyad9c7d02013-01-08 02:03:52 +00001215#if defined(MAGICKCORE_HAVE_RAISE)
1216 if (signal_handlers[signal_number] != MagickSignalHandler)
1217 raise(signal_number);
1218#endif
cristy70bda3d2011-02-20 21:58:06 +00001219 _exit(signal_number); /* do not invoke registered atexit() methods */
cristy3ed852e2009-09-05 21:47:34 +00001220#endif
1221}
1222
1223static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1224{
1225 SignalHandler
1226 *handler;
1227
1228 handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1229 if (handler == SIG_ERR)
1230 return(handler);
1231 if (handler != SIG_DFL)
1232 handler=SetMagickSignalHandler(signal_number,handler);
1233 else
1234 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1235 "Register handler for signal: %d",signal_number);
1236 return(handler);
1237}
1238
1239MagickExport void MagickCoreGenesis(const char *path,
1240 const MagickBooleanType establish_signal_handlers)
1241{
1242 char
1243 *events,
1244 execution_path[MaxTextExtent],
1245 filename[MaxTextExtent];
1246
cristy3ed852e2009-09-05 21:47:34 +00001247 /*
1248 Initialize the Magick environment.
1249 */
cristy1ea02a32014-01-24 11:23:14 +00001250 InitializeMagickMutex();
cristyd1ebf4a2010-05-13 01:54:31 +00001251 LockMagickMutex();
1252 if (instantiate_magickcore != MagickFalse)
1253 {
1254 UnlockMagickMutex();
1255 return;
1256 }
cristyf34a1452009-10-24 22:29:27 +00001257 (void) SemaphoreComponentGenesis();
1258 (void) LogComponentGenesis();
1259 (void) LocaleComponentGenesis();
1260 (void) RandomComponentGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001261 events=GetEnvironmentValue("MAGICK_DEBUG");
1262 if (events != (char *) NULL)
1263 {
1264 (void) SetLogEventMask(events);
1265 events=DestroyString(events);
1266 }
cristy0157aea2010-04-24 21:12:18 +00001267#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy9f3b4fc2014-02-08 14:56:20 +00001268 NTWindowsGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001269#endif
1270 /*
1271 Set client name and execution path.
1272 */
1273 (void) GetExecutionPath(execution_path,MaxTextExtent);
cristy695e8c32011-11-09 18:27:04 +00001274 if ((path != (const char *) NULL) && (*path == *DirectorySeparator) &&
cristy905e5302011-11-09 18:08:43 +00001275 (IsPathAccessible(path) != MagickFalse))
cristy3ed852e2009-09-05 21:47:34 +00001276 (void) CopyMagickString(execution_path,path,MaxTextExtent);
1277 GetPathComponent(execution_path,TailPath,filename);
1278 (void) SetClientName(filename);
1279 GetPathComponent(execution_path,HeadPath,execution_path);
1280 (void) SetClientPath(execution_path);
1281 if (establish_signal_handlers != MagickFalse)
1282 {
1283 /*
1284 Set signal handlers.
1285 */
1286#if defined(SIGABRT)
1287 if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1288 signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1289#endif
cristy32a348b2011-04-22 16:03:42 +00001290#if defined(SIGSEGV)
1291 if (signal_handlers[SIGSEGV] == (SignalHandler *) NULL)
1292 signal_handlers[SIGSEGV]=RegisterMagickSignalHandler(SIGSEGV);
cristy7ae29582011-04-21 16:10:06 +00001293#endif
cristy3ed852e2009-09-05 21:47:34 +00001294#if defined(SIGFPE)
1295 if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1296 signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1297#endif
1298#if defined(SIGHUP)
1299 if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1300 signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1301#endif
cristy0157aea2010-04-24 21:12:18 +00001302#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001303 if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1304 signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1305#endif
1306#if defined(SIGQUIT)
1307 if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1308 signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1309#endif
1310#if defined(SIGTERM)
1311 if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1312 signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1313#endif
1314#if defined(SIGXCPU)
1315 if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1316 signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1317#endif
1318#if defined(SIGXFSZ)
1319 if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1320 signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1321#endif
1322 }
1323 /*
cristyaf8b5cd2009-10-24 00:29:23 +00001324 Instantiate magick resources.
cristy3ed852e2009-09-05 21:47:34 +00001325 */
cristy18b17442009-10-25 18:36:48 +00001326 (void) ConfigureComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001327 (void) PolicyComponentGenesis();
1328 (void) CacheComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001329 (void) ResourceComponentGenesis();
1330 (void) CoderComponentGenesis();
1331 (void) MagickComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001332#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001333 (void) ModuleComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001334#endif
cristyf34a1452009-10-24 22:29:27 +00001335 (void) DelegateComponentGenesis();
1336 (void) MagicComponentGenesis();
1337 (void) ColorComponentGenesis();
1338 (void) TypeComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001339 (void) MimeComponentGenesis();
cristyd7ecaca2011-01-24 14:14:53 +00001340 (void) AnnotateComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001341#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001342 (void) XComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001343#endif
cristy8a23f662014-03-26 20:58:19 +00001344 (void) RegistryComponentGenesis();
cristyd1ebf4a2010-05-13 01:54:31 +00001345 instantiate_magickcore=MagickTrue;
1346 UnlockMagickMutex();
cristy3ed852e2009-09-05 21:47:34 +00001347}
1348
1349/*
1350%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1351% %
1352% %
1353% %
1354% M a g i c k C o r e T e r m i n u s %
1355% %
1356% %
1357% %
1358%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1359%
1360% MagickCoreTerminus() destroys the MagickCore environment.
1361%
cristyf34a1452009-10-24 22:29:27 +00001362% The format of the MagickCoreTerminus function is:
cristy3ed852e2009-09-05 21:47:34 +00001363%
1364% MagickCoreTerminus(void)
1365%
1366*/
1367MagickExport void MagickCoreTerminus(void)
1368{
cristy1ea02a32014-01-24 11:23:14 +00001369 InitializeMagickMutex();
cristyd1ebf4a2010-05-13 01:54:31 +00001370 LockMagickMutex();
1371 if (instantiate_magickcore == MagickFalse)
1372 {
1373 UnlockMagickMutex();
1374 return;
1375 }
cristy8a23f662014-03-26 20:58:19 +00001376 RegistryComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001377#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001378 XComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001379#endif
cristyd7ecaca2011-01-24 14:14:53 +00001380 AnnotateComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001381 MimeComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001382 TypeComponentTerminus();
1383 ColorComponentTerminus();
cristy0157aea2010-04-24 21:12:18 +00001384#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001385 NTGhostscriptUnLoadDLL();
1386#endif
cristyf34a1452009-10-24 22:29:27 +00001387 MagicComponentTerminus();
1388 DelegateComponentTerminus();
1389 MagickComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001390#if !defined(MAGICKCORE_BUILD_MODULES)
1391 UnregisterStaticModules();
1392#endif
1393#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001394 ModuleComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001395#endif
cristyf34a1452009-10-24 22:29:27 +00001396 CoderComponentTerminus();
1397 ResourceComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001398 CacheComponentTerminus();
1399 PolicyComponentTerminus();
cristy18b17442009-10-25 18:36:48 +00001400 ConfigureComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001401 RandomComponentTerminus();
1402 LocaleComponentTerminus();
1403 LogComponentTerminus();
1404 SemaphoreComponentTerminus();
cristyd1ebf4a2010-05-13 01:54:31 +00001405 instantiate_magickcore=MagickFalse;
1406 UnlockMagickMutex();
cristy1ea02a32014-01-24 11:23:14 +00001407 DestroyMagickMutex();
cristy3ed852e2009-09-05 21:47:34 +00001408}
1409
1410/*
1411%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1412% %
1413% %
1414% %
1415+ R e g i s t e r M a g i c k I n f o %
1416% %
1417% %
1418% %
1419%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1420%
1421% RegisterMagickInfo() adds attributes for a particular image format to the
1422% list of supported formats. The attributes include the image format name,
1423% a method to read and/or write the format, whether the format supports the
1424% saving of more than one frame to the same file or blob, whether the format
1425% supports native in-memory I/O, and a brief description of the format.
1426%
1427% The format of the RegisterMagickInfo method is:
1428%
1429% MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1430%
1431% A description of each parameter follows:
1432%
1433% o magick_info: the magick info.
1434%
1435*/
1436MagickExport MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1437{
1438 MagickBooleanType
1439 status;
1440
1441 /*
cristybb2ab822014-06-27 20:53:42 +00001442 Register a new image format.
cristy3ed852e2009-09-05 21:47:34 +00001443 */
1444 assert(magick_info != (MagickInfo *) NULL);
1445 assert(magick_info->signature == MagickSignature);
1446 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
1447 if (magick_list == (SplayTreeInfo *) NULL)
1448 return((MagickInfo *) NULL);
dirk4b6408d2014-06-27 20:24:29 +00001449 if (((magick_info->thread_support & DecoderThreadSupport) == 0) ||
1450 ((magick_info->thread_support & EncoderThreadSupport) == 0))
cristycd2cd182014-03-18 12:10:55 +00001451 magick_info->semaphore=AcquireSemaphoreInfo();
cristy3ed852e2009-09-05 21:47:34 +00001452 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1453 if (status == MagickFalse)
1454 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1455 return(magick_info);
1456}
1457
1458/*
1459%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1460% %
1461% %
1462% %
1463+ S e t M a g i c k I n f o %
1464% %
1465% %
1466% %
1467%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1468%
1469% SetMagickInfo() allocates a MagickInfo structure and initializes the members
1470% to default values.
1471%
1472% The format of the SetMagickInfo method is:
1473%
1474% MagickInfo *SetMagickInfo(const char *name)
1475%
1476% A description of each parameter follows:
1477%
1478% o magick_info: Method SetMagickInfo returns the allocated and initialized
1479% MagickInfo structure.
1480%
1481% o name: a character string that represents the image format associated
1482% with the MagickInfo structure.
1483%
1484*/
1485MagickExport MagickInfo *SetMagickInfo(const char *name)
1486{
1487 MagickInfo
1488 *magick_info;
1489
1490 assert(name != (const char *) NULL);
1491 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
cristy73bd4a52010-10-05 11:24:23 +00001492 magick_info=(MagickInfo *) AcquireMagickMemory(sizeof(*magick_info));
cristy3ed852e2009-09-05 21:47:34 +00001493 if (magick_info == (MagickInfo *) NULL)
1494 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1495 (void) ResetMagickMemory(magick_info,0,sizeof(*magick_info));
1496 magick_info->name=ConstantString(name);
1497 magick_info->adjoin=MagickTrue;
1498 magick_info->blob_support=MagickTrue;
1499 magick_info->thread_support=(MagickStatusType) (DecoderThreadSupport |
1500 EncoderThreadSupport);
1501 magick_info->signature=MagickSignature;
1502 return(magick_info);
1503}
1504
1505/*
1506%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1507% %
1508% %
1509% %
cristye7f51092010-01-17 00:39:37 +00001510% S e t M a g i c k P r e c i s i o n %
1511% %
1512% %
1513% %
1514%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1515%
1516% SetMagickPrecision() sets the maximum number of significant digits to be
anthonybc6fc132012-01-16 07:02:46 +00001517% printed.
1518%
1519% An input argument of 0 returns the current precision setting.
1520%
cristyabdd5b72012-01-18 03:02:15 +00001521% A negative value forces the precision to reset to a default value according
1522% to the environment variable "MAGICK_PRECISION", the current 'policy'
1523% configuration setting, or the default value of '6', in that order.
cristye7f51092010-01-17 00:39:37 +00001524%
1525% The format of the SetMagickPrecision method is:
1526%
cristybf2766a2010-01-17 03:33:23 +00001527% int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001528%
1529% A description of each parameter follows:
1530%
1531% o precision: set the maximum number of significant digits to be printed.
1532%
1533*/
cristybf2766a2010-01-17 03:33:23 +00001534MagickExport int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001535{
anthonybc6fc132012-01-16 07:02:46 +00001536#define MagickPrecision 6
1537
cristybf2766a2010-01-17 03:33:23 +00001538 static int
1539 magick_precision = 0;
1540
cristye7f51092010-01-17 00:39:37 +00001541 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
anthony82c09922012-01-16 06:38:16 +00001542 if (precision > 0)
cristyabdd5b72012-01-18 03:02:15 +00001543 magick_precision=precision;
1544 if ((precision < 0) || (magick_precision == 0))
anthonybc6fc132012-01-16 07:02:46 +00001545 {
1546 char
1547 *limit;
1548
1549 /*
cristyabdd5b72012-01-18 03:02:15 +00001550 Precision reset, or it has not been set yet
anthonybc6fc132012-01-16 07:02:46 +00001551 */
1552 magick_precision = MagickPrecision;
1553 limit=GetEnvironmentValue("MAGICK_PRECISION");
1554 if (limit == (char *) NULL)
1555 limit=GetPolicyValue("precision");
1556 if (limit != (char *) NULL)
1557 {
cristyabdd5b72012-01-18 03:02:15 +00001558 magick_precision=StringToInteger(limit);
anthonybc6fc132012-01-16 07:02:46 +00001559 limit=DestroyString(limit);
1560 }
1561 }
cristybf2766a2010-01-17 03:33:23 +00001562 return(magick_precision);
cristye7f51092010-01-17 00:39:37 +00001563}
1564
1565/*
1566%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1567% %
1568% %
1569% %
cristy3ed852e2009-09-05 21:47:34 +00001570+ U n r e g i s t e r M a g i c k I n f o %
1571% %
1572% %
1573% %
1574%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1575%
1576% UnregisterMagickInfo() removes a name from the magick info list. It returns
1577% MagickFalse if the name does not exist in the list otherwise MagickTrue.
1578%
1579% The format of the UnregisterMagickInfo method is:
1580%
1581% MagickBooleanType UnregisterMagickInfo(const char *name)
1582%
1583% A description of each parameter follows:
1584%
1585% o name: a character string that represents the image format we are
1586% looking for.
1587%
1588*/
1589MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1590{
1591 register const MagickInfo
1592 *p;
1593
1594 MagickBooleanType
1595 status;
1596
1597 assert(name != (const char *) NULL);
1598 if (magick_list == (SplayTreeInfo *) NULL)
1599 return(MagickFalse);
1600 if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1601 return(MagickFalse);
cristyf84a1932010-01-03 18:00:18 +00001602 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001603 ResetSplayTreeIterator(magick_list);
1604 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1605 while (p != (const MagickInfo *) NULL)
1606 {
1607 if (LocaleCompare(p->name,name) == 0)
1608 break;
1609 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1610 }
1611 status=DeleteNodeByValueFromSplayTree(magick_list,p);
cristyf84a1932010-01-03 18:00:18 +00001612 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001613 return(status);
1614}