1 /*****************************************************************************/
2 // Copyright 2006-2007 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_render.cpp#1 $ */
10 /* $DateTime: 2012/05/30 13:28:51 $ */
11 /* $Change: 832332 $ */
12 /* $Author: tknoll $ */
13 
14 /*****************************************************************************/
15 
16 #include "dng_render.h"
17 
18 #include "dng_1d_table.h"
19 #include "dng_bottlenecks.h"
20 #include "dng_camera_profile.h"
21 #include "dng_color_space.h"
22 #include "dng_color_spec.h"
23 #include "dng_filter_task.h"
24 #include "dng_host.h"
25 #include "dng_image.h"
26 #include "dng_negative.h"
27 #include "dng_resample.h"
28 #include "dng_safe_arithmetic.h"
29 #include "dng_utils.h"
30 
31 /*****************************************************************************/
32 
dng_function_exposure_ramp(real64 white,real64 black,real64 minBlack)33 dng_function_exposure_ramp::dng_function_exposure_ramp (real64 white,
34 														real64 black,
35 														real64 minBlack)
36 
37 	:	fSlope ((white == black) ? 0.0f : 1.0 / (white - black))
38 	,	fBlack (black)
39 
40 	,	fRadius (0.0)
41 	,	fQScale (0.0)
42 
43 	{
44 	if (fSlope == 0.0)
45 		{
46 		 ThrowBadFormat ();
47 		}
48 
49 	const real64 kMaxCurveX = 0.5;			// Fraction of minBlack.
50 
51 	const real64 kMaxCurveY = 1.0 / 16.0;	// Fraction of white.
52 
53 	fRadius = Min_real64 (kMaxCurveX * minBlack,
54 						  kMaxCurveY / fSlope);
55 
56 	if (fRadius > 0.0)
57 		fQScale= fSlope / (4.0 * fRadius);
58 	else
59 		fQScale = 0.0;
60 
61 	}
62 
63 /*****************************************************************************/
64 
Evaluate(real64 x) const65 real64 dng_function_exposure_ramp::Evaluate (real64 x) const
66 	{
67 
68 	if (x <= fBlack - fRadius)
69 		return 0.0;
70 
71 	if (x >= fBlack + fRadius)
72 		return Min_real64 ((x - fBlack) * fSlope, 1.0);
73 
74 	real64 y = x - (fBlack - fRadius);
75 
76 	return fQScale * y * y;
77 
78 	}
79 
80 /*****************************************************************************/
81 
dng_function_exposure_tone(real64 exposure)82 dng_function_exposure_tone::dng_function_exposure_tone (real64 exposure)
83 
84 	:	fIsNOP (exposure >= 0.0)
85 
86 	,	fSlope (0.0)
87 
88 	,	a (0.0)
89 	,	b (0.0)
90 	,	c (0.0)
91 
92 	{
93 
94 	if (!fIsNOP)
95 		{
96 
97 		// Find slope to use for the all except the highest two f-stops.
98 
99 		fSlope = pow (2.0, exposure);
100 
101 		// Find quadradic parameters that match this darking at the crossover
102 		// point, yet still map pure white to pure white.
103 
104 		a = 16.0 / 9.0 * (1.0 - fSlope);
105 
106 		b = fSlope - 0.5 * a;
107 
108 		c = 1.0 - a - b;
109 
110 		}
111 
112 	}
113 
114 /*****************************************************************************/
115 
Evaluate(real64 x) const116 real64 dng_function_exposure_tone::Evaluate (real64 x) const
117 	{
118 
119 	if (!fIsNOP)
120 		{
121 
122 		if (x <= 0.25)
123 			x = x * fSlope;
124 
125 		else
126 			x = (a * x + b) * x + c;
127 
128 		}
129 
130 	return x;
131 
132 	}
133 
134 /*****************************************************************************/
135 
Evaluate(real64 x) const136 real64 dng_tone_curve_acr3_default::Evaluate (real64 x) const
137 	{
138 
139 	static const real32 kTable [] =
140 		{
141 		0.00000f, 0.00078f, 0.00160f, 0.00242f,
142 		0.00314f, 0.00385f, 0.00460f, 0.00539f,
143 		0.00623f, 0.00712f, 0.00806f, 0.00906f,
144 		0.01012f, 0.01122f, 0.01238f, 0.01359f,
145 		0.01485f, 0.01616f, 0.01751f, 0.01890f,
146 		0.02033f, 0.02180f, 0.02331f, 0.02485f,
147 		0.02643f, 0.02804f, 0.02967f, 0.03134f,
148 		0.03303f, 0.03475f, 0.03648f, 0.03824f,
149 		0.04002f, 0.04181f, 0.04362f, 0.04545f,
150 		0.04730f, 0.04916f, 0.05103f, 0.05292f,
151 		0.05483f, 0.05675f, 0.05868f, 0.06063f,
152 		0.06259f, 0.06457f, 0.06655f, 0.06856f,
153 		0.07057f, 0.07259f, 0.07463f, 0.07668f,
154 		0.07874f, 0.08081f, 0.08290f, 0.08499f,
155 		0.08710f, 0.08921f, 0.09134f, 0.09348f,
156 		0.09563f, 0.09779f, 0.09996f, 0.10214f,
157 		0.10433f, 0.10652f, 0.10873f, 0.11095f,
158 		0.11318f, 0.11541f, 0.11766f, 0.11991f,
159 		0.12218f, 0.12445f, 0.12673f, 0.12902f,
160 		0.13132f, 0.13363f, 0.13595f, 0.13827f,
161 		0.14061f, 0.14295f, 0.14530f, 0.14765f,
162 		0.15002f, 0.15239f, 0.15477f, 0.15716f,
163 		0.15956f, 0.16197f, 0.16438f, 0.16680f,
164 		0.16923f, 0.17166f, 0.17410f, 0.17655f,
165 		0.17901f, 0.18148f, 0.18395f, 0.18643f,
166 		0.18891f, 0.19141f, 0.19391f, 0.19641f,
167 		0.19893f, 0.20145f, 0.20398f, 0.20651f,
168 		0.20905f, 0.21160f, 0.21416f, 0.21672f,
169 		0.21929f, 0.22185f, 0.22440f, 0.22696f,
170 		0.22950f, 0.23204f, 0.23458f, 0.23711f,
171 		0.23963f, 0.24215f, 0.24466f, 0.24717f,
172 		0.24967f, 0.25216f, 0.25465f, 0.25713f,
173 		0.25961f, 0.26208f, 0.26454f, 0.26700f,
174 		0.26945f, 0.27189f, 0.27433f, 0.27676f,
175 		0.27918f, 0.28160f, 0.28401f, 0.28641f,
176 		0.28881f, 0.29120f, 0.29358f, 0.29596f,
177 		0.29833f, 0.30069f, 0.30305f, 0.30540f,
178 		0.30774f, 0.31008f, 0.31241f, 0.31473f,
179 		0.31704f, 0.31935f, 0.32165f, 0.32395f,
180 		0.32623f, 0.32851f, 0.33079f, 0.33305f,
181 		0.33531f, 0.33756f, 0.33981f, 0.34205f,
182 		0.34428f, 0.34650f, 0.34872f, 0.35093f,
183 		0.35313f, 0.35532f, 0.35751f, 0.35969f,
184 		0.36187f, 0.36404f, 0.36620f, 0.36835f,
185 		0.37050f, 0.37264f, 0.37477f, 0.37689f,
186 		0.37901f, 0.38112f, 0.38323f, 0.38533f,
187 		0.38742f, 0.38950f, 0.39158f, 0.39365f,
188 		0.39571f, 0.39777f, 0.39982f, 0.40186f,
189 		0.40389f, 0.40592f, 0.40794f, 0.40996f,
190 		0.41197f, 0.41397f, 0.41596f, 0.41795f,
191 		0.41993f, 0.42191f, 0.42388f, 0.42584f,
192 		0.42779f, 0.42974f, 0.43168f, 0.43362f,
193 		0.43554f, 0.43747f, 0.43938f, 0.44129f,
194 		0.44319f, 0.44509f, 0.44698f, 0.44886f,
195 		0.45073f, 0.45260f, 0.45447f, 0.45632f,
196 		0.45817f, 0.46002f, 0.46186f, 0.46369f,
197 		0.46551f, 0.46733f, 0.46914f, 0.47095f,
198 		0.47275f, 0.47454f, 0.47633f, 0.47811f,
199 		0.47989f, 0.48166f, 0.48342f, 0.48518f,
200 		0.48693f, 0.48867f, 0.49041f, 0.49214f,
201 		0.49387f, 0.49559f, 0.49730f, 0.49901f,
202 		0.50072f, 0.50241f, 0.50410f, 0.50579f,
203 		0.50747f, 0.50914f, 0.51081f, 0.51247f,
204 		0.51413f, 0.51578f, 0.51742f, 0.51906f,
205 		0.52069f, 0.52232f, 0.52394f, 0.52556f,
206 		0.52717f, 0.52878f, 0.53038f, 0.53197f,
207 		0.53356f, 0.53514f, 0.53672f, 0.53829f,
208 		0.53986f, 0.54142f, 0.54297f, 0.54452f,
209 		0.54607f, 0.54761f, 0.54914f, 0.55067f,
210 		0.55220f, 0.55371f, 0.55523f, 0.55673f,
211 		0.55824f, 0.55973f, 0.56123f, 0.56271f,
212 		0.56420f, 0.56567f, 0.56715f, 0.56861f,
213 		0.57007f, 0.57153f, 0.57298f, 0.57443f,
214 		0.57587f, 0.57731f, 0.57874f, 0.58017f,
215 		0.58159f, 0.58301f, 0.58443f, 0.58583f,
216 		0.58724f, 0.58864f, 0.59003f, 0.59142f,
217 		0.59281f, 0.59419f, 0.59556f, 0.59694f,
218 		0.59830f, 0.59966f, 0.60102f, 0.60238f,
219 		0.60373f, 0.60507f, 0.60641f, 0.60775f,
220 		0.60908f, 0.61040f, 0.61173f, 0.61305f,
221 		0.61436f, 0.61567f, 0.61698f, 0.61828f,
222 		0.61957f, 0.62087f, 0.62216f, 0.62344f,
223 		0.62472f, 0.62600f, 0.62727f, 0.62854f,
224 		0.62980f, 0.63106f, 0.63232f, 0.63357f,
225 		0.63482f, 0.63606f, 0.63730f, 0.63854f,
226 		0.63977f, 0.64100f, 0.64222f, 0.64344f,
227 		0.64466f, 0.64587f, 0.64708f, 0.64829f,
228 		0.64949f, 0.65069f, 0.65188f, 0.65307f,
229 		0.65426f, 0.65544f, 0.65662f, 0.65779f,
230 		0.65897f, 0.66013f, 0.66130f, 0.66246f,
231 		0.66362f, 0.66477f, 0.66592f, 0.66707f,
232 		0.66821f, 0.66935f, 0.67048f, 0.67162f,
233 		0.67275f, 0.67387f, 0.67499f, 0.67611f,
234 		0.67723f, 0.67834f, 0.67945f, 0.68055f,
235 		0.68165f, 0.68275f, 0.68385f, 0.68494f,
236 		0.68603f, 0.68711f, 0.68819f, 0.68927f,
237 		0.69035f, 0.69142f, 0.69249f, 0.69355f,
238 		0.69461f, 0.69567f, 0.69673f, 0.69778f,
239 		0.69883f, 0.69988f, 0.70092f, 0.70196f,
240 		0.70300f, 0.70403f, 0.70506f, 0.70609f,
241 		0.70711f, 0.70813f, 0.70915f, 0.71017f,
242 		0.71118f, 0.71219f, 0.71319f, 0.71420f,
243 		0.71520f, 0.71620f, 0.71719f, 0.71818f,
244 		0.71917f, 0.72016f, 0.72114f, 0.72212f,
245 		0.72309f, 0.72407f, 0.72504f, 0.72601f,
246 		0.72697f, 0.72794f, 0.72890f, 0.72985f,
247 		0.73081f, 0.73176f, 0.73271f, 0.73365f,
248 		0.73460f, 0.73554f, 0.73647f, 0.73741f,
249 		0.73834f, 0.73927f, 0.74020f, 0.74112f,
250 		0.74204f, 0.74296f, 0.74388f, 0.74479f,
251 		0.74570f, 0.74661f, 0.74751f, 0.74842f,
252 		0.74932f, 0.75021f, 0.75111f, 0.75200f,
253 		0.75289f, 0.75378f, 0.75466f, 0.75555f,
254 		0.75643f, 0.75730f, 0.75818f, 0.75905f,
255 		0.75992f, 0.76079f, 0.76165f, 0.76251f,
256 		0.76337f, 0.76423f, 0.76508f, 0.76594f,
257 		0.76679f, 0.76763f, 0.76848f, 0.76932f,
258 		0.77016f, 0.77100f, 0.77183f, 0.77267f,
259 		0.77350f, 0.77432f, 0.77515f, 0.77597f,
260 		0.77680f, 0.77761f, 0.77843f, 0.77924f,
261 		0.78006f, 0.78087f, 0.78167f, 0.78248f,
262 		0.78328f, 0.78408f, 0.78488f, 0.78568f,
263 		0.78647f, 0.78726f, 0.78805f, 0.78884f,
264 		0.78962f, 0.79040f, 0.79118f, 0.79196f,
265 		0.79274f, 0.79351f, 0.79428f, 0.79505f,
266 		0.79582f, 0.79658f, 0.79735f, 0.79811f,
267 		0.79887f, 0.79962f, 0.80038f, 0.80113f,
268 		0.80188f, 0.80263f, 0.80337f, 0.80412f,
269 		0.80486f, 0.80560f, 0.80634f, 0.80707f,
270 		0.80780f, 0.80854f, 0.80926f, 0.80999f,
271 		0.81072f, 0.81144f, 0.81216f, 0.81288f,
272 		0.81360f, 0.81431f, 0.81503f, 0.81574f,
273 		0.81645f, 0.81715f, 0.81786f, 0.81856f,
274 		0.81926f, 0.81996f, 0.82066f, 0.82135f,
275 		0.82205f, 0.82274f, 0.82343f, 0.82412f,
276 		0.82480f, 0.82549f, 0.82617f, 0.82685f,
277 		0.82753f, 0.82820f, 0.82888f, 0.82955f,
278 		0.83022f, 0.83089f, 0.83155f, 0.83222f,
279 		0.83288f, 0.83354f, 0.83420f, 0.83486f,
280 		0.83552f, 0.83617f, 0.83682f, 0.83747f,
281 		0.83812f, 0.83877f, 0.83941f, 0.84005f,
282 		0.84069f, 0.84133f, 0.84197f, 0.84261f,
283 		0.84324f, 0.84387f, 0.84450f, 0.84513f,
284 		0.84576f, 0.84639f, 0.84701f, 0.84763f,
285 		0.84825f, 0.84887f, 0.84949f, 0.85010f,
286 		0.85071f, 0.85132f, 0.85193f, 0.85254f,
287 		0.85315f, 0.85375f, 0.85436f, 0.85496f,
288 		0.85556f, 0.85615f, 0.85675f, 0.85735f,
289 		0.85794f, 0.85853f, 0.85912f, 0.85971f,
290 		0.86029f, 0.86088f, 0.86146f, 0.86204f,
291 		0.86262f, 0.86320f, 0.86378f, 0.86435f,
292 		0.86493f, 0.86550f, 0.86607f, 0.86664f,
293 		0.86720f, 0.86777f, 0.86833f, 0.86889f,
294 		0.86945f, 0.87001f, 0.87057f, 0.87113f,
295 		0.87168f, 0.87223f, 0.87278f, 0.87333f,
296 		0.87388f, 0.87443f, 0.87497f, 0.87552f,
297 		0.87606f, 0.87660f, 0.87714f, 0.87768f,
298 		0.87821f, 0.87875f, 0.87928f, 0.87981f,
299 		0.88034f, 0.88087f, 0.88140f, 0.88192f,
300 		0.88244f, 0.88297f, 0.88349f, 0.88401f,
301 		0.88453f, 0.88504f, 0.88556f, 0.88607f,
302 		0.88658f, 0.88709f, 0.88760f, 0.88811f,
303 		0.88862f, 0.88912f, 0.88963f, 0.89013f,
304 		0.89063f, 0.89113f, 0.89163f, 0.89212f,
305 		0.89262f, 0.89311f, 0.89360f, 0.89409f,
306 		0.89458f, 0.89507f, 0.89556f, 0.89604f,
307 		0.89653f, 0.89701f, 0.89749f, 0.89797f,
308 		0.89845f, 0.89892f, 0.89940f, 0.89987f,
309 		0.90035f, 0.90082f, 0.90129f, 0.90176f,
310 		0.90222f, 0.90269f, 0.90316f, 0.90362f,
311 		0.90408f, 0.90454f, 0.90500f, 0.90546f,
312 		0.90592f, 0.90637f, 0.90683f, 0.90728f,
313 		0.90773f, 0.90818f, 0.90863f, 0.90908f,
314 		0.90952f, 0.90997f, 0.91041f, 0.91085f,
315 		0.91130f, 0.91173f, 0.91217f, 0.91261f,
316 		0.91305f, 0.91348f, 0.91392f, 0.91435f,
317 		0.91478f, 0.91521f, 0.91564f, 0.91606f,
318 		0.91649f, 0.91691f, 0.91734f, 0.91776f,
319 		0.91818f, 0.91860f, 0.91902f, 0.91944f,
320 		0.91985f, 0.92027f, 0.92068f, 0.92109f,
321 		0.92150f, 0.92191f, 0.92232f, 0.92273f,
322 		0.92314f, 0.92354f, 0.92395f, 0.92435f,
323 		0.92475f, 0.92515f, 0.92555f, 0.92595f,
324 		0.92634f, 0.92674f, 0.92713f, 0.92753f,
325 		0.92792f, 0.92831f, 0.92870f, 0.92909f,
326 		0.92947f, 0.92986f, 0.93025f, 0.93063f,
327 		0.93101f, 0.93139f, 0.93177f, 0.93215f,
328 		0.93253f, 0.93291f, 0.93328f, 0.93366f,
329 		0.93403f, 0.93440f, 0.93478f, 0.93515f,
330 		0.93551f, 0.93588f, 0.93625f, 0.93661f,
331 		0.93698f, 0.93734f, 0.93770f, 0.93807f,
332 		0.93843f, 0.93878f, 0.93914f, 0.93950f,
333 		0.93986f, 0.94021f, 0.94056f, 0.94092f,
334 		0.94127f, 0.94162f, 0.94197f, 0.94231f,
335 		0.94266f, 0.94301f, 0.94335f, 0.94369f,
336 		0.94404f, 0.94438f, 0.94472f, 0.94506f,
337 		0.94540f, 0.94573f, 0.94607f, 0.94641f,
338 		0.94674f, 0.94707f, 0.94740f, 0.94774f,
339 		0.94807f, 0.94839f, 0.94872f, 0.94905f,
340 		0.94937f, 0.94970f, 0.95002f, 0.95035f,
341 		0.95067f, 0.95099f, 0.95131f, 0.95163f,
342 		0.95194f, 0.95226f, 0.95257f, 0.95289f,
343 		0.95320f, 0.95351f, 0.95383f, 0.95414f,
344 		0.95445f, 0.95475f, 0.95506f, 0.95537f,
345 		0.95567f, 0.95598f, 0.95628f, 0.95658f,
346 		0.95688f, 0.95718f, 0.95748f, 0.95778f,
347 		0.95808f, 0.95838f, 0.95867f, 0.95897f,
348 		0.95926f, 0.95955f, 0.95984f, 0.96013f,
349 		0.96042f, 0.96071f, 0.96100f, 0.96129f,
350 		0.96157f, 0.96186f, 0.96214f, 0.96242f,
351 		0.96271f, 0.96299f, 0.96327f, 0.96355f,
352 		0.96382f, 0.96410f, 0.96438f, 0.96465f,
353 		0.96493f, 0.96520f, 0.96547f, 0.96574f,
354 		0.96602f, 0.96629f, 0.96655f, 0.96682f,
355 		0.96709f, 0.96735f, 0.96762f, 0.96788f,
356 		0.96815f, 0.96841f, 0.96867f, 0.96893f,
357 		0.96919f, 0.96945f, 0.96971f, 0.96996f,
358 		0.97022f, 0.97047f, 0.97073f, 0.97098f,
359 		0.97123f, 0.97149f, 0.97174f, 0.97199f,
360 		0.97223f, 0.97248f, 0.97273f, 0.97297f,
361 		0.97322f, 0.97346f, 0.97371f, 0.97395f,
362 		0.97419f, 0.97443f, 0.97467f, 0.97491f,
363 		0.97515f, 0.97539f, 0.97562f, 0.97586f,
364 		0.97609f, 0.97633f, 0.97656f, 0.97679f,
365 		0.97702f, 0.97725f, 0.97748f, 0.97771f,
366 		0.97794f, 0.97817f, 0.97839f, 0.97862f,
367 		0.97884f, 0.97907f, 0.97929f, 0.97951f,
368 		0.97973f, 0.97995f, 0.98017f, 0.98039f,
369 		0.98061f, 0.98082f, 0.98104f, 0.98125f,
370 		0.98147f, 0.98168f, 0.98189f, 0.98211f,
371 		0.98232f, 0.98253f, 0.98274f, 0.98295f,
372 		0.98315f, 0.98336f, 0.98357f, 0.98377f,
373 		0.98398f, 0.98418f, 0.98438f, 0.98458f,
374 		0.98478f, 0.98498f, 0.98518f, 0.98538f,
375 		0.98558f, 0.98578f, 0.98597f, 0.98617f,
376 		0.98636f, 0.98656f, 0.98675f, 0.98694f,
377 		0.98714f, 0.98733f, 0.98752f, 0.98771f,
378 		0.98789f, 0.98808f, 0.98827f, 0.98845f,
379 		0.98864f, 0.98882f, 0.98901f, 0.98919f,
380 		0.98937f, 0.98955f, 0.98973f, 0.98991f,
381 		0.99009f, 0.99027f, 0.99045f, 0.99063f,
382 		0.99080f, 0.99098f, 0.99115f, 0.99133f,
383 		0.99150f, 0.99167f, 0.99184f, 0.99201f,
384 		0.99218f, 0.99235f, 0.99252f, 0.99269f,
385 		0.99285f, 0.99302f, 0.99319f, 0.99335f,
386 		0.99351f, 0.99368f, 0.99384f, 0.99400f,
387 		0.99416f, 0.99432f, 0.99448f, 0.99464f,
388 		0.99480f, 0.99495f, 0.99511f, 0.99527f,
389 		0.99542f, 0.99558f, 0.99573f, 0.99588f,
390 		0.99603f, 0.99619f, 0.99634f, 0.99649f,
391 		0.99664f, 0.99678f, 0.99693f, 0.99708f,
392 		0.99722f, 0.99737f, 0.99751f, 0.99766f,
393 		0.99780f, 0.99794f, 0.99809f, 0.99823f,
394 		0.99837f, 0.99851f, 0.99865f, 0.99879f,
395 		0.99892f, 0.99906f, 0.99920f, 0.99933f,
396 		0.99947f, 0.99960f, 0.99974f, 0.99987f,
397 		1.00000f
398 		};
399 
400 	const uint32 kTableSize = sizeof (kTable    ) /
401 							  sizeof (kTable [0]);
402 
403 	real32 y = (real32) x * (real32) (kTableSize - 1);
404 
405 	int32 index = Pin_int32 (0, (int32) y, kTableSize - 2);
406 
407 	real32 fract = y - (real32) index;
408 
409 	return kTable [index    ] * (1.0f - fract) +
410 		   kTable [index + 1] * (       fract);
411 
412 	}
413 
414 /*****************************************************************************/
415 
EvaluateInverse(real64 x) const416 real64 dng_tone_curve_acr3_default::EvaluateInverse (real64 x) const
417 	{
418 
419 	static const real32 kTable [] =
420 		{
421 		0.00000f, 0.00121f, 0.00237f, 0.00362f,
422 		0.00496f, 0.00621f, 0.00738f, 0.00848f,
423 		0.00951f, 0.01048f, 0.01139f, 0.01227f,
424 		0.01312f, 0.01393f, 0.01471f, 0.01547f,
425 		0.01620f, 0.01692f, 0.01763f, 0.01831f,
426 		0.01899f, 0.01965f, 0.02030f, 0.02094f,
427 		0.02157f, 0.02218f, 0.02280f, 0.02340f,
428 		0.02399f, 0.02458f, 0.02517f, 0.02574f,
429 		0.02631f, 0.02688f, 0.02744f, 0.02800f,
430 		0.02855f, 0.02910f, 0.02965f, 0.03019f,
431 		0.03072f, 0.03126f, 0.03179f, 0.03232f,
432 		0.03285f, 0.03338f, 0.03390f, 0.03442f,
433 		0.03493f, 0.03545f, 0.03596f, 0.03647f,
434 		0.03698f, 0.03749f, 0.03799f, 0.03849f,
435 		0.03899f, 0.03949f, 0.03998f, 0.04048f,
436 		0.04097f, 0.04146f, 0.04195f, 0.04244f,
437 		0.04292f, 0.04341f, 0.04389f, 0.04437f,
438 		0.04485f, 0.04533f, 0.04580f, 0.04628f,
439 		0.04675f, 0.04722f, 0.04769f, 0.04816f,
440 		0.04863f, 0.04910f, 0.04956f, 0.05003f,
441 		0.05049f, 0.05095f, 0.05141f, 0.05187f,
442 		0.05233f, 0.05278f, 0.05324f, 0.05370f,
443 		0.05415f, 0.05460f, 0.05505f, 0.05551f,
444 		0.05595f, 0.05640f, 0.05685f, 0.05729f,
445 		0.05774f, 0.05818f, 0.05863f, 0.05907f,
446 		0.05951f, 0.05995f, 0.06039f, 0.06083f,
447 		0.06126f, 0.06170f, 0.06214f, 0.06257f,
448 		0.06301f, 0.06344f, 0.06388f, 0.06431f,
449 		0.06474f, 0.06517f, 0.06560f, 0.06602f,
450 		0.06645f, 0.06688f, 0.06731f, 0.06773f,
451 		0.06815f, 0.06858f, 0.06900f, 0.06943f,
452 		0.06985f, 0.07027f, 0.07069f, 0.07111f,
453 		0.07152f, 0.07194f, 0.07236f, 0.07278f,
454 		0.07319f, 0.07361f, 0.07402f, 0.07444f,
455 		0.07485f, 0.07526f, 0.07567f, 0.07608f,
456 		0.07650f, 0.07691f, 0.07732f, 0.07772f,
457 		0.07813f, 0.07854f, 0.07895f, 0.07935f,
458 		0.07976f, 0.08016f, 0.08057f, 0.08098f,
459 		0.08138f, 0.08178f, 0.08218f, 0.08259f,
460 		0.08299f, 0.08339f, 0.08379f, 0.08419f,
461 		0.08459f, 0.08499f, 0.08539f, 0.08578f,
462 		0.08618f, 0.08657f, 0.08697f, 0.08737f,
463 		0.08776f, 0.08816f, 0.08855f, 0.08894f,
464 		0.08934f, 0.08973f, 0.09012f, 0.09051f,
465 		0.09091f, 0.09130f, 0.09169f, 0.09208f,
466 		0.09247f, 0.09286f, 0.09324f, 0.09363f,
467 		0.09402f, 0.09440f, 0.09479f, 0.09518f,
468 		0.09556f, 0.09595f, 0.09633f, 0.09672f,
469 		0.09710f, 0.09749f, 0.09787f, 0.09825f,
470 		0.09863f, 0.09901f, 0.09939f, 0.09978f,
471 		0.10016f, 0.10054f, 0.10092f, 0.10130f,
472 		0.10167f, 0.10205f, 0.10243f, 0.10281f,
473 		0.10319f, 0.10356f, 0.10394f, 0.10432f,
474 		0.10469f, 0.10507f, 0.10544f, 0.10582f,
475 		0.10619f, 0.10657f, 0.10694f, 0.10731f,
476 		0.10768f, 0.10806f, 0.10843f, 0.10880f,
477 		0.10917f, 0.10954f, 0.10991f, 0.11029f,
478 		0.11066f, 0.11103f, 0.11141f, 0.11178f,
479 		0.11215f, 0.11253f, 0.11290f, 0.11328f,
480 		0.11365f, 0.11403f, 0.11440f, 0.11478f,
481 		0.11516f, 0.11553f, 0.11591f, 0.11629f,
482 		0.11666f, 0.11704f, 0.11742f, 0.11780f,
483 		0.11818f, 0.11856f, 0.11894f, 0.11932f,
484 		0.11970f, 0.12008f, 0.12046f, 0.12084f,
485 		0.12122f, 0.12161f, 0.12199f, 0.12237f,
486 		0.12276f, 0.12314f, 0.12352f, 0.12391f,
487 		0.12429f, 0.12468f, 0.12506f, 0.12545f,
488 		0.12583f, 0.12622f, 0.12661f, 0.12700f,
489 		0.12738f, 0.12777f, 0.12816f, 0.12855f,
490 		0.12894f, 0.12933f, 0.12972f, 0.13011f,
491 		0.13050f, 0.13089f, 0.13129f, 0.13168f,
492 		0.13207f, 0.13247f, 0.13286f, 0.13325f,
493 		0.13365f, 0.13404f, 0.13444f, 0.13483f,
494 		0.13523f, 0.13563f, 0.13603f, 0.13642f,
495 		0.13682f, 0.13722f, 0.13762f, 0.13802f,
496 		0.13842f, 0.13882f, 0.13922f, 0.13962f,
497 		0.14003f, 0.14043f, 0.14083f, 0.14124f,
498 		0.14164f, 0.14204f, 0.14245f, 0.14285f,
499 		0.14326f, 0.14366f, 0.14407f, 0.14448f,
500 		0.14489f, 0.14530f, 0.14570f, 0.14611f,
501 		0.14652f, 0.14693f, 0.14734f, 0.14776f,
502 		0.14817f, 0.14858f, 0.14900f, 0.14941f,
503 		0.14982f, 0.15024f, 0.15065f, 0.15107f,
504 		0.15148f, 0.15190f, 0.15232f, 0.15274f,
505 		0.15316f, 0.15357f, 0.15399f, 0.15441f,
506 		0.15483f, 0.15526f, 0.15568f, 0.15610f,
507 		0.15652f, 0.15695f, 0.15737f, 0.15779f,
508 		0.15822f, 0.15864f, 0.15907f, 0.15950f,
509 		0.15992f, 0.16035f, 0.16078f, 0.16121f,
510 		0.16164f, 0.16207f, 0.16250f, 0.16293f,
511 		0.16337f, 0.16380f, 0.16423f, 0.16467f,
512 		0.16511f, 0.16554f, 0.16598f, 0.16641f,
513 		0.16685f, 0.16729f, 0.16773f, 0.16816f,
514 		0.16860f, 0.16904f, 0.16949f, 0.16993f,
515 		0.17037f, 0.17081f, 0.17126f, 0.17170f,
516 		0.17215f, 0.17259f, 0.17304f, 0.17349f,
517 		0.17393f, 0.17438f, 0.17483f, 0.17528f,
518 		0.17573f, 0.17619f, 0.17664f, 0.17709f,
519 		0.17754f, 0.17799f, 0.17845f, 0.17890f,
520 		0.17936f, 0.17982f, 0.18028f, 0.18073f,
521 		0.18119f, 0.18165f, 0.18211f, 0.18257f,
522 		0.18303f, 0.18350f, 0.18396f, 0.18442f,
523 		0.18489f, 0.18535f, 0.18582f, 0.18629f,
524 		0.18676f, 0.18723f, 0.18770f, 0.18817f,
525 		0.18864f, 0.18911f, 0.18958f, 0.19005f,
526 		0.19053f, 0.19100f, 0.19147f, 0.19195f,
527 		0.19243f, 0.19291f, 0.19339f, 0.19387f,
528 		0.19435f, 0.19483f, 0.19531f, 0.19579f,
529 		0.19627f, 0.19676f, 0.19724f, 0.19773f,
530 		0.19821f, 0.19870f, 0.19919f, 0.19968f,
531 		0.20017f, 0.20066f, 0.20115f, 0.20164f,
532 		0.20214f, 0.20263f, 0.20313f, 0.20362f,
533 		0.20412f, 0.20462f, 0.20512f, 0.20561f,
534 		0.20611f, 0.20662f, 0.20712f, 0.20762f,
535 		0.20812f, 0.20863f, 0.20913f, 0.20964f,
536 		0.21015f, 0.21066f, 0.21117f, 0.21168f,
537 		0.21219f, 0.21270f, 0.21321f, 0.21373f,
538 		0.21424f, 0.21476f, 0.21527f, 0.21579f,
539 		0.21631f, 0.21683f, 0.21735f, 0.21787f,
540 		0.21839f, 0.21892f, 0.21944f, 0.21997f,
541 		0.22049f, 0.22102f, 0.22155f, 0.22208f,
542 		0.22261f, 0.22314f, 0.22367f, 0.22420f,
543 		0.22474f, 0.22527f, 0.22581f, 0.22634f,
544 		0.22688f, 0.22742f, 0.22796f, 0.22850f,
545 		0.22905f, 0.22959f, 0.23013f, 0.23068f,
546 		0.23123f, 0.23178f, 0.23232f, 0.23287f,
547 		0.23343f, 0.23398f, 0.23453f, 0.23508f,
548 		0.23564f, 0.23620f, 0.23675f, 0.23731f,
549 		0.23787f, 0.23843f, 0.23899f, 0.23956f,
550 		0.24012f, 0.24069f, 0.24125f, 0.24182f,
551 		0.24239f, 0.24296f, 0.24353f, 0.24410f,
552 		0.24468f, 0.24525f, 0.24582f, 0.24640f,
553 		0.24698f, 0.24756f, 0.24814f, 0.24872f,
554 		0.24931f, 0.24989f, 0.25048f, 0.25106f,
555 		0.25165f, 0.25224f, 0.25283f, 0.25342f,
556 		0.25401f, 0.25460f, 0.25520f, 0.25579f,
557 		0.25639f, 0.25699f, 0.25759f, 0.25820f,
558 		0.25880f, 0.25940f, 0.26001f, 0.26062f,
559 		0.26122f, 0.26183f, 0.26244f, 0.26306f,
560 		0.26367f, 0.26429f, 0.26490f, 0.26552f,
561 		0.26614f, 0.26676f, 0.26738f, 0.26800f,
562 		0.26863f, 0.26925f, 0.26988f, 0.27051f,
563 		0.27114f, 0.27177f, 0.27240f, 0.27303f,
564 		0.27367f, 0.27431f, 0.27495f, 0.27558f,
565 		0.27623f, 0.27687f, 0.27751f, 0.27816f,
566 		0.27881f, 0.27945f, 0.28011f, 0.28076f,
567 		0.28141f, 0.28207f, 0.28272f, 0.28338f,
568 		0.28404f, 0.28470f, 0.28536f, 0.28602f,
569 		0.28669f, 0.28736f, 0.28802f, 0.28869f,
570 		0.28937f, 0.29004f, 0.29071f, 0.29139f,
571 		0.29207f, 0.29274f, 0.29342f, 0.29410f,
572 		0.29479f, 0.29548f, 0.29616f, 0.29685f,
573 		0.29754f, 0.29823f, 0.29893f, 0.29962f,
574 		0.30032f, 0.30102f, 0.30172f, 0.30242f,
575 		0.30312f, 0.30383f, 0.30453f, 0.30524f,
576 		0.30595f, 0.30667f, 0.30738f, 0.30809f,
577 		0.30881f, 0.30953f, 0.31025f, 0.31097f,
578 		0.31170f, 0.31242f, 0.31315f, 0.31388f,
579 		0.31461f, 0.31534f, 0.31608f, 0.31682f,
580 		0.31755f, 0.31829f, 0.31904f, 0.31978f,
581 		0.32053f, 0.32127f, 0.32202f, 0.32277f,
582 		0.32353f, 0.32428f, 0.32504f, 0.32580f,
583 		0.32656f, 0.32732f, 0.32808f, 0.32885f,
584 		0.32962f, 0.33039f, 0.33116f, 0.33193f,
585 		0.33271f, 0.33349f, 0.33427f, 0.33505f,
586 		0.33583f, 0.33662f, 0.33741f, 0.33820f,
587 		0.33899f, 0.33978f, 0.34058f, 0.34138f,
588 		0.34218f, 0.34298f, 0.34378f, 0.34459f,
589 		0.34540f, 0.34621f, 0.34702f, 0.34783f,
590 		0.34865f, 0.34947f, 0.35029f, 0.35111f,
591 		0.35194f, 0.35277f, 0.35360f, 0.35443f,
592 		0.35526f, 0.35610f, 0.35694f, 0.35778f,
593 		0.35862f, 0.35946f, 0.36032f, 0.36117f,
594 		0.36202f, 0.36287f, 0.36372f, 0.36458f,
595 		0.36545f, 0.36631f, 0.36718f, 0.36805f,
596 		0.36891f, 0.36979f, 0.37066f, 0.37154f,
597 		0.37242f, 0.37331f, 0.37419f, 0.37507f,
598 		0.37596f, 0.37686f, 0.37775f, 0.37865f,
599 		0.37955f, 0.38045f, 0.38136f, 0.38227f,
600 		0.38317f, 0.38409f, 0.38500f, 0.38592f,
601 		0.38684f, 0.38776f, 0.38869f, 0.38961f,
602 		0.39055f, 0.39148f, 0.39242f, 0.39335f,
603 		0.39430f, 0.39524f, 0.39619f, 0.39714f,
604 		0.39809f, 0.39904f, 0.40000f, 0.40097f,
605 		0.40193f, 0.40289f, 0.40386f, 0.40483f,
606 		0.40581f, 0.40679f, 0.40777f, 0.40875f,
607 		0.40974f, 0.41073f, 0.41172f, 0.41272f,
608 		0.41372f, 0.41472f, 0.41572f, 0.41673f,
609 		0.41774f, 0.41875f, 0.41977f, 0.42079f,
610 		0.42181f, 0.42284f, 0.42386f, 0.42490f,
611 		0.42594f, 0.42697f, 0.42801f, 0.42906f,
612 		0.43011f, 0.43116f, 0.43222f, 0.43327f,
613 		0.43434f, 0.43540f, 0.43647f, 0.43754f,
614 		0.43862f, 0.43970f, 0.44077f, 0.44186f,
615 		0.44295f, 0.44404f, 0.44514f, 0.44624f,
616 		0.44734f, 0.44845f, 0.44956f, 0.45068f,
617 		0.45179f, 0.45291f, 0.45404f, 0.45516f,
618 		0.45630f, 0.45744f, 0.45858f, 0.45972f,
619 		0.46086f, 0.46202f, 0.46318f, 0.46433f,
620 		0.46550f, 0.46667f, 0.46784f, 0.46901f,
621 		0.47019f, 0.47137f, 0.47256f, 0.47375f,
622 		0.47495f, 0.47615f, 0.47735f, 0.47856f,
623 		0.47977f, 0.48099f, 0.48222f, 0.48344f,
624 		0.48467f, 0.48590f, 0.48714f, 0.48838f,
625 		0.48963f, 0.49088f, 0.49213f, 0.49340f,
626 		0.49466f, 0.49593f, 0.49721f, 0.49849f,
627 		0.49977f, 0.50106f, 0.50236f, 0.50366f,
628 		0.50496f, 0.50627f, 0.50758f, 0.50890f,
629 		0.51023f, 0.51155f, 0.51289f, 0.51422f,
630 		0.51556f, 0.51692f, 0.51827f, 0.51964f,
631 		0.52100f, 0.52237f, 0.52374f, 0.52512f,
632 		0.52651f, 0.52790f, 0.52930f, 0.53070f,
633 		0.53212f, 0.53353f, 0.53495f, 0.53638f,
634 		0.53781f, 0.53925f, 0.54070f, 0.54214f,
635 		0.54360f, 0.54506f, 0.54653f, 0.54800f,
636 		0.54949f, 0.55098f, 0.55247f, 0.55396f,
637 		0.55548f, 0.55699f, 0.55851f, 0.56003f,
638 		0.56156f, 0.56310f, 0.56464f, 0.56621f,
639 		0.56777f, 0.56933f, 0.57091f, 0.57248f,
640 		0.57407f, 0.57568f, 0.57727f, 0.57888f,
641 		0.58050f, 0.58213f, 0.58376f, 0.58541f,
642 		0.58705f, 0.58871f, 0.59037f, 0.59204f,
643 		0.59373f, 0.59541f, 0.59712f, 0.59882f,
644 		0.60052f, 0.60226f, 0.60399f, 0.60572f,
645 		0.60748f, 0.60922f, 0.61099f, 0.61276f,
646 		0.61455f, 0.61635f, 0.61814f, 0.61996f,
647 		0.62178f, 0.62361f, 0.62545f, 0.62730f,
648 		0.62917f, 0.63104f, 0.63291f, 0.63480f,
649 		0.63671f, 0.63862f, 0.64054f, 0.64249f,
650 		0.64443f, 0.64638f, 0.64835f, 0.65033f,
651 		0.65232f, 0.65433f, 0.65633f, 0.65836f,
652 		0.66041f, 0.66245f, 0.66452f, 0.66660f,
653 		0.66868f, 0.67078f, 0.67290f, 0.67503f,
654 		0.67717f, 0.67932f, 0.68151f, 0.68368f,
655 		0.68587f, 0.68809f, 0.69033f, 0.69257f,
656 		0.69482f, 0.69709f, 0.69939f, 0.70169f,
657 		0.70402f, 0.70634f, 0.70869f, 0.71107f,
658 		0.71346f, 0.71587f, 0.71829f, 0.72073f,
659 		0.72320f, 0.72567f, 0.72818f, 0.73069f,
660 		0.73323f, 0.73579f, 0.73838f, 0.74098f,
661 		0.74360f, 0.74622f, 0.74890f, 0.75159f,
662 		0.75429f, 0.75704f, 0.75979f, 0.76257f,
663 		0.76537f, 0.76821f, 0.77109f, 0.77396f,
664 		0.77688f, 0.77982f, 0.78278f, 0.78579f,
665 		0.78883f, 0.79187f, 0.79498f, 0.79809f,
666 		0.80127f, 0.80445f, 0.80767f, 0.81095f,
667 		0.81424f, 0.81757f, 0.82094f, 0.82438f,
668 		0.82782f, 0.83133f, 0.83488f, 0.83847f,
669 		0.84210f, 0.84577f, 0.84951f, 0.85328f,
670 		0.85713f, 0.86103f, 0.86499f, 0.86900f,
671 		0.87306f, 0.87720f, 0.88139f, 0.88566f,
672 		0.89000f, 0.89442f, 0.89891f, 0.90350f,
673 		0.90818f, 0.91295f, 0.91780f, 0.92272f,
674 		0.92780f, 0.93299f, 0.93828f, 0.94369f,
675 		0.94926f, 0.95493f, 0.96082f, 0.96684f,
676 		0.97305f, 0.97943f, 0.98605f, 0.99291f,
677 		1.00000f
678 		};
679 
680 	const uint32 kTableSize = sizeof (kTable    ) /
681 							  sizeof (kTable [0]);
682 
683 	real32 y = (real32) x * (real32) (kTableSize - 1);
684 
685 	int32 index = Pin_int32 (0, (int32) y, kTableSize - 2);
686 
687 	real32 fract = y - (real32) index;
688 
689 	return kTable [index    ] * (1.0f - fract) +
690 		   kTable [index + 1] * (       fract);
691 
692 	}
693 
694 /*****************************************************************************/
695 
Get()696 const dng_1d_function & dng_tone_curve_acr3_default::Get ()
697 	{
698 
699 	static dng_tone_curve_acr3_default static_dng_tone_curve_acr3_default;
700 
701 	return static_dng_tone_curve_acr3_default;
702 
703 	}
704 
705 /*****************************************************************************/
706 
707 class dng_render_task: public dng_filter_task
708 	{
709 
710 	protected:
711 
712 		const dng_negative &fNegative;
713 
714 		const dng_render &fParams;
715 
716 		dng_point fSrcOffset;
717 
718 		dng_vector fCameraWhite;
719 		dng_matrix fCameraToRGB;
720 
721 		AutoPtr<dng_hue_sat_map> fHueSatMap;
722 
723 		dng_1d_table fExposureRamp;
724 
725 		AutoPtr<dng_hue_sat_map> fLookTable;
726 
727 		dng_1d_table fToneCurve;
728 
729 		dng_matrix fRGBtoFinal;
730 
731 		dng_1d_table fEncodeGamma;
732 
733 		AutoPtr<dng_1d_table> fHueSatMapEncode;
734 		AutoPtr<dng_1d_table> fHueSatMapDecode;
735 
736 		AutoPtr<dng_1d_table> fLookTableEncode;
737 		AutoPtr<dng_1d_table> fLookTableDecode;
738 
739 		AutoPtr<dng_memory_block> fTempBuffer [kMaxMPThreads];
740 
741 	public:
742 
743 		dng_render_task (const dng_image &srcImage,
744 						 dng_image &dstImage,
745 						 const dng_negative &negative,
746 						 const dng_render &params,
747 						 const dng_point &srcOffset);
748 
749 		virtual dng_rect SrcArea (const dng_rect &dstArea);
750 
751 		virtual void Start (uint32 threadCount,
752 							const dng_point &tileSize,
753 							dng_memory_allocator *allocator,
754 							dng_abort_sniffer *sniffer);
755 
756 		virtual void ProcessArea (uint32 threadIndex,
757 								  dng_pixel_buffer &srcBuffer,
758 								  dng_pixel_buffer &dstBuffer);
759 
760 	};
761 
762 /*****************************************************************************/
763 
dng_render_task(const dng_image & srcImage,dng_image & dstImage,const dng_negative & negative,const dng_render & params,const dng_point & srcOffset)764 dng_render_task::dng_render_task (const dng_image &srcImage,
765 								  dng_image &dstImage,
766 								  const dng_negative &negative,
767 								  const dng_render &params,
768 								  const dng_point &srcOffset)
769 
770 	:	dng_filter_task (srcImage,
771 						 dstImage)
772 
773 	,	fNegative  (negative )
774 	,	fParams    (params   )
775 	,	fSrcOffset (srcOffset)
776 
777 	,	fCameraWhite ()
778 	,	fCameraToRGB ()
779 
780 	,	fHueSatMap ()
781 
782 	,	fExposureRamp ()
783 
784 	,	fLookTable ()
785 
786 	,	fToneCurve ()
787 
788 	,	fRGBtoFinal ()
789 
790 	,	fEncodeGamma ()
791 
792 	,	fHueSatMapEncode ()
793 	,	fHueSatMapDecode ()
794 
795 	,	fLookTableEncode ()
796 	,	fLookTableDecode ()
797 
798 	{
799 
800 	fSrcPixelType = ttFloat;
801 	fDstPixelType = ttFloat;
802 
803 	}
804 
805 /*****************************************************************************/
806 
SrcArea(const dng_rect & dstArea)807 dng_rect dng_render_task::SrcArea (const dng_rect &dstArea)
808 	{
809 
810 	return dstArea + fSrcOffset;
811 
812 	}
813 
814 /*****************************************************************************/
815 
Start(uint32 threadCount,const dng_point & tileSize,dng_memory_allocator * allocator,dng_abort_sniffer * sniffer)816 void dng_render_task::Start (uint32 threadCount,
817 							 const dng_point &tileSize,
818 							 dng_memory_allocator *allocator,
819 							 dng_abort_sniffer *sniffer)
820 	{
821 
822 	dng_filter_task::Start (threadCount,
823 							tileSize,
824 							allocator,
825 							sniffer);
826 
827 	// Compute camera space to linear ProPhoto RGB parameters.
828 
829 	dng_camera_profile_id profileID;	// Default profile ID.
830 
831 	if (!fNegative.IsMonochrome ())
832 		{
833 
834 		AutoPtr<dng_color_spec> spec (fNegative.MakeColorSpec (profileID));
835 
836 		if (fParams.WhiteXY ().IsValid ())
837 			{
838 
839 			spec->SetWhiteXY (fParams.WhiteXY ());
840 
841 			}
842 
843 		else if (fNegative.HasCameraNeutral ())
844 			{
845 
846 			spec->SetWhiteXY (spec->NeutralToXY (fNegative.CameraNeutral ()));
847 
848 			}
849 
850 		else if (fNegative.HasCameraWhiteXY ())
851 			{
852 
853 			spec->SetWhiteXY (fNegative.CameraWhiteXY ());
854 
855 			}
856 
857 		else
858 			{
859 
860 			spec->SetWhiteXY (D55_xy_coord ());
861 
862 			}
863 
864 		fCameraWhite = spec->CameraWhite ();
865 
866 		fCameraToRGB = dng_space_ProPhoto::Get ().MatrixFromPCS () *
867 					   spec->CameraToPCS ();
868 
869 		// Find Hue/Sat table, if any.
870 
871 		const dng_camera_profile *profile = fNegative.ProfileByID (profileID);
872 
873 		if (profile)
874 			{
875 
876 			fHueSatMap.Reset (profile->HueSatMapForWhite (spec->WhiteXY ()));
877 
878 			if (profile->HasLookTable ())
879 				{
880 
881 				fLookTable.Reset (new dng_hue_sat_map (profile->LookTable ()));
882 
883 				}
884 
885 			if (profile->HueSatMapEncoding () != encoding_Linear)
886 				{
887 
888 				BuildHueSatMapEncodingTable (*allocator,
889 											 profile->HueSatMapEncoding (),
890 											 fHueSatMapEncode,
891 											 fHueSatMapDecode,
892 											 false);
893 
894 				}
895 
896 			if (profile->LookTableEncoding () != encoding_Linear)
897 				{
898 
899 				BuildHueSatMapEncodingTable (*allocator,
900 											 profile->LookTableEncoding (),
901 											 fLookTableEncode,
902 											 fLookTableDecode,
903 											 false);
904 
905 				}
906 
907 			}
908 
909 		}
910 
911 	// Compute exposure/shadows ramp.
912 
913 	real64 exposure = fParams.Exposure () +
914 					  fNegative.TotalBaselineExposure (profileID) -
915 					  (log (fNegative.Stage3Gain ()) / log (2.0));
916 
917 		{
918 
919 		real64 white = 1.0 / pow (2.0, Max_real64 (0.0, exposure));
920 
921 		real64 black = fParams.Shadows () *
922 					   fNegative.ShadowScale () *
923 					   fNegative.Stage3Gain () *
924 					   0.001;
925 
926 		black = Min_real64 (black, 0.99 * white);
927 
928 		dng_function_exposure_ramp rampFunction (white,
929 												 black,
930 												 black);
931 
932 		fExposureRamp.Initialize (*allocator, rampFunction);
933 
934 		}
935 
936 	// Compute tone curve.
937 
938 		{
939 
940 		// If there is any negative exposure compenation to perform
941 		// (beyond what the camera provides for with its baseline exposure),
942 		// we fake this by darkening the tone curve.
943 
944 		dng_function_exposure_tone exposureTone (exposure);
945 
946 		dng_1d_concatenate totalTone (exposureTone,
947 									  fParams.ToneCurve ());
948 
949 		fToneCurve.Initialize (*allocator, totalTone);
950 
951 		}
952 
953 	// Compute linear ProPhoto RGB to final space parameters.
954 
955 		{
956 
957 		const dng_color_space &finalSpace = fParams.FinalSpace ();
958 
959 		fRGBtoFinal = finalSpace.MatrixFromPCS () *
960 					  dng_space_ProPhoto::Get ().MatrixToPCS ();
961 
962 		fEncodeGamma.Initialize (*allocator, finalSpace.GammaFunction ());
963 
964 		}
965 
966 	// Allocate temp buffer to hold one row of RGB data.
967 
968 	uint32 tempBufferSize = 0;
969 
970 	if (!SafeUint32Mult (tileSize.h, (uint32) sizeof (real32), &tempBufferSize) ||
971 		 !SafeUint32Mult (tempBufferSize, 3, &tempBufferSize))
972 		{
973 
974 		ThrowMemoryFull("Arithmetic overflow computing buffer size.");
975 
976 		}
977 
978 	for (uint32 threadIndex = 0; threadIndex < threadCount; threadIndex++)
979 		{
980 
981 		fTempBuffer [threadIndex] . Reset (allocator->Allocate (tempBufferSize));
982 
983 		}
984 
985 	}
986 
987 /*****************************************************************************/
988 
ProcessArea(uint32 threadIndex,dng_pixel_buffer & srcBuffer,dng_pixel_buffer & dstBuffer)989 void dng_render_task::ProcessArea (uint32 threadIndex,
990 								   dng_pixel_buffer &srcBuffer,
991 								   dng_pixel_buffer &dstBuffer)
992 	{
993 
994 	dng_rect srcArea = srcBuffer.fArea;
995 	dng_rect dstArea = dstBuffer.fArea;
996 
997 	uint32 srcCols = srcArea.W ();
998 
999 	real32 *tPtrR = fTempBuffer [threadIndex]->Buffer_real32 ();
1000 
1001 	real32 *tPtrG = tPtrR + srcCols;
1002 	real32 *tPtrB = tPtrG + srcCols;
1003 
1004 	for (int32 srcRow = srcArea.t; srcRow < srcArea.b; srcRow++)
1005 		{
1006 
1007 		// First convert from camera native space to linear PhotoRGB,
1008 		// applying the white balance and camera profile.
1009 
1010 			{
1011 
1012 			const real32 *sPtrA = (const real32 *)
1013 								  srcBuffer.ConstPixel (srcRow,
1014 													    srcArea.l,
1015 													    0);
1016 
1017 			if (fSrcPlanes == 1)
1018 				{
1019 
1020 				// For monochrome cameras, this just requires copying
1021 				// the data into all three color channels.
1022 
1023 				DoCopyBytes (sPtrA, tPtrR, srcCols * (uint32) sizeof (real32));
1024 				DoCopyBytes (sPtrA, tPtrG, srcCols * (uint32) sizeof (real32));
1025 				DoCopyBytes (sPtrA, tPtrB, srcCols * (uint32) sizeof (real32));
1026 
1027 				}
1028 
1029 			else
1030 				{
1031 
1032 				const real32 *sPtrB = sPtrA + srcBuffer.fPlaneStep;
1033 				const real32 *sPtrC = sPtrB + srcBuffer.fPlaneStep;
1034 
1035 				if (fSrcPlanes == 3)
1036 					{
1037 
1038 					DoBaselineABCtoRGB (sPtrA,
1039 									    sPtrB,
1040 									    sPtrC,
1041 									    tPtrR,
1042 									    tPtrG,
1043 									    tPtrB,
1044 									    srcCols,
1045 									    fCameraWhite,
1046 									    fCameraToRGB);
1047 
1048 					}
1049 
1050 				else
1051 					{
1052 
1053 					const real32 *sPtrD = sPtrC + srcBuffer.fPlaneStep;
1054 
1055 					DoBaselineABCDtoRGB (sPtrA,
1056 									     sPtrB,
1057 									     sPtrC,
1058 									     sPtrD,
1059 									     tPtrR,
1060 									     tPtrG,
1061 									     tPtrB,
1062 									     srcCols,
1063 									     fCameraWhite,
1064 									     fCameraToRGB);
1065 
1066 					}
1067 
1068 				// Apply Hue/Sat map, if any.
1069 
1070 				if (fHueSatMap.Get ())
1071 					{
1072 
1073 					DoBaselineHueSatMap (tPtrR,
1074 										 tPtrG,
1075 										 tPtrB,
1076 										 tPtrR,
1077 										 tPtrG,
1078 										 tPtrB,
1079 										 srcCols,
1080 										 *fHueSatMap.Get (),
1081 										 fHueSatMapEncode.Get (),
1082 										 fHueSatMapDecode.Get ());
1083 
1084 					}
1085 
1086 				}
1087 
1088 			}
1089 
1090 		// Apply exposure curve.
1091 
1092 		DoBaseline1DTable (tPtrR,
1093 						   tPtrR,
1094 						   srcCols,
1095 						   fExposureRamp);
1096 
1097 		DoBaseline1DTable (tPtrG,
1098 						   tPtrG,
1099 						   srcCols,
1100 						   fExposureRamp);
1101 
1102 		DoBaseline1DTable (tPtrB,
1103 						   tPtrB,
1104 						   srcCols,
1105 						   fExposureRamp);
1106 
1107 		// Apply look table, if any.
1108 
1109 		if (fLookTable.Get ())
1110 			{
1111 
1112 			DoBaselineHueSatMap (tPtrR,
1113 								 tPtrG,
1114 								 tPtrB,
1115 								 tPtrR,
1116 								 tPtrG,
1117 								 tPtrB,
1118 								 srcCols,
1119 								 *fLookTable.Get (),
1120 								 fLookTableEncode.Get (),
1121 								 fLookTableDecode.Get ());
1122 
1123 			}
1124 
1125 		// Apply baseline tone curve.
1126 
1127 		DoBaselineRGBTone (tPtrR,
1128 					       tPtrG,
1129 						   tPtrB,
1130 						   tPtrR,
1131 					       tPtrG,
1132 						   tPtrB,
1133 						   srcCols,
1134 						   fToneCurve);
1135 
1136 		// Convert to final color space.
1137 
1138 		int32 dstRow = srcRow + (dstArea.t - srcArea.t);
1139 
1140 		if (fDstPlanes == 1)
1141 			{
1142 
1143 			real32 *dPtrG = dstBuffer.DirtyPixel_real32 (dstRow,
1144 														 dstArea.l,
1145 														 0);
1146 
1147 			DoBaselineRGBtoGray (tPtrR,
1148 								 tPtrG,
1149 								 tPtrB,
1150 								 dPtrG,
1151 								 srcCols,
1152 								 fRGBtoFinal);
1153 
1154 			DoBaseline1DTable (dPtrG,
1155 							   dPtrG,
1156 							   srcCols,
1157 							   fEncodeGamma);
1158 
1159 			}
1160 
1161 		else
1162 			{
1163 
1164 			real32 *dPtrR = dstBuffer.DirtyPixel_real32 (dstRow,
1165 														 dstArea.l,
1166 														 0);
1167 
1168 			real32 *dPtrG = dPtrR + dstBuffer.fPlaneStep;
1169 			real32 *dPtrB = dPtrG + dstBuffer.fPlaneStep;
1170 
1171 			DoBaselineRGBtoRGB (tPtrR,
1172 								tPtrG,
1173 								tPtrB,
1174 								dPtrR,
1175 								dPtrG,
1176 								dPtrB,
1177 								srcCols,
1178 								fRGBtoFinal);
1179 
1180 			DoBaseline1DTable (dPtrR,
1181 							   dPtrR,
1182 							   srcCols,
1183 							   fEncodeGamma);
1184 
1185 			DoBaseline1DTable (dPtrG,
1186 							   dPtrG,
1187 							   srcCols,
1188 							   fEncodeGamma);
1189 
1190 			DoBaseline1DTable (dPtrB,
1191 							   dPtrB,
1192 							   srcCols,
1193 							   fEncodeGamma);
1194 
1195 			}
1196 
1197 		}
1198 
1199 	}
1200 
1201 /*****************************************************************************/
1202 
dng_render(dng_host & host,const dng_negative & negative)1203 dng_render::dng_render (dng_host &host,
1204 						const dng_negative &negative)
1205 
1206 	:	fHost			(host)
1207 	,	fNegative		(negative)
1208 
1209 	,	fWhiteXY		()
1210 
1211 	,	fExposure		(0.0)
1212 	,	fShadows		(5.0)
1213 
1214 	,	fToneCurve		(&dng_tone_curve_acr3_default::Get ())
1215 
1216 	,	fFinalSpace		(&dng_space_sRGB::Get ())
1217 	,	fFinalPixelType (ttByte)
1218 
1219 	,	fMaximumSize	(0)
1220 
1221 	,	fProfileToneCurve ()
1222 
1223 	{
1224 
1225 	// Switch to NOP default parameters for non-scene referred data.
1226 
1227 	if (fNegative.ColorimetricReference () != crSceneReferred)
1228 		{
1229 
1230 		fShadows = 0.0;
1231 
1232 		fToneCurve = &dng_1d_identity::Get ();
1233 
1234 		}
1235 
1236 	// Use default tone curve from profile if any.
1237 
1238 	const dng_camera_profile *profile = fNegative.ProfileByID (dng_camera_profile_id ());
1239 
1240 	if (profile && profile->ToneCurve ().IsValid ())
1241 		{
1242 
1243 		fProfileToneCurve.Reset (new dng_spline_solver);
1244 
1245 		profile->ToneCurve ().Solve (*fProfileToneCurve.Get ());
1246 
1247 		fToneCurve = fProfileToneCurve.Get ();
1248 
1249 		}
1250 
1251 	// Turn off default shadow mapping if requested by profile.
1252 
1253 	if (profile && (profile->DefaultBlackRender () == defaultBlackRender_None))
1254 		{
1255 
1256 		fShadows = 0.0;
1257 
1258 		}
1259 
1260 	}
1261 
1262 /*****************************************************************************/
1263 
Render()1264 dng_image * dng_render::Render ()
1265 	{
1266 
1267 	const dng_image *srcImage = fNegative.Stage3Image ();
1268 
1269 	dng_rect srcBounds = fNegative.DefaultCropArea ();
1270 
1271 	dng_point dstSize;
1272 
1273 	dstSize.h =	fNegative.DefaultFinalWidth  ();
1274 	dstSize.v = fNegative.DefaultFinalHeight ();
1275 
1276 	if (MaximumSize ())
1277 		{
1278 
1279 		if (Max_uint32 (dstSize.h, dstSize.v) > MaximumSize ())
1280 			{
1281 
1282 			real64 ratio = fNegative.AspectRatio ();
1283 
1284 			if (ratio >= 1.0)
1285 				{
1286 				dstSize.h = MaximumSize ();
1287 				dstSize.v = Max_uint32 (1, Round_uint32 (dstSize.h / ratio));
1288 				}
1289 
1290 			else
1291 				{
1292 				dstSize.v = MaximumSize ();
1293 				dstSize.h = Max_uint32 (1, Round_uint32 (dstSize.v * ratio));
1294 				}
1295 
1296 			}
1297 
1298 		}
1299 
1300 	AutoPtr<dng_image> tempImage;
1301 
1302 	if (srcBounds.Size () != dstSize)
1303 		{
1304 
1305 		tempImage.Reset (fHost.Make_dng_image (dstSize,
1306 											   srcImage->Planes    (),
1307 											   srcImage->PixelType ()));
1308 
1309 		ResampleImage (fHost,
1310 					   *srcImage,
1311 					   *tempImage.Get (),
1312 					   srcBounds,
1313 					   tempImage->Bounds (),
1314 					   dng_resample_bicubic::Get ());
1315 
1316 		srcImage = tempImage.Get ();
1317 
1318 		srcBounds = tempImage->Bounds ();
1319 
1320 		}
1321 
1322 	uint32 dstPlanes = FinalSpace ().IsMonochrome () ? 1 : 3;
1323 
1324 	AutoPtr<dng_image> dstImage (fHost.Make_dng_image (srcBounds.Size (),
1325 													   dstPlanes,
1326 													   FinalPixelType ()));
1327 
1328 	dng_render_task task (*srcImage,
1329 						  *dstImage.Get (),
1330 						  fNegative,
1331 						  *this,
1332 						  srcBounds.TL ());
1333 
1334 	fHost.PerformAreaTask (task,
1335 						   dstImage->Bounds ());
1336 
1337 	return dstImage.Release ();
1338 
1339 	}
1340 
1341 /*****************************************************************************/
1342