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