/src/LibRaw/src/demosaic/misc_demosaic.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- C++ -*- |
2 | | * Copyright 2019-2024 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::pre_interpolate() |
22 | 2.05k | { |
23 | 2.05k | ushort(*img)[4]; |
24 | 2.05k | int row, col, c; |
25 | 2.05k | RUN_CALLBACK(LIBRAW_PROGRESS_PRE_INTERPOLATE, 0, 2); |
26 | 2.05k | if (shrink) |
27 | 0 | { |
28 | 0 | if (half_size) |
29 | 0 | { |
30 | 0 | height = iheight; |
31 | 0 | width = iwidth; |
32 | 0 | if (filters == 9) |
33 | 0 | { |
34 | 0 | for (row = 0; row < 3; row++) |
35 | 0 | for (col = 1; col < 4; col++) |
36 | 0 | if (!(image[row * width + col][0] | image[row * width + col][2])) |
37 | 0 | goto break2; |
38 | 0 | break2: |
39 | 0 | for (; row < height; row += 3) |
40 | 0 | for (col = (col - 1) % 3 + 1; col < width - 1; col += 3) |
41 | 0 | { |
42 | 0 | img = image + row * width + col; |
43 | 0 | for (c = 0; c < 3; c += 2) |
44 | 0 | img[0][c] = (img[-1][c] + img[1][c]) >> 1; |
45 | 0 | } |
46 | 0 | } |
47 | 0 | } |
48 | 0 | else |
49 | 0 | { |
50 | 0 | int extra = filters ? (filters == 9 ? 6 : 2) : 0; |
51 | 0 | img = (ushort(*)[4])calloc((height+extra), (width+extra) * sizeof *img); |
52 | 0 | for (row = 0; row < height; row++) |
53 | 0 | for (col = 0; col < width; col++) |
54 | 0 | { |
55 | 0 | c = fcol(row, col); |
56 | 0 | img[row * width + col][c] = |
57 | 0 | image[(row >> 1) * iwidth + (col >> 1)][c]; |
58 | 0 | } |
59 | 0 | free(image); |
60 | 0 | image = img; |
61 | 0 | shrink = 0; |
62 | 0 | } |
63 | 0 | } |
64 | 2.05k | if (filters > 1000 && colors == 3) |
65 | 1.38k | { |
66 | 1.38k | mix_green = four_color_rgb ^ half_size; |
67 | 1.38k | if (four_color_rgb | half_size) |
68 | 0 | colors++; |
69 | 1.38k | else |
70 | 1.38k | { |
71 | 851k | for (row = FC(1, 0) >> 1; row < height; row += 2) |
72 | 157M | for (col = FC(row, 1) & 1; col < width; col += 2) |
73 | 157M | image[row * width + col][1] = image[row * width + col][3]; |
74 | 1.38k | filters &= ~((filters & 0x55555555U) << 1); |
75 | 1.38k | } |
76 | 1.38k | } |
77 | 2.05k | if (half_size) |
78 | 0 | filters = 0; |
79 | 2.05k | RUN_CALLBACK(LIBRAW_PROGRESS_PRE_INTERPOLATE, 1, 2); |
80 | 2.05k | } |
81 | | |
82 | | void LibRaw::border_interpolate(int border) |
83 | 1.70k | { |
84 | 1.70k | unsigned row, col, y, x, f, c, sum[8]; |
85 | | |
86 | 2.16M | for (row = 0; row < height; row++) |
87 | 50.1M | for (col = 0; col < width; col++) |
88 | 47.9M | { |
89 | 47.9M | if (col == (unsigned)border && row >= (unsigned)border && row < (unsigned)(height - border)) |
90 | 2.15M | col = width - border; |
91 | 47.9M | memset(sum, 0, sizeof sum); |
92 | 191M | for (y = row - 1; y != row + 2; y++) |
93 | 575M | for (x = col - 1; x != col + 2; x++) |
94 | 431M | if (y < height && x < width) |
95 | 400M | { |
96 | 400M | f = fcol(y, x); |
97 | 400M | sum[f] += image[y * width + x][f]; |
98 | 400M | sum[f + 4]++; |
99 | 400M | } |
100 | 47.9M | f = fcol(row, col); |
101 | 144M | FORC(unsigned(colors)) if (c != f && sum[c + 4]) image[row * width + col][c] = |
102 | 95.6M | sum[c] / sum[c + 4]; |
103 | 47.9M | } |
104 | 1.70k | } |
105 | | |
106 | | void LibRaw::lin_interpolate_loop(int *code, int size) |
107 | 306 | { |
108 | 306 | int row; |
109 | 457k | for (row = 1; row < height - 1; row++) |
110 | 457k | { |
111 | 457k | int col, *ip; |
112 | 457k | ushort *pix; |
113 | 93.2M | for (col = 1; col < width - 1; col++) |
114 | 92.7M | { |
115 | 92.7M | int i; |
116 | 92.7M | int sum[4]; |
117 | 92.7M | pix = image[row * width + col]; |
118 | 92.7M | ip = code + ((((row % size) * 16) + (col % size)) * 32); |
119 | 92.7M | memset(sum, 0, sizeof sum); |
120 | 682M | for (i = *ip++; i--; ip += 3) |
121 | 589M | sum[ip[2]] += pix[ip[0]] << ip[1]; |
122 | 369M | for (i = colors; --i; ip += 2) |
123 | 277M | pix[ip[0]] = sum[ip[0]] * ip[1] >> 8; |
124 | 92.7M | } |
125 | 457k | } |
126 | 306 | } |
127 | | |
128 | | void LibRaw::lin_interpolate() |
129 | 306 | { |
130 | 306 | std::vector<int> code_buffer(16 * 16 * 32); |
131 | 306 | int* code = &code_buffer[0], size = 16, *ip, sum[4]; |
132 | 306 | int f, c, x, y, row, col, shift, color; |
133 | | |
134 | 306 | RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 0, 3); |
135 | | |
136 | 306 | if (filters == 9) |
137 | 18 | size = 6; |
138 | 306 | border_interpolate(1); |
139 | 5.02k | for (row = 0; row < size; row++) |
140 | 79.0k | for (col = 0; col < size; col++) |
141 | 74.3k | { |
142 | 74.3k | ip = code + (((row * 16) + col) * 32) + 1; |
143 | 74.3k | f = fcol(row, col); |
144 | 74.3k | memset(sum, 0, sizeof sum); |
145 | 297k | for (y = -1; y <= 1; y++) |
146 | 892k | for (x = -1; x <= 1; x++) |
147 | 669k | { |
148 | 669k | shift = (y == 0) + (x == 0); |
149 | 669k | color = fcol(row + y + 48, col + x + 48); |
150 | 669k | if (color == f) |
151 | 236k | continue; |
152 | 432k | *ip++ = (width * y + x) * 4 + color; |
153 | 432k | *ip++ = shift; |
154 | 432k | *ip++ = color; |
155 | 432k | sum[color] += 1 << shift; |
156 | 432k | } |
157 | 74.3k | code[(row * 16 + col) * 32] = int((ip - (code + ((row * 16) + col) * 32)) / 3); |
158 | 74.3k | FORCC |
159 | 290k | if (c != f) |
160 | 216k | { |
161 | 216k | *ip++ = c; |
162 | 216k | *ip++ = sum[c] > 0 ? 256 / sum[c] : 0; |
163 | 216k | } |
164 | 74.3k | } |
165 | 306 | RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 1, 3); |
166 | 306 | lin_interpolate_loop(code, size); |
167 | 306 | RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 2, 3); |
168 | 306 | } |
169 | | |
170 | | /* |
171 | | This algorithm is officially called: |
172 | | |
173 | | "Interpolation using a Threshold-based variable number of gradients" |
174 | | |
175 | | described in |
176 | | http://scien.stanford.edu/pages/labsite/1999/psych221/projects/99/tingchen/algodep/vargra.html |
177 | | |
178 | | I've extended the basic idea to work with non-Bayer filter arrays. |
179 | | Gradients are numbered clockwise from NW=0 to W=7. |
180 | | */ |
181 | | void LibRaw::vng_interpolate() |
182 | 306 | { |
183 | 306 | static const signed char *cp, |
184 | 306 | terms[] = |
185 | 306 | {-2, -2, +0, -1, 0, 0x01, -2, -2, +0, +0, 1, 0x01, -2, -1, -1, |
186 | 306 | +0, 0, 0x01, -2, -1, +0, -1, 0, 0x02, -2, -1, +0, +0, 0, 0x03, |
187 | 306 | -2, -1, +0, +1, 1, 0x01, -2, +0, +0, -1, 0, 0x06, -2, +0, +0, |
188 | 306 | +0, 1, 0x02, -2, +0, +0, +1, 0, 0x03, -2, +1, -1, +0, 0, 0x04, |
189 | 306 | -2, +1, +0, -1, 1, 0x04, -2, +1, +0, +0, 0, 0x06, -2, +1, +0, |
190 | 306 | +1, 0, 0x02, -2, +2, +0, +0, 1, 0x04, -2, +2, +0, +1, 0, 0x04, |
191 | 306 | -1, -2, -1, +0, 0, -128, -1, -2, +0, -1, 0, 0x01, -1, -2, +1, |
192 | 306 | -1, 0, 0x01, -1, -2, +1, +0, 1, 0x01, -1, -1, -1, +1, 0, -120, |
193 | 306 | -1, -1, +1, -2, 0, 0x40, -1, -1, +1, -1, 0, 0x22, -1, -1, +1, |
194 | 306 | +0, 0, 0x33, -1, -1, +1, +1, 1, 0x11, -1, +0, -1, +2, 0, 0x08, |
195 | 306 | -1, +0, +0, -1, 0, 0x44, -1, +0, +0, +1, 0, 0x11, -1, +0, +1, |
196 | 306 | -2, 1, 0x40, -1, +0, +1, -1, 0, 0x66, -1, +0, +1, +0, 1, 0x22, |
197 | 306 | -1, +0, +1, +1, 0, 0x33, -1, +0, +1, +2, 1, 0x10, -1, +1, +1, |
198 | 306 | -1, 1, 0x44, -1, +1, +1, +0, 0, 0x66, -1, +1, +1, +1, 0, 0x22, |
199 | 306 | -1, +1, +1, +2, 0, 0x10, -1, +2, +0, +1, 0, 0x04, -1, +2, +1, |
200 | 306 | +0, 1, 0x04, -1, +2, +1, +1, 0, 0x04, +0, -2, +0, +0, 1, -128, |
201 | 306 | +0, -1, +0, +1, 1, -120, +0, -1, +1, -2, 0, 0x40, +0, -1, +1, |
202 | 306 | +0, 0, 0x11, +0, -1, +2, -2, 0, 0x40, +0, -1, +2, -1, 0, 0x20, |
203 | 306 | +0, -1, +2, +0, 0, 0x30, +0, -1, +2, +1, 1, 0x10, +0, +0, +0, |
204 | 306 | +2, 1, 0x08, +0, +0, +2, -2, 1, 0x40, +0, +0, +2, -1, 0, 0x60, |
205 | 306 | +0, +0, +2, +0, 1, 0x20, +0, +0, +2, +1, 0, 0x30, +0, +0, +2, |
206 | 306 | +2, 1, 0x10, +0, +1, +1, +0, 0, 0x44, +0, +1, +1, +2, 0, 0x10, |
207 | 306 | +0, +1, +2, -1, 1, 0x40, +0, +1, +2, +0, 0, 0x60, +0, +1, +2, |
208 | 306 | +1, 0, 0x20, +0, +1, +2, +2, 0, 0x10, +1, -2, +1, +0, 0, -128, |
209 | 306 | +1, -1, +1, +1, 0, -120, +1, +0, +1, +2, 0, 0x08, +1, +0, +2, |
210 | 306 | -1, 0, 0x40, +1, +0, +2, +1, 0, 0x10}, |
211 | 306 | chood[] = {-1, -1, -1, 0, -1, +1, 0, +1, +1, +1, +1, 0, +1, -1, 0, -1}; |
212 | 306 | ushort(*brow[5])[4], *pix; |
213 | 306 | int prow = 8, pcol = 2, *ip, *code[16][16], gval[8], gmin, gmax, sum[4]; |
214 | 306 | int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag; |
215 | 306 | int g, diff, thold, num, c; |
216 | | |
217 | 306 | lin_interpolate(); |
218 | | |
219 | 306 | if (filters == 1) |
220 | 12 | prow = pcol = 16; |
221 | 306 | if (filters == 9) |
222 | 18 | prow = pcol = 6; |
223 | 306 | ip = (int *)calloc(prow * pcol, 1280); |
224 | 2.81k | for (row = 0; row < prow; row++) /* Precalculate for VNG */ |
225 | 10.6k | for (col = 0; col < pcol; col++) |
226 | 8.13k | { |
227 | 8.13k | code[row][col] = ip; |
228 | 528k | for (cp = terms, t = 0; t < 64; t++) |
229 | 520k | { |
230 | 520k | y1 = *cp++; |
231 | 520k | x1 = *cp++; |
232 | 520k | y2 = *cp++; |
233 | 520k | x2 = *cp++; |
234 | 520k | weight = *cp++; |
235 | 520k | grads = *cp++; |
236 | 520k | color = fcol(row + y1 + 144, col + x1 + 144); |
237 | 520k | if (fcol(row + y2 + 144, col + x2 + 144) != color) |
238 | 307k | continue; |
239 | 213k | diag = (fcol(row, col + 1) == color && fcol(row + 1, col) == color) ? 2 |
240 | 213k | : 1; |
241 | 213k | if (abs(y1 - y2) == diag && abs(x1 - x2) == diag) |
242 | 23.6k | continue; |
243 | 189k | *ip++ = (y1 * width + x1) * 4 + color; |
244 | 189k | *ip++ = (y2 * width + x2) * 4 + color; |
245 | 189k | *ip++ = weight; |
246 | 1.70M | for (g = 0; g < 8; g++) |
247 | 1.51M | if (grads & 1 << g) |
248 | 277k | *ip++ = g; |
249 | 189k | *ip++ = -1; |
250 | 189k | } |
251 | 8.13k | *ip++ = INT_MAX; |
252 | 73.2k | for (cp = chood, g = 0; g < 8; g++) |
253 | 65.0k | { |
254 | 65.0k | y = *cp++; |
255 | 65.0k | x = *cp++; |
256 | 65.0k | *ip++ = (y * width + x) * 4; |
257 | 65.0k | color = fcol(row, col); |
258 | 65.0k | if (fcol(row + y + 144, col + x + 144) != color && |
259 | 65.0k | fcol(row + y * 2 + 144, col + x * 2 + 144) == color) |
260 | 25.0k | *ip++ = (y * width + x) * 8 + color; |
261 | 40.0k | else |
262 | 40.0k | *ip++ = 0; |
263 | 65.0k | } |
264 | 8.13k | } |
265 | 306 | brow[4] = (ushort(*)[4])calloc(width * 3, sizeof **brow); |
266 | 1.22k | for (row = 0; row < 3; row++) |
267 | 918 | brow[row] = brow[4] + row * width; |
268 | 456k | for (row = 2; row < height - 2; row++) |
269 | 456k | { /* Do VNG interpolation */ |
270 | 456k | if (!((row - 2) % 256)) |
271 | 1.96k | RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, (row - 2) / 256 + 1, |
272 | 456k | ((height - 3) / 256) + 1); |
273 | 91.9M | for (col = 2; col < width - 2; col++) |
274 | 91.5M | { |
275 | 91.5M | pix = image[row * width + col]; |
276 | 91.5M | ip = code[row % prow][col % pcol]; |
277 | 91.5M | memset(gval, 0, sizeof gval); |
278 | 2.80G | while ((g = ip[0]) != INT_MAX) |
279 | 2.71G | { /* Calculate gradients */ |
280 | 2.71G | diff = ABS(pix[g] - pix[ip[1]]) << ip[2]; |
281 | 2.71G | gval[ip[3]] += diff; |
282 | 2.71G | ip += 5; |
283 | 2.71G | if ((g = ip[-1]) == -1) |
284 | 1.74G | continue; |
285 | 970M | gval[g] += diff; |
286 | 1.20G | while ((g = *ip++) != -1) |
287 | 234M | gval[g] += diff; |
288 | 970M | } |
289 | 91.5M | ip++; |
290 | 91.5M | gmin = gmax = gval[0]; /* Choose a threshold */ |
291 | 732M | for (g = 1; g < 8; g++) |
292 | 640M | { |
293 | 640M | if (gmin > gval[g]) |
294 | 51.2M | gmin = gval[g]; |
295 | 640M | if (gmax < gval[g]) |
296 | 53.0M | gmax = gval[g]; |
297 | 640M | } |
298 | 91.5M | if (gmax == 0) |
299 | 51.6M | { |
300 | 51.6M | memcpy(brow[2][col], pix, sizeof *image); |
301 | 51.6M | continue; |
302 | 51.6M | } |
303 | 39.9M | thold = gmin + (gmax >> 1); |
304 | 39.9M | memset(sum, 0, sizeof sum); |
305 | 39.9M | color = fcol(row, col); |
306 | 359M | for (num = g = 0; g < 8; g++, ip += 2) |
307 | 319M | { /* Average the neighbors */ |
308 | 319M | if (gval[g] <= thold) |
309 | 193M | { |
310 | 193M | FORCC |
311 | 773M | if (c == color && ip[1]) |
312 | 106M | sum[c] += (pix[c] + pix[ip[1]]) >> 1; |
313 | 667M | else |
314 | 667M | sum[c] += pix[ip[0] + c]; |
315 | 193M | num++; |
316 | 193M | } |
317 | 319M | } |
318 | 39.9M | FORCC |
319 | 159M | { /* Save to buffer */ |
320 | 159M | t = pix[color]; |
321 | 159M | if (c != color) |
322 | 119M | t += (sum[c] - sum[color]) / num; |
323 | 159M | brow[2][col][c] = CLIP(t); |
324 | 159M | } |
325 | 39.9M | } |
326 | 456k | if (row > 3) /* Write buffer to image */ |
327 | 455k | memcpy(image[(row - 2) * width + 2], brow[0] + 2, |
328 | 455k | (width - 4) * sizeof *image); |
329 | 2.28M | for (g = 0; g < 4; g++) |
330 | 1.82M | brow[(g - 1) & 3] = brow[g]; |
331 | 456k | } |
332 | 306 | memcpy(image[(row - 2) * width + 2], brow[0] + 2, |
333 | 306 | (width - 4) * sizeof *image); |
334 | 306 | memcpy(image[(row - 1) * width + 2], brow[1] + 2, |
335 | 306 | (width - 4) * sizeof *image); |
336 | 306 | free(brow[4]); |
337 | 306 | free(code[0][0]); |
338 | 306 | } |
339 | | |
340 | | /* |
341 | | Patterned Pixel Grouping Interpolation by Alain Desbiolles |
342 | | */ |
343 | | void LibRaw::ppg_interpolate() |
344 | 0 | { |
345 | 0 | int dir[5] = {1, width, -1, -width, 1}; |
346 | 0 | int row, col, diff[2], guess[2], c, d, i; |
347 | 0 | ushort(*pix)[4]; |
348 | |
|
349 | 0 | border_interpolate(3); |
350 | | |
351 | | /* Fill in the green layer with gradients and pattern recognition: */ |
352 | 0 | RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 0, 3); |
353 | | #ifdef LIBRAW_USE_OPENMP |
354 | | #pragma omp parallel for default(shared) private(guess, diff, row, col, d, c, \ |
355 | | i, pix) schedule(static) |
356 | | #endif |
357 | 0 | for (row = 3; row < height - 3; row++) |
358 | 0 | for (col = 3 + (FC(row, 3) & 1), c = FC(row, col); col < width - 3; |
359 | 0 | col += 2) |
360 | 0 | { |
361 | 0 | pix = image + row * width + col; |
362 | 0 | for (i = 0; i < 2; i++) |
363 | 0 | { |
364 | 0 | d = dir[i]; |
365 | 0 | guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2 - pix[-2 * d][c] - |
366 | 0 | pix[2 * d][c]; |
367 | 0 | diff[i] = |
368 | 0 | (ABS(pix[-2 * d][c] - pix[0][c]) + ABS(pix[2 * d][c] - pix[0][c]) + |
369 | 0 | ABS(pix[-d][1] - pix[d][1])) * |
370 | 0 | 3 + |
371 | 0 | (ABS(pix[3 * d][1] - pix[d][1]) + |
372 | 0 | ABS(pix[-3 * d][1] - pix[-d][1])) * |
373 | 0 | 2; |
374 | 0 | } |
375 | 0 | d = dir[i = diff[0] > diff[1]]; |
376 | 0 | pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]); |
377 | 0 | } |
378 | | /* Calculate red and blue for each green pixel: */ |
379 | 0 | RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 1, 3); |
380 | | #ifdef LIBRAW_USE_OPENMP |
381 | | #pragma omp parallel for default(shared) private(guess, diff, row, col, d, c, \ |
382 | | i, pix) schedule(static) |
383 | | #endif |
384 | 0 | for (row = 1; row < height - 1; row++) |
385 | 0 | for (col = 1 + (FC(row, 2) & 1), c = FC(row, col + 1); col < width - 1; |
386 | 0 | col += 2) |
387 | 0 | { |
388 | 0 | pix = image + row * width + col; |
389 | 0 | for (i = 0; i < 2; c = 2 - c, i++) |
390 | 0 | { |
391 | 0 | d = dir[i]; |
392 | 0 | pix[0][c] = CLIP( |
393 | 0 | (pix[-d][c] + pix[d][c] + 2 * pix[0][1] - pix[-d][1] - pix[d][1]) >> |
394 | 0 | 1); |
395 | 0 | } |
396 | 0 | } |
397 | | /* Calculate blue for red pixels and vice versa: */ |
398 | 0 | RUN_CALLBACK(LIBRAW_PROGRESS_INTERPOLATE, 2, 3); |
399 | | #ifdef LIBRAW_USE_OPENMP |
400 | | #pragma omp parallel for default(shared) private(guess, diff, row, col, d, c, \ |
401 | | i, pix) schedule(static) |
402 | | #endif |
403 | 0 | for (row = 1; row < height - 1; row++) |
404 | 0 | for (col = 1 + (FC(row, 1) & 1), c = 2 - FC(row, col); col < width - 1; |
405 | 0 | col += 2) |
406 | 0 | { |
407 | 0 | pix = image + row * width + col; |
408 | 0 | for (i = 0; i < 2; i++) |
409 | 0 | { |
410 | 0 | d = dir[i] + dir[i+1]; |
411 | 0 | diff[i] = ABS(pix[-d][c] - pix[d][c]) + ABS(pix[-d][1] - pix[0][1]) + |
412 | 0 | ABS(pix[d][1] - pix[0][1]); |
413 | 0 | guess[i] = |
414 | 0 | pix[-d][c] + pix[d][c] + 2 * pix[0][1] - pix[-d][1] - pix[d][1]; |
415 | 0 | } |
416 | 0 | if (diff[0] != diff[1]) |
417 | 0 | pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1); |
418 | 0 | else |
419 | 0 | pix[0][c] = CLIP((guess[0] + guess[1]) >> 2); |
420 | 0 | } |
421 | 0 | } |