root / ImageMagick / trunk / magick / coder.c

Revision 11974, 28.8 kB (checked in by cristy, 10 days ago)
Line 
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3%                                                                             %
4%                                                                             %
5%                                                                             %
6%                   CCCC   OOO   DDDD    EEEEE  RRRR                          %
7%                  C      O   O  D   D   E      R   R                         %
8%                  C      O   O  D   D   EEE    RRRR                          %
9%                  C      O   O  D   D   E      R R                           %
10%                   CCCC   OOO   DDDD    EEEEE  R  R                          %
11%                                                                             %
12%                                                                             %
13%                     ImageMagick Image Coder Methods                         %
14%                                                                             %
15%                              Software Design                                %
16%                                John Cristy                                  %
17%                                 May 2001                                    %
18%                                                                             %
19%                                                                             %
20%  Copyright 1999-2008 ImageMagick Studio LLC, a non-profit organization      %
21%  dedicated to making software imaging solutions freely available.           %
22%                                                                             %
23%  You may not use this file except in compliance with the License.  You may  %
24%  obtain a copy of the License at                                            %
25%                                                                             %
26%    http://www.imagemagick.org/script/license.php                            %
27%                                                                             %
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.                                             %
33%                                                                             %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37*/
38
39/*
40  Include declarations.
41*/
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"
60
61/*
62  Define declarations.
63*/
64#define MagickCoderFilename  "coder.xml"
65
66/*
67  Declare coder map.
68*/
69static const char
70  *CoderMap = (const char *)
71    "<?xml version=\"1.0\"?>"
72    "<codermap>"
73    "  <coder magick=\"8BIM\" name=\"META\" />"
74    "  <coder magick=\"8BIMTEXT\" name=\"META\" />"
75    "  <coder magick=\"8BIMWTEXT\" name=\"META\" />"
76    "  <coder magick=\"A\" name=\"RAW\" />"
77    "  <coder magick=\"AI\" name=\"PDF\" />"
78    "  <coder magick=\"AFM\" name=\"TTF\" />"
79    "  <coder magick=\"APP1JPEG\" name=\"META\" />"
80    "  <coder magick=\"APP1\" name=\"META\" />"
81    "  <coder magick=\"BIE\" name=\"JBIG\" />"
82    "  <coder magick=\"BMP2\" name=\"BMP\" />"
83    "  <coder magick=\"BMP3\" name=\"BMP\" />"
84    "  <coder magick=\"B\" name=\"GRAY\" />"
85    "  <coder magick=\"BRF\" name=\"BRAILLE\" />"
86    "  <coder magick=\"CMYKA\" name=\"CMYK\" />"
87    "  <coder magick=\"C\" name=\"GRAY\" />"
88    "  <coder magick=\"CR2\" name=\"DNG\" />"
89    "  <coder magick=\"CRW\" name=\"DNG\" />"
90    "  <coder magick=\"CUR\" name=\"ICON\" />"
91    "  <coder magick=\"DCR\" name=\"DNG\" />"
92    "  <coder magick=\"DCX\" name=\"PCX\" />"
93    "  <coder magick=\"DFONT\" name=\"TTF\" />"
94    "  <coder magick=\"EMF\" name=\"EMF\" />"
95    "  <coder magick=\"EPDF\" name=\"PDF\" />"
96    "  <coder magick=\"EPI\" name=\"PS\" />"
97    "  <coder magick=\"EPS2\" name=\"PS2\" />"
98    "  <coder magick=\"EPS3\" name=\"PS3\" />"
99    "  <coder magick=\"EPSF\" name=\"PS\" />"
100    "  <coder magick=\"EPSI\" name=\"PS\" />"
101    "  <coder magick=\"EPS\" name=\"PS\" />"
102    "  <coder magick=\"EPT2\" name=\"EPT\" />"
103    "  <coder magick=\"EPT3\" name=\"EPT\" />"
104    "  <coder magick=\"EXIF\" name=\"META\" />"
105    "  <coder magick=\"FILE\" name=\"URL\" />"
106    "  <coder magick=\"FRACTAL\" name=\"PLASMA\" />"
107    "  <coder magick=\"FTP\" name=\"URL\" />"
108    "  <coder magick=\"FTS\" name=\"FITS\" />"
109    "  <coder magick=\"G3\" name=\"FAX\" />"
110    "  <coder magick=\"GIF87\" name=\"GIF\" />"
111    "  <coder magick=\"G\" name=\"GRAY\" />"
112    "  <coder magick=\"GRANITE\" name=\"MAGICK\" />"
113    "  <coder magick=\"H\" name=\"MAGICK\" />"
114    "  <coder magick=\"HTM\" name=\"HTML\" />"
115    "  <coder magick=\"HTTP\" name=\"URL\" />"
116    "  <coder magick=\"ICB\" name=\"TGA\" />"
117    "  <coder magick=\"ICC\" name=\"META\" />"
118    "  <coder magick=\"ICM\" name=\"META\" />"
119    "  <coder magick=\"ICO\" name=\"ICON\" />"
120    "  <coder magick=\"IMPLICIT\" name=\"***\" />"
121    "  <coder magick=\"IPTC\" name=\"META\" />"
122    "  <coder magick=\"IPTCTEXT\" name=\"META\" />"
123    "  <coder magick=\"IPTCWTEXT\" name=\"META\" />"
124    "  <coder magick=\"ISOBRL\" name=\"BRAILLE\" />"
125    "  <coder magick=\"JBG\" name=\"JBIG\" />"
126    "  <coder magick=\"JNG\" name=\"PNG\" />"
127    "  <coder magick=\"JPC\" name=\"JP2\" />"
128    "  <coder magick=\"JPG\" name=\"JPEG\" />"
129    "  <coder magick=\"JPX\" name=\"JP2\" />"
130    "  <coder magick=\"K\" name=\"GRAY\" />"
131    "  <coder magick=\"LOGO\" name=\"MAGICK\" />"
132    "  <coder magick=\"M2V\" name=\"MPEG\" />"
133    "  <coder magick=\"M4V\" name=\"MPEG\" />"
134    "  <coder magick=\"M\" name=\"GRAY\" />"
135    "  <coder magick=\"MNG\" name=\"PNG\" />"
136    "  <coder magick=\"MOV\" name=\"MPEG\" />"
137    "  <coder magick=\"MPG\" name=\"MPEG\" />"
138    "  <coder magick=\"MP4\" name=\"MPEG\" />"
139    "  <coder magick=\"MPRI\" name=\"MPR\" />"
140    "  <coder magick=\"MRW\" name=\"DNG\" />"
141    "  <coder magick=\"MSVG\" name=\"SVG\" />"
142    "  <coder magick=\"NEF\" name=\"DNG\" />"
143    "  <coder magick=\"NETSCAPE\" name=\"MAGICK\" />"
144    "  <coder magick=\"O\" name=\"GRAY\" />"
145    "  <coder magick=\"ORF\" name=\"DNG\" />"
146    "  <coder magick=\"OTF\" name=\"TTF\" />"
147    "  <coder magick=\"P7\" name=\"PNM\" />"
148    "  <coder magick=\"PAL\" name=\"UYVY\" />"
149    "  <coder magick=\"PAM\" name=\"PNM\" />"
150    "  <coder magick=\"PBM\" name=\"PNM\" />"
151    "  <coder magick=\"PCDS\" name=\"PCD\" />"
152    "  <coder magick=\"PCT\" name=\"PICT\" />"
153    "  <coder magick=\"PDFA\" name=\"PDF\" />"
154    "  <coder magick=\"PEF\" name=\"DNG\" />"
155    "  <coder magick=\"PFA\" name=\"TTF\" />"
156    "  <coder magick=\"PFB\" name=\"TTF\" />"
157    "  <coder magick=\"PFM\" name=\"PNM\" />"
158    "  <coder magick=\"PGM\" name=\"PNM\" />"
159    "  <coder magick=\"PGX\" name=\"JP2\" />"
160    "  <coder magick=\"PICON\" name=\"XPM\" />"
161    "  <coder magick=\"PJPEG\" name=\"JPEG\" />"
162    "  <coder magick=\"PM\" name=\"XPM\" />"
163    "  <coder magick=\"PNG24\" name=\"PNG\" />"
164    "  <coder magick=\"PNG32\" name=\"PNG\" />"
165    "  <coder magick=\"PNG8\" name=\"PNG\" />"
166    "  <coder magick=\"PPM\" name=\"PNM\" />"
167    "  <coder magick=\"PTIF\" name=\"TIFF\" />"
168    "  <coder magick=\"RAF\" name=\"DNG\" />"
169    "  <coder magick=\"RAS\" name=\"SUN\" />"
170    "  <coder magick=\"RGBA\" name=\"RGB\" />"
171    "  <coder magick=\"RGBO\" name=\"RGB\" />"
172    "  <coder magick=\"R\" name=\"GRAY\" />"
173    "  <coder magick=\"ROSE\" name=\"MAGICK\" />"
174    "  <coder magick=\"SHTML\" name=\"HTML\" />"
175    "  <coder magick=\"SVGZ\" name=\"SVG\" />"
176    "  <coder magick=\"TEXT\" name=\"TXT\" />"
177    "  <coder magick=\"TIFF64\" name=\"TIFF\" />"
178    "  <coder magick=\"TIF\" name=\"TIFF\" />"
179    "  <coder magick=\"TTC\" name=\"TTF\" />"
180    "  <coder magick=\"UBRL\" name=\"BRAILLE\" />"
181    "  <coder magick=\"VDA\" name=\"TGA\" />"
182    "  <coder magick=\"VST\" name=\"TGA\" />"
183    "  <coder magick=\"WMFWIN32\" name=\"EMF\" />"
184    "  <coder magick=\"WMV\" name=\"MPEG\" />"
185    "  <coder magick=\"X3F\" name=\"DNG\" />"
186    "  <coder magick=\"XTRNARRAY\" name=\"XTRN\" />"
187    "  <coder magick=\"XTRNBLOB\" name=\"XTRN\" />"
188    "  <coder magick=\"XTRNBSTR\" name=\"XTRN\" />"
189    "  <coder magick=\"XTRNFILE\" name=\"XTRN\" />"
190    "  <coder magick=\"XTRNIMAGE\" name=\"XTRN\" />"
191    "  <coder magick=\"XTRNSTREAM\" name=\"XTRN\" />"
192    "  <coder magick=\"XV\" name=\"VIFF\" />"
193    "  <coder magick=\"Y\" name=\"GRAY\" />"
194    "  <coder magick=\"YCbCrA\" name=\"YCbCr\" />"
195    "</codermap>";
196
197/*
198  Static declarations.
199*/
200static SemaphoreInfo
201  *coder_semaphore = (SemaphoreInfo *) NULL;
202
203static SplayTreeInfo
204  *coder_list = (SplayTreeInfo *) NULL;
205
206static volatile MagickBooleanType
207  instantiate_coder = MagickFalse;
208
209/*
210  Forward declarations.
211*/
212static MagickBooleanType
213  InitializeCoderList(ExceptionInfo *),
214  LoadCoderLists(const char *,ExceptionInfo *);
215
216/*
217%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
218%                                                                             %
219%                                                                             %
220%                                                                             %
221+   D e s t r o y C o d e r L i s t                                           %
222%                                                                             %
223%                                                                             %
224%                                                                             %
225%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
226%
227%  DestroyCoderList() deallocates memory associated with the font list.
228%
229%  The format of the DestroyCoderList method is:
230%
231%      DestroyCoderList(void)
232%
233*/
234MagickExport void DestroyCoderList(void)
235{
236  AcquireSemaphoreInfo(&coder_semaphore);
237  if (coder_list != (SplayTreeInfo *) NULL)
238    coder_list=DestroySplayTree(coder_list);
239  instantiate_coder=MagickFalse;
240  RelinquishSemaphoreInfo(coder_semaphore);
241  DestroySemaphoreInfo(&coder_semaphore);
242}
243
244/*
245%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
246%                                                                             %
247%                                                                             %
248%                                                                             %
249+   G e t C o d e r I n f o                                                   %
250%                                                                             %
251%                                                                             %
252%                                                                             %
253%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
254%
255%  GetCoderInfo searches the coder list for the specified name and if found
256%  returns attributes for that coder.
257%
258%  The format of the GetCoderInfo method is:
259%
260%      const CoderInfo *GetCoderInfo(const char *name,ExceptionInfo *exception)
261%
262%  A description of each parameter follows:
263%
264%    o name: the coder name.
265%
266%    o exception: Return any errors or warnings in this structure.
267%
268*/
269MagickExport const CoderInfo *GetCoderInfo(const char *name,
270  ExceptionInfo *exception)
271{
272  assert(exception != (ExceptionInfo *) NULL);
273  if ((coder_list == (SplayTreeInfo *) NULL) ||
274      (instantiate_coder == MagickFalse))
275    if (InitializeCoderList(exception) == MagickFalse)
276      return((const CoderInfo *) NULL);
277  if ((coder_list == (SplayTreeInfo *) NULL) ||
278      (GetNumberOfNodesInSplayTree(coder_list) == 0))
279    return((const CoderInfo *) NULL);
280  if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
281    {
282      ResetSplayTreeIterator(coder_list);
283      return((const CoderInfo *) GetNextValueInSplayTree(coder_list));
284    }
285  return((const CoderInfo *) GetValueFromSplayTree(coder_list,name));
286}
287
288/*
289%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
290%                                                                             %
291%                                                                             %
292%                                                                             %
293%   G e t C o d e r I n f o L i s t                                           %
294%                                                                             %
295%                                                                             %
296%                                                                             %
297%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
298%
299%  GetCoderInfoList() returns any coder_map that match the specified pattern.
300%  The format of the GetCoderInfoList function is:
301%
302%      const CoderInfo **GetCoderInfoList(const char *pattern,
303%        unsigned long *number_coders,ExceptionInfo *exception)
304%
305%  A description of each parameter follows:
306%
307%    o pattern: Specifies a pointer to a text string containing a pattern.
308%
309%    o number_coders:  This integer returns the number of coders in the list.
310%
311%    o exception: Return any errors or warnings in this structure.
312%
313*/
314
315static int CoderInfoCompare(const void *x,const void *y)
316{
317  const CoderInfo
318    **p,
319    **q;
320
321  p=(const CoderInfo **) x,
322  q=(const CoderInfo **) y;
323  if (LocaleCompare((*p)->path,(*q)->path) == 0)
324    return(LocaleCompare((*p)->name,(*q)->name));
325  return(LocaleCompare((*p)->path,(*q)->path));
326}
327
328MagickExport const CoderInfo **GetCoderInfoList(const char *pattern,
329  unsigned long *number_coders,ExceptionInfo *exception)
330{
331  const CoderInfo
332    **coder_map;
333
334  register const CoderInfo
335    *p;
336
337  register long
338    i;
339
340  /*
341    Allocate coder list.
342  */
343  assert(pattern != (char *) NULL);
344  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
345  assert(number_coders != (unsigned long *) NULL);
346  *number_coders=0;
347  p=GetCoderInfo("*",exception);
348  if (p == (const CoderInfo *) NULL)
349    return((const CoderInfo **) NULL);
350  coder_map=(const CoderInfo **) AcquireQuantumMemory((size_t)
351    GetNumberOfNodesInSplayTree(coder_list)+1UL,sizeof(*coder_map));
352  if (coder_map == (const CoderInfo **) NULL)
353    return((const CoderInfo **) NULL);
354  /*
355    Generate coder list.
356  */
357  AcquireSemaphoreInfo(&coder_semaphore);
358  ResetSplayTreeIterator(coder_list);
359  p=(const CoderInfo *) GetNextValueInSplayTree(coder_list);
360  for (i=0; p != (const CoderInfo *) NULL; )
361  {
362    if ((p->stealth == MagickFalse) &&
363        (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
364      coder_map[i++]=p;
365    p=(const CoderInfo *) GetNextValueInSplayTree(coder_list);
366  }
367  RelinquishSemaphoreInfo(coder_semaphore);
368  qsort((void *) coder_map,(size_t) i,sizeof(*coder_map),CoderInfoCompare);
369  coder_map[i]=(CoderInfo *) NULL;
370  *number_coders=(unsigned long) i;
371  return(coder_map);
372}
373
374/*
375%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
376%                                                                             %
377%                                                                             %
378%                                                                             %
379%   G e t C o d e r L i s t                                                   %
380%                                                                             %
381%                                                                             %
382%                                                                             %
383%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
384%
385%  GetCoderList() returns any coder_map that match the specified pattern.
386%
387%  The format of the GetCoderList function is:
388%
389%      char **GetCoderList(const char *pattern,unsigned long *number_coders,
390%        ExceptionInfo *exception)
391%
392%  A description of each parameter follows:
393%
394%    o pattern: Specifies a pointer to a text string containing a pattern.
395%
396%    o number_coders:  This integer returns the number of coders in the list.
397%
398%    o exception: Return any errors or warnings in this structure.
399%
400*/
401
402static int CoderCompare(const void *x,const void *y)
403{
404  register const char
405    **p,
406    **q;
407
408  p=(const char **) x;
409  q=(const char **) y;
410  return(LocaleCompare(*p,*q));
411}
412
413MagickExport char **GetCoderList(const char *pattern,
414  unsigned long *number_coders,ExceptionInfo *exception)
415{
416  char
417    **coder_map;
418
419  register const CoderInfo
420    *p;
421
422  register long
423    i;
424
425  /*
426    Allocate coder list.
427  */
428  assert(pattern != (char *) NULL);
429  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
430  assert(number_coders != (unsigned long *) NULL);
431  *number_coders=0;
432  p=GetCoderInfo("*",exception);
433  if (p == (const CoderInfo *) NULL)
434    return((char **) NULL);
435  coder_map=(char **) AcquireQuantumMemory((size_t)
436    GetNumberOfNodesInSplayTree(coder_list)+1UL,sizeof(*coder_map));
437  if (coder_map == (char **) NULL)
438    return((char **) NULL);
439  /*
440    Generate coder list.
441  */
442  AcquireSemaphoreInfo(&coder_semaphore);
443  ResetSplayTreeIterator(coder_list);
444  p=(const CoderInfo *) GetNextValueInSplayTree(coder_list);
445  for (i=0; p != (const CoderInfo *) NULL; )
446  {
447    if ((p->stealth == MagickFalse) &&
448        (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
449      coder_map[i++]=ConstantString(p->name);
450    p=(const CoderInfo *) GetNextValueInSplayTree(coder_list);
451  }
452  RelinquishSemaphoreInfo(coder_semaphore);
453  qsort((void *) coder_map,(size_t) i,sizeof(*coder_map),CoderCompare);
454  coder_map[i]=(char *) NULL;
455  *number_coders=(unsigned long) i;
456  return(coder_map);
457}
458
459/*
460%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
461%                                                                             %
462%                                                                             %
463%                                                                             %
464+   I n i t i a l i z e C o d e r L i s t                                     %
465%                                                                             %
466%                                                                             %
467%                                                                             %
468%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
469%
470%  InitializeCoderList() initializes the coder list.
471%
472%  The format of the InitializeCoderList method is:
473%
474%      MagickBooleanType InitializeCoderList(ExceptionInfo *exception)
475%
476%  A description of each parameter follows.
477%
478%    o exception: Return any errors or warnings in this structure.
479%
480*/
481static MagickBooleanType InitializeCoderList(ExceptionInfo *exception)
482{
483  if ((coder_list == (SplayTreeInfo *) NULL) &&
484      (instantiate_coder == MagickFalse))
485    {
486      AcquireSemaphoreInfo(&coder_semaphore);
487      if ((coder_list == (SplayTreeInfo *) NULL) &&
488          (instantiate_coder == MagickFalse))
489        {
490          (void) LoadCoderLists(MagickCoderFilename,exception);
491          instantiate_coder=MagickTrue;
492        }
493      RelinquishSemaphoreInfo(coder_semaphore);
494    }
495  return(coder_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
496}
497
498/*
499%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
500%                                                                             %
501%                                                                             %
502%                                                                             %
503%  L i s t C o d e r I n f o                                                  %
504%                                                                             %
505%                                                                             %
506%                                                                             %
507%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
508%
509%  ListCoderInfo() lists the coder info to a file.
510%
511%  The format of the ListCoderInfo coder is:
512%
513%      MagickBooleanType ListCoderInfo(FILE *file,ExceptionInfo *exception)
514%
515%  A description of each parameter follows.
516%
517%    o file:  An pointer to a FILE.
518%
519%    o exception: Return any errors or warnings in this structure.
520%
521*/
522MagickExport MagickBooleanType ListCoderInfo(FILE *file,
523  ExceptionInfo *exception)
524{
525  const char
526    *path;
527
528  const CoderInfo
529    **coder_info;
530
531  long
532    j;
533
534  register long
535    i;
536
537  unsigned long
538    number_coders;
539
540  if (file == (const FILE *) NULL)
541    file=stdout;
542  coder_info=GetCoderInfoList("*",&number_coders,exception);
543  if (coder_info == (const CoderInfo **) NULL)
544    return(MagickFalse);
545  path=(const char *) NULL;
546  for (i=0; i < (long) number_coders; i++)
547  {
548    if (coder_info[i]->stealth != MagickFalse)
549      continue;
550    if ((path == (const char *) NULL) ||
551        (LocaleCompare(path,coder_info[i]->path) != 0))
552      {
553        if (coder_info[i]->path != (char *) NULL)
554          (void) fprintf(file,"\nPath: %s\n\n",coder_info[i]->path);
555        (void) fprintf(file,"Magick      Coder\n");
556        (void) fprintf(file,"-------------------------------------------------"
557          "------------------------------\n");
558      }
559    path=coder_info[i]->path;
560    (void) fprintf(file,"%s",coder_info[i]->magick);
561    for (j=(long) strlen(coder_info[i]->magick); j <= 11; j++)
562      (void) fprintf(file," ");
563    if (coder_info[i]->name != (char *) NULL)
564      (void) fprintf(file,"%s",coder_info[i]->name);
565    (void) fprintf(file,"\n");
566  }
567  coder_info=(const CoderInfo **) RelinquishMagickMemory((void *) coder_info);
568  (void) fflush(file);
569  return(MagickTrue);
570}
571
572/*
573%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
574%                                                                             %
575%                                                                             %
576%                                                                             %
577+   L o a d C o d e r L i s t                                                 %
578%                                                                             %
579%                                                                             %
580%                                                                             %
581%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
582%
583%  LoadCoderList() loads the coder configuration file which provides a
584%  mapping between coder attributes and a coder name.
585%
586%  The format of the LoadCoderList coder is:
587%
588%      MagickBooleanType LoadCoderList(const char *xml,const char *filename,
589%        const unsigned long depth,ExceptionInfo *exception)
590%
591%  A description of each parameter follows:
592%
593%    o xml:  The coder list in XML format.
594%
595%    o filename:  The coder list filename.
596%
597%    o depth: depth of <include /> statements.
598%
599%    o exception: Return any errors or warnings in this structure.
600%
601*/
602
603static void *DestroyCoderNode(void *coder_info)
604{
605  register CoderInfo
606    *p;
607
608  p=(CoderInfo *) coder_info;
609  if (p->path != (char *) NULL)
610    p->path=DestroyString(p->path);
611  if (p->name != (char *) NULL)
612    p->name=DestroyString(p->name);
613  if (p->magick != (char *) NULL)
614    p->magick=DestroyString(p->magick);
615  return(RelinquishMagickMemory(p));
616}
617
618static MagickBooleanType LoadCoderList(const char *xml,const char *filename,
619  const unsigned long depth,ExceptionInfo *exception)
620{
621  CoderInfo
622    *coder_info = (CoderInfo *) NULL;
623
624  const char
625    *attribute;
626
627  MagickBooleanType
628    status;
629
630  XMLTreeInfo
631    *coder,
632    *coder_map,
633    *include;
634
635  /*
636    Load the coder map file.
637  */
638  (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
639    "Loading coder map \"%s\" ...",filename);
640  if (xml == (const char *) NULL)
641    return(MagickFalse);
642  if (coder_list == (SplayTreeInfo *) NULL)
643    {
644      coder_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL,
645        DestroyCoderNode);
646      if (coder_list == (SplayTreeInfo *) NULL)
647        {
648          (void) ThrowMagickException(exception,GetMagickModule(),
649             ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
650          return(MagickFalse);
651        }
652    }
653  coder_map=NewXMLTree(xml,exception);
654  if (coder_map == (XMLTreeInfo *) NULL)
655    return(MagickFalse);
656  status=MagickTrue;
657  include=GetXMLTreeChild(coder_map,"include");
658  while (include != (XMLTreeInfo *) NULL)
659  {
660    /*
661      Process include element.
662    */
663    attribute=GetXMLTreeAttribute(include,"file");
664    if (attribute != (const char *) NULL)
665      {
666        if (depth > 200)
667          (void) ThrowMagickException(exception,GetMagickModule(),
668            ConfigureError,"IncludeElementNestedTooDeeply","`%s'",attribute);
669        else
670          {
671            char
672              path[MaxTextExtent],
673              *xml;
674
675            GetPathComponent(filename,HeadPath,path);
676            if (*path != '\0')
677              (void) ConcatenateMagickString(path,DirectorySeparator,
678                MaxTextExtent);
679            (void) ConcatenateMagickString(path,attribute,MaxTextExtent);
680            xml=FileToString(path,~0,exception);
681            if (xml != (char *) NULL)
682              {
683                status=LoadCoderList(xml,path,depth+1,exception);
684                xml=DestroyString(xml);
685              }
686          }
687      }
688    include=GetNextXMLTreeTag(include);
689  }
690  coder=GetXMLTreeChild(coder_map,"coder");
691  while (coder != (XMLTreeInfo *) NULL)
692  {
693    /*
694      Process coder element.
695    */
696    coder_info=(CoderInfo *) AcquireMagickMemory(sizeof(*coder_info));
697    if (coder_info == (CoderInfo *) NULL)
698      ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
699    (void) ResetMagickMemory(coder_info,0,sizeof(*coder_info));
700    coder_info->path=ConstantString(filename);
701    coder_info->signature=MagickSignature;
702    attribute=GetXMLTreeAttribute(coder,"magick");
703    if (attribute != (const char *) NULL)
704      coder_info->magick=ConstantString(attribute);
705    attribute=GetXMLTreeAttribute(coder,"name");
706    if (attribute != (const char *) NULL)
707      coder_info->name=ConstantString(attribute);
708    attribute=GetXMLTreeAttribute(coder,"stealth");
709    if (attribute != (const char *) NULL)
710      coder_info->stealth=IsMagickTrue(attribute);
711    status=AddValueToSplayTree(coder_list,coder_info->magick,coder_info);
712    if (status == MagickFalse)
713      (void) ThrowMagickException(exception,GetMagickModule(),
714        ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
715    coder=GetNextXMLTreeTag(coder);
716  }
717  coder_map=DestroyXMLTree(coder_map);
718  return(status);
719}
720
721/*
722%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
723%                                                                             %
724%                                                                             %
725%                                                                             %
726%  L o a d C o d e r L i s t s                                                %
727%                                                                             %
728%                                                                             %
729%                                                                             %
730%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
731%
732%  LoadCoderLists() loads one or more coder configuration file which
733%  provides a mapping between coder attributes and a coder name.
734%
735%  The format of the LoadCoderLists coder is:
736%
737%      MagickBooleanType LoadCoderLists(const char *filename,
738%        ExceptionInfo *exception)
739%
740%  A description of each parameter follows:
741%
742%    o filename: the font file name.
743%
744%    o exception: Return any errors or warnings in this structure.
745%
746*/
747static MagickBooleanType LoadCoderLists(const char *filename,
748  ExceptionInfo *exception)
749{
750#if defined(MAGICKCORE_EMBEDDABLE_SUPPORT)
751  return(LoadCoderList(CoderMap,"built-in",0,exception));
752#else
753  const StringInfo
754    *option;
755
756  LinkedListInfo
757    *options;
758
759  MagickStatusType
760    status;
761
762  status=MagickFalse;
763  options=GetConfigureOptions(filename,exception);
764  option=(const StringInfo *) GetNextValueInLinkedList(options);
765  while (option != (const StringInfo *) NULL)
766  {
767    status|=LoadCoderList((const char *) GetStringInfoDatum(option),
768      GetStringInfoPath(option),0,exception);
769    option=(const StringInfo *) GetNextValueInLinkedList(options);
770  }
771  options=DestroyConfigureOptions(options);
772  if ((coder_list == (SplayTreeInfo *) NULL) ||
773      (GetNumberOfNodesInSplayTree(coder_list) == 0))
774    status|=LoadCoderList(CoderMap,"built-in",0,exception);
775  return(status != 0 ? MagickTrue : MagickFalse);
776#endif
777}
Note: See TracBrowser for help on using the browser.