File indexing completed on 2024-04-21 03:43:47
0001 /* 0002 1394-Based Digital Camera Control Library 0003 0004 Bayer pattern decoding functions 0005 0006 Written by Damien Douxchamps and Frederic Devernay 0007 The original VNG and AHD Bayer decoding are from Dave Coffin's DCRAW. 0008 0009 SPDX-License-Identifier: LGPL-2.1-or-later 0010 */ 0011 0012 #include "bayer.h" 0013 0014 #include <limits.h> 0015 #include <math.h> 0016 #include <stdint.h> 0017 #include <stdlib.h> 0018 #include <string.h> 0019 0020 #define CLIP(in, out) \ 0021 in = in < 0 ? 0 : in; \ 0022 in = in > 255 ? 255 : in; \ 0023 out = in; 0024 0025 #define CLIP16(in, out, bits) \ 0026 in = in < 0 ? 0 : in; \ 0027 in = in > ((1 << bits) - 1) ? ((1 << bits) - 1) : in; \ 0028 out = in; 0029 0030 void ClearBorders(uint8_t *rgb, int sx, int sy, int w) 0031 { 0032 int i, j; 0033 /* black edges are added with a width w: */ 0034 i = 3 * sx * w - 1; 0035 j = 3 * sx * sy - 1; 0036 while (i >= 0) 0037 { 0038 rgb[i--] = 0; 0039 rgb[j--] = 0; 0040 } 0041 0042 int low = sx * (w - 1) * 3 - 1 + w * 3; 0043 i = low + sx * (sy - w * 2 + 1) * 3; 0044 while (i > low) 0045 { 0046 j = 6 * w; 0047 while (j > 0) 0048 { 0049 rgb[i--] = 0; 0050 j--; 0051 } 0052 i -= (sx - 2 * w) * 3; 0053 } 0054 } 0055 0056 void ClearBorders_uint16(uint16_t *rgb, int sx, int sy, int w) 0057 { 0058 int i, j; 0059 0060 /* black edges: */ 0061 i = 3 * sx * w - 1; 0062 j = 3 * sx * sy - 1; 0063 while (i >= 0) 0064 { 0065 rgb[i--] = 0; 0066 rgb[j--] = 0; 0067 } 0068 0069 int low = sx * (w - 1) * 3 - 1 + w * 3; 0070 i = low + sx * (sy - w * 2 + 1) * 3; 0071 while (i > low) 0072 { 0073 j = 6 * w; 0074 while (j > 0) 0075 { 0076 rgb[i--] = 0; 0077 j--; 0078 } 0079 i -= (sx - 2 * w) * 3; 0080 } 0081 } 0082 0083 /************************************************************** 0084 * Color conversion functions for cameras that can * 0085 * output raw-Bayer pattern images, such as some Basler and * 0086 * Point Grey camera. Most of the algos presented here come * 0087 * from http://www-ise.stanford.edu/~tingchen/ and have been * 0088 * converted from Matlab to C and extended to all elementary * 0089 * patterns. * 0090 **************************************************************/ 0091 0092 /* 8-bits versions */ 0093 /* insprired by OpenCV's Bayer decoding */ 0094 0095 dc1394error_t dc1394_bayer_NearestNeighbor(const uint8_t *bayer, uint8_t *rgb, int sx, int sy, 0096 int tile) 0097 { 0098 const int bayerStep = sx; 0099 const int rgbStep = 3 * sx; 0100 int width = sx; 0101 int height = sy; 0102 int blue = tile == DC1394_COLOR_FILTER_BGGR || tile == DC1394_COLOR_FILTER_GBRG ? -1 : 1; 0103 int start_with_green = tile == DC1394_COLOR_FILTER_GBRG || tile == DC1394_COLOR_FILTER_GRBG; 0104 int i, imax, iinc; 0105 0106 if ((tile > DC1394_COLOR_FILTER_MAX) || (tile < DC1394_COLOR_FILTER_MIN)) 0107 return DC1394_INVALID_COLOR_FILTER; 0108 0109 /* add black border */ 0110 imax = sx * sy * 3; 0111 for (i = sx * (sy - 1) * 3; i < imax; i++) 0112 { 0113 rgb[i] = 0; 0114 } 0115 iinc = (sx - 1) * 3; 0116 for (i = (sx - 1) * 3; i < imax; i += iinc) 0117 { 0118 rgb[i++] = 0; 0119 rgb[i++] = 0; 0120 rgb[i++] = 0; 0121 } 0122 0123 rgb += 1; 0124 width -= 1; 0125 height -= 1; 0126 0127 for (; height--; bayer += bayerStep, rgb += rgbStep) 0128 { 0129 const uint8_t *bayerEnd = bayer + width; 0130 0131 if (start_with_green) 0132 { 0133 rgb[-blue] = bayer[1]; 0134 rgb[0] = bayer[bayerStep + 1]; 0135 rgb[blue] = bayer[bayerStep]; 0136 bayer++; 0137 rgb += 3; 0138 } 0139 0140 if (blue > 0) 0141 { 0142 for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) 0143 { 0144 rgb[-1] = bayer[0]; 0145 rgb[0] = bayer[1]; 0146 rgb[1] = bayer[bayerStep + 1]; 0147 0148 rgb[2] = bayer[2]; 0149 rgb[3] = bayer[bayerStep + 2]; 0150 rgb[4] = bayer[bayerStep + 1]; 0151 } 0152 } 0153 else 0154 { 0155 for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) 0156 { 0157 rgb[1] = bayer[0]; 0158 rgb[0] = bayer[1]; 0159 rgb[-1] = bayer[bayerStep + 1]; 0160 0161 rgb[4] = bayer[2]; 0162 rgb[3] = bayer[bayerStep + 2]; 0163 rgb[2] = bayer[bayerStep + 1]; 0164 } 0165 } 0166 0167 if (bayer < bayerEnd) 0168 { 0169 rgb[-blue] = bayer[0]; 0170 rgb[0] = bayer[1]; 0171 rgb[blue] = bayer[bayerStep + 1]; 0172 bayer++; 0173 rgb += 3; 0174 } 0175 0176 bayer -= width; 0177 rgb -= width * 3; 0178 0179 blue = -blue; 0180 start_with_green = !start_with_green; 0181 } 0182 0183 return DC1394_SUCCESS; 0184 } 0185 0186 /* OpenCV's Bayer decoding */ 0187 dc1394error_t dc1394_bayer_Bilinear(const uint8_t *bayer, uint8_t *rgb, int sx, int sy, int tile) 0188 { 0189 const int bayerStep = sx; 0190 const int rgbStep = 3 * sx; 0191 int width = sx; 0192 int height = sy; 0193 /* 0194 the two letters of the OpenCV name are respectively 0195 the 4th and 3rd letters from the blinky name, 0196 and we also have to switch R and B (OpenCV is BGR) 0197 0198 CV_BayerBG2BGR <-> DC1394_COLOR_FILTER_BGGR 0199 CV_BayerGB2BGR <-> DC1394_COLOR_FILTER_GBRG 0200 CV_BayerGR2BGR <-> DC1394_COLOR_FILTER_GRBG 0201 0202 int blue = tile == CV_BayerBG2BGR || tile == CV_BayerGB2BGR ? -1 : 1; 0203 int start_with_green = tile == CV_BayerGB2BGR || tile == CV_BayerGR2BGR; 0204 */ 0205 int blue = tile == DC1394_COLOR_FILTER_BGGR || tile == DC1394_COLOR_FILTER_GBRG ? -1 : 1; 0206 int start_with_green = tile == DC1394_COLOR_FILTER_GBRG || tile == DC1394_COLOR_FILTER_GRBG; 0207 0208 if ((tile > DC1394_COLOR_FILTER_MAX) || (tile < DC1394_COLOR_FILTER_MIN)) 0209 return DC1394_INVALID_COLOR_FILTER; 0210 0211 ClearBorders(rgb, sx, sy, 1); 0212 rgb += rgbStep + 3 + 1; 0213 height -= 2; 0214 width -= 2; 0215 0216 for (; height--; bayer += bayerStep, rgb += rgbStep) 0217 { 0218 int t0, t1; 0219 const uint8_t *bayerEnd = bayer + width; 0220 0221 if (start_with_green) 0222 { 0223 /* OpenCV has a bug in the next line, which was 0224 t0 = (bayer[0] + bayer[bayerStep * 2] + 1) >> 1; */ 0225 t0 = (bayer[1] + bayer[bayerStep * 2 + 1] + 1) >> 1; 0226 t1 = (bayer[bayerStep] + bayer[bayerStep + 2] + 1) >> 1; 0227 rgb[-blue] = (uint8_t)t0; 0228 rgb[0] = bayer[bayerStep + 1]; 0229 rgb[blue] = (uint8_t)t1; 0230 bayer++; 0231 rgb += 3; 0232 } 0233 0234 if (blue > 0) 0235 { 0236 for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) 0237 { 0238 t0 = (bayer[0] + bayer[2] + bayer[bayerStep * 2] + bayer[bayerStep * 2 + 2] + 2) >> 2; 0239 t1 = (bayer[1] + bayer[bayerStep] + bayer[bayerStep + 2] + bayer[bayerStep * 2 + 1] + 2) >> 2; 0240 rgb[-1] = (uint8_t)t0; 0241 rgb[0] = (uint8_t)t1; 0242 rgb[1] = bayer[bayerStep + 1]; 0243 0244 t0 = (bayer[2] + bayer[bayerStep * 2 + 2] + 1) >> 1; 0245 t1 = (bayer[bayerStep + 1] + bayer[bayerStep + 3] + 1) >> 1; 0246 rgb[2] = (uint8_t)t0; 0247 rgb[3] = bayer[bayerStep + 2]; 0248 rgb[4] = (uint8_t)t1; 0249 } 0250 } 0251 else 0252 { 0253 for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) 0254 { 0255 t0 = (bayer[0] + bayer[2] + bayer[bayerStep * 2] + bayer[bayerStep * 2 + 2] + 2) >> 2; 0256 t1 = (bayer[1] + bayer[bayerStep] + bayer[bayerStep + 2] + bayer[bayerStep * 2 + 1] + 2) >> 2; 0257 rgb[1] = (uint8_t)t0; 0258 rgb[0] = (uint8_t)t1; 0259 rgb[-1] = bayer[bayerStep + 1]; 0260 0261 t0 = (bayer[2] + bayer[bayerStep * 2 + 2] + 1) >> 1; 0262 t1 = (bayer[bayerStep + 1] + bayer[bayerStep + 3] + 1) >> 1; 0263 rgb[4] = (uint8_t)t0; 0264 rgb[3] = bayer[bayerStep + 2]; 0265 rgb[2] = (uint8_t)t1; 0266 } 0267 } 0268 0269 if (bayer < bayerEnd) 0270 { 0271 t0 = (bayer[0] + bayer[2] + bayer[bayerStep * 2] + bayer[bayerStep * 2 + 2] + 2) >> 2; 0272 t1 = (bayer[1] + bayer[bayerStep] + bayer[bayerStep + 2] + bayer[bayerStep * 2 + 1] + 2) >> 2; 0273 rgb[-blue] = (uint8_t)t0; 0274 rgb[0] = (uint8_t)t1; 0275 rgb[blue] = bayer[bayerStep + 1]; 0276 bayer++; 0277 rgb += 3; 0278 } 0279 0280 bayer -= width; 0281 rgb -= width * 3; 0282 0283 blue = -blue; 0284 start_with_green = !start_with_green; 0285 } 0286 return DC1394_SUCCESS; 0287 } 0288 0289 /* High-Quality Linear Interpolation For Demosaicing Of 0290 Bayer-Patterned Color Images, by Henrique S. Malvar, Li-wei He, and 0291 Ross Cutler, in ICASSP'04 */ 0292 dc1394error_t dc1394_bayer_HQLinear(const uint8_t *bayer, uint8_t *rgb, int sx, int sy, int tile) 0293 { 0294 const int bayerStep = sx; 0295 const int rgbStep = 3 * sx; 0296 int width = sx; 0297 int height = sy; 0298 int blue = tile == DC1394_COLOR_FILTER_BGGR || tile == DC1394_COLOR_FILTER_GBRG ? -1 : 1; 0299 int start_with_green = tile == DC1394_COLOR_FILTER_GBRG || tile == DC1394_COLOR_FILTER_GRBG; 0300 0301 if ((tile > DC1394_COLOR_FILTER_MAX) || (tile < DC1394_COLOR_FILTER_MIN)) 0302 return DC1394_INVALID_COLOR_FILTER; 0303 0304 ClearBorders(rgb, sx, sy, 2); 0305 rgb += 2 * rgbStep + 6 + 1; 0306 height -= 4; 0307 width -= 4; 0308 0309 /* We begin with a (+1 line,+1 column) offset with respect to bilinear decoding, so start_with_green is the same, but blue is opposite */ 0310 blue = -blue; 0311 0312 for (; height--; bayer += bayerStep, rgb += rgbStep) 0313 { 0314 int t0, t1; 0315 const uint8_t *bayerEnd = bayer + width; 0316 const int bayerStep2 = bayerStep * 2; 0317 const int bayerStep3 = bayerStep * 3; 0318 const int bayerStep4 = bayerStep * 4; 0319 0320 if (start_with_green) 0321 { 0322 /* at green pixel */ 0323 rgb[0] = bayer[bayerStep2 + 2]; 0324 t0 = rgb[0] * 5 + ((bayer[bayerStep + 2] + bayer[bayerStep3 + 2]) << 2) - bayer[2] - bayer[bayerStep + 1] - 0325 bayer[bayerStep + 3] - bayer[bayerStep3 + 1] - bayer[bayerStep3 + 3] - bayer[bayerStep4 + 2] + 0326 ((bayer[bayerStep2] + bayer[bayerStep2 + 4] + 1) >> 1); 0327 t1 = rgb[0] * 5 + ((bayer[bayerStep2 + 1] + bayer[bayerStep2 + 3]) << 2) - bayer[bayerStep2] - 0328 bayer[bayerStep + 1] - bayer[bayerStep + 3] - bayer[bayerStep3 + 1] - bayer[bayerStep3 + 3] - 0329 bayer[bayerStep2 + 4] + ((bayer[2] + bayer[bayerStep4 + 2] + 1) >> 1); 0330 t0 = (t0 + 4) >> 3; 0331 CLIP(t0, rgb[-blue]); 0332 t1 = (t1 + 4) >> 3; 0333 CLIP(t1, rgb[blue]); 0334 bayer++; 0335 rgb += 3; 0336 } 0337 0338 if (blue > 0) 0339 { 0340 for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) 0341 { 0342 /* B at B */ 0343 rgb[1] = bayer[bayerStep2 + 2]; 0344 /* R at B */ 0345 t0 = ((bayer[bayerStep + 1] + bayer[bayerStep + 3] + bayer[bayerStep3 + 1] + bayer[bayerStep3 + 3]) 0346 << 1) - 0347 (((bayer[2] + bayer[bayerStep2] + bayer[bayerStep2 + 4] + bayer[bayerStep4 + 2]) * 3 + 1) >> 1) + 0348 rgb[1] * 6; 0349 /* G at B */ 0350 t1 = ((bayer[bayerStep + 2] + bayer[bayerStep2 + 1] + bayer[bayerStep2 + 3] + bayer[bayerStep3 + 2]) 0351 << 1) - 0352 (bayer[2] + bayer[bayerStep2] + bayer[bayerStep2 + 4] + bayer[bayerStep4 + 2]) + (rgb[1] << 2); 0353 t0 = (t0 + 4) >> 3; 0354 CLIP(t0, rgb[-1]); 0355 t1 = (t1 + 4) >> 3; 0356 CLIP(t1, rgb[0]); 0357 /* at green pixel */ 0358 rgb[3] = bayer[bayerStep2 + 3]; 0359 t0 = rgb[3] * 5 + ((bayer[bayerStep + 3] + bayer[bayerStep3 + 3]) << 2) - bayer[3] - 0360 bayer[bayerStep + 2] - bayer[bayerStep + 4] - bayer[bayerStep3 + 2] - bayer[bayerStep3 + 4] - 0361 bayer[bayerStep4 + 3] + ((bayer[bayerStep2 + 1] + bayer[bayerStep2 + 5] + 1) >> 1); 0362 t1 = rgb[3] * 5 + ((bayer[bayerStep2 + 2] + bayer[bayerStep2 + 4]) << 2) - bayer[bayerStep2 + 1] - 0363 bayer[bayerStep + 2] - bayer[bayerStep + 4] - bayer[bayerStep3 + 2] - bayer[bayerStep3 + 4] - 0364 bayer[bayerStep2 + 5] + ((bayer[3] + bayer[bayerStep4 + 3] + 1) >> 1); 0365 t0 = (t0 + 4) >> 3; 0366 CLIP(t0, rgb[2]); 0367 t1 = (t1 + 4) >> 3; 0368 CLIP(t1, rgb[4]); 0369 } 0370 } 0371 else 0372 { 0373 for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) 0374 { 0375 /* R at R */ 0376 rgb[-1] = bayer[bayerStep2 + 2]; 0377 /* B at R */ 0378 t0 = ((bayer[bayerStep + 1] + bayer[bayerStep + 3] + bayer[bayerStep3 + 1] + bayer[bayerStep3 + 3]) 0379 << 1) - 0380 (((bayer[2] + bayer[bayerStep2] + bayer[bayerStep2 + 4] + bayer[bayerStep4 + 2]) * 3 + 1) >> 1) + 0381 rgb[-1] * 6; 0382 /* G at R */ 0383 t1 = ((bayer[bayerStep + 2] + bayer[bayerStep2 + 1] + bayer[bayerStep2 + 3] + bayer[bayerStep * 3 + 2]) 0384 << 1) - 0385 (bayer[2] + bayer[bayerStep2] + bayer[bayerStep2 + 4] + bayer[bayerStep4 + 2]) + (rgb[-1] << 2); 0386 t0 = (t0 + 4) >> 3; 0387 CLIP(t0, rgb[1]); 0388 t1 = (t1 + 4) >> 3; 0389 CLIP(t1, rgb[0]); 0390 0391 /* at green pixel */ 0392 rgb[3] = bayer[bayerStep2 + 3]; 0393 t0 = rgb[3] * 5 + ((bayer[bayerStep + 3] + bayer[bayerStep3 + 3]) << 2) - bayer[3] - 0394 bayer[bayerStep + 2] - bayer[bayerStep + 4] - bayer[bayerStep3 + 2] - bayer[bayerStep3 + 4] - 0395 bayer[bayerStep4 + 3] + ((bayer[bayerStep2 + 1] + bayer[bayerStep2 + 5] + 1) >> 1); 0396 t1 = rgb[3] * 5 + ((bayer[bayerStep2 + 2] + bayer[bayerStep2 + 4]) << 2) - bayer[bayerStep2 + 1] - 0397 bayer[bayerStep + 2] - bayer[bayerStep + 4] - bayer[bayerStep3 + 2] - bayer[bayerStep3 + 4] - 0398 bayer[bayerStep2 + 5] + ((bayer[3] + bayer[bayerStep4 + 3] + 1) >> 1); 0399 t0 = (t0 + 4) >> 3; 0400 CLIP(t0, rgb[4]); 0401 t1 = (t1 + 4) >> 3; 0402 CLIP(t1, rgb[2]); 0403 } 0404 } 0405 0406 if (bayer < bayerEnd) 0407 { 0408 /* B at B */ 0409 rgb[blue] = bayer[bayerStep2 + 2]; 0410 /* R at B */ 0411 t0 = ((bayer[bayerStep + 1] + bayer[bayerStep + 3] + bayer[bayerStep3 + 1] + bayer[bayerStep3 + 3]) << 1) - 0412 (((bayer[2] + bayer[bayerStep2] + bayer[bayerStep2 + 4] + bayer[bayerStep4 + 2]) * 3 + 1) >> 1) + 0413 rgb[blue] * 6; 0414 /* G at B */ 0415 t1 = (((bayer[bayerStep + 2] + bayer[bayerStep2 + 1] + bayer[bayerStep2 + 3] + bayer[bayerStep3 + 2])) 0416 << 1) - 0417 (bayer[2] + bayer[bayerStep2] + bayer[bayerStep2 + 4] + bayer[bayerStep4 + 2]) + (rgb[blue] << 2); 0418 t0 = (t0 + 4) >> 3; 0419 CLIP(t0, rgb[-blue]); 0420 t1 = (t1 + 4) >> 3; 0421 CLIP(t1, rgb[0]); 0422 bayer++; 0423 rgb += 3; 0424 } 0425 0426 bayer -= width; 0427 rgb -= width * 3; 0428 0429 blue = -blue; 0430 start_with_green = !start_with_green; 0431 } 0432 0433 return DC1394_SUCCESS; 0434 } 0435 0436 /* coriander's Bayer decoding */ 0437 /* Edge Sensing Interpolation II from http://www-ise.stanford.edu/~tingchen/ */ 0438 /* (Laroche,Claude A. "Apparatus and method for adaptively 0439 interpolating a full color image utilizing chrominance gradients" 0440 U.S. Patent 5,373,322) */ 0441 dc1394error_t dc1394_bayer_EdgeSense(const uint8_t *bayer, uint8_t *rgb, int sx, int sy, int tile) 0442 { 0443 uint8_t *outR, *outG, *outB; 0444 register int i3, j3, base; 0445 int i, j; 0446 int dh, dv; 0447 int tmp; 0448 int sx3 = sx * 3; 0449 0450 /* sx and sy should be even */ 0451 switch (tile) 0452 { 0453 case DC1394_COLOR_FILTER_GRBG: 0454 case DC1394_COLOR_FILTER_BGGR: 0455 outR = &rgb[0]; 0456 outG = &rgb[1]; 0457 outB = &rgb[2]; 0458 break; 0459 case DC1394_COLOR_FILTER_GBRG: 0460 case DC1394_COLOR_FILTER_RGGB: 0461 outR = &rgb[2]; 0462 outG = &rgb[1]; 0463 outB = &rgb[0]; 0464 break; 0465 default: 0466 return DC1394_INVALID_COLOR_FILTER; 0467 } 0468 0469 switch (tile) 0470 { 0471 case DC1394_COLOR_FILTER_GRBG: 0472 case DC1394_COLOR_FILTER_GBRG: 0473 /* copy original RGB data to output images */ 0474 for (i = 0, i3 = 0; i < sy * sx; i += (sx << 1), i3 += (sx3 << 1)) 0475 { 0476 for (j = 0, j3 = 0; j < sx; j += 2, j3 += 6) 0477 { 0478 base = i3 + j3; 0479 outG[base] = bayer[i + j]; 0480 outG[base + sx3 + 3] = bayer[i + j + sx + 1]; 0481 outR[base + 3] = bayer[i + j + 1]; 0482 outB[base + sx3] = bayer[i + j + sx]; 0483 } 0484 } 0485 /* process GREEN channel */ 0486 for (i3 = 3 * sx3; i3 < (sy - 2) * sx3; i3 += (sx3 << 1)) 0487 { 0488 for (j3 = 6; j3 < sx3 - 9; j3 += 6) 0489 { 0490 base = i3 + j3; 0491 dh = abs(((outB[base - 6] + outB[base + 6]) >> 1) - outB[base]); 0492 dv = abs(((outB[base - (sx3 << 1)] + outB[base + (sx3 << 1)]) >> 1) - outB[base]); 0493 tmp = (((outG[base - 3] + outG[base + 3]) >> 1) * (dh <= dv) + 0494 ((outG[base - sx3] + outG[base + sx3]) >> 1) * (dh > dv)); 0495 CLIP(tmp, outG[base]); 0496 } 0497 } 0498 0499 for (i3 = 2 * sx3; i3 < (sy - 3) * sx3; i3 += (sx3 << 1)) 0500 { 0501 for (j3 = 9; j3 < sx3 - 6; j3 += 6) 0502 { 0503 base = i3 + j3; 0504 dh = abs(((outR[base - 6] + outR[base + 6]) >> 1) - outR[base]); 0505 dv = abs(((outR[base - (sx3 << 1)] + outR[base + (sx3 << 1)]) >> 1) - outR[base]); 0506 tmp = (((outG[base - 3] + outG[base + 3]) >> 1) * (dh <= dv) + 0507 ((outG[base - sx3] + outG[base + sx3]) >> 1) * (dh > dv)); 0508 CLIP(tmp, outG[base]); 0509 } 0510 } 0511 /* process RED channel */ 0512 for (i3 = 0; i3 < (sy - 1) * sx3; i3 += (sx3 << 1)) 0513 { 0514 for (j3 = 6; j3 < sx3 - 3; j3 += 6) 0515 { 0516 base = i3 + j3; 0517 tmp = outG[base] + ((outR[base - 3] - outG[base - 3] + outR[base + 3] - outG[base + 3]) >> 1); 0518 CLIP(tmp, outR[base]); 0519 } 0520 } 0521 for (i3 = sx3; i3 < (sy - 2) * sx3; i3 += (sx3 << 1)) 0522 { 0523 for (j3 = 3; j3 < sx3; j3 += 6) 0524 { 0525 base = i3 + j3; 0526 tmp = 0527 outG[base] + ((outR[base - sx3] - outG[base - sx3] + outR[base + sx3] - outG[base + sx3]) >> 1); 0528 CLIP(tmp, outR[base]); 0529 } 0530 for (j3 = 6; j3 < sx3 - 3; j3 += 6) 0531 { 0532 base = i3 + j3; 0533 tmp = outG[base] + ((outR[base - sx3 - 3] - outG[base - sx3 - 3] + outR[base - sx3 + 3] - 0534 outG[base - sx3 + 3] + outR[base + sx3 - 3] - outG[base + sx3 - 3] + 0535 outR[base + sx3 + 3] - outG[base + sx3 + 3]) >> 0536 2); 0537 CLIP(tmp, outR[base]); 0538 } 0539 } 0540 0541 /* process BLUE channel */ 0542 for (i3 = sx3; i3 < sy * sx3; i3 += (sx3 << 1)) 0543 { 0544 for (j3 = 3; j3 < sx3 - 6; j3 += 6) 0545 { 0546 base = i3 + j3; 0547 tmp = outG[base] + ((outB[base - 3] - outG[base - 3] + outB[base + 3] - outG[base + 3]) >> 1); 0548 CLIP(tmp, outB[base]); 0549 } 0550 } 0551 for (i3 = 2 * sx3; i3 < (sy - 1) * sx3; i3 += (sx3 << 1)) 0552 { 0553 for (j3 = 0; j3 < sx3 - 3; j3 += 6) 0554 { 0555 base = i3 + j3; 0556 tmp = 0557 outG[base] + ((outB[base - sx3] - outG[base - sx3] + outB[base + sx3] - outG[base + sx3]) >> 1); 0558 CLIP(tmp, outB[base]); 0559 } 0560 for (j3 = 3; j3 < sx3 - 6; j3 += 6) 0561 { 0562 base = i3 + j3; 0563 tmp = outG[base] + ((outB[base - sx3 - 3] - outG[base - sx3 - 3] + outB[base - sx3 + 3] - 0564 outG[base - sx3 + 3] + outB[base + sx3 - 3] - outG[base + sx3 - 3] + 0565 outB[base + sx3 + 3] - outG[base + sx3 + 3]) >> 0566 2); 0567 CLIP(tmp, outB[base]); 0568 } 0569 } 0570 break; 0571 0572 case DC1394_COLOR_FILTER_BGGR: 0573 case DC1394_COLOR_FILTER_RGGB: 0574 /* copy original RGB data to output images */ 0575 for (i = 0, i3 = 0; i < sy * sx; i += (sx << 1), i3 += (sx3 << 1)) 0576 { 0577 for (j = 0, j3 = 0; j < sx; j += 2, j3 += 6) 0578 { 0579 base = i3 + j3; 0580 outB[base] = bayer[i + j]; 0581 outR[base + sx3 + 3] = bayer[i + sx + (j + 1)]; 0582 outG[base + 3] = bayer[i + j + 1]; 0583 outG[base + sx3] = bayer[i + sx + j]; 0584 } 0585 } 0586 /* process GREEN channel */ 0587 for (i3 = 2 * sx3; i3 < (sy - 2) * sx3; i3 += (sx3 << 1)) 0588 { 0589 for (j3 = 6; j3 < sx3 - 9; j3 += 6) 0590 { 0591 base = i3 + j3; 0592 dh = abs(((outB[base - 6] + outB[base + 6]) >> 1) - outB[base]); 0593 dv = abs(((outB[base - (sx3 << 1)] + outB[base + (sx3 << 1)]) >> 1) - outB[base]); 0594 tmp = (((outG[base - 3] + outG[base + 3]) >> 1) * (dh <= dv) + 0595 ((outG[base - sx3] + outG[base + sx3]) >> 1) * (dh > dv)); 0596 CLIP(tmp, outG[base]); 0597 } 0598 } 0599 for (i3 = 3 * sx3; i3 < (sy - 3) * sx3; i3 += (sx3 << 1)) 0600 { 0601 for (j3 = 9; j3 < sx3 - 6; j3 += 6) 0602 { 0603 base = i3 + j3; 0604 dh = abs(((outR[base - 6] + outR[base + 6]) >> 1) - outR[base]); 0605 dv = abs(((outR[base - (sx3 << 1)] + outR[base + (sx3 << 1)]) >> 1) - outR[base]); 0606 tmp = (((outG[base - 3] + outG[base + 3]) >> 1) * (dh <= dv) + 0607 ((outG[base - sx3] + outG[base + sx3]) >> 1) * (dh > dv)); 0608 CLIP(tmp, outG[base]); 0609 } 0610 } 0611 /* process RED channel */ 0612 for (i3 = sx3; i3 < (sy - 1) * sx3; i3 += (sx3 << 1)) 0613 { /* G-points (1/2) */ 0614 for (j3 = 6; j3 < sx3 - 3; j3 += 6) 0615 { 0616 base = i3 + j3; 0617 tmp = outG[base] + ((outR[base - 3] - outG[base - 3] + outR[base + 3] - outG[base + 3]) >> 1); 0618 CLIP(tmp, outR[base]); 0619 } 0620 } 0621 for (i3 = 2 * sx3; i3 < (sy - 2) * sx3; i3 += (sx3 << 1)) 0622 { 0623 for (j3 = 3; j3 < sx3; j3 += 6) 0624 { /* G-points (2/2) */ 0625 base = i3 + j3; 0626 tmp = 0627 outG[base] + ((outR[base - sx3] - outG[base - sx3] + outR[base + sx3] - outG[base + sx3]) >> 1); 0628 CLIP(tmp, outR[base]); 0629 } 0630 for (j3 = 6; j3 < sx3 - 3; j3 += 6) 0631 { /* B-points */ 0632 base = i3 + j3; 0633 tmp = outG[base] + ((outR[base - sx3 - 3] - outG[base - sx3 - 3] + outR[base - sx3 + 3] - 0634 outG[base - sx3 + 3] + outR[base + sx3 - 3] - outG[base + sx3 - 3] + 0635 outR[base + sx3 + 3] - outG[base + sx3 + 3]) >> 0636 2); 0637 CLIP(tmp, outR[base]); 0638 } 0639 } 0640 0641 /* process BLUE channel */ 0642 for (i = 0, i3 = 0; i < sy * sx; i += (sx << 1), i3 += (sx3 << 1)) 0643 { 0644 for (j = 1, j3 = 3; j < sx - 2; j += 2, j3 += 6) 0645 { 0646 base = i3 + j3; 0647 tmp = outG[base] + ((outB[base - 3] - outG[base - 3] + outB[base + 3] - outG[base + 3]) >> 1); 0648 CLIP(tmp, outB[base]); 0649 } 0650 } 0651 for (i3 = sx3; i3 < (sy - 1) * sx3; i3 += (sx3 << 1)) 0652 { 0653 for (j3 = 0; j3 < sx3 - 3; j3 += 6) 0654 { 0655 base = i3 + j3; 0656 tmp = 0657 outG[base] + ((outB[base - sx3] - outG[base - sx3] + outB[base + sx3] - outG[base + sx3]) >> 1); 0658 CLIP(tmp, outB[base]); 0659 } 0660 for (j3 = 3; j3 < sx3 - 6; j3 += 6) 0661 { 0662 base = i3 + j3; 0663 tmp = outG[base] + ((outB[base - sx3 - 3] - outG[base - sx3 - 3] + outB[base - sx3 + 3] - 0664 outG[base - sx3 + 3] + outB[base + sx3 - 3] - outG[base + sx3 - 3] + 0665 outB[base + sx3 + 3] - outG[base + sx3 + 3]) >> 0666 2); 0667 CLIP(tmp, outB[base]); 0668 } 0669 } 0670 break; 0671 } 0672 0673 ClearBorders(rgb, sx, sy, 3); 0674 0675 return DC1394_SUCCESS; 0676 } 0677 0678 /* coriander's Bayer decoding */ 0679 dc1394error_t dc1394_bayer_Downsample(const uint8_t *bayer, uint8_t *rgb, int sx, int sy, int tile) 0680 { 0681 uint8_t *outR, *outG, *outB; 0682 register int i, j; 0683 int tmp; 0684 0685 switch (tile) 0686 { 0687 case DC1394_COLOR_FILTER_GRBG: 0688 case DC1394_COLOR_FILTER_BGGR: 0689 outR = &rgb[0]; 0690 outG = &rgb[1]; 0691 outB = &rgb[2]; 0692 break; 0693 case DC1394_COLOR_FILTER_GBRG: 0694 case DC1394_COLOR_FILTER_RGGB: 0695 outR = &rgb[2]; 0696 outG = &rgb[1]; 0697 outB = &rgb[0]; 0698 break; 0699 default: 0700 return DC1394_INVALID_COLOR_FILTER; 0701 } 0702 0703 switch (tile) 0704 { 0705 case DC1394_COLOR_FILTER_GRBG: 0706 case DC1394_COLOR_FILTER_GBRG: 0707 for (i = 0; i < sy * sx; i += (sx << 1)) 0708 { 0709 for (j = 0; j < sx; j += 2) 0710 { 0711 tmp = ((bayer[i + j] + bayer[i + sx + j + 1]) >> 1); 0712 CLIP(tmp, outG[((i >> 2) + (j >> 1)) * 3]); 0713 tmp = bayer[i + j + 1]; 0714 CLIP(tmp, outR[((i >> 2) + (j >> 1)) * 3]); 0715 tmp = bayer[i + sx + j]; 0716 CLIP(tmp, outB[((i >> 2) + (j >> 1)) * 3]); 0717 } 0718 } 0719 break; 0720 case DC1394_COLOR_FILTER_BGGR: 0721 case DC1394_COLOR_FILTER_RGGB: 0722 for (i = 0; i < sy * sx; i += (sx << 1)) 0723 { 0724 for (j = 0; j < sx; j += 2) 0725 { 0726 tmp = ((bayer[i + sx + j] + bayer[i + j + 1]) >> 1); 0727 CLIP(tmp, outG[((i >> 2) + (j >> 1)) * 3]); 0728 tmp = bayer[i + sx + j + 1]; 0729 CLIP(tmp, outR[((i >> 2) + (j >> 1)) * 3]); 0730 tmp = bayer[i + j]; 0731 CLIP(tmp, outB[((i >> 2) + (j >> 1)) * 3]); 0732 } 0733 } 0734 break; 0735 } 0736 0737 return DC1394_SUCCESS; 0738 } 0739 0740 /* this is the method used inside AVT cameras. See AVT docs. */ 0741 dc1394error_t dc1394_bayer_Simple(const uint8_t *bayer, uint8_t *rgb, int sx, int sy, int tile) 0742 { 0743 const int bayerStep = sx; 0744 const int rgbStep = 3 * sx; 0745 int width = sx; 0746 int height = sy; 0747 int blue = tile == DC1394_COLOR_FILTER_BGGR || tile == DC1394_COLOR_FILTER_GBRG ? -1 : 1; 0748 int start_with_green = tile == DC1394_COLOR_FILTER_GBRG || tile == DC1394_COLOR_FILTER_GRBG; 0749 int i, imax, iinc; 0750 0751 if ((tile > DC1394_COLOR_FILTER_MAX) || (tile < DC1394_COLOR_FILTER_MIN)) 0752 return DC1394_INVALID_COLOR_FILTER; 0753 0754 /* add black border */ 0755 imax = sx * sy * 3; 0756 for (i = sx * (sy - 1) * 3; i < imax; i++) 0757 { 0758 rgb[i] = 0; 0759 } 0760 iinc = (sx - 1) * 3; 0761 for (i = (sx - 1) * 3; i < imax; i += iinc) 0762 { 0763 rgb[i++] = 0; 0764 rgb[i++] = 0; 0765 rgb[i++] = 0; 0766 } 0767 0768 rgb += 1; 0769 width -= 1; 0770 height -= 1; 0771 0772 for (; height--; bayer += bayerStep, rgb += rgbStep) 0773 { 0774 const uint8_t *bayerEnd = bayer + width; 0775 0776 if (start_with_green) 0777 { 0778 rgb[-blue] = bayer[1]; 0779 rgb[0] = (bayer[0] + bayer[bayerStep + 1] + 1) >> 1; 0780 rgb[blue] = bayer[bayerStep]; 0781 bayer++; 0782 rgb += 3; 0783 } 0784 0785 if (blue > 0) 0786 { 0787 for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) 0788 { 0789 rgb[-1] = bayer[0]; 0790 rgb[0] = (bayer[1] + bayer[bayerStep] + 1) >> 1; 0791 rgb[1] = bayer[bayerStep + 1]; 0792 0793 rgb[2] = bayer[2]; 0794 rgb[3] = (bayer[1] + bayer[bayerStep + 2] + 1) >> 1; 0795 rgb[4] = bayer[bayerStep + 1]; 0796 } 0797 } 0798 else 0799 { 0800 for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) 0801 { 0802 rgb[1] = bayer[0]; 0803 rgb[0] = (bayer[1] + bayer[bayerStep] + 1) >> 1; 0804 rgb[-1] = bayer[bayerStep + 1]; 0805 0806 rgb[4] = bayer[2]; 0807 rgb[3] = (bayer[1] + bayer[bayerStep + 2] + 1) >> 1; 0808 rgb[2] = bayer[bayerStep + 1]; 0809 } 0810 } 0811 0812 if (bayer < bayerEnd) 0813 { 0814 rgb[-blue] = bayer[0]; 0815 rgb[0] = (bayer[1] + bayer[bayerStep] + 1) >> 1; 0816 rgb[blue] = bayer[bayerStep + 1]; 0817 bayer++; 0818 rgb += 3; 0819 } 0820 0821 bayer -= width; 0822 rgb -= width * 3; 0823 0824 blue = -blue; 0825 start_with_green = !start_with_green; 0826 } 0827 0828 return DC1394_SUCCESS; 0829 } 0830 0831 /* 16-bits versions */ 0832 0833 dc1394error_t dc1394_bayer16_RGBX_NearestNeighbor(const uint16_t *bayer, uint16_t *rgbx, int sx, int sy, int tile) 0834 { 0835 const int bayerStep = sx; 0836 const int rgbStep = 4 * sx; 0837 int width = sx; 0838 int height = sy; 0839 int blue = (tile == DC1394_COLOR_FILTER_BGGR || tile == DC1394_COLOR_FILTER_GBRG) ? -1 : 1; 0840 int start_with_green = (tile == DC1394_COLOR_FILTER_GBRG || tile == DC1394_COLOR_FILTER_GRBG) ? 1 : 0; 0841 0842 if ((tile > DC1394_COLOR_FILTER_MAX) || (tile < DC1394_COLOR_FILTER_MIN)) 0843 return DC1394_INVALID_COLOR_FILTER; 0844 0845 for (; height--; bayer += bayerStep, rgbx += rgbStep) 0846 { 0847 const uint16_t *bayerEnd = bayer + width; 0848 0849 if (start_with_green) 0850 { 0851 rgbx[-blue] = bayer[1]; 0852 rgbx[0] = bayer[bayerStep + 1]; 0853 rgbx[blue] = bayer[bayerStep]; 0854 rgbx[2] = 0xFFFF; 0855 bayer++; 0856 rgbx += 4; 0857 } 0858 0859 if (blue > 0) 0860 { 0861 for (; bayer <= bayerEnd - 2; bayer += 2, rgbx += 8) 0862 { 0863 rgbx[-1] = bayer[0]; 0864 rgbx[0] = bayer[1]; 0865 rgbx[1] = bayer[bayerStep + 1]; 0866 rgbx[2] = 0xFFFF; 0867 0868 rgbx[3] = bayer[2]; 0869 rgbx[4] = bayer[bayerStep + 2]; 0870 rgbx[5] = bayer[bayerStep + 1]; 0871 rgbx[6] = 0xFFFF; 0872 } 0873 } 0874 else 0875 { 0876 for (; bayer <= bayerEnd - 2; bayer += 2, rgbx += 8) 0877 { 0878 rgbx[2] = 0xFFFF; 0879 rgbx[1] = bayer[0]; 0880 rgbx[0] = bayer[1]; 0881 rgbx[-1] = bayer[bayerStep + 1]; 0882 0883 rgbx[6] = 0xFFFF; 0884 rgbx[5] = bayer[2]; 0885 rgbx[4] = bayer[bayerStep + 2]; 0886 rgbx[3] = bayer[bayerStep + 1]; 0887 } 0888 } 0889 0890 if (bayer < bayerEnd) 0891 { 0892 rgbx[-blue] = bayer[0]; 0893 rgbx[0] = bayer[1]; 0894 rgbx[blue] = bayer[bayerStep + 1]; 0895 rgbx[2] = 0xFFFF; 0896 bayer++; 0897 rgbx += 4; 0898 } 0899 0900 bayer -= width; 0901 rgbx -= width * 4; 0902 0903 blue = -blue; 0904 start_with_green = !start_with_green; 0905 } 0906 0907 return DC1394_SUCCESS; 0908 } 0909 0910 /* insprired by OpenCV's Bayer decoding */ 0911 dc1394error_t dc1394_bayer_NearestNeighbor_uint16(const uint16_t *bayer, uint16_t *rgb, int sx, 0912 int sy, int tile, int bits) 0913 { 0914 (void)bits; 0915 const int bayerStep = sx; 0916 const int rgbStep = 3 * sx; 0917 int width = sx; 0918 int height = sy; 0919 int blue = tile == DC1394_COLOR_FILTER_BGGR || tile == DC1394_COLOR_FILTER_GBRG ? -1 : 1; 0920 int start_with_green = tile == DC1394_COLOR_FILTER_GBRG || tile == DC1394_COLOR_FILTER_GRBG; 0921 int i, iinc, imax; 0922 0923 if ((tile > DC1394_COLOR_FILTER_MAX) || (tile < DC1394_COLOR_FILTER_MIN)) 0924 return DC1394_INVALID_COLOR_FILTER; 0925 0926 /* add black border */ 0927 imax = sx * sy * 3; 0928 for (i = sx * (sy - 1) * 3; i < imax; i++) 0929 { 0930 rgb[i] = 0; 0931 } 0932 iinc = (sx - 1) * 3; 0933 for (i = (sx - 1) * 3; i < imax; i += iinc) 0934 { 0935 rgb[i++] = 0; 0936 rgb[i++] = 0; 0937 rgb[i++] = 0; 0938 } 0939 0940 rgb += 1; 0941 height -= 1; 0942 width -= 1; 0943 0944 for (; height--; bayer += bayerStep, rgb += rgbStep) 0945 { 0946 const uint16_t *bayerEnd = bayer + width; 0947 0948 if (start_with_green) 0949 { 0950 rgb[-blue] = bayer[1]; 0951 rgb[0] = bayer[bayerStep + 1]; 0952 rgb[blue] = bayer[bayerStep]; 0953 bayer++; 0954 rgb += 3; 0955 } 0956 0957 if (blue > 0) 0958 { 0959 for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) 0960 { 0961 rgb[-1] = bayer[0]; 0962 rgb[0] = bayer[1]; 0963 rgb[1] = bayer[bayerStep + 1]; 0964 0965 rgb[2] = bayer[2]; 0966 rgb[3] = bayer[bayerStep + 2]; 0967 rgb[4] = bayer[bayerStep + 1]; 0968 } 0969 } 0970 else 0971 { 0972 for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) 0973 { 0974 rgb[1] = bayer[0]; 0975 rgb[0] = bayer[1]; 0976 rgb[-1] = bayer[bayerStep + 1]; 0977 0978 rgb[4] = bayer[2]; 0979 rgb[3] = bayer[bayerStep + 2]; 0980 rgb[2] = bayer[bayerStep + 1]; 0981 } 0982 } 0983 0984 if (bayer < bayerEnd) 0985 { 0986 rgb[-blue] = bayer[0]; 0987 rgb[0] = bayer[1]; 0988 rgb[blue] = bayer[bayerStep + 1]; 0989 bayer++; 0990 rgb += 3; 0991 } 0992 0993 bayer -= width; 0994 rgb -= width * 3; 0995 0996 blue = -blue; 0997 start_with_green = !start_with_green; 0998 } 0999 1000 return DC1394_SUCCESS; 1001 } 1002 /* OpenCV's Bayer decoding */ 1003 dc1394error_t dc1394_bayer_Bilinear_uint16(const uint16_t *bayer, uint16_t *rgb, int sx, int sy, 1004 int tile, int bits) 1005 { 1006 (void)bits; 1007 const int bayerStep = sx; 1008 const int rgbStep = 3 * sx; 1009 int width = sx; 1010 int height = sy; 1011 int blue = tile == DC1394_COLOR_FILTER_BGGR || tile == DC1394_COLOR_FILTER_GBRG ? -1 : 1; 1012 int start_with_green = tile == DC1394_COLOR_FILTER_GBRG || tile == DC1394_COLOR_FILTER_GRBG; 1013 1014 if ((tile > DC1394_COLOR_FILTER_MAX) || (tile < DC1394_COLOR_FILTER_MIN)) 1015 return DC1394_INVALID_COLOR_FILTER; 1016 1017 rgb += rgbStep + 3 + 1; 1018 height -= 2; 1019 width -= 2; 1020 1021 for (; height--; bayer += bayerStep, rgb += rgbStep) 1022 { 1023 int t0, t1; 1024 const uint16_t *bayerEnd = bayer + width; 1025 1026 if (start_with_green) 1027 { 1028 /* OpenCV has a bug in the next line, which was 1029 t0 = (bayer[0] + bayer[bayerStep * 2] + 1) >> 1; */ 1030 t0 = (bayer[1] + bayer[bayerStep * 2 + 1] + 1) >> 1; 1031 t1 = (bayer[bayerStep] + bayer[bayerStep + 2] + 1) >> 1; 1032 rgb[-blue] = (uint16_t)t0; 1033 rgb[0] = bayer[bayerStep + 1]; 1034 rgb[blue] = (uint16_t)t1; 1035 bayer++; 1036 rgb += 3; 1037 } 1038 1039 if (blue > 0) 1040 { 1041 for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) 1042 { 1043 t0 = (bayer[0] + bayer[2] + bayer[bayerStep * 2] + bayer[bayerStep * 2 + 2] + 2) >> 2; 1044 t1 = (bayer[1] + bayer[bayerStep] + bayer[bayerStep + 2] + bayer[bayerStep * 2 + 1] + 2) >> 2; 1045 rgb[-1] = (uint16_t)t0; 1046 rgb[0] = (uint16_t)t1; 1047 rgb[1] = bayer[bayerStep + 1]; 1048 1049 t0 = (bayer[2] + bayer[bayerStep * 2 + 2] + 1) >> 1; 1050 t1 = (bayer[bayerStep + 1] + bayer[bayerStep + 3] + 1) >> 1; 1051 rgb[2] = (uint16_t)t0; 1052 rgb[3] = bayer[bayerStep + 2]; 1053 rgb[4] = (uint16_t)t1; 1054 } 1055 } 1056 else 1057 { 1058 for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) 1059 { 1060 t0 = (bayer[0] + bayer[2] + bayer[bayerStep * 2] + bayer[bayerStep * 2 + 2] + 2) >> 2; 1061 t1 = (bayer[1] + bayer[bayerStep] + bayer[bayerStep + 2] + bayer[bayerStep * 2 + 1] + 2) >> 2; 1062 rgb[1] = (uint16_t)t0; 1063 rgb[0] = (uint16_t)t1; 1064 rgb[-1] = bayer[bayerStep + 1]; 1065 1066 t0 = (bayer[2] + bayer[bayerStep * 2 + 2] + 1) >> 1; 1067 t1 = (bayer[bayerStep + 1] + bayer[bayerStep + 3] + 1) >> 1; 1068 rgb[4] = (uint16_t)t0; 1069 rgb[3] = bayer[bayerStep + 2]; 1070 rgb[2] = (uint16_t)t1; 1071 } 1072 } 1073 1074 if (bayer < bayerEnd) 1075 { 1076 t0 = (bayer[0] + bayer[2] + bayer[bayerStep * 2] + bayer[bayerStep * 2 + 2] + 2) >> 2; 1077 t1 = (bayer[1] + bayer[bayerStep] + bayer[bayerStep + 2] + bayer[bayerStep * 2 + 1] + 2) >> 2; 1078 rgb[-blue] = (uint16_t)t0; 1079 rgb[0] = (uint16_t)t1; 1080 rgb[blue] = bayer[bayerStep + 1]; 1081 bayer++; 1082 rgb += 3; 1083 } 1084 1085 bayer -= width; 1086 rgb -= width * 3; 1087 1088 blue = -blue; 1089 start_with_green = !start_with_green; 1090 } 1091 1092 return DC1394_SUCCESS; 1093 } 1094 1095 /* High-Quality Linear Interpolation For Demosaicing Of 1096 Bayer-Patterned Color Images, by Henrique S. Malvar, Li-wei He, and 1097 Ross Cutler, in ICASSP'04 */ 1098 dc1394error_t dc1394_bayer_HQLinear_uint16(const uint16_t *bayer, uint16_t *rgb, int sx, int sy, 1099 int tile, int bits) 1100 { 1101 const int bayerStep = sx; 1102 const int rgbStep = 3 * sx; 1103 int width = sx; 1104 int height = sy; 1105 /* 1106 the two letters of the OpenCV name are respectively 1107 the 4th and 3rd letters from the blinky name, 1108 and we also have to switch R and B (OpenCV is BGR) 1109 1110 CV_BayerBG2BGR <-> DC1394_COLOR_FILTER_BGGR 1111 CV_BayerGB2BGR <-> DC1394_COLOR_FILTER_GBRG 1112 CV_BayerGR2BGR <-> DC1394_COLOR_FILTER_GRBG 1113 1114 int blue = tile == CV_BayerBG2BGR || tile == CV_BayerGB2BGR ? -1 : 1; 1115 int start_with_green = tile == CV_BayerGB2BGR || tile == CV_BayerGR2BGR; 1116 */ 1117 int blue = tile == DC1394_COLOR_FILTER_BGGR || tile == DC1394_COLOR_FILTER_GBRG ? -1 : 1; 1118 int start_with_green = tile == DC1394_COLOR_FILTER_GBRG || tile == DC1394_COLOR_FILTER_GRBG; 1119 1120 if ((tile > DC1394_COLOR_FILTER_MAX) || (tile < DC1394_COLOR_FILTER_MIN)) 1121 return DC1394_INVALID_COLOR_FILTER; 1122 1123 ClearBorders_uint16(rgb, sx, sy, 2); 1124 rgb += 2 * rgbStep + 6 + 1; 1125 height -= 4; 1126 width -= 4; 1127 1128 /* We begin with a (+1 line,+1 column) offset with respect to bilinear decoding, so start_with_green is the same, but blue is opposite */ 1129 blue = -blue; 1130 1131 for (; height--; bayer += bayerStep, rgb += rgbStep) 1132 { 1133 int t0, t1; 1134 const uint16_t *bayerEnd = bayer + width; 1135 const int bayerStep2 = bayerStep * 2; 1136 const int bayerStep3 = bayerStep * 3; 1137 const int bayerStep4 = bayerStep * 4; 1138 1139 if (start_with_green) 1140 { 1141 /* at green pixel */ 1142 rgb[0] = bayer[bayerStep2 + 2]; 1143 t0 = rgb[0] * 5 + ((bayer[bayerStep + 2] + bayer[bayerStep3 + 2]) << 2) - bayer[2] - bayer[bayerStep + 1] - 1144 bayer[bayerStep + 3] - bayer[bayerStep3 + 1] - bayer[bayerStep3 + 3] - bayer[bayerStep4 + 2] + 1145 ((bayer[bayerStep2] + bayer[bayerStep2 + 4] + 1) >> 1); 1146 t1 = rgb[0] * 5 + ((bayer[bayerStep2 + 1] + bayer[bayerStep2 + 3]) << 2) - bayer[bayerStep2] - 1147 bayer[bayerStep + 1] - bayer[bayerStep + 3] - bayer[bayerStep3 + 1] - bayer[bayerStep3 + 3] - 1148 bayer[bayerStep2 + 4] + ((bayer[2] + bayer[bayerStep4 + 2] + 1) >> 1); 1149 t0 = (t0 + 4) >> 3; 1150 CLIP16(t0, rgb[-blue], bits); 1151 t1 = (t1 + 4) >> 3; 1152 CLIP16(t1, rgb[blue], bits); 1153 bayer++; 1154 rgb += 3; 1155 } 1156 1157 if (blue > 0) 1158 { 1159 for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) 1160 { 1161 /* B at B */ 1162 rgb[1] = bayer[bayerStep2 + 2]; 1163 /* R at B */ 1164 t0 = ((bayer[bayerStep + 1] + bayer[bayerStep + 3] + bayer[bayerStep3 + 1] + bayer[bayerStep3 + 3]) 1165 << 1) - 1166 (((bayer[2] + bayer[bayerStep2] + bayer[bayerStep2 + 4] + bayer[bayerStep4 + 2]) * 3 + 1) >> 1) + 1167 rgb[1] * 6; 1168 /* G at B */ 1169 t1 = ((bayer[bayerStep + 2] + bayer[bayerStep2 + 1] + bayer[bayerStep2 + 3] + bayer[bayerStep * 3 + 2]) 1170 << 1) - 1171 (bayer[2] + bayer[bayerStep2] + bayer[bayerStep2 + 4] + bayer[bayerStep4 + 2]) + (rgb[1] << 2); 1172 t0 = (t0 + 4) >> 3; 1173 CLIP16(t0, rgb[-1], bits); 1174 t1 = (t1 + 4) >> 3; 1175 CLIP16(t1, rgb[0], bits); 1176 /* at green pixel */ 1177 rgb[3] = bayer[bayerStep2 + 3]; 1178 t0 = rgb[3] * 5 + ((bayer[bayerStep + 3] + bayer[bayerStep3 + 3]) << 2) - bayer[3] - 1179 bayer[bayerStep + 2] - bayer[bayerStep + 4] - bayer[bayerStep3 + 2] - bayer[bayerStep3 + 4] - 1180 bayer[bayerStep4 + 3] + ((bayer[bayerStep2 + 1] + bayer[bayerStep2 + 5] + 1) >> 1); 1181 t1 = rgb[3] * 5 + ((bayer[bayerStep2 + 2] + bayer[bayerStep2 + 4]) << 2) - bayer[bayerStep2 + 1] - 1182 bayer[bayerStep + 2] - bayer[bayerStep + 4] - bayer[bayerStep3 + 2] - bayer[bayerStep3 + 4] - 1183 bayer[bayerStep2 + 5] + ((bayer[3] + bayer[bayerStep4 + 3] + 1) >> 1); 1184 t0 = (t0 + 4) >> 3; 1185 CLIP16(t0, rgb[2], bits); 1186 t1 = (t1 + 4) >> 3; 1187 CLIP16(t1, rgb[4], bits); 1188 } 1189 } 1190 else 1191 { 1192 for (; bayer <= bayerEnd - 2; bayer += 2, rgb += 6) 1193 { 1194 /* R at R */ 1195 rgb[-1] = bayer[bayerStep2 + 2]; 1196 /* B at R */ 1197 t0 = ((bayer[bayerStep + 1] + bayer[bayerStep + 3] + bayer[bayerStep * 3 + 1] + bayer[bayerStep3 + 3]) 1198 << 1) - 1199 (((bayer[2] + bayer[bayerStep2] + bayer[bayerStep2 + 4] + bayer[bayerStep4 + 2]) * 3 + 1) >> 1) + 1200 rgb[-1] * 6; 1201 /* G at R */ 1202 t1 = ((bayer[bayerStep + 2] + bayer[bayerStep2 + 1] + bayer[bayerStep2 + 3] + bayer[bayerStep3 + 2]) 1203 << 1) - 1204 (bayer[2] + bayer[bayerStep2] + bayer[bayerStep2 + 4] + bayer[bayerStep4 + 2]) + (rgb[-1] << 2); 1205 t0 = (t0 + 4) >> 3; 1206 CLIP16(t0, rgb[1], bits); 1207 t1 = (t1 + 4) >> 3; 1208 CLIP16(t1, rgb[0], bits); 1209 1210 /* at green pixel */ 1211 rgb[3] = bayer[bayerStep2 + 3]; 1212 t0 = rgb[3] * 5 + ((bayer[bayerStep + 3] + bayer[bayerStep3 + 3]) << 2) - bayer[3] - 1213 bayer[bayerStep + 2] - bayer[bayerStep + 4] - bayer[bayerStep3 + 2] - bayer[bayerStep3 + 4] - 1214 bayer[bayerStep4 + 3] + ((bayer[bayerStep2 + 1] + bayer[bayerStep2 + 5] + 1) >> 1); 1215 t1 = rgb[3] * 5 + ((bayer[bayerStep2 + 2] + bayer[bayerStep2 + 4]) << 2) - bayer[bayerStep2 + 1] - 1216 bayer[bayerStep + 2] - bayer[bayerStep + 4] - bayer[bayerStep3 + 2] - bayer[bayerStep3 + 4] - 1217 bayer[bayerStep2 + 5] + ((bayer[3] + bayer[bayerStep4 + 3] + 1) >> 1); 1218 t0 = (t0 + 4) >> 3; 1219 CLIP16(t0, rgb[4], bits); 1220 t1 = (t1 + 4) >> 3; 1221 CLIP16(t1, rgb[2], bits); 1222 } 1223 } 1224 1225 if (bayer < bayerEnd) 1226 { 1227 /* B at B */ 1228 rgb[blue] = bayer[bayerStep2 + 2]; 1229 /* R at B */ 1230 t0 = ((bayer[bayerStep + 1] + bayer[bayerStep + 3] + bayer[bayerStep3 + 1] + bayer[bayerStep3 + 3]) << 1) - 1231 (((bayer[2] + bayer[bayerStep2] + bayer[bayerStep2 + 4] + bayer[bayerStep4 + 2]) * 3 + 1) >> 1) + 1232 rgb[blue] * 6; 1233 /* G at B */ 1234 t1 = (((bayer[bayerStep + 2] + bayer[bayerStep2 + 1] + bayer[bayerStep2 + 3] + bayer[bayerStep3 + 2])) 1235 << 1) - 1236 (bayer[2] + bayer[bayerStep2] + bayer[bayerStep2 + 4] + bayer[bayerStep4 + 2]) + (rgb[blue] << 2); 1237 t0 = (t0 + 4) >> 3; 1238 CLIP16(t0, rgb[-blue], bits); 1239 t1 = (t1 + 4) >> 3; 1240 CLIP16(t1, rgb[0], bits); 1241 bayer++; 1242 rgb += 3; 1243 } 1244 1245 bayer -= width; 1246 rgb -= width * 3; 1247 1248 blue = -blue; 1249 start_with_green = !start_with_green; 1250 } 1251 1252 return DC1394_SUCCESS; 1253 } 1254 1255 /* coriander's Bayer decoding */ 1256 dc1394error_t dc1394_bayer_EdgeSense_uint16(const uint16_t *bayer, uint16_t *rgb, int sx, int sy, 1257 int tile, int bits) 1258 { 1259 uint16_t *outR, *outG, *outB; 1260 register int i3, j3, base; 1261 int i, j; 1262 int dh, dv; 1263 int tmp; 1264 int sx3 = sx * 3; 1265 1266 /* sx and sy should be even */ 1267 switch (tile) 1268 { 1269 case DC1394_COLOR_FILTER_GRBG: 1270 case DC1394_COLOR_FILTER_BGGR: 1271 outR = &rgb[0]; 1272 outG = &rgb[1]; 1273 outB = &rgb[2]; 1274 break; 1275 case DC1394_COLOR_FILTER_GBRG: 1276 case DC1394_COLOR_FILTER_RGGB: 1277 outR = &rgb[2]; 1278 outG = &rgb[1]; 1279 outB = &rgb[0]; 1280 break; 1281 default: 1282 return DC1394_INVALID_COLOR_FILTER; 1283 } 1284 1285 switch (tile) 1286 { 1287 case DC1394_COLOR_FILTER_GRBG: 1288 case DC1394_COLOR_FILTER_GBRG: 1289 /* copy original RGB data to output images */ 1290 for (i = 0, i3 = 0; i < sy * sx; i += (sx << 1), i3 += (sx3 << 1)) 1291 { 1292 for (j = 0, j3 = 0; j < sx; j += 2, j3 += 6) 1293 { 1294 base = i3 + j3; 1295 outG[base] = bayer[i + j]; 1296 outG[base + sx3 + 3] = bayer[i + j + sx + 1]; 1297 outR[base + 3] = bayer[i + j + 1]; 1298 outB[base + sx3] = bayer[i + j + sx]; 1299 } 1300 } 1301 /* process GREEN channel */ 1302 for (i3 = 3 * sx3; i3 < (sy - 2) * sx3; i3 += (sx3 << 1)) 1303 { 1304 for (j3 = 6; j3 < sx3 - 9; j3 += 6) 1305 { 1306 base = i3 + j3; 1307 dh = abs(((outB[base - 6] + outB[base + 6]) >> 1) - outB[base]); 1308 dv = abs(((outB[base - (sx3 << 1)] + outB[base + (sx3 << 1)]) >> 1) - outB[base]); 1309 tmp = (((outG[base - 3] + outG[base + 3]) >> 1) * (dh <= dv) + 1310 ((outG[base - sx3] + outG[base + sx3]) >> 1) * (dh > dv)); 1311 CLIP16(tmp, outG[base], bits); 1312 } 1313 } 1314 1315 for (i3 = 2 * sx3; i3 < (sy - 3) * sx3; i3 += (sx3 << 1)) 1316 { 1317 for (j3 = 9; j3 < sx3 - 6; j3 += 6) 1318 { 1319 base = i3 + j3; 1320 dh = abs(((outR[base - 6] + outR[base + 6]) >> 1) - outR[base]); 1321 dv = abs(((outR[base - (sx3 << 1)] + outR[base + (sx3 << 1)]) >> 1) - outR[base]); 1322 tmp = (((outG[base - 3] + outG[base + 3]) >> 1) * (dh <= dv) + 1323 ((outG[base - sx3] + outG[base + sx3]) >> 1) * (dh > dv)); 1324 CLIP16(tmp, outG[base], bits); 1325 } 1326 } 1327 /* process RED channel */ 1328 for (i3 = 0; i3 < (sy - 1) * sx3; i3 += (sx3 << 1)) 1329 { 1330 for (j3 = 6; j3 < sx3 - 3; j3 += 6) 1331 { 1332 base = i3 + j3; 1333 tmp = outG[base] + ((outR[base - 3] - outG[base - 3] + outR[base + 3] - outG[base + 3]) >> 1); 1334 CLIP16(tmp, outR[base], bits); 1335 } 1336 } 1337 for (i3 = sx3; i3 < (sy - 2) * sx3; i3 += (sx3 << 1)) 1338 { 1339 for (j3 = 3; j3 < sx3; j3 += 6) 1340 { 1341 base = i3 + j3; 1342 tmp = 1343 outG[base] + ((outR[base - sx3] - outG[base - sx3] + outR[base + sx3] - outG[base + sx3]) >> 1); 1344 CLIP16(tmp, outR[base], bits); 1345 } 1346 for (j3 = 6; j3 < sx3 - 3; j3 += 6) 1347 { 1348 base = i3 + j3; 1349 tmp = outG[base] + ((outR[base - sx3 - 3] - outG[base - sx3 - 3] + outR[base - sx3 + 3] - 1350 outG[base - sx3 + 3] + outR[base + sx3 - 3] - outG[base + sx3 - 3] + 1351 outR[base + sx3 + 3] - outG[base + sx3 + 3]) >> 1352 2); 1353 CLIP16(tmp, outR[base], bits); 1354 } 1355 } 1356 1357 /* process BLUE channel */ 1358 for (i3 = sx3; i3 < sy * sx3; i3 += (sx3 << 1)) 1359 { 1360 for (j3 = 3; j3 < sx3 - 6; j3 += 6) 1361 { 1362 base = i3 + j3; 1363 tmp = outG[base] + ((outB[base - 3] - outG[base - 3] + outB[base + 3] - outG[base + 3]) >> 1); 1364 CLIP16(tmp, outB[base], bits); 1365 } 1366 } 1367 for (i3 = 2 * sx3; i3 < (sy - 1) * sx3; i3 += (sx3 << 1)) 1368 { 1369 for (j3 = 0; j3 < sx3 - 3; j3 += 6) 1370 { 1371 base = i3 + j3; 1372 tmp = 1373 outG[base] + ((outB[base - sx3] - outG[base - sx3] + outB[base + sx3] - outG[base + sx3]) >> 1); 1374 CLIP16(tmp, outB[base], bits); 1375 } 1376 for (j3 = 3; j3 < sx3 - 6; j3 += 6) 1377 { 1378 base = i3 + j3; 1379 tmp = outG[base] + ((outB[base - sx3 - 3] - outG[base - sx3 - 3] + outB[base - sx3 + 3] - 1380 outG[base - sx3 + 3] + outB[base + sx3 - 3] - outG[base + sx3 - 3] + 1381 outB[base + sx3 + 3] - outG[base + sx3 + 3]) >> 1382 2); 1383 CLIP16(tmp, outB[base], bits); 1384 } 1385 } 1386 break; 1387 1388 case DC1394_COLOR_FILTER_BGGR: 1389 case DC1394_COLOR_FILTER_RGGB: 1390 /* copy original RGB data to output images */ 1391 for (i = 0, i3 = 0; i < sy * sx; i += (sx << 1), i3 += (sx3 << 1)) 1392 { 1393 for (j = 0, j3 = 0; j < sx; j += 2, j3 += 6) 1394 { 1395 base = i3 + j3; 1396 outB[base] = bayer[i + j]; 1397 outR[base + sx3 + 3] = bayer[i + sx + (j + 1)]; 1398 outG[base + 3] = bayer[i + j + 1]; 1399 outG[base + sx3] = bayer[i + sx + j]; 1400 } 1401 } 1402 /* process GREEN channel */ 1403 for (i3 = 2 * sx3; i3 < (sy - 2) * sx3; i3 += (sx3 << 1)) 1404 { 1405 for (j3 = 6; j3 < sx3 - 9; j3 += 6) 1406 { 1407 base = i3 + j3; 1408 dh = abs(((outB[base - 6] + outB[base + 6]) >> 1) - outB[base]); 1409 dv = abs(((outB[base - (sx3 << 1)] + outB[base + (sx3 << 1)]) >> 1) - outB[base]); 1410 tmp = (((outG[base - 3] + outG[base + 3]) >> 1) * (dh <= dv) + 1411 ((outG[base - sx3] + outG[base + sx3]) >> 1) * (dh > dv)); 1412 CLIP16(tmp, outG[base], bits); 1413 } 1414 } 1415 for (i3 = 3 * sx3; i3 < (sy - 3) * sx3; i3 += (sx3 << 1)) 1416 { 1417 for (j3 = 9; j3 < sx3 - 6; j3 += 6) 1418 { 1419 base = i3 + j3; 1420 dh = abs(((outR[base - 6] + outR[base + 6]) >> 1) - outR[base]); 1421 dv = abs(((outR[base - (sx3 << 1)] + outR[base + (sx3 << 1)]) >> 1) - outR[base]); 1422 tmp = (((outG[base - 3] + outG[base + 3]) >> 1) * (dh <= dv) + 1423 ((outG[base - sx3] + outG[base + sx3]) >> 1) * (dh > dv)); 1424 CLIP16(tmp, outG[base], bits); 1425 } 1426 } 1427 /* process RED channel */ 1428 for (i3 = sx3; i3 < (sy - 1) * sx3; i3 += (sx3 << 1)) 1429 { /* G-points (1/2) */ 1430 for (j3 = 6; j3 < sx3 - 3; j3 += 6) 1431 { 1432 base = i3 + j3; 1433 tmp = outG[base] + ((outR[base - 3] - outG[base - 3] + outR[base + 3] - outG[base + 3]) >> 1); 1434 CLIP16(tmp, outR[base], bits); 1435 } 1436 } 1437 for (i3 = 2 * sx3; i3 < (sy - 2) * sx3; i3 += (sx3 << 1)) 1438 { 1439 for (j3 = 3; j3 < sx3; j3 += 6) 1440 { /* G-points (2/2) */ 1441 base = i3 + j3; 1442 tmp = 1443 outG[base] + ((outR[base - sx3] - outG[base - sx3] + outR[base + sx3] - outG[base + sx3]) >> 1); 1444 CLIP16(tmp, outR[base], bits); 1445 } 1446 for (j3 = 6; j3 < sx3 - 3; j3 += 6) 1447 { /* B-points */ 1448 base = i3 + j3; 1449 tmp = outG[base] + ((outR[base - sx3 - 3] - outG[base - sx3 - 3] + outR[base - sx3 + 3] - 1450 outG[base - sx3 + 3] + outR[base + sx3 - 3] - outG[base + sx3 - 3] + 1451 outR[base + sx3 + 3] - outG[base + sx3 + 3]) >> 1452 2); 1453 CLIP16(tmp, outR[base], bits); 1454 } 1455 } 1456 1457 /* process BLUE channel */ 1458 for (i = 0, i3 = 0; i < sy * sx; i += (sx << 1), i3 += (sx3 << 1)) 1459 { 1460 for (j = 1, j3 = 3; j < sx - 2; j += 2, j3 += 6) 1461 { 1462 base = i3 + j3; 1463 tmp = outG[base] + ((outB[base - 3] - outG[base - 3] + outB[base + 3] - outG[base + 3]) >> 1); 1464 CLIP16(tmp, outB[base], bits); 1465 } 1466 } 1467 for (i3 = sx3; i3 < (sy - 1) * sx3; i3 += (sx3 << 1)) 1468 { 1469 for (j3 = 0; j3 < sx3 - 3; j3 += 6) 1470 { 1471 base = i3 + j3; 1472 tmp = 1473 outG[base] + ((outB[base - sx3] - outG[base - sx3] + outB[base + sx3] - outG[base + sx3]) >> 1); 1474 CLIP16(tmp, outB[base], bits); 1475 } 1476 for (j3 = 3; j3 < sx3 - 6; j3 += 6) 1477 { 1478 base = i3 + j3; 1479 tmp = outG[base] + ((outB[base - sx3 - 3] - outG[base - sx3 - 3] + outB[base - sx3 + 3] - 1480 outG[base - sx3 + 3] + outB[base + sx3 - 3] - outG[base + sx3 - 3] + 1481 outB[base + sx3 + 3] - outG[base + sx3 + 3]) >> 1482 2); 1483 CLIP16(tmp, outB[base], bits); 1484 } 1485 } 1486 break; 1487 } 1488 1489 ClearBorders_uint16(rgb, sx, sy, 3); 1490 1491 return DC1394_SUCCESS; 1492 } 1493 1494 /* coriander's Bayer decoding */ 1495 dc1394error_t dc1394_bayer_Downsample_uint16(const uint16_t *bayer, uint16_t *rgb, int sx, int sy, 1496 int tile, int bits) 1497 { 1498 uint16_t *outR, *outG, *outB; 1499 register int i, j; 1500 int tmp; 1501 1502 switch (tile) 1503 { 1504 case DC1394_COLOR_FILTER_GRBG: 1505 case DC1394_COLOR_FILTER_BGGR: 1506 outR = &rgb[0]; 1507 outG = &rgb[1]; 1508 outB = &rgb[2]; 1509 break; 1510 case DC1394_COLOR_FILTER_GBRG: 1511 case DC1394_COLOR_FILTER_RGGB: 1512 outR = &rgb[2]; 1513 outG = &rgb[1]; 1514 outB = &rgb[0]; 1515 break; 1516 default: 1517 return DC1394_INVALID_COLOR_FILTER; 1518 } 1519 1520 switch (tile) 1521 { 1522 case DC1394_COLOR_FILTER_GRBG: 1523 case DC1394_COLOR_FILTER_GBRG: 1524 for (i = 0; i < sy * sx; i += (sx << 1)) 1525 { 1526 for (j = 0; j < sx; j += 2) 1527 { 1528 tmp = ((bayer[i + j] + bayer[i + sx + j + 1]) >> 1); 1529 CLIP16(tmp, outG[((i >> 2) + (j >> 1)) * 3], bits); 1530 tmp = bayer[i + sx + j + 1]; 1531 CLIP16(tmp, outR[((i >> 2) + (j >> 1)) * 3], bits); 1532 tmp = bayer[i + sx + j]; 1533 CLIP16(tmp, outB[((i >> 2) + (j >> 1)) * 3], bits); 1534 } 1535 } 1536 break; 1537 case DC1394_COLOR_FILTER_BGGR: 1538 case DC1394_COLOR_FILTER_RGGB: 1539 for (i = 0; i < sy * sx; i += (sx << 1)) 1540 { 1541 for (j = 0; j < sx; j += 2) 1542 { 1543 tmp = ((bayer[i + sx + j] + bayer[i + j + 1]) >> 1); 1544 CLIP16(tmp, outG[((i >> 2) + (j >> 1)) * 3], bits); 1545 tmp = bayer[i + sx + j + 1]; 1546 CLIP16(tmp, outR[((i >> 2) + (j >> 1)) * 3], bits); 1547 tmp = bayer[i + j]; 1548 CLIP16(tmp, outB[((i >> 2) + (j >> 1)) * 3], bits); 1549 } 1550 } 1551 break; 1552 } 1553 1554 return DC1394_SUCCESS; 1555 } 1556 1557 /* coriander's Bayer decoding */ 1558 dc1394error_t dc1394_bayer_Simple_uint16(const uint16_t *bayer, uint16_t *rgb, int sx, int sy, 1559 int tile, int bits) 1560 { 1561 uint16_t *outR, *outG, *outB; 1562 register int i, j; 1563 int tmp, base; 1564 1565 /* sx and sy should be even */ 1566 switch (tile) 1567 { 1568 case DC1394_COLOR_FILTER_GRBG: 1569 case DC1394_COLOR_FILTER_BGGR: 1570 outR = &rgb[0]; 1571 outG = &rgb[1]; 1572 outB = &rgb[2]; 1573 break; 1574 case DC1394_COLOR_FILTER_GBRG: 1575 case DC1394_COLOR_FILTER_RGGB: 1576 outR = &rgb[2]; 1577 outG = &rgb[1]; 1578 outB = &rgb[0]; 1579 break; 1580 default: 1581 return DC1394_INVALID_COLOR_FILTER; 1582 } 1583 1584 switch (tile) 1585 { 1586 case DC1394_COLOR_FILTER_GRBG: 1587 case DC1394_COLOR_FILTER_BGGR: 1588 outR = &rgb[0]; 1589 outG = &rgb[1]; 1590 outB = &rgb[2]; 1591 break; 1592 case DC1394_COLOR_FILTER_GBRG: 1593 case DC1394_COLOR_FILTER_RGGB: 1594 outR = &rgb[2]; 1595 outG = &rgb[1]; 1596 outB = &rgb[0]; 1597 break; 1598 default: 1599 outR = NULL; 1600 outG = NULL; 1601 outB = NULL; 1602 break; 1603 } 1604 1605 switch (tile) 1606 { 1607 case DC1394_COLOR_FILTER_GRBG: 1608 case DC1394_COLOR_FILTER_GBRG: 1609 for (i = 0; i < sy - 1; i += 2) 1610 { 1611 for (j = 0; j < sx - 1; j += 2) 1612 { 1613 base = i * sx + j; 1614 tmp = ((bayer[base] + bayer[base + sx + 1]) >> 1); 1615 CLIP16(tmp, outG[base * 3], bits); 1616 tmp = bayer[base + 1]; 1617 CLIP16(tmp, outR[base * 3], bits); 1618 tmp = bayer[base + sx]; 1619 CLIP16(tmp, outB[base * 3], bits); 1620 } 1621 } 1622 for (i = 0; i < sy - 1; i += 2) 1623 { 1624 for (j = 1; j < sx - 1; j += 2) 1625 { 1626 base = i * sx + j; 1627 tmp = ((bayer[base + 1] + bayer[base + sx]) >> 1); 1628 CLIP16(tmp, outG[(base)*3], bits); 1629 tmp = bayer[base]; 1630 CLIP16(tmp, outR[(base)*3], bits); 1631 tmp = bayer[base + 1 + sx]; 1632 CLIP16(tmp, outB[(base)*3], bits); 1633 } 1634 } 1635 for (i = 1; i < sy - 1; i += 2) 1636 { 1637 for (j = 0; j < sx - 1; j += 2) 1638 { 1639 base = i * sx + j; 1640 tmp = ((bayer[base + sx] + bayer[base + 1]) >> 1); 1641 CLIP16(tmp, outG[base * 3], bits); 1642 tmp = bayer[base + sx + 1]; 1643 CLIP16(tmp, outR[base * 3], bits); 1644 tmp = bayer[base]; 1645 CLIP16(tmp, outB[base * 3], bits); 1646 } 1647 } 1648 for (i = 1; i < sy - 1; i += 2) 1649 { 1650 for (j = 1; j < sx - 1; j += 2) 1651 { 1652 base = i * sx + j; 1653 tmp = ((bayer[base] + bayer[base + 1 + sx]) >> 1); 1654 CLIP16(tmp, outG[(base)*3], bits); 1655 tmp = bayer[base + sx]; 1656 CLIP16(tmp, outR[(base)*3], bits); 1657 tmp = bayer[base + 1]; 1658 CLIP16(tmp, outB[(base)*3], bits); 1659 } 1660 } 1661 break; 1662 case DC1394_COLOR_FILTER_BGGR: 1663 case DC1394_COLOR_FILTER_RGGB: 1664 for (i = 0; i < sy - 1; i += 2) 1665 { 1666 for (j = 0; j < sx - 1; j += 2) 1667 { 1668 base = i * sx + j; 1669 tmp = ((bayer[base + sx] + bayer[base + 1]) >> 1); 1670 CLIP16(tmp, outG[base * 3], bits); 1671 tmp = bayer[base + sx + 1]; 1672 CLIP16(tmp, outR[base * 3], bits); 1673 tmp = bayer[base]; 1674 CLIP16(tmp, outB[base * 3], bits); 1675 } 1676 } 1677 for (i = 1; i < sy - 1; i += 2) 1678 { 1679 for (j = 0; j < sx - 1; j += 2) 1680 { 1681 base = i * sx + j; 1682 tmp = ((bayer[base] + bayer[base + 1 + sx]) >> 1); 1683 CLIP16(tmp, outG[(base)*3], bits); 1684 tmp = bayer[base + 1]; 1685 CLIP16(tmp, outR[(base)*3], bits); 1686 tmp = bayer[base + sx]; 1687 CLIP16(tmp, outB[(base)*3], bits); 1688 } 1689 } 1690 for (i = 0; i < sy - 1; i += 2) 1691 { 1692 for (j = 1; j < sx - 1; j += 2) 1693 { 1694 base = i * sx + j; 1695 tmp = ((bayer[base] + bayer[base + sx + 1]) >> 1); 1696 CLIP16(tmp, outG[base * 3], bits); 1697 tmp = bayer[base + sx]; 1698 CLIP16(tmp, outR[base * 3], bits); 1699 tmp = bayer[base + 1]; 1700 CLIP16(tmp, outB[base * 3], bits); 1701 } 1702 } 1703 for (i = 1; i < sy - 1; i += 2) 1704 { 1705 for (j = 1; j < sx - 1; j += 2) 1706 { 1707 base = i * sx + j; 1708 tmp = ((bayer[base + 1] + bayer[base + sx]) >> 1); 1709 CLIP16(tmp, outG[(base)*3], bits); 1710 tmp = bayer[base]; 1711 CLIP16(tmp, outR[(base)*3], bits); 1712 tmp = bayer[base + 1 + sx]; 1713 CLIP16(tmp, outB[(base)*3], bits); 1714 } 1715 } 1716 break; 1717 } 1718 1719 /* add black border */ 1720 for (i = sx * (sy - 1) * 3; i < sx * sy * 3; i++) 1721 { 1722 rgb[i] = 0; 1723 } 1724 for (i = (sx - 1) * 3; i < sx * sy * 3; i += (sx - 1) * 3) 1725 { 1726 rgb[i++] = 0; 1727 rgb[i++] = 0; 1728 rgb[i++] = 0; 1729 } 1730 1731 return DC1394_SUCCESS; 1732 } 1733 1734 /* Variable Number of Gradients, from dcraw <https://dechifro.org/dcraw/> */ 1735 /* Ported to libdc1394 by Frederic Devernay */ 1736 1737 #define FORC3 for (c = 0; c < 3; c++) 1738 1739 #define SQR(x) ((x) * (x)) 1740 #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31)) 1741 #ifndef MIN 1742 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 1743 #endif 1744 #ifndef MAX 1745 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 1746 #endif 1747 #define LIM(x, min, max) MAX(min, MIN(x, max)) 1748 #define ULIM(x, y, z) ((y) < (z) ? LIM(x, y, z) : LIM(x, z, y)) 1749 /* 1750 In order to inline this calculation, I make the risky 1751 assumption that all filter patterns can be described 1752 by a repeating pattern of eight rows and two columns 1753 1754 Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2 1755 */ 1756 #define FC(row, col) (filters >> ((((row) << 1 & 14) + ((col)&1)) << 1) & 3) 1757 1758 /* 1759 This algorithm is officially called: 1760 1761 "Interpolation using a Threshold-based variable number of gradients" 1762 1763 described in http://www-ise.stanford.edu/~tingchen/algodep/vargra.html 1764 1765 I've extended the basic idea to work with non-Bayer filter arrays. 1766 Gradients are numbered clockwise from NW=0 to W=7. 1767 */ 1768 static const signed char bayervng_terms[] = 1769 { -2, -2, +0, -1, 0, 0x01, -2, -2, +0, +0, 1, 0x01, -2, -1, -1, +0, 0, 0x01, -2, -1, +0, -1, 0, 0x02, 1770 -2, -1, +0, +0, 0, 0x03, -2, -1, +0, +1, 1, 0x01, -2, +0, +0, -1, 0, 0x06, -2, +0, +0, +0, 1, 0x02, 1771 -2, +0, +0, +1, 0, 0x03, -2, +1, -1, +0, 0, 0x04, -2, +1, +0, -1, 1, 0x04, -2, +1, +0, +0, 0, 0x06, 1772 -2, +1, +0, +1, 0, 0x02, -2, +2, +0, +0, 1, 0x04, -2, +2, +0, +1, 0, 0x04, -1, -2, -1, +0, 0, 0x80, 1773 -1, -2, +0, -1, 0, 0x01, -1, -2, +1, -1, 0, 0x01, -1, -2, +1, +0, 1, 0x01, -1, -1, -1, +1, 0, 0x88, 1774 -1, -1, +1, -2, 0, 0x40, -1, -1, +1, -1, 0, 0x22, -1, -1, +1, +0, 0, 0x33, -1, -1, +1, +1, 1, 0x11, 1775 -1, +0, -1, +2, 0, 0x08, -1, +0, +0, -1, 0, 0x44, -1, +0, +0, +1, 0, 0x11, -1, +0, +1, -2, 1, 0x40, 1776 -1, +0, +1, -1, 0, 0x66, -1, +0, +1, +0, 1, 0x22, -1, +0, +1, +1, 0, 0x33, -1, +0, +1, +2, 1, 0x10, 1777 -1, +1, +1, -1, 1, 0x44, -1, +1, +1, +0, 0, 0x66, -1, +1, +1, +1, 0, 0x22, -1, +1, +1, +2, 0, 0x10, 1778 -1, +2, +0, +1, 0, 0x04, -1, +2, +1, +0, 1, 0x04, -1, +2, +1, +1, 0, 0x04, +0, -2, +0, +0, 1, 0x80, 1779 +0, -1, +0, +1, 1, 0x88, +0, -1, +1, -2, 0, 0x40, +0, -1, +1, +0, 0, 0x11, +0, -1, +2, -2, 0, 0x40, 1780 +0, -1, +2, -1, 0, 0x20, +0, -1, +2, +0, 0, 0x30, +0, -1, +2, +1, 1, 0x10, +0, +0, +0, +2, 1, 0x08, 1781 +0, +0, +2, -2, 1, 0x40, +0, +0, +2, -1, 0, 0x60, +0, +0, +2, +0, 1, 0x20, +0, +0, +2, +1, 0, 0x30, 1782 +0, +0, +2, +2, 1, 0x10, +0, +1, +1, +0, 0, 0x44, +0, +1, +1, +2, 0, 0x10, +0, +1, +2, -1, 1, 0x40, 1783 +0, +1, +2, +0, 0, 0x60, +0, +1, +2, +1, 0, 0x20, +0, +1, +2, +2, 0, 0x10, +1, -2, +1, +0, 0, 0x80, 1784 +1, -1, +1, +1, 0, 0x88, +1, +0, +1, +2, 0, 0x08, +1, +0, +2, -1, 0, 0x40, +1, +0, +2, +1, 0, 0x10 }, 1785 bayervng_chood[] = { -1, -1, -1, 0, -1, +1, 0, +1, +1, +1, +1, 0, +1, -1, 0, -1 }; 1786 1787 dc1394error_t dc1394_bayer_VNG(const uint8_t *bayer, uint8_t *dst, int sx, int sy, 1788 dc1394color_filter_t pattern) 1789 { 1790 const int height = sy, width = sx; 1791 static const signed char *cp; 1792 /* the following has the same type as the image */ 1793 uint8_t(*brow[5])[3], *pix; /* [FD] */ 1794 int code[8][2][320], *ip, gval[8], gmin, gmax, sum[4]; 1795 int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag; 1796 int g, diff, thold, num, c; 1797 uint32_t filters; /* [FD] */ 1798 1799 /* first, use bilinear bayer decoding */ 1800 dc1394_bayer_Bilinear(bayer, dst, sx, sy, pattern); 1801 1802 switch (pattern) 1803 { 1804 case DC1394_COLOR_FILTER_BGGR: 1805 filters = 0x16161616; 1806 break; 1807 case DC1394_COLOR_FILTER_GRBG: 1808 filters = 0x61616161; 1809 break; 1810 case DC1394_COLOR_FILTER_RGGB: 1811 filters = 0x94949494; 1812 break; 1813 case DC1394_COLOR_FILTER_GBRG: 1814 filters = 0x49494949; 1815 break; 1816 default: 1817 return DC1394_INVALID_COLOR_FILTER; 1818 } 1819 1820 for (row = 0; row < 8; row++) 1821 { /* Precalculate for VNG */ 1822 for (col = 0; col < 2; col++) 1823 { 1824 ip = code[row][col]; 1825 for (cp = bayervng_terms, t = 0; t < 64; t++) 1826 { 1827 y1 = *cp++; 1828 x1 = *cp++; 1829 y2 = *cp++; 1830 x2 = *cp++; 1831 weight = *cp++; 1832 grads = *cp++; 1833 color = FC(row + y1, col + x1); 1834 if ((int)FC(row + y2, col + x2) != color) 1835 continue; 1836 diag = ((int)FC(row, col + 1) == color && (int)FC(row + 1, col) == color) ? 2 : 1; 1837 if (abs(y1 - y2) == diag && abs(x1 - x2) == diag) 1838 continue; 1839 *ip++ = (y1 * width + x1) * 3 + color; /* [FD] */ 1840 *ip++ = (y2 * width + x2) * 3 + color; /* [FD] */ 1841 *ip++ = weight; 1842 for (g = 0; g < 8; g++) 1843 if (grads & 1 << g) 1844 *ip++ = g; 1845 *ip++ = -1; 1846 } 1847 *ip++ = INT_MAX; 1848 for (cp = bayervng_chood, g = 0; g < 8; g++) 1849 { 1850 y = *cp++; 1851 x = *cp++; 1852 *ip++ = (y * width + x) * 3; /* [FD] */ 1853 color = FC(row, col); 1854 if ((int)FC(row + y, col + x) != color && (int)FC(row + y * 2, col + x * 2) == color) 1855 *ip++ = (y * width + x) * 6 + color; /* [FD] */ 1856 else 1857 *ip++ = 0; 1858 } 1859 } 1860 } 1861 brow[4] = calloc(width * 3, sizeof **brow); 1862 for (row = 0; row < 3; row++) 1863 brow[row] = brow[4] + row * width; 1864 for (row = 2; row < height - 2; row++) 1865 { /* Do VNG interpolation */ 1866 for (col = 2; col < width - 2; col++) 1867 { 1868 pix = dst + (row * width + col) * 3; /* [FD] */ 1869 ip = code[row & 7][col & 1]; 1870 memset(gval, 0, sizeof gval); 1871 while ((g = ip[0]) != INT_MAX) 1872 { /* Calculate gradients */ 1873 diff = ABS(pix[g] - pix[ip[1]]) << ip[2]; 1874 gval[ip[3]] += diff; 1875 ip += 5; 1876 if ((g = ip[-1]) == -1) 1877 continue; 1878 gval[g] += diff; 1879 while ((g = *ip++) != -1) 1880 gval[g] += diff; 1881 } 1882 ip++; 1883 gmin = gmax = gval[0]; /* Choose a threshold */ 1884 for (g = 1; g < 8; g++) 1885 { 1886 if (gmin > gval[g]) 1887 gmin = gval[g]; 1888 if (gmax < gval[g]) 1889 gmax = gval[g]; 1890 } 1891 if (gmax == 0) 1892 { 1893 memcpy(brow[2][col], pix, 3 * sizeof *dst); /* [FD] */ 1894 continue; 1895 } 1896 thold = gmin + (gmax >> 1); 1897 memset(sum, 0, sizeof sum); 1898 color = FC(row, col); 1899 for (num = g = 0; g < 8; g++, ip += 2) 1900 { /* Average the neighbors */ 1901 if (gval[g] <= thold) 1902 { 1903 for (c = 0; c < 3; c++) /* [FD] */ 1904 if (c == color && ip[1]) 1905 sum[c] += (pix[c] + pix[ip[1]]) >> 1; 1906 else 1907 sum[c] += pix[ip[0] + c]; 1908 num++; 1909 } 1910 } 1911 for (c = 0; c < 3; c++) 1912 { /* [FD] Save to buffer */ 1913 t = pix[color]; 1914 if (c != color) 1915 t += (sum[c] - sum[color]) / num; 1916 CLIP(t, brow[2][col][c]); /* [FD] */ 1917 } 1918 } 1919 if (row > 3) /* Write buffer to image */ 1920 memcpy(dst + 3 * ((row - 2) * width + 2), brow[0] + 2, (width - 4) * 3 * sizeof *dst); /* [FD] */ 1921 for (g = 0; g < 4; g++) 1922 brow[(g - 1) & 3] = brow[g]; 1923 } 1924 memcpy(dst + 3 * ((row - 2) * width + 2), brow[0] + 2, (width - 4) * 3 * sizeof *dst); 1925 memcpy(dst + 3 * ((row - 1) * width + 2), brow[1] + 2, (width - 4) * 3 * sizeof *dst); 1926 free(brow[4]); 1927 1928 return DC1394_SUCCESS; 1929 } 1930 1931 dc1394error_t dc1394_bayer_VNG_uint16(const uint16_t *bayer, uint16_t *dst, int sx, int sy, 1932 dc1394color_filter_t pattern, int bits) 1933 { 1934 const int height = sy, width = sx; 1935 static const signed char *cp; 1936 /* the following has the same type as the image */ 1937 uint16_t(*brow[5])[3], *pix; /* [FD] */ 1938 int code[8][2][320], *ip, gval[8], gmin, gmax, sum[4]; 1939 int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag; 1940 int g, diff, thold, num, c; 1941 uint32_t filters; /* [FD] */ 1942 1943 /* first, use bilinear bayer decoding */ 1944 1945 dc1394_bayer_Bilinear_uint16(bayer, dst, sx, sy, pattern, bits); 1946 1947 switch (pattern) 1948 { 1949 case DC1394_COLOR_FILTER_BGGR: 1950 filters = 0x16161616; 1951 break; 1952 case DC1394_COLOR_FILTER_GRBG: 1953 filters = 0x61616161; 1954 break; 1955 case DC1394_COLOR_FILTER_RGGB: 1956 filters = 0x94949494; 1957 break; 1958 case DC1394_COLOR_FILTER_GBRG: 1959 filters = 0x49494949; 1960 break; 1961 default: 1962 return DC1394_INVALID_COLOR_FILTER; 1963 } 1964 1965 for (row = 0; row < 8; row++) 1966 { /* Precalculate for VNG */ 1967 for (col = 0; col < 2; col++) 1968 { 1969 ip = code[row][col]; 1970 for (cp = bayervng_terms, t = 0; t < 64; t++) 1971 { 1972 y1 = *cp++; 1973 x1 = *cp++; 1974 y2 = *cp++; 1975 x2 = *cp++; 1976 weight = *cp++; 1977 grads = *cp++; 1978 color = FC(row + y1, col + x1); 1979 if ((int)FC(row + y2, col + x2) != color) 1980 continue; 1981 diag = ((int)FC(row, col + 1) == color && (int)FC(row + 1, col) == color) ? 2 : 1; 1982 if (abs(y1 - y2) == diag && abs(x1 - x2) == diag) 1983 continue; 1984 *ip++ = (y1 * width + x1) * 3 + color; /* [FD] */ 1985 *ip++ = (y2 * width + x2) * 3 + color; /* [FD] */ 1986 *ip++ = weight; 1987 for (g = 0; g < 8; g++) 1988 if (grads & 1 << g) 1989 *ip++ = g; 1990 *ip++ = -1; 1991 } 1992 *ip++ = INT_MAX; 1993 for (cp = bayervng_chood, g = 0; g < 8; g++) 1994 { 1995 y = *cp++; 1996 x = *cp++; 1997 *ip++ = (y * width + x) * 3; /* [FD] */ 1998 color = FC(row, col); 1999 if ((int)FC(row + y, col + x) != color && (int)FC(row + y * 2, col + x * 2) == color) 2000 *ip++ = (y * width + x) * 6 + color; /* [FD] */ 2001 else 2002 *ip++ = 0; 2003 } 2004 } 2005 } 2006 brow[4] = calloc(width * 3, sizeof **brow); 2007 for (row = 0; row < 3; row++) 2008 brow[row] = brow[4] + row * width; 2009 for (row = 2; row < height - 2; row++) 2010 { /* Do VNG interpolation */ 2011 for (col = 2; col < width - 2; col++) 2012 { 2013 pix = dst + (row * width + col) * 3; /* [FD] */ 2014 ip = code[row & 7][col & 1]; 2015 memset(gval, 0, sizeof gval); 2016 while ((g = ip[0]) != INT_MAX) 2017 { /* Calculate gradients */ 2018 diff = ABS(pix[g] - pix[ip[1]]) << ip[2]; 2019 gval[ip[3]] += diff; 2020 ip += 5; 2021 if ((g = ip[-1]) == -1) 2022 continue; 2023 gval[g] += diff; 2024 while ((g = *ip++) != -1) 2025 gval[g] += diff; 2026 } 2027 ip++; 2028 gmin = gmax = gval[0]; /* Choose a threshold */ 2029 for (g = 1; g < 8; g++) 2030 { 2031 if (gmin > gval[g]) 2032 gmin = gval[g]; 2033 if (gmax < gval[g]) 2034 gmax = gval[g]; 2035 } 2036 if (gmax == 0) 2037 { 2038 memcpy(brow[2][col], pix, 3 * sizeof *dst); /* [FD] */ 2039 continue; 2040 } 2041 thold = gmin + (gmax >> 1); 2042 memset(sum, 0, sizeof sum); 2043 color = FC(row, col); 2044 for (num = g = 0; g < 8; g++, ip += 2) 2045 { /* Average the neighbors */ 2046 if (gval[g] <= thold) 2047 { 2048 for (c = 0; c < 3; c++) /* [FD] */ 2049 if (c == color && ip[1]) 2050 sum[c] += (pix[c] + pix[ip[1]]) >> 1; 2051 else 2052 sum[c] += pix[ip[0] + c]; 2053 num++; 2054 } 2055 } 2056 for (c = 0; c < 3; c++) 2057 { /* [FD] Save to buffer */ 2058 t = pix[color]; 2059 if (c != color) 2060 t += (sum[c] - sum[color]) / num; 2061 CLIP16(t, brow[2][col][c], bits); /* [FD] */ 2062 } 2063 } 2064 if (row > 3) /* Write buffer to image */ 2065 memcpy(dst + 3 * ((row - 2) * width + 2), brow[0] + 2, (width - 4) * 3 * sizeof *dst); /* [FD] */ 2066 for (g = 0; g < 4; g++) 2067 brow[(g - 1) & 3] = brow[g]; 2068 } 2069 memcpy(dst + 3 * ((row - 2) * width + 2), brow[0] + 2, (width - 4) * 3 * sizeof *dst); 2070 memcpy(dst + 3 * ((row - 1) * width + 2), brow[1] + 2, (width - 4) * 3 * sizeof *dst); 2071 free(brow[4]); 2072 2073 return DC1394_SUCCESS; 2074 } 2075 2076 /* AHD interpolation ported from dcraw to libdc1394 by Samuel Audet */ 2077 static dc1394bool_t ahd_inited = DC1394_FALSE; /* WARNING: not multi-processor safe */ 2078 2079 #define CLIPOUT(x) LIM(x, 0, 255) 2080 #define CLIPOUT16(x, bits) LIM(x, 0, ((1 << bits) - 1)) 2081 2082 static const double xyz_rgb[3][3] = { /* XYZ from RGB */ 2083 { 0.412453, 0.357580, 0.180423 }, 2084 { 0.212671, 0.715160, 0.072169 }, 2085 { 0.019334, 0.119193, 0.950227 } 2086 }; 2087 static const float d65_white[3] = { 0.950456, 1, 1.088754 }; 2088 2089 static void cam_to_cielab(uint16_t cam[3], float lab[3]) /* [SA] */ 2090 { 2091 int c, i, j; 2092 float r, xyz[3]; 2093 static float cbrt[0x10000], xyz_cam[3][4]; 2094 2095 if (cam == NULL) 2096 { 2097 for (i = 0; i < 0x10000; i++) 2098 { 2099 r = i / 65535.0; 2100 cbrt[i] = r > 0.008856 ? pow(r, 1 / 3.0) : 7.787 * r + 16 / 116.0; 2101 } 2102 for (i = 0; i < 3; i++) 2103 for (j = 0; j < 3; j++) /* [SA] */ 2104 xyz_cam[i][j] = xyz_rgb[i][j] / d65_white[i]; /* [SA] */ 2105 } 2106 else 2107 { 2108 xyz[0] = xyz[1] = xyz[2] = 0.5; 2109 FORC3 2110 { /* [SA] */ 2111 xyz[0] += xyz_cam[0][c] * cam[c]; 2112 xyz[1] += xyz_cam[1][c] * cam[c]; 2113 xyz[2] += xyz_cam[2][c] * cam[c]; 2114 } 2115 xyz[0] = cbrt[CLIPOUT16((int)xyz[0], 16)]; /* [SA] */ 2116 xyz[1] = cbrt[CLIPOUT16((int)xyz[1], 16)]; /* [SA] */ 2117 xyz[2] = cbrt[CLIPOUT16((int)xyz[2], 16)]; /* [SA] */ 2118 lab[0] = 116 * xyz[1] - 16; 2119 lab[1] = 500 * (xyz[0] - xyz[1]); 2120 lab[2] = 200 * (xyz[1] - xyz[2]); 2121 } 2122 } 2123 2124 /* 2125 Adaptive Homogeneity-Directed interpolation is based on 2126 the work of Keigo Hirakawa, Thomas Parks, and Paul Lee. 2127 */ 2128 #define TS 256 /* Tile Size */ 2129 2130 dc1394error_t dc1394_bayer_AHD(const uint8_t *bayer, uint8_t *dst, int sx, int sy, 2131 dc1394color_filter_t pattern) 2132 { 2133 int i, j, top, left, row, col, tr, tc, fc, c, d, val, hm[2]; 2134 /* the following has the same type as the image */ 2135 uint8_t(*pix)[3], (*rix)[3]; /* [SA] */ 2136 uint16_t rix16[3]; /* [SA] */ 2137 static const int dir[4] = { -1, 1, -TS, TS }; 2138 unsigned ldiff[2][4], abdiff[2][4], leps, abeps; 2139 float flab[3]; /* [SA] */ 2140 uint8_t(*rgb)[TS][TS][3]; 2141 short(*lab)[TS][TS][3]; 2142 char(*homo)[TS][TS], *buffer; 2143 2144 /* start - new code for libdc1394 */ 2145 uint32_t filters; 2146 const int height = sy, width = sx; 2147 int x, y; 2148 2149 if (ahd_inited == DC1394_FALSE) 2150 { 2151 /* WARNING: this might not be multi-processor safe */ 2152 cam_to_cielab(NULL, NULL); 2153 ahd_inited = DC1394_TRUE; 2154 } 2155 2156 switch (pattern) 2157 { 2158 case DC1394_COLOR_FILTER_BGGR: 2159 filters = 0x16161616; 2160 break; 2161 case DC1394_COLOR_FILTER_GRBG: 2162 filters = 0x61616161; 2163 break; 2164 case DC1394_COLOR_FILTER_RGGB: 2165 filters = 0x94949494; 2166 break; 2167 case DC1394_COLOR_FILTER_GBRG: 2168 filters = 0x49494949; 2169 break; 2170 default: 2171 return DC1394_INVALID_COLOR_FILTER; 2172 } 2173 2174 /* fill-in destination with known exact values */ 2175 for (y = 0; y < height; y++) 2176 { 2177 for (x = 0; x < width; x++) 2178 { 2179 int channel = FC(y, x); 2180 dst[(y * width + x) * 3 + channel] = bayer[y * width + x]; 2181 } 2182 } 2183 /* end - new code for libdc1394 */ 2184 2185 /* start - code from border_interpolate (int border) */ 2186 { 2187 int border = 3; 2188 int row, col, y, x; 2189 unsigned f, c, sum[8]; 2190 2191 for (row = 0; row < height; row++) 2192 for (col = 0; col < width; col++) 2193 { 2194 if (col == border && row >= border && row < height - border) 2195 col = width - border; 2196 memset(sum, 0, sizeof sum); 2197 for (y = row - 1; y != row + 2; y++) 2198 for (x = col - 1; x != col + 2; x++) 2199 if (y < height && x < width) 2200 { 2201 f = FC(y, x); 2202 sum[f] += dst[(y * width + x) * 3 + f]; /* [SA] */ 2203 sum[f + 4]++; 2204 } 2205 f = FC(row, col); 2206 FORC3 if (c != f && sum[c + 4]) /* [SA] */ 2207 dst[(row * width + col) * 3 + c] = sum[c] / sum[c + 4]; /* [SA] */ 2208 } 2209 } 2210 /* end - code from border_interpolate (int border) */ 2211 2212 buffer = (char *)malloc(26 * TS * TS); /* 1664 kB */ 2213 /* merror (buffer, "ahd_interpolate()"); */ 2214 rgb = (uint8_t(*)[TS][TS][3])buffer; /* [SA] */ 2215 lab = (short(*)[TS][TS][3])(buffer + 12 * TS * TS); 2216 homo = (char(*)[TS][TS])(buffer + 24 * TS * TS); 2217 2218 for (top = 0; top < height; top += TS - 6) 2219 for (left = 0; left < width; left += TS - 6) 2220 { 2221 memset(rgb, 0, 12 * TS * TS); 2222 2223 /* Interpolate green horizontally and vertically: */ 2224 for (row = top < 2 ? 2 : top; row < top + TS && row < height - 2; row++) 2225 { 2226 col = left + (FC(row, left) == 1); 2227 if (col < 2) 2228 col += 2; 2229 for (fc = FC(row, col); col < left + TS && col < width - 2; col += 2) 2230 { 2231 pix = (uint8_t(*)[3])dst + (row * width + col); /* [SA] */ 2232 val = ((pix[-1][1] + pix[0][fc] + pix[1][1]) * 2 - pix[-2][fc] - pix[2][fc]) >> 2; 2233 rgb[0][row - top][col - left][1] = ULIM(val, pix[-1][1], pix[1][1]); 2234 val = ((pix[-width][1] + pix[0][fc] + pix[width][1]) * 2 - pix[-2 * width][fc] - 2235 pix[2 * width][fc]) >> 2236 2; 2237 rgb[1][row - top][col - left][1] = ULIM(val, pix[-width][1], pix[width][1]); 2238 } 2239 } 2240 /* Interpolate red and blue, and convert to CIELab: */ 2241 for (d = 0; d < 2; d++) 2242 for (row = top + 1; row < top + TS - 1 && row < height - 1; row++) 2243 for (col = left + 1; col < left + TS - 1 && col < width - 1; col++) 2244 { 2245 pix = (uint8_t(*)[3])dst + (row * width + col); /* [SA] */ 2246 rix = &rgb[d][row - top][col - left]; 2247 if ((c = 2 - FC(row, col)) == 1) 2248 { 2249 c = FC(row + 1, col); 2250 val = pix[0][1] + ((pix[-1][2 - c] + pix[1][2 - c] - rix[-1][1] - rix[1][1]) >> 1); 2251 rix[0][2 - c] = CLIPOUT(val); /* [SA] */ 2252 val = pix[0][1] + ((pix[-width][c] + pix[width][c] - rix[-TS][1] - rix[TS][1]) >> 1); 2253 } 2254 else 2255 val = rix[0][1] + 2256 ((pix[-width - 1][c] + pix[-width + 1][c] + pix[+width - 1][c] + pix[+width + 1][c] - 2257 rix[-TS - 1][1] - rix[-TS + 1][1] - rix[+TS - 1][1] - rix[+TS + 1][1] + 1) >> 2258 2); 2259 rix[0][c] = CLIPOUT(val); /* [SA] */ 2260 c = FC(row, col); 2261 rix[0][c] = pix[0][c]; 2262 rix16[0] = rix[0][0]; /* [SA] */ 2263 rix16[1] = rix[0][1]; /* [SA] */ 2264 rix16[2] = rix[0][2]; /* [SA] */ 2265 cam_to_cielab(rix16, flab); /* [SA] */ 2266 FORC3 lab[d][row - top][col - left][c] = 64 * flab[c]; 2267 } 2268 /* Build homogeneity maps from the CIELab images: */ 2269 memset(homo, 0, 2 * TS * TS); 2270 for (row = top + 2; row < top + TS - 2 && row < height; row++) 2271 { 2272 tr = row - top; 2273 for (col = left + 2; col < left + TS - 2 && col < width; col++) 2274 { 2275 tc = col - left; 2276 for (d = 0; d < 2; d++) 2277 for (i = 0; i < 4; i++) 2278 ldiff[d][i] = ABS(lab[d][tr][tc][0] - lab[d][tr][tc + dir[i]][0]); 2279 leps = MIN(MAX(ldiff[0][0], ldiff[0][1]), MAX(ldiff[1][2], ldiff[1][3])); 2280 for (d = 0; d < 2; d++) 2281 for (i = 0; i < 4; i++) 2282 if (i >> 1 == d || ldiff[d][i] <= leps) 2283 abdiff[d][i] = SQR(lab[d][tr][tc][1] - lab[d][tr][tc + dir[i]][1]) + 2284 SQR(lab[d][tr][tc][2] - lab[d][tr][tc + dir[i]][2]); 2285 abeps = MIN(MAX(abdiff[0][0], abdiff[0][1]), MAX(abdiff[1][2], abdiff[1][3])); 2286 for (d = 0; d < 2; d++) 2287 for (i = 0; i < 4; i++) 2288 if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps) 2289 homo[d][tr][tc]++; 2290 } 2291 } 2292 /* Combine the most homogenous pixels for the final result: */ 2293 for (row = top + 3; row < top + TS - 3 && row < height - 3; row++) 2294 { 2295 tr = row - top; 2296 for (col = left + 3; col < left + TS - 3 && col < width - 3; col++) 2297 { 2298 tc = col - left; 2299 for (d = 0; d < 2; d++) 2300 for (hm[d] = 0, i = tr - 1; i <= tr + 1; i++) 2301 for (j = tc - 1; j <= tc + 1; j++) 2302 hm[d] += homo[d][i][j]; 2303 if (hm[0] != hm[1]) 2304 FORC3 dst[(row * width + col) * 3 + c] = CLIPOUT(rgb[hm[1] > hm[0]][tr][tc][c]); /* [SA] */ 2305 else 2306 FORC3 dst[(row * width + col) * 3 + c] = 2307 CLIPOUT((rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1); /* [SA] */ 2308 } 2309 } 2310 } 2311 free(buffer); 2312 2313 return DC1394_SUCCESS; 2314 } 2315 2316 dc1394error_t dc1394_bayer_AHD_uint16(const uint16_t *bayer, uint16_t *dst, int sx, int sy, 2317 dc1394color_filter_t pattern, int bits) 2318 { 2319 int i, j, top, left, row, col, tr, tc, fc, c, d, val, hm[2]; 2320 /* the following has the same type as the image */ 2321 uint16_t(*pix)[3], (*rix)[3]; /* [SA] */ 2322 static const int dir[4] = { -1, 1, -TS, TS }; 2323 unsigned ldiff[2][4], abdiff[2][4], leps, abeps; 2324 float flab[3]; 2325 uint16_t(*rgb)[TS][TS][3]; /* [SA] */ 2326 short(*lab)[TS][TS][3]; 2327 char(*homo)[TS][TS], *buffer; 2328 2329 /* start - new code for libdc1394 */ 2330 uint32_t filters; 2331 const int height = sy, width = sx; 2332 int x, y; 2333 2334 if (ahd_inited == DC1394_FALSE) 2335 { 2336 /* WARNING: this might not be multi-processor safe */ 2337 cam_to_cielab(NULL, NULL); 2338 ahd_inited = DC1394_TRUE; 2339 } 2340 2341 switch (pattern) 2342 { 2343 case DC1394_COLOR_FILTER_BGGR: 2344 filters = 0x16161616; 2345 break; 2346 case DC1394_COLOR_FILTER_GRBG: 2347 filters = 0x61616161; 2348 break; 2349 case DC1394_COLOR_FILTER_RGGB: 2350 filters = 0x94949494; 2351 break; 2352 case DC1394_COLOR_FILTER_GBRG: 2353 filters = 0x49494949; 2354 break; 2355 default: 2356 return DC1394_INVALID_COLOR_FILTER; 2357 } 2358 2359 /* fill-in destination with known exact values */ 2360 for (y = 0; y < height; y++) 2361 { 2362 for (x = 0; x < width; x++) 2363 { 2364 int channel = FC(y, x); 2365 dst[(y * width + x) * 3 + channel] = bayer[y * width + x]; 2366 } 2367 } 2368 /* end - new code for libdc1394 */ 2369 2370 /* start - code from border_interpolate(int border) */ 2371 { 2372 int border = 3; 2373 int row, col, y, x; 2374 unsigned f, c, sum[8]; 2375 2376 for (row = 0; row < height; row++) 2377 for (col = 0; col < width; col++) 2378 { 2379 if (col == border && row >= border && row < height - border) 2380 col = width - border; 2381 memset(sum, 0, sizeof sum); 2382 for (y = row - 1; y != row + 2; y++) 2383 for (x = col - 1; x != col + 2; x++) 2384 if (y < height && x < width) 2385 { 2386 f = FC(y, x); 2387 sum[f] += dst[(y * width + x) * 3 + f]; /* [SA] */ 2388 sum[f + 4]++; 2389 } 2390 f = FC(row, col); 2391 FORC3 if (c != f && sum[c + 4]) /* [SA] */ 2392 dst[(row * width + col) * 3 + c] = sum[c] / sum[c + 4]; /* [SA] */ 2393 } 2394 } 2395 /* end - code from border_interpolate(int border) */ 2396 2397 buffer = (char *)malloc(26 * TS * TS); /* 1664 kB */ 2398 /* merror (buffer, "ahd_interpolate()"); */ 2399 rgb = (uint16_t(*)[TS][TS][3])buffer; /* [SA] */ 2400 lab = (short(*)[TS][TS][3])(buffer + 12 * TS * TS); 2401 homo = (char(*)[TS][TS])(buffer + 24 * TS * TS); 2402 2403 for (top = 0; top < height; top += TS - 6) 2404 for (left = 0; left < width; left += TS - 6) 2405 { 2406 memset(rgb, 0, 12 * TS * TS); 2407 2408 /* Interpolate green horizontally and vertically: */ 2409 for (row = top < 2 ? 2 : top; row < top + TS && row < height - 2; row++) 2410 { 2411 col = left + (FC(row, left) == 1); 2412 if (col < 2) 2413 col += 2; 2414 for (fc = FC(row, col); col < left + TS && col < width - 2; col += 2) 2415 { 2416 pix = (uint16_t(*)[3])dst + (row * width + col); /* [SA] */ 2417 val = ((pix[-1][1] + pix[0][fc] + pix[1][1]) * 2 - pix[-2][fc] - pix[2][fc]) >> 2; 2418 rgb[0][row - top][col - left][1] = ULIM(val, pix[-1][1], pix[1][1]); 2419 val = ((pix[-width][1] + pix[0][fc] + pix[width][1]) * 2 - pix[-2 * width][fc] - 2420 pix[2 * width][fc]) >> 2421 2; 2422 rgb[1][row - top][col - left][1] = ULIM(val, pix[-width][1], pix[width][1]); 2423 } 2424 } 2425 /* Interpolate red and blue, and convert to CIELab: */ 2426 for (d = 0; d < 2; d++) 2427 for (row = top + 1; row < top + TS - 1 && row < height - 1; row++) 2428 for (col = left + 1; col < left + TS - 1 && col < width - 1; col++) 2429 { 2430 pix = (uint16_t(*)[3])dst + (row * width + col); /* [SA] */ 2431 rix = &rgb[d][row - top][col - left]; 2432 if ((c = 2 - FC(row, col)) == 1) 2433 { 2434 c = FC(row + 1, col); 2435 val = pix[0][1] + ((pix[-1][2 - c] + pix[1][2 - c] - rix[-1][1] - rix[1][1]) >> 1); 2436 rix[0][2 - c] = CLIPOUT16(val, bits); /* [SA] */ 2437 val = pix[0][1] + ((pix[-width][c] + pix[width][c] - rix[-TS][1] - rix[TS][1]) >> 1); 2438 } 2439 else 2440 val = rix[0][1] + 2441 ((pix[-width - 1][c] + pix[-width + 1][c] + pix[+width - 1][c] + pix[+width + 1][c] - 2442 rix[-TS - 1][1] - rix[-TS + 1][1] - rix[+TS - 1][1] - rix[+TS + 1][1] + 1) >> 2443 2); 2444 rix[0][c] = CLIPOUT16(val, bits); /* [SA] */ 2445 c = FC(row, col); 2446 rix[0][c] = pix[0][c]; 2447 cam_to_cielab(rix[0], flab); 2448 FORC3 lab[d][row - top][col - left][c] = 64 * flab[c]; 2449 } 2450 /* Build homogeneity maps from the CIELab images: */ 2451 memset(homo, 0, 2 * TS * TS); 2452 for (row = top + 2; row < top + TS - 2 && row < height; row++) 2453 { 2454 tr = row - top; 2455 for (col = left + 2; col < left + TS - 2 && col < width; col++) 2456 { 2457 tc = col - left; 2458 for (d = 0; d < 2; d++) 2459 for (i = 0; i < 4; i++) 2460 ldiff[d][i] = ABS(lab[d][tr][tc][0] - lab[d][tr][tc + dir[i]][0]); 2461 leps = MIN(MAX(ldiff[0][0], ldiff[0][1]), MAX(ldiff[1][2], ldiff[1][3])); 2462 for (d = 0; d < 2; d++) 2463 for (i = 0; i < 4; i++) 2464 if (i >> 1 == d || ldiff[d][i] <= leps) 2465 abdiff[d][i] = SQR(lab[d][tr][tc][1] - lab[d][tr][tc + dir[i]][1]) + 2466 SQR(lab[d][tr][tc][2] - lab[d][tr][tc + dir[i]][2]); 2467 abeps = MIN(MAX(abdiff[0][0], abdiff[0][1]), MAX(abdiff[1][2], abdiff[1][3])); 2468 for (d = 0; d < 2; d++) 2469 for (i = 0; i < 4; i++) 2470 if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps) 2471 homo[d][tr][tc]++; 2472 } 2473 } 2474 /* Combine the most homogenous pixels for the final result: */ 2475 for (row = top + 3; row < top + TS - 3 && row < height - 3; row++) 2476 { 2477 tr = row - top; 2478 for (col = left + 3; col < left + TS - 3 && col < width - 3; col++) 2479 { 2480 tc = col - left; 2481 for (d = 0; d < 2; d++) 2482 for (hm[d] = 0, i = tr - 1; i <= tr + 1; i++) 2483 for (j = tc - 1; j <= tc + 1; j++) 2484 hm[d] += homo[d][i][j]; 2485 if (hm[0] != hm[1]) 2486 FORC3 dst[(row * width + col) * 3 + c] = 2487 CLIPOUT16(rgb[hm[1] > hm[0]][tr][tc][c], bits); /* [SA] */ 2488 else 2489 FORC3 dst[(row * width + col) * 3 + c] = 2490 CLIPOUT16((rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1, bits); /* [SA] */ 2491 } 2492 } 2493 } 2494 free(buffer); 2495 2496 return DC1394_SUCCESS; 2497 } 2498 2499 dc1394error_t dc1394_bayer_decoding_8bit(const uint8_t *bayer, uint8_t *rgb, uint32_t sx, uint32_t sy, 2500 dc1394color_filter_t tile, dc1394bayer_method_t method) 2501 { 2502 switch (method) 2503 { 2504 case DC1394_BAYER_METHOD_NEAREST: 2505 return dc1394_bayer_NearestNeighbor(bayer, rgb, sx, sy, tile); 2506 case DC1394_BAYER_METHOD_SIMPLE: 2507 return dc1394_bayer_Simple(bayer, rgb, sx, sy, tile); 2508 case DC1394_BAYER_METHOD_BILINEAR: 2509 return dc1394_bayer_Bilinear(bayer, rgb, sx, sy, tile); 2510 case DC1394_BAYER_METHOD_HQLINEAR: 2511 return dc1394_bayer_HQLinear(bayer, rgb, sx, sy, tile); 2512 case DC1394_BAYER_METHOD_DOWNSAMPLE: 2513 return dc1394_bayer_Downsample(bayer, rgb, sx, sy, tile); 2514 case DC1394_BAYER_METHOD_EDGESENSE: 2515 return dc1394_bayer_EdgeSense(bayer, rgb, sx, sy, tile); 2516 case DC1394_BAYER_METHOD_VNG: 2517 return dc1394_bayer_VNG(bayer, rgb, sx, sy, tile); 2518 case DC1394_BAYER_METHOD_AHD: 2519 return dc1394_bayer_AHD(bayer, rgb, sx, sy, tile); 2520 default: 2521 return DC1394_INVALID_BAYER_METHOD; 2522 } 2523 } 2524 2525 dc1394error_t dc1394_bayer_decoding_16bit(const uint16_t *bayer, uint16_t *rgb, uint32_t sx, 2526 uint32_t sy, dc1394color_filter_t tile, dc1394bayer_method_t method, 2527 uint32_t bits) 2528 { 2529 switch (method) 2530 { 2531 case DC1394_BAYER_METHOD_NEAREST: 2532 return dc1394_bayer_NearestNeighbor_uint16(bayer, rgb, sx, sy, tile, bits); 2533 case DC1394_BAYER_METHOD_SIMPLE: 2534 return dc1394_bayer_Simple_uint16(bayer, rgb, sx, sy, tile, bits); 2535 case DC1394_BAYER_METHOD_BILINEAR: 2536 return dc1394_bayer_Bilinear_uint16(bayer, rgb, sx, sy, tile, bits); 2537 case DC1394_BAYER_METHOD_HQLINEAR: 2538 return dc1394_bayer_HQLinear_uint16(bayer, rgb, sx, sy, tile, bits); 2539 case DC1394_BAYER_METHOD_DOWNSAMPLE: 2540 return dc1394_bayer_Downsample_uint16(bayer, rgb, sx, sy, tile, bits); 2541 case DC1394_BAYER_METHOD_EDGESENSE: 2542 return dc1394_bayer_EdgeSense_uint16(bayer, rgb, sx, sy, tile, bits); 2543 case DC1394_BAYER_METHOD_VNG: 2544 return dc1394_bayer_VNG_uint16(bayer, rgb, sx, sy, tile, bits); 2545 case DC1394_BAYER_METHOD_AHD: 2546 return dc1394_bayer_AHD_uint16(bayer, rgb, sx, sy, tile, bits); 2547 default: 2548 return DC1394_INVALID_BAYER_METHOD; 2549 } 2550 }