1 /*****************************************************************************/
2 // Copyright 2006-2019 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 #include "dng_1d_table.h"
10 
11 #include "dng_1d_function.h"
12 #include "dng_assertions.h"
13 #include "dng_memory.h"
14 #include "dng_utils.h"
15 
16 /*****************************************************************************/
17 
dng_1d_table(uint32 count)18 dng_1d_table::dng_1d_table (uint32 count)
19 
20 	:	fBuffer		()
21 	,	fTable		(NULL)
22 	,	fTableCount (count)
23 
24 	{
25 
26 	DNG_REQUIRE (count >= kMinTableSize,
27 				 "count must be at least kMinTableSize");
28 
29 	DNG_REQUIRE ((count & (count - 1)) == 0,
30 				 "count must be power of 2");
31 
32 	}
33 
34 /*****************************************************************************/
35 
~dng_1d_table()36 dng_1d_table::~dng_1d_table ()
37 	{
38 
39 	}
40 
41 /*****************************************************************************/
42 
SubDivide(const dng_1d_function & function,uint32 lower,uint32 upper,real32 maxDelta)43 void dng_1d_table::SubDivide (const dng_1d_function &function,
44 							  uint32 lower,
45 							  uint32 upper,
46 							  real32 maxDelta)
47 	{
48 
49 	uint32 range = upper - lower;
50 
51 	bool subDivide = (range > (fTableCount >> 8));
52 
53 	if (!subDivide)
54 		{
55 
56 		real32 delta = Abs_real32 (fTable [upper] -
57 								   fTable [lower]);
58 
59 		if (delta > maxDelta)
60 			{
61 
62 			subDivide = true;
63 
64 			}
65 
66 		}
67 
68 	if (subDivide)
69 		{
70 
71 		uint32 middle = (lower + upper) >> 1;
72 
73 		fTable [middle] = (real32) function.Evaluate (middle * (1.0 / (real64) fTableCount));
74 
75 		if (range > 2)
76 			{
77 
78 			SubDivide (function, lower, middle, maxDelta);
79 
80 			SubDivide (function, middle, upper, maxDelta);
81 
82 			}
83 
84 		}
85 
86 	else
87 		{
88 
89 		real64 y0 = fTable [lower];
90 		real64 y1 = fTable [upper];
91 
92 		real64 delta = (y1 - y0) / (real64) range;
93 
94 		for (uint32 j = lower + 1; j < upper; j++)
95 			{
96 
97 			y0 += delta;
98 
99 			fTable [j] = (real32) y0;
100 
101 			}
102 
103 		}
104 
105 	}
106 
107 /*****************************************************************************/
108 
Initialize(dng_memory_allocator & allocator,const dng_1d_function & function,bool subSample)109 void dng_1d_table::Initialize (dng_memory_allocator &allocator,
110 							   const dng_1d_function &function,
111 							   bool subSample)
112 	{
113 
114 	fBuffer.Reset (allocator.Allocate ((fTableCount + 2) * sizeof (real32)));
115 
116 	fTable = fBuffer->Buffer_real32 ();
117 
118 	if (subSample)
119 		{
120 
121 		fTable [0		   ] = (real32) function.Evaluate (0.0);
122 		fTable [fTableCount] = (real32) function.Evaluate (1.0);
123 
124 		real32 maxDelta = Max_real32 (Abs_real32 (fTable [fTableCount] -
125 												  fTable [0			 ]), 1.0f) *
126 						  (1.0f / 256.0f);
127 
128 		SubDivide (function,
129 				   0,
130 				   fTableCount,
131 				   maxDelta);
132 
133 		}
134 
135 	else
136 		{
137 
138 		for (uint32 j = 0; j <= fTableCount; j++)
139 			{
140 
141 			real64 x = j * (1.0 / (real64) fTableCount);
142 
143 			real64 y = function.Evaluate (x);
144 
145 			fTable [j] = (real32) y;
146 
147 			}
148 
149 		}
150 
151 	fTable [fTableCount + 1] = fTable [fTableCount];
152 
153 	}
154 
155 /*****************************************************************************/
156 
Expand16(uint16 * table16) const157 void dng_1d_table::Expand16 (uint16 *table16) const
158 	{
159 
160 	real64 step = (real64) fTableCount / 65535.0;
161 
162 	real64 y0 = fTable [0];
163 	real64 y1 = fTable [1];
164 
165 	real64 base  = y0 * 65535.0 + 0.5;
166 	real64 slope = (y1 - y0) * 65535.0;
167 
168 	uint32 index = 1;
169 	real64 fract = 0.0;
170 
171 	for (uint32 j = 0; j < 0x10000; j++)
172 		{
173 
174 		table16 [j] = (uint16) (base + slope * fract);
175 
176 		fract += step;
177 
178 		if (fract > 1.0)
179 			{
180 
181 			index += 1;
182 			fract -= 1.0;
183 
184 			y0 = y1;
185 			y1 = fTable [index];
186 
187 			base  = y0 * 65535.0 + 0.5;
188 			slope = (y1 - y0) * 65535.0;
189 
190 			}
191 
192 		}
193 
194 	}
195 
196 /*****************************************************************************/
197