diff --git a/rtdata/languages/default b/rtdata/languages/default index 8fcd53686..54907f6f0 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1322,6 +1322,7 @@ HISTORY_MSG_FILMNEGATIVE_ENABLED;Film Negative HISTORY_MSG_FILMNEGATIVE_REF_SPOT;FN - Reference input HISTORY_MSG_FILMNEGATIVE_VALUES;Film negative values HISTORY_MSG_HISTMATCHING;Auto-matched tone curve +HISTORY_MSG_HLBL;Color propagation - blur HISTORY_MSG_ICM_OUTPUT_PRIMARIES;Output - Primaries HISTORY_MSG_ICM_OUTPUT_TEMP;Output - ICC-v4 illuminant D HISTORY_MSG_ICM_OUTPUT_TYPE;Output - Type @@ -2367,6 +2368,7 @@ TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. TP_HLREC_BLEND;Blend TP_HLREC_CIELAB;CIELab Blending TP_HLREC_COLOR;Color Propagation +TP_HLREC_HLBLUR;Blur TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. TP_HLREC_LABEL;Highlight reconstruction TP_HLREC_LUMINANCE;Luminance Recovery diff --git a/rtengine/array2D.h b/rtengine/array2D.h index ca4db3d06..ba2e6a5d3 100644 --- a/rtengine/array2D.h +++ b/rtengine/array2D.h @@ -124,6 +124,26 @@ public: } } + // creator type 3 + array2D(int w, int h, int startx, int starty, T ** source, unsigned int flags = 0) : width(w) + { + rows.resize(h); + if (!(flags & ARRAY2D_BYREFERENCE)) { + buffer.resize(h * width); + T* start = buffer.data(); + for (ssize_t i = 0; i < h; ++i) { + rows[i] = start + i * width; + for (ssize_t j = 0; j < width; ++j) { + rows[i][j] = source[i + starty][j + startx]; + } + } + } else { + for (ssize_t i = 0; i < h; ++i) { + rows[i] = source[i + starty] + startx; + } + } + } + array2D(const array2D& other) : width(other.width), buffer(other.buffer) diff --git a/rtengine/color.h b/rtengine/color.h index b6bf60818..0fae99a5d 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -206,6 +206,11 @@ public: return static_cast(r) * workingspace[1][0] + static_cast(g) * workingspace[1][1] + static_cast(b) * workingspace[1][2]; } + static float rgbLuminance(float r, float g, float b, const float workingspace[3]) + { + return r * workingspace[0] + g * workingspace[1] + b * workingspace[2]; + } + #ifdef __SSE2__ static vfloat rgbLuminance(vfloat r, vfloat g, vfloat b, const vfloat workingspace[3]) { diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index 4902ad2c2..a45e5d345 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -32,8 +32,8 @@ #include "opthelper.h" #include "rawimagesource.h" #include "rt_math.h" -#define BENCHMARK -#include "StopWatch.h" +//#define BENCHMARK +//#include "StopWatch.h" #include "guidedfilter.h" #include "settings.h" #include "gauss.h" @@ -299,9 +299,9 @@ extern const Settings *settings; using namespace procparams; const ProcParams params; -void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue) +void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue, int blur) { - BENCHFUN + // BENCHFUN double progress = 0.0; if (plistener) { @@ -318,7 +318,7 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue constexpr float threshpct = 0.25f; constexpr float maxpct = 0.95f; constexpr float epsilon = 0.00001f; - //%%%%%%%%%%%%%%%%%%%% + //for blend algorithm: constexpr float blendthresh = 1.0; // Transform matrixes rgb>lab and back @@ -424,11 +424,6 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue return; } - // if (plistener) { - // progress += 0.05; - // plistener->setProgress(progress); - // } - constexpr int blurBorder = 256; minx = std::max(0, minx - blurBorder); miny = std::max(0, miny - blurBorder); @@ -442,21 +437,8 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue array2D temp(bufferWidth, blurHeight); // allocate temporary buffer // blur RGB channels - boxblur2(red, channelblur[0], temp, miny, minx, blurHeight, blurWidth, bufferWidth, 4); - - // if (plistener) { - // progress += 0.07; - // plistener->setProgress(progress); - // } - boxblur2(green, channelblur[1], temp, miny, minx, blurHeight, blurWidth, bufferWidth, 4); - - // if (plistener) { -// progress += 0.07; - // plistener->setProgress(progress); - // } - boxblur2(blue, channelblur[2], temp, miny, minx, blurHeight, blurWidth, bufferWidth, 4); if (plistener) { @@ -470,7 +452,7 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue #endif for (int i = 0; i < blurHeight; ++i) { for (int j = 0; j < blurWidth; ++j) { - channelblur[0][i][j] = fabsf(channelblur[0][i][j] - red[i + miny][j + minx]) + fabsf(channelblur[1][i][j] - green[i + miny][j + minx]) + fabsf(channelblur[2][i][j] - blue[i + miny][j + minx]); + channelblur[0][i][j] = std::fabs(channelblur[0][i][j] - red[i + miny][j + minx]) + std::fabs(channelblur[1][i][j] - green[i + miny][j + minx]) + std::fabs(channelblur[2][i][j] - blue[i + miny][j + minx]); } } @@ -529,7 +511,7 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue } array2D hilite_full4(bufferWidth, blurHeight); - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //blur highlight data boxblur2(hilite_full[3], hilite_full4, temp, 0, 0, blurHeight, blurWidth, bufferWidth, 1); @@ -566,9 +548,7 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue multi_array2D hilite(hfw + 1, hfh + 1, ARRAY2D_CLEAR_DATA, 48); - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // blur and resample highlight data; range=size of blur, pitch=sample spacing - array2D temp2(blurWidth / pitch + (blurWidth % pitch == 0 ? 0 : 1), blurHeight); for (int m = 0; m < 4; ++m) { @@ -651,11 +631,11 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue } if (hilite[3][2][j] <= epsilon) { - hilite_dir[0 + c][0][j] = hilite_dir0[c][j][2]; + hilite_dir[0 + c][0][j] = hilite_dir0[c][j][2]; } if (hilite[3][3][j] <= epsilon) { - hilite_dir[0 + c][1][j] = hilite_dir0[c][j][3]; + hilite_dir[0 + c][1][j] = hilite_dir0[c][j][3]; } if (hilite[3][hfh - 3][j] <= epsilon) { @@ -938,38 +918,43 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue hilite[c].free(); } - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // now reconstruct clipped channels using color ratios //using code from ART - thanks to Alberto Griggio - const int W2 = float(W) / 2.f + 0.5f; - const int H2 = float(H) / 2.f + 0.5f; + const int W2 = blur > 0 ? blurWidth / 2.f + 0.5f : 0; + const int H2 = blur > 0 ? blurHeight / 2.f + 0.5f : 0; array2D mask(W2, H2, ARRAY2D_CLEAR_DATA); array2D rbuf(W2, H2); array2D gbuf(W2, H2); array2D bbuf(W2, H2); array2D guide(W2, H2); - using rtengine::TMatrix; - TMatrix ws = ICCStore::getInstance()->workingSpaceMatrix(params.icm.workingProfile); - - { - array2D rsrc(W, H, red, ARRAY2D_BYREFERENCE); - array2D gsrc(W, H, green, ARRAY2D_BYREFERENCE); - array2D bsrc(W, H, blue, ARRAY2D_BYREFERENCE); - rescaleNearest(rsrc, rbuf, true); - rescaleNearest(gsrc, gbuf, true); - rescaleNearest(bsrc, bbuf, true); + if (blur > 0) { + array2D rbuffer(blurWidth, blurHeight, minx, miny, red, ARRAY2D_BYREFERENCE); + rescaleNearest(rbuffer, rbuf, true); + array2D gbuffer(blurWidth, blurHeight, minx, miny, green, ARRAY2D_BYREFERENCE); + rescaleNearest(gbuffer, gbuf, true); + array2D bbuffer(blurWidth, blurHeight, minx, miny, blue, ARRAY2D_BYREFERENCE); + rescaleNearest(bbuffer, bbuf, true); + LUTf gamma(65536); #ifdef _OPENMP -# pragma omp parallel for + #pragma omp parallel for +#endif + for (int i = 0; i < 65536; ++i) { + gamma[i] = pow_F(i / 65535.f, 2.2f); + } + + const float xyzcam[3] = {static_cast(imatrices.xyz_cam[1][0]), static_cast(imatrices.xyz_cam[1][1]), static_cast(imatrices.xyz_cam[1][2])}; +#ifdef _OPENMP + #pragma omp parallel for #endif for (int y = 0; y < H2; ++y) { for (int x = 0; x < W2; ++x) { - guide[y][x] = Color::igamma_srgb(Color::rgbLuminance(static_cast(rbuf[y][x]), static_cast(gbuf[y][x]), static_cast(bbuf[y][x]), ws)); + guide[y][x] = gamma[Color::rgbLuminance(rbuf[y][x], gbuf[y][x], bbuf[y][x], xyzcam)]; } } } -//end addind code ART +//end adding code ART #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) @@ -1050,21 +1035,20 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue // Copy converted pixel back if (pixel[0] > blendpt) { const float rfrac = LIM01(medFactor[0] * (pixel[0] - blendpt)); - rgb_blend[0] = rfrac * rgb[0] + (1.f - rfrac) * pixel[0]; + rgb_blend[0] = intp(rfrac, rgb[0], pixel[0]); } if (pixel[1] > blendpt) { const float gfrac = LIM01(medFactor[1] * (pixel[1] - blendpt)); - rgb_blend[1] = gfrac * rgb[1] + (1.f - gfrac) * pixel[1]; + rgb_blend[1] = intp(gfrac, rgb[1], pixel[1]); } if (pixel[2] > blendpt) { const float bfrac = LIM01(medFactor[2] * (pixel[2] - blendpt)); - rgb_blend[2] = bfrac * rgb[2] + (1.f - bfrac) * pixel[2]; + rgb_blend[2] = intp(bfrac, rgb[2], pixel[2]); } //end of HLRecovery_blend estimation - //%%%%%%%%%%%%%%%%%%%%%%% //there are clipped highlights //first, determine weighted average of unclipped extensions (weighting is by 'hue' proximity) @@ -1090,7 +1074,7 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue } for (int dir = 0; dir < 2; ++dir) { - const float Yhi2 = 1.f / ( hilite_dir[dir * 4 + 0][i1][j1] + hilite_dir[dir * 4 + 1][i1][j1] + hilite_dir[dir * 4 + 2][i1][j1]); + const float Yhi2 = 1.f / (hilite_dir[dir * 4 + 0][i1][j1] + hilite_dir[dir * 4 + 1][i1][j1] + hilite_dir[dir * 4 + 2][i1][j1]); if (Yhi2 < 2.f) { const float dirwt = 1.f / ((1.f + 65535.f * (SQR(rgb_blend[0] - hilite_dir[dir * 4 + 0][i1][j1] * Yhi2) + @@ -1119,10 +1103,11 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue if (UNLIKELY(!totwt)) { continue; } + //using code from ART - thanks to Alberto Griggio float maskval = 1.f; - int yy = i + miny; - int xx = j + minx; + const int yy = i + miny; + const int xx = j + minx; //now correct clipped channels if (pixel[0] > max_f[0] && pixel[1] > max_f[1] && pixel[2] > max_f[2]) { @@ -1160,63 +1145,81 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue if (Y > whitept) { const float mult = whitept / Y; - - red[yy][xx] *= mult; + red[yy][xx] *= mult; green[yy][xx] *= mult; - blue[yy][xx] *= mult; + blue[yy][xx] *= mult; } - int ii = (yy) / 2; - int jj = (xx) / 2; - rbuf[ii][jj] = red[yy][xx]; - gbuf[ii][jj] = green[yy][xx]; - bbuf[ii][jj] = blue[yy][xx]; - mask[ii][jj] = maskval; + if (blur > 0) { + const int ii = i / 2; + const int jj = j / 2; + rbuf[ii][jj] = red[yy][xx]; + gbuf[ii][jj] = green[yy][xx]; + bbuf[ii][jj] = blue[yy][xx]; + mask[ii][jj] = maskval; + } } } - if (plistener) { - progress += 0.05; - plistener->setProgress(progress); - } - -// #ifdef _OPENMP -// #pragma omp parallel -// #endif - { - //gaussianBlur(mask, mask, W/2, H/2, 5); - // gaussianBlur(rbuf, rbuf, W/2, H/2, 1); - // gaussianBlur(gbuf, gbuf, W/2, H/2, 1); - // gaussianBlur(bbuf, bbuf, W/2, H/2, 1); - guidedFilter(guide, mask, mask, 2, 0.001f, true, 1); - guidedFilter(guide, rbuf, rbuf, 3, 0.01f * 65535.f, true, 1); - guidedFilter(guide, gbuf, gbuf, 3, 0.01f * 65535.f, true, 1); - guidedFilter(guide, bbuf, bbuf, 3, 0.01f * 65535.f, true, 1); - } + if (blur > 0) { + if (plistener) { + progress += 0.05; + plistener->setProgress(progress); + } + blur = rtengine::LIM(blur - 1, 0, 3); - { + constexpr float vals[4][3] = {{4.0f, 0.3f, 0.3f}, + // {3.5f, 0.5f, 0.2f}, + {3.0f, 1.0f, 0.1f}, + {3.0f, 2.0f, 0.01f}, + {2.0f, 3.0f, 0.001f} + }; + + const float rad1 = vals[blur][0]; + const float rad2 = vals[blur][1]; + const float th = vals[blur][2]; + + guidedFilter(guide, mask, mask, rad1, th, true, 1); + if (plistener) { + progress += 0.03; + plistener->setProgress(progress); + } + if (blur > 0) { //no use of 2nd guidedFilter if Blur = 0 (slider to 1)..speed-up and very small differences. + guidedFilter(guide, rbuf, rbuf, rad2, 0.01f * 65535.f, true, 1); + if (plistener) { + progress += 0.03; + plistener->setProgress(progress); + } + guidedFilter(guide, gbuf, gbuf, rad2, 0.01f * 65535.f, true, 1); + if (plistener) { + progress += 0.03; + plistener->setProgress(progress); + } + guidedFilter(guide, bbuf, bbuf, rad2, 0.01f * 65535.f, true, 1); + if (plistener) { + progress += 0.03; + plistener->setProgress(progress); + } + } #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for schedule(dynamic,16) #endif - for (int y = 0; y < H; ++y) { - float fy = y * 0.5f; - int yy = y / 2; - for (int x = 0; x < W; ++x) { - float fx = x * 0.5f; - int xx = x / 2; - float m = mask[yy][xx]; + for (int y = 0; y < blurHeight; ++y) { + const float fy = y * 0.5f; + const int yy = y / 2; + for (int x = 0; x < blurWidth; ++x) { + const int xx = x / 2; + const float m = mask[yy][xx]; if (m > 0.f) { - red[y][x] = intp(m, getBilinearValue(rbuf, fx, fy), red[y][x]); - green[y][x] = intp(m, getBilinearValue(gbuf, fx, fy), green[y][x]); - blue[y][x] = intp(m, getBilinearValue(bbuf, fx, fy), blue[y][x]); + const float fx = x * 0.5f; + red[y + miny][x + minx] = intp(m, getBilinearValue(rbuf, fx, fy), red[y + miny][x + minx]); + green[y + miny][x + minx] = intp(m, getBilinearValue(gbuf, fx, fy), green[y + miny][x + minx]); + blue[y + miny][x + minx] = intp(m, getBilinearValue(bbuf, fx, fy), blue[y + miny][x + minx]); } } } } - - - if (plistener) { plistener->setProgress(1.00); } diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index a1c3731f1..25c024ed2 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -98,7 +98,6 @@ public: virtual void retinexPrepareBuffers (const procparams::ColorManagementParams& cmp, const procparams::RetinexParams &retinexParams, multi_array2D &conversionBuffer, LUTu &lhist16RETI) {}; virtual void flush () = 0; virtual void HLRecovery_Global (const procparams::ToneCurveParams &hrp) {}; - virtual void HLRecovery_inpaint (float** red, float** green, float** blue) {}; virtual bool isRGBSourceModified () const = 0; // tracks whether cached rgb output of demosaic has been modified diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 0bbcaa907..5a1bb0ff8 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -385,6 +385,7 @@ ToneCurveParams::ToneCurveParams() : saturation(0), shcompr(50), hlcompr(0), + hlbl(0), hlcomprthresh(0), histmatching(false), fromHistMatching(false), @@ -410,6 +411,7 @@ bool ToneCurveParams::isPanningRelatedChange(const ToneCurveParams& other) const && saturation == other.saturation && shcompr == other.shcompr && hlcompr == other.hlcompr + && hlbl == other.hlbl && hlcomprthresh == other.hlcomprthresh && histmatching == other.histmatching && clampOOG == other.clampOOG); @@ -433,6 +435,7 @@ bool ToneCurveParams::operator ==(const ToneCurveParams& other) const && saturation == other.saturation && shcompr == other.shcompr && hlcompr == other.hlcompr + && hlbl == other.hlbl && hlcomprthresh == other.hlcomprthresh && histmatching == other.histmatching && fromHistMatching == other.fromHistMatching @@ -5399,6 +5402,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo // Highlight recovery saveToKeyfile(!pedited || pedited->toneCurve.hrenabled, "HLRecovery", "Enabled", toneCurve.hrenabled, keyFile); saveToKeyfile(!pedited || pedited->toneCurve.method, "HLRecovery", "Method", toneCurve.method, keyFile); + saveToKeyfile(!pedited || pedited->toneCurve.hlbl, "HLRecovery", "Hlbl", toneCurve.hlbl, keyFile); const std::map tc_mapping = { {ToneCurveMode::STD, "Standard"}, @@ -6924,6 +6928,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) if (keyFile.has_group("HLRecovery")) { assignFromKeyfile(keyFile, "HLRecovery", "Enabled", pedited, toneCurve.hrenabled, pedited->toneCurve.hrenabled); assignFromKeyfile(keyFile, "HLRecovery", "Method", pedited, toneCurve.method, pedited->toneCurve.method); + assignFromKeyfile(keyFile, "HLRecovery", "Hlbl", pedited, toneCurve.hlbl, pedited->toneCurve.hlbl); } if (keyFile.has_group("Channel Mixer")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 45ce8005d..1a215b3d0 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -297,6 +297,7 @@ struct ToneCurveParams { int saturation; int shcompr; int hlcompr; // Highlight Recovery's compression + int hlbl; // Highlight Recovery's compression int hlcomprthresh; // Highlight Recovery's threshold bool histmatching; // histogram matching bool fromHistMatching; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index de0f07422..7ae919e0a 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -2438,7 +2438,7 @@ void RawImageSource::HLRecovery_Global(const ToneCurveParams &hrp) printf ("Applying Highlight Recovery: Color propagation...\n"); } - HLRecovery_inpaint (red, green, blue); + HLRecovery_inpaint (red, green, blue, hrp.hlbl); rgbSourceModified = true; } } diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 945c9da3d..16677b1da 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -195,7 +195,7 @@ public: static void inverse33(const double (*coeff)[3], double (*icoeff)[3]); void MSR(float** luminance, float **originalLuminance, float **exLuminance, const LUTf& mapcurve, bool mapcontlutili, int width, int height, const procparams::RetinexParams &deh, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax); - void HLRecovery_inpaint (float** red, float** green, float** blue) override; + void HLRecovery_inpaint (float** red, float** green, float** blue, int blur); static void HLRecovery_Luminance (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval); static void HLRecovery_CIELab (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval, double cam[3][3], double icam[3][3]); static void HLRecovery_blend (float* rin, float* gin, float* bin, int width, float maxval, float* hlmax); diff --git a/rtengine/rescale.h b/rtengine/rescale.h index 3126a7c58..2a5892224 100644 --- a/rtengine/rescale.h +++ b/rtengine/rescale.h @@ -35,23 +35,22 @@ inline float getBilinearValue(const array2D &src, float x, float y) const int H = src.getHeight(); // Get integer and fractional parts of numbers - int xi = x; - int yi = y; - float xf = x - xi; - float yf = y - yi; - int xi1 = std::min(xi + 1, W - 1); - int yi1 = std::min(yi + 1, H - 1); + const int xi = x; + const int yi = y; + const float xf = x - xi; + const float yf = y - yi; + const int xi1 = std::min(xi + 1, W - 1); + const int yi1 = std::min(yi + 1, H - 1); - float bl = src[yi][xi]; - float br = src[yi][xi1]; - float tl = src[yi1][xi]; - float tr = src[yi1][xi1]; + const float bl = src[yi][xi]; + const float br = src[yi][xi1]; + const float tl = src[yi1][xi]; + const float tr = src[yi1][xi1]; // interpolate - float b = xf * br + (1.f - xf) * bl; - float t = xf * tr + (1.f - xf) * tl; - float pxf = yf * t + (1.f - yf) * b; - return pxf; + const float b = intp(xf, br, bl); + const float t = intp(xf, tr, tl); + return intp(yf, t, b); } diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index d202577cf..a75fe8562 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -47,6 +47,7 @@ void ParamsEdited::set(bool v) toneCurve.saturation = v; toneCurve.shcompr = v; toneCurve.hlcompr = v; + toneCurve.hlbl = v; toneCurve.hlcomprthresh = v; toneCurve.autoexp = v; toneCurve.clip = v; @@ -720,6 +721,7 @@ void ParamsEdited::initFrom(const std::vector& toneCurve.saturation = toneCurve.saturation && p.toneCurve.saturation == other.toneCurve.saturation; toneCurve.shcompr = toneCurve.shcompr && p.toneCurve.shcompr == other.toneCurve.shcompr; toneCurve.hlcompr = toneCurve.hlcompr && p.toneCurve.hlcompr == other.toneCurve.hlcompr; + toneCurve.hlbl = toneCurve.hlbl && p.toneCurve.hlbl == other.toneCurve.hlbl; toneCurve.hlcomprthresh = toneCurve.hlcomprthresh && p.toneCurve.hlcomprthresh == other.toneCurve.hlcomprthresh; toneCurve.autoexp = toneCurve.autoexp && p.toneCurve.autoexp == other.toneCurve.autoexp; toneCurve.clip = toneCurve.clip && p.toneCurve.clip == other.toneCurve.clip; @@ -2008,6 +2010,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.toneCurve.method = mods.toneCurve.method; } + if (toneCurve.hlbl) { + toEdit.toneCurve.hlbl = mods.toneCurve.hlbl; + } + if (toneCurve.histmatching) { toEdit.toneCurve.histmatching = mods.toneCurve.histmatching; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 3b524c23f..ec1d9b8f4 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -51,6 +51,7 @@ struct ToneCurveParamsEdited { bool saturation; bool shcompr; bool hlcompr; + bool hlbl; bool hlcomprthresh; bool autoexp; bool clip; diff --git a/rtgui/tonecurve.cc b/rtgui/tonecurve.cc index 5e6f1fe31..8a33575ca 100644 --- a/rtgui/tonecurve.cc +++ b/rtgui/tonecurve.cc @@ -21,12 +21,9 @@ #include #include "tonecurve.h" - -#include "adjuster.h" #include "curveeditor.h" #include "curveeditorgroup.h" #include "eventmapper.h" -#include "ppversion.h" #include "options.h" #include "../rtengine/procparams.h" @@ -36,18 +33,19 @@ using namespace rtengine; using namespace rtengine::procparams; -ToneCurve::ToneCurve () : FoldableToolPanel(this, "tonecurve", M("TP_EXPOSURE_LABEL")) +ToneCurve::ToneCurve() : FoldableToolPanel(this, "tonecurve", M("TP_EXPOSURE_LABEL")) { auto m = ProcEventMapper::getInstance(); EvHistMatching = m->newEvent(AUTOEXP, "HISTORY_MSG_HISTMATCHING"); EvHistMatchingBatch = m->newEvent(M_VOID, "HISTORY_MSG_HISTMATCHING"); EvClampOOG = m->newEvent(DARKFRAME, "HISTORY_MSG_CLAMPOOG"); + EvHLbl = m->newEvent(DEMOSAIC, "HISTORY_MSG_HLBL"); CurveListener::setMulti(true); std::vector bottomMilestones; - bottomMilestones.push_back( GradientMilestone(0., 0., 0., 0.) ); - bottomMilestones.push_back( GradientMilestone(1., 1., 1., 1.) ); + bottomMilestones.push_back(GradientMilestone(0., 0., 0., 0.)); + bottomMilestones.push_back(GradientMilestone(1., 1., 1., 1.)); //----------- OOG clamping ---------------------------------- clampOOG = Gtk::manage(new Gtk::CheckButton(M("TP_EXPOSURE_CLAMPOOG"))); @@ -59,33 +57,33 @@ ToneCurve::ToneCurve () : FoldableToolPanel(this, "tonecurve", M("TP_EXPOSURE_LA abox = Gtk::manage (new Gtk::Box ()); abox->set_spacing (4); - autolevels = Gtk::manage (new Gtk::ToggleButton (M("TP_EXPOSURE_AUTOLEVELS"))); - autolevels->set_tooltip_markup (M("TP_EXPOSURE_AUTOLEVELS_TIP")); - autoconn = autolevels->signal_toggled().connect( sigc::mem_fun(*this, &ToneCurve::autolevels_toggled) ); + autolevels = Gtk::manage(new Gtk::ToggleButton(M("TP_EXPOSURE_AUTOLEVELS"))); + autolevels->set_tooltip_markup(M("TP_EXPOSURE_AUTOLEVELS_TIP")); + autoconn = autolevels->signal_toggled().connect(sigc::mem_fun(*this, &ToneCurve::autolevels_toggled)); - lclip = Gtk::manage (new Gtk::Label (M("TP_EXPOSURE_CLIP"))); - lclip->set_tooltip_text (M("TP_EXPOSURE_CLIP_TIP")); + lclip = Gtk::manage(new Gtk::Label(M("TP_EXPOSURE_CLIP"))); + lclip->set_tooltip_text(M("TP_EXPOSURE_CLIP_TIP")); - sclip = Gtk::manage (new MySpinButton ()); - sclip->set_range (0.0, 0.99); - sclip->set_increments (0.01, 0.10); - sclip->set_value (0.02); - sclip->set_digits (2); + sclip = Gtk::manage(new MySpinButton()); + sclip->set_range(0.0, 0.99); + sclip->set_increments(0.01, 0.10); + sclip->set_value(0.02); + sclip->set_digits(2); sclip->set_width_chars(4); sclip->set_max_width_chars(4); - sclip->signal_value_changed().connect( sigc::mem_fun(*this, &ToneCurve::clip_changed) ); + sclip->signal_value_changed().connect(sigc::mem_fun(*this, &ToneCurve::clip_changed)); - neutral = Gtk::manage (new Gtk::Button (M("TP_NEUTRAL"))); - neutral->set_tooltip_text (M("TP_NEUTRAL_TIP")); - neutralconn = neutral->signal_pressed().connect( sigc::mem_fun(*this, &ToneCurve::neutral_pressed) ); + neutral = Gtk::manage(new Gtk::Button(M("TP_NEUTRAL"))); + neutral->set_tooltip_text(M("TP_NEUTRAL_TIP")); + neutralconn = neutral->signal_pressed().connect(sigc::mem_fun(*this, &ToneCurve::neutral_pressed)); neutral->show(); - abox->pack_start (*autolevels, true, true, 0); + abox->pack_start(*autolevels, true, true, 0); // pack_end is used for these controls as autolevels is replaceable using pack_start in batchmode - abox->pack_end (*neutral, true, true, 0); - abox->pack_end (*sclip, false, false, 0); - abox->pack_end (*lclip, false, false, 0); - pack_start (*abox); + abox->pack_end(*neutral, true, true, 0); + abox->pack_end(*sclip, false, false, 0); + abox->pack_end(*lclip, false, false, 0); + pack_start(*abox); //-------------- Highlight Reconstruction ----------------- pack_start (*Gtk::manage (new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL))); @@ -93,20 +91,31 @@ ToneCurve::ToneCurve () : FoldableToolPanel(this, "tonecurve", M("TP_EXPOSURE_LA hrenabled = Gtk::manage (new Gtk::CheckButton (M("TP_HLREC_LABEL"))); hrenabled->set_active (false); hrenabled->set_tooltip_markup (M("TP_HLREC_ENA_TOOLTIP")); - pack_start (*hrenabled); method = Gtk::manage (new MyComboBoxText ()); method->append (M("TP_HLREC_LUMINANCE")); method->append (M("TP_HLREC_CIELAB")); method->append (M("TP_HLREC_COLOR")); method->append (M("TP_HLREC_BLEND")); + Gtk::Box *hrVBox; + hrVBox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); + hrVBox->set_spacing(2); + + method->set_active(0); + Gtk::Frame* const hrFrame = Gtk::manage(new Gtk::Frame()); + hrFrame->set_label_align(0.025, 0.5); + hrFrame->set_label_widget(*hrenabled); - method->set_active (0); hlrbox = Gtk::manage (new Gtk::Box ()); Gtk::Label* lab = Gtk::manage (new Gtk::Label (M("TP_HLREC_METHOD"))); - hlrbox->pack_start (*lab, Gtk::PACK_SHRINK, 4); + hlrbox->pack_start (*lab, Gtk::PACK_SHRINK); hlrbox->pack_start (*method); - pack_start (*hlrbox); + hlbl = Gtk::manage(new Adjuster(M("TP_HLREC_HLBLUR"), 0, 4, 1, 0)); + + hrVBox->pack_start(*hlrbox, Gtk::PACK_SHRINK); + hrVBox->pack_start(*hlbl); + hrFrame->add(*hrVBox); + pack_start(*hrFrame); enaconn = hrenabled->signal_toggled().connect( sigc::mem_fun(*this, &ToneCurve::hrenabledChanged) ); methconn = method->signal_changed().connect ( sigc::mem_fun(*this, &ToneCurve::methodChanged) ); @@ -114,32 +123,32 @@ ToneCurve::ToneCurve () : FoldableToolPanel(this, "tonecurve", M("TP_EXPOSURE_LA //----------- Exposure Compensation --------------------- pack_start (*Gtk::manage (new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL))); - expcomp = Gtk::manage (new Adjuster (M("TP_EXPOSURE_EXPCOMP"), -5, 12, 0.05, 0)); + expcomp = Gtk::manage(new Adjuster(M("TP_EXPOSURE_EXPCOMP"), -5, 12, 0.05, 0)); expcomp->setLogScale(2, 0, true); - pack_start (*expcomp); + pack_start(*expcomp); //----------- Highlight recovery & threshold ------------- - hlcompr = Gtk::manage (new Adjuster (M("TP_EXPOSURE_COMPRHIGHLIGHTS"), 0, 500, 1, 0)); - pack_start (*hlcompr); - hlcomprthresh = Gtk::manage (new Adjuster (M("TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD"), 0, 100, 1, 0)); - pack_start (*hlcomprthresh); + hlcompr = Gtk::manage(new Adjuster(M("TP_EXPOSURE_COMPRHIGHLIGHTS"), 0, 500, 1, 0)); + pack_start(*hlcompr); + hlcomprthresh = Gtk::manage(new Adjuster(M("TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD"), 0, 100, 1, 0)); + pack_start(*hlcomprthresh); //----------- Black Level & Compression ------------------- - black = Gtk::manage (new Adjuster (M("TP_EXPOSURE_BLACKLEVEL"), -16384, 32768, 50, 0)); + black = Gtk::manage(new Adjuster(M("TP_EXPOSURE_BLACKLEVEL"), -16384, 32768, 50, 0)); black->setLogScale(10, 0, true); - pack_start (*black); - shcompr = Gtk::manage (new Adjuster (M("TP_EXPOSURE_COMPRSHADOWS"), 0, 100, 1, 50)); - pack_start (*shcompr); + pack_start(*black); + shcompr = Gtk::manage(new Adjuster(M("TP_EXPOSURE_COMPRSHADOWS"), 0, 100, 1, 50)); + pack_start(*shcompr); pack_start (*Gtk::manage (new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL))); //---------Brightness / Contrast ------------------------- - brightness = Gtk::manage (new Adjuster (M("TP_EXPOSURE_BRIGHTNESS"), -100, 100, 1, 0)); - pack_start (*brightness); - contrast = Gtk::manage (new Adjuster (M("TP_EXPOSURE_CONTRAST"), -100, 100, 1, 0)); - pack_start (*contrast); - saturation = Gtk::manage (new Adjuster (M("TP_EXPOSURE_SATURATION"), -100, 100, 1, 0)); - pack_start (*saturation); + brightness = Gtk::manage(new Adjuster(M("TP_EXPOSURE_BRIGHTNESS"), -100, 100, 1, 0)); + pack_start(*brightness); + contrast = Gtk::manage(new Adjuster(M("TP_EXPOSURE_CONTRAST"), -100, 100, 1, 0)); + pack_start(*contrast); + saturation = Gtk::manage(new Adjuster(M("TP_EXPOSURE_SATURATION"), -100, 100, 1, 0)); + pack_start(*saturation); brightness->setLogScale(2, 0, true); contrast->setLogScale(2, 0, true); @@ -153,18 +162,18 @@ ToneCurve::ToneCurve () : FoldableToolPanel(this, "tonecurve", M("TP_EXPOSURE_LA histmatchconn = histmatching->signal_toggled().connect(sigc::mem_fun(*this, &ToneCurve::histmatchingToggled)); pack_start(*histmatching, true, true, 2); - toneCurveMode = Gtk::manage (new MyComboBoxText ()); - toneCurveMode->append (M("TP_EXPOSURE_TCMODE_STANDARD")); - toneCurveMode->append (M("TP_EXPOSURE_TCMODE_WEIGHTEDSTD")); - toneCurveMode->append (M("TP_EXPOSURE_TCMODE_FILMLIKE")); - toneCurveMode->append (M("TP_EXPOSURE_TCMODE_SATANDVALBLENDING")); - toneCurveMode->append (M("TP_EXPOSURE_TCMODE_LUMINANCE")); - toneCurveMode->append (M("TP_EXPOSURE_TCMODE_PERCEPTUAL")); - toneCurveMode->set_active (0); + toneCurveMode = Gtk::manage(new MyComboBoxText()); + toneCurveMode->append(M("TP_EXPOSURE_TCMODE_STANDARD")); + toneCurveMode->append(M("TP_EXPOSURE_TCMODE_WEIGHTEDSTD")); + toneCurveMode->append(M("TP_EXPOSURE_TCMODE_FILMLIKE")); + toneCurveMode->append(M("TP_EXPOSURE_TCMODE_SATANDVALBLENDING")); + toneCurveMode->append(M("TP_EXPOSURE_TCMODE_LUMINANCE")); + toneCurveMode->append(M("TP_EXPOSURE_TCMODE_PERCEPTUAL")); + toneCurveMode->set_active(0); toneCurveMode->set_tooltip_text(M("TP_EXPOSURE_TCMODE_LABEL1")); - curveEditorG = new CurveEditorGroup (options.lastToneCurvesDir, M("TP_EXPOSURE_CURVEEDITOR1")); - curveEditorG->setCurveListener (this); + curveEditorG = new CurveEditorGroup(options.lastToneCurvesDir, M("TP_EXPOSURE_CURVEEDITOR1")); + curveEditorG->setCurveListener(this); shape = static_cast(curveEditorG->addCurve(CT_Diagonal, "", toneCurveMode)); shape->setEditID(EUID_ToneCurve1, BT_IMAGEFLOAT); @@ -174,24 +183,24 @@ ToneCurve::ToneCurve () : FoldableToolPanel(this, "tonecurve", M("TP_EXPOSURE_LA // This will add the reset button at the end of the curveType buttons curveEditorG->curveListComplete(); - pack_start( *curveEditorG, Gtk::PACK_SHRINK, 2); + pack_start(*curveEditorG, Gtk::PACK_SHRINK, 2); - tcmodeconn = toneCurveMode->signal_changed().connect( sigc::mem_fun(*this, &ToneCurve::curveMode1Changed), true ); + tcmodeconn = toneCurveMode->signal_changed().connect(sigc::mem_fun(*this, &ToneCurve::curveMode1Changed), true); //----------- Curve 2 ------------------------------ - toneCurveMode2 = Gtk::manage (new MyComboBoxText ()); - toneCurveMode2->append (M("TP_EXPOSURE_TCMODE_STANDARD")); - toneCurveMode2->append (M("TP_EXPOSURE_TCMODE_WEIGHTEDSTD")); - toneCurveMode2->append (M("TP_EXPOSURE_TCMODE_FILMLIKE")); - toneCurveMode2->append (M("TP_EXPOSURE_TCMODE_SATANDVALBLENDING")); - toneCurveMode2->append (M("TP_EXPOSURE_TCMODE_LUMINANCE")); - toneCurveMode2->append (M("TP_EXPOSURE_TCMODE_PERCEPTUAL")); - toneCurveMode2->set_active (0); + toneCurveMode2 = Gtk::manage(new MyComboBoxText()); + toneCurveMode2->append(M("TP_EXPOSURE_TCMODE_STANDARD")); + toneCurveMode2->append(M("TP_EXPOSURE_TCMODE_WEIGHTEDSTD")); + toneCurveMode2->append(M("TP_EXPOSURE_TCMODE_FILMLIKE")); + toneCurveMode2->append(M("TP_EXPOSURE_TCMODE_SATANDVALBLENDING")); + toneCurveMode2->append(M("TP_EXPOSURE_TCMODE_LUMINANCE")); + toneCurveMode2->append(M("TP_EXPOSURE_TCMODE_PERCEPTUAL")); + toneCurveMode2->set_active(0); toneCurveMode2->set_tooltip_text(M("TP_EXPOSURE_TCMODE_LABEL2")); - curveEditorG2 = new CurveEditorGroup (options.lastToneCurvesDir, M("TP_EXPOSURE_CURVEEDITOR2")); - curveEditorG2->setCurveListener (this); + curveEditorG2 = new CurveEditorGroup(options.lastToneCurvesDir, M("TP_EXPOSURE_CURVEEDITOR2")); + curveEditorG2->setCurveListener(this); shape2 = static_cast(curveEditorG2->addCurve(CT_Diagonal, "", toneCurveMode2)); shape2->setEditID(EUID_ToneCurve2, BT_IMAGEFLOAT); @@ -202,22 +211,23 @@ ToneCurve::ToneCurve () : FoldableToolPanel(this, "tonecurve", M("TP_EXPOSURE_LA curveEditorG2->curveListComplete(); curveEditorG2->setTooltip(M("TP_EXPOSURE_CURVEEDITOR2_TOOLTIP")); - pack_start( *curveEditorG2, Gtk::PACK_SHRINK, 2); + pack_start(*curveEditorG2, Gtk::PACK_SHRINK, 2); - tcmode2conn = toneCurveMode2->signal_changed().connect( sigc::mem_fun(*this, &ToneCurve::curveMode2Changed), true ); + tcmode2conn = toneCurveMode2->signal_changed().connect(sigc::mem_fun(*this, &ToneCurve::curveMode2Changed), true); // --------- Set Up Listeners ------------- - expcomp->setAdjusterListener (this); - brightness->setAdjusterListener (this); - black->setAdjusterListener (this); - hlcompr->setAdjusterListener (this); - hlcomprthresh->setAdjusterListener (this); - shcompr->setAdjusterListener (this); - contrast->setAdjusterListener (this); - saturation->setAdjusterListener (this); + expcomp->setAdjusterListener(this); + brightness->setAdjusterListener(this); + black->setAdjusterListener(this); + hlcompr->setAdjusterListener(this); + hlbl->setAdjusterListener(this); + hlcomprthresh->setAdjusterListener(this); + shcompr->setAdjusterListener(this); + contrast->setAdjusterListener(this); + saturation->setAdjusterListener(this); } -ToneCurve::~ToneCurve () +ToneCurve::~ToneCurve() { idle_register.destroy(); @@ -225,38 +235,39 @@ ToneCurve::~ToneCurve () delete curveEditorG2; } -void ToneCurve::read (const ProcParams* pp, const ParamsEdited* pedited) +void ToneCurve::read(const ProcParams* pp, const ParamsEdited* pedited) { - disableListener (); + disableListener(); tcmodeconn.block(true); tcmode2conn.block(true); - autoconn.block (true); + autoconn.block(true); - autolevels->set_active (pp->toneCurve.autoexp); + autolevels->set_active(pp->toneCurve.autoexp); lastAuto = pp->toneCurve.autoexp; - sclip->set_value (pp->toneCurve.clip); + sclip->set_value(pp->toneCurve.clip); - expcomp->setValue (pp->toneCurve.expcomp); - black->setValue (pp->toneCurve.black); - hlcompr->setValue (pp->toneCurve.hlcompr); - hlcomprthresh->setValue (pp->toneCurve.hlcomprthresh); - shcompr->setValue (pp->toneCurve.shcompr); + expcomp->setValue(pp->toneCurve.expcomp); + black->setValue(pp->toneCurve.black); + hlcompr->setValue(pp->toneCurve.hlcompr); + hlbl->setValue(pp->toneCurve.hlbl); + hlcomprthresh->setValue(pp->toneCurve.hlcomprthresh); + shcompr->setValue(pp->toneCurve.shcompr); if (!black->getAddMode() && !batchMode) { - shcompr->set_sensitive(!((int)black->getValue () == 0)); //at black=0 shcompr value has no effect + shcompr->set_sensitive(!((int)black->getValue() == 0)); //at black=0 shcompr value has no effect } if (!hlcompr->getAddMode() && !batchMode) { - hlcomprthresh->set_sensitive(!((int)hlcompr->getValue () == 0)); //at hlcompr=0 hlcomprthresh value has no effect + hlcomprthresh->set_sensitive(!((int)hlcompr->getValue() == 0)); //at hlcompr=0 hlcomprthresh value has no effect } - brightness->setValue (pp->toneCurve.brightness); - contrast->setValue (pp->toneCurve.contrast); - saturation->setValue (pp->toneCurve.saturation); - shape->setCurve (pp->toneCurve.curve); - shape2->setCurve (pp->toneCurve.curve2); + brightness->setValue(pp->toneCurve.brightness); + contrast->setValue(pp->toneCurve.contrast); + saturation->setValue(pp->toneCurve.saturation); + shape->setCurve(pp->toneCurve.curve); + shape2->setCurve(pp->toneCurve.curve2); toneCurveMode->set_active(rtengine::toUnderlying(pp->toneCurve.curveMode)); toneCurveMode2->set_active(rtengine::toUnderlying(pp->toneCurve.curveMode2)); @@ -266,19 +277,20 @@ void ToneCurve::read (const ProcParams* pp, const ParamsEdited* pedited) clampOOG->set_active(pp->toneCurve.clampOOG); if (pedited) { - expcomp->setEditedState (pedited->toneCurve.expcomp ? Edited : UnEdited); - black->setEditedState (pedited->toneCurve.black ? Edited : UnEdited); - hlcompr->setEditedState (pedited->toneCurve.hlcompr ? Edited : UnEdited); - hlcomprthresh->setEditedState (pedited->toneCurve.hlcomprthresh ? Edited : UnEdited); - shcompr->setEditedState (pedited->toneCurve.shcompr ? Edited : UnEdited); - brightness->setEditedState (pedited->toneCurve.brightness ? Edited : UnEdited); - contrast->setEditedState (pedited->toneCurve.contrast ? Edited : UnEdited); - saturation->setEditedState (pedited->toneCurve.saturation ? Edited : UnEdited); - autolevels->set_inconsistent (!pedited->toneCurve.autoexp); + expcomp->setEditedState(pedited->toneCurve.expcomp ? Edited : UnEdited); + black->setEditedState(pedited->toneCurve.black ? Edited : UnEdited); + hlcompr->setEditedState(pedited->toneCurve.hlcompr ? Edited : UnEdited); + hlbl->setEditedState(pedited->toneCurve.hlbl ? Edited : UnEdited); + hlcomprthresh->setEditedState(pedited->toneCurve.hlcomprthresh ? Edited : UnEdited); + shcompr->setEditedState(pedited->toneCurve.shcompr ? Edited : UnEdited); + brightness->setEditedState(pedited->toneCurve.brightness ? Edited : UnEdited); + contrast->setEditedState(pedited->toneCurve.contrast ? Edited : UnEdited); + saturation->setEditedState(pedited->toneCurve.saturation ? Edited : UnEdited); + autolevels->set_inconsistent(!pedited->toneCurve.autoexp); clipDirty = pedited->toneCurve.clip; - shape->setUnChanged (!pedited->toneCurve.curve); - shape2->setUnChanged (!pedited->toneCurve.curve2); - hrenabled->set_inconsistent (!pedited->toneCurve.hrenabled); + shape->setUnChanged(!pedited->toneCurve.curve); + shape2->setUnChanged(!pedited->toneCurve.curve2); + hrenabled->set_inconsistent(!pedited->toneCurve.hrenabled); if (!pedited->toneCurve.curveMode) { toneCurveMode->set_active(6); @@ -292,70 +304,65 @@ void ToneCurve::read (const ProcParams* pp, const ParamsEdited* pedited) clampOOG->set_inconsistent(!pedited->toneCurve.clampOOG); } - enaconn.block (true); - hrenabled->set_active (pp->toneCurve.hrenabled); - enaconn.block (false); + enaconn.block(true); + hrenabled->set_active(pp->toneCurve.hrenabled); + enaconn.block(false); if (pedited && !pedited->toneCurve.method) { - method->set_active (4); + method->set_active(4); } else if (pp->toneCurve.method == "Luminance") { - method->set_active (0); + method->set_active(0); } else if (pp->toneCurve.method == "CIELab blending") { - method->set_active (1); + method->set_active(1); } else if (pp->toneCurve.method == "Color") { - method->set_active (2); + method->set_active(2); } else if (pp->toneCurve.method == "Blend") { - method->set_active (3); + method->set_active(3); } - if (!batchMode) { - if (hrenabled->get_active()) { - hlrbox->show(); - } else { - hlrbox->hide(); - } - } + hrenabledChanged(); lasthrEnabled = pp->toneCurve.hrenabled; - autoconn.block (false); + autoconn.block(false); tcmode2conn.block(false); tcmodeconn.block(false); - enableListener (); + enableListener(); } -void ToneCurve::autoOpenCurve () +void ToneCurve::autoOpenCurve() { shape->openIfNonlinear(); shape2->openIfNonlinear(); } -void ToneCurve::setEditProvider (EditDataProvider *provider) +void ToneCurve::setEditProvider(EditDataProvider *provider) { shape->setEditProvider(provider); shape2->setEditProvider(provider); } -void ToneCurve::write (ProcParams* pp, ParamsEdited* pedited) +void ToneCurve::write(ProcParams* pp, ParamsEdited* pedited) { pp->toneCurve.autoexp = autolevels->get_active(); - pp->toneCurve.clip = sclip->get_value (); - pp->toneCurve.expcomp = expcomp->getValue (); - pp->toneCurve.black = (int)black->getValue (); - pp->toneCurve.hlcompr = (int)hlcompr->getValue (); - pp->toneCurve.hlcomprthresh = (int)hlcomprthresh->getValue (); - pp->toneCurve.shcompr = (int)shcompr->getValue (); - pp->toneCurve.brightness = (int)brightness->getValue (); - pp->toneCurve.contrast = (int)contrast->getValue (); - pp->toneCurve.saturation = (int)saturation->getValue (); - pp->toneCurve.curve = shape->getCurve (); - pp->toneCurve.curve2 = shape2->getCurve (); + pp->toneCurve.clip = sclip->get_value(); + pp->toneCurve.expcomp = expcomp->getValue(); + pp->toneCurve.black = black->getValue(); + pp->toneCurve.hlcompr = hlcompr->getValue(); + pp->toneCurve.hlbl = hlbl->getValue(); + pp->toneCurve.hlcomprthresh = hlcomprthresh->getValue(); + pp->toneCurve.shcompr = shcompr->getValue(); + pp->toneCurve.brightness = brightness->getValue(); + pp->toneCurve.contrast = contrast->getValue(); + pp->toneCurve.saturation = saturation->getValue(); + pp->toneCurve.curve = shape->getCurve(); + pp->toneCurve.curve2 = shape2->getCurve(); int tcMode = toneCurveMode->get_active_row_number(); - if (tcMode == 0) { + if (tcMode == 0) { pp->toneCurve.curveMode = ToneCurveMode::STD; } else if (tcMode == 1) { pp->toneCurve.curveMode = ToneCurveMode::WEIGHTEDSTD; @@ -371,7 +378,7 @@ void ToneCurve::write (ProcParams* pp, ParamsEdited* pedited) tcMode = toneCurveMode2->get_active_row_number(); - if (tcMode == 0) { + if (tcMode == 0) { pp->toneCurve.curveMode2 = ToneCurveMode::STD; } else if (tcMode == 1) { pp->toneCurve.curveMode2 = ToneCurveMode::WEIGHTEDSTD; @@ -390,22 +397,23 @@ void ToneCurve::write (ProcParams* pp, ParamsEdited* pedited) pp->toneCurve.clampOOG = clampOOG->get_active(); if (pedited) { - pedited->toneCurve.expcomp = expcomp->getEditedState (); - pedited->toneCurve.black = black->getEditedState (); - pedited->toneCurve.hlcompr = hlcompr->getEditedState (); - pedited->toneCurve.hlcomprthresh = hlcomprthresh->getEditedState (); - pedited->toneCurve.shcompr = shcompr->getEditedState (); - pedited->toneCurve.brightness = brightness->getEditedState (); - pedited->toneCurve.contrast = contrast->getEditedState (); - pedited->toneCurve.saturation = saturation->getEditedState (); - pedited->toneCurve.autoexp = !autolevels->get_inconsistent(); - pedited->toneCurve.clip = clipDirty; - pedited->toneCurve.curve = !shape->isUnChanged (); - pedited->toneCurve.curve2 = !shape2->isUnChanged (); - pedited->toneCurve.curveMode = toneCurveMode->get_active_row_number() != 6; + pedited->toneCurve.expcomp = expcomp->getEditedState(); + pedited->toneCurve.black = black->getEditedState(); + pedited->toneCurve.hlcompr = hlcompr->getEditedState(); + pedited->toneCurve.hlbl = hlbl->getEditedState(); + pedited->toneCurve.hlcomprthresh = hlcomprthresh->getEditedState(); + pedited->toneCurve.shcompr = shcompr->getEditedState(); + pedited->toneCurve.brightness = brightness->getEditedState(); + pedited->toneCurve.contrast = contrast->getEditedState(); + pedited->toneCurve.saturation = saturation->getEditedState(); + pedited->toneCurve.autoexp = !autolevels->get_inconsistent(); + pedited->toneCurve.clip = clipDirty; + pedited->toneCurve.curve = !shape->isUnChanged(); + pedited->toneCurve.curve2 = !shape2->isUnChanged(); + pedited->toneCurve.curveMode = toneCurveMode->get_active_row_number() != 6; pedited->toneCurve.curveMode2 = toneCurveMode2->get_active_row_number() != 6; - pedited->toneCurve.method = method->get_active_row_number() != 4; - pedited->toneCurve.hrenabled = !hrenabled->get_inconsistent(); + pedited->toneCurve.method = method->get_active_row_number() != 4; + pedited->toneCurve.hrenabled = !hrenabled->get_inconsistent(); pedited->toneCurve.histmatching = !histmatching->get_inconsistent(); pedited->toneCurve.fromHistMatching = true; pedited->toneCurve.clampOOG = !clampOOG->get_inconsistent(); @@ -424,60 +432,72 @@ void ToneCurve::write (ProcParams* pp, ParamsEdited* pedited) } } -void ToneCurve::hrenabledChanged () +void ToneCurve::hrenabledChanged() { if (multiImage) { if (hrenabled->get_inconsistent()) { - hrenabled->set_inconsistent (false); - enaconn.block (true); - hrenabled->set_active (false); - enaconn.block (false); + hrenabled->set_inconsistent(false); + enaconn.block(true); + hrenabled->set_active(false); + enaconn.block(false); } else if (lasthrEnabled) { - hrenabled->set_inconsistent (true); + hrenabled->set_inconsistent(true); } - lasthrEnabled = hrenabled->get_active (); + lasthrEnabled = hrenabled->get_active(); } if (!batchMode) { if (hrenabled->get_active()) { hlrbox->show(); + hlrbox->set_sensitive(true); + if (method->get_active_row_number() == 2) { + hlbl->show(); + } else { + hlbl->hide(); + } } else { - hlrbox->hide(); + hlrbox->show(); + hlrbox->set_sensitive(false); + hlbl->hide(); } - } + } if (listener) { // Switch off auto exposure if user changes enabled manually - if (autolevels->get_active() ) { + if (autolevels->get_active()) { autoconn.block(true); - autolevels->set_active (false); + autolevels->set_active(false); autoconn.block(false); - autolevels->set_inconsistent (false); + autolevels->set_inconsistent(false); } setHistmatching(false); - if (hrenabled->get_active ()) { - listener->panelChanged (EvHREnabled, M("GENERAL_ENABLED")); + if (hrenabled->get_active()) { + listener->panelChanged(EvHREnabled, M("GENERAL_ENABLED")); } else { - listener->panelChanged (EvHREnabled, M("GENERAL_DISABLED")); + listener->panelChanged(EvHREnabled, M("GENERAL_DISABLED")); } } } -void ToneCurve::methodChanged () +void ToneCurve::methodChanged() { + if (method->get_active_row_number() == 2) { + hlbl->show(); + } else { + hlbl->hide(); + } if (listener) { setHistmatching(false); - if (hrenabled->get_active ()) { - listener->panelChanged (EvHRMethod, method->get_active_text ()); + if (hrenabled->get_active()) { + listener->panelChanged(EvHRMethod, method->get_active_text()); } } } - void ToneCurve::clampOOGChanged() { if (listener) { @@ -485,96 +505,96 @@ void ToneCurve::clampOOGChanged() } } - - -void ToneCurve::setRaw (bool raw) +void ToneCurve::setRaw(bool raw) { - disableListener (); - method->set_sensitive (raw); - hrenabled->set_sensitive (raw); + disableListener(); + method->set_sensitive(raw); + hlbl->set_sensitive(raw); + hrenabled->set_sensitive(raw); histmatching->set_sensitive(raw); - enableListener (); + enableListener(); } - -void ToneCurve::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) +void ToneCurve::setDefaults(const ProcParams* defParams, const ParamsEdited* pedited) { - expcomp->setDefault (defParams->toneCurve.expcomp); - brightness->setDefault (defParams->toneCurve.brightness); - black->setDefault (defParams->toneCurve.black); - hlcompr->setDefault (defParams->toneCurve.hlcompr); - hlcomprthresh->setDefault (defParams->toneCurve.hlcomprthresh); - shcompr->setDefault (defParams->toneCurve.shcompr); - contrast->setDefault (defParams->toneCurve.contrast); - saturation->setDefault (defParams->toneCurve.saturation); + expcomp->setDefault(defParams->toneCurve.expcomp); + brightness->setDefault(defParams->toneCurve.brightness); + black->setDefault(defParams->toneCurve.black); + hlcompr->setDefault(defParams->toneCurve.hlcompr); + hlbl->setDefault(defParams->toneCurve.hlbl); + hlcomprthresh->setDefault(defParams->toneCurve.hlcomprthresh); + shcompr->setDefault(defParams->toneCurve.shcompr); + contrast->setDefault(defParams->toneCurve.contrast); + saturation->setDefault(defParams->toneCurve.saturation); if (pedited) { - expcomp->setDefaultEditedState (pedited->toneCurve.expcomp ? Edited : UnEdited); - black->setDefaultEditedState (pedited->toneCurve.black ? Edited : UnEdited); - hlcompr->setDefaultEditedState (pedited->toneCurve.hlcompr ? Edited : UnEdited); - hlcomprthresh->setDefaultEditedState (pedited->toneCurve.hlcomprthresh ? Edited : UnEdited); - shcompr->setDefaultEditedState (pedited->toneCurve.shcompr ? Edited : UnEdited); - brightness->setDefaultEditedState (pedited->toneCurve.brightness ? Edited : UnEdited); - contrast->setDefaultEditedState (pedited->toneCurve.contrast ? Edited : UnEdited); - saturation->setDefaultEditedState (pedited->toneCurve.saturation ? Edited : UnEdited); + expcomp->setDefaultEditedState(pedited->toneCurve.expcomp ? Edited : UnEdited); + black->setDefaultEditedState(pedited->toneCurve.black ? Edited : UnEdited); + hlcompr->setDefaultEditedState(pedited->toneCurve.hlcompr ? Edited : UnEdited); + hlbl->setDefaultEditedState(pedited->toneCurve.hlbl ? Edited : UnEdited); + hlcomprthresh->setDefaultEditedState(pedited->toneCurve.hlcomprthresh ? Edited : UnEdited); + shcompr->setDefaultEditedState(pedited->toneCurve.shcompr ? Edited : UnEdited); + brightness->setDefaultEditedState(pedited->toneCurve.brightness ? Edited : UnEdited); + contrast->setDefaultEditedState(pedited->toneCurve.contrast ? Edited : UnEdited); + saturation->setDefaultEditedState(pedited->toneCurve.saturation ? Edited : UnEdited); } else { - expcomp->setDefaultEditedState (Irrelevant); - black->setDefaultEditedState (Irrelevant); - hlcompr->setDefaultEditedState (Irrelevant); - hlcomprthresh->setDefaultEditedState (Irrelevant); - shcompr->setDefaultEditedState (Irrelevant); - brightness->setDefaultEditedState (Irrelevant); - contrast->setDefaultEditedState (Irrelevant); - saturation->setDefaultEditedState (Irrelevant); + expcomp->setDefaultEditedState(Irrelevant); + black->setDefaultEditedState(Irrelevant); + hlcompr->setDefaultEditedState(Irrelevant); + hlbl->setDefaultEditedState(Irrelevant); + hlcomprthresh->setDefaultEditedState(Irrelevant); + shcompr->setDefaultEditedState(Irrelevant); + brightness->setDefaultEditedState(Irrelevant); + contrast->setDefaultEditedState(Irrelevant); + saturation->setDefaultEditedState(Irrelevant); } + } -void ToneCurve::curveChanged (CurveEditor* ce) +void ToneCurve::curveChanged(CurveEditor* ce) { if (listener) { setHistmatching(false); if (ce == shape) { - listener->panelChanged (EvToneCurve1, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvToneCurve1, M("HISTORY_CUSTOMCURVE")); } else if (ce == shape2) { - listener->panelChanged (EvToneCurve2, M("HISTORY_CUSTOMCURVE")); + listener->panelChanged(EvToneCurve2, M("HISTORY_CUSTOMCURVE")); } } } -void ToneCurve::curveMode1Changed () +void ToneCurve::curveMode1Changed() { - //if (listener) listener->panelChanged (EvToneCurveMode, toneCurveMode->get_active_text()); if (listener) { setHistmatching(false); - Glib::signal_idle().connect (sigc::mem_fun(*this, &ToneCurve::curveMode1Changed_)); + Glib::signal_idle().connect(sigc::mem_fun(*this, &ToneCurve::curveMode1Changed_)); } } -bool ToneCurve::curveMode1Changed_ () +bool ToneCurve::curveMode1Changed_() { if (listener) { - listener->panelChanged (EvToneCurveMode1, toneCurveMode->get_active_text()); + listener->panelChanged(EvToneCurveMode1, toneCurveMode->get_active_text()); } return false; } -void ToneCurve::curveMode2Changed () +void ToneCurve::curveMode2Changed() { - //if (listener) listener->panelChanged (EvToneCurveMode, toneCurveMode->get_active_text()); if (listener) { setHistmatching(false); - Glib::signal_idle().connect (sigc::mem_fun(*this, &ToneCurve::curveMode2Changed_)); + Glib::signal_idle().connect(sigc::mem_fun(*this, &ToneCurve::curveMode2Changed_)); } } -bool ToneCurve::curveMode2Changed_ () +bool ToneCurve::curveMode2Changed_() { if (listener) { - listener->panelChanged (EvToneCurveMode2, toneCurveMode2->get_active_text()); + listener->panelChanged(EvToneCurveMode2, toneCurveMode2->get_active_text()); } return false; @@ -601,9 +621,9 @@ void ToneCurve::adjusterChanged(Adjuster* a, double newval) // Switch off auto exposure if user changes sliders manually if (autolevels->get_active() && (a == expcomp || a == brightness || a == contrast || a == black || a == hlcompr || a == hlcomprthresh)) { autoconn.block(true); - autolevels->set_active (false); + autolevels->set_active(false); autoconn.block(false); - autolevels->set_inconsistent (false); + autolevels->set_inconsistent(false); } if (!listener) { @@ -617,39 +637,41 @@ void ToneCurve::adjusterChanged(Adjuster* a, double newval) Glib::ustring costr; if (a == expcomp) { - costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue()); + costr = Glib::ustring::format(std::setw(3), std::fixed, std::setprecision(2), a->getValue()); } else { - costr = Glib::ustring::format ((int)a->getValue()); + costr = Glib::ustring::format((int)a->getValue()); } if (a == expcomp) { - listener->panelChanged (EvExpComp, costr); + listener->panelChanged(EvExpComp, costr); } else if (a == brightness) { - listener->panelChanged (EvBrightness, costr); + listener->panelChanged(EvBrightness, costr); } else if (a == black) { - listener->panelChanged (EvBlack, costr); + listener->panelChanged(EvBlack, costr); if (!black->getAddMode() && !batchMode) { - shcompr->set_sensitive(!((int)black->getValue () == 0)); //at black=0 shcompr value has no effect + shcompr->set_sensitive(!((int)black->getValue() == 0)); //at black=0 shcompr value has no effect } } else if (a == contrast) { - listener->panelChanged (EvContrast, costr); + listener->panelChanged(EvContrast, costr); } else if (a == saturation) { - listener->panelChanged (EvSaturation, costr); + listener->panelChanged(EvSaturation, costr); + } else if (a == hlbl) { + listener->panelChanged(EvHLbl, costr); } else if (a == hlcompr) { - listener->panelChanged (EvHLCompr, costr); + listener->panelChanged(EvHLCompr, costr); if (!hlcompr->getAddMode() && !batchMode) { - hlcomprthresh->set_sensitive(!((int)hlcompr->getValue () == 0)); //at hlcompr=0 hlcomprthresh value has no effect + hlcomprthresh->set_sensitive(!((int)hlcompr->getValue() == 0)); //at hlcompr=0 hlcomprthresh value has no effect } } else if (a == hlcomprthresh) { - listener->panelChanged (EvHLComprThreshold, costr); + listener->panelChanged(EvHLComprThreshold, costr); } else if (a == shcompr) { - listener->panelChanged (EvSHCompr, costr); + listener->panelChanged(EvSHCompr, costr); } } -void ToneCurve::neutral_pressed () +void ToneCurve::neutral_pressed() { // This method deselects auto levels and HL reconstruction auto // and sets neutral values to params in exposure panel @@ -657,215 +679,222 @@ void ToneCurve::neutral_pressed () setHistmatching(false); if (batchMode) { - autolevels->set_inconsistent (false); - autoconn.block (true); - autolevels->set_active (false); - autoconn.block (false); + autolevels->set_inconsistent(false); + autoconn.block(true); + autolevels->set_active(false); + autoconn.block(false); - lastAuto = autolevels->get_active (); + lastAuto = autolevels->get_active(); } else { //!batchMode - autolevels->set_active (false); - autolevels->set_inconsistent (false); + autolevels->set_active(false); + autolevels->set_inconsistent(false); } expcomp->setValue(0); hlcompr->setValue(0); + hlbl->setValue(0); hlcomprthresh->setValue(0); brightness->setValue(0); black->setValue(0); shcompr->setValue(50); - enaconn.block (true); - hrenabled->set_active (false); - enaconn.block (false); + enaconn.block(true); + hrenabled->set_active(false); + enaconn.block(false); if (!batchMode) { - hlrbox->hide(); + hlrbox->show(); + hlrbox->set_sensitive(false); + hlbl->hide(); } if (!black->getAddMode() && !batchMode) { - shcompr->set_sensitive(!((int)black->getValue () == 0)); //at black=0 shcompr value has no effect + shcompr->set_sensitive(!((int)black->getValue() == 0)); //at black=0 shcompr value has no effect } if (!hlcompr->getAddMode() && !batchMode) { - hlcomprthresh->set_sensitive(!((int)hlcompr->getValue () == 0)); //at hlcompr=0 hlcomprthresh value has no effect + hlcomprthresh->set_sensitive(!((int)hlcompr->getValue() == 0)); //at hlcompr=0 hlcomprthresh value has no effect } contrast->setValue(0); //saturation->setValue(0); - listener->panelChanged (EvNeutralExp, M("GENERAL_ENABLED")); + listener->panelChanged(EvNeutralExp, M("GENERAL_ENABLED")); } -void ToneCurve::autolevels_toggled () + +void ToneCurve::autolevels_toggled() { setHistmatching(false); - if (batchMode) { if (autolevels->get_inconsistent()) { - autolevels->set_inconsistent (false); - autoconn.block (true); - autolevels->set_active (false); - autoconn.block (false); + autolevels->set_inconsistent(false); + autoconn.block(true); + autolevels->set_active(false); + autoconn.block(false); } else if (lastAuto) { - autolevels->set_inconsistent (true); + autolevels->set_inconsistent(true); } - lastAuto = autolevels->get_active (); + lastAuto = autolevels->get_active(); - expcomp->setEditedState (UnEdited); - brightness->setEditedState (UnEdited); - contrast->setEditedState (UnEdited); - black->setEditedState (UnEdited); - hlcompr->setEditedState (UnEdited); - hlcomprthresh->setEditedState (UnEdited); + expcomp->setEditedState(UnEdited); + brightness->setEditedState(UnEdited); + contrast->setEditedState(UnEdited); + black->setEditedState(UnEdited); + hlcompr->setEditedState(UnEdited); + hlcomprthresh->setEditedState(UnEdited); if (expcomp->getAddMode()) { - expcomp->setValue (0); + expcomp->setValue(0); } if (brightness->getAddMode()) { - brightness->setValue (0); + brightness->setValue(0); } if (contrast->getAddMode()) { - contrast->setValue (0); + contrast->setValue(0); } if (black->getAddMode()) { - black->setValue (0); + black->setValue(0); } if (hlcompr->getAddMode()) { - hlcompr->setValue (0); + hlcompr->setValue(0); } if (hlcomprthresh->getAddMode()) { - hlcomprthresh->setValue (0); + hlcomprthresh->setValue(0); } if (listener) { if (!autolevels->get_inconsistent()) { - if (autolevels->get_active ()) { - listener->panelChanged (EvAutoExp, M("GENERAL_ENABLED")); + if (autolevels->get_active()) { + listener->panelChanged(EvAutoExp, M("GENERAL_ENABLED")); } else { - listener->panelChanged (EvFixedExp, M("GENERAL_DISABLED")); + listener->panelChanged(EvFixedExp, M("GENERAL_DISABLED")); } } } } else if (/* !batchMode && */ listener) { if (autolevels->get_active()) { - listener->panelChanged (EvAutoExp, M("GENERAL_ENABLED")); - waitForAutoExp (); + listener->panelChanged(EvAutoExp, M("GENERAL_ENABLED")); + waitForAutoExp(); if (!black->getAddMode()) { - shcompr->set_sensitive(!((int)black->getValue () == 0)); //at black=0 shcompr value has no effect + shcompr->set_sensitive(!((int)black->getValue() == 0)); //at black=0 shcompr value has no effect } if (!hlcompr->getAddMode() && !batchMode) { - hlcomprthresh->set_sensitive(!((int)hlcompr->getValue () == 0)); //at hlcompr=0 hlcomprthresh value has no effect + hlcomprthresh->set_sensitive(!((int)hlcompr->getValue() == 0)); //at hlcompr=0 hlcomprthresh value has no effect } } else { - listener->panelChanged (EvFixedExp, M("GENERAL_DISABLED")); + listener->panelChanged(EvFixedExp, M("GENERAL_DISABLED")); } } } -void ToneCurve::clip_changed () +void ToneCurve::clip_changed() { clipDirty = true; if (autolevels->get_active() && listener) { - Glib::signal_idle().connect (sigc::mem_fun(*this, &ToneCurve::clip_changed_)); + Glib::signal_idle().connect(sigc::mem_fun(*this, &ToneCurve::clip_changed_)); } } -bool ToneCurve::clip_changed_ () +bool ToneCurve::clip_changed_() { if (listener) { - listener->panelChanged (EvClip, Glib::ustring::format (std::setprecision(5), sclip->get_value())); + listener->panelChanged(EvClip, Glib::ustring::format(std::setprecision(5), sclip->get_value())); if (!batchMode) { - waitForAutoExp (); + waitForAutoExp(); } } return false; } -void ToneCurve::waitForAutoExp () +void ToneCurve::waitForAutoExp() { - sclip->set_sensitive (false); - expcomp->setEnabled (false); - brightness->setEnabled (false); - contrast->setEnabled (false); - black->setEnabled (false); - hlcompr->setEnabled (false); - hlcomprthresh->setEnabled (false); - shcompr->setEnabled (false); - contrast->setEnabled (false); - saturation->setEnabled (false); - curveEditorG->set_sensitive (false); - toneCurveMode->set_sensitive (false); - curveEditorG2->set_sensitive (false); - toneCurveMode2->set_sensitive (false); + sclip->set_sensitive(false); + expcomp->setEnabled(false); + brightness->setEnabled(false); + contrast->setEnabled(false); + black->setEnabled(false); + hlcompr->setEnabled(false); + hlcomprthresh->setEnabled(false); + shcompr->setEnabled(false); + contrast->setEnabled(false); + saturation->setEnabled(false); + curveEditorG->set_sensitive(false); + toneCurveMode->set_sensitive(false); + curveEditorG2->set_sensitive(false); + toneCurveMode2->set_sensitive(false); hrenabled->set_sensitive(false); method->set_sensitive(false); + hlbl->set_sensitive(false); histmatching->set_sensitive(false); } -void ToneCurve::enableAll () +void ToneCurve::enableAll() { - sclip->set_sensitive (true); - expcomp->setEnabled (true); - brightness->setEnabled (true); - black->setEnabled (true); - hlcompr->setEnabled (true); - hlcomprthresh->setEnabled (true); - shcompr->setEnabled (true); - contrast->setEnabled (true); - saturation->setEnabled (true); - curveEditorG->set_sensitive (true); - toneCurveMode->set_sensitive (true); - curveEditorG2->set_sensitive (true); - toneCurveMode2->set_sensitive (true); + sclip->set_sensitive(true); + expcomp->setEnabled(true); + brightness->setEnabled(true); + black->setEnabled(true); + hlcompr->setEnabled(true); + hlbl->setEnabled(true); + hlcomprthresh->setEnabled(true); + shcompr->setEnabled(true); + contrast->setEnabled(true); + saturation->setEnabled(true); + curveEditorG->set_sensitive(true); + toneCurveMode->set_sensitive(true); + curveEditorG2->set_sensitive(true); + toneCurveMode2->set_sensitive(true); hrenabled->set_sensitive(true); method->set_sensitive(true); + hlbl->set_sensitive(true); histmatching->set_sensitive(true); } -void ToneCurve::setBatchMode (bool batchMode) +void ToneCurve::setBatchMode(bool batchMode) { - ToolPanel::setBatchMode (batchMode); - method->append (M("GENERAL_UNCHANGED")); + ToolPanel::setBatchMode(batchMode); + method->append(M("GENERAL_UNCHANGED")); - removeIfThere (abox, autolevels, false); - autolevels = Gtk::manage (new Gtk::CheckButton (M("TP_EXPOSURE_AUTOLEVELS"))); - autolevels->set_tooltip_markup (M("TP_EXPOSURE_AUTOLEVELS_TIP")); - autoconn = autolevels->signal_toggled().connect( sigc::mem_fun(*this, &ToneCurve::autolevels_toggled) ); - abox->pack_start (*autolevels); + removeIfThere(abox, autolevels, false); + autolevels = Gtk::manage(new Gtk::CheckButton(M("TP_EXPOSURE_AUTOLEVELS"))); + autolevels->set_tooltip_markup(M("TP_EXPOSURE_AUTOLEVELS_TIP")); + autoconn = autolevels->signal_toggled().connect(sigc::mem_fun(*this, &ToneCurve::autolevels_toggled)); + abox->pack_start(*autolevels); - ToolPanel::setBatchMode (batchMode); - expcomp->showEditedCB (); - black->showEditedCB (); - hlcompr->showEditedCB (); - hlcomprthresh->showEditedCB (); - shcompr->showEditedCB (); - brightness->showEditedCB (); - contrast->showEditedCB (); - saturation->showEditedCB (); + ToolPanel::setBatchMode(batchMode); + expcomp->showEditedCB(); + black->showEditedCB(); + hlcompr->showEditedCB(); + hlbl->showEditedCB(); + hlcomprthresh->showEditedCB(); + shcompr->showEditedCB(); + brightness->showEditedCB(); + contrast->showEditedCB(); + saturation->showEditedCB(); - toneCurveMode->append (M("GENERAL_UNCHANGED")); - toneCurveMode2->append (M("GENERAL_UNCHANGED")); + toneCurveMode->append(M("GENERAL_UNCHANGED")); + toneCurveMode2->append(M("GENERAL_UNCHANGED")); - curveEditorG->setBatchMode (batchMode); - curveEditorG2->setBatchMode (batchMode); + curveEditorG->setBatchMode(batchMode); + curveEditorG2->setBatchMode(batchMode); } -void ToneCurve::setAdjusterBehavior (bool expadd, bool hlcompadd, bool hlcompthreshadd, bool bradd, bool blackadd, bool shcompadd, bool contradd, bool satadd) +void ToneCurve::setAdjusterBehavior(bool expadd, bool hlcompadd, bool hlcompthreshadd, bool bradd, bool blackadd, bool shcompadd, bool contradd, bool satadd) { expcomp->setAddMode(expadd); @@ -878,7 +907,7 @@ void ToneCurve::setAdjusterBehavior (bool expadd, bool hlcompadd, bool hlcompthr saturation->setAddMode(satadd); } -void ToneCurve::trimValues (rtengine::procparams::ProcParams* pp) +void ToneCurve::trimValues(rtengine::procparams::ProcParams* pp) { expcomp->trimValue(pp->toneCurve.expcomp); @@ -907,7 +936,6 @@ void ToneCurve::updateCurveBackgroundHistogram( shape->updateBackgroundHistogram(histToneCurve); } - void ToneCurve::setHistmatching(bool enabled) { fromHistMatching = enabled; @@ -919,7 +947,6 @@ void ToneCurve::setHistmatching(bool enabled) } } - void ToneCurve::histmatchingToggled() { if (listener) { @@ -966,8 +993,16 @@ void ToneCurve::autoExpChanged(double expcomp, int bright, int contr, int black, if (nextHLRecons) { hlrbox->show(); + hlrbox->set_sensitive(true); + if (method->get_active_row_number() == 2) { + hlbl->show(); + } else { + hlbl->hide(); + } } else if (!batchMode) { - hlrbox->hide(); + hlrbox->show(); + hlrbox->set_sensitive(false); + hlbl->hide(); } if (!this->black->getAddMode() && !batchMode) { @@ -1007,7 +1042,7 @@ void ToneCurve::autoMatchedToneCurveChanged(rtengine::procparams::ToneCurveMode hlcomprthresh->set_sensitive(static_cast(hlcompr->getValue())); //at hlcompr=0 hlcomprthresh value has no effect } - if (autolevels->get_active() ) { + if (autolevels->get_active()) { expcomp->setValue(0); autoconn.block(true); autolevels->set_active(false); diff --git a/rtgui/tonecurve.h b/rtgui/tonecurve.h index 9439d422e..6dd77951d 100644 --- a/rtgui/tonecurve.h +++ b/rtgui/tonecurve.h @@ -47,6 +47,7 @@ protected: sigc::connection methconn; sigc::connection enaconn; bool lasthrEnabled; + Adjuster* hlbl; Gtk::Box* abox; Gtk::Box* hlrbox; @@ -80,6 +81,7 @@ protected: rtengine::ProcEvent EvHistMatching; rtengine::ProcEvent EvHistMatchingBatch; rtengine::ProcEvent EvClampOOG; + rtengine::ProcEvent EvHLbl; // used temporarily in eventing double nextExpcomp;