--- dcraw.c Wed Feb 02 23:18:25 2011 +++ dcraw.cc Thu Feb 03 00:52:38 2011 @@ -1,5 +1,14 @@ +/*RT*/#include +/*RT*/#include +/*RT*/#undef MAX +/*RT*/#undef MIN +/*RT*/#define NO_LCMS +/*RT*/#define NO_JPEG +/*RT*/#define LOCALTIME +/*RT*/#define DJGPP + /* dcraw.c -- Dave Coffin's raw photo decoder Copyright 1997-2010 by Dave Coffin, dcoffin a cybercom o net This is a command-line ANSI C program to convert raw photos from @@ -94,15 +103,16 @@ #define ushort UshORt typedef unsigned char uchar; typedef unsigned short ushort; +#include "dcraw.h" /* All global variables are defined here, and all functions that access them are prefixed with "CLASS". Note that a thread-safe C++ class cannot have non-const static local variables. - */ + FILE *ifp, *ofp; short order; const char *ifname; char *meta_data; char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64]; @@ -126,17 +136,17 @@ int half_size=0, four_color_rgb=0, document_mode=0, highlight=0; int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=-1; int output_color=1, output_bps=8, output_tiff=0, med_passes=0; int no_auto_bright=0; unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX }; -float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4]; -const double xyz_rgb[3][3] = { /* XYZ from RGB */ +float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4];*/ +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 } }; const float d65_white[3] = { 0.950456, 1, 1.088754 }; -int histogram[4][0x2000]; +/*int histogram[4][0x2000]; void (*write_thumb)(), (*write_fun)(); void (*load_raw)(), (*thumb_load_raw)(); jmp_buf failure; struct decode { @@ -150,12 +160,12 @@ struct ph1 { int format, key_off, black, black_off, split_col, tag_21a; float tag_210; } ph1; - -#define CLASS +*/ +#define CLASS DCraw:: #define FORC(cnt) for (c=0; c < cnt; c++) #define FORC3 FORC(3) #define FORC4 FORC(4) #define FORCC FORC(colors) @@ -269,10 +279,11 @@ fprintf (stderr,_("Unexpected end of file\n")); else fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp)); } data_error++; + /*RT*/ longjmp (failure, 1); } ushort CLASS sget2 (uchar *s) { if (order == 0x4949) /* "II" means little-endian */ @@ -342,11 +353,11 @@ 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); + swab ((char*)pixel, (char*)pixel, count*2); } void CLASS canon_600_fixed_wb (int temp) { static const short mul[4][5] = { @@ -534,14 +545,14 @@ /* getbits(-1) initializes the buffer getbits(n) where 0 <= n <= 25 returns an n-bit integer */ -unsigned CLASS getbithuff (int nbits, ushort *huff) +unsigned CLASS getbithuff_t::operator() (int nbits, ushort *huff) { - static unsigned bitbuf=0; - static int vbits=0, reset=0; +/*RT static unsigned bitbuf=0; */ +/*RT static int vbits=0, reset=0; */ unsigned c; if (nbits == -1) return bitbuf = vbits = reset = 0; if (nbits == 0 || vbits < 0) return 0; @@ -1284,11 +1295,11 @@ } } free (pixel); } -void CLASS jpeg_thumb(); +/*RT void CLASS jpeg_thumb(); */ void CLASS ppm_thumb() { char *thumb; thumb_length = thumb_width*thumb_height*3; @@ -1560,14 +1571,14 @@ } free (pixel); phase_one_correct(); } -unsigned CLASS ph1_bithuff (int nbits, ushort *huff) +unsigned CLASS ph1_bithuff_t::operator() (int nbits, ushort *huff) { - static UINT64 bitbuf=0; - static int vbits=0; +/*RT static UINT64 bitbuf=0; */ +/*RT static int vbits=0; */ unsigned c; if (nbits == -1) return bitbuf = vbits = 0; if (nbits == 0) return 0; @@ -1689,11 +1700,11 @@ maximum = 0xffff; raw_color = 1; } } -void CLASS unpacked_load_raw(); +/*RT void CLASS unpacked_load_raw(); */ void CLASS sinar_4shot_load_raw() { ushort *pixel; unsigned shot, row, col, r, c; @@ -1830,14 +1841,14 @@ free (data); if (top_margin) black /= top_margin * width; maximum = 0x3ff; } -unsigned CLASS pana_bits (int nbits) +unsigned CLASS pana_bits_t::operator() (int nbits) { - static uchar buf[0x4000]; - static int vbits; +/*RT static uchar buf[0x4000]; */ +/*RT static int vbits;*/ int byte; if (!nbits) return vbits=0; if (!vbits) { fread (buf+load_flags, 1, 0x4000-load_flags, ifp); @@ -2122,15 +2133,15 @@ #else METHODDEF(boolean) fill_input_buffer (j_decompress_ptr cinfo) { - static uchar jpeg_buffer[4096]; +/*RT static uchar jpeg_buffer[4096]; */ size_t nbytes; nbytes = fread (jpeg_buffer, 1, 4096, ifp); - swab (jpeg_buffer, jpeg_buffer, nbytes); + swab ((char*)jpeg_buffer, (char*)jpeg_buffer, nbytes); cinfo->src->next_input_byte = jpeg_buffer; cinfo->src->bytes_in_buffer = nbytes; return TRUE; } @@ -2398,13 +2409,13 @@ for (col=0; col < width; col++) read_shorts (image[row*width+col], colors); maximum = (1 << (thumb_misc & 31)) - 1; } -void CLASS sony_decrypt (unsigned *data, int len, int start, int key) +void CLASS sony_decrypt_t::operator()(unsigned *data, int len, int start, int key) { - static unsigned pad[128], p; +/*RT static unsigned pad[128], p;*/ if (start) { for (p=0; p < 4; p++) pad[p] = key = key * 48828125 + 1; pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31; @@ -2647,11 +2658,11 @@ /* RESTRICTED code starts here */ void CLASS foveon_decoder (unsigned size, unsigned code) { - static unsigned huff[1024]; +/*RT static unsigned huff[1024];*/ struct decode *cur; int i, len; if (!code) { for (i=0; i < size; i++) @@ -4331,11 +4342,11 @@ if (tag == tlen) thumb_length = get4(); fseek (ifp, save, SEEK_SET); } } -int CLASS parse_tiff_ifd (int base); +/*RT int CLASS parse_tiff_ifd (int base);*/ void CLASS parse_makernote (int base, int uptag) { static const uchar xlat[2][256] = { { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d, @@ -4459,11 +4470,11 @@ cam_mul[0] = getreal(type); cam_mul[2] = getreal(type); } if (tag == 0xd && type == 7 && get2() == 0xaaaa) { fread (buf97, 1, sizeof buf97, ifp); - i = (uchar *) memmem (buf97, sizeof buf97,"\xbb\xbb",2) - buf97 + 10; + i = (uchar *) memmem ((char*) buf97, sizeof buf97,"\xbb\xbb",2) - buf97 + 10; if (i < 70 && buf97[i] < 3) flip = "065"[buf97[i]]-'0'; } if (tag == 0x10 && type == 4) unique_id = get4(); @@ -4842,12 +4853,12 @@ if (tag == 64020) height = (getint(type)+1) & -2; fseek (ifp, save, SEEK_SET); } } -void CLASS parse_minolta (int base); -int CLASS parse_tiff (int base); +/*RT void CLASS parse_minolta (int base); */ +/*RT int CLASS parse_tiff (int base);*/ int CLASS parse_tiff_ifd (int base) { unsigned entries, tag, type, len, plen=16, save; int ifd, use_cm=0, cfa, i, j, c, ima_len=0; @@ -4857,11 +4868,11 @@ double cc[4][4], cm[4][3], cam_xyz[4][3], num; double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 }; unsigned sony_curve[] = { 0,0,0,0,0,4095 }; unsigned *buf, sony_offset=0, sony_length=0, sony_key=0; struct jhead jh; - FILE *sfp; +/*RT*/ IMFILE *sfp; if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0]) return 1; ifd = tiff_nifds++; for (j=0; j < 4; j++) @@ -4874,10 +4885,13 @@ switch (tag) { case 5: width = get2(); break; case 6: height = get2(); break; case 7: width += get2(); break; case 9: filters = get2(); break; + case 14: case 15: case 16: + maximum = get2(); + break; case 17: case 18: if (type == 3 && len == 1) cam_mul[(tag-17)*2] = get2() / 256.0; break; case 23: @@ -5272,16 +5286,17 @@ if (sony_length && (buf = (unsigned *) malloc(sony_length))) { fseek (ifp, sony_offset, SEEK_SET); fread (buf, sony_length, 1, ifp); sony_decrypt (buf, sony_length/4, 1, sony_key); sfp = ifp; - if ((ifp = tmpfile())) { - fwrite (buf, sony_length, 1, ifp); - fseek (ifp, 0, SEEK_SET); +/*RT*/ ifp = fopen (buf, sony_length); +// if ((ifp = tmpfile())) { +// fwrite (buf, sony_length, 1, ifp); +// fseek (ifp, 0, SEEK_SET); parse_tiff_ifd (-sony_offset); - fclose (ifp); - } +// fclose (ifp); +// } ifp = sfp; free (buf); } for (i=0; i < colors; i++) FORCC cc[i][c] *= ab[i]; @@ -5302,10 +5317,12 @@ int CLASS parse_tiff (int base) { int doff; + /*RT*/ if (exif_base == -1) exif_base = base; + fseek (ifp, base, SEEK_SET); order = get2(); if (order != 0x4949 && order != 0x4d4d) return 0; get2(); while ((doff = get4())) { @@ -5476,11 +5493,11 @@ */ void CLASS parse_external_jpeg() { const char *file, *ext; char *jname, *jfile, *jext; - FILE *save=ifp; +/*RT*/ IMFILE *save=ifp; ext = strrchr (ifname, '.'); file = strrchr (ifname, '/'); if (!file) file = strrchr (ifname, '\\'); if (!file) file = ifname-1; @@ -5504,11 +5521,12 @@ break; } *jext = '0'; } if (strcmp (jname, ifname)) { - if ((ifp = fopen (jname, "rb"))) { +/*RT*/ if ((ifp = fopen (jname))) { +// if ((ifp = fopen (jname, "rb"))) { if (verbose) fprintf (stderr,_("Reading metadata from %s ...\n"), jname); parse_tiff (12); thumb_offset = 0; is_raw = 1; @@ -5842,11 +5860,15 @@ raw_width = get2(); } order = get2(); hlen = get4(); if (get4() == 0x48454150) /* "HEAP" */ - parse_ciff (save+hlen, len-hlen); +/*RT*/ { +/*RT*/ ciff_base = save+hlen; +/*RT*/ ciff_len = len-hlen; + parse_ciff (save+hlen, len-hlen); +/*RT*/ } if (parse_tiff (save+6)) apply_tiff(); fseek (ifp, save+len, SEEK_SET); } return 1; } @@ -6626,14 +6648,14 @@ { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } }, { "SONY DSLR-A850", 128, 0, { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } }, { "SONY DSLR-A900", 128, 0, { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } }, - { "SONY NEX-3", 138, 0, /* DJC */ - { 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } }, - { "SONY NEX-5", 116, 0, /* DJC */ - { 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } }, +// { "SONY NEX-3", 138, 0, /* DJC */ +// { 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } }, +// { "SONY NEX-5", 116, 0, /* DJC */ +// { 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } }, { "SONY NEX", 128, 0, /* Adobe's matrix */ { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } }, { "SONY SLT-A33", 128, 0, { 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } }, { "SONY SLT-A55", 128, 0, @@ -6877,17 +6899,25 @@ hlen = get4(); fseek (ifp, 0, SEEK_SET); fread (head, 1, 32, ifp); fseek (ifp, 0, SEEK_END); flen = fsize = ftell(ifp); + + /*RT*/ if (fsize<100000) { + is_raw = 0; + return; + } + if ((cp = (char *) memmem (head, 32, "MMMM", 4)) || (cp = (char *) memmem (head, 32, "IIII", 4))) { parse_phase_one (cp-head); if (cp-head && parse_tiff(0)) apply_tiff(); } else if (order == 0x4949 || order == 0x4d4d) { if (!memcmp (head+6,"HEAPCCDR",8)) { data_offset = hlen; +/*RT*/ ciff_base = hlen; +/*RT*/ ciff_len = fsize - hlen; parse_ciff (hlen, flen - hlen); } else if (parse_tiff(0)) apply_tiff(); } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) && !memcmp (head+6,"Exif",4)) { fseek (ifp, 4, SEEK_SET); @@ -6925,10 +6955,11 @@ parse_fuji (i); } fseek (ifp, 100, SEEK_SET); parse_tiff (data_offset = get4()); parse_tiff (thumb_offset+12); +/*RT*/ exif_base = thumb_offset+12; apply_tiff(); } else if (!memcmp (head,"RIFF",4)) { fseek (ifp, 0, SEEK_SET); parse_riff(); } else if (!memcmp (head,"\0\001\0\001\0@",6)) { @@ -7007,11 +7038,11 @@ if (height == 2624 && width == 3936) /* Pentax K10D and Samsung GX10 */ { height = 2616; width = 3896; } if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */ { height = 3124; width = 4688; filters = 0x16161616; } if (!strcmp(model,"K-r") || !strcmp(model,"K-x")) - { width = 4309; filters = 0x16161616; } +/*RT*/ { width = 4308; filters = 0x16161616; } if (!strcmp(model,"K-5")) { left_margin = 10; width = 4950; filters = 0x16161616; } if (!strcmp(model,"K-7")) { height = 3122; width = 4684; filters = 0x16161616; top_margin = 2; } if (!strcmp(model,"645D")) @@ -8589,17 +8620,17 @@ for (col=0; col < width; col++, soff += cstep) if (output_bps == 8) FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8; else FORCC ppm2[col*colors+c] = curve[image[soff][c]]; if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa) - swab (ppm2, ppm2, width*colors*2); + swab ((char*)ppm2, (char*)ppm2, width*colors*2); fwrite (ppm, colors*output_bps/8, width, ofp); } free (ppm); } -int CLASS main (int argc, const char **argv) +/*int CLASS main (int argc, const char **argv) { int arg, status=0; int timestamp_only=0, thumbnail_only=0, identify_only=0; int user_qual=-1, user_black=-1, user_sat=-1, user_flip=-1; int use_fuji_rotate=1, write_to_stdout=0, quality, i, c; @@ -8708,11 +8739,11 @@ case 'z': timestamp_only = 1; break; case 'e': thumbnail_only = 1; break; case 'i': identify_only = 1; break; case 'c': write_to_stdout = 1; break; case 'v': verbose = 1; break; - case 'h': half_size = 1; /* "-h" implies "-f" */ + case 'h': half_size = 1; // "-h" implies "-f" case 'f': four_color_rgb = 1; break; case 'A': FORC4 greybox[c] = atoi(argv[arg++]); case 'a': use_auto_wb = 1; break; case 'w': use_camera_wb = 1; break; case 'M': use_camera_matrix = (opm == '+'); break; @@ -8971,5 +9002,6 @@ else shot_select = 0; } } return status; } +*/