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