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