/src/LibRaw/src/decoders/canon_600.cpp
Line | Count | Source |
1 | | /* -*- C++ -*- |
2 | | * Copyright 2019-2025 LibRaw LLC (info@libraw.org) |
3 | | * |
4 | | LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, |
5 | | dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. |
6 | | LibRaw do not use RESTRICTED code from dcraw.c |
7 | | |
8 | | LibRaw is free software; you can redistribute it and/or modify |
9 | | it under the terms of the one of two licenses as you choose: |
10 | | |
11 | | 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 |
12 | | (See file LICENSE.LGPL provided in LibRaw distribution archive for details). |
13 | | |
14 | | 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 |
15 | | (See file LICENSE.CDDL provided in LibRaw distribution archive for details). |
16 | | |
17 | | */ |
18 | | |
19 | | #include "../../internal/dcraw_defs.h" |
20 | | |
21 | | void LibRaw::canon_600_fixed_wb(int temp) |
22 | 59 | { |
23 | 59 | static const short mul[4][5] = {{667, 358, 397, 565, 452}, |
24 | 59 | {731, 390, 367, 499, 517}, |
25 | 59 | {1119, 396, 348, 448, 537}, |
26 | 59 | {1399, 485, 431, 508, 688}}; |
27 | 59 | int lo, hi, i; |
28 | 59 | float frac = 0; |
29 | | |
30 | 118 | for (lo = 4; --lo;) |
31 | 118 | if (*mul[lo] <= temp) |
32 | 59 | break; |
33 | 236 | for (hi = 0; hi < 3; hi++) |
34 | 177 | if (*mul[hi] >= temp) |
35 | 0 | break; |
36 | 59 | if (lo != hi) |
37 | 59 | frac = (float)(temp - *mul[lo]) / (*mul[hi] - *mul[lo]); |
38 | 295 | for (i = 1; i < 5; i++) |
39 | 236 | pre_mul[i - 1] = 1 / (frac * mul[hi][i] + (1 - frac) * mul[lo][i]); |
40 | 59 | } |
41 | | |
42 | | /* Return values: 0 = white 1 = near white 2 = not white */ |
43 | | int LibRaw::canon_600_color(int ratio[2], int mar) |
44 | 38.5k | { |
45 | 38.5k | int clipped = 0, target, miss; |
46 | | |
47 | 38.5k | if (flash_used) |
48 | 0 | { |
49 | 0 | if (ratio[1] < -104) |
50 | 0 | { |
51 | 0 | ratio[1] = -104; |
52 | 0 | clipped = 1; |
53 | 0 | } |
54 | 0 | if (ratio[1] > 12) |
55 | 0 | { |
56 | 0 | ratio[1] = 12; |
57 | 0 | clipped = 1; |
58 | 0 | } |
59 | 0 | } |
60 | 38.5k | else |
61 | 38.5k | { |
62 | 38.5k | if (ratio[1] < -264 || ratio[1] > 461) |
63 | 50 | return 2; |
64 | 38.5k | if (ratio[1] < -50) |
65 | 60 | { |
66 | 60 | ratio[1] = -50; |
67 | 60 | clipped = 1; |
68 | 60 | } |
69 | 38.5k | if (ratio[1] > 307) |
70 | 18 | { |
71 | 18 | ratio[1] = 307; |
72 | 18 | clipped = 1; |
73 | 18 | } |
74 | 38.5k | } |
75 | 38.5k | target = flash_used || ratio[1] < 197 ? -38 - (398 * ratio[1] >> 10) |
76 | 38.5k | : -123 + (48 * ratio[1] >> 10); |
77 | 38.5k | if (target - mar <= ratio[0] && target + 20 >= ratio[0] && !clipped) |
78 | 5.44k | return 0; |
79 | 33.0k | miss = target - ratio[0]; |
80 | 33.0k | if (abs(miss) >= mar * 4) |
81 | 25 | return 2; |
82 | 33.0k | if (miss < -20) |
83 | 33.0k | miss = -20; |
84 | 33.0k | if (miss > mar) |
85 | 13 | miss = mar; |
86 | 33.0k | ratio[0] = target - miss; |
87 | 33.0k | return 1; |
88 | 33.0k | } |
89 | | |
90 | | void LibRaw::canon_600_auto_wb() |
91 | 59 | { |
92 | 59 | int mar, row, col, i, j, st, count[] = {0, 0}; |
93 | 59 | int test[8], total[2][8], ratio[2][2], stat[2]; |
94 | | |
95 | 59 | memset(&total, 0, sizeof total); |
96 | 59 | i = int(canon_ev + 0.5); |
97 | 59 | if (i < 10) |
98 | 59 | mar = 150; |
99 | 0 | else if (i > 12) |
100 | 0 | mar = 20; |
101 | 0 | else |
102 | 0 | mar = 280 - 20 * i; |
103 | 59 | if (flash_used) |
104 | 0 | mar = 80; |
105 | 8.73k | for (row = 14; row < height - 14; row += 4) |
106 | 3.66M | for (col = 10; col < width; col += 2) |
107 | 3.66M | { |
108 | 32.9M | for (i = 0; i < 8; i++) |
109 | 29.2M | test[(i & 4) + FC(row + (i >> 1), col + (i & 1))] = |
110 | 29.2M | BAYER(row + (i >> 1), col + (i & 1)); |
111 | 5.29M | for (i = 0; i < 8; i++) |
112 | 5.27M | if (test[i] < 150 || test[i] > 1500) |
113 | 3.63M | goto next; |
114 | 105k | for (i = 0; i < 4; i++) |
115 | 85.8k | if (abs(test[i] - test[i + 4]) > 50) |
116 | 3.18k | goto next; |
117 | 57.8k | for (i = 0; i < 2; i++) |
118 | 38.5k | { |
119 | 115k | for (j = 0; j < 4; j += 2) |
120 | 77.1k | ratio[i][j >> 1] = |
121 | 77.1k | ((test[i * 4 + j + 1] - test[i * 4 + j]) << 10) / test[i * 4 + j]; |
122 | 38.5k | stat[i] = canon_600_color(ratio[i], mar); |
123 | 38.5k | } |
124 | 19.2k | if ((st = stat[0] | stat[1]) > 1) |
125 | 42 | goto next; |
126 | 57.7k | for (i = 0; i < 2; i++) |
127 | 38.4k | if (stat[i]) |
128 | 99.1k | for (j = 0; j < 2; j++) |
129 | 66.1k | test[i * 4 + j * 2 + 1] = |
130 | 66.1k | test[i * 4 + j * 2] * (0x400 + ratio[i][j]) >> 10; |
131 | 173k | for (i = 0; i < 8; i++) |
132 | 153k | total[st][i] += test[i]; |
133 | 19.2k | count[st]++; |
134 | 3.66M | next:; |
135 | 3.66M | } |
136 | 59 | if (count[0] | count[1]) |
137 | 39 | { |
138 | 39 | st = count[0] * 200 < count[1]; |
139 | 195 | for (i = 0; i < 4; i++) |
140 | 156 | if (total[st][i] + total[st][i + 4]) |
141 | 156 | pre_mul[i] = 1.0f / (total[st][i] + total[st][i + 4]); |
142 | 39 | } |
143 | 59 | } |
144 | | |
145 | | void LibRaw::canon_600_coeff() |
146 | 59 | { |
147 | 59 | static const short table[6][12] = { |
148 | 59 | {-190, 702, -1878, 2390, 1861, -1349, 905, -393, -432, 944, 2617, -2105}, |
149 | 59 | {-1203, 1715, -1136, 1648, 1388, -876, 267, 245, -1641, 2153, 3921, |
150 | 59 | -3409}, |
151 | 59 | {-615, 1127, -1563, 2075, 1437, -925, 509, 3, -756, 1268, 2519, -2007}, |
152 | 59 | {-190, 702, -1886, 2398, 2153, -1641, 763, -251, -452, 964, 3040, -2528}, |
153 | 59 | {-190, 702, -1878, 2390, 1861, -1349, 905, -393, -432, 944, 2617, -2105}, |
154 | 59 | {-807, 1319, -1785, 2297, 1388, -876, 769, -257, -230, 742, 2067, -1555}}; |
155 | 59 | int t = 0, i, c; |
156 | 59 | float mc, yc; |
157 | | |
158 | 59 | mc = pre_mul[1] / pre_mul[2]; |
159 | 59 | yc = pre_mul[3] / pre_mul[2]; |
160 | 59 | if (mc > 1 && mc <= 1.28 && yc < 0.8789) |
161 | 20 | t = 1; |
162 | 59 | if (mc > 1.28 && mc <= 2) |
163 | 18 | { |
164 | 18 | if (yc < 0.8789) |
165 | 2 | t = 3; |
166 | 16 | else if (yc <= 2) |
167 | 16 | t = 4; |
168 | 18 | } |
169 | 59 | if (flash_used) |
170 | 0 | t = 5; |
171 | 236 | for (raw_color = i = 0; i < 3; i++) |
172 | 708 | FORCC rgb_cam[i][c] = float(table[t][i * 4 + c]) / 1024.f; |
173 | 59 | } |
174 | | |
175 | | void LibRaw::canon_600_load_raw() |
176 | 71 | { |
177 | 71 | uchar data[1120], *dp; |
178 | 71 | ushort *pix; |
179 | 71 | int irow, row; |
180 | | |
181 | 37.5k | for (irow = row = 0; irow < height; irow++) |
182 | 37.4k | { |
183 | 37.4k | checkCancel(); |
184 | 37.4k | if (fread(data, 1, 1120, ifp) < 1120) |
185 | 12 | derror(); |
186 | 37.4k | pix = raw_image + row * raw_width; |
187 | 4.23M | for (dp = data; dp < data + 1120; dp += 10, pix += 8) |
188 | 4.19M | { |
189 | 4.19M | pix[0] = (dp[0] << 2) + (dp[1] >> 6); |
190 | 4.19M | pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3); |
191 | 4.19M | pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3); |
192 | 4.19M | pix[3] = (dp[4] << 2) + (dp[1] & 3); |
193 | 4.19M | pix[4] = (dp[5] << 2) + (dp[9] & 3); |
194 | 4.19M | pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3); |
195 | 4.19M | pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3); |
196 | 4.19M | pix[7] = (dp[8] << 2) + (dp[9] >> 6); |
197 | 4.19M | } |
198 | 37.4k | if ((row += 2) > height) |
199 | 62 | row = 1; |
200 | 37.4k | } |
201 | 71 | } |
202 | | |
203 | | void LibRaw::canon_600_correct() |
204 | 59 | { |
205 | 59 | int row, col, val; |
206 | 59 | static const short mul[4][2] = { |
207 | 59 | {1141, 1145}, {1128, 1109}, {1178, 1149}, {1128, 1109}}; |
208 | | |
209 | 36.2k | for (row = 0; row < height; row++) |
210 | 36.1k | { |
211 | 36.1k | checkCancel(); |
212 | 30.9M | for (col = 0; col < width; col++) |
213 | 30.8M | { |
214 | 30.8M | if ((val = BAYER(row, col) - black) < 0) |
215 | 24.1M | val = 0; |
216 | 30.8M | val = val * mul[row & 3][col & 1] >> 9; |
217 | 30.8M | BAYER(row, col) = val; |
218 | 30.8M | } |
219 | 36.1k | } |
220 | 59 | canon_600_fixed_wb(1311); |
221 | 59 | canon_600_auto_wb(); |
222 | 59 | canon_600_coeff(); |
223 | 59 | maximum = (0x3ff - black) * 1109 >> 9; |
224 | 59 | black = 0; |
225 | 59 | } |