SOURCES: dcraw.1, dcraw.c - updated to 2005/11/06.

pluto pluto at pld-linux.org
Thu Nov 10 21:50:11 CET 2005


Author: pluto                        Date: Thu Nov 10 20:50:11 2005 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- updated to 2005/11/06.

---- Files affected:
SOURCES:
   dcraw.1 (1.4 -> 1.5) , dcraw.c (1.5 -> 1.6) 

---- Diffs:

================================================================
Index: SOURCES/dcraw.1
diff -u SOURCES/dcraw.1:1.4 SOURCES/dcraw.1:1.5
--- SOURCES/dcraw.1:1.4	Fri Sep 30 17:38:52 2005
+++ SOURCES/dcraw.1	Thu Nov 10 21:50:06 2005
@@ -9,7 +9,7 @@
 .\" dcoffin a cybercom o net
 .\" http://www.cybercom.net/~dcoffin
 .\"
-.TH dcraw 1 "September 25, 2005"
+.TH dcraw 1 "September 29, 2005"
 .LO 1
 .SH NAME
 dcraw - convert raw digital photos to PPM format
@@ -52,18 +52,24 @@
 Show the raw data as a grayscale image with no interpolation.
 Good for photographing black-and-white documents.
 .TP
-.B -V
-Use the older VNG interpolation.  Faster than the default AHD
-algorithm, but more prone to zipper artifacts.
-.TP
-.B -q
-Use bilinear interpolation.  Much faster than
-.BR -V .
+.B -q [0-3]
+Set the interpolation quality (default is 3):
+
+.B \t0
+\ \ Bilinear (very fast, low quality)
+.br
+.B \t1
+\ \ Reserved
+.br
+.B \t2
+\ \ Variable Number of Gradients (VNG)
+.br
+.B \t3
+\ \ Adaptive Homogeneity-Directed (AHD)
 .TP
 .B -h
-Half-size the output image.  Instead of interpolating, reduce
-each 2x2 block of sensors to one pixel.  Much faster than
-.BR -q .
+Output a half-size image.  Twice as fast as
+.BR -q\ 0 .
 .TP
 .B -f
 Interpolate RGB as four colors.  This blurs the image a little,
@@ -76,9 +82,7 @@
 .B sigma_range
 is in units of CIELab colorspace.
 Try
-.B -B 1 2
-or
-.B -B 2 4
+.B -B\ 2\ 4
 to start.
 .TP
 .B -a
@@ -99,7 +103,7 @@
 Change the output brightness.  Default is 1.0.
 .TP
 .B -k black
-Change the black point.  Default depends on the camera.
+Set the black point.  Default depends on the camera.
 .TP
 .B -n
 By default,

================================================================
Index: SOURCES/dcraw.c
diff -u SOURCES/dcraw.c:1.5 SOURCES/dcraw.c:1.6
--- SOURCES/dcraw.c:1.5	Fri Sep 30 17:36:56 2005
+++ SOURCES/dcraw.c	Thu Nov 10 21:50:06 2005
@@ -85,22 +85,23 @@
 char *ifname, make[64], model[70], model2[64], *meta_data;
 float flash_used, canon_5814;
 time_t timestamp;
+unsigned shot_order, kodak_cbpp;
 int data_offset, meta_offset, meta_length, nikon_curve_offset;
-int tiff_data_compression, kodak_data_compression;
+int tiff_bps, tiff_data_compression, kodak_data_compression;
 int raw_height, raw_width, top_margin, left_margin;
 int height, width, fuji_width, colors, tiff_samples;
 int black, maximum, clip_max, clip_color=1;
 int iheight, iwidth, shrink;
-int dng_version, is_canon, is_foveon, raw_color, use_gamma;
-int trim, flip, xmag, ymag;
+int dng_version, is_foveon, raw_color, use_gamma;
+int flip, xmag, ymag;
 int zero_after_ff;
 unsigned filters;
 ushort (*image)[4], white[8][8], curve[0x1000];
 void (*load_raw)();
 float bright=1, red_scale=1, blue_scale=1, sigma_d=0, sigma_r=0;
-int four_color_rgb=0, document_mode=0, quick_interpolate=0;
+int four_color_rgb=0, document_mode=0;
 int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_rgb=0;
-int fuji_secondary, use_secondary=0;
+int fuji_layout, fuji_secondary, use_secondary=0;
 float cam_mul[4], pre_mul[4], rgb_cam[3][4];	/* RGB from camera color */
 const double xyz_rgb[3][3] = {			/* XYZ from RGB */
   { 0.412453, 0.357580, 0.180423 },
@@ -131,9 +132,11 @@
 
 #define SQR(x) ((x)*(x))
 #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-#define CLIP(x) (MAX(0,MIN((x),clip_max)))
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#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))
+#define CLIP(x) LIM(x,0,clip_max)
 
 /*
    In order to inline this calculation, I make the risky
@@ -219,6 +222,7 @@
   else
     return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
 }
+#define sget4(s) sget4((uchar *)s)
 
 int CLASS get4()
 {
@@ -520,14 +524,11 @@
   static const uchar first_tree[3][29] = {
     { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0,
       0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff  },
-
     { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0,
       0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff  },
-
     { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0,
       0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff  },
   };
-
   static const uchar second_tree[3][180] = {
     { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139,
       0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08,
@@ -544,7 +545,6 @@
       0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba,
       0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4,
       0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff  },
-
     { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140,
       0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06,
       0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32,
@@ -560,7 +560,6 @@
       0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8,
       0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8,
       0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff  },
-
     { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117,
       0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08,
       0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22,
@@ -577,7 +576,6 @@
       0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3,
       0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff  }
   };
-
   if (table > 2) table = 2;
   init_decoder();
   make_decoder ( first_tree[table], 0);
@@ -788,12 +786,12 @@
 	  row = jidx / 1748;
 	  col = jidx % 1748 + 2*1680;
 	}
-      } else if (raw_width == 3516) {
-	row = jidx / 1758;
-	col = jidx % 1758;
+      } else if (raw_width == 4476 || raw_width == 3516) {
+	row = jidx / (raw_width/2);
+	col = jidx % (raw_width/2);
 	if (row >= raw_height) {
 	  row -= raw_height;
-	  col += 1758;
+	  col += raw_width/2;
 	}
       } else {
 	row = jidx / raw_width;
@@ -875,18 +873,17 @@
 void CLASS adobe_dng_load_raw_nc()
 {
   ushort *pixel, *rp;
-  int row, col, nbits;
+  int row, col;
 
   pixel = calloc (raw_width * tiff_samples, sizeof *pixel);
   merror (pixel, "adobe_dng_load_raw_nc()");
-  for (nbits=0; 1 << nbits <= maximum; nbits++);
   for (row=0; row < raw_height; row++) {
-    if (nbits == 16)
+    if (tiff_bps == 16)
       read_shorts (pixel, raw_width * tiff_samples);
     else {
       getbits(-1);
       for (col=0; col < raw_width * tiff_samples; col++)
-	pixel[col] = getbits(nbits);
+	pixel[col] = getbits(tiff_bps);
     }
     for (rp=pixel, col=0; col < raw_width; col++)
       adobe_copy_pixel (row, col, &rp);
@@ -1068,8 +1065,8 @@
 
 void CLASS nikon_e2100_load_raw()
 {
-  uchar   data[3432], *dp;
-  ushort pixel[2288], *pix;
+  uchar   data[3456], *dp;
+  ushort pixel[2304], *pix;
   int row, col;
 
   for (row=0; row <= height; row+=2) {
@@ -1096,83 +1093,27 @@
 /*
    The Fuji Super CCD is just a Bayer grid rotated 45 degrees.
  */
-void CLASS fuji_s2_load_raw()
+void CLASS fuji_load_raw()
 {
-  ushort pixel[2944];
-  int row, col, r, c;
-
-  fseek (ifp, (2944*24+32)*2, SEEK_CUR);
-  for (row=0; row < 2144; row++) {
-    read_shorts (pixel, 2944);
-    for (col=0; col < 2880; col++) {
-      r = row + ((col+1) >> 1);
-      c = 2143 - row + (col >> 1);
-      BAYER(r,c) = pixel[col];
-    }
-  }
-}
-
-void CLASS fuji_s3_load_raw()
-{
-  ushort pixel[4352];
-  int row, col, r, c;
-
-  fseek (ifp, (4352*2+32)*2, SEEK_CUR);
-  for (row=0; row < 1440; row++) {
-    read_shorts (pixel, 4352);
-    for (col=0; col < 4288; col++) {
-      r = 2143 + row - (col >> 1);
-      c = row + ((col+1) >> 1);
-      BAYER(r,c) = pixel[col];
-    }
-  }
-}
-
-void CLASS fuji_common_load_raw (int ncol, int icol, int nrow)
-{
-  ushort pixel[2048];
+  ushort *pixel;
   int row, col, r, c;
 
-  for (row=0; row < nrow; row++) {
-    read_shorts (pixel, ncol);
-    for (col=0; col <= icol; col++) {
-      r = icol - col + (row >> 1);
-      c = col + ((row+1) >> 1);
+  pixel = calloc (raw_width, sizeof *pixel);
+  merror (pixel, "fuji_load_raw()");
+  for (row=0; row < raw_height; row++) {
+    read_shorts (pixel, raw_width);
+    for (col=0; col < fuji_width << !fuji_layout; col++) {
+      if (fuji_layout) {
+	r = fuji_width - 1 - col + (row >> 1);
+	c = col + ((row+1) >> 1);
+      } else {
+	r = fuji_width - 1 + row - (col >> 1);
+	c = row + ((col+1) >> 1);
+      }
       BAYER(r,c) = pixel[col];
     }
   }
-}
-
-void CLASS fuji_s5000_load_raw()
-{
-  fseek (ifp, (1472*4+24)*2, SEEK_CUR);
-  fuji_common_load_raw (1472, 1423, 2152);
-}
-
-void CLASS fuji_s7000_load_raw()
-{
-  fuji_common_load_raw (2048, 2047, 3080);
-}
-
-/*
-   The Fuji Super CCD SR has two photodiodes for each pixel.
-   The secondary has about 1/16 the sensitivity of the primary,
-   but this ratio may vary.
- */
-void CLASS fuji_f700_load_raw()
-{
-  ushort pixel[2944];
-  int row, col, r, c, val;
-
-  for (row=0; row < 2168; row++) {
-    read_shorts (pixel, 2944);
-    for (col=0; col < 1440; col++) {
-      r = 1439 - col + (row >> 1);
-      c = col + ((row+1) >> 1);
-      val = pixel[col+16 + use_secondary*1472];
-      BAYER(r,c) = val;
-    }
-  }
+  free (pixel);
 }
 
 void CLASS rollei_load_raw()
@@ -1340,7 +1281,10 @@
     }
     for (col=0; col < width; col++)
       BAYER(row,col) = (pixel[col] & 0xfff);
+    for (col=width+4; col < raw_width; col++)
+      black += pixel[col] & 0xfff;
   }
+  black /= (raw_width - width - 4) * height;
   free (data);
 }
 
