File indexing completed on 2025-01-19 03:55:18
0001 /*****************************************************************************/ 0002 // Copyright 2006-2019 Adobe Systems Incorporated 0003 // All Rights Reserved. 0004 // 0005 // NOTICE: Adobe permits you to use, modify, and distribute this file in 0006 // accordance with the terms of the Adobe license agreement accompanying it. 0007 /*****************************************************************************/ 0008 0009 #ifndef __dng_utils__ 0010 #define __dng_utils__ 0011 0012 /*****************************************************************************/ 0013 0014 #include "dng_classes.h" 0015 #include "dng_flags.h" 0016 #include "dng_memory.h" 0017 #include "dng_safe_arithmetic.h" 0018 #include "dng_types.h" 0019 #include "dng_uncopyable.h" 0020 0021 /*****************************************************************************/ 0022 0023 // The unsigned integer overflow is intended here since a wrap around is used to 0024 // calculate the abs() in the branchless version. 0025 0026 DNG_ATTRIB_NO_SANITIZE("unsigned-integer-overflow") 0027 inline uint32 Abs_int32 (int32 x) 0028 { 0029 0030 #if 0 0031 0032 // Reference version. 0033 0034 return (uint32) (x < 0 ? -x : x); 0035 0036 #else 0037 0038 // Branchless version. 0039 0040 uint32 mask = (uint32) (x >> 31); 0041 0042 return (uint32) (((uint32) x + mask) ^ mask); 0043 0044 #endif 0045 0046 } 0047 0048 inline int32 Min_int32 (int32 x, int32 y) 0049 { 0050 0051 return (x <= y ? x : y); 0052 0053 } 0054 0055 inline int32 Max_int32 (int32 x, int32 y) 0056 { 0057 0058 return (x >= y ? x : y); 0059 0060 } 0061 0062 inline int32 Pin_int32 (int32 min, int32 x, int32 max) 0063 { 0064 0065 return Max_int32 (min, Min_int32 (x, max)); 0066 0067 } 0068 0069 inline int32 Pin_int32_between (int32 a, int32 x, int32 b) 0070 { 0071 0072 int32 min, max; 0073 if (a < b) { min = a; max = b; } 0074 else { min = b; max = a; } 0075 0076 return Pin_int32 (min, x, max); 0077 0078 } 0079 0080 /*****************************************************************************/ 0081 0082 inline uint16 Min_uint16 (uint16 x, uint16 y) 0083 { 0084 0085 return (x <= y ? x : y); 0086 0087 } 0088 0089 inline uint16 Max_uint16 (uint16 x, uint16 y) 0090 { 0091 0092 return (x >= y ? x : y); 0093 0094 } 0095 0096 inline int16 Pin_int16 (int32 x) 0097 { 0098 0099 x = Pin_int32 (-32768, x, 32767); 0100 0101 return (int16) x; 0102 0103 } 0104 0105 /*****************************************************************************/ 0106 0107 inline uint32 Min_uint32 (uint32 x, uint32 y) 0108 { 0109 0110 return (x <= y ? x : y); 0111 0112 } 0113 0114 inline uint32 Min_uint32 (uint32 x, uint32 y, uint32 z) 0115 { 0116 0117 return Min_uint32 (x, Min_uint32 (y, z)); 0118 0119 } 0120 0121 inline uint32 Max_uint32 (uint32 x, uint32 y) 0122 { 0123 0124 return (x >= y ? x : y); 0125 0126 } 0127 0128 inline uint32 Max_uint32 (uint32 x, uint32 y, uint32 z) 0129 { 0130 0131 return Max_uint32 (x, Max_uint32 (y, z)); 0132 0133 } 0134 0135 inline uint32 Pin_uint32 (uint32 min, uint32 x, uint32 max) 0136 { 0137 0138 return Max_uint32 (min, Min_uint32 (x, max)); 0139 0140 } 0141 0142 /*****************************************************************************/ 0143 0144 inline uint16 Pin_uint16 (int32 x) 0145 { 0146 0147 #if 0 0148 0149 // Reference version. 0150 0151 x = Pin_int32 (0, x, 0x0FFFF); 0152 0153 #else 0154 0155 // Single branch version. 0156 0157 if (x & ~65535) 0158 { 0159 0160 x = ~x >> 31; 0161 0162 } 0163 0164 #endif 0165 0166 return (uint16) x; 0167 0168 } 0169 0170 /*****************************************************************************/ 0171 0172 inline uint32 RoundUp2 (uint32 x) 0173 { 0174 0175 return (x + 1) & (uint32) ~1; 0176 0177 } 0178 0179 inline uint32 RoundUp4 (uint32 x) 0180 { 0181 0182 return (x + 3) & (uint32) ~3; 0183 0184 } 0185 0186 inline uint32 RoundUp8 (uint32 x) 0187 { 0188 0189 return (x + 7) & (uint32) ~7; 0190 0191 } 0192 0193 inline uint32 RoundUp16 (uint32 x) 0194 { 0195 0196 return (x + 15) & (uint32) ~15; 0197 0198 } 0199 0200 inline uint32 RoundUp32 (uint32 x) 0201 { 0202 0203 return (x + 31) & (uint32) ~31; 0204 0205 } 0206 0207 inline uint32 RoundUpSIMD (uint32 x) 0208 { 0209 0210 #if qDNGAVXSupport 0211 return RoundUp32 (x); 0212 #else 0213 return RoundUp16 (x); 0214 #endif 0215 0216 } 0217 0218 inline uint32 RoundUp4096 (uint32 x) 0219 { 0220 0221 return (x + 4095) & (uint32) ~4095; 0222 0223 } 0224 0225 /******************************************************************************/ 0226 0227 inline uint32 RoundDown2 (uint32 x) 0228 { 0229 0230 return x & (uint32) ~1; 0231 0232 } 0233 0234 inline uint32 RoundDown4 (uint32 x) 0235 { 0236 0237 return x & (uint32) ~3; 0238 0239 } 0240 0241 inline uint32 RoundDown8 (uint32 x) 0242 { 0243 0244 return x & (uint32) ~7; 0245 0246 } 0247 0248 inline uint32 RoundDown16 (uint32 x) 0249 { 0250 0251 return x & (uint32) ~15; 0252 0253 } 0254 0255 inline uint32 RoundDown32 (uint32 x) 0256 { 0257 0258 return x & (uint32) ~31; 0259 0260 } 0261 0262 inline uint32 RoundDownSIMD (uint32 x) 0263 { 0264 0265 #if qDNGAVXSupport 0266 return RoundDown32 (x); 0267 #else 0268 return RoundDown16 (x); 0269 #endif 0270 0271 } 0272 0273 /******************************************************************************/ 0274 0275 inline bool RoundUpForPixelSize (uint32 x, 0276 uint32 pixelSize, 0277 uint32 *result) 0278 { 0279 0280 #if qDNGAVXSupport 0281 static const uint32 kTargetMultiple = 32; 0282 #else 0283 static const uint32 kTargetMultiple = 16; 0284 #endif 0285 0286 uint32 multiple; 0287 0288 switch (pixelSize) 0289 { 0290 0291 case 1: 0292 case 2: 0293 case 4: 0294 case 8: 0295 { 0296 multiple = kTargetMultiple / pixelSize; 0297 break; 0298 } 0299 0300 default: 0301 { 0302 multiple = kTargetMultiple; 0303 break; 0304 } 0305 0306 } 0307 0308 return RoundUpUint32ToMultiple (x, multiple, result); 0309 0310 } 0311 0312 /******************************************************************************/ 0313 0314 inline uint32 RoundUpForPixelSize (uint32 x, 0315 uint32 pixelSize) 0316 { 0317 0318 uint32 result = 0; 0319 0320 if (!RoundUpForPixelSize (x, pixelSize, &result)) 0321 { 0322 ThrowOverflow ("RoundUpForPixelSize"); 0323 } 0324 0325 return result; 0326 0327 } 0328 0329 /******************************************************************************/ 0330 0331 inline int32 RoundUpForPixelSizeAsInt32 (uint32 x, 0332 uint32 pixelSize) 0333 { 0334 0335 uint32 result = 0; 0336 0337 if (!RoundUpForPixelSize (x, pixelSize, &result)) 0338 { 0339 ThrowOverflow ("RoundUpForPixelSize"); 0340 } 0341 0342 dng_safe_uint32 safeResult (result); 0343 0344 return dng_safe_int32 (safeResult).Get (); 0345 0346 } 0347 0348 /******************************************************************************/ 0349 0350 // Type of padding to be performed by ComputeBufferSize. 0351 0352 enum PaddingType 0353 { 0354 0355 // Don't perform any padding. 0356 0357 padNone, 0358 0359 // Pad each scanline to an integer multiple of SIMD vector width (16 or 0360 // 32) bytes (in the same way that RoundUpForPixelSize() does). 0361 0362 padSIMDBytes 0363 0364 }; 0365 0366 // Returns the number of bytes required for an image tile with the given pixel 0367 // type, tile size, number of image planes, and desired padding. Throws a 0368 // dng_exception with dng_error_memory error code if one of the components of 0369 // tileSize is negative or if arithmetic overflow occurs during the 0370 // computation. 0371 0372 uint32 ComputeBufferSize (uint32 pixelType, 0373 const dng_point &tileSize, 0374 uint32 numPlanes, 0375 PaddingType paddingType); 0376 0377 /******************************************************************************/ 0378 0379 inline uint64 Abs_int64 (int64 x) 0380 { 0381 0382 return (uint64) (x < 0 ? -x : x); 0383 0384 } 0385 0386 inline int64 Min_int64 (int64 x, int64 y) 0387 { 0388 0389 return (x <= y ? x : y); 0390 0391 } 0392 0393 inline int64 Max_int64 (int64 x, int64 y) 0394 { 0395 0396 return (x >= y ? x : y); 0397 0398 } 0399 0400 inline int64 Pin_int64 (int64 min, int64 x, int64 max) 0401 { 0402 0403 return Max_int64 (min, Min_int64 (x, max)); 0404 0405 } 0406 0407 /******************************************************************************/ 0408 0409 inline uint64 Min_uint64 (uint64 x, uint64 y) 0410 { 0411 0412 return (x <= y ? x : y); 0413 0414 } 0415 0416 inline uint64 Max_uint64 (uint64 x, uint64 y) 0417 { 0418 0419 return (x >= y ? x : y); 0420 0421 } 0422 0423 inline uint64 Pin_uint64 (uint64 min, uint64 x, uint64 max) 0424 { 0425 0426 return Max_uint64 (min, Min_uint64 (x, max)); 0427 0428 } 0429 0430 /*****************************************************************************/ 0431 0432 inline real32 Abs_real32 (real32 x) 0433 { 0434 0435 return (x < 0.0f ? -x : x); 0436 0437 } 0438 0439 inline real32 Min_real32 (real32 x, real32 y) 0440 { 0441 0442 return (x < y ? x : y); 0443 0444 } 0445 0446 inline real32 Max_real32 (real32 x, real32 y) 0447 { 0448 0449 return (x > y ? x : y); 0450 0451 } 0452 0453 inline real32 Pin_real32 (real32 min, real32 x, real32 max) 0454 { 0455 0456 return Max_real32 (min, Min_real32 (x, max)); 0457 0458 } 0459 0460 inline real32 Pin_real32 (real32 x) 0461 { 0462 0463 return Pin_real32 (0.0f, x, 1.0f); 0464 0465 } 0466 0467 inline real32 Pin_real32_Overrange (real32 min, 0468 real32 x, 0469 real32 max) 0470 { 0471 0472 // Normal numbers in (min,max). No change. 0473 0474 if (x > min && x < max) 0475 { 0476 return x; 0477 } 0478 0479 // Map large numbers (including positive infinity) to max. 0480 0481 else if (x > min) 0482 { 0483 return max; 0484 } 0485 0486 // Map everything else (including negative infinity and all NaNs) to min. 0487 0488 return min; 0489 0490 } 0491 0492 inline real32 Pin_Overrange (real32 x) 0493 { 0494 0495 // Normal in-range numbers, except for plus and minus zero. 0496 0497 if (x > 0.0f && x <= 1.0f) 0498 { 0499 return x; 0500 } 0501 0502 // Large numbers, including positive infinity. 0503 0504 else if (x > 0.5f) 0505 { 0506 return 1.0f; 0507 } 0508 0509 // Plus and minus zero, negative numbers, negative infinity, and all NaNs. 0510 0511 return 0.0f; 0512 0513 } 0514 0515 inline real32 Lerp_real32 (real32 a, real32 b, real32 t) 0516 { 0517 0518 return a + t * (b - a); 0519 0520 } 0521 0522 /*****************************************************************************/ 0523 0524 inline real64 Abs_real64 (real64 x) 0525 { 0526 0527 return (x < 0.0 ? -x : x); 0528 0529 } 0530 0531 inline real64 Min_real64 (real64 x, real64 y) 0532 { 0533 0534 return (x < y ? x : y); 0535 0536 } 0537 0538 inline real64 Max_real64 (real64 x, real64 y) 0539 { 0540 0541 return (x > y ? x : y); 0542 0543 } 0544 0545 inline real64 Pin_real64 (real64 min, real64 x, real64 max) 0546 { 0547 0548 return Max_real64 (min, Min_real64 (x, max)); 0549 0550 } 0551 0552 inline real64 Pin_real64 (real64 x) 0553 { 0554 0555 return Pin_real64 (0.0, x, 1.0); 0556 0557 } 0558 0559 inline real64 Pin_real64_Overrange (real64 min, 0560 real64 x, 0561 real64 max) 0562 { 0563 0564 // Normal numbers in (min,max). No change. 0565 0566 if (x > min && x < max) 0567 { 0568 return x; 0569 } 0570 0571 // Map large numbers (including positive infinity) to max. 0572 0573 else if (x > min) 0574 { 0575 return max; 0576 } 0577 0578 // Map everything else (including negative infinity and all NaNs) to min. 0579 0580 return min; 0581 0582 } 0583 0584 inline real64 Lerp_real64 (real64 a, real64 b, real64 t) 0585 { 0586 0587 return a + t * (b - a); 0588 0589 } 0590 0591 /*****************************************************************************/ 0592 0593 inline int32 Round_int32 (real32 x) 0594 { 0595 0596 return (int32) (x > 0.0f ? x + 0.5f : x - 0.5f); 0597 0598 } 0599 0600 inline int32 Round_int32 (real64 x) 0601 { 0602 0603 return (int32) (x > 0.0 ? x + 0.5 : x - 0.5); 0604 0605 } 0606 0607 inline uint32 Floor_uint32 (real32 x) 0608 { 0609 0610 return (uint32) Max_real32 (0.0f, x); 0611 0612 } 0613 0614 DNG_ATTRIB_NO_SANITIZE("float-cast-overflow") 0615 inline uint32 Floor_uint32 (real64 x) 0616 { 0617 0618 return (uint32) Max_real64 (0.0, x); 0619 0620 } 0621 0622 inline uint32 Round_uint32 (real32 x) 0623 { 0624 0625 return Floor_uint32 (x + 0.5f); 0626 0627 } 0628 0629 inline uint32 Round_uint32 (real64 x) 0630 { 0631 0632 return Floor_uint32 (x + 0.5); 0633 0634 } 0635 0636 /******************************************************************************/ 0637 0638 inline int64 Round_int64 (real64 x) 0639 { 0640 0641 return (int64) (x >= 0.0 ? x + 0.5 : x - 0.5); 0642 0643 } 0644 0645 /*****************************************************************************/ 0646 0647 const int64 kFixed64_One = (((int64) 1) << 32); 0648 const int64 kFixed64_Half = (((int64) 1) << 31); 0649 0650 /******************************************************************************/ 0651 0652 inline int64 Real64ToFixed64 (real64 x) 0653 { 0654 0655 return Round_int64 (x * (real64) kFixed64_One); 0656 0657 } 0658 0659 /******************************************************************************/ 0660 0661 inline real64 Fixed64ToReal64 (int64 x) 0662 { 0663 0664 return x * (1.0 / (real64) kFixed64_One); 0665 0666 } 0667 0668 /*****************************************************************************/ 0669 0670 inline char ForceUppercase (char c) 0671 { 0672 0673 if (c >= 'a' && c <= 'z') 0674 { 0675 0676 c -= 'a' - 'A'; 0677 0678 } 0679 0680 return c; 0681 0682 } 0683 0684 /*****************************************************************************/ 0685 0686 inline uint16 SwapBytes16 (uint16 x) 0687 { 0688 0689 return (uint16) ((x << 8) | 0690 (x >> 8)); 0691 0692 } 0693 0694 inline uint32 SwapBytes32 (uint32 x) 0695 { 0696 0697 return (x << 24) + 0698 ((x << 8) & 0x00FF0000) + 0699 ((x >> 8) & 0x0000FF00) + 0700 (x >> 24); 0701 0702 } 0703 0704 /*****************************************************************************/ 0705 0706 inline bool IsAligned16 (const void *p) 0707 { 0708 0709 return (((uintptr) p) & 1) == 0; 0710 0711 } 0712 0713 inline bool IsAligned32 (const void *p) 0714 { 0715 0716 return (((uintptr) p) & 3) == 0; 0717 0718 } 0719 0720 inline bool IsAligned64 (const void *p) 0721 { 0722 0723 return (((uintptr) p) & 7) == 0; 0724 0725 } 0726 0727 inline bool IsAligned128 (const void *p) 0728 { 0729 0730 return (((uintptr) p) & 15) == 0; 0731 0732 } 0733 0734 /******************************************************************************/ 0735 0736 // Converts from RGB values (range 0.0 to 1.0) to HSV values (range 0.0 to 0737 // 6.0 for hue, and 0.0 to 1.0 for saturation and value). 0738 0739 inline void DNG_RGBtoHSV (real32 r, 0740 real32 g, 0741 real32 b, 0742 real32 &h, 0743 real32 &s, 0744 real32 &v) 0745 { 0746 0747 v = Max_real32 (r, Max_real32 (g, b)); 0748 0749 real32 gap = v - Min_real32 (r, Min_real32 (g, b)); 0750 0751 if (gap > 0.0f) 0752 { 0753 0754 if (r == v) 0755 { 0756 0757 h = (g - b) / gap; 0758 0759 if (h < 0.0f) 0760 { 0761 h += 6.0f; 0762 } 0763 0764 } 0765 0766 else if (g == v) 0767 { 0768 h = 2.0f + (b - r) / gap; 0769 } 0770 0771 else 0772 { 0773 h = 4.0f + (r - g) / gap; 0774 } 0775 0776 s = gap / v; 0777 0778 } 0779 0780 else 0781 { 0782 h = 0.0f; 0783 s = 0.0f; 0784 } 0785 0786 } 0787 0788 /*****************************************************************************/ 0789 0790 // Converts from HSV values (range 0.0 to 6.0 for hue, and 0.0 to 1.0 for 0791 // saturation and value) to RGB values (range 0.0 to 1.0). 0792 0793 inline void DNG_HSVtoRGB (real32 h, 0794 real32 s, 0795 real32 v, 0796 real32 &r, 0797 real32 &g, 0798 real32 &b) 0799 { 0800 0801 if (s > 0.0f) 0802 { 0803 0804 if (h < 0.0f) 0805 h += 6.0f; 0806 0807 if (h >= 6.0f) 0808 h -= 6.0f; 0809 0810 int32 i = (int32) h; 0811 real32 f = h - (real32) i; 0812 0813 real32 p = v * (1.0f - s); 0814 0815 #define q (v * (1.0f - s * f)) 0816 #define t (v * (1.0f - s * (1.0f - f))) 0817 0818 switch (i) 0819 { 0820 case 0: r = v; g = t; b = p; break; 0821 case 1: r = q; g = v; b = p; break; 0822 case 2: r = p; g = v; b = t; break; 0823 case 3: r = p; g = q; b = v; break; 0824 case 4: r = t; g = p; b = v; break; 0825 case 5: r = v; g = p; b = q; break; 0826 } 0827 0828 #undef q 0829 #undef t 0830 0831 } 0832 0833 else 0834 { 0835 r = v; 0836 g = v; 0837 b = v; 0838 } 0839 0840 } 0841 0842 /******************************************************************************/ 0843 0844 // High resolution timer, for code profiling. 0845 0846 real64 TickTimeInSeconds (); 0847 0848 // Lower resolution timer, but more stable. 0849 0850 real64 TickCountInSeconds (); 0851 0852 /******************************************************************************/ 0853 0854 void DNGIncrementTimerLevel (); 0855 0856 int32 DNGDecrementTimerLevel (); 0857 0858 /******************************************************************************/ 0859 0860 class dng_timer: private dng_uncopyable 0861 { 0862 0863 public: 0864 0865 dng_timer (const char *message); 0866 0867 ~dng_timer (); 0868 0869 private: 0870 0871 const char *fMessage; 0872 0873 real64 fStartTime; 0874 0875 }; 0876 0877 /*****************************************************************************/ 0878 0879 // Returns the maximum squared Euclidean distance from the specified point to the 0880 // specified rectangle rect. 0881 0882 real64 MaxSquaredDistancePointToRect (const dng_point_real64 &point, 0883 const dng_rect_real64 &rect); 0884 0885 /*****************************************************************************/ 0886 0887 // Returns the maximum Euclidean distance from the specified point to the specified 0888 // rectangle rect. 0889 0890 real64 MaxDistancePointToRect (const dng_point_real64 &point, 0891 const dng_rect_real64 &rect); 0892 0893 /*****************************************************************************/ 0894 0895 inline uint32 DNG_HalfToFloat (uint16 halfValue) 0896 { 0897 0898 int32 sign = (halfValue >> 15) & 0x00000001; 0899 int32 exponent = (halfValue >> 10) & 0x0000001f; 0900 int32 mantissa = halfValue & 0x000003ff; 0901 0902 if (exponent == 0) 0903 { 0904 0905 if (mantissa == 0) 0906 { 0907 0908 // Plus or minus zero 0909 0910 return (uint32) (sign << 31); 0911 0912 } 0913 0914 else 0915 { 0916 0917 // Denormalized number -- renormalize it 0918 0919 while (!(mantissa & 0x00000400)) 0920 { 0921 mantissa <<= 1; 0922 exponent -= 1; 0923 } 0924 0925 exponent += 1; 0926 mantissa &= ~0x00000400; 0927 0928 } 0929 0930 } 0931 0932 else if (exponent == 31) 0933 { 0934 0935 if (mantissa == 0) 0936 { 0937 0938 // Positive or negative infinity, convert to maximum (16 bit) values. 0939 0940 return (uint32) ((sign << 31) | ((0x1eL + 127 - 15) << 23) | (0x3ffL << 13)); 0941 0942 } 0943 0944 else 0945 { 0946 0947 // Nan -- Just set to zero. 0948 0949 return 0; 0950 0951 } 0952 0953 } 0954 0955 // Normalized number 0956 0957 exponent += (127 - 15); 0958 mantissa <<= 13; 0959 0960 // Assemble sign, exponent and mantissa. 0961 0962 return (uint32) ((sign << 31) | (exponent << 23) | mantissa); 0963 0964 } 0965 0966 /*****************************************************************************/ 0967 0968 inline uint16 DNG_FloatToHalf (uint32 i) 0969 { 0970 0971 int32 sign = (i >> 16) & 0x00008000; 0972 int32 exponent = ((i >> 23) & 0x000000ff) - (127 - 15); 0973 int32 mantissa = i & 0x007fffff; 0974 0975 if (exponent <= 0) 0976 { 0977 0978 if (exponent < -10) 0979 { 0980 0981 // Zero or underflow to zero. 0982 0983 return (uint16)sign; 0984 0985 } 0986 0987 // E is between -10 and 0. We convert f to a denormalized half. 0988 0989 mantissa = (mantissa | 0x00800000) >> (1 - exponent); 0990 0991 // Round to nearest, round "0.5" up. 0992 // 0993 // Rounding may cause the significand to overflow and make 0994 // our number normalized. Because of the way a half's bits 0995 // are laid out, we don't have to treat this case separately; 0996 // the code below will handle it correctly. 0997 0998 if (mantissa & 0x00001000) 0999 mantissa += 0x00002000; 1000 1001 // Assemble the half from sign, exponent (zero) and mantissa. 1002 1003 return (uint16)(sign | (mantissa >> 13)); 1004 1005 } 1006 1007 else if (exponent == 0xff - (127 - 15)) 1008 { 1009 1010 if (mantissa == 0) 1011 { 1012 1013 // F is an infinity; convert f to a half 1014 // infinity with the same sign as f. 1015 1016 return (uint16)(sign | 0x7c00); 1017 1018 } 1019 1020 else 1021 { 1022 1023 // F is a NAN; produce a half NAN that preserves 1024 // the sign bit and the 10 leftmost bits of the 1025 // significand of f. 1026 1027 return (uint16)(sign | 0x7c00 | (mantissa >> 13)); 1028 1029 } 1030 1031 } 1032 1033 // E is greater than zero. F is a normalized float. 1034 // We try to convert f to a normalized half. 1035 1036 // Round to nearest, round "0.5" up 1037 1038 if (mantissa & 0x00001000) 1039 { 1040 1041 mantissa += 0x00002000; 1042 1043 if (mantissa & 0x00800000) 1044 { 1045 mantissa = 0; // overflow in significand, 1046 exponent += 1; // adjust exponent 1047 } 1048 1049 } 1050 1051 // Handle exponent overflow 1052 1053 if (exponent > 30) 1054 { 1055 return (uint16)(sign | 0x7c00); // infinity with the same sign as f. 1056 } 1057 1058 // Assemble the half from sign, exponent and mantissa. 1059 1060 return (uint16)(sign | (exponent << 10) | (mantissa >> 13)); 1061 1062 } 1063 1064 /*****************************************************************************/ 1065 1066 inline uint32 DNG_FP24ToFloat (const uint8 *input) 1067 { 1068 1069 int32 sign = (input [0] >> 7) & 0x01; 1070 int32 exponent = (input [0] ) & 0x7F; 1071 int32 mantissa = (((int32) input [1]) << 8) | input[2]; 1072 1073 if (exponent == 0) 1074 { 1075 1076 if (mantissa == 0) 1077 { 1078 1079 // Plus or minus zero 1080 1081 return (uint32) (sign << 31); 1082 1083 } 1084 1085 else 1086 { 1087 1088 // Denormalized number -- renormalize it 1089 1090 while (!(mantissa & 0x00010000)) 1091 { 1092 mantissa <<= 1; 1093 exponent -= 1; 1094 } 1095 1096 exponent += 1; 1097 mantissa &= ~0x00010000; 1098 1099 } 1100 1101 } 1102 1103 else if (exponent == 127) 1104 { 1105 1106 if (mantissa == 0) 1107 { 1108 1109 // Positive or negative infinity, convert to maximum (24 bit) values. 1110 1111 return (uint32) ((sign << 31) | ((0x7eL + 128 - 64) << 23) | (0xffffL << 7)); 1112 1113 } 1114 1115 else 1116 { 1117 1118 // Nan -- Just set to zero. 1119 1120 return 0; 1121 1122 } 1123 1124 } 1125 1126 // Normalized number 1127 1128 exponent += (128 - 64); 1129 mantissa <<= 7; 1130 1131 // Assemble sign, exponent and mantissa. 1132 1133 return (uint32) ((sign << 31) | (exponent << 23) | mantissa); 1134 1135 } 1136 1137 /*****************************************************************************/ 1138 1139 inline void DNG_FloatToFP24 (uint32 input, uint8 *output) 1140 { 1141 1142 int32 exponent = (int32) ((input >> 23) & 0xFF) - 128; 1143 int32 mantissa = input & 0x007FFFFF; 1144 1145 if (exponent == 127) // infinity or NaN 1146 { 1147 1148 // Will the NaN alais to infinity? 1149 1150 if (mantissa != 0x007FFFFF && ((mantissa >> 7) == 0xFFFF)) 1151 { 1152 1153 mantissa &= 0x003FFFFF; // knock out msb to make it a NaN 1154 1155 } 1156 1157 } 1158 1159 else if (exponent > 63) // overflow, map to infinity 1160 { 1161 1162 exponent = 63; 1163 mantissa = 0x007FFFFF; 1164 1165 } 1166 1167 else if (exponent <= -64) 1168 { 1169 1170 if (exponent >= -79) // encode as denorm 1171 { 1172 mantissa = (mantissa | 0x00800000) >> (-63 - exponent); 1173 } 1174 1175 else // underflow to zero 1176 { 1177 mantissa = 0; 1178 } 1179 1180 exponent = -64; 1181 1182 } 1183 1184 output [0] = (uint8)(((input >> 24) & 0x80) | (uint32) (exponent + 64)); 1185 1186 output [1] = (mantissa >> 15) & 0x00FF; 1187 output [2] = (mantissa >> 7) & 0x00FF; 1188 1189 } 1190 1191 /******************************************************************************/ 1192 1193 // The following code was from PSDivide.h in Photoshop. 1194 1195 // High order 32-bits of an unsigned 32 by 32 multiply. 1196 1197 #ifndef MULUH 1198 1199 #if defined(_X86_) && defined(_MSC_VER) 1200 1201 inline uint32 Muluh86 (uint32 x, uint32 y) 1202 { 1203 uint32 result; 1204 __asm 1205 { 1206 MOV EAX, x 1207 MUL y 1208 MOV result, EDX 1209 } 1210 return (result); 1211 } 1212 1213 #define MULUH Muluh86 1214 1215 #else 1216 1217 #define MULUH(x,y) ((uint32) (((x) * (uint64) (y)) >> 32)) 1218 1219 #endif 1220 1221 #endif 1222 1223 // High order 32-bits of an signed 32 by 32 multiply. 1224 1225 #ifndef MULSH 1226 1227 #if defined(_X86_) && defined(_MSC_VER) 1228 1229 inline int32 Mulsh86 (int32 x, int32 y) 1230 { 1231 int32 result; 1232 __asm 1233 { 1234 MOV EAX, x 1235 IMUL y 1236 MOV result, EDX 1237 } 1238 return (result); 1239 } 1240 1241 #define MULSH Mulsh86 1242 1243 #else 1244 1245 #define MULSH(x,y) ((int32) (((x) * (int64) (y)) >> 32)) 1246 1247 #endif 1248 1249 #endif 1250 1251 /******************************************************************************/ 1252 1253 // Random number generator (identical to Apple's) for portable use. 1254 1255 // This implements the "minimal standard random number generator" 1256 // as proposed by Park and Miller in CACM October, 1988. 1257 // It has a period of 2147483647 (0x7fffffff) 1258 1259 // This is the ACM standard 30 bit generator: 1260 // x' = (x * 16807) mod 2^31-1 1261 1262 DNG_ATTRIB_NO_SANITIZE("unsigned-integer-overflow") 1263 inline uint32 DNG_Random (uint32 seed) 1264 { 1265 1266 // high = seed / 127773 1267 1268 uint32 temp = MULUH (0x069C16BD, seed); 1269 uint32 high = (temp + ((seed - temp) >> 1)) >> 16; 1270 1271 // low = seed % 127773 1272 1273 uint32 low = seed - high * 127773; 1274 1275 // seed = (seed * 16807) % 2147483647 1276 1277 seed = 16807 * low - 2836 * high; 1278 1279 if (seed & 0x80000000) 1280 seed += 2147483647; 1281 1282 return seed; 1283 1284 } 1285 1286 /*****************************************************************************/ 1287 1288 class dng_dither: private dng_uncopyable 1289 { 1290 1291 public: 1292 1293 static const uint32 kRNGBits = 7; 1294 1295 static const uint32 kRNGSize = 1 << kRNGBits; 1296 1297 static const uint32 kRNGMask = kRNGSize - 1; 1298 1299 static const uint32 kRNGSize2D = kRNGSize * kRNGSize; 1300 1301 private: 1302 1303 dng_memory_data fNoiseBuffer; 1304 1305 private: 1306 1307 dng_dither (); 1308 1309 public: 1310 1311 static const dng_dither & Get (); 1312 1313 public: 1314 1315 const uint16 *NoiseBuffer16 () const 1316 { 1317 return fNoiseBuffer.Buffer_uint16 (); 1318 } 1319 1320 }; 1321 1322 /*****************************************************************************/ 1323 1324 void HistogramArea (dng_host &host, 1325 const dng_image &image, 1326 const dng_rect &area, 1327 uint32 *hist, 1328 uint32 histLimit, 1329 uint32 plane = 0); 1330 1331 /*****************************************************************************/ 1332 1333 void LimitFloatBitDepth (dng_host &host, 1334 const dng_image &srcImage, 1335 dng_image &dstImage, 1336 uint32 bitDepth, 1337 real32 scale = 1.0f); 1338 1339 /*****************************************************************************/ 1340 1341 #if qMacOS 1342 1343 /*****************************************************************************/ 1344 1345 template<typename T> 1346 class CFReleaseHelper 1347 { 1348 1349 private: 1350 1351 T fRef; 1352 1353 public: 1354 1355 CFReleaseHelper (T ref) 1356 : fRef (ref) 1357 { 1358 } 1359 1360 ~CFReleaseHelper () 1361 { 1362 if (fRef) 1363 { 1364 CFRelease (fRef); 1365 } 1366 } 1367 1368 T Get () const 1369 { 1370 return fRef; 1371 } 1372 1373 }; 1374 1375 /*****************************************************************************/ 1376 1377 #endif // qMacOS 1378 1379 /*****************************************************************************/ 1380 1381 #endif 1382 1383 /*****************************************************************************/