1 /* 2 Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization 3 dedicated to making software imaging solutions freely available. 4 5 You may not use this file except in compliance with the License. You may 6 obtain a copy of the License at 7 8 https://imagemagick.org/script/license.php 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 16 MagickCore quantum inline methods. 17 */ 18 #ifndef MAGICKCORE_QUANTUM_PRIVATE_H 19 #define MAGICKCORE_QUANTUM_PRIVATE_H 20 21 #include "MagickCore/memory_.h" 22 #include "MagickCore/cache.h" 23 #include "MagickCore/image-private.h" 24 #include "MagickCore/pixel-accessor.h" 25 26 #if defined(__cplusplus) || defined(c_plusplus) 27 extern "C" { 28 #endif 29 30 typedef struct _QuantumState 31 { 32 double 33 inverse_scale; 34 35 unsigned int 36 pixel; 37 38 size_t 39 bits; 40 41 const unsigned int 42 *mask; 43 } QuantumState; 44 45 struct _QuantumInfo 46 { 47 size_t 48 depth, 49 quantum; 50 51 QuantumFormatType 52 format; 53 54 double 55 minimum, 56 maximum, 57 scale; 58 59 size_t 60 pad; 61 62 MagickBooleanType 63 min_is_white, 64 pack; 65 66 QuantumAlphaType 67 alpha_type; 68 69 size_t 70 number_threads; 71 72 MemoryInfo 73 **pixels; 74 75 size_t 76 extent; 77 78 EndianType 79 endian; 80 81 QuantumState 82 state; 83 84 SemaphoreInfo 85 *semaphore; 86 87 size_t 88 signature; 89 }; 90 91 extern MagickPrivate void 92 ResetQuantumState(QuantumInfo *); 93 94 static inline MagickSizeType GetQuantumRange(const size_t depth) 95 { 96 MagickSizeType 97 one; 98 99 size_t 100 max_depth; 101 102 if (depth == 0) 103 return(0); 104 one=1; 105 max_depth=8*sizeof(MagickSizeType); 106 return((MagickSizeType) ((one << (MagickMin(depth,max_depth)-1))+ 107 ((one << (MagickMin(depth,max_depth)-1))-1))); 108 } 109 110 static inline float HalfToSinglePrecision(const unsigned short half) 111 { 112 #define ExponentBias (127-15) 113 #define ExponentMask 0x7c00 114 #define ExponentShift 23 115 #define SignBitShift 31 116 #define SignificandShift 13 117 #define SignificandMask 0x00000400 118 119 typedef union _SinglePrecision 120 { 121 unsigned int 122 fixed_point; 123 124 float 125 single_precision; 126 } SinglePrecision; 127 128 register unsigned int 129 exponent, 130 significand, 131 sign_bit; 132 133 SinglePrecision 134 map; 135 136 unsigned int 137 value; 138 139 /* 140 The IEEE 754 standard specifies half precision as having: 141 142 Sign bit: 1 bit 143 Exponent width: 5 bits 144 Significand precision: 11 (10 explicitly stored) 145 */ 146 sign_bit=(unsigned int) ((half >> 15) & 0x00000001); 147 exponent=(unsigned int) ((half >> 10) & 0x0000001f); 148 significand=(unsigned int) (half & 0x000003ff); 149 if (exponent == 0) 150 { 151 if (significand == 0) 152 value=sign_bit << SignBitShift; 153 else 154 { 155 while ((significand & SignificandMask) == 0) 156 { 157 significand<<=1; 158 exponent--; 159 } 160 exponent++; 161 significand&=(~SignificandMask); 162 exponent+=ExponentBias; 163 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) | 164 (significand << SignificandShift); 165 } 166 } 167 else 168 if (exponent == SignBitShift) 169 { 170 value=(sign_bit << SignBitShift) | 0x7f800000; 171 if (significand != 0) 172 value|=(significand << SignificandShift); 173 } 174 else 175 { 176 exponent+=ExponentBias; 177 significand<<=SignificandShift; 178 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) | 179 significand; 180 } 181 map.fixed_point=value; 182 return(map.single_precision); 183 } 184 185 static inline unsigned char *PopCharPixel(const unsigned char pixel, 186 unsigned char *pixels) 187 { 188 *pixels++=pixel; 189 return(pixels); 190 } 191 192 static inline unsigned char *PopLongPixel(const EndianType endian, 193 const unsigned int pixel,unsigned char *pixels) 194 { 195 register unsigned int 196 quantum; 197 198 quantum=(unsigned int) pixel; 199 if (endian == LSBEndian) 200 { 201 *pixels++=(unsigned char) (quantum); 202 *pixels++=(unsigned char) (quantum >> 8); 203 *pixels++=(unsigned char) (quantum >> 16); 204 *pixels++=(unsigned char) (quantum >> 24); 205 return(pixels); 206 } 207 *pixels++=(unsigned char) (quantum >> 24); 208 *pixels++=(unsigned char) (quantum >> 16); 209 *pixels++=(unsigned char) (quantum >> 8); 210 *pixels++=(unsigned char) (quantum); 211 return(pixels); 212 } 213 214 static inline unsigned char *PopShortPixel(const EndianType endian, 215 const unsigned short pixel,unsigned char *pixels) 216 { 217 register unsigned int 218 quantum; 219 220 quantum=pixel; 221 if (endian == LSBEndian) 222 { 223 *pixels++=(unsigned char) (quantum); 224 *pixels++=(unsigned char) (quantum >> 8); 225 return(pixels); 226 } 227 *pixels++=(unsigned char) (quantum >> 8); 228 *pixels++=(unsigned char) (quantum); 229 return(pixels); 230 } 231 232 static inline const unsigned char *PushCharPixel(const unsigned char *pixels, 233 unsigned char *pixel) 234 { 235 *pixel=(*pixels++); 236 return(pixels); 237 } 238 239 static inline const unsigned char *PushLongPixel(const EndianType endian, 240 const unsigned char *pixels,unsigned int *pixel) 241 { 242 register unsigned int 243 quantum; 244 245 if (endian == LSBEndian) 246 { 247 quantum=((unsigned int) *pixels++); 248 quantum|=((unsigned int) *pixels++ << 8); 249 quantum|=((unsigned int) *pixels++ << 16); 250 quantum|=((unsigned int) *pixels++ << 24); 251 *pixel=quantum; 252 return(pixels); 253 } 254 quantum=((unsigned int) *pixels++ << 24); 255 quantum|=((unsigned int) *pixels++ << 16); 256 quantum|=((unsigned int) *pixels++ << 8); 257 quantum|=((unsigned int) *pixels++); 258 *pixel=quantum; 259 return(pixels); 260 } 261 262 static inline const unsigned char *PushShortPixel(const EndianType endian, 263 const unsigned char *pixels,unsigned short *pixel) 264 { 265 register unsigned int 266 quantum; 267 268 if (endian == LSBEndian) 269 { 270 quantum=(unsigned int) *pixels++; 271 quantum|=(unsigned int) (*pixels++ << 8); 272 *pixel=(unsigned short) (quantum & 0xffff); 273 return(pixels); 274 } 275 quantum=(unsigned int) (*pixels++ << 8); 276 quantum|=(unsigned int) *pixels++; 277 *pixel=(unsigned short) (quantum & 0xffff); 278 return(pixels); 279 } 280 281 static inline const unsigned char *PushFloatPixel(const EndianType endian, 282 const unsigned char *pixels,MagickFloatType *pixel) 283 { 284 union 285 { 286 unsigned int 287 unsigned_value; 288 289 MagickFloatType 290 float_value; 291 } quantum; 292 293 if (endian == LSBEndian) 294 { 295 quantum.unsigned_value=((unsigned int) *pixels++); 296 quantum.unsigned_value|=((unsigned int) *pixels++ << 8); 297 quantum.unsigned_value|=((unsigned int) *pixels++ << 16); 298 quantum.unsigned_value|=((unsigned int) *pixels++ << 24); 299 *pixel=quantum.float_value; 300 return(pixels); 301 } 302 quantum.unsigned_value=((unsigned int) *pixels++ << 24); 303 quantum.unsigned_value|=((unsigned int) *pixels++ << 16); 304 quantum.unsigned_value|=((unsigned int) *pixels++ << 8); 305 quantum.unsigned_value|=((unsigned int) *pixels++); 306 *pixel=quantum.float_value; 307 return(pixels); 308 } 309 310 static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum, 311 const QuantumAny range) 312 { 313 if (quantum > range) 314 return(QuantumRange); 315 #if !defined(MAGICKCORE_HDRI_SUPPORT) 316 return((Quantum) (((double) QuantumRange*quantum)* 317 PerceptibleReciprocal((double) range)+0.5)); 318 #else 319 return((Quantum) (((double) QuantumRange*quantum)* 320 PerceptibleReciprocal((double) range))); 321 #endif 322 } 323 324 static inline QuantumAny ScaleQuantumToAny(const Quantum quantum, 325 const QuantumAny range) 326 { 327 return((QuantumAny) (((double) range*quantum)/QuantumRange+0.5)); 328 } 329 330 #if (MAGICKCORE_QUANTUM_DEPTH == 8) 331 static inline Quantum ScaleCharToQuantum(const unsigned char value) 332 { 333 return((Quantum) value); 334 } 335 336 static inline Quantum ScaleLongToQuantum(const unsigned int value) 337 { 338 #if !defined(MAGICKCORE_HDRI_SUPPORT) 339 return((Quantum) ((value)/16843009UL)); 340 #else 341 return((Quantum) (value/16843009.0)); 342 #endif 343 } 344 345 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value) 346 { 347 #if !defined(MAGICKCORE_HDRI_SUPPORT) 348 return((Quantum) (value/MagickULLConstant(72340172838076673))); 349 #else 350 return((Quantum) (value/72340172838076673.0)); 351 #endif 352 } 353 354 static inline Quantum ScaleMapToQuantum(const MagickRealType value) 355 { 356 if (value <= 0.0) 357 return((Quantum) 0); 358 if (value >= MaxMap) 359 return(QuantumRange); 360 #if !defined(MAGICKCORE_HDRI_SUPPORT) 361 return((Quantum) (value+0.5)); 362 #else 363 return((Quantum) value); 364 #endif 365 } 366 367 static inline unsigned int ScaleQuantumToLong(const Quantum quantum) 368 { 369 #if !defined(MAGICKCORE_HDRI_SUPPORT) 370 return((unsigned int) (16843009UL*quantum)); 371 #else 372 if (quantum <= 0.0) 373 return(0UL); 374 if ((16843009.0*quantum) >= 4294967295.0) 375 return(4294967295UL); 376 return((unsigned int) (16843009.0*quantum+0.5)); 377 #endif 378 } 379 380 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum) 381 { 382 #if !defined(MAGICKCORE_HDRI_SUPPORT) 383 return((MagickSizeType) (MagickULLConstant(72340172838076673)*quantum)); 384 #else 385 if (quantum <= 0.0) 386 return(0UL); 387 if ((72340172838076673.0*quantum) >= 18446744073709551615.0) 388 return(MagickULLConstant(18446744073709551615)); 389 return((MagickSizeType) (72340172838076673*quantum+0.5)); 390 #endif 391 } 392 393 static inline unsigned int ScaleQuantumToMap(const Quantum quantum) 394 { 395 if (quantum >= (Quantum) MaxMap) 396 return((unsigned int) MaxMap); 397 #if !defined(MAGICKCORE_HDRI_SUPPORT) 398 return((unsigned int) quantum); 399 #else 400 if (quantum < 0.0) 401 return(0UL); 402 return((unsigned int) (quantum+0.5)); 403 #endif 404 } 405 406 static inline unsigned short ScaleQuantumToShort(const Quantum quantum) 407 { 408 #if !defined(MAGICKCORE_HDRI_SUPPORT) 409 return((unsigned short) (257UL*quantum)); 410 #else 411 if (quantum <= 0.0) 412 return(0); 413 if ((257.0*quantum) >= 65535.0) 414 return(65535); 415 return((unsigned short) (257.0*quantum+0.5)); 416 #endif 417 } 418 419 static inline Quantum ScaleShortToQuantum(const unsigned short value) 420 { 421 #if !defined(MAGICKCORE_HDRI_SUPPORT) 422 return((Quantum) ((value+128U)/257U)); 423 #else 424 return((Quantum) (value/257.0)); 425 #endif 426 } 427 #elif (MAGICKCORE_QUANTUM_DEPTH == 16) 428 static inline Quantum ScaleCharToQuantum(const unsigned char value) 429 { 430 #if !defined(MAGICKCORE_HDRI_SUPPORT) 431 return((Quantum) (257U*value)); 432 #else 433 return((Quantum) (257.0*value)); 434 #endif 435 } 436 437 static inline Quantum ScaleLongToQuantum(const unsigned int value) 438 { 439 #if !defined(MAGICKCORE_HDRI_SUPPORT) 440 return((Quantum) ((value)/MagickULLConstant(65537))); 441 #else 442 return((Quantum) (value/65537.0)); 443 #endif 444 } 445 446 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value) 447 { 448 #if !defined(MAGICKCORE_HDRI_SUPPORT) 449 return((Quantum) ((value)/MagickULLConstant(281479271743489))); 450 #else 451 return((Quantum) (value/281479271743489.0)); 452 #endif 453 } 454 455 static inline Quantum ScaleMapToQuantum(const MagickRealType value) 456 { 457 if (value <= 0.0) 458 return((Quantum) 0); 459 if (value >= MaxMap) 460 return(QuantumRange); 461 #if !defined(MAGICKCORE_HDRI_SUPPORT) 462 return((Quantum) (value+0.5)); 463 #else 464 return((Quantum) value); 465 #endif 466 } 467 468 static inline unsigned int ScaleQuantumToLong(const Quantum quantum) 469 { 470 #if !defined(MAGICKCORE_HDRI_SUPPORT) 471 return((unsigned int) (65537UL*quantum)); 472 #else 473 if (quantum <= 0.0) 474 return(0UL); 475 if ((65537.0*quantum) >= 4294967295.0) 476 return(4294967295U); 477 return((unsigned int) (65537.0*quantum+0.5)); 478 #endif 479 } 480 481 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum) 482 { 483 #if !defined(MAGICKCORE_HDRI_SUPPORT) 484 return((MagickSizeType) (MagickULLConstant(281479271743489)*quantum)); 485 #else 486 if (quantum <= 0.0) 487 return(0UL); 488 if ((281479271743489.0*quantum) >= 18446744073709551615.0) 489 return(MagickULLConstant(18446744073709551615)); 490 return((MagickSizeType) (281479271743489.0*quantum+0.5)); 491 #endif 492 } 493 494 static inline unsigned int ScaleQuantumToMap(const Quantum quantum) 495 { 496 if (quantum >= (Quantum) MaxMap) 497 return((unsigned int) MaxMap); 498 #if !defined(MAGICKCORE_HDRI_SUPPORT) 499 return((unsigned int) quantum); 500 #else 501 if (quantum < 0.0) 502 return(0UL); 503 return((unsigned int) (quantum+0.5)); 504 #endif 505 } 506 507 static inline unsigned short ScaleQuantumToShort(const Quantum quantum) 508 { 509 #if !defined(MAGICKCORE_HDRI_SUPPORT) 510 return((unsigned short) quantum); 511 #else 512 if (quantum <= 0.0) 513 return(0); 514 if (quantum >= 65535.0) 515 return(65535); 516 return((unsigned short) (quantum+0.5)); 517 #endif 518 } 519 520 static inline Quantum ScaleShortToQuantum(const unsigned short value) 521 { 522 return((Quantum) value); 523 } 524 #elif (MAGICKCORE_QUANTUM_DEPTH == 32) 525 static inline Quantum ScaleCharToQuantum(const unsigned char value) 526 { 527 #if !defined(MAGICKCORE_HDRI_SUPPORT) 528 return((Quantum) (16843009UL*value)); 529 #else 530 return((Quantum) (16843009.0*value)); 531 #endif 532 } 533 534 static inline Quantum ScaleLongToQuantum(const unsigned int value) 535 { 536 return((Quantum) value); 537 } 538 539 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value) 540 { 541 #if !defined(MAGICKCORE_HDRI_SUPPORT) 542 return((Quantum) ((value)/MagickULLConstant(4294967297))); 543 #else 544 return((Quantum) (value/4294967297.0)); 545 #endif 546 } 547 548 static inline Quantum ScaleMapToQuantum(const MagickRealType value) 549 { 550 if (value <= 0.0) 551 return((Quantum) 0); 552 if (value >= (Quantum) MaxMap) 553 return(QuantumRange); 554 #if !defined(MAGICKCORE_HDRI_SUPPORT) 555 return((Quantum) (65537.0*value+0.5)); 556 #else 557 return((Quantum) (65537.0*value)); 558 #endif 559 } 560 561 static inline unsigned int ScaleQuantumToLong(const Quantum quantum) 562 { 563 #if !defined(MAGICKCORE_HDRI_SUPPORT) 564 return((unsigned int) quantum); 565 #else 566 if (quantum <= 0.0) 567 return(0); 568 if ((quantum) >= 4294967295.0) 569 return(4294967295); 570 return((unsigned int) (quantum+0.5)); 571 #endif 572 } 573 574 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum) 575 { 576 #if !defined(MAGICKCORE_HDRI_SUPPORT) 577 return((MagickSizeType) (MagickULLConstant(4294967297)*quantum)); 578 #else 579 if (quantum <= 0.0) 580 return(0UL); 581 if ((4294967297.0*quantum) >= 18446744073709551615.0) 582 return(MagickULLConstant(18446744073709551615)); 583 return((MagickSizeType) (4294967297.0*quantum+0.5)); 584 #endif 585 } 586 587 static inline unsigned int ScaleQuantumToMap(const Quantum quantum) 588 { 589 if (quantum < 0.0) 590 return(0UL); 591 if ((quantum/65537) >= (Quantum) MaxMap) 592 return((unsigned int) MaxMap); 593 #if !defined(MAGICKCORE_HDRI_SUPPORT) 594 return((unsigned int) ((quantum+MagickULLConstant(32768))/ 595 MagickULLConstant(65537))); 596 #else 597 return((unsigned int) (quantum/65537.0+0.5)); 598 #endif 599 } 600 601 static inline unsigned short ScaleQuantumToShort(const Quantum quantum) 602 { 603 #if !defined(MAGICKCORE_HDRI_SUPPORT) 604 return((unsigned short) ((quantum+MagickULLConstant(32768))/ 605 MagickULLConstant(65537))); 606 #else 607 if (quantum <= 0.0) 608 return(0); 609 if ((quantum/65537.0) >= 65535.0) 610 return(65535); 611 return((unsigned short) (quantum/65537.0+0.5)); 612 #endif 613 } 614 615 static inline Quantum ScaleShortToQuantum(const unsigned short value) 616 { 617 #if !defined(MAGICKCORE_HDRI_SUPPORT) 618 return((Quantum) (65537UL*value)); 619 #else 620 return((Quantum) (65537.0*value)); 621 #endif 622 } 623 #elif (MAGICKCORE_QUANTUM_DEPTH == 64) 624 static inline Quantum ScaleCharToQuantum(const unsigned char value) 625 { 626 return((Quantum) (72340172838076673.0*value)); 627 } 628 629 static inline Quantum ScaleLongToQuantum(const unsigned int value) 630 { 631 return((Quantum) (4294967297.0*value)); 632 } 633 634 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value) 635 { 636 return((Quantum) (value)); 637 } 638 639 static inline Quantum ScaleMapToQuantum(const MagickRealType value) 640 { 641 if (value <= 0.0) 642 return((Quantum) 0); 643 if (value >= MaxMap) 644 return(QuantumRange); 645 return((Quantum) (281479271743489.0*value)); 646 } 647 648 static inline unsigned int ScaleQuantumToLong(const Quantum quantum) 649 { 650 return((unsigned int) (quantum/4294967297.0+0.5)); 651 } 652 653 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum) 654 { 655 #if !defined(MAGICKCORE_HDRI_SUPPORT) 656 return((MagickSizeType) quantum); 657 #else 658 if (quantum <= 0.0) 659 return(0); 660 if (quantum >= 18446744073709551615) 661 return(18446744073709551615); 662 return((MagickSizeType) (quantum+0.5)); 663 #endif 664 } 665 666 static inline unsigned int ScaleQuantumToMap(const Quantum quantum) 667 { 668 if (quantum <= 0.0) 669 return(0UL); 670 if ((quantum/281479271743489.0) >= MaxMap) 671 return((unsigned int) MaxMap); 672 return((unsigned int) (quantum/281479271743489.0+0.5)); 673 } 674 675 static inline unsigned short ScaleQuantumToShort(const Quantum quantum) 676 { 677 if (quantum <= 0.0) 678 return(0); 679 if ((quantum/281479271743489.0) >= 65535.0) 680 return(65535); 681 return((unsigned short) (quantum/281479271743489.0+0.5)); 682 } 683 684 static inline Quantum ScaleShortToQuantum(const unsigned short value) 685 { 686 return((Quantum) (281479271743489.0*value)); 687 } 688 #endif 689 690 static inline unsigned short SinglePrecisionToHalf(const float value) 691 { 692 typedef union _SinglePrecision 693 { 694 unsigned int 695 fixed_point; 696 697 float 698 single_precision; 699 } SinglePrecision; 700 701 register int 702 exponent; 703 704 register unsigned int 705 significand, 706 sign_bit; 707 708 SinglePrecision 709 map; 710 711 unsigned short 712 half; 713 714 /* 715 The IEEE 754 standard specifies half precision as having: 716 717 Sign bit: 1 bit 718 Exponent width: 5 bits 719 Significand precision: 11 (10 explicitly stored) 720 */ 721 map.single_precision=value; 722 sign_bit=(map.fixed_point >> 16) & 0x00008000; 723 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias; 724 significand=map.fixed_point & 0x007fffff; 725 if (exponent <= 0) 726 { 727 int 728 shift; 729 730 if (exponent < -10) 731 return((unsigned short) sign_bit); 732 significand=significand | 0x00800000; 733 shift=(int) (14-exponent); 734 significand=(unsigned int) ((significand+((1 << (shift-1))-1)+ 735 ((significand >> shift) & 0x01)) >> shift); 736 return((unsigned short) (sign_bit | significand)); 737 } 738 else 739 if (exponent == (0xff-ExponentBias)) 740 { 741 if (significand == 0) 742 return((unsigned short) (sign_bit | ExponentMask)); 743 else 744 { 745 significand>>=SignificandShift; 746 half=(unsigned short) (sign_bit | significand | 747 (significand == 0) | ExponentMask); 748 return(half); 749 } 750 } 751 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff; 752 if ((significand & 0x00800000) != 0) 753 { 754 significand=0; 755 exponent++; 756 } 757 if (exponent > 30) 758 { 759 float 760 alpha; 761 762 register int 763 i; 764 765 /* 766 Float overflow. 767 */ 768 alpha=1.0e10; 769 for (i=0; i < 10; i++) 770 alpha*=alpha; 771 return((unsigned short) (sign_bit | ExponentMask)); 772 } 773 half=(unsigned short) (sign_bit | (exponent << 10) | 774 (significand >> SignificandShift)); 775 return(half); 776 } 777 778 #if defined(__cplusplus) || defined(c_plusplus) 779 } 780 #endif 781 782 #endif 783