File dcraw-omp.patch of Package dcraw

Index: dcraw.c
===================================================================
--- dcraw.c.orig
+++ dcraw.c
@@ -231,9 +231,9 @@ struct ph1 {
 
 #define BAYER2(row,col) \
 	image[((row) >> shrink)*iwidth + ((col) >> shrink)][fcol(row,col)]
 
-int CLASS fcol (int row, int col)
+static int CLASS fcol (int row, 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 },
@@ -297,52 +297,52 @@ void CLASS derror()
   }
   data_error++;
 }
 
-ushort CLASS sget2 (uchar *s)
+static ushort CLASS sget2 (uchar *s)
 {
   if (order == 0x4949)		/* "II" means little-endian */
     return s[0] | s[1] << 8;
   else				/* "MM" means big-endian */
     return s[0] << 8 | s[1];
 }
 
-ushort CLASS get2()
+static ushort CLASS get2()
 {
   uchar str[2] = { 0xff,0xff };
   fread (str, 1, 2, ifp);
   return sget2(str);
 }
 
-unsigned CLASS sget4 (uchar *s)
+static unsigned CLASS sget4 (uchar *s)
 {
   if (order == 0x4949)
     return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
   else
     return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
 }
 #define sget4(s) sget4((uchar *)s)
 
-unsigned CLASS get4()
+static unsigned CLASS get4()
 {
   uchar str[4] = { 0xff,0xff,0xff,0xff };
   fread (str, 1, 4, ifp);
   return sget4(str);
 }
 
-unsigned CLASS getint (int type)
+static unsigned CLASS getint (int type)
 {
   return type == 3 ? get2() : get4();
 }
 
-float CLASS int_to_float (int i)
+static float CLASS int_to_float (int i)
 {
   union { int i; float f; } u;
   u.i = i;
   return u.f;
 }
 
-double CLASS getreal (int type)
+static double CLASS getreal (int type)
 {
   union { char c[8]; double d; } u;
   int i, rev;
 
@@ -364,9 +364,9 @@ double CLASS getreal (int type)
     default: return fgetc(ifp);
   }
 }
 
-void CLASS read_shorts (ushort *pixel, int count)
+static void CLASS read_shorts (ushort *pixel, int count)
 {
   if (fread (pixel, 2, count, ifp) < count) derror();
   if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
     swab (pixel, pixel, count*2);
@@ -540,9 +540,9 @@ int CLASS canon_s2is()
   }
   return 0;
 }
 
-unsigned CLASS getbithuff (int nbits, ushort *huff)
+static unsigned CLASS getbithuff (int nbits, ushort *huff)
 {
   static unsigned bitbuf=0;
   static int vbits=0, reset=0;
   unsigned c;
@@ -823,9 +823,9 @@ void CLASS ljpeg_end (struct jhead *jh)
   FORC4 if (jh->free[c]) free (jh->free[c]);
   free (jh->row);
 }
 
-int CLASS ljpeg_diff (ushort *huff)
+static int CLASS ljpeg_diff (ushort *huff)
 {
   int len, diff;
 
   len = gethuff(huff);
@@ -836,9 +836,9 @@ int CLASS ljpeg_diff (ushort *huff)
     diff -= (1 << len) - 1;
   return diff;
 }
 
-ushort * CLASS ljpeg_row (int jrow, struct jhead *jh)
+static ushort * CLASS ljpeg_row (int jrow, struct jhead *jh)
 {
   int col, c, diff, pred, spred=0;
   ushort mark=0, *row[3];
 
@@ -875,9 +875,9 @@ ushort * CLASS ljpeg_row (int jrow, stru
     }
   return row[2];
 }
 
