blob: fa823f1ef1f19148fd505215ac5e2f63e93037ba [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);
cristy86e5ac92014-03-16 19:27:39 +0000417#if defined(MAGICKCORE_MODULES_SUPPORT)
418 if ((name != (const char *) NULL) && (LocaleCompare(name,"*") == 0))
419 (void) OpenModules(exception);
420#endif
cristy3ed852e2009-09-05 21:47:34 +0000421 /*
422 Find name in list.
423 */
cristyf84a1932010-01-03 18:00:18 +0000424 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000425 ResetSplayTreeIterator(magick_list);
426 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
cristy49d4d222014-03-16 00:37:58 +0000427 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
428 {
cristy49d4d222014-03-16 00:37:58 +0000429 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_list == (SplayTreeInfo *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000841 {
cristy86e5ac92014-03-16 19:27:39 +0000842 if (magick_semaphore == (SemaphoreInfo *) NULL)
843 ActivateSemaphoreInfo(&magick_semaphore);
844 LockSemaphoreInfo(magick_semaphore);
cristy1460f262014-03-15 17:38:05 +0000845 if (magick_list == (SplayTreeInfo *) NULL)
cristy86e5ac92014-03-16 19:27:39 +0000846 {
847 MagickBooleanType
848 status;
849
850 MagickInfo
851 *magick_info;
852
853 magick_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *))
854 NULL, DestroyMagickNode);
855 if (magick_list == (SplayTreeInfo *) NULL)
856 ThrowFatalException(ResourceLimitFatalError,
857 "MemoryAllocationFailed");
858 magick_info=SetMagickInfo("ephemeral");
859 magick_info->stealth=MagickTrue;
860 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
861 if (status == MagickFalse)
862 ThrowFatalException(ResourceLimitFatalError,
863 "MemoryAllocationFailed");
864 magick_info=SetMagickInfo("clipmask");
865 magick_info->stealth=MagickTrue;
866 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
867 if (status == MagickFalse)
868 ThrowFatalException(ResourceLimitFatalError,
869 "MemoryAllocationFailed");
cristy3ed852e2009-09-05 21:47:34 +0000870#if defined(MAGICKCORE_MODULES_SUPPORT)
cristy86e5ac92014-03-16 19:27:39 +0000871 (void) GetModuleInfo((char *) NULL,exception);
cristy3ed852e2009-09-05 21:47:34 +0000872#endif
873#if !defined(MAGICKCORE_BUILD_MODULES)
cristy86e5ac92014-03-16 19:27:39 +0000874 RegisterStaticModules();
cristy3ed852e2009-09-05 21:47:34 +0000875#endif
cristy86e5ac92014-03-16 19:27:39 +0000876 }
877 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000878 }
879 return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
880}
881
882/*
883%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
884% %
885% %
886% %
887+ I s M a g i c k C o n f l i c t %
888% %
889% %
890% %
891%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
892%
cristy05a9a622010-03-15 17:26:04 +0000893% IsMagickConflict() returns MagickTrue if the image format conflicts with a
894% logical drive (.e.g. X:).
cristy3ed852e2009-09-05 21:47:34 +0000895%
896% The format of the IsMagickConflict method is:
897%
898% MagickBooleanType IsMagickConflict(const char *magick)
899%
900% A description of each parameter follows:
901%
902% o magick: Specifies the image format.
903%
904*/
cristy7832dc22011-09-05 01:21:53 +0000905MagickPrivate MagickBooleanType IsMagickConflict(const char *magick)
cristy3ed852e2009-09-05 21:47:34 +0000906{
cristy3ed852e2009-09-05 21:47:34 +0000907 assert(magick != (char *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000908#if defined(macintosh)
909 return(MACIsMagickConflict(magick));
910#elif defined(vms)
911 return(VMSIsMagickConflict(magick));
cristy0157aea2010-04-24 21:12:18 +0000912#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000913 return(NTIsMagickConflict(magick));
914#else
915 return(MagickFalse);
916#endif
917}
918
919/*
920%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
921% %
922% %
923% %
924+ L i s t M a g i c k I n f o %
925% %
926% %
927% %
928%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
929%
930% ListMagickInfo() lists the image formats to a file.
931%
932% The format of the ListMagickInfo method is:
933%
934% MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
935%
936% A description of each parameter follows.
937%
938% o file: A file handle.
939%
940% o exception: return any errors or warnings in this structure.
941%
942*/
943MagickExport MagickBooleanType ListMagickInfo(FILE *file,
944 ExceptionInfo *exception)
945{
946 const MagickInfo
947 **magick_info;
948
cristybb503372010-05-27 20:51:26 +0000949 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000950 i;
951
cristybb503372010-05-27 20:51:26 +0000952 size_t
cristy3ed852e2009-09-05 21:47:34 +0000953 number_formats;
954
cristy9d314ff2011-03-09 01:30:28 +0000955 ssize_t
956 j;
957
cristy3ed852e2009-09-05 21:47:34 +0000958 if (file == (FILE *) NULL)
959 file=stdout;
960 magick_info=GetMagickInfoList("*",&number_formats,exception);
961 if (magick_info == (const MagickInfo **) NULL)
962 return(MagickFalse);
963 ClearMagickException(exception);
964#if !defined(MAGICKCORE_MODULES_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000965 (void) FormatLocaleFile(file," Format Mode Description\n");
cristy3ed852e2009-09-05 21:47:34 +0000966#else
cristyb51dff52011-05-19 16:55:47 +0000967 (void) FormatLocaleFile(file," Format Module Mode Description\n");
cristy3ed852e2009-09-05 21:47:34 +0000968#endif
cristy1e604812011-05-19 18:07:50 +0000969 (void) FormatLocaleFile(file,
970 "--------------------------------------------------------"
cristy3ed852e2009-09-05 21:47:34 +0000971 "-----------------------\n");
cristybb503372010-05-27 20:51:26 +0000972 for (i=0; i < (ssize_t) number_formats; i++)
cristy3ed852e2009-09-05 21:47:34 +0000973 {
974 if (magick_info[i]->stealth != MagickFalse)
975 continue;
cristy1e604812011-05-19 18:07:50 +0000976 (void) FormatLocaleFile(file,"%9s%c ",
977 magick_info[i]->name != (char *) NULL ? magick_info[i]->name : "",
cristy3ed852e2009-09-05 21:47:34 +0000978 magick_info[i]->blob_support != MagickFalse ? '*' : ' ');
979#if defined(MAGICKCORE_MODULES_SUPPORT)
980 {
981 char
982 module[MaxTextExtent];
983
984 *module='\0';
985 if (magick_info[i]->module != (char *) NULL)
986 (void) CopyMagickString(module,magick_info[i]->module,MaxTextExtent);
987 (void) ConcatenateMagickString(module," ",MaxTextExtent);
988 module[9]='\0';
cristyb51dff52011-05-19 16:55:47 +0000989 (void) FormatLocaleFile(file,"%9s ",module);
cristy3ed852e2009-09-05 21:47:34 +0000990 }
991#endif
cristyb51dff52011-05-19 16:55:47 +0000992 (void) FormatLocaleFile(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
cristy3ed852e2009-09-05 21:47:34 +0000993 magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
994 magick_info[i]->adjoin != MagickFalse ? '+' : '-');
995 if (magick_info[i]->description != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +0000996 (void) FormatLocaleFile(file," %s",magick_info[i]->description);
cristy3ed852e2009-09-05 21:47:34 +0000997 if (magick_info[i]->version != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +0000998 (void) FormatLocaleFile(file," (%s)",magick_info[i]->version);
999 (void) FormatLocaleFile(file,"\n");
cristy3ed852e2009-09-05 21:47:34 +00001000 if (magick_info[i]->note != (char *) NULL)
1001 {
1002 char
1003 **text;
1004
1005 text=StringToList(magick_info[i]->note);
1006 if (text != (char **) NULL)
1007 {
1008 for (j=0; text[j] != (char *) NULL; j++)
1009 {
cristyb51dff52011-05-19 16:55:47 +00001010 (void) FormatLocaleFile(file," %s\n",text[j]);
cristy3ed852e2009-09-05 21:47:34 +00001011 text[j]=DestroyString(text[j]);
1012 }
1013 text=(char **) RelinquishMagickMemory(text);
1014 }
1015 }
1016 }
cristyb51dff52011-05-19 16:55:47 +00001017 (void) FormatLocaleFile(file,"\n* native blob support\n");
1018 (void) FormatLocaleFile(file,"r read support\n");
1019 (void) FormatLocaleFile(file,"w write support\n");
1020 (void) FormatLocaleFile(file,"+ support for multiple images\n");
cristy3ed852e2009-09-05 21:47:34 +00001021 (void) fflush(file);
1022 magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1023 magick_info);
1024 return(MagickTrue);
1025}
1026
1027/*
1028%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1029% %
1030% %
1031% %
cristy019459e2014-01-02 23:47:13 +00001032% 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 +00001033% %
1034% %
1035% %
1036%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1037%
cristy019459e2014-01-02 23:47:13 +00001038% IsMagickCoreInstantiated() returns MagickTrue if the ImageMagick environment
cristy3ed852e2009-09-05 21:47:34 +00001039% is currently instantiated: MagickCoreGenesis() has been called but
1040% MagickDestroy() has not.
1041%
cristy019459e2014-01-02 23:47:13 +00001042% The format of the IsMagickCoreInstantiated method is:
cristy3ed852e2009-09-05 21:47:34 +00001043%
cristy019459e2014-01-02 23:47:13 +00001044% MagickBooleanType IsMagickCoreInstantiated(void)
cristy3ed852e2009-09-05 21:47:34 +00001045%
1046*/
cristy019459e2014-01-02 23:47:13 +00001047MagickExport MagickBooleanType IsMagickCoreInstantiated(void)
cristy3ed852e2009-09-05 21:47:34 +00001048{
cristy0f86a122014-01-03 18:15:50 +00001049 return(instantiate_magickcore);
cristy3ed852e2009-09-05 21:47:34 +00001050}
1051
1052/*
1053%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1054% %
1055% %
1056% %
cristyf34a1452009-10-24 22:29:27 +00001057+ M a g i c k C o m p o n e n t G e n e s i s %
1058% %
1059% %
1060% %
1061%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1062%
1063% MagickComponentGenesis() instantiates the magick component.
1064%
1065% The format of the MagickComponentGenesis method is:
1066%
1067% MagickBooleanType MagickComponentGenesis(void)
1068%
1069*/
cristy5ff4eaf2011-09-03 01:38:02 +00001070MagickPrivate MagickBooleanType MagickComponentGenesis(void)
cristyf34a1452009-10-24 22:29:27 +00001071{
cristy3d162a92014-02-16 14:05:06 +00001072 magick_semaphore=AcquireSemaphoreInfo();
cristyf34a1452009-10-24 22:29:27 +00001073 return(MagickTrue);
1074}
1075
1076/*
1077%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1078% %
1079% %
1080% %
1081+ M a g i c k C o m p o n e n t T e r m i n u s %
1082% %
1083% %
1084% %
1085%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1086%
1087% MagickComponentTerminus() destroys the magick component.
1088%
1089% The format of the MagickComponentTerminus method is:
1090%
1091% void MagickComponentTerminus(void)
1092%
1093*/
cristy5ff4eaf2011-09-03 01:38:02 +00001094MagickPrivate void MagickComponentTerminus(void)
cristyf34a1452009-10-24 22:29:27 +00001095{
cristy18b17442009-10-25 18:36:48 +00001096 if (magick_semaphore == (SemaphoreInfo *) NULL)
cristy04b11db2014-02-16 15:10:39 +00001097 ActivateSemaphoreInfo(&magick_semaphore);
cristyf84a1932010-01-03 18:00:18 +00001098 LockSemaphoreInfo(magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001099 if (magick_list != (SplayTreeInfo *) NULL)
1100 magick_list=DestroySplayTree(magick_list);
cristyf84a1932010-01-03 18:00:18 +00001101 UnlockSemaphoreInfo(magick_semaphore);
cristy3d162a92014-02-16 14:05:06 +00001102 RelinquishSemaphoreInfo(&magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001103}
1104
1105/*
1106%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1107% %
1108% %
1109% %
cristy3ed852e2009-09-05 21:47:34 +00001110% M a g i c k C o r e G e n e s i s %
1111% %
1112% %
1113% %
1114%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1115%
1116% MagickCoreGenesis() initializes the MagickCore environment.
1117%
1118% The format of the MagickCoreGenesis function is:
1119%
1120% MagickCoreGenesis(const char *path,
1121% const MagickBooleanType establish_signal_handlers)
1122%
1123% A description of each parameter follows:
1124%
1125% o path: the execution path of the current ImageMagick client.
1126%
1127% o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1128% signal handlers for common signals.
1129%
1130*/
1131
1132static SignalHandler *SetMagickSignalHandler(int signal_number,
1133 SignalHandler *handler)
1134{
1135#if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1136 int
1137 status;
1138
1139 sigset_t
1140 mask;
1141
1142 struct sigaction
1143 action,
1144 previous_action;
1145
1146 sigemptyset(&mask);
1147 sigaddset(&mask,signal_number);
1148 sigprocmask(SIG_BLOCK,&mask,NULL);
1149 action.sa_mask=mask;
1150 action.sa_handler=handler;
1151 action.sa_flags=0;
1152#if defined(SA_INTERRUPT)
1153 action.sa_flags|=SA_INTERRUPT;
1154#endif
1155 status=sigaction(signal_number,&action,&previous_action);
1156 if (status < 0)
1157 return(SIG_ERR);
1158 sigprocmask(SIG_UNBLOCK,&mask,NULL);
1159 return(previous_action.sa_handler);
1160#else
1161 return(signal(signal_number,handler));
1162#endif
1163}
1164
1165static void MagickSignalHandler(int signal_number)
1166{
1167#if !defined(MAGICKCORE_HAVE_SIGACTION)
1168 (void) signal(signal_number,SIG_IGN);
1169#endif
cristyf34a1452009-10-24 22:29:27 +00001170 AsynchronousResourceComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001171 (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
cristy5f03dab2011-02-20 21:55:17 +00001172#if defined(SIGQUIT)
1173 if (signal_number == SIGQUIT)
1174 abort();
1175#endif
1176#if defined(SIGABRT)
1177 if (signal_number == SIGABRT)
1178 abort();
1179#endif
1180#if defined(SIGFPE)
1181 if (signal_number == SIGFPE)
1182 abort();
1183#endif
1184#if defined(SIGXCPU)
1185 if (signal_number == SIGXCPU)
1186 abort();
1187#endif
1188#if defined(SIGXFSZ)
1189 if (signal_number == SIGXFSZ)
1190 abort();
1191#endif
cristy32a348b2011-04-22 16:03:42 +00001192#if defined(SIGSEGV)
1193 if (signal_number == SIGSEGV)
cristy7ae29582011-04-21 16:10:06 +00001194 abort();
1195#endif
cristy3ed852e2009-09-05 21:47:34 +00001196#if !defined(MAGICKCORE_HAVE__EXIT)
1197 exit(signal_number);
1198#else
1199#if defined(SIGHUP)
1200 if (signal_number == SIGHUP)
1201 exit(signal_number);
1202#endif
cristy0157aea2010-04-24 21:12:18 +00001203#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001204 if (signal_number == SIGINT)
1205 exit(signal_number);
1206#endif
1207#if defined(SIGTERM)
1208 if (signal_number == SIGTERM)
1209 exit(signal_number);
1210#endif
cristyad9c7d02013-01-08 02:03:52 +00001211#if defined(MAGICKCORE_HAVE_RAISE)
1212 if (signal_handlers[signal_number] != MagickSignalHandler)
1213 raise(signal_number);
1214#endif
cristy70bda3d2011-02-20 21:58:06 +00001215 _exit(signal_number); /* do not invoke registered atexit() methods */
cristy3ed852e2009-09-05 21:47:34 +00001216#endif
1217}
1218
1219static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1220{
1221 SignalHandler
1222 *handler;
1223
1224 handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1225 if (handler == SIG_ERR)
1226 return(handler);
1227 if (handler != SIG_DFL)
1228 handler=SetMagickSignalHandler(signal_number,handler);
1229 else
1230 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1231 "Register handler for signal: %d",signal_number);
1232 return(handler);
1233}
1234
1235MagickExport void MagickCoreGenesis(const char *path,
1236 const MagickBooleanType establish_signal_handlers)
1237{
1238 char
1239 *events,
1240 execution_path[MaxTextExtent],
1241 filename[MaxTextExtent];
1242
cristy3ed852e2009-09-05 21:47:34 +00001243 /*
1244 Initialize the Magick environment.
1245 */
cristy1ea02a32014-01-24 11:23:14 +00001246 InitializeMagickMutex();
cristyd1ebf4a2010-05-13 01:54:31 +00001247 LockMagickMutex();
1248 if (instantiate_magickcore != MagickFalse)
1249 {
1250 UnlockMagickMutex();
1251 return;
1252 }
cristyf34a1452009-10-24 22:29:27 +00001253 (void) SemaphoreComponentGenesis();
1254 (void) LogComponentGenesis();
1255 (void) LocaleComponentGenesis();
1256 (void) RandomComponentGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001257 events=GetEnvironmentValue("MAGICK_DEBUG");
1258 if (events != (char *) NULL)
1259 {
1260 (void) SetLogEventMask(events);
1261 events=DestroyString(events);
1262 }
cristy0157aea2010-04-24 21:12:18 +00001263#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy9f3b4fc2014-02-08 14:56:20 +00001264 NTWindowsGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001265#endif
1266 /*
1267 Set client name and execution path.
1268 */
1269 (void) GetExecutionPath(execution_path,MaxTextExtent);
cristy695e8c32011-11-09 18:27:04 +00001270 if ((path != (const char *) NULL) && (*path == *DirectorySeparator) &&
cristy905e5302011-11-09 18:08:43 +00001271 (IsPathAccessible(path) != MagickFalse))
cristy3ed852e2009-09-05 21:47:34 +00001272 (void) CopyMagickString(execution_path,path,MaxTextExtent);
1273 GetPathComponent(execution_path,TailPath,filename);
1274 (void) SetClientName(filename);
1275 GetPathComponent(execution_path,HeadPath,execution_path);
1276 (void) SetClientPath(execution_path);
1277 if (establish_signal_handlers != MagickFalse)
1278 {
1279 /*
1280 Set signal handlers.
1281 */
1282#if defined(SIGABRT)
1283 if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1284 signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1285#endif
cristy32a348b2011-04-22 16:03:42 +00001286#if defined(SIGSEGV)
1287 if (signal_handlers[SIGSEGV] == (SignalHandler *) NULL)
1288 signal_handlers[SIGSEGV]=RegisterMagickSignalHandler(SIGSEGV);
cristy7ae29582011-04-21 16:10:06 +00001289#endif
cristy3ed852e2009-09-05 21:47:34 +00001290#if defined(SIGFPE)
1291 if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1292 signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1293#endif
1294#if defined(SIGHUP)
1295 if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1296 signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1297#endif
cristy0157aea2010-04-24 21:12:18 +00001298#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001299 if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1300 signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1301#endif
1302#if defined(SIGQUIT)
1303 if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1304 signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1305#endif
1306#if defined(SIGTERM)
1307 if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1308 signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1309#endif
1310#if defined(SIGXCPU)
1311 if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1312 signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1313#endif
1314#if defined(SIGXFSZ)
1315 if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1316 signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1317#endif
1318 }
1319 /*
cristyaf8b5cd2009-10-24 00:29:23 +00001320 Instantiate magick resources.
cristy3ed852e2009-09-05 21:47:34 +00001321 */
cristy18b17442009-10-25 18:36:48 +00001322 (void) ConfigureComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001323 (void) PolicyComponentGenesis();
1324 (void) CacheComponentGenesis();
1325 (void) RegistryComponentGenesis();
1326 (void) ResourceComponentGenesis();
1327 (void) CoderComponentGenesis();
1328 (void) MagickComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001329#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001330 (void) ModuleComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001331#endif
cristyf34a1452009-10-24 22:29:27 +00001332 (void) DelegateComponentGenesis();
1333 (void) MagicComponentGenesis();
1334 (void) ColorComponentGenesis();
1335 (void) TypeComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001336 (void) MimeComponentGenesis();
1337 (void) ConstituteComponentGenesis();
cristyd7ecaca2011-01-24 14:14:53 +00001338 (void) AnnotateComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001339#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001340 (void) XComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001341#endif
cristyd1ebf4a2010-05-13 01:54:31 +00001342 instantiate_magickcore=MagickTrue;
1343 UnlockMagickMutex();
cristy3ed852e2009-09-05 21:47:34 +00001344}
1345
1346/*
1347%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1348% %
1349% %
1350% %
1351% M a g i c k C o r e T e r m i n u s %
1352% %
1353% %
1354% %
1355%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1356%
1357% MagickCoreTerminus() destroys the MagickCore environment.
1358%
cristyf34a1452009-10-24 22:29:27 +00001359% The format of the MagickCoreTerminus function is:
cristy3ed852e2009-09-05 21:47:34 +00001360%
1361% MagickCoreTerminus(void)
1362%
1363*/
1364MagickExport void MagickCoreTerminus(void)
1365{
cristy1ea02a32014-01-24 11:23:14 +00001366 InitializeMagickMutex();
cristyd1ebf4a2010-05-13 01:54:31 +00001367 LockMagickMutex();
1368 if (instantiate_magickcore == MagickFalse)
1369 {
1370 UnlockMagickMutex();
1371 return;
1372 }
cristy3ed852e2009-09-05 21:47:34 +00001373#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001374 XComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001375#endif
cristyd7ecaca2011-01-24 14:14:53 +00001376 AnnotateComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001377 ConstituteComponentTerminus();
1378 MimeComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001379 TypeComponentTerminus();
1380 ColorComponentTerminus();
cristy0157aea2010-04-24 21:12:18 +00001381#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001382 NTGhostscriptUnLoadDLL();
1383#endif
cristyf34a1452009-10-24 22:29:27 +00001384 MagicComponentTerminus();
1385 DelegateComponentTerminus();
1386 MagickComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001387#if !defined(MAGICKCORE_BUILD_MODULES)
1388 UnregisterStaticModules();
1389#endif
1390#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001391 ModuleComponentTerminus();
cristyaf8b5cd2009-10-24 00:29:23 +00001392#endif
cristyf34a1452009-10-24 22:29:27 +00001393 CoderComponentTerminus();
1394 ResourceComponentTerminus();
1395 RegistryComponentTerminus();
1396 CacheComponentTerminus();
1397 PolicyComponentTerminus();
cristy18b17442009-10-25 18:36:48 +00001398 ConfigureComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001399 RandomComponentTerminus();
1400 LocaleComponentTerminus();
1401 LogComponentTerminus();
1402 SemaphoreComponentTerminus();
cristyd1ebf4a2010-05-13 01:54:31 +00001403 instantiate_magickcore=MagickFalse;
1404 UnlockMagickMutex();
cristy1ea02a32014-01-24 11:23:14 +00001405 DestroyMagickMutex();
cristy3ed852e2009-09-05 21:47:34 +00001406}
1407
1408/*
1409%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1410% %
1411% %
1412% %
1413+ R e g i s t e r M a g i c k I n f o %
1414% %
1415% %
1416% %
1417%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1418%
1419% RegisterMagickInfo() adds attributes for a particular image format to the
1420% list of supported formats. The attributes include the image format name,
1421% a method to read and/or write the format, whether the format supports the
1422% saving of more than one frame to the same file or blob, whether the format
1423% supports native in-memory I/O, and a brief description of the format.
1424%
1425% The format of the RegisterMagickInfo method is:
1426%
1427% MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1428%
1429% A description of each parameter follows:
1430%
1431% o magick_info: the magick info.
1432%
1433*/
1434MagickExport MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1435{
1436 MagickBooleanType
1437 status;
1438
1439 /*
1440 Delete any existing name.
1441 */
1442 assert(magick_info != (MagickInfo *) NULL);
1443 assert(magick_info->signature == MagickSignature);
1444 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
1445 if (magick_list == (SplayTreeInfo *) NULL)
1446 return((MagickInfo *) NULL);
1447 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1448 if (status == MagickFalse)
1449 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1450 return(magick_info);
1451}
1452
1453/*
1454%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1455% %
1456% %
1457% %
1458+ S e t M a g i c k I n f o %
1459% %
1460% %
1461% %
1462%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1463%
1464% SetMagickInfo() allocates a MagickInfo structure and initializes the members
1465% to default values.
1466%
1467% The format of the SetMagickInfo method is:
1468%
1469% MagickInfo *SetMagickInfo(const char *name)
1470%
1471% A description of each parameter follows:
1472%
1473% o magick_info: Method SetMagickInfo returns the allocated and initialized
1474% MagickInfo structure.
1475%
1476% o name: a character string that represents the image format associated
1477% with the MagickInfo structure.
1478%
1479*/
1480MagickExport MagickInfo *SetMagickInfo(const char *name)
1481{
1482 MagickInfo
1483 *magick_info;
1484
1485 assert(name != (const char *) NULL);
1486 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
cristy73bd4a52010-10-05 11:24:23 +00001487 magick_info=(MagickInfo *) AcquireMagickMemory(sizeof(*magick_info));
cristy3ed852e2009-09-05 21:47:34 +00001488 if (magick_info == (MagickInfo *) NULL)
1489 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1490 (void) ResetMagickMemory(magick_info,0,sizeof(*magick_info));
1491 magick_info->name=ConstantString(name);
1492 magick_info->adjoin=MagickTrue;
1493 magick_info->blob_support=MagickTrue;
1494 magick_info->thread_support=(MagickStatusType) (DecoderThreadSupport |
1495 EncoderThreadSupport);
1496 magick_info->signature=MagickSignature;
1497 return(magick_info);
1498}
1499
1500/*
1501%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1502% %
1503% %
1504% %
cristye7f51092010-01-17 00:39:37 +00001505% S e t M a g i c k P r e c i s i o n %
1506% %
1507% %
1508% %
1509%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1510%
1511% SetMagickPrecision() sets the maximum number of significant digits to be
anthonybc6fc132012-01-16 07:02:46 +00001512% printed.
1513%
1514% An input argument of 0 returns the current precision setting.
1515%
cristyabdd5b72012-01-18 03:02:15 +00001516% A negative value forces the precision to reset to a default value according
1517% to the environment variable "MAGICK_PRECISION", the current 'policy'
1518% configuration setting, or the default value of '6', in that order.
cristye7f51092010-01-17 00:39:37 +00001519%
1520% The format of the SetMagickPrecision method is:
1521%
cristybf2766a2010-01-17 03:33:23 +00001522% int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001523%
1524% A description of each parameter follows:
1525%
1526% o precision: set the maximum number of significant digits to be printed.
1527%
1528*/
cristybf2766a2010-01-17 03:33:23 +00001529MagickExport int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001530{
anthonybc6fc132012-01-16 07:02:46 +00001531#define MagickPrecision 6
1532
cristybf2766a2010-01-17 03:33:23 +00001533 static int
1534 magick_precision = 0;
1535
cristye7f51092010-01-17 00:39:37 +00001536 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
anthony82c09922012-01-16 06:38:16 +00001537 if (precision > 0)
cristyabdd5b72012-01-18 03:02:15 +00001538 magick_precision=precision;
1539 if ((precision < 0) || (magick_precision == 0))
anthonybc6fc132012-01-16 07:02:46 +00001540 {
1541 char
1542 *limit;
1543
1544 /*
cristyabdd5b72012-01-18 03:02:15 +00001545 Precision reset, or it has not been set yet
anthonybc6fc132012-01-16 07:02:46 +00001546 */
1547 magick_precision = MagickPrecision;
1548 limit=GetEnvironmentValue("MAGICK_PRECISION");
1549 if (limit == (char *) NULL)
1550 limit=GetPolicyValue("precision");
1551 if (limit != (char *) NULL)
1552 {
cristyabdd5b72012-01-18 03:02:15 +00001553 magick_precision=StringToInteger(limit);
anthonybc6fc132012-01-16 07:02:46 +00001554 limit=DestroyString(limit);
1555 }
1556 }
cristybf2766a2010-01-17 03:33:23 +00001557 return(magick_precision);
cristye7f51092010-01-17 00:39:37 +00001558}
1559
1560/*
1561%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1562% %
1563% %
1564% %
cristy3ed852e2009-09-05 21:47:34 +00001565+ U n r e g i s t e r M a g i c k I n f o %
1566% %
1567% %
1568% %
1569%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1570%
1571% UnregisterMagickInfo() removes a name from the magick info list. It returns
1572% MagickFalse if the name does not exist in the list otherwise MagickTrue.
1573%
1574% The format of the UnregisterMagickInfo method is:
1575%
1576% MagickBooleanType UnregisterMagickInfo(const char *name)
1577%
1578% A description of each parameter follows:
1579%
1580% o name: a character string that represents the image format we are
1581% looking for.
1582%
1583*/
1584MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1585{
1586 register const MagickInfo
1587 *p;
1588
1589 MagickBooleanType
1590 status;
1591
1592 assert(name != (const char *) NULL);
1593 if (magick_list == (SplayTreeInfo *) NULL)
1594 return(MagickFalse);
1595 if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1596 return(MagickFalse);
cristyf84a1932010-01-03 18:00:18 +00001597 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001598 ResetSplayTreeIterator(magick_list);
1599 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1600 while (p != (const MagickInfo *) NULL)
1601 {
1602 if (LocaleCompare(p->name,name) == 0)
1603 break;
1604 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1605 }
1606 status=DeleteNodeByValueFromSplayTree(magick_list,p);
cristyf84a1932010-01-03 18:00:18 +00001607 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001608 return(status);
1609}