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
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")
134 static MagickBooleanType
163 static
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);
198 list=NewLinkedList(0);
203 for (i=0; i < (ssize_t) (
sizeof(MagicMap)/
sizeof(*MagicMap)); i++)
212 magic_info=(
MagicInfo *) AcquireMagickMemory(
sizeof(*magic_info));
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);
265 static 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))
289 static MagickBooleanType IsMagicCacheInstantiated(
void)
294 ActivateSemaphoreInfo(&magic_cache_semaphore);
295 LockSemaphoreInfo(magic_cache_semaphore);
297 magic_cache=NewLinkedList(0);
298 UnlockSemaphoreInfo(magic_cache_semaphore);
300 return(magic_cache != (
LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
303 MagickExport
const MagicInfo *GetMagicInfo(
const unsigned char *magic,
313 if (IsMagicListInstantiated(exception) == MagickFalse)
315 if (IsMagicCacheInstantiated() == MagickFalse)
321 if (magic != (
const unsigned char *) NULL)
323 LockSemaphoreInfo(magic_cache_semaphore);
324 p=GetHeadElementInLinkedList(magic_cache);
328 if (CompareMagic(magic,length,magic_info) != MagickFalse)
332 UnlockSemaphoreInfo(magic_cache_semaphore);
339 LockSemaphoreInfo(magic_list_semaphore);
340 p=GetHeadElementInLinkedList(magic_list);
341 if (magic == (
const unsigned char *) NULL)
343 UnlockSemaphoreInfo(magic_list_semaphore);
351 if (CompareMagic(magic,length,magic_info) != MagickFalse)
355 UnlockSemaphoreInfo(magic_list_semaphore);
360 LockSemaphoreInfo(magic_cache_semaphore);
361 (void) InsertValueInSortedLinkedList(magic_cache,CompareMagickInfoExtent,
363 UnlockSemaphoreInfo(magic_cache_semaphore);
391 MagickExport
size_t GetMagicPatternExtent(
ExceptionInfo *exception)
404 if ((extent != 0) || (IsMagicListInstantiated(exception) == MagickFalse))
406 LockSemaphoreInfo(magic_list_semaphore);
407 p=GetHeadElementInLinkedList(magic_list);
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)
459 static int MagicInfoCompare(
const void *x,
const void *y)
467 return(LocaleCompare((*p)->name,(*q)->name));
470 #if defined(__cplusplus) || defined(c_plusplus)
474 MagickExport
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)
494 aliases=(
const MagicInfo **) AcquireQuantumMemory((
size_t)
495 GetNumberOfElementsInLinkedList(magic_list)+1UL,
sizeof(*aliases));
496 if (aliases == (
const MagicInfo **) NULL)
498 LockSemaphoreInfo(magic_list_semaphore);
499 p=GetHeadElementInLinkedList(magic_list);
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);
518 *number_aliases=(size_t) i;
552 #if defined(__cplusplus) || defined(c_plusplus)
556 static int MagicCompare(
const void *x,
const void *y)
564 return(LocaleCompare(p,q));
567 #if defined(__cplusplus) || defined(c_plusplus)
571 MagickExport
char **GetMagicList(
const char *pattern,
size_t *number_aliases,
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);
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;
641 MagickExport
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);
673 static MagickBooleanType IsMagicListInstantiated(
ExceptionInfo *exception)
678 ActivateSemaphoreInfo(&magic_list_semaphore);
679 LockSemaphoreInfo(magic_list_semaphore);
681 magic_list=AcquireMagicList(exception);
682 UnlockSemaphoreInfo(magic_list_semaphore);
684 return(magic_list != (
LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
711 MagickExport MagickBooleanType ListMagicInfo(FILE *file,
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);
775 MagickPrivate MagickBooleanType MagicComponentGenesis(
void)
778 magic_list_semaphore=AcquireSemaphoreInfo();
801 static void *DestroyMagicElement(
void *magic_info)
803 RelinquishMagickMemory((
MagicInfo *) magic_info);
804 return((
void *) NULL);
807 MagickPrivate
void MagicComponentTerminus(
void)
810 ActivateSemaphoreInfo(&magic_list_semaphore);
811 LockSemaphoreInfo(magic_list_semaphore);
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);
820 magic_cache=DestroyLinkedList(magic_cache,(
void *(*)(
void *)) NULL);
821 UnlockSemaphoreInfo(magic_cache_semaphore);
822 RelinquishSemaphoreInfo(&magic_cache_semaphore);