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