-void CLASS lossless_jpeg_load_raw()
+static void CLASS lossless_jpeg_load_raw()
 {
   int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0;
   struct jhead jh;
   ushort *rp;
@@ -3605,8 +3605,12 @@ void CLASS gamma_curve (double pwr, doub
   if (!mode--) {
     memcpy (gamm, g, sizeof gamm);
     return;
   }
+#pragma omp parallel for \
+  default(none) \
+  shared(curve, g, imax, mode) \
+  private(i, r)
   for (i=0; i < 0x10000; i++) {
     curve[i] = 0xffff;
     if ((r = (double) i / imax) < 1)
       curve[i] = 0x10000 * ( mode
@@ -3827,10 +3831,10 @@ void CLASS wavelet_denoise()
 }
 
 void CLASS scale_colors()
 {
-  unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
-  int val, dark, sat;
+  unsigned bottom, right, size, row, col, ur, uc, x, y, c, sum[8];
+  int val, dark, sat, i;
   double dsum[8], dmin, dmax;
   float scale_mul[4], fr, fc;
   ushort *img=0, *pix;
 
@@ -3898,8 +3902,10 @@ skip_block: ;
     FORC4 fprintf (stderr, " %f", pre_mul[c]);
     fputc ('\n', stderr);
   }
   size = iheight*iwidth;
+
+#pragma omp parallel for default(none) private(i, val) shared(size,stderr,image,black,scale_mul,cblack)
   for (i=0; i < size*4; i++) {
     val = image[0][i];
     if (!val) continue;
     val -= cblack[i & 3];
@@ -3980,9 +3986,9 @@ void CLASS pre_interpolate()
   }
   if (half_size) filters = 0;
 }
 
-void CLASS border_interpolate (int border)
+static void CLASS border_interpolate (int border)
 {
   unsigned row, col, y, x, f, c, sum[8];
 
   for (row=0; row < height; row++)
@@ -4241,19 +4247,26 @@ void CLASS cielab (ushort rgb[3], short
 {
   int c, i, j, k;
   float r, xyz[3];
   static float cbrt[0x10000], xyz_cam[3][4];
-
   if (!rgb) {
+#pragma omp parallel \
+  default(none) \
+  shared(cbrt, xyz_cam, rgb_cam, colors) \
+  private(i, j, k, c, r, xyz, rgb, lab)
+  {
+#pragma omp for schedule(static) nowait
     for (i=0; i < 0x10000; i++) {
       r = i / 65535.0;
       cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
     }
+#pragma omp for
     for (i=0; i < 3; i++)
       for (j=0; j < colors; j++)
 	for (xyz_cam[i][j] = k=0; k < 3; k++)
 	  xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
-    return;
+  }
+  return;
   }
   xyz[0] = xyz[1] = xyz[2] = 0.5;
   FORCC {
     xyz[0] += xyz_cam[0][c] * rgb[c];
@@ -4509,17 +4522,22 @@ void CLASS ahd_interpolate()
    short (*lab)[TS][TS][3], (*lix)[3];
    char (*homo)[TS][TS], *buffer;
 
   if (verbose) fprintf (stderr,_("AHD interpolation...\n"));
-
   cielab (0,0);
   border_interpolate(5);
+#pragma omp parallel \
+  default(none) \
+  shared(stderr, colors, rgb_cam, height, width, image, filters)	\
+  private(top, left, row, col, pix, rix, lix, c, val, d, tc, tr, i, j, ldiff, abdiff, leps, abeps, hm, buffer, rgb, lab, homo)
+  {
   buffer = (char *) malloc (26*TS*TS);
   merror (buffer, "ahd_interpolate()");
   rgb  = (ushort(*)[TS][TS][3]) buffer;
   lab  = (short (*)[TS][TS][3])(buffer + 12*TS*TS);
   homo = (char  (*)[TS][TS])   (buffer + 24*TS*TS);
 
+#pragma omp for
   for (top=2; top < height-5; top += TS-6)
     for (left=2; left < width-5; left += TS-6) {
 
 /*  Interpolate green horizontally and vertically:		*/
@@ -4600,8 +4618,9 @@ void CLASS ahd_interpolate()
 	}
       }
     }
   free (buffer);
+  }
 }
 #undef TS
 
 void CLASS median_filter()
@@ -8717,10 +8736,16 @@ void CLASS convert_to_rgb()
     fprintf (stderr, raw_color ? _("Building histograms...\n") :
 	_("Converting to %s colorspace...\n"), name[output_color-1]);
 
   memset (histogram, 0, sizeof histogram);
-  for (img=image[0], row=0; row < height; row++)
-    for (col=0; col < width; col++, img+=4) {
+
+#pragma omp parallel for					\
+  default(none)							\
+  shared(height, width, image, raw_color, out_cam, colors, document_mode, filters, histogram) \
+  private(row, col, out, c, img)
+  for (row = 0; row < height; row++) {
+    img = image[0] + row * width * 4;
+    for (col = 0; col < width; col++, img += 4) {
       if (!raw_color) {
 	out[0] = out[1] = out[2] = 0;
 	FORCC {
 	  out[0] += out_cam[0][c] * img[c];
@@ -8730,10 +8755,14 @@ void CLASS convert_to_rgb()
 	FORC3 img[c] = CLIP((int) out[c]);
       }
       else if (document_mode)
 	img[0] = img[fcol(row,col)];
-      FORCC histogram[c][img[c] >> 3]++;
+      FORCC {
+#pragma omp atomic
+	histogram[c][img[c] >> 3]++;
+      }
     }
+  }
   if (colors == 4 && output_color) colors = 3;
   if (document_mode && filters) colors = 1;
 }