MagickCore 7.0.10
mime.c
Go to the documentation of this file.
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% M M IIIII M M EEEEE %
6% MM MM I MM MM E %
7% M M M I M M M EEE %
8% M M I M M E %
9% M M IIIII M M EEEEE %
10% %
11% %
12% ImageMagick Mime Methods %
13% %
14% Software Design %
15% July 2000 %
16% %
17% %
18% Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization %
19% dedicated to making software imaging solutions freely available. %
20% %
21% You may not use this file except in compliance with the License. You may %
22% obtain a copy of the License at %
23% %
24% https://imagemagick.org/script/license.php %
25% %
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. %
31% %
32%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33%
34%
35*/
36
37/*
38 Include declarations.
39*/
40#include "wizard/studio.h"
41#include "wizard/blob.h"
42#include "wizard/client.h"
43#include "wizard/configure.h"
44#include "wizard/exception.h"
46#include "wizard/hashmap.h"
47#include "wizard/memory_.h"
48#include "wizard/mime.h"
49#include "wizard/mime-private.h"
50#include "wizard/option.h"
51#include "wizard/semaphore.h"
52#include "wizard/string_.h"
53#include "wizard/token.h"
54#include "wizard/utility.h"
55#include "wizard/xml-tree.h"
57
58/*
59 Define declarations.
60*/
61#define MimeFilename "mime.xml"
62
63/*
64 Typedef declaration.
65*/
67{
68 char
73
74 ssize_t
76
79
80 size_t
82
85
86 ssize_t
89
92
93 size_t
95
96 unsigned char
98
101
102 size_t
104};
105
106/*
107 Static declarations.
108*/
109static const char
110 *MimeMap = (char *)
111 "<?xml version=\"1.0\"?>"
112 "<mimemap>"
113 "</mimemap>";
114
115static LinkedListInfo
117
118static SemaphoreInfo
120
121/*
122 Forward declarations.
123*/
126 LoadMimeCache(LinkedListInfo *,const char *,const char *,const size_t,
127 ExceptionInfo *);
128
129/*
130%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
131% %
132% %
133% %
134% A c q u i r e M i m e C a c h e %
135% %
136% %
137% %
138%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139%
140% AcquireMimeCache() caches one or more magic configurations which provides
141% a mapping between magic attributes and a magic name.
142%
143% The format of the AcquireMimeCache method is:
144%
145% LinkedListInfo *AcquireMimeCache(const char *filename,
146% ExceptionInfo *exception)
147%
148% A description of each parameter follows:
149%
150% o filename: The font file name.
151%
152% o exception: Return any errors or warnings in this structure.
153%
154*/
155static LinkedListInfo *AcquireMimeCache(const char *filename,
156 ExceptionInfo *exception)
157{
159 *mime_cache;
160
162 status;
163
165 if (mime_cache == (LinkedListInfo *) NULL)
166 ThrowFatalException(ResourceFatalError,"memory allocation failed `%s`");
167 status=WizardTrue;
168#if !defined(WIZARDSTOOLKIT_EMBEDDABLE_SUPPORT)
169 {
170 const StringInfo
171 *option;
172
174 *options;
175
176 options=GetConfigureOptions(filename,exception);
177 option=(const StringInfo *) GetNextValueInLinkedList(options);
178 while (option != (const StringInfo *) NULL)
179 {
180 status&=LoadMimeCache(mime_cache,(const char *)
181 GetStringInfoDatum(option),GetStringInfoPath(option),0,exception);
182 option=(const StringInfo *) GetNextValueInLinkedList(options);
183 }
184 options=DestroyConfigureOptions(options);
185 }
186#endif
188 status&=LoadMimeCache(mime_cache,MimeMap,"built-in",0,exception);
189 return(mime_cache);
190}
191
192/*
193%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
194% %
195% %
196% %
197+ G e t M i m e I n f o %
198% %
199% %
200% %
201%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
202%
203% GetMimeInfo() attempts to classify the content to identify which mime type
204% is associated with the content, if any.
205%
206% The format of the GetMimeInfo method is:
207%
208% const MimeInfo *GetMimeInfo(const char *filename,
209% const unsigned char *magic,const size_t length,
210% ExceptionInfo *exception)
211%
212% A description of each parameter follows:
213%
214% o filename: If we cannot not classify the string, we attempt to classify
215% based on the filename (e.g. *.pdf returns application/pdf).
216%
217% o magic: A binary string generally representing the first few characters
218% of the image file or blob.
219%
220% o length: The length of the binary signature.
221%
222% o exception: Return any errors or warnings in this structure.
223%
224*/
225WizardExport const MimeInfo *GetMimeInfo(const char *filename,
226 const unsigned char *magic,const size_t length,ExceptionInfo *exception)
227{
228 const MimeInfo
229 *mime_info;
230
232 endian;
233
234 const MimeInfo
235 *p;
236
237 const unsigned char
238 *q;
239
240 ssize_t
241 i;
242
243 size_t
244 lsb_first;
245
246 ssize_t
247 value;
248
249 assert(exception != (ExceptionInfo *) NULL);
250 if (IsMimeCacheInstantiated(exception) == WizardFalse)
251 return((const MimeInfo *) NULL);
252 /*
253 Search for requested mime type.
254 */
255 mime_info=(const MimeInfo *) NULL;
256 lsb_first=1;
260 if ((magic == (const unsigned char *) NULL) || (length == 0))
261 {
263 return(p);
264 }
265 while (p != (const MimeInfo *) NULL)
266 {
267 assert(p->offset >= 0);
268 if (mime_info != (const MimeInfo *) NULL)
269 if (p->priority > mime_info->priority)
270 {
272 continue;
273 }
274 if ((p->pattern != (char *) NULL) && (filename != (char *) NULL))
275 {
276 if (GlobExpression(filename,p->pattern,WizardFalse) != WizardFalse)
277 mime_info=p;
279 continue;
280 }
281 switch (p->data_type)
282 {
283 case ByteData:
284 {
285 if ((size_t) (p->offset+4) > length)
286 break;
287 q=magic+p->offset;
288 value=(ssize_t) (*q++);
289 if (p->mask == 0)
290 {
291 if (p->value == value)
292 mime_info=p;
293 }
294 else
295 {
296 if ((p->value & p->mask) == value)
297 mime_info=p;
298 }
299 break;
300 }
301 case ShortData:
302 {
303 if ((size_t) (p->offset+4) > length)
304 break;
305 q=magic+p->offset;
306 endian=p->endian;
307 if (p->endian == UndefinedEndian)
308 endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian;
309 if (endian == LSBEndian)
310 {
311 value=(ssize_t) (*q++);
312 value|=(*q++) << 8;
313 }
314 else
315 {
316 value=(ssize_t) (*q++) << 8;
317 value|=(*q++);
318 }
319 if (p->mask == 0)
320 {
321 if (p->value == value)
322 mime_info=p;
323 }
324 else
325 {
326 if ((p->value & p->mask) == value)
327 mime_info=p;
328 }
329 break;
330 }
331 case LongData:
332 {
333 if ((size_t) (p->offset+4) > length)
334 break;
335 q=magic+p->offset;
336 endian=p->endian;
337 if (p->endian == UndefinedEndian)
338 endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian;
339 if (endian == LSBEndian)
340 {
341 value=(ssize_t) (*q++);
342 value|=((ssize_t) *q++) << 8;
343 value|=((ssize_t) *q++) << 16;
344 value|=((ssize_t) *q++) << 24;
345 }
346 else
347 {
348 value=(ssize_t) (*q++) << 24;
349 value|=((ssize_t) *q++) << 16;
350 value|=((ssize_t) *q++) << 8;
351 value|=((ssize_t) *q++);
352 }
353 if (p->mask == 0)
354 {
355 if (p->value == value)
356 mime_info=p;
357 }
358 else
359 {
360 if ((p->value & p->mask) == value)
361 mime_info=p;
362 }
363 break;
364 }
365 case StringData:
366 default:
367 {
368 for (i=0; i <= (ssize_t) p->extent; i++)
369 {
370 if ((size_t) (p->offset+i+p->length) > length)
371 break;
372 if (memcmp(magic+p->offset+i,p->magic,p->length) == 0)
373 {
374 mime_info=p;
375 break;
376 }
377 }
378 break;
379 }
380 }
382 }
383 if (mime_info != (const MimeInfo *) NULL)
387 return(mime_info);
388}
389
390/*
391%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
392% %
393% %
394% %
395% G e t M i m e I n f o L i s t %
396% %
397% %
398% %
399%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
400%
401% GetMimeInfoList() returns any image aliases that match the specified
402% pattern.
403%
404% The magic of the GetMimeInfoList function is:
405%
406% const MimeInfo **GetMimeInfoList(const char *pattern,
407% size_t *number_aliases,ExceptionInfo *exception)
408%
409% A description of each parameter follows:
410%
411% o pattern: Specifies a pointer to a text string containing a pattern.
412%
413% o number_aliases: This integer returns the number of magics in the
414% list.
415%
416% o exception: Return any errors or warnings in this structure.
417%
418*/
419
420#if defined(__cplusplus) || defined(c_plusplus)
421extern "C" {
422#endif
423
424static int MimeInfoCompare(const void *x,const void *y)
425{
426 const MimeInfo
427 **p,
428 **q;
429
430 p=(const MimeInfo **) x,
431 q=(const MimeInfo **) y;
432 if (strcasecmp((*p)->path,(*q)->path) == 0)
433 return(strcasecmp((*p)->type,(*q)->type));
434 return(strcasecmp((*p)->path,(*q)->path));
435}
436
437#if defined(__cplusplus) || defined(c_plusplus)
438}
439#endif
440
441WizardExport const MimeInfo **GetMimeInfoList(const char *pattern,
442 size_t *number_aliases,ExceptionInfo *exception)
443{
444 const MimeInfo
445 **aliases;
446
447 const MimeInfo
448 *p;
449
450 ssize_t
451 i;
452
453 /*
454 Allocate mime list.
455 */
456 assert(pattern != (char *) NULL);
457 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",pattern);
458 assert(number_aliases != (size_t *) NULL);
459 *number_aliases=0;
460 p=GetMimeInfo((char *) NULL,(unsigned char *) "*",0,exception);
461 if (p == (const MimeInfo *) NULL)
462 return((const MimeInfo **) NULL);
463 aliases=(const MimeInfo **) AcquireQuantumMemory((size_t)
464 GetNumberOfElementsInLinkedList(mime_cache)+1UL,sizeof(*aliases));
465 if (aliases == (const MimeInfo **) NULL)
466 return((const MimeInfo **) NULL);
467 /*
468 Generate mime list.
469 */
473 for (i=0; p != (const MimeInfo *) NULL; )
474 {
475 if ((p->stealth == WizardFalse) &&
477 aliases[i++]=p;
479 }
481 qsort((void *) aliases,(size_t) i,sizeof(*aliases),MimeInfoCompare);
482 aliases[i]=(MimeInfo *) NULL;
483 *number_aliases=(size_t) i;
484 return(aliases);
485}
486
487/*
488%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
489% %
490% %
491% %
492% G e t M i m e L i s t %
493% %
494% %
495% %
496%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
497%
498% GetMimeList() returns any image format aliases that match the specified
499% pattern.
500%
501% The format of the GetMimeList function is:
502%
503% char **GetMimeList(const char *pattern,size_t *number_aliases,
504% ExceptionInfo *exception)
505%
506% A description of each parameter follows:
507%
508% o pattern: Specifies a pointer to a text string containing a pattern.
509%
510% o number_aliases: This integer returns the number of image format aliases
511% in the list.
512%
513% o exception: Return any errors or warnings in this structure.
514%
515*/
516
517#if defined(__cplusplus) || defined(c_plusplus)
518extern "C" {
519#endif
520
521static int MimeCompare(const void *x,const void *y)
522{
523 char
524 *p,
525 *q;
526
527 p=(char *) x;
528 q=(char *) y;
529 return(strcasecmp(p,q));
530}
531
532#if defined(__cplusplus) || defined(c_plusplus)
533}
534#endif
535
536WizardExport char **GetMimeList(const char *pattern,
537 size_t *number_aliases,ExceptionInfo *exception)
538{
539 char
540 **aliases;
541
542 const MimeInfo
543 *p;
544
545 ssize_t
546 i;
547
548 /*
549 Allocate configure list.
550 */
551 assert(pattern != (char *) NULL);
552 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",pattern);
553 assert(number_aliases != (size_t *) NULL);
554 *number_aliases=0;
555 p=GetMimeInfo((char *) NULL,(unsigned char *) "*",0,exception);
556 if (p == (const MimeInfo *) NULL)
557 return((char **) NULL);
558 aliases=(char **) AcquireQuantumMemory((size_t)
559 GetNumberOfElementsInLinkedList(mime_cache)+1UL,sizeof(*aliases));
560 if (aliases == (char **) NULL)
561 return((char **) NULL);
565 for (i=0; p != (const MimeInfo *) NULL; )
566 {
567 if ((p->stealth == WizardFalse) &&
569 aliases[i++]=ConstantString(p->type);
571 }
573 qsort((void *) aliases,(size_t) i,sizeof(*aliases),MimeCompare);
574 aliases[i]=(char *) NULL;
575 *number_aliases=(size_t) i;
576 return(aliases);
577}
578
579/*
580%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
581% %
582% %
583% %
584% G e t M i m e D e s c r i p t i o n %
585% %
586% %
587% %
588%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
589%
590% GetMimeDescription() returns the mime type description.
591%
592% The format of the GetMimeDescription method is:
593%
594% const char *GetMimeDescription(const MimeInfo *mime_info)
595%
596% A description of each parameter follows:
597%
598% o mime_info: The magic info.
599%
600*/
601WizardExport const char *GetMimeDescription(const MimeInfo *mime_info)
602{
604 assert(mime_info != (MimeInfo *) NULL);
605 assert(mime_info->signature == WizardSignature);
606 return(mime_info->description);
607}
608
609/*
610%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
611% %
612% %
613% %
614% G e t M i m e T y p e %
615% %
616% %
617% %
618%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
619%
620% GetMimeType() returns the mime type.
621%
622% The format of the GetMimeType method is:
623%
624% const char *GetMimeType(const MimeInfo *mime_info)
625%
626% A description of each parameter follows:
627%
628% o mime_info: The magic info.
629%
630*/
631WizardExport const char *GetMimeType(const MimeInfo *mime_info)
632{
634 assert(mime_info != (MimeInfo *) NULL);
635 assert(mime_info->signature == WizardSignature);
636 return(mime_info->type);
637}
638
639/*
640%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
641% %
642% %
643% %
644+ I s M i m e C a c h e I n s t a n t i a t e d %
645% %
646% %
647% %
648%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
649%
650% IsMimeCacheInstantiated() determines if the mime list is instantiated. If
651% not, it instantiates the list and returns it.
652%
653% The format of the IsMimeInstantiated method is:
654%
655% WizardBooleanType IsMimeCacheInstantiated(ExceptionInfo *exception)
656%
657% A description of each parameter follows.
658%
659% o exception: Return any errors or warnings in this structure.
660%
661*/
663{
664 if (mime_cache == (LinkedListInfo *) NULL)
665 {
666 if (mime_semaphore == (SemaphoreInfo *) NULL)
669 if (mime_cache == (LinkedListInfo *) NULL)
672 }
673 return(mime_cache != (LinkedListInfo *) NULL ? WizardTrue : WizardFalse);
674}
675
676/*
677%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
678% %
679% %
680% %
681% L i s t M i m e I n f o %
682% %
683% %
684% %
685%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
686%
687% ListMimeInfo() lists the magic info to a file.
688%
689% The format of the ListMimeInfo method is:
690%
691% WizardBooleanType ListMimeInfo(FILE *file,ExceptionInfo *exception)
692%
693% A description of each parameter follows.
694%
695% o file: An pointer to a FILE.
696%
697% o exception: Return any errors or warnings in this structure.
698%
699*/
701{
702 const char
703 *path;
704
705 const MimeInfo
706 **mime_info;
707
708 ssize_t
709 i;
710
711 size_t
712 number_aliases;
713
714 ssize_t
715 j;
716
717 if (file == (const FILE *) NULL)
718 file=stdout;
719 mime_info=GetMimeInfoList("*",&number_aliases,exception);
720 if (mime_info == (const MimeInfo **) NULL)
721 return(WizardFalse);
722 j=0;
723 path=(const char *) NULL;
724 for (i=0; i < (ssize_t) number_aliases; i++)
725 {
726 if (mime_info[i]->stealth != WizardFalse)
727 continue;
728 if ((path == (const char *) NULL) ||
729 (strcasecmp(path,mime_info[i]->path) != 0))
730 {
731 if (mime_info[i]->path != (char *) NULL)
732 (void) fprintf(file,"\nPath: %s\n\n",mime_info[i]->path);
733 (void) fprintf(file,"Type Description\n");
734 (void) fprintf(file,"-------------------------------------------------"
735 "------------------------------\n");
736 }
737 path=mime_info[i]->path;
738 (void) fprintf(file,"%s",mime_info[i]->type);
739 if (strlen(mime_info[i]->type) <= 25)
740 {
741 for (j=(ssize_t) strlen(mime_info[i]->type); j <= 27; j++)
742 (void) fprintf(file," ");
743 }
744 else
745 {
746 (void) fprintf(file,"\n");
747 for (j=0; j <= 27; j++)
748 (void) fprintf(file," ");
749 }
750 if (mime_info[i]->description != (char *) NULL)
751 (void) fprintf(file,"%s",mime_info[i]->description);
752 (void) fprintf(file,"\n");
753 }
754 (void) fflush(file);
755 mime_info=(const MimeInfo **) RelinquishWizardMemory((void *) mime_info);
756 return(WizardTrue);
757}
758
759/*
760%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
761% %
762% %
763% %
764+ L o a d M i m e C a c h e %
765% %
766% %
767% %
768%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
769%
770% LoadMimeCache() loads the magic configurations which provides a mapping
771% between magic attributes and a magic name.
772%
773% The format of the LoadMimeCache method is:
774%
775% WizardBooleanType LoadMimeCache(LinkedListInfo *mime_cache,
776% const char *xml,const char *filename,const size_t depth,
777% ExceptionInfo *exception)
778%
779% A description of each parameter follows:
780%
781% o xml: The mime list in XML format.
782%
783% o filename: The mime list filename.
784%
785% o depth: depth of <include /> statements.
786%
787% o exception: Return any errors or warnings in this structure.
788%
789*/
791 const char *xml,const char *filename,const size_t depth,
792 ExceptionInfo *exception)
793{
794 const char
795 *attribute;
796
798 *mime_info = (MimeInfo *) NULL;
799
801 status;
802
804 *mime,
805 *mime_map,
806 *include;
807
808 /*
809 Load the mime map file.
810 */
812 "Loading mime map \"%s\" ...",filename);
813 if (xml == (const char *) NULL)
814 return(WizardFalse);
815 mime_map=NewXMLTree(xml,exception);
816 if (mime_map == (XMLTreeInfo *) NULL)
817 return(WizardFalse);
818 status=WizardTrue;
819 include=GetXMLTreeChild(mime_map,"include");
820 while (include != (XMLTreeInfo *) NULL)
821 {
822 /*
823 Process include element.
824 */
825 attribute=GetXMLTreeAttribute(include,"file");
826 if (attribute != (const char *) NULL)
827 {
828 if (depth > 200)
829 (void) ThrowWizardException(exception,GetWizardModule(),
830 ConfigureError,"include element nested too deeply `%s'",filename);
831 else
832 {
833 char
834 path[WizardPathExtent],
835 *xml;
836
837 GetPathComponent(filename,HeadPath,path);
838 if (*path != '\0')
841 if (*attribute == *DirectorySeparator)
842 (void) CopyWizardString(path,attribute,WizardPathExtent);
843 else
844 (void) ConcatenateWizardString(path,attribute,WizardPathExtent);
845 xml=FileToXML(path,~0UL);
846 if (xml != (char *) NULL)
847 {
848 status&=LoadMimeCache(mime_cache,xml,path,depth+1,exception);
849 xml=DestroyString(xml);
850 }
851 }
852 }
853 include=GetNextXMLTreeTag(include);
854 }
855 mime=GetXMLTreeChild(mime_map,"mime");
856 while (mime != (XMLTreeInfo *) NULL)
857 {
858 const char
859 *attribute;
860
861 /*
862 Process mime element.
863 */
864 mime_info=(MimeInfo *) AcquireWizardMemory(sizeof(*mime_info));
865 if (mime_info == (MimeInfo *) NULL)
866 ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
867 (void) memset(mime_info,0,sizeof(*mime_info));
868 mime_info->path=ConstantString(filename);
869 mime_info->signature=WizardSignature;
870 attribute=GetXMLTreeAttribute(mime,"data-type");
871 if (attribute != (const char *) NULL)
873 WizardTrue,attribute);
874 attribute=GetXMLTreeAttribute(mime,"description");
875 if (attribute != (const char *) NULL)
876 mime_info->description=ConstantString(attribute);
877 attribute=GetXMLTreeAttribute(mime,"endian");
878 if (attribute != (const char *) NULL)
880 WizardTrue,attribute);
881 attribute=GetXMLTreeAttribute(mime,"magic");
882 if (attribute != (const char *) NULL)
883 {
884 char
885 *token;
886
887 const char
888 *p;
889
890 unsigned char
891 *q;
892
893 token=AcquireString(attribute);
894 (void) SubstituteString((char **) &token,"&lt;","<");
895 (void) SubstituteString((char **) &token,"&amp;","&");
896 (void) SubstituteString((char **) &token,"&quot;","\"");
897 mime_info->magic=(unsigned char *) AcquireString(token);
898 q=mime_info->magic;
899 for (p=token; *p != '\0'; )
900 {
901 if (*p == '\\')
902 {
903 p++;
904 if (isdigit((int) ((unsigned char) *p)) != 0)
905 {
906 char
907 *end;
908
909 *q++=(unsigned char) strtol(p,&end,8);
910 p+=(end-p);
911 mime_info->length++;
912 continue;
913 }
914 switch (*p)
915 {
916 case 'b': *q='\b'; break;
917 case 'f': *q='\f'; break;
918 case 'n': *q='\n'; break;
919 case 'r': *q='\r'; break;
920 case 't': *q='\t'; break;
921 case 'v': *q='\v'; break;
922 case 'a': *q='a'; break;
923 case '?': *q='\?'; break;
924 default: *q=(unsigned char) (*p); break;
925 }
926 p++;
927 q++;
928 mime_info->length++;
929 continue;
930 }
931 *q++=(unsigned char) (*p++);
932 mime_info->length++;
933 }
934 token=DestroyString(token);
935 if (mime_info->data_type != StringData)
936 mime_info->value=strtol((char *) mime_info->magic,(char **) NULL,0);
937 }
938 attribute=GetXMLTreeAttribute(mime,"mask");
939 if (attribute != (const char *) NULL)
940 mime_info->mask=strtol(attribute,(char **) NULL,0);
941 attribute=GetXMLTreeAttribute(mime,"offset");
942 if (attribute != (const char *) NULL)
943 {
944 char
945 *c;
946
947 mime_info->offset=(WizardOffsetType) strtol(attribute,&c,0);
948 if (*c == ':')
949 mime_info->extent=(size_t) strtol(c+1,(char **) NULL,0);
950 }
951 attribute=GetXMLTreeAttribute(mime,"pattern");
952 if (attribute != (const char *) NULL)
953 mime_info->pattern=ConstantString(attribute);
954 attribute=GetXMLTreeAttribute(mime,"priority");
955 if (attribute != (const char *) NULL)
956 mime_info->priority=strtol(attribute,(char **) NULL,0);
957 attribute=GetXMLTreeAttribute(mime,"stealth");
958 if (attribute != (const char *) NULL)
959 mime_info->stealth=IsWizardTrue(attribute);
960 attribute=GetXMLTreeAttribute(mime,"type");
961 if (attribute != (const char *) NULL)
962 mime_info->type=ConstantString(attribute);
963 status=AppendValueToLinkedList(mime_cache,mime_info);
964 if (status == WizardFalse)
966 "memory allocation failed `%s'",filename);
967 mime=GetNextXMLTreeTag(mime);
968 }
969 mime_map=DestroyXMLTree(mime_map);
970 return(status != 0 ? WizardTrue : WizardFalse);
971}
972
973/*
974%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
975% %
976% %
977% %
978+ M i m e C o m p o n e n t G e n e s i s %
979% %
980% %
981% %
982%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
983%
984% MimeComponentGenesis() instantiates the mime component.
985%
986% The format of the MimeComponentGenesis method is:
987%
988% WizardBooleanType MimeComponentGenesis(void)
989%
990*/
992{
993 if (mime_semaphore == (SemaphoreInfo *) NULL)
995 return(WizardTrue);
996}
997
998/*
999%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1000% %
1001% %
1002% %
1003+ M i m e C o m p o n e n t T e r m i n u s %
1004% %
1005% %
1006% %
1007%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1008%
1009% MimeComponentTerminus() destroys the mime component.
1010%
1011% The format of the MimeComponentTerminus method is:
1012%
1013% MimeComponentTerminus(void)
1014%
1015*/
1016
1017static void *DestroyMimeElement(void *mime_info)
1018{
1019 MimeInfo
1020 *p;
1021
1022 p=(MimeInfo *) mime_info;
1023 if (p->magic != (unsigned char *) NULL)
1024 p->magic=(unsigned char *) RelinquishWizardMemory(p->magic);
1025 if (p->pattern != (char *) NULL)
1027 if (p->description != (char *) NULL)
1029 if (p->type != (char *) NULL)
1030 p->type=DestroyString(p->type);
1031 if (p->path != (char *) NULL)
1032 p->path=DestroyString(p->path);
1034 return((void *) NULL);
1035}
1036
1038{
1039 if (mime_semaphore == (SemaphoreInfo *) NULL)
1042 if (mime_cache != (LinkedListInfo *) NULL)
1046}
1047
1048/*
1049%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1050% %
1051% %
1052% %
1053+ W i z a r d T o M i m e %
1054% %
1055% %
1056% %
1057%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1058%
1059% WizardToMime() returns the officially registered (or de facto) MIME
1060% media-type corresponding to a wizard string. If there is no registered
1061% media-type, then the string "image/x-wizard" (all lower case) is returned.
1062% The returned string must be deallocated by the user.
1063%
1064% The format of the WizardToMime method is:
1065%
1066% char *WizardToMime(const char *wizard)
1067%
1068% A description of each parameter follows.
1069%
1070% o wizard: ImageMagick format specification "wizard" tag.
1071%
1072*/
1073WizardExport char *WizardToMime(const char *wizard)
1074{
1075 char
1076 filename[WizardPathExtent],
1077 media[WizardPathExtent];
1078
1079 const MimeInfo
1080 *mime_info;
1081
1083 *exception;
1084
1085 (void) FormatLocaleString(filename,WizardPathExtent,"file.%s",wizard);
1086 LocaleLower(filename);
1087 exception=AcquireExceptionInfo();
1088 mime_info=GetMimeInfo(filename,(unsigned char *) " ",1,exception);
1089 exception=DestroyExceptionInfo(exception);
1090 if (mime_info != (const MimeInfo *) NULL)
1091 return(ConstantString(GetMimeType(mime_info)));
1092 (void) FormatLocaleString(media,WizardPathExtent,"image/x-%s",wizard);
1093 LocaleLower(media+8);
1094 return(ConstantString(media));
1095}
WizardExport LinkedListInfo * DestroyConfigureOptions(LinkedListInfo *options)
Definition configure.c:298
WizardExport LinkedListInfo * GetConfigureOptions(const char *filename, ExceptionInfo *exception)
Definition configure.c:585
#define ThrowFatalException(severity, tag)
WizardExport ExceptionInfo * AcquireExceptionInfo(void)
Definition exception.c:125
WizardExport ExceptionInfo * DestroyExceptionInfo(ExceptionInfo *exception)
Definition exception.c:399
WizardExport WizardBooleanType ThrowWizardException(ExceptionInfo *exception, const char *module, const char *function, const size_t line, const ExceptionType severity, const char *format,...)
Definition exception.c:1029
@ ResourceFatalError
Definition exception.h:121
@ ConfigureError
Definition exception.h:88
@ ResourceError
Definition exception.h:101
WizardExport WizardBooleanType IsLinkedListEmpty(const LinkedListInfo *list_info)
Definition hashmap.c:1206
WizardExport void ResetLinkedListIterator(LinkedListInfo *list_info)
Definition hashmap.c:1919
WizardExport size_t GetNumberOfElementsInLinkedList(const LinkedListInfo *list_info)
Definition hashmap.c:678
WizardExport WizardBooleanType AppendValueToLinkedList(LinkedListInfo *list_info, const void *value)
Definition hashmap.c:149
WizardExport WizardBooleanType InsertValueInLinkedList(LinkedListInfo *list_info, const size_t index, const void *value)
Definition hashmap.c:991
WizardExport void * RemoveElementByValueFromLinkedList(LinkedListInfo *list_info, const void *value)
Definition hashmap.c:1595
WizardExport LinkedListInfo * NewLinkedList(const size_t capacity)
Definition hashmap.c:1362
WizardExport void * GetNextValueInLinkedList(LinkedListInfo *list_info)
Definition hashmap.c:605
WizardExport LinkedListInfo * DestroyLinkedList(LinkedListInfo *list_info, void *(*relinquish_value)(void *))
Definition hashmap.c:397
WizardExport ssize_t FormatLocaleString(char *string, const size_t length, const char *format,...)
Definition locale.c:465
WizardBooleanType LogWizardEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition log.c:1390
@ TraceEvent
Definition log.h:39
@ ConfigureEvent
Definition log.h:44
#define GetWizardModule()
Definition log.h:30
WizardExport void * AcquireWizardMemory(const size_t size)
Definition memory.c:586
WizardExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition memory.c:657
WizardExport void * RelinquishWizardMemory(void *memory)
Definition memory.c:1039
#define WizardExport
#define WizardPathExtent
#define WizardSignature
EndianType
@ MSBEndian
@ LSBEndian
@ UndefinedEndian
DataType
@ StringData
@ ShortData
@ LongData
@ ByteData
WizardExport const char * GetMimeDescription(const MimeInfo *mime_info)
Definition mime.c:601
WizardExport const char * GetMimeType(const MimeInfo *mime_info)
Definition mime.c:631
static int MimeCompare(const void *x, const void *y)
Definition mime.c:521
WizardExport WizardBooleanType MimeComponentGenesis(void)
Definition mime.c:991
static const char * MimeMap
Definition mime.c:110
static WizardBooleanType IsMimeCacheInstantiated(ExceptionInfo *)
Definition mime.c:662
WizardExport char ** GetMimeList(const char *pattern, size_t *number_aliases, ExceptionInfo *exception)
Definition mime.c:536
static LinkedListInfo * AcquireMimeCache(const char *filename, ExceptionInfo *exception)
Definition mime.c:155
static int MimeInfoCompare(const void *x, const void *y)
Definition mime.c:424
WizardExport void MimeComponentTerminus(void)
Definition mime.c:1037
static void * DestroyMimeElement(void *mime_info)
Definition mime.c:1017
#define MimeFilename
Definition mime.c:61
WizardExport WizardBooleanType ListMimeInfo(FILE *file, ExceptionInfo *exception)
Definition mime.c:700
WizardExport const MimeInfo * GetMimeInfo(const char *filename, const unsigned char *magic, const size_t length, ExceptionInfo *exception)
Definition mime.c:225
WizardExport const MimeInfo ** GetMimeInfoList(const char *pattern, size_t *number_aliases, ExceptionInfo *exception)
Definition mime.c:441
static LinkedListInfo * mime_cache
Definition mime.c:116
WizardExport char * WizardToMime(const char *wizard)
Definition mime.c:1073
static WizardBooleanType LoadMimeCache(LinkedListInfo *, const char *, const char *, const size_t, ExceptionInfo *)
Definition mime.c:790
static SemaphoreInfo * mime_semaphore
Definition mime.c:119
WizardExport ssize_t ParseWizardOption(const WizardOption option, const WizardBooleanType list, const char *options)
Definition option.c:422
@ WizardDataTypeOptions
Definition option.h:43
@ WizardEndianOptions
Definition option.h:45
WizardExport void RelinquishSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition semaphore.c:338
WizardExport SemaphoreInfo * AcquireSemaphoreInfo(void)
Definition semaphore.c:156
WizardExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition semaphore.c:282
WizardExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition semaphore.c:437
WizardExport void ActivateSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition semaphore.c:247
WizardExport char * DestroyString(char *string)
Definition string.c:830
WizardExport WizardBooleanType SubstituteString(char **string, const char *search, const char *replace)
Definition string.c:2295
WizardExport void LocaleLower(char *string)
Definition string.c:1563
WizardExport char * ConstantString(const char *source)
Definition string.c:655
WizardExport size_t ConcatenateWizardString(char *destination, const char *source, const size_t length)
Definition string.c:478
WizardExport char * AcquireString(const char *source)
Definition string.c:133
WizardExport unsigned char * GetStringInfoDatum(const StringInfo *string_info)
Definition string.c:1251
WizardExport size_t CopyWizardString(char *destination, const char *source, const size_t length)
Definition string.c:762
WizardExport const char * GetStringInfoPath(const StringInfo *string_info)
Definition string.c:1309
char * type
Definition mime.c:70
size_t extent
Definition mime.c:81
char * pattern
Definition mime.c:72
WizardBooleanType stealth
Definition mime.c:100
WizardOffsetType offset
Definition mime.c:78
size_t length
Definition mime.c:94
DataType data_type
Definition mime.c:84
unsigned char * magic
Definition mime.c:97
size_t signature
Definition mime.c:103
char * path
Definition mime.c:69
ssize_t value
Definition mime.c:88
char * description
Definition mime.c:71
EndianType endian
Definition mime.c:91
ssize_t priority
Definition mime.c:75
ssize_t mask
Definition mime.c:87
#define DirectorySeparator
Definition studio.h:239
WizardExport WizardBooleanType GlobExpression(const char *expression, const char *pattern, const WizardBooleanType case_insensitive)
Definition token.c:259
WizardExport WizardBooleanType IsWizardTrue(const char *value)
Definition utility.c:910
WizardExport void GetPathComponent(const char *path, PathType type, char *component)
Definition utility.c:415
@ HeadPath
Definition utility.h:30
ssize_t WizardOffsetType
Definition wizard-type.h:50
WizardBooleanType
Definition wizard-type.h:26
@ WizardTrue
Definition wizard-type.h:28
@ WizardFalse
Definition wizard-type.h:27
unsigned int WizardStatusType
Definition wizard-type.h:42
WizardPrivate char * FileToXML(const char *, const size_t)
Definition xml-tree.c:633
WizardExport XMLTreeInfo * DestroyXMLTree(XMLTreeInfo *xml_info)
Definition xml-tree.c:593
WizardExport const char * GetXMLTreeAttribute(XMLTreeInfo *xml_info, const char *tag)
Definition xml-tree.c:812
WizardExport XMLTreeInfo * NewXMLTree(const char *xml, ExceptionInfo *exception)
Definition xml-tree.c:1988
WizardExport XMLTreeInfo * GetNextXMLTreeTag(XMLTreeInfo *xml_info)
Definition xml-tree.c:778
WizardExport XMLTreeInfo * GetXMLTreeChild(XMLTreeInfo *xml_info, const char *tag)
Definition xml-tree.c:927