diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 3d0505772..b4cfc452c 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -7359,8 +7359,6 @@ canon_cr2: } else if (!strcmp(model,"D1X")) { width -= 4; pixel_aspect = 0.5; - } else if (!strcmp(model,"D7000")) { - width -= 40; } else if (!strcmp(model,"D3100")) { width -= 24; left_margin = 4; diff --git a/rtengine/dcraw.patch b/rtengine/dcraw.patch index 3be7fafab..d803744d7 100644 --- a/rtengine/dcraw.patch +++ b/rtengine/dcraw.patch @@ -1,6 +1,6 @@ ---- dcraw.c 2010-11-11 20:35:59.000000000 -0500 -+++ dcraw.cc 2010-11-15 21:14:19.000000000 -0500 -@@ -1,3 +1,15 @@ +--- dcraw.c 2010-11-11 08:44:21.000000000 -0700 ++++ dcraw.cc 2010-12-29 12:57:16.000000000 -0700 +@@ -1,3 +1,12 @@ +/*RT*/#include +/*RT*/#include +/*RT*/#undef MAX @@ -9,147 +9,53 @@ +/*RT*/#define NO_JPEG +/*RT*/#define LOCALTIME +/*RT*/#define DJGPP -+/*RT*/#include -+ -+#include "myfile.h" + /* dcraw.c -- Dave Coffin's raw photo decoder Copyright 1997-2010 by Dave Coffin, dcoffin a cybercom o net -@@ -46,7 +58,9 @@ - NO_LCMS disables the "-p" option. - */ - #ifndef NO_JPEG --#include -+/*RT*/extern "C" { -+/*RT*/#include -+/*RT*/} - #endif - #ifndef NO_LCMS - #include -@@ -96,59 +110,84 @@ +@@ -96,11 +105,12 @@ typedef unsigned char uchar; typedef unsigned short ushort; -+// RT specify thread local storage -+#ifdef __GNUC__ -+#define THREAD_LOCAL static __thread -+#define THREAD_LOCK -+#else -+#define THREAD_LOCAL static -+#define THREAD_LOCK Glib::Mutex::Lock locker(*dcrMutex); -+#endif -+ -+// patch for gcc<=4.2 on OSX -+#ifdef __APPLE__ -+#define GCC_VERSION (__GNUC__ * 10000 \ -+ + __GNUC_MINOR__ * 100 \ -+ + __GNUC_PATCHLEVEL__) -+#if GCC_VERSION < 40300 -+#undef THREAD_LOCAL -+#undef THREAD_LOCK -+#define THREAD_LOCAL static -+#define THREAD_LOCK Glib::Mutex::Lock locker(*dcrMutex); -+#endif -+#endif -+ -+ ++#include "dcraw.h" /* All global variables are defined here, and all functions that access them are prefixed with "CLASS". Note that a thread-safe C++ class cannot have non-const static local variables. - */ --FILE *ifp, *ofp; --short order; --const char *ifname; --char *meta_data; --char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64]; --float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len; --time_t timestamp; --unsigned shot_order, kodak_cbpp, filters, exif_cfa, unique_id; --off_t strip_offset, data_offset; --off_t thumb_offset, meta_offset, profile_offset; --unsigned thumb_length, meta_length, profile_length; --unsigned thumb_misc, *oprof, fuji_layout, shot_select=0, multi_out=0; --unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress; --unsigned black, cblack[8], maximum, mix_green, raw_color, zero_is_bad; --unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error; --unsigned tile_width, tile_length, gpsdata[32], load_flags; --ushort raw_height, raw_width, height, width, top_margin, left_margin; --ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height; --int flip, tiff_flip, colors; --double pixel_aspect, aber[4]={1,1,1,1}, gamm[6]={ 0.45,4.5,0,0,0,0 }; --ushort (*image)[4], white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4]; --float bright=1, user_mul[4]={0,0,0,0}, threshold=0; --int half_size=0, four_color_rgb=0, document_mode=0, highlight=0; --int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=-1; --int output_color=1, output_bps=8, output_tiff=0, med_passes=0; --int no_auto_bright=0; --unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX }; +- */ ++ + FILE *ifp, *ofp; + short order; + const char *ifname; +@@ -128,13 +138,13 @@ + int output_color=1, output_bps=8, output_tiff=0, med_passes=0; + int no_auto_bright=0; + unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX }; -float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4]; -const double xyz_rgb[3][3] = { /* XYZ from RGB */ -+/*RT*/THREAD_LOCAL int ciff_base, ciff_len, exif_base, pre_filters; -+/*RT*/THREAD_LOCAL IMFILE *ifp; -+THREAD_LOCAL FILE * ofp; -+THREAD_LOCAL short order; -+THREAD_LOCAL const char *ifname; -+THREAD_LOCAL char *meta_data; -+THREAD_LOCAL char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64]; -+THREAD_LOCAL float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len; -+THREAD_LOCAL time_t timestamp; -+THREAD_LOCAL unsigned shot_order, kodak_cbpp, filters, exif_cfa, unique_id; -+THREAD_LOCAL off_t strip_offset, data_offset; -+THREAD_LOCAL off_t thumb_offset, meta_offset, profile_offset; -+THREAD_LOCAL unsigned thumb_length, meta_length, profile_length; -+THREAD_LOCAL unsigned thumb_misc, *oprof, fuji_layout, shot_select=0, multi_out=0; -+THREAD_LOCAL unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress; -+THREAD_LOCAL unsigned black, cblack[8], maximum, mix_green, raw_color, zero_is_bad; -+THREAD_LOCAL unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error; -+THREAD_LOCAL unsigned tile_width, tile_length, gpsdata[32], load_flags; -+THREAD_LOCAL ushort raw_height, raw_width, height, width, top_margin, left_margin; -+THREAD_LOCAL ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height; -+THREAD_LOCAL int flip, tiff_flip, colors; -+THREAD_LOCAL double pixel_aspect, aber[4]={1,1,1,1}, gamm[6]={ 0.45,4.5,0,0,0,0 }; -+THREAD_LOCAL ushort (*image)[4], white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4]; -+THREAD_LOCAL float bright=1, user_mul[4]={0,0,0,0}, threshold=0; -+THREAD_LOCAL int half_size=0, four_color_rgb=0, document_mode=0, highlight=0; -+THREAD_LOCAL int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=-1; -+THREAD_LOCAL int output_color=1, output_bps=8, output_tiff=0, med_passes=0; -+THREAD_LOCAL int no_auto_bright=0; -+THREAD_LOCAL unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX }; -+THREAD_LOCAL float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4]; -+static const double xyz_rgb[3][3] = { /* XYZ from RGB */ ++float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4];*/ ++const double xyz_rgb[3][3] = { // XYZ from RGB { 0.412453, 0.357580, 0.180423 }, { 0.212671, 0.715160, 0.072169 }, { 0.019334, 0.119193, 0.950227 } }; --const float d65_white[3] = { 0.950456, 1, 1.088754 }; + const float d65_white[3] = { 0.950456, 1, 1.088754 }; -int histogram[4][0x2000]; --void (*write_thumb)(), (*write_fun)(); --void (*load_raw)(), (*thumb_load_raw)(); --jmp_buf failure; -+static const float d65_white[3] = { 0.950456, 1, 1.088754 }; -+THREAD_LOCAL int histogram[4][0x2000]; -+THREAD_LOCAL void (*write_thumb)(), (*write_fun)(); -+THREAD_LOCAL void (*load_raw)(), (*thumb_load_raw)(); -+THREAD_LOCAL jmp_buf failure; - --struct decode { -+THREAD_LOCAL struct decode { - struct decode *branch[2]; - int leaf; - } first_decode[2048], *second_decode, *free_decode; - --struct tiff_ifd { -+THREAD_LOCAL struct tiff_ifd { - int width, height, bps, comp, phint, offset, flip, samples, bytes; - } tiff_ifd[10]; - --struct ph1 { -+THREAD_LOCAL struct ph1 { ++/*int histogram[4][0x2000]; + void (*write_thumb)(), (*write_fun)(); + void (*load_raw)(), (*thumb_load_raw)(); + jmp_buf failure; +@@ -152,8 +162,8 @@ int format, key_off, black, black_off, split_col, tag_21a; float tag_210; } ph1; -@@ -271,6 +310,7 @@ +- +-#define CLASS ++*/ ++#define CLASS DCraw:: + + #define FORC(cnt) for (c=0; c < cnt; c++) + #define FORC3 FORC(3) +@@ -271,6 +281,7 @@ fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp)); } data_error++; @@ -157,7 +63,7 @@ } ushort CLASS sget2 (uchar *s) -@@ -344,7 +384,7 @@ +@@ -344,7 +355,7 @@ { if (fread (pixel, 2, count, ifp) < count) derror(); if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) @@ -166,45 +72,72 @@ } void CLASS canon_600_fixed_wb (int temp) -@@ -538,8 +578,8 @@ +@@ -536,10 +547,10 @@ + getbits(-1) initializes the buffer + getbits(n) where 0 <= n <= 25 returns an n-bit integer */ - unsigned CLASS getbithuff (int nbits, ushort *huff) +-unsigned CLASS getbithuff (int nbits, ushort *huff) ++unsigned CLASS getbithuff_t::operator() (int nbits, ushort *huff) { - static unsigned bitbuf=0; - static int vbits=0, reset=0; -+ THREAD_LOCAL unsigned bitbuf=0; -+ THREAD_LOCAL int vbits=0, reset=0; ++/*RT static unsigned bitbuf=0; */ ++/*RT static int vbits=0, reset=0; */ unsigned c; if (nbits == -1) -@@ -1563,8 +1603,8 @@ +@@ -1286,7 +1297,7 @@ + free (pixel); + } - unsigned CLASS ph1_bithuff (int nbits, ushort *huff) +-void CLASS jpeg_thumb(); ++/*RT void CLASS jpeg_thumb(); */ + + void CLASS ppm_thumb() + { +@@ -1561,10 +1572,10 @@ + phase_one_correct(); + } + +-unsigned CLASS ph1_bithuff (int nbits, ushort *huff) ++unsigned CLASS ph1_bithuff_t::operator() (int nbits, ushort *huff) { - static UINT64 bitbuf=0; - static int vbits=0; -+ THREAD_LOCAL UINT64 bitbuf=0; -+ THREAD_LOCAL int vbits=0; ++/*RT static UINT64 bitbuf=0; */ ++/*RT static int vbits=0; */ unsigned c; if (nbits == -1) -@@ -1828,8 +1868,8 @@ +@@ -1690,7 +1701,7 @@ + } + } - unsigned CLASS pana_bits (int nbits) +-void CLASS unpacked_load_raw(); ++/*RT void CLASS unpacked_load_raw(); */ + + void CLASS sinar_4shot_load_raw() + { +@@ -1826,10 +1837,10 @@ + maximum = 0x3ff; + } + +-unsigned CLASS pana_bits (int nbits) ++unsigned CLASS pana_bits_t::operator() (int nbits) { - static uchar buf[0x4000]; - static int vbits; -+ THREAD_LOCAL uchar buf[0x4000]; -+ THREAD_LOCAL int vbits; ++/*RT static uchar buf[0x4000]; */ ++/*RT static int vbits;*/ int byte; if (!nbits) return vbits=0; -@@ -2118,11 +2158,11 @@ +@@ -2118,11 +2129,11 @@ METHODDEF(boolean) fill_input_buffer (j_decompress_ptr cinfo) { - static uchar jpeg_buffer[4096]; -+ THREAD_LOCAL uchar jpeg_buffer[4096]; ++/*RT static uchar jpeg_buffer[4096]; */ size_t nbytes; nbytes = fread (jpeg_buffer, 1, 4096, ifp); @@ -213,53 +146,37 @@ cinfo->src->next_input_byte = jpeg_buffer; cinfo->src->bytes_in_buffer = nbytes; return TRUE; -@@ -2396,7 +2436,7 @@ +@@ -2394,9 +2405,9 @@ + maximum = (1 << (thumb_misc & 31)) - 1; + } - void CLASS sony_decrypt (unsigned *data, int len, int start, int key) +-void CLASS sony_decrypt (unsigned *data, int len, int start, int key) ++void CLASS sony_decrypt_t::operator()(unsigned *data, int len, int start, int key) { - static unsigned pad[128], p; -+ THREAD_LOCAL unsigned pad[128], p; ++/*RT static unsigned pad[128], p;*/ if (start) { for (p=0; p < 4; p++) -@@ -2643,7 +2683,7 @@ +@@ -2643,7 +2654,7 @@ void CLASS foveon_decoder (unsigned size, unsigned code) { - static unsigned huff[1024]; -+ THREAD_LOCAL unsigned huff[1024]; ++/*RT static unsigned huff[1024];*/ struct decode *cur; int i, len; -@@ -3765,15 +3805,18 @@ - } +@@ -4327,7 +4338,7 @@ } - 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]; -- filters &= ~((filters & 0x55555555) << 1); -- } -- } -- if (half_size) filters = 0; -+ 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]; -+ /*RT*/ pre_filters = filters; -+ filters &= ~((filters & 0x55555555) << 1); -+ } -+ } -+ if (half_size) -+ filters = 0; } - void CLASS border_interpolate (int border) -@@ -4452,7 +4495,7 @@ +-int CLASS parse_tiff_ifd (int base); ++/*RT int CLASS parse_tiff_ifd (int base);*/ + + void CLASS parse_makernote (int base, int uptag) + { +@@ -4452,7 +4463,7 @@ } if (tag == 0xd && type == 7 && get2() == 0xaaaa) { fread (buf97, 1, sizeof buf97, ifp); @@ -268,7 +185,18 @@ if (i < 70 && buf97[i] < 3) flip = "065"[buf97[i]]-'0'; } -@@ -4836,7 +4879,7 @@ +@@ -4821,8 +4832,8 @@ + } + } + +-void CLASS parse_minolta (int base); +-int CLASS parse_tiff (int base); ++/*RT void CLASS parse_minolta (int base); */ ++/*RT int CLASS parse_tiff (int base);*/ + + int CLASS parse_tiff_ifd (int base) + { +@@ -4836,7 +4847,7 @@ unsigned sony_curve[] = { 0,0,0,0,0,4095 }; unsigned *buf, sony_offset=0, sony_length=0, sony_key=0; struct jhead jh; @@ -277,7 +205,7 @@ if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0]) return 1; -@@ -5254,12 +5297,13 @@ +@@ -5254,12 +5265,13 @@ fread (buf, sony_length, 1, ifp); sony_decrypt (buf, sony_length/4, 1, sony_key); sfp = ifp; @@ -296,7 +224,7 @@ ifp = sfp; free (buf); } -@@ -5284,6 +5328,8 @@ +@@ -5284,6 +5296,8 @@ { int doff; @@ -305,7 +233,7 @@ fseek (ifp, base, SEEK_SET); order = get2(); if (order != 0x4949 && order != 0x4d4d) return 0; -@@ -5458,7 +5504,7 @@ +@@ -5458,7 +5472,7 @@ { const char *file, *ext; char *jname, *jfile, *jext; @@ -314,7 +242,7 @@ ext = strrchr (ifname, '.'); file = strrchr (ifname, '/'); -@@ -5486,7 +5532,8 @@ +@@ -5486,7 +5500,8 @@ *jext = '0'; } if (strcmp (jname, ifname)) { @@ -324,7 +252,7 @@ if (verbose) fprintf (stderr,_("Reading metadata from %s ...\n"), jname); parse_tiff (12); -@@ -5824,7 +5871,11 @@ +@@ -5824,7 +5839,11 @@ order = get2(); hlen = get4(); if (get4() == 0x48454150) /* "HEAP" */ @@ -337,7 +265,7 @@ if (parse_tiff (save+6)) apply_tiff(); fseek (ifp, save+len, SEEK_SET); } -@@ -6845,6 +6896,12 @@ +@@ -6845,6 +6864,12 @@ fread (head, 1, 32, ifp); fseek (ifp, 0, SEEK_END); flen = fsize = ftell(ifp); @@ -350,7 +278,7 @@ if ((cp = (char *) memmem (head, 32, "MMMM", 4)) || (cp = (char *) memmem (head, 32, "IIII", 4))) { parse_phase_one (cp-head); -@@ -6852,6 +6909,8 @@ +@@ -6852,6 +6877,8 @@ } else if (order == 0x4949 || order == 0x4d4d) { if (!memcmp (head+6,"HEAPCCDR",8)) { data_offset = hlen; @@ -359,19 +287,25 @@ parse_ciff (hlen, flen - hlen); } else if (parse_tiff(0)) apply_tiff(); } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) && -@@ -7331,6 +7390,11 @@ +@@ -6893,6 +6920,7 @@ + fseek (ifp, 100, SEEK_SET); + parse_tiff (data_offset = get4()); + parse_tiff (thumb_offset+12); ++/*RT*/ exif_base = thumb_offset+12; + apply_tiff(); + } else if (!memcmp (head,"RIFF",4)) { + fseek (ifp, 0, SEEK_SET); +@@ -7331,6 +7359,9 @@ } else if (!strcmp(model,"D1X")) { width -= 4; pixel_aspect = 0.5; -+ } else if (!strcmp(model,"D7000")) { -+ width -= 40; + } else if (!strcmp(model,"D3100")) { + width -= 24; + left_margin = 4; } else if (!strcmp(model,"D40X") || !strcmp(model,"D60") || !strcmp(model,"D80") || -@@ -7548,7 +7612,7 @@ +@@ -7548,7 +7579,7 @@ } else if (!strcmp(model,"*ist DS")) { height -= 2; } else if (!strcmp(model,"K-x")) { @@ -380,7 +314,7 @@ filters = 0x16161616; } else if (!strcmp(model,"Optio S")) { if (fsize == 3178560) { -@@ -8560,13 +8624,13 @@ +@@ -8560,13 +8591,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) @@ -396,607 +330,17 @@ { int arg, status=0; int timestamp_only=0, thumbnail_only=0, identify_only=0; -@@ -8679,7 +8743,7 @@ +@@ -8679,7 +8710,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 '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; -@@ -8943,3 +9007,594 @@ +@@ -8943,3 +8974,4 @@ } return status; } +*/ -+ -+#include -+#include -+#include -+#include -+#include -+ -+namespace rtengine { -+ -+extern Settings* settings; -+ -+Glib::Mutex* dcrMutex=NULL; -+ -+int RawImage::loadRaw (bool loadData) { -+ -+ THREAD_LOCK -+ -+ ifname = fname.c_str(); -+ image = NULL; -+ exif_base = -1; -+ ciff_base = -1; -+ ciff_len = -1; -+ verbose = settings->verbose; -+ oprof = NULL; -+ -+ ifp = gfopen (ifname); -+ if (!ifp) -+ return 3; -+ -+ thumb_length = 0; -+ thumb_offset = 0; -+ thumb_load_raw = 0; -+ use_camera_wb = 0; -+ highlight = 1; -+ half_size = 0; -+ -+ //***************** Read ALL raw file info -+ identify (); -+ if (!is_raw) { -+ fclose(ifp); -+ return 2; -+ } -+ this->filters = ::filters; -+ this->height = ::height; -+ this->width = ::width; -+ this->colors = ::colors; -+ this->profile_len = ::profile_length; -+ -+ this->maximum = ::maximum; -+ this->fuji_width = ::fuji_width; -+ -+ for(int i=0; i<8;i++) -+ for(int j=0;j<8;j++) -+ this->white[i][j] = ::white[i][j]; -+ -+ if (flip==5) -+ this->rotate_deg = 270; -+ else if (flip==3) -+ this->rotate_deg = 180; -+ else if (flip==6) -+ this->rotate_deg = 90; -+ else -+ this->rotate_deg = 0; -+ -+ this->make = strdup (::make); -+ this->model = strdup (::model); -+ this->iso_speed = ::iso_speed; -+ this->shutter = ::shutter; -+ this->aperture = ::aperture; -+ this->focal_len = ::focal_len; -+ this->timestamp = ::timestamp; -+ this->exifbase = ::exif_base; -+ this->ciff_base = ::ciff_base; -+ this->ciff_len = ::ciff_len; -+ this->thumbOffset = ::thumb_offset; -+ this->thumbLength = ::thumb_length; -+ this->thumbHeight = ::thumb_height; -+ this->thumbWidth = ::thumb_width; -+ if (!thumb_load_raw && thumb_offset && write_thumb == jpeg_thumb) -+ this->thumbType = 1; -+ else if (!thumb_load_raw && thumb_offset && write_thumb == ppm_thumb) -+ this->thumbType = 2; -+ else { -+ this->thumbType = 0; -+ this->thumbWidth = ::width; -+ this->thumbHeight = ::height; -+ } -+ -+ if( loadData ){ -+ allocData(); -+ use_camera_wb = 1; -+ shrink = 0; -+ if (settings->verbose) printf ("Loading %s %s image from %s...\n", make, model, fname.c_str()); -+ iheight = height; -+ iwidth = width; -+ -+ // dcraw needs this global variable to hold pixel data -+ image = (UshORt (*)[4])calloc (height*width*sizeof *image + meta_length, 1); -+ meta_data = (char *) (image + height*width); -+ if(!image) -+ return 200; -+ -+ if (setjmp (failure)) { -+ if (image) -+ free (image); -+ fclose (ifp); -+ return 100; -+ } -+ -+ // Load raw pixels data -+ fseek (ifp, data_offset, SEEK_SET); -+ (*load_raw)(); -+ -+ // Load embedded profile -+ if (profile_length) { -+ fseek (ifp, profile_offset, SEEK_SET); -+ fread ( this->profile_data, 1, this->profile_len, ifp); -+ } -+ fclose(ifp); -+ -+ // Setting the black_point and cblack -+ int i = ::cblack[3]; -+ for (int c=0; c <3; c++) -+ if (i > ::cblack[c]) -+ i = ::cblack[c]; -+ for (int c=0; c < 4; c++) -+ ::cblack[c] -= i; -+ ::black += i; -+ for (int c=0; c < 4; c++) this->cblack[c] = ::cblack[c]; -+ for (int c=0; c < 4; c++) this->cam_mul[c] = ::cam_mul[c]; -+ for (int c=0; c < 4; c++) this->pre_mul[c] = ::pre_mul[c]; -+ for (int a = 0; a < 3; a++) -+ for (int b = 0; b < 3; b++) -+ this->coeff[a][b] = ::rgb_cam[a][b]; -+ -+ this->black_point = ::black; -+ -+ // copy pixel raw data: the compressed format earns space -+ if (this->filters) { -+ for (int row = 0; row < height; row++) -+ for (int col = 0; col < width; col++) -+ this->data[row][col] = image[row * width + col][FC(row,col)]; -+ } else { -+ for (int row = 0; row < height; row++) -+ for (int col = 0; col < width; col++) { -+ this->data[row][3 * col + 0] = image[row * width + col][0]; -+ this->data[row][3 * col + 1] = image[row * width + col][1]; -+ this->data[row][3 * col + 2] = image[row * width + col][2]; -+ } -+ } -+ free(image); // we don't need this anymore -+ } -+ else -+ { -+ fclose(ifp); -+ } -+ return 0; -+} -+ -+ -+ -+int getRawFileBasicInfo (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, int& rotation, int& thumbWidth, int& thumbHeight, int& thumbOffset, int& thumbType) { -+ -+ THREAD_LOCK -+ -+ int status=0; -+ -+ 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; -+ return status; -+ } -+ identify (); -+ if (!is_raw || colors>3) { -+ status = 3; -+ fclose (ifp); -+ 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); -+ return !is_raw; -+} -+ -+#include -+ -+rtengine::Thumbnail* rtengine::Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, int &w, int &h, int fixwh) { -+ -+ THREAD_LOCK -+ -+ image = NULL; -+ ifname = fname.c_str(); -+ exif_base = -1; -+ ciff_base = -1; -+ ciff_len = -1; -+ verbose = settings->verbose; -+ oprof = NULL; -+ ifp = gfopen (ifname); -+ if (!ifp) { -+ printf("DCRAW: failed0\n"); -+ return NULL; -+ } -+ -+ if (setjmp (failure)) { -+ printf("DCRAW: failed1\n"); -+ fclose (ifp); -+ return NULL; -+ } -+ -+ identify (); -+ if (!is_raw || colors>3) { -+ printf("DCRAW: failed2\n"); -+ fclose(ifp); -+ return NULL; -+ } -+ -+ rml.exifBase = exif_base; -+ rml.ciffBase = ciff_base; -+ rml.ciffLength = ciff_len; -+ -+ rtengine::Thumbnail* tpp = rtengine::Thumbnail::loadFromMemory(fdata(thumb_offset,ifp),thumb_length,w,h,fixwh); -+ -+ fclose(ifp); -+ -+ if ( tpp == 0 ) -+ { -+ printf("DCRAW: failed4\n"); -+ return NULL; -+ } -+ -+ 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; -+ } -+ -+ return tpp; -+} -+ -+rtengine::Thumbnail* rtengine::Thumbnail::loadFromRaw (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, int &w, int &h, int fixwh) { -+ -+ THREAD_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 (ifname); -+ if (!ifp) { -+ return NULL; -+ } -+ -+t1.set (); -+ -+ if (setjmp (failure)) { -+ if (image) -+ free (image); -+ fclose (ifp); -+ 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); -+ 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> 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 && yr[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 unsigned int[65536>>tpp->aeHistCompression]; -+ memset (tpp->aeHistogram, 0, (65536>>tpp->aeHistCompression)*sizeof(int)); -+ int radd = 4; -+ int gadd = 4; -+ 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; jaeHistogram[CLIP((int)(tpp->camwbGreen*image[i* ::width+j][1]))>>tpp->aeHistCompression]+=gadd; -+ else if (FISRED(filter,i,j)) -+ tpp->aeHistogram[CLIP((int)(tpp->camwbRed*image[i* ::width+j][0]))>>tpp->aeHistCompression]+=radd; -+ else if (FISBLUE(filter,i,j)) -+ tpp->aeHistogram[CLIP((int)(tpp->camwbBlue*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; jdefGain * image[i* ::width+j][1]; -+ if (d>64000) -+ continue; -+ avg_g += d; -+ gn++; -+ } -+ if (FISRED(filter,i,j)) { -+ double d = tpp->defGain * image[i* ::width+j][0]; -+ if (d>64000) -+ continue; -+ avg_r += d; -+ rn++; -+ } -+ if (FISBLUE(filter,i,j)) { -+ double d = tpp->defGain * image[i* ::width+j][2]; -+ if (d>64000) -+ continue; -+ avg_b += d; -+ bn++; -+ } -+ } -+ } -+ -+ double reds = avg_r/rn * tpp->camwbRed; -+ double greens = avg_g/gn * tpp->camwbGreen; -+ double blues = avg_b/bn * 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); -+ -+ return tpp; -+} -+ -+ -+} -+