blob: da6528fc8d8427d47a4e43223d9b7e1181e4963e [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% M M AAA GGGG IIIII CCCC K K %
7% MM MM A A G I C K K %
8% M M M AAAAA G GGG I C KKK %
9% M M A A G G I C K K %
10% M M A A GGGG IIIII CCCC K K %
11% %
12% %
13% Methods to Read or List ImageMagick Image formats %
14% %
15% Software Design %
16% Bob Friesenhahn %
cristyde984cd2013-12-01 14:49:27 +000017% Cristy %
cristy3ed852e2009-09-05 21:47:34 +000018% November 1998 %
19% %
20% %
cristyfe676ee2013-11-18 13:03:38 +000021% Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000022% dedicated to making software imaging solutions freely available. %
23% %
24% You may not use this file except in compliance with the License. You may %
25% obtain a copy of the License at %
26% %
27% http://www.imagemagick.org/script/license.php %
28% %
29% Unless required by applicable law or agreed to in writing, software %
30% distributed under the License is distributed on an "AS IS" BASIS, %
31% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
32% See the License for the specific language governing permissions and %
33% limitations under the License. %
34% %
35%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36%
37%
38*/
39
40/*
41 Include declarations.
42*/
cristy4c08aed2011-07-01 19:47:50 +000043#include "MagickCore/studio.h"
cristy5ff4eaf2011-09-03 01:38:02 +000044#include "MagickCore/annotate-private.h"
cristy4c08aed2011-07-01 19:47:50 +000045#include "MagickCore/blob.h"
46#include "MagickCore/blob-private.h"
47#include "MagickCore/cache.h"
cristy5ff4eaf2011-09-03 01:38:02 +000048#include "MagickCore/cache-private.h"
49#include "MagickCore/coder-private.h"
cristy4c08aed2011-07-01 19:47:50 +000050#include "MagickCore/client.h"
cristy5ff4eaf2011-09-03 01:38:02 +000051#include "MagickCore/color-private.h"
52#include "MagickCore/configure-private.h"
53#include "MagickCore/constitute-private.h"
54#include "MagickCore/delegate-private.h"
cristy4c08aed2011-07-01 19:47:50 +000055#include "MagickCore/draw.h"
56#include "MagickCore/exception.h"
57#include "MagickCore/exception-private.h"
cristy5ff4eaf2011-09-03 01:38:02 +000058#include "MagickCore/locale-private.h"
59#include "MagickCore/log-private.h"
60#include "MagickCore/magic-private.h"
cristy4c08aed2011-07-01 19:47:50 +000061#include "MagickCore/magick.h"
cristy5ff4eaf2011-09-03 01:38:02 +000062#include "MagickCore/magick-private.h"
cristy4c08aed2011-07-01 19:47:50 +000063#include "MagickCore/memory_.h"
cristy5ff4eaf2011-09-03 01:38:02 +000064#include "MagickCore/mime-private.h"
cristy4c08aed2011-07-01 19:47:50 +000065#include "MagickCore/module.h"
cristy5ff4eaf2011-09-03 01:38:02 +000066#include "MagickCore/module-private.h"
cristy2c5fc272012-02-22 01:27:46 +000067#include "MagickCore/nt-base-private.h"
cristy5ff4eaf2011-09-03 01:38:02 +000068#include "MagickCore/random-private.h"
cristy4c08aed2011-07-01 19:47:50 +000069#include "MagickCore/registry.h"
cristy5ff4eaf2011-09-03 01:38:02 +000070#include "MagickCore/registry-private.h"
cristy4c08aed2011-07-01 19:47:50 +000071#include "MagickCore/resource_.h"
cristy0a4d92f2011-08-31 19:25:00 +000072#include "MagickCore/resource-private.h"
cristy4c08aed2011-07-01 19:47:50 +000073#include "MagickCore/policy.h"
cristy5ff4eaf2011-09-03 01:38:02 +000074#include "MagickCore/policy-private.h"
cristy4c08aed2011-07-01 19:47:50 +000075#include "MagickCore/semaphore.h"
76#include "MagickCore/semaphore-private.h"
77#include "MagickCore/signature-private.h"
78#include "MagickCore/splay-tree.h"
79#include "MagickCore/string_.h"
80#include "MagickCore/string-private.h"
81#include "MagickCore/thread_.h"
82#include "MagickCore/thread-private.h"
cristy5ff4eaf2011-09-03 01:38:02 +000083#include "MagickCore/type-private.h"
cristy4c08aed2011-07-01 19:47:50 +000084#include "MagickCore/token.h"
85#include "MagickCore/utility.h"
cristyd1dd6e42011-09-04 01:46:08 +000086#include "MagickCore/utility-private.h"
cristy4c08aed2011-07-01 19:47:50 +000087#include "MagickCore/xwindow-private.h"
cristy3ed852e2009-09-05 21:47:34 +000088
89/*
90 Define declarations.
91*/
92#if !defined(MAGICKCORE_RETSIGTYPE)
93# define MAGICKCORE_RETSIGTYPE void
94#endif
95#if !defined(SIG_DFL)
96# define SIG_DFL ((SignalHandler *) 0)
97#endif
98#if !defined(SIG_ERR)
99# define SIG_ERR ((SignalHandler *) -1)
100#endif
101#if !defined(SIGMAX)
102#define SIGMAX 64
103#endif
104
105/*
106 Typedef declarations.
107*/
108typedef MAGICKCORE_RETSIGTYPE
109 SignalHandler(int);
110
111/*
112 Global declarations.
113*/
114static SemaphoreInfo
115 *magick_semaphore = (SemaphoreInfo *) NULL;
116
117static SignalHandler
118 *signal_handlers[SIGMAX] = { (SignalHandler *) NULL };
119
120static SplayTreeInfo
121 *magick_list = (SplayTreeInfo *) NULL;
122
123static volatile MagickBooleanType
cristyd1ebf4a2010-05-13 01:54:31 +0000124 instantiate_magickcore = MagickFalse;
cristy3ed852e2009-09-05 21:47:34 +0000125
126/*
127 Forward declarations.
128*/
129static MagickBooleanType
cristy904e5912014-03-15 19:53:14 +0000130 IsMagickTreeInstantiated(ExceptionInfo *);
cristy3ed852e2009-09-05 21:47:34 +0000131
132/*
133%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134% %
135% %
136% %
cristy3ed852e2009-09-05 21:47:34 +0000137+ G e t I m a g e D e c o d e r %
138% %
139% %
140% %
141%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142%
143% GetImageDecoder() returns the image decoder.
144%
145% The format of the GetImageDecoder method is:
146%
147% DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
148%
149% A description of each parameter follows:
150%
151% o magick_info: The magick info.
152%
153*/
154MagickExport DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
155{
156 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
157 assert(magick_info != (MagickInfo *) NULL);
158 assert(magick_info->signature == MagickSignature);
159 return(magick_info->decoder);
160}
161
162/*
163%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164% %
165% %
166% %
167+ G e t I m a g e E n c o d e r %
168% %
169% %
170% %
171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172%
173% GetImageEncoder() returns the image encoder.
174%
175% The format of the GetImageEncoder method is:
176%
177% EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
178%
179% A description of each parameter follows:
180%
181% o magick_info: The magick info.
182%
183*/
184MagickExport EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
185{
186 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
187 assert(magick_info != (MagickInfo *) NULL);
188 assert(magick_info->signature == MagickSignature);
189 return(magick_info->encoder);
190}
191
192/*
193%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
194% %
195% %
196% %
197+ G e t I m a g e M a g i c k %
198% %
199% %
200% %
201%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
202%
203% GetImageMagick() searches for an image format that matches the specified
204% magick string. If one is found, MagickTrue is returned otherwise
205% MagickFalse.
206%
207% The format of the GetImageMagick method is:
208%
209% MagickBooleanType GetImageMagick(const unsigned char *magick,
210% const size_t length,char *format)
211%
212% A description of each parameter follows:
213%
214% o magick: the image format we are searching for.
215%
216% o length: the length of the binary string.
217%
218% o format: the image format as determined by the magick bytes.
219%
220*/
221MagickExport MagickBooleanType GetImageMagick(const unsigned char *magick,
222 const size_t length,char *format)
223{
224 ExceptionInfo
225 *exception;
226
227 MagickBooleanType
228 status;
229
230 register const MagickInfo
231 *p;
232
233 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
234 assert(magick != (const unsigned char *) NULL);
235 exception=AcquireExceptionInfo();
236 p=GetMagickInfo("*",exception);
237 exception=DestroyExceptionInfo(exception);
238 if (p == (const MagickInfo *) NULL)
239 return(MagickFalse);
240 status=MagickFalse;
cristyf84a1932010-01-03 18:00:18 +0000241 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000242 ResetSplayTreeIterator(magick_list);
243 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
244 while (p != (const MagickInfo *) NULL)
245 {
246 if ((p->magick != (IsImageFormatHandler *) NULL) &&
247 (p->magick(magick,length) != 0))
248 {
249 status=MagickTrue;
250 (void) CopyMagickString(format,p->name,MaxTextExtent);
251 break;
252 }
253 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
254 }
cristyf84a1932010-01-03 18:00:18 +0000255 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000256 return(status);
257}
258
259/*
260%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261% %
262% %
263% %
264+ G e t M a g i c k A d j o i n %
265% %
266% %
267% %
268%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
269%
270% GetMagickAdjoin() returns MagickTrue if the magick adjoin is MagickTrue.
271%
272% The format of the GetMagickAdjoin method is:
273%
274% MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
275%
276% A description of each parameter follows:
277%
278% o magick_info: The magick info.
279%
280*/
281MagickExport MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
282{
283 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
284 assert(magick_info != (MagickInfo *) NULL);
285 assert(magick_info->signature == MagickSignature);
286 return(magick_info->adjoin);
287}
288
289/*
290%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
291% %
292% %
293% %
294+ G e t M a g i c k B l o b S u p p o r t %
295% %
296% %
297% %
298%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
299%
300% GetMagickBlobSupport() returns MagickTrue if the magick supports blobs.
301%
302% The format of the GetMagickBlobSupport method is:
303%
304% MagickBooleanType GetMagickBlobSupport(const MagickInfo *magick_info)
305%
306% A description of each parameter follows:
307%
308% o magick_info: The magick info.
309%
310*/
311MagickExport MagickBooleanType GetMagickBlobSupport(
312 const MagickInfo *magick_info)
313{
314 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
315 assert(magick_info != (MagickInfo *) NULL);
316 assert(magick_info->signature == MagickSignature);
317 return(magick_info->blob_support);
318}
319
320/*
321%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
322% %
323% %
324% %
325+ G e t M a g i c k D e s c r i p t i o n %
326% %
327% %
328% %
329%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
330%
331% GetMagickDescription() returns the magick description.
332%
333% The format of the GetMagickDescription method is:
334%
335% const char *GetMagickDescription(const MagickInfo *magick_info)
336%
337% A description of each parameter follows:
338%
339% o magick_info: The magick info.
340%
341*/
342MagickExport const char *GetMagickDescription(const MagickInfo *magick_info)
343{
344 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
345 assert(magick_info != (MagickInfo *) NULL);
346 assert(magick_info->signature == MagickSignature);
347 return(magick_info->description);
348}
349
350/*
351%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
352% %
353% %
354% %
355+ G e t M a g i c k E n d i a n S u p p o r t %
356% %
357% %
358% %
359%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
360%
361% GetMagickEndianSupport() returns the MagickTrue if the coder respects
362% endianness other than MSBEndian.
363%
364% The format of the GetMagickEndianSupport method is:
365%
366% MagickBooleanType GetMagickEndianSupport(const MagickInfo *magick_info)
367%
368% A description of each parameter follows:
369%
370% o magick_info: The magick info.
371%
372*/
373MagickExport MagickBooleanType GetMagickEndianSupport(
374 const MagickInfo *magick_info)
375{
376 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
377 assert(magick_info != (MagickInfo *) NULL);
378 assert(magick_info->signature == MagickSignature);
379 return(magick_info->endian_support);
380}
381
382/*
383%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
384% %
385% %
386% %
387+ G e t M a g i c k I n f o %
388% %
389% %
390% %
391%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
392%
393% GetMagickInfo() returns a pointer MagickInfo structure that matches
394% the specified name. If name is NULL, the head of the image format list
395% is returned.
396%
397% The format of the GetMagickInfo method is:
398%
399% const MagickInfo *GetMagickInfo(const char *name,Exception *exception)
400%
401% A description of each parameter follows:
402%
403% o name: the image format we are looking for.
404%
405% o exception: return any errors or warnings in this structure.
406%
407*/
408MagickExport const MagickInfo *GetMagickInfo(const char *name,
409 ExceptionInfo *exception)
410{
411 register const MagickInfo
412 *p;
413
414 assert(exception != (ExceptionInfo *) NULL);
cristy904e5912014-03-15 19:53:14 +0000415 if (IsMagickTreeInstantiated(exception) == MagickFalse)
416 return((const MagickInfo *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000417 /*
418 Find name in list.
419 */
cristyf84a1932010-01-03 18:00:18 +0000420 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000421 ResetSplayTreeIterator(magick_list);
422 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
cristy49d4d222014-03-16 00:37:58 +0000423 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
424 {
425#if defined(MAGICKCORE_MODULES_SUPPORT)
426 if (LocaleCompare(name,"*") == 0)
427 (void) OpenModules(exception);
428#endif
429 ResetSplayTreeIterator(magick_list);
430 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
431 UnlockSemaphoreInfo(magick_semaphore);
432 return(p);
433 }
cristy3ed852e2009-09-05 21:47:34 +0000434 while (p != (const MagickInfo *) NULL)
435 {
436 if (LocaleCompare(p->name,name) == 0)
437 break;
438 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
439 }
440#if defined(MAGICKCORE_MODULES_SUPPORT)
441 if (p == (const MagickInfo *) NULL)
442 {
443 if (*name != '\0')
444 (void) OpenModule(name,exception);
445 ResetSplayTreeIterator(magick_list);
446 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
447 while (p != (const MagickInfo *) NULL)
448 {
449 if (LocaleCompare(p->name,name) == 0)
450 break;
451 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
452 }
453 }
454#endif
cristyf84a1932010-01-03 18:00:18 +0000455 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000456 return(p);
457}
458
459/*
460%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
461% %
462% %
463% %
464+ G e t M a g i c k I n f o L i s t %
465% %
466% %
467% %
468%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
469%
470% GetMagickInfoList() returns any image formats that match the specified
471% pattern.
472%
473% The format of the GetMagickInfoList function is:
474%
475% const MagickInfo **GetMagickInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000476% size_t *number_formats,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000477%
478% A description of each parameter follows:
479%
480% o pattern: Specifies a pointer to a text string containing a pattern.
481%
482% o number_formats: This integer returns the number of formats in the list.
483%
484% o exception: return any errors or warnings in this structure.
485%
486*/
487
488#if defined(__cplusplus) || defined(c_plusplus)
489extern "C" {
490#endif
491
492static int MagickInfoCompare(const void *x,const void *y)
493{
494 const MagickInfo
495 **p,
496 **q;
497
498 p=(const MagickInfo **) x,
499 q=(const MagickInfo **) y;
500 return(LocaleCompare((*p)->name,(*q)->name));
501}
502
503#if defined(__cplusplus) || defined(c_plusplus)
504}
505#endif
506
507MagickExport const MagickInfo **GetMagickInfoList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000508 size_t *number_formats,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000509{
510 const MagickInfo
511 **formats;
512
513 register const MagickInfo
514 *p;
515
cristybb503372010-05-27 20:51:26 +0000516 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000517 i;
518
519 /*
520 Allocate magick list.
521 */
522 assert(pattern != (char *) NULL);
523 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000524 assert(number_formats != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000525 *number_formats=0;
526 p=GetMagickInfo("*",exception);
527 if (p == (const MagickInfo *) NULL)
528 return((const MagickInfo **) NULL);
529 formats=(const MagickInfo **) AcquireQuantumMemory((size_t)
530 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
531 if (formats == (const MagickInfo **) NULL)
532 return((const MagickInfo **) NULL);
533 /*
534 Generate magick list.
535 */
cristyf84a1932010-01-03 18:00:18 +0000536 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000537 ResetSplayTreeIterator(magick_list);
538 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
539 for (i=0; p != (const MagickInfo *) NULL; )
540 {
541 if ((p->stealth == MagickFalse) &&
542 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
543 formats[i++]=p;
544 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
545 }
cristyf84a1932010-01-03 18:00:18 +0000546 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000547 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickInfoCompare);
548 formats[i]=(MagickInfo *) NULL;
cristybb503372010-05-27 20:51:26 +0000549 *number_formats=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000550 return(formats);
551}
552
553/*
554%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
555% %
556% %
557% %
558+ G e t M a g i c k L i s t %
559% %
560% %
561% %
562%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
563%
564% GetMagickList() returns any image formats that match the specified pattern.
565%
566% The format of the GetMagickList function is:
567%
cristybb503372010-05-27 20:51:26 +0000568% char **GetMagickList(const char *pattern,size_t *number_formats,
cristy3ed852e2009-09-05 21:47:34 +0000569% ExceptionInfo *exception)
570%
571% A description of each parameter follows:
572%
573% o pattern: Specifies a pointer to a text string containing a pattern.
574%
575% o number_formats: This integer returns the number of formats in the list.
576%
577% o exception: return any errors or warnings in this structure.
578%
579*/
580
581#if defined(__cplusplus) || defined(c_plusplus)
582extern "C" {
583#endif
584
585static int MagickCompare(const void *x,const void *y)
586{
587 register const char
588 **p,
589 **q;
590
591 p=(const char **) x;
592 q=(const char **) y;
593 return(LocaleCompare(*p,*q));
594}
595
596#if defined(__cplusplus) || defined(c_plusplus)
597}
598#endif
599
600MagickExport char **GetMagickList(const char *pattern,
cristybb503372010-05-27 20:51:26 +0000601 size_t *number_formats,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000602{
603 char
604 **formats;
605
606 register const MagickInfo
607 *p;
608
cristybb503372010-05-27 20:51:26 +0000609 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000610 i;
611
612 /*
613 Allocate magick list.
614 */
615 assert(pattern != (char *) NULL);
616 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
cristybb503372010-05-27 20:51:26 +0000617 assert(number_formats != (size_t *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000618 *number_formats=0;
619 p=GetMagickInfo("*",exception);
620 if (p == (const MagickInfo *) NULL)
621 return((char **) NULL);
622 formats=(char **) AcquireQuantumMemory((size_t)
623 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
624 if (formats == (char **) NULL)
625 return((char **) NULL);
cristyf84a1932010-01-03 18:00:18 +0000626 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000627 ResetSplayTreeIterator(magick_list);
628 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
629 for (i=0; p != (const MagickInfo *) NULL; )
630 {
631 if ((p->stealth == MagickFalse) &&
632 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
633 formats[i++]=ConstantString(p->name);
634 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
635 }
cristyf84a1932010-01-03 18:00:18 +0000636 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000637 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickCompare);
638 formats[i]=(char *) NULL;
cristybb503372010-05-27 20:51:26 +0000639 *number_formats=(size_t) i;
cristy3ed852e2009-09-05 21:47:34 +0000640 return(formats);
641}
642
643/*
644%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
645% %
646% %
647% %
cristy4a6ab482013-08-09 01:29:35 +0000648+ G e t M a g i c k M i m e T y p e %
649% %
650% %
651% %
652%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
653%
654% GetMagickMimeType() returns the magick mime type.
655%
656% The format of the GetMagickMimeType method is:
657%
658% const char *GetMagickMimeType(const MagickInfo *magick_info)
659%
660% A description of each parameter follows:
661%
662% o magick_info: The magick info.
663%
664*/
665MagickExport const char *GetMagickMimeType(const MagickInfo *magick_info)
666{
667 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
668 assert(magick_info != (MagickInfo *) NULL);
669 assert(magick_info->signature == MagickSignature);
670 return(magick_info->mime_type);
671}
672
673/*
674%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
675% %
676% %
677% %
cristye7f51092010-01-17 00:39:37 +0000678% G e t M a g i c k P r e c i s i o n %
cristy7ce14bc2010-01-17 00:01:01 +0000679% %
680% %
681% %
682%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
683%
684% GetMagickPrecision() returns the maximum number of significant digits to be
685% printed.
686%
687% The format of the GetMagickPrecision method is:
688%
cristye7f51092010-01-17 00:39:37 +0000689% int GetMagickPrecision(void)
cristy7ce14bc2010-01-17 00:01:01 +0000690%
691*/
cristye7f51092010-01-17 00:39:37 +0000692MagickExport int GetMagickPrecision(void)
cristy7ce14bc2010-01-17 00:01:01 +0000693{
cristy7ce14bc2010-01-17 00:01:01 +0000694 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
cristybf2766a2010-01-17 03:33:23 +0000695 return(SetMagickPrecision(0));
cristy7ce14bc2010-01-17 00:01:01 +0000696}
697
698/*
699%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
700% %
701% %
702% %
703+ 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 +0000704% %
705% %
706% %
707%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
708%
709% GetMagickRawSupport() returns the MagickTrue if the coder is a raw format.
710%
711% The format of the GetMagickRawSupport method is:
712%
713% MagickBooleanType GetMagickRawSupport(const MagickInfo *magick_info)
714%
715% A description of each parameter follows:
716%
717% o magick_info: The magick info.
718%
719*/
720MagickExport MagickBooleanType GetMagickRawSupport(
721 const MagickInfo *magick_info)
722{
723 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
724 assert(magick_info != (MagickInfo *) NULL);
725 assert(magick_info->signature == MagickSignature);
726 return(magick_info->raw);
727}
728
729/*
730%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
731% %
732% %
733% %
734+ G e t M a g i c k S e e k a b l e S t r e a m %
735% %
736% %
737% %
738%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
739%
740% GetMagickSeekableStream() returns MagickTrue if the magick supports a
741% seekable stream.
742%
743% The format of the GetMagickSeekableStream method is:
744%
745% MagickBooleanType GetMagickSeekableStream(const MagickInfo *magick_info)
746%
747% A description of each parameter follows:
748%
749% o magick_info: The magick info.
750%
751*/
752MagickExport MagickBooleanType GetMagickSeekableStream(
753 const MagickInfo *magick_info)
754{
755 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
756 assert(magick_info != (MagickInfo *) NULL);
757 assert(magick_info->signature == MagickSignature);
758 return(magick_info->seekable_stream);
759}
760
761/*
762%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
763% %
764% %
765% %
766+ G e t M a g i c k T h r e a d S u p p o r t %
767% %
768% %
769% %
770%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
771%
772% GetMagickThreadSupport() returns MagickTrue if the magick supports threads.
773%
774% The format of the GetMagickThreadSupport method is:
775%
776% MagickStatusType GetMagickThreadSupport(const MagickInfo *magick_info)
777%
778% A description of each parameter follows:
779%
780% o magick_info: The magick info.
781%
782*/
783MagickExport MagickStatusType GetMagickThreadSupport(
784 const MagickInfo *magick_info)
785{
786 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
787 assert(magick_info != (MagickInfo *) NULL);
788 assert(magick_info->signature == MagickSignature);
789 return(magick_info->thread_support);
790}
791
792/*
793%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
794% %
795% %
796% %
cristy904e5912014-03-15 19:53:14 +0000797+ I s M a g i c k T r e e I n s t a n t i a t e d %
cristy3ed852e2009-09-05 21:47:34 +0000798% %
799% %
800% %
801%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
802%
cristy904e5912014-03-15 19:53:14 +0000803% IsMagickTreeInstantiated() determines if the magick tree is instantiated.
804% If not, it instantiates the tree and returns it.
cristy3ed852e2009-09-05 21:47:34 +0000805%
cristy904e5912014-03-15 19:53:14 +0000806% The format of the IsMagickTreeInstantiated() method is:
cristy3ed852e2009-09-05 21:47:34 +0000807%
cristy904e5912014-03-15 19:53:14 +0000808% IsMagickTreeInstantiated(Exceptioninfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000809%
810% A description of each parameter follows.
811%
812% o exception: return any errors or warnings in this structure.
813%
814*/
815
816static void *DestroyMagickNode(void *magick_info)
817{
818 register MagickInfo
819 *p;
820
821 p=(MagickInfo *) magick_info;
cristy3ed852e2009-09-05 21:47:34 +0000822 if (p->module != (char *) NULL)
823 p->module=DestroyString(p->module);
cristy4a6ab482013-08-09 01:29:35 +0000824 if (p->note != (char *) NULL)
825 p->note=DestroyString(p->note);
826 if (p->mime_type != (char *) NULL)
827 p->mime_type=DestroyString(p->mime_type);
828 if (p->version != (char *) NULL)
829 p->version=DestroyString(p->version);
830 if (p->description != (char *) NULL)
831 p->description=DestroyString(p->description);
832 if (p->name != (char *) NULL)
833 p->name=DestroyString(p->name);
cristy3ed852e2009-09-05 21:47:34 +0000834 return(RelinquishMagickMemory(p));
835}
836
cristy904e5912014-03-15 19:53:14 +0000837static MagickBooleanType IsMagickTreeInstantiated(ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000838{
cristyf2e11662009-10-14 01:24:43 +0000839 (void) exception;
cristy1460f262014-03-15 17:38:05 +0000840 if (magick_semaphore == (SemaphoreInfo *) NULL)
841 ActivateSemaphoreInfo(&magick_semaphore);
842 LockSemaphoreInfo(magick_semaphore);
843 if (magick_list == (SplayTreeInfo *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000844 {
cristy1460f262014-03-15 17:38:05 +0000845 MagickBooleanType
846 status;
cristy3ed852e2009-09-05 21:47:34 +0000847
cristy1460f262014-03-15 17:38:05 +0000848 MagickInfo
849 *magick_info;
cristy3ed852e2009-09-05 21:47:34 +0000850
cristy1460f262014-03-15 17:38:05 +0000851 magick_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL,
852 DestroyMagickNode);
853 if (magick_list == (SplayTreeInfo *) NULL)
854 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
855 magick_info=SetMagickInfo("ephemeral");
856 magick_info->stealth=MagickTrue;
857 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
858 if (status == MagickFalse)
859 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
860 magick_info=SetMagickInfo("clipmask");
861 magick_info->stealth=MagickTrue;
862 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
863 if (status == MagickFalse)
864 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristy3ed852e2009-09-05 21:47:34 +0000865#if defined(MAGICKCORE_MODULES_SUPPORT)
cristy1460f262014-03-15 17:38:05 +0000866 (void) GetModuleInfo((char *) NULL,exception);
cristy3ed852e2009-09-05 21:47:34 +0000867#endif
868#if !defined(MAGICKCORE_BUILD_MODULES)
cristy1460f262014-03-15 17:38:05 +0000869 RegisterStaticModules();
cristy3ed852e2009-09-05 21:47:34 +0000870#endif
cristy3ed852e2009-09-05 21:47:34 +0000871 }
cristy1460f262014-03-15 17:38:05 +0000872 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000873 return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
874}
875
876/*
877%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
878% %
879% %
880% %
881+ I s M a g i c k C o n f l i c t %
882% %
883% %
884% %
885%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
886%
cristy05a9a622010-03-15 17:26:04 +0000887% IsMagickConflict() returns MagickTrue if the image format conflicts with a
888% logical drive (.e.g. X:).
cristy3ed852e2009-09-05 21:47:34 +0000889%
890% The format of the IsMagickConflict method is:
891%
892% MagickBooleanType IsMagickConflict(const char *magick)
893%
894% A description of each parameter follows:
895%
896% o magick: Specifies the image format.
897%
898*/
cristy7832dc22011-09-05 01:21:53 +0000899MagickPrivate MagickBooleanType IsMagickConflict(const char *magick)
cristy3ed852e2009-09-05 21:47:34 +0000900{
cristy3ed852e2009-09-05 21:47:34 +0000901 assert(magick != (char *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000902#if defined(macintosh)
903 return(MACIsMagickConflict(magick));
904#elif defined(vms)
905 return(VMSIsMagickConflict(magick));
cristy0157aea2010-04-24 21:12:18 +0000906#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000907 return(NTIsMagickConflict(magick));
908#else
909 return(MagickFalse);
910#endif
911}
912
913/*
914%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
915% %
916% %
917% %
918+ L i s t M a g i c k I n f o %
919% %
920% %
921% %
922%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
923%
924% ListMagickInfo() lists the image formats to a file.
925%
926% The format of the ListMagickInfo method is:
927%
928% MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
929%
930% A description of each parameter follows.
931%
932% o file: A file handle.
933%
934% o exception: return any errors or warnings in this structure.
935%
936*/
937MagickExport MagickBooleanType ListMagickInfo(FILE *file,
938 ExceptionInfo *exception)
939{
940 const MagickInfo
941 **magick_info;
942
cristybb503372010-05-27 20:51:26 +0000943 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000944 i;
945
cristybb503372010-05-27 20:51:26 +0000946 size_t
cristy3ed852e2009-09-05 21:47:34 +0000947 number_formats;
948
cristy9d314ff2011-03-09 01:30:28 +0000949 ssize_t
950 j;
951
cristy3ed852e2009-09-05 21:47:34 +0000952 if (file == (FILE *) NULL)
953 file=stdout;
954 magick_info=GetMagickInfoList("*",&number_formats,exception);
955 if (magick_info == (const MagickInfo **) NULL)
956 return(MagickFalse);
957 ClearMagickException(exception);
958#if !defined(MAGICKCORE_MODULES_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000959 (void) FormatLocaleFile(file," Format Mode Description\n");
cristy3ed852e2009-09-05 21:47:34 +0000960#else
cristyb51dff52011-05-19 16:55:47 +0000961 (void) FormatLocaleFile(file," Format Module Mode Description\n");
cristy3ed852e2009-09-05 21:47:34 +0000962#endif
cristy1e604812011-05-19 18:07:50 +0000963 (void) FormatLocaleFile(file,
964 "--------------------------------------------------------"
cristy3ed852e2009-09-05 21:47:34 +0000965 "-----------------------\n");
cristybb503372010-05-27 20:51:26 +0000966 for (i=0; i < (ssize_t) number_formats; i++)
cristy3ed852e2009-09-05 21:47:34 +0000967 {
968 if (magick_info[i]->stealth != MagickFalse)
969 continue;
cristy1e604812011-05-19 18:07:50 +0000970 (void) FormatLocaleFile(file,"%9s%c ",
971 magick_info[i]->name != (char *) NULL ? magick_info[i]->name : "",
cristy3ed852e2009-09-05 21:47:34 +0000972 magick_info[i]->blob_support != MagickFalse ? '*' : ' ');
973#if defined(MAGICKCORE_MODULES_SUPPORT)
974 {
975 char
976 module[MaxTextExtent];
977
978 *module='\0';
979 if (magick_info[i]->module != (char *) NULL)
980 (void) CopyMagickString(module,magick_info[i]->module,MaxTextExtent);
981 (void) ConcatenateMagickString(module," ",MaxTextExtent);
982 module[9]='\0';
cristyb51dff52011-05-19 16:55:47 +0000983 (void) FormatLocaleFile(file,"%9s ",module);
cristy3ed852e2009-09-05 21:47:34 +0000984 }
985#endif
cristyb51dff52011-05-19 16:55:47 +0000986 (void) FormatLocaleFile(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
cristy3ed852e2009-09-05 21:47:34 +0000987 magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
988 magick_info[i]->adjoin != MagickFalse ? '+' : '-');
989 if (magick_info[i]->description != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +0000990 (void) FormatLocaleFile(file," %s",magick_info[i]->description);
cristy3ed852e2009-09-05 21:47:34 +0000991 if (magick_info[i]->version != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +0000992 (void) FormatLocaleFile(file," (%s)",magick_info[i]->version);
993 (void) FormatLocaleFile(file,"\n");
cristy3ed852e2009-09-05 21:47:34 +0000994 if (magick_info[i]->note != (char *) NULL)
995 {
996 char
997 **text;
998
999 text=StringToList(magick_info[i]->note);
1000 if (text != (char **) NULL)
1001 {
1002 for (j=0; text[j] != (char *) NULL; j++)
1003 {
cristyb51dff52011-05-19 16:55:47 +00001004 (void) FormatLocaleFile(file," %s\n",text[j]);
cristy3ed852e2009-09-05 21:47:34 +00001005 text[j]=DestroyString(text[j]);
1006 }
1007 text=(char **) RelinquishMagickMemory(text);
1008 }
1009 }
1010 }
cristyb51dff52011-05-19 16:55:47 +00001011 (void) FormatLocaleFile(file,"\n* native blob support\n");
1012 (void) FormatLocaleFile(file,"r read support\n");
1013 (void) FormatLocaleFile(file,"w write support\n");
1014 (void) FormatLocaleFile(file,"+ support for multiple images\n");
cristy3ed852e2009-09-05 21:47:34 +00001015 (void) fflush(file);
1016 magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1017 magick_info);
1018 return(MagickTrue);
1019}
1020
1021/*
1022%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1023% %
1024% %
1025% %
cristy019459e2014-01-02 23:47:13 +00001026% 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 +00001027% %
1028% %
1029% %
1030%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1031%
cristy019459e2014-01-02 23:47:13 +00001032% IsMagickCoreInstantiated() returns MagickTrue if the ImageMagick environment
cristy3ed852e2009-09-05 21:47:34 +00001033% is currently instantiated: MagickCoreGenesis() has been called but
1034% MagickDestroy() has not.
1035%
cristy019459e2014-01-02 23:47:13 +00001036% The format of the IsMagickCoreInstantiated method is:
cristy3ed852e2009-09-05 21:47:34 +00001037%
cristy019459e2014-01-02 23:47:13 +00001038% MagickBooleanType IsMagickCoreInstantiated(void)
cristy3ed852e2009-09-05 21:47:34 +00001039%
1040*/
cristy019459e2014-01-02 23:47:13 +00001041MagickExport MagickBooleanType IsMagickCoreInstantiated(void)
cristy3ed852e2009-09-05 21:47:34 +00001042{
cristy0f86a122014-01-03 18:15:50 +00001043 return(instantiate_magickcore);
cristy3ed852e2009-09-05 21:47:34 +00001044}
1045
1046/*
1047%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1048% %
1049% %
1050% %
cristyf34a1452009-10-24 22:29:27 +00001051+ M a g i c k C o m p o n e n t G e n e s i s %
1052% %
1053% %
1054% %
1055%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1056%
1057% MagickComponentGenesis() instantiates the magick component.
1058%
1059% The format of the MagickComponentGenesis method is:
1060%
1061% MagickBooleanType MagickComponentGenesis(void)
1062%
1063*/
cristy5ff4eaf2011-09-03 01:38:02 +00001064MagickPrivate MagickBooleanType MagickComponentGenesis(void)
cristyf34a1452009-10-24 22:29:27 +00001065{
cristy3d162a92014-02-16 14:05:06 +00001066 magick_semaphore=AcquireSemaphoreInfo();
cristyf34a1452009-10-24 22:29:27 +00001067 return(MagickTrue);
1068}
1069
1070/*
1071%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1072% %
1073% %
1074% %
1075+ M a g i c k C o m p o n e n t T e r m i n u s %
1076% %
1077% %
1078% %
1079%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1080%
1081% MagickComponentTerminus() destroys the magick component.
1082%
1083% The format of the MagickComponentTerminus method is:
1084%
1085% void MagickComponentTerminus(void)
1086%
1087*/
cristy5ff4eaf2011-09-03 01:38:02 +00001088MagickPrivate void MagickComponentTerminus(void)
cristyf34a1452009-10-24 22:29:27 +00001089{
cristy18b17442009-10-25 18:36:48 +00001090 if (magick_semaphore == (SemaphoreInfo *) NULL)
cristy04b11db2014-02-16 15:10:39 +00001091 ActivateSemaphoreInfo(&magick_semaphore);
cristyf84a1932010-01-03 18:00:18 +00001092 LockSemaphoreInfo(magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001093 if (magick_list != (SplayTreeInfo *) NULL)
1094 magick_list=DestroySplayTree(magick_list);
cristyf84a1932010-01-03 18:00:18 +00001095 UnlockSemaphoreInfo(magick_semaphore);
cristy3d162a92014-02-16 14:05:06 +00001096 RelinquishSemaphoreInfo(&magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001097}
1098
1099/*
1100%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1101% %
1102% %
1103% %
cristy3ed852e2009-09-05 21:47:34 +00001104% M a g i c k C o r e G e n e s i s %
1105% %
1106% %
1107% %
1108%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1109%
1110% MagickCoreGenesis() initializes the MagickCore environment.
1111%
1112% The format of the MagickCoreGenesis function is:
1113%
1114% MagickCoreGenesis(const char *path,
1115% const MagickBooleanType establish_signal_handlers)
1116%
1117% A description of each parameter follows:
1118%
1119% o path: the execution path of the current ImageMagick client.
1120%
1121% o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1122% signal handlers for common signals.
1123%
1124*/
1125
1126static SignalHandler *SetMagickSignalHandler(int signal_number,
1127 SignalHandler *handler)
1128{
1129#if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1130 int
1131 status;
1132
1133 sigset_t
1134 mask;
1135
1136 struct sigaction
1137 action,
1138 previous_action;
1139
1140 sigemptyset(&mask);
1141 sigaddset(&mask,signal_number);
1142 sigprocmask(SIG_BLOCK,&mask,NULL);
1143 action.sa_mask=mask;
1144 action.sa_handler=handler;
1145 action.sa_flags=0;
1146#if defined(SA_INTERRUPT)
1147 action.sa_flags|=SA_INTERRUPT;
1148#endif
1149 status=sigaction(signal_number,&action,&previous_action);
1150 if (status < 0)
1151 return(SIG_ERR);
1152 sigprocmask(SIG_UNBLOCK,&mask,NULL);
1153 return(previous_action.sa_handler);
1154#else
1155 return(signal(signal_number,handler));
1156#endif
1157}
1158
1159static void MagickSignalHandler(int signal_number)
1160{
1161#if !defined(MAGICKCORE_HAVE_SIGACTION)
1162 (void) signal(signal_number,SIG_IGN);
1163#endif
cristyf34a1452009-10-24 22:29:27 +00001164 AsynchronousResourceComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001165 (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
cristy5f03dab2011-02-20 21:55:17 +00001166#if defined(SIGQUIT)
1167 if (signal_number == SIGQUIT)
1168 abort();
1169#endif
1170#if defined(SIGABRT)
1171 if (signal_number == SIGABRT)
1172 abort();
1173#endif
1174#if defined(SIGFPE)
1175 if (signal_number == SIGFPE)
1176 abort();
1177#endif
1178#if defined(SIGXCPU)
1179 if (signal_number == SIGXCPU)
1180 abort();
1181#endif
1182#if defined(SIGXFSZ)
1183 if (signal_number == SIGXFSZ)
1184 abort();
1185#endif
cristy32a348b2011-04-22 16:03:42 +00001186#if defined(SIGSEGV)
1187 if (signal_number == SIGSEGV)
cristy7ae29582011-04-21 16:10:06 +00001188 abort();
1189#endif
cristy3ed852e2009-09-05 21:47:34 +00001190#if !defined(MAGICKCORE_HAVE__EXIT)
1191 exit(signal_number);
1192#else
1193#if defined(SIGHUP)
1194 if (signal_number == SIGHUP)
1195 exit(signal_number);
1196#endif
cristy0157aea2010-04-24 21:12:18 +00001197#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001198 if (signal_number == SIGINT)
1199 exit(signal_number);
1200#endif
1201#if defined(SIGTERM)
1202 if (signal_number == SIGTERM)
1203 exit(signal_number);
1204#endif
cristyad9c7d02013-01-08 02:03:52 +00001205#if defined(MAGICKCORE_HAVE_RAISE)
1206 if (signal_handlers[signal_number] != MagickSignalHandler)
1207 raise(signal_number);
1208#endif
cristy70bda3d2011-02-20 21:58:06 +00001209 _exit(signal_number); /* do not invoke registered atexit() methods */
cristy3ed852e2009-09-05 21:47:34 +00001210#endif
1211}
1212
1213static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1214{
1215 SignalHandler
1216 *handler;
1217
1218 handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1219 if (handler == SIG_ERR)
1220 return(handler);
1221 if (handler != SIG_DFL)
1222 handler=SetMagickSignalHandler(signal_number,handler);
1223 else
1224 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1225 "Register handler for signal: %d",signal_number);
1226 return(handler);
1227}
1228
1229MagickExport void MagickCoreGenesis(const char *path,
1230 const MagickBooleanType establish_signal_handlers)
1231{
1232 char
1233 *events,
1234 execution_path[MaxTextExtent],
1235 filename[MaxTextExtent];
1236
cristy3ed852e2009-09-05 21:47:34 +00001237 /*
1238 Initialize the Magick environment.
1239 */
cristy1ea02a32014-01-24 11:23:14 +00001240 InitializeMagickMutex();
cristyd1ebf4a2010-05-13 01:54:31 +00001241 LockMagickMutex();
1242 if (instantiate_magickcore != MagickFalse)
1243 {
1244 UnlockMagickMutex();
1245 return;
1246 }
cristyf34a1452009-10-24 22:29:27 +00001247 (void) SemaphoreComponentGenesis();
1248 (void) LogComponentGenesis();
1249 (void) LocaleComponentGenesis();
1250 (void) RandomComponentGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001251 events=GetEnvironmentValue("MAGICK_DEBUG");
1252 if (events != (char *) NULL)
1253 {
1254 (void) SetLogEventMask(events);
1255 events=DestroyString(events);
1256 }
cristy0157aea2010-04-24 21:12:18 +00001257#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy9f3b4fc2014-02-08 14:56:20 +00001258 NTWindowsGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001259#endif
1260 /*
1261 Set client name and execution path.
1262 */
1263 (void) GetExecutionPath(execution_path,MaxTextExtent);
cristy695e8c32011-11-09 18:27:04 +00001264 if ((path != (const char *) NULL) && (*path == *DirectorySeparator) &&
cristy905e5302011-11-09 18:08:43 +00001265 (IsPathAccessible(path) != MagickFalse))
cristy3ed852e2009-09-05 21:47:34 +00001266 (void) CopyMagickString(execution_path,path,MaxTextExtent);
1267 GetPathComponent(execution_path,TailPath,filename);
1268 (void) SetClientName(filename);
1269 GetPathComponent(execution_path,HeadPath,execution_path);
1270 (void) SetClientPath(execution_path);
1271 if (establish_signal_handlers != MagickFalse)
1272 {
1273 /*
1274 Set signal handlers.
1275 */
1276#if defined(SIGABRT)
1277 if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1278 signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1279#endif
cristy32a348b2011-04-22 16:03:42 +00001280#if defined(SIGSEGV)
1281 if (signal_handlers[SIGSEGV] == (SignalHandler *) NULL)
1282 signal_handlers[SIGSEGV]=RegisterMagickSignalHandler(SIGSEGV);
cristy7ae29582011-04-21 16:10:06 +00001283#endif
cristy3ed852e2009-09-05 21:47:34 +00001284#if defined(SIGFPE)
1285 if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1286 signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1287#endif
1288#if defined(SIGHUP)
1289 if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1290 signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1291#endif
cristy0157aea2010-04-24 21:12:18 +00001292#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001293 if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1294 signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1295#endif
1296#if defined(SIGQUIT)
1297 if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1298 signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1299#endif
1300#if defined(SIGTERM)
1301 if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1302 signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1303#endif
1304#if defined(SIGXCPU)
1305 if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1306 signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1307#endif
1308#if defined(SIGXFSZ)
1309 if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1310 signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1311#endif
1312 }
1313 /*
cristyaf8b5cd2009-10-24 00:29:23 +00001314 Instantiate magick resources.
cristy3ed852e2009-09-05 21:47:34 +00001315 */
cristy18b17442009-10-25 18:36:48 +00001316 (void) ConfigureComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001317 (void) PolicyComponentGenesis();
1318 (void) CacheComponentGenesis();
1319 (void) RegistryComponentGenesis();
1320 (void) ResourceComponentGenesis();
1321 (void) CoderComponentGenesis();
1322 (void) MagickComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001323#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001324 (void) ModuleComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001325#endif
cristyf34a1452009-10-24 22:29:27 +00001326 (void) DelegateComponentGenesis();
1327 (void) MagicComponentGenesis();
1328 (void) ColorComponentGenesis();
1329 (void) TypeComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001330 (void) MimeComponentGenesis();
1331 (void) ConstituteComponentGenesis();
cristyd7ecaca2011-01-24 14:14:53 +00001332 (void) AnnotateComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001333#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001334 (void) XComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001335#endif
cristyd1ebf4a2010-05-13 01:54:31 +00001336 instantiate_magickcore=MagickTrue;
1337 UnlockMagickMutex();
cristy3ed852e2009-09-05 21:47:34 +00001338}
1339
1340/*
1341%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1342% %
1343% %
1344% %
1345% M a g i c k C o r e T e r m i n u s %
1346% %
1347% %
1348% %
1349%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1350%
1351% MagickCoreTerminus() destroys the MagickCore environment.
1352%
cristyf34a1452009-10-24 22:29:27 +00001353% The format of the MagickCoreTerminus function is:
cristy3ed852e2009-09-05 21:47:34 +00001354%
1355% MagickCoreTerminus(void)
1356%
1357*/
1358MagickExport void MagickCoreTerminus(void)
1359{
cristy1ea02a32014-01-24 11:23:14 +00001360 InitializeMagickMutex();
cristyd1ebf4a2010-05-13 01:54:31 +00001361 LockMagickMutex();
1362 if (instantiate_magickcore == MagickFalse)
1363 {
1364 UnlockMagickMutex();
1365 return;
1366 }
cristy3ed852e2009-09-05 21:47:34 +00001367#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001368 XComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001369#endif
cristyd7ecaca2011-01-24 14:14:53 +00001370 AnnotateComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001371 ConstituteComponentTerminus();
1372 MimeComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001373 TypeComponentTerminus();
1374 ColorComponentTerminus();
cristy0157aea2010-04-24 21:12:18 +00001375#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001376 NTGhostscriptUnLoadDLL();
1377#endif
cristyf34a1452009-10-24 22:29:27 +00001378 MagicComponentTerminus();
1379 DelegateComponentTerminus();
1380 MagickComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001381#if !defined(MAGICKCORE_BUILD_MODULES)
1382 UnregisterStaticModules();
1383#endif
1384#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001385 ModuleComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001386#endif
cristyf34a1452009-10-24 22:29:27 +00001387 CoderComponentTerminus();
1388 ResourceComponentTerminus();
1389 RegistryComponentTerminus();
1390 CacheComponentTerminus();
1391 PolicyComponentTerminus();
cristy18b17442009-10-25 18:36:48 +00001392 ConfigureComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001393 RandomComponentTerminus();
1394 LocaleComponentTerminus();
1395 LogComponentTerminus();
1396 SemaphoreComponentTerminus();
cristyd1ebf4a2010-05-13 01:54:31 +00001397 instantiate_magickcore=MagickFalse;
1398 UnlockMagickMutex();
cristy1ea02a32014-01-24 11:23:14 +00001399 DestroyMagickMutex();
cristy3ed852e2009-09-05 21:47:34 +00001400}
1401
1402/*
1403%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1404% %
1405% %
1406% %
1407+ R e g i s t e r M a g i c k I n f o %
1408% %
1409% %
1410% %
1411%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1412%
1413% RegisterMagickInfo() adds attributes for a particular image format to the
1414% list of supported formats. The attributes include the image format name,
1415% a method to read and/or write the format, whether the format supports the
1416% saving of more than one frame to the same file or blob, whether the format
1417% supports native in-memory I/O, and a brief description of the format.
1418%
1419% The format of the RegisterMagickInfo method is:
1420%
1421% MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1422%
1423% A description of each parameter follows:
1424%
1425% o magick_info: the magick info.
1426%
1427*/
1428MagickExport MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1429{
1430 MagickBooleanType
1431 status;
1432
1433 /*
1434 Delete any existing name.
1435 */
1436 assert(magick_info != (MagickInfo *) NULL);
1437 assert(magick_info->signature == MagickSignature);
1438 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
1439 if (magick_list == (SplayTreeInfo *) NULL)
1440 return((MagickInfo *) NULL);
1441 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1442 if (status == MagickFalse)
1443 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1444 return(magick_info);
1445}
1446
1447/*
1448%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1449% %
1450% %
1451% %
1452+ S e t M a g i c k I n f o %
1453% %
1454% %
1455% %
1456%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1457%
1458% SetMagickInfo() allocates a MagickInfo structure and initializes the members
1459% to default values.
1460%
1461% The format of the SetMagickInfo method is:
1462%
1463% MagickInfo *SetMagickInfo(const char *name)
1464%
1465% A description of each parameter follows:
1466%
1467% o magick_info: Method SetMagickInfo returns the allocated and initialized
1468% MagickInfo structure.
1469%
1470% o name: a character string that represents the image format associated
1471% with the MagickInfo structure.
1472%
1473*/
1474MagickExport MagickInfo *SetMagickInfo(const char *name)
1475{
1476 MagickInfo
1477 *magick_info;
1478
1479 assert(name != (const char *) NULL);
1480 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
cristy73bd4a52010-10-05 11:24:23 +00001481 magick_info=(MagickInfo *) AcquireMagickMemory(sizeof(*magick_info));
cristy3ed852e2009-09-05 21:47:34 +00001482 if (magick_info == (MagickInfo *) NULL)
1483 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1484 (void) ResetMagickMemory(magick_info,0,sizeof(*magick_info));
1485 magick_info->name=ConstantString(name);
1486 magick_info->adjoin=MagickTrue;
1487 magick_info->blob_support=MagickTrue;
1488 magick_info->thread_support=(MagickStatusType) (DecoderThreadSupport |
1489 EncoderThreadSupport);
1490 magick_info->signature=MagickSignature;
1491 return(magick_info);
1492}
1493
1494/*
1495%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1496% %
1497% %
1498% %
cristye7f51092010-01-17 00:39:37 +00001499% S e t M a g i c k P r e c i s i o n %
1500% %
1501% %
1502% %
1503%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1504%
1505% SetMagickPrecision() sets the maximum number of significant digits to be
anthonybc6fc132012-01-16 07:02:46 +00001506% printed.
1507%
1508% An input argument of 0 returns the current precision setting.
1509%
cristyabdd5b72012-01-18 03:02:15 +00001510% A negative value forces the precision to reset to a default value according
1511% to the environment variable "MAGICK_PRECISION", the current 'policy'
1512% configuration setting, or the default value of '6', in that order.
cristye7f51092010-01-17 00:39:37 +00001513%
1514% The format of the SetMagickPrecision method is:
1515%
cristybf2766a2010-01-17 03:33:23 +00001516% int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001517%
1518% A description of each parameter follows:
1519%
1520% o precision: set the maximum number of significant digits to be printed.
1521%
1522*/
cristybf2766a2010-01-17 03:33:23 +00001523MagickExport int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001524{
anthonybc6fc132012-01-16 07:02:46 +00001525#define MagickPrecision 6
1526
cristybf2766a2010-01-17 03:33:23 +00001527 static int
1528 magick_precision = 0;
1529
cristye7f51092010-01-17 00:39:37 +00001530 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
anthony82c09922012-01-16 06:38:16 +00001531 if (precision > 0)
cristyabdd5b72012-01-18 03:02:15 +00001532 magick_precision=precision;
1533 if ((precision < 0) || (magick_precision == 0))
anthonybc6fc132012-01-16 07:02:46 +00001534 {
1535 char
1536 *limit;
1537
1538 /*
cristyabdd5b72012-01-18 03:02:15 +00001539 Precision reset, or it has not been set yet
anthonybc6fc132012-01-16 07:02:46 +00001540 */
1541 magick_precision = MagickPrecision;
1542 limit=GetEnvironmentValue("MAGICK_PRECISION");
1543 if (limit == (char *) NULL)
1544 limit=GetPolicyValue("precision");
1545 if (limit != (char *) NULL)
1546 {
cristyabdd5b72012-01-18 03:02:15 +00001547 magick_precision=StringToInteger(limit);
anthonybc6fc132012-01-16 07:02:46 +00001548 limit=DestroyString(limit);
1549 }
1550 }
cristybf2766a2010-01-17 03:33:23 +00001551 return(magick_precision);
cristye7f51092010-01-17 00:39:37 +00001552}
1553
1554/*
1555%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1556% %
1557% %
1558% %
cristy3ed852e2009-09-05 21:47:34 +00001559+ U n r e g i s t e r M a g i c k I n f o %
1560% %
1561% %
1562% %
1563%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1564%
1565% UnregisterMagickInfo() removes a name from the magick info list. It returns
1566% MagickFalse if the name does not exist in the list otherwise MagickTrue.
1567%
1568% The format of the UnregisterMagickInfo method is:
1569%
1570% MagickBooleanType UnregisterMagickInfo(const char *name)
1571%
1572% A description of each parameter follows:
1573%
1574% o name: a character string that represents the image format we are
1575% looking for.
1576%
1577*/
1578MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1579{
1580 register const MagickInfo
1581 *p;
1582
1583 MagickBooleanType
1584 status;
1585
1586 assert(name != (const char *) NULL);
1587 if (magick_list == (SplayTreeInfo *) NULL)
1588 return(MagickFalse);
1589 if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1590 return(MagickFalse);
cristyf84a1932010-01-03 18:00:18 +00001591 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001592 ResetSplayTreeIterator(magick_list);
1593 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1594 while (p != (const MagickInfo *) NULL)
1595 {
1596 if (LocaleCompare(p->name,name) == 0)
1597 break;
1598 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1599 }
1600 status=DeleteNodeByValueFromSplayTree(magick_list,p);
cristyf84a1932010-01-03 18:00:18 +00001601 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001602 return(status);
1603}