42#include "MagickCore/studio.h"
43#include "MagickCore/blob.h"
44#include "MagickCore/client.h"
45#include "MagickCore/configure.h"
46#include "MagickCore/configure-private.h"
47#include "MagickCore/exception.h"
48#include "MagickCore/exception-private.h"
49#include "MagickCore/linked-list.h"
50#include "MagickCore/linked-list-private.h"
51#include "MagickCore/magic.h"
52#include "MagickCore/magic-private.h"
53#include "MagickCore/memory_.h"
54#include "MagickCore/memory-private.h"
55#include "MagickCore/semaphore.h"
56#include "MagickCore/string_.h"
57#include "MagickCore/string-private.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 ## Headers
76 const MagickOffsetType
85 const MagickBooleanType
113static const MagicMapInfo
116 #include "coders/coders-list.h"
117 MagickCoderHeader(
"CGM", 0,
"BEGMF")
118 MagickCoderHeader(
"FIG", 0,
"#FIG")
119 MagickCoderHeader(
"HPGL", 0,
"IN;")
120 MagickCoderHeader(
"ILBM", 8,
"ILBM")
124 *magic_cache = (LinkedListInfo *) NULL,
125 *magic_list = (LinkedListInfo *) NULL;
134static MagickBooleanType
135 IsMagicListInstantiated(ExceptionInfo *);
163static
int CompareMagickInfoExtent(const
void *a,const
void *b)
174 delta=(MagickOffsetType) mb->length-(MagickOffsetType) ma->length;
175 if (ma->offset != mb->offset)
180 delta=ma->offset-mb->offset;
181 if ((ma->offset > mb->offset ? ma->offset : mb->offset) <= 10)
182 delta=mb->offset-ma->offset;
184 return(delta > INT_MAX ? 0 : (
int) delta);
187static LinkedListInfo *AcquireMagicList(ExceptionInfo *exception)
198 list=NewLinkedList(0);
203 for (i=0; i < (ssize_t) (
sizeof(MagicMap)/
sizeof(*MagicMap)); i++)
212 magic_info=(MagicInfo *) AcquireMagickMemory(
sizeof(*magic_info));
213 if (magic_info == (MagicInfo *) NULL)
215 (void) ThrowMagickException(exception,GetMagickModule(),
216 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",p->name);
219 (void) memset(magic_info,0,
sizeof(*magic_info));
220 magic_info->name=(
char *) p->name;
221 magic_info->offset=p->offset;
222 magic_info->magic=(
unsigned char *) p->magic;
223 magic_info->length=p->length;
224 magic_info->skip_spaces=p->skip_spaces;
225 magic_info->signature=MagickCoreSignature;
226 status&=(MagickStatusType) InsertValueInSortedLinkedList(list,
227 CompareMagickInfoExtent,NULL,magic_info);
228 if (status == MagickFalse)
229 (void) ThrowMagickException(exception,GetMagickModule(),
230 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",magic_info->name);
265static inline MagickBooleanType CompareMagic(
const unsigned char *magic,
266 const size_t length,
const MagicInfo *magic_info)
274 assert(magic_info->offset >= 0);
275 q=magic+magic_info->offset;
276 remaining=(MagickOffsetType) length-magic_info->offset;
277 if (magic_info->skip_spaces != MagickFalse)
278 while ((remaining > 0) && (isspace(*q) != 0))
283 if ((remaining >= (MagickOffsetType) magic_info->length) &&
284 (memcmp(q,magic_info->magic,magic_info->length) == 0))
289static MagickBooleanType IsMagicCacheInstantiated(
void)
291 if (magic_cache == (LinkedListInfo *) NULL)
294 ActivateSemaphoreInfo(&magic_cache_semaphore);
295 LockSemaphoreInfo(magic_cache_semaphore);
296 if (magic_cache == (LinkedListInfo *) NULL)
297 magic_cache=NewLinkedList(0);
298 UnlockSemaphoreInfo(magic_cache_semaphore);
300 return(magic_cache != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
303MagickExport
const MagicInfo *GetMagicInfo(
const unsigned char *magic,
304 const size_t length,ExceptionInfo *exception)
312 assert(exception != (ExceptionInfo *) NULL);
313 if (IsMagicListInstantiated(exception) == MagickFalse)
314 return((
const MagicInfo *) NULL);
315 if (IsMagicCacheInstantiated() == MagickFalse)
316 return((
const MagicInfo *) NULL);
320 magic_info=(
const MagicInfo *) NULL;
321 if (magic != (
const unsigned char *) NULL)
323 LockSemaphoreInfo(magic_cache_semaphore);
324 p=GetHeadElementInLinkedList(magic_cache);
325 while (p != (ElementInfo *) NULL)
327 magic_info=(
const MagicInfo *) p->value;
328 if (CompareMagic(magic,length,magic_info) != MagickFalse)
332 UnlockSemaphoreInfo(magic_cache_semaphore);
333 if (p != (ElementInfo *) NULL)
339 LockSemaphoreInfo(magic_list_semaphore);
340 p=GetHeadElementInLinkedList(magic_list);
341 if (magic == (
const unsigned char *) NULL)
343 UnlockSemaphoreInfo(magic_list_semaphore);
344 if (p != (ElementInfo *) NULL)
345 magic_info=(
const MagicInfo *) p->value;
348 while (p != (ElementInfo *) NULL)
350 magic_info=(
const MagicInfo *) p->value;
351 if (CompareMagic(magic,length,magic_info) != MagickFalse)
355 UnlockSemaphoreInfo(magic_list_semaphore);
356 if (p == (ElementInfo *) NULL)
357 magic_info=(
const MagicInfo *) NULL;
360 LockSemaphoreInfo(magic_cache_semaphore);
361 (void) InsertValueInSortedLinkedList(magic_cache,CompareMagickInfoExtent,
363 UnlockSemaphoreInfo(magic_cache_semaphore);
391MagickExport
size_t GetMagicPatternExtent(ExceptionInfo *exception)
403 assert(exception != (ExceptionInfo *) NULL);
404 if ((extent != 0) || (IsMagicListInstantiated(exception) == MagickFalse))
406 LockSemaphoreInfo(magic_list_semaphore);
407 p=GetHeadElementInLinkedList(magic_list);
408 for (max_offset=0; p != (ElementInfo *) NULL; )
413 magic_info=(
const MagicInfo *) p->value;
414 offset=magic_info->offset+(MagickOffsetType) magic_info->length;
415 if (offset > max_offset)
419 UnlockSemaphoreInfo(magic_list_semaphore);
420 if (max_offset > (MagickOffsetType) (MAGICK_SSIZE_MAX/2))
422 extent=(size_t) max_offset;
455#if defined(__cplusplus) || defined(c_plusplus)
459static int MagicInfoCompare(
const void *x,
const void *y)
465 p=(
const MagicInfo **) x,
466 q=(
const MagicInfo **) y;
467 return(LocaleCompare((*p)->name,(*q)->name));
470#if defined(__cplusplus) || defined(c_plusplus)
474MagickExport
const MagicInfo **GetMagicInfoList(
const char *pattern,
475 size_t *number_aliases,ExceptionInfo *magick_unused(exception))
486 magick_unreferenced(exception);
487 assert(pattern != (
char *) NULL);
488 assert(number_aliases != (
size_t *) NULL);
489 if (IsEventLogging() != MagickFalse)
490 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
492 if (IsMagicCacheInstantiated() == MagickFalse)
493 return((
const MagicInfo **) NULL);
494 aliases=(
const MagicInfo **) AcquireQuantumMemory((
size_t)
495 GetNumberOfElementsInLinkedList(magic_list)+1UL,
sizeof(*aliases));
496 if (aliases == (
const MagicInfo **) NULL)
497 return((
const MagicInfo **) NULL);
498 LockSemaphoreInfo(magic_list_semaphore);
499 p=GetHeadElementInLinkedList(magic_list);
500 for (i=0; p != (ElementInfo *) NULL; )
505 magic_info=(
const MagicInfo *) p->value;
506 if (GlobExpression(magic_info->name,pattern,MagickFalse) != MagickFalse)
507 aliases[i++]=magic_info;
510 UnlockSemaphoreInfo(magic_list_semaphore);
512 aliases=(
const MagicInfo **) RelinquishMagickMemory((
void*) aliases);
515 qsort((
void *) aliases,(
size_t) i,
sizeof(*aliases),MagicInfoCompare);
516 aliases[i]=(MagicInfo *) NULL;
518 *number_aliases=(size_t) i;
552#if defined(__cplusplus) || defined(c_plusplus)
556static int MagicCompare(
const void *x,
const void *y)
564 return(LocaleCompare(p,q));
567#if defined(__cplusplus) || defined(c_plusplus)
571MagickExport
char **GetMagicList(
const char *pattern,
size_t *number_aliases,
572 ExceptionInfo *magick_unused(exception))
583 magick_unreferenced(exception);
584 assert(pattern != (
char *) NULL);
585 assert(number_aliases != (
size_t *) NULL);
586 if (IsEventLogging() != MagickFalse)
587 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
589 if (IsMagicCacheInstantiated() == MagickFalse)
590 return((
char **) NULL);
591 aliases=(
char **) AcquireQuantumMemory((
size_t)
592 GetNumberOfElementsInLinkedList(magic_list)+1UL,
sizeof(*aliases));
593 if (aliases == (
char **) NULL)
594 return((
char **) NULL);
595 LockSemaphoreInfo(magic_list_semaphore);
596 p=GetHeadElementInLinkedList(magic_list);
597 for (i=0; p != (ElementInfo *) NULL; )
602 magic_info=(
const MagicInfo *) p->value;
603 if (GlobExpression(magic_info->name,pattern,MagickFalse) != MagickFalse)
604 aliases[i++]=ConstantString(magic_info->name);
607 UnlockSemaphoreInfo(magic_list_semaphore);
609 aliases=(
char **) RelinquishMagickMemory(aliases);
612 qsort((
void *) aliases,(
size_t) i,
sizeof(*aliases),MagicCompare);
613 aliases[i]=(
char *) NULL;
615 *number_aliases=(size_t) i;
641MagickExport
const char *GetMagicName(
const MagicInfo *magic_info)
643 assert(magic_info != (MagicInfo *) NULL);
644 assert(magic_info->signature == MagickCoreSignature);
645 if (IsEventLogging() != MagickFalse)
646 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
647 return(magic_info->name);
673static MagickBooleanType IsMagicListInstantiated(ExceptionInfo *exception)
675 if (magic_list == (LinkedListInfo *) NULL)
678 ActivateSemaphoreInfo(&magic_list_semaphore);
679 LockSemaphoreInfo(magic_list_semaphore);
680 if (magic_list == (LinkedListInfo *) NULL)
681 magic_list=AcquireMagicList(exception);
682 UnlockSemaphoreInfo(magic_list_semaphore);
684 return(magic_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
711MagickExport MagickBooleanType ListMagicInfo(FILE *file,
712 ExceptionInfo *exception)
726 if (file == (
const FILE *) NULL)
728 magic_info=GetMagicInfoList(
"*",&number_aliases,exception);
729 if (magic_info == (
const MagicInfo **) NULL)
731 (void) FormatLocaleFile(file,
"Name Offset Target\n");
732 (void) FormatLocaleFile(file,
733 "-------------------------------------------------"
734 "------------------------------\n");
735 for (i=0; i < (ssize_t) number_aliases; i++)
737 (void) FormatLocaleFile(file,
"%s",magic_info[i]->name);
738 for (j=(ssize_t) strlen(magic_info[i]->name); j <= 9; j++)
739 (
void) FormatLocaleFile(file,
" ");
740 (void) FormatLocaleFile(file,
"%6ld ",(
long) magic_info[i]->offset);
741 if (magic_info[i]->magic != (
unsigned char *) NULL)
743 for (j=0; magic_info[i]->magic[j] !=
'\0'; j++)
744 if (isprint((
int) (magic_info[i]->magic[j])) != 0)
745 (void) FormatLocaleFile(file,
"%c",magic_info[i]->magic[j]);
747 (
void) FormatLocaleFile(file,
"\\%03o",(
unsigned int)
748 ((
unsigned char) magic_info[i]->magic[j]));
750 (void) FormatLocaleFile(file,
"\n");
753 magic_info=(
const MagicInfo **) RelinquishMagickMemory((
void *) magic_info);
775MagickPrivate MagickBooleanType MagicComponentGenesis(
void)
778 magic_list_semaphore=AcquireSemaphoreInfo();
801static void *DestroyMagicElement(
void *magic_info)
803 (void) RelinquishMagickMemory((MagicInfo *) magic_info);
804 return((
void *) NULL);
807MagickPrivate
void MagicComponentTerminus(
void)
810 ActivateSemaphoreInfo(&magic_list_semaphore);
811 LockSemaphoreInfo(magic_list_semaphore);
812 if (magic_list != (LinkedListInfo *) NULL)
813 magic_list=DestroyLinkedList(magic_list,DestroyMagicElement);
814 UnlockSemaphoreInfo(magic_list_semaphore);
815 RelinquishSemaphoreInfo(&magic_list_semaphore);
817 ActivateSemaphoreInfo(&magic_cache_semaphore);
818 LockSemaphoreInfo(magic_cache_semaphore);
819 if (magic_cache != (LinkedListInfo *) NULL)
820 magic_cache=DestroyLinkedList(magic_cache,(
void *(*)(
void *)) NULL);
821 UnlockSemaphoreInfo(magic_cache_semaphore);
822 RelinquishSemaphoreInfo(&magic_cache_semaphore);