File indexing completed on 2025-01-05 03:56:49
0001 /* -*- C++ -*- 0002 * Copyright 2019-2021 LibRaw LLC (info@libraw.org) 0003 * 0004 LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, 0005 dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. 0006 LibRaw do not use RESTRICTED code from dcraw.c 0007 0008 LibRaw is free software; you can redistribute it and/or modify 0009 it under the terms of the one of two licenses as you choose: 0010 0011 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 0012 (See file LICENSE.LGPL provided in LibRaw distribution archive for details). 0013 0014 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 0015 (See file LICENSE.CDDL provided in LibRaw distribution archive for details). 0016 0017 */ 0018 0019 #include "../../internal/dcraw_defs.h" 0020 0021 void LibRaw::canon_600_fixed_wb(int temp) 0022 { 0023 static const short mul[4][5] = {{667, 358, 397, 565, 452}, 0024 {731, 390, 367, 499, 517}, 0025 {1119, 396, 348, 448, 537}, 0026 {1399, 485, 431, 508, 688}}; 0027 int lo, hi, i; 0028 float frac = 0; 0029 0030 for (lo = 4; --lo;) 0031 if (*mul[lo] <= temp) 0032 break; 0033 for (hi = 0; hi < 3; hi++) 0034 if (*mul[hi] >= temp) 0035 break; 0036 if (lo != hi) 0037 frac = (float)(temp - *mul[lo]) / (*mul[hi] - *mul[lo]); 0038 for (i = 1; i < 5; i++) 0039 pre_mul[i - 1] = 1 / (frac * mul[hi][i] + (1 - frac) * mul[lo][i]); 0040 } 0041 0042 /* Return values: 0 = white 1 = near white 2 = not white */ 0043 int LibRaw::canon_600_color(int ratio[2], int mar) 0044 { 0045 int clipped = 0, target, miss; 0046 0047 if (flash_used) 0048 { 0049 if (ratio[1] < -104) 0050 { 0051 ratio[1] = -104; 0052 clipped = 1; 0053 } 0054 if (ratio[1] > 12) 0055 { 0056 ratio[1] = 12; 0057 clipped = 1; 0058 } 0059 } 0060 else 0061 { 0062 if (ratio[1] < -264 || ratio[1] > 461) 0063 return 2; 0064 if (ratio[1] < -50) 0065 { 0066 ratio[1] = -50; 0067 clipped = 1; 0068 } 0069 if (ratio[1] > 307) 0070 { 0071 ratio[1] = 307; 0072 clipped = 1; 0073 } 0074 } 0075 target = flash_used || ratio[1] < 197 ? -38 - (398 * ratio[1] >> 10) 0076 : -123 + (48 * ratio[1] >> 10); 0077 if (target - mar <= ratio[0] && target + 20 >= ratio[0] && !clipped) 0078 return 0; 0079 miss = target - ratio[0]; 0080 if (abs(miss) >= mar * 4) 0081 return 2; 0082 if (miss < -20) 0083 miss = -20; 0084 if (miss > mar) 0085 miss = mar; 0086 ratio[0] = target - miss; 0087 return 1; 0088 } 0089 0090 void LibRaw::canon_600_auto_wb() 0091 { 0092 int mar, row, col, i, j, st, count[] = {0, 0}; 0093 int test[8], total[2][8], ratio[2][2], stat[2]; 0094 0095 memset(&total, 0, sizeof total); 0096 i = int(canon_ev + 0.5); 0097 if (i < 10) 0098 mar = 150; 0099 else if (i > 12) 0100 mar = 20; 0101 else 0102 mar = 280 - 20 * i; 0103 if (flash_used) 0104 mar = 80; 0105 for (row = 14; row < height - 14; row += 4) 0106 for (col = 10; col < width; col += 2) 0107 { 0108 for (i = 0; i < 8; i++) 0109 test[(i & 4) + FC(row + (i >> 1), col + (i & 1))] = 0110 BAYER(row + (i >> 1), col + (i & 1)); 0111 for (i = 0; i < 8; i++) 0112 if (test[i] < 150 || test[i] > 1500) 0113 goto next; 0114 for (i = 0; i < 4; i++) 0115 if (abs(test[i] - test[i + 4]) > 50) 0116 goto next; 0117 for (i = 0; i < 2; i++) 0118 { 0119 for (j = 0; j < 4; j += 2) 0120 ratio[i][j >> 1] = 0121 ((test[i * 4 + j + 1] - test[i * 4 + j]) << 10) / test[i * 4 + j]; 0122 stat[i] = canon_600_color(ratio[i], mar); 0123 } 0124 if ((st = stat[0] | stat[1]) > 1) 0125 goto next; 0126 for (i = 0; i < 2; i++) 0127 if (stat[i]) 0128 for (j = 0; j < 2; j++) 0129 test[i * 4 + j * 2 + 1] = 0130 test[i * 4 + j * 2] * (0x400 + ratio[i][j]) >> 10; 0131 for (i = 0; i < 8; i++) 0132 total[st][i] += test[i]; 0133 count[st]++; 0134 next:; 0135 } 0136 if (count[0] | count[1]) 0137 { 0138 st = count[0] * 200 < count[1]; 0139 for (i = 0; i < 4; i++) 0140 if (total[st][i] + total[st][i + 4]) 0141 pre_mul[i] = 1.0f / (total[st][i] + total[st][i + 4]); 0142 } 0143 } 0144 0145 void LibRaw::canon_600_coeff() 0146 { 0147 static const short table[6][12] = { 0148 {-190, 702, -1878, 2390, 1861, -1349, 905, -393, -432, 944, 2617, -2105}, 0149 {-1203, 1715, -1136, 1648, 1388, -876, 267, 245, -1641, 2153, 3921, 0150 -3409}, 0151 {-615, 1127, -1563, 2075, 1437, -925, 509, 3, -756, 1268, 2519, -2007}, 0152 {-190, 702, -1886, 2398, 2153, -1641, 763, -251, -452, 964, 3040, -2528}, 0153 {-190, 702, -1878, 2390, 1861, -1349, 905, -393, -432, 944, 2617, -2105}, 0154 {-807, 1319, -1785, 2297, 1388, -876, 769, -257, -230, 742, 2067, -1555}}; 0155 int t = 0, i, c; 0156 float mc, yc; 0157 0158 mc = pre_mul[1] / pre_mul[2]; 0159 yc = pre_mul[3] / pre_mul[2]; 0160 if (mc > 1 && mc <= 1.28 && yc < 0.8789) 0161 t = 1; 0162 if (mc > 1.28 && mc <= 2) 0163 { 0164 if (yc < 0.8789) 0165 t = 3; 0166 else if (yc <= 2) 0167 t = 4; 0168 } 0169 if (flash_used) 0170 t = 5; 0171 for (raw_color = i = 0; i < 3; i++) 0172 FORCC rgb_cam[i][c] = float(table[t][i * 4 + c]) / 1024.f; 0173 } 0174 0175 void LibRaw::canon_600_load_raw() 0176 { 0177 uchar data[1120], *dp; 0178 ushort *pix; 0179 int irow, row; 0180 0181 for (irow = row = 0; irow < height; irow++) 0182 { 0183 checkCancel(); 0184 if (fread(data, 1, 1120, ifp) < 1120) 0185 derror(); 0186 pix = raw_image + row * raw_width; 0187 for (dp = data; dp < data + 1120; dp += 10, pix += 8) 0188 { 0189 pix[0] = (dp[0] << 2) + (dp[1] >> 6); 0190 pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3); 0191 pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3); 0192 pix[3] = (dp[4] << 2) + (dp[1] & 3); 0193 pix[4] = (dp[5] << 2) + (dp[9] & 3); 0194 pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3); 0195 pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3); 0196 pix[7] = (dp[8] << 2) + (dp[9] >> 6); 0197 } 0198 if ((row += 2) > height) 0199 row = 1; 0200 } 0201 } 0202 0203 void LibRaw::canon_600_correct() 0204 { 0205 int row, col, val; 0206 static const short mul[4][2] = { 0207 {1141, 1145}, {1128, 1109}, {1178, 1149}, {1128, 1109}}; 0208 0209 for (row = 0; row < height; row++) 0210 { 0211 checkCancel(); 0212 for (col = 0; col < width; col++) 0213 { 0214 if ((val = BAYER(row, col) - black) < 0) 0215 val = 0; 0216 val = val * mul[row & 3][col & 1] >> 9; 0217 BAYER(row, col) = val; 0218 } 0219 } 0220 canon_600_fixed_wb(1311); 0221 canon_600_auto_wb(); 0222 canon_600_coeff(); 0223 maximum = (0x3ff - black) * 1109 >> 9; 0224 black = 0; 0225 }