1 #include "dng_color_space.h"
2 #include "dng_memory.h"
3 #include "dng_bottlenecks.h"
4 #include "dng_spline.h"
5 #include "dng_render.h"
6 #include "matrix.h"
7 #include "sampler.h"
8 
Sampler(const dng_matrix & nfm)9 Sampler::Sampler(const dng_matrix &nfm)
10 {
11   fm=nfm;
12   cam2rgb_matrix=dng_space_ProPhoto::Get().MatrixFromPCS()*fm;
13   rgb2xyz_matrix=dng_space_ProPhoto::Get().MatrixToPCS();
14   tc.Initialize(gDefaultDNGMemoryAllocator, dng_tone_curve_acr3_default::Get());
15   maxrgb=1.0;
16   maxxyz=0.5;
17 }
18 
setfm(const dng_matrix & nfm)19 void Sampler::setfm(const dng_matrix &nfm)
20 {
21   if(!equal(fm,nfm)) {
22     fm=nfm;
23     cam2rgb_matrix=dng_space_ProPhoto::Get().MatrixFromPCS()*fm;
24   }
25 }
26 
getfm()27 dng_matrix Sampler::getfm()
28 {
29   return fm;
30 }
31 
sethsm(const dng_hue_sat_map & nhsm)32 void Sampler::sethsm(const dng_hue_sat_map &nhsm)
33 {
34   hsm=nhsm;
35 }
36 
setltd(const dng_hue_sat_map & nltd)37 void Sampler::setltd(const dng_hue_sat_map &nltd)
38 {
39   ltd=nltd;
40 }
41 
settc(const dng_tone_curve & ntc)42 void Sampler::settc(const dng_tone_curve &ntc)
43 {
44   dng_spline_solver ptc;
45   ntc.Solve(ptc);
46   tc.Initialize(gDefaultDNGMemoryAllocator,ptc);
47 }
48 
cam2rgb(const dng_vector & cam,int test)49 dng_vector Sampler::cam2rgb(const dng_vector &cam, int test)
50 {
51   dng_vector rgb;
52   rgb = cam2rgb_matrix * cam;
53   if(test) {
54     if(rgb[0] > maxrgb)
55       maxrgb=rgb[0];
56     if(rgb[1] > maxrgb)
57       maxrgb=rgb[1];
58     if(rgb[2] > maxrgb)
59       maxrgb=rgb[2];
60   } else {
61     rgb[0] /= maxrgb;
62     rgb[1] /= maxrgb;
63     rgb[2] /= maxrgb;
64   }
65   return rgb;
66 }
67 
cam2xyz(const dng_vector & cam,int test)68 dng_vector Sampler::cam2xyz(const dng_vector &cam, int test)
69 {
70   dng_vector rgb;
71   dng_vector xyz;
72   real32 r,g,b,r1,g1,b1;
73   rgb = cam2rgb_matrix * cam;
74   rgb[0] /= maxrgb;
75   rgb[1] /= maxrgb;
76   rgb[2] /= maxrgb;
77   if(hsm.IsValid()) {
78     r1=r=rgb[0];
79     g1=g=rgb[1];
80     b1=b=rgb[2];
81     DoBaselineHueSatMap(&r,&g,&b,&r1,&g1,&b1,1,hsm);
82     rgb[0]=r1;
83     rgb[1]=g1;
84     rgb[2]=b1;
85   }
86   if(ltd.IsValid()) {
87     r1=r=rgb[0];
88     g1=g=rgb[1];
89     b1=b=rgb[2];
90     DoBaselineHueSatMap(&r,&g,&b,&r1,&g1,&b1,1,ltd);
91     rgb[0]=r1;
92     rgb[1]=g1;
93     rgb[2]=b1;
94   }
95   if(0) {
96     /* Don't use tone curve */
97     r=rgb[0];
98     g=rgb[1];
99     b=rgb[2];
100     if(r < 0.0)
101       r=0.0;
102     if(r > 1.0)
103       r=1.0;
104     if(g < 0.0)
105       g=0.0;
106     if(g > 1.0)
107       g=1.0;
108     if(b < 0.0)
109       b=0.0;
110     if(b > 1.0)
111       b=1.0;
112     DoBaselineRGBTone(&r,&g,&b,&r1,&g1,&b1,1,tc);
113     rgb[0]=r1;
114     rgb[1]=g1;
115     rgb[2]=b1;
116   }
117   rgb[0] *= maxrgb/(1.0+32767.0/32768.0);
118   rgb[1] *= maxrgb/(1.0+32767.0/32768.0);
119   rgb[2] *= maxrgb/(1.0+32767.0/32768.0);
120   xyz=rgb2xyz_matrix * rgb;
121   if(test) {
122     if(xyz[1]>maxxyz)
123       maxxyz=xyz[1];
124   }
125   return xyz;
126 }
127 
f2w(double x)128 static WORD f2w(double x)
129 {
130   long dw;
131   dw=x*(65535.0)+0.5;
132   if(dw < 0)
133     dw=0;
134   if(dw > 0xffff)
135     dw=0xffff;
136   return dw;
137 }
138 
w2f(WORD x)139 static double w2f(WORD x)
140 {
141   return x/65535.0;
142 }
143 
dcpSampler(register WORD in[],register WORD out[],register LPVOID cargo)144 int dcpSampler(register WORD in[],
145 	       register WORD out[],
146 	       register LPVOID cargo)
147 {
148   Sampler *smp;
149   dng_vector fin(3), fout;
150   smp=(Sampler *)cargo;
151   fin[0]=w2f(in[0]);
152   fin[1]=w2f(in[1]);
153   fin[2]=w2f(in[2]);
154   fout=smp->cam2xyz(fin,0);
155   out[0]=f2w(fout[0]);
156   out[1]=f2w(fout[1]);
157   out[2]=f2w(fout[2]);
158   return TRUE;
159 }
160 
dcpTest1(register WORD in[],register WORD out[],register LPVOID cargo)161 int dcpTest1(register WORD in[],
162 	     register WORD out[],
163 	     register LPVOID cargo)
164 {
165   Sampler *smp;
166   dng_vector fin(3), fout;
167   smp=(Sampler *)cargo;
168   fin[0]=w2f(in[0]);
169   fin[1]=w2f(in[1]);
170   fin[2]=w2f(in[2]);
171   fout=smp->cam2rgb(fin,1);
172   out[0]=f2w(fout[0]);
173   out[1]=f2w(fout[1]);
174   out[2]=f2w(fout[2]);
175   return TRUE;
176 }
177 
dcpTest2(register WORD in[],register WORD out[],register LPVOID cargo)178 int dcpTest2(register WORD in[],
179 	     register WORD out[],
180 	     register LPVOID cargo)
181 {
182   Sampler *smp;
183   dng_vector fin(3), fout;
184   smp=(Sampler *)cargo;
185   fin[0]=w2f(in[0]);
186   fin[1]=w2f(in[1]);
187   fin[2]=w2f(in[2]);
188   fout=smp->cam2xyz(fin,1);
189   out[0]=f2w(fout[0]);
190   out[1]=f2w(fout[1]);
191   out[2]=f2w(fout[2]);
192   return TRUE;
193 }
194 
getmaxrgb()195 real64 Sampler::getmaxrgb()
196 {
197   return maxrgb;
198 }
getmaxxyz()199 real64 Sampler::getmaxxyz()
200 {
201   return maxxyz;
202 }
203