Author: post
Date: 2009-06-29 21:29:26 +0200 (Mon, 29 Jun 2009)
New Revision: 2524
Modified:
trunk/plugins/demosaic/demosaic.c
Log:
Added "None" Demosaic method, it will simply duplicate pixels for fast demosaic.
Modified: trunk/plugins/demosaic/demosaic.c
===================================================================
--- trunk/plugins/demosaic/demosaic.c 2009-06-29 18:26:00 UTC (rev 2523)
+++ trunk/plugins/demosaic/demosaic.c 2009-06-29 19:29:26 UTC (rev 2524)
@@ -31,6 +31,7 @@
gint start_y;
gint end_y;
RS_IMAGE16 *image;
+ RS_IMAGE16 *none_out; /* Used by "none" */
guint filters;
GThread *threadid;
} ThreadInfo;
@@ -75,6 +76,7 @@
static void border_interpolate_INDI (RS_IMAGE16 *image, const unsigned int
filters, int colors, int border);
static void lin_interpolate_INDI(RS_IMAGE16 *image, const unsigned int
filters, const int colors);
static void ppg_interpolate_INDI(RS_IMAGE16 *image, const unsigned int
filters, const int colors);
+static void none_interpolate_INDI(RS_IMAGE16 *in, RS_IMAGE16 *out, const
unsigned int filters, const int colors);
static RSFilterClass *rs_demosaic_parent_class = NULL;
@@ -147,7 +149,16 @@
}
}
+/*
+ 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)
+
static RS_IMAGE16 *
get_image(RSFilter *filter, RS_FILTER_PARAM *param)
{
@@ -177,32 +188,37 @@
filters &= ~((filters & 0x55555555) << 1);
/* Populate new image with bayer data */
- for(row=0; row<output->h; row++)
+ if (demosaic->method != RS_DEMOSAIC_NONE)
{
- src = GET_PIXEL(input, 0, row);
- dest = GET_PIXEL(output, 0, row);
- for(col=0;col<output->w;col++)
+ for(row=0; row<output->h; row++)
{
- dest[fc_INDI(filters, row, col)] = *src;
- dest += output->pixelsize;
- src++;
+ src = GET_PIXEL(input, 0, row);
+ dest = GET_PIXEL(output, 0, row);
+ for(col=0;col<output->w;col++)
+ {
+ dest[fc_INDI(filters, row, col)] = *src;
+ dest += output->pixelsize;
+ src++;
+ }
}
}
-
- /* Do the actual demosaic */
- switch (demosaic->method)
- {
- case RS_DEMOSAIC_BILINEAR:
- lin_interpolate_INDI(output, filters, 3);
- break;
- case RS_DEMOSAIC_PPG:
- ppg_interpolate_INDI(output, filters, 3);
- break;
- default:
- /* Do nothing */
- break;
- }
-
+ /* Do the actual demosaic */
+ switch (demosaic->method)
+ {
+ case RS_DEMOSAIC_BILINEAR:
+ lin_interpolate_INDI(output, filters, 3);
+ break;
+ case RS_DEMOSAIC_PPG:
+ ppg_interpolate_INDI(output, filters, 3);
+ break;
+ case RS_DEMOSAIC_NONE:
+ none_interpolate_INDI(input, output, filters, 3);
+ break;
+ default:
+ /* Do nothing */
+ break;
+ }
+
g_object_unref(input);
return output;
}
@@ -213,16 +229,7 @@
#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)]
@@ -377,31 +384,31 @@
- pix[-p][1] - pix[p][1]) >> 1);
c=2-c;
}
+
/* Calculate blue for red pixels and vice versa: */
- for (row=start_y-2; row < end_y+2; 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);
- d = 1 + p;
- diffA = ABS(pix[-d][c] - pix[d][c]) +
- ABS(pix[-d][1] - pix[0][1]) +
- ABS(pix[ d][1] - pix[0][1]);
- guessA = pix[-d][c] + pix[d][c] + 2*pix[0][1]
- - pix[-d][1] - pix[d][1];
+ for (row=start_y-2; row < end_y+2; 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);
+ d = 1 + p;
+ diffA = ABS(pix[-d][c] - pix[d][c]) +
+ ABS(pix[-d][1] - pix[0][1]) +
+ ABS(pix[ d][1] - pix[0][1]);
+ guessA = pix[-d][c] + pix[d][c] + 2*pix[0][1]
+ - pix[-d][1] - pix[d][1];
- d = p - 1;
- diffB = ABS(pix[-d][c] - pix[d][c]) +
- ABS(pix[-d][1] - pix[0][1]) +
- ABS(pix[ d][1] - pix[0][1]);
- guessB = pix[-d][c] + pix[d][c] + 2*pix[0][1]
- - pix[-d][1] - pix[d][1];
+ d = p - 1;
+ diffB = ABS(pix[-d][c] - pix[d][c]) +
+ ABS(pix[-d][1] - pix[0][1]) +
+ ABS(pix[ d][1] - pix[0][1]);
+ guessB = pix[-d][c] + pix[d][c] + 2*pix[0][1]
+ - pix[-d][1] - pix[d][1];
- if (diffA > diffB)
- pix[0][c] = CLIP(guessB >> 1);
- else
- pix[0][c] = CLIP(guessA >> 1);
-
- }
- }
+ if (diffA > diffB)
+ pix[0][c] = CLIP(guessB >> 1);
+ else
+ pix[0][c] = CLIP(guessA >> 1);
+ }
+ }
}
gpointer
@@ -447,3 +454,89 @@
g_free(t);
}
+
+gpointer
+start_none_thread(gpointer _thread_info)
+{
+ gint row, col;
+ gushort *src;
+ gushort *dest;
+
+ ThreadInfo* t = _thread_info;
+ gint ops = t->none_out->pixelsize;
+ gint ors = t->none_out->rowstride;
+ guint filters = t->filters;
+
+ for(row=t->start_y; row < t->end_y; row++)
+ {
+ src = GET_PIXEL(t->image, 0, row);
+ dest = GET_PIXEL(t->none_out, 0, row);
+ guint first = FC(row, 0);
+ guint second = FC(row, 1);
+ if (first == 1) { // Green first
+ for(col=0 ; col < (t->none_out->w - 2); col += 2)
+ {
+ dest[1] = dest[1+ops]= *src;
+ /* Move to next pixel */
+ src++;
+ dest += ops;
+
+ dest[second] = dest[second+ops] =
+ dest[second+ors] = dest[second+ops+ors] = *src;
+
+ /* Move to next pixel */
+ dest += ops;
+ src++;
+ }
+ } else {
+ for(col=0 ; col < (t->none_out->w - 2); col += 2)
+ {
+ dest[first] = dest[first+ops] =
+ dest[first+ors] = dest[first+ops+ors] = *src;
+
+ dest += ops;
+ src++;
+
+ dest[1] = dest[1+ops]= *src;
+
+ dest += ops;
+ src++;
+ }
+ }
+ }
+ g_thread_exit(NULL);
+
+ return NULL; /* Make the compiler shut up - we'll never return */
+}
+
+static void
+none_interpolate_INDI(RS_IMAGE16 *in, RS_IMAGE16 *out, const unsigned int
filters, const int colors)
+{
+ guint i, y_offset, y_per_thread, threaded_h;
+ const guint threads = rs_get_number_of_processor_cores();
+ ThreadInfo *t = g_new(ThreadInfo, threads);
+
+ /* Subtract 1 from bottom */
+ threaded_h = out->h-1;
+ y_per_thread = (threaded_h + threads-1)/threads;
+ y_offset = 0;
+
+ for (i = 0; i < threads; i++)
+ {
+ t[i].image = in;
+ t[i].filters = filters;
+ t[i].start_y = y_offset;
+ t[i].none_out = out;
+ y_offset += y_per_thread;
+ y_offset = MIN(out->h-1, y_offset);
+ t[i].end_y = y_offset;
+
+ t[i].threadid = g_thread_create(start_none_thread, &t[i], TRUE,
NULL);
+ }
+
+ /* Wait for threads to finish */
+ for(i = 0; i < threads; i++)
+ g_thread_join(t[i].threadid);
+
+ g_free(t);
+}
_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit