File indexing completed on 2025-01-19 03:55:15

0001 /*****************************************************************************/
0002 // Copyright 2006-2019 Adobe Systems Incorporated
0003 // All Rights Reserved.
0004 //
0005 // NOTICE:  Adobe permits you to use, modify, and distribute this file in
0006 // accordance with the terms of the Adobe license agreement accompanying it.
0007 /*****************************************************************************/
0008 
0009 #include "dng_render.h"
0010 
0011 #include "dng_1d_table.h"
0012 #include "dng_bottlenecks.h"
0013 #include "dng_camera_profile.h"
0014 #include "dng_color_space.h"
0015 #include "dng_color_spec.h"
0016 #include "dng_filter_task.h"
0017 #include "dng_host.h"
0018 #include "dng_image.h"
0019 #include "dng_negative.h"
0020 #include "dng_resample.h"
0021 #include "dng_safe_arithmetic.h"
0022 #include "dng_utils.h"
0023 
0024 /*****************************************************************************/
0025 
0026 dng_function_zero_offset::dng_function_zero_offset (real64 zeroOffset)
0027 
0028     :   fZeroOffset (zeroOffset)
0029 
0030     ,   fScale (1.0 / (1.0 - zeroOffset))
0031 
0032     {
0033 
0034     }
0035 
0036 /*****************************************************************************/
0037 
0038 real64 dng_function_zero_offset::Evaluate (real64 x) const
0039     {
0040 
0041     return Pin_real64 (0.0, (x - fZeroOffset) * fScale, 1.0);
0042 
0043     }
0044 
0045 /*****************************************************************************/
0046 
0047 dng_function_exposure_ramp::dng_function_exposure_ramp (real64 white,
0048                                                         real64 black,
0049                                                         real64 minBlack)
0050 
0051     :   fSlope (1.0 / (white - black))
0052     ,   fBlack (black)
0053 
0054     ,   fRadius (0.0)
0055     ,   fQScale (0.0)
0056 
0057     {
0058 
0059     const real64 kMaxCurveX = 0.5;          // Fraction of minBlack.
0060 
0061     const real64 kMaxCurveY = 1.0 / 16.0;   // Fraction of white.
0062 
0063     fRadius = Min_real64 (kMaxCurveX * minBlack,
0064                           kMaxCurveY / fSlope);
0065 
0066     if (fRadius > 0.0)
0067         fQScale= fSlope / (4.0 * fRadius);
0068     else
0069         fQScale = 0.0;
0070 
0071     }
0072 
0073 /*****************************************************************************/
0074 
0075 real64 dng_function_exposure_ramp::Evaluate (real64 x) const
0076     {
0077 
0078     if (x <= fBlack - fRadius)
0079         return 0.0;
0080 
0081     if (x >= fBlack + fRadius)
0082         return Min_real64 ((x - fBlack) * fSlope, 1.0);
0083 
0084     real64 y = x - (fBlack - fRadius);
0085 
0086     return fQScale * y * y;
0087 
0088     }
0089 
0090 /*****************************************************************************/
0091 
0092 dng_function_exposure_tone::dng_function_exposure_tone (real64 exposure)
0093 
0094     :   fIsNOP (exposure >= 0.0)
0095 
0096     ,   fSlope (0.0)
0097 
0098     ,   a (0.0)
0099     ,   b (0.0)
0100     ,   c (0.0)
0101 
0102     {
0103 
0104     if (!fIsNOP)
0105         {
0106 
0107         // Find slope to use for the all except the highest two f-stops.
0108 
0109         fSlope = pow (2.0, exposure);
0110 
0111         // Find quadradic parameters that match this darking at the crossover
0112         // point, yet still map pure white to pure white.
0113 
0114         a = 16.0 / 9.0 * (1.0 - fSlope);
0115 
0116         b = fSlope - 0.5 * a;
0117 
0118         c = 1.0 - a - b;
0119 
0120         }
0121 
0122     }
0123 
0124 /*****************************************************************************/
0125 
0126 real64 dng_function_exposure_tone::Evaluate (real64 x) const
0127     {
0128 
0129     if (!fIsNOP)
0130         {
0131 
0132         if (x <= 0.25)
0133             x = x * fSlope;
0134 
0135         else
0136             x = (a * x + b) * x + c;
0137 
0138         }
0139 
0140     return x;
0141 
0142     }
0143 
0144 /*****************************************************************************/
0145 
0146 real64 dng_tone_curve_acr3_default::Evaluate (real64 x) const
0147     {
0148 
0149     static const real32 kTable [] =
0150         {
0151         0.00000f, 0.00078f, 0.00160f, 0.00242f,
0152         0.00314f, 0.00385f, 0.00460f, 0.00539f,
0153         0.00623f, 0.00712f, 0.00806f, 0.00906f,
0154         0.01012f, 0.01122f, 0.01238f, 0.01359f,
0155         0.01485f, 0.01616f, 0.01751f, 0.01890f,
0156         0.02033f, 0.02180f, 0.02331f, 0.02485f,
0157         0.02643f, 0.02804f, 0.02967f, 0.03134f,
0158         0.03303f, 0.03475f, 0.03648f, 0.03824f,
0159         0.04002f, 0.04181f, 0.04362f, 0.04545f,
0160         0.04730f, 0.04916f, 0.05103f, 0.05292f,
0161         0.05483f, 0.05675f, 0.05868f, 0.06063f,
0162         0.06259f, 0.06457f, 0.06655f, 0.06856f,
0163         0.07057f, 0.07259f, 0.07463f, 0.07668f,
0164         0.07874f, 0.08081f, 0.08290f, 0.08499f,
0165         0.08710f, 0.08921f, 0.09134f, 0.09348f,
0166         0.09563f, 0.09779f, 0.09996f, 0.10214f,
0167         0.10433f, 0.10652f, 0.10873f, 0.11095f,
0168         0.11318f, 0.11541f, 0.11766f, 0.11991f,
0169         0.12218f, 0.12445f, 0.12673f, 0.12902f,
0170         0.13132f, 0.13363f, 0.13595f, 0.13827f,
0171         0.14061f, 0.14295f, 0.14530f, 0.14765f,
0172         0.15002f, 0.15239f, 0.15477f, 0.15716f,
0173         0.15956f, 0.16197f, 0.16438f, 0.16680f,
0174         0.16923f, 0.17166f, 0.17410f, 0.17655f,
0175         0.17901f, 0.18148f, 0.18395f, 0.18643f,
0176         0.18891f, 0.19141f, 0.19391f, 0.19641f,
0177         0.19893f, 0.20145f, 0.20398f, 0.20651f,
0178         0.20905f, 0.21160f, 0.21416f, 0.21672f,
0179         0.21929f, 0.22185f, 0.22440f, 0.22696f,
0180         0.22950f, 0.23204f, 0.23458f, 0.23711f,
0181         0.23963f, 0.24215f, 0.24466f, 0.24717f,
0182         0.24967f, 0.25216f, 0.25465f, 0.25713f,
0183         0.25961f, 0.26208f, 0.26454f, 0.26700f,
0184         0.26945f, 0.27189f, 0.27433f, 0.27676f,
0185         0.27918f, 0.28160f, 0.28401f, 0.28641f,
0186         0.28881f, 0.29120f, 0.29358f, 0.29596f,
0187         0.29833f, 0.30069f, 0.30305f, 0.30540f,
0188         0.30774f, 0.31008f, 0.31241f, 0.31473f,
0189         0.31704f, 0.31935f, 0.32165f, 0.32395f,
0190         0.32623f, 0.32851f, 0.33079f, 0.33305f,
0191         0.33531f, 0.33756f, 0.33981f, 0.34205f,
0192         0.34428f, 0.34650f, 0.34872f, 0.35093f,
0193         0.35313f, 0.35532f, 0.35751f, 0.35969f,
0194         0.36187f, 0.36404f, 0.36620f, 0.36835f,
0195         0.37050f, 0.37264f, 0.37477f, 0.37689f,
0196         0.37901f, 0.38112f, 0.38323f, 0.38533f,
0197         0.38742f, 0.38950f, 0.39158f, 0.39365f,
0198         0.39571f, 0.39777f, 0.39982f, 0.40186f,
0199         0.40389f, 0.40592f, 0.40794f, 0.40996f,
0200         0.41197f, 0.41397f, 0.41596f, 0.41795f,
0201         0.41993f, 0.42191f, 0.42388f, 0.42584f,
0202         0.42779f, 0.42974f, 0.43168f, 0.43362f,
0203         0.43554f, 0.43747f, 0.43938f, 0.44129f,
0204         0.44319f, 0.44509f, 0.44698f, 0.44886f,
0205         0.45073f, 0.45260f, 0.45447f, 0.45632f,
0206         0.45817f, 0.46002f, 0.46186f, 0.46369f,
0207         0.46551f, 0.46733f, 0.46914f, 0.47095f,
0208         0.47275f, 0.47454f, 0.47633f, 0.47811f,
0209         0.47989f, 0.48166f, 0.48342f, 0.48518f,
0210         0.48693f, 0.48867f, 0.49041f, 0.49214f,
0211         0.49387f, 0.49559f, 0.49730f, 0.49901f,
0212         0.50072f, 0.50241f, 0.50410f, 0.50579f,
0213         0.50747f, 0.50914f, 0.51081f, 0.51247f,
0214         0.51413f, 0.51578f, 0.51742f, 0.51906f,
0215         0.52069f, 0.52232f, 0.52394f, 0.52556f,
0216         0.52717f, 0.52878f, 0.53038f, 0.53197f,
0217         0.53356f, 0.53514f, 0.53672f, 0.53829f,
0218         0.53986f, 0.54142f, 0.54297f, 0.54452f,
0219         0.54607f, 0.54761f, 0.54914f, 0.55067f,
0220         0.55220f, 0.55371f, 0.55523f, 0.55673f,
0221         0.55824f, 0.55973f, 0.56123f, 0.56271f,
0222         0.56420f, 0.56567f, 0.56715f, 0.56861f,
0223         0.57007f, 0.57153f, 0.57298f, 0.57443f,
0224         0.57587f, 0.57731f, 0.57874f, 0.58017f,
0225         0.58159f, 0.58301f, 0.58443f, 0.58583f,
0226         0.58724f, 0.58864f, 0.59003f, 0.59142f,
0227         0.59281f, 0.59419f, 0.59556f, 0.59694f,
0228         0.59830f, 0.59966f, 0.60102f, 0.60238f,
0229         0.60373f, 0.60507f, 0.60641f, 0.60775f,
0230         0.60908f, 0.61040f, 0.61173f, 0.61305f,
0231         0.61436f, 0.61567f, 0.61698f, 0.61828f,
0232         0.61957f, 0.62087f, 0.62216f, 0.62344f,
0233         0.62472f, 0.62600f, 0.62727f, 0.62854f,
0234         0.62980f, 0.63106f, 0.63232f, 0.63357f,
0235         0.63482f, 0.63606f, 0.63730f, 0.63854f,
0236         0.63977f, 0.64100f, 0.64222f, 0.64344f,
0237         0.64466f, 0.64587f, 0.64708f, 0.64829f,
0238         0.64949f, 0.65069f, 0.65188f, 0.65307f,
0239         0.65426f, 0.65544f, 0.65662f, 0.65779f,
0240         0.65897f, 0.66013f, 0.66130f, 0.66246f,
0241         0.66362f, 0.66477f, 0.66592f, 0.66707f,
0242         0.66821f, 0.66935f, 0.67048f, 0.67162f,
0243         0.67275f, 0.67387f, 0.67499f, 0.67611f,
0244         0.67723f, 0.67834f, 0.67945f, 0.68055f,
0245         0.68165f, 0.68275f, 0.68385f, 0.68494f,
0246         0.68603f, 0.68711f, 0.68819f, 0.68927f,
0247         0.69035f, 0.69142f, 0.69249f, 0.69355f,
0248         0.69461f, 0.69567f, 0.69673f, 0.69778f,
0249         0.69883f, 0.69988f, 0.70092f, 0.70196f,
0250         0.70300f, 0.70403f, 0.70506f, 0.70609f,
0251         0.70711f, 0.70813f, 0.70915f, 0.71017f,
0252         0.71118f, 0.71219f, 0.71319f, 0.71420f,
0253         0.71520f, 0.71620f, 0.71719f, 0.71818f,
0254         0.71917f, 0.72016f, 0.72114f, 0.72212f,
0255         0.72309f, 0.72407f, 0.72504f, 0.72601f,
0256         0.72697f, 0.72794f, 0.72890f, 0.72985f,
0257         0.73081f, 0.73176f, 0.73271f, 0.73365f,
0258         0.73460f, 0.73554f, 0.73647f, 0.73741f,
0259         0.73834f, 0.73927f, 0.74020f, 0.74112f,
0260         0.74204f, 0.74296f, 0.74388f, 0.74479f,
0261         0.74570f, 0.74661f, 0.74751f, 0.74842f,
0262         0.74932f, 0.75021f, 0.75111f, 0.75200f,
0263         0.75289f, 0.75378f, 0.75466f, 0.75555f,
0264         0.75643f, 0.75730f, 0.75818f, 0.75905f,
0265         0.75992f, 0.76079f, 0.76165f, 0.76251f,
0266         0.76337f, 0.76423f, 0.76508f, 0.76594f,
0267         0.76679f, 0.76763f, 0.76848f, 0.76932f,
0268         0.77016f, 0.77100f, 0.77183f, 0.77267f,
0269         0.77350f, 0.77432f, 0.77515f, 0.77597f,
0270         0.77680f, 0.77761f, 0.77843f, 0.77924f,
0271         0.78006f, 0.78087f, 0.78167f, 0.78248f,
0272         0.78328f, 0.78408f, 0.78488f, 0.78568f,
0273         0.78647f, 0.78726f, 0.78805f, 0.78884f,
0274         0.78962f, 0.79040f, 0.79118f, 0.79196f,
0275         0.79274f, 0.79351f, 0.79428f, 0.79505f,
0276         0.79582f, 0.79658f, 0.79735f, 0.79811f,
0277         0.79887f, 0.79962f, 0.80038f, 0.80113f,
0278         0.80188f, 0.80263f, 0.80337f, 0.80412f,
0279         0.80486f, 0.80560f, 0.80634f, 0.80707f,
0280         0.80780f, 0.80854f, 0.80926f, 0.80999f,
0281         0.81072f, 0.81144f, 0.81216f, 0.81288f,
0282         0.81360f, 0.81431f, 0.81503f, 0.81574f,
0283         0.81645f, 0.81715f, 0.81786f, 0.81856f,
0284         0.81926f, 0.81996f, 0.82066f, 0.82135f,
0285         0.82205f, 0.82274f, 0.82343f, 0.82412f,
0286         0.82480f, 0.82549f, 0.82617f, 0.82685f,
0287         0.82753f, 0.82820f, 0.82888f, 0.82955f,
0288         0.83022f, 0.83089f, 0.83155f, 0.83222f,
0289         0.83288f, 0.83354f, 0.83420f, 0.83486f,
0290         0.83552f, 0.83617f, 0.83682f, 0.83747f,
0291         0.83812f, 0.83877f, 0.83941f, 0.84005f,
0292         0.84069f, 0.84133f, 0.84197f, 0.84261f,
0293         0.84324f, 0.84387f, 0.84450f, 0.84513f,
0294         0.84576f, 0.84639f, 0.84701f, 0.84763f,
0295         0.84825f, 0.84887f, 0.84949f, 0.85010f,
0296         0.85071f, 0.85132f, 0.85193f, 0.85254f,
0297         0.85315f, 0.85375f, 0.85436f, 0.85496f,
0298         0.85556f, 0.85615f, 0.85675f, 0.85735f,
0299         0.85794f, 0.85853f, 0.85912f, 0.85971f,
0300         0.86029f, 0.86088f, 0.86146f, 0.86204f,
0301         0.86262f, 0.86320f, 0.86378f, 0.86435f,
0302         0.86493f, 0.86550f, 0.86607f, 0.86664f,
0303         0.86720f, 0.86777f, 0.86833f, 0.86889f,
0304         0.86945f, 0.87001f, 0.87057f, 0.87113f,
0305         0.87168f, 0.87223f, 0.87278f, 0.87333f,
0306         0.87388f, 0.87443f, 0.87497f, 0.87552f,
0307         0.87606f, 0.87660f, 0.87714f, 0.87768f,
0308         0.87821f, 0.87875f, 0.87928f, 0.87981f,
0309         0.88034f, 0.88087f, 0.88140f, 0.88192f,
0310         0.88244f, 0.88297f, 0.88349f, 0.88401f,
0311         0.88453f, 0.88504f, 0.88556f, 0.88607f,
0312         0.88658f, 0.88709f, 0.88760f, 0.88811f,
0313         0.88862f, 0.88912f, 0.88963f, 0.89013f,
0314         0.89063f, 0.89113f, 0.89163f, 0.89212f,
0315         0.89262f, 0.89311f, 0.89360f, 0.89409f,
0316         0.89458f, 0.89507f, 0.89556f, 0.89604f,
0317         0.89653f, 0.89701f, 0.89749f, 0.89797f,
0318         0.89845f, 0.89892f, 0.89940f, 0.89987f,
0319         0.90035f, 0.90082f, 0.90129f, 0.90176f,
0320         0.90222f, 0.90269f, 0.90316f, 0.90362f,
0321         0.90408f, 0.90454f, 0.90500f, 0.90546f,
0322         0.90592f, 0.90637f, 0.90683f, 0.90728f,
0323         0.90773f, 0.90818f, 0.90863f, 0.90908f,
0324         0.90952f, 0.90997f, 0.91041f, 0.91085f,
0325         0.91130f, 0.91173f, 0.91217f, 0.91261f,
0326         0.91305f, 0.91348f, 0.91392f, 0.91435f,
0327         0.91478f, 0.91521f, 0.91564f, 0.91606f,
0328         0.91649f, 0.91691f, 0.91734f, 0.91776f,
0329         0.91818f, 0.91860f, 0.91902f, 0.91944f,
0330         0.91985f, 0.92027f, 0.92068f, 0.92109f,
0331         0.92150f, 0.92191f, 0.92232f, 0.92273f,
0332         0.92314f, 0.92354f, 0.92395f, 0.92435f,
0333         0.92475f, 0.92515f, 0.92555f, 0.92595f,
0334         0.92634f, 0.92674f, 0.92713f, 0.92753f,
0335         0.92792f, 0.92831f, 0.92870f, 0.92909f,
0336         0.92947f, 0.92986f, 0.93025f, 0.93063f,
0337         0.93101f, 0.93139f, 0.93177f, 0.93215f,
0338         0.93253f, 0.93291f, 0.93328f, 0.93366f,
0339         0.93403f, 0.93440f, 0.93478f, 0.93515f,
0340         0.93551f, 0.93588f, 0.93625f, 0.93661f,
0341         0.93698f, 0.93734f, 0.93770f, 0.93807f,
0342         0.93843f, 0.93878f, 0.93914f, 0.93950f,
0343         0.93986f, 0.94021f, 0.94056f, 0.94092f,
0344         0.94127f, 0.94162f, 0.94197f, 0.94231f,
0345         0.94266f, 0.94301f, 0.94335f, 0.94369f,
0346         0.94404f, 0.94438f, 0.94472f, 0.94506f,
0347         0.94540f, 0.94573f, 0.94607f, 0.94641f,
0348         0.94674f, 0.94707f, 0.94740f, 0.94774f,
0349         0.94807f, 0.94839f, 0.94872f, 0.94905f,
0350         0.94937f, 0.94970f, 0.95002f, 0.95035f,
0351         0.95067f, 0.95099f, 0.95131f, 0.95163f,
0352         0.95194f, 0.95226f, 0.95257f, 0.95289f,
0353         0.95320f, 0.95351f, 0.95383f, 0.95414f,
0354         0.95445f, 0.95475f, 0.95506f, 0.95537f,
0355         0.95567f, 0.95598f, 0.95628f, 0.95658f,
0356         0.95688f, 0.95718f, 0.95748f, 0.95778f,
0357         0.95808f, 0.95838f, 0.95867f, 0.95897f,
0358         0.95926f, 0.95955f, 0.95984f, 0.96013f,
0359         0.96042f, 0.96071f, 0.96100f, 0.96129f,
0360         0.96157f, 0.96186f, 0.96214f, 0.96242f,
0361         0.96271f, 0.96299f, 0.96327f, 0.96355f,
0362         0.96382f, 0.96410f, 0.96438f, 0.96465f,
0363         0.96493f, 0.96520f, 0.96547f, 0.96574f,
0364         0.96602f, 0.96629f, 0.96655f, 0.96682f,
0365         0.96709f, 0.96735f, 0.96762f, 0.96788f,
0366         0.96815f, 0.96841f, 0.96867f, 0.96893f,
0367         0.96919f, 0.96945f, 0.96971f, 0.96996f,
0368         0.97022f, 0.97047f, 0.97073f, 0.97098f,
0369         0.97123f, 0.97149f, 0.97174f, 0.97199f,
0370         0.97223f, 0.97248f, 0.97273f, 0.97297f,
0371         0.97322f, 0.97346f, 0.97371f, 0.97395f,
0372         0.97419f, 0.97443f, 0.97467f, 0.97491f,
0373         0.97515f, 0.97539f, 0.97562f, 0.97586f,
0374         0.97609f, 0.97633f, 0.97656f, 0.97679f,
0375         0.97702f, 0.97725f, 0.97748f, 0.97771f,
0376         0.97794f, 0.97817f, 0.97839f, 0.97862f,
0377         0.97884f, 0.97907f, 0.97929f, 0.97951f,
0378         0.97973f, 0.97995f, 0.98017f, 0.98039f,
0379         0.98061f, 0.98082f, 0.98104f, 0.98125f,
0380         0.98147f, 0.98168f, 0.98189f, 0.98211f,
0381         0.98232f, 0.98253f, 0.98274f, 0.98295f,
0382         0.98315f, 0.98336f, 0.98357f, 0.98377f,
0383         0.98398f, 0.98418f, 0.98438f, 0.98458f,
0384         0.98478f, 0.98498f, 0.98518f, 0.98538f,
0385         0.98558f, 0.98578f, 0.98597f, 0.98617f,
0386         0.98636f, 0.98656f, 0.98675f, 0.98694f,
0387         0.98714f, 0.98733f, 0.98752f, 0.98771f,
0388         0.98789f, 0.98808f, 0.98827f, 0.98845f,
0389         0.98864f, 0.98882f, 0.98901f, 0.98919f,
0390         0.98937f, 0.98955f, 0.98973f, 0.98991f,
0391         0.99009f, 0.99027f, 0.99045f, 0.99063f,
0392         0.99080f, 0.99098f, 0.99115f, 0.99133f,
0393         0.99150f, 0.99167f, 0.99184f, 0.99201f,
0394         0.99218f, 0.99235f, 0.99252f, 0.99269f,
0395         0.99285f, 0.99302f, 0.99319f, 0.99335f,
0396         0.99351f, 0.99368f, 0.99384f, 0.99400f,
0397         0.99416f, 0.99432f, 0.99448f, 0.99464f,
0398         0.99480f, 0.99495f, 0.99511f, 0.99527f,
0399         0.99542f, 0.99558f, 0.99573f, 0.99588f,
0400         0.99603f, 0.99619f, 0.99634f, 0.99649f,
0401         0.99664f, 0.99678f, 0.99693f, 0.99708f,
0402         0.99722f, 0.99737f, 0.99751f, 0.99766f,
0403         0.99780f, 0.99794f, 0.99809f, 0.99823f,
0404         0.99837f, 0.99851f, 0.99865f, 0.99879f,
0405         0.99892f, 0.99906f, 0.99920f, 0.99933f,
0406         0.99947f, 0.99960f, 0.99974f, 0.99987f,
0407         1.00000f
0408         };
0409 
0410     const uint32 kTableSize = sizeof (kTable    ) /
0411                               sizeof (kTable [0]);
0412 
0413     real32 y = (real32) x * (real32) (kTableSize - 1);
0414 
0415     int32 index = Pin_int32 (0, (int32) y, kTableSize - 2);
0416 
0417     real32 fract = y - (real32) index;
0418 
0419     return kTable [index    ] * (1.0f - fract) +
0420            kTable [index + 1] * (       fract);
0421 
0422     }
0423 
0424 /*****************************************************************************/
0425 
0426 real64 dng_tone_curve_acr3_default::EvaluateInverse (real64 x) const
0427     {
0428 
0429     static const real32 kTable [] =
0430         {
0431         0.00000f, 0.00121f, 0.00237f, 0.00362f,
0432         0.00496f, 0.00621f, 0.00738f, 0.00848f,
0433         0.00951f, 0.01048f, 0.01139f, 0.01227f,
0434         0.01312f, 0.01393f, 0.01471f, 0.01547f,
0435         0.01620f, 0.01692f, 0.01763f, 0.01831f,
0436         0.01899f, 0.01965f, 0.02030f, 0.02094f,
0437         0.02157f, 0.02218f, 0.02280f, 0.02340f,
0438         0.02399f, 0.02458f, 0.02517f, 0.02574f,
0439         0.02631f, 0.02688f, 0.02744f, 0.02800f,
0440         0.02855f, 0.02910f, 0.02965f, 0.03019f,
0441         0.03072f, 0.03126f, 0.03179f, 0.03232f,
0442         0.03285f, 0.03338f, 0.03390f, 0.03442f,
0443         0.03493f, 0.03545f, 0.03596f, 0.03647f,
0444         0.03698f, 0.03749f, 0.03799f, 0.03849f,
0445         0.03899f, 0.03949f, 0.03998f, 0.04048f,
0446         0.04097f, 0.04146f, 0.04195f, 0.04244f,
0447         0.04292f, 0.04341f, 0.04389f, 0.04437f,
0448         0.04485f, 0.04533f, 0.04580f, 0.04628f,
0449         0.04675f, 0.04722f, 0.04769f, 0.04816f,
0450         0.04863f, 0.04910f, 0.04956f, 0.05003f,
0451         0.05049f, 0.05095f, 0.05141f, 0.05187f,
0452         0.05233f, 0.05278f, 0.05324f, 0.05370f,
0453         0.05415f, 0.05460f, 0.05505f, 0.05551f,
0454         0.05595f, 0.05640f, 0.05685f, 0.05729f,
0455         0.05774f, 0.05818f, 0.05863f, 0.05907f,
0456         0.05951f, 0.05995f, 0.06039f, 0.06083f,
0457         0.06126f, 0.06170f, 0.06214f, 0.06257f,
0458         0.06301f, 0.06344f, 0.06388f, 0.06431f,
0459         0.06474f, 0.06517f, 0.06560f, 0.06602f,
0460         0.06645f, 0.06688f, 0.06731f, 0.06773f,
0461         0.06815f, 0.06858f, 0.06900f, 0.06943f,
0462         0.06985f, 0.07027f, 0.07069f, 0.07111f,
0463         0.07152f, 0.07194f, 0.07236f, 0.07278f,
0464         0.07319f, 0.07361f, 0.07402f, 0.07444f,
0465         0.07485f, 0.07526f, 0.07567f, 0.07608f,
0466         0.07650f, 0.07691f, 0.07732f, 0.07772f,
0467         0.07813f, 0.07854f, 0.07895f, 0.07935f,
0468         0.07976f, 0.08016f, 0.08057f, 0.08098f,
0469         0.08138f, 0.08178f, 0.08218f, 0.08259f,
0470         0.08299f, 0.08339f, 0.08379f, 0.08419f,
0471         0.08459f, 0.08499f, 0.08539f, 0.08578f,
0472         0.08618f, 0.08657f, 0.08697f, 0.08737f,
0473         0.08776f, 0.08816f, 0.08855f, 0.08894f,
0474         0.08934f, 0.08973f, 0.09012f, 0.09051f,
0475         0.09091f, 0.09130f, 0.09169f, 0.09208f,
0476         0.09247f, 0.09286f, 0.09324f, 0.09363f,
0477         0.09402f, 0.09440f, 0.09479f, 0.09518f,
0478         0.09556f, 0.09595f, 0.09633f, 0.09672f,
0479         0.09710f, 0.09749f, 0.09787f, 0.09825f,
0480         0.09863f, 0.09901f, 0.09939f, 0.09978f,
0481         0.10016f, 0.10054f, 0.10092f, 0.10130f,
0482         0.10167f, 0.10205f, 0.10243f, 0.10281f,
0483         0.10319f, 0.10356f, 0.10394f, 0.10432f,
0484         0.10469f, 0.10507f, 0.10544f, 0.10582f,
0485         0.10619f, 0.10657f, 0.10694f, 0.10731f,
0486         0.10768f, 0.10806f, 0.10843f, 0.10880f,
0487         0.10917f, 0.10954f, 0.10991f, 0.11029f,
0488         0.11066f, 0.11103f, 0.11141f, 0.11178f,
0489         0.11215f, 0.11253f, 0.11290f, 0.11328f,
0490         0.11365f, 0.11403f, 0.11440f, 0.11478f,
0491         0.11516f, 0.11553f, 0.11591f, 0.11629f,
0492         0.11666f, 0.11704f, 0.11742f, 0.11780f,
0493         0.11818f, 0.11856f, 0.11894f, 0.11932f,
0494         0.11970f, 0.12008f, 0.12046f, 0.12084f,
0495         0.12122f, 0.12161f, 0.12199f, 0.12237f,
0496         0.12276f, 0.12314f, 0.12352f, 0.12391f,
0497         0.12429f, 0.12468f, 0.12506f, 0.12545f,
0498         0.12583f, 0.12622f, 0.12661f, 0.12700f,
0499         0.12738f, 0.12777f, 0.12816f, 0.12855f,
0500         0.12894f, 0.12933f, 0.12972f, 0.13011f,
0501         0.13050f, 0.13089f, 0.13129f, 0.13168f,
0502         0.13207f, 0.13247f, 0.13286f, 0.13325f,
0503         0.13365f, 0.13404f, 0.13444f, 0.13483f,
0504         0.13523f, 0.13563f, 0.13603f, 0.13642f,
0505         0.13682f, 0.13722f, 0.13762f, 0.13802f,
0506         0.13842f, 0.13882f, 0.13922f, 0.13962f,
0507         0.14003f, 0.14043f, 0.14083f, 0.14124f,
0508         0.14164f, 0.14204f, 0.14245f, 0.14285f,
0509         0.14326f, 0.14366f, 0.14407f, 0.14448f,
0510         0.14489f, 0.14530f, 0.14570f, 0.14611f,
0511         0.14652f, 0.14693f, 0.14734f, 0.14776f,
0512         0.14817f, 0.14858f, 0.14900f, 0.14941f,
0513         0.14982f, 0.15024f, 0.15065f, 0.15107f,
0514         0.15148f, 0.15190f, 0.15232f, 0.15274f,
0515         0.15316f, 0.15357f, 0.15399f, 0.15441f,
0516         0.15483f, 0.15526f, 0.15568f, 0.15610f,
0517         0.15652f, 0.15695f, 0.15737f, 0.15779f,
0518         0.15822f, 0.15864f, 0.15907f, 0.15950f,
0519         0.15992f, 0.16035f, 0.16078f, 0.16121f,
0520         0.16164f, 0.16207f, 0.16250f, 0.16293f,
0521         0.16337f, 0.16380f, 0.16423f, 0.16467f,
0522         0.16511f, 0.16554f, 0.16598f, 0.16641f,
0523         0.16685f, 0.16729f, 0.16773f, 0.16816f,
0524         0.16860f, 0.16904f, 0.16949f, 0.16993f,
0525         0.17037f, 0.17081f, 0.17126f, 0.17170f,
0526         0.17215f, 0.17259f, 0.17304f, 0.17349f,
0527         0.17393f, 0.17438f, 0.17483f, 0.17528f,
0528         0.17573f, 0.17619f, 0.17664f, 0.17709f,
0529         0.17754f, 0.17799f, 0.17845f, 0.17890f,
0530         0.17936f, 0.17982f, 0.18028f, 0.18073f,
0531         0.18119f, 0.18165f, 0.18211f, 0.18257f,
0532         0.18303f, 0.18350f, 0.18396f, 0.18442f,
0533         0.18489f, 0.18535f, 0.18582f, 0.18629f,
0534         0.18676f, 0.18723f, 0.18770f, 0.18817f,
0535         0.18864f, 0.18911f, 0.18958f, 0.19005f,
0536         0.19053f, 0.19100f, 0.19147f, 0.19195f,
0537         0.19243f, 0.19291f, 0.19339f, 0.19387f,
0538         0.19435f, 0.19483f, 0.19531f, 0.19579f,
0539         0.19627f, 0.19676f, 0.19724f, 0.19773f,
0540         0.19821f, 0.19870f, 0.19919f, 0.19968f,
0541         0.20017f, 0.20066f, 0.20115f, 0.20164f,
0542         0.20214f, 0.20263f, 0.20313f, 0.20362f,
0543         0.20412f, 0.20462f, 0.20512f, 0.20561f,
0544         0.20611f, 0.20662f, 0.20712f, 0.20762f,
0545         0.20812f, 0.20863f, 0.20913f, 0.20964f,
0546         0.21015f, 0.21066f, 0.21117f, 0.21168f,
0547         0.21219f, 0.21270f, 0.21321f, 0.21373f,
0548         0.21424f, 0.21476f, 0.21527f, 0.21579f,
0549         0.21631f, 0.21683f, 0.21735f, 0.21787f,
0550         0.21839f, 0.21892f, 0.21944f, 0.21997f,
0551         0.22049f, 0.22102f, 0.22155f, 0.22208f,
0552         0.22261f, 0.22314f, 0.22367f, 0.22420f,
0553         0.22474f, 0.22527f, 0.22581f, 0.22634f,
0554         0.22688f, 0.22742f, 0.22796f, 0.22850f,
0555         0.22905f, 0.22959f, 0.23013f, 0.23068f,
0556         0.23123f, 0.23178f, 0.23232f, 0.23287f,
0557         0.23343f, 0.23398f, 0.23453f, 0.23508f,
0558         0.23564f, 0.23620f, 0.23675f, 0.23731f,
0559         0.23787f, 0.23843f, 0.23899f, 0.23956f,
0560         0.24012f, 0.24069f, 0.24125f, 0.24182f,
0561         0.24239f, 0.24296f, 0.24353f, 0.24410f,
0562         0.24468f, 0.24525f, 0.24582f, 0.24640f,
0563         0.24698f, 0.24756f, 0.24814f, 0.24872f,
0564         0.24931f, 0.24989f, 0.25048f, 0.25106f,
0565         0.25165f, 0.25224f, 0.25283f, 0.25342f,
0566         0.25401f, 0.25460f, 0.25520f, 0.25579f,
0567         0.25639f, 0.25699f, 0.25759f, 0.25820f,
0568         0.25880f, 0.25940f, 0.26001f, 0.26062f,
0569         0.26122f, 0.26183f, 0.26244f, 0.26306f,
0570         0.26367f, 0.26429f, 0.26490f, 0.26552f,
0571         0.26614f, 0.26676f, 0.26738f, 0.26800f,
0572         0.26863f, 0.26925f, 0.26988f, 0.27051f,
0573         0.27114f, 0.27177f, 0.27240f, 0.27303f,
0574         0.27367f, 0.27431f, 0.27495f, 0.27558f,
0575         0.27623f, 0.27687f, 0.27751f, 0.27816f,
0576         0.27881f, 0.27945f, 0.28011f, 0.28076f,
0577         0.28141f, 0.28207f, 0.28272f, 0.28338f,
0578         0.28404f, 0.28470f, 0.28536f, 0.28602f,
0579         0.28669f, 0.28736f, 0.28802f, 0.28869f,
0580         0.28937f, 0.29004f, 0.29071f, 0.29139f,
0581         0.29207f, 0.29274f, 0.29342f, 0.29410f,
0582         0.29479f, 0.29548f, 0.29616f, 0.29685f,
0583         0.29754f, 0.29823f, 0.29893f, 0.29962f,
0584         0.30032f, 0.30102f, 0.30172f, 0.30242f,
0585         0.30312f, 0.30383f, 0.30453f, 0.30524f,
0586         0.30595f, 0.30667f, 0.30738f, 0.30809f,
0587         0.30881f, 0.30953f, 0.31025f, 0.31097f,
0588         0.31170f, 0.31242f, 0.31315f, 0.31388f,
0589         0.31461f, 0.31534f, 0.31608f, 0.31682f,
0590         0.31755f, 0.31829f, 0.31904f, 0.31978f,
0591         0.32053f, 0.32127f, 0.32202f, 0.32277f,
0592         0.32353f, 0.32428f, 0.32504f, 0.32580f,
0593         0.32656f, 0.32732f, 0.32808f, 0.32885f,
0594         0.32962f, 0.33039f, 0.33116f, 0.33193f,
0595         0.33271f, 0.33349f, 0.33427f, 0.33505f,
0596         0.33583f, 0.33662f, 0.33741f, 0.33820f,
0597         0.33899f, 0.33978f, 0.34058f, 0.34138f,
0598         0.34218f, 0.34298f, 0.34378f, 0.34459f,
0599         0.34540f, 0.34621f, 0.34702f, 0.34783f,
0600         0.34865f, 0.34947f, 0.35029f, 0.35111f,
0601         0.35194f, 0.35277f, 0.35360f, 0.35443f,
0602         0.35526f, 0.35610f, 0.35694f, 0.35778f,
0603         0.35862f, 0.35946f, 0.36032f, 0.36117f,
0604         0.36202f, 0.36287f, 0.36372f, 0.36458f,
0605         0.36545f, 0.36631f, 0.36718f, 0.36805f,
0606         0.36891f, 0.36979f, 0.37066f, 0.37154f,
0607         0.37242f, 0.37331f, 0.37419f, 0.37507f,
0608         0.37596f, 0.37686f, 0.37775f, 0.37865f,
0609         0.37955f, 0.38045f, 0.38136f, 0.38227f,
0610         0.38317f, 0.38409f, 0.38500f, 0.38592f,
0611         0.38684f, 0.38776f, 0.38869f, 0.38961f,
0612         0.39055f, 0.39148f, 0.39242f, 0.39335f,
0613         0.39430f, 0.39524f, 0.39619f, 0.39714f,
0614         0.39809f, 0.39904f, 0.40000f, 0.40097f,
0615         0.40193f, 0.40289f, 0.40386f, 0.40483f,
0616         0.40581f, 0.40679f, 0.40777f, 0.40875f,
0617         0.40974f, 0.41073f, 0.41172f, 0.41272f,
0618         0.41372f, 0.41472f, 0.41572f, 0.41673f,
0619         0.41774f, 0.41875f, 0.41977f, 0.42079f,
0620         0.42181f, 0.42284f, 0.42386f, 0.42490f,
0621         0.42594f, 0.42697f, 0.42801f, 0.42906f,
0622         0.43011f, 0.43116f, 0.43222f, 0.43327f,
0623         0.43434f, 0.43540f, 0.43647f, 0.43754f,
0624         0.43862f, 0.43970f, 0.44077f, 0.44186f,
0625         0.44295f, 0.44404f, 0.44514f, 0.44624f,
0626         0.44734f, 0.44845f, 0.44956f, 0.45068f,
0627         0.45179f, 0.45291f, 0.45404f, 0.45516f,
0628         0.45630f, 0.45744f, 0.45858f, 0.45972f,
0629         0.46086f, 0.46202f, 0.46318f, 0.46433f,
0630         0.46550f, 0.46667f, 0.46784f, 0.46901f,
0631         0.47019f, 0.47137f, 0.47256f, 0.47375f,
0632         0.47495f, 0.47615f, 0.47735f, 0.47856f,
0633         0.47977f, 0.48099f, 0.48222f, 0.48344f,
0634         0.48467f, 0.48590f, 0.48714f, 0.48838f,
0635         0.48963f, 0.49088f, 0.49213f, 0.49340f,
0636         0.49466f, 0.49593f, 0.49721f, 0.49849f,
0637         0.49977f, 0.50106f, 0.50236f, 0.50366f,
0638         0.50496f, 0.50627f, 0.50758f, 0.50890f,
0639         0.51023f, 0.51155f, 0.51289f, 0.51422f,
0640         0.51556f, 0.51692f, 0.51827f, 0.51964f,
0641         0.52100f, 0.52237f, 0.52374f, 0.52512f,
0642         0.52651f, 0.52790f, 0.52930f, 0.53070f,
0643         0.53212f, 0.53353f, 0.53495f, 0.53638f,
0644         0.53781f, 0.53925f, 0.54070f, 0.54214f,
0645         0.54360f, 0.54506f, 0.54653f, 0.54800f,
0646         0.54949f, 0.55098f, 0.55247f, 0.55396f,
0647         0.55548f, 0.55699f, 0.55851f, 0.56003f,
0648         0.56156f, 0.56310f, 0.56464f, 0.56621f,
0649         0.56777f, 0.56933f, 0.57091f, 0.57248f,
0650         0.57407f, 0.57568f, 0.57727f, 0.57888f,
0651         0.58050f, 0.58213f, 0.58376f, 0.58541f,
0652         0.58705f, 0.58871f, 0.59037f, 0.59204f,
0653         0.59373f, 0.59541f, 0.59712f, 0.59882f,
0654         0.60052f, 0.60226f, 0.60399f, 0.60572f,
0655         0.60748f, 0.60922f, 0.61099f, 0.61276f,
0656         0.61455f, 0.61635f, 0.61814f, 0.61996f,
0657         0.62178f, 0.62361f, 0.62545f, 0.62730f,
0658         0.62917f, 0.63104f, 0.63291f, 0.63480f,
0659         0.63671f, 0.63862f, 0.64054f, 0.64249f,
0660         0.64443f, 0.64638f, 0.64835f, 0.65033f,
0661         0.65232f, 0.65433f, 0.65633f, 0.65836f,
0662         0.66041f, 0.66245f, 0.66452f, 0.66660f,
0663         0.66868f, 0.67078f, 0.67290f, 0.67503f,
0664         0.67717f, 0.67932f, 0.68151f, 0.68368f,
0665         0.68587f, 0.68809f, 0.69033f, 0.69257f,
0666         0.69482f, 0.69709f, 0.69939f, 0.70169f,
0667         0.70402f, 0.70634f, 0.70869f, 0.71107f,
0668         0.71346f, 0.71587f, 0.71829f, 0.72073f,
0669         0.72320f, 0.72567f, 0.72818f, 0.73069f,
0670         0.73323f, 0.73579f, 0.73838f, 0.74098f,
0671         0.74360f, 0.74622f, 0.74890f, 0.75159f,
0672         0.75429f, 0.75704f, 0.75979f, 0.76257f,
0673         0.76537f, 0.76821f, 0.77109f, 0.77396f,
0674         0.77688f, 0.77982f, 0.78278f, 0.78579f,
0675         0.78883f, 0.79187f, 0.79498f, 0.79809f,
0676         0.80127f, 0.80445f, 0.80767f, 0.81095f,
0677         0.81424f, 0.81757f, 0.82094f, 0.82438f,
0678         0.82782f, 0.83133f, 0.83488f, 0.83847f,
0679         0.84210f, 0.84577f, 0.84951f, 0.85328f,
0680         0.85713f, 0.86103f, 0.86499f, 0.86900f,
0681         0.87306f, 0.87720f, 0.88139f, 0.88566f,
0682         0.89000f, 0.89442f, 0.89891f, 0.90350f,
0683         0.90818f, 0.91295f, 0.91780f, 0.92272f,
0684         0.92780f, 0.93299f, 0.93828f, 0.94369f,
0685         0.94926f, 0.95493f, 0.96082f, 0.96684f,
0686         0.97305f, 0.97943f, 0.98605f, 0.99291f,
0687         1.00000f
0688         };
0689 
0690     const uint32 kTableSize = sizeof (kTable    ) /
0691                               sizeof (kTable [0]);
0692 
0693     real32 y = (real32) x * (real32) (kTableSize - 1);
0694 
0695     int32 index = Pin_int32 (0, (int32) y, kTableSize - 2);
0696 
0697     real32 fract = y - (real32) index;
0698 
0699     return kTable [index    ] * (1.0f - fract) +
0700            kTable [index + 1] * (       fract);
0701 
0702     }
0703 
0704 /*****************************************************************************/
0705 
0706 const dng_1d_function & dng_tone_curve_acr3_default::Get ()
0707     {
0708 
0709     static dng_tone_curve_acr3_default static_dng_tone_curve_acr3_default;
0710 
0711     return static_dng_tone_curve_acr3_default;
0712 
0713     }
0714 
0715 /*****************************************************************************/
0716 
0717 class dng_render_task: public dng_filter_task
0718     {
0719 
0720     protected:
0721 
0722         const dng_image *fSrcMask;
0723 
0724         const dng_negative &fNegative;
0725 
0726         const dng_render &fParams;
0727 
0728         dng_point fSrcOffset;
0729 
0730         dng_1d_table fZeroOffsetRamp;
0731 
0732         dng_vector fCameraWhite;
0733         dng_matrix fCameraToRGB;
0734 
0735         AutoPtr<dng_hue_sat_map> fHueSatMap;
0736 
0737         dng_1d_table fExposureRamp;
0738 
0739         AutoPtr<dng_hue_sat_map> fLookTable;
0740 
0741         dng_1d_table fToneCurve;
0742 
0743         dng_matrix fRGBtoFinal;
0744 
0745         dng_1d_table fEncodeGamma;
0746 
0747         AutoPtr<dng_1d_table> fHueSatMapEncode;
0748         AutoPtr<dng_1d_table> fHueSatMapDecode;
0749 
0750         AutoPtr<dng_1d_table> fLookTableEncode;
0751         AutoPtr<dng_1d_table> fLookTableDecode;
0752 
0753         AutoPtr<dng_memory_block> fTempBuffer [kMaxMPThreads];
0754 
0755         AutoPtr<dng_memory_block> fMaskBuffer [kMaxMPThreads];
0756 
0757     public:
0758 
0759         dng_render_task (const dng_image &srcImage,
0760                          const dng_image *srcMask,
0761                          dng_image &dstImage,
0762                          const dng_negative &negative,
0763                          const dng_render &params,
0764                          const dng_point &srcOffset);
0765 
0766         virtual dng_rect SrcArea (const dng_rect &dstArea);
0767 
0768         virtual void Start (uint32 threadCount,
0769                             const dng_rect &dstArea,
0770                             const dng_point &tileSize,
0771                             dng_memory_allocator *allocator,
0772                             dng_abort_sniffer *sniffer);
0773 
0774         virtual void ProcessArea (uint32 threadIndex,
0775                                   dng_pixel_buffer &srcBuffer,
0776                                   dng_pixel_buffer &dstBuffer);
0777 
0778     };
0779 
0780 /*****************************************************************************/
0781 
0782 dng_render_task::dng_render_task (const dng_image &srcImage,
0783                                   const dng_image *srcMask,
0784                                   dng_image &dstImage,
0785                                   const dng_negative &negative,
0786                                   const dng_render &params,
0787                                   const dng_point &srcOffset)
0788 
0789     :   dng_filter_task ("dng_render_task",
0790                          srcImage,
0791                          dstImage)
0792 
0793     ,   fSrcMask   (srcMask  )
0794     ,   fNegative  (negative )
0795     ,   fParams    (params   )
0796     ,   fSrcOffset (srcOffset)
0797 
0798     ,   fZeroOffsetRamp ()
0799 
0800     ,   fCameraWhite ()
0801     ,   fCameraToRGB ()
0802 
0803     ,   fHueSatMap ()
0804 
0805     ,   fExposureRamp ()
0806 
0807     ,   fLookTable ()
0808 
0809     ,   fToneCurve ()
0810 
0811     ,   fRGBtoFinal ()
0812 
0813     ,   fEncodeGamma ()
0814 
0815     ,   fHueSatMapEncode ()
0816     ,   fHueSatMapDecode ()
0817 
0818     ,   fLookTableEncode ()
0819     ,   fLookTableDecode ()
0820 
0821     {
0822 
0823     fSrcPixelType = ttFloat;
0824     fDstPixelType = ttFloat;
0825 
0826     }
0827 
0828 /*****************************************************************************/
0829 
0830 dng_rect dng_render_task::SrcArea (const dng_rect &dstArea)
0831     {
0832 
0833     return dstArea + fSrcOffset;
0834 
0835     }
0836 
0837 /*****************************************************************************/
0838 
0839 void dng_render_task::Start (uint32 threadCount,
0840                              const dng_rect &dstArea,
0841                              const dng_point &tileSize,
0842                              dng_memory_allocator *allocator,
0843                              dng_abort_sniffer *sniffer)
0844     {
0845 
0846     dng_filter_task::Start (threadCount,
0847                             dstArea,
0848                             tileSize,
0849                             allocator,
0850                             sniffer);
0851 
0852     // Compute zero offset ramp, if any.
0853 
0854     if (fNegative.Stage3BlackLevel ())
0855         {
0856 
0857         dng_function_zero_offset offsetFunction (fNegative.Stage3BlackLevelNormalized ());
0858 
0859         fZeroOffsetRamp.Initialize (*allocator, offsetFunction);
0860 
0861         }
0862 
0863     // Compute camera space to linear ProPhoto RGB parameters.
0864 
0865     dng_camera_profile_id profileID;    // Default profile ID.
0866 
0867     if (!fNegative.IsMonochrome ())
0868         {
0869 
0870         AutoPtr<dng_color_spec> spec (fNegative.MakeColorSpec (profileID));
0871 
0872         if (fParams.WhiteXY ().IsValid ())
0873             {
0874 
0875             spec->SetWhiteXY (fParams.WhiteXY ());
0876 
0877             }
0878 
0879         else if (fNegative.HasCameraNeutral ())
0880             {
0881 
0882             spec->SetWhiteXY (spec->NeutralToXY (fNegative.CameraNeutral ()));
0883 
0884             }
0885 
0886         else if (fNegative.HasCameraWhiteXY ())
0887             {
0888 
0889             spec->SetWhiteXY (fNegative.CameraWhiteXY ());
0890 
0891             }
0892 
0893         else
0894             {
0895 
0896             spec->SetWhiteXY (D55_xy_coord ());
0897 
0898             }
0899 
0900         fCameraWhite = spec->CameraWhite ();
0901 
0902         fCameraToRGB = dng_space_ProPhoto::Get ().MatrixFromPCS () *
0903                        spec->CameraToPCS ();
0904 
0905         // Find Hue/Sat table, if any.
0906 
0907         const dng_camera_profile *profile = fNegative.ProfileByID (profileID);
0908 
0909         if (profile)
0910             {
0911 
0912             fHueSatMap.Reset (profile->HueSatMapForWhite (spec->WhiteXY ()));
0913 
0914             if (profile->HasLookTable ())
0915                 {
0916 
0917                 fLookTable.Reset (new dng_hue_sat_map (profile->LookTable ()));
0918 
0919                 }
0920 
0921             if (profile->HueSatMapEncoding () != encoding_Linear)
0922                 {
0923 
0924                 BuildHueSatMapEncodingTable (*allocator,
0925                                              profile->HueSatMapEncoding (),
0926                                              fHueSatMapEncode,
0927                                              fHueSatMapDecode,
0928                                              false);
0929 
0930                 }
0931 
0932             if (profile->LookTableEncoding () != encoding_Linear)
0933                 {
0934 
0935                 BuildHueSatMapEncodingTable (*allocator,
0936                                              profile->LookTableEncoding (),
0937                                              fLookTableEncode,
0938                                              fLookTableDecode,
0939                                              false);
0940 
0941                 }
0942 
0943             }
0944 
0945         }
0946 
0947     // Compute exposure/shadows ramp.
0948 
0949     real64 exposure = fParams.Exposure () +
0950                       fNegative.TotalBaselineExposure (profileID) -
0951                       (log (fNegative.Stage3Gain ()) / log (2.0));
0952 
0953         {
0954 
0955         real64 white = 1.0 / pow (2.0, Max_real64 (0.0, exposure));
0956 
0957         real64 black = fParams.Shadows () *
0958                        fNegative.ShadowScale () *
0959                        fNegative.Stage3Gain () *
0960                        0.001;
0961 
0962         black = Min_real64 (black, 0.99 * white);
0963 
0964         dng_function_exposure_ramp rampFunction (white,
0965                                                  black,
0966                                                  black);
0967 
0968         fExposureRamp.Initialize (*allocator, rampFunction);
0969 
0970         }
0971 
0972     // Compute tone curve.
0973 
0974         {
0975 
0976         // If there is any negative exposure compenation to perform
0977         // (beyond what the camera provides for with its baseline exposure),
0978         // we fake this by darkening the tone curve.
0979 
0980         dng_function_exposure_tone exposureTone (exposure);
0981 
0982         dng_1d_concatenate totalTone (exposureTone,
0983                                       fParams.ToneCurve ());
0984 
0985         fToneCurve.Initialize (*allocator, totalTone);
0986 
0987         }
0988 
0989     // Compute linear ProPhoto RGB to final space parameters.
0990 
0991         {
0992 
0993         const dng_color_space &finalSpace = fParams.FinalSpace ();
0994 
0995         fRGBtoFinal = finalSpace.MatrixFromPCS () *
0996                       dng_space_ProPhoto::Get ().MatrixToPCS ();
0997 
0998         fEncodeGamma.Initialize (*allocator, finalSpace.GammaFunction ());
0999 
1000         }
1001 
1002     // Allocate temp buffer to hold one row of RGB data.
1003 
1004     uint32 tempBufferSize = 0;
1005 
1006     if (!SafeUint32Mult (tileSize.h, (uint32) sizeof (real32), &tempBufferSize) ||
1007         !SafeUint32Mult (tempBufferSize, 3, &tempBufferSize))
1008         {
1009 
1010         ThrowOverflow ("Arithmetic overflow computing buffer size.");
1011 
1012         }
1013 
1014     for (uint32 threadIndex = 0; threadIndex < threadCount; threadIndex++)
1015         {
1016 
1017         fTempBuffer [threadIndex] . Reset (allocator->Allocate (tempBufferSize));
1018 
1019         }
1020 
1021     // Allocate mask buffer to hold one tile of mask data, if needed.
1022 
1023     if (fSrcMask)
1024         {
1025 
1026         uint32 maskBufferSize = 0;
1027 
1028         if (!SafeUint32Mult (tileSize.h, tileSize.v, &maskBufferSize) ||
1029             !SafeUint32Mult (maskBufferSize, (uint32) sizeof (real32), &maskBufferSize))
1030             {
1031 
1032             ThrowOverflow ("Arithmetic overflow computing buffer size.");
1033 
1034             }
1035 
1036         for (uint32 threadIndex = 0; threadIndex < threadCount; threadIndex++)
1037             {
1038 
1039             fMaskBuffer [threadIndex] . Reset (allocator->Allocate (maskBufferSize));
1040 
1041             }
1042 
1043         }
1044 
1045     }
1046 
1047 /*****************************************************************************/
1048 
1049 void dng_render_task::ProcessArea (uint32 threadIndex,
1050                                    dng_pixel_buffer &srcBuffer,
1051                                    dng_pixel_buffer &dstBuffer)
1052     {
1053 
1054     dng_rect srcArea = srcBuffer.fArea;
1055     dng_rect dstArea = dstBuffer.fArea;
1056 
1057     uint32 srcCols = srcArea.W ();
1058 
1059     real32 *tPtrR = fTempBuffer [threadIndex]->Buffer_real32 ();
1060 
1061     real32 *tPtrG = tPtrR + srcCols;
1062     real32 *tPtrB = tPtrG + srcCols;
1063 
1064     dng_pixel_buffer maskBuffer;
1065 
1066     if (fSrcMask)
1067         {
1068 
1069         maskBuffer.fArea      = srcArea;
1070         maskBuffer.fPlane     = 0;
1071         maskBuffer.fPlanes    = 1;
1072         maskBuffer.fRowStep   = srcArea.W ();
1073         maskBuffer.fColStep   = 1;
1074         maskBuffer.fPlaneStep = 0;
1075         maskBuffer.fPixelType = ttFloat;
1076         maskBuffer.fPixelSize = sizeof (real32);
1077         maskBuffer.fData      = fMaskBuffer [threadIndex]->Buffer_real32 ();
1078         maskBuffer.fDirty     = true;
1079 
1080         fSrcMask->Get (maskBuffer);
1081 
1082         }
1083 
1084     for (int32 srcRow = srcArea.t; srcRow < srcArea.b; srcRow++)
1085         {
1086 
1087         if (fNegative.Stage3BlackLevel ())
1088             {
1089 
1090             for (uint32 plane = 0; plane < fSrcPlanes; plane++)
1091                 {
1092 
1093                 real32 *sPtr = (real32 *)
1094                                srcBuffer.DirtyPixel (srcRow,
1095                                                      srcArea.l,
1096                                                      plane);
1097 
1098                 DoBaseline1DTable (sPtr,
1099                                    sPtr,
1100                                    srcCols,
1101                                    fZeroOffsetRamp);
1102 
1103                 }
1104 
1105             }
1106 
1107         // First convert from camera native space to linear PhotoRGB,
1108         // applying the white balance and camera profile.
1109 
1110             {
1111 
1112             const real32 *sPtrA = (const real32 *)
1113                                   srcBuffer.ConstPixel (srcRow,
1114                                                         srcArea.l,
1115                                                         0);
1116 
1117             if (fSrcPlanes == 1)
1118                 {
1119 
1120                 // For monochrome cameras, this just requires copying
1121                 // the data into all three color channels.
1122 
1123                 DoCopyBytes (sPtrA, tPtrR, srcCols * (uint32) sizeof (real32));
1124                 DoCopyBytes (sPtrA, tPtrG, srcCols * (uint32) sizeof (real32));
1125                 DoCopyBytes (sPtrA, tPtrB, srcCols * (uint32) sizeof (real32));
1126 
1127                 }
1128 
1129             else
1130                 {
1131 
1132                 const real32 *sPtrB = sPtrA + srcBuffer.fPlaneStep;
1133                 const real32 *sPtrC = sPtrB + srcBuffer.fPlaneStep;
1134 
1135                 if (fSrcPlanes == 3)
1136                     {
1137 
1138                     DoBaselineABCtoRGB (sPtrA,
1139                                         sPtrB,
1140                                         sPtrC,
1141                                         tPtrR,
1142                                         tPtrG,
1143                                         tPtrB,
1144                                         srcCols,
1145                                         fCameraWhite,
1146                                         fCameraToRGB);
1147 
1148                     }
1149 
1150                 else
1151                     {
1152 
1153                     const real32 *sPtrD = sPtrC + srcBuffer.fPlaneStep;
1154 
1155                     DoBaselineABCDtoRGB (sPtrA,
1156                                          sPtrB,
1157                                          sPtrC,
1158                                          sPtrD,
1159                                          tPtrR,
1160                                          tPtrG,
1161                                          tPtrB,
1162                                          srcCols,
1163                                          fCameraWhite,
1164                                          fCameraToRGB);
1165 
1166                     }
1167 
1168                 // Apply Hue/Sat map, if any.
1169 
1170                 if (fHueSatMap.Get ())
1171                     {
1172 
1173                     DoBaselineHueSatMap (tPtrR,
1174                                          tPtrG,
1175                                          tPtrB,
1176                                          tPtrR,
1177                                          tPtrG,
1178                                          tPtrB,
1179                                          srcCols,
1180                                          *fHueSatMap.Get (),
1181                                          fHueSatMapEncode.Get (),
1182                                          fHueSatMapDecode.Get ());
1183 
1184                     }
1185 
1186                 }
1187 
1188             }
1189 
1190         // Apply exposure curve.
1191 
1192         DoBaseline1DTable (tPtrR,
1193                            tPtrR,
1194                            srcCols,
1195                            fExposureRamp);
1196 
1197         DoBaseline1DTable (tPtrG,
1198                            tPtrG,
1199                            srcCols,
1200                            fExposureRamp);
1201 
1202         DoBaseline1DTable (tPtrB,
1203                            tPtrB,
1204                            srcCols,
1205                            fExposureRamp);
1206 
1207         // Apply look table, if any.
1208 
1209         if (fLookTable.Get ())
1210             {
1211 
1212             DoBaselineHueSatMap (tPtrR,
1213                                  tPtrG,
1214                                  tPtrB,
1215                                  tPtrR,
1216                                  tPtrG,
1217                                  tPtrB,
1218                                  srcCols,
1219                                  *fLookTable.Get (),
1220                                  fLookTableEncode.Get (),
1221                                  fLookTableDecode.Get ());
1222 
1223             }
1224 
1225         // Apply baseline tone curve.
1226 
1227         DoBaselineRGBTone (tPtrR,
1228                            tPtrG,
1229                            tPtrB,
1230                            tPtrR,
1231                            tPtrG,
1232                            tPtrB,
1233                            srcCols,
1234                            fToneCurve);
1235 
1236         // Convert to final color space.
1237 
1238         int32 dstRow = srcRow + (dstArea.t - srcArea.t);
1239 
1240         if (fDstPlanes == 1)
1241             {
1242 
1243             real32 *dPtrG = dstBuffer.DirtyPixel_real32 (dstRow,
1244                                                          dstArea.l,
1245                                                          0);
1246 
1247             DoBaselineRGBtoGray (tPtrR,
1248                                  tPtrG,
1249                                  tPtrB,
1250                                  dPtrG,
1251                                  srcCols,
1252                                  fRGBtoFinal);
1253 
1254             DoBaseline1DTable (dPtrG,
1255                                dPtrG,
1256                                srcCols,
1257                                fEncodeGamma);
1258 
1259             }
1260 
1261         else
1262             {
1263 
1264             real32 *dPtrR = dstBuffer.DirtyPixel_real32 (dstRow,
1265                                                          dstArea.l,
1266                                                          0);
1267 
1268             real32 *dPtrG = dPtrR + dstBuffer.fPlaneStep;
1269             real32 *dPtrB = dPtrG + dstBuffer.fPlaneStep;
1270 
1271             DoBaselineRGBtoRGB (tPtrR,
1272                                 tPtrG,
1273                                 tPtrB,
1274                                 dPtrR,
1275                                 dPtrG,
1276                                 dPtrB,
1277                                 srcCols,
1278                                 fRGBtoFinal);
1279 
1280             DoBaseline1DTable (dPtrR,
1281                                dPtrR,
1282                                srcCols,
1283                                fEncodeGamma);
1284 
1285             DoBaseline1DTable (dPtrG,
1286                                dPtrG,
1287                                srcCols,
1288                                fEncodeGamma);
1289 
1290             DoBaseline1DTable (dPtrB,
1291                                dPtrB,
1292                                srcCols,
1293                                fEncodeGamma);
1294 
1295             }
1296 
1297         if (fSrcMask)
1298             {
1299 
1300             const real32 *mPtr = maskBuffer.ConstPixel_real32 (srcRow,
1301                                                                srcArea.l,
1302                                                                0);
1303 
1304             for (uint32 dstPlane = 0; dstPlane < fDstPlanes; dstPlane++)
1305                 {
1306 
1307                 real32 *dPtr = dstBuffer.DirtyPixel_real32 (dstRow,
1308                                                             dstArea.l,
1309                                                             dstPlane);
1310 
1311                 for (uint32 col = 0; col < srcCols; col++)
1312                     {
1313 
1314                     // White Matte
1315 
1316                     dPtr [col] = 1.0f - (1.0f - dPtr [col]) * mPtr [col];
1317 
1318                     }
1319 
1320                 }
1321 
1322             }
1323 
1324         }
1325 
1326     }
1327 
1328 /*****************************************************************************/
1329 
1330 dng_render::dng_render (dng_host &host,
1331                         const dng_negative &negative)
1332 
1333     :   fHost           (host)
1334     ,   fNegative       (negative)
1335 
1336     ,   fWhiteXY        ()
1337 
1338     ,   fExposure       (0.0)
1339     ,   fShadows        (5.0)
1340 
1341     ,   fToneCurve      (&dng_tone_curve_acr3_default::Get ())
1342 
1343     ,   fFinalSpace     (&dng_space_sRGB::Get ())
1344     ,   fFinalPixelType (ttByte)
1345 
1346     ,   fMaximumSize    (0)
1347 
1348     ,   fProfileToneCurve ()
1349 
1350     {
1351 
1352     // Switch to NOP default parameters for non-scene referred data.
1353 
1354     if (fNegative.ColorimetricReference () != crSceneReferred)
1355         {
1356 
1357         fShadows = 0.0;
1358 
1359         fToneCurve = &dng_1d_identity::Get ();
1360 
1361         }
1362 
1363     // Use default tone curve from profile if any.
1364 
1365     const dng_camera_profile *profile = fNegative.ProfileByID (dng_camera_profile_id ());
1366 
1367     if (profile && profile->ToneCurve ().IsValid ())
1368         {
1369 
1370         fProfileToneCurve.Reset (new dng_spline_solver);
1371 
1372         profile->ToneCurve ().Solve (*fProfileToneCurve.Get ());
1373 
1374         fToneCurve = fProfileToneCurve.Get ();
1375 
1376         }
1377 
1378     // Turn off default shadow mapping if requested by profile.
1379 
1380     if (profile && (profile->DefaultBlackRender () == defaultBlackRender_None))
1381         {
1382 
1383         fShadows = 0.0;
1384 
1385         }
1386 
1387     }
1388 
1389 /*****************************************************************************/
1390 
1391 dng_image * dng_render::Render ()
1392     {
1393 
1394     const dng_image *srcImage = fNegative.Stage3Image ();
1395 
1396     const dng_image *srcMask = fNegative.TransparencyMask ();
1397 
1398     dng_rect srcBounds = fNegative.DefaultCropArea ();
1399 
1400     dng_point dstSize;
1401 
1402     dstSize.h = fNegative.DefaultFinalWidth  ();
1403     dstSize.v = fNegative.DefaultFinalHeight ();
1404 
1405     if (MaximumSize ())
1406         {
1407 
1408         if (Max_uint32 (dstSize.h, dstSize.v) > MaximumSize ())
1409             {
1410 
1411             real64 ratio = fNegative.AspectRatio ();
1412 
1413             if (ratio >= 1.0)
1414                 {
1415                 dstSize.h = MaximumSize ();
1416                 dstSize.v = Max_uint32 (1, Round_uint32 (dstSize.h / ratio));
1417                 }
1418 
1419             else
1420                 {
1421                 dstSize.v = MaximumSize ();
1422                 dstSize.h = Max_uint32 (1, Round_uint32 (dstSize.v * ratio));
1423                 }
1424 
1425             }
1426 
1427         }
1428 
1429     AutoPtr<dng_image> tempImage;
1430 
1431     AutoPtr<dng_image> tempMask;
1432 
1433     if (srcBounds.Size () != dstSize)
1434         {
1435 
1436         tempImage.Reset (fHost.Make_dng_image (dstSize,
1437                                                srcImage->Planes    (),
1438                                                srcImage->PixelType ()));
1439 
1440         ResampleImage (fHost,
1441                        *srcImage,
1442                        *tempImage.Get (),
1443                        srcBounds,
1444                        tempImage->Bounds (),
1445                        dng_resample_bicubic::Get ());
1446 
1447         if (srcMask != NULL)
1448             {
1449 
1450             tempMask.Reset (fHost.Make_dng_image (dstSize,
1451                                                   srcMask->Planes    (),
1452                                                   srcMask->PixelType ()));
1453 
1454             ResampleImage (fHost,
1455                            *srcMask,
1456                            *tempMask.Get (),
1457                            srcBounds,
1458                            tempMask->Bounds (),
1459                            dng_resample_bicubic::Get ());
1460 
1461             srcMask = tempMask.Get ();
1462 
1463             }
1464 
1465         srcImage = tempImage.Get ();
1466 
1467         srcBounds = tempImage->Bounds ();
1468 
1469         }
1470 
1471     uint32 dstPlanes = FinalSpace ().IsMonochrome () ? 1 : 3;
1472 
1473     AutoPtr<dng_image> dstImage (fHost.Make_dng_image (srcBounds.Size (),
1474                                                        dstPlanes,
1475                                                        FinalPixelType ()));
1476 
1477     dng_render_task task (*srcImage,
1478                           srcMask,
1479                           *dstImage.Get (),
1480                           fNegative,
1481                           *this,
1482                           srcBounds.TL ());
1483 
1484     fHost.PerformAreaTask (task,
1485                            dstImage->Bounds ());
1486 
1487     return dstImage.Release ();
1488 
1489     }
1490 
1491 /*****************************************************************************/