rawTherapee/rtengine/dcraw.patch

1999 lines
72 KiB
Diff

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