2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 % M M IIIII M M EEEEE %
9 % M M IIIII M M EEEEE %
12 % MagickCore Mime Methods %
18 % Copyright 1999-2009 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 + D e s t r o y M i m e F a c i l i t y %
138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
140 % DestroyMimeFacility() destroys the mime facility.
142 % The format of the DestroyMimeFacility method is:
144 % DestroyMimeFacility(void)
148 static void *DestroyMimeElement(void *mime_info)
153 p=(MimeInfo *) mime_info;
154 if (p->magic != (unsigned char *) NULL)
155 p->magic=(unsigned char *) RelinquishMagickMemory(p->magic);
156 if (p->pattern != (char *) NULL)
157 p->pattern=DestroyString(p->pattern);
158 if (p->description != (char *) NULL)
159 p->description=DestroyString(p->description);
160 if (p->type != (char *) NULL)
161 p->type=DestroyString(p->type);
162 if (p->path != (char *) NULL)
163 p->path=DestroyString(p->path);
164 p=(MimeInfo *) RelinquishMagickMemory(p);
165 return((void *) NULL);
168 MagickExport void DestroyMimeFacility(void)
170 AcquireSemaphoreInfo(&mime_semaphore);
171 if (mime_list != (LinkedListInfo *) NULL)
172 mime_list=DestroyLinkedList(mime_list,DestroyMimeElement);
173 instantiate_mime=MagickFalse;
174 RelinquishSemaphoreInfo(mime_semaphore);
175 DestroySemaphoreInfo(&mime_semaphore);
179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
183 + G e t M i m e I n f o %
187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
189 % GetMimeInfo() attempts to classify the content to identify which mime type
190 % is associated with the content, if any.
192 % The format of the GetMimeInfo method is:
194 % const MimeInfo *GetMimeInfo(const char *filename,
195 % const unsigned char *magic,const size_t length,
196 % ExceptionInfo *exception)
198 % A description of each parameter follows:
200 % o filename: If we cannot not classify the string, we attempt to classify
201 % based on the filename (e.g. *.pdf returns application/pdf).
203 % o magic: A binary string generally representing the first few characters
204 % of the image file or blob.
206 % o length: the length of the binary signature.
208 % o exception: return any errors or warnings in this structure.
211 MagickExport const MimeInfo *GetMimeInfo(const char *filename,
212 const unsigned char *magic,const size_t length,ExceptionInfo *exception)
223 register const MimeInfo
226 register const unsigned char
235 assert(exception != (ExceptionInfo *) NULL);
236 if ((mime_list == (LinkedListInfo *) NULL) ||
237 (instantiate_mime == MagickFalse))
238 if (InitializeMimeList(exception) == MagickFalse)
239 return((const MimeInfo *) NULL);
240 if ((mime_list == (LinkedListInfo *) NULL) ||
241 (IsLinkedListEmpty(mime_list) != MagickFalse))
242 return((const MimeInfo *) NULL);
243 if ((magic == (const unsigned char *) NULL) || (length == 0))
244 return((const MimeInfo *) GetValueFromLinkedList(mime_list,0));
246 return((const MimeInfo *) NULL);
250 mime_info=(const MimeInfo *) NULL;
252 AcquireSemaphoreInfo(&mime_semaphore);
253 ResetLinkedListIterator(mime_list);
254 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
255 while (p != (const MimeInfo *) NULL)
257 assert(p->offset >= 0);
258 if (mime_info != (const MimeInfo *) NULL)
259 if (p->priority > mime_info->priority)
261 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
264 if ((p->pattern != (char *) NULL) && (filename != (char *) NULL))
266 if (GlobExpression(filename,p->pattern,MagickFalse) != MagickFalse)
268 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
271 switch (p->data_type)
275 if ((size_t) (p->offset+4) > length)
281 if (p->value == value)
286 if ((p->value & p->mask) == value)
293 if ((size_t) (p->offset+4) > length)
297 if (p->endian == UndefinedEndian)
298 endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian;
299 if (endian == LSBEndian)
311 if (p->value == value)
316 if ((p->value & p->mask) == value)
323 if ((size_t) (p->offset+4) > length)
327 if (p->endian == UndefinedEndian)
328 endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian;
329 if (endian == LSBEndian)
345 if (p->value == value)
350 if ((p->value & p->mask) == value)
358 for (i=0; i <= (long) p->extent; i++)
360 if ((size_t) (p->offset+i+p->length) > length)
362 if (memcmp(magic+p->offset+i,p->magic,p->length) == 0)
371 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
373 if (p != (const MimeInfo *) NULL)
374 (void) InsertValueInLinkedList(mime_list,0,
375 RemoveElementByValueFromLinkedList(mime_list,p));
376 RelinquishSemaphoreInfo(mime_semaphore);
381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
385 % G e t M i m e I n f o L i s t %
389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
391 % GetMimeInfoList() returns any image aliases that match the specified
394 % The magic of the GetMimeInfoList function is:
396 % const MimeInfo **GetMimeInfoList(const char *pattern,
397 % unsigned long *number_aliases,ExceptionInfo *exception)
399 % A description of each parameter follows:
401 % o pattern: Specifies a pointer to a text string containing a pattern.
403 % o number_aliases: This integer returns the number of magics in the
406 % o exception: return any errors or warnings in this structure.
410 #if defined(__cplusplus) || defined(c_plusplus)
414 static int MimeInfoCompare(const void *x,const void *y)
420 p=(const MimeInfo **) x,
421 q=(const MimeInfo **) y;
422 if (strcasecmp((*p)->path,(*q)->path) == 0)
423 return(strcasecmp((*p)->type,(*q)->type));
424 return(strcasecmp((*p)->path,(*q)->path));
427 #if defined(__cplusplus) || defined(c_plusplus)
431 MagickExport const MimeInfo **GetMimeInfoList(const char *pattern,
432 unsigned long *number_aliases,ExceptionInfo *exception)
437 register const MimeInfo
446 assert(pattern != (char *) NULL);
447 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
448 assert(number_aliases != (unsigned long *) NULL);
450 p=GetMimeInfo((char *) NULL,(unsigned char *) "*",0,exception);
451 if (p == (const MimeInfo *) NULL)
452 return((const MimeInfo **) NULL);
453 aliases=(const MimeInfo **) AcquireQuantumMemory((size_t)
454 GetNumberOfElementsInLinkedList(mime_list)+1UL,sizeof(*aliases));
455 if (aliases == (const MimeInfo **) NULL)
456 return((const MimeInfo **) NULL);
460 AcquireSemaphoreInfo(&mime_semaphore);
461 ResetLinkedListIterator(mime_list);
462 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
463 for (i=0; p != (const MimeInfo *) NULL; )
465 if ((p->stealth == MagickFalse) &&
466 (GlobExpression(p->type,pattern,MagickFalse) != MagickFalse))
468 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
470 RelinquishSemaphoreInfo(mime_semaphore);
471 qsort((void *) aliases,(size_t) i,sizeof(*aliases),MimeInfoCompare);
472 aliases[i]=(MimeInfo *) NULL;
473 *number_aliases=(unsigned long) i;
478 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
482 % G e t M i m e L i s t %
486 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
488 % GetMimeList() returns any image format alias that matches the specified
491 % The format of the GetMimeList function is:
493 % char **GetMimeList(const char *pattern,unsigned long *number_aliases,
494 % ExceptionInfo *exception)
496 % A description of each parameter follows:
498 % o pattern: Specifies a pointer to a text string containing a pattern.
500 % o number_aliases: This integer returns the number of image format aliases
503 % o exception: return any errors or warnings in this structure.
507 #if defined(__cplusplus) || defined(c_plusplus)
511 static int MimeCompare(const void *x,const void *y)
519 return(strcasecmp(p,q));
522 #if defined(__cplusplus) || defined(c_plusplus)
526 MagickExport char **GetMimeList(const char *pattern,
527 unsigned long *number_aliases,ExceptionInfo *exception)
532 register const MimeInfo
539 Allocate configure list.
541 assert(pattern != (char *) NULL);
542 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
543 assert(number_aliases != (unsigned long *) NULL);
545 p=GetMimeInfo((char *) NULL,(unsigned char *) "*",0,exception);
546 if (p == (const MimeInfo *) NULL)
547 return((char **) NULL);
548 aliases=(char **) AcquireQuantumMemory((size_t)
549 GetNumberOfElementsInLinkedList(mime_list)+1UL,sizeof(*aliases));
550 if (aliases == (char **) NULL)
551 return((char **) NULL);
552 AcquireSemaphoreInfo(&mime_semaphore);
553 ResetLinkedListIterator(mime_list);
554 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
555 for (i=0; p != (const MimeInfo *) NULL; )
557 if ((p->stealth == MagickFalse) &&
558 (GlobExpression(p->type,pattern,MagickFalse) != MagickFalse))
559 aliases[i++]=ConstantString(p->type);
560 p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
562 RelinquishSemaphoreInfo(mime_semaphore);
563 qsort((void *) aliases,(size_t) i,sizeof(*aliases),MimeCompare);
564 aliases[i]=(char *) NULL;
565 *number_aliases=(unsigned long) i;
570 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
574 % G e t M i m e D e s c r i p t i o n %
578 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
580 % GetMimeDescription() returns the mime type description.
582 % The format of the GetMimeDescription method is:
584 % const char *GetMimeDescription(const MimeInfo *mime_info)
586 % A description of each parameter follows:
588 % o mime_info: The magic info.
591 MagickExport const char *GetMimeDescription(const MimeInfo *mime_info)
593 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
594 assert(mime_info != (MimeInfo *) NULL);
595 assert(mime_info->signature == MagickSignature);
596 return(mime_info->description);
600 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
604 % G e t M i m e T y p e %
608 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
610 % GetMimeType() returns the mime type.
612 % The format of the GetMimeType method is:
614 % const char *GetMimeType(const MimeInfo *mime_info)
616 % A description of each parameter follows:
618 % o mime_info: The magic info.
621 MagickExport const char *GetMimeType(const MimeInfo *mime_info)
623 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
624 assert(mime_info != (MimeInfo *) NULL);
625 assert(mime_info->signature == MagickSignature);
626 return(mime_info->type);
630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
634 + I n i t i a l i z e M i m e L i s t %
638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
640 % InitializeMimeList() initializes the mime list.
642 % The format of the InitializeMimeList method is:
644 % MagickBooleanType InitializeMimeList(ExceptionInfo *exception)
646 % A description of each parameter follows.
648 % o exception: return any errors or warnings in this structure.
651 static MagickBooleanType InitializeMimeList(ExceptionInfo *exception)
653 if ((mime_list == (LinkedListInfo *) NULL) &&
654 (instantiate_mime == MagickFalse))
656 AcquireSemaphoreInfo(&mime_semaphore);
657 if ((mime_list == (LinkedListInfo *) NULL) &&
658 (instantiate_mime == MagickFalse))
660 (void) LoadMimeLists(MimeFilename,exception);
661 instantiate_mime=MagickTrue;
663 RelinquishSemaphoreInfo(mime_semaphore);
665 return(mime_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
673 + I n s t a n t i a t e M i m e F a c i l i t y %
677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
679 % InstantiateMimeFacility() instantiates the mime facility.
681 % The format of the InstantiateMimeFacility method is:
683 % MagickBooleanType InstantiateMimeFacility(void)
686 MagickExport MagickBooleanType InstantiateMimeFacility(void)
688 AcquireSemaphoreInfo(&mime_semaphore);
689 RelinquishSemaphoreInfo(mime_semaphore);
694 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
698 % L i s t M i m e I n f o %
702 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
704 % ListMimeInfo() lists the magic info to a file.
706 % The format of the ListMimeInfo method is:
708 % MagickBooleanType ListMimeInfo(FILE *file,ExceptionInfo *exception)
710 % A description of each parameter follows.
712 % o file: An pointer to a FILE.
714 % o exception: return any errors or warnings in this structure.
717 MagickExport MagickBooleanType ListMimeInfo(FILE *file,ExceptionInfo *exception)
734 if (file == (const FILE *) NULL)
736 mime_info=GetMimeInfoList("*",&number_aliases,exception);
737 if (mime_info == (const MimeInfo **) NULL)
740 path=(const char *) NULL;
741 for (i=0; i < (long) number_aliases; i++)
743 if (mime_info[i]->stealth != MagickFalse)
745 if ((path == (const char *) NULL) ||
746 (strcasecmp(path,mime_info[i]->path) != 0))
748 if (mime_info[i]->path != (char *) NULL)
749 (void) fprintf(file,"\nPath: %s\n\n",mime_info[i]->path);
750 (void) fprintf(file,"Type Description\n");
751 (void) fprintf(file,"-------------------------------------------------"
752 "------------------------------\n");
754 path=mime_info[i]->path;
755 (void) fprintf(file,"%s",mime_info[i]->type);
756 if (strlen(mime_info[i]->type) <= 25)
758 for (j=(long) strlen(mime_info[i]->type); j <= 27; j++)
759 (void) fprintf(file," ");
763 (void) fprintf(file,"\n");
764 for (j=0; j <= 27; j++)
765 (void) fprintf(file," ");
767 if (mime_info[i]->description != (char *) NULL)
768 (void) fprintf(file,"%s",mime_info[i]->description);
769 (void) fprintf(file,"\n");
772 mime_info=(const MimeInfo **) RelinquishMagickMemory((void *) mime_info);
777 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
781 + L o a d M i m e L i s t %
785 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
787 % LoadMimeList() loads the magic configuration file which provides a mapping
788 % between magic attributes and a magic name.
790 % The format of the LoadMimeList method is:
792 % MagickBooleanType LoadMimeList(const char *xml,const char *filename,
793 % const unsigned long depth,ExceptionInfo *exception)
795 % A description of each parameter follows:
797 % o xml: The mime list in XML format.
799 % o filename: The mime list filename.
801 % o depth: depth of <include /> statements.
803 % o exception: return any errors or warnings in this structure.
806 static MagickBooleanType LoadMimeList(const char *xml,const char *filename,
807 const unsigned long depth,ExceptionInfo *exception)
813 *mime_info = (MimeInfo *) NULL;
824 Load the mime map file.
826 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
827 "Loading mime map \"%s\" ...",filename);
828 if (xml == (const char *) NULL)
830 if (mime_list == (LinkedListInfo *) NULL)
832 mime_list=NewLinkedList(0);
833 if (mime_list == (LinkedListInfo *) NULL)
835 ThrowFileException(exception,ResourceLimitError,
836 "MemoryAllocationFailed",filename);
840 mime_map=NewXMLTree(xml,exception);
841 if (mime_map == (XMLTreeInfo *) NULL)
844 include=GetXMLTreeChild(mime_map,"include");
845 while (include != (XMLTreeInfo *) NULL)
848 Process include element.
850 attribute=GetXMLTreeAttribute(include,"file");
851 if (attribute != (const char *) NULL)
854 (void) ThrowMagickException(exception,GetMagickModule(),
855 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",filename);
862 GetPathComponent(filename,HeadPath,path);
864 (void) ConcatenateMagickString(path,DirectorySeparator,
866 if (*attribute == *DirectorySeparator)
867 (void) CopyMagickString(path,attribute,MaxTextExtent);
869 (void) ConcatenateMagickString(path,attribute,MaxTextExtent);
870 xml=FileToString(path,~0,exception);
871 if (xml != (char *) NULL)
873 status=LoadMimeList(xml,path,depth+1,exception);
874 xml=DestroyString(xml);
878 include=GetNextXMLTreeTag(include);
880 mime=GetXMLTreeChild(mime_map,"mime");
881 while (mime != (XMLTreeInfo *) NULL)
887 Process mime element.
889 mime_info=(MimeInfo *) AcquireMagickMemory(sizeof(*mime_info));
890 if (mime_info == (MimeInfo *) NULL)
891 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
892 (void) ResetMagickMemory(mime_info,0,sizeof(*mime_info));
893 mime_info->path=ConstantString(filename);
894 mime_info->signature=MagickSignature;
895 attribute=GetXMLTreeAttribute(mime,"data-type");
896 if (attribute != (const char *) NULL)
897 mime_info->data_type=(DataType) ParseMagickOption(MagickDataTypeOptions,
898 MagickTrue,attribute);
899 attribute=GetXMLTreeAttribute(mime,"description");
900 if (attribute != (const char *) NULL)
901 mime_info->description=ConstantString(attribute);
902 attribute=GetXMLTreeAttribute(mime,"endian");
903 if (attribute != (const char *) NULL)
904 mime_info->endian=(EndianType) ParseMagickOption(MagickEndianOptions,
905 MagickTrue,attribute);
906 attribute=GetXMLTreeAttribute(mime,"magic");
907 if (attribute != (const char *) NULL)
915 register unsigned char
918 token=AcquireString(attribute);
919 (void) SubstituteString((char **) &token,"<","<");
920 (void) SubstituteString((char **) &token,"&","&");
921 (void) SubstituteString((char **) &token,""","\"");
922 mime_info->magic=(unsigned char *) AcquireString(token);
924 for (p=token; *p != '\0'; )
929 if (isdigit((int) ((unsigned char) *p)) != 0)
934 *q++=(unsigned char) strtol(p,&end,8);
941 case 'b': *q='\b'; break;
942 case 'f': *q='\f'; break;
943 case 'n': *q='\n'; break;
944 case 'r': *q='\r'; break;
945 case 't': *q='\t'; break;
946 case 'v': *q='\v'; break;
947 case 'a': *q='a'; break;
948 case '?': *q='\?'; break;
949 default: *q=(unsigned char) (*p); break;
956 *q++=(unsigned char) (*p++);
959 token=DestroyString(token);
960 if (mime_info->data_type != StringData)
961 mime_info->value=strtol((char *) mime_info->magic,(char **) NULL,0);
963 attribute=GetXMLTreeAttribute(mime,"mask");
964 if (attribute != (const char *) NULL)
965 mime_info->mask=strtol(attribute,(char **) NULL,0);
966 attribute=GetXMLTreeAttribute(mime,"offset");
967 if (attribute != (const char *) NULL)
972 mime_info->offset=(MagickOffsetType) strtol(attribute,&c,0);
974 mime_info->extent=(size_t) strtol(c+1,(char **) NULL,0);
976 attribute=GetXMLTreeAttribute(mime,"pattern");
977 if (attribute != (const char *) NULL)
978 mime_info->pattern=ConstantString(attribute);
979 attribute=GetXMLTreeAttribute(mime,"priority");
980 if (attribute != (const char *) NULL)
981 mime_info->priority=strtol(attribute,(char **) NULL,0);
982 attribute=GetXMLTreeAttribute(mime,"stealth");
983 if (attribute != (const char *) NULL)
984 mime_info->stealth=IsMagickTrue(attribute);
985 attribute=GetXMLTreeAttribute(mime,"type");
986 if (attribute != (const char *) NULL)
987 mime_info->type=ConstantString(attribute);
988 status=AppendValueToLinkedList(mime_list,mime_info);
989 if (status == MagickFalse)
990 (void) ThrowMagickException(exception,GetMagickModule(),
991 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
992 mime=GetNextXMLTreeTag(mime);
994 mime_map=DestroyXMLTree(mime_map);
999 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1003 % L o a d M i m e L i s t s %
1007 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1009 % LoadMimeList() loads one or more magic configuration file which provides a
1010 % mapping between magic attributes and a magic name.
1012 % The format of the LoadMimeLists method is:
1014 % MagickBooleanType LoadMimeLists(const char *filename,
1015 % ExceptionInfo *exception)
1017 % A description of each parameter follows:
1019 % o filename: the font file name.
1021 % o exception: return any errors or warnings in this structure.
1024 MagickExport MagickBooleanType LoadMimeLists(const char *filename,
1025 ExceptionInfo *exception)
1027 #if defined(MAGICKCORE_EMBEDDABLE_SUPPORT)
1028 return(LoadMimeList(MimeMap,"built-in",0,exception));
1040 options=GetConfigureOptions(filename,exception);
1041 option=(const StringInfo *) GetNextValueInLinkedList(options);
1042 while (option != (const StringInfo *) NULL)
1044 status|=LoadMimeList((const char *) GetStringInfoDatum(option),
1045 GetStringInfoPath(option),0,exception);
1046 option=(const StringInfo *) GetNextValueInLinkedList(options);
1048 options=DestroyConfigureOptions(options);
1049 if ((mime_list == (LinkedListInfo *) NULL) ||
1050 (IsLinkedListEmpty(mime_list) != MagickFalse))
1051 status|=LoadMimeList(MimeMap,"built-in",0,exception);
1053 ClearMagickException(exception);
1054 return(status != 0 ? MagickTrue : MagickFalse);
1059 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1063 + M a g i c k T o M i m e %
1067 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1069 % MagickToMime() returns the officially registered (or de facto) MIME
1070 % media-type corresponding to a magick string. If there is no registered
1071 % media-type, then the string "image/x-magick" (all lower case) is returned.
1072 % The returned string must be deallocated by the user.
1074 % The format of the MagickToMime method is:
1076 % char *MagickToMime(const char *magick)
1078 % A description of each parameter follows.
1080 % o magick: ImageMagick format specification "magick" tag.
1083 MagickExport char *MagickToMime(const char *magick)
1086 filename[MaxTextExtent],
1087 media[MaxTextExtent];
1095 (void) FormatMagickString(filename,MaxTextExtent,"file.%s",magick);
1096 LocaleLower(filename);
1097 exception=AcquireExceptionInfo();
1098 mime_info=GetMimeInfo(filename,(unsigned char *) " ",1,exception);
1099 exception=DestroyExceptionInfo(exception);
1100 if (mime_info != (const MimeInfo *) NULL)
1101 return(ConstantString(GetMimeType(mime_info)));
1102 (void) FormatMagickString(media,MaxTextExtent,"image/x-%s",magick);
1103 LocaleLower(media+8);
1104 return(ConstantString(media));