MagickCore  7.0.8
Convert, Edit, Or Compose Bitmap Images
coder.c
Go to the documentation of this file.
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 % MagickCore Image Coder Methods %
14 % %
15 % Software Design %
16 % Cristy %
17 % May 2001 %
18 % %
19 % %
20 % Copyright 1999-2018 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 % https://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 "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/client.h"
45 #include "MagickCore/coder.h"
47 #include "MagickCore/configure.h"
48 #include "MagickCore/draw.h"
49 #include "MagickCore/exception.h"
51 #include "MagickCore/linked-list.h"
52 #include "MagickCore/log.h"
53 #include "MagickCore/memory_.h"
55 #include "MagickCore/option.h"
56 #include "MagickCore/semaphore.h"
57 #include "MagickCore/string_.h"
58 #include "MagickCore/splay-tree.h"
59 #include "MagickCore/token.h"
60 #include "MagickCore/utility.h"
62 #include "MagickCore/xml-tree.h"
64 
65 /*
66  Define declarations.
67 */
68 #define MagickCoderFilename "coder.xml"
69 
70 /*
71  Typedef declarations.
72 */
73 typedef struct _CoderMapInfo
74 {
75  const char
77  *name;
78 } CoderMapInfo;
79 
80 /*
81  Static declarations.
82 */
83 static const CoderMapInfo
85  {
86  { "3FR", "DNG" },
87  { "3GP", "MPEG" },
88  { "3G2", "MPEG" },
89  { "8BIMTEXT", "META" },
90  { "8BIMWTEXT", "META" },
91  { "AFM", "TTF" },
92  { "A", "RAW" },
93  { "AI", "PDF" },
94  { "APP1JPEG", "META" },
95  { "APP1", "META" },
96  { "ARW", "DNG" },
97  { "AVI", "MPEG" },
98  { "BIE", "JBIG" },
99  { "BMP2", "BMP" },
100  { "BMP3", "BMP" },
101  { "B", "RAW" },
102  { "BRF", "BRAILLE" },
103  { "BGRA", "BGR" },
104  { "BGRO", "BGR" },
105  { "CMYKA", "CMYK" },
106  { "C", "RAW" },
107  { "CAL", "CALS" },
108  { "CANVAS", "XC" },
109  { "CMYKA", "CMYK" },
110  { "CR2", "DNG" },
111  { "CRW", "DNG" },
112  { "CUR", "ICON" },
113  { "DATA", "INLINE" },
114  { "DCR", "DNG" },
115  { "DCX", "PCX" },
116  { "DFONT", "TTF" },
117  { "DXT1", "DDS" },
118  { "DXT5", "DDS" },
119  { "EPDF", "PDF" },
120  { "EPI", "PS" },
121  { "EPS2", "PS2" },
122  { "EPS3", "PS3" },
123  { "EPSF", "PS" },
124  { "EPSI", "PS" },
125  { "EPS", "PS" },
126  { "EPT2", "EPT" },
127  { "EPT3", "EPT" },
128  { "ERF", "DNG" },
129  { "EXIF", "META" },
130  { "FILE", "URL" },
131  { "FRACTAL", "PLASMA" },
132  { "FTP", "URL" },
133  { "FTS", "FITS" },
134  { "G3", "FAX" },
135  { "G4", "FAX" },
136  { "GIF87", "GIF" },
137  { "G", "RAW" },
138  { "GRANITE", "MAGICK" },
139  { "GRAYA", "GRAY" },
140  { "GROUP4", "TIFF" },
141  { "GV", "DOT" },
142  { "HTM", "HTML" },
143  { "ICB", "TGA" },
144  { "ICO", "ICON" },
145  { "ICODIB", "DIB" },
146  { "IIQ", "DNG" },
147  { "K25", "DNG" },
148  { "KDC", "DNG" },
149  { "H", "MAGICK" },
150  { "HTM", "HTML" },
151  { "HTTP", "URL" },
152  { "HTTPS", "URL" },
153  { "ICB", "TGA" },
154  { "ICC", "META" },
155  { "ICM", "META" },
156  { "ICO", "ICON" },
157  { "IMPLICIT", "***" },
158  { "IPTC", "META" },
159  { "IPTCTEXT", "META" },
160  { "IPTCWTEXT", "META" },
161  { "ISOBRL", "BRAILLE" },
162  { "ISOBRL6", "BRAILLE" },
163  { "JBG", "JBIG" },
164  { "JNG", "PNG" },
165  { "JPC", "JP2" },
166  { "JPT", "JP2" },
167  { "JPM", "JP2" },
168  { "J2C", "JP2" },
169  { "J2K", "JP2" },
170  { "JNG", "PNG" },
171  { "JPE", "JPEG" },
172  { "JPG", "JPEG" },
173  { "JPM", "JP2" },
174  { "JPS", "JPEG" },
175  { "JPT", "JP2" },
176  { "JPX", "JP2" },
177  { "K", "RAW" },
178  { "K25", "DNG" },
179  { "KDC", "DNG" },
180  { "LOGO", "MAGICK" },
181  { "M", "RAW" },
182  { "M2V", "MPEG" },
183  { "M4V", "MPEG" },
184  { "MEF", "DNG" },
185  { "MKV", "MPEG" },
186  { "MNG", "PNG" },
187  { "MOV", "MPEG" },
188  { "MP4", "MPEG" },
189  { "MPG", "MPEG" },
190  { "MPRI", "MPR" },
191  { "MEF", "DNG" },
192  { "MRW", "DNG" },
193  { "MSVG", "SVG" },
194  { "NEF", "DNG" },
195  { "NETSCAPE", "MAGICK" },
196  { "NRW", "DNG" },
197  { "O", "RAW" },
198  { "ORF", "DNG" },
199  { "OTF", "TTF" },
200  { "P7", "PNM" },
201  { "PAL", "UYVY" },
202  { "PAM", "PNM" },
203  { "PBM", "PNM" },
204  { "PCDS", "PCD" },
205  { "PCT", "PICT" },
206  { "PDFA", "PDF" },
207  { "PEF", "DNG" },
208  { "PEF", "DNG" },
209  { "PFA", "TTF" },
210  { "PFB", "TTF" },
211  { "PFM", "PNM" },
212  { "PGM", "PNM" },
213  { "PICON", "XPM" },
214  { "PJPEG", "JPEG" },
215  { "PM", "XPM" },
216  { "PNG00", "PNG" },
217  { "PNG24", "PNG" },
218  { "PNG32", "PNG" },
219  { "PNG48", "PNG" },
220  { "PNG64", "PNG" },
221  { "PNG8", "PNG" },
222  { "PPM", "PNM" },
223  { "PSB", "PSD" },
224  { "PTIF", "TIFF" },
225  { "R", "RAW" },
226  { "RADIAL-GRADIENT", "GRADIENT" },
227  { "RAF", "DNG" },
228  { "RAS", "SUN" },
229  { "RAW", "DNG" },
230  { "RGBA", "RGB" },
231  { "RGBO", "RGB" },
232  { "RMF", "DNG" },
233  { "ROSE", "MAGICK" },
234  { "RW2", "DNG" },
235  { "SHTML", "HTML" },
236  { "SIX", "SIXEL" },
237  { "SPARSE-COLOR", "TXT" },
238  { "SR2", "DNG" },
239  { "SRF", "DNG" },
240  { "SVGZ", "SVG" },
241  { "TEXT", "TXT" },
242  { "TIFF64", "TIFF" },
243  { "TIF", "TIFF" },
244  { "TTC", "TTF" },
245  { "UBRL", "BRAILLE" },
246  { "UBRL6", "BRAILLE" },
247  { "VDA", "TGA" },
248  { "VST", "TGA" },
249  { "WIZARD", "MAGICK" },
250 #if defined(MAGICKCORE_WINGDI32_DELEGATE)
251  { "WMF", "EMF" },
252 #endif
253  { "WMV", "MPEG" },
254  { "WMZ", "WMF" },
255  { "X3f", "DNG" },
256  { "XMP", "META" },
257  { "XTRNARRAY", "XTRN" },
258  { "XV", "VIFF" },
259  { "Y", "RAW" },
260  { "YCbCrA", "YCbCr" }
261  };
262 
263 static SemaphoreInfo
265 
266 static SplayTreeInfo
268 
269 /*
270  Forward declarations.
271 */
272 static MagickBooleanType
274  LoadCoderCache(SplayTreeInfo *,const char *,const char *,const size_t,
275  ExceptionInfo *);
276 
277 /*
278 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279 % %
280 % %
281 % %
282 + A c q u i r e C o d e r C a c h e %
283 % %
284 % %
285 % %
286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
287 %
288 % AcquireCoderCache() caches one or more coder configurations which provides a
289 % mapping between coder attributes and a coder name.
290 %
291 % The format of the AcquireCoderCache coder is:
292 %
293 % SplayTreeInfo *AcquireCoderCache(const char *filename,
294 % ExceptionInfo *exception)
295 %
296 % A description of each parameter follows:
297 %
298 % o filename: the font file name.
299 %
300 % o exception: return any errors or warnings in this structure.
301 %
302 */
303 
304 static void *DestroyCoderNode(void *coder_info)
305 {
306  register CoderInfo
307  *p;
308 
309  p=(CoderInfo *) coder_info;
310  if (p->exempt == MagickFalse)
311  {
312  if (p->path != (char *) NULL)
313  p->path=DestroyString(p->path);
314  if (p->name != (char *) NULL)
315  p->name=DestroyString(p->name);
316  if (p->magick != (char *) NULL)
317  p->magick=DestroyString(p->magick);
318  }
319  return(RelinquishMagickMemory(p));
320 }
321 
322 static SplayTreeInfo *AcquireCoderCache(const char *filename,
323  ExceptionInfo *exception)
324 {
326  status;
327 
328  register ssize_t
329  i;
330 
332  *cache;
333 
334  /*
335  Load external coder map.
336  */
339  status=MagickTrue;
340 #if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
341  {
342  const StringInfo
343  *option;
344 
346  *options;
347 
348  options=GetConfigureOptions(filename,exception);
349  option=(const StringInfo *) GetNextValueInLinkedList(options);
350  while (option != (const StringInfo *) NULL)
351  {
352  status&=LoadCoderCache(cache,(const char *) GetStringInfoDatum(option),
353  GetStringInfoPath(option),0,exception);
354  option=(const StringInfo *) GetNextValueInLinkedList(options);
355  }
356  options=DestroyConfigureOptions(options);
357  }
358 #endif
359  /*
360  Load built-in coder map.
361  */
362  for (i=0; i < (ssize_t) (sizeof(CoderMap)/sizeof(*CoderMap)); i++)
363  {
364  CoderInfo
365  *coder_info;
366 
367  register const CoderMapInfo
368  *p;
369 
370  p=CoderMap+i;
371  coder_info=(CoderInfo *) AcquireMagickMemory(sizeof(*coder_info));
372  if (coder_info == (CoderInfo *) NULL)
373  {
374  (void) ThrowMagickException(exception,GetMagickModule(),
375  ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name);
376  continue;
377  }
378  (void) memset(coder_info,0,sizeof(*coder_info));
379  coder_info->path=(char *) "[built-in]";
380  coder_info->magick=(char *) p->magick;
381  coder_info->name=(char *) p->name;
382  coder_info->exempt=MagickTrue;
383  coder_info->signature=MagickCoreSignature;
384  status&=AddValueToSplayTree(cache,ConstantString(coder_info->magick),
385  coder_info);
386  if (status == MagickFalse)
387  (void) ThrowMagickException(exception,GetMagickModule(),
388  ResourceLimitError,"MemoryAllocationFailed","`%s'",coder_info->name);
389  }
390  return(cache);
391 }
392 
393 /*
394 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
395 % %
396 % %
397 % %
398 + C o d e r C o m p o n e n t G e n e s i s %
399 % %
400 % %
401 % %
402 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
403 %
404 % CoderComponentGenesis() instantiates the coder component.
405 %
406 % The format of the CoderComponentGenesis method is:
407 %
408 % MagickBooleanType CoderComponentGenesis(void)
409 %
410 */
412 {
413  if (coder_semaphore == (SemaphoreInfo *) NULL)
415  return(MagickTrue);
416 }
417 
418 /*
419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
420 % %
421 % %
422 % %
423 + C o d e r C o m p o n e n t T e r m i n u s %
424 % %
425 % %
426 % %
427 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
428 %
429 % CoderComponentTerminus() destroys the coder component.
430 %
431 % The format of the CoderComponentTerminus method is:
432 %
433 % CoderComponentTerminus(void)
434 %
435 */
437 {
438  if (coder_semaphore == (SemaphoreInfo *) NULL)
441  if (coder_cache != (SplayTreeInfo *) NULL)
445 }
446 
447 /*
448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
449 % %
450 % %
451 % %
452 + G e t C o d e r I n f o %
453 % %
454 % %
455 % %
456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
457 %
458 % GetCoderInfo searches the coder list for the specified name and if found
459 % returns attributes for that coder.
460 %
461 % The format of the GetCoderInfo method is:
462 %
463 % const CoderInfo *GetCoderInfo(const char *name,ExceptionInfo *exception)
464 %
465 % A description of each parameter follows:
466 %
467 % o name: the coder name.
468 %
469 % o exception: return any errors or warnings in this structure.
470 %
471 */
472 MagickExport const CoderInfo *GetCoderInfo(const char *name,
473  ExceptionInfo *exception)
474 {
475  assert(exception != (ExceptionInfo *) NULL);
476  if (IsCoderTreeInstantiated(exception) == MagickFalse)
477  return((const CoderInfo *) NULL);
478  if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
480  return((const CoderInfo *) GetValueFromSplayTree(coder_cache,name));
481 }
482 
483 /*
484 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
485 % %
486 % %
487 % %
488 % G e t C o d e r I n f o L i s t %
489 % %
490 % %
491 % %
492 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
493 %
494 % GetCoderInfoList() returns any coder_map that match the specified pattern.
495 % The format of the GetCoderInfoList function is:
496 %
497 % const CoderInfo **GetCoderInfoList(const char *pattern,
498 % size_t *number_coders,ExceptionInfo *exception)
499 %
500 % A description of each parameter follows:
501 %
502 % o pattern: Specifies a pointer to a text string containing a pattern.
503 %
504 % o number_coders: This integer returns the number of coders in the list.
505 %
506 % o exception: return any errors or warnings in this structure.
507 %
508 */
509 
510 static int CoderInfoCompare(const void *x,const void *y)
511 {
512  const CoderInfo
513  **p,
514  **q;
515 
516  p=(const CoderInfo **) x,
517  q=(const CoderInfo **) y;
518  if (LocaleCompare((*p)->path,(*q)->path) == 0)
519  return(LocaleCompare((*p)->name,(*q)->name));
520  return(LocaleCompare((*p)->path,(*q)->path));
521 }
522 
523 MagickExport const CoderInfo **GetCoderInfoList(const char *pattern,
524  size_t *number_coders,ExceptionInfo *exception)
525 {
526  const CoderInfo
527  **coder_map;
528 
529  register const CoderInfo
530  *p;
531 
532  register ssize_t
533  i;
534 
535  /*
536  Allocate coder list.
537  */
538  assert(pattern != (char *) NULL);
539  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
540  assert(number_coders != (size_t *) NULL);
541  *number_coders=0;
542  p=GetCoderInfo("*",exception);
543  if (p == (const CoderInfo *) NULL)
544  return((const CoderInfo **) NULL);
545  coder_map=(const CoderInfo **) AcquireQuantumMemory((size_t)
546  GetNumberOfNodesInSplayTree(coder_cache)+1UL,sizeof(*coder_map));
547  if (coder_map == (const CoderInfo **) NULL)
548  return((const CoderInfo **) NULL);
549  /*
550  Generate coder list.
551  */
555  for (i=0; p != (const CoderInfo *) NULL; )
556  {
557  if ((p->stealth == MagickFalse) &&
558  (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
559  coder_map[i++]=p;
561  }
563  qsort((void *) coder_map,(size_t) i,sizeof(*coder_map),CoderInfoCompare);
564  coder_map[i]=(CoderInfo *) NULL;
565  *number_coders=(size_t) i;
566  return(coder_map);
567 }
568 
569 /*
570 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
571 % %
572 % %
573 % %
574 % G e t C o d e r L i s t %
575 % %
576 % %
577 % %
578 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
579 %
580 % GetCoderList() returns any coder_map that match the specified pattern.
581 %
582 % The format of the GetCoderList function is:
583 %
584 % char **GetCoderList(const char *pattern,size_t *number_coders,
585 % ExceptionInfo *exception)
586 %
587 % A description of each parameter follows:
588 %
589 % o pattern: Specifies a pointer to a text string containing a pattern.
590 %
591 % o number_coders: This integer returns the number of coders in the list.
592 %
593 % o exception: return any errors or warnings in this structure.
594 %
595 */
596 
597 static int CoderCompare(const void *x,const void *y)
598 {
599  register const char
600  **p,
601  **q;
602 
603  p=(const char **) x;
604  q=(const char **) y;
605  return(LocaleCompare(*p,*q));
606 }
607 
608 MagickExport char **GetCoderList(const char *pattern,
609  size_t *number_coders,ExceptionInfo *exception)
610 {
611  char
612  **coder_map;
613 
614  register const CoderInfo
615  *p;
616 
617  register ssize_t
618  i;
619 
620  /*
621  Allocate coder list.
622  */
623  assert(pattern != (char *) NULL);
624  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
625  assert(number_coders != (size_t *) NULL);
626  *number_coders=0;
627  p=GetCoderInfo("*",exception);
628  if (p == (const CoderInfo *) NULL)
629  return((char **) NULL);
630  coder_map=(char **) AcquireQuantumMemory((size_t)
631  GetNumberOfNodesInSplayTree(coder_cache)+1UL,sizeof(*coder_map));
632  if (coder_map == (char **) NULL)
633  return((char **) NULL);
634  /*
635  Generate coder list.
636  */
640  for (i=0; p != (const CoderInfo *) NULL; )
641  {
642  if ((p->stealth == MagickFalse) &&
643  (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
644  coder_map[i++]=ConstantString(p->name);
646  }
648  qsort((void *) coder_map,(size_t) i,sizeof(*coder_map),CoderCompare);
649  coder_map[i]=(char *) NULL;
650  *number_coders=(size_t) i;
651  return(coder_map);
652 }
653 
654 /*
655 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
656 % %
657 % %
658 % %
659 + I s C o d e r T r e e I n s t a n t i a t e d %
660 % %
661 % %
662 % %
663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
664 %
665 % IsCoderTreeInstantiated() determines if the coder tree is instantiated. If
666 % not, it instantiates the tree and returns it.
667 %
668 % The format of the IsCoderInstantiated method is:
669 %
670 % MagickBooleanType IsCoderTreeInstantiated(ExceptionInfo *exception)
671 %
672 % A description of each parameter follows.
673 %
674 % o exception: return any errors or warnings in this structure.
675 %
676 */
678 {
679  if (coder_cache == (SplayTreeInfo *) NULL)
680  {
681  if (coder_semaphore == (SemaphoreInfo *) NULL)
684  if (coder_cache == (SplayTreeInfo *) NULL)
687  }
688  return(coder_cache != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
689 }
690 
691 /*
692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
693 % %
694 % %
695 % %
696 % L i s t C o d e r I n f o %
697 % %
698 % %
699 % %
700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
701 %
702 % ListCoderInfo() lists the coder info to a file.
703 %
704 % The format of the ListCoderInfo coder is:
705 %
706 % MagickBooleanType ListCoderInfo(FILE *file,ExceptionInfo *exception)
707 %
708 % A description of each parameter follows.
709 %
710 % o file: An pointer to a FILE.
711 %
712 % o exception: return any errors or warnings in this structure.
713 %
714 */
716  ExceptionInfo *exception)
717 {
718  const char
719  *path;
720 
721  const CoderInfo
722  **coder_info;
723 
724  register ssize_t
725  i;
726 
727  size_t
728  number_coders;
729 
730  ssize_t
731  j;
732 
733  if (file == (const FILE *) NULL)
734  file=stdout;
735  coder_info=GetCoderInfoList("*",&number_coders,exception);
736  if (coder_info == (const CoderInfo **) NULL)
737  return(MagickFalse);
738  path=(const char *) NULL;
739  for (i=0; i < (ssize_t) number_coders; i++)
740  {
741  if (coder_info[i]->stealth != MagickFalse)
742  continue;
743  if ((path == (const char *) NULL) ||
744  (LocaleCompare(path,coder_info[i]->path) != 0))
745  {
746  if (coder_info[i]->path != (char *) NULL)
747  (void) FormatLocaleFile(file,"\nPath: %s\n\n",coder_info[i]->path);
748  (void) FormatLocaleFile(file,"Magick Coder\n");
749  (void) FormatLocaleFile(file,
750  "-------------------------------------------------"
751  "------------------------------\n");
752  }
753  path=coder_info[i]->path;
754  (void) FormatLocaleFile(file,"%s",coder_info[i]->magick);
755  for (j=(ssize_t) strlen(coder_info[i]->magick); j <= 11; j++)
756  (void) FormatLocaleFile(file," ");
757  if (coder_info[i]->name != (char *) NULL)
758  (void) FormatLocaleFile(file,"%s",coder_info[i]->name);
759  (void) FormatLocaleFile(file,"\n");
760  }
761  coder_info=(const CoderInfo **) RelinquishMagickMemory((void *) coder_info);
762  (void) fflush(file);
763  return(MagickTrue);
764 }
765 
766 /*
767 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
768 % %
769 % %
770 % %
771 + L o a d C o d e r C a c h e %
772 % %
773 % %
774 % %
775 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
776 %
777 % LoadCoderCache() loads the coder configurations which provides a
778 % mapping between coder attributes and a coder name.
779 %
780 % The format of the LoadCoderCache coder is:
781 %
782 % MagickBooleanType LoadCoderCache(SplayTreeInfo *cache,const char *xml,
783 % const char *filename,const size_t depth,ExceptionInfo *exception)
784 %
785 % A description of each parameter follows:
786 %
787 % o xml: The coder list in XML format.
788 %
789 % o filename: The coder list filename.
790 %
791 % o depth: depth of <include /> statements.
792 %
793 % o exception: return any errors or warnings in this structure.
794 %
795 */
796 static MagickBooleanType LoadCoderCache(SplayTreeInfo *cache,const char *xml,
797  const char *filename,const size_t depth,ExceptionInfo *exception)
798 {
799  char
800  keyword[MagickPathExtent],
801  *token;
802 
803  const char
804  *q;
805 
806  CoderInfo
807  *coder_info;
808 
810  status;
811 
812  size_t
813  extent;
814 
815  /*
816  Load the coder map file.
817  */
819  "Loading coder configuration file \"%s\" ...",filename);
820  if (xml == (const char *) NULL)
821  return(MagickFalse);
822  status=MagickTrue;
823  coder_info=(CoderInfo *) NULL;
824  token=AcquireString(xml);
825  extent=strlen(token)+MagickPathExtent;
826  for (q=(char *) xml; *q != '\0'; )
827  {
828  /*
829  Interpret XML.
830  */
831  GetNextToken(q,&q,extent,token);
832  if (*token == '\0')
833  break;
834  (void) CopyMagickString(keyword,token,MagickPathExtent);
835  if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
836  {
837  /*
838  Doctype element.
839  */
840  while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
841  GetNextToken(q,&q,extent,token);
842  continue;
843  }
844  if (LocaleNCompare(keyword,"<!--",4) == 0)
845  {
846  /*
847  Comment element.
848  */
849  while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
850  GetNextToken(q,&q,extent,token);
851  continue;
852  }
853  if (LocaleCompare(keyword,"<include") == 0)
854  {
855  /*
856  Include element.
857  */
858  while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
859  {
860  (void) CopyMagickString(keyword,token,MagickPathExtent);
861  GetNextToken(q,&q,extent,token);
862  if (*token != '=')
863  continue;
864  GetNextToken(q,&q,extent,token);
865  if (LocaleCompare(keyword,"file") == 0)
866  {
867  if (depth > MagickMaxRecursionDepth)
868  (void) ThrowMagickException(exception,GetMagickModule(),
869  ConfigureError,"IncludeNodeNestedTooDeeply","`%s'",token);
870  else
871  {
872  char
873  path[MagickPathExtent],
874  *file_xml;
875 
876  GetPathComponent(filename,HeadPath,path);
877  if (*path != '\0')
880  if (*token == *DirectorySeparator)
881  (void) CopyMagickString(path,token,MagickPathExtent);
882  else
883  (void) ConcatenateMagickString(path,token,MagickPathExtent);
884  file_xml=FileToXML(path,~0UL);
885  if (file_xml != (char *) NULL)
886  {
887  status&=LoadCoderCache(cache,file_xml,path,depth+1,
888  exception);
889  file_xml=DestroyString(file_xml);
890  }
891  }
892  }
893  }
894  continue;
895  }
896  if (LocaleCompare(keyword,"<coder") == 0)
897  {
898  /*
899  Coder element.
900  */
901  coder_info=(CoderInfo *) AcquireCriticalMemory(sizeof(*coder_info));
902  (void) memset(coder_info,0,sizeof(*coder_info));
903  coder_info->path=ConstantString(filename);
904  coder_info->exempt=MagickFalse;
905  coder_info->signature=MagickCoreSignature;
906  continue;
907  }
908  if (coder_info == (CoderInfo *) NULL)
909  continue;
910  if ((LocaleCompare(keyword,"/>") == 0) ||
911  (LocaleCompare(keyword,"</policy>") == 0))
912  {
913  status=AddValueToSplayTree(cache,ConstantString(coder_info->magick),
914  coder_info);
915  if (status == MagickFalse)
916  (void) ThrowMagickException(exception,GetMagickModule(),
917  ResourceLimitError,"MemoryAllocationFailed","`%s'",
918  coder_info->magick);
919  coder_info=(CoderInfo *) NULL;
920  continue;
921  }
922  GetNextToken(q,(const char **) NULL,extent,token);
923  if (*token != '=')
924  continue;
925  GetNextToken(q,&q,extent,token);
926  GetNextToken(q,&q,extent,token);
927  switch (*keyword)
928  {
929  case 'M':
930  case 'm':
931  {
932  if (LocaleCompare((char *) keyword,"magick") == 0)
933  {
934  coder_info->magick=ConstantString(token);
935  break;
936  }
937  break;
938  }
939  case 'N':
940  case 'n':
941  {
942  if (LocaleCompare((char *) keyword,"name") == 0)
943  {
944  coder_info->name=ConstantString(token);
945  break;
946  }
947  break;
948  }
949  case 'S':
950  case 's':
951  {
952  if (LocaleCompare((char *) keyword,"stealth") == 0)
953  {
954  coder_info->stealth=IsStringTrue(token);
955  break;
956  }
957  break;
958  }
959  default:
960  break;
961  }
962  }
963  token=(char *) RelinquishMagickMemory(token);
964  return(status != 0 ? MagickTrue : MagickFalse);
965 }
MagickExport const CoderInfo ** GetCoderInfoList(const char *pattern, size_t *number_coders, ExceptionInfo *exception)
Definition: coder.c:523
static SplayTreeInfo * AcquireCoderCache(const char *filename, ExceptionInfo *exception)
Definition: coder.c:322
#define MagickMaxRecursionDepth
Definition: studio.h:344
static MagickBooleanType LoadCoderCache(SplayTreeInfo *, const char *, const char *, const size_t, ExceptionInfo *)
Definition: coder.c:796
MagickExport MagickBooleanType AddValueToSplayTree(SplayTreeInfo *splay_tree, const void *key, const void *value)
Definition: splay-tree.c:154
MagickBooleanType stealth
Definition: coder.h:33
MagickExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:450
static MagickBooleanType IsCoderTreeInstantiated(ExceptionInfo *)
Definition: coder.c:677
MagickExport size_t ConcatenateMagickString(char *destination, const char *source, const size_t length)
Definition: string.c:426
MagickExport SemaphoreInfo * AcquireSemaphoreInfo(void)
Definition: semaphore.c:192
static int CoderCompare(const void *x, const void *y)
Definition: coder.c:597
MagickExport MagickBooleanType ListCoderInfo(FILE *file, ExceptionInfo *exception)
Definition: coder.c:715
static void * AcquireCriticalMemory(const size_t size)
Definition: log.h:52
static int CoderInfoCompare(const void *x, const void *y)
Definition: coder.c:510
MagickExport void * GetNextValueInLinkedList(LinkedListInfo *list_info)
Definition: linked-list.c:305
MagickExport const void * GetNextValueInSplayTree(SplayTreeInfo *splay_tree)
Definition: splay-tree.c:823
MagickPrivate MagickBooleanType CoderComponentGenesis(void)
Definition: coder.c:411
#define MagickCoreSignature
MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:293
const char * magick
Definition: coder.c:76
MagickExport unsigned char * GetStringInfoDatum(const StringInfo *string_info)
Definition: string.c:1295
MagickExport LinkedListInfo * GetConfigureOptions(const char *filename, ExceptionInfo *exception)
Definition: configure.c:654
MagickPrivate void CoderComponentTerminus(void)
Definition: coder.c:436
MagickExport void GetPathComponent(const char *path, PathType type, char *component)
Definition: utility.c:1213
MagickExport ssize_t FormatLocaleFile(FILE *file, const char *magick_restrict format,...)
Definition: locale.c:409
MagickBooleanType
Definition: magick-type.h:156
#define DirectorySeparator
Definition: studio.h:259
unsigned int MagickStatusType
Definition: magick-type.h:119
MagickExport char * AcquireString(const char *source)
Definition: string.c:129
char * magick
Definition: coder.h:28
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition: memory.c:533
MagickExport int LocaleNCompare(const char *p, const char *q, const size_t length)
Definition: locale.c:1540
static const CoderMapInfo CoderMap[]
Definition: coder.c:84
MagickExport SplayTreeInfo * DestroySplayTree(SplayTreeInfo *splay_tree)
Definition: splay-tree.c:682
MagickExport MagickBooleanType GlobExpression(const char *expression, const char *pattern, const MagickBooleanType case_insensitive)
Definition: token.c:353
#define MagickPathExtent
static SemaphoreInfo * coder_semaphore
Definition: coder.c:264
MagickExport MagickBooleanType IsStringTrue(const char *value)
Definition: string.c:1505
MagickExport SplayTreeInfo * NewSplayTree(int(*compare)(const void *, const void *), void *(*relinquish_key)(void *), void *(*relinquish_value)(void *))
Definition: splay-tree.c:1141
MagickExport MagickBooleanType ThrowMagickException(ExceptionInfo *exception, const char *module, const char *function, const size_t line, const ExceptionType severity, const char *tag, const char *format,...)
Definition: exception.c:1064
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition: log.c:1398
#define MagickCoderFilename
Definition: coder.c:68
char * path
Definition: coder.h:28
MagickExport char ** GetCoderList(const char *pattern, size_t *number_coders, ExceptionInfo *exception)
Definition: coder.c:608
MagickExport size_t CopyMagickString(char *destination, const char *source, const size_t length)
Definition: string.c:755
MagickExport const void * GetValueFromSplayTree(SplayTreeInfo *splay_tree, const void *key)
Definition: splay-tree.c:921
static SplayTreeInfo * coder_cache
Definition: coder.c:267
MagickExport int LocaleCompare(const char *p, const char *q)
Definition: locale.c:1440
#define GetMagickModule()
Definition: log.h:28
MagickExport int CompareSplayTreeString(const void *target, const void *source)
Definition: splay-tree.c:412
MagickExport const char * GetStringInfoPath(const StringInfo *string_info)
Definition: string.c:1382
MagickExport void GetNextToken(const char *start, const char **end, const size_t extent, char *token)
Definition: token.c:172
MagickBooleanType exempt
Definition: coder.h:33
MagickExport const CoderInfo * GetCoderInfo(const char *name, ExceptionInfo *exception)
Definition: coder.c:472
MagickExport char * DestroyString(char *string)
Definition: string.c:823
MagickExport void * AcquireMagickMemory(const size_t size)
Definition: memory.c:462
MagickExport void ActivateSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:97
struct _CoderMapInfo CoderMapInfo
MagickExport const void * GetRootValueFromSplayTree(SplayTreeInfo *splay_tree)
Definition: splay-tree.c:877
char * name
Definition: coder.h:28
MagickExport void ResetSplayTreeIterator(SplayTreeInfo *splay_tree)
Definition: splay-tree.c:1472
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1054
MagickExport size_t GetNumberOfNodesInSplayTree(const SplayTreeInfo *splay_tree)
Definition: splay-tree.c:976
static void * DestroyCoderNode(void *coder_info)
Definition: coder.c:304
#define MagickPrivate
MagickPrivate char * FileToXML(const char *, const size_t)
Definition: xml-tree.c:599
#define MagickExport
MagickExport void RelinquishSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:351
MagickExport LinkedListInfo * DestroyConfigureOptions(LinkedListInfo *options)
Definition: configure.c:326
MagickExport char * ConstantString(const char *source)
Definition: string.c:700
size_t signature
Definition: coder.h:37
const char * name
Definition: coder.c:76