Implementing issue #190 (a new "Fit box" option in the resize tool), and correction of issue #28, #92, #149, #237 and #345, but i had to disable the resize preview for that.

This commit is contained in:
Hombre
2010-12-12 22:24:53 +01:00
parent e394b29d6d
commit 5027c8c00b
24 changed files with 934 additions and 727 deletions

View File

@@ -149,6 +149,8 @@ HISTORY_MSG_104;Égaliseur TSV
HISTORY_MSG_105;Corr. aberr. chromatique HISTORY_MSG_105;Corr. aberr. chromatique
HISTORY_MSG_106;Corr. a.c. - Rayon HISTORY_MSG_106;Corr. a.c. - Rayon
HISTORY_MSG_107;Corr. a.c. - Seuil HISTORY_MSG_107;Corr. a.c. - Seuil
HISTORY_MSG_108;Redim. - boîte englobante
HISTORY_MSG_109;Redim. s'applique à
HISTORY_MSG_10;Compression des ombres HISTORY_MSG_10;Compression des ombres
HISTORY_MSG_11;Courbe tonale HISTORY_MSG_11;Courbe tonale
HISTORY_MSG_12;Exposition auto HISTORY_MSG_12;Exposition auto
@@ -698,12 +700,16 @@ TP_PREPROCESS_DARKFRAME;Image noire
TP_PREPROCESS_DFAUTOSELECT;Sélection automatique TP_PREPROCESS_DFAUTOSELECT;Sélection automatique
TP_RAWPANEL_DEMOSAICING;Dématriçage TP_RAWPANEL_DEMOSAICING;Dématriçage
TP_RAWPANEL_PREPROCESSING;Pre-traitement TP_RAWPANEL_PREPROCESSING;Pre-traitement
TP_RESIZE_APPLIESTO;S'applique à:
TP_RESIZE_FULLIMAGE;L'image entière
TP_RESIZE_CROPPEDAREA;La zone recadrée
TP_RESIZE_BICUBIC;Bicubique TP_RESIZE_BICUBIC;Bicubique
TP_RESIZE_BICUBICSF;Bicubique (Plus doux) TP_RESIZE_BICUBICSF;Bicubique (Plus doux)
TP_RESIZE_BICUBICSH;Bicubique (Plus net) TP_RESIZE_BICUBICSH;Bicubique (Plus net)
TP_RESIZE_BILINEAR;Bilinéaire TP_RESIZE_BILINEAR;Bilinéaire
TP_RESIZE_DOWNSCALEB;Diminuer (Meilleur) TP_RESIZE_DOWNSCALEB;Diminuer (Meilleur)
TP_RESIZE_DOWNSCALEF;Diminuer (Plus rapide) TP_RESIZE_DOWNSCALEF;Diminuer (Plus rapide)
TP_RESIZE_FITBOX;Boîte englobante
TP_RESIZE_FULLSIZE;Dimensions finales de l'image: TP_RESIZE_FULLSIZE;Dimensions finales de l'image:
TP_RESIZE_H;H: TP_RESIZE_H;H:
TP_RESIZE_HEIGHT;Hauteur TP_RESIZE_HEIGHT;Hauteur

View File

@@ -145,6 +145,8 @@ HISTORY_MSG_104;HSV Equalizer
HISTORY_MSG_105;Defringing HISTORY_MSG_105;Defringing
HISTORY_MSG_106;Defringing Radius HISTORY_MSG_106;Defringing Radius
HISTORY_MSG_107;Defringing Threshold HISTORY_MSG_107;Defringing Threshold
HISTORY_MSG_108;Resize bounding box
HISTORY_MSG_109;Resizing applies to
HISTORY_MSG_10;Shadow Compression HISTORY_MSG_10;Shadow Compression
HISTORY_MSG_11;Tone Curve HISTORY_MSG_11;Tone Curve
HISTORY_MSG_12;Auto Exposure HISTORY_MSG_12;Auto Exposure
@@ -697,12 +699,16 @@ TP_PREPROCESS_DARKFRAME;Dark frame
TP_PREPROCESS_DFAUTOSELECT;Auto selection TP_PREPROCESS_DFAUTOSELECT;Auto selection
TP_RAWPANEL_DEMOSAICING;Demosaicing TP_RAWPANEL_DEMOSAICING;Demosaicing
TP_RAWPANEL_PREPROCESSING;Preprocessing TP_RAWPANEL_PREPROCESSING;Preprocessing
TP_RESIZE_APPLIESTO;Applies to:
TP_RESIZE_FULLIMAGE;Full image
TP_RESIZE_CROPPEDAREA;Cropped area
TP_RESIZE_BICUBIC;Bicubic TP_RESIZE_BICUBIC;Bicubic
TP_RESIZE_BICUBICSF;Bicubic (Softer) TP_RESIZE_BICUBICSF;Bicubic (Softer)
TP_RESIZE_BICUBICSH;Bicubic (Sharper) TP_RESIZE_BICUBICSH;Bicubic (Sharper)
TP_RESIZE_BILINEAR;Bilinear TP_RESIZE_BILINEAR;Bilinear
TP_RESIZE_DOWNSCALEB;Downscale (Better) TP_RESIZE_DOWNSCALEB;Downscale (Better)
TP_RESIZE_DOWNSCALEF;Downscale (Faster) TP_RESIZE_DOWNSCALEF;Downscale (Faster)
TP_RESIZE_FITBOX;Bounding box
TP_RESIZE_FULLSIZE;Full Image Size: TP_RESIZE_FULLSIZE;Full Image Size:
TP_RESIZE_H;H: TP_RESIZE_H;H:
TP_RESIZE_HEIGHT;Height TP_RESIZE_HEIGHT;Height

View File

@@ -65,13 +65,6 @@ void Crop::update (int todo, bool internal) {
ProcParams& params = parent->params; ProcParams& params = parent->params;
cropMutex.lock (); cropMutex.lock ();
if (!params.resize.enabled)
params.resize.scale = 1.0;
else if (params.resize.dataspec==1)
params.resize.scale = (double)params.resize.width / (params.coarse.rotate==90 || params.coarse.rotate==270 ? parent->fh : parent->fw);
else if (params.resize.dataspec==2)
params.resize.scale = (double)params.resize.height / (params.coarse.rotate==90 || params.coarse.rotate==270 ? parent->fw : parent->fh);
parent->ipf.setScale (skip); parent->ipf.setScale (skip);
// give possibility to the listener to modify crop window (as the full image dimensions are already known at this point) // give possibility to the listener to modify crop window (as the full image dimensions are already known at this point)
@@ -98,10 +91,7 @@ void Crop::update (int todo, bool internal) {
if( regenHighDetail ) if( regenHighDetail )
parent->updatePreviewImage (ALL,this); // We have just set skip to 1 parent->updatePreviewImage (ALL,this); // We have just set skip to 1
if (resizeCrop) baseCrop = origCrop;
baseCrop = resizeCrop;
else
baseCrop = origCrop;
bool needstransform = parent->ipf.needsTransform(); bool needstransform = parent->ipf.needsTransform();
@@ -119,29 +109,6 @@ void Crop::update (int todo, bool internal) {
PreviewProps pp (trafx, trafy, trafw*skip, trafh*skip, skip); 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, params.raw );
if (fabs(params.resize.scale-1.0)<1e-7) {
if (resizeCrop) {
delete resizeCrop;
resizeCrop = NULL;
}
baseCrop = origCrop;
}
else {
int rcw = trafw*params.resize.scale;
int rch = trafh*params.resize.scale;
if (!needstransform) {
rcw = cropw;
rch = croph;
}
if (resizeCrop && (resizeCrop->width!=rcw || resizeCrop->height!=rch)) {
delete resizeCrop;
resizeCrop = NULL;
}
if (!resizeCrop)
resizeCrop = new Image16 (rcw, rch);
parent->ipf.resize (origCrop, resizeCrop);
baseCrop = resizeCrop;
}
parent->minit.unlock (); parent->minit.unlock ();
} }
@@ -153,7 +120,7 @@ void Crop::update (int todo, bool internal) {
if (needstransform && !transCrop) if (needstransform && !transCrop)
transCrop = new Image16 (cropw, croph); transCrop = new Image16 (cropw, croph);
if ((todo & M_TRANSFORM) && needstransform) if ((todo & M_TRANSFORM) && needstransform)
parent->ipf.transform (baseCrop, transCrop, cropx/skip, cropy/skip, trafx*params.resize.scale/skip, trafy*params.resize.scale/skip, SKIPS(parent->fw,skip), SKIPS(parent->fh,skip)); parent->ipf.transform (baseCrop, transCrop, cropx/skip, cropy/skip, trafx/skip, trafy/skip, SKIPS(parent->fw,skip), SKIPS(parent->fh,skip));
if (transCrop) if (transCrop)
baseCrop = transCrop; baseCrop = transCrop;

View File

@@ -69,13 +69,6 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
int numofphases = 10; int numofphases = 10;
int readyphase = 0; int readyphase = 0;
if (!params.resize.enabled)
params.resize.scale = 1.0;
else if (params.resize.dataspec==1)
params.resize.scale = (double)params.resize.width / (params.coarse.rotate==90 || params.coarse.rotate==270 ? fh : fw);
else if (params.resize.dataspec==2)
params.resize.scale = (double)params.resize.height / (params.coarse.rotate==90 || params.coarse.rotate==270 ? fw : fh);
ipf.setScale (scale); ipf.setScale (scale);
bool highDetailNeeded=false; bool highDetailNeeded=false;
@@ -256,7 +249,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
if (!resultValid) { if (!resultValid) {
resultValid = true; resultValid = true;
if (imageListener) if (imageListener)
imageListener->setImage (previmg, scale*params.resize.scale, params.crop); imageListener->setImage (previmg, scale, params.crop);
} }
if (imageListener) if (imageListener)
imageListener->imageReady (params.crop); imageListener->imageReady (params.crop);
@@ -347,22 +340,8 @@ if (settings->verbose) printf ("setscale before lock\n");
scale = prevscale; scale = prevscale;
resultValid = false; resultValid = false;
if (!params.resize.enabled) { fullw = fw;
fullw = fw; fullh = fh;
fullh = fh;
}
else if (params.resize.dataspec==0) {
fullw = fw*params.resize.scale;
fullh = fh*params.resize.scale;
}
else if (params.resize.dataspec==1) {
fullw = params.resize.width;
fullh = (double)fh*params.resize.width/(params.coarse.rotate==90 || params.coarse.rotate==270 ? fh : fw);
}
else if (params.resize.dataspec==2) {
fullw = (double)fw*params.resize.height/(params.coarse.rotate==90 || params.coarse.rotate==270 ? fw : fh);
fullh = params.resize.height;
}
if (settings->verbose) printf ("setscale ends\n"); if (settings->verbose) printf ("setscale ends\n");
if (sizeListeners.size()>0) if (sizeListeners.size()>0)
for (int i=0; i<sizeListeners.size(); i++) for (int i=0; i<sizeListeners.size(); i++)

View File

@@ -32,96 +32,96 @@ using namespace procparams;
class ImProcFunctions { class ImProcFunctions {
static int* cacheL; static int* cacheL;
static int* cachea; static int* cachea;
static int* cacheb; static int* cacheb;
static int* xcache; static int* xcache;
static int* ycache; static int* ycache;
static int* zcache; static int* zcache;
static unsigned short gamma2curve[65536]; static unsigned short gamma2curve[65536];
cmsHTRANSFORM monitorTransform; cmsHTRANSFORM monitorTransform;
int chroma_scale; int chroma_scale;
int chroma_radius; int chroma_radius;
const ProcParams* params; const ProcParams* params;
double scale; double scale;
bool multiThread; bool multiThread;
void simpltransform (Image16* original, Image16* transformed, int cx, int cy, int sx, int sy, int oW, int oH); void simpltransform (Image16* original, Image16* transformed, int cx, int cy, int sx, int sy, int oW, int oH);
void vignetting (Image16* original, Image16* transformed, int cx, int cy, int oW, int oH); void vignetting (Image16* original, Image16* transformed, int cx, int cy, int oW, int oH);
void transformNonSep (Image16* original, Image16* transformed, int cx, int cy, int sx, int sy, int oW, int oH); void transformNonSep (Image16* original, Image16* transformed, int cx, int cy, int sx, int sy, int oW, int oH);
void transformSep (Image16* original, Image16* transformed, int cx, int cy, int sx, int sy, int oW, int oH); void transformSep (Image16* original, Image16* transformed, int cx, int cy, int sx, int sy, int oW, int oH);
void sharpenHaloCtrl (LabImage* lab, unsigned short** blurmap, unsigned short** base, int W, int H); void sharpenHaloCtrl (LabImage* lab, unsigned short** blurmap, unsigned short** base, int W, int H);
void firstAnalysis_ (Image16* original, Glib::ustring wprofile, unsigned int* histogram, int* chroma_radius, int row_from, int row_to); void firstAnalysis_ (Image16* original, Glib::ustring wprofile, unsigned int* histogram, int* chroma_radius, int row_from, int row_to);
void dcdamping (float** aI, unsigned short** aO, float damping, int W, int H); void dcdamping (float** aI, unsigned short** aO, float damping, int W, int H);
bool needsCA (); bool needsCA ();
bool needsDistortion (); bool needsDistortion ();
bool needsRotation (); bool needsRotation ();
bool needsPerspective (); bool needsPerspective ();
bool needsVignetting (); bool needsVignetting ();
public: public:
double lumimul[3]; double lumimul[3];
static void initCache (); static void initCache ();
ImProcFunctions (const ProcParams* iparams, bool imultiThread=true) ImProcFunctions (const ProcParams* iparams, bool imultiThread=true)
: monitorTransform(NULL), params(iparams), scale(1), multiThread(imultiThread) {} : monitorTransform(NULL), params(iparams), scale(1), multiThread(imultiThread) {}
~ImProcFunctions (); ~ImProcFunctions ();
void setScale (double iscale); void setScale (double iscale);
bool needsTransform (); bool needsTransform ();
void firstAnalysis (Image16* working, const ProcParams* params, unsigned int* vhist16, double gamma); void firstAnalysis (Image16* working, const ProcParams* params, unsigned int* vhist16, double gamma);
void rgbProc (Image16* working, LabImage* lab, float* hltonecurve, float* shtonecurve, int* tonecurve, SHMap* shmap, int sat); void rgbProc (Image16* working, LabImage* lab, float* hltonecurve, float* shtonecurve, int* tonecurve, SHMap* shmap, int sat);
void luminanceCurve (LabImage* lold, LabImage* lnew, int* curve, int row_from, int row_to); void luminanceCurve (LabImage* lold, LabImage* lnew, int* curve, int row_from, int row_to);
void chrominanceCurve (LabImage* lold, LabImage* lnew, int channel, int* curve, int row_from, int row_to); void chrominanceCurve (LabImage* lold, LabImage* lnew, int channel, int* curve, int row_from, int row_to);
void colorCurve (LabImage* lold, LabImage* lnew); void colorCurve (LabImage* lold, LabImage* lnew);
void sharpening (LabImage* lab, unsigned short** buffer); void sharpening (LabImage* lab, unsigned short** buffer);
void lumadenoise (LabImage* lab, int** buffer); void lumadenoise (LabImage* lab, int** buffer);
void colordenoise (LabImage* lab, int** buffer); void colordenoise (LabImage* lab, int** buffer);
void transform (Image16* original, Image16* transformed, int cx, int cy, int sx, int sy, int oW, int oH); void transform (Image16* original, Image16* transformed, int cx, int cy, int sx, int sy, int oW, int oH);
void lab2rgb (LabImage* lab, Image8* image); void lab2rgb (LabImage* lab, Image8* image);
void resize (Image16* src, Image16* dst); void resize (Image16* src, Image16* dst, double dScale);
void deconvsharpening(LabImage* lab, unsigned short** buffer); void deconvsharpening (LabImage* lab, unsigned short** buffer);
void waveletEqualizer(Image16 * image); void waveletEqualizer (Image16 * image);
void waveletEqualizer(LabImage * image, bool luminance, bool chromaticity); void waveletEqualizer (LabImage * image, bool luminance, bool chromaticity);
void impulsedenoise (LabImage* lab);//Emil's impulse denoise
void dirpyrdenoise (LabImage* lab);//Emil's impulse denoise
void dirpyrequalizer (LabImage* lab);//Emil's equalizer
void dirpyrLab_denoise(LabImage * src, LabImage * dst, int luma, int chroma, float gamma );//Emil's directional pyramid denoise void impulsedenoise (LabImage* lab);//Emil's impulse denoise
void dirpyr(LabImage* data_fine, LabImage* data_coarse, int level, int * rangefn_L, int * rangefn_ab, int pitch, int scale, const int luma, int chroma ); void dirpyrdenoise (LabImage* lab);//Emil's impulse denoise
void idirpyr(LabImage* data_coarse, LabImage* data_fine, int level, float * nrwt_l, float * nrwt_ab, int pitch, int scale, const int luma, int chroma ); void dirpyrequalizer (LabImage* lab);//Emil's equalizer
void dirpyrLab_equalizer(LabImage * src, LabImage * dst, const double * mult );//Emil's directional pyramid equalizer
void dirpyr_eq(LabImage* data_coarse, LabImage* data_fine, int * rangefn, int level, int pitch, int scale, const double * mult );
void idirpyr_eq(LabImage* data_coarse, LabImage* data_fine, int *** buffer, int * irangefn, int level, int pitch, int scale, const double * mult );
void dirpyr_equalizer(unsigned short ** src, unsigned short ** dst, int srcwidth, int srcheight, const double * mult );//Emil's directional pyramid equalizer
void dirpyr_channel(unsigned short ** data_fine, unsigned short ** data_coarse, int width, int height, int * rangefn, int level, int scale, const double * mult );
void idirpyr_eq_channel(unsigned short ** data_coarse, unsigned short ** data_fine, int ** buffer, int width, int height, int level, const double * mult );
void defringe (LabImage* lab);
void PF_correct_RT(LabImage * src, LabImage * dst, double radius, int thresh, bool edges);
Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile);
Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile);
bool transCoord (int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1); void dirpyrLab_denoise(LabImage * src, LabImage * dst, int luma, int chroma, float gamma );//Emil's directional pyramid denoise
bool transCoord (int W, int H, std::vector<Coord2D> &src, std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, double ascaleDef = -1); void dirpyr (LabImage* data_fine, LabImage* data_coarse, int level, int * rangefn_L, int * rangefn_ab, int pitch, int scale, const int luma, int chroma );
void getAutoExp (unsigned int* histogram, int histcompr, double expcomp, double clip, double& br, int& bl); void idirpyr (LabImage* data_coarse, LabImage* data_fine, int level, float * nrwt_l, float * nrwt_ab, int pitch, int scale, const int luma, int chroma );
double getTransformAutoFill (int oW, int oH);
void dirpyrLab_equalizer (LabImage * src, LabImage * dst, const double * mult );//Emil's directional pyramid equalizer
void rgb2hsv (int r, int g, int b, float &h, float &s, float &v); void dirpyr_eq (LabImage* data_coarse, LabImage* data_fine, int * rangefn, int level, int pitch, int scale, const double * mult );
void hsv2rgb (float h, float s, float v, int &r, int &g, int &b); void idirpyr_eq (LabImage* data_coarse, LabImage* data_fine, int *** buffer, int * irangefn, int level, int pitch, int scale, const double * mult );
void dirpyr_equalizer (unsigned short ** src, unsigned short ** dst, int srcwidth, int srcheight, const double * mult );//Emil's directional pyramid equalizer
void dirpyr_channel (unsigned short ** data_fine, unsigned short ** data_coarse, int width, int height, int * rangefn, int level, int scale, const double * mult );
void idirpyr_eq_channel (unsigned short ** data_coarse, unsigned short ** data_fine, int ** buffer, int width, int height, int level, const double * mult );
void defringe (LabImage* lab);
void PF_correct_RT (LabImage * src, LabImage * dst, double radius, int thresh, bool edges);
Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile);
Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile);
bool transCoord (int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1);
bool transCoord (int W, int H, std::vector<Coord2D> &src, std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, double ascaleDef = -1);
void getAutoExp (unsigned int* histogram, int histcompr, double expcomp, double clip, double& br, int& bl);
double getTransformAutoFill (int oW, int oH);
void rgb2hsv (int r, int g, int b, float &h, float &s, float &v);
void hsv2rgb (float h, float s, float v, int &r, int &g, int &b);
}; };
} }
#endif #endif

View File

@@ -170,12 +170,12 @@ void Lanczos(const Image16* src, Image16* dst, double scale)
delete[] lb; delete[] lb;
} }
void ImProcFunctions::resize (Image16* src, Image16* dst) { void ImProcFunctions::resize (Image16* src, Image16* dst, double dScale) {
//time_t t1 = clock(); //time_t t1 = clock();
if(params->resize.method == "Lanczos") { if(params->resize.method == "Lanczos") {
Lanczos(src, dst, params->resize.scale); Lanczos(src, dst, dScale);
} }
else if(params->resize.method == "Downscale (Better)") { else if(params->resize.method == "Downscale (Better)") {
// small-scale algorithm by Ilia // small-scale algorithm by Ilia
@@ -187,8 +187,8 @@ void ImProcFunctions::resize (Image16* src, Image16* dst) {
// this algorithm is much slower on small factors than others, because it uses all pixels of the SOURCE image // this algorithm is much slower on small factors than others, because it uses all pixels of the SOURCE image
// Ilia Popov ilia_popov@rambler.ru 2010 // Ilia Popov ilia_popov@rambler.ru 2010
double delta = 1.0 / params->resize.scale; double delta = 1.0 / dScale;
double k = params->resize.scale * params->resize.scale; double k = dScale * dScale;
#pragma omp parallel for if (multiThread) #pragma omp parallel for if (multiThread)
for(int i = 0; i < dst->height; i++) { for(int i = 0; i < dst->height; i++) {
@@ -266,7 +266,7 @@ void ImProcFunctions::resize (Image16* src, Image16* dst) {
// for weights at all // for weights at all
// Ilia Popov ilia_popov@rambler.ru 5.04.2010 // Ilia Popov ilia_popov@rambler.ru 5.04.2010
double delta = 1.0 / params->resize.scale; double delta = 1.0 / dScale;
int p = (int) delta; int p = (int) delta;
@@ -339,7 +339,7 @@ void ImProcFunctions::resize (Image16* src, Image16* dst) {
#pragma omp parallel for if (multiThread) #pragma omp parallel for if (multiThread)
for (int i=0; i<dst->height; i++) { for (int i=0; i<dst->height; i++) {
double wx[4], wy[4]; double wx[4], wy[4];
double Dy = i / params->resize.scale; double Dy = i / dScale;
int yc = (int) Dy; Dy -= (double)yc; int yc = (int) Dy; Dy -= (double)yc;
int ys = yc - 1; // smallest y-index used for interpolation int ys = yc - 1; // smallest y-index used for interpolation
// compute vertical weights // compute vertical weights
@@ -350,7 +350,7 @@ void ImProcFunctions::resize (Image16* src, Image16* dst) {
wy[1] = -t1y*Dy + 1.0 - t2y; wy[1] = -t1y*Dy + 1.0 - t2y;
wy[0] = -t1y*(Dy-1.0); wy[0] = -t1y*(Dy-1.0);
for (int j=0; j<dst->width; j++) { for (int j=0; j<dst->width; j++) {
double Dx = j / params->resize.scale; double Dx = j / dScale;
int xc = (int) Dx; Dx -= (double)xc; int xc = (int) Dx; Dx -= (double)xc;
int xs = xc - 1; // smallest x-index used for interpolation int xs = xc - 1; // smallest x-index used for interpolation
if (ys >= 0 && ys <src->height-3 && xs >= 0 && xs <= src->width-3) { if (ys >= 0 && ys <src->height-3 && xs >= 0 && xs <= src->width-3) {
@@ -395,16 +395,16 @@ void ImProcFunctions::resize (Image16* src, Image16* dst) {
else if (params->resize.method=="Bilinear") { else if (params->resize.method=="Bilinear") {
#pragma omp parallel for if (multiThread) #pragma omp parallel for if (multiThread)
for (int i=0; i<dst->height; i++) { for (int i=0; i<dst->height; i++) {
int sy = i/params->resize.scale; int sy = i/dScale;
sy = CLIPTO(sy, 0, src->height-1); sy = CLIPTO(sy, 0, src->height-1);
double dy = i/params->resize.scale - sy; double dy = i/dScale - sy;
int ny = sy+1; int ny = sy+1;
if (ny>=src->height) if (ny>=src->height)
ny = sy; ny = sy;
for (int j=0; j<dst->width; j++) { for (int j=0; j<dst->width; j++) {
int sx = j/params->resize.scale; int sx = j/dScale;
sx = CLIPTO(sx, 0, src->width-1); sx = CLIPTO(sx, 0, src->width-1);
double dx = j/params->resize.scale - sx; double dx = j/dScale - sx;
int nx = sx+1; int nx = sx+1;
if (nx>=src->width) if (nx>=src->width)
nx = sx; nx = sx;
@@ -417,10 +417,10 @@ void ImProcFunctions::resize (Image16* src, Image16* dst) {
else { else {
#pragma omp parallel for if (multiThread) #pragma omp parallel for if (multiThread)
for (int i=0; i<dst->height; i++) { for (int i=0; i<dst->height; i++) {
int sy = i/params->resize.scale; int sy = i/dScale;
sy = CLIPTO(sy, 0, src->height-1); sy = CLIPTO(sy, 0, src->height-1);
for (int j=0; j<dst->width; j++) { for (int j=0; j<dst->width; j++) {
int sx = j/params->resize.scale; int sx = j/dScale;
sx = CLIPTO(sx, 0, src->width-1); sx = CLIPTO(sx, 0, src->width-1);
dst->r[i][j] = src->r[sy][sx]; dst->r[i][j] = src->r[sy][sx];
dst->g[i][j] = src->g[sy][sx]; dst->g[i][j] = src->g[sy][sx];

View File

@@ -38,6 +38,7 @@ namespace rtengine {
#define CLIP(a) ((a)>0?((a)<CMAXVAL?(a):CMAXVAL):0) #define CLIP(a) ((a)>0?((a)<CMAXVAL?(a):CMAXVAL):0)
#define CLIPTO(a,b,c) ((a)>(b)?((a)<(c)?(a):(c)):(b)) #define CLIPTO(a,b,c) ((a)>(b)?((a)<(c)?(a):(c)):(b))
#define CLIPTOC(a,b,c,d) ((a)>=(b)?((a)<=(c)?(a):(d=true,(c))):(d=true,(b))) #define CLIPTOC(a,b,c,d) ((a)>=(b)?((a)<=(c)?(a):(d=true,(c))):(d=true,(b)))
#define RT_PI 3.141592653589
bool ImProcFunctions::transCoord (int W, int H, std::vector<Coord2D> &src, std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, double ascaleDef) { bool ImProcFunctions::transCoord (int W, int H, std::vector<Coord2D> &src, std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, double ascaleDef) {
@@ -50,23 +51,6 @@ bool ImProcFunctions::transCoord (int W, int H, std::vector<Coord2D> &src, std::
if (!needsCA() && !needsDistortion() && !needsRotation() && !needsPerspective()) { if (!needsCA() && !needsDistortion() && !needsRotation() && !needsPerspective()) {
if (clipresize) { if (clipresize) {
// Apply resizing
if (fabs(params->resize.scale-1.0)>=1e-7) {
for (int i=0; i<src.size(); i++) {
red.push_back (Coord2D (src[i].x / params->resize.scale, src[i].y / params->resize.scale));
green.push_back (Coord2D (src[i].x / params->resize.scale, src[i].y / params->resize.scale));
blue.push_back (Coord2D (src[i].x / params->resize.scale, src[i].y / params->resize.scale));
}
for (int i=0; i<src.size(); i++) {
red[i].x = CLIPTOC(red[i].x,0,W-1,clipped);
red[i].y = CLIPTOC(red[i].y,0,H-1,clipped);
green[i].x = CLIPTOC(green[i].x,0,W-1,clipped);
green[i].y = CLIPTOC(green[i].y,0,H-1,clipped);
blue[i].x = CLIPTOC(blue[i].x,0,W-1,clipped);
blue[i].y = CLIPTOC(blue[i].y,0,H-1,clipped);
}
}
else
for (int i=0; i<src.size(); i++) { for (int i=0; i<src.size(); i++) {
red.push_back (Coord2D (src[i].x, src[i].y)); red.push_back (Coord2D (src[i].x, src[i].y));
green.push_back (Coord2D (src[i].x, src[i].y)); green.push_back (Coord2D (src[i].x, src[i].y));
@@ -76,21 +60,21 @@ bool ImProcFunctions::transCoord (int W, int H, std::vector<Coord2D> &src, std::
return clipped; return clipped;
} }
double oW = W*params->resize.scale; double oW = W;
double oH = H*params->resize.scale; double oH = H;
double w2 = (double) oW / 2.0 - 0.5; double w2 = (double) oW / 2.0 - 0.5;
double h2 = (double) oH / 2.0 - 0.5; double h2 = (double) oH / 2.0 - 0.5;
double a = params->distortion.amount; double a = params->distortion.amount;
double cost = cos(params->rotate.degree * 3.14/180.0); double cost = cos(params->rotate.degree * RT_PI/180.0);
double sint = sin(params->rotate.degree * 3.14/180.0); double sint = sin(params->rotate.degree * RT_PI/180.0);
double maxRadius = sqrt( (double)( oW*oW + oH*oH ) ) / 2; double maxRadius = sqrt( (double)( oW*oW + oH*oH ) ) / 2;
double vpdeg = params->perspective.vertical / 100.0 * 45.0; double vpdeg = params->perspective.vertical / 100.0 * 45.0;
double vpalpha = (90.0 - vpdeg) / 180.0 * 3.14; double vpalpha = (90.0 - vpdeg) / 180.0 * RT_PI;
double vpteta = fabs(vpalpha-3.14/2)<1e-3 ? 0.0 : acos ((vpdeg>0 ? 1.0 : -1.0) * sqrt((-oW*oW*tan(vpalpha)*tan(vpalpha) + (vpdeg>0 ? 1.0 : -1.0) * oW*tan(vpalpha)*sqrt(16*maxRadius*maxRadius+oW*oW*tan(vpalpha)*tan(vpalpha)))/(maxRadius*maxRadius*8))); double vpteta = fabs(vpalpha-RT_PI/2)<1e-3 ? 0.0 : acos ((vpdeg>0 ? 1.0 : -1.0) * sqrt((-oW*oW*tan(vpalpha)*tan(vpalpha) + (vpdeg>0 ? 1.0 : -1.0) * oW*tan(vpalpha)*sqrt(16*maxRadius*maxRadius+oW*oW*tan(vpalpha)*tan(vpalpha)))/(maxRadius*maxRadius*8)));
double vpcospt = (vpdeg>=0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta); double vpcospt = (vpdeg>=0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta);
double hpdeg = params->perspective.horizontal / 100.0 * 45.0; double hpdeg = params->perspective.horizontal / 100.0 * 45.0;
double hpalpha = (90.0 - hpdeg) / 180.0 * 3.14; double hpalpha = (90.0 - hpdeg) / 180.0 * RT_PI;
double hpteta = fabs(hpalpha-3.14/2)<1e-3 ? 0.0 : acos ((hpdeg>0 ? 1.0 : -1.0) * sqrt((-oH*oH*tan(hpalpha)*tan(hpalpha) + (hpdeg>0 ? 1.0 : -1.0) * oH*tan(hpalpha)*sqrt(16*maxRadius*maxRadius+oH*oH*tan(hpalpha)*tan(hpalpha)))/(maxRadius*maxRadius*8))); double hpteta = fabs(hpalpha-RT_PI/2)<1e-3 ? 0.0 : acos ((hpdeg>0 ? 1.0 : -1.0) * sqrt((-oH*oH*tan(hpalpha)*tan(hpalpha) + (hpdeg>0 ? 1.0 : -1.0) * oH*tan(hpalpha)*sqrt(16*maxRadius*maxRadius+oH*oH*tan(hpalpha)*tan(hpalpha)))/(maxRadius*maxRadius*8)));
double hpcospt = (hpdeg>=0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta); double hpcospt = (hpdeg>=0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta);
double ascale = ascaleDef>0 ? ascaleDef : (params->commonTrans.autofill ? getTransformAutoFill (oW, oH) : 1.0); double ascale = ascaleDef>0 ? ascaleDef : (params->commonTrans.autofill ? getTransformAutoFill (oW, oH) : 1.0);
@@ -118,16 +102,6 @@ bool ImProcFunctions::transCoord (int W, int H, std::vector<Coord2D> &src, std::
} }
if (clipresize) { if (clipresize) {
if (fabs(params->resize.scale-1.0)>=1e-7) {
for (int i=0; i<src.size(); i++) {
red[i].x /= params->resize.scale;
red[i].y /= params->resize.scale;
green[i].x /= params->resize.scale;
green[i].y /= params->resize.scale;
blue[i].x /= params->resize.scale;
blue[i].y /= params->resize.scale;
}
}
for (int i=0; i<src.size(); i++) { for (int i=0; i<src.size(); i++) {
red[i].x = CLIPTOC(red[i].x,0,W-1,clipped); red[i].x = CLIPTOC(red[i].x,0,W-1,clipped);
red[i].y = CLIPTOC(red[i].y,0,H-1,clipped); red[i].y = CLIPTOC(red[i].y,0,H-1,clipped);
@@ -287,21 +261,21 @@ void ImProcFunctions::transformNonSep (Image16* original, Image16* transformed,
double a = params->distortion.amount; double a = params->distortion.amount;
// auxiliary variables for rotation // auxiliary variables for rotation
double cost = cos(params->rotate.degree * 3.14/180.0); double cost = cos(params->rotate.degree * RT_PI/180.0);
double sint = sin(params->rotate.degree * 3.14/180.0); double sint = sin(params->rotate.degree * RT_PI/180.0);
bool dovign = params->vignetting.amount != 0; bool dovign = params->vignetting.amount != 0;
// auxiliary variables for vertical perspective correction // auxiliary variables for vertical perspective correction
double vpdeg = params->perspective.vertical / 100.0 * 45.0; double vpdeg = params->perspective.vertical / 100.0 * 45.0;
double vpalpha = (90.0 - vpdeg) / 180.0 * 3.14; double vpalpha = (90.0 - vpdeg) / 180.0 * RT_PI;
double vpteta = fabs(vpalpha-3.14/2)<1e-3 ? 0.0 : acos ((vpdeg>0 ? 1.0 : -1.0) * sqrt((-oW*oW*tan(vpalpha)*tan(vpalpha) + (vpdeg>0 ? 1.0 : -1.0) * oW*tan(vpalpha)*sqrt(16*maxRadius*maxRadius+oW*oW*tan(vpalpha)*tan(vpalpha)))/(maxRadius*maxRadius*8))); double vpteta = fabs(vpalpha-RT_PI/2)<1e-3 ? 0.0 : acos ((vpdeg>0 ? 1.0 : -1.0) * sqrt((-oW*oW*tan(vpalpha)*tan(vpalpha) + (vpdeg>0 ? 1.0 : -1.0) * oW*tan(vpalpha)*sqrt(16*maxRadius*maxRadius+oW*oW*tan(vpalpha)*tan(vpalpha)))/(maxRadius*maxRadius*8)));
double vpcospt = (vpdeg>=0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta); double vpcospt = (vpdeg>=0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta);
// auxiliary variables for horizontal perspective correction // auxiliary variables for horizontal perspective correction
double hpdeg = params->perspective.horizontal / 100.0 * 45.0; double hpdeg = params->perspective.horizontal / 100.0 * 45.0;
double hpalpha = (90.0 - hpdeg) / 180.0 * 3.14; double hpalpha = (90.0 - hpdeg) / 180.0 * RT_PI;
double hpteta = fabs(hpalpha-3.14/2)<1e-3 ? 0.0 : acos ((hpdeg>0 ? 1.0 : -1.0) * sqrt((-oH*oH*tan(hpalpha)*tan(hpalpha) + (hpdeg>0 ? 1.0 : -1.0) * oH*tan(hpalpha)*sqrt(16*maxRadius*maxRadius+oH*oH*tan(hpalpha)*tan(hpalpha)))/(maxRadius*maxRadius*8))); double hpteta = fabs(hpalpha-RT_PI/2)<1e-3 ? 0.0 : acos ((hpdeg>0 ? 1.0 : -1.0) * sqrt((-oH*oH*tan(hpalpha)*tan(hpalpha) + (hpdeg>0 ? 1.0 : -1.0) * oH*tan(hpalpha)*sqrt(16*maxRadius*maxRadius+oH*oH*tan(hpalpha)*tan(hpalpha)))/(maxRadius*maxRadius*8)));
double hpcospt = (hpdeg>=0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta); double hpcospt = (hpdeg>=0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta);
double ascale = params->commonTrans.autofill ? getTransformAutoFill (oW, oH) : 1.0; double ascale = params->commonTrans.autofill ? getTransformAutoFill (oW, oH) : 1.0;
@@ -410,21 +384,21 @@ void ImProcFunctions::transformSep (Image16* original, Image16* transformed, int
double a = params->distortion.amount; double a = params->distortion.amount;
// auxiliary variables for rotation // auxiliary variables for rotation
double cost = cos(params->rotate.degree * 3.14/180.0); double cost = cos(params->rotate.degree * RT_PI/180.0);
double sint = sin(params->rotate.degree * 3.14/180.0); double sint = sin(params->rotate.degree * RT_PI/180.0);
bool dovign = params->vignetting.amount != 0; bool dovign = params->vignetting.amount != 0;
// auxiliary variables for vertical perspective correction // auxiliary variables for vertical perspective correction
double vpdeg = params->perspective.vertical / 100.0 * 45.0; double vpdeg = params->perspective.vertical / 100.0 * 45.0;
double vpalpha = (90.0 - vpdeg) / 180.0 * 3.14; double vpalpha = (90.0 - vpdeg) / 180.0 * RT_PI;
double vpteta = fabs(vpalpha-3.14/2)<1e-3 ? 0.0 : acos ((vpdeg>0 ? 1.0 : -1.0) * sqrt((-oW*oW*tan(vpalpha)*tan(vpalpha) + (vpdeg>0 ? 1.0 : -1.0) * oW*tan(vpalpha)*sqrt(16*maxRadius*maxRadius+oW*oW*tan(vpalpha)*tan(vpalpha)))/(maxRadius*maxRadius*8))); double vpteta = fabs(vpalpha-RT_PI/2)<1e-3 ? 0.0 : acos ((vpdeg>0 ? 1.0 : -1.0) * sqrt((-oW*oW*tan(vpalpha)*tan(vpalpha) + (vpdeg>0 ? 1.0 : -1.0) * oW*tan(vpalpha)*sqrt(16*maxRadius*maxRadius+oW*oW*tan(vpalpha)*tan(vpalpha)))/(maxRadius*maxRadius*8)));
double vpcospt = (vpdeg>=0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta); double vpcospt = (vpdeg>=0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta);
// auxiliary variables for horizontal perspective correction // auxiliary variables for horizontal perspective correction
double hpdeg = params->perspective.horizontal / 100.0 * 45.0; double hpdeg = params->perspective.horizontal / 100.0 * 45.0;
double hpalpha = (90.0 - hpdeg) / 180.0 * 3.14; double hpalpha = (90.0 - hpdeg) / 180.0 * RT_PI;
double hpteta = fabs(hpalpha-3.14/2)<1e-3 ? 0.0 : acos ((hpdeg>0 ? 1.0 : -1.0) * sqrt((-oH*oH*tan(hpalpha)*tan(hpalpha) + (hpdeg>0 ? 1.0 : -1.0) * oH*tan(hpalpha)*sqrt(16*maxRadius*maxRadius+oH*oH*tan(hpalpha)*tan(hpalpha)))/(maxRadius*maxRadius*8))); double hpteta = fabs(hpalpha-RT_PI/2)<1e-3 ? 0.0 : acos ((hpdeg>0 ? 1.0 : -1.0) * sqrt((-oH*oH*tan(hpalpha)*tan(hpalpha) + (hpdeg>0 ? 1.0 : -1.0) * oH*tan(hpalpha)*sqrt(16*maxRadius*maxRadius+oH*oH*tan(hpalpha)*tan(hpalpha)))/(maxRadius*maxRadius*8)));
double hpcospt = (hpdeg>=0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta); double hpcospt = (hpdeg>=0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta);
double ascale = params->commonTrans.autofill ? getTransformAutoFill (oW, oH) : 1.0; double ascale = params->commonTrans.autofill ? getTransformAutoFill (oW, oH) : 1.0;
@@ -515,21 +489,21 @@ void ImProcFunctions::simpltransform (Image16* original, Image16* transformed, i
double a = params->distortion.amount; double a = params->distortion.amount;
// auxiliary variables for rotation // auxiliary variables for rotation
double cost = cos(params->rotate.degree * 3.14/180.0); double cost = cos(params->rotate.degree * RT_PI/180.0);
double sint = sin(params->rotate.degree * 3.14/180.0); double sint = sin(params->rotate.degree * RT_PI/180.0);
bool dovign = params->vignetting.amount != 0; bool dovign = params->vignetting.amount != 0;
// auxiliary variables for vertical perspective correction // auxiliary variables for vertical perspective correction
double vpdeg = params->perspective.vertical / 100.0 * 45.0; double vpdeg = params->perspective.vertical / 100.0 * 45.0;
double vpalpha = (90 - vpdeg) / 180.0 * 3.14; double vpalpha = (90 - vpdeg) / 180.0 * RT_PI;
double vpteta = fabs(vpalpha-3.14/2)<1e-3 ? 0.0 : acos ((vpdeg>0 ? 1.0 : -1.0) * sqrt((-oW*oW*tan(vpalpha)*tan(vpalpha) + (vpdeg>0 ? 1.0 : -1.0) * oW*tan(vpalpha)*sqrt(16*maxRadius*maxRadius+oW*oW*tan(vpalpha)*tan(vpalpha)))/(maxRadius*maxRadius*8))); double vpteta = fabs(vpalpha-RT_PI/2)<1e-3 ? 0.0 : acos ((vpdeg>0 ? 1.0 : -1.0) * sqrt((-oW*oW*tan(vpalpha)*tan(vpalpha) + (vpdeg>0 ? 1.0 : -1.0) * oW*tan(vpalpha)*sqrt(16*maxRadius*maxRadius+oW*oW*tan(vpalpha)*tan(vpalpha)))/(maxRadius*maxRadius*8)));
double vpcospt = (vpdeg>=0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta); double vpcospt = (vpdeg>=0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta);
// auxiliary variables for horizontal perspective correction // auxiliary variables for horizontal perspective correction
double hpdeg = params->perspective.horizontal / 100.0 * 45.0; double hpdeg = params->perspective.horizontal / 100.0 * 45.0;
double hpalpha = (90 - hpdeg) / 180.0 * 3.14; double hpalpha = (90 - hpdeg) / 180.0 * RT_PI;
double hpteta = fabs(hpalpha-3.14/2)<1e-3 ? 0.0 : acos ((hpdeg>0 ? 1.0 : -1.0) * sqrt((-oH*oH*tan(hpalpha)*tan(hpalpha) + (hpdeg>0 ? 1.0 : -1.0) * oH*tan(hpalpha)*sqrt(16*maxRadius*maxRadius+oH*oH*tan(hpalpha)*tan(hpalpha)))/(maxRadius*maxRadius*8))); double hpteta = fabs(hpalpha-RT_PI/2)<1e-3 ? 0.0 : acos ((hpdeg>0 ? 1.0 : -1.0) * sqrt((-oH*oH*tan(hpalpha)*tan(hpalpha) + (hpdeg>0 ? 1.0 : -1.0) * oH*tan(hpalpha)*sqrt(16*maxRadius*maxRadius+oH*oH*tan(hpalpha)*tan(hpalpha)))/(maxRadius*maxRadius*8)));
double hpcospt = (hpdeg>=0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta); double hpcospt = (hpdeg>=0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta);
double ascale = params->commonTrans.autofill ? getTransformAutoFill (oW, oH) : 1.0; double ascale = params->commonTrans.autofill ? getTransformAutoFill (oW, oH) : 1.0;

View File

@@ -129,7 +129,9 @@ enum ProcEvent {
EvDefringeEnabled=104, EvDefringeEnabled=104,
EvDefringeRadius=105, EvDefringeRadius=105,
EvDefringeThreshold=106, EvDefringeThreshold=106,
NUMOFEVENTS=107 EvResizeBoundingBox=107,
EvResizeAppliesTo=108,
NUMOFEVENTS=109
}; };
} }
#endif #endif

View File

@@ -170,6 +170,7 @@ void ProcParams::setDefaults () {
resize.enabled = false; resize.enabled = false;
resize.scale = 1.0; resize.scale = 1.0;
resize.appliesTo = "Cropped area";
resize.method = "Bicubic"; resize.method = "Bicubic";
resize.dataspec = 0; resize.dataspec = 0;
resize.width = 800; resize.width = 800;
@@ -369,6 +370,7 @@ int ProcParams::save (Glib::ustring fname) const {
keyFile.set_boolean ("Resize", "Enabled",resize.enabled); keyFile.set_boolean ("Resize", "Enabled",resize.enabled);
keyFile.set_double ("Resize", "Scale", resize.scale); keyFile.set_double ("Resize", "Scale", resize.scale);
keyFile.set_string ("Resize", "AppliesTo", resize.appliesTo);
keyFile.set_string ("Resize", "Method", resize.method); keyFile.set_string ("Resize", "Method", resize.method);
keyFile.set_integer ("Resize", "DataSpecified", resize.dataspec); keyFile.set_integer ("Resize", "DataSpecified", resize.dataspec);
keyFile.set_integer ("Resize", "Width", resize.width); keyFile.set_integer ("Resize", "Width", resize.width);
@@ -676,6 +678,7 @@ if (keyFile.has_group ("HLRecovery")) {
if (keyFile.has_group ("Resize")) { if (keyFile.has_group ("Resize")) {
if (keyFile.has_key ("Resize", "Enabled")) resize.enabled = keyFile.get_boolean ("Resize", "Enabled"); if (keyFile.has_key ("Resize", "Enabled")) resize.enabled = keyFile.get_boolean ("Resize", "Enabled");
if (keyFile.has_key ("Resize", "Scale")) resize.scale = keyFile.get_double ("Resize", "Scale"); if (keyFile.has_key ("Resize", "Scale")) resize.scale = keyFile.get_double ("Resize", "Scale");
if (keyFile.has_key ("Resize", "AppliesTo")) resize.appliesTo = keyFile.get_string ("Resize", "AppliesTo");
if (keyFile.has_key ("Resize", "Method")) resize.method = keyFile.get_string ("Resize", "Method"); if (keyFile.has_key ("Resize", "Method")) resize.method = keyFile.get_string ("Resize", "Method");
if (keyFile.has_key ("Resize", "DataSpecified")) resize.dataspec = keyFile.get_integer ("Resize", "DataSpecified"); if (keyFile.has_key ("Resize", "DataSpecified")) resize.dataspec = keyFile.get_integer ("Resize", "DataSpecified");
if (keyFile.has_key ("Resize", "Width")) resize.width = keyFile.get_integer ("Resize", "Width"); if (keyFile.has_key ("Resize", "Width")) resize.width = keyFile.get_integer ("Resize", "Width");
@@ -828,127 +831,128 @@ bool operator==(const IPTCPair& a, const IPTCPair& b) {
} }
bool ProcParams::operator== (const ProcParams& other) { bool ProcParams::operator== (const ProcParams& other) {
return return
toneCurve.curve == other.toneCurve.curve toneCurve.curve == other.toneCurve.curve
&& toneCurve.brightness == other.toneCurve.brightness && toneCurve.brightness == other.toneCurve.brightness
&& toneCurve.black == other.toneCurve.black && toneCurve.black == other.toneCurve.black
&& toneCurve.contrast == other.toneCurve.contrast && toneCurve.contrast == other.toneCurve.contrast
&& toneCurve.saturation == other.toneCurve.saturation && toneCurve.saturation == other.toneCurve.saturation
&& toneCurve.shcompr == other.toneCurve.shcompr && toneCurve.shcompr == other.toneCurve.shcompr
&& toneCurve.hlcompr == other.toneCurve.hlcompr && toneCurve.hlcompr == other.toneCurve.hlcompr
&& toneCurve.autoexp == other.toneCurve.autoexp && toneCurve.autoexp == other.toneCurve.autoexp
&& toneCurve.clip == other.toneCurve.clip && toneCurve.clip == other.toneCurve.clip
&& toneCurve.expcomp == other.toneCurve.expcomp && toneCurve.expcomp == other.toneCurve.expcomp
&& labCurve.lcurve == other.labCurve.lcurve && labCurve.lcurve == other.labCurve.lcurve
&& labCurve.acurve == other.labCurve.acurve && labCurve.acurve == other.labCurve.acurve
&& labCurve.bcurve == other.labCurve.bcurve && labCurve.bcurve == other.labCurve.bcurve
&& labCurve.brightness == other.labCurve.brightness && labCurve.brightness == other.labCurve.brightness
&& labCurve.contrast == other.labCurve.contrast && labCurve.contrast == other.labCurve.contrast
&& labCurve.saturation == other.labCurve.saturation && labCurve.saturation == other.labCurve.saturation
&& sharpening.enabled == other.sharpening.enabled && sharpening.enabled == other.sharpening.enabled
&& sharpening.radius == other.sharpening.radius && sharpening.radius == other.sharpening.radius
&& sharpening.amount == other.sharpening.amount && sharpening.amount == other.sharpening.amount
&& sharpening.threshold == other.sharpening.threshold && sharpening.threshold == other.sharpening.threshold
&& sharpening.edgesonly == other.sharpening.edgesonly && sharpening.edgesonly == other.sharpening.edgesonly
&& sharpening.edges_radius == other.sharpening.edges_radius && sharpening.edges_radius == other.sharpening.edges_radius
&& sharpening.edges_tolerance == other.sharpening.edges_tolerance && sharpening.edges_tolerance == other.sharpening.edges_tolerance
&& sharpening.halocontrol == other.sharpening.halocontrol && sharpening.halocontrol == other.sharpening.halocontrol
&& sharpening.halocontrol_amount== other.sharpening.halocontrol_amount && sharpening.halocontrol_amount== other.sharpening.halocontrol_amount
&& sharpening.method == other.sharpening.method && sharpening.method == other.sharpening.method
&& sharpening.deconvamount == other.sharpening.deconvamount && sharpening.deconvamount == other.sharpening.deconvamount
&& sharpening.deconvradius == other.sharpening.deconvradius && sharpening.deconvradius == other.sharpening.deconvradius
&& sharpening.deconviter == other.sharpening.deconviter && sharpening.deconviter == other.sharpening.deconviter
&& sharpening.deconvdamping == other.sharpening.deconvdamping && sharpening.deconvdamping == other.sharpening.deconvdamping
&& colorBoost.amount == other.colorBoost.amount && colorBoost.amount == other.colorBoost.amount
&& colorBoost.avoidclip == other.colorBoost.avoidclip && colorBoost.avoidclip == other.colorBoost.avoidclip
&& colorBoost.enable_saturationlimiter == other.colorBoost.enable_saturationlimiter && colorBoost.enable_saturationlimiter == other.colorBoost.enable_saturationlimiter
&& colorBoost.saturationlimit == other.colorBoost.saturationlimit && colorBoost.saturationlimit == other.colorBoost.saturationlimit
&& wb.method == other.wb.method && wb.method == other.wb.method
&& wb.green == other.wb.green && wb.green == other.wb.green
&& wb.temperature == other.wb.temperature && wb.temperature == other.wb.temperature
&& colorShift.a == other.colorShift.a && colorShift.a == other.colorShift.a
&& colorShift.b == other.colorShift.b && colorShift.b == other.colorShift.b
&& impulseDenoise.enabled == other.impulseDenoise.enabled && impulseDenoise.enabled == other.impulseDenoise.enabled
&& impulseDenoise.thresh == other.impulseDenoise.thresh && impulseDenoise.thresh == other.impulseDenoise.thresh
&& dirpyrDenoise.enabled == other.dirpyrDenoise.enabled && dirpyrDenoise.enabled == other.dirpyrDenoise.enabled
&& dirpyrDenoise.luma == other.dirpyrDenoise.luma && dirpyrDenoise.luma == other.dirpyrDenoise.luma
&& dirpyrDenoise.chroma == other.dirpyrDenoise.chroma && dirpyrDenoise.chroma == other.dirpyrDenoise.chroma
&& dirpyrDenoise.gamma == other.dirpyrDenoise.gamma && dirpyrDenoise.gamma == other.dirpyrDenoise.gamma
&& defringe.enabled == other.defringe.enabled && defringe.enabled == other.defringe.enabled
&& defringe.radius == other.defringe.radius && defringe.radius == other.defringe.radius
&& defringe.threshold == other.defringe.threshold && defringe.threshold == other.defringe.threshold
&& lumaDenoise.enabled == other.lumaDenoise.enabled && lumaDenoise.enabled == other.lumaDenoise.enabled
&& lumaDenoise.radius == other.lumaDenoise.radius && lumaDenoise.radius == other.lumaDenoise.radius
&& lumaDenoise.edgetolerance == other.lumaDenoise.edgetolerance && lumaDenoise.edgetolerance == other.lumaDenoise.edgetolerance
&& colorDenoise.enabled == other.colorDenoise.enabled && colorDenoise.enabled == other.colorDenoise.enabled
&& colorDenoise.radius == other.colorDenoise.radius && colorDenoise.radius == other.colorDenoise.radius
&& colorDenoise.edgetolerance == other.colorDenoise.edgetolerance && colorDenoise.edgetolerance == other.colorDenoise.edgetolerance
&& colorDenoise.edgesensitive == other.colorDenoise.edgesensitive && colorDenoise.edgesensitive == other.colorDenoise.edgesensitive
&& sh.enabled == other.sh.enabled && sh.enabled == other.sh.enabled
&& sh.hq == other.sh.hq && sh.hq == other.sh.hq
&& sh.highlights == other.sh.highlights && sh.highlights == other.sh.highlights
&& sh.htonalwidth == other.sh.htonalwidth && sh.htonalwidth == other.sh.htonalwidth
&& sh.shadows == other.sh.shadows && sh.shadows == other.sh.shadows
&& sh.stonalwidth == other.sh.stonalwidth && sh.stonalwidth == other.sh.stonalwidth
&& sh.localcontrast == other.sh.localcontrast && sh.localcontrast == other.sh.localcontrast
&& sh.radius == other.sh.radius && sh.radius == other.sh.radius
&& crop.enabled == other.crop.enabled && crop.enabled == other.crop.enabled
&& crop.x == other.crop.x && crop.x == other.crop.x
&& crop.y == other.crop.y && crop.y == other.crop.y
&& crop.w == other.crop.w && crop.w == other.crop.w
&& crop.h == other.crop.h && crop.h == other.crop.h
&& crop.fixratio == other.crop.fixratio && crop.fixratio == other.crop.fixratio
&& crop.ratio == other.crop.ratio && crop.ratio == other.crop.ratio
&& crop.orientation == other.crop.orientation && crop.orientation == other.crop.orientation
&& crop.guide == other.crop.guide && crop.guide == other.crop.guide
&& coarse.rotate == other.coarse.rotate && coarse.rotate == other.coarse.rotate
&& coarse.hflip == other.coarse.hflip && coarse.hflip == other.coarse.hflip
&& coarse.vflip == other.coarse.vflip && coarse.vflip == other.coarse.vflip
&& rotate.degree == other.rotate.degree && rotate.degree == other.rotate.degree
&& commonTrans.autofill == other.commonTrans.autofill && commonTrans.autofill == other.commonTrans.autofill
&& distortion.uselensfun == other.distortion.uselensfun && distortion.uselensfun == other.distortion.uselensfun
&& distortion.amount == other.distortion.amount && distortion.amount == other.distortion.amount
&& perspective.horizontal == other.perspective.horizontal && perspective.horizontal == other.perspective.horizontal
&& perspective.vertical == other.perspective.vertical && perspective.vertical == other.perspective.vertical
&& cacorrection.red == other.cacorrection.red && cacorrection.red == other.cacorrection.red
&& cacorrection.blue == other.cacorrection.blue && cacorrection.blue == other.cacorrection.blue
&& vignetting.amount == other.vignetting.amount && vignetting.amount == other.vignetting.amount
&& vignetting.radius == other.vignetting.radius && vignetting.radius == other.vignetting.radius
&& vignetting.strength == other.vignetting.strength && vignetting.strength == other.vignetting.strength
&& vignetting.centerX == other.vignetting.centerX && vignetting.centerX == other.vignetting.centerX
&& vignetting.centerY == other.vignetting.centerY && vignetting.centerY == other.vignetting.centerY
&& !memcmp (&chmixer.red, &other.chmixer.red, 3*sizeof(int)) && !memcmp (&chmixer.red, &other.chmixer.red, 3*sizeof(int))
&& !memcmp (&chmixer.green, &other.chmixer.green, 3*sizeof(int)) && !memcmp (&chmixer.green, &other.chmixer.green, 3*sizeof(int))
&& !memcmp (&chmixer.blue, &other.chmixer.blue, 3*sizeof(int)) && !memcmp (&chmixer.blue, &other.chmixer.blue, 3*sizeof(int))
&& hlrecovery.enabled == other.hlrecovery.enabled && hlrecovery.enabled == other.hlrecovery.enabled
&& hlrecovery.method == other.hlrecovery.method && hlrecovery.method == other.hlrecovery.method
&& resize.scale == other.resize.scale && resize.scale == other.resize.scale
&& resize.method == other.resize.method && resize.appliesTo == other.resize.appliesTo
&& resize.dataspec == other.resize.dataspec && resize.method == other.resize.method
&& resize.width == other.resize.width && resize.dataspec == other.resize.dataspec
&& resize.height == other.resize.height && resize.width == other.resize.width
&& raw.dark_frame == other.raw.dark_frame && resize.height == other.resize.height
&& raw.df_autoselect == other.raw.df_autoselect && raw.dark_frame == other.raw.dark_frame
&& raw.dcb_enhance == other.raw.dcb_enhance && raw.df_autoselect == other.raw.df_autoselect
&& raw.dcb_iterations == other.raw.dcb_iterations && raw.dcb_enhance == other.raw.dcb_enhance
&& raw.ccSteps == other.raw.ccSteps && raw.dcb_iterations == other.raw.dcb_iterations
&& raw.ca_autocorrect == other.raw.ca_autocorrect && raw.ccSteps == other.raw.ccSteps
&& raw.cared == other.raw.cared && raw.ca_autocorrect == other.raw.ca_autocorrect
&& raw.cablue == other.raw.cablue && raw.cared == other.raw.cared
&& raw.hotdeadpix_filt == other.raw.hotdeadpix_filt && raw.cablue == other.raw.cablue
&& raw.dmethod == other.raw.dmethod && raw.hotdeadpix_filt == other.raw.hotdeadpix_filt
&& raw.greenthresh == other.raw.greenthresh && raw.dmethod == other.raw.dmethod
&& raw.linenoise == other.raw.linenoise && raw.greenthresh == other.raw.greenthresh
&& icm.input == other.icm.input && raw.linenoise == other.raw.linenoise
&& icm.gammaOnInput == other.icm.gammaOnInput && icm.input == other.icm.input
&& icm.working == other.icm.working && icm.gammaOnInput == other.icm.gammaOnInput
&& icm.output == other.icm.output && icm.working == other.icm.working
&& equalizer == other.equalizer && icm.output == other.icm.output
&& dirpyrequalizer == other.dirpyrequalizer && equalizer == other.equalizer
&& hsvequalizer == other.hsvequalizer && dirpyrequalizer == other.dirpyrequalizer
&& exif==other.exif && hsvequalizer == other.hsvequalizer
&& iptc==other.iptc; && exif==other.exif
} && iptc==other.iptc;
}
bool ProcParams::operator!= (const ProcParams& other) { bool ProcParams::operator!= (const ProcParams& other) {

View File

@@ -306,6 +306,7 @@ class ResizeParams {
public: public:
bool enabled; bool enabled;
double scale; double scale;
Glib::ustring appliesTo;
Glib::ustring method; Glib::ustring method;
int dataspec; int dataspec;
int width; int width;
@@ -409,38 +410,38 @@ class RAWParams {
class ProcParams { class ProcParams {
public: public:
ToneCurveParams toneCurve; ///< Tone curve parameters ToneCurveParams toneCurve; ///< Tone curve parameters
LCurveParams labCurve; ///< CIELAB luminance curve parameters LCurveParams labCurve; ///< CIELAB luminance curve parameters
SharpeningParams sharpening; ///< Sharpening parameters SharpeningParams sharpening; ///< Sharpening parameters
ColorBoostParams colorBoost; ///< Color boost parameters ColorBoostParams colorBoost; ///< Color boost parameters
WBParams wb; ///< White balance parameters WBParams wb; ///< White balance parameters
ColorShiftParams colorShift; ///< Color shift parameters ColorShiftParams colorShift; ///< Color shift parameters
LumaDenoiseParams lumaDenoise; ///< Luminance denoising parameters LumaDenoiseParams lumaDenoise; ///< Luminance denoising parameters
ColorDenoiseParams colorDenoise; ///< Color denoising parameters ColorDenoiseParams colorDenoise; ///< Color denoising parameters
DefringeParams defringe; ///< Defringing parameters DefringeParams defringe; ///< Defringing parameters
ImpulseDenoiseParams impulseDenoise; ///< Impulse denoising parameters ImpulseDenoiseParams impulseDenoise; ///< Impulse denoising parameters
DirPyrDenoiseParams dirpyrDenoise; ///< Directional Pyramid denoising parameters DirPyrDenoiseParams dirpyrDenoise; ///< Directional Pyramid denoising parameters
SHParams sh; ///< Shadow/highlight enhancement parameters SHParams sh; ///< Shadow/highlight enhancement parameters
CropParams crop; ///< Crop parameters CropParams crop; ///< Crop parameters
CoarseTransformParams coarse; ///< Coarse transformation (90, 180, 270 deg rotation, h/v flipping) parameters CoarseTransformParams coarse; ///< Coarse transformation (90, 180, 270 deg rotation, h/v flipping) parameters
CommonTransformParams commonTrans; ///< Common transformation parameters (autofill) CommonTransformParams commonTrans; ///< Common transformation parameters (autofill)
RotateParams rotate; ///< Rotation parameters RotateParams rotate; ///< Rotation parameters
DistortionParams distortion; ///< Lens distortion correction parameters DistortionParams distortion; ///< Lens distortion correction parameters
PerspectiveParams perspective; ///< Perspective correction parameters PerspectiveParams perspective; ///< Perspective correction parameters
CACorrParams cacorrection; ///< Lens c/a correction parameters CACorrParams cacorrection; ///< Lens c/a correction parameters
VignettingParams vignetting; ///< Lens vignetting correction parameters VignettingParams vignetting; ///< Lens vignetting correction parameters
ChannelMixerParams chmixer; ///< Channel mixer parameters ChannelMixerParams chmixer; ///< Channel mixer parameters
HRecParams hlrecovery; ///< Highlight recovery parameters HRecParams hlrecovery; ///< Highlight recovery parameters
ResizeParams resize; ///< Resize parameters ResizeParams resize; ///< Resize parameters
ColorManagementParams icm; ///< profiles/color spaces used during the image processing ColorManagementParams icm; ///< profiles/color spaces used during the image processing
EqualizerParams equalizer; ///< wavelet equalizer parameters EqualizerParams equalizer; ///< wavelet equalizer parameters
RAWParams raw; ///< RAW parameters before demosaicing RAWParams raw; ///< RAW parameters before demosaicing
DirPyrEqualizerParams dirpyrequalizer; ///< directional pyramid equalizer parameters DirPyrEqualizerParams dirpyrequalizer; ///< directional pyramid equalizer parameters
HSVEqualizerParams hsvequalizer; ///< hsv equalizer parameters HSVEqualizerParams hsvequalizer; ///< hsv equalizer parameters
std::vector<ExifPair> exif; ///< List of modifications appplied on the exif tags of the input image std::vector<ExifPair> exif; ///< List of modifications appplied on the exif tags of the input image
std::vector<IPTCPair> iptc; ///< The IPTC tags and values to be saved to the output image std::vector<IPTCPair> 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 int version; ///< Version of the file from which the parameters have been read
/** /**
* The constructor only sets the hand-wired defaults. * The constructor only sets the hand-wired defaults.
*/ */

View File

@@ -93,14 +93,14 @@ ALL, // EvOProfile,
ALL, // EvIProfile, ALL, // EvIProfile,
TRANSFORM, // EvVignetting, TRANSFORM, // EvVignetting,
RGBCURVE, // EvChMixer, RGBCURVE, // EvChMixer,
ALL, // EvResizeScale, RESIZE, // EvResizeScale,
ALL, // EvResizeMethod, RESIZE, // EvResizeMethod,
EXIF, // EvExif, EXIF, // EvExif,
IPTC, // EvIPTC IPTC, // EvIPTC
ALL, // EvResizeSpec, RESIZE, // EvResizeSpec,
ALL, // EvResizeWidth RESIZE, // EvResizeWidth
ALL, // EvResizeHeight RESIZE, // EvResizeHeight
ALL, // EvResizeEnabled RESIZE, // EvResizeEnabled
ALL, // EvProfileChangeNotification ALL, // EvProfileChangeNotification
RETINEX, // EvShrHighQuality RETINEX, // EvShrHighQuality
TRANSFORM, // EvPerspCorr TRANSFORM, // EvPerspCorr
@@ -127,5 +127,6 @@ RGBCURVE, // EvHSVEqEnabled,
DEFRINGE, // EvDefringeEnabled, DEFRINGE, // EvDefringeEnabled,
DEFRINGE, // EvDefringeRadius, DEFRINGE, // EvDefringeRadius,
DEFRINGE, // EvDefringeThreshold, DEFRINGE, // EvDefringeThreshold,
RESIZE, // EvResizeBoundingBox
RESIZE // EvResizeAppliesTo
}; };

View File

@@ -59,6 +59,7 @@
#define COLORDENOISE M_COLOR #define COLORDENOISE M_COLOR
#define DIRPYRDENOISE (M_COLOR|M_LUMINANCE) #define DIRPYRDENOISE (M_COLOR|M_LUMINANCE)
#define CROP M_MINUPDATE #define CROP M_MINUPDATE
#define RESIZE M_VOID
#define EXIF M_VOID #define EXIF M_VOID
#define IPTC M_VOID #define IPTC M_VOID
#define EQUALIZER (M_COLOR|M_LUMINANCE) #define EQUALIZER (M_COLOR|M_LUMINANCE)

View File

@@ -157,7 +157,7 @@ namespace rtengine {
/** With this member function the staged processor notifies the listener that it allocated a new /** With this member function the staged processor notifies the listener that it allocated a new
* image to store the end result of the processing. It can be used in a shared manner. * image to store the end result of the processing. It can be used in a shared manner.
* @param img is a pointer to the image * @param img is a pointer to the image
* @param scale describes the current scaling applied compared to the 100% size (preview scale + resize scale) * @param scale describes the current scaling applied compared to the 100% size (preview scale)
* @param cp holds the coordinates of the current crop rectangle */ * @param cp holds the coordinates of the current crop rectangle */
virtual void setImage (IImage8* img, double scale, procparams::CropParams cp) {} virtual void setImage (IImage8* img, double scale, procparams::CropParams cp) {}
/** With this member function the staged processor notifies the listener that the image passed as parameter /** With this member function the staged processor notifies the listener that the image passed as parameter

View File

@@ -728,14 +728,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
else else
myscale = scale * thumbImg->height / fh; myscale = scale * thumbImg->height / fh;
if (params.resize.enabled) {
if (params.resize.dataspec==0)
myscale *= params.resize.scale;
else if (params.resize.dataspec==1)
myscale *= (double)params.resize.width / (params.coarse.rotate==90 || params.coarse.rotate==270 ? thumbImg->height : thumbImg->width) / scale;
else if (params.resize.dataspec==2)
myscale *= (double)params.resize.height / (params.coarse.rotate==90 || params.coarse.rotate==270 ? thumbImg->width : thumbImg->height) / scale;
}
myscale = 1.0 / myscale; myscale = 1.0 / myscale;
/* // apply crop /* // apply crop
@@ -767,6 +759,7 @@ int Thumbnail::getImageWidth (const procparams::ProcParams& params, int rheight)
void Thumbnail::getFinalSize (const rtengine::procparams::ProcParams& params, int& fullw, int& fullh) { void Thumbnail::getFinalSize (const rtengine::procparams::ProcParams& params, int& fullw, int& fullh) {
// WARNING: When downscaled, the ratio have loosed a lot of precision, so we can't get back the exact initial dimensions
double fw = thumbImg->width*scale; double fw = thumbImg->width*scale;
double fh = thumbImg->height*scale; double fh = thumbImg->height*scale;
@@ -778,17 +771,9 @@ void Thumbnail::getFinalSize (const rtengine::procparams::ProcParams& params, in
fullw = fw; fullw = fw;
fullh = fh; fullh = fh;
} }
else if (params.resize.dataspec==0) { else {
fullw = fw*params.resize.scale; fullw = (int)((double)fw+0.5);
fullh = fh*params.resize.scale; fullh = (int)((double)fh+0.5);
}
else if (params.resize.dataspec==1) {
fullw = params.resize.width;
fullh = (double)fh*params.resize.width/(params.coarse.rotate==90 || params.coarse.rotate==270 ? fh : fw);
}
else if (params.resize.dataspec==2) {
fullw = (double)fw*params.resize.height/(params.coarse.rotate==90 || params.coarse.rotate==270 ? fw : fh);
fullh = params.resize.height;
} }
} }

View File

@@ -52,14 +52,9 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
} }
} }
procparams::ProcParams& params = job->pparams; procparams::ProcParams& params = job->pparams;
// aquire image from imagesource // aquire image from imagesource
ImageSource* imgsrc = ii->getImageSource (); ImageSource* imgsrc = ii->getImageSource ();
ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green);
if (params.wb.method=="Camera")
currWB = imgsrc->getWB ();
else if (params.wb.method=="Auto")
currWB = imgsrc->getAutoWB ();
int tr = TR_NONE; int tr = TR_NONE;
if (params.coarse.rotate==90) tr |= TR_R90; if (params.coarse.rotate==90) tr |= TR_R90;
@@ -71,25 +66,42 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
int fw, fh; int fw, fh;
imgsrc->getFullSize (fw, fh, tr); imgsrc->getFullSize (fw, fh, tr);
// check the crop params
if (params.crop.x > fw || params.crop.y > fh) {
// the crop is completely out of the image, so we disable the crop
params.crop.enabled = false;
// and we set the values to the defaults
params.crop.x = 0;
params.crop.y = 0;
params.crop.w = fw;
params.crop.h = fh;
}
else {
if ((params.crop.x + params.crop.w) > fw) {
// crop overflow in the width dimension ; we trim it
params.crop.w = fw-params.crop.x;
}
if ((params.crop.y + params.crop.h) > fh) {
// crop overflow in the height dimension ; we trim it
params.crop.h = fh-params.crop.y;
}
}
ImProcFunctions ipf (&params, true); ImProcFunctions ipf (&params, true);
// set the color temperature
ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green);
if (params.wb.method=="Camera")
currWB = imgsrc->getWB ();
else if (params.wb.method=="Auto")
currWB = imgsrc->getAutoWB ();
Image16* baseImg; Image16* baseImg;
PreviewProps pp (0, 0, fw, fh, 1); PreviewProps pp (0, 0, fw, fh, 1);
imgsrc->preprocess( params.raw ); imgsrc->preprocess( params.raw );
imgsrc->demosaic( params.raw ); imgsrc->demosaic( params.raw );
if (fabs(params.resize.scale-1.0)<1e-5) { baseImg = new Image16 (fw, fh);
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, params.raw);
}
else {
Image16* oorig = new Image16 (fw, fh);
imgsrc->getImage (currWB, tr, oorig, pp, params.hlrecovery, params.icm, params.raw);
fw *= params.resize.scale;
fh *= params.resize.scale;
baseImg = new Image16 (fw, fh);
ipf.resize (oorig, baseImg);
delete oorig;
}
if (pl) if (pl)
pl->setProgress (0.25); pl->setProgress (0.25);
@@ -97,7 +109,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
unsigned int* hist16 = new unsigned int[65536]; unsigned int* hist16 = new unsigned int[65536];
ipf.firstAnalysis (baseImg, &params, hist16, imgsrc->getGamma()); ipf.firstAnalysis (baseImg, &params, hist16, imgsrc->getGamma());
// perform transform // perform transform (excepted resizing)
if (ipf.needsTransform()) { if (ipf.needsTransform()) {
Image16* trImg = new Image16 (fw, fh); Image16* trImg = new Image16 (fw, fh);
ipf.transform (baseImg, trImg, 0, 0, 0, 0, fw, fh); ipf.transform (baseImg, trImg, 0, 0, 0, 0, fw, fh);
@@ -184,9 +196,9 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
delete [] buffer; delete [] buffer;
if (pl) if (pl)
pl->setProgress (0.75); pl->setProgress (0.70);
// obtain final image // crop and convert to rgb16
Image16* readyImg; Image16* readyImg;
int cx = 0, cy = 0, cw = labView->W, ch = labView->H; int cx = 0, cy = 0, cw = labView->W, ch = labView->H;
if (params.crop.enabled) { if (params.crop.enabled) {
@@ -197,6 +209,73 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
} }
readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output); readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output);
if (pl)
pl->setProgress (0.85);
// get the resize parameters
int refw, refh;
double tmpScale;
if (params.resize.enabled) {
if (params.crop.enabled && params.resize.appliesTo == "Cropped area") {
// the resize values applies to the crop dimensions
refw = cw;
refh = ch;
}
else {
// the resize values applies to the image dimensions
// if a crop exists, it will be resized to the calculated scale
refw = fw;
refh = fh;
}
switch(params.resize.dataspec) {
case (1):
// Width
tmpScale = (double)params.resize.width/(double)refw;
break;
case (2):
// Height
tmpScale = (double)params.resize.height/(double)refh;
break;
case (3):
// FitBox
if ((double)refw/(double)refh > (double)params.resize.width/(double)params.resize.height) {
tmpScale = (double)params.resize.width/(double)refw;
}
else {
tmpScale = (double)params.resize.height/(double)refh;
}
break;
default:
// Scale
tmpScale = params.resize.scale;
break;
}
// resize image
if (fabs(tmpScale-1.0)>1e-5)
{
int imw, imh;
if (params.crop.enabled && params.resize.appliesTo == "Full image") {
imw = cw;
imh = ch;
}
else {
imw = refw;
imh = refh;
}
imw = (int)( (double)imw * tmpScale + 0.5 );
imh = (int)( (double)imh * tmpScale + 0.5 );
Image16* tempImage = new Image16 (imw, imh);
ipf.resize (readyImg, tempImage, tmpScale);
delete readyImg;
readyImg = tempImage;
}
}
if (pl) if (pl)
pl->setProgress (1.0); pl->setProgress (1.0);

View File

@@ -186,6 +186,8 @@ void BatchToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const G
for (int i=0; i<toolPanels.size(); i++) for (int i=0; i<toolPanels.size(); i++)
toolPanels[i]->write (&pparams, &pparamsEdited); toolPanels[i]->write (&pparams, &pparamsEdited);
// TODO: We may update the crop on coarse rotate events here, like in ToolPanelCoordinator::panelChanged
if (event==rtengine::EvAutoExp || event==rtengine::EvClip) if (event==rtengine::EvAutoExp || event==rtengine::EvClip)
for (int i=0; i<selected.size(); i++) { for (int i=0; i<selected.size(); i++) {
initialPP[i].toneCurve.autoexp = pparams.toneCurve.autoexp; initialPP[i].toneCurve.autoexp = pparams.toneCurve.autoexp;

View File

@@ -187,8 +187,6 @@ Crop::Crop () {
dpi->signal_value_changed().connect( sigc::mem_fun(*this, &Crop::refreshSize) ); dpi->signal_value_changed().connect( sigc::mem_fun(*this, &Crop::refreshSize) );
nx = ny = nw = nh = 0; nx = ny = nw = nh = 0;
nsx = nsy = nsw = nsh = 0;
lastScale = 1.0;
lastRotationDeg = 0; lastRotationDeg = 0;
show_all (); show_all ();
} }
@@ -217,15 +215,17 @@ void Crop::read (const ProcParams* pp, const ParamsEdited* pedited) {
hconn.block (true); hconn.block (true);
rconn.block (true); rconn.block (true);
fconn.block (true); fconn.block (true);
econn.block (true);
oconn.block (true); oconn.block (true);
gconn.block (true); gconn.block (true);
enabled->set_active (pp->crop.enabled); enabled->set_active (pp->crop.enabled);
// check if the new values are larger than the maximum // check if the new values are larger than the maximum
double tmp, maxw, maxh; double tmp, maxw, maxh;
w->get_range (tmp, maxw); w->get_range (tmp, maxw);
h->get_range (tmp, maxh); h->get_range (tmp, maxh);
if (pp->crop.x + pp->crop.w > maxw || pp->crop.y + pp->crop.h > maxh) if (pp->crop.x + pp->crop.w > (int)maxw || pp->crop.y + pp->crop.h > (int)maxh)
setDimensions (pp->crop.x + pp->crop.w, pp->crop.y + pp->crop.h); setDimensions (pp->crop.x + pp->crop.w, pp->crop.y + pp->crop.h);
ratio->set_active_text (pp->crop.ratio); ratio->set_active_text (pp->crop.ratio);
@@ -263,14 +263,6 @@ void Crop::read (const ProcParams* pp, const ParamsEdited* pedited) {
nw = pp->crop.w; nw = pp->crop.w;
nh = pp->crop.h; nh = pp->crop.h;
if (pp->resize.enabled)
lastScale = pp->resize.scale;
else
lastScale = 1.0;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
lastRotationDeg = pp->coarse.rotate; lastRotationDeg = pp->coarse.rotate;
wDirty = false; wDirty = false;
@@ -302,6 +294,7 @@ void Crop::read (const ProcParams* pp, const ParamsEdited* pedited) {
hconn.block (false); hconn.block (false);
rconn.block (false); rconn.block (false);
fconn.block (false); fconn.block (false);
econn.block (false);
oconn.block (false); oconn.block (false);
gconn.block (false); gconn.block (false);
@@ -354,6 +347,40 @@ void Crop::write (ProcParams* pp, ParamsEdited* pedited) {
} }
void Crop::trim (ProcParams* pp, int ow, int oh) {
int xmin = pp->crop.x;
int ymin = pp->crop.y;
if (xmin > maxw || ymin > maxh) {
// the crop is completely out of the image, so we disable the crop
pp->crop.enabled = false;
// and we set the values to the defaults
pp->crop.x = 0;
pp->crop.y = 0;
pp->crop.w = ow;
pp->crop.h = oh;
// the ratio is now not guaranteed, so we set it off
pp->crop.fixratio = false;
}
else {
bool unsetRatio = false;
if ((xmin + pp->crop.w) > ow) {
// crop overflow in the width dimension ; we trim it
pp->crop.w = ow-xmin;
unsetRatio = true;
}
if ((ymin + pp->crop.h) > oh) {
// crop overflow in the height dimension ; we trim it
pp->crop.h = oh-ymin;
unsetRatio = true;
}
if (unsetRatio) {
// the ratio is certainly not respected anymore, so we set it off
pp->crop.fixratio = false;
}
}
}
void Crop::selectPressed () { void Crop::selectPressed () {
if (clistener) if (clistener)
@@ -407,32 +434,15 @@ int refreshspins (void* data) {
return 0; return 0;
} }
void Crop::resizeScaleChanged (double rsc) {
lastScale = rsc;
nx = (int)round (nsx * rsc);
ny = (int)round (nsy * rsc);
nw = (int)round (nsw * rsc);
nh = (int)round (nsh * rsc);
if (nx+nw > maxw || ny+nh > maxh)
setDimensions (nx+nw, ny+nh);
g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
}
void Crop::hFlipCrop () { void Crop::hFlipCrop () {
nx = maxw - nx - nw; nx = maxw - nx - nw;
nsx = nx / lastScale;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
} }
void Crop::vFlipCrop () { void Crop::vFlipCrop () {
ny = maxh - ny - nh; ny = maxh - ny - nh;
nsy = ny / lastScale;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
} }
@@ -461,10 +471,6 @@ void Crop::rotateCrop (int deg) {
ny = maxh - ny - nh; ny = maxh - ny - nh;
break; break;
} }
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
lastRotationDeg = deg; lastRotationDeg = deg;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
@@ -561,25 +567,29 @@ void Crop::refreshSize () {
} }
} }
/*
* Set the maximum dimensions of the image. This method can be called with wrong values, then
* called with the good ones !?
*/
void Crop::setDimensions (int mw, int mh) { void Crop::setDimensions (int mw, int mh) {
maxw = mw; maxw = mw;
maxh = mh; maxh = mh;
xconn.block (true); bool xconnWasBlocked = xconn.block (true);
yconn.block (true); bool yconnWasBlocked = yconn.block (true);
wconn.block (true); bool wconnWasBlocked = wconn.block (true);
hconn.block (true); bool hconnWasBlocked = hconn.block (true);
w->set_range (0, maxw); w->set_range (0, maxw);
h->set_range (0, maxh); h->set_range (0, maxh);
x->set_range (0, maxw); x->set_range (0, maxw);
y->set_range (0, maxh); y->set_range (0, maxh);
xconn.block (false); if (!xconnWasBlocked) xconn.block (false);
yconn.block (false); if (!yconnWasBlocked) yconn.block (false);
wconn.block (false); if (!wconnWasBlocked) wconn.block (false);
hconn.block (false); if (!hconnWasBlocked) hconn.block (false);
if (enabled->get_active()==false) { if (enabled->get_active()==false) {
nx = 0; nx = 0;
@@ -587,12 +597,8 @@ void Crop::setDimensions (int mw, int mh) {
nw = mw; nw = mw;
nh = mh; nh = mh;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
refreshSpins (); refreshSpins ();
} }
refreshSize (); refreshSize ();
} }
@@ -671,11 +677,6 @@ void Crop::cropMoved (int &X, int &Y, int &W, int &H) {
nw = W; nw = W;
nh = H; nh = H;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); // Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins));
} }
@@ -706,11 +707,6 @@ void Crop::cropWidth1Resized (int &X, int &Y, int &W, int &H) {
nw = W; nw = W;
nh = H; nh = H;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); // Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins));
} }
@@ -743,11 +739,6 @@ void Crop::cropWidth2Resized (int &X, int &Y, int &W, int &H) {
nw = W; nw = W;
nh = H; nh = H;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); // Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins));
} }
@@ -779,11 +770,6 @@ void Crop::cropHeight1Resized (int &X, int &Y, int &W, int &H) {
nw = W; nw = W;
nh = H; nh = H;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); // Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins));
} }
@@ -815,11 +801,6 @@ void Crop::cropHeight2Resized (int &X, int &Y, int &W, int &H) {
nw = W; nw = W;
nh = H; nh = H;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); // Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins));
} }
@@ -831,11 +812,6 @@ void Crop::cropInit (int &x, int &y, int &w, int &h) {
nw = 1; nw = 1;
nh = 1; nh = 1;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
w = 1; h = 1; w = 1; h = 1;
econn.block (true); econn.block (true);
@@ -926,11 +902,6 @@ void Crop::cropResized (int &x, int &y, int& x2, int& y2) {
nw = W; nw = W;
nh = H; nh = H;
nsx = nx / lastScale;
nsy = ny / lastScale;
nsw = nw / lastScale;
nsh = nh / lastScale;
g_idle_add (refreshspins, new RefreshSpinHelper (this, false)); g_idle_add (refreshspins, new RefreshSpinHelper (this, false));
// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); // Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins));
} }

View File

@@ -51,7 +51,6 @@ class Crop : public Gtk::VBox, public CropGUIListener, public ToolPanel, public
Gtk::VBox* dpibox; Gtk::VBox* dpibox;
int maxw, maxh; int maxw, maxh;
int nx, ny, nw, nh; int nx, ny, nw, nh;
double nsx, nsy, nsw, nsh, lastScale;
int lastRotationDeg; int lastRotationDeg;
sigc::connection xconn, yconn, wconn, hconn, econn, fconn, rconn, oconn, gconn; sigc::connection xconn, yconn, wconn, hconn, econn, fconn, rconn, oconn, gconn;
bool wDirty, hDirty, xDirty, yDirty, lastEnabled, lastAspect; bool wDirty, hDirty, xDirty, yDirty, lastEnabled, lastAspect;
@@ -67,7 +66,7 @@ class Crop : public Gtk::VBox, public CropGUIListener, public ToolPanel, public
void ratioChanged (); void ratioChanged ();
void refreshSize (); void refreshSize ();
void selectPressed (); void selectPressed ();
void setDimensions (int mw, int mh); void setDimensions (int mw, int mh);
void enabledChanged (); void enabledChanged ();
void positionChanged (); void positionChanged ();
void widthChanged (); void widthChanged ();
@@ -75,6 +74,7 @@ class Crop : public Gtk::VBox, public CropGUIListener, public ToolPanel, public
bool refreshSpins (bool notify=false); bool refreshSpins (bool notify=false);
void notifyListener (); void notifyListener ();
void sizeChanged (int w, int h, int ow, int oh); void sizeChanged (int w, int h, int ow, int oh);
void trim (rtengine::procparams::ProcParams* pp, int ow, int oh);
void readOptions (); void readOptions ();
void writeOptions (); void writeOptions ();

View File

@@ -246,8 +246,6 @@ EditorPanel::EditorPanel (FilePanel* filePanel) : beforePreviewHandler(NULL), be
} }
EditorPanel::~EditorPanel () { EditorPanel::~EditorPanel () {
history->setHistoryBeforeLineListener (NULL); history->setHistoryBeforeLineListener (NULL);
@@ -389,15 +387,15 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) {
} }
void EditorPanel::close () { void EditorPanel::close () {
if (ipc) if (ipc)
{ {
saveProfile (); saveProfile ();
// close image processor and the current thumbnail // close image processor and the current thumbnail
tpc->closeImage (); // this call stops image processing tpc->closeImage (); // this call stops image processing
tpc->writeOptions (); tpc->writeOptions ();
rtengine::ImageSource* is=isrc->getImageSource(); rtengine::ImageSource* is=isrc->getImageSource();
is->setProgressListener( NULL ); is->setProgressListener( NULL );
if (ipc) if (ipc)
ipc->setPreviewImageListener (NULL); ipc->setPreviewImageListener (NULL);
@@ -425,9 +423,8 @@ void EditorPanel::close () {
} }
void EditorPanel::saveProfile () { void EditorPanel::saveProfile () {
if (!ipc) return;
if (!ipc)
return;
ProcParams params; ProcParams params;
ipc->getParams (&params); ipc->getParams (&params);
@@ -894,7 +891,6 @@ void EditorPanel::saveAsPressed () {
} }
void EditorPanel::queueImgPressed () { void EditorPanel::queueImgPressed () {
saveProfile (); saveProfile ();
parent->addBatchQueueJob (createBatchQueueEntry ()); parent->addBatchQueueJob (createBatchQueueEntry ());
} }
@@ -1042,11 +1038,6 @@ bool EditorPanel::idle_sentToGimp(ProgressConnector<int> *pc,rtengine::IImage16*
return false; return false;
} }
/*
void EditorPanel::saveOptions () {
}
*/
void EditorPanel::historyBeforeLineChanged (const rtengine::procparams::ProcParams& params) { void EditorPanel::historyBeforeLineChanged (const rtengine::procparams::ProcParams& params) {
if (beforeIpc) { if (beforeIpc) {

View File

@@ -28,123 +28,124 @@ ParamsEdited::ParamsEdited () {
void ParamsEdited::set (bool v) { void ParamsEdited::set (bool v) {
toneCurve.curve = v; toneCurve.curve = v;
toneCurve.brightness = v; toneCurve.brightness = v;
toneCurve.black = v; toneCurve.black = v;
toneCurve.contrast = v; toneCurve.contrast = v;
toneCurve.saturation = v; toneCurve.saturation = v;
toneCurve.shcompr = v; toneCurve.shcompr = v;
toneCurve.hlcompr = v; toneCurve.hlcompr = v;
toneCurve.autoexp = v; toneCurve.autoexp = v;
toneCurve.clip = v; toneCurve.clip = v;
toneCurve.expcomp = v; toneCurve.expcomp = v;
labCurve.lcurve = v; labCurve.lcurve = v;
labCurve.acurve = v; labCurve.acurve = v;
labCurve.bcurve = v; labCurve.bcurve = v;
labCurve.brightness = v; labCurve.brightness = v;
labCurve.contrast = v; labCurve.contrast = v;
labCurve.saturation = v; labCurve.saturation = v;
sharpening.enabled = v; sharpening.enabled = v;
sharpening.radius = v; sharpening.radius = v;
sharpening.amount = v; sharpening.amount = v;
sharpening.threshold = v; sharpening.threshold = v;
sharpening.edgesonly = v; sharpening.edgesonly = v;
sharpening.edges_radius = v; sharpening.edges_radius = v;
sharpening.edges_tolerance = v; sharpening.edges_tolerance = v;
sharpening.halocontrol = v; sharpening.halocontrol = v;
sharpening.halocontrol_amount= v; sharpening.halocontrol_amount= v;
sharpening.method = v; sharpening.method = v;
sharpening.deconvamount = v; sharpening.deconvamount = v;
sharpening.deconvradius = v; sharpening.deconvradius = v;
sharpening.deconviter = v; sharpening.deconviter = v;
sharpening.deconvdamping = v; sharpening.deconvdamping = v;
colorBoost.amount = v; colorBoost.amount = v;
colorBoost.avoidclip = v; colorBoost.avoidclip = v;
colorBoost.enable_saturationlimiter = v; colorBoost.enable_saturationlimiter = v;
colorBoost.saturationlimit = v; colorBoost.saturationlimit = v;
wb.method = v; wb.method = v;
wb.green = v; wb.green = v;
wb.temperature = v; wb.temperature = v;
colorShift.a = v; colorShift.a = v;
colorShift.b = v; colorShift.b = v;
lumaDenoise.enabled = v; lumaDenoise.enabled = v;
lumaDenoise.radius = v; lumaDenoise.radius = v;
lumaDenoise.edgetolerance = v; lumaDenoise.edgetolerance = v;
colorDenoise.enabled = v; colorDenoise.enabled = v;
colorDenoise.amount = v; colorDenoise.amount = v;
defringe.enabled = v; defringe.enabled = v;
defringe.radius = v; defringe.radius = v;
defringe.threshold = v; defringe.threshold = v;
impulseDenoise.enabled = v; impulseDenoise.enabled = v;
impulseDenoise.thresh = v; impulseDenoise.thresh = v;
dirpyrDenoise.enabled = v; dirpyrDenoise.enabled = v;
dirpyrDenoise.luma = v; dirpyrDenoise.luma = v;
dirpyrDenoise.chroma = v; dirpyrDenoise.chroma = v;
dirpyrDenoise.gamma = v; dirpyrDenoise.gamma = v;
sh.enabled = v; sh.enabled = v;
sh.hq = v; sh.hq = v;
sh.highlights = v; sh.highlights = v;
sh.htonalwidth = v; sh.htonalwidth = v;
sh.shadows = v; sh.shadows = v;
sh.stonalwidth = v; sh.stonalwidth = v;
sh.localcontrast = v; sh.localcontrast = v;
sh.radius = v; sh.radius = v;
crop.enabled = v; crop.enabled = v;
crop.x = v; crop.x = v;
crop.y = v; crop.y = v;
crop.w = v; crop.w = v;
crop.h = v; crop.h = v;
crop.fixratio = v; crop.fixratio = v;
crop.ratio = v; crop.ratio = v;
crop.orientation = v; crop.orientation = v;
crop.guide = v; crop.guide = v;
coarse.rotate = v; coarse.rotate = v;
coarse.hflip = v; coarse.hflip = v;
coarse.vflip = v; coarse.vflip = v;
commonTrans.autofill = v; commonTrans.autofill = v;
rotate.degree = v; rotate.degree = v;
distortion.uselensfun = v; distortion.uselensfun = v;
distortion.amount = v; distortion.amount = v;
perspective.horizontal = v; perspective.horizontal = v;
perspective.vertical = v; perspective.vertical = v;
cacorrection.red = v; cacorrection.red = v;
cacorrection.blue = v; cacorrection.blue = v;
vignetting.amount = v; vignetting.amount = v;
vignetting.radius = v; vignetting.radius = v;
vignetting.strength = v; vignetting.strength = v;
vignetting.centerX = v; vignetting.centerX = v;
vignetting.centerY = v; vignetting.centerY = v;
chmixer.red[0] = v; chmixer.red[0] = v;
chmixer.red[1] = v; chmixer.red[1] = v;
chmixer.red[2] = v; chmixer.red[2] = v;
chmixer.green[0] = v; chmixer.green[0] = v;
chmixer.green[1] = v; chmixer.green[1] = v;
chmixer.green[2] = v; chmixer.green[2] = v;
chmixer.blue[0] = v; chmixer.blue[0] = v;
chmixer.blue[1] = v; chmixer.blue[1] = v;
chmixer.blue[2] = v; chmixer.blue[2] = v;
hlrecovery.enabled = v; hlrecovery.enabled = v;
hlrecovery.method = v; hlrecovery.method = v;
resize.scale = v; resize.scale = v;
resize.method = v; resize.appliesTo = v;
resize.dataspec = v; resize.method = v;
resize.width = v; resize.dataspec = v;
resize.height = v; resize.width = v;
resize.enabled = v; resize.height = v;
icm.input = v; resize.enabled = v;
icm.gammaOnInput = v; icm.input = v;
icm.working = v; icm.gammaOnInput = v;
icm.output = v; icm.working = v;
raw.ccSteps = v; icm.output = v;
raw.dmethod = v; raw.ccSteps = v;
raw.dcbIterations = v; raw.dmethod = v;
raw.dcbEnhance = v; raw.dcbIterations = v;
equalizer.enabled = v; raw.dcbEnhance = v;
dirpyrequalizer.enabled = v; equalizer.enabled = v;
hsvequalizer.enabled = v; dirpyrequalizer.enabled = v;
for(int i = 0; i < 8; i++) { hsvequalizer.enabled = v;
equalizer.c[i] = v; for(int i = 0; i < 8; i++) {
} equalizer.c[i] = v;
}
for(int i = 0; i < 5; i++) { for(int i = 0; i < 5; i++) {
dirpyrequalizer.mult[i] = v; dirpyrequalizer.mult[i] = v;
} }
@@ -153,8 +154,8 @@ void ParamsEdited::set (bool v) {
hsvequalizer.val[i] = v; hsvequalizer.val[i] = v;
hsvequalizer.hue[i] = v; hsvequalizer.hue[i] = v;
} }
exif.clear (); exif.clear ();
iptc.clear (); iptc.clear ();
} }
using namespace rtengine; using namespace rtengine;
@@ -173,19 +174,19 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
toneCurve.brightness = toneCurve.brightness && p.toneCurve.brightness == other.toneCurve.brightness; toneCurve.brightness = toneCurve.brightness && p.toneCurve.brightness == other.toneCurve.brightness;
toneCurve.black = toneCurve.black && p.toneCurve.black == other.toneCurve.black; toneCurve.black = toneCurve.black && p.toneCurve.black == other.toneCurve.black;
toneCurve.contrast = toneCurve.contrast && p.toneCurve.contrast == other.toneCurve.contrast; toneCurve.contrast = toneCurve.contrast && p.toneCurve.contrast == other.toneCurve.contrast;
toneCurve.saturation = toneCurve.saturation && p.toneCurve.saturation == other.toneCurve.saturation; toneCurve.saturation = toneCurve.saturation && p.toneCurve.saturation == other.toneCurve.saturation;
toneCurve.shcompr = toneCurve.shcompr && p.toneCurve.shcompr == other.toneCurve.shcompr; toneCurve.shcompr = toneCurve.shcompr && p.toneCurve.shcompr == other.toneCurve.shcompr;
toneCurve.hlcompr = toneCurve.hlcompr && p.toneCurve.hlcompr == other.toneCurve.hlcompr; toneCurve.hlcompr = toneCurve.hlcompr && p.toneCurve.hlcompr == other.toneCurve.hlcompr;
toneCurve.autoexp = toneCurve.autoexp && p.toneCurve.autoexp == other.toneCurve.autoexp; toneCurve.autoexp = toneCurve.autoexp && p.toneCurve.autoexp == other.toneCurve.autoexp;
toneCurve.clip = toneCurve.clip && p.toneCurve.clip == other.toneCurve.clip; toneCurve.clip = toneCurve.clip && p.toneCurve.clip == other.toneCurve.clip;
toneCurve.expcomp = toneCurve.expcomp && p.toneCurve.expcomp == other.toneCurve.expcomp; toneCurve.expcomp = toneCurve.expcomp && p.toneCurve.expcomp == other.toneCurve.expcomp;
labCurve.lcurve = labCurve.lcurve && p.labCurve.lcurve == other.labCurve.lcurve; labCurve.lcurve = labCurve.lcurve && p.labCurve.lcurve == other.labCurve.lcurve;
labCurve.acurve = labCurve.acurve && p.labCurve.acurve == other.labCurve.acurve; labCurve.acurve = labCurve.acurve && p.labCurve.acurve == other.labCurve.acurve;
labCurve.bcurve = labCurve.bcurve && p.labCurve.bcurve == other.labCurve.bcurve; labCurve.bcurve = labCurve.bcurve && p.labCurve.bcurve == other.labCurve.bcurve;
labCurve.brightness = labCurve.brightness && p.labCurve.brightness == other.labCurve.brightness; labCurve.brightness = labCurve.brightness && p.labCurve.brightness == other.labCurve.brightness;
labCurve.contrast = labCurve.contrast && p.labCurve.contrast == other.labCurve.contrast; labCurve.contrast = labCurve.contrast && p.labCurve.contrast == other.labCurve.contrast;
labCurve.saturation = labCurve.saturation && p.labCurve.saturation == other.labCurve.saturation; labCurve.saturation = labCurve.saturation && p.labCurve.saturation == other.labCurve.saturation;
sharpening.enabled = sharpening.enabled && p.sharpening.enabled == other.sharpening.enabled; sharpening.enabled = sharpening.enabled && p.sharpening.enabled == other.sharpening.enabled;
sharpening.radius = sharpening.radius && p.sharpening.radius == other.sharpening.radius; sharpening.radius = sharpening.radius && p.sharpening.radius == other.sharpening.radius;
sharpening.amount = sharpening.amount && p.sharpening.amount == other.sharpening.amount; sharpening.amount = sharpening.amount && p.sharpening.amount == other.sharpening.amount;
sharpening.threshold = sharpening.threshold && p.sharpening.threshold == other.sharpening.threshold; sharpening.threshold = sharpening.threshold && p.sharpening.threshold == other.sharpening.threshold;
@@ -213,17 +214,17 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
lumaDenoise.edgetolerance = lumaDenoise.edgetolerance && p.lumaDenoise.edgetolerance == other.lumaDenoise.edgetolerance; lumaDenoise.edgetolerance = lumaDenoise.edgetolerance && p.lumaDenoise.edgetolerance == other.lumaDenoise.edgetolerance;
colorDenoise.enabled = colorDenoise.enabled && p.colorDenoise.enabled == other.colorDenoise.enabled; colorDenoise.enabled = colorDenoise.enabled && p.colorDenoise.enabled == other.colorDenoise.enabled;
colorDenoise.amount = colorDenoise.amount && p.colorDenoise.amount == other.colorDenoise.amount; colorDenoise.amount = colorDenoise.amount && p.colorDenoise.amount == other.colorDenoise.amount;
defringe.enabled = defringe.enabled && p.defringe.enabled == other.defringe.enabled; defringe.enabled = defringe.enabled && p.defringe.enabled == other.defringe.enabled;
defringe.radius = defringe.radius && p.defringe.radius == other.defringe.radius; defringe.radius = defringe.radius && p.defringe.radius == other.defringe.radius;
defringe.threshold = defringe.threshold && p.defringe.threshold == other.defringe.threshold; defringe.threshold = defringe.threshold && p.defringe.threshold == other.defringe.threshold;
impulseDenoise.enabled = impulseDenoise.enabled && p.impulseDenoise.enabled == other.impulseDenoise.enabled; impulseDenoise.enabled = impulseDenoise.enabled && p.impulseDenoise.enabled == other.impulseDenoise.enabled;
impulseDenoise.thresh = impulseDenoise.thresh && p.impulseDenoise.thresh == other.impulseDenoise.thresh; impulseDenoise.thresh = impulseDenoise.thresh && p.impulseDenoise.thresh == other.impulseDenoise.thresh;
dirpyrDenoise.enabled = dirpyrDenoise.enabled && p.dirpyrDenoise.enabled == other.dirpyrDenoise.enabled; dirpyrDenoise.enabled = dirpyrDenoise.enabled && p.dirpyrDenoise.enabled == other.dirpyrDenoise.enabled;
dirpyrDenoise.luma = dirpyrDenoise.luma && p.dirpyrDenoise.luma == other.dirpyrDenoise.luma; dirpyrDenoise.luma = dirpyrDenoise.luma && p.dirpyrDenoise.luma == other.dirpyrDenoise.luma;
dirpyrDenoise.chroma = dirpyrDenoise.chroma && p.dirpyrDenoise.chroma == other.dirpyrDenoise.chroma; dirpyrDenoise.chroma = dirpyrDenoise.chroma && p.dirpyrDenoise.chroma == other.dirpyrDenoise.chroma;
dirpyrDenoise.gamma = dirpyrDenoise.gamma && p.dirpyrDenoise.gamma == other.dirpyrDenoise.gamma; dirpyrDenoise.gamma = dirpyrDenoise.gamma && p.dirpyrDenoise.gamma == other.dirpyrDenoise.gamma;
sh.enabled = sh.enabled && p.sh.enabled == other.sh.enabled; sh.enabled = sh.enabled && p.sh.enabled == other.sh.enabled;
sh.hq = sh.hq && p.sh.hq == other.sh.hq; sh.hq = sh.hq && p.sh.hq == other.sh.hq;
@@ -270,6 +271,7 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
hlrecovery.enabled = hlrecovery.enabled && p.hlrecovery.enabled == other.hlrecovery.enabled; hlrecovery.enabled = hlrecovery.enabled && p.hlrecovery.enabled == other.hlrecovery.enabled;
hlrecovery.method = hlrecovery.method && p.hlrecovery.method == other.hlrecovery.method; hlrecovery.method = hlrecovery.method && p.hlrecovery.method == other.hlrecovery.method;
resize.scale = resize.scale && p.resize.scale == other.resize.scale; resize.scale = resize.scale && p.resize.scale == other.resize.scale;
resize.appliesTo = resize.appliesTo && p.resize.appliesTo == other.resize.appliesTo;
resize.method = resize.method && p.resize.method == other.resize.method; resize.method = resize.method && p.resize.method == other.resize.method;
resize.dataspec = resize.dataspec && p.resize.dataspec == other.resize.dataspec; resize.dataspec = resize.dataspec && p.resize.dataspec == other.resize.dataspec;
resize.width = resize.width && p.resize.width == other.resize.width; resize.width = resize.width && p.resize.width == other.resize.width;
@@ -296,14 +298,14 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
for(int i = 0; i < 8; i++) { for(int i = 0; i < 8; i++) {
equalizer.c[i] = equalizer.c[i] && p.equalizer.c[i] == other.equalizer.c[i]; equalizer.c[i] = equalizer.c[i] && p.equalizer.c[i] == other.equalizer.c[i];
} }
dirpyrequalizer.enabled = dirpyrequalizer.enabled && p.dirpyrequalizer.enabled == other.dirpyrequalizer.enabled; dirpyrequalizer.enabled = dirpyrequalizer.enabled && p.dirpyrequalizer.enabled == other.dirpyrequalizer.enabled;
for(int i = 0; i < 8; i++) { for(int i = 0; i < 8; i++) {
dirpyrequalizer.mult[i] = dirpyrequalizer.mult[i] && p.dirpyrequalizer.mult[i] == other.dirpyrequalizer.mult[i]; dirpyrequalizer.mult[i] = dirpyrequalizer.mult[i] && p.dirpyrequalizer.mult[i] == other.dirpyrequalizer.mult[i];
} }
hsvequalizer.enabled = hsvequalizer.enabled && p.hsvequalizer.enabled == other.hsvequalizer.enabled; hsvequalizer.enabled = hsvequalizer.enabled && p.hsvequalizer.enabled == other.hsvequalizer.enabled;
for(int i = 0; i < 8; i++) { for(int i = 0; i < 8; i++) {
hsvequalizer.sat[i] = hsvequalizer.sat[i] && p.hsvequalizer.sat[i] == other.hsvequalizer.sat[i]; hsvequalizer.sat[i] = hsvequalizer.sat[i] && p.hsvequalizer.sat[i] == other.hsvequalizer.sat[i];
hsvequalizer.val[i] = hsvequalizer.val[i] && p.hsvequalizer.val[i] == other.hsvequalizer.val[i]; hsvequalizer.val[i] = hsvequalizer.val[i] && p.hsvequalizer.val[i] == other.hsvequalizer.val[i];
hsvequalizer.hue[i] = hsvequalizer.hue[i] && p.hsvequalizer.hue[i] == other.hsvequalizer.hue[i]; hsvequalizer.hue[i] = hsvequalizer.hue[i] && p.hsvequalizer.hue[i] == other.hsvequalizer.hue[i];
} }
// exif = exif && p.exif==other.exif // exif = exif && p.exif==other.exif
@@ -415,6 +417,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
if (hlrecovery.enabled) toEdit.hlrecovery.enabled = mods.hlrecovery.enabled; if (hlrecovery.enabled) toEdit.hlrecovery.enabled = mods.hlrecovery.enabled;
if (hlrecovery.method) toEdit.hlrecovery.method = mods.hlrecovery.method; if (hlrecovery.method) toEdit.hlrecovery.method = mods.hlrecovery.method;
if (resize.scale) toEdit.resize.scale = mods.resize.scale; if (resize.scale) toEdit.resize.scale = mods.resize.scale;
if (resize.appliesTo) toEdit.resize.appliesTo = mods.resize.appliesTo;
if (resize.method) toEdit.resize.method = mods.resize.method; if (resize.method) toEdit.resize.method = mods.resize.method;
if (resize.dataspec) toEdit.resize.dataspec = mods.resize.dataspec; if (resize.dataspec) toEdit.resize.dataspec = mods.resize.dataspec;
if (resize.width) toEdit.resize.width = mods.resize.width; if (resize.width) toEdit.resize.width = mods.resize.width;

View File

@@ -231,6 +231,7 @@ class ResizeParamsEdited {
public: public:
bool scale; bool scale;
bool appliesTo;
bool method; bool method;
bool dataspec; bool dataspec;
bool width; bool width;
@@ -314,9 +315,9 @@ class ParamsEdited {
LumaDenoiseParamsEdited lumaDenoise; LumaDenoiseParamsEdited lumaDenoise;
ColorDenoiseParamsEdited colorDenoise; ColorDenoiseParamsEdited colorDenoise;
DefringeParamsEdited defringe; DefringeParamsEdited defringe;
DirPyrDenoiseParamsEdited dirpyrDenoise; DirPyrDenoiseParamsEdited dirpyrDenoise;
ImpulseDenoiseParamsEdited impulseDenoise; ImpulseDenoiseParamsEdited impulseDenoise;
SHParamsEdited sh; SHParamsEdited sh;
CropParamsEdited crop; CropParamsEdited crop;
@@ -333,8 +334,8 @@ class ParamsEdited {
ColorManagementParamsEdited icm; ColorManagementParamsEdited icm;
EqualizerParamsEdited equalizer; EqualizerParamsEdited equalizer;
RAWParamsEdited raw; RAWParamsEdited raw;
DirPyrEqualizerParamsEdited dirpyrequalizer; DirPyrEqualizerParamsEdited dirpyrequalizer;
HSVEqualizerParamsEdited hsvequalizer; HSVEqualizerParamsEdited hsvequalizer;
std::vector<ExifPairEdited> exif; std::vector<ExifPairEdited> exif;
std::vector<IPTCPairEdited> iptc; std::vector<IPTCPairEdited> iptc;

View File

@@ -25,12 +25,23 @@ using namespace rtengine::procparams;
Resize::Resize () : maxw(100000), maxh(100000) { Resize::Resize () : maxw(100000), maxh(100000) {
cropw = 0;
croph = 0;
enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED")));
pack_start(*enabled); pack_start(*enabled);
pack_start(*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_SHRINK, 2); pack_start(*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_SHRINK, 2);
Gtk::Table* combos = Gtk::manage (new Gtk::Table (2, 2)); Gtk::Table* combos = Gtk::manage (new Gtk::Table (2, 2));
appliesTo = Gtk::manage (new Gtk::ComboBoxText ());
appliesTo->append_text (M("TP_RESIZE_CROPPEDAREA"));
appliesTo->append_text (M("TP_RESIZE_FULLIMAGE"));
appliesTo->set_active (0);
combos->attach (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_APPLIESTO"))), 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2);
combos->attach (*appliesTo, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2);
method = Gtk::manage (new Gtk::ComboBoxText ()); method = Gtk::manage (new Gtk::ComboBoxText ());
method->append_text (M("TP_RESIZE_NEAREST")); method->append_text (M("TP_RESIZE_NEAREST"));
method->append_text (M("TP_RESIZE_BILINEAR")); method->append_text (M("TP_RESIZE_BILINEAR"));
@@ -42,22 +53,23 @@ Resize::Resize () : maxw(100000), maxh(100000) {
method->append_text (M("TP_RESIZE_LANCZOS")); method->append_text (M("TP_RESIZE_LANCZOS"));
method->set_active (0); method->set_active (0);
combos->attach (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_METHOD"))), 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); combos->attach (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_METHOD"))), 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 2, 2);
combos->attach (*method, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); combos->attach (*method, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2);
spec = Gtk::manage (new Gtk::ComboBoxText ()); spec = Gtk::manage (new Gtk::ComboBoxText ());
spec->append_text (M("TP_RESIZE_SCALE")); spec->append_text (M("TP_RESIZE_SCALE"));
spec->append_text (M("TP_RESIZE_WIDTH")); spec->append_text (M("TP_RESIZE_WIDTH"));
spec->append_text (M("TP_RESIZE_HEIGHT")); spec->append_text (M("TP_RESIZE_HEIGHT"));
method->set_active (0); spec->append_text (M("TP_RESIZE_FITBOX"));
spec->set_active (0);
combos->attach (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_SPECIFY"))), 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 2, 2); combos->attach (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_SPECIFY"))), 0, 1, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 2, 2);
combos->attach (*spec, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); combos->attach (*spec, 1, 2, 2, 3, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2);
pack_start (*combos, Gtk::PACK_SHRINK, 4); pack_start (*combos, Gtk::PACK_SHRINK, 4);
scale = new Adjuster (M("TP_RESIZE_SCALE"), 0.2, 4, 0.01, 1); scale = new Adjuster (M("TP_RESIZE_SCALE"), 0.01, 4, 0.01, 1.);
scale->setAdjusterListener (this); scale->setAdjusterListener (this);
pack_start (*scale, Gtk::PACK_SHRINK, 4); pack_start (*scale, Gtk::PACK_SHRINK, 4);
@@ -91,8 +103,9 @@ Resize::Resize () : maxw(100000), maxh(100000) {
wconn = w->signal_value_changed().connect ( sigc::mem_fun(*this, &Resize::entryWChanged), true); wconn = w->signal_value_changed().connect ( sigc::mem_fun(*this, &Resize::entryWChanged), true);
hconn = h->signal_value_changed().connect ( sigc::mem_fun(*this, &Resize::entryHChanged), true); hconn = h->signal_value_changed().connect ( sigc::mem_fun(*this, &Resize::entryHChanged), true);
aconn = appliesTo->signal_changed().connect ( sigc::mem_fun(*this, &Resize::appliesToChanged) );
method->signal_changed().connect ( sigc::mem_fun(*this, &Resize::methodChanged) ); method->signal_changed().connect ( sigc::mem_fun(*this, &Resize::methodChanged) );
spec->signal_changed().connect ( sigc::mem_fun(*this, &Resize::specChanged) ); sconn = spec->signal_changed().connect ( sigc::mem_fun(*this, &Resize::specChanged) );
enaConn = enabled->signal_toggled().connect ( sigc::mem_fun(*this, &Resize::enabledToggled) ); enaConn = enabled->signal_toggled().connect ( sigc::mem_fun(*this, &Resize::enabledToggled) );
show_all(); show_all();
@@ -107,14 +120,24 @@ Resize::~Resize () {
void Resize::read (const ProcParams* pp, const ParamsEdited* pedited) { void Resize::read (const ProcParams* pp, const ParamsEdited* pedited) {
disableListener (); disableListener ();
aconn.block (true);
wconn.block (true); wconn.block (true);
hconn.block (true); hconn.block (true);
sconn.block (true);
scale->block(true);
scale->setValue (pp->resize.scale); scale->setValue (pp->resize.scale);
w->set_value (pp->resize.width); w->set_value (pp->resize.width);
h->set_value (pp->resize.height); h->set_value (pp->resize.height);
enabled->set_active (pp->resize.enabled); enabled->set_active (pp->resize.enabled);
spec->set_active (pp->resize.dataspec); spec->set_active (pp->resize.dataspec);
updateGUI();
appliesTo->set_active (0);
if (pp->resize.appliesTo == "Cropped area")
appliesTo->set_active (0);
else if (pp->resize.appliesTo == "Full image")
appliesTo->set_active (1);
method->set_active (2); method->set_active (2);
if (pp->resize.method == "Nearest") if (pp->resize.method == "Nearest")
@@ -141,23 +164,36 @@ void Resize::read (const ProcParams* pp, const ParamsEdited* pedited) {
wDirty = pedited->resize.width; wDirty = pedited->resize.width;
hDirty = pedited->resize.height; hDirty = pedited->resize.height;
scale->setEditedState (pedited->resize.scale ? Edited : UnEdited); scale->setEditedState (pedited->resize.scale ? Edited : UnEdited);
if (!pedited->resize.appliesTo)
method->set_active (2);
if (!pedited->resize.method) if (!pedited->resize.method)
method->set_active (5); method->set_active (8);
if (!pedited->resize.dataspec) if (!pedited->resize.dataspec)
spec->set_active (3); spec->set_active (4);
enabled->set_inconsistent (!pedited->resize.enabled); enabled->set_inconsistent (!pedited->resize.enabled);
} }
lastEnabled = pp->resize.enabled; lastEnabled = pp->resize.enabled;
scale->block(false);
sconn.block (false);
wconn.block (false); wconn.block (false);
hconn.block (false); hconn.block (false);
aconn.block (false);
enableListener (); enableListener ();
} }
void Resize::write (ProcParams* pp, ParamsEdited* pedited) { void Resize::write (ProcParams* pp, ParamsEdited* pedited) {
int dataSpec = spec->get_active_row_number();
pp->resize.scale = scale->getValue();
pp->resize.appliesTo = "Cropped area";
if (appliesTo->get_active_row_number() == 0)
pp->resize.appliesTo = "Cropped area";
else if (appliesTo->get_active_row_number() == 1)
pp->resize.appliesTo = "Full image";
pp->resize.scale = scale->getValue ();
pp->resize.method = "Bicubic"; pp->resize.method = "Bicubic";
if (method->get_active_row_number() == 0) if (method->get_active_row_number() == 0)
pp->resize.method = "Nearest"; pp->resize.method = "Nearest";
@@ -176,15 +212,17 @@ void Resize::write (ProcParams* pp, ParamsEdited* pedited) {
else if (method->get_active_row_number() == 7) else if (method->get_active_row_number() == 7)
pp->resize.method = "Lanczos"; pp->resize.method = "Lanczos";
pp->resize.dataspec = spec->get_active_row_number(); pp->resize.dataspec = dataSpec;
pp->resize.width = round (w->get_value ()); pp->resize.width = w->get_value_as_int ();
pp->resize.height = round(h->get_value ()); pp->resize.height = h->get_value_as_int ();
pp->resize.enabled = enabled->get_active (); pp->resize.enabled = enabled->get_active ();
//printf(" L:%d H:%d\n", pp->resize.width, pp->resize.height);
if (pedited) { if (pedited) {
pedited->resize.enabled = !enabled->get_inconsistent(); pedited->resize.enabled = !enabled->get_inconsistent();
pedited->resize.dataspec = spec->get_active_row_number() != 3; pedited->resize.dataspec = dataSpec != 4;
pedited->resize.method = method->get_active_row_number() != 5; pedited->resize.appliesTo = appliesTo->get_active_row_number() != 2;
pedited->resize.method = method->get_active_row_number() != 8;
if (pedited->resize.dataspec) { if (pedited->resize.dataspec) {
pedited->resize.scale = scale->getEditedState (); pedited->resize.scale = scale->getEditedState ();
pedited->resize.width = wDirty; pedited->resize.width = wDirty;
@@ -213,14 +251,44 @@ void Resize::adjusterChanged (Adjuster* a, double newval) {
if (!batchMode) { if (!batchMode) {
wconn.block (true); wconn.block (true);
hconn.block (true); hconn.block (true);
h->set_value (maxh * a->getValue ()); h->set_value ((croph && appliesTo->get_active_row_number()==0 ? croph : maxh) * a->getValue ());
w->set_value (maxw * a->getValue ()); w->set_value ((cropw && appliesTo->get_active_row_number()==0 ? cropw : maxw) * a->getValue ());
wconn.block (false); wconn.block (false);
hconn.block (false); hconn.block (false);
} }
if (listener && (enabled->get_active () || batchMode)) if (listener && (enabled->get_active () || batchMode))
listener->panelChanged (EvResizeScale, Glib::ustring::format (std::setw(5), std::fixed, std::setprecision(4), scale->getValue())); listener->panelChanged (EvResizeScale, Glib::ustring::format (std::setw(5), std::fixed, std::setprecision(2), scale->getValue()));
}
int Resize::getComputedWidth() {
if (cropw && appliesTo->get_active_row_number()==0)
// we use the crop dimensions
return (int)((double)(cropw) * (h->get_value()/(double)(croph)) + 0.5);
else
// we use the image dimensions
return (int)((double)(maxw) * (h->get_value()/(double)(maxh)) + 0.5);
}
int Resize::getComputedHeight() {
if (croph && appliesTo->get_active_row_number()==0)
// we use the crop dimensions
return (int)((double)(croph) * (w->get_value()/(double)(cropw)) + 0.5);
else
// we use the image dimensions
return (int)((double)(maxh) * (w->get_value()/(double)(maxw)) + 0.5);
}
void Resize::appliesToChanged () {
//printf("\nPASSAGE EN MODE \"%s\"\n\n", appliesTo->get_active_text().c_str());
setDimensions();
if (listener && (enabled->get_active () || batchMode)) {
//printf("Appel du listener\n");
listener->panelChanged (EvResizeAppliesTo, appliesTo->get_active_text());
}
} }
void Resize::methodChanged () { void Resize::methodChanged () {
@@ -229,65 +297,155 @@ void Resize::methodChanged () {
listener->panelChanged (EvResizeMethod, method->get_active_text()); listener->panelChanged (EvResizeMethod, method->get_active_text());
} }
struct setrdimparams { void Resize::update (bool isCropped, int cw, int ch, int ow, int oh) {
Resize* resize;
int mw;
int mh;
int ow;
int oh;
};
int setrdim (void* data) { // updating crop values now
if (isCropped) {
cropw = cw;
croph = ch;
}
else {
cropw = 0;
croph = 0;
}
gdk_threads_enter (); // updating the full image dimensions
setrdimparams* params = (setrdimparams*)data; if (ow && oh) {
params->resize->setDimensions (params->mw, params->mh, params->ow, params->oh); maxw = ow;
delete params; maxh = oh;
gdk_threads_leave (); }
return 0; // updating the GUI synchronously
setDimensions();
} }
void Resize::sizeChanged (int mw, int mh, int ow, int oh) { void Resize::sizeChanged (int mw, int mh, int ow, int oh) {
setrdimparams* params = new setrdimparams; // updating max values now
params->mw = mw;
params->mh = mh;
params->ow = ow;
params->oh = oh;
params->resize = this;
g_idle_add (setrdim, params);
}
void Resize::setDimensions (int mw, int mh, int ow, int oh) {
maxw = ow; maxw = ow;
maxh = oh; maxh = oh;
// updating the GUI synchronously
setDimensions();
}
void Resize::setDimensions () {
int refw, refh;
wconn.block (true); wconn.block (true);
hconn.block (true); hconn.block (true);
scale->block(true);
w->set_range (32, 4*maxw); if (appliesTo->get_active_row_number()==0 && cropw) {
h->set_range (32, 4*maxh); // Applies to Cropped area
refw = cropw;
refh = croph;
}
else {
// Applies to Full image or crop is disabled
refw = maxw;
refh = maxh;
}
w->set_range (32, 4*refw);
h->set_range (32, 4*refh);
double tmpScale;
switch (spec->get_active_row_number()) {
case (0): // Scale mode
w->set_value((double)((int)( (double)(refw) * scale->getValue() + 0.5) ));
h->set_value((double)((int)( (double)(refh) * scale->getValue() + 0.5) ));
break;
case (1): // Width mode
tmpScale = w->get_value() / (double)refw;
scale->setValue (tmpScale);
h->set_value((double)((int)( (double)(refh) * tmpScale + 0.5) ));
break;
case (2): // Height mode
tmpScale = h->get_value() / (double)refh;
scale->setValue (tmpScale);
w->set_value((double)((int)( (double)(refw) * tmpScale + 0.5) ));
case (3): { // Bounding box mode
double wSliderValue = w->get_value();
double hSliderValue = h->get_value();
if ( (wSliderValue/hSliderValue) < ((double)refw/(double)refh)) {
tmpScale = wSliderValue / (double)refw;
}
else {
tmpScale = hSliderValue / (double)refh;
}
scale->setValue (tmpScale);
break;
}
default:
break;
}
scale->block(false);
wconn.block (false); wconn.block (false);
hconn.block (false); hconn.block (false);
} }
void Resize::fitBoxScale() {
double tmpScale;
double neww = w->get_value ();
double newh = h->get_value ();
if (cropw && appliesTo->get_active_row_number()==0) {
// we use the crop dimensions
if (((double)(cropw) / (double)(croph)) > (neww / newh)) {
// the new scale is given by the image width
tmpScale = neww / (double)(cropw);
}
else {
// the new scale is given by the image height
tmpScale = newh / (double)(croph);
}
}
else {
// we use the image dimensions
if (((double)(maxw) / (double)(maxh)) > (neww / newh)) {
// the new scale is given by the image width
tmpScale = neww / (double)(maxw);
}
else {
// the new scale is given by the image height
tmpScale = newh / (double)(maxh);
}
}
scale->setValue (tmpScale);
}
void Resize::entryWChanged () { void Resize::entryWChanged () {
wDirty = true; wDirty = true;
if (!batchMode && listener) { // updating width
hconn.block (true); if (!batchMode) {
h->set_value (w->get_value () * maxh / maxw); if (spec->get_active_row_number() == 3) {
hconn.block (false); // Fit box mode
scale->setValue (w->get_value () / maxw); fitBoxScale();
}
else {
// Other modes
hconn.block (true);
scale->block (true);
h->set_value ((double)(getComputedHeight()));
scale->setValue (w->get_value () / (cropw && appliesTo->get_active_row_number()==0 ? (double)cropw : (double)maxw));
scale->block (false);
hconn.block (false);
}
} }
if (listener && (enabled->get_active () || batchMode)) if (listener) {
listener->panelChanged (EvResizeWidth, Glib::ustring::format ((int)w->get_value())); if (spec->get_active_row_number() == 3)
notifyBBox();
else {
if (enabled->get_active () || batchMode)
listener->panelChanged (EvResizeWidth, Glib::ustring::format (w->get_value_as_int()));
}
}
} }
void Resize::entryHChanged () { void Resize::entryHChanged () {
@@ -295,39 +453,96 @@ void Resize::entryHChanged () {
hDirty = true; hDirty = true;
if (!batchMode && listener) { if (!batchMode && listener) {
wconn.block (true); if (spec->get_active_row_number() == 3) {
w->set_value (h->get_value () * maxw / maxh); // Fit box mode
wconn.block (false); fitBoxScale();
scale->setValue (h->get_value () / maxh); }
else {
// Other modes
wconn.block (true);
scale->block (true);
w->set_value ((double)(getComputedWidth()));
scale->setValue (h->get_value () / (croph && appliesTo->get_active_row_number()==0 ? (double)croph : (double)maxh));
scale->block (false);
wconn.block (false);
}
} }
if (listener && (enabled->get_active () || batchMode)) if (listener) {
listener->panelChanged (EvResizeHeight, Glib::ustring::format ((int)h->get_value())); if (spec->get_active_row_number() == 3)
notifyBBox();
else {
if (enabled->get_active () || batchMode)
listener->panelChanged (EvResizeHeight, Glib::ustring::format (h->get_value_as_int()));
}
}
} }
void Resize::specChanged () { void Resize::specChanged () {
switch (spec->get_active_row_number()) {
case (0):
// Scale mode
scale->sliderChanged ();
break;
case (1):
// Width mode
w->set_value((double)(getComputedWidth()));
entryWChanged ();
break;
case (2):
// Height mode
h->set_value((double)(getComputedHeight()));
entryHChanged ();
break;
case (3):
// Bounding box mode
notifyBBox();
default:
break;
}
updateGUI();
}
void Resize::updateGUI () {
removeIfThere (this, scale, false); removeIfThere (this, scale, false);
removeIfThere (this, sizeBox, false); removeIfThere (this, sizeBox, false);
if (spec->get_active_row_number() == 0) { switch (spec->get_active_row_number()) {
case (0):
// Scale mode
pack_start (*scale, Gtk::PACK_SHRINK, 4); pack_start (*scale, Gtk::PACK_SHRINK, 4);
scale->sliderChanged (); break;
} case (1):
else if (spec->get_active_row_number() == 1) { // Width mode
pack_start (*sizeBox, Gtk::PACK_SHRINK, 4); pack_start (*sizeBox, Gtk::PACK_SHRINK, 4);
w->set_sensitive (true); w->set_sensitive (true);
h->set_sensitive (false); h->set_sensitive (false);
entryWChanged (); break;
} case (2):
else if (spec->get_active_row_number() == 2) { // Height mode
pack_start (*sizeBox, Gtk::PACK_SHRINK, 4); pack_start (*sizeBox, Gtk::PACK_SHRINK, 4);
h->set_sensitive (true);
w->set_sensitive (false); w->set_sensitive (false);
entryHChanged (); h->set_sensitive (true);
break;
case (3):
// Bounding box mode
pack_start (*sizeBox, Gtk::PACK_SHRINK, 4);
w->set_sensitive (true);
h->set_sensitive (true);
default:
break;
} }
} }
void Resize::notifyBBox() {
if (listener && (enabled->get_active () || batchMode))
listener->panelChanged (EvResizeBoundingBox, Glib::ustring::compose("(%1x%2)",(int)w->get_value(), (int)h->get_value() ));
}
void Resize::setBatchMode (bool batchMode) { void Resize::setBatchMode (bool batchMode) {
method->append_text (M("GENERAL_UNCHANGED")); method->append_text (M("GENERAL_UNCHANGED"));

View File

@@ -29,12 +29,14 @@ class Resize : public Gtk::VBox, public AdjusterListener, public ToolPanel, publ
Gtk::CheckButton* enabled; Gtk::CheckButton* enabled;
Adjuster* scale; Adjuster* scale;
Gtk::VBox* sizeBox; Gtk::VBox* sizeBox;
Gtk::ComboBoxText* appliesTo;
Gtk::ComboBoxText* method; Gtk::ComboBoxText* method;
Gtk::ComboBoxText* spec; Gtk::ComboBoxText* spec;
Gtk::SpinButton* w; Gtk::SpinButton* w;
Gtk::SpinButton* h; Gtk::SpinButton* h;
int maxw, maxh; int maxw, maxh;
sigc::connection wconn, hconn, enaConn; int cropw, croph;
sigc::connection sconn, aconn, wconn, hconn, enaConn;
bool wDirty, hDirty, lastEnabled; bool wDirty, hDirty, lastEnabled;
public: public:
@@ -47,14 +49,24 @@ class Resize : public Gtk::VBox, public AdjusterListener, public ToolPanel, publ
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL);
void setBatchMode (bool batchMode); void setBatchMode (bool batchMode);
void adjusterChanged (Adjuster* a, double newval); void adjusterChanged (Adjuster* a, double newval);
void entryWChanged (); void entryWChanged ();
void entryHChanged (); void entryHChanged ();
void methodChanged (); void appliesToChanged ();
void specChanged (); void methodChanged ();
void sizeChanged (int w, int h, int ow, int oh); void specChanged ();
void setDimensions (int w, int h, int ow, int oh); void update (bool isCropped, int cw, int ch, int ow=0, int oh=0);
void enabledToggled (); void setGUIFromCrop (bool isCropped, int cw, int ch);
void sizeChanged (int w, int h, int ow, int oh);
void setDimensions ();
void enabledToggled ();
private:
void fitBoxScale ();
int getComputedWidth ();
int getComputedHeight ();
void notifyBBox ();
void updateGUI ();
}; };
#endif #endif

View File

@@ -36,19 +36,19 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
shadowshighlights = Gtk::manage (new ShadowsHighlights ()); shadowshighlights = Gtk::manage (new ShadowsHighlights ());
lumadenoise = Gtk::manage (new LumaDenoise ()); lumadenoise = Gtk::manage (new LumaDenoise ());
colordenoise = Gtk::manage (new ColorDenoise ()); colordenoise = Gtk::manage (new ColorDenoise ());
impulsedenoise = Gtk::manage (new ImpulseDenoise ()); impulsedenoise = Gtk::manage (new ImpulseDenoise ());
defringe = Gtk::manage (new Defringe ()); defringe = Gtk::manage (new Defringe ());
dirpyrdenoise = Gtk::manage (new DirPyrDenoise ()); dirpyrdenoise = Gtk::manage (new DirPyrDenoise ());
sharpening = Gtk::manage (new Sharpening ()); sharpening = Gtk::manage (new Sharpening ());
lcurve = Gtk::manage (new LCurve ()); lcurve = Gtk::manage (new LCurve ());
colorboost = Gtk::manage (new ColorBoost ()); colorboost = Gtk::manage (new ColorBoost ());
colorshift = Gtk::manage (new ColorShift ()); colorshift = Gtk::manage (new ColorShift ());
lensgeom = Gtk::manage (new LensGeometry ()); lensgeom = Gtk::manage (new LensGeometry ());
distortion = Gtk::manage (new Distortion ()); distortion = Gtk::manage (new Distortion ());
rotate = Gtk::manage (new Rotate ()); rotate = Gtk::manage (new Rotate ());
whitebalance = Gtk::manage (new WhiteBalance ()); whitebalance = Gtk::manage (new WhiteBalance ());
vignetting = Gtk::manage (new Vignetting ()); vignetting = Gtk::manage (new Vignetting ());
perspective = Gtk::manage (new PerspCorrection ()); perspective = Gtk::manage (new PerspCorrection ());
cacorrection = Gtk::manage (new CACorrection ()); cacorrection = Gtk::manage (new CACorrection ());
hlrecovery = Gtk::manage (new HLRecovery ()); hlrecovery = Gtk::manage (new HLRecovery ());
chmixer = Gtk::manage (new ChMixer ()); chmixer = Gtk::manage (new ChMixer ());
@@ -59,7 +59,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
iptcpanel = Gtk::manage (new IPTCPanel ()); iptcpanel = Gtk::manage (new IPTCPanel ());
equalizer = Gtk::manage (new Equalizer ()); equalizer = Gtk::manage (new Equalizer ());
dirpyrequalizer = Gtk::manage (new DirPyrEqualizer ()); dirpyrequalizer = Gtk::manage (new DirPyrEqualizer ());
hsvequalizer = Gtk::manage (new HSVEqualizer ()); hsvequalizer = Gtk::manage (new HSVEqualizer ());
rawprocess = Gtk::manage (new RawProcess ()); rawprocess = Gtk::manage (new RawProcess ());
preprocess = Gtk::manage (new PreProcess ()); preprocess = Gtk::manage (new PreProcess ());
@@ -71,14 +71,14 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
addPanel (detailsPanel, sharpening, M("TP_SHARPENING_LABEL")); toolPanels.push_back (sharpening); addPanel (detailsPanel, sharpening, M("TP_SHARPENING_LABEL")); toolPanels.push_back (sharpening);
addPanel (colorPanel, colorboost, M("TP_COLORBOOST_LABEL")); toolPanels.push_back (colorboost); addPanel (colorPanel, colorboost, M("TP_COLORBOOST_LABEL")); toolPanels.push_back (colorboost);
addPanel (colorPanel, colorshift, M("TP_COLORSHIFT_LABEL")); toolPanels.push_back (colorshift); addPanel (colorPanel, colorshift, M("TP_COLORSHIFT_LABEL")); toolPanels.push_back (colorshift);
addPanel (colorPanel, hsvequalizer, M("TP_HSVEQUALIZER_LABEL")); toolPanels.push_back (hsvequalizer); addPanel (colorPanel, hsvequalizer, M("TP_HSVEQUALIZER_LABEL")); toolPanels.push_back (hsvequalizer);
addPanel (exposurePanel, lcurve, M("TP_LABCURVE_LABEL")); toolPanels.push_back (lcurve); addPanel (exposurePanel, lcurve, M("TP_LABCURVE_LABEL")); toolPanels.push_back (lcurve);
addPanel (detailsPanel, impulsedenoise, M("TP_IMPULSEDENOISE_LABEL")); toolPanels.push_back (impulsedenoise); addPanel (detailsPanel, impulsedenoise, M("TP_IMPULSEDENOISE_LABEL")); toolPanels.push_back (impulsedenoise);
addPanel (detailsPanel, lumadenoise, M("TP_LUMADENOISE_LABEL")); toolPanels.push_back (lumadenoise); addPanel (detailsPanel, lumadenoise, M("TP_LUMADENOISE_LABEL")); toolPanels.push_back (lumadenoise);
addPanel (detailsPanel, colordenoise, M("TP_COLORDENOISE_LABEL")); toolPanels.push_back (colordenoise); addPanel (detailsPanel, colordenoise, M("TP_COLORDENOISE_LABEL")); toolPanels.push_back (colordenoise);
addPanel (detailsPanel, dirpyrdenoise, M("TP_DIRPYRDENOISE_LABEL")); toolPanels.push_back (dirpyrdenoise); addPanel (detailsPanel, dirpyrdenoise, M("TP_DIRPYRDENOISE_LABEL")); toolPanels.push_back (dirpyrdenoise);
addPanel (detailsPanel, defringe, M("TP_DEFRINGE_LABEL")); toolPanels.push_back (defringe); addPanel (detailsPanel, defringe, M("TP_DEFRINGE_LABEL")); toolPanels.push_back (defringe);
addPanel (detailsPanel, dirpyrequalizer, M("TP_DIRPYREQUALIZER_LABEL")); toolPanels.push_back (dirpyrequalizer); addPanel (detailsPanel, dirpyrequalizer, M("TP_DIRPYREQUALIZER_LABEL")); toolPanels.push_back (dirpyrequalizer);
addPanel (detailsPanel, equalizer, M("TP_EQUALIZER_LABEL")); toolPanels.push_back (equalizer); addPanel (detailsPanel, equalizer, M("TP_EQUALIZER_LABEL")); toolPanels.push_back (equalizer);
addPanel (transformPanel, crop, M("TP_CROP_LABEL")); toolPanels.push_back (crop); addPanel (transformPanel, crop, M("TP_CROP_LABEL")); toolPanels.push_back (crop);
addPanel (transformPanel, resize, M("TP_RESIZE_LABEL")); toolPanels.push_back (resize); addPanel (transformPanel, resize, M("TP_RESIZE_LABEL")); toolPanels.push_back (resize);
@@ -188,11 +188,7 @@ void ToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib::
toolPanels[i]->write (params); toolPanels[i]->write (params);
// some transformations make the crop change for convenience // some transformations make the crop change for convenience
if (event==rtengine::EvResizeScale) { if (event==rtengine::EvCTHFlip) {
crop->resizeScaleChanged (params->resize.scale);
crop->write (params);
}
else if (event==rtengine::EvCTHFlip) {
crop->hFlipCrop (); crop->hFlipCrop ();
crop->write (params); crop->write (params);
} }
@@ -203,6 +199,12 @@ void ToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib::
else if (event==rtengine::EvCTRotate) { else if (event==rtengine::EvCTRotate) {
crop->rotateCrop (params->coarse.rotate); crop->rotateCrop (params->coarse.rotate);
crop->write (params); crop->write (params);
resize->update (params->crop.enabled, params->crop.w, params->crop.h, ipc->getFullWidth(), ipc->getFullHeight());
resize->write (params);
}
else if (event==rtengine::EvCrop) {
resize->update (params->crop.enabled, params->crop.w, params->crop.h);
resize->write (params);
} }
ipc->paramsUpdateReady (); ipc->paramsUpdateReady ();
@@ -216,10 +218,15 @@ void ToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib::
void ToolPanelCoordinator::profileChange (const ProcParams *nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited) { void ToolPanelCoordinator::profileChange (const ProcParams *nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited) {
if (!ipc) return; if (!ipc) return;
ProcParams* params = ipc->getParamsForUpdate (event); ProcParams *params = ipc->getParamsForUpdate (event);
*params = *nparams; *params = *nparams;
for (int i=0; i<toolPanels.size(); i++)
toolPanels[i]->read (nparams); // trimming overflowing cropped area
crop->trim(params, ipc->getFullWidth(), ipc->getFullHeight());
// updating the GUI with updated values
for (unsigned int i=0; i<toolPanels.size(); i++)
toolPanels[i]->read (params);
ipc->paramsUpdateReady (); ipc->paramsUpdateReady ();