blob: 72246fd7d9d6475b616d98d70387be70b39e8213 [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 %
17% John Cristy %
18% November 1998 %
19% %
20% %
cristy45ef08f2012-12-07 13:13:34 +000021% Copyright 1999-2013 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)
873 {
874 char
875 *message;
876
877 message=GetExceptionMessage(errno);
878 ThrowFatalException(ResourceLimitFatalError,
879 "MemoryAllocationFailed");
880 message=DestroyString(message);
881 }
882#if defined(MAGICKCORE_MODULES_SUPPORT)
883 (void) GetModuleInfo((char *) NULL,exception);
884#endif
885#if !defined(MAGICKCORE_BUILD_MODULES)
886 RegisterStaticModules();
887#endif
888 instantiate_magick=MagickTrue;
889 }
cristyf84a1932010-01-03 18:00:18 +0000890 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000891 }
892 return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
893}
894
895/*
896%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
897% %
898% %
899% %
900+ I s M a g i c k C o n f l i c t %
901% %
902% %
903% %
904%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
905%
cristy05a9a622010-03-15 17:26:04 +0000906% IsMagickConflict() returns MagickTrue if the image format conflicts with a
907% logical drive (.e.g. X:).
cristy3ed852e2009-09-05 21:47:34 +0000908%
909% The format of the IsMagickConflict method is:
910%
911% MagickBooleanType IsMagickConflict(const char *magick)
912%
913% A description of each parameter follows:
914%
915% o magick: Specifies the image format.
916%
917*/
cristy7832dc22011-09-05 01:21:53 +0000918MagickPrivate MagickBooleanType IsMagickConflict(const char *magick)
cristy3ed852e2009-09-05 21:47:34 +0000919{
cristy3ed852e2009-09-05 21:47:34 +0000920 assert(magick != (char *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000921#if defined(macintosh)
922 return(MACIsMagickConflict(magick));
923#elif defined(vms)
924 return(VMSIsMagickConflict(magick));
cristy0157aea2010-04-24 21:12:18 +0000925#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000926 return(NTIsMagickConflict(magick));
927#else
928 return(MagickFalse);
929#endif
930}
931
932/*
933%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
934% %
935% %
936% %
937+ L i s t M a g i c k I n f o %
938% %
939% %
940% %
941%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
942%
943% ListMagickInfo() lists the image formats to a file.
944%
945% The format of the ListMagickInfo method is:
946%
947% MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
948%
949% A description of each parameter follows.
950%
951% o file: A file handle.
952%
953% o exception: return any errors or warnings in this structure.
954%
955*/
956MagickExport MagickBooleanType ListMagickInfo(FILE *file,
957 ExceptionInfo *exception)
958{
959 const MagickInfo
960 **magick_info;
961
cristybb503372010-05-27 20:51:26 +0000962 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000963 i;
964
cristybb503372010-05-27 20:51:26 +0000965 size_t
cristy3ed852e2009-09-05 21:47:34 +0000966 number_formats;
967
cristy9d314ff2011-03-09 01:30:28 +0000968 ssize_t
969 j;
970
cristy3ed852e2009-09-05 21:47:34 +0000971 if (file == (FILE *) NULL)
972 file=stdout;
973 magick_info=GetMagickInfoList("*",&number_formats,exception);
974 if (magick_info == (const MagickInfo **) NULL)
975 return(MagickFalse);
976 ClearMagickException(exception);
977#if !defined(MAGICKCORE_MODULES_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000978 (void) FormatLocaleFile(file," Format Mode Description\n");
cristy3ed852e2009-09-05 21:47:34 +0000979#else
cristyb51dff52011-05-19 16:55:47 +0000980 (void) FormatLocaleFile(file," Format Module Mode Description\n");
cristy3ed852e2009-09-05 21:47:34 +0000981#endif
cristy1e604812011-05-19 18:07:50 +0000982 (void) FormatLocaleFile(file,
983 "--------------------------------------------------------"
cristy3ed852e2009-09-05 21:47:34 +0000984 "-----------------------\n");
cristybb503372010-05-27 20:51:26 +0000985 for (i=0; i < (ssize_t) number_formats; i++)
cristy3ed852e2009-09-05 21:47:34 +0000986 {
987 if (magick_info[i]->stealth != MagickFalse)
988 continue;
cristy1e604812011-05-19 18:07:50 +0000989 (void) FormatLocaleFile(file,"%9s%c ",
990 magick_info[i]->name != (char *) NULL ? magick_info[i]->name : "",
cristy3ed852e2009-09-05 21:47:34 +0000991 magick_info[i]->blob_support != MagickFalse ? '*' : ' ');
992#if defined(MAGICKCORE_MODULES_SUPPORT)
993 {
994 char
995 module[MaxTextExtent];
996
997 *module='\0';
998 if (magick_info[i]->module != (char *) NULL)
999 (void) CopyMagickString(module,magick_info[i]->module,MaxTextExtent);
1000 (void) ConcatenateMagickString(module," ",MaxTextExtent);
1001 module[9]='\0';
cristyb51dff52011-05-19 16:55:47 +00001002 (void) FormatLocaleFile(file,"%9s ",module);
cristy3ed852e2009-09-05 21:47:34 +00001003 }
1004#endif
cristyb51dff52011-05-19 16:55:47 +00001005 (void) FormatLocaleFile(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
cristy3ed852e2009-09-05 21:47:34 +00001006 magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
1007 magick_info[i]->adjoin != MagickFalse ? '+' : '-');
1008 if (magick_info[i]->description != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +00001009 (void) FormatLocaleFile(file," %s",magick_info[i]->description);
cristy3ed852e2009-09-05 21:47:34 +00001010 if (magick_info[i]->version != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +00001011 (void) FormatLocaleFile(file," (%s)",magick_info[i]->version);
1012 (void) FormatLocaleFile(file,"\n");
cristy3ed852e2009-09-05 21:47:34 +00001013 if (magick_info[i]->note != (char *) NULL)
1014 {
1015 char
1016 **text;
1017
1018 text=StringToList(magick_info[i]->note);
1019 if (text != (char **) NULL)
1020 {
1021 for (j=0; text[j] != (char *) NULL; j++)
1022 {
cristyb51dff52011-05-19 16:55:47 +00001023 (void) FormatLocaleFile(file," %s\n",text[j]);
cristy3ed852e2009-09-05 21:47:34 +00001024 text[j]=DestroyString(text[j]);
1025 }
1026 text=(char **) RelinquishMagickMemory(text);
1027 }
1028 }
1029 }
cristyb51dff52011-05-19 16:55:47 +00001030 (void) FormatLocaleFile(file,"\n* native blob support\n");
1031 (void) FormatLocaleFile(file,"r read support\n");
1032 (void) FormatLocaleFile(file,"w write support\n");
1033 (void) FormatLocaleFile(file,"+ support for multiple images\n");
cristy3ed852e2009-09-05 21:47:34 +00001034 (void) fflush(file);
1035 magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1036 magick_info);
1037 return(MagickTrue);
1038}
1039
1040/*
1041%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1042% %
1043% %
1044% %
1045% I s M a g i c k I n s t a n t i a t e d %
1046% %
1047% %
1048% %
1049%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1050%
1051% IsMagickInstantiated() returns MagickTrue if the ImageMagick environment
1052% is currently instantiated: MagickCoreGenesis() has been called but
1053% MagickDestroy() has not.
1054%
1055% The format of the IsMagickInstantiated method is:
1056%
1057% MagickBooleanType IsMagickInstantiated(void)
1058%
1059*/
1060MagickExport MagickBooleanType IsMagickInstantiated(void)
1061{
1062 return(instantiate_magick);
1063}
1064
1065/*
1066%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1067% %
1068% %
1069% %
cristyf34a1452009-10-24 22:29:27 +00001070+ M a g i c k C o m p o n e n t G e n e s i s %
1071% %
1072% %
1073% %
1074%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1075%
1076% MagickComponentGenesis() instantiates the magick component.
1077%
1078% The format of the MagickComponentGenesis method is:
1079%
1080% MagickBooleanType MagickComponentGenesis(void)
1081%
1082*/
cristy5ff4eaf2011-09-03 01:38:02 +00001083MagickPrivate MagickBooleanType MagickComponentGenesis(void)
cristyf34a1452009-10-24 22:29:27 +00001084{
cristy165b6092009-10-26 13:52:10 +00001085 AcquireSemaphoreInfo(&magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001086 return(MagickTrue);
1087}
1088
1089/*
1090%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1091% %
1092% %
1093% %
1094+ M a g i c k C o m p o n e n t T e r m i n u s %
1095% %
1096% %
1097% %
1098%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1099%
1100% MagickComponentTerminus() destroys the magick component.
1101%
1102% The format of the MagickComponentTerminus method is:
1103%
1104% void MagickComponentTerminus(void)
1105%
1106*/
cristy5ff4eaf2011-09-03 01:38:02 +00001107MagickPrivate void MagickComponentTerminus(void)
cristyf34a1452009-10-24 22:29:27 +00001108{
cristy18b17442009-10-25 18:36:48 +00001109 if (magick_semaphore == (SemaphoreInfo *) NULL)
1110 AcquireSemaphoreInfo(&magick_semaphore);
cristyf84a1932010-01-03 18:00:18 +00001111 LockSemaphoreInfo(magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001112 if (magick_list != (SplayTreeInfo *) NULL)
1113 magick_list=DestroySplayTree(magick_list);
1114 instantiate_magick=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +00001115 UnlockSemaphoreInfo(magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001116 DestroySemaphoreInfo(&magick_semaphore);
1117}
1118
1119/*
1120%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1121% %
1122% %
1123% %
cristy3ed852e2009-09-05 21:47:34 +00001124% M a g i c k C o r e G e n e s i s %
1125% %
1126% %
1127% %
1128%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1129%
1130% MagickCoreGenesis() initializes the MagickCore environment.
1131%
1132% The format of the MagickCoreGenesis function is:
1133%
1134% MagickCoreGenesis(const char *path,
1135% const MagickBooleanType establish_signal_handlers)
1136%
1137% A description of each parameter follows:
1138%
1139% o path: the execution path of the current ImageMagick client.
1140%
1141% o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1142% signal handlers for common signals.
1143%
1144*/
1145
1146static SignalHandler *SetMagickSignalHandler(int signal_number,
1147 SignalHandler *handler)
1148{
1149#if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1150 int
1151 status;
1152
1153 sigset_t
1154 mask;
1155
1156 struct sigaction
1157 action,
1158 previous_action;
1159
1160 sigemptyset(&mask);
1161 sigaddset(&mask,signal_number);
1162 sigprocmask(SIG_BLOCK,&mask,NULL);
1163 action.sa_mask=mask;
1164 action.sa_handler=handler;
1165 action.sa_flags=0;
1166#if defined(SA_INTERRUPT)
1167 action.sa_flags|=SA_INTERRUPT;
1168#endif
1169 status=sigaction(signal_number,&action,&previous_action);
1170 if (status < 0)
1171 return(SIG_ERR);
1172 sigprocmask(SIG_UNBLOCK,&mask,NULL);
1173 return(previous_action.sa_handler);
1174#else
1175 return(signal(signal_number,handler));
1176#endif
1177}
1178
1179static void MagickSignalHandler(int signal_number)
1180{
1181#if !defined(MAGICKCORE_HAVE_SIGACTION)
1182 (void) signal(signal_number,SIG_IGN);
1183#endif
cristyf34a1452009-10-24 22:29:27 +00001184 AsynchronousResourceComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001185 instantiate_magick=MagickFalse;
1186 (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
cristy5f03dab2011-02-20 21:55:17 +00001187#if defined(SIGQUIT)
1188 if (signal_number == SIGQUIT)
1189 abort();
1190#endif
1191#if defined(SIGABRT)
1192 if (signal_number == SIGABRT)
1193 abort();
1194#endif
1195#if defined(SIGFPE)
1196 if (signal_number == SIGFPE)
1197 abort();
1198#endif
1199#if defined(SIGXCPU)
1200 if (signal_number == SIGXCPU)
1201 abort();
1202#endif
1203#if defined(SIGXFSZ)
1204 if (signal_number == SIGXFSZ)
1205 abort();
1206#endif
cristy32a348b2011-04-22 16:03:42 +00001207#if defined(SIGSEGV)
1208 if (signal_number == SIGSEGV)
cristy7ae29582011-04-21 16:10:06 +00001209 abort();
1210#endif
cristy3ed852e2009-09-05 21:47:34 +00001211#if !defined(MAGICKCORE_HAVE__EXIT)
1212 exit(signal_number);
1213#else
1214#if defined(SIGHUP)
1215 if (signal_number == SIGHUP)
1216 exit(signal_number);
1217#endif
cristy0157aea2010-04-24 21:12:18 +00001218#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001219 if (signal_number == SIGINT)
1220 exit(signal_number);
1221#endif
1222#if defined(SIGTERM)
1223 if (signal_number == SIGTERM)
1224 exit(signal_number);
1225#endif
cristyad9c7d02013-01-08 02:03:52 +00001226#if defined(MAGICKCORE_HAVE_RAISE)
1227 if (signal_handlers[signal_number] != MagickSignalHandler)
1228 raise(signal_number);
1229#endif
cristy70bda3d2011-02-20 21:58:06 +00001230 _exit(signal_number); /* do not invoke registered atexit() methods */
cristy3ed852e2009-09-05 21:47:34 +00001231#endif
1232}
1233
1234static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1235{
1236 SignalHandler
1237 *handler;
1238
1239 handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1240 if (handler == SIG_ERR)
1241 return(handler);
1242 if (handler != SIG_DFL)
1243 handler=SetMagickSignalHandler(signal_number,handler);
1244 else
1245 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1246 "Register handler for signal: %d",signal_number);
1247 return(handler);
1248}
1249
1250MagickExport void MagickCoreGenesis(const char *path,
1251 const MagickBooleanType establish_signal_handlers)
1252{
1253 char
1254 *events,
1255 execution_path[MaxTextExtent],
1256 filename[MaxTextExtent];
1257
cristy3ed852e2009-09-05 21:47:34 +00001258 /*
1259 Initialize the Magick environment.
1260 */
cristyd1ebf4a2010-05-13 01:54:31 +00001261 LockMagickMutex();
1262 if (instantiate_magickcore != MagickFalse)
1263 {
1264 UnlockMagickMutex();
1265 return;
1266 }
cristyf34a1452009-10-24 22:29:27 +00001267 (void) SemaphoreComponentGenesis();
1268 (void) LogComponentGenesis();
1269 (void) LocaleComponentGenesis();
1270 (void) RandomComponentGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001271 events=GetEnvironmentValue("MAGICK_DEBUG");
1272 if (events != (char *) NULL)
1273 {
1274 (void) SetLogEventMask(events);
1275 events=DestroyString(events);
1276 }
cristy0157aea2010-04-24 21:12:18 +00001277#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy277f3a22012-12-10 13:18:45 +00001278#if defined(_DEBUG) && !defined(__BORLANDC__) && !defined(__MINGW32__) && !defined(__MINGW64__)
cristy3ed852e2009-09-05 21:47:34 +00001279 if (IsEventLogging() != MagickFalse)
1280 {
1281 int
1282 debug;
1283
1284 debug=_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
1285 debug|=_CRTDBG_CHECK_ALWAYS_DF |_CRTDBG_DELAY_FREE_MEM_DF |
1286 _CRTDBG_LEAK_CHECK_DF;
1287 if (0)
1288 {
1289 debug=_CrtSetDbgFlag(debug);
1290 _ASSERTE(_CrtCheckMemory());
1291 }
1292 }
1293#endif
1294#endif
1295 /*
1296 Set client name and execution path.
1297 */
1298 (void) GetExecutionPath(execution_path,MaxTextExtent);
cristy695e8c32011-11-09 18:27:04 +00001299 if ((path != (const char *) NULL) && (*path == *DirectorySeparator) &&
cristy905e5302011-11-09 18:08:43 +00001300 (IsPathAccessible(path) != MagickFalse))
cristy3ed852e2009-09-05 21:47:34 +00001301 (void) CopyMagickString(execution_path,path,MaxTextExtent);
1302 GetPathComponent(execution_path,TailPath,filename);
1303 (void) SetClientName(filename);
1304 GetPathComponent(execution_path,HeadPath,execution_path);
1305 (void) SetClientPath(execution_path);
1306 if (establish_signal_handlers != MagickFalse)
1307 {
1308 /*
1309 Set signal handlers.
1310 */
1311#if defined(SIGABRT)
1312 if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1313 signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1314#endif
cristy32a348b2011-04-22 16:03:42 +00001315#if defined(SIGSEGV)
1316 if (signal_handlers[SIGSEGV] == (SignalHandler *) NULL)
1317 signal_handlers[SIGSEGV]=RegisterMagickSignalHandler(SIGSEGV);
cristy7ae29582011-04-21 16:10:06 +00001318#endif
cristy3ed852e2009-09-05 21:47:34 +00001319#if defined(SIGFPE)
1320 if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1321 signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1322#endif
1323#if defined(SIGHUP)
1324 if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1325 signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1326#endif
cristy0157aea2010-04-24 21:12:18 +00001327#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001328 if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1329 signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1330#endif
1331#if defined(SIGQUIT)
1332 if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1333 signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1334#endif
1335#if defined(SIGTERM)
1336 if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1337 signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1338#endif
1339#if defined(SIGXCPU)
1340 if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1341 signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1342#endif
1343#if defined(SIGXFSZ)
1344 if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1345 signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1346#endif
1347 }
1348 /*
cristyaf8b5cd2009-10-24 00:29:23 +00001349 Instantiate magick resources.
cristy3ed852e2009-09-05 21:47:34 +00001350 */
cristy18b17442009-10-25 18:36:48 +00001351 (void) ConfigureComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001352 (void) PolicyComponentGenesis();
1353 (void) CacheComponentGenesis();
1354 (void) RegistryComponentGenesis();
1355 (void) ResourceComponentGenesis();
1356 (void) CoderComponentGenesis();
1357 (void) MagickComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001358#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001359 (void) ModuleComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001360#endif
cristyf34a1452009-10-24 22:29:27 +00001361 (void) DelegateComponentGenesis();
1362 (void) MagicComponentGenesis();
1363 (void) ColorComponentGenesis();
1364 (void) TypeComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001365 (void) MimeComponentGenesis();
1366 (void) ConstituteComponentGenesis();
cristyd7ecaca2011-01-24 14:14:53 +00001367 (void) AnnotateComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001368#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001369 (void) XComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001370#endif
cristyd1ebf4a2010-05-13 01:54:31 +00001371 instantiate_magickcore=MagickTrue;
1372 UnlockMagickMutex();
cristy3ed852e2009-09-05 21:47:34 +00001373}
1374
1375/*
1376%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1377% %
1378% %
1379% %
1380% M a g i c k C o r e T e r m i n u s %
1381% %
1382% %
1383% %
1384%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1385%
1386% MagickCoreTerminus() destroys the MagickCore environment.
1387%
cristyf34a1452009-10-24 22:29:27 +00001388% The format of the MagickCoreTerminus function is:
cristy3ed852e2009-09-05 21:47:34 +00001389%
1390% MagickCoreTerminus(void)
1391%
1392*/
1393MagickExport void MagickCoreTerminus(void)
1394{
cristyd1ebf4a2010-05-13 01:54:31 +00001395 LockMagickMutex();
1396 if (instantiate_magickcore == MagickFalse)
1397 {
1398 UnlockMagickMutex();
1399 return;
1400 }
cristy3ed852e2009-09-05 21:47:34 +00001401#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001402 XComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001403#endif
cristyd7ecaca2011-01-24 14:14:53 +00001404 AnnotateComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001405 ConstituteComponentTerminus();
1406 MimeComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001407 TypeComponentTerminus();
1408 ColorComponentTerminus();
cristy0157aea2010-04-24 21:12:18 +00001409#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001410 NTGhostscriptUnLoadDLL();
1411#endif
cristyf34a1452009-10-24 22:29:27 +00001412 MagicComponentTerminus();
1413 DelegateComponentTerminus();
1414 MagickComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001415#if !defined(MAGICKCORE_BUILD_MODULES)
1416 UnregisterStaticModules();
1417#endif
1418#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001419 ModuleComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001420#endif
cristyf34a1452009-10-24 22:29:27 +00001421 CoderComponentTerminus();
1422 ResourceComponentTerminus();
1423 RegistryComponentTerminus();
1424 CacheComponentTerminus();
1425 PolicyComponentTerminus();
cristy18b17442009-10-25 18:36:48 +00001426 ConfigureComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001427 RandomComponentTerminus();
1428 LocaleComponentTerminus();
1429 LogComponentTerminus();
1430 SemaphoreComponentTerminus();
cristyd1ebf4a2010-05-13 01:54:31 +00001431 instantiate_magickcore=MagickFalse;
1432 UnlockMagickMutex();
cristy3ed852e2009-09-05 21:47:34 +00001433}
1434
1435/*
1436%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1437% %
1438% %
1439% %
1440+ R e g i s t e r M a g i c k I n f o %
1441% %
1442% %
1443% %
1444%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1445%
1446% RegisterMagickInfo() adds attributes for a particular image format to the
1447% list of supported formats. The attributes include the image format name,
1448% a method to read and/or write the format, whether the format supports the
1449% saving of more than one frame to the same file or blob, whether the format
1450% supports native in-memory I/O, and a brief description of the format.
1451%
1452% The format of the RegisterMagickInfo method is:
1453%
1454% MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1455%
1456% A description of each parameter follows:
1457%
1458% o magick_info: the magick info.
1459%
1460*/
1461MagickExport MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1462{
1463 MagickBooleanType
1464 status;
1465
1466 /*
1467 Delete any existing name.
1468 */
1469 assert(magick_info != (MagickInfo *) NULL);
1470 assert(magick_info->signature == MagickSignature);
1471 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
1472 if (magick_list == (SplayTreeInfo *) NULL)
1473 return((MagickInfo *) NULL);
1474 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1475 if (status == MagickFalse)
1476 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1477 return(magick_info);
1478}
1479
1480/*
1481%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1482% %
1483% %
1484% %
1485+ S e t M a g i c k I n f o %
1486% %
1487% %
1488% %
1489%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1490%
1491% SetMagickInfo() allocates a MagickInfo structure and initializes the members
1492% to default values.
1493%
1494% The format of the SetMagickInfo method is:
1495%
1496% MagickInfo *SetMagickInfo(const char *name)
1497%
1498% A description of each parameter follows:
1499%
1500% o magick_info: Method SetMagickInfo returns the allocated and initialized
1501% MagickInfo structure.
1502%
1503% o name: a character string that represents the image format associated
1504% with the MagickInfo structure.
1505%
1506*/
1507MagickExport MagickInfo *SetMagickInfo(const char *name)
1508{
1509 MagickInfo
1510 *magick_info;
1511
1512 assert(name != (const char *) NULL);
1513 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
cristy73bd4a52010-10-05 11:24:23 +00001514 magick_info=(MagickInfo *) AcquireMagickMemory(sizeof(*magick_info));
cristy3ed852e2009-09-05 21:47:34 +00001515 if (magick_info == (MagickInfo *) NULL)
1516 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1517 (void) ResetMagickMemory(magick_info,0,sizeof(*magick_info));
1518 magick_info->name=ConstantString(name);
1519 magick_info->adjoin=MagickTrue;
1520 magick_info->blob_support=MagickTrue;
1521 magick_info->thread_support=(MagickStatusType) (DecoderThreadSupport |
1522 EncoderThreadSupport);
1523 magick_info->signature=MagickSignature;
1524 return(magick_info);
1525}
1526
1527/*
1528%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1529% %
1530% %
1531% %
cristye7f51092010-01-17 00:39:37 +00001532% S e t M a g i c k P r e c i s i o n %
1533% %
1534% %
1535% %
1536%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1537%
1538% SetMagickPrecision() sets the maximum number of significant digits to be
anthonybc6fc132012-01-16 07:02:46 +00001539% printed.
1540%
1541% An input argument of 0 returns the current precision setting.
1542%
cristyabdd5b72012-01-18 03:02:15 +00001543% A negative value forces the precision to reset to a default value according
1544% to the environment variable "MAGICK_PRECISION", the current 'policy'
1545% configuration setting, or the default value of '6', in that order.
cristye7f51092010-01-17 00:39:37 +00001546%
1547% The format of the SetMagickPrecision method is:
1548%
cristybf2766a2010-01-17 03:33:23 +00001549% int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001550%
1551% A description of each parameter follows:
1552%
1553% o precision: set the maximum number of significant digits to be printed.
1554%
1555*/
cristybf2766a2010-01-17 03:33:23 +00001556MagickExport int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001557{
anthonybc6fc132012-01-16 07:02:46 +00001558#define MagickPrecision 6
1559
cristybf2766a2010-01-17 03:33:23 +00001560 static int
1561 magick_precision = 0;
1562
cristye7f51092010-01-17 00:39:37 +00001563 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
anthony82c09922012-01-16 06:38:16 +00001564 if (precision > 0)
cristyabdd5b72012-01-18 03:02:15 +00001565 magick_precision=precision;
1566 if ((precision < 0) || (magick_precision == 0))
anthonybc6fc132012-01-16 07:02:46 +00001567 {
1568 char
1569 *limit;
1570
1571 /*
cristyabdd5b72012-01-18 03:02:15 +00001572 Precision reset, or it has not been set yet
anthonybc6fc132012-01-16 07:02:46 +00001573 */
1574 magick_precision = MagickPrecision;
1575 limit=GetEnvironmentValue("MAGICK_PRECISION");
1576 if (limit == (char *) NULL)
1577 limit=GetPolicyValue("precision");
1578 if (limit != (char *) NULL)
1579 {
cristyabdd5b72012-01-18 03:02:15 +00001580 magick_precision=StringToInteger(limit);
anthonybc6fc132012-01-16 07:02:46 +00001581 limit=DestroyString(limit);
1582 }
1583 }
cristybf2766a2010-01-17 03:33:23 +00001584 return(magick_precision);
cristye7f51092010-01-17 00:39:37 +00001585}
1586
1587/*
1588%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1589% %
1590% %
1591% %
cristy3ed852e2009-09-05 21:47:34 +00001592+ U n r e g i s t e r M a g i c k I n f o %
1593% %
1594% %
1595% %
1596%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1597%
1598% UnregisterMagickInfo() removes a name from the magick info list. It returns
1599% MagickFalse if the name does not exist in the list otherwise MagickTrue.
1600%
1601% The format of the UnregisterMagickInfo method is:
1602%
1603% MagickBooleanType UnregisterMagickInfo(const char *name)
1604%
1605% A description of each parameter follows:
1606%
1607% o name: a character string that represents the image format we are
1608% looking for.
1609%
1610*/
1611MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1612{
1613 register const MagickInfo
1614 *p;
1615
1616 MagickBooleanType
1617 status;
1618
1619 assert(name != (const char *) NULL);
1620 if (magick_list == (SplayTreeInfo *) NULL)
1621 return(MagickFalse);
1622 if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1623 return(MagickFalse);
cristyf84a1932010-01-03 18:00:18 +00001624 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001625 ResetSplayTreeIterator(magick_list);
1626 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1627 while (p != (const MagickInfo *) NULL)
1628 {
1629 if (LocaleCompare(p->name,name) == 0)
1630 break;
1631 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1632 }
1633 status=DeleteNodeByValueFromSplayTree(magick_list,p);
cristyf84a1932010-01-03 18:00:18 +00001634 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001635 return(status);
1636}