File indexing completed on 2024-04-21 14:45:44

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 }