1/* 2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3% % 4% % 5% % 6% M M AAA GGGG IIIII CCCC K K % 7% MM MM A A G I C K K % 8% M M M AAAAA G GGG I C KKK % 9% M M A A G G I C K K % 10% M M A A GGGG IIIII CCCC K K % 11% % 12% % 13% Methods to Read or List ImageMagick Image formats % 14% % 15% Software Design % 16% Bob Friesenhahn % 17% Cristy % 18% November 1998 % 19% % 20% % 21% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 22% dedicated to making software imaging solutions freely available. % 23% % 24% You may not use this file except in compliance with the License. You may % 25% obtain a copy of the License at % 26% % 27% http://www.imagemagick.org/script/license.php % 28% % 29% Unless required by applicable law or agreed to in writing, software % 30% distributed under the License is distributed on an "AS IS" BASIS, % 31% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 32% See the License for the specific language governing permissions and % 33% limitations under the License. % 34% % 35%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 36% 37% 38*/ 39 40/* 41 Include declarations. 42*/ 43#include "MagickCore/studio.h" 44#include "MagickCore/annotate-private.h" 45#include "MagickCore/blob.h" 46#include "MagickCore/blob-private.h" 47#include "MagickCore/cache.h" 48#include "MagickCore/cache-private.h" 49#include "MagickCore/coder-private.h" 50#include "MagickCore/client.h" 51#include "MagickCore/color-private.h" 52#include "MagickCore/configure-private.h" 53#include "MagickCore/constitute-private.h" 54#include "MagickCore/delegate-private.h" 55#include "MagickCore/draw.h" 56#include "MagickCore/exception.h" 57#include "MagickCore/exception-private.h" 58#include "MagickCore/locale-private.h" 59#include "MagickCore/log-private.h" 60#include "MagickCore/magic-private.h" 61#include "MagickCore/magick.h" 62#include "MagickCore/magick-private.h" 63#include "MagickCore/memory_.h" 64#include "MagickCore/mime-private.h" 65#include "MagickCore/module.h" 66#include "MagickCore/module-private.h" 67#include "MagickCore/nt-base-private.h" 68#include "MagickCore/nt-feature.h" 69#include "MagickCore/opencl-private.h" 70#include "MagickCore/option-private.h" 71#include "MagickCore/random-private.h" 72#include "MagickCore/registry.h" 73#include "MagickCore/registry-private.h" 74#include "MagickCore/resource_.h" 75#include "MagickCore/resource-private.h" 76#include "MagickCore/policy.h" 77#include "MagickCore/policy-private.h" 78#include "MagickCore/semaphore.h" 79#include "MagickCore/semaphore-private.h" 80#include "MagickCore/signature-private.h" 81#include "MagickCore/splay-tree.h" 82#include "MagickCore/string_.h" 83#include "MagickCore/string-private.h" 84#include "MagickCore/thread_.h" 85#include "MagickCore/thread-private.h" 86#include "MagickCore/type-private.h" 87#include "MagickCore/token.h" 88#include "MagickCore/utility.h" 89#include "MagickCore/utility-private.h" 90#include "MagickCore/xwindow-private.h" 91 92/* 93 Define declarations. 94*/ 95#if !defined(MAGICKCORE_RETSIGTYPE) 96# define MAGICKCORE_RETSIGTYPE void 97#endif 98#if !defined(SIG_DFL) 99# define SIG_DFL ((SignalHandler *) 0) 100#endif 101#if !defined(SIG_ERR) 102# define SIG_ERR ((SignalHandler *) -1) 103#endif 104#if !defined(SIGMAX) 105#define SIGMAX 64 106#endif 107 108/* 109 Typedef declarations. 110*/ 111typedef MAGICKCORE_RETSIGTYPE 112 SignalHandler(int); 113 114/* 115 Global declarations. 116*/ 117static SemaphoreInfo 118 *magick_semaphore = (SemaphoreInfo *) NULL; 119 120static SignalHandler 121 *signal_handlers[SIGMAX] = { (SignalHandler *) NULL }; 122 123static SplayTreeInfo 124 *magick_list = (SplayTreeInfo *) NULL; 125 126static volatile MagickBooleanType 127 instantiate_magickcore = MagickFalse, 128 magickcore_signal_in_progress = MagickFalse; 129 130/* 131 Forward declarations. 132*/ 133static MagickBooleanType 134 IsMagickTreeInstantiated(ExceptionInfo *); 135 136/* 137%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 138% % 139% % 140% % 141% A c q u i r e M a g i c k I n f o % 142% % 143% % 144% % 145%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 146% 147% AcquireMagickInfo() allocates a MagickInfo structure and initializes the 148% members to default values. 149% 150% The format of the AcquireMagickInfo method is: 151% 152% MagickInfo *AcquireMagickInfo(const char *module, const char *name,) 153% 154% A description of each parameter follows: 155% 156% o module: a character string that represents the module associated 157% with the MagickInfo structure. 158% 159% o name: a character string that represents the image format associated 160% with the MagickInfo structure. 161% 162% o description: a character string that represents the image format 163% associated with the MagickInfo structure. 164% 165*/ 166MagickExport MagickInfo *AcquireMagickInfo(const char *module, 167 const char *name, const char *description) 168{ 169 MagickInfo 170 *magick_info; 171 172 assert(module != (const char *) NULL); 173 assert(name != (const char *) NULL); 174 assert(description != (const char *) NULL); 175 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name); 176 magick_info=(MagickInfo *) AcquireMagickMemory(sizeof(*magick_info)); 177 if (magick_info == (MagickInfo *) NULL) 178 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 179 (void) ResetMagickMemory(magick_info,0,sizeof(*magick_info)); 180 magick_info->module=ConstantString(module); 181 magick_info->name=ConstantString(name); 182 magick_info->description=ConstantString(description); 183 magick_info->flags=CoderAdjoinFlag | CoderBlobSupportFlag | 184 CoderDecoderThreadSupportFlag | CoderEncoderThreadSupportFlag | 185 CoderUseExtensionFlag; 186 magick_info->signature=MagickCoreSignature; 187 return(magick_info); 188} 189 190/* 191%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 192% % 193% % 194% % 195+ G e t I m a g e D e c o d e r % 196% % 197% % 198% % 199%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 200% 201% GetImageDecoder() returns the image decoder. 202% 203% The format of the GetImageDecoder method is: 204% 205% DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info) 206% 207% A description of each parameter follows: 208% 209% o magick_info: The magick info. 210% 211*/ 212MagickExport DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info) 213{ 214 assert(magick_info != (MagickInfo *) NULL); 215 assert(magick_info->signature == MagickCoreSignature); 216 return(magick_info->decoder); 217} 218 219/* 220%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 221% % 222% % 223% % 224+ G e t I m a g e E n c o d e r % 225% % 226% % 227% % 228%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 229% 230% GetImageEncoder() returns the image encoder. 231% 232% The format of the GetImageEncoder method is: 233% 234% EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info) 235% 236% A description of each parameter follows: 237% 238% o magick_info: The magick info. 239% 240*/ 241MagickExport EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info) 242{ 243 assert(magick_info != (MagickInfo *) NULL); 244 assert(magick_info->signature == MagickCoreSignature); 245 return(magick_info->encoder); 246} 247 248/* 249%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 250% % 251% % 252% % 253+ G e t I m a g e M a g i c k % 254% % 255% % 256% % 257%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 258% 259% GetImageMagick() searches for an image format that matches the specified 260% magick string. If one is found, MagickTrue is returned otherwise 261% MagickFalse. 262% 263% The format of the GetImageMagick method is: 264% 265% MagickBooleanType GetImageMagick(const unsigned char *magick, 266% const size_t length,char *format) 267% 268% A description of each parameter follows: 269% 270% o magick: the image format we are searching for. 271% 272% o length: the length of the binary string. 273% 274% o format: the image format as determined by the magick bytes. 275% 276*/ 277MagickExport MagickBooleanType GetImageMagick(const unsigned char *magick, 278 const size_t length,char *format) 279{ 280 ExceptionInfo 281 *exception; 282 283 MagickBooleanType 284 status; 285 286 register const MagickInfo 287 *p; 288 289 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 290 assert(magick != (const unsigned char *) NULL); 291 exception=AcquireExceptionInfo(); 292 p=GetMagickInfo("*",exception); 293 exception=DestroyExceptionInfo(exception); 294 if (p == (const MagickInfo *) NULL) 295 return(MagickFalse); 296 status=MagickFalse; 297 LockSemaphoreInfo(magick_semaphore); 298 ResetSplayTreeIterator(magick_list); 299 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list); 300 while (p != (const MagickInfo *) NULL) 301 { 302 if ((p->magick != (IsImageFormatHandler *) NULL) && 303 (p->magick(magick,length) != 0)) 304 { 305 status=MagickTrue; 306 (void) CopyMagickString(format,p->name,MagickPathExtent); 307 break; 308 } 309 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list); 310 } 311 UnlockSemaphoreInfo(magick_semaphore); 312 return(status); 313} 314 315/* 316%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 317% % 318% % 319% % 320+ G e t M a g i c k A d j o i n % 321% % 322% % 323% % 324%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 325% 326% GetMagickAdjoin() returns MagickTrue if the magick adjoin is MagickTrue. 327% 328% The format of the GetMagickAdjoin method is: 329% 330% MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info) 331% 332% A description of each parameter follows: 333% 334% o magick_info: The magick info. 335% 336*/ 337MagickExport MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info) 338{ 339 assert(magick_info != (MagickInfo *) NULL); 340 assert(magick_info->signature == MagickCoreSignature); 341 return(((magick_info->flags & CoderAdjoinFlag) == 0) ? MagickFalse : 342 MagickTrue); 343} 344 345/* 346%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 347% % 348% % 349% % 350+ G e t M a g i c k B l o b S u p p o r t % 351% % 352% % 353% % 354%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 355% 356% GetMagickBlobSupport() returns MagickTrue if the magick supports blobs. 357% 358% The format of the GetMagickBlobSupport method is: 359% 360% MagickBooleanType GetMagickBlobSupport(const MagickInfo *magick_info) 361% 362% A description of each parameter follows: 363% 364% o magick_info: The magick info. 365% 366*/ 367MagickExport MagickBooleanType GetMagickBlobSupport( 368 const MagickInfo *magick_info) 369{ 370 assert(magick_info != (MagickInfo *) NULL); 371 assert(magick_info->signature == MagickCoreSignature); 372 return(((magick_info->flags & CoderBlobSupportFlag) == 0) ? MagickFalse : 373 MagickTrue); 374} 375 376/* 377%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 378% % 379% % 380% % 381+ G e t M a g i c k D e c o d e r T h r e a d S u p p o r t % 382% % 383% % 384% % 385%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 386% 387% GetMagickDecoderThreadSupport() returns MagickTrue if the decoder supports 388% threads. 389% 390% The format of the GetMagickDecoderThreadSupport method is: 391% 392% MagickStatusType GetMagickDecoderThreadSupport( 393% const MagickInfo *magick_info) 394% 395% A description of each parameter follows: 396% 397% o magick_info: The magick info. 398% 399*/ 400MagickExport MagickBooleanType GetMagickDecoderThreadSupport( 401 const MagickInfo *magick_info) 402{ 403 assert(magick_info != (MagickInfo *) NULL); 404 assert(magick_info->signature == MagickCoreSignature); 405 return(((magick_info->flags & CoderDecoderThreadSupportFlag) == 0) ? 406 MagickFalse : MagickTrue); 407} 408 409/* 410%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 411% % 412% % 413% % 414+ G e t M a g i c k D e s c r i p t i o n % 415% % 416% % 417% % 418%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 419% 420% GetMagickDescription() returns the magick description. 421% 422% The format of the GetMagickDescription method is: 423% 424% const char *GetMagickDescription(const MagickInfo *magick_info) 425% 426% A description of each parameter follows: 427% 428% o magick_info: The magick info. 429% 430*/ 431MagickExport const char *GetMagickDescription(const MagickInfo *magick_info) 432{ 433 assert(magick_info != (MagickInfo *) NULL); 434 assert(magick_info->signature == MagickCoreSignature); 435 return(magick_info->description); 436} 437 438/* 439%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 440% % 441% % 442% % 443+ G e t M a g i c k E n c o d e r T h r e a d S u p p o r t % 444% % 445% % 446% % 447%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 448% 449% GetMagickEncoderThreadSupport() returns MagickTrue if the encoder supports 450% threads. 451% 452% The format of the GetMagickEncoderThreadSupport method is: 453% 454% MagickStatusType GetMagickEncoderThreadSupport( 455% const MagickInfo *magick_info) 456% 457% A description of each parameter follows: 458% 459% o magick_info: The magick info. 460% 461*/ 462MagickExport MagickBooleanType GetMagickEncoderThreadSupport( 463 const MagickInfo *magick_info) 464{ 465 assert(magick_info != (MagickInfo *) NULL); 466 assert(magick_info->signature == MagickCoreSignature); 467 return(((magick_info->flags & CoderDecoderThreadSupportFlag) == 0) ? 468 MagickFalse : MagickTrue); 469} 470 471/* 472%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 473% % 474% % 475% % 476+ G e t M a g i c k E n d i a n S u p p o r t % 477% % 478% % 479% % 480%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 481% 482% GetMagickEndianSupport() returns the MagickTrue if the coder respects 483% endianness other than MSBEndian. 484% 485% The format of the GetMagickEndianSupport method is: 486% 487% MagickBooleanType GetMagickEndianSupport(const MagickInfo *magick_info) 488% 489% A description of each parameter follows: 490% 491% o magick_info: The magick info. 492% 493*/ 494MagickExport MagickBooleanType GetMagickEndianSupport( 495 const MagickInfo *magick_info) 496{ 497 assert(magick_info != (MagickInfo *) NULL); 498 assert(magick_info->signature == MagickCoreSignature); 499 return(((magick_info->flags & CoderEndianSupportFlag) == 0) ? MagickFalse : 500 MagickTrue); 501} 502 503/* 504%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 505% % 506% % 507% % 508+ G e t M a g i c k I n f o % 509% % 510% % 511% % 512%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 513% 514% GetMagickInfo() returns a pointer MagickInfo structure that matches 515% the specified name. If name is NULL, the head of the image format list 516% is returned. 517% 518% The format of the GetMagickInfo method is: 519% 520% const MagickInfo *GetMagickInfo(const char *name,Exception *exception) 521% 522% A description of each parameter follows: 523% 524% o name: the image format we are looking for. 525% 526% o exception: return any errors or warnings in this structure. 527% 528*/ 529MagickExport const MagickInfo *GetMagickInfo(const char *name, 530 ExceptionInfo *exception) 531{ 532 register const MagickInfo 533 *p; 534 535 assert(exception != (ExceptionInfo *) NULL); 536 if (IsMagickTreeInstantiated(exception) == MagickFalse) 537 return((const MagickInfo *) NULL); 538#if defined(MAGICKCORE_MODULES_SUPPORT) 539 if ((name != (const char *) NULL) && (LocaleCompare(name,"*") == 0)) 540 (void) OpenModules(exception); 541#endif 542 /* 543 Find name in list. 544 */ 545 LockSemaphoreInfo(magick_semaphore); 546 ResetSplayTreeIterator(magick_list); 547 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list); 548 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0)) 549 { 550 ResetSplayTreeIterator(magick_list); 551 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list); 552 UnlockSemaphoreInfo(magick_semaphore); 553 return(p); 554 } 555 while (p != (const MagickInfo *) NULL) 556 { 557 if (LocaleCompare(p->name,name) == 0) 558 break; 559 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list); 560 } 561#if defined(MAGICKCORE_MODULES_SUPPORT) 562 if (p == (const MagickInfo *) NULL) 563 { 564 if (*name != '\0') 565 (void) OpenModule(name,exception); 566 ResetSplayTreeIterator(magick_list); 567 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list); 568 while (p != (const MagickInfo *) NULL) 569 { 570 if (LocaleCompare(p->name,name) == 0) 571 break; 572 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list); 573 } 574 } 575#endif 576 UnlockSemaphoreInfo(magick_semaphore); 577 return(p); 578} 579 580/* 581%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 582% % 583% % 584% % 585+ G e t M a g i c k I n f o L i s t % 586% % 587% % 588% % 589%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 590% 591% GetMagickInfoList() returns any image formats that match the specified 592% pattern. 593% 594% The format of the GetMagickInfoList function is: 595% 596% const MagickInfo **GetMagickInfoList(const char *pattern, 597% size_t *number_formats,ExceptionInfo *exception) 598% 599% A description of each parameter follows: 600% 601% o pattern: Specifies a pointer to a text string containing a pattern. 602% 603% o number_formats: This integer returns the number of formats in the list. 604% 605% o exception: return any errors or warnings in this structure. 606% 607*/ 608 609#if defined(__cplusplus) || defined(c_plusplus) 610extern "C" { 611#endif 612 613static int MagickInfoCompare(const void *x,const void *y) 614{ 615 const MagickInfo 616 **p, 617 **q; 618 619 p=(const MagickInfo **) x, 620 q=(const MagickInfo **) y; 621 return(LocaleCompare((*p)->name,(*q)->name)); 622} 623 624#if defined(__cplusplus) || defined(c_plusplus) 625} 626#endif 627 628MagickExport const MagickInfo **GetMagickInfoList(const char *pattern, 629 size_t *number_formats,ExceptionInfo *exception) 630{ 631 const MagickInfo 632 **formats; 633 634 register const MagickInfo 635 *p; 636 637 register ssize_t 638 i; 639 640 /* 641 Allocate magick list. 642 */ 643 assert(pattern != (char *) NULL); 644 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern); 645 assert(number_formats != (size_t *) NULL); 646 *number_formats=0; 647 p=GetMagickInfo("*",exception); 648 if (p == (const MagickInfo *) NULL) 649 return((const MagickInfo **) NULL); 650 formats=(const MagickInfo **) AcquireQuantumMemory((size_t) 651 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats)); 652 if (formats == (const MagickInfo **) NULL) 653 return((const MagickInfo **) NULL); 654 /* 655 Generate magick list. 656 */ 657 LockSemaphoreInfo(magick_semaphore); 658 ResetSplayTreeIterator(magick_list); 659 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list); 660 for (i=0; p != (const MagickInfo *) NULL; ) 661 { 662 if ((GetMagickStealth(p) == MagickFalse) && 663 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse)) 664 formats[i++]=p; 665 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list); 666 } 667 UnlockSemaphoreInfo(magick_semaphore); 668 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickInfoCompare); 669 formats[i]=(MagickInfo *) NULL; 670 *number_formats=(size_t) i; 671 return(formats); 672} 673 674/* 675%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 676% % 677% % 678% % 679+ G e t M a g i c k L i s t % 680% % 681% % 682% % 683%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 684% 685% GetMagickList() returns any image formats that match the specified pattern. 686% 687% The format of the GetMagickList function is: 688% 689% char **GetMagickList(const char *pattern,size_t *number_formats, 690% ExceptionInfo *exception) 691% 692% A description of each parameter follows: 693% 694% o pattern: Specifies a pointer to a text string containing a pattern. 695% 696% o number_formats: This integer returns the number of formats in the list. 697% 698% o exception: return any errors or warnings in this structure. 699% 700*/ 701 702#if defined(__cplusplus) || defined(c_plusplus) 703extern "C" { 704#endif 705 706static int MagickCompare(const void *x,const void *y) 707{ 708 register const char 709 **p, 710 **q; 711 712 p=(const char **) x; 713 q=(const char **) y; 714 return(LocaleCompare(*p,*q)); 715} 716 717#if defined(__cplusplus) || defined(c_plusplus) 718} 719#endif 720 721MagickExport char **GetMagickList(const char *pattern, 722 size_t *number_formats,ExceptionInfo *exception) 723{ 724 char 725 **formats; 726 727 register const MagickInfo 728 *p; 729 730 register ssize_t 731 i; 732 733 /* 734 Allocate magick list. 735 */ 736 assert(pattern != (char *) NULL); 737 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern); 738 assert(number_formats != (size_t *) NULL); 739 *number_formats=0; 740 p=GetMagickInfo("*",exception); 741 if (p == (const MagickInfo *) NULL) 742 return((char **) NULL); 743 formats=(char **) AcquireQuantumMemory((size_t) 744 GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats)); 745 if (formats == (char **) NULL) 746 return((char **) NULL); 747 LockSemaphoreInfo(magick_semaphore); 748 ResetSplayTreeIterator(magick_list); 749 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list); 750 for (i=0; p != (const MagickInfo *) NULL; ) 751 { 752 if ((GetMagickStealth(p) == MagickFalse) && 753 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse)) 754 formats[i++]=ConstantString(p->name); 755 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list); 756 } 757 UnlockSemaphoreInfo(magick_semaphore); 758 qsort((void *) formats,(size_t) i,sizeof(*formats),MagickCompare); 759 formats[i]=(char *) NULL; 760 *number_formats=(size_t) i; 761 return(formats); 762} 763 764/* 765%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 766% % 767% % 768% % 769+ G e t M a g i c k M i m e T y p e % 770% % 771% % 772% % 773%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 774% 775% GetMagickMimeType() returns the magick mime type. 776% 777% The format of the GetMagickMimeType method is: 778% 779% const char *GetMagickMimeType(const MagickInfo *magick_info) 780% 781% A description of each parameter follows: 782% 783% o magick_info: The magick info. 784% 785*/ 786MagickExport const char *GetMagickMimeType(const MagickInfo *magick_info) 787{ 788 assert(magick_info != (MagickInfo *) NULL); 789 assert(magick_info->signature == MagickCoreSignature); 790 return(magick_info->mime_type); 791} 792 793/* 794%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 795% % 796% % 797% % 798% G e t M a g i c k P r e c i s i o n % 799% % 800% % 801% % 802%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 803% 804% GetMagickPrecision() returns the maximum number of significant digits to be 805% printed. 806% 807% The format of the GetMagickPrecision method is: 808% 809% int GetMagickPrecision(void) 810% 811*/ 812MagickExport int GetMagickPrecision(void) 813{ 814 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 815 return(SetMagickPrecision(0)); 816} 817 818/* 819%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 820% % 821% % 822% % 823+ G e t M a g i c k R a w S u p p o r t % 824% % 825% % 826% % 827%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 828% 829% GetMagickRawSupport() returns the MagickTrue if the coder is a raw format. 830% 831% The format of the GetMagickRawSupport method is: 832% 833% MagickBooleanType GetMagickRawSupport(const MagickInfo *magick_info) 834% 835% A description of each parameter follows: 836% 837% o magick_info: The magick info. 838% 839*/ 840MagickExport MagickBooleanType GetMagickRawSupport( 841 const MagickInfo *magick_info) 842{ 843 assert(magick_info != (MagickInfo *) NULL); 844 assert(magick_info->signature == MagickCoreSignature); 845 return(((magick_info->flags & CoderRawSupportFlag) == 0) ? MagickFalse : 846 MagickTrue); 847} 848 849/* 850%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 851% % 852% % 853% % 854+ G e t M a g i c k S e e k a b l e S t r e a m % 855% % 856% % 857% % 858%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 859% 860% GetMagickSeekableStream() returns MagickTrue if the magick supports a 861% seekable stream. 862% 863% The format of the GetMagickSeekableStream method is: 864% 865% MagickBooleanType GetMagickSeekableStream(const MagickInfo *magick_info) 866% 867% A description of each parameter follows: 868% 869% o magick_info: The magick info. 870% 871*/ 872MagickExport MagickBooleanType GetMagickSeekableStream( 873 const MagickInfo *magick_info) 874{ 875 assert(magick_info != (MagickInfo *) NULL); 876 assert(magick_info->signature == MagickCoreSignature); 877 return(((magick_info->flags & CoderSeekableStreamFlag) == 0) ? MagickFalse : 878 MagickTrue); 879} 880 881/* 882%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 883% % 884% % 885% % 886+ G e t M a g i c k S t e a l t h % 887% % 888% % 889% % 890%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 891% 892% GetMagickStealth() returns MagickTrue if the magick is a stealth coder. 893% 894% The format of the GetMagickStealth method is: 895% 896% MagickBooleanType GetMagickStealth(const MagickInfo *magick_info) 897% 898% A description of each parameter follows: 899% 900% o magick_info: The magick info. 901% 902*/ 903MagickExport MagickBooleanType GetMagickStealth(const MagickInfo *magick_info) 904{ 905 assert(magick_info != (MagickInfo *) NULL); 906 assert(magick_info->signature == MagickCoreSignature); 907 return(((magick_info->flags & CoderStealthFlag) == 0) ? MagickFalse : 908 MagickTrue); 909} 910 911/* 912%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 913% % 914% % 915% % 916+ G e t M a g i c k U s e E x t e n s i o n % 917% % 918% % 919% % 920%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 921% 922% GetMagickUseExtension() returns MagickTrue if the magick can use the 923% extension of the format if the format return by IsImageFormatHandler uses 924% the same coder. 925% 926% The format of the GetMagickUseExtension method is: 927% 928% MagickBooleanType GetMagickUseExtension(const MagickInfo *magick_info) 929% 930% A description of each parameter follows: 931% 932% o magick_info: The magick info. 933% 934*/ 935MagickExport MagickBooleanType GetMagickUseExtension( 936 const MagickInfo *magick_info) 937{ 938 assert(magick_info != (MagickInfo *) NULL); 939 assert(magick_info->signature == MagickCoreSignature); 940 return(((magick_info->flags & CoderUseExtensionFlag) == 0) ? MagickFalse : 941 MagickTrue); 942} 943 944/* 945%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 946% % 947% % 948% % 949+ I s M a g i c k T r e e I n s t a n t i a t e d % 950% % 951% % 952% % 953%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 954% 955% IsMagickTreeInstantiated() determines if the magick tree is instantiated. 956% If not, it instantiates the tree and returns it. 957% 958% The format of the IsMagickTreeInstantiated() method is: 959% 960% IsMagickTreeInstantiated(Exceptioninfo *exception) 961% 962% A description of each parameter follows. 963% 964% o exception: return any errors or warnings in this structure. 965% 966*/ 967 968static void *DestroyMagickNode(void *magick_info) 969{ 970 register MagickInfo 971 *p; 972 973 p=(MagickInfo *) magick_info; 974 if (p->module != (char *) NULL) 975 p->module=DestroyString(p->module); 976 if (p->note != (char *) NULL) 977 p->note=DestroyString(p->note); 978 if (p->mime_type != (char *) NULL) 979 p->mime_type=DestroyString(p->mime_type); 980 if (p->version != (char *) NULL) 981 p->version=DestroyString(p->version); 982 if (p->description != (char *) NULL) 983 p->description=DestroyString(p->description); 984 if (p->name != (char *) NULL) 985 p->name=DestroyString(p->name); 986 if (p->semaphore != (SemaphoreInfo *) NULL) 987 RelinquishSemaphoreInfo(&p->semaphore); 988 return(RelinquishMagickMemory(p)); 989} 990 991static MagickBooleanType IsMagickTreeInstantiated(ExceptionInfo *exception) 992{ 993 (void) exception; 994 if (magick_list == (SplayTreeInfo *) NULL) 995 { 996 if (magick_semaphore == (SemaphoreInfo *) NULL) 997 ActivateSemaphoreInfo(&magick_semaphore); 998 LockSemaphoreInfo(magick_semaphore); 999 if (magick_list == (SplayTreeInfo *) NULL) 1000 { 1001 magick_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) 1002 NULL,DestroyMagickNode); 1003 if (magick_list == (SplayTreeInfo *) NULL) 1004 ThrowFatalException(ResourceLimitFatalError, 1005 "MemoryAllocationFailed"); 1006#if defined(MAGICKCORE_MODULES_SUPPORT) 1007 (void) GetModuleInfo((char *) NULL,exception); 1008#endif 1009#if !defined(MAGICKCORE_BUILD_MODULES) 1010 RegisterStaticModules(); 1011#endif 1012 } 1013 UnlockSemaphoreInfo(magick_semaphore); 1014 } 1015 return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse); 1016} 1017 1018/* 1019%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1020% % 1021% % 1022% % 1023+ I s M a g i c k C o n f l i c t % 1024% % 1025% % 1026% % 1027%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1028% 1029% IsMagickConflict() returns MagickTrue if the image format conflicts with a 1030% logical drive (.e.g. X:). 1031% 1032% The format of the IsMagickConflict method is: 1033% 1034% MagickBooleanType IsMagickConflict(const char *magick) 1035% 1036% A description of each parameter follows: 1037% 1038% o magick: Specifies the image format. 1039% 1040*/ 1041MagickPrivate MagickBooleanType IsMagickConflict(const char *magick) 1042{ 1043 assert(magick != (char *) NULL); 1044#if defined(macintosh) 1045 return(MACIsMagickConflict(magick)); 1046#elif defined(vms) 1047 return(VMSIsMagickConflict(magick)); 1048#elif defined(MAGICKCORE_WINDOWS_SUPPORT) 1049 return(NTIsMagickConflict(magick)); 1050#else 1051 return(MagickFalse); 1052#endif 1053} 1054 1055/* 1056%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1057% % 1058% % 1059% % 1060+ L i s t M a g i c k I n f o % 1061% % 1062% % 1063% % 1064%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1065% 1066% ListMagickInfo() lists the image formats to a file. 1067% 1068% The format of the ListMagickInfo method is: 1069% 1070% MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception) 1071% 1072% A description of each parameter follows. 1073% 1074% o file: A file handle. 1075% 1076% o exception: return any errors or warnings in this structure. 1077% 1078*/ 1079MagickExport MagickBooleanType ListMagickInfo(FILE *file, 1080 ExceptionInfo *exception) 1081{ 1082 const MagickInfo 1083 **magick_info; 1084 1085 register ssize_t 1086 i; 1087 1088 size_t 1089 number_formats; 1090 1091 ssize_t 1092 j; 1093 1094 if (file == (FILE *) NULL) 1095 file=stdout; 1096 magick_info=GetMagickInfoList("*",&number_formats,exception); 1097 if (magick_info == (const MagickInfo **) NULL) 1098 return(MagickFalse); 1099 ClearMagickException(exception); 1100#if !defined(MAGICKCORE_MODULES_SUPPORT) 1101 (void) FormatLocaleFile(file," Format Mode Description\n"); 1102#else 1103 (void) FormatLocaleFile(file," Format Module Mode Description\n"); 1104#endif 1105 (void) FormatLocaleFile(file, 1106 "--------------------------------------------------------" 1107 "-----------------------\n"); 1108 for (i=0; i < (ssize_t) number_formats; i++) 1109 { 1110 if (GetMagickStealth(magick_info[i]) != MagickFalse) 1111 continue; 1112 (void) FormatLocaleFile(file,"%9s%c ", 1113 magick_info[i]->name != (char *) NULL ? magick_info[i]->name : "", 1114 GetMagickBlobSupport(magick_info[i]) != MagickFalse ? '*' : ' '); 1115#if defined(MAGICKCORE_MODULES_SUPPORT) 1116 { 1117 char 1118 module[MagickPathExtent]; 1119 1120 *module='\0'; 1121 if (magick_info[i]->module != (char *) NULL) 1122 (void) CopyMagickString(module,magick_info[i]->module,MagickPathExtent); 1123 (void) ConcatenateMagickString(module," ",MagickPathExtent); 1124 module[9]='\0'; 1125 (void) FormatLocaleFile(file,"%9s ",module); 1126 } 1127#endif 1128 (void) FormatLocaleFile(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-', 1129 magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL && 1130 GetMagickAdjoin(magick_info[i]) != MagickFalse ? '+' : '-'); 1131 if (magick_info[i]->description != (char *) NULL) 1132 (void) FormatLocaleFile(file," %s",magick_info[i]->description); 1133 if (magick_info[i]->version != (char *) NULL) 1134 (void) FormatLocaleFile(file," (%s)",magick_info[i]->version); 1135 (void) FormatLocaleFile(file,"\n"); 1136 if (magick_info[i]->note != (char *) NULL) 1137 { 1138 char 1139 **text; 1140 1141 text=StringToList(magick_info[i]->note); 1142 if (text != (char **) NULL) 1143 { 1144 for (j=0; text[j] != (char *) NULL; j++) 1145 { 1146 (void) FormatLocaleFile(file," %s\n",text[j]); 1147 text[j]=DestroyString(text[j]); 1148 } 1149 text=(char **) RelinquishMagickMemory(text); 1150 } 1151 } 1152 } 1153 (void) FormatLocaleFile(file,"\n* native blob support\n"); 1154 (void) FormatLocaleFile(file,"r read support\n"); 1155 (void) FormatLocaleFile(file,"w write support\n"); 1156 (void) FormatLocaleFile(file,"+ support for multiple images\n"); 1157 (void) fflush(file); 1158 magick_info=(const MagickInfo **) RelinquishMagickMemory((void *) 1159 magick_info); 1160 return(MagickTrue); 1161} 1162 1163/* 1164%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1165% % 1166% % 1167% % 1168% I s M a g i c k C o r e I n s t a n t i a t e d % 1169% % 1170% % 1171% % 1172%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1173% 1174% IsMagickCoreInstantiated() returns MagickTrue if the ImageMagick environment 1175% is currently instantiated: MagickCoreGenesis() has been called but 1176% MagickDestroy() has not. 1177% 1178% The format of the IsMagickCoreInstantiated method is: 1179% 1180% MagickBooleanType IsMagickCoreInstantiated(void) 1181% 1182*/ 1183MagickExport MagickBooleanType IsMagickCoreInstantiated(void) 1184{ 1185 return(instantiate_magickcore); 1186} 1187 1188/* 1189%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1190% % 1191% % 1192% % 1193+ M a g i c k C o m p o n e n t G e n e s i s % 1194% % 1195% % 1196% % 1197%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1198% 1199% MagickComponentGenesis() instantiates the magick component. 1200% 1201% The format of the MagickComponentGenesis method is: 1202% 1203% MagickBooleanType MagickComponentGenesis(void) 1204% 1205*/ 1206MagickPrivate MagickBooleanType MagickComponentGenesis(void) 1207{ 1208 if (magick_semaphore == (SemaphoreInfo *) NULL) 1209 magick_semaphore=AcquireSemaphoreInfo(); 1210 return(MagickTrue); 1211} 1212 1213/* 1214%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1215% % 1216% % 1217% % 1218+ M a g i c k C o m p o n e n t T e r m i n u s % 1219% % 1220% % 1221% % 1222%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1223% 1224% MagickComponentTerminus() destroys the magick component. 1225% 1226% The format of the MagickComponentTerminus method is: 1227% 1228% void MagickComponentTerminus(void) 1229% 1230*/ 1231MagickPrivate void MagickComponentTerminus(void) 1232{ 1233 if (magick_semaphore == (SemaphoreInfo *) NULL) 1234 ActivateSemaphoreInfo(&magick_semaphore); 1235 LockSemaphoreInfo(magick_semaphore); 1236 if (magick_list != (SplayTreeInfo *) NULL) 1237 magick_list=DestroySplayTree(magick_list); 1238 UnlockSemaphoreInfo(magick_semaphore); 1239 RelinquishSemaphoreInfo(&magick_semaphore); 1240} 1241 1242/* 1243%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1244% % 1245% % 1246% % 1247% M a g i c k C o r e G e n e s i s % 1248% % 1249% % 1250% % 1251%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1252% 1253% MagickCoreGenesis() initializes the MagickCore environment. 1254% 1255% The format of the MagickCoreGenesis function is: 1256% 1257% MagickCoreGenesis(const char *path, 1258% const MagickBooleanType establish_signal_handlers) 1259% 1260% A description of each parameter follows: 1261% 1262% o path: the execution path of the current ImageMagick client. 1263% 1264% o establish_signal_handlers: set to MagickTrue to use MagickCore's own 1265% signal handlers for common signals. 1266% 1267*/ 1268 1269static SignalHandler *SetMagickSignalHandler(int signal_number, 1270 SignalHandler *handler) 1271{ 1272#if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET) 1273 int 1274 status; 1275 1276 sigset_t 1277 mask; 1278 1279 struct sigaction 1280 action, 1281 previous_action; 1282 1283 sigemptyset(&mask); 1284 sigaddset(&mask,signal_number); 1285 sigprocmask(SIG_BLOCK,&mask,NULL); 1286 action.sa_mask=mask; 1287 action.sa_handler=handler; 1288 action.sa_flags=0; 1289#if defined(SA_INTERRUPT) 1290 action.sa_flags|=SA_INTERRUPT; 1291#endif 1292 status=sigaction(signal_number,&action,&previous_action); 1293 if (status < 0) 1294 return(SIG_ERR); 1295 sigprocmask(SIG_UNBLOCK,&mask,NULL); 1296 return(previous_action.sa_handler); 1297#else 1298 return(signal(signal_number,handler)); 1299#endif 1300} 1301 1302static void MagickSignalHandler(int signal_number) 1303{ 1304 if (magickcore_signal_in_progress != MagickFalse) 1305 (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]); 1306 magickcore_signal_in_progress=MagickTrue; 1307 AsynchronousResourceComponentTerminus(); 1308#if defined(SIGQUIT) 1309 if (signal_number == SIGQUIT) 1310 abort(); 1311#endif 1312#if defined(SIGABRT) 1313 if (signal_number == SIGABRT) 1314 abort(); 1315#endif 1316#if defined(SIGFPE) 1317 if (signal_number == SIGFPE) 1318 abort(); 1319#endif 1320#if defined(SIGXCPU) 1321 if (signal_number == SIGXCPU) 1322 abort(); 1323#endif 1324#if defined(SIGXFSZ) 1325 if (signal_number == SIGXFSZ) 1326 abort(); 1327#endif 1328#if defined(SIGSEGV) 1329 if (signal_number == SIGSEGV) 1330 abort(); 1331#endif 1332#if !defined(MAGICKCORE_HAVE__EXIT) 1333 exit(signal_number); 1334#else 1335#if defined(SIGHUP) 1336 if (signal_number == SIGHUP) 1337 _exit(signal_number); 1338#endif 1339#if defined(SIGINT) 1340 if (signal_number == SIGINT) 1341 _exit(signal_number); 1342#endif 1343#if defined(SIGTERM) 1344 if (signal_number == SIGTERM) 1345 _exit(signal_number); 1346#endif 1347#if defined(MAGICKCORE_HAVE_RAISE) 1348 if (signal_handlers[signal_number] != MagickSignalHandler) 1349 raise(signal_number); 1350#endif 1351 _exit(signal_number); /* do not invoke registered atexit() methods */ 1352#endif 1353} 1354 1355static SignalHandler *RegisterMagickSignalHandler(int signal_number) 1356{ 1357 SignalHandler 1358 *handler; 1359 1360 handler=SetMagickSignalHandler(signal_number,MagickSignalHandler); 1361 if (handler == SIG_ERR) 1362 return(handler); 1363 if (handler != SIG_DFL) 1364 handler=SetMagickSignalHandler(signal_number,handler); 1365 else 1366 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), 1367 "Register handler for signal: %d",signal_number); 1368 return(handler); 1369} 1370 1371MagickExport void MagickCoreGenesis(const char *path, 1372 const MagickBooleanType establish_signal_handlers) 1373{ 1374 char 1375 *events, 1376 execution_path[MagickPathExtent], 1377 filename[MagickPathExtent]; 1378 1379 /* 1380 Initialize the Magick environment. 1381 */ 1382 InitializeMagickMutex(); 1383 LockMagickMutex(); 1384 if (instantiate_magickcore != MagickFalse) 1385 { 1386 UnlockMagickMutex(); 1387 return; 1388 } 1389 (void) SemaphoreComponentGenesis(); 1390 (void) LogComponentGenesis(); 1391 (void) LocaleComponentGenesis(); 1392 (void) RandomComponentGenesis(); 1393 events=GetEnvironmentValue("MAGICK_DEBUG"); 1394 if (events != (char *) NULL) 1395 { 1396 (void) SetLogEventMask(events); 1397 events=DestroyString(events); 1398 } 1399#if defined(MAGICKCORE_WINDOWS_SUPPORT) 1400 NTWindowsGenesis(); 1401#endif 1402 /* 1403 Set client name and execution path. 1404 */ 1405#if defined(MAGICKCORE_WINDOWS_SUPPORT) 1406 if ((path != (const char *) NULL) && (IsPathAccessible(path) != MagickFalse)) 1407#else 1408 if ((path != (const char *) NULL) && (*path == *DirectorySeparator) && 1409 (IsPathAccessible(path) != MagickFalse)) 1410#endif 1411 (void) CopyMagickString(execution_path,path,MagickPathExtent); 1412 else 1413 (void) GetExecutionPath(execution_path,MagickPathExtent); 1414 GetPathComponent(execution_path,TailPath,filename); 1415 (void) SetClientName(filename); 1416 GetPathComponent(execution_path,HeadPath,execution_path); 1417 (void) SetClientPath(execution_path); 1418 if (establish_signal_handlers != MagickFalse) 1419 { 1420 /* 1421 Set signal handlers. 1422 */ 1423#if defined(SIGABRT) 1424 if (signal_handlers[SIGABRT] == (SignalHandler *) NULL) 1425 signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT); 1426#endif 1427#if defined(SIGSEGV) 1428 if (signal_handlers[SIGSEGV] == (SignalHandler *) NULL) 1429 signal_handlers[SIGSEGV]=RegisterMagickSignalHandler(SIGSEGV); 1430#endif 1431#if defined(SIGFPE) 1432 if (signal_handlers[SIGFPE] == (SignalHandler *) NULL) 1433 signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE); 1434#endif 1435#if defined(SIGHUP) 1436 if (signal_handlers[SIGHUP] == (SignalHandler *) NULL) 1437 signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP); 1438#endif 1439#if defined(SIGINT) 1440 if (signal_handlers[SIGINT] == (SignalHandler *) NULL) 1441 signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT); 1442#endif 1443#if defined(SIGQUIT) 1444 if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL) 1445 signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT); 1446#endif 1447#if defined(SIGTERM) 1448 if (signal_handlers[SIGTERM] == (SignalHandler *) NULL) 1449 signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM); 1450#endif 1451#if defined(SIGXCPU) 1452 if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL) 1453 signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU); 1454#endif 1455#if defined(SIGXFSZ) 1456 if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL) 1457 signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ); 1458#endif 1459 } 1460 /* 1461 Instantiate magick resources. 1462 */ 1463 (void) ConfigureComponentGenesis(); 1464 (void) PolicyComponentGenesis(); 1465 (void) CacheComponentGenesis(); 1466 (void) ResourceComponentGenesis(); 1467 (void) CoderComponentGenesis(); 1468 (void) MagickComponentGenesis(); 1469#if defined(MAGICKCORE_MODULES_SUPPORT) 1470 (void) ModuleComponentGenesis(); 1471#endif 1472 (void) DelegateComponentGenesis(); 1473 (void) MagicComponentGenesis(); 1474 (void) ColorComponentGenesis(); 1475 (void) TypeComponentGenesis(); 1476 (void) MimeComponentGenesis(); 1477 (void) AnnotateComponentGenesis(); 1478#if defined(MAGICKCORE_X11_DELEGATE) 1479 (void) XComponentGenesis(); 1480#endif 1481 (void) RegistryComponentGenesis(); 1482 instantiate_magickcore=MagickTrue; 1483 UnlockMagickMutex(); 1484} 1485 1486/* 1487%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1488% % 1489% % 1490% % 1491% M a g i c k C o r e T e r m i n u s % 1492% % 1493% % 1494% % 1495%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1496% 1497% MagickCoreTerminus() destroys the MagickCore environment. 1498% 1499% The format of the MagickCoreTerminus function is: 1500% 1501% MagickCoreTerminus(void) 1502% 1503*/ 1504MagickExport void MagickCoreTerminus(void) 1505{ 1506 InitializeMagickMutex(); 1507 LockMagickMutex(); 1508 if (instantiate_magickcore == MagickFalse) 1509 { 1510 UnlockMagickMutex(); 1511 return; 1512 } 1513 RegistryComponentTerminus(); 1514#if defined(MAGICKCORE_X11_DELEGATE) 1515 XComponentTerminus(); 1516#endif 1517 AnnotateComponentTerminus(); 1518 MimeComponentTerminus(); 1519 TypeComponentTerminus(); 1520#if defined(MAGICKCORE_OPENCL_SUPPORT) 1521 OpenCLTerminus(); 1522#endif 1523 ColorComponentTerminus(); 1524#if defined(MAGICKCORE_WINDOWS_SUPPORT) 1525 NTWindowsTerminus(); 1526#endif 1527 MagicComponentTerminus(); 1528 DelegateComponentTerminus(); 1529 MagickComponentTerminus(); 1530#if !defined(MAGICKCORE_BUILD_MODULES) 1531 UnregisterStaticModules(); 1532#endif 1533#if defined(MAGICKCORE_MODULES_SUPPORT) 1534 ModuleComponentTerminus(); 1535#endif 1536 CoderComponentTerminus(); 1537 ResourceComponentTerminus(); 1538 CacheComponentTerminus(); 1539 PolicyComponentTerminus(); 1540 ConfigureComponentTerminus(); 1541 RandomComponentTerminus(); 1542 LocaleComponentTerminus(); 1543 LogComponentTerminus(); 1544 instantiate_magickcore=MagickFalse; 1545 UnlockMagickMutex(); 1546 SemaphoreComponentTerminus(); 1547} 1548 1549/* 1550%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1551% % 1552% % 1553% % 1554+ R e g i s t e r M a g i c k I n f o % 1555% % 1556% % 1557% % 1558%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1559% 1560% RegisterMagickInfo() adds attributes for a particular image format to the 1561% list of supported formats. The attributes include the image format name, 1562% a method to read and/or write the format, whether the format supports the 1563% saving of more than one frame to the same file or blob, whether the format 1564% supports native in-memory I/O, and a brief description of the format. 1565% 1566% The format of the RegisterMagickInfo method is: 1567% 1568% MagickInfo *RegisterMagickInfo(MagickInfo *magick_info) 1569% 1570% A description of each parameter follows: 1571% 1572% o magick_info: the magick info. 1573% 1574*/ 1575MagickExport MagickBooleanType RegisterMagickInfo(MagickInfo *magick_info) 1576{ 1577 MagickBooleanType 1578 status; 1579 1580 /* 1581 Register a new image format. 1582 */ 1583 assert(magick_info != (MagickInfo *) NULL); 1584 assert(magick_info->signature == MagickCoreSignature); 1585 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name); 1586 if (magick_list == (SplayTreeInfo *) NULL) 1587 return(MagickFalse); 1588 if ((GetMagickDecoderThreadSupport(magick_info) == MagickFalse) || 1589 (GetMagickEncoderThreadSupport(magick_info) == MagickFalse)) 1590 magick_info->semaphore=AcquireSemaphoreInfo(); 1591 status=AddValueToSplayTree(magick_list,magick_info->name,magick_info); 1592 return(status); 1593} 1594 1595/* 1596%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1597% % 1598% % 1599% % 1600% S e t M a g i c k P r e c i s i o n % 1601% % 1602% % 1603% % 1604%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1605% 1606% SetMagickPrecision() sets the maximum number of significant digits to be 1607% printed. 1608% 1609% An input argument of 0 returns the current precision setting. 1610% 1611% A negative value forces the precision to reset to a default value according 1612% to the environment variable "MAGICK_PRECISION", the current 'policy' 1613% configuration setting, or the default value of '6', in that order. 1614% 1615% The format of the SetMagickPrecision method is: 1616% 1617% int SetMagickPrecision(const int precision) 1618% 1619% A description of each parameter follows: 1620% 1621% o precision: set the maximum number of significant digits to be printed. 1622% 1623*/ 1624MagickExport int SetMagickPrecision(const int precision) 1625{ 1626#define MagickPrecision 6 1627 1628 static int 1629 magick_precision = 0; 1630 1631 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1632 if (precision > 0) 1633 magick_precision=precision; 1634 if ((precision < 0) || (magick_precision == 0)) 1635 { 1636 char 1637 *limit; 1638 1639 /* 1640 Precision reset, or it has not been set yet 1641 */ 1642 magick_precision=MagickPrecision; 1643 limit=GetEnvironmentValue("MAGICK_PRECISION"); 1644 if (limit == (char *) NULL) 1645 limit=GetPolicyValue("precision"); 1646 if (limit != (char *) NULL) 1647 { 1648 magick_precision=StringToInteger(limit); 1649 limit=DestroyString(limit); 1650 } 1651 } 1652 return(magick_precision); 1653} 1654 1655/* 1656%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1657% % 1658% % 1659% % 1660+ U n r e g i s t e r M a g i c k I n f o % 1661% % 1662% % 1663% % 1664%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1665% 1666% UnregisterMagickInfo() removes a name from the magick info list. It returns 1667% MagickFalse if the name does not exist in the list otherwise MagickTrue. 1668% 1669% The format of the UnregisterMagickInfo method is: 1670% 1671% MagickBooleanType UnregisterMagickInfo(const char *name) 1672% 1673% A description of each parameter follows: 1674% 1675% o name: a character string that represents the image format we are 1676% looking for. 1677% 1678*/ 1679MagickExport MagickBooleanType UnregisterMagickInfo(const char *name) 1680{ 1681 register const MagickInfo 1682 *p; 1683 1684 MagickBooleanType 1685 status; 1686 1687 assert(name != (const char *) NULL); 1688 if (magick_list == (SplayTreeInfo *) NULL) 1689 return(MagickFalse); 1690 if (GetNumberOfNodesInSplayTree(magick_list) == 0) 1691 return(MagickFalse); 1692 LockSemaphoreInfo(magick_semaphore); 1693 ResetSplayTreeIterator(magick_list); 1694 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list); 1695 while (p != (const MagickInfo *) NULL) 1696 { 1697 if (LocaleCompare(p->name,name) == 0) 1698 break; 1699 p=(const MagickInfo *) GetNextValueInSplayTree(magick_list); 1700 } 1701 status=DeleteNodeByValueFromSplayTree(magick_list,p); 1702 UnlockSemaphoreInfo(magick_semaphore); 1703 return(status); 1704} 1705