/src/libraw/src/demosaic/dcb_demosaic.cpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 2010, Jacek Gozdz (cuniek@kft.umcs.lublin.pl) |
3 | | * |
4 | | * This code is licensed under a (3-clause) BSD license as follows : |
5 | | * |
6 | | * Redistribution and use in source and binary forms, with or without |
7 | | * modification, are permitted provided that the following |
8 | | * conditions are met: |
9 | | * |
10 | | * * Redistributions of source code must retain the above copyright |
11 | | * notice, this list of conditions and the following disclaimer. |
12 | | * * Redistributions in binary form must reproduce the above |
13 | | * copyright notice, this list of conditions and the following |
14 | | * disclaimer in the documentation and/or other materials provided |
15 | | * with the distribution. |
16 | | * * Neither the name of the author nor the names of its |
17 | | * contributors may be used to endorse or promote products |
18 | | * derived from this software without specific prior written permission. |
19 | | * |
20 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
21 | | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
22 | | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
23 | | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL |
24 | | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
25 | | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
26 | | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
27 | | * SERVICES; LOSS OF USE, |
28 | | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
29 | | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
30 | | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
31 | | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
32 | | * OF SUCH DAMAGE. |
33 | | */ |
34 | | |
35 | | // DCB demosaicing by Jacek Gozdz (cuniek@kft.umcs.lublin.pl) |
36 | | |
37 | | // FBDD denoising by Jacek Gozdz (cuniek@kft.umcs.lublin.pl) and |
38 | | // Luis Sanz Rodríguez (luis.sanz.rodriguez@gmail.com) |
39 | | |
40 | | // last modification: 11.07.2010 |
41 | | |
42 | | #include "../../internal/dcraw_defs.h" |
43 | | |
44 | | // interpolates green vertically and saves it to image3 |
45 | | void LibRaw::dcb_ver(float (*image3)[3]) |
46 | 3.07k | { |
47 | 3.07k | int row, col, u = width, indx; |
48 | | |
49 | 1.03M | for (row = 2; row < height - 2; row++) |
50 | 65.6M | for (col = 2 + (FC(row, 2) & 1), indx = row * width + col; col < u - 2; |
51 | 64.6M | col += 2, indx += 2) |
52 | 64.6M | { |
53 | | |
54 | 64.6M | image3[indx][1] = float(CLIP((image[indx + u][1] + image[indx - u][1]) / 2.0)); |
55 | 64.6M | } |
56 | 3.07k | } |
57 | | |
58 | | // interpolates green horizontally and saves it to image2 |
59 | | void LibRaw::dcb_hor(float (*image2)[3]) |
60 | 3.07k | { |
61 | 3.07k | int row, col, u = width, indx; |
62 | | |
63 | 1.03M | for (row = 2; row < height - 2; row++) |
64 | 65.6M | for (col = 2 + (FC(row, 2) & 1), indx = row * width + col; col < u - 2; |
65 | 64.6M | col += 2, indx += 2) |
66 | 64.6M | { |
67 | | |
68 | 64.6M | image2[indx][1] = float(CLIP((image[indx + 1][1] + image[indx - 1][1]) / 2.0)); |
69 | 64.6M | } |
70 | 3.07k | } |
71 | | |
72 | | // missing colors are interpolated |
73 | | void LibRaw::dcb_color() |
74 | 19.1k | { |
75 | 19.1k | int row, col, c, d, u = width, indx; |
76 | | |
77 | 4.62M | for (row = 1; row < height - 1; row++) |
78 | 4.60M | for (col = 1 + (FC(row, 1) & 1), indx = row * width + col, |
79 | 4.60M | c = 2 - FC(row, col); |
80 | 326M | col < u - 1; col += 2, indx += 2) |
81 | 321M | { |
82 | | |
83 | 321M | image[indx][c] = CLIP((4 * image[indx][1] - image[indx + u + 1][1] - |
84 | 321M | image[indx + u - 1][1] - image[indx - u + 1][1] - |
85 | 321M | image[indx - u - 1][1] + image[indx + u + 1][c] + |
86 | 321M | image[indx + u - 1][c] + image[indx - u + 1][c] + |
87 | 321M | image[indx - u - 1][c]) / |
88 | 321M | 4.0); |
89 | 321M | } |
90 | | |
91 | 4.62M | for (row = 1; row < height - 1; row++) |
92 | 4.60M | for (col = 1 + (FC(row, 2) & 1), indx = row * width + col, |
93 | 4.60M | c = FC(row, col + 1), d = 2 - c; |
94 | 326M | col < width - 1; col += 2, indx += 2) |
95 | 321M | { |
96 | | |
97 | 321M | image[indx][c] = |
98 | 321M | CLIP((2 * image[indx][1] - image[indx + 1][1] - image[indx - 1][1] + |
99 | 321M | image[indx + 1][c] + image[indx - 1][c]) / |
100 | 321M | 2.0); |
101 | 321M | image[indx][d] = |
102 | 321M | CLIP((2 * image[indx][1] - image[indx + u][1] - image[indx - u][1] + |
103 | 321M | image[indx + u][d] + image[indx - u][d]) / |
104 | 321M | 2.0); |
105 | 321M | } |
106 | 19.1k | } |
107 | | |
108 | | // missing R and B are interpolated horizontally and saved in image2 |
109 | | void LibRaw::dcb_color2(float (*image2)[3]) |
110 | 3.07k | { |
111 | 3.07k | int row, col, c, d, u = width, indx; |
112 | | |
113 | 1.04M | for (row = 1; row < height - 1; row++) |
114 | 1.04M | for (col = 1 + (FC(row, 1) & 1), indx = row * width + col, |
115 | 1.04M | c = 2 - FC(row, col); |
116 | 67.5M | col < u - 1; col += 2, indx += 2) |
117 | 66.5M | { |
118 | | |
119 | 66.5M | image2[indx][c] = |
120 | 66.5M | float( |
121 | 66.5M | CLIP((4 * image2[indx][1] - image2[indx + u + 1][1] - |
122 | 66.5M | image2[indx + u - 1][1] - image2[indx - u + 1][1] - |
123 | 66.5M | image2[indx - u - 1][1] + image[indx + u + 1][c] + |
124 | 66.5M | image[indx + u - 1][c] + image[indx - u + 1][c] + |
125 | 66.5M | image[indx - u - 1][c]) / |
126 | 66.5M | 4.0) |
127 | 66.5M | ); |
128 | 66.5M | } |
129 | | |
130 | 1.04M | for (row = 1; row < height - 1; row++) |
131 | 1.04M | for (col = 1 + (FC(row, 2) & 1), indx = row * width + col, |
132 | 1.04M | c = FC(row, col + 1), d = 2 - c; |
133 | 67.5M | col < width - 1; col += 2, indx += 2) |
134 | 66.5M | { |
135 | | |
136 | 66.5M | image2[indx][c] = float(CLIP((image[indx + 1][c] + image[indx - 1][c]) / 2.0)); |
137 | 66.5M | image2[indx][d] = |
138 | 66.5M | float(CLIP((2 * image2[indx][1] - image2[indx + u][1] - |
139 | 66.5M | image2[indx - u][1] + image[indx + u][d] + image[indx - u][d]) / |
140 | 66.5M | 2.0)); |
141 | 66.5M | } |
142 | 3.07k | } |
143 | | |
144 | | // missing R and B are interpolated vertically and saved in image3 |
145 | | void LibRaw::dcb_color3(float (*image3)[3]) |
146 | 3.07k | { |
147 | 3.07k | int row, col, c, d, u = width, indx; |
148 | | |
149 | 1.04M | for (row = 1; row < height - 1; row++) |
150 | 1.04M | for (col = 1 + (FC(row, 1) & 1), indx = row * width + col, |
151 | 1.04M | c = 2 - FC(row, col); |
152 | 67.5M | col < u - 1; col += 2, indx += 2) |
153 | 66.5M | { |
154 | | |
155 | 66.5M | image3[indx][c] = |
156 | 66.5M | float( |
157 | 66.5M | CLIP((4 * image3[indx][1] - image3[indx + u + 1][1] - |
158 | 66.5M | image3[indx + u - 1][1] - image3[indx - u + 1][1] - |
159 | 66.5M | image3[indx - u - 1][1] + image[indx + u + 1][c] + |
160 | 66.5M | image[indx + u - 1][c] + image[indx - u + 1][c] + |
161 | 66.5M | image[indx - u - 1][c]) / |
162 | 66.5M | 4.0) |
163 | 66.5M | ); |
164 | 66.5M | } |
165 | | |
166 | 1.04M | for (row = 1; row < height - 1; row++) |
167 | 1.04M | for (col = 1 + (FC(row, 2) & 1), indx = row * width + col, |
168 | 1.04M | c = FC(row, col + 1), d = 2 - c; |
169 | 67.5M | col < width - 1; col += 2, indx += 2) |
170 | 66.5M | { |
171 | | |
172 | 66.5M | image3[indx][c] = |
173 | 66.5M | float( |
174 | 66.5M | CLIP((2 * image3[indx][1] - image3[indx + 1][1] - |
175 | 66.5M | image3[indx - 1][1] + image[indx + 1][c] + image[indx - 1][c]) / |
176 | 66.5M | 2.0) |
177 | 66.5M | ); |
178 | 66.5M | image3[indx][d] = float(CLIP((image[indx + u][d] + image[indx - u][d]) / 2.0)); |
179 | 66.5M | } |
180 | 3.07k | } |
181 | | |
182 | | // decides the primary green interpolation direction |
183 | | void LibRaw::dcb_decide(float (*image2)[3], float (*image3)[3]) |
184 | 3.07k | { |
185 | 3.07k | int row, col, c, d, u = width, v = 2 * u, indx; |
186 | 3.07k | float current, current2, current3; |
187 | | |
188 | 1.03M | for (row = 2; row < height - 2; row++) |
189 | 1.03M | for (col = 2 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col); |
190 | 65.6M | col < u - 2; col += 2, indx += 2) |
191 | 64.6M | { |
192 | | |
193 | 64.6M | d = ABS(c - 2); |
194 | | |
195 | 64.6M | current = float(MAX(image[indx + v][c], |
196 | 64.6M | MAX(image[indx - v][c], |
197 | 64.6M | MAX(image[indx - 2][c], image[indx + 2][c]))) - |
198 | 64.6M | MIN(image[indx + v][c], |
199 | 64.6M | MIN(image[indx - v][c], |
200 | 64.6M | MIN(image[indx - 2][c], image[indx + 2][c]))) + |
201 | 64.6M | MAX(image[indx + 1 + u][d], |
202 | 64.6M | MAX(image[indx + 1 - u][d], |
203 | 64.6M | MAX(image[indx - 1 + u][d], image[indx - 1 - u][d]))) - |
204 | 64.6M | MIN(image[indx + 1 + u][d], |
205 | 64.6M | MIN(image[indx + 1 - u][d], |
206 | 64.6M | MIN(image[indx - 1 + u][d], image[indx - 1 - u][d])))); |
207 | | |
208 | 64.6M | current2 = |
209 | 64.6M | float( |
210 | 64.6M | MAX(image2[indx + v][d], |
211 | 64.6M | MAX(image2[indx - v][d], |
212 | 64.6M | MAX(image2[indx - 2][d], image2[indx + 2][d]))) - |
213 | 64.6M | MIN(image2[indx + v][d], |
214 | 64.6M | MIN(image2[indx - v][d], |
215 | 64.6M | MIN(image2[indx - 2][d], image2[indx + 2][d]))) + |
216 | 64.6M | MAX(image2[indx + 1 + u][c], |
217 | 64.6M | MAX(image2[indx + 1 - u][c], |
218 | 64.6M | MAX(image2[indx - 1 + u][c], image2[indx - 1 - u][c]))) - |
219 | 64.6M | MIN(image2[indx + 1 + u][c], |
220 | 64.6M | MIN(image2[indx + 1 - u][c], |
221 | 64.6M | MIN(image2[indx - 1 + u][c], image2[indx - 1 - u][c]))) |
222 | 64.6M | ); |
223 | | |
224 | 64.6M | current3 = |
225 | 64.6M | float( |
226 | 64.6M | MAX(image3[indx + v][d], |
227 | 64.6M | MAX(image3[indx - v][d], |
228 | 64.6M | MAX(image3[indx - 2][d], image3[indx + 2][d]))) - |
229 | 64.6M | MIN(image3[indx + v][d], |
230 | 64.6M | MIN(image3[indx - v][d], |
231 | 64.6M | MIN(image3[indx - 2][d], image3[indx + 2][d]))) + |
232 | 64.6M | MAX(image3[indx + 1 + u][c], |
233 | 64.6M | MAX(image3[indx + 1 - u][c], |
234 | 64.6M | MAX(image3[indx - 1 + u][c], image3[indx - 1 - u][c]))) - |
235 | 64.6M | MIN(image3[indx + 1 + u][c], |
236 | 64.6M | MIN(image3[indx + 1 - u][c], |
237 | 64.6M | MIN(image3[indx - 1 + u][c], image3[indx - 1 - u][c]))) |
238 | 64.6M | ); |
239 | | |
240 | 64.6M | if (ABS(current - current2) < ABS(current - current3)) |
241 | 11.0M | image[indx][1] = ushort(image2[indx][1]); |
242 | 53.6M | else |
243 | 53.6M | image[indx][1] = ushort(image3[indx][1]); |
244 | 64.6M | } |
245 | 3.07k | } |
246 | | |
247 | | // saves red and blue in image2 |
248 | | void LibRaw::dcb_copy_to_buffer(float (*image2)[3]) |
249 | 3.07k | { |
250 | 3.07k | int indx; |
251 | | |
252 | 136M | for (indx = 0; indx < height * width; indx++) |
253 | 136M | { |
254 | 136M | image2[indx][0] = image[indx][0]; // R |
255 | 136M | image2[indx][2] = image[indx][2]; // B |
256 | 136M | } |
257 | 3.07k | } |
258 | | |
259 | | // restores red and blue from image2 |
260 | | void LibRaw::dcb_restore_from_buffer(float (*image2)[3]) |
261 | 3.07k | { |
262 | 3.07k | int indx; |
263 | | |
264 | 136M | for (indx = 0; indx < height * width; indx++) |
265 | 136M | { |
266 | 136M | image[indx][0] = ushort(image2[indx][0]); // R |
267 | 136M | image[indx][2] = ushort(image2[indx][2]); // B |
268 | 136M | } |
269 | 3.07k | } |
270 | | |
271 | | // R and B smoothing using green contrast, all pixels except 2 pixel wide border |
272 | | void LibRaw::dcb_pp() |
273 | 3.07k | { |
274 | 3.07k | int g1, r1, b1, u = width, indx, row, col; |
275 | | |
276 | 1.03M | for (row = 2; row < height - 2; row++) |
277 | 130M | for (col = 2, indx = row * u + col; col < width - 2; col++, indx++) |
278 | 129M | { |
279 | | |
280 | 129M | r1 = int((image[indx - 1][0] + image[indx + 1][0] + image[indx - u][0] + |
281 | 129M | image[indx + u][0] + image[indx - u - 1][0] + |
282 | 129M | image[indx + u + 1][0] + image[indx - u + 1][0] + |
283 | 129M | image[indx + u - 1][0]) / |
284 | 129M | 8.0f); |
285 | 129M | g1 = int((image[indx - 1][1] + image[indx + 1][1] + image[indx - u][1] + |
286 | 129M | image[indx + u][1] + image[indx - u - 1][1] + |
287 | 129M | image[indx + u + 1][1] + image[indx - u + 1][1] + |
288 | 129M | image[indx + u - 1][1]) / |
289 | 129M | 8.0f); |
290 | 129M | b1 = int((image[indx - 1][2] + image[indx + 1][2] + image[indx - u][2] + |
291 | 129M | image[indx + u][2] + image[indx - u - 1][2] + |
292 | 129M | image[indx + u + 1][2] + image[indx - u + 1][2] + |
293 | 129M | image[indx + u - 1][2]) / |
294 | 129M | 8.0f); |
295 | | |
296 | 129M | image[indx][0] = CLIP(r1 + (image[indx][1] - g1)); |
297 | 129M | image[indx][2] = CLIP(b1 + (image[indx][1] - g1)); |
298 | 129M | } |
299 | 3.07k | } |
300 | | |
301 | | // green blurring correction, helps to get the nyquist right |
302 | | void LibRaw::dcb_nyquist() |
303 | 0 | { |
304 | 0 | int row, col, c, u = width, v = 2 * u, indx; |
305 | |
|
306 | 0 | for (row = 2; row < height - 2; row++) |
307 | 0 | for (col = 2 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col); |
308 | 0 | col < u - 2; col += 2, indx += 2) |
309 | 0 | { |
310 | |
|
311 | 0 | image[indx][1] = CLIP((image[indx + v][1] + image[indx - v][1] + |
312 | 0 | image[indx - 2][1] + image[indx + 2][1]) / |
313 | 0 | 4.0 + |
314 | 0 | image[indx][c] - |
315 | 0 | (image[indx + v][c] + image[indx - v][c] + |
316 | 0 | image[indx - 2][c] + image[indx + 2][c]) / |
317 | 0 | 4.0); |
318 | 0 | } |
319 | 0 | } |
320 | | |
321 | | // missing colors are interpolated using high quality algorithm by Luis Sanz |
322 | | // Rodríguez |
323 | | void LibRaw::dcb_color_full() |
324 | 16.3k | { |
325 | 16.3k | int row, col, c, d, u = width, w = 3 * u, indx, g1, g2; |
326 | 16.3k | float f[4], g[4], (*chroma)[2]; |
327 | | |
328 | 16.3k | chroma = (float(*)[2])calloc(width * height, sizeof *chroma); |
329 | | |
330 | 3.32M | for (row = 1; row < height - 1; row++) |
331 | 3.31M | for (col = 1 + (FC(row, 1) & 1), indx = row * width + col, c = FC(row, col), |
332 | 3.31M | d = c / 2; |
333 | 239M | col < u - 1; col += 2, indx += 2) |
334 | 236M | chroma[indx][d] = float(image[indx][c] - image[indx][1]); |
335 | | |
336 | 3.26M | for (row = 3; row < height - 3; row++) |
337 | 3.24M | for (col = 3 + (FC(row, 1) & 1), indx = row * width + col, |
338 | 3.24M | c = 1 - FC(row, col) / 2, d = 1 - c; |
339 | 228M | col < u - 3; col += 2, indx += 2) |
340 | 225M | { |
341 | 225M | f[0] = 1.0f / |
342 | 225M | (float)(1.0 + |
343 | 225M | fabsf(chroma[indx - u - 1][c] - chroma[indx + u + 1][c]) + |
344 | 225M | fabsf(chroma[indx - u - 1][c] - chroma[indx - w - 3][c]) + |
345 | 225M | fabsf(chroma[indx + u + 1][c] - chroma[indx - w - 3][c])); |
346 | 225M | f[1] = 1.0f / |
347 | 225M | (float)(1.0 + |
348 | 225M | fabsf(chroma[indx - u + 1][c] - chroma[indx + u - 1][c]) + |
349 | 225M | fabsf(chroma[indx - u + 1][c] - chroma[indx - w + 3][c]) + |
350 | 225M | fabsf(chroma[indx + u - 1][c] - chroma[indx - w + 3][c])); |
351 | 225M | f[2] = 1.0f / |
352 | 225M | (float)(1.0 + |
353 | 225M | fabsf(chroma[indx + u - 1][c] - chroma[indx - u + 1][c]) + |
354 | 225M | fabsf(chroma[indx + u - 1][c] - chroma[indx + w + 3][c]) + |
355 | 225M | fabsf(chroma[indx - u + 1][c] - chroma[indx + w - 3][c])); |
356 | 225M | f[3] = 1.0f / |
357 | 225M | (float)(1.0 + |
358 | 225M | fabsf(chroma[indx + u + 1][c] - chroma[indx - u - 1][c]) + |
359 | 225M | fabsf(chroma[indx + u + 1][c] - chroma[indx + w - 3][c]) + |
360 | 225M | fabsf(chroma[indx - u - 1][c] - chroma[indx + w + 3][c])); |
361 | 225M | g[0] = 1.325f * chroma[indx - u - 1][c] - 0.175f * chroma[indx - w - 3][c] - |
362 | 225M | 0.075f * chroma[indx - w - 1][c] - 0.075f * chroma[indx - u - 3][c]; |
363 | 225M | g[1] = 1.325f * chroma[indx - u + 1][c] - 0.175f * chroma[indx - w + 3][c] - |
364 | 225M | 0.075f * chroma[indx - w + 1][c] - 0.075f * chroma[indx - u + 3][c]; |
365 | 225M | g[2] = 1.325f * chroma[indx + u - 1][c] - 0.175f * chroma[indx + w - 3][c] - |
366 | 225M | 0.075f * chroma[indx + w - 1][c] - 0.075f * chroma[indx + u - 3][c]; |
367 | 225M | g[3] = 1.325f * chroma[indx + u + 1][c] - 0.175f * chroma[indx + w + 3][c] - |
368 | 225M | 0.075f * chroma[indx + w + 1][c] - 0.075f * chroma[indx + u + 3][c]; |
369 | 225M | chroma[indx][c] = |
370 | 225M | (f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) / |
371 | 225M | (f[0] + f[1] + f[2] + f[3]); |
372 | 225M | } |
373 | 3.26M | for (row = 3; row < height - 3; row++) |
374 | 3.24M | for (col = 3 + (FC(row, 2) & 1), indx = row * width + col, |
375 | 3.24M | c = FC(row, col + 1) / 2; |
376 | 228M | col < u - 3; col += 2, indx += 2) |
377 | 675M | for (d = 0; d <= 1; c = 1 - c, d++) |
378 | 450M | { |
379 | 450M | f[0] = 1.0f / |
380 | 450M | (float)(1.0f + fabsf(chroma[indx - u][c] - chroma[indx + u][c]) + |
381 | 450M | fabsf(chroma[indx - u][c] - chroma[indx - w][c]) + |
382 | 450M | fabsf(chroma[indx + u][c] - chroma[indx - w][c])); |
383 | 450M | f[1] = 1.0f / |
384 | 450M | (float)(1.0f + fabsf(chroma[indx + 1][c] - chroma[indx - 1][c]) + |
385 | 450M | fabsf(chroma[indx + 1][c] - chroma[indx + 3][c]) + |
386 | 450M | fabsf(chroma[indx - 1][c] - chroma[indx + 3][c])); |
387 | 450M | f[2] = 1.0f / |
388 | 450M | (float)(1.0 + fabs(chroma[indx - 1][c] - chroma[indx + 1][c]) + |
389 | 450M | fabs(chroma[indx - 1][c] - chroma[indx - 3][c]) + |
390 | 450M | fabs(chroma[indx + 1][c] - chroma[indx - 3][c])); |
391 | 450M | f[3] = 1.0f / |
392 | 450M | (float)(1.0 + fabs(chroma[indx + u][c] - chroma[indx - u][c]) + |
393 | 450M | fabs(chroma[indx + u][c] - chroma[indx + w][c]) + |
394 | 450M | fabs(chroma[indx - u][c] - chroma[indx + w][c])); |
395 | | |
396 | 450M | g[0] = 0.875f * chroma[indx - u][c] + 0.125f * chroma[indx - w][c]; |
397 | 450M | g[1] = 0.875f * chroma[indx + 1][c] + 0.125f * chroma[indx + 3][c]; |
398 | 450M | g[2] = 0.875f * chroma[indx - 1][c] + 0.125f * chroma[indx - 3][c]; |
399 | 450M | g[3] = 0.875f * chroma[indx + u][c] + 0.125f * chroma[indx + w][c]; |
400 | | |
401 | 450M | chroma[indx][c] = |
402 | 450M | (f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) / |
403 | 450M | (f[0] + f[1] + f[2] + f[3]); |
404 | 450M | } |
405 | | |
406 | 3.16M | for (row = 6; row < height - 6; row++) |
407 | 420M | for (col = 6, indx = row * width + col; col < width - 6; col++, indx++) |
408 | 416M | { |
409 | 416M | image[indx][0] = CLIP(chroma[indx][0] + image[indx][1]); |
410 | 416M | image[indx][2] = CLIP(chroma[indx][1] + image[indx][1]); |
411 | | |
412 | 416M | g1 = MIN( |
413 | 416M | image[indx + 1 + u][0], |
414 | 416M | MIN(image[indx + 1 - u][0], |
415 | 416M | MIN(image[indx - 1 + u][0], |
416 | 416M | MIN(image[indx - 1 - u][0], |
417 | 416M | MIN(image[indx - 1][0], |
418 | 416M | MIN(image[indx + 1][0], |
419 | 416M | MIN(image[indx - u][0], image[indx + u][0]))))))); |
420 | | |
421 | 416M | g2 = MAX( |
422 | 416M | image[indx + 1 + u][0], |
423 | 416M | MAX(image[indx + 1 - u][0], |
424 | 416M | MAX(image[indx - 1 + u][0], |
425 | 416M | MAX(image[indx - 1 - u][0], |
426 | 416M | MAX(image[indx - 1][0], |
427 | 416M | MAX(image[indx + 1][0], |
428 | 416M | MAX(image[indx - u][0], image[indx + u][0]))))))); |
429 | | |
430 | 416M | image[indx][0] = ULIM(image[indx][0], g2, g1); |
431 | | |
432 | 416M | g1 = MIN( |
433 | 416M | image[indx + 1 + u][2], |
434 | 416M | MIN(image[indx + 1 - u][2], |
435 | 416M | MIN(image[indx - 1 + u][2], |
436 | 416M | MIN(image[indx - 1 - u][2], |
437 | 416M | MIN(image[indx - 1][2], |
438 | 416M | MIN(image[indx + 1][2], |
439 | 416M | MIN(image[indx - u][2], image[indx + u][2]))))))); |
440 | | |
441 | 416M | g2 = MAX( |
442 | 416M | image[indx + 1 + u][2], |
443 | 416M | MAX(image[indx + 1 - u][2], |
444 | 416M | MAX(image[indx - 1 + u][2], |
445 | 416M | MAX(image[indx - 1 - u][2], |
446 | 416M | MAX(image[indx - 1][2], |
447 | 416M | MAX(image[indx + 1][2], |
448 | 416M | MAX(image[indx - u][2], image[indx + u][2]))))))); |
449 | | |
450 | 416M | image[indx][2] = ULIM(image[indx][2], g2, g1); |
451 | 416M | } |
452 | | |
453 | 16.3k | free(chroma); |
454 | 16.3k | } |
455 | | |
456 | | // green is used to create an interpolation direction map saved in image[][3] |
457 | | // 1 = vertical |
458 | | // 0 = horizontal |
459 | | void LibRaw::dcb_map() |
460 | 15.3k | { |
461 | 15.3k | int row, col, u = width, indx; |
462 | | |
463 | 5.22M | for (row = 1; row < height - 1; row++) |
464 | 5.20M | { |
465 | 670M | for (col = 1, indx = row * width + col; col < width - 1; col++, indx++) |
466 | 665M | { |
467 | | |
468 | 665M | if (image[indx][1] > (image[indx - 1][1] + image[indx + 1][1] + |
469 | 665M | image[indx - u][1] + image[indx + u][1]) / |
470 | 665M | 4.0) |
471 | 120M | image[indx][3] = ((MIN(image[indx - 1][1], image[indx + 1][1]) + |
472 | 120M | image[indx - 1][1] + image[indx + 1][1]) < |
473 | 120M | (MIN(image[indx - u][1], image[indx + u][1]) + |
474 | 120M | image[indx - u][1] + image[indx + u][1])); |
475 | 545M | else |
476 | 545M | image[indx][3] = ((MAX(image[indx - 1][1], image[indx + 1][1]) + |
477 | 545M | image[indx - 1][1] + image[indx + 1][1]) > |
478 | 545M | (MAX(image[indx - u][1], image[indx + u][1]) + |
479 | 545M | image[indx - u][1] + image[indx + u][1])); |
480 | 665M | } |
481 | 5.20M | } |
482 | 15.3k | } |
483 | | |
484 | | // interpolated green pixels are corrected using the map |
485 | | void LibRaw::dcb_correction() |
486 | 9.21k | { |
487 | 9.21k | int current, row, col, u = width, v = 2 * u, indx; |
488 | | |
489 | 3.11M | for (row = 2; row < height - 2; row++) |
490 | 196M | for (col = 2 + (FC(row, 2) & 1), indx = row * width + col; col < u - 2; |
491 | 193M | col += 2, indx += 2) |
492 | 193M | { |
493 | | |
494 | 193M | current = 4 * image[indx][3] + |
495 | 193M | 2 * (image[indx + u][3] + image[indx - u][3] + |
496 | 193M | image[indx + 1][3] + image[indx - 1][3]) + |
497 | 193M | image[indx + v][3] + image[indx - v][3] + image[indx + 2][3] + |
498 | 193M | image[indx - 2][3]; |
499 | | |
500 | 193M | image[indx][1] = |
501 | 193M | ushort( |
502 | 193M | ((16 - current) * (image[indx - 1][1] + image[indx + 1][1]) / 2.0 + |
503 | 193M | current * (image[indx - u][1] + image[indx + u][1]) / 2.0) / |
504 | 193M | 16.0f); |
505 | 193M | } |
506 | 9.21k | } |
507 | | |
508 | | // interpolated green pixels are corrected using the map |
509 | | // with contrast correction |
510 | | void LibRaw::dcb_correction2() |
511 | 3.07k | { |
512 | 3.07k | int current, row, col, c, u = width, v = 2 * u, indx; |
513 | | |
514 | 1.02M | for (row = 4; row < height - 4; row++) |
515 | 1.02M | for (col = 4 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col); |
516 | 61.8M | col < u - 4; col += 2, indx += 2) |
517 | 60.8M | { |
518 | | |
519 | 60.8M | current = 4 * image[indx][3] + |
520 | 60.8M | 2 * (image[indx + u][3] + image[indx - u][3] + |
521 | 60.8M | image[indx + 1][3] + image[indx - 1][3]) + |
522 | 60.8M | image[indx + v][3] + image[indx - v][3] + image[indx + 2][3] + |
523 | 60.8M | image[indx - 2][3]; |
524 | | |
525 | 60.8M | image[indx][1] = CLIP( |
526 | 60.8M | ((16 - current) * ((image[indx - 1][1] + image[indx + 1][1]) / 2.0 + |
527 | 60.8M | image[indx][c] - |
528 | 60.8M | (image[indx + 2][c] + image[indx - 2][c]) / 2.0) + |
529 | 60.8M | current * ((image[indx - u][1] + image[indx + u][1]) / 2.0 + |
530 | 60.8M | image[indx][c] - |
531 | 60.8M | (image[indx + v][c] + image[indx - v][c]) / 2.0)) / |
532 | 60.8M | 16.0); |
533 | 60.8M | } |
534 | 3.07k | } |
535 | | |
536 | | void LibRaw::dcb_refinement() |
537 | 0 | { |
538 | 0 | int row, col, c, u = width, v = 2 * u, w = 3 * u, indx, current; |
539 | 0 | float f[5], g1, g2; |
540 | |
|
541 | 0 | for (row = 4; row < height - 4; row++) |
542 | 0 | for (col = 4 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col); |
543 | 0 | col < u - 4; col += 2, indx += 2) |
544 | 0 | { |
545 | |
|
546 | 0 | current = 4 * image[indx][3] + |
547 | 0 | 2 * (image[indx + u][3] + image[indx - u][3] + |
548 | 0 | image[indx + 1][3] + image[indx - 1][3]) + |
549 | 0 | image[indx + v][3] + image[indx - v][3] + image[indx - 2][3] + |
550 | 0 | image[indx + 2][3]; |
551 | |
|
552 | 0 | if (image[indx][c] > 1) |
553 | 0 | { |
554 | |
|
555 | 0 | f[0] = (float)(image[indx - u][1] + image[indx + u][1]) / |
556 | 0 | (2 * image[indx][c]); |
557 | |
|
558 | 0 | if (image[indx - v][c] > 0) |
559 | 0 | f[1] = 2 * (float)image[indx - u][1] / |
560 | 0 | (image[indx - v][c] + image[indx][c]); |
561 | 0 | else |
562 | 0 | f[1] = f[0]; |
563 | |
|
564 | 0 | if (image[indx - v][c] > 0) |
565 | 0 | f[2] = (float)(image[indx - u][1] + image[indx - w][1]) / |
566 | 0 | (2 * image[indx - v][c]); |
567 | 0 | else |
568 | 0 | f[2] = f[0]; |
569 | |
|
570 | 0 | if (image[indx + v][c] > 0) |
571 | 0 | f[3] = 2 * (float)image[indx + u][1] / |
572 | 0 | (image[indx + v][c] + image[indx][c]); |
573 | 0 | else |
574 | 0 | f[3] = f[0]; |
575 | |
|
576 | 0 | if (image[indx + v][c] > 0) |
577 | 0 | f[4] = (float)(image[indx + u][1] + image[indx + w][1]) / |
578 | 0 | (2 * image[indx + v][c]); |
579 | 0 | else |
580 | 0 | f[4] = f[0]; |
581 | |
|
582 | 0 | g1 = (5.f * f[0] + 3.f * f[1] + f[2] + 3.f * f[3] + f[4]) / 13.0f; |
583 | |
|
584 | 0 | f[0] = (float)(image[indx - 1][1] + image[indx + 1][1]) / |
585 | 0 | (2 * image[indx][c]); |
586 | |
|
587 | 0 | if (image[indx - 2][c] > 0) |
588 | 0 | f[1] = 2 * (float)image[indx - 1][1] / |
589 | 0 | (image[indx - 2][c] + image[indx][c]); |
590 | 0 | else |
591 | 0 | f[1] = f[0]; |
592 | |
|
593 | 0 | if (image[indx - 2][c] > 0) |
594 | 0 | f[2] = (float)(image[indx - 1][1] + image[indx - 3][1]) / |
595 | 0 | (2 * image[indx - 2][c]); |
596 | 0 | else |
597 | 0 | f[2] = f[0]; |
598 | |
|
599 | 0 | if (image[indx + 2][c] > 0) |
600 | 0 | f[3] = 2 * (float)image[indx + 1][1] / |
601 | 0 | (image[indx + 2][c] + image[indx][c]); |
602 | 0 | else |
603 | 0 | f[3] = f[0]; |
604 | |
|
605 | 0 | if (image[indx + 2][c] > 0) |
606 | 0 | f[4] = (float)(image[indx + 1][1] + image[indx + 3][1]) / |
607 | 0 | (2 * image[indx + 2][c]); |
608 | 0 | else |
609 | 0 | f[4] = f[0]; |
610 | |
|
611 | 0 | g2 = (5.f * f[0] + 3.f * f[1] + f[2] + 3.f * f[3] + f[4]) / 13.0f; |
612 | |
|
613 | 0 | image[indx][1] = CLIP((image[indx][c]) * |
614 | 0 | (current * g1 + (16 - current) * g2) / 16.0); |
615 | 0 | } |
616 | 0 | else |
617 | 0 | image[indx][1] = image[indx][c]; |
618 | | |
619 | | // get rid of overshooted pixels |
620 | |
|
621 | 0 | g1 = MIN( |
622 | 0 | image[indx + 1 + u][1], |
623 | 0 | MIN(image[indx + 1 - u][1], |
624 | 0 | MIN(image[indx - 1 + u][1], |
625 | 0 | MIN(image[indx - 1 - u][1], |
626 | 0 | MIN(image[indx - 1][1], |
627 | 0 | MIN(image[indx + 1][1], |
628 | 0 | MIN(image[indx - u][1], image[indx + u][1]))))))); |
629 | |
|
630 | 0 | g2 = MAX( |
631 | 0 | image[indx + 1 + u][1], |
632 | 0 | MAX(image[indx + 1 - u][1], |
633 | 0 | MAX(image[indx - 1 + u][1], |
634 | 0 | MAX(image[indx - 1 - u][1], |
635 | 0 | MAX(image[indx - 1][1], |
636 | 0 | MAX(image[indx + 1][1], |
637 | 0 | MAX(image[indx - u][1], image[indx + u][1]))))))); |
638 | |
|
639 | 0 | image[indx][1] = ushort(ULIM(image[indx][1], g2, g1)); |
640 | 0 | } |
641 | 0 | } |
642 | | |
643 | | // converts RGB to LCH colorspace and saves it to image3 |
644 | | void LibRaw::rgb_to_lch(double (*image2)[3]) |
645 | 13.0k | { |
646 | 13.0k | int indx; |
647 | 385M | for (indx = 0; indx < height * width; indx++) |
648 | 385M | { |
649 | | |
650 | 385M | image2[indx][0] = image[indx][0] + image[indx][1] + image[indx][2]; // L |
651 | 385M | image2[indx][1] = 1.732050808 * (image[indx][0] - image[indx][1]); // C |
652 | 385M | image2[indx][2] = |
653 | 385M | 2.0 * image[indx][2] - image[indx][0] - image[indx][1]; // H |
654 | 385M | } |
655 | 13.0k | } |
656 | | |
657 | | // converts LCH to RGB colorspace and saves it back to image |
658 | | void LibRaw::lch_to_rgb(double (*image2)[3]) |
659 | 13.0k | { |
660 | 13.0k | int indx; |
661 | 385M | for (indx = 0; indx < height * width; indx++) |
662 | 385M | { |
663 | | |
664 | 385M | image[indx][0] = CLIP(image2[indx][0] / 3.0 - image2[indx][2] / 6.0 + |
665 | 385M | image2[indx][1] / 3.464101615); |
666 | 385M | image[indx][1] = CLIP(image2[indx][0] / 3.0 - image2[indx][2] / 6.0 - |
667 | 385M | image2[indx][1] / 3.464101615); |
668 | 385M | image[indx][2] = CLIP(image2[indx][0] / 3.0 + image2[indx][2] / 3.0); |
669 | 385M | } |
670 | 13.0k | } |
671 | | |
672 | | // denoising using interpolated neighbours |
673 | | void LibRaw::fbdd_correction() |
674 | 16.3k | { |
675 | 16.3k | int row, col, c, u = width, indx; |
676 | | |
677 | 3.29M | for (row = 2; row < height - 2; row++) |
678 | 3.27M | { |
679 | 464M | for (col = 2, indx = row * width + col; col < width - 2; col++, indx++) |
680 | 461M | { |
681 | | |
682 | 461M | c = fcol(row, col); |
683 | | |
684 | 461M | image[indx][c] = |
685 | 461M | ULIM(image[indx][c], |
686 | 461M | MAX(image[indx - 1][c], |
687 | 461M | MAX(image[indx + 1][c], |
688 | 461M | MAX(image[indx - u][c], image[indx + u][c]))), |
689 | 461M | MIN(image[indx - 1][c], |
690 | 461M | MIN(image[indx + 1][c], |
691 | 461M | MIN(image[indx - u][c], image[indx + u][c])))); |
692 | 461M | } |
693 | 3.27M | } |
694 | 16.3k | } |
695 | | |
696 | | // corrects chroma noise |
697 | | void LibRaw::fbdd_correction2(double (*image2)[3]) |
698 | 26.0k | { |
699 | 26.0k | int indx, v = 2 * width; |
700 | 26.0k | int col, row; |
701 | 26.0k | double Co, Ho, ratio; |
702 | | |
703 | 4.80M | for (row = 6; row < height - 6; row++) |
704 | 4.77M | { |
705 | 671M | for (col = 6; col < width - 6; col++) |
706 | 666M | { |
707 | 666M | indx = row * width + col; |
708 | | |
709 | 666M | if (image2[indx][1] * image2[indx][2] != 0) |
710 | 344M | { |
711 | 344M | Co = (image2[indx + v][1] + image2[indx - v][1] + image2[indx - 2][1] + |
712 | 344M | image2[indx + 2][1] - |
713 | 344M | MAX(image2[indx - 2][1], |
714 | 344M | MAX(image2[indx + 2][1], |
715 | 344M | MAX(image2[indx - v][1], image2[indx + v][1]))) - |
716 | 344M | MIN(image2[indx - 2][1], |
717 | 344M | MIN(image2[indx + 2][1], |
718 | 344M | MIN(image2[indx - v][1], image2[indx + v][1])))) / |
719 | 344M | 2.0; |
720 | 344M | Ho = (image2[indx + v][2] + image2[indx - v][2] + image2[indx - 2][2] + |
721 | 344M | image2[indx + 2][2] - |
722 | 344M | MAX(image2[indx - 2][2], |
723 | 344M | MAX(image2[indx + 2][2], |
724 | 344M | MAX(image2[indx - v][2], image2[indx + v][2]))) - |
725 | 344M | MIN(image2[indx - 2][2], |
726 | 344M | MIN(image2[indx + 2][2], |
727 | 344M | MIN(image2[indx - v][2], image2[indx + v][2])))) / |
728 | 344M | 2.0; |
729 | 344M | ratio = sqrt((Co * Co + Ho * Ho) / (image2[indx][1] * image2[indx][1] + |
730 | 344M | image2[indx][2] * image2[indx][2])); |
731 | | |
732 | 344M | if (ratio < 0.85) |
733 | 39.0M | { |
734 | 39.0M | image2[indx][0] = |
735 | 39.0M | -(image2[indx][1] + image2[indx][2] - Co - Ho) + image2[indx][0]; |
736 | 39.0M | image2[indx][1] = Co; |
737 | 39.0M | image2[indx][2] = Ho; |
738 | 39.0M | } |
739 | 344M | } |
740 | 666M | } |
741 | 4.77M | } |
742 | 26.0k | } |
743 | | |
744 | | // Cubic Spline Interpolation by Li and Randhawa, modified by Jacek Gozdz and |
745 | | // Luis Sanz Rodríguez |
746 | | void LibRaw::fbdd_green() |
747 | 16.3k | { |
748 | 16.3k | int row, col, c, u = width, v = 2 * u, w = 3 * u, x = 4 * u, y = 5 * u, indx, |
749 | 16.3k | min, max; |
750 | 16.3k | float f[4], g[4]; |
751 | | |
752 | 3.19M | for (row = 5; row < height - 5; row++) |
753 | 3.17M | for (col = 5 + (FC(row, 1) & 1), indx = row * width + col, c = FC(row, col); |
754 | 217M | col < u - 5; col += 2, indx += 2) |
755 | 213M | { |
756 | | |
757 | 213M | f[0] = 1.0f / (1.0f + abs(image[indx - u][1] - image[indx - w][1]) + |
758 | 213M | abs(image[indx - w][1] - image[indx + y][1])); |
759 | 213M | f[1] = 1.0f / (1.0f + abs(image[indx + 1][1] - image[indx + 3][1]) + |
760 | 213M | abs(image[indx + 3][1] - image[indx - 5][1])); |
761 | 213M | f[2] = 1.0f / (1.0f + abs(image[indx - 1][1] - image[indx - 3][1]) + |
762 | 213M | abs(image[indx - 3][1] - image[indx + 5][1])); |
763 | 213M | f[3] = 1.0f / (1.0f + abs(image[indx + u][1] - image[indx + w][1]) + |
764 | 213M | abs(image[indx + w][1] - image[indx - y][1])); |
765 | | |
766 | 213M | g[0] = float(CLIP((23 * image[indx - u][1] + 23 * image[indx - w][1] + |
767 | 213M | 2 * image[indx - y][1] + |
768 | 213M | 8 * (image[indx - v][c] - image[indx - x][c]) + |
769 | 213M | 40 * (image[indx][c] - image[indx - v][c])) / |
770 | 213M | 48.0f)); |
771 | 213M | g[1] = float(CLIP((23 * image[indx + 1][1] + 23 * image[indx + 3][1] + |
772 | 213M | 2 * image[indx + 5][1] + |
773 | 213M | 8 * (image[indx + 2][c] - image[indx + 4][c]) + |
774 | 213M | 40 * (image[indx][c] - image[indx + 2][c])) / |
775 | 213M | 48.f)); |
776 | 213M | g[2] = float(CLIP((23 * image[indx - 1][1] + 23 * image[indx - 3][1] + |
777 | 213M | 2 * image[indx - 5][1] + |
778 | 213M | 8 * (image[indx - 2][c] - image[indx - 4][c]) + |
779 | 213M | 40 * (image[indx][c] - image[indx - 2][c])) / |
780 | 213M | 48.0f)); |
781 | 213M | g[3] = float(CLIP((23 * image[indx + u][1] + 23 * image[indx + w][1] + |
782 | 213M | 2 * image[indx + y][1] + |
783 | 213M | 8 * (image[indx + v][c] - image[indx + x][c]) + |
784 | 213M | 40 * (image[indx][c] - image[indx + v][c])) / |
785 | 213M | 48.0f)); |
786 | | |
787 | 213M | image[indx][1] = |
788 | 213M | CLIP((f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) / |
789 | 213M | (f[0] + f[1] + f[2] + f[3])); |
790 | | |
791 | 213M | min = MIN( |
792 | 213M | image[indx + 1 + u][1], |
793 | 213M | MIN(image[indx + 1 - u][1], |
794 | 213M | MIN(image[indx - 1 + u][1], |
795 | 213M | MIN(image[indx - 1 - u][1], |
796 | 213M | MIN(image[indx - 1][1], |
797 | 213M | MIN(image[indx + 1][1], |
798 | 213M | MIN(image[indx - u][1], image[indx + u][1]))))))); |
799 | | |
800 | 213M | max = MAX( |
801 | 213M | image[indx + 1 + u][1], |
802 | 213M | MAX(image[indx + 1 - u][1], |
803 | 213M | MAX(image[indx - 1 + u][1], |
804 | 213M | MAX(image[indx - 1 - u][1], |
805 | 213M | MAX(image[indx - 1][1], |
806 | 213M | MAX(image[indx + 1][1], |
807 | 213M | MAX(image[indx - u][1], image[indx + u][1]))))))); |
808 | | |
809 | 213M | image[indx][1] = ULIM(image[indx][1], max, min); |
810 | 213M | } |
811 | 16.3k | } |
812 | | |
813 | | // FBDD (Fake Before Demosaicing Denoising) |
814 | | void LibRaw::fbdd(int noiserd) |
815 | 16.3k | { |
816 | 16.3k | double(*image2)[3]; |
817 | | // safety net: disable for 4-color bayer or full-color images |
818 | 16.3k | if (colors != 3 || !filters) |
819 | 0 | return; |
820 | 16.3k | image2 = (double(*)[3])calloc(width * height, sizeof *image2); |
821 | | |
822 | 16.3k | border_interpolate(4); |
823 | | |
824 | 16.3k | if (noiserd > 1) |
825 | 13.0k | { |
826 | 13.0k | fbdd_green(); |
827 | | // dcb_color_full(image2); |
828 | 13.0k | dcb_color_full(); |
829 | 13.0k | fbdd_correction(); |
830 | | |
831 | 13.0k | dcb_color(); |
832 | 13.0k | rgb_to_lch(image2); |
833 | 13.0k | fbdd_correction2(image2); |
834 | 13.0k | fbdd_correction2(image2); |
835 | 13.0k | lch_to_rgb(image2); |
836 | 13.0k | } |
837 | 3.32k | else |
838 | 3.32k | { |
839 | 3.32k | fbdd_green(); |
840 | | // dcb_color_full(image2); |
841 | 3.32k | dcb_color_full(); |
842 | 3.32k | fbdd_correction(); |
843 | 3.32k | } |
844 | | |
845 | 16.3k | free(image2); |
846 | 16.3k | } |
847 | | |
848 | | // DCB demosaicing main routine |
849 | | void LibRaw::dcb(int iterations, int dcb_enhance) |
850 | 3.07k | { |
851 | | |
852 | 3.07k | int i = 1; |
853 | | |
854 | 3.07k | float(*image2)[3]; |
855 | 3.07k | image2 = (float(*)[3])calloc(width * height, sizeof *image2); |
856 | | |
857 | 3.07k | float(*image3)[3]; |
858 | 3.07k | image3 = (float(*)[3])calloc(width * height, sizeof *image3); |
859 | | |
860 | 3.07k | border_interpolate(6); |
861 | | |
862 | 3.07k | dcb_hor(image2); |
863 | 3.07k | dcb_color2(image2); |
864 | | |
865 | 3.07k | dcb_ver(image3); |
866 | 3.07k | dcb_color3(image3); |
867 | | |
868 | 3.07k | dcb_decide(image2, image3); |
869 | | |
870 | 3.07k | free(image3); |
871 | | |
872 | 3.07k | dcb_copy_to_buffer(image2); |
873 | | |
874 | 3.07k | while (i <= iterations) |
875 | 0 | { |
876 | 0 | dcb_nyquist(); |
877 | 0 | dcb_nyquist(); |
878 | 0 | dcb_nyquist(); |
879 | 0 | dcb_map(); |
880 | 0 | dcb_correction(); |
881 | 0 | i++; |
882 | 0 | } |
883 | | |
884 | 3.07k | dcb_color(); |
885 | 3.07k | dcb_pp(); |
886 | | |
887 | 3.07k | dcb_map(); |
888 | 3.07k | dcb_correction2(); |
889 | | |
890 | 3.07k | dcb_map(); |
891 | 3.07k | dcb_correction(); |
892 | | |
893 | 3.07k | dcb_map(); |
894 | 3.07k | dcb_correction(); |
895 | | |
896 | 3.07k | dcb_map(); |
897 | 3.07k | dcb_correction(); |
898 | | |
899 | 3.07k | dcb_map(); |
900 | 3.07k | dcb_restore_from_buffer(image2); |
901 | 3.07k | dcb_color(); |
902 | | |
903 | 3.07k | if (dcb_enhance) |
904 | 0 | { |
905 | 0 | dcb_refinement(); |
906 | | // dcb_color_full(image2); |
907 | 0 | dcb_color_full(); |
908 | 0 | } |
909 | | |
910 | 3.07k | free(image2); |
911 | 3.07k | } |