From 100d9868e5dbea2acabd479a8d7f8984a52cd058 Mon Sep 17 00:00:00 2001 From: Jan Rinze Date: Wed, 3 Nov 2010 01:14:43 +0100 Subject: [PATCH] up to date version of dcraw.patch --- rtengine/dcraw.patch | 1859 +++++++++++++++++++++++------------------- 1 file changed, 1002 insertions(+), 857 deletions(-) diff --git a/rtengine/dcraw.patch b/rtengine/dcraw.patch index 7d059f919..c2962966d 100644 --- a/rtengine/dcraw.patch +++ b/rtengine/dcraw.patch @@ -1,857 +1,1002 @@ -0a1,12 -> /*RT*/#include -> /*RT*/#include -> /*RT*/#undef MAX -> /*RT*/#undef MIN -> /*RT*/#define NO_LCMS -> /*RT*/#define NO_JPEG -> /*RT*/#define LOCALTIME -> /*RT*/#define DJGPP -> /*RT*/#include -> -> #include "myfile.h" -> -49c61,63 -< #include ---- -> /*RT*/extern "C" { -> /*RT*/#include -> /*RT*/} -98a113,135 -> // 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 -> -> -104,132c141,171 -< 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 }; -< 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 */ -136,140c175,179 -< 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; -142c181 -< struct decode { ---- -> THREAD_LOCAL struct decode { -147c186 -< struct tiff_ifd { ---- -> THREAD_LOCAL struct tiff_ifd { -151c190 -< struct ph1 { ---- -> THREAD_LOCAL struct ph1 { -273a313 -> /*RT*/ longjmp (failure, 1); -347c387 -< swab (pixel, pixel, count*2); ---- -> swab ((char*)pixel, (char*)pixel, count*2); -541,542c581,582 -< static unsigned bitbuf=0; -< static int vbits=0, reset=0; ---- -> THREAD_LOCAL unsigned bitbuf=0; -> THREAD_LOCAL int vbits=0, reset=0; -1563,1564c1603,1604 -< static UINT64 bitbuf=0; -< static int vbits=0; ---- -> THREAD_LOCAL UINT64 bitbuf=0; -> THREAD_LOCAL int vbits=0; -1826,1827c1866,1867 -< static uchar buf[0x4000]; -< static int vbits; ---- -> THREAD_LOCAL uchar buf[0x4000]; -> THREAD_LOCAL int vbits; -2116c2156 -< static uchar jpeg_buffer[4096]; ---- -> THREAD_LOCAL uchar jpeg_buffer[4096]; -2120c2160 -< swab (jpeg_buffer, jpeg_buffer, nbytes); ---- -> swab ((char*)jpeg_buffer, (char*)jpeg_buffer, nbytes); -2394c2434 -< static unsigned pad[128], p; ---- -> THREAD_LOCAL unsigned pad[128], p; -2641c2681 -< static unsigned huff[1024]; ---- -> THREAD_LOCAL unsigned huff[1024]; -3763,3771c3803,3814 -< 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; -4820c4863 -< FILE *sfp; ---- -> /*RT*/ IMFILE *sfp; -5228,5230c5271,5274 -< 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); -5232,5233c5276,5277 -< fclose (ifp); -< } ---- -> // fclose (ifp); -> // } -5258a5303,5304 -> /*RT*/ exif_base = base; -> -5427c5473 -< FILE *save=ifp; ---- -> /*RT*/ IMFILE *save=ifp; -5455c5501,5502 -< if ((ifp = fopen (jname, "rb"))) { ---- -> /*RT*/ if ((ifp = fopen (jname))) { -> // if ((ifp = fopen (jname, "rb"))) { -5792a5840,5842 -> /*RT*/ { -> /*RT*/ ciff_base = save+hlen; -> /*RT*/ ciff_len = len-hlen; -5793a5844 -> /*RT*/ } -6740a6792,6797 -> -> /*RT*/ if (fsize<100000) { -> is_raw = 0; -> return; -> } -> -6747a6805,6806 -> /*RT*/ ciff_base = hlen; -> /*RT*/ ciff_len = fsize - hlen; -6860a6920,6921 -> if (height == 2868 && width == 4352) /* Pentax K-x */ -> width = 4308; -7193a7255,7256 -> } else if (!strcmp(model,"D7000")) { -> width -= 40; -7408c7471 -< width = 4309; ---- -> width = 4308; -8497c8560 -< swab (ppm2, ppm2, width*colors*2); ---- -> swab ((char*)ppm2, (char*)ppm2, width*colors*2); -8503c8566 -< int CLASS main (int argc, const char **argv) ---- -> /*int CLASS main (int argc, const char **argv) -8616c8679 -< case 'h': half_size = 1; /* "-h" implies "-f" */ ---- -> case 'h': half_size = 1; /* "-h" implies "-f" *//* -8879a8943,9537 -> */ -> -> #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 (fname.c_str()); -> 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 -> } -> 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 (fname.c_str()); -> 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; -> -> char *thumb_buffer malloc(thumb_length+64); // malloc instead of on the stack. -> if ( thumb_buffer == NULL ) -> { -> printf("DCRAW: failed3\n"); -> return NULL; -> } -> fseek(ifp,thumb_offset,SEEK_SET); -> fread(thumb_buffer,1,thumb_length,ifp); -> fclose(ifp); -> -> rtengine::Thumbnail* tpp = rtengine::Thumbnail::loadFromMemory(thumb_buffer,thumb_length,w,h,fixwh); -> free(thumb_buffer); -> 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 (fname.c_str()); -> 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 rofs = row*::width; -> for (int col=firstgreen,x=0; col< ::width-1 && 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 rofs = row*::width; -> for (int col=firstgreen,x=0; col< ::width-1 && 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 unsigned 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 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 if (FISGREEN(filter,i,j)) { -> double d = tpp->defGain * 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; -> } -> -> -> } -> +--- dcraw.c 2010-10-29 15:11:49.000000000 +0200 ++++ dcraw.cc 2010-11-02 19:02:54.000000000 +0100 +@@ -1,3 +1,15 @@ ++/*RT*/#include ++/*RT*/#include ++/*RT*/#undef MAX ++/*RT*/#undef MIN ++/*RT*/#define NO_LCMS ++/*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 @@ + 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 ++ ++ + /* + 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 }; +-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 */ + { 0.412453, 0.357580, 0.180423 }, + { 0.212671, 0.715160, 0.072169 }, + { 0.019334, 0.119193, 0.950227 } }; +-const float d65_white[3] = { 0.950456, 1, 1.088754 }; +-int histogram[4][0x2000]; +-void (*write_thumb)(), (*write_fun)(); +-void (*load_raw)(), (*thumb_load_raw)(); +-jmp_buf failure; ++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 format, key_off, black, black_off, split_col, tag_21a; + float tag_210; + } ph1; +@@ -271,6 +310,7 @@ + fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp)); + } + data_error++; ++ /*RT*/ longjmp (failure, 1); + } + + ushort CLASS sget2 (uchar *s) +@@ -344,7 +384,7 @@ + { + if (fread (pixel, 2, count, ifp) < count) derror(); + if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) +- swab (pixel, pixel, count*2); ++ swab ((char*)pixel, (char*)pixel, count*2); + } + + void CLASS canon_600_fixed_wb (int temp) +@@ -538,8 +578,8 @@ + */ + unsigned CLASS getbithuff (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; + unsigned c; + + if (nbits == -1) +@@ -1560,8 +1600,8 @@ + + unsigned CLASS ph1_bithuff (int nbits, ushort *huff) + { +- static UINT64 bitbuf=0; +- static int vbits=0; ++ THREAD_LOCAL UINT64 bitbuf=0; ++ THREAD_LOCAL int vbits=0; + unsigned c; + + if (nbits == -1) +@@ -1823,8 +1863,8 @@ + + unsigned CLASS pana_bits (int nbits) + { +- static uchar buf[0x4000]; +- static int vbits; ++ THREAD_LOCAL uchar buf[0x4000]; ++ THREAD_LOCAL int vbits; + int byte; + + if (!nbits) return vbits=0; +@@ -2113,11 +2153,11 @@ + METHODDEF(boolean) + fill_input_buffer (j_decompress_ptr cinfo) + { +- static uchar jpeg_buffer[4096]; ++ THREAD_LOCAL uchar jpeg_buffer[4096]; + size_t nbytes; + + nbytes = fread (jpeg_buffer, 1, 4096, ifp); +- swab (jpeg_buffer, jpeg_buffer, nbytes); ++ swab ((char*)jpeg_buffer, (char*)jpeg_buffer, nbytes); + cinfo->src->next_input_byte = jpeg_buffer; + cinfo->src->bytes_in_buffer = nbytes; + return TRUE; +@@ -2391,7 +2431,7 @@ + + void CLASS sony_decrypt (unsigned *data, int len, int start, int key) + { +- static unsigned pad[128], p; ++ THREAD_LOCAL unsigned pad[128], p; + + if (start) { + for (p=0; p < 4; p++) +@@ -2638,7 +2678,7 @@ + + void CLASS foveon_decoder (unsigned size, unsigned code) + { +- static unsigned huff[1024]; ++ THREAD_LOCAL unsigned huff[1024]; + struct decode *cur; + int i, len; + +@@ -3760,15 +3800,18 @@ + } + } + 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) +@@ -4817,7 +4860,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; +@@ -5225,12 +5268,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); + } +@@ -5256,6 +5300,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; +@@ -5424,7 +5470,7 @@ + { + const char *file, *ext; + char *jname, *jfile, *jext; +- FILE *save=ifp; ++/*RT*/ IMFILE *save=ifp; + + ext = strrchr (ifname, '.'); + file = strrchr (ifname, '/'); +@@ -5452,7 +5498,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); +@@ -5790,7 +5837,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); + } +@@ -6738,6 +6789,12 @@ + fread (head, 1, 32, ifp); + fseek (ifp, 0, SEEK_END); + flen = 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); +@@ -6745,6 +6802,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, flen - hlen); + } else { + parse_tiff(0); +@@ -6858,6 +6917,8 @@ + if (height == 3136 && width == 4736) /* Pentax K-7 */ + { height = 3122; width = 4684; + top_margin = 2; filters = 0x16161616; } ++ if (height == 2868 && width == 4352) /* Pentax K-x */ ++ width = 4308; + if (height == 3014 && width == 4096) /* Ricoh GX200 */ + width = 4014; + if (dng_version) { +@@ -7191,6 +7252,8 @@ + } else if (!strcmp(model,"D1X")) { + width -= 4; + pixel_aspect = 0.5; ++ } else if (!strcmp(model,"D7000")) { ++ width -= 40; + } else if (!strcmp(model,"D40X") || + !strcmp(model,"D60") || + !strcmp(model,"D80") || +@@ -7405,7 +7468,7 @@ + } else if (!strcmp(model,"K20D")) { + filters = 0x16161616; + } else if (!strcmp(model,"K-x")) { +- width = 4309; ++ width = 4308; + filters = 0x16161616; + } else if (!strcmp(model,"Optio S")) { + if (fsize == 3178560) { +@@ -8494,13 +8557,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; +@@ -8613,7 +8676,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; +@@ -8877,3 +8940,598 @@ + } + 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 (fname.c_str()); ++ 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 ++ } ++ 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 (fname.c_str()); ++ 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; ++ ++ char *thumb_buffer = (char *)malloc(thumb_length+64); // malloc instead of on the stack. ++ if ( thumb_buffer == NULL ) ++ { ++ printf("DCRAW: failed3\n"); ++ return NULL; ++ } ++ fseek(ifp,thumb_offset,SEEK_SET); ++ fread(thumb_buffer,1,thumb_length,ifp); ++ fclose(ifp); ++ ++ rtengine::Thumbnail* tpp = rtengine::Thumbnail::loadFromMemory(thumb_buffer,thumb_length,w,h,fixwh); ++ free(thumb_buffer); ++ 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 (fname.c_str()); ++ 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 = 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; jaeHistogram[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; 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; ++} ++ ++ ++} ++