2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 % M M IIIII M M EEEEE %
9 % M M IIIII M M EEEEE %
12 % MagickCore Mime Methods %
18 % Copyright 1999-2011 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 "magick/studio.h"
41 #include "magick/blob.h"
42 #include "magick/client.h"
43 #include "magick/configure.h"
44 #include "magick/exception.h"
45 #include "magick/exception-private.h"
46 #include "magick/hashmap.h"
47 #include "magick/memory_.h"
48 #include "magick/mime.h"
49 #include "magick/mime-private.h"
50 #include "magick/option.h"
51 #include "magick/semaphore.h"
52 #include "magick/string_.h"
53 #include "magick/token.h"
54 #include "magick/utility.h"
55 #include "magick/xml-tree.h"
60 #define MimeFilename "mime.xml"
110 "<?xml version=\"1.0\"?>"
114 static LinkedListInfo
115 *mime_list = (LinkedListInfo *) NULL;
118 *mime_semaphore = (SemaphoreInfo *) NULL;
120 static volatile MagickBooleanType
121 instantiate_mime = MagickFalse;
124 Forward declarations.
126 static MagickBooleanType
127 InitializeMimeList(ExceptionInfo *);
130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134 + G e t M i m e I n f o %
138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
140 % GetMimeInfo() attempts to classify the content to identify which mime type
141 % is associated with the content, if any.
143 % The format of the GetMimeInfo method is:
145 % const MimeInfo *GetMimeInfo(const char *filename,
146 % const unsigned char *magic,const size_t length,
147 % ExceptionInfo *exception)
149 % A description of each parameter follows:
151 % o filename: If we cannot not classify the string, we attempt to classify
152 % based on the filename (e.g. *.pdf returns application/pdf).
154 % o magic: A binary string generally representing the first few characters
155 % of the image file or blob.
157 % o length: the length of the binary signature.
159 % o exception: return any errors or warnings in this structure.
162 MagickExport const MimeInfo *GetMimeInfo(const char *filename,
163 const unsigned char *magic,const size_t length,ExceptionInfo *exception)
171 register const MimeInfo
174 register const unsigned char
186 assert(exception != (ExceptionInfo *) NULL);
187 if ((mime_list == (LinkedListInfo *) NULL) ||
188 (instantiate_mime == MagickFalse))
189 if (InitializeMimeList(exception) == MagickFalse)
190 return((const MimeInfo *) NULL);
191 if ((mime_list == (LinkedListInfo *) NULL) ||
192 (IsLinkedListEmpty(mime_list) != MagickFalse))
193 return((const MimeInfo *) NULL);
194 if ((magic == (const unsigned char *) NULL) || (length == 0))
195 return((const MimeInfo *) GetValueFromLinkedList(mime_list,0));
197 return((const MimeInfo *) NULL);
201 mime_info=(const MimeInfo *) NULL;
203 LockSemaphoreInfo(mime_semaphore);
204 ResetLinkedListIterator(mime_list);
205 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
206 while (p != (const MimeInfo *) NULL)
208 assert(p->offset >= 0);
209 if (mime_info != (const MimeInfo *) NULL)
210 if (p->priority > mime_info->priority)
212 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
215 if ((p->pattern != (char *) NULL) && (filename != (char *) NULL))
217 if (GlobExpression(filename,p->pattern,MagickFalse) != MagickFalse)
219 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
222 switch (p->data_type)
226 if ((size_t) (p->offset+4) > length)
229 value=(ssize_t) (*q++);
232 if (p->value == value)
237 if ((p->value & p->mask) == value)
244 if ((size_t) (p->offset+4) > length)
248 if (p->endian == UndefinedEndian)
249 endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian;
250 if (endian == LSBEndian)
252 value=(ssize_t) (*q++);
257 value=(ssize_t) (*q++) << 8;
262 if (p->value == value)
267 if ((p->value & p->mask) == value)
274 if ((size_t) (p->offset+4) > length)
278 if (p->endian == UndefinedEndian)
279 endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian;
280 if (endian == LSBEndian)
282 value=(ssize_t) (*q++);
289 value=(ssize_t) (*q++) << 24;
296 if (p->value == value)
301 if ((p->value & p->mask) == value)
309 for (i=0; i <= (ssize_t) p->extent; i++)
311 if ((size_t) (p->offset+i+p->length) > length)
313 if (memcmp(magic+p->offset+i,p->magic,p->length) == 0)
322 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
324 if (p != (const MimeInfo *) NULL)
325 (void) InsertValueInLinkedList(mime_list,0,
326 RemoveElementByValueFromLinkedList(mime_list,p));
327 UnlockSemaphoreInfo(mime_semaphore);
332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
336 % G e t M i m e I n f o L i s t %
340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
342 % GetMimeInfoList() returns any image aliases that match the specified
345 % The magic of the GetMimeInfoList function is:
347 % const MimeInfo **GetMimeInfoList(const char *pattern,
348 % size_t *number_aliases,ExceptionInfo *exception)
350 % A description of each parameter follows:
352 % o pattern: Specifies a pointer to a text string containing a pattern.
354 % o number_aliases: This integer returns the number of magics in the
357 % o exception: return any errors or warnings in this structure.
361 #if defined(__cplusplus) || defined(c_plusplus)
365 static int MimeInfoCompare(const void *x,const void *y)
371 p=(const MimeInfo **) x,
372 q=(const MimeInfo **) y;
373 if (strcasecmp((*p)->path,(*q)->path) == 0)
374 return(strcasecmp((*p)->type,(*q)->type));
375 return(strcasecmp((*p)->path,(*q)->path));
378 #if defined(__cplusplus) || defined(c_plusplus)
382 MagickExport const MimeInfo **GetMimeInfoList(const char *pattern,
383 size_t *number_aliases,ExceptionInfo *exception)
388 register const MimeInfo
397 assert(pattern != (char *) NULL);
398 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
399 assert(number_aliases != (size_t *) NULL);
401 p=GetMimeInfo((char *) NULL,(unsigned char *) "*",0,exception);
402 if (p == (const MimeInfo *) NULL)
403 return((const MimeInfo **) NULL);
404 aliases=(const MimeInfo **) AcquireQuantumMemory((size_t)
405 GetNumberOfElementsInLinkedList(mime_list)+1UL,sizeof(*aliases));
406 if (aliases == (const MimeInfo **) NULL)
407 return((const MimeInfo **) NULL);
411 LockSemaphoreInfo(mime_semaphore);
412 ResetLinkedListIterator(mime_list);
413 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
414 for (i=0; p != (const MimeInfo *) NULL; )
416 if ((p->stealth == MagickFalse) &&
417 (GlobExpression(p->type,pattern,MagickFalse) != MagickFalse))
419 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
421 UnlockSemaphoreInfo(mime_semaphore);
422 qsort((void *) aliases,(size_t) i,sizeof(*aliases),MimeInfoCompare);
423 aliases[i]=(MimeInfo *) NULL;
424 *number_aliases=(size_t) i;
429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
433 % G e t M i m e L i s t %
437 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
439 % GetMimeList() returns any image format alias that matches the specified
442 % The format of the GetMimeList function is:
444 % char **GetMimeList(const char *pattern,size_t *number_aliases,
445 % ExceptionInfo *exception)
447 % A description of each parameter follows:
449 % o pattern: Specifies a pointer to a text string containing a pattern.
451 % o number_aliases: This integer returns the number of image format aliases
454 % o exception: return any errors or warnings in this structure.
458 #if defined(__cplusplus) || defined(c_plusplus)
462 static int MimeCompare(const void *x,const void *y)
470 return(strcasecmp(p,q));
473 #if defined(__cplusplus) || defined(c_plusplus)
477 MagickExport char **GetMimeList(const char *pattern,
478 size_t *number_aliases,ExceptionInfo *exception)
483 register const MimeInfo
490 Allocate configure list.
492 assert(pattern != (char *) NULL);
493 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
494 assert(number_aliases != (size_t *) NULL);
496 p=GetMimeInfo((char *) NULL,(unsigned char *) "*",0,exception);
497 if (p == (const MimeInfo *) NULL)
498 return((char **) NULL);
499 aliases=(char **) AcquireQuantumMemory((size_t)
500 GetNumberOfElementsInLinkedList(mime_list)+1UL,sizeof(*aliases));
501 if (aliases == (char **) NULL)
502 return((char **) NULL);
503 LockSemaphoreInfo(mime_semaphore);
504 ResetLinkedListIterator(mime_list);
505 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
506 for (i=0; p != (const MimeInfo *) NULL; )
508 if ((p->stealth == MagickFalse) &&
509 (GlobExpression(p->type,pattern,MagickFalse) != MagickFalse))
510 aliases[i++]=ConstantString(p->type);
511 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
513 UnlockSemaphoreInfo(mime_semaphore);
514 qsort((void *) aliases,(size_t) i,sizeof(*aliases),MimeCompare);
515 aliases[i]=(char *) NULL;
516 *number_aliases=(size_t) i;
521 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
525 % G e t M i m e D e s c r i p t i o n %
529 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
531 % GetMimeDescription() returns the mime type description.
533 % The format of the GetMimeDescription method is:
535 % const char *GetMimeDescription(const MimeInfo *mime_info)
537 % A description of each parameter follows:
539 % o mime_info: The magic info.
542 MagickExport const char *GetMimeDescription(const MimeInfo *mime_info)
544 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
545 assert(mime_info != (MimeInfo *) NULL);
546 assert(mime_info->signature == MagickSignature);
547 return(mime_info->description);
551 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
555 % G e t M i m e T y p e %
559 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
561 % GetMimeType() returns the mime type.
563 % The format of the GetMimeType method is:
565 % const char *GetMimeType(const MimeInfo *mime_info)
567 % A description of each parameter follows:
569 % o mime_info: The magic info.
572 MagickExport const char *GetMimeType(const MimeInfo *mime_info)
574 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
575 assert(mime_info != (MimeInfo *) NULL);
576 assert(mime_info->signature == MagickSignature);
577 return(mime_info->type);
581 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
585 + I n i t i a l i z e M i m e L i s t %
589 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
591 % InitializeMimeList() initializes the mime list.
593 % The format of the InitializeMimeList method is:
595 % MagickBooleanType InitializeMimeList(ExceptionInfo *exception)
597 % A description of each parameter follows.
599 % o exception: return any errors or warnings in this structure.
602 static MagickBooleanType InitializeMimeList(ExceptionInfo *exception)
604 if ((mime_list == (LinkedListInfo *) NULL) &&
605 (instantiate_mime == MagickFalse))
607 if (mime_semaphore == (SemaphoreInfo *) NULL)
608 AcquireSemaphoreInfo(&mime_semaphore);
609 LockSemaphoreInfo(mime_semaphore);
610 if ((mime_list == (LinkedListInfo *) NULL) &&
611 (instantiate_mime == MagickFalse))
613 (void) LoadMimeLists(MimeFilename,exception);
614 instantiate_mime=MagickTrue;
616 UnlockSemaphoreInfo(mime_semaphore);
618 return(mime_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
622 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
626 % L i s t M i m e I n f o %
630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
632 % ListMimeInfo() lists the magic info to a file.
634 % The format of the ListMimeInfo method is:
636 % MagickBooleanType ListMimeInfo(FILE *file,ExceptionInfo *exception)
638 % A description of each parameter follows.
640 % o file: An pointer to a FILE.
642 % o exception: return any errors or warnings in this structure.
645 MagickExport MagickBooleanType ListMimeInfo(FILE *file,ExceptionInfo *exception)
662 if (file == (const FILE *) NULL)
664 mime_info=GetMimeInfoList("*",&number_aliases,exception);
665 if (mime_info == (const MimeInfo **) NULL)
668 path=(const char *) NULL;
669 for (i=0; i < (ssize_t) number_aliases; i++)
671 if (mime_info[i]->stealth != MagickFalse)
673 if ((path == (const char *) NULL) ||
674 (strcasecmp(path,mime_info[i]->path) != 0))
676 if (mime_info[i]->path != (char *) NULL)
677 (void) FormatLocaleFile(file,"\nPath: %s\n\n",mime_info[i]->path);
678 (void) FormatLocaleFile(file,"Type Description\n");
679 (void) FormatLocaleFile(file,
680 "-------------------------------------------------"
681 "------------------------------\n");
683 path=mime_info[i]->path;
684 (void) FormatLocaleFile(file,"%s",mime_info[i]->type);
685 if (strlen(mime_info[i]->type) <= 25)
687 for (j=(ssize_t) strlen(mime_info[i]->type); j <= 27; j++)
688 (void) FormatLocaleFile(file," ");
692 (void) FormatLocaleFile(file,"\n");
693 for (j=0; j <= 27; j++)
694 (void) FormatLocaleFile(file," ");
696 if (mime_info[i]->description != (char *) NULL)
697 (void) FormatLocaleFile(file,"%s",mime_info[i]->description);
698 (void) FormatLocaleFile(file,"\n");
701 mime_info=(const MimeInfo **) RelinquishMagickMemory((void *) mime_info);
706 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
710 + L o a d M i m e L i s t %
714 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
716 % LoadMimeList() loads the magic configuration file which provides a mapping
717 % between magic attributes and a magic name.
719 % The format of the LoadMimeList method is:
721 % MagickBooleanType LoadMimeList(const char *xml,const char *filename,
722 % const size_t depth,ExceptionInfo *exception)
724 % A description of each parameter follows:
726 % o xml: The mime list in XML format.
728 % o filename: The mime list filename.
730 % o depth: depth of <include /> statements.
732 % o exception: return any errors or warnings in this structure.
735 static MagickBooleanType LoadMimeList(const char *xml,const char *filename,
736 const size_t depth,ExceptionInfo *exception)
742 *mime_info = (MimeInfo *) NULL;
753 Load the mime map file.
755 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
756 "Loading mime map \"%s\" ...",filename);
757 if (xml == (const char *) NULL)
759 if (mime_list == (LinkedListInfo *) NULL)
761 mime_list=NewLinkedList(0);
762 if (mime_list == (LinkedListInfo *) NULL)
764 ThrowFileException(exception,ResourceLimitError,
765 "MemoryAllocationFailed",filename);
769 mime_map=NewXMLTree(xml,exception);
770 if (mime_map == (XMLTreeInfo *) NULL)
773 include=GetXMLTreeChild(mime_map,"include");
774 while (include != (XMLTreeInfo *) NULL)
777 Process include element.
779 attribute=GetXMLTreeAttribute(include,"file");
780 if (attribute != (const char *) NULL)
783 (void) ThrowMagickException(exception,GetMagickModule(),
784 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",filename);
791 GetPathComponent(filename,HeadPath,path);
793 (void) ConcatenateMagickString(path,DirectorySeparator,
795 if (*attribute == *DirectorySeparator)
796 (void) CopyMagickString(path,attribute,MaxTextExtent);
798 (void) ConcatenateMagickString(path,attribute,MaxTextExtent);
799 xml=FileToString(path,~0,exception);
800 if (xml != (char *) NULL)
802 status=LoadMimeList(xml,path,depth+1,exception);
803 xml=DestroyString(xml);
807 include=GetNextXMLTreeTag(include);
809 mime=GetXMLTreeChild(mime_map,"mime");
810 while (mime != (XMLTreeInfo *) NULL)
816 Process mime element.
818 mime_info=(MimeInfo *) AcquireMagickMemory(sizeof(*mime_info));
819 if (mime_info == (MimeInfo *) NULL)
820 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
821 (void) ResetMagickMemory(mime_info,0,sizeof(*mime_info));
822 mime_info->path=ConstantString(filename);
823 mime_info->signature=MagickSignature;
824 attribute=GetXMLTreeAttribute(mime,"data-type");
825 if (attribute != (const char *) NULL)
826 mime_info->data_type=(DataType) ParseCommandOption(MagickDataTypeOptions,
827 MagickTrue,attribute);
828 attribute=GetXMLTreeAttribute(mime,"description");
829 if (attribute != (const char *) NULL)
830 mime_info->description=ConstantString(attribute);
831 attribute=GetXMLTreeAttribute(mime,"endian");
832 if (attribute != (const char *) NULL)
833 mime_info->endian=(EndianType) ParseCommandOption(MagickEndianOptions,
834 MagickTrue,attribute);
835 attribute=GetXMLTreeAttribute(mime,"magic");
836 if (attribute != (const char *) NULL)
844 register unsigned char
847 token=AcquireString(attribute);
848 (void) SubstituteString((char **) &token,"<","<");
849 (void) SubstituteString((char **) &token,"&","&");
850 (void) SubstituteString((char **) &token,""","\"");
851 mime_info->magic=(unsigned char *) AcquireString(token);
853 for (p=token; *p != '\0'; )
858 if (isdigit((int) ((unsigned char) *p)) != 0)
863 *q++=(unsigned char) strtol(p,&end,8);
870 case 'b': *q='\b'; break;
871 case 'f': *q='\f'; break;
872 case 'n': *q='\n'; break;
873 case 'r': *q='\r'; break;
874 case 't': *q='\t'; break;
875 case 'v': *q='\v'; break;
876 case 'a': *q='a'; break;
877 case '?': *q='\?'; break;
878 default: *q=(unsigned char) (*p); break;
885 *q++=(unsigned char) (*p++);
888 token=DestroyString(token);
889 if (mime_info->data_type != StringData)
890 mime_info->value=(ssize_t) strtoul((char *) mime_info->magic,
893 attribute=GetXMLTreeAttribute(mime,"mask");
894 if (attribute != (const char *) NULL)
895 mime_info->mask=(ssize_t) strtoul(attribute,(char **) NULL,0);
896 attribute=GetXMLTreeAttribute(mime,"offset");
897 if (attribute != (const char *) NULL)
902 mime_info->offset=(MagickOffsetType) strtol(attribute,&c,0);
904 mime_info->extent=(size_t) strtol(c+1,(char **) NULL,0);
906 attribute=GetXMLTreeAttribute(mime,"pattern");
907 if (attribute != (const char *) NULL)
908 mime_info->pattern=ConstantString(attribute);
909 attribute=GetXMLTreeAttribute(mime,"priority");
910 if (attribute != (const char *) NULL)
911 mime_info->priority=(ssize_t) strtol(attribute,(char **) NULL,0);
912 attribute=GetXMLTreeAttribute(mime,"stealth");
913 if (attribute != (const char *) NULL)
914 mime_info->stealth=IsMagickTrue(attribute);
915 attribute=GetXMLTreeAttribute(mime,"type");
916 if (attribute != (const char *) NULL)
917 mime_info->type=ConstantString(attribute);
918 status=AppendValueToLinkedList(mime_list,mime_info);
919 if (status == MagickFalse)
920 (void) ThrowMagickException(exception,GetMagickModule(),
921 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
922 mime=GetNextXMLTreeTag(mime);
924 mime_map=DestroyXMLTree(mime_map);
929 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
933 % L o a d M i m e L i s t s %
937 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
939 % LoadMimeList() loads one or more magic configuration file which provides a
940 % mapping between magic attributes and a magic name.
942 % The format of the LoadMimeLists method is:
944 % MagickBooleanType LoadMimeLists(const char *filename,
945 % ExceptionInfo *exception)
947 % A description of each parameter follows:
949 % o filename: the font file name.
951 % o exception: return any errors or warnings in this structure.
954 MagickExport MagickBooleanType LoadMimeLists(const char *filename,
955 ExceptionInfo *exception)
957 #if defined(MAGICKCORE_EMBEDDABLE_SUPPORT)
958 return(LoadMimeList(MimeMap,"built-in",0,exception));
970 options=GetConfigureOptions(filename,exception);
971 option=(const StringInfo *) GetNextValueInLinkedList(options);
972 while (option != (const StringInfo *) NULL)
974 status|=LoadMimeList((const char *) GetStringInfoDatum(option),
975 GetStringInfoPath(option),0,exception);
976 option=(const StringInfo *) GetNextValueInLinkedList(options);
978 options=DestroyConfigureOptions(options);
979 if ((mime_list == (LinkedListInfo *) NULL) ||
980 (IsLinkedListEmpty(mime_list) != MagickFalse))
981 status|=LoadMimeList(MimeMap,"built-in",0,exception);
983 ClearMagickException(exception);
984 return(status != 0 ? MagickTrue : MagickFalse);
989 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
993 + M a g i c k T o M i m e %
997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
999 % MagickToMime() returns the officially registered (or de facto) MIME
1000 % media-type corresponding to a magick string. If there is no registered
1001 % media-type, then the string "image/x-magick" (all lower case) is returned.
1002 % The returned string must be deallocated by the user.
1004 % The format of the MagickToMime method is:
1006 % char *MagickToMime(const char *magick)
1008 % A description of each parameter follows.
1010 % o magick: ImageMagick format specification "magick" tag.
1013 MagickExport char *MagickToMime(const char *magick)
1016 filename[MaxTextExtent],
1017 media[MaxTextExtent];
1025 (void) FormatLocaleString(filename,MaxTextExtent,"file.%s",magick);
1026 LocaleLower(filename);
1027 exception=AcquireExceptionInfo();
1028 mime_info=GetMimeInfo(filename,(unsigned char *) " ",1,exception);
1029 exception=DestroyExceptionInfo(exception);
1030 if (mime_info != (const MimeInfo *) NULL)
1031 return(ConstantString(GetMimeType(mime_info)));
1032 (void) FormatLocaleString(media,MaxTextExtent,"image/x-%s",magick);
1033 LocaleLower(media+8);
1034 return(ConstantString(media));
1038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1042 + M i m e C o m p o n e n t G e n e s i s %
1046 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1048 % MimeComponentGenesis() instantiates the mime component.
1050 % The format of the MimeComponentGenesis method is:
1052 % MagickBooleanType MimeComponentGenesis(void)
1055 MagickExport MagickBooleanType MimeComponentGenesis(void)
1057 AcquireSemaphoreInfo(&mime_semaphore);
1062 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1066 + M i m e C o m p o n e n t T e r m i n u s %
1070 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1072 % MimeComponentTerminus() destroys the mime component.
1074 % The format of the MimeComponentTerminus method is:
1076 % MimeComponentTerminus(void)
1080 static void *DestroyMimeElement(void *mime_info)
1085 p=(MimeInfo *) mime_info;
1086 if (p->magic != (unsigned char *) NULL)
1087 p->magic=(unsigned char *) RelinquishMagickMemory(p->magic);
1088 if (p->pattern != (char *) NULL)
1089 p->pattern=DestroyString(p->pattern);
1090 if (p->description != (char *) NULL)
1091 p->description=DestroyString(p->description);
1092 if (p->type != (char *) NULL)
1093 p->type=DestroyString(p->type);
1094 if (p->path != (char *) NULL)
1095 p->path=DestroyString(p->path);
1096 p=(MimeInfo *) RelinquishMagickMemory(p);
1097 return((void *) NULL);
1100 MagickExport void MimeComponentTerminus(void)
1102 if (mime_semaphore == (SemaphoreInfo *) NULL)
1103 AcquireSemaphoreInfo(&mime_semaphore);
1104 LockSemaphoreInfo(mime_semaphore);
1105 if (mime_list != (LinkedListInfo *) NULL)
1106 mime_list=DestroyLinkedList(mime_list,DestroyMimeElement);
1107 instantiate_mime=MagickFalse;
1108 UnlockSemaphoreInfo(mime_semaphore);
1109 DestroySemaphoreInfo(&mime_semaphore);