SOURCES: rawstudio-rev1487-demosaic.patch (NEW) - rev 1487 - demos...
blues
blues at pld-linux.org
Tue Oct 30 00:03:47 CET 2007
Author: blues Date: Mon Oct 29 23:03:47 2007 GMT
Module: SOURCES Tag: HEAD
---- Log message:
- rev 1487 - demosaic support
---- Files affected:
SOURCES:
rawstudio-rev1487-demosaic.patch (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/rawstudio-rev1487-demosaic.patch
diff -u /dev/null SOURCES/rawstudio-rev1487-demosaic.patch:1.1
--- /dev/null Tue Oct 30 00:03:47 2007
+++ SOURCES/rawstudio-rev1487-demosaic.patch Tue Oct 30 00:03:42 2007
@@ -0,0 +1,535 @@
+Index: rawstudio.c
+===================================================================
+--- rawstudio.c (revision 1487)
++++ rawstudio.c (working copy)
+@@ -597,11 +597,15 @@
+ {
+ dcraw_load_raw(raw);
+ photo = rs_photo_new(NULL);
+- photo->input = rs_image16_new(raw->raw.width, raw->raw.height, raw->raw.colors, 4);
++ photo->input = rs_image16_new(raw->raw.width*2, raw->raw.height*2, raw->raw.colors, 4);
+ photo->input->filters = raw->filters;
++ photo->input->fourColorFilters = raw->fourColorFilters;
+
+ rs_photo_open_dcraw_apply_black_and_shift(raw, photo);
+
++ /* FIXME: This should be in a seperate thread!! */
++ rs_image16_demosaic(photo->input, RS_DEMOSAIC_PPG);
++
+ photo->filename = g_strdup(filename);
+ dcraw_close(raw);
+ }
+@@ -623,10 +627,10 @@
+ gushort *src = (gushort*)raw->raw.image;
+ gint64 shift = (gint64) (16.0-log((gdouble) raw->rgbMax)/log(2.0)+0.5);
+
+- for (y=0; y<raw->raw.height; y++)
++ for (y=0; y<(raw->raw.height*2); y++)
+ {
+ destoffset = y*photo->input->rowstride;
+- srcoffset = y * raw->raw.width * 4;
++ srcoffset = y/2 * raw->raw.width * 4;
+ for (x=0; x<raw->raw.width; x++)
+ {
+ register gint r, g, b, g2;
+@@ -642,6 +646,10 @@
+ photo->input->pixels[destoffset++] = (gushort)( g<<shift);
+ photo->input->pixels[destoffset++] = (gushort)( b<<shift);
+ photo->input->pixels[destoffset++] = (gushort)(g2<<shift);
++ photo->input->pixels[destoffset++] = (gushort)( r<<shift);
++ photo->input->pixels[destoffset++] = (gushort)( g<<shift);
++ photo->input->pixels[destoffset++] = (gushort)( b<<shift);
++ photo->input->pixels[destoffset++] = (gushort)(g2<<shift);
+ }
+ }
+ }
+@@ -664,10 +672,10 @@
+ sub[2] = raw->black;
+ sub[3] = raw->black;
+
+- for (y=0; y<raw->raw.height; y++)
++ for (y=0; y<(raw->raw.height*2); y++)
+ {
+ destoffset = (void*) (photo->input->pixels + y*photo->input->rowstride);
+- srcoffset = (void*) (src + y * raw->raw.width * photo->input->pixelsize);
++ srcoffset = (void*) (src + y/2 * raw->raw.width * photo->input->pixelsize);
+ x = raw->raw.width;
+ asm volatile (
+ "mov %3, %%"REG_a"\n\t" /* copy x to %eax */
+@@ -691,8 +699,16 @@
+ "movq %%mm1, 8(%0)\n\t"
+ "movq %%mm2, 16(%0)\n\t"
+ "movq %%mm3, 24(%0)\n\t"
++ "movq %%mm0, (%0)\n\t" /* write destination */
++ "movq %%mm0, 8(%0)\n\t"
++ "movq %%mm1, 16(%0)\n\t"
++ "movq %%mm1, 24(%0)\n\t"
++ "movq %%mm2, 32(%0)\n\t"
++ "movq %%mm2, 40(%0)\n\t"
++ "movq %%mm3, 48(%0)\n\t"
++ "movq %%mm3, 56(%0)\n\t"
+ "sub $4, %%"REG_a"\n\t"
+- "add $32, %0\n\t"
++ "add $64, %0\n\t"
+ "add $32, %1\n\t"
+ "cmp $3, %%"REG_a"\n\t"
+ "jg load_raw_inner_loop\n\t"
+Index: rawstudio.h
+===================================================================
+--- rawstudio.h (revision 1487)
++++ rawstudio.h (working copy)
+@@ -132,6 +132,7 @@
+ guint orientation;
+ gushort *pixels;
+ guint filters;
++ guint fourColorFilters;
+ } RS_IMAGE16;
+
+ typedef struct {
+Index: rs-image.c
+===================================================================
+--- rs-image.c (revision 1487)
++++ rs-image.c (working copy)
+@@ -556,6 +556,7 @@
+ rsi->pixelsize = pixelsize;
+ ORIENTATION_RESET(rsi->orientation);
+ rsi->filters = 0;
++ rsi->fourColorFilters = 0;
+ rsi->pixels = g_new0(gushort, rsi->h*rsi->rowstride);
+ return(rsi);
+ }
+@@ -754,3 +755,410 @@
+ return(FALSE);
+ return(TRUE);
+ }
++
++#define FORCC for (c=0; c < colors; c++)
++
++/*
++ In order to inline this calculation, I make the risky
++ assumption that all filter patterns can be described
++ by a repeating pattern of eight rows and two columns
++
++ Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2
++ */
++#define FC(row,col) \
++ (int)(filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
++
++#define BAYER(row,col) \
++ image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)]
++#define CLIP(x) LIM(x,0,65535)
++#define LIM(x,min,max) MAX(min,MIN(x,max))
++
++int fc_INDI (const unsigned filters, const int row, const int col)
++{
++ static const char filter[16][16] =
++ { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
++ { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
++ { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
++ { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
++ { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
++ { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
++ { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
++ { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
++ { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
++ { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
++ { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
++ { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
++ { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
++ { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
++ { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
++ { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
++
++ if (filters != 1) return FC(row,col);
++ /* Assume that we are handling the Leaf CatchLight with
++ * top_margin = 8; left_margin = 18; */
++// return filter[(row+top_margin) & 15][(col+left_margin) & 15];
++ return filter[(row+8) & 15][(col+18) & 15];
++}
++
++void
++border_interpolate_INDI (RS_IMAGE16 *image, const unsigned filters, int colors, int border)
++{
++ int row, col, y, x, f, c, sum[8];
++
++ for (row=0; row < image->h; row++)
++ for (col=0; col < image->w; col++) {
++ if (col==border && row >= border && row < image->h-border)
++ col = image->w-border;
++ memset (sum, 0, sizeof sum);
++ for (y=row-1; y != row+2; y++)
++ for (x=col-1; x != col+2; x++)
++ if (y >= 0 && y < image->h && x >= 0 && x < image->w) {
++ f = fc_INDI(filters, y, x);
++ sum[f] += image->pixels[y*image->rowstride+x*4+f];
++ sum[f+4]++;
++ }
++ f = fc_INDI(filters,row,col);
++ for (c=0; c < colors; c++)
++ if (c != f && sum[c+4])
++ image->pixels[row*image->rowstride+col*4+c] = sum[c] / sum[c+4];
++ }
++}
++
++void lin_interpolate_INDI(RS_IMAGE16 *image, const unsigned filters, const int colors) /*UF*/
++{
++ int code[16][16][32], *ip, sum[4];
++ int c, i, x, y, row, col, shift, color;
++ ushort *pix;
++
++ border_interpolate_INDI(image, filters, colors, 1);
++
++ for (row=0; row < 16; row++)
++ for (col=0; col < 16; col++)
++ {
++ ip = code[row][col];
++ memset (sum, 0, sizeof sum);
++ for (y=-1; y <= 1; y++)
++ for (x=-1; x <= 1; x++)
++ {
++ shift = (y==0) + (x==0);
++ if (shift == 2)
++ continue;
++ color = fc_INDI(filters,row+y,col+x);
++ *ip++ = (image->pitch*y + x)*4 + color;
++ *ip++ = shift;
++ *ip++ = color;
++ sum[color] += 1 << shift;
++ }
++ FORCC
++ if (c != fc_INDI(filters,row,col))
++ {
++ *ip++ = c;
++ *ip++ = sum[c];
++ }
++ }
++ for (row=1; row < image->h-1; row++)
++ for (col=1; col < image->w-1; col++)
++ {
++ pix = GET_PIXEL(image, col, row);
++ ip = code[row & 15][col & 15];
++ memset (sum, 0, sizeof sum);
++ for (i=8; i--; ip+=3)
++ sum[ip[2]] += pix[ip[0]] << ip[1];
++ for (i=colors; --i; ip+=2)
++ pix[ip[0]] = sum[ip[0]] / ip[1];
++ }
++}
++
++/*
++ This algorithm is officially called:
++
++ "Interpolation using a Threshold-based variable number of gradients"
++
++ described in http://www-ise.stanford.edu/~tingchen/algodep/vargra.html
++
++ I've extended the basic idea to work with non-Bayer filter arrays.
++ Gradients are numbered clockwise from NW=0 to W=7.
++ */
++void vng_interpolate_INDI(RS_IMAGE16 *image, const unsigned filters, const int colors)
++{
++ static const signed char *cp, terms[] = {
++ -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,
++ -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,
++ -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,
++ -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,
++ -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,
++ -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,
++ -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,
++ -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,
++ -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,
++ -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,
++ -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,
++ -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,
++ -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,
++ +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,
++ +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,
++ +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,
++ +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,
++ +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,
++ +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,
++ +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,
++ +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,
++ +1,+0,+2,+1,0,0x10
++ }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
++ ushort (*brow[5])[4], *pix;
++ int prow=7, pcol=1, *ip, *code[16][16], gval[8], gmin, gmax, sum[4];
++ int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
++ int g, diff, thold, num, c;
++
++ lin_interpolate_INDI(image, filters, colors); /*UF*/
++
++ if (filters == 1) prow = pcol = 15;
++ int *ipalloc = ip = (int *) calloc ((prow+1)*(pcol+1), 1280);
++
++ for (row=0; row <= prow; row++) /* Precalculate for VNG */
++ for (col=0; col <= pcol; col++) {
++ code[row][col] = ip;
++ for (cp=terms, t=0; t < 64; t++) {
++ y1 = *cp++; x1 = *cp++;
++ y2 = *cp++; x2 = *cp++;
++ weight = *cp++;
++ grads = *cp++;
++ color = fc_INDI(filters,row+y1,col+x1);
++ if (fc_INDI(filters,row+y2,col+x2) != color) continue;
++ diag = (fc_INDI(filters,row,col+1) == color && fc_INDI(filters,row+1,col) == color) ? 2:1;
++ if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;
++ *ip++ = (y1*image->pitch + x1)*4 + color;
++ *ip++ = (y2*image->pitch + x2)*4 + color;
++ *ip++ = weight;
++ for (g=0; g < 8; g++)
++ if (grads & 1<<g) *ip++ = g;
++ *ip++ = -1;
++ }
++ *ip++ = INT_MAX;
++ for (cp=chood, g=0; g < 8; g++) {
++ y = *cp++; x = *cp++;
++ *ip++ = (y*image->pitch + x) * 4;
++ color = fc_INDI(filters,row,col);
++ if (fc_INDI(filters,row+y,col+x) != color && fc_INDI(filters,row+y*2,col+x*2) == color)
++ *ip++ = (y*image->pitch + x) * 8 + color;
++ else
++ *ip++ = 0;
++ }
++ }
++ brow[4] = (ushort (*)[4]) calloc (image->pitch*3, sizeof **brow);
++
++ for (row=0; row < 3; row++)
++ brow[row] = brow[4] + row*image->pitch;
++ for (row=2; row < image->h-2; row++) { /* Do VNG interpolation */
++ for (col=2; col < image->w-2; col++) {
++ pix = GET_PIXEL(image, col, row);
++ ip = code[row & prow][col & pcol];
++ memset (gval, 0, sizeof gval);
++ while ((g = ip[0]) != INT_MAX) { /* Calculate gradients */
++ diff = ABS(pix[g] - pix[ip[1]]) << ip[2];
++ gval[ip[3]] += diff;
++ ip += 5;
++ if ((g = ip[-1]) == -1) continue;
++ gval[g] += diff;
++ while ((g = *ip++) != -1)
++ gval[g] += diff;
++ }
++ ip++;
++ gmin = gmax = gval[0]; /* Choose a threshold */
++ for (g=1; g < 8; g++) {
++ if (gmin > gval[g]) gmin = gval[g];
++ if (gmax < gval[g]) gmax = gval[g];
++ }
++ if (gmax == 0) {
++ memcpy (brow[2][col], pix, sizeof *image->pixels);
++ continue;
++ }
++ thold = gmin + (gmax >> 1);
++ memset (sum, 0, sizeof sum);
++ color = fc_INDI(filters,row,col);
++ for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */
++ if (gval[g] <= thold) {
++ FORCC
++ if (c == color && ip[1])
++ sum[c] += (pix[c] + pix[ip[1]]) >> 1;
++ else
++ sum[c] += pix[ip[0] + c];
++ num++;
++ }
++ }
++ FORCC { /* Save to buffer */
++ t = pix[color];
++ if (c != color)
++ t += (sum[c] - sum[color]) / num;
++ brow[2][col][c] = CLIP(t);
++ }
++ }
++ if (row > 3) /* Write buffer to image */
++ memcpy (GET_PIXEL(image, 0, row-2)+2, brow[0]+2, (image->pitch-4)*sizeof *image->pixels);
++ for (g=0; g < 4; g++)
++ brow[(g-1) & 3] = brow[g];
++ }
++ memcpy (GET_PIXEL(image, row-2, 0)+2, brow[0]+2, (image->pitch-4)*sizeof *image->pixels);
++ memcpy (GET_PIXEL(image, 0, row-1)+2, brow[1]+2, (image->pitch-4)*sizeof *image->pixels);
++ free (brow[4]);
++ free(ipalloc);
++}
++
++/*
++ Patterned Pixel Grouping Interpolation by Alain Desbiolles
++*/
++#define UT(c1, c2, c3, g1, g3) \
++ CLIP((long)(((g1 +g3) >> 1) +((c2-c1 +c2-c3) >> 3)))
++
++#define UT1(v1, v2, v3, c1, c3) \
++ CLIP((long)(v2 +((c1 +c3 -v1 -v3) >> 1)))
++#define LIM(x,min,max) MAX(min,MIN(x,max))
++#define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y))
++
++void ppg_interpolate_INDI(RS_IMAGE16 *image, const unsigned filters, const int colors)
++{
++ ushort (*pix)[4]; // Pixel matrix
++ ushort g2, c1, c2, cc1, cc2; // Simulated green and color
++ int row, col, diff[2], guess[2], c, d, i;
++ int dir[5] = { 1, image->pitch, -1, -image->pitch, 1 };
++ int g[2][4] = {{ -1 -2*image->pitch, -1 +2*image->pitch, 1 -2*image->pitch, 1 +2*image->pitch },
++ { -2 -image->pitch, 2 -image->pitch, -2 +image->pitch, 2 +image->pitch }};
++
++ border_interpolate_INDI (image, filters, colors, 4);
++
++ // Fill in the green layer with gradients from RGB color pattern simulation
++ for (row=3; row < image->h-4; row++) {
++ for (col=3+(FC(row,3) & 1), c=FC(row,col); col < image->w-4; col+=2) {
++ pix = (ushort (*)[4])GET_PIXEL(image, col, row);
++
++ // Horizontaly and verticaly
++ for (i=0; d=dir[i], i < 2; i++) {
++
++ // Simulate RGB color pattern
++ guess[i] = UT (pix[-2*d][c], pix[0][c], pix[2*d][c],
++ pix[-d][1], pix[d][1]);
++ g2 = UT (pix[0][c], pix[2*d][c], pix[4*d][c],
++ pix[d][1], pix[3*d][1]);
++ c1 = UT1(pix[-2*d][1], pix[-d][1], guess[i],
++ pix[-2*d][c], pix[0][c]);
++ c2 = UT1(guess[i], pix[d][1], g2,
++ pix[0][c], pix[2*d][c]);
++ cc1 = UT (pix[g[i][0]][1], pix[-d][1], pix[g[i][1]][1],
++ pix[-1-image->pitch][2-c], pix[1-image->pitch][2-c]);
++ cc2 = UT (pix[g[i][2]][1], pix[d][1], pix[g[i][3]][1],
++ pix[-1+image->pitch][2-c], pix[1+image->pitch][2-c]);
++
++ // Calculate gradient with RGB simulated color
++ diff[i] = ((ABS(pix[-d][1] -pix[-3*d][1]) +
++ ABS(pix[0][c] -pix[-2*d][c]) +
++ ABS(cc1 -cc2) +
++ ABS(pix[0][c] -pix[2*d][c]) +
++ ABS(pix[d][1] -pix[3*d][1])) * 2 / 3) +
++ ABS(guess[i] -pix[-d][1]) +
++ ABS(pix[0][c] -c1) +
++ ABS(pix[0][c] -c2) +
++ ABS(guess[i] -pix[d][1]);
++ }
++
++ // Then, select the best gradient
++ d = dir[diff[0] > diff[1]];
++ pix[0][1] = ULIM(guess[diff[0] > diff[1]], pix[-d][1], pix[d][1]);
++ }
++ }
++
++ // Calculate red and blue for each green pixel
++ for (row=1; row < image->h-1; row++)
++ for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < image->w-1; col+=2) {
++ pix = (ushort (*)[4])GET_PIXEL(image, col, row);
++ for (i=0; (d=dir[i]) > 0; c=2-c, i++)
++ pix[0][c] = UT1(pix[-d][1], pix[0][1], pix[d][1],
++ pix[-d][c], pix[d][c]);
++ }
++
++ // Calculate blue for red pixels and vice versa
++ for (row=1; row < image->h-1; row++)
++ for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < image->w-1; col+=2) {
++ pix = (ushort (*)[4])GET_PIXEL(image, col, row);
++ for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) {
++ diff[i] = ABS(pix[-d][c] - pix[d][c]) +
++ ABS(pix[-d][1] - pix[d][1]);
++ guess[i] = UT1(pix[-d][1], pix[0][1], pix[d][1],
++ pix[-d][c], pix[d][c]);
++ }
++ pix[0][c] = CLIP(guess[diff[0] > diff[1]]);
++ }
++}
++
++RS_IMAGE16 *
++rs_image16_demosaic(RS_IMAGE16 *in, RS_DEMOSAIC demosaic)
++{
++ gint row,col;
++ gint width, height;
++ gushort *src, *dst;
++ guint filters;
++
++ /* Do some sanity checks on input */
++ if (!in)
++ return NULL;
++ if (in->filters == 0)
++ return NULL;
++ if (in->fourColorFilters == 0)
++ return NULL;
++ if (in->channels != 4)
++ return NULL;
++
++ /* Calculate new width/height */
++ width = in->w;// * 2;
++ height = in->h;// * 2;
++
++ /* Sanity checks on output */
++/* if (!out)
++ out = rs_image16_new(width, height, 3, 4);
++ else
++ {
++ if (out->channels != 3)
++ return NULL;
++ if (out->w != width)
++ return NULL;
++ if (out->h != height)
++ return NULL;
++ if (out->filters != 0)
++ return NULL;
++ if (out->fourColorFilters != 0)
++ return NULL;
++ }
++*/
++ /* Magic - Ask Dave ;) */
++ filters = in->filters;
++ filters &= ~((filters & 0x55555555) << 1);
++
++ /* Populate new image with bayer data */
++ for(row=0; row<height; row++)
++ {
++ for(col=0; col<width; col++)
++ {
++ dst = GET_PIXEL(in, col, row);
++ src = GET_PIXEL(in, col, row);
++ dst[fc_INDI(filters, row, col)] = src[fc_INDI(in->fourColorFilters, row, col)];
++ }
++ }
++
++ /* Switch ourself to three channels after populating */
++ in->channels = 3;
++
++ /* Do the actual demosaic */
++ switch (demosaic)
++ {
++ case RS_DEMOSAIC_BILINEAR:
++ lin_interpolate_INDI(in, filters, 3);
++ break;
++ case RS_DEMOSAIC_VNG:
++ vng_interpolate_INDI(in, filters, 3);
++ break;
++ case RS_DEMOSAIC_PPG:
++ ppg_interpolate_INDI(in, filters, 3);
++ break;
++ }
++
++ return in;
++}
+Index: rs-image.h
+===================================================================
+--- rs-image.h (revision 1487)
++++ rs-image.h (working copy)
+@@ -20,6 +20,12 @@
+ #ifndef RS_IMAGE_H
+ #define RS_IMAGE_H
+
++typedef enum {
++ RS_DEMOSAIC_BILINEAR,
++ RS_DEMOSAIC_VNG,
++ RS_DEMOSAIC_PPG,
++} RS_DEMOSAIC;
++
+ #define rs_image16_scale(in, out, scale) rs_image16_scale_double(in, out, scale)
+
+ /**
+@@ -83,4 +89,6 @@
+ extern inline gushort *rs_image16_get_pixel(RS_IMAGE16 *image, gint x, gint y, gboolean extend_edges);
+ extern gboolean rs_image16_8_cmp_size(RS_IMAGE16 *a, RS_IMAGE8 *b);
+
++RS_IMAGE16 *rs_image16_demosaic(RS_IMAGE16 *in, RS_DEMOSAIC demosaic);
++
+ #endif
================================================================
More information about the pld-cvs-commit
mailing list