From 1892bbf7724ddc01835a4e1e77fd793358c4389b Mon Sep 17 00:00:00 2001 From: Desmis Date: Sat, 7 Nov 2015 18:47:37 +0100 Subject: [PATCH 01/61] Init retinex add tone-mapping --- rtdata/languages/default | 10 +- rtengine/ipretinex.cc | 533 ++++++++++++++++++++++----------------- rtengine/procevents.h | 2 + rtengine/procparams.cc | 28 ++ rtengine/procparams.h | 2 + rtengine/refreshmap.cc | 5 +- rtgui/paramsedited.cc | 16 ++ rtgui/paramsedited.h | 2 + rtgui/retinex.cc | 70 ++++- rtgui/retinex.h | 2 + 10 files changed, 428 insertions(+), 242 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index ee6952559..aeb5664e8 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -641,7 +641,7 @@ HISTORY_MSG_408;Retinex - Neighboring HISTORY_MSG_409;Retinex - Gain HISTORY_MSG_410;Retinex - Offset HISTORY_MSG_411;Retinex - Strength -HISTORY_MSG_412;Retinex - Scales +HISTORY_MSG_412;Retinex - G. Gradient HISTORY_MSG_413;Retinex - Variance HISTORY_MSG_414;Retinex - Histogram - Lab HISTORY_MSG_415;Retinex - Transmission @@ -656,6 +656,8 @@ HISTORY_MSG_423;Retinex - Gamma slope HISTORY_MSG_424;Retinex - HL threshold HISTORY_MSG_425;Retinex - Log base HISTORY_MSG_426;Retinex - Hue equalizer +HISTORY_MSG_427;Retinex - Iterations +HISTORY_MSG_428;Retinex - T. Gradient HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOTS;Snapshots @@ -1654,6 +1656,10 @@ TP_RETINEX_HIGHLIG;Highlight TP_RETINEX_HIGH;High TP_RETINEX_HSLSPACE_LIN;HSL-Linear TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic +TP_RETINEX_ITER;Iterations (Tone-mapping) +TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator\nHigh values increase the processing time +TP_RETINEX_GRAD;Transmission gradient +TP_RETINEX_GRAD_TOOLTIP;If slider at 0, all iterations are identical\nIf > 0 Variance and Threshold are reduce when iteration increases and conversely TP_RETINEX_LABEL;Retinex TP_RETINEX_LABSPACE;L*a*b* TP_RETINEX_LOW;Low @@ -1667,6 +1673,8 @@ TP_RETINEX_NEUTRAL;Reset TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. TP_RETINEX_OFFSET;Offset TP_RETINEX_SETTINGS;Settings +TP_RETINEX_SCALES;Gaussian gradient +TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical\nIf > 0 Scale and Neighboring pixels are reduce when iteration increases and conversely TP_RETINEX_SLOPE;Free gamma slope TP_RETINEX_STRENGTH;Strength TP_RETINEX_THRESHOLD;Threshold diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index 54d5d3515..1f6602b62 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -217,10 +217,12 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e float gain2 = (float) deh.gain / 100.f; //def =1 not use gain2 = useHslLin ? gain2 * 0.5f : gain2; float offse = (float) deh.offs; //def = 0 not use - int scal = deh.scal; //def=3 - scal = 3;//disabled scal + int iter = deh.iter; + int gradient = deh.scal; + int scal = 3;//disabled scal int nei = (int) 2.8f * deh.neigh; //def = 220 float vart = (float)deh.vart / 100.f;//variance + float gradvart = (float)deh.grad; float strength = (float) deh.str / 100.f; // Blend with original L channel data float limD = (float) deh.limd; limD = pow(limD, 1.7f);//about 2500 enough @@ -271,283 +273,342 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e if (deh.retinexMethod == "highli" || deh.retinexMethod == "highliplus") { moderetinex = 3; } - - float aahi = 49.f / 99.f; ////reduce sensibility 50% - float bbhi = 1.f - aahi; - float high; - high = bbhi + aahi * (float) deh.highl; - retinex_scales( RetinexScales, scal, moderetinex, nei, high ); - - int H_L = height; - int W_L = width; - - float *src[H_L] ALIGNED16; - float *srcBuffer = new float[H_L * W_L]; - - for (int i = 0; i < H_L; i++) { - src[i] = &srcBuffer[i * W_L]; - } - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int i = 0; i < H_L; i++) - for (int j = 0; j < W_L; j++) { - src[i][j] = luminance[i][j] + eps; - luminance[i][j] = 0.f; + for(int it=1; it= 0; scale-- ) { - if(scale == scal - 1) { - gaussianBlur (src, out, W_L, H_L, RetinexScales[scale], buffer); - } else { // reuse result of last iteration - gaussianBlur (out, out, W_L, H_L, sqrtf(SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])), buffer); + else if(gradient==1) { + grad=0.25f*it+0.75f; + sc=-0.5f*it+4.5f; + } + else if(gradient==2) { + grad=0.5f*it+0.5f; + sc=-it+6.f; + } + else if(gradient==3) { + grad=0.666f*it+0.333f; + sc=-it+6.f; + } + else if(gradient==4) { + grad=0.8f*it+0.2f; + sc=-it+6.f; + } + else if(gradient==5) { + grad=0.9f*it+0.1f; + sc=-it+6.f; + } + else if(gradient==-1) { + grad=-0.125f*it+1.125f; + sc=3.f; + } + float varx; + float limdx, ilimdx; + if(gradvart!=0) { + if(gradvart==1) { + varx=vart*(-0.125f*it+1.125f); + limdx=limD*(-0.125f*it+1.125f); + ilimdx=1.f/limdx; } - -#ifdef __SSE2__ - vfloat pondv = F2V(pond); - vfloat limMinv = F2V(ilimD); - vfloat limMaxv = F2V(limD); - -#endif -#ifdef _OPENMP - #pragma omp for -#endif - - for (int i = 0; i < H_L; i++) { - int j = 0; - -#ifdef __SSE2__ - - if(useHslLin) { - for (; j < W_L - 3; j += 4) { - _mm_storeu_ps(&luminance[i][j], LVFU(luminance[i][j]) + pondv * (LIMV(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv) )); - } - } else { - for (; j < W_L - 3; j += 4) { - _mm_storeu_ps(&luminance[i][j], LVFU(luminance[i][j]) + pondv * xlogf(LIMV(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv) )); - } - } - -#endif - - if(useHslLin) { - for (; j < W_L; j++) { - luminance[i][j] += pond * (LIM(src[i][j] / out[i][j], ilimD, limD)); - } - } else { - for (; j < W_L; j++) { - luminance[i][j] += pond * xlogf(LIM(src[i][j] / out[i][j], ilimD, limD)); // /logt ? - } - } + else if(gradvart==2) { + varx=vart*(-0.2f*it+1.2f); + limdx=limD*(-0.2f*it+1.2f); + ilimdx=1.f/limdx; + } + else if(gradvart==-1) { + varx=vart*(0.125f*it+0.875f); + limdx=limD*(0.125f*it+0.875f); + ilimdx=1.f/limdx; + } + else if(gradvart==-2) { + varx=vart*(0.4f*it+0.6f); + limdx=limD*(0.4f*it+0.6f); + ilimdx=1.f/limdx; } } - } - delete [] buffer; - delete [] outBuffer; - delete [] srcBuffer; + else { + varx=vart; + limdx=limD; + ilimdx=ilimD; + } + scal=round(sc); + float aahi = 49.f / 99.f; ////reduce sensibility 50% + float bbhi = 1.f - aahi; + float high; + high = bbhi + aahi * (float) deh.highl; + retinex_scales( RetinexScales, scal, moderetinex, nei/grad, high ); - mean = 0.f; - stddv = 0.f; - // I call mean_stddv2 instead of mean_stddv ==> logBetaGain + int H_L = height; + int W_L = width; - mean_stddv2( luminance, mean, stddv, W_L, H_L, maxtr, mintr); -// printf("mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", mean, stddv, delta, maxtr, mintr); + float *src[H_L] ALIGNED16; + float *srcBuffer = new float[H_L * W_L]; - // mean_stddv( luminance, mean, stddv, W_L, H_L, logBetaGain, maxtr, mintr); - if (dehatransmissionCurve && mean != 0.f && stddv != 0.f) { //if curve - float asig = 0.166666f / stddv; - float bsig = 0.5f - asig * mean; - float amax = 0.333333f / (maxtr - mean - stddv); - float bmax = 1.f - amax * maxtr; - float amin = 0.333333f / (mean - stddv - mintr); - float bmin = -amin * mintr; + for (int i = 0; i < H_L; i++) { + src[i] = &srcBuffer[i * W_L]; + } - asig *= 500.f; - bsig *= 500.f; - amax *= 500.f; - bmax *= 500.f; - amin *= 500.f; - bmin *= 500.f; +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int i = 0; i < H_L; i++) + for (int j = 0; j < W_L; j++) { + src[i][j] = luminance[i][j] + eps; + luminance[i][j] = 0.f; + } + + float *out[H_L] ALIGNED16; + float *outBuffer = new float[H_L * W_L]; + + for (int i = 0; i < H_L; i++) { + out[i] = &outBuffer[i * W_L]; + } + + const float logBetaGain = xlogf(16384.f); + float pond = logBetaGain / (float) scal; + + if(!useHslLin) { + pond /= log(elogt); + } + + float *buffer = new float[W_L * H_L];; #ifdef _OPENMP #pragma omp parallel #endif { - float absciss; + for ( int scale = scal - 1; scale >= 0; scale-- ) { + if(scale == scal - 1) { + gaussianBlur (src, out, W_L, H_L, RetinexScales[scale], buffer); + } else { // reuse result of last iteration + gaussianBlur (out, out, W_L, H_L, sqrtf(SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])), buffer); + } + +#ifdef __SSE2__ + vfloat pondv = F2V(pond); + vfloat limMinv = F2V(ilimdx); + vfloat limMaxv = F2V(limdx); + +#endif #ifdef _OPENMP - #pragma omp for schedule(dynamic,16) + #pragma omp for #endif - for (int i = 0; i < H_L; i++ ) - for (int j = 0; j < W_L; j++) { //for mintr to maxtr evalate absciss in function of original transmission - if (LIKELY(fabsf(luminance[i][j] - mean) < stddv)) { - absciss = asig * luminance[i][j] + bsig; - } else if (luminance[i][j] >= mean) { - absciss = amax * luminance[i][j] + bmax; - } else { /*if(luminance[i][j] <= mean - stddv)*/ - absciss = amin * luminance[i][j] + bmin; + for (int i = 0; i < H_L; i++) { + int j = 0; + +#ifdef __SSE2__ + + if(useHslLin) { + for (; j < W_L - 3; j += 4) { + _mm_storeu_ps(&luminance[i][j], LVFU(luminance[i][j]) + pondv * (LIMV(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv) )); + } + } else { + for (; j < W_L - 3; j += 4) { + _mm_storeu_ps(&luminance[i][j], LVFU(luminance[i][j]) + pondv * xlogf(LIMV(LVFU(src[i][j]) / LVFU(out[i][j]), limMinv, limMaxv) )); + } } - luminance[i][j] *= (-1.f + 4.f * dehatransmissionCurve[absciss]); //new transmission - } - } - - // median filter on transmission ==> reduce artifacts - if (deh.medianmap) { - int wid = W_L; - int hei = H_L; - float *tmL[hei] ALIGNED16; - float *tmLBuffer = new float[wid * hei]; - int borderL = 1; - - for (int i = 0; i < hei; i++) { - tmL[i] = &tmLBuffer[i * wid]; - } - -#ifdef _OPENMP - #pragma omp parallel for #endif - for (int i = borderL; i < hei - borderL; i++) { - float pp[9], temp; - - for (int j = borderL; j < wid - borderL; j++) { - med3(luminance[i][j], luminance[i - 1][j], luminance[i + 1][j], luminance[i][j + 1], luminance[i][j - 1], luminance[i - 1][j - 1], luminance[i - 1][j + 1], luminance[i + 1][j - 1], luminance[i + 1][j + 1], tmL[i][j]); //3x3 + if(useHslLin) { + for (; j < W_L; j++) { + luminance[i][j] += pond * (LIM(src[i][j] / out[i][j], ilimdx, limdx)); + } + } else { + for (; j < W_L; j++) { + luminance[i][j] += pond * xlogf(LIM(src[i][j] / out[i][j], ilimdx, limdx)); // /logt ? + } + } } } - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int i = borderL; i < hei - borderL; i++ ) { - for (int j = borderL; j < wid - borderL; j++) { - luminance[i][j] = tmL[i][j]; - } - } - - delete [] tmLBuffer; - } + delete [] buffer; + delete [] outBuffer; + delete [] srcBuffer; + mean = 0.f; + stddv = 0.f; // I call mean_stddv2 instead of mean_stddv ==> logBetaGain - // mean_stddv( luminance, mean, stddv, W_L, H_L, 1.f, maxtr, mintr); + mean_stddv2( luminance, mean, stddv, W_L, H_L, maxtr, mintr); +// printf("mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", mean, stddv, delta, maxtr, mintr); - } - - float epsil = 0.1f; - - mini = mean - vart * stddv; - - if (mini < mintr) { - mini = mintr + epsil; - } - - maxi = mean + vart * stddv; - - if (maxi > maxtr) { - maxi = maxtr - epsil; - } - - delta = maxi - mini; - // printf("maxi=%f mini=%f mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", maxi, mini, mean, stddv, delta, maxtr, mintr); - - if ( !delta ) { - delta = 1.0f; - } - - float cdfactor = gain2 * 32768.f / delta; - maxCD = -9999999.f; - minCD = 9999999.f; - - - + // mean_stddv( luminance, mean, stddv, W_L, H_L, logBetaGain, maxtr, mintr); + if (dehatransmissionCurve && mean != 0.f && stddv != 0.f) { //if curve + float asig = 0.166666f / stddv; + float bsig = 0.5f - asig * mean; + float amax = 0.333333f / (maxtr - mean - stddv); + float bmax = 1.f - amax * maxtr; + float amin = 0.333333f / (mean - stddv - mintr); + float bmin = -amin * mintr; + asig *= 500.f; + bsig *= 500.f; + amax *= 500.f; + bmax *= 500.f; + amin *= 500.f; + bmin *= 500.f; #ifdef _OPENMP - #pragma omp parallel + #pragma omp parallel #endif - { - float cdmax = -999999.f, cdmin = 999999.f; - + { + float absciss; #ifdef _OPENMP - #pragma omp for + #pragma omp for schedule(dynamic,16) #endif - for ( int i = 0; i < H_L; i ++ ) - for (int j = 0; j < W_L; j++) { - // float cd = cdfactor * ( luminance[i][j] * logBetaGain - mini ) + offse; - float cd = cdfactor * ( luminance[i][j] - mini ) + offse; - - if(cd > cdmax) { - cdmax = cd; - } - - if(cd < cdmin) { - cdmin = cd; - } - - float str = strength; - - if(lhutili) { // S=f(H) - { - float HH = exLuminance[i][j]; - float valparam; - - if(useHsl || useHslLin) { - valparam = float((shcurve->getVal(HH) - 0.5f)); - } else { - valparam = float((shcurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5f)); + for (int i = 0; i < H_L; i++ ) + for (int j = 0; j < W_L; j++) { //for mintr to maxtr evalate absciss in function of original transmission + if (LIKELY(fabsf(luminance[i][j] - mean) < stddv)) { + absciss = asig * luminance[i][j] + bsig; + } else if (luminance[i][j] >= mean) { + absciss = amax * luminance[i][j] + bmax; + } else { /*if(luminance[i][j] <= mean - stddv)*/ + absciss = amin * luminance[i][j] + bmin; } - str *= (1.f + 2.f * valparam); + luminance[i][j] *= (-1.f + 4.f * dehatransmissionCurve[absciss]); //new transmission + } + } + + // median filter on transmission ==> reduce artifacts + if (deh.medianmap && it==1) {//only one time + int wid = W_L; + int hei = H_L; + float *tmL[hei] ALIGNED16; + float *tmLBuffer = new float[wid * hei]; + int borderL = 1; + + for (int i = 0; i < hei; i++) { + tmL[i] = &tmLBuffer[i * wid]; + } + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int i = borderL; i < hei - borderL; i++) { + float pp[9], temp; + + for (int j = borderL; j < wid - borderL; j++) { + med3(luminance[i][j], luminance[i - 1][j], luminance[i + 1][j], luminance[i][j + 1], luminance[i][j - 1], luminance[i - 1][j - 1], luminance[i - 1][j + 1], luminance[i + 1][j - 1], luminance[i + 1][j + 1], tmL[i][j]); //3x3 } } - // if(exLuminance[i][j] > 65535.f*hig && higplus) str *= hig; - luminance[i][j] = clipretinex( cd, 0.f, 32768.f ) * str + (1.f - str) * originalLuminance[i][j]; +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int i = borderL; i < hei - borderL; i++ ) { + for (int j = borderL; j < wid - borderL; j++) { + luminance[i][j] = tmL[i][j]; + } + } + + delete [] tmLBuffer; + } -#ifdef _OPENMP - #pragma omp critical -#endif - { - maxCD = maxCD > cdmax ? maxCD : cdmax; - minCD = minCD < cdmin ? minCD : cdmin; + // I call mean_stddv2 instead of mean_stddv ==> logBetaGain + // mean_stddv( luminance, mean, stddv, W_L, H_L, 1.f, maxtr, mintr); + mean_stddv2( luminance, mean, stddv, W_L, H_L, maxtr, mintr); + } - } - // printf("cdmin=%f cdmax=%f\n",minCD, maxCD); - Tmean = mean; - Tsigma = stddv; - Tmin = mintr; - Tmax = maxtr; + float epsil = 0.1f; - if (shcurve) { - delete shcurve; - } + mini = mean - varx * stddv; + if (mini < mintr) { + mini = mintr + epsil; + } + + maxi = mean + varx * stddv; + + if (maxi > maxtr) { + maxi = maxtr - epsil; + } + + delta = maxi - mini; + // printf("maxi=%f mini=%f mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", maxi, mini, mean, stddv, delta, maxtr, mintr); + + if ( !delta ) { + delta = 1.0f; + } + + float cdfactor = gain2 * 32768.f / delta; + maxCD = -9999999.f; + minCD = 9999999.f; + + + + +#ifdef _OPENMP + #pragma omp parallel +#endif + { + float cdmax = -999999.f, cdmin = 999999.f; + +#ifdef _OPENMP + #pragma omp for +#endif + + for ( int i = 0; i < H_L; i ++ ) + for (int j = 0; j < W_L; j++) { + // float cd = cdfactor * ( luminance[i][j] * logBetaGain - mini ) + offse; + float cd = cdfactor * ( luminance[i][j] - mini ) + offse; + + if(cd > cdmax) { + cdmax = cd; + } + + if(cd < cdmin) { + cdmin = cd; + } + + float str = strength; + + if(lhutili) { // S=f(H) + { + float HH = exLuminance[i][j]; + float valparam; + + if(useHsl || useHslLin) { + valparam = float((shcurve->getVal(HH) - 0.5f)); + } else { + valparam = float((shcurve->getVal(Color::huelab_to_huehsv2(HH)) - 0.5f)); + } + + str *= (1.f + 2.f * valparam); + } + } + + // if(exLuminance[i][j] > 65535.f*hig && higplus) str *= hig; + luminance[i][j] = clipretinex( cd, 0.f, 32768.f ) * str + (1.f - str) * originalLuminance[i][j]; + } + +#ifdef _OPENMP + #pragma omp critical +#endif + { + maxCD = maxCD > cdmax ? maxCD : cdmax; + minCD = minCD < cdmin ? minCD : cdmin; + } + + } + // printf("cdmin=%f cdmax=%f\n",minCD, maxCD); + Tmean = mean; + Tsigma = stddv; + Tmin = mintr; + Tmax = maxtr; + + if (shcurve) { + delete shcurve; + } + } } } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 4dbbad07c..ae348316f 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -454,6 +454,8 @@ enum ProcEvent { EvLbaselog = 424, // EvLgrbl = 425, EvRetinexlhcurve = 425, + EvLiter = 426, + EvLgrad = 427, NUMOFEVENTS }; } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index becd8932e..ed57f50d3 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -142,6 +142,8 @@ void RetinexParams::setDefaults() enabled = false; str = 20; scal = 3; + iter = 1; + grad = 1; gam = 1.30; slope = 3.; neigh = 80; @@ -1444,6 +1446,14 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol keyFile.set_integer ("Retinex", "Scal", retinex.scal); } + if (!pedited || pedited->retinex.iter) { + keyFile.set_integer ("Retinex", "Iter", retinex.iter); + } + + if (!pedited || pedited->retinex.grad) { + keyFile.set_integer ("Retinex", "Grad", retinex.iter); + } + if (!pedited || pedited->retinex.gam) { keyFile.set_double ("Retinex", "Gam", retinex.gam); } @@ -3851,6 +3861,22 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) } } + if (keyFile.has_key ("Retinex", "Iter")) { + retinex.iter = keyFile.get_integer ("Retinex", "Iter"); + + if (pedited) { + pedited->retinex.iter = true; + } + } + + if (keyFile.has_key ("Retinex", "Grad")) { + retinex.grad = keyFile.get_integer ("Retinex", "Grad"); + + if (pedited) { + pedited->retinex.grad = true; + } + } + if (keyFile.has_key ("Retinex", "Gam")) { retinex.gam = keyFile.get_double ("Retinex", "Gam"); @@ -7322,6 +7348,8 @@ bool ProcParams::operator== (const ProcParams& other) && retinex.transmissionCurve == other.retinex.transmissionCurve && retinex.str == other.retinex.str && retinex.scal == other.retinex.scal + && retinex.iter == other.retinex.iter + && retinex.grad == other.retinex.grad && retinex.gam == other.retinex.gam && retinex.slope == other.retinex.slope && retinex.neigh == other.retinex.neigh diff --git a/rtengine/procparams.h b/rtengine/procparams.h index d46fd4181..1226d1584 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -275,6 +275,8 @@ public: std::vector transmissionCurve; int str; int scal; + int iter; + int grad; double gam; double slope; int neigh; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 3505da24f..88338f06c 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -453,6 +453,9 @@ int refreshmap[rtengine::NUMOFEVENTS] = { RETINEX, // EvLhighl DEMOSAIC, // EvLbaselog // DEMOSAIC, // EvLgrbl - DEMOSAIC // EvRetinexlhcurve + DEMOSAIC, // EvRetinexlhcurve + RETINEX, // EvLiter + RETINEX // EvLgrad + }; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index ac2fe6523..600a68af4 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -58,6 +58,8 @@ void ParamsEdited::set (bool v) retinex.enabled = v; retinex.str = v; retinex.scal = v; + retinex.iter = v; + retinex.grad = v; retinex.gam = v; retinex.slope = v; retinex.neigh = v; @@ -535,6 +537,8 @@ void ParamsEdited::initFrom (const std::vector retinex.gammaretinex = retinex.gammaretinex && p.retinex.gammaretinex == other.retinex.gammaretinex; retinex.str = retinex.str && p.retinex.str == other.retinex.str; retinex.scal = retinex.scal && p.retinex.scal == other.retinex.scal; + retinex.iter = retinex.iter && p.retinex.iter == other.retinex.iter; + retinex.grad = retinex.grad && p.retinex.grad == other.retinex.grad; retinex.gam = retinex.gam && p.retinex.gam == other.retinex.gam; retinex.slope = retinex.slope && p.retinex.slope == other.retinex.slope; retinex.neigh = retinex.neigh && p.retinex.neigh == other.retinex.neigh; @@ -1082,6 +1086,18 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.retinex.str = dontforceSet && options.baBehav[ADDSET_RETI_STR] ? toEdit.retinex.str + mods.retinex.str : mods.retinex.str; } + if (retinex.scal) { + toEdit.retinex.scal = mods.retinex.scal; + } + + if (retinex.iter) { + toEdit.retinex.iter = mods.retinex.iter; + } + + if (retinex.grad) { + toEdit.retinex.grad = mods.retinex.grad; + } + // if (retinex.scal) { // toEdit.retinex.scal = dontforceSet && options.baBehav[ADDSET_RETI_SCAL] ? toEdit.retinex.scal + mods.retinex.scal : mods.retinex.scal; // } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 3fa753013..ed1f07aec 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -61,6 +61,8 @@ public: bool enabled; bool str; bool scal; + bool iter; + bool grad; bool gam; bool slope; bool neigh; diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index b964ecbb5..0578c3e57 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -144,7 +144,9 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), transLabels->set_tooltip_markup (M("TP_RETINEX_TLABEL_TOOLTIP")); transLabels2 = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); - scal = Gtk::manage (new Adjuster (M("TP_RETINEX_SCALES"), 1, 8., 1., 3.)); + scal = Gtk::manage (new Adjuster (M("TP_RETINEX_SCALES"), -1, 5., 1., 3.)); + iter = Gtk::manage (new Adjuster (M("TP_RETINEX_ITER"), 1, 5., 1., 1.)); + grad = Gtk::manage (new Adjuster (M("TP_RETINEX_GRAD"), -2., 2., 1., 1.)); gain = Gtk::manage (new Adjuster (M("TP_RETINEX_GAIN"), 20, 200, 1, 50)); offs = Gtk::manage (new Adjuster (M("TP_RETINEX_OFFSET"), -10000, 10000, 1, 0)); // vart = Gtk::manage (new Adjuster (M("TP_RETINEX_VARIANCE"), 50, 500, 1, 125)); @@ -153,6 +155,8 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), // grbl = Gtk::manage (new Adjuster (M("TP_RETINEX_HIGHLIGHT3"), 1, 100, 1, 50)); gain->set_tooltip_markup (M("TP_RETINEX_GAIN_TOOLTIP")); scal->set_tooltip_markup (M("TP_RETINEX_SCALES_TOOLTIP")); + iter->set_tooltip_markup (M("TP_RETINEX_ITER_TOOLTIP")); + grad->set_tooltip_markup (M("TP_RETINEX_GRAD_TOOLTIP")); // vart->set_tooltip_markup (M("TP_RETINEX_VARIANCE_TOOLTIP")); limd->set_tooltip_markup (M("TP_RETINEX_THRESHOLD_TOOLTIP")); baselog->set_tooltip_markup (M("TP_RETINEX_BASELOG_TOOLTIP")); @@ -211,8 +215,14 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), slope->show (); -// settingsVBox->pack_start (*scal); -// scal->show (); + settingsVBox->pack_start (*iter); + iter->show (); + + settingsVBox->pack_start (*scal); + scal->show (); + + settingsVBox->pack_start (*grad); + grad->show (); settingsVBox->pack_start (*gain); gain->show (); @@ -267,6 +277,18 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), scal->delay = 200; } + iter->setAdjusterListener (this); + + if (iter->delay < 200) { + iter->delay = 200; + } + + grad->setAdjusterListener (this); + + if (grad->delay < 200) { + grad->delay = 200; + } + gam->setAdjusterListener (this); if (gam->delay < 500) { @@ -354,6 +376,8 @@ void Retinex::neutral_pressed () offs->resetValue(false); str->resetValue(false); scal->resetValue(false); + iter->resetValue(false); + grad->resetValue(false); vart->resetValue(false); limd->resetValue(false); highl->resetValue(false); @@ -477,6 +501,8 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) if (pedited) { scal->setEditedState (pedited->retinex.scal ? Edited : UnEdited); + iter->setEditedState (pedited->retinex.iter ? Edited : UnEdited); + grad->setEditedState (pedited->retinex.grad ? Edited : UnEdited); neigh->setEditedState (pedited->retinex.neigh ? Edited : UnEdited); gam->setEditedState (pedited->retinex.gam ? Edited : UnEdited); slope->setEditedState (pedited->retinex.slope ? Edited : UnEdited); @@ -515,6 +541,8 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) offs->setValue (pp->retinex.offs); str->setValue (pp->retinex.str); scal->setValue (pp->retinex.scal); + iter->setValue (pp->retinex.iter); + grad->setValue (pp->retinex.grad); vart->setValue (pp->retinex.vart); limd->setValue (pp->retinex.limd); gam->setValue (pp->retinex.gam); @@ -522,10 +550,17 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) highl->setValue (pp->retinex.highl); baselog->setValue (pp->retinex.baselog); // grbl->setValue (pp->retinex.grbl); + if(pp->retinex.iter == 1) { + grad->set_sensitive(false); + scal->set_sensitive(false); + } + else { + grad->set_sensitive(true); + scal->set_sensitive(true); + } setEnabled (pp->retinex.enabled); - medianmapConn.block (true); medianmap->set_active (pp->retinex.medianmap); medianmapConn.block (false); lastmedianmap = pp->retinex.medianmap; @@ -590,6 +625,8 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited) pp->retinex.str = str->getValue (); pp->retinex.scal = (int)scal->getValue (); + pp->retinex.iter = (int) iter->getValue (); + pp->retinex.grad = (int) grad->getValue (); pp->retinex.gam = gam->getValue (); pp->retinex.slope = slope->getValue (); pp->retinex.neigh = neigh->getValue (); @@ -615,6 +652,8 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited) //%%%%%%%%%%%%%%%%%%%%%% pedited->retinex.str = str->getEditedState (); pedited->retinex.scal = scal->getEditedState (); + pedited->retinex.iter = iter->getEditedState (); + pedited->retinex.grad = grad->getEditedState (); pedited->retinex.gam = gam->getEditedState (); pedited->retinex.slope = slope->getEditedState (); pedited->retinex.neigh = neigh->getEditedState (); @@ -770,6 +809,8 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi offs->setDefault (defParams->retinex.offs); str->setDefault (defParams->retinex.str); scal->setDefault (defParams->retinex.scal); + iter->setDefault (defParams->retinex.iter); + grad->setDefault (defParams->retinex.grad); vart->setDefault (defParams->retinex.vart); limd->setDefault (defParams->retinex.limd); highl->setDefault (defParams->retinex.highl); @@ -784,6 +825,8 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi offs->setDefaultEditedState (pedited->retinex.offs ? Edited : UnEdited); str->setDefaultEditedState (pedited->retinex.str ? Edited : UnEdited); scal->setDefaultEditedState (pedited->retinex.scal ? Edited : UnEdited); + iter->setDefaultEditedState (pedited->retinex.iter ? Edited : UnEdited); + grad->setDefaultEditedState (pedited->retinex.grad ? Edited : UnEdited); vart->setDefaultEditedState (pedited->retinex.vart ? Edited : UnEdited); limd->setDefaultEditedState (pedited->retinex.limd ? Edited : UnEdited); highl->setDefaultEditedState (pedited->retinex.highl ? Edited : UnEdited); @@ -803,6 +846,8 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi // grbl->setDefaultEditedState (Irrelevant); str->setDefaultEditedState (Irrelevant); scal->setDefaultEditedState (Irrelevant); + iter->setDefaultEditedState (Irrelevant); + grad->setDefaultEditedState (Irrelevant); gam->setDefaultEditedState (Irrelevant); slope->setDefaultEditedState (Irrelevant); } @@ -827,6 +872,15 @@ void Retinex::adjusterChanged (Adjuster* a, double newval) if (!listener || !getEnabled()) { return; } + if(iter->getTextValue() > "1") { + scal->set_sensitive(true); + grad->set_sensitive(true); + } + else { + scal->set_sensitive(false); + grad->set_sensitive(false); + } + if (a == neigh) { listener->panelChanged (EvLneigh, neigh->getTextValue()); @@ -834,6 +888,10 @@ void Retinex::adjusterChanged (Adjuster* a, double newval) listener->panelChanged (EvLstr, str->getTextValue()); } else if (a == scal) { listener->panelChanged (EvLscal, scal->getTextValue()); + } else if (a == iter) { + listener->panelChanged (EvLiter, iter->getTextValue()); + } else if (a == grad) { + listener->panelChanged (EvLgrad, grad->getTextValue()); } else if (a == gain) { listener->panelChanged (EvLgain, gain->getTextValue()); } else if (a == offs) { @@ -902,6 +960,8 @@ void Retinex::trimValues (rtengine::procparams::ProcParams* pp) { str->trimValue(pp->retinex.str); scal->trimValue(pp->retinex.scal); + iter->trimValue(pp->retinex.iter); + grad->trimValue(pp->retinex.grad); neigh->trimValue(pp->retinex.neigh); gain->trimValue(pp->retinex.gain); offs->trimValue(pp->retinex.offs); @@ -975,6 +1035,8 @@ void Retinex::setBatchMode (bool batchMode) offs->showEditedCB (); str->showEditedCB (); scal->showEditedCB (); + iter->showEditedCB (); + grad->showEditedCB (); gam->showEditedCB (); slope->showEditedCB (); vart->showEditedCB (); diff --git a/rtgui/retinex.h b/rtgui/retinex.h index 59001ce18..499b0ef0f 100644 --- a/rtgui/retinex.h +++ b/rtgui/retinex.h @@ -24,6 +24,8 @@ protected: CurveEditorGroup* curveEditorGH; Adjuster* str; Adjuster* scal; + Adjuster* grad; + Adjuster* iter; Adjuster* neigh; Adjuster* gain; Adjuster* offs; From 04478c3b946fc3e836d62330bda0d917084f440f Mon Sep 17 00:00:00 2001 From: Desmis Date: Mon, 9 Nov 2015 07:57:22 +0100 Subject: [PATCH 02/61] Fixed segfault bug and add strength gradient --- rtdata/languages/default | 3 +++ rtengine/ipretinex.cc | 31 ++++++++++++++++++++++++++++--- rtengine/procevents.h | 1 + rtengine/procparams.cc | 16 +++++++++++++++- rtengine/procparams.h | 1 + rtengine/refreshmap.cc | 3 ++- rtgui/paramsedited.cc | 6 ++++++ rtgui/paramsedited.h | 1 + rtgui/retinex.cc | 27 +++++++++++++++++++++++++++ rtgui/retinex.h | 1 + 10 files changed, 85 insertions(+), 5 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index aeb5664e8..ca1d0ac76 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -658,6 +658,7 @@ HISTORY_MSG_425;Retinex - Log base HISTORY_MSG_426;Retinex - Hue equalizer HISTORY_MSG_427;Retinex - Iterations HISTORY_MSG_428;Retinex - T. Gradient +HISTORY_MSG_429;Retinex - S. Gradient HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOTS;Snapshots @@ -1660,6 +1661,8 @@ TP_RETINEX_ITER;Iterations (Tone-mapping) TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator\nHigh values increase the processing time TP_RETINEX_GRAD;Transmission gradient TP_RETINEX_GRAD_TOOLTIP;If slider at 0, all iterations are identical\nIf > 0 Variance and Threshold are reduce when iteration increases and conversely +TP_RETINEX_GRADS;Strength gradient +TP_RETINEX_GRAD_TOOLTIP;If slider at 0, all iterations are identical\nIf > 0 Strength is reduce when iteration increases and conversely TP_RETINEX_LABEL;Retinex TP_RETINEX_LABSPACE;L*a*b* TP_RETINEX_LOW;Low diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index 1f6602b62..b07af2e14 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -223,6 +223,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e int nei = (int) 2.8f * deh.neigh; //def = 220 float vart = (float)deh.vart / 100.f;//variance float gradvart = (float)deh.grad; + float gradstr = (float)deh.grads; float strength = (float) deh.str / 100.f; // Blend with original L channel data float limD = (float) deh.limd; limD = pow(limD, 1.7f);//about 2500 enough @@ -274,6 +275,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e moderetinex = 3; } for(int it=1; itretinex.grad) { - keyFile.set_integer ("Retinex", "Grad", retinex.iter); + keyFile.set_integer ("Retinex", "Grad", retinex.grad); + } + + if (!pedited || pedited->retinex.grads) { + keyFile.set_integer ("Retinex", "Grads", retinex.grads); } if (!pedited || pedited->retinex.gam) { @@ -3877,6 +3882,14 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) } } + if (keyFile.has_key ("Retinex", "Grads")) { + retinex.grads = keyFile.get_integer ("Retinex", "Grads"); + + if (pedited) { + pedited->retinex.grads = true; + } + } + if (keyFile.has_key ("Retinex", "Gam")) { retinex.gam = keyFile.get_double ("Retinex", "Gam"); @@ -7350,6 +7363,7 @@ bool ProcParams::operator== (const ProcParams& other) && retinex.scal == other.retinex.scal && retinex.iter == other.retinex.iter && retinex.grad == other.retinex.grad + && retinex.grads == other.retinex.grads && retinex.gam == other.retinex.gam && retinex.slope == other.retinex.slope && retinex.neigh == other.retinex.neigh diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 1226d1584..2b8b7ada6 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -277,6 +277,7 @@ public: int scal; int iter; int grad; + int grads; double gam; double slope; int neigh; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 88338f06c..30373a35e 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -455,7 +455,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { // DEMOSAIC, // EvLgrbl DEMOSAIC, // EvRetinexlhcurve RETINEX, // EvLiter - RETINEX // EvLgrad + RETINEX, // EvLgrad + RETINEX // EvLgrads }; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 600a68af4..2efed572e 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -60,6 +60,7 @@ void ParamsEdited::set (bool v) retinex.scal = v; retinex.iter = v; retinex.grad = v; + retinex.grads = v; retinex.gam = v; retinex.slope = v; retinex.neigh = v; @@ -539,6 +540,7 @@ void ParamsEdited::initFrom (const std::vector retinex.scal = retinex.scal && p.retinex.scal == other.retinex.scal; retinex.iter = retinex.iter && p.retinex.iter == other.retinex.iter; retinex.grad = retinex.grad && p.retinex.grad == other.retinex.grad; + retinex.grads = retinex.grads && p.retinex.grads == other.retinex.grads; retinex.gam = retinex.gam && p.retinex.gam == other.retinex.gam; retinex.slope = retinex.slope && p.retinex.slope == other.retinex.slope; retinex.neigh = retinex.neigh && p.retinex.neigh == other.retinex.neigh; @@ -1098,6 +1100,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.retinex.grad = mods.retinex.grad; } + if (retinex.grads) { + toEdit.retinex.grads = mods.retinex.grads; + } + // if (retinex.scal) { // toEdit.retinex.scal = dontforceSet && options.baBehav[ADDSET_RETI_SCAL] ? toEdit.retinex.scal + mods.retinex.scal : mods.retinex.scal; // } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index ed1f07aec..f174c8d52 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -63,6 +63,7 @@ public: bool scal; bool iter; bool grad; + bool grads; bool gam; bool slope; bool neigh; diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index 0578c3e57..0bd5c28ae 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -147,6 +147,7 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), scal = Gtk::manage (new Adjuster (M("TP_RETINEX_SCALES"), -1, 5., 1., 3.)); iter = Gtk::manage (new Adjuster (M("TP_RETINEX_ITER"), 1, 5., 1., 1.)); grad = Gtk::manage (new Adjuster (M("TP_RETINEX_GRAD"), -2., 2., 1., 1.)); + grads = Gtk::manage (new Adjuster (M("TP_RETINEX_GRADS"), -2., 2., 1., 1.)); gain = Gtk::manage (new Adjuster (M("TP_RETINEX_GAIN"), 20, 200, 1, 50)); offs = Gtk::manage (new Adjuster (M("TP_RETINEX_OFFSET"), -10000, 10000, 1, 0)); // vart = Gtk::manage (new Adjuster (M("TP_RETINEX_VARIANCE"), 50, 500, 1, 125)); @@ -157,6 +158,7 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), scal->set_tooltip_markup (M("TP_RETINEX_SCALES_TOOLTIP")); iter->set_tooltip_markup (M("TP_RETINEX_ITER_TOOLTIP")); grad->set_tooltip_markup (M("TP_RETINEX_GRAD_TOOLTIP")); + grads->set_tooltip_markup (M("TP_RETINEX_GRADS_TOOLTIP")); // vart->set_tooltip_markup (M("TP_RETINEX_VARIANCE_TOOLTIP")); limd->set_tooltip_markup (M("TP_RETINEX_THRESHOLD_TOOLTIP")); baselog->set_tooltip_markup (M("TP_RETINEX_BASELOG_TOOLTIP")); @@ -224,6 +226,9 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), settingsVBox->pack_start (*grad); grad->show (); + settingsVBox->pack_start (*grads); + grads->show (); + settingsVBox->pack_start (*gain); gain->show (); @@ -289,6 +294,12 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), grad->delay = 200; } + grads->setAdjusterListener (this); + + if (grads->delay < 200) { + grads->delay = 200; + } + gam->setAdjusterListener (this); if (gam->delay < 500) { @@ -378,6 +389,7 @@ void Retinex::neutral_pressed () scal->resetValue(false); iter->resetValue(false); grad->resetValue(false); + grads->resetValue(false); vart->resetValue(false); limd->resetValue(false); highl->resetValue(false); @@ -503,6 +515,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) scal->setEditedState (pedited->retinex.scal ? Edited : UnEdited); iter->setEditedState (pedited->retinex.iter ? Edited : UnEdited); grad->setEditedState (pedited->retinex.grad ? Edited : UnEdited); + grads->setEditedState (pedited->retinex.grads ? Edited : UnEdited); neigh->setEditedState (pedited->retinex.neigh ? Edited : UnEdited); gam->setEditedState (pedited->retinex.gam ? Edited : UnEdited); slope->setEditedState (pedited->retinex.slope ? Edited : UnEdited); @@ -543,6 +556,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) scal->setValue (pp->retinex.scal); iter->setValue (pp->retinex.iter); grad->setValue (pp->retinex.grad); + grads->setValue (pp->retinex.grads); vart->setValue (pp->retinex.vart); limd->setValue (pp->retinex.limd); gam->setValue (pp->retinex.gam); @@ -553,10 +567,12 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) if(pp->retinex.iter == 1) { grad->set_sensitive(false); scal->set_sensitive(false); + grads->set_sensitive(false); } else { grad->set_sensitive(true); scal->set_sensitive(true); + grads->set_sensitive(true); } setEnabled (pp->retinex.enabled); @@ -627,6 +643,7 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited) pp->retinex.scal = (int)scal->getValue (); pp->retinex.iter = (int) iter->getValue (); pp->retinex.grad = (int) grad->getValue (); + pp->retinex.grads = (int) grads->getValue (); pp->retinex.gam = gam->getValue (); pp->retinex.slope = slope->getValue (); pp->retinex.neigh = neigh->getValue (); @@ -654,6 +671,7 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited) pedited->retinex.scal = scal->getEditedState (); pedited->retinex.iter = iter->getEditedState (); pedited->retinex.grad = grad->getEditedState (); + pedited->retinex.grads = grads->getEditedState (); pedited->retinex.gam = gam->getEditedState (); pedited->retinex.slope = slope->getEditedState (); pedited->retinex.neigh = neigh->getEditedState (); @@ -811,6 +829,7 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi scal->setDefault (defParams->retinex.scal); iter->setDefault (defParams->retinex.iter); grad->setDefault (defParams->retinex.grad); + grads->setDefault (defParams->retinex.grads); vart->setDefault (defParams->retinex.vart); limd->setDefault (defParams->retinex.limd); highl->setDefault (defParams->retinex.highl); @@ -827,6 +846,7 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi scal->setDefaultEditedState (pedited->retinex.scal ? Edited : UnEdited); iter->setDefaultEditedState (pedited->retinex.iter ? Edited : UnEdited); grad->setDefaultEditedState (pedited->retinex.grad ? Edited : UnEdited); + grads->setDefaultEditedState (pedited->retinex.grads ? Edited : UnEdited); vart->setDefaultEditedState (pedited->retinex.vart ? Edited : UnEdited); limd->setDefaultEditedState (pedited->retinex.limd ? Edited : UnEdited); highl->setDefaultEditedState (pedited->retinex.highl ? Edited : UnEdited); @@ -848,6 +868,7 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi scal->setDefaultEditedState (Irrelevant); iter->setDefaultEditedState (Irrelevant); grad->setDefaultEditedState (Irrelevant); + grads->setDefaultEditedState (Irrelevant); gam->setDefaultEditedState (Irrelevant); slope->setDefaultEditedState (Irrelevant); } @@ -875,10 +896,12 @@ void Retinex::adjusterChanged (Adjuster* a, double newval) if(iter->getTextValue() > "1") { scal->set_sensitive(true); grad->set_sensitive(true); + grads->set_sensitive(true); } else { scal->set_sensitive(false); grad->set_sensitive(false); + grads->set_sensitive(false); } @@ -892,6 +915,8 @@ void Retinex::adjusterChanged (Adjuster* a, double newval) listener->panelChanged (EvLiter, iter->getTextValue()); } else if (a == grad) { listener->panelChanged (EvLgrad, grad->getTextValue()); + } else if (a == grads) { + listener->panelChanged (EvLgrads, grads->getTextValue()); } else if (a == gain) { listener->panelChanged (EvLgain, gain->getTextValue()); } else if (a == offs) { @@ -962,6 +987,7 @@ void Retinex::trimValues (rtengine::procparams::ProcParams* pp) scal->trimValue(pp->retinex.scal); iter->trimValue(pp->retinex.iter); grad->trimValue(pp->retinex.grad); + grads->trimValue(pp->retinex.grads); neigh->trimValue(pp->retinex.neigh); gain->trimValue(pp->retinex.gain); offs->trimValue(pp->retinex.offs); @@ -1037,6 +1063,7 @@ void Retinex::setBatchMode (bool batchMode) scal->showEditedCB (); iter->showEditedCB (); grad->showEditedCB (); + grads->showEditedCB (); gam->showEditedCB (); slope->showEditedCB (); vart->showEditedCB (); diff --git a/rtgui/retinex.h b/rtgui/retinex.h index 499b0ef0f..e014bed5d 100644 --- a/rtgui/retinex.h +++ b/rtgui/retinex.h @@ -25,6 +25,7 @@ protected: Adjuster* str; Adjuster* scal; Adjuster* grad; + Adjuster* grads; Adjuster* iter; Adjuster* neigh; Adjuster* gain; From 8cfab83f51dd5b35a60bd7039187b951bcc0a1a5 Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 10 Nov 2015 08:05:44 +0100 Subject: [PATCH 03/61] Changes some labels - small change to gradient --- rtdata/languages/default | 12 ++++++------ rtengine/ipretinex.cc | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index ca1d0ac76..43eda0146 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -637,9 +637,9 @@ HISTORY_MSG_404;W - ES - Base amplification HISTORY_MSG_405;W - Denoise - Level 4 HISTORY_MSG_406;W - ES - Neighboring pixels HISTORY_MSG_407;Retinex - Method -HISTORY_MSG_408;Retinex - Neighboring -HISTORY_MSG_409;Retinex - Gain -HISTORY_MSG_410;Retinex - Offset +HISTORY_MSG_408;Retinex - Radius +HISTORY_MSG_409;Retinex - Contrast +HISTORY_MSG_410;Retinex - Brightness HISTORY_MSG_411;Retinex - Strength HISTORY_MSG_412;Retinex - G. Gradient HISTORY_MSG_413;Retinex - Variance @@ -1642,7 +1642,7 @@ TP_RETINEX_CURVEEDITOR_CD_TOOLTIP;Luminance according to luminance L=f(L)\nCorre TP_RETINEX_CURVEEDITOR_LH;Strength=f(H) TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. TP_RETINEX_FREEGAMMA;Free gamma -TP_RETINEX_GAIN;Gain +TP_RETINEX_GAIN;Contrast TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. TP_RETINEX_GAMMA;Gamma TP_RETINEX_GAMMA_FREE;Free @@ -1671,10 +1671,10 @@ TP_RETINEX_METHOD;Method TP_RETINEX_METHOD_TOOLTIP;Low = Reinforce low light,\nUniform = Equalize action,\nHigh = Reinforce high light,\nHighlights = Remove magenta in highlights. TP_RETINEX_MLABEL;Restored haze-free Min=%1 Max=%2 TP_RETINEX_MLABEL_TOOLTIP;Should be near min=0 max=32768\nRestored image with no mixture. -TP_RETINEX_NEIGHBOR;Neighboring pixels +TP_RETINEX_NEIGHBOR;Radius TP_RETINEX_NEUTRAL;Reset TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. -TP_RETINEX_OFFSET;Offset +TP_RETINEX_OFFSET;Brightness TP_RETINEX_SETTINGS;Settings TP_RETINEX_SCALES;Gaussian gradient TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical\nIf > 0 Scale and Neighboring pixels are reduce when iteration increases and conversely diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index b07af2e14..a93afbabc 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -288,19 +288,19 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } else if(gradient==2) { grad=0.5f*it+0.5f; - sc=-it+6.f; + sc=-0.75f*it+5.75f; } else if(gradient==3) { grad=0.666f*it+0.333f; - sc=-it+6.f; + sc=-0.75f*it+5.75f; } else if(gradient==4) { grad=0.8f*it+0.2f; - sc=-it+6.f; + sc=-0.75f*it+5.75f; } else if(gradient==5) { grad=0.9f*it+0.1f; - sc=-it+6.f; + sc=-0.75f*it+5.75f; } else if(gradient==-1) { grad=-0.125f*it+1.125f; From 4b6fa0c5f830e45a16467888091c3cb31e8fa397 Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 10 Nov 2015 08:30:29 +0100 Subject: [PATCH 04/61] Forgot Tooltip label --- rtdata/languages/default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 43eda0146..e7836298a 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1662,7 +1662,7 @@ TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator\nHigh values increase t TP_RETINEX_GRAD;Transmission gradient TP_RETINEX_GRAD_TOOLTIP;If slider at 0, all iterations are identical\nIf > 0 Variance and Threshold are reduce when iteration increases and conversely TP_RETINEX_GRADS;Strength gradient -TP_RETINEX_GRAD_TOOLTIP;If slider at 0, all iterations are identical\nIf > 0 Strength is reduce when iteration increases and conversely +TP_RETINEX_GRADS_TOOLTIP;If slider at 0, all iterations are identical\nIf > 0 Strength is reduce when iteration increases and conversely TP_RETINEX_LABEL;Retinex TP_RETINEX_LABSPACE;L*a*b* TP_RETINEX_LOW;Low From a1fd3d72b205e3fb362ab29afc1e8807567562c0 Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 10 Nov 2015 11:34:17 +0100 Subject: [PATCH 05/61] Improvement to Gaussian gradient --- rtengine/ipretinex.cc | 33 ++++++++++++++++++++++++++++++--- rtgui/retinex.cc | 2 +- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index a93afbabc..0f67c1a84 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -275,6 +275,11 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e moderetinex = 3; } for(int it=1; it= 0; scale-- ) { if(scale == scal - 1) { gaussianBlur (src, out, W_L, H_L, RetinexScales[scale], buffer); - } else { // reuse result of last iteration + } else { + printf("reti=%f\n",RetinexScales[scale]);// reuse result of last iteration gaussianBlur (out, out, W_L, H_L, sqrtf(SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])), buffer); } diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index 0bd5c28ae..099ee7310 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -144,7 +144,7 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), transLabels->set_tooltip_markup (M("TP_RETINEX_TLABEL_TOOLTIP")); transLabels2 = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); - scal = Gtk::manage (new Adjuster (M("TP_RETINEX_SCALES"), -1, 5., 1., 3.)); + scal = Gtk::manage (new Adjuster (M("TP_RETINEX_SCALES"), -1, 6., 1., 3.)); iter = Gtk::manage (new Adjuster (M("TP_RETINEX_ITER"), 1, 5., 1., 1.)); grad = Gtk::manage (new Adjuster (M("TP_RETINEX_GRAD"), -2., 2., 1., 1.)); grads = Gtk::manage (new Adjuster (M("TP_RETINEX_GRADS"), -2., 2., 1., 1.)); From 44490e81ae9bb9cde02cfcc9d61de2d4d9db39ed Mon Sep 17 00:00:00 2001 From: Desmis Date: Thu, 12 Nov 2015 08:58:07 +0100 Subject: [PATCH 06/61] Add mask method --- rtdata/languages/default | 17 +++ rtengine/curves.cc | 39 ++++++ rtengine/curves.h | 1 + rtengine/imagesource.h | 6 +- rtengine/improccoordinator.cc | 6 +- rtengine/ipretinex.cc | 95 ++++++++++++-- rtengine/procevents.h | 7 ++ rtengine/procparams.cc | 104 ++++++++++++++++ rtengine/procparams.h | 8 ++ rtengine/rawimagesource.cc | 7 +- rtengine/rawimagesource.h | 6 +- rtengine/refreshmap.cc | 15 ++- rtengine/shmap.cc | 162 ++++++++++++++++++++++++ rtengine/shmap.h | 2 + rtengine/simpleprocess.cc | 6 +- rtgui/paramsedited.cc | 46 +++++++ rtgui/paramsedited.h | 8 ++ rtgui/retinex.cc | 228 ++++++++++++++++++++++++++++++++++ rtgui/retinex.h | 15 ++- 19 files changed, 750 insertions(+), 28 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index e7836298a..97b327ef6 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -659,6 +659,13 @@ HISTORY_MSG_426;Retinex - Hue equalizer HISTORY_MSG_427;Retinex - Iterations HISTORY_MSG_428;Retinex - T. Gradient HISTORY_MSG_429;Retinex - S. Gradient +HISTORY_MSG_430;Retinex - Mask highlights +HISTORY_MSG_431;Retinex - Mask TW highlights +HISTORY_MSG_432;Retinex - Mask shadows +HISTORY_MSG_433;Retinex - Mask TW shadows +HISTORY_MSG_434;Retinex - Mask radius +HISTORY_MSG_435;Retinex - Mask method +HISTORY_MSG_436;Retinex - Mask curve HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOTS;Snapshots @@ -1637,6 +1644,9 @@ TP_RESIZE_W;Width: TP_RETINEX_CONTEDIT_HSL;Histogram equalizer HSL TP_RETINEX_CONTEDIT_LAB;Histogram equalizer L*a*b* TP_RETINEX_CONTEDIT_LH;Hue equalizer +TP_RETINEX_CONTEDIT_MAP;Mask equalizer +TP_RETINEX_CURVEEDITOR_MAP;L=f(L) +TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This Curve can be applied alone or with gaussian mask or wavelet mask\nBe aware to artifacts TP_RETINEX_CURVEEDITOR_CD;L=f(L) TP_RETINEX_CURVEEDITOR_CD_TOOLTIP;Luminance according to luminance L=f(L)\nCorrect raw data to reduce halos and artifacts. TP_RETINEX_CURVEEDITOR_LH;Strength=f(H) @@ -1666,6 +1676,13 @@ TP_RETINEX_GRADS_TOOLTIP;If slider at 0, all iterations are identical\nIf > 0 St TP_RETINEX_LABEL;Retinex TP_RETINEX_LABSPACE;L*a*b* TP_RETINEX_LOW;Low +TP_RETINEX_MAP;Mask method +TP_RETINEX_MAP_METHOD_TOOLTIP;Use the mask generate by Gaussian function above to reduce halos and artifacts\nCurve only: apply a diagonal contrast curve on mask, be aware to artifacts\nGaussian mask : generate and use a gaussian blur of the original mask (quick)\nSharp mask : generate and use a wavelet on the original mask (slow or very very slow) +TP_RETINEX_MAP_NONE;none +TP_RETINEX_MAP_CURV;Curve only +TP_RETINEX_MAP_GAUS;Gaussian mask +TP_RETINEX_MAP_MAPP;Sharp mask (wavelet partial) +TP_RETINEX_MAP_MAPT;Sharp mask (wavelet total) TP_RETINEX_MEDIAN;Transmission median filter TP_RETINEX_METHOD;Method TP_RETINEX_METHOD_TOOLTIP;Low = Reinforce low light,\nUniform = Equalize action,\nHigh = Reinforce high light,\nHighlights = Remove magenta in highlights. diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 4ad1d06bd..d0b4c026f 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -504,6 +504,45 @@ void CurveFactory::curveCL ( bool & clcutili, const std::vector& clcurve } } +void CurveFactory::mapcurve ( bool & mapcontlutili, const std::vector& mapcurvePoints, LUTf & mapcurve, int skip, LUTu & histogram, LUTu & outBeforeCurveHistogram) +{ + bool needed = false; + DiagonalCurve* dCurve = NULL; + outBeforeCurveHistogram.clear(); + bool histNeeded = false; + + if (!mapcurvePoints.empty() && mapcurvePoints[0] != 0) { + dCurve = new DiagonalCurve (mapcurvePoints, CURVES_MIN_POLY_POINTS / skip); + + if (outBeforeCurveHistogram) { + histNeeded = true; + } + + if (dCurve && !dCurve->isIdentity()) { + needed = true; + mapcontlutili = true; + } + } + + if (histNeeded) { + for (int i = 0; i < 32768; i++) { + double hval = CLIPD((double)i / 32767.0); + int hi = (int)(255.0 * hval); + outBeforeCurveHistogram[hi] += histogram[i] ; + } + } + + fillCurveArray(dCurve, mapcurve, skip, needed); + + if (dCurve) { + delete dCurve; + dCurve = NULL; + } +} + + + + void CurveFactory::curveDehaContL ( bool & dehacontlutili, const std::vector& dehaclcurvePoints, LUTf & dehaclCurve, int skip, LUTu & histogram, LUTu & outBeforeCurveHistogram) { bool needed = false; diff --git a/rtengine/curves.h b/rtengine/curves.h index f0643c7a9..e55d7bc2a 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -283,6 +283,7 @@ public: static void curveWavContL ( bool & wavcontlutili, const std::vector& wavclcurvePoints, LUTf & wavclCurve,/* LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,*/int skip); static void curveDehaContL ( bool & dehacontlutili, const std::vector& dehaclcurvePoints, LUTf & dehaclCurve, int skip, LUTu & histogram, LUTu & outBeforeCurveHistogram); + static void mapcurve ( bool & mapcontlutili, const std::vector& mapcurvePoints, LUTf & mapcurve, int skip, LUTu & histogram, LUTu & outBeforeCurveHistogram); static void curveToningCL ( bool & clctoningutili, const std::vector& clcurvePoints, LUTf & clToningCurve, int skip); static void curveToningLL ( bool & llctoningutili, const std::vector& llcurvePoints, LUTf & llToningCurve, int skip); diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index d9f088813..eaf9997fa 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -69,14 +69,14 @@ public: virtual int load (Glib::ustring fname, bool batch = false) = 0; virtual void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse) {}; virtual void demosaic (const RAWParams &raw) {}; - virtual void retinex (ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) {}; - virtual void retinexPrepareCurves (RetinexParams retinexParams, LUTf &cdcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {}; + virtual void retinex (ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) {}; + virtual void retinexPrepareCurves (RetinexParams retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {}; virtual void retinexPrepareBuffers (ColorManagementParams cmp, RetinexParams retinexParams, multi_array2D &conversionBuffer, LUTu &lhist16RETI) {}; virtual void flushRawData () {}; virtual void flushRGB () {}; virtual void HLRecovery_Global (ToneCurveParams hrp) {}; virtual void HLRecovery_inpaint (float** red, float** green, float** blue) {}; - virtual void MSR(LabImage* lab, int width, int height, int skip, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) {}; + virtual void MSR(LabImage* lab, LUTf & mapcurve, bool &mapcontlutili, int width, int height, int skip, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) {}; virtual bool IsrgbSourceModified() = 0; // tracks whether cached rgb output of demosaic has been modified diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 8389ec34e..479ec1282 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -244,12 +244,14 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) if ((todo & (M_RETINEX|M_INIT)) && params.retinex.enabled) { bool dehacontlutili = false; + bool mapcontlutili = false; bool useHsl = false; LUTf cdcurve (65536, 0); + LUTf mapcurve (65536, 0); - imgsrc->retinexPrepareCurves(params.retinex, cdcurve, dehatransmissionCurve, dehacontlutili, useHsl, lhist16RETI, histLRETI); + imgsrc->retinexPrepareCurves(params.retinex, cdcurve, mapcurve, dehatransmissionCurve, dehacontlutili, mapcontlutili, useHsl, lhist16RETI, histLRETI); float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax; - imgsrc->retinex( params.icm, params.retinex, params.toneCurve, cdcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, histLRETI);//enabled Retinex + imgsrc->retinex( params.icm, params.retinex, params.toneCurve, mapcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, mapcontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, histLRETI);//enabled Retinex if(dehaListener) { dehaListener->minmaxChanged(maxCD, minCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index 0f67c1a84..d444380ce 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -32,6 +32,7 @@ * College of Physics and Information Engineering, Fuzhou University, Fuzhou, China * inspired from 2003 Fabien Pelisson + * some ideas taken (use of mask) Russell Cottrell - The Retinex .8bf Plugin */ @@ -205,7 +206,7 @@ void mean_stddv( float **dst, float &mean, float &stddv, int W_L, int H_L, const stddv = (float)sqrt(stddv); } -void RawImageSource::MSR(float** luminance, float** originalLuminance, float **exLuminance, int width, int height, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) +void RawImageSource::MSR(float** luminance, float** originalLuminance, float **exLuminance, LUTf & mapcurve, bool &mapcontlutili, int width, int height, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax) { if (deh.enabled) {//enabled float mean, stddv, maxtr, mintr; @@ -234,7 +235,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e bool higplus = false ; float elogt; float hl = deh.baselog; - + SHMap* shmap; if(hl >= 2.71828f) { elogt = 2.71828f + SQR(SQR(hl - 2.71828f)); } else { @@ -382,13 +383,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } } strengthx=ks*strength; - /* - float aahi = 49.f / 99.f; ////reduce sensibility 50% - float bbhi = 1.f - aahi; - float high; - high = bbhi + aahi * (float) deh.highl; - */ - printf("high=%f moderetinex=%d\n",high,moderetinex); + retinex_scales( RetinexScales, scal, moderetinex, nei/grad, high ); int H_L = height; @@ -401,6 +396,17 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e src[i] = &srcBuffer[i * W_L]; } + int h_th, s_th; + + int shHighlights = deh.highlights; + int shShadows = deh.shadows; + int mapmet=0; + if(deh.mapMethod=="map") mapmet=2; + if(deh.mapMethod=="mapT") mapmet=3; + if(deh.mapMethod=="curv") mapmet=1; + if(deh.mapMethod=="gaus") mapmet=4; + + #ifdef _OPENMP #pragma omp parallel for #endif @@ -425,6 +431,10 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e pond /= log(elogt); } + if(mapmet > 1) shmap = new SHMap (W_L, H_L, true); + + + float *buffer = new float[W_L * H_L];; #ifdef _OPENMP #pragma omp parallel @@ -434,9 +444,26 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e if(scale == scal - 1) { gaussianBlur (src, out, W_L, H_L, RetinexScales[scale], buffer); } else { - printf("reti=%f\n",RetinexScales[scale]);// reuse result of last iteration + // reuse result of last iteration gaussianBlur (out, out, W_L, H_L, sqrtf(SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])), buffer); } + //printf("scal=%d RetinexScales=%f\n",scale, RetinexScales[scale]); + printf(".."); + + + double shradius = deh.radius; + if(mapmet==4) shradius /= 10.; + + // if(shHighlights > 0 || shShadows > 0) { + if(mapmet==3) if(it==1) shmap->updateL (out, shradius, true, 1);//wav Total + if(mapmet==2 && scale >2) if(it==1) shmap->updateL (out, shradius, true, 1);//wav partial + if(mapmet==4) if(it==1) shmap->updateL (out, shradius, false, 1);//gauss + // } + if (shmap) { + h_th = shmap->max_f - deh.htonalwidth * (shmap->max_f - shmap->avg) / 100; + s_th = deh.stonalwidth * (shmap->avg - shmap->min_f) / 100; + } + #ifdef __SSE2__ vfloat pondv = F2V(pond); @@ -444,6 +471,47 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e vfloat limMaxv = F2V(limdx); #endif + + if(mapmet > 0) { +#ifdef _OPENMP + #pragma omp for +#endif + for (int i = 0; i < H_L; i++) { + if(mapcontlutili) { + int j = 0; + for (; j < W_L; j++) { + if(it==1) out[i][j] = mapcurve[2.f * out[i][j]] / 2.f; + } + } + } + + } + + // if(shHighlights > 0 || shShadows > 0) { + if((mapmet == 2 && scale >2) || mapmet==3 || mapmet==4) { + + +#ifdef _OPENMP + #pragma omp for +#endif + for (int i = 0; i < H_L; i++) { + int j = 0; + for (; j < W_L; j++) { + double mapval = 1.0 + shmap->map[i][j]; + double factor = 1.0; + + if (mapval > h_th) { + factor = (h_th + (100.0 - shHighlights) * (mapval - h_th) / 100.0) / mapval; + } else if (mapval < s_th) { + factor = (s_th - (100.0 - shShadows) * (s_th - mapval) / 100.0) / mapval; + } + out[i][j] *= factor; + + } + } + } + // } + #ifdef _OPENMP #pragma omp for #endif @@ -477,6 +545,13 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } } } + if(mapmet > 1) { + if(shmap) { + delete shmap; + } + } + shmap = NULL; + delete [] buffer; delete [] outBuffer; delete [] srcBuffer; diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 6f1d7144a..f23d68f2e 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -457,6 +457,13 @@ enum ProcEvent { EvLiter = 426, EvLgrad = 427, EvLgrads = 428, + EvLhighlights = 429, + EvLh_tonalwidth = 430, + EvLshadows = 431, + EvLs_tonalwidth = 432, + EvLradius = 433, + EvmapMethod = 434, + EvRetinexmapcurve = 435, NUMOFEVENTS }; } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 6c737f8a2..075067585 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -153,9 +153,16 @@ void RetinexParams::setDefaults() vart = 200; limd = 8; highl = 4; + highlights = 0; + htonalwidth = 80; + shadows = 0; + stonalwidth = 80; + radius = 40; + baselog = 2.71828; // grbl = 50; retinexMethod = "high"; + mapMethod = "none"; retinexcolorspace = "Lab"; gammaretinex = "none"; medianmap = false; @@ -165,6 +172,8 @@ void RetinexParams::setDefaults() cdHcurve.push_back(DCT_Linear); lhcurve.clear(); lhcurve.push_back(DCT_Linear); + mapcurve.clear(); + mapcurve.push_back(DCT_Linear); getDefaulttransmissionCurve(transmissionCurve); } @@ -1513,6 +1522,10 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol keyFile.set_string ("Retinex", "RetinexMethod", retinex.retinexMethod); } + if (!pedited || pedited->retinex.mapMethod) { + keyFile.set_string ("Retinex", "mapMethod", retinex.mapMethod); + } + if (!pedited || pedited->retinex.retinexcolorspace) { keyFile.set_string ("Retinex", "Retinexcolorspace", retinex.retinexcolorspace); } @@ -1526,6 +1539,11 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol keyFile.set_double_list("Retinex", "CDCurve", cdcurve); } + if (!pedited || pedited->retinex.mapcurve) { + Glib::ArrayHandle mapcurve = retinex.mapcurve; + keyFile.set_double_list("Retinex", "MAPCurve", mapcurve); + } + if (!pedited || pedited->retinex.cdHcurve) { Glib::ArrayHandle cdHcurve = retinex.cdHcurve; keyFile.set_double_list("Retinex", "CDHCurve", cdHcurve); @@ -1536,6 +1554,26 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol keyFile.set_double_list("Retinex", "LHCurve", lhcurve); } + if (!pedited || pedited->retinex.highlights) { + keyFile.set_integer ("Retinex", "Highlights", retinex.highlights); + } + + if (!pedited || pedited->retinex.htonalwidth) { + keyFile.set_integer ("Retinex", "HighlightTonalWidth", retinex.htonalwidth); + } + + if (!pedited || pedited->retinex.shadows) { + keyFile.set_integer ("Retinex", "Shadows", retinex.shadows); + } + + if (!pedited || pedited->retinex.stonalwidth) { + keyFile.set_integer ("Retinex", "ShadowTonalWidth", retinex.stonalwidth); + } + + if (!pedited || pedited->retinex.radius) { + keyFile.set_integer ("Retinex", "Radius", retinex.radius); + } + if (!pedited || pedited->retinex.transmissionCurve) { Glib::ArrayHandle transmissionCurve = retinex.transmissionCurve; keyFile.set_double_list("Retinex", "TransmissionCurve", transmissionCurve); @@ -3818,6 +3856,14 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) } } + if (keyFile.has_key ("Retinex", "mapMethod")) { + retinex.mapMethod = keyFile.get_string ("Retinex", "mapMethod"); + + if (pedited) { + pedited->retinex.mapMethod = true; + } + } + if (keyFile.has_key ("Retinex", "Retinexcolorspace")) { retinex.retinexcolorspace = keyFile.get_string ("Retinex", "Retinexcolorspace"); @@ -3970,6 +4016,14 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) } } + if (keyFile.has_key ("Retinex", "MAPCurve")) { + retinex.mapcurve = keyFile.get_double_list ("Retinex", "MAPCurve"); + + if (pedited) { + pedited->retinex.mapcurve = true; + } + } + if (keyFile.has_key ("Retinex", "CDHCurve")) { retinex.cdHcurve = keyFile.get_double_list ("Retinex", "CDHCurve"); @@ -3986,6 +4040,48 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) } } + if (keyFile.has_key ("Retinex", "Highlights")) { + retinex.highlights = keyFile.get_integer ("Retinex", "Highlights"); + + if (pedited) { + pedited->retinex.highlights = true; + } + } + + if (keyFile.has_key ("Retinex", "HighlightTonalWidth")) { + retinex.htonalwidth = keyFile.get_integer ("Retinex", "HighlightTonalWidth"); + + if (pedited) { + pedited->retinex.htonalwidth = true; + } + } + + if (keyFile.has_key ("Retinex", "Shadows")) { + retinex.shadows = keyFile.get_integer ("Retinex", "Shadows"); + + if (pedited) { + pedited->retinex.shadows = true; + } + } + + if (keyFile.has_key ("Retinex", "ShadowTonalWidth")) { + retinex.stonalwidth = keyFile.get_integer ("Retinex", "ShadowTonalWidth"); + + if (pedited) { + pedited->retinex.stonalwidth = true; + } + } + + + if (keyFile.has_key ("Retinex", "Radius")) { + sh.radius = keyFile.get_integer ("Retinex", "Radius"); + + if (pedited) { + pedited->retinex.radius = true; + } + } + + if (keyFile.has_key ("Retinex", "TransmissionCurve")) { retinex.transmissionCurve = keyFile.get_double_list ("Retinex", "TransmissionCurve"); @@ -7356,6 +7452,7 @@ bool ProcParams::operator== (const ProcParams& other) && toneCurve.hrenabled == other.toneCurve.hrenabled && toneCurve.method == other.toneCurve.method && retinex.cdcurve == other.retinex.cdcurve + && retinex.mapcurve == other.retinex.mapcurve && retinex.cdHcurve == other.retinex.cdHcurve && retinex.lhcurve == other.retinex.lhcurve && retinex.transmissionCurve == other.retinex.transmissionCurve @@ -7370,10 +7467,17 @@ bool ProcParams::operator== (const ProcParams& other) && retinex.gain == other.retinex.gain && retinex.limd == other.retinex.limd && retinex.highl == other.retinex.highl + && retinex.highlights == other.retinex.highlights + && retinex.htonalwidth == other.retinex.htonalwidth + && retinex.shadows == other.retinex.shadows + && retinex.stonalwidth == other.retinex.stonalwidth + && retinex.radius == other.retinex.radius + && retinex.baselog == other.retinex.baselog // && retinex.grbl == other.retinex.grbl && retinex.offs == other.retinex.offs && retinex.retinexMethod == other.retinex.retinexMethod + && retinex.mapMethod == other.retinex.mapMethod && retinex.retinexcolorspace == other.retinex.retinexcolorspace && retinex.gammaretinex == other.retinex.gammaretinex && retinex.vart == other.retinex.vart diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 2b8b7ada6..e2d2539ea 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -273,6 +273,7 @@ public: std::vector cdHcurve; std::vector lhcurve; std::vector transmissionCurve; + std::vector mapcurve; int str; int scal; int iter; @@ -283,9 +284,16 @@ public: int neigh; int gain; int offs; + int highlights; + int htonalwidth; + int shadows; + int stonalwidth; + int radius; + Glib::ustring retinexMethod; Glib::ustring retinexcolorspace; Glib::ustring gammaretinex; + Glib::ustring mapMethod; int vart; int limd; int highl; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 32d91be64..8a4fc3559 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -2107,7 +2107,7 @@ void RawImageSource::retinexPrepareBuffers(ColorManagementParams cmp, RetinexPar } -void RawImageSource::retinexPrepareCurves(RetinexParams retinexParams, LUTf &cdcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) +void RawImageSource::retinexPrepareCurves(RetinexParams retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) { useHsl = (retinexParams.retinexcolorspace == "HSLLOG" || retinexParams.retinexcolorspace == "HSLLIN"); @@ -2116,12 +2116,13 @@ void RawImageSource::retinexPrepareCurves(RetinexParams retinexParams, LUTf &cdc } else { CurveFactory::curveDehaContL (retinexcontlutili, retinexParams.cdcurve, cdcurve, 1, lhist16RETI, histLRETI); } + CurveFactory::mapcurve (mapcontlutili, retinexParams.mapcurve, mapcurve, 1, lhist16RETI, histLRETI); retinexParams.getCurves(retinextransmissionCurve); } //void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) -void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) +void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) { MyTime t4, t5; @@ -2273,7 +2274,7 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC } } - MSR(LBuffer, conversionBuffer[2], conversionBuffer[3], WNew, HNew, deh, dehatransmissionCurve, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); + MSR(LBuffer, conversionBuffer[2], conversionBuffer[3], cdcurve, mapcontlutili, WNew, HNew, deh, dehatransmissionCurve, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); if(useHsl) { if(chutili) { diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index ee89dd079..f9e7e6cf1 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -152,8 +152,8 @@ public: void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse); void demosaic (const RAWParams &raw); // void retinex (RAWParams raw, ColorManagementParams cmp, RetinexParams lcur, LUTf & cdcurve, bool dehacontlutili); - void retinex (ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI); - void retinexPrepareCurves (RetinexParams retinexParams, LUTf &cdcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI); + void retinex (ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI); + void retinexPrepareCurves (RetinexParams retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI); void retinexPrepareBuffers (ColorManagementParams cmp, RetinexParams retinexParams, multi_array2D &conversionBuffer, LUTu &lhist16RETI); void flushRawData (); void flushRGB (); @@ -230,7 +230,7 @@ public: void boxblur2(float** src, float** dst, float** temp, int H, int W, int box ); void boxblur_resamp(float **src, float **dst, float** temp, int H, int W, int box, int samp ); - void MSR(float** luminance, float **originalLuminance, float **exLuminance, int width, int height, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax); + void MSR(float** luminance, float **originalLuminance, float **exLuminance, LUTf & mapcurve, bool &mapcontlutili, int width, int height, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax); // void MSR(LabImage* lab, int width, int height, int skip, RetinexParams deh, const RetinextransmissionCurve & dehatransmissionCurve); //void boxblur_resamp(float **red, float **green, float **blue, int H, int W, float thresh[3], float max[3], diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 30373a35e..83cacfa1a 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -453,10 +453,17 @@ int refreshmap[rtengine::NUMOFEVENTS] = { RETINEX, // EvLhighl DEMOSAIC, // EvLbaselog // DEMOSAIC, // EvLgrbl - DEMOSAIC, // EvRetinexlhcurve - RETINEX, // EvLiter - RETINEX, // EvLgrad - RETINEX // EvLgrads + DEMOSAIC, // EvRetinexlhcurve + RETINEX, // EvLiter + RETINEX, // EvLgrad + RETINEX, // EvLgrads + RETINEX, //EvLhighlights + RETINEX, //EvLh_tonalwidth + RETINEX, //EvLshadows + RETINEX, //EvLs_tonalwidth + RETINEX, //EvLradius + RETINEX, //EvmapMethod + RETINEX //EvRetinexmapcurve }; diff --git a/rtengine/shmap.cc b/rtengine/shmap.cc index 34fadd5e7..f1539171d 100644 --- a/rtengine/shmap.cc +++ b/rtengine/shmap.cc @@ -64,6 +64,20 @@ void SHMap::fillLuminance( Imagefloat * img, float **luminance, double lumi[3] ) } +void SHMap::fillLuminanceL( float ** L, float **luminance) // fill with luminance +{ + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int i = 0; i < H; i++) + for (int j = 0; j < W; j++) { + luminance[i][j] = std::max(L[i][j], 0.f) ;//we can put here some enhancements Gamma, compression data,... + } + +} + void SHMap::update (Imagefloat* img, double radius, double lumi[3], bool hq, int skip) { @@ -210,6 +224,154 @@ void SHMap::update (Imagefloat* img, double radius, double lumi[3], bool hq, int } +void SHMap::updateL (float** L, double radius, bool hq, int skip) +{ + + if (!hq) { + fillLuminanceL( L, map); +#ifdef _OPENMP + #pragma omp parallel +#endif + { + gaussianBlur (map, map, W, H, radius); + } + } + + else + + { + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //experimental dirpyr shmap + + float thresh = (100.f * radius); //1000; + + // set up range function + // calculate size of Lookup table. That's possible because from a value k for all i>=k rangefn[i] will be exp(-10) + // So we use this fact and the automatic clip of lut to reduce the size of lut and the number of calculations to fill the lut + // In past this lut had only integer precision with rangefn[i] = 0 for all i>=k + // We set the last element to a small epsilon 1e-15 instead of zero to avoid divisions by zero + const int lutSize = thresh * sqrtf(10.f) + 1; + thresh *= thresh; + LUTf rangefn(lutSize); + + for (int i = 0; i < lutSize - 1; i++) { + rangefn[i] = xexpf(-min(10.f, (static_cast(i) * i) / thresh )); //*intfactor; + } + + rangefn[lutSize - 1] = 1e-15f; + + // We need one temporary buffer + float ** buffer = allocArray (W, H); + + // the final result has to be in map + // for an even number of levels that means: map => buffer, buffer => map + // for an odd number of levels that means: buffer => map, map => buffer, buffer => map + // so let's calculate the number of levels first + // There are at least two levels + int numLevels = 2; + int scale = 2; + + while (skip * scale < 16) { + scale *= 2; + numLevels++; + } + //printf("numlev=%d\n",numLevels); + float ** dirpyrlo[2]; + + if(numLevels & 1) { // odd number of levels, start with buffer + dirpyrlo[0] = buffer; + dirpyrlo[1] = map; + } else { // even number of levels, start with map + dirpyrlo[0] = map; + dirpyrlo[1] = buffer; + } + + fillLuminanceL( L, dirpyrlo[0]); + + scale = 1; + int level = 0; + int indx = 0; + dirpyr_shmap(dirpyrlo[indx], dirpyrlo[1 - indx], W, H, rangefn, level, scale ); + scale *= 2; + level ++; + indx = 1 - indx; + + while (skip * scale < 16) { + dirpyr_shmap(dirpyrlo[indx], dirpyrlo[1 - indx], W, H, rangefn, level, scale ); + scale *= 2; + level ++; + indx = 1 - indx; + } + + dirpyr_shmap(dirpyrlo[indx], dirpyrlo[1 - indx], W, H, rangefn, level, scale ); + + freeArray(buffer, H); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + /* + // anti-alias filtering the result + #ifdef _OPENMP + #pragma omp for + #endif + for (int i=0; i0 && j>0 && i _max_f) { + _max_f = _val; + } + + _avg += _val; + } + +#ifdef _OPENMP + #pragma omp critical +#endif + { + if(_min_f < min_f ) { + min_f = _min_f; + } + + if(_max_f > max_f ) { + max_f = _max_f; + } + } + } + _avg /= ((H) * (W)); + avg = _avg; + +} + + void SHMap::forceStat (float max_, float min_, float avg_) { diff --git a/rtengine/shmap.h b/rtengine/shmap.h index 3d5609f48..97a394927 100644 --- a/rtengine/shmap.h +++ b/rtengine/shmap.h @@ -36,6 +36,7 @@ public: ~SHMap (); void update (Imagefloat* img, double radius, double lumi[3], bool hq, int skip); + void updateL (float** L, double radius, bool hq, int skip); void forceStat (float max_, float min_, float avg_); private: @@ -43,6 +44,7 @@ private: bool multiThread; void fillLuminance( Imagefloat * img, float **luminance, double lumi[3] ); + void fillLuminanceL( float ** L, float **luminance ); void dirpyr_shmap(float ** data_fine, float ** data_coarse, int width, int height, LUTf & rangefn, int level, int scale); }; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 91b7df178..1836c5446 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -118,16 +118,18 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p if(params.retinex.enabled) { //enabled Retinex LUTf cdcurve (65536, 0); + LUTf mapcurve (65536, 0); LUTu dummy; RetinextransmissionCurve dehatransmissionCurve; bool dehacontlutili = false; + bool mapcontlutili = false; bool useHsl = false; // multi_array2D conversionBuffer(1, 1); multi_array2D conversionBuffer(1, 1); imgsrc->retinexPrepareBuffers(params.icm, params.retinex, conversionBuffer, dummy); - imgsrc->retinexPrepareCurves(params.retinex, cdcurve, dehatransmissionCurve, dehacontlutili, useHsl, dummy, dummy ); + imgsrc->retinexPrepareCurves(params.retinex, cdcurve, mapcurve, dehatransmissionCurve, dehacontlutili, mapcontlutili, useHsl, dummy, dummy ); float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax; - imgsrc->retinex( params.icm, params.retinex, params.toneCurve, cdcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, dummy); + imgsrc->retinex( params.icm, params.retinex, params.toneCurve, mapcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, mapcontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, dummy); } if (pl) { diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 2efed572e..5178f3b8a 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -50,9 +50,11 @@ void ParamsEdited::set (bool v) toneCurve.hrenabled = v; toneCurve.method = v; retinex.cdcurve = v; + retinex.mapcurve = v; retinex.cdHcurve = v; retinex.lhcurve = v; retinex.retinexMethod = v; + retinex.mapMethod = v; retinex.retinexcolorspace = v; retinex.gammaretinex = v; retinex.enabled = v; @@ -73,6 +75,12 @@ void ParamsEdited::set (bool v) // retinex.grbl = v; retinex.medianmap = v; retinex.transmissionCurve = v; + retinex.highlights = v; + retinex.htonalwidth = v; + retinex.shadows = v; + retinex.stonalwidth = v; + retinex.radius = v; + retinex.retinex = v; labCurve.lcurve = v; labCurve.acurve = v; @@ -530,10 +538,12 @@ void ParamsEdited::initFrom (const std::vector toneCurve.hrenabled = toneCurve.hrenabled && p.toneCurve.hrenabled == other.toneCurve.hrenabled; toneCurve.method = toneCurve.method && p.toneCurve.method == other.toneCurve.method; retinex.cdcurve = retinex.cdcurve && p.retinex.cdcurve == other.retinex.cdcurve; + retinex.mapcurve = retinex.mapcurve && p.retinex.mapcurve == other.retinex.mapcurve; retinex.cdHcurve = retinex.cdHcurve && p.retinex.cdHcurve == other.retinex.cdHcurve; retinex.lhcurve = retinex.lhcurve && p.retinex.lhcurve == other.retinex.lhcurve; retinex.transmissionCurve = retinex.transmissionCurve && p.retinex.transmissionCurve == other.retinex.transmissionCurve; retinex.retinexMethod = retinex.retinexMethod && p.retinex.retinexMethod == other.retinex.retinexMethod; + retinex.mapMethod = retinex.mapMethod && p.retinex.mapMethod == other.retinex.mapMethod; retinex.retinexcolorspace = retinex.retinexcolorspace && p.retinex.retinexcolorspace == other.retinex.retinexcolorspace; retinex.gammaretinex = retinex.gammaretinex && p.retinex.gammaretinex == other.retinex.gammaretinex; retinex.str = retinex.str && p.retinex.str == other.retinex.str; @@ -552,6 +562,12 @@ void ParamsEdited::initFrom (const std::vector retinex.baselog = retinex.baselog && p.retinex.baselog == other.retinex.baselog; // retinex.grbl = retinex.grbl && p.retinex.grbl == other.retinex.grbl; retinex.medianmap = retinex.medianmap && p.retinex.medianmap == other.retinex.medianmap; + retinex.highlights = retinex.highlights && p.retinex.highlights == other.retinex.highlights; + retinex.htonalwidth = retinex.htonalwidth && p.retinex.htonalwidth == other.retinex.htonalwidth; + retinex.shadows = retinex.shadows && p.retinex.shadows == other.retinex.shadows; + retinex.stonalwidth = retinex.stonalwidth && p.retinex.stonalwidth == other.retinex.stonalwidth; + retinex.radius = retinex.radius && p.retinex.radius == other.retinex.radius; + retinex.enabled = retinex.enabled && p.retinex.enabled == other.retinex.enabled; labCurve.lcurve = labCurve.lcurve && p.labCurve.lcurve == other.labCurve.lcurve; labCurve.acurve = labCurve.acurve && p.labCurve.acurve == other.labCurve.acurve; @@ -1052,6 +1068,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.retinex.cdcurve = mods.retinex.cdcurve; } + if (retinex.mapcurve) { + toEdit.retinex.mapcurve = mods.retinex.mapcurve; + } + if (retinex.cdHcurve) { toEdit.retinex.cdHcurve = mods.retinex.cdHcurve; } @@ -1068,6 +1088,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.retinex.retinexMethod = mods.retinex.retinexMethod; } + if (retinex.mapMethod) { + toEdit.retinex.mapMethod = mods.retinex.mapMethod; + } + if (retinex.retinexcolorspace) { toEdit.retinex.retinexcolorspace = mods.retinex.retinexcolorspace; } @@ -1144,6 +1168,28 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.retinex.vart = dontforceSet && options.baBehav[ADDSET_RETI_VART] ? toEdit.retinex.vart + mods.retinex.vart : mods.retinex.vart; } + if (retinex.highlights) { + toEdit.retinex.highlights = mods.retinex.highlights; + } + + if (retinex.htonalwidth) { + toEdit.retinex.htonalwidth = mods.retinex.htonalwidth; + } + + if (retinex.shadows) { + toEdit.retinex.shadows = mods.retinex.shadows; + + } + + if (retinex.stonalwidth) { + toEdit.retinex.stonalwidth = mods.retinex.stonalwidth; + } + + if (retinex.radius) { + toEdit.retinex.radius = mods.retinex.radius; + } + + if (labCurve.lcurve) { toEdit.labCurve.lcurve = mods.labCurve.lcurve; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index f174c8d52..ba53ee5ea 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -70,6 +70,7 @@ public: bool gain; bool offs; bool retinexMethod; + bool mapMethod; bool retinexcolorspace; bool gammaretinex; bool vart; @@ -80,11 +81,18 @@ public: bool method; bool transmissionCurve; bool cdcurve; + bool mapcurve; bool cdHcurve; bool lhcurve; bool retinex; bool medianmap; bool isUnchanged() const; + bool highlights; + bool htonalwidth; + bool shadows; + bool stonalwidth; + bool radius; + }; diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index 099ee7310..2ede52af6 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -83,6 +83,17 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), curveEditorGDH->curveListComplete(); + curveEditormap = new CurveEditorGroup (options.lastRetinexDir, M("TP_RETINEX_CONTEDIT_MAP")); + curveEditormap->setCurveListener (this); + mapshape = static_cast(curveEditormap->addCurve(CT_Diagonal, M("TP_RETINEX_CURVEEDITOR_MAP"))); + mapshape->setTooltip(M("TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP")); + std::vector milestones222; + milestones222.push_back( GradientMilestone(0., 0., 0., 0.) ); + milestones222.push_back( GradientMilestone(1., 1., 1., 1.) ); + mapshape->setBottomBarBgGradient(milestones222); + mapshape->setLeftBarBgGradient(milestones222); + + curveEditormap->curveListComplete(); // Transmission map curve transmissionCurveEditorG = new CurveEditorGroup (options.lastRetinexDir, M("TP_RETINEX_TRANSMISSION")); @@ -163,6 +174,28 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), limd->set_tooltip_markup (M("TP_RETINEX_THRESHOLD_TOOLTIP")); baselog->set_tooltip_markup (M("TP_RETINEX_BASELOG_TOOLTIP")); + + mapbox = Gtk::manage (new Gtk::HBox ()); + labmap = Gtk::manage (new Gtk::Label (M("TP_RETINEX_MAP") + ":")); + mapbox->pack_start (*labmap, Gtk::PACK_SHRINK, 1); + + mapMethod = Gtk::manage (new MyComboBoxText ()); + mapMethod->append_text (M("TP_RETINEX_MAP_NONE")); + mapMethod->append_text (M("TP_RETINEX_MAP_CURV")); + mapMethod->append_text (M("TP_RETINEX_MAP_GAUS")); + mapMethod->append_text (M("TP_RETINEX_MAP_MAPP")); + mapMethod->append_text (M("TP_RETINEX_MAP_MAPT")); + mapMethod->set_active(0); + mapMethodConn = mapMethod->signal_changed().connect ( sigc::mem_fun(*this, &Retinex::mapMethodChanged) ); + mapMethod->set_tooltip_markup (M("TP_RETINEX_MAP_METHOD_TOOLTIP")); + + highlights = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_HIGHLIGHTS"), 0, 100, 1, 0)); + h_tonalwidth = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_HLTONALW"), 10, 100, 1, 80)); + shadows = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_SHADOWS"), 0, 100, 1, 0)); + s_tonalwidth = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_SHTONALW"), 10, 100, 1, 80)); + radius = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_RADIUS"), 5, 100, 1, 40)); + + curveEditorGH = new CurveEditorGroup (options.lastRetinexDir, M("TP_RETINEX_CONTEDIT_LH")); curveEditorGH->setCurveListener (this); @@ -241,6 +274,24 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), settingsVBox->pack_start (*limd); limd->show (); + settingsVBox->pack_start (*Gtk::manage (new Gtk::HSeparator())); + + mapbox->pack_start(*mapMethod); + settingsVBox->pack_start(*mapbox); + + settingsVBox->pack_start (*curveEditormap, Gtk::PACK_SHRINK, 4); + curveEditormap->show(); + + settingsVBox->pack_start (*highlights); + highlights->show(); + settingsVBox->pack_start (*h_tonalwidth); + h_tonalwidth->show(); + settingsVBox->pack_start (*shadows); + shadows->show(); + settingsVBox->pack_start (*s_tonalwidth); + s_tonalwidth->show(); + settingsVBox->pack_start (*radius); + radius->show(); // settingsVBox->pack_start (*highl); // highl->show (); @@ -249,6 +300,7 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), // settingsVBox->pack_start (*grbl); // grbl->show (); + settingsVBox->pack_start (*Gtk::manage (new Gtk::HSeparator())); settingsVBox->pack_start( *transmissionCurveEditorG, Gtk::PACK_SHRINK, 2); transmissionCurveEditorG->show(); @@ -354,6 +406,32 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), baselog->delay = 200; } + + radius->setAdjusterListener (this); + if (radius->delay < 200) { + radius->delay = 200; + } + + highlights->setAdjusterListener (this); + if (highlights->delay < 200) { + highlights->delay = 200; + } + + h_tonalwidth->setAdjusterListener (this); + if (h_tonalwidth->delay < 200) { + h_tonalwidth->delay = 200; + } + + shadows->setAdjusterListener (this); + if (shadows->delay < 200) { + shadows->delay = 200; + } + + s_tonalwidth->setAdjusterListener (this); + if (s_tonalwidth->delay < 200) { + s_tonalwidth->delay = 200; + } + /* grbl->setAdjusterListener (this); if (grbl->delay < 200) { @@ -378,6 +456,7 @@ Retinex::~Retinex() delete curveEditorGDH; delete transmissionCurveEditorG; delete curveEditorGH; + delete curveEditormap; } void Retinex::neutral_pressed () @@ -396,10 +475,20 @@ void Retinex::neutral_pressed () baselog->resetValue(false); gam->resetValue(false); slope->resetValue(false); + highlights->resetValue(false); + h_tonalwidth->resetValue(false); + shadows->resetValue(false); + s_tonalwidth->resetValue(false); + radius->resetValue(false); + mapMethod->set_active(0); + retinexMethod->set_active(2); + retinexcolorspace->set_active(0); + gammaretinex->set_active(0); transmissionShape->reset(); cdshape->reset(); cdshapeH->reset(); lhshape->reset(); + mapshape->reset(); } void Retinex::foldAllButMe (GdkEventButton* event, MyExpander *expander) @@ -509,6 +598,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) retinexMethodConn.block(true); retinexColorSpaceConn.block(true); gammaretinexConn.block(true); + mapMethodConn.block(true); if (pedited) { @@ -528,12 +618,21 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) // grbl->setEditedState (pedited->retinex.grbl ? Edited : UnEdited); set_inconsistent (multiImage && !pedited->retinex.enabled); medianmap->set_inconsistent (!pedited->retinex.medianmap); + radius->setEditedState (pedited->retinex.radius ? Edited : UnEdited); + highlights->setEditedState (pedited->retinex.highlights ? Edited : UnEdited); + h_tonalwidth->setEditedState (pedited->retinex.htonalwidth ? Edited : UnEdited); + shadows->setEditedState (pedited->retinex.shadows ? Edited : UnEdited); + s_tonalwidth->setEditedState (pedited->retinex.stonalwidth ? Edited : UnEdited); if (!pedited->retinex.retinexMethod) { retinexMethod->set_active_text(M("GENERAL_UNCHANGED")); } + if (!pedited->retinex.mapMethod) { + mapMethod->set_active_text(M("GENERAL_UNCHANGED")); + } + if (!pedited->retinex.retinexcolorspace) { retinexcolorspace->set_active_text(M("GENERAL_UNCHANGED")); } @@ -546,6 +645,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) cdshapeH->setUnChanged (!pedited->retinex.cdHcurve); transmissionShape->setUnChanged (!pedited->retinex.transmissionCurve); lhshape->setUnChanged (!pedited->retinex.lhcurve); + mapshape->setUnChanged (!pedited->retinex.mapcurve); } @@ -563,6 +663,13 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) slope->setValue (pp->retinex.slope); highl->setValue (pp->retinex.highl); baselog->setValue (pp->retinex.baselog); + + radius->setValue (pp->retinex.radius); + highlights->setValue (pp->retinex.highlights); + h_tonalwidth->setValue (pp->retinex.htonalwidth); + shadows->setValue (pp->retinex.shadows); + s_tonalwidth->setValue (pp->retinex.stonalwidth); + // grbl->setValue (pp->retinex.grbl); if(pp->retinex.iter == 1) { grad->set_sensitive(false); @@ -593,6 +700,19 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) // retinexMethod->set_active (4); } + if (pp->retinex.mapMethod == "none") { + mapMethod->set_active (0); + } else if (pp->retinex.mapMethod == "curv") { + mapMethod->set_active (1); + } else if (pp->retinex.mapMethod == "gaus") { + mapMethod->set_active (2); + } else if (pp->retinex.mapMethod == "map") { + mapMethod->set_active (3); + } else if (pp->retinex.mapMethod == "mapT") { + mapMethod->set_active (4); + } + + if (pp->retinex.retinexcolorspace == "Lab") { retinexcolorspace->set_active (0); } else if (pp->retinex.retinexcolorspace == "HSLLOG") { @@ -616,6 +736,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) retinexMethodChanged (); retinexColorSpaceChanged(); gammaretinexChanged(); + mapMethodChanged (); medianmapConn.block(true); medianmapChanged (); @@ -624,10 +745,12 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) cdshape->setCurve (pp->retinex.cdcurve); cdshapeH->setCurve (pp->retinex.cdHcurve); lhshape->setCurve (pp->retinex.lhcurve); + mapshape->setCurve (pp->retinex.mapcurve); retinexMethodConn.block(false); retinexColorSpaceConn.block(false); gammaretinexConn.block(false); + mapMethodConn.block(false); transmissionShape->setCurve (pp->retinex.transmissionCurve); @@ -657,14 +780,22 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited) pp->retinex.cdcurve = cdshape->getCurve (); pp->retinex.lhcurve = lhshape->getCurve (); pp->retinex.cdHcurve = cdshapeH->getCurve (); + pp->retinex.mapcurve = mapshape->getCurve (); pp->retinex.transmissionCurve = transmissionShape->getCurve (); pp->retinex.enabled = getEnabled(); pp->retinex.medianmap = medianmap->get_active(); + pp->retinex.radius = (int)radius->getValue (); + pp->retinex.highlights = (int)highlights->getValue (); + pp->retinex.htonalwidth = (int)h_tonalwidth->getValue (); + pp->retinex.shadows = (int)shadows->getValue (); + pp->retinex.stonalwidth = (int)s_tonalwidth->getValue (); + if (pedited) { pedited->retinex.retinexMethod = retinexMethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->retinex.retinexcolorspace = retinexcolorspace->get_active_text() != M("GENERAL_UNCHANGED"); pedited->retinex.gammaretinex = gammaretinex->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->retinex.mapMethod = mapMethod->get_active_text() != M("GENERAL_UNCHANGED"); //%%%%%%%%%%%%%%%%%%%%%% pedited->retinex.str = str->getEditedState (); @@ -685,10 +816,17 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited) pedited->retinex.cdcurve = !cdshape->isUnChanged (); pedited->retinex.cdHcurve = !cdshapeH->isUnChanged (); pedited->retinex.transmissionCurve = !transmissionShape->isUnChanged (); + pedited->retinex.mapcurve = !mapshape->isUnChanged (); pedited->retinex.enabled = !get_inconsistent(); pedited->retinex.medianmap = !medianmap->get_inconsistent(); pedited->retinex.lhcurve = !lhshape->isUnChanged (); + pedited->retinex.radius = radius->getEditedState (); + pedited->retinex.highlights = highlights->getEditedState (); + pedited->retinex.htonalwidth = h_tonalwidth->getEditedState (); + pedited->retinex.shadows = shadows->getEditedState (); + pedited->retinex.stonalwidth = s_tonalwidth->getEditedState (); + } if (retinexMethod->get_active_row_number() == 0) { @@ -703,6 +841,18 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited) // pp->retinex.retinexMethod = "highliplus"; } + if (mapMethod->get_active_row_number() == 0) { + pp->retinex.mapMethod = "none"; + } else if (mapMethod->get_active_row_number() == 1) { + pp->retinex.mapMethod = "curv"; + } else if (mapMethod->get_active_row_number() == 2) { + pp->retinex.mapMethod = "gaus"; + } else if (mapMethod->get_active_row_number() == 3) { + pp->retinex.mapMethod = "map"; + } else if (mapMethod->get_active_row_number() == 4) { + pp->retinex.mapMethod = "mapT"; + } + if (retinexcolorspace->get_active_row_number() == 0) { pp->retinex.retinexcolorspace = "Lab"; } else if (retinexcolorspace->get_active_row_number() == 1) { @@ -739,6 +889,40 @@ void Retinex::retinexMethodChanged() } } + + +void Retinex::mapMethodChanged() +{ + + if(mapMethod->get_active_row_number() >= 1) { + curveEditormap->show(); + highlights->show(); + h_tonalwidth->show(); + shadows->show(); + s_tonalwidth->show(); + radius->show(); + /* } else if(mapMethod->get_active_row_number() == 1) { + curveEditormap->show(); + highlights->hide(); + h_tonalwidth->hide(); + shadows->hide(); + s_tonalwidth->hide(); + radius->hide();*/ + } else { + curveEditormap->hide(); + highlights->hide(); + h_tonalwidth->hide(); + shadows->hide(); + s_tonalwidth->hide(); + radius->hide(); + + } + + if (listener) { + listener->panelChanged (EvmapMethod, mapMethod->get_active_text ()); + } +} + void Retinex::ColorSpaceUpdateUI () { if (!batchMode) { @@ -838,6 +1022,12 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi gam->setDefault (defParams->retinex.gam); slope->setDefault (defParams->retinex.slope); + radius->setDefault (defParams->retinex.radius); + highlights->setDefault (defParams->retinex.highlights); + h_tonalwidth->setDefault (defParams->retinex.htonalwidth); + shadows->setDefault (defParams->retinex.shadows); + s_tonalwidth->setDefault (defParams->retinex.stonalwidth); + if (pedited) { neigh->setDefaultEditedState (pedited->retinex.neigh ? Edited : UnEdited); gain->setDefaultEditedState (pedited->retinex.gain ? Edited : UnEdited); @@ -855,6 +1045,12 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi gam->setDefaultEditedState (pedited->retinex.gam ? Edited : UnEdited); slope->setDefaultEditedState (pedited->retinex.slope ? Edited : UnEdited); + radius->setDefaultEditedState (pedited->retinex.radius ? Edited : UnEdited); + highlights->setDefaultEditedState (pedited->retinex.highlights ? Edited : UnEdited); + h_tonalwidth->setDefaultEditedState (pedited->retinex.htonalwidth ? Edited : UnEdited); + shadows->setDefaultEditedState (pedited->retinex.shadows ? Edited : UnEdited); + s_tonalwidth->setDefaultEditedState (pedited->retinex.stonalwidth ? Edited : UnEdited); + } else { neigh->setDefaultEditedState (Irrelevant); gain->setDefaultEditedState (Irrelevant); @@ -871,6 +1067,13 @@ void Retinex::setDefaults (const ProcParams* defParams, const ParamsEdited* pedi grads->setDefaultEditedState (Irrelevant); gam->setDefaultEditedState (Irrelevant); slope->setDefaultEditedState (Irrelevant); + + radius->setDefaultEditedState (Irrelevant); + highlights->setDefaultEditedState (Irrelevant); + h_tonalwidth->setDefaultEditedState (Irrelevant); + shadows->setDefaultEditedState (Irrelevant); + s_tonalwidth->setDefaultEditedState (Irrelevant); + } } @@ -935,8 +1138,20 @@ void Retinex::adjusterChanged (Adjuster* a, double newval) listener->panelChanged (EvLgam, gam->getTextValue()); } else if (a == slope) { listener->panelChanged (EvLslope, slope->getTextValue()); + } else if (a == highlights) { + listener->panelChanged (EvLhighlights, highlights->getTextValue()); + } else if (a == h_tonalwidth) { + listener->panelChanged (EvLh_tonalwidth, h_tonalwidth->getTextValue()); + } else if (a == shadows) { + listener->panelChanged (EvLshadows, shadows->getTextValue()); + } else if (a == s_tonalwidth) { + listener->panelChanged (EvLs_tonalwidth, s_tonalwidth->getTextValue()); + } else if (a == radius) { + listener->panelChanged (EvLradius, radius->getTextValue()); + } + } @@ -947,6 +1162,7 @@ void Retinex::autoOpenCurve () cdshapeH->openIfNonlinear(); transmissionShape->openIfNonlinear(); lhshape->openIfNonlinear(); + mapshape->openIfNonlinear(); } @@ -962,6 +1178,8 @@ void Retinex::curveChanged (CurveEditor* ce) listener->panelChanged (EvRetinextransmission, M("HISTORY_CUSTOMCURVE")); } else if (ce == lhshape) { listener->panelChanged (EvRetinexlhcurve, M("HISTORY_CUSTOMCURVE")); + } else if (ce == mapshape) { + listener->panelChanged (EvRetinexmapcurve, M("HISTORY_CUSTOMCURVE")); } } } @@ -998,6 +1216,8 @@ void Retinex::trimValues (rtengine::procparams::ProcParams* pp) // grbl->trimValue(pp->retinex.grbl); gam->trimValue(pp->retinex.gam); slope->trimValue(pp->retinex.slope); + highlights->trimValue(pp->retinex.highlights); + shadows->trimValue(pp->retinex.shadows); } void Retinex::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve,/* LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma, LUTu & histLRETI) @@ -1070,11 +1290,19 @@ void Retinex::setBatchMode (bool batchMode) limd->showEditedCB (); highl->showEditedCB (); baselog->showEditedCB (); + + radius->showEditedCB (); + highlights->showEditedCB (); + h_tonalwidth->showEditedCB (); + shadows->showEditedCB (); + s_tonalwidth->showEditedCB (); + // grbl->showEditedCB (); curveEditorGD->setBatchMode (batchMode); curveEditorGDH->setBatchMode (batchMode); transmissionCurveEditorG->setBatchMode (batchMode); curveEditorGH->setBatchMode (batchMode); + curveEditormap->setBatchMode (batchMode); } diff --git a/rtgui/retinex.h b/rtgui/retinex.h index e014bed5d..ac55fea99 100644 --- a/rtgui/retinex.h +++ b/rtgui/retinex.h @@ -22,6 +22,7 @@ protected: CurveEditorGroup* curveEditorGD; CurveEditorGroup* curveEditorGDH; CurveEditorGroup* curveEditorGH; + CurveEditorGroup* curveEditormap; Adjuster* str; Adjuster* scal; Adjuster* grad; @@ -37,10 +38,19 @@ protected: Adjuster* grbl; Adjuster* gam; Adjuster* slope; + Adjuster* highlights; + Adjuster* h_tonalwidth; + Adjuster* shadows; + Adjuster* s_tonalwidth; + Adjuster* radius; + MyExpander* expsettings; Gtk::Label* labmdh; Gtk::HBox* dhbox; + Gtk::HBox* mapbox; + Gtk::Label* labmap; + Gtk::Label* labgam; Gtk::HBox* gambox; Gtk::Button* neutral; @@ -49,6 +59,7 @@ protected: MyComboBoxText* retinexMethod; MyComboBoxText* retinexcolorspace; MyComboBoxText* gammaretinex; + MyComboBoxText* mapMethod; Gtk::CheckButton* medianmap; double nextmin; double nextmax; @@ -65,8 +76,9 @@ protected: DiagonalCurveEditor* cdshape; DiagonalCurveEditor* cdshapeH; + DiagonalCurveEditor* mapshape; CurveEditorGroup* transmissionCurveEditorG; - sigc::connection retinexMethodConn, neutralconn; + sigc::connection retinexMethodConn, neutralconn, mapMethodConn; sigc::connection retinexColorSpaceConn; sigc::connection gammaretinexConn; FlatCurveEditor* transmissionShape; @@ -95,6 +107,7 @@ public: void enabledChanged (); void curveChanged (CurveEditor* ce); void retinexMethodChanged(); + void mapMethodChanged(); void retinexColorSpaceChanged(); void gammaretinexChanged(); void ColorSpaceUpdateUI(); From 6b52742d84535dba497ea4ebc7e037fdf5f25cc6 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Thu, 12 Nov 2015 22:17:28 +0100 Subject: [PATCH 07/61] Fix the number of files displayed in the file browser tab title being wrong after removal of a file by an external actor. --- rtgui/filecatalog.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index d40b7d720..c7d01edc0 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -1721,6 +1721,11 @@ void FileCatalog::reparseDirectory () for (size_t i = 0; i < fileNamesToDel.size(); i++) { delete fileBrowser->delEntry (fileNamesToDel[i]); cacheMgr->deleteEntry (fileNamesToDel[i]); + previewsLoaded--; + } + + if (!fileNamesToDel.empty ()) { + _refreshProgressBar(); } // check if a new file has been added From f74e4b0dd20aafce52a208434570bece705687c1 Mon Sep 17 00:00:00 2001 From: Desmis Date: Fri, 13 Nov 2015 08:45:24 +0100 Subject: [PATCH 08/61] Fixed numerous bug and add Preview for mask and transmission --- rtdata/languages/default | 6 +++ rtengine/imagesource.h | 2 +- rtengine/improccoordinator.cc | 2 +- rtengine/ipretinex.cc | 33 ++++++++++--- rtengine/procevents.h | 2 + rtengine/procparams.cc | 15 ++++++ rtengine/procparams.h | 1 + rtengine/rawimagesource.cc | 4 +- rtengine/rawimagesource.h | 2 +- rtengine/refreshmap.cc | 7 +-- rtengine/shmap.cc | 17 ++++--- rtengine/simpleprocess.cc | 2 +- rtgui/paramsedited.cc | 6 +++ rtgui/paramsedited.h | 1 + rtgui/retinex.cc | 91 ++++++++++++++++++++++++++++++++--- rtgui/retinex.h | 6 ++- 16 files changed, 165 insertions(+), 32 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 97b327ef6..4ec24b42c 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -666,6 +666,7 @@ HISTORY_MSG_433;Retinex - Mask TW shadows HISTORY_MSG_434;Retinex - Mask radius HISTORY_MSG_435;Retinex - Mask method HISTORY_MSG_436;Retinex - Mask curve +HISTORY_MSG_437;Retinex - Preview HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOTS;Snapshots @@ -1707,6 +1708,11 @@ TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbsciss TP_RETINEX_UNIFORM;Uniform TP_RETINEX_VARIANCE;Variance TP_RETINEX_VARIANCE_TOOLTIP;Low variance increase local contrast and saturation, but can lead to artifacts. +TP_RETINEX_VIEW;Preview +TP_RETINEX_VIEW_NONE;Standard +TP_RETINEX_VIEW_MASK;Mask +TP_RETINEX_VIEW_TRAN;Transmission +TP_RETINEX_VIEW_METHOD_TOOLTIP;Standard - normal display\nMask - display mask\nTransmission - displays the file transmission-map , before any action on contrast and brightness\nAttention, this does not correspond to reality, but a shift to make it visible TP_RGBCURVES_BLUE;B TP_RGBCURVES_CHANNEL;Channel TP_RGBCURVES_GREEN;G diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index eaf9997fa..80fc53f23 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -69,7 +69,7 @@ public: virtual int load (Glib::ustring fname, bool batch = false) = 0; virtual void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse) {}; virtual void demosaic (const RAWParams &raw) {}; - virtual void retinex (ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) {}; + virtual void retinex (ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) {}; virtual void retinexPrepareCurves (RetinexParams retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI) {}; virtual void retinexPrepareBuffers (ColorManagementParams cmp, RetinexParams retinexParams, multi_array2D &conversionBuffer, LUTu &lhist16RETI) {}; virtual void flushRawData () {}; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 479ec1282..dc135c4d5 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -251,7 +251,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) imgsrc->retinexPrepareCurves(params.retinex, cdcurve, mapcurve, dehatransmissionCurve, dehacontlutili, mapcontlutili, useHsl, lhist16RETI, histLRETI); float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax; - imgsrc->retinex( params.icm, params.retinex, params.toneCurve, mapcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, mapcontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, histLRETI);//enabled Retinex + imgsrc->retinex( params.icm, params.retinex, params.toneCurve, cdcurve, mapcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, mapcontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, histLRETI);//enabled Retinex if(dehaListener) { dehaListener->minmaxChanged(maxCD, minCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index d444380ce..839d8646e 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -405,7 +405,12 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e if(deh.mapMethod=="mapT") mapmet=3; if(deh.mapMethod=="curv") mapmet=1; if(deh.mapMethod=="gaus") mapmet=4; + double shradius = (double) deh.radius; + // printf("shrad=%f\n",shradius); + int viewmet=0; + if(deh.viewMethod=="mask") viewmet=1; + if(deh.viewMethod=="tran") viewmet=2; #ifdef _OPENMP #pragma omp parallel for @@ -424,6 +429,13 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e out[i] = &outBuffer[i * W_L]; } + float *tran[H_L] ALIGNED16; + float *tranBuffer = new float[H_L * W_L]; + + for (int i = 0; i < H_L; i++) { + tran[i] = &tranBuffer[i * W_L]; + } + const float logBetaGain = xlogf(16384.f); float pond = logBetaGain / (float) scal; @@ -451,8 +463,8 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e printf(".."); - double shradius = deh.radius; - if(mapmet==4) shradius /= 10.; + if(mapmet==4) shradius /= 1.; + else shradius = 40.; // if(shHighlights > 0 || shShadows > 0) { if(mapmet==3) if(it==1) shmap->updateL (out, shradius, true, 1);//wav Total @@ -488,7 +500,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } // if(shHighlights > 0 || shShadows > 0) { - if((mapmet == 2 && scale >2) || mapmet==3 || mapmet==4) { + if(((mapmet == 2 && scale >2) || mapmet==3 || mapmet==4) && it==1) { #ifdef _OPENMP @@ -545,6 +557,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } } } + printf(".\n"); if(mapmet > 1) { if(shmap) { delete shmap; @@ -553,7 +566,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e shmap = NULL; delete [] buffer; - delete [] outBuffer; +// delete [] outBuffer; delete [] srcBuffer; mean = 0.f; @@ -598,6 +611,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } luminance[i][j] *= (-1.f + 4.f * dehatransmissionCurve[absciss]); //new transmission + tran[i][j]=luminance[i][j]; } } @@ -713,8 +727,10 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } } - // if(exLuminance[i][j] > 65535.f*hig && higplus) str *= hig; - luminance[i][j] = clipretinex( cd, 0.f, 32768.f ) * str + (1.f - str) * originalLuminance[i][j]; + if(exLuminance[i][j] > 65535.f*hig && higplus) str *= hig; + if(viewmet==0) luminance[i][j]=clipretinex( cd, 0.f, 32768.f ) * str + (1.f - str) * originalLuminance[i][j]; + if(viewmet==1) luminance[i][j] = out[i][j]; + if(viewmet==2) luminance[i][j] = 1000.f+ tran[i][j]*700.f;//arbitrary values to help display log values which are between -20 to + 30 - usage values -4 + 5 } #ifdef _OPENMP @@ -726,6 +742,11 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } } + delete [] outBuffer; + outBuffer = NULL; + delete [] tranBuffer; + tranBuffer = NULL; + // printf("cdmin=%f cdmax=%f\n",minCD, maxCD); Tmean = mean; Tsigma = stddv; diff --git a/rtengine/procevents.h b/rtengine/procevents.h index f23d68f2e..d02018d78 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -464,6 +464,8 @@ enum ProcEvent { EvLradius = 433, EvmapMethod = 434, EvRetinexmapcurve = 435, + EvviewMethod = 436, + NUMOFEVENTS }; } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 075067585..7a674e8c3 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -163,6 +163,7 @@ void RetinexParams::setDefaults() // grbl = 50; retinexMethod = "high"; mapMethod = "none"; + viewMethod = "none"; retinexcolorspace = "Lab"; gammaretinex = "none"; medianmap = false; @@ -1526,6 +1527,10 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol keyFile.set_string ("Retinex", "mapMethod", retinex.mapMethod); } + if (!pedited || pedited->retinex.viewMethod) { + keyFile.set_string ("Retinex", "viewMethod", retinex.viewMethod); + } + if (!pedited || pedited->retinex.retinexcolorspace) { keyFile.set_string ("Retinex", "Retinexcolorspace", retinex.retinexcolorspace); } @@ -3864,6 +3869,15 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) } } + if (keyFile.has_key ("Retinex", "viewMethod")) { + retinex.viewMethod = keyFile.get_string ("Retinex", "viewMethod"); + + if (pedited) { + pedited->retinex.viewMethod = true; + } + } + + if (keyFile.has_key ("Retinex", "Retinexcolorspace")) { retinex.retinexcolorspace = keyFile.get_string ("Retinex", "Retinexcolorspace"); @@ -7478,6 +7492,7 @@ bool ProcParams::operator== (const ProcParams& other) && retinex.offs == other.retinex.offs && retinex.retinexMethod == other.retinex.retinexMethod && retinex.mapMethod == other.retinex.mapMethod + && retinex.viewMethod == other.retinex.viewMethod && retinex.retinexcolorspace == other.retinex.retinexcolorspace && retinex.gammaretinex == other.retinex.gammaretinex && retinex.vart == other.retinex.vart diff --git a/rtengine/procparams.h b/rtengine/procparams.h index e2d2539ea..0aa31a9bd 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -294,6 +294,7 @@ public: Glib::ustring retinexcolorspace; Glib::ustring gammaretinex; Glib::ustring mapMethod; + Glib::ustring viewMethod; int vart; int limd; int highl; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 8a4fc3559..c552c64ac 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -2122,7 +2122,7 @@ void RawImageSource::retinexPrepareCurves(RetinexParams retinexParams, LUTf &cdc } //void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) -void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) +void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI) { MyTime t4, t5; @@ -2274,7 +2274,7 @@ void RawImageSource::retinex(ColorManagementParams cmp, RetinexParams deh, ToneC } } - MSR(LBuffer, conversionBuffer[2], conversionBuffer[3], cdcurve, mapcontlutili, WNew, HNew, deh, dehatransmissionCurve, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); + MSR(LBuffer, conversionBuffer[2], conversionBuffer[3], mapcurve, mapcontlutili, WNew, HNew, deh, dehatransmissionCurve, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax); if(useHsl) { if(chutili) { diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index f9e7e6cf1..10057d58a 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -152,7 +152,7 @@ public: void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse); void demosaic (const RAWParams &raw); // void retinex (RAWParams raw, ColorManagementParams cmp, RetinexParams lcur, LUTf & cdcurve, bool dehacontlutili); - void retinex (ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI); + void retinex (ColorManagementParams cmp, RetinexParams deh, ToneCurveParams Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, multi_array2D &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI); void retinexPrepareCurves (RetinexParams retinexParams, LUTf &cdcurve, LUTf &mapcurve, RetinextransmissionCurve &retinextransmissionCurve, bool &retinexcontlutili, bool &mapcontlutili, bool &useHsl, LUTu & lhist16RETI, LUTu & histLRETI); void retinexPrepareBuffers (ColorManagementParams cmp, RetinexParams retinexParams, multi_array2D &conversionBuffer, LUTu &lhist16RETI); void flushRawData (); diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 83cacfa1a..915ed615d 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -440,13 +440,13 @@ int refreshmap[rtengine::NUMOFEVENTS] = { RETINEX, // EvLstr RETINEX, // EvLscal RETINEX, // EvLvart - RETINEX, // EvLCDCurve + DEMOSAIC, // EvLCDCurve RETINEX, // EvRetinextransmission DEMOSAIC, // EvRetinexEnabled RETINEX, // EvRetinexmedianmap RETINEX, // EvLlimd DEMOSAIC, // Evretinexcolorspace - RETINEX, // EvLCDHCurve + DEMOSAIC, // EvLCDHCurve DEMOSAIC, // Evretinexgamma DEMOSAIC, // EvLgam DEMOSAIC, // EvLslope @@ -463,7 +463,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { RETINEX, //EvLs_tonalwidth RETINEX, //EvLradius RETINEX, //EvmapMethod - RETINEX //EvRetinexmapcurve + DEMOSAIC, //EvRetinexmapcurve + DEMOSAIC //EvviewMethod }; diff --git a/rtengine/shmap.cc b/rtengine/shmap.cc index f1539171d..2471b17a4 100644 --- a/rtengine/shmap.cc +++ b/rtengine/shmap.cc @@ -242,23 +242,23 @@ void SHMap::updateL (float** L, double radius, bool hq, int skip) { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //experimental dirpyr shmap - float thresh = (100.f * radius); //1000; - + int levrad = 16; + levrad=2;//for retinex - otherwise levrad = 16 // set up range function // calculate size of Lookup table. That's possible because from a value k for all i>=k rangefn[i] will be exp(-10) // So we use this fact and the automatic clip of lut to reduce the size of lut and the number of calculations to fill the lut // In past this lut had only integer precision with rangefn[i] = 0 for all i>=k // We set the last element to a small epsilon 1e-15 instead of zero to avoid divisions by zero - const int lutSize = thresh * sqrtf(10.f) + 1; + const int lutSize = (int) thresh * sqrtf(10.f) + 1; thresh *= thresh; LUTf rangefn(lutSize); - for (int i = 0; i < lutSize - 1; i++) { rangefn[i] = xexpf(-min(10.f, (static_cast(i) * i) / thresh )); //*intfactor; } rangefn[lutSize - 1] = 1e-15f; + //printf("lut=%d rf5=%f rfm=%f\n thre=%f",lutSize, rangefn[5],rangefn[lutSize-10],thresh ); // We need one temporary buffer float ** buffer = allocArray (W, H); @@ -271,7 +271,7 @@ void SHMap::updateL (float** L, double radius, bool hq, int skip) int numLevels = 2; int scale = 2; - while (skip * scale < 16) { + while (skip * scale < levrad) { scale *= 2; numLevels++; } @@ -296,7 +296,7 @@ void SHMap::updateL (float** L, double radius, bool hq, int skip) level ++; indx = 1 - indx; - while (skip * scale < 16) { + while (skip * scale < levrad) { dirpyr_shmap(dirpyrlo[indx], dirpyrlo[1 - indx], W, H, rangefn, level, scale ); scale *= 2; level ++; @@ -398,7 +398,7 @@ SSEFUNCTION void SHMap::dirpyr_shmap(float ** data_fine, float ** data_coarse, i #endif { #if defined( __SSE2__ ) && defined( __x86_64__ ) - __m128 dirwtv, valv, normv, dftemp1v, dftemp2v; + __m128 dirwtv, valv, normv, dftemp1v, dftemp2v, fg; #endif // __SSE2__ int j; #ifdef _OPENMP @@ -414,6 +414,7 @@ SSEFUNCTION void SHMap::dirpyr_shmap(float ** data_fine, float ** data_coarse, i for(int inbr = max(i - scalewin, i % scale); inbr <= min(i + scalewin, height - 1); inbr += scale) { for (int jnbr = j % scale; jnbr <= j + scalewin; jnbr += scale) { + //printf("dat=%f ",abs(data_fine[inbr][jnbr] - data_fine[i][j])); dirwt = ( rangefn[abs(data_fine[inbr][jnbr] - data_fine[i][j])] ); val += dirwt * data_fine[inbr][jnbr]; norm += dirwt; @@ -504,7 +505,7 @@ SSEFUNCTION void SHMap::dirpyr_shmap(float ** data_fine, float ** data_coarse, i #endif { #if defined( __SSE2__ ) && defined( __x86_64__ ) - __m128 dirwtv, valv, normv, dftemp1v, dftemp2v; + __m128 dirwtv, valv, normv, dftemp1v, dftemp2v, fgg; float domkerv[5][5][4] __attribute__ ((aligned (16))) = {{{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}, {{1, 1, 1, 1}, {2, 2, 2, 2}, {2, 2, 2, 2}, {2, 2, 2, 2}, {1, 1, 1, 1}}, {{1, 1, 1, 1}, {2, 2, 2, 2}, {2, 2, 2, 2}, {2, 2, 2, 2}, {1, 1, 1, 1}}, {{1, 1, 1, 1}, {2, 2, 2, 2}, {2, 2, 2, 2}, {2, 2, 2, 2}, {1, 1, 1, 1}}, {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}}}; #endif // __SSE2__ diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 1836c5446..3e667c129 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -129,7 +129,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p imgsrc->retinexPrepareBuffers(params.icm, params.retinex, conversionBuffer, dummy); imgsrc->retinexPrepareCurves(params.retinex, cdcurve, mapcurve, dehatransmissionCurve, dehacontlutili, mapcontlutili, useHsl, dummy, dummy ); float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax; - imgsrc->retinex( params.icm, params.retinex, params.toneCurve, mapcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, mapcontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, dummy); + imgsrc->retinex( params.icm, params.retinex, params.toneCurve, cdcurve, mapcurve, dehatransmissionCurve, conversionBuffer, dehacontlutili, mapcontlutili, useHsl, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, dummy); } if (pl) { diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 5178f3b8a..35f26c58c 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -55,6 +55,7 @@ void ParamsEdited::set (bool v) retinex.lhcurve = v; retinex.retinexMethod = v; retinex.mapMethod = v; + retinex.viewMethod = v; retinex.retinexcolorspace = v; retinex.gammaretinex = v; retinex.enabled = v; @@ -544,6 +545,7 @@ void ParamsEdited::initFrom (const std::vector retinex.transmissionCurve = retinex.transmissionCurve && p.retinex.transmissionCurve == other.retinex.transmissionCurve; retinex.retinexMethod = retinex.retinexMethod && p.retinex.retinexMethod == other.retinex.retinexMethod; retinex.mapMethod = retinex.mapMethod && p.retinex.mapMethod == other.retinex.mapMethod; + retinex.viewMethod = retinex.viewMethod && p.retinex.viewMethod == other.retinex.viewMethod; retinex.retinexcolorspace = retinex.retinexcolorspace && p.retinex.retinexcolorspace == other.retinex.retinexcolorspace; retinex.gammaretinex = retinex.gammaretinex && p.retinex.gammaretinex == other.retinex.gammaretinex; retinex.str = retinex.str && p.retinex.str == other.retinex.str; @@ -1092,6 +1094,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.retinex.mapMethod = mods.retinex.mapMethod; } + if (retinex.viewMethod) { + toEdit.retinex.viewMethod = mods.retinex.viewMethod; + } + if (retinex.retinexcolorspace) { toEdit.retinex.retinexcolorspace = mods.retinex.retinexcolorspace; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index ba53ee5ea..60fbbdb81 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -71,6 +71,7 @@ public: bool offs; bool retinexMethod; bool mapMethod; + bool viewMethod; bool retinexcolorspace; bool gammaretinex; bool vart; diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index 2ede52af6..5e4a9f636 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -195,6 +195,17 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), s_tonalwidth = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_SHTONALW"), 10, 100, 1, 80)); radius = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_RADIUS"), 5, 100, 1, 40)); + viewbox = Gtk::manage (new Gtk::HBox ()); + labview = Gtk::manage (new Gtk::Label (M("TP_RETINEX_VIEW") + ":")); + viewbox->pack_start (*labview, Gtk::PACK_SHRINK, 1); + + viewMethod = Gtk::manage (new MyComboBoxText ()); + viewMethod->append_text (M("TP_RETINEX_VIEW_NONE")); + viewMethod->append_text (M("TP_RETINEX_VIEW_MASK")); + viewMethod->append_text (M("TP_RETINEX_VIEW_TRAN")); + viewMethod->set_active(0); + viewMethodConn = viewMethod->signal_changed().connect ( sigc::mem_fun(*this, &Retinex::viewMethodChanged) ); + viewMethod->set_tooltip_markup (M("TP_RETINEX_VIEW_METHOD_TOOLTIP")); curveEditorGH = new CurveEditorGroup (options.lastRetinexDir, M("TP_RETINEX_CONTEDIT_LH")); curveEditorGH->setCurveListener (this); @@ -292,6 +303,12 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), s_tonalwidth->show(); settingsVBox->pack_start (*radius); radius->show(); + + viewbox->pack_start(*viewMethod); + settingsVBox->pack_start(*viewbox); + + //settingsVBox->pack_start (*viewMethod); + // settingsVBox->pack_start (*highl); // highl->show (); @@ -481,6 +498,7 @@ void Retinex::neutral_pressed () s_tonalwidth->resetValue(false); radius->resetValue(false); mapMethod->set_active(0); + viewMethod->set_active(0); retinexMethod->set_active(2); retinexcolorspace->set_active(0); gammaretinex->set_active(0); @@ -599,6 +617,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) retinexColorSpaceConn.block(true); gammaretinexConn.block(true); mapMethodConn.block(true); + viewMethodConn.block(true); if (pedited) { @@ -633,6 +652,10 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) mapMethod->set_active_text(M("GENERAL_UNCHANGED")); } + if (!pedited->retinex.viewMethod) { + viewMethod->set_active_text(M("GENERAL_UNCHANGED")); + } + if (!pedited->retinex.retinexcolorspace) { retinexcolorspace->set_active_text(M("GENERAL_UNCHANGED")); } @@ -712,6 +735,13 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) mapMethod->set_active (4); } + if (pp->retinex.viewMethod == "none") { + viewMethod->set_active (0); + } else if (pp->retinex.viewMethod == "mask") { + viewMethod->set_active (1); + } else if (pp->retinex.viewMethod == "tran") { + viewMethod->set_active (2); + } if (pp->retinex.retinexcolorspace == "Lab") { retinexcolorspace->set_active (0); @@ -737,6 +767,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) retinexColorSpaceChanged(); gammaretinexChanged(); mapMethodChanged (); + viewMethodChanged (); medianmapConn.block(true); medianmapChanged (); @@ -751,6 +782,7 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) retinexColorSpaceConn.block(false); gammaretinexConn.block(false); mapMethodConn.block(false); + viewMethodConn.block(false); transmissionShape->setCurve (pp->retinex.transmissionCurve); @@ -796,6 +828,7 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited) pedited->retinex.retinexcolorspace = retinexcolorspace->get_active_text() != M("GENERAL_UNCHANGED"); pedited->retinex.gammaretinex = gammaretinex->get_active_text() != M("GENERAL_UNCHANGED"); pedited->retinex.mapMethod = mapMethod->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->retinex.viewMethod = viewMethod->get_active_text() != M("GENERAL_UNCHANGED"); //%%%%%%%%%%%%%%%%%%%%%% pedited->retinex.str = str->getEditedState (); @@ -853,6 +886,14 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited) pp->retinex.mapMethod = "mapT"; } + if (viewMethod->get_active_row_number() == 0) { + pp->retinex.viewMethod = "none"; + } else if (viewMethod->get_active_row_number() == 1) { + pp->retinex.viewMethod = "mask"; + } else if (viewMethod->get_active_row_number() == 2) { + pp->retinex.viewMethod = "tran"; + } + if (retinexcolorspace->get_active_row_number() == 0) { pp->retinex.retinexcolorspace = "Lab"; } else if (retinexcolorspace->get_active_row_number() == 1) { @@ -894,20 +935,20 @@ void Retinex::retinexMethodChanged() void Retinex::mapMethodChanged() { - if(mapMethod->get_active_row_number() >= 1) { + if(mapMethod->get_active_row_number() == 1 || mapMethod->get_active_row_number() == 2) { curveEditormap->show(); highlights->show(); h_tonalwidth->show(); shadows->show(); s_tonalwidth->show(); radius->show(); - /* } else if(mapMethod->get_active_row_number() == 1) { - curveEditormap->show(); - highlights->hide(); - h_tonalwidth->hide(); - shadows->hide(); - s_tonalwidth->hide(); - radius->hide();*/ + } else if(mapMethod->get_active_row_number() == 3 || mapMethod->get_active_row_number() == 4) { + curveEditormap->show(); + highlights->show(); + h_tonalwidth->show(); + shadows->show(); + s_tonalwidth->show(); + radius->hide(); } else { curveEditormap->hide(); highlights->hide(); @@ -923,6 +964,40 @@ void Retinex::mapMethodChanged() } } +void Retinex::viewMethodChanged() +{ + /* + if(mapMethod->get_active_row_number() == 1 || mapMethod->get_active_row_number() == 2) { + curveEditormap->show(); + highlights->show(); + h_tonalwidth->show(); + shadows->show(); + s_tonalwidth->show(); + radius->show(); + } else if(mapMethod->get_active_row_number() == 3 || mapMethod->get_active_row_number() == 4) { + curveEditormap->show(); + highlights->show(); + h_tonalwidth->show(); + shadows->show(); + s_tonalwidth->show(); + radius->hide(); + } else { + curveEditormap->hide(); + highlights->hide(); + h_tonalwidth->hide(); + shadows->hide(); + s_tonalwidth->hide(); + radius->hide(); + + } + */ + if (listener) { + listener->panelChanged (EvviewMethod, viewMethod->get_active_text ()); + } +} + + + void Retinex::ColorSpaceUpdateUI () { if (!batchMode) { diff --git a/rtgui/retinex.h b/rtgui/retinex.h index ac55fea99..d24254757 100644 --- a/rtgui/retinex.h +++ b/rtgui/retinex.h @@ -50,6 +50,8 @@ protected: Gtk::HBox* dhbox; Gtk::HBox* mapbox; Gtk::Label* labmap; + Gtk::HBox* viewbox; + Gtk::Label* labview; Gtk::Label* labgam; Gtk::HBox* gambox; @@ -60,6 +62,7 @@ protected: MyComboBoxText* retinexcolorspace; MyComboBoxText* gammaretinex; MyComboBoxText* mapMethod; + MyComboBoxText* viewMethod; Gtk::CheckButton* medianmap; double nextmin; double nextmax; @@ -78,7 +81,7 @@ protected: DiagonalCurveEditor* cdshapeH; DiagonalCurveEditor* mapshape; CurveEditorGroup* transmissionCurveEditorG; - sigc::connection retinexMethodConn, neutralconn, mapMethodConn; + sigc::connection retinexMethodConn, neutralconn, mapMethodConn, viewMethodConn; sigc::connection retinexColorSpaceConn; sigc::connection gammaretinexConn; FlatCurveEditor* transmissionShape; @@ -108,6 +111,7 @@ public: void curveChanged (CurveEditor* ce); void retinexMethodChanged(); void mapMethodChanged(); + void viewMethodChanged(); void retinexColorSpaceChanged(); void gammaretinexChanged(); void ColorSpaceUpdateUI(); From 38f9c05c3c2ec2a75981daaa5a85f187a1dbe4d1 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 15 Nov 2015 16:57:02 +0100 Subject: [PATCH 09/61] Enhancement to 'Process Transmission' and High radius unsharp mask --- rtdata/languages/default | 12 ++++--- rtengine/ipretinex.cc | 49 ++++++++++++++++++++-------- rtgui/retinex.cc | 69 +++++++++++++++++++++++++--------------- 3 files changed, 86 insertions(+), 44 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 4ec24b42c..2cb777a8c 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1653,7 +1653,7 @@ TP_RETINEX_CURVEEDITOR_CD_TOOLTIP;Luminance according to luminance L=f(L)\nCorre TP_RETINEX_CURVEEDITOR_LH;Strength=f(H) TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. TP_RETINEX_FREEGAMMA;Free gamma -TP_RETINEX_GAIN;Contrast +TP_RETINEX_GAIN;Gain TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. TP_RETINEX_GAMMA;Gamma TP_RETINEX_GAMMA_FREE;Free @@ -1706,13 +1706,15 @@ TP_RETINEX_TLABEL_TOOLTIP;Transmission map result.\nMin and Max are used by Vari TP_RETINEX_TRANSMISSION;Transmission map TP_RETINEX_TRANSMISSION_TOOLTIP;Transmission according to transmission.\nAbscissa: transmission from negative values (min), mean, and positives values (max).\nOrdinate: amplification or reduction. TP_RETINEX_UNIFORM;Uniform -TP_RETINEX_VARIANCE;Variance +TP_RETINEX_VARIANCE;Contrast TP_RETINEX_VARIANCE_TOOLTIP;Low variance increase local contrast and saturation, but can lead to artifacts. -TP_RETINEX_VIEW;Preview +TP_RETINEX_VIEW;Process (Preview) TP_RETINEX_VIEW_NONE;Standard TP_RETINEX_VIEW_MASK;Mask -TP_RETINEX_VIEW_TRAN;Transmission -TP_RETINEX_VIEW_METHOD_TOOLTIP;Standard - normal display\nMask - display mask\nTransmission - displays the file transmission-map , before any action on contrast and brightness\nAttention, this does not correspond to reality, but a shift to make it visible +TP_RETINEX_VIEW_UNSHARP;Unsharp mask +TP_RETINEX_VIEW_TRAN;Transmission (auto) +TP_RETINEX_VIEW_TRAN2;Transmission (fixed) +TP_RETINEX_VIEW_METHOD_TOOLTIP;Standard - normal display\nMask - display mask\nUnsharp mask - display image with high radius unsharp mask\nTransmission (auto - fixed) - displays the file transmission-map , before any action on contrast and brightness\nAttention, this does not correspond to reality, but a shift (or auto) to make it visible TP_RGBCURVES_BLUE;B TP_RGBCURVES_CHANNEL;Channel TP_RGBCURVES_GREEN;G diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index 839d8646e..b24cc9bb3 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -241,6 +241,12 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } else { elogt = hl; } + int H_L = height; + int W_L = width; + + float *tran[H_L] ALIGNED16; + float *tranBuffer; + int viewmet=0; elogt = 2.71828f;//disabled baselog FlatCurve* shcurve = NULL;//curve L=f(H) @@ -386,8 +392,8 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e retinex_scales( RetinexScales, scal, moderetinex, nei/grad, high ); - int H_L = height; - int W_L = width; + // int H_L = height; + // int W_L = width; float *src[H_L] ALIGNED16; float *srcBuffer = new float[H_L * W_L]; @@ -408,9 +414,11 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e double shradius = (double) deh.radius; // printf("shrad=%f\n",shradius); - int viewmet=0; + // int viewmet=0; if(deh.viewMethod=="mask") viewmet=1; if(deh.viewMethod=="tran") viewmet=2; + if(deh.viewMethod=="tran2") viewmet=3; + if(deh.viewMethod=="unsharp") viewmet=4; #ifdef _OPENMP #pragma omp parallel for @@ -429,13 +437,13 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e out[i] = &outBuffer[i * W_L]; } - float *tran[H_L] ALIGNED16; - float *tranBuffer = new float[H_L * W_L]; + if(viewmet==3 || viewmet==2) { + tranBuffer = new float[H_L * W_L]; - for (int i = 0; i < H_L; i++) { - tran[i] = &tranBuffer[i * W_L]; + for (int i = 0; i < H_L; i++) { + tran[i] = &tranBuffer[i * W_L]; + } } - const float logBetaGain = xlogf(16384.f); float pond = logBetaGain / (float) scal; @@ -611,7 +619,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } luminance[i][j] *= (-1.f + 4.f * dehatransmissionCurve[absciss]); //new transmission - tran[i][j]=luminance[i][j]; + if(viewmet==3 || viewmet==2) tran[i][j]=luminance[i][j]; } } @@ -683,7 +691,11 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e float cdfactor = gain2 * 32768.f / delta; maxCD = -9999999.f; minCD = 9999999.f; - + // coeff for auto "transmission" with 2 sigma #95% datas + float aza=16300.f/(2.f*stddv); + float azb=-aza*(mean-2.f*stddv); + float bza=16300.f/(2.f*stddv); + float bzb=16300.f-bza*(mean); @@ -730,7 +742,13 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e if(exLuminance[i][j] > 65535.f*hig && higplus) str *= hig; if(viewmet==0) luminance[i][j]=clipretinex( cd, 0.f, 32768.f ) * str + (1.f - str) * originalLuminance[i][j]; if(viewmet==1) luminance[i][j] = out[i][j]; - if(viewmet==2) luminance[i][j] = 1000.f+ tran[i][j]*700.f;//arbitrary values to help display log values which are between -20 to + 30 - usage values -4 + 5 + if(viewmet==4) luminance[i][j] = (1.f + str) * originalLuminance[i][j] - str* out[i][j];//unsharp + if(viewmet==2) { + if(tran[i][j]<= mean) luminance[i][j] = azb + aza*tran[i][j];//auto values + else luminance[i][j] = bzb + bza*tran[i][j]; + } + if(viewmet==3) luminance[i][j] = 1000.f + tran[i][j]*700.f;//arbitrary values to help display log values which are between -20 to + 30 - usage values -4 + 5 + } #ifdef _OPENMP @@ -744,19 +762,22 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } delete [] outBuffer; outBuffer = NULL; - delete [] tranBuffer; - tranBuffer = NULL; - // printf("cdmin=%f cdmax=%f\n",minCD, maxCD); Tmean = mean; Tsigma = stddv; Tmin = mintr; Tmax = maxtr; + if (shcurve && it==1) { delete shcurve; } } + if(viewmet==3 || viewmet==2) { + delete [] tranBuffer; + tranBuffer = NULL; + } + } } diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index 5e4a9f636..eca9f7a91 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -202,7 +202,9 @@ Retinex::Retinex () : FoldableToolPanel(this, "retinex", M("TP_RETINEX_LABEL"), viewMethod = Gtk::manage (new MyComboBoxText ()); viewMethod->append_text (M("TP_RETINEX_VIEW_NONE")); viewMethod->append_text (M("TP_RETINEX_VIEW_MASK")); + viewMethod->append_text (M("TP_RETINEX_VIEW_UNSHARP")); viewMethod->append_text (M("TP_RETINEX_VIEW_TRAN")); + viewMethod->append_text (M("TP_RETINEX_VIEW_TRAN2")); viewMethod->set_active(0); viewMethodConn = viewMethod->signal_changed().connect ( sigc::mem_fun(*this, &Retinex::viewMethodChanged) ); viewMethod->set_tooltip_markup (M("TP_RETINEX_VIEW_METHOD_TOOLTIP")); @@ -739,8 +741,12 @@ void Retinex::read (const ProcParams* pp, const ParamsEdited* pedited) viewMethod->set_active (0); } else if (pp->retinex.viewMethod == "mask") { viewMethod->set_active (1); - } else if (pp->retinex.viewMethod == "tran") { + } else if (pp->retinex.viewMethod == "unsharp") { viewMethod->set_active (2); + } else if (pp->retinex.viewMethod == "tran") { + viewMethod->set_active (3); + } else if (pp->retinex.viewMethod == "tran2") { + viewMethod->set_active (4); } if (pp->retinex.retinexcolorspace == "Lab") { @@ -891,7 +897,11 @@ void Retinex::write (ProcParams* pp, ParamsEdited* pedited) } else if (viewMethod->get_active_row_number() == 1) { pp->retinex.viewMethod = "mask"; } else if (viewMethod->get_active_row_number() == 2) { + pp->retinex.viewMethod = "unsharp"; + } else if (viewMethod->get_active_row_number() == 3) { pp->retinex.viewMethod = "tran"; + } else if (viewMethod->get_active_row_number() == 4) { + pp->retinex.viewMethod = "tran2"; } if (retinexcolorspace->get_active_row_number() == 0) { @@ -966,31 +976,40 @@ void Retinex::mapMethodChanged() void Retinex::viewMethodChanged() { - /* - if(mapMethod->get_active_row_number() == 1 || mapMethod->get_active_row_number() == 2) { - curveEditormap->show(); - highlights->show(); - h_tonalwidth->show(); - shadows->show(); - s_tonalwidth->show(); - radius->show(); - } else if(mapMethod->get_active_row_number() == 3 || mapMethod->get_active_row_number() == 4) { - curveEditormap->show(); - highlights->show(); - h_tonalwidth->show(); - shadows->show(); - s_tonalwidth->show(); - radius->hide(); - } else { - curveEditormap->hide(); - highlights->hide(); - h_tonalwidth->hide(); - shadows->hide(); - s_tonalwidth->hide(); - radius->hide(); + if(viewMethod->get_active_row_number() == 1 || viewMethod->get_active_row_number() == 2) { + vart->hide(); + gain->hide(); + offs->hide(); + limd->hide(); + transmissionCurveEditorG->hide(); + medianmap->hide(); + iter->hide(); + scal->hide(); + grad->hide(); + grads->hide(); + curveEditorGH->hide(); + } + else if(viewMethod->get_active_row_number() == 3 || viewMethod->get_active_row_number() == 4) { + gain->hide(); + offs->hide(); + vart->hide(); + curveEditorGH->hide(); + } + else { + vart->show(); + neigh->show(); + gain->show(); + offs->show(); + limd->show(); + transmissionCurveEditorG->show(); + medianmap->show(); + iter->show(); + scal->show(); + grad->show(); + grads->show(); + curveEditorGH->show(); + } - } - */ if (listener) { listener->panelChanged (EvviewMethod, viewMethod->get_active_text ()); } From 88ab82cee9073b0cc7abcfef172433b7dccb6f48 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sat, 28 Nov 2015 23:21:17 +0100 Subject: [PATCH 10/61] Factor out the three thumbnail browser selection modes without changing their behaviour. --- rtgui/threadutils.h | 16 +++ rtgui/thumbbrowserbase.cc | 202 +++++++++++++++++--------------------- rtgui/thumbbrowserbase.h | 6 ++ 3 files changed, 114 insertions(+), 110 deletions(-) diff --git a/rtgui/threadutils.h b/rtgui/threadutils.h index b7231d5de..e8ef2f29e 100644 --- a/rtgui/threadutils.h +++ b/rtgui/threadutils.h @@ -704,4 +704,20 @@ public: #define MYWRITERLOCK_RELEASE(ln) ln.release(); #endif +#ifdef PROTECT_VECTORS +#define IFPV_MYREADERLOCK(l, e) MYREADERLOCK(l, e) +#define IFPV_MYWRITERLOCK(l, e) MYWRITERLOCK(l, e) +#define IFPV_MYREADERLOCK_ACQUIRE(l) MYREADERLOCK_ACQUIRE(l) +#define IFPV_MYWRITERLOCK_ACQUIRE(l) MYWRITERLOCK_ACQUIRE(l) +#define IFPV_MYREADERLOCK_RELEASE(l) MYREADERLOCK_RELEASE(l) +#define IFPV_MYWRITERLOCK_RELEASE(l) MYWRITERLOCK_RELEASE(l) +#else +#define IFPV_MYREADERLOCK(l, e) +#define IFPV_MYWRITERLOCK(l, e) +#define IFPV_MYREADERLOCK_ACQUIRE(l) +#define IFPV_MYWRITERLOCK_ACQUIRE(l) +#define IFPV_MYREADERLOCK_RELEASE(l) +#define IFPV_MYWRITERLOCK_RELEASE(l) +#endif + #endif /* _THREADUTILS_ */ diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index c2ed480f2..ed6366266 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -98,6 +98,84 @@ void ThumbBrowserBase::scrollPage (int direction) } } +void ThumbBrowserBase::selectSingle (ThumbBrowserEntryBase* fileDescr) +{ + for (size_t i = 0; i < selected.size(); i++) { + selected[i]->selected = false; + } + + selected.clear (); + + if (fileDescr) { + selected.push_back (fileDescr); + fileDescr->selected = true; + } +} + +void ThumbBrowserBase::selectRange (ThumbBrowserEntryBase* fileDescr) +{ + if (selected.empty()) { + selected.push_back (fileDescr); + fileDescr->selected = true; + } else { + // find the start and the end of the selection interval + size_t startx = fd.size() - 1; + + if (lastClicked) { + for (; startx > 0; startx--) + if (fd[startx] == lastClicked) { + break; + } + } else { + for (; startx > 0; startx--) + if (fd[startx] == selected[0]) { + break; + } + } + + size_t endx = 0; + + for (; endx < fd.size(); endx++) + if (fd[endx] == fileDescr) { + break; + } + + if (endx < startx) { + int tmp = endx; + endx = startx; + startx = tmp; + } + + // clear current selection + for (size_t i = 0; i < selected.size(); i++) { + selected[i]->selected = false; + } + + selected.clear (); + + // select thumbnails in the interval + for (size_t i = startx; i <= endx; i++) { + if (!fd[i]->filtered) { + fd[i]->selected = true; + selected.push_back (fd[i]); + } + } + } +} + +void ThumbBrowserBase::selectSet (ThumbBrowserEntryBase* fileDescr) +{ + std::vector::iterator i = std::find (selected.begin(), selected.end(), fileDescr); + + if (i != selected.end()) { + (*i)->selected = false; + selected.erase (i); + } else { + selected.push_back (fileDescr); + fileDescr->selected = true; + } +} + static void scrollToEntry (double& h, double& v, int iw, int ih, ThumbBrowserEntryBase* entry) { const int hmin = entry->getX (); @@ -726,9 +804,7 @@ void ThumbBrowserBase::buttonPressed (int x, int y, int button, GdkEventType typ bool handled = false; { -#if PROTECT_VECTORS - MYREADERLOCK(l, entryRW); -#endif + IFPV_MYREADERLOCK(l, entryRW); for (size_t i = 0; i < fd.size(); i++) if (fd[i]->drawable) { @@ -746,125 +822,31 @@ void ThumbBrowserBase::buttonPressed (int x, int y, int button, GdkEventType typ } { -#if PROTECT_VECTORS - MYWRITERLOCK(l, entryRW); -#endif + IFPV_MYWRITERLOCK(l, entryRW); if (selected.size() == 1 && type == GDK_2BUTTON_PRESS && button == 1) { doubleClicked (selected[0]); } else if (button == 1 && type == GDK_BUTTON_PRESS) { - if (fileDescr && (state & GDK_SHIFT_MASK)) { - if (selected.empty()) { - selected.push_back (fileDescr); - fileDescr->selected = true; - lastClicked = fileDescr; -#if PROTECT_VECTORS - MYWRITERLOCK_RELEASE(l); -#endif - selectionChanged (); - } else { - // find the start and the end of the selection interval - size_t startx = fd.size() - 1; + if (fileDescr && (state & GDK_SHIFT_MASK)) + selectRange (fileDescr); + else if (fileDescr && (state & GDK_CONTROL_MASK)) + selectSet (fileDescr); + else + selectSingle (fileDescr); - if (lastClicked) { - for (; startx > 0; startx--) - if (fd[startx] == lastClicked) { - break; - } - } else { - for (; startx > 0; startx--) - if (fd[startx] == selected[0]) { - break; - } - } - - size_t endx = 0; - - for (; endx < fd.size(); endx++) - if (fd[endx] == fileDescr) { - break; - } - - if (endx < startx) { - int tmp = endx; - endx = startx; - startx = tmp; - } - - // clear current selection - for (size_t i = 0; i < selected.size(); i++) { - selected[i]->selected = false; - } - - selected.clear (); - - // select thumbnails in the interval - for (size_t i = startx; i <= endx; i++) { - if (!fd[i]->filtered) { - fd[i]->selected = true; - selected.push_back (fd[i]); - } - } - - lastClicked = fileDescr; -#if PROTECT_VECTORS - MYWRITERLOCK_RELEASE(l); -#endif - selectionChanged (); - } - } else if (fileDescr && (state & GDK_CONTROL_MASK)) { - std::vector::iterator i = std::find (selected.begin(), selected.end(), fileDescr); - - if (i != selected.end()) { - (*i)->selected = false; - selected.erase (i); - } else { - selected.push_back (fileDescr); - fileDescr->selected = true; - } - - lastClicked = fileDescr; -#if PROTECT_VECTORS - MYWRITERLOCK_RELEASE(l); -#endif - selectionChanged (); - } else { - for (size_t i = 0; i < selected.size(); i++) { - selected[i]->selected = false; - } - - selected.clear (); - - if (fileDescr) { - selected.push_back (fileDescr); - fileDescr->selected = true; - } - - lastClicked = fileDescr; -#if PROTECT_VECTORS - MYWRITERLOCK_RELEASE(l); -#endif - selectionChanged (); - } + lastClicked = fileDescr; + IFPV_MYWRITERLOCK_RELEASE(l); + selectionChanged (); } else if (fileDescr && button == 3 && type == GDK_BUTTON_PRESS) { if (!fileDescr->selected) { - for (size_t i = 0; i < selected.size(); i++) { - selected[i]->selected = false; - } + selectSingle (fileDescr); - selected.clear (); - fileDescr->selected = true; - selected.push_back (fileDescr); lastClicked = fileDescr; -#if PROTECT_VECTORS - MYWRITERLOCK_RELEASE(l); -#endif + IFPV_MYWRITERLOCK_RELEASE(l); selectionChanged (); } -#if PROTECT_VECTORS - MYWRITERLOCK_RELEASE(l); -#endif + IFPV_MYWRITERLOCK_RELEASE(l); rightClicked (fileDescr); } } // end of MYWRITERLOCK(l, entryRW); diff --git a/rtgui/thumbbrowserbase.h b/rtgui/thumbbrowserbase.h index bd410292d..ee11f550e 100644 --- a/rtgui/thumbbrowserbase.h +++ b/rtgui/thumbbrowserbase.h @@ -110,6 +110,12 @@ public: void scroll (int direction); void scrollPage (int direction); +private: + void selectSingle (ThumbBrowserEntryBase* fileDescr); + void selectRange (ThumbBrowserEntryBase* fileDescr); + void selectSet (ThumbBrowserEntryBase* fileDescr); + +public: void selectPrev (int distance, bool enlarge); void selectNext (int distance, bool enlarge); void selectFirst (bool enlarge); From df70d03e1398d9d1394405b7123fd0d1a2c188ac Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sun, 29 Nov 2015 00:07:21 +0100 Subject: [PATCH 11/61] Try to refactor the behaviour of the thumb browser selection modes adding support for shift-and-control range-selection to select several independent ranges. --- rtgui/thumbbrowserbase.cc | 138 ++++++++++++++++++++------------------ rtgui/thumbbrowserbase.h | 6 +- 2 files changed, 74 insertions(+), 70 deletions(-) diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index ed6366266..3536cc9b7 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -98,81 +98,85 @@ void ThumbBrowserBase::scrollPage (int direction) } } -void ThumbBrowserBase::selectSingle (ThumbBrowserEntryBase* fileDescr) +namespace { - for (size_t i = 0; i < selected.size(); i++) { - selected[i]->selected = false; - } + +typedef std::vector ThumbVector; +typedef ThumbVector::iterator ThumbIterator; + +inline void clearSelection (ThumbVector& selected) +{ + for (ThumbIterator thumb = selected.begin (); thumb != selected.end (); ++thumb) + (*thumb)->selected = false; selected.clear (); +} - if (fileDescr) { - selected.push_back (fileDescr); - fileDescr->selected = true; +inline void addToSelection (ThumbBrowserEntryBase* entry, ThumbVector& selected) +{ + if (entry->selected || entry->filtered) + return; + + entry->selected = true; + selected.push_back (entry); +} + +inline void removeFromSelection (const ThumbIterator& iterator, ThumbVector& selected) +{ + (*iterator)->selected = false; + selected.erase (iterator); +} + +} + +void ThumbBrowserBase::selectSingle (ThumbBrowserEntryBase* clicked) +{ + clearSelection (selected); + + if (clicked) + addToSelection (clicked, selected); +} + +void ThumbBrowserBase::selectRange (ThumbBrowserEntryBase* clicked, bool additional) +{ + if (selected.empty ()) { + addToSelection (clicked, selected); + return; + } + + if (!additional || !lastClicked) { + // Extend the current range w.r.t to first selected entry. + ThumbIterator front = std::find (fd.begin (), fd.end (), selected.front ()); + ThumbIterator current = std::find (fd.begin (), fd.end (), clicked); + + if (front > current) + std::swap (front, current); + + clearSelection (selected); + + for (; front <= current; ++front) + addToSelection (*front, selected); + } else { + // Add an additional range w.r.t. the last clicked entry. + ThumbIterator last = std::find (fd.begin (), fd.end (), lastClicked); + ThumbIterator current = std::find (fd.begin (), fd.end (), clicked); + + if (last > current) + std::swap (last, current); + + for (; last <= current; ++last) + addToSelection (*last, selected); } } -void ThumbBrowserBase::selectRange (ThumbBrowserEntryBase* fileDescr) +void ThumbBrowserBase::selectSet (ThumbBrowserEntryBase* clicked) { - if (selected.empty()) { - selected.push_back (fileDescr); - fileDescr->selected = true; + const ThumbIterator iterator = std::find (selected.begin (), selected.end (), clicked); + + if (iterator != selected.end ()) { + removeFromSelection (iterator, selected); } else { - // find the start and the end of the selection interval - size_t startx = fd.size() - 1; - - if (lastClicked) { - for (; startx > 0; startx--) - if (fd[startx] == lastClicked) { - break; - } - } else { - for (; startx > 0; startx--) - if (fd[startx] == selected[0]) { - break; - } - } - - size_t endx = 0; - - for (; endx < fd.size(); endx++) - if (fd[endx] == fileDescr) { - break; - } - - if (endx < startx) { - int tmp = endx; - endx = startx; - startx = tmp; - } - - // clear current selection - for (size_t i = 0; i < selected.size(); i++) { - selected[i]->selected = false; - } - - selected.clear (); - - // select thumbnails in the interval - for (size_t i = startx; i <= endx; i++) { - if (!fd[i]->filtered) { - fd[i]->selected = true; - selected.push_back (fd[i]); - } - } - } -} - -void ThumbBrowserBase::selectSet (ThumbBrowserEntryBase* fileDescr) -{ - std::vector::iterator i = std::find (selected.begin(), selected.end(), fileDescr); - - if (i != selected.end()) { - (*i)->selected = false; - selected.erase (i); - } else { - selected.push_back (fileDescr); - fileDescr->selected = true; + addToSelection (clicked, selected); } } @@ -828,7 +832,7 @@ void ThumbBrowserBase::buttonPressed (int x, int y, int button, GdkEventType typ doubleClicked (selected[0]); } else if (button == 1 && type == GDK_BUTTON_PRESS) { if (fileDescr && (state & GDK_SHIFT_MASK)) - selectRange (fileDescr); + selectRange (fileDescr, state & GDK_CONTROL_MASK); else if (fileDescr && (state & GDK_CONTROL_MASK)) selectSet (fileDescr); else diff --git a/rtgui/thumbbrowserbase.h b/rtgui/thumbbrowserbase.h index ee11f550e..a3ef08d80 100644 --- a/rtgui/thumbbrowserbase.h +++ b/rtgui/thumbbrowserbase.h @@ -111,9 +111,9 @@ public: void scrollPage (int direction); private: - void selectSingle (ThumbBrowserEntryBase* fileDescr); - void selectRange (ThumbBrowserEntryBase* fileDescr); - void selectSet (ThumbBrowserEntryBase* fileDescr); + void selectSingle (ThumbBrowserEntryBase* clicked); + void selectRange (ThumbBrowserEntryBase* clicked, bool additional); + void selectSet (ThumbBrowserEntryBase* clicked); public: void selectPrev (int distance, bool enlarge); From 606a1cabc3f62a101d7d1694d0b5c9a30c41124a Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Tue, 1 Dec 2015 21:52:45 +0100 Subject: [PATCH 12/61] Updated Deutsch interface translation by TooWaBoo --- rtdata/languages/Deutsch | 927 +++++++++++++++++++-------------------- 1 file changed, 462 insertions(+), 465 deletions(-) diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index 099752a48..ee4033541 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -22,6 +22,7 @@ #22 2015-09-04 komplette Überarbeitung (TooWaBoo) #23 2015-10-24 Retinexübersetzung und Korrekturen (TooWaBoo) #24 2015-11-01 Korrekturen (TooWaBoo) RT4.2.450 +#25 2015-11-30 Korrekturen (TooWaBoo) RT4.2.507 ABOUT_TAB_BUILD;Version ABOUT_TAB_CREDITS;Danksagungen @@ -86,7 +87,7 @@ EXIFPANEL_SUBDIRECTORY;Unterverzeichnis EXPORT_BYPASS_ALL;Alle/Keine auswählen EXPORT_BYPASS_DEFRINGE;Farbsaum entfernen überspringen EXPORT_BYPASS_DIRPYRDENOISE;Rauschreduzierung überspringen -EXPORT_BYPASS_DIRPYREQUALIZER;Kontrast nach Detailebenen überspringen +EXPORT_BYPASS_DIRPYREQUALIZER;Detailebenenkontrast überspringen EXPORT_BYPASS_EQUALIZER;Waveletebenen überspringen EXPORT_BYPASS_RAW_CA;CA-Korrektur überspringen [RAW] EXPORT_BYPASS_RAW_CCSTEPS;Falschfarbenunterdrückung überspringen\n[RAW] @@ -252,430 +253,431 @@ HISTORY_CUSTOMCURVE;Benutzerdefiniert HISTORY_DELSNAPSHOT;Entfernen HISTORY_FROMCLIPBOARD;Aus der Zwischenablage HISTORY_LABEL;Historie -HISTORY_MSG_1;Bild geladen -HISTORY_MSG_2;Profil geladen -HISTORY_MSG_3;Profil geändert -HISTORY_MSG_4;Historie durchsuchen -HISTORY_MSG_5;Belichtung\nHelligkeit -HISTORY_MSG_6;Belichtung\nKontrast -HISTORY_MSG_7;Belichtung\nSchwarzwert -HISTORY_MSG_8;Belichtung\nBelichtungskorrektur -HISTORY_MSG_9;Belichtung\nLichterkompression -HISTORY_MSG_10;Belichtung\nSchattenkompression -HISTORY_MSG_11;Belichtung\nTonwertkurve 1 -HISTORY_MSG_12;Belichtung - Auto -HISTORY_MSG_13;Belichtung\nAuto-Grenzwert -HISTORY_MSG_14;L*a*b* - Helligkeit -HISTORY_MSG_15;L*a*b* - Kontrast +HISTORY_MSG_1;Bild geladen +HISTORY_MSG_2;Profil geladen +HISTORY_MSG_3;Profil geändert +HISTORY_MSG_4;Historie durchsuchen +HISTORY_MSG_5;Belichtung - Helligkeit +HISTORY_MSG_6;Belichtung - Kontrast +HISTORY_MSG_7;Belichtung - Schwarzwert +HISTORY_MSG_8;Belichtung\nBelichtungskorrektur +HISTORY_MSG_9;Belichtung\nLichterkompression +HISTORY_MSG_10;Belichtung\nSchattenkompression +HISTORY_MSG_11;Belichtung\nTonwertkurve 1 +HISTORY_MSG_12;Belichtung - Auto +HISTORY_MSG_13;Belichtung\nAuto-Grenzwert +HISTORY_MSG_14;L*a*b* - Helligkeit +HISTORY_MSG_15;L*a*b* - Kontrast HISTORY_MSG_16;- HISTORY_MSG_17;- HISTORY_MSG_18;- -HISTORY_MSG_19;L*a*b* - L-Kurve -HISTORY_MSG_20;Schärfung -HISTORY_MSG_21;Schärfung\nUnschärfemaskierung\nRadius -HISTORY_MSG_22;Schärfung\nUnschärfemaskierung\nIntensität -HISTORY_MSG_23;Schärfung\nUnschärfemaskierung\nSchwellenwert -HISTORY_MSG_24;Schärfung\nUnschärfemaskierung\nNur Kanten schärfen -HISTORY_MSG_25;Schärfung\nUnschärfemaskierung\nKantenradius -HISTORY_MSG_26;Schärfung\nUnschärfemaskierung\nKantentoleranz -HISTORY_MSG_27;Schärfung\nUnschärfemaskierung\nHalokontrolle -HISTORY_MSG_28;Schärfung\nUnschärfemaskierung\nHalokontrolle - Intensität -HISTORY_MSG_29;Schärfung - Methode -HISTORY_MSG_30;Schärfung\nDekonvolution\nRadius -HISTORY_MSG_31;Schärfung\nDekonvolution\nIntensität -HISTORY_MSG_32;Schärfung\nDekonvolution\nDämpfung -HISTORY_MSG_33;Schärfung\nDekonvolution\nIterationen -HISTORY_MSG_34;Objektivkorrektur\nProfil\nVerzeichnung -HISTORY_MSG_35;Objektivkorrektur\nProfil\nVignettierung -HISTORY_MSG_36;Objektivkorrektur\nProfil\nCA-Korrektur -HISTORY_MSG_37;Belichtung - Auto -HISTORY_MSG_38;Weißabgleich Methode -HISTORY_MSG_39;Weißabgleich\nFarbtemperatur -HISTORY_MSG_40;Weißabgleich\nTönung -HISTORY_MSG_41;Belichtung\nTonwertkurve 1\nModus -HISTORY_MSG_42;Belichtung\nTonwertkurve 2 -HISTORY_MSG_43;Belichtung\nTonwertkurve 2\nModus -HISTORY_MSG_44;Luminanz-Rauschfilter\nRadius -HISTORY_MSG_45;Luminanz-Rauschfilter\nKantentoleranz -HISTORY_MSG_46;Farb-Rauschfilter -HISTORY_MSG_47;ICC Lichter aus Matrix\nüberlagern -HISTORY_MSG_48;Eingangsfarbprofil\nDCP\nTonwertkurve -HISTORY_MSG_49;Eingangsfarbprofil\n DCP\nIllumination -HISTORY_MSG_50;Schatten/Lichter -HISTORY_MSG_51;Schatten/Lichter\nLichter -HISTORY_MSG_52;Schatten/Lichter\nSchatten -HISTORY_MSG_53;Schatten/Lichter\nTonwertbreite\nLichter -HISTORY_MSG_54;Schatten/Lichter\nTonwertbreite\nSchatten -HISTORY_MSG_55;Schatten/Lichter\nLokaler Kontrast -HISTORY_MSG_56;Schatten/Lichter\nRadius -HISTORY_MSG_57;Grobe Drehung -HISTORY_MSG_58;Horizontal spiegeln -HISTORY_MSG_59;Vertikal spiegeln -HISTORY_MSG_60;Objektivkorrektur\nDrehen - Grad -HISTORY_MSG_61;Objektivkorrektur\nAuto-Füllen -HISTORY_MSG_62;Objektivkorrektur\nVerzeichnung -HISTORY_MSG_63;Schnappschuss\nausgewählt -HISTORY_MSG_64;Ausschnitt -HISTORY_MSG_65;Objektivkorrektur\nFarbsaum entfernen -HISTORY_MSG_66;Belichtung\nLichter rekonstruieren -HISTORY_MSG_67;Belichtung\nLichterkompression\nUmfang -HISTORY_MSG_68;Belichtung\nLichterkompression\nMethode -HISTORY_MSG_69;Farbmanagement\nArbeitsfarbraum -HISTORY_MSG_70;Farbmanagement\nAusgabeprofil -HISTORY_MSG_71;Eingangsfarbprofil -HISTORY_MSG_72;Objektivkorrektur\nVignettierung\nIntensität -HISTORY_MSG_73;RGB-Kanalmixer -HISTORY_MSG_74;Größe ändern\nMaßstab -HISTORY_MSG_75;Größe ändern\nMethode -HISTORY_MSG_76;Exif Metadaten -HISTORY_MSG_77;IPTC Metadaten +HISTORY_MSG_19;L*a*b* - L-Kurve +HISTORY_MSG_20;Schärfung +HISTORY_MSG_21;Schärfung - USM\nRadius +HISTORY_MSG_22;Schärfung - USM\nIntensität +HISTORY_MSG_23;Schärfung - USM\nSchwellenwert +HISTORY_MSG_24;Schärfung - USM\nNur Kanten schärfen +HISTORY_MSG_25;Schärfung - USM\nKantenschärfung\nRadius +HISTORY_MSG_26;Schärfung - USM\nKantenschärfung\nKantentoleranz +HISTORY_MSG_27;Schärfung - USM\nHalokontrolle +HISTORY_MSG_28;Schärfung - USM\nHalokontrolle - Intensität +HISTORY_MSG_29;Schärfung - Methode +HISTORY_MSG_30;Schärfung - RLD\nRadius +HISTORY_MSG_31;Schärfung - RLD\nIntensität +HISTORY_MSG_32;Schärfung - RLD\nDämpfung +HISTORY_MSG_33;Schärfung - RLD\nIterationen +HISTORY_MSG_34;Objektivkorrektur\nProfil - Verzeichnung +HISTORY_MSG_35;Objektivkorrektur\nProfil - Vignettierung +HISTORY_MSG_36;Objektivkorrektur\nProfil - CA-Korrektur +HISTORY_MSG_37;Belichtung - Auto +HISTORY_MSG_38;Weißabgleich\nMethode +HISTORY_MSG_39;Weißabgleich\nFarbtemperatur +HISTORY_MSG_40;Weißabgleich\nTönung +HISTORY_MSG_41;Belichtung\nTonwertkurve 1 - Modus +HISTORY_MSG_42;Belichtung\nTonwertkurve 2 +HISTORY_MSG_43;Belichtung\nTonwertkurve 2 - Modus +HISTORY_MSG_44;Luminanz-Rauschfilter\nRadius +HISTORY_MSG_45;Luminanz-Rauschfilter\nKantentoleranz +HISTORY_MSG_46;Farb-Rauschfilter +HISTORY_MSG_47;ICC Lichter aus Matrix\nüberlagern +HISTORY_MSG_48;Farbmanagement\nEingangsfarbprofil\nDCP - Tonwertkurve +HISTORY_MSG_49;Farbmanagement\nEingangsfarbprofil\nDCP - Illumination +HISTORY_MSG_50;Schatten/Lichter +HISTORY_MSG_51;Schatten/Lichter\nLichter +HISTORY_MSG_52;Schatten/Lichter\nSchatten +HISTORY_MSG_53;Schatten/Lichter\nTonwertbreite Lichter +HISTORY_MSG_54;Schatten/Lichter\nTonwertbreite Schatten +HISTORY_MSG_55;Schatten/Lichter\nLokaler Kontrast +HISTORY_MSG_56;Schatten/Lichter\nRadius +HISTORY_MSG_57;Grobe Drehung +HISTORY_MSG_58;Horizontal spiegeln +HISTORY_MSG_59;Vertikal spiegeln +HISTORY_MSG_60;Objektivkorrektur\nDrehen - Winkel +HISTORY_MSG_61;Objektivkorrektur\nAuto-Füllen +HISTORY_MSG_62;Objektivkorrektur\nVerzeichnung +HISTORY_MSG_63;Schnappschuss\nausgewählt +HISTORY_MSG_64;Ausschnitt +HISTORY_MSG_65;Objektivkorrektur\nFarbsaum entfernen +HISTORY_MSG_66;Belichtung\nLichter rekonstruieren +HISTORY_MSG_67;Belichtung\nLichterkompression\nUmfang +HISTORY_MSG_68;Belichtung\nLichterkompression\nMethode +HISTORY_MSG_69;Farbmanagement\nArbeitsfarbraum +HISTORY_MSG_70;Farbmanagement\nAusgabeprofil +HISTORY_MSG_71;Farbmanagement\nEingangsfarbprofil +HISTORY_MSG_72;Objektivkorrektur\nVignettierung - Intensität +HISTORY_MSG_73;RGB-Kanalmixer +HISTORY_MSG_74;Skalieren - Maßstab +HISTORY_MSG_75;Skalieren - Methode +HISTORY_MSG_76;Exif Metadaten +HISTORY_MSG_77;IPTC Metadaten HISTORY_MSG_78;- -HISTORY_MSG_79;Größe ändern - Breite -HISTORY_MSG_80;Größe ändern - Höhe -HISTORY_MSG_81;Größe ändern -HISTORY_MSG_82;Profil geändert -HISTORY_MSG_83;Schatten/Lichter\nSchärfemaske -HISTORY_MSG_84;Objektivkorrektur\nPerspektive -HISTORY_MSG_85;Objektivkorrektur\nProfil -HISTORY_MSG_86;RGB-Kurven\nHelligkeitsmodus -HISTORY_MSG_87;Impulsrauschred. -HISTORY_MSG_88;Impulsrauschred.\nSchwellenwert -HISTORY_MSG_89;Rauschreduzierung -HISTORY_MSG_90;Rauschreduzierung\nLuminanz -HISTORY_MSG_91;Rauschreduzierung\nChrominanz (Master) -HISTORY_MSG_92;Rauschreduzierung\nGamma -HISTORY_MSG_93;Kontrast nach\nDetailebenen - Wert -HISTORY_MSG_94;Kontrast nach\nDetailebenen -HISTORY_MSG_95;L*a*b* - Chromatizität -HISTORY_MSG_96;L*a*b* - a-Kurve -HISTORY_MSG_97;L*a*b* - b-Kurve -HISTORY_MSG_98;Demosaikmethode -HISTORY_MSG_99;Vorverarbeitung\nHot-Pixel-Filter -HISTORY_MSG_100;Belichtung\nSättigung -HISTORY_MSG_101;HSV - Farbton (H) -HISTORY_MSG_102;HSV - Sättigung (S) -HISTORY_MSG_103;HSV - Dynamik (V) -HISTORY_MSG_104;HSV -HISTORY_MSG_105;Farbsaum entfernen -HISTORY_MSG_106;Farbsaum entfernen\nRadius -HISTORY_MSG_107;Farbsaum entfernen\nSchwellenwert -HISTORY_MSG_108;Belichtung\nLichterkompression\nSchwellenwert -HISTORY_MSG_109;Größe ändern\nBegrenzungsrahmen -HISTORY_MSG_110;Größe ändern\nGilt für -HISTORY_MSG_111;L*a*b*\nFarbverschiebung\nvermeiden +HISTORY_MSG_79;Skalieren - Breite +HISTORY_MSG_80;Skalieren - Höhe +HISTORY_MSG_81;Skalieren +HISTORY_MSG_82;Profil geändert +HISTORY_MSG_83;Schatten/Lichter\nSchärfemaske +HISTORY_MSG_84;Objektivkorrektur\nPerspektive +HISTORY_MSG_85;Objektivkorrektur\nProfil +HISTORY_MSG_86;RGB-Kurven\nHelligkeitsmodus +HISTORY_MSG_87;Impulsrauschred. +HISTORY_MSG_88;Impulsrauschred.\nSchwellenwert +HISTORY_MSG_89;Rauschreduzierung +HISTORY_MSG_90;Rauschreduzierung\nLuminanz +HISTORY_MSG_91;Rauschreduzierung\nChrominanz (Master) +HISTORY_MSG_92;Rauschreduzierung\nChrominanz - Gamma +HISTORY_MSG_93;Detailebenenkontrast\nWert +HISTORY_MSG_94;Detailebenenkontrast +HISTORY_MSG_95;L*a*b* - Chromatizität +HISTORY_MSG_96;L*a*b* - a-Kurve +HISTORY_MSG_97;L*a*b* - b-Kurve +HISTORY_MSG_98;Sensor-Matrix\nFarbinterpolation\nMethode +HISTORY_MSG_99;Vorverarbeitung\nHot-Pixel-Filter +HISTORY_MSG_100;Belichtung - Sättigung +HISTORY_MSG_101;HSV - Farbton (H) +HISTORY_MSG_102;HSV - Sättigung (S) +HISTORY_MSG_103;HSV - Dynamik (V) +HISTORY_MSG_104;HSV +HISTORY_MSG_105;Farbsaum entfernen +HISTORY_MSG_106;Farbsaum entfernen\nRadius +HISTORY_MSG_107;Farbsaum entfernen\nSchwellenwert +HISTORY_MSG_108;Belichtung\nLichterkompression\nSchwellenwert +HISTORY_MSG_109;Skalieren - Breite & Höhe +HISTORY_MSG_110;Skalieren - Anwenden auf: +HISTORY_MSG_111;L*a*b* - Farbverschiebung\nvermeiden HISTORY_MSG_112;--unused-- -HISTORY_MSG_113;L*a*b* - Hautfarbtöne\nschützen -HISTORY_MSG_114;DCB-Iterationen -HISTORY_MSG_115;Falschfarben-\nunterdrückung -HISTORY_MSG_116;DCB-Verbesserung -HISTORY_MSG_117;CA-Korrektur Rot -HISTORY_MSG_118;CA-Korrektur Blau -HISTORY_MSG_119;Zeilenrauschfilter -HISTORY_MSG_120;Grün-Ausgleich -HISTORY_MSG_121;Autom. CA-Korrektur -HISTORY_MSG_122;Dunkelbild\nAutom. Auswahl -HISTORY_MSG_123;Dunkelbild - Datei -HISTORY_MSG_124;Weißpunktkorrektur -HISTORY_MSG_125;Belichtungskorrektur\nLichter schützen -HISTORY_MSG_126;Weißbild - Datei -HISTORY_MSG_127;Weißbild\nAutom. Auswahl -HISTORY_MSG_128;Weißbild\nUnschärferadius -HISTORY_MSG_129;Weißbild\nUnschärfetyp -HISTORY_MSG_130;Autom. Verzeichnung -HISTORY_MSG_131;Rauschreduzierung\nLuminanz -HISTORY_MSG_132;Rauschreduzierung\nChrominanz -HISTORY_MSG_133;Farbmanagement\nAusgabeprofil\nAusgabe-Gamma -HISTORY_MSG_134;Farbmanagement\nAusgabeprofil\nGamma -HISTORY_MSG_135;Farbmanagement\nAusgabeprofil\nFreies Gamma -HISTORY_MSG_136;Farbmanagement\nAusgabeprofil\nGradient (linear) -HISTORY_MSG_137;Schwarzpunkt Grün 1 -HISTORY_MSG_138;Schwarzpunkt Rot -HISTORY_MSG_139;Schwarzpunkt Blau -HISTORY_MSG_140;Schwarzpunkt Grün 2 -HISTORY_MSG_141;Schwarzpunkt\nGrün-Werte angleichen -HISTORY_MSG_142;Kantenschärfung\nIterationen -HISTORY_MSG_143;Kantenschärfung\nIntensität -HISTORY_MSG_144;Mikrokontrast\nIntensität -HISTORY_MSG_145;Mikrokontrast\nGleichmäßigkeit -HISTORY_MSG_146;Kantenschärfung -HISTORY_MSG_147;Kantenschärfung\nNur Luminanz -HISTORY_MSG_148;Mikrokontrast -HISTORY_MSG_149;Mikrokontrast\n3×3-Matrix -HISTORY_MSG_150;Artefakt-/Rauschred.\nnach Farbinterpolation -HISTORY_MSG_151;Dynamik -HISTORY_MSG_152;Dynamik\nPastelltöne -HISTORY_MSG_153;Dynamik\nGesättigte Töne -HISTORY_MSG_154;Dynamik\nHautfarbtöne schützen -HISTORY_MSG_155;Dynamik\nFarbverschiebungen\nvermeiden -HISTORY_MSG_156;Dynamik\nPastell und gesättigte\nTöne koppeln -HISTORY_MSG_157;Dynamik\nPastell/gesättigte Töne\nSchwellenwert -HISTORY_MSG_158;Dynamikkompression\nIntensität -HISTORY_MSG_159;Dynamikkompression\nKantenschutz -HISTORY_MSG_160;Dynamikkompression\nFaktor -HISTORY_MSG_161;Dynamikkompression\nIterationen -HISTORY_MSG_162;Dynamikkompression -HISTORY_MSG_163;RGB-Kurven - Rot -HISTORY_MSG_164;RGB-Kurven - Grün -HISTORY_MSG_165;RGB-Kurven - Blau -HISTORY_MSG_167;--unused-- -HISTORY_MSG_168;L*a*b* - CC-Kurve -HISTORY_MSG_169;L*a*b* - CH-Kurve -HISTORY_MSG_170;Dynamik - HH-Kurve -HISTORY_MSG_171;L*a*b* - LC-Kurve -HISTORY_MSG_172;L*a*b* - LC-Kurve\nbeschränken -HISTORY_MSG_173;Rauschreduzierung\nLuminanz-Details -HISTORY_MSG_174;CIECAM02 -HISTORY_MSG_175;CAM02 - CAT02\nAdaptation -HISTORY_MSG_176;CAM02 - Umgebung -HISTORY_MSG_177;CAM02 - Szene\nLeuchtstärke -HISTORY_MSG_178;CAM02\nBetrachtungsbed.\nLeuchtstärke -HISTORY_MSG_179;CAM02 - Weißpunkt-\nmodell -HISTORY_MSG_180;CAM02 - Helligkeit (J) -HISTORY_MSG_181;CAM02 - Buntheit (H) -HISTORY_MSG_182;CAM02 - CAT02\nAutomatisch -HISTORY_MSG_183;CAM02 - Kontrast (J) -HISTORY_MSG_184;CAM02 - Dunkle\nUmgebung -HISTORY_MSG_185;CAM02\nGamutkontrolle -HISTORY_MSG_186;CAM02 - Algorithmus -HISTORY_MSG_187;CAM02 - Hautfarbtöne\nschützen -HISTORY_MSG_188;CAM02 - Helligkeit (Q) -HISTORY_MSG_189;CAM02 - Kontrast (Q) -HISTORY_MSG_190;CAM02 - Sättigung (S) -HISTORY_MSG_191;CAM02 - Farbigkeit (M) -HISTORY_MSG_192;CAM02 - Farbton (H) -HISTORY_MSG_193;CAM02\nTonwertkurve 1 -HISTORY_MSG_194;CAM02\nTonwertkurve 2 -HISTORY_MSG_195;CAM02\nTonwertkurve 1\nModus -HISTORY_MSG_196;CAM02\nTonwertkurve 2\nModus -HISTORY_MSG_197;CAM02 - Farbkurve -HISTORY_MSG_198;CAM02 - Farbkurve\nModus -HISTORY_MSG_199;CAM02 - Ausgabe-\nHistogramm -HISTORY_MSG_200;CAM02\nDynamikkompression -HISTORY_MSG_201;Rauschreduzierung\nDelta-Chrominanz\nRot/Grün -HISTORY_MSG_202;Rauschreduzierung\nDelta-Chrominanz\nBlau/Gelb -HISTORY_MSG_203;Rauschreduzierung\nMethode -HISTORY_MSG_204;LMMSE-\nVerbesserung -HISTORY_MSG_205;CAM02 - Hot/Bad-\nPixelfilter -HISTORY_MSG_206;CAT02 - Auto-Szenen-\nLuminanz -HISTORY_MSG_207;Farbsaum entfernen\nFarbtonkurve -HISTORY_MSG_208;Weißabgleich\nBau/Rot-Korrektur -HISTORY_MSG_210;Grauverlaufsfilter\nRotationswinkel -HISTORY_MSG_211;Grauverlaufsfilter -HISTORY_MSG_212;Vignettierungsfilter\nIntensität -HISTORY_MSG_213;Vignettierungsfilter -HISTORY_MSG_214;Schwarz/Weiß -HISTORY_MSG_215;Schwarz/Weiß - Rot -HISTORY_MSG_216;Schwarz/Weiß - Grün -HISTORY_MSG_217;Schwarz/Weiß - Blau -HISTORY_MSG_218;Schwarz/Weiß\nGamma - Rot -HISTORY_MSG_219;Schwarz/Weiß\nGamma - Grün -HISTORY_MSG_220;Schwarz/Weiß\nGamma - Blau -HISTORY_MSG_221;Schwarz/Weiß\nFarbfilter -HISTORY_MSG_222;Schwarz/Weiß\nVorgaben -HISTORY_MSG_223;Schwarz/Weiß - Orange -HISTORY_MSG_224;Schwarz/Weiß - Gelb -HISTORY_MSG_225;Schwarz/Weiß - Cyan -HISTORY_MSG_226;Schwarz/Weiß - Magenta -HISTORY_MSG_227;Schwarz/Weiß - Violett -HISTORY_MSG_228;Schwarz/Weiß\nLuminanzequalizer -HISTORY_MSG_229;Schwarz/Weiß\nLuminanzequalizer -HISTORY_MSG_230;Schwarz/Weiß - Modus -HISTORY_MSG_231;Schwarz/Weiß\n“Bevor“-Kurve -HISTORY_MSG_232;Schwarz/Weiß\n“Bevor“-Kurventyp -HISTORY_MSG_233;Schwarz/Weiß\n“Danach“-Kurve -HISTORY_MSG_234;Schwarz/Weiß\n“Danach“-Kurventyp -HISTORY_MSG_235;Schwarz/Weiß\nAuto-Kanalmixer +HISTORY_MSG_113;L*a*b* - Hautfarbtöne\nschützen +HISTORY_MSG_114;Sensor Bayer-Matrix\nFarbinterpolation\nDCB-Iterationen +HISTORY_MSG_115;Sensor-Matrix\nFarbinterpolation\nFalschfarbenunterdrückung +HISTORY_MSG_116;Sensor Bayer-Matrix\nFarbinterpolation\nDCB-Verbesserung +HISTORY_MSG_117;Sensor Bayer-Matrix\nChromatische Aberration\nRot +HISTORY_MSG_118;Sensor Bayer-Matrix\nChromatische Aberration\nBlau +HISTORY_MSG_119;Sensor Bayer-Matrix\nVorverarbeitung\nZeilenrauschfilter +HISTORY_MSG_120;Sensor Bayer-Matrix\nVorverarbeitung\nGrün-Ausgleich +HISTORY_MSG_121;Sensor Bayer-Matrix\nChromatische Aberration\nAutomatische Korrektur +HISTORY_MSG_122;Dunkelbild\nAutomatische Auswahl +HISTORY_MSG_123;Dunkelbild - Datei +HISTORY_MSG_124;Weißpunkt\nKorrekturfaktor +HISTORY_MSG_125;Belichtungskorrektur\nLichter schützen +HISTORY_MSG_126;Weißbild - Datei +HISTORY_MSG_127;Weißbild\nAutomatische Auswahl +HISTORY_MSG_128;Weißbild\nUnschärferadius +HISTORY_MSG_129;Weißbild - Unschärfetyp +HISTORY_MSG_130;Autom. Verzeichnung +HISTORY_MSG_131;Rauschreduzierung\nLuminanz +HISTORY_MSG_132;Rauschreduzierung\nChrominanz +HISTORY_MSG_133;Farbmanagement\nAusgabeprofil\nAusgabe-Gamma +HISTORY_MSG_134;Farbmanagement\nAusgabeprofil\nGamma +HISTORY_MSG_135;Farbmanagement\nAusgabeprofil\nFreies Gamma +HISTORY_MSG_136;Farbmanagement\nAusgabeprofil\nGradient (linear) +HISTORY_MSG_137;Sensor Bayer-Matrix\nSchwarzpunkt - Grün 1 +HISTORY_MSG_138;Sensor Bayer-Matrix\nSchwarzpunkt - Rot +HISTORY_MSG_139;Sensor Bayer-Matrix\nSchwarzpunkt - Blau +HISTORY_MSG_140;Sensor Bayer-Matrix\nSchwarzpunkt - Grün 2 +HISTORY_MSG_141;Sensor Bayer-Matrix\nSchwarzpunkt\nGrün-Werte angleichen +HISTORY_MSG_142;Kantenschärfung\nIterationen +HISTORY_MSG_143;Kantenschärfung\nIntensität +HISTORY_MSG_144;Mikrokontrast\nIntensität +HISTORY_MSG_145;Mikrokontrast\nGleichmäßigkeit +HISTORY_MSG_146;Kantenschärfung +HISTORY_MSG_147;Kantenschärfung\nNur Luminanz +HISTORY_MSG_148;Mikrokontrast +HISTORY_MSG_149;Mikrokontrast\n3×3-Matrix +HISTORY_MSG_150;Artefakt-/Rauschred.\nnach Farbinterpolation +HISTORY_MSG_151;Dynamik +HISTORY_MSG_152;Dynamik - Pastelltöne +HISTORY_MSG_153;Dynamik\nGesättigte Töne +HISTORY_MSG_154;Dynamik\nHautfarbtöne schützen +HISTORY_MSG_155;Dynamik\nFarbverschiebungen\nvermeiden +HISTORY_MSG_156;Dynamik\nPastell und gesättigte\nTöne koppeln +HISTORY_MSG_157;Dynamik\nPastell/gesättigte Töne\nSchwellenwert +HISTORY_MSG_158;Dynamikkompression\nIntensität +HISTORY_MSG_159;Dynamikkompression\nKantenschutz +HISTORY_MSG_160;Dynamikkompression\nFaktor +HISTORY_MSG_161;Dynamikkompression\nIterationen +HISTORY_MSG_162;Dynamikkompression +HISTORY_MSG_163;RGB-Kurven - Rot +HISTORY_MSG_164;RGB-Kurven - Grün +HISTORY_MSG_165;RGB-Kurven - Blau +HISTORY_MSG_166;Belichtung - Zurücksetzen +HISTORY_MSG_167;Sensor-Matrix\nFarbinterpolation\nMethode +HISTORY_MSG_168;L*a*b* - CC-Kurve +HISTORY_MSG_169;L*a*b* - CH-Kurve +HISTORY_MSG_170;Dynamik - HH-Kurve +HISTORY_MSG_171;L*a*b* - LC-Kurve +HISTORY_MSG_172;L*a*b* - LC-Kurve\nbeschränken +HISTORY_MSG_173;Rauschreduzierung\nLuminanzdetails +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CIECAM02 - Szene\nCAT02-Adaptation +HISTORY_MSG_176;CIECAM02\nBetrachtungsbed.\nUmgebung +HISTORY_MSG_177;CIECAM02 - Szene\nLeuchtstärke +HISTORY_MSG_178;CIECAM02\nBetrachtungsbed.\nLeuchtstärke +HISTORY_MSG_179;CIECAM02 - Szene\nWeißpunktmodell +HISTORY_MSG_180;CIECAM02 - Helligkeit (J) +HISTORY_MSG_181;CIECAM02 - Buntheit (H) +HISTORY_MSG_182;CIECAM02 - Szene\nCAT02-Automatisch +HISTORY_MSG_183;CIECAM02 - Kontrast (J) +HISTORY_MSG_184;CIECAM02 - Szene\nDunkle Umgebung +HISTORY_MSG_185;CIECAM02\nBetrachtungsbed.\nGamutkontrolle +HISTORY_MSG_186;CIECAM02 - Algorithmus +HISTORY_MSG_187;CIECAM02 - Hautfarbtöne\nschützen +HISTORY_MSG_188;CIECAM02 - Helligkeit (Q) +HISTORY_MSG_189;CIECAM02 - Kontrast (Q) +HISTORY_MSG_190;CIECAM02 - Sättigung (S) +HISTORY_MSG_191;CIECAM02 - Farbigkeit (M) +HISTORY_MSG_192;CIECAM02 - Farbton (H) +HISTORY_MSG_193;CIECAM02\nTonwertkurve 1 +HISTORY_MSG_194;CIECAM02\nTonwertkurve 2 +HISTORY_MSG_195;CIECAM02\nTonwertkurve 1 - Modus +HISTORY_MSG_196;CIECAM02\nTonwertkurve 2 - Modus +HISTORY_MSG_197;CIECAM02 - Farbkurve +HISTORY_MSG_198;CIECAM02 - Farbkurve\nModus +HISTORY_MSG_199;CIECAM02 - Ausgabe-\nHistogramm anzeigen +HISTORY_MSG_200;CIECAM02\nDynamikkompression +HISTORY_MSG_201;Rauschreduzierung\nDelta-Chrominanz\nRot/Grün +HISTORY_MSG_202;Rauschreduzierung\nDelta-Chrominanz\nBlau/Gelb +HISTORY_MSG_203;Rauschreduzierung\nMethode +HISTORY_MSG_204;Sensor Bayer-Matrix\nFarbinterpolation\nLMMSE-Verbesserung +HISTORY_MSG_205;CIECAM02\nBetrachtungsbed.\nHot/Bad-Pixelfilter +HISTORY_MSG_206;CIECAM02 - Szene\nAuto-Leuchtstärke +HISTORY_MSG_207;Farbsaum entfernen\nFarbtonkurve +HISTORY_MSG_208;Weißabgleich\nBau/Rot-Korrektur +HISTORY_MSG_210;Grauverlaufsfilter\nRotationswinkel +HISTORY_MSG_211;Grauverlaufsfilter +HISTORY_MSG_212;Vignettierungsfilter\nIntensität +HISTORY_MSG_213;Vignettierungsfilter +HISTORY_MSG_214;Schwarz/Weiß +HISTORY_MSG_215;Schwarz/Weiß - Rot +HISTORY_MSG_216;Schwarz/Weiß - Grün +HISTORY_MSG_217;Schwarz/Weiß - Blau +HISTORY_MSG_218;Schwarz/Weiß\nGamma - Rot +HISTORY_MSG_219;Schwarz/Weiß\nGamma - Grün +HISTORY_MSG_220;Schwarz/Weiß\nGamma - Blau +HISTORY_MSG_221;Schwarz/Weiß\nFarbfilter +HISTORY_MSG_222;Schwarz/Weiß\nVorgaben +HISTORY_MSG_223;Schwarz/Weiß - Orange +HISTORY_MSG_224;Schwarz/Weiß - Gelb +HISTORY_MSG_225;Schwarz/Weiß - Cyan +HISTORY_MSG_226;Schwarz/Weiß - Magenta +HISTORY_MSG_227;Schwarz/Weiß - Violett +HISTORY_MSG_228;Schwarz/Weiß\nLuminanzequalizer +HISTORY_MSG_229;Schwarz/Weiß\nLuminanzequalizer +HISTORY_MSG_230;Schwarz/Weiß - Modus +HISTORY_MSG_231;Schwarz/Weiß\n“Bevor“-Kurve +HISTORY_MSG_232;Schwarz/Weiß\n“Bevor“-Kurventyp +HISTORY_MSG_233;Schwarz/Weiß\n“Danach“-Kurve +HISTORY_MSG_234;Schwarz/Weiß\n“Danach“-Kurventyp +HISTORY_MSG_235;Schwarz/Weiß\nAuto-Kanalmixer HISTORY_MSG_236;--unused-- -HISTORY_MSG_237;Schwarz/Weiß - Mixer -HISTORY_MSG_238;Grauverlaufsfilter\nBereich -HISTORY_MSG_239;Grauverlaufsfilter\nIntensität -HISTORY_MSG_240;Grauverlaufsfilter\nRotationsachsen -HISTORY_MSG_241;Vignettierungsfilter\nBereich -HISTORY_MSG_242;Vignettierungsfilter\nRundung -HISTORY_MSG_243;Objektivkorrektur\nVignettierung\nRadius -HISTORY_MSG_244;Objektivkorrektur\nVignettierung\nFaktor -HISTORY_MSG_245;Objektivkorrektur\nVignettierung\nZentrum -HISTORY_MSG_246;L*a*b* - CL-Kurve -HISTORY_MSG_247;L*a*b* - LH-Kurve -HISTORY_MSG_248;L*a*b* - BB-Kurve -HISTORY_MSG_249;Kontrast nach\nDetailebenen\nSchwellenwert -HISTORY_MSG_250;Rauschreduzierung\nVerbesserung -HISTORY_MSG_251;Schwarz/Weiß\nAlgorithmus -HISTORY_MSG_252;Kontrast nach\nDetailebenen\nHautfarbtöne\nändern/schützen -HISTORY_MSG_253;Kontrast nach\nDetailebenen\nArtefakte reduzieren -HISTORY_MSG_254;Kontrast nach\nDetailebenen\nHautfarbton -HISTORY_MSG_255;Rauschreduzierung\nMedianfilter -HISTORY_MSG_256;Rauschreduzierung\nMediantyp -HISTORY_MSG_257;Farbanpassungen -HISTORY_MSG_258;Farbanpassungen\nFarbkurve -HISTORY_MSG_259;Farbanpassungen\nDeckkraftkurve -HISTORY_MSG_260;Farbanpassungen\na*[b*]-Transparenz -HISTORY_MSG_261;Farbanpassungen\nMethode -HISTORY_MSG_262;Farbanpassungen\nb*-Transparenz -HISTORY_MSG_263;Farbanpassungen\nSchatten - Blau/Rot -HISTORY_MSG_264;Farbanpassungen\nSchatten - Cyan/Grün -HISTORY_MSG_265;Farbanpassungen\nSchatten - Gelb/Blau -HISTORY_MSG_266;Farbanpassungen\nMitten - Blau/Rot -HISTORY_MSG_267;Farbanpassungen\nMitten - Cyan/Grün -HISTORY_MSG_268;Farbanpassungen\nMitten - Gelb/Blau -HISTORY_MSG_269;Farbanpassungen\nLichter - Bau/Rot -HISTORY_MSG_270;Farbanpassungen\nLichter - Cyan/Grün -HISTORY_MSG_271;Farbanpassungen\nLichter - GelbBlau -HISTORY_MSG_272;Farbanpassungen\nFarbausgleich -HISTORY_MSG_273;Farbanpassungen\nZurücksetzen -HISTORY_MSG_274;Farbanpassungen\nSättigung Schatten -HISTORY_MSG_275;Farbanpassungen\nSättigung Lichter -HISTORY_MSG_276;Farbanpassungen\nDeckkraft +HISTORY_MSG_237;Schwarz/Weiß - Mixer +HISTORY_MSG_238;Grauverlaufsfilter\nBereich +HISTORY_MSG_239;Grauverlaufsfilter\nIntensität +HISTORY_MSG_240;Grauverlaufsfilter\nRotationsachsen +HISTORY_MSG_241;Vignettierungsfilter\nBereich +HISTORY_MSG_242;Vignettierungsfilter\nForm +HISTORY_MSG_243;Objektivkorrektur\nVignettierung - Radius +HISTORY_MSG_244;Objektivkorrektur\nVignettierung - Faktor +HISTORY_MSG_245;Objektivkorrektur\nVignettierung - Zentrum +HISTORY_MSG_246;L*a*b* - CL-Kurve +HISTORY_MSG_247;L*a*b* - LH-Kurve +HISTORY_MSG_248;L*a*b* - HH-Kurve +HISTORY_MSG_249;Detailebenenkontrast\nSchwellenwert +HISTORY_MSG_250;Rauschreduzierung\nVerbesserung +HISTORY_MSG_251;Schwarz/Weiß\nAlgorithmus +HISTORY_MSG_252;Detailebenenkontrast\nHautfarbtöne schützen +HISTORY_MSG_253;Detailebenenkontrast\nArtefakte reduzieren +HISTORY_MSG_254;Detailebenenkontrast\nHautfarbton +HISTORY_MSG_255;Rauschreduzierung\nMedianfilter +HISTORY_MSG_256;Rauschreduzierung\nMediantyp +HISTORY_MSG_257;Farbanpassungen +HISTORY_MSG_258;Farbanpassungen\nFarbkurve +HISTORY_MSG_259;Farbanpassungen\nDeckkraftkurve +HISTORY_MSG_260;Farbanpassungen\na*[b*]-Transparenz +HISTORY_MSG_261;Farbanpassungen\nMethode +HISTORY_MSG_262;Farbanpassungen\nb*-Transparenz +HISTORY_MSG_263;Farbanpassungen\nSchatten - Blau/Rot +HISTORY_MSG_264;Farbanpassungen\nSchatten - Cyan/Grün +HISTORY_MSG_265;Farbanpassungen\nSchatten - Gelb/Blau +HISTORY_MSG_266;Farbanpassungen\nMitten - Blau/Rot +HISTORY_MSG_267;Farbanpassungen\nMitten - Cyan/Grün +HISTORY_MSG_268;Farbanpassungen\nMitten - Gelb/Blau +HISTORY_MSG_269;Farbanpassungen\nLichter - Bau/Rot +HISTORY_MSG_270;Farbanpassungen\nLichter - Cyan/Grün +HISTORY_MSG_271;Farbanpassungen\nLichter - GelbBlau +HISTORY_MSG_272;Farbanpassungen\nFarbausgleich +HISTORY_MSG_273;Farbanpassungen\nZurücksetzen +HISTORY_MSG_274;Farbanpassungen\nSättigung Schatten +HISTORY_MSG_275;Farbanpassungen\nSättigung Lichter +HISTORY_MSG_276;Farbanpassungen\nDeckkraft HISTORY_MSG_277;--unused-- -HISTORY_MSG_278;Farbanpassungen\nLuminanz schützen -HISTORY_MSG_279;Farbanpassungen\nSchatten -HISTORY_MSG_280;Farbanpassungen\nLichter -HISTORY_MSG_281;Farbanpassungen\nSättigung schützen\nIntensität -HISTORY_MSG_282;Farbanpassungen\nSättigung schützen\nSchwellenwert -HISTORY_MSG_283;Farbanpassungen\nIntensität -HISTORY_MSG_284;Farbanpassungen\nSättigung schützen\nAutomatisch -HISTORY_MSG_285;Rauschreduzierung\nMedianmethode -HISTORY_MSG_286;Rauschreduzierung\nMediantyp -HISTORY_MSG_287;Rauschreduzierung\nMedianiterationen -HISTORY_MSG_288;Weißbild\nKontrolle zu heller\nBereiche -HISTORY_MSG_289;Weißbild\nAuto-Kontrolle zu\nheller Bereiche -HISTORY_MSG_290;Schwarzpunkt - Rot -HISTORY_MSG_291;Schwarzpunkt - Grün -HISTORY_MSG_292;Schwarzpunkt - Blau -HISTORY_MSG_293;Filmsimulation -HISTORY_MSG_294;Filmsimulation - Intensität -HISTORY_MSG_295;Filmsimulation - Film -HISTORY_MSG_296;Rauschreduzierung\nLuminanzkurve -HISTORY_MSG_297;Rauschreduzierung\nQualität -HISTORY_MSG_298;Vorverarbeitung\nDead-Pixel-Filter -HISTORY_MSG_299;Rauschreduzierung\nChrominanzkurve +HISTORY_MSG_278;Farbanpassungen\nLuminanz schützen +HISTORY_MSG_279;Farbanpassungen\nSchatten +HISTORY_MSG_280;Farbanpassungen\nLichter +HISTORY_MSG_281;Farbanpassungen\nSättigung schützen\nIntensität +HISTORY_MSG_282;Farbanpassungen\nSättigung schützen\nSchwellenwert +HISTORY_MSG_283;Farbanpassungen\nIntensität +HISTORY_MSG_284;Farbanpassungen\nSättigung schützen\nAutomatisch +HISTORY_MSG_285;Rauschreduzierung\nMedianmethode +HISTORY_MSG_286;Rauschreduzierung\nMediantyp +HISTORY_MSG_287;Rauschreduzierung\nMedianiterationen +HISTORY_MSG_288;Weißbild\nKontrolle zu heller Bereiche +HISTORY_MSG_289;Weißbild\nAuto-Kontrolle zu\nheller Bereiche +HISTORY_MSG_290;Sensor X-Trans-Matrix\nSchwarzpunkt - Rot +HISTORY_MSG_291;Sensor X-Trans-Matrix\nSchwarzpunkt - Grün +HISTORY_MSG_292;Sensor X-Trans-Matrix\nSchwarzpunkt - Blau +HISTORY_MSG_293;Filmsimulation +HISTORY_MSG_294;Filmsimulation\nIntensität +HISTORY_MSG_295;Filmsimulation - Film +HISTORY_MSG_296;Rauschreduzierung\nLuminanzkurve +HISTORY_MSG_297;Rauschreduzierung\nQualität +HISTORY_MSG_298;Vorverarbeitung\nDead-Pixel-Filter +HISTORY_MSG_299;Rauschreduzierung\nChrominanzkurve HISTORY_MSG_300;- -HISTORY_MSG_301;Rauschreduzierung\nLumakontrolle -HISTORY_MSG_302;Rauschreduzierung\nChrominanz\nMethode -HISTORY_MSG_303;Rauschreduzierung\nChrominanz\nMethode -HISTORY_MSG_304;Wavelet\nKontrastebenen -HISTORY_MSG_305;Wavelet -HISTORY_MSG_306;Wavelet - Einstellungen\nVerarbeitungsebene -HISTORY_MSG_307;Wavelet - Einstellungen\nVerarbeitung -HISTORY_MSG_308;Wavelet - Einstellungen\nVerarbeitungsrichtung -HISTORY_MSG_309;Wavelet\nKantenschärfung\nDetails -HISTORY_MSG_310;Wavelet - Nachbild\nHimmelsfarbtöne\nändern/schützen -HISTORY_MSG_311;Wavelet - Einstellungen\nWaveletebenen -HISTORY_MSG_312;Wavelet - Nachbild\nSchatten Schwellenwert -HISTORY_MSG_313;Wavelet\nFarbe\nSättigung -HISTORY_MSG_314;Wavelet\nGamut\nArtefakte reduzieren -HISTORY_MSG_315;Wavelet - Nachbild\nKontrast -HISTORY_MSG_316;Wavelet - Gamut\nHautfarbtöne\nändern/schützen -HISTORY_MSG_317;Wavelet - Gamut\nHautfarbton -HISTORY_MSG_318;Wavelet - Kontrast\nLichterebenen -HISTORY_MSG_319;Wavelet - Kontrast\nLichterbereich -HISTORY_MSG_320;Wavelet - Kontrast\nSchattenbereich -HISTORY_MSG_321;Wavelet - Kontrast\nSchattenebenen -HISTORY_MSG_322;Wavelet - Gamut\nFarbverschiebungen\nvermeiden -HISTORY_MSG_323;Wavelet\nKantenschärfung\nLokaler Kontrast -HISTORY_MSG_324;Wavelet - Farbe\nPastellfarben -HISTORY_MSG_325;Wavelet - Farbe\nGesättigt Farben -HISTORY_MSG_326;Wavelet - Farbe\nMethode -HISTORY_MSG_327;Wavelet - Kontrast\nAnwenden auf -HISTORY_MSG_328;Wavelet - Farbe\nVerlinkungsstärke -HISTORY_MSG_329;Wavelet - Tönung\nDeckkraft Rot/Grün -HISTORY_MSG_330;Wavelet - Tönung\nDeckkraft Blau/Gelb -HISTORY_MSG_331;Wavelet\nKontrastebenen\nExtra -HISTORY_MSG_332;Wavelet- -Einstellungen\nKachelgröße -HISTORY_MSG_333;Wavelet - Nachbild\nSchatten -HISTORY_MSG_334;Wavelet - Nachbild\nBuntheit -HISTORY_MSG_335;Wavelet - Nachbild\nLichter -HISTORY_MSG_336;Wavelet - Nachbild\nLichter Schwellenwert -HISTORY_MSG_337;Wavelet - Nachbild\nHimmelsfarbton -HISTORY_MSG_338;Wavelet\nKantenschärfung\nRadius -HISTORY_MSG_339;Wavelet\nKantenschärfung\nIntensität -HISTORY_MSG_340;Wavelet - Einstellungen\nIntensität -HISTORY_MSG_341;Wavelet - Einstellungen\nKantenperformance -HISTORY_MSG_342;Wavelet\nKantenschärfung\nErste Ebene -HISTORY_MSG_343;Wavelet - Farbe\nFarbebenen -HISTORY_MSG_344;Wavelet\nFarbemethode\nRegler/Kurve -HISTORY_MSG_345;Wavelet\nKantenschärfung\nLokaler Kontrast -HISTORY_MSG_346;Wavelet\nKantenschärfung\nLokale Kontrastmethode -HISTORY_MSG_347;Wavelet\nRauschreduzierung\nEbene 1 -HISTORY_MSG_348;Wavelet\nRauschreduzierung\nEbene 2 -HISTORY_MSG_349;Wavelet\nRauschreduzierung\nEbene 3 -HISTORY_MSG_350;Wavelet\nKantenschärfung\nKantenerkennung -HISTORY_MSG_351;Wavelet - Nachbild\nHH-Kurve -HISTORY_MSG_352;Wavelet - Einstellungen\nHintergrund -HISTORY_MSG_353;Wavelet\nKantenschärfung\nGradienten-\nempfindlichkeit -HISTORY_MSG_354;Wavelet\nKantenschärfung\nErweitert -HISTORY_MSG_355;Wavelet\nKantenschärfung\nSchwellenwert niedrig -HISTORY_MSG_356;Wavelet\nKantenschärfung\nSchwellenwert hoch -HISTORY_MSG_357;Wavelet\nRauschreduzierung\nSchärfung -HISTORY_MSG_358;Wavelet - Gamut\nKontrastkurve -HISTORY_MSG_359;Vorverarbeitung\nHot/Dead-Pixel\nSchwellenwert -HISTORY_MSG_360;Dynamikkompression\nGamma -HISTORY_MSG_361;Wavelet - Endretusche\nFarbausgleich -HISTORY_MSG_362;Wavelet - Nachbild\nKompression -HISTORY_MSG_363;Wavelet - Nachbild\nKompressionsstärke -HISTORY_MSG_364;Wavelet - Endretusche\nKontrastausgleich -HISTORY_MSG_365;Wavelet - Endretusche\nDelta-Ausgleich -HISTORY_MSG_366;Wavelet - Nachbild\nGammakompression -HISTORY_MSG_367;Wavelet\nKantenschärfung\nLokale Kontrastkurve -HISTORY_MSG_368;Wavelet - Endretusche\nKontrastausgleich -HISTORY_MSG_369;Wavelet - Endretusche\nKontrastmethode -HISTORY_MSG_370;Wavelet - Endretusche\nLokale Kontrastkurve -HISTORY_MSG_371;Nach Größenänderung\nschärfen -HISTORY_MSG_372;Größe ändern\nSchärfen - USM\nRadius -HISTORY_MSG_373;Größe ändern\nSchärfen - USM\nIntensität -HISTORY_MSG_374;Größe ändern\nSchärfen - USM\nSchwellenwert -HISTORY_MSG_375;Größe ändern\nSchärfen - USM\nNur Kanten schärfen -HISTORY_MSG_376;Größe ändern\nSchärfen - USM\nKantenerkennung Radius -HISTORY_MSG_377;Größe ändern\nSchärfen - USM\nKantentoleranz -HISTORY_MSG_378;Größe ändern\nSchärfen - USM\nHalokontrolle -HISTORY_MSG_379;Größe ändern\nSchärfen - USM\nHalokontrolle Intensität -HISTORY_MSG_380;Größe ändern\nSchärfen - Methode -HISTORY_MSG_381;Größe ändern\nSchärfen - RLD\nRadius -HISTORY_MSG_382;Größe ändern\nSchärfen - RLD\nIntensität -HISTORY_MSG_383;Größe ändern\nSchärfen - RLD\nDämpfung -HISTORY_MSG_384;Größe ändern\nSchärfen - RLD\nIterationen -HISTORY_MSG_385;Wavelet - Nachbild\nFarbausgleich -HISTORY_MSG_386;Wavelet - Nachbild\nFarbausgleich\nLichter Grün/Cyan -HISTORY_MSG_387;Wavelet - Nachbild\nFarbausgleich\nLichter Blau/Gelb -HISTORY_MSG_388;Wavelet - Nachbild\nFarbausgleich\nMitten Grün/Cyan -HISTORY_MSG_389;Wavelet - Nachbild\nFarbausgleich\nMitten Blau/Gelb -HISTORY_MSG_390;Wavelet - Nachbild\nFarbausgleich\nSchatten Grün/Cyan -HISTORY_MSG_391;Wavelet - Nachbild\nFarbausgleich\nSchatten Blau/Gelb -HISTORY_MSG_392;Wavelet - Nachbild\nFarbausgleich -HISTORY_MSG_393;Eingangsfarbprofil\nDCP\nLook-Tabelle -HISTORY_MSG_394;Eingangsfarbprofil\nDCP\nAusgangsbelichtung -HISTORY_MSG_395;Eingangsfarbprofil\nDCP\nBasistabelle -HISTORY_MSG_396;Wavelet - Kontrast -HISTORY_MSG_397;Wavelet - Farbe -HISTORY_MSG_398;Wavelet\nKantenschärfung -HISTORY_MSG_399;Wavelet - Nachbild -HISTORY_MSG_400;Wavelet - Endretusche -HISTORY_MSG_401;Wavelet - Tönung -HISTORY_MSG_402;Wavelet\nRauschreduzierung -HISTORY_MSG_403;Wavelet\nKantenschärfung\nKantenempfindlichkeit -HISTORY_MSG_404;Wavelet\nKantenschärfung\nGrundverstärkung -HISTORY_MSG_405;Wavelet\nRauschreduzierung\nEbene 4 -HISTORY_MSG_406;Wavelet\nKantenschärfung\nNachbarpixel -HISTORY_MSG_407;Retinex - Methode -HISTORY_MSG_408;Retinex\nBenachbarte Pixel -HISTORY_MSG_409;Retinex - Verstärkung -HISTORY_MSG_410;Retinex - Versatz -HISTORY_MSG_411;Retinex - Intensität -HISTORY_MSG_412;Retinex - Skalierung -HISTORY_MSG_413;Retinex - Abweichung -HISTORY_MSG_414;Retinex\nLuminanz(L)\nL*a*b* -HISTORY_MSG_415;Retinex\nTransmissionskurve -HISTORY_MSG_416;Retinex -HISTORY_MSG_417;Retinex\nTransmission median -HISTORY_MSG_418;Retinex - Transmission\nSchwellenwert -HISTORY_MSG_419;Retinex - Farbraum -HISTORY_MSG_420;Retinex\nHSL-Kurve -HISTORY_MSG_421;Retinex\nGammakorrektur -HISTORY_MSG_422;Retinex - Gamma -HISTORY_MSG_423;Retinex\nGammasteigung -HISTORY_MSG_424;Retinex\nHL-Schwellenwert -HISTORY_MSG_425;Retinex\nBasis-Logarithmus -HISTORY_MSG_426;Retinex - Farbton (H) +HISTORY_MSG_301;Rauschreduzierung\nLuminanzkontrolle +HISTORY_MSG_302;Rauschreduzierung\nChrominanz - Methode +HISTORY_MSG_303;Rauschreduzierung\nChrominanz - Methode +HISTORY_MSG_304;Wavelet\nKontrastebenen +HISTORY_MSG_305;Wavelet +HISTORY_MSG_306;Wavelet - Einstellungen\nVerarbeitungsebene +HISTORY_MSG_307;Wavelet - Einstellungen\nVerarbeitung +HISTORY_MSG_308;Wavelet - Einstellungen\nVerarbeitungsrichtung +HISTORY_MSG_309;Wavelet\nKantenschärfung\nDetails +HISTORY_MSG_310;Wavelet - Restbild\nHimmelsfarbtöne\nschützen +HISTORY_MSG_311;Wavelet - Einstellungen\nAnzahl der Ebenen +HISTORY_MSG_312;Wavelet - Restbild\nSchatten Schwellenwert +HISTORY_MSG_313;Wavelet - Farbe\nEbenengrenze +HISTORY_MSG_314;Wavelet - Gamut\nArtefakte reduzieren +HISTORY_MSG_315;Wavelet - Restbild\nKontrast +HISTORY_MSG_316;Wavelet - Gamut\nHautfarbtöne schützen +HISTORY_MSG_317;Wavelet - Gamut\nHautfarbton +HISTORY_MSG_318;Wavelet - Kontrast\nLichterebenen +HISTORY_MSG_319;Wavelet - Kontrast\nLichter-Luminanzbereich +HISTORY_MSG_320;Wavelet - Kontrast\nSchatten-Luminanzbereich +HISTORY_MSG_321;Wavelet - Kontrast\nSchattenebenen +HISTORY_MSG_322;Wavelet - Gamut\nFarbverschiebungen\nvermeiden +HISTORY_MSG_323;Wavelet\nKantenschärfung\nLokale Kontrastkurve +HISTORY_MSG_324;Wavelet - Farbe\nPastellfarben +HISTORY_MSG_325;Wavelet - Farbe\nGesättigte Farben +HISTORY_MSG_326;Wavelet - Farbe\nChrominanzethode +HISTORY_MSG_327;Wavelet - Kontrast\nAnwenden auf +HISTORY_MSG_328;Wavelet - Farbe\nFarb-Kontrast-\nVerknüpfung +HISTORY_MSG_329;Wavelet - Tönung\nDeckkraft Rot/Grün +HISTORY_MSG_330;Wavelet - Tönung\nDeckkraft Blau/Gelb +HISTORY_MSG_331;Wavelet\nKontrastebenen\nExtra +HISTORY_MSG_332;Wavelet- -Einstellungen\nKachelgröße +HISTORY_MSG_333;Wavelet - Restbild\nSchatten +HISTORY_MSG_334;Wavelet - Restbild\nBuntheit +HISTORY_MSG_335;Wavelet - Restbild\nLichter +HISTORY_MSG_336;Wavelet - Restbild\nLichter Schwellenwert +HISTORY_MSG_337;Wavelet - Restbild\nHimmelsfarbton +HISTORY_MSG_338;Wavelet\nKantenschärfung\nRadius +HISTORY_MSG_339;Wavelet\nKantenschärfung\nIntensität +HISTORY_MSG_340;Wavelet - Einstellungen\nIntensität +HISTORY_MSG_341;Wavelet - Einstellungen\nKantenperformance +HISTORY_MSG_342;Wavelet\nKantenschärfung\nErste Ebene +HISTORY_MSG_343;Wavelet - Farbe\nFarbebenen +HISTORY_MSG_344;Wavelet\nFarbmethode\nRegler/Kurve +HISTORY_MSG_345;Wavelet\nKantenschärfung\nLokaler Kontrast +HISTORY_MSG_346;Wavelet\nKantenschärfung\nLokale Kontrastmethode +HISTORY_MSG_347;Wavelet\nRauschreduzierung\nEbene 1 +HISTORY_MSG_348;Wavelet\nRauschreduzierung\nEbene 2 +HISTORY_MSG_349;Wavelet\nRauschreduzierung\nEbene 3 +HISTORY_MSG_350;Wavelet\nKantenschärfung\nKantenerkennung +HISTORY_MSG_351;Wavelet - Restbild\nHH-Kurve +HISTORY_MSG_352;Wavelet - Einstellungen\nHintergrund +HISTORY_MSG_353;Wavelet\nKantenschärfung\nGradientenempfindlichkeit +HISTORY_MSG_354;Wavelet\nKantenschärfung\nErweiterter Algorithmus +HISTORY_MSG_355;Wavelet\nKantenschärfung\nSchwellenwert niedrig +HISTORY_MSG_356;Wavelet\nKantenschärfung\nSchwellenwert hoch +HISTORY_MSG_357;Wavelet\nRauschreduzierung\nSchärfung verknüpfen +HISTORY_MSG_358;Wavelet - Gamut\nKontrastkurve +HISTORY_MSG_359;Vorverarbeitung\nHot/Dead-Pixel-Filter\nSchwellenwert +HISTORY_MSG_360;Dynamikkompression\nGamma +HISTORY_MSG_361;Wavelet - Endretusche\nFarbausgleich +HISTORY_MSG_362;Wavelet - Restbild\nKompression +HISTORY_MSG_363;Wavelet - Restbild\nKompression - Intensität +HISTORY_MSG_364;Wavelet - Endretusche\nKontrastausgleich +HISTORY_MSG_365;Wavelet - Endretusche\nDelta-Kontrastausgleich +HISTORY_MSG_366;Wavelet - Restbild\nGammakompression +HISTORY_MSG_367;Wavelet - Endretusche\n"Danach"-Kontrastkurve +HISTORY_MSG_368;Wavelet - Endretusche\nKontrastausgleichskurve +HISTORY_MSG_369;Wavelet - Endretusche\nKontrastmethode +HISTORY_MSG_370;Wavelet - Endretusche\nLokale Kontrastkurve +HISTORY_MSG_371;Skalieren - Schärfen +HISTORY_MSG_372;Skalieren - Schärfen\nUSM - Radius +HISTORY_MSG_373;Skalieren - Schärfen\nUSM - Intensität +HISTORY_MSG_374;Skalieren - Schärfen\nUSM - Schwellenwert +HISTORY_MSG_375;Skalieren - Schärfen\nUSM - Nur Kanten\nschärfen +HISTORY_MSG_376;Skalieren - Schärfen\nUSM - Kantenschärfung\nRadius +HISTORY_MSG_377;Skalieren - Schärfen\nUSM - Kantentoleranz +HISTORY_MSG_378;Skalieren - Schärfen\nUSM - Halokontrolle +HISTORY_MSG_379;Skalieren - Schärfen\nUSM - Halokontrolle\nIntensität +HISTORY_MSG_380;Skalieren - Schärfen\nMethode +HISTORY_MSG_381;Skalieren - Schärfen\nRLD - Radius +HISTORY_MSG_382;Skalieren - Schärfen\nRLD - Intensität +HISTORY_MSG_383;Skalieren - Schärfen\nRLD - Dämpfung +HISTORY_MSG_384;Skalieren - Schärfen\nRLD - Iterationen +HISTORY_MSG_385;Wavelet - Restbild\nFarbausgleich +HISTORY_MSG_386;Wavelet - Restbild\nFarbausgleich\nLichter Grün/Cyan +HISTORY_MSG_387;Wavelet - Restbild\nFarbausgleich\nLichter Blau/Gelb +HISTORY_MSG_388;Wavelet - Restbild\nFarbausgleich\nMitten Grün/Cyan +HISTORY_MSG_389;Wavelet - Restbild\nFarbausgleich\nMitten Blau/Gelb +HISTORY_MSG_390;Wavelet - Restbild\nFarbausgleich\nSchatten Grün/Cyan +HISTORY_MSG_391;Wavelet - Restbild\nFarbausgleich\nSchatten Blau/Gelb +HISTORY_MSG_392;Wavelet - Restbild\nFarbausgleich +HISTORY_MSG_393;Farbmanagement\nEingangsfarbprofil\nDCP - Look-Tabelle +HISTORY_MSG_394;Farbmanagement\nEingangsfarbprofil\nDCP - Ausgangsbelichtung +HISTORY_MSG_395;Farbmanagement\nEingangsfarbprofil\nDCP - Basistabelle +HISTORY_MSG_396;Wavelet - Kontrast +HISTORY_MSG_397;Wavelet - Farbe +HISTORY_MSG_398;Wavelet\nKantenschärfung +HISTORY_MSG_399;Wavelet - Restbild +HISTORY_MSG_400;Wavelet - Endretusche +HISTORY_MSG_401;Wavelet - Tönung +HISTORY_MSG_402;Wavelet\nRauschreduzierung +HISTORY_MSG_403;Wavelet\nKantenschärfung\nKantenempfindlichkeit +HISTORY_MSG_404;Wavelet\nKantenschärfung\nGrundverstärkung +HISTORY_MSG_405;Wavelet\nRauschreduzierung\nEbene 4 +HISTORY_MSG_406;Wavelet\nKantenschärfung\nBenachbarte Pixel +HISTORY_MSG_407;Retinex - Methode +HISTORY_MSG_408;Retinex\nBenachbarte Pixel +HISTORY_MSG_409;Retinex - Einstellungen\nVerstärkung +HISTORY_MSG_410;Retinex - Einstellungen\nVersatz +HISTORY_MSG_411;Retinex - Intensität +HISTORY_MSG_412;Retinex - Skalierung +HISTORY_MSG_413;Retinex - Abweichung +HISTORY_MSG_414;Retinex - Einstellungen\nLuminanz(L) - L*a*b* +HISTORY_MSG_415;Retinex - Einstellungen\nTransmissionskurve +HISTORY_MSG_416;Retinex +HISTORY_MSG_417;Retinex - Einstellungen\nTransmission Median-\nfilter +HISTORY_MSG_418;Retinex - Einstellungen\nTransmission\nSchwellenwert +HISTORY_MSG_419;Retinex - Farbraum +HISTORY_MSG_420;Retinex - Einstellungen\nHSL-Kurve +HISTORY_MSG_421;Retinex - Einstellungen\nGammakorrektur +HISTORY_MSG_422;Retinex - Einstellungen\nGamma +HISTORY_MSG_423;Retinex - Einstellungen\nGammasteigung +HISTORY_MSG_424;Retinex - Einstellungen\nHL-Schwellenwert +HISTORY_MSG_425;Retinex - Einstellungen\nBasis-Logarithmus +HISTORY_MSG_426;Retinex - Einstellungen\nFarbton (H) HISTORY_NEWSNAPSHOT;Hinzufügen HISTORY_NEWSNAPSHOT_TOOLTIP;Taste: Alt + s HISTORY_SNAPSHOT;Schnappschuss @@ -824,10 +826,10 @@ PARTIALPASTE_DEFRINGE;Farbsaum entfernen (Defringe) PARTIALPASTE_DETAILGROUP;Gruppe Detaileinstellungen PARTIALPASTE_DIALOGLABEL;Selektives Einfügen des Bearbeitungsprofils PARTIALPASTE_DIRPYRDENOISE;Rauschreduzierung -PARTIALPASTE_DIRPYREQUALIZER;Kontrast nach Detailebenen +PARTIALPASTE_DIRPYREQUALIZER;Detailebenenkontrast PARTIALPASTE_DISTORTION;Verzeichnungskorrektur PARTIALPASTE_EPD;Dynamikkompression -PARTIALPASTE_EQUALIZER;Waveletebenen +PARTIALPASTE_EQUALIZER;Anzahl der Ebenen PARTIALPASTE_EVERYTHING;Alles PARTIALPASTE_EXIFCHANGES;Änderungen an Exif-Daten PARTIALPASTE_EXPOSURE;Belichtung @@ -855,16 +857,16 @@ PARTIALPASTE_PREPROCESS_LINEDENOISE;Vorverarbeitung: Zeilenrauschfilter PARTIALPASTE_RAWCACORR_AUTO;Chromatische Aberration: Automatische Korrektur PARTIALPASTE_RAWCACORR_CABLUE;Chromatische Aberration: Blau PARTIALPASTE_RAWCACORR_CARED;Chromatische Aberration: Rot -PARTIALPASTE_RAWEXPOS_BLACK;RAW-Weiß/Schwarz-Punkt: Schwarzpegel -PARTIALPASTE_RAWEXPOS_LINEAR;RAW-Weiß/Schwarz-Punkt: Linearer Korrekturfaktor -PARTIALPASTE_RAWEXPOS_PRESER;RAW-Weiß/Schwarz-Punkt: Lichter schützen (EV) +PARTIALPASTE_RAWEXPOS_BLACK;Weißpunkt: Schwarzpegel +PARTIALPASTE_RAWEXPOS_LINEAR;Weißpunkt: Korrekturfaktor +PARTIALPASTE_RAWEXPOS_PRESER;Weißpunkt: Lichter schützen (EV) PARTIALPASTE_RAWGROUP;Gruppe RAW PARTIALPASTE_RAW_DCBENHANCE;Farbinterpolation: DCB-Verbesserung PARTIALPASTE_RAW_DCBITERATIONS;Farbinterpolation: Anzahl der DCB-Iterationen -PARTIALPASTE_RAW_DMETHOD;Demosaikmethode +PARTIALPASTE_RAW_DMETHOD;Farbinterpolation: Methode PARTIALPASTE_RAW_FALSECOLOR;Farbinterpolation: Falschfarbenunterdrückung -PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE-Verbesserungsstufen -PARTIALPASTE_RESIZE;Größe ändern +PARTIALPASTE_RAW_LMMSEITERATIONS;Farbinterpolation: LMMSE-Verbesserungsstufen +PARTIALPASTE_RESIZE;Skalieren PARTIALPASTE_RETINEX;Retinex (Bildschleier entfernen) PARTIALPASTE_RGBCURVES;RGB-Kurven PARTIALPASTE_ROTATION;Drehen @@ -1071,6 +1073,7 @@ PREFERENCES_TISTD;Standard PREFERENCES_TP_LABEL;Werkzeugbereich: PREFERENCES_TP_USEICONORTEXT;Symbole statt Text in Karteireitern PREFERENCES_TP_VSCROLLBAR;Keine vertikale Laufleiste +PREFERENCES_TUNNELMETADATA;Exif/XMP unverändert in die Ausgabedatei übernehmen. PREFERENCES_USEBUNDLEDPROFILES;Standardprofile verwenden PREFERENCES_USESYSTEMTHEME;Systemoberfläche verwenden PREFERENCES_VIEW;Weißabgleich-Einstellung des Ausgabegerätes (Monitor, TV, Projektor, usw.) @@ -1222,7 +1225,7 @@ TP_COLORAPP_ADAP_AUTO_TOOLTIP;Wenn aktiviert (empfohlen), werden die optimalen W TP_COLORAPP_ALGO;Algorithmus TP_COLORAPP_ALGO_ALL;Alle TP_COLORAPP_ALGO_JC;Helligkeit + Buntheit (JH) -TP_COLORAPP_ALGO_JS;Helligkeit+ Sättigung (JS) +TP_COLORAPP_ALGO_JS;Helligkeit + Sättigung (JS) TP_COLORAPP_ALGO_QM;Helligkeit + Farbigkeit (QM) TP_COLORAPP_ALGO_TOOLTIP;Auswahl zwischen Parameter-Teilmengen und allen Parametern TP_COLORAPP_BADPIXSL;Hot/Bad-Pixelfilter @@ -1415,13 +1418,13 @@ TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fein: Ist näher an den Hautfarbtönen und minim TP_DIRPYREQUALIZER_ARTIF;Artefakte reduzieren TP_DIRPYREQUALIZER_HUESKIN;Hautfarbton TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;Wenn Sie den Bereich signifikant nach Links oder Rechts verschieben müssen, ist der Weißabgleich nicht richtig gewählt.\n\nWählen Sie den eingeschlossenen Bereich so eng wie möglich, um den Einfluss auf benachbarte Farben zu verhindern. -TP_DIRPYREQUALIZER_LABEL;Kontrast nach Detailebenen +TP_DIRPYREQUALIZER_LABEL;Detailebenenkontrast TP_DIRPYREQUALIZER_LUMACOARSEST;Grob TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Kontrast - TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Kontrast + TP_DIRPYREQUALIZER_LUMAFINEST;Fein TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral -TP_DIRPYREQUALIZER_SKIN;Hautfarbtöne ändern/schützen +TP_DIRPYREQUALIZER_SKIN;Hautfarbtöne schützen TP_DIRPYREQUALIZER_SKIN_TOOLTIP;-100: Nur Farben innerhalb des Bereichs werden verändert.\n0: Alle Farben werden gleich behandelt.\n+100: Nur Farben außerhalb des Bereichs werden verändert. TP_DIRPYREQUALIZER_THRESHOLD;Schwellenwert TP_DIRPYREQUALIZER_TOOLTIP;Verringert Artefakte an den Übergängen zwischen Hautfarbtöne und dem Rest des Bildes. @@ -1583,12 +1586,13 @@ TP_LENSPROFILE_LABEL;Objektivkorrekturprofil TP_LENSPROFILE_USECA;CA korrigieren TP_LENSPROFILE_USEDIST;Verzeichnung korrigieren TP_LENSPROFILE_USEVIGN;Vignettierung korrigieren +TP_NEUTRAL;Zurücksetzen TP_NEUTRAL_TIP;Belichtungseinstellungen auf neutrale Werte zurücksetzen TP_PCVIGNETTE_FEATHER;Bereich TP_PCVIGNETTE_FEATHER_TOOLTIP;Bereich:\n0 = nur Bildecken\n50 = halbe Strecke zum Mittelpunkt\n100 = bis zum Mittelpunkt TP_PCVIGNETTE_LABEL;Vignettierungsfilter -TP_PCVIGNETTE_ROUNDNESS;Rundung -TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Rundung:\n0 = Rechteck\n50 = Ellipse\n100 = Kreis +TP_PCVIGNETTE_ROUNDNESS;Form +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Form:\n0 = Rechteck\n50 = Ellipse\n100 = Kreis TP_PCVIGNETTE_STRENGTH;Intensität TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filterstärke in Blendenstufen (bezogen auf die Bildecken) TP_PERSPECTIVE_HORIZONTAL;Horizontal @@ -1604,7 +1608,7 @@ TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Entfernt Hot-Pixel TP_PREPROCESS_LABEL;Vorverarbeitung TP_PREPROCESS_LINEDENOISE;Zeilenrauschfilter TP_PREPROCESS_NO_FOUND;Nichts gefunden -TP_PRSHARPENING_LABEL;Nach Größenänderung schärfen +TP_PRSHARPENING_LABEL;Nach Skalierung schärfen TP_PRSHARPENING_TOOLTIP;Schärft das Bild nach der Größenänderung. Funktioniert nur mit der Methode „Lanczos“. Das Ergebnis wird nicht in RawTherapee angezeigt.\nWeitere Informationen finden Sie in „RawPedia“. TP_RAWCACORR_AUTO;Automatische Korrektur TP_RAWCACORR_CABLUE;Blau @@ -1617,7 +1621,7 @@ TP_RAWEXPOS_BLACK_3;Grün 2 TP_RAWEXPOS_BLACK_BLUE;Blau TP_RAWEXPOS_BLACK_GREEN;Grün TP_RAWEXPOS_BLACK_RED;Rot -TP_RAWEXPOS_LINEAR;Weißpunktkorrektur +TP_RAWEXPOS_LINEAR;Korrekturfaktor TP_RAWEXPOS_PRESER;Weißpunkt: Lichter schützen TP_RAWEXPOS_RGB;Rot, Grün, Blau TP_RAWEXPOS_TWOGREEN;Grün-Werte automatisch angleichen @@ -1636,18 +1640,18 @@ TP_RAW_LMMSE_TOOLTIP;Fügt Gamma (Stufe 1), Median (Stufe 2-4) und Optimierung ( TP_RAW_SENSOR_BAYER_LABEL;Sensor mit Bayer-Matrix TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;Mit “3-pass“ erzielt man die besten Ergebnisse (empfohlen bei Bildern mit niedrigen ISO-Werten).\n\nBei hohen ISO-Werten unterscheidet sich “1-pass“ kaum gegenüber “3-pass“, ist aber deutlich schneller. TP_RAW_SENSOR_XTRANS_LABEL;Sensor mit X-Trans-Matrix -TP_RESIZE_APPLIESTO;Gilt für: +TP_RESIZE_APPLIESTO;Anwenden auf: TP_RESIZE_CROPPEDAREA;Ausschnitt -TP_RESIZE_FITBOX;Begrenzungsrahmen +TP_RESIZE_FITBOX;Breite & Höhe TP_RESIZE_FULLIMAGE;Ganzes Bild -TP_RESIZE_H;H: +TP_RESIZE_H;Höhe: TP_RESIZE_HEIGHT;Höhe -TP_RESIZE_LABEL;Größe ändern +TP_RESIZE_LABEL;Skalieren TP_RESIZE_LANCZOS;Lanczos TP_RESIZE_METHOD;Methode: TP_RESIZE_NEAREST;Nächster Nachbar TP_RESIZE_SCALE;Maßstab -TP_RESIZE_SPECIFY;Vorgabe: +TP_RESIZE_SPECIFY;Basierend auf: TP_RESIZE_W;Breite: TP_RESIZE_WIDTH;Breite TP_RETINEX_CONTEDIT_HSL;HSL-Kurve @@ -1659,7 +1663,7 @@ TP_RETINEX_CURVEEDITOR_LH;Intensität=f(H) TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Intensität in Abhängikeit des Farbtons (H)\nBei der Retinex-Methode "Spitzlichter" wirken sich die Änderungen auch auf die Chromakorrektur aus. TP_RETINEX_FREEGAMMA;Gamma TP_RETINEX_GAIN;Verstärkung -TP_RETINEX_GAIN_TOOLTIP;In Kombination mit dem Versatz beeinflusst die Einstellung die Transmission. Wird für schwarze oder weiße Pixel verwendet und hilft das Histogram auszugleichen. +TP_RETINEX_GAIN_TOOLTIP;Wirkt sich auf das verarbeitete Bild aus. Wird für schwarze oder weiße Pixel verwendet und hilft das Histogram auszugleichen. TP_RETINEX_GAMMA;Gammakorrektur TP_RETINEX_GAMMA_FREE;Benutzerdefiniert TP_RETINEX_GAMMA_HIGH;Hoch @@ -1705,7 +1709,7 @@ TP_RGBCURVES_LABEL;RGB-Kurven TP_RGBCURVES_LUMAMODE;Helligkeitsmodus TP_RGBCURVES_LUMAMODE_TOOLTIP;Der Helligkeitsmodus ändert die Helligkeit der R-, G- und B-Kanäle ohne die Farben des Bildes zu verändern. TP_RGBCURVES_RED;R -TP_ROTATE_DEGREE;Grad +TP_ROTATE_DEGREE;Winkel TP_ROTATE_LABEL;Drehen TP_ROTATE_SELECTLINE;Leitlinie wählen TP_SAVEDIALOG_OK_TIP;Taste: Strg + Enter @@ -1778,11 +1782,11 @@ TP_WAVELET_APPLYTO;Anwenden auf: TP_WAVELET_AVOID;Farbverschiebungen vermeiden TP_WAVELET_B0;Schwarz TP_WAVELET_B1;Grau -TP_WAVELET_B2;Rest +TP_WAVELET_B2;Restbild TP_WAVELET_BACKGROUND;Hintergrund TP_WAVELET_BACUR;Kurve TP_WAVELET_BALANCE;Kontrastausgleich d/v-h -TP_WAVELET_BALANCE_TOOLTIP;Verändert die Gewichtung zwischen den Wavelet-Richtungen vertikal, horizontal und diagonal.\n\nSind Kontrast-, Farb- oder Nachbild-Dynamikkompression aktiviert, wird die Wirkung aufgrund des Ausgleichs verstärkt. +TP_WAVELET_BALANCE_TOOLTIP;Verändert die Gewichtung zwischen den Wavelet-Richtungen vertikal, horizontal und diagonal.\n\nSind Kontrast-, Farb- oder Restbild-Dynamikkompression aktiviert, wird die Wirkung aufgrund des Ausgleichs verstärkt. TP_WAVELET_BALCHRO;Farbausgleich TP_WAVELET_BALCHRO_TOOLTIP;Wenn aktiviert, beeinflusst der Kontrastausgleich auch den Farbausgleich. TP_WAVELET_BANONE;Keine @@ -1790,28 +1794,28 @@ TP_WAVELET_BASLI;Regler TP_WAVELET_BATYPE;Kontrastmethode TP_WAVELET_CBENAB;Farbausgleich TP_WAVELET_CB_TOOLTIP;Farbausgleich mit getrennten Reglern für Schatten, Mitten und Lichter aktivieren. -TP_WAVELET_CCURVE;Lokaler Kontrast +TP_WAVELET_CCURVE;Lokale Kontrastkurve TP_WAVELET_CH1;Gesamter Farbbereich -TP_WAVELET_CH2;Sättigung/Pastell -TP_WAVELET_CH3;Kontrastebenen verlinken +TP_WAVELET_CH2;Gesättigte/Pastellfarben +TP_WAVELET_CH3;Kontrastebenen verknüpfen TP_WAVELET_CHCU;Kurve -TP_WAVELET_CHR;Farb-Kontrast-Verlinkungsstärke -TP_WAVELET_CHRO;Sättigung/Pastell Schwellenwert -TP_WAVELET_CHRO_TOOLTIP;Anzahl der Waveletebenen, deren Schwellenwert für die gesättigten und Pastellfarben angewendet werden soll.\n1-n: Gesättigte Farben\nn-9: Pastellfarben\n\nIst der Wert größer als die vorgegebene Anzahl an Waveletebenen werden diese ignoriert. -TP_WAVELET_CHR_TOOLTIP;Farbton als Funktion des Kontrasts und der Farbton-Kontrast-Verlinkungsstärke +TP_WAVELET_CHR;Farb-Kontrast-Verknüpfung +TP_WAVELET_CHRO;Ebenengrenze Gesättigte/Pastellfarben +TP_WAVELET_CHRO_TOOLTIP;Waveletebene (n) die, die Grenze zwischen gesättigten und Pastellfarben bestimmt.\n1-n: Gesättigte Farben\nn-9: Pastellfarben\n\nIst der Wert größer als die vorgegebene Anzahl an Waveletebenen werden diese ignoriert. +TP_WAVELET_CHR_TOOLTIP;Farbton als Funktion des Kontrasts und der Farb-Kontrast-Verknüpfung TP_WAVELET_CHSL;Regler TP_WAVELET_CHTYPE;Chrominanzmethode TP_WAVELET_COLORT;Deckkraft Rot/Grün TP_WAVELET_COMPCONT;Kontrast TP_WAVELET_COMPGAMMA;Gammakompression -TP_WAVELET_COMPGAMMA_TOOLTIP;Das Anpassen des Gammawerts des Nachbildes ermöglicht das Angleichen der Daten und des Histogramms +TP_WAVELET_COMPGAMMA_TOOLTIP;Das Anpassen des Gammawerts des Restbildes ermöglicht das Angleichen der Daten und des Histogramms TP_WAVELET_COMPTM;Dynamik TP_WAVELET_CONTEDIT;“Danach“-Kontrastkurve TP_WAVELET_CONTR;Gamut TP_WAVELET_CONTRA;Kontrast TP_WAVELET_CONTRAST_MINUS;Kontrast - TP_WAVELET_CONTRAST_PLUS;Kontrast + -TP_WAVELET_CONTRA_TOOLTIP;Ändert den Kontrast des Nachbildes +TP_WAVELET_CONTRA_TOOLTIP;Ändert den Kontrast des Restbildes TP_WAVELET_CTYPE;Chrominanzkontrolle TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Lokaler Kontrast als Funktion des ursprünglichen Kontrasts.\n\nNiedrige Werte: Wenig lokaler Kontrast (Werte zwischen 10 - 20)\n\n50%: Durchschnittlicher lokaler Kontrast (Werte zwischen 100 - 300)\n\n66%: Standardabweichung des Lokalen Kontrasts (Werte zwischen 300 - 800)\n\n100%: Maximaler lokaler Kontrast (Werte zwischen 3000 - 8000) TP_WAVELET_CURVEEDITOR_CH;Kontrast = f(H) @@ -1868,7 +1872,7 @@ TP_WAVELET_LEVDIR_ALL;Alle Ebenen und Richtungen TP_WAVELET_LEVDIR_INF;Kleiner oder gleich der Ebene TP_WAVELET_LEVDIR_ONE;Diese Ebene TP_WAVELET_LEVDIR_SUP;Über der Ebene -TP_WAVELET_LEVELS;Waveletebenen +TP_WAVELET_LEVELS;Anzahl der Ebenen TP_WAVELET_LEVELS_TOOLTIP;Wählen Sie die Anzahl der Ebenen in die das Bild zerlegt werden soll. Mehr Ebenen benötigen mehr RAM und eine längere Verarbeitungszeit. TP_WAVELET_LEVF;Kontrast TP_WAVELET_LEVLABEL;Vorschau max. möglicher Ebenen @@ -1876,7 +1880,7 @@ TP_WAVELET_LEVONE;Ebene 2 TP_WAVELET_LEVTHRE;Ebene 4 TP_WAVELET_LEVTWO;Ebene 3 TP_WAVELET_LEVZERO;Ebene 1 -TP_WAVELET_LINKEDG;Mit der Kantenschärfungsstärke verlinken +TP_WAVELET_LINKEDG;Mit der Kantenschärfungsintensität verknüpfen TP_WAVELET_LIPST;Erweiterter Algorithmus TP_WAVELET_LOWLIGHT;Schatten-Luminanzbereich TP_WAVELET_MEDGREINF;Erste Ebene @@ -1893,7 +1897,7 @@ TP_WAVELET_NPTYPE;Benachbarte Pixel TP_WAVELET_NPTYPE_TOOLTIP;Dieser Algorithmus verwendet einen Pixel und acht seiner Nachbarn. Sind die Unterschiede gering, werden die Kanten geschärft. TP_WAVELET_OPACITY;Deckkraft Blau/Gelb TP_WAVELET_OPACITYW;Kontrastausgleichskurve -TP_WAVELET_OPACITYWL;Lokaler Kontrast +TP_WAVELET_OPACITYWL;Lokale Kontrastkurve TP_WAVELET_OPACITYWL_TOOLTIP;Wendet eine lokale Kontrastkurve am Ende der Wavelet-Verarbeitung an.\n\nLinks stellt den niedrigsten, rechts den höchsten Kontrast dar. TP_WAVELET_PASTEL;Pastellfarben TP_WAVELET_PROC;Verarbeitung @@ -1903,12 +1907,12 @@ TP_WAVELET_RE3;Schärfung reduzieren TP_WAVELET_RESCHRO;Buntheit TP_WAVELET_RESCON;Schatten TP_WAVELET_RESCONH;Lichter -TP_WAVELET_RESID;Nachbild +TP_WAVELET_RESID;Restbild TP_WAVELET_SAT;Gesättigte Farben -TP_WAVELET_SETTINGS;Wavelet-Einstellungen -TP_WAVELET_SKIN;Hautfarbtöne ändern/schützen +TP_WAVELET_SETTINGS;Einstellungen +TP_WAVELET_SKIN;Hautfarbtöne schützen TP_WAVELET_SKIN_TOOLTIP;-100: Nur Farben innerhalb des Bereichs werden verändert.\n0: Alle Farben werden gleich behandelt.\n+100: Nur Farben außerhalb des Bereichs werden verändert. -TP_WAVELET_SKY;Himmelsfarbtöne ändern/schützen +TP_WAVELET_SKY;Himmelsfarbtöne schützen TP_WAVELET_SKY_TOOLTIP;-100: Nur Farben innerhalb des Bereichs werden verändert.\n0: Alle Farben werden gleich behandelt.\n+100: Nur Farben außerhalb des Bereichs werden verändert. TP_WAVELET_STREN;Intensität TP_WAVELET_STRENGTH;Intensität @@ -1925,7 +1929,7 @@ TP_WAVELET_TILESIZE;Kachelgröße TP_WAVELET_TILESLIT;Kleine Kacheln TP_WAVELET_TILES_TOOLTIP;“Ganzes Bild“ (empfohlen) liefert eine bessere Qualität.\n“Kacheln“ benötigen weniger Speicher und sind nur für Computer mit wenig RAM zu empfehlen. TP_WAVELET_TMSTRENGTH;Intensität -TP_WAVELET_TMSTRENGTH_TOOLTIP;Kontrolliert die Intensität der Dynamik- oder Kontrastkompression des Nachbildes. Ist der Wert ungleich 0, werden die Intensitäts- und Gammaregler des Dynamikkompressions-Werkzeugs im Belichtungsreiter deaktiviert. +TP_WAVELET_TMSTRENGTH_TOOLTIP;Kontrolliert die Intensität der Dynamik- oder Kontrastkompression des Restbildes. Ist der Wert ungleich 0, werden die Intensitäts- und Gammaregler des Dynamikkompressions-Werkzeugs im Belichtungsreiter deaktiviert. TP_WAVELET_TMTYPE;Kompression TP_WAVELET_TON;Tönung TP_WBALANCE_AUTO;Automatisch @@ -1982,10 +1986,3 @@ ZOOMPANEL_ZOOMFITSCREEN;An Bildschirm anpassen\nTaste: f ZOOMPANEL_ZOOMIN;Hineinzoomen\nTaste: + ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: - -!!!!!!!!!!!!!!!!!!!!!!!!! -! Untranslated keys follow; remove the ! prefix after an entry is translated. -!!!!!!!!!!!!!!!!!!!!!!!!! - -!HISTORY_MSG_166;Exposure - Reset -!PREFERENCES_TUNNELMETADATA;Copy Exif/IPTC/XMP unchanged to output file -!TP_NEUTRAL;Reset From 871e661a93325393348ba451d6addd3eb6744c5a Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sun, 29 Nov 2015 11:56:38 +0100 Subject: [PATCH 13/61] Remove two unused labels from the color toning tool that were always hidden when not in batch mode. --- rtgui/colortoning.cc | 18 ------------------ rtgui/colortoning.h | 2 -- 2 files changed, 20 deletions(-) diff --git a/rtgui/colortoning.cc b/rtgui/colortoning.cc index 5b6f21412..38cf88230 100644 --- a/rtgui/colortoning.cc +++ b/rtgui/colortoning.cc @@ -36,14 +36,6 @@ ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLOR colorSep = Gtk::manage (new Gtk::HSeparator()); pack_start (*colorSep); - colLabel = Gtk::manage (new Gtk::Label (M("TP_COLORTONING_LABCOL"))); - colLabel->set_tooltip_text (M("TP_COLORTONING_LABCOL_TOOLTIP")); - - interLabel = Gtk::manage (new Gtk::Label (M("TP_COLORTONING_LABINT"))); - interLabel->set_tooltip_text (M("TP_COLORTONING_LABINT_TOOLTIP")); - pack_start (*colLabel, Gtk::PACK_SHRINK, 4); - pack_start (*interLabel, Gtk::PACK_SHRINK, 4); - colorCurveEditorG = new CurveEditorGroup (options.lastColorToningCurvesDir, M("TP_COLORTONING_COLOR")); colorCurveEditorG->setCurveListener (this); @@ -799,8 +791,6 @@ void ColorToning::methodChanged () if (!batchMode) { if (method->get_active_row_number() == 0) { // Lab colorSep->show(); - colLabel->hide(); - interLabel->hide(); colorCurveEditorG->show(); twocolor->show(); opacityCurveEditorG->hide(); @@ -838,8 +828,6 @@ void ColorToning::methodChanged () twocolorChanged(true); } else if (method->get_active_row_number() == 1) { // RGB Sliders colorSep->hide(); - colLabel->hide(); - interLabel->hide(); colorCurveEditorG->hide(); twocolor->hide(); twocolor->set_active (false); @@ -873,8 +861,6 @@ void ColorToning::methodChanged () } else if (method->get_active_row_number() == 2) { // RGB Curves colorSep->hide(); - colLabel->hide(); - interLabel->hide(); colorCurveEditorG->show(); twocolor->hide(); twocolor->set_active (false); @@ -908,8 +894,6 @@ void ColorToning::methodChanged () lumamode->hide(); } else if (method->get_active_row_number() == 3) { // Split LR colorSep->hide(); - colLabel->hide(); - interLabel->hide(); colorCurveEditorG->hide(); twocolor->hide(); twocolor->set_active (false); @@ -932,8 +916,6 @@ void ColorToning::methodChanged () lumamode->show(); } else if (method->get_active_row_number() == 4) { // Split Color colorSep->show(); - colLabel->hide(); - interLabel->hide(); colorCurveEditorG->hide(); twocolor->hide(); opacityCurveEditorG->hide(); diff --git a/rtgui/colortoning.h b/rtgui/colortoning.h index c37d75f22..e55ff36e8 100644 --- a/rtgui/colortoning.h +++ b/rtgui/colortoning.h @@ -60,8 +60,6 @@ protected: //Gtk::Button* neutralCurves; Gtk::HBox* neutrHBox; Gtk::HBox* chromaHbox; - Gtk::Label* colLabel; - Gtk::Label* interLabel; Gtk::Label* chroLabel; int nextbw; int nextsatth; From 594b4f9b6e344434436c448ac282323b42da8f3a Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sun, 29 Nov 2015 10:25:12 +0100 Subject: [PATCH 14/61] Reenable the colorimetric intent selector on the color management tab, but display it below the monitor profile to indicate that this is the only place where it is used. --- rtengine/improcfun.cc | 4 ++-- rtgui/preferences.cc | 24 +++++++++++++----------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 8180c353f..337b5935f 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -223,7 +223,7 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par if (monitor) { lcmsMutex->lock (); cmsHPROFILE iprof = cmsCreateLab4Profile(NULL); - monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC, + monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, settings->colorimetricIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is for thread safety, NOOPTIMIZE for precision Glib::ustring outputProfile; @@ -236,7 +236,7 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); if (monitor) { - output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); + output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, settings->colorimetricIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); } } } diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index f6feef35f..5c85ea18f 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -687,14 +687,12 @@ Gtk::Widget* Preferences::getColorManagementPanel () Gtk::VBox* mvbcm = Gtk::manage (new Gtk::VBox ()); mvbcm->set_border_width (4); - /* Gtk::Label* intlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_CMETRICINTENT")+":", Gtk::ALIGN_LEFT)); intent = Gtk::manage (new Gtk::ComboBoxText ()); intent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); intent->append_text (M("PREFERENCES_INTENT_RELATIVE")); intent->append_text (M("PREFERENCES_INTENT_SATURATION")); intent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); - */ iccDir = Gtk::manage (new Gtk::FileChooserButton (M("PREFERENCES_ICCDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); Gtk::Label* pdlabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_ICCDIR") + ":", Gtk::ALIGN_LEFT)); @@ -720,17 +718,21 @@ Gtk::Widget* Preferences::getColorManagementPanel () #endif Gtk::Table* colt = Gtk::manage (new Gtk::Table (3, 2)); - //colt->attach (*intlab, 0, 1, 0, 1, Gtk::FILL, Gtk::SHRINK, 2, 2); - //colt->attach (*intent, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); - colt->attach (*pdlabel, 0, 1, 1, 2, Gtk::FILL, Gtk::SHRINK, 2, 2); - colt->attach (*iccDir, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + int row = 0; + colt->attach (*pdlabel, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + colt->attach (*iccDir, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); #if !defined(__APPLE__) // monitor profile not supported on apple - colt->attach (*mplabel, 0, 1, 2, 3, Gtk::FILL, Gtk::SHRINK, 2, 2); - colt->attach (*monProfile, 1, 2, 2, 3, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + ++row; + colt->attach (*mplabel, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + colt->attach (*monProfile, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); #if defined(WIN32) - colt->attach (*cbAutoMonProfile, 1, 2, 3, 4, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + ++row; + colt->attach (*cbAutoMonProfile, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); #endif #endif + ++row; + colt->attach (*intlab, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + colt->attach (*intent, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); mvbcm->pack_start (*colt, Gtk::PACK_SHRINK, 4); #if defined(WIN32) @@ -1438,7 +1440,7 @@ void Preferences::storePreferences () moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active (); #endif moptions.rtSettings.iccDirectory = iccDir->get_filename (); - //moptions.rtSettings.colorimetricIntent = intent->get_active_row_number (); + moptions.rtSettings.colorimetricIntent = intent->get_active_row_number (); moptions.rtSettings.viewingdevice = view->get_active_row_number (); moptions.rtSettings.viewingdevicegrey = grey->get_active_row_number (); moptions.rtSettings.viewinggreySc = greySc->get_active_row_number (); @@ -1567,7 +1569,7 @@ void Preferences::fillPreferences () iccDir->set_current_folder (moptions.rtSettings.iccDirectory); } - //intent->set_active (moptions.rtSettings.colorimetricIntent); + intent->set_active (moptions.rtSettings.colorimetricIntent); view->set_active (moptions.rtSettings.viewingdevice); grey->set_active (moptions.rtSettings.viewingdevicegrey); greySc->set_active (moptions.rtSettings.viewinggreySc); From 35919bddc9947f81850efcb0e7c773eff44f2993 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Mon, 30 Nov 2015 21:23:22 +0100 Subject: [PATCH 15/61] Copy-edit the ICC store for better performance and maintainability and add a method to load profile lists from arbitrary directories. --- rtengine/iccstore.cc | 382 ++++++++++++++++++++------------------ rtengine/iccstore.h | 137 ++++++++++---- rtengine/improcfun.cc | 2 +- rtengine/simpleprocess.cc | 2 +- rtgui/icmpanel.cc | 2 +- 5 files changed, 300 insertions(+), 225 deletions(-) diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index bad4e8dfa..24f2bb936 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -29,9 +29,90 @@ #include -namespace rtengine +namespace { +void loadProfiles (const Glib::ustring& dirName, + std::map* profiles, + std::map* profileContents, + std::map* profileNames, + bool nameUpper, bool onlyRgb) +{ + if (dirName.empty ()) + return; + + try { + + Glib::Dir dir (dirName); + + for (Glib::DirIterator entry = dir.begin (); entry != dir.end (); ++entry) { + + const Glib::ustring fileName = *entry; + + if (fileName.size () < 4) + continue; + + const Glib::ustring extension = fileName.substr (fileName.size () - 4).casefold (); + + if (extension.compare(".icc") == 0 && extension.compare(".icm") == 0) + continue; + + const Glib::ustring filePath = Glib::build_filename (dirName, fileName); + + if (!safe_file_test (filePath, Glib::FILE_TEST_IS_REGULAR)) + continue; + + Glib::ustring name = fileName.substr (0, fileName.size() - 4); + + if (nameUpper) + name = name.uppercase (); + + if (profiles) { + const rtengine::ProfileContent content (filePath); + const cmsHPROFILE profile = content.toProfile (); + + if (profile && (!onlyRgb || cmsGetColorSpace (profile) == cmsSigRgbData)) { + profiles->insert (std::make_pair (name, profile)); + + if (profileContents) + profileContents->insert (std::make_pair (name, content)); + } + } + + if (profileNames) + profileNames->insert (std::make_pair (name, filePath)); + } + } + catch (Glib::Exception&) {} +} + +inline void getSupportedIntent (cmsHPROFILE profile, cmsUInt32Number intent, cmsUInt32Number direction, std::uint8_t& result) +{ + if (cmsIsIntentSupported (profile, intent, direction)) + result |= 1 << intent; +} + +inline std::uint8_t getSupportedIntents (cmsHPROFILE profile, cmsUInt32Number direction) +{ + if (!profile) + return 0; + + std::uint8_t result = 0; + + getSupportedIntent (profile, INTENT_PERCEPTUAL, direction, result); + getSupportedIntent (profile, INTENT_RELATIVE_COLORIMETRIC, direction, result); + getSupportedIntent (profile, INTENT_SATURATION, direction, result); + getSupportedIntent (profile, INTENT_ABSOLUTE_COLORIMETRIC, direction, result); + + return result; +} + +inline cmsHPROFILE createXYZProfile () +{ + double mat[3][3] = { {1.0, 0, 0}, {0, 1.0, 0}, {0, 0, 1.0} }; + return rtengine::ICCStore::createFromMatrix (mat, false, "XYZ"); +} + const double (*wprofiles[])[3] = {xyz_sRGB, xyz_adobe, xyz_prophoto, xyz_widegamut, xyz_bruce, xyz_beta, xyz_best}; const double (*iwprofiles[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz, bruce_xyz, beta_xyz, best_xyz}; const char* wpnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB"}; @@ -43,8 +124,12 @@ const char* wpgamma[] = {"default", "BT709_g2.2_s4.5", "sRGB_g2.4_s12.92", "line // high g=1.3 s=3.35 for high dynamic images //low g=2.6 s=6.9 for low contrast images +} -std::vector getGamma () //return gamma +namespace rtengine +{ + +std::vector getGamma () { std::vector res; @@ -56,7 +141,6 @@ std::vector getGamma () //return gamma return res; } - std::vector getWorkingProfiles () { @@ -69,32 +153,38 @@ std::vector getWorkingProfiles () return res; } -std::vector ICCStore::getOutputProfiles () +std::vector ICCStore::getProfiles () const { MyMutex::MyLock lock(mutex_); std::vector res; - for (std::map::iterator i = fileProfiles.begin(); i != fileProfiles.end(); i++) { - Glib::ustring name(i->first); - std::string::size_type i2 = name.find_last_of('/'); - - if( i2 == std::string::npos ) { - i2 = name.find_last_of('\\'); - } - - if( i2 == std::string::npos ) { - res.push_back ( name ); // list only profiles inside selected profiles directory - } - } + for (ProfileMap::const_iterator profile = fileProfiles.begin (); profile != fileProfiles.end (); ++profile) + res.push_back (profile->first); return res; } +std::vector ICCStore::getProfilesFromDir (const Glib::ustring& dirName) const +{ -cmsHPROFILE -ICCStore::makeStdGammaProfile(cmsHPROFILE iprof) + MyMutex::MyLock lock(mutex_); + + std::vector res; + + ProfileMap profiles; + + loadProfiles (profilesDir, &profiles, NULL, NULL, false, true); + loadProfiles (dirName, &profiles, NULL, NULL, false, true); + + for (ProfileMap::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile) + res.push_back (profile->first); + + return res; +} + +cmsHPROFILE ICCStore::makeStdGammaProfile (cmsHPROFILE iprof) { // forgive me for the messy code, quick hack to change gamma of an ICC profile to the RT standard gamma if (!iprof) { @@ -189,14 +279,15 @@ ICCStore::makeStdGammaProfile(cmsHPROFILE iprof) return oprof; } -ICCStore* -ICCStore::getInstance(void) +ICCStore* ICCStore::getInstance () { static ICCStore instance_; return &instance_; } -ICCStore::ICCStore () +ICCStore::ICCStore () : + xyz (createXYZProfile ()), + srgb (cmsCreate_sRGBProfile ()) { //cmsErrorAction (LCMS_ERROR_SHOW); @@ -208,234 +299,172 @@ ICCStore::ICCStore () wMatrices[wpnames[i]] = wprofiles[i]; iwMatrices[wpnames[i]] = iwprofiles[i]; } - - double mat[3][3] = { {1.0, 0, 0}, {0, 1.0, 0}, {0, 0, 1.0}}; - xyz = createFromMatrix (mat, false, "XYZ"); - srgb = cmsCreate_sRGBProfile (); } -int ICCStore::numOfWProfiles () +TMatrix ICCStore::workingSpaceMatrix (const Glib::ustring& name) const { - return sizeof(wpnames) / sizeof(wpnames[0]); -} - -TMatrix ICCStore::workingSpaceMatrix (Glib::ustring name) -{ - - std::map::iterator r = wMatrices.find (name); + const MatrixMap::const_iterator r = wMatrices.find (name); if (r != wMatrices.end()) { return r->second; } else { - return wMatrices["sRGB"]; + return wMatrices.find ("sRGB")->second; } } -TMatrix ICCStore::workingSpaceInverseMatrix (Glib::ustring name) +TMatrix ICCStore::workingSpaceInverseMatrix (const Glib::ustring& name) const { - std::map::iterator r = iwMatrices.find (name); + const MatrixMap::const_iterator r = iwMatrices.find (name); if (r != iwMatrices.end()) { return r->second; } else { - return iwMatrices["sRGB"]; + return iwMatrices.find ("sRGB")->second; } } -cmsHPROFILE ICCStore::workingSpace (Glib::ustring name) +cmsHPROFILE ICCStore::workingSpace (const Glib::ustring& name) const { - std::map::iterator r = wProfiles.find (name); + const ProfileMap::const_iterator r = wProfiles.find (name); if (r != wProfiles.end()) { return r->second; } else { - return wProfiles["sRGB"]; + return wProfiles.find ("sRGB")->second; } } -cmsHPROFILE ICCStore::workingSpaceGamma (Glib::ustring name) +cmsHPROFILE ICCStore::workingSpaceGamma (const Glib::ustring& name) const { - std::map::iterator r = wProfilesGamma.find (name); + const ProfileMap::const_iterator r = wProfilesGamma.find (name); if (r != wProfilesGamma.end()) { return r->second; } else { - return wProfilesGamma["sRGB"]; + return wProfilesGamma.find ("sRGB")->second; } } -cmsHPROFILE ICCStore::getProfile (Glib::ustring name) +cmsHPROFILE ICCStore::getProfile (const Glib::ustring& name) const { MyMutex::MyLock lock(mutex_); - std::map::iterator r = fileProfiles.find (name); + const ProfileMap::const_iterator r = fileProfiles.find (name); - if (r != fileProfiles.end()) { + if (r != fileProfiles.end ()) return r->second; - } else { - if (!name.compare (0, 5, "file:") && safe_file_test (name.substr(5), Glib::FILE_TEST_EXISTS) && !safe_file_test (name.substr(5), Glib::FILE_TEST_IS_DIR)) { - ProfileContent pc (name.substr(5)); - if (pc.data) { - cmsHPROFILE profile = pc.toProfile (); + if (name.compare (0, 5, "file:") == 0) { + const ProfileContent content (name.substr (5)); + const cmsHPROFILE profile = content.toProfile (); - if (profile) { - fileProfiles[name] = profile; - fileProfileContents[name] = pc; - return profile; - } - } + if (profile) { + const_cast(fileProfiles).insert(std::make_pair(name, profile)); + const_cast(fileProfileContents).insert(std::make_pair(name, content)); + + return profile; } } return NULL; } -cmsHPROFILE ICCStore::getStdProfile (Glib::ustring name) +cmsHPROFILE ICCStore::getStdProfile (const Glib::ustring& name) const { + const Glib::ustring nameUpper = name.uppercase (); + MyMutex::MyLock lock(mutex_); - std::map::iterator r = fileStdProfiles.find (name.uppercase()); + const ProfileMap::const_iterator r = fileStdProfiles.find (nameUpper); - if (r == fileStdProfiles.end()) { - // profile is not yet in store - std::map::iterator f = fileStdProfilesFileNames.find (name.uppercase()); - - if(f != fileStdProfilesFileNames.end()) { - // but there exists one => load it - ProfileContent pc (f->second); - - if (pc.data) { - cmsHPROFILE profile = pc.toProfile (); - - if (profile) { - fileStdProfiles[name.uppercase()] = profile; - } - - // profile is not valid or it is now stored => remove entry from fileStdProfilesFileNames - fileStdProfilesFileNames.erase(f); - return profile; - } else { - // profile not valid => remove entry from fileStdProfilesFileNames - fileStdProfilesFileNames.erase(f); - return NULL; - } - } else { - // profile does not exist - return NULL; - } - } else { - // return profile from store + // return profile from store + if (r != fileStdProfiles.end ()) return r->second; - } + + // profile is not yet in store + const NameMap::const_iterator f = fileStdProfilesFileNames.find (nameUpper); + + // profile does not exist + if (f == fileStdProfilesFileNames.end ()) + return NULL; + + // but there exists one => load it + const ProfileContent content (f->second); + const cmsHPROFILE profile = content.toProfile (); + + if (profile) + const_cast(fileStdProfiles).insert (std::make_pair (f->first, profile)); + + // profile is not valid or it is now stored => remove entry from fileStdProfilesFileNames + const_cast(fileStdProfilesFileNames).erase (f); + return profile; } -ProfileContent ICCStore::getContent (Glib::ustring name) +ProfileContent ICCStore::getContent (const Glib::ustring& name) const { MyMutex::MyLock lock(mutex_); - return fileProfileContents[name]; + const ContentMap::const_iterator r = fileProfileContents.find (name); + + return r != fileProfileContents.end () ? r->second : ProfileContent(); +} + +std::uint8_t ICCStore::getInputIntents (cmsHPROFILE profile) const +{ + + MyMutex::MyLock lock (mutex_); + + return getSupportedIntents (profile, LCMS_USED_AS_INPUT); +} + +std::uint8_t ICCStore::getOutputIntents (cmsHPROFILE profile) const +{ + + MyMutex::MyLock lock (mutex_); + + return getSupportedIntents (profile, LCMS_USED_AS_OUTPUT); +} + +std::uint8_t ICCStore::getProofIntents (cmsHPROFILE profile) const +{ + + MyMutex::MyLock lock (mutex_); + + return getSupportedIntents (profile, LCMS_USED_AS_PROOF); } // Reads all profiles from the given profiles dir -void ICCStore::init (Glib::ustring usrICCDir, Glib::ustring rtICCDir) +void ICCStore::init (const Glib::ustring& usrICCDir, const Glib::ustring& rtICCDir) { MyMutex::MyLock lock(mutex_); - // + // RawTherapee's profiles take precedence if a user's profile of the same name exists + profilesDir = Glib::build_filename (rtICCDir, "output"); fileProfiles.clear(); fileProfileContents.clear(); - // RawTherapee's profiles take precedence if a user's profile of the same name exists - loadICCs(Glib::build_filename(rtICCDir, "output"), false, fileProfiles, &fileProfileContents, true, true); - loadICCs(usrICCDir, false, fileProfiles, &fileProfileContents, true, true); + loadProfiles (profilesDir, &fileProfiles, &fileProfileContents, NULL, false, true); + loadProfiles (usrICCDir, &fileProfiles, &fileProfileContents, NULL, false, true); // Input profiles // Load these to different areas, since the short name (e.g. "NIKON D700" may overlap between system/user and RT dir) + stdProfilesDir = Glib::build_filename (rtICCDir, "input"); fileStdProfiles.clear(); fileStdProfilesFileNames.clear(); - loadICCs(Glib::build_filename(rtICCDir, "input"), true, fileStdProfiles, NULL); -} - -void ICCStore::loadICCs(Glib::ustring rootDirName, bool nameUpper, std::map& resultProfiles, std::map *resultProfileContents, bool prefetch, bool onlyRgb) -{ - if (rootDirName != "") { - std::deque qDirs; - - qDirs.push_front(rootDirName); - - while (!qDirs.empty()) { - // process directory - Glib::ustring dirname = qDirs.back(); - qDirs.pop_back(); - - Glib::Dir* dir = NULL; - - try { - if (!safe_file_test (dirname, Glib::FILE_TEST_IS_DIR)) { - return; - } - - dir = new Glib::Dir (dirname); - } catch (Glib::Exception& fe) { - return; - } - - dirname = dirname + "/"; - - for (Glib::DirIterator i = dir->begin(); i != dir->end(); ++i) { - Glib::ustring fname = dirname + *i; - Glib::ustring sname = *i; - - // ignore directories - if (!safe_file_test (fname, Glib::FILE_TEST_IS_DIR)) { - size_t lastdot = sname.find_last_of ('.'); - - if (lastdot != Glib::ustring::npos && lastdot <= sname.size() - 4 && (!sname.casefold().compare (lastdot, 4, ".icm") || !sname.casefold().compare (lastdot, 4, ".icc"))) { - Glib::ustring name = nameUpper ? sname.substr(0, lastdot).uppercase() : sname.substr(0, lastdot); - - if(!prefetch) { - fileStdProfilesFileNames[name] = fname; - } else { - ProfileContent pc (fname); - - if (pc.data) { - cmsHPROFILE profile = pc.toProfile (); - - if (profile && (!onlyRgb || cmsGetColorSpace(profile) == cmsSigRgbData)) { - resultProfiles[name] = profile; - - if(resultProfileContents) { - (*resultProfileContents)[name] = pc; - } - } - } - } - } - } - - // Removed recursive scanning, see issue #1730. - // To revert to the recursive method, just uncomment the next line. - - //else qDirs.push_front(fname); // for later scanning - } - - delete dir; - } - } + loadProfiles (stdProfilesDir, NULL, NULL, &fileStdProfilesFileNames, true, false); } // Determine the first monitor default profile of operating system, if selected -void ICCStore::findDefaultMonitorProfile() +void ICCStore::findDefaultMonitorProfile () { - defaultMonitorProfile = ""; + defaultMonitorProfile.clear (); #ifdef WIN32 // Get current main monitor. Could be fine tuned to get the current windows monitor (multi monitor setup), @@ -466,7 +495,7 @@ void ICCStore::findDefaultMonitorProfile() } } -ProfileContent::ProfileContent (Glib::ustring fileName) : data(NULL), length(0) +ProfileContent::ProfileContent (const Glib::ustring& fileName) : data(NULL), length(0) { FILE* f = safe_g_fopen (fileName, "rb"); @@ -518,9 +547,7 @@ ProfileContent& ProfileContent::operator= (const ProfileContent& other) length = other.length; - if (data) { - delete [] data; - } + delete [] data; if (other.data) { data = new char[length + 1]; @@ -532,15 +559,7 @@ ProfileContent& ProfileContent::operator= (const ProfileContent& other) return *this; } -ProfileContent::~ProfileContent () -{ - - if (data) { - delete [] data; - } -} - -cmsHPROFILE ProfileContent::toProfile () +cmsHPROFILE ProfileContent::toProfile () const { if (data) { @@ -550,7 +569,7 @@ cmsHPROFILE ProfileContent::toProfile () } } -cmsHPROFILE ICCStore::createFromMatrix (const double matrix[3][3], bool gamma, Glib::ustring name) +cmsHPROFILE ICCStore::createFromMatrix (const double matrix[3][3], bool gamma, const Glib::ustring& name) { static const unsigned phead[] = { @@ -644,4 +663,5 @@ cmsHPROFILE ICCStore::createFromMatrix (const double matrix[3][3], bool gamma, G delete [] oprof; return p; } + } diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h index acb31e4cf..524db9cd2 100644 --- a/rtengine/iccstore.h +++ b/rtengine/iccstore.h @@ -37,74 +37,129 @@ public: char* data; int length; - ProfileContent (): data(NULL), length(0) {} - ProfileContent (Glib::ustring fileName); - ProfileContent (const ProfileContent& other); - ProfileContent (cmsHPROFILE hProfile); + ProfileContent (); ~ProfileContent (); + + ProfileContent (const ProfileContent& other); ProfileContent& operator= (const rtengine::ProfileContent& other); - cmsHPROFILE toProfile (); + + ProfileContent (const Glib::ustring& fileName); + ProfileContent (cmsHPROFILE hProfile); + cmsHPROFILE toProfile () const; }; class ICCStore { + typedef std::map ProfileMap; + typedef std::map MatrixMap; + typedef std::map ContentMap; + typedef std::map NameMap; - std::map wProfiles; - std::map wProfilesGamma; - std::map wMatrices; - std::map iwMatrices; + ProfileMap wProfiles; + ProfileMap wProfilesGamma; + MatrixMap wMatrices; + MatrixMap iwMatrices; // these contain profiles from user/system directory (supplied on init) - std::map fileProfiles; - std::map fileProfileContents; + Glib::ustring profilesDir; + ProfileMap fileProfiles; + ContentMap fileProfileContents; // these contain standard profiles from RT. keys are all in uppercase - std::map fileStdProfilesFileNames; - std::map fileStdProfiles; + Glib::ustring stdProfilesDir; + NameMap fileStdProfilesFileNames; + ProfileMap fileStdProfiles; - cmsHPROFILE xyz; - cmsHPROFILE srgb; + Glib::ustring defaultMonitorProfile; - MyMutex mutex_; + const cmsHPROFILE xyz; + const cmsHPROFILE srgb; + + mutable MyMutex mutex_; ICCStore (); - void loadICCs(Glib::ustring rootDirName, bool nameUpper, std::map& resultProfiles, std::map *resultProfileContents, bool prefetch = false, bool onlyRgb = false); public: - static ICCStore* getInstance(void); - static cmsHPROFILE makeStdGammaProfile(cmsHPROFILE iprof); + static ICCStore* getInstance (); - Glib::ustring defaultMonitorProfile; // Main monitors standard profile name, from OS - void findDefaultMonitorProfile(); + void init (const Glib::ustring& usrICCDir, const Glib::ustring& stdICCDir); - int numOfWProfiles (); - cmsHPROFILE createFromMatrix (const double matrix[3][3], bool gamma = false, Glib::ustring name = ""); - cmsHPROFILE workingSpace (Glib::ustring name); - cmsHPROFILE workingSpaceGamma (Glib::ustring name); - TMatrix workingSpaceMatrix (Glib::ustring name); - TMatrix workingSpaceInverseMatrix (Glib::ustring name); + static cmsHPROFILE makeStdGammaProfile (cmsHPROFILE iprof); + static cmsHPROFILE createFromMatrix (const double matrix[3][3], bool gamma = false, const Glib::ustring& name = Glib::ustring()); - cmsHPROFILE getProfile (Glib::ustring name); - cmsHPROFILE getStdProfile(Glib::ustring name); + // Main monitors standard profile name, from OS + const Glib::ustring& getDefaultMonitorProfile () const; + void findDefaultMonitorProfile (); - void init (Glib::ustring usrICCDir, Glib::ustring stdICCDir); - ProfileContent getContent (Glib::ustring name); + cmsHPROFILE workingSpace (const Glib::ustring& name) const; + cmsHPROFILE workingSpaceGamma (const Glib::ustring& name) const; + TMatrix workingSpaceMatrix (const Glib::ustring& name) const; + TMatrix workingSpaceInverseMatrix (const Glib::ustring& name) const; - cmsHPROFILE getXYZProfile () - { - return xyz; - } - cmsHPROFILE getsRGBProfile () - { - return srgb; - } - std::vector getOutputProfiles (); + cmsHPROFILE getProfile (const Glib::ustring& name) const; + cmsHPROFILE getStdProfile (const Glib::ustring& name) const; + ProfileContent getContent (const Glib::ustring& name) const; + + cmsHPROFILE getXYZProfile () const; + cmsHPROFILE getsRGBProfile () const; + + std::vector getProfiles () const; + std::vector getProfilesFromDir (const Glib::ustring& dirName) const; + + std::uint8_t getInputIntents (cmsHPROFILE profile) const; + std::uint8_t getOutputIntents (cmsHPROFILE profile) const; + std::uint8_t getProofIntents (cmsHPROFILE profile) const; + + std::uint8_t getInputIntents (const Glib::ustring& name) const; + std::uint8_t getOutputIntents (const Glib::ustring& name) const; + std::uint8_t getProofIntents (const Glib::ustring& name) const; }; #define iccStore ICCStore::getInstance() -//extern const char* wpnames[]; +inline ProfileContent::ProfileContent () : + data(NULL), + length(0) +{ } + +inline ProfileContent::~ProfileContent () +{ + delete [] data; +} + +inline const Glib::ustring& ICCStore::getDefaultMonitorProfile () const +{ + return defaultMonitorProfile; +} + +inline std::uint8_t ICCStore::getInputIntents (const Glib::ustring &name) const +{ + return getInputIntents (getProfile (name)); +} + +inline std::uint8_t ICCStore::getOutputIntents (const Glib::ustring &name) const +{ + return getOutputIntents (getProfile (name)); +} + +inline std::uint8_t ICCStore::getProofIntents (const Glib::ustring &name) const +{ + return getProofIntents (getProfile (name)); +} + +inline cmsHPROFILE ICCStore::getXYZProfile () const +{ + return xyz; +} + +inline cmsHPROFILE ICCStore::getsRGBProfile () const +{ + return srgb; +} + +} + #endif diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 337b5935f..62255cd39 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -213,7 +213,7 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par #if defined(WIN32) if (settings->autoMonitorProfile) { - monitorProfile = iccStore->defaultMonitorProfile; + monitorProfile = iccStore->getDefaultMonitorProfile (); } #endif diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 91b7df178..5ea834b2d 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1159,7 +1159,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p bool pro = false; Glib::ustring chpro, outProfile; bool present_space[9] = {false, false, false, false, false, false, false, false, false}; - std::vector opnames = iccStore->getOutputProfiles (); + std::vector opnames = iccStore->getProfiles (); //test if files are in system for (int j = 0; j < 9; j++) { diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index e9e4e05ff..51ee408a2 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -185,7 +185,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch onames->append_text (M("TP_ICM_NOICM")); onames->set_active (0); - std::vector opnames = iccStore->getOutputProfiles (); + std::vector opnames = iccStore->getProfiles (); for (size_t i = 0; i < opnames.size(); i++) { onames->append_text (opnames[i]); From 22bffabe7fed331fa913c605490a79b471fa9a1b Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Mon, 30 Nov 2015 21:24:26 +0100 Subject: [PATCH 16/61] Extend the editor panel to support selection of a monitor profile and rendering intent and extend the preferences to provide a default profile and intent for the editor panel. --- rtdata/languages/default | 5 ++- rtengine/improcfun.cc | 21 ++++----- rtengine/procparams.cc | 2 + rtengine/procparams.h | 2 + rtengine/settings.h | 4 +- rtgui/editorpanel.cc | 97 +++++++++++++++++++++++++++++++++++++++- rtgui/editorpanel.h | 4 ++ rtgui/guiutils.h | 7 +++ rtgui/options.cc | 8 ++-- rtgui/preferences.cc | 77 +++++++++++++++++-------------- rtgui/preferences.h | 7 +-- 11 files changed, 178 insertions(+), 56 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 84586340e..9c703954a 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -886,7 +886,7 @@ PREFERENCES_CLIPPINGIND;Clipping Indication PREFERENCES_CLUTSCACHE;HaldCLUT Cache PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs PREFERENCES_CLUTSDIR;HaldCLUT directory -PREFERENCES_CMETRICINTENT;Colorimetric intent +PREFERENCES_MONINTENT;Default monitor intent PREFERENCES_CURVEBBOXPOS;Position of curve copypasta buttons PREFERENCES_CURVEBBOXPOS_ABOVE;Above PREFERENCES_CURVEBBOXPOS_BELOW;Below @@ -981,7 +981,7 @@ PREFERENCES_MENUGROUPRANK;Group "Rank" PREFERENCES_MENUOPTIONS;Context Menu Options PREFERENCES_METADATA;Metadata PREFERENCES_MIN;Mini (100x115) -PREFERENCES_MONITORICC;Monitor color profile +PREFERENCES_MONPROFILE;Default monitor profile PREFERENCES_MULTITAB;Multiple Editor Tabs Mode PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode PREFERENCES_NAVGUIDEBRUSH;Navigator guide color @@ -1010,6 +1010,7 @@ PREFERENCES_PROFILEPRCACHE;Profile in cache PREFERENCES_PROFILEPRFILE;Profile next to the input file PREFERENCES_PROFILESAVECACHE;Save processing profile to the cache PREFERENCES_PROFILESAVEINPUT;Save processing profile next to the input file +PREFERENCES_PROFILE_NONE;None PREFERENCES_PROPERTY;Property PREFERENCES_PSPATH;Adobe Photoshop installation directory PREFERENCES_REMEMBERZOOMPAN;Remember zoom % and pan offset diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 62255cd39..4306d4a6e 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -209,21 +209,23 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par lab2outputTransform = NULL; #if !defined(__APPLE__) // No support for monitor profiles on OS X, all data is sRGB - Glib::ustring monitorProfile = settings->monitorProfile; + #if defined(WIN32) - if (settings->autoMonitorProfile) { - monitorProfile = iccStore->getDefaultMonitorProfile (); - } + cmsHPROFILE monitor = iccStore->getProfile (settings->autoMonitorProfile + ? iccStore->getDefaultMonitorProfile () + : params->icm.monitorProfile); + +#else + + cmsHPROFILE monitor = iccStore->getProfile (params->icm.monitorProfile); #endif - cmsHPROFILE monitor = iccStore->getProfile ("file:" + monitorProfile); - if (monitor) { - lcmsMutex->lock (); + MyMutex::MyLock lcmsLock (*lcmsMutex); cmsHPROFILE iprof = cmsCreateLab4Profile(NULL); - monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, settings->colorimetricIntent, + monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, params->icm.monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is for thread safety, NOOPTIMIZE for precision Glib::ustring outputProfile; @@ -236,13 +238,12 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); if (monitor) { - output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, settings->colorimetricIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); + output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, params->icm.monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); } } } cmsCloseProfile(iprof); - lcmsMutex->unlock (); } #endif diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index becd8932e..44c02a531 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -894,6 +894,8 @@ void ColorManagementParams::setDefaults() dcpIlluminant = 0; working = "ProPhoto"; output = "RT_sRGB"; + monitorProfile = Glib::ustring (); + monitorIntent = 1; gamma = "default"; gampos = 2.22; slpos = 4.5; diff --git a/rtengine/procparams.h b/rtengine/procparams.h index d46fd4181..77c1004e8 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -941,6 +941,8 @@ public: int dcpIlluminant; Glib::ustring working; Glib::ustring output; + Glib::ustring monitorProfile; // Not stored persistently as it is just an optional settings override. + int monitorIntent; // Not store persistently as it is just an optional settings override. static const Glib::ustring NoICMString; Glib::ustring gamma; diff --git a/rtengine/settings.h b/rtengine/settings.h index 373103d07..bd37faaf2 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -27,7 +27,6 @@ class Settings { public: Glib::ustring iccDirectory; ///< The directory containing the possible output icc profiles - int colorimetricIntent; ///< Colorimetric intent used at color space conversions int viewingdevice; // white of output device (D50...D65..) int viewingdevicegrey; // level of grey output device int viewinggreySc; // level of grey Scene @@ -37,7 +36,8 @@ public: int leveldnliss; // level of auto multi zone int leveldnautsimpl; // STD or EXPERT - Glib::ustring monitorProfile; ///< ICC profile of the monitor (full path recommended) + Glib::ustring monitorProfile; ///< ICC profile name used for the monitor + int monitorIntent; ///< Colorimetric intent used with the above profile bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile bool autocielab; bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 82e8d9fcf..c6d2804c1 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -25,12 +25,102 @@ #include "procparamchangers.h" #include "../rtengine/safegtk.h" #include "../rtengine/imagesource.h" +#include "../rtengine/iccstore.h" #include "soundman.h" #include "rtimage.h" #include using namespace rtengine::procparams; +class MonitorProfileSelector +{ +private: + Gtk::ComboBoxText profileBox; + Gtk::ComboBoxText intentBox; + + rtengine::StagedImageProcessor* const& processor; + +private: + MonitorProfileSelector(const MonitorProfileSelector&); + MonitorProfileSelector& operator=(const MonitorProfileSelector&); + + void prepareProfileBox () + { + profileBox.append_text (M("PREFERENCES_PROFILE_NONE")); + profileBox.set_active (0); + + const std::vector profiles = rtengine::ICCStore::getInstance ()->getProfiles (); + for (std::vector::const_iterator iterator = profiles.begin (); iterator != profiles.end (); ++iterator) + profileBox.append_text (*iterator); + } + + void prepareIntentBox () + { + intentBox.append_text (M("PREFERENCES_INTENT_RELATIVE")); + intentBox.append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); + intentBox.set_active (0); + } + + void updateParameters () + { + const Glib::ustring profile = profileBox.get_active_row_number () > 0 ? profileBox.get_active_text () : Glib::ustring(); + + std::uint8_t supportedIntents = rtengine::ICCStore::getInstance ()->getProofIntents (profile); + const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL; + const bool supportsRelativeColorimetric = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC; + + if (supportsPerceptual && supportsRelativeColorimetric) { + intentBox.set_sensitive (true); + } + else { + intentBox.set_sensitive (false); + intentBox.set_active (supportsPerceptual ? 1 : 0); + } + + const int intent = intentBox.get_active_row_number () > 0 ? INTENT_PERCEPTUAL : INTENT_RELATIVE_COLORIMETRIC; + + if (!processor) + return; + + rtengine::ProcParams* parameters = processor->beginUpdateParams (); + + parameters->icm.monitorProfile = profile; + parameters->icm.monitorIntent = intent; + + processor->endUpdateParams (rtengine::EvOProfile); + } + +public: + MonitorProfileSelector (rtengine::StagedImageProcessor* const& ipc) : + profileBox (), + intentBox (), + processor (ipc) + { + prepareProfileBox (); + prepareIntentBox (); + + reset (); + + profileBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); + intentBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); + } + + void pack_end (Gtk::Box* box) + { + box->pack_end (intentBox, Gtk::PACK_SHRINK, 0); + box->pack_end (profileBox, Gtk::PACK_SHRINK, 0); + } + + void reset () + { + setActiveTextOrIndex (profileBox, options.rtSettings.monitorProfile, 0); + intentBox.set_active (options.rtSettings.monitorIntent == INTENT_PERCEPTUAL ? 1 : 0); + + updateParameters (); + } + +}; + EditorPanel::EditorPanel (FilePanel* filePanel) : realized(false), iHistoryShow(NULL), iHistoryHide(NULL), iTopPanel_1_Show(NULL), iTopPanel_1_Hide(NULL), iRightPanel_1_Show(NULL), iRightPanel_1_Hide(NULL), iBeforeLockON(NULL), iBeforeLockOFF(NULL), beforePreviewHandler(NULL), beforeIarea(NULL), beforeBox(NULL), afterBox(NULL), afterHeaderBox(NULL), parent(NULL), openThm(NULL), ipc(NULL), beforeIpc(NULL), isProcessing(false), catalogPane(NULL) { @@ -256,12 +346,15 @@ EditorPanel::EditorPanel (FilePanel* filePanel) navSync->set_relief(Gtk::RELIEF_NONE); navSync->set_tooltip_markup(M("MAIN_BUTTON_NAVSYNC_TOOLTIP")); - iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); iops->pack_end (*navNext, Gtk::PACK_SHRINK, 0); iops->pack_end (*navSync, Gtk::PACK_SHRINK, 0); iops->pack_end (*navPrev, Gtk::PACK_SHRINK, 0); + iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); } + monitorProfile.reset(new MonitorProfileSelector (ipc)); + monitorProfile->pack_end (iops); + editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0); editbox->pack_start (*iops, Gtk::PACK_SHRINK, 0); editbox->show_all (); @@ -568,6 +661,8 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) } history->resetSnapShotNumber(); + + monitorProfile->reset (); } void EditorPanel::close () diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index cf446da97..ffb8a93a4 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -42,6 +42,8 @@ struct EditorPanelIdleHelper { int pending; }; +class MonitorProfileSelector; + class RTWindow; class EditorPanel : public Gtk::VBox, public PParamsChangeListener, @@ -84,6 +86,8 @@ protected: Gtk::Button* navNext; Gtk::Button* navPrev; + std::auto_ptr monitorProfile; + ImageAreaPanel* iareapanel; PreviewHandler* previewHandler; PreviewHandler* beforePreviewHandler; // for the before-after view diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 1e65f2753..80729b96b 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -496,5 +496,12 @@ public: } }; +inline void setActiveTextOrIndex (Gtk::ComboBoxText& comboBox, const Glib::ustring& text, int index) +{ + comboBox.set_active_text (text); + + if (comboBox.get_active_row_number () < 0) + comboBox.set_active (index); +} #endif diff --git a/rtgui/options.cc b/rtgui/options.cc index 6d0b6a0d0..ce85acc09 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -626,7 +626,6 @@ void Options::setDefaults () #else rtSettings.iccDirectory = "/usr/share/color/icc"; #endif - rtSettings.colorimetricIntent = 1; rtSettings.viewingdevice = 0; rtSettings.viewingdevicegrey = 3; rtSettings.viewinggreySc = 1; @@ -636,7 +635,8 @@ void Options::setDefaults () rtSettings.leveldnliss = 0; rtSettings.leveldnautsimpl = 0; - rtSettings.monitorProfile = ""; + rtSettings.monitorProfile = Glib::ustring(); + rtSettings.monitorIntent = 1; rtSettings.autoMonitorProfile = false; rtSettings.adobe = "RT_Medium_gsRGB"; // put the name of yours profiles (here windows) rtSettings.prophoto = "RT_Large_gBT709"; // these names appear in the menu "output profile" @@ -1461,7 +1461,7 @@ int Options::readFromFile (Glib::ustring fname) } if (keyFile.has_key ("Color Management", "Intent")) { - rtSettings.colorimetricIntent = keyFile.get_integer("Color Management", "Intent"); + rtSettings.monitorIntent = keyFile.get_integer("Color Management", "Intent"); } if (keyFile.has_key ("Color Management", "CRI")) { @@ -2008,7 +2008,7 @@ int Options::saveToFile (Glib::ustring fname) keyFile.set_boolean ("Color Management", "AutoMonitorProfile", rtSettings.autoMonitorProfile); keyFile.set_boolean ("Color Management", "Autocielab", rtSettings.autocielab); keyFile.set_boolean ("Color Management", "RGBcurvesLumamode_Gamut", rtSettings.rgbcurveslumamode_gamut); - keyFile.set_integer ("Color Management", "Intent", rtSettings.colorimetricIntent); + keyFile.set_integer ("Color Management", "Intent", rtSettings.monitorIntent); keyFile.set_integer ("Color Management", "view", rtSettings.viewingdevice); keyFile.set_integer ("Color Management", "grey", rtSettings.viewingdevicegrey); keyFile.set_integer ("Color Management", "greySc", rtSettings.viewinggreySc); diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 5c85ea18f..4aa1d2427 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -687,30 +687,27 @@ Gtk::Widget* Preferences::getColorManagementPanel () Gtk::VBox* mvbcm = Gtk::manage (new Gtk::VBox ()); mvbcm->set_border_width (4); - Gtk::Label* intlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_CMETRICINTENT")+":", Gtk::ALIGN_LEFT)); - intent = Gtk::manage (new Gtk::ComboBoxText ()); - intent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); - intent->append_text (M("PREFERENCES_INTENT_RELATIVE")); - intent->append_text (M("PREFERENCES_INTENT_SATURATION")); - intent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); - iccDir = Gtk::manage (new Gtk::FileChooserButton (M("PREFERENCES_ICCDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); Gtk::Label* pdlabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_ICCDIR") + ":", Gtk::ALIGN_LEFT)); - Gtk::FileFilter monProfileFilter_colprof; - monProfileFilter_colprof.set_name(M("FILECHOOSER_FILTER_COLPROF")); - monProfileFilter_colprof.add_pattern("*.icc"); - monProfileFilter_colprof.add_pattern("*.ICC"); - monProfileFilter_colprof.add_pattern("*.icm"); - monProfileFilter_colprof.add_pattern("*.ICM"); - Gtk::FileFilter monProfileFilter_any; - monProfileFilter_any.set_name(M("FILECHOOSER_FILTER_ANY")); - monProfileFilter_any.add_pattern("*"); + monProfile = Gtk::manage (new Gtk::ComboBoxText ()); + Gtk::Label* mplabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_MONPROFILE") + ":", Gtk::ALIGN_LEFT)); - monProfile = Gtk::manage (new Gtk::FileChooserButton (M("PREFERENCES_MONITORICC"), Gtk::FILE_CHOOSER_ACTION_OPEN)); - monProfile->add_filter (monProfileFilter_colprof); - monProfile->add_filter (monProfileFilter_any); - Gtk::Label* mplabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_MONITORICC") + ":", Gtk::ALIGN_LEFT)); + monIntent = Gtk::manage (new Gtk::ComboBoxText ()); + Gtk::Label* milabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_MONINTENT")+":", Gtk::ALIGN_LEFT)); + + monProfile->append_text (M("PREFERENCES_PROFILE_NONE")); + monProfile->set_active (0); + + const std::vector profiles = rtengine::ICCStore::getInstance ()->getProfiles (); + for (std::vector::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile) + monProfile->append_text (*profile); + + monIntent->append_text (M("PREFERENCES_INTENT_RELATIVE")); + monIntent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); + monIntent->set_active (0); + + iccDir->signal_selection_changed ().connect (sigc::mem_fun (this, &Preferences::iccDirChanged)); #if defined(WIN32) // Auto-detection not implemented for Linux, see issue 851 cbAutoMonProfile = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_AUTOMONPROFILE"))); @@ -731,8 +728,8 @@ Gtk::Widget* Preferences::getColorManagementPanel () #endif #endif ++row; - colt->attach (*intlab, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 2, 2); - colt->attach (*intent, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + colt->attach (*milabel, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + colt->attach (*monIntent, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); mvbcm->pack_start (*colt, Gtk::PACK_SHRINK, 4); #if defined(WIN32) @@ -1435,12 +1432,15 @@ void Preferences::storePreferences () moptions.CPBPath = txtCustProfBuilderPath->get_text(); moptions.CPBKeys = CPBKeyType(custProfBuilderLabelType->get_active_row_number()); - moptions.rtSettings.monitorProfile = monProfile->get_filename (); +#if !defined(__APPLE__) // monitor profile not supported on apple + moptions.rtSettings.monitorProfile = monProfile->get_active_text (); + moptions.rtSettings.monitorIntent = monIntent->get_active_row_number () > 0 ? INTENT_PERCEPTUAL : INTENT_RELATIVE_COLORIMETRIC; #if defined(WIN32) moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active (); #endif +#endif + moptions.rtSettings.iccDirectory = iccDir->get_filename (); - moptions.rtSettings.colorimetricIntent = intent->get_active_row_number (); moptions.rtSettings.viewingdevice = view->get_active_row_number (); moptions.rtSettings.viewingdevicegrey = grey->get_active_row_number (); moptions.rtSettings.viewinggreySc = greySc->get_active_row_number (); @@ -1550,16 +1550,10 @@ void Preferences::fillPreferences () panFactor->set_value (moptions.panAccelFactor); rememberZoomPanCheckbutton->set_active (moptions.rememberZoomAndPan); ctiffserialize->set_active(moptions.serializeTiffRead); + #if !defined(__APPLE__) // monitor profile not supported on apple - - if (safe_file_test (moptions.rtSettings.monitorProfile, Glib::FILE_TEST_EXISTS)) { - monProfile->set_filename (moptions.rtSettings.monitorProfile); - } - - if (moptions.rtSettings.monitorProfile.empty()) { - monProfile->set_current_folder (moptions.rtSettings.iccDirectory); - } - + setActiveTextOrIndex (*monProfile, moptions.rtSettings.monitorProfile, 0); + monIntent->set_active (moptions.rtSettings.monitorIntent == INTENT_PERCEPTUAL ? 1 : 0); #if defined(WIN32) cbAutoMonProfile->set_active(moptions.rtSettings.autoMonitorProfile); #endif @@ -1569,7 +1563,6 @@ void Preferences::fillPreferences () iccDir->set_current_folder (moptions.rtSettings.iccDirectory); } - intent->set_active (moptions.rtSettings.colorimetricIntent); view->set_active (moptions.rtSettings.viewingdevice); grey->set_active (moptions.rtSettings.viewingdevicegrey); greySc->set_active (moptions.rtSettings.viewinggreySc); @@ -1921,6 +1914,22 @@ void Preferences::bundledProfilesChanged () rpconn.block (false); } +void Preferences::iccDirChanged () +{ + const Glib::ustring currentSelection = monProfile->get_active_text (); + + monProfile->clear(); + + monProfile->append_text (M("PREFERENCES_PROFILE_NONE")); + monProfile->set_active (0); + + const std::vector profiles = rtengine::ICCStore::getInstance ()->getProfilesFromDir (iccDir->get_filename ()); + for (std::vector::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile) + monProfile->append_text (*profile); + + monProfile->set_active_text (currentSelection); +} + void Preferences::storeCurrentValue() { // TODO: Find a way to get and restore the current selection; the following line can't work anymore diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 76abd0a19..2bf118459 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -95,7 +95,8 @@ protected: Gtk::CheckButton* showExpComp; Gtk::FileChooserButton* iccDir; - Gtk::FileChooserButton* monProfile; + Gtk::ComboBoxText* monProfile; + Gtk::ComboBoxText* monIntent; Gtk::CheckButton* cbAutoMonProfile; //Gtk::CheckButton* cbAutocielab; Gtk::CheckButton* cbciecamfloat; @@ -106,7 +107,6 @@ protected: Gtk::SpinButton* panFactor; Gtk::CheckButton* rememberZoomPanCheckbutton; - Gtk::ComboBoxText* intent; Gtk::ComboBoxText* view; Gtk::ComboBoxText* grey; Gtk::ComboBoxText* greySc; @@ -210,7 +210,8 @@ protected: void forRAWComboChanged (); void forImageComboChanged (); void layoutComboChanged (); - void bundledProfilesChanged(); + void bundledProfilesChanged (); + void iccDirChanged (); void switchThemeTo (Glib::ustring newTheme, bool slimInterface); void switchFontTo (Glib::ustring newFont); bool splashClosed(GdkEventAny* event); From 5f59156bb0377ff20a70b0a8d89d5e0665d9259f Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sun, 6 Dec 2015 02:30:18 +0100 Subject: [PATCH 17/61] Simplify querying the default monitor profile as suggested by Hombre57. --- rtengine/iccstore.h | 6 +++--- rtengine/improcfun.cc | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h index 524db9cd2..ed9fbb424 100644 --- a/rtengine/iccstore.h +++ b/rtengine/iccstore.h @@ -89,8 +89,8 @@ public: static cmsHPROFILE createFromMatrix (const double matrix[3][3], bool gamma = false, const Glib::ustring& name = Glib::ustring()); // Main monitors standard profile name, from OS - const Glib::ustring& getDefaultMonitorProfile () const; void findDefaultMonitorProfile (); + cmsHPROFILE getDefaultMonitorProfile () const; cmsHPROFILE workingSpace (const Glib::ustring& name) const; cmsHPROFILE workingSpaceGamma (const Glib::ustring& name) const; @@ -129,9 +129,9 @@ inline ProfileContent::~ProfileContent () delete [] data; } -inline const Glib::ustring& ICCStore::getDefaultMonitorProfile () const +inline cmsHPROFILE ICCStore::getDefaultMonitorProfile () const { - return defaultMonitorProfile; + return getProfile (defaultMonitorProfile); } inline std::uint8_t ICCStore::getInputIntents (const Glib::ustring &name) const diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 4306d4a6e..c9fa3c6c8 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -212,9 +212,9 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par #if defined(WIN32) - cmsHPROFILE monitor = iccStore->getProfile (settings->autoMonitorProfile - ? iccStore->getDefaultMonitorProfile () - : params->icm.monitorProfile); + cmsHPROFILE monitor = settings->autoMonitorProfile + ? iccStore->getDefaultMonitorProfile () + : iccStore->getProfile (params->icm.monitorProfile); #else From 8f733776014d3535f897905cb0bafe66cccb49c1 Mon Sep 17 00:00:00 2001 From: Hombre Date: Tue, 8 Dec 2015 18:00:14 +0100 Subject: [PATCH 18/61] Add method to explicitly handle menu item sensitivy for the pop-up button. --- rtgui/popupcommon.cc | 9 +++++++++ rtgui/popupcommon.h | 1 + 2 files changed, 10 insertions(+) diff --git a/rtgui/popupcommon.cc b/rtgui/popupcommon.cc index 881994589..2a1387d3f 100644 --- a/rtgui/popupcommon.cc +++ b/rtgui/popupcommon.cc @@ -19,6 +19,7 @@ * Class created by Jean-Christophe FRISCH, aka 'Hombre' */ +#include #include "multilangmgr.h" #include "popupcommon.h" #include "../rtengine/safegtk.h" @@ -135,6 +136,14 @@ void PopUpCommon::entrySelected (int i) } } +void PopUpCommon::setItemSensitivity (int i, bool isSensitive) { + Gtk::Menu_Helpers::MenuList items = menu->items(); + if (i < items.size()) { + items[i].set_sensitive(isSensitive); + } +} + + /* * Set the button image with the selected item */ diff --git a/rtgui/popupcommon.h b/rtgui/popupcommon.h index 872beb434..7b05a08e9 100644 --- a/rtgui/popupcommon.h +++ b/rtgui/popupcommon.h @@ -68,6 +68,7 @@ private: void showMenu(GdkEventButton* event); void entrySelected (int i); + void setItemSensitivity (int i, bool isSensitive); }; From b856e210aed86d7c8da5bd4f1d4b969da8fbbd2f Mon Sep 17 00:00:00 2001 From: heckflosse Date: Tue, 8 Dec 2015 19:00:35 +0100 Subject: [PATCH 19/61] Fix Win32 Debug build part one --- rtengine/improcfun.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 8180c353f..f21748a3b 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -5824,7 +5824,7 @@ SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (EditBuffer *editBuffer, }; #ifdef _DEBUG - #pragma omp parallel default(shared) firstprivate(highlight, ccut, clut, chromaticity, bwToning, rstprotection, avoidColorShift, LCredsk, protectRed, protectRedH, gamutLch, lold, lnew, MunsDebugInfo, pW) if (multiThread) + #pragma omp parallel default(shared) firstprivate(lold, lnew, MunsDebugInfo, pW) if (multiThread) #else #pragma omp parallel if (multiThread) #endif From 031c41af60469314ccceef649c0683bf04a5205b Mon Sep 17 00:00:00 2001 From: heckflosse Date: Wed, 9 Dec 2015 01:54:47 +0100 Subject: [PATCH 20/61] Fix Win32 Debug build part two --- rtengine/ipvibrance.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/ipvibrance.cc b/rtengine/ipvibrance.cc index 2c91fbf01..3e6ff97f2 100644 --- a/rtengine/ipvibrance.cc +++ b/rtengine/ipvibrance.cc @@ -188,7 +188,7 @@ void ImProcFunctions::vibrance (LabImage* lab) MunsDebugInfo = new MunsellDebugInfo(); } - #pragma omp parallel default(shared) firstprivate(lab, width, height, chromaPastel, chromaSatur, highlight, limitpastelsatur, transitionweighting, protectskins, avoidcolorshift, MunsDebugInfo) reduction(+: negat, moreRGB, negsat, moresat) if (multiThread) + #pragma omp parallel default(shared) firstprivate(lab, MunsDebugInfo) reduction(+: negat, moreRGB, negsat, moresat) if (multiThread) #else #pragma omp parallel default(shared) if (multiThread) #endif From 26e094d56e996e76e995fd921ade7dcd0972171f Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Wed, 9 Dec 2015 14:04:02 +0100 Subject: [PATCH 21/61] Prevent segfault when invalid theme in options file, fixes #2991 --- rtgui/main.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rtgui/main.cc b/rtgui/main.cc index bbfca0c52..4ca8b94d7 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -278,6 +278,12 @@ int main(int argc, char **argv) if (options.theme.empty()) { options.theme = "21-Gray-Gray"; + } else { + std::string themeFile = argv0 + "/themes/" + options.theme + ".gtkrc"; + if (!std::ifstream(themeFile)) { + printf ("Current theme in options file is invalid: %s\nChanging to 21-Gray-Gray\n", options.theme.c_str()); + options.theme = "21-Gray-Gray"; + } } if (!options.useSystemTheme) { From 09062a95076bb3c2b3c63fb053047df5780be226 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Wed, 9 Dec 2015 15:44:28 +0100 Subject: [PATCH 22/61] Fix build problem with latest commit --- rtgui/main.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/main.cc b/rtgui/main.cc index 4ca8b94d7..03b85654e 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -280,7 +280,7 @@ int main(int argc, char **argv) options.theme = "21-Gray-Gray"; } else { std::string themeFile = argv0 + "/themes/" + options.theme + ".gtkrc"; - if (!std::ifstream(themeFile)) { + if (!std::ifstream(themeFile.c_str())) { printf ("Current theme in options file is invalid: %s\nChanging to 21-Gray-Gray\n", options.theme.c_str()); options.theme = "21-Gray-Gray"; } From 32eb6b996c73708d5dc30c75cf7f4fe4a8061028 Mon Sep 17 00:00:00 2001 From: Hombre Date: Tue, 15 Dec 2015 01:06:38 +0100 Subject: [PATCH 23/61] Adding softproofing. Now the output profile and the new rendering intent profile for the output profile will only be shown when the new softproof toggle button (bottom of the preview in the Editor panel) will be on. --- .../images/Dark/actions/intent-absolute.png | Bin 0 -> 464 bytes .../images/Dark/actions/intent-perceptual.png | Bin 0 -> 666 bytes .../images/Dark/actions/intent-relative.png | Bin 0 -> 944 bytes .../images/Dark/actions/intent-saturation.png | Bin 0 -> 809 bytes rtdata/images/Dark/actions/softProof.png | Bin 0 -> 827 bytes .../images/Light/actions/intent-absolute.png | Bin 0 -> 445 bytes .../Light/actions/intent-perceptual.png | Bin 0 -> 638 bytes .../images/Light/actions/intent-relative.png | Bin 0 -> 882 bytes .../Light/actions/intent-saturation.png | Bin 0 -> 779 bytes rtdata/images/Light/actions/softProof.png | Bin 0 -> 868 bytes rtdata/languages/default | 2 + rtengine/dcrop.cc | 8 +- rtengine/dcrop.h | 5 + rtengine/iccstore.h | 6 + rtengine/improccoordinator.cc | 45 +- rtengine/improccoordinator.h | 11 + rtengine/improcfun.cc | 44 +- rtengine/improcfun.h | 9 +- rtengine/iplab2rgb.cc | 16 +- rtengine/procevents.h | 3 + rtengine/procparams.cc | 34 +- rtengine/procparams.h | 12 +- rtengine/refreshmap.cc | 24 +- rtengine/refreshmap.h | 56 +- rtengine/rtengine.h | 8 +- rtengine/settings.h | 4 +- rtengine/simpleprocess.cc | 4 +- rtgui/editorpanel.cc | 171 +- rtgui/editorpanel.h | 2 +- rtgui/filecatalog.cc | 1 + rtgui/history.cc | 5 +- rtgui/icmpanel.cc | 29 +- rtgui/icmpanel.h | 1 + rtgui/options.cc | 10 +- rtgui/options.h | 1 + rtgui/paramsedited.cc | 5 + rtgui/paramsedited.h | 1 + rtgui/preferences.cc | 2 +- .../scalable/intent-absolute.file | 1 + .../source_icons/scalable/intent-absolute.svg | 1378 ++++++++++++++++ .../scalable/intent-perceptual.file | 1 + .../scalable/intent-perceptual.svg | 1366 ++++++++++++++++ .../scalable/intent-relative.file | 1 + .../source_icons/scalable/intent-relative.svg | 1374 ++++++++++++++++ .../scalable/intent-saturation.file | 1 + .../scalable/intent-saturation.svg | 1366 ++++++++++++++++ tools/source_icons/scalable/softProof.file | 1 + tools/source_icons/scalable/softProof.svg | 1389 +++++++++++++++++ 48 files changed, 7255 insertions(+), 142 deletions(-) create mode 100644 rtdata/images/Dark/actions/intent-absolute.png create mode 100644 rtdata/images/Dark/actions/intent-perceptual.png create mode 100644 rtdata/images/Dark/actions/intent-relative.png create mode 100644 rtdata/images/Dark/actions/intent-saturation.png create mode 100644 rtdata/images/Dark/actions/softProof.png create mode 100644 rtdata/images/Light/actions/intent-absolute.png create mode 100644 rtdata/images/Light/actions/intent-perceptual.png create mode 100644 rtdata/images/Light/actions/intent-relative.png create mode 100644 rtdata/images/Light/actions/intent-saturation.png create mode 100644 rtdata/images/Light/actions/softProof.png create mode 100644 tools/source_icons/scalable/intent-absolute.file create mode 100644 tools/source_icons/scalable/intent-absolute.svg create mode 100644 tools/source_icons/scalable/intent-perceptual.file create mode 100644 tools/source_icons/scalable/intent-perceptual.svg create mode 100644 tools/source_icons/scalable/intent-relative.file create mode 100644 tools/source_icons/scalable/intent-relative.svg create mode 100644 tools/source_icons/scalable/intent-saturation.file create mode 100644 tools/source_icons/scalable/intent-saturation.svg create mode 100644 tools/source_icons/scalable/softProof.file create mode 100644 tools/source_icons/scalable/softProof.svg diff --git a/rtdata/images/Dark/actions/intent-absolute.png b/rtdata/images/Dark/actions/intent-absolute.png new file mode 100644 index 0000000000000000000000000000000000000000..bb7e1a85d0cf0b4a131e3dc02ef8e74161a5f367 GIT binary patch literal 464 zcmV;>0WbcEP)P000&U1^@s6HNQ8u00004b3#c}2nYxW zdu*o9?cT=WR@DbA6 zO0c!hJ7}41leM!+At|&`v9i*1F|r7|_gbiBU@nY!>cjWJW#-Nh0AyL#VrCCTX0zGT za5&_Ut^)w)+<=)6G?GrIa{}N!SW;EhB@tyBNu$vyLc0zC>h=1=VzF=P000&U1^@s6HNQ8u00004b3#c}2nYxW zdPNB7i*4H_JLPvshJcg%IvI z=MvzN_Z|@$1EW08->Iq<<>q;Q02MXa+1aV5X?h!Ih)4ri0(3^oUZ>O9s6hEtg7ncvd&fYJMj5bGnS1NRb4Z)1v8s9R;rt^-|sh6b=}NvQguL{ zhI1M97rnHi<3bOdb2Ha(9LHx~zf<8~T;xaMANVyY-gCezlK=n!07*qoM6N<$g0=S` AF8}}l literal 0 HcmV?d00001 diff --git a/rtdata/images/Dark/actions/intent-relative.png b/rtdata/images/Dark/actions/intent-relative.png new file mode 100644 index 0000000000000000000000000000000000000000..c1fb040a9ddabae8f9ebdd03367c2bacbba0978c GIT binary patch literal 944 zcmV;h15f;kP)P000&U1^@s6HNQ8u00004b3#c}2nYxW zd z86-(Excq7v6hy(x@ z0Ki(CkUSQVeUd&S$&-IOIX^$YS1cB@=z@p zD*#g477;HZCrOfYYPDLgUayeLylW#=MplTvboPF#Md8s!&z#?(V*oBuQY5 zSpl%5s)h0P8GsXG%qXM4$6*+LNdRax8uyGbw=?oMRn3pTp8`0t*0wJ$F51;fYYo3#z)@Y&L5EUe5|HB9F@D@)r~70)YMf{Tsbr z?~aJ97-NC}4m9ueoxAOV?JEPGkl@V+0p8(Dr02B&^&$6U`eturd^A(Z5fUC=R z7eFdqBtddS@@EnG&N9o+Ty!fdc?z%>5)uZloGGC&S_Jw`m`!H2e+50fabx S=)Ix<0000P000&U1^@s6HNQ8u00004b3#c}2nYxW zdk)ELp(-tYN- z?m6Fkf&Wkf0L5Z)gyfEYZZ0x6Ffec}0Dzf&^4@3vHAGcE0rg4#wu;4KPF35RoyQm} z`Fy?<)@tg#?Jh>Vg<%n|^+_s;-42z8S_ zl8H~zIoA$gkff2k9b>$ss=cauh2&BQ;X<`qT}tYWF;*Irh{zrhNesSzJ`3R1%*@Q^ zo}QkAB=?bgCnAr{>{tlN3o)}-0Dk`XwzjrQ3kwTANtny!I5ad=o}Hb|c6WE5Cb^sB z{Sd-SRXt*6Z@u>)l6py&fEIuJ`1tr1@BKLu*#=r~{Yb4=`&}lV&FoA%oleyQ z|B}sS&kqg`{t?iCkQ^uZFiGH?V+i5i^78TqGrM4BWs+xmdwajN0sz*Q$yES8l}erJ z>+73u6#%sG8K0*|5aVxLlBlgKm=J>Z;E^NU?Mm+bW6O5 zhZZ~tiXQgv$3-#XO}vRlK@fF8Z{iA*kC)g)Q1IZAfF4A=8c5724w7`w>sKB!BjY$T z$$)<-cwJQex<2TBKtmG~6MxOk&HahrBxxRe-#?w_xdU(!0466VcYB_9n3*TSF#Nw? zFav-wX1}WL1h6Yj(-8m=kqZEhJLeu6W5%bZrndG2rZi2ZD2j1a-PZ6eW?6Q=R4Tmy z;57qP^^50uXTvajzNw1yJTE!tZm8-EfN52|31C|*6aa{5&^dR@7;|h>;5d%IMNu?Q zM2pV3#VCsAMTEP=djKvOW6o>{?&Kt*VuQTXv$M13Rh9Yz2SM;@ql%n!Cyg|5n&Nw zW~R3IJxfbV_tP{T>yY-hwf0`6Qu*VTp|`+ZTWbsFoQen&k*aDF zincuhfW`U;c5ifa^lMjexm^AXRf%R)6WZ7nqr!*6a0uYPH%95urTK z3nF@16vcxmic%uduDQLy<#O3F^A+dZ*LuDFukZT@!!SG%$MLgP==AjTsrF0a#|Dfs z2{Y@;%F2@t?+5_o-3k~Q8oKP9+penfs(L$)<8Q6tBSdthR|nmss#~x=R>#aAnE71S zzf(Ul##{w3NJMkhYV}c)Bt_5V^`RF70|U=SMn-B)$9E!tHa;dGDfa*X002ovPDHLk FV1jU2Y!3hc literal 0 HcmV?d00001 diff --git a/rtdata/images/Light/actions/intent-absolute.png b/rtdata/images/Light/actions/intent-absolute.png new file mode 100644 index 0000000000000000000000000000000000000000..1396e378553270124944c886d2536016f879e622 GIT binary patch literal 445 zcmV;u0Yd(XP)P000&U1^@s6HNQ8u00004b3#c}2nYxW zdZHp_>f})Ds;LOx90%L6aId8JZ-Jlhg9G^!15gyjz*@UQL`0+p+K{dV z==FNzwrvk%B+j`r5qS@msOq(<-o{A!{r;zj1a%ESp66+nWj014A|HSTOUkmmRMn_+ zB}o!@F5nJ$iji1rzhe4Zj{z8sM(3(pb`CeDs_Xj7t{xVu8ugw8N)}x+H_HHq!{Hbx zw!nXx&1REi3*i5W0dUTpsOq3|xG}FHa$^C!_xnkb9CR)5-e+AiH)g$EN2P000&U1^@s6HNQ8u00004b3#c}2nYxW zd9p#k(uphS(a}t5{BU&0N3jX&bccjACgq( z+=tn0_GUVrp0pNOhkn0*&CH&XybIujjIxQXI$k%xnih2f$YVW!+hl$7z}#cmSZP&zcHvW>8f` zQIwM$nb~MQpMNTf;$x@Nd17X_8#5630{|WXR8@7*lnH=~BGNarTLA8>>LXQ!@B6u# zjhu7uM1&2Q`~q6mq}%OYQq_T~4oMD4Mk1msG8rdHve!zaPSo?f8zgJvsA`cU$qx?z zq9}S!GTK&5r2bn;egp8zTaroSkp0Am1q9hnOyw;3MGDIXNd017|$jrt?Q7o2beB5+SL=pg>*P5|utoXjaL$V_x ztHw%uGX_C0bk6MpxQVs{avjcO)SvgGP000&U1^@s6HNQ8u00004b3#c}2nYxW zdyD28hkRH zPJb2vaL#?Fs@K{aNyY#!HOChsvIihHv)p_Cbd4s@)FmQbL|XZhG?JyN?v-Wv2mpt} z;X5QJ&bco|l8?RjKdplcyD! zT$bgpYvBTb!C>$)fNc?(nArrtyZ;sQ#*6Rw`?pnftId&QL~=m#z2@o_fPIpA6h(Pa z6pwL+F=*$z%aII8*Z>@n{5^`Iy`m_l0PI{0{eJ&*k|83`y!Ut4#^s#rh{!cF%S0pt z;2JRm?G0Scxf=l95BOeE)iKE-fVWf?0G^WEF|#~Lk|R|O;aUO>E>*pC(SkIynTYI? z%sZVP000&U1^@s6HNQ8u00004b3#c}2nYxW zdux+o%-Nw%r#M{DgyOztw!r175TodR$JKsU(+k~7Y^LvebNtGQh6eM81) zGMN)$7>)oqO>)&*`z#E@vN2{%RU^HuPm%?&4N0fd=K#b##jY?6&x?qXd>I76D-k&h zUB>GhRgAB@&4j*=)Ab+uM7Uxm;dLrBZF4=iMWD#u)P!z&BML5s`v1=6h7Gs+NETjqmU8 zKOO|ZIDnLh%&2NnMD75X_kDkS=jFw20ssaE208&Gq6EJ0cayvgpoQd95!nDRL9$e> zR>vxpN^P$uUA@rgZk_2tFHpzeu?bdo$4qX_^^?-y`j@f(*TH1x}--+TZ7002ov JPDHLkV1jwrP1yhd literal 0 HcmV?d00001 diff --git a/rtdata/images/Light/actions/softProof.png b/rtdata/images/Light/actions/softProof.png new file mode 100644 index 0000000000000000000000000000000000000000..2c12e216fe3e86915a5928a7a413c37a6219fc23 GIT binary patch literal 868 zcmV-q1DpJbP)F_~hZyqC1|D|6?a z(?w@OJI;&~@C%Q7Ih^x(-*fNfUSOcb#l`2AmX@Bu|0FY(*W)-oGe1B7bCzYTS;1VXR1AQ( z0E8kEG4tEY%ggfsUKl2+>RD#KnIy?8Gdu2dIwuN+LLGpJNR64lZnxVfnEB0-+yW7; z$8nscY5Mzrf?KVYPt)|DVzKzFs@|{FYPX8T;!^-FjO!3UC641lnx?m>fq86@IiFUf zsu!Je9|E9bfdSl|1|I0$BuOq!G&e3-tyVK4$^pO_L)Kch)>04zk2zG;3(mPu2M1s# z$2k#Y%#1J$If^2Vq9_Q%kgc_&?XNc)jnAEP(JWx7>R$k0tqr0m3I^ce$RoLDnfc3= zm6emTfd3eP$y&=p=hj*_#_;H}h{%hbPUp(%>guVfU;uv(Cxt>G2*WTK0*BuiGfS;j z>#}q1$$u^SQ7g>90LZ=fYK&nK(LB$InTeS}^f;G@`l|XpfXlU7?cPLiwOYNKB*{w39budY)dXk8YstPmLOQq5W6K|*EC`pn}RP_{q uAJ^8_u5WB?OuZdvmUHgaa=HA(qp=6oX)*PXM7#a~0000Alt-l MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l MAIN_TOOLTIP_THRESHOLD;Threshold MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b +MONITOR_PROFILE_SYSTEM;System default NAVIGATOR_B;B: NAVIGATOR_G;G: NAVIGATOR_H;H: @@ -1512,6 +1513,7 @@ TP_ICM_INPUTPROFILE;Input Profile TP_ICM_LABEL;Color Management TP_ICM_NOICM;No ICM: sRGB Output TP_ICM_OUTPUTPROFILE;Output Profile +TP_ICM_OUTPUTPROFILEINTENT;Output Rendering Intent TP_ICM_SAVEREFERENCE;Save Reference Image for Profiling TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Generally, apply the white balance when saving images to create ICC profiles, and do not apply the white balance to create DCP profiles. diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index a97ae7f39..cd68aa0a6 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -33,7 +33,7 @@ extern const Settings* settings; Crop::Crop (ImProcCoordinator* parent, EditDataProvider *editDataProvider, bool isDetailWindow) : EditBuffer(editDataProvider), origCrop(NULL), laboCrop(NULL), labnCrop(NULL), cropImg(NULL), cbuf_real(NULL), cshmap(NULL), transCrop(NULL), cieCrop(NULL), cbuffer(NULL), - updating(false), newUpdatePending(false), skip(10), + softProofing(false), updating(false), newUpdatePending(false), skip(10), cropx(0), cropy(0), cropw(-1), croph(-1), trafx(0), trafy(0), trafw(-1), trafh(-1), rqcropx(0), rqcropy(0), rqcropw(-1), rqcroph(-1), @@ -987,7 +987,7 @@ void Crop::update (int todo) EditBuffer::setReady(); // switch back to rgb - parent->ipf.lab2monitorRgb (labnCrop, cropImg); + parent->ipf.lab2monitorRgb (labnCrop, cropImg, softProofing); //parent->ipf.lab2monitorRgb (laboCrop, cropImg); @@ -1030,13 +1030,13 @@ void Crop::update (int todo) Image8 *cropImgtrue; if(settings->HistogramWorking) { - cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, workProfile, false); + cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, workProfile, RI_RELATIVE, false); // HOMBRE: was RELATIVE by default in lab2rgb, is it safe to assume we have to use it again ? } else { if (params.icm.output == "" || params.icm.output == ColorManagementParams::NoICMString) { outProfile = "sRGB"; } - cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, outProfile, false); + cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, outProfile, params.icm.outputIntent, false); } int finalW = rqcropw; diff --git a/rtengine/dcrop.h b/rtengine/dcrop.h index 57f388a51..ea9b1bc00 100644 --- a/rtengine/dcrop.h +++ b/rtengine/dcrop.h @@ -54,6 +54,7 @@ protected: // ----------------------------------------------------------------- float** cbuffer; + bool softProofing; /// True if the Crop has to display a soft proof of the output with its profile bool updating; /// Flag telling if an updater thread is currently processing bool newUpdatePending; /// Flag telling the updater thread that a new update is pending int skip; @@ -103,6 +104,10 @@ public: /** @brief Asynchronously reprocess the detailed crop */ void fullUpdate (); // called via thread + void setSoftProofing(bool doSoftProof) { + softProofing = doSoftProof; + } + void setListener (DetailedCropListener* il); void destroy (); int get_skip () diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h index ed9fbb424..6b41987f7 100644 --- a/rtengine/iccstore.h +++ b/rtengine/iccstore.h @@ -91,6 +91,7 @@ public: // Main monitors standard profile name, from OS void findDefaultMonitorProfile (); cmsHPROFILE getDefaultMonitorProfile () const; + Glib::ustring getDefaultMonitorProfileStr () const; cmsHPROFILE workingSpace (const Glib::ustring& name) const; cmsHPROFILE workingSpaceGamma (const Glib::ustring& name) const; @@ -134,6 +135,11 @@ inline cmsHPROFILE ICCStore::getDefaultMonitorProfile () const return getProfile (defaultMonitorProfile); } +inline Glib::ustring ICCStore::getDefaultMonitorProfileStr () const +{ + return defaultMonitorProfile; +} + inline std::uint8_t ICCStore::getInputIntents (const Glib::ustring &name) const { return getInputIntents (getProfile (name)); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 8389ec34e..62de26076 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -31,9 +31,9 @@ extern const Settings* settings; ImProcCoordinator::ImProcCoordinator () : orig_prev(NULL), oprevi(NULL), oprevl(NULL), nprevl(NULL), previmg(NULL), workimg(NULL), - ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), scale(10), - highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), - bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.), + ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), monitorIntent(RI_PERCEPTUAL), scale(10), + highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), isColorProfileDirty(true), + softProofing(false), bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.), hltonecurve(65536), shtonecurve(65536), @@ -781,9 +781,16 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } } + // Update the output color transform if necessary + if (isColorProfileDirty || (todo & M_MONITOR)) { + ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent, softProofing); + isColorProfileDirty = false; + } + // process crop, if needed for (size_t i = 0; i < crops.size(); i++) if (crops[i]->hasListener () && cropCall != crops[i] ) { + crops[i]->setSoftProofing(softProofing); crops[i]->update (todo); // may call ourselves } @@ -794,23 +801,23 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) progress ("Conversion to RGB...", 100 * readyphase / numofphases); - if (todo != CROP && todo != MINUPDATE) { + if ((todo != CROP && todo != MINUPDATE) || (todo & M_MONITOR)) { MyMutex::MyLock prevImgLock(previmg->getMutex()); try { - ipf.lab2monitorRgb (nprevl, previmg); + ipf.lab2monitorRgb (nprevl, previmg, softProofing); delete workimg; Glib::ustring outProfile = params.icm.output; if(settings->HistogramWorking) { Glib::ustring workProfile = params.icm.working; - workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, workProfile, true); + workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, workProfile, RI_RELATIVE, true); // HOMBRE: was RELATIVE by default in lab2rgb, is it safe to assume we have to use it again ? } else { - if (params.icm.output == "" || params.icm.output == ColorManagementParams::NoICMString) { + if (params.icm.output.empty() || params.icm.output == ColorManagementParams::NoICMString) { outProfile = "sRGB"; } - workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, outProfile, false); + workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, outProfile, params.icm.outputIntent, false); } } catch(char * str) { progress ("Error converting file...", 0); @@ -1126,6 +1133,28 @@ void ImProcCoordinator::getAutoCrop (double ratio, int &x, int &y, int &w, int & y = (fullh - h) / 2; } +void ImProcCoordinator::setSoftProofing (bool softProof) +{ + softProofing = softProof; +} + +void ImProcCoordinator::setMonitorProfile (Glib::ustring profile, eRenderingIntent intent) +{ + if (profile != monitorProfile) { + monitorProfile = profile; + isColorProfileDirty = true; + } + if (intent != monitorIntent) { + monitorIntent = intent; + isColorProfileDirty = true; + } +} + +void ImProcCoordinator::getMonitorProfile (Glib::ustring &profile, eRenderingIntent &intent) +{ + profile = monitorProfile; + intent = monitorIntent; +} void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname, bool apply_wb) { diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index ef981fe6a..901804eba 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -72,11 +72,18 @@ protected: ImProcFunctions ipf; + Glib::ustring monitorProfile; + + eRenderingIntent monitorIntent; + int scale; bool highDetailPreprocessComputed; bool highDetailRawComputed; bool allocated; + bool isColorProfileDirty; + bool softProofing; + void freeAll (); // Precomputed values used by DetailedCrop ---------------------------------------------- @@ -249,6 +256,10 @@ public: void getSpotWB (int x, int y, int rectSize, double& temp, double& green); void getAutoCrop (double ratio, int &x, int &y, int &w, int &h); + void setMonitorProfile (Glib::ustring profile, eRenderingIntent intent); + void getMonitorProfile (Glib::ustring &profile, eRenderingIntent &intent); + void setSoftProofing (bool softProof); + bool updateTryLock () { return updaterThreadStart.trylock(); diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index c9fa3c6c8..e99daa79a 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -186,12 +186,11 @@ void ImProcFunctions::CAT02 (Imagefloat* baseImg, const ProcParams* params) } } */ -void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* params, LUTu & histogram) + + +void ImProcFunctions::updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, eRenderingIntent monitorIntent, bool softProofing) { - // set up monitor transform - Glib::ustring wprofile = params->icm.working; - if (monitorTransform != NULL) { cmsDeleteTransform (monitorTransform); } @@ -210,36 +209,30 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par #if !defined(__APPLE__) // No support for monitor profiles on OS X, all data is sRGB -#if defined(WIN32) - - cmsHPROFILE monitor = settings->autoMonitorProfile - ? iccStore->getDefaultMonitorProfile () - : iccStore->getProfile (params->icm.monitorProfile); - -#else - - cmsHPROFILE monitor = iccStore->getProfile (params->icm.monitorProfile); - -#endif + cmsHPROFILE monitor = iccStore->getProfile (monitorProfile); + printf("ImProcFunctions::updateColorProfiles / monitor profile = %s / intent = %d\n", monitorProfile.c_str(), monitorIntent); if (monitor) { MyMutex::MyLock lcmsLock (*lcmsMutex); cmsHPROFILE iprof = cmsCreateLab4Profile(NULL); - monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, params->icm.monitorIntent, + printf(" - monitorTransform = cmsCreateTransform / intent=%d\n", monitorIntent); + monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is for thread safety, NOOPTIMIZE for precision Glib::ustring outputProfile; - if (params->icm.output != "" && params->icm.output != ColorManagementParams::NoICMString) { - outputProfile = params->icm.output; + if (!icm.output.empty() && icm.output != ColorManagementParams::NoICMString) { + outputProfile = icm.output; cmsHPROFILE jprof = iccStore->getProfile(outputProfile); if (jprof) { - lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); + //TODO: Create a dedicated softproof transformation (line below to be finished) + //lab2outputTransform = cmsCreateProofingTransform(iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, monitor, icm.outputIntent, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE | cmsFLAGS_SOFTPROOFING ); - if (monitor) { - output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, params->icm.monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); - } + printf(" - lab2outputTransform = cmsCreateTransform / intent=%d\n", icm.outputIntent); + lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, icm.outputIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); + printf(" - output2monitorTransform = cmsCreateTransform / intent=%d\n", monitorIntent); + output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); } } @@ -247,6 +240,13 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par } #endif +} + +void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* params, LUTu & histogram) +{ + + Glib::ustring wprofile = params->icm.working; + // calculate histogram of the y channel needed for contrast curve calculation in exposure adjustments int T = 1; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index cfabbba64..c34219c0d 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -233,6 +233,7 @@ public: bool needsPCVignetting (); void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16); + void updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, eRenderingIntent monitorIntent, bool softProofing); void rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *editBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf); @@ -265,7 +266,7 @@ public: void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, double focalLen, double focalLen35mm, float focusDist, int rawRotationDeg, bool fullImage); float resizeScale (const ProcParams* params, int fw, int fh, int &imw, int &imh); - void lab2monitorRgb (LabImage* lab, Image8* image); + void lab2monitorRgb (LabImage* lab, Image8* image, bool softProofing=false); void resize (Image16* src, Image16* dst, float dScale); void Lanczos (const LabImage* src, LabImage* dst, float scale); void Lanczos (const Image16* src, Image16* dst, float scale); @@ -379,9 +380,9 @@ public: void Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad); void BadpixelsLab(LabImage * src, LabImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom); - Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool standard_gamma); - Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw);// for gamma output - Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool bw);//without gamma ==>default + Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool standard_gamma); + Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw);// for gamma output + Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool bw);//without gamma ==>default // CieImage *ciec; 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, const LCPMapper *pLCPMap = NULL); diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index cc01b783f..a727423ef 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -39,7 +39,7 @@ const double (*iwprof[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz, const char* wprofnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB"}; const int numprof = 7; -void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) +void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image, bool softProofing) { //gamutmap(lab); @@ -78,7 +78,7 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) buffer[iy++] = rb[j] / 327.68f; } - if (!settings->HistogramWorking && output2monitorTransform && lab2outputTransform) { + if (softProofing && !settings->HistogramWorking && output2monitorTransform && lab2outputTransform) { AlignedBuffer buf(3 * W); cmsDoTransform (lab2outputTransform, buffer, buf.data, W); cmsDoTransform (output2monitorTransform, buf.data, data + ix, W); @@ -134,7 +134,7 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) } } -Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool standard_gamma) +Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool standard_gamma) { //gamutmap(lab); @@ -167,7 +167,7 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, lcmsMutex->lock (); cmsHPROFILE hLab = cmsCreateLab4Profile(NULL); - cmsHTRANSFORM hTransform = cmsCreateTransform (hLab, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC, + cmsHTRANSFORM hTransform = cmsCreateTransform (hLab, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety cmsCloseProfile(hLab); lcmsMutex->unlock (); @@ -259,7 +259,7 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, return image; } // for default (not gamma) -Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool bw) +Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool bw) { //gamutmap(lab); @@ -322,7 +322,7 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int cmsHPROFILE iprof = iccStore->getXYZProfile (); lcmsMutex->lock (); - cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); lcmsMutex->unlock (); image->ExecCMSTransform(hTransform); @@ -363,7 +363,7 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int // for gamma options (BT709...sRGB linear...) -Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw) +Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw) { //gamutmap(lab); @@ -593,7 +593,7 @@ Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int cmsHPROFILE iprof = iccStore->getXYZProfile (); lcmsMutex->lock (); - cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); lcmsMutex->unlock (); image->ExecCMSTransform(hTransform); diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 4dbbad07c..4609c674a 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -454,6 +454,9 @@ enum ProcEvent { EvLbaselog = 424, // EvLgrbl = 425, EvRetinexlhcurve = 425, + EvOIntent = 426, + EvSoftProof = 427, + EvMonitorTransform = 428, NUMOFEVENTS }; } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 44c02a531..2c93bfd47 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -894,8 +894,7 @@ void ColorManagementParams::setDefaults() dcpIlluminant = 0; working = "ProPhoto"; output = "RT_sRGB"; - monitorProfile = Glib::ustring (); - monitorIntent = 1; + outputIntent = RI_PERCEPTUAL; gamma = "default"; gampos = 2.22; slpos = 4.5; @@ -2550,6 +2549,20 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol keyFile.set_string ("Color Management", "OutputProfile", icm.output); } + if (!pedited || pedited->icm.outputIntent) { + Glib::ustring intent; + if (icm.outputIntent == RI_PERCEPTUAL) { + intent = "Perceptual"; + } else if (icm.outputIntent == RI_RELATIVE) { + intent = "Relative"; + } else if (icm.outputIntent == RI_SATURATION) { + intent = "Saturation"; + } else if (icm.outputIntent == RI_ABSOLUTE) { + intent = "Absolute"; + } + keyFile.set_string ("Color Management", "OutputProfileIntent", intent); + } + if (!pedited || pedited->icm.gamma) { keyFile.set_string ("Color Management", "Gammafree", icm.gamma); } @@ -5674,6 +5687,23 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) } } + if (keyFile.has_key ("Color Management", "OutputProfileIntent")) { + Glib::ustring intent = keyFile.get_string ("Color Management", "OutputProfileIntent"); + if (intent == "Perceptual") { + icm.outputIntent = RI_PERCEPTUAL; + } else if (intent == "Relative") { + icm.outputIntent = RI_RELATIVE; + } else if (intent == "Saturation") { + icm.outputIntent = RI_SATURATION; + } else if (intent == "Absolute") { + icm.outputIntent = RI_ABSOLUTE; + } + + if (pedited) { + pedited->icm.outputIntent = true; + } + } + if (keyFile.has_key ("Color Management", "Gammafree")) { icm.gamma = keyFile.get_string ("Color Management", "Gammafree"); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 77c1004e8..cbbbed7a5 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "LUT.h" #include "coord.h" @@ -41,6 +42,14 @@ class WavOpacityCurveW; class WavOpacityCurveWL; class RetinextransmissionCurve; +typedef enum RenderingIntent { + RI_PERCEPTUAL = INTENT_PERCEPTUAL, + RI_RELATIVE = INTENT_RELATIVE_COLORIMETRIC, + RI_SATURATION = INTENT_SATURATION, + RI_ABSOLUTE = INTENT_ABSOLUTE_COLORIMETRIC, + RI__COUNT +} eRenderingIntent; + namespace procparams { @@ -941,8 +950,7 @@ public: int dcpIlluminant; Glib::ustring working; Glib::ustring output; - Glib::ustring monitorProfile; // Not stored persistently as it is just an optional settings override. - int monitorIntent; // Not store persistently as it is just an optional settings override. + eRenderingIntent outputIntent; static const Glib::ustring NoICMString; Glib::ustring gamma; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 3505da24f..37d0f52b4 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -64,9 +64,9 @@ int refreshmap[rtengine::NUMOFEVENTS] = { DARKFRAME, // EvLCPUseVign, TRANSFORM, // EvLCPUseCA, M_VOID, // EvFixedExp - WHITEBALANCE, // EvWBMethod, - WHITEBALANCE, // EvWBTemp, - WHITEBALANCE, // EvWBGreen, + ALLNORAW, // EvWBMethod, + ALLNORAW, // EvWBTemp, + ALLNORAW, // EvWBGreen, RGBCURVE, // EvToneCurveMode1, RGBCURVE, // EvToneCurve2, RGBCURVE, // EvToneCurveMode2, @@ -75,7 +75,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { 0, // EvCDNEnabled:obsolete, ALL, // EvBlendCMSMatrix, RGBCURVE, // EvDCPToneCurve, - INPUTPROFILE, // EvDCPIlluminant, + ALLNORAW, // EvDCPIlluminant, RETINEX, // EvSHEnabled, RGBCURVE, // EvSHHighlights, RGBCURVE, // EvSHShadows, @@ -97,7 +97,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { ALLNORAW, // EvHRMethod, ALLNORAW, // EvWProfile, OUTPUTPROFILE, // EvOProfile, - INPUTPROFILE, // EvIProfile, + ALLNORAW, // EvIProfile, TRANSFORM, // EvVignettingAmount, RGBCURVE, // EvChMixer, RESIZE, // EvResizeScale, @@ -234,8 +234,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // EvCATbadpix LUMINANCECURVE, // EvCATAutoadap DEFRINGE, // EvPFCurve - WHITEBALANCE, // EvWBequal - WHITEBALANCE, // EvWBequalbo + ALLNORAW, // EvWBequal + ALLNORAW, // EvWBequalbo TRANSFORM, // EvGradientDegree TRANSFORM, // EvGradientEnabled TRANSFORM, // EvPCVignetteStrength @@ -421,7 +421,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { DIRPYREQUALIZER, // EvWavNeutral RGBCURVE, // EvDCPApplyLookTable, RGBCURVE, // EvDCPApplyBaselineExposureOffset, - INPUTPROFILE, // EvDCPApplyHueSatMap + ALLNORAW, // EvDCPApplyHueSatMap DIRPYREQUALIZER, // EvWavenacont DIRPYREQUALIZER, // EvWavenachrom DIRPYREQUALIZER, // EvWavenaedge @@ -452,7 +452,11 @@ int refreshmap[rtengine::NUMOFEVENTS] = { DEMOSAIC, // EvLslope RETINEX, // EvLhighl DEMOSAIC, // EvLbaselog -// DEMOSAIC, // EvLgrbl - DEMOSAIC // EvRetinexlhcurve +// DEMOSAIC, // EvLgrbl + DEMOSAIC, // EvRetinexlhcurve + ALLNORAW, // EvOIntent + ALLNORAW, // EvSoftProof + MONITORTRANSFORM // EvMonitorTransform + }; diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h index e24d0c422..23e179f9f 100644 --- a/rtengine/refreshmap.h +++ b/rtengine/refreshmap.h @@ -20,15 +20,16 @@ #define __REFRESHMAP__ // Use M_VOID if you wish to update the proc params without updating the preview at all ! -#define M_VOID (1<<15) +#define M_VOID (1<<16) // Use M_MINUPDATE if you wish to update the preview without modifying the image (think about it like a "refreshPreview") // Must NOT be used with other event (i.e. will be used for MINUPDATE only) -#define M_MINUPDATE (1<<14) +#define M_MINUPDATE (1<<15) // Force high quality -#define M_HIGHQUAL (1<<13) +#define M_HIGHQUAL (1<<14) // Elementary functions that can be done to // the preview image when an event occurs +#define M_MONITOR (1<<13) #define M_RETINEX (1<<12) #define M_CROP (1<<11) #define M_PREPROC (1<<10) @@ -45,31 +46,30 @@ // Bitfield of functions to do to the preview image when an event occurs // Use those or create new ones for your new events -#define FIRST (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL -#define ALL (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL -#define TRANSFORM (M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define AUTOEXP (M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define RGBCURVE (M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define LUMINANCECURVE (M_LUMACURVE|M_LUMINANCE) -#define SHARPENING M_LUMINANCE -#define IMPULSEDENOISE M_LUMINANCE -#define DEFRINGE M_LUMINANCE -#define WHITEBALANCE (M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define DEMOSAIC (M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define DARKFRAME (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define FLATFIELD (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define DIRPYRDENOISE (M_COLOR|M_LUMINANCE) -#define CROP M_CROP -#define RESIZE M_VOID -#define EXIF M_VOID -#define IPTC M_VOID -#define DIRPYREQUALIZER (M_COLOR|M_LUMINANCE) -#define OUTPUTPROFILE (M_INIT|M_COLOR|M_LUMINANCE) -#define INPUTPROFILE WHITEBALANCE -#define GAMMA (M_COLOR|M_LUMINANCE) -#define MINUPDATE M_MINUPDATE -#define ALLNORAW (M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define RETINEX (M_RETINEX|ALLNORAW) +#define FIRST (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL +#define ALL (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL +#define DARKFRAME (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define FLATFIELD (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define DEMOSAIC (M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define ALLNORAW (M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define TRANSFORM (M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define AUTOEXP (M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define RGBCURVE (M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define LUMINANCECURVE (M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define SHARPENING (M_LUMINANCE|M_COLOR) +#define IMPULSEDENOISE (M_LUMINANCE|M_COLOR) +#define DEFRINGE (M_LUMINANCE|M_COLOR) +#define DIRPYRDENOISE (M_LUMINANCE|M_COLOR) +#define DIRPYREQUALIZER (M_LUMINANCE|M_COLOR) +#define GAMMA (M_LUMINANCE|M_COLOR) +#define CROP M_CROP +#define RESIZE M_VOID +#define EXIF M_VOID +#define IPTC M_VOID +#define MINUPDATE M_MINUPDATE +#define RETINEX (M_RETINEX|ALLNORAW) +#define MONITORTRANSFORM M_MONITOR +#define OUTPUTPROFILE (ALLNORAW|MONITORTRANSFORM) extern int refreshmap[]; #endif diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 195911a3a..d10acb561 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -35,7 +35,7 @@ #include "LUT.h" /** * @file - * This file contains the main functionality of the raw therapee engine. + * This file contains the main functionality of the RawTherapee engine. * */ @@ -413,9 +413,13 @@ public: virtual void setAutoBWListener (AutoBWListener* l) = 0; virtual void setAutoColorTonListener (AutoColorTonListener* l) = 0; virtual void setAutoChromaListener (AutoChromaListener* l) = 0; - virtual void setRetinexListener (RetinexListener* l) = 0; + virtual void setRetinexListener (RetinexListener* l) = 0; virtual void setWaveletListener (WaveletListener* l) = 0; + virtual void setMonitorProfile (Glib::ustring monitorProfile, eRenderingIntent intent) = 0; + virtual void getMonitorProfile (Glib::ustring &monitorProfile, eRenderingIntent &intent) = 0; + virtual void setSoftProofing (bool softProof) = 0; + virtual ~StagedImageProcessor () {} /** Returns a staged, cached image processing manager supporting partial updates diff --git a/rtengine/settings.h b/rtengine/settings.h index bd37faaf2..98c85ba6f 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -19,6 +19,8 @@ #ifndef _RTSETTINGS_ #define _RTSETTINGS_ +#include "procparams.h" + namespace rtengine { @@ -37,7 +39,7 @@ public: int leveldnautsimpl; // STD or EXPERT Glib::ustring monitorProfile; ///< ICC profile name used for the monitor - int monitorIntent; ///< Colorimetric intent used with the above profile + eRenderingIntent monitorIntent; ///< Colorimetric intent used with the above profile bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile bool autocielab; bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 5ea834b2d..1edfa590c 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1151,7 +1151,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p cmsFloat64Number Parameters[7]; double ga0, ga1, ga2, ga3, ga4, ga5, ga6; // if(params.blackwhite.enabled) params.toneCurve.hrenabled=false; - readyImg = ipf.lab2rgb16b (labView, cx, cy, cw, ch, params.icm.output, params.icm.working, params.icm.gamma, params.icm.freegamma, params.icm.gampos, params.icm.slpos, ga0, ga1, ga2, ga3, ga4, ga5, ga6, params.blackwhite.enabled ); + readyImg = ipf.lab2rgb16b (labView, cx, cy, cw, ch, params.icm.output, params.icm.outputIntent, params.icm.working, params.icm.gamma, params.icm.freegamma, params.icm.gampos, params.icm.slpos, ga0, ga1, ga2, ga3, ga4, ga5, ga6, params.blackwhite.enabled ); customGamma = true; //or selected Free gamma @@ -1343,7 +1343,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p bwonly = false; } - readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output, bwonly); + readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output, params.icm.outputIntent, bwonly); if (settings->verbose) { printf("Output profile_: \"%s\"\n", params.icm.output.c_str()); diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index c6d2804c1..a762fc95b 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -35,88 +35,171 @@ using namespace rtengine::procparams; class MonitorProfileSelector { private: - Gtk::ComboBoxText profileBox; - Gtk::ComboBoxText intentBox; + Gtk::ToggleButton* softProof; + MyComboBoxText* profileBox; + //PopUpButton* intentBox; + MyComboBoxText* intentBox; + sigc::connection profileConn, intentConn; - rtengine::StagedImageProcessor* const& processor; + rtengine::StagedImageProcessor* processor; private: - MonitorProfileSelector(const MonitorProfileSelector&); - MonitorProfileSelector& operator=(const MonitorProfileSelector&); + void prepareSoftProofButton () + { + Gtk::Image *softProofImg = Gtk::manage (new RTImage("softProof.png")); + softProofImg->set_padding(0, 0); + softProof = Gtk::manage(new Gtk::ToggleButton()); + softProof->add(*softProofImg); + softProof->set_relief(Gtk::RELIEF_NONE); + softProof->signal_toggled().connect (sigc::mem_fun (this, &MonitorProfileSelector::softProofToggled)); + } void prepareProfileBox () { - profileBox.append_text (M("PREFERENCES_PROFILE_NONE")); - profileBox.set_active (0); + profileBox = Gtk::manage(new MyComboBoxText()); + profileBox->set_size_request(100,-1); - const std::vector profiles = rtengine::ICCStore::getInstance ()->getProfiles (); - for (std::vector::const_iterator iterator = profiles.begin (); iterator != profiles.end (); ++iterator) - profileBox.append_text (*iterator); + profileBox->append_text (M("PREFERENCES_PROFILE_NONE")); + #if defined(WIN32) + profileBox->append_text (M("MONITOR_PROFILE_SYSTEM") + " (" + rtengine::iccStore->getDefaultMonitorProfileStr() + ")"); + profileBox->set_active (options.rtSettings.autoMonitorProfile ? 1 : 0); + #else + profileBox->set_active (0); + #endif + + const std::vector profiles = rtengine::iccStore->getProfiles (); + for (std::vector::const_iterator iterator = profiles.begin (); iterator != profiles.end (); ++iterator) { + profileBox->append_text (*iterator); + } + profileConn = profileBox->signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); } void prepareIntentBox () { - intentBox.append_text (M("PREFERENCES_INTENT_RELATIVE")); - intentBox.append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); - intentBox.set_active (0); + intentBox = Gtk::manage(new MyComboBoxText()); + intentBox->set_size_request(-1,-1); + //intentBox = Gtk::manage(new PopUpButton()); + + intentBox->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); + intentBox->append_text (M("PREFERENCES_INTENT_RELATIVE")); + //intentBox->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); + //intentBox->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); + //intentBox->setSelected(0); + intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); + //intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateIntent)); + } + + void softProofToggled () + { + if (processor) { + processor->setSoftProofing( softProof->get_active() ); + processor->endUpdateParams ( rtengine::EvMonitorTransform ); + } + } + + void updateIntent (int i) + { + updateParameters(); } void updateParameters () { - const Glib::ustring profile = profileBox.get_active_row_number () > 0 ? profileBox.get_active_text () : Glib::ustring(); + Glib::ustring profile; +#ifdef WIN32 + if (profileBox->get_active_row_number () == 1) { + profile = rtengine::iccStore->getDefaultMonitorProfileStr (); + if (profile.empty()) { + profile = options.rtSettings.monitorProfile; + } + if (profile.empty()) { + profile = "sRGB IEC61966-2.1"; // assuming this profile always exist on Windows + } + } else if (profileBox->get_active_row_number () > 1) { + profile = profileBox->get_active_text (); + } +#else + profile = profileBox->get_active_row_number () > 0 ? profileBox->get_active_text () : Glib::ustring(); +#endif - std::uint8_t supportedIntents = rtengine::ICCStore::getInstance ()->getProofIntents (profile); + std::uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile); const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL; const bool supportsRelativeColorimetric = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC; if (supportsPerceptual && supportsRelativeColorimetric) { - intentBox.set_sensitive (true); + intentBox->set_sensitive (true); } else { - intentBox.set_sensitive (false); - intentBox.set_active (supportsPerceptual ? 1 : 0); + bool wasBlocked = intentConn.block(true); + intentBox->set_active(supportsPerceptual ? 0 : 1); + //intentBox->setSelected(supportsPerceptual ? 0 : 1); + intentBox->set_sensitive (false); + intentConn.block(wasBlocked); } - const int intent = intentBox.get_active_row_number () > 0 ? INTENT_PERCEPTUAL : INTENT_RELATIVE_COLORIMETRIC; + //rtengine::eRenderingIntent intent = intentBox->getSelected() > 0 ? rtengine::RI_PERCEPTUAL : rtengine::RI_RELATIVE; + rtengine::eRenderingIntent intent = intentBox->get_active_row_number() > 0 ? rtengine::RI_RELATIVE : rtengine::RI_PERCEPTUAL; - if (!processor) + if (!processor) { return; + } - rtengine::ProcParams* parameters = processor->beginUpdateParams (); + // either store them in the options file for the default value when opening the next EditorPanel + //options.rtSettings.monitorProfile = profile; + //options.rtSettings.monitorIntent = intent; - parameters->icm.monitorProfile = profile; - parameters->icm.monitorIntent = intent; - - processor->endUpdateParams (rtengine::EvOProfile); + // ...or store them locally + printf("Appel de processor->setMonitorProfile(%s, %d)\n", profile.c_str(), intent); + processor->setMonitorProfile(profile, intent); + printf("Appel de processor->endUpdateParams(%d)\n", rtengine::EvMonitorTransform); + processor->endUpdateParams (rtengine::EvMonitorTransform); } public: - MonitorProfileSelector (rtengine::StagedImageProcessor* const& ipc) : - profileBox (), - intentBox (), - processor (ipc) + MonitorProfileSelector () : + processor (NULL) { + prepareSoftProofButton (); prepareProfileBox (); prepareIntentBox (); reset (); - - profileBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); - intentBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); } - void pack_end (Gtk::Box* box) + // HOMBRE: renamed to 'pack_end_in', because 'pack_end' already widely used by Gtk::Widget in a different way + void pack_end_in (Gtk::Box* box) { - box->pack_end (intentBox, Gtk::PACK_SHRINK, 0); - box->pack_end (profileBox, Gtk::PACK_SHRINK, 0); + box->pack_end (*softProof, Gtk::PACK_SHRINK, 0); + box->pack_end (*intentBox, Gtk::PACK_SHRINK, 0); + box->pack_end (*profileBox, Gtk::PACK_EXPAND_WIDGET, 0); } void reset () { - setActiveTextOrIndex (profileBox, options.rtSettings.monitorProfile, 0); - intentBox.set_active (options.rtSettings.monitorIntent == INTENT_PERCEPTUAL ? 1 : 0); + bool wasBlocked; +#ifdef WIN32 + wasBlocked = profileConn.block(true); + if (options.rtSettings.autoMonitorProfile) { + setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 1); + } else { + setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 0); + } + profileConn.block(wasBlocked); +#else + wasBlocked = profileConn.block(true); + setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 0); + profileConn.block(wasBlocked); +#endif + wasBlocked = intentConn.block(true); + intentBox->set_active (options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 0 : 1); + //intentBox->setSelected(options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 0 : 1); + intentConn.block(wasBlocked); - updateParameters (); + // useless, set_active will trigger the signal_changed event + //updateParameters (); + } + + void setImageProcessor (rtengine::StagedImageProcessor* imageProc) { + processor = imageProc; } }; @@ -269,6 +352,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) // Save buttons Gtk::HBox* iops = Gtk::manage (new Gtk::HBox ()); + iops->set_spacing(2); //Gtk::Image *saveButtonImage = Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON)); Gtk::Image *saveButtonImage = Gtk::manage (new RTImage ("gtk-save-large.png")); @@ -346,14 +430,16 @@ EditorPanel::EditorPanel (FilePanel* filePanel) navSync->set_relief(Gtk::RELIEF_NONE); navSync->set_tooltip_markup(M("MAIN_BUTTON_NAVSYNC_TOOLTIP")); + iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); iops->pack_end (*navNext, Gtk::PACK_SHRINK, 0); iops->pack_end (*navSync, Gtk::PACK_SHRINK, 0); iops->pack_end (*navPrev, Gtk::PACK_SHRINK, 0); - iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); } - monitorProfile.reset(new MonitorProfileSelector (ipc)); - monitorProfile->pack_end (iops); + // Monitor profile buttons + iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); + monitorProfile = new MonitorProfileSelector (); + monitorProfile->pack_end_in (iops); editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0); editbox->pack_start (*iops, Gtk::PACK_SHRINK, 0); @@ -491,6 +577,7 @@ EditorPanel::~EditorPanel () delete ppframe; delete leftbox; delete vboxright; + delete monitorProfile; //delete saveAsDialog; if(catalogPane) { @@ -612,6 +699,7 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) this->isrc = isrc; ipc = rtengine::StagedImageProcessor::create (isrc); + monitorProfile->setImageProcessor(ipc); ipc->setProgressListener (this); ipc->setPreviewImageListener (previewHandler); ipc->setPreviewScale (10); // Important @@ -662,6 +750,7 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) history->resetSnapShotNumber(); + //HOMBRE: not sure if we want to reset on opening a new image monitorProfile->reset (); } diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index ffb8a93a4..0575b7f92 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -86,7 +86,7 @@ protected: Gtk::Button* navNext; Gtk::Button* navPrev; - std::auto_ptr monitorProfile; + MonitorProfileSelector* monitorProfile; ImageAreaPanel* iareapanel; PreviewHandler* previewHandler; diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index d40b7d720..0112f9ebf 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -1139,6 +1139,7 @@ void FileCatalog::developRequested (std::vector tbe, bool fas params.icm.input = options.fastexport_icm_input ; params.icm.working = options.fastexport_icm_working ; params.icm.output = options.fastexport_icm_output ; + params.icm.outputIntent = options.fastexport_icm_outputIntent ; params.icm.gamma = options.fastexport_icm_gamma ; params.resize.enabled = options.fastexport_resize_enabled ; params.resize.scale = options.fastexport_resize_scale ; diff --git a/rtgui/history.cc b/rtgui/history.cc index 57f7549db..689ea6394 100644 --- a/rtgui/history.cc +++ b/rtgui/history.cc @@ -24,7 +24,6 @@ using namespace rtengine; using namespace rtengine::procparams; Glib::ustring eventDescrArray[NUMOFEVENTS]; -extern Glib::ustring argv0; History::History (bool bookmarkSupport) : blistener(NULL), tpc (NULL), bmnum (1) { @@ -204,8 +203,8 @@ void History::bookmarkSelectionChanged () void History::procParamsChanged (ProcParams* params, ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited) { - // to prevent recursion, we filter out the events triggered by the history - if (ev == EvHistoryBrowsed) { + // to prevent recursion, we filter out the events triggered by the history and events that should not be registered + if (ev == EvHistoryBrowsed || ev == EvMonitorTransform) { return; } diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index 51ee408a2..55e8e1a6e 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -193,6 +193,18 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch onames->set_active (0); + // Rendering intent + + Gtk::Label* outputIntentLbl = Gtk::manage (new Gtk::Label(M("TP_ICM_OUTPUTPROFILEINTENT"))); + oVBox->pack_start (*outputIntentLbl, Gtk::PACK_SHRINK); + ointent = Gtk::manage (new MyComboBoxText ()); + oVBox->pack_start (*ointent, Gtk::PACK_EXPAND_WIDGET); + ointent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); + ointent->append_text (M("PREFERENCES_INTENT_RELATIVE")); + ointent->append_text (M("PREFERENCES_INTENT_SATURATION")); + ointent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); + ointent->set_active(0); + // Output gamma Gtk::HBox* gaHBox = Gtk::manage (new Gtk::HBox ()); @@ -282,6 +294,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch wnames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::wpChanged) ); onames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) ); + ointent->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) ); wgamma->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::gpChanged) ); dcpIll->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::dcpIlluminantChanged) ); @@ -507,6 +520,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) if (onames->get_active_row_number() == -1) { onames->set_active_text (M("TP_ICM_NOICM")); } + ointent->set_active(pp->icm.outputIntent); ckbToneCurve->set_active (pp->icm.toneCurve); lastToneCurve = pp->icm.toneCurve; @@ -545,6 +559,10 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) onames->set_active_text(M("GENERAL_UNCHANGED")); } + if (!pedited->icm.outputIntent) { + ointent->set_active_text(M("GENERAL_UNCHANGED")); + } + if (!pedited->icm.dcpIlluminant) { dcpIll->set_active_text(M("GENERAL_UNCHANGED")); } @@ -605,6 +623,13 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) pp->icm.output = onames->get_active_text(); } + int ointentVal = ointent->get_active_row_number(); + if (ointentVal >= 0 && ointentVal < RI__COUNT) { + pp->icm.outputIntent = static_cast(ointentVal); + } else { + pp->icm.outputIntent = rtengine::RI_PERCEPTUAL; + } + pp->icm.freegamma = freegamma->get_active(); DCPProfile* dcp = NULL; @@ -641,6 +666,7 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) pedited->icm.input = !iunchanged->get_active (); pedited->icm.working = wnames->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.output = onames->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->icm.outputIntent = ointent->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.dcpIlluminant = dcpIll->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.toneCurve = !ckbToneCurve->get_inconsistent (); pedited->icm.applyLookTable = !ckbApplyLookTable->get_inconsistent (); @@ -876,7 +902,7 @@ void ICMPanel::opChanged () { if (listener) { - listener->panelChanged (EvOProfile, onames->get_active_text()); + listener->panelChanged (EvOProfile, Glib::ustring(onames->get_active_text())+Glib::ustring("\n")+ointent->get_active_text()); } } @@ -979,6 +1005,7 @@ void ICMPanel::setBatchMode (bool batchMode) iVBox->reorder_child (*iunchanged, 5); removeIfThere (this, saveRef); onames->append_text (M("GENERAL_UNCHANGED")); + ointent->append_text (M("GENERAL_UNCHANGED")); wnames->append_text (M("GENERAL_UNCHANGED")); wgamma->append_text (M("GENERAL_UNCHANGED")); dcpIll->append_text (M("GENERAL_UNCHANGED")); diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index 93828f5fd..e10f42b20 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -78,6 +78,7 @@ private: MyComboBoxText* wgamma; MyComboBoxText* onames; + MyComboBoxText* ointent; Gtk::RadioButton* ofromdir; Gtk::RadioButton* ofromfile; Gtk::RadioButton* iunchanged; diff --git a/rtgui/options.cc b/rtgui/options.cc index ce85acc09..1ffc74e2b 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -470,6 +470,7 @@ void Options::setDefaults () fastexport_icm_input = "(camera)"; fastexport_icm_working = "ProPhoto"; fastexport_icm_output = "RT_sRGB"; + fastexport_icm_outputIntent = rtengine::RI_PERCEPTUAL; fastexport_icm_gamma = "default"; fastexport_resize_enabled = true; fastexport_resize_scale = 1; @@ -636,7 +637,7 @@ void Options::setDefaults () rtSettings.leveldnautsimpl = 0; rtSettings.monitorProfile = Glib::ustring(); - rtSettings.monitorIntent = 1; + rtSettings.monitorIntent = rtengine::RI_PERCEPTUAL; rtSettings.autoMonitorProfile = false; rtSettings.adobe = "RT_Medium_gsRGB"; // put the name of yours profiles (here windows) rtSettings.prophoto = "RT_Large_gBT709"; // these names appear in the menu "output profile" @@ -1461,7 +1462,7 @@ int Options::readFromFile (Glib::ustring fname) } if (keyFile.has_key ("Color Management", "Intent")) { - rtSettings.monitorIntent = keyFile.get_integer("Color Management", "Intent"); + rtSettings.monitorIntent = static_cast(keyFile.get_integer("Color Management", "Intent")); } if (keyFile.has_key ("Color Management", "CRI")) { @@ -1712,6 +1713,10 @@ int Options::readFromFile (Glib::ustring fname) fastexport_icm_output = keyFile.get_string ("Fast Export", "fastexport_icm_output" ); } + if (keyFile.has_key ("Fast Export", "fastexport_icm_output_intent" )) { + fastexport_icm_outputIntent = static_cast(keyFile.get_integer ("Fast Export", "fastexport_icm_output_intent" )); + } + if (keyFile.has_key ("Fast Export", "fastexport_icm_gamma" )) { fastexport_icm_gamma = keyFile.get_string ("Fast Export", "fastexport_icm_gamma" ); } @@ -2075,6 +2080,7 @@ int Options::saveToFile (Glib::ustring fname) keyFile.set_string ("Fast Export", "fastexport_icm_input" , fastexport_icm_input ); keyFile.set_string ("Fast Export", "fastexport_icm_working" , fastexport_icm_working ); keyFile.set_string ("Fast Export", "fastexport_icm_output" , fastexport_icm_output ); + keyFile.set_integer ("Fast Export", "fastexport_icm_output_intent" , fastexport_icm_outputIntent ); keyFile.set_string ("Fast Export", "fastexport_icm_gamma" , fastexport_icm_gamma ); keyFile.set_boolean ("Fast Export", "fastexport_resize_enabled" , fastexport_resize_enabled ); keyFile.set_double ("Fast Export", "fastexport_resize_scale" , fastexport_resize_scale ); diff --git a/rtgui/options.h b/rtgui/options.h index 614042fa2..969b66642 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -264,6 +264,7 @@ public: Glib::ustring fastexport_icm_input; Glib::ustring fastexport_icm_working; Glib::ustring fastexport_icm_output; + rtengine::eRenderingIntent fastexport_icm_outputIntent; Glib::ustring fastexport_icm_gamma; bool fastexport_resize_enabled; double fastexport_resize_scale; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index ac2fe6523..28d4c13b8 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -816,6 +816,7 @@ void ParamsEdited::initFrom (const std::vector icm.dcpIlluminant = icm.dcpIlluminant && p.icm.dcpIlluminant == other.icm.dcpIlluminant; icm.working = icm.working && p.icm.working == other.icm.working; icm.output = icm.output && p.icm.output == other.icm.output; + icm.outputIntent = icm.outputIntent && p.icm.outputIntent == other.icm.outputIntent; icm.gamma = icm.gamma && p.icm.gamma == other.icm.gamma; icm.freegamma = icm.freegamma && p.icm.freegamma == other.icm.freegamma; icm.gampos = icm.gampos && p.icm.gampos == other.icm.gampos; @@ -2119,6 +2120,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.icm.output = mods.icm.output; } + if (icm.outputIntent) { + toEdit.icm.outputIntent = mods.icm.outputIntent; + } + //if (icm.gampos) toEdit.icm.gampos = mods.icm.gampos; //if (icm.slpos) toEdit.icm.slpos = mods.icm.slpos; if (icm.gampos) { diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 3fa753013..1993c7aaa 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -530,6 +530,7 @@ public: bool dcpIlluminant; bool working; bool output; + bool outputIntent; bool gamma; bool gampos; bool slpos; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 4aa1d2427..56fb63c3e 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1434,7 +1434,7 @@ void Preferences::storePreferences () #if !defined(__APPLE__) // monitor profile not supported on apple moptions.rtSettings.monitorProfile = monProfile->get_active_text (); - moptions.rtSettings.monitorIntent = monIntent->get_active_row_number () > 0 ? INTENT_PERCEPTUAL : INTENT_RELATIVE_COLORIMETRIC; + moptions.rtSettings.monitorIntent = monIntent->get_active_row_number () > 0 ? rtengine::RI_PERCEPTUAL : rtengine::RI_RELATIVE; #if defined(WIN32) moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active (); #endif diff --git a/tools/source_icons/scalable/intent-absolute.file b/tools/source_icons/scalable/intent-absolute.file new file mode 100644 index 000000000..57278bff2 --- /dev/null +++ b/tools/source_icons/scalable/intent-absolute.file @@ -0,0 +1 @@ +intent-absolute.png,w25,actions diff --git a/tools/source_icons/scalable/intent-absolute.svg b/tools/source_icons/scalable/intent-absolute.svg new file mode 100644 index 000000000..497ce9c66 --- /dev/null +++ b/tools/source_icons/scalable/intent-absolute.svg @@ -0,0 +1,1378 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/intent-perceptual.file b/tools/source_icons/scalable/intent-perceptual.file new file mode 100644 index 000000000..3e7520042 --- /dev/null +++ b/tools/source_icons/scalable/intent-perceptual.file @@ -0,0 +1 @@ +intent-perceptual.png,w25,actions diff --git a/tools/source_icons/scalable/intent-perceptual.svg b/tools/source_icons/scalable/intent-perceptual.svg new file mode 100644 index 000000000..ab34b86b7 --- /dev/null +++ b/tools/source_icons/scalable/intent-perceptual.svg @@ -0,0 +1,1366 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/intent-relative.file b/tools/source_icons/scalable/intent-relative.file new file mode 100644 index 000000000..5191a25c3 --- /dev/null +++ b/tools/source_icons/scalable/intent-relative.file @@ -0,0 +1 @@ +intent-relative.png,w25,actions diff --git a/tools/source_icons/scalable/intent-relative.svg b/tools/source_icons/scalable/intent-relative.svg new file mode 100644 index 000000000..31a2fb342 --- /dev/null +++ b/tools/source_icons/scalable/intent-relative.svg @@ -0,0 +1,1374 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/intent-saturation.file b/tools/source_icons/scalable/intent-saturation.file new file mode 100644 index 000000000..9f33b978e --- /dev/null +++ b/tools/source_icons/scalable/intent-saturation.file @@ -0,0 +1 @@ +intent-saturation.png,w25,actions diff --git a/tools/source_icons/scalable/intent-saturation.svg b/tools/source_icons/scalable/intent-saturation.svg new file mode 100644 index 000000000..638df39f2 --- /dev/null +++ b/tools/source_icons/scalable/intent-saturation.svg @@ -0,0 +1,1366 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/softProof.file b/tools/source_icons/scalable/softProof.file new file mode 100644 index 000000000..e275113ec --- /dev/null +++ b/tools/source_icons/scalable/softProof.file @@ -0,0 +1 @@ +softProof.png,w22,actions diff --git a/tools/source_icons/scalable/softProof.svg b/tools/source_icons/scalable/softProof.svg new file mode 100644 index 000000000..7d142fc4c --- /dev/null +++ b/tools/source_icons/scalable/softProof.svg @@ -0,0 +1,1389 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + From 4e0e3230ccde4e4290c78859cccf19c088525f6a Mon Sep 17 00:00:00 2001 From: heckflosse Date: Wed, 16 Dec 2015 16:56:26 +0100 Subject: [PATCH 24/61] Segfault in Denoise Auto Multizone mode when smoothing set to max in preferences, fixes #3022 --- rtengine/simpleprocess.cc | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 91b7df178..665a3a236 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -191,8 +191,6 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p float *ry = new float [nbtl]; float *sk = new float [nbtl]; float *pcsk = new float [nbtl]; - float *Max_R_ = new float [nbtl]; - float *Max_B_ = new float [nbtl]; // printf("expert=%d\n",settings->leveldnautsimpl); if(settings->leveldnautsimpl == 1 && params.dirpyrDenoise.Cmethod == "PON") { @@ -371,11 +369,11 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p MaxRMoy += max_r[k]; if(max_r[k] > MaxR) { - MaxR = Max_R_[k]; + MaxR = max_r[k]; } if(max_b[k] > MaxB) { - MaxB = Max_B_[k]; + MaxB = max_b[k]; } } @@ -713,8 +711,6 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p delete [] ry; delete [] sk; delete [] pcsk; - delete [] Max_R_; - delete [] Max_B_; imgsrc->convertColorSpace(baseImg, params.icm, currWB); From d3ac22531bc4899f0ae8b4f3c45cdb1daca3d09c Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sun, 8 Nov 2015 11:32:14 +0100 Subject: [PATCH 25/61] Extend the file browser so that it will only show the original image if several files of different formats are present. --- rtgui/filebrowser.cc | 99 ++++++++++++++++++++++++++++++++++ rtgui/thumbbrowserentrybase.cc | 13 ++++- rtgui/thumbbrowserentrybase.h | 26 +++++---- 3 files changed, 127 insertions(+), 11 deletions(-) diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 294c074bb..5e1dd734e 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -19,6 +19,7 @@ * along with RawTherapee. If not, see . */ #include "filebrowser.h" +#include #include #include "options.h" #include "multilangmgr.h" @@ -32,6 +33,96 @@ extern Options options; +namespace +{ + +const Glib::ustring* getOriginalExtension (const ThumbBrowserEntryBase* entry) +{ + // We use the parsed extensions as a priority list, + // i.e. what comes earlier in the list is considered an original of what comes later. + typedef std::vector ExtensionVector; + typedef ExtensionVector::const_iterator ExtensionIterator; + + const ExtensionVector& originalExtensions = options.parsedExtensions; + + // Extract extension from basename + const Glib::ustring basename = Glib::path_get_basename (entry->filename.lowercase()); + + const Glib::ustring::size_type pos = basename.find_last_of ('.'); + if (pos >= basename.length () - 1) { + return NULL; + } + + const Glib::ustring extension = basename.substr (pos + 1); + + // Try to find a matching original extension + for (ExtensionIterator originalExtension = originalExtensions.begin(); originalExtension != originalExtensions.end(); ++originalExtension) { + if (*originalExtension == extension) { + return &*originalExtension; + } + } + + return NULL; +} + +ThumbBrowserEntryBase* selectOriginalEntry (ThumbBrowserEntryBase* original, ThumbBrowserEntryBase* candidate) +{ + // The candidate will become the new original, if it has an original extension + // and if its extension is higher in the list than the old original. + if (const Glib::ustring* candidateExtension = getOriginalExtension (candidate)) { + if (original == NULL) { + return candidate; + } else if (const Glib::ustring* originalExtension = getOriginalExtension (original)) { + return candidateExtension < originalExtension ? candidate : original; + } + } else { + return original; + } +} + +void findOriginalEntries (const std::vector& entries) +{ + typedef std::vector EntryVector; + typedef EntryVector::const_iterator EntryIterator; + typedef std::map BasenameMap; + typedef BasenameMap::const_iterator BasenameIterator; + + // Sort all entries into buckets by basename without extension + BasenameMap byBasename; + + for (EntryIterator entry = entries.begin (); entry != entries.end (); ++entry) { + const Glib::ustring basename = Glib::path_get_basename ((*entry)->filename.lowercase()); + + const Glib::ustring::size_type pos = basename.find_last_of ('.'); + if (pos >= basename.length () - 1) { + (*entry)->setOriginal (NULL); + continue; + } + + const Glib::ustring withoutExtension = basename.substr (0, pos); + + byBasename[withoutExtension].push_back (*entry); + } + + // Find the original image for each bucket + for (BasenameIterator bucket = byBasename.begin (); bucket != byBasename.end (); ++bucket) { + const EntryVector& entries = bucket->second; + ThumbBrowserEntryBase* original = NULL; + + // Select the most likely original in a first pass... + for (EntryIterator entry = entries.begin (); entry != entries.end (); ++entry) { + original = selectOriginalEntry (original, *entry); + } + + // ...and link all other images to it in a second pass. + for (EntryIterator entry = entries.begin (); entry != entries.end (); ++entry) { + (*entry)->setOriginal (*entry != original ? original : NULL); + } + } +} + +} + FileBrowser::FileBrowser () : tbl(NULL), numFiltered(0), partialPasteDlg(M("PARTIALPASTE_DIALOGLABEL")) { @@ -1370,6 +1461,10 @@ void FileBrowser::applyFilter (const BrowserFilter& filter) MYWRITERLOCK(l, entryRW); // Don't make this a writer lock! HOMBRE: Why? 'selected' is modified here #endif + if (true/* TODO: filterOriginal */) { + findOriginalEntries(fd); + } + for (size_t i = 0; i < fd.size(); i++) { if (checkFilter (fd[i])) { numFiltered++; @@ -1400,6 +1495,10 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry FileBrowserEntry* entry = static_cast(entryb); + if (true/* TODO: filterOriginal */ && entry->getOriginal() != NULL) { + return false; + } + // return false if basic filter settings are not satisfied if ((filter.showRanked[entry->thumbnail->getRank()] == false ) || (filter.showCLabeled[entry->thumbnail->getColorLabel()] == false ) || diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc index f9f8f9f1e..d1d7adc51 100644 --- a/rtgui/thumbbrowserentrybase.cc +++ b/rtgui/thumbbrowserentrybase.cc @@ -26,7 +26,7 @@ ThumbBrowserEntryBase::ThumbBrowserEntryBase (const Glib::ustring& fname) prex(0), prey(0), upperMargin(6), borderWidth(1), textGap(6), sideMargin(8), lowerMargin(8), preview(NULL), dispname(Glib::path_get_basename (fname)), buttonSet(NULL), width(0), height(0), exp_width(0), exp_height(0), startx(0), starty(0), ofsX(0), ofsY(0), redrawRequests(0), - parent(NULL), bbSelected(false), bbFramed(false), bbPreview(NULL), + parent(NULL), original(NULL), bbSelected(false), bbFramed(false), bbPreview(NULL), thumbnail(NULL), filename(fname), shortname(dispname), exifline(""), datetimeline(""), selected(false), drawable(false), filtered(false), framed(false), processing(false), italicstyle(false), edited(false), recentlysaved(false), updatepriority(false), withFilename(WFNAME_NONE) {} @@ -544,6 +544,17 @@ bool ThumbBrowserEntryBase::insideWindow (int x, int y, int w, int h) return !(ofsX + startx > x + w || ofsX + startx + exp_width < x || ofsY + starty > y + h || ofsY + starty + exp_height < y); } +std::vector > ThumbBrowserEntryBase::getIconsOnImageArea() +{ + return std::vector >(); +} + +void ThumbBrowserEntryBase::getIconSize(int& w, int& h) +{ + w = 0; + h = 0; +} + bool ThumbBrowserEntryBase::motionNotify (int x, int y) { diff --git a/rtgui/thumbbrowserentrybase.h b/rtgui/thumbbrowserentrybase.h index e910aedd0..1b7f0691a 100644 --- a/rtgui/thumbbrowserentrybase.h +++ b/rtgui/thumbbrowserentrybase.h @@ -72,6 +72,7 @@ protected: int redrawRequests; ThumbBrowserBase* parent; + ThumbBrowserEntryBase* original; Glib::RefPtr backBuffer; bool bbSelected, bbFramed; @@ -168,22 +169,17 @@ public: return shortname.casefold() > other.shortname.casefold(); } + ThumbBrowserEntryBase* getOriginal () const; + void setOriginal (ThumbBrowserEntryBase* original); + virtual void refreshThumbnailImage () {} virtual void refreshQuickThumbnailImage () {} virtual void calcThumbnailSize () {} virtual void drawProgressBar (Glib::RefPtr win, Glib::RefPtr gc, const Gdk::Color& foregr, const Gdk::Color& backgr, int x, int w, int y, int h) {} - virtual std::vector > getIconsOnImageArea () - { - std::vector > r; - return r; - } - virtual void getIconSize (int& w, int& h) - { - w = 0; - h = 0; - } + virtual std::vector > getIconsOnImageArea (); + virtual void getIconSize (int& w, int& h); virtual bool motionNotify (int x, int y); virtual bool pressNotify (int button, int type, int bstate, int x, int y); @@ -191,4 +187,14 @@ public: virtual Glib::ustring getToolTip (int x, int y); }; +inline ThumbBrowserEntryBase* ThumbBrowserEntryBase::getOriginal() const +{ + return original; +} + +inline void ThumbBrowserEntryBase::setOriginal(ThumbBrowserEntryBase* original) +{ + this->original = original; +} + #endif From ee766b71b83dd9377300da829a821d488bfe39e7 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sun, 8 Nov 2015 12:24:48 +0100 Subject: [PATCH 26/61] Add a button to filter the original files to the file browser. --- rtdata/languages/default | 1 + rtgui/browserfilter.cc | 8 ++++---- rtgui/browserfilter.h | 1 + rtgui/filebrowser.cc | 4 ++-- rtgui/filecatalog.cc | 43 ++++++++++++++++++++++++++++------------ rtgui/filecatalog.h | 5 +++-- 6 files changed, 41 insertions(+), 21 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 84586340e..dbcb29a6a 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -171,6 +171,7 @@ FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +FILEBROWSER_SHOWORIGINALHINT;Show only the original images. FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1-star.\nShortcut: 1 FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2-star.\nShortcut: 2 FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3-star.\nShortcut: 3 diff --git a/rtgui/browserfilter.cc b/rtgui/browserfilter.cc index f7d1038ed..6fa663aa3 100644 --- a/rtgui/browserfilter.cc +++ b/rtgui/browserfilter.cc @@ -18,11 +18,11 @@ */ #include "browserfilter.h" -BrowserFilter::BrowserFilter () : exifFilterEnabled (false) +BrowserFilter::BrowserFilter () : exifFilterEnabled (false), + showTrash (true), + showNotTrash (true), + showOriginal (false) { - - showTrash = true; - for (int i = 0; i < 6; i++) { showRanked[i] = true; showCLabeled[i] = true; diff --git a/rtgui/browserfilter.h b/rtgui/browserfilter.h index 6cfa3be62..8880a364d 100644 --- a/rtgui/browserfilter.h +++ b/rtgui/browserfilter.h @@ -30,6 +30,7 @@ public: bool showCLabeled[6]; bool showTrash; bool showNotTrash; + bool showOriginal; bool showEdited[2]; bool showRecentlySaved[2]; bool multiselect; diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 5e1dd734e..7d921b328 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -1461,7 +1461,7 @@ void FileBrowser::applyFilter (const BrowserFilter& filter) MYWRITERLOCK(l, entryRW); // Don't make this a writer lock! HOMBRE: Why? 'selected' is modified here #endif - if (true/* TODO: filterOriginal */) { + if (filter.showOriginal) { findOriginalEntries(fd); } @@ -1495,7 +1495,7 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry FileBrowserEntry* entry = static_cast(entryb); - if (true/* TODO: filterOriginal */ && entry->getOriginal() != NULL) { + if (filter.showOriginal && entry->getOriginal() != NULL) { return false; } diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index d40b7d720..92ce120c2 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -294,8 +294,16 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : bCateg[18] = bNotTrash->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bNotTrash, true)); bNotTrash->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event), false); + bOriginal = Gtk::manage( new Gtk::ToggleButton () ); + bOriginal->set_label ("O"); // TODO: Add icon... + bOriginal->set_tooltip_markup (M("FILEBROWSER_SHOWORIGINALHINT")); + bOriginal->set_relief (Gtk::RELIEF_NONE); + bCateg[19] = bOriginal->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bOriginal, true)); + bOriginal->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event), false); + buttonBar->pack_start (*bTrash, Gtk::PACK_SHRINK); buttonBar->pack_start (*bNotTrash, Gtk::PACK_SHRINK); + buttonBar->pack_start (*bOriginal, Gtk::PACK_SHRINK); buttonBar->pack_start (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK); fileBrowser->trash_changed().connect( sigc::mem_fun(*this, &FileCatalog::trashChanged) ); @@ -318,6 +326,7 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : // 16 - bRecentlySaved[1] // 17 - bTrash // 18 - bNotTrash + // 19 - bOriginal categoryButtons[0] = bFilterClear; categoryButtons[1] = bUnRanked; @@ -342,6 +351,7 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : categoryButtons[17] = bTrash; categoryButtons[18] = bNotTrash; + categoryButtons[19] = bOriginal; exifInfo = Gtk::manage(new Gtk::ToggleButton ()); exifInfo->set_image (*Gtk::manage(new RTImage ("info.png"))); @@ -1351,8 +1361,8 @@ void FileCatalog::categoryButtonToggled (Gtk::ToggleButton* b, bool isMouseClick // if no modifier key is pressed, if (!(control_down || shift_down)) { - // if we're deselecting non-trashed - if (toggled_button == 18 && (buttons & (1 << toggled_button))) { + // if we're deselecting non-trashed or original + if (toggled_button >= 18 && toggled_button <= 19 && (buttons & (1 << toggled_button))) { categoryButtons[0]->set_active (true); for (int i = 1; i < numButtons; i++) { @@ -1445,9 +1455,15 @@ void FileCatalog::categoryButtonToggled (Gtk::ToggleButton* b, bool isMouseClick //if more than one star & color label is selected, do nothing } } - // ...or non-trashed with Control modifier - else if (toggled_button == 18 && control_down) { - bNotTrash->set_active (!bNotTrash->get_active ()); + // ...or non-trashed or original with Control modifier + else if (toggled_button >= 18 && toggled_button <= 19 && control_down) { + Gtk::ToggleButton* categoryButton = categoryButtons[toggled_button]; + categoryButton->set_active (!categoryButton->get_active ()); + + // If it was the first or last one, we reset the clear filter. + if (buttons == 1 || buttons == (1 << toggled_button)) { + bFilterClear->set_active (!categoryButton->get_active ()); + } } bool active_now, active_before; @@ -1554,30 +1570,30 @@ BrowserFilter FileCatalog::getFilter () bool anyCLabelFilterActive = bUnCLabeled->get_active () || bCLabel[0]->get_active () || bCLabel[1]->get_active () || bCLabel[2]->get_active () || bCLabel[3]->get_active () || bCLabel[4]->get_active (); bool anyEditedFilterActive = bEdited[0]->get_active() || bEdited[1]->get_active(); bool anyRecentlySavedFilterActive = bRecentlySaved[0]->get_active() || bRecentlySaved[1]->get_active(); - const bool nonTrashedActive = bNotTrash->get_active(); + const bool anySupplementaryActive = bNotTrash->get_active() || bOriginal->get_active(); /* * filter is setup in 2 steps * Step 1: handle individual filters */ - filter.showRanked[0] = bFilterClear->get_active() || bUnRanked->get_active () || bTrash->get_active () || nonTrashedActive || + filter.showRanked[0] = bFilterClear->get_active() || bUnRanked->get_active () || bTrash->get_active () || anySupplementaryActive || anyCLabelFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive; - filter.showCLabeled[0] = bFilterClear->get_active() || bUnCLabeled->get_active () || bTrash->get_active () || nonTrashedActive || + filter.showCLabeled[0] = bFilterClear->get_active() || bUnCLabeled->get_active () || bTrash->get_active () || anySupplementaryActive || anyRankFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive; for (int i = 1; i <= 5; i++) { - filter.showRanked[i] = bFilterClear->get_active() || bRank[i - 1]->get_active () || bTrash->get_active () || nonTrashedActive || + filter.showRanked[i] = bFilterClear->get_active() || bRank[i - 1]->get_active () || bTrash->get_active () || anySupplementaryActive || anyCLabelFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive; - filter.showCLabeled[i] = bFilterClear->get_active() || bCLabel[i - 1]->get_active () || bTrash->get_active () || nonTrashedActive || + filter.showCLabeled[i] = bFilterClear->get_active() || bCLabel[i - 1]->get_active () || bTrash->get_active () || anySupplementaryActive || anyRankFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive; } for (int i = 0; i < 2; i++) { - filter.showEdited[i] = bFilterClear->get_active() || bEdited[i]->get_active () || bTrash->get_active () || nonTrashedActive || + filter.showEdited[i] = bFilterClear->get_active() || bEdited[i]->get_active () || bTrash->get_active () || anySupplementaryActive || anyRankFilterActive || anyCLabelFilterActive || anyRecentlySavedFilterActive; - filter.showRecentlySaved[i] = bFilterClear->get_active() || bRecentlySaved[i]->get_active () || bTrash->get_active () || nonTrashedActive || + filter.showRecentlySaved[i] = bFilterClear->get_active() || bRecentlySaved[i]->get_active () || bTrash->get_active () || anySupplementaryActive || anyRankFilterActive || anyCLabelFilterActive || anyEditedFilterActive; } @@ -1615,7 +1631,7 @@ BrowserFilter FileCatalog::getFilter () (anyCLabelFilterActive && anyEditedFilterActive ) || (anyCLabelFilterActive && anyRecentlySavedFilterActive ) || (anyEditedFilterActive && anyRecentlySavedFilterActive) || - (nonTrashedActive && (anyRankFilterActive || anyCLabelFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive))) { + (anySupplementaryActive && (anyRankFilterActive || anyCLabelFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive))) { filter.multiselect = true; filter.showRanked[0] = anyRankFilterActive ? bUnRanked->get_active () : true; @@ -1657,6 +1673,7 @@ BrowserFilter FileCatalog::getFilter () filter.showTrash = bTrash->get_active () || !bNotTrash->get_active (); filter.showNotTrash = !bTrash->get_active (); + filter.showOriginal = bOriginal->get_active(); if (!filterPanel) { filter.exifFilterEnabled = false; diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h index 377a6b0da..eda0ff81a 100644 --- a/rtgui/filecatalog.h +++ b/rtgui/filecatalog.h @@ -108,9 +108,10 @@ private: Gtk::ToggleButton* bRecentlySaved[2]; Gtk::ToggleButton* bTrash; Gtk::ToggleButton* bNotTrash; - Gtk::ToggleButton* categoryButtons[19]; + Gtk::ToggleButton* bOriginal; + Gtk::ToggleButton* categoryButtons[20]; Gtk::ToggleButton* exifInfo; - sigc::connection bCateg[19]; + sigc::connection bCateg[20]; Gtk::Image* iFilterClear, *igFilterClear; Gtk::Image* iranked[5], *igranked[5], *iUnRanked, *igUnRanked; Gtk::Image* iCLabeled[5], *igCLabeled[5], *iUnCLabeled, *igUnCLabeled; From b89cd282e012ec0d82bd80e145b8db2fa32a74a3 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Fri, 13 Nov 2015 20:08:25 +0100 Subject: [PATCH 27/61] Add buttons to the file browser preferences to make the list of extensions user-sortable. --- rtdata/languages/default | 2 ++ rtgui/preferences.cc | 40 ++++++++++++++++++++++++++++++++++++++++ rtgui/preferences.h | 4 ++++ 3 files changed, 46 insertions(+) diff --git a/rtdata/languages/default b/rtdata/languages/default index dbcb29a6a..9b23d2e3b 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1001,6 +1001,8 @@ PREFERENCES_PARSEDEXT;Parsed Extensions PREFERENCES_PARSEDEXTADD;Add extension PREFERENCES_PARSEDEXTADDHINT;Add entered extension to the list. PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list. +PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. +PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. PREFERENCES_PREVDEMO;Preview Demosaic Method PREFERENCES_PREVDEMO_FAST;Fast PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index f6feef35f..739f833b1 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1188,12 +1188,20 @@ Gtk::Widget* Preferences::getFileBrowserPanel () hb0->pack_start (*extension); addExt = Gtk::manage( new Gtk::Button () ); delExt = Gtk::manage( new Gtk::Button () ); + moveExtUp = Gtk::manage( new Gtk::Button () ); + moveExtDown = Gtk::manage( new Gtk::Button () ); addExt->set_tooltip_text (M("PREFERENCES_PARSEDEXTADDHINT")); delExt->set_tooltip_text (M("PREFERENCES_PARSEDEXTDELHINT")); + moveExtUp->set_tooltip_text (M("PREFERENCES_PARSEDEXTUPHINT")); + moveExtDown->set_tooltip_text (M("PREFERENCES_PARSEDEXTDOWNHINT")); Gtk::Image* addExtImg = Gtk::manage( new RTImage ("list-add-small.png") ); Gtk::Image* delExtImg = Gtk::manage( new RTImage ("list-remove-red-small.png") ); addExt->add (*addExtImg); delExt->add (*delExtImg); + moveExtUp->set_label ("↑"); // TODO: Add arrow up image... + moveExtDown->set_label ("↓"); // TODO: Add arrow down image... + hb0->pack_end (*moveExtDown, Gtk::PACK_SHRINK, 4); + hb0->pack_end (*moveExtUp, Gtk::PACK_SHRINK, 4); hb0->pack_end (*delExt, Gtk::PACK_SHRINK, 4); hb0->pack_end (*addExt, Gtk::PACK_SHRINK, 4); extensions = Gtk::manage( new Gtk::TreeView () ); @@ -1264,6 +1272,8 @@ Gtk::Widget* Preferences::getFileBrowserPanel () addExt->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::addExtPressed) ); delExt->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::delExtPressed) ); + moveExtUp->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::moveExtUpPressed) ); + moveExtDown->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::moveExtDownPressed) ); extension->signal_activate().connect( sigc::mem_fun(*this, &Preferences::addExtPressed) ); clearThumbnails->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::clearThumbImagesPressed) ); clearProfiles->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::clearProfilesPressed) ); @@ -2082,6 +2092,36 @@ void Preferences::delExtPressed () extensionModel->erase (extensions->get_selection()->get_selected ()); } +void Preferences::moveExtUpPressed () +{ + const Glib::RefPtr selection = extensions->get_selection (); + if (!selection) + return; + + const Gtk::TreeModel::iterator selected = selection->get_selected (); + if (!selected || selected == extensionModel->children ().begin ()) + return; + + Gtk::TreeModel::iterator previous = selected; + --previous; + extensionModel->iter_swap (selected, previous); +} + +void Preferences::moveExtDownPressed () +{ + const Glib::RefPtr selection = extensions->get_selection (); + if (!selection) + return; + + const Gtk::TreeModel::iterator selected = selection->get_selected (); + if (!selected) + return; + + Gtk::TreeModel::iterator next = selected; + if (++next) + extensionModel->iter_swap (selected, next); +} + void Preferences::clearProfilesPressed () { diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 76abd0a19..ee885c568 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -144,6 +144,8 @@ protected: Gtk::TreeView* extensions; Gtk::Button* addExt; Gtk::Button* delExt; + Gtk::Button* moveExtUp; + Gtk::Button* moveExtDown; Gtk::CheckButton* overlayedFileNames; Gtk::CheckButton* filmStripOverlayedFileNames; Gtk::CheckButton* sameThumbSize; @@ -242,6 +244,8 @@ public: void selectStartupDir (); void addExtPressed (); void delExtPressed (); + void moveExtUpPressed (); + void moveExtDownPressed (); void darkFrameChanged (); void flatFieldChanged (); void clearProfilesPressed (); From 97814fbf6ed628566ff047e090a712c6f1be06fa Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Thu, 17 Dec 2015 19:45:13 +0100 Subject: [PATCH 28/61] Import icons provided by Beep6581 into source tree. --- .../images/Dark/actions/arrow-down-small.png | Bin 0 -> 353 bytes rtdata/images/Dark/actions/arrow-down.png | Bin 0 -> 475 bytes .../images/Dark/actions/arrow-left-small.png | Bin 0 -> 357 bytes rtdata/images/Dark/actions/arrow-left.png | Bin 0 -> 449 bytes .../images/Dark/actions/arrow-right-small.png | Bin 0 -> 359 bytes rtdata/images/Dark/actions/arrow-right.png | Bin 0 -> 443 bytes rtdata/images/Dark/actions/arrow-up-small.png | Bin 0 -> 315 bytes rtdata/images/Dark/actions/arrow-up.png | Bin 0 -> 472 bytes .../images/Dark/actions/filter-original-1.png | Bin 0 -> 519 bytes .../images/Dark/actions/filter-original-2.png | Bin 0 -> 701 bytes .../images/Light/actions/arrow-down-small.png | Bin 0 -> 381 bytes rtdata/images/Light/actions/arrow-down.png | Bin 0 -> 490 bytes .../images/Light/actions/arrow-left-small.png | Bin 0 -> 360 bytes rtdata/images/Light/actions/arrow-left.png | Bin 0 -> 447 bytes .../Light/actions/arrow-right-small.png | Bin 0 -> 365 bytes rtdata/images/Light/actions/arrow-right.png | Bin 0 -> 445 bytes .../images/Light/actions/arrow-up-small.png | Bin 0 -> 338 bytes rtdata/images/Light/actions/arrow-up.png | Bin 0 -> 468 bytes .../Light/actions/filter-original-1.png | Bin 0 -> 504 bytes .../Light/actions/filter-original-2.png | Bin 0 -> 727 bytes .../scalable/arrow-down-small.file | 1 + .../scalable/arrow-down-small.svg | 134 +++ tools/source_icons/scalable/arrow-down.file | 1 + tools/source_icons/scalable/arrow-down.svg | 134 +++ .../scalable/arrow-left-small.file | 1 + .../scalable/arrow-left-small.svg | 134 +++ tools/source_icons/scalable/arrow-left.file | 1 + tools/source_icons/scalable/arrow-left.svg | 134 +++ .../scalable/arrow-right-small.file | 1 + .../scalable/arrow-right-small.svg | 134 +++ tools/source_icons/scalable/arrow-right.file | 1 + tools/source_icons/scalable/arrow-right.svg | 134 +++ .../source_icons/scalable/arrow-up-small.file | 1 + .../source_icons/scalable/arrow-up-small.svg | 134 +++ tools/source_icons/scalable/arrow-up.file | 1 + tools/source_icons/scalable/arrow-up.svg | 134 +++ .../scalable/filter-original-1.file | 1 + .../scalable/filter-original-1.svg | 738 +++++++++++++++++ .../scalable/filter-original-2.file | 1 + .../scalable/filter-original-2.svg | 768 ++++++++++++++++++ 40 files changed, 2588 insertions(+) create mode 100644 rtdata/images/Dark/actions/arrow-down-small.png create mode 100644 rtdata/images/Dark/actions/arrow-down.png create mode 100644 rtdata/images/Dark/actions/arrow-left-small.png create mode 100644 rtdata/images/Dark/actions/arrow-left.png create mode 100644 rtdata/images/Dark/actions/arrow-right-small.png create mode 100644 rtdata/images/Dark/actions/arrow-right.png create mode 100644 rtdata/images/Dark/actions/arrow-up-small.png create mode 100644 rtdata/images/Dark/actions/arrow-up.png create mode 100644 rtdata/images/Dark/actions/filter-original-1.png create mode 100644 rtdata/images/Dark/actions/filter-original-2.png create mode 100644 rtdata/images/Light/actions/arrow-down-small.png create mode 100644 rtdata/images/Light/actions/arrow-down.png create mode 100644 rtdata/images/Light/actions/arrow-left-small.png create mode 100644 rtdata/images/Light/actions/arrow-left.png create mode 100644 rtdata/images/Light/actions/arrow-right-small.png create mode 100644 rtdata/images/Light/actions/arrow-right.png create mode 100644 rtdata/images/Light/actions/arrow-up-small.png create mode 100644 rtdata/images/Light/actions/arrow-up.png create mode 100644 rtdata/images/Light/actions/filter-original-1.png create mode 100644 rtdata/images/Light/actions/filter-original-2.png create mode 100644 tools/source_icons/scalable/arrow-down-small.file create mode 100644 tools/source_icons/scalable/arrow-down-small.svg create mode 100644 tools/source_icons/scalable/arrow-down.file create mode 100644 tools/source_icons/scalable/arrow-down.svg create mode 100644 tools/source_icons/scalable/arrow-left-small.file create mode 100644 tools/source_icons/scalable/arrow-left-small.svg create mode 100644 tools/source_icons/scalable/arrow-left.file create mode 100644 tools/source_icons/scalable/arrow-left.svg create mode 100644 tools/source_icons/scalable/arrow-right-small.file create mode 100644 tools/source_icons/scalable/arrow-right-small.svg create mode 100644 tools/source_icons/scalable/arrow-right.file create mode 100644 tools/source_icons/scalable/arrow-right.svg create mode 100644 tools/source_icons/scalable/arrow-up-small.file create mode 100644 tools/source_icons/scalable/arrow-up-small.svg create mode 100644 tools/source_icons/scalable/arrow-up.file create mode 100644 tools/source_icons/scalable/arrow-up.svg create mode 100644 tools/source_icons/scalable/filter-original-1.file create mode 100644 tools/source_icons/scalable/filter-original-1.svg create mode 100644 tools/source_icons/scalable/filter-original-2.file create mode 100644 tools/source_icons/scalable/filter-original-2.svg diff --git a/rtdata/images/Dark/actions/arrow-down-small.png b/rtdata/images/Dark/actions/arrow-down-small.png new file mode 100644 index 0000000000000000000000000000000000000000..d631a72f51f3e142be4a1baabcbaaf845eae78ef GIT binary patch literal 353 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2>S zOAux}KILpRkRe&(8c`CQpH@mmtT}V`<;yxP|-b47sn8b z-mQ}yxegf!xT>2vWxVX&^>UF&Of^G)V*Ud^mcS2e>$shkw9a$C(=kQFXl9{ylv}`` z(`O!kZ09^+pS;%h)vi8OH}AtHzWfXi7!y8DJs@Em>ZRG)xkOQr(YRheAuTD5b7Hu{ zA_j&e=D-7IM4W!?Y~1lI+BQ3P(bjo_6T2Q)teZ0HOKpA6q7K22A=6UzfnMLWZgr30 z(a*Ds-_3dc^VL+@wad5OvwE)AAt7MMbGX3u$X^L-trMHxoI8{K-nQ!f#11ppz&pnx r41F($bP0l+XkKD@2G3 literal 0 HcmV?d00001 diff --git a/rtdata/images/Dark/actions/arrow-down.png b/rtdata/images/Dark/actions/arrow-down.png new file mode 100644 index 0000000000000000000000000000000000000000..417038d15097eb6b2746a3bf4bef67034fae02a7 GIT binary patch literal 475 zcmV<10VMv3P)=GXMYp8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10a!^yK~y-6)sw$U13?hRzun7b3tLk}tb7BTJU}=S2&D97?6uWe z6kp>G^9CZs7f2=IpW>>Mz3k46O(GU18RQE6U}1{+e$0Hs0{=}$(^Qt_p0)NE0Ah^y zlgXsn<>_d^DW&~huXhFjRaKn;cxwgR?RLdE*D*%5AOOH>!RtE9G8J6~4k3KiTCge# zA`%f10H$f0_Q2kI5fK&7H_03;%c%zU2b`Qj)4#^dFAz96DU=iH(9{$O=92{lUD|kAcex#HxVvI{#X}MfRW6b4vJg$EY z27u9MG>2>S zOAux}KILpRkRe&(8c`CQpH@mmtT}V`<;yxP|+h#7sn8b z-nSDrdL3~PXiG1fK2tzCut}k8-=W0$C7E9oMZ7;szIhk>=28xax5b59;X95Qg>vu| z9**$fduYS4?N_PspU)qS8UD+-gcf?9`?DqIcA2Qtj(DYl`|Z2d_0RY@ZRUE{C#jtY z;g_rHU0wKHN}kQxtn?{wZLRS!1tlq$BbN5Qm#=*PTO2tpnw=paG}Oz*yraU3d$Nip zdjog&+KusNgd~oCbapXg*l^c0AT(#zvXp1mX?AjL54XPF^>yK^$Z4MQo)^BqeDC*U w6JPn{o{bt^%T?=dIENax6#QKM*#3n2uLO_vmp?yT3G^+4r>mdKI;Vst0Lg8S;Q#;t literal 0 HcmV?d00001 diff --git a/rtdata/images/Dark/actions/arrow-left.png b/rtdata/images/Dark/actions/arrow-left.png new file mode 100644 index 0000000000000000000000000000000000000000..a30aeadef2ea3e6c4e3dbf3058d1aa27f44cbc95 GIT binary patch literal 449 zcmV;y0Y3hTP)=GXMYp8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10X|7YK~y-6?UFr913?gmcix%Z3l?bvMFcB*5wSWeA>`~VZES5s z^e3e8Pv}1g*yl)&i(oC-TiMtNA&`T;+glrB)cAFxm3gXRmwEP`Wt5sRqcYxmYPZ{_ zY9Btk?Dcw!Ns^q_>-Cji5qs~c-|z1PL2z!2*{CX2N-24J(CKuR(lk9W#;l8oSZnj2 zh-qB3S}lZOxC>xkYdt3-0KjEgI_KOS5rK#_5fK1VN&%P*T$ZID3p7WQ^I=S~CE)*5=mQ3+LR! zM`MeK^WJAgQQSvSbTcI$)9rS*wARP9T5aB1n~z4L!zhYwzy8???`}n-(YRvfgDlG~ ropWUs;kSw7csogw2>S zOAux}KILpRkRe&(8c`CQpH@mmtT}V`<;yxP|*`l7sn8b z-nSDK{f-6*xW515o5|bOCM3hDec&&zN#-n*h;Ik@_BlQ9yzpkxqE+u_uFBtcu#7pu z^Jw;co-Vc{?QGoYlBLG!MaBp0R|kYzO>xa;xppi1`JHFinbPdMCq20rwfpVwe?N-d z7%psk>pCsf+$DvmdKI;Vst0Men8 A!vFvP literal 0 HcmV?d00001 diff --git a/rtdata/images/Dark/actions/arrow-right.png b/rtdata/images/Dark/actions/arrow-right.png new file mode 100644 index 0000000000000000000000000000000000000000..2f426f9f1078fb029e8ad01bb4713dce3157ffa0 GIT binary patch literal 443 zcmV;s0Yv_ZP)=GXMYp8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10XRuSK~y-6?U1ob!%!54|J-{M8!2~iQBa)Rbx*;ep?!jao0IR6 z*={1};O5rJsnn2)OC|-MK%}b(jwQLd=QwCf)M{;Yv)^)u`=9R|eqh0ZU(@MyJZ5&L z<;1LFt@UP-B!~TefBjFz0O0%nj_bOoaU8dzD4OV)OAG*>=Pmobe^9H{+TCt<R)r8Kih_v9=6OD3=JPa7FQOYXp*Xx&#<8V2rz7l*#@yd;q@+b_$r%9Qa#jfiP lvn*>jo6W0vj#}`ac>y!(mQWT@9J>Gj002ovPDHLkV1f`6!A<}G literal 0 HcmV?d00001 diff --git a/rtdata/images/Dark/actions/arrow-up-small.png b/rtdata/images/Dark/actions/arrow-up-small.png new file mode 100644 index 0000000000000000000000000000000000000000..21f8f61eb5135f54458dc220ae6a60735b7df5b2 GIT binary patch literal 315 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2>S zOAux}KILpRkRe&(8c`CQpH@mmtT}V`<;yxP|*%g7sn8b z-m{Z7avcibaV?&F-F^C^j`+t48o$JMb$0*o<~ygCpRIUd<(GP|=f{>VuH9Ptam`Md zJdcilQlYl1UMWs{xX^LlbM3T!9VfQxoc@~9`2F9rIniAw4xM>7nZ-5m&ED_P*C#J~ z=@wcZ&*{VwIY~vGLAQa=Aw5mkc)l~o&49`MA)#N_y#6J4ddH0b7Y7%kXoiMP4trCB z%|DqKcoeiG{xruWB=fqlp1J5z)4D7(?u^XdL+AG}?iDsXA(4MK7w88DPgg&ebxsLQ E0EEGLuK)l5 literal 0 HcmV?d00001 diff --git a/rtdata/images/Dark/actions/arrow-up.png b/rtdata/images/Dark/actions/arrow-up.png new file mode 100644 index 0000000000000000000000000000000000000000..2f4a9d228668fb7f0b8351da9d680e516f69c4f9 GIT binary patch literal 472 zcmV;}0Vn>6P)=GXMYp8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10aZyvK~y-6-IKje0znjo&)lD#wICGKXkw$r*PvAkV`B`jKzJVu zYYNLH8xmTYZ7FR@j145a0gB;Th{i&65E?znbmx9Kb8;{6Zd|B} zx!Vcc@Apqs^;$%Ph?t02M8tc4GZ+lceg!UyLen(udhZWJgg(C{Nm5nq_IkaIm2BLK z*=%-bW}~t!MIHx;7K=GXMYp8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10fb3JK~y-6?UFG|13?gl-|U6Gh$#{!2zElS5X&G~1};ez()c^H z@<&)$*l1yAnJ#T^@vzWF`~zYkYLFCyNsM@xy;&O-jTf>=ECgS*^Je&V7#{GiH_@a4 z-}kGIi?*RZ(@1{~}o|zAbNB{s4?RcJdZj9ND<9N;zyaC|s3z(T*A;h{d zW(xqMly?9igculOtTs-iQu>?OYPA-XQnxk$t4~IaAP9u^X4m<+aZ>5#38Eg$=md?S^B)ql)ABMQc4V zmH?2?=XosH_x&RPVCKDQwR$0hSYl?YQ}lYhO91^uFcGx?KuX!Mflbt}$4x1<0sw=- z;I>|`_k$oPL{VgQiYSV1YPDK&+?crm0GUi?6Top8hO@SDW9IR3t5hnhpKI53JHz47 zDsF{BAxvyE8Vx70@dJHq(rh*ta=F~;)WPX=`iY1Rrv?6ddIbt=lrrDaS>XTx002ov JPDHLkV1h#>)=GXMYp8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10y;@VK~y-6wNyQC6G0H2-P=pJORSS4xv(NAp+v}nhA5JS>$GFun#-&S3r5ye!PA2W_D+Z zt_W%wAx+b30B$pLxP*GzYPC+s6SFk3QqPhkc>+L2008#h3p0y|Ff$7Po2Kd0X0!Qg zC1GPsH3$MV7!2Mx=XwC3wZ?cKfCli0h!SgUOhogA(=;_v6g8c5CqzWvd$!iTYPZ{8 zXYu#;_HF{WH@T)~5%WCXuGMOfiKwh<~qYwdjzDVW)dh+}3yhKRT%N!}9ChlRr93)|h@{j$Hm|I!#!0RUqR z0Kj`sB7#u~h?(u$+S;dC<}Nrk#@skMI{Frd;dc?~udlB|M37|}kAfozg1psgW%J52 zCERE2>S zOAux}KILpRkRe&(8c`CQpH@mmtT}V`<;yxP|+_>7sn8b z-mMeuy^c8u9E~>;oK_s|ZQ7VUh!>#{s!i-2{Yh^wN%j1c34 zaEAALKi^}wk6<=1X6HP}w`Qwe-(k(`RtftjC9YP`e5!W-bFxxbi-0=A35nvG!(M@`eIsXON{dwKCU<0KW!*~?!3`}|3Xf#F%@K7(U20vGidBC_MRTnqP( zi>i9_`=9CQP3jEoXWneN_B{8tU5zvY!(js(ao3H{=Tzs+diG5F{w+y;=U?;BNQc&? WElD^yWg0LP7(8A5T-G@yGywoe5tIi2 literal 0 HcmV?d00001 diff --git a/rtdata/images/Light/actions/arrow-down.png b/rtdata/images/Light/actions/arrow-down.png new file mode 100644 index 0000000000000000000000000000000000000000..36c366bd3c930ed55c9f9317ecebc59a46bc20c7 GIT binary patch literal 490 zcmV=GXMYp8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10cS}>K~y-6)sw+W0#Ou(|8vLY4h|t=G#GAb;l3A$UZR(2T|Pwg z4()pdHwCROVht{|2}Bu29Ile|T)2z#fBfg?USQuunxP~~;y8}a0l*m3 z?e%))Hcv$Zu2!o@Ns`u{vkvT>>ofDSwYFugJ)!R&D2k${wYDW9PwSun z5Nui}ilP@|%ta6chs-RiGn>tZlgZ?!C<^~4aGvMBUa!9axFjNohGWRX*_s#tilXq1Mq>z| gI~WXJHJ<&`7k?79nj0p3A^-pY07*qoM6N<$f2>S zOAux}KILpRkRe&(8c`CQpH@mmtT}V`<;yxP|;IQ7sn8b z-nSDrdL3~PaecpMx}xOe4o#+m=L|S~wEs2t)*aD{)~jot`~Q)<%Y|EIr%b{;#hskg z*rdxN3(7gS?cQFw=XCY-(~Re=)C`|@e480L?e4S6eY1ogywxj|X%7_9J!DXmar;}X z-+^t*uKnukxaPGo!s}%0^;*UsDoTni3+`(&9I*Uu%X4`3)@@%H6g($&XU>vaI_098 z0Y_8I%=I&8&Y0QRF(Z<};r{n^t5%saJk`@!xOLz6+WM7KcIC`^ws_s^>CRVs4Qm5M z9?M@kHbYyfs_0zrwOh|EWxj3ly!_?a{`1S1$samyxu!y^qX+0=22WQ%mvv4FO#l&w BmL32A literal 0 HcmV?d00001 diff --git a/rtdata/images/Light/actions/arrow-left.png b/rtdata/images/Light/actions/arrow-left.png new file mode 100644 index 0000000000000000000000000000000000000000..711ad1016b4735c4d693b71919e3afab98e25e42 GIT binary patch literal 447 zcmeAS@N?(olHy`uVBq!ia0vp^Vj#@H1|*Mc$*~4fEX7WqAsj$Z!;#Vf2>S zKM-czcvjvR$dD{?jVKAuPb(=;EJ|f4FE7{2%*!rLPAo{(%P&fw{mw>;fq~J+)5S5w zqWA5j-CoX)0&V60=0-*abH#Z~pQG}GNhv8kH9bA^v2e$c=Yb!1*W|L?ci3P%L#=o2 z@)M1dZKtnkRdJcbp?+iLda1OT`TrV2vkteFF38)SeTwg6e*fOMe0|@`|0- z$xKOxw1bySblnzTe7)(&s<`#;}oNxF{Ne=O&vn-|GG=G z<#RvM+#2=vO4RN3AzIewcIxy!etj?@;8pmG)Uz60ZP#w4FTJww`@UJve+G-VY74J- nU47Lm+idn#`>A<9me(-;`Vn8GX(W3Q7}yM+u6{1-oD!M2>S zOAux}KILpRkRe&(8c`CQpH@mmtT}V`<;yxP|+(-7sn8b z-nadRUPm27T;Kmt=j36T)X>5s)}+~1Qnv14^Nm|O8N(Bv^08!pe<+u;#lUw)P>_bF zYGaDg`$*RxM~^40US2z=`abKw$nG2EH`Z+IHN5UQN#;xK|8J`s7HOQD8Wf&6OD;9? z+ojUGTRzV+d}h)2*jw?4(1|lX_o|hYm2P zn-Z8A?p4R7JeT2AtjL@al=j#nE@N%{?QOCu3>jivIou3DAH*mBwAZe+IoH4E!0sg;|yz0v=~s>~dF@NtJ&6VTTTp00i_>zopr E0MF5rjQ{`u literal 0 HcmV?d00001 diff --git a/rtdata/images/Light/actions/arrow-right.png b/rtdata/images/Light/actions/arrow-right.png new file mode 100644 index 0000000000000000000000000000000000000000..933e84025cd8ffbda6fd003066fc3b01abf6b12b GIT binary patch literal 445 zcmV;u0Yd(XP)=GXMYp8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10Xj)UK~y-6?U1ob!%!54|K471VhSas6orCIF3HfL`UHZrYr)O; zaTGxZH($Wj&0WDwNZa5pQo$jnaPB!SMk=M&YB&3B2mbRN&JV0v^Jlu>D*4q9&M}1jo6h)Eec?ZTAqqW`*!>|{I;lp@5ex1&J zb`{6*QM=vVt7Z||VCEV#GXQbUiHHa@*L~mL1OOsp=bW2NCU4AqIUEkJ05AaPN@R@L zYPDLu>8s4lM8p+D#6;voM4WS6<&;vMh#XpLA4j9n{TDG2-DFvoFRDT*6*U@-zSdfO zd?rM6$IPdBo`l n#xX;ZB%L%(_g5lY^Urt(7ax<&*{b^b00000NkvXXu0mjf6C=Bo literal 0 HcmV?d00001 diff --git a/rtdata/images/Light/actions/arrow-up-small.png b/rtdata/images/Light/actions/arrow-up-small.png new file mode 100644 index 0000000000000000000000000000000000000000..9b8884c5e0d3a95b023540860e4b77b2d1cba5b5 GIT binary patch literal 338 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2>S zOAux}KILpRkRe&(8c`CQpH@mmtT}V`<;yxP|j2zDoDqfhgf~!#_lXcTg*N3}yGaa66 ztbhLxQ~laitIA4a^ONPcRA()VtbDJ}kTGjn^8N4YE#=!8&h4DMN-wnZ;F;$W{GTwa96(^b literal 0 HcmV?d00001 diff --git a/rtdata/images/Light/actions/arrow-up.png b/rtdata/images/Light/actions/arrow-up.png new file mode 100644 index 0000000000000000000000000000000000000000..df6b022a3b543747551dbaf9ced99ecdcf4acef2 GIT binary patch literal 468 zcmV;_0W1EAP)=GXMYp8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10Z~arK~y-6-IGm913?glt6ud_Hen!}xKY70Gl5yoIn=#qt`NL} zC-DUCJwbM^vh@HmGB5)Yl3}J@Xdr>abZ|EMprN7aeO0`siT85EO`u+Y10Ny;t7**GGJRA<6^E_{M z`PDvfS(ax2W<^oVy!TNQMOSUxQdLz?06vI_>bgE9qSsx1-kZaQMx)W`U@&+jB3djK zH}m=Y?T}~h##_^wy@FaXcYU}oR8ZFgWIA`xNlJ#`9ZW)I+~D1yE;052lU z%t6p#@LJ5wp-}{HyuNoD1vC4@UE2zJywz&eR8^G|(a{6`jy?fX&}x<8Hqhb#0000< KMNUMnLSTaEz{R%! literal 0 HcmV?d00001 diff --git a/rtdata/images/Light/actions/filter-original-1.png b/rtdata/images/Light/actions/filter-original-1.png new file mode 100644 index 0000000000000000000000000000000000000000..2daef11fbc1548b6be2ec88e4170164bffa5560f GIT binary patch literal 504 zcmV=GXMYp8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10d+}4K~y-6?UKJr13?gnf3tIN5lI3{5bR9$%poa7@CkeYpF=Aj z!otEv3p-06!9uW51UX2VKL*4|LJC31DJI7S{nFm&@H%tJP=U_gAARnwU!>pU>Y1 zLGYR=X67RR2*Yp>z@^rD&KP4Q4#SXBH*PkY8>4rnR97h_Y{Z#NW{@f#hlt*U5L06b z0EI$9r;4SNrvPA#Ic&9Bfe>QF_A9#GZUaC+QOwNe0HBoW*~q5y>v5A(t^oiux9jzK zzf>woX0}bmL#NY8jvEo3#m5~07tB1bl(G_Mv)OOsRvEnyhr^!hx>j*>9A}W$AD0??g2ZdVz0000=GXMYp8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10#r#vK~y-6wUobZ6G0HhXVyMlE_cWx7nDe`(WMBK2u0A)1R+H! zprJyd<{fwx8Y*6ahJuj^Pe0Ah?kvC! z36}+uBw6!3?*TJ=OQM}ttJS$!l$U{{D0&me@hcG#W)=}q5n<98Rt1l7p4gi3v7R9brA=vkQER{-2FLnws^O#Gm zI669dG#Cs9XJ=>mjQ#iJ!c4{c`}^L;#>T@+rBayLy3000pSTk|jaZ=h?z zh&b)1h!pz&1ZL*BfQW#q8X{U>1VO~$s<(9V06=};FUN8GE{@}znMGBVh-5O#AR++( z==u5i^kkR7SB|Uz0K?(%bGO^Qud1cVKOw5B6R7B)>FF6`zI8gC?n)I0K~NiwMqjcl zd%Gy(d0y}2MMTQXiik=?fQZV>;+z8_vejy}QLoqM7<1q#itZjB9{$X-EJeg$zVEBG zR8JX#4#> zjYcEO%q~sS769}Li4$G=1d=3Kn>?L`GRA1T-Od0&uFKt+egmtzS*k03#e4t&002ov JPDHLkV1irIJZ1m@ literal 0 HcmV?d00001 diff --git a/tools/source_icons/scalable/arrow-down-small.file b/tools/source_icons/scalable/arrow-down-small.file new file mode 100644 index 000000000..df0b971b0 --- /dev/null +++ b/tools/source_icons/scalable/arrow-down-small.file @@ -0,0 +1 @@ +arrow-down-small.png,w16,actions diff --git a/tools/source_icons/scalable/arrow-down-small.svg b/tools/source_icons/scalable/arrow-down-small.svg new file mode 100644 index 000000000..7042bdabd --- /dev/null +++ b/tools/source_icons/scalable/arrow-down-small.svg @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/arrow-down.file b/tools/source_icons/scalable/arrow-down.file new file mode 100644 index 000000000..67ebd1f45 --- /dev/null +++ b/tools/source_icons/scalable/arrow-down.file @@ -0,0 +1 @@ +arrow-down.png,w22,actions diff --git a/tools/source_icons/scalable/arrow-down.svg b/tools/source_icons/scalable/arrow-down.svg new file mode 100644 index 000000000..7042bdabd --- /dev/null +++ b/tools/source_icons/scalable/arrow-down.svg @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/arrow-left-small.file b/tools/source_icons/scalable/arrow-left-small.file new file mode 100644 index 000000000..fcf5e7094 --- /dev/null +++ b/tools/source_icons/scalable/arrow-left-small.file @@ -0,0 +1 @@ +arrow-left-small.png,w16,actions diff --git a/tools/source_icons/scalable/arrow-left-small.svg b/tools/source_icons/scalable/arrow-left-small.svg new file mode 100644 index 000000000..c0ecb3b13 --- /dev/null +++ b/tools/source_icons/scalable/arrow-left-small.svg @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/arrow-left.file b/tools/source_icons/scalable/arrow-left.file new file mode 100644 index 000000000..4ed6a9390 --- /dev/null +++ b/tools/source_icons/scalable/arrow-left.file @@ -0,0 +1 @@ +arrow-left.png,w22,actions diff --git a/tools/source_icons/scalable/arrow-left.svg b/tools/source_icons/scalable/arrow-left.svg new file mode 100644 index 000000000..c0ecb3b13 --- /dev/null +++ b/tools/source_icons/scalable/arrow-left.svg @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/arrow-right-small.file b/tools/source_icons/scalable/arrow-right-small.file new file mode 100644 index 000000000..bc480df22 --- /dev/null +++ b/tools/source_icons/scalable/arrow-right-small.file @@ -0,0 +1 @@ +arrow-right-small.png,w16,actions diff --git a/tools/source_icons/scalable/arrow-right-small.svg b/tools/source_icons/scalable/arrow-right-small.svg new file mode 100644 index 000000000..8d1c4694c --- /dev/null +++ b/tools/source_icons/scalable/arrow-right-small.svg @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/arrow-right.file b/tools/source_icons/scalable/arrow-right.file new file mode 100644 index 000000000..7040fee0a --- /dev/null +++ b/tools/source_icons/scalable/arrow-right.file @@ -0,0 +1 @@ +arrow-right.png,w22,actions diff --git a/tools/source_icons/scalable/arrow-right.svg b/tools/source_icons/scalable/arrow-right.svg new file mode 100644 index 000000000..8d1c4694c --- /dev/null +++ b/tools/source_icons/scalable/arrow-right.svg @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/arrow-up-small.file b/tools/source_icons/scalable/arrow-up-small.file new file mode 100644 index 000000000..e20834553 --- /dev/null +++ b/tools/source_icons/scalable/arrow-up-small.file @@ -0,0 +1 @@ +arrow-up-small.png,w16,actions diff --git a/tools/source_icons/scalable/arrow-up-small.svg b/tools/source_icons/scalable/arrow-up-small.svg new file mode 100644 index 000000000..cb6379f6b --- /dev/null +++ b/tools/source_icons/scalable/arrow-up-small.svg @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/arrow-up.file b/tools/source_icons/scalable/arrow-up.file new file mode 100644 index 000000000..187c9e710 --- /dev/null +++ b/tools/source_icons/scalable/arrow-up.file @@ -0,0 +1 @@ +arrow-up.png,w22,actions diff --git a/tools/source_icons/scalable/arrow-up.svg b/tools/source_icons/scalable/arrow-up.svg new file mode 100644 index 000000000..cb6379f6b --- /dev/null +++ b/tools/source_icons/scalable/arrow-up.svg @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/filter-original-1.file b/tools/source_icons/scalable/filter-original-1.file new file mode 100644 index 000000000..8f2876c7b --- /dev/null +++ b/tools/source_icons/scalable/filter-original-1.file @@ -0,0 +1 @@ +filter-original-1.png,w22,actions diff --git a/tools/source_icons/scalable/filter-original-1.svg b/tools/source_icons/scalable/filter-original-1.svg new file mode 100644 index 000000000..4295c2fdb --- /dev/null +++ b/tools/source_icons/scalable/filter-original-1.svg @@ -0,0 +1,738 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/filter-original-2.file b/tools/source_icons/scalable/filter-original-2.file new file mode 100644 index 000000000..d2e205806 --- /dev/null +++ b/tools/source_icons/scalable/filter-original-2.file @@ -0,0 +1 @@ +filter-original-2.png,w22,actions diff --git a/tools/source_icons/scalable/filter-original-2.svg b/tools/source_icons/scalable/filter-original-2.svg new file mode 100644 index 000000000..e1c436ac0 --- /dev/null +++ b/tools/source_icons/scalable/filter-original-2.svg @@ -0,0 +1,768 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + From 1b4fd2dcb5e1a56c0f17390a741e9be4137937a5 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Thu, 17 Dec 2015 20:01:40 +0100 Subject: [PATCH 29/61] Use the provided images for the filter-original button and the parsed extensions list and extend the filer-original tool tip. --- rtdata/languages/default | 2 +- rtgui/filecatalog.cc | 5 ++++- rtgui/filecatalog.h | 2 +- rtgui/preferences.cc | 6 ++++-- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 9b23d2e3b..48acb81f9 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -171,7 +171,7 @@ FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. -FILEBROWSER_SHOWORIGINALHINT;Show only the original images. +FILEBROWSER_SHOWORIGINALHINT;Show only the original images.\n\nThe orignal images are determined by the position of their file extensions in the parsed extensions list in the preferences. Extensions higher up in that list are considered the originals of those below. FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1-star.\nShortcut: 1 FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2-star.\nShortcut: 2 FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3-star.\nShortcut: 3 diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 92ce120c2..3ea7e6db2 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -286,6 +286,7 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : bTrash->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event), false); iNotTrash = new RTImage("trash-hide-deleted.png") ; + iOriginal = new RTImage("filter-original-2.png"); bNotTrash = Gtk::manage( new Gtk::ToggleButton () ); bNotTrash->set_image (*iNotTrash); @@ -295,7 +296,7 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : bNotTrash->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event), false); bOriginal = Gtk::manage( new Gtk::ToggleButton () ); - bOriginal->set_label ("O"); // TODO: Add icon... + bOriginal->set_image (*iOriginal); bOriginal->set_tooltip_markup (M("FILEBROWSER_SHOWORIGINALHINT")); bOriginal->set_relief (Gtk::RELIEF_NONE); bCateg[19] = bOriginal->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bOriginal, true)); @@ -450,6 +451,8 @@ FileCatalog::~FileCatalog() delete igUnCLabeled; delete iTrashEmpty; delete iTrashFull; + delete iNotTrash; + delete iOriginal; delete iRefreshWhite; delete iRefreshRed; delete iQueryClear; diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h index eda0ff81a..b30ebb553 100644 --- a/rtgui/filecatalog.h +++ b/rtgui/filecatalog.h @@ -118,7 +118,7 @@ private: Gtk::Image* iEdited[2], *igEdited[2]; Gtk::Image* iRecentlySaved[2], *igRecentlySaved[2]; Gtk::Image *iTrashEmpty, *iTrashFull; - Gtk::Image *iNotTrash; + Gtk::Image *iNotTrash, *iOriginal; Gtk::Image *iRefreshWhite, *iRefreshRed; Gtk::Image *iLeftPanel_1_Show, *iLeftPanel_1_Hide, *iRightPanel_1_Show, *iRightPanel_1_Hide; Gtk::Image *iQueryClear; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 739f833b1..dca0eff17 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1196,10 +1196,12 @@ Gtk::Widget* Preferences::getFileBrowserPanel () moveExtDown->set_tooltip_text (M("PREFERENCES_PARSEDEXTDOWNHINT")); Gtk::Image* addExtImg = Gtk::manage( new RTImage ("list-add-small.png") ); Gtk::Image* delExtImg = Gtk::manage( new RTImage ("list-remove-red-small.png") ); + Gtk::Image* moveExtUpImg = Gtk::manage( new RTImage ("arrow-up-small.png") ); + Gtk::Image* moveExtDownImg = Gtk::manage( new RTImage ("arrow-down-small.png") ); addExt->add (*addExtImg); delExt->add (*delExtImg); - moveExtUp->set_label ("↑"); // TODO: Add arrow up image... - moveExtDown->set_label ("↓"); // TODO: Add arrow down image... + moveExtUp->set_image (*moveExtUpImg); + moveExtDown->set_image (*moveExtDownImg); hb0->pack_end (*moveExtDown, Gtk::PACK_SHRINK, 4); hb0->pack_end (*moveExtUp, Gtk::PACK_SHRINK, 4); hb0->pack_end (*delExt, Gtk::PACK_SHRINK, 4); From e9141dd98c98d3e8d9dee1fb36bfa0cfbef360d8 Mon Sep 17 00:00:00 2001 From: Hombre Date: Fri, 18 Dec 2015 01:45:59 +0100 Subject: [PATCH 30/61] Cleaning up the GUI for the monitor profile and rendering intent + output profile rendering intent + soft-proof button. DCP profile GUI switched from 2x2 array to a single column. --- rtdata/languages/default | 3 +- rtengine/iccstore.cc | 5 +++ rtengine/improcfun.cc | 4 -- rtgui/editorpanel.cc | 87 ++++++++++++++++++++++------------------ rtgui/editorpanel.h | 2 +- rtgui/icmpanel.cc | 26 ++++++------ rtgui/popupbutton.cc | 5 +++ rtgui/popupbutton.h | 1 + 8 files changed, 75 insertions(+), 58 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index ad30fbff2..a5e4611c6 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -773,6 +773,7 @@ MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l MAIN_TOOLTIP_THRESHOLD;Threshold MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b +MONITOR_SOFTPROOF;Soft-proof MONITOR_PROFILE_SYSTEM;System default NAVIGATOR_B;B: NAVIGATOR_G;G: @@ -1513,7 +1514,7 @@ TP_ICM_INPUTPROFILE;Input Profile TP_ICM_LABEL;Color Management TP_ICM_NOICM;No ICM: sRGB Output TP_ICM_OUTPUTPROFILE;Output Profile -TP_ICM_OUTPUTPROFILEINTENT;Output Rendering Intent +TP_ICM_PROFILEINTENT;Rendering Intent TP_ICM_SAVEREFERENCE;Save Reference Image for Profiling TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP;Generally, apply the white balance when saving images to create ICC profiles, and do not apply the white balance to create DCP profiles. diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index 24f2bb936..b77da03dd 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -478,6 +478,11 @@ void ICCStore::findDefaultMonitorProfile () if (GetICMProfileA(hDC, &profileLength, profileName)) { defaultMonitorProfile = Glib::ustring(profileName); + defaultMonitorProfile = Glib::path_get_basename(defaultMonitorProfile); + size_t pos = defaultMonitorProfile.rfind("."); + if (pos != Glib::ustring::npos) { + defaultMonitorProfile = defaultMonitorProfile.substr(0, pos); + } } // might fail if e.g. the monitor has no profile diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index e99daa79a..8866cd398 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -211,11 +211,9 @@ void ImProcFunctions::updateColorProfiles (const ColorManagementParams &icm, Gli cmsHPROFILE monitor = iccStore->getProfile (monitorProfile); - printf("ImProcFunctions::updateColorProfiles / monitor profile = %s / intent = %d\n", monitorProfile.c_str(), monitorIntent); if (monitor) { MyMutex::MyLock lcmsLock (*lcmsMutex); cmsHPROFILE iprof = cmsCreateLab4Profile(NULL); - printf(" - monitorTransform = cmsCreateTransform / intent=%d\n", monitorIntent); monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is for thread safety, NOOPTIMIZE for precision @@ -229,9 +227,7 @@ void ImProcFunctions::updateColorProfiles (const ColorManagementParams &icm, Gli //TODO: Create a dedicated softproof transformation (line below to be finished) //lab2outputTransform = cmsCreateProofingTransform(iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, monitor, icm.outputIntent, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE | cmsFLAGS_SOFTPROOFING ); - printf(" - lab2outputTransform = cmsCreateTransform / intent=%d\n", icm.outputIntent); lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, icm.outputIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); - printf(" - output2monitorTransform = cmsCreateTransform / intent=%d\n", monitorIntent); output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); } } diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index a762fc95b..74fa2f937 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -37,9 +37,8 @@ class MonitorProfileSelector private: Gtk::ToggleButton* softProof; MyComboBoxText* profileBox; - //PopUpButton* intentBox; - MyComboBoxText* intentBox; - sigc::connection profileConn, intentConn; + PopUpButton* intentBox; + sigc::connection profileConn, intentConn, softProofConn; rtengine::StagedImageProcessor* processor; @@ -51,7 +50,8 @@ private: softProof = Gtk::manage(new Gtk::ToggleButton()); softProof->add(*softProofImg); softProof->set_relief(Gtk::RELIEF_NONE); - softProof->signal_toggled().connect (sigc::mem_fun (this, &MonitorProfileSelector::softProofToggled)); + softProof->set_tooltip_text(M("MONITOR_SOFTPROOF")); + softProofConn = softProof->signal_toggled().connect (sigc::mem_fun (this, &MonitorProfileSelector::softProofToggled)); } void prepareProfileBox () @@ -76,17 +76,13 @@ private: void prepareIntentBox () { - intentBox = Gtk::manage(new MyComboBoxText()); - intentBox->set_size_request(-1,-1); - //intentBox = Gtk::manage(new PopUpButton()); - - intentBox->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); - intentBox->append_text (M("PREFERENCES_INTENT_RELATIVE")); - //intentBox->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); - //intentBox->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); - //intentBox->setSelected(0); - intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); - //intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateIntent)); + PopUpButton *bt = new PopUpButton(); + intentBox = Gtk::manage(bt); + intentBox->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); + intentBox->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); + intentBox->setSelected(0); + intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateIntent)); + intentBox->show(); } void softProofToggled () @@ -105,6 +101,7 @@ private: void updateParameters () { Glib::ustring profile; + profileBox->set_tooltip_text(profileBox->get_active_text ()); #ifdef WIN32 if (profileBox->get_active_row_number () == 1) { profile = rtengine::iccStore->getDefaultMonitorProfileStr (); @@ -121,23 +118,36 @@ private: profile = profileBox->get_active_row_number () > 0 ? profileBox->get_active_text () : Glib::ustring(); #endif - std::uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile); - const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL; - const bool supportsRelativeColorimetric = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC; - - if (supportsPerceptual && supportsRelativeColorimetric) { - intentBox->set_sensitive (true); - } - else { + // MonitorProfile = None , disabling everything + if (profileBox->get_active_row_number () == 0) { + profile.clear(); bool wasBlocked = intentConn.block(true); - intentBox->set_active(supportsPerceptual ? 0 : 1); - //intentBox->setSelected(supportsPerceptual ? 0 : 1); + intentBox->setSelected(1); intentBox->set_sensitive (false); intentConn.block(wasBlocked); + softProof->set_active(false); + softProof->set_sensitive(false); + wasBlocked = softProofConn.block(true); + softProofConn.block(wasBlocked); + + } else { + std::uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile); + const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL; + const bool supportsRelativeColorimetric = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC; + + if (supportsPerceptual && supportsRelativeColorimetric) { + intentBox->set_sensitive (true); + } + else { + bool wasBlocked = intentConn.block(true); + intentBox->setSelected(supportsPerceptual ? 0 : 1); + intentBox->set_sensitive (false); + intentConn.block(wasBlocked); + } + softProof->set_sensitive(true); } - //rtengine::eRenderingIntent intent = intentBox->getSelected() > 0 ? rtengine::RI_PERCEPTUAL : rtengine::RI_RELATIVE; - rtengine::eRenderingIntent intent = intentBox->get_active_row_number() > 0 ? rtengine::RI_RELATIVE : rtengine::RI_PERCEPTUAL; + rtengine::eRenderingIntent intent = intentBox->getSelected() > 0 ? rtengine::RI_PERCEPTUAL : rtengine::RI_RELATIVE; if (!processor) { return; @@ -148,9 +158,14 @@ private: //options.rtSettings.monitorIntent = intent; // ...or store them locally - printf("Appel de processor->setMonitorProfile(%s, %d)\n", profile.c_str(), intent); + processor->beginUpdateParams (); + if (options.rtSettings.verbose) { + printf("Monitor profile: %s, Intent: %s)\n", + profile.empty() ? "None" : profile.c_str(), + intent > 0 ? M("PREFERENCES_INTENT_PERCEPTUAL").c_str() : M("PREFERENCES_INTENT_RELATIVE").c_str() + ); + } processor->setMonitorProfile(profile, intent); - printf("Appel de processor->endUpdateParams(%d)\n", rtengine::EvMonitorTransform); processor->endUpdateParams (rtengine::EvMonitorTransform); } @@ -169,8 +184,8 @@ public: void pack_end_in (Gtk::Box* box) { box->pack_end (*softProof, Gtk::PACK_SHRINK, 0); - box->pack_end (*intentBox, Gtk::PACK_SHRINK, 0); - box->pack_end (*profileBox, Gtk::PACK_EXPAND_WIDGET, 0); + box->pack_end (*intentBox->buttonGroup, Gtk::PACK_SHRINK, 0); + box->pack_end (*profileBox, Gtk::PACK_SHRINK, 0); } void reset () @@ -190,12 +205,10 @@ public: profileConn.block(wasBlocked); #endif wasBlocked = intentConn.block(true); - intentBox->set_active (options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 0 : 1); - //intentBox->setSelected(options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 0 : 1); + intentBox->setSelected(options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 0 : 1); intentConn.block(wasBlocked); - // useless, set_active will trigger the signal_changed event - //updateParameters (); + updateParameters(); } void setImageProcessor (rtengine::StagedImageProcessor* imageProc) { @@ -205,7 +218,7 @@ public: }; EditorPanel::EditorPanel (FilePanel* filePanel) - : realized(false), iHistoryShow(NULL), iHistoryHide(NULL), iTopPanel_1_Show(NULL), iTopPanel_1_Hide(NULL), iRightPanel_1_Show(NULL), iRightPanel_1_Hide(NULL), iBeforeLockON(NULL), iBeforeLockOFF(NULL), beforePreviewHandler(NULL), beforeIarea(NULL), beforeBox(NULL), afterBox(NULL), afterHeaderBox(NULL), parent(NULL), openThm(NULL), ipc(NULL), beforeIpc(NULL), isProcessing(false), catalogPane(NULL) + : realized(false), iHistoryShow(NULL), iHistoryHide(NULL), iTopPanel_1_Show(NULL), iTopPanel_1_Hide(NULL), iRightPanel_1_Show(NULL), iRightPanel_1_Hide(NULL), iBeforeLockON(NULL), iBeforeLockOFF(NULL), beforePreviewHandler(NULL), monitorProfile(new MonitorProfileSelector ()), beforeIarea(NULL), beforeBox(NULL), afterBox(NULL), afterHeaderBox(NULL), parent(NULL), openThm(NULL), ipc(NULL), beforeIpc(NULL), isProcessing(false), catalogPane(NULL) { epih = new EditorPanelIdleHelper; @@ -438,7 +451,6 @@ EditorPanel::EditorPanel (FilePanel* filePanel) // Monitor profile buttons iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); - monitorProfile = new MonitorProfileSelector (); monitorProfile->pack_end_in (iops); editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0); @@ -577,7 +589,6 @@ EditorPanel::~EditorPanel () delete ppframe; delete leftbox; delete vboxright; - delete monitorProfile; //delete saveAsDialog; if(catalogPane) { diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index 0575b7f92..ffb8a93a4 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -86,7 +86,7 @@ protected: Gtk::Button* navNext; Gtk::Button* navPrev; - MonitorProfileSelector* monitorProfile; + std::auto_ptr monitorProfile; ImageAreaPanel* iareapanel; PreviewHandler* previewHandler; diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index 55e8e1a6e..8b2965cab 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -83,7 +83,8 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch dcpFrame = Gtk::manage (new Gtk::Frame ("DCP")); Gtk::VBox* dcpFrameVBox = Gtk::manage (new Gtk::VBox ()); - dcpFrameVBox->set_border_width(4); + dcpFrameVBox->set_border_width(0); + dcpFrameVBox->set_spacing(2); Gtk::HBox* dcpIllHBox = Gtk::manage (new Gtk::HBox ()); dcpIllLabel = Gtk::manage (new Gtk::Label (M("TP_ICM_DCPILLUMINANT") + ":")); @@ -101,29 +102,25 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch dcpIllHBox->pack_start(*dcpIllLabel, Gtk::PACK_SHRINK, 4); dcpIllHBox->pack_start(*dcpIll); - Gtk::HBox* c1HBox = Gtk::manage ( new Gtk::HBox(true, 4)); ckbToneCurve = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_TONECURVE"))); ckbToneCurve->set_sensitive (false); ckbToneCurve->set_tooltip_text (M("TP_ICM_TONECURVE_TOOLTIP")); ckbApplyHueSatMap = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_APPLYHUESATMAP"))); ckbApplyHueSatMap->set_sensitive (false); ckbApplyHueSatMap->set_tooltip_text (M("TP_ICM_APPLYHUESATMAP_TOOLTIP")); - c1HBox->pack_start (*ckbToneCurve); - c1HBox->pack_start (*ckbApplyHueSatMap); - Gtk::HBox* c2HBox = Gtk::manage ( new Gtk::HBox(true, 4)); ckbApplyLookTable = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_APPLYLOOKTABLE"))); ckbApplyLookTable->set_sensitive (false); ckbApplyLookTable->set_tooltip_text (M("TP_ICM_APPLYLOOKTABLE_TOOLTIP")); ckbApplyBaselineExposureOffset = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_APPLYBASELINEEXPOSUREOFFSET"))); ckbApplyBaselineExposureOffset->set_sensitive (false); ckbApplyBaselineExposureOffset->set_tooltip_text (M("TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP")); - c2HBox->pack_start (*ckbApplyLookTable); - c2HBox->pack_start (*ckbApplyBaselineExposureOffset); - dcpFrameVBox->pack_start(*dcpIllHBox); - dcpFrameVBox->pack_start(*c1HBox); - dcpFrameVBox->pack_start(*c2HBox); + dcpFrameVBox->pack_start(*dcpIllHBox, Gtk::PACK_SHRINK, 0); + dcpFrameVBox->pack_start(*ckbToneCurve, Gtk::PACK_SHRINK,0); + dcpFrameVBox->pack_start(*ckbApplyHueSatMap, Gtk::PACK_SHRINK,0); + dcpFrameVBox->pack_start(*ckbApplyLookTable, Gtk::PACK_SHRINK,0); + dcpFrameVBox->pack_start(*ckbApplyBaselineExposureOffset, Gtk::PACK_SHRINK,0); dcpFrame->add(*dcpFrameVBox); dcpFrame->set_sensitive(false); iVBox->pack_start (*dcpFrame); @@ -194,16 +191,17 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch onames->set_active (0); // Rendering intent - - Gtk::Label* outputIntentLbl = Gtk::manage (new Gtk::Label(M("TP_ICM_OUTPUTPROFILEINTENT"))); - oVBox->pack_start (*outputIntentLbl, Gtk::PACK_SHRINK); + Gtk::HBox *riHBox = Gtk::manage ( new Gtk::HBox()); + Gtk::Label* outputIntentLbl = Gtk::manage (new Gtk::Label(M("TP_ICM_PROFILEINTENT")+":")); + riHBox->pack_start (*outputIntentLbl, Gtk::PACK_SHRINK); ointent = Gtk::manage (new MyComboBoxText ()); - oVBox->pack_start (*ointent, Gtk::PACK_EXPAND_WIDGET); + riHBox->pack_start (*ointent, Gtk::PACK_EXPAND_WIDGET); ointent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); ointent->append_text (M("PREFERENCES_INTENT_RELATIVE")); ointent->append_text (M("PREFERENCES_INTENT_SATURATION")); ointent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); ointent->set_active(0); + oVBox->pack_start(*riHBox, Gtk::PACK_SHRINK); // Output gamma diff --git a/rtgui/popupbutton.cc b/rtgui/popupbutton.cc index 440d7b420..e0cca8bd0 100644 --- a/rtgui/popupbutton.cc +++ b/rtgui/popupbutton.cc @@ -39,3 +39,8 @@ void PopUpButton::set_tooltip_text (const Glib::ustring &text) { PopUpCommon::set_tooltip_text (text); } + +void PopUpButton::set_sensitive (bool isSensitive) +{ + buttonGroup->set_sensitive(isSensitive); +} diff --git a/rtgui/popupbutton.h b/rtgui/popupbutton.h index 23a9211a8..dec848b14 100644 --- a/rtgui/popupbutton.h +++ b/rtgui/popupbutton.h @@ -31,6 +31,7 @@ public: PopUpButton (const Glib::ustring& label = ""); void show (); void set_tooltip_text (const Glib::ustring &text); + void set_sensitive (bool isSensitive=true); }; #endif From 1ef2229ba43338a53d049d893b6a009635332e28 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sat, 19 Dec 2015 09:18:18 +0100 Subject: [PATCH 31/61] Close #3025 by fixing the fully defining the original selection function. --- rtgui/filebrowser.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 7d921b328..8bb1d69bb 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -67,17 +67,19 @@ const Glib::ustring* getOriginalExtension (const ThumbBrowserEntryBase* entry) ThumbBrowserEntryBase* selectOriginalEntry (ThumbBrowserEntryBase* original, ThumbBrowserEntryBase* candidate) { + if (original == NULL) { + return candidate; + } + // The candidate will become the new original, if it has an original extension // and if its extension is higher in the list than the old original. if (const Glib::ustring* candidateExtension = getOriginalExtension (candidate)) { - if (original == NULL) { - return candidate; - } else if (const Glib::ustring* originalExtension = getOriginalExtension (original)) { + if (const Glib::ustring* originalExtension = getOriginalExtension (original)) { return candidateExtension < originalExtension ? candidate : original; } - } else { - return original; } + + return original; } void findOriginalEntries (const std::vector& entries) From c09a00bf16cbb29cb7fc3dccd4d5a76f7d580a68 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sat, 19 Dec 2015 09:39:54 +0100 Subject: [PATCH 32/61] Expose force the old C++ ABI as a build time flag. --- CMakeLists.txt | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 615348484..4724c4001 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,14 +13,9 @@ endif () string (TOUPPER ${CMAKE_BUILD_TYPE} UPPER_CMAKE_BUILD_TYPE) -# assuming that Linux and Apple users will have gtk2 built by their installed gcc -if (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) - if (GCC_VERSION VERSION_GREATER 5.0 OR GCC_VERSION VERSION_EQUAL 5.0) - message(STATUS "Gcc Version >= 5.0 ; adding -D_GLIBCXX_USE_CXX11_ABI=0 to build with Gtk2") - add_definitions (-D_GLIBCXX_USE_CXX11_ABI=0) - # see here : https://gcc.gnu.org/gcc-5/changes.html#libstdcxx - endif() +# We might want to build using the old C++ ABI, even when using a new GCC version +if (USE_OLD_CXX_ABI) + add_definitions (-D_GLIBCXX_USE_CXX11_ABI=0) endif() if (UPPER_CMAKE_BUILD_TYPE STREQUAL "DEBUG") From 052533bdcc049469a2140c2ea8c49817285b0e0f Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sat, 19 Dec 2015 15:45:35 +0100 Subject: [PATCH 33/61] Always enable C++11 support and warn if GCC older than 4.9 is used. --- CMakeLists.txt | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4724c4001..6f5c168f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,14 @@ endif () string (TOUPPER ${CMAKE_BUILD_TYPE} UPPER_CMAKE_BUILD_TYPE) +# Set required C and C++ standards and check GCC version +SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11") +SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") + +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9") + message(WARNING "RawTherapee should be built using GCC version 4.9 or higher!") +endif() + # We might want to build using the old C++ ABI, even when using a new GCC version if (USE_OLD_CXX_ABI) add_definitions (-D_GLIBCXX_USE_CXX11_ABI=0) @@ -89,6 +97,7 @@ option(USE_EXPERIMENTAL_LANG_VERSIONS "Build RT with -std=c++0x" OFF) option (BUILD_SHARED "Build rawtherapee with shared libraries" OFF) option (WITH_BZIP "Build with Bzip2 support" ON) option (WITH_MYFILE_MMAP "Build using memory mapped file" ON) +option (WITH_LTO "Build with link-time optimizations" OFF) option (OPTION_OMP "Build with OpenMP support" ON) option (PROTECT_VECTORS "Protect critical vectors by custom R/W Mutex, recommanded even if your std::vector is thread safe" ON) option (STRICT_MUTEX "True (recommended): MyMutex will behave like POSIX Mutex; False: MyMutex will behave like POSIX RecMutex; Note: forced to ON for Debug builds" ON) @@ -266,6 +275,12 @@ if (WITH_MYFILE_MMAP) add_definitions (-DMYFILE_MMAP) endif (WITH_MYFILE_MMAP) +if (WITH_LTO) + SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto") + SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto") + SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto") +endif (WITH_LTO) + if (OPTION_OMP) find_package(OpenMP) if (OPENMP_FOUND) @@ -273,11 +288,6 @@ if (OPTION_OMP) endif (OPENMP_FOUND) endif (OPTION_OMP) -if(USE_EXPERIMENTAL_LANG_VERSIONS OR NOT (SIGC_VERSION VERSION_LESS 2.5.1)) - SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu1x") - SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x") -endif () - # find out whether we are building out of source get_filename_component(ABS_SOURCE_DIR "${PROJECT_SOURCE_DIR}" ABSOLUTE) get_filename_component(ABS_BINARY_DIR "${CMAKE_BINARY_DIR}" ABSOLUTE) From 0a56ba6e87fd57f2239f220ae14ba1fa158a2559 Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Sat, 19 Dec 2015 18:12:05 +0100 Subject: [PATCH 34/61] Delete COMPILE.txt Deleted COMPILE.txt, refer to: http://rawpedia.rawtherapee.com/Linux http://rawpedia.rawtherapee.com/Windows http://rawpedia.rawtherapee.com/OS_X --- COMPILE.txt | 516 ---------------------------------------------------- 1 file changed, 516 deletions(-) delete mode 100644 COMPILE.txt diff --git a/COMPILE.txt b/COMPILE.txt deleted file mode 100644 index 9b16c1f79..000000000 --- a/COMPILE.txt +++ /dev/null @@ -1,516 +0,0 @@ -If you have problems with the compilation, please ask on the appropriate -RawTherapee forum: http://www.rawtherapee.com/forum/viewforum.php?f=10 - -PREAMBLE --------- - - Some commands span multiple lines, each line of such a command except for the - last one will end in a backslash character, "\". - When copying code, be sure to copy all lines from the first one that ends in \ - till the last line that does not end in a \ character. - - Some parts of code contain . Replace these with whatever - value is needed, e.g. - - CMake is actually used to create the makefiles (scripts that handle the build - process) or specific Integrated Developement Environement (IDE) projects. It - is designed to find all necessary compilation flags for your specific machine, - but everything can be overriden. - - RawTherapee's build mechanism will generate a build information file, named - "AboutThisBuild.txt", and require some parameters that can't be set by CMake, - so it's done in our build script, and may be overridden at your own will. The - build process also enables some sort of cross-compiling, since you can only - choose a specific processor variation of the same type (e.g. core2, athlon64, - which are both an x86 architecture). Real cross-compiling (e.g. building the - Windows version on a Linux platform) has not been tested. - - By default, no processor is specified, so CMake/GCC will build RT for your - machine's processor. You can specify that the build is to be made for a - generic processor by using the -DPROC_TARGET_NUMBER="1" CMake option. - Developers who are providing builds for download from the RawTherapee website - have to set the processor label (a human-readable description of the - processor, set to "undefined" by default) manually with the -DPROC_LABEL="foo" - CMake parameter. - - Note for developers that handle an automated build system: Mercurial is - required in order to produce the build information file, but your build system - will certainly only use the source code without any access to a Mercurial - repository. To generate the needed information, run the script: - ./tools/generateReleaseInfo - After that, you can delete .hg* (the example below uses "-X *.hg*" to exclude - those files and folders instead of deleting them - the end result is the same) - and continue with the normal compile instructions without the need for - mercurial. - - In short, once you cd into your clone of the RawTherapee source code - repository, using version "4.1" as an example: - 1. Check out the desired hg tag: hg update "4.1" - 2. Run tools/generateReleaseInfo to generate ReleaseInfo.cmake: - ./tools/generateReleaseInfo - 3. The repository is now ready to be made into a public tarball: - ./tools/generateSourceTarball - - The build system especially encourages to perform out-of-source builds. This - means that the CMake project is generated in a folder which is not in the - source tree of RawTherapee. This way the source tree stays clean all the time - and multiple different compilation settings can be maintained in parallel - using different binary folders. Further information about out-of-source builds - can be found here: - http://www.cmake.org/Wiki/CMake_FAQ#What_is_an_.22out-of-source.22_build.3F - - If an in-source build is performed, the CMake logic now warns about this but - does not fail. Especially important for clean out-of-source builds is that the - CMake code does not generate files inside the source tree, e.g. when using - configure_file. Please keep this in mind when altering the CMake files. - - -DEPENDENCIES ------------- - - PACKAGE URL - BZIP2 bzip2>-1.0.4 http://www.bzip.org/ - EXIV2 exiv2>=0.19 http://www.exiv2.org/ - EXPAT expat>=2.1.0 http://expat.sourceforge.net/ - FFTW fftw>=3.2.2 http://fftw.org/ - GCC gcc>=4.7 http://gcc.gnu.org/ - GLIB2 glib-2.0>=2.24 http://www.gtk.org/ - GLIBMM glibmm-2.4>=2.24 http://www.gtkmm.org - GTK+ gtk+-2.0>=2.24.18 http://www.gtk.org/ - GTK2-Engines gtk-engines-2.20.2 http://www.gtk.org/ - GTKMM gtkmm-2.4>=2.22 http://www.gtkmm.org - JPEG libjpeg>=6b http://libjpeg-turbo.virtualgl.org/ - http://jpegclub.org/ - http://www.ijg.org/ - LCMS2 lcms>=2.0a http://www.littlecms.com/ - LIBCANBERRA libcanberra-gtk http://0pointer.de/lennart/projects/libcanberra/ (Linux only) - LIBIPTCDATA libiptcdata>=1.0.2 http://libiptcdata.sourceforge.net - PNG libpng>=1.2.44 http://www.libpng.org/ - SIGC sigc++-2.0 http://libsigc.sourceforge.net/ - TIFF libtiff>=3.9.4 http://www.remotesensing.org/libtiff/ - ZLIB zlib>=1.2.3 http://www.zlib.net/ - - -WINDOWS -------- - - OPTIONAL - - - TortoiseHG - You can make your life a little easier by using a graphical client for - working with Mercurial. One such free and open-soure cross-platform - client is TortoiseHG, you can get it bundled with Mercurial from: - http://tortoisehg.bitbucket.org/ - - - Weird compressed archive formats? - You might need to unpack archives in formats which Windows does not - handle by default. That's no problem, there are a few free programs out - there which handle many more formats than Windows does, and faster too. - We recommend: - http://www.7-zip.org/ - http://peazip.sourceforge.net/ - - - THE TOOLCHAIN - - This document assumes that you install MinGW, CMake and gtkmm respectively - to "C:\MinGW64" (or "C:\MinGW32" for 32-bit), "C:\CMake", and "C:\gtkmm64" (or - "C:\gtkmm" for 32-bit). - These packages must be installed in paths that DO NOT CONTAIN SPACES. - - INSTALL THE TOOLCHAIN - - TDM-GCC On-Demand Installer - http://tdm-gcc.tdragon.net/download - GCC 4.9 is recommended for Win64 builds, as under some conditions older - versions of GCC can cause artifacts. - Download the "tdm-gcc-webdl" option. Run it, select "Create a new - TDM-GCC installation" and choose the appropriate option for your - machine: "MinGW/TDM (32-bit)" if you use a 32-bit machine, or - "MinGW-w64/TDM64 Experimental (32-bit and 64-bit)" if you use a 64-bit - machine. Even though the 64-bit version contains a 32-bit version too, - we had no luck making 32-bit RT builds using it at the time of writing. - Be sure to install with OpenMP support (Components > gcc > openmp). - - - CMake - http://www.cmake.org/cmake/resources/software.html - Use "Windows (Win32 Installer)", the newest version. - - - >=GTK+ 2.24.18 - http://hexchat.github.io/gtk-win32/ - - - gtkmm-2.24 - http://sourceforge.net/projects/gtk-mingw/files/gtkmm2/ - - - INSTALL THE DEPENDENCIES - - RawTherapee depends on additional build-time libraries. There are two ways - you can get these libraries: - - The easy way, you can use the pre-compiled ones available from: - http://www.rawtherapee.com/releases_head/windows/dependencies_for_creating_builds/ - Just unzip them to the base installation dir of MinGW, which should be - C:\MinGW64 if you followed the instructions to the letter. - - Note that this archive might not contain all of the required - libraries. If compilation fails due to missing libraries, then see the - dependency list at the beginning of this document, find the missing - ones, and see below for instructions on where to download them from - and how to install them. Please notify us so that we may update the - archive. - - - The hard way, you will need to download the source code for each and - compile each yourself. See further below for instructions. - - - SET UP THE TOOLCHAIN ENVIRONMENT VARIABLES - - The toolchain installers should have set up some environment variables - for you automatically, but some will be missing. Fire up: - System Properties > Advanced > Environment Variables - - Make sure you have the relevant ones, and that they point to the correct - places: - GTKMM_BASEPATH = "C:\gtkmm" - GTKMM64_BASEPATH = "C:\gtkmm64" - MINGW_BASEPATH = "C:\MinGW64" - PKG_CONFIG_PATH = "C:\MinGW64\lib\pkgconfig;c:\gtkmm64\lib\pkgconfig" - and that PATH contains "C:\gtkmm64\bin;C:\MinGW64\bin;C:\CMake\bin;" - (or the 32-bit counteparts) - - Restart your console to be sure the changes took effect. - - - COMPILE - - Clone or update the RawTherapee repository - You can use TortoiseHG to clone and update the repository, or you can - do it from the command line: - hg clone https://rawtherapee.googlecode.com/hg/ "C:\rtrepo" - If you have already cloned it before, update it: - cd C:\rtrepo - hg pull - hg update -C default - - - Tailor the buildRT.bat batch file to your needs - Copy C:\rtrepo\tools\buildRT.bat to C:\buildRT.bat so that you can make - changes to it and not lose them when you update the repository. - - Edit C:\buildRT.bat and customize as follows: - - If you are building RT for yourself, use - "-DPROC_TARGET_NUMBER:STRING=2" - - If you are building RT to be distributed to other people, use - "-DPROC_TARGET_NUMBER:STRING=1" - - If you want to upload a build, you should set some additional - information about your processor. There are two possibilities: - 1. You pick up a target processor from "ProcessorTargets.cmake". - All you have to do is set the PROC_TARGET_NUMBER parameter - to the desired target number. If you choose the "native" - solution, you have to set the processor label manually - by setting the PROC_LABEL parameter. Please provide a short name, - like "core i5" or "athlon64". Processor frequency is of no use. - 2. You don't need specific processor flags, so you'll let - PROC_TARGET_NUMBER default to 0, but you have to set the - PROC_LABEL parameter. Please provide a short name, like "core i5" - or "athlon64". Specifying the processor frequency is of no use. - - - Run buildRT.bat to compile RawTherapee - C:\buildRT.bat - - - DEPENDENCIES - THE HARD WAY - - The MSYS package is required to build the libraries. Before building them, - check if they are already installed in your gtkmm and MinGW directories. - There shouldn't be two versions of the same library in different places. - - Open an MSYS console, that will create a Linux environment, and compile - the dependencies in the following order: - zlib: - If you have gtkmm-2.22 installed, you should skip this zlib section. - - Download: http://zlib.net/ - - How to build: - cd to the directory you unpacked zlib-1.2.5 to, - make -f win32/Makefile.gcc - - Then, manually copy the files as follows (tip: you can individually - copy the lines below and paste them in MSYS' prompt with the middle - mouse button): - cp -iv zlib1.dll /mingw/bin - cp -iv zconf.h zlib.h /mingw/include - cp -iv libz.a /mingw/lib - cp -iv libzdll.a /mingw/lib/libz.dll.a - - libpng: - If you have gtkmm-2.22 installed, you should skip this libpng section. - - Download: http://sourceforge.net/projects/libpng/files/ - - How to build: - cd to the directory you unpacked lpng144 to. - There are two methods of building libpng: - 1. gtkmm doesn't provide zlib so compile it yourself: - cmake -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX:PATH=/mingw -DCMAKE_BUILD_TYPE:STRING=Release - 2. gtkmm provides zlib so you can reuse it (assuming that you - hadn't compiled zlib as explained above): - cmake -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX:PATH=/mingw -DCMAKE_PREFIX_PATH:PATH=C:/gtkmm -DCMAKE_BUILD_TYPE:STRING=Release - - Then build and install: - make - make install - - libjpeg: - - Download: http://www.ijg.org/ - - How to build: - cd to the directory you unpacked jpeg-8b to. - ./configure --prefix=/mingw - Copy jconfig.txt to jconfig.h (overwrite the existing file). - make - make install - - libtiff: - - Download: ftp://ftp.remotesensing.org/pub/libtiff/ - - How to build: - In the configure process below, set the zlib include and lib path to - the right folder. We're assuming that you're using the one provided - in the gtkmm bundle. - ./configure --prefix=/mingw --with-zlib-include-dir=/c/gtkmm/include --with-zlib-lib-dir=/c/gtkmm/lib - make - cd libtiff - make install - - libiptcdata: - - Download: http://libiptcdata.sourceforge.net/ - - How to build: - ./configure --prefix=/mingw - - Edit the "Makefile" file from the root dir of libiptcdata and - search for "DIST_SUBDIRS =" and "SUBDIRS =". You should only find - one line for each search. From these lines, remove "iptc", then: - make - make install - - LCMS: - - Download LCMS2 - http://sourceforge.net/projects/lcms/files/ - - How to build: - ./configure --prefix=/mingw - make - make install - - Expat: - - Download: http://expat.sourceforge.net/ - - Install - - FFTW: - - Instructions: http://www.fftw.org/install/windows.html - - Specific instructions more suitable for RawTherapee purposes: - 1. Download the official FFTW-64 DLL package from - http://www.fftw.org/download.html - Unpack it to C:\fftw3\ - 2. Start MSYS console and go to your FFTW3 directory - cd /c/fftw3 - 2. In MSYS console, execute: - dlltool --def libfftw3f-3.def --dllname libfftw3f-3.dll --output-lib libfftw3f-3.a - dlltool --def libfftw3l-3.def --dllname libfftw3l-3.dll --output-lib libfftw3l-3.a - dlltool --def libfftw3-3.def --dllname libfftw3-3.dll --output-lib libfftw3-3.a - 3. Copy files: - cp libfftw3f-3.dll /c/MinGW64/bin - cp libfftw3l-3.dll /c/MinGW64/bin - cp libfftw3-3.dll /c/MinGW64/bin - cp libfftw3f-3.a /c/MinGW64/lib - cp fftw3.h /c/MinGW64/include - 4. Create a new text file MinGW64/lib/pkgconfig/fftw3f.pc with the - following contents: - prefix=/mingw64 - exec_prefix=${prefix} - libdir=${exec_prefix}/lib - includedir=${prefix}/include - Name: fftw3f - Description: FFTW3 Float - Version: 3.3 - Libs: -L${libdir} -lfftw3f-3 -lm - Cflags: -I${includedir} - - - IMPORTANT - - Make sure that the lcms.pc and libiptcdata.pc files located in the - pkgconfig dir have the first line like this: - prefix=/mingw - - If everything has been installed correctly, you should see lines like - the following when running the cmake command (see "COMPILE" below): - -- checking for module 'libiptcdata' - -- found libiptcdata, version 1.0.4 - -- checking for module 'lcms2' - -- found lcms2, version 2.3 - -- Found JPEG: C:/mingw/lib/libjpeg.dll.a - -- Found ZLIB: C:/gtkmm/lib/libz.dll.a - -- Found PNG: C:/gtkmm/lib/libpng.lib - -- Found TIFF: C:/mingw/lib/libtiff.dll.a - - -LINUX ------ - - DEPENDENCIES - - See the list of dependencies at the beginning of this document. - - In Arch, run: - sudo pacman -S bzip2 exiv2 expat fftw glib2 glibmm gtk gtkmm lcms2 \ - libcanberra libiptcdata libjpeg-turbo libpng libsigc++ libtiff zlib - - In Fedora, run: - sudo yum install bzip2-devel cmake exiv2-devel expat-devel fftw-devel \ - gcc-c++ glib2-devel glibmm24-devel gtk+-devel gtk2-engines gtkmm24-devel \ - lcms2-devel libcanberra-devel libiptcdata-devel libjpeg-turbo-devel \ - libpng-devel libsigc++20-devel libtiff-devel zlib-devel - - In Gentoo, run: - sudo emerge -uva app-arch/bzip2 dev-cpp/glibmm dev-cpp/gtkmm \ - dev-libs/expat dev-libs/glib dev-libs/libsigc++ dev-vcs/mercurial \ - media-gfx/exiv2 media-libs/lcms media-libs/libcanberra \ - media-libs/libiptcdata media-libs/libjpeg-turbo media-libs/libpng \ - media-libs/tiff net-misc/curl sci-libs/fftw sys-libs/zlib x11-libs/gtk+ \ - x11-themes/gtk-engines - - In openSUSE, run: - sudo zypper in cmake fftw3-devel gcc-c++ glib2-devel glibmm2-devel \ - gtk2-devel gtkmm2-devel libbz2-devel libcanberra-devel libexpat-devel \ - libiptcdata-devel libjpeg-devel liblcms2-devel libpng-devel \ - libsigc++2-devel libtiff-devel zlib-devel - - In Ubuntu/Debian the requirements can be installed by running: - sudo apt-get update && sudo apt-get install build-essential cmake curl \ - libbz2-dev libcanberra-gtk-dev libexiv2-dev libexpat-dev libfftw3-dev \ - libglibmm-2.4-dev libgtk2.0-dev libgtkmm-2.4-dev libiptcdata0-dev \ - libjpeg8-dev liblcms2-dev libpng12-dev libsigc++-2.0-dev libtiff4-dev \ - mercurial zlib1g-dev - - - COMPILE - - The Automatic Way: - The easiest way compile RawTherapee is by using the buildRT script, read - all about it in the forum: - http://rawtherapee.com/forum/viewtopic.php?p=22213#p22213 - - The Manual Way: - - Create and enter a new empty folder outside RawTherapee's source - directory: - mkdir ~/rt-build - cd ~/rt-build - - Type: - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=./release \ - -DBINDIR=. -DDATADIR=. -DLIBDIR=. - Developers who want to provide a public build have to set the PROC_LABEL - to their processor name, e.g.: - cmake -DPROC_LABEL:STRING=athlon64 -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=./release -DBINDIR=. -DDATADIR=. -DLIBDIR=. \ - - - Type: - make install - - You'll find the compiled program in the subdirectory named like the - value of CMAKE_BUILD_TYPE ("Release" in this example). You can copy it - anywhere you want. By changing the cmake flags, you can change where - the release will compile to. By removing all flags it should go to the - standard system install location. - - You're done. - - - Using Eclipse under Linux: - - Eclipse mercurial plugin: Click "Help > Install New Software". - The Eclipse Update Site for MercurialEclipse is available at this URL: - http://cbes.javaforge.com/update - - Import the RawTherapee Mercurial repository: - "File > new > other > mercurial > Clone existing repository" - Enter this URL: - https://rawtherapee.googlecode.com/hg - - Create and enter a new empty folder outside RawTherapee's source directory. - Configure the source for Eclipse with: - cmake -G "Eclipse CDT4 - Unix Makefiles" -DCMAKE_INSTALL_PREFIX=./release -DBINDIR=. -DDATADIR=. -DLIBDIR=. -DCMAKE_BUILD_TYPE=Release - - If you want to upload a build, you should set some additional information - about your processor. There are two possibilities: - 1. You pick up a target processor from "ProcessorTargets.cmake". All you - have to do is set "-D PROC_TARGET_NUMBER:STRING=number" in cmake's - command line to the desired target number. If you choose the 'native' - solution, you have to set the processor label manually by setting "-D - PROC_LABEL:STRING=procLabel" in cmake's command line. Please provide a - short name, like "core i5" or "athlon64" (without double quotes). - Processor frequency is of no use. - 2. You don't need specific processor flags, so you'll let - PROC_TARGET_NUMBER default to 0, but you still have to set the - PROC_LABEL parameter (see point 1 righ above). - - Eclipse does not do 'make install', but only 'make all'. - There are two ways to compile: - 1. type 'make install' in the console or, - 2. in "Project > properties > C/C++ Make Project > Build (incremental - build)" change 'all' to 'install'. - -OS X ----- - - REQUIREMENTS - - - XCode Development Tools (you only need a subset of these, but it is - probably easier to just install all of them) - - MacPorts - - Add following line to /opt/local/etc/macports/variants.conf: - +no_gnome +no_x11 +quartz -x11 - - To install the dependencies, run: - sudo port install cairo pango gdk-pixbuf2 gtk2 libsigcxx2 gtk-osx-application-gtk2 gtkmm - - To install other dependencies and tools. - sudo port install gtk-engines2 lcms2 libiptcdata fftw-3-single cmake - - Install compiler, either - sudo port install gcc47 - or - Clang with OpenMP by follow instructions at https://clang-omp.github.io/ - - If you don't already have Git installed, run: - sudo port install git - - - COMPILE - - - Make build directory. - mkdir build - cd build - - To enable OpenMP, for gcc47, type: - cmake -D CMAKE_C_COMPILER=gcc-mp-4.7 -D CMAKE_CXX_COMPILER=g++-mp-4.7 \ - - - or if using Clang with OpenMP - cmake -v -D CMAKE_BUILD_TYPE=Release \ - -DPROC_TARGET_NUMBER="1" \ - -DBUILD_BUNDLE="ON" \ - -DBINDIR="." \ - -DDATADIR="." \ - -DCACHE_NAME_SUFFIX=4 \ - -DCMAKE_C_COMPILER="/tmp/clang/build_llvm/bin/clang" \ - -DCMAKE_CXX_COMPILER="/tmp/clang/build_llvm/bin/clang++" \ - -DCMAKE_C_FLAGS="-I/opt/local/include/libomp" \ - -DCMAKE_CXX_FLAGS="-I/opt/local/include/libomp" \ - - - If you want to upload a build, you should set some additional information - about your processor. There are two possibilities: - 1. You pick up a target processor from "ProcessorTargets.cmake". All you - have to do is set "-D PROC_TARGET_NUMBER:STRING=number" in cmake's - command line to the desired target number. If you choose the 'native' - solution, you have to set the processor label manually by setting "-D - PROC_LABEL:STRING=procLabel" in cmake's command line. Please provide a - short name, like "core i5" or "athlon64" (without double quotes). - Processor frequency is of no use. - 2. You don't need specific processor flags, so you'll let - PROC_TARGET_NUMBER default to 0, but you still have to set the - PROC_LABEL parameter (see point 1 righ above). - - - Type: - make -j4 install - - Type: - make macosx_bundle - - You will find a disk image in the build directory; this is the - distribution release and can be run on any machine which meets the - architecture requirements you specified in variants.conf earlier. From 46388488ca0db156dee68a58e38c6bbba6aa1ec6 Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Sat, 19 Dec 2015 18:32:58 +0100 Subject: [PATCH 35/61] Update README.md Removed brief compilation instructions as the RawPedia articles are now up to date and explain everything in relevant detail. --- README.md | 41 ++--------------------------------------- 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index f0b286ba3..5bc7650e2 100644 --- a/README.md +++ b/README.md @@ -23,42 +23,5 @@ http://git-scm.com/book/en/ ## Compilation, branches and Git Refer to RawPedia for a detailed explanation of how to get the necessary dependencies and how to compile RawTherapee: http://rawpedia.rawtherapee.com/Linux - -The information below is a brief summary of that. - -### Clone the source code -Clone the source code either using HTTPS: -``` -git clone https://github.com/Beep6581/RawTherapee ~/repo-rt -``` -or using SSH (see https://help.github.com/articles/generating-ssh-keys/ ): -``` -git clone git@github.com:Beep6581/RawTherapee.git ~/repo-rt -``` -or update a previously cloned repository: -``` -cd ~/repo-rt && git pull -``` - -### Optionally pick a branch -New features and bug fixes are made on their own branches. Once tested, those branches are merged into the "master" branch. We used to test new features and bug fixes by sharing patches (.diff files) but git makes branching easy and branching makes sharing patches unnecessary. -To test a new feature or bug fix, just checkout [the right branch](https://github.com/Beep6581/RawTherapee/branches/active) before compiling: -``` -git checkout -``` - -### Compile and run -To find out how many threads your CPU supports, run: -`grep -c processor /proc/cpuinfo` -Then replace the number in `-j8` below with this number. This will make compilation faster but it will have no effect on the speed of running RawTherapee. - -Now you will make an out-of-source compilation of RawTherapee, it will be built into the ~/repo-rt/build/release folder, and then you will move this folder to your home directory and rename it to "rt", so make sure there is no ~/rt folder already! -``` -mkdir build && cd build && \ -cmake -DCMAKE_CXX_FLAGS="-std=c++11" -DCMAKE_BUILD_TYPE="release" -DPROC_TARGET_NUMBER="2" -DBUILD_BUNDLE="ON" -DBINDIR="." -DDATADIR="." -DCACHE_NAME_SUFFIX=4 .. && \ -make -j8 install && \ -mv release ~/rt -``` - -Run RawTherapee: -`~/rt/rawtherapee` +http://rawpedia.rawtherapee.com/Windows +http://rawpedia.rawtherapee.com/OS_X From d90d803977327ac0e8b6b3df53afd642a6f05d32 Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Sat, 19 Dec 2015 18:35:08 +0100 Subject: [PATCH 36/61] Update README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5bc7650e2..baa566ca0 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,13 @@ Git handbook: http://git-scm.com/book/en/ ## Compilation, branches and Git -Refer to RawPedia for a detailed explanation of how to get the necessary dependencies and how to compile RawTherapee: +Refer to RawPedia for a detailed explanation of how to get the necessary dependencies and how to compile RawTherapee. + +Linux: http://rawpedia.rawtherapee.com/Linux + +Windows: http://rawpedia.rawtherapee.com/Windows + +OS X: http://rawpedia.rawtherapee.com/OS_X From 4d6533746e155e1834f59a65f4514f62659a3fd8 Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Sat, 19 Dec 2015 19:45:54 +0100 Subject: [PATCH 37/61] Delete WindowsEnvironmentSetup.html Made obsolete by http://rawpedia.rawtherapee.com/Windows --- WindowsEnvironmentSetup.html | 43 ------------------------------------ 1 file changed, 43 deletions(-) delete mode 100644 WindowsEnvironmentSetup.html diff --git a/WindowsEnvironmentSetup.html b/WindowsEnvironmentSetup.html deleted file mode 100644 index 113a8dc6a..000000000 --- a/WindowsEnvironmentSetup.html +++ /dev/null @@ -1,43 +0,0 @@ -

Building RawTherapee in Windows 64

-12 November 2011
-
-
-This short guide outlines setting up a development environment for building RawTherapee (64 bit) in Windows.
-Apology and warning: the procedure is convoluted. Prepare for frustration if you deviate even one bit. Sorry.
-
-Step 0:
-Use TortoiseHg to grab the latest RawTherapee, put it in a directory whose name doesn't contain spaces. This is more or less simple but well documented, please figure it out yourself.
-
-Step 1:
-Download the latest CMake. Install it into C:\CMake.
-
-Step 2:
-Download a rather specific version of gtkmm64. Install it into C:\gtkmm64.
-
-Step 3:
-Download a rather specific build of MinGW. When installing, uncheck "Check for updated files...", check "Experimental (32 and 64 bit)", check the "openmp" component under Components->gcc, install into C:\MinGW64.
-
-Step 4:
-Download the latest Precompiled package for 64bit Windows. Unzip the file contents (already organized into several subdirectories) into C:\MinGW64.
-
-Step 5:
-Download a rather specific build of MSYS. Install to C:\msys. At the end it asks for your MinGW directory, make sure you give it C:/MinGW64. That's a forward slash, and it matters.
-
-Step 6:
-Create a file named build.bat in your RawTherapee source directory with the following content:
-
-set GTKMM_BASEPATH=C:\gtkmm64
-set GTKMM64_BASEPATH=C:\gtkmm64
-set MINGW_BASEPATH=C:\MinGW64
-set PATH=%PATH%;C:\gtkmm64\bin;C:\MinGW64\bin;C:\CMake\bin
-set PKG_CONFIG_PATH=C:\MinGW64\lib\pkgconfig;c:\gtkmm64\lib\pkgconfig
-
-cmake -DCMAKE_BUILD_TYPE=Release -G "MinGW Makefiles" -DPROC_TARGET_NUMBER:STRING=2
-mingw32-make -j2 install
-pause
-
-
-
-Running the batch file above after completing all steps properly should slowly but flawlessly build RawTherapee.
-If it doesn't work, please tell us about it at the RawTherapee forum. Maybe this document needs updating.
-Do not rest until it builds. A complicated build sucks, but out of date or inaccurate build documentation is unacceptable.
From f63ebce657aa4fddd6e0dfea73c60925a98f3d23 Mon Sep 17 00:00:00 2001 From: Hombre Date: Sat, 19 Dec 2015 22:10:31 +0100 Subject: [PATCH 38/61] Updating the path of Inkscape/64 on Windows --- tools/source_icons/script/svg2png.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/source_icons/script/svg2png.bash b/tools/source_icons/script/svg2png.bash index 2e9c4bb5a..27642a52c 100755 --- a/tools/source_icons/script/svg2png.bash +++ b/tools/source_icons/script/svg2png.bash @@ -49,7 +49,7 @@ do echo "#! /bin/bash" > $DIR_TMP/$FILE_NAME.bash if [[ $OSTYPE == msys || $OSTYPE == MSYS ]]; then - awk -v s="$SVG" -v d="$DIR_OUT" -F, '{print "\"/c/Program Files (x86)/Inkscape/inkscape.exe\" " s " --export-png=" d "/" $1 " -" $2}' $DIR_IN/$FILE >> $DIR_TMP/$FILE_NAME.bash + awk -v s="$SVG" -v d="$DIR_OUT" -F, '{print "\"/c/Program Files/Inkscape/inkscape.exe\" " s " --export-png=" d "/" $1 " -" $2}' $DIR_IN/$FILE >> $DIR_TMP/$FILE_NAME.bash else awk -v s="$SVG" -v d="$DIR_OUT" -F, '{print "inkscape " s " --export-png=" d "/" $1 " -" $2}' $DIR_IN/$FILE >> $DIR_TMP/$FILE_NAME.bash fi From 7227ccc63c6446b00e65da049a57997a631c3e08 Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Sat, 19 Dec 2015 22:50:38 +0100 Subject: [PATCH 39/61] Fixes #3003 Detect pango-querymodules version from Homebrew on OS X --- rtdata/osx/macosx_bundle.sh | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/rtdata/osx/macosx_bundle.sh b/rtdata/osx/macosx_bundle.sh index 6667548c5..670343b08 100644 --- a/rtdata/osx/macosx_bundle.sh +++ b/rtdata/osx/macosx_bundle.sh @@ -41,6 +41,18 @@ if test ! -n "${MINIMUM_SYSTEM_VERSION}"; then MINIMUM_SYSTEM_VERSION=$(sw_vers -productVersion | cut -d. -f-2) fi +# check for pango-querymodules. Pango 1.38.0 and above do not include it. +# https://github.com/Homebrew/homebrew/issues/44764#issuecomment-146795820 +PangoVer="$(brew list --versions pango)" +PangoVer="${PangoVer//./}" +# Only check the first 4 digits, so that "1.36.99" (13699) doesn't test greater than "1.38.0" (1380) +PangoVer="${PangoVer:0:4}" +if [[ "$PangoVer" -ge "1380" ]]; then + ExistPangoQuerymodules="false" +else + ExistPangoQuerymodules="true" +fi + case ${PROC_BIT_DEPTH} in 64) arch=x86_64;; 32) arch=i386;; @@ -93,13 +105,13 @@ install -d "${ETC}"/{gtk-2.0,pango} cp "${GTK_PREFIX}"/etc/gtk-2.0/im-multipress.conf "${ETC}"/gtk-2.0 "${GTK_PREFIX}"/bin/gdk-pixbuf-query-loaders "${LIB}"/gdk-pixbuf-2.0/*/loaders/*.so > "${ETC}"/gtk-2.0/gdk-pixbuf.loaders "${GTK_PREFIX}"/bin/gtk-query-immodules-2.0 "${LIB}"/gtk-2.0/*/immodules/*.so > "${ETC}"/gtk-2.0/gtk.immodules -"${GTK_PREFIX}"/bin/pango-querymodules "${LIB}"/pango/*/modules/*.so > "${ETC}"/pango/pango.modules sed -i "" -e "s|${PWD}|/tmp|" "${ETC}"/gtk-2.0/gdk-pixbuf.loaders \ - "${ETC}"/gtk-2.0/gtk.immodules \ - "${ETC}"/pango/pango.modules -printf "[Pango]\nModuleFiles = /tmp/${ETC}/pango/pango.modules" > "${ETC}"/pango/pangorc - - + "${ETC}"/gtk-2.0/gtk.immodules +if [[ "$ExistPangoQuerymodules" = "true" ]]; then + "${GTK_PREFIX}"/bin/pango-querymodules "${LIB}"/pango/*/modules/*.so > "${ETC}"/pango/pango.modules + sed -i "" -e "s|${PWD}|/tmp|" "${ETC}"/pango/pango.modules + printf "[Pango]\nModuleFiles = /tmp/${ETC}/pango/pango.modules" > "${ETC}"/pango/pangorc +fi message "Copying shared files from ${GTK_PREFIX}" cp -R "${GTK_PREFIX}"/share/mime "${MACOS}"/share From 13e7260a237333687a25a1bff105c7c41c103379 Mon Sep 17 00:00:00 2001 From: Harshula Jayasuriya Date: Sun, 20 Dec 2015 13:26:27 +0100 Subject: [PATCH 40/61] Close #2964: Fix Segmentation fault in rtengine::processImage due to crop When a pp3 contains negative values for X & Y in the Crop section these get parsed into array indexing code without being checked and set to 0. This results in a segmentation fault because the code tries to index the '-1' element of the array. --- rtengine/simpleprocess.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 665a3a236..da44b25e3 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -77,6 +77,14 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p params.crop.w = fw; params.crop.h = fh; } else { + if (params.crop.x < 0) { + params.crop.x = 0; + } + + if (params.crop.y < 0) { + params.crop.y = 0; + } + if ((params.crop.x + params.crop.w) > fw) { // crop overflow in the width dimension ; we trim it params.crop.w = fw - params.crop.x; From 151556ae23b0ec883a098c739c18092aac69bb4f Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sun, 20 Dec 2015 15:56:12 +0100 Subject: [PATCH 41/61] Add an optional function to the pop-up button, so that it will select the next entry when clicked and also do some miscellaneous code clean-ups including forward declarations. --- rtgui/colortoning.cc | 1 + rtgui/diagonalcurveeditorsubgroup.cc | 1 + rtgui/editorpanel.cc | 3 +- rtgui/flatcurveeditorsubgroup.cc | 1 + rtgui/popupbutton.cc | 29 ++++++- rtgui/popupbutton.h | 11 ++- rtgui/popupcommon.cc | 119 +++++++++++---------------- rtgui/popupcommon.h | 49 +++++++---- rtgui/popuptogglebutton.h | 2 +- rtgui/retinex.cc | 1 + rtgui/wavelet.cc | 1 + 11 files changed, 127 insertions(+), 91 deletions(-) diff --git a/rtgui/colortoning.cc b/rtgui/colortoning.cc index 38cf88230..99ad03e9f 100644 --- a/rtgui/colortoning.cc +++ b/rtgui/colortoning.cc @@ -3,6 +3,7 @@ */ #include "colortoning.h" #include "mycurve.h" +#include "rtimage.h" using namespace rtengine; using namespace rtengine::procparams; diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc index ad896789f..4ca2bb159 100644 --- a/rtgui/diagonalcurveeditorsubgroup.cc +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -30,6 +30,7 @@ #include "mydiagonalcurve.h" #include "curveeditor.h" #include "diagonalcurveeditorsubgroup.h" +#include "rtimage.h" DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, Glib::ustring& curveDir) : CurveEditorSubGroup(curveDir) { diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 74fa2f937..621c088e3 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -29,6 +29,7 @@ #include "soundman.h" #include "rtimage.h" #include +#include "popupbutton.h" using namespace rtengine::procparams; @@ -76,7 +77,7 @@ private: void prepareIntentBox () { - PopUpButton *bt = new PopUpButton(); + PopUpButton *bt = new PopUpButton(Glib::ustring(), true); intentBox = Gtk::manage(bt); intentBox->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); intentBox->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); diff --git a/rtgui/flatcurveeditorsubgroup.cc b/rtgui/flatcurveeditorsubgroup.cc index 516bed44a..691fbe3dd 100644 --- a/rtgui/flatcurveeditorsubgroup.cc +++ b/rtgui/flatcurveeditorsubgroup.cc @@ -31,6 +31,7 @@ #include "myflatcurve.h" #include "curveeditor.h" #include "flatcurveeditorsubgroup.h" +#include "rtimage.h" FlatCurveEditorSubGroup::FlatCurveEditorSubGroup (CurveEditorGroup* prt, Glib::ustring& curveDir) : CurveEditorSubGroup(curveDir) { diff --git a/rtgui/popupbutton.cc b/rtgui/popupbutton.cc index e0cca8bd0..554f41cc6 100644 --- a/rtgui/popupbutton.cc +++ b/rtgui/popupbutton.cc @@ -21,6 +21,8 @@ #include "popupbutton.h" +#include + /* * PopUpButton::PopUpButton (const Glib::ustring& label, bool imgRight) * @@ -28,8 +30,14 @@ * * Parameters: * label = label displayed in the button + * nextOnClicked = selects the next entry if the button is clicked */ -PopUpButton::PopUpButton (const Glib::ustring& label) : Gtk::Button(), PopUpCommon(this, label) { } +PopUpButton::PopUpButton (const Glib::ustring& label, bool nextOnClicked) + : Gtk::Button () + , PopUpCommon (this, label) + , nextOnClicked(nextOnClicked) +{ +} void PopUpButton::show() { @@ -44,3 +52,22 @@ void PopUpButton::set_sensitive (bool isSensitive) { buttonGroup->set_sensitive(isSensitive); } + +bool PopUpButton::on_button_release_event (GdkEventButton* event) +{ + if (nextOnClicked && getEntryCount () > 1) + { + const int last = getEntryCount () - 1; + int next = getSelected (); + + if (event->state & GDK_SHIFT_MASK) { + next = next > 0 ? next - 1 : last; + } else { + next = next < last ? next + 1 : 0; + } + + entrySelected (next); + } + + return Gtk::Button::on_button_release_event(event); +} diff --git a/rtgui/popupbutton.h b/rtgui/popupbutton.h index dec848b14..245d29aee 100644 --- a/rtgui/popupbutton.h +++ b/rtgui/popupbutton.h @@ -21,17 +21,24 @@ #ifndef _POPUPBUTTON_ #define _POPUPBUTTON_ -#include +#include #include "popupcommon.h" class PopUpButton : public Gtk::Button, public PopUpCommon { public: - PopUpButton (const Glib::ustring& label = ""); + PopUpButton (const Glib::ustring& label = Glib::ustring (), bool nextOnClicked = false); void show (); void set_tooltip_text (const Glib::ustring &text); void set_sensitive (bool isSensitive=true); + +protected: + bool on_button_release_event (GdkEventButton* event); + +private: + bool nextOnClicked; + }; #endif diff --git a/rtgui/popupcommon.cc b/rtgui/popupcommon.cc index 2a1387d3f..8acbd2802 100644 --- a/rtgui/popupcommon.cc +++ b/rtgui/popupcommon.cc @@ -26,6 +26,9 @@ #include "rtimage.h" PopUpCommon::PopUpCommon (Gtk::Button* thisButton, const Glib::ustring& label) + : selected (-1) // -1 means that the button is invalid + , menu (0) + , buttonImage (0) { button = thisButton; hasMenu = false; @@ -42,15 +45,6 @@ PopUpCommon::PopUpCommon (Gtk::Button* thisButton, const Glib::ustring& label) // Create the global container and put the button in it buttonGroup = Gtk::manage( new Gtk::HBox(false, 0)); buttonGroup->pack_start(*button, Gtk::PACK_EXPAND_WIDGET, 0); - // Create the list entry - imageFilenames.clear(); - images.clear(); - sItems.clear(); - items.clear(); - selected = -1; // -1 : means that the button is invalid - menu = 0; - buttonImage = 0; - buttonHint = ""; } PopUpCommon::~PopUpCommon () @@ -59,81 +53,59 @@ PopUpCommon::~PopUpCommon () delete *i; } - for (std::vector::iterator i = items.begin(); i != items.end(); ++i) { - delete *i; - } - - if (menu) { - delete menu; - } - - if (buttonImage) { - delete buttonImage; - } - + delete menu; + delete buttonImage; delete buttonGroup; } -PopUpCommon::type_signal_changed PopUpCommon::signal_changed() +bool PopUpCommon::addEntry (const Glib::ustring& fileName, const Glib::ustring& label) { - return message; -} + if (label.empty ()) + return false; -bool PopUpCommon::addEntry (Glib::ustring fileName, Glib::ustring label) -{ - bool added = false; + // Create the image + RTImage* newImage = new RTImage(fileName); + images.push_back(newImage); + imageFilenames.push_back(fileName); + int currPos = (int)images.size(); + // Create the menu item + Gtk::ImageMenuItem* newItem = Gtk::manage(new Gtk::ImageMenuItem (*newImage, label)); - if ( label.size() ) { - imageFilenames.push_back(fileName); - sItems.push_back(label); - // Create the image - RTImage* newImage = new RTImage(fileName); - images.push_back(newImage); - int currPos = (int)images.size(); - // Create the menu item - Gtk::ImageMenuItem* newItem = new Gtk::ImageMenuItem (*newImage, label); - items.push_back(newItem); - - if (selected == -1) { - // Create the menu on the first item - menu = new Gtk::Menu (); - // Create the image for the button - buttonImage = new RTImage(fileName); - // Use the first image by default - imageContainer->pack_start(*buttonImage, Gtk::PACK_EXPAND_WIDGET); - selected = 0; - } - - // When there is at least 1 choice, we add the arrow button - if (images.size() == 1) { - Gtk::Button* arrowButton = Gtk::manage( new Gtk::Button() ); - RTImage* arrowImage = Gtk::manage( new RTImage("popuparrow.png") ); - arrowButton->add(*arrowImage); //menuSymbol); - arrowButton->set_relief (Gtk::RELIEF_NONE); - arrowButton->set_border_width (0); - buttonGroup->pack_start(*arrowButton, Gtk::PACK_SHRINK, 0); - arrowButton->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &PopUpCommon::showMenu) ); - hasMenu = true; - } - - newItem->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &PopUpCommon::entrySelected), currPos - 1)); - menu->attach (*newItem, 0, 1, currPos - 1, currPos); - // The item has been created - added = true; + if (selected == -1) { + // Create the menu on the first item + menu = new Gtk::Menu (); + // Create the image for the button + buttonImage = new RTImage(fileName); + // Use the first image by default + imageContainer->pack_start(*buttonImage, Gtk::PACK_EXPAND_WIDGET); + selected = 0; } - return added; + // When there is at least 1 choice, we add the arrow button + if (images.size() == 1) { + Gtk::Button* arrowButton = Gtk::manage( new Gtk::Button() ); + RTImage* arrowImage = Gtk::manage( new RTImage("popuparrow.png") ); + arrowButton->add(*arrowImage); //menuSymbol); + arrowButton->set_relief (Gtk::RELIEF_NONE); + arrowButton->set_border_width (0); + buttonGroup->pack_start(*arrowButton, Gtk::PACK_SHRINK, 0); + arrowButton->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &PopUpCommon::showMenu) ); + hasMenu = true; + } + + newItem->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &PopUpCommon::entrySelected), currPos - 1)); + menu->attach (*newItem, 0, 1, currPos - 1, currPos); + + return true; } // TODO: 'PopUpCommon::removeEntry' method to be created... void PopUpCommon::entrySelected (int i) { - if (setSelected((unsigned int)i)) - // Emit a a signal if the selected item has changed - { - message.emit(selected); - } + // Emit a a signal if the selected item has changed + if (setSelected (i)) + message (selected); } void PopUpCommon::setItemSensitivity (int i, bool isSensitive) { @@ -181,7 +153,12 @@ void PopUpCommon::setButtonHint() } if (selected > -1) { - hint += sItems.at(selected); + // HACK: Gtk::MenuItem::get_label does not seem to work reliably. + Gtk::MenuItem& item = menu->items ()[selected]; + Gtk::Label* label = dynamic_cast(item.get_child ()); + + if (label) + hint += label->get_text (); } button->set_tooltip_markup(hint); diff --git a/rtgui/popupcommon.h b/rtgui/popupcommon.h index 7b05a08e9..04044fb2d 100644 --- a/rtgui/popupcommon.h +++ b/rtgui/popupcommon.h @@ -21,11 +21,21 @@ #ifndef _POPUPCOMMON_ #define _POPUPCOMMON_ +#include +#include +#include -#include -#include -#include "rtimage.h" +namespace Gtk +{ +class HBox; +class Menu; +class Button; +class ImageMenuItem; +} +typedef struct _GdkEventButton GdkEventButton; + +class RTImage; class PopUpCommon { @@ -37,12 +47,10 @@ public: PopUpCommon (Gtk::Button* button, const Glib::ustring& label = ""); virtual ~PopUpCommon (); - bool addEntry (Glib::ustring fileName, Glib::ustring label); + bool addEntry (const Glib::ustring& fileName, const Glib::ustring& label); + int getEntryCount () const; bool setSelected (int entryNum); - int getSelected () - { - return selected; - } + int getSelected () const; void setButtonHint(); void show (); void set_tooltip_text (const Glib::ustring &text); @@ -50,14 +58,8 @@ public: private: type_signal_changed message; - /* - TODO: MenuItem::get_label() doesn't return any string, or an empty string !? - That's why we store entries strings in sItems, but it would be nice to get ride of it... - */ - std::vector sItems; std::vector imageFilenames; std::vector images; - std::vector items; Glib::ustring buttonHint; RTImage* buttonImage; Gtk::HBox* imageContainer; @@ -67,9 +69,26 @@ private: bool hasMenu; void showMenu(GdkEventButton* event); - void entrySelected (int i); void setItemSensitivity (int i, bool isSensitive); +protected: + void entrySelected (int i); + }; +inline PopUpCommon::type_signal_changed PopUpCommon::signal_changed () +{ + return message; +} + +inline int PopUpCommon::getEntryCount () const +{ + return images.size(); +} + +inline int PopUpCommon::getSelected () const +{ + return selected; +} + #endif diff --git a/rtgui/popuptogglebutton.h b/rtgui/popuptogglebutton.h index 58342e66c..930fae4f2 100644 --- a/rtgui/popuptogglebutton.h +++ b/rtgui/popuptogglebutton.h @@ -21,7 +21,7 @@ #ifndef _POPUPTOGGLEBUTTON_ #define _POPUPTOGGLEBUTTON_ -#include "popupbutton.h" +#include #include "popupcommon.h" class PopUpToggleButton : public Gtk::ToggleButton, public PopUpCommon diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index b964ecbb5..43cbe4f28 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -3,6 +3,7 @@ */ #include "retinex.h" #include "mycurve.h" +#include "rtimage.h" using namespace rtengine; using namespace rtengine::procparams; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 4bebb10ad..abab1d2d1 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -21,6 +21,7 @@ #include #include "edit.h" #include "guiutils.h" +#include "rtimage.h" using namespace rtengine; using namespace rtengine::procparams; From 9cf3fac41428b10378b4bb425e7ecdb5ac116844 Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Mon, 21 Dec 2015 22:55:07 +0100 Subject: [PATCH 42/61] Deutsch interface translation updated by TooWaBoo, closes #3020 --- rtdata/languages/Deutsch | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index ee4033541..9dda4d684 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -23,6 +23,7 @@ #23 2015-10-24 Retinexübersetzung und Korrekturen (TooWaBoo) #24 2015-11-01 Korrekturen (TooWaBoo) RT4.2.450 #25 2015-11-30 Korrekturen (TooWaBoo) RT4.2.507 +#26 2015-12-13 Korrekturen (TooWaBoo) RT4.2.514 ABOUT_TAB_BUILD;Version ABOUT_TAB_CREDITS;Danksagungen @@ -290,9 +291,9 @@ HISTORY_MSG_34;Objektivkorrektur\nProfil - Verzeichnung HISTORY_MSG_35;Objektivkorrektur\nProfil - Vignettierung HISTORY_MSG_36;Objektivkorrektur\nProfil - CA-Korrektur HISTORY_MSG_37;Belichtung - Auto -HISTORY_MSG_38;Weißabgleich\nMethode +HISTORY_MSG_38;Weißabgleich - Methode HISTORY_MSG_39;Weißabgleich\nFarbtemperatur -HISTORY_MSG_40;Weißabgleich\nTönung +HISTORY_MSG_40;Weißabgleich - Tönung HISTORY_MSG_41;Belichtung\nTonwertkurve 1 - Modus HISTORY_MSG_42;Belichtung\nTonwertkurve 2 HISTORY_MSG_43;Belichtung\nTonwertkurve 2 - Modus @@ -377,7 +378,7 @@ HISTORY_MSG_121;Sensor Bayer-Matrix\nChromatische Aberration\nAutomatisch HISTORY_MSG_122;Dunkelbild\nAutomatische Auswahl HISTORY_MSG_123;Dunkelbild - Datei HISTORY_MSG_124;Weißpunkt\nKorrekturfaktor -HISTORY_MSG_125;Belichtungskorrektur\nLichter schützen +HISTORY_MSG_125;Belichtungskorrektur\nLichter schützen HISTORY_MSG_126;Weißbild - Datei HISTORY_MSG_127;Weißbild\nAutomatische Auswahl HISTORY_MSG_128;Weißbild\nUnschärferadius @@ -460,7 +461,7 @@ HISTORY_MSG_204;Sensor Bayer-Matrix\nFarbinterpolation\nLMMSE-Verbesserun HISTORY_MSG_205;CIECAM02\nBetrachtungsbed.\nHot/Bad-Pixelfilter HISTORY_MSG_206;CIECAM02 - Szene\nAuto-Leuchtstärke HISTORY_MSG_207;Farbsaum entfernen\nFarbtonkurve -HISTORY_MSG_208;Weißabgleich\nBau/Rot-Korrektur +HISTORY_MSG_208;Weißabgleich\nBlau/Rot-Korrektur HISTORY_MSG_210;Grauverlaufsfilter\nRotationswinkel HISTORY_MSG_211;Grauverlaufsfilter HISTORY_MSG_212;Vignettierungsfilter\nIntensität @@ -520,9 +521,9 @@ HISTORY_MSG_265;Farbanpassungen\nSchatten - Gelb/Blau HISTORY_MSG_266;Farbanpassungen\nMitten - Blau/Rot HISTORY_MSG_267;Farbanpassungen\nMitten - Cyan/Grün HISTORY_MSG_268;Farbanpassungen\nMitten - Gelb/Blau -HISTORY_MSG_269;Farbanpassungen\nLichter - Bau/Rot +HISTORY_MSG_269;Farbanpassungen\nLichter - Blau/Rot HISTORY_MSG_270;Farbanpassungen\nLichter - Cyan/Grün -HISTORY_MSG_271;Farbanpassungen\nLichter - GelbBlau +HISTORY_MSG_271;Farbanpassungen\nLichter - Gelb/Blau HISTORY_MSG_272;Farbanpassungen\nFarbausgleich HISTORY_MSG_273;Farbanpassungen\nZurücksetzen HISTORY_MSG_274;Farbanpassungen\nSättigung Schatten @@ -807,7 +808,7 @@ NAVIGATOR_S;S: NAVIGATOR_V;V: NAVIGATOR_XY_FULL;Breite = %1, Höhe = %2 NAVIGATOR_XY_NA;x: --, y: -- -OPTIONS_DEFIMG_MISSING;Die Standard-Profile für nicht-RAW-Bilder wurden nicht gefunden oder nicht festgelegt.\n\nBitte prüfen Sie das Profil-Verzeichnis, es fehlt möglicherweise oder ist beschädigt.\n\nEs werden stattdessen interne Standardwerte verwendet. +OPTIONS_DEFIMG_MISSING;Die Standard-Profile für Nicht-RAW-Bilder wurden nicht gefunden oder nicht festgelegt.\n\nBitte prüfen Sie das Profil-Verzeichnis, es fehlt möglicherweise oder ist beschädigt.\n\nEs werden stattdessen interne Standardwerte verwendet. OPTIONS_DEFRAW_MISSING;Die Standard-Profile für RAW-Bilder wurden nicht gefunden oder nicht festgelegt.\n\nBitte prüfen Sie das Profil-Verzeichnis, es fehlt möglicherweise oder ist beschädigt.\n\nEs werden stattdessen interne Standardwerte verwendet. PARTIALPASTE_BASICGROUP;Gruppe Basiseinstellungen PARTIALPASTE_CACORRECTION;Farbsaum entfernen @@ -1295,7 +1296,7 @@ TP_COLORTONING_BALANCE;Farbausgleich TP_COLORTONING_BY;o C/L TP_COLORTONING_CHROMAC;Deckkraft TP_COLORTONING_COLOR;Farbe -TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Buntheitdeckkraft als Funktion der Luminanz oB=f(L) +TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Buntheitsdeckkraft als Funktion der Luminanz oB=f(L) TP_COLORTONING_HIGHLIGHT;Lichter TP_COLORTONING_HUE;Farbton TP_COLORTONING_LAB;L*a*b*-Überlagerung @@ -1323,7 +1324,7 @@ TP_COLORTONING_STRENGTH;Intensität TP_COLORTONING_TWO2;Spezial-Farbe (2 Farben) TP_COLORTONING_TWOALL;Spezial-Farbe TP_COLORTONING_TWOBY;Spezial a* und b* -TP_COLORTONING_TWOCOLOR_TOOLTIP;Standardfarbe:\nLinearer Verlauf, a* = b*.\n\nSpezial-Farbe:\nLinearer Verlauf, a* = b*, aber nicht verbunden\n\nSpezial a* and b*:\nLinearer Verlauf, nicht verbunden, mit unterschiedlichen Kurven für a* and b*. Bevorzugt für spezielle Effekte.\n\nSpezial-Farbe (2 Farben):\nBesser vorhersehbar +TP_COLORTONING_TWOCOLOR_TOOLTIP;Standardfarbe:\nLinearer Verlauf, a* = b*.\n\nSpezial-Farbe:\nLinearer Verlauf, a* = b*, aber nicht verbunden\n\nSpezial a* und b*:\nLinearer Verlauf, nicht verbunden, mit unterschiedlichen Kurven für a* und b*. Bevorzugt für spezielle Effekte.\n\nSpezial-Farbe (2 Farben):\nBesser vorhersehbar TP_COLORTONING_TWOSTD;Standardfarbe TP_CROP_FIXRATIO;Festes\nVerhältnis: TP_CROP_GTDIAGONALS;Diagonalregel @@ -1660,10 +1661,10 @@ TP_RETINEX_CONTEDIT_LH;Farbton (H) TP_RETINEX_CURVEEDITOR_CD;L=f(L) TP_RETINEX_CURVEEDITOR_CD_TOOLTIP;Luminanz in Abhängigkeit der Luminanz.\nKorrigiert direkt die RAW-Daten, um Halos und Artefakte zu verringern. TP_RETINEX_CURVEEDITOR_LH;Intensität=f(H) -TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Intensität in Abhängikeit des Farbtons (H)\nBei der Retinex-Methode "Spitzlichter" wirken sich die Änderungen auch auf die Chromakorrektur aus. +TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Intensität in Abhängigkeit des Farbtons (H)\nBei der Retinex-Methode "Spitzlichter" wirken sich die Änderungen auch auf die Chromakorrektur aus. TP_RETINEX_FREEGAMMA;Gamma TP_RETINEX_GAIN;Verstärkung -TP_RETINEX_GAIN_TOOLTIP;Wirkt sich auf das verarbeitete Bild aus. Wird für schwarze oder weiße Pixel verwendet und hilft das Histogram auszugleichen. +TP_RETINEX_GAIN_TOOLTIP;Wirkt sich auf das verarbeitete Bild aus. Wird für schwarze oder weiße Pixel verwendet und hilft das Histogramm auszugleichen. TP_RETINEX_GAMMA;Gammakorrektur TP_RETINEX_GAMMA_FREE;Benutzerdefiniert TP_RETINEX_GAMMA_HIGH;Hoch @@ -1986,3 +1987,10 @@ ZOOMPANEL_ZOOMFITSCREEN;An Bildschirm anpassen\nTaste: f ZOOMPANEL_ZOOMIN;Hineinzoomen\nTaste: + ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: - +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. From de42472225a0141ddc823f7c90c4ff177cbe8d15 Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Mon, 21 Dec 2015 22:55:33 +0100 Subject: [PATCH 43/61] Updated all interface translations --- rtdata/languages/Catala | 3 +++ rtdata/languages/Chinese (Simplified) | 3 +++ rtdata/languages/Chinese (Traditional) | 3 +++ rtdata/languages/Czech | 3 +++ rtdata/languages/Dansk | 3 +++ rtdata/languages/English (UK) | 3 +++ rtdata/languages/English (US) | 3 +++ rtdata/languages/Espanol | 3 +++ rtdata/languages/Euskara | 3 +++ rtdata/languages/Francais | 3 +++ rtdata/languages/Greek | 3 +++ rtdata/languages/Hebrew | 3 +++ rtdata/languages/Italiano | 3 +++ rtdata/languages/Japanese | 3 +++ rtdata/languages/Latvian | 3 +++ rtdata/languages/Magyar | 3 +++ rtdata/languages/Nederlands | 3 +++ rtdata/languages/Norsk BM | 3 +++ rtdata/languages/Polish | 3 +++ rtdata/languages/Polish (Latin Characters) | 3 +++ rtdata/languages/Portugues (Brasil) | 3 +++ rtdata/languages/Russian | 3 +++ rtdata/languages/Serbian (Cyrilic Characters) | 3 +++ rtdata/languages/Serbian (Latin Characters) | 3 +++ rtdata/languages/Slovak | 3 +++ rtdata/languages/Suomi | 3 +++ rtdata/languages/Swedish | 3 +++ rtdata/languages/Turkish | 3 +++ rtdata/languages/default | 4 ++-- 29 files changed, 86 insertions(+), 2 deletions(-) diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala index 269e122d4..ba8e339ad 100644 --- a/rtdata/languages/Catala +++ b/rtdata/languages/Catala @@ -1025,6 +1025,7 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !FILEBROWSER_RANK4_TOOLTIP;Rank 4 *\nShortcut: Shift-4 !FILEBROWSER_RANK5_TOOLTIP;Rank 5 *\nShortcut: Shift-5 !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_UNRANK_TOOLTIP;Unrank.\nShortcut: Shift-0 !FILECHOOSER_FILTER_ANY;All files !FILECHOOSER_FILTER_COLPROF;Color profiles @@ -1392,6 +1393,8 @@ ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - !PREFERENCES_NAVIGATIONFRAME;Navigation !PREFERENCES_NOISE;Noise Reduction !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) index b1a8ff415..de7c3afcb 100644 --- a/rtdata/languages/Chinese (Simplified) +++ b/rtdata/languages/Chinese (Simplified) @@ -883,6 +883,7 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 !FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 !FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 !FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives. @@ -1344,6 +1345,8 @@ ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel !PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files !PREFERENCES_PANFACTORLABEL;Pan rate amplification +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Chinese (Traditional) b/rtdata/languages/Chinese (Traditional) index 63cb46885..885a79980 100644 --- a/rtdata/languages/Chinese (Traditional) +++ b/rtdata/languages/Chinese (Traditional) @@ -577,6 +577,7 @@ TP_WBALANCE_TEMPERATURE;色溫 !FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 !FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 !FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 !FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 @@ -1151,6 +1152,8 @@ TP_WBALANCE_TEMPERATURE;色溫 !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel !PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files !PREFERENCES_PANFACTORLABEL;Pan rate amplification +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech index b6d64cc45..bac9323ff 100644 --- a/rtdata/languages/Czech +++ b/rtdata/languages/Czech @@ -1998,6 +1998,9 @@ ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !HISTORY_MSG_166;Exposure - Reset !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !TP_NEUTRAL;Reset diff --git a/rtdata/languages/Dansk b/rtdata/languages/Dansk index 39a4f23ee..9cc3fc7d3 100644 --- a/rtdata/languages/Dansk +++ b/rtdata/languages/Dansk @@ -569,6 +569,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 !FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 !FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 !FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 @@ -1149,6 +1150,8 @@ TP_WBALANCE_TEMPERATURE;Temperatur !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel !PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files !PREFERENCES_PANFACTORLABEL;Pan rate amplification +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) index f0cdc3390..7ad989e24 100644 --- a/rtdata/languages/English (UK) +++ b/rtdata/languages/English (UK) @@ -271,6 +271,7 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 !FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1-star.\nShortcut: 1 !FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2-star.\nShortcut: 2 !FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3-star.\nShortcut: 3 @@ -1062,6 +1063,8 @@ TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "wh !PREFERENCES_PARSEDEXTADD;Add extension !PREFERENCES_PARSEDEXTADDHINT;Add entered extension to the list. !PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list. +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) index 82087395d..5933990ba 100644 --- a/rtdata/languages/English (US) +++ b/rtdata/languages/English (US) @@ -172,6 +172,7 @@ !FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 !FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1-star.\nShortcut: 1 !FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2-star.\nShortcut: 2 !FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3-star.\nShortcut: 3 @@ -1001,6 +1002,8 @@ !PREFERENCES_PARSEDEXTADD;Add extension !PREFERENCES_PARSEDEXTADDHINT;Add entered extension to the list. !PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list. +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Espanol b/rtdata/languages/Espanol index 1aaad0523..1ed7ab26b 100644 --- a/rtdata/languages/Espanol +++ b/rtdata/languages/Espanol @@ -1556,6 +1556,7 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !FILEBROWSER_POPUPCOLORLABEL0;Label: None !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILECHOOSER_FILTER_ANY;All files !FILECHOOSER_FILTER_COLPROF;Color profiles !FILECHOOSER_FILTER_CURVE;Curve files @@ -1745,6 +1746,8 @@ ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - !PREFERENCES_NAVIGATIONFRAME;Navigation !PREFERENCES_NOISE;Noise Reduction !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Euskara b/rtdata/languages/Euskara index 6462a5d36..68243898d 100644 --- a/rtdata/languages/Euskara +++ b/rtdata/languages/Euskara @@ -569,6 +569,7 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 !FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 !FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 !FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 @@ -1149,6 +1150,8 @@ TP_WBALANCE_TEMPERATURE;Tenperatura !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel !PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files !PREFERENCES_PANFACTORLABEL;Pan rate amplification +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index 9c57dd7d4..7da48754f 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -1891,6 +1891,7 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !HISTORY_MSG_166;Exposure - Reset !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Neighboring @@ -1914,6 +1915,8 @@ ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - !HISTORY_MSG_426;Retinex - Hue equalizer !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor !PARTIALPASTE_RETINEX;Retinex +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_TUNNELMETADATA;Copy Exif/IPTC/XMP unchanged to output file !SAVEDLG_SUBSAMP_TOOLTIP;Best compression:\nJ:a:b 4:2:0\nh/v 2/2\nChroma halved horizontally and vertically.\n\nBalanced:\nJ:a:b 4:2:2\nh/v 2/1\nChroma halved horizontally.\n\nBest quality:\nJ:a:b 4:4:4\nh/v 1/1\nNo chroma subsampling. !TP_COLORTONING_NEUTRAL;Reset sliders diff --git a/rtdata/languages/Greek b/rtdata/languages/Greek index 9de561b7e..2ea0c9324 100644 --- a/rtdata/languages/Greek +++ b/rtdata/languages/Greek @@ -568,6 +568,7 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 !FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 !FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 !FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 @@ -1148,6 +1149,8 @@ TP_WBALANCE_TEMPERATURE;Θερμοκρασία !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel !PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files !PREFERENCES_PANFACTORLABEL;Pan rate amplification +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Hebrew b/rtdata/languages/Hebrew index 51239264f..4c45e109d 100644 --- a/rtdata/languages/Hebrew +++ b/rtdata/languages/Hebrew @@ -569,6 +569,7 @@ TP_WBALANCE_TEMPERATURE;מידת חום !FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 !FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 !FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 !FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 @@ -1149,6 +1150,8 @@ TP_WBALANCE_TEMPERATURE;מידת חום !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel !PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files !PREFERENCES_PANFACTORLABEL;Pan rate amplification +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano index 1268b74d2..72a0c9d20 100644 --- a/rtdata/languages/Italiano +++ b/rtdata/languages/Italiano @@ -1378,6 +1378,7 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILECHOOSER_FILTER_ANY;All files !FILECHOOSER_FILTER_COLPROF;Color profiles !FILECHOOSER_FILTER_CURVE;Curve files @@ -1608,6 +1609,8 @@ ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - !PREFERENCES_NAVIGATIONFRAME;Navigation !PREFERENCES_NOISE;Noise Reduction !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese index 164d9d5de..fbce3a1c2 100644 --- a/rtdata/languages/Japanese +++ b/rtdata/languages/Japanese @@ -1925,6 +1925,7 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !HISTORY_MSG_166;Exposure - Reset !HISTORY_MSG_407;Retinex - Method !HISTORY_MSG_408;Retinex - Neighboring @@ -1948,6 +1949,8 @@ ZOOMPANEL_ZOOMOUT;ズームアウト\nショートカット: - !HISTORY_MSG_426;Retinex - Hue equalizer !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor !PARTIALPASTE_RETINEX;Retinex +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_TUNNELMETADATA;Copy Exif/IPTC/XMP unchanged to output file !SAVEDLG_SUBSAMP_TOOLTIP;Best compression:\nJ:a:b 4:2:0\nh/v 2/2\nChroma halved horizontally and vertically.\n\nBalanced:\nJ:a:b 4:2:2\nh/v 2/1\nChroma halved horizontally.\n\nBest quality:\nJ:a:b 4:4:4\nh/v 1/1\nNo chroma subsampling. !TP_NEUTRAL;Reset diff --git a/rtdata/languages/Latvian b/rtdata/languages/Latvian index c3dcd1b79..200bc80a0 100644 --- a/rtdata/languages/Latvian +++ b/rtdata/languages/Latvian @@ -569,6 +569,7 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 !FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 !FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 !FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 @@ -1149,6 +1150,8 @@ TP_WBALANCE_TEMPERATURE;Temperatūra !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel !PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files !PREFERENCES_PANFACTORLABEL;Pan rate amplification +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar index fdf4ffa1f..84b23b8fb 100644 --- a/rtdata/languages/Magyar +++ b/rtdata/languages/Magyar @@ -945,6 +945,7 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !FILEBROWSER_RANK4_TOOLTIP;Rank 4 *\nShortcut: Shift-4 !FILEBROWSER_RANK5_TOOLTIP;Rank 5 *\nShortcut: Shift-5 !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_UNRANK_TOOLTIP;Unrank.\nShortcut: Shift-0 !FILECHOOSER_FILTER_ANY;All files !FILECHOOSER_FILTER_COLPROF;Color profiles @@ -1329,6 +1330,8 @@ ZOOMPANEL_ZOOMOUT;Kicsinyítés - !PREFERENCES_NAVIGATIONFRAME;Navigation !PREFERENCES_NOISE;Noise Reduction !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands index 3b854174e..4ff8bc482 100644 --- a/rtdata/languages/Nederlands +++ b/rtdata/languages/Nederlands @@ -1965,10 +1965,13 @@ ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - ! Untranslated keys follow; remove the ! prefix after an entry is translated. !!!!!!!!!!!!!!!!!!!!!!!!! +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !HISTORY_MSG_166;Exposure - Reset !HISTORY_MSG_412;Retinex - Scales !HISTORY_MSG_416;Retinex !MAIN_BUTTON_SENDTOEDITOR;Edit image in external editor +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !TP_COLORTONING_STR;Strength !TP_DIRPYRDENOISE_CUR;Curve !TP_DIRPYRDENOISE_LAB;L*a*b* diff --git a/rtdata/languages/Norsk BM b/rtdata/languages/Norsk BM index c6e6328cd..e27fc6897 100644 --- a/rtdata/languages/Norsk BM +++ b/rtdata/languages/Norsk BM @@ -568,6 +568,7 @@ TP_WBALANCE_TEMPERATURE;Temperatur !FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 !FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 !FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 !FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 @@ -1148,6 +1149,8 @@ TP_WBALANCE_TEMPERATURE;Temperatur !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel !PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files !PREFERENCES_PANFACTORLABEL;Pan rate amplification +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish index 1e3702cbd..cc0c436e0 100644 --- a/rtdata/languages/Polish +++ b/rtdata/languages/Polish @@ -1513,6 +1513,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILECHOOSER_FILTER_ANY;All files !FILECHOOSER_FILTER_COLPROF;Color profiles !FILECHOOSER_FILTER_CURVE;Curve files @@ -1693,6 +1694,8 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - !PREFERENCES_NAVIGATIONFRAME;Navigation !PREFERENCES_NOISE;Noise Reduction !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Polish (Latin Characters) b/rtdata/languages/Polish (Latin Characters) index aa4edff85..3c3d08d8e 100644 --- a/rtdata/languages/Polish (Latin Characters) +++ b/rtdata/languages/Polish (Latin Characters) @@ -1513,6 +1513,7 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILECHOOSER_FILTER_ANY;All files !FILECHOOSER_FILTER_COLPROF;Color profiles !FILECHOOSER_FILTER_CURVE;Curve files @@ -1693,6 +1694,8 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - !PREFERENCES_NAVIGATIONFRAME;Navigation !PREFERENCES_NOISE;Noise Reduction !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) index 65349c85c..0d141802b 100644 --- a/rtdata/languages/Portugues (Brasil) +++ b/rtdata/languages/Portugues (Brasil) @@ -569,6 +569,7 @@ TP_WBALANCE_TEMPERATURE;Temperatura !FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 !FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 !FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 !FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 @@ -1149,6 +1150,8 @@ TP_WBALANCE_TEMPERATURE;Temperatura !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel !PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files !PREFERENCES_PANFACTORLABEL;Pan rate amplification +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian index 1748fd39a..2eacee616 100644 --- a/rtdata/languages/Russian +++ b/rtdata/languages/Russian @@ -1317,6 +1317,7 @@ ZOOMPANEL_ZOOMOUT;Удалить - !EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels !FILEBROWSER_POPUPRANK0;Unrank !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILECHOOSER_FILTER_ANY;All files !FILECHOOSER_FILTER_COLPROF;Color profiles !FILECHOOSER_FILTER_CURVE;Curve files @@ -1565,6 +1566,8 @@ ZOOMPANEL_ZOOMOUT;Удалить - !PREFERENCES_NAVIGATIONFRAME;Navigation !PREFERENCES_NOISE;Noise Reduction !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) index c4731adf5..efbfd7ecd 100644 --- a/rtdata/languages/Serbian (Cyrilic Characters) +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -853,6 +853,7 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !FILEBROWSER_RANK4_TOOLTIP;Rank 4 *\nShortcut: Shift-4 !FILEBROWSER_RANK5_TOOLTIP;Rank 5 *\nShortcut: Shift-5 !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_UNRANK_TOOLTIP;Unrank.\nShortcut: Shift-0 !FILECHOOSER_FILTER_ANY;All files !FILECHOOSER_FILTER_COLPROF;Color profiles @@ -1263,6 +1264,8 @@ ZOOMPANEL_ZOOMOUT;Умањује приказ слике - !PREFERENCES_NAVIGATIONFRAME;Navigation !PREFERENCES_NOISE;Noise Reduction !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Serbian (Latin Characters) b/rtdata/languages/Serbian (Latin Characters) index ebd352375..ad813a976 100644 --- a/rtdata/languages/Serbian (Latin Characters) +++ b/rtdata/languages/Serbian (Latin Characters) @@ -853,6 +853,7 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !FILEBROWSER_RANK4_TOOLTIP;Rank 4 *\nShortcut: Shift-4 !FILEBROWSER_RANK5_TOOLTIP;Rank 5 *\nShortcut: Shift-5 !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_UNRANK_TOOLTIP;Unrank.\nShortcut: Shift-0 !FILECHOOSER_FILTER_ANY;All files !FILECHOOSER_FILTER_COLPROF;Color profiles @@ -1263,6 +1264,8 @@ ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - !PREFERENCES_NAVIGATIONFRAME;Navigation !PREFERENCES_NOISE;Noise Reduction !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Slovak b/rtdata/languages/Slovak index 217e36dac..2924fe7dd 100644 --- a/rtdata/languages/Slovak +++ b/rtdata/languages/Slovak @@ -646,6 +646,7 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 !FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 !FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 !FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 @@ -1197,6 +1198,8 @@ ZOOMPANEL_ZOOMOUT;Oddialiť - !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel !PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files !PREFERENCES_PANFACTORLABEL;Pan rate amplification +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Suomi b/rtdata/languages/Suomi index e425b5cb0..5c8c27551 100644 --- a/rtdata/languages/Suomi +++ b/rtdata/languages/Suomi @@ -570,6 +570,7 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 !FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 !FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 !FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 @@ -1150,6 +1151,8 @@ TP_WBALANCE_TEMPERATURE;Lämpötila [K] !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel !PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files !PREFERENCES_PANFACTORLABEL;Pan rate amplification +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish index 62416d9ee..c7ee0a82e 100644 --- a/rtdata/languages/Swedish +++ b/rtdata/languages/Swedish @@ -1724,6 +1724,7 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !CURVEEDITOR_AXIS_RIGHT_TAN;RT: !CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. !EDIT_PIPETTE_TOOLTIP;To add an adjustment point to the curve, hold the Ctrl key while left-clicking the desired spot in the image preview.\nTo adjust the point, hold the Ctrl key while left-clicking the corresponding area in the preview, then let go of Ctrl (unless you desire fine control) and while still holding the left mouse button move the mouse up or down to move that point up or down in the curve. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !HISTORY_MSG_166;Exposure - Reset !HISTORY_MSG_256;NR - Median type !HISTORY_MSG_257;Color Toning @@ -1788,6 +1789,8 @@ ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - !PREFERENCES_MAX;Maxi (Tile) !PREFERENCES_MED;Medium (Tile/2) !PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_SERIALIZE_TIFF_READ;Tiff Read Settings !PREFERENCES_SIMPLAUT;Tool mode !PREFERENCES_TINB;Number of tiles diff --git a/rtdata/languages/Turkish b/rtdata/languages/Turkish index 3f4b2ac5a..2a6694a87 100644 --- a/rtdata/languages/Turkish +++ b/rtdata/languages/Turkish @@ -569,6 +569,7 @@ TP_WBALANCE_TEMPERATURE;Isı !FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 !FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. !FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. !FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 !FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 !FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 @@ -1149,6 +1150,8 @@ TP_WBALANCE_TEMPERATURE;Isı !PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel !PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files !PREFERENCES_PANFACTORLABEL;Pan rate amplification +!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. !PREFERENCES_PREVDEMO;Preview Demosaic Method !PREFERENCES_PREVDEMO_FAST;Fast !PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: diff --git a/rtdata/languages/default b/rtdata/languages/default index 48acb81f9..2df0b7fb9 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -171,7 +171,7 @@ FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. -FILEBROWSER_SHOWORIGINALHINT;Show only the original images.\n\nThe orignal images are determined by the position of their file extensions in the parsed extensions list in the preferences. Extensions higher up in that list are considered the originals of those below. +FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1-star.\nShortcut: 1 FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2-star.\nShortcut: 2 FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3-star.\nShortcut: 3 @@ -1001,8 +1001,8 @@ PREFERENCES_PARSEDEXT;Parsed Extensions PREFERENCES_PARSEDEXTADD;Add extension PREFERENCES_PARSEDEXTADDHINT;Add entered extension to the list. PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list. -PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. +PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. PREFERENCES_PREVDEMO;Preview Demosaic Method PREFERENCES_PREVDEMO_FAST;Fast PREFERENCES_PREVDEMO_LABEL;Demosaicing method used for the preview at <100% zoom: From 6260b472a628e1d099c2b833e2e006c90a20e875 Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Fri, 25 Dec 2015 13:17:33 +0100 Subject: [PATCH 44/61] Deutsch interface translation updated by TooWaBoo, closes #3039 --- rtdata/languages/Deutsch | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch index 9dda4d684..029718871 100644 --- a/rtdata/languages/Deutsch +++ b/rtdata/languages/Deutsch @@ -24,6 +24,7 @@ #24 2015-11-01 Korrekturen (TooWaBoo) RT4.2.450 #25 2015-11-30 Korrekturen (TooWaBoo) RT4.2.507 #26 2015-12-13 Korrekturen (TooWaBoo) RT4.2.514 +#26 2015-12-22 Korrekturen (TooWaBoo) RT4.2.536 ABOUT_TAB_BUILD;Version ABOUT_TAB_CREDITS;Danksagungen @@ -194,6 +195,7 @@ FILEBROWSER_SHOWEDITEDHINT;Nur bearbeitete Bilder anzeigen\nTaste: 7 FILEBROWSER_SHOWEDITEDNOTHINT;Nur unbearbeitete Bilder anzeigen\nTaste: 6 FILEBROWSER_SHOWEXIFINFO;Bildinformationen ein-/ausblenden\n\nIm Multi-Reitermodus:\nTaste: i\nIm Ein-Reitermodus:\nTaste: Alt + i FILEBROWSER_SHOWNOTTRASHHINT;Nur nicht gelöschte Bilder anzeigen +FILEBROWSER_SHOWORIGINALHINT;Zeige nur das Originalbild.\n\nWenn mehrere Bilder mit dem gleichen Dateinamen und unterschiedlichen Dateitypen existieren, ist das Originalbild das Bild, welches in der Liste "Dateitypen anzeigen" unter Einstellungen > Dateiverwaltung als erstes gefunden wird. FILEBROWSER_SHOWRANK1HINT;Nur mit 1 Stern bewertete Bilder anzeigen\nTaste: 1 FILEBROWSER_SHOWRANK2HINT;Nur mit 2 Sternen bewertete Bilder anzeigen\nTaste: 2 FILEBROWSER_SHOWRANK3HINT;Nur mit 3 Sternen bewertete Bilder anzeigen\nTaste: 3 @@ -1019,10 +1021,12 @@ PREFERENCES_OVERLAY_FILENAMES;Bildinformationen überlagern die Miniaturbilder i PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Bildinformationen der Miniaturbilder im Filmstreifen anzeigen PREFERENCES_OVERWRITEOUTPUTFILE;Bestehende Ausgabedateien überschreiben PREFERENCES_PANFACTORLABEL;Mausgeschwindigkeit beim Bewegen von Bildern -PREFERENCES_PARSEDEXT;Angezeigte Dateitypen +PREFERENCES_PARSEDEXT;Dateitypen anzeigen PREFERENCES_PARSEDEXTADD;Dateityp\nhinzufügen -PREFERENCES_PARSEDEXTADDHINT;Dateityp (Extension) zur Liste hinzufügen -PREFERENCES_PARSEDEXTDELHINT;Selektierten Dateityp aus Liste entfernen +PREFERENCES_PARSEDEXTADDHINT;Dateityp zur Liste hinzufügen +PREFERENCES_PARSEDEXTDELHINT;Ausgewählten Dateityp aus Liste entfernen +PREFERENCES_PARSEDEXTDOWNHINT;Ausgewählten Dateityp nach unten verschieben. +PREFERENCES_PARSEDEXTUPHINT;Ausgewählten Dateityp nach oben verschieben. PREFERENCES_PREVDEMO;Farbinterpolation PREFERENCES_PREVDEMO_FAST;Schnell PREFERENCES_PREVDEMO_LABEL;Demosaikmethode für 100%-Ansicht @@ -1987,10 +1991,3 @@ ZOOMPANEL_ZOOMFITSCREEN;An Bildschirm anpassen\nTaste: f ZOOMPANEL_ZOOMIN;Hineinzoomen\nTaste: + ZOOMPANEL_ZOOMOUT;Herauszoomen\nTaste: - -!!!!!!!!!!!!!!!!!!!!!!!!! -! Untranslated keys follow; remove the ! prefix after an entry is translated. -!!!!!!!!!!!!!!!!!!!!!!!!! - -!FILEBROWSER_SHOWORIGINALHINT;Show only original images.\n\nWhen several images exist with the same filename but different extensions, the one considered original is the one whose extension is nearest the top of the parsed extensions list in Preferences > File Browser > Parsed Extensions. -!PREFERENCES_PARSEDEXTDOWNHINT;Move selected extension down in the list. -!PREFERENCES_PARSEDEXTUPHINT;Move selected extension up in the list. From 0daea6659747ce4b0eeecbf56dcd37cae4a6c0ba Mon Sep 17 00:00:00 2001 From: Hombre Date: Mon, 28 Dec 2015 14:43:37 +0100 Subject: [PATCH 45/61] Adding the Absolute entry for monitor rendering intent + icons updated --- .../images/Dark/actions/intent-absolute.png | Bin 464 -> 670 bytes .../images/Dark/actions/intent-perceptual.png | Bin 666 -> 898 bytes .../images/Dark/actions/intent-relative.png | Bin 944 -> 1072 bytes .../images/Dark/actions/intent-saturation.png | Bin 809 -> 1012 bytes rtdata/images/Dark/actions/softProof.png | Bin 827 -> 842 bytes .../images/Light/actions/intent-absolute.png | Bin 445 -> 674 bytes .../Light/actions/intent-perceptual.png | Bin 638 -> 847 bytes .../images/Light/actions/intent-relative.png | Bin 882 -> 1057 bytes .../Light/actions/intent-saturation.png | Bin 779 -> 1007 bytes rtdata/images/Light/actions/softProof.png | Bin 868 -> 915 bytes rtgui/editorpanel.cc | 10 +- rtgui/popupcommon.h | 2 +- .../source_icons/scalable/intent-absolute.svg | 122 +++++++++++------- .../scalable/intent-perceptual.svg | 70 +++++----- .../source_icons/scalable/intent-relative.svg | 53 +++++--- .../scalable/intent-saturation.svg | 72 +++++------ tools/source_icons/scalable/softProof.svg | 4 +- 17 files changed, 182 insertions(+), 151 deletions(-) diff --git a/rtdata/images/Dark/actions/intent-absolute.png b/rtdata/images/Dark/actions/intent-absolute.png index bb7e1a85d0cf0b4a131e3dc02ef8e74161a5f367..7732eba534d0ac33ee87d0275054fa27426bcb94 100644 GIT binary patch delta 572 zcmV-C0>k~#1D*wtZGQqANklPv`rxu3axWCQ#04v zws_kX?b^4OHZ58O(b`222!R`6m_JBFE{mWb5*LvKDm=t=NPX{~7C9i2j*}1ituFT* ze&4<49ynJ3TCLW_y}i8%Ac~?LYwbpi4WyN+j<2c^xtZTK}porWw z#@q!i0h_?Ab8fy|E~mZRFH@RIXQXOIaeqY3Ol7zX$$x(s8g;-A~M$P+Pz9uzgDZ& zrw%|w)>O5aH$+6%^7cF$2GDFaABGSv=WT9`S*}znFMmwl#{W&7?uu1)v|Dn|<|5y# z)#|JRP}Qr(m}_}MLI`K__B>JoP_Nf-i^y=d7nI>ZhHo+>D!5^^6BLsI-rd03| z(%VX~wa+_fnQoJ{vq>Q-v{A9L(sVJh2)p-MsAXU-jCkt9_rYc6&JX}(S=M4^4@G9P z+0$@1nNv2Yqmzu&J^ zlAk_5oK+~hKtB+uh+YF0AQ_6wC_nsthM(5z9qFh=2D#+XYC5s|3d?M9VK<%A1B02+S5@_fh=f2FxCb=Li7Gt?d|ROr9~!bwOVgD=Qe@QRP{9x8K`R8dw)L+!-G<(H27DMDaQY4jOi^cEyZhV zYrWH(s@1AlUw>c!C`ppr#+X|`AR?-&T@m?fv`$qYmCNO?0|0C77o0NQdrut4G#U-3 zs?SvQv50hxF^{da9pGSVYwO3|-QA@i2yUin`Yv$U7?Yc*5dj1M&beYVvNbFYG%ro!*aQNXD*Rh?Ck9178Vwkz4znm%49PA&CShU1Au0;`K9;% zor@4N#*Cj;^(Wx&$df@31Q!w^lcZ@nfH^&x#jwkklO)NG-o0>L=VfHPwf35GZUwjw zyanWez<+y>wRXJTdw&Sr3E=E7T5I!Zn&yXHQvj}r$Vwc?c>w1efCG+!M?fSZJ?C7{ zT03sxG)@1RlhecKy&oGWA}R12@K8iLz>_3NI*W^oPfMjzTC3GA6$*t9z4xoYbyXdA zmx%lV{4jMGN3n8pa?+a?fYoZ%6pO`=o6Y8JRe${i2#hgjV#OHKgE@__*XwTvLGUTV zfK=6iG3I;VzP0w@%z&K5(a}+Oe0+Q+>P2KXm&<)yEEfC!Rb%Q;OI35mnAd?Ds=5k< zA`+?Uy)X=$8yg#)a~*xisD(dg!gvuuRRMli)$f3IyWM_JtycX!#a|FPZG0w^d7jN? fqZ(=dlK;cse2jX}&U8Ab00000NkvXXu0mjfML(4T delta 567 zcmV-70?7S>2bu+tZhsd^L_t(YiM5t7XcSQphQBwn=UyR16e~MPh~U{;9h`8StCkii zLcl`O+NZnD!p>4mD^^xw?s5kygdi3oTnf=9a@be|P6CGAw{L865M=jq8*)lK|k=N~Z`^#J;yqdd>wsj3y_=6QYq6*bw}*{P>#dK+knNCQ{`bVkZvr_hEtg7ncvd&fYJMj5bGnS1NRb4Z)1v8s9R;rt^-|sh6b=}Nv zQguL{hA?v(^%uRgqT@mjoO3hRZyd*GUcXb}UtHuz;ve`mD&BLzDw6;J002ovPDHLk FV1iq93Sj^M diff --git a/rtdata/images/Dark/actions/intent-relative.png b/rtdata/images/Dark/actions/intent-relative.png index c1fb040a9ddabae8f9ebdd03367c2bacbba0978c..117806ddb42aac5c440c5634ce1279bbebb971b7 100644 GIT binary patch delta 976 zcmV;>126or2e1f`Zhx&wL_t(YiH%iDPg_SAJ>NIiZ{Ws}qSR>6S%)Kv(?(-Q*8+n{BsUcvI1ZWo%Ov386~ebOAt+hLaLZNl-BIR=VCdsj3Ael@?thEXN&bdB-{kgfh*Of{oNpi{wa%MC5?vOV9KE$mMb!04SA8A4Q|lthIJrRWkraL?j+gPV(0v2)>c4x>#FV8|`#D z84-EtoSOnL2_QXydm{2L$u}hX#+YuX(Z7Qr_)Y+zQh%vDQPqhHYNSZMZA3&40c?@n zJU%|&Xf~TK78e)8`*6+#0IJpMV^zHy>Y^(mJ(7DQcdfPC3kwT>i3m%jQcP7Jsp>e% zj4>ufG8s!AOv^1JZr5;&pCslO{Cr8&Cz&!wagKsAkx*Y_;)6+@5 z0`Td%F@Hr80DO`oL(2^Sn*cVPbM<^a|LQ6wxU5JYK$qkmfL&|tw&!{EAPDvWpj0Z| zipS&Q&bbVLlyh!GRnH`F&i#|m=fA%eUBHRHk(?lzC7BhG+gC@O-1zryJOEg0V*q>+ z$p9Dy0Fpfb&qZXz^SpYy-QGzg5^r+3-0}M=d4Gez`y|6h*s5xqWRv7CBC-vj9*IPL z%jI&%#bVL;zJD(ki#@Q`j#aDGm~-xoeu>Ddd_Mo|+H@6*#i;N5AIru5OIkoS&cH1%TDn)p)1V`M?-+!&)0585@o_#_R)lEda2- zzMg0_8fMtR_kD&RrE`*upKfhNj7PIJrhyZ{m`9M{_cFwi?{r*qYYITt1a~%YL zIF2g-Qri|0FMlE@Ns@GGwOX%UubZ{CwMFlJKr%4Kyp|PQRZqe&{G5}jP*v{k?!J{I zNnngw0kEX1h4JcPD5Jo~VHkc%0BAHC_lz;OGx9i9&5ysI0ywhPwl6L&+SO{c zJE=%ud?q9xkWA%Q{yC5nl1CdG8xKk9-rn8|s=C~4Hh*gXUe5|HB9F@D@)r~70)YMf z{Tsbr?~aJ97-N#i|oApVFiDc5gM))#>h-!@4uh(`DI%$iko==mDt$jSUEAB+Ip^GMl7XrQBo_gs z>fJS531p+u_()Y>%BUt!a*5>osyZ`X>jH?ZwSVp5aCn-_M~YHW(uUL zJ|VdapzXbHS1OgWad)@!`TRSh(I}M>Ywe!^&Kv*~3Wd+Iq<(&WUd!e3IRHda^s;mA zgE)=@Rb2sa)B7xy2LN;cY+XwIVzF3E9Z6NqMNzag9^F?}6#xdR`lB)CTau^Vdr9*Z zkx0LQtIK#7Kq_4%L2^X$XA$|%IoBq6yuQAkB_;oX0{~;p{Uk|lq#8IU!{P9^X&;v#H$-}C;S45KL8^)L`BrlNsGmhhBYi$HzT~)P3XBhwzC#L}% zODZHmG7-E6V1HIsN8>pDHI+)u_V@QM3=a>dUDrM4y6#Z`PmydFkq(mgwK$mq@S_6& z#+diFwzh5x-WanHMbWiVsq|O!RxX!KZ*T9@VHm!aN~KN!*drn!xga9fN&ZH%-tyVs zn@+OXZ1r||_`aVp#uNa&2w*?SbyfYwT00TP@lWmT?SHzmvT^{x0RZSF* z4T~hX*BEm|M2?VDlHURNBA3hk5QgFL`T6;`NggMuBJvA>AprBLx}d5z5)s#RH=9mK z7D+aP2Y(QW$R7Yct=H>cl}e?#Fbp3Ig5XV6?Q4u{$Z?!XXJ_YftyX(pRr`!F2T8gK ziHJ-C*xvX|CiBkR+?-8{larGh<#JgX_8A000l>=uQmXo;h-w zi{vtZS(0lBkE&LIJ8Zn~`}>VCuLF2ORcDMb?|1|eCT=JRR9RX@L3T#LvjS>yjv&~7Iz~6?BWUsLC_&0Zx~~q6p>2+&KC-W_1y~GR%Bvg zBE7b@b`ro#B-5(;k>`1z?G)}EMSS0X)fn?=%X>;y4>ivC6v+>Ax!m->B~OqX$S#rx rTi!PST!`a%tXM35|6j@PDgFjNYM$N22@Vuu00000NkvXXu0mjf)!MSg delta 712 zcmV;(0yq8i2dM^-ZGQr$Nklc#CR(V7%&4te zg+Wl8B5D~SWG{McBB)L4{(!>P>KJa)MNrU#%3cIIL=Q@#VPu?hzAYLDg5T5_(b?Yb z`F`#>-+O`oPyztOVsV7zj(=`0GB+?Va4i6UnSJu!Xa6-sRewJL^-2D=ip641Rok1L z#~3U5e7+RcYU;i3B-v$VT_V!qy>EI^GkXSLG}N2B0OXQ{A`(Sp$EvBS3IHYfmgHUU z{W~+WCY&VzSe@hmfX*ZpNsv?#d1GdGLkLeZnap!l%~UFtLnM!jBoAX|F919Z0N|Xv zxw5j77<`P8&VRX5e}Dfn08CF$hjO{R7r=h!Tvk;dg%B!DwlLqAB%jZhnvDBPO-@ek ztkr5q0dxR(U9DEfQmNEBl8Jg%{n~)EV7}EkcZB3F0AJ1QMvU>Jh>Vg<%n|^+_s;-4 z2z8S_l8H~zIoA$gkff2k9b>$ss=cauh2&BQ;X<`qU4KgIjWJdllZeP35lIZbem)D} z*38Vz=boOPgCzHnd?zB0&FokR$qO;FR{(zg__nsTOA8ANK1rC%$pv_X$0|6iCTz_kRp;mlAR!= z2{I^_J`e&H5$uH6+N;>u2_a386nWfrhZLfQ2mu8V42UAZVwXI3vUhjxv2a$BHJir6gl)Pd{VqvN7i7zJnO5TO^|MmS^E^)rA(Rk8N-0I7IL(|ALX1sMPakb6&SWxQIp;~OR!gLm zDwT2}1Ovc0|0kLNSOV~JczC!h|1qX?cXw|XW4`R{>|9Ke#4*N*h{!od0LVG#(kWvA zZ)>%h8GjlYD%JB%#cAk$rBXRxE|<4F&r{Y~8^`f>9LE(R`pG#j6pO`oVHn!R?1AD^ zskGSH*?DDseO(A4q_wu+2D=83ZhyE*L_t(IjjfeUXcSox$NyDb-9r$TKtKdpSZ|7Z_Fy77Hgrq8 zh=&$D2#Ox|?#D$j;!V7XMnMpDL2u#;laH6!L{RYHl7JpWyc$T%C=QZz&+AtnG9%+S zGs%E|D0p2|{klHren3ML6BB>U&CUIZ-y~@seBVEv=eYxL5q|(CCntA%o_Cm;C&DoN zzh5u|fH7vjs_q1^D^1f801%N20FFE79vWlDr>3U1_5-FgO{FM`aaG;c@GWLpcD__9 zy#U}f16B2l=XqztFnqqLit{`#Ip=Pu>I{HsRlNydTPqX*h-lC`cgq-aY*XMkj=x1w zG*3i}&bh@Xiht%sguBFh04^D0&TI(oP4_Iy#q^mp=n20Dzgv^E?(2BBGxvB%-6k!^79oG?jKnM{trP1rdEFA_PIeK@hO- z`(6+PEF$ggAF|e7uT(0f4Z#4Qs_y_mM7(zMJg+_PKz|SfcNP{FwrmFc23Q}3@B7>| z5n&NwW~R3IJxfbV_tP{T>yY-hwf0`6Qu*VTp|`+ZTWbsFoQen& zk*aDFincuhfW`U;c5ifa^lMjexm^AYb z4iTX|&kG`YSro;CD2h@d(yqC^z~yq;GV>MZ+}C=&{;%)*2g5Kt5y$bfR_OHf^r`ks z;>QMzF$pv4%F4=<4(|v67a>bfi}Y-K45pus&AD z%paKfT-U!-KQhK#1u#fNbJc3~QIaG@&*k-@7Xt$W&qhW@YE8#?B7inNCLk&I00000 LNkvXXu0mjfO-@%3 diff --git a/rtdata/images/Light/actions/intent-absolute.png b/rtdata/images/Light/actions/intent-absolute.png index 1396e378553270124944c886d2536016f879e622..7a507e0f5cbea2301a3bccdc4b36630d804c1426 100644 GIT binary patch delta 576 zcmV-G0>Aye1EK|xZGQqENkl-|8NI{5*S4B|b<_D<=!nPo3(}W~s_UoZp$)!zFw)nlw z%-fmo=gllLPXNI4yo=V_MI5ScjA{A4-$qO_qxO-i7NTGnhJSEfcL<;X;48^5jYi`; z0GA?b8_vET1IQE+#6 z_aN%$^ZDh$U~pYT?vPvsuupO$old_km&?PcA)e}4{Q=-(u~__EDwS+5 zm%9ewJ^)ulet$ZS^Sn~2)TV;0t*zZAc_9jtTo92}k{*Bsl79efwcG8@APBmi=iMOr zfMf!|t9rfu2FLs_nUq8(lbKi5d1K6+s&7LvF%!x?f_x*#TKmq`{ zT<-BG>sTcs)mp9g%!~#*qpimc*@@fpXcz#vuKN(crGHcKZ`AAcmwF1u|3}e1xkqwk z(&U-VMSl6dzhMBtT6%({0`g;5beQU_X^gwWh6nlk^w1l;)l@3ok|h O0000-X&&nlR`SB%~kL%^cfUMAAkl+%Cfvv z)u?kNNfLK1;0}0-kyvZLV)|Q;0T_)&=c-zE4mYN%>-x&B9u}$^^_~Pu7F{zp%K(PM z;TR~kz<-&|W|L$K;QxsMaL%2m>Y#JDF|Q(WV*$MP`$>`T21{@)#mb(@w9~>l_{){)6{`2mnF|-%I-R{C_ZnfH;m3$MFkEJ7%_B ztyUjyZEdChhlBvIva<3SfcXr`B}rFERsh@pkR$oh-D~cCXK!!s>C7b4u(`RJ>-YP& zLI~dis19qIlJ15O?$+z|-aC_w5H6maoP1648vq{xIF__c^8R2j*xBFTKb}Z3Dm;J_ zl3jQ2HJi=un14E}R4QM%`)zl>MKS^)NiPAMUNk2gySuwTjTIhe6(EUnxtx-GM)HZf zADGz_GdoyZT->SEYJZeUrOWwzzDjb#%&th9%k=0>o1_S!0H7!-HnVGzmXTQwNh!%^ z0NTR|UIFNa5C&P2Mx*f{0)SSl)tn&1Ybck?MR#A0qJQWUNy{X!Nh*^p0{8#`-2LKv zl8*sAm`V6)SXx?|D-;TGk|Y<`6+-AY8jU|A09adF`$5v$yAq{o3i7}Imb44t=Li5u z9+P}85i){fU`C%zL#b4{JU>4lr)hfW{Oq;sdRt_LclTv8yYB8w0E#3dNief)$zuRN zM!>`sE`Q=|g+Da2kB2K<3?V=g0Hl)sBH57Ck<`VQ6$U1x@CXt~f0KMPG~?5u8QZm5 zEm>Gt$QKHQ&!Z@+0J!e%Su^efIP*!GroW7f6_VWv0ceuGTwhb%7 delta 540 zcmV+%0^|M92L1$)ZGQp#NklbRON=sR= zkZtYv7g*R?E^aGURw8U|BNnnSQ%FpPm0;t5gR+neL+-JeEtF(tGVGr6z4PwLefOUG zA^3f_^K?Ppn*Z+|TkhT$Cm*Xsz*xho_e zl2qs1huLiQW;&gov=&*1e!qXs%$}0G3*dz0+cZtz1F$m_IYk`DaaC2jA`%10Nxn|g z^vgyfK@fz_xyy9~=bSATi|>=k>LXQ! z@B6u#jhu7uM1&2Q`~q6mq}%OYQq_T~4oMD4Mk1msG8rdHve!zaPSo?f8zgJvsA`cU z$qx?zq9}S!GTK&5r2bn;egp8zTaroCU00i+b%k%bE&yWydmgab zjQF>OLlIGu0FVPX6p`a~Exgu@OEN?xCwW*^)yT}oMNur4W_;XqPDBy_pVykPX{`9Z zzeBPkBCEzqdou<>Fm%rC0=S8`19BbCWYnMcqvb6FJ!mTYvXhQT?k7pI)${8CfbaV+ eagIL{e-#0jvM`gDSQBdi0000?E!t3^JJJ#r{eb{U z8z4xj#=jwdAWhm7Y2Btxqaw&32&gVVnt-4vl1C~GB1I+~+14k?)80%99UbySOPuC_ zeLMSR-tD|404NrVE2{b!sSuG1$8oNP!{Jr8+dT!K={>WAlYe}_0`PSjWM+s6GMNm5 zAQ%!+6Tt7xTz6gfs9LRF&O$-}P$(20EiNuTm;i_}BEkTms@KeX+GsT1EH5wTJkKkO z$R;xfBJzZYmH=dK9ZpnhwOZefI_aOBoJ8XrJkR57Hk-57dLr^nRZBq-lmV=&DiM*Y z>LD{XMdTDfpMRO-6iM%WC&gm%dsW@Mt7TP<0UR)MT|{cen7wARc|MC=PQthgppmNL zDvskwRnM6Dm9_TIZnrxC0N?iu06q(Xph!e{5m^Ki7=}O4eN~i7r6nTDTWd?q zTn4bAsvjkAL`27``c_r1jWNUVToL&@48xx&sq8yuUVon=(E<`llgchcWS@xkn7OvK zwbkC)*@@G6w>koVAP8PC^V4x4j^klc={q9oF>|NUX#530ec#VA^K&99ib$S_7F0Di zrO0l(-Tv`jxqutVRP{M-q$;awKt!XP8L8?!B8mVE#`8p^)9G|x5&*2Nt$oAHYg5jj zCn8T(7k|gr4n<^-h-$f9u3oKHU*jGpaPGja0bBqGRka78BO>*KgM(85@O}UB<>h73 z_x;bAc_F!B6T!^?v|6p7XOauJ@izeLBC-i!lZck@%Nb4l2Y);O#BrPj;1N+Cz*4dt z5m8fBYXIu1dQ>PB-c~9V`ynz1094gi)rl*dOn-PEz&U_F0CWJnKL2+0RIxvZvgg*=#Yrcj4^}TG>CviE@u8RZIDC+RRs}U0C*)L zzkfQ8Q_o~Fd$n4v2LP+9t8;U6b05cX{7^(P*4k`}Ei0lHWTWj}6wm(aZCjO;}%%?$P kOkYIK!!SIX^}uQIA2l`3U`$oa>;M1&07*qoM6N<$f(FpQX#fBK delta 786 zcmV+t1MU2w2=WGyZGQsqNklXKa(q?6ngq!O|*{r9_*oXR~u&3Xc&%bInSe z?%p|{kKTJm03c1%tvHUmXfcwn%d$Lb`?jvd01!pd*JgG-P=DkEz*qmf2+3ba?gV_Q ze;&r;@s+BoG7-s0W+L)ID7lF2mu2~F3;>J8qNu7WYIEG&+)UCm{X$hU0NHZ6+!7H0 zc&)01ncY*>I#6T=00IDm!Qgw6t+>vOWDUTR%vCif`M`T$T@>?oF#s42hqp+!j%{YO zs+RNleE<0P_yD2 z8hkRHPJb2vaL#?Fs@K{aNyY#!HOChsvIihHv)p_Cbd4s@)FmQbL|XZhG?JyN?v-Wv z2mpt};X5QJ&bco|l8?RjKdplcy0l zH8aaZBm>|YF$C=mT+X>00NxMyUQ*RD$svHZR22Z8lH4(~JV}xxRSn@<0u3%zy>-!o zG_#qA?2^noolbsmaB$Kz*IO=^pIw0KIe-%Z&VL?TXw|DKXS3N$0LZdz^YrvI1CW{7 zwuoE_H3s|(SCS+yNs?Ac#&O))*w`48oGccL51Z>sME)T88-ODbv9{Q{uIE65D~{va zAzUOua;2&dN!}ru_j_0iGMjn&oF#?;i**u=!d3Fq8#l8;(zQvfDC&l`^mopTicKgQ#F z&pG#}#e1IDw$|RL)oR_Lu*&6fj};1qmjIk3IU*t;*$|PN0DcmYUVKid?zh&S z0`N4+F%hW)SWF}mUpwb!j4|_C>$3o+j4{w!!#Ovo7m=#~E_(ow&*z`S?vkOk7HjPh z00m=A0RTyUueJWHTCJ|k&d!!a-+wzBU*E~ZkcsMTscWsI3uN*yDah($;S0CsPD zyWM`X+wJN&*=#o30Ak-#EEX4>b1yjO4k@KRkD}Gx0Xz(#E+X#+K~OK1N`L8IuXhf>NdR@{+|v5``gZ`h7moly zsZ>e>7>R>BJ3EH~JWg@}fL2N^mdoW&mzS5V@B3Mjuamq-L_Q9~aB;}>o)7@=egB=| z%NUOoz-4Rg2laaW=l;1TNS*`G0q}MhhL!!uV|W1IoVy6%%22$SNF;(vrE)!PCZErr zA%A(A!1SricC*Wk0q1IQ_i{P zNsei)Kde@(pWrsjy`xAzpMOzA9vq4v0+7Y-%TUo;zrVJ&7W`fE81bJmP4d`4S)@(! ml2YocAP9c=r{s4Pe*h?1j$Np+MCSki00{s|MNUMnLSTYz#<9Nu delta 682 zcmV;b0#*I*2a5)fZGQrYNklQ?}BJGakOHPUzyVGsnR zVzKxO0EUN$U4N-mx+o%-Nw%r#M{DgyOztw!r175TodR$JKsU(+k~7Y^LvebNtGQh6 zeM81)GMN)$7>)oqO>)&*`z#E@vN2{%RU^HuPm%?&4N0fd=K#b##jY?6&x?qXd>I76 zD-k&hUB>GhRgAB@&4j*?(-d(%aj6mE`;{!8m}Fh|H*JQAF+lnD>2ueCOrGZUO)X1_n9-B%%bq?{|~D4WNbOQxVw! zFhR0Zt$$X>DwRrYuO?l+(CBWS0H_#a?gL1u>J-TzTU%QbjR5{YRP{B04^aXUq3`=| zlF8%|RhVPe@u-y;~?0mKy~CfZ0pX*VlK{_x;BJlFqrw zW&uEbl5{$KT|`dCXi@+U2SM;~X=&+mvjCv(i6e+~k~|ip2>?v*7jR(l8(2pVitl67jFFzT(}pC3)eb>y732yEz(Y{uP_XqV$=4u&F|#(-Q&Wf z#@M78nD6Rx?)QA|x#w^%(9y!e!tCPW;?sCcQr(4f?!7pU9e;pN0AOxz?isE1i%F9F z8iwKSqk<&>SZh}Ryg@|4UaYdVe~du0>IF|4MMJR*R!3`YW5w&M>(;l@Q`T zej<9sTKmrG>Z%;IVh5l~L^L)wW>Tq?mrA9)@$qp_Yk#eJjYM>PV`Jlk<>h5P3K-1% z5CFU$br118PxX11DwWEIv$M1QDB$}5ptY8s=Xt*G8?Ci5#%N=V5kkm5|GZM__R`W) zYABe99(30osHe5oQc9(ilE#?-^_7Tb8jZ&7TrM}R`Zs$N5>XPzaiX=>Ns@q>lQ@ov zh^TLl0Dq7;=YEq?-r3*ZuMY%=VOX}-{!y(~U&v%Kj)*u(68`7b%$*Ml02)N}W4&Jg zW^ZpV>gErt7yy25wOY?rDwV1+M#pj7E|<%-dcEH24EL@v=BLfg&31p{P;jwW{AGQ8 z{q@7cLurgr&1SQ8etv#WN_l5zXXkeSJSg{K0DnOcJkQJ=MbTC_wzajz>2$i}oV(U; zw|_9ke6hW~{q6Db@j)+Set!Pl>FMdiQmJ(DVlSR!p-{L5fR$2T_n+?jzG^m`=Yy(? znO+*3k`^|Q0H&kqg`Y8T*qK7SLy&0(z>BxX(#kz!^igxJmHavu%+ogPK`eEu_L xek>Be_r+rI%eA$&qK;VZf@>QmSum(ar~L8o)eMR<2XJuKR^F-mSwG3!Ca|S z41l))gd!3#^V`eI%kuzU7$&LeS!TYOB*`l?JMMHkCkll^9e{{PjhVl0x7#O}`OT5s z0uimpah#=T`hWX>f?KVYPt)|DVzKzFs@|{FYPX8T;!^-FjO!3UC641lnx?m>fq86@ zIiFUfsu!Je9|E9bfdSl|1|I0$BuOq!G&e3-tyVK4$^pO_L)Kch)>04zk2zG;3(mPu z2M1s#$2k#Y%#1J$If^2Vq9_Q%kgc_&?XNc)jnAEP(SIypsOnz;V66?JC<+GP;m9Mo zXPNoSm6er~vw;5?fXQ0RL+937HpcMivWUowolfV<>gwvLsbBzq4kv{|Aqc}T7y^gi z7&A+)R_n5J?#X{G`cW&)zW~U+_iBt`5z#!)iJ6I+LG(D6i2ADfJ%G!#TJ7FMaJ5>! znzp`nKo5r~Km4BS`MZ@S&?S35g9cZT&7!2=iHdhcIqHk&>SL-yWF zv)SzTdOZ=5ZDzjOZntmj?(TL*Yo~%srP9qtqw)U!{{HjE80z(Uxrp2rk*oE3{RaR# zsdn1tVRLh{PedR0`~7=|hlkeyoZH^sey3iq-+X!$y0EbD-smH7v;*aG`3(SSjJYx9 zA0dF=Bm>_2OCs_#GyisQaPY<6-d^hnoFvJ40OzN5FiEOQrZ zNs>=g^%Q^~*VfjqZ)|K#y&Y$kbMDo0x%|YVu?N*@G4+r{yZ!(G002ovPDHLkV1jAd Bh4TOa diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 621c088e3..f27e27467 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -81,6 +81,7 @@ private: intentBox = Gtk::manage(bt); intentBox->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); intentBox->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); + intentBox->addEntry("intent-absolute.png", M("PREFERENCES_INTENT_ABSOLUTE")); intentBox->setSelected(0); intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateIntent)); intentBox->show(); @@ -135,9 +136,12 @@ private: std::uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile); const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL; const bool supportsRelativeColorimetric = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC; + const bool supportsAbsoluteColorimetric = supportedIntents & 1 << INTENT_ABSOLUTE_COLORIMETRIC; - if (supportsPerceptual && supportsRelativeColorimetric) { + if (supportsPerceptual && (supportsRelativeColorimetric || supportsAbsoluteColorimetric)) { intentBox->set_sensitive (true); + intentBox->setItemSensitivity(0, supportsRelativeColorimetric); + intentBox->setItemSensitivity(2, supportsAbsoluteColorimetric); } else { bool wasBlocked = intentConn.block(true); @@ -148,7 +152,7 @@ private: softProof->set_sensitive(true); } - rtengine::eRenderingIntent intent = intentBox->getSelected() > 0 ? rtengine::RI_PERCEPTUAL : rtengine::RI_RELATIVE; + rtengine::eRenderingIntent intent = intentBox->getSelected() > 0 ? (intentBox->getSelected() == 1 ? rtengine::RI_PERCEPTUAL : rtengine::RI_ABSOLUTE) : rtengine::RI_RELATIVE; if (!processor) { return; @@ -206,7 +210,7 @@ public: profileConn.block(wasBlocked); #endif wasBlocked = intentConn.block(true); - intentBox->setSelected(options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 0 : 1); + intentBox->setSelected(options.rtSettings.monitorIntent == rtengine::RI_RELATIVE ? 0 : options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 1 : 2); intentConn.block(wasBlocked); updateParameters(); diff --git a/rtgui/popupcommon.h b/rtgui/popupcommon.h index 04044fb2d..b5cb757f4 100644 --- a/rtgui/popupcommon.h +++ b/rtgui/popupcommon.h @@ -54,6 +54,7 @@ public: void setButtonHint(); void show (); void set_tooltip_text (const Glib::ustring &text); + void setItemSensitivity (int i, bool isSensitive); private: type_signal_changed message; @@ -69,7 +70,6 @@ private: bool hasMenu; void showMenu(GdkEventButton* event); - void setItemSensitivity (int i, bool isSensitive); protected: void entrySelected (int i); diff --git a/tools/source_icons/scalable/intent-absolute.svg b/tools/source_icons/scalable/intent-absolute.svg index 497ce9c66..799deffc0 100644 --- a/tools/source_icons/scalable/intent-absolute.svg +++ b/tools/source_icons/scalable/intent-absolute.svg @@ -28,8 +28,8 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.28397906" - inkscape:cx="443.36338" - inkscape:cy="-4.6332449" + inkscape:cx="497.94487" + inkscape:cy="-71.539587" inkscape:document-units="px" inkscape:current-layer="svg2" showguides="true" @@ -1294,6 +1294,24 @@ y1="1004.7048" x2="1694.8438" y2="1004.7048" /> + + + + + + @@ -1303,7 +1321,7 @@ image/svg+xml - + @@ -1329,50 +1347,56 @@ inkscape:groupmode="layer" id="layer1" transform="translate(464.16179,164.03236)" /> - - - - - - - - - + + + + + + + + diff --git a/tools/source_icons/scalable/intent-perceptual.svg b/tools/source_icons/scalable/intent-perceptual.svg index ab34b86b7..3c949c91e 100644 --- a/tools/source_icons/scalable/intent-perceptual.svg +++ b/tools/source_icons/scalable/intent-perceptual.svg @@ -15,7 +15,7 @@ id="svg2" sodipodi:version="0.32" inkscape:version="0.91 r13725" - sodipodi:docname="intent-relative.svg" + sodipodi:docname="intent-perceptual.svg" inkscape:export-filename="/home/philippe/devel/rawtherapee/icons/NewIcons/distorsion.png" inkscape:export-xdpi="1.98" inkscape:export-ydpi="1.98" @@ -28,8 +28,8 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.28397906" - inkscape:cx="443.36338" - inkscape:cy="-4.6332449" + inkscape:cx="-22.166458" + inkscape:cy="-89.632823" inkscape:document-units="px" inkscape:current-layer="svg2" showguides="true" @@ -1329,38 +1329,34 @@ inkscape:groupmode="layer" id="layer1" transform="translate(464.16179,164.03236)" /> - - - - - - - + + + + + diff --git a/tools/source_icons/scalable/intent-relative.svg b/tools/source_icons/scalable/intent-relative.svg index 31a2fb342..1cd7135f2 100644 --- a/tools/source_icons/scalable/intent-relative.svg +++ b/tools/source_icons/scalable/intent-relative.svg @@ -15,7 +15,7 @@ id="svg2" sodipodi:version="0.32" inkscape:version="0.91 r13725" - sodipodi:docname="intent-perceptual.svg" + sodipodi:docname="intent-relative.svg" inkscape:export-filename="/home/philippe/devel/rawtherapee/icons/NewIcons/distorsion.png" inkscape:export-xdpi="1.98" inkscape:export-ydpi="1.98" @@ -27,9 +27,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="0.28397906" - inkscape:cx="443.36338" - inkscape:cy="-4.6332449" + inkscape:zoom="0.20080352" + inkscape:cx="1490.3375" + inkscape:cy="469.77917" inkscape:document-units="px" inkscape:current-layer="svg2" showguides="true" @@ -1294,6 +1294,16 @@ y1="1004.7048" x2="1694.8438" y2="1004.7048" /> + + + @@ -1307,6 +1317,13 @@ + - diff --git a/tools/source_icons/scalable/intent-saturation.svg b/tools/source_icons/scalable/intent-saturation.svg index 638df39f2..1af08f4f2 100644 --- a/tools/source_icons/scalable/intent-saturation.svg +++ b/tools/source_icons/scalable/intent-saturation.svg @@ -27,9 +27,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="0.10040176" - inkscape:cx="2047.3204" - inkscape:cy="-1169.7659" + inkscape:zoom="0.28397906" + inkscape:cx="432.87769" + inkscape:cy="408.60409" inkscape:document-units="px" inkscape:current-layer="svg2" showguides="true" @@ -1303,7 +1303,7 @@ image/svg+xml - + @@ -1329,38 +1329,34 @@ inkscape:groupmode="layer" id="layer1" transform="translate(464.16179,164.03236)" /> - - - - - - - + + + + + diff --git a/tools/source_icons/scalable/softProof.svg b/tools/source_icons/scalable/softProof.svg index 7d142fc4c..d09f316a2 100644 --- a/tools/source_icons/scalable/softProof.svg +++ b/tools/source_icons/scalable/softProof.svg @@ -1337,7 +1337,7 @@ image/svg+xml - + @@ -1369,7 +1369,7 @@ d="m 95.191608,588.78944 0,-496.118075" style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#2a7fff;stroke-width:30;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker4687)" /> Date: Tue, 29 Dec 2015 03:52:50 +0100 Subject: [PATCH 46/61] Updated icons (from Drslony), code cleanup and bugfix --- .../images/Dark/actions/intent-absolute.png | Bin 670 -> 710 bytes .../images/Dark/actions/intent-relative.png | Bin 1072 -> 1140 bytes .../images/Light/actions/intent-absolute.png | Bin 674 -> 700 bytes .../images/Light/actions/intent-relative.png | Bin 1057 -> 1101 bytes rtdata/languages/default | 1 + rtengine/iccstore.h | 4 +- rtengine/improccoordinator.cc | 4 +- rtengine/improccoordinator.h | 6 +- rtengine/improcfun.cc | 2 +- rtengine/improcfun.h | 8 +- rtengine/iplab2rgb.cc | 6 +- rtengine/procparams.h | 6 +- rtengine/rtengine.h | 4 +- rtengine/settings.h | 2 +- rtgui/editorpanel.cc | 37 +++++--- rtgui/icmpanel.cc | 14 ++- rtgui/icmpanel.h | 1 + rtgui/options.cc | 4 +- rtgui/options.h | 2 +- rtgui/preferences.cc | 29 ++++++- .../source_icons/scalable/intent-absolute.svg | 60 ++++--------- .../source_icons/scalable/intent-relative.svg | 80 ++++++------------ 22 files changed, 135 insertions(+), 135 deletions(-) diff --git a/rtdata/images/Dark/actions/intent-absolute.png b/rtdata/images/Dark/actions/intent-absolute.png index 7732eba534d0ac33ee87d0275054fa27426bcb94..6d274a2c0aa81d1a0965843aa6040aacbe205a22 100644 GIT binary patch delta 611 zcmV-p0-XJx1;z!CZhu2bL_t(YiN%)9OH@%9#((d*7t@i^E>Zz z4(B}vP_0(`Tdh`y_x^WRSJ%%{snjAv89=2{c?b*wn3;edz<+1pQxrvWrBZ46*pOm`jr6Q4A15XgKGNbxrqD z2%(X+=e}wm{Jjvu#jMSpb4%rN`H9Qg_`j)ryCx)^&41k7>|2r~lQDp#E6%yASwlhy z-C29?D+8FCn!1xdBiWjptqu+9>+3xz_V*=**bD2jm|NquRA z{lE!H09+epHXA~C@4cTLA0MwBrkxldilV#T`$6X%l1Qgv!^~EISHPl~EjAjBrK3#7 x7{EFA*g5C7x3|OE+S*33Slld^%b9&9{sR8a444G8me>FQ002ovPDHLkV1l7wD!Bjv delta 571 zcmV-B0>u5s1)c?vZhsp|L_t(YiN%&rNK{c2hre_09rR6=vO(7Kut#dY0GuPU- zc-t23+P9ZBEm{T9+C>lufg53%KS)F_i=ZG97m)-iJj8TJeea$YIUtgblMni>F83UM z-@WG^I9C8#t=7f8y}bw^ilQBB?MA6o`bka_fJUS71Q%i!K?hj*3Eltz<)YQ~=&ydB%#b{+^#dbF1INs{4Yqi>-h}<;B z+yyQHo4~AdZoXVDr@h?daJd4oDk5Kiw@H$`kK;I7SXj7`rs;j)iims*Aw2WmFP#X| zY&P!z!w2^J_kT}4rmFoSk^uEA%jUfI?M9<P%uL_N z$Vi`au8?J!T5Gq<1i`LIeFGOS11$;JEc--3-~LjQ?5rMGS=7On=_S|4p6lidA*ATXN6lBHydk z>Z}7$)vLysYk5OL2xs#4JW>Ksuh(yj$Z)shUZtw5-uspVu+~;W2#4p%sb#JG1pI+S zQS^9yecj~^85$Z&0USWP-5xI%i-Vn@F{ZfRZ4;_`K}2>{^__^ks#Gegy}~-(b&mt{ zB!qyf?lc->mVmh=N!}bBWd8&)#yszQB%E`>TDu8soOJSa({JNC(wg5+2=oY$Zh!GfL_t(YiLF&lZ&YO%J?D96rh`zSv`k~=Gni7KgpUvxEYyLv z(_p%AgNeVvtqV7XojW)F0`)H_nR?sI#?Y0aLTjKX0zGb0B#nG#rkWBjE|3>kyHpFU1zjH2iafR6NikbGulk0jkUv)FrI2XKGWxFm6ObhLwH!8x}tgwPA1&&&=; zqNLc&rhfq3kaVkFug{K*jI3@I*QWrElFWq=@+5Zv$h7n&0Dc2-1HfcYPtWx6FHdxT0KnifcL)J%nAVB1ds=iA^BinVBo7Jkq7V?K*Kq=9zs|FFz>xzFtfScyLaC^ zd-iOjQmJI(IPR;}Y9B{Ybh=ut9s-b&1TzDGC4T@<0n{bMA%v%!#??d=MLWIs2LT*0 zvpxVPNaoY>eE?IEW+dHhZ*Q-iJ9lpFWpRB%@<2KjSxGx36-ee5DOS&m(p5%iN!c3`D zntxA8yS(?OqbNEBpf5?1!atagC9RPRTgC+dV`F380D8UmN6qXMfPEW#% zJLhf}i^V6c^-M}M44^xNup?cf4l^r+5DJpEr9?r}f|)5@)`VmQ!1os}T)6u(qs_S9 z2hdNlx!tR2RI?->NUDVpj*u*+fOOS%yhk!e z@;ZQT1_lOZUWNPxk#f2Gu5)frdQWtQ5Dt+%oSrn1G?B?0oN$S6lZp2^rh8lp2I}ZH8 P00000NkvXXu0mjf&{*-h delta 976 zcmV;>126pa2(So{Zhx&wL_t(YiH%iDPg_SAJ>NIiZ{Ws}qSR>6S%)Kv(?(-Q*8+n{BsUcvI1ZWo%Ov386~ebOAt+hLaLZNl-BIR=VCdsj3Ael@?thEXN&bdB-{kgfh*Of{oNpi{wa%MC5?vOV9KE$mMb!04SA8A4Q|lthIJrRWkraL?j+gPV(0v2)>c4x>#FV8|`#D z84-EtoSOnL2_QXydm{2L$u}hX#+YuX(Z7Qr_)Y+zQh%vDQPqhHYNSZMZA3&40c?@n zJU%|&Xf~TK78e)8`*6+#0IJpMV^zHy>Y^(mJ(7DQcdfPC3kwT>i3m%jQcP7Jsp>e% zj4>ufG8s!AOv^1JZr5;&pCslO{Cr8&Cz&!wagKsAkx*Y_;)6+@5 z0`Td%F@Hr80DO`oL(2^Sn*cVPbM<^a|LQ6wxU5JYK$qkmfL&|tw&!{EAPDvWpj0Z| zipS&Q&bbVLlyh!GRnH`F&i#|m=fA%eUBHRHk(?lzC7BhG+gC@O-1zryJOEg0V*q>+ z$p9Dy0Fpfb&qZXz^SpYy-QGzg5^r+3-0}M=d4Gez`y|6h*s5xqWRv7CBC-vj9*IPL z%jI&%#bVL;zJD(ki#@Q`j#aDGm~-xoeu>Ddd_Mo|+H@6*#i;N5AIru5OIkoS&cH1%TDn)p)1V`M?-+!&)0585@o_#_R)lEda2- zzMg0_8fMtR_kD&RrE!Xy3zx~FyFj9zxRFl z=AF*~k|Y^1vtpKIzslwE_u1Lm4n36Rko%G*@-<2N=A8RzW`7^TFq~glSXeqTB#z_B zAP9yf^#MbY&I1*o4-oLqd;e^5a`M&8%uIGDNV!}-8OQNfcblfCr-NFpHoCR7bp8A2e@zy{>?N^AG%{O{y*CJPHsy&+jDcXFMsuV{YeOrW!XjN+@)SavMf8* zYtMgbXLns^dxZ2_D`}cO4*{HWQ(XhHXEL)IunlRoTK6_LH-o)@ayaA8vr3d6h+l2iUz&+k#jBt`Xvps-NF&z zM4nko(o&qHx4>MQri%xuD9rD-Bu$tZl3;s+t^v!EUYJ=U2!cknT5TTs&zL01NTE>3 n+U>UA*w|=|kB_%|d6@VE!OsP-8KN>y00000NkvXXu0mjfQ>81f delta 575 zcmV-F0>J&e1)>FzZhs$1L_t(YiN%%AYZE~f$G`9Gl(q?4sGtzj65?j7CMBLdst3J# z@an;vc=aFf;=z+3{sn^2AoL!Df6rA<<{_`S@` z+nMj@%`7ud0KoISi`Lpj9I9`OY5Bh2MocoJ_K~U2!Lr-|st7aCdk2 zAnNDy`Q^c2a9u?1kX!|@PjVxjPQNXe%fqQ5p65L!Ss06lBm-6b0pMe?So~Znm257T zy9VGs09QnQI)9Gyyi%#urh=@kt=%ShAqtXQ5Rp}q9)Jase*kQ?+wILD2)dr<-5~jZ zWCFmedcFPz$NVpultdN6|gGM{;G- z;fTCP=Q3To;k^00tyKS!-W6o6TTWSd{%; z5&3sqBsc+JpsF>Jo2^#s!+0S(Dda^MhKm5;I8F#)Kb1XNM{#*G^jR}HmvZ2LN`Bdr6ph61H!-h1=D`SQE>ewP3cMbW!vRtSQilVw@g-FKSJW`h4o?1g+KX@Ba_+75s%lJ`iiy8B9& zWlODAtMghRwOZ{)5CoMx&x-(xBu@c22jDz_VF0H9KvLJtmI2I3`h9wOI=*%5R{lyM z!^6WTk|YU^G7Sw4Rn2USYol^?Lma0M|$cl1?5DC;1dWOme}@ z<`x$hn*cO1G4XbmWs#YUNUBPz0ys^wOws_f_HjwN7k>nSxqC-aSJF-xhMOd}NVXRj z7w-YUl`B_<%xt<=t9@){H@e;KS(1se2Hbs+WY{-J>H_$a;>cBzM}0^l@&0RSP%^*D~d4tvaVNe=;JBoj%yK@e5&Q+i@KK0{|l-BnlTGBYlN*@=w4<>c@XC(clxBy^kYO0#1X#`+G(lmez zhkreiR!Gj1Y@}(r(rUFH9b69qU~FvcBS}?vACzPy&ze~UKqX0%6Fsj>+9D|cl+-2p z3&|f=R#w)IYqXE+14&aPVP;R=eGkBy{;U#9(0fAi+e z^x)r6tJO+oHZExf!25Xq&&-?Iw@XV)@n)+Oe<37_qW2`7Cwa=<-vV$Mz$nSEhvhd( zKQ^1q#(yc^SN~Oi0${2)gSuw+x4Zu==?{0GTU%Ru{5r*72qF1Rp-^xDX`|8D2B0@7 bdRYGg*Dn1MGhyDO00000NkvXXu0mjfQ-b47 delta 961 zcmV;y13vuC2%!j&ZhxLhL_t(YiH%h~ZyQGteKUJJN|fYt3>XS6+EAc7(h?Q@fdEMx zAV{gkzaf7hP1+P`-KI^WBFG;Is4hU7fS@RnM=A^=MJ62C)+fo+-b@M|9r8p=oaTUi zJNstd?Yt!bC>Dz=s`?nI5RnVVaju5L;Z?WWJq4iYJ+p+9e1E?J@O2twW{3zfnGAv; z7!pwv!0*glcU||WTCHBrLP7vgC=?zoE-pTp0EjXo!T_ME*UWs{Xf)m|FE8gj&nt__ zCNl>j@`Q+%0Ay|*PE>2PTHlU3>7SgOMB^Jg&*N-1o3qw>BJxaCOFtm;-}eguJ_~}NNJM!NSp+aQMXpvDhCk4KRg_AlB_hgOYfH>r z2C$*3A0==^M8~T7R#mT!F~jj(5&1g|!=EUr>^o*&pMN6J0uo7+$}U7?pNRIDxwf^n z)!y0JiPL$vIs$+o2wpJr({Uh<<6%l-iU178^F*Z6>2zKa0IaR8eZ$OaQ_i0! zB2QHp$A8uiMP!eNYPnplUaeMN;~pn)?!c}ATmT4FwFjUhBK3oVgHr(TegE<0?!hahwI<5m6q%QnDNo zQBzfG0P3oGR45eQRw@R#w7FrDC_Yw@tNL zeP*o>2{}Rz}0QQOKkciHVF@xJQh=4>cX8tm5kVFJk1rc2UcqJmg zI)9E+&tx)twOXwQ0IRF3b8~ZZAIEY0P((7;+H8vC6u_I&don*94$U~q%-ZYqCLX17 zx%{Z#?{6^kr_8*ms!uUyJ9o;kA;YxhUCKTC`z{-ub_r$J*( jUqsHsFg%;}z-jRxH8sv)OjXS600000NkvXXu0mjfc<8`G diff --git a/rtdata/languages/default b/rtdata/languages/default index 4f0dae8f7..d83171de2 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -657,6 +657,7 @@ HISTORY_MSG_423;Retinex - Gamma slope HISTORY_MSG_424;Retinex - HL threshold HISTORY_MSG_425;Retinex - Log base HISTORY_MSG_426;Retinex - Hue equalizer +HISTORY_MSG_427;Output rendering intent HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h index 6b41987f7..8b6e6465c 100644 --- a/rtengine/iccstore.h +++ b/rtengine/iccstore.h @@ -91,7 +91,7 @@ public: // Main monitors standard profile name, from OS void findDefaultMonitorProfile (); cmsHPROFILE getDefaultMonitorProfile () const; - Glib::ustring getDefaultMonitorProfileStr () const; + Glib::ustring getDefaultMonitorProfileName () const; cmsHPROFILE workingSpace (const Glib::ustring& name) const; cmsHPROFILE workingSpaceGamma (const Glib::ustring& name) const; @@ -135,7 +135,7 @@ inline cmsHPROFILE ICCStore::getDefaultMonitorProfile () const return getProfile (defaultMonitorProfile); } -inline Glib::ustring ICCStore::getDefaultMonitorProfileStr () const +inline Glib::ustring ICCStore::getDefaultMonitorProfileName () const { return defaultMonitorProfile; } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 62de26076..8d700a0cc 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1138,7 +1138,7 @@ void ImProcCoordinator::setSoftProofing (bool softProof) softProofing = softProof; } -void ImProcCoordinator::setMonitorProfile (Glib::ustring profile, eRenderingIntent intent) +void ImProcCoordinator::setMonitorProfile (Glib::ustring profile, RenderingIntent intent) { if (profile != monitorProfile) { monitorProfile = profile; @@ -1150,7 +1150,7 @@ void ImProcCoordinator::setMonitorProfile (Glib::ustring profile, eRenderingInte } } -void ImProcCoordinator::getMonitorProfile (Glib::ustring &profile, eRenderingIntent &intent) +void ImProcCoordinator::getMonitorProfile (Glib::ustring &profile, RenderingIntent &intent) { profile = monitorProfile; intent = monitorIntent; diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 901804eba..31f9543b6 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -74,7 +74,7 @@ protected: Glib::ustring monitorProfile; - eRenderingIntent monitorIntent; + RenderingIntent monitorIntent; int scale; bool highDetailPreprocessComputed; @@ -256,8 +256,8 @@ public: void getSpotWB (int x, int y, int rectSize, double& temp, double& green); void getAutoCrop (double ratio, int &x, int &y, int &w, int &h); - void setMonitorProfile (Glib::ustring profile, eRenderingIntent intent); - void getMonitorProfile (Glib::ustring &profile, eRenderingIntent &intent); + void setMonitorProfile (Glib::ustring profile, RenderingIntent intent); + void getMonitorProfile (Glib::ustring &profile, RenderingIntent &intent); void setSoftProofing (bool softProof); bool updateTryLock () diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 18b5eed6d..18ffc0e8d 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -188,7 +188,7 @@ void ImProcFunctions::CAT02 (Imagefloat* baseImg, const ProcParams* params) */ -void ImProcFunctions::updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, eRenderingIntent monitorIntent, bool softProofing) +void ImProcFunctions::updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, RenderingIntent monitorIntent, bool softProofing) { // set up monitor transform if (monitorTransform != NULL) { diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index c34219c0d..af49cb937 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -233,7 +233,7 @@ public: bool needsPCVignetting (); void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16); - void updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, eRenderingIntent monitorIntent, bool softProofing); + void updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, RenderingIntent monitorIntent, bool softProofing); void rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *editBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf); @@ -380,9 +380,9 @@ public: void Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad); void BadpixelsLab(LabImage * src, LabImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom); - Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool standard_gamma); - Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw);// for gamma output - Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool bw);//without gamma ==>default + Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool standard_gamma); + Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw);// for gamma output + Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool bw);//without gamma ==>default // CieImage *ciec; 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, const LCPMapper *pLCPMap = NULL); diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index a727423ef..a53bdb8e1 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -134,7 +134,7 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image, bool softPro } } -Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool standard_gamma) +Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool standard_gamma) { //gamutmap(lab); @@ -259,7 +259,7 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, return image; } // for default (not gamma) -Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, bool bw) +Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool bw) { //gamutmap(lab); @@ -363,7 +363,7 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int // for gamma options (BT709...sRGB linear...) -Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, eRenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw) +Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw) { //gamutmap(lab); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index cbbbed7a5..1103d274d 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -42,13 +42,13 @@ class WavOpacityCurveW; class WavOpacityCurveWL; class RetinextransmissionCurve; -typedef enum RenderingIntent { +enum RenderingIntent { RI_PERCEPTUAL = INTENT_PERCEPTUAL, RI_RELATIVE = INTENT_RELATIVE_COLORIMETRIC, RI_SATURATION = INTENT_SATURATION, RI_ABSOLUTE = INTENT_ABSOLUTE_COLORIMETRIC, RI__COUNT -} eRenderingIntent; +}; namespace procparams { @@ -950,7 +950,7 @@ public: int dcpIlluminant; Glib::ustring working; Glib::ustring output; - eRenderingIntent outputIntent; + RenderingIntent outputIntent; static const Glib::ustring NoICMString; Glib::ustring gamma; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index d10acb561..0c6999158 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -416,8 +416,8 @@ public: virtual void setRetinexListener (RetinexListener* l) = 0; virtual void setWaveletListener (WaveletListener* l) = 0; - virtual void setMonitorProfile (Glib::ustring monitorProfile, eRenderingIntent intent) = 0; - virtual void getMonitorProfile (Glib::ustring &monitorProfile, eRenderingIntent &intent) = 0; + virtual void setMonitorProfile (Glib::ustring monitorProfile, RenderingIntent intent) = 0; + virtual void getMonitorProfile (Glib::ustring &monitorProfile, RenderingIntent &intent) = 0; virtual void setSoftProofing (bool softProof) = 0; virtual ~StagedImageProcessor () {} diff --git a/rtengine/settings.h b/rtengine/settings.h index 98c85ba6f..3e9c9d38a 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -39,7 +39,7 @@ public: int leveldnautsimpl; // STD or EXPERT Glib::ustring monitorProfile; ///< ICC profile name used for the monitor - eRenderingIntent monitorIntent; ///< Colorimetric intent used with the above profile + RenderingIntent monitorIntent; ///< Colorimetric intent used with the above profile bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile bool autocielab; bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index f27e27467..518b5ad8d 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -62,7 +62,7 @@ private: profileBox->append_text (M("PREFERENCES_PROFILE_NONE")); #if defined(WIN32) - profileBox->append_text (M("MONITOR_PROFILE_SYSTEM") + " (" + rtengine::iccStore->getDefaultMonitorProfileStr() + ")"); + profileBox->append_text (M("MONITOR_PROFILE_SYSTEM") + " (" + rtengine::iccStore->getDefaultMonitorProfileName() + ")"); profileBox->set_active (options.rtSettings.autoMonitorProfile ? 1 : 0); #else profileBox->set_active (0); @@ -77,8 +77,7 @@ private: void prepareIntentBox () { - PopUpButton *bt = new PopUpButton(Glib::ustring(), true); - intentBox = Gtk::manage(bt); + intentBox = Gtk::manage(new PopUpButton(Glib::ustring(), true)); intentBox->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); intentBox->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); intentBox->addEntry("intent-absolute.png", M("PREFERENCES_INTENT_ABSOLUTE")); @@ -90,6 +89,7 @@ private: void softProofToggled () { if (processor) { + processor->beginUpdateParams (); processor->setSoftProofing( softProof->get_active() ); processor->endUpdateParams ( rtengine::EvMonitorTransform ); } @@ -106,7 +106,7 @@ private: profileBox->set_tooltip_text(profileBox->get_active_text ()); #ifdef WIN32 if (profileBox->get_active_row_number () == 1) { - profile = rtengine::iccStore->getDefaultMonitorProfileStr (); + profile = rtengine::iccStore->getDefaultMonitorProfileName (); if (profile.empty()) { profile = options.rtSettings.monitorProfile; } @@ -152,7 +152,15 @@ private: softProof->set_sensitive(true); } - rtengine::eRenderingIntent intent = intentBox->getSelected() > 0 ? (intentBox->getSelected() == 1 ? rtengine::RI_PERCEPTUAL : rtengine::RI_ABSOLUTE) : rtengine::RI_RELATIVE; + rtengine::RenderingIntent intent = rtengine::RI_PERCEPTUAL; + switch (intentBox->getSelected()) { + case (0): + intent = rtengine::RI_RELATIVE; + break; + case (2): + intent = rtengine::RI_ABSOLUTE; + break; + } if (!processor) { return; @@ -165,10 +173,20 @@ private: // ...or store them locally processor->beginUpdateParams (); if (options.rtSettings.verbose) { - printf("Monitor profile: %s, Intent: %s)\n", - profile.empty() ? "None" : profile.c_str(), - intent > 0 ? M("PREFERENCES_INTENT_PERCEPTUAL").c_str() : M("PREFERENCES_INTENT_RELATIVE").c_str() - ); + Glib::ustring intentName; + switch (intent) { + case (0): + intentName = M("PREFERENCES_INTENT_RELATIVE"); + break; + case (1): + intentName = M("PREFERENCES_INTENT_PERCEPTUAL"); + break; + case (2): + default: // to avoid complains from gcc + intentName = M("PREFERENCES_INTENT_ABSOLUTE"); + break; + } + printf("Monitor profile: %s, Intent: %s)\n", profile.empty() ? "None" : profile.c_str(), intentName.c_str()); } processor->setMonitorProfile(profile, intent); processor->endUpdateParams (rtengine::EvMonitorTransform); @@ -185,7 +203,6 @@ public: reset (); } - // HOMBRE: renamed to 'pack_end_in', because 'pack_end' already widely used by Gtk::Widget in a different way void pack_end_in (Gtk::Box* box) { box->pack_end (*softProof, Gtk::PACK_SHRINK, 0); diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index 8b2965cab..d24ec9312 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -292,7 +292,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch wnames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::wpChanged) ); onames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) ); - ointent->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) ); + ointent->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::oiChanged) ); wgamma->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::gpChanged) ); dcpIll->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::dcpIlluminantChanged) ); @@ -623,7 +623,7 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) int ointentVal = ointent->get_active_row_number(); if (ointentVal >= 0 && ointentVal < RI__COUNT) { - pp->icm.outputIntent = static_cast(ointentVal); + pp->icm.outputIntent = static_cast(ointentVal); } else { pp->icm.outputIntent = rtengine::RI_PERCEPTUAL; } @@ -900,7 +900,15 @@ void ICMPanel::opChanged () { if (listener) { - listener->panelChanged (EvOProfile, Glib::ustring(onames->get_active_text())+Glib::ustring("\n")+ointent->get_active_text()); + listener->panelChanged (EvOProfile, onames->get_active_text()); + } +} + +void ICMPanel::oiChanged () +{ + + if (listener) { + listener->panelChanged (EvOIntent, ointent->get_active_text()); } } diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index e10f42b20..863e88a46 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -108,6 +108,7 @@ public: void wpChanged (); void opChanged (); + void oiChanged (); void ipChanged (); void gpChanged (); void GamChanged (); diff --git a/rtgui/options.cc b/rtgui/options.cc index 1ffc74e2b..c2e31ec38 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -1462,7 +1462,7 @@ int Options::readFromFile (Glib::ustring fname) } if (keyFile.has_key ("Color Management", "Intent")) { - rtSettings.monitorIntent = static_cast(keyFile.get_integer("Color Management", "Intent")); + rtSettings.monitorIntent = static_cast(keyFile.get_integer("Color Management", "Intent")); } if (keyFile.has_key ("Color Management", "CRI")) { @@ -1714,7 +1714,7 @@ int Options::readFromFile (Glib::ustring fname) } if (keyFile.has_key ("Fast Export", "fastexport_icm_output_intent" )) { - fastexport_icm_outputIntent = static_cast(keyFile.get_integer ("Fast Export", "fastexport_icm_output_intent" )); + fastexport_icm_outputIntent = static_cast(keyFile.get_integer ("Fast Export", "fastexport_icm_output_intent" )); } if (keyFile.has_key ("Fast Export", "fastexport_icm_gamma" )) { diff --git a/rtgui/options.h b/rtgui/options.h index 969b66642..b896f4129 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -264,7 +264,7 @@ public: Glib::ustring fastexport_icm_input; Glib::ustring fastexport_icm_working; Glib::ustring fastexport_icm_output; - rtengine::eRenderingIntent fastexport_icm_outputIntent; + rtengine::RenderingIntent fastexport_icm_outputIntent; Glib::ustring fastexport_icm_gamma; bool fastexport_resize_enabled; double fastexport_resize_scale; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 4551b6bad..68f8206e1 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -705,7 +705,8 @@ Gtk::Widget* Preferences::getColorManagementPanel () monIntent->append_text (M("PREFERENCES_INTENT_RELATIVE")); monIntent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); - monIntent->set_active (0); + monIntent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); + monIntent->set_active (1); iccDir->signal_selection_changed ().connect (sigc::mem_fun (this, &Preferences::iccDirChanged)); @@ -1446,7 +1447,18 @@ void Preferences::storePreferences () #if !defined(__APPLE__) // monitor profile not supported on apple moptions.rtSettings.monitorProfile = monProfile->get_active_text (); - moptions.rtSettings.monitorIntent = monIntent->get_active_row_number () > 0 ? rtengine::RI_PERCEPTUAL : rtengine::RI_RELATIVE; + switch (monIntent->get_active_row_number ()) { + case (0): + moptions.rtSettings.monitorIntent = rtengine::RI_RELATIVE; + break; + case (2): + moptions.rtSettings.monitorIntent = rtengine::RI_ABSOLUTE; + break; + case (1): + default: + moptions.rtSettings.monitorIntent = rtengine::RI_PERCEPTUAL; + break; + } #if defined(WIN32) moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active (); #endif @@ -1565,7 +1577,18 @@ void Preferences::fillPreferences () #if !defined(__APPLE__) // monitor profile not supported on apple setActiveTextOrIndex (*monProfile, moptions.rtSettings.monitorProfile, 0); - monIntent->set_active (moptions.rtSettings.monitorIntent == INTENT_PERCEPTUAL ? 1 : 0); + switch (moptions.rtSettings.monitorIntent) { + case(0) : + monIntent->set_active (0); + break; + case(2) : + monIntent->set_active (2); + break; + case(1) : + default: + monIntent->set_active (1); + break; + } #if defined(WIN32) cbAutoMonProfile->set_active(moptions.rtSettings.autoMonitorProfile); #endif diff --git a/tools/source_icons/scalable/intent-absolute.svg b/tools/source_icons/scalable/intent-absolute.svg index 799deffc0..b5092b0c5 100644 --- a/tools/source_icons/scalable/intent-absolute.svg +++ b/tools/source_icons/scalable/intent-absolute.svg @@ -15,7 +15,7 @@ id="svg2" sodipodi:version="0.32" inkscape:version="0.91 r13725" - sodipodi:docname="intent-absolute.svg" + sodipodi:docname="intent-absolute-3.svg" inkscape:export-filename="/home/philippe/devel/rawtherapee/icons/NewIcons/distorsion.png" inkscape:export-xdpi="1.98" inkscape:export-ydpi="1.98" @@ -27,9 +27,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="0.28397906" - inkscape:cx="497.94487" - inkscape:cy="-71.539587" + inkscape:zoom="0.5" + inkscape:cx="400" + inkscape:cy="350" inkscape:document-units="px" inkscape:current-layer="svg2" showguides="true" @@ -47,7 +47,13 @@ inkscape:bbox-nodes="true" inkscape:snap-bbox-edge-midpoints="true" inkscape:snap-bbox-midpoints="true" - inkscape:snap-global="false" /> + inkscape:snap-global="true" + inkscape:object-paths="false" + inkscape:snap-intersection-paths="false" + inkscape:object-nodes="true" + inkscape:snap-smooth-nodes="false" + inkscape:snap-midpoints="false" + inkscape:snap-nodes="true" /> - + id="path5187" + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#2a7fff;stroke-width:50;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 39.8267,50 c 372.08564,0 376.87989,202 720.3466,202 M 39.8267,150 c 372.08564,0 376.87989,102 720.3466,102 m -720.346599,0 720.346599,0" /> - - - + id="path5189" + style="opacity:0.7;fill:none;fill-rule:evenodd;stroke:#2a7fff;stroke-width:50;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 39.826704,649.33407 C 408.29238,649.33407 404.24771,550 760.1733,550 m -720.346599,0 720.346599,0" /> diff --git a/tools/source_icons/scalable/intent-relative.svg b/tools/source_icons/scalable/intent-relative.svg index 1cd7135f2..706de23d1 100644 --- a/tools/source_icons/scalable/intent-relative.svg +++ b/tools/source_icons/scalable/intent-relative.svg @@ -15,7 +15,7 @@ id="svg2" sodipodi:version="0.32" inkscape:version="0.91 r13725" - sodipodi:docname="intent-relative.svg" + sodipodi:docname="intent-relative-3.svg" inkscape:export-filename="/home/philippe/devel/rawtherapee/icons/NewIcons/distorsion.png" inkscape:export-xdpi="1.98" inkscape:export-ydpi="1.98" @@ -27,9 +27,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="0.20080352" - inkscape:cx="1490.3375" - inkscape:cy="469.77917" + inkscape:zoom="0.40160704" + inkscape:cx="315.89751" + inkscape:cy="196.7604" inkscape:document-units="px" inkscape:current-layer="svg2" showguides="true" @@ -47,7 +47,14 @@ inkscape:bbox-nodes="true" inkscape:snap-bbox-edge-midpoints="true" inkscape:snap-bbox-midpoints="true" - inkscape:snap-global="false" /> + inkscape:snap-global="true" + inkscape:object-paths="false" + inkscape:snap-intersection-paths="false" + inkscape:object-nodes="true" + inkscape:snap-smooth-nodes="false" + inkscape:snap-midpoints="false" + inkscape:snap-nodes="true" + inkscape:snap-page="false" /> + id="clipPath7774"> + + + + d="m -48.208488,-24.69248 0,219.02655 896.416978,0 0,-219.02655 -896.416978,0 z" + id="path7780" + inkscape:connector-curvature="0" /> image/svg+xml - + - - - - - - + d="m 39.826704,649.33407 c 368.465676,0 364.421006,-201.42391 720.346596,-201.42391 M 39.8267,50 c 372.08564,0 376.87989,99.91016 720.3466,99.91016 M 39.8267,150 c 372.08564,0 376.87989,-0.0898 720.3466,-0.0898 M 39.826701,550 C 403.19705,550 404.27294,447.91016 760.1733,447.91016 M 39.826701,450 C 405.68704,450 405.51794,347.91016 760.1733,347.91016 M 39.826701,252 C 411.99422,252 414.41617,149.91016 760.1733,149.91016 M 39.826701,350 C 410.66703,350 410.49793,247.91016 760.1733,247.91016" /> From 31eef891185da3e832918d09f5b77a95bd66abe5 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Mon, 28 Dec 2015 18:05:46 +0100 Subject: [PATCH 47/61] Use the LOCAL_SISO* constants to determine the language name on Windows to support systems older than Vista. --- rtgui/multilangmgr.cc | 62 +++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/rtgui/multilangmgr.cc b/rtgui/multilangmgr.cc index 37dcb5e3c..509a53923 100644 --- a/rtgui/multilangmgr.cc +++ b/rtgui/multilangmgr.cc @@ -123,14 +123,7 @@ bool MultiLangMgr::save (Glib::ustring fname) bool MultiLangMgr::isOSLanguageDetectSupported() { -#ifdef WIN32 -#ifdef __MINGW64_VERSION_MAJOR - // Only on Vista or above - return LOBYTE(LOWORD(GetVersion())) >= 6; -#else - return false; -#endif -#elif defined(__linux__) || defined(__APPLE__) +#if defined(WIN32) || defined(__linux__) || defined(__APPLE__) return true; #else return false; @@ -141,37 +134,38 @@ bool MultiLangMgr::isOSLanguageDetectSupported() // returns Language name mapped from the currently selected OS language Glib::ustring MultiLangMgr::getOSUserLanguage() { - Glib::ustring langName = Glib::ustring("default"); + Glib::ustring langName ("default"); - if (isOSLanguageDetectSupported()) { +#if defined(WIN32) -#ifdef WIN32 -// When using old versions of MINGW this is not defined -#ifdef __MINGW64_VERSION_MAJOR - WCHAR langRFCU[64] = {0}; + const LCID localeID = GetUserDefaultLCID (); + TCHAR localeName[18]; - if (GetUserDefaultLocaleName(langRFCU, 64) != 0 && lstrlenW(langRFCU) >= 2) { - // convert UNICODE16 to GTK - char langRFC[64]; - WideCharToMultiByte(CP_UTF8, 0, langRFCU, -1, langRFC, 64, 0, 0); - Glib::ustring localRFC = Glib::ustring(langRFC); - - langName = TranslateRFC2Language(localRFC); - } - -#endif -#elif defined(__linux__) || defined(__APPLE__) - char *tmplocale; - tmplocale = setlocale(LC_CTYPE, ""); - setlocale(LC_NUMERIC, "C"); // to set decimal point to "." - - if(tmplocale) { - langName = TranslateRFC2Language(tmplocale); - } - -#endif + const int langLen = GetLocaleInfo (localeID, LOCALE_SISO639LANGNAME, localeName, 9); + if (langLen <= 0) { + return langName; } + localeName[langLen - 1] = '-'; + + const int countryLen = GetLocaleInfo (localeID, LOCALE_SISO3166CTRYNAME, localeName + langLen, 9); + if (countryLen <= 0) { + return langName; + } + + langName = TranslateRFC2Language (localeName); + +#elif defined(__linux__) || defined(__APPLE__) + + const char* locale = setlocale(LC_CTYPE, ""); + setlocale(LC_NUMERIC, "C"); // to set decimal point to "." + + if (locale) { + langName = TranslateRFC2Language (locale); + } + +#endif + return langName; } From 79a1c19c60ccbbcf3dd934d222de8b2c2565ca90 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Thu, 12 Nov 2015 17:11:56 +0100 Subject: [PATCH 48/61] Fix issue #2905 by using the file chooser's selected instead of the current folder. --- rtgui/batchqueuepanel.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index db78913b0..826fdf422 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -333,8 +333,8 @@ void BatchQueuePanel::pathFolderButtonPressed () int result = fc.run(); if (result == Gtk::RESPONSE_OK) { - if (safe_file_test(fc.get_current_folder(), Glib::FILE_TEST_IS_DIR)) { - options.savePathFolder = fc.get_current_folder(); + if (safe_file_test(fc.get_filename(), Glib::FILE_TEST_IS_DIR)) { + options.savePathFolder = fc.get_filename(); outdirFolderButton->set_label(makeFolderLabel(options.savePathFolder)); } } From b343b9a7b3bd13c5b37155296efe703fd2168d8e Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Tue, 29 Dec 2015 17:42:14 +0100 Subject: [PATCH 49/61] Also change the currently Windows-specific code path for selecting the output folder in the batch queue. --- rtgui/batchqueuepanel.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc index 826fdf422..e4400d449 100644 --- a/rtgui/batchqueuepanel.cc +++ b/rtgui/batchqueuepanel.cc @@ -345,7 +345,7 @@ void BatchQueuePanel::pathFolderButtonPressed () void BatchQueuePanel::pathFolderChanged () { - options.savePathFolder = outdirFolder->get_current_folder(); + options.savePathFolder = outdirFolder->get_filename(); } void BatchQueuePanel::formatChanged (Glib::ustring f) From 5fd5d5bece84b0930a8aa96e6b83ce4b5194a2b2 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Fri, 1 Jan 2016 19:43:09 +0100 Subject: [PATCH 50/61] Remove the soft proof button and internal flag as it was decided not to mix this with the output profile handling. --- rtengine/dcrop.cc | 38 +----- rtengine/dcrop.h | 5 - rtengine/improccoordinator.cc | 12 +- rtengine/improccoordinator.h | 2 - rtengine/improcfun.cc | 52 +------- rtengine/improcfun.h | 4 +- rtengine/iplab2rgb.cc | 4 +- rtengine/procevents.h | 3 +- rtengine/refreshmap.cc | 1 - rtengine/rtengine.h | 1 - rtgui/editorpanel.cc | 218 +++++++++++++++------------------- rtgui/editorpanel.h | 3 +- rtgui/guiutils.h | 16 +++ rtgui/popupcommon.cc | 1 - 14 files changed, 121 insertions(+), 239 deletions(-) diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index cd68aa0a6..2220f68c5 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -33,7 +33,7 @@ extern const Settings* settings; Crop::Crop (ImProcCoordinator* parent, EditDataProvider *editDataProvider, bool isDetailWindow) : EditBuffer(editDataProvider), origCrop(NULL), laboCrop(NULL), labnCrop(NULL), cropImg(NULL), cbuf_real(NULL), cshmap(NULL), transCrop(NULL), cieCrop(NULL), cbuffer(NULL), - softProofing(false), updating(false), newUpdatePending(false), skip(10), + updating(false), newUpdatePending(false), skip(10), cropx(0), cropy(0), cropw(-1), croph(-1), trafx(0), trafy(0), trafw(-1), trafh(-1), rqcropx(0), rqcropy(0), rqcropw(-1), rqcroph(-1), @@ -987,42 +987,8 @@ void Crop::update (int todo) EditBuffer::setReady(); // switch back to rgb - parent->ipf.lab2monitorRgb (labnCrop, cropImg, softProofing); + parent->ipf.lab2monitorRgb (labnCrop, cropImg); - //parent->ipf.lab2monitorRgb (laboCrop, cropImg); - - //cropImg = baseCrop->to8(); - /* - // int xref,yref; - xref=000;yref=000; - if (colortest && cropw>115 && croph>115) - for(int j=1;j<5;j++){ - xref+=j*30;yref+=j*30; - int rlin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))]/255.0) * 255.0); - int glin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+1]/255.0) * 255.0); - int blin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+2]/255.0) * 255.0); - - printf("after lab2rgb RGB lab2 Xr%i Yr%i Skip=%d R=%d G=%d B=%d \n",xref,yref,skip, - rlin,glin,blin); - //cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))], - //cropImg->data[(3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+1)], - //cropImg->data[(3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+2)]); - //printf("after lab2rgb Lab lab2 Xr%i Yr%i Skip=%d l=%f a=%f b=%f \n",xref,yref,skip, labnCrop->L[(int)(xref/skip)][(int)(yref/skip)]/327,labnCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327,labnCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327); - printf("after lab2rgb Lab Xr%i Yr%i Skip=%d l=%f a=%f b=%f \n",xref,yref,skip, - labnCrop->L[(int)(xref/skip)][(int)(yref/skip)]/327, - labnCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327, - labnCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327)q; - } - */ - /* - if (colortest && cropImg->height>115 && cropImg->width>115) {//for testing - xref=000;yref=000; - printf("dcrop final R= %d G= %d B= %d \n", - cropImg->data[3*xref/(skip)*(cropImg->width+1)], - cropImg->data[3*xref/(skip)*(cropImg->width+1)+1], - cropImg->data[3*xref/(skip)*(cropImg->width+1)+2]); - } - */ if (cropImageListener) { // this in output space held in parallel to allow analysis like shadow/highlight Glib::ustring outProfile = params.icm.output; diff --git a/rtengine/dcrop.h b/rtengine/dcrop.h index ea9b1bc00..57f388a51 100644 --- a/rtengine/dcrop.h +++ b/rtengine/dcrop.h @@ -54,7 +54,6 @@ protected: // ----------------------------------------------------------------- float** cbuffer; - bool softProofing; /// True if the Crop has to display a soft proof of the output with its profile bool updating; /// Flag telling if an updater thread is currently processing bool newUpdatePending; /// Flag telling the updater thread that a new update is pending int skip; @@ -104,10 +103,6 @@ public: /** @brief Asynchronously reprocess the detailed crop */ void fullUpdate (); // called via thread - void setSoftProofing(bool doSoftProof) { - softProofing = doSoftProof; - } - void setListener (DetailedCropListener* il); void destroy (); int get_skip () diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 8d700a0cc..63ca9c5d0 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -33,7 +33,7 @@ ImProcCoordinator::ImProcCoordinator () : orig_prev(NULL), oprevi(NULL), oprevl(NULL), nprevl(NULL), previmg(NULL), workimg(NULL), ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), monitorIntent(RI_PERCEPTUAL), scale(10), highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), isColorProfileDirty(true), - softProofing(false), bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.), + bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.), hltonecurve(65536), shtonecurve(65536), @@ -783,14 +783,13 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) // Update the output color transform if necessary if (isColorProfileDirty || (todo & M_MONITOR)) { - ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent, softProofing); + ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent); isColorProfileDirty = false; } // process crop, if needed for (size_t i = 0; i < crops.size(); i++) if (crops[i]->hasListener () && cropCall != crops[i] ) { - crops[i]->setSoftProofing(softProofing); crops[i]->update (todo); // may call ourselves } @@ -805,7 +804,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) MyMutex::MyLock prevImgLock(previmg->getMutex()); try { - ipf.lab2monitorRgb (nprevl, previmg, softProofing); + ipf.lab2monitorRgb (nprevl, previmg); delete workimg; Glib::ustring outProfile = params.icm.output; @@ -1133,11 +1132,6 @@ void ImProcCoordinator::getAutoCrop (double ratio, int &x, int &y, int &w, int & y = (fullh - h) / 2; } -void ImProcCoordinator::setSoftProofing (bool softProof) -{ - softProofing = softProof; -} - void ImProcCoordinator::setMonitorProfile (Glib::ustring profile, RenderingIntent intent) { if (profile != monitorProfile) { diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 31f9543b6..78d3dca7f 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -82,7 +82,6 @@ protected: bool allocated; bool isColorProfileDirty; - bool softProofing; void freeAll (); @@ -258,7 +257,6 @@ public: void setMonitorProfile (Glib::ustring profile, RenderingIntent intent); void getMonitorProfile (Glib::ustring &profile, RenderingIntent &intent); - void setSoftProofing (bool softProof); bool updateTryLock () { diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 18ffc0e8d..b1f47c3a9 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -140,55 +140,8 @@ void ImProcFunctions::firstAnalysisThread (Imagefloat* original, Glib::ustring w } } } -/* -void ImProcFunctions::CAT02 (Imagefloat* baseImg, const ProcParams* params) -{ - const double toxyz[3][3] = {{0.7976749, 0.1351917, 0.0313534}, - {0.2880402, 0.7118741, 0.0000857}, - {0.0000000, 0.0000000, 0.8252100}}; - const double xyzto[3][3] = {{1.3459433, -0.2556075, -0.0511118}, - {-0.5445989, 1.5081673, 0.0205351}, - {0.0000000, 0.0000000, 1.2118128}}; - int fw = baseImg->width; - int fh = baseImg->height; - - double CAM02BB00,CAM02BB01,CAM02BB02,CAM02BB10,CAM02BB11,CAM02BB12,CAM02BB20,CAM02BB21,CAM02BB22; - double Xxx,Yyy,Zzz; - // Xxx=1.09844; - // Yyy=1.0; - // Zzz=0.355961; - //params.wb.temperature, params.wb.green, params.wb.method - double Xxyz, Zxyz; -// ColorTemp::temp2mulxyz (params->wb.temperature, params->wb.green, params->wb.method, Xxyz, Zxyz); - ColorTemp::temp2mulxyz (5000.0, 1.0, "Camera", Xxyz, Zxyz); - - ColorTemp::cieCAT02(Xxx, Yyy, Zzz, CAM02BB00,CAM02BB01,CAM02BB02,CAM02BB10,CAM02BB11,CAM02BB12,CAM02BB20,CAM02BB21,CAM02BB22); - printf("00=%f 01=%f 11=%f 20=%f 22=%f\n", CAM02BB00,CAM02BB01,CAM02BB11,CAM02BB20,CAM02BB22); - - - for (int i=0; ir(i,j); - float g = baseImg->g(i,j); - float b = baseImg->b(i,j); - - float x = toxyz[0][0] * r + toxyz[0][1] * g + toxyz[0][2] * b; - float y = toxyz[1][0] * r + toxyz[1][1] * g + toxyz[1][2] * b; - float z = toxyz[2][0] * r + toxyz[2][1] * g + toxyz[2][2] * b; - float Xcam=CAM02BB00* x +CAM02BB01* y + CAM02BB02* z ; - float Ycam=CAM02BB10* x +CAM02BB11* y + CAM02BB12* z ; - float Zcam=CAM02BB20* x +CAM02BB21* y + CAM02BB22* z ; - baseImg->r(i,j) = xyzto[0][0] * Xcam + xyzto[0][1] * Ycam + xyzto[0][2] * Zcam; - baseImg->g(i,j) = xyzto[1][0] * Xcam + xyzto[1][1] * Ycam + xyzto[1][2] * Zcam; - baseImg->b(i,j) = xyzto[2][0] * Xcam + xyzto[2][1] * Ycam + xyzto[2][2] * Zcam; - } - } -} -*/ - - -void ImProcFunctions::updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, RenderingIntent monitorIntent, bool softProofing) +void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent) { // set up monitor transform if (monitorTransform != NULL) { @@ -224,9 +177,6 @@ void ImProcFunctions::updateColorProfiles (const ColorManagementParams &icm, Gli cmsHPROFILE jprof = iccStore->getProfile(outputProfile); if (jprof) { - //TODO: Create a dedicated softproof transformation (line below to be finished) - //lab2outputTransform = cmsCreateProofingTransform(iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, monitor, icm.outputIntent, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE | cmsFLAGS_SOFTPROOFING ); - lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, icm.outputIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); } diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index af49cb937..ec81f26eb 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -233,7 +233,7 @@ public: bool needsPCVignetting (); void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16); - void updateColorProfiles (const ColorManagementParams &icm, Glib::ustring monitorProfile, RenderingIntent monitorIntent, bool softProofing); + void updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent); void rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *editBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf); @@ -266,7 +266,7 @@ public: void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, double focalLen, double focalLen35mm, float focusDist, int rawRotationDeg, bool fullImage); float resizeScale (const ProcParams* params, int fw, int fh, int &imw, int &imh); - void lab2monitorRgb (LabImage* lab, Image8* image, bool softProofing=false); + void lab2monitorRgb (LabImage* lab, Image8* image); void resize (Image16* src, Image16* dst, float dScale); void Lanczos (const LabImage* src, LabImage* dst, float scale); void Lanczos (const Image16* src, Image16* dst, float scale); diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index a53bdb8e1..c36e185d0 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -39,7 +39,7 @@ const double (*iwprof[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz, const char* wprofnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB"}; const int numprof = 7; -void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image, bool softProofing) +void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) { //gamutmap(lab); @@ -78,7 +78,7 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image, bool softPro buffer[iy++] = rb[j] / 327.68f; } - if (softProofing && !settings->HistogramWorking && output2monitorTransform && lab2outputTransform) { + if (!settings->HistogramWorking && output2monitorTransform && lab2outputTransform) { AlignedBuffer buf(3 * W); cmsDoTransform (lab2outputTransform, buffer, buf.data, W); cmsDoTransform (output2monitorTransform, buf.data, data + ix, W); diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 4609c674a..21ecf5a83 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -455,8 +455,7 @@ enum ProcEvent { // EvLgrbl = 425, EvRetinexlhcurve = 425, EvOIntent = 426, - EvSoftProof = 427, - EvMonitorTransform = 428, + EvMonitorTransform = 427, NUMOFEVENTS }; } diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 37d0f52b4..f31300a64 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -455,7 +455,6 @@ int refreshmap[rtengine::NUMOFEVENTS] = { // DEMOSAIC, // EvLgrbl DEMOSAIC, // EvRetinexlhcurve ALLNORAW, // EvOIntent - ALLNORAW, // EvSoftProof MONITORTRANSFORM // EvMonitorTransform }; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 0c6999158..d20b89c33 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -418,7 +418,6 @@ public: virtual void setMonitorProfile (Glib::ustring monitorProfile, RenderingIntent intent) = 0; virtual void getMonitorProfile (Glib::ustring &monitorProfile, RenderingIntent &intent) = 0; - virtual void setSoftProofing (bool softProof) = 0; virtual ~StagedImageProcessor () {} diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 518b5ad8d..b9f123ac5 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -33,131 +33,113 @@ using namespace rtengine::procparams; -class MonitorProfileSelector +class EditorPanel::MonitorProfileSelector { private: - Gtk::ToggleButton* softProof; - MyComboBoxText* profileBox; - PopUpButton* intentBox; - sigc::connection profileConn, intentConn, softProofConn; + MyComboBoxText profileBox; + PopUpButton intentBox; + sigc::connection profileConn, intentConn; - rtengine::StagedImageProcessor* processor; + rtengine::StagedImageProcessor* const& processor; private: - void prepareSoftProofButton () - { - Gtk::Image *softProofImg = Gtk::manage (new RTImage("softProof.png")); - softProofImg->set_padding(0, 0); - softProof = Gtk::manage(new Gtk::ToggleButton()); - softProof->add(*softProofImg); - softProof->set_relief(Gtk::RELIEF_NONE); - softProof->set_tooltip_text(M("MONITOR_SOFTPROOF")); - softProofConn = softProof->signal_toggled().connect (sigc::mem_fun (this, &MonitorProfileSelector::softProofToggled)); - } - void prepareProfileBox () { - profileBox = Gtk::manage(new MyComboBoxText()); - profileBox->set_size_request(100,-1); + profileBox.set_size_request (100, -1); - profileBox->append_text (M("PREFERENCES_PROFILE_NONE")); - #if defined(WIN32) - profileBox->append_text (M("MONITOR_PROFILE_SYSTEM") + " (" + rtengine::iccStore->getDefaultMonitorProfileName() + ")"); - profileBox->set_active (options.rtSettings.autoMonitorProfile ? 1 : 0); - #else - profileBox->set_active (0); - #endif + profileBox.append_text (M("PREFERENCES_PROFILE_NONE")); +#ifdef WIN32 + profileBox.append_text (M("MONITOR_PROFILE_SYSTEM") + " (" + rtengine::iccStore->getDefaultMonitorProfileName() + ")"); + profileBox.set_active (options.rtSettings.autoMonitorProfile ? 1 : 0); +#else + profileBox.set_active (0); +#endif const std::vector profiles = rtengine::iccStore->getProfiles (); for (std::vector::const_iterator iterator = profiles.begin (); iterator != profiles.end (); ++iterator) { - profileBox->append_text (*iterator); + profileBox.append_text (*iterator); } - profileConn = profileBox->signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateParameters)); } void prepareIntentBox () { - intentBox = Gtk::manage(new PopUpButton(Glib::ustring(), true)); - intentBox->addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); - intentBox->addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); - intentBox->addEntry("intent-absolute.png", M("PREFERENCES_INTENT_ABSOLUTE")); - intentBox->setSelected(0); - intentConn = intentBox->signal_changed().connect (sigc::mem_fun (this, &MonitorProfileSelector::updateIntent)); - intentBox->show(); + intentBox.addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); + intentBox.addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); + intentBox.addEntry("intent-absolute.png", M("PREFERENCES_INTENT_ABSOLUTE")); + + intentBox.setSelected(0); + intentBox.show (); } - void softProofToggled () + void profileBoxChanged () { - if (processor) { - processor->beginUpdateParams (); - processor->setSoftProofing( softProof->get_active() ); - processor->endUpdateParams ( rtengine::EvMonitorTransform ); - } + updateParameters (); + + profileBox.set_tooltip_text (profileBox.get_active_text ()); } - void updateIntent (int i) + void intentBoxChanged (int) { - updateParameters(); + updateParameters (); } void updateParameters () { + ConnectionBlocker profileBlocker (profileConn); + ConnectionBlocker intentBlocker (intentConn); + Glib::ustring profile; - profileBox->set_tooltip_text(profileBox->get_active_text ()); + #ifdef WIN32 - if (profileBox->get_active_row_number () == 1) { + if (profileBox.get_active_row_number () == 1) { profile = rtengine::iccStore->getDefaultMonitorProfileName (); - if (profile.empty()) { + if (profile.empty ()) { profile = options.rtSettings.monitorProfile; } - if (profile.empty()) { - profile = "sRGB IEC61966-2.1"; // assuming this profile always exist on Windows + if (profile.empty ()) { + profile = "sRGB IEC61966-2.1"; } - } else if (profileBox->get_active_row_number () > 1) { - profile = profileBox->get_active_text (); + } else if (profileBox.get_active_row_number () > 1) { + profile = profileBox.get_active_text (); } #else - profile = profileBox->get_active_row_number () > 0 ? profileBox->get_active_text () : Glib::ustring(); + profile = profileBox.get_active_row_number () > 0 ? profileBox.get_active_text () : Glib::ustring (); #endif - // MonitorProfile = None , disabling everything - if (profileBox->get_active_row_number () == 0) { + if (profileBox.get_active_row_number () == 0) { + profile.clear(); - bool wasBlocked = intentConn.block(true); - intentBox->setSelected(1); - intentBox->set_sensitive (false); - intentConn.block(wasBlocked); - softProof->set_active(false); - softProof->set_sensitive(false); - wasBlocked = softProofConn.block(true); - softProofConn.block(wasBlocked); + + intentBox.set_sensitive (false); + intentBox.setSelected (0); } else { - std::uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile); - const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL; + const std::uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile); const bool supportsRelativeColorimetric = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC; + const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL; const bool supportsAbsoluteColorimetric = supportedIntents & 1 << INTENT_ABSOLUTE_COLORIMETRIC; - if (supportsPerceptual && (supportsRelativeColorimetric || supportsAbsoluteColorimetric)) { - intentBox->set_sensitive (true); - intentBox->setItemSensitivity(0, supportsRelativeColorimetric); - intentBox->setItemSensitivity(2, supportsAbsoluteColorimetric); + if (supportsPerceptual || supportsRelativeColorimetric || supportsAbsoluteColorimetric) { + intentBox.set_sensitive (true); + intentBox.setItemSensitivity(0, supportsRelativeColorimetric); + intentBox.setItemSensitivity(1, supportsPerceptual); + intentBox.setItemSensitivity(2, supportsAbsoluteColorimetric); + } else { + intentBox.set_sensitive (false); + intentBox.setSelected (0); } - else { - bool wasBlocked = intentConn.block(true); - intentBox->setSelected(supportsPerceptual ? 0 : 1); - intentBox->set_sensitive (false); - intentConn.block(wasBlocked); - } - softProof->set_sensitive(true); } - rtengine::RenderingIntent intent = rtengine::RI_PERCEPTUAL; - switch (intentBox->getSelected()) { - case (0): + rtengine::RenderingIntent intent; + switch (intentBox.getSelected ()) { + default: + case 0: intent = rtengine::RI_RELATIVE; break; - case (2): + case 1: + intent = rtengine::RI_PERCEPTUAL; + break; + case 2: intent = rtengine::RI_ABSOLUTE; break; } @@ -166,81 +148,67 @@ private: return; } - // either store them in the options file for the default value when opening the next EditorPanel - //options.rtSettings.monitorProfile = profile; - //options.rtSettings.monitorIntent = intent; - - // ...or store them locally processor->beginUpdateParams (); - if (options.rtSettings.verbose) { - Glib::ustring intentName; - switch (intent) { - case (0): - intentName = M("PREFERENCES_INTENT_RELATIVE"); - break; - case (1): - intentName = M("PREFERENCES_INTENT_PERCEPTUAL"); - break; - case (2): - default: // to avoid complains from gcc - intentName = M("PREFERENCES_INTENT_ABSOLUTE"); - break; - } - printf("Monitor profile: %s, Intent: %s)\n", profile.empty() ? "None" : profile.c_str(), intentName.c_str()); - } - processor->setMonitorProfile(profile, intent); + processor->setMonitorProfile (profile, intent); processor->endUpdateParams (rtengine::EvMonitorTransform); } public: - MonitorProfileSelector () : - processor (NULL) + MonitorProfileSelector (rtengine::StagedImageProcessor* const& ipc) : + intentBox (Glib::ustring (), true), + processor (ipc) { - prepareSoftProofButton (); prepareProfileBox (); prepareIntentBox (); reset (); + + profileConn = profileBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::profileBoxChanged)); + intentConn = intentBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::intentBoxChanged)); } void pack_end_in (Gtk::Box* box) { - box->pack_end (*softProof, Gtk::PACK_SHRINK, 0); - box->pack_end (*intentBox->buttonGroup, Gtk::PACK_SHRINK, 0); - box->pack_end (*profileBox, Gtk::PACK_SHRINK, 0); + box->pack_end (*intentBox.buttonGroup, Gtk::PACK_SHRINK, 0); + box->pack_end (profileBox, Gtk::PACK_SHRINK, 0); } void reset () { - bool wasBlocked; + ConnectionBlocker profileBlocker (profileConn); + ConnectionBlocker intentBlocker (intentConn); + #ifdef WIN32 - wasBlocked = profileConn.block(true); if (options.rtSettings.autoMonitorProfile) { - setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 1); + setActiveTextOrIndex (profileBox, options.rtSettings.monitorProfile, 1); } else { - setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 0); + setActiveTextOrIndex (profileBox, options.rtSettings.monitorProfile, 0); } - profileConn.block(wasBlocked); #else - wasBlocked = profileConn.block(true); - setActiveTextOrIndex (*profileBox, options.rtSettings.monitorProfile, 0); - profileConn.block(wasBlocked); + setActiveTextOrIndex (profileBox, options.rtSettings.monitorProfile, 0); #endif - wasBlocked = intentConn.block(true); - intentBox->setSelected(options.rtSettings.monitorIntent == rtengine::RI_RELATIVE ? 0 : options.rtSettings.monitorIntent == rtengine::RI_PERCEPTUAL ? 1 : 2); - intentConn.block(wasBlocked); - updateParameters(); - } + switch (options.rtSettings.monitorIntent) + { + default: + case rtengine::RI_RELATIVE: + intentBox.setSelected (0); + break; + case rtengine::RI_PERCEPTUAL: + intentBox.setSelected (1); + break; + case rtengine::RI_ABSOLUTE: + intentBox.setSelected (2); + break; + } - void setImageProcessor (rtengine::StagedImageProcessor* imageProc) { - processor = imageProc; + updateParameters (); } }; EditorPanel::EditorPanel (FilePanel* filePanel) - : realized(false), iHistoryShow(NULL), iHistoryHide(NULL), iTopPanel_1_Show(NULL), iTopPanel_1_Hide(NULL), iRightPanel_1_Show(NULL), iRightPanel_1_Hide(NULL), iBeforeLockON(NULL), iBeforeLockOFF(NULL), beforePreviewHandler(NULL), monitorProfile(new MonitorProfileSelector ()), beforeIarea(NULL), beforeBox(NULL), afterBox(NULL), afterHeaderBox(NULL), parent(NULL), openThm(NULL), ipc(NULL), beforeIpc(NULL), isProcessing(false), catalogPane(NULL) + : realized(false), iHistoryShow(NULL), iHistoryHide(NULL), iTopPanel_1_Show(NULL), iTopPanel_1_Hide(NULL), iRightPanel_1_Show(NULL), iRightPanel_1_Hide(NULL), iBeforeLockON(NULL), iBeforeLockOFF(NULL), beforePreviewHandler(NULL), beforeIarea(NULL), beforeBox(NULL), afterBox(NULL), afterHeaderBox(NULL), parent(NULL), openThm(NULL), ipc(NULL), beforeIpc(NULL), isProcessing(false), catalogPane(NULL) { epih = new EditorPanelIdleHelper; @@ -471,8 +439,10 @@ EditorPanel::EditorPanel (FilePanel* filePanel) iops->pack_end (*navPrev, Gtk::PACK_SHRINK, 0); } - // Monitor profile buttons iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); + + // Monitor profile buttons + monitorProfile.reset (new MonitorProfileSelector (ipc)); monitorProfile->pack_end_in (iops); editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0); @@ -732,7 +702,6 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) this->isrc = isrc; ipc = rtengine::StagedImageProcessor::create (isrc); - monitorProfile->setImageProcessor(ipc); ipc->setProgressListener (this); ipc->setPreviewImageListener (previewHandler); ipc->setPreviewScale (10); // Important @@ -783,7 +752,6 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) history->resetSnapShotNumber(); - //HOMBRE: not sure if we want to reset on opening a new image monitorProfile->reset (); } diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index ffb8a93a4..6de9928bd 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -42,8 +42,6 @@ struct EditorPanelIdleHelper { int pending; }; -class MonitorProfileSelector; - class RTWindow; class EditorPanel : public Gtk::VBox, public PParamsChangeListener, @@ -86,6 +84,7 @@ protected: Gtk::Button* navNext; Gtk::Button* navPrev; + class MonitorProfileSelector; std::auto_ptr monitorProfile; ImageAreaPanel* iareapanel; diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 80729b96b..79f050c2f 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -76,6 +76,22 @@ public: } }; +class ConnectionBlocker +{ +public: + ConnectionBlocker (sigc::connection& connection) : connection (connection) + { + wasBlocked = connection.block(); + } + ~ConnectionBlocker () + { + connection.block(wasBlocked); + } +private: + sigc::connection& connection; + bool wasBlocked; +}; + /** * @brief Glue box to control visibility of the MyExpender's content ; also handle the frame around it */ diff --git a/rtgui/popupcommon.cc b/rtgui/popupcommon.cc index 8acbd2802..f7e667219 100644 --- a/rtgui/popupcommon.cc +++ b/rtgui/popupcommon.cc @@ -55,7 +55,6 @@ PopUpCommon::~PopUpCommon () delete menu; delete buttonImage; - delete buttonGroup; } bool PopUpCommon::addEntry (const Glib::ustring& fileName, const Glib::ustring& label) From cefb22122000654ed3b2521c1efb71ba6a0395b9 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Fri, 1 Jan 2016 20:10:48 +0100 Subject: [PATCH 51/61] Remove the redundant isColorProfile dirty flag, but keep updating the monitor profile using processing parameter change events. --- rtengine/improccoordinator.cc | 21 +++++++-------------- rtengine/improccoordinator.h | 6 ++---- rtengine/rtengine.h | 4 ++-- 3 files changed, 11 insertions(+), 20 deletions(-) diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 63ca9c5d0..6ff60506b 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -32,7 +32,7 @@ extern const Settings* settings; ImProcCoordinator::ImProcCoordinator () : orig_prev(NULL), oprevi(NULL), oprevl(NULL), nprevl(NULL), previmg(NULL), workimg(NULL), ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), monitorIntent(RI_PERCEPTUAL), scale(10), - highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), isColorProfileDirty(true), + highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.), hltonecurve(65536), @@ -781,10 +781,9 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } } - // Update the output color transform if necessary - if (isColorProfileDirty || (todo & M_MONITOR)) { + // Update the monitor color transform if necessary + if (todo & M_MONITOR) { ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent); - isColorProfileDirty = false; } // process crop, if needed @@ -1132,19 +1131,13 @@ void ImProcCoordinator::getAutoCrop (double ratio, int &x, int &y, int &w, int & y = (fullh - h) / 2; } -void ImProcCoordinator::setMonitorProfile (Glib::ustring profile, RenderingIntent intent) +void ImProcCoordinator::setMonitorProfile (const Glib::ustring& profile, RenderingIntent intent) { - if (profile != monitorProfile) { - monitorProfile = profile; - isColorProfileDirty = true; - } - if (intent != monitorIntent) { - monitorIntent = intent; - isColorProfileDirty = true; - } + monitorProfile = profile; + monitorIntent = intent; } -void ImProcCoordinator::getMonitorProfile (Glib::ustring &profile, RenderingIntent &intent) +void ImProcCoordinator::getMonitorProfile (Glib::ustring& profile, RenderingIntent& intent) const { profile = monitorProfile; intent = monitorIntent; diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 78d3dca7f..4d442482e 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -81,8 +81,6 @@ protected: bool highDetailRawComputed; bool allocated; - bool isColorProfileDirty; - void freeAll (); // Precomputed values used by DetailedCrop ---------------------------------------------- @@ -255,8 +253,8 @@ public: void getSpotWB (int x, int y, int rectSize, double& temp, double& green); void getAutoCrop (double ratio, int &x, int &y, int &w, int &h); - void setMonitorProfile (Glib::ustring profile, RenderingIntent intent); - void getMonitorProfile (Glib::ustring &profile, RenderingIntent &intent); + void setMonitorProfile (const Glib::ustring& profile, RenderingIntent intent); + void getMonitorProfile (Glib::ustring& profile, RenderingIntent& intent) const; bool updateTryLock () { diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index d20b89c33..42e06406e 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -416,8 +416,8 @@ public: virtual void setRetinexListener (RetinexListener* l) = 0; virtual void setWaveletListener (WaveletListener* l) = 0; - virtual void setMonitorProfile (Glib::ustring monitorProfile, RenderingIntent intent) = 0; - virtual void getMonitorProfile (Glib::ustring &monitorProfile, RenderingIntent &intent) = 0; + virtual void setMonitorProfile (const Glib::ustring& monitorProfile, RenderingIntent intent) = 0; + virtual void getMonitorProfile (Glib::ustring& monitorProfile, RenderingIntent& intent) const = 0; virtual ~StagedImageProcessor () {} From 61f639192f32066bd6fc4498232a95a8c29ecb91 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Fri, 1 Jan 2016 20:24:10 +0100 Subject: [PATCH 52/61] Make use of the rendering intent enum in the preferences implementation as well. --- rtgui/preferences.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 68f8206e1..0033978c3 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -1448,16 +1448,16 @@ void Preferences::storePreferences () #if !defined(__APPLE__) // monitor profile not supported on apple moptions.rtSettings.monitorProfile = monProfile->get_active_text (); switch (monIntent->get_active_row_number ()) { - case (0): + default: + case 0: moptions.rtSettings.monitorIntent = rtengine::RI_RELATIVE; break; - case (2): - moptions.rtSettings.monitorIntent = rtengine::RI_ABSOLUTE; - break; - case (1): - default: + case 1: moptions.rtSettings.monitorIntent = rtengine::RI_PERCEPTUAL; break; + case 2: + moptions.rtSettings.monitorIntent = rtengine::RI_ABSOLUTE; + break; } #if defined(WIN32) moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active (); @@ -1578,16 +1578,16 @@ void Preferences::fillPreferences () #if !defined(__APPLE__) // monitor profile not supported on apple setActiveTextOrIndex (*monProfile, moptions.rtSettings.monitorProfile, 0); switch (moptions.rtSettings.monitorIntent) { - case(0) : + default: + case rtengine::RI_RELATIVE: monIntent->set_active (0); break; - case(2) : - monIntent->set_active (2); - break; - case(1) : - default: + case rtengine::RI_PERCEPTUAL: monIntent->set_active (1); break; + case rtengine::RI_ABSOLUTE: + monIntent->set_active (2); + break; } #if defined(WIN32) cbAutoMonProfile->set_active(moptions.rtSettings.autoMonitorProfile); From fd7dcf4b847adf15790024aefe7bae16f3b0d34e Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Sat, 2 Jan 2016 02:14:33 +0100 Subject: [PATCH 53/61] Implement post-resize sharpening in the partial paste dialog, fixes #3051 --- rtdata/languages/default | 1 + rtgui/partialpastedlg.cc | 10 ++++++++++ rtgui/partialpastedlg.h | 3 ++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 2df0b7fb9..494a3a186 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -833,6 +833,7 @@ PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter +PARTIALPASTE_PRSHARPENING;Post-resize sharpening PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction PARTIALPASTE_RAWCACORR_CABLUE;CA blue PARTIALPASTE_RAWCACORR_CARED;CA red diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index ec2320138..bbfdd0701 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -92,6 +92,7 @@ PartialPasteDlg::PartialPasteDlg (Glib::ustring title) finerot = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_ROTATION"))); crop = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_CROP"))); resize = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RESIZE"))); + prsharpening = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PRSHARPENING"))); perspective = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PERSPECTIVE"))); commonTrans = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COMMONTRANSFORMPARAMS"))); @@ -187,6 +188,7 @@ PartialPasteDlg::PartialPasteDlg (Glib::ustring title) vboxes[4]->pack_start (*finerot, Gtk::PACK_SHRINK, 2); vboxes[4]->pack_start (*crop, Gtk::PACK_SHRINK, 2); vboxes[4]->pack_start (*resize, Gtk::PACK_SHRINK, 2); + vboxes[4]->pack_start (*prsharpening, Gtk::PACK_SHRINK, 2); vboxes[4]->pack_start (*perspective, Gtk::PACK_SHRINK, 2); vboxes[4]->pack_start (*commonTrans, Gtk::PACK_SHRINK, 2); @@ -331,6 +333,7 @@ PartialPasteDlg::PartialPasteDlg (Glib::ustring title) finerotConn = finerot->signal_toggled().connect (sigc::bind (sigc::mem_fun(*composition, &Gtk::CheckButton::set_inconsistent), true)); cropConn = crop->signal_toggled().connect (sigc::bind (sigc::mem_fun(*composition, &Gtk::CheckButton::set_inconsistent), true)); resizeConn = resize->signal_toggled().connect (sigc::bind (sigc::mem_fun(*composition, &Gtk::CheckButton::set_inconsistent), true)); + prsharpeningConn = prsharpening->signal_toggled().connect (sigc::bind (sigc::mem_fun(*composition, &Gtk::CheckButton::set_inconsistent), true)); perspectiveConn = perspective->signal_toggled().connect (sigc::bind (sigc::mem_fun(*composition, &Gtk::CheckButton::set_inconsistent), true)); commonTransConn = commonTrans->signal_toggled().connect (sigc::bind (sigc::mem_fun(*composition, &Gtk::CheckButton::set_inconsistent), true)); @@ -628,6 +631,7 @@ void PartialPasteDlg::compositionToggled () finerotConn.block (true); cropConn.block (true); resizeConn.block (true); + prsharpeningConn.block (true); perspectiveConn.block (true); commonTransConn.block (true); @@ -637,6 +641,7 @@ void PartialPasteDlg::compositionToggled () finerot->set_active (composition->get_active ()); crop->set_active (composition->get_active ()); resize->set_active (composition->get_active ()); + prsharpening->set_active (composition->get_active ()); perspective->set_active (composition->get_active ()); commonTrans->set_active (composition->get_active ()); @@ -644,6 +649,7 @@ void PartialPasteDlg::compositionToggled () finerotConn.block (false); cropConn.block (false); resizeConn.block (false); + prsharpeningConn.block (false); perspectiveConn.block (false); commonTransConn.block (false); } @@ -814,6 +820,10 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param filterPE.resize = falsePE.resize; } + if (!prsharpening->get_active ()) { + filterPE.prsharpening = falsePE.prsharpening; + } + if (!perspective->get_active ()) { filterPE.perspective = falsePE.perspective; } diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h index 57a235f35..86f7fd1c2 100644 --- a/rtgui/partialpastedlg.h +++ b/rtgui/partialpastedlg.h @@ -87,6 +87,7 @@ public: Gtk::CheckButton* finerot; Gtk::CheckButton* crop; Gtk::CheckButton* resize; + Gtk::CheckButton* prsharpening; Gtk::CheckButton* perspective; Gtk::CheckButton* commonTrans; @@ -127,7 +128,7 @@ public: sigc::connection sharpenConn, gradsharpenConn, microcontrastConn, impdenConn, dirpyrdenConn, defringeConn, epdConn, dirpyreqConn, waveletConn, retinexConn; sigc::connection vibranceConn, chmixerConn, hsveqConn, rgbcurvesConn, chmixerbwConn, colortoningConn, filmSimulationConn; sigc::connection distortionConn, cacorrConn, vignettingConn, lcpConn; - sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, perspectiveConn, commonTransConn; + sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, prsharpeningConn, perspectiveConn, commonTransConn; sigc::connection exifchConn, iptcConn, icmConn, gamcsconn; sigc::connection df_fileConn, df_AutoSelectConn, ff_fileConn, ff_AutoSelectConn, ff_BlurRadiusConn, ff_BlurTypeConn, ff_ClipControlConn; sigc::connection raw_caredConn, raw_cablueConn, raw_ca_autocorrectConn, raw_hotpix_filtConn, raw_deadpix_filtConn, raw_linenoiseConn, raw_greenthreshConn, raw_ccStepsConn, raw_methodConn, raw_dcb_iterationsConn, raw_lmmse_iterationsConn, raw_dcb_enhanceConn, raw_exposConn, raw_preserConn, raw_blackConn; //,raw_all_enhanceConn From 15813b9fb045e8314e5a80615866754ffc1e889f Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Sat, 2 Jan 2016 12:22:32 +0100 Subject: [PATCH 54/61] Fix the missing output profile intent in ParamsEdited::set and make sure the default output intent is relative colorimetric everywhere instead of perceptual as to not change the previous behaviour. --- rtengine/improccoordinator.cc | 2 +- rtengine/procparams.cc | 17 ++++++++++++----- rtgui/icmpanel.cc | 4 ++-- rtgui/options.cc | 4 ++-- rtgui/paramsedited.cc | 1 + 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 6ff60506b..96a55989e 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -31,7 +31,7 @@ extern const Settings* settings; ImProcCoordinator::ImProcCoordinator () : orig_prev(NULL), oprevi(NULL), oprevl(NULL), nprevl(NULL), previmg(NULL), workimg(NULL), - ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), monitorIntent(RI_PERCEPTUAL), scale(10), + ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), monitorIntent(RI_RELATIVE), scale(10), highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.), diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 2c93bfd47..613334469 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -894,7 +894,7 @@ void ColorManagementParams::setDefaults() dcpIlluminant = 0; working = "ProPhoto"; output = "RT_sRGB"; - outputIntent = RI_PERCEPTUAL; + outputIntent = RI_RELATIVE; gamma = "default"; gampos = 2.22; slpos = 4.5; @@ -2551,15 +2551,22 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol if (!pedited || pedited->icm.outputIntent) { Glib::ustring intent; - if (icm.outputIntent == RI_PERCEPTUAL) { + switch (icm.outputIntent) { + default: + case RI_PERCEPTUAL: intent = "Perceptual"; - } else if (icm.outputIntent == RI_RELATIVE) { + break; + case RI_RELATIVE: intent = "Relative"; - } else if (icm.outputIntent == RI_SATURATION) { + break; + case RI_SATURATION: intent = "Saturation"; - } else if (icm.outputIntent == RI_ABSOLUTE) { + break; + case RI_ABSOLUTE: intent = "Absolute"; + break; } + keyFile.set_string ("Color Management", "OutputProfileIntent", intent); } diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index d24ec9312..8b8057d45 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -200,7 +200,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch ointent->append_text (M("PREFERENCES_INTENT_RELATIVE")); ointent->append_text (M("PREFERENCES_INTENT_SATURATION")); ointent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); - ointent->set_active(0); + ointent->set_active (1); oVBox->pack_start(*riHBox, Gtk::PACK_SHRINK); // Output gamma @@ -625,7 +625,7 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) if (ointentVal >= 0 && ointentVal < RI__COUNT) { pp->icm.outputIntent = static_cast(ointentVal); } else { - pp->icm.outputIntent = rtengine::RI_PERCEPTUAL; + pp->icm.outputIntent = rtengine::RI_RELATIVE; } pp->icm.freegamma = freegamma->get_active(); diff --git a/rtgui/options.cc b/rtgui/options.cc index c2e31ec38..e97a27ecb 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -470,7 +470,7 @@ void Options::setDefaults () fastexport_icm_input = "(camera)"; fastexport_icm_working = "ProPhoto"; fastexport_icm_output = "RT_sRGB"; - fastexport_icm_outputIntent = rtengine::RI_PERCEPTUAL; + fastexport_icm_outputIntent = rtengine::RI_RELATIVE; fastexport_icm_gamma = "default"; fastexport_resize_enabled = true; fastexport_resize_scale = 1; @@ -637,7 +637,7 @@ void Options::setDefaults () rtSettings.leveldnautsimpl = 0; rtSettings.monitorProfile = Glib::ustring(); - rtSettings.monitorIntent = rtengine::RI_PERCEPTUAL; + rtSettings.monitorIntent = rtengine::RI_RELATIVE; rtSettings.autoMonitorProfile = false; rtSettings.adobe = "RT_Medium_gsRGB"; // put the name of yours profiles (here windows) rtSettings.prophoto = "RT_Large_gBT709"; // these names appear in the menu "output profile" diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 28d4c13b8..866142a10 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -339,6 +339,7 @@ void ParamsEdited::set (bool v) icm.dcpIlluminant = v; icm.working = v; icm.output = v; + icm.outputIntent = v; icm.gamma = v; icm.freegamma = v; icm.gampos = v; From 527c45c68588ba7ce9bfc83dbedeabb17c5507e0 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Sat, 2 Jan 2016 14:28:48 +0100 Subject: [PATCH 55/61] Build failure on ARM and PowerPC architectures, fixes #3053 --- rtengine/dcraw.cc | 2 +- rtengine/dcraw.patch | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 9c41e17f9..b1260e307 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -1925,7 +1925,7 @@ void CLASS hasselblad_correct() blur than this, but this does not need any buffer and makes nice-looking radial gradients */ ushort *corners_weight = (ushort *)malloc(bw*bh*9*sizeof(*corners_weight)); - const char corners_mix[9][4][2] = { { {0,0}, {0,1}, {1,0}, {1,1} }, + const int corners_mix[9][4][2] = { { {0,0}, {0,1}, {1,0}, {1,1} }, { {0,1}, {1,1}, {-1,-1}, {-1,-1} }, { {0,1}, {0,2}, {1,1}, {1,2} }, { {1,0}, {1,1}, {-1,-1}, {-1,-1} }, diff --git a/rtengine/dcraw.patch b/rtengine/dcraw.patch index 5b0a2b2ec..4451e8909 100644 --- a/rtengine/dcraw.patch +++ b/rtengine/dcraw.patch @@ -1,5 +1,5 @@ ---- dcraw.c 2015-11-24 19:17:16 +0000 -+++ dcraw.cc 2015-11-27 12:35:05 +0000 +--- dcraw.c 2016-01-02 12:05:48 +0000 ++++ dcraw.cc 2016-01-02 13:21:21 +0000 @@ -1,3 +1,15 @@ +/*RT*/#include +/*RT*/#include @@ -470,7 +470,7 @@ + blur than this, but this does not need any buffer and makes nice-looking + radial gradients */ + ushort *corners_weight = (ushort *)malloc(bw*bh*9*sizeof(*corners_weight)); -+ const char corners_mix[9][4][2] = { { {0,0}, {0,1}, {1,0}, {1,1} }, ++ const int corners_mix[9][4][2] = { { {0,0}, {0,1}, {1,0}, {1,1} }, + { {0,1}, {1,1}, {-1,-1}, {-1,-1} }, + { {0,1}, {0,2}, {1,1}, {1,2} }, + { {1,0}, {1,1}, {-1,-1}, {-1,-1} }, From 96af836f614f188d809bd63f0b96b4c77ba6afc1 Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Sat, 2 Jan 2016 18:35:27 +0100 Subject: [PATCH 56/61] "Apply white balance" off by default, closes #2953 --- rtgui/icmpanel.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index 8b8057d45..584a99a22 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -953,7 +953,6 @@ void ICMPanel::saveReferencePressed () Gtk::CheckButton applyWB(M("TP_ICM_SAVEREFERENCE_APPLYWB")); applyWB.set_tooltip_text (M("TP_ICM_SAVEREFERENCE_APPLYWB_TOOLTIP")); - applyWB.set_active(true); Gtk::HBox* hbox = Gtk::manage( new Gtk::HBox() ); hbox->pack_end(applyWB, Gtk::PACK_SHRINK, 2); Gtk::VBox *vbox = dialog.get_vbox(); From 4e229fe9284b62346b8cf096cd7037d03260b73d Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 3 Jan 2016 15:48:22 +0100 Subject: [PATCH 57/61] update retinexadd with master 4d6833c --- .../images/Dark/actions/intent-perceptual.png | Bin 0 -> 898 bytes .../images/Dark/actions/intent-relative.png | Bin 0 -> 1140 bytes .../images/Dark/actions/intent-saturation.png | Bin 0 -> 1012 bytes rtdata/images/Dark/actions/softProof.png | Bin 0 -> 842 bytes .../images/Light/actions/intent-absolute.png | Bin 0 -> 700 bytes .../Light/actions/intent-perceptual.png | Bin 0 -> 847 bytes .../images/Light/actions/intent-relative.png | Bin 0 -> 1101 bytes .../Light/actions/intent-saturation.png | Bin 0 -> 1007 bytes rtdata/images/Light/actions/softProof.png | Bin 0 -> 915 bytes rtengine/dcrop.cc | 38 +- rtengine/iccstore.cc | 387 ++--- rtengine/iccstore.h | 143 +- rtengine/improccoordinator.cc | 26 +- rtengine/improccoordinator.h | 7 + rtengine/improcfun.cc | 84 +- rtengine/improcfun.h | 7 +- rtengine/iplab2rgb.cc | 12 +- rtengine/procevents.h | 3 +- rtengine/procparams.cc | 39 + rtengine/procparams.h | 10 + rtengine/refreshmap.cc | 21 +- rtengine/refreshmap.h | 56 +- rtengine/rtengine.h | 7 +- rtengine/settings.h | 4 +- rtengine/simpleprocess.cc | 8 +- rtgui/colortoning.cc | 1 + rtgui/diagonalcurveeditorsubgroup.cc | 1 + rtgui/editorpanel.cc | 185 +++ rtgui/editorpanel.h | 3 + rtgui/filecatalog.cc | 1 + rtgui/flatcurveeditorsubgroup.cc | 1 + rtgui/guiutils.h | 23 + rtgui/history.cc | 5 +- rtgui/icmpanel.cc | 55 +- rtgui/icmpanel.h | 2 + rtgui/options.cc | 10 +- rtgui/options.h | 1 + rtgui/paramsedited.cc | 6 + rtgui/paramsedited.h | 1 + rtgui/popupbutton.cc | 34 +- rtgui/popupbutton.h | 12 +- rtgui/popupcommon.cc | 127 +- rtgui/popupcommon.h | 48 +- rtgui/popuptogglebutton.h | 2 +- rtgui/preferences.cc | 109 +- rtgui/preferences.h | 7 +- rtgui/retinex.cc | 1 + rtgui/wavelet.cc | 1 + .../scalable/intent-absolute.file | 1 + .../source_icons/scalable/intent-absolute.svg | 1376 ++++++++++++++++ .../scalable/intent-perceptual.file | 1 + .../scalable/intent-perceptual.svg | 1362 ++++++++++++++++ .../scalable/intent-relative.file | 1 + .../source_icons/scalable/intent-relative.svg | 1361 ++++++++++++++++ .../scalable/intent-saturation.file | 1 + .../scalable/intent-saturation.svg | 1362 ++++++++++++++++ tools/source_icons/scalable/softProof.file | 1 + tools/source_icons/scalable/softProof.svg | 1389 +++++++++++++++++ 58 files changed, 7810 insertions(+), 533 deletions(-) create mode 100644 rtdata/images/Dark/actions/intent-perceptual.png create mode 100644 rtdata/images/Dark/actions/intent-relative.png create mode 100644 rtdata/images/Dark/actions/intent-saturation.png create mode 100644 rtdata/images/Dark/actions/softProof.png create mode 100644 rtdata/images/Light/actions/intent-absolute.png create mode 100644 rtdata/images/Light/actions/intent-perceptual.png create mode 100644 rtdata/images/Light/actions/intent-relative.png create mode 100644 rtdata/images/Light/actions/intent-saturation.png create mode 100644 rtdata/images/Light/actions/softProof.png create mode 100644 tools/source_icons/scalable/intent-absolute.file create mode 100644 tools/source_icons/scalable/intent-absolute.svg create mode 100644 tools/source_icons/scalable/intent-perceptual.file create mode 100644 tools/source_icons/scalable/intent-perceptual.svg create mode 100644 tools/source_icons/scalable/intent-relative.file create mode 100644 tools/source_icons/scalable/intent-relative.svg create mode 100644 tools/source_icons/scalable/intent-saturation.file create mode 100644 tools/source_icons/scalable/intent-saturation.svg create mode 100644 tools/source_icons/scalable/softProof.file create mode 100644 tools/source_icons/scalable/softProof.svg diff --git a/rtdata/images/Dark/actions/intent-perceptual.png b/rtdata/images/Dark/actions/intent-perceptual.png new file mode 100644 index 0000000000000000000000000000000000000000..821a714aef1582240a179b26dce741f5500e2c14 GIT binary patch literal 898 zcmV-|1AY97P)P000&U1^@s6HNQ8u00004b3#c}2nYxW zdpNm?f9idCTX==Z#d^RfzMR+H4z!8YTJ8%KMcczQmHifSCJ{k|7ncrEiEm@Yin!0 z)0?W*s##xO|0qe4+s2q%Kp-Njs$CKJYqU;PAC=4HuLA&U?H8Of-g{3R$21xZr>f6X z^|6R_j4_X`wH@GKYisMr-QC@#AP8=zY5Fd3*%*_Xs1X4K0M5B@CQo9m&3o@(QPsSN zEE{940`IA6QB_IP6u|B6?L8Bbr_Q;qwf4D)9I9$Eagu0!UFT(ge?K3`@rtTm6Ok1W zx$3>YVvNbFYG%ro!*aQNXD*Rh?Ck9178Vwkz4znm%49PA&CShU1Au0;`K9;%or@4N z#*Cj;^(Wx&$df@31Q!w^lcZ@nfH^&x#jwkklO)NG-o0>L=VfHPwf35GZUwjwyanWe zz|0OuTl1CD`5KqMkP=UmTPJ8t1L zP5+sb)5GY!9~&qlDexQcP((VwlO#zxi;Ig-OQlj;tJN+Q3WX27_p88lRULPii2MTl zFm)J5v2t>9(wi25)oRrgi^Y$d&E{=Y{R9Y%F=t}M7}J9}jjz}1Zw5i|DZ_wN)qyeQ zd*Hsc_TkKcoW;@6QFwfOd?xBeWH*<~eOoLR`~OvA>Q75mbHPx# literal 0 HcmV?d00001 diff --git a/rtdata/images/Dark/actions/intent-relative.png b/rtdata/images/Dark/actions/intent-relative.png new file mode 100644 index 0000000000000000000000000000000000000000..d586b47b20aac6c2d20688c32399828f2dd32663 GIT binary patch literal 1140 zcmV-)1dIELP)P000&U1^@s6HNQ8u00004b3#c}2nYxW zdsKd}23iNAw=f3Z8;T9;Bx`GHOBXL*T*vS& z%g;teMpiQbu(Go9MMpU1zjH2iafR6NikbGulk0jkUv)FrI2XKGWxFm6ObhLwH!8x}tgwPA1&&&=;qNLc& zrU2ZKbgN#k&yI|YtZo(8rvQ$U%!Ls0BzFMFwDctaegkj=z+_KP&-C%*$K&bg>0Gs1 zJxua|_rBZA3IN^&kOz<<`CwpR;HxH)2k;m`!#TGeLRbMX@4a6zv$@^7ci%gE_H3h4 zsbu0f?yJ>mA4gGix>~Is0+5jeGXsDn08atbCB-3xr<=yrL=;6kz4r$J95JGT1 z)AD@)Q<7#R-ED7gubn%0ZtZ1peM0g;Iu%(-J0%rJ=32hf6Oz|SPCDnV6^q3`0iaT; z?DF342ha_m0AQD-teLfW@2f*YL*F&0>m5n^Nd`$PBp*wO*`jq7mLLw zt@TVwGz_3Sgs>xBq7E}Fgb)gnwxvWt(t?>OUDkwT1;F zX;iZ$A4sZ&5RQ;6rGh^-8jWw8OS%yhk!e@;ZQT1_lOZ zUWNPxk#f2Gu5)frdQWtQ5Dt+%oSrn1G?B?0oN$S6lZp2^rh8lp2JN&@_0000P000&U1^@s6HNQ8u00004b3#c}2nYxW zd|a!fwv=vavFO4O#o)}F z8OLtiq|lu|TcIurb|DVB>`HLy%7rHWfI=4Y@?H#56QS6JS`v+z*qSjU(oX(UC-2?s zBJ+l+G;P$rP!<{QSCDpDHI+)u_V@QM3=a>dUDrM4y6#Z`PmydFkq(mgwK$mq@S_6&#+diF zwzh5x-WanHMbWiVsq|O!RxX!KZ*T9@VHm!aN~KN!*drn!xga9fN&ZH%-tyVsn@+OX zZ1r||_`aVp#uNa&2w*?SbyfYwT00TP@lWmT?YgqEasa>q0QV<-aU5T79oH>UsZ_eH zwI@~81CS;;17NVbyZh^Ewb~O!Q6I@yR##UaY8h{{-&%Vaz(ofDMn*=SQ`LP9izK<% z7;{8Kj*wK6-vRg{m&^SShT-w~`T4g=9w(_H@(X|=0Q0K4psF_#5!ZD$n@&g;Nj8HA z5Q)ei06wkP>tB^hrMWN+9}I%vO;zn{jBChooJwbB=W?x9dtO!hj4=mEx(SJhOas{7 z_)I4A&fMIbO^TC~lN;r7SsL~k1VI77%K%cU`lX0`oX_Vs#>U28SXx>-1)z)MGJsi< zYYC64R)ITgyzl$_jWMqSctTZYj4|)!a=DpGrP5`LIYaV zQ8N=`40Ib80et9r-cS>yjv&~7Iz~6?BWUsLC_&0Zx~~q6p>2+&KC-W_1y~GR%BvgBE7b@b`ro# zB-5(;k>`1z?G)}EMSS0X)fn?=%X>;y4>ivC6v+>Ax!m->B~OqX$S#rxTi!PST!`a% itXM35|6j@PDgFjNYM$N22^3-g0000?>2K~y-6t&}@x6j2n0|NENjxJ|NY1o2UcT8NF1B9cIoogkzM zGANcl5CRqv?1b3btJv5HAx)4JdE9k}6rzR*0R<5Zh$6vamppf}cX#fwa8{Bvo6UkB z3|tQ9|L!?cTp(p;X6E$5!omssCuIGgl)7!LbpRd$fHCHz5TcuiKJ@qZue2-XsicpH z&H^|WMNtm`5Ye?HN&2005Ayl^=+x9yM>}E`MUhOBlx^qS ziy#O-9cp50t#-~mA)-8hc_Mncxw+ZZAO(O7=X}%{(|0Iw5Cq$~TyB{$w(6W)&E;~- zQcBmXAHa2E%t%Y|e#L6F+Du$0$mjD{iHNl&&StY4ttKL(L1WB~X7YW-v$L~X02}}a zA%s#&Dy1Z2Y)?O9?6NWD=H%q0IFxvNeB1%p0>HG^p58@z!EX7bY&Ls$X=zEd6sP9d*noPVQp>gUKB+~T8bHC-vB^LDYVwwOHoQGDW%6b-?KguovBu< zV{>zJnO5TO^|MmS^E^)rA(Rk8N-0I7IL(|ALX1sMPakb6&SWxQIp;~OR!gLmDwT2} z1Ovc0|0kLNSOV~JczC!h|1qX?cXw|XW4`R{>|9Ke#4*N*h{!od0LVG#(kWvAZ)>%h z85$ZY)$>ioY3O~WQaN8Pm$y96Q`TA=$MJR?#}y*_$vH0+i^X?g7~00{f#OoBwAk6% zd1ZZlT?iqhwYK7%`^*@7JuoovkugTivImO8FiZ-C!i2T<4(EIkKz?v=@KW$#bWVQW6<|~8OL$0*#KQ#U5}h|$BAf}h@J;Qu)SM6!We7$ zYV8LRW$vr- UDcf2aR{#J207*qoM6N<$g6`yc_W%F@ literal 0 HcmV?d00001 diff --git a/rtdata/images/Light/actions/intent-absolute.png b/rtdata/images/Light/actions/intent-absolute.png new file mode 100644 index 0000000000000000000000000000000000000000..fb59191816dd7244af926633e6883b7dbe8a6f56 GIT binary patch literal 700 zcmV;t0z>_YP)P000&U1^@s6HNQ8u00004b3#c}2nYxW zd1 zozDQ0BpETYVwPpU%H{I++1c3+J(T5;`;sQ|HA(vBocm~IAHp!4UszaJIx-}VTs|4c@m6=6rl+TaTCFy^wY7E4%x(ZB zV9|U3xY=yJ%;5)z>}pqAQp?PiffY$#opYZhm4TbUprpE_N6lulc3?=QQkjx;#(N(D z&ddgYq5LX!#ji>lFtZ?ko_EeYt=H?X_o~eH%VKnN^mL(681vpIz*R{}7X$!FOTZiN z{d?zJJx$ZqZm0o_jg8%vlpLsZvk2(lD@Ibs%v!*FqtSQ}=8J1)cBE~(E0G=8TCY6! zhXTZLd)@ayaA8vr3d6h+l2iUz&+k#jBt`Xvps-NF&zM4nko z(wwBXz+9T9iwCJF%P000&U1^@s6HNQ8u00004b3#c}2nYxW zdMKS^)NiPAMUNk2gySuwTjTIhe6(EUnxtx-GM)HZfADGz_ zGdoyZT->SEYJZeUrOWwzzDjb#%&th9%k=0>o1_S!0H7!-HnVGzmXTQwNh!%^0NTR| zUIFNa5C&P2Mx*f{0)SSl)tn&1Ybck?MR#A0qUaMz%OtN!Dw8Y%_y7Rh{o;F)j{!WG zN%(14T3VVb6bf;YBp25eLg+UdjXxs*SX*2BLDJg05~XPh^1uIE>^n0jKXhhY+M}- z247_Z62R{y@1LHYKAIYk(=aLO&Ft5sqod#2?RNi7J;pv-xm<28Ns+f06r2mqoe`YtQ{xpUq9Imvrwwq38+9|G`+o!&$;DtrjxRgxr~32({F Z_!oStca#5KBYpq?002ovPDHLkV1im@c^Loz literal 0 HcmV?d00001 diff --git a/rtdata/images/Light/actions/intent-relative.png b/rtdata/images/Light/actions/intent-relative.png new file mode 100644 index 0000000000000000000000000000000000000000..f952f4ab7ec55317c9d8073f91eca01ad4fd409f GIT binary patch literal 1101 zcmV-T1hV^yP)P000&U1^@s6HNQ8u00004b3#c}2nYxW zd&OxS35 znz(Xh;@{xbg@1uNH~t0clC37jjT;kJ4YhP^`#P;7tpl`%0;Of%d-J~If|;f?X+iL8 z@44Uk^1JtbmjDn&(Yt0=2!f!KWm(tVcbd&+g8xbEg?uGx>d@K_fGv{uNUpm3N|t3y ztyZh^S|PPs?M4s;l|0Xj0E#3}0XPTXJb+;UrvN}w*UXjy%t`uvdU`s(b?a9CN+H9; z!zYp?363%i4GmSzY>ebpcfZyT1&{z(CE0ZM`)2ka2!ic2O*;bv1KIZW_LFwIy>}e0 zHx|i-IF7#z0l?jV0xse2Hbs+WY{-J>H_$ab zTeGvX+04vLxW2wVo+QbqwOZ|Zk|dW&hVJ`kz60PffDVAv-5(!^3;i<)!*GP;Sf1zO zB(L_m1j)PZzF=lC$+g|x-TNCG8_$l!Rj=1SBY8?284cOR5wB+r^z1wbW9k`q0zOWGnS0F=}v`3uP(R#sNl zj%&1!>jOzsBw=Px-F*+hrn|2KSno~PF*Ey663pyZGyAUpNMEM?QGfI1&Gg{kP^;BS zW;QNq2EhAx{?E*t*|$qeOYy4|e<37_qW2`7Cwa=<-vV$Mz$nSEhvhd(KQ^1q#(yc^ zSN~Oi0${2)gSuw+x4Zu==?{0GTU%Ru{5r*72qF1Rp-^xDX`|8D2B0@7dRYGg*Dn1M TGhyDO00000NkvXXu0mjf9P000&U1^@s6HNQ8u00004b3#c}2nYxW zdJR{A{B*V7siIkyf>LxHI~WH!XwU1XL9fT zTx8xbN}9&Me!F+hJ>Pe}bKZRqxC;;fC=?2>kUajMlZ#ZtFudUPAGS!2{SP8rK;Ox~ zK_-()rqk(Euh&cdHK(=i1VOOr9h5Aa%}y$%aw0M-A~Pgs089fIF~&eCwO83y0Izv{ zf`mk*feMdjOEn=byyxlA*O0YwZyL1!GJB z07-tYwf?MHt**?@&Xz^w4U*-4E(EZol)7%MZ2-6xi)gJo11CzUXX3^8J26VB->kLE zBJyReR{OPBEZ*z;{;MSC0klXiDWxu^QmLrbYCUC)nO903BbkUrNCp6QZ+yGmezV){ z>NweKHroJV-%>0V7o2l1IOh&2r9O|M=%YrX(e{1+*(i!mi%42TA^;m&>)&G@=iDZ6 zhZ|ommydQjotFVT44^I|?*>6oFO^E^Uaxl!z)1jg=iJiz`ucYOxEGHAK&ezp0~m>e zJ3Bjv0X$A}0f1IYEtbpWPnVaMt?&C;lCP7zM?^jj!*FrP^_~y_@O}TC;ma706u@O` z?FaRG{pbF1So$YXc_;GDY%;L1?EnMfppN~Ll=ZYH14pCNgg!1SricC*Wk0q1IQ_i{PNsei)Kde@( zpWrsjy`xAzpMOzA9vq4v0+7Y-%TUo;zrVJ&7W`fE81bJmP4d`4S)@(!l2YocAP9c= dr{s4Pe*h?1j$Np+MCSki002ovPDHLkV1oH}#n%7; literal 0 HcmV?d00001 diff --git a/rtdata/images/Light/actions/softProof.png b/rtdata/images/Light/actions/softProof.png new file mode 100644 index 0000000000000000000000000000000000000000..3e5eb2f182e5f0b9768fb82948230d0d03ec04f0 GIT binary patch literal 915 zcmV;E18n?>P)K~y-6t(4DeV^tK#zvupXuMM@5yigj^mU`0^?G!^95XGSz z5p*F8b~Y|mbmd|ef(sXJ{SREY7m5qlI)l3L2Z$}wPOYyn44q=r_O;FLT>S)eD1mDa4*o&!otGr;^N}dcuZ2=g>&w`IF22FPXJ(UZtfYa^@~Z8{2GSg z?xTVw09b2R0K7p&!Q|xR{>jP7gCGdrXXa%hdN~M!nTd&sKTl6jnhAd zCYf0g(X-iX_B&?21%NufDIvs5Q&Uq9kB*K?BY_)@#+dK>y8xVXE)+t1)o!IF|4MMJR*R!3`YW5w&M>(;l@Q`Tej<9s zTKmrG>Z%;IVh5l~L^L)wW>Tq?mrA9)@$qp_Ypr^XM09;)W8;J6nmCA>+v$Osv;QIiewU(aedA{!(t+g@6Xk&~KLdZVUcK|#n_hJA+5IoP!97WMqH@3C4#p!gq4r&+Rd_I2@z|CQ;86;*-5s_kMCxqC|<#Hbl{GA>}`F#E}W_}XD_r+rI p%eA$&ipf.lab2monitorRgb (labnCrop, cropImg); - //parent->ipf.lab2monitorRgb (laboCrop, cropImg); - - //cropImg = baseCrop->to8(); - /* - // int xref,yref; - xref=000;yref=000; - if (colortest && cropw>115 && croph>115) - for(int j=1;j<5;j++){ - xref+=j*30;yref+=j*30; - int rlin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))]/255.0) * 255.0); - int glin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+1]/255.0) * 255.0); - int blin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+2]/255.0) * 255.0); - - printf("after lab2rgb RGB lab2 Xr%i Yr%i Skip=%d R=%d G=%d B=%d \n",xref,yref,skip, - rlin,glin,blin); - //cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))], - //cropImg->data[(3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+1)], - //cropImg->data[(3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+2)]); - //printf("after lab2rgb Lab lab2 Xr%i Yr%i Skip=%d l=%f a=%f b=%f \n",xref,yref,skip, labnCrop->L[(int)(xref/skip)][(int)(yref/skip)]/327,labnCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327,labnCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327); - printf("after lab2rgb Lab Xr%i Yr%i Skip=%d l=%f a=%f b=%f \n",xref,yref,skip, - labnCrop->L[(int)(xref/skip)][(int)(yref/skip)]/327, - labnCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327, - labnCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327)q; - } - */ - /* - if (colortest && cropImg->height>115 && cropImg->width>115) {//for testing - xref=000;yref=000; - printf("dcrop final R= %d G= %d B= %d \n", - cropImg->data[3*xref/(skip)*(cropImg->width+1)], - cropImg->data[3*xref/(skip)*(cropImg->width+1)+1], - cropImg->data[3*xref/(skip)*(cropImg->width+1)+2]); - } - */ if (cropImageListener) { // this in output space held in parallel to allow analysis like shadow/highlight Glib::ustring outProfile = params.icm.output; @@ -1030,13 +996,13 @@ void Crop::update (int todo) Image8 *cropImgtrue; if(settings->HistogramWorking) { - cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, workProfile, false); + cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, workProfile, RI_RELATIVE, false); // HOMBRE: was RELATIVE by default in lab2rgb, is it safe to assume we have to use it again ? } else { if (params.icm.output == "" || params.icm.output == ColorManagementParams::NoICMString) { outProfile = "sRGB"; } - cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, outProfile, false); + cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0, 0, cropw, croph, outProfile, params.icm.outputIntent, false); } int finalW = rqcropw; diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc index bad4e8dfa..b77da03dd 100644 --- a/rtengine/iccstore.cc +++ b/rtengine/iccstore.cc @@ -29,9 +29,90 @@ #include -namespace rtengine +namespace { +void loadProfiles (const Glib::ustring& dirName, + std::map* profiles, + std::map* profileContents, + std::map* profileNames, + bool nameUpper, bool onlyRgb) +{ + if (dirName.empty ()) + return; + + try { + + Glib::Dir dir (dirName); + + for (Glib::DirIterator entry = dir.begin (); entry != dir.end (); ++entry) { + + const Glib::ustring fileName = *entry; + + if (fileName.size () < 4) + continue; + + const Glib::ustring extension = fileName.substr (fileName.size () - 4).casefold (); + + if (extension.compare(".icc") == 0 && extension.compare(".icm") == 0) + continue; + + const Glib::ustring filePath = Glib::build_filename (dirName, fileName); + + if (!safe_file_test (filePath, Glib::FILE_TEST_IS_REGULAR)) + continue; + + Glib::ustring name = fileName.substr (0, fileName.size() - 4); + + if (nameUpper) + name = name.uppercase (); + + if (profiles) { + const rtengine::ProfileContent content (filePath); + const cmsHPROFILE profile = content.toProfile (); + + if (profile && (!onlyRgb || cmsGetColorSpace (profile) == cmsSigRgbData)) { + profiles->insert (std::make_pair (name, profile)); + + if (profileContents) + profileContents->insert (std::make_pair (name, content)); + } + } + + if (profileNames) + profileNames->insert (std::make_pair (name, filePath)); + } + } + catch (Glib::Exception&) {} +} + +inline void getSupportedIntent (cmsHPROFILE profile, cmsUInt32Number intent, cmsUInt32Number direction, std::uint8_t& result) +{ + if (cmsIsIntentSupported (profile, intent, direction)) + result |= 1 << intent; +} + +inline std::uint8_t getSupportedIntents (cmsHPROFILE profile, cmsUInt32Number direction) +{ + if (!profile) + return 0; + + std::uint8_t result = 0; + + getSupportedIntent (profile, INTENT_PERCEPTUAL, direction, result); + getSupportedIntent (profile, INTENT_RELATIVE_COLORIMETRIC, direction, result); + getSupportedIntent (profile, INTENT_SATURATION, direction, result); + getSupportedIntent (profile, INTENT_ABSOLUTE_COLORIMETRIC, direction, result); + + return result; +} + +inline cmsHPROFILE createXYZProfile () +{ + double mat[3][3] = { {1.0, 0, 0}, {0, 1.0, 0}, {0, 0, 1.0} }; + return rtengine::ICCStore::createFromMatrix (mat, false, "XYZ"); +} + const double (*wprofiles[])[3] = {xyz_sRGB, xyz_adobe, xyz_prophoto, xyz_widegamut, xyz_bruce, xyz_beta, xyz_best}; const double (*iwprofiles[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz, bruce_xyz, beta_xyz, best_xyz}; const char* wpnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB"}; @@ -43,8 +124,12 @@ const char* wpgamma[] = {"default", "BT709_g2.2_s4.5", "sRGB_g2.4_s12.92", "line // high g=1.3 s=3.35 for high dynamic images //low g=2.6 s=6.9 for low contrast images +} -std::vector getGamma () //return gamma +namespace rtengine +{ + +std::vector getGamma () { std::vector res; @@ -56,7 +141,6 @@ std::vector getGamma () //return gamma return res; } - std::vector getWorkingProfiles () { @@ -69,32 +153,38 @@ std::vector getWorkingProfiles () return res; } -std::vector ICCStore::getOutputProfiles () +std::vector ICCStore::getProfiles () const { MyMutex::MyLock lock(mutex_); std::vector res; - for (std::map::iterator i = fileProfiles.begin(); i != fileProfiles.end(); i++) { - Glib::ustring name(i->first); - std::string::size_type i2 = name.find_last_of('/'); - - if( i2 == std::string::npos ) { - i2 = name.find_last_of('\\'); - } - - if( i2 == std::string::npos ) { - res.push_back ( name ); // list only profiles inside selected profiles directory - } - } + for (ProfileMap::const_iterator profile = fileProfiles.begin (); profile != fileProfiles.end (); ++profile) + res.push_back (profile->first); return res; } +std::vector ICCStore::getProfilesFromDir (const Glib::ustring& dirName) const +{ -cmsHPROFILE -ICCStore::makeStdGammaProfile(cmsHPROFILE iprof) + MyMutex::MyLock lock(mutex_); + + std::vector res; + + ProfileMap profiles; + + loadProfiles (profilesDir, &profiles, NULL, NULL, false, true); + loadProfiles (dirName, &profiles, NULL, NULL, false, true); + + for (ProfileMap::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile) + res.push_back (profile->first); + + return res; +} + +cmsHPROFILE ICCStore::makeStdGammaProfile (cmsHPROFILE iprof) { // forgive me for the messy code, quick hack to change gamma of an ICC profile to the RT standard gamma if (!iprof) { @@ -189,14 +279,15 @@ ICCStore::makeStdGammaProfile(cmsHPROFILE iprof) return oprof; } -ICCStore* -ICCStore::getInstance(void) +ICCStore* ICCStore::getInstance () { static ICCStore instance_; return &instance_; } -ICCStore::ICCStore () +ICCStore::ICCStore () : + xyz (createXYZProfile ()), + srgb (cmsCreate_sRGBProfile ()) { //cmsErrorAction (LCMS_ERROR_SHOW); @@ -208,234 +299,172 @@ ICCStore::ICCStore () wMatrices[wpnames[i]] = wprofiles[i]; iwMatrices[wpnames[i]] = iwprofiles[i]; } - - double mat[3][3] = { {1.0, 0, 0}, {0, 1.0, 0}, {0, 0, 1.0}}; - xyz = createFromMatrix (mat, false, "XYZ"); - srgb = cmsCreate_sRGBProfile (); } -int ICCStore::numOfWProfiles () +TMatrix ICCStore::workingSpaceMatrix (const Glib::ustring& name) const { - return sizeof(wpnames) / sizeof(wpnames[0]); -} - -TMatrix ICCStore::workingSpaceMatrix (Glib::ustring name) -{ - - std::map::iterator r = wMatrices.find (name); + const MatrixMap::const_iterator r = wMatrices.find (name); if (r != wMatrices.end()) { return r->second; } else { - return wMatrices["sRGB"]; + return wMatrices.find ("sRGB")->second; } } -TMatrix ICCStore::workingSpaceInverseMatrix (Glib::ustring name) +TMatrix ICCStore::workingSpaceInverseMatrix (const Glib::ustring& name) const { - std::map::iterator r = iwMatrices.find (name); + const MatrixMap::const_iterator r = iwMatrices.find (name); if (r != iwMatrices.end()) { return r->second; } else { - return iwMatrices["sRGB"]; + return iwMatrices.find ("sRGB")->second; } } -cmsHPROFILE ICCStore::workingSpace (Glib::ustring name) +cmsHPROFILE ICCStore::workingSpace (const Glib::ustring& name) const { - std::map::iterator r = wProfiles.find (name); + const ProfileMap::const_iterator r = wProfiles.find (name); if (r != wProfiles.end()) { return r->second; } else { - return wProfiles["sRGB"]; + return wProfiles.find ("sRGB")->second; } } -cmsHPROFILE ICCStore::workingSpaceGamma (Glib::ustring name) +cmsHPROFILE ICCStore::workingSpaceGamma (const Glib::ustring& name) const { - std::map::iterator r = wProfilesGamma.find (name); + const ProfileMap::const_iterator r = wProfilesGamma.find (name); if (r != wProfilesGamma.end()) { return r->second; } else { - return wProfilesGamma["sRGB"]; + return wProfilesGamma.find ("sRGB")->second; } } -cmsHPROFILE ICCStore::getProfile (Glib::ustring name) +cmsHPROFILE ICCStore::getProfile (const Glib::ustring& name) const { MyMutex::MyLock lock(mutex_); - std::map::iterator r = fileProfiles.find (name); + const ProfileMap::const_iterator r = fileProfiles.find (name); - if (r != fileProfiles.end()) { + if (r != fileProfiles.end ()) return r->second; - } else { - if (!name.compare (0, 5, "file:") && safe_file_test (name.substr(5), Glib::FILE_TEST_EXISTS) && !safe_file_test (name.substr(5), Glib::FILE_TEST_IS_DIR)) { - ProfileContent pc (name.substr(5)); - if (pc.data) { - cmsHPROFILE profile = pc.toProfile (); + if (name.compare (0, 5, "file:") == 0) { + const ProfileContent content (name.substr (5)); + const cmsHPROFILE profile = content.toProfile (); - if (profile) { - fileProfiles[name] = profile; - fileProfileContents[name] = pc; - return profile; - } - } + if (profile) { + const_cast(fileProfiles).insert(std::make_pair(name, profile)); + const_cast(fileProfileContents).insert(std::make_pair(name, content)); + + return profile; } } return NULL; } -cmsHPROFILE ICCStore::getStdProfile (Glib::ustring name) +cmsHPROFILE ICCStore::getStdProfile (const Glib::ustring& name) const { + const Glib::ustring nameUpper = name.uppercase (); + MyMutex::MyLock lock(mutex_); - std::map::iterator r = fileStdProfiles.find (name.uppercase()); + const ProfileMap::const_iterator r = fileStdProfiles.find (nameUpper); - if (r == fileStdProfiles.end()) { - // profile is not yet in store - std::map::iterator f = fileStdProfilesFileNames.find (name.uppercase()); - - if(f != fileStdProfilesFileNames.end()) { - // but there exists one => load it - ProfileContent pc (f->second); - - if (pc.data) { - cmsHPROFILE profile = pc.toProfile (); - - if (profile) { - fileStdProfiles[name.uppercase()] = profile; - } - - // profile is not valid or it is now stored => remove entry from fileStdProfilesFileNames - fileStdProfilesFileNames.erase(f); - return profile; - } else { - // profile not valid => remove entry from fileStdProfilesFileNames - fileStdProfilesFileNames.erase(f); - return NULL; - } - } else { - // profile does not exist - return NULL; - } - } else { - // return profile from store + // return profile from store + if (r != fileStdProfiles.end ()) return r->second; - } + + // profile is not yet in store + const NameMap::const_iterator f = fileStdProfilesFileNames.find (nameUpper); + + // profile does not exist + if (f == fileStdProfilesFileNames.end ()) + return NULL; + + // but there exists one => load it + const ProfileContent content (f->second); + const cmsHPROFILE profile = content.toProfile (); + + if (profile) + const_cast(fileStdProfiles).insert (std::make_pair (f->first, profile)); + + // profile is not valid or it is now stored => remove entry from fileStdProfilesFileNames + const_cast(fileStdProfilesFileNames).erase (f); + return profile; } -ProfileContent ICCStore::getContent (Glib::ustring name) +ProfileContent ICCStore::getContent (const Glib::ustring& name) const { MyMutex::MyLock lock(mutex_); - return fileProfileContents[name]; + const ContentMap::const_iterator r = fileProfileContents.find (name); + + return r != fileProfileContents.end () ? r->second : ProfileContent(); +} + +std::uint8_t ICCStore::getInputIntents (cmsHPROFILE profile) const +{ + + MyMutex::MyLock lock (mutex_); + + return getSupportedIntents (profile, LCMS_USED_AS_INPUT); +} + +std::uint8_t ICCStore::getOutputIntents (cmsHPROFILE profile) const +{ + + MyMutex::MyLock lock (mutex_); + + return getSupportedIntents (profile, LCMS_USED_AS_OUTPUT); +} + +std::uint8_t ICCStore::getProofIntents (cmsHPROFILE profile) const +{ + + MyMutex::MyLock lock (mutex_); + + return getSupportedIntents (profile, LCMS_USED_AS_PROOF); } // Reads all profiles from the given profiles dir -void ICCStore::init (Glib::ustring usrICCDir, Glib::ustring rtICCDir) +void ICCStore::init (const Glib::ustring& usrICCDir, const Glib::ustring& rtICCDir) { MyMutex::MyLock lock(mutex_); - // + // RawTherapee's profiles take precedence if a user's profile of the same name exists + profilesDir = Glib::build_filename (rtICCDir, "output"); fileProfiles.clear(); fileProfileContents.clear(); - // RawTherapee's profiles take precedence if a user's profile of the same name exists - loadICCs(Glib::build_filename(rtICCDir, "output"), false, fileProfiles, &fileProfileContents, true, true); - loadICCs(usrICCDir, false, fileProfiles, &fileProfileContents, true, true); + loadProfiles (profilesDir, &fileProfiles, &fileProfileContents, NULL, false, true); + loadProfiles (usrICCDir, &fileProfiles, &fileProfileContents, NULL, false, true); // Input profiles // Load these to different areas, since the short name (e.g. "NIKON D700" may overlap between system/user and RT dir) + stdProfilesDir = Glib::build_filename (rtICCDir, "input"); fileStdProfiles.clear(); fileStdProfilesFileNames.clear(); - loadICCs(Glib::build_filename(rtICCDir, "input"), true, fileStdProfiles, NULL); -} - -void ICCStore::loadICCs(Glib::ustring rootDirName, bool nameUpper, std::map& resultProfiles, std::map *resultProfileContents, bool prefetch, bool onlyRgb) -{ - if (rootDirName != "") { - std::deque qDirs; - - qDirs.push_front(rootDirName); - - while (!qDirs.empty()) { - // process directory - Glib::ustring dirname = qDirs.back(); - qDirs.pop_back(); - - Glib::Dir* dir = NULL; - - try { - if (!safe_file_test (dirname, Glib::FILE_TEST_IS_DIR)) { - return; - } - - dir = new Glib::Dir (dirname); - } catch (Glib::Exception& fe) { - return; - } - - dirname = dirname + "/"; - - for (Glib::DirIterator i = dir->begin(); i != dir->end(); ++i) { - Glib::ustring fname = dirname + *i; - Glib::ustring sname = *i; - - // ignore directories - if (!safe_file_test (fname, Glib::FILE_TEST_IS_DIR)) { - size_t lastdot = sname.find_last_of ('.'); - - if (lastdot != Glib::ustring::npos && lastdot <= sname.size() - 4 && (!sname.casefold().compare (lastdot, 4, ".icm") || !sname.casefold().compare (lastdot, 4, ".icc"))) { - Glib::ustring name = nameUpper ? sname.substr(0, lastdot).uppercase() : sname.substr(0, lastdot); - - if(!prefetch) { - fileStdProfilesFileNames[name] = fname; - } else { - ProfileContent pc (fname); - - if (pc.data) { - cmsHPROFILE profile = pc.toProfile (); - - if (profile && (!onlyRgb || cmsGetColorSpace(profile) == cmsSigRgbData)) { - resultProfiles[name] = profile; - - if(resultProfileContents) { - (*resultProfileContents)[name] = pc; - } - } - } - } - } - } - - // Removed recursive scanning, see issue #1730. - // To revert to the recursive method, just uncomment the next line. - - //else qDirs.push_front(fname); // for later scanning - } - - delete dir; - } - } + loadProfiles (stdProfilesDir, NULL, NULL, &fileStdProfilesFileNames, true, false); } // Determine the first monitor default profile of operating system, if selected -void ICCStore::findDefaultMonitorProfile() +void ICCStore::findDefaultMonitorProfile () { - defaultMonitorProfile = ""; + defaultMonitorProfile.clear (); #ifdef WIN32 // Get current main monitor. Could be fine tuned to get the current windows monitor (multi monitor setup), @@ -449,6 +478,11 @@ void ICCStore::findDefaultMonitorProfile() if (GetICMProfileA(hDC, &profileLength, profileName)) { defaultMonitorProfile = Glib::ustring(profileName); + defaultMonitorProfile = Glib::path_get_basename(defaultMonitorProfile); + size_t pos = defaultMonitorProfile.rfind("."); + if (pos != Glib::ustring::npos) { + defaultMonitorProfile = defaultMonitorProfile.substr(0, pos); + } } // might fail if e.g. the monitor has no profile @@ -466,7 +500,7 @@ void ICCStore::findDefaultMonitorProfile() } } -ProfileContent::ProfileContent (Glib::ustring fileName) : data(NULL), length(0) +ProfileContent::ProfileContent (const Glib::ustring& fileName) : data(NULL), length(0) { FILE* f = safe_g_fopen (fileName, "rb"); @@ -518,9 +552,7 @@ ProfileContent& ProfileContent::operator= (const ProfileContent& other) length = other.length; - if (data) { - delete [] data; - } + delete [] data; if (other.data) { data = new char[length + 1]; @@ -532,15 +564,7 @@ ProfileContent& ProfileContent::operator= (const ProfileContent& other) return *this; } -ProfileContent::~ProfileContent () -{ - - if (data) { - delete [] data; - } -} - -cmsHPROFILE ProfileContent::toProfile () +cmsHPROFILE ProfileContent::toProfile () const { if (data) { @@ -550,7 +574,7 @@ cmsHPROFILE ProfileContent::toProfile () } } -cmsHPROFILE ICCStore::createFromMatrix (const double matrix[3][3], bool gamma, Glib::ustring name) +cmsHPROFILE ICCStore::createFromMatrix (const double matrix[3][3], bool gamma, const Glib::ustring& name) { static const unsigned phead[] = { @@ -644,4 +668,5 @@ cmsHPROFILE ICCStore::createFromMatrix (const double matrix[3][3], bool gamma, G delete [] oprof; return p; } + } diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h index acb31e4cf..8b6e6465c 100644 --- a/rtengine/iccstore.h +++ b/rtengine/iccstore.h @@ -37,74 +37,135 @@ public: char* data; int length; - ProfileContent (): data(NULL), length(0) {} - ProfileContent (Glib::ustring fileName); - ProfileContent (const ProfileContent& other); - ProfileContent (cmsHPROFILE hProfile); + ProfileContent (); ~ProfileContent (); + + ProfileContent (const ProfileContent& other); ProfileContent& operator= (const rtengine::ProfileContent& other); - cmsHPROFILE toProfile (); + + ProfileContent (const Glib::ustring& fileName); + ProfileContent (cmsHPROFILE hProfile); + cmsHPROFILE toProfile () const; }; class ICCStore { + typedef std::map ProfileMap; + typedef std::map MatrixMap; + typedef std::map ContentMap; + typedef std::map NameMap; - std::map wProfiles; - std::map wProfilesGamma; - std::map wMatrices; - std::map iwMatrices; + ProfileMap wProfiles; + ProfileMap wProfilesGamma; + MatrixMap wMatrices; + MatrixMap iwMatrices; // these contain profiles from user/system directory (supplied on init) - std::map fileProfiles; - std::map fileProfileContents; + Glib::ustring profilesDir; + ProfileMap fileProfiles; + ContentMap fileProfileContents; // these contain standard profiles from RT. keys are all in uppercase - std::map fileStdProfilesFileNames; - std::map fileStdProfiles; + Glib::ustring stdProfilesDir; + NameMap fileStdProfilesFileNames; + ProfileMap fileStdProfiles; - cmsHPROFILE xyz; - cmsHPROFILE srgb; + Glib::ustring defaultMonitorProfile; - MyMutex mutex_; + const cmsHPROFILE xyz; + const cmsHPROFILE srgb; + + mutable MyMutex mutex_; ICCStore (); - void loadICCs(Glib::ustring rootDirName, bool nameUpper, std::map& resultProfiles, std::map *resultProfileContents, bool prefetch = false, bool onlyRgb = false); public: - static ICCStore* getInstance(void); - static cmsHPROFILE makeStdGammaProfile(cmsHPROFILE iprof); + static ICCStore* getInstance (); - Glib::ustring defaultMonitorProfile; // Main monitors standard profile name, from OS - void findDefaultMonitorProfile(); + void init (const Glib::ustring& usrICCDir, const Glib::ustring& stdICCDir); - int numOfWProfiles (); - cmsHPROFILE createFromMatrix (const double matrix[3][3], bool gamma = false, Glib::ustring name = ""); - cmsHPROFILE workingSpace (Glib::ustring name); - cmsHPROFILE workingSpaceGamma (Glib::ustring name); - TMatrix workingSpaceMatrix (Glib::ustring name); - TMatrix workingSpaceInverseMatrix (Glib::ustring name); + static cmsHPROFILE makeStdGammaProfile (cmsHPROFILE iprof); + static cmsHPROFILE createFromMatrix (const double matrix[3][3], bool gamma = false, const Glib::ustring& name = Glib::ustring()); - cmsHPROFILE getProfile (Glib::ustring name); - cmsHPROFILE getStdProfile(Glib::ustring name); + // Main monitors standard profile name, from OS + void findDefaultMonitorProfile (); + cmsHPROFILE getDefaultMonitorProfile () const; + Glib::ustring getDefaultMonitorProfileName () const; - void init (Glib::ustring usrICCDir, Glib::ustring stdICCDir); - ProfileContent getContent (Glib::ustring name); + cmsHPROFILE workingSpace (const Glib::ustring& name) const; + cmsHPROFILE workingSpaceGamma (const Glib::ustring& name) const; + TMatrix workingSpaceMatrix (const Glib::ustring& name) const; + TMatrix workingSpaceInverseMatrix (const Glib::ustring& name) const; - cmsHPROFILE getXYZProfile () - { - return xyz; - } - cmsHPROFILE getsRGBProfile () - { - return srgb; - } - std::vector getOutputProfiles (); + cmsHPROFILE getProfile (const Glib::ustring& name) const; + cmsHPROFILE getStdProfile (const Glib::ustring& name) const; + ProfileContent getContent (const Glib::ustring& name) const; + + cmsHPROFILE getXYZProfile () const; + cmsHPROFILE getsRGBProfile () const; + + std::vector getProfiles () const; + std::vector getProfilesFromDir (const Glib::ustring& dirName) const; + + std::uint8_t getInputIntents (cmsHPROFILE profile) const; + std::uint8_t getOutputIntents (cmsHPROFILE profile) const; + std::uint8_t getProofIntents (cmsHPROFILE profile) const; + + std::uint8_t getInputIntents (const Glib::ustring& name) const; + std::uint8_t getOutputIntents (const Glib::ustring& name) const; + std::uint8_t getProofIntents (const Glib::ustring& name) const; }; #define iccStore ICCStore::getInstance() -//extern const char* wpnames[]; +inline ProfileContent::ProfileContent () : + data(NULL), + length(0) +{ } + +inline ProfileContent::~ProfileContent () +{ + delete [] data; +} + +inline cmsHPROFILE ICCStore::getDefaultMonitorProfile () const +{ + return getProfile (defaultMonitorProfile); +} + +inline Glib::ustring ICCStore::getDefaultMonitorProfileName () const +{ + return defaultMonitorProfile; +} + +inline std::uint8_t ICCStore::getInputIntents (const Glib::ustring &name) const +{ + return getInputIntents (getProfile (name)); +} + +inline std::uint8_t ICCStore::getOutputIntents (const Glib::ustring &name) const +{ + return getOutputIntents (getProfile (name)); +} + +inline std::uint8_t ICCStore::getProofIntents (const Glib::ustring &name) const +{ + return getProofIntents (getProfile (name)); +} + +inline cmsHPROFILE ICCStore::getXYZProfile () const +{ + return xyz; +} + +inline cmsHPROFILE ICCStore::getsRGBProfile () const +{ + return srgb; +} + +} + #endif diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index dc135c4d5..1745d8210 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -31,7 +31,7 @@ extern const Settings* settings; ImProcCoordinator::ImProcCoordinator () : orig_prev(NULL), oprevi(NULL), oprevl(NULL), nprevl(NULL), previmg(NULL), workimg(NULL), - ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), scale(10), + ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), monitorIntent(RI_RELATIVE), scale(10), highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.), @@ -782,6 +782,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } } } + // Update the monitor color transform if necessary + if (todo & M_MONITOR) { + ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent); + } // process crop, if needed for (size_t i = 0; i < crops.size(); i++) @@ -796,7 +800,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) progress ("Conversion to RGB...", 100 * readyphase / numofphases); - if (todo != CROP && todo != MINUPDATE) { +// if (todo != CROP && todo != MINUPDATE) { + if ((todo != CROP && todo != MINUPDATE) || (todo & M_MONITOR)) { MyMutex::MyLock prevImgLock(previmg->getMutex()); try { @@ -806,13 +811,13 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) if(settings->HistogramWorking) { Glib::ustring workProfile = params.icm.working; - workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, workProfile, true); + workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, workProfile, RI_RELATIVE, true); // HOMBRE: was RELATIVE by default in lab2rgb, is it safe to assume we have to use it again ? } else { - if (params.icm.output == "" || params.icm.output == ColorManagementParams::NoICMString) { + if (params.icm.output.empty() || params.icm.output == ColorManagementParams::NoICMString) { outProfile = "sRGB"; } - workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, outProfile, false); + workimg = ipf.lab2rgb (nprevl, 0, 0, pW, pH, outProfile, params.icm.outputIntent, false); } } catch(char * str) { progress ("Error converting file...", 0); @@ -1128,6 +1133,17 @@ void ImProcCoordinator::getAutoCrop (double ratio, int &x, int &y, int &w, int & y = (fullh - h) / 2; } +void ImProcCoordinator::setMonitorProfile (const Glib::ustring& profile, RenderingIntent intent) +{ + monitorProfile = profile; + monitorIntent = intent; +} + +void ImProcCoordinator::getMonitorProfile (Glib::ustring& profile, RenderingIntent& intent) const +{ + profile = monitorProfile; + intent = monitorIntent; +} void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname, bool apply_wb) { diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index ef981fe6a..4d442482e 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -72,6 +72,10 @@ protected: ImProcFunctions ipf; + Glib::ustring monitorProfile; + + RenderingIntent monitorIntent; + int scale; bool highDetailPreprocessComputed; bool highDetailRawComputed; @@ -249,6 +253,9 @@ public: void getSpotWB (int x, int y, int rectSize, double& temp, double& green); void getAutoCrop (double ratio, int &x, int &y, int &w, int &h); + void setMonitorProfile (const Glib::ustring& profile, RenderingIntent intent); + void getMonitorProfile (Glib::ustring& profile, RenderingIntent& intent) const; + bool updateTryLock () { return updaterThreadStart.trylock(); diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index f21748a3b..c3c5af03f 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -140,57 +140,10 @@ void ImProcFunctions::firstAnalysisThread (Imagefloat* original, Glib::ustring w } } } -/* -void ImProcFunctions::CAT02 (Imagefloat* baseImg, const ProcParams* params) + +void ImProcFunctions::updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent) { - const double toxyz[3][3] = {{0.7976749, 0.1351917, 0.0313534}, - {0.2880402, 0.7118741, 0.0000857}, - {0.0000000, 0.0000000, 0.8252100}}; - - const double xyzto[3][3] = {{1.3459433, -0.2556075, -0.0511118}, - {-0.5445989, 1.5081673, 0.0205351}, - {0.0000000, 0.0000000, 1.2118128}}; - int fw = baseImg->width; - int fh = baseImg->height; - - double CAM02BB00,CAM02BB01,CAM02BB02,CAM02BB10,CAM02BB11,CAM02BB12,CAM02BB20,CAM02BB21,CAM02BB22; - double Xxx,Yyy,Zzz; - // Xxx=1.09844; - // Yyy=1.0; - // Zzz=0.355961; - //params.wb.temperature, params.wb.green, params.wb.method - double Xxyz, Zxyz; -// ColorTemp::temp2mulxyz (params->wb.temperature, params->wb.green, params->wb.method, Xxyz, Zxyz); - ColorTemp::temp2mulxyz (5000.0, 1.0, "Camera", Xxyz, Zxyz); - - ColorTemp::cieCAT02(Xxx, Yyy, Zzz, CAM02BB00,CAM02BB01,CAM02BB02,CAM02BB10,CAM02BB11,CAM02BB12,CAM02BB20,CAM02BB21,CAM02BB22); - printf("00=%f 01=%f 11=%f 20=%f 22=%f\n", CAM02BB00,CAM02BB01,CAM02BB11,CAM02BB20,CAM02BB22); - - - for (int i=0; ir(i,j); - float g = baseImg->g(i,j); - float b = baseImg->b(i,j); - - float x = toxyz[0][0] * r + toxyz[0][1] * g + toxyz[0][2] * b; - float y = toxyz[1][0] * r + toxyz[1][1] * g + toxyz[1][2] * b; - float z = toxyz[2][0] * r + toxyz[2][1] * g + toxyz[2][2] * b; - float Xcam=CAM02BB00* x +CAM02BB01* y + CAM02BB02* z ; - float Ycam=CAM02BB10* x +CAM02BB11* y + CAM02BB12* z ; - float Zcam=CAM02BB20* x +CAM02BB21* y + CAM02BB22* z ; - baseImg->r(i,j) = xyzto[0][0] * Xcam + xyzto[0][1] * Ycam + xyzto[0][2] * Zcam; - baseImg->g(i,j) = xyzto[1][0] * Xcam + xyzto[1][1] * Ycam + xyzto[1][2] * Zcam; - baseImg->b(i,j) = xyzto[2][0] * Xcam + xyzto[2][1] * Ycam + xyzto[2][2] * Zcam; - } - } -} -*/ -void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* params, LUTu & histogram) -{ - // set up monitor transform - Glib::ustring wprofile = params->icm.working; if (monitorTransform != NULL) { cmsDeleteTransform (monitorTransform); @@ -209,43 +162,38 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par lab2outputTransform = NULL; #if !defined(__APPLE__) // No support for monitor profiles on OS X, all data is sRGB - Glib::ustring monitorProfile = settings->monitorProfile; -#if defined(WIN32) - if (settings->autoMonitorProfile) { - monitorProfile = iccStore->defaultMonitorProfile; - } - -#endif - - cmsHPROFILE monitor = iccStore->getProfile ("file:" + monitorProfile); + cmsHPROFILE monitor = iccStore->getProfile (monitorProfile); if (monitor) { - lcmsMutex->lock (); + MyMutex::MyLock lcmsLock (*lcmsMutex); cmsHPROFILE iprof = cmsCreateLab4Profile(NULL); - monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC, + monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is for thread safety, NOOPTIMIZE for precision Glib::ustring outputProfile; - if (params->icm.output != "" && params->icm.output != ColorManagementParams::NoICMString) { - outputProfile = params->icm.output; + if (!icm.output.empty() && icm.output != ColorManagementParams::NoICMString) { + outputProfile = icm.output; cmsHPROFILE jprof = iccStore->getProfile(outputProfile); if (jprof) { - lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); - - if (monitor) { - output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); - } + lab2outputTransform = cmsCreateTransform (iprof, TYPE_Lab_FLT, jprof, TYPE_RGB_FLT, icm.outputIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); + output2monitorTransform = cmsCreateTransform (jprof, TYPE_RGB_FLT, monitor, TYPE_RGB_8, monitorIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); } } cmsCloseProfile(iprof); - lcmsMutex->unlock (); } #endif +} + +void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* params, LUTu & histogram) +{ + + Glib::ustring wprofile = params->icm.working; + // calculate histogram of the y channel needed for contrast curve calculation in exposure adjustments int T = 1; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index cfabbba64..ec81f26eb 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -233,6 +233,7 @@ public: bool needsPCVignetting (); void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16); + void updateColorProfiles (const ColorManagementParams& icm, const Glib::ustring& monitorProfile, RenderingIntent monitorIntent); void rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *editBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit , float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clcurve, LUTf & cl2curve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1, const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf); @@ -379,9 +380,9 @@ public: void Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad); void BadpixelsLab(LabImage * src, LabImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom); - Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool standard_gamma); - Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw);// for gamma output - Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool bw);//without gamma ==>default + Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool standard_gamma); + Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw);// for gamma output + Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool bw);//without gamma ==>default // CieImage *ciec; 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, const LCPMapper *pLCPMap = NULL); diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index cc01b783f..c36e185d0 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -134,7 +134,7 @@ void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) } } -Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool standard_gamma) +Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool standard_gamma) { //gamutmap(lab); @@ -167,7 +167,7 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, lcmsMutex->lock (); cmsHPROFILE hLab = cmsCreateLab4Profile(NULL); - cmsHTRANSFORM hTransform = cmsCreateTransform (hLab, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC, + cmsHTRANSFORM hTransform = cmsCreateTransform (hLab, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety cmsCloseProfile(hLab); lcmsMutex->unlock (); @@ -259,7 +259,7 @@ Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, return image; } // for default (not gamma) -Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool bw) +Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, bool bw) { //gamutmap(lab); @@ -322,7 +322,7 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int cmsHPROFILE iprof = iccStore->getXYZProfile (); lcmsMutex->lock (); - cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); lcmsMutex->unlock (); image->ExecCMSTransform(hTransform); @@ -363,7 +363,7 @@ Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int // for gamma options (BT709...sRGB linear...) -Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw) +Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, RenderingIntent intent, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw) { //gamutmap(lab); @@ -593,7 +593,7 @@ Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int cmsHPROFILE iprof = iccStore->getXYZProfile (); lcmsMutex->lock (); - cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, intent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); lcmsMutex->unlock (); image->ExecCMSTransform(hTransform); diff --git a/rtengine/procevents.h b/rtengine/procevents.h index d02018d78..3c7e1ceb5 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -465,7 +465,8 @@ enum ProcEvent { EvmapMethod = 434, EvRetinexmapcurve = 435, EvviewMethod = 436, - + EvOIntent = 437, + EvMonitorTransform = 438, NUMOFEVENTS }; } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 7a674e8c3..90eafe375 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -907,6 +907,7 @@ void ColorManagementParams::setDefaults() dcpIlluminant = 0; working = "ProPhoto"; output = "RT_sRGB"; + outputIntent = RI_RELATIVE; gamma = "default"; gampos = 2.22; slpos = 4.5; @@ -2606,6 +2607,27 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol keyFile.set_string ("Color Management", "OutputProfile", icm.output); } + if (!pedited || pedited->icm.outputIntent) { + Glib::ustring intent; + switch (icm.outputIntent) { + default: + case RI_PERCEPTUAL: + intent = "Perceptual"; + break; + case RI_RELATIVE: + intent = "Relative"; + break; + case RI_SATURATION: + intent = "Saturation"; + break; + case RI_ABSOLUTE: + intent = "Absolute"; + break; + } + + keyFile.set_string ("Color Management", "OutputProfileIntent", intent); + } + if (!pedited || pedited->icm.gamma) { keyFile.set_string ("Color Management", "Gammafree", icm.gamma); } @@ -5821,6 +5843,23 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) } } + if (keyFile.has_key ("Color Management", "OutputProfileIntent")) { + Glib::ustring intent = keyFile.get_string ("Color Management", "OutputProfileIntent"); + if (intent == "Perceptual") { + icm.outputIntent = RI_PERCEPTUAL; + } else if (intent == "Relative") { + icm.outputIntent = RI_RELATIVE; + } else if (intent == "Saturation") { + icm.outputIntent = RI_SATURATION; + } else if (intent == "Absolute") { + icm.outputIntent = RI_ABSOLUTE; + } + + if (pedited) { + pedited->icm.outputIntent = true; + } + } + if (keyFile.has_key ("Color Management", "Gammafree")) { icm.gamma = keyFile.get_string ("Color Management", "Gammafree"); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 0aa31a9bd..47b8f1cf1 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "LUT.h" #include "coord.h" @@ -41,6 +42,14 @@ class WavOpacityCurveW; class WavOpacityCurveWL; class RetinextransmissionCurve; +enum RenderingIntent { + RI_PERCEPTUAL = INTENT_PERCEPTUAL, + RI_RELATIVE = INTENT_RELATIVE_COLORIMETRIC, + RI_SATURATION = INTENT_SATURATION, + RI_ABSOLUTE = INTENT_ABSOLUTE_COLORIMETRIC, + RI__COUNT +}; + namespace procparams { @@ -953,6 +962,7 @@ public: int dcpIlluminant; Glib::ustring working; Glib::ustring output; + RenderingIntent outputIntent; static const Glib::ustring NoICMString; Glib::ustring gamma; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 915ed615d..291dc0550 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -64,9 +64,9 @@ int refreshmap[rtengine::NUMOFEVENTS] = { DARKFRAME, // EvLCPUseVign, TRANSFORM, // EvLCPUseCA, M_VOID, // EvFixedExp - WHITEBALANCE, // EvWBMethod, - WHITEBALANCE, // EvWBTemp, - WHITEBALANCE, // EvWBGreen, + ALLNORAW, // EvWBMethod, + ALLNORAW, // EvWBTemp, + ALLNORAW, // EvWBGreen, RGBCURVE, // EvToneCurveMode1, RGBCURVE, // EvToneCurve2, RGBCURVE, // EvToneCurveMode2, @@ -75,7 +75,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { 0, // EvCDNEnabled:obsolete, ALL, // EvBlendCMSMatrix, RGBCURVE, // EvDCPToneCurve, - INPUTPROFILE, // EvDCPIlluminant, + ALLNORAW, // EvDCPIlluminant, RETINEX, // EvSHEnabled, RGBCURVE, // EvSHHighlights, RGBCURVE, // EvSHShadows, @@ -97,7 +97,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { ALLNORAW, // EvHRMethod, ALLNORAW, // EvWProfile, OUTPUTPROFILE, // EvOProfile, - INPUTPROFILE, // EvIProfile, + ALLNORAW, // EvIProfile, TRANSFORM, // EvVignettingAmount, RGBCURVE, // EvChMixer, RESIZE, // EvResizeScale, @@ -234,8 +234,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // EvCATbadpix LUMINANCECURVE, // EvCATAutoadap DEFRINGE, // EvPFCurve - WHITEBALANCE, // EvWBequal - WHITEBALANCE, // EvWBequalbo + ALLNORAW, // EvWBequal + ALLNORAW, // EvWBequalbo TRANSFORM, // EvGradientDegree TRANSFORM, // EvGradientEnabled TRANSFORM, // EvPCVignetteStrength @@ -421,7 +421,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { DIRPYREQUALIZER, // EvWavNeutral RGBCURVE, // EvDCPApplyLookTable, RGBCURVE, // EvDCPApplyBaselineExposureOffset, - INPUTPROFILE, // EvDCPApplyHueSatMap + ALLNORAW, // EvDCPApplyHueSatMap DIRPYREQUALIZER, // EvWavenacont DIRPYREQUALIZER, // EvWavenachrom DIRPYREQUALIZER, // EvWavenaedge @@ -464,7 +464,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { RETINEX, //EvLradius RETINEX, //EvmapMethod DEMOSAIC, //EvRetinexmapcurve - DEMOSAIC //EvviewMethod - + DEMOSAIC, //EvviewMethod + ALLNORAW, // EvOIntent + MONITORTRANSFORM // EvMonitorTransform }; diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h index e24d0c422..23e179f9f 100644 --- a/rtengine/refreshmap.h +++ b/rtengine/refreshmap.h @@ -20,15 +20,16 @@ #define __REFRESHMAP__ // Use M_VOID if you wish to update the proc params without updating the preview at all ! -#define M_VOID (1<<15) +#define M_VOID (1<<16) // Use M_MINUPDATE if you wish to update the preview without modifying the image (think about it like a "refreshPreview") // Must NOT be used with other event (i.e. will be used for MINUPDATE only) -#define M_MINUPDATE (1<<14) +#define M_MINUPDATE (1<<15) // Force high quality -#define M_HIGHQUAL (1<<13) +#define M_HIGHQUAL (1<<14) // Elementary functions that can be done to // the preview image when an event occurs +#define M_MONITOR (1<<13) #define M_RETINEX (1<<12) #define M_CROP (1<<11) #define M_PREPROC (1<<10) @@ -45,31 +46,30 @@ // Bitfield of functions to do to the preview image when an event occurs // Use those or create new ones for your new events -#define FIRST (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL -#define ALL (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL -#define TRANSFORM (M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define AUTOEXP (M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define RGBCURVE (M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define LUMINANCECURVE (M_LUMACURVE|M_LUMINANCE) -#define SHARPENING M_LUMINANCE -#define IMPULSEDENOISE M_LUMINANCE -#define DEFRINGE M_LUMINANCE -#define WHITEBALANCE (M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define DEMOSAIC (M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define DARKFRAME (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define FLATFIELD (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define DIRPYRDENOISE (M_COLOR|M_LUMINANCE) -#define CROP M_CROP -#define RESIZE M_VOID -#define EXIF M_VOID -#define IPTC M_VOID -#define DIRPYREQUALIZER (M_COLOR|M_LUMINANCE) -#define OUTPUTPROFILE (M_INIT|M_COLOR|M_LUMINANCE) -#define INPUTPROFILE WHITEBALANCE -#define GAMMA (M_COLOR|M_LUMINANCE) -#define MINUPDATE M_MINUPDATE -#define ALLNORAW (M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) -#define RETINEX (M_RETINEX|ALLNORAW) +#define FIRST (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL +#define ALL (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL +#define DARKFRAME (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define FLATFIELD (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define DEMOSAIC (M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define ALLNORAW (M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define TRANSFORM (M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define AUTOEXP (M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define RGBCURVE (M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define LUMINANCECURVE (M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define SHARPENING (M_LUMINANCE|M_COLOR) +#define IMPULSEDENOISE (M_LUMINANCE|M_COLOR) +#define DEFRINGE (M_LUMINANCE|M_COLOR) +#define DIRPYRDENOISE (M_LUMINANCE|M_COLOR) +#define DIRPYREQUALIZER (M_LUMINANCE|M_COLOR) +#define GAMMA (M_LUMINANCE|M_COLOR) +#define CROP M_CROP +#define RESIZE M_VOID +#define EXIF M_VOID +#define IPTC M_VOID +#define MINUPDATE M_MINUPDATE +#define RETINEX (M_RETINEX|ALLNORAW) +#define MONITORTRANSFORM M_MONITOR +#define OUTPUTPROFILE (ALLNORAW|MONITORTRANSFORM) extern int refreshmap[]; #endif diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index 195911a3a..42e06406e 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -35,7 +35,7 @@ #include "LUT.h" /** * @file - * This file contains the main functionality of the raw therapee engine. + * This file contains the main functionality of the RawTherapee engine. * */ @@ -413,9 +413,12 @@ public: virtual void setAutoBWListener (AutoBWListener* l) = 0; virtual void setAutoColorTonListener (AutoColorTonListener* l) = 0; virtual void setAutoChromaListener (AutoChromaListener* l) = 0; - virtual void setRetinexListener (RetinexListener* l) = 0; + virtual void setRetinexListener (RetinexListener* l) = 0; virtual void setWaveletListener (WaveletListener* l) = 0; + virtual void setMonitorProfile (const Glib::ustring& monitorProfile, RenderingIntent intent) = 0; + virtual void getMonitorProfile (Glib::ustring& monitorProfile, RenderingIntent& intent) const = 0; + virtual ~StagedImageProcessor () {} /** Returns a staged, cached image processing manager supporting partial updates diff --git a/rtengine/settings.h b/rtengine/settings.h index 373103d07..e3e220af9 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -19,6 +19,8 @@ #ifndef _RTSETTINGS_ #define _RTSETTINGS_ +#include "procparams.h" + namespace rtengine { @@ -27,7 +29,6 @@ class Settings { public: Glib::ustring iccDirectory; ///< The directory containing the possible output icc profiles - int colorimetricIntent; ///< Colorimetric intent used at color space conversions int viewingdevice; // white of output device (D50...D65..) int viewingdevicegrey; // level of grey output device int viewinggreySc; // level of grey Scene @@ -38,6 +39,7 @@ public: int leveldnautsimpl; // STD or EXPERT Glib::ustring monitorProfile; ///< ICC profile of the monitor (full path recommended) + RenderingIntent monitorIntent; ///< Colorimetric intent used with the above profile bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile bool autocielab; bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 8bb0e839c..14d827bab 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1157,7 +1157,8 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p cmsFloat64Number Parameters[7]; double ga0, ga1, ga2, ga3, ga4, ga5, ga6; // if(params.blackwhite.enabled) params.toneCurve.hrenabled=false; - readyImg = ipf.lab2rgb16b (labView, cx, cy, cw, ch, params.icm.output, params.icm.working, params.icm.gamma, params.icm.freegamma, params.icm.gampos, params.icm.slpos, ga0, ga1, ga2, ga3, ga4, ga5, ga6, params.blackwhite.enabled ); + readyImg = ipf.lab2rgb16b (labView, cx, cy, cw, ch, params.icm.output, params.icm.outputIntent, params.icm.working, params.icm.gamma, params.icm.freegamma, params.icm.gampos, params.icm.slpos, ga0, ga1, ga2, ga3, ga4, ga5, ga6, params.blackwhite.enabled ); + customGamma = true; customGamma = true; //or selected Free gamma @@ -1165,8 +1166,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p bool pro = false; Glib::ustring chpro, outProfile; bool present_space[9] = {false, false, false, false, false, false, false, false, false}; - std::vector opnames = iccStore->getOutputProfiles (); - + std::vector opnames = iccStore->getProfiles (); //test if files are in system for (int j = 0; j < 9; j++) { // one can modify "option" [Color Management] to adapt the profile's name if they are different for windows, MacOS, Linux ?? @@ -1349,7 +1349,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p bwonly = false; } - readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output, bwonly); + readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output, params.icm.outputIntent, bwonly); if (settings->verbose) { printf("Output profile_: \"%s\"\n", params.icm.output.c_str()); diff --git a/rtgui/colortoning.cc b/rtgui/colortoning.cc index 38cf88230..99ad03e9f 100644 --- a/rtgui/colortoning.cc +++ b/rtgui/colortoning.cc @@ -3,6 +3,7 @@ */ #include "colortoning.h" #include "mycurve.h" +#include "rtimage.h" using namespace rtengine; using namespace rtengine::procparams; diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc index ad896789f..4ca2bb159 100644 --- a/rtgui/diagonalcurveeditorsubgroup.cc +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -30,6 +30,7 @@ #include "mydiagonalcurve.h" #include "curveeditor.h" #include "diagonalcurveeditorsubgroup.h" +#include "rtimage.h" DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, Glib::ustring& curveDir) : CurveEditorSubGroup(curveDir) { diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index 82e8d9fcf..b9f123ac5 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -25,12 +25,188 @@ #include "procparamchangers.h" #include "../rtengine/safegtk.h" #include "../rtengine/imagesource.h" +#include "../rtengine/iccstore.h" #include "soundman.h" #include "rtimage.h" #include +#include "popupbutton.h" using namespace rtengine::procparams; +class EditorPanel::MonitorProfileSelector +{ +private: + MyComboBoxText profileBox; + PopUpButton intentBox; + sigc::connection profileConn, intentConn; + + rtengine::StagedImageProcessor* const& processor; + +private: + void prepareProfileBox () + { + profileBox.set_size_request (100, -1); + + profileBox.append_text (M("PREFERENCES_PROFILE_NONE")); +#ifdef WIN32 + profileBox.append_text (M("MONITOR_PROFILE_SYSTEM") + " (" + rtengine::iccStore->getDefaultMonitorProfileName() + ")"); + profileBox.set_active (options.rtSettings.autoMonitorProfile ? 1 : 0); +#else + profileBox.set_active (0); +#endif + + const std::vector profiles = rtengine::iccStore->getProfiles (); + for (std::vector::const_iterator iterator = profiles.begin (); iterator != profiles.end (); ++iterator) { + profileBox.append_text (*iterator); + } + } + + void prepareIntentBox () + { + intentBox.addEntry("intent-relative.png", M("PREFERENCES_INTENT_RELATIVE")); + intentBox.addEntry("intent-perceptual.png", M("PREFERENCES_INTENT_PERCEPTUAL")); + intentBox.addEntry("intent-absolute.png", M("PREFERENCES_INTENT_ABSOLUTE")); + + intentBox.setSelected(0); + intentBox.show (); + } + + void profileBoxChanged () + { + updateParameters (); + + profileBox.set_tooltip_text (profileBox.get_active_text ()); + } + + void intentBoxChanged (int) + { + updateParameters (); + } + + void updateParameters () + { + ConnectionBlocker profileBlocker (profileConn); + ConnectionBlocker intentBlocker (intentConn); + + Glib::ustring profile; + +#ifdef WIN32 + if (profileBox.get_active_row_number () == 1) { + profile = rtengine::iccStore->getDefaultMonitorProfileName (); + if (profile.empty ()) { + profile = options.rtSettings.monitorProfile; + } + if (profile.empty ()) { + profile = "sRGB IEC61966-2.1"; + } + } else if (profileBox.get_active_row_number () > 1) { + profile = profileBox.get_active_text (); + } +#else + profile = profileBox.get_active_row_number () > 0 ? profileBox.get_active_text () : Glib::ustring (); +#endif + + if (profileBox.get_active_row_number () == 0) { + + profile.clear(); + + intentBox.set_sensitive (false); + intentBox.setSelected (0); + + } else { + const std::uint8_t supportedIntents = rtengine::iccStore->getProofIntents (profile); + const bool supportsRelativeColorimetric = supportedIntents & 1 << INTENT_RELATIVE_COLORIMETRIC; + const bool supportsPerceptual = supportedIntents & 1 << INTENT_PERCEPTUAL; + const bool supportsAbsoluteColorimetric = supportedIntents & 1 << INTENT_ABSOLUTE_COLORIMETRIC; + + if (supportsPerceptual || supportsRelativeColorimetric || supportsAbsoluteColorimetric) { + intentBox.set_sensitive (true); + intentBox.setItemSensitivity(0, supportsRelativeColorimetric); + intentBox.setItemSensitivity(1, supportsPerceptual); + intentBox.setItemSensitivity(2, supportsAbsoluteColorimetric); + } else { + intentBox.set_sensitive (false); + intentBox.setSelected (0); + } + } + + rtengine::RenderingIntent intent; + switch (intentBox.getSelected ()) { + default: + case 0: + intent = rtengine::RI_RELATIVE; + break; + case 1: + intent = rtengine::RI_PERCEPTUAL; + break; + case 2: + intent = rtengine::RI_ABSOLUTE; + break; + } + + if (!processor) { + return; + } + + processor->beginUpdateParams (); + processor->setMonitorProfile (profile, intent); + processor->endUpdateParams (rtengine::EvMonitorTransform); + } + +public: + MonitorProfileSelector (rtengine::StagedImageProcessor* const& ipc) : + intentBox (Glib::ustring (), true), + processor (ipc) + { + prepareProfileBox (); + prepareIntentBox (); + + reset (); + + profileConn = profileBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::profileBoxChanged)); + intentConn = intentBox.signal_changed ().connect (sigc::mem_fun (this, &MonitorProfileSelector::intentBoxChanged)); + } + + void pack_end_in (Gtk::Box* box) + { + box->pack_end (*intentBox.buttonGroup, Gtk::PACK_SHRINK, 0); + box->pack_end (profileBox, Gtk::PACK_SHRINK, 0); + } + + void reset () + { + ConnectionBlocker profileBlocker (profileConn); + ConnectionBlocker intentBlocker (intentConn); + +#ifdef WIN32 + if (options.rtSettings.autoMonitorProfile) { + setActiveTextOrIndex (profileBox, options.rtSettings.monitorProfile, 1); + } else { + setActiveTextOrIndex (profileBox, options.rtSettings.monitorProfile, 0); + } +#else + setActiveTextOrIndex (profileBox, options.rtSettings.monitorProfile, 0); +#endif + + switch (options.rtSettings.monitorIntent) + { + default: + case rtengine::RI_RELATIVE: + intentBox.setSelected (0); + break; + case rtengine::RI_PERCEPTUAL: + intentBox.setSelected (1); + break; + case rtengine::RI_ABSOLUTE: + intentBox.setSelected (2); + break; + } + + updateParameters (); + } + +}; + EditorPanel::EditorPanel (FilePanel* filePanel) : realized(false), iHistoryShow(NULL), iHistoryHide(NULL), iTopPanel_1_Show(NULL), iTopPanel_1_Hide(NULL), iRightPanel_1_Show(NULL), iRightPanel_1_Hide(NULL), iBeforeLockON(NULL), iBeforeLockOFF(NULL), beforePreviewHandler(NULL), beforeIarea(NULL), beforeBox(NULL), afterBox(NULL), afterHeaderBox(NULL), parent(NULL), openThm(NULL), ipc(NULL), beforeIpc(NULL), isProcessing(false), catalogPane(NULL) { @@ -179,6 +355,7 @@ EditorPanel::EditorPanel (FilePanel* filePanel) // Save buttons Gtk::HBox* iops = Gtk::manage (new Gtk::HBox ()); + iops->set_spacing(2); //Gtk::Image *saveButtonImage = Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON)); Gtk::Image *saveButtonImage = Gtk::manage (new RTImage ("gtk-save-large.png")); @@ -262,6 +439,12 @@ EditorPanel::EditorPanel (FilePanel* filePanel) iops->pack_end (*navPrev, Gtk::PACK_SHRINK, 0); } + iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); + + // Monitor profile buttons + monitorProfile.reset (new MonitorProfileSelector (ipc)); + monitorProfile->pack_end_in (iops); + editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0); editbox->pack_start (*iops, Gtk::PACK_SHRINK, 0); editbox->show_all (); @@ -568,6 +751,8 @@ void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) } history->resetSnapShotNumber(); + + monitorProfile->reset (); } void EditorPanel::close () diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index cf446da97..6de9928bd 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -84,6 +84,9 @@ protected: Gtk::Button* navNext; Gtk::Button* navPrev; + class MonitorProfileSelector; + std::auto_ptr monitorProfile; + ImageAreaPanel* iareapanel; PreviewHandler* previewHandler; PreviewHandler* beforePreviewHandler; // for the before-after view diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index e464b050e..915f0d84e 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -1152,6 +1152,7 @@ void FileCatalog::developRequested (std::vector tbe, bool fas params.icm.input = options.fastexport_icm_input ; params.icm.working = options.fastexport_icm_working ; params.icm.output = options.fastexport_icm_output ; + params.icm.outputIntent = options.fastexport_icm_outputIntent ; params.icm.gamma = options.fastexport_icm_gamma ; params.resize.enabled = options.fastexport_resize_enabled ; params.resize.scale = options.fastexport_resize_scale ; diff --git a/rtgui/flatcurveeditorsubgroup.cc b/rtgui/flatcurveeditorsubgroup.cc index 516bed44a..691fbe3dd 100644 --- a/rtgui/flatcurveeditorsubgroup.cc +++ b/rtgui/flatcurveeditorsubgroup.cc @@ -31,6 +31,7 @@ #include "myflatcurve.h" #include "curveeditor.h" #include "flatcurveeditorsubgroup.h" +#include "rtimage.h" FlatCurveEditorSubGroup::FlatCurveEditorSubGroup (CurveEditorGroup* prt, Glib::ustring& curveDir) : CurveEditorSubGroup(curveDir) { diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 1e65f2753..79f050c2f 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -76,6 +76,22 @@ public: } }; +class ConnectionBlocker +{ +public: + ConnectionBlocker (sigc::connection& connection) : connection (connection) + { + wasBlocked = connection.block(); + } + ~ConnectionBlocker () + { + connection.block(wasBlocked); + } +private: + sigc::connection& connection; + bool wasBlocked; +}; + /** * @brief Glue box to control visibility of the MyExpender's content ; also handle the frame around it */ @@ -496,5 +512,12 @@ public: } }; +inline void setActiveTextOrIndex (Gtk::ComboBoxText& comboBox, const Glib::ustring& text, int index) +{ + comboBox.set_active_text (text); + + if (comboBox.get_active_row_number () < 0) + comboBox.set_active (index); +} #endif diff --git a/rtgui/history.cc b/rtgui/history.cc index 57f7549db..689ea6394 100644 --- a/rtgui/history.cc +++ b/rtgui/history.cc @@ -24,7 +24,6 @@ using namespace rtengine; using namespace rtengine::procparams; Glib::ustring eventDescrArray[NUMOFEVENTS]; -extern Glib::ustring argv0; History::History (bool bookmarkSupport) : blistener(NULL), tpc (NULL), bmnum (1) { @@ -204,8 +203,8 @@ void History::bookmarkSelectionChanged () void History::procParamsChanged (ProcParams* params, ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited) { - // to prevent recursion, we filter out the events triggered by the history - if (ev == EvHistoryBrowsed) { + // to prevent recursion, we filter out the events triggered by the history and events that should not be registered + if (ev == EvHistoryBrowsed || ev == EvMonitorTransform) { return; } diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index e9e4e05ff..8b8057d45 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -83,7 +83,8 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch dcpFrame = Gtk::manage (new Gtk::Frame ("DCP")); Gtk::VBox* dcpFrameVBox = Gtk::manage (new Gtk::VBox ()); - dcpFrameVBox->set_border_width(4); + dcpFrameVBox->set_border_width(0); + dcpFrameVBox->set_spacing(2); Gtk::HBox* dcpIllHBox = Gtk::manage (new Gtk::HBox ()); dcpIllLabel = Gtk::manage (new Gtk::Label (M("TP_ICM_DCPILLUMINANT") + ":")); @@ -101,29 +102,25 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch dcpIllHBox->pack_start(*dcpIllLabel, Gtk::PACK_SHRINK, 4); dcpIllHBox->pack_start(*dcpIll); - Gtk::HBox* c1HBox = Gtk::manage ( new Gtk::HBox(true, 4)); ckbToneCurve = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_TONECURVE"))); ckbToneCurve->set_sensitive (false); ckbToneCurve->set_tooltip_text (M("TP_ICM_TONECURVE_TOOLTIP")); ckbApplyHueSatMap = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_APPLYHUESATMAP"))); ckbApplyHueSatMap->set_sensitive (false); ckbApplyHueSatMap->set_tooltip_text (M("TP_ICM_APPLYHUESATMAP_TOOLTIP")); - c1HBox->pack_start (*ckbToneCurve); - c1HBox->pack_start (*ckbApplyHueSatMap); - Gtk::HBox* c2HBox = Gtk::manage ( new Gtk::HBox(true, 4)); ckbApplyLookTable = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_APPLYLOOKTABLE"))); ckbApplyLookTable->set_sensitive (false); ckbApplyLookTable->set_tooltip_text (M("TP_ICM_APPLYLOOKTABLE_TOOLTIP")); ckbApplyBaselineExposureOffset = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_APPLYBASELINEEXPOSUREOFFSET"))); ckbApplyBaselineExposureOffset->set_sensitive (false); ckbApplyBaselineExposureOffset->set_tooltip_text (M("TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP")); - c2HBox->pack_start (*ckbApplyLookTable); - c2HBox->pack_start (*ckbApplyBaselineExposureOffset); - dcpFrameVBox->pack_start(*dcpIllHBox); - dcpFrameVBox->pack_start(*c1HBox); - dcpFrameVBox->pack_start(*c2HBox); + dcpFrameVBox->pack_start(*dcpIllHBox, Gtk::PACK_SHRINK, 0); + dcpFrameVBox->pack_start(*ckbToneCurve, Gtk::PACK_SHRINK,0); + dcpFrameVBox->pack_start(*ckbApplyHueSatMap, Gtk::PACK_SHRINK,0); + dcpFrameVBox->pack_start(*ckbApplyLookTable, Gtk::PACK_SHRINK,0); + dcpFrameVBox->pack_start(*ckbApplyBaselineExposureOffset, Gtk::PACK_SHRINK,0); dcpFrame->add(*dcpFrameVBox); dcpFrame->set_sensitive(false); iVBox->pack_start (*dcpFrame); @@ -185,7 +182,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch onames->append_text (M("TP_ICM_NOICM")); onames->set_active (0); - std::vector opnames = iccStore->getOutputProfiles (); + std::vector opnames = iccStore->getProfiles (); for (size_t i = 0; i < opnames.size(); i++) { onames->append_text (opnames[i]); @@ -193,6 +190,19 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch onames->set_active (0); + // Rendering intent + Gtk::HBox *riHBox = Gtk::manage ( new Gtk::HBox()); + Gtk::Label* outputIntentLbl = Gtk::manage (new Gtk::Label(M("TP_ICM_PROFILEINTENT")+":")); + riHBox->pack_start (*outputIntentLbl, Gtk::PACK_SHRINK); + ointent = Gtk::manage (new MyComboBoxText ()); + riHBox->pack_start (*ointent, Gtk::PACK_EXPAND_WIDGET); + ointent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); + ointent->append_text (M("PREFERENCES_INTENT_RELATIVE")); + ointent->append_text (M("PREFERENCES_INTENT_SATURATION")); + ointent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); + ointent->set_active (1); + oVBox->pack_start(*riHBox, Gtk::PACK_SHRINK); + // Output gamma Gtk::HBox* gaHBox = Gtk::manage (new Gtk::HBox ()); @@ -282,6 +292,7 @@ ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunch wnames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::wpChanged) ); onames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) ); + ointent->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::oiChanged) ); wgamma->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::gpChanged) ); dcpIll->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::dcpIlluminantChanged) ); @@ -507,6 +518,7 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) if (onames->get_active_row_number() == -1) { onames->set_active_text (M("TP_ICM_NOICM")); } + ointent->set_active(pp->icm.outputIntent); ckbToneCurve->set_active (pp->icm.toneCurve); lastToneCurve = pp->icm.toneCurve; @@ -545,6 +557,10 @@ void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) onames->set_active_text(M("GENERAL_UNCHANGED")); } + if (!pedited->icm.outputIntent) { + ointent->set_active_text(M("GENERAL_UNCHANGED")); + } + if (!pedited->icm.dcpIlluminant) { dcpIll->set_active_text(M("GENERAL_UNCHANGED")); } @@ -605,6 +621,13 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) pp->icm.output = onames->get_active_text(); } + int ointentVal = ointent->get_active_row_number(); + if (ointentVal >= 0 && ointentVal < RI__COUNT) { + pp->icm.outputIntent = static_cast(ointentVal); + } else { + pp->icm.outputIntent = rtengine::RI_RELATIVE; + } + pp->icm.freegamma = freegamma->get_active(); DCPProfile* dcp = NULL; @@ -641,6 +664,7 @@ void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) pedited->icm.input = !iunchanged->get_active (); pedited->icm.working = wnames->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.output = onames->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->icm.outputIntent = ointent->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.dcpIlluminant = dcpIll->get_active_text() != M("GENERAL_UNCHANGED"); pedited->icm.toneCurve = !ckbToneCurve->get_inconsistent (); pedited->icm.applyLookTable = !ckbApplyLookTable->get_inconsistent (); @@ -880,6 +904,14 @@ void ICMPanel::opChanged () } } +void ICMPanel::oiChanged () +{ + + if (listener) { + listener->panelChanged (EvOIntent, ointent->get_active_text()); + } +} + void ICMPanel::setRawMeta (bool raw, const rtengine::ImageData* pMeta) { @@ -979,6 +1011,7 @@ void ICMPanel::setBatchMode (bool batchMode) iVBox->reorder_child (*iunchanged, 5); removeIfThere (this, saveRef); onames->append_text (M("GENERAL_UNCHANGED")); + ointent->append_text (M("GENERAL_UNCHANGED")); wnames->append_text (M("GENERAL_UNCHANGED")); wgamma->append_text (M("GENERAL_UNCHANGED")); dcpIll->append_text (M("GENERAL_UNCHANGED")); diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h index 93828f5fd..863e88a46 100644 --- a/rtgui/icmpanel.h +++ b/rtgui/icmpanel.h @@ -78,6 +78,7 @@ private: MyComboBoxText* wgamma; MyComboBoxText* onames; + MyComboBoxText* ointent; Gtk::RadioButton* ofromdir; Gtk::RadioButton* ofromfile; Gtk::RadioButton* iunchanged; @@ -107,6 +108,7 @@ public: void wpChanged (); void opChanged (); + void oiChanged (); void ipChanged (); void gpChanged (); void GamChanged (); diff --git a/rtgui/options.cc b/rtgui/options.cc index 6d0b6a0d0..e6c697983 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -470,6 +470,7 @@ void Options::setDefaults () fastexport_icm_input = "(camera)"; fastexport_icm_working = "ProPhoto"; fastexport_icm_output = "RT_sRGB"; + fastexport_icm_outputIntent = rtengine::RI_RELATIVE; fastexport_icm_gamma = "default"; fastexport_resize_enabled = true; fastexport_resize_scale = 1; @@ -626,7 +627,6 @@ void Options::setDefaults () #else rtSettings.iccDirectory = "/usr/share/color/icc"; #endif - rtSettings.colorimetricIntent = 1; rtSettings.viewingdevice = 0; rtSettings.viewingdevicegrey = 3; rtSettings.viewinggreySc = 1; @@ -636,7 +636,8 @@ void Options::setDefaults () rtSettings.leveldnliss = 0; rtSettings.leveldnautsimpl = 0; - rtSettings.monitorProfile = ""; + rtSettings.monitorProfile = Glib::ustring(); + rtSettings.monitorIntent = rtengine::RI_RELATIVE; rtSettings.autoMonitorProfile = false; rtSettings.adobe = "RT_Medium_gsRGB"; // put the name of yours profiles (here windows) rtSettings.prophoto = "RT_Large_gBT709"; // these names appear in the menu "output profile" @@ -1461,7 +1462,7 @@ int Options::readFromFile (Glib::ustring fname) } if (keyFile.has_key ("Color Management", "Intent")) { - rtSettings.colorimetricIntent = keyFile.get_integer("Color Management", "Intent"); + rtSettings.monitorIntent = static_cast(keyFile.get_integer("Color Management", "Intent")); } if (keyFile.has_key ("Color Management", "CRI")) { @@ -2008,7 +2009,7 @@ int Options::saveToFile (Glib::ustring fname) keyFile.set_boolean ("Color Management", "AutoMonitorProfile", rtSettings.autoMonitorProfile); keyFile.set_boolean ("Color Management", "Autocielab", rtSettings.autocielab); keyFile.set_boolean ("Color Management", "RGBcurvesLumamode_Gamut", rtSettings.rgbcurveslumamode_gamut); - keyFile.set_integer ("Color Management", "Intent", rtSettings.colorimetricIntent); + keyFile.set_integer ("Color Management", "Intent", rtSettings.monitorIntent); keyFile.set_integer ("Color Management", "view", rtSettings.viewingdevice); keyFile.set_integer ("Color Management", "grey", rtSettings.viewingdevicegrey); keyFile.set_integer ("Color Management", "greySc", rtSettings.viewinggreySc); @@ -2075,6 +2076,7 @@ int Options::saveToFile (Glib::ustring fname) keyFile.set_string ("Fast Export", "fastexport_icm_input" , fastexport_icm_input ); keyFile.set_string ("Fast Export", "fastexport_icm_working" , fastexport_icm_working ); keyFile.set_string ("Fast Export", "fastexport_icm_output" , fastexport_icm_output ); + keyFile.set_integer ("Fast Export", "fastexport_icm_output_intent" , fastexport_icm_outputIntent ); keyFile.set_string ("Fast Export", "fastexport_icm_gamma" , fastexport_icm_gamma ); keyFile.set_boolean ("Fast Export", "fastexport_resize_enabled" , fastexport_resize_enabled ); keyFile.set_double ("Fast Export", "fastexport_resize_scale" , fastexport_resize_scale ); diff --git a/rtgui/options.h b/rtgui/options.h index 614042fa2..b896f4129 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -264,6 +264,7 @@ public: Glib::ustring fastexport_icm_input; Glib::ustring fastexport_icm_working; Glib::ustring fastexport_icm_output; + rtengine::RenderingIntent fastexport_icm_outputIntent; Glib::ustring fastexport_icm_gamma; bool fastexport_resize_enabled; double fastexport_resize_scale; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 35f26c58c..062c61ba2 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -351,6 +351,7 @@ void ParamsEdited::set (bool v) icm.dcpIlluminant = v; icm.working = v; icm.output = v; + icm.outputIntent = v; icm.gamma = v; icm.freegamma = v; icm.gampos = v; @@ -840,6 +841,7 @@ void ParamsEdited::initFrom (const std::vector icm.dcpIlluminant = icm.dcpIlluminant && p.icm.dcpIlluminant == other.icm.dcpIlluminant; icm.working = icm.working && p.icm.working == other.icm.working; icm.output = icm.output && p.icm.output == other.icm.output; + icm.outputIntent = icm.outputIntent && p.icm.outputIntent == other.icm.outputIntent; icm.gamma = icm.gamma && p.icm.gamma == other.icm.gamma; icm.freegamma = icm.freegamma && p.icm.freegamma == other.icm.freegamma; icm.gampos = icm.gampos && p.icm.gampos == other.icm.gampos; @@ -2193,6 +2195,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.icm.output = mods.icm.output; } + if (icm.outputIntent) { + toEdit.icm.outputIntent = mods.icm.outputIntent; + } + //if (icm.gampos) toEdit.icm.gampos = mods.icm.gampos; //if (icm.slpos) toEdit.icm.slpos = mods.icm.slpos; if (icm.gampos) { diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 60fbbdb81..261da1753 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -542,6 +542,7 @@ public: bool dcpIlluminant; bool working; bool output; + bool outputIntent; bool gamma; bool gampos; bool slpos; diff --git a/rtgui/popupbutton.cc b/rtgui/popupbutton.cc index 440d7b420..554f41cc6 100644 --- a/rtgui/popupbutton.cc +++ b/rtgui/popupbutton.cc @@ -21,6 +21,8 @@ #include "popupbutton.h" +#include + /* * PopUpButton::PopUpButton (const Glib::ustring& label, bool imgRight) * @@ -28,8 +30,14 @@ * * Parameters: * label = label displayed in the button + * nextOnClicked = selects the next entry if the button is clicked */ -PopUpButton::PopUpButton (const Glib::ustring& label) : Gtk::Button(), PopUpCommon(this, label) { } +PopUpButton::PopUpButton (const Glib::ustring& label, bool nextOnClicked) + : Gtk::Button () + , PopUpCommon (this, label) + , nextOnClicked(nextOnClicked) +{ +} void PopUpButton::show() { @@ -39,3 +47,27 @@ void PopUpButton::set_tooltip_text (const Glib::ustring &text) { PopUpCommon::set_tooltip_text (text); } + +void PopUpButton::set_sensitive (bool isSensitive) +{ + buttonGroup->set_sensitive(isSensitive); +} + +bool PopUpButton::on_button_release_event (GdkEventButton* event) +{ + if (nextOnClicked && getEntryCount () > 1) + { + const int last = getEntryCount () - 1; + int next = getSelected (); + + if (event->state & GDK_SHIFT_MASK) { + next = next > 0 ? next - 1 : last; + } else { + next = next < last ? next + 1 : 0; + } + + entrySelected (next); + } + + return Gtk::Button::on_button_release_event(event); +} diff --git a/rtgui/popupbutton.h b/rtgui/popupbutton.h index 23a9211a8..245d29aee 100644 --- a/rtgui/popupbutton.h +++ b/rtgui/popupbutton.h @@ -21,16 +21,24 @@ #ifndef _POPUPBUTTON_ #define _POPUPBUTTON_ -#include +#include #include "popupcommon.h" class PopUpButton : public Gtk::Button, public PopUpCommon { public: - PopUpButton (const Glib::ustring& label = ""); + PopUpButton (const Glib::ustring& label = Glib::ustring (), bool nextOnClicked = false); void show (); void set_tooltip_text (const Glib::ustring &text); + void set_sensitive (bool isSensitive=true); + +protected: + bool on_button_release_event (GdkEventButton* event); + +private: + bool nextOnClicked; + }; #endif diff --git a/rtgui/popupcommon.cc b/rtgui/popupcommon.cc index 881994589..f7e667219 100644 --- a/rtgui/popupcommon.cc +++ b/rtgui/popupcommon.cc @@ -19,12 +19,16 @@ * Class created by Jean-Christophe FRISCH, aka 'Hombre' */ +#include #include "multilangmgr.h" #include "popupcommon.h" #include "../rtengine/safegtk.h" #include "rtimage.h" PopUpCommon::PopUpCommon (Gtk::Button* thisButton, const Glib::ustring& label) + : selected (-1) // -1 means that the button is invalid + , menu (0) + , buttonImage (0) { button = thisButton; hasMenu = false; @@ -41,15 +45,6 @@ PopUpCommon::PopUpCommon (Gtk::Button* thisButton, const Glib::ustring& label) // Create the global container and put the button in it buttonGroup = Gtk::manage( new Gtk::HBox(false, 0)); buttonGroup->pack_start(*button, Gtk::PACK_EXPAND_WIDGET, 0); - // Create the list entry - imageFilenames.clear(); - images.clear(); - sItems.clear(); - items.clear(); - selected = -1; // -1 : means that the button is invalid - menu = 0; - buttonImage = 0; - buttonHint = ""; } PopUpCommon::~PopUpCommon () @@ -58,83 +53,68 @@ PopUpCommon::~PopUpCommon () delete *i; } - for (std::vector::iterator i = items.begin(); i != items.end(); ++i) { - delete *i; - } - - if (menu) { - delete menu; - } - - if (buttonImage) { - delete buttonImage; - } - - delete buttonGroup; + delete menu; + delete buttonImage; } -PopUpCommon::type_signal_changed PopUpCommon::signal_changed() +bool PopUpCommon::addEntry (const Glib::ustring& fileName, const Glib::ustring& label) { - return message; -} + if (label.empty ()) + return false; -bool PopUpCommon::addEntry (Glib::ustring fileName, Glib::ustring label) -{ - bool added = false; + // Create the image + RTImage* newImage = new RTImage(fileName); + images.push_back(newImage); + imageFilenames.push_back(fileName); + int currPos = (int)images.size(); + // Create the menu item + Gtk::ImageMenuItem* newItem = Gtk::manage(new Gtk::ImageMenuItem (*newImage, label)); - if ( label.size() ) { - imageFilenames.push_back(fileName); - sItems.push_back(label); - // Create the image - RTImage* newImage = new RTImage(fileName); - images.push_back(newImage); - int currPos = (int)images.size(); - // Create the menu item - Gtk::ImageMenuItem* newItem = new Gtk::ImageMenuItem (*newImage, label); - items.push_back(newItem); - - if (selected == -1) { - // Create the menu on the first item - menu = new Gtk::Menu (); - // Create the image for the button - buttonImage = new RTImage(fileName); - // Use the first image by default - imageContainer->pack_start(*buttonImage, Gtk::PACK_EXPAND_WIDGET); - selected = 0; - } - - // When there is at least 1 choice, we add the arrow button - if (images.size() == 1) { - Gtk::Button* arrowButton = Gtk::manage( new Gtk::Button() ); - RTImage* arrowImage = Gtk::manage( new RTImage("popuparrow.png") ); - arrowButton->add(*arrowImage); //menuSymbol); - arrowButton->set_relief (Gtk::RELIEF_NONE); - arrowButton->set_border_width (0); - buttonGroup->pack_start(*arrowButton, Gtk::PACK_SHRINK, 0); - arrowButton->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &PopUpCommon::showMenu) ); - hasMenu = true; - } - - newItem->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &PopUpCommon::entrySelected), currPos - 1)); - menu->attach (*newItem, 0, 1, currPos - 1, currPos); - // The item has been created - added = true; + if (selected == -1) { + // Create the menu on the first item + menu = new Gtk::Menu (); + // Create the image for the button + buttonImage = new RTImage(fileName); + // Use the first image by default + imageContainer->pack_start(*buttonImage, Gtk::PACK_EXPAND_WIDGET); + selected = 0; } - return added; + // When there is at least 1 choice, we add the arrow button + if (images.size() == 1) { + Gtk::Button* arrowButton = Gtk::manage( new Gtk::Button() ); + RTImage* arrowImage = Gtk::manage( new RTImage("popuparrow.png") ); + arrowButton->add(*arrowImage); //menuSymbol); + arrowButton->set_relief (Gtk::RELIEF_NONE); + arrowButton->set_border_width (0); + buttonGroup->pack_start(*arrowButton, Gtk::PACK_SHRINK, 0); + arrowButton->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &PopUpCommon::showMenu) ); + hasMenu = true; + } + + newItem->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &PopUpCommon::entrySelected), currPos - 1)); + menu->attach (*newItem, 0, 1, currPos - 1, currPos); + + return true; } // TODO: 'PopUpCommon::removeEntry' method to be created... void PopUpCommon::entrySelected (int i) { - if (setSelected((unsigned int)i)) - // Emit a a signal if the selected item has changed - { - message.emit(selected); + // Emit a a signal if the selected item has changed + if (setSelected (i)) + message (selected); +} + +void PopUpCommon::setItemSensitivity (int i, bool isSensitive) { + Gtk::Menu_Helpers::MenuList items = menu->items(); + if (i < items.size()) { + items[i].set_sensitive(isSensitive); } } + /* * Set the button image with the selected item */ @@ -172,7 +152,12 @@ void PopUpCommon::setButtonHint() } if (selected > -1) { - hint += sItems.at(selected); + // HACK: Gtk::MenuItem::get_label does not seem to work reliably. + Gtk::MenuItem& item = menu->items ()[selected]; + Gtk::Label* label = dynamic_cast(item.get_child ()); + + if (label) + hint += label->get_text (); } button->set_tooltip_markup(hint); diff --git a/rtgui/popupcommon.h b/rtgui/popupcommon.h index 872beb434..b5cb757f4 100644 --- a/rtgui/popupcommon.h +++ b/rtgui/popupcommon.h @@ -21,11 +21,21 @@ #ifndef _POPUPCOMMON_ #define _POPUPCOMMON_ +#include +#include +#include -#include -#include -#include "rtimage.h" +namespace Gtk +{ +class HBox; +class Menu; +class Button; +class ImageMenuItem; +} +typedef struct _GdkEventButton GdkEventButton; + +class RTImage; class PopUpCommon { @@ -37,27 +47,20 @@ public: PopUpCommon (Gtk::Button* button, const Glib::ustring& label = ""); virtual ~PopUpCommon (); - bool addEntry (Glib::ustring fileName, Glib::ustring label); + bool addEntry (const Glib::ustring& fileName, const Glib::ustring& label); + int getEntryCount () const; bool setSelected (int entryNum); - int getSelected () - { - return selected; - } + int getSelected () const; void setButtonHint(); void show (); void set_tooltip_text (const Glib::ustring &text); + void setItemSensitivity (int i, bool isSensitive); private: type_signal_changed message; - /* - TODO: MenuItem::get_label() doesn't return any string, or an empty string !? - That's why we store entries strings in sItems, but it would be nice to get ride of it... - */ - std::vector sItems; std::vector imageFilenames; std::vector images; - std::vector items; Glib::ustring buttonHint; RTImage* buttonImage; Gtk::HBox* imageContainer; @@ -67,8 +70,25 @@ private: bool hasMenu; void showMenu(GdkEventButton* event); + +protected: void entrySelected (int i); }; +inline PopUpCommon::type_signal_changed PopUpCommon::signal_changed () +{ + return message; +} + +inline int PopUpCommon::getEntryCount () const +{ + return images.size(); +} + +inline int PopUpCommon::getSelected () const +{ + return selected; +} + #endif diff --git a/rtgui/popuptogglebutton.h b/rtgui/popuptogglebutton.h index 58342e66c..930fae4f2 100644 --- a/rtgui/popuptogglebutton.h +++ b/rtgui/popuptogglebutton.h @@ -21,7 +21,7 @@ #ifndef _POPUPTOGGLEBUTTON_ #define _POPUPTOGGLEBUTTON_ -#include "popupbutton.h" +#include #include "popupcommon.h" class PopUpToggleButton : public Gtk::ToggleButton, public PopUpCommon diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index dca0eff17..f5adf43e0 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -687,32 +687,29 @@ Gtk::Widget* Preferences::getColorManagementPanel () Gtk::VBox* mvbcm = Gtk::manage (new Gtk::VBox ()); mvbcm->set_border_width (4); - /* - Gtk::Label* intlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_CMETRICINTENT")+":", Gtk::ALIGN_LEFT)); - intent = Gtk::manage (new Gtk::ComboBoxText ()); - intent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); - intent->append_text (M("PREFERENCES_INTENT_RELATIVE")); - intent->append_text (M("PREFERENCES_INTENT_SATURATION")); - intent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); - */ iccDir = Gtk::manage (new Gtk::FileChooserButton (M("PREFERENCES_ICCDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); Gtk::Label* pdlabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_ICCDIR") + ":", Gtk::ALIGN_LEFT)); - Gtk::FileFilter monProfileFilter_colprof; - monProfileFilter_colprof.set_name(M("FILECHOOSER_FILTER_COLPROF")); - monProfileFilter_colprof.add_pattern("*.icc"); - monProfileFilter_colprof.add_pattern("*.ICC"); - monProfileFilter_colprof.add_pattern("*.icm"); - monProfileFilter_colprof.add_pattern("*.ICM"); - Gtk::FileFilter monProfileFilter_any; - monProfileFilter_any.set_name(M("FILECHOOSER_FILTER_ANY")); - monProfileFilter_any.add_pattern("*"); + monProfile = Gtk::manage (new Gtk::ComboBoxText ()); + Gtk::Label* mplabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_MONPROFILE") + ":", Gtk::ALIGN_LEFT)); - monProfile = Gtk::manage (new Gtk::FileChooserButton (M("PREFERENCES_MONITORICC"), Gtk::FILE_CHOOSER_ACTION_OPEN)); - monProfile->add_filter (monProfileFilter_colprof); - monProfile->add_filter (monProfileFilter_any); - Gtk::Label* mplabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_MONITORICC") + ":", Gtk::ALIGN_LEFT)); + monIntent = Gtk::manage (new Gtk::ComboBoxText ()); + Gtk::Label* milabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_MONINTENT")+":", Gtk::ALIGN_LEFT)); + + monProfile->append_text (M("PREFERENCES_PROFILE_NONE")); + monProfile->set_active (0); + + const std::vector profiles = rtengine::ICCStore::getInstance ()->getProfiles (); + for (std::vector::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile) + monProfile->append_text (*profile); + + monIntent->append_text (M("PREFERENCES_INTENT_RELATIVE")); + monIntent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); + monIntent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); + monIntent->set_active (1); + + iccDir->signal_selection_changed ().connect (sigc::mem_fun (this, &Preferences::iccDirChanged)); #if defined(WIN32) // Auto-detection not implemented for Linux, see issue 851 cbAutoMonProfile = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_AUTOMONPROFILE"))); @@ -720,17 +717,21 @@ Gtk::Widget* Preferences::getColorManagementPanel () #endif Gtk::Table* colt = Gtk::manage (new Gtk::Table (3, 2)); - //colt->attach (*intlab, 0, 1, 0, 1, Gtk::FILL, Gtk::SHRINK, 2, 2); - //colt->attach (*intent, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); - colt->attach (*pdlabel, 0, 1, 1, 2, Gtk::FILL, Gtk::SHRINK, 2, 2); - colt->attach (*iccDir, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + int row = 0; + colt->attach (*pdlabel, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + colt->attach (*iccDir, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); #if !defined(__APPLE__) // monitor profile not supported on apple - colt->attach (*mplabel, 0, 1, 2, 3, Gtk::FILL, Gtk::SHRINK, 2, 2); - colt->attach (*monProfile, 1, 2, 2, 3, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + ++row; + colt->attach (*mplabel, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + colt->attach (*monProfile, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); #if defined(WIN32) - colt->attach (*cbAutoMonProfile, 1, 2, 3, 4, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + ++row; + colt->attach (*cbAutoMonProfile, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); #endif #endif + ++row; + colt->attach (*milabel, 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + colt->attach (*monIntent, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); mvbcm->pack_start (*colt, Gtk::PACK_SHRINK, 4); #if defined(WIN32) @@ -1445,10 +1446,25 @@ void Preferences::storePreferences () moptions.CPBPath = txtCustProfBuilderPath->get_text(); moptions.CPBKeys = CPBKeyType(custProfBuilderLabelType->get_active_row_number()); - moptions.rtSettings.monitorProfile = monProfile->get_filename (); +#if !defined(__APPLE__) // monitor profile not supported on apple + moptions.rtSettings.monitorProfile = monProfile->get_active_text (); + switch (monIntent->get_active_row_number ()) { + default: + case 0: + moptions.rtSettings.monitorIntent = rtengine::RI_RELATIVE; + break; + case 1: + moptions.rtSettings.monitorIntent = rtengine::RI_PERCEPTUAL; + break; + case 2: + moptions.rtSettings.monitorIntent = rtengine::RI_ABSOLUTE; + break; + } #if defined(WIN32) moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active (); #endif +#endif + moptions.rtSettings.iccDirectory = iccDir->get_filename (); //moptions.rtSettings.colorimetricIntent = intent->get_active_row_number (); moptions.rtSettings.viewingdevice = view->get_active_row_number (); @@ -1561,13 +1577,18 @@ void Preferences::fillPreferences () rememberZoomPanCheckbutton->set_active (moptions.rememberZoomAndPan); ctiffserialize->set_active(moptions.serializeTiffRead); #if !defined(__APPLE__) // monitor profile not supported on apple - - if (safe_file_test (moptions.rtSettings.monitorProfile, Glib::FILE_TEST_EXISTS)) { - monProfile->set_filename (moptions.rtSettings.monitorProfile); - } - - if (moptions.rtSettings.monitorProfile.empty()) { - monProfile->set_current_folder (moptions.rtSettings.iccDirectory); + setActiveTextOrIndex (*monProfile, moptions.rtSettings.monitorProfile, 0); + switch (moptions.rtSettings.monitorIntent) { + default: + case rtengine::RI_RELATIVE: + monIntent->set_active (0); + break; + case rtengine::RI_PERCEPTUAL: + monIntent->set_active (1); + break; + case rtengine::RI_ABSOLUTE: + monIntent->set_active (2); + break; } #if defined(WIN32) @@ -1579,7 +1600,6 @@ void Preferences::fillPreferences () iccDir->set_current_folder (moptions.rtSettings.iccDirectory); } - //intent->set_active (moptions.rtSettings.colorimetricIntent); view->set_active (moptions.rtSettings.viewingdevice); grey->set_active (moptions.rtSettings.viewingdevicegrey); greySc->set_active (moptions.rtSettings.viewinggreySc); @@ -1931,6 +1951,21 @@ void Preferences::bundledProfilesChanged () rpconn.block (false); } +void Preferences::iccDirChanged () +{ + const Glib::ustring currentSelection = monProfile->get_active_text (); + + monProfile->clear(); + + monProfile->append_text (M("PREFERENCES_PROFILE_NONE")); + monProfile->set_active (0); + const std::vector profiles = rtengine::ICCStore::getInstance ()->getProfilesFromDir (iccDir->get_filename ()); + for (std::vector::const_iterator profile = profiles.begin (); profile != profiles.end (); ++profile) + monProfile->append_text (*profile); + + monProfile->set_active_text (currentSelection); +} + void Preferences::storeCurrentValue() { // TODO: Find a way to get and restore the current selection; the following line can't work anymore diff --git a/rtgui/preferences.h b/rtgui/preferences.h index ee885c568..1cfb435cf 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -95,7 +95,8 @@ protected: Gtk::CheckButton* showExpComp; Gtk::FileChooserButton* iccDir; - Gtk::FileChooserButton* monProfile; + Gtk::ComboBoxText* monProfile; + Gtk::ComboBoxText* monIntent; Gtk::CheckButton* cbAutoMonProfile; //Gtk::CheckButton* cbAutocielab; Gtk::CheckButton* cbciecamfloat; @@ -106,7 +107,6 @@ protected: Gtk::SpinButton* panFactor; Gtk::CheckButton* rememberZoomPanCheckbutton; - Gtk::ComboBoxText* intent; Gtk::ComboBoxText* view; Gtk::ComboBoxText* grey; Gtk::ComboBoxText* greySc; @@ -212,7 +212,8 @@ protected: void forRAWComboChanged (); void forImageComboChanged (); void layoutComboChanged (); - void bundledProfilesChanged(); + void bundledProfilesChanged (); + void iccDirChanged (); void switchThemeTo (Glib::ustring newTheme, bool slimInterface); void switchFontTo (Glib::ustring newFont); bool splashClosed(GdkEventAny* event); diff --git a/rtgui/retinex.cc b/rtgui/retinex.cc index eca9f7a91..fb69de3e3 100644 --- a/rtgui/retinex.cc +++ b/rtgui/retinex.cc @@ -3,6 +3,7 @@ */ #include "retinex.h" #include "mycurve.h" +#include "rtimage.h" using namespace rtengine; using namespace rtengine::procparams; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 4bebb10ad..abab1d2d1 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -21,6 +21,7 @@ #include #include "edit.h" #include "guiutils.h" +#include "rtimage.h" using namespace rtengine; using namespace rtengine::procparams; diff --git a/tools/source_icons/scalable/intent-absolute.file b/tools/source_icons/scalable/intent-absolute.file new file mode 100644 index 000000000..57278bff2 --- /dev/null +++ b/tools/source_icons/scalable/intent-absolute.file @@ -0,0 +1 @@ +intent-absolute.png,w25,actions diff --git a/tools/source_icons/scalable/intent-absolute.svg b/tools/source_icons/scalable/intent-absolute.svg new file mode 100644 index 000000000..b5092b0c5 --- /dev/null +++ b/tools/source_icons/scalable/intent-absolute.svg @@ -0,0 +1,1376 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/intent-perceptual.file b/tools/source_icons/scalable/intent-perceptual.file new file mode 100644 index 000000000..3e7520042 --- /dev/null +++ b/tools/source_icons/scalable/intent-perceptual.file @@ -0,0 +1 @@ +intent-perceptual.png,w25,actions diff --git a/tools/source_icons/scalable/intent-perceptual.svg b/tools/source_icons/scalable/intent-perceptual.svg new file mode 100644 index 000000000..3c949c91e --- /dev/null +++ b/tools/source_icons/scalable/intent-perceptual.svg @@ -0,0 +1,1362 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/intent-relative.file b/tools/source_icons/scalable/intent-relative.file new file mode 100644 index 000000000..5191a25c3 --- /dev/null +++ b/tools/source_icons/scalable/intent-relative.file @@ -0,0 +1 @@ +intent-relative.png,w25,actions diff --git a/tools/source_icons/scalable/intent-relative.svg b/tools/source_icons/scalable/intent-relative.svg new file mode 100644 index 000000000..706de23d1 --- /dev/null +++ b/tools/source_icons/scalable/intent-relative.svg @@ -0,0 +1,1361 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/tools/source_icons/scalable/intent-saturation.file b/tools/source_icons/scalable/intent-saturation.file new file mode 100644 index 000000000..9f33b978e --- /dev/null +++ b/tools/source_icons/scalable/intent-saturation.file @@ -0,0 +1 @@ +intent-saturation.png,w25,actions diff --git a/tools/source_icons/scalable/intent-saturation.svg b/tools/source_icons/scalable/intent-saturation.svg new file mode 100644 index 000000000..1af08f4f2 --- /dev/null +++ b/tools/source_icons/scalable/intent-saturation.svg @@ -0,0 +1,1362 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/softProof.file b/tools/source_icons/scalable/softProof.file new file mode 100644 index 000000000..e275113ec --- /dev/null +++ b/tools/source_icons/scalable/softProof.file @@ -0,0 +1 @@ +softProof.png,w22,actions diff --git a/tools/source_icons/scalable/softProof.svg b/tools/source_icons/scalable/softProof.svg new file mode 100644 index 000000000..d09f316a2 --- /dev/null +++ b/tools/source_icons/scalable/softProof.svg @@ -0,0 +1,1389 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + From d146809651e2a676e816ef0aeb3a52f4532727b7 Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Mon, 4 Jan 2016 02:39:55 +0100 Subject: [PATCH 58/61] Several fixes to Retinex additions, issue #2969 --- rtdata/languages/default | 47 ++++++++++++++++++++-------------------- rtengine/procevents.h | 1 - rtengine/refreshmap.cc | 33 ++++++++++++++-------------- 3 files changed, 40 insertions(+), 41 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index c361da52f..e7a2b97f6 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -642,7 +642,7 @@ HISTORY_MSG_408;Retinex - Radius HISTORY_MSG_409;Retinex - Contrast HISTORY_MSG_410;Retinex - Brightness HISTORY_MSG_411;Retinex - Strength -HISTORY_MSG_412;Retinex - G. Gradient +HISTORY_MSG_412;Retinex - Gaussian Gradient HISTORY_MSG_413;Retinex - Variance HISTORY_MSG_414;Retinex - Histogram - Lab HISTORY_MSG_415;Retinex - Transmission @@ -658,17 +658,18 @@ HISTORY_MSG_424;Retinex - HL threshold HISTORY_MSG_425;Retinex - Log base HISTORY_MSG_426;Retinex - Hue equalizer HISTORY_MSG_427;Output rendering intent -HISTORY_MSG_428;Retinex - Iterations -HISTORY_MSG_429;Retinex - T. Gradient -HISTORY_MSG_430;Retinex - S. Gradient -HISTORY_MSG_431;Retinex - Mask highlights -HISTORY_MSG_432;Retinex - Mask TW highlights -HISTORY_MSG_433;Retinex - Mask shadows -HISTORY_MSG_434;Retinex - Mask TW shadows -HISTORY_MSG_435;Retinex - Mask radius -HISTORY_MSG_436;Retinex - Mask method -HISTORY_MSG_437;Retinex - Mask curve -HISTORY_MSG_438;Retinex - Preview +HISTORY_MSG_428;Monitor rendering intent +HISTORY_MSG_429;Retinex - Iterations +HISTORY_MSG_430;Retinex - Transmission Gradient +HISTORY_MSG_431;Retinex - Strength Gradient +HISTORY_MSG_432;Retinex - M - Highlights +HISTORY_MSG_433;Retinex - M - Highlights TW +HISTORY_MSG_434;Retinex - M - Shadows +HISTORY_MSG_435;Retinex - M - Shadows TW +HISTORY_MSG_436;Retinex - M - Radius +HISTORY_MSG_437;Retinex - M - Method +HISTORY_MSG_438;Retinex - M - Equalizer +HISTORY_MSG_439;Retinex - Preview HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot @@ -1657,13 +1658,13 @@ TP_RETINEX_CONTEDIT_LAB;Histogram equalizer L*a*b* TP_RETINEX_CONTEDIT_LH;Hue equalizer TP_RETINEX_CONTEDIT_MAP;Mask equalizer TP_RETINEX_CURVEEDITOR_MAP;L=f(L) -TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This Curve can be applied alone or with gaussian mask or wavelet mask\nBe aware to artifacts +TP_RETINEX_CURVEEDITOR_MAP_TOOLTIP;This curve can be applied alone or with a Gaussian mask or wavelet mask.\nBeware of artifacts! TP_RETINEX_CURVEEDITOR_CD;L=f(L) TP_RETINEX_CURVEEDITOR_CD_TOOLTIP;Luminance according to luminance L=f(L)\nCorrect raw data to reduce halos and artifacts. TP_RETINEX_CURVEEDITOR_LH;Strength=f(H) TP_RETINEX_CURVEEDITOR_LH_TOOLTIP;Strength according to hue Strength=f(H)\nThis curve also acts on chroma when using the "Highlight" retinex method. TP_RETINEX_FREEGAMMA;Free gamma -TP_RETINEX_GAIN;Gain +TP_RETINEX_GAIN;Contrast TP_RETINEX_GAIN_TOOLTIP;Acts on the restored image.\n\nThis is very different from the others settings. Used for black or white pixels, and to help balance the histogram. TP_RETINEX_GAMMA;Gamma TP_RETINEX_GAMMA_FREE;Free @@ -1679,17 +1680,17 @@ TP_RETINEX_HIGHLIGHT_TOOLTIP;Increase action of High algorithm.\nMay require you TP_RETINEX_HSLSPACE_LIN;HSL-Linear TP_RETINEX_HSLSPACE_LOG;HSL-Logarithmic TP_RETINEX_ITER;Iterations (Tone-mapping) -TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator\nHigh values increase the processing time +TP_RETINEX_ITER_TOOLTIP;Simulate a tone-mapping operator.\nHigh values increase the processing time. TP_RETINEX_GRAD;Transmission gradient -TP_RETINEX_GRAD_TOOLTIP;If slider at 0, all iterations are identical\nIf > 0 Variance and Threshold are reduce when iteration increases and conversely +TP_RETINEX_GRAD_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Variance and Threshold are reduced when iterations increase, and conversely. TP_RETINEX_GRADS;Strength gradient -TP_RETINEX_GRADS_TOOLTIP;If slider at 0, all iterations are identical\nIf > 0 Strength is reduce when iteration increases and conversely +TP_RETINEX_GRADS_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Strength is reduced when iterations increase, and conversely. TP_RETINEX_LABEL;Retinex TP_RETINEX_LABSPACE;L*a*b* TP_RETINEX_LOW;Low TP_RETINEX_MAP;Mask method -TP_RETINEX_MAP_METHOD_TOOLTIP;Use the mask generate by Gaussian function above to reduce halos and artifacts\nCurve only: apply a diagonal contrast curve on mask, be aware to artifacts\nGaussian mask : generate and use a gaussian blur of the original mask (quick)\nSharp mask : generate and use a wavelet on the original mask (slow or very very slow) -TP_RETINEX_MAP_NONE;none +TP_RETINEX_MAP_METHOD_TOOLTIP;Use the mask generated by the Gaussian function above to reduce halos and artifacts.\n\nCurve only: apply a diagonal contrast curve on the mask.\nBeware of artifacts!\n\nGaussian mask: generate and use a Gaussian blur of the original mask.\nQuick.\n\nSharp mask: generate and use a wavelet on the original mask.\nSlow. +TP_RETINEX_MAP_NONE;None TP_RETINEX_MAP_CURV;Curve only TP_RETINEX_MAP_GAUS;Gaussian mask TP_RETINEX_MAP_MAPP;Sharp mask (wavelet partial) @@ -1705,7 +1706,7 @@ TP_RETINEX_NEUTRAL_TIP;Reset all sliders and curves to their default values. TP_RETINEX_OFFSET;Brightness TP_RETINEX_SETTINGS;Settings TP_RETINEX_SCALES;Gaussian gradient -TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical\nIf > 0 Scale and Neighboring pixels are reduce when iteration increases and conversely +TP_RETINEX_SCALES_TOOLTIP;If slider at 0, all iterations are identical.\nIf > 0 Scale and Neighboring pixels are reduced when iterations increase, and conversely. TP_RETINEX_SLOPE;Free gamma slope TP_RETINEX_STRENGTH;Strength TP_RETINEX_THRESHOLD;Threshold @@ -1722,9 +1723,9 @@ TP_RETINEX_VIEW;Process (Preview) TP_RETINEX_VIEW_NONE;Standard TP_RETINEX_VIEW_MASK;Mask TP_RETINEX_VIEW_UNSHARP;Unsharp mask -TP_RETINEX_VIEW_TRAN;Transmission (auto) -TP_RETINEX_VIEW_TRAN2;Transmission (fixed) -TP_RETINEX_VIEW_METHOD_TOOLTIP;Standard - normal display\nMask - display mask\nUnsharp mask - display image with high radius unsharp mask\nTransmission (auto - fixed) - displays the file transmission-map , before any action on contrast and brightness\nAttention, this does not correspond to reality, but a shift (or auto) to make it visible +TP_RETINEX_VIEW_TRAN;Transmission - Auto +TP_RETINEX_VIEW_TRAN2;Transmission - Fixed +TP_RETINEX_VIEW_METHOD_TOOLTIP;Standard - Normal display.\nMask - Displays the mask.\nUnsharp mask - Displays the image with a high radius unsharp mask.\nTransmission - Auto/Fixed - Displays the file transmission-map, before any action on contrast and brightness.\n\nAttention: the mask does not correspond to reality, but is amplified to make it more visible. TP_RGBCURVES_BLUE;B TP_RGBCURVES_CHANNEL;Channel TP_RGBCURVES_GREEN;G diff --git a/rtengine/procevents.h b/rtengine/procevents.h index be95686be..558f509c2 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -452,7 +452,6 @@ enum ProcEvent { EvLslope = 422, EvLhighl = 423, EvLbaselog = 424, -// EvLgrbl = 425, EvRetinexlhcurve = 425, EvOIntent = 426, EvMonitorTransform = 427, diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 607aa1226..b23212aeb 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -25,7 +25,7 @@ -// Aligned so the first entry starts on line 30 +// Aligned so the first entry starts on line 30. int refreshmap[rtengine::NUMOFEVENTS] = { ALL, // EvPhotoLoaded, ALL, // EvProfileLoaded, @@ -440,32 +440,31 @@ int refreshmap[rtengine::NUMOFEVENTS] = { RETINEX, // EvLstr RETINEX, // EvLscal RETINEX, // EvLvart - DEMOSAIC, // EvLCDCurve + DEMOSAIC, // EvLCDCurve RETINEX, // EvRetinextransmission DEMOSAIC, // EvRetinexEnabled RETINEX, // EvRetinexmedianmap RETINEX, // EvLlimd DEMOSAIC, // Evretinexcolorspace - DEMOSAIC, // EvLCDHCurve + DEMOSAIC, // EvLCDHCurve DEMOSAIC, // Evretinexgamma DEMOSAIC, // EvLgam DEMOSAIC, // EvLslope RETINEX, // EvLhighl DEMOSAIC, // EvLbaselog -// DEMOSAIC, // EvLgrbl - DEMOSAIC, // EvRetinexlhcurve + DEMOSAIC, // EvRetinexlhcurve ALLNORAW, // EvOIntent - MONITORTRANSFORM, // EvMonitorTransform - RETINEX, // EvLiter - RETINEX, // EvLgrad - RETINEX, // EvLgrads - RETINEX, //EvLhighlights - RETINEX, //EvLh_tonalwidth - RETINEX, //EvLshadows - RETINEX, //EvLs_tonalwidth - RETINEX, //EvLradius - RETINEX, //EvmapMethod - DEMOSAIC, //EvRetinexmapcurve - DEMOSAIC //EvviewMethod + MONITORTRANSFORM, // EvMonitorTransform: no history message + RETINEX, // EvLiter + RETINEX, // EvLgrad + RETINEX, // EvLgrads + RETINEX, // EvLhighlights + RETINEX, // EvLh_tonalwidth + RETINEX, // EvLshadows + RETINEX, // EvLs_tonalwidth + RETINEX, // EvLradius + RETINEX, // EvmapMethod + DEMOSAIC, // EvRetinexmapcurve + DEMOSAIC // EvviewMethod }; From f85d9a5b4523156e88164397442c988b3f32b4fc Mon Sep 17 00:00:00 2001 From: Beep6581 Date: Mon, 4 Jan 2016 02:41:16 +0100 Subject: [PATCH 59/61] History message fixed for Wavelet's "'After' contrast curve", closes #2992 --- rtdata/languages/default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index e7a2b97f6..8a43155c9 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -597,7 +597,7 @@ HISTORY_MSG_363;W - Residual - Compression strength HISTORY_MSG_364;W - Final - Contrast balance HISTORY_MSG_365;W - Final - Delta balance HISTORY_MSG_366;W - Residual - Compression gamma -HISTORY_MSG_367;W - ES - Local contrast curve +HISTORY_MSG_367;W - Final - 'After' contrast curve HISTORY_MSG_368;W - Final - Contrast balance HISTORY_MSG_369;W - Final - Balance method HISTORY_MSG_370;W - Final - Local contrast curve From f66e838eb97af45603bee83636223136bc79f613 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Mon, 4 Jan 2016 21:02:40 +0100 Subject: [PATCH 60/61] Fix enforcing the cache size limit and modernize the cache manager. --- rtgui/cachemanager.cc | 460 +++++++++++++++++++++--------------------- rtgui/cachemanager.h | 53 +++-- rtgui/preferences.cc | 2 +- rtgui/thumbnail.cc | 2 +- 4 files changed, 253 insertions(+), 264 deletions(-) diff --git a/rtgui/cachemanager.cc b/rtgui/cachemanager.cc index 0b88ea5f4..4d3519cf1 100644 --- a/rtgui/cachemanager.cc +++ b/rtgui/cachemanager.cc @@ -17,372 +17,362 @@ * along with RawTherapee. If not, see . */ #include "cachemanager.h" -#include "options.h" -#include -#include -#include "guiutils.h" -#include "procparamchangers.h" -#include "../rtengine/safegtk.h" + #ifdef WIN32 #include #endif -CacheManager* -CacheManager::getInstance(void) +#include +#include + +#include "guiutils.h" +#include "options.h" +#include "procparamchangers.h" +#include "thumbnail.h" + +namespace { - static CacheManager instance_; - return &instance_; + +constexpr auto cacheDirMode = 511; +constexpr auto cacheDirs = { "profiles", "images", "aehistograms", "embprofiles", "data" }; + +} + +CacheManager* CacheManager::getInstance () +{ + static CacheManager instance; + return &instance; } void CacheManager::init () { - - MyMutex::MyLock lock(mutex_); + MyMutex::MyLock lock (mutex); openEntries.clear (); baseDir = options.cacheBaseDir; - if (!safe_file_test (baseDir, Glib::FILE_TEST_IS_DIR)) { - safe_g_mkdir_with_parents (baseDir, 511); + auto error = g_mkdir_with_parents (baseDir.c_str(), cacheDirMode); + + for (const auto& cacheDir : cacheDirs) { + error |= g_mkdir_with_parents (Glib::build_filename (baseDir, cacheDir).c_str(), cacheDirMode); } - if (!safe_file_test (Glib::build_filename (baseDir, "profiles"), Glib::FILE_TEST_IS_DIR)) { - safe_g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "profiles")), 511); - } - - if (!safe_file_test (Glib::build_filename (baseDir, "images"), Glib::FILE_TEST_IS_DIR)) { - safe_g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "images")), 511); - } - - if (!safe_file_test (Glib::build_filename (baseDir, "aehistograms"), Glib::FILE_TEST_IS_DIR)) { - safe_g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "aehistograms")), 511); - } - - if (!safe_file_test (Glib::build_filename (baseDir, "embprofiles"), Glib::FILE_TEST_IS_DIR)) { - safe_g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "embprofiles")), 511); - } - - if (!safe_file_test (Glib::build_filename (baseDir, "data"), Glib::FILE_TEST_IS_DIR)) { - safe_g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "data")), 511); + if (error != 0 && options.rtSettings.verbose) { + std::cerr << "Failed to create all cache directories: " << g_strerror(errno) << std::endl; } } Thumbnail* CacheManager::getEntry (const Glib::ustring& fname) { + std::unique_ptr thumbnail; - Thumbnail* res = NULL; - - // take manager lock and search for entry, if found return it else release - // lock and create it + // take manager lock and search for entry, + // if found return it, + // else release lock and create it { - MyMutex::MyLock lock(mutex_); - - string_thumb_map::iterator r = openEntries.find (fname); + MyMutex::MyLock lock (mutex); // if it is open, return it - if (r != openEntries.end()) { - r->second->increaseRef (); - return r->second; + const auto iterator = openEntries.find (fname); + if (iterator != openEntries.end ()) { + + auto cachedThumbnail = iterator->second; + + cachedThumbnail->increaseRef (); + return cachedThumbnail; } } - // compute the md5 - std::string md5 = getMD5 (fname); - - if (md5 == "") { - return NULL; - } - // build path name - Glib::ustring cfname = getCacheFileName ("data", fname, md5) + ".txt"; + const auto md5 = getMD5 (fname); + + if (md5.empty ()) { + return nullptr; + } + + const auto cacheName = getCacheFileName ("data", fname, ".txt", md5); // let's see if we have it in the cache - if (safe_file_test (cfname, Glib::FILE_TEST_EXISTS)) { - CacheImageData* cfs = new CacheImageData (); - int e = cfs->load (cfname); + { + CacheImageData imageData; - if (!e && cfs->supported == true) { - res = new Thumbnail (this, fname, cfs); + const auto error = imageData.load (cacheName); + if (error == 0 && imageData.supported) { + + thumbnail.reset (new Thumbnail (this, fname, &imageData)); + if (!thumbnail->isSupported ()) { + thumbnail.reset (); + } } - - if (res && !res->isSupported ()) { - delete res; - res = NULL; - } - - delete cfs; } // if not, create a new one - if (!res) { - res = new Thumbnail (this, fname, md5); + if (!thumbnail) { - if (!res->isSupported ()) { - delete res; - res = NULL; + thumbnail.reset (new Thumbnail (this, fname, md5)); + if (!thumbnail->isSupported ()) { + thumbnail.reset (); } } // retake the lock and see if it was added while we we're unlocked, if it // was use it over our version. if not added we create the cache entry - if (res) { - MyMutex::MyLock lock(mutex_); + if (thumbnail) { + MyMutex::MyLock lock (mutex); - string_thumb_map::iterator r = openEntries.find (fname); + const auto iterator = openEntries.find (fname); + if (iterator != openEntries.end ()) { - if (r != openEntries.end()) { - delete res; - r->second->increaseRef (); - return r->second; + auto cachedThumbnail = iterator->second; + + cachedThumbnail->increaseRef (); + return cachedThumbnail; } // it wasn't, create a new entry - openEntries[fname] = res; + openEntries.emplace (fname, thumbnail.get ()); } - return res; + return thumbnail.release (); } void CacheManager::deleteEntry (const Glib::ustring& fname) { - - MyMutex::MyLock lock(mutex_); + MyMutex::MyLock lock (mutex); // check if it is opened - string_thumb_map::iterator r = openEntries.find (fname); + auto iterator = openEntries.find (fname); + if (iterator == openEntries.end ()) { + deleteFiles (fname, getMD5 (fname), true, true); + return; + } - // if it is open, dont delete it - if (r != openEntries.end()) { - std::string md5 = r->second->getMD5 (); + auto thumbnail = iterator->second; - // decrease reference count; this will call back into CacheManager so - // we release the lock for it. - { - lock.release(); - r->second->decreaseRef (); - lock.acquire(); - } + // decrease reference count; + // this will call back into CacheManager, + // so we release the lock for it + { + lock.release (); + thumbnail->decreaseRef (); + lock.acquire (); + } - // if in the editor, the thumbnail still exists. If not, delete it: - r = openEntries.find (fname); - - if (r == openEntries.end() && md5 != "") { - safe_g_remove (getCacheFileName ("data", fname, md5) + ".txt"); - safe_g_remove (getCacheFileName ("profiles", fname, md5) + paramFileExtension); - safe_g_remove (getCacheFileName ("images", fname, md5) + ".rtti"); - safe_g_remove (getCacheFileName ("images", fname, md5) + ".cust16"); - safe_g_remove (getCacheFileName ("images", fname, md5) + ".cust"); - safe_g_remove (getCacheFileName ("images", fname, md5) + ".jpg"); - safe_g_remove (getCacheFileName ("aehistograms", fname, md5)); - safe_g_remove (getCacheFileName ("embprofiles", fname, md5) + ".icc"); - } - } else { - std::string md5 = getMD5 (fname); - - if (md5 != "") { - safe_g_remove (getCacheFileName ("data", fname, md5) + ".txt"); - safe_g_remove (getCacheFileName ("profiles", fname, md5) + paramFileExtension); - safe_g_remove (getCacheFileName ("images", fname, md5) + ".rtti"); - safe_g_remove (getCacheFileName ("images", fname, md5) + ".cust16"); - safe_g_remove (getCacheFileName ("images", fname, md5) + ".cust"); - safe_g_remove (getCacheFileName ("images", fname, md5) + ".jpg"); - safe_g_remove (getCacheFileName ("aehistograms", fname, md5)); - safe_g_remove (getCacheFileName ("embprofiles", fname, md5) + ".icc"); - } + // check again if in the editor, + // the thumbnail still exists, + // if not, delete it + if (openEntries.count (fname) == 0) { + deleteFiles (fname, thumbnail->getMD5 (), true, true); } } -void CacheManager::clearFromCache (const Glib::ustring& fname, bool leavenotrace) +void CacheManager::clearFromCache (const Glib::ustring& fname, bool purge) const { - std::string md5 = getMD5 (fname); - - if (md5 != "") { - if (leavenotrace) { - safe_g_remove (getCacheFileName ("data", fname, md5) + ".txt"); - safe_g_remove (getCacheFileName ("profiles", fname, md5) + paramFileExtension); - } - - safe_g_remove (getCacheFileName ("images", fname, md5) + ".rtti"); - safe_g_remove (getCacheFileName ("images", fname, md5) + ".cust16"); - safe_g_remove (getCacheFileName ("images", fname, md5) + ".cust"); - safe_g_remove (getCacheFileName ("images", fname, md5) + ".jpg"); - safe_g_remove (getCacheFileName ("aehistograms", fname, md5)); - safe_g_remove (getCacheFileName ("embprofiles", fname, md5) + ".icc"); - } + deleteFiles (fname, getMD5 (fname), purge, purge); } void CacheManager::renameEntry (const std::string& oldfilename, const std::string& oldmd5, const std::string& newfilename) { + MyMutex::MyLock lock (mutex); - MyMutex::MyLock lock(mutex_); + const auto newmd5 = getMD5 (newfilename); - std::string newmd5 = getMD5 (newfilename); + auto error = g_rename (getCacheFileName ("profiles", oldfilename, paramFileExtension, oldmd5).c_str (), getCacheFileName ("profiles", newfilename, paramFileExtension, newmd5).c_str ()); + error |= g_rename (getCacheFileName ("images", oldfilename, ".rtti", oldmd5).c_str (), getCacheFileName ("images", newfilename, ".rtti", newmd5).c_str ()); + error |= g_rename (getCacheFileName ("images", oldfilename, ".cust16", oldmd5).c_str (), getCacheFileName ("images", newfilename, ".cust16", newmd5).c_str ()); + error |= g_rename (getCacheFileName ("images", oldfilename, ".cust", oldmd5).c_str (), getCacheFileName ("images", newfilename, ".cust", newmd5).c_str ()); + error |= g_rename (getCacheFileName ("images", oldfilename, ".jpg", oldmd5).c_str (), getCacheFileName ("images", newfilename, ".jpg", newmd5).c_str ()); + error |= g_rename (getCacheFileName ("aehistograms", oldfilename, "", oldmd5).c_str (), getCacheFileName ("aehistograms", newfilename, "", newmd5).c_str ()); + error |= g_rename (getCacheFileName ("embprofiles", oldfilename, ".icc", oldmd5).c_str (), getCacheFileName ("embprofiles", newfilename, ".icc", newmd5).c_str ()); + error |= g_rename (getCacheFileName ("data", oldfilename, ".txt", oldmd5).c_str (), getCacheFileName ("data", newfilename, ".txt", newmd5).c_str ()); - safe_g_rename (getCacheFileName ("profiles", oldfilename, oldmd5) + paramFileExtension, (getCacheFileName ("profiles", newfilename, newmd5) + paramFileExtension).c_str()); - safe_g_rename (getCacheFileName ("images", oldfilename, oldmd5) + ".rtti", getCacheFileName ("images", newfilename, newmd5) + ".rtti"); - safe_g_rename (getCacheFileName ("images", oldfilename, oldmd5) + ".cust16", getCacheFileName ("images", newfilename, newmd5) + ".cust16"); - safe_g_rename (getCacheFileName ("images", oldfilename, oldmd5) + ".cust", getCacheFileName ("images", newfilename, newmd5) + ".cust"); - safe_g_rename (getCacheFileName ("images", oldfilename, oldmd5) + ".jpg", getCacheFileName ("images", newfilename, newmd5) + ".jpg"); - safe_g_rename (getCacheFileName ("aehistograms", oldfilename, oldmd5), getCacheFileName ("aehistograms", newfilename, newmd5)); - safe_g_rename (getCacheFileName ("embprofiles", oldfilename, oldmd5) + ".icc", getCacheFileName ("embprofiles", newfilename, newmd5) + ".icc"); - safe_g_rename (getCacheFileName ("data", oldfilename, oldmd5) + ".txt", getCacheFileName ("data", newfilename, newmd5) + ".txt"); + if (error != 0 && options.rtSettings.verbose) { + std::cerr << "Failed to rename all files for cache entry '" << oldfilename << "': " << g_strerror(errno) << std::endl; + } // check if it is opened - string_thumb_map::iterator r = openEntries.find (oldfilename); - // if it is open, update md5 - if (r != openEntries.end()) { - Thumbnail* t = r->second; - openEntries.erase (r); - t->setFileName (newfilename); - openEntries[newfilename] = t; - t->updateCache (); - t->saveThumbnail (); - } -} - -void CacheManager::closeThumbnail (Thumbnail* t) -{ - - MyMutex::MyLock lock(mutex_); - -// t->updateCache (); - string_thumb_map::iterator r = openEntries.find (t->getFileName()); - - if (r != openEntries.end()) { - openEntries.erase (r); + const auto iterator = openEntries.find (oldfilename); + if (iterator == openEntries.end ()) { + return; } - delete t; + auto thumbnail = iterator->second; + openEntries.erase (iterator); + openEntries.emplace (newfilename, thumbnail); + + thumbnail->setFileName (newfilename); + thumbnail->updateCache (); + thumbnail->saveThumbnail (); } -void CacheManager::closeCache () +void CacheManager::closeThumbnail (Thumbnail* thumbnail) { + MyMutex::MyLock lock (mutex); - MyMutex::MyLock lock(mutex_); + openEntries.erase (thumbnail->getFileName ()); + delete thumbnail; +} + +void CacheManager::closeCache () const +{ + MyMutex::MyLock lock (mutex); applyCacheSizeLimitation (); } -void CacheManager::clearAll () +void CacheManager::clearAll () const { + MyMutex::MyLock lock (mutex); - MyMutex::MyLock lock(mutex_); - - deleteDir ("images"); - deleteDir ("aehistograms"); - deleteDir ("embprofiles"); - deleteDir ("profiles"); - deleteDir ("data"); - - // re-generate thumbnail images and clear profiles of open thumbnails - //string_thumb_map::iterator i; - //for (i=openEntries.begin(); i!=openEntries.end(); i++) { - // i->second->clearProcParams (CACHEMGR); - // i->second->generateThumbnailImage (); - // i->second->updateCache (); - //} + for (const auto& cacheDir : cacheDirs) { + deleteDir (cacheDir); + } } -void CacheManager::clearThumbImages () -{ - MyMutex::MyLock lock(mutex_); +void CacheManager::clearImages () const +{ + MyMutex::MyLock lock (mutex); deleteDir ("images"); deleteDir ("aehistograms"); deleteDir ("embprofiles"); } -void CacheManager::clearProfiles () +void CacheManager::clearProfiles () const { - MyMutex::MyLock lock(mutex_); + MyMutex::MyLock lock (mutex); deleteDir ("profiles"); } -void CacheManager::deleteDir (const Glib::ustring& dirName) +void CacheManager::deleteDir (const Glib::ustring& dirName) const { - try { - Glib::Dir* dir = new Glib::Dir (Glib::build_filename (baseDir, dirName)); - for (Glib::DirIterator i = dir->begin(); i != dir->end(); ++i) { - safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, dirName), *i)); + Glib::Dir dir (Glib::build_filename (baseDir, dirName)); + + auto error = 0; + for (auto entry = dir.begin (); entry != dir.end (); ++entry) { + error |= g_remove (Glib::build_filename (baseDir, dirName, *entry).c_str ()); } - delete dir; - } catch (const Glib::Error& e) { + if (error != 0 && options.rtSettings.verbose) { + std::cerr << "Failed to delete all entries in cache directory '" << dirName << "': " << g_strerror(errno) << std::endl; + } + + } catch (Glib::Error&) {} +} + +void CacheManager::deleteFiles (const Glib::ustring& fname, const std::string& md5, bool purgeData, bool purgeProfile) const +{ + if (md5.empty ()) { + return; + } + + auto error = g_remove (getCacheFileName ("images", fname, ".rtti", md5).c_str ()); + error |= g_remove (getCacheFileName ("images", fname, ".cust16", md5).c_str ()); + error |= g_remove (getCacheFileName ("images", fname, ".cust", md5).c_str ()); + error |= g_remove (getCacheFileName ("images", fname, ".jpg", md5).c_str ()); + error |= g_remove (getCacheFileName ("aehistograms", fname, "", md5).c_str ()); + error |= g_remove (getCacheFileName ("embprofiles", fname, ".icc", md5).c_str ()); + + if (purgeData) { + error |= g_remove (getCacheFileName ("data", fname, ".txt", md5).c_str ()); + } + + if (purgeProfile) { + error |= g_remove (getCacheFileName ("profiles", fname, paramFileExtension, md5).c_str ()); + } + + if (error != 0 && options.rtSettings.verbose) { + std::cerr << "Failed to delete all files for cache entry '" << fname << "': " << g_strerror(errno) << std::endl; } } std::string CacheManager::getMD5 (const Glib::ustring& fname) { - Glib::RefPtr file = Gio::File::create_for_path (fname); + auto file = Gio::File::create_for_path (fname); - if (file && file->query_exists()) { + if (file && file->query_exists ()) { #ifdef WIN32 - // Windows: file name + size + creation time - // Safer because e.g. your camera image counter turns over. Do NOT use modified date, since tagging programs will change that - wchar_t *wFname = (wchar_t*)g_utf8_to_utf16 (fname.c_str(), -1, NULL, NULL, NULL); - WIN32_FILE_ATTRIBUTE_DATA fileAttr; - bool success = GetFileAttributesExW(wFname, GetFileExInfoStandard, &fileAttr); - g_free(wFname); - if (success) { - // Just need the low file size, since RAWs are never that large - Glib::ustring fileID = Glib::ustring::compose ("%1-%2-%3-%4", fileAttr.nFileSizeLow, fileAttr.ftCreationTime.dwHighDateTime, fileAttr.ftCreationTime.dwLowDateTime, fname ); - return Glib::Checksum::compute_checksum (Glib::Checksum::CHECKSUM_MD5, fileID); + std::unique_ptr wfname (reinterpret_cast(g_utf8_to_utf16 (fname.c_str (), -1, NULL, NULL, NULL)), g_free); + + WIN32_FILE_ATTRIBUTE_DATA fileAttr; + if (GetFileAttributesExW (wfname.get (), GetFileExInfoStandard, &fileAttr)) { + // We use name, size and creation time to identify a file. + const auto identifier = Glib::ustring::compose ("%1-%2-%3-%4", fileAttr.nFileSizeLow, fileAttr.ftCreationTime.dwHighDateTime, fileAttr.ftCreationTime.dwLowDateTime, fname); + return Glib::Checksum::compute_checksum (Glib::Checksum::CHECKSUM_MD5, identifier); } #else - // Least common denominator: file name + size to identify a file - Glib::RefPtr info = safe_query_file_info (file); - if (info) { - return Glib::Checksum::compute_checksum (Glib::Checksum::CHECKSUM_MD5, Glib::ustring::compose ("%1%2", fname, info->get_size())); - } + try + { + + if (auto info = file->query_info ()) { + // We only use name and size to identify a file. + const auto identifier = Glib::ustring::compose ("%1%2", fname, info->get_size ()); + return Glib::Checksum::compute_checksum (Glib::Checksum::CHECKSUM_MD5, identifier); + } + + } catch(Gio::Error&) {} #endif + } - return ""; + return {}; } -Glib::ustring CacheManager::getCacheFileName (const Glib::ustring& subdir, const Glib::ustring& fname, const Glib::ustring& md5) +Glib::ustring CacheManager::getCacheFileName (const Glib::ustring& subDir, + const Glib::ustring& fname, + const Glib::ustring& fext, + const Glib::ustring& md5) const { - - Glib::ustring cfn = Glib::build_filename (baseDir, subdir); - Glib::ustring cname = Glib::path_get_basename (fname) + "." + md5; - return Glib::build_filename (cfn, cname); + const auto dirName = Glib::build_filename (baseDir, subDir); + const auto baseName = Glib::path_get_basename (fname) + "." + md5; + return Glib::build_filename (dirName, baseName + fext); } -void CacheManager::applyCacheSizeLimitation () +void CacheManager::applyCacheSizeLimitation () const { + using FNameMTime = std::pair; + std::vector files; - // TODO: Improve this, it just blindly deletes image without looking at create time or something to keep the current ones - std::vector flist; - Glib::ustring dataDir = Glib::build_filename (baseDir, "data"); - Glib::RefPtr dir = Gio::File::create_for_path (dataDir); + try { - safe_build_file_list (dir, flist); + const auto dirName = Glib::build_filename (baseDir, "data"); + const auto dir = Gio::File::create_for_path (dirName); - if (flist.size() > options.maxCacheEntries) { - std::sort (flist.begin(), flist.end()); + auto enumerator = dir->enumerate_children (); - while (flist.size() > options.maxCacheEntries) { - safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "data"), flist.front().fname) + ".txt"); - safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "images"), flist.front().fname) + ".rtti"); - safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "images"), flist.front().fname) + ".cust16"); - safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "images"), flist.front().fname) + ".cust"); - safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "images"), flist.front().fname) + ".jpg"); - safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "aehistograms"), flist.front().fname)); - safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "embprofiles"), flist.front().fname) + ".icc"); - // safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "profiles"), flist.front().fname) + paramFileExtension); - flist.erase (flist.begin()); + while (auto file = enumerator->next_file ()) { + files.emplace_back (file->get_name (), file->modification_time ()); } + + } catch (Glib::Exception&) {} + + if (files.size () <= options.maxCacheEntries) { + return; + } + + std::sort (files.begin (), files.end (), [] (const FNameMTime& lhs, const FNameMTime& rhs) + { + return lhs.second < rhs.second; + }); + + auto cacheEntries = files.size (); + + for (auto entry = files.begin(); cacheEntries-- > options.maxCacheEntries; ++entry) { + + const auto& fname = entry->first; + + deleteFiles (fname, getMD5 (fname), true, false); } } diff --git a/rtgui/cachemanager.h b/rtgui/cachemanager.h index 159964104..4460204cc 100644 --- a/rtgui/cachemanager.h +++ b/rtgui/cachemanager.h @@ -21,56 +21,55 @@ #include #include -#include -#include "thumbnail.h" -#include -#include "../rtengine/procparams.h" + +#include + #include "threadutils.h" class Thumbnail; class CacheManager { - - typedef std::pair string_thumb_pair; - typedef std::map string_thumb_map; - - string_thumb_map openEntries; +private: + using Entries = std::map; + Entries openEntries; Glib::ustring baseDir; - MyMutex mutex_; + mutable MyMutex mutex; - void deleteDir (const Glib::ustring& dirName); + void deleteDir (const Glib::ustring& dirName) const; + void deleteFiles (const Glib::ustring& fname, const std::string& md5, bool purgeData, bool purgeProfile) const; - CacheManager () {} + void applyCacheSizeLimitation () const; + + CacheManager () = default; + CacheManager (const CacheManager&) = delete; + CacheManager& operator= (const CacheManager&) = delete; public: - static CacheManager* getInstance(void); + static CacheManager* getInstance (); void init (); + Thumbnail* getEntry (const Glib::ustring& fname); void deleteEntry (const Glib::ustring& fname); void renameEntry (const std::string& oldfilename, const std::string& oldmd5, const std::string& newfilename); - void closeThumbnail (Thumbnail* t); + void closeThumbnail (Thumbnail* thumbnail); + void closeCache () const; - const Glib::ustring& getBaseDir () - { - MyMutex::MyLock lock(mutex_); - return baseDir; - } - void closeCache (); + void clearAll () const; + void clearImages () const; + void clearProfiles () const; + void clearFromCache (const Glib::ustring& fname, bool purge) const; static std::string getMD5 (const Glib::ustring& fname); - void clearAll (); - void clearThumbImages (); - void clearProfiles (); - void clearFromCache(const Glib::ustring& fname, bool leavenotrace); + Glib::ustring getCacheFileName (const Glib::ustring& subDir, + const Glib::ustring& fname, + const Glib::ustring& fext, + const Glib::ustring& md5) const; - void applyCacheSizeLimitation (); - - Glib::ustring getCacheFileName (const Glib::ustring& subdir, const Glib::ustring& fname, const Glib::ustring& md5); }; #define cacheMgr CacheManager::getInstance() diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 0033978c3..5f5ececee 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -2167,7 +2167,7 @@ void Preferences::clearProfilesPressed () void Preferences::clearThumbImagesPressed () { - cacheMgr->clearThumbImages (); + cacheMgr->clearImages (); } void Preferences::clearAllPressed () diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 838c852a8..5e132cc14 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -915,7 +915,7 @@ Thumbnail::~Thumbnail () Glib::ustring Thumbnail::getCacheFileName (Glib::ustring subdir) { - return cachemgr->getCacheFileName (subdir, fname, cfs.md5); + return cachemgr->getCacheFileName (subdir, fname, Glib::ustring(), cfs.md5); } void Thumbnail::setFileName (const Glib::ustring fn) From 142e0886a656d5066a90df5f52d92a1024dabaad Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Tue, 5 Jan 2016 19:32:51 +0100 Subject: [PATCH 61/61] Remove those parts of the safegtk API that were only used in the cache manager. --- rtengine/safegtk.cc | 53 --------------------------------------------- rtengine/safegtk.h | 15 ------------- 2 files changed, 68 deletions(-) diff --git a/rtengine/safegtk.cc b/rtengine/safegtk.cc index a1e45b998..e072a5356 100644 --- a/rtengine/safegtk.cc +++ b/rtengine/safegtk.cc @@ -150,59 +150,6 @@ Glib::RefPtr safe_next_file (Glib::RefPtr &d # define SAFE_ENUMERATOR_CODE_END } if (error.get()) printf ("%s\n", error->what().c_str());}while (0) #endif -#ifdef WIN32 - -// High speed Windows version -void safe_build_file_list (Glib::RefPtr &dir, std::vector &flist) -{ - Glib::ustring fullPath = dir->get_path() + Glib::ustring("\\*"); - - DWORD dwVersion = GetVersion(); - bool win7Plus = (LOBYTE(LOWORD(dwVersion)) > 6) || ((LOBYTE(LOWORD(dwVersion)) == 6) && HIBYTE(LOWORD(dwVersion)) >= 1); // 6.1 or better - - wchar_t *wDirName = (wchar_t*)g_utf8_to_utf16 (fullPath.c_str(), -1, NULL, NULL, NULL); - WIN32_FIND_DATAW fi; - - HANDLE hFF = FindFirstFileExW(wDirName, - //win7Plus ? FindExInfoBasic : // TODO: Add if MinGW is updated, makes it even faster - FindExInfoStandard, &fi, - FindExSearchNameMatch, NULL, - win7Plus ? 2 : 0); // Win7 large fetch - - if (hFF != INVALID_HANDLE_VALUE) { - do { - SYSTEMTIME stUTC; - FileTimeToSystemTime(&fi.ftLastWriteTime, &stUTC); - char time[64]; - sprintf(time, "%d-%02d-%02dT%02d:%02d:%02dZ", stUTC.wYear, stUTC.wMonth, stUTC.wDay, stUTC.wHour, stUTC.wMinute, stUTC.wSecond); - Glib::TimeVal timeVal; - timeVal.assign_from_iso8601(Glib::ustring(time)); - - char pathA[MAX_PATH]; - WideCharToMultiByte(CP_UTF8, 0, (WCHAR*)fi.cFileName, -1, pathA, MAX_PATH, 0, 0); - flist.push_back (FileMTimeInfo (removeExtension(Glib::ustring(pathA)), timeVal)); - - } while (FindNextFileW(hFF, &fi)); - - FindClose(hFF); - } - - g_free(wDirName); -} -#else - -// Generic file list build -void safe_build_file_list (Glib::RefPtr &dir, std::vector &flist) -{ - Glib::RefPtr dirList; - - if (dir) { - SAFE_ENUMERATOR_CODE_START - flist.push_back (FileMTimeInfo (removeExtension(info->get_name()), info->modification_time())); - SAFE_ENUMERATOR_CODE_END; - } -} -#endif /* * safe_build_file_list can now filter out at the source all files that doesn't have the extensions specified (if provided) */ diff --git a/rtengine/safegtk.h b/rtengine/safegtk.h index f29c18d0b..768d55148 100644 --- a/rtengine/safegtk.h +++ b/rtengine/safegtk.h @@ -8,22 +8,7 @@ Glib::RefPtr safe_create_from_file(const Glib::ustring& filename); Cairo::RefPtr safe_create_from_png(const Glib::ustring& filename); -class FileMTimeInfo -{ - -public: - Glib::ustring fname; - Glib::TimeVal mtime; - - FileMTimeInfo (Glib::ustring name, Glib::TimeVal mtime) : fname(name), mtime(mtime) {} - bool operator<(const FileMTimeInfo& other) const - { - return mtime < other.mtime; - } -}; - Glib::RefPtr safe_query_file_info (Glib::RefPtr &file); -void safe_build_file_list (Glib::RefPtr &dir, std::vector &flist); void safe_build_file_list (Glib::RefPtr &dir, std::vector &names, const Glib::ustring &directory = "", const std::vector *extensions = NULL); void safe_build_subdir_list (Glib::RefPtr &dir, std::vector &subDirs, bool add_hidden);