--- dcraw.c 2013-06-28 08:27:29 -0400 +++ dcraw.cc 2013-06-29 20:49:02 -0400 @@ -1,3 +1,15 @@ +/*RT*/#include +/*RT*/#include +/*RT*/#undef MAX +/*RT*/#undef MIN +/*RT*/#undef ABS +/*RT*/#include "rt_math.h" +/*RT*/#define NO_LCMS +/*RT*/#define NO_JPEG +/*RT*/#define NO_JASPER +/*RT*/#define LOCALTIME +/*RT*/#define DJGPP + /* dcraw.c -- Dave Coffin's raw photo decoder Copyright 1997-2013 by Dave Coffin, dcoffin a cybercom o net @@ -29,17 +41,17 @@ #define _GNU_SOURCE #endif #define _USE_MATH_DEFINES -#include -#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #if defined(DJGPP) || defined(__MINGW32__) @@ -98,87 +110,37 @@ #define LONG_BIT (8 * sizeof (long)) #endif -#if !defined(uchar) -#define uchar unsigned char -#endif -#if !defined(ushort) -#define ushort unsigned short -#endif +#define ushort UshORt +typedef unsigned char uchar; +typedef unsigned short ushort; +#include "dcraw.h" /* - All global variables are defined here, and all functions that + RT 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, xtrans[6][6]; -char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64]; -float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len; -time_t timestamp; -off_t strip_offset, data_offset; -off_t thumb_offset, meta_offset, profile_offset; -unsigned shot_order, kodak_cbpp, exif_cfa, unique_id; -unsigned thumb_length, meta_length, profile_length; -unsigned thumb_misc, *oprof, fuji_layout, shot_select=0, multi_out=0; -unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress; -unsigned black, cblack[4], maximum, mix_green, raw_color, zero_is_bad; -unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error; -unsigned tile_width, tile_length, gpsdata[32], load_flags; -unsigned flip, tiff_flip, filters, colors; -ushort raw_height, raw_width, height, width, top_margin, left_margin; -ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height; -ushort *raw_image, (*image)[4]; -ushort white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4]; -double pixel_aspect, aber[4]={1,1,1,1}, gamm[6]={ 0.45,4.5,0,0,0,0 }; -float bright=1, user_mul[4]={0,0,0,0}, threshold=0; -int mask[8][4]; -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 */ +*/ +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]; -void (*write_thumb)(), (*write_fun)(); -void (*load_raw)(), (*thumb_load_raw)(); -jmp_buf failure; - -struct decode { - struct decode *branch[2]; - int leaf; -} first_decode[2048], *second_decode, *free_decode; - -struct tiff_ifd { - int width, height, bps, comp, phint, offset, flip, samples, bytes; - int tile_width, tile_length; -} tiff_ifd[10]; - -struct ph1 { - int format, key_off, black, black_off, split_col, tag_21a; - float tag_210; -} ph1; -#define CLASS +/* RT: Removed unused structs */ +#define CLASS DCraw:: #define FORC(cnt) for (c=0; c < cnt; c++) #define FORC3 FORC(3) #define FORC4 FORC(4) #define FORCC FORC(colors) -#define SQR(x) ((x)*(x)) +#define SQR(x) rtengine::SQR(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 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,65535) +#define MIN(a,b) rtengine::min(a,static_cast(b)) +#define MAX(a,b) rtengine::max(a,static_cast(b)) +#define LIM(x,min,max) rtengine::LIM(x,static_cast(min),static_cast(max)) +#define ULIM(x,y,z) rtengine::ULIM(x,static_cast(y),static_cast(z)) +#define CLIP(x) rtengine::CLIP(x) #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; } /* @@ -250,10 +212,11 @@ { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 }, { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 }, { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 }, - { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } }; + { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } }; - if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15]; + if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15]; if (filters == 9) return xtrans[(row+top_margin+6)%6][(col+left_margin+6)%6]; + return FC(row,col); } @@ -296,6 +259,7 @@ fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp)); } data_error++; +/*RT*/ longjmp (failure, 1); } ushort CLASS sget2 (uchar *s) @@ -369,7 +333,7 @@ { 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) @@ -541,10 +505,10 @@ return 0; } -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 > 25) return 0; @@ -1209,14 +1173,14 @@ int i, nz; char tail[424]; - fseek (ifp, -sizeof tail, SEEK_END); + fseek (ifp, -(int)sizeof tail, SEEK_END); fread (tail, 1, sizeof tail, ifp); for (nz=i=0; i < sizeof tail; i++) if (tail[i]) nz++; return nz > 20; } -void CLASS jpeg_thumb(); +/*RT void CLASS jpeg_thumb(); */ void CLASS ppm_thumb() { @@ -1494,10 +1458,10 @@ } } -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) @@ -1757,10 +1721,10 @@ 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; @@ -2049,11 +2013,11 @@ 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; @@ -2373,10 +2337,9 @@ 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; @@ -2690,7 +2653,7 @@ void CLASS foveon_decoder (unsigned size, unsigned code) { - static unsigned huff[1024]; +/*RT static unsigned huff[1024];*/ struct decode *cur; int i, len; @@ -4002,240 +3965,9 @@ image[row*width+col][c] = sum[c] / sum[c+4]; } } + +/* RT: delete interpolation functions */ -void CLASS lin_interpolate() -{ - int code[16][16][32], size=16, *ip, sum[4]; - int f, c, i, x, y, row, col, shift, color; - ushort *pix; - - if (verbose) fprintf (stderr,_("Bilinear interpolation...\n")); - if (filters == 9) size = 6; - border_interpolate(1); - for (row=0; row < size; row++) - for (col=0; col < size; col++) { - ip = code[row][col]+1; - f = fcol(row,col); - memset (sum, 0, sizeof sum); - for (y=-1; y <= 1; y++) - for (x=-1; x <= 1; x++) { - shift = (y==0) + (x==0); - color = fcol(row+y,col+x); - if (color == f) continue; - *ip++ = (width*y + x)*4 + color; - *ip++ = shift; - *ip++ = color; - sum[color] += 1 << shift; - } - code[row][col][0] = (ip - code[row][col]) / 3; - FORCC - if (c != f) { - *ip++ = c; - *ip++ = 256 / sum[c]; - } - } - for (row=1; row < height-1; row++) - for (col=1; col < width-1; col++) { - pix = image[row*width+col]; - ip = code[row % size][col % size]; - memset (sum, 0, sizeof sum); - for (i=*ip++; 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] >> 8; - } -} - -/* - This algorithm is officially called: - - "Interpolation using a Threshold-based variable number of gradients" - - described in http://scien.stanford.edu/pages/labsite/1999/psych221/projects/99/tingchen/algodep/vargra.html - - I've extended the basic idea to work with non-Bayer filter arrays. - Gradients are numbered clockwise from NW=0 to W=7. - */ -void CLASS vng_interpolate() -{ - static const signed char *cp, terms[] = { - -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01, - -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01, - -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03, - -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06, - -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04, - -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01, - -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40, - -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11, - -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11, - -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22, - -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44, - -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10, - -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04, - +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40, - +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20, - +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08, - +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20, - +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44, - +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60, - +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80, - +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40, - +1,+0,+2,+1,0,0x10 - }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 }; - ushort (*brow[5])[4], *pix; - int prow=8, pcol=2, *ip, *code[16][16], gval[8], gmin, gmax, sum[4]; - int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag; - int g, diff, thold, num, c; - - lin_interpolate(); - if (verbose) fprintf (stderr,_("VNG interpolation...\n")); - - if (filters == 1) prow = pcol = 16; - if (filters == 9) prow = pcol = 6; - ip = (int *) calloc (prow*pcol, 1280); - merror (ip, "vng_interpolate()"); - for (row=0; row < prow; row++) /* Precalculate for VNG */ - for (col=0; col < pcol; col++) { - code[row][col] = ip; - for (cp=terms, t=0; t < 64; t++) { - y1 = *cp++; x1 = *cp++; - y2 = *cp++; x2 = *cp++; - weight = *cp++; - grads = *cp++; - color = fcol(row+y1,col+x1); - if (fcol(row+y2,col+x2) != color) continue; - diag = (fcol(row,col+1) == color && fcol(row+1,col) == color) ? 2:1; - if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue; - *ip++ = (y1*width + x1)*4 + color; - *ip++ = (y2*width + x2)*4 + color; - *ip++ = weight; - for (g=0; g < 8; g++) - if (grads & 1< gval[g]) gmin = gval[g]; - if (gmax < gval[g]) gmax = gval[g]; - } - if (gmax == 0) { - memcpy (brow[2][col], pix, sizeof *image); - continue; - } - thold = gmin + (gmax >> 1); - memset (sum, 0, sizeof sum); - color = fcol(row,col); - for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */ - if (gval[g] <= thold) { - FORCC - if (c == color && ip[1]) - sum[c] += (pix[c] + pix[ip[1]]) >> 1; - else - sum[c] += pix[ip[0] + c]; - num++; - } - } - FORCC { /* Save to buffer */ - t = pix[color]; - if (c != color) - t += (sum[c] - sum[color]) / num; - brow[2][col][c] = CLIP(t); - } - } - if (row > 3) /* Write buffer to image */ - memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); - for (g=0; g < 4; g++) - brow[(g-1) & 3] = brow[g]; - } - memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); - memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image); - free (brow[4]); - free (code[0][0]); -} - -/* - Patterned Pixel Grouping Interpolation by Alain Desbiolles -*/ -void CLASS ppg_interpolate() -{ - int dir[5] = { 1, width, -1, -width, 1 }; - int row, col, diff[2], guess[2], c, d, i; - ushort (*pix)[4]; - - border_interpolate(3); - if (verbose) fprintf (stderr,_("PPG interpolation...\n")); - -/* Fill in the green layer with gradients and pattern recognition: */ - for (row=3; row < height-3; row++) - for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) { - pix = image + row*width+col; - for (i=0; (d=dir[i]) > 0; i++) { - guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2 - - pix[-2*d][c] - pix[2*d][c]; - diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) + - ABS(pix[ 2*d][c] - pix[ 0][c]) + - ABS(pix[ -d][1] - pix[ d][1]) ) * 3 + - ( ABS(pix[ 3*d][1] - pix[ d][1]) + - ABS(pix[-3*d][1] - pix[-d][1]) ) * 2; - } - d = dir[i = diff[0] > diff[1]]; - pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]); - } -/* Calculate red and blue for each green pixel: */ - for (row=1; row < height-1; row++) - for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) { - pix = image + row*width+col; - for (i=0; (d=dir[i]) > 0; c=2-c, i++) - pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1] - - pix[-d][1] - pix[d][1]) >> 1); - } -/* Calculate blue for red pixels and vice versa: */ - for (row=1; row < height-1; row++) - for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) { - pix = image + row*width+col; - for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) { - diff[i] = ABS(pix[-d][c] - pix[d][c]) + - ABS(pix[-d][1] - pix[0][1]) + - ABS(pix[ d][1] - pix[0][1]); - guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1] - - pix[-d][1] - pix[d][1]; - } - if (diff[0] != diff[1]) - pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1); - else - pix[0][c] = CLIP((guess[0]+guess[1]) >> 2); - } -} void CLASS cielab (ushort rgb[3], short lab[3]) { @@ -4496,112 +4228,7 @@ } #undef fcol -/* - Adaptive Homogeneity-Directed interpolation is based on - the work of Keigo Hirakawa, Thomas Parks, and Paul Lee. - */ -void CLASS ahd_interpolate() -{ - int i, j, top, left, row, col, tr, tc, c, d, val, hm[2]; - static const int dir[4] = { -1, 1, -TS, TS }; - unsigned ldiff[2][4], abdiff[2][4], leps, abeps; - ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4]; - 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); - 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); - - for (top=2; top < height-5; top += TS-6) - for (left=2; left < width-5; left += TS-6) { -/* Interpolate green horizontally and vertically: */ - for (row=top; row < top+TS && row < height-2; row++) { - col = left + (FC(row,left) & 1); - for (c = FC(row,col); col < left+TS && col < width-2; col+=2) { - pix = image + row*width+col; - val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2 - - pix[-2][c] - pix[2][c]) >> 2; - rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]); - val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2 - - pix[-2*width][c] - pix[2*width][c]) >> 2; - 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-3; row++) - for (col=left+1; col < left+TS-1 && col < width-3; col++) { - pix = image + row*width+col; - rix = &rgb[d][row-top][col-left]; - lix = &lab[d][row-top][col-left]; - if ((c = 2 - FC(row,col)) == 1) { - c = FC(row+1,col); - val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c] - - rix[-1][1] - rix[1][1] ) >> 1); - rix[0][2-c] = CLIP(val); - val = pix[0][1] + (( pix[-width][c] + pix[width][c] - - rix[-TS][1] - rix[TS][1] ) >> 1); - } else - val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c] - + pix[+width-1][c] + pix[+width+1][c] - - rix[-TS-1][1] - rix[-TS+1][1] - - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2); - rix[0][c] = CLIP(val); - c = FC(row,col); - rix[0][c] = pix[0][c]; - cielab (rix[0],lix[0]); - } -/* Build homogeneity maps from the CIELab images: */ - memset (homo, 0, 2*TS*TS); - for (row=top+2; row < top+TS-2 && row < height-4; row++) { - tr = row-top; - for (col=left+2; col < left+TS-2 && col < width-4; col++) { - tc = col-left; - for (d=0; d < 2; d++) { - lix = &lab[d][tr][tc]; - for (i=0; i < 4; i++) { - ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]); - abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1]) - + SQR(lix[0][2]-lix[dir[i]][2]); - } - } - leps = MIN(MAX(ldiff[0][0],ldiff[0][1]), - MAX(ldiff[1][2],ldiff[1][3])); - abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]), - MAX(abdiff[1][2],abdiff[1][3])); - for (d=0; d < 2; d++) - for (i=0; i < 4; i++) - if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps) - homo[d][tr][tc]++; - } - } -/* Combine the most homogenous pixels for the final result: */ - for (row=top+3; row < top+TS-3 && row < height-5; row++) { - tr = row-top; - for (col=left+3; col < left+TS-3 && col < width-5; col++) { - tc = col-left; - for (d=0; d < 2; d++) - for (hm[d]=0, i=tr-1; i <= tr+1; i++) - for (j=tc-1; j <= tc+1; j++) - hm[d] += homo[d][i][j]; - if (hm[0] != hm[1]) - FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c]; - else - FORC3 image[row*width+col][c] = - (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1; - } - } - } - free (buffer); -} #undef TS void CLASS median_filter() @@ -4771,7 +4398,7 @@ } } -int CLASS parse_tiff_ifd (int base); +/*RT int CLASS parse_tiff_ifd (int base);*/ void CLASS parse_makernote (int base, int uptag) { @@ -5284,8 +4911,8 @@ } } -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) { @@ -5299,7 +4926,7 @@ 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; @@ -5737,12 +5364,13 @@ 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); - parse_tiff_ifd (-sony_offset); - fclose (ifp); - } +/*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); +// } ifp = sfp; free (buf); } @@ -5766,6 +5394,7 @@ int CLASS parse_tiff (int base) { int doff; + /*RT*/ if (exif_base == -1) exif_base = base; fseek (ifp, base, SEEK_SET); order = get2(); @@ -5843,7 +5472,7 @@ case 8: load_raw = &CLASS eight_bit_load_raw; break; case 12: if (tiff_ifd[raw].phint == 2) load_flags = 6; - load_raw = &CLASS packed_load_raw; break; + load_raw = &CLASS packed_load_raw; break; case 14: load_flags = 0; case 16: load_raw = &CLASS unpacked_load_raw; if (!strncmp(make,"OLYMPUS",7) && @@ -5959,7 +5588,7 @@ { const char *file, *ext; char *jname, *jfile, *jext; - FILE *save=ifp; +/*RT*/ IMFILE *save=ifp; ext = strrchr (ifname, '.'); file = strrchr (ifname, '/'); @@ -5981,13 +5610,14 @@ } else while (isdigit(*--jext)) { if (*jext != '9') { - (*jext)++; + (*jext)++; 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); @@ -6330,7 +5960,11 @@ order = get2(); hlen = get4(); if (get4() == 0x48454150) /* "HEAP" */ +/*RT*/ { +/*RT*/ ciff_base = save+hlen; +/*RT*/ ciff_len = len-hlen; parse_ciff (save+hlen, len-hlen, 0); +/*RT*/ } if (parse_tiff (save+6)) apply_tiff(); fseek (ifp, save+len, SEEK_SET); } @@ -6582,7 +6216,8 @@ { static const struct { const char *prefix; - short black, maximum, trans[12]; + unsigned short black, maximum; // RT: Change to UShort + short trans[12]; } table[] = { { "AgfaPhoto DC-833m", 0, 0, /* DJC */ { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } }, @@ -6596,30 +6231,30 @@ { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } }, { "Canon EOS D60", 0, 0xfa0, { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } }, - { "Canon EOS 5D Mark III", 0, 0x3c80, + { "Canon EOS 5D Mark III", 0, 0x3a98, /* RT */ { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } }, { "Canon EOS 5D Mark II", 0, 0x3cf0, { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } }, - { "Canon EOS 5D", 0, 0xe6c, - { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } }, - { "Canon EOS 6D", 0, 0x3c82, + { "Canon EOS 5D", 0, 0xe6c, /* RT */ + { 6319,-793,-614,-5809,13342,2738,-1132,1559,7971 } }, + { "Canon EOS 6D", 0, 0x3c82, { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, - { "Canon EOS 7D", 0, 0x3510, - { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } }, + { "Canon EOS 7D", 0, 0x3510, /* RT - Colin Walker */ + { 5962,-171,-732,-4189,12307,2099,-911,1981,6304 } }, { "Canon EOS 10D", 0, 0xfa0, { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } }, { "Canon EOS 20Da", 0, 0, { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } }, - { "Canon EOS 20D", 0, 0xfff, - { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } }, + { "Canon EOS 20D", 0, 0xfff, /* RT */ + { 7590,-1646,-673,-4697,12411,2568,-627,1118,7295 } }, { "Canon EOS 30D", 0, 0, { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } }, - { "Canon EOS 40D", 0, 0x3f60, - { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } }, + { "Canon EOS 40D", 0, 0x3f60, /* RT */ + { 6070,-531,-883,-5763,13647,2315,-1533,2582,6801 } }, { "Canon EOS 50D", 0, 0x3d93, { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } }, - { "Canon EOS 60D", 0, 0x2ff7, - { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } }, + { "Canon EOS 60D", 0, 0x2ff7, /* RT - Colin Walker */ + { 5678,-179,-718,-4389,12381,2243,-869,1819,6380 } }, { "Canon EOS 100D", 0, 0x350f, { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, { "Canon EOS 300D", 0, 0xfa0, @@ -6628,12 +6263,12 @@ { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } }, { "Canon EOS 400D", 0, 0xe8e, { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } }, - { "Canon EOS 450D", 0, 0x390d, - { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } }, + { "Canon EOS 450D", 0, 0x390d, /* RT */ + { 6246,-1272,-523,-5075,12357,3075,-1035,1825,7333 } }, { "Canon EOS 500D", 0, 0x3479, { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } }, - { "Canon EOS 550D", 0, 0x3dd7, - { 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } }, + { "Canon EOS 550D", 0, 0x3dd7, /* RT - Lebedev*/ + { 6519,-772,-703,-4994,12737,2519,-1387,2492,6175 } }, { "Canon EOS 600D", 0, 0x3510, { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } }, { "Canon EOS 650D", 0, 0x354d, @@ -6652,8 +6287,8 @@ { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } }, { "Canon EOS-1D Mark IV", 0, 0x3bb0, { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } }, - { "Canon EOS-1D Mark III", 0, 0x3bb0, - { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } }, + { "Canon EOS-1D Mark III", 0, 0x3bb0, /* RT */ + { 7406,-1592,-646,-4856,12457,2698,-432,726,7921 } }, { "Canon EOS-1D Mark II N", 0, 0xe80, { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } }, { "Canon EOS-1D Mark II", 0, 0xe80, @@ -6672,12 +6307,12 @@ { -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } }, { "Canon PowerShot A5", 0, 0, { -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } }, - { "Canon PowerShot G10", 0, 0, - { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } }, + { "Canon PowerShot G10", 0, 0, /* RT */ + { 12535,-5030,-796,-2711,10134,3006,-413,1605,5264 } }, { "Canon PowerShot G11", 0, 0, { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } }, - { "Canon PowerShot G12", 0, 0, - { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } }, + { "Canon PowerShot G12", 0, 0, /* RT */ + { 12222,-4097,-1380,-2876,11016,2130,-888,1630,4434 } }, { "Canon PowerShot G15", 0, 0, { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } }, { "Canon PowerShot G1 X", 0, 0, @@ -6743,7 +6378,7 @@ { "Canon PowerShot S3 IS", 0, 0, /* DJC */ { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } }, { "Canon PowerShot SX110 IS", 0, 0, /* DJC */ - { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } }, + { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } }, { "Canon PowerShot SX220", 0, 0, /* DJC */ { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } }, { "Casio EX-S20", 0, 0, /* DJC */ @@ -6826,8 +6461,8 @@ { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, { "Fujifilm X100S", 0, 0, { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, - { "Fujifilm X100", 0, 0, - { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } }, + { "Fujifilm X100", 0, 0, /* RT - Colin Walker */ + { 10841,-3288,-807,-4652,12552,2344,-642,1355,7206 } }, { "Fujifilm X10", 0, 0, { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, { "Fujifilm X20", 0, 0, @@ -6938,24 +6573,24 @@ { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } }, { "Nikon D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */ { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } }, - { "Nikon D200", 0, 0xfbc, - { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } }, + { "Nikon D200", 0, 0xfbc, /* RT */ + { 8498,-2633,-295,-5423,12869,2860,-777,1077,8124 } }, { "Nikon D2H", 0, 0, { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } }, { "Nikon D2X", 0, 0, { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } }, - { "Nikon D3000", 0, 0, - { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, - { "Nikon D3100", 0, 0, - { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } }, + { "Nikon D3000", 0, 0, /* RT */ + { 9211,-2521,-104,-6487,14280,2394,-754,1122,8033 } }, + { "Nikon D3100", 0, 0, /* RT */ + { 7729,-2212,-481,-5709,13148,2858,-1295,1908,8936 } }, { "Nikon D3200", 0, 0xfb9, { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } }, { "Nikon D300", 0, 0, { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } }, { "Nikon D3X", 0, 0, { 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } }, - { "Nikon D3S", 0, 0, - { 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } }, + { "Nikon D3S", 0, 0, /* RT */ + { 8792,-2663,-344,-5221,12764,2752,-1491,2165,8121 } }, { "Nikon D3", 0, 0, { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } }, { "Nikon D40X", 0, 0, @@ -6968,7 +6603,7 @@ { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } }, { "Nikon D5100", 0, 0x3de6, { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, - { "Nikon D5200", 0, 0, + { "Nikon D5200", 0, 0, // color matrix copied from D5200 DNG D65 matrix { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, { "Nikon D50", 0, 0, { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, @@ -6976,12 +6611,12 @@ { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } }, { "Nikon D60", 0, 0, { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, - { "Nikon D7000", 0, 0, - { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, - { "Nikon D7100", 0, 0, + { "Nikon D7000", 0, 0, /* RT - Tanveer(tsk1979) */ + { 7530,-1942,-255,-4318,11390,3362,-926,1694,7649 } }, + { "Nikon D7100", 0, 0, // color matrix and WP copied from D7100 DNG D65 matrix { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, - { "Nikon D700", 0, 0, - { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } }, + { "Nikon D700", 0, 0, /* RT */ + { 8364,-2503,-352,-6307,14026,2492,-1134,1512,8156 } }, { "Nikon D70", 0, 0, { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, { "Nikon D800", 0, 0, @@ -7020,8 +6655,8 @@ { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, { "Nikon E8800", 0, 0, { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } }, - { "Nikon COOLPIX A", 0, 0, - { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, + { "Nikon COOLPIX A", 0, 0x3e00, // color matrix and WP copied from "COOLPIX A" DNG D65 matrix + { 8198,-2239,-724,-4871,12389,2798,-1043,205,7181 } }, { "Nikon COOLPIX P330", 0, 0, { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, { "Nikon COOLPIX P6000", 0, 0, @@ -7058,8 +6693,8 @@ { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } }, { "Olympus E-330", 0, 0, { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } }, - { "Olympus E-30", 0, 0xfbc, - { 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } }, + { "Olympus E-30", 0, 0xfbc, /* RT - Colin Walker */ + { 8510,-2355,-693,-4819,12520,2578,-1029,2067,7752 } }, { "Olympus E-3", 0, 0xf99, { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } }, { "Olympus E-400", 0, 0, @@ -7076,26 +6711,26 @@ { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } }, { "Olympus E-520", 0, 0xfd2, { 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } }, - { "Olympus E-5", 0, 0xeec, - { 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } }, + { "Olympus E-5", 0, 0xeec, /* RT - Colin Walker */ + { 9732,-2629,-999,-4899,12931,2173,-1243,2353,7457 } }, { "Olympus E-600", 0, 0xfaf, { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } }, { "Olympus E-620", 0, 0xfaf, { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } }, - { "Olympus E-P1", 0, 0xffd, - { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } }, - { "Olympus E-P2", 0, 0xffd, - { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } }, - { "Olympus E-P3", 0, 0, - { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, - { "Olympus E-PL1s", 0, 0, - { 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } }, - { "Olympus E-PL1", 0, 0, - { 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } }, - { "Olympus E-PL2", 0, 0xcf3, - { 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } }, - { "Olympus E-PL3", 0, 0, - { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, + { "Olympus E-P1", 0, 0xffd, /* RT - Colin Walker */ + { 8834,-2344,-804,-4691,12503,2448,-978,1919,7603 } }, + { "Olympus E-P2", 0, 0xffd, /* RT - Colin Walker */ + { 7758,-1619,-800,-5002,12886,2349,-985,1964,8305 } }, + { "Olympus E-P3", 0, 0, /* RT - Colin Walker */ + { 7041,-1794,-336,-3790,11192,2984,-1364,2625,6217 } }, + { "Olympus E-PL1s", 0, 0, /* RT - Colin Walker */ + { 9010,-2271,-838,-4792,12753,2263,-1059,2058,7589 } }, + { "Olympus E-PL1", 0, 0, /* RT - Colin Walker */ + { 9010,-2271,-838,-4792,12753,2263,-1059,2058,7589 } }, + { "Olympus E-PL2", 0, 0, /* RT - Colin Walker */ + { 11975,-3351,-1184,-4500,12639,2061,-1230,2353,7009 } }, + { "Olympus E-PL3", 0, 0, /* RT - Colin Walker */ + { 7041,-1794,-336,-3790,11192,2984,-1364,2625,6217 } }, { "Olympus E-PL5", 0, 0xfcb, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { "Olympus E-PM1", 0, 0, @@ -7120,8 +6755,8 @@ { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } }, { "Olympus XZ-10", 0, 0, { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, - { "Olympus XZ-1", 0, 0, - { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } }, + { "Olympus XZ-1", 0, 0, /* RT - Colin Walker */ + { 8665,-2247,-762,-2424,10372,2382,-1011,2286,5189 } }, { "Olympus XZ-2", 0, 0, { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, { "OmniVision ov5647", 0, 0, /* DJC */ @@ -7142,8 +6777,8 @@ { 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } }, { "Pentax K20D", 0, 0, { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } }, - { "Pentax K200D", 0, 0, - { 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } }, + { "Pentax K200D", 0, 0, /* RT */ + { 10962,-4428,-542,-5486,13023,2748,-569,842,8390 } }, { "Pentax K2000", 0, 0, { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } }, { "Pentax K-m", 0, 0, @@ -7202,6 +6837,8 @@ { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } }, { "Leica D-LUX 5", 143, 0, { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } }, + { "Leica Camera AG M9 Digital Camera", 0, 0, /* RT */ + { 7181,-1706,-55,-3557,11409,2450,-621,2072,7533 } }, { "Panasonic DMC-LX7", 143, 0, { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } }, { "Leica D-LUX 6", 143, 0, @@ -7210,8 +6847,8 @@ { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } }, { "Leica V-LUX 2", 143, 0xfff, { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } }, - { "Panasonic DMC-FZ150", 143, 0xfff, - { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } }, + { "Panasonic DMC-FZ150", 143, 0xfff, /* RT */ + { 10435,-3208,-72,-2293,10506,2067,-486,1725,4682 } }, { "Leica V-LUX 3", 143, 0xfff, { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } }, { "Panasonic DMC-FZ200", 143, 0xfff, @@ -7220,32 +6857,30 @@ { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } }, { "Panasonic DMC-FX150", 15, 0xfff, { 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } }, - { "Panasonic DMC-G10", 0, 0, - { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } }, - { "Panasonic DMC-G1", 15, 0xf94, - { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } }, - { "Panasonic DMC-G2", 15, 0xf3c, - { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } }, - { "Panasonic DMC-G3", 143, 0xfff, - { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, - { "Panasonic DMC-G5", 143, 0xfff, - { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } }, - { "Panasonic DMC-G6", 143, 0xfff, /* DJC */ - { 6395,-2583,-40,-3677,9109,4569,-1502,2806,6431 } }, - { "Panasonic DMC-GF1", 15, 0xf92, - { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, - { "Panasonic DMC-GF2", 143, 0xfff, - { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, - { "Panasonic DMC-GF3", 143, 0xfff, - { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } }, + { "Panasonic DMC-G10", 15, 0xf3c, /* RT - Colin Walker */ + { 8310,-1811,-960,-4941,12990,2151,-1378,2468,6860 } }, + { "Panasonic DMC-G1", 15, 0xf94, /* RT - Colin Walker*/ + { 7477,-1615,-651,-5016,12769,2506,-1380,2475,7240 } }, + { "Panasonic DMC-G2", 15, 0xf3c, /* RT - Colin Walker */ + { 8310,-1811,-960,-4941,12990,2151,-1378,2468,6860 } }, + { "Panasonic DMC-G3", 143, 0xfff, /* RT - Colin Walker */ + { 6051,-1406,-671,-4015,11505,2868,-1654,2667,6219 } }, + { "Panasonic DMC-G5", 143, 0xfff, /* RT */ + { 7122,-2092,-419,-4643,11769,3283,-1363,2413,5944 } }, + { "Panasonic DMC-GF1", 15, 0xf92, /* RT - Colin Walker */ + { 7863,-2080,-668,-4623,12331,2578,-1020,2066,7266 } }, + { "Panasonic DMC-GF2", 143, 0xfff, /* RT - Colin Walker */ + { 7694,-1791,-745,-4917,12818,2332,-1221,2322,7197 } }, + { "Panasonic DMC-GF3", 143, 0xfff, /* RT - Colin Walker */ + { 8074,-1846,-861,-5026,12999,2239,-1320,2375,7422 } }, { "Panasonic DMC-GF5", 143, 0xfff, { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } }, { "Panasonic DMC-GF6", 143, 0, { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } }, - { "Panasonic DMC-GH1", 15, 0xf92, - { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } }, - { "Panasonic DMC-GH2", 15, 0xf95, - { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } }, + { "Panasonic DMC-GH1", 15, 0xf92, /* RT - Colin Walker */ + { 6360,-1557,-375,-4201,11504,3086,-1378,2518,5843 } }, { "Panasonic DMC-GH3", 144, 0, { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } }, { "Panasonic DMC-GX1", 143, 0, @@ -7322,30 +6957,28 @@ { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } }, { "Sony DSLR-A5", 128, 0xfeb, { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } }, - { "Sony DSLR-A700", 126, 0, - { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } }, + { "Sony DSLR-A700", 126, 0, /* RT */ + { 6509,-1333,-137,-6171,13621,2824,-1490,2226,6952 } }, { "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-5N", 128, 0, - { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, - { "Sony NEX-5R", 128, 0, - { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, + { "Sony DSLR-A900", 128, 0, /* RT */ + { 5715,-1433,-410,-5603,12937,2989,-644,1247,8372 } }, + { "SONY NEX-3", 128, 0, /* RT - Colin Walker */ + { 5145,-741,-123,-4915,12310,2945,-794,1489,6906 } }, { "Sony NEX-3N", 128, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, - { "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", 128, 0, /* Adobe */ - { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } }, - { "Sony NEX-5", 128, 0, /* Adobe */ - { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } }, + { "SONY NEX-5", 128, 0, /* RT - Colin Walker */ + { 5154,-716,-115,-5065,12506,2882,-988,1715,6800 } }, + { "Sony NEX-5N", 128, 0, /* RT - Colin Walker */ + { 5130,-1055,-269,-4473,11797,3050,-701,1310,7121 } }, + { "Sony NEX-5R", 128, 0, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, { "Sony NEX-6", 128, 0, { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, { "Sony NEX-7", 128, 0, { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, + { "SONY NEX-C3", 128, 0, /* RT - Colin Walker */ + { 5130,-1055,-269,-4473,11797,3050,-701,1310,7121 } }, { "Sony NEX", 128, 0, /* NEX-C3, NEX-F3 */ { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, { "Sony SLT-A33", 128, 0, @@ -7362,10 +6995,10 @@ { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, { "Sony SLT-A65", 128, 0, { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, - { "Sony SLT-A77", 128, 0, - { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, + { "Sony SLT-A77", 128, 0, /* RT - Colin Walker */ + { 5126,-830,-261,-4788,12196,2934,-948,1602,7068 } }, { "Sony SLT-A99", 128, 0, - { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, + { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } } }; double cam_xyz[4][3]; char name[130]; @@ -7682,13 +7315,20 @@ fread (head, 1, 32, ifp); fseek (ifp, 0, SEEK_END); flen = fsize = ftell(ifp); - if ((cp = (char *) memmem (head, 32, "MMMM", 4)) || - (cp = (char *) memmem (head, 32, "IIII", 4))) { + /*RT*/ if (fsize<100000) { + is_raw = 0; + return; + } + /* RT: changed string constant */ + if ((cp = (char *) memmem (head, 32, (char*)"MMMM", 4)) || + (cp = (char *) memmem (head, 32, (char*)"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, 0); load_raw = &CLASS canon_load_raw; } else if (parse_tiff(0)) apply_tiff(); @@ -7734,6 +7374,7 @@ fseek (ifp, 100+28*(shot_select > 0), 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); @@ -7839,15 +7480,18 @@ if (make[0] == 0) parse_smal (0, flen); if (make[0] == 0) { parse_jpeg(0); - if (!strncmp(model,"ov",2) && !fseek (ifp, -6404096, SEEK_END) && - fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) { - strcpy (make, "OmniVision"); - data_offset = ftell(ifp) + 0x8000-32; - width = raw_width; - raw_width = 2611; - load_raw = &CLASS nokia_load_raw; - filters = 0x16161616; - } else is_raw = 0; + //RT fix for the use of fseek below + if (!strncmp(model,"ov",2)) { + fseek (ifp, -6404096, SEEK_END); + if (fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) { + strcpy (make, "OmniVision"); + data_offset = ftell(ifp) + 0x8000-32; + width = raw_width; + raw_width = 2611; + load_raw = &CLASS nokia_load_raw; + filters = 0x16161616; + } else is_raw = 0; + } } for (i=0; i < sizeof corp / sizeof *corp; i++) @@ -7878,7 +7522,7 @@ if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */ { height = 3124; width = 4688; filters = 0x16161616; } if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x"))) - { width = 4309; filters = 0x16161616; } +/*RT*/ { width = 4308; filters = 0x16161616; } if (width >= 4960 && !strncmp(model,"K-5",3)) { left_margin = 10; width = 4950; filters = 0x16161616; } if (width == 4736 && !strcmp(model,"K-7")) @@ -8026,7 +7670,7 @@ width -= 44; } else if (!strcmp(model,"D3200") || !strcmp(model,"D600") || - !strncmp(model,"D800",4)) { + !strcmp(model,"D800") || !strcmp(model,"D800E") ) { width -= 46; } else if (!strcmp(model,"D4")) { width -= 52; @@ -8630,195 +8274,8 @@ cmsCloseProfile (hInProfile); } #endif - -void CLASS convert_to_rgb() -{ - int row, col, c, i, j, k; - ushort *img; - float out[3], out_cam[3][4]; - double num, inverse[3][3]; - static const double xyzd50_srgb[3][3] = - { { 0.436083, 0.385083, 0.143055 }, - { 0.222507, 0.716888, 0.060608 }, - { 0.013930, 0.097097, 0.714022 } }; - static const double rgb_rgb[3][3] = - { { 1,0,0 }, { 0,1,0 }, { 0,0,1 } }; - static const double adobe_rgb[3][3] = - { { 0.715146, 0.284856, 0.000000 }, - { 0.000000, 1.000000, 0.000000 }, - { 0.000000, 0.041166, 0.958839 } }; - static const double wide_rgb[3][3] = - { { 0.593087, 0.404710, 0.002206 }, - { 0.095413, 0.843149, 0.061439 }, - { 0.011621, 0.069091, 0.919288 } }; - static const double prophoto_rgb[3][3] = - { { 0.529317, 0.330092, 0.140588 }, - { 0.098368, 0.873465, 0.028169 }, - { 0.016879, 0.117663, 0.865457 } }; - static const double (*out_rgb[])[3] = - { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb }; - static const char *name[] = - { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ" }; - static const unsigned phead[] = - { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0, - 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d }; - unsigned pbody[] = - { 10, 0x63707274, 0, 36, /* cprt */ - 0x64657363, 0, 40, /* desc */ - 0x77747074, 0, 20, /* wtpt */ - 0x626b7074, 0, 20, /* bkpt */ - 0x72545243, 0, 14, /* rTRC */ - 0x67545243, 0, 14, /* gTRC */ - 0x62545243, 0, 14, /* bTRC */ - 0x7258595a, 0, 20, /* rXYZ */ - 0x6758595a, 0, 20, /* gXYZ */ - 0x6258595a, 0, 20 }; /* bXYZ */ - static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc }; - unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 }; - - gamma_curve (gamm[0], gamm[1], 0, 0); - memcpy (out_cam, rgb_cam, sizeof out_cam); - raw_color |= colors == 1 || document_mode || - output_color < 1 || output_color > 5; - if (!raw_color) { - oprof = (unsigned *) calloc (phead[0], 1); - merror (oprof, "convert_to_rgb()"); - memcpy (oprof, phead, sizeof phead); - if (output_color == 5) oprof[4] = oprof[5]; - oprof[0] = 132 + 12*pbody[0]; - for (i=0; i < pbody[0]; i++) { - oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874; - pbody[i*3+2] = oprof[0]; - oprof[0] += (pbody[i*3+3] + 3) & -4; - } - memcpy (oprof+32, pbody, sizeof pbody); - oprof[pbody[5]/4+2] = strlen(name[output_color-1]) + 1; - memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof pwhite); - pcurve[3] = (short)(256/gamm[5]+0.5) << 16; - for (i=4; i < 7; i++) - memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof pcurve); - pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3); - for (i=0; i < 3; i++) - for (j=0; j < 3; j++) { - for (num = k=0; k < 3; k++) - num += xyzd50_srgb[i][k] * inverse[j][k]; - oprof[pbody[j*3+23]/4+i+2] = num * 0x10000 + 0.5; - } - for (i=0; i < phead[0]/4; i++) - oprof[i] = htonl(oprof[i]); - strcpy ((char *)oprof+pbody[2]+8, "auto-generated by dcraw"); - strcpy ((char *)oprof+pbody[5]+12, name[output_color-1]); - for (i=0; i < 3; i++) - for (j=0; j < colors; j++) - for (out_cam[i][j] = k=0; k < 3; k++) - out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j]; - } - if (verbose) - 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) { - if (!raw_color) { - out[0] = out[1] = out[2] = 0; - FORCC { - out[0] += out_cam[0][c] * img[c]; - out[1] += out_cam[1][c] * img[c]; - out[2] += out_cam[2][c] * img[c]; - } - FORC3 img[c] = CLIP((int) out[c]); - } - else if (document_mode) - img[0] = img[fcol(row,col)]; - FORCC histogram[c][img[c] >> 3]++; - } - if (colors == 4 && output_color) colors = 3; - if (document_mode && filters) colors = 1; -} - -void CLASS fuji_rotate() -{ - int i, row, col; - double step; - float r, c, fr, fc; - unsigned ur, uc; - ushort wide, high, (*img)[4], (*pix)[4]; - - if (!fuji_width) return; - if (verbose) - fprintf (stderr,_("Rotating image 45 degrees...\n")); - fuji_width = (fuji_width - 1 + shrink) >> shrink; - step = sqrt(0.5); - wide = fuji_width / step; - high = (height - fuji_width) / step; - img = (ushort (*)[4]) calloc (high, wide*sizeof *img); - merror (img, "fuji_rotate()"); - - for (row=0; row < high; row++) - for (col=0; col < wide; col++) { - ur = r = fuji_width + (row-col)*step; - uc = c = (row+col)*step; - if (ur > height-2 || uc > width-2) continue; - fr = r - ur; - fc = c - uc; - pix = image + ur*width + uc; - for (i=0; i < colors; i++) - img[row*wide+col][i] = - (pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) + - (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr; - } - free (image); - width = wide; - height = high; - image = img; - fuji_width = 0; -} - -void CLASS stretch() -{ - ushort newdim, (*img)[4], *pix0, *pix1; - int row, col, c; - double rc, frac; - - if (pixel_aspect == 1) return; - if (verbose) fprintf (stderr,_("Stretching the image...\n")); - if (pixel_aspect < 1) { - newdim = height / pixel_aspect + 0.5; - img = (ushort (*)[4]) calloc (width, newdim*sizeof *img); - merror (img, "stretch()"); - for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) { - frac = rc - (c = rc); - pix0 = pix1 = image[c*width]; - if (c+1 < height) pix1 += width*4; - for (col=0; col < width; col++, pix0+=4, pix1+=4) - FORCC img[row*width+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5; - } - height = newdim; - } else { - newdim = width * pixel_aspect + 0.5; - img = (ushort (*)[4]) calloc (height, newdim*sizeof *img); - merror (img, "stretch()"); - for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) { - frac = rc - (c = rc); - pix0 = pix1 = image[c]; - if (c+1 < width) pix1 += 4; - for (row=0; row < height; row++, pix0+=width*4, pix1+=width*4) - FORCC img[row*newdim+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5; - } - width = newdim; - } - free (image); - image = img; -} - -int CLASS flip_index (int row, int col) -{ - if (flip & 4) SWAP(row,col); - if (flip & 2) row = iheight - 1 - row; - if (flip & 1) col = iwidth - 1 - col; - return row * iwidth + col; -} + +/* RT: removed unused functions */ struct tiff_tag { ushort tag, type; @@ -8841,584 +8298,12 @@ unsigned gps[26]; char desc[512], make[64], model[64], soft[32], date[20], artist[64]; }; +/* RT: Delete from here */ +/*RT*/#undef SQR +/*RT*/#undef MAX +/*RT*/#undef MIN +/*RT*/#undef ABS +/*RT*/#undef LIM +/*RT*/#undef ULIM +/*RT*/#undef CLIP -void CLASS tiff_set (ushort *ntag, - ushort tag, ushort type, int count, int val) -{ - struct tiff_tag *tt; - int c; - - tt = (struct tiff_tag *)(ntag+1) + (*ntag)++; - tt->tag = tag; - tt->type = type; - tt->count = count; - if (type < 3 && count <= 4) - FORC(4) tt->val.c[c] = val >> (c << 3); - else if (type == 3 && count <= 2) - FORC(2) tt->val.s[c] = val >> (c << 4); - else tt->val.i = val; -} - -#define TOFF(ptr) ((char *)(&(ptr)) - (char *)th) - -void CLASS tiff_head (struct tiff_hdr *th, int full) -{ - int c, psize=0; - struct tm *t; - - memset (th, 0, sizeof *th); - th->order = htonl(0x4d4d4949) >> 16; - th->magic = 42; - th->ifd = 10; - if (full) { - tiff_set (&th->ntag, 254, 4, 1, 0); - tiff_set (&th->ntag, 256, 4, 1, width); - tiff_set (&th->ntag, 257, 4, 1, height); - tiff_set (&th->ntag, 258, 3, colors, output_bps); - if (colors > 2) - th->tag[th->ntag-1].val.i = TOFF(th->bps); - FORC4 th->bps[c] = output_bps; - tiff_set (&th->ntag, 259, 3, 1, 1); - tiff_set (&th->ntag, 262, 3, 1, 1 + (colors > 1)); - } - tiff_set (&th->ntag, 270, 2, 512, TOFF(th->desc)); - tiff_set (&th->ntag, 271, 2, 64, TOFF(th->make)); - tiff_set (&th->ntag, 272, 2, 64, TOFF(th->model)); - if (full) { - if (oprof) psize = ntohl(oprof[0]); - tiff_set (&th->ntag, 273, 4, 1, sizeof *th + psize); - tiff_set (&th->ntag, 277, 3, 1, colors); - tiff_set (&th->ntag, 278, 4, 1, height); - tiff_set (&th->ntag, 279, 4, 1, height*width*colors*output_bps/8); - } else - tiff_set (&th->ntag, 274, 3, 1, "12435867"[flip]-'0'); - tiff_set (&th->ntag, 282, 5, 1, TOFF(th->rat[0])); - tiff_set (&th->ntag, 283, 5, 1, TOFF(th->rat[2])); - tiff_set (&th->ntag, 284, 3, 1, 1); - tiff_set (&th->ntag, 296, 3, 1, 2); - tiff_set (&th->ntag, 305, 2, 32, TOFF(th->soft)); - tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date)); - tiff_set (&th->ntag, 315, 2, 64, TOFF(th->artist)); - tiff_set (&th->ntag, 34665, 4, 1, TOFF(th->nexif)); - if (psize) tiff_set (&th->ntag, 34675, 7, psize, sizeof *th); - tiff_set (&th->nexif, 33434, 5, 1, TOFF(th->rat[4])); - tiff_set (&th->nexif, 33437, 5, 1, TOFF(th->rat[6])); - tiff_set (&th->nexif, 34855, 3, 1, iso_speed); - tiff_set (&th->nexif, 37386, 5, 1, TOFF(th->rat[8])); - if (gpsdata[1]) { - tiff_set (&th->ntag, 34853, 4, 1, TOFF(th->ngps)); - tiff_set (&th->ngps, 0, 1, 4, 0x202); - tiff_set (&th->ngps, 1, 2, 2, gpsdata[29]); - tiff_set (&th->ngps, 2, 5, 3, TOFF(th->gps[0])); - tiff_set (&th->ngps, 3, 2, 2, gpsdata[30]); - tiff_set (&th->ngps, 4, 5, 3, TOFF(th->gps[6])); - tiff_set (&th->ngps, 5, 1, 1, gpsdata[31]); - tiff_set (&th->ngps, 6, 5, 1, TOFF(th->gps[18])); - tiff_set (&th->ngps, 7, 5, 3, TOFF(th->gps[12])); - tiff_set (&th->ngps, 18, 2, 12, TOFF(th->gps[20])); - tiff_set (&th->ngps, 29, 2, 12, TOFF(th->gps[23])); - memcpy (th->gps, gpsdata, sizeof th->gps); - } - th->rat[0] = th->rat[2] = 300; - th->rat[1] = th->rat[3] = 1; - FORC(6) th->rat[4+c] = 1000000; - th->rat[4] *= shutter; - th->rat[6] *= aperture; - th->rat[8] *= focal_len; - strncpy (th->desc, desc, 512); - strncpy (th->make, make, 64); - strncpy (th->model, model, 64); - strcpy (th->soft, "dcraw v"DCRAW_VERSION); - t = localtime (×tamp); - sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d", - t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec); - strncpy (th->artist, artist, 64); -} - -void CLASS jpeg_thumb() -{ - char *thumb; - ushort exif[5]; - struct tiff_hdr th; - - thumb = (char *) malloc (thumb_length); - merror (thumb, "jpeg_thumb()"); - fread (thumb, 1, thumb_length, ifp); - fputc (0xff, ofp); - fputc (0xd8, ofp); - if (strcmp (thumb+6, "Exif")) { - memcpy (exif, "\xff\xe1 Exif\0\0", 10); - exif[1] = htons (8 + sizeof th); - fwrite (exif, 1, sizeof exif, ofp); - tiff_head (&th, 0); - fwrite (&th, 1, sizeof th, ofp); - } - fwrite (thumb+2, 1, thumb_length-2, ofp); - free (thumb); -} - -void CLASS write_ppm_tiff() -{ - struct tiff_hdr th; - uchar *ppm; - ushort *ppm2; - int c, row, col, soff, rstep, cstep; - int perc, val, total, white=0x2000; - - perc = width * height * 0.01; /* 99th percentile white level */ - if (fuji_width) perc /= 2; - if (!((highlight & ~2) || no_auto_bright)) - for (white=c=0; c < colors; c++) { - for (val=0x2000, total=0; --val > 32; ) - if ((total += histogram[c][val]) > perc) break; - if (white < val) white = val; - } - gamma_curve (gamm[0], gamm[1], 2, (white << 3)/bright); - iheight = height; - iwidth = width; - if (flip & 4) SWAP(height,width); - ppm = (uchar *) calloc (width, colors*output_bps/8); - ppm2 = (ushort *) ppm; - merror (ppm, "write_ppm_tiff()"); - if (output_tiff) { - tiff_head (&th, 1); - fwrite (&th, sizeof th, 1, ofp); - if (oprof) - fwrite (oprof, ntohl(oprof[0]), 1, ofp); - } else if (colors > 3) - fprintf (ofp, - "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n", - width, height, colors, (1 << output_bps)-1, cdesc); - else - fprintf (ofp, "P%d\n%d %d\n%d\n", - colors/2+5, width, height, (1 << output_bps)-1); - soff = flip_index (0, 0); - cstep = flip_index (0, 1) - soff; - rstep = flip_index (1, 0) - flip_index (0, width); - for (row=0; row < height; row++, soff += rstep) { - 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); - fwrite (ppm, colors*output_bps/8, width, ofp); - } - free (ppm); -} - -int CLASS main (int argc, const char **argv) -{ - int arg, status=0, quality, i, c; - 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, read_from_stdin=0; - const char *sp, *bpfile=0, *dark_frame=0, *write_ext; - char opm, opt, *ofname, *cp; - struct utimbuf ut; -#ifndef NO_LCMS - const char *cam_profile=0, *out_profile=0; -#endif - -#ifndef LOCALTIME - putenv ((char *) "TZ=UTC"); -#endif -#ifdef LOCALEDIR - setlocale (LC_CTYPE, ""); - setlocale (LC_MESSAGES, ""); - bindtextdomain ("dcraw", LOCALEDIR); - textdomain ("dcraw"); -#endif - - if (argc == 1) { - printf(_("\nRaw photo decoder \"dcraw\" v%s"), DCRAW_VERSION); - printf(_("\nby Dave Coffin, dcoffin a cybercom o net\n")); - printf(_("\nUsage: %s [OPTION]... [FILE]...\n\n"), argv[0]); - puts(_("-v Print verbose messages")); - puts(_("-c Write image data to standard output")); - puts(_("-e Extract embedded thumbnail image")); - puts(_("-i Identify files without decoding them")); - puts(_("-i -v Identify files and show metadata")); - puts(_("-z Change file dates to camera timestamp")); - puts(_("-w Use camera white balance, if possible")); - puts(_("-a Average the whole image for white balance")); - puts(_("-A Average a grey box for white balance")); - puts(_("-r Set custom white balance")); - puts(_("+M/-M Use/don't use an embedded color matrix")); - puts(_("-C Correct chromatic aberration")); - puts(_("-P Fix the dead pixels listed in this file")); - puts(_("-K Subtract dark frame (16-bit raw PGM)")); - puts(_("-k Set the darkness level")); - puts(_("-S Set the saturation level")); - puts(_("-n Set threshold for wavelet denoising")); - puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)")); - puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)")); - puts(_("-o [0-5] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ)")); -#ifndef NO_LCMS - puts(_("-o Apply output ICC profile from file")); - puts(_("-p Apply camera ICC profile from file or \"embed\"")); -#endif - puts(_("-d Document mode (no color, no interpolation)")); - puts(_("-D Document mode without scaling (totally raw)")); - puts(_("-j Don't stretch or rotate raw pixels")); - puts(_("-W Don't automatically brighten the image")); - puts(_("-b Adjust brightness (default = 1.0)")); - puts(_("-g

