MagickCore  7.1.0
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-2021 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/log.h"
52 #include "MagickCore/memory_.h"
54 #include "MagickCore/option.h"
55 #include "MagickCore/semaphore.h"
56 #include "MagickCore/string_.h"
57 #include "MagickCore/splay-tree.h"
58 #include "MagickCore/token.h"
59 #include "MagickCore/utility.h"
61 #include "coders/coders.h"
62 
63 /*
64  Define declarations.
65 */
66 #define AddMagickCoder(coder) Magick ## coder ## Aliases
67 
68 /*
69  Typedef declarations.
70 */
71 typedef struct _CoderMapInfo
72 {
73  const char
75  *name;
76 } CoderMapInfo;
77 
78 /*
79  Static declarations.
80 */
81 static const CoderMapInfo
83  {
84  #include "coders/coders-list.h"
85  };
86 
87 static SemaphoreInfo
89 
90 static SplayTreeInfo
92 
93 /*
94  Forward declarations.
95 */
96 static MagickBooleanType
98 
99 /*
100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101 % %
102 % %
103 % %
104 + A c q u i r e C o d e r C a c h e %
105 % %
106 % %
107 % %
108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109 %
110 % AcquireCoderCache() caches one or more coder configurations which provides a
111 % mapping between coder attributes and a coder name.
112 %
113 % The format of the AcquireCoderCache coder is:
114 %
115 % SplayTreeInfo *AcquireCoderCache(ExceptionInfo *exception)
116 %
117 % A description of each parameter follows:
118 %
119 % o exception: return any errors or warnings in this structure.
120 %
121 */
122 
123 static void *DestroyCoderNode(void *coder_info)
124 {
125  CoderInfo
126  *p;
127 
128  p=(CoderInfo *) coder_info;
129  if (p->exempt == MagickFalse)
130  {
131  if (p->path != (char *) NULL)
132  p->path=DestroyString(p->path);
133  if (p->name != (char *) NULL)
134  p->name=DestroyString(p->name);
135  if (p->magick != (char *) NULL)
136  p->magick=DestroyString(p->magick);
137  }
138  return(RelinquishMagickMemory(p));
139 }
140 
142 {
144  status;
145 
146  ssize_t
147  i;
148 
150  *cache;
151 
152  /*
153  Load built-in coder map.
154  */
157  status=MagickTrue;
158  for (i=0; i < (ssize_t) (sizeof(CoderMap)/sizeof(*CoderMap)); i++)
159  {
160  CoderInfo
161  *coder_info;
162 
163  const CoderMapInfo
164  *p;
165 
166  p=CoderMap+i;
167  coder_info=(CoderInfo *) AcquireMagickMemory(sizeof(*coder_info));
168  if (coder_info == (CoderInfo *) NULL)
169  {
170  (void) ThrowMagickException(exception,GetMagickModule(),
171  ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name);
172  continue;
173  }
174  (void) memset(coder_info,0,sizeof(*coder_info));
175  coder_info->path=(char *) "[built-in]";
176  coder_info->magick=(char *) p->magick;
177  coder_info->name=(char *) p->name;
178  coder_info->exempt=MagickTrue;
179  coder_info->signature=MagickCoreSignature;
180  status&=AddValueToSplayTree(cache,ConstantString(coder_info->magick),
181  coder_info);
182  if (status == MagickFalse)
183  (void) ThrowMagickException(exception,GetMagickModule(),
184  ResourceLimitError,"MemoryAllocationFailed","`%s'",coder_info->name);
185  }
186  return(cache);
187 }
188 
189 /*
190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
191 % %
192 % %
193 % %
194 + C o d e r C o m p o n e n t G e n e s i s %
195 % %
196 % %
197 % %
198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
199 %
200 % CoderComponentGenesis() instantiates the coder component.
201 %
202 % The format of the CoderComponentGenesis method is:
203 %
204 % MagickBooleanType CoderComponentGenesis(void)
205 %
206 */
208 {
209  if (coder_semaphore == (SemaphoreInfo *) NULL)
211  return(MagickTrue);
212 }
213 
214 /*
215 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
216 % %
217 % %
218 % %
219 + C o d e r C o m p o n e n t T e r m i n u s %
220 % %
221 % %
222 % %
223 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
224 %
225 % CoderComponentTerminus() destroys the coder component.
226 %
227 % The format of the CoderComponentTerminus method is:
228 %
229 % CoderComponentTerminus(void)
230 %
231 */
233 {
234  if (coder_semaphore == (SemaphoreInfo *) NULL)
237  if (coder_cache != (SplayTreeInfo *) NULL)
241 }
242 
243 /*
244 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
245 % %
246 % %
247 % %
248 + G e t C o d e r I n f o %
249 % %
250 % %
251 % %
252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
253 %
254 % GetCoderInfo searches the coder list for the specified name and if found
255 % returns attributes for that coder.
256 %
257 % The format of the GetCoderInfo method is:
258 %
259 % const CoderInfo *GetCoderInfo(const char *name,ExceptionInfo *exception)
260 %
261 % A description of each parameter follows:
262 %
263 % o name: the coder name.
264 %
265 % o exception: return any errors or warnings in this structure.
266 %
267 */
268 MagickExport const CoderInfo *GetCoderInfo(const char *name,
269  ExceptionInfo *exception)
270 {
271  assert(exception != (ExceptionInfo *) NULL);
272  if (IsCoderTreeInstantiated(exception) == MagickFalse)
273  return((const CoderInfo *) NULL);
274  if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
276  return((const CoderInfo *) GetValueFromSplayTree(coder_cache,name));
277 }
278 
279 /*
280 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
281 % %
282 % %
283 % %
284 % G e t C o d e r I n f o L i s t %
285 % %
286 % %
287 % %
288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
289 %
290 % GetCoderInfoList() returns any coder_map that match the specified pattern.
291 % The format of the GetCoderInfoList function is:
292 %
293 % const CoderInfo **GetCoderInfoList(const char *pattern,
294 % size_t *number_coders,ExceptionInfo *exception)
295 %
296 % A description of each parameter follows:
297 %
298 % o pattern: Specifies a pointer to a text string containing a pattern.
299 %
300 % o number_coders: This integer returns the number of coders in the list.
301 %
302 % o exception: return any errors or warnings in this structure.
303 %
304 */
305 
306 static int CoderInfoCompare(const void *x,const void *y)
307 {
308  const CoderInfo
309  **p,
310  **q;
311 
312  p=(const CoderInfo **) x,
313  q=(const CoderInfo **) y;
314  if (LocaleCompare((*p)->path,(*q)->path) == 0)
315  return(LocaleCompare((*p)->name,(*q)->name));
316  return(LocaleCompare((*p)->path,(*q)->path));
317 }
318 
319 MagickExport const CoderInfo **GetCoderInfoList(const char *pattern,
320  size_t *number_coders,ExceptionInfo *exception)
321 {
322  const CoderInfo
323  **coder_map;
324 
325  const CoderInfo
326  *p;
327 
328  ssize_t
329  i;
330 
331  /*
332  Allocate coder list.
333  */
334  assert(pattern != (char *) NULL);
335  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
336  assert(number_coders != (size_t *) NULL);
337  *number_coders=0;
338  p=GetCoderInfo("*",exception);
339  if (p == (const CoderInfo *) NULL)
340  return((const CoderInfo **) NULL);
341  coder_map=(const CoderInfo **) AcquireQuantumMemory((size_t)
342  GetNumberOfNodesInSplayTree(coder_cache)+1UL,sizeof(*coder_map));
343  if (coder_map == (const CoderInfo **) NULL)
344  return((const CoderInfo **) NULL);
345  /*
346  Generate coder list.
347  */
351  for (i=0; p != (const CoderInfo *) NULL; )
352  {
353  if ((p->stealth == MagickFalse) &&
354  (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
355  coder_map[i++]=p;
357  }
359  qsort((void *) coder_map,(size_t) i,sizeof(*coder_map),CoderInfoCompare);
360  coder_map[i]=(CoderInfo *) NULL;
361  *number_coders=(size_t) i;
362  return(coder_map);
363 }
364 
365 /*
366 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
367 % %
368 % %
369 % %
370 % G e t C o d e r L i s t %
371 % %
372 % %
373 % %
374 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
375 %
376 % GetCoderList() returns any coder_map that match the specified pattern.
377 %
378 % The format of the GetCoderList function is:
379 %
380 % char **GetCoderList(const char *pattern,size_t *number_coders,
381 % ExceptionInfo *exception)
382 %
383 % A description of each parameter follows:
384 %
385 % o pattern: Specifies a pointer to a text string containing a pattern.
386 %
387 % o number_coders: This integer returns the number of coders in the list.
388 %
389 % o exception: return any errors or warnings in this structure.
390 %
391 */
392 
393 static int CoderCompare(const void *x,const void *y)
394 {
395  const char
396  **p,
397  **q;
398 
399  p=(const char **) x;
400  q=(const char **) y;
401  return(LocaleCompare(*p,*q));
402 }
403 
404 MagickExport char **GetCoderList(const char *pattern,
405  size_t *number_coders,ExceptionInfo *exception)
406 {
407  char
408  **coder_map;
409 
410  const CoderInfo
411  *p;
412 
413  ssize_t
414  i;
415 
416  /*
417  Allocate coder list.
418  */
419  assert(pattern != (char *) NULL);
420  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
421  assert(number_coders != (size_t *) NULL);
422  *number_coders=0;
423  p=GetCoderInfo("*",exception);
424  if (p == (const CoderInfo *) NULL)
425  return((char **) NULL);
426  coder_map=(char **) AcquireQuantumMemory((size_t)
427  GetNumberOfNodesInSplayTree(coder_cache)+1UL,sizeof(*coder_map));
428  if (coder_map == (char **) NULL)
429  return((char **) NULL);
430  /*
431  Generate coder list.
432  */
436  for (i=0; p != (const CoderInfo *) NULL; )
437  {
438  if ((p->stealth == MagickFalse) &&
439  (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
440  coder_map[i++]=ConstantString(p->name);
442  }
444  qsort((void *) coder_map,(size_t) i,sizeof(*coder_map),CoderCompare);
445  coder_map[i]=(char *) NULL;
446  *number_coders=(size_t) i;
447  return(coder_map);
448 }
449 
450 /*
451 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
452 % %
453 % %
454 % %
455 + I s C o d e r T r e e I n s t a n t i a t e d %
456 % %
457 % %
458 % %
459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
460 %
461 % IsCoderTreeInstantiated() determines if the coder tree is instantiated. If
462 % not, it instantiates the tree and returns it.
463 %
464 % The format of the IsCoderInstantiated method is:
465 %
466 % MagickBooleanType IsCoderTreeInstantiated(ExceptionInfo *exception)
467 %
468 % A description of each parameter follows.
469 %
470 % o exception: return any errors or warnings in this structure.
471 %
472 */
474 {
475  if (coder_cache == (SplayTreeInfo *) NULL)
476  {
477  if (coder_semaphore == (SemaphoreInfo *) NULL)
480  if (coder_cache == (SplayTreeInfo *) NULL)
481  coder_cache=AcquireCoderCache(exception);
483  }
484  return(coder_cache != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
485 }
486 
487 /*
488 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
489 % %
490 % %
491 % %
492 % L i s t C o d e r I n f o %
493 % %
494 % %
495 % %
496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
497 %
498 % ListCoderInfo() lists the coder info to a file.
499 %
500 % The format of the ListCoderInfo coder is:
501 %
502 % MagickBooleanType ListCoderInfo(FILE *file,ExceptionInfo *exception)
503 %
504 % A description of each parameter follows.
505 %
506 % o file: An pointer to a FILE.
507 %
508 % o exception: return any errors or warnings in this structure.
509 %
510 */
512  ExceptionInfo *exception)
513 {
514  const char
515  *path;
516 
517  const CoderInfo
518  **coder_info;
519 
520  ssize_t
521  i;
522 
523  size_t
524  number_coders;
525 
526  ssize_t
527  j;
528 
529  if (file == (const FILE *) NULL)
530  file=stdout;
531  coder_info=GetCoderInfoList("*",&number_coders,exception);
532  if (coder_info == (const CoderInfo **) NULL)
533  return(MagickFalse);
534  path=(const char *) NULL;
535  for (i=0; i < (ssize_t) number_coders; i++)
536  {
537  if (coder_info[i]->stealth != MagickFalse)
538  continue;
539  if ((path == (const char *) NULL) ||
540  (LocaleCompare(path,coder_info[i]->path) != 0))
541  {
542  if (coder_info[i]->path != (char *) NULL)
543  (void) FormatLocaleFile(file,"\nPath: %s\n\n",coder_info[i]->path);
544  (void) FormatLocaleFile(file,"Magick Coder\n");
545  (void) FormatLocaleFile(file,
546  "-------------------------------------------------"
547  "------------------------------\n");
548  }
549  path=coder_info[i]->path;
550  (void) FormatLocaleFile(file,"%s",coder_info[i]->magick);
551  for (j=(ssize_t) strlen(coder_info[i]->magick); j <= 15; j++)
552  (void) FormatLocaleFile(file," ");
553  if (coder_info[i]->name != (char *) NULL)
554  (void) FormatLocaleFile(file,"%s",coder_info[i]->name);
555  (void) FormatLocaleFile(file,"\n");
556  }
557  coder_info=(const CoderInfo **) RelinquishMagickMemory((void *) coder_info);
558  (void) fflush(file);
559  return(MagickTrue);
560 }
MagickExport const CoderInfo ** GetCoderInfoList(const char *pattern, size_t *number_coders, ExceptionInfo *exception)
Definition: coder.c:319
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:449
static MagickBooleanType IsCoderTreeInstantiated(ExceptionInfo *)
Definition: coder.c:473
MagickExport SemaphoreInfo * AcquireSemaphoreInfo(void)
Definition: semaphore.c:192
static int CoderCompare(const void *x, const void *y)
Definition: coder.c:393
MagickExport MagickBooleanType ListCoderInfo(FILE *file, ExceptionInfo *exception)
Definition: coder.c:511
Definition: log.h:52
static int CoderInfoCompare(const void *x, const void *y)
Definition: coder.c:306
MagickExport const void * GetNextValueInSplayTree(SplayTreeInfo *splay_tree)
Definition: splay-tree.c:823
MagickPrivate MagickBooleanType CoderComponentGenesis(void)
Definition: coder.c:207
#define MagickCoreSignature
MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:293
const char * magick
Definition: coder.c:74
MagickPrivate void CoderComponentTerminus(void)
Definition: coder.c:232
MagickExport ssize_t FormatLocaleFile(FILE *file, const char *magick_restrict format,...)
Definition: locale.c:368
MagickBooleanType
Definition: magick-type.h:165
unsigned int MagickStatusType
Definition: magick-type.h:125
static SplayTreeInfo * AcquireCoderCache(ExceptionInfo *exception)
Definition: coder.c:141
MagickExport MagickBooleanType GlobExpression(const char *magick_restrict expression, const char *magick_restrict pattern, const MagickBooleanType case_insensitive)
Definition: token.c:352
char * magick
Definition: coder.h:28
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition: memory.c:665
static const CoderMapInfo CoderMap[]
Definition: coder.c:82
MagickExport SplayTreeInfo * DestroySplayTree(SplayTreeInfo *splay_tree)
Definition: splay-tree.c:682
static SemaphoreInfo * coder_semaphore
Definition: coder.c:88
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:1145
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition: log.c:1660
char * path
Definition: coder.h:28
MagickExport char ** GetCoderList(const char *pattern, size_t *number_coders, ExceptionInfo *exception)
Definition: coder.c:404
MagickExport const void * GetValueFromSplayTree(SplayTreeInfo *splay_tree, const void *key)
Definition: splay-tree.c:921
static SplayTreeInfo * coder_cache
Definition: coder.c:91
MagickExport int LocaleCompare(const char *p, const char *q)
Definition: locale.c:1399
#define GetMagickModule()
Definition: log.h:28
MagickExport int CompareSplayTreeString(const void *target, const void *source)
Definition: splay-tree.c:412
MagickBooleanType exempt
Definition: coder.h:33
MagickExport const CoderInfo * GetCoderInfo(const char *name, ExceptionInfo *exception)
Definition: coder.c:268
MagickExport char * DestroyString(char *string)
Definition: string.c:788
MagickExport void * AcquireMagickMemory(const size_t size)
Definition: memory.c:552
MagickExport void ActivateSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:98
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:1162
MagickExport size_t GetNumberOfNodesInSplayTree(const SplayTreeInfo *splay_tree)
Definition: splay-tree.c:976
static void * DestroyCoderNode(void *coder_info)
Definition: coder.c:123
#define MagickPrivate
#define MagickExport
MagickExport void RelinquishSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:351
MagickExport char * ConstantString(const char *source)
Definition: string.c:678
size_t signature
Definition: coder.h:37
const char * name
Definition: coder.c:74