summaryrefslogtreecommitdiff
path: root/dcraw
diff options
context:
space:
mode:
authorHubert Figuiere <hub@figuiere.net>2007-04-08 13:06:23 -0400
committerHubert Figuiere <hub@figuiere.net>2007-04-08 13:06:23 -0400
commitd4e186d332cd790372ef2952e3ffcef5f30a23d1 (patch)
treeddaeb605ed7bf559a9a8ca55b24cfa9407c4f963 /dcraw
parent690b5f6e6bf9c3f5eedceeb5f9e722f0b4ac04b2 (diff)
update dcraw reference code
Diffstat (limited to 'dcraw')
-rw-r--r--dcraw/dcraw.c,v2495
1 files changed, 2024 insertions, 471 deletions
diff --git a/dcraw/dcraw.c,v b/dcraw/dcraw.c,v
index 51c4e3d..6584cde 100644
--- a/dcraw/dcraw.c,v
+++ b/dcraw/dcraw.c,v
@@ -1,10 +1,100 @@
-head 1.359;
+head 1.377;
access;
symbols;
locks; strict;
comment @ * @;
+1.377
+date 2007.03.25.22.56.19; author dcoffin; state Exp;
+branches;
+next 1.376;
+
+1.376
+date 2007.03.19.21.09.00; author dcoffin; state Exp;
+branches;
+next 1.375;
+
+1.375
+date 2007.03.17.05.18.22; author dcoffin; state Exp;
+branches;
+next 1.374;
+
+1.374
+date 2007.03.15.05.19.10; author dcoffin; state Exp;
+branches;
+next 1.373;
+
+1.373
+date 2007.03.14.20.30.19; author dcoffin; state Exp;
+branches;
+next 1.372;
+
+1.372
+date 2007.03.13.05.04.22; author dcoffin; state Exp;
+branches;
+next 1.371;
+
+1.371
+date 2007.03.07.23.37.58; author dcoffin; state Exp;
+branches;
+next 1.370;
+
+1.370
+date 2007.03.02.17.40.15; author dcoffin; state Exp;
+branches;
+next 1.369;
+
+1.369
+date 2007.02.27.02.11.06; author dcoffin; state Exp;
+branches;
+next 1.368;
+
+1.368
+date 2007.02.25.03.09.54; author dcoffin; state Exp;
+branches;
+next 1.367;
+
+1.367
+date 2007.02.24.22.10.59; author dcoffin; state Exp;
+branches;
+next 1.366;
+
+1.366
+date 2007.02.22.16.50.08; author dcoffin; state Exp;
+branches;
+next 1.365;
+
+1.365
+date 2007.02.12.22.55.47; author dcoffin; state Exp;
+branches;
+next 1.364;
+
+1.364
+date 2007.01.21.00.41.17; author dcoffin; state Exp;
+branches;
+next 1.363;
+
+1.363
+date 2007.01.18.23.57.32; author dcoffin; state Exp;
+branches;
+next 1.362;
+
+1.362
+date 2007.01.09.02.06.51; author dcoffin; state Exp;
+branches;
+next 1.361;
+
+1.361
+date 2007.01.02.03.51.27; author dcoffin; state Exp;
+branches;
+next 1.360;
+
+1.360
+date 2006.12.22.03.56.43; author dcoffin; state Exp;
+branches;
+next 1.359;
+
1.359
date 2006.12.14.15.40.47; author dcoffin; state Exp;
branches;
@@ -1828,37 +1918,36 @@ desc
@
-1.359
+1.377
log
-@Added the Kodak DCS200 and Canon PowerShots A620 and S3 IS.
+@Better detect and reject non-raw TIFFs.
@
text
@/*
dcraw.c -- Dave Coffin's raw photo decoder
- Copyright 1997-2006 by Dave Coffin, dcoffin a cybercom o net
+ Copyright 1997-2007 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.
- Attention! Some parts of this program are restricted under the
- terms of the GNU General Public License. Such code is enclosed
- in "BEGIN GPL BLOCK" and "END GPL BLOCK" declarations.
- Any code not declared GPL is free for all uses.
+ 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.
- Starting in Revision 1.237, the code to support Foveon cameras
- is under GPL.
+ The functions that process Foveon images have been RESTRICTED
+ since Revision 1.237. All other code remains free for all uses.
- To lawfully redistribute dcraw.c, you must either (a) include
- full source code for all executable files containing restricted
- functions, (b) remove these functions, re-implement them, or
- copy them from an earlier, non-GPL Revision of dcraw.c, or (c)
- purchase a license from the author.
+ *If you have not modified dcraw.c in any way, a link to my
+ homepage qualifies as "full source code".
$Revision$
$Date$
*/
-#define VERSION "8.46"
+#define VERSION "8.69"
#define _GNU_SOURCE
#define _USE_MATH_DEFINES
@@ -1883,6 +1972,12 @@ text
#ifndef NO_LCMS
#include <lcms.h>
#endif
+#ifdef LOCALEDIR
+#include <libintl.h>
+#define _(String) gettext(String)
+#else
+#define _(String) (String)
+#endif
#ifdef __CYGWIN__
#include <io.h>
@@ -1922,22 +2017,23 @@ typedef unsigned short ushort;
*/
FILE *ifp;
short order;
-char *ifname, make[64], model[72], model2[64], *meta_data, cdesc[5];
+char *ifname, make[64], model[64], model2[64], *meta_data, cdesc[5];
float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len;
time_t timestamp;
-unsigned shot_order, kodak_cbpp, filters, unique_id, *oprof;
+unsigned shot_order, kodak_cbpp, filters, exif_cfa, unique_id, *oprof;
int profile_offset, profile_length;
int thumb_offset, thumb_length, thumb_width, thumb_height, thumb_misc;
int data_offset, strip_offset, curve_offset, meta_offset, meta_length;
int tiff_nifds, tiff_flip, tiff_bps, tiff_compress, tile_length;
int raw_height, raw_width, top_margin, left_margin;
int height, width, fuji_width, colors, tiff_samples;
-int black, maximum, raw_color, use_gamma;
-int iheight, iwidth, shrink, flip, xmag, ymag;
-int zero_after_ff, is_raw, dng_version, is_foveon;
+int black, maximum, mix_green, raw_color, use_gamma;
+int iheight, iwidth, shrink, flip;
+double pixel_aspect;
+int zero_after_ff, is_raw, dng_version, is_foveon, data_error;
ushort (*image)[4], white[8][8], curve[0x1000], cr2_slice[3];
-float bright=1, user_mul[4]={0,0,0,0}, sigma_d=0, sigma_r=0;
-int four_color_rgb=0, document_mode=0, highlight=0;
+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;
@@ -2070,10 +2166,22 @@ char *my_memmem (char *haystack, size_t haystacklen,
void CLASS merror (void *ptr, char *where)
{
if (ptr) return;
- fprintf (stderr, "%s: Out of memory in %s\n", ifname, where);
+ fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where);
longjmp (failure, 1);
}
+void CLASS derror()
+{
+ if (!data_error) {
+ fprintf (stderr, "%s: ", ifname);
+ if (feof(ifp))
+ fprintf (stderr,_("Unexpected end of file\n"));
+ else
+ fprintf (stderr,_("Corrupt data near 0x%lx\n"), ftell(ifp));
+ }
+ data_error = 1;
+}
+
ushort CLASS sget2 (uchar *s)
{
if (order == 0x4949) /* "II" means little-endian */
@@ -2144,7 +2252,7 @@ double CLASS getreal (int type)
void CLASS read_shorts (ushort *pixel, int count)
{
- fread (pixel, 2, count, ifp);
+ if (fread (pixel, 2, count, ifp) < count) derror();
if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
swab (pixel, pixel, count*2);
}
@@ -2274,7 +2382,7 @@ void CLASS canon_600_load_raw()
{ { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } };
for (irow=row=0; irow < height; irow++) {
- fread (data, raw_width * 10 / 8, 1, ifp);
+ if (fread (data, 1, raw_width*5/4, ifp) < raw_width*5/4) derror();
for (dp=data, pix=pixel; dp < data+1120; dp+=10, pix+=8) {
pix[0] = (dp[0] << 2) + (dp[1] >> 6 );
pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3);
@@ -2359,9 +2467,9 @@ unsigned CLASS getbits (int nbits)
return bitbuf = vbits = reset = 0;
if (nbits == 0 || reset) return 0;
while (vbits < nbits) {
- c = fgetc(ifp);
+ if ((c = fgetc(ifp)) == EOF) derror();
if ((reset = zero_after_ff && c == 0xff && fgetc(ifp))) return 0;
- bitbuf = (bitbuf << 8) + c;
+ bitbuf = (bitbuf << 8) + (uchar) c;
vbits += 8;
}
vbits -= nbits;
@@ -2409,7 +2517,7 @@ uchar * CLASS make_decoder (const uchar *source, int level)
if (level==0) leaf=0;
cur = free_decode++;
if (free_decode > first_decode+2048) {
- fprintf (stderr, "%s: decoder table overflow\n", ifname);
+ fprintf (stderr,_("%s: decoder table overflow\n"), ifname);
longjmp (failure, 2);
}
for (i=next=0; i <= leaf && next < 16; )
@@ -2514,7 +2622,7 @@ int CLASS canon_has_lowbits()
void CLASS canon_compressed_load_raw()
{
ushort *pixel, *prow;
- int lowbits, i, row, r, col, save, val;
+ int nblocks, lowbits, i, row, r, col, save, val;
unsigned irow, icol;
struct decode *decode, *dindex;
int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2];
@@ -2529,7 +2637,8 @@ void CLASS canon_compressed_load_raw()
zero_after_ff = 1;
getbits(-1);
for (row=0; row < raw_height; row+=8) {
- for (block=0; block < raw_width >> 3; block++) {
+ nblocks = MIN (8, raw_height-row) * raw_width >> 6;
+ for (block=0; block < nblocks; block++) {
memset (diffbuf, 0, sizeof diffbuf);
decode = first_decode;
for (i=0; i < 64; i++ ) {
@@ -2552,7 +2661,8 @@ void CLASS canon_compressed_load_raw()
for (i=0; i < 64; i++ ) {
if (pnum++ % raw_width == 0)
base[0] = base[1] = 512;
- pixel[(block << 6) + i] = ( base[i & 1] += diffbuf[i] );
+ if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10)
+ derror();
}
}
if (lowbits) {
@@ -2667,7 +2777,8 @@ void CLASS ljpeg_row (int jrow, struct jhead *jh)
for (col=0; col < jh->wide; col++)
for (c=0; c < jh->clrs; c++) {
diff = ljpeg_diff (jh->huff[c]);
- *outp = col ? outp[-jh->clrs]+diff : (jh->vpred[c] += diff);
+ *outp = diff = col ? outp[-jh->clrs]+diff : (jh->vpred[c] += diff);
+ if (diff >> jh->bits) derror();
outp++;
}
}
@@ -2696,6 +2807,8 @@ void CLASS lossless_jpeg_load_raw()
row = jidx / cr2_slice[1+j];
col = jidx % cr2_slice[1+j] + i*cr2_slice[1];
}
+ if (raw_width == 3984 && (col -= 2) < 0)
+ col += (row--,raw_width);
if ((unsigned) (row-top_margin) < height) {
if ((unsigned) (col-left_margin) < width) {
BAYER(row-top_margin,col-left_margin) = val;
@@ -2814,6 +2927,7 @@ void CLASS pentax_k10_load_raw()
hpred[col & 1] += diff;
if (col < width)
BAYER(row,col) = hpred[col & 1];
+ if (hpred[col & 1] >> 12) derror();
}
}
@@ -2847,9 +2961,8 @@ void CLASS nikon_compressed_load_raw()
} else
hpred[col & 1] += diff;
if ((unsigned) (col-left_margin) >= width) continue;
- diff = hpred[col & 1];
- if (diff >= csize) diff = csize-1;
- BAYER(row,col-left_margin) = curve[diff];
+ if (hpred[col & 1] >= csize) derror();
+ else BAYER(row,col-left_margin) = curve[hpred[col & 1]];
}
free (curve);
}
@@ -2874,7 +2987,7 @@ void CLASS nikon_load_raw()
if ((unsigned) (col-left_margin) < width)
BAYER(row,col-left_margin) = i;
if (tiff_compress == 34713 && (col % 10) == 9)
- getbits(8);
+ if (getbits(8)) derror();
}
}
}
@@ -3024,14 +3137,16 @@ void CLASS nikon_e2100_load_raw()
void CLASS fuji_load_raw()
{
ushort *pixel;
- int row, col, r, c;
+ int wide, row, col, r, c;
fseek (ifp, (top_margin*raw_width + left_margin) * 2, SEEK_CUR);
- pixel = (ushort *) calloc (raw_width, sizeof *pixel);
+ wide = fuji_width << !fuji_layout;
+ pixel = (ushort *) calloc (wide, sizeof *pixel);
merror (pixel, "fuji_load_raw()");
for (row=0; row < raw_height; row++) {
- read_shorts (pixel, raw_width);
- for (col=0; col < fuji_width << !fuji_layout; col++) {
+ read_shorts (pixel, wide);
+ fseek (ifp, 2*(raw_width - wide), SEEK_CUR);
+ for (col=0; col < wide; col++) {
if (fuji_layout) {
r = fuji_width - 1 - col + (row >> 1);
c = col + ((row+1) >> 1);
@@ -3045,15 +3160,7 @@ void CLASS fuji_load_raw()
free (pixel);
}
-void CLASS jpeg_thumb (FILE *tfp)
-{
- char *thumb = (char *) malloc (thumb_length);
- merror (thumb, "jpeg_thumb()");
- fread (thumb, 1, thumb_length, ifp);
- thumb[0] = 0xff;
- fwrite (thumb, 1, thumb_length, tfp);
- free (thumb);
-}
+void CLASS jpeg_thumb (FILE *tfp);
void CLASS ppm_thumb (FILE *tfp)
{
@@ -3185,8 +3292,8 @@ void CLASS phase_one_correct()
float poly[8], num, cfrac, frac, mult[2], *yval[2];
ushort curve[0x10000], *xval[2];
- if (shrink || !meta_length) return;
- if (verbose) fprintf (stderr, "Phase One correction...\n");
+ if (half_size || !meta_length) return;
+ if (verbose) fprintf (stderr,_("Phase One correction...\n"));
fseek (ifp, meta_offset, SEEK_SET);
order = get2();
fseek (ifp, 6, SEEK_CUR);
@@ -3375,6 +3482,7 @@ void CLASS phase_one_load_raw_c()
pixel[col] = pred[col & 1] = ph1_bits(16);
else
pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1));
+ if (pred[col & 1] >> 16) derror();
if (ph1.format == 5 && pixel[col] < 256)
pixel[col] = curve[pixel[col]];
}
@@ -3418,11 +3526,25 @@ void CLASS leaf_hdr_load_raw()
}
}
+void CLASS unpacked_load_raw();
+
void CLASS sinar_4shot_load_raw()
{
ushort *pixel;
unsigned shot, row, col, r, c;
+ if ((shot = shot_select) || half_size) {
+ if (shot) shot--;
+ if (shot > 3) shot = 3;
+ fseek (ifp, data_offset + shot*4, SEEK_SET);
+ fseek (ifp, get4(), SEEK_SET);
+ unpacked_load_raw();
+ return;
+ }
+ free (image);
+ image = (ushort (*)[4])
+ calloc ((iheight=height)*(iwidth=width), sizeof *image);
+ merror (image, "sinar_4shot_load_raw()");
pixel = (ushort *) calloc (raw_width, sizeof *pixel);
merror (pixel, "sinar_4shot_load_raw()");
for (shot=0; shot < 4; shot++) {
@@ -3438,7 +3560,7 @@ void CLASS sinar_4shot_load_raw()
}
}
free (pixel);
- filters = 0;
+ shrink = filters = 0;
}
void CLASS imacon_full_load_raw()
@@ -3460,26 +3582,34 @@ void CLASS packed_12_load_raw()
for (col=0; col < width; col++)
BAYER(row,col) = getbits(12);
for (col = width*3/2; col < raw_width; col++)
- getbits(8);
+ if (getbits(8)) derror();
}
}
void CLASS unpacked_load_raw()
{
ushort *pixel;
- int row, col;
+ int row, col, bits=0;
+ while (1 << ++bits < maximum);
fseek (ifp, (top_margin*raw_width + left_margin) * 2, SEEK_CUR);
- pixel = (ushort *) calloc (raw_width, sizeof *pixel);
+ pixel = (ushort *) calloc (width, sizeof *pixel);
merror (pixel, "unpacked_load_raw()");
for (row=0; row < height; row++) {
- read_shorts (pixel, raw_width);
+ read_shorts (pixel, width);
+ fseek (ifp, 2*(raw_width - width), SEEK_CUR);
for (col=0; col < width; col++)
- BAYER2(row,col) = pixel[col];
+ if ((BAYER2(row,col) = pixel[col]) >> bits) derror();
}
free (pixel);
}
+void CLASS panasonic_load_raw()
+{
+ unpacked_load_raw();
+ remove_zeroes();
+}
+
void CLASS olympus_e300_load_raw()
{
uchar *data, *dp;
@@ -3491,9 +3621,10 @@ void CLASS olympus_e300_load_raw()
merror (data, "olympus_e300_load_raw()");
pixel = (ushort *) (data + dwide);
for (row=0; row < height; row++) {
- fread (data, 1, dwide, ifp);
+ if (fread (data, 1, dwide, ifp) < dwide) derror();
for (dp=data, pix=pixel; pix < pixel+raw_width; dp+=3, pix+=2) {
- if (((dp-data) & 15) == 15) dp++;
+ if (((dp-data) & 15) == 15)
+ if (*dp++) derror();
pix[0] = dp[1] << 8 | dp[0];
pix[1] = dp[2] << 4 | dp[1] >> 4;
}
@@ -3527,7 +3658,7 @@ void CLASS minolta_rd175_load_raw()
unsigned irow, box, row, col;
for (irow=0; irow < 1481; irow++) {
- fread (pixel, 1, 768, ifp);
+ if (fread (pixel, 1, 768, ifp) < 768) derror();
box = irow / 82;
row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2);
switch (irow) {
@@ -3557,7 +3688,7 @@ void CLASS eight_bit_load_raw()
pixel = (uchar *) calloc (raw_width, sizeof *pixel);
merror (pixel, "eight_bit_load_raw()");
for (row=0; row < height; row++) {
- fread (pixel, 1, raw_width, ifp);
+ if (fread (pixel, 1, raw_width, ifp) < raw_width) derror();
for (col=0; col < width; col++)
BAYER(row,col) = pixel[col];
}
@@ -3709,10 +3840,8 @@ void CLASS kodak_radc_load_raw()
for (x=0; x < width/2; x++) {
val = (buf[c][y+1][x] << 4) / mul[c];
if (val < 0) val = 0;
- if (c)
- BAYER(row+y*2+c-1,x*2+2-c) = val;
- else
- BAYER(row+r*2+y,x*2+y) = val;
+ if (c) BAYER(row+y*2+c-1,x*2+2-c) = val;
+ else BAYER(row+r*2+y,x*2+y) = val;
}
memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c);
}
@@ -3765,7 +3894,7 @@ void CLASS kodak_jpeg_load_raw()
if ((cinfo.output_width != width ) ||
(cinfo.output_height*2 != height ) ||
(cinfo.output_components != 3 )) {
- fprintf (stderr, "%s: incorrect JPEG dimensions\n", ifname);
+ fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), ifname);
jpeg_destroy_decompress (&cinfo);
longjmp (failure, 3);
}
@@ -3797,7 +3926,7 @@ void CLASS kodak_dc120_load_raw()
int row, shift, col;
for (row=0; row < height; row++) {
- fread (pixel, 848, 1, ifp);
+ if (fread (pixel, 1, 848, ifp) < 848) derror();
shift = row * mul[row & 3] + add[row & 3];
for (col=0; col < width; col++)
BAYER(row,col) = (ushort) pixel[(col + shift) % 848];
@@ -3815,7 +3944,7 @@ void CLASS kodak_easy_load_raw()
pixel = (uchar *) calloc (raw_width, sizeof *pixel);
merror (pixel, "kodak_easy_load_raw()");
for (row=0; row < height; row++) {
- fread (pixel, 1, raw_width, ifp);
+ 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)
@@ -3867,7 +3996,8 @@ void CLASS kodak_262_load_raw()
if (pi2 < 0) pi2 = pi1;
if (pi1 < 0 && col > 1) pi1 = pi2 = pi-2;
pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1;
- pixel[pi] = pred + ljpeg_diff (decode[chess]);
+ pixel[pi] = val = pred + ljpeg_diff (decode[chess]);
+ if (val >> 8) derror();
val = curve[pixel[pi++]];
if ((unsigned) (col-left_margin) < width)
BAYER(row,col-left_margin) = val;
@@ -3936,7 +4066,8 @@ void CLASS kodak_65000_load_raw()
len = MIN (256, width-col);
ret = kodak_65000_decode (buf, len);
for (i=0; i < len; i++)
- BAYER(row,col+i) = curve[ret ? buf[i] : (pred[i & 1] += buf[i])];
+ if ((BAYER(row,col+i) = curve[ret ? buf[i] :
+ (pred[i & 1] += buf[i])]) >> 12) derror();
}
}
@@ -3959,7 +4090,7 @@ void CLASS kodak_ycbcr_load_raw()
rgb[0] = rgb[1] + cr;
for (j=0; j < 2; j++)
for (k=0; k < 2; k++) {
- y[j][k] = y[j][k^1] + *bp++;
+ if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror();
ip = image[(row+j)*width + col+i+k];
FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)];
}
@@ -3979,7 +4110,7 @@ void CLASS kodak_rgb_load_raw()
kodak_65000_decode (buf, len*3);
memset (rgb, 0, sizeof rgb);
for (bp=buf, i=0; i < len; i++, ip+=4)
- FORC3 ip[c] = (rgb[c] += *bp++) & 0xfff;
+ FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror();
}
}
@@ -4029,12 +4160,13 @@ void CLASS sony_load_raw()
pixel = (ushort *) calloc (raw_width, sizeof *pixel);
merror (pixel, "sony_load_raw()");
for (row=0; row < height; row++) {
- fread (pixel, 2, raw_width, ifp);
+ if (fread (pixel, 2, raw_width, ifp) < raw_width) derror();
sony_decrypt ((unsigned int *) pixel, raw_width/2, !row, key);
for (col=9; col < left_margin; col++)
black += ntohs(pixel[col]);
for (col=0; col < width; col++)
- BAYER(row,col) = ntohs(pixel[col+left_margin]);
+ if ((BAYER(row,col) = ntohs(pixel[col+left_margin])) >> 14)
+ derror();
}
free (pixel);
if (left_margin > 9)
@@ -4057,7 +4189,7 @@ void CLASS sony_arw_load_raw()
diff = getbits(len);
if ((diff & (1 << (len-1))) == 0)
diff -= (1 << len) - 1;
- sum += diff;
+ if ((sum += diff) >> 12) derror();
if (row < height) BAYER(row,col) = sum;
}
}
@@ -4203,7 +4335,7 @@ void CLASS smal_v9_load_raw()
if (holes) fill_holes (holes);
}
-/* BEGIN GPL BLOCK */
+/* RESTRICTED code starts here */
void CLASS foveon_decoder (unsigned size, unsigned code)
{
@@ -4218,7 +4350,7 @@ void CLASS foveon_decoder (unsigned size, unsigned code)
}
cur = free_decode++;
if (free_decode > first_decode+2048) {
- fprintf (stderr, "%s: decoder table overflow\n", ifname);
+ fprintf (stderr,_("%s: decoder table overflow\n"), ifname);
longjmp (failure, 2);
}
if (code)
@@ -4292,9 +4424,9 @@ void CLASS foveon_load_camf()
void CLASS foveon_load_raw()
{
struct decode *dindex;
- short diff[1024], pred[3];
+ short diff[1024];
unsigned bitbuf=0;
- int fixed, row, col, bit=-1, c, i;
+ int pred[3], fixed, row, col, bit=-1, c, i;
fixed = get4();
read_shorts ((ushort *) diff, 1024);
@@ -4316,6 +4448,7 @@ void CLASS foveon_load_raw()
dindex = dindex->branch[bitbuf >> bit & 1];
}
pred[c] += diff[dindex->leaf];
+ if (pred[c] >> 16 && ~pred[c] >> 16) derror();
}
FORC3 image[row*width+col][c] = pred[c];
}
@@ -4377,7 +4510,7 @@ void * CLASS foveon_camf_matrix (int dim[3], const char *name)
mat[i] = sget4(dp + i*2) & 0xffff;
return mat;
}
- fprintf (stderr, "%s: \"%s\" matrix not found!\n", ifname, name);
+ fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), ifname, name);
return NULL;
}
@@ -4462,7 +4595,7 @@ void CLASS foveon_interpolate()
const char* cp;
if (verbose)
- fprintf (stderr, "Foveon interpolation...\n");
+ fprintf (stderr,_("Foveon interpolation...\n"));
foveon_fixed (dscr, 4, "DarkShieldColRange");
foveon_fixed (ppm[0][0], 27, "PostPolyMatrix");
@@ -4488,7 +4621,7 @@ void CLASS foveon_interpolate()
}
if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2)))
- { fprintf (stderr, "%s: Invalid white balance \"%s\"\n", ifname, model2);
+ { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2);
return; }
foveon_fixed (cam_xyz, 9, cp);
foveon_fixed (correct, 9,
@@ -4498,16 +4631,14 @@ void CLASS foveon_interpolate()
for (j=0; j < 3; j++)
FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j];
+ #define LAST(x,y) last[(i+x)%3][(c+y)%3]
+ for (i=0; i < 3; i++)
+ FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1);
+ #undef LAST
+ FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583;
sprintf (str, "%sRGBNeutral", model2);
if (foveon_camf_param ("IncludeBlocks", str))
foveon_fixed (div, 3, str);
- else {
- #define LAST(x,y) last[(i+x)%3][(c+y)%3]
- for (i=0; i < 3; i++)
- FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1);
- #undef LAST
- FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583;
- }
num = 0;
FORC3 if (num < div[c]) num = div[c];
FORC3 div[c] /= num;
@@ -4842,7 +4973,7 @@ void CLASS foveon_interpolate()
}
#undef image
-/* END GPL BLOCK */
+/* RESTRICTED code ends here */
/*
Seach from the current directory up to the root looking for
@@ -4895,7 +5026,7 @@ void CLASS bad_pixels()
BAYER2(row,col) = tot/n;
if (verbose) {
if (!fixed++)
- fprintf (stderr, "Fixed bad pixels at:");
+ fprintf (stderr,_("Fixed bad pixels at:"));
fprintf (stderr, " %d,%d", col, row);
}
}
@@ -4926,10 +5057,10 @@ void CLASS subtract (char *fname)
}
}
if (error || nd < 3) {
- fprintf (stderr, "%s is not a valid PGM file!\n", fname);
+ fprintf (stderr,_("%s is not a valid PGM file!\n"), fname);
fclose (fp); return;
} else if (dim[0] != width || dim[1] != height || dim[2] != 65535) {
- fprintf (stderr, "%s has the wrong dimensions!\n", fname);
+ fprintf (stderr,_("%s has the wrong dimensions!\n"), fname);
fclose (fp); return;
}
pixel = (ushort *) calloc (width, sizeof *pixel);
@@ -5089,25 +5220,110 @@ void CLASS colorcheck()
}
#endif
+void CLASS hat_transform (float *temp, float *base, int st, int size, int sc)
+{
+ int i;
+ for (i=0; i < sc; i++)
+ temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)];
+ for (; i+sc < size; i++)
+ temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)];
+ for (; i < size; i++)
+ temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))];
+}
+
+void CLASS wavelet_denoise()
+{
+ float *fimg, *temp, thold, mul[2], avg, diff;
+ int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast;
+ ushort *window[4];
+ static const float noise[] =
+ { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 };
+
+ if (verbose) fprintf (stderr,_("Wavelet denoising...\n"));
+
+ while (maximum << scale < 0x10000) scale++;
+ maximum <<= --scale;
+ black <<= scale;
+ size = iheight*iwidth;
+ fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg);
+ 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 */
+ for (i=0; i < size; i++)
+ fimg[i] = sqrt((unsigned) (image[i][c] << (scale+16)));
+ for (hpass=lev=0; lev < 5; lev++) {
+ lpass = size*((lev & 1)+1);
+ for (row=0; row < iheight; row++) {
+ hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev);
+ for (col=0; col < iwidth; col++)
+ fimg[lpass + row*iwidth + col] = temp[col] * 0.25;
+ }
+ for (col=0; col < iwidth; col++) {
+ hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev);
+ for (row=0; row < iheight; row++)
+ fimg[lpass + row*iwidth + col] = temp[row] * 0.25;
+ }
+ thold = threshold * noise[lev];
+ for (i=0; i < size; i++) {
+ fimg[hpass+i] -= fimg[lpass+i];
+ if (fimg[hpass+i] < -thold) fimg[hpass+i] += thold;
+ else if (fimg[hpass+i] > thold) fimg[hpass+i] -= thold;
+ else fimg[hpass+i] = 0;
+ if (hpass) fimg[i] += fimg[hpass+i];
+ }
+ hpass = lpass;
+ }
+ for (i=0; i < size; i++)
+ image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000);
+ }
+ if (filters && colors == 3) { /* pull G1 and G3 closer together */
+ for (row=0; row < 2; row++)
+ mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1];
+ for (i=0; i < 4; i++)
+ window[i] = (ushort *) fimg + width*i;
+ for (wlast=-1, row=1; row < height-1; row++) {
+ while (wlast < row+1) {
+ for (wlast++, i=0; i < 4; i++)
+ window[(i+3) & 3] = window[i];
+ for (col = FC(wlast,1) & 1; col < width; col+=2)
+ window[2][col] = BAYER(wlast,col);
+ }
+ thold = threshold/512;
+ for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) {
+ avg = ( window[0][col-1] + window[0][col+1] +
+ window[2][col-1] + window[2][col+1] - black*4 )
+ * mul[row & 1] + (window[1][col] - black) * 0.5 + black;
+ avg = avg < 0 ? 0 : sqrt(avg);
+ diff = sqrt(BAYER(row,col)) - avg;
+ if (diff < -thold) diff += thold;
+ else if (diff > thold) diff -= thold;
+ else diff = 0;
+ BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5);
+ }
+ }
+ }
+ free (fimg);
+}
+
void CLASS scale_colors()
{
- int row, col, x, y, c, val, sum[8];
+ int dblack, row, col, x, y, c, val, sum[8];
double dsum[8], dmin, dmax;
float scale_mul[4];
- maximum -= black;
if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) {
memset (dsum, 0, sizeof dsum);
- for (row=0; row < height-7; row += 8)
- for (col=0; col < width-7; col += 8) {
+ for (row=0; row < iheight-7; row += 8)
+ for (col=0; col < iwidth-7; col += 8) {
memset (sum, 0, sizeof sum);
for (y=row; y < row+8; y++)
for (x=col; x < col+8; x++)
FORC4 {
- val = image[y*width+x][c];
+ val = image[y*iwidth+x][c];
if (!val) continue;
- val -= black;
if (val > maximum-25) goto skip_block;
+ val -= black;
if (val < 0) val = 0;
sum[c] += val;
sum[c+4]++;
@@ -5132,11 +5348,14 @@ skip_block:
else if (cam_mul[0] && cam_mul[2])
memcpy (pre_mul, cam_mul, sizeof pre_mul);
else
- fprintf (stderr, "%s: Cannot use camera white balance.\n", ifname);
+ fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname);
}
if (user_mul[0])
memcpy (pre_mul, user_mul, sizeof pre_mul);
if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
+ dblack = black;
+ if (threshold) wavelet_denoise();
+ maximum -= black;
for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) {
if (dmin > pre_mul[c])
dmin = pre_mul[c];
@@ -5146,24 +5365,47 @@ skip_block:
if (!highlight) dmax = dmin;
FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;
if (verbose) {
- fprintf (stderr, "Scaling with black=%d, pre_mul[] =", black);
+ fprintf (stderr,_("Scaling with black %d, multipliers"), dblack);
FORC4 fprintf (stderr, " %f", pre_mul[c]);
fputc ('\n', stderr);
}
- for (row=0; row < height; row++)
- for (col=0; col < width; col++)
+ for (row=0; row < iheight; row++)
+ for (col=0; col < iwidth; col++)
FORC4 {
- val = image[row*width+col][c];
+ val = image[row*iwidth+col][c];
if (!val) continue;
val -= black;
val *= scale_mul[c];
- image[row*width+col][c] = CLIP(val);
+ image[row*iwidth+col][c] = CLIP(val);
}
- if (filters && colors == 3) {
- if (four_color_rgb) {
- colors++;
- FORC3 rgb_cam[c][3] = rgb_cam[c][1] /= 2;
+}
+
+void CLASS pre_interpolate()
+{
+ ushort (*img)[4];
+ int row, col, c;
+
+ if (shrink) {
+ if (half_size) {
+ height = iheight;
+ width = iwidth;
+ filters = 0;
} else {
+ img = (ushort (*)[4]) calloc (height*width, sizeof *img);
+ merror (img, "unshrink()");
+ for (row=0; row < height; row++)
+ for (col=0; col < width; col++) {
+ c = fc(row,col);
+ img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c];
+ }
+ free (image);
+ image = img;
+ shrink = 0;
+ }
+ }
+ if (filters && colors == 3) {
+ if ((mix_green = four_color_rgb)) colors++;
+ else {
for (row = FC(1,0) >> 1; row < height; row+=2)
for (col = FC(row,1) & 1; col < width; col+=2)
image[row*width+col][1] = image[row*width+col][3];
@@ -5200,7 +5442,7 @@ void CLASS lin_interpolate()
int c, i, x, y, row, col, shift, color;
ushort *pix;
- if (verbose) fprintf (stderr, "Bilinear interpolation...\n");
+ if (verbose) fprintf (stderr,_("Bilinear interpolation...\n"));
border_interpolate(1);
for (row=0; row < 16; row++)
@@ -5277,7 +5519,7 @@ void CLASS vng_interpolate()
int g, diff, thold, num, c;
lin_interpolate();
- if (verbose) fprintf (stderr, "VNG interpolation...\n");
+ if (verbose) fprintf (stderr,_("VNG interpolation...\n"));
if (filters == 1) prow = pcol = 15;
ip = (int *) calloc ((prow+1)*(pcol+1), 1280);
@@ -5371,37 +5613,6 @@ void CLASS vng_interpolate()
free (code[0][0]);
}
-void CLASS cam_to_cielab (ushort cam[4], float lab[3])
-{
- int c, i, j, k;
- float r, xyz[3];
- static float cbrt[0x10000], xyz_cam[3][4];
-
- if (cam == NULL) {
- for (i=0; i < 0x10000; i++) {
- r = i / 65535.0;
- cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
- }
- for (i=0; i < 3; i++)
- for (j=0; j < colors; j++)
- for (xyz_cam[i][j] = k=0; k < 3; k++)
- xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
- } else {
- xyz[0] = xyz[1] = xyz[2] = 0.5;
- FORCC {
- xyz[0] += xyz_cam[0][c] * cam[c];
- xyz[1] += xyz_cam[1][c] * cam[c];
- xyz[2] += xyz_cam[2][c] * cam[c];
- }
- xyz[0] = cbrt[CLIP((int) xyz[0])];
- xyz[1] = cbrt[CLIP((int) xyz[1])];
- xyz[2] = cbrt[CLIP((int) xyz[2])];
- lab[0] = 116 * xyz[1] - 16;
- lab[1] = 500 * (xyz[0] - xyz[1]);
- lab[2] = 200 * (xyz[1] - xyz[2]);
- }
-}
-
/*
Adaptive Homogeneity-Directed interpolation is based on
the work of Keigo Hirakawa, Thomas Parks, and Paul Lee.
@@ -5410,48 +5621,56 @@ void CLASS cam_to_cielab (ushort cam[4], float lab[3])
void CLASS ahd_interpolate()
{
- int i, j, top, left, row, col, tr, tc, fc, c, d, val, hm[2];
+ int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2];
ushort (*pix)[4], (*rix)[3];
static const int dir[4] = { -1, 1, -TS, TS };
unsigned ldiff[2][4], abdiff[2][4], leps, abeps;
- float flab[3];
+ float r, cbrt[0x10000], xyz[3], xyz_cam[3][4];
ushort (*rgb)[TS][TS][3];
- short (*lab)[TS][TS][3];
+ short (*lab)[TS][TS][3], (*lix)[3];
char (*homo)[TS][TS], *buffer;
- if (verbose) fprintf (stderr, "AHD interpolation...\n");
+ if (verbose) fprintf (stderr,_("AHD interpolation...\n"));
- border_interpolate(3);
+ for (i=0; i < 0x10000; i++) {
+ r = i / 65535.0;
+ cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
+ }
+ for (i=0; i < 3; i++)
+ for (j=0; j < colors; j++)
+ for (xyz_cam[i][j] = k=0; k < 3; k++)
+ xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
+
+ border_interpolate(5);
buffer = (char *) malloc (26*TS*TS); /* 1664 kB */
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=0; top < height; top += TS-6)
- for (left=0; left < width; left += TS-6) {
- memset (rgb, 0, 12*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 < 2 ? 2:top; row < top+TS && row < height-2; row++) {
- col = left + (FC(row,left) == 1);
- if (col < 2) col += 2;
- for (fc = FC(row,col); col < left+TS && col < width-2; col+=2) {
+ 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][fc] + pix[1][1]) * 2
- - pix[-2][fc] - pix[2][fc]) >> 2;
+ 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][fc] + pix[width][1]) * 2
- - pix[-2*width][fc] - pix[2*width][fc]) >> 2;
+ 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-1; row++)
- for (col=left+1; col < left+TS-1 && col < width-1; col++) {
+ 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]
@@ -5467,25 +5686,35 @@ void CLASS ahd_interpolate()
rix[0][c] = CLIP(val);
c = FC(row,col);
rix[0][c] = pix[0][c];
- cam_to_cielab (rix[0], flab);
- FORC3 lab[d][row-top][col-left][c] = 64*flab[c];
+ xyz[0] = xyz[1] = xyz[2] = 0.5;
+ FORCC {
+ xyz[0] += xyz_cam[0][c] * rix[0][c];
+ xyz[1] += xyz_cam[1][c] * rix[0][c];
+ xyz[2] += xyz_cam[2][c] * rix[0][c];
+ }
+ xyz[0] = cbrt[CLIP((int) xyz[0])];
+ xyz[1] = cbrt[CLIP((int) xyz[1])];
+ xyz[2] = cbrt[CLIP((int) xyz[2])];
+ lix[0][0] = 64 * (116 * xyz[1] - 16);
+ lix[0][1] = 64 * 500 * (xyz[0] - xyz[1]);
+ lix[0][2] = 64 * 200 * (xyz[1] - xyz[2]);
}
/* Build homogeneity maps from the CIELab images: */
memset (homo, 0, 2*TS*TS);
- for (row=top+2; row < top+TS-2 && row < height; row++) {
+ 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; col++) {
+ for (col=left+2; col < left+TS-2 && col < width-4; col++) {
tc = col-left;
- for (d=0; d < 2; d++)
- for (i=0; i < 4; i++)
- ldiff[d][i] = ABS(lab[d][tr][tc][0]-lab[d][tr][tc+dir[i]][0]);
+ 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]));
- for (d=0; d < 2; d++)
- for (i=0; i < 4; i++)
- if (i >> 1 == d || ldiff[d][i] <= leps)
- abdiff[d][i] = SQR(lab[d][tr][tc][1]-lab[d][tr][tc+dir[i]][1])
- + SQR(lab[d][tr][tc][2]-lab[d][tr][tc+dir[i]][2]);
abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]),
MAX(abdiff[1][2],abdiff[1][3]));
for (d=0; d < 2; d++)
@@ -5495,9 +5724,9 @@ void CLASS ahd_interpolate()
}
}
/* Combine the most homogenous pixels for the final result: */
- for (row=top+3; row < top+TS-3 && row < height-3; row++) {
+ 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-3; col++) {
+ 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++)
@@ -5515,63 +5744,6 @@ void CLASS ahd_interpolate()
}
#undef TS
-/*
- Bilateral Filtering was developed by C. Tomasi and R. Manduchi.
- */
-void CLASS bilateral_filter()
-{
- float (**window)[7], *kernel, scale_r, elut[1024], sum[5];
- int c, i, wr, ws, wlast, row, col, y, x;
- unsigned sep;
-
- if (verbose) fprintf (stderr, "Bilateral filtering...\n");
-
- wr = ceil(sigma_d*2); /* window radius */
- ws = 2*wr + 1; /* window size */
- window = (float (**)[7]) calloc ((ws+1)*sizeof *window +
- ws*width*sizeof **window + ws*sizeof *kernel, 1);
- merror (window, "bilateral_filter()");
- for (i=0; i <= ws; i++)
- window[i] = (float (*)[7]) (window+ws+1) + i*width;
- kernel = (float *) window[ws] + wr;
- for (i=-wr; i <= wr; i++)
- kernel[i] = 256 / (2*SQR(sigma_d)) * i*i + 0.25;
- scale_r = 256 / (2*SQR(sigma_r));
- for (i=0; i < 1024; i++)
- elut[i] = exp (-i/256.0);
-
- for (wlast=-1, row=0; row < height; row++) {
- while (wlast < row+wr) {
- wlast++;
- for (i=0; i <= ws; i++) /* rotate window rows */
- window[(ws+i) % (ws+1)] = window[i];
- if (wlast < height)
- for (col=0; col < width; col++) {
- FORCC window[ws-1][col][c] = image[wlast*width+col][c];
- cam_to_cielab (image[wlast*width+col], window[ws-1][col]+4);
- }
- }
- for (col=0; col < width; col++) {
- memset (sum, 0, sizeof sum);
- for (y=-wr; y <= wr; y++)
- if ((unsigned)(row+y) < height)
- for (x=-wr; x <= wr; x++)
- if ((unsigned)(col+x) < width) {
- sep = ( SQR(window[wr+y][col+x][4] - window[wr][col][4])
- + SQR(window[wr+y][col+x][5] - window[wr][col][5])
- + SQR(window[wr+y][col+x][6] - window[wr][col][6]) )
- * scale_r + kernel[y] + kernel[x];
- if (sep < 1024) {
- FORCC sum[c] += elut[sep] * window[wr+y][col+x][c];
- sum[4] += elut[sep];
- }
- }
- FORCC image[row*width+col][c] = sum[c]/sum[4];
- }
- }
- free (window);
-}
-
#define SCALE (4 >> shrink)
void CLASS recover_highlights()
{
@@ -5582,7 +5754,7 @@ void CLASS recover_highlights()
static const signed char dir[8][2] =
{ {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} };
- if (verbose) fprintf (stderr, "Highlight recovery...\n");
+ if (verbose) fprintf (stderr,_("Highlight recovery...\n"));
grow = pow (2, 4-highlight);
FORCC hsat[c] = 32000 * pre_mul[c];
@@ -5674,6 +5846,8 @@ void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen)
}
}
+int CLASS parse_tiff_ifd (int base);
+
void CLASS parse_makernote (int base)
{
static const uchar xlat[2][256] = {
@@ -5776,6 +5950,10 @@ void CLASS parse_makernote (int base)
}
if (tag == 0x10 && type == 4)
unique_id = get4();
+ if (tag == 0x11 && is_raw) {
+ fseek (ifp, get4()+base, SEEK_SET);
+ parse_tiff_ifd (base);
+ }
if (tag == 0x14 && len == 2560 && type == 7) {
fseek (ifp, 1248, SEEK_CUR);
goto get2_256;
@@ -5785,7 +5963,7 @@ void CLASS parse_makernote (int base)
if (tag == 0x1c) tag = 0x1017;
}
if (tag == 0x1d)
- while ((c = fgetc(ifp)))
+ while ((c = fgetc(ifp)) && c != EOF)
serial = serial*10 + (isdigit(c) ? c - '0' : c % 10);
if (tag == 0x81 && type == 4) {
data_offset = get4();
@@ -5895,7 +6073,7 @@ get2_256:
parse_thumb_note (base, 136, 137);
}
if (tag == 0x4001) {
- i = len == 582 ? 50 : len == 653 ? 68 : len == 796 ? 126 : 0;
+ i = len == 582 ? 50 : len == 653 ? 68 : 126;
fseek (ifp, i, SEEK_CUR);
get2_rggb:
FORC4 cam_mul[c ^ (c >> 1)] = get2();
@@ -5935,7 +6113,7 @@ void CLASS get_timestamp (int reversed)
void CLASS parse_exif (int base)
{
- unsigned kodak, entries, tag, type, len, save;
+ unsigned kodak, entries, tag, type, len, save, c;
double expo;
kodak = !strncmp(make,"EASTMAN",7);
@@ -5955,6 +6133,10 @@ void CLASS parse_exif (int base)
case 37500: parse_makernote (base); break;
case 40962: if (kodak) raw_width = get4(); break;
case 40963: if (kodak) raw_height = get4(); break;
+ case 41730:
+ if (get4() == 0x20002)
+ for (exif_cfa=c=0; c < 8; c+=2)
+ exif_cfa |= fgetc(ifp) * 0x01010101 << c;
}
fseek (ifp, save, SEEK_SET);
}
@@ -5980,7 +6162,8 @@ void CLASS parse_mos (int offset)
int skip, from, i, c, neut[4], planes=0, frot=0;
static const char *mod[] =
{ "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22",
- "","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65" };
+ "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65",
+ "Aptus 54S","Aptus 65S","Aptus 75S" };
float romm_cam[3][3];
fseek (ifp, offset, SEEK_SET);
@@ -6076,13 +6259,13 @@ void CLASS parse_kodak_ifd (int base)
void CLASS parse_minolta (int base);
-int CLASS parse_tiff_ifd (int base, int level)
+int CLASS parse_tiff_ifd (int base)
{
unsigned entries, tag, type, len, plen=16, save;
int ifd, use_cm=0, cfa, i, j, c, ima_len=0;
char software[64], *cbuf, *cp;
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, sx, sy;
+ 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 *buf, sony_offset=0, sony_length=0, sony_key=0;
struct jhead jh;
@@ -6187,7 +6370,7 @@ int CLASS parse_tiff_ifd (int base, int level)
while (len--) {
i = ftell(ifp);
fseek (ifp, get4()+base, SEEK_SET);
- if (parse_tiff_ifd (base, level+1)) break;
+ if (parse_tiff_ifd (base)) break;
fseek (ifp, i+4, SEEK_SET);
}
break;
@@ -6334,10 +6517,8 @@ guess_cfa_pc:
maximum = getint(type);
break;
case 50718: /* DefaultScale */
- sx = getrat();
- sy = getrat();
- if (sx > sy) xmag = sx / sy;
- else ymag = sy / sx;
+ pixel_aspect = getrat();
+ pixel_aspect /= getrat();
break;
case 50721: /* ColorMatrix1 */
case 50722: /* ColorMatrix2 */
@@ -6367,7 +6548,7 @@ guess_cfa_pc:
parse_minolta (j = get4()+base);
order = i;
fseek (ifp, j, SEEK_SET);
- parse_tiff_ifd (base, level+1);
+ parse_tiff_ifd (base);
break;
case 50752:
read_shorts (cr2_slice, 3);
@@ -6395,7 +6576,7 @@ guess_cfa_pc:
if ((ifp = tmpfile())) {
fwrite (buf, sony_length, 1, ifp);
fseek (ifp, 0, SEEK_SET);
- parse_tiff_ifd (-sony_offset, level);
+ parse_tiff_ifd (-sony_offset);
fclose (ifp);
}
ifp = sfp;
@@ -6429,7 +6610,7 @@ void CLASS parse_tiff (int base)
tiff_nifds = 0;
while ((doff = get4())) {
fseek (ifp, doff+base, SEEK_SET);
- if (parse_tiff_ifd (base, 0)) break;
+ if (parse_tiff_ifd (base)) break;
}
thumb_misc = 16;
if (thumb_offset) {
@@ -6465,6 +6646,8 @@ void CLASS parse_tiff (int base)
&CLASS unpacked_load_raw : &CLASS eight_bit_load_raw;
if (tiff_ifd[raw].bytes * 5 == raw_width * raw_height * 8)
load_raw = &CLASS olympus_e300_load_raw;
+ if (tiff_bps == 12 && tiff_ifd[raw].phint == 2)
+ load_raw = &CLASS olympus_cseries_load_raw;
break;
case 6: case 7: case 99:
load_raw = &CLASS lossless_jpeg_load_raw; break;
@@ -6481,8 +6664,9 @@ void CLASS parse_tiff (int base)
case 32803: load_raw = &CLASS kodak_65000_load_raw;
}
}
- if (tiff_samples == 3 && tiff_bps == 8)
- if (!dng_version) is_raw = 0;
+ if (!dng_version && tiff_samples == 3)
+ if (tiff_ifd[raw].bytes && tiff_bps != 14 && tiff_bps != 2048)
+ 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) >
@@ -6582,7 +6766,7 @@ void CLASS parse_external_jpeg()
if (strcmp (jname, ifname)) {
if ((ifp = fopen (jname, "rb"))) {
if (verbose)
- fprintf (stderr, "Reading metadata from %s...\n", jname);
+ fprintf (stderr,_("Reading metadata from %s ...\n"), jname);
parse_tiff (12);
thumb_offset = 0;
is_raw = 1;
@@ -6590,7 +6774,7 @@ void CLASS parse_external_jpeg()
}
}
if (!timestamp)
- fprintf (stderr, "Failed to read metadata from %s\n", jname);
+ fprintf (stderr,_("Failed to read metadata from %s\n"), jname);
free (jname);
ifp = save;
}
@@ -6763,6 +6947,38 @@ void CLASS parse_rollei()
write_thumb = &CLASS rollei_thumb;
}
+void CLASS parse_sinar_ia()
+{
+ int entries, off;
+ char str[8], *cp;
+
+ order = 0x4949;
+ fseek (ifp, 4, SEEK_SET);
+ entries = get4();
+ fseek (ifp, get4(), SEEK_SET);
+ while (entries--) {
+ off = get4(); get4();
+ fread (str, 8, 1, ifp);
+ if (!strcmp(str,"META")) meta_offset = off;
+ if (!strcmp(str,"THUMB")) thumb_offset = off;
+ if (!strcmp(str,"RAW0")) data_offset = off;
+ }
+ fseek (ifp, meta_offset+20, SEEK_SET);
+ fread (make, 64, 1, ifp);
+ make[63] = 0;
+ if ((cp = strchr(make,' '))) {
+ strcpy (model, cp+1);
+ *cp = 0;
+ }
+ raw_width = get2();
+ raw_height = get2();
+ load_raw = &CLASS unpacked_load_raw;
+ thumb_width = (get4(),get2());
+ thumb_height = get2();
+ write_thumb = &CLASS ppm_thumb;
+ maximum = 0x3fff;
+}
+
void CLASS parse_phase_one (int base)
{
unsigned entries, tag, type, len, data, save, i, c;
@@ -6853,10 +7069,8 @@ void CLASS parse_fuji (int offset)
FORC4 cam_mul[c ^ 1] = get2();
fseek (ifp, save+len, SEEK_SET);
}
- if (fuji_layout) {
- height *= 2;
- width /= 2;
- }
+ height <<= fuji_layout;
+ width >>= fuji_layout;
}
int CLASS parse_jpeg (int offset)
@@ -7103,10 +7317,12 @@ void CLASS adobe_coeff (char *make, char *model)
{ 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } },
{ "Canon PowerShot S70", 0,
{ 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } },
- { "Canon PowerShot A610", 0, /* copied from the S60 */
- { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } },
+ { "Canon PowerShot A610", 0, /* DJC */
+ { 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 S3 IS", 0, /* DJC */
+ { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } },
{ "Contax N Digital", 0,
{ 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } },
{ "EPSON R-D1", 0,
@@ -7125,6 +7341,8 @@ void CLASS adobe_coeff (char *make, char *model)
{ 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } },
{ "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 } },
{ "FUJIFILM FinePix S5000", 0,
{ 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } },
{ "FUJIFILM FinePix S5100", 0,
@@ -7135,6 +7353,8 @@ void CLASS adobe_coeff (char *make, char *model)
{ 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
{ "FUJIFILM FinePix S5600", 0,
{ 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } },
+ { "FUJIFILM FinePix S6", 0,
+ { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } },
{ "FUJIFILM FinePix S7000", 0,
{ 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } },
{ "FUJIFILM FinePix S9000", 0,
@@ -7233,6 +7453,8 @@ void CLASS adobe_coeff (char *make, char *model)
{ 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } },
{ "NIKON D2X", 0,
{ 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } },
+ { "NIKON D40", 0,
+ { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } },
{ "NIKON D50", 0,
{ 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } },
{ "NIKON D70", 0,
@@ -7293,6 +7515,8 @@ void CLASS adobe_coeff (char *make, char *model)
{ 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } },
{ "OLYMPUS SP500UZ", 0,
{ 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } },
+ { "OLYMPUS SP510UZ", 0,
+ { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } },
{ "PENTAX *ist DL2", 0,
{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
{ "PENTAX *ist DL", 0,
@@ -7304,18 +7528,20 @@ void CLASS adobe_coeff (char *make, char *model)
{ "PENTAX *ist D", 0,
{ 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } },
{ "PENTAX K10D", 0,
- { 28402,-6651,-983,-14699,32553,6467,-1746,1571,25283 } },
+ { 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } },
{ "PENTAX K1", 0,
{ 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } },
{ "Panasonic DMC-FZ30", 0,
{ 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } },
- { "Panasonic DMC-FZ50", 0,
+ { "Panasonic DMC-FZ50", 0, /* aka "LEICA V-LUX1" */
{ 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } },
- { "Panasonic DMC-LC1", 0,
+ { "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" */
{ 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } },
- { "Panasonic DMC-LX1", 0,
+ { "Panasonic DMC-LX1", 0, /* aka "LEICA D-LUX2" */
{ 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } },
- { "Panasonic DMC-LX2", 0,
+ { "Panasonic DMC-LX2", 0, /* aka "LEICA D-LUX3" */
{ 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } },
{ "SAMSUNG GX-1", 0,
{ 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } },
@@ -7442,7 +7668,7 @@ void CLASS identify()
{ 10979200, "CASIO", "EX-P700" ,1 },
{ 3178560, "PENTAX", "Optio S" ,1 },
{ 4841984, "PENTAX", "Optio S" ,1 },
- { 6114240, "PENTAX", "Optio S4" ,1 }, /* or S4i */
+ { 6114240, "PENTAX", "Optio S4" ,1 }, /* or S4i, CASIO EX-Z4 */
{ 12582980, "Sinar", "" ,0 },
{ 33292868, "Sinar", "" ,0 },
{ 44390468, "Sinar", "" ,0 } };
@@ -7452,7 +7678,7 @@ void CLASS identify()
"SAMSUNG" };
tiff_flip = flip = filters = -1; /* 0 is valid, so -1 is unknown */
- raw_height = raw_width = fuji_width = cr2_slice[0] = 0;
+ raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
maximum = height = width = top_margin = left_margin = 0;
make[0] = model[0] = model2[0] = cdesc[0] = 0;
iso_speed = shutter = aperture = focal_len = unique_id = 0;
@@ -7463,7 +7689,7 @@ void CLASS identify()
data_offset = meta_length = tiff_bps = tiff_compress = 0;
kodak_cbpp = zero_after_ff = dng_version = fuji_secondary = 0;
timestamp = shot_order = tiff_samples = black = is_foveon = 0;
- is_raw = raw_color = use_gamma = xmag = ymag = 1;
+ pixel_aspect = is_raw = raw_color = use_gamma = 1;
tile_length = INT_MAX;
for (i=0; i < 4; i++) {
cam_mul[i] = i == 1;
@@ -7473,7 +7699,7 @@ void CLASS identify()
colors = 3;
tiff_bps = 12;
for (i=0; i < 0x1000; i++) curve[i] = i;
- profile_length = 0;
+ mix_green = profile_length = data_error = 0;
order = get2();
hlen = get4();
@@ -7553,6 +7779,8 @@ nucore:
parse_riff();
} else if (!memcmp (head,"DSC-Image",9))
parse_rollei();
+ else if (!memcmp (head,"PWAD",4))
+ parse_sinar_ia();
else if (!memcmp (head,"\0MRM",4))
parse_minolta(0);
else if (!memcmp (head,"FOVb",4))
@@ -7583,7 +7811,7 @@ nucore:
if (!strncmp (model,"Digital Camera ",15))
strcpy (model, model+15);
make[63] = model[63] = model2[63] = 0;
- if (!is_raw) return;
+ if (!is_raw) goto notraw;
if ((raw_height | raw_width) < 0)
raw_height = raw_width = 0;
@@ -7593,14 +7821,13 @@ nucore:
if (fuji_width) {
width = height + fuji_width;
height = width - 1;
- xmag = ymag = 1;
+ pixel_aspect = 1;
}
- if (!strcmp(model,"K10D")) { /* Camera DNGs are not cropped! */
+ if (height == 2624 && width == 3936) { /* Pentax K10D and Samsung GX10 */
height = 2616;
width = 3896;
}
if (dng_version) {
- strcat (model," DNG");
if (filters == UINT_MAX) filters = 0;
if (!filters)
colors = tiff_samples;
@@ -7622,14 +7849,12 @@ nucore:
if (!strcmp(make,"NIKON"))
load_raw = nikon_is_compressed() ?
&CLASS nikon_compressed_load_raw : &CLASS nikon_load_raw;
- if (!strncmp (make,"OLYMPUS",7))
- height += height & 1;
/* Set parameters based on camera name (for non-DNG files). */
if (is_foveon) {
- if (height*2 < width) ymag = 2;
- if (height > width) xmag = 2;
+ if (height*2 < width) pixel_aspect = 0.5;
+ if (height > width) pixel_aspect = 2;
filters = 0;
load_raw = &CLASS foveon_load_raw;
simple_coeff(0);
@@ -7637,6 +7862,7 @@ nucore:
height = 613;
width = 854;
raw_width = 896;
+ pixel_aspect = 607/628.0;
colors = 4;
filters = 0xe1e4e1e4;
load_raw = &CLASS canon_600_load_raw;
@@ -7645,6 +7871,7 @@ nucore:
height = 773;
width = 960;
raw_width = 992;
+ pixel_aspect = 256/235.0;
colors = 4;
filters = 0x1e4e1e4e;
load_raw = &CLASS canon_a5_load_raw;
@@ -7751,6 +7978,12 @@ nucore:
if (unique_id == 0x80000236)
adobe_coeff ("Canon","EOS 400D");
goto canon_cr2;
+ } else if (is_canon && raw_width == 3984) {
+ top_margin = 20;
+ left_margin = 76;
+ height -= 2;
+ maximum = 0x3bb0;
+ goto canon_cr2;
} else if (is_canon && raw_width == 4476) {
top_margin = 34;
left_margin = 90;
@@ -7768,7 +8001,9 @@ canon_cr2:
cam_mul[2] *= 256/317.0;
} else if (!strcmp(model,"D1X")) {
width -= 4;
- ymag = 2;
+ pixel_aspect = 0.5;
+ } else if (!strncmp(model,"D40",3)) {
+ width--;
} else if (!strncmp(model,"D50",3) || !strncmp(model,"D70",3)) {
width--;
maximum = 0xf53;
@@ -7895,8 +8130,8 @@ cp_e2500:
top_margin = (raw_height - height)/2;
left_margin = (raw_width - width )/2;
if (fuji_secondary)
- data_offset += (shot_select > 0) * ( strcmp(model+7," S3Pro")
- ? (raw_width *= 2) : raw_height*raw_width*2 );
+ data_offset += (shot_select > 0) * ( fuji_layout ?
+ (raw_width *= 2) : raw_height*raw_width*2 );
fuji_width = width >> !fuji_layout;
width = (height >> fuji_layout) + fuji_width;
raw_height = height;
@@ -7971,7 +8206,7 @@ konica_400z:
pre_mul[0] = 1.137;
pre_mul[2] = 1.453;
}
- } else if (!strncmp(model,"Optio S4",8)) {
+ } else if (fsize == 6114240) {
height = 1737;
width = 2324;
raw_width = 3520;
@@ -8116,12 +8351,20 @@ konica_400z:
}
} else if (!strcmp(make,"LEICA") || !strcmp(make,"Panasonic")) {
maximum = 0xfff0;
- if (width == 2568)
+ load_raw = &CLASS unpacked_load_raw;
+ if (width == 2568) {
adobe_coeff ("Panasonic","DMC-LC1");
- else if (width == 3304) {
+ } else if (width == 3177) {
+ maximum = 0xf7fc;
+ width -= 10;
+ filters = 0x49494949;
+ adobe_coeff ("Panasonic","DMC-L1");
+ load_raw = &CLASS panasonic_load_raw;
+ } else if (width == 3304) {
maximum = 0xf94c;
width -= 16;
adobe_coeff ("Panasonic","DMC-FZ30");
+ load_raw = &CLASS panasonic_load_raw;
} else if (width == 3690) {
maximum = 0xf7f0;
height -= 3;
@@ -8129,17 +8372,20 @@ konica_400z:
left_margin = 3;
filters = 0x49494949;
adobe_coeff ("Panasonic","DMC-FZ50");
+ load_raw = &CLASS panasonic_load_raw;
} else if (width == 3770) {
height = 2760;
width = 3672;
top_margin = 15;
left_margin = 17;
adobe_coeff ("Panasonic","DMC-FZ50");
+ load_raw = &CLASS panasonic_load_raw;
} else if (width == 3880) {
maximum = 0xf7f0;
width -= 22;
left_margin = 6;
adobe_coeff ("Panasonic","DMC-LX1");
+ load_raw = &CLASS panasonic_load_raw;
} else if (width == 4290) {
height--;
width = 4248;
@@ -8153,34 +8399,33 @@ konica_400z:
left_margin = 17;
adobe_coeff ("Panasonic","DMC-LX2");
}
- load_raw = &CLASS unpacked_load_raw;
- } else if (!strcmp(model,"E-1") ||
- !strcmp(model,"E-400")) {
- filters = 0x61616161;
- maximum = 0xfff0;
- } else if (!strcmp(model,"E-10") ||
- !strncmp(model,"E-20",4)) {
- maximum = 0xffc0;
- black <<= 2;
- } else if (!strcmp(model,"E-300") ||
- !strcmp(model,"E-500")) {
- width -= 20;
- maximum = 0xfc30;
- if (load_raw == &CLASS unpacked_load_raw) black = 0;
- } else if (!strcmp(model,"E-330")) {
- width -= 30;
} else if (!strcmp(model,"C770UZ")) {
height = 1718;
width = 2304;
filters = 0x16161616;
load_raw = &CLASS nikon_e2100_load_raw;
} else if (!strcmp(make,"OLYMPUS")) {
- load_raw = &CLASS olympus_cseries_load_raw;
- if (!strcmp(model,"C5050Z") ||
- !strcmp(model,"C8080WZ"))
- filters = 0x16161616;
- if (!strcmp(model,"SP500UZ"))
- filters = 0x49494949;
+ height += height & 1;
+ filters = exif_cfa;
+ if (!strcmp(model,"E-1") ||
+ !strcmp(model,"E-400")) {
+ maximum = 0xfff0;
+ } else if (!strcmp(model,"E-10") ||
+ !strncmp(model,"E-20",4)) {
+ maximum = 0xffc0;
+ black <<= 2;
+ } else if (!strcmp(model,"E-300") ||
+ !strcmp(model,"E-500")) {
+ width -= 20;
+ maximum = 0xfc30;
+ if (load_raw == &CLASS unpacked_load_raw) black = 0;
+ } else if (!strcmp(model,"E-330")) {
+ width -= 30;
+ } else if (!strcmp(model,"SP550UZ")) {
+ thumb_length = fsize - (thumb_offset = 0xa39800);
+ thumb_height = 480;
+ thumb_width = 640;
+ }
} else if (!strcmp(model,"N Digital")) {
height = 2047;
width = 3072;
@@ -8251,8 +8496,10 @@ konica_400z:
height = 242;
if (fsize < 100000) {
raw_width = 256; width = 249;
+ pixel_aspect = (4.0*height) / (3.0*width);
} else {
raw_width = 512; width = 501;
+ pixel_aspect = (493.0*height) / (373.0*width);
}
data_offset += raw_width + 1;
colors = 4;
@@ -8278,6 +8525,7 @@ konica_400z:
strcpy (model, "DC120");
height = 976;
width = 848;
+ pixel_aspect = height/0.75/width;
load_raw = tiff_compress == 7 ?
&CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw;
} else if (!strcmp(model,"DCS200")) {
@@ -8299,7 +8547,7 @@ konica_400z:
load_raw = &CLASS kodak_radc_load_raw;
filters = 0x61616161;
simple_coeff(2);
- } else if (!strcmp(make,"Rollei")) {
+ } else if (!strcmp(make,"Rollei") && !load_raw) {
switch (raw_width) {
case 1316:
height = 1030;
@@ -8345,7 +8593,7 @@ konica_400z:
load_raw = &CLASS casio_qv5700_load_raw;
} else if (!strcmp(model,"QV-R51")) {
height = 1926;
- width = 2576;
+ width = 2580;
raw_width = 3904;
load_raw = &CLASS packed_12_load_raw;
pre_mul[0] = 1.340;
@@ -8416,12 +8664,10 @@ dng_skip:
if (!load_raw || !height) is_raw = 0;
#ifdef NO_JPEG
if (load_raw == kodak_jpeg_load_raw) {
- fprintf (stderr, "%s: You must link dcraw.c with libjpeg!!\n", ifname);
+ fprintf (stderr,_("%s: You must link dcraw with libjpeg!!\n"), ifname);
is_raw = 0;
}
#endif
- if (flip == -1) flip = tiff_flip;
- if (flip == -1) flip = 0;
if (!cdesc[0])
strcpy (cdesc, colors == 3 ? "RGB":"GMCY");
if (!raw_height) raw_height = height;
@@ -8433,6 +8679,9 @@ dng_skip:
if ((filters >> i & 15) == 6)
filters |= 8 << i;
}
+notraw:
+ if (flip == -1) flip = tiff_flip;
+ if (flip == -1) flip = 0;
}
#ifndef NO_LCMS
@@ -8455,7 +8704,7 @@ void CLASS apply_profile (char *input, char *output)
hInProfile = cmsOpenProfileFromMem (prof, profile_length);
free (prof);
} else
- fprintf (stderr, "%s has no embedded profile.\n", ifname);
+ fprintf (stderr,_("%s has no embedded profile.\n"), ifname);
if (!hInProfile) return;
if (!output)
hOutProfile = cmsCreate_sRGBProfile();
@@ -8471,10 +8720,10 @@ void CLASS apply_profile (char *input, char *output)
oprof = NULL;
}
} else
- fprintf (stderr, "Cannot open %s!\n", output);
+ fprintf (stderr,_("Cannot open file %s!\n"), output);
if (!hOutProfile) goto quit;
if (verbose)
- fprintf (stderr, "Applying color profile...\n");
+ fprintf (stderr,_("Applying color profile...\n"));
hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16,
hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0);
cmsDoTransform (hTransform, image, image, width*height);
@@ -8488,7 +8737,7 @@ quit:
void CLASS convert_to_rgb()
{
- int mix_green, row, col, c, i, j, k;
+ int row, col, c, i, j, k;
ushort *img;
float out[3], out_cam[3][4];
double num, inverse[3][3];
@@ -8573,10 +8822,9 @@ void CLASS convert_to_rgb()
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]);
+ fprintf (stderr, raw_color ? _("Building histograms...\n") :
+ _("Converting to %s colorspace...\n"), name[output_color-1]);
- mix_green = rgb_cam[1][1] == rgb_cam[1][3];
memset (histogram, 0, sizeof histogram);
for (img=image[0], row=0; row < height; row++)
for (col=0; col < width; col++, img+=4) {
@@ -8591,11 +8839,9 @@ void CLASS convert_to_rgb()
}
else if (document_mode)
img[0] = img[FC(row,col)];
- else if (mix_green)
- img[1] = (img[1] + img[3]) >> 1;
FORCC histogram[c][img[c] >> 3]++;
}
- if (colors == 4 && (output_color || mix_green)) colors = 3;
+ if (colors == 4 && output_color) colors = 3;
if (document_mode && filters) colors = 1;
}
@@ -8609,7 +8855,7 @@ void CLASS fuji_rotate()
if (!fuji_width) return;
if (verbose)
- fprintf (stderr, "Rotating image 45 degrees...\n");
+ fprintf (stderr,_("Rotating image 45 degrees...\n"));
fuji_width = (fuji_width - 1 + shrink) >> shrink;
step = sqrt(0.5);
wide = fuji_width / step;
@@ -8637,6 +8883,43 @@ void CLASS fuji_rotate()
fuji_width = 0;
}
+void CLASS stretch()
+{
+ int newdim, row, col, c;
+ double rc, frac;
+ ushort (*img)[4], *pix0, *pix1;
+
+ 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);
@@ -8688,7 +8971,7 @@ struct tiff_hdr {
struct tiff_tag exif[4];
short bps[4];
int rat[6];
- char make[64], model[72], soft[32], date[20];
+ char make[64], model[64], soft[32], date[20];
};
void CLASS tiff_set (ushort *ntag,
@@ -8705,91 +8988,117 @@ void CLASS tiff_set (ushort *ntag,
else tt->val.i0 = val;
}
-#define TOFF(ptr) ((char *)(&(ptr)) - (char *)(&th))
+#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, 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.i0 = 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, 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, 305, 2, 32, TOFF(th->soft));
+ tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date));
+ 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[0]));
+ tiff_set (&th->nexif, 33437, 5, 1, TOFF(th->rat[2]));
+ tiff_set (&th->nexif, 34855, 3, 1, iso_speed);
+ tiff_set (&th->nexif, 37386, 5, 1, TOFF(th->rat[4]));
+ for (c=0; c < 6; c++) th->rat[c] = 1000000;
+ th->rat[0] *= shutter;
+ th->rat[2] *= aperture;
+ th->rat[4] *= focal_len;
+ strncpy (th->make, make, 64);
+ strncpy (th->model, model, 64);
+ strcpy (th->soft, "dcraw v"VERSION);
+ t = gmtime (&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);
+}
+
+void CLASS jpeg_thumb (FILE *tfp)
+{
+ 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, tfp);
+ fputc (0xd8, tfp);
+ if (strcmp (thumb+6, "Exif")) {
+ memcpy (exif, "\xff\xe1 Exif\0\0", 10);
+ exif[1] = htons (8 + sizeof th);
+ fwrite (exif, 1, sizeof exif, tfp);
+ tiff_head (&th, 0);
+ fwrite (&th, 1, sizeof th, tfp);
+ }
+ fwrite (thumb+2, 1, thumb_length-2, tfp);
+ free (thumb);
+}
void CLASS write_ppm_tiff (FILE *ofp)
{
struct tiff_hdr th;
- struct tm *t;
uchar *ppm, lut[0x10000];
ushort *ppm2;
- int i, c, row, col, psize=0, soff, rstep, cstep;
+ int c, row, col, soff, rstep, cstep;
iheight = height;
iwidth = width;
- if (flip & 4) {
- SWAP(height,width);
- SWAP(ymag,xmag);
- }
- ppm = (uchar *) calloc (width, colors*xmag*output_bps/8);
+ if (flip & 4) SWAP(height,width);
+ ppm = (uchar *) calloc (width, colors*output_bps/8);
ppm2 = (ushort *) ppm;
merror (ppm, "write_ppm_tiff()");
-
- memset (&th, 0, sizeof th);
- th.order = htonl(0x4d4d4949) >> 16;
- th.magic = 42;
- th.ifd = 10;
- tiff_set (&th.ntag, 256, 4, 1, xmag*width);
- tiff_set (&th.ntag, 257, 4, 1, ymag*height);
- tiff_set (&th.ntag, 258, 3, colors, output_bps);
- if (colors > 2)
- th.tag[th.ntag-1].val.i0 = 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, 271, 2, 64, TOFF(th.make));
- tiff_set (&th.ntag, 272, 2, 72, TOFF(th.model));
- 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, ymag*height);
- tiff_set (&th.ntag, 279, 4, 1, ymag*height*xmag*width*colors*output_bps/8);
- tiff_set (&th.ntag, 305, 2, 32, TOFF(th.soft));
- tiff_set (&th.ntag, 306, 2, 20, TOFF(th.date));
- 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[0]));
- tiff_set (&th.nexif, 33437, 5, 1, TOFF(th.rat[2]));
- tiff_set (&th.nexif, 34855, 3, 1, iso_speed);
- tiff_set (&th.nexif, 37386, 5, 1, TOFF(th.rat[4]));
- for (i=0; i < 6; i++) th.rat[i] = 1000000;
- th.rat[0] *= shutter;
- th.rat[2] *= aperture;
- th.rat[4] *= focal_len;
- strncpy (th.make, make, 64);
- strncpy (th.model, model, 72);
- strcpy (th.soft, "dcraw v"VERSION);
- t = gmtime (&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);
-
if (output_tiff) {
+ tiff_head (&th, 1);
fwrite (&th, sizeof th, 1, ofp);
- if (psize)
- fwrite (oprof, psize, 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",
- xmag*width, ymag*height, colors, (1 << output_bps)-1, cdesc);
+ width, height, colors, (1 << output_bps)-1, cdesc);
else
fprintf (ofp, "P%d\n%d %d\n%d\n",
- colors/2+5, xmag*width, ymag*height, (1 << output_bps)-1);
+ colors/2+5, width, height, (1 << output_bps)-1);
- if (output_bps == 8)
- gamma_lut (lut);
+ if (output_bps == 8) gamma_lut (lut);
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)
- FORCC for (i=0; i < xmag; i++)
- if (output_bps == 8)
- ppm [(col*xmag+i)*colors+c] = lut[image[soff][c]];
- else ppm2[(col*xmag+i)*colors+c] = image[soff][c];
- if (output_bps == 16 && !output_tiff && th.order == 0x4949)
- swab (ppm2, ppm2, xmag*width*colors*2);
- for (i=0; i < ymag; i++)
- fwrite (ppm, colors*output_bps/8, xmag*width, ofp);
+ if (output_bps == 8)
+ FORCC ppm [col*colors+c] = lut[image[soff][c]];
+ else FORCC ppm2[col*colors+c] = 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);
}
@@ -8797,8 +9106,8 @@ void CLASS write_ppm_tiff (FILE *ofp)
int CLASS main (int argc, char **argv)
{
int arg, status=0, user_flip=-1, user_black=-1, user_qual=-1;
- int timestamp_only=0, thumbnail_only=0, identify_only=0, write_to_stdout=0;
- int half_size=0, use_fuji_rotate=1, quality, i, c;
+ int timestamp_only=0, thumbnail_only=0, identify_only=0;
+ int use_fuji_rotate=1, write_to_stdout=0, quality, i, c;
char opt, *ofname, *sp, *cp, *dark_frame = NULL;
const char *write_ext;
struct utimbuf ut;
@@ -8810,56 +9119,60 @@ int CLASS main (int argc, char **argv)
#ifndef LOCALTIME
putenv ("TZ=UTC");
#endif
+#ifdef LOCALEDIR
+ setlocale (LC_CTYPE, "");
+ setlocale (LC_MESSAGES, "");
+ bindtextdomain ("dcraw", LOCALEDIR);
+ textdomain ("dcraw");
+#endif
+
if (argc == 1) {
- fprintf (stderr,
- "\nRaw Photo Decoder \"dcraw\" v"VERSION
- "\nby Dave Coffin, dcoffin a cybercom o net"
- "\n\nUsage: %s [options] file1 file2 ...\n"
- "\nValid options:"
- "\n-v Print verbose messages"
- "\n-c Write image data to standard output"
- "\n-e Extract embedded thumbnail image"
- "\n-i Identify files without decoding them"
- "\n-z Change file dates to camera timestamp"
- "\n-a Use automatic white balance"
- "\n-w Use camera white balance, if possible"
- "\n-r <nums> Set raw white balance (four values required)"
- "\n-b <num> Adjust brightness (default = 1.0)"
- "\n-k <num> Set black point"
- "\n-K <file> Subtract dark frame (16-bit raw PGM)"
- "\n-H [0-9] Highlight mode (0=clip, 1=no clip, 2+=recover)"
- "\n-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)"
- "\n-o [0-5] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ)"
+ printf(_("\nRaw photo decoder \"dcraw\" v%s"), 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(_("-a Use automatic white balance"));
+ puts(_("-w Use camera white balance, if possible"));
+ puts(_("-r <4 numbers> Set custom white balance"));
+ puts(_("-b <num> Adjust brightness (default = 1.0)"));
+ puts(_("-n <num> Set threshold for wavelet denoising"));
+ puts(_("-k <num> Set black point"));
+ puts(_("-K <file> Subtract dark frame (16-bit raw PGM)"));
+ puts(_("-H [0-9] Highlight mode (0=clip, 1=no clip, 2+=recover)"));
+ 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
- "\n-o <file> Apply output ICC profile from file"
- "\n-p <file> Apply camera ICC profile from file or \"embed\""
+ puts(_("-o <file> Apply output ICC profile from file"));
+ puts(_("-p <file> Apply camera ICC profile from file or \"embed\""));
#endif
- "\n-d Document Mode (no color, no interpolation)"
- "\n-D Document Mode without scaling (totally raw)"
- "\n-q [0-3] Set the interpolation quality"
- "\n-h Half-size color image (twice as fast as \"-q 0\")"
- "\n-f Interpolate RGGB as four colors"
- "\n-B <domain> <range> Apply bilateral filter to reduce noise"
- "\n-j Show Fuji Super CCD images tilted 45 degrees"
- "\n-s [0-99] Select a different raw image from the same file"
- "\n-4 Write 16-bit linear instead of 8-bit with gamma"
- "\n-T Write TIFF instead of PPM"
- "\n\n", argv[0]);
+ 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(_("-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(_("-s [0-99] Select a different raw image from the same file"));
+ puts(_("-4 Write 16-bit linear instead of 8-bit with gamma"));
+ puts(_("-T Write TIFF instead of PPM"));
+ puts("");
return 1;
}
-
argv[argc] = "";
for (arg=1; argv[arg][0] == '-'; ) {
opt = argv[arg++][1];
- if ((cp = strchr (sp="BbrktqsH", opt)))
- for (i=0; i < "21411111"[cp-sp]-'0'; i++)
+ if ((cp = strchr (sp="nbrktqsH", opt)))
+ for (i=0; i < "11411111"[cp-sp]-'0'; i++)
if (!isdigit(argv[arg+i][0])) {
- fprintf (stderr, "Non-numeric argument to \"-%c\"\n", opt);
+ fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt);
return 1;
}
switch (opt) {
- case 'B': sigma_d = atof(argv[arg++]);
- sigma_r = atof(argv[arg++]); break;
+ case 'n': threshold = atof(argv[arg++]); break;
case 'b': bright = atof(argv[arg++]); break;
case 'r':
FORC4 user_mul[c] = atof(argv[arg++]); break;
@@ -8886,26 +9199,26 @@ int CLASS main (int argc, char **argv)
case 'v': verbose = 1; break;
case 'h': half_size = 1; /* "-h" implies "-f" */
case 'f': four_color_rgb = 1; break;
- case 'd': document_mode = 1; break;
- case 'D': document_mode = 2; break;
case 'a': use_auto_wb = 1; break;
case 'w': use_camera_wb = 1; break;
+ case 'D':
+ case 'd': document_mode = 1 + (opt == 'D');
case 'j': use_fuji_rotate = 0; break;
case 'm': output_color = 0; break;
case 'T': output_tiff = 1; break;
case '4': output_bps = 16; break;
default:
- fprintf (stderr, "Unknown option \"-%c\".\n", opt);
+ fprintf (stderr,_("Unknown option \"-%c\".\n"), opt);
return 1;
}
}
if (arg == argc) {
- fprintf (stderr, "No files to process.\n");
+ 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");
+ fprintf (stderr,_("Will not write an image to the terminal!\n"));
return 1;
}
#if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__)
@@ -8932,14 +9245,21 @@ int CLASS main (int argc, char **argv)
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);
+ 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);
+ fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp);
ut.actime = ut.modtime = timestamp;
utime (ifname, &ut);
}
@@ -8948,7 +9268,7 @@ int CLASS main (int argc, char **argv)
write_fun = &CLASS write_ppm_tiff;
if (thumbnail_only) {
if ((status = !thumb_offset)) {
- fprintf (stderr, "%s has no thumbnail.\n", ifname);
+ fprintf (stderr,_("%s has no thumbnail.\n"), ifname);
goto next;
} else if (thumb_load_raw) {
load_raw = thumb_load_raw;
@@ -8967,64 +9287,67 @@ int CLASS main (int argc, char **argv)
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);
- printf ("ISO speed: %d\n", (int) iso_speed);
- printf ("Shutter: ");
+ printf (_("\nFilename: %s\n"), ifname);
+ printf (_("Timestamp: %s"), ctime(&timestamp));
+ printf (_("Camera: %s %s\n"), make, model);
+ 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 ("Secondary pixels: %s\n", fuji_secondary ? "yes":"no");
- printf ("Embedded ICC profile: %s\n", profile_length ? "yes":"no");
- printf ("Decodable with dcraw: %s\n", is_raw ? "yes":"no");
+ printf (_("%0.1f sec\n"), shutter);
+ printf (_("Aperture: f/%0.1f\n"), aperture);
+ printf (_("Focal length: %0.1f mm\n"), focal_len);
+ printf (_("Secondary pixels: %s\n"), fuji_secondary ? _("yes"):_("no"));
+ printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no"));
+ printf (_("Decodable with dcraw: %s\n"), is_raw ? _("yes"):_("no"));
+ 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);
+ 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 %s\n", ifname);
+ fprintf (stderr,_("Cannot decode file %s\n"), ifname);
if (!is_raw) goto next;
- 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;
- }
- shrink = half_size && filters;
+ shrink = (half_size || threshold) && filters;
iheight = (height + shrink) >> shrink;
iwidth = (width + shrink) >> shrink;
if (identify_only) {
if (verbose) {
- if (fuji_width && use_fuji_rotate) {
- fuji_width = (fuji_width - 1 + shrink) >> shrink;
- iwidth = fuji_width / sqrt(0.5);
- iheight = (iheight - fuji_width) / sqrt(0.5);
+ 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;
+ }
}
- iheight *= ymag;
- iwidth *= xmag;
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);
+ 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: ");
+ printf (_("\nFilter pattern: "));
if (!cdesc[3]) cdesc[3] = 'G';
for (i=0; i < 16; i++)
putchar (cdesc[fc(i >> 1,i & 1)]);
}
- printf ("\nDaylight multipliers:");
+ printf (_("\nDaylight multipliers:"));
FORCC printf (" %f", pre_mul[c]);
if (cam_mul[0] > 0) {
- printf ("\nCamera multipliers:");
+ printf (_("\nCamera multipliers:"));
FORC4 printf (" %f", cam_mul[c]);
}
putchar ('\n');
} else
- printf ("%s is a %s %s image.\n", ifname, make, model);
+ printf (_("%s is a %s %s image.\n"), ifname, make, model);
next:
fclose(ifp);
continue;
@@ -9035,13 +9358,11 @@ next:
meta_data = (char *) (image + iheight*iwidth);
if (verbose)
fprintf (stderr,
- "Loading %s %s image from %s...\n", make, model, ifname);
+ _("Loading %s %s image from %s ...\n"), make, model, ifname);
fseek (ifp, data_offset, SEEK_SET);
(*load_raw)();
bad_pixels();
if (dark_frame) subtract (dark_frame);
- height = iheight;
- width = iwidth;
quality = 2 + !fuji_width;
if (user_qual >= 0) quality = user_qual;
if (user_black >= 0) black = user_black;
@@ -9050,8 +9371,7 @@ next:
#endif
if (is_foveon && !document_mode) foveon_interpolate();
if (!is_foveon && document_mode < 2) scale_colors();
- if (shrink) filters = 0;
- cam_to_cielab (NULL,NULL);
+ pre_interpolate();
if (filters && !document_mode) {
if (quality == 0)
lin_interpolate();
@@ -9059,13 +9379,16 @@ next:
vng_interpolate();
else ahd_interpolate();
}
- if (sigma_d > 0 && sigma_r > 0) bilateral_filter();
if (!is_foveon && highlight > 1) recover_highlights();
if (use_fuji_rotate) fuji_rotate();
+ if (mix_green && (colors = 3))
+ for (i=0; i < height*width; i++)
+ image[i][1] = (image[i][1] + image[i][3]) >> 1;
#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";
@@ -9076,7 +9399,7 @@ thumbnail:
ofname = (char *) malloc (strlen(ifname) + 16);
merror (ofname, "main()");
if (write_to_stdout)
- strcpy (ofname, "standard output");
+ strcpy (ofname,_("standard output"));
else {
strcpy (ofname, ifname);
if ((cp = strrchr (ofname, '.'))) *cp = 0;
@@ -9091,7 +9414,7 @@ thumbnail:
}
}
if (verbose)
- fprintf (stderr, "Writing data to %s ...\n", ofname);
+ fprintf (stderr,_("Writing data to %s ...\n"), ofname);
(*write_fun)(ofp);
fclose(ifp);
if (ofp != stdout) fclose(ofp);
@@ -9105,6 +9428,1236 @@ cleanup:
@
+1.376
+log
+@Optimized AHD interpolation to take 22% less time.
+@
+text
+@d25 1
+a25 1
+#define VERSION "8.68"
+d4742 3
+a4744 2
+ if (tiff_samples == 3 && tiff_bps == 8)
+ if (!dng_version) is_raw = 0;
+@
+
+
+1.375
+log
+@Support the Fuji FinePix S5Pro.
+@
+text
+@d25 1
+a25 1
+#define VERSION "8.67"
+a3690 31
+void CLASS cam_to_cielab (ushort cam[4], float lab[3])
+{
+ int c, i, j, k;
+ float r, xyz[3];
+ static float cbrt[0x10000], xyz_cam[3][4];
+
+ if (cam == NULL) {
+ for (i=0; i < 0x10000; i++) {
+ r = i / 65535.0;
+ cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0;
+ }
+ for (i=0; i < 3; i++)
+ for (j=0; j < colors; j++)
+ for (xyz_cam[i][j] = k=0; k < 3; k++)
+ xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i];
+ } else {
+ xyz[0] = xyz[1] = xyz[2] = 0.5;
+ FORCC {
+ xyz[0] += xyz_cam[0][c] * cam[c];
+ xyz[1] += xyz_cam[1][c] * cam[c];
+ xyz[2] += xyz_cam[2][c] * cam[c];
+ }
+ xyz[0] = cbrt[CLIP((int) xyz[0])];
+ xyz[1] = cbrt[CLIP((int) xyz[1])];
+ xyz[2] = cbrt[CLIP((int) xyz[2])];
+ lab[0] = 116 * xyz[1] - 16;
+ lab[1] = 500 * (xyz[0] - xyz[1]);
+ lab[2] = 200 * (xyz[1] - xyz[2]);
+ }
+}
+
+d3699 1
+a3699 1
+ int i, j, top, left, row, col, tr, tc, fc, c, d, val, hm[2];
+d3703 1
+a3703 1
+ float flab[3];
+d3705 1
+a3705 1
+ short (*lab)[TS][TS][3];
+d3710 10
+a3719 1
+ border_interpolate(3);
+d3726 2
+a3727 3
+ for (top=0; top < height; top += TS-6)
+ for (left=0; left < width; left += TS-6) {
+ memset (rgb, 0, 12*TS*TS);
+d3730 3
+a3732 4
+ for (row = top < 2 ? 2:top; row < top+TS && row < height-2; row++) {
+ col = left + (FC(row,left) == 1);
+ if (col < 2) col += 2;
+ for (fc = FC(row,col); col < left+TS && col < width-2; col+=2) {
+d3734 2
+a3735 2
+ val = ((pix[-1][1] + pix[0][fc] + pix[1][1]) * 2
+ - pix[-2][fc] - pix[2][fc]) >> 2;
+d3737 2
+a3738 2
+ val = ((pix[-width][1] + pix[0][fc] + pix[width][1]) * 2
+ - pix[-2*width][fc] - pix[2*width][fc]) >> 2;
+d3744 2
+a3745 2
+ for (row=top+1; row < top+TS-1 && row < height-1; row++)
+ for (col=left+1; col < left+TS-1 && col < width-1; col++) {
+d3748 1
+d3764 12
+a3775 2
+ cam_to_cielab (rix[0], flab);
+ FORC3 lab[d][row-top][col-left][c] = 64*flab[c];
+d3779 1
+a3779 1
+ for (row=top+2; row < top+TS-2 && row < height; row++) {
+d3781 1
+a3781 1
+ for (col=left+2; col < left+TS-2 && col < width; col++) {
+d3783 8
+a3790 3
+ for (d=0; d < 2; d++)
+ for (i=0; i < 4; i++)
+ ldiff[d][i] = ABS(lab[d][tr][tc][0]-lab[d][tr][tc+dir[i]][0]);
+a3792 5
+ for (d=0; d < 2; d++)
+ for (i=0; i < 4; i++)
+ if (i >> 1 == d || ldiff[d][i] <= leps)
+ abdiff[d][i] = SQR(lab[d][tr][tc][1]-lab[d][tr][tc+dir[i]][1])
+ + SQR(lab[d][tr][tc][2]-lab[d][tr][tc+dir[i]][2]);
+d3802 1
+a3802 1
+ for (row=top+3; row < top+TS-3 && row < height-3; row++) {
+d3804 1
+a3804 1
+ for (col=left+3; col < left+TS-3 && col < width-3; col++) {
+a7448 1
+ cam_to_cielab (NULL,NULL);
+@
+
+
+1.374
+log
+@Refactored wavelet_denoise() to use memory more intelligently.
+@
+text
+@d25 1
+a25 1
+#define VERSION "8.66"
+d5159 2
+a5160 4
+ if (fuji_layout) {
+ height *= 2;
+ width /= 2;
+ }
+d5431 2
+d5768 1
+a5768 1
+ raw_height = raw_width = fuji_width = cr2_slice[0] = 0;
+d6220 2
+a6221 2
+ data_offset += (shot_select > 0) * ( strcmp(model+7," S3Pro")
+ ? (raw_width *= 2) : raw_height*raw_width*2 );
+@
+
+
+1.373
+log
+@Detect and report data errors wherever possible.
+@
+text
+@d25 1
+a25 1
+#define VERSION "8.65"
+d1370 1
+a1370 1
+ if (shrink || !meta_length) return;
+d1611 1
+a1611 1
+ if ((shot = shot_select) || shrink) {
+d1619 4
+d1638 1
+a1638 1
+ filters = 0;
+a3306 2
+ for (i=0; i < size; i++)
+ base[st*i] = temp[i] * 0.25;
+d3311 2
+a3312 2
+ float *fimg, *temp, thold, val, mul[2], avg, diff;
+ int scale=1, depth=6, lev, row, col, size, nc, c, i, wlast;
+d3323 1
+a3323 1
+ fimg = (float *) calloc (depth*size+iheight+iwidth, sizeof *fimg);
+d3325 1
+a3325 1
+ temp = fimg + depth*size;
+d3330 12
+a3341 6
+ for (lev=0; lev < depth-1; lev++) {
+ memcpy (fimg+size*(lev+1), fimg+size*lev, size*sizeof *fimg);
+ for (i=0; i < iheight; i++)
+ hat_transform (temp, fimg+size*(lev+1)+i*iwidth,1,iwidth, 1 << lev);
+ for (i=0; i < iwidth; i++)
+ hat_transform (temp, fimg+size*(lev+1)+i,iwidth, iheight, 1 << lev);
+d3343 6
+a3348 5
+ for (i=size*lev; i < size*(lev+1); i++) {
+ fimg[i] -= fimg[i+size];
+ if (fimg[i] < -thold) fimg[i] += thold;
+ else if (fimg[i] > thold) fimg[i] -= thold;
+ else fimg[i] = 0;
+d3350 1
+d3352 2
+a3353 5
+ for (i=0; i < size; i++) {
+ for (val=lev=0; lev < depth; lev++)
+ val += fimg[size*lev+i];
+ image[i][c] = CLIP(val*val/0x10000);
+ }
+d3461 1
+a3461 1
+ int row, col;
+d3472 4
+a3475 2
+ for (col=0; col < width; col++)
+ img[row*width+col][FC(row,col)] = BAYER(row,col);
+@
+
+
+1.372
+log
+@Use the "a trous" wavelet transform instead of the JPEG2000 method.
+Apply sqrt() to denoise highlights and shadows evenly.
+@
+text
+@d25 1
+a25 1
+#define VERSION "8.64"
+d108 1
+a108 1
+int zero_after_ff, is_raw, dng_version, is_foveon;
+d248 12
+d330 1
+a330 1
+ fread (pixel, 2, count, ifp);
+d460 1
+a460 1
+ fread (data, raw_width * 10 / 8, 1, ifp);
+d545 1
+a545 1
+ c = fgetc(ifp);
+d547 1
+a547 1
+ bitbuf = (bitbuf << 8) + c;
+d700 1
+a700 1
+ int lowbits, i, row, r, col, save, val;
+d715 2
+a716 1
+ for (block=0; block < raw_width >> 3; block++) {
+d739 2
+a740 1
+ pixel[(block << 6) + i] = ( base[i & 1] += diffbuf[i] );
+d855 2
+a856 1
+ *outp = col ? outp[-jh->clrs]+diff : (jh->vpred[c] += diff);
+d1005 1
+d1039 2
+a1040 3
+ diff = hpred[col & 1];
+ if (diff >= csize) diff = csize-1;
+ BAYER(row,col-left_margin) = curve[diff];
+d1065 1
+a1065 1
+ getbits(8);
+d1215 1
+a1215 1
+ int row, col, r, c;
+d1218 2
+a1219 1
+ pixel = (ushort *) calloc (raw_width, sizeof *pixel);
+d1222 3
+a1224 2
+ read_shorts (pixel, raw_width);
+ for (col=0; col < fuji_width << !fuji_layout; col++) {
+d1560 1
+d1656 1
+a1656 1
+ getbits(8);
+d1663 1
+a1663 1
+ int row, col;
+d1665 1
+d1667 1
+a1667 1
+ pixel = (ushort *) calloc (raw_width, sizeof *pixel);
+d1670 2
+a1671 1
+ read_shorts (pixel, raw_width);
+d1673 1
+a1673 1
+ BAYER2(row,col) = pixel[col];
+d1695 1
+a1695 1
+ fread (data, 1, dwide, ifp);
+d1697 2
+a1698 1
+ if (((dp-data) & 15) == 15) dp++;
+d1732 1
+a1732 1
+ fread (pixel, 1, 768, ifp);
+d1762 1
+a1762 1
+ fread (pixel, 1, raw_width, ifp);
+d1914 2
+a1915 4
+ if (c)
+ BAYER(row+y*2+c-1,x*2+2-c) = val;
+ else
+ BAYER(row+r*2+y,x*2+y) = val;
+d2000 1
+a2000 1
+ fread (pixel, 848, 1, ifp);
+d2018 1
+a2018 1
+ fread (pixel, 1, raw_width, ifp);
+d2070 2
+a2071 1
+ pixel[pi] = pred + ljpeg_diff (decode[chess]);
+d2140 2
+a2141 1
+ BAYER(row,col+i) = curve[ret ? buf[i] : (pred[i & 1] += buf[i])];
+d2164 1
+a2164 1
+ y[j][k] = y[j][k^1] + *bp++;
+d2184 1
+a2184 1
+ FORC3 ip[c] = (rgb[c] += *bp++) & 0xfff;
+d2234 1
+a2234 1
+ fread (pixel, 2, raw_width, ifp);
+d2239 2
+a2240 1
+ BAYER(row,col) = ntohs(pixel[col+left_margin]);
+d2263 1
+a2263 1
+ sum += diff;
+d2498 1
+a2498 1
+ short diff[1024], pred[3];
+d2500 1
+a2500 1
+ int fixed, row, col, bit=-1, c, i;
+d2522 1
+d5780 1
+a5780 1
+ mix_green = profile_length = 0;
+d6674 1
+a6674 1
+ width = 2576;
+@
+
+
+1.371
+log
+@Added the Olympus SP550UZ.
+@
+text
+@d25 1
+a25 1
+#define VERSION "8.63"
+d3271 13
+d3286 2
+a3287 2
+ float *fimg, *temp, mul[2], avg, diff;
+ int scale=1, dim=0, row, col, size, sh, nc, c, i, j, k, m, wlast;
+d3289 2
+a3290 2
+ static const float wlet[] = /* Daubechies 9-tap/7-tap filter */
+ { 1.149604398, -1.586134342, -0.05298011854, 0.8829110762, 0.4435068522 };
+d3297 2
+a3298 2
+ while (1 << dim < iwidth || 1 << dim < iheight) dim++;
+ fimg = (float *) calloc ((1 << dim*2)+(1 << dim)+2, sizeof *fimg);
+d3300 1
+a3300 1
+ temp = fimg + (1 << dim*2) + 1;
+d3303 21
+a3323 50
+ for (row=0; row < iheight; row++)
+ for (col=0; col < iwidth; col++)
+ fimg[(row << dim)+col] = image[row*iwidth+col][c] << scale;
+ for (size = 1 << dim; size > 1; size >>= 1)
+ for (sh=0; sh <= dim; sh += dim)
+ for (i=0; i < size; i++) {
+ for (j=0; j < size; j++)
+ temp[j] = fimg[(i << (dim-sh))+(j << sh)];
+ for (k=1; k < 5; k+=2) {
+ temp[size] = temp[size-2];
+ for (m=1; m < size; m+=2)
+ temp[m] += wlet[k] * (temp[m-1] + temp[m+1]);
+ temp[-1] = temp[1];
+ for (m=0; m < size; m+=2)
+ temp[m] += wlet[k+1] * (temp[m-1] + temp[m+1]);
+ }
+ for (m=0; m < size; m++)
+ temp[m] *= (m & 1) ? 1/wlet[0] : wlet[0];
+ for (j=k=0; j < size; j++, k+=2) {
+ if (k == size) k = 1;
+ fimg[(i << (dim-sh))+(j << sh)] = temp[k];
+ }
+ }
+ for (i=0; i < 1 << dim*2; i++)
+ if (fimg[i] < -threshold) fimg[i] += threshold;
+ else if (fimg[i] > threshold) fimg[i] -= threshold;
+ else fimg[i] = 0;
+ for (size = 2; size <= 1 << dim; size <<= 1)
+ for (sh=dim; sh >= 0; sh -= dim)
+ for (i=0; i < size; i++) {
+ for (j=k=0; j < size; j++, k+=2) {
+ if (k == size) k = 1;
+ temp[k] = fimg[(i << (dim-sh))+(j << sh)];
+ }
+ for (m=0; m < size; m++)
+ temp[m] *= (m & 1) ? wlet[0] : 1/wlet[0];
+ for (k=3; k > 0; k-=2) {
+ temp[-1] = temp[1];
+ for (m=0; m < size; m+=2)
+ temp[m] -= wlet[k+1] * (temp[m-1] + temp[m+1]);
+ temp[size] = temp[size-2];
+ for (m=1; m < size; m+=2)
+ temp[m] -= wlet[k] * (temp[m-1] + temp[m+1]);
+ }
+ for (j=0; j < size; j++)
+ fimg[(i << (dim-sh))+(j << sh)] = temp[j];
+ }
+ for (row=0; row < iheight; row++)
+ for (col=0; col < iwidth; col++)
+ image[row*iwidth+col][c] = CLIP(fimg[(row << dim)+col] + 0.5);
+d3337 1
+d3342 4
+a3345 3
+ diff = BAYER(row,col) - avg;
+ if (diff < -threshold/M_SQRT2) diff += threshold/M_SQRT2;
+ else if (diff > threshold/M_SQRT2) diff -= threshold/M_SQRT2;
+d3347 1
+a3347 1
+ BAYER(row,col) = CLIP(avg + diff + 0.5);
+@
+
+
+1.370
+log
+@Support the Canon EOS-1D Mark III.
+@
+text
+@d25 1
+a25 1
+#define VERSION "8.62"
+d98 1
+a98 1
+unsigned shot_order, kodak_cbpp, filters, unique_id, *oprof;
+d4186 1
+a4186 1
+ unsigned kodak, entries, tag, type, len, save;
+d4206 4
+d4719 2
+a5920 2
+ if (!strncmp (make,"OLYMPUS",7))
+ height += height & 1;
+a6470 15
+ } else if (!strcmp(model,"E-1") ||
+ !strcmp(model,"E-400")) {
+ filters = 0x61616161;
+ maximum = 0xfff0;
+ } else if (!strcmp(model,"E-10") ||
+ !strncmp(model,"E-20",4)) {
+ maximum = 0xffc0;
+ black <<= 2;
+ } else if (!strcmp(model,"E-300") ||
+ !strcmp(model,"E-500")) {
+ width -= 20;
+ maximum = 0xfc30;
+ if (load_raw == &CLASS unpacked_load_raw) black = 0;
+ } else if (!strcmp(model,"E-330")) {
+ width -= 30;
+d6477 21
+a6497 6
+ load_raw = &CLASS olympus_cseries_load_raw;
+ if (!strcmp(model,"C5050Z") ||
+ !strcmp(model,"C8080WZ"))
+ filters = 0x16161616;
+ if (!strncmp(model,"SP5",3))
+ filters = 0x49494949;
+@
+
+
+1.369
+log
+@As the Pentax K10D was cropped, do likewise for the Samsung GX10.
+@
+text
+@d25 1
+a25 1
+#define VERSION "8.61"
+d870 2
+d4146 1
+a4146 1
+ i = len == 582 ? 50 : len == 653 ? 68 : len == 796 ? 126 : 0;
+d6046 6
+@
+
+
+1.368
+log
+@Found larger JPEG thumbs for Nikon D100,D1H,D1X,D2H,D2X,E5000,E5700.
+@
+text
+@d5887 1
+a5887 1
+ if (!strcmp(model,"K10D")) { /* Camera DNGs are not cropped! */
+@
+
+
+1.367
+log
+@Reworded the copyright notice to avoid mention of the GPL.
+@
+text
+@d25 1
+a25 1
+#define VERSION "8.60"
+d3917 2
+d4021 4
+d4326 1
+a4326 1
+int CLASS parse_tiff_ifd (int base, int level)
+d4437 1
+a4437 1
+ if (parse_tiff_ifd (base, level+1)) break;
+d4615 1
+a4615 1
+ parse_tiff_ifd (base, level+1);
+d4643 1
+a4643 1
+ parse_tiff_ifd (-sony_offset, level);
+d4677 1
+a4677 1
+ if (parse_tiff_ifd (base, 0)) break;
+@
+
+
+1.366
+log
+@Replaced bilateral filter with wavelet denoising.
+Fixed incompatibility between "-f" and "-p".
+Fixed strange color casts with the Polaroid x530.
+Added Adobe matrices for the Nikon D40 and Pentax K10D.
+@
+text
+@d8 12
+a19 13
+ Attention! Some parts of this program are restricted under the
+ terms of the GNU General Public License. Such code is enclosed
+ in "BEGIN GPL BLOCK" and "END GPL BLOCK" declarations.
+ Any code not declared GPL is free for all uses.
+
+ Starting in Revision 1.237, the code to support Foveon cameras
+ is under GPL.
+
+ To lawfully redistribute dcraw.c, you must either (a) include
+ full source code for all executable files containing restricted
+ functions, (b) remove these functions, re-implement them, or
+ copy them from an earlier, non-GPL Revision of dcraw.c, or (c)
+ purchase a license from the author.
+d2385 1
+a2385 1
+/* BEGIN GPL BLOCK */
+d3022 1
+a3022 1
+/* END GPL BLOCK */
+@
+
+
+1.365
+log
+@Added a color matrix for the Fuji S6000fd.
+Set aspect ratio for the Kodak DC20 and DC25.
+@
+text
+@d26 1
+a26 1
+#define VERSION "8.54"
+d106 1
+a106 1
+int black, maximum, raw_color, use_gamma;
+d111 2
+a112 2
+float bright=1, user_mul[4]={0,0,0,0}, sigma_d=0, sigma_r=0;
+int four_color_rgb=0, document_mode=0, highlight=0;
+d2681 5
+a2688 7
+ else {
+ #define LAST(x,y) last[(i+x)%3][(c+y)%3]
+ for (i=0; i < 3; i++)
+ FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1);
+ #undef LAST
+ FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583;
+ }
+d3270 97
+d3369 1
+a3369 1
+ int row, col, x, y, c, val, sum[8];
+a3372 1
+ maximum -= black;
+d3375 2
+a3376 2
+ for (row=0; row < height-7; row += 8)
+ for (col=0; col < width-7; col += 8) {
+d3381 1
+a3381 1
+ val = image[y*width+x][c];
+d3383 1
+a3384 1
+ if (val > maximum-25) goto skip_block;
+d3414 3
+d3426 1
+a3426 1
+ fprintf (stderr,_("Scaling with black %d, multipliers"), black);
+d3430 2
+a3431 2
+ for (row=0; row < height; row++)
+ for (col=0; col < width; col++)
+d3433 1
+a3433 1
+ val = image[row*width+col][c];
+d3437 1
+a3437 1
+ image[row*width+col][c] = CLIP(val);
+d3439 23
+d3463 2
+a3464 4
+ if (four_color_rgb) {
+ colors++;
+ FORC3 rgb_cam[c][3] = rgb_cam[c][1] /= 2;
+ } else {
+a3815 57
+/*
+ Bilateral Filtering was developed by C. Tomasi and R. Manduchi.
+ */
+void CLASS bilateral_filter()
+{
+ float (**window)[7], *kernel, scale_r, elut[1024], sum[5];
+ int c, i, wr, ws, wlast, row, col, y, x;
+ unsigned sep;
+
+ if (verbose) fprintf (stderr,_("Bilateral filtering...\n"));
+
+ wr = ceil(sigma_d*2); /* window radius */
+ ws = 2*wr + 1; /* window size */
+ window = (float (**)[7]) calloc ((ws+1)*sizeof *window +
+ ws*width*sizeof **window + ws*sizeof *kernel, 1);
+ merror (window, "bilateral_filter()");
+ for (i=0; i <= ws; i++)
+ window[i] = (float (*)[7]) (window+ws+1) + i*width;
+ kernel = (float *) window[ws] + wr;
+ for (i=-wr; i <= wr; i++)
+ kernel[i] = 256 / (2*SQR(sigma_d)) * i*i + 0.25;
+ scale_r = 256 / (2*SQR(sigma_r));
+ for (i=0; i < 1024; i++)
+ elut[i] = exp (-i/256.0);
+
+ for (wlast=-1, row=0; row < height; row++) {
+ while (wlast < row+wr) {
+ wlast++;
+ for (i=0; i <= ws; i++) /* rotate window rows */
+ window[(ws+i) % (ws+1)] = window[i];
+ if (wlast < height)
+ for (col=0; col < width; col++) {
+ FORCC window[ws-1][col][c] = image[wlast*width+col][c];
+ cam_to_cielab (image[wlast*width+col], window[ws-1][col]+4);
+ }
+ }
+ for (col=0; col < width; col++) {
+ memset (sum, 0, sizeof sum);
+ for (y=-wr; y <= wr; y++)
+ if ((unsigned)(row+y) < height)
+ for (x=-wr; x <= wr; x++)
+ if ((unsigned)(col+x) < width) {
+ sep = ( SQR(window[wr+y][col+x][4] - window[wr][col][4])
+ + SQR(window[wr+y][col+x][5] - window[wr][col][5])
+ + SQR(window[wr+y][col+x][6] - window[wr][col][6]) )
+ * scale_r + kernel[y] + kernel[x];
+ if (sep < 1024) {
+ FORCC sum[c] += elut[sep] * window[wr+y][col+x][c];
+ sum[4] += elut[sep];
+ }
+ }
+ FORCC image[row*width+col][c] = sum[c]/sum[4];
+ }
+ }
+ free (window);
+}
+
+d4029 1
+a4029 1
+ while ((c = fgetc(ifp)))
+d5512 2
+d5587 1
+a5587 1
+ { 28402,-6651,-983,-14699,32553,6467,-1746,1571,25283 } },
+d5758 1
+a5758 1
+ profile_length = 0;
+d6792 1
+a6792 1
+ int mix_green, row, col, c, i, j, k;
+a6879 1
+ mix_green = rgb_cam[1][1] == rgb_cam[1][3];
+a6893 2
+ else if (mix_green)
+ img[1] = (img[1] + img[3]) >> 1;
+d6896 1
+a6896 1
+ if (colors == 4 && (output_color || mix_green)) colors = 3;
+d7161 2
+a7162 2
+ int timestamp_only=0, thumbnail_only=0, identify_only=0, write_to_stdout=0;
+ int half_size=0, use_fuji_rotate=1, quality, i, c;
+d7195 1
+a7210 1
+ puts(_("-B <domain> <range> Apply bilateral filter to smooth noise"));
+d7220 2
+a7221 2
+ if ((cp = strchr (sp="BbrktqsH", opt)))
+ for (i=0; i < "21411111"[cp-sp]-'0'; i++)
+d7227 1
+a7227 2
+ case 'B': sigma_d = atof(argv[arg++]);
+ sigma_r = atof(argv[arg++]); break;
+d7368 1
+a7368 1
+ shrink = half_size && filters;
+a7417 2
+ height = iheight;
+ width = iwidth;
+d7426 1
+a7426 1
+ if (shrink) filters = 0;
+a7434 1
+ if (sigma_d > 0 && sigma_r > 0) bilateral_filter();
+d7437 3
+@
+
+
+1.364
+log
+@The last version broke 16-bit PPM byte order.
+@
+text
+@d26 1
+a26 1
+#define VERSION "8.53"
+d4163 2
+a4164 1
+ "","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65" };
+d5351 2
+d5529 1
+a5529 1
+ { "Panasonic DMC-FZ50", 0,
+d5531 1
+a5531 1
+ { "Panasonic DMC-L1", 0,
+d5533 1
+a5533 1
+ { "Panasonic DMC-LC1", 0,
+d5535 1
+a5535 1
+ { "Panasonic DMC-LX1", 0,
+d5537 1
+a5537 1
+ { "Panasonic DMC-LX2", 0,
+d6488 1
+d6491 1
+@
+
+
+1.363
+log
+@If the JPEG thumbnail has no EXIF table, add one.
+Built a color matrix for the Canon PowerShot S3 IS.
+@
+text
+@d26 1
+a26 1
+#define VERSION "8.52"
+d7086 1
+a7086 1
+ if (output_bps == 16 && !output_tiff && th.order == 0x4949)
+@
+
+
+1.362
+log
+@Added the Olympus SP510UZ.
+@
+text
+@d26 1
+a26 1
+#define VERSION "8.50"
+d1220 1
+a1220 9
+void CLASS jpeg_thumb (FILE *tfp)
+{
+ char *thumb = (char *) malloc (thumb_length);
+ merror (thumb, "jpeg_thumb()");
+ fread (thumb, 1, thumb_length, ifp);
+ thumb[0] = 0xff;
+ fwrite (thumb, 1, thumb_length, tfp);
+ free (thumb);
+}
+d5320 2
+d5804 1
+a5804 1
+ if (!is_raw) return;
+a6654 2
+ if (flip == -1) flip = tiff_flip;
+ if (flip == -1) flip = 0;
+d6666 3
+d6978 72
+a7049 1
+#define TOFF(ptr) ((char *)(&(ptr)) - (char *)(&th))
+a7053 1
+ struct tm *t;
+d7056 1
+a7056 1
+ int i, c, row, col, psize=0, soff, rstep, cstep;
+a7063 39
+
+ memset (&th, 0, sizeof th);
+ th.order = htonl(0x4d4d4949) >> 16;
+ th.magic = 42;
+ th.ifd = 10;
+ 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.i0 = 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, 271, 2, 64, TOFF(th.make));
+ tiff_set (&th.ntag, 272, 2, 72, TOFF(th.model));
+ 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);
+ tiff_set (&th.ntag, 305, 2, 32, TOFF(th.soft));
+ tiff_set (&th.ntag, 306, 2, 20, TOFF(th.date));
+ 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[0]));
+ tiff_set (&th.nexif, 33437, 5, 1, TOFF(th.rat[2]));
+ tiff_set (&th.nexif, 34855, 3, 1, iso_speed);
+ tiff_set (&th.nexif, 37386, 5, 1, TOFF(th.rat[4]));
+ for (i=0; i < 6; i++) th.rat[i] = 1000000;
+ th.rat[0] *= shutter;
+ th.rat[2] *= aperture;
+ th.rat[4] *= focal_len;
+ strncpy (th.make, make, 64);
+ strncpy (th.model, model, 64);
+ strcpy (th.soft, "dcraw v"VERSION);
+ t = gmtime (&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);
+
+d7065 1
+d7067 2
+a7068 2
+ if (psize)
+ fwrite (oprof, psize, 1, ofp);
+d7236 7
+a7303 7
+ 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;
+ }
+@
+
+
+1.361
+log
+@Support the Panasonic DMC-L1, Leica Digilux 3, and Casio EX-Z4.
+Run remove_zeroes() on most Panasonic and Leica models.
+Built a color matrix for the Canon PowerShot A610.
+Support Sinar IA file format.
+@
+text
+@d26 1
+a26 1
+#define VERSION "8.49"
+d5514 2
+d6419 1
+a6419 1
+ if (!strcmp(model,"SP500UZ"))
+@
+
+
+1.360
+log
+@Support internationalization if LOCALEDIR is defined.
+Added stretch() function for cameras with non-square pixels.
+Support "-h" and "-s" with Sinar 4-shot files.
+Never append "DNG" to the camera model.
+@
+text
+@d3 1
+a3 1
+ Copyright 1997-2006 by Dave Coffin, dcoffin a cybercom o net
+d26 1
+a26 1
+#define VERSION "8.48"
+d1665 6
+d4952 32
+d5324 2
+a5325 2
+ { "Canon PowerShot A610", 0, /* copied from the S60 */
+ { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } },
+d5532 2
+d5665 1
+a5665 1
+ { 6114240, "PENTAX", "Optio S4" ,1 }, /* or S4i */
+d5776 2
+d6199 1
+a6199 1
+ } else if (!strncmp(model,"Optio S4",8)) {
+d6344 1
+d6347 6
+d6357 1
+d6365 1
+d6372 1
+d6378 1
+a6391 1
+ load_raw = &CLASS unpacked_load_raw;
+d6538 1
+a6538 1
+ } else if (!strcmp(make,"Rollei")) {
+@
+
+
+1.359
+log
+@Added the Kodak DCS200 and Canon PowerShots A620 and S3 IS.
+@
+text
+@d26 1
+a26 1
+#define VERSION "8.46"
+d51 6
+d96 1
+a96 1
+char *ifname, make[64], model[72], model2[64], *meta_data, cdesc[5];
+d107 2
+a108 1
+int iheight, iwidth, shrink, flip, xmag, ymag;
+d245 1
+a245 1
+ fprintf (stderr, "%s: Out of memory in %s\n", ifname, where);
+d584 1
+a584 1
+ fprintf (stderr, "%s: decoder table overflow\n", ifname);
+d1361 1
+a1361 1
+ if (verbose) fprintf (stderr, "Phase One correction...\n");
+d1593 2
+d1600 8
+d1950 1
+a1950 1
+ fprintf (stderr, "%s: incorrect JPEG dimensions\n", ifname);
+d2403 1
+a2403 1
+ fprintf (stderr, "%s: decoder table overflow\n", ifname);
+d2562 1
+a2562 1
+ fprintf (stderr, "%s: \"%s\" matrix not found!\n", ifname, name);
+d2647 1
+a2647 1
+ fprintf (stderr, "Foveon interpolation...\n");
+d2673 1
+a2673 1
+ { fprintf (stderr, "%s: Invalid white balance \"%s\"\n", ifname, model2);
+d3080 1
+a3080 1
+ fprintf (stderr, "Fixed bad pixels at:");
+d3111 1
+a3111 1
+ fprintf (stderr, "%s is not a valid PGM file!\n", fname);
+d3114 1
+a3114 1
+ fprintf (stderr, "%s has the wrong dimensions!\n", fname);
+d3317 1
+a3317 1
+ fprintf (stderr, "%s: Cannot use camera white balance.\n", ifname);
+d3331 1
+a3331 1
+ fprintf (stderr, "Scaling with black=%d, pre_mul[] =", black);
+d3385 1
+a3385 1
+ if (verbose) fprintf (stderr, "Bilinear interpolation...\n");
+d3462 1
+a3462 1
+ if (verbose) fprintf (stderr, "VNG interpolation...\n");
+d3604 1
+a3604 1
+ if (verbose) fprintf (stderr, "AHD interpolation...\n");
+d3709 1
+a3709 1
+ if (verbose) fprintf (stderr, "Bilateral filtering...\n");
+d3767 1
+a3767 1
+ if (verbose) fprintf (stderr, "Highlight recovery...\n");
+d4267 1
+a4267 1
+ double dblack, cc[4][4], cm[4][3], cam_xyz[4][3], num, sx, sy;
+d4519 2
+a4520 4
+ sx = getrat();
+ sy = getrat();
+ if (sx > sy) xmag = sx / sy;
+ else ymag = sy / sx;
+d4765 1
+a4765 1
+ fprintf (stderr, "Reading metadata from %s...\n", jname);
+d4773 1
+a4773 1
+ fprintf (stderr, "Failed to read metadata from %s\n", jname);
+d5646 1
+a5646 1
+ is_raw = raw_color = use_gamma = xmag = ymag = 1;
+d5776 1
+a5776 1
+ xmag = ymag = 1;
+a5782 1
+ strcat (model," DNG");
+d5810 2
+a5811 2
+ if (height*2 < width) ymag = 2;
+ if (height > width) xmag = 2;
+d5819 1
+d5828 1
+d5952 3
+a5954 1
+ ymag = 2;
+d6464 1
+d6603 1
+a6603 1
+ fprintf (stderr, "%s: You must link dcraw.c with libjpeg!!\n", ifname);
+d6642 1
+a6642 1
+ fprintf (stderr, "%s has no embedded profile.\n", ifname);
+d6658 1
+a6658 1
+ fprintf (stderr, "Cannot open %s!\n", output);
+d6661 1
+a6661 1
+ fprintf (stderr, "Applying color profile...\n");
+d6760 2
+a6761 2
+ fprintf (stderr, raw_color ? "Building histograms...\n" :
+ "Converting to %s colorspace...\n", name[output_color-1]);
+d6796 1
+a6796 1
+ fprintf (stderr, "Rotating image 45 degrees...\n");
+d6824 37
+d6912 1
+a6912 1
+ char make[64], model[72], soft[32], date[20];
+d6941 2
+a6942 5
+ if (flip & 4) {
+ SWAP(height,width);
+ SWAP(ymag,xmag);
+ }
+ ppm = (uchar *) calloc (width, colors*xmag*output_bps/8);
+d6950 2
+a6951 2
+ tiff_set (&th.ntag, 256, 4, 1, xmag*width);
+ tiff_set (&th.ntag, 257, 4, 1, ymag*height);
+d6963 2
+a6964 2
+ tiff_set (&th.ntag, 278, 4, 1, ymag*height);
+ tiff_set (&th.ntag, 279, 4, 1, ymag*height*xmag*width*colors*output_bps/8);
+d6978 1
+a6978 1
+ strncpy (th.model, model, 72);
+d6991 1
+a6991 1
+ xmag*width, ymag*height, colors, (1 << output_bps)-1, cdesc);
+d6994 1
+a6994 1
+ colors/2+5, xmag*width, ymag*height, (1 << output_bps)-1);
+d6996 1
+a6996 2
+ if (output_bps == 8)
+ gamma_lut (lut);
+d7002 3
+a7004 4
+ FORCC for (i=0; i < xmag; i++)
+ if (output_bps == 8)
+ ppm [(col*xmag+i)*colors+c] = lut[image[soff][c]];
+ else ppm2[(col*xmag+i)*colors+c] = image[soff][c];
+d7006 2
+a7007 3
+ swab (ppm2, ppm2, xmag*width*colors*2);
+ for (i=0; i < ymag; i++)
+ fwrite (ppm, colors*output_bps/8, xmag*width, ofp);
+d7028 7
+d7036 18
+a7053 19
+ fprintf (stderr,
+ "\nRaw Photo Decoder \"dcraw\" v"VERSION
+ "\nby Dave Coffin, dcoffin a cybercom o net"
+ "\n\nUsage: %s [options] file1 file2 ...\n"
+ "\nValid options:"
+ "\n-v Print verbose messages"
+ "\n-c Write image data to standard output"
+ "\n-e Extract embedded thumbnail image"
+ "\n-i Identify files without decoding them"
+ "\n-z Change file dates to camera timestamp"
+ "\n-a Use automatic white balance"
+ "\n-w Use camera white balance, if possible"
+ "\n-r <nums> Set raw white balance (four values required)"
+ "\n-b <num> Adjust brightness (default = 1.0)"
+ "\n-k <num> Set black point"
+ "\n-K <file> Subtract dark frame (16-bit raw PGM)"
+ "\n-H [0-9] Highlight mode (0=clip, 1=no clip, 2+=recover)"
+ "\n-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)"
+ "\n-o [0-5] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ)"
+d7055 2
+a7056 2
+ "\n-o <file> Apply output ICC profile from file"
+ "\n-p <file> Apply camera ICC profile from file or \"embed\""
+d7058 11
+a7068 11
+ "\n-d Document Mode (no color, no interpolation)"
+ "\n-D Document Mode without scaling (totally raw)"
+ "\n-q [0-3] Set the interpolation quality"
+ "\n-h Half-size color image (twice as fast as \"-q 0\")"
+ "\n-f Interpolate RGGB as four colors"
+ "\n-B <domain> <range> Apply bilateral filter to reduce noise"
+ "\n-j Show Fuji Super CCD images tilted 45 degrees"
+ "\n-s [0-99] Select a different raw image from the same file"
+ "\n-4 Write 16-bit linear instead of 8-bit with gamma"
+ "\n-T Write TIFF instead of PPM"
+ "\n\n", argv[0]);
+a7070 1
+
+d7077 1
+a7077 1
+ fprintf (stderr, "Non-numeric argument to \"-%c\"\n", opt);
+a7108 2
+ case 'd': document_mode = 1; break;
+ case 'D': document_mode = 2; break;
+d7111 2
+d7118 1
+a7118 1
+ fprintf (stderr, "Unknown option \"-%c\".\n", opt);
+d7123 1
+a7123 1
+ fprintf (stderr, "No files to process.\n");
+d7128 1
+a7128 1
+ fprintf (stderr, "Will not write an image to the terminal!\n");
+d7157 1
+a7157 1
+ fprintf (stderr, "%s has no timestamp.\n", ifname);
+d7162 1
+a7162 1
+ fprintf (stderr, "%s time set to %d.\n", ifname, (int) timestamp);
+d7171 1
+a7171 1
+ fprintf (stderr, "%s has no thumbnail.\n", ifname);
+d7190 10
+a7199 5
+ printf ("\nFilename: %s\n", ifname);
+ printf ("Timestamp: %s", ctime(&timestamp));
+ printf ("Camera: %s %s\n", make, model);
+ printf ("ISO speed: %d\n", (int) iso_speed);
+ printf ("Shutter: ");
+d7202 8
+a7209 6
+ printf ("%0.1f sec\n", shutter);
+ printf ("Aperture: f/%0.1f\n", aperture);
+ printf ("Focal Length: %0.1f mm\n", focal_len);
+ printf ("Secondary pixels: %s\n", fuji_secondary ? "yes":"no");
+ printf ("Embedded ICC profile: %s\n", profile_length ? "yes":"no");
+ printf ("Decodable with dcraw: %s\n", is_raw ? "yes":"no");
+d7211 2
+a7212 2
+ printf ("Thumb size: %4d x %d\n", thumb_width, thumb_height);
+ printf ("Full size: %4d x %d\n", raw_width, raw_height);
+d7214 1
+a7214 1
+ fprintf (stderr, "Cannot decode %s\n", ifname);
+d7228 9
+a7236 4
+ if (fuji_width && use_fuji_rotate) {
+ fuji_width = (fuji_width - 1 + shrink) >> shrink;
+ iwidth = fuji_width / sqrt(0.5);
+ iheight = (iheight - fuji_width) / sqrt(0.5);
+a7237 2
+ iheight *= ymag;
+ iwidth *= xmag;
+d7240 3
+a7242 3
+ printf ("Image size: %4d x %d\n", width, height);
+ printf ("Output size: %4d x %d\n", iwidth, iheight);
+ printf ("Raw colors: %d", colors);
+d7244 1
+a7244 1
+ printf ("\nFilter pattern: ");
+d7249 1
+a7249 1
+ printf ("\nDaylight multipliers:");
+d7252 1
+a7252 1
+ printf ("\nCamera multipliers:");
+d7257 1
+a7257 1
+ printf ("%s is a %s %s image.\n", ifname, make, model);
+d7268 1
+a7268 1
+ "Loading %s %s image from %s...\n", make, model, ifname);
+d7299 1
+d7310 1
+a7310 1
+ strcpy (ofname, "standard output");
+d7325 1
+a7325 1
+ fprintf (stderr, "Writing data to %s ...\n", ofname);
+@
+
+
1.358
log
@Added the Pentax K10D.