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