Author: pluto Date: Tue Sep 6 07:13:45 2005 GMT Module: SOURCES Tag: HEAD ---- Log message: - updated. 0edfe10acf69c93724e271646ae79df5 dcraw.1 2fc0584127c3746debba941273f8b417 dcraw.c
---- Files affected: SOURCES: dcraw.1 (1.2 -> 1.3) , dcraw.c (1.3 -> 1.4) ---- Diffs: ================================================================ Index: SOURCES/dcraw.1 diff -u SOURCES/dcraw.1:1.2 SOURCES/dcraw.1:1.3 --- SOURCES/dcraw.1:1.2 Thu Apr 28 20:38:44 2005 +++ SOURCES/dcraw.1 Tue Sep 6 09:13:40 2005 @@ -9,7 +9,7 @@ .\" dcoffin a cybercom o net .\" http://www.cybercom.net/~dcoffin .\" -.TH dcraw 1 "April 28, 2005" +.TH dcraw 1 "August 30, 2005" .LO 1 .SH NAME dcraw - convert raw digital photos to PPM format @@ -23,21 +23,31 @@ format. .SH OPTIONS .TP +.B -v +Print verbose messages. The default is to print only warnings +and errors. +.TP +.B -z +Change the access and modification times of a JPEG or raw file to +when the photo was taken, assuming that the camera clock was set +to Universal Time. +.TP .B -i Identify files but don't decode them. Exit status is 0 if .B dcraw can decode the last file, 1 if it can't. .TP +.B "" +.B dcraw +cannot decode JPEG files!! +.TP .B -c Write binary image data to standard output. By default, .B dcraw creates files with a ".ppm" extension. .TP -.B -v -Print verbose messages. Default is to print only warnings and errors. -.TP .B -d Show the raw data as a grayscale image with no interpolation. Good for photographing black-and-white documents. @@ -52,10 +62,8 @@ .BR -q . .TP .B -f -Interpolate RGB as four colors. This causes a slight loss -of detail, so use -.B -f -only if you see false 2x2 mesh patterns in blue sky. +Interpolate RGB as four colors. This blurs the image a little, +but it eliminates false 2x2 mesh patterns. .TP .B -a Automatic color balance. The default is to use a fixed @@ -74,6 +82,9 @@ .B -b brightness Change the output brightness. Default is 1.0. .TP +.B -k black +Change the black point. Default depends on the camera. +.TP .B -n By default, .B dcraw @@ -87,12 +98,21 @@ .B dcraw converts to sRGB colorspace. .TP +.B -j +For Fuji\ Super\ CCD cameras, show the image tilted 45 degrees +so that each output pixel corresponds to one raw pixel. +.TP .B -s -For cameras based on the Fuji Super CCD SR, use the secondary -sensors, in effect underexposing the image by four stops to -reveal detail in the highlights. For all other cameras, +For Fuji\ Super\ CCD\ SR cameras, use the secondary sensors, in +effect underexposing the image by four stops to reveal detail +in the highlights. +.TP +.B "" +For all other cameras, +.B -j +and .B -s -is silently ignored. +are silently ignored. .TP .B -t [0-7] Flip the output image. The most common flips are 5 @@ -117,7 +137,12 @@ .BR -4 , written in Adobe PhotoShop format. File extension is ".psd". .SH "SEE ALSO" -ppm(5), ppm2tiff(1), pnmtotiff(1), pnmtopng(1), gphoto2(1). +.BR ppm (5), +.BR ppm2tiff (1), +.BR pnmtotiff (1), +.BR pnmtopng (1), +.BR gphoto2 (1), +.BR djpeg (1) .SH BUGS The .B -w @@ -125,7 +150,7 @@ .P No attempt is made to save camera settings or thumbnail images. .P -Author stubbornly refuses to add more output formats. +The author stubbornly refuses to add more output formats. .P Don't expect .B dcraw ================================================================ Index: SOURCES/dcraw.c diff -u SOURCES/dcraw.c:1.3 SOURCES/dcraw.c:1.4 --- SOURCES/dcraw.c:1.3 Thu Apr 28 20:38:44 2005 +++ SOURCES/dcraw.c Tue Sep 6 09:13:40 2005 @@ -48,14 +48,18 @@ #include <io.h> #endif #ifdef WIN32 +#include <sys/utime.h> #include <winsock2.h> #pragma comment(lib, "ws2_32.lib") #define strcasecmp stricmp typedef __int64 INT64; +typedef unsigned __int64 UINT64; #else #include <unistd.h> +#include <utime.h> #include <netinet/in.h> typedef long long INT64; +typedef unsigned long long UINT64; #endif #ifdef LJPEG_DECODE @@ -79,6 +83,7 @@ FILE *ifp; short order; char *ifname, make[64], model[70], model2[64], *meta_data; +float flash_used, canon_5814; time_t timestamp; int data_offset, meta_offset, meta_length, nikon_curve_offset; int tiff_data_compression, kodak_data_compression; @@ -86,7 +91,7 @@ int height, width, fuji_width, colors, tiff_samples; int black, maximum, clip_max, clip_color=1; int iheight, iwidth, shrink; -int is_dng, is_canon, is_foveon, use_coeff, use_gamma; +int dng_version, is_canon, is_foveon, raw_color, use_gamma; int trim, flip, xmag, ymag; int zero_after_ff; unsigned filters; @@ -96,7 +101,11 @@ int four_color_rgb=0, document_mode=0, quick_interpolate=0; int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_rgb=0; int fuji_secondary, use_secondary=0; -float cam_mul[4], pre_mul[4], coeff[3][4]; +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 }, + { 0.212671, 0.715160, 0.072169 }, + { 0.019334, 0.119193, 0.950227 } }; #define camera_red cam_mul[0] #define camera_blue cam_mul[2] int histogram[3][0x2000]; @@ -120,6 +129,12 @@ #define FORC4 for (c=0; c < 4; c++) #define FORCC for (c=0; c < colors; c++) +#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))) + /* In order to inline this calculation, I make the risky assumption that all filter patterns can be described @@ -182,41 +197,49 @@ longjmp (failure, 1); } -/* - Get a 2-byte integer, making no assumptions about CPU byte order. - Nor should we assume that the compiler evaluates left-to-right. - */ -ushort CLASS get2() +ushort CLASS sget2 (uchar *s) { - uchar a, b; - - a = fgetc(ifp); b = fgetc(ifp); - if (order == 0x4949) /* "II" means little-endian */ - return a | b << 8; + return s[0] | s[1] << 8; else /* "MM" means big-endian */ - return a << 8 | b; + return s[0] << 8 | s[1]; } -/* - Same for a 4-byte integer. - */ -int CLASS get4() +ushort CLASS get2() { - uchar a, b, c, d; - - a = fgetc(ifp); b = fgetc(ifp); - c = fgetc(ifp); d = fgetc(ifp); + uchar str[2] = { 0xff,0xff }; + fread (str, 1, 2, ifp); + return sget2(str); +} +int CLASS sget4 (uchar *s) +{ if (order == 0x4949) - return a | b << 8 | c << 16 | d << 24; + return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; else - return a << 24 | b << 16 | c << 8 | d; + return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; +} + +int CLASS get4() +{ + uchar str[4] = { 0xff,0xff,0xff,0xff }; + fread (str, 1, 4, ifp); + return sget4(str); +} + +double CLASS getrat() +{ + double num = get4(); + return num / get4(); +} + +float CLASS int_to_float (int i) +{ + union { int i; float f; } u; + u.i = i; + return u.f; } -/* - Faster than calling get2() multiple times. - */ void CLASS read_shorts (ushort *pixel, int count) { fread (pixel, 2, count, ifp); @@ -224,13 +247,131 @@ swab (pixel, pixel, count*2); } +void CLASS canon_600_fixed_wb (int temp) +{ + static const short mul[4][5] = { + { 667, 358,397,565,452 }, + { 731, 390,367,499,517 }, + { 1119, 396,348,448,537 }, + { 1399, 485,431,508,688 } }; + int lo, hi, i; + float frac=0; + + for (lo=4; --lo; ) + if (*mul[lo] <= temp) break; + for (hi=0; hi < 3; hi++) + if (*mul[hi] >= temp) break; + if (lo != hi) + frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]); + for (i=1; i < 5; i++) + pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]); +} + +/* Return values: 0 = white 1 = near white 2 = not white */ +int CLASS canon_600_color (int ratio[2], int mar) +{ + int clipped=0, target, miss; + + if (flash_used) { + if (ratio[1] < -104) + { ratio[1] = -104; clipped = 1; } + if (ratio[1] > 12) + { ratio[1] = 12; clipped = 1; } + } else { + if (ratio[1] < -264 || ratio[1] > 461) return 2; + if (ratio[1] < -50) + { ratio[1] = -50; clipped = 1; } + if (ratio[1] > 307) + { ratio[1] = 307; clipped = 1; } + } + target = flash_used || ratio[1] < 197 + ? -38 - (398 * ratio[1] >> 10) + : -123 + (48 * ratio[1] >> 10); + if (target - mar <= ratio[0] && + target + 20 >= ratio[0] && !clipped) return 0; + miss = target - ratio[0]; + if (abs(miss) >= mar*4) return 2; + if (miss < -20) miss = -20; + if (miss > mar) miss = mar; + ratio[0] = target - miss; + return 1; +} + +void CLASS canon_600_auto_wb () +{ + int mar, row, col, i, j, st, count[] = { 0,0 }; + int test[8], total[2][8], ratio[2][2], stat[2]; + + memset (&total, 0, sizeof total); + i = canon_5814 + 0.5; + if (i < 10) mar = 150; + else if (i > 12) mar = 20; + else mar = 280 - 20 * i; + if (flash_used) mar = 80; + for (row=14; row < height-14; row+=4) + for (col=10; col < width; col+=2) { + for (i=0; i < 8; i++) + test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] = + BAYER(row+(i >> 1),col+(i & 1)); + for (i=0; i < 8; i++) + if (test[i] < 150 || test[i] > 1500) goto next; + for (i=0; i < 4; i++) + if (abs(test[i] - test[i+4]) > 50) goto next; + for (i=0; i < 2; i++) { + for (j=0; j < 4; j+=2) + ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j]; + stat[i] = canon_600_color (ratio[i], mar); + } + if ((st = stat[0] | stat[1]) > 1) goto next; + for (i=0; i < 2; i++) + if (stat[i]) + for (j=0; j < 2; j++) + test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10; + for (i=0; i < 8; i++) + total[st][i] += test[i]; + count[st]++; +next: continue; + } + if (count[0] | count[1]) { + st = count[0]*200 < count[1]; + for (i=0; i < 4; i++) + pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]); + } +} + +void CLASS canon_600_coeff () +{ + static const short table[6][12] = { + { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, + { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 }, + { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 }, + { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 }, + { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, + { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } }; + int t=0, i, c; + float mc, yc; + + mc = pre_mul[1] / pre_mul[2]; + yc = pre_mul[3] / pre_mul[2]; + if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1; + if (mc > 1.28 && mc <= 2) { + if (yc < 0.8789) t=3; + else if (yc <= 2) t=4; + } + if (flash_used) t=5; + for (raw_color = i=0; i < 3; i++) + FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0; +} + void CLASS canon_600_load_raw() { uchar data[1120], *dp; ushort pixel[896], *pix; - int irow, orow, col; + int irow, row, col, val; + static const short mul[4][2] = + { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } }; - for (irow=orow=0; irow < height; irow++) + for (irow=row=0; irow < height; irow++) { fread (data, 1120, 1, ifp); for (dp=data, pix=pixel; dp < data+1120; dp+=10, pix+=8) @@ -245,14 +386,23 @@ pix[7] = (dp[8] << 2) + (dp[9] >> 6 ); } for (col=0; col < width; col++) - BAYER(orow,col) = pixel[col]; + BAYER(row,col) = pixel[col]; for (col=width; col < 896; col++) black += pixel[col]; - if ((orow+=2) > height) - orow = 1; + if ((row+=2) > height) row = 1; } - black /= (896 - width) * height; - maximum = 0x3ff; + black = black / ((896 - width) * height) - 4; + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + val = (BAYER(row,col) - black) * mul[row & 3][col & 1] >> 9; + if (val < 0) val = 0; + BAYER(row,col) = val; + } + canon_600_fixed_wb(1311); + canon_600_auto_wb(); + canon_600_coeff(); + maximum = (0x3ff - black) * 1109 >> 9; + black = 0; } void CLASS canon_a5_load_raw() @@ -291,21 +441,22 @@ unsigned CLASS getbits (int nbits) { static unsigned long bitbuf=0; - static int vbits=0; + static int vbits=0, reset=0; unsigned c, ret; - if (nbits == 0) return 0; + if (nbits == 0 || nbits > vbits) return 0; + if (nbits == -2) + return ftell(ifp) + (-vbits >> 3); if (nbits == -1) - ret = bitbuf = vbits = 0; + ret = bitbuf = vbits = reset = 0; else { ret = bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - nbits); vbits -= nbits; } - while (vbits < LONG_BIT - 7) { + while (!reset && vbits < LONG_BIT - 7) { c = fgetc(ifp); + if ((reset = zero_after_ff && c == 0xff && fgetc(ifp))) break; bitbuf = (bitbuf << 8) + c; - if (c == 0xff && zero_after_ff) - fgetc(ifp); vbits += 8; } return ret; @@ -538,7 +689,7 @@ enough to decode Canon, Kodak and Adobe DNG images. */ struct jhead { - int bits, high, wide, clrs, vpred[4]; + int bits, high, wide, clrs, restart, vpred[4]; struct decode *huff[4]; ushort *row; }; @@ -551,6 +702,7 @@ init_decoder(); for (i=0; i < 4; i++) jh->huff[i] = free_decode; + jh->restart = INT_MAX; fread (data, 2, 1, ifp); if (data[0] != 0xff || data[1] != 0xd8) return 0; do { @@ -571,14 +723,14 @@ jh->huff[*dp] = free_decode; dp = make_decoder (++dp, 0); } + break; + case 0xffdd: + jh->restart = data[0] << 8 | data[1]; } } while (tag != 0xffda); jh->row = calloc (jh->wide*jh->clrs, 2); merror (jh->row, " jpeg_start()"); - for (i=0; i < 4; i++) - jh->vpred[i] = 1 << (jh->bits-1); zero_after_ff = 1; - getbits(-1); return 1; } @@ -588,17 +740,24 @@ while (dindex->branch[0]) dindex = dindex->branch[getbits(1)]; - diff = getbits (len = dindex->leaf); + len = dindex->leaf; + if (len == 16 && (!dng_version || dng_version >= 0x1010000)) + return -32768; + diff = getbits(len); if ((diff & (1 << (len-1))) == 0) diff -= (1 << len) - 1; return diff; } -void CLASS ljpeg_row (struct jhead *jh) +void CLASS ljpeg_row (int jrow, struct jhead *jh) { int col, c, diff; ushort *outp=jh->row; + if (jrow * jh->wide % jh->restart == 0) { + FORC4 jh->vpred[c] = 1 << (jh->bits-1); + getbits(-1); + } for (col=0; col < jh->wide; col++) for (c=0; c < jh->clrs; c++) { diff = ljpeg_diff (jh->huff[c]); @@ -617,9 +776,11 @@ jwide = jh.wide * jh.clrs; for (jrow=0; jrow < jh.high; jrow++) { - ljpeg_row (&jh); + ljpeg_row (jrow, &jh); for (jcol=0; jcol < jwide; jcol++) { - val = curve[jh.row[jcol]]; + val = jh.row[jcol]; + if (jh.bits <= 12) + val = curve[val]; jidx = jrow*jwide + jcol; if (raw_width == 5108) { i = jidx / (1680*jh.high); @@ -659,8 +820,10 @@ void CLASS adobe_copy_pixel (int row, int col, ushort **rp) { - unsigned r=row, c=col; + unsigned r, c; + r = row -= top_margin; + c = col -= left_margin; if (fuji_secondary && use_secondary) (*rp)++; if (filters) { if (fuji_width) { @@ -670,11 +833,12 @@ if (r < height && c < width) BAYER(r,c) = **rp < 0x1000 ? curve[**rp] : **rp; *rp += 1 + fuji_secondary; - } else - for (c=0; c < tiff_samples; c++) { - image[row*width+col][c] = **rp < 0x1000 ? curve[**rp] : **rp; - (*rp)++; - } + } else { + if (r < height && c < width) + for (c=0; c < tiff_samples; c++) + image[row*width+col][c] = (*rp)[c] < 0x1000 ? curve[(*rp)[c]]:(*rp)[c]; + *rp += tiff_samples; + } if (fuji_secondary && use_secondary) (*rp)--; } @@ -699,7 +863,7 @@ twide = raw_width-tcol; for (jrow=0; jrow < jh.high; jrow++) { - ljpeg_row (&jh); + ljpeg_row (jrow, &jh); for (rp=jh.row, jcol=0; jcol < twide; jcol++) adobe_copy_pixel (trow+jrow, tcol+jcol, &rp); } @@ -764,7 +928,6 @@ if (diff >= csize) diff = csize-1; BAYER(row,col-left_margin) = curve[diff]; } - maximum = curve[csize-1]; free (curve); } @@ -851,9 +1014,11 @@ } /* - Separates a Pentax Optio 33WR from a Nikon E3700. + Returns 0 for a Pentax Optio 33WR, + 1 for a Nikon E3700, + 2 for an Olympus C740UZ. */ -int CLASS pentax_optio33() +int CLASS nikon_3700() { int i, sum[] = { 0, 0 }; uchar tail[952]; @@ -862,7 +1027,8 @@ fread (tail, 1, sizeof tail, ifp); for (i=0; i < sizeof tail; i++) sum[(i>>2) & 1] += tail[i]; - return sum[0] < sum[1]*4; + if (sum[1] > 4*sum[0]) return 2; <<Diff was trimmed, longer than 597 lines>> ---- CVS-web: http://cvs.pld-linux.org/SOURCES/dcraw.1?r1=1.2&r2=1.3&f=u http://cvs.pld-linux.org/SOURCES/dcraw.c?r1=1.3&r2=1.4&f=u _______________________________________________ pld-cvs-commit mailing list [email protected] http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit
