From 34a419a6caca30d219a90fcfcbe8b85956f6b4b1 Mon Sep 17 00:00:00 2001 From: Ingo Date: Tue, 28 Apr 2015 15:36:50 +0200 Subject: [PATCH] Update to dcraw 9.25, Revision: 1.475 --- rtengine/dcraw.c | 546 ++++++++++++++++++++++++++++++----------- rtengine/dcraw.cc | 560 +++++++++++++++++++++++++++++++------------ rtengine/dcraw.h | 15 +- rtengine/dcraw.patch | 526 ++++++++++++++++++---------------------- 4 files changed, 1074 insertions(+), 573 deletions(-) diff --git a/rtengine/dcraw.c b/rtengine/dcraw.c index c5edada64..cf1afe4ac 100644 --- a/rtengine/dcraw.c +++ b/rtengine/dcraw.c @@ -1,6 +1,6 @@ /* dcraw.c -- Dave Coffin's raw photo decoder - Copyright 1997-2014 by Dave Coffin, dcoffin a cybercom o net + Copyright 1997-2015 by Dave Coffin, dcoffin a cybercom o net This is a command-line ANSI C program to convert raw photos from any digital camera on any computer running any operating system. @@ -19,11 +19,11 @@ *If you have not modified dcraw.c in any way, a link to my homepage qualifies as "full source code". - $Revision: 1.467 $ - $Date: 2014/07/03 21:19:24 $ + $Revision: 1.475 $ + $Date: 2015/04/11 00:08:36 $ */ -#define DCRAW_VERSION "9.22" +#define DCRAW_VERSION "9.25" #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -949,10 +949,10 @@ void CLASS lossless_jpeg_load_raw() val = curve[*rp++]; if (cr2_slice[0]) { jidx = jrow*jwide + jcol; - i = jidx / (cr2_slice[1]*jh.high); + i = jidx / (cr2_slice[1]*raw_height); if ((j = i >= cr2_slice[0])) i = cr2_slice[0]; - jidx -= i * (cr2_slice[1]*jh.high); + jidx -= i * (cr2_slice[1]*raw_height); row = jidx / cr2_slice[1+j]; col = jidx % cr2_slice[1+j] + i*cr2_slice[1]; } @@ -1198,6 +1198,25 @@ void CLASS nikon_load_raw() free (huff); } +void CLASS nikon_yuv_load_raw() +{ + int row, col, yuv[4], rgb[3], b, c; + UINT64 bitbuf=0; + + for (row=0; row < raw_height; row++) + for (col=0; col < raw_width; col++) { + if (!(b = col & 1)) { + bitbuf = 0; + FORC(6) bitbuf |= (UINT64) fgetc(ifp) << c*8; + FORC(4) yuv[c] = (bitbuf >> c*12 & 0xfff) - (c >> 1 << 11); + } + rgb[0] = yuv[b] + 1.370705*yuv[3]; + rgb[1] = yuv[b] - 0.337633*yuv[2] - 0.698001*yuv[3]; + rgb[2] = yuv[b] + 1.732446*yuv[2]; + FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,0xfff)] / cam_mul[c]; + } +} + /* Returns 1 for a Coolpix 995, 0 for anything else. */ @@ -1506,7 +1525,7 @@ void CLASS phase_one_correct() for (qr = 0; qr < 2; qr++) for (qc = 0; qc < 2; qc++) for (i = 0; i < 16; i++) - lc[qr][qc][i] = (ushort)get4(); + lc[qr][qc][i] = get4(); for (i = 0; i < 16; i++) { int v = 0; for (qr = 0; qr < 2; qr++) @@ -1516,15 +1535,15 @@ void CLASS phase_one_correct() } for (qr = 0; qr < 2; qr++) { for (qc = 0; qc < 2; qc++) { - int cx[18], cf[18]; + int cx[19], cf[19]; for (i = 0; i < 16; i++) { cx[1+i] = lc[qr][qc][i]; cf[1+i] = ref[i]; } cx[0] = cf[0] = 0; - cx[17] = cf[17] = ((unsigned int)ref[15] * 65535) / lc[qr][qc][15]; - cubic_spline(cx, cf, 18); - + cx[17] = cf[17] = ((unsigned) ref[15] * 65535) / lc[qr][qc][15]; + cx[18] = cf[18] = 65535; + cubic_spline(cx, cf, 19); for (row = (qr ? ph1.split_row : 0); row < (qr ? raw_height : ph1.split_row); row++) for (col = (qc ? ph1.split_col : 0); @@ -1553,17 +1572,17 @@ void CLASS phase_one_correct() ushort lc[2][2][7], ref[7]; int qr, qc; for (i = 0; i < 7; i++) - ref[i] = (ushort)get4(); + ref[i] = get4(); for (qr = 0; qr < 2; qr++) for (qc = 0; qc < 2; qc++) for (i = 0; i < 7; i++) - lc[qr][qc][i] = (ushort)get4(); + lc[qr][qc][i] = get4(); for (qr = 0; qr < 2; qr++) { for (qc = 0; qc < 2; qc++) { int cx[9], cf[9]; for (i = 0; i < 7; i++) { cx[1+i] = ref[i]; - cf[1+i] = ((unsigned int)ref[i] * lc[qr][qc][i]) / 10000; + cf[1+i] = ((unsigned) ref[i] * lc[qr][qc][i]) / 10000; } cx[0] = cf[0] = 0; cx[8] = cf[8] = 65535; @@ -1715,26 +1734,57 @@ void CLASS phase_one_load_raw_c() void CLASS hasselblad_load_raw() { struct jhead jh; - int row, col, pred[2], len[2], diff, c; + int shot, row, col, *back[5], len[2], diff[12], pred, sh, f, s, c; + unsigned upix, urow, ucol; + ushort *ip; if (!ljpeg_start (&jh, 0)) return; order = 0x4949; ph1_bits(-1); + back[4] = (int *) calloc (raw_width, 3*sizeof **back); + merror (back[4], "hasselblad_load_raw()"); + FORC3 back[c] = back[4] + c*raw_width; + cblack[6] >>= sh = tiff_samples > 1; + shot = LIM(shot_select, 1, tiff_samples) - 1; for (row=0; row < raw_height; row++) { - pred[0] = pred[1] = 0x8000 + load_flags; + FORC4 back[(c+3) & 3] = back[c]; for (col=0; col < raw_width; col+=2) { - FORC(2) len[c] = ph1_huff(jh.huff[0]); - FORC(2) { - diff = ph1_bits(len[c]); - if ((diff & (1 << (len[c]-1))) == 0) - diff -= (1 << len[c]) - 1; - if (diff == 65535) diff = -32768; - RAW(row,col+c) = pred[c] += diff; + for (s=0; s < tiff_samples*2; s+=2) { + FORC(2) len[c] = ph1_huff(jh.huff[0]); + FORC(2) { + diff[s+c] = ph1_bits(len[c]); + if ((diff[s+c] & (1 << (len[c]-1))) == 0) + diff[s+c] -= (1 << len[c]) - 1; + if (diff[s+c] == 65535) diff[s+c] = -32768; + } + } + for (s=col; s < col+2; s++) { + pred = 0x8000 + load_flags; + if (col) pred = back[2][s-2]; + if (col && row > 1) switch (jh.psv) { + case 11: pred += back[0][s]/2 - back[0][s-2]/2; break; + } + f = (row & 1)*3 ^ ((col+s) & 1); + FORC (tiff_samples) { + pred += diff[(s & 1)*tiff_samples+c]; + upix = pred >> sh & 0xffff; + if (raw_image && c == shot) + RAW(row,s) = upix; + if (image) { + urow = row-top_margin + (c & 1); + ucol = col-left_margin - ((c >> 1) & 1); + ip = &image[urow*width+ucol][f]; + if (urow < height && ucol < width) + *ip = c < 4 ? upix : (*ip + upix) >> 1; + } + } + back[2][s] = pred; } } } + free (back[4]); ljpeg_end (&jh); - maximum = 0xffff; + if (image) mix_green = 1; } void CLASS leaf_hdr_load_raw() @@ -1784,20 +1834,13 @@ void CLASS sinar_4shot_load_raw() ushort *pixel; unsigned shot, row, col, r, c; - if ((shot = shot_select) || half_size) { - if (shot) shot--; - if (shot > 3) shot = 3; + if (raw_image) { + shot = LIM (shot_select, 1, 4) - 1; fseek (ifp, data_offset + shot*4, SEEK_SET); fseek (ifp, get4(), SEEK_SET); unpacked_load_raw(); return; } - free (raw_image); - raw_image = 0; - free (image); - image = (ushort (*)[4]) - calloc ((iheight=height), (iwidth=width)*sizeof *image); - merror (image, "sinar_4shot_load_raw()"); pixel = (ushort *) calloc (raw_width, sizeof *pixel); merror (pixel, "sinar_4shot_load_raw()"); for (shot=0; shot < 4; shot++) { @@ -1808,12 +1851,12 @@ void CLASS sinar_4shot_load_raw() if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue; for (col=0; col < raw_width; col++) { if ((c = col-left_margin - (shot & 1)) >= width) continue; - image[r*width+c][FC(row,col)] = pixel[col]; + image[r*width+c][(row & 1)*3 ^ (~col & 1)] = pixel[col]; } } } free (pixel); - shrink = filters = 0; + mix_green = 1; } void CLASS imacon_full_load_raw() @@ -1857,8 +1900,8 @@ void CLASS packed_load_raw() } val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps); RAW(row,col ^ (load_flags >> 6 & 1)) = val; - if (load_flags & 1 && (col % 10) == 9 && - fgetc(ifp) && col < width+left_margin) derror(); + if (load_flags & 1 && (col % 10) == 9 && fgetc(ifp) && + row < height+top_margin && col < width+left_margin) derror(); } vbits -= rbits; } @@ -1868,6 +1911,7 @@ void CLASS nokia_load_raw() { uchar *data, *dp; int rev, dwide, row, col, c; + double sum[]={0,0}; rev = 3 * (order == 0x4949); dwide = (raw_width * 5 + 1) / 4; @@ -1881,6 +1925,13 @@ void CLASS nokia_load_raw() } free (data); maximum = 0x3ff; + if (strcmp(make,"OmniVision")) return; + row = raw_height/2; + FORC(width-1) { + sum[ c & 1] += SQR(RAW(row,c)-RAW(row+1,c+1)); + sum[~c & 1] += SQR(RAW(row+1,c)-RAW(row,c+1)); + } + if (sum[1] > sum[0]) filters = 0x4b4b4b4b; } void CLASS canon_rmf_load_raw() @@ -2121,12 +2172,12 @@ void CLASS kodak_radc_load_raw() (c-pt[i-2]) / (pt[i]-pt[i-2]) * (pt[i+1]-pt[i-1]) + pt[i-1] + 0.5; for (s=i=0; i < sizeof src; i+=2) FORC(256 >> src[i]) - huff[0][s++] = src[i] << 8 | (uchar) src[i+1]; + ((ushort *)huff)[s++] = src[i] << 8 | (uchar) src[i+1]; s = kodak_cbpp == 243 ? 2 : 3; FORC(256) huff[18][c] = (8-s) << 8 | c >> s << s | 1 << (s-1); getbits(-1); for (i=0; i < sizeof(buf)/sizeof(short); i++) - buf[0][0][i] = 2048; + ((short *)buf)[i] = 2048; for (row=0; row < height; row+=4) { FORC3 mul[c] = getbits(6); FORC3 { @@ -2135,7 +2186,7 @@ void CLASS kodak_radc_load_raw() x = ~(-1 << (s-1)); val <<= 12-s; for (i=0; i < sizeof(buf[0])/sizeof(short); i++) - buf[c][0][i] = (buf[c][0][i] * val + x) >> s; + ((short *)buf[c])[i] = (((short *)buf[c])[i] * val + x) >> s; last[c] = mul[c]; for (r=0; r <= !c; r++) { buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7; @@ -2343,21 +2394,46 @@ void CLASS eight_bit_load_raw() maximum = curve[0xff]; } -void CLASS kodak_yrgb_load_raw() +void CLASS kodak_c330_load_raw() +{ + uchar *pixel; + int row, col, y, cb, cr, rgb[3], c; + + pixel = (uchar *) calloc (raw_width, 2*sizeof *pixel); + merror (pixel, "kodak_c330_load_raw()"); + for (row=0; row < height; row++) { + if (fread (pixel, raw_width, 2, ifp) < 2) derror(); + if (load_flags && (row & 31) == 31) + fseek (ifp, raw_width*32, SEEK_CUR); + for (col=0; col < width; col++) { + y = pixel[col*2]; + cb = pixel[(col*2 & -4) | 1] - 128; + cr = pixel[(col*2 & -4) | 3] - 128; + rgb[1] = y - ((cb + cr + 2) >> 2); + rgb[2] = rgb[1] + cb; + rgb[0] = rgb[1] + cr; + FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)]; + } + } + free (pixel); + maximum = curve[0xff]; +} + +void CLASS kodak_c603_load_raw() { uchar *pixel; int row, col, y, cb, cr, rgb[3], c; pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel); - merror (pixel, "kodak_yrgb_load_raw()"); + merror (pixel, "kodak_c603_load_raw()"); for (row=0; row < height; row++) { if (~row & 1) if (fread (pixel, raw_width, 3, ifp) < 3) derror(); - for (col=0; col < raw_width; col++) { + for (col=0; col < width; col++) { y = pixel[width*2*(row & 1) + col]; cb = pixel[width + (col & -2)] - 128; cr = pixel[width + (col & -2)+1] - 128; - rgb[1] = y-((cb + cr + 2) >> 2); + rgb[1] = y - ((cb + cr + 2) >> 2); rgb[2] = rgb[1] + cb; rgb[0] = rgb[1] + cr; FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)]; @@ -2553,14 +2629,14 @@ void CLASS sony_load_raw() key = get4(); fseek (ifp, 164600, SEEK_SET); fread (head, 1, 40, ifp); - sony_decrypt ((unsigned int *) head, 10, 1, key); + sony_decrypt ((unsigned *) head, 10, 1, key); for (i=26; i-- > 22; ) key = key << 8 | head[i]; fseek (ifp, data_offset, SEEK_SET); for (row=0; row < raw_height; row++) { pixel = raw_image + row*raw_width; if (fread (pixel, 2, raw_width, ifp) < raw_width) derror(); - sony_decrypt ((unsigned int *) pixel, raw_width/2, !row, key); + sony_decrypt ((unsigned *) pixel, raw_width/2, !row, key); for (col=0; col < raw_width; col++) if ((pixel[col] = ntohs(pixel[col])) >> 14) derror(); } @@ -2672,6 +2748,55 @@ void CLASS samsung2_load_raw() } } +void CLASS samsung3_load_raw() +{ + int opt, init, mag, pmode, row, tab, col, pred, diff, i, c; + ushort lent[3][2], len[4], *prow[2]; + + order = 0x4949; + fseek (ifp, 9, SEEK_CUR); + opt = fgetc(ifp); + init = (get2(),get2()); + for (row=0; row < raw_height; row++) { + fseek (ifp, (data_offset-ftell(ifp)) & 15, SEEK_CUR); + ph1_bits(-1); + mag = 0; pmode = 7; + FORC(6) ((ushort *)lent)[c] = row < 2 ? 7:4; + prow[ row & 1] = &RAW(row-1,1-((row & 1) << 1)); // green + prow[~row & 1] = &RAW(row-2,0); // red and blue + for (tab=0; tab+15 < raw_width; tab+=16) { + if (~opt & 4 && !(tab & 63)) { + i = ph1_bits(2); + mag = i < 3 ? mag-'2'+"204"[i] : ph1_bits(12); + } + if (opt & 2) + pmode = 7 - 4*ph1_bits(1); + else if (!ph1_bits(1)) + pmode = ph1_bits(3); + if (opt & 1 || !ph1_bits(1)) { + FORC4 len[c] = ph1_bits(2); + FORC4 { + i = ((row & 1) << 1 | (c & 1)) % 3; + len[c] = len[c] < 3 ? lent[i][0]-'1'+"120"[len[c]] : ph1_bits(4); + lent[i][0] = lent[i][1]; + lent[i][1] = len[c]; + } + } + FORC(16) { + col = tab + (((c & 7) << 1)^(c >> 3)^(row & 1)); + pred = (pmode == 7 || row < 2) + ? (tab ? RAW(row,tab-2+(col & 1)) : init) + : (prow[col & 1][col-'4'+"0224468"[pmode]] + + prow[col & 1][col-'4'+"0244668"[pmode]] + 1) >> 1; + diff = ph1_bits (i = len[c >> 2]); + if (diff >> (i-1)) diff -= 1 << i; + diff = diff * (mag*2+1) + mag; + RAW(row,col) = pred + diff; + } + } + } +} + #define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1) /* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */ @@ -2793,10 +2918,10 @@ void CLASS smal_v9_load_raw() fseek (ifp, 67, SEEK_SET); offset = get4(); - nseg = fgetc(ifp); + nseg = (uchar) fgetc(ifp); fseek (ifp, offset, SEEK_SET); for (i=0; i < nseg*2; i++) - seg[0][i] = get4() + data_offset*(i & 1); + ((unsigned *)seg)[i] = get4() + data_offset*(i & 1); fseek (ifp, 78, SEEK_SET); holes = fgetc(ifp); fseek (ifp, 88, SEEK_SET); @@ -3259,8 +3384,8 @@ void CLASS foveon_interpolate() black = (float (*)[3]) calloc (height, sizeof *black); for (row=0; row < height; row++) { for (i=0; i < 6; i++) - ddft[0][0][i] = ddft[1][0][i] + - row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]); + ((float *)ddft[0])[i] = ((float *)ddft[1])[i] + + row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]); FORC3 black[row][c] = ( foveon_avg (image[row*width]+c, dscr[0], cfilt) + foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3 @@ -3305,8 +3430,8 @@ void CLASS foveon_interpolate() for (row=0; row < height; row++) { for (i=0; i < 6; i++) - ddft[0][0][i] = ddft[1][0][i] + - row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]); + ((float *)ddft[0])[i] = ((float *)ddft[1])[i] + + row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]); pix = image[row*width]; memcpy (prev, pix, sizeof prev); frow = row / (height-1.0) * (dim[2]-1); @@ -3345,7 +3470,7 @@ void CLASS foveon_interpolate() free (sgrow); free (sgain); - if ((badpix = (unsigned int *) foveon_camf_matrix (dim, "BadPixels"))) { + if ((badpix = (unsigned *) foveon_camf_matrix (dim, "BadPixels"))) { for (i=0; i < dim[0]; i++) { col = (badpix[i] >> 8 & 0xfff) - keep[0]; row = (badpix[i] >> 20 ) - keep[1]; @@ -4086,13 +4211,13 @@ skip_block: ; } size = iheight*iwidth; for (i=0; i < size*4; i++) { - if (!(val = image[0][i])) continue; + if (!(val = ((ushort *)image)[i])) continue; if (cblack[4] && cblack[5]) val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[5] + i/4 % iwidth % cblack[5]]; val -= cblack[i & 3]; val *= scale_mul[i & 3]; - image[0][i] = CLIP(val); + ((ushort *)image)[i] = CLIP(val); } if ((aber[0] != 1 || aber[2] != 1) && colors == 3) { if (verbose) @@ -4481,7 +4606,6 @@ void CLASS xtrans_interpolate (int passes) fprintf (stderr,_("%d-pass X-Trans interpolation...\n"), passes); cielab (0,0); - border_interpolate(6); ndir = 4 << (passes > 1); buffer = (char *) malloc (TS*TS*(ndir*11+6)); merror (buffer, "xtrans_interpolate()"); @@ -4595,14 +4719,19 @@ void CLASS xtrans_interpolate (int passes) } /* Interpolate red for blue pixels and vice versa: */ - for (row=top+1; row < mrow-1; row++) - for (col=left+1; col < mcol-1; col++) { + for (row=top+3; row < mrow-3; row++) + for (col=left+3; col < mcol-3; col++) { if ((f = 2-fcol(row,col)) == 1) continue; rix = &rgb[0][row-top][col-left]; - i = (row-sgrow) % 3 ? TS:1; - for (d=0; d < 4; d++, rix += TS*TS) + c = (row-sgrow) % 3 ? TS:1; + h = 3 * (c ^ TS ^ 1); + for (d=0; d < 4; d++, rix += TS*TS) { + i = d > 1 || ((d ^ c) & 1) || + ((ABS(rix[0][1]-rix[c][1])+ABS(rix[0][1]-rix[-c][1])) < + 2*(ABS(rix[0][1]-rix[h][1])+ABS(rix[0][1]-rix[-h][1]))) ? c:h; rix[0][f] = CLIP((rix[i][f] + rix[-i][f] + 2*rix[0][1] - rix[i][1] - rix[-i][1])/2); + } } /* Fill in red and blue for 2x2 blocks of green: */ @@ -4681,6 +4810,7 @@ void CLASS xtrans_interpolate (int passes) } } free(buffer); + border_interpolate(8); } #undef fcol @@ -5125,6 +5255,13 @@ nf: order = 0x4949; if (tag == 0x1d) while ((c = fgetc(ifp)) && c != EOF) serial = serial*10 + (isdigit(c) ? c - '0' : c % 10); + if (tag == 0x29 && type == 1) { + c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0; + fseek (ifp, 8 + c*32, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4(); + } + if (tag == 0x3d && type == 3 && len == 4) + FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_ifd[2].bps); if (tag == 0x81 && type == 4) { data_offset = get4(); fseek (ifp, data_offset + 41, SEEK_SET); @@ -5132,11 +5269,6 @@ nf: order = 0x4949; raw_width = get2(); filters = 0x61616161; } - if (tag == 0x29 && type == 1) { - c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0; - fseek (ifp, 8 + c*32, SEEK_CUR); - FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4(); - } if ((tag == 0x81 && type == 7) || (tag == 0x100 && type == 7) || (tag == 0x280 && type == 1)) { @@ -5252,14 +5384,18 @@ get2_256: fseek (ifp, i, SEEK_CUR); get2_rggb: FORC4 cam_mul[c ^ (c >> 1)] = get2(); - i = len >> 3 == 164 ? 112:22; + i = len >> 3 == 164 || len == 1506 ? 112:22; fseek (ifp, i, SEEK_CUR); FORC4 sraw_mul[c ^ (c >> 1)] = get2(); } + if (tag == 0x4021 && get4() && get4()) + FORC4 cam_mul[c] = 1024; if (tag == 0xa021) FORC4 cam_mul[c ^ (c >> 1)] = get4(); if (tag == 0xa028) FORC4 cam_mul[c ^ (c >> 1)] -= get4(); + if (tag == 0xb001) + unique_id = get2(); next: fseek (ifp, save, SEEK_SET); } @@ -5367,7 +5503,7 @@ void CLASS parse_mos (int offset) { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22", "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65", "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7", - "Aptus-II 7","","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5", + "AFi-II 7","Aptus-II 7","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5", "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" }; float romm_cam[3][3]; @@ -5393,12 +5529,12 @@ void CLASS parse_mos (int offset) } if (!strcmp(data,"icc_camera_to_tone_matrix")) { for (i=0; i < 9; i++) - romm_cam[0][i] = int_to_float(get4()); + ((float *)romm_cam)[i] = int_to_float(get4()); romm_coeff (romm_cam); } if (!strcmp(data,"CaptProf_color_matrix")) { for (i=0; i < 9; i++) - fscanf (ifp, "%f", &romm_cam[0][i]); + fscanf (ifp, "%f", (float *)romm_cam + i); romm_coeff (romm_cam); } if (!strcmp(data,"CaptProf_number_of_planes")) @@ -5456,6 +5592,8 @@ void CLASS parse_kodak_ifd (int base) wbi = -2; } if (tag == 2118) wbtemp = getint(type); + if (tag == 2120 + wbi && wbi >= 0) + FORC3 cam_mul[c] = 2048.0 / getreal(type); if (tag == 2130 + wbi) FORC3 mul[c] = getreal(type); if (tag == 2140 + wbi && wbi >= 0) @@ -5584,6 +5722,10 @@ int CLASS parse_tiff_ifd (int base) tiff_ifd[ifd].samples = jh.clrs; if (!(jh.sraw || (jh.clrs & 1))) tiff_ifd[ifd].width *= jh.clrs; + if ((tiff_ifd[ifd].width > 4*tiff_ifd[ifd].height) & ~jh.clrs) { + tiff_ifd[ifd].width /= 2; + tiff_ifd[ifd].height *= 2; + } i = order; parse_tiff (tiff_ifd[ifd].offset + 12); order = i; @@ -5682,7 +5824,7 @@ int CLASS parse_tiff_ifd (int base) break; case 33422: /* CFAPattern */ if (filters == 9) { - FORC(36) xtrans[0][c] = fgetc(ifp) & 3; + FORC(36) ((char *)xtrans)[c] = fgetc(ifp) & 3; break; } case 64777: /* Kodak P-series */ @@ -5757,8 +5899,9 @@ int CLASS parse_tiff_ifd (int base) case 40976: strip_offset = get4(); switch (tiff_ifd[ifd].comp) { - case 32770: load_raw = &CLASS samsung_load_raw; break; - case 32772: load_raw = &CLASS samsung2_load_raw; + case 32770: load_raw = &CLASS samsung_load_raw; break; + case 32772: load_raw = &CLASS samsung2_load_raw; break; + case 32773: load_raw = &CLASS samsung3_load_raw; break; } break; case 46275: /* Imacon tags */ @@ -5859,6 +6002,8 @@ guess_cfa_pc: case 61450: cblack[4] = cblack[5] = MIN(sqrt(len),64); case 50714: /* BlackLevel */ + if (!(cblack[4] * cblack[5])) + cblack[4] = cblack[5] = 1; FORC (cblack[4] * cblack[5]) cblack[6+c] = getreal(type); black = 0; @@ -5916,7 +6061,7 @@ guess_cfa_pc: break; case 50830: /* MaskedAreas */ for (i=0; i < len && i < 32; i++) - mask[0][i] = getint(type); + ((int *)mask)[i] = getint(type); black = 0; break; case 51009: /* OpcodeList2 */ @@ -6064,6 +6209,12 @@ void CLASS apply_tiff() load_flags = 1; } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes*2) { load_raw = &CLASS packed_load_raw; + if (model[0] == 'N') load_flags = 80; + } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes) { + load_raw = &CLASS nikon_yuv_load_raw; + gamma_curve (1/2.4, 12.92, 1, 4095); + memset (cblack, 0, sizeof cblack); + filters = 0; } else if (raw_width*raw_height*2 == tiff_ifd[raw].bytes) { load_raw = &CLASS unpacked_load_raw; load_flags = 4; @@ -6434,7 +6585,7 @@ void CLASS parse_phase_one (int base) case 0x100: flip = "0653"[data & 3]-'0'; break; case 0x106: for (i=0; i < 9; i++) - romm_cam[0][i] = getreal(11); + ((float *)romm_cam)[i] = getreal(11); romm_coeff (romm_cam); break; case 0x107: @@ -6558,7 +6709,7 @@ void CLASS parse_riff() end = ftell(ifp) + size; if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) { get4(); - while (ftell(ifp)+7 < end) + while (ftell(ifp)+7 < end && !feof(ifp)) parse_riff(); } else if (!memcmp(tag,"nctg",4)) { while (ftell(ifp)+7 < end) { @@ -6584,6 +6735,26 @@ void CLASS parse_riff() fseek (ifp, size, SEEK_CUR); } +void CLASS parse_qt (int end) +{ + unsigned save, size; + char tag[4]; + + order = 0x4d4d; + while (ftell(ifp)+7 < end) { + save = ftell(ifp); + if ((size = get4()) < 8) return; + fread (tag, 4, 1, ifp); + if (!memcmp(tag,"moov",4) || + !memcmp(tag,"udta",4) || + !memcmp(tag,"CNTH",4)) + parse_qt (save+size); + if (!memcmp(tag,"CNDA",4)) + parse_jpeg (ftell(ifp)); + fseek (ifp, save+size, SEEK_SET); + } +} + void CLASS parse_smal (int offset, int fsize) { int ver; @@ -6753,7 +6924,7 @@ void CLASS parse_foveon() off += pent*8 + 24; if ((unsigned) pent > 256) pent=256; for (i=0; i < pent*2; i++) - poff[0][i] = off + get4()*2; + ((int *)poff)[i] = off + get4()*2; for (i=0; i < pent; i++) { foveon_gets (poff[i][0], name, 64); foveon_gets (poff[i][1], value, 64); @@ -6803,6 +6974,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 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 5DS", 0, 0x3c96, /* DJC */ + { 6885,-753,-856,-4416,11752,2665,-1266,2393,5468 } }, { "Canon EOS 5D Mark III", 0, 0x3c80, { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } }, { "Canon EOS 5D Mark II", 0, 0x3cf0, @@ -6811,6 +6984,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } }, { "Canon EOS 6D", 0, 0x3c82, { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, + { "Canon EOS 7D Mark II", 0, 0x3510, + { 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 } }, { "Canon EOS 7D", 0, 0x3510, { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } }, { "Canon EOS 10D", 0, 0xfa0, @@ -6907,6 +7082,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } }, { "Canon PowerShot G6", 0, 0, { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } }, + { "Canon PowerShot G7 X", 0, 0, + { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, { "Canon PowerShot G9", 0, 0, { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } }, { "Canon PowerShot Pro1", 0, 0, @@ -6941,6 +7118,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } }, { "Canon PowerShot SX50 HS", 0, 0, { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } }, + { "Canon PowerShot SX60 HS", 0, 0, + { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } }, { "Canon PowerShot A3300", 0, 0, /* DJC */ { 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } }, { "Canon PowerShot A470", 0, 0, /* DJC */ @@ -6995,6 +7174,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, { "Fujifilm S100FS", 514, 0, { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } }, + { "Fujifilm S1", 0, 0, + { 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 } }, { "Fujifilm S20Pro", 0, 0, { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, { "Fujifilm S20", 512, 0x3fff, @@ -7045,16 +7226,22 @@ void CLASS adobe_coeff (const char *make, const char *model) { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, { "Fujifilm X100S", 0, 0, { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, + { "Fujifilm X100T", 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 X10", 0, 0, { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, { "Fujifilm X20", 0, 0, { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } }, + { "Fujifilm X30", 0, 0, + { 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } }, { "Fujifilm X-Pro1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, { "Fujifilm X-A1", 0, 0, { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } }, + { "Fujifilm X-A2", 0, 0, + { 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 } }, { "Fujifilm X-E1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, { "Fujifilm X-E2", 0, 0, @@ -7067,7 +7254,7 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, { "Fujifilm XF1", 0, 0, { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, - { "Fujifilm XQ1", 0, 0, + { "Fujifilm XQ", 0, 0, // XQ1 and XQ2 { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } }, { "Imacon Ixpress", 0, 0, /* DJC */ { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } }, @@ -7179,7 +7366,7 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } }, { "Nikon D3200", 0, 0xfb9, { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } }, - { "Nikon D3300", 150, 0, + { "Nikon D3300", 0, 0, { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, { "Nikon D300", 0, 0, { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } }, @@ -7193,7 +7380,7 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } }, { "Nikon D40", 0, 0, { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } }, - { "Nikon D4S", 768, 0, + { "Nikon D4S", 0, 0, { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, { "Nikon D4", 0, 0, { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, @@ -7205,8 +7392,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, { "Nikon D5200", 0, 0, { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, - { "Nikon D5300", 600, 0, + { "Nikon D5300", 0, 0, { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, + { "Nikon D5500", 0, 0, + { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } }, { "Nikon D50", 0, 0, { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, { "Nikon D600", 0, 0x3e07, @@ -7219,12 +7408,16 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, { "Nikon D7100", 0, 0, { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, + { "Nikon D7200", 0, 0, /* DJC */ + { 6111,-2759,-358,-5108,10766,4343,-769,1691,8030 } }, + { "Nikon D750", 0, 0, + { 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } }, { "Nikon D700", 0, 0, { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } }, { "Nikon D70", 0, 0, { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, - { "Nikon D810", 596, 0, /* DJC */ - { 6502,-2328,154,-4249,9943,4307,-1303,2538,8108 } }, + { "Nikon D810", 0, 0, + { 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 } }, { "Nikon D800", 0, 0, { 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } }, { "Nikon D80", 0, 0, @@ -7263,7 +7456,7 @@ void CLASS adobe_coeff (const char *make, const char *model) { 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 P330", 0, 0, + { "Nikon COOLPIX P330", 200, 0, { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, { "Nikon COOLPIX P340", 200, 0, { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, @@ -7277,10 +7470,12 @@ void CLASS adobe_coeff (const char *make, const char *model) { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, { "Nikon COOLPIX P7800", 200, 0, { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, - { "Nikon 1 V3", 200, 0, + { "Nikon 1 V3", 0, 0, { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } }, - { "Nikon 1 J4", 200, 0, + { "Nikon 1 J4", 0, 0, { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } }, + { "Nikon 1 J5", 0, 0, /* DJC */ + { 2621,-856,500,-4471,8761,5711,-1321,2644,11945 } }, { "Nikon 1 S2", 200, 0, { 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 } }, { "Nikon 1 V2", 0, 0, @@ -7355,6 +7550,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { "Olympus E-PL6", 0, 0, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-PL7", 0, 0, + { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } }, { "Olympus E-PM1", 0, 0, { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, { "Olympus E-PM2", 0, 0, @@ -7363,6 +7560,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { "Olympus E-M1", 0, 0, { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } }, + { "Olympus E-M5MarkII", 0, 0, + { 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 } }, { "Olympus E-M5", 0, 0xfe1, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { "Olympus SP350", 0, 0, @@ -7387,7 +7586,7 @@ void CLASS adobe_coeff (const char *make, const char *model) { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } }, { "Olympus XZ-2", 0, 0, { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, - { "OmniVision ov5647", 0, 0, /* DJC */ + { "OmniVision", 0, 0, /* DJC */ { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, { "Pentax *ist DL2", 0, 0, { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, @@ -7423,8 +7622,12 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } }, { "Pentax K-7", 0, 0, { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } }, + { "Pentax K-S1", 0, 0, + { 8512,-3211,-787,-4167,11966,2487,-638,1288,6054 } }, { "Pentax 645D", 0, 0x3e00, { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } }, + { "Panasonic DMC-CM1", 15, 0, + { 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 } }, { "Panasonic DMC-FZ8", 0, 0xf7f, { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } }, { "Panasonic DMC-FZ18", 0, 0, @@ -7453,6 +7656,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, { "Leica DIGILUX 2", 0, 0, { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, + { "Panasonic DMC-LX100", 15, 0, + { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } }, + { "Leica D-LUX (Typ 109)", 15, 0, + { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } }, { "Panasonic DMC-LF1", 15, 0, { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } }, { "Leica C (Typ 112)", 15, 0, @@ -7477,8 +7684,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } }, { "Leica D-LUX 6", 15, 0, { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } }, - { "Panasonic DMC-FZ1000", 15, 0, /* DJC */ - { 5686,-2219,-68,-4143,9912,4232,-1244,2246,5917 } }, + { "Panasonic DMC-FZ1000", 15, 0, + { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } }, + { "Leica V-LUX (Typ 114)", 15, 0, + { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } }, { "Panasonic DMC-FZ100", 15, 0xfff, { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } }, { "Leica V-LUX 2", 15, 0xfff, @@ -7515,6 +7724,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } }, { "Panasonic DMC-GF6", 15, 0, { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } }, + { "Panasonic DMC-GF7", 15, 0, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, { "Panasonic DMC-GH1", 15, 0xf92, { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } }, { "Panasonic DMC-GH2", 15, 0xf95, @@ -7525,6 +7736,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } }, { "Panasonic DMC-GM1", 15, 0, { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } }, + { "Panasonic DMC-GM5", 15, 0, + { 8238,-3244,-679,-3921,11814,2384,-836,2022,5852 } }, { "Panasonic DMC-GX1", 15, 0, { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, { "Panasonic DMC-GX7", 15, 0, @@ -7533,6 +7746,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } }, { "Panasonic DMC-ZS4", 15, 0, { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } }, + { "Panasonic DMC-TZ7", 15, 0, + { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } }, + { "Panasonic DMC-ZS5", 15, 0, + { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } }, { "Phase One H 20", 0, 0, /* DJC */ { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } }, { "Phase One H 25", 0, 0, @@ -7557,7 +7774,9 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, { "Samsung NX mini", 0, 0, { 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } }, - { "Samsung NX30", 0, 0, /* NX30, NX300 */ + { "Samsung NX3000", 0, 0, + { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } }, + { "Samsung NX30", 0, 0, /* NX30, NX300, NX300M */ { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, { "Samsung NX2000", 0, 0, { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, @@ -7567,8 +7786,16 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } }, { "Samsung NX1100", 0, 0, { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } }, - { "Samsung NX", 0, 0, /* NX5, NX10, NX11, NX100 */ + { "Samsung NX11", 0, 0, { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, + { "Samsung NX10", 0, 0, /* also NX100 */ + { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, + { "Samsung NX500", 0, 0, /* DJC */ + { 10196,-4532,-272,-3888,11489,2400,-1203,2424,9173 } }, + { "Samsung NX5", 0, 0, + { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, + { "Samsung NX1", 0, 0, + { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } }, { "Samsung WB2000", 0, 0xfff, { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } }, { "Samsung GX-1", 0, 0, @@ -7585,7 +7812,7 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } }, { "Sony DSC-V3", 0, 0, { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } }, - { "Sony DSC-RX100M2", 200, 0, + { "Sony DSC-RX100M", 200, 0, /* M2 and M3 */ { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, { "Sony DSC-RX100", 200, 0, { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } }, @@ -7625,13 +7852,15 @@ void CLASS adobe_coeff (const char *make, const char *model) { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } }, { "Sony ILCA-77M2", 128, 0, { 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } }, + { "Sony ILCE-7M2", 128, 0, + { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, { "Sony ILCE-7S", 128, 0, { 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } }, { "Sony ILCE-7R", 128, 0, { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } }, { "Sony ILCE-7", 128, 0, { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, - { "Sony ILCE", 128, 0, /* 3000, 5000, and 6000 */ + { "Sony ILCE", 128, 0, /* 3000, 5000, 5100, 6000, and QX1 */ { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, { "Sony NEX-5N", 128, 0, { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, @@ -7685,7 +7914,7 @@ void CLASS adobe_coeff (const char *make, const char *model) if (table[i].maximum) maximum = (ushort) table[i].maximum; if (table[i].trans[0]) { for (raw_color = j=0; j < 12; j++) - cam_xyz[0][j] = table[i].trans[j] / 10000.0; + ((double *)cam_xyz)[j] = table[i].trans[j] / 10000.0; cam_xyz_coeff (rgb_cam, cam_xyz); } break; @@ -7814,6 +8043,7 @@ void CLASS identify() { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 }, { 4480, 3366, 80, 50, 0, 0 }, { 4496, 3366, 80, 50, 12, 0 }, + { 4768, 3516, 96, 16, 0, 0, 0, 16 }, { 4832, 3204, 62, 26, 0, 0 }, { 4832, 3228, 62, 51, 0, 0 }, { 5108, 3349, 98, 13, 0, 0 }, @@ -7823,9 +8053,11 @@ void CLASS identify() { 5344, 3584, 126,100, 0, 2 }, { 5360, 3516, 158, 51, 0, 0 }, { 5568, 3708, 72, 38, 0, 0 }, + { 5632, 3710, 96, 17, 0, 0, 0, 16, 0, 0, 0x49 }, { 5712, 3774, 62, 20, 10, 2 }, { 5792, 3804, 158, 51, 0, 0 }, { 5920, 3950, 122, 80, 2, 0 }, + { 8896, 5920, 160, 64, 0, 0 }, }; static const struct { ushort id; @@ -7851,6 +8083,33 @@ void CLASS identify() { 0x288, "EOS 1100D" }, { 0x327, "EOS 1200D" }, { 0x346, "EOS 100D" }, + }, sonique[] = { + { 0x002, "DSC-R1" }, { 0x100, "DSLR-A100" }, + { 0x101, "DSLR-A900" }, { 0x102, "DSLR-A700" }, + { 0x103, "DSLR-A200" }, { 0x104, "DSLR-A350" }, + { 0x105, "DSLR-A300" }, { 0x108, "DSLR-A330" }, + { 0x109, "DSLR-A230" }, { 0x10a, "DSLR-A290" }, + { 0x10d, "DSLR-A850" }, { 0x111, "DSLR-A550" }, + { 0x112, "DSLR-A500" }, { 0x113, "DSLR-A450" }, + { 0x116, "NEX-5" }, { 0x117, "NEX-3" }, + { 0x118, "SLT-A33" }, { 0x119, "SLT-A55V" }, + { 0x11a, "DSLR-A560" }, { 0x11b, "DSLR-A580" }, + { 0x11c, "NEX-C3" }, { 0x11d, "SLT-A35" }, + { 0x11e, "SLT-A65V" }, { 0x11f, "SLT-A77V" }, + { 0x120, "NEX-5N" }, { 0x121, "NEX-7" }, + { 0x123, "SLT-A37" }, { 0x124, "SLT-A57" }, + { 0x125, "NEX-F3" }, { 0x126, "SLT-A99V" }, + { 0x127, "NEX-6" }, { 0x128, "NEX-5R" }, + { 0x129, "DSC-RX100" }, { 0x12a, "DSC-RX1" }, + { 0x12e, "ILCE-3000" }, { 0x12f, "SLT-A58" }, + { 0x131, "NEX-3N" }, { 0x132, "ILCE-7" }, + { 0x133, "NEX-5T" }, { 0x134, "DSC-RX100M2" }, + { 0x135, "DSC-RX10" }, { 0x136, "DSC-RX1R" }, + { 0x137, "ILCE-7R" }, { 0x138, "ILCE-6000" }, + { 0x139, "ILCE-5000" }, { 0x13d, "DSC-RX100M3" }, + { 0x13e, "ILCE-7S" }, { 0x13f, "ILCA-77M2" }, + { 0x153, "ILCE-5100" }, { 0x154, "ILCE-7M2" }, + { 0x15a, "ILCE-QX1" }, }; static const struct { unsigned fsize; @@ -7918,6 +8177,8 @@ void CLASS identify() { 1652736,1536,1076, 0,52, 0, 0, 0,0x61,0,0,"Kodak","DCS200" }, { 4159302,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330" }, { 4162462,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330",3160 }, + { 2247168,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" }, + { 3370752,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" }, { 6163328,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603" }, { 6166488,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603",3160 }, { 460800, 640, 480, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" }, @@ -7926,6 +8187,7 @@ void CLASS identify() { 12272756,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP",31556 }, { 18000000,4000,3000, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","12MP" }, { 614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" }, + { 15360000,3200,2400, 0, 0, 0, 0,96,0x16,0,0,"Lenovo","A820" }, { 3884928,1608,1207, 0, 0, 0, 0,96,0x16,0,0,"Micron","2010",3212 }, { 1138688,1534, 986, 0, 0, 0, 0, 0,0x61,0,0,"Minolta","RD175",513 }, { 1581060,1305, 969, 0, 0,18, 6, 6,0x1e,4,1,"Nikon","E900" }, @@ -8055,6 +8317,10 @@ void CLASS identify() } else if (!memcmp (head,"RIFF",4)) { fseek (ifp, 0, SEEK_SET); parse_riff(); + } else if (!memcmp (head+4,"ftypqt ",9)) { + fseek (ifp, 0, SEEK_SET); + parse_qt (fsize); + is_raw = 0; } else if (!memcmp (head,"\0\001\0\001\0@",6)) { fseek (ifp, 6, SEEK_SET); fread (make, 1, 8, ifp); @@ -8160,7 +8426,8 @@ void CLASS identify() 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) && + if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5)) && + !fseek (ifp, -6404096, SEEK_END) && fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) { strcpy (make, "OmniVision"); data_offset = ftell(ifp) + 0x8000-32; @@ -8246,8 +8513,14 @@ void CLASS identify() } } for (i=0; i < sizeof unique / sizeof *unique; i++) - if (unique_id == 0x80000000 + unique[i].id) + if (unique_id == 0x80000000 + unique[i].id) { adobe_coeff ("Canon", unique[i].model); + if (model[4] == 'K' && strlen(model) == 8) + strcpy (model, unique[i].model); + } + for (i=0; i < sizeof sonique / sizeof *sonique; i++) + if (unique_id == sonique[i].id) + strcpy (model, sonique[i].model); if (!strcmp(make,"Nikon")) { if (!load_raw) load_raw = &CLASS packed_load_raw; @@ -8273,7 +8546,10 @@ void CLASS identify() case 3344: width -= 66; case 3872: width -= 6; } - if (height > width) SWAP(height,width); + if (height > width) { + SWAP(height,width); + SWAP(raw_height,raw_width); + } filters = 0; tiff_samples = colors = 3; load_raw = &CLASS canon_sraw_load_raw; @@ -8346,7 +8622,7 @@ canon_a5: !strcmp(model,"COOLPIX A")) { width -= 44; } else if (!strcmp(model,"D3200") || - !strcmp(model,"D600") || + !strncmp(model,"D6",2) || !strncmp(model,"D800",4)) { width -= 46; } else if (!strcmp(model,"D4") || @@ -8372,9 +8648,7 @@ canon_a5: else width -= 8; } else if (!strncmp(model,"D300",4)) { width -= 32; - } else if (!strcmp(make,"Nikon") && raw_width == 4032) { - adobe_coeff ("Nikon","COOLPIX P7700"); - } else if (!strncmp(model,"COOLPIX P",9)) { + } else if (!strncmp(model,"COOLPIX P",9) && raw_width != 4032) { load_flags = 24; filters = 0x94949494; if (model[9] == '7' && iso_speed >= 400) @@ -8462,7 +8736,7 @@ canon_a5: } if (fuji_layout) raw_width *= is_raw; if (filters == 9) - FORC(36) xtrans[0][c] = + FORC(36) ((char *)xtrans)[c] = xtrans_abs[(c/6+top_margin) % 6][(c+left_margin) % 6]; } else if (!strcmp(model,"KD-400Z")) { height = 1712; @@ -8515,8 +8789,10 @@ konica_400z: width -= 2 * (left_margin = 8); load_flags = 32; } else if (!strcmp(make,"Samsung") && raw_height == 3714) { - height -= 18; - width = 5536; + height -= top_margin = 18; + left_margin = raw_width - (width = 5536); + if (raw_width != 5600) + left_margin = top_margin = 0; filters = 0x61616161; colors = 3; } else if (!strcmp(make,"Samsung") && raw_width == 5632) { @@ -8530,6 +8806,9 @@ konica_400z: left_margin = 96; width = 5544; filters = 0x49494949; + } else if (!strcmp(make,"Samsung") && raw_width == 6496) { + filters = 0x61616161; + black = 1 << (tiff_bps - 7); } else if (!strcmp(model,"EX1")) { order = 0x4949; height -= 20; @@ -8572,9 +8851,9 @@ konica_400z: top_margin = 4; left_margin = 7; filters = 0x61616161; - } else if (raw_width == 7410) { - height = 5502; - width = 7328; + } else if (raw_width == 7410 || raw_width == 8282) { + height -= 84; + width -= 82; top_margin = 4; left_margin = 41; filters = 0x61616161; @@ -8591,8 +8870,13 @@ konica_400z: width -= (left_margin = 3) + 7; filters = 0x61616161; } + if (tiff_samples > 1) { + is_raw = tiff_samples+1; + if (!shot_select && !half_size) filters = 0; + } } else if (!strcmp(make,"Sinar")) { if (!load_raw) load_raw = &CLASS unpacked_load_raw; + if (is_raw > 1 && !shot_select && !half_size) filters = 0; maximum = 0x3fff; } else if (!strcmp(make,"Leaf")) { maximum = 0x3fff; @@ -8665,6 +8949,7 @@ konica_400z: if (exif_cfa) filters = exif_cfa; if (width == 4100) width -= 4; if (width == 4080) width -= 24; + if (width == 9280) { width -= 6; height -= 6; } if (load_raw == &CLASS unpacked_load_raw) load_flags = 4; tiff_bps = 12; @@ -8706,7 +8991,6 @@ konica_400z: data_offset = 787392; load_raw = &CLASS sony_load_raw; } else if (!strcmp(make,"Sony") && raw_width == 3984) { - adobe_coeff ("Sony","DSC-R1"); width = 3925; order = 0x4d4d; } else if (!strcmp(make,"Sony") && raw_width == 4288) { @@ -8745,40 +9029,28 @@ konica_400z: fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET); read_shorts (curve, 256); } else gamma_curve (0, 3.875, 1, 255); - load_raw = filters ? &CLASS eight_bit_load_raw - : &CLASS kodak_yrgb_load_raw; + load_raw = filters ? &CLASS eight_bit_load_raw : + strcmp(model,"C330") ? &CLASS kodak_c603_load_raw : + &CLASS kodak_c330_load_raw; + load_flags = tiff_bps > 16; + tiff_bps = 8; } else if (!strncasecmp(model,"EasyShare",9)) { data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000; load_raw = &CLASS packed_load_raw; } else if (!strcasecmp(make,"Kodak")) { if (filters == UINT_MAX) filters = 0x61616161; - if (!strncmp(model,"NC2000",6)) { + if (!strncmp(model,"NC2000",6) || + !strncmp(model,"EOSDCS",6) || + !strncmp(model,"DCS4",4)) { width -= 4; left_margin = 2; - } else if (!strcmp(model,"EOSDCS3B")) { - width -= 4; - left_margin = 2; - } else if (!strcmp(model,"EOSDCS1")) { - width -= 4; - left_margin = 2; - } else if (!strcmp(model,"DCS420")) { - width -= 4; - left_margin = 2; - } else if (!strncmp(model,"DCS460 ",7)) { - model[6] = 0; - width -= 4; - left_margin = 2; - } else if (!strcmp(model,"DCS460A")) { - width -= 4; - left_margin = 2; - colors = 1; - filters = 0; + if (model[6] == ' ') model[6] = 0; + if (!strcmp(model,"DCS460A")) goto bw; } else if (!strcmp(model,"DCS660M")) { black = 214; - colors = 1; - filters = 0; + goto bw; } else if (!strcmp(model,"DCS760M")) { - colors = 1; +bw: colors = 1; filters = 0; } if (!strcmp(model+4,"20X")) @@ -8899,7 +9171,7 @@ dng_skip: if (!tiff_bps) tiff_bps = 12; if (!maximum) maximum = (1 << tiff_bps) - 1; if (!load_raw || height < 22 || width < 22 || - tiff_bps > 16 || tiff_samples > 4 || colors > 4) + tiff_bps > 16 || tiff_samples > 6 || colors > 4) is_raw = 0; #ifdef NO_JASPER if (load_raw == &CLASS redcine_load_raw) { @@ -9622,9 +9894,15 @@ int CLASS main (int argc, const char **argv) printf (_("Output size: %4d x %d\n"), iwidth, iheight); printf (_("Raw colors: %d"), colors); if (filters) { + int fhigh = 2, fwide = 2; + if ((filters ^ (filters >> 8)) & 0xff) fhigh = 4; + if ((filters ^ (filters >> 16)) & 0xffff) fhigh = 8; + if (filters == 1) fhigh = fwide = 16; + if (filters == 9) fhigh = fwide = 6; printf (_("\nFilter pattern: ")); - for (i=0; i < 16; i++) - putchar (cdesc[fcol(i >> 1,i & 1)]); + for (i=0; i < fhigh; i++) + for (c = i && putchar('/') && 0; c < fwide; c++) + putchar (cdesc[fcol(i,c)]); } printf (_("\nDaylight multipliers:")); FORCC printf (" %f", pre_mul[c]); diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index bba64ba71..437784fb5 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -12,7 +12,7 @@ /* dcraw.c -- Dave Coffin's raw photo decoder - Copyright 1997-2014 by Dave Coffin, dcoffin a cybercom o net + Copyright 1997-2015 by Dave Coffin, dcoffin a cybercom o net This is a command-line ANSI C program to convert raw photos from any digital camera on any computer running any operating system. @@ -31,11 +31,11 @@ *If you have not modified dcraw.c in any way, a link to my homepage qualifies as "full source code". - $Revision: 1.467 $ - $Date: 2014/07/03 21:19:24 $ + $Revision: 1.475 $ + $Date: 2015/04/11 00:08:36 $ */ -#define DCRAW_VERSION "9.22" +#define DCRAW_VERSION "9.25" #ifndef _GNU_SOURCE #define _GNU_SOURCE @@ -112,7 +112,7 @@ typedef unsigned long long UINT64; #define ushort UshORt typedef unsigned char uchar; typedef unsigned short ushort; - + #include "dcraw.h" /* RT All global variables are defined here, and all functions that @@ -912,10 +912,10 @@ void CLASS lossless_jpeg_load_raw() val = curve[*rp++]; if (cr2_slice[0]) { jidx = jrow*jwide + jcol; - i = jidx / (cr2_slice[1]*jh.high); + i = jidx / (cr2_slice[1]*raw_height); if ((j = i >= cr2_slice[0])) i = cr2_slice[0]; - jidx -= i * (cr2_slice[1]*jh.high); + jidx -= i * (cr2_slice[1]*raw_height); row = jidx / cr2_slice[1+j]; col = jidx % cr2_slice[1+j] + i*cr2_slice[1]; } @@ -1161,6 +1161,25 @@ void CLASS nikon_load_raw() free (huff); } +void CLASS nikon_yuv_load_raw() +{ + int row, col, yuv[4], rgb[3], b, c; + UINT64 bitbuf=0; + + for (row=0; row < raw_height; row++) + for (col=0; col < raw_width; col++) { + if (!(b = col & 1)) { + bitbuf = 0; + FORC(6) bitbuf |= (UINT64) fgetc(ifp) << c*8; + FORC(4) yuv[c] = (bitbuf >> c*12 & 0xfff) - (c >> 1 << 11); + } + rgb[0] = yuv[b] + 1.370705*yuv[3]; + rgb[1] = yuv[b] - 0.337633*yuv[2] - 0.698001*yuv[3]; + rgb[2] = yuv[b] + 1.732446*yuv[2]; + FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,0xfff)] / cam_mul[c]; + } +} + /* Returns 1 for a Coolpix 995, 0 for anything else. */ @@ -1469,7 +1488,7 @@ void CLASS phase_one_correct() for (qr = 0; qr < 2; qr++) for (qc = 0; qc < 2; qc++) for (i = 0; i < 16; i++) - lc[qr][qc][i] = (ushort)get4(); + lc[qr][qc][i] = get4(); for (i = 0; i < 16; i++) { int v = 0; for (qr = 0; qr < 2; qr++) @@ -1485,10 +1504,9 @@ void CLASS phase_one_correct() cf[1+i] = ref[i]; } cx[0] = cf[0] = 0; - cx[17] = cf[17] = ((unsigned int)ref[15] * 65535) / lc[qr][qc][15]; - cx[18] = cf[18] = 65535; + cx[17] = cf[17] = ((unsigned) ref[15] * 65535) / lc[qr][qc][15]; + cx[18] = cf[18] = 65535; cubic_spline(cx, cf, 19); - for (row = (qr ? ph1.split_row : 0); row < (qr ? raw_height : ph1.split_row); row++) for (col = (qc ? ph1.split_col : 0); @@ -1517,17 +1535,17 @@ void CLASS phase_one_correct() ushort lc[2][2][7], ref[7]; int qr, qc; for (i = 0; i < 7; i++) - ref[i] = (ushort)get4(); + ref[i] = get4(); for (qr = 0; qr < 2; qr++) for (qc = 0; qc < 2; qc++) for (i = 0; i < 7; i++) - lc[qr][qc][i] = (ushort)get4(); + lc[qr][qc][i] = get4(); for (qr = 0; qr < 2; qr++) { for (qc = 0; qc < 2; qc++) { int cx[9], cf[9]; for (i = 0; i < 7; i++) { cx[1+i] = ref[i]; - cf[1+i] = ((unsigned int)ref[i] * lc[qr][qc][i]) / 10000; + cf[1+i] = ((unsigned) ref[i] * lc[qr][qc][i]) / 10000; } cx[0] = cf[0] = 0; cx[8] = cf[8] = 65535; @@ -2009,26 +2027,57 @@ void CLASS hasselblad_correct() void CLASS hasselblad_load_raw() { struct jhead jh; - int row, col, pred[2], len[2], diff, c; + int shot, row, col, *back[5], len[2], diff[12], pred, sh, f, s, c; + unsigned upix, urow, ucol; + ushort *ip; if (!ljpeg_start (&jh, 0)) return; order = 0x4949; ph1_bits(-1); + back[4] = (int *) calloc (raw_width, 3*sizeof **back); + merror (back[4], "hasselblad_load_raw()"); + FORC3 back[c] = back[4] + c*raw_width; + cblack[6] >>= sh = tiff_samples > 1; + shot = LIM(shot_select, 1, tiff_samples) - 1; for (row=0; row < raw_height; row++) { - pred[0] = pred[1] = 0x8000 + load_flags; + FORC4 back[(c+3) & 3] = back[c]; for (col=0; col < raw_width; col+=2) { - FORC(2) len[c] = ph1_huff(jh.huff[0]); - FORC(2) { - diff = ph1_bits(len[c]); - if ((diff & (1 << (len[c]-1))) == 0) - diff -= (1 << len[c]) - 1; - if (diff == 65535) diff = -32768; - RAW(row,col+c) = pred[c] += diff; + for (s=0; s < tiff_samples*2; s+=2) { + FORC(2) len[c] = ph1_huff(jh.huff[0]); + FORC(2) { + diff[s+c] = ph1_bits(len[c]); + if ((diff[s+c] & (1 << (len[c]-1))) == 0) + diff[s+c] -= (1 << len[c]) - 1; + if (diff[s+c] == 65535) diff[s+c] = -32768; + } + } + for (s=col; s < col+2; s++) { + pred = 0x8000 + load_flags; + if (col) pred = back[2][s-2]; + if (col && row > 1) switch (jh.psv) { + case 11: pred += back[0][s]/2 - back[0][s-2]/2; break; + } + f = (row & 1)*3 ^ ((col+s) & 1); + FORC (tiff_samples) { + pred += diff[(s & 1)*tiff_samples+c]; + upix = pred >> sh & 0xffff; + if (raw_image && c == shot) + RAW(row,s) = upix; + if (image) { + urow = row-top_margin + (c & 1); + ucol = col-left_margin - ((c >> 1) & 1); + ip = &image[urow*width+ucol][f]; + if (urow < height && ucol < width) + *ip = c < 4 ? upix : (*ip + upix) >> 1; + } + } + back[2][s] = pred; } } } + free (back[4]); ljpeg_end (&jh); - maximum = 0xffff; + if (image) mix_green = 1; } void CLASS leaf_hdr_load_raw() @@ -2078,20 +2127,13 @@ void CLASS sinar_4shot_load_raw() ushort *pixel; unsigned shot, row, col, r, c; - if ((shot = shot_select) || half_size) { - if (shot) shot--; - if (shot > 3) shot = 3; + if (raw_image) { + shot = LIM (shot_select, 1, 4) - 1; fseek (ifp, data_offset + shot*4, SEEK_SET); fseek (ifp, get4(), SEEK_SET); unpacked_load_raw(); return; } - free (raw_image); - raw_image = 0; - free (image); - image = (ushort (*)[4]) - calloc ((iheight=height), (iwidth=width)*sizeof *image); - merror (image, "sinar_4shot_load_raw()"); pixel = (ushort *) calloc (raw_width, sizeof *pixel); merror (pixel, "sinar_4shot_load_raw()"); for (shot=0; shot < 4; shot++) { @@ -2102,12 +2144,12 @@ void CLASS sinar_4shot_load_raw() if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue; for (col=0; col < raw_width; col++) { if ((c = col-left_margin - (shot & 1)) >= width) continue; - image[r*width+c][FC(row,col)] = pixel[col]; + image[r*width+c][(row & 1)*3 ^ (~col & 1)] = pixel[col]; } } } free (pixel); - shrink = filters = 0; + mix_green = 1; } void CLASS imacon_full_load_raw() @@ -2151,8 +2193,8 @@ void CLASS packed_load_raw() } val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps); RAW(row,col ^ (load_flags >> 6 & 1)) = val; - if (load_flags & 1 && (col % 10) == 9 && - fgetc(ifp) && col < width+left_margin) derror(); + if (load_flags & 1 && (col % 10) == 9 && fgetc(ifp) && + row < height+top_margin && col < width+left_margin) derror(); } vbits -= rbits; } @@ -2162,6 +2204,7 @@ void CLASS nokia_load_raw() { uchar *data, *dp; int rev, dwide, row, col, c; + double sum[]={0,0}; rev = 3 * (order == 0x4949); dwide = (raw_width * 5 + 1) / 4; @@ -2175,6 +2218,13 @@ void CLASS nokia_load_raw() } free (data); maximum = 0x3ff; + if (strcmp(make,"OmniVision")) return; + row = raw_height/2; + FORC(width-1) { + sum[ c & 1] += SQR(RAW(row,c)-RAW(row+1,c+1)); + sum[~c & 1] += SQR(RAW(row+1,c)-RAW(row,c+1)); + } + if (sum[1] > sum[0]) filters = 0x4b4b4b4b; } void CLASS canon_rmf_load_raw() @@ -2415,12 +2465,12 @@ void CLASS kodak_radc_load_raw() (c-pt[i-2]) / (pt[i]-pt[i-2]) * (pt[i+1]-pt[i-1]) + pt[i-1] + 0.5; for (s=i=0; i < sizeof src; i+=2) FORC(256 >> src[i]) - huff[0][s++] = src[i] << 8 | (uchar) src[i+1]; + ((ushort *)huff)[s++] = src[i] << 8 | (uchar) src[i+1]; s = kodak_cbpp == 243 ? 2 : 3; FORC(256) huff[18][c] = (8-s) << 8 | c >> s << s | 1 << (s-1); getbits(-1); for (i=0; i < sizeof(buf)/sizeof(short); i++) - buf[0][0][i] = 2048; + ((short *)buf)[i] = 2048; for (row=0; row < height; row+=4) { FORC3 mul[c] = getbits(6); FORC3 { @@ -2429,7 +2479,7 @@ void CLASS kodak_radc_load_raw() x = ~(-1 << (s-1)); val <<= 12-s; for (i=0; i < sizeof(buf[0])/sizeof(short); i++) - buf[c][0][i] = (buf[c][0][i] * val + x) >> s; + ((short *)buf[c])[i] = (((short *)buf[c])[i] * val + x) >> s; last[c] = mul[c]; for (r=0; r <= !c; r++) { buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7; @@ -2637,21 +2687,46 @@ void CLASS eight_bit_load_raw() maximum = curve[0xff]; } -void CLASS kodak_yrgb_load_raw() +void CLASS kodak_c330_load_raw() +{ + uchar *pixel; + int row, col, y, cb, cr, rgb[3], c; + + pixel = (uchar *) calloc (raw_width, 2*sizeof *pixel); + merror (pixel, "kodak_c330_load_raw()"); + for (row=0; row < height; row++) { + if (fread (pixel, raw_width, 2, ifp) < 2) derror(); + if (load_flags && (row & 31) == 31) + fseek (ifp, raw_width*32, SEEK_CUR); + for (col=0; col < width; col++) { + y = pixel[col*2]; + cb = pixel[(col*2 & -4) | 1] - 128; + cr = pixel[(col*2 & -4) | 3] - 128; + rgb[1] = y - ((cb + cr + 2) >> 2); + rgb[2] = rgb[1] + cb; + rgb[0] = rgb[1] + cr; + FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)]; + } + } + free (pixel); + maximum = curve[0xff]; +} + +void CLASS kodak_c603_load_raw() { uchar *pixel; int row, col, y, cb, cr, rgb[3], c; pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel); - merror (pixel, "kodak_yrgb_load_raw()"); + merror (pixel, "kodak_c603_load_raw()"); for (row=0; row < height; row++) { if (~row & 1) if (fread (pixel, raw_width, 3, ifp) < 3) derror(); - for (col=0; col < raw_width; col++) { + for (col=0; col < width; col++) { y = pixel[width*2*(row & 1) + col]; cb = pixel[width + (col & -2)] - 128; cr = pixel[width + (col & -2)+1] - 128; - rgb[1] = y-((cb + cr + 2) >> 2); + rgb[1] = y - ((cb + cr + 2) >> 2); rgb[2] = rgb[1] + cb; rgb[0] = rgb[1] + cr; FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)]; @@ -2846,14 +2921,14 @@ void CLASS sony_load_raw() key = get4(); fseek (ifp, 164600, SEEK_SET); fread (head, 1, 40, ifp); - sony_decrypt ((unsigned int *) head, 10, 1, key); + sony_decrypt ((unsigned *) head, 10, 1, key); for (i=26; i-- > 22; ) key = key << 8 | head[i]; fseek (ifp, data_offset, SEEK_SET); for (row=0; row < raw_height; row++) { pixel = raw_image + row*raw_width; if (fread (pixel, 2, raw_width, ifp) < raw_width) derror(); - sony_decrypt ((unsigned int *) pixel, raw_width/2, !row, key); + sony_decrypt ((unsigned *) pixel, raw_width/2, !row, key); for (col=0; col < raw_width; col++) if ((pixel[col] = ntohs(pixel[col])) >> 14) derror(); } @@ -2967,6 +3042,55 @@ void CLASS samsung2_load_raw() } } +void CLASS samsung3_load_raw() +{ + int opt, init, mag, pmode, row, tab, col, pred, diff, i, c; + ushort lent[3][2], len[4], *prow[2]; + + order = 0x4949; + fseek (ifp, 9, SEEK_CUR); + opt = fgetc(ifp); + init = (get2(),get2()); + for (row=0; row < raw_height; row++) { + fseek (ifp, (data_offset-ftell(ifp)) & 15, SEEK_CUR); + ph1_bits(-1); + mag = 0; pmode = 7; + FORC(6) ((ushort *)lent)[c] = row < 2 ? 7:4; + prow[ row & 1] = &RAW(row-1,1-((row & 1) << 1)); // green + prow[~row & 1] = &RAW(row-2,0); // red and blue + for (tab=0; tab+15 < raw_width; tab+=16) { + if (~opt & 4 && !(tab & 63)) { + i = ph1_bits(2); + mag = i < 3 ? mag-'2'+"204"[i] : ph1_bits(12); + } + if (opt & 2) + pmode = 7 - 4*ph1_bits(1); + else if (!ph1_bits(1)) + pmode = ph1_bits(3); + if (opt & 1 || !ph1_bits(1)) { + FORC4 len[c] = ph1_bits(2); + FORC4 { + i = ((row & 1) << 1 | (c & 1)) % 3; + len[c] = len[c] < 3 ? lent[i][0]-'1'+"120"[len[c]] : ph1_bits(4); + lent[i][0] = lent[i][1]; + lent[i][1] = len[c]; + } + } + FORC(16) { + col = tab + (((c & 7) << 1)^(c >> 3)^(row & 1)); + pred = (pmode == 7 || row < 2) + ? (tab ? RAW(row,tab-2+(col & 1)) : init) + : (prow[col & 1][col-'4'+"0224468"[pmode]] + + prow[col & 1][col-'4'+"0244668"[pmode]] + 1) >> 1; + diff = ph1_bits (i = len[c >> 2]); + if (diff >> (i-1)) diff -= 1 << i; + diff = diff * (mag*2+1) + mag; + RAW(row,col) = pred + diff; + } + } + } +} + #define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1) /* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */ @@ -3088,10 +3212,10 @@ void CLASS smal_v9_load_raw() fseek (ifp, 67, SEEK_SET); offset = get4(); - nseg = fgetc(ifp); + nseg = (uchar) fgetc(ifp); fseek (ifp, offset, SEEK_SET); for (i=0; i < nseg*2; i++) - seg[0][i] = get4() + data_offset*(i & 1); + ((unsigned *)seg)[i] = get4() + data_offset*(i & 1); fseek (ifp, 78, SEEK_SET); holes = fgetc(ifp); fseek (ifp, 88, SEEK_SET); @@ -3554,8 +3678,8 @@ void CLASS foveon_interpolate() black = (float (*)[3]) calloc (height, sizeof *black); for (row=0; row < height; row++) { for (i=0; i < 6; i++) - ddft[0][0][i] = ddft[1][0][i] + - row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]); + ((float *)ddft[0])[i] = ((float *)ddft[1])[i] + + row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]); FORC3 black[row][c] = ( foveon_avg (image[row*width]+c, dscr[0], cfilt) + foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3 @@ -3600,8 +3724,8 @@ void CLASS foveon_interpolate() for (row=0; row < height; row++) { for (i=0; i < 6; i++) - ddft[0][0][i] = ddft[1][0][i] + - row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]); + ((float *)ddft[0])[i] = ((float *)ddft[1])[i] + + row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]); pix = image[row*width]; memcpy (prev, pix, sizeof prev); frow = row / (height-1.0) * (dim[2]-1); @@ -3640,7 +3764,7 @@ void CLASS foveon_interpolate() free (sgrow); free (sgain); - if ((badpix = (unsigned int *) foveon_camf_matrix (dim, "BadPixels"))) { + if ((badpix = (unsigned *) foveon_camf_matrix (dim, "BadPixels"))) { for (i=0; i < dim[0]; i++) { col = (badpix[i] >> 8 & 0xfff) - keep[0]; row = (badpix[i] >> 20 ) - keep[1]; @@ -4386,13 +4510,13 @@ skip_block: ; } size = iheight*iwidth; for (i=0; i < size*4; i++) { - if (!(val = image[0][i])) continue; + if (!(val = ((ushort *)image)[i])) continue; if (cblack[4] && cblack[5]) val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[5] + i/4 % iwidth % cblack[5]]; val -= cblack[i & 3]; val *= scale_mul[i & 3]; - image[0][i] = CLIP(val); + ((ushort *)image)[i] = CLIP(val); } if ((aber[0] != 1 || aber[2] != 1) && colors == 3) { if (verbose) @@ -4550,7 +4674,6 @@ void CLASS xtrans_interpolate (int passes) fprintf (stderr,_("%d-pass X-Trans interpolation...\n"), passes); cielab (0,0); - border_interpolate(6); ndir = 4 << (passes > 1); buffer = (char *) malloc (TS*TS*(ndir*11+6)); merror (buffer, "xtrans_interpolate()"); @@ -4664,14 +4787,19 @@ void CLASS xtrans_interpolate (int passes) } /* Interpolate red for blue pixels and vice versa: */ - for (row=top+1; row < mrow-1; row++) - for (col=left+1; col < mcol-1; col++) { + for (row=top+3; row < mrow-3; row++) + for (col=left+3; col < mcol-3; col++) { if ((f = 2-fcol(row,col)) == 1) continue; rix = &rgb[0][row-top][col-left]; - i = (row-sgrow) % 3 ? TS:1; - for (d=0; d < 4; d++, rix += TS*TS) + c = (row-sgrow) % 3 ? TS:1; + h = 3 * (c ^ TS ^ 1); + for (d=0; d < 4; d++, rix += TS*TS) { + i = d > 1 || ((d ^ c) & 1) || + ((ABS(rix[0][1]-rix[c][1])+ABS(rix[0][1]-rix[-c][1])) < + 2*(ABS(rix[0][1]-rix[h][1])+ABS(rix[0][1]-rix[-h][1]))) ? c:h; rix[0][f] = CLIP((rix[i][f] + rix[-i][f] + 2*rix[0][1] - rix[i][1] - rix[-i][1])/2); + } } /* Fill in red and blue for 2x2 blocks of green: */ @@ -4750,6 +4878,7 @@ void CLASS xtrans_interpolate (int passes) } } free(buffer); + border_interpolate(8); } #undef fcol @@ -5093,6 +5222,13 @@ nf: order = 0x4949; if (tag == 0x1d) while ((c = fgetc(ifp)) && c != EOF) serial = serial*10 + (isdigit(c) ? c - '0' : c % 10); + if (tag == 0x29 && type == 1) { + c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0; + fseek (ifp, 8 + c*32, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4(); + } + if (tag == 0x3d && type == 3 && len == 4) + FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_ifd[2].bps); if (tag == 0x81 && type == 4) { data_offset = get4(); fseek (ifp, data_offset + 41, SEEK_SET); @@ -5100,11 +5236,6 @@ nf: order = 0x4949; raw_width = get2(); filters = 0x61616161; } - if (tag == 0x29 && type == 1) { - c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0; - fseek (ifp, 8 + c*32, SEEK_CUR); - FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4(); - } if ((tag == 0x81 && type == 7) || (tag == 0x100 && type == 7) || (tag == 0x280 && type == 1)) { @@ -5220,14 +5351,18 @@ get2_256: fseek (ifp, i, SEEK_CUR); get2_rggb: FORC4 cam_mul[c ^ (c >> 1)] = get2(); - i = len >> 3 == 164 ? 112:22; + i = len >> 3 == 164 || len == 1506 ? 112:22; fseek (ifp, i, SEEK_CUR); FORC4 sraw_mul[c ^ (c >> 1)] = get2(); } + if (tag == 0x4021 && get4() && get4()) + FORC4 cam_mul[c] = 1024; if (tag == 0xa021) FORC4 cam_mul[c ^ (c >> 1)] = get4(); if (tag == 0xa028) FORC4 cam_mul[c ^ (c >> 1)] -= get4(); + if (tag == 0xb001) + unique_id = get2(); next: fseek (ifp, save, SEEK_SET); } @@ -5335,7 +5470,7 @@ void CLASS parse_mos (int offset) { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22", "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65", "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7", - "AFi-II 7","","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5", + "AFi-II 7","Aptus-II 7","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5", "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" }; float romm_cam[3][3]; @@ -5361,12 +5496,12 @@ void CLASS parse_mos (int offset) } if (!strcmp(data,"icc_camera_to_tone_matrix")) { for (i=0; i < 9; i++) - romm_cam[0][i] = int_to_float(get4()); + ((float *)romm_cam)[i] = int_to_float(get4()); romm_coeff (romm_cam); } if (!strcmp(data,"CaptProf_color_matrix")) { for (i=0; i < 9; i++) - fscanf (ifp, "%f", &romm_cam[0][i]); + fscanf (ifp, "%f", (float *)romm_cam + i); romm_coeff (romm_cam); } if (!strcmp(data,"CaptProf_number_of_planes")) @@ -5424,8 +5559,8 @@ void CLASS parse_kodak_ifd (int base) wbi = -2; } if (tag == 2118) wbtemp = getint(type); - if (tag == 2120 + wbi) /* RT: wb tag for DCS760 */ - FORC3 cam_mul[c] = 2048.0 / getreal(type); /* RT: wb tag for DCS760 */ + if (tag == 2120 + wbi && wbi >= 0) + FORC3 cam_mul[c] = 2048.0 / getreal(type); if (tag == 2130 + wbi) FORC3 mul[c] = getreal(type); if (tag == 2140 + wbi && wbi >= 0) @@ -5555,6 +5690,10 @@ int CLASS parse_tiff_ifd (int base) tiff_ifd[ifd].samples = jh.clrs; if (!(jh.sraw || (jh.clrs & 1))) tiff_ifd[ifd].width *= jh.clrs; + if ((tiff_ifd[ifd].width > 4*tiff_ifd[ifd].height) & ~jh.clrs) { + tiff_ifd[ifd].width /= 2; + tiff_ifd[ifd].height *= 2; + } i = order; parse_tiff (tiff_ifd[ifd].offset + 12); order = i; @@ -5662,7 +5801,7 @@ int CLASS parse_tiff_ifd (int base) break; case 33422: /* CFAPattern */ if (filters == 9) { - FORC(36) xtrans[0][c] = fgetc(ifp) & 3; + FORC(36) ((char *)xtrans)[c] = fgetc(ifp) & 3; break; } case 64777: /* Kodak P-series */ @@ -5737,8 +5876,9 @@ int CLASS parse_tiff_ifd (int base) case 40976: strip_offset = get4(); switch (tiff_ifd[ifd].comp) { - case 32770: load_raw = &CLASS samsung_load_raw; break; - case 32772: load_raw = &CLASS samsung2_load_raw; + case 32770: load_raw = &CLASS samsung_load_raw; break; + case 32772: load_raw = &CLASS samsung2_load_raw; break; + case 32773: load_raw = &CLASS samsung3_load_raw; break; } break; case 46275: /* Imacon tags */ @@ -5910,7 +6050,7 @@ guess_cfa_pc: break; case 50830: /* MaskedAreas */ for (i=0; i < len && i < 32; i++) - mask[0][i] = getint(type); + ((int *)mask)[i] = getint(type); black = 0; break; case 51009: /* OpcodeList2 */ @@ -6062,6 +6202,12 @@ void CLASS apply_tiff() load_flags = 1; } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes*2) { load_raw = &CLASS packed_load_raw; + if (model[0] == 'N') load_flags = 80; + } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes) { + load_raw = &CLASS nikon_yuv_load_raw; + gamma_curve (1/2.4, 12.92, 1, 4095); + memset (cblack, 0, sizeof cblack); + filters = 0; } else if (raw_width*raw_height*2 == tiff_ifd[raw].bytes) { load_raw = &CLASS unpacked_load_raw; load_flags = 4; @@ -6434,7 +6580,7 @@ void CLASS parse_phase_one (int base) case 0x100: flip = "0653"[data & 3]-'0'; break; case 0x106: for (i=0; i < 9; i++) - romm_cam[0][i] = getreal(11); + ((float *)romm_cam)[i] = getreal(11); romm_coeff (romm_cam); break; case 0x107: @@ -6562,7 +6708,7 @@ void CLASS parse_riff() end = ftell(ifp) + size; if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) { get4(); - while (ftell(ifp)+7 < end) + while (ftell(ifp)+7 < end && !feof(ifp)) parse_riff(); } else if (!memcmp(tag,"nctg",4)) { while (ftell(ifp)+7 < end) { @@ -6588,6 +6734,26 @@ void CLASS parse_riff() fseek (ifp, size, SEEK_CUR); } +void CLASS parse_qt (int end) +{ + unsigned save, size; + char tag[4]; + + order = 0x4d4d; + while (ftell(ifp)+7 < end) { + save = ftell(ifp); + if ((size = get4()) < 8) return; + fread (tag, 4, 1, ifp); + if (!memcmp(tag,"moov",4) || + !memcmp(tag,"udta",4) || + !memcmp(tag,"CNTH",4)) + parse_qt (save+size); + if (!memcmp(tag,"CNDA",4)) + parse_jpeg (ftell(ifp)); + fseek (ifp, save+size, SEEK_SET); + } +} + void CLASS parse_smal (int offset, int fsize) { int ver; @@ -6757,7 +6923,7 @@ void CLASS parse_foveon() off += pent*8 + 24; if ((unsigned) pent > 256) pent=256; for (i=0; i < pent*2; i++) - poff[0][i] = off + get4()*2; + ((int *)poff)[i] = off + get4()*2; for (i=0; i < pent; i++) { foveon_gets (poff[i][0], name, 64); foveon_gets (poff[i][1], value, 64); @@ -6808,6 +6974,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 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 5DS", 0, 0x3c96, /* DJC */ + { 6885,-753,-856,-4416,11752,2665,-1266,2393,5468 } }, { "Canon EOS 5D Mark III", 0, 0x3c80, { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } }, { "Canon EOS 5D Mark II", 0, 0x3cf0, @@ -6816,6 +6984,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } }, { "Canon EOS 6D", 0, 0x3c82, { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, + { "Canon EOS 7D Mark II", 0, 0x3510, + { 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 } }, { "Canon EOS 7D", 0, 0x3510, { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } }, { "Canon EOS 10D", 0, 0xfa0, @@ -6912,6 +7082,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } }, { "Canon PowerShot G6", 0, 0, { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } }, + { "Canon PowerShot G7 X", 0, 0, + { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, { "Canon PowerShot G9", 0, 0, { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } }, { "Canon PowerShot Pro1", 0, 0, @@ -6946,6 +7118,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } }, { "Canon PowerShot SX50 HS", 0, 0, { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } }, + { "Canon PowerShot SX60 HS", 0, 0, + { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } }, { "Canon PowerShot A3300", 0, 0, /* DJC */ { 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } }, { "Canon PowerShot A470", 0, 0, /* DJC */ @@ -7000,6 +7174,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, { "Fujifilm S100FS", 514, 0, { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } }, + { "Fujifilm S1", 0, 0, + { 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 } }, { "Fujifilm S20Pro", 0, 0, { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, { "Fujifilm S20", 512, 0x3fff, @@ -7050,16 +7226,22 @@ void CLASS adobe_coeff (const char *make, const char *model) { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, { "Fujifilm X100S", 0, 0, { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, + { "Fujifilm X100T", 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 X10", 0, 0, { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, { "Fujifilm X20", 0, 0, { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } }, + { "Fujifilm X30", 0, 0, + { 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } }, { "Fujifilm X-Pro1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, { "Fujifilm X-A1", 0, 0, { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } }, + { "Fujifilm X-A2", 0, 0, + { 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 } }, { "Fujifilm X-E1", 0, 0, { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, { "Fujifilm X-E2", 0, 0, @@ -7072,7 +7254,7 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, { "Fujifilm XF1", 0, 0, { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, - { "Fujifilm XQ1", 0, 0, + { "Fujifilm XQ", 0, 0, // XQ1 and XQ2 { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } }, { "Imacon Ixpress", 0, 0, /* DJC */ { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } }, @@ -7184,7 +7366,7 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } }, { "Nikon D3200", 0, 0xfb9, { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } }, - { "Nikon D3300", 150, 0, + { "Nikon D3300", 0, 0, { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, { "Nikon D300", 0, 0, { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } }, @@ -7198,7 +7380,7 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } }, { "Nikon D40", 0, 0, { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } }, - { "Nikon D4S", 768, 0, + { "Nikon D4S", 0, 0, { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, { "Nikon D4", 0, 0, { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, @@ -7210,8 +7392,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, { "Nikon D5200", 0, 0, { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, - { "Nikon D5300", 600, 0, + { "Nikon D5300", 0, 0, { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, + { "Nikon D5500", 0, 0, + { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } }, { "Nikon D50", 0, 0, { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, { "Nikon D600", 0, 0x3e07, @@ -7224,12 +7408,16 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, { "Nikon D7100", 0, 0, { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, + { "Nikon D7200", 0, 0, /* DJC */ + { 6111,-2759,-358,-5108,10766,4343,-769,1691,8030 } }, + { "Nikon D750", 0, 0, + { 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } }, { "Nikon D700", 0, 0, { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } }, { "Nikon D70", 0, 0, { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, - { "Nikon D810", 596, 0, /* DJC */ - { 6502,-2328,154,-4249,9943,4307,-1303,2538,8108 } }, + { "Nikon D810", 0, 0, + { 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 } }, { "Nikon D800", 0, 0, { 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } }, { "Nikon D80", 0, 0, @@ -7268,7 +7456,7 @@ void CLASS adobe_coeff (const char *make, const char *model) { 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 P330", 0, 0, + { "Nikon COOLPIX P330", 200, 0, { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, { "Nikon COOLPIX P340", 200, 0, { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, @@ -7282,10 +7470,12 @@ void CLASS adobe_coeff (const char *make, const char *model) { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, { "Nikon COOLPIX P7800", 200, 0, { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, - { "Nikon 1 V3", 200, 0, + { "Nikon 1 V3", 0, 0, { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } }, - { "Nikon 1 J4", 200, 0, + { "Nikon 1 J4", 0, 0, { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } }, + { "Nikon 1 J5", 0, 0, /* DJC */ + { 2621,-856,500,-4471,8761,5711,-1321,2644,11945 } }, { "Nikon 1 S2", 200, 0, { 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 } }, { "Nikon 1 V2", 0, 0, @@ -7360,6 +7550,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { "Olympus E-PL6", 0, 0, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-PL7", 0, 0, + { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } }, { "Olympus E-PM1", 0, 0, { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, { "Olympus E-PM2", 0, 0, @@ -7368,6 +7560,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { "Olympus E-M1", 0, 0, { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } }, + { "Olympus E-M5MarkII", 0, 0, + { 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 } }, { "Olympus E-M5", 0, 0xfe1, { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, { "Olympus SP350", 0, 0, @@ -7392,7 +7586,7 @@ void CLASS adobe_coeff (const char *make, const char *model) { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } }, { "Olympus XZ-2", 0, 0, { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, - { "OmniVision ov5647", 0, 0, /* DJC */ + { "OmniVision", 0, 0, /* DJC */ { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, { "Pentax *ist DL2", 0, 0, { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, @@ -7428,8 +7622,12 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } }, { "Pentax K-7", 0, 0, { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } }, + { "Pentax K-S1", 0, 0, + { 8512,-3211,-787,-4167,11966,2487,-638,1288,6054 } }, { "Pentax 645D", 0, 0x3e00, { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } }, + { "Panasonic DMC-CM1", 15, 0, + { 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 } }, { "Panasonic DMC-FZ8", 0, 0xf7f, { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } }, { "Panasonic DMC-FZ18", 0, 0, @@ -7458,6 +7656,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, { "Leica DIGILUX 2", 0, 0, { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, + { "Panasonic DMC-LX100", 15, 0, + { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } }, + { "Leica D-LUX (Typ 109)", 15, 0, + { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } }, { "Panasonic DMC-LF1", 15, 0, { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } }, { "Leica C (Typ 112)", 15, 0, @@ -7482,8 +7684,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } }, { "Leica D-LUX 6", 15, 0, { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } }, - { "Panasonic DMC-FZ1000", 15, 0, /* DJC */ - { 5686,-2219,-68,-4143,9912,4232,-1244,2246,5917 } }, + { "Panasonic DMC-FZ1000", 15, 0, + { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } }, + { "Leica V-LUX (Typ 114)", 15, 0, + { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } }, { "Panasonic DMC-FZ100", 15, 0xfff, { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } }, { "Leica V-LUX 2", 15, 0xfff, @@ -7520,6 +7724,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } }, { "Panasonic DMC-GF6", 15, 0, { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } }, + { "Panasonic DMC-GF7", 15, 0, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, { "Panasonic DMC-GH1", 15, 0xf92, { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } }, { "Panasonic DMC-GH2", 15, 0xf95, @@ -7530,6 +7736,8 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } }, { "Panasonic DMC-GM1", 15, 0, { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } }, + { "Panasonic DMC-GM5", 15, 0, + { 8238,-3244,-679,-3921,11814,2384,-836,2022,5852 } }, { "Panasonic DMC-GX1", 15, 0, { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, { "Panasonic DMC-GX7", 15, 0, @@ -7538,6 +7746,10 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } }, { "Panasonic DMC-ZS4", 15, 0, { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } }, + { "Panasonic DMC-TZ7", 15, 0, + { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } }, + { "Panasonic DMC-ZS5", 15, 0, + { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } }, { "Phase One H 20", 0, 0, /* DJC */ { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } }, { "Phase One H 25", 0, 0, @@ -7562,7 +7774,9 @@ void CLASS adobe_coeff (const char *make, const char *model) { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, { "Samsung NX mini", 0, 0, { 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } }, - { "Samsung NX30", 0, 0, /* NX30, NX300 */ + { "Samsung NX3000", 0, 0, + { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } }, + { "Samsung NX30", 0, 0, /* NX30, NX300, NX300M */ { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, { "Samsung NX2000", 0, 0, { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, @@ -7572,8 +7786,16 @@ void CLASS adobe_coeff (const char *make, const char *model) { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } }, { "Samsung NX1100", 0, 0, { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } }, - { "Samsung NX", 0, 0, /* NX5, NX10, NX11, NX100 */ + { "Samsung NX11", 0, 0, { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, + { "Samsung NX10", 0, 0, /* also NX100 */ + { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, + { "Samsung NX500", 0, 0, /* DJC */ + { 10196,-4532,-272,-3888,11489,2400,-1203,2424,9173 } }, + { "Samsung NX5", 0, 0, + { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, + { "Samsung NX1", 0, 0, + { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } }, { "Samsung WB2000", 0, 0xfff, { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } }, { "Samsung GX-1", 0, 0, @@ -7590,7 +7812,7 @@ void CLASS adobe_coeff (const char *make, const char *model) { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } }, { "Sony DSC-V3", 0, 0, { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } }, - { "Sony DSC-RX100M2", 200, 0, + { "Sony DSC-RX100M", 200, 0, /* M2 and M3 */ { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, { "Sony DSC-RX100", 200, 0, { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } }, @@ -7630,13 +7852,15 @@ void CLASS adobe_coeff (const char *make, const char *model) { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } }, { "Sony ILCA-77M2", 128, 0, { 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } }, + { "Sony ILCE-7M2", 128, 0, + { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, { "Sony ILCE-7S", 128, 0, { 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } }, { "Sony ILCE-7R", 128, 0, { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } }, { "Sony ILCE-7", 128, 0, { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, - { "Sony ILCE", 128, 0, /* 3000, 5000, and 6000 */ + { "Sony ILCE", 128, 0, /* 3000, 5000, 5100, 6000, and QX1 */ { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, { "Sony NEX-5N", 128, 0, { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, @@ -7690,7 +7914,7 @@ void CLASS adobe_coeff (const char *make, const char *model) if (table[i].maximum) maximum = (ushort) table[i].maximum; if (table[i].trans[0]) { for (raw_color = j=0; j < 12; j++) - cam_xyz[0][j] = table[i].trans[j] / 10000.0; + ((double *)cam_xyz)[j] = table[i].trans[j] / 10000.0; cam_xyz_coeff (rgb_cam, cam_xyz); } break; @@ -7710,7 +7934,7 @@ void CLASS adobe_coeff (const char *make, const char *model) } if (trans[0]) { for (j=0; j < 12; j++) { - cam_xyz[0][j] = trans[j] / 10000.0; + ((double *)cam_xyz)[j] = trans[j] / 10000.0; } cam_xyz_coeff (rgb_cam,cam_xyz); } @@ -7840,6 +8064,7 @@ void CLASS identify() { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 }, { 4480, 3366, 80, 50, 0, 0 }, { 4496, 3366, 80, 50, 12, 0 }, + { 4768, 3516, 96, 16, 0, 0, 0, 16 }, { 4832, 3204, 62, 26, 0, 0 }, { 4832, 3228, 62, 51, 0, 0 }, { 5108, 3349, 98, 13, 0, 0 }, @@ -7849,9 +8074,11 @@ void CLASS identify() { 5344, 3584, 126,100, 0, 2 }, { 5360, 3516, 158, 51, 0, 0 }, { 5568, 3708, 72, 38, 0, 0 }, + { 5632, 3710, 96, 17, 0, 0, 0, 16, 0, 0, 0x49 }, { 5712, 3774, 62, 20, 10, 2 }, { 5792, 3804, 158, 51, 0, 0 }, { 5920, 3950, 122, 80, 2, 0 }, + { 8896, 5920, 160, 64, 0, 0 }, }; static const struct { ushort id; @@ -7877,6 +8104,33 @@ void CLASS identify() { 0x288, "EOS 1100D" }, { 0x327, "EOS 1200D" }, { 0x346, "EOS 100D" }, + }, sonique[] = { + { 0x002, "DSC-R1" }, { 0x100, "DSLR-A100" }, + { 0x101, "DSLR-A900" }, { 0x102, "DSLR-A700" }, + { 0x103, "DSLR-A200" }, { 0x104, "DSLR-A350" }, + { 0x105, "DSLR-A300" }, { 0x108, "DSLR-A330" }, + { 0x109, "DSLR-A230" }, { 0x10a, "DSLR-A290" }, + { 0x10d, "DSLR-A850" }, { 0x111, "DSLR-A550" }, + { 0x112, "DSLR-A500" }, { 0x113, "DSLR-A450" }, + { 0x116, "NEX-5" }, { 0x117, "NEX-3" }, + { 0x118, "SLT-A33" }, { 0x119, "SLT-A55V" }, + { 0x11a, "DSLR-A560" }, { 0x11b, "DSLR-A580" }, + { 0x11c, "NEX-C3" }, { 0x11d, "SLT-A35" }, + { 0x11e, "SLT-A65V" }, { 0x11f, "SLT-A77V" }, + { 0x120, "NEX-5N" }, { 0x121, "NEX-7" }, + { 0x123, "SLT-A37" }, { 0x124, "SLT-A57" }, + { 0x125, "NEX-F3" }, { 0x126, "SLT-A99V" }, + { 0x127, "NEX-6" }, { 0x128, "NEX-5R" }, + { 0x129, "DSC-RX100" }, { 0x12a, "DSC-RX1" }, + { 0x12e, "ILCE-3000" }, { 0x12f, "SLT-A58" }, + { 0x131, "NEX-3N" }, { 0x132, "ILCE-7" }, + { 0x133, "NEX-5T" }, { 0x134, "DSC-RX100M2" }, + { 0x135, "DSC-RX10" }, { 0x136, "DSC-RX1R" }, + { 0x137, "ILCE-7R" }, { 0x138, "ILCE-6000" }, + { 0x139, "ILCE-5000" }, { 0x13d, "DSC-RX100M3" }, + { 0x13e, "ILCE-7S" }, { 0x13f, "ILCA-77M2" }, + { 0x153, "ILCE-5100" }, { 0x154, "ILCE-7M2" }, + { 0x15a, "ILCE-QX1" }, }; static const struct { unsigned fsize; @@ -7944,6 +8198,8 @@ void CLASS identify() { 1652736,1536,1076, 0,52, 0, 0, 0,0x61,0,0,"Kodak","DCS200" }, { 4159302,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330" }, { 4162462,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330",3160 }, + { 2247168,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" }, + { 3370752,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" }, { 6163328,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603" }, { 6166488,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603",3160 }, { 460800, 640, 480, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" }, @@ -7952,6 +8208,7 @@ void CLASS identify() { 12272756,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP",31556 }, { 18000000,4000,3000, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","12MP" }, { 614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" }, + { 15360000,3200,2400, 0, 0, 0, 0,96,0x16,0,0,"Lenovo","A820" }, { 3884928,1608,1207, 0, 0, 0, 0,96,0x16,0,0,"Micron","2010",3212 }, { 1138688,1534, 986, 0, 0, 0, 0, 0,0x61,0,0,"Minolta","RD175",513 }, { 1581060,1305, 969, 0, 0,18, 6, 6,0x1e,4,1,"Nikon","E900" }, @@ -8089,6 +8346,10 @@ void CLASS identify() } else if (!memcmp (head,"RIFF",4)) { fseek (ifp, 0, SEEK_SET); parse_riff(); + } else if (!memcmp (head+4,"ftypqt ",9)) { + fseek (ifp, 0, SEEK_SET); + parse_qt (fsize); + is_raw = 0; } else if (!memcmp (head,"\0\001\0\001\0@",6)) { fseek (ifp, 6, SEEK_SET); fread (make, 1, 8, ifp); @@ -8194,18 +8455,18 @@ void CLASS identify() if (make[0] == 0) parse_smal (0, flen); if (make[0] == 0) { parse_jpeg(0); - //RT fix for the use of fseek below - if (!strncmp(model,"ov",2)) { + //RT fix for the use of fseek below + if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5))) { 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; - } + 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++) @@ -8284,8 +8545,14 @@ void CLASS identify() } } for (i=0; i < sizeof unique / sizeof *unique; i++) - if (unique_id == 0x80000000 + unique[i].id) + if (unique_id == 0x80000000 + unique[i].id) { adobe_coeff ("Canon", unique[i].model); + if (model[4] == 'K' && strlen(model) == 8) + strcpy (model, unique[i].model); + } + for (i=0; i < sizeof sonique / sizeof *sonique; i++) + if (unique_id == sonique[i].id) + strcpy (model, sonique[i].model); if (!strcmp(make,"Nikon")) { if (!load_raw) load_raw = &CLASS packed_load_raw; @@ -8312,7 +8579,10 @@ void CLASS identify() case 3344: width -= 66; case 3872: width -= 6; } - if (height > width) SWAP(height,width); + if (height > width) { + SWAP(height,width); + SWAP(raw_height,raw_width); + } filters = 0; tiff_samples = colors = 3; load_raw = &CLASS canon_sraw_load_raw; @@ -8385,8 +8655,8 @@ canon_a5: !strcmp(model,"COOLPIX A")) { width -= 44; } else if (!strcmp(model,"D3200") || - !strcmp(model,"D600") || - !strcmp(model,"D800") || !strcmp(model,"D800E") ) { + !strncmp(model,"D6",2) || + !strncmp(model,"D800",4)) { width -= 46; } else if (!strcmp(model,"D4") || !strcmp(model,"Df")) { @@ -8411,9 +8681,7 @@ canon_a5: else width -= 8; } else if (!strncmp(model,"D300",4)) { width -= 32; - } else if (!strcmp(make,"Nikon") && raw_width == 4032) { - adobe_coeff ("Nikon","COOLPIX P7700"); - } else if (!strncmp(model,"COOLPIX P",9)) { + } else if (!strncmp(model,"COOLPIX P",9) && raw_width != 4032) { load_flags = 24; filters = 0x94949494; if (model[9] == '7' && iso_speed >= 400) @@ -8501,7 +8769,7 @@ canon_a5: } if (fuji_layout) raw_width *= is_raw; if (filters == 9) - FORC(36) xtrans[0][c] = + FORC(36) ((char *)xtrans)[c] = xtrans_abs[(c/6+top_margin) % 6][(c+left_margin) % 6]; } else if (!strcmp(model,"KD-400Z")) { height = 1712; @@ -8554,8 +8822,10 @@ konica_400z: width -= 2 * (left_margin = 8); load_flags = 32; } else if (!strcmp(make,"Samsung") && raw_height == 3714) { - height -= 18; - width = 5536; + height -= top_margin = 18; + left_margin = raw_width - (width = 5536); + if (raw_width != 5600) + left_margin = top_margin = 0; filters = 0x61616161; colors = 3; } else if (!strcmp(make,"Samsung") && raw_width == 5632) { @@ -8569,6 +8839,9 @@ konica_400z: left_margin = 96; width = 5544; filters = 0x49494949; + } else if (!strcmp(make,"Samsung") && raw_width == 6496) { + filters = 0x61616161; + black = 1 << (tiff_bps - 7); } else if (!strcmp(model,"EX1")) { order = 0x4949; height -= 20; @@ -8659,8 +8932,13 @@ konica_400z: width -= (left_margin = 3) + 7; filters = 0x61616161; } + if (tiff_samples > 1) { + is_raw = tiff_samples+1; + if (!shot_select && !half_size) filters = 0; + } } else if (!strcmp(make,"Sinar")) { if (!load_raw) load_raw = &CLASS unpacked_load_raw; + if (is_raw > 1 && !shot_select && !half_size) filters = 0; maximum = 0x3fff; } else if (!strcmp(make,"Leaf")) { maximum = 0x3fff; @@ -8735,6 +9013,7 @@ konica_400z: if (exif_cfa) filters = exif_cfa; if (width == 4100) width -= 4; if (width == 4080) width -= 24; + if (width == 9280) { width -= 6; height -= 6; } if (load_raw == &CLASS unpacked_load_raw) load_flags = 4; tiff_bps = 12; @@ -8776,7 +9055,6 @@ konica_400z: data_offset = 787392; load_raw = &CLASS sony_load_raw; } else if (!strcmp(make,"Sony") && raw_width == 3984) { - adobe_coeff ("Sony","DSC-R1"); width = 3925; order = 0x4d4d; } else if (!strcmp(make,"Sony") && raw_width == 4288) { @@ -8815,40 +9093,28 @@ konica_400z: fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET); read_shorts (curve, 256); } else gamma_curve (0, 3.875, 1, 255); - load_raw = filters ? &CLASS eight_bit_load_raw - : &CLASS kodak_yrgb_load_raw; + load_raw = filters ? &CLASS eight_bit_load_raw : + strcmp(model,"C330") ? &CLASS kodak_c603_load_raw : + &CLASS kodak_c330_load_raw; + load_flags = tiff_bps > 16; + tiff_bps = 8; } else if (!strncasecmp(model,"EasyShare",9)) { data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000; load_raw = &CLASS packed_load_raw; } else if (!strcasecmp(make,"Kodak")) { if (filters == UINT_MAX) filters = 0x61616161; - if (!strncmp(model,"NC2000",6)) { + if (!strncmp(model,"NC2000",6) || + !strncmp(model,"EOSDCS",6) || + !strncmp(model,"DCS4",4)) { width -= 4; left_margin = 2; - } else if (!strcmp(model,"EOSDCS3B")) { - width -= 4; - left_margin = 2; - } else if (!strcmp(model,"EOSDCS1")) { - width -= 4; - left_margin = 2; - } else if (!strcmp(model,"DCS420")) { - width -= 4; - left_margin = 2; - } else if (!strncmp(model,"DCS460 ",7)) { - model[6] = 0; - width -= 4; - left_margin = 2; - } else if (!strcmp(model,"DCS460A")) { - width -= 4; - left_margin = 2; - colors = 1; - filters = 0; + if (model[6] == ' ') model[6] = 0; + if (!strcmp(model,"DCS460A")) goto bw; } else if (!strcmp(model,"DCS660M")) { black = 214; - colors = 1; - filters = 0; + goto bw; } else if (!strcmp(model,"DCS760M")) { - colors = 1; +bw: colors = 1; filters = 0; } if (!strcmp(model+4,"20X")) @@ -8977,7 +9243,7 @@ dng_skip: if (!tiff_bps) tiff_bps = 12; if (!maximum) maximum = (1 << tiff_bps) - 1; if (!load_raw || height < 22 || width < 22 || - tiff_samples > 4 || colors > 4) + tiff_bps > 16 || tiff_samples > 6 || colors > 4) is_raw = 0; #ifdef NO_JASPER if (load_raw == &CLASS redcine_load_raw) { @@ -9080,7 +9346,7 @@ static void decodeFPDeltaRow(Bytef * src, Bytef * dst, size_t tileWidth, size_t for (size_t col = 0; col < tileWidth; ++col) { for (size_t byte = 0; byte < bytesps; ++byte) dst[col*bytesps + byte] = src[col + realTileWidth*(bytesps-byte-1)]; // Little endian - } + } } else { for (size_t col = 0; col < tileWidth; ++col) { for (size_t byte = 0; byte < bytesps; ++byte) @@ -9088,7 +9354,7 @@ static void decodeFPDeltaRow(Bytef * src, Bytef * dst, size_t tileWidth, size_t } } } - + } // From DNG SDK dng_utils.h @@ -9287,12 +9553,12 @@ void CLASS deflate_dng_load_raw() { } } } - + delete [] cBuffer; delete [] uBuffer; } } - + if (ifd->sample_format == 3) { // Floating point data copyFloatDataToInt(float_raw_image, raw_image, raw_width*raw_height, maximum); } @@ -9321,6 +9587,7 @@ struct tiff_hdr { 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 @@ -9329,4 +9596,3 @@ struct tiff_hdr { /*RT*/#undef LIM /*RT*/#undef ULIM /*RT*/#undef CLIP - diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h index 804cfc49c..3317a68bf 100644 --- a/rtengine/dcraw.h +++ b/rtengine/dcraw.h @@ -91,9 +91,9 @@ protected: unsigned tile_width, tile_length, gpsdata[32], load_flags; ushort raw_height, raw_width, height, width, top_margin, left_margin; ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height; - ushort *raw_image; + ushort *raw_image; float * float_raw_image; - ushort white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4]; + ushort white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4]; int mask[8][4], flip, tiff_flip, colors; double pixel_aspect; double aber[4]; @@ -130,9 +130,9 @@ protected: } tiff_ifd[10]; struct ph1 { - int format, key_off, tag_21a; - int black, split_col, black_col, split_row, black_row; - float tag_210; + int format, key_off, tag_21a; + int black, split_col, black_col, split_row, black_row; + float tag_210; } ph1; struct hbd { off_t levels, unknown1, flatfield; @@ -239,6 +239,11 @@ int raw (unsigned row, unsigned col); void phase_one_flat_field (int is_float, int nc); void phase_one_correct(); void phase_one_load_raw(); +void nikon_yuv_load_raw(); +void kodak_c330_load_raw(); +void kodak_c603_load_raw(); +void samsung3_load_raw(); +void parse_qt (int end); // ph1_bithuff(int nbits, ushort *huff); class ph1_bithuff_t { diff --git a/rtengine/dcraw.patch b/rtengine/dcraw.patch index e322f28fe..ecf31033d 100755 --- a/rtengine/dcraw.patch +++ b/rtengine/dcraw.patch @@ -1,5 +1,5 @@ ---- dcraw.c 2015-04-17 13:02:57 +0000 -+++ dcraw.cc 2015-04-17 13:09:41 +0000 +--- dcraw.c 2015-04-28 15:32:57.638976274 +0200 ++++ dcraw.cc 2015-04-28 15:32:57.665976273 +0200 @@ -1,3 +1,15 @@ +/*RT*/#include +/*RT*/#include @@ -15,7 +15,7 @@ + /* dcraw.c -- Dave Coffin's raw photo decoder - Copyright 1997-2014 by Dave Coffin, dcoffin a cybercom o net + Copyright 1997-2015 by Dave Coffin, dcoffin a cybercom o net @@ -29,17 +41,17 @@ #define _GNU_SOURCE #endif @@ -62,11 +62,10 @@ -#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 @@ -196,7 +195,7 @@ unsigned c; if (nbits > 25) return 0; -@@ -1265,14 +1228,14 @@ +@@ -1284,14 +1247,14 @@ int i, nz; char tail[424]; @@ -213,25 +212,7 @@ void CLASS ppm_thumb() { -@@ -1516,14 +1479,15 @@ - } - for (qr = 0; qr < 2; qr++) { - for (qc = 0; qc < 2; qc++) { -- int cx[18], cf[18]; -+ int cx[19], cf[19]; - for (i = 0; i < 16; i++) { - cx[1+i] = lc[qr][qc][i]; - cf[1+i] = ref[i]; - } - cx[0] = cf[0] = 0; - cx[17] = cf[17] = ((unsigned int)ref[15] * 65535) / lc[qr][qc][15]; -- cubic_spline(cx, cf, 18); -+ cx[18] = cf[18] = 65535; -+ cubic_spline(cx, cf, 19); - - for (row = (qr ? ph1.split_row : 0); - row < (qr ? raw_height : ph1.split_row); row++) -@@ -1634,10 +1598,10 @@ +@@ -1653,10 +1616,10 @@ } } @@ -245,7 +226,7 @@ unsigned c; if (nbits == -1) -@@ -1712,6 +1676,336 @@ +@@ -1731,6 +1694,336 @@ maximum = 0xfffc - ph1.black; } @@ -582,7 +563,7 @@ void CLASS hasselblad_load_raw() { struct jhead jh; -@@ -1903,10 +2197,10 @@ +@@ -1954,10 +2247,10 @@ maximum = curve[0x3ff]; } @@ -596,7 +577,7 @@ int byte; if (!nbits) return vbits=0; -@@ -2195,11 +2489,11 @@ +@@ -2246,11 +2539,11 @@ METHODDEF(boolean) fill_input_buffer (j_decompress_ptr cinfo) { @@ -610,7 +591,7 @@ cinfo->src->next_input_byte = jpeg_buffer; cinfo->src->bytes_in_buffer = nbytes; return TRUE; -@@ -2524,10 +2818,9 @@ +@@ -2600,10 +2893,9 @@ maximum = (1 << (thumb_misc & 31)) - 1; } @@ -623,7 +604,7 @@ if (start) { for (p=0; p < 4; p++) pad[p] = key = key * 48828125 + 1; -@@ -2612,11 +2905,13 @@ +@@ -2688,11 +2980,13 @@ bit += 7; } for (i=0; i < 16; i++, col+=2) @@ -638,7 +619,7 @@ } void CLASS samsung_load_raw() -@@ -2863,7 +3158,7 @@ +@@ -2988,7 +3282,7 @@ void CLASS foveon_decoder (unsigned size, unsigned code) { @@ -647,7 +628,7 @@ struct decode *cur; int i, len; -@@ -2960,7 +3255,7 @@ +@@ -3085,7 +3379,7 @@ pred[c] += diff[dindex->leaf]; if (pred[c] >> 16 && ~pred[c] >> 16) derror(); } @@ -656,7 +637,7 @@ } } } -@@ -3571,6 +3866,8 @@ +@@ -3696,6 +3990,8 @@ if (load_raw == &CLASS phase_one_load_raw || load_raw == &CLASS phase_one_load_raw_c) phase_one_correct(); @@ -665,7 +646,7 @@ if (fuji_width) { for (row=0; row < raw_height-top_margin*2; row++) { for (col=0; col < fuji_width << !fuji_layout; col++) { -@@ -3586,10 +3883,13 @@ +@@ -3711,10 +4007,13 @@ } } } else { @@ -681,7 +662,7 @@ if (mask[0][3] > 0) goto mask_set; if (load_raw == &CLASS canon_load_raw || load_raw == &CLASS lossless_jpeg_load_raw) { -@@ -4191,239 +4491,8 @@ +@@ -4316,239 +4615,8 @@ } } @@ -730,8 +711,7 @@ - -/* - This algorithm is officially called: -+/* RT: delete interpolation functions */ - +- - "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 @@ -874,7 +854,8 @@ - int dir[5] = { 1, width, -1, -width, 1 }; - int row, col, diff[2], guess[2], c, d, i; - ushort (*pix)[4]; -- ++/* RT: delete interpolation functions */ + - border_interpolate(3); - if (verbose) fprintf (stderr,_("PPG interpolation...\n")); - @@ -922,7 +903,7 @@ void CLASS cielab (ushort rgb[3], short lab[3]) { -@@ -4684,112 +4753,7 @@ +@@ -4814,112 +4882,7 @@ } #undef fcol @@ -948,10 +929,10 @@ - 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); @@ -1035,7 +1016,7 @@ #undef TS void CLASS median_filter() -@@ -4959,7 +4923,7 @@ +@@ -5089,7 +5052,7 @@ } } @@ -1044,7 +1025,7 @@ void CLASS parse_makernote (int base, int uptag) { -@@ -5116,12 +5080,16 @@ +@@ -5246,12 +5209,16 @@ cam_mul[2] = get4() << 2; } } @@ -1062,25 +1043,7 @@ if (tag == 0x1d) while ((c = fgetc(ifp)) && c != EOF) serial = serial*10 + (isdigit(c) ? c - '0' : c % 10); -@@ -5367,7 +5335,7 @@ - { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22", - "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65", - "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7", -- "Aptus-II 7","","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5", -+ "AFi-II 7","","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5", - "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" }; - float romm_cam[3][3]; - -@@ -5456,6 +5424,8 @@ - wbi = -2; - } - if (tag == 2118) wbtemp = getint(type); -+ if (tag == 2120 + wbi) /* RT: wb tag for DCS760 */ -+ FORC3 cam_mul[c] = 2048.0 / getreal(type); /* RT: wb tag for DCS760 */ - if (tag == 2130 + wbi) - FORC3 mul[c] = getreal(type); - if (tag == 2140 + wbi && wbi >= 0) -@@ -5475,8 +5445,8 @@ +@@ -5613,8 +5580,8 @@ } } @@ -1091,7 +1054,7 @@ int CLASS parse_tiff_ifd (int base) { -@@ -5489,7 +5459,7 @@ +@@ -5627,7 +5594,7 @@ unsigned sony_curve[] = { 0,0,0,0,0,4095 }; unsigned *buf, sony_offset=0, sony_length=0, sony_key=0; struct jhead jh; @@ -1100,7 +1063,7 @@ if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0]) return 1; -@@ -5564,7 +5534,8 @@ +@@ -5702,7 +5669,8 @@ fgets (make, 64, ifp); break; case 272: /* Model */ @@ -1110,7 +1073,7 @@ break; case 280: /* Panasonic RW2 offset */ if (type != 4) break; -@@ -5620,6 +5591,9 @@ +@@ -5762,6 +5730,9 @@ case 315: /* Artist */ fread (artist, 64, 1, ifp); break; @@ -1120,7 +1083,7 @@ case 322: /* TileWidth */ tiff_ifd[ifd].tile_width = getint(type); break; -@@ -5635,6 +5609,9 @@ +@@ -5777,6 +5748,9 @@ is_raw = 5; } break; @@ -1130,7 +1093,7 @@ case 330: /* SubIFDs */ if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) { load_raw = &CLASS sony_arw_load_raw; -@@ -5648,6 +5625,9 @@ +@@ -5790,6 +5764,9 @@ fseek (ifp, i+4, SEEK_SET); } break; @@ -1140,7 +1103,7 @@ case 400: strcpy (make, "Sarnoff"); maximum = 0xfff; -@@ -5828,6 +5808,9 @@ +@@ -5971,6 +5948,9 @@ if (!make[0]) strcpy (make, "DNG"); is_raw = 1; break; @@ -1150,10 +1113,12 @@ case 50710: /* CFAPlaneColor */ if (filters == 9) break; if (len > 4) len = 4; -@@ -5859,10 +5842,21 @@ +@@ -6002,12 +5982,21 @@ case 61450: cblack[4] = cblack[5] = MIN(sqrt(len),64); case 50714: /* BlackLevel */ +- if (!(cblack[4] * cblack[5])) +- cblack[4] = cblack[5] = 1; - FORC (cblack[4] * cblack[5]) - cblack[6+c] = getreal(type); - black = 0; @@ -1176,7 +1141,7 @@ case 50715: /* BlackLevelDeltaH */ case 50716: /* BlackLevelDeltaV */ for (num=i=0; i < len; i++) -@@ -5940,12 +5934,15 @@ +@@ -6085,12 +6074,15 @@ fread (buf, sony_length, 1, ifp); sony_decrypt (buf, sony_length/4, 1, sony_key); sfp = ifp; @@ -1198,7 +1163,7 @@ ifp = sfp; free (buf); } -@@ -5969,6 +5966,7 @@ +@@ -6114,6 +6106,7 @@ int CLASS parse_tiff (int base) { int doff; @@ -1206,7 +1171,7 @@ fseek (ifp, base, SEEK_SET); order = get2(); -@@ -6046,7 +6044,7 @@ +@@ -6191,7 +6184,7 @@ case 8: load_raw = &CLASS eight_bit_load_raw; break; case 12: if (tiff_ifd[raw].phint == 2) load_flags = 6; @@ -1215,7 +1180,7 @@ case 14: load_flags = 0; case 16: load_raw = &CLASS unpacked_load_raw; if (!strncmp(make,"OLYMPUS",7) && -@@ -6079,6 +6077,7 @@ +@@ -6230,6 +6223,7 @@ case 32803: load_raw = &CLASS kodak_65000_load_raw; } case 32867: case 34892: break; @@ -1223,7 +1188,7 @@ default: is_raw = 0; } if (!dng_version) -@@ -6164,7 +6163,7 @@ +@@ -6315,7 +6309,7 @@ { const char *file, *ext; char *jname, *jfile, *jext; @@ -1232,7 +1197,7 @@ ext = strrchr (ifname, '.'); file = strrchr (ifname, '/'); -@@ -6186,13 +6185,14 @@ +@@ -6337,13 +6331,14 @@ } else while (isdigit(*--jext)) { if (*jext != '9') { @@ -1249,7 +1214,7 @@ if (verbose) fprintf (stderr,_("Reading metadata from %s ...\n"), jname); parse_tiff (12); -@@ -6537,7 +6537,11 @@ +@@ -6688,7 +6683,11 @@ order = get2(); hlen = get4(); if (get4() == 0x48454150) /* "HEAP" */ @@ -1261,7 +1226,7 @@ if (parse_tiff (save+6)) apply_tiff(); fseek (ifp, save+len, SEEK_SET); } -@@ -6789,7 +6793,8 @@ +@@ -6960,7 +6959,8 @@ { static const struct { const char *prefix; @@ -1271,7 +1236,7 @@ } table[] = { { "AgfaPhoto DC-833m", 0, 0, /* DJC */ { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } }, -@@ -7690,6 +7695,27 @@ +@@ -7919,6 +7919,27 @@ } break; } @@ -1290,7 +1255,7 @@ + } + if (trans[0]) { + for (j=0; j < 12; j++) { -+ cam_xyz[0][j] = trans[j] / 10000.0; ++ ((double *)cam_xyz)[j] = trans[j] / 10000.0; + } + cam_xyz_coeff (rgb_cam,cam_xyz); + } @@ -1299,7 +1264,7 @@ } void CLASS simple_coeff (int index) -@@ -7967,7 +7993,7 @@ +@@ -8229,7 +8250,7 @@ tiff_flip = flip = filters = UINT_MAX; /* unknown */ raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0; maximum = height = width = top_margin = left_margin = 0; @@ -1308,7 +1273,7 @@ iso_speed = shutter = aperture = focal_len = unique_id = 0; tiff_nifds = 0; memset (tiff_ifd, 0, sizeof tiff_ifd); -@@ -7999,13 +8025,20 @@ +@@ -8261,13 +8282,20 @@ fread (head, 1, 32, ifp); fseek (ifp, 0, SEEK_END); flen = fsize = ftell(ifp); @@ -1331,7 +1296,7 @@ parse_ciff (hlen, flen-hlen, 0); load_raw = &CLASS canon_load_raw; } else if (parse_tiff(0)) apply_tiff(); -@@ -8051,6 +8084,7 @@ +@@ -8313,6 +8341,7 @@ fseek (ifp, 100+28*(shot_select > 0), SEEK_SET); parse_tiff (data_offset = get4()); parse_tiff (thumb_offset+12); @@ -1339,35 +1304,29 @@ apply_tiff(); } else if (!memcmp (head,"RIFF",4)) { fseek (ifp, 0, SEEK_SET); -@@ -8160,15 +8194,18 @@ +@@ -8426,9 +8455,10 @@ 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) && +- if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5)) && +- !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)) { ++ //RT fix for the use of fseek below ++ if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5))) { + 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; -+ } + strcpy (make, "OmniVision"); + data_offset = ftell(ifp) + 0x8000-32; + width = raw_width; +@@ -8437,6 +8467,7 @@ + filters = 0x16161616; + } else is_raw = 0; } ++ } for (i=0; i < sizeof corp / sizeof *corp; i++) -@@ -8201,7 +8238,7 @@ + if (strcasestr (make, corp[i])) /* Simplify company names */ +@@ -8468,7 +8499,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"))) @@ -1376,7 +1335,7 @@ if (width >= 4960 && !strncmp(model,"K-5",3)) { left_margin = 10; width = 4950; filters = 0x16161616; } if (width == 4736 && !strcmp(model,"K-7")) -@@ -8220,6 +8257,7 @@ +@@ -8487,6 +8518,7 @@ switch (tiff_compress) { case 1: load_raw = &CLASS packed_dng_load_raw; break; case 7: load_raw = &CLASS lossless_dng_load_raw; break; @@ -1384,7 +1343,7 @@ case 34892: load_raw = &CLASS lossy_dng_load_raw; break; default: load_raw = 0; } -@@ -8268,6 +8306,7 @@ +@@ -8541,6 +8573,7 @@ if (height > width) pixel_aspect = 2; filters = 0; simple_coeff(0); @@ -1392,16 +1351,7 @@ } else if (!strcmp(make,"Canon") && tiff_bps == 15) { switch (width) { case 3344: width -= 66; -@@ -8347,7 +8386,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") || - !strcmp(model,"Df")) { -@@ -8567,24 +8606,53 @@ +@@ -8846,24 +8879,53 @@ if (load_raw == &CLASS lossless_jpeg_load_raw) load_raw = &CLASS hasselblad_load_raw; if (raw_width == 7262) { @@ -1411,10 +1361,13 @@ top_margin = 4; left_margin = 7; filters = 0x61616161; - } else if (raw_width == 7410) { +- } else if (raw_width == 7410 || raw_width == 8282) { +- height -= 84; +- width -= 82; ++ } else if (raw_width == 7410) { + if (!strcmp(model, "H4D")) strcpy(model, "H4D-40"); // RT - height = 5502; - width = 7328; ++ height = 5502; ++ width = 7328; top_margin = 4; left_margin = 41; filters = 0x61616161; @@ -1457,7 +1410,7 @@ } else if (raw_width == 4090) { strcpy (model, "V96C"); height -= (top_margin = 6); -@@ -8637,6 +8705,7 @@ +@@ -8921,6 +8983,7 @@ filters = 0x16161616; } } else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) { @@ -1465,7 +1418,7 @@ if ((flen - data_offset) / (raw_width*8/7) == raw_height) load_raw = &CLASS panasonic_load_raw; if (!load_raw) { -@@ -8654,6 +8723,7 @@ +@@ -8938,6 +9001,7 @@ } filters = 0x01010101 * (uchar) "\x94\x61\x49\x16" [((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3]; @@ -1473,7 +1426,7 @@ } else if (!strcmp(model,"C770UZ")) { height = 1718; width = 2304; -@@ -8883,6 +8953,14 @@ +@@ -9155,6 +9219,14 @@ memcpy (rgb_cam, cmatrix, sizeof cmatrix); raw_color = 0; } @@ -1488,16 +1441,7 @@ if (raw_color) adobe_coeff (make, model); if (load_raw == &CLASS kodak_radc_load_raw) if (raw_color) adobe_coeff ("Apple","Quicktake"); -@@ -8899,7 +8977,7 @@ - if (!tiff_bps) tiff_bps = 12; - if (!maximum) maximum = (1 << tiff_bps) - 1; - if (!load_raw || height < 22 || width < 22 || -- tiff_bps > 16 || tiff_samples > 4 || colors > 4) -+ tiff_samples > 4 || colors > 4) - is_raw = 0; - #ifdef NO_JASPER - if (load_raw == &CLASS redcine_load_raw) { -@@ -8978,195 +9056,250 @@ +@@ -9250,194 +9322,249 @@ } #endif @@ -1582,11 +1526,77 @@ - 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]; -- } ++/* RT: DNG Float */ ++ ++#include ++#include ++ ++static void decodeFPDeltaRow(Bytef * src, Bytef * dst, size_t tileWidth, size_t realTileWidth, int bytesps, int factor) { ++ // DecodeDeltaBytes ++ for (size_t col = factor; col < realTileWidth*bytesps; ++col) { ++ src[col] += src[col - factor]; ++ } ++ // Reorder bytes into the image ++ // 16 and 32-bit versions depend on local architecture, 24-bit does not ++ if (bytesps == 3) { ++ for (size_t col = 0; col < tileWidth; ++col) { ++ dst[col*3] = src[col]; ++ dst[col*3 + 1] = src[col + realTileWidth]; ++ dst[col*3 + 2] = src[col + realTileWidth*2]; ++ } ++ } else { ++ union X { uint32_t x; uint8_t c; }; ++ if (((union X){1}).c) { ++ for (size_t col = 0; col < tileWidth; ++col) { ++ for (size_t byte = 0; byte < bytesps; ++byte) ++ dst[col*bytesps + byte] = src[col + realTileWidth*(bytesps-byte-1)]; // Little endian ++ } ++ } else { ++ for (size_t col = 0; col < tileWidth; ++col) { ++ for (size_t byte = 0; byte < bytesps; ++byte) ++ dst[col*bytesps + byte] = src[col + realTileWidth*byte]; ++ } ++ } ++ } ++ ++} ++ ++// From DNG SDK dng_utils.h ++static inline uint32_t DNG_HalfToFloat(uint16_t halfValue) { ++ int32_t sign = (halfValue >> 15) & 0x00000001; ++ int32_t exponent = (halfValue >> 10) & 0x0000001f; ++ int32_t mantissa = halfValue & 0x000003ff; ++ if (exponent == 0) { ++ if (mantissa == 0) { ++ // Plus or minus zero ++ return (uint32_t) (sign << 31); ++ } else { ++ // Denormalized number -- renormalize it ++ while (!(mantissa & 0x00000400)) { ++ mantissa <<= 1; ++ exponent -= 1; ++ } ++ exponent += 1; ++ mantissa &= ~0x00000400; ++ } ++ } else if (exponent == 31) { ++ if (mantissa == 0) { ++ // Positive or negative infinity, convert to maximum (16 bit) values. ++ return (uint32_t) ((sign << 31) | ((0x1eL + 127 - 15) << 23) | (0x3ffL << 13)); ++ } else { ++ // Nan -- Just set to zero. ++ return 0; ++ } + } - if (verbose) - fprintf (stderr, raw_color ? _("Building histograms...\n") : - _("Converting to %s colorspace...\n"), name[output_color-1]); -+/* RT: DNG Float */ ++ // Normalized number ++ exponent += (127 - 15); ++ mantissa <<= 13; ++ // Assemble sign, exponent and mantissa. ++ return (uint32_t) ((sign << 31) | (exponent << 23) | mantissa); ++} - memset (histogram, 0, sizeof histogram); - for (img=image[0], row=0; row < height; row++) @@ -1615,117 +1625,6 @@ - float r, c, fr, fc; - unsigned ur, uc; - ushort wide, high, (*img)[4], (*pix)[4]; -+#include -+#include - -- 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; -+static void decodeFPDeltaRow(Bytef * src, Bytef * dst, size_t tileWidth, size_t realTileWidth, int bytesps, int factor) { -+ // DecodeDeltaBytes -+ for (size_t col = factor; col < realTileWidth*bytesps; ++col) { -+ src[col] += src[col - factor]; -+ } -+ // Reorder bytes into the image -+ // 16 and 32-bit versions depend on local architecture, 24-bit does not -+ if (bytesps == 3) { -+ for (size_t col = 0; col < tileWidth; ++col) { -+ dst[col*3] = src[col]; -+ dst[col*3 + 1] = src[col + realTileWidth]; -+ dst[col*3 + 2] = src[col + realTileWidth*2]; - } -- free (image); -- width = wide; -- height = high; -- image = img; -- fuji_width = 0; -+ } else { -+ union X { uint32_t x; uint8_t c; }; -+ if (((union X){1}).c) { -+ for (size_t col = 0; col < tileWidth; ++col) { -+ for (size_t byte = 0; byte < bytesps; ++byte) -+ dst[col*bytesps + byte] = src[col + realTileWidth*(bytesps-byte-1)]; // Little endian -+ } -+ } else { -+ for (size_t col = 0; col < tileWidth; ++col) { -+ for (size_t byte = 0; byte < bytesps; ++byte) -+ dst[col*bytesps + byte] = src[col + realTileWidth*byte]; -+ } -+ } -+ } -+ - } - --void CLASS stretch() --{ -- ushort newdim, (*img)[4], *pix0, *pix1; -- int row, col, c; -- double rc, frac; -+// From DNG SDK dng_utils.h -+static inline uint32_t DNG_HalfToFloat(uint16_t halfValue) { -+ int32_t sign = (halfValue >> 15) & 0x00000001; -+ int32_t exponent = (halfValue >> 10) & 0x0000001f; -+ int32_t mantissa = halfValue & 0x000003ff; -+ if (exponent == 0) { -+ if (mantissa == 0) { -+ // Plus or minus zero -+ return (uint32_t) (sign << 31); -+ } else { -+ // Denormalized number -- renormalize it -+ while (!(mantissa & 0x00000400)) { -+ mantissa <<= 1; -+ exponent -= 1; -+ } -+ exponent += 1; -+ mantissa &= ~0x00000400; -+ } -+ } else if (exponent == 31) { -+ if (mantissa == 0) { -+ // Positive or negative infinity, convert to maximum (16 bit) values. -+ return (uint32_t) ((sign << 31) | ((0x1eL + 127 - 15) << 23) | (0x3ffL << 13)); -+ } else { -+ // Nan -- Just set to zero. -+ return 0; -+ } -+ } -+ // Normalized number -+ exponent += (127 - 15); -+ mantissa <<= 13; -+ // Assemble sign, exponent and mantissa. -+ return (uint32_t) ((sign << 31) | (exponent << 23) | mantissa); -+} - -- 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; +static inline uint32_t DNG_FP24ToFloat(const uint8_t * input) { + int32_t sign = (input [0] >> 7) & 0x01; + int32_t exponent = (input [0] ) & 0x7F; @@ -1750,18 +1649,7 @@ + } else { + // Nan -- Just set to zero. + return 0; - } -- 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; ++ } + } + // Normalized number + exponent += (128 - 64); @@ -1769,7 +1657,35 @@ + // Assemble sign, exponent and mantissa. + return (uint32_t) ((sign << 31) | (exponent << 23) | mantissa); +} -+ + +- 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; +static void expandFloats(Bytef * dst, int tileWidth, int bytesps) { + if (bytesps == 2) { + uint16_t * dst16 = (uint16_t *) dst; @@ -1782,14 +1698,11 @@ + uint32_t * dst32 = (uint32_t *) dst; + for (int index = tileWidth - 1; index >= 0; --index, dst8 -= 3) { + dst32[index] = DNG_FP24ToFloat(dst8); - } -- width = newdim; - } -- free (image); -- image = img; ++ } ++ } } --int CLASS flip_index (int row, int col) +-void CLASS stretch() +static void copyFloatDataToInt(float * src, ushort * dst, size_t size, float max) { + bool negative = false, nan = false; + @@ -1870,13 +1783,24 @@ +#pragma omp parallel +#endif { -- if (flip & 4) SWAP(row,col); -- if (flip & 2) row = iheight - 1 - row; -- if (flip & 1) col = iwidth - 1 - col; -- return row * iwidth + col; +- ushort newdim, (*img)[4], *pix0, *pix1; +- int row, col, c; +- double rc, frac; + Bytef * cBuffer = new Bytef[maxCompressed]; + Bytef * uBuffer = new Bytef[dstLen]; -+ + +- 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; +#ifdef _OPENMP +#pragma omp for collapse(2) nowait +#endif @@ -1906,35 +1830,49 @@ + // TODO + } + } -+ } -+ + } +- 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; ++ + delete [] cBuffer; + delete [] uBuffer; -+} + } + } -+ ++ + if (ifd->sample_format == 3) { // Floating point data + copyFloatDataToInt(float_raw_image, raw_image, raw_width*raw_height, maximum); + } - } - -+/* RT: removed unused functions */ ++} + ++/* RT: removed unused functions */ + struct tiff_tag { ushort tag, type; - int count; -@@ -9188,585 +9321,12 @@ - unsigned gps[26]; +@@ -9461,590 +9588,11 @@ 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) @@ -2369,9 +2307,15 @@ - printf (_("Output size: %4d x %d\n"), iwidth, iheight); - printf (_("Raw colors: %d"), colors); - if (filters) { +- int fhigh = 2, fwide = 2; +- if ((filters ^ (filters >> 8)) & 0xff) fhigh = 4; +- if ((filters ^ (filters >> 16)) & 0xffff) fhigh = 8; +- if (filters == 1) fhigh = fwide = 16; +- if (filters == 9) fhigh = fwide = 6; - printf (_("\nFilter pattern: ")); -- for (i=0; i < 16; i++) -- putchar (cdesc[fcol(i >> 1,i & 1)]); +- for (i=0; i < fhigh; i++) +- for (c = i && putchar('/') && 0; c < fwide; c++) +- putchar (cdesc[fcol(i,c)]); - } - printf (_("\nDaylight multipliers:")); - FORCC printf (" %f", pre_mul[c]); @@ -2517,3 +2461,11 @@ - } - return status; -} ++/* 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