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