1 /*****************************************************************************/ 2 // Copyright 2006-2012 Adobe Systems Incorporated 3 // All Rights Reserved. 4 // 5 // NOTICE: Adobe permits you to use, modify, and distribute this file in 6 // accordance with the terms of the Adobe license agreement accompanying it. 7 /*****************************************************************************/ 8 9 /* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_utils.h#3 $ */ 10 /* $DateTime: 2012/06/14 20:24:41 $ */ 11 /* $Change: 835078 $ */ 12 /* $Author: tknoll $ */ 13 14 /*****************************************************************************/ 15 16 #ifndef __dng_utils__ 17 #define __dng_utils__ 18 19 /*****************************************************************************/ 20 21 #include <cmath> 22 #include <limits> 23 24 #include "dng_classes.h" 25 #include "dng_flags.h" 26 #include "dng_memory.h" 27 #include "dng_safe_arithmetic.h" 28 #include "dng_types.h" 29 30 /*****************************************************************************/ 31 32 // The unsigned integer overflow is intended here since a wrap around is used to 33 // calculate the abs() in the branchless version. 34 #if defined(__clang__) && defined(__has_attribute) 35 #if __has_attribute(no_sanitize) 36 __attribute__((no_sanitize("unsigned-integer-overflow"))) 37 #endif 38 #endif 39 inline uint32 Abs_int32 (int32 x) 40 { 41 42 #if 0 43 44 // Reference version. 45 46 return (uint32) (x < 0 ? -x : x); 47 48 #else 49 50 // Branchless version. 51 52 uint32 mask = (uint32) (x >> 31); 53 54 return (uint32) (((uint32) x + mask) ^ mask); 55 56 #endif 57 58 } 59 60 inline int32 Min_int32 (int32 x, int32 y) 61 { 62 63 return (x <= y ? x : y); 64 65 } 66 67 inline int32 Max_int32 (int32 x, int32 y) 68 { 69 70 return (x >= y ? x : y); 71 72 } 73 74 inline int32 Pin_int32 (int32 min, int32 x, int32 max) 75 { 76 77 return Max_int32 (min, Min_int32 (x, max)); 78 79 } 80 81 inline int32 Pin_int32_between (int32 a, int32 x, int32 b) 82 { 83 84 int32 min, max; 85 if (a < b) { min = a; max = b; } 86 else { min = b; max = a; } 87 88 return Pin_int32 (min, x, max); 89 90 } 91 92 /*****************************************************************************/ 93 94 inline uint16 Min_uint16 (uint16 x, uint16 y) 95 { 96 97 return (x <= y ? x : y); 98 99 } 100 101 inline uint16 Max_uint16 (uint16 x, uint16 y) 102 { 103 104 return (x >= y ? x : y); 105 106 } 107 108 inline int16 Pin_int16 (int32 x) 109 { 110 111 x = Pin_int32 (-32768, x, 32767); 112 113 return (int16) x; 114 115 } 116 117 /*****************************************************************************/ 118 119 inline uint32 Min_uint32 (uint32 x, uint32 y) 120 { 121 122 return (x <= y ? x : y); 123 124 } 125 126 inline uint32 Min_uint32 (uint32 x, uint32 y, uint32 z) 127 { 128 129 return Min_uint32 (x, Min_uint32 (y, z)); 130 131 } 132 133 inline uint32 Max_uint32 (uint32 x, uint32 y) 134 { 135 136 return (x >= y ? x : y); 137 138 } 139 140 inline uint32 Max_uint32 (uint32 x, uint32 y, uint32 z) 141 { 142 143 return Max_uint32 (x, Max_uint32 (y, z)); 144 145 } 146 147 inline uint32 Pin_uint32 (uint32 min, uint32 x, uint32 max) 148 { 149 150 return Max_uint32 (min, Min_uint32 (x, max)); 151 152 } 153 154 /*****************************************************************************/ 155 156 inline uint16 Pin_uint16 (int32 x) 157 { 158 159 #if 0 160 161 // Reference version. 162 163 x = Pin_int32 (0, x, 0x0FFFF); 164 165 #else 166 167 // Single branch version. 168 169 if (x & ~65535) 170 { 171 172 x = ~x >> 31; 173 174 } 175 176 #endif 177 178 return (uint16) x; 179 180 } 181 182 /*****************************************************************************/ 183 184 inline uint32 RoundDown2 (uint32 x) 185 { 186 187 return x & (uint32) ~1; 188 189 } 190 191 inline uint32 RoundDown4 (uint32 x) 192 { 193 194 return x & (uint32) ~3; 195 196 } 197 198 inline uint32 RoundDown8 (uint32 x) 199 { 200 201 return x & (uint32) ~7; 202 203 } 204 205 inline uint32 RoundDown16 (uint32 x) 206 { 207 208 return x & (uint32) ~15; 209 210 } 211 212 /******************************************************************************/ 213 214 inline bool RoundUpForPixelSize (uint32 x, uint32 pixelSize, uint32 *result) 215 { 216 217 uint32 multiple; 218 switch (pixelSize) 219 { 220 221 case 1: 222 case 2: 223 case 4: 224 case 8: 225 multiple = 16 / pixelSize; 226 break; 227 228 default: 229 multiple = 16; 230 break; 231 232 } 233 234 return RoundUpUint32ToMultiple(x, multiple, result); 235 236 } 237 238 /******************************************************************************/ 239 240 // Type of padding to be performed by ComputeBufferSize(). 241 enum PaddingType 242 { 243 // Don't perform any padding. 244 padNone, 245 // Pad each scanline to an integer multiple of 16 bytes (in the same way 246 // that RoundUpForPixelSize() does). 247 pad16Bytes 248 }; 249 250 // Returns the number of bytes required for an image tile with the given pixel 251 // type, tile size, number of image planes, and desired padding. Throws a 252 // dng_exception with dng_error_memory error code if one of the components of 253 // tileSize is negative or if arithmetic overflow occurs during the computation. 254 uint32 ComputeBufferSize(uint32 pixelType, const dng_point &tileSize, 255 uint32 numPlanes, PaddingType paddingType); 256 257 /******************************************************************************/ 258 259 inline uint64 Abs_int64 (int64 x) 260 { 261 262 return (uint64) (x < 0 ? -x : x); 263 264 } 265 266 inline int64 Min_int64 (int64 x, int64 y) 267 { 268 269 return (x <= y ? x : y); 270 271 } 272 273 inline int64 Max_int64 (int64 x, int64 y) 274 { 275 276 return (x >= y ? x : y); 277 278 } 279 280 inline int64 Pin_int64 (int64 min, int64 x, int64 max) 281 { 282 283 return Max_int64 (min, Min_int64 (x, max)); 284 285 } 286 287 /******************************************************************************/ 288 289 inline uint64 Min_uint64 (uint64 x, uint64 y) 290 { 291 292 return (x <= y ? x : y); 293 294 } 295 296 inline uint64 Max_uint64 (uint64 x, uint64 y) 297 { 298 299 return (x >= y ? x : y); 300 301 } 302 303 inline uint64 Pin_uint64 (uint64 min, uint64 x, uint64 max) 304 { 305 306 return Max_uint64 (min, Min_uint64 (x, max)); 307 308 } 309 310 /*****************************************************************************/ 311 312 inline real32 Abs_real32 (real32 x) 313 { 314 315 return (x < 0.0f ? -x : x); 316 317 } 318 319 inline real32 Min_real32 (real32 x, real32 y) 320 { 321 322 return (x < y ? x : y); 323 324 } 325 326 inline real32 Max_real32 (real32 x, real32 y) 327 { 328 329 return (x > y ? x : y); 330 331 } 332 333 inline real32 Pin_real32 (real32 min, real32 x, real32 max) 334 { 335 336 return Max_real32 (min, Min_real32 (x, max)); 337 338 } 339 340 inline real32 Pin_real32 (real32 x) 341 { 342 343 return Pin_real32 (0.0f, x, 1.0f); 344 345 } 346 347 inline real32 Pin_real32_Overrange (real32 min, 348 real32 x, 349 real32 max) 350 { 351 352 // Normal numbers in (min,max). No change. 353 354 if (x > min && x < max) 355 { 356 return x; 357 } 358 359 // Map large numbers (including positive infinity) to max. 360 361 else if (x > min) 362 { 363 return max; 364 } 365 366 // Map everything else (including negative infinity and all NaNs) to min. 367 368 return min; 369 370 } 371 372 inline real32 Pin_Overrange (real32 x) 373 { 374 375 // Normal in-range numbers, except for plus and minus zero. 376 377 if (x > 0.0f && x <= 1.0f) 378 { 379 return x; 380 } 381 382 // Large numbers, including positive infinity. 383 384 else if (x > 0.5f) 385 { 386 return 1.0f; 387 } 388 389 // Plus and minus zero, negative numbers, negative infinity, and all NaNs. 390 391 return 0.0f; 392 393 } 394 395 inline real32 Lerp_real32 (real32 a, real32 b, real32 t) 396 { 397 398 return a + t * (b - a); 399 400 } 401 402 /*****************************************************************************/ 403 404 inline real64 Abs_real64 (real64 x) 405 { 406 407 return (x < 0.0 ? -x : x); 408 409 } 410 411 inline real64 Min_real64 (real64 x, real64 y) 412 { 413 414 return (x < y ? x : y); 415 416 } 417 418 inline real64 Max_real64 (real64 x, real64 y) 419 { 420 421 return (x > y ? x : y); 422 423 } 424 425 inline real64 Pin_real64 (real64 min, real64 x, real64 max) 426 { 427 428 return Max_real64 (min, Min_real64 (x, max)); 429 430 } 431 432 inline real64 Pin_real64 (real64 x) 433 { 434 435 return Pin_real64 (0.0, x, 1.0); 436 437 } 438 439 inline real64 Pin_real64_Overrange (real64 min, 440 real64 x, 441 real64 max) 442 { 443 444 // Normal numbers in (min,max). No change. 445 446 if (x > min && x < max) 447 { 448 return x; 449 } 450 451 // Map large numbers (including positive infinity) to max. 452 453 else if (x > min) 454 { 455 return max; 456 } 457 458 // Map everything else (including negative infinity and all NaNs) to min. 459 460 return min; 461 462 } 463 464 inline real64 Lerp_real64 (real64 a, real64 b, real64 t) 465 { 466 467 return a + t * (b - a); 468 469 } 470 471 /*****************************************************************************/ 472 473 inline int32 Round_int32 (real32 x) 474 { 475 476 return (int32) (x > 0.0f ? x + 0.5f : x - 0.5f); 477 478 } 479 480 inline int32 Round_int32 (real64 x) 481 { 482 483 const real64 temp = x > 0.0 ? x + 0.5 : x - 0.5; 484 485 // NaNs will fail this test (because NaNs compare false against 486 // everything) and will therefore also take the else branch. 487 if (temp > real64(std::numeric_limits<int32>::min()) - 1.0 && 488 temp < real64(std::numeric_limits<int32>::max()) + 1.0) 489 { 490 return (int32) temp; 491 } 492 493 else 494 { 495 ThrowProgramError("Overflow in Round_int32"); 496 // Dummy return. 497 return 0; 498 } 499 500 } 501 502 inline uint32 Floor_uint32 (real32 x) 503 { 504 505 return (uint32) Max_real32 (0.0f, x); 506 507 } 508 509 inline uint32 Floor_uint32 (real64 x) 510 { 511 512 const real64 temp = Max_real64 (0.0, x); 513 514 // NaNs will fail this test (because NaNs compare false against 515 // everything) and will therefore also take the else branch. 516 if (temp < real64(std::numeric_limits<uint32>::max()) + 1.0) 517 { 518 return (uint32) temp; 519 } 520 521 else 522 { 523 ThrowProgramError("Overflow in Floor_uint32"); 524 // Dummy return. 525 return 0; 526 } 527 528 } 529 530 inline uint32 Round_uint32 (real32 x) 531 { 532 533 return Floor_uint32 (x + 0.5f); 534 535 } 536 537 inline uint32 Round_uint32 (real64 x) 538 { 539 540 return Floor_uint32 (x + 0.5); 541 542 } 543 544 /******************************************************************************/ 545 546 inline int64 Round_int64 (real64 x) 547 { 548 549 return (int64) (x >= 0.0 ? x + 0.5 : x - 0.5); 550 551 } 552 553 /*****************************************************************************/ 554 555 const int64 kFixed64_One = (((int64) 1) << 32); 556 const int64 kFixed64_Half = (((int64) 1) << 31); 557 558 /******************************************************************************/ 559 560 inline int64 Real64ToFixed64 (real64 x) 561 { 562 563 return Round_int64 (x * (real64) kFixed64_One); 564 565 } 566 567 /******************************************************************************/ 568 569 inline real64 Fixed64ToReal64 (int64 x) 570 { 571 572 return x * (1.0 / (real64) kFixed64_One); 573 574 } 575 576 /*****************************************************************************/ 577 578 inline char ForceUppercase (char c) 579 { 580 581 if (c >= 'a' && c <= 'z') 582 { 583 584 c -= 'a' - 'A'; 585 586 } 587 588 return c; 589 590 } 591 592 /*****************************************************************************/ 593 594 inline uint16 SwapBytes16 (uint16 x) 595 { 596 597 return (uint16) ((x << 8) | 598 (x >> 8)); 599 600 } 601 602 inline uint32 SwapBytes32 (uint32 x) 603 { 604 605 return (x << 24) + 606 ((x << 8) & 0x00FF0000) + 607 ((x >> 8) & 0x0000FF00) + 608 (x >> 24); 609 610 } 611 612 /*****************************************************************************/ 613 614 inline bool IsAligned16 (const void *p) 615 { 616 617 return (((uintptr) p) & 1) == 0; 618 619 } 620 621 inline bool IsAligned32 (const void *p) 622 { 623 624 return (((uintptr) p) & 3) == 0; 625 626 } 627 628 inline bool IsAligned64 (const void *p) 629 { 630 631 return (((uintptr) p) & 7) == 0; 632 633 } 634 635 inline bool IsAligned128 (const void *p) 636 { 637 638 return (((uintptr) p) & 15) == 0; 639 640 } 641 642 /******************************************************************************/ 643 644 // Converts from RGB values (range 0.0 to 1.0) to HSV values (range 0.0 to 645 // 6.0 for hue, and 0.0 to 1.0 for saturation and value). 646 647 inline void DNG_RGBtoHSV (real32 r, 648 real32 g, 649 real32 b, 650 real32 &h, 651 real32 &s, 652 real32 &v) 653 { 654 655 v = Max_real32 (r, Max_real32 (g, b)); 656 657 real32 gap = v - Min_real32 (r, Min_real32 (g, b)); 658 659 if (gap > 0.0f) 660 { 661 662 if (r == v) 663 { 664 665 h = (g - b) / gap; 666 667 if (h < 0.0f) 668 { 669 h += 6.0f; 670 } 671 672 } 673 674 else if (g == v) 675 { 676 h = 2.0f + (b - r) / gap; 677 } 678 679 else 680 { 681 h = 4.0f + (r - g) / gap; 682 } 683 684 s = gap / v; 685 686 } 687 688 else 689 { 690 h = 0.0f; 691 s = 0.0f; 692 } 693 694 } 695 696 /*****************************************************************************/ 697 698 // Converts from HSV values (range 0.0 to 6.0 for hue, and 0.0 to 1.0 for 699 // saturation and value) to RGB values (range 0.0 to 1.0). 700 701 inline void DNG_HSVtoRGB (real32 h, 702 real32 s, 703 real32 v, 704 real32 &r, 705 real32 &g, 706 real32 &b) 707 { 708 709 if (s > 0.0f) 710 { 711 712 if (!std::isfinite(h)) 713 ThrowProgramError("Unexpected NaN or Inf"); 714 h = std::fmod(h, 6.0f); 715 if (h < 0.0f) 716 h += 6.0f; 717 718 int32 i = (int32) h; 719 real32 f = h - (real32) i; 720 721 real32 p = v * (1.0f - s); 722 723 #define q (v * (1.0f - s * f)) 724 #define t (v * (1.0f - s * (1.0f - f))) 725 726 switch (i) 727 { 728 case 0: r = v; g = t; b = p; break; 729 case 1: r = q; g = v; b = p; break; 730 case 2: r = p; g = v; b = t; break; 731 case 3: r = p; g = q; b = v; break; 732 case 4: r = t; g = p; b = v; break; 733 case 5: r = v; g = p; b = q; break; 734 } 735 736 #undef q 737 #undef t 738 739 } 740 741 else 742 { 743 r = v; 744 g = v; 745 b = v; 746 } 747 748 } 749 750 /******************************************************************************/ 751 752 // High resolution timer, for code profiling. 753 754 real64 TickTimeInSeconds (); 755 756 // Lower resolution timer, but more stable. 757 758 real64 TickCountInSeconds (); 759 760 /******************************************************************************/ 761 762 class dng_timer 763 { 764 765 public: 766 767 dng_timer (const char *message); 768 769 ~dng_timer (); 770 771 private: 772 773 // Hidden copy constructor and assignment operator. 774 775 dng_timer (const dng_timer &timer); 776 777 dng_timer & operator= (const dng_timer &timer); 778 779 private: 780 781 const char *fMessage; 782 783 real64 fStartTime; 784 785 }; 786 787 /*****************************************************************************/ 788 789 // Returns the maximum squared Euclidean distance from the specified point to the 790 // specified rectangle rect. 791 792 real64 MaxSquaredDistancePointToRect (const dng_point_real64 &point, 793 const dng_rect_real64 &rect); 794 795 /*****************************************************************************/ 796 797 // Returns the maximum Euclidean distance from the specified point to the specified 798 // rectangle rect. 799 800 real64 MaxDistancePointToRect (const dng_point_real64 &point, 801 const dng_rect_real64 &rect); 802 803 /*****************************************************************************/ 804 805 inline uint32 DNG_HalfToFloat (uint16 halfValue) 806 { 807 808 int32 sign = (halfValue >> 15) & 0x00000001; 809 int32 exponent = (halfValue >> 10) & 0x0000001f; 810 int32 mantissa = halfValue & 0x000003ff; 811 812 if (exponent == 0) 813 { 814 815 if (mantissa == 0) 816 { 817 818 // Plus or minus zero 819 820 return (uint32) (sign << 31); 821 822 } 823 824 else 825 { 826 827 // Denormalized number -- renormalize it 828 829 while (!(mantissa & 0x00000400)) 830 { 831 mantissa <<= 1; 832 exponent -= 1; 833 } 834 835 exponent += 1; 836 mantissa &= ~0x00000400; 837 838 } 839 840 } 841 842 else if (exponent == 31) 843 { 844 845 if (mantissa == 0) 846 { 847 848 // Positive or negative infinity, convert to maximum (16 bit) values. 849 850 return (uint32) ((sign << 31) | ((0x1eL + 127 - 15) << 23) | (0x3ffL << 13)); 851 852 } 853 854 else 855 { 856 857 // Nan -- Just set to zero. 858 859 return 0; 860 861 } 862 863 } 864 865 // Normalized number 866 867 exponent += (127 - 15); 868 mantissa <<= 13; 869 870 // Assemble sign, exponent and mantissa. 871 872 return (uint32) ((sign << 31) | (exponent << 23) | mantissa); 873 874 } 875 876 /*****************************************************************************/ 877 878 inline uint16 DNG_FloatToHalf (uint32 i) 879 { 880 881 int32 sign = (i >> 16) & 0x00008000; 882 int32 exponent = ((i >> 23) & 0x000000ff) - (127 - 15); 883 int32 mantissa = i & 0x007fffff; 884 885 if (exponent <= 0) 886 { 887 888 if (exponent < -10) 889 { 890 891 // Zero or underflow to zero. 892 893 return (uint16)sign; 894 895 } 896 897 // E is between -10 and 0. We convert f to a denormalized half. 898 899 mantissa = (mantissa | 0x00800000) >> (1 - exponent); 900 901 // Round to nearest, round "0.5" up. 902 // 903 // Rounding may cause the significand to overflow and make 904 // our number normalized. Because of the way a half's bits 905 // are laid out, we don't have to treat this case separately; 906 // the code below will handle it correctly. 907 908 if (mantissa & 0x00001000) 909 mantissa += 0x00002000; 910 911 // Assemble the half from sign, exponent (zero) and mantissa. 912 913 return (uint16)(sign | (mantissa >> 13)); 914 915 } 916 917 else if (exponent == 0xff - (127 - 15)) 918 { 919 920 if (mantissa == 0) 921 { 922 923 // F is an infinity; convert f to a half 924 // infinity with the same sign as f. 925 926 return (uint16)(sign | 0x7c00); 927 928 } 929 930 else 931 { 932 933 // F is a NAN; produce a half NAN that preserves 934 // the sign bit and the 10 leftmost bits of the 935 // significand of f. 936 937 return (uint16)(sign | 0x7c00 | (mantissa >> 13)); 938 939 } 940 941 } 942 943 // E is greater than zero. F is a normalized float. 944 // We try to convert f to a normalized half. 945 946 // Round to nearest, round "0.5" up 947 948 if (mantissa & 0x00001000) 949 { 950 951 mantissa += 0x00002000; 952 953 if (mantissa & 0x00800000) 954 { 955 mantissa = 0; // overflow in significand, 956 exponent += 1; // adjust exponent 957 } 958 959 } 960 961 // Handle exponent overflow 962 963 if (exponent > 30) 964 { 965 return (uint16)(sign | 0x7c00); // infinity with the same sign as f. 966 } 967 968 // Assemble the half from sign, exponent and mantissa. 969 970 return (uint16)(sign | (exponent << 10) | (mantissa >> 13)); 971 972 } 973 974 /*****************************************************************************/ 975 976 inline uint32 DNG_FP24ToFloat (const uint8 *input) 977 { 978 979 int32 sign = (input [0] >> 7) & 0x01; 980 int32 exponent = (input [0] ) & 0x7F; 981 int32 mantissa = (((int32) input [1]) << 8) | input[2]; 982 983 if (exponent == 0) 984 { 985 986 if (mantissa == 0) 987 { 988 989 // Plus or minus zero 990 991 return (uint32) (sign << 31); 992 993 } 994 995 else 996 { 997 998 // Denormalized number -- renormalize it 999 1000 while (!(mantissa & 0x00010000)) 1001 { 1002 mantissa <<= 1; 1003 exponent -= 1; 1004 } 1005 1006 exponent += 1; 1007 mantissa &= ~0x00010000; 1008 1009 } 1010 1011 } 1012 1013 else if (exponent == 127) 1014 { 1015 1016 if (mantissa == 0) 1017 { 1018 1019 // Positive or negative infinity, convert to maximum (24 bit) values. 1020 1021 return (uint32) ((sign << 31) | ((0x7eL + 128 - 64) << 23) | (0xffffL << 7)); 1022 1023 } 1024 1025 else 1026 { 1027 1028 // Nan -- Just set to zero. 1029 1030 return 0; 1031 1032 } 1033 1034 } 1035 1036 // Normalized number 1037 1038 exponent += (128 - 64); 1039 mantissa <<= 7; 1040 1041 // Assemble sign, exponent and mantissa. 1042 1043 return (uint32) ((sign << 31) | (exponent << 23) | mantissa); 1044 1045 } 1046 1047 /*****************************************************************************/ 1048 1049 inline void DNG_FloatToFP24 (uint32 input, uint8 *output) 1050 { 1051 1052 int32 exponent = (int32) ((input >> 23) & 0xFF) - 128; 1053 int32 mantissa = input & 0x007FFFFF; 1054 1055 if (exponent == 127) // infinity or NaN 1056 { 1057 1058 // Will the NaN alais to infinity? 1059 1060 if (mantissa != 0x007FFFFF && ((mantissa >> 7) == 0xFFFF)) 1061 { 1062 1063 mantissa &= 0x003FFFFF; // knock out msb to make it a NaN 1064 1065 } 1066 1067 } 1068 1069 else if (exponent > 63) // overflow, map to infinity 1070 { 1071 1072 exponent = 63; 1073 mantissa = 0x007FFFFF; 1074 1075 } 1076 1077 else if (exponent <= -64) 1078 { 1079 1080 if (exponent >= -79) // encode as denorm 1081 { 1082 mantissa = (mantissa | 0x00800000) >> (-63 - exponent); 1083 } 1084 1085 else // underflow to zero 1086 { 1087 mantissa = 0; 1088 } 1089 1090 exponent = -64; 1091 1092 } 1093 1094 output [0] = (uint8)(((input >> 24) & 0x80) | (uint32) (exponent + 64)); 1095 1096 output [1] = (mantissa >> 15) & 0x00FF; 1097 output [2] = (mantissa >> 7) & 0x00FF; 1098 1099 } 1100 1101 /******************************************************************************/ 1102 1103 // The following code was from PSDivide.h in Photoshop. 1104 1105 // High order 32-bits of an unsigned 32 by 32 multiply. 1106 1107 #ifndef MULUH 1108 1109 #if defined(_X86_) && defined(_MSC_VER) 1110 1111 inline uint32 Muluh86 (uint32 x, uint32 y) 1112 { 1113 uint32 result; 1114 __asm 1115 { 1116 MOV EAX, x 1117 MUL y 1118 MOV result, EDX 1119 } 1120 return (result); 1121 } 1122 1123 #define MULUH Muluh86 1124 1125 #else 1126 1127 #define MULUH(x,y) ((uint32) (((x) * (uint64) (y)) >> 32)) 1128 1129 #endif 1130 1131 #endif 1132 1133 // High order 32-bits of an signed 32 by 32 multiply. 1134 1135 #ifndef MULSH 1136 1137 #if defined(_X86_) && defined(_MSC_VER) 1138 1139 inline int32 Mulsh86 (int32 x, int32 y) 1140 { 1141 int32 result; 1142 __asm 1143 { 1144 MOV EAX, x 1145 IMUL y 1146 MOV result, EDX 1147 } 1148 return (result); 1149 } 1150 1151 #define MULSH Mulsh86 1152 1153 #else 1154 1155 #define MULSH(x,y) ((int32) (((x) * (int64) (y)) >> 32)) 1156 1157 #endif 1158 1159 #endif 1160 1161 /******************************************************************************/ 1162 1163 // Random number generator (identical to Apple's) for portable use. 1164 1165 // This implements the "minimal standard random number generator" 1166 // as proposed by Park and Miller in CACM October, 1988. 1167 // It has a period of 2147483647 (0x7fffffff) 1168 1169 // This is the ACM standard 30 bit generator: 1170 // x' = (x * 16807) mod 2^31-1 1171 // This function intentionally exploits the defined behavior of unsigned integer 1172 // overflow. 1173 #if defined(__clang__) && defined(__has_attribute) 1174 #if __has_attribute(no_sanitize) 1175 __attribute__((no_sanitize("unsigned-integer-overflow"))) 1176 #endif 1177 #endif 1178 inline uint32 DNG_Random (uint32 seed) 1179 { 1180 1181 // high = seed / 127773 1182 1183 uint32 temp = MULUH (0x069C16BD, seed); 1184 uint32 high = (temp + ((seed - temp) >> 1)) >> 16; 1185 1186 // low = seed % 127773 1187 1188 uint32 low = seed - high * 127773; 1189 1190 // seed = (seed * 16807) % 2147483647 1191 1192 seed = 16807 * low - 2836 * high; 1193 1194 if (seed & 0x80000000) 1195 seed += 2147483647; 1196 1197 return seed; 1198 1199 } 1200 1201 /*****************************************************************************/ 1202 1203 class dng_dither 1204 { 1205 1206 public: 1207 1208 static const uint32 kRNGBits = 7; 1209 1210 static const uint32 kRNGSize = 1 << kRNGBits; 1211 1212 static const uint32 kRNGMask = kRNGSize - 1; 1213 1214 static const uint32 kRNGSize2D = kRNGSize * kRNGSize; 1215 1216 private: 1217 1218 dng_memory_data fNoiseBuffer; 1219 1220 private: 1221 1222 dng_dither (); 1223 1224 // Hidden copy constructor and assignment operator. 1225 1226 dng_dither (const dng_dither &); 1227 1228 dng_dither & operator= (const dng_dither &); 1229 1230 public: 1231 1232 static const dng_dither & Get (); 1233 1234 public: 1235 1236 const uint16 *NoiseBuffer16 () const 1237 { 1238 return fNoiseBuffer.Buffer_uint16 (); 1239 } 1240 1241 }; 1242 1243 /*****************************************************************************/ 1244 1245 void HistogramArea (dng_host &host, 1246 const dng_image &image, 1247 const dng_rect &area, 1248 uint32 *hist, 1249 uint32 histLimit, 1250 uint32 plane = 0); 1251 1252 /*****************************************************************************/ 1253 1254 void LimitFloatBitDepth (dng_host &host, 1255 const dng_image &srcImage, 1256 dng_image &dstImage, 1257 uint32 bitDepth, 1258 real32 scale = 1.0f); 1259 1260 /*****************************************************************************/ 1261 1262 #endif 1263 1264 /*****************************************************************************/ 1265