mime.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                        M   M  IIIII  M   M  EEEEE                           %
00006 %                        MM MM    I    MM MM  E                               %
00007 %                        M M M    I    M M M  EEE                             %
00008 %                        M   M    I    M   M  E                               %
00009 %                        M   M  IIIII  M   M  EEEEE                           %
00010 %                                                                             %
00011 %                                                                             %
00012 %                          MagickCore Mime Methods                            %
00013 %                                                                             %
00014 %                              Software Design                                %
00015 %                                 July 2000                                   %
00016 %                                                                             %
00017 %                                                                             %
00018 %  Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization      %
00019 %  dedicated to making software imaging solutions freely available.           %
00020 %                                                                             %
00021 %  You may not use this file except in compliance with the License.  You may  %
00022 %  obtain a copy of the License at                                            %
00023 %                                                                             %
00024 %    http://www.imagemagick.org/MagicksToolkit/script/license.php             %
00025 %                                                                             %
00026 %  Unless required by applicable law or agreed to in writing, software        %
00027 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00028 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00029 %  See the License for the specific language governing permissions and        %
00030 %  limitations under the License.                                             %
00031 %                                                                             %
00032 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00033 %
00034 %
00035 */
00036 
00037 /*
00038   Include declarations.
00039 */
00040 #include "magick/studio.h"
00041 #include "magick/blob.h"
00042 #include "magick/client.h"
00043 #include "magick/configure.h"
00044 #include "magick/exception.h"
00045 #include "magick/exception-private.h"
00046 #include "magick/hashmap.h"
00047 #include "magick/memory_.h"
00048 #include "magick/mime.h"
00049 #include "magick/mime-private.h"
00050 #include "magick/option.h"
00051 #include "magick/semaphore.h"
00052 #include "magick/string_.h"
00053 #include "magick/token.h"
00054 #include "magick/utility.h"
00055 #include "magick/xml-tree.h"
00056 
00057 /*
00058   Define declarations.
00059 */
00060 #define MimeFilename  "mime.xml"
00061 
00062 /*
00063   Typedef declaration.
00064 */
00065 struct _MimeInfo
00066 {
00067   char
00068     *path,
00069     *type,
00070     *description,
00071     *pattern;
00072 
00073   long
00074     priority;
00075 
00076   MagickOffsetType
00077     offset;
00078 
00079   size_t
00080     extent;
00081 
00082   DataType
00083     data_type;
00084 
00085   long
00086     mask,
00087     value;
00088 
00089   EndianType
00090     endian;
00091 
00092   size_t
00093     length;
00094 
00095   unsigned char
00096     *magic;
00097 
00098   MagickBooleanType
00099     stealth;
00100 
00101   unsigned long
00102     signature;
00103 };
00104 
00105 /*
00106   Static declarations.
00107 */
00108 static const char
00109   *MimeMap = (char *)
00110     "<?xml version=\"1.0\"?>"
00111     "<mimemap>"
00112     "</mimemap>";
00113 
00114 static LinkedListInfo
00115   *mime_list = (LinkedListInfo *) NULL;
00116 
00117 static SemaphoreInfo
00118   *mime_semaphore = (SemaphoreInfo *) NULL;
00119 
00120 static volatile MagickBooleanType
00121   instantiate_mime = MagickFalse;
00122 
00123 /*
00124   Forward declarations.
00125 */
00126 static MagickBooleanType
00127   InitializeMimeList(ExceptionInfo *);
00128 
00129 /*
00130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00131 %                                                                             %
00132 %                                                                             %
00133 %                                                                             %
00134 +   G e t M i m e I n f o                                                     %
00135 %                                                                             %
00136 %                                                                             %
00137 %                                                                             %
00138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00139 %
00140 %  GetMimeInfo() attempts to classify the content to identify which mime type
00141 %  is associated with the content, if any.
00142 %
00143 %  The format of the GetMimeInfo method is:
00144 %
00145 %      const MimeInfo *GetMimeInfo(const char *filename,
00146 %        const unsigned char *magic,const size_t length,
00147 %        ExceptionInfo *exception)
00148 %
00149 %  A description of each parameter follows:
00150 %
00151 %    o filename:  If we cannot not classify the string, we attempt to classify
00152 %      based on the filename (e.g. *.pdf returns application/pdf).
00153 %
00154 %    o magic: A binary string generally representing the first few characters
00155 %      of the image file or blob.
00156 %
00157 %    o length: the length of the binary signature.
00158 %
00159 %    o exception: return any errors or warnings in this structure.
00160 %
00161 */
00162 MagickExport const MimeInfo *GetMimeInfo(const char *filename,
00163   const unsigned char *magic,const size_t length,ExceptionInfo *exception)
00164 {
00165   const MimeInfo
00166     *mime_info;
00167 
00168   EndianType
00169     endian;
00170 
00171   long
00172     value;
00173 
00174   register const MimeInfo
00175     *p;
00176 
00177   register const unsigned char
00178     *q;
00179 
00180   register long
00181     i;
00182 
00183   unsigned long
00184     lsb_first;
00185 
00186   assert(exception != (ExceptionInfo *) NULL);
00187   if ((mime_list == (LinkedListInfo *) NULL) ||
00188       (instantiate_mime == MagickFalse))
00189     if (InitializeMimeList(exception) == MagickFalse)
00190       return((const MimeInfo *) NULL);
00191   if ((mime_list == (LinkedListInfo *) NULL) ||
00192       (IsLinkedListEmpty(mime_list) != MagickFalse))
00193     return((const MimeInfo *) NULL);
00194   if ((magic == (const unsigned char *) NULL) || (length == 0))
00195     return((const MimeInfo *) GetValueFromLinkedList(mime_list,0));
00196   if (length == 0)
00197     return((const MimeInfo *) NULL);
00198   /*
00199     Search for mime tag.
00200   */
00201   mime_info=(const MimeInfo *) NULL;
00202   lsb_first=1;
00203   (void) LockSemaphoreInfo(mime_semaphore);
00204   ResetLinkedListIterator(mime_list);
00205   p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
00206   while (p != (const MimeInfo *) NULL)
00207   {
00208     assert(p->offset >= 0);
00209     if (mime_info != (const MimeInfo *) NULL)
00210       if (p->priority > mime_info->priority)
00211         {
00212           p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
00213           continue;
00214         }
00215     if ((p->pattern != (char *) NULL) && (filename != (char *) NULL))
00216       {
00217         if (GlobExpression(filename,p->pattern,MagickFalse) != MagickFalse)
00218           mime_info=p;
00219         p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
00220         continue;
00221       }
00222     switch (p->data_type)
00223     {
00224       case ByteData:
00225       {
00226         if ((size_t) (p->offset+4) > length)
00227           break;
00228         q=magic+p->offset;
00229         value=(*q++);
00230         if (p->mask == 0)
00231           {
00232             if (p->value == value)
00233               mime_info=p;
00234           }
00235         else
00236           {
00237             if ((p->value & p->mask) == value)
00238               mime_info=p;
00239           }
00240         break;
00241       }
00242       case ShortData:
00243       {
00244         if ((size_t) (p->offset+4) > length)
00245           break;
00246         q=magic+p->offset;
00247         endian=p->endian;
00248         if (p->endian == UndefinedEndian)
00249           endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian;
00250         if (endian == LSBEndian)
00251           {
00252             value=(*q++);
00253             value|=(*q++) << 8;
00254           }
00255         else
00256           {
00257             value=(*q++) << 8;
00258             value|=(*q++);
00259           }
00260         if (p->mask == 0)
00261           {
00262             if (p->value == value)
00263               mime_info=p;
00264           }
00265         else
00266           {
00267             if ((p->value & p->mask) == value)
00268               mime_info=p;
00269           }
00270         break;
00271       }
00272       case LongData:
00273       {
00274         if ((size_t) (p->offset+4) > length)
00275           break;
00276         q=magic+p->offset;
00277         endian=p->endian;
00278         if (p->endian == UndefinedEndian)
00279           endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian;
00280         if (endian == LSBEndian)
00281           {
00282             value=(*q++);
00283             value|=(*q++) << 8;
00284             value|=(*q++) << 16;
00285             value|=(*q++) << 24;
00286           }
00287         else
00288           {
00289             value=(*q++) << 24;
00290             value|=(*q++) << 16;
00291             value|=(*q++) << 8;
00292             value|=(*q++);
00293           }
00294         if (p->mask == 0)
00295           {
00296             if (p->value == value)
00297               mime_info=p;
00298           }
00299         else
00300           {
00301             if ((p->value & p->mask) == value)
00302               mime_info=p;
00303           }
00304         break;
00305       }
00306       case StringData:
00307       default:
00308       {
00309         for (i=0; i <= (long) p->extent; i++)
00310         {
00311           if ((size_t) (p->offset+i+p->length) > length)
00312             break;
00313           if (memcmp(magic+p->offset+i,p->magic,p->length) == 0)
00314             {
00315               mime_info=p;
00316               break;
00317             }
00318         }
00319         break;
00320       }
00321     }
00322     p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
00323   }
00324   if (p != (const MimeInfo *) NULL)
00325     (void) InsertValueInLinkedList(mime_list,0,
00326       RemoveElementByValueFromLinkedList(mime_list,p));
00327   (void) UnlockSemaphoreInfo(mime_semaphore);
00328   return(mime_info);
00329 }
00330 
00331 /*
00332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00333 %                                                                             %
00334 %                                                                             %
00335 %                                                                             %
00336 %   G e t M i m e I n f o L i s t                                             %
00337 %                                                                             %
00338 %                                                                             %
00339 %                                                                             %
00340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00341 %
00342 %  GetMimeInfoList() returns any image aliases that match the specified
00343 %  pattern.
00344 %
00345 %  The magic of the GetMimeInfoList function is:
00346 %
00347 %      const MimeInfo **GetMimeInfoList(const char *pattern,
00348 %        unsigned long *number_aliases,ExceptionInfo *exception)
00349 %
00350 %  A description of each parameter follows:
00351 %
00352 %    o pattern: Specifies a pointer to a text string containing a pattern.
00353 %
00354 %    o number_aliases:  This integer returns the number of magics in the
00355 %      list.
00356 %
00357 %    o exception: return any errors or warnings in this structure.
00358 %
00359 */
00360 
00361 #if defined(__cplusplus) || defined(c_plusplus)
00362 extern "C" {
00363 #endif
00364 
00365 static int MimeInfoCompare(const void *x,const void *y)
00366 {
00367   const MimeInfo
00368     **p,
00369     **q;
00370 
00371   p=(const MimeInfo **) x,
00372   q=(const MimeInfo **) y;
00373   if (strcasecmp((*p)->path,(*q)->path) == 0)
00374     return(strcasecmp((*p)->type,(*q)->type));
00375   return(strcasecmp((*p)->path,(*q)->path));
00376 }
00377 
00378 #if defined(__cplusplus) || defined(c_plusplus)
00379 }
00380 #endif
00381 
00382 MagickExport const MimeInfo **GetMimeInfoList(const char *pattern,
00383   unsigned long *number_aliases,ExceptionInfo *exception)
00384 {
00385   const MimeInfo
00386     **aliases;
00387 
00388   register const MimeInfo
00389     *p;
00390 
00391   register long
00392     i;
00393 
00394   /*
00395     Allocate mime list.
00396   */
00397   assert(pattern != (char *) NULL);
00398   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00399   assert(number_aliases != (unsigned long *) NULL);
00400   *number_aliases=0;
00401   p=GetMimeInfo((char *) NULL,(unsigned char *) "*",0,exception);
00402   if (p == (const MimeInfo *) NULL)
00403     return((const MimeInfo **) NULL);
00404   aliases=(const MimeInfo **) AcquireQuantumMemory((size_t)
00405     GetNumberOfElementsInLinkedList(mime_list)+1UL,sizeof(*aliases));
00406   if (aliases == (const MimeInfo **) NULL)
00407     return((const MimeInfo **) NULL);
00408   /*
00409     Generate mime list.
00410   */
00411   (void) LockSemaphoreInfo(mime_semaphore);
00412   ResetLinkedListIterator(mime_list);
00413   p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
00414   for (i=0; p != (const MimeInfo *) NULL; )
00415   {
00416     if ((p->stealth == MagickFalse) &&
00417         (GlobExpression(p->type,pattern,MagickFalse) != MagickFalse))
00418       aliases[i++]=p;
00419     p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
00420   }
00421   (void) UnlockSemaphoreInfo(mime_semaphore);
00422   qsort((void *) aliases,(size_t) i,sizeof(*aliases),MimeInfoCompare);
00423   aliases[i]=(MimeInfo *) NULL;
00424   *number_aliases=(unsigned long) i;
00425   return(aliases);
00426 }
00427 
00428 /*
00429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00430 %                                                                             %
00431 %                                                                             %
00432 %                                                                             %
00433 %   G e t M i m e L i s t                                                     %
00434 %                                                                             %
00435 %                                                                             %
00436 %                                                                             %
00437 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00438 %
00439 %  GetMimeList() returns any image format alias that matches the specified
00440 %  pattern.
00441 %
00442 %  The format of the GetMimeList function is:
00443 %
00444 %      char **GetMimeList(const char *pattern,unsigned long *number_aliases,
00445 %        ExceptionInfo *exception)
00446 %
00447 %  A description of each parameter follows:
00448 %
00449 %    o pattern: Specifies a pointer to a text string containing a pattern.
00450 %
00451 %    o number_aliases:  This integer returns the number of image format aliases
00452 %      in the list.
00453 %
00454 %    o exception: return any errors or warnings in this structure.
00455 %
00456 */
00457 
00458 #if defined(__cplusplus) || defined(c_plusplus)
00459 extern "C" {
00460 #endif
00461 
00462 static int MimeCompare(const void *x,const void *y)
00463 {
00464   register char
00465     *p,
00466     *q;
00467 
00468   p=(char *) x;
00469   q=(char *) y;
00470   return(strcasecmp(p,q));
00471 }
00472 
00473 #if defined(__cplusplus) || defined(c_plusplus)
00474 }
00475 #endif
00476 
00477 MagickExport char **GetMimeList(const char *pattern,
00478   unsigned long *number_aliases,ExceptionInfo *exception)
00479 {
00480   char
00481     **aliases;
00482 
00483   register const MimeInfo
00484     *p;
00485 
00486   register long
00487     i;
00488 
00489   /*
00490     Allocate configure list.
00491   */
00492   assert(pattern != (char *) NULL);
00493   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00494   assert(number_aliases != (unsigned long *) NULL);
00495   *number_aliases=0;
00496   p=GetMimeInfo((char *) NULL,(unsigned char *) "*",0,exception);
00497   if (p == (const MimeInfo *) NULL)
00498     return((char **) NULL);
00499   aliases=(char **) AcquireQuantumMemory((size_t)
00500     GetNumberOfElementsInLinkedList(mime_list)+1UL,sizeof(*aliases));
00501   if (aliases == (char **) NULL)
00502     return((char **) NULL);
00503   (void) LockSemaphoreInfo(mime_semaphore);
00504   ResetLinkedListIterator(mime_list);
00505   p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
00506   for (i=0; p != (const MimeInfo *) NULL; )
00507   {
00508     if ((p->stealth == MagickFalse) &&
00509         (GlobExpression(p->type,pattern,MagickFalse) != MagickFalse))
00510       aliases[i++]=ConstantString(p->type);
00511     p=(const MimeInfo *) GetNextValueInLinkedList(mime_list);
00512   }
00513   (void) UnlockSemaphoreInfo(mime_semaphore);
00514   qsort((void *) aliases,(size_t) i,sizeof(*aliases),MimeCompare);
00515   aliases[i]=(char *) NULL;
00516   *number_aliases=(unsigned long) i;
00517   return(aliases);
00518 }
00519 
00520 /*
00521 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00522 %                                                                             %
00523 %                                                                             %
00524 %                                                                             %
00525 %   G e t M i m e D e s c r i p t i o n                                       %
00526 %                                                                             %
00527 %                                                                             %
00528 %                                                                             %
00529 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00530 %
00531 %  GetMimeDescription() returns the mime type description.
00532 %
00533 %  The format of the GetMimeDescription method is:
00534 %
00535 %      const char *GetMimeDescription(const MimeInfo *mime_info)
00536 %
00537 %  A description of each parameter follows:
00538 %
00539 %    o mime_info:  The magic info.
00540 %
00541 */
00542 MagickExport const char *GetMimeDescription(const MimeInfo *mime_info)
00543 {
00544   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00545   assert(mime_info != (MimeInfo *) NULL);
00546   assert(mime_info->signature == MagickSignature);
00547   return(mime_info->description);
00548 }
00549 
00550 /*
00551 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00552 %                                                                             %
00553 %                                                                             %
00554 %                                                                             %
00555 %   G e t M i m e T y p e                                                     %
00556 %                                                                             %
00557 %                                                                             %
00558 %                                                                             %
00559 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00560 %
00561 %  GetMimeType() returns the mime type.
00562 %
00563 %  The format of the GetMimeType method is:
00564 %
00565 %      const char *GetMimeType(const MimeInfo *mime_info)
00566 %
00567 %  A description of each parameter follows:
00568 %
00569 %    o mime_info:  The magic info.
00570 %
00571 */
00572 MagickExport const char *GetMimeType(const MimeInfo *mime_info)
00573 {
00574   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00575   assert(mime_info != (MimeInfo *) NULL);
00576   assert(mime_info->signature == MagickSignature);
00577   return(mime_info->type);
00578 }
00579 
00580 /*
00581 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00582 %                                                                             %
00583 %                                                                             %
00584 %                                                                             %
00585 +   I n i t i a l i z e M i m e L i s t                                       %
00586 %                                                                             %
00587 %                                                                             %
00588 %                                                                             %
00589 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00590 %
00591 %  InitializeMimeList() initializes the mime list.
00592 %
00593 %  The format of the InitializeMimeList method is:
00594 %
00595 %      MagickBooleanType InitializeMimeList(ExceptionInfo *exception)
00596 %
00597 %  A description of each parameter follows.
00598 %
00599 %    o exception: return any errors or warnings in this structure.
00600 %
00601 */
00602 static MagickBooleanType InitializeMimeList(ExceptionInfo *exception)
00603 {
00604   if ((mime_list == (LinkedListInfo *) NULL) &&
00605       (instantiate_mime == MagickFalse))
00606     {
00607       if (mime_semaphore == (SemaphoreInfo *) NULL)
00608         AcquireSemaphoreInfo(&mime_semaphore);
00609       (void) LockSemaphoreInfo(mime_semaphore);
00610       if ((mime_list == (LinkedListInfo *) NULL) &&
00611           (instantiate_mime == MagickFalse))
00612         {
00613           (void) LoadMimeLists(MimeFilename,exception);
00614           instantiate_mime=MagickTrue;
00615         }
00616       (void) UnlockSemaphoreInfo(mime_semaphore);
00617     }
00618   return(mime_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
00619 }
00620 
00621 /*
00622 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00623 %                                                                             %
00624 %                                                                             %
00625 %                                                                             %
00626 %  L i s t M i m e I n f o                                                    %
00627 %                                                                             %
00628 %                                                                             %
00629 %                                                                             %
00630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00631 %
00632 %  ListMimeInfo() lists the magic info to a file.
00633 %
00634 %  The format of the ListMimeInfo method is:
00635 %
00636 %      MagickBooleanType ListMimeInfo(FILE *file,ExceptionInfo *exception)
00637 %
00638 %  A description of each parameter follows.
00639 %
00640 %    o file:  An pointer to a FILE.
00641 %
00642 %    o exception: return any errors or warnings in this structure.
00643 %
00644 */
00645 MagickExport MagickBooleanType ListMimeInfo(FILE *file,ExceptionInfo *exception)
00646 {
00647   const char
00648     *path;
00649 
00650   const MimeInfo
00651     **mime_info;
00652 
00653   long
00654     j;
00655 
00656   register long
00657     i;
00658 
00659   unsigned long
00660     number_aliases;
00661 
00662   if (file == (const FILE *) NULL)
00663     file=stdout;
00664   mime_info=GetMimeInfoList("*",&number_aliases,exception);
00665   if (mime_info == (const MimeInfo **) NULL)
00666     return(MagickFalse);
00667   j=0;
00668   path=(const char *) NULL;
00669   for (i=0; i < (long) number_aliases; i++)
00670   {
00671     if (mime_info[i]->stealth != MagickFalse)
00672       continue;
00673     if ((path == (const char *) NULL) ||
00674         (strcasecmp(path,mime_info[i]->path) != 0))
00675       {
00676         if (mime_info[i]->path != (char *) NULL)
00677           (void) fprintf(file,"\nPath: %s\n\n",mime_info[i]->path);
00678         (void) fprintf(file,"Type                   Description\n");
00679         (void) fprintf(file,"-------------------------------------------------"
00680           "------------------------------\n");
00681       }
00682     path=mime_info[i]->path;
00683     (void) fprintf(file,"%s",mime_info[i]->type);
00684     if (strlen(mime_info[i]->type) <= 25)
00685       {
00686         for (j=(long) strlen(mime_info[i]->type); j <= 27; j++)
00687           (void) fprintf(file," ");
00688       }
00689     else
00690       {
00691         (void) fprintf(file,"\n");
00692         for (j=0; j <= 27; j++)
00693           (void) fprintf(file," ");
00694       }
00695     if (mime_info[i]->description != (char *) NULL)
00696       (void) fprintf(file,"%s",mime_info[i]->description);
00697     (void) fprintf(file,"\n");
00698   }
00699   (void) fflush(file);
00700   mime_info=(const MimeInfo **) RelinquishMagickMemory((void *) mime_info);
00701   return(MagickTrue);
00702 }
00703 
00704 /*
00705 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00706 %                                                                             %
00707 %                                                                             %
00708 %                                                                             %
00709 +   L o a d M i m e L i s t                                                   %
00710 %                                                                             %
00711 %                                                                             %
00712 %                                                                             %
00713 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00714 %
00715 %  LoadMimeList() loads the magic configuration file which provides a mapping
00716 %  between magic attributes and a magic name.
00717 %
00718 %  The format of the LoadMimeList method is:
00719 %
00720 %      MagickBooleanType LoadMimeList(const char *xml,const char *filename,
00721 %        const unsigned long depth,ExceptionInfo *exception)
00722 %
00723 %  A description of each parameter follows:
00724 %
00725 %    o xml:  The mime list in XML format.
00726 %
00727 %    o filename:  The mime list filename.
00728 %
00729 %    o depth: depth of <include /> statements.
00730 %
00731 %    o exception: return any errors or warnings in this structure.
00732 %
00733 */
00734 static MagickBooleanType LoadMimeList(const char *xml,const char *filename,
00735   const unsigned long depth,ExceptionInfo *exception)
00736 {
00737   const char
00738     *attribute;
00739 
00740   MimeInfo
00741     *mime_info = (MimeInfo *) NULL;
00742 
00743   MagickBooleanType
00744     status;
00745 
00746   XMLTreeInfo
00747     *mime,
00748     *mime_map,
00749     *include;
00750 
00751   /*
00752     Load the mime map file.
00753   */
00754   (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
00755     "Loading mime map \"%s\" ...",filename);
00756   if (xml == (const char *) NULL)
00757     return(MagickFalse);
00758   if (mime_list == (LinkedListInfo *) NULL)
00759     {
00760       mime_list=NewLinkedList(0);
00761       if (mime_list == (LinkedListInfo *) NULL)
00762         {
00763           ThrowFileException(exception,ResourceLimitError,
00764             "MemoryAllocationFailed",filename);
00765           return(MagickFalse);
00766         }
00767     }
00768   mime_map=NewXMLTree(xml,exception);
00769   if (mime_map == (XMLTreeInfo *) NULL)
00770     return(MagickFalse);
00771   status=MagickTrue;
00772   include=GetXMLTreeChild(mime_map,"include");
00773   while (include != (XMLTreeInfo *) NULL)
00774   {
00775     /*
00776       Process include element.
00777     */
00778     attribute=GetXMLTreeAttribute(include,"file");
00779     if (attribute != (const char *) NULL)
00780       {
00781         if (depth > 200)
00782           (void) ThrowMagickException(exception,GetMagickModule(),
00783             ConfigureError,"IncludeElementNestedTooDeeply","`%s'",filename);
00784         else
00785           {
00786             char
00787               path[MaxTextExtent],
00788               *xml;
00789 
00790             GetPathComponent(filename,HeadPath,path);
00791             if (*path != '\0')
00792               (void) ConcatenateMagickString(path,DirectorySeparator,
00793                 MaxTextExtent);
00794             if (*attribute == *DirectorySeparator)
00795               (void) CopyMagickString(path,attribute,MaxTextExtent);
00796             else
00797               (void) ConcatenateMagickString(path,attribute,MaxTextExtent);
00798             xml=FileToString(path,~0,exception);
00799             if (xml != (char *) NULL)
00800               {
00801                 status=LoadMimeList(xml,path,depth+1,exception);
00802                 xml=DestroyString(xml);
00803               }
00804           }
00805       }
00806     include=GetNextXMLTreeTag(include);
00807   }
00808   mime=GetXMLTreeChild(mime_map,"mime");
00809   while (mime != (XMLTreeInfo *) NULL)
00810   {
00811     const char
00812       *attribute;
00813 
00814     /*
00815       Process mime element.
00816     */
00817     mime_info=(MimeInfo *) AcquireMagickMemory(sizeof(*mime_info));
00818     if (mime_info == (MimeInfo *) NULL)
00819       ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00820     (void) ResetMagickMemory(mime_info,0,sizeof(*mime_info));
00821     mime_info->path=ConstantString(filename);
00822     mime_info->signature=MagickSignature;
00823     attribute=GetXMLTreeAttribute(mime,"data-type");
00824     if (attribute != (const char *) NULL)
00825       mime_info->data_type=(DataType) ParseMagickOption(MagickDataTypeOptions,
00826         MagickTrue,attribute);
00827     attribute=GetXMLTreeAttribute(mime,"description");
00828     if (attribute != (const char *) NULL)
00829       mime_info->description=ConstantString(attribute);
00830     attribute=GetXMLTreeAttribute(mime,"endian");
00831     if (attribute != (const char *) NULL)
00832       mime_info->endian=(EndianType) ParseMagickOption(MagickEndianOptions,
00833         MagickTrue,attribute);
00834     attribute=GetXMLTreeAttribute(mime,"magic");
00835     if (attribute != (const char *) NULL)
00836       {
00837         char
00838           *token;
00839 
00840         const char
00841           *p;
00842 
00843         register unsigned char
00844           *q;
00845 
00846         token=AcquireString(attribute);
00847         (void) SubstituteString((char **) &token,"&lt;","<");
00848         (void) SubstituteString((char **) &token,"&amp;","&");
00849         (void) SubstituteString((char **) &token,"&quot;","\"");
00850         mime_info->magic=(unsigned char *) AcquireString(token);
00851         q=mime_info->magic;
00852         for (p=token; *p != '\0'; )
00853         {
00854           if (*p == '\\')
00855             {
00856               p++;
00857               if (isdigit((int) ((unsigned char) *p)) != 0)
00858                 {
00859                   char
00860                     *end;
00861 
00862                   *q++=(unsigned char) strtol(p,&end,8);
00863                   p+=(end-p);
00864                   mime_info->length++;
00865                   continue;
00866                 }
00867               switch (*p)
00868               {
00869                 case 'b': *q='\b'; break;
00870                 case 'f': *q='\f'; break;
00871                 case 'n': *q='\n'; break;
00872                 case 'r': *q='\r'; break;
00873                 case 't': *q='\t'; break;
00874                 case 'v': *q='\v'; break;
00875                 case 'a': *q='a'; break;
00876                 case '?': *q='\?'; break;
00877                 default: *q=(unsigned char) (*p); break;
00878               }
00879               p++;
00880               q++;
00881               mime_info->length++;
00882               continue;
00883             }
00884           *q++=(unsigned char) (*p++);
00885           mime_info->length++;
00886         }
00887         token=DestroyString(token);
00888         if (mime_info->data_type != StringData)
00889           mime_info->value=strtol((char *) mime_info->magic,(char **) NULL,0);
00890       }
00891     attribute=GetXMLTreeAttribute(mime,"mask");
00892     if (attribute != (const char *) NULL)
00893       mime_info->mask=strtol(attribute,(char **) NULL,0);
00894     attribute=GetXMLTreeAttribute(mime,"offset");
00895     if (attribute != (const char *) NULL)
00896       {
00897         char
00898           *c;
00899 
00900         mime_info->offset=(MagickOffsetType) strtol(attribute,&c,0);
00901         if (*c == ':')
00902           mime_info->extent=(size_t) strtol(c+1,(char **) NULL,0);
00903       }
00904     attribute=GetXMLTreeAttribute(mime,"pattern");
00905     if (attribute != (const char *) NULL)
00906       mime_info->pattern=ConstantString(attribute);
00907     attribute=GetXMLTreeAttribute(mime,"priority");
00908     if (attribute != (const char *) NULL)
00909       mime_info->priority=strtol(attribute,(char **) NULL,0);
00910     attribute=GetXMLTreeAttribute(mime,"stealth");
00911     if (attribute != (const char *) NULL)
00912       mime_info->stealth=IsMagickTrue(attribute);
00913     attribute=GetXMLTreeAttribute(mime,"type");
00914     if (attribute != (const char *) NULL)
00915       mime_info->type=ConstantString(attribute);
00916     status=AppendValueToLinkedList(mime_list,mime_info);
00917     if (status == MagickFalse)
00918       (void) ThrowMagickException(exception,GetMagickModule(),
00919         ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
00920     mime=GetNextXMLTreeTag(mime);
00921   }
00922   mime_map=DestroyXMLTree(mime_map);
00923   return(status);
00924 }
00925 
00926 /*
00927 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00928 %                                                                             %
00929 %                                                                             %
00930 %                                                                             %
00931 %  L o a d M i m e L i s t s                                                  %
00932 %                                                                             %
00933 %                                                                             %
00934 %                                                                             %
00935 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00936 %
00937 %  LoadMimeList() loads one or more magic configuration file which provides a
00938 %  mapping between magic attributes and a magic name.
00939 %
00940 %  The format of the LoadMimeLists method is:
00941 %
00942 %      MagickBooleanType LoadMimeLists(const char *filename,
00943 %        ExceptionInfo *exception)
00944 %
00945 %  A description of each parameter follows:
00946 %
00947 %    o filename: the font file name.
00948 %
00949 %    o exception: return any errors or warnings in this structure.
00950 %
00951 */
00952 MagickExport MagickBooleanType LoadMimeLists(const char *filename,
00953   ExceptionInfo *exception)
00954 {
00955 #if defined(MAGICKCORE_EMBEDDABLE_SUPPORT)
00956   return(LoadMimeList(MimeMap,"built-in",0,exception));
00957 #else
00958   const StringInfo
00959     *option;
00960 
00961   LinkedListInfo
00962     *options;
00963 
00964   MagickStatusType
00965     status;
00966 
00967   status=MagickFalse;
00968   options=GetConfigureOptions(filename,exception);
00969   option=(const StringInfo *) GetNextValueInLinkedList(options);
00970   while (option != (const StringInfo *) NULL)
00971   {
00972     status|=LoadMimeList((const char *) GetStringInfoDatum(option),
00973       GetStringInfoPath(option),0,exception);
00974     option=(const StringInfo *) GetNextValueInLinkedList(options);
00975   }
00976   options=DestroyConfigureOptions(options);
00977   if ((mime_list == (LinkedListInfo *) NULL) ||
00978       (IsLinkedListEmpty(mime_list) != MagickFalse))
00979     status|=LoadMimeList(MimeMap,"built-in",0,exception);
00980   else
00981     ClearMagickException(exception);
00982   return(status != 0 ? MagickTrue : MagickFalse);
00983 #endif
00984 }
00985 
00986 /*
00987 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00988 %                                                                             %
00989 %                                                                             %
00990 %                                                                             %
00991 +  M a g i c k T o M i m e                                                    %
00992 %                                                                             %
00993 %                                                                             %
00994 %                                                                             %
00995 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00996 %
00997 %  MagickToMime() returns the officially registered (or de facto) MIME
00998 %  media-type corresponding to a magick string.  If there is no registered
00999 %  media-type, then the string "image/x-magick" (all lower case) is returned.
01000 %  The returned string must be deallocated by the user.
01001 %
01002 %  The format of the MagickToMime method is:
01003 %
01004 %      char *MagickToMime(const char *magick)
01005 %
01006 %  A description of each parameter follows.
01007 %
01008 %   o  magick:  ImageMagick format specification "magick" tag.
01009 %
01010 */
01011 MagickExport char *MagickToMime(const char *magick)
01012 {
01013   char
01014     filename[MaxTextExtent],
01015     media[MaxTextExtent];
01016 
01017   const MimeInfo
01018     *mime_info;
01019 
01020   ExceptionInfo
01021     *exception;
01022 
01023   (void) FormatMagickString(filename,MaxTextExtent,"file.%s",magick);
01024   LocaleLower(filename);
01025   exception=AcquireExceptionInfo();
01026   mime_info=GetMimeInfo(filename,(unsigned char *) " ",1,exception);
01027   exception=DestroyExceptionInfo(exception);
01028   if (mime_info != (const MimeInfo *) NULL)
01029     return(ConstantString(GetMimeType(mime_info)));
01030   (void) FormatMagickString(media,MaxTextExtent,"image/x-%s",magick);
01031   LocaleLower(media+8);
01032   return(ConstantString(media));
01033 }
01034 
01035 /*
01036 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01037 %                                                                             %
01038 %                                                                             %
01039 %                                                                             %
01040 +   M i m e C o m p o n e n t G e n e s i s                                   %
01041 %                                                                             %
01042 %                                                                             %
01043 %                                                                             %
01044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01045 %
01046 %  MimeComponentGenesis() instantiates the mime component.
01047 %
01048 %  The format of the MimeComponentGenesis method is:
01049 %
01050 %      MagickBooleanType MimeComponentGenesis(void)
01051 %
01052 */
01053 MagickExport MagickBooleanType MimeComponentGenesis(void)
01054 {
01055   AcquireSemaphoreInfo(&mime_semaphore);
01056   return(MagickTrue);
01057 }
01058 
01059 /*
01060 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01061 %                                                                             %
01062 %                                                                             %
01063 %                                                                             %
01064 +   M i m e C o m p o n e n t T e r m i n u s                                 %
01065 %                                                                             %
01066 %                                                                             %
01067 %                                                                             %
01068 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01069 %
01070 %  MimeComponentTerminus() destroys the mime component.
01071 %
01072 %  The format of the MimeComponentTerminus method is:
01073 %
01074 %      MimeComponentTerminus(void)
01075 %
01076 */
01077 
01078 static void *DestroyMimeElement(void *mime_info)
01079 {
01080   register MimeInfo
01081     *p;
01082 
01083   p=(MimeInfo *) mime_info;
01084   if (p->magic != (unsigned char *) NULL)
01085     p->magic=(unsigned char *) RelinquishMagickMemory(p->magic);
01086   if (p->pattern != (char *) NULL)
01087     p->pattern=DestroyString(p->pattern);
01088   if (p->description != (char *) NULL)
01089     p->description=DestroyString(p->description);
01090   if (p->type != (char *) NULL)
01091     p->type=DestroyString(p->type);
01092   if (p->path != (char *) NULL)
01093     p->path=DestroyString(p->path);
01094   p=(MimeInfo *) RelinquishMagickMemory(p);
01095   return((void *) NULL);
01096 }
01097 
01098 MagickExport void MimeComponentTerminus(void)
01099 {
01100   if (mime_semaphore == (SemaphoreInfo *) NULL)
01101     AcquireSemaphoreInfo(&mime_semaphore);
01102   (void) LockSemaphoreInfo(mime_semaphore);
01103   if (mime_list != (LinkedListInfo *) NULL)
01104     mime_list=DestroyLinkedList(mime_list,DestroyMimeElement);
01105   instantiate_mime=MagickFalse;
01106   (void) UnlockSemaphoreInfo(mime_semaphore);
01107   DestroySemaphoreInfo(&mime_semaphore);
01108 }

Generated on 19 Nov 2009 for MagickCore by  doxygen 1.6.1