blob: 61107f39611584189e13320e6e499ff12fc37fd8 [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);
cristy191ba5c2014-03-16 21:26:40 +0000834 if (p->semaphore != (SemaphoreInfo *) NULL)
cristy1d51f832014-03-19 13:20:31 +0000835 RelinquishSemaphoreInfo(&p->semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000836 return(RelinquishMagickMemory(p));
837}
838
cristy904e5912014-03-15 19:53:14 +0000839static MagickBooleanType IsMagickTreeInstantiated(ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000840{
cristyf2e11662009-10-14 01:24:43 +0000841 (void) exception;
cristy1460f262014-03-15 17:38:05 +0000842 if (magick_list == (SplayTreeInfo *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000843 {
cristy86e5ac92014-03-16 19:27:39 +0000844 if (magick_semaphore == (SemaphoreInfo *) NULL)
845 ActivateSemaphoreInfo(&magick_semaphore);
846 LockSemaphoreInfo(magick_semaphore);
cristy1460f262014-03-15 17:38:05 +0000847 if (magick_list == (SplayTreeInfo *) NULL)
cristy86e5ac92014-03-16 19:27:39 +0000848 {
849 MagickBooleanType
850 status;
851
852 MagickInfo
853 *magick_info;
854
855 magick_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *))
856 NULL, DestroyMagickNode);
857 if (magick_list == (SplayTreeInfo *) NULL)
858 ThrowFatalException(ResourceLimitFatalError,
859 "MemoryAllocationFailed");
860 magick_info=SetMagickInfo("ephemeral");
861 magick_info->stealth=MagickTrue;
862 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
863 if (status == MagickFalse)
864 ThrowFatalException(ResourceLimitFatalError,
865 "MemoryAllocationFailed");
866 magick_info=SetMagickInfo("clipmask");
867 magick_info->stealth=MagickTrue;
868 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
869 if (status == MagickFalse)
870 ThrowFatalException(ResourceLimitFatalError,
871 "MemoryAllocationFailed");
cristy3ed852e2009-09-05 21:47:34 +0000872#if defined(MAGICKCORE_MODULES_SUPPORT)
cristy86e5ac92014-03-16 19:27:39 +0000873 (void) GetModuleInfo((char *) NULL,exception);
cristy3ed852e2009-09-05 21:47:34 +0000874#endif
875#if !defined(MAGICKCORE_BUILD_MODULES)
cristy86e5ac92014-03-16 19:27:39 +0000876 RegisterStaticModules();
cristy3ed852e2009-09-05 21:47:34 +0000877#endif
cristy86e5ac92014-03-16 19:27:39 +0000878 }
879 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000880 }
881 return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
882}
883
884/*
885%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
886% %
887% %
888% %
889+ I s M a g i c k C o n f l i c t %
890% %
891% %
892% %
893%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
894%
cristy05a9a622010-03-15 17:26:04 +0000895% IsMagickConflict() returns MagickTrue if the image format conflicts with a
896% logical drive (.e.g. X:).
cristy3ed852e2009-09-05 21:47:34 +0000897%
898% The format of the IsMagickConflict method is:
899%
900% MagickBooleanType IsMagickConflict(const char *magick)
901%
902% A description of each parameter follows:
903%
904% o magick: Specifies the image format.
905%
906*/
cristy7832dc22011-09-05 01:21:53 +0000907MagickPrivate MagickBooleanType IsMagickConflict(const char *magick)
cristy3ed852e2009-09-05 21:47:34 +0000908{
cristy3ed852e2009-09-05 21:47:34 +0000909 assert(magick != (char *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000910#if defined(macintosh)
911 return(MACIsMagickConflict(magick));
912#elif defined(vms)
913 return(VMSIsMagickConflict(magick));
cristy0157aea2010-04-24 21:12:18 +0000914#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +0000915 return(NTIsMagickConflict(magick));
916#else
917 return(MagickFalse);
918#endif
919}
920
921/*
922%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
923% %
924% %
925% %
926+ L i s t M a g i c k I n f o %
927% %
928% %
929% %
930%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
931%
932% ListMagickInfo() lists the image formats to a file.
933%
934% The format of the ListMagickInfo method is:
935%
936% MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
937%
938% A description of each parameter follows.
939%
940% o file: A file handle.
941%
942% o exception: return any errors or warnings in this structure.
943%
944*/
945MagickExport MagickBooleanType ListMagickInfo(FILE *file,
946 ExceptionInfo *exception)
947{
948 const MagickInfo
949 **magick_info;
950
cristybb503372010-05-27 20:51:26 +0000951 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000952 i;
953
cristybb503372010-05-27 20:51:26 +0000954 size_t
cristy3ed852e2009-09-05 21:47:34 +0000955 number_formats;
956
cristy9d314ff2011-03-09 01:30:28 +0000957 ssize_t
958 j;
959
cristy3ed852e2009-09-05 21:47:34 +0000960 if (file == (FILE *) NULL)
961 file=stdout;
962 magick_info=GetMagickInfoList("*",&number_formats,exception);
963 if (magick_info == (const MagickInfo **) NULL)
964 return(MagickFalse);
965 ClearMagickException(exception);
966#if !defined(MAGICKCORE_MODULES_SUPPORT)
cristyb51dff52011-05-19 16:55:47 +0000967 (void) FormatLocaleFile(file," Format Mode Description\n");
cristy3ed852e2009-09-05 21:47:34 +0000968#else
cristyb51dff52011-05-19 16:55:47 +0000969 (void) FormatLocaleFile(file," Format Module Mode Description\n");
cristy3ed852e2009-09-05 21:47:34 +0000970#endif
cristy1e604812011-05-19 18:07:50 +0000971 (void) FormatLocaleFile(file,
972 "--------------------------------------------------------"
cristy3ed852e2009-09-05 21:47:34 +0000973 "-----------------------\n");
cristybb503372010-05-27 20:51:26 +0000974 for (i=0; i < (ssize_t) number_formats; i++)
cristy3ed852e2009-09-05 21:47:34 +0000975 {
976 if (magick_info[i]->stealth != MagickFalse)
977 continue;
cristy1e604812011-05-19 18:07:50 +0000978 (void) FormatLocaleFile(file,"%9s%c ",
979 magick_info[i]->name != (char *) NULL ? magick_info[i]->name : "",
cristy3ed852e2009-09-05 21:47:34 +0000980 magick_info[i]->blob_support != MagickFalse ? '*' : ' ');
981#if defined(MAGICKCORE_MODULES_SUPPORT)
982 {
983 char
984 module[MaxTextExtent];
985
986 *module='\0';
987 if (magick_info[i]->module != (char *) NULL)
988 (void) CopyMagickString(module,magick_info[i]->module,MaxTextExtent);
989 (void) ConcatenateMagickString(module," ",MaxTextExtent);
990 module[9]='\0';
cristyb51dff52011-05-19 16:55:47 +0000991 (void) FormatLocaleFile(file,"%9s ",module);
cristy3ed852e2009-09-05 21:47:34 +0000992 }
993#endif
cristyb51dff52011-05-19 16:55:47 +0000994 (void) FormatLocaleFile(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
cristy3ed852e2009-09-05 21:47:34 +0000995 magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
996 magick_info[i]->adjoin != MagickFalse ? '+' : '-');
997 if (magick_info[i]->description != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +0000998 (void) FormatLocaleFile(file," %s",magick_info[i]->description);
cristy3ed852e2009-09-05 21:47:34 +0000999 if (magick_info[i]->version != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +00001000 (void) FormatLocaleFile(file," (%s)",magick_info[i]->version);
1001 (void) FormatLocaleFile(file,"\n");
cristy3ed852e2009-09-05 21:47:34 +00001002 if (magick_info[i]->note != (char *) NULL)
1003 {
1004 char
1005 **text;
1006
1007 text=StringToList(magick_info[i]->note);
1008 if (text != (char **) NULL)
1009 {
1010 for (j=0; text[j] != (char *) NULL; j++)
1011 {
cristyb51dff52011-05-19 16:55:47 +00001012 (void) FormatLocaleFile(file," %s\n",text[j]);
cristy3ed852e2009-09-05 21:47:34 +00001013 text[j]=DestroyString(text[j]);
1014 }
1015 text=(char **) RelinquishMagickMemory(text);
1016 }
1017 }
1018 }
cristyb51dff52011-05-19 16:55:47 +00001019 (void) FormatLocaleFile(file,"\n* native blob support\n");
1020 (void) FormatLocaleFile(file,"r read support\n");
1021 (void) FormatLocaleFile(file,"w write support\n");
1022 (void) FormatLocaleFile(file,"+ support for multiple images\n");
cristy3ed852e2009-09-05 21:47:34 +00001023 (void) fflush(file);
1024 magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1025 magick_info);
1026 return(MagickTrue);
1027}
1028
1029/*
1030%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1031% %
1032% %
1033% %
cristy019459e2014-01-02 23:47:13 +00001034% 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 +00001035% %
1036% %
1037% %
1038%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1039%
cristy019459e2014-01-02 23:47:13 +00001040% IsMagickCoreInstantiated() returns MagickTrue if the ImageMagick environment
cristy3ed852e2009-09-05 21:47:34 +00001041% is currently instantiated: MagickCoreGenesis() has been called but
1042% MagickDestroy() has not.
1043%
cristy019459e2014-01-02 23:47:13 +00001044% The format of the IsMagickCoreInstantiated method is:
cristy3ed852e2009-09-05 21:47:34 +00001045%
cristy019459e2014-01-02 23:47:13 +00001046% MagickBooleanType IsMagickCoreInstantiated(void)
cristy3ed852e2009-09-05 21:47:34 +00001047%
1048*/
cristy019459e2014-01-02 23:47:13 +00001049MagickExport MagickBooleanType IsMagickCoreInstantiated(void)
cristy3ed852e2009-09-05 21:47:34 +00001050{
cristy0f86a122014-01-03 18:15:50 +00001051 return(instantiate_magickcore);
cristy3ed852e2009-09-05 21:47:34 +00001052}
1053
1054/*
1055%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1056% %
1057% %
1058% %
cristyf34a1452009-10-24 22:29:27 +00001059+ M a g i c k C o m p o n e n t G e n e s i s %
1060% %
1061% %
1062% %
1063%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1064%
1065% MagickComponentGenesis() instantiates the magick component.
1066%
1067% The format of the MagickComponentGenesis method is:
1068%
1069% MagickBooleanType MagickComponentGenesis(void)
1070%
1071*/
cristy5ff4eaf2011-09-03 01:38:02 +00001072MagickPrivate MagickBooleanType MagickComponentGenesis(void)
cristyf34a1452009-10-24 22:29:27 +00001073{
cristy3d162a92014-02-16 14:05:06 +00001074 magick_semaphore=AcquireSemaphoreInfo();
cristyf34a1452009-10-24 22:29:27 +00001075 return(MagickTrue);
1076}
1077
1078/*
1079%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1080% %
1081% %
1082% %
1083+ M a g i c k C o m p o n e n t T e r m i n u s %
1084% %
1085% %
1086% %
1087%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1088%
1089% MagickComponentTerminus() destroys the magick component.
1090%
1091% The format of the MagickComponentTerminus method is:
1092%
1093% void MagickComponentTerminus(void)
1094%
1095*/
cristy5ff4eaf2011-09-03 01:38:02 +00001096MagickPrivate void MagickComponentTerminus(void)
cristyf34a1452009-10-24 22:29:27 +00001097{
cristy18b17442009-10-25 18:36:48 +00001098 if (magick_semaphore == (SemaphoreInfo *) NULL)
cristy04b11db2014-02-16 15:10:39 +00001099 ActivateSemaphoreInfo(&magick_semaphore);
cristyf84a1932010-01-03 18:00:18 +00001100 LockSemaphoreInfo(magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001101 if (magick_list != (SplayTreeInfo *) NULL)
1102 magick_list=DestroySplayTree(magick_list);
cristyf84a1932010-01-03 18:00:18 +00001103 UnlockSemaphoreInfo(magick_semaphore);
cristy3d162a92014-02-16 14:05:06 +00001104 RelinquishSemaphoreInfo(&magick_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001105}
1106
1107/*
1108%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1109% %
1110% %
1111% %
cristy3ed852e2009-09-05 21:47:34 +00001112% M a g i c k C o r e G e n e s i s %
1113% %
1114% %
1115% %
1116%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1117%
1118% MagickCoreGenesis() initializes the MagickCore environment.
1119%
1120% The format of the MagickCoreGenesis function is:
1121%
1122% MagickCoreGenesis(const char *path,
1123% const MagickBooleanType establish_signal_handlers)
1124%
1125% A description of each parameter follows:
1126%
1127% o path: the execution path of the current ImageMagick client.
1128%
1129% o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1130% signal handlers for common signals.
1131%
1132*/
1133
1134static SignalHandler *SetMagickSignalHandler(int signal_number,
1135 SignalHandler *handler)
1136{
1137#if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1138 int
1139 status;
1140
1141 sigset_t
1142 mask;
1143
1144 struct sigaction
1145 action,
1146 previous_action;
1147
1148 sigemptyset(&mask);
1149 sigaddset(&mask,signal_number);
1150 sigprocmask(SIG_BLOCK,&mask,NULL);
1151 action.sa_mask=mask;
1152 action.sa_handler=handler;
1153 action.sa_flags=0;
1154#if defined(SA_INTERRUPT)
1155 action.sa_flags|=SA_INTERRUPT;
1156#endif
1157 status=sigaction(signal_number,&action,&previous_action);
1158 if (status < 0)
1159 return(SIG_ERR);
1160 sigprocmask(SIG_UNBLOCK,&mask,NULL);
1161 return(previous_action.sa_handler);
1162#else
1163 return(signal(signal_number,handler));
1164#endif
1165}
1166
1167static void MagickSignalHandler(int signal_number)
1168{
1169#if !defined(MAGICKCORE_HAVE_SIGACTION)
1170 (void) signal(signal_number,SIG_IGN);
1171#endif
cristyf34a1452009-10-24 22:29:27 +00001172 AsynchronousResourceComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001173 (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
cristy5f03dab2011-02-20 21:55:17 +00001174#if defined(SIGQUIT)
1175 if (signal_number == SIGQUIT)
1176 abort();
1177#endif
1178#if defined(SIGABRT)
1179 if (signal_number == SIGABRT)
1180 abort();
1181#endif
1182#if defined(SIGFPE)
1183 if (signal_number == SIGFPE)
1184 abort();
1185#endif
1186#if defined(SIGXCPU)
1187 if (signal_number == SIGXCPU)
1188 abort();
1189#endif
1190#if defined(SIGXFSZ)
1191 if (signal_number == SIGXFSZ)
1192 abort();
1193#endif
cristy32a348b2011-04-22 16:03:42 +00001194#if defined(SIGSEGV)
1195 if (signal_number == SIGSEGV)
cristy7ae29582011-04-21 16:10:06 +00001196 abort();
1197#endif
cristy3ed852e2009-09-05 21:47:34 +00001198#if !defined(MAGICKCORE_HAVE__EXIT)
1199 exit(signal_number);
1200#else
1201#if defined(SIGHUP)
1202 if (signal_number == SIGHUP)
1203 exit(signal_number);
1204#endif
cristy0157aea2010-04-24 21:12:18 +00001205#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001206 if (signal_number == SIGINT)
1207 exit(signal_number);
1208#endif
1209#if defined(SIGTERM)
1210 if (signal_number == SIGTERM)
1211 exit(signal_number);
1212#endif
cristyad9c7d02013-01-08 02:03:52 +00001213#if defined(MAGICKCORE_HAVE_RAISE)
1214 if (signal_handlers[signal_number] != MagickSignalHandler)
1215 raise(signal_number);
1216#endif
cristy70bda3d2011-02-20 21:58:06 +00001217 _exit(signal_number); /* do not invoke registered atexit() methods */
cristy3ed852e2009-09-05 21:47:34 +00001218#endif
1219}
1220
1221static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1222{
1223 SignalHandler
1224 *handler;
1225
1226 handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1227 if (handler == SIG_ERR)
1228 return(handler);
1229 if (handler != SIG_DFL)
1230 handler=SetMagickSignalHandler(signal_number,handler);
1231 else
1232 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1233 "Register handler for signal: %d",signal_number);
1234 return(handler);
1235}
1236
1237MagickExport void MagickCoreGenesis(const char *path,
1238 const MagickBooleanType establish_signal_handlers)
1239{
1240 char
1241 *events,
1242 execution_path[MaxTextExtent],
1243 filename[MaxTextExtent];
1244
cristy3ed852e2009-09-05 21:47:34 +00001245 /*
1246 Initialize the Magick environment.
1247 */
cristy1ea02a32014-01-24 11:23:14 +00001248 InitializeMagickMutex();
cristyd1ebf4a2010-05-13 01:54:31 +00001249 LockMagickMutex();
1250 if (instantiate_magickcore != MagickFalse)
1251 {
1252 UnlockMagickMutex();
1253 return;
1254 }
cristyf34a1452009-10-24 22:29:27 +00001255 (void) SemaphoreComponentGenesis();
1256 (void) LogComponentGenesis();
1257 (void) LocaleComponentGenesis();
1258 (void) RandomComponentGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001259 events=GetEnvironmentValue("MAGICK_DEBUG");
1260 if (events != (char *) NULL)
1261 {
1262 (void) SetLogEventMask(events);
1263 events=DestroyString(events);
1264 }
cristy0157aea2010-04-24 21:12:18 +00001265#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy9f3b4fc2014-02-08 14:56:20 +00001266 NTWindowsGenesis();
cristy3ed852e2009-09-05 21:47:34 +00001267#endif
1268 /*
1269 Set client name and execution path.
1270 */
1271 (void) GetExecutionPath(execution_path,MaxTextExtent);
cristy695e8c32011-11-09 18:27:04 +00001272 if ((path != (const char *) NULL) && (*path == *DirectorySeparator) &&
cristy905e5302011-11-09 18:08:43 +00001273 (IsPathAccessible(path) != MagickFalse))
cristy3ed852e2009-09-05 21:47:34 +00001274 (void) CopyMagickString(execution_path,path,MaxTextExtent);
1275 GetPathComponent(execution_path,TailPath,filename);
1276 (void) SetClientName(filename);
1277 GetPathComponent(execution_path,HeadPath,execution_path);
1278 (void) SetClientPath(execution_path);
1279 if (establish_signal_handlers != MagickFalse)
1280 {
1281 /*
1282 Set signal handlers.
1283 */
1284#if defined(SIGABRT)
1285 if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1286 signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1287#endif
cristy32a348b2011-04-22 16:03:42 +00001288#if defined(SIGSEGV)
1289 if (signal_handlers[SIGSEGV] == (SignalHandler *) NULL)
1290 signal_handlers[SIGSEGV]=RegisterMagickSignalHandler(SIGSEGV);
cristy7ae29582011-04-21 16:10:06 +00001291#endif
cristy3ed852e2009-09-05 21:47:34 +00001292#if defined(SIGFPE)
1293 if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1294 signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1295#endif
1296#if defined(SIGHUP)
1297 if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1298 signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1299#endif
cristy0157aea2010-04-24 21:12:18 +00001300#if defined(SIGINT) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +00001301 if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1302 signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1303#endif
1304#if defined(SIGQUIT)
1305 if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1306 signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1307#endif
1308#if defined(SIGTERM)
1309 if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1310 signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1311#endif
1312#if defined(SIGXCPU)
1313 if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1314 signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1315#endif
1316#if defined(SIGXFSZ)
1317 if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1318 signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1319#endif
1320 }
1321 /*
cristyaf8b5cd2009-10-24 00:29:23 +00001322 Instantiate magick resources.
cristy3ed852e2009-09-05 21:47:34 +00001323 */
cristy18b17442009-10-25 18:36:48 +00001324 (void) ConfigureComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001325 (void) PolicyComponentGenesis();
1326 (void) CacheComponentGenesis();
1327 (void) RegistryComponentGenesis();
1328 (void) ResourceComponentGenesis();
1329 (void) CoderComponentGenesis();
1330 (void) MagickComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001331#if defined(MAGICKCORE_MODULES_SUPPORT)
cristyf34a1452009-10-24 22:29:27 +00001332 (void) ModuleComponentGenesis();
cristyaf8b5cd2009-10-24 00:29:23 +00001333#endif
cristyf34a1452009-10-24 22:29:27 +00001334 (void) DelegateComponentGenesis();
1335 (void) MagicComponentGenesis();
1336 (void) ColorComponentGenesis();
1337 (void) TypeComponentGenesis();
cristyf34a1452009-10-24 22:29:27 +00001338 (void) MimeComponentGenesis();
cristyd7ecaca2011-01-24 14:14:53 +00001339 (void) AnnotateComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001340#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001341 (void) XComponentGenesis();
cristy0157aea2010-04-24 21:12:18 +00001342#endif
cristyd1ebf4a2010-05-13 01:54:31 +00001343 instantiate_magickcore=MagickTrue;
1344 UnlockMagickMutex();
cristy3ed852e2009-09-05 21:47:34 +00001345}
1346
1347/*
1348%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1349% %
1350% %
1351% %
1352% M a g i c k C o r e T e r m i n u s %
1353% %
1354% %
1355% %
1356%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1357%
1358% MagickCoreTerminus() destroys the MagickCore environment.
1359%
cristyf34a1452009-10-24 22:29:27 +00001360% The format of the MagickCoreTerminus function is:
cristy3ed852e2009-09-05 21:47:34 +00001361%
1362% MagickCoreTerminus(void)
1363%
1364*/
1365MagickExport void MagickCoreTerminus(void)
1366{
cristy1ea02a32014-01-24 11:23:14 +00001367 InitializeMagickMutex();
cristyd1ebf4a2010-05-13 01:54:31 +00001368 LockMagickMutex();
1369 if (instantiate_magickcore == MagickFalse)
1370 {
1371 UnlockMagickMutex();
1372 return;
1373 }
cristy3ed852e2009-09-05 21:47:34 +00001374#if defined(MAGICKCORE_X11_DELEGATE)
cristyf34a1452009-10-24 22:29:27 +00001375 XComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +00001376#endif
cristyd7ecaca2011-01-24 14:14:53 +00001377 AnnotateComponentTerminus();
cristyf34a1452009-10-24 22:29:27 +00001378 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);
cristycd2cd182014-03-18 12:10:55 +00001447 if (magick_info->thread_support == NoThreadSupport)
1448 magick_info->semaphore=AcquireSemaphoreInfo();
cristy3ed852e2009-09-05 21:47:34 +00001449 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1450 if (status == MagickFalse)
1451 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1452 return(magick_info);
1453}
1454
1455/*
1456%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1457% %
1458% %
1459% %
1460+ S e t M a g i c k I n f o %
1461% %
1462% %
1463% %
1464%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1465%
1466% SetMagickInfo() allocates a MagickInfo structure and initializes the members
1467% to default values.
1468%
1469% The format of the SetMagickInfo method is:
1470%
1471% MagickInfo *SetMagickInfo(const char *name)
1472%
1473% A description of each parameter follows:
1474%
1475% o magick_info: Method SetMagickInfo returns the allocated and initialized
1476% MagickInfo structure.
1477%
1478% o name: a character string that represents the image format associated
1479% with the MagickInfo structure.
1480%
1481*/
1482MagickExport MagickInfo *SetMagickInfo(const char *name)
1483{
1484 MagickInfo
1485 *magick_info;
1486
1487 assert(name != (const char *) NULL);
1488 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
cristy73bd4a52010-10-05 11:24:23 +00001489 magick_info=(MagickInfo *) AcquireMagickMemory(sizeof(*magick_info));
cristy3ed852e2009-09-05 21:47:34 +00001490 if (magick_info == (MagickInfo *) NULL)
1491 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1492 (void) ResetMagickMemory(magick_info,0,sizeof(*magick_info));
1493 magick_info->name=ConstantString(name);
1494 magick_info->adjoin=MagickTrue;
1495 magick_info->blob_support=MagickTrue;
1496 magick_info->thread_support=(MagickStatusType) (DecoderThreadSupport |
1497 EncoderThreadSupport);
1498 magick_info->signature=MagickSignature;
1499 return(magick_info);
1500}
1501
1502/*
1503%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1504% %
1505% %
1506% %
cristye7f51092010-01-17 00:39:37 +00001507% S e t M a g i c k P r e c i s i o n %
1508% %
1509% %
1510% %
1511%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1512%
1513% SetMagickPrecision() sets the maximum number of significant digits to be
anthonybc6fc132012-01-16 07:02:46 +00001514% printed.
1515%
1516% An input argument of 0 returns the current precision setting.
1517%
cristyabdd5b72012-01-18 03:02:15 +00001518% A negative value forces the precision to reset to a default value according
1519% to the environment variable "MAGICK_PRECISION", the current 'policy'
1520% configuration setting, or the default value of '6', in that order.
cristye7f51092010-01-17 00:39:37 +00001521%
1522% The format of the SetMagickPrecision method is:
1523%
cristybf2766a2010-01-17 03:33:23 +00001524% int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001525%
1526% A description of each parameter follows:
1527%
1528% o precision: set the maximum number of significant digits to be printed.
1529%
1530*/
cristybf2766a2010-01-17 03:33:23 +00001531MagickExport int SetMagickPrecision(const int precision)
cristye7f51092010-01-17 00:39:37 +00001532{
anthonybc6fc132012-01-16 07:02:46 +00001533#define MagickPrecision 6
1534
cristybf2766a2010-01-17 03:33:23 +00001535 static int
1536 magick_precision = 0;
1537
cristye7f51092010-01-17 00:39:37 +00001538 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
anthony82c09922012-01-16 06:38:16 +00001539 if (precision > 0)
cristyabdd5b72012-01-18 03:02:15 +00001540 magick_precision=precision;
1541 if ((precision < 0) || (magick_precision == 0))
anthonybc6fc132012-01-16 07:02:46 +00001542 {
1543 char
1544 *limit;
1545
1546 /*
cristyabdd5b72012-01-18 03:02:15 +00001547 Precision reset, or it has not been set yet
anthonybc6fc132012-01-16 07:02:46 +00001548 */
1549 magick_precision = MagickPrecision;
1550 limit=GetEnvironmentValue("MAGICK_PRECISION");
1551 if (limit == (char *) NULL)
1552 limit=GetPolicyValue("precision");
1553 if (limit != (char *) NULL)
1554 {
cristyabdd5b72012-01-18 03:02:15 +00001555 magick_precision=StringToInteger(limit);
anthonybc6fc132012-01-16 07:02:46 +00001556 limit=DestroyString(limit);
1557 }
1558 }
cristybf2766a2010-01-17 03:33:23 +00001559 return(magick_precision);
cristye7f51092010-01-17 00:39:37 +00001560}
1561
1562/*
1563%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1564% %
1565% %
1566% %
cristy3ed852e2009-09-05 21:47:34 +00001567+ U n r e g i s t e r M a g i c k I n f o %
1568% %
1569% %
1570% %
1571%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1572%
1573% UnregisterMagickInfo() removes a name from the magick info list. It returns
1574% MagickFalse if the name does not exist in the list otherwise MagickTrue.
1575%
1576% The format of the UnregisterMagickInfo method is:
1577%
1578% MagickBooleanType UnregisterMagickInfo(const char *name)
1579%
1580% A description of each parameter follows:
1581%
1582% o name: a character string that represents the image format we are
1583% looking for.
1584%
1585*/
1586MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1587{
1588 register const MagickInfo
1589 *p;
1590
1591 MagickBooleanType
1592 status;
1593
1594 assert(name != (const char *) NULL);
1595 if (magick_list == (SplayTreeInfo *) NULL)
1596 return(MagickFalse);
1597 if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1598 return(MagickFalse);
cristyf84a1932010-01-03 18:00:18 +00001599 LockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001600 ResetSplayTreeIterator(magick_list);
1601 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1602 while (p != (const MagickInfo *) NULL)
1603 {
1604 if (LocaleCompare(p->name,name) == 0)
1605 break;
1606 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1607 }
1608 status=DeleteNodeByValueFromSplayTree(magick_list,p);
cristyf84a1932010-01-03 18:00:18 +00001609 UnlockSemaphoreInfo(magick_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001610 return(status);
1611}