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