• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #endif
1263 
1264 /*****************************************************************************/
1265