1 /* 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % % 4 % % 5 % % 6 % QQQ U U AAA N N TTTTT U U M M % 7 % Q Q U U A A NN N T U U MM MM % 8 % Q Q U U AAAAA N N N T U U M M M % 9 % Q QQ U U A A N NN T U U M M % 10 % QQQQ UUU A A N N T UUU M M % 11 % % 12 % MagicCore Methods to Acquire / Destroy Quantum Pixels % 13 % % 14 % Software Design % 15 % Cristy % 16 % October 1998 % 17 % % 18 % % 19 % Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization % 20 % dedicated to making software imaging solutions freely available. % 21 % % 22 % You may not use this file except in compliance with the License. You may % 23 % obtain a copy of the License at % 24 % % 25 % https://imagemagick.org/script/license.php % 26 % % 27 % Unless required by applicable law or agreed to in writing, software % 28 % distributed under the License is distributed on an "AS IS" BASIS, % 29 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 30 % See the License for the specific language governing permissions and % 31 % limitations under the License. % 32 % % 33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 34 % 35 % 36 */ 37 38 /* 40 Include declarations. 41 */ 42 #include "MagickCore/studio.h" 43 #include "MagickCore/attribute.h" 44 #include "MagickCore/blob.h" 45 #include "MagickCore/blob-private.h" 46 #include "MagickCore/color-private.h" 47 #include "MagickCore/exception.h" 48 #include "MagickCore/exception-private.h" 49 #include "MagickCore/cache.h" 50 #include "MagickCore/cache-private.h" 51 #include "MagickCore/colorspace.h" 52 #include "MagickCore/colorspace-private.h" 53 #include "MagickCore/constitute.h" 54 #include "MagickCore/delegate.h" 55 #include "MagickCore/geometry.h" 56 #include "MagickCore/list.h" 57 #include "MagickCore/magick.h" 58 #include "MagickCore/memory_.h" 59 #include "MagickCore/memory-private.h" 60 #include "MagickCore/monitor.h" 61 #include "MagickCore/option.h" 62 #include "MagickCore/pixel.h" 63 #include "MagickCore/pixel-accessor.h" 64 #include "MagickCore/property.h" 65 #include "MagickCore/quantum.h" 66 #include "MagickCore/quantum-private.h" 67 #include "MagickCore/resource_.h" 68 #include "MagickCore/semaphore.h" 69 #include "MagickCore/statistic.h" 70 #include "MagickCore/stream.h" 71 #include "MagickCore/string_.h" 72 #include "MagickCore/string-private.h" 73 #include "MagickCore/thread-private.h" 74 #include "MagickCore/utility.h" 75 76 /* 78 Define declarations. 79 */ 80 #define QuantumSignature 0xab 81 82 /* 84 Forward declarations. 85 */ 86 static void 87 DestroyQuantumPixels(QuantumInfo *); 88 89 /* 91 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 92 % % 93 % % 94 % % 95 % A c q u i r e Q u a n t u m I n f o % 96 % % 97 % % 98 % % 99 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 100 % 101 % AcquireQuantumInfo() allocates the QuantumInfo structure. 102 % 103 % The format of the AcquireQuantumInfo method is: 104 % 105 % QuantumInfo *AcquireQuantumInfo(const ImageInfo *image_info,Image *image) 106 % 107 % A description of each parameter follows: 108 % 109 % o image_info: the image info. 110 % 111 % o image: the image. 112 % 113 */ 114 MagickExport QuantumInfo *AcquireQuantumInfo(const ImageInfo *image_info, 115 Image *image) 116 { 117 MagickBooleanType 118 status; 119 120 QuantumInfo 121 *quantum_info; 122 123 quantum_info=(QuantumInfo *) AcquireCriticalMemory(sizeof(*quantum_info)); 124 quantum_info->signature=MagickCoreSignature; 125 GetQuantumInfo(image_info,quantum_info); 126 if (image == (const Image *) NULL) 127 return(quantum_info); 128 status=SetQuantumDepth(image,quantum_info,image->depth); 129 quantum_info->endian=image->endian; 130 if (status == MagickFalse) 131 quantum_info=DestroyQuantumInfo(quantum_info); 132 return(quantum_info); 133 } 134 135 /* 137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 138 % % 139 % % 140 % % 141 + A c q u i r e Q u a n t u m P i x e l s % 142 % % 143 % % 144 % % 145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 146 % 147 % AcquireQuantumPixels() allocates the pixel staging areas. 148 % 149 % The format of the AcquireQuantumPixels method is: 150 % 151 % MagickBooleanType AcquireQuantumPixels(QuantumInfo *quantum_info, 152 % const size_t extent) 153 % 154 % A description of each parameter follows: 155 % 156 % o quantum_info: the quantum info. 157 % 158 % o extent: the quantum info. 159 % 160 */ 161 static MagickBooleanType AcquireQuantumPixels(QuantumInfo *quantum_info, 162 const size_t extent) 163 { 164 register ssize_t 165 i; 166 167 assert(quantum_info != (QuantumInfo *) NULL); 168 assert(quantum_info->signature == MagickCoreSignature); 169 quantum_info->number_threads=(size_t) GetMagickResourceLimit(ThreadResource); 170 quantum_info->pixels=(MemoryInfo **) AcquireQuantumMemory( 171 quantum_info->number_threads,sizeof(*quantum_info->pixels)); 172 if (quantum_info->pixels == (MemoryInfo **) NULL) 173 return(MagickFalse); 174 quantum_info->extent=extent; 175 (void) memset(quantum_info->pixels,0,quantum_info->number_threads* 176 sizeof(*quantum_info->pixels)); 177 for (i=0; i < (ssize_t) quantum_info->number_threads; i++) 178 { 179 unsigned char 180 *pixels; 181 182 quantum_info->pixels[i]=AcquireVirtualMemory((extent+1),sizeof(*pixels)); 183 if (quantum_info->pixels[i] == (MemoryInfo *) NULL) 184 { 185 DestroyQuantumPixels(quantum_info); 186 return(MagickFalse); 187 } 188 pixels=(unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[i]); 189 (void) memset(pixels,0,(extent+1)*sizeof(*pixels)); 190 pixels[extent]=QuantumSignature; 191 } 192 return(MagickTrue); 193 } 194 195 /* 197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 198 % % 199 % % 200 % % 201 % D e s t r o y Q u a n t u m I n f o % 202 % % 203 % % 204 % % 205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 206 % 207 % DestroyQuantumInfo() deallocates memory associated with the QuantumInfo 208 % structure. 209 % 210 % The format of the DestroyQuantumInfo method is: 211 % 212 % QuantumInfo *DestroyQuantumInfo(QuantumInfo *quantum_info) 213 % 214 % A description of each parameter follows: 215 % 216 % o quantum_info: the quantum info. 217 % 218 */ 219 MagickExport QuantumInfo *DestroyQuantumInfo(QuantumInfo *quantum_info) 220 { 221 assert(quantum_info != (QuantumInfo *) NULL); 222 assert(quantum_info->signature == MagickCoreSignature); 223 if (quantum_info->pixels != (MemoryInfo **) NULL) 224 DestroyQuantumPixels(quantum_info); 225 if (quantum_info->semaphore != (SemaphoreInfo *) NULL) 226 RelinquishSemaphoreInfo(&quantum_info->semaphore); 227 quantum_info->signature=(~MagickCoreSignature); 228 quantum_info=(QuantumInfo *) RelinquishMagickMemory(quantum_info); 229 return(quantum_info); 230 } 231 232 /* 234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 235 % % 236 % % 237 % % 238 + D e s t r o y Q u a n t u m P i x e l s % 239 % % 240 % % 241 % % 242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 243 % 244 % DestroyQuantumPixels() destroys the quantum pixels. 245 % 246 % The format of the DestroyQuantumPixels() method is: 247 % 248 % void DestroyQuantumPixels(QuantumInfo *quantum_info) 249 % 250 % A description of each parameter follows: 251 % 252 % o quantum_info: the quantum info. 253 % 254 */ 255 static void DestroyQuantumPixels(QuantumInfo *quantum_info) 256 { 257 register ssize_t 258 i; 259 260 ssize_t 261 extent; 262 263 assert(quantum_info != (QuantumInfo *) NULL); 264 assert(quantum_info->signature == MagickCoreSignature); 265 assert(quantum_info->pixels != (MemoryInfo **) NULL); 266 extent=(ssize_t) quantum_info->extent; 267 for (i=0; i < (ssize_t) quantum_info->number_threads; i++) 268 if (quantum_info->pixels[i] != (MemoryInfo *) NULL) 269 { 270 unsigned char 271 *pixels; 272 273 /* 274 Did we overrun our quantum buffer? 275 */ 276 pixels=(unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[i]); 277 assert(pixels[extent] == QuantumSignature); 278 quantum_info->pixels[i]=RelinquishVirtualMemory( 279 quantum_info->pixels[i]); 280 } 281 quantum_info->pixels=(MemoryInfo **) RelinquishMagickMemory( 282 quantum_info->pixels); 283 } 284 285 /* 287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 288 % % 289 % % 290 % % 291 % G e t Q u a n t u m E x t e n t % 292 % % 293 % % 294 % % 295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 296 % 297 % GetQuantumExtent() returns the quantum pixel buffer extent. 298 % 299 % The format of the GetQuantumExtent method is: 300 % 301 % size_t GetQuantumExtent(Image *image,const QuantumInfo *quantum_info, 302 % const QuantumType quantum_type) 303 % 304 % A description of each parameter follows: 305 % 306 % o image: the image. 307 % 308 % o quantum_info: the quantum info. 309 % 310 % o quantum_type: Declare which pixel components to transfer (red, green, 311 % blue, opacity, RGB, or RGBA). 312 % 313 */ 314 MagickExport size_t GetQuantumExtent(const Image *image, 315 const QuantumInfo *quantum_info,const QuantumType quantum_type) 316 { 317 size_t 318 packet_size; 319 320 assert(quantum_info != (QuantumInfo *) NULL); 321 assert(quantum_info->signature == MagickCoreSignature); 322 packet_size=1; 323 switch (quantum_type) 324 { 325 case GrayAlphaQuantum: packet_size=2; break; 326 case IndexAlphaQuantum: packet_size=2; break; 327 case RGBQuantum: packet_size=3; break; 328 case BGRQuantum: packet_size=3; break; 329 case RGBAQuantum: packet_size=4; break; 330 case RGBOQuantum: packet_size=4; break; 331 case BGRAQuantum: packet_size=4; break; 332 case CMYKQuantum: packet_size=4; break; 333 case CMYKAQuantum: packet_size=5; break; 334 case CbYCrAQuantum: packet_size=4; break; 335 case CbYCrQuantum: packet_size=3; break; 336 case CbYCrYQuantum: packet_size=4; break; 337 default: break; 338 } 339 if (quantum_info->pack == MagickFalse) 340 return((size_t) (packet_size*image->columns*((quantum_info->depth+7)/8))); 341 return((size_t) ((packet_size*image->columns*quantum_info->depth+7)/8)); 342 } 343 344 /* 346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 347 % % 348 % % 349 % % 350 % G e t Q u a n t u m E n d i a n % 351 % % 352 % % 353 % % 354 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 355 % 356 % GetQuantumEndian() returns the quantum endian of the image. 357 % 358 % The endian of the GetQuantumEndian method is: 359 % 360 % EndianType GetQuantumEndian(const QuantumInfo *quantum_info) 361 % 362 % A description of each parameter follows: 363 % 364 % o quantum_info: the quantum info. 365 % 366 */ 367 MagickExport EndianType GetQuantumEndian(const QuantumInfo *quantum_info) 368 { 369 assert(quantum_info != (QuantumInfo *) NULL); 370 assert(quantum_info->signature == MagickCoreSignature); 371 return(quantum_info->endian); 372 } 373 374 /* 376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 377 % % 378 % % 379 % % 380 % G e t Q u a n t u m F o r m a t % 381 % % 382 % % 383 % % 384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 385 % 386 % GetQuantumFormat() returns the quantum format of the image. 387 % 388 % The format of the GetQuantumFormat method is: 389 % 390 % QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info) 391 % 392 % A description of each parameter follows: 393 % 394 % o quantum_info: the quantum info. 395 % 396 */ 397 MagickExport QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info) 398 { 399 assert(quantum_info != (QuantumInfo *) NULL); 400 assert(quantum_info->signature == MagickCoreSignature); 401 return(quantum_info->format); 402 } 403 404 /* 406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 407 % % 408 % % 409 % % 410 % G e t Q u a n t u m I n f o % 411 % % 412 % % 413 % % 414 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 415 % 416 % GetQuantumInfo() initializes the QuantumInfo structure to default values. 417 % 418 % The format of the GetQuantumInfo method is: 419 % 420 % GetQuantumInfo(const ImageInfo *image_info,QuantumInfo *quantum_info) 421 % 422 % A description of each parameter follows: 423 % 424 % o image_info: the image info. 425 % 426 % o quantum_info: the quantum info. 427 % 428 */ 429 MagickExport void GetQuantumInfo(const ImageInfo *image_info, 430 QuantumInfo *quantum_info) 431 { 432 const char 433 *option; 434 435 assert(quantum_info != (QuantumInfo *) NULL); 436 (void) memset(quantum_info,0,sizeof(*quantum_info)); 437 quantum_info->quantum=8; 438 quantum_info->maximum=1.0; 439 quantum_info->scale=QuantumRange; 440 quantum_info->pack=MagickTrue; 441 quantum_info->semaphore=AcquireSemaphoreInfo(); 442 quantum_info->signature=MagickCoreSignature; 443 if (image_info == (const ImageInfo *) NULL) 444 return; 445 option=GetImageOption(image_info,"quantum:format"); 446 if (option != (char *) NULL) 447 quantum_info->format=(QuantumFormatType) ParseCommandOption( 448 MagickQuantumFormatOptions,MagickFalse,option); 449 option=GetImageOption(image_info,"quantum:minimum"); 450 if (option != (char *) NULL) 451 quantum_info->minimum=StringToDouble(option,(char **) NULL); 452 option=GetImageOption(image_info,"quantum:maximum"); 453 if (option != (char *) NULL) 454 quantum_info->maximum=StringToDouble(option,(char **) NULL); 455 if ((quantum_info->minimum == 0.0) && (quantum_info->maximum == 0.0)) 456 quantum_info->scale=0.0; 457 else 458 if (quantum_info->minimum == quantum_info->maximum) 459 { 460 quantum_info->scale=(double) QuantumRange/quantum_info->minimum; 461 quantum_info->minimum=0.0; 462 } 463 else 464 quantum_info->scale=(double) QuantumRange/(quantum_info->maximum- 465 quantum_info->minimum); 466 option=GetImageOption(image_info,"quantum:scale"); 467 if (option != (char *) NULL) 468 quantum_info->scale=StringToDouble(option,(char **) NULL); 469 option=GetImageOption(image_info,"quantum:polarity"); 470 if (option != (char *) NULL) 471 quantum_info->min_is_white=LocaleCompare(option,"min-is-white") == 0 ? 472 MagickTrue : MagickFalse; 473 quantum_info->endian=image_info->endian; 474 ResetQuantumState(quantum_info); 475 } 476 477 /* 479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 480 % % 481 % % 482 % % 483 % G e t Q u a n t u m P i x e l s % 484 % % 485 % % 486 % % 487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 488 % 489 % GetQuantumPixels() returns the quantum pixels. 490 % 491 % The format of the GetQuantumPixels method is: 492 % 493 % unsigned char *QuantumPixels GetQuantumPixels( 494 % const QuantumInfo *quantum_info) 495 % 496 % A description of each parameter follows: 497 % 498 % o image: the image. 499 % 500 */ 501 MagickExport unsigned char *GetQuantumPixels(const QuantumInfo *quantum_info) 502 { 503 const int 504 id = GetOpenMPThreadId(); 505 506 assert(quantum_info != (QuantumInfo *) NULL); 507 assert(quantum_info->signature == MagickCoreSignature); 508 return((unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[id])); 509 } 510 511 /* 513 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 514 % % 515 % % 516 % % 517 % G e t Q u a n t u m T y p e % 518 % % 519 % % 520 % % 521 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 522 % 523 % GetQuantumType() returns the quantum type of the image. 524 % 525 % The format of the GetQuantumType method is: 526 % 527 % QuantumType GetQuantumType(Image *image,ExceptionInfo *exception) 528 % 529 % A description of each parameter follows: 530 % 531 % o image: the image. 532 % 533 % o exception: return any errors or warnings in this structure. 534 % 535 */ 536 MagickExport QuantumType GetQuantumType(Image *image,ExceptionInfo *exception) 537 { 538 QuantumType 539 quantum_type; 540 541 assert(image != (Image *) NULL); 542 assert(image->signature == MagickCoreSignature); 543 if (image->debug != MagickFalse) 544 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 545 (void) exception; 546 quantum_type=RGBQuantum; 547 if (image->alpha_trait != UndefinedPixelTrait) 548 quantum_type=RGBAQuantum; 549 if (image->colorspace == CMYKColorspace) 550 { 551 quantum_type=CMYKQuantum; 552 if (image->alpha_trait != UndefinedPixelTrait) 553 quantum_type=CMYKAQuantum; 554 } 555 if (IsGrayColorspace(image->colorspace) != MagickFalse) 556 { 557 quantum_type=GrayQuantum; 558 if (image->alpha_trait != UndefinedPixelTrait) 559 quantum_type=GrayAlphaQuantum; 560 } 561 if (image->storage_class == PseudoClass) 562 { 563 quantum_type=IndexQuantum; 564 if (image->alpha_trait != UndefinedPixelTrait) 565 quantum_type=IndexAlphaQuantum; 566 } 567 return(quantum_type); 568 } 569 570 /* 572 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 573 % % 574 % % 575 % % 576 + R e s e t Q u a n t u m S t a t e % 577 % % 578 % % 579 % % 580 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 581 % 582 % ResetQuantumState() resets the quantum state. 583 % 584 % The format of the ResetQuantumState method is: 585 % 586 % void ResetQuantumState(QuantumInfo *quantum_info) 587 % 588 % A description of each parameter follows: 589 % 590 % o quantum_info: the quantum info. 591 % 592 */ 593 MagickPrivate void ResetQuantumState(QuantumInfo *quantum_info) 594 { 595 static const unsigned int mask[32] = 596 { 597 0x00000000U, 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000fU, 598 0x0000001fU, 0x0000003fU, 0x0000007fU, 0x000000ffU, 0x000001ffU, 599 0x000003ffU, 0x000007ffU, 0x00000fffU, 0x00001fffU, 0x00003fffU, 600 0x00007fffU, 0x0000ffffU, 0x0001ffffU, 0x0003ffffU, 0x0007ffffU, 601 0x000fffffU, 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU, 602 0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU, 0x1fffffffU, 603 0x3fffffffU, 0x7fffffffU 604 }; 605 606 assert(quantum_info != (QuantumInfo *) NULL); 607 assert(quantum_info->signature == MagickCoreSignature); 608 quantum_info->state.inverse_scale=1.0; 609 if (fabs(quantum_info->scale) >= MagickEpsilon) 610 quantum_info->state.inverse_scale/=quantum_info->scale; 611 quantum_info->state.pixel=0U; 612 quantum_info->state.bits=0U; 613 quantum_info->state.mask=mask; 614 } 615 616 /* 618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 619 % % 620 % % 621 % % 622 % S e t Q u a n t u m F o r m a t % 623 % % 624 % % 625 % % 626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 627 % 628 % SetQuantumAlphaType() sets the quantum format. 629 % 630 % The format of the SetQuantumAlphaType method is: 631 % 632 % void SetQuantumAlphaType(QuantumInfo *quantum_info, 633 % const QuantumAlphaType type) 634 % 635 % A description of each parameter follows: 636 % 637 % o quantum_info: the quantum info. 638 % 639 % o type: the alpha type (e.g. associate). 640 % 641 */ 642 MagickExport void SetQuantumAlphaType(QuantumInfo *quantum_info, 643 const QuantumAlphaType type) 644 { 645 assert(quantum_info != (QuantumInfo *) NULL); 646 assert(quantum_info->signature == MagickCoreSignature); 647 quantum_info->alpha_type=type; 648 } 649 650 /* 652 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 653 % % 654 % % 655 % % 656 % S e t Q u a n t u m D e p t h % 657 % % 658 % % 659 % % 660 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 661 % 662 % SetQuantumDepth() sets the quantum depth. 663 % 664 % The format of the SetQuantumDepth method is: 665 % 666 % MagickBooleanType SetQuantumDepth(const Image *image, 667 % QuantumInfo *quantum_info,const size_t depth) 668 % 669 % A description of each parameter follows: 670 % 671 % o image: the image. 672 % 673 % o quantum_info: the quantum info. 674 % 675 % o depth: the quantum depth. 676 % 677 */ 678 MagickExport MagickBooleanType SetQuantumDepth(const Image *image, 679 QuantumInfo *quantum_info,const size_t depth) 680 { 681 size_t 682 extent, 683 quantum; 684 685 /* 686 Allocate the quantum pixel buffer. 687 */ 688 assert(image != (Image *) NULL); 689 assert(image->signature == MagickCoreSignature); 690 if (image->debug != MagickFalse) 691 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 692 assert(quantum_info != (QuantumInfo *) NULL); 693 assert(quantum_info->signature == MagickCoreSignature); 694 quantum_info->depth=depth; 695 if (quantum_info->format == FloatingPointQuantumFormat) 696 { 697 if (quantum_info->depth > 32) 698 quantum_info->depth=64; 699 else 700 if (quantum_info->depth > 16) 701 quantum_info->depth=32; 702 else 703 quantum_info->depth=16; 704 } 705 if (quantum_info->pixels != (MemoryInfo **) NULL) 706 DestroyQuantumPixels(quantum_info); 707 quantum=(quantum_info->pad+MaxPixelChannels)*(quantum_info->depth+7)/8; 708 extent=MagickMax(image->columns,image->rows)*quantum; 709 if ((MagickMax(image->columns,image->rows) != 0) && 710 (quantum != (extent/MagickMax(image->columns,image->rows)))) 711 return(MagickFalse); 712 return(AcquireQuantumPixels(quantum_info,extent)); 713 } 714 715 /* 717 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 718 % % 719 % % 720 % % 721 % S e t Q u a n t u m E n d i a n % 722 % % 723 % % 724 % % 725 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 726 % 727 % SetQuantumEndian() sets the quantum endian. 728 % 729 % The endian of the SetQuantumEndian method is: 730 % 731 % MagickBooleanType SetQuantumEndian(const Image *image, 732 % QuantumInfo *quantum_info,const EndianType endian) 733 % 734 % A description of each parameter follows: 735 % 736 % o image: the image. 737 % 738 % o quantum_info: the quantum info. 739 % 740 % o endian: the quantum endian. 741 % 742 */ 743 MagickExport MagickBooleanType SetQuantumEndian(const Image *image, 744 QuantumInfo *quantum_info,const EndianType endian) 745 { 746 assert(image != (Image *) NULL); 747 assert(image->signature == MagickCoreSignature); 748 if (image->debug != MagickFalse) 749 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 750 assert(quantum_info != (QuantumInfo *) NULL); 751 assert(quantum_info->signature == MagickCoreSignature); 752 quantum_info->endian=endian; 753 return(SetQuantumDepth(image,quantum_info,quantum_info->depth)); 754 } 755 756 /* 758 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 759 % % 760 % % 761 % % 762 % S e t Q u a n t u m F o r m a t % 763 % % 764 % % 765 % % 766 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 767 % 768 % SetQuantumFormat() sets the quantum format. 769 % 770 % The format of the SetQuantumFormat method is: 771 % 772 % MagickBooleanType SetQuantumFormat(const Image *image, 773 % QuantumInfo *quantum_info,const QuantumFormatType format) 774 % 775 % A description of each parameter follows: 776 % 777 % o image: the image. 778 % 779 % o quantum_info: the quantum info. 780 % 781 % o format: the quantum format. 782 % 783 */ 784 MagickExport MagickBooleanType SetQuantumFormat(const Image *image, 785 QuantumInfo *quantum_info,const QuantumFormatType format) 786 { 787 assert(image != (Image *) NULL); 788 assert(image->signature == MagickCoreSignature); 789 if (image->debug != MagickFalse) 790 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 791 assert(quantum_info != (QuantumInfo *) NULL); 792 assert(quantum_info->signature == MagickCoreSignature); 793 quantum_info->format=format; 794 return(SetQuantumDepth(image,quantum_info,quantum_info->depth)); 795 } 796 797 /* 799 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 800 % % 801 % % 802 % % 803 % S e t Q u a n t u m I m a g e T y p e % 804 % % 805 % % 806 % % 807 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 808 % 809 % SetQuantumImageType() sets the image type based on the quantum type. 810 % 811 % The format of the SetQuantumImageType method is: 812 % 813 % void ImageType SetQuantumImageType(Image *image, 814 % const QuantumType quantum_type) 815 % 816 % A description of each parameter follows: 817 % 818 % o image: the image. 819 % 820 % o quantum_type: Declare which pixel components to transfer (red, green, 821 % blue, opacity, RGB, or RGBA). 822 % 823 */ 824 MagickExport void SetQuantumImageType(Image *image, 825 const QuantumType quantum_type) 826 { 827 assert(image != (Image *) NULL); 828 assert(image->signature == MagickCoreSignature); 829 if (image->debug != MagickFalse) 830 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 831 switch (quantum_type) 832 { 833 case IndexQuantum: 834 case IndexAlphaQuantum: 835 { 836 image->type=PaletteType; 837 break; 838 } 839 case GrayQuantum: 840 case GrayAlphaQuantum: 841 { 842 image->type=GrayscaleType; 843 if (image->depth == 1) 844 image->type=BilevelType; 845 break; 846 } 847 case CyanQuantum: 848 case MagentaQuantum: 849 case YellowQuantum: 850 case BlackQuantum: 851 case CMYKQuantum: 852 case CMYKAQuantum: 853 { 854 image->type=ColorSeparationType; 855 break; 856 } 857 default: 858 { 859 image->type=TrueColorType; 860 break; 861 } 862 } 863 } 864 865 /* 867 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 868 % % 869 % % 870 % % 871 % S e t Q u a n t u m P a c k % 872 % % 873 % % 874 % % 875 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 876 % 877 % SetQuantumPack() sets the quantum pack flag. 878 % 879 % The format of the SetQuantumPack method is: 880 % 881 % void SetQuantumPack(QuantumInfo *quantum_info, 882 % const MagickBooleanType pack) 883 % 884 % A description of each parameter follows: 885 % 886 % o quantum_info: the quantum info. 887 % 888 % o pack: the pack flag. 889 % 890 */ 891 MagickExport void SetQuantumPack(QuantumInfo *quantum_info, 892 const MagickBooleanType pack) 893 { 894 assert(quantum_info != (QuantumInfo *) NULL); 895 assert(quantum_info->signature == MagickCoreSignature); 896 quantum_info->pack=pack; 897 } 898 899 /* 901 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 902 % % 903 % % 904 % % 905 % S e t Q u a n t u m P a d % 906 % % 907 % % 908 % % 909 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 910 % 911 % SetQuantumPad() sets the quantum pad. 912 % 913 % The format of the SetQuantumPad method is: 914 % 915 % MagickBooleanType SetQuantumPad(const Image *image, 916 % QuantumInfo *quantum_info,const size_t pad) 917 % 918 % A description of each parameter follows: 919 % 920 % o image: the image. 921 % 922 % o quantum_info: the quantum info. 923 % 924 % o pad: the quantum pad. 925 % 926 */ 927 MagickExport MagickBooleanType SetQuantumPad(const Image *image, 928 QuantumInfo *quantum_info,const size_t pad) 929 { 930 assert(image != (Image *) NULL); 931 assert(image->signature == MagickCoreSignature); 932 if (image->debug != MagickFalse) 933 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 934 assert(quantum_info != (QuantumInfo *) NULL); 935 assert(quantum_info->signature == MagickCoreSignature); 936 quantum_info->pad=pad; 937 return(SetQuantumDepth(image,quantum_info,quantum_info->depth)); 938 } 939 940 /* 942 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 943 % % 944 % % 945 % % 946 % S e t Q u a n t u m M i n I s W h i t e % 947 % % 948 % % 949 % % 950 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 951 % 952 % SetQuantumMinIsWhite() sets the quantum min-is-white flag. 953 % 954 % The format of the SetQuantumMinIsWhite method is: 955 % 956 % void SetQuantumMinIsWhite(QuantumInfo *quantum_info, 957 % const MagickBooleanType min_is_white) 958 % 959 % A description of each parameter follows: 960 % 961 % o quantum_info: the quantum info. 962 % 963 % o min_is_white: the min-is-white flag. 964 % 965 */ 966 MagickExport void SetQuantumMinIsWhite(QuantumInfo *quantum_info, 967 const MagickBooleanType min_is_white) 968 { 969 assert(quantum_info != (QuantumInfo *) NULL); 970 assert(quantum_info->signature == MagickCoreSignature); 971 quantum_info->min_is_white=min_is_white; 972 } 973 974 /* 976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 977 % % 978 % % 979 % % 980 % S e t Q u a n t u m Q u a n t u m % 981 % % 982 % % 983 % % 984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 985 % 986 % SetQuantumQuantum() sets the quantum quantum. 987 % 988 % The format of the SetQuantumQuantum method is: 989 % 990 % void SetQuantumQuantum(QuantumInfo *quantum_info, 991 % const size_t quantum) 992 % 993 % A description of each parameter follows: 994 % 995 % o quantum_info: the quantum info. 996 % 997 % o quantum: the quantum quantum. 998 % 999 */ 1000 MagickExport void SetQuantumQuantum(QuantumInfo *quantum_info, 1001 const size_t quantum) 1002 { 1003 assert(quantum_info != (QuantumInfo *) NULL); 1004 assert(quantum_info->signature == MagickCoreSignature); 1005 quantum_info->quantum=quantum; 1006 } 1007 1008 /* 1010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1011 % % 1012 % % 1013 % % 1014 % S e t Q u a n t u m S c a l e % 1015 % % 1016 % % 1017 % % 1018 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1019 % 1020 % SetQuantumScale() sets the quantum scale. 1021 % 1022 % The format of the SetQuantumScale method is: 1023 % 1024 % void SetQuantumScale(QuantumInfo *quantum_info,const double scale) 1025 % 1026 % A description of each parameter follows: 1027 % 1028 % o quantum_info: the quantum info. 1029 % 1030 % o scale: the quantum scale. 1031 % 1032 */ 1033 MagickExport void SetQuantumScale(QuantumInfo *quantum_info,const double scale) 1034 { 1035 assert(quantum_info != (QuantumInfo *) NULL); 1036 assert(quantum_info->signature == MagickCoreSignature); 1037 quantum_info->scale=scale; 1038 } 1039