[Hdrflow-svn] SF.net SVN: hdrflow: [431] trunk/lib/extras/src/raw
Status: Pre-Alpha
Brought to you by:
glslang
|
From: <gl...@us...> - 2008-03-29 18:40:44
|
Revision: 431
http://hdrflow.svn.sourceforge.net/hdrflow/?rev=431&view=rev
Author: glslang
Date: 2008-03-29 11:40:39 -0700 (Sat, 29 Mar 2008)
Log Message:
-----------
+ update dcraw
Modified Paths:
--------------
trunk/lib/extras/src/raw/dcraw.c
trunk/lib/extras/src/raw/raw.cpp
trunk/lib/extras/src/raw/raw_vc8.vcproj
Modified: trunk/lib/extras/src/raw/dcraw.c
===================================================================
--- trunk/lib/extras/src/raw/dcraw.c 2008-03-08 19:53:37 UTC (rev 430)
+++ trunk/lib/extras/src/raw/dcraw.c 2008-03-29 18:40:39 UTC (rev 431)
@@ -1,16 +1,17 @@
/*
dcraw.c -- Dave Coffin's raw photo decoder
- Copyright 1997-2007 by Dave Coffin, dcoffin a cybercom o net
+ Copyright 1997-2008 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.
No license is required to download and use dcraw.c. However,
- to lawfully redistribute this code, you must either (a) include
- full source code* for all executable files containing RESTRICTED
- functions, (b) remove all RESTRICTED functions, re-implement them,
- or copy them from an earlier, unrestricted Revision of dcraw.c,
- or (c) purchase a license from the author.
+ to lawfully redistribute dcraw, you must either (a) offer, at
+ no extra charge, full source code* for all executable files
+ containing RESTRICTED functions, (b) distribute this code under
+ the GPL Version 2 or later, (c) remove all RESTRICTED functions,
+ re-implement them, or copy them from an earlier, unrestricted
+ Revision of dcraw.c, or (d) purchase a license from the author.
The functions that process Foveon images have been RESTRICTED
since Revision 1.237. All other code remains free for all uses.
@@ -18,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.379 $
- $Date: 2007/05/03 06:15:16 $
+ $Revision: 1.399 $
+ $Date: 2008/03/05 01:29:34 $
*/
-#define VERSION "8.71"
+#define VERSION "8.83"
#define _GNU_SOURCE
#define _USE_MATH_DEFINES
@@ -37,6 +38,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include <sys/types.h>
/*
NO_JPEG disables decoding of compressed Kodak DC120 files.
NO_LCMS disables the "-p" option.
@@ -53,7 +55,10 @@
#else
#define _(String) (String)
#endif
-#ifndef DJGPP
+#ifdef DJGPP
+#define fseeko fseek
+#define ftello ftell
+#else
#define fgetc getc_unlocked
#endif
#ifdef __CYGWIN__
@@ -63,12 +68,11 @@
#include <sys/utime.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
-#define strcasecmp _stricmp
-#define strncasecmp _strnicmp
-#define getc_unlocked getc
+#define snprintf _snprintf
+#define strcasecmp stricmp
+#define strncasecmp strnicmp
typedef __int64 INT64;
typedef unsigned __int64 UINT64;
-#pragma warning( disable:4018 4244 4305 4389 4706 )
#else
#include <unistd.h>
#include <utime.h>
@@ -97,28 +101,31 @@
*/
FILE *ifp;
short order;
-char *ifname, make[64], model[64], model2[64], *meta_data, cdesc[5];
+char *ifname, *meta_data;
+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;
unsigned shot_order, kodak_cbpp, filters, exif_cfa, unique_id;
-unsigned profile_offset, profile_length, *oprof;
-unsigned thumb_offset, thumb_length, thumb_misc;
-unsigned data_offset, strip_offset, curve_offset, meta_offset, meta_length;
-unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress, tile_length;
+off_t strip_offset, data_offset;
+off_t thumb_offset, meta_offset, profile_offset;
+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, maximum, mix_green, raw_color, use_gamma, zero_is_bad;
unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error;
+unsigned tile_width, tile_length, gpsdata[32];
ushort raw_height, raw_width, height, width, top_margin, left_margin;
ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height;
int flip, tiff_flip, colors;
-double pixel_aspect;
-ushort (*image)[4], white[8][8], curve[0x1000], cr2_slice[3];
+double pixel_aspect, aber[4]={1,1,1,1};
+ushort (*image)[4], white[8][8], curve[0x4001], cr2_slice[3], sraw_mul[4];
float bright=1, user_mul[4]={0,0,0,0}, threshold=0;
int half_size=0, four_color_rgb=0, document_mode=0, highlight=0;
-int verbose=0, use_auto_wb=0, use_camera_wb=0;
-int output_color=1, output_bps=8, output_tiff=0;
-int fuji_layout, fuji_secondary, shot_select=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], rgb_cam[3][4]; /* RGB from camera color */
+float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4];
const double xyz_rgb[3][3] = { /* XYZ from RGB */
{ 0.412453, 0.357580, 0.180423 },
{ 0.212671, 0.715160, 0.072169 },
@@ -145,9 +152,10 @@
#define CLASS
-#define FORC3 for (c=0; c < 3; c++)
-#define FORC4 for (c=0; c < 4; c++)
-#define FORCC for (c=0; c < colors; c++)
+#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 ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
@@ -257,7 +265,7 @@
if (feof(ifp))
fprintf (stderr,_("Unexpected end of file\n"));
else
- fprintf (stderr,_("Corrupt data near 0x%lx\n"), ftell(ifp));
+ fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp));
}
data_error = 1;
}
@@ -328,7 +336,6 @@
default: return fgetc(ifp);
}
}
-#define getrat() getreal(10)
void CLASS read_shorts (ushort *pixel, int count)
{
@@ -420,7 +427,7 @@
for (i=0; i < 8; i++)
total[st][i] += test[i];
count[st]++;
-next: continue;
+next: ;
}
if (count[0] | count[1]) {
st = count[0]*200 < count[1];
@@ -483,8 +490,8 @@
black = black / ((raw_width - width) * height) - 4;
for (row=0; row < height; row++)
for (col=0; col < width; col++) {
- val = (BAYER(row,col) - black) * mul[row & 3][col & 1] >> 9;
- if (val < 0) val = 0;
+ if ((val = BAYER(row,col) - black) < 0) val = 0;
+ val = val * mul[row & 3][col & 1] >> 9;
BAYER(row,col) = val;
}
canon_600_fixed_wb(1311);
@@ -524,7 +531,7 @@
void CLASS canon_a5_load_raw()
{
- ushort data[2335], *dp, pixel;
+ ushort data[2565], *dp, pixel;
int vbits=0, buf=0, row, col, bc=0;
order = 0x4949;
@@ -792,8 +799,8 @@
enough to decode Canon, Kodak and Adobe DNG images.
*/
struct jhead {
- int bits, high, wide, clrs, restart, vpred[4];
- struct decode *huff[4];
+ int bits, high, wide, clrs, psv, restart, vpred[4];
+ struct CLASS decode *huff[4];
ushort *row;
};
@@ -816,12 +823,13 @@
if (tag <= 0xff00) return 0;
fread (data, 1, len, ifp);
switch (tag) {
- case 0xffc0:
+ case 0xffc0: data[7] = 0;
case 0xffc3:
jh->bits = data[0];
jh->high = data[1] << 8 | data[2];
jh->wide = data[3] << 8 | data[4];
- jh->clrs = data[5];
+ jh->clrs = data[5] + (data[7] == 0x21);
+ if (len == 9 && !dng_version) getc(ifp);
break;
case 0xffc4:
if (info_only) break;
@@ -830,13 +838,20 @@
dp = make_decoder (++dp, 0);
}
break;
+ case 0xffda:
+ jh->psv = data[1+data[0]*2];
+ break;
case 0xffdd:
jh->restart = data[0] << 8 | data[1];
}
} while (tag != 0xffda);
if (info_only) return 1;
- jh->row = (ushort *) calloc (jh->wide*jh->clrs, 2);
- merror (jh->row, " jpeg_start()");
+ if (jh->clrs == 4) {
+ jh->huff[3] = jh->huff[2] = jh->huff[1];
+ jh->huff[1] = jh->huff[0];
+ }
+ jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4);
+ merror (jh->row, "ljpeg_start()");
return zero_after_ff = 1;
}
@@ -855,10 +870,10 @@
return diff;
}
-void CLASS ljpeg_row (int jrow, struct jhead *jh)
+ushort * CLASS ljpeg_row (int jrow, struct jhead *jh)
{
- int col, c, diff;
- ushort mark=0, *outp=jh->row;
+ int col, c, diff, pred;
+ ushort mark=0, *row[3];
if (jrow * jh->wide % jh->restart == 0) {
FORC4 jh->vpred[c] = 1 << (jh->bits-1);
@@ -867,13 +882,28 @@
while (c != EOF && mark >> 4 != 0xffd);
getbits(-1);
}
+ FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1);
for (col=0; col < jh->wide; col++)
- for (c=0; c < jh->clrs; c++) {
+ FORC(jh->clrs) {
diff = ljpeg_diff (jh->huff[c]);
- *outp = diff = col ? outp[-jh->clrs]+diff : (jh->vpred[c] += diff);
- if (diff >> jh->bits) derror();
- outp++;
+ if (jh->clrs == 4 && c < 2 && (col | c))
+ pred = row[0][(c << 1)-3];
+ else if (col) pred = row[0][-jh->clrs];
+ else pred = (jh->vpred[c] += diff) - diff;
+ if (jrow && col) switch (jh->psv) {
+ case 1: break;
+ case 2: pred = row[1][0]; break;
+ case 3: pred = row[1][-jh->clrs]; break;
+ case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break;
+ case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break;
+ case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break;
+ case 7: pred = (pred + row[1][0]) >> 1; break;
+ default: pred = 0;
+ }
+ if ((**row = pred + diff) >> jh->bits) derror();
+ row[0]++; row[1]++;
}
+ return row[2];
}
void CLASS lossless_jpeg_load_raw()
@@ -881,14 +911,15 @@
int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0;
struct jhead jh;
int min=INT_MAX;
+ ushort *rp;
if (!ljpeg_start (&jh, 0)) return;
jwide = jh.wide * jh.clrs;
for (jrow=0; jrow < jh.high; jrow++) {
- ljpeg_row (jrow, &jh);
+ rp = ljpeg_row (jrow, &jh);
for (jcol=0; jcol < jwide; jcol++) {
- val = jh.row[jcol];
+ val = *rp++;
if (jh.bits <= 12)
val = curve[val];
if (cr2_slice[0]) {
@@ -919,13 +950,57 @@
black = min;
}
+void CLASS canon_sraw_load_raw()
+{
+ struct jhead jh;
+ short *rp=0, *ip;
+ int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c;
+
+ if (!ljpeg_start (&jh, 0)) return;
+ jwide = (jh.wide >>= 1) * 4;
+
+ for (ecol=slice=0; slice <= cr2_slice[0]; slice++) {
+ scol = ecol;
+ ecol += cr2_slice[1] >> 1;
+ if (!cr2_slice[0] || ecol > width-1) ecol = width & -2;
+ for (row=0; row < height; row++) {
+ ip = (short *) image[row*width+scol];
+ for (col=scol; col < ecol; col+=2, jcol+=4, ip+=8) {
+ if ((jcol %= jwide) == 0)
+ rp = (short *) ljpeg_row (jrow++, &jh);
+ ip[0] = rp[jcol];
+ ip[4] = rp[jcol+1];
+ ip[1] = (short) (rp[jcol+2] << 2) >> 2;
+ ip[2] = (short) (rp[jcol+3] << 2) >> 2;
+ }
+ }
+ }
+ for (row=0; row < height; row++) {
+ ip = (short *) image[row*width+1];
+ for (col=1; col < width-1; col+=2, ip+=8) {
+ ip[1] = (ip[-3] + ip[5] + 1) >> 1;
+ ip[2] = (ip[-2] + ip[6] + 1) >> 1;
+ }
+ if (col < width) { ip[1] = ip[-3]; ip[2] = ip[-2]; }
+ ip = (short *) image[row*width];
+ for (col=0; col < width; col++, ip+=4) {
+ pix[0] = ip[2] + ip[0];
+ pix[2] = ip[1] + ip[0];
+ pix[1] = ((ip[0] << 12) - ip[1]*778 - (ip[2] << 11)) >> 12;
+ FORC3 ip[c] = CLIP((pix[c] - 512) * sraw_mul[c] >> 10);
+ }
+ }
+ free (jh.row);
+ maximum = 0x3fff;
+}
+
void CLASS adobe_copy_pixel (int row, int col, ushort **rp)
{
unsigned r, c;
r = row -= top_margin;
c = col -= left_margin;
- if (fuji_secondary && shot_select) (*rp)++;
+ if (is_raw == 2 && shot_select) (*rp)++;
if (filters) {
if (fuji_width) {
r = row + fuji_width - 1 - (col >> 1);
@@ -933,47 +1008,41 @@
}
if (r < height && c < width)
BAYER(r,c) = **rp < 0x1000 ? curve[**rp] : **rp;
- *rp += 1 + fuji_secondary;
+ *rp += is_raw;
} else {
if (r < height && c < width)
- for (c=0; c < tiff_samples; c++)
+ FORC(tiff_samples)
image[row*width+col][c] = (*rp)[c] < 0x1000 ? curve[(*rp)[c]]:(*rp)[c];
*rp += tiff_samples;
}
- if (fuji_secondary && shot_select) (*rp)--;
+ if (is_raw == 2 && shot_select) (*rp)--;
}
void CLASS adobe_dng_load_raw_lj()
{
- int save, twide, trow=0, tcol=0, jrow, jcol;
+ unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col;
struct jhead jh;
ushort *rp;
- while (1) {
+ while (trow < raw_height) {
save = ftell(ifp);
if (tile_length < INT_MAX)
fseek (ifp, get4(), SEEK_SET);
if (!ljpeg_start (&jh, 0)) break;
- if (trow >= raw_height) break;
- if (jh.high > raw_height-trow)
- jh.high = raw_height-trow;
- twide = jh.wide;
- if (filters) twide *= jh.clrs;
- else colors = jh.clrs;
- if (fuji_secondary) twide /= 2;
- if (twide > raw_width-tcol)
- twide = raw_width-tcol;
-
- for (jrow=0; jrow < jh.high; jrow++) {
- ljpeg_row (jrow, &jh);
- for (rp=jh.row, jcol=0; jcol < twide; jcol++)
- adobe_copy_pixel (trow+jrow, tcol+jcol, &rp);
+ jwide = jh.wide;
+ if (filters) jwide *= jh.clrs;
+ jwide /= is_raw;
+ for (row=col=jrow=0; jrow < jh.high; jrow++) {
+ rp = ljpeg_row (jrow, &jh);
+ for (jcol=0; jcol < jwide; jcol++) {
+ adobe_copy_pixel (trow+row, tcol+col, &rp);
+ if (++col >= tile_width || col >= raw_width)
+ row += 1 + (col = 0);
+ }
}
fseek (ifp, save+4, SEEK_SET);
- if ((tcol += twide) >= raw_width) {
- tcol = 0;
- trow += jh.high;
- }
+ if ((tcol += tile_width) >= raw_width)
+ trow += tile_length + (tcol = 0);
free (jh.row);
}
}
@@ -1013,10 +1082,8 @@
for (row=0; row < height; row++)
for (col=0; col < raw_width; col++) {
diff = ljpeg_diff (first_decode);
- if (col < 2)
- hpred[col] = vpred[row & 1][col] += diff;
- else
- hpred[col & 1] += diff;
+ if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
+ else hpred[col & 1] += diff;
if (col < width)
BAYER(row,col) = hpred[col & 1];
if (hpred[col & 1] >> 12) derror();
@@ -1025,36 +1092,68 @@
void CLASS nikon_compressed_load_raw()
{
- static const uchar nikon_tree[] =
- { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0,
- 5,4,3,6,2,7,1,0,8,9,11,10,12 };
- int csize, row, col, diff;
- ushort vpred[2][2], hpred[2], *curve;
+ static const uchar nikon_tree[][32] = {
+ { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */
+ 5,4,3,6,2,7,1,0,8,9,11,10,12 },
+ { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */
+ 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 },
+ { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */
+ 5,4,6,3,7,2,8,1,9,0,10,11,12 },
+ { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */
+ 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 },
+ { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */
+ 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 },
+ { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */
+ 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } };
+ struct decode *dindex;
+ ushort ver0, ver1, vpred[2][2], hpred[2], csize;
+ int i, max, step=0, huff=0, split=0, row, col, len, shl, diff;
+ fseek (ifp, meta_offset, SEEK_SET);
+ ver0 = fgetc(ifp);
+ ver1 = fgetc(ifp);
+ if (ver0 == 0x49 || ver1 == 0x58)
+ fseek (ifp, 2110, SEEK_CUR);
+ if (ver0 == 0x46) huff = 2;
+ if (tiff_bps == 14) huff += 3;
+ read_shorts (vpred[0], 4);
+ max = 1 << tiff_bps & 0x7fff;
+ if ((csize = get2()) > 1)
+ step = max / (csize-1);
+ if (ver0 == 0x44 && ver1 == 0x20 && step > 0) {
+ for (i=0; i < csize; i++)
+ curve[i*step] = get2();
+ for (i=0; i < max; i++)
+ curve[i] = ( curve[i-i%step]*(step-i%step) +
+ curve[i-i%step+step]*(i%step) ) / step;
+ fseek (ifp, meta_offset+562, SEEK_SET);
+ split = get2();
+ } else if (ver0 != 0x46 && csize <= 0x4001)
+ read_shorts (curve, max=csize);
init_decoder();
- make_decoder (nikon_tree, 0);
-
- fseek (ifp, curve_offset, SEEK_SET);
- read_shorts (vpred[0], 4);
- csize = get2();
- curve = (ushort *) calloc (csize, sizeof *curve);
- merror (curve, "nikon_compressed_load_raw()");
- read_shorts (curve, csize);
-
+ make_decoder (nikon_tree[huff], 0);
fseek (ifp, data_offset, SEEK_SET);
getbits(-1);
- for (row=0; row < height; row++)
+ for (row=0; row < height; row++) {
+ if (split && row == split) {
+ init_decoder();
+ make_decoder (nikon_tree[huff+1], 0);
+ }
for (col=0; col < raw_width; col++) {
- diff = ljpeg_diff (first_decode);
- if (col < 2)
- hpred[col] = vpred[row & 1][col] += diff;
- else
- hpred[col & 1] += diff;
- if ((unsigned) (col-left_margin) >= width) continue;
- if (hpred[col & 1] >= csize) derror();
- else BAYER(row,col-left_margin) = curve[hpred[col & 1]];
+ for (dindex=first_decode; dindex->branch[0]; )
+ dindex = dindex->branch[getbits(1)];
+ len = dindex->leaf & 15;
+ shl = dindex->leaf >> 4;
+ diff = ((getbits(len-shl) << 1) + 1) << shl >> 1;
+ if ((diff & (1 << (len-1))) == 0)
+ diff -= (1 << len) - !shl;
+ if (col < 2) hpred[col] = vpred[row & 1][col] += diff;
+ else hpred[col & 1] += diff;
+ if (hpred[col & 1] >= max) derror();
+ if ((unsigned) (col-left_margin) < width)
+ BAYER(row,col-left_margin) = curve[hpred[col & 1] & 0x3fff];
}
- free (curve);
+ }
}
void CLASS nikon_load_raw()
@@ -1076,7 +1175,7 @@
i = getbits(12);
if ((unsigned) (col-left_margin) < width)
BAYER(row,col-left_margin) = i;
- if (tiff_compress == 34713 && (col % 10) == 9)
+ if (tiff_compress > 32768 && (col % 10) == 9)
if (getbits(8)) derror();
}
}
@@ -1092,10 +1191,6 @@
uchar test[256];
int i;
- if (tiff_compress != 34713)
- return 0;
- if (strcmp(model,"D100"))
- return 1;
fseek (ifp, data_offset, SEEK_SET);
fread (test, 1, 256, ifp);
for (i=15; i < 256; i+=16)
@@ -1531,14 +1626,15 @@
static UINT64 bitbuf=0;
static int vbits=0;
- if (nbits == 0)
+ if (nbits == -1)
return bitbuf = vbits = 0;
+ if (nbits == 0) return 0;
if (vbits < nbits) {
bitbuf = bitbuf << 32 | get4();
vbits += 32;
}
vbits -= nbits;
- return bitbuf << (64 - nbits - vbits) >> (64 - nbits);
+ return bitbuf << (64-nbits-vbits) >> (64-nbits);
}
void CLASS phase_one_load_raw_c()
@@ -1562,7 +1658,7 @@
curve[i] = i*i / 3.969 + 0.5;
for (row=0; row < raw_height; row++) {
fseek (ifp, data_offset + offset[row], SEEK_SET);
- ph1_bits(0);
+ ph1_bits(-1);
pred[0] = pred[1] = 0;
for (col=0; col < raw_width; col++) {
if (col >= (raw_width & -8))
@@ -1592,6 +1688,36 @@
maximum = 0xfffc - ph1.black;
}
+void CLASS hasselblad_load_raw()
+{
+ struct jhead jh;
+ struct decode *dindex;
+ int row, col, pred[2], len[2], diff, i;
+
+ if (!ljpeg_start (&jh, 0)) return;
+ free (jh.row);
+ ph1_bits(-1);
+ for (row=-top_margin; row < height; row++) {
+ pred[0] = pred[1] = 0x8000;
+ for (col=-left_margin; col < raw_width-left_margin; col+=2) {
+ for (i=0; i < 2; i++) {
+ for (dindex=jh.huff[0]; dindex->branch[0]; )
+ dindex = dindex->branch[ph1_bits(1)];
+ len[i] = dindex->leaf;
+ }
+ for (i=0; i < 2; i++) {
+ diff = ph1_bits(len[i]);
+ if ((diff & (1 << (len[i]-1))) == 0)
+ diff -= (1 << len[i]) - 1;
+ pred[i] += diff;
+ if (row >= 0 && (unsigned)(col+i) < width)
+ BAYER(row,col+i) = pred[i];
+ }
+ }
+ }
+ maximum = 0xffff;
+}
+
void CLASS leaf_hdr_load_raw()
{
ushort *pixel;
@@ -1599,7 +1725,7 @@
pixel = (ushort *) calloc (raw_width, sizeof *pixel);
merror (pixel, "leaf_hdr_load_raw()");
- for (c=0; c < tiff_samples; c++) {
+ FORC(tiff_samples)
for (r=0; r < raw_height; r++) {
if (r % tile_length == 0) {
fseek (ifp, data_offset + 4*tile++, SEEK_SET);
@@ -1612,7 +1738,6 @@
if (filters) BAYER(row,col) = pixel[col];
else image[row*width+col][c] = pixel[col];
}
- }
free (pixel);
if (!filters) {
maximum = 0xffff;
@@ -1701,6 +1826,65 @@
free (pixel);
}
+void CLASS nokia_load_raw()
+{
+ uchar *data, *dp;
+ ushort *pixel, *pix;
+ int dwide, row, c;
+
+ dwide = raw_width * 5 / 4;
+ data = (uchar *) malloc (dwide + raw_width*2);
+ merror (data, "nokia_load_raw()");
+ pixel = (ushort *) (data + dwide);
+ for (row=0; row < raw_height; row++) {
+ if (fread (data, 1, dwide, ifp) < dwide) derror();
+ for (dp=data, pix=pixel; pix < pixel+raw_width; dp+=5, pix+=4)
+ FORC4 pix[c] = (dp[c] << 2) | (dp[4] >> (c << 1) & 3);
+ if (row < top_margin)
+ FORC(width) black += pixel[c];
+ else
+ FORC(width) BAYER(row-top_margin,c) = pixel[c];
+ }
+ free (data);
+ if (top_margin) black /= top_margin * width;
+ maximum = 0x3ff;
+}
+
+unsigned CLASS pana_bits (int nbits)
+{
+ static uchar buf[16], vbits=0;
+
+ if (!vbits && fread (buf, 1, 16, ifp) < 16) derror();
+ vbits = (vbits - nbits) & 127;
+ return (buf[(vbits >> 3)+1] << 8 | buf[vbits >> 3])
+ >> (vbits & 7) & ~(-1 << nbits);
+}
+
+void CLASS panasonic_load_raw()
+{
+ int row, col, i, j, sh=0, pred[2], nonz[2];
+
+ raw_width = (raw_width+13)/14*14;
+ for (row=0; row < height; row++)
+ for (col=0; col < raw_width; col++) {
+ if ((i = col % 14) < 2)
+ nonz[i] = pred[i] = pana_bits(12);
+ else {
+ if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2));
+ if ((j = pana_bits(8))) {
+ if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4)
+ pred[i & 1] &= ~(-1 << sh);
+ pred[i & 1] += nonz[i & 1] ? j << sh : j;
+ nonz[i & 1] = 1;
+ }
+ }
+ if (col < width)
+ if ((BAYER(row,col) = pred[col & 1]) >> 12) derror();
+ }
+ maximum = 0xf96;
+ black = 15;
+}
+
void CLASS olympus_e300_load_raw()
{
uchar *data, *dp;
@@ -1724,10 +1908,8 @@
BAYER(row,col) = (pixel[col+left_margin] & 0xfff);
}
free (data);
- if (!strcmp(make,"OLYMPUS")) {
- maximum = 0xfff;
- black >>= 4;
- }
+ maximum >>= 4;
+ black >>= 4;
}
void CLASS olympus_e410_load_raw()
@@ -1815,22 +1997,6 @@
maximum = 0xff << 1;
}
-void CLASS eight_bit_load_raw()
-{
- uchar *pixel;
- int row, col;
-
- pixel = (uchar *) calloc (raw_width, sizeof *pixel);
- merror (pixel, "eight_bit_load_raw()");
- for (row=0; row < height; row++) {
- if (fread (pixel, 1, raw_width, ifp) < raw_width) derror();
- for (col=0; col < width; col++)
- BAYER(row,col) = pixel[col];
- }
- free (pixel);
- maximum = 0xff;
-}
-
void CLASS casio_qv5700_load_raw()
{
uchar data[3232], *dp;
@@ -2123,27 +2289,26 @@
maximum = 0xff;
}
-void CLASS kodak_easy_load_raw()
+void CLASS eight_bit_load_raw()
{
uchar *pixel;
- unsigned row, col, val;
+ unsigned row, col, val, lblack=0;
- if (raw_width > width)
- black = 0;
pixel = (uchar *) calloc (raw_width, sizeof *pixel);
- merror (pixel, "kodak_easy_load_raw()");
+ merror (pixel, "eight_bit_load_raw()");
+ fseek (ifp, top_margin*raw_width, SEEK_CUR);
for (row=0; row < height; row++) {
if (fread (pixel, 1, raw_width, ifp) < raw_width) derror();
for (col=0; col < raw_width; col++) {
val = curve[pixel[col]];
if ((unsigned) (col-left_margin) < width)
BAYER(row,col-left_margin) = val;
- else black += val;
+ else lblack += val;
}
}
free (pixel);
- if (raw_width > width)
- black /= (raw_width - width) * height;
+ if (raw_width > width+1)
+ black = lblack / ((raw_width - width) * height);
if (!strncmp(model,"DC2",3))
black = 0;
maximum = curve[0xff];
@@ -2383,6 +2548,45 @@
}
}
+void CLASS sony_arw2_load_raw()
+{
+ uchar *data, *dp;
+ ushort pix[16];
+ int row, col, val, max, min, imax, imin, sh, bit, i;
+
+ data = (uchar *) malloc (raw_width*tiff_bps >> 3);
+ merror (data, "sony_arw2_load_raw()");
+ for (row=0; row < height; row++) {
+ fread (data, 1, raw_width*tiff_bps >> 3, ifp);
+ if (tiff_bps == 8) {
+ for (dp=data, col=0; col < width-30; dp+=16) {
+ max = 0x7ff & (val = sget4(dp));
+ min = 0x7ff & val >> 11;
+ imax = 0x0f & val >> 22;
+ imin = 0x0f & val >> 26;
+ for (sh=0; sh < 4 && 0x80 << sh <= max-min; sh++);
+ for (bit=30, i=0; i < 16; i++)
+ if (i == imax) pix[i] = max;
+ else if (i == imin) pix[i] = min;
+ else {
+ pix[i] = ((sget2(dp+(bit >> 3)) >> (bit & 7) & 0x7f) << sh) + min;
+ if (pix[i] > 0x7ff) pix[i] = 0x7ff;
+ bit += 7;
+ }
+ for (i=0; i < 16; i++, col+=2)
+ BAYER(row,col) = curve[pix[i] << 1] >> 1;
+ col -= col & 1 ? 1:31;
+ }
+ } else if (tiff_bps == 12)
+ for (dp=data, col=0; col < width; dp+=3, col+=2) {
+ BAYER(row,col) = ((dp[1] << 8 | dp[0]) & 0xfff) << 1;
+ BAYER(row,col+1) = (dp[2] << 4 | dp[1] >> 4) << 1;
+ }
+ }
+ free (data);
+ maximum = 0x1fff;
+}
+
#define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1)
/* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */
@@ -2623,7 +2827,7 @@
for (row=0; row < height; row++) {
memset (pred, 0, sizeof pred);
- if (!bit && !fixed && width < 2688) get4();
+ if (!bit && !fixed && atoi(model+2) < 14) get4();
for (col=bit=0; col < width; col++) {
if (fixed) {
bitbuf = get4();
@@ -3171,35 +3375,39 @@
Seach from the current directory up to the root looking for
a ".badpixels" file, and fix those pixels now.
*/
-void CLASS bad_pixels()
+void CLASS bad_pixels (char *fname)
{
FILE *fp=0;
- char *fname, *cp, line[128];
+ char *cp, line[128];
int len, time, row, col, r, c, rad, tot, n, fixed=0;
if (!filters) return;
- for (len=32 ; ; len *= 2) {
- fname = (char *) malloc (len);
- if (!fname) return;
- if (getcwd (fname, len-16)) break;
- free (fname);
- if (errno != ERANGE) return;
- }
+ if (fname)
+ fp = fopen (fname, "r");
+ else {
+ for (len=32 ; ; len *= 2) {
+ fname = (char *) malloc (len);
+ if (!fname) return;
+ if (getcwd (fname, len-16)) break;
+ free (fname);
+ if (errno != ERANGE) return;
+ }
#if defined(WIN32) || defined(DJGPP)
- if (fname[1] == ':')
- memmove (fname, fname+2, len-2);
- for (cp=fname; *cp; cp++)
- if (*cp == '\\') *cp = '/';
+ if (fname[1] == ':')
+ memmove (fname, fname+2, len-2);
+ for (cp=fname; *cp; cp++)
+ if (*cp == '\\') *cp = '/';
#endif
- cp = fname + strlen(fname);
- if (cp[-1] == '/') cp--;
- while (*fname == '/') {
- strcpy (cp, "/.badpixels");
- if ((fp = fopen (fname, "r"))) break;
- if (cp == fname) break;
- while (*--cp != '/');
+ cp = fname + strlen(fname);
+ if (cp[-1] == '/') cp--;
+ while (*fname == '/') {
+ strcpy (cp, "/.badpixels");
+ if ((fp = fopen (fname, "r"))) break;
+ if (cp == fname) break;
+ while (*--cp != '/');
+ }
+ free (fname);
}
- free (fname);
if (!fp) return;
while (fgets (line, 128, fp)) {
cp = strchr (line, '#');
@@ -3218,7 +3426,7 @@
BAYER2(row,col) = tot/n;
if (verbose) {
if (!fixed++)
- fprintf (stderr,_("Fixed bad pixels at:"));
+ fprintf (stderr,_("Fixed dead pixels at:"));
fprintf (stderr, " %d,%d", col, row);
}
}
@@ -3441,7 +3649,7 @@
merror (fimg, "wavelet_denoise()");
temp = fimg + size*3;
if ((nc = colors) == 3 && filters) nc++;
- for (c=0; c < nc; c++) { /* denoise R,G1,B,G3 individually */
+ FORC(nc) { /* denoise R,G1,B,G3 individually */
for (i=0; i < size; i++)
fimg[i] = sqrt((unsigned) (image[i][c] << (scale+16)));
for (hpass=lev=0; lev < 5; lev++) {
@@ -3500,10 +3708,11 @@
void CLASS scale_colors()
{
- unsigned bottom, right, row, col, x, y, c, sum[8];
- int val, dblack;
+ unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8];
+ int val, dark, sat;
double dsum[8], dmin, dmax;
- float scale_mul[4];
+ float scale_mul[4], fr, fc;
+ ushort *img=0, *pix;
if (user_mul[0])
memcpy (pre_mul, user_mul, sizeof pre_mul);
@@ -3528,9 +3737,8 @@
sum[c+4]++;
if (filters) break;
}
- for (c=0; c < 8; c++) dsum[c] += sum[c];
-skip_block:
- continue;
+ FORC(8) dsum[c] += sum[c];
+skip_block: ;
}
FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c];
}
@@ -3551,7 +3759,8 @@
fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
}
if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
- dblack = black;
+ dark = black;
+ sat = maximum;
if (threshold) wavelet_denoise();
maximum -= black;
for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) {
@@ -3563,19 +3772,45 @@
if (!highlight) dmax = dmin;
FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;
if (verbose) {
- fprintf (stderr,_("Scaling with black %d, multipliers"), dblack);
+ fprintf (stderr,
+ _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat);
FORC4 fprintf (stderr, " %f", pre_mul[c]);
fputc ('\n', stderr);
}
- for (row=0; row < iheight; row++)
- for (col=0; col < iwidth; col++)
- FORC4 {
- val = image[row*iwidth+col][c];
- if (!val) continue;
- val -= black;
- val *= scale_mul[c];
- image[row*iwidth+col][c] = CLIP(val);
+ size = iheight*iwidth;
+ for (i=0; i < size*4; i++) {
+ val = image[0][i];
+ if (!val) continue;
+ val -= black;
+ val *= scale_mul[i & 3];
+ image[0][i] = CLIP(val);
+ }
+ if ((aber[0] != 1 || aber[2] != 1) && colors == 3) {
+ if (verbose)
+ fprintf (stderr,_("Correcting chromatic aberration...\n"));
+ for (c=0; c < 4; c+=2) {
+ if (aber[c] == 1) continue;
+ img = (ushort *) malloc (size * sizeof *img);
+ merror (img, "scale_colors()");
+ for (i=0; i < size; i++)
+ img[i] = image[i][c];
+ for (row=0; row < iheight; row++) {
+ ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5;
+ if (ur > iheight-2) continue;
+ fr -= ur;
+ for (col=0; col < iwidth; col++) {
+ uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5;
+ if (uc > iwidth-2) continue;
+ fc -= uc;
+ pix = img + ur*iwidth + uc;
+ image[row*iwidth+col][c] =
+ (pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) +
+ (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr;
+ }
}
+ free(img);
+ }
+ }
}
void CLASS pre_interpolate()
@@ -3587,7 +3822,6 @@
if (half_size) {
height = iheight;
width = iwidth;
- filters = 0;
} else {
img = (ushort (*)[4]) calloc (height*width, sizeof *img);
merror (img, "unshrink()");
@@ -3610,6 +3844,7 @@
filters &= ~((filters & 0x55555555) << 1);
}
}
+ if (half_size) filters = 0;
}
void CLASS border_interpolate (int border)
@@ -3660,7 +3895,7 @@
FORCC
if (c != fc(row,col)) {
*ip++ = c;
- *ip++ = sum[c];
+ *ip++ = 256 / sum[c];
}
}
for (row=1; row < height-1; row++)
@@ -3671,7 +3906,7 @@
for (i=8; 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];
+ pix[ip[0]] = sum[ip[0]] * ip[1] >> 8;
}
}
@@ -3812,6 +4047,76 @@
}
/*
+ Patterned Pixel Grouping Interpolation by Alain Desbiolles
+*/
+void CLASS ppg_interpolate()
+{
+ int gr[4], dir[5] = { 1, width, -1, -width, 1 };
+ int row, col, avg, diff[2], guess[2], c, d, i;
+ static const short sort[] = { 0,2,1,3,0,1,2,3 };
+ 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 (avg=i=0; i < 4; i++)
+ avg += gr[i] = pix[dir[i]][1] << 2;
+ avg >>= 2;
+ for (i=0; i < 8; i+=2)
+ if (gr[sort[i]] > gr[sort[i+1]])
+ SWAP(gr[sort[i]],gr[sort[i+1]])
+ for (d=0; d < 4; d++) {
+ for (i=-2; i < 2; i++)
+ if (pix[i*dir[d] + (i+1)*dir[d+1]][1] <= avg) break;
+ if (i == 2) {
+ pix[0][1] = (gr[1]+gr[2]) >> 3;
+ goto next_pixel;
+ }
+ }
+ 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]);
+next_pixel: ;
+ }
+/* 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);
+ }
+}
+
+/*
Adaptive Homogeneity-Directed interpolation is based on
the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
*/
@@ -3942,6 +4247,34 @@
}
#undef TS
+void CLASS median_filter ()
+{
+ ushort (*pix)[4];
+ int pass, c, i, j, k, med[9];
+ static const uchar opt[] = /* Optimal 9-element median search */
+ { 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8,
+ 0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 };
+
+ for (pass=1; pass <= med_passes; pass++) {
+ if (verbose)
+ fprintf (stderr,_("Median filter pass %d...\n"), pass);
+ for (c=0; c < 3; c+=2) {
+ for (pix = image; pix < image+width*height; pix++)
+ pix[0][3] = pix[0][c];
+ for (pix = image+width; pix < image+width*(height-1); pix++) {
+ if ((pix-image+1) % width < 2) continue;
+ for (k=0, i = -width; i <= width; i += width)
+ for (j = i-1; j <= i+1; j++)
+ med[k++] = pix[j][3] - pix[j][1];
+ for (i=0; i < sizeof opt; i+=2)
+ if (med[opt[i]] > med[opt[i+1]])
+ SWAP (med[opt[i]] , med[opt[i+1]]);
+ pix[0][c] = CLIP(med[4] + pix[0][1]);
+ }
+ }
+ }
+}
+
void CLASS blend_highlights()
{
int clip=INT_MAX, row, col, c, i, j;
@@ -4119,15 +4452,14 @@
0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
unsigned offset=0, entries, tag, type, len, save, c;
- unsigned ver97=0, serial=0, i, wb[4]={0,0,0,0};
+ unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0};
uchar buf97[324], ci, cj, ck;
- short sorder;
+ short sorder=order;
char buf[10];
/*
The MakerNote might have its own TIFF header (possibly with
its own byte-order!), or it might just be a table.
*/
- sorder = order;
fread (buf, 1, 10, ifp);
if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */
!strncmp (buf,"VER" ,3) ||
@@ -4183,17 +4515,20 @@
aperture = pow (2, i/64.0);
if ((i=get2()) != 0xffff)
shutter = pow (2, (short) i/-32.0);
- shot_order = (get4(),get2(),get2());
+ wbi = (get2(),get2());
+ shot_order = (get2(),get2());
}
if (tag == 8 && type == 4)
shot_order = get4();
+ if (tag == 9 && !strcmp(make,"Canon"))
+ fread (artist, 64, 1, ifp);
if (tag == 0xc && len == 4) {
- cam_mul[0] = getrat();
- cam_mul[2] = getrat();
+ cam_mul[0] = getreal(type);
+ cam_mul[2] = getreal(type);
}
if (tag == 0x10 && type == 4)
unique_id = get4();
- if (tag == 0x11 && is_raw) {
+ if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) {
fseek (ifp, get4()+base, SEEK_SET);
parse_tiff_ifd (base);
}
@@ -4201,6 +4536,8 @@
fseek (ifp, 1248, SEEK_CUR);
goto get2_256;
}
+ if (tag == 0x15 && type == 2 && is_raw)
+ fread (model, 64, 1, ifp);
if (strstr(make,"PENTAX")) {
if (tag == 0x1b) tag = 0x1018;
if (tag == 0x1c) tag = 0x1017;
@@ -4215,6 +4552,11 @@
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)) {
@@ -4225,10 +4567,8 @@
thumb_offset += base;
if (tag == 0x89 && type == 4)
thumb_length = get4();
- if (tag == 0x8c)
- curve_offset = ftell(ifp) + 2112;
- if (tag == 0x96)
- curve_offset = ftell(ifp) + 2;
+ if (tag == 0x8c || tag == 0x96)
+ meta_offset = ftell(ifp);
if (tag == 0x97) {
for (i=0; i < 4; i++)
ver97 = (ver97 << 4) + fgetc(ifp)-'0';
@@ -4249,6 +4589,10 @@
fread (buf97, 324, 1, ifp);
}
}
+ if (tag == 0xa4 && type == 3) {
+ fseek (ifp, wbi*48, SEEK_CUR);
+ FORC3 cam_mul[c] = get2();
+ }
if (tag == 0xa7 && ver97 >> 8 == 2) {
ci = xlat[0][serial & 0xff];
cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)];
@@ -4257,6 +4601,9 @@
buf97[i] ^= (cj += ci * ck++);
FORC4 cam_mul[c ^ (c >> 1)] =
sget2 (buf97 + (ver97 == 0x205 ? 14:6) + c*2);
+ if (ver97 == 0x209)
+ FORC4 cam_mul[c ^ (c >> 1) ^ 1] =
+ sget2 (buf97 + 10 + c*2);
}
if (tag == 0x200 && len == 3)
shot_order = (get4(),get4());
@@ -4293,11 +4640,9 @@
else goto next;
goto get2_256;
}
- if (((tag == 0x1011 && len == 9) || tag == 0x20400200) && use_camera_wb) {
+ if ((tag == 0x1011 && len == 9) || tag == 0x20400200)
for (i=0; i < 3; i++)
- FORC3 rgb_cam[i][c] = ((short) get2()) / 256.0;
- raw_color = rgb_cam[0][0] < 1;
- }
+ FORC3 cmatrix[i][c] = ((short) get2()) / 256.0;
if ((tag == 0x1012 || tag == 0x20400600) && len == 4)
for (black = i=0; i < 4; i++)
black += get2() << 2;
@@ -4324,6 +4669,8 @@
fseek (ifp, i, SEEK_CUR);
get2_rggb:
FORC4 cam_mul[c ^ (c >> 1)] = get2();
+ fseek (ifp, 22, SEEK_CUR);
+ FORC4 sraw_mul[c ^ (c >> 1)] = get2();
}
next:
fseek (ifp, save, SEEK_SET);
@@ -4342,7 +4689,6 @@
char str[20];
int i;
- if (timestamp) return;
str[19] = 0;
if (reversed)
for (i=19; i--; ) str[i] = fgetc(ifp);
@@ -4368,15 +4714,15 @@
while (entries--) {
tiff_get (base, &tag, &type, &len, &save);
switch (tag) {
- case 33434: shutter = getrat(); break;
- case 33437: aperture = getrat(); break;
+ case 33434: shutter = getreal(type); break;
+ case 33437: aperture = getreal(type); break;
case 34855: iso_speed = get2(); break;
case 36867:
case 36868: get_timestamp(0); break;
- case 37377: if ((expo = -getrat()) < 128)
+ case 37377: if ((expo = -getreal(type)) < 128)
shutter = pow (2, expo); break;
- case 37378: aperture = pow (2, getrat()/2); break;
- case 37386: focal_len = getrat(); break;
+ case 37378: aperture = pow (2, getreal(type)/2); break;
+ case 37386: focal_len = getreal(type); break;
case 37500: parse_makernote (base, 0); break;
case 40962: if (kodak) raw_width = get4(); break;
case 40963: if (kodak) raw_height = get4(); break;
@@ -4389,6 +4735,27 @@
}
}
+void CLASS parse_gps (int base)
+{
+ unsigned entries, tag, type, len, save, c;
+
+ entries = get2();
+ while (entries--) {
+ tiff_get (base, &tag, &type, &len, &save);
+ switch (tag) {
+ case 1: case 3: case 5:
+ gpsdata[29+tag/2] = getc(ifp); break;
+ case 2: case 4: case 7:
+ FORC(6) gpsdata[tag/3*6+c] = get4(); break;
+ case 6:
+ FORC(2) gpsdata[18+c] = get4(); break;
+ case 18: case 29:
+ fgets ((char *) (gpsdata+14+tag/3), MIN(len,12), ifp);
+ }
+ fseek (ifp, save, SEEK_SET);
+ }
+}
+
void CLASS romm_coeff (float romm_cam[3][3])
{
static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */
@@ -4397,10 +4764,10 @@
{ -0.008565, -0.153273, 1.161839 } };
int i, j, k;
- for (raw_color = i=0; i < 3; i++)
+ for (i=0; i < 3; i++)
for (j=0; j < 3; j++)
- for (rgb_cam[i][j] = k=0; k < 3; k++)
- rgb_cam[i][j] += rgb_romm[i][k] * romm_cam[k][j];
+ for (cmatrix[i][j] = k=0; k < 3; k++)
+ cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
}
void CLASS parse_mos (int offset)
@@ -4433,8 +4800,13 @@
if ((unsigned) i < sizeof mod / sizeof (*mod))
strcpy (model, mod[i]);
}
- if (!strcmp(data,"CaptProf_color_matrix") && use_camera_wb) {
+ if (!strcmp(data,"icc_camera_to_tone_matrix")) {
for (i=0; i < 9; i++)
+ romm_cam[0][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]);
romm_coeff (romm_cam);
}
@@ -4514,6 +4886,7 @@
uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256];
double dblack, cc[4][4], cm[4][3], cam_xyz[4][3], num;
double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 };
+ unsigned sony_curve[] = { 0,0,0,0,0,4095 };
unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
struct jhead jh;
FILE *sfp;
@@ -4544,6 +4917,11 @@
fseek (ifp, 12, SEEK_CUR);
FORC3 cam_mul[c] = get2();
break;
+ case 46:
+ if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break;
+ thumb_offset = ftell(ifp) - 2;
+ thumb_length = len;
+ break;
case 2: case 256: /* ImageWidth */
tiff_ifd[ifd].width = getint(type);
break;
@@ -4560,6 +4938,9 @@
case 262: /* PhotometricInterpretation */
tiff_ifd[ifd].phint = get2();
break;
+ case 270: /* ImageDescription */
+ fread (desc, 512, 1, ifp);
+ break;
case 271: /* Make */
fgets (make, 64, ifp);
break;
@@ -4602,12 +4983,21 @@
case 306: /* DateTime */
get_timestamp(0);
break;
+ case 315: /* Artist */
+ fread (artist, 64, 1, ifp);
+ break;
+ case 322: /* TileWidth */
+ tile_width = getint(type);
+ break;
case 323: /* TileLength */
tile_length = getint(type);
break;
case 324: /* TileOffsets */
tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4();
- if (len == 4) load_raw = &CLASS sinar_4shot_load_raw;
+ if (len == 4) {
+ load_raw = &CLASS sinar_4shot_load_raw;
+ is_raw = 5;
+ }
break;
case 330: /* SubIFDs */
if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) {
@@ -4625,9 +5015,19 @@
strcpy (make, "Sarnoff");
maximum = 0xfff;
break;
+ case 28688:
+ FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff;
+ for (i=0; i < 5; i++)
+ for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++)
+ curve[j] = curve[j-1] + (1 << i);
+ break;
case 29184: sony_offset = get4(); break;
case 29185: sony_length = get4(); break;
case 29217: sony_key = get4(); break;
+ case 29264:
+ parse_minolta (ftell(ifp));
+ raw_width = 0;
+ break;
case 29443:
FORC4 cam_mul[c ^ (c < 2)] = get2();
break;
@@ -4650,10 +5050,10 @@
parse_kodak_ifd (base);
break;
case 33434: /* ExposureTime */
- shutter = getrat();
+ shutter = getreal(type);
break;
case 33437: /* FNumber */
- aperture = getrat();
+ aperture = getreal(type);
break;
case 34306: /* Leaf white balance */
FORC4 cam_mul[c ^ 1] = 4096.0 / get2();
@@ -4679,6 +5079,10 @@
fseek (ifp, get4()+base, SEEK_SET);
parse_exif (base);
break;
+ case 34853: /* GPSInfo tag */
+ fseek (ifp, get4()+base, SEEK_SET);
+ parse_gps (base);
+ break;
case 34675: /* InterColorProfile */
case 50831: /* AsShotICCProfile */
profile_offset = ftell(ifp);
@@ -4688,15 +5092,15 @@
kodak_cbpp = get4();
break;
case 37386: /* FocalLength */
- focal_len = getrat();
+ focal_len = getreal(type);
break;
case 37393: /* ImageNumber */
shot_order = getint(type);
break;
case 37400: /* old Kodak KDC tag */
for (raw_color = i=0; i < 3; i++) {
- getrat();
- FORC3 rgb_cam[i][c] = getrat();
+ getreal(type);
+ FORC3 rgb_cam[i][c] = getreal(type);
}
break;
case 46275: /* Imacon tags */
@@ -4712,6 +5116,11 @@
width = raw_width - left_margin - (get4() & 7);
top_margin = get4() & 7;
height = raw_height - top_margin - (get4() & 7);
+ if (raw_width == 7262) {
+ height = 5444;
+ width = 7244;
+ left_margin = 7;
+ }
fseek (ifp, 52, SEEK_CUR);
FORC3 cam_mul[c] = getreal(11);
fseek (ifp, 114, SEEK_CUR);
@@ -4720,6 +5129,13 @@
if (flip % 180 == 90) SWAP(width,height);
filters = flip = 0;
}
+ sprintf (model, "Ixpress %d-Mp", height*width/1000000);
+ load_raw = &CLASS imacon_full_load_raw;
+ if (filters) {
+ if (left_margin & 1) filters = 0x61616161;
+ load_raw = &CLASS unpacked_load_raw;
+ }
+ maximum = 0xffff;
break;
case 50454: /* Sinar tag */
case 50455:
@@ -4730,6 +5146,17 @@
sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2);
free (cbuf);
break;
+ case 50459: /* Hasselblad tag */
+ i = order;
+ j = ftell(ifp);
+ c = tiff_nifds;
+ order = get2();
+ fseek (ifp, j+(get2(),get4()), SEEK_SET);
+ parse_tiff_ifd (j);
+ maximum = 0xffff;
+ tiff_nifds = c;
+ order = i;
+ break;
case 50706: /* DNGVersion */
FORC4 dng_version = (dng_version << 8) + fgetc(ifp);
break;
@@ -4764,36 +5191,34 @@
maximum = getint(type);
break;
case 50718: /* DefaultScale */
- pixel_aspect = getrat();
- pixel_aspect /= getrat();
+ pixel_aspect = getreal(type);
+ pixel_aspect /= getreal(type);
break;
case 50721: /* ColorMatrix1 */
case 50722: /* ColorMatrix2 */
FORCC for (j=0; j < 3; j++)
- cm[c][j] = getrat();
+ cm[c][j] = getreal(type);
use_cm = 1;
break;
case 50723: /* CameraCalibration1 */
case 50724: /* CameraCalibration2 */
for (i=0; i < colors; i++)
- FORCC cc[i][c] = getrat();
+ FORCC cc[i][c] = getreal(type);
case 50727: /* AnalogBalance */
- FORCC ab[c] = getrat();
+ FORCC ab[c] = getreal(type);
break;
case 50728: /* AsShotNeutral */
FORCC asn[c] = getreal(type);
break;
case 50729: /* AsShotWhiteXY */
- xyz[0] = getrat();
- xyz[1] = getrat();
+ xyz[0] = getreal(type);
+ xyz[1] = getreal(type);
xyz[2] = 1 - xyz[0] - xyz[1];
FORC3 xyz[c] /= d65_white[c];
break;
case 50740: /* DNGPrivateData */
if (dng_version) break;
- i = order;
parse_minolta (j = get4()+base);
- order = i;
fseek (ifp, j, SEEK_SET);
parse_tiff_ifd (base);
break;
@@ -4873,6 +5298,7 @@
for (i=0; i < tiff_nifds; i++) {
if (max_samp < tiff_ifd[i].samples)
max_samp = tiff_ifd[i].samples;
+ if (max_samp > 3) max_samp = 3;
if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) &&
tiff_ifd[i].width*tiff_ifd[i].height > raw_width*raw_height) {
raw_width = tiff_ifd[i].width;
@@ -4882,7 +5308,6 @@
data_offset = tiff_ifd[i].offset;
tiff_flip = tiff_ifd[i].flip;
tiff_samples = tiff_ifd[i].samples;
- fuji_secondary = tiff_samples == 2;
raw = i;
}
}
@@ -4894,6 +5319,8 @@
switch (tiff_bps) {
case 8: load_raw = &CLASS eight_bit_load_raw; break;
case 12: load_raw = &CLASS packed_12_load_raw;
+ if (!strncmp(make,"NIKON",5))
+ load_raw = &CLASS nikon_load_raw;
if (strncmp(make,"PENTAX",6)) break;
case 14:
case 16: load_raw = &CLASS unpacked_load_raw; break;
@@ -4907,8 +5334,14 @@
load_raw = &CLASS lossless_jpeg_load_raw; break;
case 262:
load_raw = &CLASS kodak_262_load_raw; break;
+ case 32767:
+ load_raw = &CLASS sony_arw2_load_raw; break;
+ case 32769:
+ load_raw = &CLASS nikon_load_raw; break;
case 32773:
load_raw = &CLASS packed_12_load_raw; break;
+ case 34713:
+ load_raw = &CLASS nikon_compressed_load_raw; break;
case 65535:
load_raw = &CLASS pentax_k10_load_raw; break;
case 65000:
@@ -4917,10 +5350,14 @@
case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0; break;
case 32803: load_raw = &CLASS kodak_65000_load_raw;
}
+ case 32867: break;
+ default: is_raw = 0;
}
if (!dng_version && tiff_samples == 3)
if (tiff_ifd[raw].bytes && tiff_bps != 14 && tiff_bps != 2048)
is_raw = 0;
+ if (!dng_version && tiff_bps == 8 && tiff_compress == 1 &&
+ tiff_ifd[raw].phint == 1) is_raw = 0;
for (i=0; i < tiff_nifds; i++)
if (i != raw && tiff_ifd[i].samples == max_samp &&
tiff_ifd[i].width * tiff_ifd[i].height / SQR(tiff_ifd[i].bps+1) >
@@ -4954,6 +5391,7 @@
void CLASS parse_minolta (int base)
{
int save, tag, len, offset, high=0, wide=0, i, c;
+ short sorder=order;
fseek (ifp, base, SEEK_SET);
if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return;
@@ -4982,6 +5420,7 @@
}
raw_height = high;
raw_width = wide;
+ order = sorder;
}
/*
@@ -5079,6 +5518,8 @@
if ((((type >> 8) + 8) | 8) == 0x38)
parse_ciff (ftell(ifp), len); /* Parse a sub-table */
+ if (type == 0x0810)
+ fread (artist, 64, 1, ifp);
if (type == 0x080a) {
fread (make, 64, 1, ifp);
fseek (ifp, strlen(make) - 63, SEEK_CUR);
@@ -5261,7 +5702,7 @@
romm_coeff (romm_cam);
break;
case 0x107:
- FORC3 cam_mul[c] = pre_mul[c] = getreal(11);
+ FORC3 cam_mul[c] = getreal(11);
break;
case 0x108: raw_width = data; break;
case 0x109: raw_height = data; break;
@@ -5404,6 +5845,55 @@
if (ver == 9) load_raw = &CLASS smal_v9_load_raw;
}
+void CLASS parse_cine()
+{
+ unsigned off_head, off_setup, off_image, i;
+
+ order = 0x4949;
+ fseek (ifp, 4, SEEK_SET);
+ is_raw = get2() == 2;
+ fseek (ifp, 14, SEEK_CUR);
+ is_raw *= get4();
+ off_head = get4();
+ off_setup = get4();
+ off_image = get4();
+ timestamp = get4();
+ if ((i = get4())) timestamp = i;
+ fseek (ifp, off_head+4, SEEK_SET);
+ raw_width = get4();
+ raw_height = get4();
+ switch (get2(),get2()) {
+ case 8: load_raw = &CLASS eight_bit_load_raw; break;
+ case 16: load_raw = &CLASS unpacked_load_raw;
+ }
+ fseek (ifp, off_setup+792, SEEK_SET);
+ strcpy (make, "CINE");
+ sprintf (model, "%d", get4());
+ fseek (ifp, 12, SEEK_CUR);
+ switch ((i=get4()) & 0xffffff) {
+ case 3: filters = 0x94949494; break;
+ case 4: filters = 0x49494949; break;
+ default: is_raw = 0;
+ }
+ fseek (ifp, 72, SEEK_CUR);
+ switch ((get4()+3600) % 360) {
+ case 270: flip = 4; break;
+ case 180: flip = 1; break;
+ case 90: flip = 7; break;
+ case 0: flip = 2;
+ }
+ cam_mul[0] = getreal(11);
+ cam_mul[2] = getreal(11);
+ maximum = ~(-1 << get4());
+ fseek (ifp, 668, SEEK_CUR);
+ shutter = get4()/1000000000.0;
+ fseek (ifp, off_image, SEEK_SET);
+ if (shot_select < is_raw)
+ fseek (ifp, shot_select*8, SEEK_CUR);
+ data_offset = (INT64) get4() + 8;
+ data_offset += (INT64) get4() << 32;
+}
+
char * CLASS foveon_gets (int offset, char *str, int len)
{
int i;
@@ -5508,6 +5998,8 @@
const char *prefix;
short black, trans[12];
} table[] = {
+ { "Apple QuickTake", 0, /* DJC */
+ { 17576,-3191,-3318,5210,6733,-1942,9031,1280,-124 } },
{ "Canon EOS D2000", 0,
{ 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } },
{ "Canon EOS D6000", 0,
@@ -5524,14 +6016,20 @@
{ 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } },
{ "Canon EOS 30D", 0,
{ 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } },
+ { "Canon EOS 40D", 0,
+ { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } },
{ "Canon EOS 350D", 0,
{ 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } },
{ "Canon EOS 400D", 0,
{ 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } },
+ { "Canon EOS-1Ds Mark III", 0,
+ { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } },
{ "Canon EOS-1Ds Mark II", 0,
{ 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } },
{ "Canon EOS-1D Mark II N", 0,
{ 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } },
+ { "Canon EOS-1D Mark III", 0,
+ { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } },
{ "Canon EOS-1D Mark II", 0,
{ 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } },
{ "Canon EOS-1DS", 0,
@@ -5554,6 +6052,8 @@
{ 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
{ "Canon PowerShot G6", 0,
{ 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
+ { "Canon PowerShot G9", 0,
+ { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } },
{ "Canon PowerShot Pro1", 0,
{ 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } },
{ "Canon PowerShot Pro70", 34,
@@ -5576,8 +6076,18 @@
{ 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } },
{ "Canon PowerShot A620", 0, /* DJC */
{ 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } },
+ { "Canon PowerShot A640", 0, /* DJC */
+ { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } },
+ { "Canon PowerShot A650", 0, /* DJC */
+ { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } },
{ "Canon PowerShot S3 IS", 0, /* DJC */
{ 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } },
+ { "CINE 650", 0,
+ { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
+ { "CINE 660", 0,
+ { 3390,480,-500,-800,3610,340,-550,2336,1192 } },
+ { "CINE", 0,
+ { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } },
{ "Contax N Digital", 0,
{ 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } },
{ "EPSON R-D1", 0,
@@ -5597,7 +6107,7 @@
{ "FUJIFILM FinePix S3Pro", 0,
{ 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
{ "FUJIFILM FinePix S5Pro", 0,
- { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } },
+ { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } },
{ "FUJIFILM FinePix S5000", 0,
{ 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
{ "FUJIFILM FinePix S5100", 0,
@@ -5620,10 +6130,12 @@
{ 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
{ "FUJIFILM FinePix S9600", 0,
{ 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } },
+ { "FUJIFILM IS-1", 0,
+ { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } },
{ "Imacon Ixpress", 0, /* DJC */
{ 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } },
- { "KODAK NC2000", 0, /* DJC */
- { 16475,-6903,-1218,-851,10375,477,2505,-7,1020 } },
+ { "KODAK NC2000", 0,
+ { 13891,-6055,-803,-465,9919,642,2121,82,1291 } },
{ "Kodak DCS315C", 8,
{ 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } },
{ "Kodak DCS330C", 8,
@@ -5670,6 +6182,8 @@
{ 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
{ "Leaf Valeo 6", 0,
{ 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } },
+ { "Leaf Aptus 54S", 0,
+ { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } },
{ "Leaf Aptus 65", 0,
{ 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } },
{ "Leaf Aptus 75", 0,
@@ -5710,6 +6224,8 @@
{ 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } },
{ "NIKON D2X", 0,
{ 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
+ { "NIKON D40X", 0,
+ { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } },
{ "NIKON D40", 0,
{ 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } },
{ "NIKON D50", 0,
@@ -5720,10 +6236,16 @@
{ 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } },
{ "NIKON D200", 0,
{ 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } },
+ { "NIKON D300", 0,
+ { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } },
+ { "NIKON D3", 0,
+ { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } },
{ "NIKON E950", 0, /* DJC */
{ -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } },
{ "NIKON E995", 0, /* copied from E5000 */
{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
+ { "NIKON E2100", 0, /* copied from Z2, new white balance */
+ { 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} },
{ "NIKON E2500", 0,
{ -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } },
{ "NIKON E4300", 0, /* copied from Minolta DiMAGE Z2 */
@@ -5762,10 +6284,16 @@
{ 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } },
{ "OLYMPUS E-330", 0,
{ 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } },
+ { "OLYMPUS E-3", 0,
+ { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } },
{ "OLYMPUS E-400", 0,
{ 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } },
+ { "OLYMPUS E-410", 0,
+ { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } },
{ "OLYMPUS E-500", 0,
{ 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } },
+ { "OLYMPUS E-510", 0,
+ { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } },
{ "OLYMPUS SP350", 0,
{ 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } },
{ "OLYMPUS SP3", 0,
@@ -5774,6 +6302,10 @@
{ 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
{ "OLYMPUS SP510UZ", 0,
{ 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } },
+ { "OLYMPUS SP550UZ", 0,
+ { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } },
+ { "OLYMPUS SP560UZ", 0,
+ { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } },
{ "PENTAX *ist DL2", 0,
{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
{ "PENTAX *ist DL", 0,
@@ -5790,10 +6322,14 @@
{ 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } },
{ "Panasonic DMC-FZ8", 0,
{ 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } },
+ { "Panasonic DMC-FZ18", 0,
+ { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } },
{ "Panasonic DMC-FZ30", 0,
{ 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
{ "Panasonic DMC-FZ50", 0, /* aka "LEICA V-LUX1" */
{ 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
+ { "Panasonic DMC-L10", 0,
+ { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } },
{ "Panasonic DMC-L1", 0, /* aka "LEICA DIGILUX 3" */
{ 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } },
{ "Panasonic DMC-LC1", 0, /* aka "LEICA DIGILUX 2" */
@@ -5802,6 +6338,14 @@
{ 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
{ "Panasonic DMC-LX2", 0, /* aka "LEICA D-LUX3" */
{ 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
+ { "Phase One H 20", 0, /* DJC */
+ { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } },
+ { "Phase One P 2", 0,
+ { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } },
+ { "Phase One P 30", 0,
+ { 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } },
+ { "Phase One P 45", 0,
+ { 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } },
{ "SAMSUNG GX-1", 0,
{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
{ "Sinar", 0, /* DJC */
@@ -5813,7 +6357,13 @@
{ "SONY DSC-V3", 0,
{ 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } },
{ "SONY DSLR-A100", 0,
- { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } }
+ { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } },
+ { "SONY DSLR-A200", 0,
+ { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
+ { "SONY DSLR-A350", 0, /* copied from above */
+ { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } },
+ { "SONY DSLR-A700", 254,
+ { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } }
};
double cam_xyz[4][3];
char name[130];
@@ -5886,11 +6436,14 @@
{ 62464, "Kodak", "DC20" ,0 },
{ 124928, "Kodak", "DC20" ,0 },
{ 1652736, "Kodak", "DCS200" ,0 },
+ { 4159302, "Kodak", "C330" ,0 },
+ { 4162462, "Kodak", "C330" ,0 },
{ 311696, "ST Micro", "STV680 VGA" ,0 }, /* SPYz */
{ 614400, "Kodak", "KAI-0340" ,0 },
{ 787456, "Creative", "PC-CAM 600" ,0 },
{ 1138688, "Minolta", "RD175" ,0 },
{ 3840000, "Foculus", "531C" ,0 },
+ { 786432, "AVT", "F-080C" ,0 },
{ 1447680, "AVT", "F-145C" ,0 },
{ 1920000, "AVT", "F-201C" ,0 },
{ 5067304, "AVT", "F-510C" ,0 },
@@ -5902,10 +6455,14 @@
{ 6624000, "Pixelink", "A782" ,0 },
{ 13248000, "Pixelink", "A782" ,0 },
{ 6291456, "RoverShot","3320AF" ,0 },
+ { 6553440, "Canon", "PowerShot A460",0 },
+ { 6653280, "Canon", "PowerShot A530",0 },
{ 657312...
[truncated message content] |