magic.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                    M   M   AAA    GGGG  IIIII   CCCC                        %
00006 %                    MM MM  A   A  G        I    C                            %
00007 %                    M M M  AAAAA  G GGG    I    C                            %
00008 %                    M   M  A   A  G   G    I    C                            %
00009 %                    M   M  A   A   GGGG  IIIII   CCCC                        %
00010 %                                                                             %
00011 %                                                                             %
00012 %                      MagickCore Image Magic Methods                         %
00013 %                                                                             %
00014 %                              Software Design                                %
00015 %                              Bob Friesenhahn                                %
00016 %                                 July 2000                                   %
00017 %                                                                             %
00018 %                                                                             %
00019 %  Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization      %
00020 %  dedicated to making software imaging solutions freely available.           %
00021 %                                                                             %
00022 %  You may not use this file except in compliance with the License.  You may  %
00023 %  obtain a copy of the License at                                            %
00024 %                                                                             %
00025 %    http://www.imagemagick.org/script/license.php                            %
00026 %                                                                             %
00027 %  Unless required by applicable law or agreed to in writing, software        %
00028 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00029 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00030 %  See the License for the specific language governing permissions and        %
00031 %  limitations under the License.                                             %
00032 %                                                                             %
00033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00034 %
00035 %
00036 */
00037 
00038 /*
00039   Include declarations.
00040 */
00041 #include "magick/studio.h"
00042 #include "magick/blob.h"
00043 #include "magick/client.h"
00044 #include "magick/configure.h"
00045 #include "magick/exception.h"
00046 #include "magick/exception-private.h"
00047 #include "magick/hashmap.h"
00048 #include "magick/magic.h"
00049 #include "magick/memory_.h"
00050 #include "magick/semaphore.h"
00051 #include "magick/string_.h"
00052 #include "magick/token.h"
00053 #include "magick/utility.h"
00054 #include "magick/xml-tree.h"
00055 
00056 /*
00057   Define declarations.
00058 */
00059 #define MagicFilename  "magic.xml"
00060 #define MagickString(magic)  (const unsigned char *) (magic), sizeof(magic)-1
00061 
00062 /*
00063   Typedef declarations.
00064 */
00065 typedef struct _MagicMapInfo
00066 {
00067   const char
00068     *name;
00069 
00070   const MagickOffsetType
00071     offset;
00072 
00073   const unsigned char
00074     *magic;
00075 
00076   const size_t
00077     length;
00078 } MagicMapInfo;
00079 
00080 /*
00081   Static declarations.
00082 */
00083 static const MagicMapInfo
00084   MagicMap[] =
00085   {
00086     { "AVI", 0, MagickString("RIFF") },
00087     { "8BIMWTEXT", 0, MagickString("8\000B\000I\000M\000#") },
00088     { "8BIMTEXT", 0, MagickString("8BIM#") },
00089     { "8BIM", 0, MagickString("8BIM") },
00090     { "BMP", 0, MagickString("BA") },
00091     { "BMP", 0, MagickString("BM") },
00092     { "BMP", 0, MagickString("CI") },
00093     { "BMP", 0, MagickString("CP") },
00094     { "BMP", 0, MagickString("IC") },
00095     { "BMP", 0, MagickString("PI") },
00096     { "CALS", 21, MagickString("version: MIL-STD-1840") },
00097     { "CALS", 0, MagickString("srcdocid:") },
00098     { "CALS", 9, MagickString("srcdocid:") },
00099     { "CALS", 8, MagickString("rorient:") },
00100     { "CGM", 0, MagickString("BEGMF") },
00101     { "CIN", 0, MagickString("\200\052\137\327") },
00102     { "CRW", 0, MagickString("II\x1a\x00\x00\x00HEAPCCDR") },
00103     { "DCM", 128, MagickString("DICM") },
00104     { "DCX", 0, MagickString("\261\150\336\72") },
00105     { "DIB", 0, MagickString("\050\000") },
00106     { "DDS", 0, MagickString("DDS ") },
00107     { "DJVU", 0, MagickString("AT&TFORM") },
00108     { "DOT", 0, MagickString("digraph") },
00109     { "DPX", 0, MagickString("SDPX") },
00110     { "DPX", 0, MagickString("XPDS") },
00111     { "EMF", 40, MagickString("\040\105\115\106\000\000\001\000") },
00112     { "EPT", 0, MagickString("\305\320\323\306") },
00113     { "EXR", 0, MagickString("\166\057\061\001") },
00114     { "FAX", 0, MagickString("DFAX") },
00115     { "FIG", 0, MagickString("#FIG") },
00116     { "FITS", 0, MagickString("IT0") },
00117     { "FITS", 0, MagickString("SIMPLE") },
00118     { "FPX", 0, MagickString("\320\317\021\340") },
00119     { "GIF", 0, MagickString("GIF8") },
00120     { "GPLT", 0, MagickString("#!/usr/local/bin/gnuplot") },
00121     { "HDF", 1, MagickString("HDF") },
00122     { "HPGL", 0, MagickString("IN;") },
00123     { "HPGL", 0, MagickString("\033E\033") },
00124     { "HTML", 1, MagickString("HTML") },
00125     { "HTML", 1, MagickString("html") },
00126     { "ILBM", 8, MagickString("ILBM") },
00127     { "IPTCWTEXT", 0, MagickString("\062\000#\000\060\000=\000\042\000&\000#\000\060\000;\000&\000#\000\062\000;\000\042\000") },
00128     { "IPTCTEXT", 0, MagickString("2#0=\042�\042") },
00129     { "IPTC", 0, MagickString("\034\002") },
00130     { "JNG", 0, MagickString("\213JNG\r\n\032\n") },
00131     { "JPEG", 0, MagickString("\377\330\377") },
00132     { "JPC", 0, MagickString("\377\117") },
00133     { "JP2", 4, MagickString("\152\120\040\040\015") },
00134     { "MIFF", 0, MagickString("Id=ImageMagick") },
00135     { "MIFF", 0, MagickString("id=ImageMagick") },
00136     { "MNG", 0, MagickString("\212MNG\r\n\032\n") },
00137     { "MPC", 0, MagickString("id=MagickCache") },
00138     { "MPEG", 0, MagickString("\000\000\001\263") },
00139     { "MRW", 0, MagickString("\x00MRM") },
00140     { "MVG", 0, MagickString("push graphic-context") },
00141     { "ORF", 0, MagickString("IIRO\x08\x00\x00\x00") },
00142     { "PCD", 2048, MagickString("PCD_") },
00143     { "PCL", 0, MagickString("\033E\033") },
00144     { "PCX", 0, MagickString("\012\002") },
00145     { "PCX", 0, MagickString("\012\005") },
00146     { "PDB", 60, MagickString("vIMGView") },
00147     { "PDF", 0, MagickString("%PDF-") },
00148     { "PFA", 0, MagickString("%!PS-AdobeFont-1.0") },
00149     { "PFB", 6, MagickString("%!PS-AdobeFont-1.0") },
00150     { "PGX", 0, MagickString("\050\107\020\115\046") },
00151     { "PICT", 522, MagickString("\000\021\002\377\014\000") },
00152     { "PNG", 0, MagickString("\211PNG\r\n\032\n") },
00153     { "PNM", 0, MagickString("P1") },
00154     { "PNM", 0, MagickString("P2") },
00155     { "PNM", 0, MagickString("P3") },
00156     { "PNM", 0, MagickString("P4") },
00157     { "PNM", 0, MagickString("P5") },
00158     { "PNM", 0, MagickString("P6") },
00159     { "PNM", 0, MagickString("P7") },
00160     { "PNM", 0, MagickString("PF") },
00161     { "PNM", 0, MagickString("Pf") },
00162     { "PS", 0, MagickString("%!") },
00163     { "PS", 0, MagickString("\004%!") },
00164     { "PS", 0, MagickString("\305\320\323\306") },
00165     { "PSD", 0, MagickString("8BPS") },
00166     { "PWP", 0, MagickString("SFW95") },
00167     { "RAF", 0, MagickString("FUJIFILMCCD-RAW ") },
00168     { "RAD", 0, MagickString("#?RADIANCE") },
00169     { "RAD", 0, MagickString("VIEW= ") },
00170     { "RLE", 0, MagickString("\122\314") },
00171     { "SCT", 0, MagickString("CT") },
00172     { "SFW", 0, MagickString("SFW94") },
00173     { "SGI", 0, MagickString("\001\332") },
00174     { "SUN", 0, MagickString("\131\246\152\225") },
00175     { "SVG", 1, MagickString("?XML") },
00176     { "SVG", 1, MagickString("?xml") },
00177     { "TIFF", 0, MagickString("\115\115\000\052") },
00178     { "TIFF", 0, MagickString("\111\111\052\000") },
00179     { "TIFF64", 0, MagickString("\115\115\000\053\000\010\000\000") },
00180     { "TIFF64", 0, MagickString("\111\111\053\000\010\000\000\000") },
00181     { "TXT", 0, MagickString("# ImageMagick pixel enumeration:") },
00182     { "VICAR", 0, MagickString("LBLSIZE") },
00183     { "VICAR", 0, MagickString("NJPL1I") },
00184     { "VIFF", 0, MagickString("\253\001") },
00185     { "WMF", 0, MagickString("\327\315\306\232") },
00186     { "WMF", 0, MagickString("\001\000\011\000") },
00187     { "WPG", 0, MagickString("\377WPC") },
00188     { "XBM", 0, MagickString("#define") },
00189     { "XCF", 0, MagickString("gimp xcf") },
00190     { "XEF", 0, MagickString("FOVb") },
00191     { "XPM", 1, MagickString("* XPM *") },
00192     { "XWD", 4, MagickString("\007\000\000") },
00193     { "XWD", 5, MagickString("\000\000\007") }
00194  };
00195 
00196 static LinkedListInfo
00197   *magic_list = (LinkedListInfo *) NULL;
00198 
00199 static SemaphoreInfo
00200   *magic_semaphore = (SemaphoreInfo *) NULL;
00201 
00202 static volatile MagickBooleanType
00203   instantiate_magic = MagickFalse;
00204 
00205 /*
00206   Forward declarations.
00207 */
00208 static MagickBooleanType
00209   InitializeMagicList(ExceptionInfo *),
00210   LoadMagicLists(const char *,ExceptionInfo *);
00211 
00212 /*
00213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00214 %                                                                             %
00215 %                                                                             %
00216 %                                                                             %
00217 +   G e t M a g i c I n f o                                                   %
00218 %                                                                             %
00219 %                                                                             %
00220 %                                                                             %
00221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00222 %
00223 %  GetMagicInfo() searches the magic list for the specified name and if found
00224 %  returns attributes for that magic.
00225 %
00226 %  The format of the GetMagicInfo method is:
00227 %
00228 %      const MagicInfo *GetMagicInfo(const unsigned char *magic,
00229 %        const size_t length,ExceptionInfo *exception)
00230 %
00231 %  A description of each parameter follows:
00232 %
00233 %    o magic: A binary string generally representing the first few characters
00234 %      of the image file or blob.
00235 %
00236 %    o length: the length of the binary signature.
00237 %
00238 %    o exception: return any errors or warnings in this structure.
00239 %
00240 */
00241 MagickExport const MagicInfo *GetMagicInfo(const unsigned char *magic,
00242   const size_t length,ExceptionInfo *exception)
00243 {
00244   register const MagicInfo
00245     *p;
00246 
00247   assert(exception != (ExceptionInfo *) NULL);
00248   if ((magic_list == (LinkedListInfo *) NULL) ||
00249       (instantiate_magic == MagickFalse))
00250     if (InitializeMagicList(exception) == MagickFalse)
00251       return((const MagicInfo *) NULL);
00252   if ((magic_list == (LinkedListInfo *) NULL) ||
00253       (IsLinkedListEmpty(magic_list) != MagickFalse))
00254     return((const MagicInfo *) NULL);
00255   if (magic == (const unsigned char *) NULL)
00256     return((const MagicInfo *) GetValueFromLinkedList(magic_list,0));
00257   if (length == 0)
00258     return((const MagicInfo *) NULL);
00259   /*
00260     Search for magic tag.
00261   */
00262   (void) LockSemaphoreInfo(magic_semaphore);
00263   ResetLinkedListIterator(magic_list);
00264   p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
00265   while (p != (const MagicInfo *) NULL)
00266   {
00267     assert(p->offset >= 0);
00268     if (((size_t) (p->offset+p->length) <= length) &&
00269         (memcmp(magic+p->offset,p->magic,p->length) == 0))
00270       break;
00271     p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
00272   }
00273   if (p != (const MagicInfo *) NULL)
00274     (void) InsertValueInLinkedList(magic_list,0,
00275       RemoveElementByValueFromLinkedList(magic_list,p));
00276   (void) UnlockSemaphoreInfo(magic_semaphore);
00277   return(p);
00278 }
00279 
00280 /*
00281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00282 %                                                                             %
00283 %                                                                             %
00284 %                                                                             %
00285 %   G e t M a g i c I n f o L i s t                                           %
00286 %                                                                             %
00287 %                                                                             %
00288 %                                                                             %
00289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00290 %
00291 %  GetMagicInfoList() returns any image aliases that match the specified
00292 %  pattern.
00293 %
00294 %  The magic of the GetMagicInfoList function is:
00295 %
00296 %      const MagicInfo **GetMagicInfoList(const char *pattern,
00297 %        unsigned long *number_aliases,ExceptionInfo *exception)
00298 %
00299 %  A description of each parameter follows:
00300 %
00301 %    o pattern: Specifies a pointer to a text string containing a pattern.
00302 %
00303 %    o number_aliases:  This integer returns the number of aliases in the list.
00304 %
00305 %    o exception: return any errors or warnings in this structure.
00306 %
00307 */
00308 
00309 #if defined(__cplusplus) || defined(c_plusplus)
00310 extern "C" {
00311 #endif
00312 
00313 static int MagicInfoCompare(const void *x,const void *y)
00314 {
00315   const MagicInfo
00316     **p,
00317     **q;
00318 
00319   p=(const MagicInfo **) x,
00320   q=(const MagicInfo **) y;
00321   if (LocaleCompare((*p)->path,(*q)->path) == 0)
00322     return(LocaleCompare((*p)->name,(*q)->name));
00323   return(LocaleCompare((*p)->path,(*q)->path));
00324 }
00325 
00326 #if defined(__cplusplus) || defined(c_plusplus)
00327 }
00328 #endif
00329 
00330 MagickExport const MagicInfo **GetMagicInfoList(const char *pattern,
00331   unsigned long *number_aliases,ExceptionInfo *exception)
00332 {
00333   const MagicInfo
00334     **aliases;
00335 
00336   register const MagicInfo
00337     *p;
00338 
00339   register long
00340     i;
00341 
00342   /*
00343     Allocate magic list.
00344   */
00345   assert(pattern != (char *) NULL);
00346   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00347   assert(number_aliases != (unsigned long *) NULL);
00348   *number_aliases=0;
00349   p=GetMagicInfo((const unsigned char *) NULL,0,exception);
00350   if (p == (const MagicInfo *) NULL)
00351     return((const MagicInfo **) NULL);
00352   aliases=(const MagicInfo **) AcquireQuantumMemory((size_t)
00353     GetNumberOfElementsInLinkedList(magic_list)+1UL,sizeof(*aliases));
00354   if (aliases == (const MagicInfo **) NULL)
00355     return((const MagicInfo **) NULL);
00356   /*
00357     Generate magic list.
00358   */
00359   (void) LockSemaphoreInfo(magic_semaphore);
00360   ResetLinkedListIterator(magic_list);
00361   p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
00362   for (i=0; p != (const MagicInfo *) NULL; )
00363   {
00364     if ((p->stealth == MagickFalse) &&
00365         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
00366       aliases[i++]=p;
00367     p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
00368   }
00369   (void) UnlockSemaphoreInfo(magic_semaphore);
00370   qsort((void *) aliases,(size_t) i,sizeof(*aliases),MagicInfoCompare);
00371   aliases[i]=(MagicInfo *) NULL;
00372   *number_aliases=(unsigned long) i;
00373   return(aliases);
00374 }
00375 
00376 /*
00377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00378 %                                                                             %
00379 %                                                                             %
00380 %                                                                             %
00381 %   G e t M a g i c L i s t                                                   %
00382 %                                                                             %
00383 %                                                                             %
00384 %                                                                             %
00385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00386 %
00387 %  GetMagicList() returns any image format aliases that match the specified
00388 %  pattern.
00389 %
00390 %  The format of the GetMagicList function is:
00391 %
00392 %      char **GetMagicList(const char *pattern,unsigned long *number_aliases,
00393 %        ExceptionInfo *exception)
00394 %
00395 %  A description of each parameter follows:
00396 %
00397 %    o pattern: Specifies a pointer to a text string containing a pattern.
00398 %
00399 %    o number_aliases:  This integer returns the number of image format aliases
00400 %      in the list.
00401 %
00402 %    o exception: return any errors or warnings in this structure.
00403 %
00404 */
00405 
00406 #if defined(__cplusplus) || defined(c_plusplus)
00407 extern "C" {
00408 #endif
00409 
00410 static int MagicCompare(const void *x,const void *y)
00411 {
00412   register const char
00413     *p,
00414     *q;
00415 
00416   p=(const char *) x;
00417   q=(const char *) y;
00418   return(LocaleCompare(p,q));
00419 }
00420 
00421 #if defined(__cplusplus) || defined(c_plusplus)
00422 }
00423 #endif
00424 
00425 MagickExport char **GetMagicList(const char *pattern,
00426   unsigned long *number_aliases,ExceptionInfo *exception)
00427 {
00428   char
00429     **aliases;
00430 
00431   register const MagicInfo
00432     *p;
00433 
00434   register long
00435     i;
00436 
00437   /*
00438     Allocate configure list.
00439   */
00440   assert(pattern != (char *) NULL);
00441   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00442   assert(number_aliases != (unsigned long *) NULL);
00443   *number_aliases=0;
00444   p=GetMagicInfo((const unsigned char *) NULL,0,exception);
00445   if (p == (const MagicInfo *) NULL)
00446     return((char **) NULL);
00447   aliases=(char **) AcquireQuantumMemory((size_t)
00448     GetNumberOfElementsInLinkedList(magic_list)+1UL,sizeof(*aliases));
00449   if (aliases == (char **) NULL)
00450     return((char **) NULL);
00451   (void) LockSemaphoreInfo(magic_semaphore);
00452   ResetLinkedListIterator(magic_list);
00453   p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
00454   for (i=0; p != (const MagicInfo *) NULL; )
00455   {
00456     if ((p->stealth == MagickFalse) &&
00457         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
00458       aliases[i++]=ConstantString(p->name);
00459     p=(const MagicInfo *) GetNextValueInLinkedList(magic_list);
00460   }
00461   (void) UnlockSemaphoreInfo(magic_semaphore);
00462   qsort((void *) aliases,(size_t) i,sizeof(*aliases),MagicCompare);
00463   aliases[i]=(char *) NULL;
00464   *number_aliases=(unsigned long) i;
00465   return(aliases);
00466 }
00467 
00468 /*
00469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00470 %                                                                             %
00471 %                                                                             %
00472 %                                                                             %
00473 %   G e t M a g i c N a m e                                                   %
00474 %                                                                             %
00475 %                                                                             %
00476 %                                                                             %
00477 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00478 %
00479 %  GetMagicName() returns the name associated with the magic.
00480 %
00481 %  The format of the GetMagicName method is:
00482 %
00483 %      const char *GetMagicName(const MagicInfo *magic_info)
00484 %
00485 %  A description of each parameter follows:
00486 %
00487 %    o magic_info:  The magic info.
00488 %
00489 */
00490 MagickExport const char *GetMagicName(const MagicInfo *magic_info)
00491 {
00492   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00493   assert(magic_info != (MagicInfo *) NULL);
00494   assert(magic_info->signature == MagickSignature);
00495   return(magic_info->name);
00496 }
00497 
00498 /*
00499 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00500 %                                                                             %
00501 %                                                                             %
00502 %                                                                             %
00503 +   I n i t i a l i z e M a g i c L i s t                                     %
00504 %                                                                             %
00505 %                                                                             %
00506 %                                                                             %
00507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00508 %
00509 %  InitializeMagicList() initializes the magic list.
00510 %
00511 %  The format of the InitializeMagicList method is:
00512 %
00513 %      MagickBooleanType InitializeMagicList(ExceptionInfo *exception)
00514 %
00515 %  A description of each parameter follows.
00516 %
00517 %    o exception: return any errors or warnings in this structure.
00518 %
00519 */
00520 static MagickBooleanType InitializeMagicList(ExceptionInfo *exception)
00521 {
00522   if ((magic_list == (LinkedListInfo *) NULL) &&
00523       (instantiate_magic == MagickFalse))
00524     {
00525       if (magic_semaphore == (SemaphoreInfo *) NULL)
00526         AcquireSemaphoreInfo(&magic_semaphore);
00527       (void) LockSemaphoreInfo(magic_semaphore);
00528       if ((magic_list == (LinkedListInfo *) NULL) &&
00529           (instantiate_magic == MagickFalse))
00530         {
00531           (void) LoadMagicLists(MagicFilename,exception);
00532           instantiate_magic=MagickTrue;
00533         }
00534       (void) UnlockSemaphoreInfo(magic_semaphore);
00535     }
00536   return(magic_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
00537 }
00538 
00539 /*
00540 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00541 %                                                                             %
00542 %                                                                             %
00543 %                                                                             %
00544 %  L i s t M a g i c I n f o                                                  %
00545 %                                                                             %
00546 %                                                                             %
00547 %                                                                             %
00548 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00549 %
00550 %  ListMagicInfo() lists the magic info to a file.
00551 %
00552 %  The format of the ListMagicInfo method is:
00553 %
00554 %      MagickBooleanType ListMagicInfo(FILE *file,ExceptionInfo *exception)
00555 %
00556 %  A description of each parameter follows.
00557 %
00558 %    o file:  An pointer to a FILE.
00559 %
00560 %    o exception: return any errors or warnings in this structure.
00561 %
00562 */
00563 MagickExport MagickBooleanType ListMagicInfo(FILE *file,
00564   ExceptionInfo *exception)
00565 {
00566   const char
00567     *path;
00568 
00569   const MagicInfo
00570     **magic_info;
00571 
00572   long
00573     j;
00574 
00575   register long
00576     i;
00577 
00578   unsigned long
00579     number_aliases;
00580 
00581   if (file == (const FILE *) NULL)
00582     file=stdout;
00583   magic_info=GetMagicInfoList("*",&number_aliases,exception);
00584   if (magic_info == (const MagicInfo **) NULL)
00585     return(MagickFalse);
00586   j=0;
00587   path=(const char *) NULL;
00588   for (i=0; i < (long) number_aliases; i++)
00589   {
00590     if (magic_info[i]->stealth != MagickFalse)
00591       continue;
00592     if ((path == (const char *) NULL) ||
00593         (LocaleCompare(path,magic_info[i]->path) != 0))
00594       {
00595         if (magic_info[i]->path != (char *) NULL)
00596           (void) fprintf(file,"\nPath: %s\n\n",magic_info[i]->path);
00597         (void) fprintf(file,"Name      Offset Target\n");
00598         (void) fprintf(file,"-------------------------------------------------"
00599           "------------------------------\n");
00600       }
00601     path=magic_info[i]->path;
00602     (void) fprintf(file,"%s",magic_info[i]->name);
00603     for (j=(long) strlen(magic_info[i]->name); j <= 9; j++)
00604       (void) fprintf(file," ");
00605     (void) fprintf(file,"%6ld ",(long) magic_info[i]->offset);
00606     if (magic_info[i]->target != (char *) NULL)
00607       {
00608         register long
00609           j;
00610 
00611         for (j=0; magic_info[i]->target[j] != '\0'; j++)
00612           if (isprint((int) ((unsigned char) magic_info[i]->target[j])) != 0)
00613             (void) fprintf(file,"%c",magic_info[i]->target[j]);
00614           else
00615             (void) fprintf(file,"\\%03o",(unsigned int)
00616               ((unsigned char) magic_info[i]->target[j]));
00617       }
00618     (void) fprintf(file,"\n");
00619   }
00620   (void) fflush(file);
00621   magic_info=(const MagicInfo **) RelinquishMagickMemory((void *) magic_info);
00622   return(MagickTrue);
00623 }
00624 
00625 /*
00626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00627 %                                                                             %
00628 %                                                                             %
00629 %                                                                             %
00630 +   L o a d M a g i c L i s t                                                 %
00631 %                                                                             %
00632 %                                                                             %
00633 %                                                                             %
00634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00635 %
00636 %  LoadMagicList() loads the magic configuration file which provides a mapping
00637 %  between magic attributes and a magic name.
00638 %
00639 %  The format of the LoadMagicList method is:
00640 %
00641 %      MagickBooleanType LoadMagicList(const char *xml,const char *filename,
00642 %        const unsigned long depth,ExceptionInfo *exception)
00643 %
00644 %  A description of each parameter follows:
00645 %
00646 %    o xml: The magic list in XML format.
00647 %
00648 %    o filename: The magic list filename.
00649 %
00650 %    o depth: depth of <include /> statements.
00651 %
00652 %    o exception: return any errors or warnings in this structure.
00653 %
00654 */
00655 static MagickBooleanType LoadMagicList(const char *xml,const char *filename,
00656   const unsigned long depth,ExceptionInfo *exception)
00657 {
00658   char
00659     keyword[MaxTextExtent],
00660     *token;
00661 
00662   const char
00663     *q;
00664 
00665   MagickBooleanType
00666     status;
00667 
00668   MagicInfo
00669     *magic_info;
00670 
00671   /*
00672     Load the magic map file.
00673   */
00674   (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
00675     "Loading magic configure file \"%s\" ...",filename);
00676   if (xml == (char *) NULL)
00677     return(MagickFalse);
00678   if (magic_list == (LinkedListInfo *) NULL)
00679     {
00680       magic_list=NewLinkedList(0);
00681       if (magic_list == (LinkedListInfo *) NULL)
00682         {
00683           ThrowFileException(exception,ResourceLimitError,
00684             "MemoryAllocationFailed",filename);
00685           return(MagickFalse);
00686         }
00687     }
00688   status=MagickTrue;
00689   magic_info=(MagicInfo *) NULL;
00690   token=AcquireString(xml);
00691   for (q=(char *) xml; *q != '\0'; )
00692   {
00693     /*
00694       Interpret XML.
00695     */
00696     GetMagickToken(q,&q,token);
00697     if (*token == '\0')
00698       break;
00699     (void) CopyMagickString(keyword,token,MaxTextExtent);
00700     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
00701       {
00702         /*
00703           Doctype element.
00704         */
00705         while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
00706           GetMagickToken(q,&q,token);
00707         continue;
00708       }
00709     if (LocaleNCompare(keyword,"<!--",4) == 0)
00710       {
00711         /*
00712           Comment element.
00713         */
00714         while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
00715           GetMagickToken(q,&q,token);
00716         continue;
00717       }
00718     if (LocaleCompare(keyword,"<include") == 0)
00719       {
00720         /*
00721           Include element.
00722         */
00723         while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
00724         {
00725           (void) CopyMagickString(keyword,token,MaxTextExtent);
00726           GetMagickToken(q,&q,token);
00727           if (*token != '=')
00728             continue;
00729           GetMagickToken(q,&q,token);
00730           if (LocaleCompare(keyword,"file") == 0)
00731             {
00732               if (depth > 200)
00733                 (void) ThrowMagickException(exception,GetMagickModule(),
00734                   ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
00735               else
00736                 {
00737                   char
00738                     path[MaxTextExtent],
00739                     *xml;
00740 
00741                   GetPathComponent(filename,HeadPath,path);
00742                   if (*path != '\0')
00743                     (void) ConcatenateMagickString(path,DirectorySeparator,
00744                       MaxTextExtent);
00745                   if (*token == *DirectorySeparator)
00746                     (void) CopyMagickString(path,token,MaxTextExtent);
00747                   else
00748                     (void) ConcatenateMagickString(path,token,MaxTextExtent);
00749                   xml=FileToString(path,~0,exception);
00750                   if (xml != (char *) NULL)
00751                     {
00752                       status=LoadMagicList(xml,path,depth+1,exception);
00753                       xml=(char *) RelinquishMagickMemory(xml);
00754                     }
00755                 }
00756             }
00757         }
00758         continue;
00759       }
00760     if (LocaleCompare(keyword,"<magic") == 0)
00761       {
00762         /*
00763           Magic element.
00764         */
00765         magic_info=(MagicInfo *) AcquireMagickMemory(sizeof(*magic_info));
00766         if (magic_info == (MagicInfo *) NULL)
00767           ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00768         (void) ResetMagickMemory(magic_info,0,sizeof(*magic_info));
00769         magic_info->path=ConstantString(filename);
00770         magic_info->exempt=MagickFalse;
00771         magic_info->signature=MagickSignature;
00772         continue;
00773       }
00774     if (magic_info == (MagicInfo *) NULL)
00775       continue;
00776     if (LocaleCompare(keyword,"/>") == 0)
00777       {
00778         status=AppendValueToLinkedList(magic_list,magic_info);
00779         if (status == MagickFalse)
00780           (void) ThrowMagickException(exception,GetMagickModule(),
00781             ResourceLimitError,"MemoryAllocationFailed","`%s'",
00782             magic_info->name);
00783         magic_info=(MagicInfo *) NULL;
00784       }
00785     GetMagickToken(q,(const char **) NULL,token);
00786     if (*token != '=')
00787       continue;
00788     GetMagickToken(q,&q,token);
00789     GetMagickToken(q,&q,token);
00790     switch (*keyword)
00791     {
00792       case 'N':
00793       case 'n':
00794       {
00795         if (LocaleCompare((char *) keyword,"name") == 0)
00796           {
00797             magic_info->name=ConstantString(token);
00798             break;
00799           }
00800         break;
00801       }
00802       case 'O':
00803       case 'o':
00804       {
00805         if (LocaleCompare((char *) keyword,"offset") == 0)
00806           {
00807             magic_info->offset=(MagickOffsetType) atol(token);
00808             break;
00809           }
00810         break;
00811       }
00812       case 'S':
00813       case 's':
00814       {
00815         if (LocaleCompare((char *) keyword,"stealth") == 0)
00816           {
00817             magic_info->stealth=IsMagickTrue(token);
00818             break;
00819           }
00820         break;
00821       }
00822       case 'T':
00823       case 't':
00824       {
00825         if (LocaleCompare((char *) keyword,"target") == 0)
00826           {
00827             char
00828               *p;
00829 
00830             register unsigned char
00831               *q;
00832 
00833             size_t
00834               length;
00835 
00836             length=strlen(token);
00837             magic_info->target=ConstantString(token);
00838             magic_info->magic=(unsigned char *) ConstantString(token);
00839             q=magic_info->magic;
00840             for (p=magic_info->target; *p != '\0'; )
00841             {
00842               if (*p == '\\')
00843                 {
00844                   p++;
00845                   if (isdigit((int) ((unsigned char) *p)) != 0)
00846                     {
00847                       char
00848                         *end;
00849 
00850                       *q++=(unsigned char) strtol(p,&end,8);
00851                       p+=(end-p);
00852                       magic_info->length++;
00853                       continue;
00854                     }
00855                   switch (*p)
00856                   {
00857                     case 'b': *q='\b'; break;
00858                     case 'f': *q='\f'; break;
00859                     case 'n': *q='\n'; break;
00860                     case 'r': *q='\r'; break;
00861                     case 't': *q='\t'; break;
00862                     case 'v': *q='\v'; break;
00863                     case 'a': *q='a'; break;
00864                     case '?': *q='\?'; break;
00865                     default: *q=(unsigned char) (*p); break;
00866                   }
00867                   p++;
00868                   q++;
00869                   magic_info->length++;
00870                   continue;
00871                 }
00872               else
00873                 if (LocaleNCompare(p,"&amp;",5) == 0)
00874                   (void) CopyMagickString(p+1,p+5,length-magic_info->length);
00875               *q++=(unsigned char) (*p++);
00876               magic_info->length++;
00877             }
00878             break;
00879           }
00880         break;
00881       }
00882       default:
00883         break;
00884     }
00885   }
00886   token=(char *) RelinquishMagickMemory(token);
00887   return(status);
00888 }
00889 
00890 /*
00891 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00892 %                                                                             %
00893 %                                                                             %
00894 %                                                                             %
00895 %  L o a d M a g i c L i s t s                                                %
00896 %                                                                             %
00897 %                                                                             %
00898 %                                                                             %
00899 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00900 %
00901 %  LoadMagicLists() loads one or more magic configuration file which provides a
00902 %  mapping between magic attributes and a magic name.
00903 %
00904 %  The format of the LoadMagicLists method is:
00905 %
00906 %      MagickBooleanType LoadMagicLists(const char *filename,
00907 %        ExceptionInfo *exception)
00908 %
00909 %  A description of each parameter follows:
00910 %
00911 %    o filename: the font file name.
00912 %
00913 %    o exception: return any errors or warnings in this structure.
00914 %
00915 */
00916 static MagickBooleanType LoadMagicLists(const char *filename,
00917   ExceptionInfo *exception)
00918 {
00919   char
00920     path[MaxTextExtent];
00921 
00922   const StringInfo
00923     *option;
00924 
00925   LinkedListInfo
00926     *options;
00927 
00928   MagickStatusType
00929     status;
00930 
00931   register long
00932     i;
00933 
00934   /*
00935     Load built-in magic map.
00936   */
00937   status=MagickFalse;
00938   if (magic_list == (LinkedListInfo *) NULL)
00939     {
00940       magic_list=NewLinkedList(0);
00941       if (magic_list == (LinkedListInfo *) NULL)
00942         {
00943           ThrowFileException(exception,ResourceLimitError,
00944             "MemoryAllocationFailed",filename);
00945           return(MagickFalse);
00946         }
00947     }
00948   for (i=0; i < (long) (sizeof(MagicMap)/sizeof(*MagicMap)); i++)
00949   {
00950     MagicInfo
00951       *magic_info;
00952 
00953     register const MagicMapInfo
00954       *p;
00955 
00956     p=MagicMap+i;
00957     magic_info=(MagicInfo *) AcquireMagickMemory(sizeof(*magic_info));
00958     if (magic_info == (MagicInfo *) NULL)
00959       {
00960         (void) ThrowMagickException(exception,GetMagickModule(),
00961           ResourceLimitError,"MemoryAllocationFailed","`%s'",magic_info->name);
00962         continue;
00963       }
00964     (void) ResetMagickMemory(magic_info,0,sizeof(*magic_info));
00965     magic_info->path=(char *) "[built-in]";
00966     magic_info->name=(char *) p->name;
00967     magic_info->offset=p->offset;
00968     magic_info->target=(char *) p->magic;
00969     magic_info->magic=(unsigned char *) p->magic;
00970     magic_info->length=p->length;
00971     magic_info->exempt=MagickTrue;
00972     magic_info->signature=MagickSignature;
00973     status=AppendValueToLinkedList(magic_list,magic_info);
00974     if (status == MagickFalse)
00975       (void) ThrowMagickException(exception,GetMagickModule(),
00976         ResourceLimitError,"MemoryAllocationFailed","`%s'",magic_info->name);
00977   }
00978   /*
00979     Load external magic map.
00980   */
00981   *path='\0';
00982   options=GetConfigureOptions(filename,exception);
00983   option=(const StringInfo *) GetNextValueInLinkedList(options);
00984   while (option != (const StringInfo *) NULL)
00985   {
00986     (void) CopyMagickString(path,GetStringInfoPath(option),MaxTextExtent);
00987     status|=LoadMagicList((const char *) GetStringInfoDatum(option),
00988       GetStringInfoPath(option),0,exception);
00989     option=(const StringInfo *) GetNextValueInLinkedList(options);
00990   }
00991   options=DestroyConfigureOptions(options);
00992   return(status != 0 ? MagickTrue : MagickFalse);
00993 }
00994 
00995 /*
00996 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00997 %                                                                             %
00998 %                                                                             %
00999 %                                                                             %
01000 +   M a g i c C o m p o n e n t G e n e s i s                                 %
01001 %                                                                             %
01002 %                                                                             %
01003 %                                                                             %
01004 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01005 %
01006 %  MagicComponentGenesis() instantiates the magic component.
01007 %
01008 %  The format of the MagicComponentGenesis method is:
01009 %
01010 %      MagickBooleanType MagicComponentGenesis(void)
01011 %
01012 */
01013 MagickExport MagickBooleanType MagicComponentGenesis(void)
01014 {
01015   AcquireSemaphoreInfo(&magic_semaphore);
01016   return(MagickTrue);
01017 }
01018 
01019 /*
01020 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01021 %                                                                             %
01022 %                                                                             %
01023 %                                                                             %
01024 +   M a g i c C o m p o n e n t T e r m i n u s                               %
01025 %                                                                             %
01026 %                                                                             %
01027 %                                                                             %
01028 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01029 %
01030 %  MagicComponentTerminus() destroys the magic component.
01031 %
01032 %  The format of the MagicComponentTerminus method is:
01033 %
01034 %      MagicComponentTerminus(void)
01035 %
01036 */
01037 
01038 static void *DestroyMagicElement(void *magic_info)
01039 {
01040   register MagicInfo
01041     *p;
01042 
01043   p=(MagicInfo *) magic_info;
01044   if (p->exempt == MagickFalse)
01045     {
01046       if (p->path != (char *) NULL)
01047         p->path=DestroyString(p->path);
01048       if (p->name != (char *) NULL)
01049         p->name=DestroyString(p->name);
01050       if (p->target != (char *) NULL)
01051         p->target=DestroyString(p->target);
01052       if (p->magic != (unsigned char *) NULL)
01053         p->magic=(unsigned char *) RelinquishMagickMemory(p->magic);
01054     }
01055   p=(MagicInfo *) RelinquishMagickMemory(p);
01056   return((void *) NULL);
01057 }
01058 
01059 MagickExport void MagicComponentTerminus(void)
01060 {
01061   if (magic_semaphore == (SemaphoreInfo *) NULL)
01062     AcquireSemaphoreInfo(&magic_semaphore);
01063   (void) LockSemaphoreInfo(magic_semaphore);
01064   if (magic_list != (LinkedListInfo *) NULL)
01065     magic_list=DestroyLinkedList(magic_list,DestroyMagicElement);
01066   instantiate_magic=MagickFalse;
01067   (void) UnlockSemaphoreInfo(magic_semaphore);
01068   DestroySemaphoreInfo(&magic_semaphore);
01069 }

Generated on 21 Nov 2009 for MagickCore by  doxygen 1.6.1