728 lines
20 KiB
Diff
728 lines
20 KiB
Diff
--- dcraw.c 2009-08-31 17:24:29.000000000 +0200
|
|
+++ dcraw.cc 2009-10-09 08:55:28.000000000 +0200
|
|
@@ -1,3 +1,16 @@
|
|
+/*RT*/#include <glib.h>
|
|
+/*RT*/#include <glib/gstdio.h>
|
|
+/*RT*/int ciff_base, ciff_len, exif_base, pre_filters;
|
|
+/*RT*/#undef MAX
|
|
+/*RT*/#undef MIN
|
|
+/*RT*/#define NO_LCMS
|
|
+/*RT*/#define NO_JPEG
|
|
+/*RT*/#define LOCALTIME
|
|
+/*RT*/#define DJGPP
|
|
+/*RT*/#include <rtthumbnail.h>
|
|
+
|
|
+#include "myfile.h"
|
|
+
|
|
/*
|
|
dcraw.c -- Dave Coffin's raw photo decoder
|
|
Copyright 1997-2009 by Dave Coffin, dcoffin a cybercom o net
|
|
@@ -46,7 +59,9 @@
|
|
NO_LCMS disables the "-p" option.
|
|
*/
|
|
#ifndef NO_JPEG
|
|
-#include <jpeglib.h>
|
|
+/*RT*/extern "C" {
|
|
+/*RT*/#include <jpeglib.h>
|
|
+/*RT*/}
|
|
#endif
|
|
#ifndef NO_LCMS
|
|
#include <lcms.h>
|
|
@@ -101,7 +116,8 @@
|
|
access them are prefixed with "CLASS". Note that a thread-safe
|
|
C++ class cannot have non-const static local variables.
|
|
*/
|
|
-FILE *ifp, *ofp;
|
|
+/*RT*/IMFILE *ifp;
|
|
+FILE * ofp;
|
|
short order;
|
|
const char *ifname;
|
|
char *meta_data;
|
|
@@ -271,6 +287,7 @@
|
|
fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp));
|
|
}
|
|
data_error = 1;
|
|
+ /*RT*/ longjmp (failure, 1);
|
|
}
|
|
|
|
ushort CLASS sget2 (uchar *s)
|
|
@@ -344,7 +361,7 @@
|
|
{
|
|
if (fread (pixel, 2, count, ifp) < count) derror();
|
|
if ((order == 0x4949) == (ntohs(0x1234) == 0x1234))
|
|
- swab (pixel, pixel, count*2);
|
|
+ swab ((char*)pixel, (char*)pixel, count*2);
|
|
}
|
|
|
|
void CLASS canon_black (double dark[2], int nblack)
|
|
@@ -2131,7 +2148,7 @@
|
|
size_t nbytes;
|
|
|
|
nbytes = fread (jpeg_buffer, 1, 4096, ifp);
|
|
- swab (jpeg_buffer, jpeg_buffer, nbytes);
|
|
+ swab ((char*)jpeg_buffer, (char*)jpeg_buffer, nbytes);
|
|
cinfo->src->next_input_byte = jpeg_buffer;
|
|
cinfo->src->bytes_in_buffer = nbytes;
|
|
return TRUE;
|
|
@@ -3773,6 +3790,7 @@
|
|
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];
|
|
+/*RT*/ pre_filters = filters;
|
|
filters &= ~((filters & 0x55555555) << 1);
|
|
}
|
|
}
|
|
@@ -4824,7 +4842,7 @@
|
|
unsigned sony_curve[] = { 0,0,0,0,0,4095 };
|
|
unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
|
|
struct jhead jh;
|
|
- FILE *sfp;
|
|
+/*RT*/ IMFILE *sfp;
|
|
|
|
if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0])
|
|
return 1;
|
|
@@ -5200,12 +5218,13 @@
|
|
fread (buf, sony_length, 1, ifp);
|
|
sony_decrypt (buf, sony_length/4, 1, sony_key);
|
|
sfp = ifp;
|
|
- if ((ifp = tmpfile())) {
|
|
- fwrite (buf, sony_length, 1, ifp);
|
|
- fseek (ifp, 0, SEEK_SET);
|
|
+/*RT*/ ifp = fopen (buf, sony_length);
|
|
+// if ((ifp = tmpfile())) {
|
|
+// fwrite (buf, sony_length, 1, ifp);
|
|
+// fseek (ifp, 0, SEEK_SET);
|
|
parse_tiff_ifd (-sony_offset);
|
|
- fclose (ifp);
|
|
- }
|
|
+// fclose (ifp);
|
|
+// }
|
|
ifp = sfp;
|
|
free (buf);
|
|
}
|
|
@@ -5231,6 +5250,8 @@
|
|
int doff, max_samp=0, raw=-1, thm=-1, i;
|
|
struct jhead jh;
|
|
|
|
+ /*RT*/ exif_base = base;
|
|
+
|
|
fseek (ifp, base, SEEK_SET);
|
|
order = get2();
|
|
if (order != 0x4949 && order != 0x4d4d) return;
|
|
@@ -5399,7 +5420,7 @@
|
|
{
|
|
const char *file, *ext;
|
|
char *jname, *jfile, *jext;
|
|
- FILE *save=ifp;
|
|
+/*RT*/ IMFILE *save=ifp;
|
|
|
|
ext = strrchr (ifname, '.');
|
|
file = strrchr (ifname, '/');
|
|
@@ -5427,7 +5448,8 @@
|
|
*jext = '0';
|
|
}
|
|
if (strcmp (jname, ifname)) {
|
|
- if ((ifp = fopen (jname, "rb"))) {
|
|
+/*RT*/ if ((ifp = fopen (jname))) {
|
|
+// if ((ifp = fopen (jname, "rb"))) {
|
|
if (verbose)
|
|
fprintf (stderr,_("Reading metadata from %s ...\n"), jname);
|
|
parse_tiff (12);
|
|
@@ -5757,7 +5779,11 @@
|
|
order = get2();
|
|
hlen = get4();
|
|
if (get4() == 0x48454150) /* "HEAP" */
|
|
+/*RT*/ {
|
|
+/*RT*/ ciff_base = save+hlen;
|
|
+/*RT*/ ciff_len = len-hlen;
|
|
parse_ciff (save+hlen, len-hlen);
|
|
+/*RT*/ }
|
|
parse_tiff (save+6);
|
|
fseek (ifp, save+len, SEEK_SET);
|
|
}
|
|
@@ -6656,6 +6682,12 @@
|
|
fread (head, 1, 32, ifp);
|
|
fseek (ifp, 0, SEEK_END);
|
|
fsize = ftell(ifp);
|
|
+
|
|
+ /*RT*/ if (fsize<100000) {
|
|
+ is_raw = 0;
|
|
+ return;
|
|
+ }
|
|
+
|
|
if ((cp = (char *) memmem (head, 32, "MMMM", 4)) ||
|
|
(cp = (char *) memmem (head, 32, "IIII", 4))) {
|
|
parse_phase_one (cp-head);
|
|
@@ -6663,6 +6695,8 @@
|
|
} else if (order == 0x4949 || order == 0x4d4d) {
|
|
if (!memcmp (head+6,"HEAPCCDR",8)) {
|
|
data_offset = hlen;
|
|
+/*RT*/ ciff_base = hlen;
|
|
+/*RT*/ ciff_len = fsize - hlen;
|
|
parse_ciff (hlen, fsize - hlen);
|
|
} else {
|
|
parse_tiff(0);
|
|
@@ -8354,13 +8388,13 @@
|
|
FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8;
|
|
else FORCC ppm2[col*colors+c] = curve[image[soff][c]];
|
|
if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa)
|
|
- swab (ppm2, ppm2, width*colors*2);
|
|
+ swab ((char*)ppm2, (char*)ppm2, width*colors*2);
|
|
fwrite (ppm, colors*output_bps/8, width, ofp);
|
|
}
|
|
free (ppm);
|
|
}
|
|
|
|
-int CLASS main (int argc, const char **argv)
|
|
+/*int CLASS main (int argc, const char **argv)
|
|
{
|
|
int arg, status=0;
|
|
int timestamp_only=0, thumbnail_only=0, identify_only=0;
|
|
@@ -8473,7 +8507,7 @@
|
|
case 'i': identify_only = 1; break;
|
|
case 'c': write_to_stdout = 1; break;
|
|
case 'v': verbose = 1; break;
|
|
- case 'h': half_size = 1; /* "-h" implies "-f" */
|
|
+ case 'h': half_size = 1; /* "-h" implies "-f" *//*
|
|
case 'f': four_color_rgb = 1; break;
|
|
case 'A': FORC4 greybox[c] = atoi(argv[arg++]);
|
|
case 'a': use_auto_wb = 1; break;
|
|
@@ -8733,3 +8767,537 @@
|
|
}
|
|
return status;
|
|
}
|
|
+*/
|
|
+
|
|
+#include <common.h>
|
|
+#include <rawmetadatalocation.h>
|
|
+#include <glibmm.h>
|
|
+#include <utils.h>
|
|
+#include <colortemp.h>
|
|
+#include <settings.h>
|
|
+
|
|
+namespace rtengine {
|
|
+
|
|
+extern Settings* settings;
|
|
+
|
|
+Glib::Mutex* dcrMutex=NULL;
|
|
+
|
|
+int loadRaw (const char* fname, struct RawImage *ri) {
|
|
+
|
|
+ static const double xyzd50_srgb[3][3] =
|
|
+ { { 0.436083, 0.385083, 0.143055 },
|
|
+ { 0.222507, 0.716888, 0.060608 },
|
|
+ { 0.013930, 0.097097, 0.714022 } };
|
|
+
|
|
+dcrMutex->lock ();
|
|
+
|
|
+ ifname = fname;//strdup (fname);
|
|
+ image = NULL;
|
|
+
|
|
+ exif_base = -1;
|
|
+ ciff_base = -1;
|
|
+ ciff_len = -1;
|
|
+ verbose = settings->verbose;
|
|
+ oprof = NULL;
|
|
+ ri->data = NULL;
|
|
+ ri->allocation = NULL;
|
|
+ ri->profile_data = NULL;
|
|
+ ifp = gfopen (fname);
|
|
+ if (!ifp) {
|
|
+ dcrMutex->unlock ();
|
|
+ return 3;
|
|
+ }
|
|
+
|
|
+ use_camera_wb = 0;
|
|
+ highlight = 1;
|
|
+ half_size = 0;
|
|
+
|
|
+ identify ();
|
|
+ use_camera_wb = 1;
|
|
+ if (!is_raw) {
|
|
+ fclose(ifp);
|
|
+ dcrMutex->unlock ();
|
|
+ return 2;
|
|
+ }
|
|
+
|
|
+ shrink = 0;
|
|
+
|
|
+ if (settings->verbose) printf ("Loading %s %s image from %s...\n", make, model, fname);
|
|
+ iheight = height;
|
|
+ iwidth = width;
|
|
+
|
|
+ image = (UshORt (*)[4])calloc (height*width*sizeof *image + meta_length, 1);
|
|
+ meta_data = (char *) (image + height*width);
|
|
+
|
|
+ if (setjmp (failure)) {
|
|
+ if (image)
|
|
+ free (image);
|
|
+ if (ri->data)
|
|
+ free(ri->data);
|
|
+ fclose (ifp);
|
|
+ dcrMutex->unlock ();
|
|
+ return 100;
|
|
+ }
|
|
+
|
|
+ fseek (ifp, data_offset, SEEK_SET);
|
|
+ (*load_raw)();
|
|
+
|
|
+ ri->profile_len = 0;
|
|
+ ri->profile_data = NULL;
|
|
+ if (profile_length) {
|
|
+ ri->profile_len = profile_length;
|
|
+ ri->profile_data = (char *) malloc (profile_length);
|
|
+ fseek (ifp, profile_offset, SEEK_SET);
|
|
+ fread (ri->profile_data, 1, profile_length, ifp);
|
|
+ }
|
|
+
|
|
+ fclose(ifp);
|
|
+ if (zero_is_bad) remove_zeroes();
|
|
+
|
|
+ ri->red_multiplier = pre_mul[0];
|
|
+ ri->green_multiplier = pre_mul[1];
|
|
+ ri->blue_multiplier = pre_mul[2];
|
|
+
|
|
+ scale_colors();
|
|
+ pre_interpolate ();
|
|
+
|
|
+ ri->width = width;
|
|
+ ri->height = height;
|
|
+ ri->filters = filters;
|
|
+
|
|
+ if (filters) {
|
|
+ ri->allocation = (short unsigned int*)calloc(height*width, sizeof(unsigned short));
|
|
+ ri->data = (unsigned short**)calloc(height, sizeof(unsigned short*));
|
|
+ for (int i=0; i<height; i++)
|
|
+ ri->data[i] = ri->allocation + i*width;
|
|
+ for (int row = 0; row < height; row++)
|
|
+ for (int col = 0; col < width; col++)
|
|
+ if (ISGREEN(ri,row,col))
|
|
+ ri->data[row][col] = image[row*width+col][1];
|
|
+ else if (ISRED(ri,row,col))
|
|
+ ri->data[row][col] = image[row*width+col][0];
|
|
+ else
|
|
+ ri->data[row][col] = image[row*width+col][2];
|
|
+ }
|
|
+ else {
|
|
+ ri->allocation = (short unsigned int*)calloc(3*height*width, sizeof(unsigned short));
|
|
+ ri->data = (unsigned short**)calloc(height, sizeof(unsigned short*));
|
|
+ for (int i=0; i<height; i++)
|
|
+ ri->data[i] = ri->allocation + 3*i*width;
|
|
+ for (int row = 0; row < height; row++)
|
|
+ for (int col = 0; col < width; col++) {
|
|
+ ri->data[row][3*col+0] = image[row*width+col][0];
|
|
+ ri->data[row][3*col+1] = image[row*width+col][1];
|
|
+ ri->data[row][3*col+2] = image[row*width+col][2];
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (flip==5)
|
|
+ ri->rotate_deg = 270;
|
|
+ else if (flip==3)
|
|
+ ri->rotate_deg = 180;
|
|
+ else if (flip==6)
|
|
+ ri->rotate_deg = 90;
|
|
+ else
|
|
+ ri->rotate_deg = 0;
|
|
+
|
|
+ ri->make = strdup (make);
|
|
+ ri->model = strdup (model);
|
|
+
|
|
+ ri->exifbase = exif_base;
|
|
+ ri->prefilters = pre_filters;
|
|
+ ri->ciff_base = ciff_base;
|
|
+ ri->ciff_len = ciff_len;
|
|
+
|
|
+ ri->camwb_red = ri->red_multiplier / pre_mul[0];
|
|
+ ri->camwb_green = ri->green_multiplier / pre_mul[1];
|
|
+ ri->camwb_blue = ri->blue_multiplier / pre_mul[2];
|
|
+
|
|
+ ri->defgain = 1.0 / MIN(MIN(pre_mul[0],pre_mul[1]),pre_mul[2]);
|
|
+
|
|
+ ri->fuji_width = fuji_width;
|
|
+
|
|
+ for (int a=0; a < 3; a++)
|
|
+ for (int b=0; b < 3; b++)
|
|
+ ri->coeff[a][b] = rgb_cam[a][b];
|
|
+
|
|
+ free (image);
|
|
+dcrMutex->unlock ();
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int getRawFileBasicInfo (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, int& rotation, int& thumbWidth, int& thumbHeight, int& thumbOffset, int& thumbType) {
|
|
+
|
|
+ int status=0;
|
|
+
|
|
+dcrMutex->lock ();
|
|
+
|
|
+ exif_base = -1;
|
|
+ ciff_base = -1;
|
|
+ ciff_len = -1;
|
|
+
|
|
+ half_size = 1;
|
|
+ bright = 1.0;
|
|
+ verbose = settings->verbose;
|
|
+ use_camera_wb = 1;
|
|
+
|
|
+ thumb_length = 0;
|
|
+ thumb_offset = 0;
|
|
+ thumb_load_raw = 0;
|
|
+ status = 1;
|
|
+
|
|
+ ifname = fname.c_str();
|
|
+ if (!(ifp = gfopen (ifname))) {
|
|
+ status = 2;
|
|
+ dcrMutex->unlock ();
|
|
+ return status;
|
|
+ }
|
|
+ identify ();
|
|
+ if (!is_raw || colors>3) {
|
|
+ status = 3;
|
|
+ fclose (ifp);
|
|
+ dcrMutex->unlock ();
|
|
+ return status;
|
|
+ }
|
|
+
|
|
+ thumbOffset = thumb_offset;
|
|
+
|
|
+ if (flip==5)
|
|
+ rotation = 270;
|
|
+ else if (flip==3)
|
|
+ rotation = 180;
|
|
+ else if (flip==6)
|
|
+ rotation = 90;
|
|
+ else
|
|
+ rotation = 0;
|
|
+
|
|
+ thumbWidth = thumb_width;
|
|
+ thumbHeight = thumb_height;
|
|
+ if (!thumb_load_raw && thumb_offset && write_thumb == jpeg_thumb)
|
|
+ thumbType = 1;
|
|
+ else if (!thumb_load_raw && thumb_offset && write_thumb == ppm_thumb)
|
|
+ thumbType = 2;
|
|
+ else {
|
|
+ thumbType = 0;
|
|
+ thumbWidth = width;
|
|
+ thumbHeight = height;
|
|
+ }
|
|
+
|
|
+ rml.exifBase = exif_base;
|
|
+ rml.ciffBase = ciff_base;
|
|
+ rml.ciffLength = ciff_len;
|
|
+
|
|
+ fclose (ifp);
|
|
+dcrMutex->unlock ();
|
|
+ return !is_raw;
|
|
+}
|
|
+
|
|
+#include <mytime.h>
|
|
+
|
|
+rtengine::Thumbnail* rtengine::Thumbnail::loadFromRaw (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, int &w, int &h, int fixwh) {
|
|
+
|
|
+dcrMutex->lock ();
|
|
+MyTime t0, t1, t2, t3, t4, t5, t6;
|
|
+t0.set ();
|
|
+
|
|
+ image = NULL;
|
|
+ ifname = fname.c_str();
|
|
+ exif_base = -1;
|
|
+ ciff_base = -1;
|
|
+ ciff_len = -1;
|
|
+ verbose = settings->verbose;
|
|
+ oprof = NULL;
|
|
+ ifp = gfopen (fname.c_str());
|
|
+ if (!ifp) {
|
|
+ dcrMutex->unlock ();
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+t1.set ();
|
|
+
|
|
+ if (setjmp (failure)) {
|
|
+ if (image)
|
|
+ free (image);
|
|
+ fclose (ifp);
|
|
+ dcrMutex->unlock ();
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ use_camera_wb = 0;
|
|
+ highlight = 1;
|
|
+ half_size = 0;
|
|
+ shrink = 0;
|
|
+ identify ();
|
|
+ use_camera_wb = 1;
|
|
+ if (!is_raw || colors>3) {
|
|
+ fclose(ifp);
|
|
+ dcrMutex->unlock ();
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+t2.set();
|
|
+
|
|
+ iheight = ::height;
|
|
+ iwidth = ::width;
|
|
+
|
|
+ image = (UshORt (*)[4])calloc (::height*::width*sizeof *image + meta_length, 1);
|
|
+ meta_data = (char *) (image + ::height*::width);
|
|
+
|
|
+ if (settings->verbose) printf ("Loading %s %s image from %s...\n", make, model, fname.c_str());
|
|
+ fseek (ifp, data_offset, SEEK_SET);
|
|
+ (*load_raw)();
|
|
+ if (zero_is_bad) remove_zeroes();
|
|
+
|
|
+ rtengine::Thumbnail* tpp = new rtengine::Thumbnail;
|
|
+
|
|
+ tpp->isRaw = true;
|
|
+ tpp->embProfileLength = 0;
|
|
+ if (profile_length) {
|
|
+ tpp->embProfileLength = profile_length;
|
|
+ tpp->embProfileData = new unsigned char[profile_length];
|
|
+ fseek (ifp, profile_offset, SEEK_SET);
|
|
+ fread (tpp->embProfileData, 1, profile_length, ifp);
|
|
+ tpp->embProfile = cmsOpenProfileFromMem (tpp->embProfileData, tpp->embProfileLength);
|
|
+ }
|
|
+ else {
|
|
+ tpp->embProfile = NULL;
|
|
+ tpp->embProfileData = NULL;
|
|
+ }
|
|
+
|
|
+ fclose(ifp);
|
|
+ tpp->redMultiplier = pre_mul[0];
|
|
+ tpp->greenMultiplier = pre_mul[1];
|
|
+ tpp->blueMultiplier = pre_mul[2];
|
|
+
|
|
+t3.set ();
|
|
+
|
|
+ scale_colors();
|
|
+ pre_interpolate ();
|
|
+
|
|
+ unsigned filter = filters;
|
|
+ int firstgreen = 1;
|
|
+ // locate first green location in the first row
|
|
+ while (!FISGREEN(filter,1,firstgreen))
|
|
+ firstgreen++;
|
|
+
|
|
+ int skip = 1;
|
|
+ if (fixwh==1) // fix height, scale width
|
|
+ skip = (::height-firstgreen-1) / h;
|
|
+ else
|
|
+ skip = (::width-firstgreen-1) / w;
|
|
+ if (skip%2)
|
|
+ skip--;
|
|
+ if (skip<1)
|
|
+ skip = 1;
|
|
+
|
|
+ int hskip = skip, vskip = skip;
|
|
+ if (!strcmp (model, "D1X"))
|
|
+ hskip *=2;
|
|
+
|
|
+ rml.exifBase = exif_base;
|
|
+ rml.ciffBase = ciff_base;
|
|
+ rml.ciffLength = ciff_len;
|
|
+ tpp->camwbRed = tpp->redMultiplier / pre_mul[0];
|
|
+ tpp->camwbGreen = tpp->greenMultiplier / pre_mul[1];
|
|
+ tpp->camwbBlue = tpp->blueMultiplier / pre_mul[2];
|
|
+
|
|
+ tpp->defGain = 1.0 / MIN(MIN(pre_mul[0],pre_mul[1]),pre_mul[2]);
|
|
+ tpp->gammaCorrected = true;
|
|
+
|
|
+ int ix = 0;
|
|
+ int rofs = 0;
|
|
+ int tmpw = (::width-2)/hskip;
|
|
+ int tmph = (::height-2)/vskip;
|
|
+ Image16* tmpImg = new Image16 (tmpw, tmph);
|
|
+ if (filter) {
|
|
+ for (int row=1, y=0; row< ::height-1 && y<tmph; row+=vskip, y++) {
|
|
+ rofs = row*::width;
|
|
+ for (int col=firstgreen,x=0; col< ::width-1 && x<tmpw; col+=hskip, x++) {
|
|
+ int ofs = rofs+col;
|
|
+ int g = image[ofs][1];
|
|
+ int r, b;
|
|
+ if (FISRED(filter,row,col+1)) {
|
|
+ r = (image[ofs+1][0] + image[ofs-1][0]) >> 1;
|
|
+ b = (image[ofs+::width][2] + image[ofs-::width][2]) >> 1;
|
|
+ }
|
|
+ else {
|
|
+ b = (image[ofs+1][2] + image[ofs-1][2]) >> 1;
|
|
+ r = (image[ofs+::width][0] + image[ofs-::width][0]) >> 1;
|
|
+ }
|
|
+ tmpImg->r[y][x] = r;
|
|
+ tmpImg->g[y][x] = g;
|
|
+ tmpImg->b[y][x] = b;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ for (int row=1, y=0; row< ::height-1 && y<tmph; row+=vskip, y++) {
|
|
+ rofs = row*::width;
|
|
+ for (int col=firstgreen,x=0; col< ::width-1 && x<tmpw; col+=hskip, x++) {
|
|
+ int ofs = rofs+col;
|
|
+ tmpImg->r[y][x] = image[ofs][0];
|
|
+ tmpImg->g[y][x] = image[ofs][1];
|
|
+ tmpImg->b[y][x] = image[ofs][2];
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (fuji_width) {
|
|
+ int fw = fuji_width / hskip;
|
|
+ double step = sqrt(0.5);
|
|
+ int wide = fw / step;
|
|
+ int high = (tmph - fw) / step;
|
|
+ Image16* fImg = new Image16 (wide, high);
|
|
+ float r, c;
|
|
+
|
|
+ for (int row=0; row < high; row++)
|
|
+ for (int col=0; col < wide; col++) {
|
|
+ unsigned ur = r = fw + (row-col)*step;
|
|
+ unsigned uc = c = (row+col)*step;
|
|
+ if (ur > tmph-2 || uc > tmpw-2)
|
|
+ continue;
|
|
+ double fr = r - ur;
|
|
+ double fc = c - uc;
|
|
+ int oofs = (ur*tmpw + uc)*3;
|
|
+ int fofs = (row*wide+col)*3;
|
|
+ fImg->r[row][col] = (tmpImg->r[ur][uc] * (1-fc) + tmpImg->r[ur][uc+1] * fc) * (1-fr) + (tmpImg->r[ur+1][uc] * (1-fc) + tmpImg->r[ur+1][uc+1] * fc) * fr;
|
|
+ fImg->g[row][col] = (tmpImg->g[ur][uc] * (1-fc) + tmpImg->g[ur][uc+1] * fc) * (1-fr) + (tmpImg->g[ur+1][uc] * (1-fc) + tmpImg->g[ur+1][uc+1] * fc) * fr;
|
|
+ fImg->b[row][col] = (tmpImg->b[ur][uc] * (1-fc) + tmpImg->b[ur][uc+1] * fc) * (1-fr) + (tmpImg->b[ur+1][uc] * (1-fc) + tmpImg->b[ur+1][uc+1] * fc) * fr;
|
|
+ }
|
|
+ delete tmpImg;
|
|
+ tmpImg = fImg;
|
|
+ }
|
|
+
|
|
+
|
|
+ if (fixwh==1) // fix height, scale width
|
|
+ w = tmpw * h / tmph;
|
|
+ else
|
|
+ h = tmph * w / tmpw;
|
|
+
|
|
+ tpp->thumbImg = tmpImg->resize (w, h, TI_Bilinear);
|
|
+ delete tmpImg;
|
|
+
|
|
+ if (fuji_width)
|
|
+ tpp->scale = (double)(::height - fuji_width) / sqrt(0.5) / h;
|
|
+ else
|
|
+ tpp->scale = (double)::height / h;
|
|
+
|
|
+t4.set ();
|
|
+
|
|
+ // generate histogram for auto exposure
|
|
+ tpp->aeHistCompression = 3;
|
|
+ tpp->aeHistogram = new int[65536>>tpp->aeHistCompression];
|
|
+ memset (tpp->aeHistogram, 0, (65536>>tpp->aeHistCompression)*sizeof(int));
|
|
+ int radd = 4;
|
|
+ int gadd = 2;
|
|
+ int badd = 4;
|
|
+ if (!filter)
|
|
+ radd = gadd = badd = 1;
|
|
+ for (int i=8; i< ::height-8; i++) {
|
|
+ int start, end;
|
|
+ if (fuji_width) {
|
|
+ int fw = fuji_width;
|
|
+ start = ABS(fw-i) + 8;
|
|
+ end = MIN( ::height+ ::width-fw-i, fw+i) - 8;
|
|
+ }
|
|
+ else {
|
|
+ start = 8;
|
|
+ end = ::width-8;
|
|
+ }
|
|
+ for (int j=start; j<end; j++)
|
|
+ if (FISGREEN(filter,i,j))
|
|
+ tpp->aeHistogram[image[i* ::width+j][1]>>tpp->aeHistCompression]+=gadd;
|
|
+ else if (FISRED(filter,i,j))
|
|
+ tpp->aeHistogram[image[i* ::width+j][0]>>tpp->aeHistCompression]+=radd;
|
|
+ else if (FISBLUE(filter,i,j))
|
|
+ tpp->aeHistogram[image[i* ::width+j][2]>>tpp->aeHistCompression]+=badd;
|
|
+ }
|
|
+
|
|
+t5.set ();
|
|
+
|
|
+ // generate autoWB
|
|
+ double avg_r = 0;
|
|
+ double avg_g = 0;
|
|
+ double avg_b = 0;
|
|
+ int rn = 0, gn = 0, bn = 0;
|
|
+
|
|
+ for (int i=32; i< ::height-32; i++) {
|
|
+ int start, end;
|
|
+ if (fuji_width) {
|
|
+ int fw = fuji_width;
|
|
+ start = ABS(fw-i) + 32;
|
|
+ end = MIN( ::height+ ::width-fw-i, fw+i) - 32;
|
|
+ }
|
|
+ else {
|
|
+ start = 32;
|
|
+ end = ::width-32;
|
|
+ }
|
|
+ for (int j=start; j<end; j++) {
|
|
+ if (FISGREEN(filter,i,j)) {
|
|
+ double d = tpp->defGain * image[i* ::width+j][1];
|
|
+ if (d>64000)
|
|
+ continue;
|
|
+ avg_g += d*d*d*d*d*d;
|
|
+ gn++;
|
|
+ }
|
|
+ if (FISRED(filter,i,j)) {
|
|
+ double d = tpp->defGain * image[i* ::width+j][0];
|
|
+ if (d>64000)
|
|
+ continue;
|
|
+ avg_r += d*d*d*d*d*d;
|
|
+ rn++;
|
|
+ }
|
|
+ if (FISBLUE(filter,i,j)) {
|
|
+ double d = tpp->defGain * image[i* ::width+j][2];
|
|
+ if (d>64000)
|
|
+ continue;
|
|
+ avg_b += d*d*d*d*d*d;
|
|
+ bn++;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ double reds = pow (avg_r/rn, 1.0/6.0) * tpp->camwbRed;
|
|
+ double greens = pow (avg_g/gn, 1.0/6.0) * tpp->camwbGreen;
|
|
+ double blues = pow (avg_b/bn, 1.0/6.0) * tpp->camwbBlue;
|
|
+
|
|
+ double rm = rgb_cam[0][0]*reds + rgb_cam[0][1]*greens + rgb_cam[0][2]*blues;
|
|
+ double gm = rgb_cam[1][0]*reds + rgb_cam[1][1]*greens + rgb_cam[1][2]*blues;
|
|
+ double bm = rgb_cam[2][0]*reds + rgb_cam[2][1]*greens + rgb_cam[2][2]*blues;
|
|
+
|
|
+ ColorTemp::mul2temp (rm, gm, bm, tpp->autowbTemp, tpp->autowbGreen);
|
|
+
|
|
+t6.set ();
|
|
+
|
|
+if (settings->verbose) printf ("0: %d, 1: %d, 2: %d, 3: %d, 4: %d, 5: %d All: %d\n", t1.etime(t0), t2.etime(t1), t3.etime(t2), t4.etime(t3), t5.etime(t4), t6.etime(t5), t6.etime(t0));
|
|
+
|
|
+ int deg = 0;
|
|
+ if (flip==5)
|
|
+ deg = 270;
|
|
+ else if (flip==3)
|
|
+ deg = 180;
|
|
+ else if (flip==6)
|
|
+ deg = 90;
|
|
+
|
|
+ if (deg>0) {
|
|
+ Image16* rot = tpp->thumbImg->rotate (deg);
|
|
+ delete tpp->thumbImg;
|
|
+ tpp->thumbImg = rot;
|
|
+ }
|
|
+
|
|
+ for (int a=0; a < 3; a++)
|
|
+ for (int b=0; b < 3; b++)
|
|
+ tpp->colorMatrix[a][b] = rgb_cam[a][b];
|
|
+
|
|
+ tpp->init ();
|
|
+
|
|
+ free (image);
|
|
+
|
|
+dcrMutex->unlock ();
|
|
+
|
|
+ return tpp;
|
|
+}
|
|
+
|
|
+
|
|
+}
|
|
+
|