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