Files
rawTherapee/rtengine/dcraw.patch
2010-11-02 18:56:56 +01:00

858 lines
25 KiB
Diff

0a1,12
> /*RT*/#include <glib.h>
> /*RT*/#include <glib/gstdio.h>
> /*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"
>
49c61,63
< #include <jpeglib.h>
---
> /*RT*/extern "C" {
> /*RT*/#include <jpeglib.h>
> /*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 <common.h>
> #include <rawmetadatalocation.h>
> #include <utils.h>
> #include <colortemp.h>
> #include <settings.h>
>
> 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 <mytime.h>
>
> 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<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 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<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;
> 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;
> }
>
>
> }
>