OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the Chromium LICENSE file. | |
4 | |
5 #include "qcms_test_util.h" | |
6 | |
7 #include <math.h> | |
8 #include <stdlib.h> | |
9 | |
10 #define MAX_FLOAT_ERROR 0.000001f | |
11 | |
12 void generate_source_uint8_t(unsigned char *src, const size_t length, const size _t pixel_size) | |
Noel Gordon
2016/04/19 01:06:00
Perhaps prefix this helper with a comment ...
//
radu.velea
2016/04/19 08:42:07
Done.
| |
13 { | |
14 size_t bytes = length * pixel_size; | |
15 size_t i; | |
16 | |
17 for (i = 0; i < bytes; ++i) { | |
18 *src++ = rand() & 255; | |
19 } | |
20 } | |
21 | |
22 // Parametric Fn using floating point <from lcms>: DefaultEvalParametricFn | |
Noel Gordon
2016/04/19 01:06:01
DefaultEvalParametricFn() is in which LCMS file?
radu.velea
2016/04/19 08:42:07
Done.
| |
23 float evaluate_parametric_curve(int type, const float params[], float r) | |
24 { | |
25 float e, val, disc; | |
26 | |
27 switch (type) { | |
28 | |
29 // X = Y ^ Gamma | |
30 case 1: | |
31 if (r < 0) { | |
32 | |
33 if (fabs(params[0] - 1.0) < MAX_FLOAT_ERROR) | |
34 val = r; | |
35 else | |
36 val = 0; | |
37 } | |
38 else | |
39 val = pow(r, params[0]); | |
40 break; | |
41 | |
42 // Type 1 Reversed: X = Y ^1/gamma | |
43 case -1: | |
44 if (r < 0) { | |
45 | |
46 if (fabs(params[0] - 1.0) < MAX_FLOAT_ERROR) | |
47 val = r; | |
48 else | |
49 val = 0; | |
50 } | |
51 else | |
52 val = pow(r, 1/params[0]); | |
53 break; | |
54 | |
55 // CIE 122-1966 | |
56 // Y = (aX + b)^Gamma | X >= -b/a | |
57 // Y = 0 | else | |
58 case 2: | |
59 disc = -params[2] / params[1]; | |
60 | |
61 if (r >= disc ) { | |
62 | |
63 e = params[1]*r + params[2]; | |
64 | |
65 if (e > 0) | |
66 val = pow(e, params[0]); | |
67 else | |
68 val = 0; | |
69 } | |
70 else | |
71 val = 0; | |
72 break; | |
73 | |
74 // Type 2 Reversed | |
75 // X = (Y ^1/g - b) / a | |
76 case -2: | |
77 if (r < 0) | |
78 val = 0; | |
79 else | |
80 val = (pow(r, 1.0/params[0]) - params[2]) / params[1]; | |
81 | |
82 if (val < 0) | |
83 val = 0; | |
84 break; | |
85 | |
86 | |
87 // IEC 61966-3 | |
88 // Y = (aX + b)^Gamma | X <= -b/a | |
89 // Y = c | else | |
90 case 3: | |
91 disc = -params[2] / params[1]; | |
92 if (disc < 0) | |
93 disc = 0; | |
94 | |
95 if (r >= disc) { | |
96 | |
97 e = params[1]*r + params[2]; | |
98 | |
99 if (e > 0) | |
100 val = pow(e, params[0]) + params[3]; | |
101 else | |
102 val = 0; | |
103 } | |
104 else | |
105 val = params[3]; | |
106 break; | |
107 | |
108 | |
109 // Type 3 reversed | |
110 // X=((Y-c)^1/g - b)/a | (Y>=c) | |
111 // X=-b/a | (Y<c) | |
112 case -3: | |
113 if (r >= params[3]) { | |
114 | |
115 e = r - params[3]; | |
116 | |
117 if (e > 0) | |
118 val = (pow(e, 1/params[0]) - params[2]) / params[1]; | |
119 else | |
120 val = 0; | |
121 } | |
122 else { | |
123 val = -params[2] / params[1]; | |
124 } | |
125 break; | |
126 | |
127 | |
128 // IEC 61966-2.1 (sRGB) | |
129 // Y = (aX + b)^Gamma | X >= d | |
130 // Y = cX | X < d | |
131 case 4: | |
132 if (r >= params[4]) { | |
133 | |
134 e = params[1]*r + params[2]; | |
135 | |
136 if (e > 0) | |
137 val = pow(e, params[0]); | |
138 else | |
139 val = 0; | |
140 } | |
141 else | |
142 val = r * params[3]; | |
143 break; | |
144 | |
145 // Type 4 reversed | |
146 // X=((Y^1/g-b)/a) | Y >= (ad+b)^g | |
147 // X=Y/c | Y< (ad+b)^g | |
148 case -4: | |
149 e = params[1] * params[4] + params[2]; | |
150 if (e < 0) | |
151 disc = 0; | |
152 else | |
153 disc = pow(e, params[0]); | |
154 | |
155 if (r >= disc) { | |
156 | |
157 val = (pow(r, 1.0/params[0]) - params[2]) / params[1]; | |
158 } | |
159 else { | |
160 val = r / params[3]; | |
161 } | |
162 break; | |
163 | |
164 | |
165 // Y = (aX + b)^Gamma + e | X >= d | |
166 // Y = cX + f | X < d | |
167 case 5: | |
168 if (r >= params[4]) { | |
169 | |
170 e = params[1]*r + params[2]; | |
171 | |
172 if (e > 0) | |
173 val = pow(e, params[0]) + params[5]; | |
174 else | |
175 val = params[5]; | |
176 } | |
177 else | |
178 val = r*params[3] + params[6]; | |
179 break; | |
180 | |
181 | |
182 // Reversed type 5 | |
183 // X=((Y-e)1/g-b)/a | Y >=(ad+b)^g+e), cd+f | |
184 // X=(Y-f)/c | else | |
185 case -5: | |
186 | |
187 disc = params[3] * params[4] + params[6]; | |
188 if (r >= disc) { | |
189 | |
190 e = r - params[5]; | |
191 if (e < 0) | |
192 val = 0; | |
193 else | |
194 val = (pow(e, 1.0/params[0]) - params[2]) / params[1]; | |
195 } | |
196 else { | |
197 val = (r - params[6]) / params[3]; | |
198 } | |
199 break; | |
200 | |
201 | |
202 // Types 6,7,8 comes from segmented curves as described in ICCSpecRevisi on_02_11_06_Float.pdf | |
203 // Type 6 is basically identical to type 5 without d | |
204 | |
205 // Y = (a * X + b) ^ Gamma + c | |
206 case 6: | |
207 e = params[1]*r + params[2]; | |
208 | |
209 if (e < 0) | |
210 val = params[3]; | |
211 else | |
212 val = pow(e, params[0]) + params[3]; | |
213 break; | |
214 | |
215 // ((Y - c) ^1/Gamma - b) / a | |
216 case -6: | |
217 e = r - params[3]; | |
218 if (e < 0) | |
219 val = 0; | |
220 else | |
221 val = (pow(e, 1.0/params[0]) - params[2]) / params[1]; | |
222 break; | |
223 | |
224 | |
225 // Y = a * log (b * X^Gamma + c) + d | |
226 case 7: | |
227 | |
228 e = params[2] * pow(r, params[0]) + params[3]; | |
229 if (e <= 0) | |
230 val = params[4]; | |
231 else | |
232 val = params[1]*log10(e) + params[4]; | |
233 break; | |
234 | |
235 // (Y - d) / a = log(b * X ^Gamma + c) | |
236 // pow(10, (Y-d) / a) = b * X ^Gamma + c | |
237 // pow((pow(10, (Y-d) / a) - c) / b, 1/g) = X | |
238 case -7: | |
239 val = pow((pow(10.0, (r-params[4]) / params[1]) - params[3]) / params[2] , 1.0 / params[0]); | |
240 break; | |
241 | |
242 | |
243 //Y = a * b^(c*X+d) + e | |
244 case 8: | |
245 val = (params[0] * pow(params[1], params[2] * r + params[3]) + params[4] ); | |
246 break; | |
247 | |
248 | |
249 // Y = (log((y-e) / a) / log(b) - d ) / c | |
250 // a=0, b=1, c=2, d=3, e=4, | |
251 case -8: | |
252 | |
253 disc = r - params[4]; | |
254 if (disc < 0) val = 0; | |
255 else | |
256 val = (log(disc / params[0]) / log(params[1]) - params[3]) / params[ 2]; | |
257 break; | |
258 | |
259 // S-Shaped: (1 - (1-x)^1/g)^1/g | |
260 case 108: | |
261 val = pow(1.0 - pow(1 - r, 1/params[0]), 1/params[0]); | |
262 break; | |
263 | |
264 // y = (1 - (1-x)^1/g)^1/g | |
265 // y^g = (1 - (1-x)^1/g) | |
266 // 1 - y^g = (1-x)^1/g | |
267 // (1 - y^g)^g = 1 - x | |
268 // 1 - (1 - y^g)^g | |
269 case -108: | |
270 val = 1 - pow(1 - pow(r, params[0]), params[0]); | |
271 break; | |
272 | |
273 default: | |
274 // Unsupported parametric curve. Should never reach here | |
275 return 0; | |
276 } | |
277 | |
278 return val; | |
279 } | |
OLD | NEW |