Set custom gamma curve (default = 2.222 4.5)")); - puts(_("-q [0-3] Set the interpolation quality")); - puts(_("-h Half-size color image (twice as fast as \"-q 0\")")); - puts(_("-f Interpolate RGGB as four colors")); - puts(_("-m Apply a 3x3 median filter to R-G and B-G")); - puts(_("-s [0..N-1] Select one raw image or \"all\" from each file")); - puts(_("-6 Write 16-bit instead of 8-bit")); - puts(_("-4 Linear 16-bit, same as \"-6 -W -g 1 1\"")); - puts(_("-T Write TIFF instead of PPM")); - puts(""); - return 1; - } - argv[argc] = ""; - for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) { - opt = argv[arg++][1]; - if ((cp = (char *) strchr (sp="nbrkStqmHACg", opt))) - for (i=0; i < "114111111422"[cp-sp]-'0'; i++) - if (!isdigit(argv[arg+i][0])) { - fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt); - return 1; - } - switch (opt) { - case 'n': threshold = atof(argv[arg++]); break; - case 'b': bright = atof(argv[arg++]); break; - case 'r': - FORC4 user_mul[c] = atof(argv[arg++]); break; - case 'C': aber[0] = 1 / atof(argv[arg++]); - aber[2] = 1 / atof(argv[arg++]); break; - case 'g': gamm[0] = atof(argv[arg++]); - gamm[1] = atof(argv[arg++]); - if (gamm[0]) gamm[0] = 1/gamm[0]; break; - case 'k': user_black = atoi(argv[arg++]); break; - case 'S': user_sat = atoi(argv[arg++]); break; - case 't': user_flip = atoi(argv[arg++]); break; - case 'q': user_qual = atoi(argv[arg++]); break; - case 'm': med_passes = atoi(argv[arg++]); break; - case 'H': highlight = atoi(argv[arg++]); break; - case 's': - shot_select = abs(atoi(argv[arg])); - multi_out = !strcmp(argv[arg++],"all"); - break; - case 'o': - if (isdigit(argv[arg][0]) && !argv[arg][1]) - output_color = atoi(argv[arg++]); -#ifndef NO_LCMS - else out_profile = argv[arg++]; - break; - case 'p': cam_profile = argv[arg++]; -#endif - break; - case 'P': bpfile = argv[arg++]; break; - case 'K': dark_frame = argv[arg++]; break; - 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; break; - 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; - case 'I': read_from_stdin = 1; break; - case 'E': document_mode++; - case 'D': document_mode++; - case 'd': document_mode++; - case 'j': use_fuji_rotate = 0; break; - case 'W': no_auto_bright = 1; break; - case 'T': output_tiff = 1; break; - case '4': gamm[0] = gamm[1] = - no_auto_bright = 1; - case '6': output_bps = 16; break; - default: - fprintf (stderr,_("Unknown option \"-%c\".\n"), opt); - return 1; - } - } - if (use_camera_matrix < 0) - use_camera_matrix = use_camera_wb; - if (arg == argc) { - fprintf (stderr,_("No files to process.\n")); - return 1; - } - if (write_to_stdout) { - if (isatty(1)) { - fprintf (stderr,_("Will not write an image to the terminal!\n")); - return 1; - } -#if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__) - if (setmode(1,O_BINARY) < 0) { - perror ("setmode()"); - return 1; - } -#endif - } - for ( ; arg < argc; arg++) { - status = 1; - raw_image = 0; - image = 0; - oprof = 0; - meta_data = ofname = 0; - ofp = stdout; - if (setjmp (failure)) { - if (fileno(ifp) > 2) fclose(ifp); - if (fileno(ofp) > 2) fclose(ofp); - status = 1; - goto cleanup; - } - ifname = argv[arg]; - if (!(ifp = fopen (ifname, "rb"))) { - perror (ifname); - continue; - } - status = (identify(),!is_raw); - if (user_flip >= 0) - flip = user_flip; - switch ((flip+3600) % 360) { - case 270: flip = 5; break; - case 180: flip = 3; break; - case 90: flip = 6; - } - if (timestamp_only) { - if ((status = !timestamp)) - fprintf (stderr,_("%s has no timestamp.\n"), ifname); - else if (identify_only) - printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname); - else { - if (verbose) - fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp); - ut.actime = ut.modtime = timestamp; - utime (ifname, &ut); - } - goto next; - } - write_fun = &CLASS write_ppm_tiff; - if (thumbnail_only) { - if ((status = !thumb_offset)) { - fprintf (stderr,_("%s has no thumbnail.\n"), ifname); - goto next; - } else if (thumb_load_raw) { - load_raw = thumb_load_raw; - data_offset = thumb_offset; - height = thumb_height; - width = thumb_width; - filters = 0; - } else { - fseek (ifp, thumb_offset, SEEK_SET); - write_fun = write_thumb; - goto thumbnail; - } - } - if (load_raw == &CLASS kodak_ycbcr_load_raw) { - height += height & 1; - width += width & 1; - } - if (identify_only && verbose && make[0]) { - printf (_("\nFilename: %s\n"), ifname); - printf (_("Timestamp: %s"), ctime(×tamp)); - printf (_("Camera: %s %s\n"), make, model); - if (artist[0]) - printf (_("Owner: %s\n"), artist); - if (dng_version) { - printf (_("DNG Version: ")); - for (i=24; i >= 0; i -= 8) - printf ("%d%c", dng_version >> i & 255, i ? '.':'\n'); - } - printf (_("ISO speed: %d\n"), (int) iso_speed); - printf (_("Shutter: ")); - if (shutter > 0 && shutter < 1) - shutter = (printf ("1/"), 1 / shutter); - printf (_("%0.1f sec\n"), shutter); - printf (_("Aperture: f/%0.1f\n"), aperture); - printf (_("Focal length: %0.1f mm\n"), focal_len); - printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no")); - printf (_("Number of raw images: %d\n"), is_raw); - if (pixel_aspect != 1) - printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect); - if (thumb_offset) - printf (_("Thumb size: %4d x %d\n"), thumb_width, thumb_height); - printf (_("Full size: %4d x %d\n"), raw_width, raw_height); - } else if (!is_raw) - fprintf (stderr,_("Cannot decode file %s\n"), ifname); - if (!is_raw) goto next; - shrink = filters && (half_size || (!identify_only && - (threshold || aber[0] != 1 || aber[2] != 1))); - iheight = (height + shrink) >> shrink; - iwidth = (width + shrink) >> shrink; - if (identify_only) { - if (verbose) { - if (document_mode == 3) { - top_margin = left_margin = fuji_width = 0; - height = raw_height; - width = raw_width; - } - iheight = (height + shrink) >> shrink; - iwidth = (width + shrink) >> shrink; - if (use_fuji_rotate) { - if (fuji_width) { - fuji_width = (fuji_width - 1 + shrink) >> shrink; - iwidth = fuji_width / sqrt(0.5); - iheight = (iheight - fuji_width) / sqrt(0.5); - } else { - if (pixel_aspect < 1) iheight = iheight / pixel_aspect + 0.5; - if (pixel_aspect > 1) iwidth = iwidth * pixel_aspect + 0.5; - } - } - if (flip & 4) - SWAP(iheight,iwidth); - printf (_("Image size: %4d x %d\n"), width, height); - printf (_("Output size: %4d x %d\n"), iwidth, iheight); - printf (_("Raw colors: %d"), colors); - if (filters) { - printf (_("\nFilter pattern: ")); - for (i=0; i < 16; i++) - putchar (cdesc[fcol(i >> 1,i & 1)]); - } - printf (_("\nDaylight multipliers:")); - FORCC printf (" %f", pre_mul[c]); - if (cam_mul[0] > 0) { - printf (_("\nCamera multipliers:")); - FORC4 printf (" %f", cam_mul[c]); - } - putchar ('\n'); - } else - printf (_("%s is a %s %s image.\n"), ifname, make, model); -next: - fclose(ifp); - continue; - } - if (use_camera_matrix && cmatrix[0][0] > 0.25) { - memcpy (rgb_cam, cmatrix, sizeof cmatrix); - raw_color = 0; - } - if (meta_length) { - meta_data = (char *) malloc (meta_length); - merror (meta_data, "main()"); - } - if (filters || colors == 1) { - raw_image = (ushort *) calloc ((raw_height+7), raw_width*2); - merror (raw_image, "main()"); - } else { - image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image); - merror (image, "main()"); - } - if (verbose) - fprintf (stderr,_("Loading %s %s image from %s ...\n"), - make, model, ifname); - if (shot_select >= is_raw) - fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"), - ifname, shot_select); - fseeko (ifp, data_offset, SEEK_SET); - if (raw_image && read_from_stdin) - fread (raw_image, 2, raw_height*raw_width, stdin); - else (*load_raw)(); - if (document_mode == 3) { - top_margin = left_margin = fuji_width = 0; - height = raw_height; - width = raw_width; - } - iheight = (height + shrink) >> shrink; - iwidth = (width + shrink) >> shrink; - if (raw_image) { - image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image); - merror (image, "main()"); - crop_masked_pixels(); - free (raw_image); - } - if (zero_is_bad) remove_zeroes(); - bad_pixels (bpfile); - if (dark_frame) subtract (dark_frame); - quality = 2 + !fuji_width; - if (user_qual >= 0) quality = user_qual; - i = cblack[3]; - FORC3 if (i > cblack[c]) i = cblack[c]; - FORC4 cblack[c] -= i; - black += i; - if (user_black >= 0) black = user_black; - FORC4 cblack[c] += black; - if (user_sat > 0) maximum = user_sat; -#ifdef COLORCHECK - colorcheck(); -#endif - if (is_foveon) { - if (document_mode || load_raw == &CLASS foveon_dp_load_raw) { - for (i=0; i < height*width*4; i++) - if ((short) image[0][i] < 0) image[0][i] = 0; - } else foveon_interpolate(); - } else if (document_mode < 2) - scale_colors(); - pre_interpolate(); - if (filters && !document_mode) { - if (quality == 0) - lin_interpolate(); - else if (quality == 1 || colors > 3) - vng_interpolate(); - else if (quality == 2 && filters > 1000) - ppg_interpolate(); - else if (filters == 9) - xtrans_interpolate (quality*2-3); - else - ahd_interpolate(); - } - if (mix_green) - for (colors=3, i=0; i < height*width; i++) - image[i][1] = (image[i][1] + image[i][3]) >> 1; - if (!is_foveon && colors == 3) median_filter(); - if (!is_foveon && highlight == 2) blend_highlights(); - if (!is_foveon && highlight > 2) recover_highlights(); - if (use_fuji_rotate) fuji_rotate(); -#ifndef NO_LCMS - if (cam_profile) apply_profile (cam_profile, out_profile); -#endif - convert_to_rgb(); - if (use_fuji_rotate) stretch(); -thumbnail: - if (write_fun == &CLASS jpeg_thumb) - write_ext = ".jpg"; - else if (output_tiff && write_fun == &CLASS write_ppm_tiff) - write_ext = ".tiff"; - else - write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5; - ofname = (char *) malloc (strlen(ifname) + 64); - merror (ofname, "main()"); - if (write_to_stdout) - strcpy (ofname,_("standard output")); - else { - strcpy (ofname, ifname); - if ((cp = strrchr (ofname, '.'))) *cp = 0; - if (multi_out) - sprintf (ofname+strlen(ofname), "_%0*d", - snprintf(0,0,"%d",is_raw-1), shot_select); - if (thumbnail_only) - strcat (ofname, ".thumb"); - strcat (ofname, write_ext); - ofp = fopen (ofname, "wb"); - if (!ofp) { - status = 1; - perror (ofname); - goto cleanup; - } - } - if (verbose) - fprintf (stderr,_("Writing data to %s ...\n"), ofname); - (*write_fun)(); - fclose(ifp); - if (ofp != stdout) fclose(ofp); -cleanup: - if (meta_data) free (meta_data); - if (ofname) free (ofname); - if (oprof) free (oprof); - if (image) free (image); - if (multi_out) { - if (++shot_select < is_raw) arg--; - else shot_select = 0; - } - } - return status; -}