|
MagickCore
6.7.5
|
00001 /* 00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00003 % % 00004 % % 00005 % % 00006 % CCCC OOO DDDD EEEEE RRRR % 00007 % C O O D D E R R % 00008 % C O O D D EEE RRRR % 00009 % C O O D D E R R % 00010 % CCCC OOO DDDD EEEEE R R % 00011 % % 00012 % % 00013 % MagickCore Image Coder Methods % 00014 % % 00015 % Software Design % 00016 % John Cristy % 00017 % May 2001 % 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/coder.h" 00046 #include "MagickCore/coder-private.h" 00047 #include "MagickCore/configure.h" 00048 #include "MagickCore/draw.h" 00049 #include "MagickCore/exception.h" 00050 #include "MagickCore/exception-private.h" 00051 #include "MagickCore/hashmap.h" 00052 #include "MagickCore/log.h" 00053 #include "MagickCore/memory_.h" 00054 #include "MagickCore/option.h" 00055 #include "MagickCore/semaphore.h" 00056 #include "MagickCore/string_.h" 00057 #include "MagickCore/splay-tree.h" 00058 #include "MagickCore/token.h" 00059 #include "MagickCore/utility.h" 00060 #include "MagickCore/utility-private.h" 00061 #include "MagickCore/xml-tree.h" 00062 00063 /* 00064 Define declarations. 00065 */ 00066 #define MagickCoderFilename "coder.xml" 00067 00068 /* 00069 Typedef declarations. 00070 */ 00071 typedef struct _CoderMapInfo 00072 { 00073 const char 00074 *magick, 00075 *name; 00076 } CoderMapInfo; 00077 00078 /* 00079 Static declarations. 00080 */ 00081 static const CoderMapInfo 00082 CoderMap[] = 00083 { 00084 { "3FR", "DNG" }, 00085 { "8BIM", "META" }, 00086 { "8BIMTEXT", "META" }, 00087 { "8BIMWTEXT", "META" }, 00088 { "AFM", "TTF" }, 00089 { "A", "RAW" }, 00090 { "AI", "PDF" }, 00091 { "APP1JPEG", "META" }, 00092 { "APP1", "META" }, 00093 { "ARW", "DNG" }, 00094 { "AVI", "MPEG" }, 00095 { "BIE", "JBIG" }, 00096 { "BMP2", "BMP" }, 00097 { "BMP3", "BMP" }, 00098 { "B", "RAW" }, 00099 { "BRF", "BRAILLE" }, 00100 { "BGRA", "BGR" }, 00101 { "CMYKA", "CMYK" }, 00102 { "C", "RAW" }, 00103 { "CAL", "CALS" }, 00104 { "CANVAS", "XC" }, 00105 { "CR2", "DNG" }, 00106 { "CRW", "DNG" }, 00107 { "CUR", "ICON" }, 00108 { "DCR", "DNG" }, 00109 { "DCX", "PCX" }, 00110 { "DFONT", "TTF" }, 00111 { "EPDF", "PDF" }, 00112 { "EPI", "PS" }, 00113 { "EPS2", "PS2" }, 00114 { "EPS3", "PS3" }, 00115 { "EPSF", "PS" }, 00116 { "EPSI", "PS" }, 00117 { "EPS", "PS" }, 00118 { "EPT2", "EPT" }, 00119 { "EPT3", "EPT" }, 00120 { "ERF", "DNG" }, 00121 { "EXIF", "META" }, 00122 { "FILE", "URL" }, 00123 { "FRACTAL", "PLASMA" }, 00124 { "FTP", "URL" }, 00125 { "FTS", "FITS" }, 00126 { "G3", "FAX" }, 00127 { "GIF87", "GIF" }, 00128 { "G", "RAW" }, 00129 { "GRANITE", "MAGICK" }, 00130 { "GROUP4", "TIFF" }, 00131 { "K25", "DNG" }, 00132 { "KDC", "DNG" }, 00133 { "H", "MAGICK" }, 00134 { "HTM", "HTML" }, 00135 { "HTTP", "URL" }, 00136 { "ICB", "TGA" }, 00137 { "ICC", "META" }, 00138 { "ICM", "META" }, 00139 { "ICO", "ICON" }, 00140 { "IMPLICIT", "***" }, 00141 { "IPTC", "META" }, 00142 { "IPTCTEXT", "META" }, 00143 { "IPTCWTEXT", "META" }, 00144 { "ISOBRL", "BRAILLE" }, 00145 { "JBG", "JBIG" }, 00146 { "JNG", "PNG" }, 00147 { "JPC", "JP2" }, 00148 { "J2C", "JP2" }, 00149 { "JPG", "JPEG" }, 00150 { "JPX", "JP2" }, 00151 { "K", "RAW" }, 00152 { "LOGO", "MAGICK" }, 00153 { "M2V", "MPEG" }, 00154 { "M4V", "MPEG" }, 00155 { "M", "RAW" }, 00156 { "MNG", "PNG" }, 00157 { "MOV", "MPEG" }, 00158 { "MP4", "MPEG" }, 00159 { "MPG", "MPEG" }, 00160 { "MPRI", "MPR" }, 00161 { "MEF", "DNG" }, 00162 { "MRW", "DNG" }, 00163 { "MSVG", "SVG" }, 00164 { "NEF", "DNG" }, 00165 { "NETSCAPE", "MAGICK" }, 00166 { "O", "RAW" }, 00167 { "ORF", "DNG" }, 00168 { "OTF", "TTF" }, 00169 { "P7", "PNM" }, 00170 { "PAL", "UYVY" }, 00171 { "PAM", "PNM" }, 00172 { "PBM", "PNM" }, 00173 { "PCDS", "PCD" }, 00174 { "PDFA", "PDF" }, 00175 { "PEF", "DNG" }, 00176 { "PEF", "DNG" }, 00177 { "PFA", "TTF" }, 00178 { "PFB", "TTF" }, 00179 { "PFM", "PNM" }, 00180 { "PGM", "PNM" }, 00181 { "PGX", "JP2" }, 00182 { "PICON", "XPM" }, 00183 { "PJPEG", "JPEG" }, 00184 { "PM", "XPM" }, 00185 { "PNG24", "PNG" }, 00186 { "PNG32", "PNG" }, 00187 { "PNG8", "PNG" }, 00188 { "PPM", "PNM" }, 00189 { "PSB", "PSD" }, 00190 { "PTIF", "TIFF" }, 00191 { "RADIAL-GRADIENT", "GRADIENT" }, 00192 { "RAF", "DNG" }, 00193 { "RAS", "SUN" }, 00194 { "RGBA", "RGB" }, 00195 { "RGBO", "RGB" }, 00196 { "R", "RAW" }, 00197 { "ROSE", "MAGICK" }, 00198 { "SHTML", "HTML" }, 00199 { "SR2", "DNG" }, 00200 { "SRF", "DNG" }, 00201 { "SVGZ", "SVG" }, 00202 { "TEXT", "TXT" }, 00203 { "TIFF64", "TIFF" }, 00204 { "TIF", "TIFF" }, 00205 { "TTC", "TTF" }, 00206 { "UBRL", "BRAILLE" }, 00207 { "VDA", "TGA" }, 00208 { "VST", "TGA" }, 00209 { "WIZARD", "MAGICK" }, 00210 { "WMV", "MPEG" }, 00211 { "WMFWIN32", "EMF" }, 00212 { "WMZ", "WMF" }, 00213 { "X3f", "DNG" }, 00214 { "XMP", "META" }, 00215 { "XTRNARRAY", "XTRN" }, 00216 { "XTRNBLOB", "XTRN" }, 00217 { "XTRNFILE", "XTRN" }, 00218 { "XTRNIMAGE", "XTRN" }, 00219 { "XV", "VIFF" }, 00220 { "Y", "RAW" }, 00221 { "YCbCrA", "YCbCr" } 00222 }; 00223 00224 static SemaphoreInfo 00225 *coder_semaphore = (SemaphoreInfo *) NULL; 00226 00227 static SplayTreeInfo 00228 *coder_list = (SplayTreeInfo *) NULL; 00229 00230 static volatile MagickBooleanType 00231 instantiate_coder = MagickFalse; 00232 00233 /* 00234 Forward declarations. 00235 */ 00236 static MagickBooleanType 00237 InitializeCoderList(ExceptionInfo *), 00238 LoadCoderLists(const char *,ExceptionInfo *); 00239 00240 /* 00241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00242 % % 00243 % % 00244 % % 00245 + C o d e r C o m p o n e n t G e n e s i s % 00246 % % 00247 % % 00248 % % 00249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00250 % 00251 % CoderComponentGenesis() instantiates the coder component. 00252 % 00253 % The format of the CoderComponentGenesis method is: 00254 % 00255 % MagickBooleanType CoderComponentGenesis(void) 00256 % 00257 */ 00258 MagickPrivate MagickBooleanType CoderComponentGenesis(void) 00259 { 00260 AcquireSemaphoreInfo(&coder_semaphore); 00261 return(MagickTrue); 00262 } 00263 00264 /* 00265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00266 % % 00267 % % 00268 % % 00269 + C o d e r C o m p o n e n t T e r m i n u s % 00270 % % 00271 % % 00272 % % 00273 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00274 % 00275 % CoderComponentTerminus() destroys the coder component. 00276 % 00277 % The format of the CoderComponentTerminus method is: 00278 % 00279 % CoderComponentTerminus(void) 00280 % 00281 */ 00282 MagickPrivate void CoderComponentTerminus(void) 00283 { 00284 if (coder_semaphore == (SemaphoreInfo *) NULL) 00285 AcquireSemaphoreInfo(&coder_semaphore); 00286 LockSemaphoreInfo(coder_semaphore); 00287 if (coder_list != (SplayTreeInfo *) NULL) 00288 coder_list=DestroySplayTree(coder_list); 00289 instantiate_coder=MagickFalse; 00290 UnlockSemaphoreInfo(coder_semaphore); 00291 DestroySemaphoreInfo(&coder_semaphore); 00292 } 00293 00294 /* 00295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00296 % % 00297 % % 00298 % % 00299 + G e t C o d e r I n f o % 00300 % % 00301 % % 00302 % % 00303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00304 % 00305 % GetCoderInfo searches the coder list for the specified name and if found 00306 % returns attributes for that coder. 00307 % 00308 % The format of the GetCoderInfo method is: 00309 % 00310 % const CoderInfo *GetCoderInfo(const char *name,ExceptionInfo *exception) 00311 % 00312 % A description of each parameter follows: 00313 % 00314 % o name: the coder name. 00315 % 00316 % o exception: return any errors or warnings in this structure. 00317 % 00318 */ 00319 MagickExport const CoderInfo *GetCoderInfo(const char *name, 00320 ExceptionInfo *exception) 00321 { 00322 assert(exception != (ExceptionInfo *) NULL); 00323 if ((coder_list == (SplayTreeInfo *) NULL) || 00324 (instantiate_coder == MagickFalse)) 00325 if (InitializeCoderList(exception) == MagickFalse) 00326 return((const CoderInfo *) NULL); 00327 if ((coder_list == (SplayTreeInfo *) NULL) || 00328 (GetNumberOfNodesInSplayTree(coder_list) == 0)) 00329 return((const CoderInfo *) NULL); 00330 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0)) 00331 { 00332 ResetSplayTreeIterator(coder_list); 00333 return((const CoderInfo *) GetNextValueInSplayTree(coder_list)); 00334 } 00335 return((const CoderInfo *) GetValueFromSplayTree(coder_list,name)); 00336 } 00337 00338 /* 00339 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00340 % % 00341 % % 00342 % % 00343 % G e t C o d e r I n f o L i s t % 00344 % % 00345 % % 00346 % % 00347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00348 % 00349 % GetCoderInfoList() returns any coder_map that match the specified pattern. 00350 % The format of the GetCoderInfoList function is: 00351 % 00352 % const CoderInfo **GetCoderInfoList(const char *pattern, 00353 % size_t *number_coders,ExceptionInfo *exception) 00354 % 00355 % A description of each parameter follows: 00356 % 00357 % o pattern: Specifies a pointer to a text string containing a pattern. 00358 % 00359 % o number_coders: This integer returns the number of coders in the list. 00360 % 00361 % o exception: return any errors or warnings in this structure. 00362 % 00363 */ 00364 00365 static int CoderInfoCompare(const void *x,const void *y) 00366 { 00367 const CoderInfo 00368 **p, 00369 **q; 00370 00371 p=(const CoderInfo **) x, 00372 q=(const CoderInfo **) y; 00373 if (LocaleCompare((*p)->path,(*q)->path) == 0) 00374 return(LocaleCompare((*p)->name,(*q)->name)); 00375 return(LocaleCompare((*p)->path,(*q)->path)); 00376 } 00377 00378 MagickExport const CoderInfo **GetCoderInfoList(const char *pattern, 00379 size_t *number_coders,ExceptionInfo *exception) 00380 { 00381 const CoderInfo 00382 **coder_map; 00383 00384 register const CoderInfo 00385 *p; 00386 00387 register ssize_t 00388 i; 00389 00390 /* 00391 Allocate coder list. 00392 */ 00393 assert(pattern != (char *) NULL); 00394 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern); 00395 assert(number_coders != (size_t *) NULL); 00396 *number_coders=0; 00397 p=GetCoderInfo("*",exception); 00398 if (p == (const CoderInfo *) NULL) 00399 return((const CoderInfo **) NULL); 00400 coder_map=(const CoderInfo **) AcquireQuantumMemory((size_t) 00401 GetNumberOfNodesInSplayTree(coder_list)+1UL,sizeof(*coder_map)); 00402 if (coder_map == (const CoderInfo **) NULL) 00403 return((const CoderInfo **) NULL); 00404 /* 00405 Generate coder list. 00406 */ 00407 LockSemaphoreInfo(coder_semaphore); 00408 ResetSplayTreeIterator(coder_list); 00409 p=(const CoderInfo *) GetNextValueInSplayTree(coder_list); 00410 for (i=0; p != (const CoderInfo *) NULL; ) 00411 { 00412 if ((p->stealth == MagickFalse) && 00413 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse)) 00414 coder_map[i++]=p; 00415 p=(const CoderInfo *) GetNextValueInSplayTree(coder_list); 00416 } 00417 UnlockSemaphoreInfo(coder_semaphore); 00418 qsort((void *) coder_map,(size_t) i,sizeof(*coder_map),CoderInfoCompare); 00419 coder_map[i]=(CoderInfo *) NULL; 00420 *number_coders=(size_t) i; 00421 return(coder_map); 00422 } 00423 00424 /* 00425 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00426 % % 00427 % % 00428 % % 00429 % G e t C o d e r L i s t % 00430 % % 00431 % % 00432 % % 00433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00434 % 00435 % GetCoderList() returns any coder_map that match the specified pattern. 00436 % 00437 % The format of the GetCoderList function is: 00438 % 00439 % char **GetCoderList(const char *pattern,size_t *number_coders, 00440 % ExceptionInfo *exception) 00441 % 00442 % A description of each parameter follows: 00443 % 00444 % o pattern: Specifies a pointer to a text string containing a pattern. 00445 % 00446 % o number_coders: This integer returns the number of coders in the list. 00447 % 00448 % o exception: return any errors or warnings in this structure. 00449 % 00450 */ 00451 00452 static int CoderCompare(const void *x,const void *y) 00453 { 00454 register const char 00455 **p, 00456 **q; 00457 00458 p=(const char **) x; 00459 q=(const char **) y; 00460 return(LocaleCompare(*p,*q)); 00461 } 00462 00463 MagickExport char **GetCoderList(const char *pattern, 00464 size_t *number_coders,ExceptionInfo *exception) 00465 { 00466 char 00467 **coder_map; 00468 00469 register const CoderInfo 00470 *p; 00471 00472 register ssize_t 00473 i; 00474 00475 /* 00476 Allocate coder list. 00477 */ 00478 assert(pattern != (char *) NULL); 00479 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern); 00480 assert(number_coders != (size_t *) NULL); 00481 *number_coders=0; 00482 p=GetCoderInfo("*",exception); 00483 if (p == (const CoderInfo *) NULL) 00484 return((char **) NULL); 00485 coder_map=(char **) AcquireQuantumMemory((size_t) 00486 GetNumberOfNodesInSplayTree(coder_list)+1UL,sizeof(*coder_map)); 00487 if (coder_map == (char **) NULL) 00488 return((char **) NULL); 00489 /* 00490 Generate coder list. 00491 */ 00492 LockSemaphoreInfo(coder_semaphore); 00493 ResetSplayTreeIterator(coder_list); 00494 p=(const CoderInfo *) GetNextValueInSplayTree(coder_list); 00495 for (i=0; p != (const CoderInfo *) NULL; ) 00496 { 00497 if ((p->stealth == MagickFalse) && 00498 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse)) 00499 coder_map[i++]=ConstantString(p->name); 00500 p=(const CoderInfo *) GetNextValueInSplayTree(coder_list); 00501 } 00502 UnlockSemaphoreInfo(coder_semaphore); 00503 qsort((void *) coder_map,(size_t) i,sizeof(*coder_map),CoderCompare); 00504 coder_map[i]=(char *) NULL; 00505 *number_coders=(size_t) i; 00506 return(coder_map); 00507 } 00508 00509 /* 00510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00511 % % 00512 % % 00513 % % 00514 + I n i t i a l i z e C o d e r L i s t % 00515 % % 00516 % % 00517 % % 00518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00519 % 00520 % InitializeCoderList() initializes the coder list. 00521 % 00522 % The format of the InitializeCoderList method is: 00523 % 00524 % MagickBooleanType InitializeCoderList(ExceptionInfo *exception) 00525 % 00526 % A description of each parameter follows. 00527 % 00528 % o exception: return any errors or warnings in this structure. 00529 % 00530 */ 00531 static MagickBooleanType InitializeCoderList(ExceptionInfo *exception) 00532 { 00533 if ((coder_list == (SplayTreeInfo *) NULL) && 00534 (instantiate_coder == MagickFalse)) 00535 { 00536 if (coder_semaphore == (SemaphoreInfo *) NULL) 00537 AcquireSemaphoreInfo(&coder_semaphore); 00538 LockSemaphoreInfo(coder_semaphore); 00539 if ((coder_list == (SplayTreeInfo *) NULL) && 00540 (instantiate_coder == MagickFalse)) 00541 { 00542 (void) LoadCoderLists(MagickCoderFilename,exception); 00543 instantiate_coder=MagickTrue; 00544 } 00545 UnlockSemaphoreInfo(coder_semaphore); 00546 } 00547 return(coder_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse); 00548 } 00549 00550 /* 00551 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00552 % % 00553 % % 00554 % % 00555 % L i s t C o d e r I n f o % 00556 % % 00557 % % 00558 % % 00559 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00560 % 00561 % ListCoderInfo() lists the coder info to a file. 00562 % 00563 % The format of the ListCoderInfo coder is: 00564 % 00565 % MagickBooleanType ListCoderInfo(FILE *file,ExceptionInfo *exception) 00566 % 00567 % A description of each parameter follows. 00568 % 00569 % o file: An pointer to a FILE. 00570 % 00571 % o exception: return any errors or warnings in this structure. 00572 % 00573 */ 00574 MagickExport MagickBooleanType ListCoderInfo(FILE *file, 00575 ExceptionInfo *exception) 00576 { 00577 const char 00578 *path; 00579 00580 const CoderInfo 00581 **coder_info; 00582 00583 register ssize_t 00584 i; 00585 00586 size_t 00587 number_coders; 00588 00589 ssize_t 00590 j; 00591 00592 if (file == (const FILE *) NULL) 00593 file=stdout; 00594 coder_info=GetCoderInfoList("*",&number_coders,exception); 00595 if (coder_info == (const CoderInfo **) NULL) 00596 return(MagickFalse); 00597 path=(const char *) NULL; 00598 for (i=0; i < (ssize_t) number_coders; i++) 00599 { 00600 if (coder_info[i]->stealth != MagickFalse) 00601 continue; 00602 if ((path == (const char *) NULL) || 00603 (LocaleCompare(path,coder_info[i]->path) != 0)) 00604 { 00605 if (coder_info[i]->path != (char *) NULL) 00606 (void) FormatLocaleFile(file,"\nPath: %s\n\n",coder_info[i]->path); 00607 (void) FormatLocaleFile(file,"Magick Coder\n"); 00608 (void) FormatLocaleFile(file, 00609 "-------------------------------------------------" 00610 "------------------------------\n"); 00611 } 00612 path=coder_info[i]->path; 00613 (void) FormatLocaleFile(file,"%s",coder_info[i]->magick); 00614 for (j=(ssize_t) strlen(coder_info[i]->magick); j <= 11; j++) 00615 (void) FormatLocaleFile(file," "); 00616 if (coder_info[i]->name != (char *) NULL) 00617 (void) FormatLocaleFile(file,"%s",coder_info[i]->name); 00618 (void) FormatLocaleFile(file,"\n"); 00619 } 00620 coder_info=(const CoderInfo **) RelinquishMagickMemory((void *) coder_info); 00621 (void) fflush(file); 00622 return(MagickTrue); 00623 } 00624 00625 /* 00626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00627 % % 00628 % % 00629 % % 00630 + L o a d C o d e r L i s t % 00631 % % 00632 % % 00633 % % 00634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00635 % 00636 % LoadCoderList() loads the coder configuration file which provides a 00637 % mapping between coder attributes and a coder name. 00638 % 00639 % The format of the LoadCoderList coder is: 00640 % 00641 % MagickBooleanType LoadCoderList(const char *xml,const char *filename, 00642 % const size_t depth,ExceptionInfo *exception) 00643 % 00644 % A description of each parameter follows: 00645 % 00646 % o xml: The coder list in XML format. 00647 % 00648 % o filename: The coder 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 00656 static void *DestroyCoderNode(void *coder_info) 00657 { 00658 register CoderInfo 00659 *p; 00660 00661 p=(CoderInfo *) coder_info; 00662 if (p->exempt == MagickFalse) 00663 { 00664 if (p->path != (char *) NULL) 00665 p->path=DestroyString(p->path); 00666 if (p->name != (char *) NULL) 00667 p->name=DestroyString(p->name); 00668 if (p->magick != (char *) NULL) 00669 p->magick=DestroyString(p->magick); 00670 } 00671 return(RelinquishMagickMemory(p)); 00672 } 00673 00674 static MagickBooleanType LoadCoderList(const char *xml,const char *filename, 00675 const size_t depth,ExceptionInfo *exception) 00676 { 00677 char 00678 keyword[MaxTextExtent], 00679 *token; 00680 00681 const char 00682 *q; 00683 00684 CoderInfo 00685 *coder_info; 00686 00687 MagickBooleanType 00688 status; 00689 00690 /* 00691 Load the coder map file. 00692 */ 00693 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), 00694 "Loading coder configuration file \"%s\" ...",filename); 00695 if (xml == (const char *) NULL) 00696 return(MagickFalse); 00697 if (coder_list == (SplayTreeInfo *) NULL) 00698 { 00699 coder_list=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory, 00700 DestroyCoderNode); 00701 if (coder_list == (SplayTreeInfo *) NULL) 00702 { 00703 ThrowFileException(exception,ResourceLimitError, 00704 "MemoryAllocationFailed",filename); 00705 return(MagickFalse); 00706 } 00707 } 00708 status=MagickTrue; 00709 coder_info=(CoderInfo *) NULL; 00710 token=AcquireString(xml); 00711 for (q=(char *) xml; *q != '\0'; ) 00712 { 00713 /* 00714 Interpret XML. 00715 */ 00716 GetMagickToken(q,&q,token); 00717 if (*token == '\0') 00718 break; 00719 (void) CopyMagickString(keyword,token,MaxTextExtent); 00720 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) 00721 { 00722 /* 00723 Doctype element. 00724 */ 00725 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) 00726 GetMagickToken(q,&q,token); 00727 continue; 00728 } 00729 if (LocaleNCompare(keyword,"<!--",4) == 0) 00730 { 00731 /* 00732 Comment element. 00733 */ 00734 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) 00735 GetMagickToken(q,&q,token); 00736 continue; 00737 } 00738 if (LocaleCompare(keyword,"<include") == 0) 00739 { 00740 /* 00741 Include element. 00742 */ 00743 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0')) 00744 { 00745 (void) CopyMagickString(keyword,token,MaxTextExtent); 00746 GetMagickToken(q,&q,token); 00747 if (*token != '=') 00748 continue; 00749 GetMagickToken(q,&q,token); 00750 if (LocaleCompare(keyword,"file") == 0) 00751 { 00752 if (depth > 200) 00753 (void) ThrowMagickException(exception,GetMagickModule(), 00754 ConfigureError,"IncludeNodeNestedTooDeeply","`%s'",token); 00755 else 00756 { 00757 char 00758 path[MaxTextExtent], 00759 *xml; 00760 00761 GetPathComponent(filename,HeadPath,path); 00762 if (*path != '\0') 00763 (void) ConcatenateMagickString(path,DirectorySeparator, 00764 MaxTextExtent); 00765 if (*token == *DirectorySeparator) 00766 (void) CopyMagickString(path,token,MaxTextExtent); 00767 else 00768 (void) ConcatenateMagickString(path,token,MaxTextExtent); 00769 xml=FileToString(path,~0,exception); 00770 if (xml != (char *) NULL) 00771 { 00772 status=LoadCoderList(xml,path,depth+1,exception); 00773 xml=(char *) RelinquishMagickMemory(xml); 00774 } 00775 } 00776 } 00777 } 00778 continue; 00779 } 00780 if (LocaleCompare(keyword,"<coder") == 0) 00781 { 00782 /* 00783 Coder element. 00784 */ 00785 coder_info=(CoderInfo *) AcquireMagickMemory(sizeof(*coder_info)); 00786 if (coder_info == (CoderInfo *) NULL) 00787 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 00788 (void) ResetMagickMemory(coder_info,0,sizeof(*coder_info)); 00789 coder_info->path=ConstantString(filename); 00790 coder_info->exempt=MagickFalse; 00791 coder_info->signature=MagickSignature; 00792 continue; 00793 } 00794 if (coder_info == (CoderInfo *) NULL) 00795 continue; 00796 if (LocaleCompare(keyword,"/>") == 0) 00797 { 00798 status=AddValueToSplayTree(coder_list,ConstantString( 00799 coder_info->magick),coder_info); 00800 if (status == MagickFalse) 00801 (void) ThrowMagickException(exception,GetMagickModule(), 00802 ResourceLimitError,"MemoryAllocationFailed","`%s'", 00803 coder_info->magick); 00804 coder_info=(CoderInfo *) NULL; 00805 } 00806 GetMagickToken(q,(const char **) NULL,token); 00807 if (*token != '=') 00808 continue; 00809 GetMagickToken(q,&q,token); 00810 GetMagickToken(q,&q,token); 00811 switch (*keyword) 00812 { 00813 case 'M': 00814 case 'm': 00815 { 00816 if (LocaleCompare((char *) keyword,"magick") == 0) 00817 { 00818 coder_info->magick=ConstantString(token); 00819 break; 00820 } 00821 break; 00822 } 00823 case 'N': 00824 case 'n': 00825 { 00826 if (LocaleCompare((char *) keyword,"name") == 0) 00827 { 00828 coder_info->name=ConstantString(token); 00829 break; 00830 } 00831 break; 00832 } 00833 case 'S': 00834 case 's': 00835 { 00836 if (LocaleCompare((char *) keyword,"stealth") == 0) 00837 { 00838 coder_info->stealth=IsMagickTrue(token); 00839 break; 00840 } 00841 break; 00842 } 00843 default: 00844 break; 00845 } 00846 } 00847 token=(char *) RelinquishMagickMemory(token); 00848 return(status); 00849 } 00850 00851 /* 00852 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00853 % % 00854 % % 00855 % % 00856 % L o a d C o d e r L i s t s % 00857 % % 00858 % % 00859 % % 00860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00861 % 00862 % LoadCoderLists() loads one or more coder configuration file which 00863 % provides a mapping between coder attributes and a coder name. 00864 % 00865 % The format of the LoadCoderLists coder is: 00866 % 00867 % MagickBooleanType LoadCoderLists(const char *filename, 00868 % ExceptionInfo *exception) 00869 % 00870 % A description of each parameter follows: 00871 % 00872 % o filename: the font file name. 00873 % 00874 % o exception: return any errors or warnings in this structure. 00875 % 00876 */ 00877 static MagickBooleanType LoadCoderLists(const char *filename, 00878 ExceptionInfo *exception) 00879 { 00880 const StringInfo 00881 *option; 00882 00883 LinkedListInfo 00884 *options; 00885 00886 MagickStatusType 00887 status; 00888 00889 register ssize_t 00890 i; 00891 00892 /* 00893 Load built-in coder map. 00894 */ 00895 status=MagickFalse; 00896 if (coder_list == (SplayTreeInfo *) NULL) 00897 { 00898 coder_list=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory, 00899 DestroyCoderNode); 00900 if (coder_list == (SplayTreeInfo *) NULL) 00901 { 00902 ThrowFileException(exception,ResourceLimitError, 00903 "MemoryAllocationFailed",filename); 00904 return(MagickFalse); 00905 } 00906 } 00907 for (i=0; i < (ssize_t) (sizeof(CoderMap)/sizeof(*CoderMap)); i++) 00908 { 00909 CoderInfo 00910 *coder_info; 00911 00912 register const CoderMapInfo 00913 *p; 00914 00915 p=CoderMap+i; 00916 coder_info=(CoderInfo *) AcquireMagickMemory(sizeof(*coder_info)); 00917 if (coder_info == (CoderInfo *) NULL) 00918 { 00919 (void) ThrowMagickException(exception,GetMagickModule(), 00920 ResourceLimitError,"MemoryAllocationFailed","`%s'",coder_info->name); 00921 continue; 00922 } 00923 (void) ResetMagickMemory(coder_info,0,sizeof(*coder_info)); 00924 coder_info->path=(char *) "[built-in]"; 00925 coder_info->magick=(char *) p->magick; 00926 coder_info->name=(char *) p->name; 00927 coder_info->exempt=MagickTrue; 00928 coder_info->signature=MagickSignature; 00929 status=AddValueToSplayTree(coder_list,ConstantString(coder_info->magick), 00930 coder_info); 00931 if (status == MagickFalse) 00932 (void) ThrowMagickException(exception,GetMagickModule(), 00933 ResourceLimitError,"MemoryAllocationFailed","`%s'",coder_info->name); 00934 } 00935 /* 00936 Load external coder map. 00937 */ 00938 options=GetConfigureOptions(filename,exception); 00939 option=(const StringInfo *) GetNextValueInLinkedList(options); 00940 while (option != (const StringInfo *) NULL) 00941 { 00942 status|=LoadCoderList((const char *) GetStringInfoDatum(option), 00943 GetStringInfoPath(option),0,exception); 00944 option=(const StringInfo *) GetNextValueInLinkedList(options); 00945 } 00946 options=DestroyConfigureOptions(options); 00947 return(status != 0 ? MagickTrue : MagickFalse); 00948 }