blob: e59d6e92fedbad123c5d77d3f16b0a09b1f4f713 [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"
cristy5ff4eaf2011-09-03 01:38:02 +000068#include "MagickCore/random-private.h"
cristy4c08aed2011-07-01 19:47:50 +000069#include "MagickCore/registry.h"
cristy5ff4eaf2011-09-03 01:38:02 +000070#include "MagickCore/registry-private.h"
cristy4c08aed2011-07-01 19:47:50 +000071#include "MagickCore/resource_.h"
cristy0a4d92f2011-08-31 19:25:00 +000072#include "MagickCore/resource-private.h"
cristy4c08aed2011-07-01 19:47:50 +000073#include "MagickCore/policy.h"
cristy5ff4eaf2011-09-03 01:38:02 +000074#include "MagickCore/policy-private.h"
cristy4c08aed2011-07-01 19:47:50 +000075#include "MagickCore/semaphore.h"
76#include "MagickCore/semaphore-private.h"
77#include "MagickCore/signature-private.h"
78#include "MagickCore/splay-tree.h"
79#include "MagickCore/string_.h"
80#include "MagickCore/string-private.h"
81#include "MagickCore/thread_.h"
82#include "MagickCore/thread-private.h"
cristy5ff4eaf2011-09-03 01:38:02 +000083#include "MagickCore/type-private.h"
cristy4c08aed2011-07-01 19:47:50 +000084#include "MagickCore/token.h"
85#include "MagickCore/utility.h"
cristyd1dd6e42011-09-04 01:46:08 +000086#include "MagickCore/utility-private.h"
cristy4c08aed2011-07-01 19:47:50 +000087#include "MagickCore/xwindow-private.h"
cristy3ed852e2009-09-05 21:47:34 +000088
89/*
90 Define declarations.
91*/
92#if !defined(MAGICKCORE_RETSIGTYPE)
93# define MAGICKCORE_RETSIGTYPE void
94#endif
95#if !defined(SIG_DFL)
96# define SIG_DFL ((SignalHandler *) 0)
97#endif
98#if !defined(SIG_ERR)
99# define SIG_ERR ((SignalHandler *) -1)
100#endif
101#if !defined(SIGMAX)
102#define SIGMAX 64
103#endif
104
105/*
106 Typedef declarations.
107*/
108typedef MAGICKCORE_RETSIGTYPE
109 SignalHandler(int);
110
111/*
112 Global declarations.
113*/
114static SemaphoreInfo
115 *magick_semaphore = (SemaphoreInfo *) NULL;
116
117static SignalHandler
118 *signal_handlers[SIGMAX] = { (SignalHandler *) NULL };
119
120static SplayTreeInfo
121 *magick_list = (SplayTreeInfo *) NULL;
122
123static volatile MagickBooleanType
cristyd1ebf4a2010-05-13 01:54:31 +0000124 instantiate_magickcore = MagickFalse;
cristy3ed852e2009-09-05 21:47:34 +0000125
126/*
127 Forward declarations.
128*/
129static MagickBooleanType
130 InitializeMagickList(ExceptionInfo *);
131
132/*
133%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134% %
135% %
136% %
cristy3ed852e2009-09-05 21:47:34 +0000137+ G e t I m a g e D e c o d e r %
138% %
139% %
140% %
141%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142%
143% GetImageDecoder() returns the image decoder.
144%
145% The format of the GetImageDecoder method is:
146%
147% DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
148%
149% A description of each parameter follows:
150%
151% o magick_info: The magick info.
152%
153*/
154MagickExport DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
155{
156 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
157 assert(magick_info != (MagickInfo *) NULL);
158 assert(magick_info->signature == MagickSignature);
159 return(magick_info->decoder);
160}
161
162/*
163%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164% %
165% %
166% %
167+ G e t I m a g e E n c o d e r %
168% %
169% %
170% %
171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172%
173% GetImageEncoder() returns the image encoder.
174%
175% The format of the GetImageEncoder method is:
176%
177% EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
178%
179% A description of each parameter follows:
180%
181% o magick_info: The magick info.
182%
183*/
184MagickExport EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
185{
186 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
187 assert(magick_info != (MagickInfo *) NULL);
188 assert(magick_info->signature == MagickSignature);
189 return(magick_info->encoder);
190}
191
192/*
193%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
194% %
195% %
196% %
197+ G e t I m a g e M a g i c k %
198% %
199% %
200% %
201%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
202%
203% GetImageMagick() searches for an image format that matches the specified
204% magick string. If one is found, MagickTrue is returned otherwise
205% MagickFalse.
206%
207% The format of the GetImageMagick method is:
208%
209% MagickBooleanType GetImageMagick(const unsigned char *magick,
210% const size_t length,char *format)
211%
212% A description of each parameter follows:
213%
214% o magick: the image format we are searching for.
215%
216% o length: the length of the binary string.
217%
218% o format: the image format as determined by the magick bytes.
219%
220*/
221MagickExport MagickBooleanType GetImageMagick(const unsigned char *magick,
222 const size_t length,char *format)
223{
224 ExceptionInfo
225 *exception;
226
227 MagickBooleanType
228 status;
229
230 register const MagickInfo
231 *p;
232
233 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
234 assert(magick != (const unsigned char *) NULL);
235 exception=AcquireExceptionInfo();
236 p=GetMagickInfo("*",exception);
237 exception=DestroyExceptionInfo(exception);
238 if (p == (const MagickInfo *) NULL)
239 return(MagickFalse);
240 status=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +0000241 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000242 ResetSplayTreeIterator(magick_list);
243 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
244 while (p != (const MagickInfo *) NULL)
245 {
246 if ((p->magick != (IsImageFormatHandler *) NULL) &&
247 (p->magick(magick,length) != 0))
248 {
249 status=MagickTrue;
250 (void) CopyMagickString(format,p->name,MaxTextExtent);
251 break;
252 }
253 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
254 }
cristyf84a1932010-01-03 18:00:18 +0000255 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000256 return(status);
257}
258
259/*
260%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261% %
262% %
263% %
264+ G e t M a g i c k A d j o i n %
265% %
266% %
267% %
268%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
269%
270% GetMagickAdjoin() returns MagickTrue if the magick adjoin is MagickTrue.
271%
272% The format of the GetMagickAdjoin method is:
273%
274% MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
275%
276% A description of each parameter follows:
277%
278% o magick_info: The magick info.
279%
280*/
281MagickExport MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
282{
283 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
284 assert(magick_info != (MagickInfo *) NULL);
285 assert(magick_info->signature == MagickSignature);
286 return(magick_info->adjoin);
287}
288
289/*
290%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
291% %
292% %
293% %
294+ G e t M a g i c k B l o b S u p p o r t %
295% %
296% %
297% %
298%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
299%
300% GetMagickBlobSupport() returns MagickTrue if the magick supports blobs.
301%
302% The format of the GetMagickBlobSupport method is:
303%
304% MagickBooleanType GetMagickBlobSupport(const MagickInfo *magick_info)
305%
306% A description of each parameter follows:
307%
308% o magick_info: The magick info.
309%
310*/
311MagickExport MagickBooleanType GetMagickBlobSupport(
312 const MagickInfo *magick_info)
313{
314 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
315 assert(magick_info != (MagickInfo *) NULL);
316 assert(magick_info->signature == MagickSignature);
317 return(magick_info->blob_support);
318}
319
320/*
321%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
322% %
323% %
324% %
325+ G e t M a g i c k D e s c r i p t i o n %
326% %
327% %
328% %
329%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
330%
331% GetMagickDescription() returns the magick description.
332%
333% The format of the GetMagickDescription method is:
334%
335% const char *GetMagickDescription(const MagickInfo *magick_info)
336%
337% A description of each parameter follows:
338%
339% o magick_info: The magick info.
340%
341*/
342MagickExport const char *GetMagickDescription(const MagickInfo *magick_info)
343{
344 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
345 assert(magick_info != (MagickInfo *) NULL);
346 assert(magick_info->signature == MagickSignature);
347 return(magick_info->description);
348}
349
350/*
351%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
352% %
353% %
354% %
355+ G e t M a g i c k E n d i a n S u p p o r t %
356% %
357% %
358% %
359%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
360%
361% GetMagickEndianSupport() returns the MagickTrue if the coder respects
362% endianness other than MSBEndian.
363%
364% The format of the GetMagickEndianSupport method is:
365%
366% MagickBooleanType GetMagickEndianSupport(const MagickInfo *magick_info)
367%
368% A description of each parameter follows:
369%
370% o magick_info: The magick info.
371%
372*/
373MagickExport MagickBooleanType GetMagickEndianSupport(
374 const MagickInfo *magick_info)
375{
376 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
377 assert(magick_info != (MagickInfo *) NULL);
378 assert(magick_info->signature == MagickSignature);
379 return(magick_info->endian_support);
380}
381
382/*
383%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
384% %
385% %
386% %
387+ G e t M a g i c k I n f o %
388% %
389% %
390% %
391%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
392%
393% GetMagickInfo() returns a pointer MagickInfo structure that matches
394% the specified name. If name is NULL, the head of the image format list
395% is returned.
396%
397% The format of the GetMagickInfo method is:
398%
399% const MagickInfo *GetMagickInfo(const char *name,Exception *exception)
400%
401% A description of each parameter follows:
402%
403% o name: the image format we are looking for.
404%
405% o exception: return any errors or warnings in this structure.
406%
407*/
408MagickExport const MagickInfo *GetMagickInfo(const char *name,
409 ExceptionInfo *exception)
410{
411 register const MagickInfo
412 *p;
413
414 assert(exception != (ExceptionInfo *) NULL);
cristy1460f262014-03-15 17:38:05 +0000415 if (magick_list == (SplayTreeInfo *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000416 if (InitializeMagickList(exception) == MagickFalse)
417 return((const MagickInfo *) NULL);
418 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
419 {
420#if defined(MAGICKCORE_MODULES_SUPPORT)
421 if (LocaleCompare(name,"*") == 0)
422 (void) OpenModules(exception);
423#endif
cristyf84a1932010-01-03 18:00:18 +0000424 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000425 ResetSplayTreeIterator(magick_list);
426 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
cristyf84a1932010-01-03 18:00:18 +0000427 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000428 return(p);
429 }
430 /*
431 Find name in list.
432 */
cristyf84a1932010-01-03 18:00:18 +0000433 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000434 ResetSplayTreeIterator(magick_list);
435 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
436 while (p != (const MagickInfo *) NULL)
437 {
438 if (LocaleCompare(p->name,name) == 0)
439 break;
440 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
441 }
442#if defined(MAGICKCORE_MODULES_SUPPORT)
443 if (p == (const MagickInfo *) NULL)
444 {
445 if (*name != '\0')
446 (void) OpenModule(name,exception);
447 ResetSplayTreeIterator(magick_list);
448 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
449 while (p != (const MagickInfo *) NULL)
450 {
451 if (LocaleCompare(p->name,name) == 0)
452 break;
453 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
454 }
455 }
456#endif
cristyf84a1932010-01-03 18:00:18 +0000457 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000458 return(p);
459}
460
461/*
462%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
463% %
464% %
465% %
466+ G e t M a g i c k I n f o L i s t %
467% %
468% %
469% %
470%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
471%
472% GetMagickInfoList() returns any image formats that match the specified
473% pattern.
474%
475% The format of the GetMagickInfoList function is:
476%
477% const MagickInfo **GetMagickInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000478% size_t *number_formats,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000479%
480% A description of each parameter follows:
481%
482% o pattern: Specifies a pointer to a text string containing a pattern.
483%
484% o number_formats: This integer returns the number of formats in the list.
485%
486% o exception: return any errors or warnings in this structure.
487%
488*/
489
490#if defined(__cplusplus) || defined(c_plusplus)
491extern "C" {
492#endif
493
494static int MagickInfoCompare(const void *x,const void *y)
495{
496 const MagickInfo
497 **p,
498 **q;
499
500 p=(const MagickInfo **) x,
501 q=(const MagickInfo **) y;
502 return(LocaleCompare((*p)->name,(*q)->name));
503}
504
505#if defined(__cplusplus) || defined(c_plusplus)
506}
507#endif
508
509MagickExport const MagickInfo **GetMagickInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000510 size_t *number_formats,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000511{
512 const MagickInfo
513 **formats;
514
515 register const MagickInfo
516 *p;
517
cristybb503372010-05-27 20:51:26 +0000518 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000519 i;
520
521 /*
522 Allocate magick list.
523 */
524 assert(pattern != (char *) NULL);
525 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000526 assert(number_formats != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000527 *number_formats=0;
528 p=GetMagickInfo("*",exception);
529 if (p == (const MagickInfo *) NULL)
530 return((const MagickInfo **) NULL);
531 formats=(const MagickInfo **) AcquireQuantumMemory((size_t)
532 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
533 if (formats == (const MagickInfo **) NULL)
534 return((const MagickInfo **) NULL);
535 /*
536 Generate magick list.
537 */
cristyf84a1932010-01-03 18:00:18 +0000538 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000539 ResetSplayTreeIterator(magick_list);
540 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
541 for (i=0; p != (const MagickInfo *) NULL; )
542 {
543 if ((p->stealth == MagickFalse) &&
544 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
545 formats[i++]=p;
546 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
547 }
cristyf84a1932010-01-03 18:00:18 +0000548 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000549 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickInfoCompare);
550 formats[i]=(MagickInfo *) NULL;
cristybb503372010-05-27 20:51:26 +0000551 *number_formats=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000552 return(formats);
553}
554
555/*
556%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
557% %
558% %
559% %
560+ G e t M a g i c k L i s t %
561% %
562% %
563% %
564%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
565%
566% GetMagickList() returns any image formats that match the specified pattern.
567%
568% The format of the GetMagickList function is:
569%
cristybb503372010-05-27 20:51:26 +0000570% char **GetMagickList(const char *pattern,size_t *number_formats,
cristy3ed852e2009-09-05 21:47:34 +0000571% ExceptionInfo *exception)
572%
573% A description of each parameter follows:
574%
575% o pattern: Specifies a pointer to a text string containing a pattern.
576%
577% o number_formats: This integer returns the number of formats in the list.
578%
579% o exception: return any errors or warnings in this structure.
580%
581*/
582
583#if defined(__cplusplus) || defined(c_plusplus)
584extern "C" {
585#endif
586
587static int MagickCompare(const void *x,const void *y)
588{
589 register const char
590 **p,
591 **q;
592
593 p=(const char **) x;
594 q=(const char **) y;
595 return(LocaleCompare(*p,*q));
596}
597
598#if defined(__cplusplus) || defined(c_plusplus)
599}
600#endif
601
602MagickExport char **GetMagickList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000603 size_t *number_formats,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000604{
605 char
606 **formats;
607
608 register const MagickInfo
609 *p;
610
cristybb503372010-05-27 20:51:26 +0000611 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000612 i;
613
614 /*
615 Allocate magick list.
616 */
617 assert(pattern != (char *) NULL);
618 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000619 assert(number_formats != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000620 *number_formats=0;
621 p=GetMagickInfo("*",exception);
622 if (p == (const MagickInfo *) NULL)
623 return((char **) NULL);
624 formats=(char **) AcquireQuantumMemory((size_t)
625 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
626 if (formats == (char **) NULL)
627 return((char **) NULL);
cristyf84a1932010-01-03 18:00:18 +0000628 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000629 ResetSplayTreeIterator(magick_list);
630 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
631 for (i=0; p != (const MagickInfo *) NULL; )
632 {
633 if ((p->stealth == MagickFalse) &&
634 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
635 formats[i++]=ConstantString(p->name);
636 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
637 }
cristyf84a1932010-01-03 18:00:18 +0000638 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000639 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickCompare);
640 formats[i]=(char *) NULL;
cristybb503372010-05-27 20:51:26 +0000641 *number_formats=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000642 return(formats);
643}
644
645/*
646%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
647% %
648% %
649% %
cristy4a6ab482013-08-09 01:29:35 +0000650+ G e t M a g i c k M i m e T y p e %
651% %
652% %
653% %
654%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
655%
656% GetMagickMimeType() returns the magick mime type.
657%
658% The format of the GetMagickMimeType method is:
659%
660% const char *GetMagickMimeType(const MagickInfo *magick_info)
661%
662% A description of each parameter follows:
663%
664% o magick_info: The magick info.
665%
666*/
667MagickExport const char *GetMagickMimeType(const MagickInfo *magick_info)
668{
669 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
670 assert(magick_info != (MagickInfo *) NULL);
671 assert(magick_info->signature == MagickSignature);
672 return(magick_info->mime_type);
673}
674
675/*
676%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
677% %
678% %
679% %
cristye7f51092010-01-17 00:39:37 +0000680% G e t M a g i c k P r e c i s i o n %
cristy7ce14bc2010-01-17 00:01:01 +0000681% %
682% %
683% %
684%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
685%
686% GetMagickPrecision() returns the maximum number of significant digits to be
687% printed.
688%
689% The format of the GetMagickPrecision method is:
690%
cristye7f51092010-01-17 00:39:37 +0000691% int GetMagickPrecision(void)
cristy7ce14bc2010-01-17 00:01:01 +0000692%
693*/
cristye7f51092010-01-17 00:39:37 +0000694MagickExport int GetMagickPrecision(void)
cristy7ce14bc2010-01-17 00:01:01 +0000695{
cristy7ce14bc2010-01-17 00:01:01 +0000696 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
cristybf2766a2010-01-17 03:33:23 +0000697 return(SetMagickPrecision(0));
cristy7ce14bc2010-01-17 00:01:01 +0000698}
699
700/*
701%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
702% %
703% %
704% %
705+ 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 +0000706% %
707% %
708% %
709%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
710%
711% GetMagickRawSupport() returns the MagickTrue if the coder is a raw format.
712%
713% The format of the GetMagickRawSupport method is:
714%
715% MagickBooleanType GetMagickRawSupport(const MagickInfo *magick_info)
716%
717% A description of each parameter follows:
718%
719% o magick_info: The magick info.
720%
721*/
722MagickExport MagickBooleanType GetMagickRawSupport(
723 const MagickInfo *magick_info)
724{
725 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
726 assert(magick_info != (MagickInfo *) NULL);
727 assert(magick_info->signature == MagickSignature);
728 return(magick_info->raw);
729}
730
731/*
732%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
733% %
734% %
735% %
736+ G e t M a g i c k S e e k a b l e S t r e a m %
737% %
738% %
739% %
740%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
741%
742% GetMagickSeekableStream() returns MagickTrue if the magick supports a
743% seekable stream.
744%
745% The format of the GetMagickSeekableStream method is:
746%
747% MagickBooleanType GetMagickSeekableStream(const MagickInfo *magick_info)
748%
749% A description of each parameter follows:
750%
751% o magick_info: The magick info.
752%
753*/
754MagickExport MagickBooleanType GetMagickSeekableStream(
755 const MagickInfo *magick_info)
756{
757 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
758 assert(magick_info != (MagickInfo *) NULL);
759 assert(magick_info->signature == MagickSignature);
760 return(magick_info->seekable_stream);
761}
762
763/*
764%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
765% %
766% %
767% %
768+ G e t M a g i c k T h r e a d S u p p o r t %
769% %
770% %
771% %
772%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
773%
774% GetMagickThreadSupport() returns MagickTrue if the magick supports threads.
775%
776% The format of the GetMagickThreadSupport method is:
777%
778% MagickStatusType GetMagickThreadSupport(const MagickInfo *magick_info)
779%
780% A description of each parameter follows:
781%
782% o magick_info: The magick info.
783%
784*/
785MagickExport MagickStatusType GetMagickThreadSupport(
786 const MagickInfo *magick_info)
787{
788 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
789 assert(magick_info != (MagickInfo *) NULL);
790 assert(magick_info->signature == MagickSignature);
791 return(magick_info->thread_support);
792}
793
794/*
795%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
796% %
797% %
798% %
799+ I n i t i a l i z e M a g i c k L i s t %
800% %
801% %
802% %
803%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
804%
805% InitializeMagickList() initializes the magick list.
806%
807% The format of the InitializeMagickList() method is:
808%
809% InitializeMagickList(Exceptioninfo *exception)
810%
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);
cristy3ed852e2009-09-05 21:47:34 +0000835 return(RelinquishMagickMemory(p));
836}
837
838static MagickBooleanType InitializeMagickList(ExceptionInfo *exception)
839{
cristyf2e11662009-10-14 01:24:43 +0000840 (void) exception;
cristy1460f262014-03-15 17:38:05 +0000841 if (magick_semaphore == (SemaphoreInfo *) NULL)
842 ActivateSemaphoreInfo(&magick_semaphore);
843 LockSemaphoreInfo(magick_semaphore);
844 if (magick_list == (SplayTreeInfo *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000845 {
cristy1460f262014-03-15 17:38:05 +0000846 MagickBooleanType
847 status;
cristy3ed852e2009-09-05 21:47:34 +0000848
cristy1460f262014-03-15 17:38:05 +0000849 MagickInfo
850 *magick_info;
cristy3ed852e2009-09-05 21:47:34 +0000851
cristy1460f262014-03-15 17:38:05 +0000852 magick_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL,
853 DestroyMagickNode);
854 if (magick_list == (SplayTreeInfo *) NULL)
855 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
856 magick_info=SetMagickInfo("ephemeral");
857 magick_info->stealth=MagickTrue;
858 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
859 if (status == MagickFalse)
860 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
861 magick_info=SetMagickInfo("clipmask");
862 magick_info->stealth=MagickTrue;
863 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
864 if (status == MagickFalse)
865 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristy3ed852e2009-09-05 21:47:34 +0000866#if defined(MAGICKCORE_MODULES_SUPPORT)
cristy1460f262014-03-15 17:38:05 +0000867 (void) GetModuleInfo((char *) NULL,exception);
cristy3ed852e2009-09-05 21:47:34 +0000868#endif
869#if !defined(MAGICKCORE_BUILD_MODULES)
cristy1460f262014-03-15 17:38:05 +0000870 RegisterStaticModules();
cristy3ed852e2009-09-05 21:47:34 +0000871#endif
cristy3ed852e2009-09-05 21:47:34 +0000872 }
cristy1460f262014-03-15 17:38:05 +0000873 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000874 return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
875}
876
877/*
878%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
879% %
880% %
881% %
882+ I s M a g i c k C o n f l i c t %
883% %
884% %
885% %
886%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
887%
cristy05a9a622010-03-15 17:26:04 +0000888% IsMagickConflict() returns MagickTrue if the image format conflicts with a
889% logical drive (.e.g. X:).
cristy3ed852e2009-09-05 21:47:34 +0000890%
891% The format of the IsMagickConflict method is:
892%
893% MagickBooleanType IsMagickConflict(const char *magick)
894%
895% A description of each parameter follows:
896%
897% o magick: Specifies the image format.
898%
899*/
cristy7832dc22011-09-05 01:21:53 +0000900MagickPrivate MagickBooleanType IsMagickConflict(const char *magick)
cristy3ed852e2009-09-05 21:47:34 +0000901{
cristy3ed852e2009-09-05 21:47:34 +0000902 assert(magick != (char *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000903#if defined(macintosh)
904 return(MACIsMagickConflict(magick));
905#elif defined(vms)
906 return(VMSIsMagickConflict(magick));
cristy0157aea2010-04-24 21:12:18 +0000907#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000908 return(NTIsMagickConflict(magick));
909#else
910 return(MagickFalse);
911#endif
912}
913
914/*
915%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
916% %
917% %
918% %
919+ L i s t M a g i c k I n f o %
920% %
921% %
922% %
923%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
924%
925% ListMagickInfo() lists the image formats to a file.
926%
927% The format of the ListMagickInfo method is:
928%
929% MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
930%
931% A description of each parameter follows.
932%
933% o file: A file handle.
934%
935% o exception: return any errors or warnings in this structure.
936%
937*/
938MagickExport MagickBooleanType ListMagickInfo(FILE *file,
939 ExceptionInfo *exception)
940{
941 const MagickInfo
942 **magick_info;
943
cristybb503372010-05-27 20:51:26 +0000944 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000945 i;
946
cristybb503372010-05-27 20:51:26 +0000947 size_t
cristy3ed852e2009-09-05 21:47:34 +0000948 number_formats;
949
cristy9d314ff2011-03-09 01:30:28 +0000950 ssize_t
951 j;
952
cristy3ed852e2009-09-05 21:47:34 +0000953 if (file == (FILE *) NULL)
954 file=stdout;
955 magick_info=GetMagickInfoList("*",&number_formats,exception);
956 if (magick_info == (const MagickInfo **) NULL)
957 return(MagickFalse);
958 ClearMagickException(exception);
959#if !defined(MAGICKCORE_MODULES_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000960 (void) FormatLocaleFile(file," Format Mode Description\n");
cristy3ed852e2009-09-05 21:47:34 +0000961#else
cristyb51dff52011-05-19 16:55:47 +0000962 (void) FormatLocaleFile(file," Format Module Mode Description\n");
cristy3ed852e2009-09-05 21:47:34 +0000963#endif
cristy1e604812011-05-19 18:07:50 +0000964 (void) FormatLocaleFile(file,
965 "--------------------------------------------------------"
cristy3ed852e2009-09-05 21:47:34 +0000966 "-----------------------\n");
cristybb503372010-05-27 20:51:26 +0000967 for (i=0; i < (ssize_t) number_formats; i++)
cristy3ed852e2009-09-05 21:47:34 +0000968 {
969 if (magick_info[i]->stealth != MagickFalse)
970 continue;
cristy1e604812011-05-19 18:07:50 +0000971 (void) FormatLocaleFile(file,"%9s%c ",
972 magick_info[i]->name != (char *) NULL ? magick_info[i]->name : "",
cristy3ed852e2009-09-05 21:47:34 +0000973 magick_info[i]->blob_support != MagickFalse ? '*' : ' ');
974#if defined(MAGICKCORE_MODULES_SUPPORT)
975 {
976 char
977 module[MaxTextExtent];
978
979 *module='\0';
980 if (magick_info[i]->module != (char *) NULL)
981 (void) CopyMagickString(module,magick_info[i]->module,MaxTextExtent);
982 (void) ConcatenateMagickString(module," ",MaxTextExtent);
983 module[9]='\0';
cristyb51dff52011-05-19 16:55:47 +0000984 (void) FormatLocaleFile(file,"%9s ",module);
cristy3ed852e2009-09-05 21:47:34 +0000985 }
986#endif
cristyb51dff52011-05-19 16:55:47 +0000987 (void) FormatLocaleFile(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
cristy3ed852e2009-09-05 21:47:34 +0000988 magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
989 magick_info[i]->adjoin != MagickFalse ? '+' : '-');
990 if (magick_info[i]->description != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +0000991 (void) FormatLocaleFile(file," %s",magick_info[i]->description);
cristy3ed852e2009-09-05 21:47:34 +0000992 if (magick_info[i]->version != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +0000993 (void) FormatLocaleFile(file," (%s)",magick_info[i]->version);
994 (void) FormatLocaleFile(file,"\n");
cristy3ed852e2009-09-05 21:47:34 +0000995 if (magick_info[i]->note != (char *) NULL)
996 {
997 char
998 **text;
999
1000 text=StringToList(magick_info[i]->note);
1001 if (text != (char **) NULL)
1002 {
1003 for (j=0; text[j] != (char *) NULL; j++)
1004 {
cristyb51dff52011-05-19 16:55:47 +00001005 (void) FormatLocaleFile(file," %s\n",text[j]);
cristy3ed852e2009-09-05 21:47:34 +00001006 text[j]=DestroyString(text[j]);
1007 }
1008 text=(char **) RelinquishMagickMemory(text);
1009 }
1010 }
1011 }
cristyb51dff52011-05-19 16:55:47 +00001012 (void) FormatLocaleFile(file,"\n* native blob support\n");
1013 (void) FormatLocaleFile(file,"r read support\n");
1014 (void) FormatLocaleFile(file,"w write support\n");
1015 (void) FormatLocaleFile(file,"+ support for multiple images\n");
cristy3ed852e2009-09-05 21:47:34 +00001016 (void) fflush(file);
1017 magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1018 magick_info);
1019 return(MagickTrue);
1020}
1021
1022/*
1023%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1024% %
1025% %
1026% %
cristy019459e2014-01-02 23:47:13 +00001027% 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 +00001028% %
1029% %
1030% %
1031%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1032%
cristy019459e2014-01-02 23:47:13 +00001033% IsMagickCoreInstantiated() returns MagickTrue if the ImageMagick environment
cristy3ed852e2009-09-05 21:47:34 +00001034% is currently instantiated: MagickCoreGenesis() has been called but
1035% MagickDestroy() has not.
1036%
cristy019459e2014-01-02 23:47:13 +00001037% The format of the IsMagickCoreInstantiated method is:
cristy3ed852e2009-09-05 21:47:34 +00001038%
cristy019459e2014-01-02 23:47:13 +00001039% MagickBooleanType IsMagickCoreInstantiated(void)
cristy3ed852e2009-09-05 21:47:34 +00001040%
1041*/
cristy019459e2014-01-02 23:47:13 +00001042MagickExport MagickBooleanType IsMagickCoreInstantiated(void)
cristy3ed852e2009-09-05 21:47:34 +00001043{
cristy0f86a122014-01-03 18:15:50 +00001044 return(instantiate_magickcore);
cristy3ed852e2009-09-05 21:47:34 +00001045}
1046
1047/*
1048%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1049% %
1050% %
1051% %
cristyf34a1452009-10-24 22:29:27 +00001052+ M a g i c k C o m p o n e n t G e n e s i s %
1053% %
1054% %
1055% %
1056%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1057%
1058% MagickComponentGenesis() instantiates the magick component.
1059%
1060% The format of the MagickComponentGenesis method is:
1061%
1062% MagickBooleanType MagickComponentGenesis(void)
1063%
1064*/
cristy5ff4eaf2011-09-03 01:38:02 +00001065MagickPrivate MagickBooleanType MagickComponentGenesis(void)
cristyf34a1452009-10-24 22:29:27 +00001066{
cristy3d162a92014-02-16 14:05:06 +00001067 magick_semaphore=AcquireSemaphoreInfo();
cristyf34a1452009-10-24 22:29:27 +00001068 return(MagickTrue);
1069}
1070
1071/*
1072%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1073% %
1074% %
1075% %
1076+ M a g i c k C o m p o n e n t T e r m i n u s %
1077% %
1078% %
1079% %
1080%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1081%
1082% MagickComponentTerminus() destroys the magick component.
1083%
1084% The format of the MagickComponentTerminus method is:
1085%
1086% void MagickComponentTerminus(void)
1087%
1088*/
cristy5ff4eaf2011-09-03 01:38:02 +00001089MagickPrivate void MagickComponentTerminus(void)
cristyf34a1452009-10-24 22:29:27 +00001090{
cristy18b17442009-10-25 18:36:48 +00001091 if (magick_semaphore == (SemaphoreInfo *) NULL)
cristy04b11db2014-02-16 15:10:39 +00001092 ActivateSemaphoreInfo(&magick_semaphore);
cristyf84a1932010-01-03 18:00:18 +00001093 LockSemaphoreInfo(magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001094 if (magick_list != (SplayTreeInfo *) NULL)
1095 magick_list=DestroySplayTree(magick_list);
cristyf84a1932010-01-03 18:00:18 +00001096 UnlockSemaphoreInfo(magick_semaphore);
cristy3d162a92014-02-16 14:05:06 +00001097 RelinquishSemaphoreInfo(&magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001098}
1099
1100/*
1101%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1102% %
1103% %
1104% %
cristy3ed852e2009-09-05 21:47:34 +00001105% M a g i c k C o r e G e n e s i s %
1106% %
1107% %
1108% %
1109%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1110%
1111% MagickCoreGenesis() initializes the MagickCore environment.
1112%
1113% The format of the MagickCoreGenesis function is:
1114%
1115% MagickCoreGenesis(const char *path,
1116% const MagickBooleanType establish_signal_handlers)
1117%
1118% A description of each parameter follows:
1119%
1120% o path: the execution path of the current ImageMagick client.
1121%
1122% o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1123% signal handlers for common signals.
1124%
1125*/
1126
1127static SignalHandler *SetMagickSignalHandler(int signal_number,
1128 SignalHandler *handler)
1129{
1130#if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1131 int
1132 status;
1133
1134 sigset_t
1135 mask;
1136
1137 struct sigaction
1138 action,
1139 previous_action;
1140
1141 sigemptyset(&mask);
1142 sigaddset(&mask,signal_number);
1143 sigprocmask(SIG_BLOCK,&mask,NULL);
1144 action.sa_mask=mask;
1145 action.sa_handler=handler;
1146 action.sa_flags=0;
1147#if defined(SA_INTERRUPT)
1148 action.sa_flags|=SA_INTERRUPT;
1149#endif
1150 status=sigaction(signal_number,&action,&previous_action);
1151 if (status < 0)
1152 return(SIG_ERR);
1153 sigprocmask(SIG_UNBLOCK,&mask,NULL);
1154 return(previous_action.sa_handler);
1155#else
1156 return(signal(signal_number,handler));
1157#endif
1158}
1159
1160static void MagickSignalHandler(int signal_number)
1161{
1162#if !defined(MAGICKCORE_HAVE_SIGACTION)
1163 (void) signal(signal_number,SIG_IGN);
1164#endif
cristyf34a1452009-10-24 22:29:27 +00001165 AsynchronousResourceComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001166 (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
cristy5f03dab2011-02-20 21:55:17 +00001167#if defined(SIGQUIT)
1168 if (signal_number == SIGQUIT)
1169 abort();
1170#endif
1171#if defined(SIGABRT)
1172 if (signal_number == SIGABRT)
1173 abort();
1174#endif
1175#if defined(SIGFPE)
1176 if (signal_number == SIGFPE)
1177 abort();
1178#endif
1179#if defined(SIGXCPU)
1180 if (signal_number == SIGXCPU)
1181 abort();
1182#endif
1183#if defined(SIGXFSZ)
1184 if (signal_number == SIGXFSZ)
1185 abort();
1186#endif
cristy32a348b2011-04-22 16:03:42 +00001187#if defined(SIGSEGV)
1188 if (signal_number == SIGSEGV)
cristy7ae29582011-04-21 16:10:06 +00001189 abort();
1190#endif
cristy3ed852e2009-09-05 21:47:34 +00001191#if !defined(MAGICKCORE_HAVE__EXIT)
1192 exit(signal_number);
1193#else
1194#if defined(SIGHUP)
1195 if (signal_number == SIGHUP)
1196 exit(signal_number);
1197#endif
cristy0157aea2010-04-24 21:12:18 +00001198#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001199 if (signal_number == SIGINT)
1200 exit(signal_number);
1201#endif
1202#if defined(SIGTERM)
1203 if (signal_number == SIGTERM)
1204 exit(signal_number);
1205#endif
cristyad9c7d02013-01-08 02:03:52 +00001206#if defined(MAGICKCORE_HAVE_RAISE)
1207 if (signal_handlers[signal_number] != MagickSignalHandler)
1208 raise(signal_number);
1209#endif
cristy70bda3d2011-02-20 21:58:06 +00001210 _exit(signal_number); /* do not invoke registered atexit() methods */
cristy3ed852e2009-09-05 21:47:34 +00001211#endif
1212}
1213
1214static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1215{
1216 SignalHandler
1217 *handler;
1218
1219 handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1220 if (handler == SIG_ERR)
1221 return(handler);
1222 if (handler != SIG_DFL)
1223 handler=SetMagickSignalHandler(signal_number,handler);
1224 else
1225 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1226 "Register handler for signal: %d",signal_number);
1227 return(handler);
1228}
1229
1230MagickExport void MagickCoreGenesis(const char *path,
1231 const MagickBooleanType establish_signal_handlers)
1232{
1233 char
1234 *events,
1235 execution_path[MaxTextExtent],
1236 filename[MaxTextExtent];
1237
cristy3ed852e2009-09-05 21:47:34 +00001238 /*
1239 Initialize the Magick environment.
1240 */
cristy1ea02a32014-01-24 11:23:14 +00001241 InitializeMagickMutex();
cristyd1ebf4a2010-05-13 01:54:31 +00001242 LockMagickMutex();
1243 if (instantiate_magickcore != MagickFalse)
1244 {
1245 UnlockMagickMutex();
1246 return;
1247 }
cristyf34a1452009-10-24 22:29:27 +00001248 (void) SemaphoreComponentGenesis();
1249 (void) LogComponentGenesis();
1250 (void) LocaleComponentGenesis();
1251 (void) RandomComponentGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001252 events=GetEnvironmentValue("MAGICK_DEBUG");
1253 if (events != (char *) NULL)
1254 {
1255 (void) SetLogEventMask(events);
1256 events=DestroyString(events);
1257 }
cristy0157aea2010-04-24 21:12:18 +00001258#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy9f3b4fc2014-02-08 14:56:20 +00001259 NTWindowsGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001260#endif
1261 /*
1262 Set client name and execution path.
1263 */
1264 (void) GetExecutionPath(execution_path,MaxTextExtent);
cristy695e8c32011-11-09 18:27:04 +00001265 if ((path != (const char *) NULL) && (*path == *DirectorySeparator) &&
cristy905e5302011-11-09 18:08:43 +00001266 (IsPathAccessible(path) != MagickFalse))
cristy3ed852e2009-09-05 21:47:34 +00001267 (void) CopyMagickString(execution_path,path,MaxTextExtent);
1268 GetPathComponent(execution_path,TailPath,filename);
1269 (void) SetClientName(filename);
1270 GetPathComponent(execution_path,HeadPath,execution_path);
1271 (void) SetClientPath(execution_path);
1272 if (establish_signal_handlers != MagickFalse)
1273 {
1274 /*
1275 Set signal handlers.
1276 */
1277#if defined(SIGABRT)
1278 if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1279 signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1280#endif
cristy32a348b2011-04-22 16:03:42 +00001281#if defined(SIGSEGV)
1282 if (signal_handlers[SIGSEGV] == (SignalHandler *) NULL)
1283 signal_handlers[SIGSEGV]=RegisterMagickSignalHandler(SIGSEGV);
cristy7ae29582011-04-21 16:10:06 +00001284#endif
cristy3ed852e2009-09-05 21:47:34 +00001285#if defined(SIGFPE)
1286 if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1287 signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1288#endif
1289#if defined(SIGHUP)
1290 if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1291 signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1292#endif
cristy0157aea2010-04-24 21:12:18 +00001293#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001294 if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1295 signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1296#endif
1297#if defined(SIGQUIT)
1298 if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1299 signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1300#endif
1301#if defined(SIGTERM)
1302 if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1303 signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1304#endif
1305#if defined(SIGXCPU)
1306 if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1307 signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1308#endif
1309#if defined(SIGXFSZ)
1310 if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1311 signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1312#endif
1313 }
1314 /*
cristyaf8b5cd2009-10-24 00:29:23 +00001315 Instantiate magick resources.
cristy3ed852e2009-09-05 21:47:34 +00001316 */
cristy18b17442009-10-25 18:36:48 +00001317 (void) ConfigureComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001318 (void) PolicyComponentGenesis();
1319 (void) CacheComponentGenesis();
1320 (void) RegistryComponentGenesis();
1321 (void) ResourceComponentGenesis();
1322 (void) CoderComponentGenesis();
1323 (void) MagickComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001324#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001325 (void) ModuleComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001326#endif
cristyf34a1452009-10-24 22:29:27 +00001327 (void) DelegateComponentGenesis();
1328 (void) MagicComponentGenesis();
1329 (void) ColorComponentGenesis();
1330 (void) TypeComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001331 (void) MimeComponentGenesis();
1332 (void) ConstituteComponentGenesis();
cristyd7ecaca2011-01-24 14:14:53 +00001333 (void) AnnotateComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001334#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001335 (void) XComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001336#endif
cristyd1ebf4a2010-05-13 01:54:31 +00001337 instantiate_magickcore=MagickTrue;
1338 UnlockMagickMutex();
cristy3ed852e2009-09-05 21:47:34 +00001339}
1340
1341/*
1342%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1343% %
1344% %
1345% %
1346% M a g i c k C o r e T e r m i n u s %
1347% %
1348% %
1349% %
1350%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1351%
1352% MagickCoreTerminus() destroys the MagickCore environment.
1353%
cristyf34a1452009-10-24 22:29:27 +00001354% The format of the MagickCoreTerminus function is:
cristy3ed852e2009-09-05 21:47:34 +00001355%
1356% MagickCoreTerminus(void)
1357%
1358*/
1359MagickExport void MagickCoreTerminus(void)
1360{
cristy1ea02a32014-01-24 11:23:14 +00001361 InitializeMagickMutex();
cristyd1ebf4a2010-05-13 01:54:31 +00001362 LockMagickMutex();
1363 if (instantiate_magickcore == MagickFalse)
1364 {
1365 UnlockMagickMutex();
1366 return;
1367 }
cristy3ed852e2009-09-05 21:47:34 +00001368#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001369 XComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001370#endif
cristyd7ecaca2011-01-24 14:14:53 +00001371 AnnotateComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001372 ConstituteComponentTerminus();
1373 MimeComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001374 TypeComponentTerminus();
1375 ColorComponentTerminus();
cristy0157aea2010-04-24 21:12:18 +00001376#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001377 NTGhostscriptUnLoadDLL();
1378#endif
cristyf34a1452009-10-24 22:29:27 +00001379 MagicComponentTerminus();
1380 DelegateComponentTerminus();
1381 MagickComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001382#if !defined(MAGICKCORE_BUILD_MODULES)
1383 UnregisterStaticModules();
1384#endif
1385#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001386 ModuleComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001387#endif
cristyf34a1452009-10-24 22:29:27 +00001388 CoderComponentTerminus();
1389 ResourceComponentTerminus();
1390 RegistryComponentTerminus();
1391 CacheComponentTerminus();
1392 PolicyComponentTerminus();
cristy18b17442009-10-25 18:36:48 +00001393 ConfigureComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001394 RandomComponentTerminus();
1395 LocaleComponentTerminus();
1396 LogComponentTerminus();
1397 SemaphoreComponentTerminus();
cristyd1ebf4a2010-05-13 01:54:31 +00001398 instantiate_magickcore=MagickFalse;
1399 UnlockMagickMutex();
cristy1ea02a32014-01-24 11:23:14 +00001400 DestroyMagickMutex();
cristy3ed852e2009-09-05 21:47:34 +00001401}
1402
1403/*
1404%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1405% %
1406% %
1407% %
1408+ R e g i s t e r M a g i c k I n f o %
1409% %
1410% %
1411% %
1412%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1413%
1414% RegisterMagickInfo() adds attributes for a particular image format to the
1415% list of supported formats. The attributes include the image format name,
1416% a method to read and/or write the format, whether the format supports the
1417% saving of more than one frame to the same file or blob, whether the format
1418% supports native in-memory I/O, and a brief description of the format.
1419%
1420% The format of the RegisterMagickInfo method is:
1421%
1422% MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1423%
1424% A description of each parameter follows:
1425%
1426% o magick_info: the magick info.
1427%
1428*/
1429MagickExport MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1430{
1431 MagickBooleanType
1432 status;
1433
1434 /*
1435 Delete any existing name.
1436 */
1437 assert(magick_info != (MagickInfo *) NULL);
1438 assert(magick_info->signature == MagickSignature);
1439 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
1440 if (magick_list == (SplayTreeInfo *) NULL)
1441 return((MagickInfo *) NULL);
1442 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1443 if (status == MagickFalse)
1444 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1445 return(magick_info);
1446}
1447
1448/*
1449%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1450% %
1451% %
1452% %
1453+ S e t M a g i c k I n f o %
1454% %
1455% %
1456% %
1457%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1458%
1459% SetMagickInfo() allocates a MagickInfo structure and initializes the members
1460% to default values.
1461%
1462% The format of the SetMagickInfo method is:
1463%
1464% MagickInfo *SetMagickInfo(const char *name)
1465%
1466% A description of each parameter follows:
1467%
1468% o magick_info: Method SetMagickInfo returns the allocated and initialized
1469% MagickInfo structure.
1470%
1471% o name: a character string that represents the image format associated
1472% with the MagickInfo structure.
1473%
1474*/
1475MagickExport MagickInfo *SetMagickInfo(const char *name)
1476{
1477 MagickInfo
1478 *magick_info;
1479
1480 assert(name != (const char *) NULL);
1481 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
cristy73bd4a52010-10-05 11:24:23 +00001482 magick_info=(MagickInfo *) AcquireMagickMemory(sizeof(*magick_info));
cristy3ed852e2009-09-05 21:47:34 +00001483 if (magick_info == (MagickInfo *) NULL)
1484 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1485 (void) ResetMagickMemory(magick_info,0,sizeof(*magick_info));
1486 magick_info->name=ConstantString(name);
1487 magick_info->adjoin=MagickTrue;
1488 magick_info->blob_support=MagickTrue;
1489 magick_info->thread_support=(MagickStatusType) (DecoderThreadSupport |
1490 EncoderThreadSupport);
1491 magick_info->signature=MagickSignature;
1492 return(magick_info);
1493}
1494
1495/*
1496%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1497% %
1498% %
1499% %
cristye7f51092010-01-17 00:39:37 +00001500% S e t M a g i c k P r e c i s i o n %
1501% %
1502% %
1503% %
1504%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1505%
1506% SetMagickPrecision() sets the maximum number of significant digits to be
anthonybc6fc132012-01-16 07:02:46 +00001507% printed.
1508%
1509% An input argument of 0 returns the current precision setting.
1510%
cristyabdd5b72012-01-18 03:02:15 +00001511% A negative value forces the precision to reset to a default value according
1512% to the environment variable "MAGICK_PRECISION", the current 'policy'
1513% configuration setting, or the default value of '6', in that order.
cristye7f51092010-01-17 00:39:37 +00001514%
1515% The format of the SetMagickPrecision method is:
1516%
cristybf2766a2010-01-17 03:33:23 +00001517% int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001518%
1519% A description of each parameter follows:
1520%
1521% o precision: set the maximum number of significant digits to be printed.
1522%
1523*/
cristybf2766a2010-01-17 03:33:23 +00001524MagickExport int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001525{
anthonybc6fc132012-01-16 07:02:46 +00001526#define MagickPrecision 6
1527
cristybf2766a2010-01-17 03:33:23 +00001528 static int
1529 magick_precision = 0;
1530
cristye7f51092010-01-17 00:39:37 +00001531 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
anthony82c09922012-01-16 06:38:16 +00001532 if (precision > 0)
cristyabdd5b72012-01-18 03:02:15 +00001533 magick_precision=precision;
1534 if ((precision < 0) || (magick_precision == 0))
anthonybc6fc132012-01-16 07:02:46 +00001535 {
1536 char
1537 *limit;
1538
1539 /*
cristyabdd5b72012-01-18 03:02:15 +00001540 Precision reset, or it has not been set yet
anthonybc6fc132012-01-16 07:02:46 +00001541 */
1542 magick_precision = MagickPrecision;
1543 limit=GetEnvironmentValue("MAGICK_PRECISION");
1544 if (limit == (char *) NULL)
1545 limit=GetPolicyValue("precision");
1546 if (limit != (char *) NULL)
1547 {
cristyabdd5b72012-01-18 03:02:15 +00001548 magick_precision=StringToInteger(limit);
anthonybc6fc132012-01-16 07:02:46 +00001549 limit=DestroyString(limit);
1550 }
1551 }
cristybf2766a2010-01-17 03:33:23 +00001552 return(magick_precision);
cristye7f51092010-01-17 00:39:37 +00001553}
1554
1555/*
1556%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1557% %
1558% %
1559% %
cristy3ed852e2009-09-05 21:47:34 +00001560+ U n r e g i s t e r M a g i c k I n f o %
1561% %
1562% %
1563% %
1564%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1565%
1566% UnregisterMagickInfo() removes a name from the magick info list. It returns
1567% MagickFalse if the name does not exist in the list otherwise MagickTrue.
1568%
1569% The format of the UnregisterMagickInfo method is:
1570%
1571% MagickBooleanType UnregisterMagickInfo(const char *name)
1572%
1573% A description of each parameter follows:
1574%
1575% o name: a character string that represents the image format we are
1576% looking for.
1577%
1578*/
1579MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1580{
1581 register const MagickInfo
1582 *p;
1583
1584 MagickBooleanType
1585 status;
1586
1587 assert(name != (const char *) NULL);
1588 if (magick_list == (SplayTreeInfo *) NULL)
1589 return(MagickFalse);
1590 if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1591 return(MagickFalse);
cristyf84a1932010-01-03 18:00:18 +00001592 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001593 ResetSplayTreeIterator(magick_list);
1594 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1595 while (p != (const MagickInfo *) NULL)
1596 {
1597 if (LocaleCompare(p->name,name) == 0)
1598 break;
1599 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1600 }
1601 status=DeleteNodeByValueFromSplayTree(magick_list,p);
cristyf84a1932010-01-03 18:00:18 +00001602 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001603 return(status);
1604}