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