42#include "MagickCore/studio.h"
43#include "MagickCore/blob.h"
44#include "MagickCore/client.h"
45#include "MagickCore/coder.h"
46#include "MagickCore/coder-private.h"
47#include "MagickCore/configure.h"
48#include "MagickCore/draw.h"
49#include "MagickCore/exception.h"
50#include "MagickCore/exception-private.h"
51#include "MagickCore/log.h"
52#include "MagickCore/memory_.h"
53#include "MagickCore/memory-private.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"
60#include "MagickCore/utility-private.h"
61#include "coders/coders.h"
66#define AddMagickCoder(coder) Magick ## coder ## Aliases
84 #include "coders/coders-list.h"
96static MagickBooleanType
123static void *DestroyCoderNode(
void *coder_info)
129 if (p->exempt == MagickFalse)
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);
138 return(RelinquishMagickMemory(p));
155 cache=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
158 for (i=0; i < (ssize_t) (
sizeof(CoderMap)/
sizeof(*CoderMap)); i++)
167 coder_info=(
CoderInfo *) AcquireMagickMemory(
sizeof(*coder_info));
170 (void) ThrowMagickException(exception,GetMagickModule(),
171 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",p->name);
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&=(MagickStatusType) AddValueToSplayTree(cache,
181 ConstantString(coder_info->magick),coder_info);
182 if (status == MagickFalse)
183 (void) ThrowMagickException(exception,GetMagickModule(),
184 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",coder_info->name);
207MagickPrivate MagickBooleanType CoderComponentGenesis(
void)
210 coder_semaphore=AcquireSemaphoreInfo();
232MagickPrivate
void CoderComponentTerminus(
void)
235 ActivateSemaphoreInfo(&coder_semaphore);
236 LockSemaphoreInfo(coder_semaphore);
238 coder_cache=DestroySplayTree(coder_cache);
239 UnlockSemaphoreInfo(coder_semaphore);
240 RelinquishSemaphoreInfo(&coder_semaphore);
268MagickExport
const CoderInfo *GetCoderInfo(
const char *name,
272 if (IsCoderTreeInstantiated(exception) == MagickFalse)
274 if ((name == (
const char *) NULL) || (LocaleCompare(name,
"*") == 0))
275 return((
const CoderInfo *) GetRootValueFromSplayTree(coder_cache));
276 return((
const CoderInfo *) GetValueFromSplayTree(coder_cache,name));
306static int CoderInfoCompare(
const void *x,
const void *y)
314 if (LocaleCompare((*p)->path,(*q)->path) == 0)
315 return(LocaleCompare((*p)->name,(*q)->name));
316 return(LocaleCompare((*p)->path,(*q)->path));
319MagickExport
const CoderInfo **GetCoderInfoList(
const char *pattern,
334 assert(pattern != (
char *) NULL);
335 assert(number_coders != (
size_t *) NULL);
336 if (IsEventLogging() != MagickFalse)
337 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
339 p=GetCoderInfo(
"*",exception);
342 coder_map=(
const CoderInfo **) AcquireQuantumMemory((
size_t)
343 GetNumberOfNodesInSplayTree(coder_cache)+1UL,
sizeof(*coder_map));
344 if (coder_map == (
const CoderInfo **) NULL)
349 LockSemaphoreInfo(coder_semaphore);
350 ResetSplayTreeIterator(coder_cache);
351 p=(
const CoderInfo *) GetNextValueInSplayTree(coder_cache);
352 for (i=0; p != (
const CoderInfo *) NULL; )
354 if ((p->stealth == MagickFalse) &&
355 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
357 p=(
const CoderInfo *) GetNextValueInSplayTree(coder_cache);
359 UnlockSemaphoreInfo(coder_semaphore);
360 qsort((
void *) coder_map,(
size_t) i,
sizeof(*coder_map),CoderInfoCompare);
362 *number_coders=(size_t) i;
394static int CoderCompare(
const void *x,
const void *y)
402 return(LocaleCompare(*p,*q));
405MagickExport
char **GetCoderList(
const char *pattern,
420 assert(pattern != (
char *) NULL);
421 assert(number_coders != (
size_t *) NULL);
422 if (IsEventLogging() != MagickFalse)
423 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
425 p=GetCoderInfo(
"*",exception);
427 return((
char **) NULL);
428 coder_map=(
char **) AcquireQuantumMemory((
size_t)
429 GetNumberOfNodesInSplayTree(coder_cache)+1UL,
sizeof(*coder_map));
430 if (coder_map == (
char **) NULL)
431 return((
char **) NULL);
435 LockSemaphoreInfo(coder_semaphore);
436 ResetSplayTreeIterator(coder_cache);
437 p=(
const CoderInfo *) GetNextValueInSplayTree(coder_cache);
438 for (i=0; p != (
const CoderInfo *) NULL; )
440 if ((p->stealth == MagickFalse) &&
441 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
442 coder_map[i++]=ConstantString(p->name);
443 p=(
const CoderInfo *) GetNextValueInSplayTree(coder_cache);
445 UnlockSemaphoreInfo(coder_semaphore);
446 qsort((
void *) coder_map,(
size_t) i,
sizeof(*coder_map),CoderCompare);
447 coder_map[i]=(
char *) NULL;
448 *number_coders=(size_t) i;
475static MagickBooleanType IsCoderTreeInstantiated(
ExceptionInfo *exception)
480 ActivateSemaphoreInfo(&coder_semaphore);
481 LockSemaphoreInfo(coder_semaphore);
483 coder_cache=AcquireCoderCache(exception);
484 UnlockSemaphoreInfo(coder_semaphore);
486 return(coder_cache != (
SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
513MagickExport MagickBooleanType ListCoderInfo(FILE *file,
531 if (file == (
const FILE *) NULL)
533 coder_info=GetCoderInfoList(
"*",&number_coders,exception);
534 if (coder_info == (
const CoderInfo **) NULL)
536 path=(
const char *) NULL;
537 for (i=0; i < (ssize_t) number_coders; i++)
539 if (coder_info[i]->stealth != MagickFalse)
541 if ((path == (
const char *) NULL) ||
542 (LocaleCompare(path,coder_info[i]->path) != 0))
544 if (coder_info[i]->path != (
char *) NULL)
545 (void) FormatLocaleFile(file,
"\nPath: %s\n\n",coder_info[i]->path);
546 (void) FormatLocaleFile(file,
"Magick Coder\n");
547 (void) FormatLocaleFile(file,
548 "-------------------------------------------------"
549 "------------------------------\n");
551 path=coder_info[i]->path;
552 (void) FormatLocaleFile(file,
"%s",coder_info[i]->magick);
553 for (j=(ssize_t) strlen(coder_info[i]->magick); j <= 15; j++)
554 (
void) FormatLocaleFile(file,
" ");
555 if (coder_info[i]->name != (
char *) NULL)
556 (void) FormatLocaleFile(file,
"%s",coder_info[i]->name);
557 (void) FormatLocaleFile(file,
"\n");
559 coder_info=(
const CoderInfo **) RelinquishMagickMemory((
void *) coder_info);