2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % CCCC OOO DDDD EEEEE RRRR %
10 % CCCC OOO DDDD EEEEE R R %
13 % MagickCore Image Coder Methods %
20 % Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "magick/studio.h"
43 #include "magick/blob.h"
44 #include "magick/client.h"
45 #include "magick/coder.h"
46 #include "magick/configure.h"
47 #include "magick/draw.h"
48 #include "magick/exception.h"
49 #include "magick/exception-private.h"
50 #include "magick/hashmap.h"
51 #include "magick/log.h"
52 #include "magick/memory_.h"
53 #include "magick/option.h"
54 #include "magick/semaphore.h"
55 #include "magick/string_.h"
56 #include "magick/splay-tree.h"
57 #include "magick/token.h"
58 #include "magick/utility.h"
59 #include "magick/xml-tree.h"
64 #define MagickCoderFilename "coder.xml"
70 *CoderMap = (const char *)
71 "<?xml version=\"1.0\"?>"
73 " <coder magick=\"3FR\" name=\"DNG\" />"
74 " <coder magick=\"8BIM\" name=\"META\" />"
75 " <coder magick=\"8BIMTEXT\" name=\"META\" />"
76 " <coder magick=\"8BIMWTEXT\" name=\"META\" />"
77 " <coder magick=\"A\" name=\"RAW\" />"
78 " <coder magick=\"AI\" name=\"PDF\" />"
79 " <coder magick=\"AFM\" name=\"TTF\" />"
80 " <coder magick=\"APP1JPEG\" name=\"META\" />"
81 " <coder magick=\"APP1\" name=\"META\" />"
82 " <coder magick=\"ARW\" name=\"DNG\" />"
83 " <coder magick=\"BIE\" name=\"JBIG\" />"
84 " <coder magick=\"BMP2\" name=\"BMP\" />"
85 " <coder magick=\"BMP3\" name=\"BMP\" />"
86 " <coder magick=\"B\" name=\"GRAY\" />"
87 " <coder magick=\"BRF\" name=\"BRAILLE\" />"
88 " <coder magick=\"CMYKA\" name=\"CMYK\" />"
89 " <coder magick=\"C\" name=\"GRAY\" />"
90 " <coder magick=\"CAL\" name=\"CALS\" />"
91 " <coder magick=\"CR2\" name=\"DNG\" />"
92 " <coder magick=\"CRW\" name=\"DNG\" />"
93 " <coder magick=\"CUR\" name=\"ICON\" />"
94 " <coder magick=\"DCR\" name=\"DNG\" />"
95 " <coder magick=\"DCX\" name=\"PCX\" />"
96 " <coder magick=\"DFONT\" name=\"TTF\" />"
97 " <coder magick=\"EMF\" name=\"EMF\" />"
98 " <coder magick=\"EPDF\" name=\"PDF\" />"
99 " <coder magick=\"EPI\" name=\"PS\" />"
100 " <coder magick=\"EPS2\" name=\"PS2\" />"
101 " <coder magick=\"EPS3\" name=\"PS3\" />"
102 " <coder magick=\"EPSF\" name=\"PS\" />"
103 " <coder magick=\"EPSI\" name=\"PS\" />"
104 " <coder magick=\"EPS\" name=\"PS\" />"
105 " <coder magick=\"EPT2\" name=\"EPT\" />"
106 " <coder magick=\"EPT3\" name=\"EPT\" />"
107 " <coder magick=\"ERF\" name=\"DNG\" />"
108 " <coder magick=\"EXIF\" name=\"META\" />"
109 " <coder magick=\"FILE\" name=\"URL\" />"
110 " <coder magick=\"FRACTAL\" name=\"PLASMA\" />"
111 " <coder magick=\"FTP\" name=\"URL\" />"
112 " <coder magick=\"FTS\" name=\"FITS\" />"
113 " <coder magick=\"G3\" name=\"FAX\" />"
114 " <coder magick=\"GIF87\" name=\"GIF\" />"
115 " <coder magick=\"G\" name=\"GRAY\" />"
116 " <coder magick=\"GRANITE\" name=\"MAGICK\" />"
117 " <coder magick=\"GROUP4\" name=\"TIFF\" />"
118 " <coder magick=\"H\" name=\"MAGICK\" />"
119 " <coder magick=\"HTM\" name=\"HTML\" />"
120 " <coder magick=\"HTTP\" name=\"URL\" />"
121 " <coder magick=\"ICB\" name=\"TGA\" />"
122 " <coder magick=\"ICC\" name=\"META\" />"
123 " <coder magick=\"ICM\" name=\"META\" />"
124 " <coder magick=\"ICO\" name=\"ICON\" />"
125 " <coder magick=\"IMPLICIT\" name=\"***\" />"
126 " <coder magick=\"IPTC\" name=\"META\" />"
127 " <coder magick=\"IPTCTEXT\" name=\"META\" />"
128 " <coder magick=\"IPTCWTEXT\" name=\"META\" />"
129 " <coder magick=\"ISOBRL\" name=\"BRAILLE\" />"
130 " <coder magick=\"JBG\" name=\"JBIG\" />"
131 " <coder magick=\"JNG\" name=\"PNG\" />"
132 " <coder magick=\"JPC\" name=\"JP2\" />"
133 " <coder magick=\"JPG\" name=\"JPEG\" />"
134 " <coder magick=\"JPX\" name=\"JP2\" />"
135 " <coder magick=\"K\" name=\"GRAY\" />"
136 " <coder magick=\"K25\" name=\"DNG\" />"
137 " <coder magick=\"KDC\" name=\"DNG\" />"
138 " <coder magick=\"LOGO\" name=\"MAGICK\" />"
139 " <coder magick=\"M2V\" name=\"MPEG\" />"
140 " <coder magick=\"M4V\" name=\"MPEG\" />"
141 " <coder magick=\"M\" name=\"GRAY\" />"
142 " <coder magick=\"MNG\" name=\"PNG\" />"
143 " <coder magick=\"MOV\" name=\"MPEG\" />"
144 " <coder magick=\"MPG\" name=\"MPEG\" />"
145 " <coder magick=\"MP4\" name=\"MPEG\" />"
146 " <coder magick=\"MPRI\" name=\"MPR\" />"
147 " <coder magick=\"MRW\" name=\"DNG\" />"
148 " <coder magick=\"MSVG\" name=\"SVG\" />"
149 " <coder magick=\"NEF\" name=\"DNG\" />"
150 " <coder magick=\"NETSCAPE\" name=\"MAGICK\" />"
151 " <coder magick=\"O\" name=\"GRAY\" />"
152 " <coder magick=\"ORF\" name=\"DNG\" />"
153 " <coder magick=\"OTF\" name=\"TTF\" />"
154 " <coder magick=\"P7\" name=\"PNM\" />"
155 " <coder magick=\"PAL\" name=\"UYVY\" />"
156 " <coder magick=\"PAM\" name=\"PNM\" />"
157 " <coder magick=\"PBM\" name=\"PNM\" />"
158 " <coder magick=\"PCDS\" name=\"PCD\" />"
159 " <coder magick=\"PCT\" name=\"PICT\" />"
160 " <coder magick=\"PDFA\" name=\"PDF\" />"
161 " <coder magick=\"PEF\" name=\"DNG\" />"
162 " <coder magick=\"PFA\" name=\"TTF\" />"
163 " <coder magick=\"PFB\" name=\"TTF\" />"
164 " <coder magick=\"PFM\" name=\"PNM\" />"
165 " <coder magick=\"PGM\" name=\"PNM\" />"
166 " <coder magick=\"PGX\" name=\"JP2\" />"
167 " <coder magick=\"PICON\" name=\"XPM\" />"
168 " <coder magick=\"PJPEG\" name=\"JPEG\" />"
169 " <coder magick=\"PM\" name=\"XPM\" />"
170 " <coder magick=\"PNG24\" name=\"PNG\" />"
171 " <coder magick=\"PNG32\" name=\"PNG\" />"
172 " <coder magick=\"PNG8\" name=\"PNG\" />"
173 " <coder magick=\"PPM\" name=\"PNM\" />"
174 " <coder magick=\"PTIF\" name=\"TIFF\" />"
175 " <coder magick=\"RADIAL-GRADIENT\" name=\"GRADIENT\" />"
176 " <coder magick=\"RAF\" name=\"DNG\" />"
177 " <coder magick=\"RAS\" name=\"SUN\" />"
178 " <coder magick=\"RGBA\" name=\"RGB\" />"
179 " <coder magick=\"RGBO\" name=\"RGB\" />"
180 " <coder magick=\"R\" name=\"GRAY\" />"
181 " <coder magick=\"ROSE\" name=\"MAGICK\" />"
182 " <coder magick=\"SHTML\" name=\"HTML\" />"
183 " <coder magick=\"SR2\" name=\"DNG\" />"
184 " <coder magick=\"SRF\" name=\"DNG\" />"
185 " <coder magick=\"SVGZ\" name=\"SVG\" />"
186 " <coder magick=\"TEXT\" name=\"TXT\" />"
187 " <coder magick=\"TIFF64\" name=\"TIFF\" />"
188 " <coder magick=\"TIF\" name=\"TIFF\" />"
189 " <coder magick=\"TTC\" name=\"TTF\" />"
190 " <coder magick=\"UBRL\" name=\"BRAILLE\" />"
191 " <coder magick=\"VDA\" name=\"TGA\" />"
192 " <coder magick=\"VST\" name=\"TGA\" />"
193 " <coder magick=\"WMFWIN32\" name=\"EMF\" />"
194 " <coder magick=\"WMV\" name=\"MPEG\" />"
195 " <coder magick=\"X3F\" name=\"DNG\" />"
196 " <coder magick=\"XTRNARRAY\" name=\"XTRN\" />"
197 " <coder magick=\"XTRNBLOB\" name=\"XTRN\" />"
198 " <coder magick=\"XTRNBSTR\" name=\"XTRN\" />"
199 " <coder magick=\"XTRNFILE\" name=\"XTRN\" />"
200 " <coder magick=\"XTRNIMAGE\" name=\"XTRN\" />"
201 " <coder magick=\"XTRNSTREAM\" name=\"XTRN\" />"
202 " <coder magick=\"XV\" name=\"VIFF\" />"
203 " <coder magick=\"Y\" name=\"GRAY\" />"
204 " <coder magick=\"YCbCrA\" name=\"YCbCr\" />"
211 *coder_semaphore = (SemaphoreInfo *) NULL;
214 *coder_list = (SplayTreeInfo *) NULL;
216 static volatile MagickBooleanType
217 instantiate_coder = MagickFalse;
220 Forward declarations.
222 static MagickBooleanType
223 InitializeCoderList(ExceptionInfo *),
224 LoadCoderLists(const char *,ExceptionInfo *);
227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
231 + D e s t r o y C o d e r L i s t %
235 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
237 % DestroyCoderList() deallocates memory associated with the font list.
239 % The format of the DestroyCoderList method is:
241 % DestroyCoderList(void)
244 MagickExport void DestroyCoderList(void)
246 AcquireSemaphoreInfo(&coder_semaphore);
247 if (coder_list != (SplayTreeInfo *) NULL)
248 coder_list=DestroySplayTree(coder_list);
249 instantiate_coder=MagickFalse;
250 RelinquishSemaphoreInfo(coder_semaphore);
251 DestroySemaphoreInfo(&coder_semaphore);
255 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
259 + G e t C o d e r I n f o %
263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
265 % GetCoderInfo searches the coder list for the specified name and if found
266 % returns attributes for that coder.
268 % The format of the GetCoderInfo method is:
270 % const CoderInfo *GetCoderInfo(const char *name,ExceptionInfo *exception)
272 % A description of each parameter follows:
274 % o name: the coder name.
276 % o exception: return any errors or warnings in this structure.
279 MagickExport const CoderInfo *GetCoderInfo(const char *name,
280 ExceptionInfo *exception)
282 assert(exception != (ExceptionInfo *) NULL);
283 if ((coder_list == (SplayTreeInfo *) NULL) ||
284 (instantiate_coder == MagickFalse))
285 if (InitializeCoderList(exception) == MagickFalse)
286 return((const CoderInfo *) NULL);
287 if ((coder_list == (SplayTreeInfo *) NULL) ||
288 (GetNumberOfNodesInSplayTree(coder_list) == 0))
289 return((const CoderInfo *) NULL);
290 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
292 ResetSplayTreeIterator(coder_list);
293 return((const CoderInfo *) GetNextValueInSplayTree(coder_list));
295 return((const CoderInfo *) GetValueFromSplayTree(coder_list,name));
299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
303 % G e t C o d e r I n f o L i s t %
307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
309 % GetCoderInfoList() returns any coder_map that match the specified pattern.
310 % The format of the GetCoderInfoList function is:
312 % const CoderInfo **GetCoderInfoList(const char *pattern,
313 % unsigned long *number_coders,ExceptionInfo *exception)
315 % A description of each parameter follows:
317 % o pattern: Specifies a pointer to a text string containing a pattern.
319 % o number_coders: This integer returns the number of coders in the list.
321 % o exception: return any errors or warnings in this structure.
325 static int CoderInfoCompare(const void *x,const void *y)
331 p=(const CoderInfo **) x,
332 q=(const CoderInfo **) y;
333 if (LocaleCompare((*p)->path,(*q)->path) == 0)
334 return(LocaleCompare((*p)->name,(*q)->name));
335 return(LocaleCompare((*p)->path,(*q)->path));
338 MagickExport const CoderInfo **GetCoderInfoList(const char *pattern,
339 unsigned long *number_coders,ExceptionInfo *exception)
344 register const CoderInfo
353 assert(pattern != (char *) NULL);
354 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
355 assert(number_coders != (unsigned long *) NULL);
357 p=GetCoderInfo("*",exception);
358 if (p == (const CoderInfo *) NULL)
359 return((const CoderInfo **) NULL);
360 coder_map=(const CoderInfo **) AcquireQuantumMemory((size_t)
361 GetNumberOfNodesInSplayTree(coder_list)+1UL,sizeof(*coder_map));
362 if (coder_map == (const CoderInfo **) NULL)
363 return((const CoderInfo **) NULL);
367 AcquireSemaphoreInfo(&coder_semaphore);
368 ResetSplayTreeIterator(coder_list);
369 p=(const CoderInfo *) GetNextValueInSplayTree(coder_list);
370 for (i=0; p != (const CoderInfo *) NULL; )
372 if ((p->stealth == MagickFalse) &&
373 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
375 p=(const CoderInfo *) GetNextValueInSplayTree(coder_list);
377 RelinquishSemaphoreInfo(coder_semaphore);
378 qsort((void *) coder_map,(size_t) i,sizeof(*coder_map),CoderInfoCompare);
379 coder_map[i]=(CoderInfo *) NULL;
380 *number_coders=(unsigned long) i;
385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
389 % G e t C o d e r L i s t %
393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
395 % GetCoderList() returns any coder_map that match the specified pattern.
397 % The format of the GetCoderList function is:
399 % char **GetCoderList(const char *pattern,unsigned long *number_coders,
400 % ExceptionInfo *exception)
402 % A description of each parameter follows:
404 % o pattern: Specifies a pointer to a text string containing a pattern.
406 % o number_coders: This integer returns the number of coders in the list.
408 % o exception: return any errors or warnings in this structure.
412 static int CoderCompare(const void *x,const void *y)
420 return(LocaleCompare(*p,*q));
423 MagickExport char **GetCoderList(const char *pattern,
424 unsigned long *number_coders,ExceptionInfo *exception)
429 register const CoderInfo
438 assert(pattern != (char *) NULL);
439 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
440 assert(number_coders != (unsigned long *) NULL);
442 p=GetCoderInfo("*",exception);
443 if (p == (const CoderInfo *) NULL)
444 return((char **) NULL);
445 coder_map=(char **) AcquireQuantumMemory((size_t)
446 GetNumberOfNodesInSplayTree(coder_list)+1UL,sizeof(*coder_map));
447 if (coder_map == (char **) NULL)
448 return((char **) NULL);
452 AcquireSemaphoreInfo(&coder_semaphore);
453 ResetSplayTreeIterator(coder_list);
454 p=(const CoderInfo *) GetNextValueInSplayTree(coder_list);
455 for (i=0; p != (const CoderInfo *) NULL; )
457 if ((p->stealth == MagickFalse) &&
458 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
459 coder_map[i++]=ConstantString(p->name);
460 p=(const CoderInfo *) GetNextValueInSplayTree(coder_list);
462 RelinquishSemaphoreInfo(coder_semaphore);
463 qsort((void *) coder_map,(size_t) i,sizeof(*coder_map),CoderCompare);
464 coder_map[i]=(char *) NULL;
465 *number_coders=(unsigned long) i;
470 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
474 + I n i t i a l i z e C o d e r L i s t %
478 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
480 % InitializeCoderList() initializes the coder list.
482 % The format of the InitializeCoderList method is:
484 % MagickBooleanType InitializeCoderList(ExceptionInfo *exception)
486 % A description of each parameter follows.
488 % o exception: return any errors or warnings in this structure.
491 static MagickBooleanType InitializeCoderList(ExceptionInfo *exception)
493 if ((coder_list == (SplayTreeInfo *) NULL) &&
494 (instantiate_coder == MagickFalse))
496 AcquireSemaphoreInfo(&coder_semaphore);
497 if ((coder_list == (SplayTreeInfo *) NULL) &&
498 (instantiate_coder == MagickFalse))
500 (void) LoadCoderLists(MagickCoderFilename,exception);
501 instantiate_coder=MagickTrue;
503 RelinquishSemaphoreInfo(coder_semaphore);
505 return(coder_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
509 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
513 % L i s t C o d e r I n f o %
517 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
519 % ListCoderInfo() lists the coder info to a file.
521 % The format of the ListCoderInfo coder is:
523 % MagickBooleanType ListCoderInfo(FILE *file,ExceptionInfo *exception)
525 % A description of each parameter follows.
527 % o file: An pointer to a FILE.
529 % o exception: return any errors or warnings in this structure.
532 MagickExport MagickBooleanType ListCoderInfo(FILE *file,
533 ExceptionInfo *exception)
550 if (file == (const FILE *) NULL)
552 coder_info=GetCoderInfoList("*",&number_coders,exception);
553 if (coder_info == (const CoderInfo **) NULL)
555 path=(const char *) NULL;
556 for (i=0; i < (long) number_coders; i++)
558 if (coder_info[i]->stealth != MagickFalse)
560 if ((path == (const char *) NULL) ||
561 (LocaleCompare(path,coder_info[i]->path) != 0))
563 if (coder_info[i]->path != (char *) NULL)
564 (void) fprintf(file,"\nPath: %s\n\n",coder_info[i]->path);
565 (void) fprintf(file,"Magick Coder\n");
566 (void) fprintf(file,"-------------------------------------------------"
567 "------------------------------\n");
569 path=coder_info[i]->path;
570 (void) fprintf(file,"%s",coder_info[i]->magick);
571 for (j=(long) strlen(coder_info[i]->magick); j <= 11; j++)
572 (void) fprintf(file," ");
573 if (coder_info[i]->name != (char *) NULL)
574 (void) fprintf(file,"%s",coder_info[i]->name);
575 (void) fprintf(file,"\n");
577 coder_info=(const CoderInfo **) RelinquishMagickMemory((void *) coder_info);
583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
587 + L o a d C o d e r L i s t %
591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
593 % LoadCoderList() loads the coder configuration file which provides a
594 % mapping between coder attributes and a coder name.
596 % The format of the LoadCoderList coder is:
598 % MagickBooleanType LoadCoderList(const char *xml,const char *filename,
599 % const unsigned long depth,ExceptionInfo *exception)
601 % A description of each parameter follows:
603 % o xml: The coder list in XML format.
605 % o filename: The coder list filename.
607 % o depth: depth of <include /> statements.
609 % o exception: return any errors or warnings in this structure.
613 static void *DestroyCoderNode(void *coder_info)
618 p=(CoderInfo *) coder_info;
619 if (p->path != (char *) NULL)
620 p->path=DestroyString(p->path);
621 if (p->name != (char *) NULL)
622 p->name=DestroyString(p->name);
623 if (p->magick != (char *) NULL)
624 p->magick=DestroyString(p->magick);
625 return(RelinquishMagickMemory(p));
628 static MagickBooleanType LoadCoderList(const char *xml,const char *filename,
629 const unsigned long depth,ExceptionInfo *exception)
632 keyword[MaxTextExtent],
645 Load the coder map file.
647 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
648 "Loading coder configuration file \"%s\" ...",filename);
649 if (xml == (const char *) NULL)
651 if (coder_list == (SplayTreeInfo *) NULL)
653 coder_list=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
655 if (coder_list == (SplayTreeInfo *) NULL)
657 ThrowFileException(exception,ResourceLimitError,
658 "MemoryAllocationFailed",filename);
663 coder_info=(CoderInfo *) NULL;
664 token=AcquireString(xml);
665 for (q=(char *) xml; *q != '\0'; )
670 GetMagickToken(q,&q,token);
673 (void) CopyMagickString(keyword,token,MaxTextExtent);
674 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
679 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
680 GetMagickToken(q,&q,token);
683 if (LocaleNCompare(keyword,"<!--",4) == 0)
688 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
689 GetMagickToken(q,&q,token);
692 if (LocaleCompare(keyword,"<include") == 0)
697 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
699 (void) CopyMagickString(keyword,token,MaxTextExtent);
700 GetMagickToken(q,&q,token);
703 GetMagickToken(q,&q,token);
704 if (LocaleCompare(keyword,"file") == 0)
707 (void) ThrowMagickException(exception,GetMagickModule(),
708 ConfigureError,"IncludeNodeNestedTooDeeply","`%s'",token);
715 GetPathComponent(filename,HeadPath,path);
717 (void) ConcatenateMagickString(path,DirectorySeparator,
719 if (*token == *DirectorySeparator)
720 (void) CopyMagickString(path,token,MaxTextExtent);
722 (void) ConcatenateMagickString(path,token,MaxTextExtent);
723 xml=FileToString(path,~0,exception);
724 if (xml != (char *) NULL)
726 status=LoadCoderList(xml,path,depth+1,exception);
727 xml=(char *) RelinquishMagickMemory(xml);
734 if (LocaleCompare(keyword,"<coder") == 0)
739 coder_info=(CoderInfo *) AcquireMagickMemory(sizeof(*coder_info));
740 if (coder_info == (CoderInfo *) NULL)
741 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
742 (void) ResetMagickMemory(coder_info,0,sizeof(*coder_info));
743 coder_info->path=ConstantString(filename);
744 coder_info->signature=MagickSignature;
747 if (coder_info == (CoderInfo *) NULL)
749 if (LocaleCompare(keyword,"/>") == 0)
751 status=AddValueToSplayTree(coder_list,ConstantString(
752 coder_info->magick),coder_info);
753 if (status == MagickFalse)
754 (void) ThrowMagickException(exception,GetMagickModule(),
755 ResourceLimitError,"MemoryAllocationFailed","`%s'",
757 coder_info=(CoderInfo *) NULL;
759 GetMagickToken(q,(const char **) NULL,token);
762 GetMagickToken(q,&q,token);
763 GetMagickToken(q,&q,token);
769 if (LocaleCompare((char *) keyword,"magick") == 0)
771 coder_info->magick=ConstantString(token);
779 if (LocaleCompare((char *) keyword,"name") == 0)
781 coder_info->name=ConstantString(token);
789 if (LocaleCompare((char *) keyword,"stealth") == 0)
791 coder_info->stealth=IsMagickTrue(token);
800 token=(char *) RelinquishMagickMemory(token);
805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
809 % L o a d C o d e r L i s t s %
813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
815 % LoadCoderLists() loads one or more coder configuration file which
816 % provides a mapping between coder attributes and a coder name.
818 % The format of the LoadCoderLists coder is:
820 % MagickBooleanType LoadCoderLists(const char *filename,
821 % ExceptionInfo *exception)
823 % A description of each parameter follows:
825 % o filename: the font file name.
827 % o exception: return any errors or warnings in this structure.
830 static MagickBooleanType LoadCoderLists(const char *filename,
831 ExceptionInfo *exception)
833 #if defined(MAGICKCORE_EMBEDDABLE_SUPPORT)
834 return(LoadCoderList(CoderMap,"built-in",0,exception));
846 options=GetConfigureOptions(filename,exception);
847 option=(const StringInfo *) GetNextValueInLinkedList(options);
848 while (option != (const StringInfo *) NULL)
850 status|=LoadCoderList((const char *) GetStringInfoDatum(option),
851 GetStringInfoPath(option),0,exception);
852 option=(const StringInfo *) GetNextValueInLinkedList(options);
854 options=DestroyConfigureOptions(options);
855 if ((coder_list == (SplayTreeInfo *) NULL) ||
856 (GetNumberOfNodesInSplayTree(coder_list) == 0))
857 status|=LoadCoderList(CoderMap,"built-in",0,exception);
858 return(status != 0 ? MagickTrue : MagickFalse);