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