blob: 70e4e48259088b1a0d26e35fc89d64aba7d7af1d [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_magick = MagickFalse,
125 instantiate_magickcore = MagickFalse;
cristy3ed852e2009-09-05 21:47:34 +0000126
127/*
128 Forward declarations.
129*/
130static MagickBooleanType
131 InitializeMagickList(ExceptionInfo *);
132
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);
416 if ((magick_list == (SplayTreeInfo *) NULL) ||
417 (instantiate_magick == MagickFalse))
418 if (InitializeMagickList(exception) == MagickFalse)
419 return((const MagickInfo *) NULL);
420 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
421 {
422#if defined(MAGICKCORE_MODULES_SUPPORT)
423 if (LocaleCompare(name,"*") == 0)
424 (void) OpenModules(exception);
425#endif
cristyf84a1932010-01-03 18:00:18 +0000426 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000427 ResetSplayTreeIterator(magick_list);
428 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
cristyf84a1932010-01-03 18:00:18 +0000429 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000430 return(p);
431 }
432 /*
433 Find name in list.
434 */
cristyf84a1932010-01-03 18:00:18 +0000435 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000436 ResetSplayTreeIterator(magick_list);
437 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
438 while (p != (const MagickInfo *) NULL)
439 {
440 if (LocaleCompare(p->name,name) == 0)
441 break;
442 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
443 }
444#if defined(MAGICKCORE_MODULES_SUPPORT)
445 if (p == (const MagickInfo *) NULL)
446 {
447 if (*name != '\0')
448 (void) OpenModule(name,exception);
449 ResetSplayTreeIterator(magick_list);
450 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
451 while (p != (const MagickInfo *) NULL)
452 {
453 if (LocaleCompare(p->name,name) == 0)
454 break;
455 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
456 }
457 }
458#endif
cristyf84a1932010-01-03 18:00:18 +0000459 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000460 return(p);
461}
462
463/*
464%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465% %
466% %
467% %
468+ G e t M a g i c k I n f o L i s t %
469% %
470% %
471% %
472%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
473%
474% GetMagickInfoList() returns any image formats that match the specified
475% pattern.
476%
477% The format of the GetMagickInfoList function is:
478%
479% const MagickInfo **GetMagickInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000480% size_t *number_formats,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000481%
482% A description of each parameter follows:
483%
484% o pattern: Specifies a pointer to a text string containing a pattern.
485%
486% o number_formats: This integer returns the number of formats in the list.
487%
488% o exception: return any errors or warnings in this structure.
489%
490*/
491
492#if defined(__cplusplus) || defined(c_plusplus)
493extern "C" {
494#endif
495
496static int MagickInfoCompare(const void *x,const void *y)
497{
498 const MagickInfo
499 **p,
500 **q;
501
502 p=(const MagickInfo **) x,
503 q=(const MagickInfo **) y;
504 return(LocaleCompare((*p)->name,(*q)->name));
505}
506
507#if defined(__cplusplus) || defined(c_plusplus)
508}
509#endif
510
511MagickExport const MagickInfo **GetMagickInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000512 size_t *number_formats,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000513{
514 const MagickInfo
515 **formats;
516
517 register const MagickInfo
518 *p;
519
cristybb503372010-05-27 20:51:26 +0000520 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000521 i;
522
523 /*
524 Allocate magick list.
525 */
526 assert(pattern != (char *) NULL);
527 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000528 assert(number_formats != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000529 *number_formats=0;
530 p=GetMagickInfo("*",exception);
531 if (p == (const MagickInfo *) NULL)
532 return((const MagickInfo **) NULL);
533 formats=(const MagickInfo **) AcquireQuantumMemory((size_t)
534 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
535 if (formats == (const MagickInfo **) NULL)
536 return((const MagickInfo **) NULL);
537 /*
538 Generate magick list.
539 */
cristyf84a1932010-01-03 18:00:18 +0000540 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000541 ResetSplayTreeIterator(magick_list);
542 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
543 for (i=0; p != (const MagickInfo *) NULL; )
544 {
545 if ((p->stealth == MagickFalse) &&
546 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
547 formats[i++]=p;
548 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
549 }
cristyf84a1932010-01-03 18:00:18 +0000550 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000551 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickInfoCompare);
552 formats[i]=(MagickInfo *) NULL;
cristybb503372010-05-27 20:51:26 +0000553 *number_formats=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000554 return(formats);
555}
556
557/*
558%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
559% %
560% %
561% %
562+ G e t M a g i c k L i s t %
563% %
564% %
565% %
566%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
567%
568% GetMagickList() returns any image formats that match the specified pattern.
569%
570% The format of the GetMagickList function is:
571%
cristybb503372010-05-27 20:51:26 +0000572% char **GetMagickList(const char *pattern,size_t *number_formats,
cristy3ed852e2009-09-05 21:47:34 +0000573% ExceptionInfo *exception)
574%
575% A description of each parameter follows:
576%
577% o pattern: Specifies a pointer to a text string containing a pattern.
578%
579% o number_formats: This integer returns the number of formats in the list.
580%
581% o exception: return any errors or warnings in this structure.
582%
583*/
584
585#if defined(__cplusplus) || defined(c_plusplus)
586extern "C" {
587#endif
588
589static int MagickCompare(const void *x,const void *y)
590{
591 register const char
592 **p,
593 **q;
594
595 p=(const char **) x;
596 q=(const char **) y;
597 return(LocaleCompare(*p,*q));
598}
599
600#if defined(__cplusplus) || defined(c_plusplus)
601}
602#endif
603
604MagickExport char **GetMagickList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000605 size_t *number_formats,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000606{
607 char
608 **formats;
609
610 register const MagickInfo
611 *p;
612
cristybb503372010-05-27 20:51:26 +0000613 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000614 i;
615
616 /*
617 Allocate magick list.
618 */
619 assert(pattern != (char *) NULL);
620 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000621 assert(number_formats != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000622 *number_formats=0;
623 p=GetMagickInfo("*",exception);
624 if (p == (const MagickInfo *) NULL)
625 return((char **) NULL);
626 formats=(char **) AcquireQuantumMemory((size_t)
627 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
628 if (formats == (char **) NULL)
629 return((char **) NULL);
cristyf84a1932010-01-03 18:00:18 +0000630 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000631 ResetSplayTreeIterator(magick_list);
632 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
633 for (i=0; p != (const MagickInfo *) NULL; )
634 {
635 if ((p->stealth == MagickFalse) &&
636 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
637 formats[i++]=ConstantString(p->name);
638 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
639 }
cristyf84a1932010-01-03 18:00:18 +0000640 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000641 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickCompare);
642 formats[i]=(char *) NULL;
cristybb503372010-05-27 20:51:26 +0000643 *number_formats=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000644 return(formats);
645}
646
647/*
648%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
649% %
650% %
651% %
cristy4a6ab482013-08-09 01:29:35 +0000652+ G e t M a g i c k M i m e T y p e %
653% %
654% %
655% %
656%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
657%
658% GetMagickMimeType() returns the magick mime type.
659%
660% The format of the GetMagickMimeType method is:
661%
662% const char *GetMagickMimeType(const MagickInfo *magick_info)
663%
664% A description of each parameter follows:
665%
666% o magick_info: The magick info.
667%
668*/
669MagickExport const char *GetMagickMimeType(const MagickInfo *magick_info)
670{
671 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
672 assert(magick_info != (MagickInfo *) NULL);
673 assert(magick_info->signature == MagickSignature);
674 return(magick_info->mime_type);
675}
676
677/*
678%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
679% %
680% %
681% %
cristye7f51092010-01-17 00:39:37 +0000682% G e t M a g i c k P r e c i s i o n %
cristy7ce14bc2010-01-17 00:01:01 +0000683% %
684% %
685% %
686%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
687%
688% GetMagickPrecision() returns the maximum number of significant digits to be
689% printed.
690%
691% The format of the GetMagickPrecision method is:
692%
cristye7f51092010-01-17 00:39:37 +0000693% int GetMagickPrecision(void)
cristy7ce14bc2010-01-17 00:01:01 +0000694%
695*/
cristye7f51092010-01-17 00:39:37 +0000696MagickExport int GetMagickPrecision(void)
cristy7ce14bc2010-01-17 00:01:01 +0000697{
cristy7ce14bc2010-01-17 00:01:01 +0000698 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
cristybf2766a2010-01-17 03:33:23 +0000699 return(SetMagickPrecision(0));
cristy7ce14bc2010-01-17 00:01:01 +0000700}
701
702/*
703%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
704% %
705% %
706% %
707+ 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 +0000708% %
709% %
710% %
711%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
712%
713% GetMagickRawSupport() returns the MagickTrue if the coder is a raw format.
714%
715% The format of the GetMagickRawSupport method is:
716%
717% MagickBooleanType GetMagickRawSupport(const MagickInfo *magick_info)
718%
719% A description of each parameter follows:
720%
721% o magick_info: The magick info.
722%
723*/
724MagickExport MagickBooleanType GetMagickRawSupport(
725 const MagickInfo *magick_info)
726{
727 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
728 assert(magick_info != (MagickInfo *) NULL);
729 assert(magick_info->signature == MagickSignature);
730 return(magick_info->raw);
731}
732
733/*
734%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
735% %
736% %
737% %
738+ G e t M a g i c k S e e k a b l e S t r e a m %
739% %
740% %
741% %
742%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
743%
744% GetMagickSeekableStream() returns MagickTrue if the magick supports a
745% seekable stream.
746%
747% The format of the GetMagickSeekableStream method is:
748%
749% MagickBooleanType GetMagickSeekableStream(const MagickInfo *magick_info)
750%
751% A description of each parameter follows:
752%
753% o magick_info: The magick info.
754%
755*/
756MagickExport MagickBooleanType GetMagickSeekableStream(
757 const MagickInfo *magick_info)
758{
759 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
760 assert(magick_info != (MagickInfo *) NULL);
761 assert(magick_info->signature == MagickSignature);
762 return(magick_info->seekable_stream);
763}
764
765/*
766%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
767% %
768% %
769% %
770+ G e t M a g i c k T h r e a d S u p p o r t %
771% %
772% %
773% %
774%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
775%
776% GetMagickThreadSupport() returns MagickTrue if the magick supports threads.
777%
778% The format of the GetMagickThreadSupport method is:
779%
780% MagickStatusType GetMagickThreadSupport(const MagickInfo *magick_info)
781%
782% A description of each parameter follows:
783%
784% o magick_info: The magick info.
785%
786*/
787MagickExport MagickStatusType GetMagickThreadSupport(
788 const MagickInfo *magick_info)
789{
790 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
791 assert(magick_info != (MagickInfo *) NULL);
792 assert(magick_info->signature == MagickSignature);
793 return(magick_info->thread_support);
794}
795
796/*
797%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
798% %
799% %
800% %
801+ I n i t i a l i z e M a g i c k L i s t %
802% %
803% %
804% %
805%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
806%
807% InitializeMagickList() initializes the magick list.
808%
809% The format of the InitializeMagickList() method is:
810%
811% InitializeMagickList(Exceptioninfo *exception)
812%
813% A description of each parameter follows.
814%
815% o exception: return any errors or warnings in this structure.
816%
817*/
818
819static void *DestroyMagickNode(void *magick_info)
820{
821 register MagickInfo
822 *p;
823
824 p=(MagickInfo *) magick_info;
cristy3ed852e2009-09-05 21:47:34 +0000825 if (p->module != (char *) NULL)
826 p->module=DestroyString(p->module);
cristy4a6ab482013-08-09 01:29:35 +0000827 if (p->note != (char *) NULL)
828 p->note=DestroyString(p->note);
829 if (p->mime_type != (char *) NULL)
830 p->mime_type=DestroyString(p->mime_type);
831 if (p->version != (char *) NULL)
832 p->version=DestroyString(p->version);
833 if (p->description != (char *) NULL)
834 p->description=DestroyString(p->description);
835 if (p->name != (char *) NULL)
836 p->name=DestroyString(p->name);
cristy3ed852e2009-09-05 21:47:34 +0000837 return(RelinquishMagickMemory(p));
838}
839
840static MagickBooleanType InitializeMagickList(ExceptionInfo *exception)
841{
cristyf2e11662009-10-14 01:24:43 +0000842 (void) exception;
cristy3ed852e2009-09-05 21:47:34 +0000843 if ((magick_list == (SplayTreeInfo *) NULL) &&
844 (instantiate_magick == MagickFalse))
845 {
cristy4e1dff62009-10-25 20:36:03 +0000846 if (magick_semaphore == (SemaphoreInfo *) NULL)
847 AcquireSemaphoreInfo(&magick_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000848 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000849 if ((magick_list == (SplayTreeInfo *) NULL) &&
850 (instantiate_magick == MagickFalse))
851 {
852 MagickBooleanType
853 status;
854
855 MagickInfo
856 *magick_info;
857
858 magick_list=NewSplayTree(CompareSplayTreeString,
859 (void *(*)(void *)) NULL,DestroyMagickNode);
860 if (magick_list == (SplayTreeInfo *) NULL)
861 ThrowFatalException(ResourceLimitFatalError,
862 "MemoryAllocationFailed");
863 magick_info=SetMagickInfo("ephemeral");
864 magick_info->stealth=MagickTrue;
865 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
866 if (status == MagickFalse)
867 ThrowFatalException(ResourceLimitFatalError,
868 "MemoryAllocationFailed");
869 magick_info=SetMagickInfo("clipmask");
870 magick_info->stealth=MagickTrue;
871 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
872 if (status == MagickFalse)
dirk93b02b72013-11-16 16:03:36 +0000873 ThrowFatalException(ResourceLimitFatalError,
874 "MemoryAllocationFailed");
cristy3ed852e2009-09-05 21:47:34 +0000875#if defined(MAGICKCORE_MODULES_SUPPORT)
876 (void) GetModuleInfo((char *) NULL,exception);
877#endif
878#if !defined(MAGICKCORE_BUILD_MODULES)
879 RegisterStaticModules();
880#endif
881 instantiate_magick=MagickTrue;
882 }
cristyf84a1932010-01-03 18:00:18 +0000883 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000884 }
885 return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
886}
887
888/*
889%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
890% %
891% %
892% %
893+ I s M a g i c k C o n f l i c t %
894% %
895% %
896% %
897%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
898%
cristy05a9a622010-03-15 17:26:04 +0000899% IsMagickConflict() returns MagickTrue if the image format conflicts with a
900% logical drive (.e.g. X:).
cristy3ed852e2009-09-05 21:47:34 +0000901%
902% The format of the IsMagickConflict method is:
903%
904% MagickBooleanType IsMagickConflict(const char *magick)
905%
906% A description of each parameter follows:
907%
908% o magick: Specifies the image format.
909%
910*/
cristy7832dc22011-09-05 01:21:53 +0000911MagickPrivate MagickBooleanType IsMagickConflict(const char *magick)
cristy3ed852e2009-09-05 21:47:34 +0000912{
cristy3ed852e2009-09-05 21:47:34 +0000913 assert(magick != (char *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000914#if defined(macintosh)
915 return(MACIsMagickConflict(magick));
916#elif defined(vms)
917 return(VMSIsMagickConflict(magick));
cristy0157aea2010-04-24 21:12:18 +0000918#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000919 return(NTIsMagickConflict(magick));
920#else
921 return(MagickFalse);
922#endif
923}
924
925/*
926%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
927% %
928% %
929% %
930+ L i s t M a g i c k I n f o %
931% %
932% %
933% %
934%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
935%
936% ListMagickInfo() lists the image formats to a file.
937%
938% The format of the ListMagickInfo method is:
939%
940% MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
941%
942% A description of each parameter follows.
943%
944% o file: A file handle.
945%
946% o exception: return any errors or warnings in this structure.
947%
948*/
949MagickExport MagickBooleanType ListMagickInfo(FILE *file,
950 ExceptionInfo *exception)
951{
952 const MagickInfo
953 **magick_info;
954
cristybb503372010-05-27 20:51:26 +0000955 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000956 i;
957
cristybb503372010-05-27 20:51:26 +0000958 size_t
cristy3ed852e2009-09-05 21:47:34 +0000959 number_formats;
960
cristy9d314ff2011-03-09 01:30:28 +0000961 ssize_t
962 j;
963
cristy3ed852e2009-09-05 21:47:34 +0000964 if (file == (FILE *) NULL)
965 file=stdout;
966 magick_info=GetMagickInfoList("*",&number_formats,exception);
967 if (magick_info == (const MagickInfo **) NULL)
968 return(MagickFalse);
969 ClearMagickException(exception);
970#if !defined(MAGICKCORE_MODULES_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000971 (void) FormatLocaleFile(file," Format Mode Description\n");
cristy3ed852e2009-09-05 21:47:34 +0000972#else
cristyb51dff52011-05-19 16:55:47 +0000973 (void) FormatLocaleFile(file," Format Module Mode Description\n");
cristy3ed852e2009-09-05 21:47:34 +0000974#endif
cristy1e604812011-05-19 18:07:50 +0000975 (void) FormatLocaleFile(file,
976 "--------------------------------------------------------"
cristy3ed852e2009-09-05 21:47:34 +0000977 "-----------------------\n");
cristybb503372010-05-27 20:51:26 +0000978 for (i=0; i < (ssize_t) number_formats; i++)
cristy3ed852e2009-09-05 21:47:34 +0000979 {
980 if (magick_info[i]->stealth != MagickFalse)
981 continue;
cristy1e604812011-05-19 18:07:50 +0000982 (void) FormatLocaleFile(file,"%9s%c ",
983 magick_info[i]->name != (char *) NULL ? magick_info[i]->name : "",
cristy3ed852e2009-09-05 21:47:34 +0000984 magick_info[i]->blob_support != MagickFalse ? '*' : ' ');
985#if defined(MAGICKCORE_MODULES_SUPPORT)
986 {
987 char
988 module[MaxTextExtent];
989
990 *module='\0';
991 if (magick_info[i]->module != (char *) NULL)
992 (void) CopyMagickString(module,magick_info[i]->module,MaxTextExtent);
993 (void) ConcatenateMagickString(module," ",MaxTextExtent);
994 module[9]='\0';
cristyb51dff52011-05-19 16:55:47 +0000995 (void) FormatLocaleFile(file,"%9s ",module);
cristy3ed852e2009-09-05 21:47:34 +0000996 }
997#endif
cristyb51dff52011-05-19 16:55:47 +0000998 (void) FormatLocaleFile(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
cristy3ed852e2009-09-05 21:47:34 +0000999 magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
1000 magick_info[i]->adjoin != MagickFalse ? '+' : '-');
1001 if (magick_info[i]->description != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +00001002 (void) FormatLocaleFile(file," %s",magick_info[i]->description);
cristy3ed852e2009-09-05 21:47:34 +00001003 if (magick_info[i]->version != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +00001004 (void) FormatLocaleFile(file," (%s)",magick_info[i]->version);
1005 (void) FormatLocaleFile(file,"\n");
cristy3ed852e2009-09-05 21:47:34 +00001006 if (magick_info[i]->note != (char *) NULL)
1007 {
1008 char
1009 **text;
1010
1011 text=StringToList(magick_info[i]->note);
1012 if (text != (char **) NULL)
1013 {
1014 for (j=0; text[j] != (char *) NULL; j++)
1015 {
cristyb51dff52011-05-19 16:55:47 +00001016 (void) FormatLocaleFile(file," %s\n",text[j]);
cristy3ed852e2009-09-05 21:47:34 +00001017 text[j]=DestroyString(text[j]);
1018 }
1019 text=(char **) RelinquishMagickMemory(text);
1020 }
1021 }
1022 }
cristyb51dff52011-05-19 16:55:47 +00001023 (void) FormatLocaleFile(file,"\n* native blob support\n");
1024 (void) FormatLocaleFile(file,"r read support\n");
1025 (void) FormatLocaleFile(file,"w write support\n");
1026 (void) FormatLocaleFile(file,"+ support for multiple images\n");
cristy3ed852e2009-09-05 21:47:34 +00001027 (void) fflush(file);
1028 magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1029 magick_info);
1030 return(MagickTrue);
1031}
1032
1033/*
1034%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1035% %
1036% %
1037% %
cristy019459e2014-01-02 23:47:13 +00001038% 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 +00001039% %
1040% %
1041% %
1042%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1043%
cristy019459e2014-01-02 23:47:13 +00001044% IsMagickCoreInstantiated() returns MagickTrue if the ImageMagick environment
cristy3ed852e2009-09-05 21:47:34 +00001045% is currently instantiated: MagickCoreGenesis() has been called but
1046% MagickDestroy() has not.
1047%
cristy019459e2014-01-02 23:47:13 +00001048% The format of the IsMagickCoreInstantiated method is:
cristy3ed852e2009-09-05 21:47:34 +00001049%
cristy019459e2014-01-02 23:47:13 +00001050% MagickBooleanType IsMagickCoreInstantiated(void)
cristy3ed852e2009-09-05 21:47:34 +00001051%
1052*/
cristy019459e2014-01-02 23:47:13 +00001053MagickExport MagickBooleanType IsMagickCoreInstantiated(void)
cristy3ed852e2009-09-05 21:47:34 +00001054{
cristy0f86a122014-01-03 18:15:50 +00001055 return(instantiate_magickcore);
cristy3ed852e2009-09-05 21:47:34 +00001056}
1057
1058/*
1059%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1060% %
1061% %
1062% %
cristyf34a1452009-10-24 22:29:27 +00001063+ M a g i c k C o m p o n e n t G e n e s i s %
1064% %
1065% %
1066% %
1067%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1068%
1069% MagickComponentGenesis() instantiates the magick component.
1070%
1071% The format of the MagickComponentGenesis method is:
1072%
1073% MagickBooleanType MagickComponentGenesis(void)
1074%
1075*/
cristy5ff4eaf2011-09-03 01:38:02 +00001076MagickPrivate MagickBooleanType MagickComponentGenesis(void)
cristyf34a1452009-10-24 22:29:27 +00001077{
cristy165b6092009-10-26 13:52:10 +00001078 AcquireSemaphoreInfo(&magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001079 return(MagickTrue);
1080}
1081
1082/*
1083%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1084% %
1085% %
1086% %
1087+ M a g i c k C o m p o n e n t T e r m i n u s %
1088% %
1089% %
1090% %
1091%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1092%
1093% MagickComponentTerminus() destroys the magick component.
1094%
1095% The format of the MagickComponentTerminus method is:
1096%
1097% void MagickComponentTerminus(void)
1098%
1099*/
cristy5ff4eaf2011-09-03 01:38:02 +00001100MagickPrivate void MagickComponentTerminus(void)
cristyf34a1452009-10-24 22:29:27 +00001101{
cristy18b17442009-10-25 18:36:48 +00001102 if (magick_semaphore == (SemaphoreInfo *) NULL)
1103 AcquireSemaphoreInfo(&magick_semaphore);
cristyf84a1932010-01-03 18:00:18 +00001104 LockSemaphoreInfo(magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001105 if (magick_list != (SplayTreeInfo *) NULL)
1106 magick_list=DestroySplayTree(magick_list);
1107 instantiate_magick=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +00001108 UnlockSemaphoreInfo(magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001109 DestroySemaphoreInfo(&magick_semaphore);
1110}
1111
1112/*
1113%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1114% %
1115% %
1116% %
cristy3ed852e2009-09-05 21:47:34 +00001117% M a g i c k C o r e G e n e s i s %
1118% %
1119% %
1120% %
1121%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1122%
1123% MagickCoreGenesis() initializes the MagickCore environment.
1124%
1125% The format of the MagickCoreGenesis function is:
1126%
1127% MagickCoreGenesis(const char *path,
1128% const MagickBooleanType establish_signal_handlers)
1129%
1130% A description of each parameter follows:
1131%
1132% o path: the execution path of the current ImageMagick client.
1133%
1134% o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1135% signal handlers for common signals.
1136%
1137*/
1138
1139static SignalHandler *SetMagickSignalHandler(int signal_number,
1140 SignalHandler *handler)
1141{
1142#if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1143 int
1144 status;
1145
1146 sigset_t
1147 mask;
1148
1149 struct sigaction
1150 action,
1151 previous_action;
1152
1153 sigemptyset(&mask);
1154 sigaddset(&mask,signal_number);
1155 sigprocmask(SIG_BLOCK,&mask,NULL);
1156 action.sa_mask=mask;
1157 action.sa_handler=handler;
1158 action.sa_flags=0;
1159#if defined(SA_INTERRUPT)
1160 action.sa_flags|=SA_INTERRUPT;
1161#endif
1162 status=sigaction(signal_number,&action,&previous_action);
1163 if (status < 0)
1164 return(SIG_ERR);
1165 sigprocmask(SIG_UNBLOCK,&mask,NULL);
1166 return(previous_action.sa_handler);
1167#else
1168 return(signal(signal_number,handler));
1169#endif
1170}
1171
1172static void MagickSignalHandler(int signal_number)
1173{
1174#if !defined(MAGICKCORE_HAVE_SIGACTION)
1175 (void) signal(signal_number,SIG_IGN);
1176#endif
cristyf34a1452009-10-24 22:29:27 +00001177 AsynchronousResourceComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001178 instantiate_magick=MagickFalse;
1179 (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
cristy5f03dab2011-02-20 21:55:17 +00001180#if defined(SIGQUIT)
1181 if (signal_number == SIGQUIT)
1182 abort();
1183#endif
1184#if defined(SIGABRT)
1185 if (signal_number == SIGABRT)
1186 abort();
1187#endif
1188#if defined(SIGFPE)
1189 if (signal_number == SIGFPE)
1190 abort();
1191#endif
1192#if defined(SIGXCPU)
1193 if (signal_number == SIGXCPU)
1194 abort();
1195#endif
1196#if defined(SIGXFSZ)
1197 if (signal_number == SIGXFSZ)
1198 abort();
1199#endif
cristy32a348b2011-04-22 16:03:42 +00001200#if defined(SIGSEGV)
1201 if (signal_number == SIGSEGV)
cristy7ae29582011-04-21 16:10:06 +00001202 abort();
1203#endif
cristy3ed852e2009-09-05 21:47:34 +00001204#if !defined(MAGICKCORE_HAVE__EXIT)
1205 exit(signal_number);
1206#else
1207#if defined(SIGHUP)
1208 if (signal_number == SIGHUP)
1209 exit(signal_number);
1210#endif
cristy0157aea2010-04-24 21:12:18 +00001211#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001212 if (signal_number == SIGINT)
1213 exit(signal_number);
1214#endif
1215#if defined(SIGTERM)
1216 if (signal_number == SIGTERM)
1217 exit(signal_number);
1218#endif
cristyad9c7d02013-01-08 02:03:52 +00001219#if defined(MAGICKCORE_HAVE_RAISE)
1220 if (signal_handlers[signal_number] != MagickSignalHandler)
1221 raise(signal_number);
1222#endif
cristy70bda3d2011-02-20 21:58:06 +00001223 _exit(signal_number); /* do not invoke registered atexit() methods */
cristy3ed852e2009-09-05 21:47:34 +00001224#endif
1225}
1226
1227static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1228{
1229 SignalHandler
1230 *handler;
1231
1232 handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1233 if (handler == SIG_ERR)
1234 return(handler);
1235 if (handler != SIG_DFL)
1236 handler=SetMagickSignalHandler(signal_number,handler);
1237 else
1238 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1239 "Register handler for signal: %d",signal_number);
1240 return(handler);
1241}
1242
1243MagickExport void MagickCoreGenesis(const char *path,
1244 const MagickBooleanType establish_signal_handlers)
1245{
1246 char
1247 *events,
1248 execution_path[MaxTextExtent],
1249 filename[MaxTextExtent];
1250
cristy3ed852e2009-09-05 21:47:34 +00001251 /*
1252 Initialize the Magick environment.
1253 */
cristy1ea02a32014-01-24 11:23:14 +00001254 InitializeMagickMutex();
cristyd1ebf4a2010-05-13 01:54:31 +00001255 LockMagickMutex();
1256 if (instantiate_magickcore != MagickFalse)
1257 {
1258 UnlockMagickMutex();
1259 return;
1260 }
cristyf34a1452009-10-24 22:29:27 +00001261 (void) SemaphoreComponentGenesis();
1262 (void) LogComponentGenesis();
1263 (void) LocaleComponentGenesis();
1264 (void) RandomComponentGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001265 events=GetEnvironmentValue("MAGICK_DEBUG");
1266 if (events != (char *) NULL)
1267 {
1268 (void) SetLogEventMask(events);
1269 events=DestroyString(events);
1270 }
cristy0157aea2010-04-24 21:12:18 +00001271#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy9f3b4fc2014-02-08 14:56:20 +00001272 NTWindowsGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001273#endif
1274 /*
1275 Set client name and execution path.
1276 */
1277 (void) GetExecutionPath(execution_path,MaxTextExtent);
cristy695e8c32011-11-09 18:27:04 +00001278 if ((path != (const char *) NULL) && (*path == *DirectorySeparator) &&
cristy905e5302011-11-09 18:08:43 +00001279 (IsPathAccessible(path) != MagickFalse))
cristy3ed852e2009-09-05 21:47:34 +00001280 (void) CopyMagickString(execution_path,path,MaxTextExtent);
1281 GetPathComponent(execution_path,TailPath,filename);
1282 (void) SetClientName(filename);
1283 GetPathComponent(execution_path,HeadPath,execution_path);
1284 (void) SetClientPath(execution_path);
1285 if (establish_signal_handlers != MagickFalse)
1286 {
1287 /*
1288 Set signal handlers.
1289 */
1290#if defined(SIGABRT)
1291 if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1292 signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1293#endif
cristy32a348b2011-04-22 16:03:42 +00001294#if defined(SIGSEGV)
1295 if (signal_handlers[SIGSEGV] == (SignalHandler *) NULL)
1296 signal_handlers[SIGSEGV]=RegisterMagickSignalHandler(SIGSEGV);
cristy7ae29582011-04-21 16:10:06 +00001297#endif
cristy3ed852e2009-09-05 21:47:34 +00001298#if defined(SIGFPE)
1299 if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1300 signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1301#endif
1302#if defined(SIGHUP)
1303 if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1304 signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1305#endif
cristy0157aea2010-04-24 21:12:18 +00001306#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001307 if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1308 signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1309#endif
1310#if defined(SIGQUIT)
1311 if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1312 signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1313#endif
1314#if defined(SIGTERM)
1315 if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1316 signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1317#endif
1318#if defined(SIGXCPU)
1319 if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1320 signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1321#endif
1322#if defined(SIGXFSZ)
1323 if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1324 signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1325#endif
1326 }
1327 /*
cristyaf8b5cd2009-10-24 00:29:23 +00001328 Instantiate magick resources.
cristy3ed852e2009-09-05 21:47:34 +00001329 */
cristy18b17442009-10-25 18:36:48 +00001330 (void) ConfigureComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001331 (void) PolicyComponentGenesis();
1332 (void) CacheComponentGenesis();
1333 (void) RegistryComponentGenesis();
1334 (void) ResourceComponentGenesis();
1335 (void) CoderComponentGenesis();
1336 (void) MagickComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001337#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001338 (void) ModuleComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001339#endif
cristyf34a1452009-10-24 22:29:27 +00001340 (void) DelegateComponentGenesis();
1341 (void) MagicComponentGenesis();
1342 (void) ColorComponentGenesis();
1343 (void) TypeComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001344 (void) MimeComponentGenesis();
1345 (void) ConstituteComponentGenesis();
cristyd7ecaca2011-01-24 14:14:53 +00001346 (void) AnnotateComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001347#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001348 (void) XComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001349#endif
cristyd1ebf4a2010-05-13 01:54:31 +00001350 instantiate_magickcore=MagickTrue;
1351 UnlockMagickMutex();
cristy3ed852e2009-09-05 21:47:34 +00001352}
1353
1354/*
1355%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1356% %
1357% %
1358% %
1359% M a g i c k C o r e T e r m i n u s %
1360% %
1361% %
1362% %
1363%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1364%
1365% MagickCoreTerminus() destroys the MagickCore environment.
1366%
cristyf34a1452009-10-24 22:29:27 +00001367% The format of the MagickCoreTerminus function is:
cristy3ed852e2009-09-05 21:47:34 +00001368%
1369% MagickCoreTerminus(void)
1370%
1371*/
1372MagickExport void MagickCoreTerminus(void)
1373{
cristy1ea02a32014-01-24 11:23:14 +00001374 InitializeMagickMutex();
cristyd1ebf4a2010-05-13 01:54:31 +00001375 LockMagickMutex();
1376 if (instantiate_magickcore == MagickFalse)
1377 {
1378 UnlockMagickMutex();
1379 return;
1380 }
cristy3ed852e2009-09-05 21:47:34 +00001381#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001382 XComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001383#endif
cristyd7ecaca2011-01-24 14:14:53 +00001384 AnnotateComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001385 ConstituteComponentTerminus();
1386 MimeComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001387 TypeComponentTerminus();
1388 ColorComponentTerminus();
cristy0157aea2010-04-24 21:12:18 +00001389#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001390 NTGhostscriptUnLoadDLL();
1391#endif
cristyf34a1452009-10-24 22:29:27 +00001392 MagicComponentTerminus();
1393 DelegateComponentTerminus();
1394 MagickComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001395#if !defined(MAGICKCORE_BUILD_MODULES)
1396 UnregisterStaticModules();
1397#endif
1398#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001399 ModuleComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001400#endif
cristyf34a1452009-10-24 22:29:27 +00001401 CoderComponentTerminus();
1402 ResourceComponentTerminus();
1403 RegistryComponentTerminus();
1404 CacheComponentTerminus();
1405 PolicyComponentTerminus();
cristy18b17442009-10-25 18:36:48 +00001406 ConfigureComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001407 RandomComponentTerminus();
1408 LocaleComponentTerminus();
1409 LogComponentTerminus();
1410 SemaphoreComponentTerminus();
cristyd1ebf4a2010-05-13 01:54:31 +00001411 instantiate_magickcore=MagickFalse;
1412 UnlockMagickMutex();
cristy1ea02a32014-01-24 11:23:14 +00001413 DestroyMagickMutex();
cristy3ed852e2009-09-05 21:47:34 +00001414}
1415
1416/*
1417%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1418% %
1419% %
1420% %
1421+ R e g i s t e r M a g i c k I n f o %
1422% %
1423% %
1424% %
1425%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1426%
1427% RegisterMagickInfo() adds attributes for a particular image format to the
1428% list of supported formats. The attributes include the image format name,
1429% a method to read and/or write the format, whether the format supports the
1430% saving of more than one frame to the same file or blob, whether the format
1431% supports native in-memory I/O, and a brief description of the format.
1432%
1433% The format of the RegisterMagickInfo method is:
1434%
1435% MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1436%
1437% A description of each parameter follows:
1438%
1439% o magick_info: the magick info.
1440%
1441*/
1442MagickExport MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1443{
1444 MagickBooleanType
1445 status;
1446
1447 /*
1448 Delete any existing name.
1449 */
1450 assert(magick_info != (MagickInfo *) NULL);
1451 assert(magick_info->signature == MagickSignature);
1452 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
1453 if (magick_list == (SplayTreeInfo *) NULL)
1454 return((MagickInfo *) NULL);
1455 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1456 if (status == MagickFalse)
1457 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1458 return(magick_info);
1459}
1460
1461/*
1462%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1463% %
1464% %
1465% %
1466+ S e t M a g i c k I n f o %
1467% %
1468% %
1469% %
1470%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1471%
1472% SetMagickInfo() allocates a MagickInfo structure and initializes the members
1473% to default values.
1474%
1475% The format of the SetMagickInfo method is:
1476%
1477% MagickInfo *SetMagickInfo(const char *name)
1478%
1479% A description of each parameter follows:
1480%
1481% o magick_info: Method SetMagickInfo returns the allocated and initialized
1482% MagickInfo structure.
1483%
1484% o name: a character string that represents the image format associated
1485% with the MagickInfo structure.
1486%
1487*/
1488MagickExport MagickInfo *SetMagickInfo(const char *name)
1489{
1490 MagickInfo
1491 *magick_info;
1492
1493 assert(name != (const char *) NULL);
1494 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
cristy73bd4a52010-10-05 11:24:23 +00001495 magick_info=(MagickInfo *) AcquireMagickMemory(sizeof(*magick_info));
cristy3ed852e2009-09-05 21:47:34 +00001496 if (magick_info == (MagickInfo *) NULL)
1497 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1498 (void) ResetMagickMemory(magick_info,0,sizeof(*magick_info));
1499 magick_info->name=ConstantString(name);
1500 magick_info->adjoin=MagickTrue;
1501 magick_info->blob_support=MagickTrue;
1502 magick_info->thread_support=(MagickStatusType) (DecoderThreadSupport |
1503 EncoderThreadSupport);
1504 magick_info->signature=MagickSignature;
1505 return(magick_info);
1506}
1507
1508/*
1509%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1510% %
1511% %
1512% %
cristye7f51092010-01-17 00:39:37 +00001513% S e t M a g i c k P r e c i s i o n %
1514% %
1515% %
1516% %
1517%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1518%
1519% SetMagickPrecision() sets the maximum number of significant digits to be
anthonybc6fc132012-01-16 07:02:46 +00001520% printed.
1521%
1522% An input argument of 0 returns the current precision setting.
1523%
cristyabdd5b72012-01-18 03:02:15 +00001524% A negative value forces the precision to reset to a default value according
1525% to the environment variable "MAGICK_PRECISION", the current 'policy'
1526% configuration setting, or the default value of '6', in that order.
cristye7f51092010-01-17 00:39:37 +00001527%
1528% The format of the SetMagickPrecision method is:
1529%
cristybf2766a2010-01-17 03:33:23 +00001530% int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001531%
1532% A description of each parameter follows:
1533%
1534% o precision: set the maximum number of significant digits to be printed.
1535%
1536*/
cristybf2766a2010-01-17 03:33:23 +00001537MagickExport int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001538{
anthonybc6fc132012-01-16 07:02:46 +00001539#define MagickPrecision 6
1540
cristybf2766a2010-01-17 03:33:23 +00001541 static int
1542 magick_precision = 0;
1543
cristye7f51092010-01-17 00:39:37 +00001544 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
anthony82c09922012-01-16 06:38:16 +00001545 if (precision > 0)
cristyabdd5b72012-01-18 03:02:15 +00001546 magick_precision=precision;
1547 if ((precision < 0) || (magick_precision == 0))
anthonybc6fc132012-01-16 07:02:46 +00001548 {
1549 char
1550 *limit;
1551
1552 /*
cristyabdd5b72012-01-18 03:02:15 +00001553 Precision reset, or it has not been set yet
anthonybc6fc132012-01-16 07:02:46 +00001554 */
1555 magick_precision = MagickPrecision;
1556 limit=GetEnvironmentValue("MAGICK_PRECISION");
1557 if (limit == (char *) NULL)
1558 limit=GetPolicyValue("precision");
1559 if (limit != (char *) NULL)
1560 {
cristyabdd5b72012-01-18 03:02:15 +00001561 magick_precision=StringToInteger(limit);
anthonybc6fc132012-01-16 07:02:46 +00001562 limit=DestroyString(limit);
1563 }
1564 }
cristybf2766a2010-01-17 03:33:23 +00001565 return(magick_precision);
cristye7f51092010-01-17 00:39:37 +00001566}
1567
1568/*
1569%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1570% %
1571% %
1572% %
cristy3ed852e2009-09-05 21:47:34 +00001573+ U n r e g i s t e r M a g i c k I n f o %
1574% %
1575% %
1576% %
1577%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1578%
1579% UnregisterMagickInfo() removes a name from the magick info list. It returns
1580% MagickFalse if the name does not exist in the list otherwise MagickTrue.
1581%
1582% The format of the UnregisterMagickInfo method is:
1583%
1584% MagickBooleanType UnregisterMagickInfo(const char *name)
1585%
1586% A description of each parameter follows:
1587%
1588% o name: a character string that represents the image format we are
1589% looking for.
1590%
1591*/
1592MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1593{
1594 register const MagickInfo
1595 *p;
1596
1597 MagickBooleanType
1598 status;
1599
1600 assert(name != (const char *) NULL);
1601 if (magick_list == (SplayTreeInfo *) NULL)
1602 return(MagickFalse);
1603 if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1604 return(MagickFalse);
cristyf84a1932010-01-03 18:00:18 +00001605 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001606 ResetSplayTreeIterator(magick_list);
1607 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1608 while (p != (const MagickInfo *) NULL)
1609 {
1610 if (LocaleCompare(p->name,name) == 0)
1611 break;
1612 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1613 }
1614 status=DeleteNodeByValueFromSplayTree(magick_list,p);
cristyf84a1932010-01-03 18:00:18 +00001615 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001616 return(status);
1617}