2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 % M M IIIII M M EEEEE %
9 % M M IIIII M M EEEEE %
12 % MagickCore Mime Methods %
18 % Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
19 % dedicated to making software imaging solutions freely available. %
21 % You may not use this file except in compliance with the License. You may %
22 % obtain a copy of the License at %
24 % http://www.imagemagick.org/MagicksToolkit/script/license.php %
26 % Unless required by applicable law or agreed to in writing, software %
27 % distributed under the License is distributed on an "AS IS" BASIS, %
28 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
29 % See the License for the specific language governing permissions and %
30 % limitations under the License. %
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40 #include "MagickCore/studio.h"
41 #include "MagickCore/blob.h"
42 #include "MagickCore/client.h"
43 #include "MagickCore/configure.h"
44 #include "MagickCore/configure-private.h"
45 #include "MagickCore/exception.h"
46 #include "MagickCore/exception-private.h"
47 #include "MagickCore/hashmap.h"
48 #include "MagickCore/memory_.h"
49 #include "MagickCore/mime.h"
50 #include "MagickCore/mime-private.h"
51 #include "MagickCore/option.h"
52 #include "MagickCore/semaphore.h"
53 #include "MagickCore/string_.h"
54 #include "MagickCore/token.h"
55 #include "MagickCore/utility.h"
56 #include "MagickCore/utility-private.h"
57 #include "MagickCore/xml-tree.h"
58 #include "MagickCore/xml-tree-private.h"
63 #define MimeFilename "mime.xml"
113 "<?xml version=\"1.0\"?>"
117 static LinkedListInfo
118 *mime_list = (LinkedListInfo *) NULL;
121 *mime_semaphore = (SemaphoreInfo *) NULL;
123 static volatile MagickBooleanType
124 instantiate_mime = MagickFalse;
127 Forward declarations.
129 static MagickBooleanType
130 InitializeMimeList(ExceptionInfo *);
133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
137 + G e t M i m e I n f o %
141 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143 % GetMimeInfo() attempts to classify the content to identify which mime type
144 % is associated with the content, if any.
146 % The format of the GetMimeInfo method is:
148 % const MimeInfo *GetMimeInfo(const char *filename,
149 % const unsigned char *magic,const size_t length,
150 % ExceptionInfo *exception)
152 % A description of each parameter follows:
154 % o filename: If we cannot not classify the string, we attempt to classify
155 % based on the filename (e.g. *.pdf returns application/pdf).
157 % o magic: A binary string generally representing the first few characters
158 % of the image file or blob.
160 % o length: the length of the binary signature.
162 % o exception: return any errors or warnings in this structure.
165 MagickExport const MimeInfo *GetMimeInfo(const char *filename,
166 const unsigned char *magic,const size_t length,ExceptionInfo *exception)
174 register const MimeInfo
177 register const unsigned char
189 assert(exception != (ExceptionInfo *) NULL);
190 if ((mime_list == (LinkedListInfo *) NULL) ||
191 (instantiate_mime == MagickFalse))
192 if (InitializeMimeList(exception) == MagickFalse)
193 return((const MimeInfo *) NULL);
194 if ((mime_list == (LinkedListInfo *) NULL) ||
195 (IsLinkedListEmpty(mime_list) != MagickFalse))
196 return((const MimeInfo *) NULL);
197 if ((magic == (const unsigned char *) NULL) || (length == 0))
198 return((const MimeInfo *) GetValueFromLinkedList(mime_list,0));
200 return((const MimeInfo *) NULL);
204 mime_info=(const MimeInfo *) NULL;
206 LockSemaphoreInfo(mime_semaphore);
207 ResetLinkedListIterator(mime_list);
208 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
209 while (p != (const MimeInfo *) NULL)
211 assert(p->offset >= 0);
212 if (mime_info != (const MimeInfo *) NULL)
213 if (p->priority > mime_info->priority)
215 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
218 if ((p->pattern != (char *) NULL) && (filename != (char *) NULL))
220 if (GlobExpression(filename,p->pattern,MagickFalse) != MagickFalse)
222 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
225 switch (p->data_type)
229 if ((size_t) (p->offset+4) > length)
232 value=(ssize_t) (*q++);
235 if (p->value == value)
240 if ((p->value & p->mask) == value)
247 if ((size_t) (p->offset+4) > length)
251 if (p->endian == UndefinedEndian)
252 endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian;
253 if (endian == LSBEndian)
255 value=(ssize_t) (*q++);
260 value=(ssize_t) (*q++) << 8;
265 if (p->value == value)
270 if ((p->value & p->mask) == value)
277 if ((size_t) (p->offset+4) > length)
281 if (p->endian == UndefinedEndian)
282 endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian;
283 if (endian == LSBEndian)
285 value=(ssize_t) (*q++);
292 value=(ssize_t) (*q++) << 24;
299 if (p->value == value)
304 if ((p->value & p->mask) == value)
312 for (i=0; i <= (ssize_t) p->extent; i++)
314 if ((size_t) (p->offset+i+p->length) > length)
316 if (memcmp(magic+p->offset+i,p->magic,p->length) == 0)
325 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
327 if (p != (const MimeInfo *) NULL)
328 (void) InsertValueInLinkedList(mime_list,0,
329 RemoveElementByValueFromLinkedList(mime_list,p));
330 UnlockSemaphoreInfo(mime_semaphore);
335 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
339 % G e t M i m e I n f o L i s t %
343 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
345 % GetMimeInfoList() returns any image aliases that match the specified
348 % The magic of the GetMimeInfoList function is:
350 % const MimeInfo **GetMimeInfoList(const char *pattern,
351 % size_t *number_aliases,ExceptionInfo *exception)
353 % A description of each parameter follows:
355 % o pattern: Specifies a pointer to a text string containing a pattern.
357 % o number_aliases: This integer returns the number of magics in the
360 % o exception: return any errors or warnings in this structure.
364 #if defined(__cplusplus) || defined(c_plusplus)
368 static int MimeInfoCompare(const void *x,const void *y)
374 p=(const MimeInfo **) x,
375 q=(const MimeInfo **) y;
376 if (strcasecmp((*p)->path,(*q)->path) == 0)
377 return(strcasecmp((*p)->type,(*q)->type));
378 return(strcasecmp((*p)->path,(*q)->path));
381 #if defined(__cplusplus) || defined(c_plusplus)
385 MagickExport const MimeInfo **GetMimeInfoList(const char *pattern,
386 size_t *number_aliases,ExceptionInfo *exception)
391 register const MimeInfo
400 assert(pattern != (char *) NULL);
401 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
402 assert(number_aliases != (size_t *) NULL);
404 p=GetMimeInfo((char *) NULL,(unsigned char *) "*",0,exception);
405 if (p == (const MimeInfo *) NULL)
406 return((const MimeInfo **) NULL);
407 aliases=(const MimeInfo **) AcquireQuantumMemory((size_t)
408 GetNumberOfElementsInLinkedList(mime_list)+1UL,sizeof(*aliases));
409 if (aliases == (const MimeInfo **) NULL)
410 return((const MimeInfo **) NULL);
414 LockSemaphoreInfo(mime_semaphore);
415 ResetLinkedListIterator(mime_list);
416 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
417 for (i=0; p != (const MimeInfo *) NULL; )
419 if ((p->stealth == MagickFalse) &&
420 (GlobExpression(p->type,pattern,MagickFalse) != MagickFalse))
422 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
424 UnlockSemaphoreInfo(mime_semaphore);
425 qsort((void *) aliases,(size_t) i,sizeof(*aliases),MimeInfoCompare);
426 aliases[i]=(MimeInfo *) NULL;
427 *number_aliases=(size_t) i;
432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
436 % G e t M i m e L i s t %
440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
442 % GetMimeList() returns any image format alias that matches the specified
445 % The format of the GetMimeList function is:
447 % char **GetMimeList(const char *pattern,size_t *number_aliases,
448 % ExceptionInfo *exception)
450 % A description of each parameter follows:
452 % o pattern: Specifies a pointer to a text string containing a pattern.
454 % o number_aliases: This integer returns the number of image format aliases
457 % o exception: return any errors or warnings in this structure.
461 #if defined(__cplusplus) || defined(c_plusplus)
465 static int MimeCompare(const void *x,const void *y)
473 return(strcasecmp(p,q));
476 #if defined(__cplusplus) || defined(c_plusplus)
480 MagickExport char **GetMimeList(const char *pattern,
481 size_t *number_aliases,ExceptionInfo *exception)
486 register const MimeInfo
493 Allocate configure list.
495 assert(pattern != (char *) NULL);
496 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
497 assert(number_aliases != (size_t *) NULL);
499 p=GetMimeInfo((char *) NULL,(unsigned char *) "*",0,exception);
500 if (p == (const MimeInfo *) NULL)
501 return((char **) NULL);
502 aliases=(char **) AcquireQuantumMemory((size_t)
503 GetNumberOfElementsInLinkedList(mime_list)+1UL,sizeof(*aliases));
504 if (aliases == (char **) NULL)
505 return((char **) NULL);
506 LockSemaphoreInfo(mime_semaphore);
507 ResetLinkedListIterator(mime_list);
508 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
509 for (i=0; p != (const MimeInfo *) NULL; )
511 if ((p->stealth == MagickFalse) &&
512 (GlobExpression(p->type,pattern,MagickFalse) != MagickFalse))
513 aliases[i++]=ConstantString(p->type);
514 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
516 UnlockSemaphoreInfo(mime_semaphore);
517 qsort((void *) aliases,(size_t) i,sizeof(*aliases),MimeCompare);
518 aliases[i]=(char *) NULL;
519 *number_aliases=(size_t) i;
524 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
528 % G e t M i m e D e s c r i p t i o n %
532 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
534 % GetMimeDescription() returns the mime type description.
536 % The format of the GetMimeDescription method is:
538 % const char *GetMimeDescription(const MimeInfo *mime_info)
540 % A description of each parameter follows:
542 % o mime_info: The magic info.
545 MagickExport const char *GetMimeDescription(const MimeInfo *mime_info)
547 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
548 assert(mime_info != (MimeInfo *) NULL);
549 assert(mime_info->signature == MagickSignature);
550 return(mime_info->description);
554 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
558 % G e t M i m e T y p e %
562 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
564 % GetMimeType() returns the mime type.
566 % The format of the GetMimeType method is:
568 % const char *GetMimeType(const MimeInfo *mime_info)
570 % A description of each parameter follows:
572 % o mime_info: The magic info.
575 MagickExport const char *GetMimeType(const MimeInfo *mime_info)
577 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
578 assert(mime_info != (MimeInfo *) NULL);
579 assert(mime_info->signature == MagickSignature);
580 return(mime_info->type);
584 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
588 + I n i t i a l i z e M i m e L i s t %
592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
594 % InitializeMimeList() initializes the mime list.
596 % The format of the InitializeMimeList method is:
598 % MagickBooleanType InitializeMimeList(ExceptionInfo *exception)
600 % A description of each parameter follows.
602 % o exception: return any errors or warnings in this structure.
605 static MagickBooleanType InitializeMimeList(ExceptionInfo *exception)
607 if ((mime_list == (LinkedListInfo *) NULL) &&
608 (instantiate_mime == MagickFalse))
610 if (mime_semaphore == (SemaphoreInfo *) NULL)
611 AcquireSemaphoreInfo(&mime_semaphore);
612 LockSemaphoreInfo(mime_semaphore);
613 if ((mime_list == (LinkedListInfo *) NULL) &&
614 (instantiate_mime == MagickFalse))
616 (void) LoadMimeLists(MimeFilename,exception);
617 instantiate_mime=MagickTrue;
619 UnlockSemaphoreInfo(mime_semaphore);
621 return(mime_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
625 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
629 % L i s t M i m e I n f o %
633 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
635 % ListMimeInfo() lists the magic info to a file.
637 % The format of the ListMimeInfo method is:
639 % MagickBooleanType ListMimeInfo(FILE *file,ExceptionInfo *exception)
641 % A description of each parameter follows.
643 % o file: An pointer to a FILE.
645 % o exception: return any errors or warnings in this structure.
648 MagickExport MagickBooleanType ListMimeInfo(FILE *file,ExceptionInfo *exception)
665 if (file == (const FILE *) NULL)
667 mime_info=GetMimeInfoList("*",&number_aliases,exception);
668 if (mime_info == (const MimeInfo **) NULL)
671 path=(const char *) NULL;
672 for (i=0; i < (ssize_t) number_aliases; i++)
674 if (mime_info[i]->stealth != MagickFalse)
676 if ((path == (const char *) NULL) ||
677 (strcasecmp(path,mime_info[i]->path) != 0))
679 if (mime_info[i]->path != (char *) NULL)
680 (void) FormatLocaleFile(file,"\nPath: %s\n\n",mime_info[i]->path);
681 (void) FormatLocaleFile(file,"Type Description\n");
682 (void) FormatLocaleFile(file,
683 "-------------------------------------------------"
684 "------------------------------\n");
686 path=mime_info[i]->path;
687 (void) FormatLocaleFile(file,"%s",mime_info[i]->type);
688 if (strlen(mime_info[i]->type) <= 25)
690 for (j=(ssize_t) strlen(mime_info[i]->type); j <= 27; j++)
691 (void) FormatLocaleFile(file," ");
695 (void) FormatLocaleFile(file,"\n");
696 for (j=0; j <= 27; j++)
697 (void) FormatLocaleFile(file," ");
699 if (mime_info[i]->description != (char *) NULL)
700 (void) FormatLocaleFile(file,"%s",mime_info[i]->description);
701 (void) FormatLocaleFile(file,"\n");
704 mime_info=(const MimeInfo **) RelinquishMagickMemory((void *) mime_info);
709 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
713 + L o a d M i m e L i s t %
717 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
719 % LoadMimeList() loads the magic configuration file which provides a mapping
720 % between magic attributes and a magic name.
722 % The format of the LoadMimeList method is:
724 % MagickBooleanType LoadMimeList(const char *xml,const char *filename,
725 % const size_t depth,ExceptionInfo *exception)
727 % A description of each parameter follows:
729 % o xml: The mime list in XML format.
731 % o filename: The mime list filename.
733 % o depth: depth of <include /> statements.
735 % o exception: return any errors or warnings in this structure.
738 static MagickBooleanType LoadMimeList(const char *xml,const char *filename,
739 const size_t depth,ExceptionInfo *exception)
745 *mime_info = (MimeInfo *) NULL;
756 Load the mime map file.
758 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
759 "Loading mime map \"%s\" ...",filename);
760 if (xml == (const char *) NULL)
762 if (mime_list == (LinkedListInfo *) NULL)
764 mime_list=NewLinkedList(0);
765 if (mime_list == (LinkedListInfo *) NULL)
767 ThrowFileException(exception,ResourceLimitError,
768 "MemoryAllocationFailed",filename);
772 mime_map=NewXMLTree(xml,exception);
773 if (mime_map == (XMLTreeInfo *) NULL)
776 include=GetXMLTreeChild(mime_map,"include");
777 while (include != (XMLTreeInfo *) NULL)
780 Process include element.
782 attribute=GetXMLTreeAttribute(include,"file");
783 if (attribute != (const char *) NULL)
786 (void) ThrowMagickException(exception,GetMagickModule(),
787 ConfigureError,"IncludeElementNestedTooDeeply","'%s'",filename);
794 GetPathComponent(filename,HeadPath,path);
796 (void) ConcatenateMagickString(path,DirectorySeparator,
798 if (*attribute == *DirectorySeparator)
799 (void) CopyMagickString(path,attribute,MaxTextExtent);
801 (void) ConcatenateMagickString(path,attribute,MaxTextExtent);
802 xml=FileToString(path,~0,exception);
803 if (xml != (char *) NULL)
805 status=LoadMimeList(xml,path,depth+1,exception);
806 xml=DestroyString(xml);
810 include=GetNextXMLTreeTag(include);
812 mime=GetXMLTreeChild(mime_map,"mime");
813 while (mime != (XMLTreeInfo *) NULL)
819 Process mime element.
821 mime_info=(MimeInfo *) AcquireMagickMemory(sizeof(*mime_info));
822 if (mime_info == (MimeInfo *) NULL)
823 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
824 (void) ResetMagickMemory(mime_info,0,sizeof(*mime_info));
825 mime_info->path=ConstantString(filename);
826 mime_info->signature=MagickSignature;
827 attribute=GetXMLTreeAttribute(mime,"data-type");
828 if (attribute != (const char *) NULL)
829 mime_info->data_type=(DataType) ParseCommandOption(MagickDataTypeOptions,
830 MagickTrue,attribute);
831 attribute=GetXMLTreeAttribute(mime,"description");
832 if (attribute != (const char *) NULL)
833 mime_info->description=ConstantString(attribute);
834 attribute=GetXMLTreeAttribute(mime,"endian");
835 if (attribute != (const char *) NULL)
836 mime_info->endian=(EndianType) ParseCommandOption(MagickEndianOptions,
837 MagickTrue,attribute);
838 attribute=GetXMLTreeAttribute(mime,"magic");
839 if (attribute != (const char *) NULL)
847 register unsigned char
850 token=AcquireString(attribute);
851 (void) SubstituteString((char **) &token,"<","<");
852 (void) SubstituteString((char **) &token,"&","&");
853 (void) SubstituteString((char **) &token,""","\"");
854 mime_info->magic=(unsigned char *) AcquireString(token);
856 for (p=token; *p != '\0'; )
861 if (isdigit((int) ((unsigned char) *p)) != 0)
866 *q++=(unsigned char) strtol(p,&end,8);
873 case 'b': *q='\b'; break;
874 case 'f': *q='\f'; break;
875 case 'n': *q='\n'; break;
876 case 'r': *q='\r'; break;
877 case 't': *q='\t'; break;
878 case 'v': *q='\v'; break;
879 case 'a': *q='a'; break;
880 case '?': *q='\?'; break;
881 default: *q=(unsigned char) (*p); break;
888 *q++=(unsigned char) (*p++);
891 token=DestroyString(token);
892 if (mime_info->data_type != StringData)
893 mime_info->value=(ssize_t) strtoul((char *) mime_info->magic,
896 attribute=GetXMLTreeAttribute(mime,"mask");
897 if (attribute != (const char *) NULL)
898 mime_info->mask=(ssize_t) strtoul(attribute,(char **) NULL,0);
899 attribute=GetXMLTreeAttribute(mime,"offset");
900 if (attribute != (const char *) NULL)
905 mime_info->offset=(MagickOffsetType) strtol(attribute,&c,0);
907 mime_info->extent=(size_t) strtol(c+1,(char **) NULL,0);
909 attribute=GetXMLTreeAttribute(mime,"pattern");
910 if (attribute != (const char *) NULL)
911 mime_info->pattern=ConstantString(attribute);
912 attribute=GetXMLTreeAttribute(mime,"priority");
913 if (attribute != (const char *) NULL)
914 mime_info->priority=(ssize_t) strtol(attribute,(char **) NULL,0);
915 attribute=GetXMLTreeAttribute(mime,"stealth");
916 mime_info->stealth=IsStringTrue(attribute);
917 attribute=GetXMLTreeAttribute(mime,"type");
918 if (attribute != (const char *) NULL)
919 mime_info->type=ConstantString(attribute);
920 status=AppendValueToLinkedList(mime_list,mime_info);
921 if (status == MagickFalse)
922 (void) ThrowMagickException(exception,GetMagickModule(),
923 ResourceLimitError,"MemoryAllocationFailed","'%s'",filename);
924 mime=GetNextXMLTreeTag(mime);
926 mime_map=DestroyXMLTree(mime_map);
931 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
935 % L o a d M i m e L i s t s %
939 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
941 % LoadMimeList() loads one or more magic configuration file which provides a
942 % mapping between magic attributes and a magic name.
944 % The format of the LoadMimeLists method is:
946 % MagickBooleanType LoadMimeLists(const char *filename,
947 % ExceptionInfo *exception)
949 % A description of each parameter follows:
951 % o filename: the font file name.
953 % o exception: return any errors or warnings in this structure.
956 MagickExport MagickBooleanType LoadMimeLists(const char *filename,
957 ExceptionInfo *exception)
959 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
960 return(LoadMimeList(MimeMap,"built-in",0,exception));
972 options=GetConfigureOptions(filename,exception);
973 option=(const StringInfo *) GetNextValueInLinkedList(options);
974 while (option != (const StringInfo *) NULL)
976 status|=LoadMimeList((const char *) GetStringInfoDatum(option),
977 GetStringInfoPath(option),0,exception);
978 option=(const StringInfo *) GetNextValueInLinkedList(options);
980 options=DestroyConfigureOptions(options);
981 if ((mime_list == (LinkedListInfo *) NULL) ||
982 (IsLinkedListEmpty(mime_list) != MagickFalse))
983 status|=LoadMimeList(MimeMap,"built-in",0,exception);
985 ClearMagickException(exception);
986 return(status != 0 ? MagickTrue : MagickFalse);
991 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
995 + M a g i c k T o M i m e %
999 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1001 % MagickToMime() returns the officially registered (or de facto) MIME
1002 % media-type corresponding to a magick string. If there is no registered
1003 % media-type, then the string "image/x-magick" (all lower case) is returned.
1004 % The returned string must be deallocated by the user.
1006 % The format of the MagickToMime method is:
1008 % char *MagickToMime(const char *magick)
1010 % A description of each parameter follows.
1012 % o magick: ImageMagick format specification "magick" tag.
1015 MagickExport char *MagickToMime(const char *magick)
1018 filename[MaxTextExtent],
1019 media[MaxTextExtent];
1027 (void) FormatLocaleString(filename,MaxTextExtent,"file.%s",magick);
1028 LocaleLower(filename);
1029 exception=AcquireExceptionInfo();
1030 mime_info=GetMimeInfo(filename,(unsigned char *) " ",1,exception);
1031 exception=DestroyExceptionInfo(exception);
1032 if (mime_info != (const MimeInfo *) NULL)
1033 return(ConstantString(GetMimeType(mime_info)));
1034 (void) FormatLocaleString(media,MaxTextExtent,"image/x-%s",magick);
1035 LocaleLower(media+8);
1036 return(ConstantString(media));
1040 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1044 + M i m e C o m p o n e n t G e n e s i s %
1048 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1050 % MimeComponentGenesis() instantiates the mime component.
1052 % The format of the MimeComponentGenesis method is:
1054 % MagickBooleanType MimeComponentGenesis(void)
1057 MagickPrivate MagickBooleanType MimeComponentGenesis(void)
1059 AcquireSemaphoreInfo(&mime_semaphore);
1064 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1068 + M i m e C o m p o n e n t T e r m i n u s %
1072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1074 % MimeComponentTerminus() destroys the mime component.
1076 % The format of the MimeComponentTerminus method is:
1078 % MimeComponentTerminus(void)
1082 static void *DestroyMimeElement(void *mime_info)
1087 p=(MimeInfo *) mime_info;
1088 if (p->magic != (unsigned char *) NULL)
1089 p->magic=(unsigned char *) RelinquishMagickMemory(p->magic);
1090 if (p->pattern != (char *) NULL)
1091 p->pattern=DestroyString(p->pattern);
1092 if (p->description != (char *) NULL)
1093 p->description=DestroyString(p->description);
1094 if (p->type != (char *) NULL)
1095 p->type=DestroyString(p->type);
1096 if (p->path != (char *) NULL)
1097 p->path=DestroyString(p->path);
1098 p=(MimeInfo *) RelinquishMagickMemory(p);
1099 return((void *) NULL);
1102 MagickPrivate void MimeComponentTerminus(void)
1104 if (mime_semaphore == (SemaphoreInfo *) NULL)
1105 AcquireSemaphoreInfo(&mime_semaphore);
1106 LockSemaphoreInfo(mime_semaphore);
1107 if (mime_list != (LinkedListInfo *) NULL)
1108 mime_list=DestroyLinkedList(mime_list,DestroyMimeElement);
1109 instantiate_mime=MagickFalse;
1110 UnlockSemaphoreInfo(mime_semaphore);
1111 DestroySemaphoreInfo(&mime_semaphore);