@@ -1487,8 +1431,8 @@
       s = make_decoder_int (s, 0);
     }
   if (tree == 18) {
-    if (model[2] == '5')
-      return (getbits(6) << 2) + 2;	/* DC50 */
+    if (kodak_cbpp == 243)
+      return (getbits(6) << 2) + 2;	/* most DC50 photos */
     else
       return (getbits(5) << 3) + 4;	/* DC40, Fotoman Pixtura */
   }
@@ -1512,8 +1456,7 @@
   for (i=0; i < sizeof(buf)/sizeof(short); i++)
     buf[0][0][i] = 2048;
   for (row=0; row < height; row+=4) {
-    for (i=0; i < 3; i++)
-      mul[i] = getbits(6);
+    FORC3 mul[c] = getbits(6);
     FORC3 {
       val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c];
       s = val > 65564 ? 10:12;
@@ -1564,7 +1507,7 @@
 	  BAYER(y,x) = val;
 	}
   }
-  maximum = 0x1fff;		/* wild guess */
+  maximum = 10000;
 }
 
 #undef FORYX
@@ -1577,7 +1520,7 @@
 METHODDEF(boolean)
 fill_input_buffer (j_decompress_ptr cinfo)
 {
-  static char jpeg_buffer[4096];
+  static uchar jpeg_buffer[4096];
   size_t nbytes;
 
   nbytes = fread (jpeg_buffer, 1, 4096, ifp);
@@ -1786,7 +1729,6 @@
 	FORC3 if (rgb[c] > 0) ip[c] = curve[rgb[c]];
       }
     }
