42#include "magick/studio.h"
43#include "magick/blob.h"
44#include "magick/client.h"
45#include "magick/configure.h"
46#include "magick/exception.h"
47#include "magick/exception-private.h"
48#include "magick/hashmap.h"
49#include "magick/magic.h"
50#include "magick/memory_.h"
51#include "magick/semaphore.h"
52#include "magick/string_.h"
53#include "magick/string-private.h"
54#include "magick/token.h"
55#include "magick/utility.h"
56#include "magick/xml-tree.h"
57#include "magick/xml-tree-private.h"
62#define MagicFilename "magic.xml"
63#define MagicPattern(magic) (const unsigned char *) (magic), sizeof(magic)-1
73 const MagickOffsetType
89 {
"8BIMWTEXT", 0, MagicPattern(
"8\000B\000I\000M\000#") },
90 {
"8BIMTEXT", 0, MagicPattern(
"8BIM#") },
91 {
"8BIM", 0, MagicPattern(
"8BIM") },
92 {
"AVIF", 4, MagicPattern(
"ftypavif") },
93 {
"BMP", 0, MagicPattern(
"BA") },
94 {
"BMP", 0, MagicPattern(
"BM") },
95 {
"BMP", 0, MagicPattern(
"CI") },
96 {
"BMP", 0, MagicPattern(
"CP") },
97 {
"BMP", 0, MagicPattern(
"IC") },
98 {
"PICT", 0, MagicPattern(
"PICT") },
99 {
"BMP", 0, MagicPattern(
"PI") },
100 {
"CALS", 21, MagicPattern(
"version: MIL-STD-1840") },
101 {
"CALS", 0, MagicPattern(
"srcdocid:") },
102 {
"CALS", 9, MagicPattern(
"srcdocid:") },
103 {
"CALS", 8, MagicPattern(
"rorient:") },
104 {
"CGM", 0, MagicPattern(
"BEGMF") },
105 {
"CIN", 0, MagicPattern(
"\200\052\137\327") },
106 {
"CRW", 0, MagicPattern(
"II\x1a\x00\x00\x00HEAPCCDR") },
107 {
"DCM", 128, MagicPattern(
"DICM") },
108 {
"DCX", 0, MagicPattern(
"\261\150\336\72") },
109 {
"DIB", 0, MagicPattern(
"\050\000") },
110 {
"DDS", 0, MagicPattern(
"DDS ") },
111 {
"DJVU", 0, MagicPattern(
"AT&TFORM") },
112 {
"DOT", 0, MagicPattern(
"digraph") },
113 {
"DPX", 0, MagicPattern(
"SDPX") },
114 {
"DPX", 0, MagicPattern(
"XPDS") },
115 {
"EMF", 40, MagicPattern(
"\040\105\115\106\000\000\001\000") },
116 {
"EPT", 0, MagicPattern(
"\305\320\323\306") },
117 {
"EXR", 0, MagicPattern(
"\166\057\061\001") },
118 {
"FAX", 0, MagicPattern(
"DFAX") },
119 {
"FIG", 0, MagicPattern(
"#FIG") },
120 {
"FITS", 0, MagicPattern(
"IT0") },
121 {
"FITS", 0, MagicPattern(
"SIMPLE") },
122 {
"FLIF", 0, MagicPattern(
"FLIF") },
123 {
"GIF", 0, MagicPattern(
"GIF8") },
124 {
"GPLT", 0, MagicPattern(
"#!/usr/local/bin/gnuplot") },
125 {
"HDF", 1, MagicPattern(
"HDF") },
126 {
"HDR", 0, MagicPattern(
"#?RADIANCE") },
127 {
"HDR", 0, MagicPattern(
"#?RGBE") },
128 {
"HEIC", 4, MagicPattern(
"ftypheic") },
129 {
"HEIC", 4, MagicPattern(
"ftypheix") },
130 {
"HEIC", 4, MagicPattern(
"ftypmif1") },
131 {
"HPGL", 0, MagicPattern(
"IN;") },
132 {
"HTML", 1, MagicPattern(
"HTML") },
133 {
"HTML", 1, MagicPattern(
"html") },
134 {
"ILBM", 8, MagicPattern(
"ILBM") },
135 {
"IPTCWTEXT", 0, MagicPattern(
"\062\000#\000\060\000=\000\042\000&\000#\000\060\000;\000&\000#\000\062\000;\000\042\000") },
136 {
"IPTCTEXT", 0, MagicPattern(
"2#0=\042�\042") },
137 {
"IPTC", 0, MagicPattern(
"\034\002") },
138 {
"JNG", 0, MagicPattern(
"\213JNG\r\n\032\n") },
139 {
"JPEG", 0, MagicPattern(
"\377\330\377") },
140 {
"J2K", 0, MagicPattern(
"\xff\x4f\xff\x51") },
141 {
"JPC", 0, MagicPattern(
"\x0d\x0a\x87\x0a") },
142 {
"JP2", 0, MagicPattern(
"\x00\x00\x00\x0c\x6a\x50\x20\x20\x0d\x0a\x87\x0a") },
143 {
"JXL", 0, MagicPattern(
"\xff\x0a") },
144 {
"JXL", 0, MagicPattern(
"\x00\x00\x00\x0c\x4a\x58\x4c\x20\x0d\x0a\x87\x0a") },
145 {
"MAT", 0, MagicPattern(
"MATLAB 5.0 MAT-file,") },
146 {
"MIFF", 0, MagicPattern(
"Id=ImageMagick") },
147 {
"MIFF", 0, MagicPattern(
"id=ImageMagick") },
148 {
"MNG", 0, MagicPattern(
"\212MNG\r\n\032\n") },
149 {
"MPC", 0, MagicPattern(
"id=MagickCache") },
150 {
"MPEG", 0, MagicPattern(
"\000\000\001\263") },
151 {
"MRW", 0, MagicPattern(
"\x00MRM") },
152 {
"ORF", 0, MagicPattern(
"IIRO\x08\x00\x00\x00") },
153 {
"PCD", 2048, MagicPattern(
"PCD_") },
154 {
"PCL", 0, MagicPattern(
"\033E\033") },
155 {
"PCX", 0, MagicPattern(
"\012\002") },
156 {
"PCX", 0, MagicPattern(
"\012\005") },
157 {
"PDB", 60, MagicPattern(
"vIMGView") },
158 {
"PDF", 0, MagicPattern(
"%PDF-") },
159 {
"PES", 0, MagicPattern(
"#PES") },
160 {
"PFA", 0, MagicPattern(
"%!PS-AdobeFont-1.0") },
161 {
"PFB", 6, MagicPattern(
"%!PS-AdobeFont-1.0") },
162 {
"PGX", 0, MagicPattern(
"PG ML") },
163 {
"PGX", 0, MagicPattern(
"PG LM") },
164 {
"PICT", 522, MagicPattern(
"\000\021\002\377\014\000") },
165 {
"PNG", 0, MagicPattern(
"\211PNG\r\n\032\n") },
166 {
"PBM", 0, MagicPattern(
"P1") },
167 {
"PGM", 0, MagicPattern(
"P2") },
168 {
"PPM", 0, MagicPattern(
"P3") },
169 {
"PBM", 0, MagicPattern(
"P4") },
170 {
"PGM", 0, MagicPattern(
"P5") },
171 {
"PPM", 0, MagicPattern(
"P6") },
172 {
"PAM", 0, MagicPattern(
"P7") },
173 {
"PFM", 0, MagicPattern(
"PF") },
174 {
"PFM", 0, MagicPattern(
"Pf") },
175 {
"PS", 0, MagicPattern(
"%!") },
176 {
"PS", 0, MagicPattern(
"\004%!") },
177 {
"PS", 0, MagicPattern(
"\305\320\323\306") },
178 {
"PSB", 0, MagicPattern(
"8BPB") },
179 {
"PSD", 0, MagicPattern(
"8BPS") },
180 {
"PWP", 0, MagicPattern(
"SFW95") },
181 {
"RAF", 0, MagicPattern(
"FUJIFILMCCD-RAW ") },
182 {
"RLE", 0, MagicPattern(
"\122\314") },
183 {
"SCT", 0, MagicPattern(
"CT") },
184 {
"SFW", 0, MagicPattern(
"SFW94") },
185 {
"SGI", 0, MagicPattern(
"\001\332") },
186 {
"SUN", 0, MagicPattern(
"\131\246\152\225") },
187 {
"SVG", 1, MagicPattern(
"?XML") },
188 {
"SVG", 1, MagicPattern(
"?xml") },
189 {
"SVG", 1, MagicPattern(
"SVG") },
190 {
"SVG", 1, MagicPattern(
"svg") },
191 {
"TIFF", 0, MagicPattern(
"\115\115\000\052") },
192 {
"TIFF", 0, MagicPattern(
"\111\111\052\000") },
193 {
"TIFF64", 0, MagicPattern(
"\115\115\000\053\000\010\000\000") },
194 {
"TIFF64", 0, MagicPattern(
"\111\111\053\000\010\000\000\000") },
195 {
"TTF", 0, MagicPattern(
"\000\001\000\000\000") },
196 {
"TXT", 0, MagicPattern(
"# ImageMagick pixel enumeration:") },
197 {
"VICAR", 0, MagicPattern(
"LBLSIZE") },
198 {
"VICAR", 0, MagicPattern(
"NJPL1I") },
199 {
"VIFF", 0, MagicPattern(
"\253\001") },
200 {
"WEBP", 8, MagicPattern(
"WEBP") },
201 {
"WMF", 0, MagicPattern(
"\327\315\306\232") },
202 {
"WMF", 0, MagicPattern(
"\001\000\011\000") },
203 {
"WPG", 0, MagicPattern(
"\377WPC") },
204 {
"XBM", 0, MagicPattern(
"#define") },
205 {
"XCF", 0, MagicPattern(
"gimp xcf") },
206 {
"XEF", 0, MagicPattern(
"FOVb") },
207 {
"XPM", 1, MagicPattern(
"* XPM *") }
219static MagickBooleanType
222#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
223static MagickBooleanType
224 LoadMagicCache(
LinkedListInfo *,
const char *,
const char *,
const size_t,
254static int CompareMagickInfoSize(
const void *a,
const void *b)
262 if (ma->offset != mb->offset)
263 return((
int) (ma->offset-mb->offset));
264 return((
int) (mb->length-(ssize_t) ma->length));
279 cache=NewLinkedList(0);
281 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
286#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
298 options=GetConfigureOptions(filename,exception);
299 option=(
const StringInfo *) GetNextValueInLinkedList(options);
302 (void) CopyMagickString(path,GetStringInfoPath(option),MaxTextExtent);
303 status&=LoadMagicCache(cache,(
const char *)
304 GetStringInfoDatum(option),GetStringInfoPath(option),0,exception);
305 option=(
const StringInfo *) GetNextValueInLinkedList(options);
307 options=DestroyConfigureOptions(options);
313 for (i=0; i < (ssize_t) (
sizeof(MagicMap)/
sizeof(*MagicMap)); i++)
322 magic_info=(
MagicInfo *) AcquireMagickMemory(
sizeof(*magic_info));
325 (void) ThrowMagickException(exception,GetMagickModule(),
326 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",p->name);
329 (void) memset(magic_info,0,
sizeof(*magic_info));
330 magic_info->path=(
char *)
"[built-in]";
331 magic_info->name=(
char *) p->name;
332 magic_info->offset=p->offset;
333 magic_info->target=(
char *) p->magic;
334 magic_info->magic=(
unsigned char *) p->magic;
335 magic_info->length=p->length;
336 magic_info->exempt=MagickTrue;
337 magic_info->signature=MagickCoreSignature;
338 status&=InsertValueInSortedLinkedList(cache,CompareMagickInfoSize,
340 if (status == MagickFalse)
341 (void) ThrowMagickException(exception,GetMagickModule(),
342 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",magic_info->name);
376MagickExport
const MagicInfo *GetMagicInfo(
const unsigned char *magic,
383 if (IsMagicCacheInstantiated(exception) == MagickFalse)
388 LockSemaphoreInfo(magic_semaphore);
389 ResetLinkedListIterator(magic_cache);
390 p=(
const MagicInfo *) GetNextValueInLinkedList(magic_cache);
391 if (magic == (
const unsigned char *) NULL)
393 UnlockSemaphoreInfo(magic_semaphore);
404 assert(p->offset >= 0);
406 remaining=(MagickOffsetType) length-p->offset;
407 if (LocaleCompare(p->name,
"SVG") == 0)
408 while ((remaining > 0) && (isspace(*q) != 0))
413 if ((remaining >= (MagickOffsetType) p->length) &&
414 (memcmp(q,p->magic,p->length) == 0))
416 p=(
const MagicInfo *) GetNextValueInLinkedList(magic_cache);
419 (
void) InsertValueInLinkedList(magic_cache,0,
420 RemoveElementByValueFromLinkedList(magic_cache,p));
421 UnlockSemaphoreInfo(magic_semaphore);
454#if defined(__cplusplus) || defined(c_plusplus)
458static int MagicInfoCompare(
const void *x,
const void *y)
466 if (LocaleCompare((*p)->path,(*q)->path) == 0)
467 return(LocaleCompare((*p)->name,(*q)->name));
468 return(LocaleCompare((*p)->path,(*q)->path));
471#if defined(__cplusplus) || defined(c_plusplus)
475MagickExport
const MagicInfo **GetMagicInfoList(
const char *pattern,
490 assert(pattern != (
char *) NULL);
491 assert(number_aliases != (
size_t *) NULL);
492 if (IsEventLogging() != MagickFalse)
493 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
495 p=GetMagicInfo((
const unsigned char *) NULL,0,exception);
498 aliases=(
const MagicInfo **) AcquireQuantumMemory((
size_t)
499 GetNumberOfElementsInLinkedList(magic_cache)+1UL,
sizeof(*aliases));
500 if (aliases == (
const MagicInfo **) NULL)
505 LockSemaphoreInfo(magic_semaphore);
506 ResetLinkedListIterator(magic_cache);
507 p=(
const MagicInfo *) GetNextValueInLinkedList(magic_cache);
508 for (i=0; p != (
const MagicInfo *) NULL; )
510 if ((p->stealth == MagickFalse) &&
511 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
513 p=(
const MagicInfo *) GetNextValueInLinkedList(magic_cache);
515 UnlockSemaphoreInfo(magic_semaphore);
516 qsort((
void *) aliases,(
size_t) i,
sizeof(*aliases),MagicInfoCompare);
518 *number_aliases=(size_t) i;
552#if defined(__cplusplus) || defined(c_plusplus)
556static int MagicCompare(
const void *x,
const void *y)
564 return(LocaleCompare(p,q));
567#if defined(__cplusplus) || defined(c_plusplus)
571MagickExport
char **GetMagicList(
const char *pattern,
size_t *number_aliases,
586 assert(pattern != (
char *) NULL);
587 assert(number_aliases != (
size_t *) NULL);
588 if (IsEventLogging() != MagickFalse)
589 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
591 p=GetMagicInfo((
const unsigned char *) NULL,0,exception);
593 return((
char **) NULL);
594 aliases=(
char **) AcquireQuantumMemory((
size_t)
595 GetNumberOfElementsInLinkedList(magic_cache)+1UL,
sizeof(*aliases));
596 if (aliases == (
char **) NULL)
597 return((
char **) NULL);
598 LockSemaphoreInfo(magic_semaphore);
599 ResetLinkedListIterator(magic_cache);
600 p=(
const MagicInfo *) GetNextValueInLinkedList(magic_cache);
601 for (i=0; p != (
const MagicInfo *) NULL; )
603 if ((p->stealth == MagickFalse) &&
604 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
605 aliases[i++]=ConstantString(p->name);
606 p=(
const MagicInfo *) GetNextValueInLinkedList(magic_cache);
608 UnlockSemaphoreInfo(magic_semaphore);
609 qsort((
void *) aliases,(
size_t) i,
sizeof(*aliases),MagicCompare);
610 aliases[i]=(
char *) NULL;
611 *number_aliases=(size_t) i;
637MagickExport
const char *GetMagicName(
const MagicInfo *magic_info)
639 assert(magic_info != (
MagicInfo *) NULL);
640 assert(magic_info->signature == MagickCoreSignature);
641 if (IsEventLogging() != MagickFalse)
642 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
643 return(magic_info->name);
669static MagickBooleanType IsMagicCacheInstantiated(
ExceptionInfo *exception)
674 ActivateSemaphoreInfo(&magic_semaphore);
675 LockSemaphoreInfo(magic_semaphore);
677 magic_cache=AcquireMagicCache(MagicFilename,exception);
678 UnlockSemaphoreInfo(magic_semaphore);
680 return(magic_cache != (
LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
707MagickExport MagickBooleanType ListMagicInfo(FILE *file,
725 if (file == (
const FILE *) NULL)
727 magic_info=GetMagicInfoList(
"*",&number_aliases,exception);
728 if (magic_info == (
const MagicInfo **) NULL)
731 path=(
const char *) NULL;
732 for (i=0; i < (ssize_t) number_aliases; i++)
734 if (magic_info[i]->stealth != MagickFalse)
736 if ((path == (
const char *) NULL) ||
737 (LocaleCompare(path,magic_info[i]->path) != 0))
739 if (magic_info[i]->path != (
char *) NULL)
740 (
void) FormatLocaleFile(file,
"\nPath: %s\n\n",magic_info[i]->path);
741 (void) FormatLocaleFile(file,
"Name Offset Target\n");
742 (void) FormatLocaleFile(file,
743 "-------------------------------------------------"
744 "------------------------------\n");
746 path=magic_info[i]->path;
747 (void) FormatLocaleFile(file,
"%s",magic_info[i]->name);
748 for (j=(ssize_t) strlen(magic_info[i]->name); j <= 9; j++)
749 (
void) FormatLocaleFile(file,
" ");
750 (void) FormatLocaleFile(file,
"%6ld ",(
long) magic_info[i]->offset);
751 if (magic_info[i]->target != (
char *) NULL)
756 for (j=0; magic_info[i]->target[j] !=
'\0'; j++)
757 if (isprint((
int) ((
unsigned char) magic_info[i]->target[j])) != 0)
758 (
void) FormatLocaleFile(file,
"%c",magic_info[i]->target[j]);
760 (
void) FormatLocaleFile(file,
"\\%03o",(
unsigned int)
761 ((
unsigned char) magic_info[i]->target[j]));
763 (void) FormatLocaleFile(file,
"\n");
766 magic_info=(
const MagicInfo **) RelinquishMagickMemory((
void *) magic_info);
770#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
801static MagickBooleanType LoadMagicCache(
LinkedListInfo *cache,
const char *xml,
802 const char *filename,
const size_t depth,
ExceptionInfo *exception)
805 keyword[MaxTextExtent],
823 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
824 "Loading magic configure file \"%s\" ...",filename);
825 if (xml == (
char *) NULL)
829 token=AcquireString(xml);
830 extent=strlen(token)+MaxTextExtent;
831 for (q=(
char *) xml; *q !=
'\0'; )
836 (void) GetNextToken(q,&q,extent,token);
839 (void) CopyMagickString(keyword,token,MaxTextExtent);
840 if (LocaleNCompare(keyword,
"<!DOCTYPE",9) == 0)
845 while ((LocaleNCompare(q,
"]>",2) != 0) && (*q !=
'\0'))
846 (
void) GetNextToken(q,&q,extent,token);
849 if (LocaleNCompare(keyword,
"<!--",4) == 0)
854 while ((LocaleNCompare(q,
"->",2) != 0) && (*q !=
'\0'))
855 (void) GetNextToken(q,&q,extent,token);
858 if (LocaleCompare(keyword,
"<include") == 0)
863 while (((*token !=
'/') && (*(token+1) !=
'>')) && (*q !=
'\0'))
865 (void) CopyMagickString(keyword,token,MaxTextExtent);
866 (void) GetNextToken(q,&q,extent,token);
869 (void) GetNextToken(q,&q,extent,token);
870 if (LocaleCompare(keyword,
"file") == 0)
872 if (depth > MagickMaxRecursionDepth)
873 (void) ThrowMagickException(exception,GetMagickModule(),
874 ConfigureError,
"IncludeElementNestedTooDeeply",
"`%s'",token);
881 GetPathComponent(filename,HeadPath,path);
883 (void) ConcatenateMagickString(path,DirectorySeparator,
885 if (*token == *DirectorySeparator)
886 (void) CopyMagickString(path,token,MaxTextExtent);
888 (
void) ConcatenateMagickString(path,token,MaxTextExtent);
889 xml=FileToXML(path,~0UL);
890 if (xml != (
char *) NULL)
892 status&=LoadMagicCache(cache,xml,path,depth+1,
894 xml=(
char *) RelinquishMagickMemory(xml);
901 if (LocaleCompare(keyword,
"<magic") == 0)
906 magic_info=(
MagicInfo *) AcquireMagickMemory(
sizeof(*magic_info));
908 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
909 (void) memset(magic_info,0,
sizeof(*magic_info));
910 magic_info->path=ConstantString(filename);
911 magic_info->exempt=MagickFalse;
912 magic_info->signature=MagickCoreSignature;
917 if ((LocaleCompare(keyword,
"/>") == 0) ||
918 (LocaleCompare(keyword,
"</policy>") == 0))
920 status=AppendValueToLinkedList(cache,magic_info);
921 if (status == MagickFalse)
922 (void) ThrowMagickException(exception,GetMagickModule(),
923 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
928 (void) GetNextToken(q,(
const char **) NULL,extent,token);
931 (void) GetNextToken(q,&q,extent,token);
932 (void) GetNextToken(q,&q,extent,token);
938 if (LocaleCompare((
char *) keyword,
"name") == 0)
940 magic_info->name=ConstantString(token);
948 if (LocaleCompare((
char *) keyword,
"offset") == 0)
950 magic_info->offset=(MagickOffsetType) StringToLong(token);
958 if (LocaleCompare((
char *) keyword,
"stealth") == 0)
960 magic_info->stealth=IsMagickTrue(token);
968 if (LocaleCompare((
char *) keyword,
"target") == 0)
979 length=strlen(token);
980 magic_info->target=ConstantString(token);
981 magic_info->magic=(
unsigned char *) ConstantString(token);
983 for (p=magic_info->target; *p !=
'\0'; )
988 if (isdigit((
int) ((
unsigned char) *p)) != 0)
993 *q++=(
unsigned char) strtol(p,&end,8);
995 magic_info->length++;
1000 case 'b': *q=
'\b';
break;
1001 case 'f': *q=
'\f';
break;
1002 case 'n': *q=
'\n';
break;
1003 case 'r': *q=
'\r';
break;
1004 case 't': *q=
'\t';
break;
1005 case 'v': *q=
'\v';
break;
1006 case 'a': *q=
'a';
break;
1007 case '?': *q=
'\?';
break;
1008 default: *q=(
unsigned char) (*p);
break;
1012 magic_info->length++;
1016 if (LocaleNCompare(p,
"&",5) == 0)
1017 (
void) CopyMagickString(p+1,p+5,length-magic_info->length);
1018 *q++=(
unsigned char) (*p++);
1019 magic_info->length++;
1029 token=(
char *) RelinquishMagickMemory(token);
1030 return(status != 0 ? MagickTrue : MagickFalse);
1052MagickExport MagickBooleanType MagicComponentGenesis(
void)
1055 magic_semaphore=AllocateSemaphoreInfo();
1078static void *DestroyMagicElement(
void *magic_info)
1084 if (p->exempt == MagickFalse)
1086 if (p->path != (
char *) NULL)
1087 p->path=DestroyString(p->path);
1088 if (p->name != (
char *) NULL)
1089 p->name=DestroyString(p->name);
1090 if (p->target != (
char *) NULL)
1091 p->target=DestroyString(p->target);
1092 if (p->magic != (
unsigned char *) NULL)
1093 p->magic=(
unsigned char *) RelinquishMagickMemory(p->magic);
1095 p=(
MagicInfo *) RelinquishMagickMemory(p);
1096 return((
void *) NULL);
1099MagickExport
void MagicComponentTerminus(
void)
1102 ActivateSemaphoreInfo(&magic_semaphore);
1103 LockSemaphoreInfo(magic_semaphore);
1105 magic_cache=DestroyLinkedList(magic_cache,DestroyMagicElement);
1106 UnlockSemaphoreInfo(magic_semaphore);
1107 DestroySemaphoreInfo(&magic_semaphore);