[Rawstudio-commit] r2202 - trunk/plugins/demosaic
Anders Brander
anders at brander.dk
Sat Feb 14 12:49:20 CET 2009
Author: abrander
Date: 2009-02-14 12:49:20 +0100 (Sat, 14 Feb 2009)
New Revision: 2202
Modified:
trunk/plugins/demosaic/demosaic.c
Log:
Unrolling loops and added multithreading support to RSDemosaic (Patch by Klaus Post).
Modified: trunk/plugins/demosaic/demosaic.c
===================================================================
--- trunk/plugins/demosaic/demosaic.c 2009-02-14 10:37:12 UTC (rev 2201)
+++ trunk/plugins/demosaic/demosaic.c 2009-02-14 11:49:20 UTC (rev 2202)
@@ -27,6 +27,14 @@
#define RS_DEMOSAIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RS_TYPE_DEMOSAIC, RSDemosaicClass))
#define RS_IS_DEMOSAIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RS_TYPE_DEMOSAIC))
+typedef struct {
+ gint start_y;
+ gint end_y;
+ RS_IMAGE16 *image;
+ unsigned filters;
+ GThread *threadid;
+} ThreadInfo;
+
typedef enum {
RS_DEMOSAIC_NONE,
RS_DEMOSAIC_BILINEAR,
@@ -201,10 +209,6 @@
The rest of this file is pretty much copied verbatim from dcraw/ufraw
*/
-#ifdef _OPENMP
- #error Check all code herein for openmp+gthread-issues
-#endif
-
#define FORCC for (c=0; c < colors; c++)
/*
@@ -301,9 +305,6 @@
*ip++ = 256 / sum[c];
}
}
-#ifdef _OPENMP
-#pragma omp parallel for default(shared) private(row,col,pix,ip,sum,i)
-#endif
for (row=1; row < image->h-1; row++)
for (col=1; col < image->w-1; col++) {
pix = GET_PIXEL(image, col, row);
@@ -319,73 +320,134 @@
/*
Patterned Pixel Grouping Interpolation by Alain Desbiolles
*/
-#define CLIP(x) CLAMP(x,0,65535)
+inline guint clampbits16(gint x) { guint32 _y_temp; if( (_y_temp=x>>16) ) x = ~_y_temp >> 16; return x;}
+
+#define CLIP(x) clampbits16(x)
#define ULIM(x,y,z) ((y) < (z) ? CLAMP(x,y,z) : CLAMP(x,z,y))
static void
-ppg_interpolate_INDI(RS_IMAGE16 *image, const unsigned filters, const int colors)
+interpolate_INDI_part(ThreadInfo *t)
{
+ RS_IMAGE16 *image = t->image;
+ const unsigned filters = t->filters;
+ const int start_y = t->start_y;
+ const int end_y = t->end_y;
int dir[5] = { 1, image->pitch, -1, -image->pitch, 1 };
- int row, col, diff[2], guess[2], c, d, i;
+ int row, col, c, d, i;
+ int diffA, diffB, guessA, guessB;
+ int p = image->pitch;
ushort (*pix)[4];
- border_interpolate_INDI (image, filters, colors, 3);
-
-#ifdef _OPENMP
-#pragma omp parallel \
- default(none) \
- shared(image,dir) \
- private(row,col,i,d,c,pix,diff,guess)
-#endif
{
/* Fill in the green layer with gradients and pattern recognition: */
-#ifdef _OPENMP
-#pragma omp for
-#endif
- for (row=3; row < image->h-3; row++)
+ for (row=start_y; row < end_y; row++)
for (col=3+(FC(row,3) & 1), c=FC(row,col); col < image->w-3; col+=2) {
pix = (ushort (*)[4])GET_PIXEL(image, col, row);
- for (i=0; (d=dir[i]) > 0; i++) {
- guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2
- - pix[-2*d][c] - pix[2*d][c];
- diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) +
- ABS(pix[ 2*d][c] - pix[ 0][c]) +
- ABS(pix[ -d][1] - pix[ d][1]) ) * 3 +
- ( ABS(pix[ 3*d][1] - pix[ d][1]) +
- ABS(pix[-3*d][1] - pix[-d][1]) ) * 2;
- }
- d = dir[i = diff[0] > diff[1]];
- pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]);
+
+ guessA = (pix[-1][1] + pix[0][c] + pix[1][1]) * 2
+ - pix[-2*1][c] - pix[2*1][c];
+ diffA = ( ABS(pix[-2*1][c] - pix[ 0][c]) +
+ ABS(pix[ 2*1][c] - pix[ 0][c]) +
+ ABS(pix[ -1][1] - pix[ 1][1]) ) * 3 +
+ ( ABS(pix[ 3*1][1] - pix[ 1][1]) +
+ ABS(pix[-3*1][1] - pix[-1][1]) ) * 2;
+
+ guessB = (pix[-p][1] + pix[0][c] + pix[p][1]) * 2
+ - pix[-2*p][c] - pix[2*p][c];
+ diffB = ( ABS(pix[-2*p][c] - pix[ 0][c]) +
+ ABS(pix[ 2*p][c] - pix[ 0][c]) +
+ ABS(pix[ -p][1] - pix[ p][1]) ) * 3 +
+ ( ABS(pix[ 3*p][1] - pix[ p][1]) +
+ ABS(pix[-3*p][1] - pix[-p][1]) ) * 2;
+
+ if (diffA > diffB)
+ pix[0][1] = ULIM(guessB >> 2, pix[p][1], pix[-p][1]);
+ else
+ pix[0][1] = ULIM(guessA >> 2, pix[1][1], pix[-1][1]);
}
/* Calculate red and blue for each green pixel: */
-#ifdef _OPENMP
-#pragma omp for
-#endif
- for (row=1; row < image->h-1; row++)
+ for (row=start_y-2; row < end_y+2; 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);
+#if 1
for (i=0; (d=dir[i]) > 0; c=2-c, i++)
pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1]
- pix[-d][1] - pix[d][1]) >> 1);
+#else /* FIXME: Why is this not equivalent? */
+ pix[0][c] = CLIP((pix[-1][c] + pix[1][c] + 2*pix[0][1]
+ - pix[-1][1] - pix[1][1]) >> 1);
+ c=2-c;
+ pix[0][c] = CLIP((pix[-p][c] + pix[p][c] + 2*pix[0][1]
+ - pix[-p][1] - pix[p][1]) >> 1);
+#endif
}
/* Calculate blue for red pixels and vice versa: */
-#ifdef _OPENMP
-#pragma omp for
-#endif
- for (row=1; row < image->h-1; row++)
+ 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);
- for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) {
- diff[i] = ABS(pix[-d][c] - pix[d][c]) +
+ 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]);
- guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1]
+ guessA = pix[-d][c] + pix[d][c] + 2*pix[0][1]
- pix[-d][1] - pix[d][1];
- }
- if (diff[0] != diff[1])
- pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 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((guess[0]+guess[1]) >> 2);
+ pix[0][c] = CLIP(guessA >> 1);
+
}
}
}
+
+gpointer
+start_interp_thread(gpointer _thread_info)
+{
+ ThreadInfo* t = _thread_info;
+
+ interpolate_INDI_part(t);
+ g_thread_exit(NULL);
+
+ return NULL; /* Make the compiler shut up - we'll never return */
+}
+
+static void
+ppg_interpolate_INDI(RS_IMAGE16 *image, const unsigned 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);
+
+ border_interpolate_INDI (image, filters, colors, 3);
+
+ /* Subtract 3 from top and bottom */
+ threaded_h = image->h-6;
+ y_per_thread = (threaded_h + threads-1)/threads;
+ y_offset = 3;
+
+ for (i = 0; i < threads; i++)
+ {
+ t[i].image = image;
+ t[i].filters = filters;
+ t[i].start_y = y_offset;
+ y_offset += y_per_thread;
+ y_offset = MIN(image->h-3, y_offset);
+ t[i].end_y = y_offset;
+
+ t[i].threadid = g_thread_create(start_interp_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);
+}
More information about the Rawstudio-commit
mailing list