diff --git a/rtengine/CA_correct_RT.cc b/rtengine/CA_correct_RT.cc index 6349f999e..2e78254f9 100644 --- a/rtengine/CA_correct_RT.cc +++ b/rtengine/CA_correct_RT.cc @@ -21,6 +21,9 @@ // along with this program. If not, see . // //////////////////////////////////////////////////////////////// + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% int RawImageSource::LinEqSolve(int nDim, float* pfMatr, float* pfVect, float* pfSolution) { @@ -103,6 +106,8 @@ void RawImageSource::CA_correct_RT() { #define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } #define SQR(x) ((x)*(x)) + //static const float pre_mul[3] = {MIN(ri->red_multiplier,ri->green_multiplier), ri->green_multiplier, \ + MIN(ri->blue_multiplier,ri->green_multiplier)}; static const float clip_pt = ri->defgain; @@ -112,8 +117,8 @@ void RawImageSource::CA_correct_RT() { float (*Gtmp); Gtmp = (float (*)) calloc ((height)*(width), sizeof *Gtmp); - const int border=8; - const int border2=16; + static const int border=8; + static const int border2=16; //order of 2d polynomial fit (polyord), and numpar=polyord^2 int polyord=4, numpar=16; //number of blocks used in the fit @@ -135,7 +140,7 @@ void RawImageSource::CA_correct_RT() { //flag indicating success or failure of polynomial fit int res; //shifts to location of vertical and diagonal neighbors - const int v1=TS, v2=2*TS, /* v3=3*TS,*/ v4=4*TS;//, p1=-TS+1, p2=-2*TS+2, p3=-3*TS+3, m1=TS+1, m2=2*TS+2, m3=3*TS+3; + static const int v1=TS, v2=2*TS, v3=3*TS, v4=4*TS;//, p1=-TS+1, p2=-2*TS+2, p3=-3*TS+3, m1=TS+1, m2=2*TS+2, m3=3*TS+3; float eps=1e-5; //tolerance to avoid dividing by zero @@ -146,13 +151,13 @@ void RawImageSource::CA_correct_RT() { //measured CA shift parameters for a tile float CAshift[2][3]; //polynomial fit coefficients - float polymat[3][2][256], shiftmat[3][2][16], fitparams[3][2][16]; + float polymat[3][2][1296], shiftmat[3][2][36], fitparams[3][2][36]; //residual CA shift amount within a plaquette float shifthfrac[3], shiftvfrac[3]; //temporary storage for median filter float temp, p[9]; //temporary parameters for tile CA evaluation - float gdiff, deltgrb; + float gdiff, deltgrb, denom; //interpolated G at edge of plaquette float Ginthfloor, Ginthceil, Gint, RBint, gradwt; //interpolated color difference at edge of plaquette @@ -160,15 +165,20 @@ void RawImageSource::CA_correct_RT() { //data for evaluation of block CA shift variance float blockave[2][3]={{0,0,0},{0,0,0}}, blocksqave[2][3]={{0,0,0},{0,0,0}}, blockdenom[2][3]={{0,0,0},{0,0,0}}, blockvar[2][3]; //low and high pass 1D filters of G in vertical/horizontal directions - float glpfh, glpfv; + float glpfh, glpfv, ghpfh, ghpfv; //max allowed CA shift - const float bslim = 3.99; + static const float bslim = 3.99; //gaussians for low pass filtering of G and R/B - //static const float gaussg[5] = {0.171582, 0.15839, 0.124594, 0.083518, 0.0477063};//sig=2.5 - //static const float gaussrb[3] = {0.332406, 0.241376, 0.0924212};//sig=1.25 + static const float gaussg[5] = {0.171582, 0.15839, 0.124594, 0.083518, 0.0477063};//sig=2.5 + static const float gaussrb[3] = {0.332406, 0.241376, 0.0924212};//sig=1.25 //block CA shift values and weight assigned to block + //char *buffer1; // vblsz*hblsz*3*2 + //float (*blockshifts)[3][2]; // vblsz*hblsz*3*2 + float blockshifts[10000][3][2]; //fixed memory allocation + float blockwt[10000]; //fixed memory allocation + char *buffer; // TS*TS*16 //rgb data in a tile @@ -215,19 +225,11 @@ void RawImageSource::CA_correct_RT() { vblsz=ceil((float)(height+border2)/(TS-border2)+2+vz1); hblsz=ceil((float)(width+border2)/(TS-border2)+2+hz1); - //block CA shift values and weight assigned to block - char *buffer1; // vblsz*hblsz*(3*2+1) - float (*blockwt); // vblsz*hblsz - float (*blockshifts)[3][2]; // vblsz*hblsz*3*2 - //float blockshifts[1000][3][2]; //fixed memory allocation - //float blockwt[1000]; //fixed memory allocation - - buffer1 = (char *) malloc(vblsz*hblsz*(3*2+1)*sizeof(float)); - //merror(buffer1,"CA_correct()"); - memset(buffer1,0,vblsz*hblsz*(3*2+1)*sizeof(float)); - // block CA shifts - blockwt = (float (*)) (buffer1); - blockshifts = (float (*)[3][2]) (buffer1+(vblsz*hblsz*sizeof(float))); + /*buffer1 = (char *) malloc(vblsz*hblsz*3*2*sizeof(float)); + merror(buffer1,"CA_correct()"); + memset(buffer1,0,vblsz*hblsz*3*2*sizeof(float)); + // block CA shifts + blockshifts = (float (*)[3][2]) buffer1;*/ @@ -255,7 +257,7 @@ void RawImageSource::CA_correct_RT() { c = FC(rr,cc); indx=row*width+col; indx1=rr*TS+cc; - rgb[indx1][c] = (rawData[row][col])/65535.0f; + rgb[indx1][c] = (ri->data[row][col])/65535.0f; //rgb[indx1][c] = image[indx][c]/65535.0f;//for dcraw implementation } @@ -272,7 +274,7 @@ void RawImageSource::CA_correct_RT() { for (rr=0; rrdata[(height-rr-2)][left+cc])/65535.0f; //rgb[(rrmax+rr)*TS+cc][c] = (image[(height-rr-2)*width+left+cc][c])/65535.0f;//for dcraw implementation } } @@ -287,7 +289,7 @@ void RawImageSource::CA_correct_RT() { for (rr=rrmin; rrdata[(top+rr)][(width-cc-2)])/65535.0f; //rgb[rr*TS+ccmax+cc][c] = (image[(top+rr)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation } } @@ -297,7 +299,7 @@ void RawImageSource::CA_correct_RT() { for (rr=0; rrdata[border2-rr][border2-cc])/65535.0f; //rgb[(rr)*TS+cc][c] = (rgb[(border2-rr)*TS+(border2-cc)][c]);//for dcraw implementation } } @@ -305,7 +307,7 @@ void RawImageSource::CA_correct_RT() { for (rr=0; rrdata[(height-rr-2)][(width-cc-2)])/65535.0f; //rgb[(rrmax+rr)*TS+ccmax+cc][c] = (image[(height-rr-2)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation } } @@ -313,7 +315,7 @@ void RawImageSource::CA_correct_RT() { for (rr=0; rrdata[(border2-rr)][(width-cc-2)])/65535.0f; //rgb[(rr)*TS+ccmax+cc][c] = (image[(border2-rr)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation } } @@ -321,7 +323,7 @@ void RawImageSource::CA_correct_RT() { for (rr=0; rrdata[(height-rr-2)][(border2-cc)])/65535.0f; //rgb[(rrmax+rr)*TS+cc][c] = (image[(height-rr-2)*width+(border2-cc)][c])/65535.0f;//for dcraw implementation } } @@ -368,6 +370,14 @@ void RawImageSource::CA_correct_RT() { fabs((rgb[indx-4][1]-rgb[indx-4][c])-(rgb[indx][1]-rgb[indx][c])) - \ fabs((rgb[indx-4][1]-rgb[indx-4][c])-(rgb[indx+4][1]-rgb[indx+4][c]))); + /*ghpfv = fabs(fabs(rgb[indx][1]-rgb[indx+v4][1])+fabs(rgb[indx][1]-rgb[indx-v4][1]) - \ + fabs(rgb[indx+v4][1]-rgb[indx-v4][1])); + ghpfh = fabs(fabs(rgb[indx][1]-rgb[indx+4][1])+fabs(rgb[indx][1]-rgb[indx-4][1]) - \ + fabs(rgb[indx+4][1]-rgb[indx-4][1])); + rbhpfv[indx] = fabs(ghpfv - fabs(fabs(rgb[indx][c]-rgb[indx+v4][c])+fabs(rgb[indx][c]-rgb[indx-v4][c]) - \ + fabs(rgb[indx+v4][c]-rgb[indx-v4][c]))); + rbhpfh[indx] = fabs(ghpfh - fabs(fabs(rgb[indx][c]-rgb[indx+4][c])+fabs(rgb[indx][c]-rgb[indx-4][c]) - \ + fabs(rgb[indx+4][c]-rgb[indx-4][c])));*/ glpfv = 0.25*(2*rgb[indx][1]+rgb[indx+v2][1]+rgb[indx-v2][1]); glpfh = 0.25*(2*rgb[indx][1]+rgb[indx+2][1]+rgb[indx-2][1]); @@ -475,7 +485,6 @@ void RawImageSource::CA_correct_RT() { if (blockdenom[j][c]) { blockvar[j][c] = blocksqave[j][c]/blockdenom[j][c]-SQR(blockave[j][c]/blockdenom[j][c]); } else { - fprintf (stderr,"blockdenom vanishes"); return; } } @@ -506,8 +515,8 @@ void RawImageSource::CA_correct_RT() { //end of filling border pixels of blockshift array //initialize fit arrays - for (i=0; i<256; i++) {polymat[0][0][i] = polymat[0][1][i] = polymat[2][0][i] = polymat[2][1][i] = 0;} - for (i=0; i<16; i++) {shiftmat[0][0][i] = shiftmat[0][1][i] = shiftmat[2][0][i] = shiftmat[2][1][i] = 0;} + for (i=0; i<1296; i++) {polymat[0][0][i] = polymat[0][1][i] = polymat[2][0][i] = polymat[2][1][i] = 0;} + for (i=0; i<36; i++) {shiftmat[0][0][i] = shiftmat[0][1][i] = shiftmat[2][0][i] = shiftmat[2][1][i] = 0;} for (vblock=1; vblockdata[row][col])/65535.0f; //rgb[indx1][c] = image[indx][c]/65535.0f;//for dcraw implementation if ((c&1)==0) rgb[indx1][1] = Gtmp[indx]; @@ -623,7 +628,7 @@ void RawImageSource::CA_correct_RT() { for (rr=0; rrdata[(height-rr-2)][left+cc])/65535.0f; //rgb[(rrmax+rr)*TS+cc][c] = (image[(height-rr-2)*width+left+cc][c])/65535.0f;//for dcraw implementation rgb[(rrmax+rr)*TS+cc][1] = Gtmp[(height-rr-2)*width+left+cc]; @@ -641,7 +646,7 @@ void RawImageSource::CA_correct_RT() { for (rr=rrmin; rrdata[(top+rr)][(width-cc-2)])/65535.0f; //rgb[rr*TS+ccmax+cc][c] = (image[(top+rr)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation rgb[rr*TS+ccmax+cc][1] = Gtmp[(top+rr)*width+(width-cc-2)]; @@ -653,7 +658,7 @@ void RawImageSource::CA_correct_RT() { for (rr=0; rrdata[border2-rr][border2-cc])/65535.0f; //rgb[(rr)*TS+cc][c] = (rgb[(border2-rr)*TS+(border2-cc)][c]);//for dcraw implementation rgb[(rr)*TS+cc][1] = Gtmp[(border2-rr)*width+border2-cc]; @@ -663,7 +668,7 @@ void RawImageSource::CA_correct_RT() { for (rr=0; rrdata[(height-rr-2)][(width-cc-2)])/65535.0f; //rgb[(rrmax+rr)*TS+ccmax+cc][c] = (image[(height-rr-2)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation rgb[(rrmax+rr)*TS+ccmax+cc][1] = Gtmp[(height-rr-2)*width+(width-cc-2)]; @@ -673,7 +678,7 @@ void RawImageSource::CA_correct_RT() { for (rr=0; rrdata[(border2-rr)][(width-cc-2)])/65535.0f; //rgb[(rr)*TS+ccmax+cc][c] = (image[(border2-rr)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation rgb[(rr)*TS+ccmax+cc][1] = Gtmp[(border2-rr)*width+(width-cc-2)]; @@ -683,7 +688,7 @@ void RawImageSource::CA_correct_RT() { for (rr=0; rrdata[(height-rr-2)][(border2-cc)])/65535.0f; //rgb[(rrmax+rr)*TS+cc][c] = (image[(height-rr-2)*width+(border2-cc)][c])/65535.0f;//for dcraw implementation rgb[(rrmax+rr)*TS+cc][1] = Gtmp[(height-rr-2)*width+(border2-cc)]; @@ -786,7 +791,7 @@ void RawImageSource::CA_correct_RT() { indx = row*width + col; c = FC(row,col); - rawData[row][col] = CLIP((int)(65535.0f*rgb[(rr)*TS+cc][c] + 0.5f)); + ri->data[row][col] = CLIP((int)(65535.0f*rgb[(rr)*TS+cc][c] + 0.5f)); //image[indx][c] = CLIP((int)(65535.0*rgb[(rr)*TS+cc][c] + 0.5));//for dcraw implementation } @@ -798,7 +803,7 @@ void RawImageSource::CA_correct_RT() { // clean up free(buffer); free(Gtmp); - free(buffer1); + //free(buffer1); diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 6442a3091..d5cae4e78 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -7,7 +7,7 @@ link_directories (${CMAKE_CURRENT_SOURCE_DIR}/../rtexif ${EXTRA_LIBDIR} ${GTHREA ${GOBJECT_LIBRARY_DIRS} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} ${IPTCDATA_LIBRARY_DIRS} ${LCMS_LIBRARY_DIRS}) -set (RTENGINESOURCEFILES colortemp.cc curves.cc dcraw.cc iccstore.cc dfmanager.cc +set (RTENGINESOURCEFILES colortemp.cc curves.cc dcraw.cc iccstore.cc image8.cc image16.cc imagedata.cc imageio.cc improcfun.cc init.cc dcrop.cc loadinitial.cc procparams.cc rawimagesource.cc shmap.cc simpleprocess.cc refreshmap.cc stdimagesource.cc myfile.cc iccjpeg.c hlmultipliers.cc improccoordinator.cc diff --git a/rtengine/amaze_interpolate_RT.cc b/rtengine/amaze_interpolate_RT.cc index ed59989ea..a223ddea5 100644 --- a/rtengine/amaze_interpolate_RT.cc +++ b/rtengine/amaze_interpolate_RT.cc @@ -35,7 +35,20 @@ void RawImageSource::amaze_demosaic_RT() { #define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y)) //#define CLIP(x) LIM(x,0,65535) + //allocate outpute arrays int width=W, height=H; + red = new unsigned short*[H]; + for (int i=0; idefgain; @@ -226,7 +239,7 @@ void RawImageSource::amaze_demosaic_RT() { } // Main algorithm: Tile loop - //#pragma omp parallel for shared(rawData,height,width,red,green,blue) private(top,left) schedule(dynamic) + //#pragma omp parallel for shared(ri->data,height,width,red,green,blue) private(top,left) schedule(dynamic) //code is openmp ready; just have to pull local tile variable declarations inside the tile loop #pragma omp for schedule(dynamic) nowait for (top=-16; top < height; top += TS-32) @@ -327,7 +340,7 @@ void RawImageSource::amaze_demosaic_RT() { c = FC(rr,cc); indx=row*width+col; indx1=rr*TS+cc; - rgb[indx1][c] = (rawData[row][col])/65535.0f; + rgb[indx1][c] = (ri->data[row][col])/65535.0f; //rgb[indx1][c] = image[indx][c]/65535.0f;//for dcraw implementation cfa[indx1] = rgb[indx1][c]; @@ -346,7 +359,7 @@ void RawImageSource::amaze_demosaic_RT() { for (rr=0; rr<16; rr++) for (cc=ccmin; ccdata[(height-rr-2)][left+cc])/65535.0f; //rgb[(rrmax+rr)*TS+cc][c] = (image[(height-rr-2)*width+left+cc][c])/65535.0f;//for dcraw implementation cfa[(rrmax+rr)*TS+cc] = rgb[(rrmax+rr)*TS+cc][c]; } @@ -363,7 +376,7 @@ void RawImageSource::amaze_demosaic_RT() { for (rr=rrmin; rrdata[(top+rr)][(width-cc-2)])/65535.0f; //rgb[rr*TS+ccmax+cc][c] = (image[(top+rr)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation cfa[rr*TS+ccmax+cc] = rgb[rr*TS+ccmax+cc][c]; } @@ -374,7 +387,7 @@ void RawImageSource::amaze_demosaic_RT() { for (rr=0; rr<16; rr++) for (cc=0; cc<16; cc++) { c=FC(rr,cc); - rgb[(rr)*TS+cc][c] = (rawData[32-rr][32-cc])/65535.0f; + rgb[(rr)*TS+cc][c] = (ri->data[32-rr][32-cc])/65535.0f; //rgb[(rr)*TS+cc][c] = (rgb[(32-rr)*TS+(32-cc)][c]);//for dcraw implementation cfa[(rr)*TS+cc] = rgb[(rr)*TS+cc][c]; } @@ -383,7 +396,7 @@ void RawImageSource::amaze_demosaic_RT() { for (rr=0; rr<16; rr++) for (cc=0; cc<16; cc++) { c=FC(rr,cc); - rgb[(rrmax+rr)*TS+ccmax+cc][c] = (rawData[(height-rr-2)][(width-cc-2)])/65535.0f; + rgb[(rrmax+rr)*TS+ccmax+cc][c] = (ri->data[(height-rr-2)][(width-cc-2)])/65535.0f; //rgb[(rrmax+rr)*TS+ccmax+cc][c] = (image[(height-rr-2)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation cfa[(rrmax+rr)*TS+ccmax+cc] = rgb[(rrmax+rr)*TS+ccmax+cc][c]; } @@ -392,7 +405,7 @@ void RawImageSource::amaze_demosaic_RT() { for (rr=0; rr<16; rr++) for (cc=0; cc<16; cc++) { c=FC(rr,cc); - rgb[(rr)*TS+ccmax+cc][c] = (rawData[(32-rr)][(width-cc-2)])/65535.0f; + rgb[(rr)*TS+ccmax+cc][c] = (ri->data[(32-rr)][(width-cc-2)])/65535.0f; //rgb[(rr)*TS+ccmax+cc][c] = (image[(32-rr)*width+(width-cc-2)][c])/65535.0f;//for dcraw implementation cfa[(rr)*TS+ccmax+cc] = rgb[(rr)*TS+ccmax+cc][c]; } @@ -401,7 +414,7 @@ void RawImageSource::amaze_demosaic_RT() { for (rr=0; rr<16; rr++) for (cc=0; cc<16; cc++) { c=FC(rr,cc); - rgb[(rrmax+rr)*TS+cc][c] = (rawData[(height-rr-2)][(32-cc)])/65535.0f; + rgb[(rrmax+rr)*TS+cc][c] = (ri->data[(height-rr-2)][(32-cc)])/65535.0f; //rgb[(rrmax+rr)*TS+cc][c] = (image[(height-rr-2)*width+(32-cc)][c])/65535.0f;//for dcraw implementation cfa[(rrmax+rr)*TS+cc] = rgb[(rrmax+rr)*TS+cc][c]; } diff --git a/rtengine/cfa_linedn_RT.cc b/rtengine/cfa_linedn_RT.cc index 2050c0f77..0c38f01a3 100644 --- a/rtengine/cfa_linedn_RT.cc +++ b/rtengine/cfa_linedn_RT.cc @@ -101,7 +101,7 @@ void RawImageSource::CLASS cfa_linedn(float noise) // load CFA data; data should be in linear gamma space, before white balance multipliers are applied for (rr=top; rr < top+numrows; rr++) for (cc=left, indx=(rr-top)*TS; cc < left+numcols; cc++, indx++) { - cfain[indx] = rawData[rr][cc]; + cfain[indx] = ri->data[rr][cc]; } //pad the block to a multiple of 16 on both sides @@ -189,7 +189,7 @@ void RawImageSource::CLASS cfa_linedn(float noise) for (rr=16; rr < numrows-16; rr++) { row = rr + top; for (col=16+left, indx=rr*TS+16; indx < rr*TS+numcols-16; indx++, col++) { - rawData[row][col] = CLIP((int)(cfadn[indx]+ 0.5)); + ri->data[row][col] = CLIP((int)(cfadn[indx]+ 0.5)); } } if(plistener) plistener->setProgress(fabs((float)top/height)); diff --git a/rtengine/common.h b/rtengine/common.h index 760a2144f..61b5d4720 100644 --- a/rtengine/common.h +++ b/rtengine/common.h @@ -36,49 +36,32 @@ #define CMAXVAL 65535 #include -#include - -namespace rtengine { - -struct badPix -{ - int x; - int y; - badPix( int xc, int yc ):x(xc),y(yc){} -}; struct RawImage { - Glib::ustring fname; // complete filename - int width; // with of the image as reported by dcraw - int height; // height of the image as reported by dcraw + int width; + int height; - unsigned filters; // sequence of Bayer filter colors: 2bit for each of 2x8 pixels grid indicate 0=Red,1=Green1,2=Blue,(3=green2) - int colors; // Number of colors of bayer filter (3 or 4) + unsigned filters; - int black_point; // Black offset taken from dslr info by dcraw - int cblack[4]; // Black for each color. - unsigned short white[8][8]; // square of white registered by camera - float cam_mul[4]; // Camera color multiplier taken from exif by dcraw - float pre_mul[4]; - int maximum; // White (maximum) point taken from dslr info - int rotate_deg; // 0,90,180,270 degree of rotation: info taken by dcraw from exif + double red_multiplier; + double green_multiplier; + double blue_multiplier; + + double camwb_red; + double camwb_green; + double camwb_blue; + + int blackpoint; + int rgb_max; + int rotate_deg; int fuji_width; double defgain; - double iso_speed; - double shutter; - double aperture; - double focal_len; - time_t timestamp; + char *make, *model; int exifbase, prefilters, ciff_base, ciff_len; - int thumbLength; - int thumbOffset; - int thumbType; - int thumbWidth; - int thumbHeight; unsigned short* allocation; unsigned short** data; // holds pixel values, data[i][j] corresponds to the ith row and jth column @@ -87,43 +70,7 @@ struct RawImage { float icoeff[3][3]; int profile_len; - char* profile_data; // Embedded ICC color profile - - RawImage( const Glib::ustring name):allocation(NULL),data(NULL),profile_data(NULL),fname(name) - { - } - ~RawImage() - { - if(allocation){ delete [] allocation; allocation=NULL;} - if(data){ delete [] data; data=NULL;} - if(profile_data){ delete [] profile_data; profile_data=NULL;} - } - - int loadRaw (bool loadData=true); - - void allocData() - { - if (filters) { - if (!allocation) { - allocation = new unsigned short[height * width]; - data = new unsigned short*[height]; - for (int i = 0; i < height; i++) - data[i] = allocation + i * width; - } - }else{ - if (!allocation) { - allocation = new unsigned short[3 * height * width]; - data = new unsigned short*[height]; - for (int i = 0; i < height; i++) - data[i] = allocation + 3 * i * width; - } - } - if(profile_len) - profile_data = new char[profile_len]; - } - + char* profile_data; }; -} - #endif diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index defb860cb..9a934c85f 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -3777,18 +3777,16 @@ void CLASS pre_interpolate() } } 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]; - /*RT*/ pre_filters = filters; - 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) @@ -8917,6 +8915,7 @@ cleanup: #include #include +#include #include #include #include @@ -8927,148 +8926,150 @@ extern Settings* settings; Glib::Mutex* dcrMutex=NULL; -int RawImage::loadRaw (bool loadData) { +int loadRaw (const char* fname, struct RawImage *ri) { - Glib::Mutex::Lock lock(*dcrMutex); // auto unlock + static const double xyzd50_srgb[3][3] = + { { 0.436083, 0.385083, 0.143055 }, + { 0.222507, 0.716888, 0.060608 }, + { 0.013930, 0.097097, 0.714022 } }; - ifname = fname.c_str(); +dcrMutex->lock (); + + ifname = fname;//strdup (fname); image = NULL; + exif_base = -1; ciff_base = -1; ciff_len = -1; verbose = settings->verbose; oprof = NULL; - - ifp = gfopen (fname.c_str()); - if (!ifp) + ri->data = NULL; + ri->allocation = NULL; + ri->profile_data = NULL; + ifp = gfopen (fname); + if (!ifp) { + dcrMutex->unlock (); 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 (); + use_camera_wb = 1; if (!is_raw) { fclose(ifp); + dcrMutex->unlock (); return 2; } - this->filters = ::filters; - this->height = ::height; - this->width = ::width; - this->colors = ::colors; - this->profile_len = ::profile_length; - 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]; + shrink = 0; - this->black_point = ::black; - this->maximum = ::maximum; - this->fuji_width = ::fuji_width; + if (settings->verbose) printf ("Loading %s %s image from %s...\n", make, model, fname); + iheight = height; + iwidth = width; - for(int i=0; i<8;i++) - for(int j=0;j<8;j++) - this->white[i][j] = ::white[i][j]; + image = (UshORt (*)[4])calloc (height*width*sizeof *image + meta_length, 1); + meta_data = (char *) (image + height*width); + + if (setjmp (failure)) { + if (image) + free (image); + if (ri->data) + free(ri->data); + fclose (ifp); + dcrMutex->unlock (); + return 100; + } + + fseek (ifp, data_offset, SEEK_SET); + (*load_raw)(); + + ri->profile_len = 0; + ri->profile_data = NULL; + if (profile_length) { + ri->profile_len = profile_length; + ri->profile_data = (char *) malloc (profile_length); + fseek (ifp, profile_offset, SEEK_SET); + fread (ri->profile_data, 1, profile_length, ifp); + } + + fclose(ifp); + if (zero_is_bad) remove_zeroes(); + + ri->red_multiplier = pre_mul[0]; + ri->green_multiplier = pre_mul[1]; + ri->blue_multiplier = pre_mul[2]; + + scale_colors(); + pre_interpolate (); + + ri->width = width; + ri->height = height; + ri->filters = filters; + + if (filters) { + ri->allocation = (short unsigned int*)calloc(height*width, sizeof(unsigned short)); + ri->data = (unsigned short**)calloc(height, sizeof(unsigned short*)); + for (int i=0; idata[i] = ri->allocation + i*width; + for (int row = 0; row < height; row++) + for (int col = 0; col < width; col++) + if (ISGREEN(ri,row,col)) + ri->data[row][col] = image[row*width+col][1]; + else if (ISRED(ri,row,col)) + ri->data[row][col] = image[row*width+col][0]; + else + ri->data[row][col] = image[row*width+col][2]; + } + else { + ri->allocation = (short unsigned int*)calloc(3*height*width, sizeof(unsigned short)); + ri->data = (unsigned short**)calloc(height, sizeof(unsigned short*)); + for (int i=0; idata[i] = ri->allocation + 3*i*width; + for (int row = 0; row < height; row++) + for (int col = 0; col < width; col++) { + ri->data[row][3*col+0] = image[row*width+col][0]; + ri->data[row][3*col+1] = image[row*width+col][1]; + ri->data[row][3*col+2] = image[row*width+col][2]; + } + } if (flip==5) - this->rotate_deg = 270; + ri->rotate_deg = 270; else if (flip==3) - this->rotate_deg = 180; + ri->rotate_deg = 180; else if (flip==6) - this->rotate_deg = 90; + ri->rotate_deg = 90; else - this->rotate_deg = 0; + ri->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; - } + ri->make = strdup (make); + ri->model = strdup (model); - 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; + ri->exifbase = exif_base; + ri->prefilters = pre_filters; + ri->ciff_base = ciff_base; + ri->ciff_len = ciff_len; - // 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; + ri->camwb_red = ri->red_multiplier / pre_mul[0]; + ri->camwb_green = ri->green_multiplier / pre_mul[1]; + ri->camwb_blue = ri->blue_multiplier / pre_mul[2]; - if (setjmp (failure)) { - if (image) - free (image); - fclose (ifp); - return 100; - } + ri->defgain = 1.0 / MIN(MIN(pre_mul[0],pre_mul[1]),pre_mul[2]); - // Load raw pixels data - fseek (ifp, data_offset, SEEK_SET); - (*load_raw)(); + ri->fuji_width = fuji_width; - // Load embedded profile - if (profile_length) { - fseek (ifp, profile_offset, SEEK_SET); - fread ( this->profile_data, 1, this->profile_len, ifp); - } - fclose(ifp); + for (int a=0; a < 3; a++) + for (int b=0; b < 3; b++) + ri->coeff[a][b] = rgb_cam[a][b]; - // 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 - } + free (image); +dcrMutex->unlock (); return 0; } - - int getRawFileBasicInfo (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, int& rotation, int& thumbWidth, int& thumbHeight, int& thumbOffset, int& thumbType) { int status=0; diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 3a1c2fdf5..4a54fdcee 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -108,7 +108,7 @@ void Crop::update (int todo, bool internal) { if (!needsinitupdate) setCropSizes (rqcropx, rqcropy, rqcropw, rqcroph, skip, true); PreviewProps pp (trafx, trafy, trafw*skip, trafh*skip, skip); - parent->imgsrc->getImage (parent->currWB, tr, origCrop, pp, params.hlrecovery, params.icm, params.raw ); + parent->imgsrc->getImage (parent->currWB, tr, origCrop, pp, params.hlrecovery, params.icm); if (fabs(params.resize.scale-1.0)<1e-7) { if (resizeCrop) { diff --git a/rtengine/dfmanager.cc b/rtengine/dfmanager.cc deleted file mode 100644 index 86f08704b..000000000 --- a/rtengine/dfmanager.cc +++ /dev/null @@ -1,353 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#include -#include -#include -#include -#include -#include -#include - -namespace rtengine{ - -extern Settings* settings; - -// *********************** class dfInfo ************************************** - -inline dfInfo& dfInfo::operator =(const dfInfo &o){ - pathname = o.pathname; - maker = o.maker; - model = o.model; - iso = o.iso; - shutter = o.shutter; - timestamp = o.timestamp; - if( ri ){ - delete ri; - ri = NULL; - } - return *this; -} - -bool dfInfo::operator <(const dfInfo &e2) const -{ - if( this->maker.compare( e2.maker) >=0 ) - return false; - if( this->model.compare( e2.model) >=0 ) - return false; - if( this->iso >= e2.iso ) - return false; - if( this->shutter >= e2.shutter ) - return false; - if( this->timestamp >= e2.timestamp ) - return false; - return true; -} - -std::string dfInfo::key(const std::string &mak, const std::string &mod, int iso, double shut ) -{ - std::ostringstream s; - s << mak << " " << mod << " "; - s.width(5); - s << iso << "ISO "; - s.precision( 2 ); - s.width(4); - s << shut << "s"; - return s.str(); -} - -double dfInfo::distance(const std::string &mak, const std::string &mod, int iso, double shutter) const -{ - if( this->maker.compare( mak) != 0 ) - return INFINITY; - if( this->model.compare( mod) != 0 ) - return INFINITY; - double dISO= (log(this->iso/100.) - log(iso/100.))/log(2); - double dShutter = (log(this->shutter) - log(shutter))/log(2); - return sqrt( dISO*dISO + dShutter*dShutter); -} - -RawImage* dfInfo::getRawImage() -{ - if(ri) - return ri; - updateRawImage(); - updateBadPixelList( ri ); - - return ri; -} - -std::list& dfInfo::getBadPixels() -{ - if( !ri ){ - updateRawImage(); - updateBadPixelList( ri ); - } - return badPixels; -} -/* updateRawImage() load into ri the actual pixel data from pathname if there is a single shot - * otherwise load each file from the pathNames list and extract a template from the media; - * the first file is used also for reading all information other than pixels - */ -void dfInfo::updateRawImage() -{ - typedef unsigned int acc_t; - if( pathNames.size() >0 ){ - std::list::iterator iName = pathNames.begin(); - ri = new RawImage(*iName); // First file used also for extra pixels informations (width,height, shutter, filters etc.. ) - if( ri->loadRaw(true)){ - delete ri; - ri=NULL; - }else{ - - acc_t **acc = new acc_t*[ri->height]; - for( int row=0; rowheight;row++) - acc[row] = new acc_t[ri->width*(ri->filters?1:3)]; - - // copy first image into accumulators - for (int row = 0; row < ri->height; row++) - for (int col = 0; col < ri->width * (ri->filters ? 1 : 3); col++) - acc[row][col] = ri->data[row][col]; - int nFiles = 1; // First file data already loaded - - for( iName++; iName != pathNames.end(); iName++){ - RawImage* temp = new RawImage(*iName); - if( !temp->loadRaw(true)){ - nFiles++; - if( ri->filters ){ - for( int row=0; rowheight;row++){ - for( int col=0; col < ri->width;col++) - acc[row][col] += temp->data[row][col]; - } - }else{ - for( int row=0; rowheight;row++){ - for( int col=0; col < ri->width;col++){ - acc[row][3*col+0] += temp->data[row][3*col+0]; - acc[row][3*col+1] += temp->data[row][3*col+1]; - acc[row][3*col+2] += temp->data[row][3*col+2]; - } - } - } - } - delete temp; - } - for (int row = 0; row < ri->height; row++){ - for (int col = 0; col < ri->width * (ri->filters ? 1 : 3); col++) - ri->data[row][col] = acc[row][col] / nFiles; - delete [] acc[row]; - } - delete [] acc; - } - }else{ - ri = new RawImage(pathname); - if( ri->loadRaw(true)){ - delete ri; - ri=NULL; - } - } -} - -void dfInfo::updateBadPixelList( RawImage *df ) -{ - const int threshold=10; - if( df->filters ){ - for( int row=2; rowheight-2; row++) - for( int col=2; col < df->width-2; col++){ - int m = (df->data[row-2][col-2] + df->data[row-2][col] + df->data[row-2][col+2]+ - df->data[row][col-2] + df->data[row][col+2]+ - df->data[row+2][col-2] + df->data[row+2][col] + df->data[row+2][col+2])/8; - if( df->data[row][col]/threshold > m ) - badPixels.push_back( badPix(col,row) ); - } - }else{ - for( int row=1; rowheight-1; row++) - for( int col=1; col < df->width-1; col++){ - int m[3]; - for( int c=0; c<3;c++){ - m[c] = (df->data[row-1][3*(col-1)+c] + df->data[row-1][3*col+c] + df->data[row-1][3*(col+1)+c]+ - df->data[row] [3*(col-1)+c] + df->data[row] [3*col+c]+ - df->data[row+1][3*(col-1)+c] + df->data[row+1][3*col+c] + df->data[row+1][3*(col+1)+c])/8; - } - if( df->data[row][3*col]/threshold > m[0] || df->data[row][3*col+1]/threshold > m[1] || df->data[row][3*col+2]/threshold > m[2]) - badPixels.push_back( badPix(col,row) ); - } - } - if( settings->verbose ){ - for (std::list::iterator iter = badPixels.begin(); iter !=badPixels.end(); iter ++) - printf( "(%d,%d) ",iter->x, iter->y); - printf( "Tot: %d\n", badPixels.size() ); - } -} - - -// ************************* class DFManager ********************************* - -void DFManager::init( Glib::ustring pathname ) -{ - std::vector names; - Glib::RefPtr dir = Gio::File::create_for_path (pathname); - if( dir && !dir->query_exists()) - return; - safe_build_file_list (dir, names, pathname); - - dfList.clear(); - for (int i=0; isecond; - if( i.pathNames.size()>0 && !i.pathname.empty() ){ - i.pathNames.push_back( i.pathname ); - i.pathname.clear(); - } - if( !i.pathname.empty() ) - printf( "%s: %s\n",i.key().c_str(),i.pathname.c_str()); - else{ - printf( "%s: MEAN of \n ",i.key().c_str()); - for( std::list::iterator iter = i.pathNames.begin(); iter != i.pathNames.end();iter++ ) - printf( "%s, ", iter->c_str() ); - printf("\n"); - } - } - currentPath = pathname; - return; -} - -bool DFManager::addFileInfo(const Glib::ustring &filename ) -{ - Glib::RefPtr file = Gio::File::create_for_path(filename); - if (!file ) - return false; - if( !file->query_exists()) - return false; - Glib::RefPtr info = safe_query_file_info(file); - if (info && info->get_file_type() != Gio::FILE_TYPE_DIRECTORY && (!info->is_hidden() || !options.fbShowHidden)) { - int lastdot = info->get_name().find_last_of ('.'); - if (options.is_extention_enabled(lastdot!=Glib::ustring::npos ? info->get_name().substr (lastdot+1) : "")){ - RawImage ri(filename); - int res = ri.loadRaw(false); // Read informations about shot - if( !res ){ - /* Files are added in the map, divided by same maker/model,ISO and shutter*/ - std::string key( dfInfo::key(ri.make, ri.model,(int)ri.iso_speed,ri.shutter) ); - dfList_t::iterator iter = dfList.find( key ); - if( iter == dfList.end() ){ - dfInfo n(filename, ri.make, ri.model,(int)ri.iso_speed,ri.shutter,ri.timestamp); - dfList.insert(std::pair< std::string,dfInfo>( key,n ) ); - }else{ - while( iter != dfList.end() && iter->second.key() == key && ABS(iter->second.timestamp - ri.timestamp) >60*60*6 ) // 6 hour difference - iter++; - - if( iter != dfList.end() ) - iter->second.pathNames.push_back( filename ); - else{ - dfInfo n(filename, ri.make, ri.model,(int)ri.iso_speed,ri.shutter,ri.timestamp); - dfList.insert(std::pair< std::string,dfInfo>( key,n ) ); - } - } - return true; - } - } - } - return false; -} - -void DFManager::getStat( int &totFiles, int &totTemplates) -{ - totFiles=0; - totTemplates=0; - for( dfList_t::iterator iter = dfList.begin(); iter != dfList.end();iter++ ){ - dfInfo &i = iter->second; - if( i.pathname.empty() ){ - totTemplates++; - totFiles += i.pathNames.size(); - }else - totFiles++; - } -} - -/* The search for the best match is twofold: - * if perfect matches for iso and shutter are found, then the list is scanned for lesser distance in time - * otherwise if no match is found, the whole list is searched for lesser distance in iso and shutter - */ -dfInfo& DFManager::find( const std::string &mak, const std::string &mod, int isospeed, double shut, time_t t ) -{ - if( dfList.size() == 0 ) - throw std::exception(); - std::string key( dfInfo::key(mak,mod,isospeed,shut) ); - dfList_t::iterator iter = dfList.find( key ); - - if( iter != dfList.end() ){ - dfList_t::iterator bestMatch = iter; - time_t bestDeltaTime = ABS(iter->second.timestamp - t); - for(iter++; iter != dfList.end() && !key.compare( iter->second.key() ); iter++ ){ - time_t d = ABS(iter->second.timestamp - t ); - if( d< bestDeltaTime ){ - bestMatch = iter; - bestDeltaTime = d; - } - } - return bestMatch->second; - }else{ - iter = dfList.begin(); - dfList_t::iterator bestMatch = iter; - double bestD = iter->second.distance( mak, mod, isospeed, shut ); - for( iter++; iter != dfList.end();iter++ ){ - double d = iter->second.distance( mak, mod, isospeed, shut ); - if( d < bestD ){ - bestD = d; - bestMatch = iter; - } - } - return bestMatch->second; - } -} - -RawImage* DFManager::searchDarkFrame( const std::string &mak, const std::string &mod, int iso, double shut, time_t t ) -{ - try{ - dfInfo &df = find( mak, mod, iso, shut, t ); - return df.getRawImage(); - }catch( std::exception e){ - return NULL; - } -} - -RawImage* DFManager::searchDarkFrame( Glib::ustring filename ) -{ - for ( dfList_t::iterator iter = dfList.begin(); iter != dfList.end();iter++ ){ - if( iter->second.pathname.compare( filename )==0 ) - return iter->second.getRawImage(); - } -} - -std::list DFManager::searchBadPixels ( const std::string &mak, const std::string &mod, int iso, double shut, time_t t ) -{ - try{ - dfInfo &df = find( mak, mod, iso, shut, t ); - return df.getBadPixels(); - }catch( std::exception e){ - return std::list(); - } -} - -// Global variable -DFManager dfm; - - -} diff --git a/rtengine/dfmanager.h b/rtengine/dfmanager.h deleted file mode 100644 index f15070b06..000000000 --- a/rtengine/dfmanager.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#include -#include -#include -#include -#include - -namespace rtengine{ - -class dfInfo -{ -public: - - Glib::ustring pathname; // filename of dark frame - std::list pathNames; // other similar dark frames, used to mediate - std::string maker; ///< manufacturer - std::string model; ///< model - int iso; ///< ISO (gain) - double shutter; ///< shutter or exposure time in sec - time_t timestamp; ///< seconds since 1 Jan 1970 - - - dfInfo(const Glib::ustring &name, const std::string &mak, const std::string &mod,int iso,double shut,time_t t) - :pathname(name),maker(mak),model(mod),iso(iso),shutter(shut),timestamp(t),ri(NULL){} - - dfInfo( const dfInfo &o) - :pathname(o.pathname),maker(o.maker),model(o.model),iso(o.iso),shutter(o.shutter),timestamp(o.timestamp),ri(NULL){} - ~dfInfo() { if( ri ) delete ri; } - - - dfInfo &operator =(const dfInfo &o); - bool operator <(const dfInfo &e2) const; - - // Calculate virtual distance between two shots; different model return infinite - double distance(const std::string &mak, const std::string &mod, int iso, double shutter) const; - - static std::string key(const std::string &mak, const std::string &mod, int iso, double shut ); - std::string key(){ return key( maker,model,iso,shutter); } - - RawImage *getRawImage(); - std::list &getBadPixels(); - -protected: - RawImage *ri; ///< Dark Frame raw data - std::list badPixels; ///< Unreliable pixels - - void updateBadPixelList( RawImage *df ); - void updateRawImage(); -}; - -class DFManager -{ -public: - void init( Glib::ustring pathname ); - Glib::ustring getPathname(){ return currentPath; }; - void getStat( int &totFiles, int &totTemplate); - RawImage *searchDarkFrame( const std::string &mak, const std::string &mod, int iso, double shut, time_t t ); - RawImage *searchDarkFrame( Glib::ustring filename ); - std::list searchBadPixels ( const std::string &mak, const std::string &mod, int iso, double shut, time_t t ); - -protected: - typedef std::multimap dfList_t; - dfList_t dfList; - bool initialized; - Glib::ustring currentPath; - bool addFileInfo(const Glib::ustring &filename ); - dfInfo &find( const std::string &mak, const std::string &mod, int isospeed, double shut, time_t t ); -}; - -extern DFManager dfm; - -} diff --git a/rtengine/green_equil_RT.cc b/rtengine/green_equil_RT.cc index e7f5a00e2..b64999db6 100644 --- a/rtengine/green_equil_RT.cc +++ b/rtengine/green_equil_RT.cc @@ -110,7 +110,7 @@ void CLASS RawImageSource::green_equilibrate(float thresh) for (row=rr+top, cc=0; cc < numcols; cc++) { col = cc+left; //cfa[rr*TS+cc] = image[row*width+col][FC(row,col)];//for dcraw implementation - cfa[rr*TS+cc] = rawData[row][col]; + cfa[rr*TS+cc] = ri->data[row][col]; } @@ -190,7 +190,7 @@ void CLASS RawImageSource::green_equilibrate(float thresh) col = cc + left; //c = FC(row,col); //image[row*width + col][c] = CLIP((int)(cfa[indx] + 0.5)); //for dcraw implementation - rawData[row][col] = CLIP((int)(cfa[indx] + 0.5)); + ri->data[row][col] = CLIP((int)(cfa[indx] + 0.5)); } // clean up diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 1d4850e01..2e260c853 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -66,9 +66,7 @@ class ImageSource : public InitialImage { virtual ~ImageSource () {} virtual int load (Glib::ustring fname) =0; - virtual void preprocess (const RAWParams &raw){}; - virtual void demosaic (const RAWParams &raw){}; - virtual void getImage (ColorTemp ctemp, int tran, Image16* image, PreviewProps pp, HRecParams hlp, ColorManagementParams cmp, RAWParams raw) {} + virtual void getImage (ColorTemp ctemp, int tran, Image16* image, PreviewProps pp, HRecParams hlp, ColorManagementParams cmp) {} virtual ColorTemp getWB () =0; virtual ColorTemp getAutoWB () =0; virtual ColorTemp getSpotWB (std::vector red, std::vector green, std::vector& blue, int tran) =0; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 76aeb432f..fc66c93e9 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -79,10 +79,6 @@ void ImProcCoordinator::updatePreviewImage (int todo) { ipf.setScale (scale); progress ("Applying white balance, color correction & sRBG conversion...",100*readyphase/numofphases); - if ( todo & M_PREPROC) - imgsrc->preprocess( params.raw ); - if( todo & M_RAW) - imgsrc->demosaic( params.raw ); if (todo & M_INIT) { minit.lock (); if (settings->verbose) printf ("Applying white balance, color correction & sRBG conversion...\n"); @@ -109,7 +105,7 @@ void ImProcCoordinator::updatePreviewImage (int todo) { imgsrc->getFullSize (fw, fh, tr); PreviewProps pp (0, 0, fw, fh, scale); setScale (scale, true); - imgsrc->getImage (currWB, tr, orig_prev, pp, params.hlrecovery, params.icm, params.raw); + imgsrc->getImage (currWB, tr, orig_prev, pp, params.hlrecovery, params.icm); ipf.firstAnalysis (orig_prev, ¶ms, vhist16, imgsrc->getGamma()); minit.unlock (); } @@ -483,9 +479,7 @@ void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname) { ppar.hlrecovery.enabled = false; ppar.icm.input = "(none)"; Image16* im = new Image16 (fW, fH); - imgsrc->preprocess( ppar.raw ); - imgsrc->demosaic( ppar.raw ); - imgsrc->getImage (imgsrc->getWB(), 0, im, pp, ppar.hlrecovery, ppar.icm, ppar.raw); + imgsrc->getImage (imgsrc->getWB(), 0, im, pp, ppar.hlrecovery, ppar.icm); im->saveJPEG (fname, 85); mProcessing.unlock (); } diff --git a/rtengine/init.cc b/rtengine/init.cc index 86044077c..167ca3e3a 100644 --- a/rtengine/init.cc +++ b/rtengine/init.cc @@ -21,7 +21,6 @@ #include #include #include -#include namespace rtengine { @@ -40,7 +39,6 @@ int init (const Settings* s) { dcrMutex = new Glib::Mutex; delete lcmsMutex; lcmsMutex = new Glib::Mutex; - dfm.init( s->darkFramesPath ); return 0; } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 4fbf9b746..185835498 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -19,6 +19,10 @@ #ifndef __PROCEVENT__ #define __PROCEVENT__ +#include + +#define NUMOFEVENTS 86 + namespace rtengine { enum ProcEvent { @@ -107,10 +111,7 @@ enum ProcEvent { EvSHHighQuality=82, EvPerspCorr=83, EvEqualizer=84, - EvEqlEnabled=85, - EvDemosaic=86, - EvPreProcess=87, - NUMOFEVENTS=88 + EvEqlEnabled=85 }; } #endif diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 1fee2c314..d8c1715a2 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -27,8 +27,6 @@ namespace rtengine { namespace procparams { -const char *RAWParams::methodstring[RAWParams::numMethods]={"eahd", "hphd", "vng4", "dcb", "amaze", "ahd" }; - ProcParams::ProcParams () { setDefaults (); @@ -165,16 +163,7 @@ void ProcParams::setDefaults () { { equalizer.c[i] = 0; } - raw.df_autoselect = false; - raw.ca_autocorrect = false; - raw.hotdeadpix_filt = false; - raw.linenoise = 0; - raw.greenthresh = 0; - raw.ccSteps = 1; - raw.dmethod = RAWParams::methodstring[RAWParams::hphd];; - raw.dcb_iterations=2; - raw.dcb_enhance=false; - + exif.clear (); iptc.clear (); @@ -330,18 +319,6 @@ int ProcParams::save (Glib::ustring fname) const { keyFile.set_integer("Equalizer", ss.str(), equalizer.c[i]); } - // save RAW parameters - keyFile.set_string ("RAW", "DarkFrame", raw.dark_frame ); - keyFile.set_boolean ("RAW", "DarkFrameAuto", raw.df_autoselect ); - keyFile.set_boolean ("RAW", "CA", raw.ca_autocorrect ); - keyFile.set_boolean ("RAW", "HotDeadPixels", raw.hotdeadpix_filt ); - keyFile.set_integer ("RAW", "LineDenoise", raw.linenoise); - keyFile.set_integer ("RAW", "GreenEqThreshold", raw.greenthresh); - keyFile.set_integer ("RAW", "CcSteps", raw.ccSteps); - keyFile.set_string ("RAW", "Method", raw.dmethod ); - keyFile.set_integer ("RAW", "DCBIterations", raw.dcb_iterations ); - keyFile.set_boolean ("RAW", "DCBEnhance", raw.dcb_enhance ); - // save exif change list for (int i=0; i keys = keyFile.get_keys ("Exif"); @@ -730,16 +693,6 @@ bool ProcParams::operator== (const ProcParams& other) { && resize.dataspec == other.resize.dataspec && resize.width == other.resize.width && resize.height == other.resize.height - && raw.dark_frame == other.raw.dark_frame - && raw.df_autoselect == other.raw.df_autoselect - && raw.dcb_enhance == other.raw.dcb_enhance - && raw.dcb_iterations == other.raw.dcb_iterations - && raw.ccSteps == other.raw.ccSteps - && raw.ca_autocorrect == other.raw.ca_autocorrect - && raw.hotdeadpix_filt == other.raw.hotdeadpix_filt - && raw.dmethod == other.raw.dmethod - && raw.greenthresh == other.raw.greenthresh - && raw.linenoise == other.raw.linenoise && icm.input == other.icm.input && icm.gammaOnInput == other.icm.gammaOnInput && icm.working == other.icm.working diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 219f9fe72..9d6909f3d 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -312,28 +312,6 @@ class EqualizerParams { int c[8]; }; -/** - * Parameters for RAW demosaicing - */ -class RAWParams { - - public: - enum eMethod{eahd,hphd,vng4,dcb,amaze,ahd, - numMethods }; // This MUST be the last enum - static const char *methodstring[numMethods]; - - Glib::ustring dark_frame; - bool df_autoselect; - bool ca_autocorrect; - bool hotdeadpix_filt; - int linenoise; - int greenthresh; - int ccSteps; - Glib::ustring dmethod; - int dcb_iterations; - bool dcb_enhance; -}; - /** * This class holds all the processing parameters applied on the images */ @@ -362,7 +340,6 @@ class ProcParams { ResizeParams resize; ///< Resize parameters ColorManagementParams icm; ///< profiles/color spaces used during the image processing EqualizerParams equalizer; ///< wavelet equalizer parameters - RAWParams raw; ///< RAW parameters before demosaicing std::vector exif; ///< List of modifications appplied on the exif tags of the input image std::vector iptc; ///< The IPTC tags and values to be saved to the output image int version; ///< Version of the file from which the parameters have been read diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index c1785464a..a9aa2a881 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -26,7 +26,6 @@ #include #include #include -#include #ifdef _OPENMP #include @@ -34,6 +33,8 @@ namespace rtengine { +int loadRaw (const char* fname, struct RawImage* ri); + extern const Settings* settings; #undef ABS @@ -46,23 +47,14 @@ extern const Settings* settings; #define MIN(a,b) ((a)>(b)?(b):(a)) #define DIST(a,b) (ABS(a-b)) -RawImageSource::RawImageSource () -:ImageSource() -,plistener(NULL) -,green(NULL) -,red(NULL) -,blue(NULL) -,cache(NULL) -,border(4) -,rawData(NULL) -,ri(NULL) -,df(NULL) -{ +RawImageSource::RawImageSource () : ImageSource(), plistener(NULL), green(NULL), red(NULL), blue(NULL), cache(NULL), border(4) { + hrmap[0] = NULL; hrmap[1] = NULL; hrmap[2] = NULL; needhr = NULL; hpmap = NULL; + oldmethod = "None"; camProfile = NULL; embProfile = NULL; } @@ -71,20 +63,20 @@ RawImageSource::~RawImageSource () { delete idata; if (ri) { + if (ri->allocation) + free (ri->allocation); + if (ri->data) + free (ri->data); + if (ri->profile_data) + free (ri->profile_data); delete ri; } - if(df){ - delete df; - } - if (green) freeArray(green, H); if (red) freeArray(red, H); if (blue) freeArray(blue, H); - if(rawData) - freeArray(rawData, H); delete [] cache; if (hrmap[0]!=NULL) { @@ -181,8 +173,7 @@ void RawImageSource::transformRect (PreviewProps pp, int tran, int &ssx1, int &s } } -void RawImageSource::getImage (ColorTemp ctemp, int tran, Image16* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp, RAWParams raw ) -{ +void RawImageSource::getImage (ColorTemp ctemp, int tran, Image16* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp) { isrcMutex.lock (); @@ -194,9 +185,9 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Image16* image, Previe rm = icoeff[0][0]*r + icoeff[0][1]*g + icoeff[0][2]*b; gm = icoeff[1][0]*r + icoeff[1][1]*g + icoeff[1][2]*b; bm = icoeff[2][0]*r + icoeff[2][1]*g + icoeff[2][2]*b; - rm = camwb_red / rm; - gm = camwb_green / gm; - bm = camwb_blue / bm; + rm = ri->camwb_red / rm; + gm = ri->camwb_green / gm; + bm = ri->camwb_blue / bm; double mul_lum = 0.299*rm + 0.587*gm + 0.114*bm; rm /= mul_lum; gm /= mul_lum; @@ -243,17 +234,27 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Image16* image, Previe unsigned short* blue = new unsigned short[imwidth]; for (int i=sy1,ix=0; ixfilters) { + if (ri->filters && this->red && this->blue) { for (int j=0,jx=sx1; jred[i][jx]); - grn[j] = CLIP(gm*this->green[i][jx]); + grn[j] = CLIP(gm*green[i][jx]); blue[j] = CLIP(bm*this->blue[i][jx]); - } + } + } else if(ri->filters) { + if (i==0) + interpolate_row_rb_mul_pp (red, blue, NULL, green[i], green[i+1], i, rm, gm, bm, sx1, imwidth, pp.skip); + else if (i==H-1) + interpolate_row_rb_mul_pp (red, blue, green[i-1], green[i], NULL, i, rm, gm, bm, sx1, imwidth, pp.skip); + else + interpolate_row_rb_mul_pp (red, blue, green[i-1], green[i], green[i+1], i, rm, gm, bm, sx1, imwidth, pp.skip); + + for (int j=0,jx=sx1; jdata[i][jx*3+0]); + grn[j] = CLIP(gm*ri->data[i][jx*3+1]); + blue[j] = CLIP(bm*ri->data[i][jx*3+2]); } } @@ -317,52 +318,14 @@ void RawImageSource::getImage (ColorTemp ctemp, int tran, Image16* image, Previe // Color correction if (ri->filters && pp.skip==1) - correction_YIQ_LQ (image, raw.ccSteps); + correction_YIQ_LQ (image, settings->colorCorrectionSteps); // Applying postmul colorSpaceConversion (image, cmp, embProfile, camProfile, cam, defGain); isrcMutex.unlock (); } - -void RawImageSource::cfaCleanFromList( const std::list &bpList ) -{ - int rr, cc; - unsigned short gin,g[8]; - float eps=1e-10;//tolerance to avoid dividing by zero - float p[8]; - - for (std::list::const_iterator iter=bpList.begin(); iter != bpList.end(); iter++ ){ - rr = iter->y; - if( rr<4 || rr>=H-4 ) - continue; - cc = iter->x; - if( cc<4 || cc>=W-4 ) - continue; - - //pixel neighbor average - gin=rawData[rr][cc]; - g[0]=rawData[rr-2][cc-2]; - g[1]=rawData[rr-2][cc]; - g[2]=rawData[rr-2][cc+2]; - g[3]=rawData[rr][cc-2]; - g[4]=rawData[rr][cc+2]; - g[5]=rawData[rr+2][cc-2]; - g[6]=rawData[rr+2][cc]; - g[7]=rawData[rr+2][cc+2]; - - p[0]=1/(eps+fabs(g[0]-gin)+fabs(g[0]-rawData[rr-4][cc-4])+fabs(rawData[rr-1][cc-1]-rawData[rr-3][cc-3])); - p[1]=1/(eps+fabs(g[1]-gin)+fabs(g[1]-rawData[rr-4][cc])+fabs(rawData[rr-1][cc]-rawData[rr-3][cc])); - p[2]=1/(eps+fabs(g[2]-gin)+fabs(g[2]-rawData[rr-4][cc+4])+fabs(rawData[rr-1][cc+1]-rawData[rr-3][cc+3])); - p[3]=1/(eps+fabs(g[3]-gin)+fabs(g[3]-rawData[rr][cc-4])+fabs(rawData[rr][cc-1]-rawData[rr][cc-3])); - p[4]=1/(eps+fabs(g[4]-gin)+fabs(g[4]-rawData[rr][cc+4])+fabs(rawData[rr][cc+1]-rawData[rr][cc+3])); - p[5]=1/(eps+fabs(g[5]-gin)+fabs(g[5]-rawData[rr+4][cc-4])+fabs(rawData[rr+1][cc-1]-rawData[rr+3][cc-3])); - p[6]=1/(eps+fabs(g[6]-gin)+fabs(g[6]-rawData[rr+4][cc])+fabs(rawData[rr+1][cc]-rawData[rr+3][cc])); - p[7]=1/(eps+fabs(g[7]-gin)+fabs(g[7]-rawData[rr+4][cc+4])+fabs(rawData[rr+1][cc+1]-rawData[rr+3][cc+3])); - - rawData[rr][cc] = (int)((g[0]*p[0]+g[1]*p[1]+g[2]*p[2]+g[3]*p[3]+g[4]*p[4]+ g[5]*p[5]+g[6]*p[6]+g[7]*p[7])/(p[0]+p[1]+p[2]+p[3]+p[4]+p[5]+p[6]+p[7])); - } -} + void RawImageSource::cfa_clean(float thresh) //Emil's hot/dead pixel removal -- only filters egregiously impulsive pixels { @@ -381,31 +344,31 @@ void RawImageSource::cfa_clean(float thresh) //Emil's hot/dead pixel removal -- for (cc=4; cc < W-4; cc++) { //pixel neighbor average - gin=rawData[rr][cc]; - g[0]=rawData[rr-2][cc-2]; - g[1]=rawData[rr-2][cc]; - g[2]=rawData[rr-2][cc+2]; - g[3]=rawData[rr][cc-2]; - g[4]=rawData[rr][cc+2]; - g[5]=rawData[rr+2][cc-2]; - g[6]=rawData[rr+2][cc]; - g[7]=rawData[rr+2][cc+2]; + gin=ri->data[rr][cc]; + g[0]=ri->data[rr-2][cc-2]; + g[1]=ri->data[rr-2][cc]; + g[2]=ri->data[rr-2][cc+2]; + g[3]=ri->data[rr][cc-2]; + g[4]=ri->data[rr][cc+2]; + g[5]=ri->data[rr+2][cc-2]; + g[6]=ri->data[rr+2][cc]; + g[7]=ri->data[rr+2][cc+2]; pixave=(float)(g[0]+g[1]+g[2]+g[3]+g[4]+g[5]+g[6]+g[7])/8; pixratio=MIN(gin,pixave)/(eps+MAX(gin,pixave)); if (pixratio > thresh) continue; - p[0]=1/(eps+fabs(g[0]-gin)+fabs(g[0]-rawData[rr-4][cc-4])+fabs(rawData[rr-1][cc-1]-rawData[rr-3][cc-3])); - p[1]=1/(eps+fabs(g[1]-gin)+fabs(g[1]-rawData[rr-4][cc])+fabs(rawData[rr-1][cc]-rawData[rr-3][cc])); - p[2]=1/(eps+fabs(g[2]-gin)+fabs(g[2]-rawData[rr-4][cc+4])+fabs(rawData[rr-1][cc+1]-rawData[rr-3][cc+3])); - p[3]=1/(eps+fabs(g[3]-gin)+fabs(g[3]-rawData[rr][cc-4])+fabs(rawData[rr][cc-1]-rawData[rr][cc-3])); - p[4]=1/(eps+fabs(g[4]-gin)+fabs(g[4]-rawData[rr][cc+4])+fabs(rawData[rr][cc+1]-rawData[rr][cc+3])); - p[5]=1/(eps+fabs(g[5]-gin)+fabs(g[5]-rawData[rr+4][cc-4])+fabs(rawData[rr+1][cc-1]-rawData[rr+3][cc-3])); - p[6]=1/(eps+fabs(g[6]-gin)+fabs(g[6]-rawData[rr+4][cc])+fabs(rawData[rr+1][cc]-rawData[rr+3][cc])); - p[7]=1/(eps+fabs(g[7]-gin)+fabs(g[7]-rawData[rr+4][cc+4])+fabs(rawData[rr+1][cc+1]-rawData[rr+3][cc+3])); + p[0]=1/(eps+fabs(g[0]-gin)+fabs(g[0]-ri->data[rr-4][cc-4])+fabs(ri->data[rr-1][cc-1]-ri->data[rr-3][cc-3])); + p[1]=1/(eps+fabs(g[1]-gin)+fabs(g[1]-ri->data[rr-4][cc])+fabs(ri->data[rr-1][cc]-ri->data[rr-3][cc])); + p[2]=1/(eps+fabs(g[2]-gin)+fabs(g[2]-ri->data[rr-4][cc+4])+fabs(ri->data[rr-1][cc+1]-ri->data[rr-3][cc+3])); + p[3]=1/(eps+fabs(g[3]-gin)+fabs(g[3]-ri->data[rr][cc-4])+fabs(ri->data[rr][cc-1]-ri->data[rr][cc-3])); + p[4]=1/(eps+fabs(g[4]-gin)+fabs(g[4]-ri->data[rr][cc+4])+fabs(ri->data[rr][cc+1]-ri->data[rr][cc+3])); + p[5]=1/(eps+fabs(g[5]-gin)+fabs(g[5]-ri->data[rr+4][cc-4])+fabs(ri->data[rr+1][cc-1]-ri->data[rr+3][cc-3])); + p[6]=1/(eps+fabs(g[6]-gin)+fabs(g[6]-ri->data[rr+4][cc])+fabs(ri->data[rr+1][cc]-ri->data[rr+3][cc])); + p[7]=1/(eps+fabs(g[7]-gin)+fabs(g[7]-ri->data[rr+4][cc+4])+fabs(ri->data[rr+1][cc+1]-ri->data[rr+3][cc+3])); - rawData[rr][cc] = (int)((g[0]*p[0]+g[1]*p[1]+g[2]*p[2]+g[3]*p[3]+g[4]*p[4]+ \ + ri->data[rr][cc] = (int)((g[0]*p[0]+g[1]*p[1]+g[2]*p[2]+g[3]*p[3]+g[4]*p[4]+ \ g[5]*p[5]+g[6]*p[6]+g[7]*p[7])/(p[0]+p[1]+p[2]+p[3]+p[4]+p[5]+p[6]+p[7])); }//now impulsive values have been corrected @@ -750,27 +713,48 @@ int RawImageSource::load (Glib::ustring fname) { plistener->setProgress (0.0); } - ri = new RawImage(fname); - int res = ri->loadRaw (); + ri = new RawImage; + int res = loadRaw (fname.c_str(), ri); if (res) return res; - plistener=NULL; //\TODO must be reintroduced -/***** Copy once constant data extracted from raw *******/ + if(red) { + delete red; + red = 0; + } + if(green) { + delete green; + green = 0; + } + if(blue) { + delete blue; + blue = 0; + } + W = ri->width; H = ri->height; + + d1x = !strcmp(ri->model, "D1X"); fuji = ri->fuji_width; + if (d1x) + border = 8; + for (int i=0; i<3; i++) for (int j=0; j<3; j++) coeff[i][j] = ri->coeff[i][j]; + // compute inverse of the color transformation matrix inverse33 (coeff, icoeff); - d1x = !strcmp(ri->model, "D1X"); - if (d1x) - border = 8; - if (ri->profile_data) - embProfile = cmsOpenProfileFromMem (ri->profile_data, ri->profile_len); + double cam_r = coeff[0][0]*ri->camwb_red + coeff[0][1]*ri->camwb_green + coeff[0][2]*ri->camwb_blue; + double cam_g = coeff[1][0]*ri->camwb_red + coeff[1][1]*ri->camwb_green + coeff[1][2]*ri->camwb_blue; + double cam_b = coeff[2][0]*ri->camwb_red + coeff[2][1]*ri->camwb_green + coeff[2][2]*ri->camwb_blue; + + wb = ColorTemp (cam_r, cam_g, cam_b); + + double tr = icoeff[0][0] * cam_r + icoeff[0][1] * cam_g + icoeff[0][2] * cam_b; + double tg = icoeff[1][0] * cam_r + icoeff[1][1] * cam_g + icoeff[1][2] * cam_b; + double tb = icoeff[2][0] * cam_r + icoeff[2][1] * cam_g + icoeff[2][2] * cam_b; // create profile memset (cam, 0, sizeof(cam)); @@ -781,66 +765,20 @@ int RawImageSource::load (Glib::ustring fname) { camProfile = iccStore.createFromMatrix (cam, false, "Camera"); inverse33 (cam, icam); - //Load complete Exif informations + if (ri->profile_data) + embProfile = cmsOpenProfileFromMem (ri->profile_data, ri->profile_len); + + defGain = log(ri->defgain) / log(2.0); + RawMetaDataLocation rml; rml.exifBase = ri->exifbase; rml.ciffBase = ri->ciff_base; rml.ciffLength = ri->ciff_len; - idata = new ImageData (fname, &rml); - green = allocArray(W,H); - red = allocArray(W,H); - blue = allocArray(W,H); - hpmap = allocArray(W, H); - - return 0; // OK! -} - -void RawImageSource::preprocess (const RAWParams &raw) -{ - Glib::ustring newDF = raw.dark_frame; - Glib::ustring currentDF = (df ? df->fname : ""); - if (!raw.df_autoselect) { - if (newDF != currentDF) { - if (df) - delete df; - df = NULL; - if (newDF.length() > 0) { - df = new RawImage(newDF); - int res = df->loadRaw(); - if (res) { - delete df; - df = NULL; - } - } - } - - copyOriginalPixels(ri, df); - }else{ - RawImage *rid = dfm.searchDarkFrame( ri->make, ri->model, ri->iso_speed, ri->shutter, ri->timestamp); - copyOriginalPixels(ri, rid); - } - if(!raw.hotdeadpix_filt && raw.df_autoselect ){ - std::list bp = dfm.searchBadPixels( ri->make, ri->model, ri->iso_speed, ri->shutter, ri->timestamp); - cfaCleanFromList(bp); - } - preInterpolate(false); - scaleColors( false,true); - - double cam_r = coeff[0][0]*camwb_red + coeff[0][1]*camwb_green + coeff[0][2]*camwb_blue; - double cam_g = coeff[1][0]*camwb_red + coeff[1][1]*camwb_green + coeff[1][2]*camwb_blue; - double cam_b = coeff[2][0]*camwb_red + coeff[2][1]*camwb_green + coeff[2][2]*camwb_blue; - - wb = ColorTemp (cam_r, cam_g, cam_b); - - double tr = icoeff[0][0] * cam_r + icoeff[0][1] * cam_g + icoeff[0][2] * cam_b; - double tg = icoeff[1][0] * cam_r + icoeff[1][1] * cam_g + icoeff[1][2] * cam_b; - double tb = icoeff[2][0] * cam_r + icoeff[2][1] * cam_g + icoeff[2][2] * cam_b; - - defGain = log(ri->defgain) / log(2.0); //\TODO rivedere l'assegnamento di ri->defgain che dovrebbe essere "costante" + idata = new ImageData (fname, &rml); // check if it is an olympus E camera, if yes, compute G channel pre-compensation factors - if ( raw.greenthresh || (((idata->getMake().size()>=7 && idata->getMake().substr(0,7)=="OLYMPUS" && idata->getModel()[0]=='E') || (idata->getMake().size()>=9 && idata->getMake().substr(0,7)=="Panasonic")) && raw.dmethod != RAWParams::methodstring[ RAWParams::vng4] && ri->filters) ) { + if (settings->greenthresh || (((idata->getMake().size()>=7 && idata->getMake().substr(0,7)=="OLYMPUS" && idata->getModel()[0]=='E') || (idata->getMake().size()>=9 && idata->getMake().substr(0,7)=="Panasonic")) && settings->demosaicMethod!="vng4" && ri->filters) ) { // global correction int ng1=0, ng2=0; double avgg1=0, avgg2=0; @@ -848,11 +786,11 @@ void RawImageSource::preprocess (const RAWParams &raw) for (int j=border; jdata[i][j]; ng1++; } else { - avgg2 += rawData[i][j]; + avgg2 += ri->data[i][j]; ng2++; } } @@ -861,18 +799,48 @@ void RawImageSource::preprocess (const RAWParams &raw) for (int i=border; idata[i][j] = CLIP(ri->data[i][j] * (i%2 ? corrg2 : corrg1)); } - if ( raw.greenthresh >0) { + + // local correction in a 9x9 box + if (settings->greenthresh) { +//Emil's green equilbration if (plistener) { plistener->setProgressStr ("Green equilibrate..."); plistener->setProgress (0.0); } - green_equilibrate(0.01*(raw.greenthresh)); + green_equilibrate(0.01*(settings->greenthresh)); + +/* unsigned short* corr_alloc = new unsigned short[W*H]; + unsigned short** corr_data = new unsigned short* [H]; + for (int i=0; iallocation, W*H*sizeof(unsigned short)); + for (int i=border; idata[i-4][j-4] + ri->data[i-4][j-2] + ri->data[i-4][j] + ri->data[i-4][j+2] + + ri->data[i-2][j-4] + ri->data[i-2][j-2] + ri->data[i-2][j] + ri->data[i-2][j+2] + + ri->data[i][j-4] + ri->data[i][j-2] + ri->data[i][j] + ri->data[i][j+2] + + ri->data[i+2][j-4] + ri->data[i+2][j-2] + ri->data[i+2][j] + ri->data[i+2][j+2]; + unsigned int ag2 = ri->data[i-3][j-3] + ri->data[i-3][j-1] + ri->data[i-3][j+1] + ri->data[i-3][j+1] + + ri->data[i-1][j-3] + ri->data[i-1][j-1] + ri->data[i-1][j+1] + ri->data[i-1][j+1] + + ri->data[i+1][j-3] + ri->data[i+1][j-1] + ri->data[i+1][j+1] + ri->data[i+1][j+1] + + ri->data[i+3][j-3] + ri->data[i+3][j-1] + ri->data[i+3][j+1] + ri->data[i+3][j+1]; + unsigned int val = (ri->data[i][j] + ri->data[i][j] * ag2 / ag1) / 2; + corr_data[i][j] = CLIP (val); + } + memcpy (ri->allocation, corr_alloc, W*H*sizeof(unsigned short)); + delete corr_alloc; + delete corr_data; */ + } - if ( raw.hotdeadpix_filt ) { +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//Emil's CFA hot/dead pixel filter + + if (settings->hotdeadpix_filt) { if (plistener) { plistener->setProgressStr ("Hot/Dead Pixel Filter..."); plistener->setProgress (0.0); @@ -880,17 +848,23 @@ void RawImageSource::preprocess (const RAWParams &raw) cfa_clean(0.1); } + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//Emil's line noise filter - if ( raw.linenoise >0 ) { + if (settings->linenoise) { if (plistener) { plistener->setProgressStr ("Line Denoise..."); plistener->setProgress (0.0); } - cfa_linedn(0.00002*(raw.linenoise)); + cfa_linedn(0.00002*(settings->linenoise)); } - if ( raw.ca_autocorrect ) { +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//Emil's CA auto correction + + if (settings->ca_autocorrect) { if (plistener) { plistener->setProgressStr ("CA Auto Correction..."); plistener->setProgress (0.0); @@ -898,203 +872,37 @@ void RawImageSource::preprocess (const RAWParams &raw) CA_correct_RT(); } - - - return; -} -void RawImageSource::demosaic(const RAWParams &raw) -{ +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + if (ri->filters) { //MyTime t1,t2; //t1.set(); - if ( raw.dmethod == RAWParams::methodstring[RAWParams::hphd] ) + // demosaic + if (settings->demosaicMethod=="hphd") hphd_demosaic (); - else if (raw.dmethod == RAWParams::methodstring[RAWParams::vng4] ) + else if (settings->demosaicMethod=="vng4") vng4_demosaic (); - else if (raw.dmethod == RAWParams::methodstring[RAWParams::ahd] ) + else if (settings->demosaicMethod=="ahd") ahd_demosaic (); - else if (raw.dmethod == RAWParams::methodstring[RAWParams::amaze] ) - amaze_demosaic_RT (); - else if (raw.dmethod == RAWParams::methodstring[RAWParams::dcb] ) - dcb_demosaic(raw.dcb_iterations, raw.dcb_enhance? 1:0); - else if (raw.dmethod == RAWParams::methodstring[RAWParams::eahd]) - eahd_demosaic (); + //else if (settings->demosaicMethod=="ppg") + // ppg_demosaic (); + else if (settings->demosaicMethod=="amaze") + amaze_demosaic_RT ();//Emil's code for AMaZE + else if (settings->demosaicMethod=="dcb") + dcb_demosaic(settings->dcb_iterations, settings->dcb_enhance? 1:0); else - nodemosaic(); + eahd_demosaic (); //t2.set(); //printf("Demosaicing:%d usec\n",t2.etime(t1)); } + + if (plistener) { plistener->setProgressStr ("Ready."); plistener->setProgress (1.0); } -} - -/* Copy original pixel data and - * subtract dark frame (if present) from current image - */ -void RawImageSource::copyOriginalPixels(RawImage *src, RawImage *riDark ) -{ - if (ri->filters) { - if (!rawData) - rawData = allocArray< unsigned short >(W,H); - if (riDark && W == riDark->width && H == riDark->height) { - for (int row = 0; row < H; row++) { - for (int col = 0; col < W; col++) { - rawData[row][col] = MAX (src->data[row][col]+ri->black_point - riDark->data[row][col], 0); - } - } - }else{ - for (int row = 0; row < H; row++) { - for (int col = 0; col < W; col++) { - rawData[row][col] = src->data[row][col]; - } - } - } - }else{ - if (!rawData) - rawData = allocArray< unsigned short >(3*W,H); - if (riDark && W == riDark->width && H == riDark->height) { - for (int row = 0; row < H; row++) { - for (int col = 0; col < W; col++) { - rawData[row][3*col+0] = MAX (src->data[row][3*col+0]+ri->black_point - riDark->data[row][3*col+0], 0); - rawData[row][3*col+1] = MAX (src->data[row][3*col+1]+ri->black_point - riDark->data[row][3*col+1], 0); - rawData[row][3*col+2] = MAX (src->data[row][3*col+2]+ri->black_point - riDark->data[row][3*col+2], 0); - } - } - }else{ - for (int row = 0; row < H; row++) { - for (int col = 0; col < W; col++) { - rawData[row][3*col+0] = src->data[row][3*col+0]; - rawData[row][3*col+1] = src->data[row][3*col+1]; - rawData[row][3*col+2] = src->data[row][3*col+2]; - } - } - } - } -} - -/* Scale original pixels into the range 0 65535 using black offsets and multipliers - * Calculate camwb_red,camwb_green,camwb_blue - * - * Calculate 4 coeff. scale_mul[] and 4 offset cblack[] - * and reset all pixels - */ -void RawImageSource::scaleColors(bool use_auto_wb, bool use_camera_wb, int highlight) -{ - unsigned row, col, ur, uc, i, x, y, c, sum[8]; - int val, dark, sat; - double dsum[8], dmin, dmax; - float pre_mul[4]; - - int cblack[4]; // offset calculated - float scale_mul[4]; // coeff. calculated to scale - - for (int c = 0; c < 4; c++){ - cblack[c] = ri->cblack[c] + ri->black_point; - pre_mul[c] = ri->pre_mul[c]; - } - /* - if (user_mul[0]) - memcpy(pre_mul, user_mul, sizeof pre_mul);*/ - if (use_auto_wb || (use_camera_wb && ri->cam_mul[0] == -1)) { - memset(dsum, 0, sizeof dsum); - for (row = 0; row < H; row += 8) - for (col = 0; col < W; col += 8) { - memset(sum, 0, sizeof sum); - for (y = row; y < row + 8 && y < H; y++) - for (x = col; x < col + 8 && x < W; x++) - for (int c = 0; c < 3; c++) { - if (ri->filters) { - c = FC(y, x); - val = rawData[y][x]; - } else - val = rawData[y][3*x+c]; - if (val > ri->maximum - 25) - goto skip_block; - if ((val -= cblack[c]) < 0) - val = 0; - sum[c] += val; - sum[c + 4]++; - if (ri->filters) - break; - } - for (c = 0; c < 8; c++) - dsum[c] += sum[c]; -skip_block: ; - } - for (int c = 0; c < 4; c++) - if (dsum[c]) - pre_mul[c] = dsum[c + 4] / dsum[c]; - } - if (use_camera_wb && ri->cam_mul[0] != -1) { - memset(sum, 0, sizeof sum); - for (row = 0; row < 8; row++) - for (col = 0; col < 8; col++) { - int c = FC(row, col); - if ((val = ri->white[row][col] - cblack[c]) > 0) - sum[c] += val; - sum[c + 4]++; - } - if (sum[0] && sum[1] && sum[2] && sum[3]) - for (int c = 0; c < 4; c++) - pre_mul[c] = (float) sum[c + 4] / sum[c]; - else if (ri->cam_mul[0] && ri->cam_mul[2]) - memcpy(pre_mul, ri->cam_mul, sizeof pre_mul); - else - fprintf(stderr, "Cannot use camera white balance.\n"); - } - if (pre_mul[3] == 0) - pre_mul[3] = ri->colors < 4 ? pre_mul[1] : 1; - dark = ri->black_point; - sat = ri->maximum; - sat -= ri->black_point; - for (dmin = DBL_MAX, dmax = c = 0; c < 4; c++) { - if (dmin > pre_mul[c]) - dmin = pre_mul[c]; - if (dmax < pre_mul[c]) - dmax = pre_mul[c]; - } - if (!highlight) - dmax = dmin; - for (c = 0; c < 4; c++) - scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / sat; - if (settings->verbose) { - fprintf(stderr,"Scaling with darkness %d, saturation %d, and\nmultipliers", dark, sat); - for (c = 0; c < 4; c++) - fprintf(stderr, " %f", pre_mul[c]); - fputc('\n', stderr); - } - - // scale image colors - for (row = 0; row < H; row ++){ - for (col = 0; col < W; col++) { - val = rawData[row][col]; - if (!val) - continue; - int c = FC(row, col); - val -= cblack[c]; - val *= scale_mul[c]; - rawData[row][col] = CLIP(val); - } - } - camwb_red = ri->pre_mul[0] / pre_mul[0]; - camwb_green = ri->pre_mul[1] / pre_mul[1]; - camwb_blue = ri->pre_mul[2] / pre_mul[2]; - ri->defgain = 1.0 / MIN(MIN(pre_mul[0],pre_mul[1]),pre_mul[2]); -} - -void RawImageSource::preInterpolate(bool force4colors) -{ - if (ri->filters && ri->colors == 3) { - if (force4colors) - ri->colors++; - else { - ri->prefilters = ri->filters; - ri->filters &= ~((ri->filters & 0x55555555) << 1); - } - } + return 0; } int RawImageSource::defTransform (int tran) { @@ -1411,6 +1219,10 @@ void RawImageSource::eahd_demosaic () { unsigned short* homh[3]; unsigned short* homv[3]; + green = new unsigned short*[H]; + for (int i=0; idata[i-1][j]; else { hc = homh[imx][j]; vc = homv[imx][j]; @@ -1617,19 +1429,6 @@ void RawImageSource::eahd_demosaic () { freeArray2(lav, 3); freeArray2(lbv, 3); freeArray2(homv, 3); - - // Interpolate R and B - for (int i=0; idata[i-5][k] - 8*ri->data[i-4][k] + 27*ri->data[i-3][k] - 48*ri->data[i-2][k] + 42*ri->data[i-1][k] - + (ri->data[i+5][k] - 8*ri->data[i+4][k] + 27*ri->data[i+3][k] - 48*ri->data[i+2][k] + 42*ri->data[i+1][k])) / 100.0; temp[i] = ABS(temp[i]); } for (int j=4; jdata[i][j-5] - 8*ri->data[i][j-4] + 27*ri->data[i][j-3] - 48*ri->data[i][j-2] + 42*ri->data[i][j-1] - + (ri->data[i][j+5] - 8*ri->data[i][j+4] + 27*ri->data[i][j+3] - 48*ri->data[i][j+2] + 42*ri->data[i][j+1])) / 100; temp[j] = ABS(temp[j]); } for (int j=4; jdata[i][j]; else { if (this->hpmap[i][j]==1) { - int g2 = rawData[i][j+1] + ((rawData[i][j] - rawData[i][j+2]) >> 1); - int g4 = rawData[i][j-1] + ((rawData[i][j] - rawData[i][j-2]) >> 1); + int g2 = ri->data[i][j+1] + ((ri->data[i][j] - ri->data[i][j+2]) >> 1); + int g4 = ri->data[i][j-1] + ((ri->data[i][j] - ri->data[i][j-2]) >> 1); - int dx = rawData[i][j+1] - rawData[i][j-1]; - int d1 = rawData[i][j+3] - rawData[i][j+1]; - int d2 = rawData[i][j+2] - rawData[i][j]; - int d3 = (rawData[i-1][j+2] - rawData[i-1][j]) >> 1; - int d4 = (rawData[i+1][j+2] - rawData[i+1][j]) >> 1; + int dx = ri->data[i][j+1] - ri->data[i][j-1]; + int d1 = ri->data[i][j+3] - ri->data[i][j+1]; + int d2 = ri->data[i][j+2] - ri->data[i][j]; + int d3 = (ri->data[i-1][j+2] - ri->data[i-1][j]) >> 1; + int d4 = (ri->data[i+1][j+2] - ri->data[i+1][j]) >> 1; double e2 = 1.0 / (1.0 + ABS(dx) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); - d1 = rawData[i][j-3] - rawData[i][j-1]; - d2 = rawData[i][j-2] - rawData[i][j]; - d3 = (rawData[i-1][j-2] - rawData[i-1][j]) >> 1; - d4 = (rawData[i+1][j-2] - rawData[i+1][j]) >> 1; + d1 = ri->data[i][j-3] - ri->data[i][j-1]; + d2 = ri->data[i][j-2] - ri->data[i][j]; + d3 = (ri->data[i-1][j-2] - ri->data[i-1][j]) >> 1; + d4 = (ri->data[i+1][j-2] - ri->data[i+1][j]) >> 1; double e4 = 1.0 / (1.0 + ABS(dx) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); green[i][j] = CLIP((e2 * g2 + e4 * g4) / (e2 + e4)); } else if (this->hpmap[i][j]==2) { - int g1 = rawData[i-1][j] + ((rawData[i][j] - rawData[i-2][j]) >> 1); - int g3 = rawData[i+1][j] + ((rawData[i][j] - rawData[i+2][j]) >> 1); + int g1 = ri->data[i-1][j] + ((ri->data[i][j] - ri->data[i-2][j]) >> 1); + int g3 = ri->data[i+1][j] + ((ri->data[i][j] - ri->data[i+2][j]) >> 1); - int dy = rawData[i+1][j] - rawData[i-1][j]; - int d1 = rawData[i-1][j] - rawData[i-3][j]; - int d2 = rawData[i][j] - rawData[i-2][j]; - int d3 = (rawData[i][j-1] - rawData[i-2][j-1]) >> 1; - int d4 = (rawData[i][j+1] - rawData[i-2][j+1]) >> 1; + int dy = ri->data[i+1][j] - ri->data[i-1][j]; + int d1 = ri->data[i-1][j] - ri->data[i-3][j]; + int d2 = ri->data[i][j] - ri->data[i-2][j]; + int d3 = (ri->data[i][j-1] - ri->data[i-2][j-1]) >> 1; + int d4 = (ri->data[i][j+1] - ri->data[i-2][j+1]) >> 1; double e1 = 1.0 / (1.0 + ABS(dy) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); - d1 = rawData[i+1][j] - rawData[i+3][j]; - d2 = rawData[i][j] - rawData[i+2][j]; - d3 = (rawData[i][j-1] - rawData[i+2][j-1]) >> 1; - d4 = (rawData[i][j+1] - rawData[i+2][j+1]) >> 1; + d1 = ri->data[i+1][j] - ri->data[i+3][j]; + d2 = ri->data[i][j] - ri->data[i+2][j]; + d3 = (ri->data[i][j-1] - ri->data[i+2][j-1]) >> 1; + d4 = (ri->data[i][j+1] - ri->data[i+2][j+1]) >> 1; double e3 = 1.0 / (1.0 + ABS(dy) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); green[i][j] = CLIP((e1 * g1 + e3 * g3) / (e1 + e3)); } else { - int g1 = rawData[i-1][j] + ((rawData[i][j] - rawData[i-2][j]) >> 1); - int g2 = rawData[i][j+1] + ((rawData[i][j] - rawData[i][j+2]) >> 1); - int g3 = rawData[i+1][j] + ((rawData[i][j] - rawData[i+2][j]) >> 1); - int g4 = rawData[i][j-1] + ((rawData[i][j] - rawData[i][j-2]) >> 1); + int g1 = ri->data[i-1][j] + ((ri->data[i][j] - ri->data[i-2][j]) >> 1); + int g2 = ri->data[i][j+1] + ((ri->data[i][j] - ri->data[i][j+2]) >> 1); + int g3 = ri->data[i+1][j] + ((ri->data[i][j] - ri->data[i+2][j]) >> 1); + int g4 = ri->data[i][j-1] + ((ri->data[i][j] - ri->data[i][j-2]) >> 1); - int dx = rawData[i][j+1] - rawData[i][j-1]; - int dy = rawData[i+1][j] - rawData[i-1][j]; + int dx = ri->data[i][j+1] - ri->data[i][j-1]; + int dy = ri->data[i+1][j] - ri->data[i-1][j]; - int d1 = rawData[i-1][j] - rawData[i-3][j]; - int d2 = rawData[i][j] - rawData[i-2][j]; - int d3 = (rawData[i][j-1] - rawData[i-2][j-1]) >> 1; - int d4 = (rawData[i][j+1] - rawData[i-2][j+1]) >> 1; + int d1 = ri->data[i-1][j] - ri->data[i-3][j]; + int d2 = ri->data[i][j] - ri->data[i-2][j]; + int d3 = (ri->data[i][j-1] - ri->data[i-2][j-1]) >> 1; + int d4 = (ri->data[i][j+1] - ri->data[i-2][j+1]) >> 1; double e1 = 1.0 / (1.0 + ABS(dy) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); - d1 = rawData[i][j+3] - rawData[i][j+1]; - d2 = rawData[i][j+2] - rawData[i][j]; - d3 = (rawData[i-1][j+2] - rawData[i-1][j]) >> 1; - d4 = (rawData[i+1][j+2] - rawData[i+1][j]) >> 1; + d1 = ri->data[i][j+3] - ri->data[i][j+1]; + d2 = ri->data[i][j+2] - ri->data[i][j]; + d3 = (ri->data[i-1][j+2] - ri->data[i-1][j]) >> 1; + d4 = (ri->data[i+1][j+2] - ri->data[i+1][j]) >> 1; double e2 = 1.0 / (1.0 + ABS(dx) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); - d1 = rawData[i+1][j] - rawData[i+3][j]; - d2 = rawData[i][j] - rawData[i+2][j]; - d3 = (rawData[i][j-1] - rawData[i+2][j-1]) >> 1; - d4 = (rawData[i][j+1] - rawData[i+2][j+1]) >> 1; + d1 = ri->data[i+1][j] - ri->data[i+3][j]; + d2 = ri->data[i][j] - ri->data[i+2][j]; + d3 = (ri->data[i][j-1] - ri->data[i+2][j-1]) >> 1; + d4 = (ri->data[i][j+1] - ri->data[i+2][j+1]) >> 1; double e3 = 1.0 / (1.0 + ABS(dy) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); - d1 = rawData[i][j-3] - rawData[i][j-1]; - d2 = rawData[i][j-2] - rawData[i][j]; - d3 = (rawData[i-1][j-2] - rawData[i-1][j]) >> 1; - d4 = (rawData[i+1][j-2] - rawData[i+1][j]) >> 1; + d1 = ri->data[i][j-3] - ri->data[i][j-1]; + d2 = ri->data[i][j-2] - ri->data[i][j]; + d3 = (ri->data[i-1][j-2] - ri->data[i-1][j]) >> 1; + d4 = (ri->data[i+1][j-2] - ri->data[i+1][j]) >> 1; double e4 = 1.0 / (1.0 + ABS(dx) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); @@ -1835,6 +1634,7 @@ void RawImageSource::hphd_demosaic () { if (plistener) plistener->setProgress (0.33); + this->hpmap = allocArray(W, H); for (int i=0; ihpmap[i], 0, W*sizeof(char)); @@ -1857,20 +1657,13 @@ void RawImageSource::hphd_demosaic () { if (plistener) plistener->setProgress (0.66); - + + green = new unsigned short*[H]; + for (int i=0; isetProgress (1.0); } @@ -1988,14 +1781,14 @@ int RawImageSource::getAEHistogram (unsigned int* histogram, int& histcompr) { if (ri->filters) for (int j=start; j>histcompr]+=2; + histogram[ri->data[i][j]>>histcompr]+=2; else - histogram[rawData[i][j]>>histcompr]+=4; + histogram[ri->data[i][j]>>histcompr]+=4; else for (int j=start; j<3*end; j++) { - histogram[rawData[i][j+0]>>histcompr]++; - histogram[rawData[i][j+1]>>histcompr]++; - histogram[rawData[i][j+2]>>histcompr]++; + histogram[ri->data[i][j+0]>>histcompr]++; + histogram[ri->data[i][j+1]>>histcompr]++; + histogram[ri->data[i][j+2]>>histcompr]++; } } return 1; @@ -2015,21 +1808,21 @@ ColorTemp RawImageSource::getAutoWB () { int end = MIN(ri->height+ri->width-fw-i, fw+i) - 32; for (int j=start; jfilters) { - double d = CLIP(ri->defgain*rawData[i][3*j]); + double d = CLIP(ri->defgain*ri->data[i][3*j]); if (d>64000) continue; avg_r += d*d*d*d*d*d; rn++; - d = CLIP(ri->defgain*rawData[i][3*j+1]); + d = CLIP(ri->defgain*ri->data[i][3*j+1]); if (d>64000) continue; avg_g += d*d*d*d*d*d; gn++; - d = CLIP(ri->defgain*rawData[i][3*j+2]); + d = CLIP(ri->defgain*ri->data[i][3*j+2]); if (d>64000) continue; avg_b += d*d*d*d*d*d; bn++; } else { - double d = CLIP(ri->defgain*rawData[i][j]); + double d = CLIP(ri->defgain*ri->data[i][j]); if (d>64000) continue; double dp = d*d*d*d*d*d; @@ -2053,21 +1846,21 @@ ColorTemp RawImageSource::getAutoWB () { for (int i=32; iheight-32; i++) for (int j=32; jwidth-32; j++) { if (!ri->filters) { - double d = CLIP(ri->defgain*rawData[i][3*j]); + double d = CLIP(ri->defgain*ri->data[i][3*j]); if (d>64000) continue; avg_r += d*d*d*d*d*d; rn++; - d = CLIP(ri->defgain*rawData[i][3*j+1]); + d = CLIP(ri->defgain*ri->data[i][3*j+1]); if (d>64000) continue; avg_g += d*d*d*d*d*d; gn++; - d = CLIP(ri->defgain*rawData[i][3*j+2]); + d = CLIP(ri->defgain*ri->data[i][3*j+2]); if (d>64000) continue; avg_b += d*d*d*d*d*d; bn++; } else { - double d = CLIP(ri->defgain*rawData[i][j]); + double d = CLIP(ri->defgain*ri->data[i][j]); if (d>64000) continue; double dp = d*d*d*d*d*d; @@ -2094,9 +1887,9 @@ ColorTemp RawImageSource::getAutoWB () { // return ColorTemp (pow(avg_r/rn, 1.0/6.0)*img_r, pow(avg_g/gn, 1.0/6.0)*img_g, pow(avg_b/bn, 1.0/6.0)*img_b); - double reds = pow (avg_r/rn, 1.0/6.0) * camwb_red; - double greens = pow (avg_g/gn, 1.0/6.0) * camwb_green; - double blues = pow (avg_b/bn, 1.0/6.0) * camwb_blue; + double reds = pow (avg_r/rn, 1.0/6.0) * ri->camwb_red; + double greens = pow (avg_g/gn, 1.0/6.0) * ri->camwb_green; + double blues = pow (avg_b/bn, 1.0/6.0) * ri->camwb_blue; double rm = coeff[0][0]*reds + coeff[0][1]*greens + coeff[0][2]*blues; double gm = coeff[1][0]*reds + coeff[1][1]*greens + coeff[1][2]*blues; @@ -2173,17 +1966,17 @@ ColorTemp RawImageSource::getSpotWB (std::vector red, std::vector=0 && y>=0 && xdata[y][3*x]; rn++; } transformPosition (green[i].x, green[i].y, tran, x, y); if (x>=0 && y>=0 && xdata[y][3*x+1]; gn++; } transformPosition (blue[i].x, blue[i].y, tran, x, y); if (x>=0 && y>=0 && xdata[y][3*x+2]; bn++; } } @@ -2195,7 +1988,7 @@ ColorTemp RawImageSource::getSpotWB (std::vector red, std::vector=0 && yv>=0 && xvdata[yv][xv]; rn++; break; } @@ -2205,7 +1998,7 @@ ColorTemp RawImageSource::getSpotWB (std::vector red, std::vector=0 && yv>=0 && xvdata[yv][xv]; gn++; break; } @@ -2215,7 +2008,7 @@ ColorTemp RawImageSource::getSpotWB (std::vector red, std::vector=0 && yv>=0 && xvdata[yv][xv]; bn++; break; } @@ -2223,9 +2016,9 @@ ColorTemp RawImageSource::getSpotWB (std::vector red, std::vectorcamwb_red; + greens = greens/gn * ri->camwb_green; + blues = blues/bn * ri->camwb_blue; double rm = coeff[0][0]*reds + coeff[0][1]*greens + coeff[0][2]*blues; double gm = coeff[1][0]*reds + coeff[1][1]*greens + coeff[1][2]*blues; @@ -2280,7 +2073,7 @@ void RawImageSource::vng4_demosaic () { image = (ushort (*)[4]) calloc (H*W, sizeof *image); for (int ii=0; iidata[ii][jj]; // first linear interpolation for (row=0; row < 16; row++) @@ -2408,21 +2201,12 @@ void RawImageSource::vng4_demosaic () { free (brow[4]); free (code[0][0]); + green = new unsigned short*[H]; for (int i=0; i> 1; } - // Interpolate R and B - for (int i=0; idata[ii][jj]; border_interpolate(3, image); @@ -2595,7 +2379,7 @@ void RawImageSource::ahd_demosaic() image = (ushort (*)[4]) calloc (H*W, sizeof *image); for (int ii=0; iidata[ii][jj]; for (i=0; i < 0x10000; i++) { r = i / 65535.0; @@ -2721,37 +2505,28 @@ void RawImageSource::ahd_demosaic() if(plistener) plistener->setProgress (1.0); free (buffer); + red = new unsigned short*[H]; for (int i=0; isetProgressStr ("DCB Demosaicing..."); @@ -3228,7 +3011,7 @@ void RawImageSource::dcb_demosaic(int iterations, int dcb_enhance) float (*chrm)[2] = chroma; #endif - fill_raw( tile, x0,y0,rawData ); + fill_raw( tile, x0,y0,ri->data ); if( !xTile || !yTile || xTile==wTiles-1 || yTile==hTiles-1) fill_border(tile,6, x0, y0); dcb_hid(tile,buffer,buffer2,x0,y0); diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 9fe1e31f8..fe6fc8b30 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -21,7 +21,6 @@ #include #include - #define HR_SCALE 2 namespace rtengine { @@ -54,9 +53,6 @@ class RawImageSource : public ImageSource { int W, H; ColorTemp wb; ProgressListener* plistener; - double camwb_red; - double camwb_green; - double camwb_blue; double coeff[3][3]; double icoeff[3][3]; double cam[3][3]; @@ -69,20 +65,18 @@ class RawImageSource : public ImageSource { char** needhr; // for color propagation int max[3]; double defGain; - + bool full; + Glib::ustring oldmethod; cmsHPROFILE camProfile; cmsHPROFILE embProfile; - RawImage* ri; // Copy of raw pixels - RawImage* df; // Darkframe pixels (if present) + RawImage* ri; // to accelerate CIELAB conversion: double lc00, lc01, lc02, lc10, lc11, lc12, lc20, lc21, lc22; double* cache; int threshold; - - unsigned short** rawData; // holds pixel values, data[i][j] corresponds to the ith row and jth column - + // the interpolated green plane: unsigned short** green; // the interpolated red plane: @@ -103,18 +97,13 @@ class RawImageSource : public ImageSource { void updateHLRecoveryMap (std::string method, double rm, double gm, double bm); void updateHLRecoveryMap_ColorPropagation (); void HLRecovery_ColorPropagation (unsigned short* red, unsigned short* green, unsigned short* blue, int i, int sx1, int width, int skip); - int FC(int row, int col){ return (ri->prefilters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3); } + public: RawImageSource (); ~RawImageSource (); int load (Glib::ustring fname); - void preprocess (const RAWParams &raw); - void demosaic (const RAWParams &raw); - void copyOriginalPixels( RawImage *ri, RawImage *riDark ); - void scaleColors( bool use_auto_wb=true, bool use_camera_wb=false, int highlight=1 ); - void preInterpolate(bool force4colors=false); - void getImage (ColorTemp ctemp, int tran, Image16* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp, RAWParams raw); + void getImage (ColorTemp ctemp, int tran, Image16* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp); ColorTemp getWB () { return wb; } ColorTemp getAutoWB (); ColorTemp getSpotWB (std::vector red, std::vector green, std::vector& blue, int tran); @@ -146,9 +135,9 @@ class RawImageSource : public ImageSource { inline void interpolate_row_rb (unsigned short* ar, unsigned short* ab, unsigned short* pg, unsigned short* cg, unsigned short* ng, int i); inline void interpolate_row_rb_mul_pp (unsigned short* ar, unsigned short* ab, unsigned short* pg, unsigned short* cg, unsigned short* ng, int i, double r_mul, double g_mul, double b_mul, int x1, int width, int skip); - int LinEqSolve( int nDim, float* pfMatr, float* pfVect, float* pfSolution);//Emil's CA auto correction + int LinEqSolve (int nDim, float* pfMatr, float* pfVect, float* pfSolution);//Emil's CA auto correction void CA_correct_RT (); - void cfaCleanFromList( const std::list &bpList ); + void cfa_clean (float thresh);//Emil's hot/dead pixel filter void ddct8x8s(int isgn, float **a); @@ -156,7 +145,7 @@ class RawImageSource : public ImageSource { void green_equilibrate (float greenthresh);//Emil's green equilibration - void nodemosaic (); + void eahd_demosaic (); void hphd_demosaic (); void vng4_demosaic (); diff --git a/rtengine/rawimagesource_i.h b/rtengine/rawimagesource_i.h index 552467c6a..c9dcfaf8e 100644 --- a/rtengine/rawimagesource_i.h +++ b/rtengine/rawimagesource_i.h @@ -76,47 +76,47 @@ inline void RawImageSource::interpolate_row_g (unsigned short* agh, unsigned sho for (int j=0; jdata[i][j]; + agv[j] = ri->data[i][j]; } else { int gh=0; int gv=0; if (j>1 && jdata[i][j-2] + 2*ri->data[i][j-1] + 2*ri->data[i][j] + 2*ri->data[i][j+1] -ri->data[i][j+2]) / 4; + int maxgh = MAX(ri->data[i][j-1], ri->data[i][j+1]); + int mingh = MIN(ri->data[i][j-1], ri->data[i][j+1]); if (gh>maxgh) gh = maxgh; else if (ghdata[i][1]; else if (j==1) - gh = (rawData[i][0] + rawData[i][2]) / 2; + gh = (ri->data[i][0] + ri->data[i][2]) / 2; else if (j==W-1) - gh = rawData[i][W-2]; + gh = ri->data[i][W-2]; else if (j==W-2) - gh = (rawData[i][W-1] + rawData[i][W-3]) / 2; + gh = (ri->data[i][W-1] + ri->data[i][W-3]) / 2; if (i>1 && idata[i-2][j] + 2*ri->data[i-1][j] + 2*ri->data[i][j] + 2*ri->data[i+1][j] - ri->data[i+2][j]) / 4; + int maxgv = MAX(ri->data[i-1][j], ri->data[i+1][j]); + int mingv = MIN(ri->data[i-1][j], ri->data[i+1][j]); if (gv>maxgv) gv = maxgv; else if (gvdata[1][j]; else if (i==1) - gv = (rawData[0][j] + rawData[2][j]) / 2; + gv = (ri->data[0][j] + ri->data[2][j]) / 2; else if (i==H-1) - gv = rawData[H-2][j]; + gv = ri->data[H-2][j]; else if (i==H-2) - gv = (rawData[H-1][j] + rawData[H-3][j]) / 2; + gv = (ri->data[H-1][j] + ri->data[H-3][j]) / 2; agh[j] = CLIP(gh); agv[j] = CLIP(gv); @@ -130,24 +130,24 @@ inline void RawImageSource::interpolate_row_rb (unsigned short* ar, unsigned sho for (int j=0; jdata[i][j]; // blue: cross interpolation int b = 0; int n = 0; if (i>0 && j>0) { - b += rawData[i-1][j-1] - pg[j-1]; + b += ri->data[i-1][j-1] - pg[j-1]; n++; } if (i>0 && jdata[i-1][j+1] - pg[j+1]; n++; } if (i0) { - b += rawData[i+1][j-1] - ng[j-1]; + b += ri->data[i+1][j-1] - ng[j-1]; n++; } if (idata[i+1][j+1] - ng[j+1]; n++; } b = cg[j] + b / n; @@ -157,20 +157,20 @@ inline void RawImageSource::interpolate_row_rb (unsigned short* ar, unsigned sho // linear R-G interp. horizontally int r; if (j==0) - r = cg[0] + rawData[i][1] - cg[1]; + r = cg[0] + ri->data[i][1] - cg[1]; else if (j==W-1) - r = cg[W-1] + rawData[i][W-2] - cg[W-2]; + r = cg[W-1] + ri->data[i][W-2] - cg[W-2]; else - r = cg[j] + (rawData[i][j-1] - cg[j-1] + rawData[i][j+1] - cg[j+1]) / 2; + r = cg[j] + (ri->data[i][j-1] - cg[j-1] + ri->data[i][j+1] - cg[j+1]) / 2; ar[j] = CLIP(r); // linear B-G interp. vertically int b; if (i==0) - b = ng[j] + rawData[1][j] - cg[j]; + b = ng[j] + ri->data[1][j] - cg[j]; else if (i==H-1) - b = pg[j] + rawData[H-2][j] - cg[j]; + b = pg[j] + ri->data[H-2][j] - cg[j]; else - b = cg[j] + (rawData[i-1][j] - pg[j] + rawData[i+1][j] - ng[j]) / 2; + b = cg[j] + (ri->data[i-1][j] - pg[j] + ri->data[i+1][j] - ng[j]) / 2; ab[j] = CLIP(b); } } @@ -180,24 +180,24 @@ inline void RawImageSource::interpolate_row_rb (unsigned short* ar, unsigned sho for (int j=0; jdata[i][j]; // blue: cross interpolation int r = 0; int n = 0; if (i>0 && j>0) { - r += rawData[i-1][j-1] - pg[j-1]; + r += ri->data[i-1][j-1] - pg[j-1]; n++; } if (i>0 && jdata[i-1][j+1] - pg[j+1]; n++; } if (i0) { - r += rawData[i+1][j-1] - ng[j-1]; + r += ri->data[i+1][j-1] - ng[j-1]; n++; } if (idata[i+1][j+1] - ng[j+1]; n++; } r = cg[j] + r / n; @@ -208,20 +208,20 @@ inline void RawImageSource::interpolate_row_rb (unsigned short* ar, unsigned sho // linear B-G interp. horizontally int b; if (j==0) - b = cg[0] + rawData[i][1] - cg[1]; + b = cg[0] + ri->data[i][1] - cg[1]; else if (j==W-1) - b = cg[W-1] + rawData[i][W-2] - cg[W-2]; + b = cg[W-1] + ri->data[i][W-2] - cg[W-2]; else - b = cg[j] + (rawData[i][j-1] - cg[j-1] + rawData[i][j+1] - cg[j+1]) / 2; + b = cg[j] + (ri->data[i][j-1] - cg[j-1] + ri->data[i][j+1] - cg[j+1]) / 2; ab[j] = CLIP(b); // linear R-G interp. vertically int r; if (i==0) - r = ng[j] + rawData[1][j] - cg[j]; + r = ng[j] + ri->data[1][j] - cg[j]; else if (i==H-1) - r = pg[j] + rawData[H-2][j] - cg[j]; + r = pg[j] + ri->data[H-2][j] - cg[j]; else - r = cg[j] + (rawData[i-1][j] - pg[j] + rawData[i+1][j] - ng[j]) / 2; + r = cg[j] + (ri->data[i-1][j] - pg[j] + ri->data[i+1][j] - ng[j]) / 2; ar[j] = CLIP(r); } } @@ -235,24 +235,24 @@ inline void RawImageSource::interpolate_row_rb_mul_pp (unsigned short* ar, unsig for (int j=x1, jx=0; jxdata[i][j]); // blue: cross interpolation int b = 0; int n = 0; if (i>0 && j>0) { - b += b_mul*rawData[i-1][j-1] - g_mul*pg[j-1]; + b += b_mul*ri->data[i-1][j-1] - g_mul*pg[j-1]; n++; } if (i>0 && jdata[i-1][j+1] - g_mul*pg[j+1]; n++; } if (i0) { - b += b_mul*rawData[i+1][j-1] - g_mul*ng[j-1]; + b += b_mul*ri->data[i+1][j-1] - g_mul*ng[j-1]; n++; } if (idata[i+1][j+1] - g_mul*ng[j+1]; n++; } b = g_mul*cg[j] + b / n; @@ -262,20 +262,20 @@ inline void RawImageSource::interpolate_row_rb_mul_pp (unsigned short* ar, unsig // linear R-G interp. horizontally int r; if (j==0) - r = g_mul*cg[0] + r_mul*rawData[i][1] - g_mul*cg[1]; + r = g_mul*cg[0] + r_mul*ri->data[i][1] - g_mul*cg[1]; else if (j==W-1) - r = g_mul*cg[W-1] + r_mul*rawData[i][W-2] - g_mul*cg[W-2]; + r = g_mul*cg[W-1] + r_mul*ri->data[i][W-2] - g_mul*cg[W-2]; else - r = g_mul*cg[j] + (r_mul*rawData[i][j-1] - g_mul*cg[j-1] + r_mul*rawData[i][j+1] - g_mul*cg[j+1]) / 2; + r = g_mul*cg[j] + (r_mul*ri->data[i][j-1] - g_mul*cg[j-1] + r_mul*ri->data[i][j+1] - g_mul*cg[j+1]) / 2; ar[jx] = CLIP(r); // linear B-G interp. vertically int b; if (i==0) - b = g_mul*ng[j] + b_mul*rawData[1][j] - g_mul*cg[j]; + b = g_mul*ng[j] + b_mul*ri->data[1][j] - g_mul*cg[j]; else if (i==H-1) - b = g_mul*pg[j] + b_mul*rawData[H-2][j] - g_mul*cg[j]; + b = g_mul*pg[j] + b_mul*ri->data[H-2][j] - g_mul*cg[j]; else - b = g_mul*cg[j] + (b_mul*rawData[i-1][j] - g_mul*pg[j] + b_mul*rawData[i+1][j] - g_mul*ng[j]) / 2; + b = g_mul*cg[j] + (b_mul*ri->data[i-1][j] - g_mul*pg[j] + b_mul*ri->data[i+1][j] - g_mul*ng[j]) / 2; ab[jx] = CLIP(b); } } @@ -285,24 +285,24 @@ inline void RawImageSource::interpolate_row_rb_mul_pp (unsigned short* ar, unsig for (int j=x1, jx=0; jxdata[i][j]); // blue: cross interpolation int r = 0; int n = 0; if (i>0 && j>0) { - r += r_mul*rawData[i-1][j-1] - g_mul*pg[j-1]; + r += r_mul*ri->data[i-1][j-1] - g_mul*pg[j-1]; n++; } if (i>0 && jdata[i-1][j+1] - g_mul*pg[j+1]; n++; } if (i0) { - r += r_mul*rawData[i+1][j-1] - g_mul*ng[j-1]; + r += r_mul*ri->data[i+1][j-1] - g_mul*ng[j-1]; n++; } if (idata[i+1][j+1] - g_mul*ng[j+1]; n++; } r = g_mul*cg[j] + r / n; @@ -313,20 +313,20 @@ inline void RawImageSource::interpolate_row_rb_mul_pp (unsigned short* ar, unsig // linear B-G interp. horizontally int b; if (j==0) - b = g_mul*cg[0] + b_mul*rawData[i][1] - g_mul*cg[1]; + b = g_mul*cg[0] + b_mul*ri->data[i][1] - g_mul*cg[1]; else if (j==W-1) - b = g_mul*cg[W-1] + b_mul*rawData[i][W-2] - g_mul*cg[W-2]; + b = g_mul*cg[W-1] + b_mul*ri->data[i][W-2] - g_mul*cg[W-2]; else - b = g_mul*cg[j] + (b_mul*rawData[i][j-1] - g_mul*cg[j-1] + b_mul*rawData[i][j+1] - g_mul*cg[j+1]) / 2; + b = g_mul*cg[j] + (b_mul*ri->data[i][j-1] - g_mul*cg[j-1] + b_mul*ri->data[i][j+1] - g_mul*cg[j+1]) / 2; ab[jx] = CLIP(b); // linear R-G interp. vertically int r; if (i==0) - r = g_mul*ng[j] + r_mul*rawData[1][j] - g_mul*cg[j]; + r = g_mul*ng[j] + r_mul*ri->data[1][j] - g_mul*cg[j]; else if (i==H-1) - r = g_mul*pg[j] + r_mul*rawData[H-2][j] - g_mul*cg[j]; + r = g_mul*pg[j] + r_mul*ri->data[H-2][j] - g_mul*cg[j]; else - r = g_mul*cg[j] + (r_mul*rawData[i-1][j] - g_mul*pg[j] + r_mul*rawData[i+1][j] - g_mul*ng[j]) / 2; + r = g_mul*cg[j] + (r_mul*ri->data[i-1][j] - g_mul*pg[j] + r_mul*ri->data[i+1][j] - g_mul*ng[j]) / 2; ar[jx] = CLIP(r); } } diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 56dc140ca..a27ae2bb7 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -17,9 +17,8 @@ * along with RawTherapee. If not, see . */ #include -#include -int refreshmap[rtengine::NUMOFEVENTS] = { +int refreshmap[] = { ALL, // EvPhotoLoaded, ALL, // EvProfileLoaded, ALL, // EvProfileChanged, @@ -105,8 +104,6 @@ ALL, // EvProfileChangeNotification RETINEX, // EvShrHighQuality TRANSFORM, // EvPerspCorr EQUALIZER, // EvEqualizer -EQUALIZER, // EvEqlEnabled -DEMOSAIC, // EvDemosaic -DARKFRAME //EvPreProcess +EQUALIZER // EvEqlEnabled }; diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h index 530b02d1b..962bbcf59 100644 --- a/rtengine/refreshmap.h +++ b/rtengine/refreshmap.h @@ -21,7 +21,6 @@ #include - #define FIRST 65535 #define ALL 65535 #define TRANSFORM 127 @@ -32,8 +31,6 @@ #define SHARPENING 2 #define LUMADENOISE 2 #define WHITEBALANCE 255 -#define DEMOSAIC 511 -#define DARKFRAME 1023 #define COLORBOOST 1 #define COLORDENOISE 1 #define CROP 16384 @@ -42,8 +39,6 @@ #define EQUALIZER 3 #define NONE 0 -#define M_PREPROC 512 -#define M_RAW 256 #define M_INIT 128 #define M_TRANSFORM 64 #define M_BLURMAP 32 diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 860d5c206..71ff9a3a1 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -113,6 +113,7 @@ namespace rtengine { /** * This class represents an image loaded into the memory. It is the basis of further processing. + * In case of raw files the most time consuming operation, the demosaicing is already performed. * The embedded icc profile and metadata information can be obtained through this class, too. */ class InitialImage { @@ -136,7 +137,7 @@ namespace rtengine { virtual void decreaseRef () {} - /** Loads an image into the memory. + /** Loads an image into the memory. If it is a raw file, is is partially demosaiced (the time consuming part is done) * @param fname the name of the file * @param isRaw shall be true if it is a raw file * @param errorCode is a pointer to a variable that is set to nonzero if an error happened (output) diff --git a/rtengine/settings.h b/rtengine/settings.h index fac2557ca..fe2fc8380 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -25,11 +25,18 @@ namespace rtengine { class Settings { public: bool dualThreadEnabled; ///< If true, the image processing operations with utilize two processor cores (if possible) + std::string demosaicMethod; ///< The algorithm used for demosaicing. Can be "eahd", "hphd" or "vng4". + int colorCorrectionSteps; ///< The number of color correction steps applied right after the demosaicing Glib::ustring iccDirectory; ///< The directory containing the possible output icc profiles int colorimetricIntent; ///< Colorimetric intent used at color space conversions Glib::ustring monitorProfile; ///< ICC profile of the monitor (full path recommended) bool verbose; - Glib::ustring darkFramesPath; ///< The default directory for dark frames + int dcb_iterations; // number of dcb iterations + bool dcb_enhance; // whether to do image refinment + bool ca_autocorrect; // Emil's CA auto correction + bool hotdeadpix_filt; // Emil's hot/dead pixel filter + int linenoise; //Emil's line denoise + int greenthresh; //Emil's Green equilibration /** Creates a new instance of Settings. * @return a pointer to the new Settings instance. */ diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 4395c2c2f..b64238e3b 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -75,15 +75,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p Image16* baseImg; PreviewProps pp (0, 0, fw, fh, 1); - imgsrc->preprocess( params.raw ); - imgsrc->demosaic( params.raw ); if (fabs(params.resize.scale-1.0)<1e-5) { baseImg = new Image16 (fw, fh); - imgsrc->getImage (currWB, tr, baseImg, pp, params.hlrecovery, params.icm, params.raw); + imgsrc->getImage (currWB, tr, baseImg, pp, params.hlrecovery, params.icm); } else { Image16* oorig = new Image16 (fw, fh); - imgsrc->getImage (currWB, tr, oorig, pp, params.hlrecovery, params.icm, params.raw); + imgsrc->getImage (currWB, tr, oorig, pp, params.hlrecovery, params.icm); fw *= params.resize.scale; fh *= params.resize.scale; baseImg = new Image16 (fw, fh); diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 32bdca1b1..beb547684 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -223,7 +223,7 @@ void StdImageSource::getImage_ (ColorTemp ctemp, int tran, Image16* image, Previ delete [] blue; } -void StdImageSource::getImage (ColorTemp ctemp, int tran, Image16* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp, RAWParams raw) { +void StdImageSource::getImage (ColorTemp ctemp, int tran, Image16* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp) { MyTime t1,t2; diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index 811d063ae..8565c5670 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -44,7 +44,7 @@ class StdImageSource : public ImageSource { ~StdImageSource (); int load (Glib::ustring fname); - void getImage (ColorTemp ctemp, int tran, Image16* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp, RAWParams raw); + void getImage (ColorTemp ctemp, int tran, Image16* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp); ColorTemp getWB () { return wb; } ColorTemp getAutoWB (); ColorTemp getSpotWB (std::vector red, std::vector green, std::vector& blue, int tran); diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index c977dc8d4..5a96dfceb 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -23,7 +23,7 @@ set (BASESOURCEFILES thumbbrowserentrybase.cc batchqueueentry.cc batchqueue.cc lwbutton.cc lwbuttonset.cc batchqueuebuttonset.cc browserfilter.cc exiffiltersettings.cc - profilestore.cc partialpastedlg.cc rawprocess.cc preprocess.cc + profilestore.cc partialpastedlg.cc equalizer.cc) if (WIN32) diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 5bc0f331f..e2717a69a 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -24,8 +24,6 @@ #include #include -extern Options options; - FileBrowser::FileBrowser () : tbl(NULL) { @@ -58,10 +56,6 @@ FileBrowser::FileBrowser () pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; pmenu->attach (*(selall = new Gtk::MenuItem (M("FILEBROWSER_POPUPSELECTALL"))), 0, 1, p, p+1); p++; pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; - pmenu->attach (*(selectDF = new Gtk::MenuItem ("Select Dark Frame...")), 0, 1, p, p+1); p++; - pmenu->attach (*(autoDF = new Gtk::MenuItem ("Auto Dark Frame")), 0, 1, p, p+1); p++; - pmenu->attach (*(thisIsDF = new Gtk::MenuItem ("This is a Dark Frame")), 0, 1, p, p+1); p++; - pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; pmenu->attach (*(copyprof = new Gtk::MenuItem (M("FILEBROWSER_COPYPROFILE"))), 0, 1, p, p+1); p++; pmenu->attach (*(pasteprof = new Gtk::MenuItem (M("FILEBROWSER_PASTEPROFILE"))), 0, 1, p, p+1); p++; pmenu->attach (*(partpasteprof = new Gtk::MenuItem (M("FILEBROWSER_PARTIALPASTEPROFILE"))), 0, 1, p, p+1); p++; @@ -89,9 +83,7 @@ FileBrowser::FileBrowser () develop->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), develop)); rename->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), rename)); remove->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), remove)); - selall->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), selall)); - selectDF->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), selectDF)); - autoDF->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), autoDF)); + selall->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), selall)); copyprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), copyprof)); pasteprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), pasteprof)); partpasteprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), partpasteprof)); @@ -296,33 +288,7 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) { queue_draw (); notifySelectionListener (); } - else if (m==autoDF){ - for (int i=0; ithumbnail->getProcParams(); - pp.raw.df_autoselect= true; - pp.raw.dark_frame.clear(); - mselected[i]->thumbnail->setProcParams(pp,FILEBROWSER,false); - } - }else if (m==selectDF){ - if( mselected.size() > 0 ){ - rtengine::procparams::ProcParams pp=mselected[0]->thumbnail->getProcParams(); - Gtk::FileChooserDialog fc("Dark Frame",Gtk::FILE_CHOOSER_ACTION_OPEN ); - fc.add_button( Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); - fc.add_button( Gtk::StockID("gtk-apply"), Gtk::RESPONSE_APPLY); - if( pp.raw.dark_frame.empty()) - fc.set_current_folder( options.rtSettings.darkFramesPath ); - else - fc.set_filename( pp.raw.dark_frame ); - if( fc.run() == Gtk::RESPONSE_APPLY ){ - for (int i=0; ithumbnail->getProcParams(); - pp.raw.dark_frame= fc.get_filename(); - pp.raw.df_autoselect= false; - mselected[i]->thumbnail->setProcParams(pp,FILEBROWSER,false); - } - } - } - }else if (m==copyprof) + else if (m==copyprof) copyProfile (); else if (m==pasteprof) pasteProfile (); diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h index 822039293..bfe22f934 100644 --- a/rtgui/filebrowser.h +++ b/rtgui/filebrowser.h @@ -58,9 +58,6 @@ class FileBrowser : public ThumbBrowserBase, public LWButtonListener { Gtk::MenuItem* remove; Gtk::MenuItem* open; Gtk::MenuItem* selall; - Gtk::MenuItem* selectDF; - Gtk::MenuItem* thisIsDF; - Gtk::MenuItem* autoDF; Gtk::MenuItem* copyprof; Gtk::MenuItem* pasteprof; Gtk::MenuItem* partpasteprof; diff --git a/rtgui/options.cc b/rtgui/options.cc index 0d6f6188a..a56bdef83 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -119,7 +119,16 @@ void Options::setDefaults () { baBehav = std::vector (babehav, babehav+ADDSET_PARAM_NUM); rtSettings.dualThreadEnabled = true; - rtSettings.darkFramesPath = ""; + rtSettings.demosaicMethod = "amaze";//Emil's code for AMaZE + rtSettings.ca_autocorrect = false;//Emil's CA correction + rtSettings.hotdeadpix_filt = true;//Emil's hot/dead pixel filter + + rtSettings.linenoise = 0;//Emil's line denoise + rtSettings.greenthresh = 0;//Emil's Green equilibration + + rtSettings.colorCorrectionSteps = 0; + rtSettings.dcb_iterations = 2; + rtSettings.dcb_enhance = true; rtSettings.iccDirectory = "/usr/share/color/icc"; rtSettings.colorimetricIntent = 1; rtSettings.monitorProfile = ""; @@ -169,8 +178,6 @@ if (keyFile.has_group ("General")) { if (keyFile.has_key ("General", "Language")) language = keyFile.get_string ("General", "Language"); if (keyFile.has_key ("General", "Theme")) theme = keyFile.get_string ("General", "Theme"); if (keyFile.has_key ("General", "FirstRun")) firstRun = keyFile.get_boolean ("General", "FirstRun"); - if( keyFile.has_key ("General", "DarkFramesPath")) rtSettings.darkFramesPath = keyFile.get_string("General", "DarkFramesPath"); - if( keyFile.has_key ("General", "Verbose")) rtSettings.verbose = keyFile.get_boolean ( "General", "Verbose"); } if (keyFile.has_group ("External Editor")) { @@ -255,7 +262,16 @@ if (keyFile.has_group ("GUI")) { if (keyFile.has_key ("GUI", "CurvePanelsExpanded")) crvOpen = keyFile.get_integer_list ("GUI", "CurvePanelsExpanded"); } - +if (keyFile.has_group ("Algorithms")) { + if (keyFile.has_key ("Algorithms", "DemosaicMethod")) rtSettings.demosaicMethod = keyFile.get_string ("Algorithms", "DemosaicMethod"); + if (keyFile.has_key ("Algorithms", "ColorCorrection")) rtSettings.colorCorrectionSteps = keyFile.get_integer ("Algorithms", "ColorCorrection"); + if(keyFile.has_key("Algorithms", "DCBIterations")) rtSettings.dcb_iterations = keyFile.get_integer("Algorithms", "DCBIterations"); + if(keyFile.has_key("Algorithms", "DCBEnhance")) rtSettings.dcb_enhance = keyFile.get_boolean("Algorithms", "DCBEnhance"); + if(keyFile.has_key("Algorithms", "CACorrect")) rtSettings.ca_autocorrect = keyFile.get_boolean("Algorithms", "CACorrect");//Emil's CA autocorrect + if(keyFile.has_key("Algorithms", "HotDeadPixFilt")) rtSettings.hotdeadpix_filt = keyFile.get_boolean("Algorithms", "HotDeadPixFilt");//Emil's hot/dead pixel filter + if(keyFile.has_key("Algorithms", "LineDenoise")) rtSettings.linenoise = keyFile.get_integer("Algorithms", "LineDenoise");//Emil's line denoise + if(keyFile.has_key("Algorithms", "GreenEquil")) rtSettings.greenthresh = keyFile.get_integer("Algorithms", "GreenEquil");//Emil's Green equilibration +} if (keyFile.has_group ("Crop Settings")) { if (keyFile.has_key ("Crop Settings", "DPI")) cropDPI = keyFile.get_integer ("Crop Settings", "DPI"); @@ -296,7 +312,6 @@ int Options::saveToFile (Glib::ustring fname) { keyFile.set_string ("General", "Theme", theme); keyFile.set_integer ("General", "Version", 290); keyFile.set_boolean ("General", "FirstRun", firstRun); - keyFile.set_string ("General", "DarkFramesPath", rtSettings.darkFramesPath); keyFile.set_integer ("External Editor", "EditorKind", editorToSendTo); keyFile.set_string ("External Editor", "GimpDir", gimpDir); @@ -375,6 +390,15 @@ int Options::saveToFile (Glib::ustring fname) { Glib::ArrayHandle crvopen = crvOpen; keyFile.set_integer_list ("GUI", "CurvePanelsExpanded", crvopen); + keyFile.set_string ("Algorithms", "DemosaicMethod", rtSettings.demosaicMethod); + keyFile.set_integer ("Algorithms", "ColorCorrection", rtSettings.colorCorrectionSteps); + keyFile.set_integer ("Algorithms", "DCBIterations", rtSettings.dcb_iterations); + keyFile.set_boolean ("Algorithms", "DCBEnhance", rtSettings.dcb_enhance); + keyFile.set_boolean ("Algorithms", "CACorrect", rtSettings.ca_autocorrect);//Emil's CA correction + keyFile.set_boolean ("Algorithms", "HotDeadPixFilt", rtSettings.hotdeadpix_filt);//Emil's hot/dead pixel filter + keyFile.set_integer ("Algorithms", "LineDenoise", rtSettings.linenoise);//Emil's line denoise + keyFile.set_integer ("Algorithms", "GreenEquil", rtSettings.greenthresh);//Emil's Green equilibration + keyFile.set_integer ("Crop Settings", "DPI", cropDPI); keyFile.set_string ("Color Management", "ICCDirectory", rtSettings.iccDirectory); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index e6a4858d2..a0ca51c38 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -119,10 +119,6 @@ void ParamsEdited::set (bool v) { icm.gammaOnInput = v; icm.working = v; icm.output = v; - raw.ccSteps = v; - raw.dmethod = v; - raw.dcbIterations = v; - raw.dcbEnhance = v; equalizer.enabled = v; for(int i = 0; i < 8; i++) { @@ -235,17 +231,6 @@ void ParamsEdited::initFrom (const std::vector icm.gammaOnInput = icm.gammaOnInput && p.icm.gammaOnInput == other.icm.gammaOnInput; icm.working = icm.working && p.icm.working == other.icm.working; icm.output = icm.output && p.icm.output == other.icm.output; - raw.ccSteps = raw.ccSteps && p.raw.ccSteps == other.raw.ccSteps; - raw.dcbEnhance = raw.dcbEnhance && p.raw.dcb_enhance == other.raw.dcb_enhance; - raw.dcbIterations = raw.dcbIterations && p.raw.dcb_iterations == other.raw.dcb_iterations; - raw.dmethod = raw.dmethod && p.raw.dmethod == other.raw.dmethod; - raw.caCorrection = raw.caCorrection && p.raw.ca_autocorrect == other.raw.ca_autocorrect; - raw.darkFrame = raw.darkFrame && p.raw.dark_frame == other.raw.dark_frame; - raw.dfAuto = raw.dfAuto && p.raw.df_autoselect == other.raw.df_autoselect; - raw.greenEq = raw.greenEq && p.raw.greenthresh == other.raw.greenthresh; - raw.hotDeadPixel = raw.hotDeadPixel && p.raw.hotdeadpix_filt == other.raw.hotdeadpix_filt; - raw.linenoise = raw.linenoise && p.raw.linenoise == other.raw.linenoise; - equalizer.enabled = equalizer.enabled && p.equalizer.enabled == other.equalizer.enabled; for(int i = 0; i < 8; i++) { equalizer.c[i] = equalizer.c[i] && p.equalizer.c[i] == other.equalizer.c[i]; @@ -348,16 +333,6 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (icm.gammaOnInput) toEdit.icm.gammaOnInput = mods.icm.gammaOnInput; if (icm.working) toEdit.icm.working = mods.icm.working; if (icm.output) toEdit.icm.output = mods.icm.output; - if (raw.ccSteps) toEdit.raw.ccSteps = mods.raw.ccSteps; - if (raw.dmethod) toEdit.raw.dmethod = mods.raw.dmethod; - if (raw.dcbIterations) toEdit.raw.dcb_iterations = mods.raw.dcb_iterations; - if (raw.dcbEnhance) toEdit.raw.dcb_enhance = mods.raw.dcb_enhance; - if (raw.caCorrection) toEdit.raw.ca_autocorrect = mods.raw.ca_autocorrect; - if (raw.greenEq) toEdit.raw.greenthresh = mods.raw.greenthresh; - if (raw.hotDeadPixel) toEdit.raw.hotdeadpix_filt= mods.raw.hotdeadpix_filt; - if (raw.linenoise) toEdit.raw.linenoise = mods.raw.linenoise; - if (raw.darkFrame) toEdit.raw.dark_frame = mods.raw.dark_frame; - if (raw.dfAuto) toEdit.raw.df_autoselect= mods.raw.df_autoselect; if (equalizer.enabled) toEdit.equalizer.enabled = mods.equalizer.enabled; for(int i = 0; i < 8; i++) { if(equalizer.c[i]) toEdit.equalizer.c[i] = mods.equalizer.c[i]; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 4feb33b28..c8dd43085 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -222,21 +222,6 @@ class EqualizerParamsEdited { bool c[8]; }; -class RAWParamsEdited { - - public: - bool ccSteps; - bool dmethod; - bool dcbIterations; - bool dcbEnhance; - bool caCorrection; - bool greenEq; - bool hotDeadPixel; - bool linenoise; - bool darkFrame; - bool dfAuto; -}; - class ExifPairEdited { public: @@ -276,7 +261,6 @@ class ParamsEdited { ResizeParamsEdited resize; ColorManagementParamsEdited icm; EqualizerParamsEdited equalizer; - RAWParamsEdited raw; std::vector exif; std::vector iptc; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index e63f5b1a5..166107801 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -22,8 +22,6 @@ #include #include #include -#include -#include extern Options options; extern Glib::ustring argv0; @@ -253,19 +251,81 @@ Gtk::Widget* Preferences::getProcParamsPanel () { fdp->add (*vbdp); mvbpp->pack_start (*fdp, Gtk::PACK_SHRINK, 4); - Gtk::Frame* fdf = Gtk::manage (new Gtk::Frame ("Dark Frame") ); - Gtk::HBox* hb42 = Gtk::manage (new Gtk::HBox ()); - darkFrameDir = Gtk::manage(new Gtk::FileChooserButton( "Dark frames directory", Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); - Gtk::Label *dfLab = Gtk::manage(new Gtk::Label("Dark Frames directory")); - hb42->pack_start(*dfLab , Gtk::PACK_SHRINK, 4 ); - hb42->pack_start(*darkFrameDir); - dfLabel = Gtk::manage(new Gtk::Label("Found:")); - Gtk::VBox* vbdf = Gtk::manage (new Gtk::VBox ()); - vbdf->pack_start( *hb42, Gtk::PACK_SHRINK, 4); - vbdf->pack_start( *dfLabel, Gtk::PACK_SHRINK, 4 ); - fdf->add( *vbdf ); - mvbpp->pack_start ( *fdf , Gtk::PACK_SHRINK, 4); + Gtk::Frame* fdem = Gtk::manage (new Gtk::Frame (M("PREFERENCES_DEMOSAICINGALGO"))); + Gtk::VBox* fdb = Gtk::manage (new Gtk::VBox ()); + fdb->set_border_width (4); + fdem->add (*fdb); + Gtk::Label* dmlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_DMETHOD")+":")); + dmethod = Gtk::manage (new Gtk::ComboBoxText ()); + Gtk::HBox* hb11 = Gtk::manage (new Gtk::HBox ()); + hb11->pack_start (*dmlab, Gtk::PACK_SHRINK, 4); + hb11->pack_start (*dmethod); + dmethod->append_text ("EAHD"); + dmethod->append_text ("HPHD"); + dmethod->append_text ("VNG-4"); + //dmethod->append_text ("PPG"); + dmethod->append_text ("AMaZE");//Emil's code for AMaZE + dmethod->append_text ("DCB"); + dmethod->append_text ("AHD"); + Gtk::Label* cclab = Gtk::manage (new Gtk::Label (M("PREFERENCES_FALSECOLOR")+":")); + ccSteps = Gtk::manage (new Gtk::SpinButton ()); + ccSteps->set_digits (0); + ccSteps->set_increments (1, 2); + ccSteps->set_range (0, 5); + Gtk::HBox* hb12 = Gtk::manage (new Gtk::HBox ()); + hb12->pack_start (*cclab, Gtk::PACK_SHRINK, 4); + hb12->pack_start (*ccSteps); + + dcbIterationsLabel = Gtk::manage(new Gtk::Label(M("PREFERENCES_DCBITERATIONS")+":")); + dcbIterations = Gtk::manage(new Gtk::SpinButton ()); + dcbIterations->set_digits(0); + dcbIterations->set_increments(1, 2); + dcbIterations->set_range(0, 10); + Gtk::HBox* hb13 = Gtk::manage(new Gtk::HBox()); + hb13->pack_start (*dcbIterationsLabel, Gtk::PACK_SHRINK, 4); + hb13->pack_start (*dcbIterations); + + dcbEnhance = Gtk::manage(new Gtk::CheckButton((M("PREFERENCES_DCBENHANCE")))); + + caAutoCorrect = Gtk::manage(new Gtk::CheckButton((M("PREFERENCES_CACORRECTION"))));//Emil's CA correction + HotDeadPixFilt = Gtk::manage(new Gtk::CheckButton((M("PREFERENCES_HOTDEADPIXFILT"))));//Emil's hot/dead pixel filter + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //Emil's line denoise + LineDenoiseLabel = Gtk::manage(new Gtk::Label(M("PREFERENCES_LINEDENOISE")+":")); + LineDenoise = Gtk::manage(new Gtk::SpinButton ()); + LineDenoise->set_digits(0); + LineDenoise->set_increments(1, 10); + LineDenoise->set_range(0, 1000); + Gtk::HBox* hb14 = Gtk::manage(new Gtk::HBox()); + hb14->pack_start (*LineDenoiseLabel, Gtk::PACK_SHRINK, 4); + hb14->pack_start (*LineDenoise); + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //Emil's Green equilibration + GreenEquilLabel = Gtk::manage(new Gtk::Label(M("PREFERENCES_GREENEQUIL")+":")); + GreenEquil = Gtk::manage(new Gtk::SpinButton ()); + GreenEquil->set_digits(0); + GreenEquil->set_increments(1, 10); + GreenEquil->set_range(0, 100); + Gtk::HBox* hb15 = Gtk::manage(new Gtk::HBox()); + hb15->pack_start (*GreenEquilLabel, Gtk::PACK_SHRINK, 4); + hb15->pack_start (*GreenEquil); + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + fdb->pack_start (*hb11, Gtk::PACK_SHRINK, 4); + fdb->pack_start (*hb12, Gtk::PACK_SHRINK, 4); + fdb->pack_start (*hb13, Gtk::PACK_SHRINK, 4); + fdb->pack_start (*dcbEnhance, Gtk::PACK_SHRINK, 4); + fdb->pack_start (*caAutoCorrect, Gtk::PACK_SHRINK, 4);//Emil's CA correction + fdb->pack_start (*HotDeadPixFilt, Gtk::PACK_SHRINK, 4);//Emil's hot/dead pixel filter + fdb->pack_start (*hb14, Gtk::PACK_SHRINK, 4);//Emil's line denoise + fdb->pack_start (*hb15, Gtk::PACK_SHRINK, 4);//Emil's Green equlibration + + mvbpp->pack_start (*fdem, Gtk::PACK_SHRINK, 4); mvbpp->set_border_width (4); + // drlab->set_size_request (drimg->get_width(), -1); std::vector pnames; if (options.multiUser) @@ -276,7 +336,7 @@ Gtk::Widget* Preferences::getProcParamsPanel () { iprofiles->append_text (pnames[i]); } - dfconn = darkFrameDir->signal_file_set().connect ( sigc::mem_fun(*this, &Preferences::darkFrameChanged), true); + dmconn = dmethod->signal_changed().connect( sigc::mem_fun(*this, &Preferences::dmethodChanged) ); return mvbpp; } @@ -670,9 +730,31 @@ void Preferences::storePreferences () { moptions.editorToSendTo = 3; + moptions.rtSettings.colorCorrectionSteps= (int)ccSteps->get_value (); moptions.rtSettings.monitorProfile = monProfile->get_filename (); moptions.rtSettings.iccDirectory = iccDir->get_filename (); moptions.rtSettings.colorimetricIntent = intent->get_active_row_number (); + if (dmethod->get_active_row_number()==0) + moptions.rtSettings.demosaicMethod = "eahd"; + else if (dmethod->get_active_row_number()==1) + moptions.rtSettings.demosaicMethod = "hphd"; + else if (dmethod->get_active_row_number()==2) + moptions.rtSettings.demosaicMethod = "vng4"; + //else if (dmethod->get_active_row_number()==3) + // moptions.rtSettings.demosaicMethod = "ppg"; + else if (dmethod->get_active_row_number()==3) + moptions.rtSettings.demosaicMethod = "amaze";//Emil's code for AMaZE + else if (dmethod->get_active_row_number()==4) + moptions.rtSettings.demosaicMethod = "dcb"; + else if (dmethod->get_active_row_number()==5) + moptions.rtSettings.demosaicMethod = "ahd"; + moptions.rtSettings.dcb_iterations=(int)dcbIterations->get_value(); + moptions.rtSettings.dcb_enhance=dcbEnhance->get_active(); + moptions.rtSettings.ca_autocorrect=caAutoCorrect->get_active();//Emil's CA correction + moptions.rtSettings.hotdeadpix_filt=HotDeadPixFilt->get_active();//Emil's hot/dead pixel filter + moptions.rtSettings.linenoise=(int)LineDenoise->get_value();//Emil's line denoise + moptions.rtSettings.greenthresh=(int)GreenEquil->get_value();//Emil's Green equilibration + if (sdcurrent->get_active ()) moptions.startupDir = STARTUPDIR_CURRENT; @@ -708,8 +790,6 @@ void Preferences::storePreferences () { moptions.saveParamsCache = saveParamsCache->get_active (); moptions.paramsLoadLocation = (PPLoadLocation)loadParamsPreference->get_active_row_number (); - moptions.rtSettings.darkFramesPath = darkFrameDir->get_filename(); - int i = 0; moptions.baBehav.resize (ADDSET_PARAM_NUM); for (Gtk::TreeIter sections=behModel->children().begin(); sections!=behModel->children().end(); sections++) @@ -719,12 +799,13 @@ void Preferences::storePreferences () { void Preferences::fillPreferences () { + dmconn.block (true); tconn.block (true); - dfconn.block (true); rprofiles->set_active_text (moptions.defProfRaw); iprofiles->set_active_text (moptions.defProfImg); dateformat->set_text (moptions.dateFormat); + ccSteps->set_value (moptions.rtSettings.colorCorrectionSteps); if (Glib::file_test (moptions.rtSettings.monitorProfile, Glib::FILE_TEST_EXISTS)) monProfile->set_filename (moptions.rtSettings.monitorProfile); if (Glib::file_test (moptions.rtSettings.iccDirectory, Glib::FILE_TEST_IS_DIR)) @@ -753,6 +834,32 @@ void Preferences::fillPreferences () { #endif editorToSendTo->set_text (moptions.customEditorProg); + if (moptions.rtSettings.demosaicMethod=="eahd") + dmethod->set_active (0); + else if (moptions.rtSettings.demosaicMethod=="hphd") + dmethod->set_active (1); + else if (moptions.rtSettings.demosaicMethod=="vng4") + dmethod->set_active (2); + //else if (moptions.rtSettings.demosaicMethod=="ppg") + // dmethod->set_active (3); + else if (moptions.rtSettings.demosaicMethod=="amaze")//Emil's code for AMaZE + dmethod->set_active (3); + else if (moptions.rtSettings.demosaicMethod=="dcb") + dmethod->set_active (4); + else if (moptions.rtSettings.demosaicMethod=="ahd") + dmethod->set_active (5); + dcbEnhance->set_active(moptions.rtSettings.dcb_enhance); + dcbIterations->set_value(moptions.rtSettings.dcb_iterations); + dcbEnhance->set_sensitive(moptions.rtSettings.demosaicMethod=="dcb"); + dcbIterations->set_sensitive(moptions.rtSettings.demosaicMethod=="dcb"); + dcbIterationsLabel->set_sensitive(moptions.rtSettings.demosaicMethod=="dcb"); + caAutoCorrect->set_active(moptions.rtSettings.ca_autocorrect);//Emil's CA Auto Correction + HotDeadPixFilt->set_active(moptions.rtSettings.hotdeadpix_filt);//Emil's hot/dead pixel filter + LineDenoise->set_value(moptions.rtSettings.linenoise);//Emil's line denoise + GreenEquil->set_value(moptions.rtSettings.greenthresh);//Emil's Green equilibration + + + if (moptions.startupDir==STARTUPDIR_CURRENT) sdcurrent->set_active (); else if (moptions.startupDir==STARTUPDIR_LAST) @@ -786,9 +893,6 @@ void Preferences::fillPreferences () { saveParamsCache->set_active (moptions.saveParamsCache); loadParamsPreference->set_active (moptions.paramsLoadLocation); - darkFrameDir->set_filename( moptions.rtSettings.darkFramesPath ); - updateDFinfos(); - addc.block (true); setc.block (true); if (moptions.baBehav.size() == ADDSET_PARAM_NUM) { @@ -803,8 +907,9 @@ void Preferences::fillPreferences () { } addc.block (false); setc.block (false); + + dmconn.block (false); tconn.block (false); - dfconn.block (false); } void Preferences::loadPressed () { @@ -847,6 +952,26 @@ void Preferences::selectStartupDir () { startupdir->set_text (dialog.get_filename()); } +void Preferences::dmethodChanged () { + + if (dmethod->get_active_row_number()==0) + ccSteps->set_value (2); + else if (dmethod->get_active_row_number()==1) + ccSteps->set_value (1); + else if (dmethod->get_active_row_number()==2) + ccSteps->set_value (2); + + if (dmethod->get_active_row_number()==4) { + dcbEnhance->set_sensitive(true); + dcbIterations->set_sensitive(true); + dcbIterationsLabel->set_sensitive(true); + } else { + dcbEnhance->set_sensitive(false); + dcbIterations->set_sensitive(false); + dcbIterationsLabel->set_sensitive(false); + } +} + void Preferences::aboutPressed () { Splash* splash = new Splash (-1); @@ -915,19 +1040,3 @@ void Preferences::clearAllPressed () { md.hide (); } -void Preferences::darkFrameChanged () -{ - Glib::ustring s(darkFrameDir->get_filename()); - if( s.compare( rtengine::dfm.getPathname()) !=0 ){ - rtengine::dfm.init( s ); - updateDFinfos(); - } -} -void Preferences::updateDFinfos() -{ - int t1,t2; - rtengine::dfm.getStat(t1,t2); - std::ostringstream s; - s << "Found: "<< t1 << " shots, " << t2 << " templates"; - dfLabel->set_text(s.str()); -} diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 83072cd78..646202017 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -52,6 +52,7 @@ class Preferences : public Gtk::Dialog { protected: Gtk::ComboBoxText* rprofiles; Gtk::ComboBoxText* iprofiles; + Gtk::ComboBoxText* dmethod; Gtk::ComboBoxText* languages; Gtk::Entry* dateformat; Gtk::Entry* startupdir; @@ -65,12 +66,22 @@ class Preferences : public Gtk::Dialog { Gtk::RadioButton* edGimp; Gtk::RadioButton* edPS; Gtk::RadioButton* edOther; - Gtk::FileChooserButton* darkFrameDir; - Gtk::Label *dfLabel; + Gtk::CheckButton* showDateTime; Gtk::CheckButton* showBasicExif; + Gtk::SpinButton* ccSteps; + Gtk::Label* dcbIterationsLabel; + Gtk::SpinButton* dcbIterations; + Gtk::CheckButton* dcbEnhance; + Gtk::CheckButton* caAutoCorrect;//Emil's CA correction + Gtk::CheckButton* HotDeadPixFilt;//Emil's hot/dead pixel filter + Gtk::Label* LineDenoiseLabel;//Emil's line denoise + Gtk::SpinButton* LineDenoise; + Gtk::Label* GreenEquilLabel;//Emil's Green equilibration + Gtk::SpinButton* GreenEquil; + Gtk::FileChooserButton* iccDir; Gtk::FileChooserButton* monProfile; @@ -99,12 +110,13 @@ class Preferences : public Gtk::Dialog { Gtk::ComboBoxText* loadParamsPreference; Options moptions; - sigc::connection tconn, addc, setc, dfconn; + sigc::connection dmconn, tconn, addc, setc; void fillPreferences (); void storePreferences (); void parseDir (Glib::ustring dirname, std::vector& items, Glib::ustring ext); - void updateDFinfos (); + void dmethodChanged (); + void themeChanged (); void appendBehavList (Gtk::TreeModel::iterator& parent, Glib::ustring label, int id, bool set); @@ -127,7 +139,7 @@ class Preferences : public Gtk::Dialog { void selectStartupDir (); void addExtPressed (); void delExtPressed (); - void darkFrameChanged (); + void clearProfilesPressed (); void clearThumbImagesPressed (); void clearAllPressed (); diff --git a/rtgui/preprocess.cc b/rtgui/preprocess.cc deleted file mode 100644 index 5d64d6362..000000000 --- a/rtgui/preprocess.cc +++ /dev/null @@ -1,220 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#include -#include -#include -using namespace rtengine; -using namespace rtengine::procparams; - -PreProcess::PreProcess () -{ - hbdf = Gtk::manage(new Gtk::HBox()); - darkFrameFile = Gtk::manage(new Gtk::FileChooserButton(M("PREFERENCES_DARKFRAME"), Gtk::FILE_CHOOSER_ACTION_OPEN)); - dfLabel = Gtk::manage(new Gtk::Label("Dark Frame")); - btnReset = Gtk::manage(new Gtk::Button()); - btnReset->set_image (*Gtk::manage(new Gtk::Image (Gtk::StockID("gtk-cancel"), Gtk::ICON_SIZE_BUTTON))); - hbdf->pack_start(*dfLabel, Gtk::PACK_SHRINK, 4); - hbdf->pack_start(*darkFrameFile); - hbdf->pack_start(*btnReset, Gtk::PACK_SHRINK, 4); - dfAuto = Gtk::manage(new Gtk::CheckButton(("Auto selection"))); - caAutocorrect = Gtk::manage(new Gtk::CheckButton((M("PREFERENCES_CACORRECTION")))); - hotDeadPixel = Gtk::manage(new Gtk::CheckButton((M("PREFERENCES_HOTDEADPIXFILT")))); - - lineDenoise = Gtk::manage(new Adjuster (M("PREFERENCES_LINEDENOISE"),0,30,1,0)); - lineDenoise->setAdjusterListener (this); - lineDenoise->show(); - - greenEqThreshold = Gtk::manage(new Adjuster (M("PREFERENCES_GREENEQUIL"),0,100,1,0)); - greenEqThreshold->setAdjusterListener (this); - greenEqThreshold->show(); - - pack_start( *hbdf, Gtk::PACK_SHRINK, 4); - pack_start( *dfAuto, Gtk::PACK_SHRINK, 4); - pack_start( *Gtk::manage (new Gtk::HSeparator())); - pack_start( *hotDeadPixel, Gtk::PACK_SHRINK, 4); - pack_start( *Gtk::manage (new Gtk::HSeparator())); - pack_start( *caAutocorrect, Gtk::PACK_SHRINK, 4); - pack_start( *Gtk::manage (new Gtk::HSeparator())); - pack_start( *lineDenoise, Gtk::PACK_SHRINK, 4); - pack_start( *Gtk::manage (new Gtk::HSeparator())); - pack_start( *greenEqThreshold, Gtk::PACK_SHRINK, 4); - - caacsconn = caAutocorrect->signal_toggled().connect ( sigc::mem_fun(*this, &PreProcess::caCorrectionChanged), true); - dfautoconn = dfAuto->signal_toggled().connect ( sigc::mem_fun(*this, &PreProcess::dfAutoChanged), true); - hdpixelconn = hotDeadPixel->signal_toggled().connect ( sigc::mem_fun(*this, &PreProcess::hotDeadPixelChanged), true); - dfFile = darkFrameFile->signal_file_set().connect ( sigc::mem_fun(*this, &PreProcess::darkFrameChanged), true); - btnReset->signal_clicked().connect( sigc::mem_fun(*this, &PreProcess::darkFrameReset), true ); -} - - -void PreProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) -{ - disableListener (); - caacsconn.block (true); - dfautoconn.block(true); - hdpixelconn.block (true); - - if(pedited ){ - dfAuto->set_inconsistent(!pedited->raw.dfAuto ); - caAutocorrect->set_inconsistent(!pedited->raw.caCorrection); - hotDeadPixel->set_inconsistent (!pedited->raw.hotDeadPixel); - lineDenoise->setEditedState( pedited->raw.linenoise ? Edited : UnEdited ); - greenEqThreshold->setEditedState( pedited->raw.greenEq ? Edited : UnEdited ); - } - - if (Glib::file_test (pp->raw.dark_frame, Glib::FILE_TEST_EXISTS)) - darkFrameFile->set_filename (pp->raw.dark_frame); - else if( !options.rtSettings.darkFramesPath.empty() ) - darkFrameFile->set_current_folder( options.rtSettings.darkFramesPath ); - - lastCA = pp->raw.ca_autocorrect; - lastHot = pp->raw.hotdeadpix_filt; - lastDFauto = pp->raw.df_autoselect; - - dfAuto->set_active( pp->raw.df_autoselect ); - caAutocorrect->set_active(pp->raw.ca_autocorrect); - hotDeadPixel->set_active (pp->raw.hotdeadpix_filt); - lineDenoise->setValue (pp->raw.linenoise); - greenEqThreshold->setValue (pp->raw.greenthresh); - - dfChanged = false; - - - caacsconn.block (false); - dfautoconn.block(false); - hdpixelconn.block (false); - - enableListener (); -} - -void PreProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) -{ - pp->raw.dark_frame = darkFrameFile->get_filename(); - pp->raw.df_autoselect = dfAuto->get_active(); - pp->raw.ca_autocorrect = caAutocorrect->get_active(); - pp->raw.hotdeadpix_filt = hotDeadPixel->get_active(); - pp->raw.linenoise = (int)lineDenoise->getValue(); - pp->raw.greenthresh = (int)greenEqThreshold->getValue(); - - if (pedited) { - pedited->raw.darkFrame = dfChanged; - pedited->raw.dfAuto = !dfAuto->get_inconsistent(); - pedited->raw.linenoise = lineDenoise->getEditedState (); - pedited->raw.greenEq= greenEqThreshold->getEditedState (); - pedited->raw.caCorrection = !caAutocorrect->get_inconsistent(); - pedited->raw.hotDeadPixel = !hotDeadPixel->get_inconsistent(); - } -} - -void PreProcess::adjusterChanged (Adjuster* a, double newval) -{ - if (listener) - listener->panelChanged (EvPreProcess, Glib::ustring("params") ); -} - -void PreProcess::setBatchMode(bool batchMode) -{ - ToolPanel::setBatchMode (batchMode); - lineDenoise->showEditedCB (); - greenEqThreshold->showEditedCB (); -} - -void PreProcess::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) -{ - lineDenoise->setDefault( defParams->raw.linenoise); - greenEqThreshold->setDefault (defParams->raw.greenthresh); - if (pedited) { - lineDenoise->setDefaultEditedState( pedited->raw.linenoise ? Edited : UnEdited); - greenEqThreshold->setDefaultEditedState(pedited->raw.greenEq ? Edited : UnEdited); - }else{ - lineDenoise->setDefaultEditedState( Irrelevant ); - greenEqThreshold->setDefaultEditedState(Irrelevant ); - } -} - -void PreProcess::caCorrectionChanged() -{ - if (batchMode) { - if (caAutocorrect->get_inconsistent()) { - caAutocorrect->set_inconsistent (false); - caacsconn.block (true); - caAutocorrect->set_active (false); - caacsconn.block (false); - } - else if (lastCA) - caAutocorrect->set_inconsistent (true); - - lastCA = caAutocorrect->get_active (); - } - if (listener) - listener->panelChanged (EvPreProcess, Glib::ustring("CA autocorrection ")+ (caAutocorrect->get_active()?"ON":"OFF") ); -} - -void PreProcess::dfAutoChanged() -{ - if (batchMode) { - if (dfAuto->get_inconsistent()) { - dfAuto->set_inconsistent (false); - dfautoconn.block (true); - dfAuto->set_active (false); - dfautoconn.block (false); - } - else if (lastDFauto) - dfAuto->set_inconsistent (true); - - lastDFauto = dfAuto->get_active (); - } - hbdf->set_sensitive( !dfAuto->get_active() ); - if (listener) - listener->panelChanged (EvPreProcess, Glib::ustring("Dark Frame autoselection")+ (dfAuto->get_active()?"ON":"OFF") ); -} - -void PreProcess::hotDeadPixelChanged () -{ - if (batchMode) { - if (hotDeadPixel->get_inconsistent()) { - hotDeadPixel->set_inconsistent (false); - hdpixelconn.block (true); - hotDeadPixel->set_active (false); - hdpixelconn.block (false); - } - else if (lastHot) - hotDeadPixel->set_inconsistent (true); - - lastHot = hotDeadPixel->get_active (); - } - if (listener) - listener->panelChanged (EvPreProcess, Glib::ustring("Hot Dead Pixel ")+(hotDeadPixel->get_active()?"ON":"OFF") ); -} -void PreProcess::darkFrameChanged() -{ - dfChanged=true; - if (listener) - listener->panelChanged (EvPreProcess, Glib::ustring("Dark Framet set to ")+darkFrameFile->get_filename()); -} - -void PreProcess::darkFrameReset() -{ - dfChanged=true; - darkFrameFile->set_current_name(""); - darkFrameFile->set_filename (""); - if (listener) - listener->panelChanged (EvPreProcess, Glib::ustring("Dark Framet reset")); - -} diff --git a/rtgui/preprocess.h b/rtgui/preprocess.h deleted file mode 100644 index edf6fbdad..000000000 --- a/rtgui/preprocess.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#ifndef _PREPROCESS_H_ -#define _PREPROCESS_H_ - -#include -#include -#include - - -class PreProcess : public Gtk::VBox, public AdjusterListener, public ToolPanel{ - - protected: - - Gtk::ComboBoxText* darkFrameMethod; - Gtk::FileChooserButton *darkFrameFile; - Gtk::HBox *hbdf; - Gtk::Button *btnReset; - Gtk::Label *dfLabel; - bool dfChanged; - - Adjuster* lineDenoise; - Adjuster* greenEqThreshold; - Gtk::CheckButton* caAutocorrect; - Gtk::CheckButton* hotDeadPixel; - Gtk::CheckButton* dfAuto; - bool lastCA,lastHot,lastDFauto; - - sigc::connection caacsconn,dfautoconn,hdpixelconn,dfFile; - public: - - PreProcess (); - - void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); - void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); - void setBatchMode (bool batchMode); - void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); - - void adjusterChanged (Adjuster* a, double newval); - void caCorrectionChanged(); - void hotDeadPixelChanged(); - void darkFrameChanged(); - void darkFrameReset(); - void dfAutoChanged(); -}; - -#endif diff --git a/rtgui/rawprocess.cc b/rtgui/rawprocess.cc deleted file mode 100644 index 8ef48e259..000000000 --- a/rtgui/rawprocess.cc +++ /dev/null @@ -1,181 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#include -#include -#include -using namespace rtengine; -using namespace rtengine::procparams; - -RawProcess::RawProcess () -{ - Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ()); - hb1->pack_start (*Gtk::manage (new Gtk::Label ( M("PREFERENCES_DMETHOD") +": "))); - dmethod = Gtk::manage (new Gtk::ComboBoxText ()); - for( size_t i=0; i< procparams::RAWParams::numMethods;i++) - dmethod->append_text(procparams::RAWParams::methodstring[i]); - - dmethod->set_active(0); - hb1->pack_end (*dmethod); - pack_start( *hb1, Gtk::PACK_SHRINK, 4); - - dcbOptions = Gtk::manage (new Gtk::VBox ()); - dcbOptions->set_border_width(4); - - dcbIterations = Gtk::manage (new Adjuster (M("PREFERENCES_DCBITERATIONS"),0,5,1,2)); - dcbIterations ->setAdjusterListener (this); - dcbIterations ->show(); - dcbEnhance = Gtk::manage (new Gtk::CheckButton(M("PREFERENCES_DCBENHANCE"))); - dcbOptions->pack_start(*dcbIterations); - dcbOptions->pack_start(*dcbEnhance); - pack_start( *dcbOptions, Gtk::PACK_SHRINK, 4); - pack_start( *Gtk::manage( new Gtk::HSeparator()), Gtk::PACK_SHRINK, 4 ); - - ccOptions = Gtk::manage (new Gtk::VBox ()); - ccOptions->set_border_width(4); - ccSteps = Gtk::manage (new Adjuster (M("PREFERENCES_FALSECOLOR"),0,5,1,2 )); - ccSteps->setAdjusterListener (this); - ccSteps->show(); - pack_start( *ccSteps, Gtk::PACK_SHRINK, 4); - - methodconn = dmethod->signal_changed().connect( sigc::mem_fun(*this, &RawProcess::methodChanged) ); - dcbEnhconn = dcbEnhance->signal_toggled().connect ( sigc::mem_fun(*this, &RawProcess::dcbEnhanceChanged), true); -} - - -void RawProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) -{ - disableListener (); - methodconn.block (true); - dcbEnhconn.block (true); - - dmethod->set_active(procparams::RAWParams::numMethods); - for( size_t i=0; i< procparams::RAWParams::numMethods;i++) - if( pp->raw.dmethod == procparams::RAWParams::methodstring[i]){ - dmethod->set_active(i); - break; - } - - dcbIterations->setValue (pp->raw.dcb_iterations); - dcbEnhance->set_active(pp->raw.dcb_enhance); - ccSteps->setValue (pp->raw.ccSteps); - if (pp->raw.dmethod == procparams::RAWParams::methodstring[procparams::RAWParams::dcb]) - dcbOptions->show(); - else - dcbOptions->hide(); - - if (pp->raw.dmethod == procparams::RAWParams::methodstring[procparams::RAWParams::eahd] || - pp->raw.dmethod == procparams::RAWParams::methodstring[procparams::RAWParams::hphd] || - pp->raw.dmethod == procparams::RAWParams::methodstring[procparams::RAWParams::vng4]) - ccOptions->show(); - else - ccOptions->hide(); - - lastDCBen = pp->raw.dcb_enhance; - - if(pedited ){ - ccSteps->setEditedState (pedited->raw.ccSteps ? Edited : UnEdited); - dcbIterations->setEditedState ( pedited->raw.dcbIterations ? Edited : UnEdited); - dcbEnhance->set_inconsistent(!pedited->raw.dcbEnhance); - if( !pedited->raw.dmethod ) - dmethod->set_active(procparams::RAWParams::numMethods); // No name - } - - methodconn.block (false); - dcbEnhconn.block (false); - enableListener (); -} - -void RawProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) -{ - pp->raw.ccSteps = (int)ccSteps->getValue(); - pp->raw.dcb_iterations = (int)dcbIterations->getValue(); - pp->raw.dcb_enhance = dcbEnhance->get_active(); - - if( dmethod->get_active_row_number() < procparams::RAWParams::numMethods) - pp->raw.dmethod = procparams::RAWParams::methodstring[dmethod->get_active_row_number()]; - - if (pedited) { - pedited->raw.ccSteps = ccSteps->getEditedState (); - pedited->raw.dmethod = dmethod->get_active_row_number() != procparams::RAWParams::numMethods; - pedited->raw.dcbIterations = dcbIterations->getEditedState (); - pedited->raw.dcbEnhance = !dcbEnhance->get_inconsistent(); - } -} - -void RawProcess::setBatchMode(bool batchMode) -{ - dmethod->set_active(procparams::RAWParams::numMethods); // No name - dcbOptions->hide(); - ToolPanel::setBatchMode (batchMode); - ccSteps->showEditedCB (); - dcbIterations->showEditedCB (); -} - -void RawProcess::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) -{ - dcbIterations->setDefault( defParams->raw.dcb_iterations); - ccSteps->setDefault (defParams->raw.ccSteps); - if (pedited) { - dcbIterations->setDefaultEditedState( pedited->raw.dcbIterations ? Edited : UnEdited); - ccSteps->setDefaultEditedState(pedited->raw.ccSteps ? Edited : UnEdited); - }else{ - dcbIterations->setDefaultEditedState( Irrelevant ); - ccSteps->setDefaultEditedState(Irrelevant ); - } -} - -void RawProcess::adjusterChanged (Adjuster* a, double newval) -{ - if (listener) - listener->panelChanged (EvDemosaic, Glib::ustring("params") ); -} - -void RawProcess::methodChanged () -{ - int curSelection = dmethod->get_active_row_number(); - if ( curSelection == procparams::RAWParams::dcb){ - dcbOptions->show(); - }else{ - dcbOptions->hide(); - } - Glib::ustring s=""; - if( curSelection>=0 && curSelection < procparams::RAWParams::numMethods) - s = procparams::RAWParams::methodstring[curSelection]; - - if (listener) - listener->panelChanged (EvDemosaic, Glib::ustring(M("PREFERENCES_DMETHOD"))+ "="+ s); -} - -void RawProcess::dcbEnhanceChanged () -{ - if (batchMode) { - if (dcbEnhance->get_inconsistent()) { - dcbEnhance->set_inconsistent (false); - dcbEnhconn.block (true); - dcbEnhance->set_active (false); - dcbEnhconn.block (false); - } - else if (lastDCBen) - dcbEnhance->set_inconsistent (true); - - lastDCBen = dcbEnhance->get_active (); - } - if (listener) - listener->panelChanged (EvDemosaic, Glib::ustring("params") ); -} diff --git a/rtgui/rawprocess.h b/rtgui/rawprocess.h deleted file mode 100644 index e3eeab49d..000000000 --- a/rtgui/rawprocess.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * RawTherapee is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * RawTherapee is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with RawTherapee. If not, see . - */ -#ifndef _RAWPROCESS_H_ -#define _RAWPROCESS_H_ - -#include -#include -#include - - -class RawProcess : public Gtk::VBox, public AdjusterListener, public ToolPanel{ - - protected: - - Gtk::ComboBoxText* dmethod; - Gtk::Label* methodl; - Adjuster* ccSteps; - Gtk::VBox *dcbOptions; - Gtk::VBox *ccOptions; - Adjuster* dcbIterations; - Gtk::CheckButton* dcbEnhance; - - bool lastDCBen; - sigc::connection methodconn,dcbEnhconn; - public: - - RawProcess (); - - void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); - void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); - void setBatchMode (bool batchMode); - void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); - - void methodChanged (); - void adjusterChanged (Adjuster* a, double newval); - void dcbEnhanceChanged(); -}; - -#endif diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 5ac0585ba..f01cc2105 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -29,7 +29,6 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) { detailsPanel = Gtk::manage (new Gtk::VBox ()); colorPanel = Gtk::manage (new Gtk::VBox ()); transformPanel = Gtk::manage (new Gtk::VBox ()); - rawPanel = Gtk::manage (new Gtk::VBox ()); coarse = Gtk::manage (new CoarsePanel ()); curve = Gtk::manage (new ToneCurve ()); @@ -55,8 +54,6 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) { exifpanel = Gtk::manage (new ExifPanel ()); iptcpanel = Gtk::manage (new IPTCPanel ()); equalizer = Gtk::manage (new Equalizer ()); - rawprocess = Gtk::manage (new RawProcess ()); - preprocess = Gtk::manage (new PreProcess ()); addPanel (colorPanel, whitebalance, M("TP_WBALANCE_LABEL")); toolPanels.push_back (whitebalance); addPanel (exposurePanel, curve, M("TP_EXPOSURE_LABEL")); toolPanels.push_back (curve); @@ -79,8 +76,6 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) { addPanel (lensgeom->getPackBox(), cacorrection, M("TP_CACORRECTION_LABEL")); toolPanels.push_back (cacorrection); addPanel (lensgeom->getPackBox(), vignetting, M("TP_VIGNETTING_LABEL")); toolPanels.push_back (vignetting); addPanel (colorPanel, icm, M("TP_ICM_LABEL")); toolPanels.push_back (icm); - addPanel (rawPanel, rawprocess, "Demosaicing"); toolPanels.push_back (rawprocess); - addPanel (rawPanel, preprocess, "Pre-processing"); toolPanels.push_back (preprocess); toolPanels.push_back (coarse); toolPanels.push_back (exifpanel); @@ -96,24 +91,20 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) { Gtk::ScrolledWindow* detailsPanelSW = Gtk::manage (new Gtk::ScrolledWindow ()); Gtk::ScrolledWindow* colorPanelSW = Gtk::manage (new Gtk::ScrolledWindow ()); Gtk::ScrolledWindow* transformPanelSW = Gtk::manage (new Gtk::ScrolledWindow ()); - Gtk::ScrolledWindow* rawPanelSW = Gtk::manage (new Gtk::ScrolledWindow ()); exposurePanelSW->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); detailsPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); colorPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); transformPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); - rawPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); exposurePanelSW->add (*exposurePanel); detailsPanelSW->add (*detailsPanel); colorPanelSW->add (*colorPanel); transformPanelSW->add (*transformPanel); - rawPanelSW->add (*rawPanel); toolPanelNotebook->append_page (*exposurePanelSW, M("MAIN_TAB_EXPOSURE")); toolPanelNotebook->append_page (*detailsPanelSW, M("MAIN_TAB_DETAIL")); toolPanelNotebook->append_page (*colorPanelSW, M("MAIN_TAB_COLOR")); toolPanelNotebook->append_page (*transformPanelSW, M("MAIN_TAB_TRANSFORM")); - toolPanelNotebook->append_page (*rawPanelSW, "RAW"); toolPanelNotebook->append_page (*metadataPanel, M("MAIN_TAB_METADATA")); toolPanelNotebook->set_current_page (0); diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 9eb34255f..6407b4a47 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -52,8 +52,7 @@ #include #include #include -#include -#include + class ImageEditorCoordinator; @@ -89,8 +88,6 @@ class ToolPanelCoordinator : public ToolPanelListener, Sharpening* sharpening; LCurve* lcurve; Equalizer * equalizer; - RawProcess* rawprocess; - PreProcess* preprocess; std::vector paramcListeners; @@ -101,7 +98,6 @@ class ToolPanelCoordinator : public ToolPanelListener, Gtk::VBox* detailsPanel; Gtk::VBox* colorPanel; Gtk::VBox* transformPanel; - Gtk::VBox* rawPanel; Gtk::Notebook* metadataPanel; ExifPanel* exifpanel; IPTCPanel* iptcpanel;