2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % M M AAA GGGG IIIII CCCC %
8 % M M M AAAAA G GGG I C %
10 % M M A A GGGG IIIII CCCC %
13 % MagickCore Image Magic Methods %
20 % Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % https://imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/client.h"
45 #include "MagickCore/configure.h"
46 #include "MagickCore/configure-private.h"
47 #include "MagickCore/exception.h"
48 #include "MagickCore/exception-private.h"
49 #include "MagickCore/linked-list.h"
50 #include "MagickCore/magic.h"
51 #include "MagickCore/magic-private.h"
52 #include "MagickCore/memory_.h"
53 #include "MagickCore/memory-private.h"
54 #include "MagickCore/semaphore.h"
55 #include "MagickCore/string_.h"
56 #include "MagickCore/string-private.h"
57 #include "MagickCore/token.h"
58 #include "MagickCore/utility.h"
59 #include "MagickCore/utility-private.h"
60 #include "MagickCore/xml-tree.h"
61 #include "MagickCore/xml-tree-private.h"
66 #define MagicPattern(magic) (const unsigned char *) (magic), sizeof(magic)-1
71 typedef struct _MagicMapInfo
76 const MagickOffsetType
113 static const MagicMapInfo
116 { "8BIMWTEXT", 0, MagicPattern("8\000B\000I\000M\000#") },
117 { "8BIMTEXT", 0, MagicPattern("8BIM#") },
118 { "8BIM", 0, MagicPattern("8BIM") },
119 { "BMP", 0, MagicPattern("BA") },
120 { "BMP", 0, MagicPattern("BM") },
121 { "BMP", 0, MagicPattern("CI") },
122 { "BMP", 0, MagicPattern("CP") },
123 { "BMP", 0, MagicPattern("IC") },
124 { "PICT", 0, MagicPattern("PICT") },
125 { "BMP", 0, MagicPattern("PI") },
126 { "CALS", 21, MagicPattern("version: MIL-STD-1840") },
127 { "CALS", 0, MagicPattern("srcdocid:") },
128 { "CALS", 9, MagicPattern("srcdocid:") },
129 { "CALS", 8, MagicPattern("rorient:") },
130 { "CGM", 0, MagicPattern("BEGMF") },
131 { "CIN", 0, MagicPattern("\200\052\137\327") },
132 { "CRW", 0, MagicPattern("II\x1a\x00\x00\x00HEAPCCDR") },
133 { "DCM", 128, MagicPattern("DICM") },
134 { "DCX", 0, MagicPattern("\261\150\336\72") },
135 { "DIB", 0, MagicPattern("\050\000") },
136 { "DDS", 0, MagicPattern("DDS ") },
137 { "DJVU", 0, MagicPattern("AT&TFORM") },
138 { "DOT", 0, MagicPattern("digraph") },
139 { "DPX", 0, MagicPattern("SDPX") },
140 { "DPX", 0, MagicPattern("XPDS") },
141 { "EMF", 40, MagicPattern("\040\105\115\106\000\000\001\000") },
142 { "EPT", 0, MagicPattern("\305\320\323\306") },
143 { "EXR", 0, MagicPattern("\166\057\061\001") },
144 { "FAX", 0, MagicPattern("DFAX") },
145 { "FIG", 0, MagicPattern("#FIG") },
146 { "FITS", 0, MagicPattern("IT0") },
147 { "FITS", 0, MagicPattern("SIMPLE") },
148 { "FLIF", 0, MagicPattern("FLIF") },
149 { "GIF", 0, MagicPattern("GIF8") },
150 { "GPLT", 0, MagicPattern("#!/usr/local/bin/gnuplot") },
151 { "HDF", 1, MagicPattern("HDF") },
152 { "HDR", 0, MagicPattern("#?RADIANCE") },
153 { "HDR", 0, MagicPattern("#?RGBE") },
154 { "HEIC", 8, MagicPattern("heic") },
155 { "HPGL", 0, MagicPattern("IN;") },
156 { "HTML", 1, MagicPattern("HTML") },
157 { "HTML", 1, MagicPattern("html") },
158 { "ILBM", 8, MagicPattern("ILBM") },
159 { "IPTCWTEXT", 0, MagicPattern("\062\000#\000\060\000=\000\042\000&\000#\000\060\000;\000&\000#\000\062\000;\000\042\000") },
160 { "IPTCTEXT", 0, MagicPattern("2#0=\042�\042") },
161 { "IPTC", 0, MagicPattern("\034\002") },
162 { "JNG", 0, MagicPattern("\213JNG\r\n\032\n") },
163 { "JPEG", 0, MagicPattern("\377\330\377") },
164 { "J2K", 0, MagicPattern("\xff\x4f\xff\x51") },
165 { "JPC", 0, MagicPattern("\x0d\x0a\x87\x0a") },
166 { "JP2", 0, MagicPattern("\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a") },
167 { "MAT", 0, MagicPattern("MATLAB 5.0 MAT-file,") },
168 { "MIFF", 0, MagicPattern("Id=ImageMagick") },
169 { "MIFF", 0, MagicPattern("id=ImageMagick") },
170 { "MNG", 0, MagicPattern("\212MNG\r\n\032\n") },
171 { "MPC", 0, MagicPattern("id=MagickCache") },
172 { "MPEG", 0, MagicPattern("\000\000\001\263") },
173 { "MRW", 0, MagicPattern("\x00MRM") },
174 { "ORF", 0, MagicPattern("IIRO\x08\x00\x00\x00") },
175 { "PCD", 2048, MagicPattern("PCD_") },
176 { "PCL", 0, MagicPattern("\033E\033") },
177 { "PCX", 0, MagicPattern("\012\002") },
178 { "PCX", 0, MagicPattern("\012\005") },
179 { "PDB", 60, MagicPattern("vIMGView") },
180 { "PDF", 0, MagicPattern("%PDF-") },
181 { "PES", 0, MagicPattern("#PES") },
182 { "PFA", 0, MagicPattern("%!PS-AdobeFont-1.0") },
183 { "PFB", 6, MagicPattern("%!PS-AdobeFont-1.0") },
184 { "PGX", 0, MagicPattern("\050\107\020\115\046") },
185 { "PICT", 522, MagicPattern("\000\021\002\377\014\000") },
186 { "PNG", 0, MagicPattern("\211PNG\r\n\032\n") },
187 { "PBM", 0, MagicPattern("P1") },
188 { "PGM", 0, MagicPattern("P2") },
189 { "PPM", 0, MagicPattern("P3") },
190 { "PBM", 0, MagicPattern("P4") },
191 { "PGM", 0, MagicPattern("P5") },
192 { "PPM", 0, MagicPattern("P6") },
193 { "PAM", 0, MagicPattern("P7") },
194 { "PFM", 0, MagicPattern("PF") },
195 { "PFM", 0, MagicPattern("Pf") },
196 { "PGX", 0, MagicPattern("PG ML") },
197 { "PGX", 0, MagicPattern("PG LM") },
198 { "PS", 0, MagicPattern("%!") },
199 { "PS", 0, MagicPattern("\004%!") },
200 { "PS", 0, MagicPattern("\305\320\323\306") },
201 { "PSB", 0, MagicPattern("8BPB") },
202 { "PSD", 0, MagicPattern("8BPS") },
203 { "PWP", 0, MagicPattern("SFW95") },
204 { "RAF", 0, MagicPattern("FUJIFILMCCD-RAW ") },
205 { "RLE", 0, MagicPattern("\122\314") },
206 { "SCT", 0, MagicPattern("CT") },
207 { "SFW", 0, MagicPattern("SFW94") },
208 { "SGI", 0, MagicPattern("\001\332") },
209 { "SUN", 0, MagicPattern("\131\246\152\225") },
210 { "SVG", 1, MagicPattern("?XML") },
211 { "SVG", 1, MagicPattern("?xml") },
212 { "SVG", 1, MagicPattern("SVG") },
213 { "SVG", 1, MagicPattern("svg") },
214 { "TIFF", 0, MagicPattern("\115\115\000\052") },
215 { "TIFF", 0, MagicPattern("\111\111\052\000") },
216 { "TIFF64", 0, MagicPattern("\115\115\000\053\000\010\000\000") },
217 { "TIFF64", 0, MagicPattern("\111\111\053\000\010\000\000\000") },
218 { "TTF", 0, MagicPattern("\000\001\000\000\000") },
219 { "TXT", 0, MagicPattern("# ImageMagick pixel enumeration:") },
220 { "VICAR", 0, MagicPattern("LBLSIZE") },
221 { "VICAR", 0, MagicPattern("NJPL1I") },
222 { "VIFF", 0, MagicPattern("\253\001") },
223 { "WEBP", 8, MagicPattern("WEBP") },
224 { "WMF", 0, MagicPattern("\327\315\306\232") },
225 { "WMF", 0, MagicPattern("\001\000\011\000") },
226 { "WPG", 0, MagicPattern("\377WPC") },
227 { "XBM", 0, MagicPattern("#define") },
228 { "XCF", 0, MagicPattern("gimp xcf") },
229 { "XEF", 0, MagicPattern("FOVb") },
230 { "XPM", 1, MagicPattern("* XPM *") }
233 static LinkedListInfo
234 *magic_cache = (LinkedListInfo *) NULL,
235 *magic_list = (LinkedListInfo *) NULL;
238 *magic_cache_semaphore = (SemaphoreInfo *) NULL,
239 *magic_list_semaphore = (SemaphoreInfo *) NULL;
242 Forward declarations.
244 static MagickBooleanType
245 IsMagicListInstantiated(ExceptionInfo *);
248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252 % A c q u i r e M a g i c L i s t %
256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
258 % AcquireMagicList() caches one or more magic configurations which provides a
259 % mapping between magic attributes and a magic name.
261 % The format of the AcquireMagicList method is:
263 % LinkedListInfo *AcquireMagicList(ExceptionInfo *exception)
265 % A description of each parameter follows:
267 % o filename: the font file name.
269 % o exception: return any errors or warnings in this structure.
272 static int CompareMagickInfoSize(const void *a,const void *b)
280 if (ma->offset != mb->offset)
281 return((int) (ma->offset-mb->offset));
282 return((int) (mb->length-ma->length));
285 static LinkedListInfo *AcquireMagicList(ExceptionInfo *exception)
296 list=NewLinkedList(0);
299 Load built-in magic map.
301 for (i=0; i < (ssize_t) (sizeof(MagicMap)/sizeof(*MagicMap)); i++)
306 register const MagicMapInfo
310 magic_info=(MagicInfo *) AcquireMagickMemory(sizeof(*magic_info));
311 if (magic_info == (MagicInfo *) NULL)
313 (void) ThrowMagickException(exception,GetMagickModule(),
314 ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name);
317 (void) memset(magic_info,0,sizeof(*magic_info));
318 magic_info->path=(char *) "[built-in]";
319 magic_info->name=(char *) p->name;
320 magic_info->offset=p->offset;
321 magic_info->target=(char *) p->magic;
322 magic_info->magic=(unsigned char *) p->magic;
323 magic_info->length=p->length;
324 magic_info->exempt=MagickTrue;
325 magic_info->signature=MagickCoreSignature;
326 status&=InsertValueInSortedLinkedList(list,CompareMagickInfoSize,
328 if (status == MagickFalse)
329 (void) ThrowMagickException(exception,GetMagickModule(),
330 ResourceLimitError,"MemoryAllocationFailed","`%s'",magic_info->name);
336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
340 % G e t M a g i c I n f o %
344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
346 % GetMagicInfo() searches the magic list for the specified name and if found
347 % returns attributes for that magic.
349 % The format of the GetMagicInfo method is:
351 % const MagicInfo *GetMagicInfo(const unsigned char *magic,
352 % const size_t length,ExceptionInfo *exception)
354 % A description of each parameter follows:
356 % o magic: A binary string generally representing the first few characters
357 % of the image file or blob.
359 % o length: the length of the binary signature.
361 % o exception: return any errors or warnings in this structure.
364 static MagickBooleanType IsMagicCacheInstantiated()
366 if (magic_cache == (LinkedListInfo *) NULL)
368 if (magic_cache_semaphore == (SemaphoreInfo *) NULL)
369 ActivateSemaphoreInfo(&magic_cache_semaphore);
370 LockSemaphoreInfo(magic_cache_semaphore);
371 if (magic_cache == (LinkedListInfo *) NULL)
372 magic_cache=NewLinkedList(0);
373 UnlockSemaphoreInfo(magic_cache_semaphore);
375 return(magic_cache != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
378 MagickExport const MagicInfo *GetMagicInfo(const unsigned char *magic,
379 const size_t length,ExceptionInfo *exception)
381 register const MagicInfo
384 assert(exception != (ExceptionInfo *) NULL);
385 if (IsMagicListInstantiated(exception) == MagickFalse)
386 return((const MagicInfo *) NULL);
387 if (IsMagicCacheInstantiated() == MagickFalse)
388 return((const MagicInfo *) NULL);
390 Search for cached entries.
392 if (magic != (const unsigned char *) NULL)
394 LockSemaphoreInfo(magic_cache_semaphore);
395 ResetLinkedListIterator(magic_cache);
396 p=(const MagicInfo *) GetNextValueInLinkedList(magic_cache);
397 while (p != (const MagicInfo *) NULL)
399 if (((size_t) (p->offset+p->length) <= length) &&
400 (memcmp(magic+p->offset,p->magic,p->length) == 0))
402 p=(const MagicInfo *) GetNextValueInLinkedList(magic_cache);
404 UnlockSemaphoreInfo(magic_cache_semaphore);
405 if (p != (const MagicInfo *) NULL)
409 Search for magic tag.
411 LockSemaphoreInfo(magic_list_semaphore);
412 ResetLinkedListIterator(magic_list);
413 p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
414 if (magic == (const unsigned char *) NULL)
416 UnlockSemaphoreInfo(magic_list_semaphore);
419 while (p != (const MagicInfo *) NULL)
421 assert(p->offset >= 0);
422 if (((size_t) (p->offset+p->length) <= length) &&
423 (memcmp(magic+p->offset,p->magic,p->length) == 0))
425 p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
427 UnlockSemaphoreInfo(magic_list_semaphore);
428 if (p != (const MagicInfo *) NULL)
430 LockSemaphoreInfo(magic_cache_semaphore);
431 InsertValueInSortedLinkedList(magic_cache,CompareMagickInfoSize,
433 UnlockSemaphoreInfo(magic_cache_semaphore);
439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
443 % G e t M a g i c P a t t e r n E x t e n t %
447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
449 % GetMagicPatternExtent() returns the the extent of the buffer that is
450 % required to check all the MagickInfos. It returns zero if the list is empty.
452 % The format of the GetMagicPatternExtent method is:
454 % size_t GetMagicPatternExtent(ExceptionInfo *exception)
456 % A description of each parameter follows:
458 % o exception: return any errors or warnings in this structure.
461 MagickExport size_t GetMagicPatternExtent(ExceptionInfo *exception)
463 register const MagicInfo
473 assert(exception != (ExceptionInfo *) NULL);
474 if ((size != 0) || (IsMagicListInstantiated(exception) == MagickFalse))
476 LockSemaphoreInfo(magic_list_semaphore);
477 ResetLinkedListIterator(magic_list);
479 p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
480 while (p != (const MagicInfo *) NULL)
482 magickSize=(size_t) (p->offset+p->length);
483 if (magickSize > max)
485 p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
488 UnlockSemaphoreInfo(magic_list_semaphore);
493 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
497 % G e t M a g i c I n f o L i s t %
501 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
503 % GetMagicInfoList() returns any image aliases that match the specified
506 % The magic of the GetMagicInfoList function is:
508 % const MagicInfo **GetMagicInfoList(const char *pattern,
509 % size_t *number_aliases,ExceptionInfo *exception)
511 % A description of each parameter follows:
513 % o pattern: Specifies a pointer to a text string containing a pattern.
515 % o number_aliases: This integer returns the number of aliases in the list.
517 % o exception: return any errors or warnings in this structure.
521 #if defined(__cplusplus) || defined(c_plusplus)
525 static int MagicInfoCompare(const void *x,const void *y)
531 p=(const MagicInfo **) x,
532 q=(const MagicInfo **) y;
533 if (LocaleCompare((*p)->path,(*q)->path) == 0)
534 return(LocaleCompare((*p)->name,(*q)->name));
535 return(LocaleCompare((*p)->path,(*q)->path));
538 #if defined(__cplusplus) || defined(c_plusplus)
542 MagickExport const MagicInfo **GetMagicInfoList(const char *pattern,
543 size_t *number_aliases,ExceptionInfo *exception)
548 register const MagicInfo
557 assert(pattern != (char *) NULL);
558 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
559 assert(number_aliases != (size_t *) NULL);
561 p=GetMagicInfo((const unsigned char *) NULL,0,exception);
562 if (p == (const MagicInfo *) NULL)
563 return((const MagicInfo **) NULL);
564 aliases=(const MagicInfo **) AcquireQuantumMemory((size_t)
565 GetNumberOfElementsInLinkedList(magic_list)+1UL,sizeof(*aliases));
566 if (aliases == (const MagicInfo **) NULL)
567 return((const MagicInfo **) NULL);
571 LockSemaphoreInfo(magic_list_semaphore);
572 ResetLinkedListIterator(magic_list);
573 p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
574 for (i=0; p != (const MagicInfo *) NULL; )
576 if ((p->stealth == MagickFalse) &&
577 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
579 p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
581 UnlockSemaphoreInfo(magic_list_semaphore);
582 qsort((void *) aliases,(size_t) i,sizeof(*aliases),MagicInfoCompare);
583 aliases[i]=(MagicInfo *) NULL;
584 *number_aliases=(size_t) i;
589 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
593 % G e t M a g i c L i s t %
597 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
599 % GetMagicList() returns any image format aliases that match the specified
602 % The format of the GetMagicList function is:
604 % char **GetMagicList(const char *pattern,size_t *number_aliases,
605 % ExceptionInfo *exception)
607 % A description of each parameter follows:
609 % o pattern: Specifies a pointer to a text string containing a pattern.
611 % o number_aliases: This integer returns the number of image format aliases
614 % o exception: return any errors or warnings in this structure.
618 #if defined(__cplusplus) || defined(c_plusplus)
622 static int MagicCompare(const void *x,const void *y)
630 return(LocaleCompare(p,q));
633 #if defined(__cplusplus) || defined(c_plusplus)
637 MagickExport char **GetMagicList(const char *pattern,size_t *number_aliases,
638 ExceptionInfo *exception)
643 register const MagicInfo
650 Allocate configure list.
652 assert(pattern != (char *) NULL);
653 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
654 assert(number_aliases != (size_t *) NULL);
656 p=GetMagicInfo((const unsigned char *) NULL,0,exception);
657 if (p == (const MagicInfo *) NULL)
658 return((char **) NULL);
659 aliases=(char **) AcquireQuantumMemory((size_t)
660 GetNumberOfElementsInLinkedList(magic_list)+1UL,sizeof(*aliases));
661 if (aliases == (char **) NULL)
662 return((char **) NULL);
663 LockSemaphoreInfo(magic_list_semaphore);
664 ResetLinkedListIterator(magic_list);
665 p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
666 for (i=0; p != (const MagicInfo *) NULL; )
668 if ((p->stealth == MagickFalse) &&
669 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
670 aliases[i++]=ConstantString(p->name);
671 p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
673 UnlockSemaphoreInfo(magic_list_semaphore);
674 qsort((void *) aliases,(size_t) i,sizeof(*aliases),MagicCompare);
675 aliases[i]=(char *) NULL;
676 *number_aliases=(size_t) i;
681 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
685 % G e t M a g i c N a m e %
689 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
691 % GetMagicName() returns the name associated with the magic.
693 % The format of the GetMagicName method is:
695 % const char *GetMagicName(const MagicInfo *magic_info)
697 % A description of each parameter follows:
699 % o magic_info: The magic info.
702 MagickExport const char *GetMagicName(const MagicInfo *magic_info)
704 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
705 assert(magic_info != (MagicInfo *) NULL);
706 assert(magic_info->signature == MagickCoreSignature);
707 return(magic_info->name);
711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
715 + I s M a g i c L i s t I n s t a n t i a t e d %
719 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
721 % IsMagicListInstantiated() determines if the magic list is instantiated.
722 % If not, it instantiates the list and returns it.
724 % The format of the IsMagicListInstantiated method is:
726 % MagickBooleanType IsMagicListInstantiated(ExceptionInfo *exception)
728 % A description of each parameter follows.
730 % o exception: return any errors or warnings in this structure.
733 static MagickBooleanType IsMagicListInstantiated(ExceptionInfo *exception)
735 if (magic_list == (LinkedListInfo *) NULL)
737 if (magic_list_semaphore == (SemaphoreInfo *) NULL)
738 ActivateSemaphoreInfo(&magic_list_semaphore);
739 LockSemaphoreInfo(magic_list_semaphore);
740 if (magic_list == (LinkedListInfo *) NULL)
741 magic_list=AcquireMagicList(exception);
742 UnlockSemaphoreInfo(magic_list_semaphore);
744 return(magic_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
748 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
752 % L i s t M a g i c I n f o %
756 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
758 % ListMagicInfo() lists the magic info to a file.
760 % The format of the ListMagicInfo method is:
762 % MagickBooleanType ListMagicInfo(FILE *file,ExceptionInfo *exception)
764 % A description of each parameter follows.
766 % o file: An pointer to a FILE.
768 % o exception: return any errors or warnings in this structure.
771 MagickExport MagickBooleanType ListMagicInfo(FILE *file,
772 ExceptionInfo *exception)
789 if (file == (const FILE *) NULL)
791 magic_info=GetMagicInfoList("*",&number_aliases,exception);
792 if (magic_info == (const MagicInfo **) NULL)
794 path=(const char *) NULL;
795 for (i=0; i < (ssize_t) number_aliases; i++)
797 if (magic_info[i]->stealth != MagickFalse)
799 if ((path == (const char *) NULL) ||
800 (LocaleCompare(path,magic_info[i]->path) != 0))
802 if (magic_info[i]->path != (char *) NULL)
803 (void) FormatLocaleFile(file,"\nPath: %s\n\n",magic_info[i]->path);
804 (void) FormatLocaleFile(file,"Name Offset Target\n");
805 (void) FormatLocaleFile(file,
806 "-------------------------------------------------"
807 "------------------------------\n");
809 path=magic_info[i]->path;
810 (void) FormatLocaleFile(file,"%s",magic_info[i]->name);
811 for (j=(ssize_t) strlen(magic_info[i]->name); j <= 9; j++)
812 (void) FormatLocaleFile(file," ");
813 (void) FormatLocaleFile(file,"%6ld ",(long) magic_info[i]->offset);
814 if (magic_info[i]->target != (char *) NULL)
816 for (j=0; magic_info[i]->target[j] != '\0'; j++)
817 if (isprint((int) ((unsigned char) magic_info[i]->target[j])) != 0)
818 (void) FormatLocaleFile(file,"%c",magic_info[i]->target[j]);
820 (void) FormatLocaleFile(file,"\\%03o",(unsigned int)
821 ((unsigned char) magic_info[i]->target[j]));
823 (void) FormatLocaleFile(file,"\n");
826 magic_info=(const MagicInfo **) RelinquishMagickMemory((void *) magic_info);
831 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
835 + M a g i c C o m p o n e n t G e n e s i s %
839 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
841 % MagicComponentGenesis() instantiates the magic component.
843 % The format of the MagicComponentGenesis method is:
845 % MagickBooleanType MagicComponentGenesis(void)
848 MagickPrivate MagickBooleanType MagicComponentGenesis(void)
850 if (magic_list_semaphore == (SemaphoreInfo *) NULL)
851 magic_list_semaphore=AcquireSemaphoreInfo();
856 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
860 + M a g i c C o m p o n e n t T e r m i n u s %
864 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
866 % MagicComponentTerminus() destroys the magic component.
868 % The format of the MagicComponentTerminus method is:
870 % MagicComponentTerminus(void)
874 static void *DestroyMagicElement(void *magic_info)
879 p=(MagicInfo *) magic_info;
880 if (p->exempt == MagickFalse)
882 if (p->path != (char *) NULL)
883 p->path=DestroyString(p->path);
884 if (p->name != (char *) NULL)
885 p->name=DestroyString(p->name);
886 if (p->target != (char *) NULL)
887 p->target=DestroyString(p->target);
888 if (p->magic != (unsigned char *) NULL)
889 p->magic=(unsigned char *) RelinquishMagickMemory(p->magic);
891 p=(MagicInfo *) RelinquishMagickMemory(p);
892 return((void *) NULL);
895 MagickPrivate void MagicComponentTerminus(void)
897 if (magic_list_semaphore == (SemaphoreInfo *) NULL)
898 ActivateSemaphoreInfo(&magic_list_semaphore);
899 LockSemaphoreInfo(magic_list_semaphore);
900 if (magic_list != (LinkedListInfo *) NULL)
901 magic_list=DestroyLinkedList(magic_list,DestroyMagicElement);
902 UnlockSemaphoreInfo(magic_list_semaphore);
903 RelinquishSemaphoreInfo(&magic_list_semaphore);