Home | History | Annotate | Download | only in source
      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 
     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 
     65 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 
     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 
    116 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 
    136 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 
    416 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 
    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 
    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 
    807 dng_rect dng_render_task::SrcArea (const dng_rect &dstArea)
    808 	{
    809 
    810 	return dstArea + fSrcOffset;
    811 
    812 	}
    813 
    814 /*****************************************************************************/
    815 
    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 
    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 
   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 
   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