/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 | 0 | { |
23 | 0 | static const short mul[4][5] = {{667, 358, 397, 565, 452}, |
24 | 0 | {731, 390, 367, 499, 517}, |
25 | 0 | {1119, 396, 348, 448, 537}, |
26 | 0 | {1399, 485, 431, 508, 688}}; |
27 | 0 | int lo, hi, i; |
28 | 0 | float frac = 0; |
29 | |
|
30 | 0 | for (lo = 4; --lo;) |
31 | 0 | if (*mul[lo] <= temp) |
32 | 0 | break; |
33 | 0 | for (hi = 0; hi < 3; hi++) |
34 | 0 | if (*mul[hi] >= temp) |
35 | 0 | break; |
36 | 0 | if (lo != hi) |
37 | 0 | frac = (float)(temp - *mul[lo]) / (*mul[hi] - *mul[lo]); |
38 | 0 | for (i = 1; i < 5; i++) |
39 | 0 | pre_mul[i - 1] = 1 / (frac * mul[hi][i] + (1 - frac) * mul[lo][i]); |
40 | 0 | } |
41 | | |
42 | | /* Return values: 0 = white 1 = near white 2 = not white */ |
43 | | int LibRaw::canon_600_color(int ratio[2], int mar) |
44 | 0 | { |
45 | 0 | int clipped = 0, target, miss; |
46 | |
|
47 | 0 | 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 | 0 | else |
61 | 0 | { |
62 | 0 | if (ratio[1] < -264 || ratio[1] > 461) |
63 | 0 | return 2; |
64 | 0 | if (ratio[1] < -50) |
65 | 0 | { |
66 | 0 | ratio[1] = -50; |
67 | 0 | clipped = 1; |
68 | 0 | } |
69 | 0 | if (ratio[1] > 307) |
70 | 0 | { |
71 | 0 | ratio[1] = 307; |
72 | 0 | clipped = 1; |
73 | 0 | } |
74 | 0 | } |
75 | 0 | target = flash_used || ratio[1] < 197 ? -38 - (398 * ratio[1] >> 10) |
76 | 0 | : -123 + (48 * ratio[1] >> 10); |
77 | 0 | if (target - mar <= ratio[0] && target + 20 >= ratio[0] && !clipped) |
78 | 0 | return 0; |
79 | 0 | miss = target - ratio[0]; |
80 | 0 | if (abs(miss) >= mar * 4) |
81 | 0 | return 2; |
82 | 0 | if (miss < -20) |
83 | 0 | miss = -20; |
84 | 0 | if (miss > mar) |
85 | 0 | miss = mar; |
86 | 0 | ratio[0] = target - miss; |
87 | 0 | return 1; |
88 | 0 | } |
89 | | |
90 | | void LibRaw::canon_600_auto_wb() |
91 | 0 | { |
92 | 0 | int mar, row, col, i, j, st, count[] = {0, 0}; |
93 | 0 | int test[8], total[2][8], ratio[2][2], stat[2]; |
94 | |
|
95 | 0 | memset(&total, 0, sizeof total); |
96 | 0 | i = int(canon_ev + 0.5); |
97 | 0 | if (i < 10) |
98 | 0 | mar = 150; |
99 | 0 | else if (i > 12) |
100 | 0 | mar = 20; |
101 | 0 | else |
102 | 0 | mar = 280 - 20 * i; |
103 | 0 | if (flash_used) |
104 | 0 | mar = 80; |
105 | 0 | for (row = 14; row < height - 14; row += 4) |
106 | 0 | for (col = 10; col < width; col += 2) |
107 | 0 | { |
108 | 0 | for (i = 0; i < 8; i++) |
109 | 0 | test[(i & 4) + FC(row + (i >> 1), col + (i & 1))] = |
110 | 0 | BAYER(row + (i >> 1), col + (i & 1)); |
111 | 0 | for (i = 0; i < 8; i++) |
112 | 0 | if (test[i] < 150 || test[i] > 1500) |
113 | 0 | goto next; |
114 | 0 | for (i = 0; i < 4; i++) |
115 | 0 | if (abs(test[i] - test[i + 4]) > 50) |
116 | 0 | goto next; |
117 | 0 | for (i = 0; i < 2; i++) |
118 | 0 | { |
119 | 0 | for (j = 0; j < 4; j += 2) |
120 | 0 | ratio[i][j >> 1] = |
121 | 0 | ((test[i * 4 + j + 1] - test[i * 4 + j]) << 10) / test[i * 4 + j]; |
122 | 0 | stat[i] = canon_600_color(ratio[i], mar); |
123 | 0 | } |
124 | 0 | if ((st = stat[0] | stat[1]) > 1) |
125 | 0 | goto next; |
126 | 0 | for (i = 0; i < 2; i++) |
127 | 0 | if (stat[i]) |
128 | 0 | for (j = 0; j < 2; j++) |
129 | 0 | test[i * 4 + j * 2 + 1] = |
130 | 0 | test[i * 4 + j * 2] * (0x400 + ratio[i][j]) >> 10; |
131 | 0 | for (i = 0; i < 8; i++) |
132 | 0 | total[st][i] += test[i]; |
133 | 0 | count[st]++; |
134 | 0 | next:; |
135 | 0 | } |
136 | 0 | if (count[0] | count[1]) |
137 | 0 | { |
138 | 0 | st = count[0] * 200 < count[1]; |
139 | 0 | for (i = 0; i < 4; i++) |
140 | 0 | if (total[st][i] + total[st][i + 4]) |
141 | 0 | pre_mul[i] = 1.0f / (total[st][i] + total[st][i + 4]); |
142 | 0 | } |
143 | 0 | } |
144 | | |
145 | | void LibRaw::canon_600_coeff() |
146 | 0 | { |
147 | 0 | static const short table[6][12] = { |
148 | 0 | {-190, 702, -1878, 2390, 1861, -1349, 905, -393, -432, 944, 2617, -2105}, |
149 | 0 | {-1203, 1715, -1136, 1648, 1388, -876, 267, 245, -1641, 2153, 3921, |
150 | 0 | -3409}, |
151 | 0 | {-615, 1127, -1563, 2075, 1437, -925, 509, 3, -756, 1268, 2519, -2007}, |
152 | 0 | {-190, 702, -1886, 2398, 2153, -1641, 763, -251, -452, 964, 3040, -2528}, |
153 | 0 | {-190, 702, -1878, 2390, 1861, -1349, 905, -393, -432, 944, 2617, -2105}, |
154 | 0 | {-807, 1319, -1785, 2297, 1388, -876, 769, -257, -230, 742, 2067, -1555}}; |
155 | 0 | int t = 0, i, c; |
156 | 0 | float mc, yc; |
157 | |
|
158 | 0 | mc = pre_mul[1] / pre_mul[2]; |
159 | 0 | yc = pre_mul[3] / pre_mul[2]; |
160 | 0 | if (mc > 1 && mc <= 1.28 && yc < 0.8789) |
161 | 0 | t = 1; |
162 | 0 | if (mc > 1.28 && mc <= 2) |
163 | 0 | { |
164 | 0 | if (yc < 0.8789) |
165 | 0 | t = 3; |
166 | 0 | else if (yc <= 2) |
167 | 0 | t = 4; |
168 | 0 | } |
169 | 0 | if (flash_used) |
170 | 0 | t = 5; |
171 | 0 | for (raw_color = i = 0; i < 3; i++) |
172 | 0 | FORCC rgb_cam[i][c] = float(table[t][i * 4 + c]) / 1024.f; |
173 | 0 | } |
174 | | |
175 | | void LibRaw::canon_600_load_raw() |
176 | 0 | { |
177 | 0 | uchar data[1120], *dp; |
178 | 0 | ushort *pix; |
179 | 0 | int irow, row; |
180 | |
|
181 | 0 | for (irow = row = 0; irow < height; irow++) |
182 | 0 | { |
183 | 0 | checkCancel(); |
184 | 0 | if (fread(data, 1, 1120, ifp) < 1120) |
185 | 0 | derror(); |
186 | 0 | pix = raw_image + row * raw_width; |
187 | 0 | for (dp = data; dp < data + 1120; dp += 10, pix += 8) |
188 | 0 | { |
189 | 0 | pix[0] = (dp[0] << 2) + (dp[1] >> 6); |
190 | 0 | pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3); |
191 | 0 | pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3); |
192 | 0 | pix[3] = (dp[4] << 2) + (dp[1] & 3); |
193 | 0 | pix[4] = (dp[5] << 2) + (dp[9] & 3); |
194 | 0 | pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3); |
195 | 0 | pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3); |
196 | 0 | pix[7] = (dp[8] << 2) + (dp[9] >> 6); |
197 | 0 | } |
198 | 0 | if ((row += 2) > height) |
199 | 0 | row = 1; |
200 | 0 | } |
201 | 0 | } |
202 | | |
203 | | void LibRaw::canon_600_correct() |
204 | 0 | { |
205 | 0 | int row, col, val; |
206 | 0 | static const short mul[4][2] = { |
207 | 0 | {1141, 1145}, {1128, 1109}, {1178, 1149}, {1128, 1109}}; |
208 | |
|
209 | 0 | for (row = 0; row < height; row++) |
210 | 0 | { |
211 | 0 | checkCancel(); |
212 | 0 | for (col = 0; col < width; col++) |
213 | 0 | { |
214 | 0 | if ((val = BAYER(row, col) - black) < 0) |
215 | 0 | val = 0; |
216 | 0 | val = val * mul[row & 3][col & 1] >> 9; |
217 | 0 | BAYER(row, col) = val; |
218 | 0 | } |
219 | 0 | } |
220 | 0 | canon_600_fixed_wb(1311); |
221 | 0 | canon_600_auto_wb(); |
222 | 0 | canon_600_coeff(); |
223 | 0 | maximum = (0x3ff - black) * 1109 >> 9; |
224 | 0 | black = 0; |
225 | 0 | } |