/src/libraw/src/demosaic/dcb_demosaic.cpp
Line | Count | Source (jump to first uncovered line) |
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 | 0 | { |
47 | 0 | int row, col, u = width, indx; |
48 | |
|
49 | 0 | for (row = 2; row < height - 2; row++) |
50 | 0 | for (col = 2 + (FC(row, 2) & 1), indx = row * width + col; col < u - 2; |
51 | 0 | col += 2, indx += 2) |
52 | 0 | { |
53 | |
|
54 | 0 | image3[indx][1] = float(CLIP((image[indx + u][1] + image[indx - u][1]) / 2.0)); |
55 | 0 | } |
56 | 0 | } |
57 | | |
58 | | // interpolates green horizontally and saves it to image2 |
59 | | void LibRaw::dcb_hor(float (*image2)[3]) |
60 | 0 | { |
61 | 0 | int row, col, u = width, indx; |
62 | |
|
63 | 0 | for (row = 2; row < height - 2; row++) |
64 | 0 | for (col = 2 + (FC(row, 2) & 1), indx = row * width + col; col < u - 2; |
65 | 0 | col += 2, indx += 2) |
66 | 0 | { |
67 | |
|
68 | 0 | image2[indx][1] = float(CLIP((image[indx + 1][1] + image[indx - 1][1]) / 2.0)); |
69 | 0 | } |
70 | 0 | } |
71 | | |
72 | | // missing colors are interpolated |
73 | | void LibRaw::dcb_color() |
74 | 0 | { |
75 | 0 | int row, col, c, d, u = width, indx; |
76 | |
|
77 | 0 | for (row = 1; row < height - 1; row++) |
78 | 0 | for (col = 1 + (FC(row, 1) & 1), indx = row * width + col, |
79 | 0 | c = 2 - FC(row, col); |
80 | 0 | col < u - 1; col += 2, indx += 2) |
81 | 0 | { |
82 | |
|
83 | 0 | image[indx][c] = CLIP((4 * image[indx][1] - image[indx + u + 1][1] - |
84 | 0 | image[indx + u - 1][1] - image[indx - u + 1][1] - |
85 | 0 | image[indx - u - 1][1] + image[indx + u + 1][c] + |
86 | 0 | image[indx + u - 1][c] + image[indx - u + 1][c] + |
87 | 0 | image[indx - u - 1][c]) / |
88 | 0 | 4.0); |
89 | 0 | } |
90 | |
|
91 | 0 | for (row = 1; row < height - 1; row++) |
92 | 0 | for (col = 1 + (FC(row, 2) & 1), indx = row * width + col, |
93 | 0 | c = FC(row, col + 1), d = 2 - c; |
94 | 0 | col < width - 1; col += 2, indx += 2) |
95 | 0 | { |
96 | |
|
97 | 0 | image[indx][c] = |
98 | 0 | CLIP((2 * image[indx][1] - image[indx + 1][1] - image[indx - 1][1] + |
99 | 0 | image[indx + 1][c] + image[indx - 1][c]) / |
100 | 0 | 2.0); |
101 | 0 | image[indx][d] = |
102 | 0 | CLIP((2 * image[indx][1] - image[indx + u][1] - image[indx - u][1] + |
103 | 0 | image[indx + u][d] + image[indx - u][d]) / |
104 | 0 | 2.0); |
105 | 0 | } |
106 | 0 | } |
107 | | |
108 | | // missing R and B are interpolated horizontally and saved in image2 |
109 | | void LibRaw::dcb_color2(float (*image2)[3]) |
110 | 0 | { |
111 | 0 | int row, col, c, d, u = width, indx; |
112 | |
|
113 | 0 | for (row = 1; row < height - 1; row++) |
114 | 0 | for (col = 1 + (FC(row, 1) & 1), indx = row * width + col, |
115 | 0 | c = 2 - FC(row, col); |
116 | 0 | col < u - 1; col += 2, indx += 2) |
117 | 0 | { |
118 | |
|
119 | 0 | image2[indx][c] = |
120 | 0 | float( |
121 | 0 | CLIP((4 * image2[indx][1] - image2[indx + u + 1][1] - |
122 | 0 | image2[indx + u - 1][1] - image2[indx - u + 1][1] - |
123 | 0 | image2[indx - u - 1][1] + image[indx + u + 1][c] + |
124 | 0 | image[indx + u - 1][c] + image[indx - u + 1][c] + |
125 | 0 | image[indx - u - 1][c]) / |
126 | 0 | 4.0) |
127 | 0 | ); |
128 | 0 | } |
129 | |
|
130 | 0 | for (row = 1; row < height - 1; row++) |
131 | 0 | for (col = 1 + (FC(row, 2) & 1), indx = row * width + col, |
132 | 0 | c = FC(row, col + 1), d = 2 - c; |
133 | 0 | col < width - 1; col += 2, indx += 2) |
134 | 0 | { |
135 | |
|
136 | 0 | image2[indx][c] = float(CLIP((image[indx + 1][c] + image[indx - 1][c]) / 2.0)); |
137 | 0 | image2[indx][d] = |
138 | 0 | float(CLIP((2 * image2[indx][1] - image2[indx + u][1] - |
139 | 0 | image2[indx - u][1] + image[indx + u][d] + image[indx - u][d]) / |
140 | 0 | 2.0)); |
141 | 0 | } |
142 | 0 | } |
143 | | |
144 | | // missing R and B are interpolated vertically and saved in image3 |
145 | | void LibRaw::dcb_color3(float (*image3)[3]) |
146 | 0 | { |
147 | 0 | int row, col, c, d, u = width, indx; |
148 | |
|
149 | 0 | for (row = 1; row < height - 1; row++) |
150 | 0 | for (col = 1 + (FC(row, 1) & 1), indx = row * width + col, |
151 | 0 | c = 2 - FC(row, col); |
152 | 0 | col < u - 1; col += 2, indx += 2) |
153 | 0 | { |
154 | |
|
155 | 0 | image3[indx][c] = |
156 | 0 | float( |
157 | 0 | CLIP((4 * image3[indx][1] - image3[indx + u + 1][1] - |
158 | 0 | image3[indx + u - 1][1] - image3[indx - u + 1][1] - |
159 | 0 | image3[indx - u - 1][1] + image[indx + u + 1][c] + |
160 | 0 | image[indx + u - 1][c] + image[indx - u + 1][c] + |
161 | 0 | image[indx - u - 1][c]) / |
162 | 0 | 4.0) |
163 | 0 | ); |
164 | 0 | } |
165 | |
|
166 | 0 | for (row = 1; row < height - 1; row++) |
167 | 0 | for (col = 1 + (FC(row, 2) & 1), indx = row * width + col, |
168 | 0 | c = FC(row, col + 1), d = 2 - c; |
169 | 0 | col < width - 1; col += 2, indx += 2) |
170 | 0 | { |
171 | |
|
172 | 0 | image3[indx][c] = |
173 | 0 | float( |
174 | 0 | CLIP((2 * image3[indx][1] - image3[indx + 1][1] - |
175 | 0 | image3[indx - 1][1] + image[indx + 1][c] + image[indx - 1][c]) / |
176 | 0 | 2.0) |
177 | 0 | ); |
178 | 0 | image3[indx][d] = float(CLIP((image[indx + u][d] + image[indx - u][d]) / 2.0)); |
179 | 0 | } |
180 | 0 | } |
181 | | |
182 | | // decides the primary green interpolation direction |
183 | | void LibRaw::dcb_decide(float (*image2)[3], float (*image3)[3]) |
184 | 0 | { |
185 | 0 | int row, col, c, d, u = width, v = 2 * u, indx; |
186 | 0 | float current, current2, current3; |
187 | |
|
188 | 0 | for (row = 2; row < height - 2; row++) |
189 | 0 | for (col = 2 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col); |
190 | 0 | col < u - 2; col += 2, indx += 2) |
191 | 0 | { |
192 | |
|
193 | 0 | d = ABS(c - 2); |
194 | |
|
195 | 0 | current = float(MAX(image[indx + v][c], |
196 | 0 | MAX(image[indx - v][c], |
197 | 0 | MAX(image[indx - 2][c], image[indx + 2][c]))) - |
198 | 0 | MIN(image[indx + v][c], |
199 | 0 | MIN(image[indx - v][c], |
200 | 0 | MIN(image[indx - 2][c], image[indx + 2][c]))) + |
201 | 0 | MAX(image[indx + 1 + u][d], |
202 | 0 | MAX(image[indx + 1 - u][d], |
203 | 0 | MAX(image[indx - 1 + u][d], image[indx - 1 - u][d]))) - |
204 | 0 | MIN(image[indx + 1 + u][d], |
205 | 0 | MIN(image[indx + 1 - u][d], |
206 | 0 | MIN(image[indx - 1 + u][d], image[indx - 1 - u][d])))); |
207 | |
|
208 | 0 | current2 = |
209 | 0 | float( |
210 | 0 | MAX(image2[indx + v][d], |
211 | 0 | MAX(image2[indx - v][d], |
212 | 0 | MAX(image2[indx - 2][d], image2[indx + 2][d]))) - |
213 | 0 | MIN(image2[indx + v][d], |
214 | 0 | MIN(image2[indx - v][d], |
215 | 0 | MIN(image2[indx - 2][d], image2[indx + 2][d]))) + |
216 | 0 | MAX(image2[indx + 1 + u][c], |
217 | 0 | MAX(image2[indx + 1 - u][c], |
218 | 0 | MAX(image2[indx - 1 + u][c], image2[indx - 1 - u][c]))) - |
219 | 0 | MIN(image2[indx + 1 + u][c], |
220 | 0 | MIN(image2[indx + 1 - u][c], |
221 | 0 | MIN(image2[indx - 1 + u][c], image2[indx - 1 - u][c]))) |
222 | 0 | ); |
223 | |
|
224 | 0 | current3 = |
225 | 0 | float( |
226 | 0 | MAX(image3[indx + v][d], |
227 | 0 | MAX(image3[indx - v][d], |
228 | 0 | MAX(image3[indx - 2][d], image3[indx + 2][d]))) - |
229 | 0 | MIN(image3[indx + v][d], |
230 | 0 | MIN(image3[indx - v][d], |
231 | 0 | MIN(image3[indx - 2][d], image3[indx + 2][d]))) + |
232 | 0 | MAX(image3[indx + 1 + u][c], |
233 | 0 | MAX(image3[indx + 1 - u][c], |
234 | 0 | MAX(image3[indx - 1 + u][c], image3[indx - 1 - u][c]))) - |
235 | 0 | MIN(image3[indx + 1 + u][c], |
236 | 0 | MIN(image3[indx + 1 - u][c], |
237 | 0 | MIN(image3[indx - 1 + u][c], image3[indx - 1 - u][c]))) |
238 | 0 | ); |
239 | |
|
240 | 0 | if (ABS(current - current2) < ABS(current - current3)) |
241 | 0 | image[indx][1] = ushort(image2[indx][1]); |
242 | 0 | else |
243 | 0 | image[indx][1] = ushort(image3[indx][1]); |
244 | 0 | } |
245 | 0 | } |
246 | | |
247 | | // saves red and blue in image2 |
248 | | void LibRaw::dcb_copy_to_buffer(float (*image2)[3]) |
249 | 0 | { |
250 | 0 | int indx; |
251 | |
|
252 | 0 | for (indx = 0; indx < height * width; indx++) |
253 | 0 | { |
254 | 0 | image2[indx][0] = image[indx][0]; // R |
255 | 0 | image2[indx][2] = image[indx][2]; // B |
256 | 0 | } |
257 | 0 | } |
258 | | |
259 | | // restores red and blue from image2 |
260 | | void LibRaw::dcb_restore_from_buffer(float (*image2)[3]) |
261 | 0 | { |
262 | 0 | int indx; |
263 | |
|
264 | 0 | for (indx = 0; indx < height * width; indx++) |
265 | 0 | { |
266 | 0 | image[indx][0] = ushort(image2[indx][0]); // R |
267 | 0 | image[indx][2] = ushort(image2[indx][2]); // B |
268 | 0 | } |
269 | 0 | } |
270 | | |
271 | | // R and B smoothing using green contrast, all pixels except 2 pixel wide border |
272 | | void LibRaw::dcb_pp() |
273 | 0 | { |
274 | 0 | int g1, r1, b1, u = width, indx, row, col; |
275 | |
|
276 | 0 | for (row = 2; row < height - 2; row++) |
277 | 0 | for (col = 2, indx = row * u + col; col < width - 2; col++, indx++) |
278 | 0 | { |
279 | |
|
280 | 0 | r1 = int((image[indx - 1][0] + image[indx + 1][0] + image[indx - u][0] + |
281 | 0 | image[indx + u][0] + image[indx - u - 1][0] + |
282 | 0 | image[indx + u + 1][0] + image[indx - u + 1][0] + |
283 | 0 | image[indx + u - 1][0]) / |
284 | 0 | 8.0f); |
285 | 0 | g1 = int((image[indx - 1][1] + image[indx + 1][1] + image[indx - u][1] + |
286 | 0 | image[indx + u][1] + image[indx - u - 1][1] + |
287 | 0 | image[indx + u + 1][1] + image[indx - u + 1][1] + |
288 | 0 | image[indx + u - 1][1]) / |
289 | 0 | 8.0f); |
290 | 0 | b1 = int((image[indx - 1][2] + image[indx + 1][2] + image[indx - u][2] + |
291 | 0 | image[indx + u][2] + image[indx - u - 1][2] + |
292 | 0 | image[indx + u + 1][2] + image[indx - u + 1][2] + |
293 | 0 | image[indx + u - 1][2]) / |
294 | 0 | 8.0f); |
295 | |
|
296 | 0 | image[indx][0] = CLIP(r1 + (image[indx][1] - g1)); |
297 | 0 | image[indx][2] = CLIP(b1 + (image[indx][1] - g1)); |
298 | 0 | } |
299 | 0 | } |
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 | 0 | { |
325 | 0 | int row, col, c, d, u = width, w = 3 * u, indx, g1, g2; |
326 | 0 | float f[4], g[4], (*chroma)[2]; |
327 | |
|
328 | 0 | chroma = (float(*)[2])calloc(width * height, sizeof *chroma); |
329 | |
|
330 | 0 | for (row = 1; row < height - 1; row++) |
331 | 0 | for (col = 1 + (FC(row, 1) & 1), indx = row * width + col, c = FC(row, col), |
332 | 0 | d = c / 2; |
333 | 0 | col < u - 1; col += 2, indx += 2) |
334 | 0 | chroma[indx][d] = float(image[indx][c] - image[indx][1]); |
335 | |
|
336 | 0 | for (row = 3; row < height - 3; row++) |
337 | 0 | for (col = 3 + (FC(row, 1) & 1), indx = row * width + col, |
338 | 0 | c = 1 - FC(row, col) / 2, d = 1 - c; |
339 | 0 | col < u - 3; col += 2, indx += 2) |
340 | 0 | { |
341 | 0 | f[0] = 1.0f / |
342 | 0 | (float)(1.0 + |
343 | 0 | fabsf(chroma[indx - u - 1][c] - chroma[indx + u + 1][c]) + |
344 | 0 | fabsf(chroma[indx - u - 1][c] - chroma[indx - w - 3][c]) + |
345 | 0 | fabsf(chroma[indx + u + 1][c] - chroma[indx - w - 3][c])); |
346 | 0 | f[1] = 1.0f / |
347 | 0 | (float)(1.0 + |
348 | 0 | fabsf(chroma[indx - u + 1][c] - chroma[indx + u - 1][c]) + |
349 | 0 | fabsf(chroma[indx - u + 1][c] - chroma[indx - w + 3][c]) + |
350 | 0 | fabsf(chroma[indx + u - 1][c] - chroma[indx - w + 3][c])); |
351 | 0 | f[2] = 1.0f / |
352 | 0 | (float)(1.0 + |
353 | 0 | fabsf(chroma[indx + u - 1][c] - chroma[indx - u + 1][c]) + |
354 | 0 | fabsf(chroma[indx + u - 1][c] - chroma[indx + w + 3][c]) + |
355 | 0 | fabsf(chroma[indx - u + 1][c] - chroma[indx + w - 3][c])); |
356 | 0 | f[3] = 1.0f / |
357 | 0 | (float)(1.0 + |
358 | 0 | fabsf(chroma[indx + u + 1][c] - chroma[indx - u - 1][c]) + |
359 | 0 | fabsf(chroma[indx + u + 1][c] - chroma[indx + w - 3][c]) + |
360 | 0 | fabsf(chroma[indx - u - 1][c] - chroma[indx + w + 3][c])); |
361 | 0 | g[0] = 1.325f * chroma[indx - u - 1][c] - 0.175f * chroma[indx - w - 3][c] - |
362 | 0 | 0.075f * chroma[indx - w - 1][c] - 0.075f * chroma[indx - u - 3][c]; |
363 | 0 | g[1] = 1.325f * chroma[indx - u + 1][c] - 0.175f * chroma[indx - w + 3][c] - |
364 | 0 | 0.075f * chroma[indx - w + 1][c] - 0.075f * chroma[indx - u + 3][c]; |
365 | 0 | g[2] = 1.325f * chroma[indx + u - 1][c] - 0.175f * chroma[indx + w - 3][c] - |
366 | 0 | 0.075f * chroma[indx + w - 1][c] - 0.075f * chroma[indx + u - 3][c]; |
367 | 0 | g[3] = 1.325f * chroma[indx + u + 1][c] - 0.175f * chroma[indx + w + 3][c] - |
368 | 0 | 0.075f * chroma[indx + w + 1][c] - 0.075f * chroma[indx + u + 3][c]; |
369 | 0 | chroma[indx][c] = |
370 | 0 | (f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) / |
371 | 0 | (f[0] + f[1] + f[2] + f[3]); |
372 | 0 | } |
373 | 0 | for (row = 3; row < height - 3; row++) |
374 | 0 | for (col = 3 + (FC(row, 2) & 1), indx = row * width + col, |
375 | 0 | c = FC(row, col + 1) / 2; |
376 | 0 | col < u - 3; col += 2, indx += 2) |
377 | 0 | for (d = 0; d <= 1; c = 1 - c, d++) |
378 | 0 | { |
379 | 0 | f[0] = 1.0f / |
380 | 0 | (float)(1.0f + fabsf(chroma[indx - u][c] - chroma[indx + u][c]) + |
381 | 0 | fabsf(chroma[indx - u][c] - chroma[indx - w][c]) + |
382 | 0 | fabsf(chroma[indx + u][c] - chroma[indx - w][c])); |
383 | 0 | f[1] = 1.0f / |
384 | 0 | (float)(1.0f + fabsf(chroma[indx + 1][c] - chroma[indx - 1][c]) + |
385 | 0 | fabsf(chroma[indx + 1][c] - chroma[indx + 3][c]) + |
386 | 0 | fabsf(chroma[indx - 1][c] - chroma[indx + 3][c])); |
387 | 0 | f[2] = 1.0f / |
388 | 0 | (float)(1.0 + fabs(chroma[indx - 1][c] - chroma[indx + 1][c]) + |
389 | 0 | fabs(chroma[indx - 1][c] - chroma[indx - 3][c]) + |
390 | 0 | fabs(chroma[indx + 1][c] - chroma[indx - 3][c])); |
391 | 0 | f[3] = 1.0f / |
392 | 0 | (float)(1.0 + fabs(chroma[indx + u][c] - chroma[indx - u][c]) + |
393 | 0 | fabs(chroma[indx + u][c] - chroma[indx + w][c]) + |
394 | 0 | fabs(chroma[indx - u][c] - chroma[indx + w][c])); |
395 | |
|
396 | 0 | g[0] = 0.875f * chroma[indx - u][c] + 0.125f * chroma[indx - w][c]; |
397 | 0 | g[1] = 0.875f * chroma[indx + 1][c] + 0.125f * chroma[indx + 3][c]; |
398 | 0 | g[2] = 0.875f * chroma[indx - 1][c] + 0.125f * chroma[indx - 3][c]; |
399 | 0 | g[3] = 0.875f * chroma[indx + u][c] + 0.125f * chroma[indx + w][c]; |
400 | |
|
401 | 0 | chroma[indx][c] = |
402 | 0 | (f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) / |
403 | 0 | (f[0] + f[1] + f[2] + f[3]); |
404 | 0 | } |
405 | |
|
406 | 0 | for (row = 6; row < height - 6; row++) |
407 | 0 | for (col = 6, indx = row * width + col; col < width - 6; col++, indx++) |
408 | 0 | { |
409 | 0 | image[indx][0] = CLIP(chroma[indx][0] + image[indx][1]); |
410 | 0 | image[indx][2] = CLIP(chroma[indx][1] + image[indx][1]); |
411 | |
|
412 | 0 | g1 = MIN( |
413 | 0 | image[indx + 1 + u][0], |
414 | 0 | MIN(image[indx + 1 - u][0], |
415 | 0 | MIN(image[indx - 1 + u][0], |
416 | 0 | MIN(image[indx - 1 - u][0], |
417 | 0 | MIN(image[indx - 1][0], |
418 | 0 | MIN(image[indx + 1][0], |
419 | 0 | MIN(image[indx - u][0], image[indx + u][0]))))))); |
420 | |
|
421 | 0 | g2 = MAX( |
422 | 0 | image[indx + 1 + u][0], |
423 | 0 | MAX(image[indx + 1 - u][0], |
424 | 0 | MAX(image[indx - 1 + u][0], |
425 | 0 | MAX(image[indx - 1 - u][0], |
426 | 0 | MAX(image[indx - 1][0], |
427 | 0 | MAX(image[indx + 1][0], |
428 | 0 | MAX(image[indx - u][0], image[indx + u][0]))))))); |
429 | |
|
430 | 0 | image[indx][0] = ULIM(image[indx][0], g2, g1); |
431 | |
|
432 | 0 | g1 = MIN( |
433 | 0 | image[indx + 1 + u][2], |
434 | 0 | MIN(image[indx + 1 - u][2], |
435 | 0 | MIN(image[indx - 1 + u][2], |
436 | 0 | MIN(image[indx - 1 - u][2], |
437 | 0 | MIN(image[indx - 1][2], |
438 | 0 | MIN(image[indx + 1][2], |
439 | 0 | MIN(image[indx - u][2], image[indx + u][2]))))))); |
440 | |
|
441 | 0 | g2 = MAX( |
442 | 0 | image[indx + 1 + u][2], |
443 | 0 | MAX(image[indx + 1 - u][2], |
444 | 0 | MAX(image[indx - 1 + u][2], |
445 | 0 | MAX(image[indx - 1 - u][2], |
446 | 0 | MAX(image[indx - 1][2], |
447 | 0 | MAX(image[indx + 1][2], |
448 | 0 | MAX(image[indx - u][2], image[indx + u][2]))))))); |
449 | |
|
450 | 0 | image[indx][2] = ULIM(image[indx][2], g2, g1); |
451 | 0 | } |
452 | |
|
453 | 0 | free(chroma); |
454 | 0 | } |
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 | 0 | { |
461 | 0 | int row, col, u = width, indx; |
462 | |
|
463 | 0 | for (row = 1; row < height - 1; row++) |
464 | 0 | { |
465 | 0 | for (col = 1, indx = row * width + col; col < width - 1; col++, indx++) |
466 | 0 | { |
467 | |
|
468 | 0 | if (image[indx][1] > (image[indx - 1][1] + image[indx + 1][1] + |
469 | 0 | image[indx - u][1] + image[indx + u][1]) / |
470 | 0 | 4.0) |
471 | 0 | image[indx][3] = ((MIN(image[indx - 1][1], image[indx + 1][1]) + |
472 | 0 | image[indx - 1][1] + image[indx + 1][1]) < |
473 | 0 | (MIN(image[indx - u][1], image[indx + u][1]) + |
474 | 0 | image[indx - u][1] + image[indx + u][1])); |
475 | 0 | else |
476 | 0 | image[indx][3] = ((MAX(image[indx - 1][1], image[indx + 1][1]) + |
477 | 0 | image[indx - 1][1] + image[indx + 1][1]) > |
478 | 0 | (MAX(image[indx - u][1], image[indx + u][1]) + |
479 | 0 | image[indx - u][1] + image[indx + u][1])); |
480 | 0 | } |
481 | 0 | } |
482 | 0 | } |
483 | | |
484 | | // interpolated green pixels are corrected using the map |
485 | | void LibRaw::dcb_correction() |
486 | 0 | { |
487 | 0 | int current, row, col, u = width, v = 2 * u, indx; |
488 | |
|
489 | 0 | for (row = 2; row < height - 2; row++) |
490 | 0 | for (col = 2 + (FC(row, 2) & 1), indx = row * width + col; col < u - 2; |
491 | 0 | col += 2, indx += 2) |
492 | 0 | { |
493 | |
|
494 | 0 | current = 4 * image[indx][3] + |
495 | 0 | 2 * (image[indx + u][3] + image[indx - u][3] + |
496 | 0 | image[indx + 1][3] + image[indx - 1][3]) + |
497 | 0 | image[indx + v][3] + image[indx - v][3] + image[indx + 2][3] + |
498 | 0 | image[indx - 2][3]; |
499 | |
|
500 | 0 | image[indx][1] = |
501 | 0 | ushort( |
502 | 0 | ((16 - current) * (image[indx - 1][1] + image[indx + 1][1]) / 2.0 + |
503 | 0 | current * (image[indx - u][1] + image[indx + u][1]) / 2.0) / |
504 | 0 | 16.0f); |
505 | 0 | } |
506 | 0 | } |
507 | | |
508 | | // interpolated green pixels are corrected using the map |
509 | | // with contrast correction |
510 | | void LibRaw::dcb_correction2() |
511 | 0 | { |
512 | 0 | int current, row, col, c, u = width, v = 2 * u, indx; |
513 | |
|
514 | 0 | for (row = 4; row < height - 4; row++) |
515 | 0 | for (col = 4 + (FC(row, 2) & 1), indx = row * width + col, c = FC(row, col); |
516 | 0 | col < u - 4; col += 2, indx += 2) |
517 | 0 | { |
518 | |
|
519 | 0 | current = 4 * image[indx][3] + |
520 | 0 | 2 * (image[indx + u][3] + image[indx - u][3] + |
521 | 0 | image[indx + 1][3] + image[indx - 1][3]) + |
522 | 0 | image[indx + v][3] + image[indx - v][3] + image[indx + 2][3] + |
523 | 0 | image[indx - 2][3]; |
524 | |
|
525 | 0 | image[indx][1] = CLIP( |
526 | 0 | ((16 - current) * ((image[indx - 1][1] + image[indx + 1][1]) / 2.0 + |
527 | 0 | image[indx][c] - |
528 | 0 | (image[indx + 2][c] + image[indx - 2][c]) / 2.0) + |
529 | 0 | current * ((image[indx - u][1] + image[indx + u][1]) / 2.0 + |
530 | 0 | image[indx][c] - |
531 | 0 | (image[indx + v][c] + image[indx - v][c]) / 2.0)) / |
532 | 0 | 16.0); |
533 | 0 | } |
534 | 0 | } |
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 | 0 | { |
646 | 0 | int indx; |
647 | 0 | for (indx = 0; indx < height * width; indx++) |
648 | 0 | { |
649 | |
|
650 | 0 | image2[indx][0] = image[indx][0] + image[indx][1] + image[indx][2]; // L |
651 | 0 | image2[indx][1] = 1.732050808 * (image[indx][0] - image[indx][1]); // C |
652 | 0 | image2[indx][2] = |
653 | 0 | 2.0 * image[indx][2] - image[indx][0] - image[indx][1]; // H |
654 | 0 | } |
655 | 0 | } |
656 | | |
657 | | // converts LCH to RGB colorspace and saves it back to image |
658 | | void LibRaw::lch_to_rgb(double (*image2)[3]) |
659 | 0 | { |
660 | 0 | int indx; |
661 | 0 | for (indx = 0; indx < height * width; indx++) |
662 | 0 | { |
663 | |
|
664 | 0 | image[indx][0] = CLIP(image2[indx][0] / 3.0 - image2[indx][2] / 6.0 + |
665 | 0 | image2[indx][1] / 3.464101615); |
666 | 0 | image[indx][1] = CLIP(image2[indx][0] / 3.0 - image2[indx][2] / 6.0 - |
667 | 0 | image2[indx][1] / 3.464101615); |
668 | 0 | image[indx][2] = CLIP(image2[indx][0] / 3.0 + image2[indx][2] / 3.0); |
669 | 0 | } |
670 | 0 | } |
671 | | |
672 | | // denoising using interpolated neighbours |
673 | | void LibRaw::fbdd_correction() |
674 | 0 | { |
675 | 0 | int row, col, c, u = width, indx; |
676 | |
|
677 | 0 | for (row = 2; row < height - 2; row++) |
678 | 0 | { |
679 | 0 | for (col = 2, indx = row * width + col; col < width - 2; col++, indx++) |
680 | 0 | { |
681 | |
|
682 | 0 | c = fcol(row, col); |
683 | |
|
684 | 0 | image[indx][c] = |
685 | 0 | ULIM(image[indx][c], |
686 | 0 | MAX(image[indx - 1][c], |
687 | 0 | MAX(image[indx + 1][c], |
688 | 0 | MAX(image[indx - u][c], image[indx + u][c]))), |
689 | 0 | MIN(image[indx - 1][c], |
690 | 0 | MIN(image[indx + 1][c], |
691 | 0 | MIN(image[indx - u][c], image[indx + u][c])))); |
692 | 0 | } |
693 | 0 | } |
694 | 0 | } |
695 | | |
696 | | // corrects chroma noise |
697 | | void LibRaw::fbdd_correction2(double (*image2)[3]) |
698 | 0 | { |
699 | 0 | int indx, v = 2 * width; |
700 | 0 | int col, row; |
701 | 0 | double Co, Ho, ratio; |
702 | |
|
703 | 0 | for (row = 6; row < height - 6; row++) |
704 | 0 | { |
705 | 0 | for (col = 6; col < width - 6; col++) |
706 | 0 | { |
707 | 0 | indx = row * width + col; |
708 | |
|
709 | 0 | if (image2[indx][1] * image2[indx][2] != 0) |
710 | 0 | { |
711 | 0 | Co = (image2[indx + v][1] + image2[indx - v][1] + image2[indx - 2][1] + |
712 | 0 | image2[indx + 2][1] - |
713 | 0 | MAX(image2[indx - 2][1], |
714 | 0 | MAX(image2[indx + 2][1], |
715 | 0 | MAX(image2[indx - v][1], image2[indx + v][1]))) - |
716 | 0 | MIN(image2[indx - 2][1], |
717 | 0 | MIN(image2[indx + 2][1], |
718 | 0 | MIN(image2[indx - v][1], image2[indx + v][1])))) / |
719 | 0 | 2.0; |
720 | 0 | Ho = (image2[indx + v][2] + image2[indx - v][2] + image2[indx - 2][2] + |
721 | 0 | image2[indx + 2][2] - |
722 | 0 | MAX(image2[indx - 2][2], |
723 | 0 | MAX(image2[indx + 2][2], |
724 | 0 | MAX(image2[indx - v][2], image2[indx + v][2]))) - |
725 | 0 | MIN(image2[indx - 2][2], |
726 | 0 | MIN(image2[indx + 2][2], |
727 | 0 | MIN(image2[indx - v][2], image2[indx + v][2])))) / |
728 | 0 | 2.0; |
729 | 0 | ratio = sqrt((Co * Co + Ho * Ho) / (image2[indx][1] * image2[indx][1] + |
730 | 0 | image2[indx][2] * image2[indx][2])); |
731 | |
|
732 | 0 | if (ratio < 0.85) |
733 | 0 | { |
734 | 0 | image2[indx][0] = |
735 | 0 | -(image2[indx][1] + image2[indx][2] - Co - Ho) + image2[indx][0]; |
736 | 0 | image2[indx][1] = Co; |
737 | 0 | image2[indx][2] = Ho; |
738 | 0 | } |
739 | 0 | } |
740 | 0 | } |
741 | 0 | } |
742 | 0 | } |
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 | 0 | { |
748 | 0 | int row, col, c, u = width, v = 2 * u, w = 3 * u, x = 4 * u, y = 5 * u, indx, |
749 | 0 | min, max; |
750 | 0 | float f[4], g[4]; |
751 | |
|
752 | 0 | for (row = 5; row < height - 5; row++) |
753 | 0 | for (col = 5 + (FC(row, 1) & 1), indx = row * width + col, c = FC(row, col); |
754 | 0 | col < u - 5; col += 2, indx += 2) |
755 | 0 | { |
756 | |
|
757 | 0 | f[0] = 1.0f / (1.0f + abs(image[indx - u][1] - image[indx - w][1]) + |
758 | 0 | abs(image[indx - w][1] - image[indx + y][1])); |
759 | 0 | f[1] = 1.0f / (1.0f + abs(image[indx + 1][1] - image[indx + 3][1]) + |
760 | 0 | abs(image[indx + 3][1] - image[indx - 5][1])); |
761 | 0 | f[2] = 1.0f / (1.0f + abs(image[indx - 1][1] - image[indx - 3][1]) + |
762 | 0 | abs(image[indx - 3][1] - image[indx + 5][1])); |
763 | 0 | f[3] = 1.0f / (1.0f + abs(image[indx + u][1] - image[indx + w][1]) + |
764 | 0 | abs(image[indx + w][1] - image[indx - y][1])); |
765 | |
|
766 | 0 | g[0] = float(CLIP((23 * image[indx - u][1] + 23 * image[indx - w][1] + |
767 | 0 | 2 * image[indx - y][1] + |
768 | 0 | 8 * (image[indx - v][c] - image[indx - x][c]) + |
769 | 0 | 40 * (image[indx][c] - image[indx - v][c])) / |
770 | 0 | 48.0f)); |
771 | 0 | g[1] = float(CLIP((23 * image[indx + 1][1] + 23 * image[indx + 3][1] + |
772 | 0 | 2 * image[indx + 5][1] + |
773 | 0 | 8 * (image[indx + 2][c] - image[indx + 4][c]) + |
774 | 0 | 40 * (image[indx][c] - image[indx + 2][c])) / |
775 | 0 | 48.f)); |
776 | 0 | g[2] = float(CLIP((23 * image[indx - 1][1] + 23 * image[indx - 3][1] + |
777 | 0 | 2 * image[indx - 5][1] + |
778 | 0 | 8 * (image[indx - 2][c] - image[indx - 4][c]) + |
779 | 0 | 40 * (image[indx][c] - image[indx - 2][c])) / |
780 | 0 | 48.0f)); |
781 | 0 | g[3] = float(CLIP((23 * image[indx + u][1] + 23 * image[indx + w][1] + |
782 | 0 | 2 * image[indx + y][1] + |
783 | 0 | 8 * (image[indx + v][c] - image[indx + x][c]) + |
784 | 0 | 40 * (image[indx][c] - image[indx + v][c])) / |
785 | 0 | 48.0f)); |
786 | |
|
787 | 0 | image[indx][1] = |
788 | 0 | CLIP((f[0] * g[0] + f[1] * g[1] + f[2] * g[2] + f[3] * g[3]) / |
789 | 0 | (f[0] + f[1] + f[2] + f[3])); |
790 | |
|
791 | 0 | min = MIN( |
792 | 0 | image[indx + 1 + u][1], |
793 | 0 | MIN(image[indx + 1 - u][1], |
794 | 0 | MIN(image[indx - 1 + u][1], |
795 | 0 | MIN(image[indx - 1 - u][1], |
796 | 0 | MIN(image[indx - 1][1], |
797 | 0 | MIN(image[indx + 1][1], |
798 | 0 | MIN(image[indx - u][1], image[indx + u][1]))))))); |
799 | |
|
800 | 0 | max = MAX( |
801 | 0 | image[indx + 1 + u][1], |
802 | 0 | MAX(image[indx + 1 - u][1], |
803 | 0 | MAX(image[indx - 1 + u][1], |
804 | 0 | MAX(image[indx - 1 - u][1], |
805 | 0 | MAX(image[indx - 1][1], |
806 | 0 | MAX(image[indx + 1][1], |
807 | 0 | MAX(image[indx - u][1], image[indx + u][1]))))))); |
808 | |
|
809 | 0 | image[indx][1] = ULIM(image[indx][1], max, min); |
810 | 0 | } |
811 | 0 | } |
812 | | |
813 | | // FBDD (Fake Before Demosaicing Denoising) |
814 | | void LibRaw::fbdd(int noiserd) |
815 | 0 | { |
816 | 0 | double(*image2)[3]; |
817 | | // safety net: disable for 4-color bayer or full-color images |
818 | 0 | if (colors != 3 || !filters) |
819 | 0 | return; |
820 | 0 | image2 = (double(*)[3])calloc(width * height, sizeof *image2); |
821 | |
|
822 | 0 | border_interpolate(4); |
823 | |
|
824 | 0 | if (noiserd > 1) |
825 | 0 | { |
826 | 0 | fbdd_green(); |
827 | | // dcb_color_full(image2); |
828 | 0 | dcb_color_full(); |
829 | 0 | fbdd_correction(); |
830 | |
|
831 | 0 | dcb_color(); |
832 | 0 | rgb_to_lch(image2); |
833 | 0 | fbdd_correction2(image2); |
834 | 0 | fbdd_correction2(image2); |
835 | 0 | lch_to_rgb(image2); |
836 | 0 | } |
837 | 0 | else |
838 | 0 | { |
839 | 0 | fbdd_green(); |
840 | | // dcb_color_full(image2); |
841 | 0 | dcb_color_full(); |
842 | 0 | fbdd_correction(); |
843 | 0 | } |
844 | |
|
845 | 0 | free(image2); |
846 | 0 | } |
847 | | |
848 | | // DCB demosaicing main routine |
849 | | void LibRaw::dcb(int iterations, int dcb_enhance) |
850 | 0 | { |
851 | |
|
852 | 0 | int i = 1; |
853 | |
|
854 | 0 | float(*image2)[3]; |
855 | 0 | image2 = (float(*)[3])calloc(width * height, sizeof *image2); |
856 | |
|
857 | 0 | float(*image3)[3]; |
858 | 0 | image3 = (float(*)[3])calloc(width * height, sizeof *image3); |
859 | |
|
860 | 0 | border_interpolate(6); |
861 | |
|
862 | 0 | dcb_hor(image2); |
863 | 0 | dcb_color2(image2); |
864 | |
|
865 | 0 | dcb_ver(image3); |
866 | 0 | dcb_color3(image3); |
867 | |
|
868 | 0 | dcb_decide(image2, image3); |
869 | |
|
870 | 0 | free(image3); |
871 | |
|
872 | 0 | dcb_copy_to_buffer(image2); |
873 | |
|
874 | 0 | 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 | 0 | dcb_color(); |
885 | 0 | dcb_pp(); |
886 | |
|
887 | 0 | dcb_map(); |
888 | 0 | dcb_correction2(); |
889 | |
|
890 | 0 | dcb_map(); |
891 | 0 | dcb_correction(); |
892 | |
|
893 | 0 | dcb_map(); |
894 | 0 | dcb_correction(); |
895 | |
|
896 | 0 | dcb_map(); |
897 | 0 | dcb_correction(); |
898 | |
|
899 | 0 | dcb_map(); |
900 | 0 | dcb_restore_from_buffer(image2); |
901 | 0 | dcb_color(); |
902 | |
|
903 | 0 | if (dcb_enhance) |
904 | 0 | { |
905 | 0 | dcb_refinement(); |
906 | | // dcb_color_full(image2); |
907 | 0 | dcb_color_full(); |
908 | 0 | } |
909 | |
|
910 | 0 | free(image2); |
911 | 0 | } |