green equilibration
| 258 | |
| 259 | // green equilibration |
| 260 | void LibRaw::green_matching() |
| 261 | { |
| 262 | int i, j; |
| 263 | double m1, m2, c1, c2; |
| 264 | int o1_1, o1_2, o1_3, o1_4; |
| 265 | int o2_1, o2_2, o2_3, o2_4; |
| 266 | ushort(*img)[4]; |
| 267 | const int margin = 3; |
| 268 | int oj = 2, oi = 2; |
| 269 | float f; |
| 270 | const float thr = 0.01f; |
| 271 | if (half_size || shrink) |
| 272 | return; |
| 273 | if (FC(oj, oi) != 3) |
| 274 | oj++; |
| 275 | if (FC(oj, oi) != 3) |
| 276 | oi++; |
| 277 | if (FC(oj, oi) != 3) |
| 278 | oj--; |
| 279 | |
| 280 | img = (ushort(*)[4])calloc(height * width, sizeof *image); |
| 281 | memcpy(img, image, height * width * sizeof *image); |
| 282 | |
| 283 | for (j = oj; j < height - margin; j += 2) |
| 284 | for (i = oi; i < width - margin; i += 2) |
| 285 | { |
| 286 | o1_1 = img[(j - 1) * width + i - 1][1]; |
| 287 | o1_2 = img[(j - 1) * width + i + 1][1]; |
| 288 | o1_3 = img[(j + 1) * width + i - 1][1]; |
| 289 | o1_4 = img[(j + 1) * width + i + 1][1]; |
| 290 | o2_1 = img[(j - 2) * width + i][3]; |
| 291 | o2_2 = img[(j + 2) * width + i][3]; |
| 292 | o2_3 = img[j * width + i - 2][3]; |
| 293 | o2_4 = img[j * width + i + 2][3]; |
| 294 | |
| 295 | m1 = (o1_1 + o1_2 + o1_3 + o1_4) / 4.0; |
| 296 | m2 = (o2_1 + o2_2 + o2_3 + o2_4) / 4.0; |
| 297 | |
| 298 | c1 = (abs(o1_1 - o1_2) + abs(o1_1 - o1_3) + abs(o1_1 - o1_4) + |
| 299 | abs(o1_2 - o1_3) + abs(o1_3 - o1_4) + abs(o1_2 - o1_4)) / |
| 300 | 6.0; |
| 301 | c2 = (abs(o2_1 - o2_2) + abs(o2_1 - o2_3) + abs(o2_1 - o2_4) + |
| 302 | abs(o2_2 - o2_3) + abs(o2_3 - o2_4) + abs(o2_2 - o2_4)) / |
| 303 | 6.0; |
| 304 | if ((img[j * width + i][3] < maximum * 0.95) && (c1 < maximum * thr) && |
| 305 | (c2 < maximum * thr)) |
| 306 | { |
| 307 | f = float(image[j * width + i][3] * m1 / m2); |
| 308 | image[j * width + i][3] = f > 65535.f ? 0xffff : ushort(f); |
| 309 | } |
| 310 | } |
| 311 | free(img); |
| 312 | } |