-  maximum = 0xe74;
 }
 
 void CLASS sony_decrypt (unsigned *data, int len, int start, int key)
@@ -2028,7 +1970,7 @@
   int fixed, row, col, bit=-1, c, i;
 
   fixed = get4();
-  read_shorts (diff, 1024);
+  read_shorts ((ushort *) diff, 1024);
   if (!fixed) {
     for (i=0; i < 1024; i++)
       huff[i] = get4();
@@ -2168,12 +2110,14 @@
   FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt);
 }
 
-int CLASS foveon_apply_curve (ushort *curve, int i)
+int CLASS foveon_apply_curve (short *curve, int i)
 {
   if (abs(i) >= curve[0]) return 0;
   return i < 0 ? -curve[1-i] : curve[1+i];
 }
 
+#define image ((short (*)[4]) image)
+
 void CLASS foveon_interpolate()
 {
   static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 };
@@ -2414,7 +2358,7 @@
     if (min > i) min = i;
   }
   limit = min * 9 >> 4;
-  for (pix=image[0]; pix < (short *) image[height*width]; pix+=4) {
+  for (pix=image[0]; pix < image[height*width]; pix+=4) {
     if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit)
       continue;
     min = max = pix[0];
@@ -2483,7 +2427,7 @@
   }
 
   /* Transform the image to a different colorspace */
-  for (pix=image[0]; pix < (short *) image[height*width]; pix+=4) {
+  for (pix=image[0]; pix < image[height*width]; pix+=4) {
     FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]);
     sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2;
     FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum);
@@ -2570,6 +2514,7 @@
   width = i;
   height = row;
 }
+#undef image
 
 /* END GPL BLOCK */
 
@@ -2879,6 +2824,67 @@
   }
 }
 
+void CLASS border_interpolate (int border)
+{
+  unsigned row, col, y, x, c, sum[8];
+
+  for (row=0; row < height; row++)
+    for (col=0; col < width; col++) {
+      if (col==border && row >= border && row < height-border)
+	col = width-border;
+      memset (sum, 0, sizeof sum);
+      for (y=row-1; y != row+2; y++)
+	for (x=col-1; x != col+2; x++)
+	  if (y < height && x < width) {
+	    sum[FC(y,x)] += BAYER(y,x);
+	    sum[FC(y,x)+4]++;
+	  }
+      FORCC if (c != FC(row,col))
+	image[row*width+col][c] = sum[c] / sum[c+4];
+    }
+}
+
+void CLASS lin_interpolate()
+{
+  int code[8][2][32], *ip, sum[4];
+  int c, i, x, y, row, col, shift, color;
+  ushort *pix;
+
+  if (verbose) fprintf (stderr, "Bilinear interpolation...\n");
+
+  border_interpolate(1);
+  for (row=0; row < 8; row++)
+    for (col=0; col < 2; 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(row+y,col+x);
+	  *ip++ = (width*y + x)*4 + color;
+	  *ip++ = shift;
+	  *ip++ = color;
+	  sum[color] += 1 << shift;
+	}
+      FORCC
+	if (c != FC(row,col)) {
+	  *ip++ = c;
+	  *ip++ = sum[c];
+	}
+    }
+  for (row=1; row < height-1; row++)
+    for (col=1; col < width-1; col++) {
+      pix = image[row*width+col];
+      ip = code[row & 7][col & 1];
+      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:
 
@@ -2917,46 +2923,11 @@
   }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };
   ushort (*brow[5])[4], *pix;
   int code[8][2][320], *ip, gval[8], gmin, gmax, sum[4];
-  int row, col, shift, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
+  int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;
   int g, diff, thold, num, c;
 
