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
Abs_int32(int32 x)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
Min_int32(int32 x,int32 y)60 inline int32 Min_int32 (int32 x, int32 y)
61 {
62
63 return (x <= y ? x : y);
64
65 }
66
Max_int32(int32 x,int32 y)67 inline int32 Max_int32 (int32 x, int32 y)
68 {
69
70 return (x >= y ? x : y);
71
72 }
73
Pin_int32(int32 min,int32 x,int32 max)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
Pin_int32_between(int32 a,int32 x,int32 b)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
Min_uint16(uint16 x,uint16 y)94 inline uint16 Min_uint16 (uint16 x, uint16 y)
95 {
96
97 return (x <= y ? x : y);
98
99 }
100
Max_uint16(uint16 x,uint16 y)101 inline uint16 Max_uint16 (uint16 x, uint16 y)
102 {
103
104 return (x >= y ? x : y);
105
106 }
107
Pin_int16(int32 x)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
Min_uint32(uint32 x,uint32 y)119 inline uint32 Min_uint32 (uint32 x, uint32 y)
120 {
121
122 return (x <= y ? x : y);
123
124 }
125
Min_uint32(uint32 x,uint32 y,uint32 z)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
Max_uint32(uint32 x,uint32 y)133 inline uint32 Max_uint32 (uint32 x, uint32 y)
134 {
135
136 return (x >= y ? x : y);
137
138 }
139
Max_uint32(uint32 x,uint32 y,uint32 z)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
Pin_uint32(uint32 min,uint32 x,uint32 max)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
Pin_uint16(int32 x)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
RoundDown2(uint32 x)184 inline uint32 RoundDown2 (uint32 x)
185 {
186
187 return x & (uint32) ~1;
188
189 }
190
RoundDown4(uint32 x)191 inline uint32 RoundDown4 (uint32 x)
192 {
193
194 return x & (uint32) ~3;
195
196 }
197
RoundDown8(uint32 x)198 inline uint32 RoundDown8 (uint32 x)
199 {
200
201 return x & (uint32) ~7;
202
203 }
204
RoundDown16(uint32 x)205 inline uint32 RoundDown16 (uint32 x)
206 {
207
208 return x & (uint32) ~15;
209
210 }
211
212 /******************************************************************************/
213
RoundUpForPixelSize(uint32 x,uint32 pixelSize,uint32 * result)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
Abs_int64(int64 x)259 inline uint64 Abs_int64 (int64 x)
260 {
261
262 return (uint64) (x < 0 ? -x : x);
263
264 }
265
Min_int64(int64 x,int64 y)266 inline int64 Min_int64 (int64 x, int64 y)
267 {
268
269 return (x <= y ? x : y);
270
271 }
272
Max_int64(int64 x,int64 y)273 inline int64 Max_int64 (int64 x, int64 y)
274 {
275
276 return (x >= y ? x : y);
277
278 }
279
Pin_int64(int64 min,int64 x,int64 max)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
Min_uint64(uint64 x,uint64 y)289 inline uint64 Min_uint64 (uint64 x, uint64 y)
290 {
291
292 return (x <= y ? x : y);
293
294 }
295
Max_uint64(uint64 x,uint64 y)296 inline uint64 Max_uint64 (uint64 x, uint64 y)
297 {
298
299 return (x >= y ? x : y);
300
301 }
302
Pin_uint64(uint64 min,uint64 x,uint64 max)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
Abs_real32(real32 x)312 inline real32 Abs_real32 (real32 x)
313 {
314
315 return (x < 0.0f ? -x : x);
316
317 }
318
Min_real32(real32 x,real32 y)319 inline real32 Min_real32 (real32 x, real32 y)
320 {
321
322 return (x < y ? x : y);
323
324 }
325
Max_real32(real32 x,real32 y)326 inline real32 Max_real32 (real32 x, real32 y)
327 {
328
329 return (x > y ? x : y);
330
331 }
332
Pin_real32(real32 min,real32 x,real32 max)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
Pin_real32(real32 x)340 inline real32 Pin_real32 (real32 x)
341 {
342
343 return Pin_real32 (0.0f, x, 1.0f);
344
345 }
346
Pin_real32_Overrange(real32 min,real32 x,real32 max)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
Pin_Overrange(real32 x)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
Lerp_real32(real32 a,real32 b,real32 t)395 inline real32 Lerp_real32 (real32 a, real32 b, real32 t)
396 {
397
398 return a + t * (b - a);
399
400 }
401
402 /*****************************************************************************/
403
Abs_real64(real64 x)404 inline real64 Abs_real64 (real64 x)
405 {
406
407 return (x < 0.0 ? -x : x);
408
409 }
410
Min_real64(real64 x,real64 y)411 inline real64 Min_real64 (real64 x, real64 y)
412 {
413
414 return (x < y ? x : y);
415
416 }
417
Max_real64(real64 x,real64 y)418 inline real64 Max_real64 (real64 x, real64 y)
419 {
420
421 return (x > y ? x : y);
422
423 }
424
Pin_real64(real64 min,real64 x,real64 max)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
Pin_real64(real64 x)432 inline real64 Pin_real64 (real64 x)
433 {
434
435 return Pin_real64 (0.0, x, 1.0);
436
437 }
438
Pin_real64_Overrange(real64 min,real64 x,real64 max)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
Lerp_real64(real64 a,real64 b,real64 t)464 inline real64 Lerp_real64 (real64 a, real64 b, real64 t)
465 {
466
467 return a + t * (b - a);
468
469 }
470
471 /*****************************************************************************/
472
Round_int32(real32 x)473 inline int32 Round_int32 (real32 x)
474 {
475
476 return (int32) (x > 0.0f ? x + 0.5f : x - 0.5f);
477
478 }
479
Round_int32(real64 x)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
Floor_uint32(real32 x)502 inline uint32 Floor_uint32 (real32 x)
503 {
504
505 return (uint32) Max_real32 (0.0f, x);
506
507 }
508
Floor_uint32(real64 x)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
Round_uint32(real32 x)530 inline uint32 Round_uint32 (real32 x)
531 {
532
533 return Floor_uint32 (x + 0.5f);
534
535 }
536
Round_uint32(real64 x)537 inline uint32 Round_uint32 (real64 x)
538 {
539
540 return Floor_uint32 (x + 0.5);
541
542 }
543
544 /******************************************************************************/
545
Round_int64(real64 x)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
Real64ToFixed64(real64 x)560 inline int64 Real64ToFixed64 (real64 x)
561 {
562
563 return Round_int64 (x * (real64) kFixed64_One);
564
565 }
566
567 /******************************************************************************/
568
Fixed64ToReal64(int64 x)569 inline real64 Fixed64ToReal64 (int64 x)
570 {
571
572 return x * (1.0 / (real64) kFixed64_One);
573
574 }
575
576 /*****************************************************************************/
577
ForceUppercase(char c)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
SwapBytes16(uint16 x)594 inline uint16 SwapBytes16 (uint16 x)
595 {
596
597 return (uint16) ((x << 8) |
598 (x >> 8));
599
600 }
601
SwapBytes32(uint32 x)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
IsAligned16(const void * p)614 inline bool IsAligned16 (const void *p)
615 {
616
617 return (((uintptr) p) & 1) == 0;
618
619 }
620
IsAligned32(const void * p)621 inline bool IsAligned32 (const void *p)
622 {
623
624 return (((uintptr) p) & 3) == 0;
625
626 }
627
IsAligned64(const void * p)628 inline bool IsAligned64 (const void *p)
629 {
630
631 return (((uintptr) p) & 7) == 0;
632
633 }
634
IsAligned128(const void * p)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
DNG_RGBtoHSV(real32 r,real32 g,real32 b,real32 & h,real32 & s,real32 & v)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
DNG_HSVtoRGB(real32 h,real32 s,real32 v,real32 & r,real32 & g,real32 & b)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
DNG_HalfToFloat(uint16 halfValue)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
DNG_FloatToHalf(uint32 i)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
DNG_FP24ToFloat(const uint8 * input)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
DNG_FloatToFP24(uint32 input,uint8 * output)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
Muluh86(uint32 x,uint32 y)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
Mulsh86(int32 x,int32 y)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
DNG_Random(uint32 seed)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
NoiseBuffer16()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 #if qMacOS
1263
1264 /*****************************************************************************/
1265
1266 template<typename T>
1267 class CFReleaseHelper
1268 {
1269
1270 private:
1271
1272 T fRef;
1273
1274 public:
1275
CFReleaseHelper(T ref)1276 CFReleaseHelper (T ref)
1277 : fRef (ref)
1278 {
1279 }
1280
~CFReleaseHelper()1281 ~CFReleaseHelper ()
1282 {
1283 if (fRef)
1284 {
1285 CFRelease (fRef);
1286 }
1287 }
1288
Get()1289 T Get () const
1290 {
1291 return fRef;
1292 }
1293
1294 };
1295
1296 /*****************************************************************************/
1297
1298 #endif // qMacOS
1299
1300 /*****************************************************************************/
1301
1302 #endif
1303
1304 /*****************************************************************************/
1305