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
39inline 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
60inline int32 Min_int32 (int32 x, int32 y)
61	{
62
63	return (x <= y ? x : y);
64
65	}
66
67inline int32 Max_int32 (int32 x, int32 y)
68	{
69
70	return (x >= y ? x : y);
71
72	}
73
74inline int32 Pin_int32 (int32 min, int32 x, int32 max)
75	{
76
77	return Max_int32 (min, Min_int32 (x, max));
78
79	}
80
81inline 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
94inline uint16 Min_uint16 (uint16 x, uint16 y)
95	{
96
97	return (x <= y ? x : y);
98
99	}
100
101inline uint16 Max_uint16 (uint16 x, uint16 y)
102	{
103
104	return (x >= y ? x : y);
105
106	}
107
108inline int16 Pin_int16 (int32 x)
109	{
110
111	x = Pin_int32 (-32768, x, 32767);
112
113	return (int16) x;
114
115	}
116
117/*****************************************************************************/
118
119inline uint32 Min_uint32 (uint32 x, uint32 y)
120	{
121
122	return (x <= y ? x : y);
123
124	}
125
126inline uint32 Min_uint32 (uint32 x, uint32 y, uint32 z)
127	{
128
129	return Min_uint32 (x, Min_uint32 (y, z));
130
131	}
132
133inline uint32 Max_uint32 (uint32 x, uint32 y)
134	{
135
136	return (x >= y ? x : y);
137
138	}
139
140inline uint32 Max_uint32 (uint32 x, uint32 y, uint32 z)
141	{
142
143	return Max_uint32 (x, Max_uint32 (y, z));
144
145	}
146
147inline 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
156inline 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
184inline uint32 RoundDown2 (uint32 x)
185	{
186
187	return x & (uint32) ~1;
188
189	}
190
191inline uint32 RoundDown4 (uint32 x)
192	{
193
194	return x & (uint32) ~3;
195
196	}
197
198inline uint32 RoundDown8 (uint32 x)
199	{
200
201	return x & (uint32) ~7;
202
203	}
204
205inline uint32 RoundDown16 (uint32 x)
206	{
207
208	return x & (uint32) ~15;
209
210	}
211
212/******************************************************************************/
213
214inline 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().
241enum 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.
254uint32 ComputeBufferSize(uint32 pixelType, const dng_point &tileSize,
255						 uint32 numPlanes, PaddingType paddingType);
256
257/******************************************************************************/
258
259inline uint64 Abs_int64 (int64 x)
260	{
261
262	return (uint64) (x < 0 ? -x : x);
263
264	}
265
266inline int64 Min_int64 (int64 x, int64 y)
267	{
268
269	return (x <= y ? x : y);
270
271	}
272
273inline int64 Max_int64 (int64 x, int64 y)
274	{
275
276	return (x >= y ? x : y);
277
278	}
279
280inline 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
289inline uint64 Min_uint64 (uint64 x, uint64 y)
290	{
291
292	return (x <= y ? x : y);
293
294	}
295
296inline uint64 Max_uint64 (uint64 x, uint64 y)
297	{
298
299	return (x >= y ? x : y);
300
301	}
302
303inline 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
312inline real32 Abs_real32 (real32 x)
313	{
314
315	return (x < 0.0f ? -x : x);
316
317	}
318
319inline real32 Min_real32 (real32 x, real32 y)
320	{
321
322	return (x < y ? x : y);
323
324	}
325
326inline real32 Max_real32 (real32 x, real32 y)
327	{
328
329	return (x > y ? x : y);
330
331	}
332
333inline real32 Pin_real32 (real32 min, real32 x, real32 max)
334	{
335
336	return Max_real32 (min, Min_real32 (x, max));
337
338	}
339
340inline real32 Pin_real32 (real32 x)
341	{
342
343	return Pin_real32 (0.0f, x, 1.0f);
344
345	}
346
347inline 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
372inline 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
395inline real32 Lerp_real32 (real32 a, real32 b, real32 t)
396	{
397
398	return a + t * (b - a);
399
400	}
401
402/*****************************************************************************/
403
404inline real64 Abs_real64 (real64 x)
405	{
406
407	return (x < 0.0 ? -x : x);
408
409	}
410
411inline real64 Min_real64 (real64 x, real64 y)
412	{
413
414	return (x < y ? x : y);
415
416	}
417
418inline real64 Max_real64 (real64 x, real64 y)
419	{
420
421	return (x > y ? x : y);
422
423	}
424
425inline real64 Pin_real64 (real64 min, real64 x, real64 max)
426	{
427
428	return Max_real64 (min, Min_real64 (x, max));
429
430	}
431
432inline real64 Pin_real64 (real64 x)
433	{
434
435	return Pin_real64 (0.0, x, 1.0);
436
437	}
438
439inline 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
464inline real64 Lerp_real64 (real64 a, real64 b, real64 t)
465	{
466
467	return a + t * (b - a);
468
469	}
470
471/*****************************************************************************/
472
473inline int32 Round_int32 (real32 x)
474	{
475
476	return (int32) (x > 0.0f ? x + 0.5f : x - 0.5f);
477
478	}
479
480inline 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
502inline uint32 Floor_uint32 (real32 x)
503	{
504
505	return (uint32) Max_real32 (0.0f, x);
506
507	}
508
509inline 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
530inline uint32 Round_uint32 (real32 x)
531	{
532
533	return Floor_uint32 (x + 0.5f);
534
535	}
536
537inline uint32 Round_uint32 (real64 x)
538	{
539
540	return Floor_uint32 (x + 0.5);
541
542	}
543
544/******************************************************************************/
545
546inline int64 Round_int64 (real64 x)
547	{
548
549	return (int64) (x >= 0.0 ? x + 0.5 : x - 0.5);
550
551	}
552
553/*****************************************************************************/
554
555const int64 kFixed64_One  = (((int64) 1) << 32);
556const int64 kFixed64_Half = (((int64) 1) << 31);
557
558/******************************************************************************/
559
560inline int64 Real64ToFixed64 (real64 x)
561	{
562
563	return Round_int64 (x * (real64) kFixed64_One);
564
565	}
566
567/******************************************************************************/
568
569inline real64 Fixed64ToReal64 (int64 x)
570	{
571
572	return x * (1.0 / (real64) kFixed64_One);
573
574	}
575
576/*****************************************************************************/
577
578inline 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
594inline uint16 SwapBytes16 (uint16 x)
595	{
596
597	return (uint16) ((x << 8) |
598					 (x >> 8));
599
600	}
601
602inline 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
614inline bool IsAligned16 (const void *p)
615	{
616
617	return (((uintptr) p) & 1) == 0;
618
619	}
620
621inline bool IsAligned32 (const void *p)
622	{
623
624	return (((uintptr) p) & 3) == 0;
625
626	}
627
628inline bool IsAligned64 (const void *p)
629	{
630
631	return (((uintptr) p) & 7) == 0;
632
633	}
634
635inline 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
647inline 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
701inline 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
754real64 TickTimeInSeconds ();
755
756// Lower resolution timer, but more stable.
757
758real64 TickCountInSeconds ();
759
760/******************************************************************************/
761
762class 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
792real64 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
800real64 MaxDistancePointToRect (const dng_point_real64 &point,
801							   const dng_rect_real64 &rect);
802
803/*****************************************************************************/
804
805inline 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
878inline 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
976inline 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
1049inline 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
1111inline 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
1139inline 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
1178inline 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
1203class 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
1245void 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
1254void 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