-  if (verbose)
-    fprintf (stderr, "%s interpolation...\n",
-	quick_interpolate ? "Bilinear":"VNG");
-
-  for (row=0; row < 8; row++) {		/* Precalculate for bilinear */
-    for (col=1; col < 3; col++) {
-      ip = code[row][col & 1];
-      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(row+y,col+x);
-	  *ip++ = (width*y + x)*4 + color;
-	  *ip++ = shift;
-	  *ip++ = color;
-	  sum[color] += 1 << shift;
-	}
-      FORCC
-	if (c != FC(row,col)) {
-	  *ip++ = c;
-	  *ip++ = sum[c];
-	}
-    }
-  }
-  for (row=1; row < height-1; row++) {	/* Do bilinear interpolation */
-    for (col=1; col < width-1; col++) {
-      pix = image[row*width+col];
-      ip = code[row & 7][col & 1];
-      memset (sum, 0, sizeof sum);
-      for (g=8; g--; ip+=3)
-	sum[ip[2]] += pix[ip[0]] << ip[1];
-      for (g=colors; --g; ip+=2)
-	pix[ip[0]] = sum[ip[0]] / ip[1];
-    }
-  }
-  if (quick_interpolate) return;
+  lin_interpolate();
+  if (verbose) fprintf (stderr, "VNG interpolation...\n");
 
   for (row=0; row < 8; row++) {		/* Precalculate for VNG */
     for (col=0; col < 2; col++) {
@@ -3052,7 +3023,7 @@
   int c, i, j, k;
   float r, xyz[3];
   static const float d65[3] = { 0.950456, 1, 1.088754 };
-  static float cbrt[0x10000], xyz_cam[3][3];
+  static float cbrt[0x10000], xyz_cam[3][4];
 
   if (cam == NULL) {
     for (i=0; i < 0x10000; i++) {
@@ -3093,6 +3064,8 @@
    char (*homo)[TS][TS], *buffer;
 
   if (verbose) fprintf (stderr, "AHD interpolation...\n");
+
+  border_interpolate(3);
   buffer = malloc (26*TS*TS);			/* 1664 kB */
   merror (buffer, "ahd_interpolate()");
   rgb  = (void *) buffer;
@@ -3103,35 +3076,26 @@
     for (left=0; left < width; left += TS-6) {
       memset (rgb, 0, 12*TS*TS);
 
-/*  Horizontally interpolate green into rgb[0]:			*/
-      for (row = top; row < top+TS && row < height; row++) {
+/*  Interpolate green horizontally and vertically:		*/
+      for (row = top < 2 ? 2:top; row < top+TS && row < height-2; row++) {
 	col = left + (FC(row,left) == 1);
 	if (col < 2) col += 2;
 	for (fc = FC(row,col); col < left+TS && col < width-2; col+=2) {
-	  pix = image + row*width + col;
+	  pix = image + row*width+col;
 	  val = ((pix[-1][1] + pix[0][fc] + pix[1][1]) * 2
 		- pix[-2][fc] - pix[2][fc]) >> 2;
-	  rgb[0][row-top][col-left][1] = CLIP(val);
-	}
-      }
-/*  Vertically interpolate green into rgb[1]:			*/
-      for (row = top < 2 ? 2:top; row < top+TS && row < height-2; row++) {
-	col = left + (FC(row,left) == 1);
-	for (fc = FC(row,col); col < left+TS && col < width; col+=2) {
-	  pix = image + row*width + col;
+	  rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]);
 	  val = ((pix[-width][1] + pix[0][fc] + pix[width][1]) * 2
 		- pix[-2*width][fc] - pix[2*width][fc]) >> 2;
-	  rgb[1][row-top][col-left][1] = CLIP(val);
+	  rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]);
 	}
       }
 /*  Interpolate red and blue, and convert to CIELab:		*/
       for (d=0; d < 2; d++)
-	for (row=top+1; row < top+TS-1 && row < height-1; row++) {
-	  tr = row-top;
+	for (row=top+1; row < top+TS-1 && row < height-1; row++)
 	  for (col=left+1; col < left+TS-1 && col < width-1; col++) {
-	    tc = col-left;
-	    pix = image + row*width + col;
<<Diff was trimmed, longer than 597 lines>>

---- CVS-web:
    http://cvs.pld-linux.org/SOURCES/dcraw.1?r1=1.4&r2=1.5&f=u
    http://cvs.pld-linux.org/SOURCES/dcraw.c?r1=1.5&r2=1.6&f=u




More information about the pld-cvs-commit mailing list