From 5f988861b0adf134fc1683e4006877a499186ce3 Mon Sep 17 00:00:00 2001 From: Desmis Date: Fri, 19 Feb 2016 16:58:23 +0100 Subject: [PATCH 1/7] Init CBDL before Black and White --- rtdata/languages/default | 5 ++ rtengine/color.cc | 30 ++++++++ rtengine/dcrop.cc | 79 +++++++++++++++++++- rtengine/improccoordinator.cc | 87 ++++++++++++++++++++-- rtengine/improcfun.cc | 135 ++++++++++++++++++++++++---------- rtengine/improcfun.h | 3 +- rtengine/procevents.h | 2 + rtengine/procparams.cc | 17 +++++ rtengine/procparams.h | 2 +- rtengine/refreshmap.cc | 15 ++-- rtengine/simpleprocess.cc | 75 ++++++++++++++++++- rtgui/dirpyrequalizer.cc | 50 +++++++++++++ rtgui/dirpyrequalizer.h | 6 +- rtgui/paramsedited.cc | 7 ++ rtgui/paramsedited.h | 2 +- 15 files changed, 451 insertions(+), 64 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 6bedd3443..553fc4a4b 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -670,6 +670,7 @@ HISTORY_MSG_436;Retinex - M - Radius HISTORY_MSG_437;Retinex - M - Method HISTORY_MSG_438;Retinex - M - Equalizer HISTORY_MSG_439;Retinex - Preview +HISTORY_MSG_440;CbDL - method HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot @@ -1206,6 +1207,10 @@ TP_BWMIX_VAL;L TP_CACORRECTION_BLUE;Blue TP_CACORRECTION_LABEL;Chromatic Aberration Correction TP_CACORRECTION_RED;Red +TP_CBDL_METHOD;Process located +TP_CBDL_METHOD_TOOLTIP;"After Black and White" located the tool in L*a*b process.\n"Before Black and White" located the tool at the beginning of rgb process.\nObviously this can lead to differences. +TP_CBDL_AFT;After Black and White +TP_CBDL_BEF;Before Black and White TP_CHMIXER_BLUE;Blue channel TP_CHMIXER_GREEN;Green channel TP_CHMIXER_LABEL;Channel Mixer diff --git a/rtengine/color.cc b/rtengine/color.cc index c0dbab4d3..56880833b 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -808,6 +808,15 @@ void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::u float somm; float som = mixerRed + mixerGreen + mixerBlue; + if(som >= 0.f && som < 1.f) { + som = 1.f; + } + + if(som < 0.f && som > -1.f) { + som = -1.f; + } + + // rM = mixerRed, gM = mixerGreen, bM = mixerBlue ! //presets if (setting == "RGB-Abs" || setting == "ROYGCBPM-Abs") { @@ -869,6 +878,15 @@ void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::u bbm = mixerBlue; somm = mixerRed + mixerGreen + mixerBlue; + + if(somm >= 0.f && somm < 1.f) { + somm = 1.f; + } + + if(somm < 0.f && somm > -1.f) { + somm = -1.f; + } + mixerRed = mixerRed / somm; mixerGreen = mixerGreen / somm; mixerBlue = mixerBlue / somm; @@ -1084,6 +1102,10 @@ void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::u mixerGreen = mixerGreen * filgreen; mixerBlue = mixerBlue * filblue; + if(mixerRed + mixerGreen + mixerBlue == 0) { + mixerRed += 1.f; + } + mixerRed = filcor * mixerRed / (mixerRed + mixerGreen + mixerBlue); mixerGreen = filcor * mixerGreen / (mixerRed + mixerGreen + mixerBlue); mixerBlue = filcor * mixerBlue / (mixerRed + mixerGreen + mixerBlue); @@ -1091,6 +1113,14 @@ void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::u if(filter != "None") { som = mixerRed + mixerGreen + mixerBlue; + if(som >= 0.f && som < 1.f) { + som = 1.f; + } + + if(som < 0.f && som > -1.f) { + som = -1.f; + } + if(setting == "RGB-Abs" || setting == "ROYGCBPM-Abs") { kcorec = kcorec * som; } diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 2220f68c5..6eb60988c 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -712,6 +712,75 @@ void Crop::update (int todo) transCrop = NULL; } + if ((todo && (M_TRANSFORM)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled) { + + if( (!params.colorappearance.enabled )) { + TMatrix wprof, wiprof; + wprof = iccStore->workingSpaceMatrix( params.icm.working ); + wiprof = iccStore->workingSpaceInverseMatrix( params.icm.working ); + double wip[3][3] = { + {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, + {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, + {wiprof[2][0], wiprof[2][1], wiprof[2][2]} + }; + + double wp[3][3] = { + {wprof[0][0], wprof[0][1], wprof[0][2]}, + {wprof[1][0], wprof[1][1], wprof[1][2]}, + {wprof[2][0], wprof[2][1], wprof[2][2]} + }; + + int W = baseCrop->getWidth(); + int H = baseCrop->getHeight(); + LabImage * labcbdl; + labcbdl = new LabImage(W, H); +#ifndef _DEBUG + #pragma omp parallel for schedule(dynamic, 10) +#endif + + for(int i = 0; i < H; i++) { + for(int j = 0; j < W; j++) { + float r = baseCrop->r(i, j); + float g = baseCrop->g(i, j); + float b = baseCrop->b(i, j); + float X, Y, Z; + float L, aa, bb; + Color::rgbxyz(r, g, b, X, Y, Z, wp); + //convert Lab + Color::XYZ2Lab(X, Y, Z, L, aa, bb); + labcbdl->L[i][j] = L; + labcbdl->a[i][j] = aa; + labcbdl->b[i][j] = bb; + } + } + + parent->ipf.dirpyrequalizer (labcbdl, skip, 0); + + +#ifndef _DEBUG + #pragma omp parallel for schedule(dynamic, 10) +#endif + + for(int i = 0; i < H; i++) { + for(int j = 0; j < W; j++) { + float L = labcbdl->L[i][j]; + float a = labcbdl->a[i][j]; + float b = labcbdl->b[i][j]; + float x1, y1, z1; + float R, G, B; + Color::Lab2XYZ(L, a, b, x1, y1, z1); + Color::xyz2rgb(x1, y1, z1, R, G, B, wip); + baseCrop->r(i, j) = R; + baseCrop->g(i, j) = G; + baseCrop->b(i, j) = B; + } + } + + delete labcbdl; + + } + } + // blurmap for shadow & highlights if ((todo & M_BLURMAP) && params.sh.enabled) { double radius = sqrt (double(SKIPS(parent->fw, skip) * SKIPS(parent->fw, skip) + SKIPS(parent->fh, skip) * SKIPS(parent->fh, skip))) / 2.0; @@ -732,6 +801,7 @@ void Crop::update (int todo) } } + // shadows & highlights & tone curve & convert to cielab /*int xref,yref; xref=000;yref=000; @@ -838,12 +908,13 @@ void Crop::update (int todo) // if (skip==1) { WaveletParams WaveParams = params.wavelet; - if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { - parent->ipf.dirpyrequalizer (labnCrop, skip); - // parent->ipf.Lanczoslab (labnCrop,labnCrop , 1.f/skip); + if(params.dirpyrequalizer.cbdlMethod == "aft") { + if(((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled))) { + parent->ipf.dirpyrequalizer (labnCrop, skip, 1); + // parent->ipf.Lanczoslab (labnCrop,labnCrop , 1.f/skip); + } } - int kall = 0; int minwin = min(labnCrop->W, labnCrop->H); int maxlevelcrop = 10; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index ee75e831a..84b4412ba 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -242,7 +242,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } } - if ((todo & (M_RETINEX|M_INIT)) && params.retinex.enabled) { + if ((todo & (M_RETINEX | M_INIT)) && params.retinex.enabled) { bool dehacontlutili = false; bool mapcontlutili = false; bool useHsl = false; @@ -392,6 +392,73 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) progress ("Preparing shadow/highlight map...", 100 * readyphase / numofphases); + if ((todo & (M_TRANSFORM)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled) { + if(((!params.colorappearance.enabled))) { + TMatrix wprof, wiprof; + wprof = iccStore->workingSpaceMatrix( params.icm.working ); + wiprof = iccStore->workingSpaceInverseMatrix( params.icm.working ); + double wip[3][3] = { + {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, + {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, + {wiprof[2][0], wiprof[2][1], wiprof[2][2]} + }; + + double wp[3][3] = { + {wprof[0][0], wprof[0][1], wprof[0][2]}, + {wprof[1][0], wprof[1][1], wprof[1][2]}, + {wprof[2][0], wprof[2][1], wprof[2][2]} + }; + + int W = oprevi->getWidth(); + int H = oprevi->getHeight(); + LabImage * labcbdl; + labcbdl = new LabImage(W, H); +#ifndef _DEBUG + #pragma omp parallel for schedule(dynamic, 10) +#endif + + for(int i = 0; i < H; i++) { + for(int j = 0; j < W; j++) { + float r = oprevi->r(i, j); + float g = oprevi->g(i, j); + float b = oprevi->b(i, j); + float X, Y, Z; + float L, aa, bb; + Color::rgbxyz(r, g, b, X, Y, Z, wp); + //convert Lab + Color::XYZ2Lab(X, Y, Z, L, aa, bb); + labcbdl->L[i][j] = L; + labcbdl->a[i][j] = aa; + labcbdl->b[i][j] = bb; + } + } + + ipf.dirpyrequalizer (labcbdl, scale, 0); + +#ifndef _DEBUG + #pragma omp parallel for schedule(dynamic, 10) +#endif + + for(int i = 0; i < H; i++) { + for(int j = 0; j < W; j++) { + float L = labcbdl->L[i][j]; + float a = labcbdl->a[i][j]; + float b = labcbdl->b[i][j]; + float x1, y1, z1; + float R, G, B; + Color::Lab2XYZ(L, a, b, x1, y1, z1); + Color::xyz2rgb(x1, y1, z1, R, G, B, wip); + oprevi->r(i, j) = R; + oprevi->g(i, j) = G; + oprevi->b(i, j) = B; + } + } + + delete labcbdl; + + } + } + if ((todo & M_BLURMAP) && params.sh.enabled) { double radius = sqrt (double(pW * pW + pH * pH)) / 2.0; double shradius = params.sh.radius; @@ -407,6 +474,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) shmap->update (oprevi, shradius, ipf.lumimul, params.sh.hq, scale); } + + readyphase++; if (todo & M_AUTOEXP) { @@ -439,6 +508,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, scale == 1 ? 1 : 1); CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, scale == 1 ? 1 : 1); + TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); double wp[3][3] = { {wprof[0][0], wprof[0][1], wprof[0][2]}, @@ -656,15 +726,15 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } } */ - //if (scale==1) { - if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { - progress ("Pyramid wavelet...", 100 * readyphase / numofphases); - ipf.dirpyrequalizer (nprevl, scale); - //ipf.Lanczoslab (ip_wavelet(LabImage * lab, LabImage * dst, const procparams::EqualizerParams & eqparams), nprevl, 1.f/scale); - readyphase++; + if(params.dirpyrequalizer.cbdlMethod == "aft") { + if(((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) ) { + progress ("Pyramid wavelet...", 100 * readyphase / numofphases); + ipf.dirpyrequalizer (nprevl, scale, 1); + //ipf.Lanczoslab (ip_wavelet(LabImage * lab, LabImage * dst, const procparams::EqualizerParams & eqparams), nprevl, 1.f/scale); + readyphase++; + } } - //} wavcontlutili = false; //CurveFactory::curveWavContL ( wavcontlutili,params.wavelet.lcurve, wavclCurve, LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,int skip); @@ -782,6 +852,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) } } } + // Update the monitor color transform if necessary if (todo & M_MONITOR) { ipf.updateColorProfiles(params.icm, monitorProfile, monitorIntent); diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index b1f47c3a9..87c51dd64 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -3421,10 +3421,22 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *e fGammaLUTf[i] = CurveFactory::gamma2 (float(i) / 65535.f) * 65535.f; } - if (hasColorToning || blackwhite) { + if (hasColorToning || blackwhite || (params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled)) { tmpImage = new Imagefloat(working->width, working->height); } + int W = working->width; + int H = working->height; + + + + + + + + + + #define TS 112 #ifdef _OPENMP @@ -4217,48 +4229,48 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *e } } - //Film Simulations - if ( colorLUT ) { - for (int i = istart, ti = 0; i < tH; i++, ti++) { - for (int j = jstart, tj = 0; j < tW; j++, tj++) { - float &sourceR = rtemp[ti * TS + tj]; - float &sourceG = gtemp[ti * TS + tj]; - float &sourceB = btemp[ti * TS + tj]; + /* //Film Simulations + if ( colorLUT ) { + for (int i = istart, ti = 0; i < tH; i++, ti++) { + for (int j = jstart, tj = 0; j < tW; j++, tj++) { + float &sourceR = rtemp[ti * TS + tj]; + float &sourceG = gtemp[ti * TS + tj]; + float &sourceB = btemp[ti * TS + tj]; - if (!clutAndWorkingProfilesAreSame) { - //convert from working to clut profile - float x, y, z; - Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, work2xyz ); - Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2clut ); - } + if (!clutAndWorkingProfilesAreSame) { + //convert from working to clut profile + float x, y, z; + Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, work2xyz ); + Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2clut ); + } - //appply gamma sRGB (default RT) - sourceR = CLIP( Color::gamma_srgb( sourceR ) ); - sourceG = CLIP( Color::gamma_srgb( sourceG ) ); - sourceB = CLIP( Color::gamma_srgb( sourceB ) ); + //appply gamma sRGB (default RT) + sourceR = CLIP( Color::gamma_srgb( sourceR ) ); + sourceG = CLIP( Color::gamma_srgb( sourceG ) ); + sourceB = CLIP( Color::gamma_srgb( sourceB ) ); - float r, g, b; - colorLUT->getRGB( sourceR, sourceG, sourceB, r, g, b ); - // apply strength - sourceR = r * filmSimCorrectedStrength + sourceR * filmSimSourceStrength; - sourceG = g * filmSimCorrectedStrength + sourceG * filmSimSourceStrength; - sourceB = b * filmSimCorrectedStrength + sourceB * filmSimSourceStrength; - // apply inverse gamma sRGB - sourceR = Color::igamma_srgb( sourceR ); - sourceG = Color::igamma_srgb( sourceG ); - sourceB = Color::igamma_srgb( sourceB ); + float r, g, b; + colorLUT->getRGB( sourceR, sourceG, sourceB, r, g, b ); + // apply strength + sourceR = r * filmSimCorrectedStrength + sourceR * filmSimSourceStrength; + sourceG = g * filmSimCorrectedStrength + sourceG * filmSimSourceStrength; + sourceB = b * filmSimCorrectedStrength + sourceB * filmSimSourceStrength; + // apply inverse gamma sRGB + sourceR = Color::igamma_srgb( sourceR ); + sourceG = Color::igamma_srgb( sourceG ); + sourceB = Color::igamma_srgb( sourceB ); - if (!clutAndWorkingProfilesAreSame) { - //convert from clut to working profile - float x, y, z; - Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, clut2xyz ); - Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2work ); - } - - } - } - } + if (!clutAndWorkingProfilesAreSame) { + //convert from clut to working profile + float x, y, z; + Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, clut2xyz ); + Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2work ); + } + } + } + } + */ //black and white if(blackwhite) { if (hasToneCurvebw1) { @@ -4405,6 +4417,50 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *e } } + + //Film Simulations + if ( colorLUT ) { + for (int i = istart, ti = 0; i < tH; i++, ti++) { + for (int j = jstart, tj = 0; j < tW; j++, tj++) { + float &sourceR = rtemp[ti * TS + tj]; + float &sourceG = gtemp[ti * TS + tj]; + float &sourceB = btemp[ti * TS + tj]; + + if (!clutAndWorkingProfilesAreSame) { + //convert from working to clut profile + float x, y, z; + Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, work2xyz ); + Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2clut ); + } + + //appply gamma sRGB (default RT) + sourceR = CLIP( Color::gamma_srgb( sourceR ) ); + sourceG = CLIP( Color::gamma_srgb( sourceG ) ); + sourceB = CLIP( Color::gamma_srgb( sourceB ) ); + + float r, g, b; + colorLUT->getRGB( sourceR, sourceG, sourceB, r, g, b ); + // apply strength + sourceR = r * filmSimCorrectedStrength + sourceR * filmSimSourceStrength; + sourceG = g * filmSimCorrectedStrength + sourceG * filmSimSourceStrength; + sourceB = b * filmSimCorrectedStrength + sourceB * filmSimSourceStrength; + // apply inverse gamma sRGB + sourceR = Color::igamma_srgb( sourceR ); + sourceG = Color::igamma_srgb( sourceG ); + sourceB = Color::igamma_srgb( sourceB ); + + if (!clutAndWorkingProfilesAreSame) { + //convert from clut to working profile + float x, y, z; + Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, clut2xyz ); + Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2work ); + } + + } + } + } + + if(!blackwhite) { // ready, fill lab for (int i = istart, ti = 0; i < tH; i++, ti++) { @@ -6481,8 +6537,9 @@ void ImProcFunctions::badpixlab(LabImage* lab, double rad, int thr, int mode, fl } } -void ImProcFunctions::dirpyrequalizer (LabImage* lab, int scale) +void ImProcFunctions::dirpyrequalizer (LabImage* lab, int scale, int mode) { + printf("mode=%d\n", mode); if (params->dirpyrequalizer.enabled && lab->W >= 8 && lab->H >= 8) { float b_l = static_cast(params->dirpyrequalizer.hueskin.value[0]) / 100.0f; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 44224fa2e..f69f04e19 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -284,7 +284,8 @@ public: void impulse_nrcam (CieImage* ncie, double thresh, float **buffers[3]); void dirpyrdenoise (LabImage* src);//Emil's pyramid denoise - void dirpyrequalizer (LabImage* lab, int scale);//Emil's wavelet + void dirpyrequalizer (LabImage* lab, int scale, int mode);//Emil's wavelet + void EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params& cp, int W_L, int H_L, float max0, float min0); float *CompressDR(float *Source, int skip, struct cont_params &cp, int W_L, int H_L, float Compression, float DetailBoost, float max0, float min0, float ave, float ah, float bh, float al, float bl, float factorx, float *Compressed); diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 558f509c2..3d4f90af1 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -466,7 +466,9 @@ enum ProcEvent { EvmapMethod = 436, EvRetinexmapcurve = 437, EvviewMethod = 438, + EvcbdlMethod = 439, NUMOFEVENTS + }; } #endif diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index f79f51c91..fcdd9fa0f 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1219,7 +1219,9 @@ void ProcParams::setDefaults () dirpyrequalizer.enabled = false; dirpyrequalizer.gamutlab = false; + dirpyrequalizer.cbdlMethod = "aft"; + for(int i = 0; i < 6; i ++) { dirpyrequalizer.mult[i] = 1.0; } @@ -3028,6 +3030,10 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol keyFile.set_boolean ("Directional Pyramid Equalizer", "Gamutlab", dirpyrequalizer.gamutlab); } + if (!pedited || pedited->dirpyrequalizer.cbdlMethod) { + keyFile.set_string ("Directional Pyramid Equalizer", "cbdlMethod", dirpyrequalizer.cbdlMethod); + } + for(int i = 0; i < 6; i++) { std::stringstream ss; ss << "Mult" << i; @@ -6610,6 +6616,16 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) } } + + if (keyFile.has_key ("Directional Pyramid Equalizer", "cbdlMethod")) { + dirpyrequalizer.cbdlMethod = keyFile.get_string ("Directional Pyramid Equalizer", "cbdlMethod"); + + if (pedited) { + pedited->dirpyrequalizer.cbdlMethod = true; + } + } + + // if (keyFile.has_key ("Directional Pyramid Equalizer", "Algorithm")) { dirpyrequalizer.algo = keyFile.get_string ("Directional Pyramid Equalizer", "Algorithm"); if (pedited) pedited->dirpyrequalizer.algo = true; } if (keyFile.has_key ("Directional Pyramid Equalizer", "Hueskin")) { Glib::ArrayHandle thresh = keyFile.get_integer_list ("Directional Pyramid Equalizer", "Hueskin"); @@ -7880,6 +7896,7 @@ bool ProcParams::operator== (const ProcParams& other) // && dirpyrequalizer.algo == other.dirpyrequalizer.algo && dirpyrequalizer.hueskin == other.dirpyrequalizer.hueskin && dirpyrequalizer.threshold == other.dirpyrequalizer.threshold + && dirpyrequalizer.cbdlMethod == other.dirpyrequalizer.cbdlMethod && dirpyrequalizer.skinprotect == other.dirpyrequalizer.skinprotect && hsvequalizer.hcurve == other.hsvequalizer.hcurve && hsvequalizer.scurve == other.hsvequalizer.scurve diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 47b8f1cf1..b68db845c 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1106,7 +1106,7 @@ public: double skinprotect; Threshold hueskin; //Glib::ustring algo; - + Glib::ustring cbdlMethod; DirPyrEqualizerParams() : hueskin(20, 80, 2000, 1200, false) {}; }; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 6a2925be9..292a54133 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -119,8 +119,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { ALLNORAW, // EvDPDNLuma, ALLNORAW, // EvDPDNChroma, ALLNORAW, // EvDPDNGamma, - DIRPYREQUALIZER, // EvDirPyrEqualizer, - DIRPYREQUALIZER, // EvDirPyrEqlEnabled, + ALLNORAW, // EvDirPyrEqualizer, + ALLNORAW, // EvDirPyrEqlEnabled, LUMINANCECURVE, // EvLSaturation, LUMINANCECURVE, // EvLaCurve, LUMINANCECURVE, // EvLbCurve, @@ -275,12 +275,12 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // EvLCLCurve LUMINANCECURVE, // EvLLHCurve LUMINANCECURVE, // EvLHHCurve - DIRPYREQUALIZER, // EvDirPyrEqualizerThreshold + ALLNORAW, // EvDirPyrEqualizerThreshold ALLNORAW, // EvDPDNenhance RGBCURVE, // EvBWMethodalg - DIRPYREQUALIZER, // EvDirPyrEqualizerSkin - DIRPYREQUALIZER, // EvDirPyrEqlgamutlab - DIRPYREQUALIZER, // EvDirPyrEqualizerHueskin + ALLNORAW, // EvDirPyrEqualizerSkin + ALLNORAW, // EvDirPyrEqlgamutlab + ALLNORAW, // EvDirPyrEqualizerHueskin ALLNORAW, // EvDPDNmedian ALLNORAW, // EvDPDNmedmet RGBCURVE, // EvColorToningEnabled @@ -465,6 +465,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { RETINEX, // EvLradius RETINEX, // EvmapMethod DEMOSAIC, // EvRetinexmapcurve - DEMOSAIC // EvviewMethod + DEMOSAIC, // EvviewMethod + ALLNORAW // EvcbdlMethod }; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 9ae940980..06bd755e4 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -739,6 +739,74 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p baseImg = trImg; } + + if (params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled) { + if(((!params.colorappearance.enabled))) { + TMatrix wprof, wiprof; + wprof = iccStore->workingSpaceMatrix( params.icm.working ); + wiprof = iccStore->workingSpaceInverseMatrix( params.icm.working ); + double wip[3][3] = { + {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, + {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, + {wiprof[2][0], wiprof[2][1], wiprof[2][2]} + }; + + double wp[3][3] = { + {wprof[0][0], wprof[0][1], wprof[0][2]}, + {wprof[1][0], wprof[1][1], wprof[1][2]}, + {wprof[2][0], wprof[2][1], wprof[2][2]} + }; + + int W = baseImg->getWidth(); + int H = baseImg->getHeight(); + LabImage * labcbdl; + labcbdl = new LabImage(W, H); +#ifndef _DEBUG + #pragma omp parallel for schedule(dynamic, 10) +#endif + + for(int i = 0; i < H; i++) { + for(int j = 0; j < W; j++) { + float r = baseImg->r(i, j); + float g = baseImg->g(i, j); + float b = baseImg->b(i, j); + float X, Y, Z; + float L, aa, bb; + Color::rgbxyz(r, g, b, X, Y, Z, wp); + //convert Lab + Color::XYZ2Lab(X, Y, Z, L, aa, bb); + labcbdl->L[i][j] = L; + labcbdl->a[i][j] = aa; + labcbdl->b[i][j] = bb; + } + } + + ipf.dirpyrequalizer (labcbdl, 1, 0); + +#ifndef _DEBUG + #pragma omp parallel for schedule(dynamic, 10) +#endif + + for(int i = 0; i < H; i++) { + for(int j = 0; j < W; j++) { + float L = labcbdl->L[i][j]; + float a = labcbdl->a[i][j]; + float b = labcbdl->b[i][j]; + float x1, y1, z1; + float R, G, B; + Color::Lab2XYZ(L, a, b, x1, y1, z1); + Color::xyz2rgb(x1, y1, z1, R, G, B, wip); + baseImg->r(i, j) = R; + baseImg->g(i, j) = G; + baseImg->b(i, j) = B; + } + } + + delete labcbdl; + + } + } + // update blurmap SHMap* shmap = NULL; @@ -982,9 +1050,12 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p params.wavelet.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL ); + // directional pyramid wavelet - if((params.colorappearance.enabled && !settings->autocielab) || !params.colorappearance.enabled) { - ipf.dirpyrequalizer (labView, 1); //TODO: this is the luminance tonecurve, not the RGB one + if(params.dirpyrequalizer.cbdlMethod == "aft") { + if((params.colorappearance.enabled && !settings->autocielab) || !params.colorappearance.enabled) { + ipf.dirpyrequalizer (labView, 1, 2); //TODO: this is the luminance tonecurve, not the RGB one + } } int kall = 2; diff --git a/rtgui/dirpyrequalizer.cc b/rtgui/dirpyrequalizer.cc index 5d8a7011e..7996a340e 100644 --- a/rtgui/dirpyrequalizer.cc +++ b/rtgui/dirpyrequalizer.cc @@ -51,6 +51,24 @@ DirPyrEqualizer::DirPyrEqualizer () : FoldableToolPanel(this, "dirpyrequalizer", Color::hsv2rgb01(0.3240, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(1. , r, g, b) ); // hsv: 0.324 rad: 2.5 + Gtk::VBox * cbVBox = Gtk::manage ( new Gtk::VBox()); + cbVBox->set_border_width(4); + cbVBox->set_spacing(2); + + cdbox = Gtk::manage (new Gtk::HBox ()); + labmcd = Gtk::manage (new Gtk::Label (M("TP_CBDL_METHOD") + ":")); + cdbox->pack_start (*labmcd, Gtk::PACK_SHRINK, 1); + + cbdlMethod = Gtk::manage (new MyComboBoxText ()); + cbdlMethod->append_text (M("TP_CBDL_BEF")); + cbdlMethod->append_text (M("TP_CBDL_AFT")); + cbdlMethod->set_active(0); + cbdlMethodConn = cbdlMethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrEqualizer::cbdlMethodChanged) ); + cbdlMethod->set_tooltip_markup (M("TP_CBDL_METHOD_TOOLTIP")); + cdbox->pack_start(*cbdlMethod); + cbVBox->pack_start(*cdbox); + pack_start(*cbVBox); + setEnabledTooltipMarkup(M("TP_SHARPENING_TOOLTIP")); Gtk::HBox * buttonBox1 = Gtk::manage (new Gtk::HBox(true, 10)); @@ -146,12 +164,17 @@ void DirPyrEqualizer::read (const ProcParams* pp, const ParamsEdited* pedited) { disableListener (); + cbdlMethodConn.block(true); if (pedited) { set_inconsistent (multiImage && !pedited->dirpyrequalizer.enabled); gamutlab->set_inconsistent (!pedited->dirpyrequalizer.gamutlab); + if (!pedited->dirpyrequalizer.cbdlMethod) { + cbdlMethod->set_active_text(M("GENERAL_UNCHANGED")); + } + for(int i = 0; i < 6; i++) { multiplier[i]->setEditedState (pedited->dirpyrequalizer.mult[i] ? Edited : UnEdited); } @@ -187,6 +210,15 @@ void DirPyrEqualizer::read (const ProcParams* pp, const ParamsEdited* pedited) skinprotect->setValue(pp->dirpyrequalizer.skinprotect); hueskin->setValue(pp->dirpyrequalizer.hueskin); + if (pp->dirpyrequalizer.cbdlMethod == "bef") { + cbdlMethod->set_active (0); + } else if (pp->dirpyrequalizer.cbdlMethod == "aft") { + cbdlMethod->set_active (1); + } + + cbdlMethodChanged (); + cbdlMethodConn.block(false); + enableListener (); } @@ -208,6 +240,7 @@ void DirPyrEqualizer::write (ProcParams* pp, ParamsEdited* pedited) pedited->dirpyrequalizer.enabled = !get_inconsistent(); pedited->dirpyrequalizer.hueskin = hueskin->getEditedState (); + pedited->dirpyrequalizer.cbdlMethod = cbdlMethod->get_active_text() != M("GENERAL_UNCHANGED"); for(int i = 0; i < 6; i++) { pedited->dirpyrequalizer.mult[i] = multiplier[i]->getEditedState(); @@ -218,6 +251,13 @@ void DirPyrEqualizer::write (ProcParams* pp, ParamsEdited* pedited) // pedited->dirpyrequalizer.algo = algo->get_active_text()!=M("GENERAL_UNCHANGED"); } + + if (cbdlMethod->get_active_row_number() == 0) { + pp->dirpyrequalizer.cbdlMethod = "bef"; + } else if (cbdlMethod->get_active_row_number() == 1) { + pp->dirpyrequalizer.cbdlMethod = "aft"; + } + /* if (algo->get_active_row_number()==0) pp->dirpyrequalizer.algo = "FI"; else if (algo->get_active_row_number()==1) @@ -282,6 +322,16 @@ void DirPyrEqualizer::setBatchMode (bool batchMode) // algo->append_text (M("GENERAL_UNCHANGED")); } +void DirPyrEqualizer::cbdlMethodChanged() +{ + + if (listener) { + listener->panelChanged (EvcbdlMethod, cbdlMethod->get_active_text ()); + } +} + + + void DirPyrEqualizer::adjusterChanged (Adjuster* a, double newval) { diff --git a/rtgui/dirpyrequalizer.h b/rtgui/dirpyrequalizer.h index 6c0a4613d..9b806989c 100644 --- a/rtgui/dirpyrequalizer.h +++ b/rtgui/dirpyrequalizer.h @@ -45,6 +45,10 @@ protected: sigc::connection lumaneutralPressedConn; sigc::connection lumacontrastPlusPressedConn; sigc::connection lumacontrastMinusPressedConn; + sigc::connection cbdlMethodConn; + Gtk::Label* labmcd; + Gtk::HBox* cdbox; + MyComboBoxText* cbdlMethod; bool lastgamutlab; @@ -61,7 +65,7 @@ public: void trimValues (rtengine::procparams::ProcParams* pp); void adjusterChanged (ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight); // void algoChanged (); - + void cbdlMethodChanged(); void adjusterChanged (Adjuster* a, double newval); void enabledChanged(); void gamutlabToggled (); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 062c61ba2..30d44f476 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -487,6 +487,8 @@ void ParamsEdited::set (bool v) dirpyrequalizer.enabled = v; dirpyrequalizer.gamutlab = v; + dirpyrequalizer.cbdlMethod = v; + for(int i = 0; i < 6; i++) { dirpyrequalizer.mult[i] = v; @@ -973,6 +975,7 @@ void ParamsEdited::initFrom (const std::vector dirpyrequalizer.enabled = dirpyrequalizer.enabled && p.dirpyrequalizer.enabled == other.dirpyrequalizer.enabled; dirpyrequalizer.gamutlab = dirpyrequalizer.gamutlab && p.dirpyrequalizer.gamutlab == other.dirpyrequalizer.gamutlab; + dirpyrequalizer.cbdlMethod = dirpyrequalizer.cbdlMethod && p.dirpyrequalizer.cbdlMethod == other.dirpyrequalizer.cbdlMethod; for(int i = 0; i < 6; i++) { dirpyrequalizer.mult[i] = dirpyrequalizer.mult[i] && p.dirpyrequalizer.mult[i] == other.dirpyrequalizer.mult[i]; @@ -2700,6 +2703,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten toEdit.dirpyrequalizer.gamutlab = mods.dirpyrequalizer.gamutlab; } + if (dirpyrequalizer.cbdlMethod) { + toEdit.dirpyrequalizer.cbdlMethod = mods.dirpyrequalizer.cbdlMethod; + } + for(int i = 0; i < 6; i++) { if(dirpyrequalizer.mult[i]) { toEdit.dirpyrequalizer.mult[i] = dontforceSet && options.baBehav[ADDSET_DIRPYREQ] ? toEdit.dirpyrequalizer.mult[i] + mods.dirpyrequalizer.mult[i] : mods.dirpyrequalizer.mult[i]; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 261da1753..3a0105c55 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -647,7 +647,7 @@ public: bool enabled; bool gamutlab; bool mult[6]; - + bool cbdlMethod; bool threshold; bool skinprotect; bool hueskin; From 5d9b07ae1a78c4d9ec45246ead441703e7f1051b Mon Sep 17 00:00:00 2001 From: heckflosse Date: Fri, 19 Feb 2016 17:34:57 +0100 Subject: [PATCH 2/7] CMakeLists.txt, remove package fftw3 (we use fftw3f) --- CMakeLists.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 646dbf46f..929ebc4f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -243,7 +243,6 @@ pkg_check_modules (LCMS REQUIRED lcms2) find_package (EXPAT REQUIRED expat>=2.0) pkg_check_modules (FFTW3F REQUIRED fftw3f) pkg_check_modules (IPTCDATA REQUIRED libiptcdata) -pkg_check_modules(FFTW3 fftw3) find_package (JPEG REQUIRED) find_package (PNG REQUIRED) find_package (TIFF REQUIRED) @@ -297,7 +296,7 @@ set(OOSB_FILES "${PROJECT_SOURCE_DIR}/rtdata/rawtherapee.desktop" "${PROJECT_SOU if (OUT_OF_SOURCE_BUILD) foreach(f ${OOSB_FILES}) file (REMOVE "${f}") - endforeach(f) + endforeach(f) endif () # check for generated files in the source tree which should not be there when @@ -308,7 +307,7 @@ if (OUT_OF_SOURCE_BUILD) if (EXISTS "${f}") message (SEND_ERROR "Generated \"${f}\" found inside the source tree. Please remove it as it is a relic of the old build system and prevents valid compilation now.") endif () - endforeach(f) + endforeach(f) endif () ## BEGIN: Generating AboutThisBuild.txt From c2c93faa3581352fc8156b43be614c43a5c2fe70 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Fri, 19 Feb 2016 19:26:11 +0100 Subject: [PATCH 3/7] Cbdl before b&w, fix refresh bug --- rtengine/dcrop.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 6eb60988c..36a0f62d0 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -712,7 +712,7 @@ void Crop::update (int todo) transCrop = NULL; } - if ((todo && (M_TRANSFORM)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled) { + if ((todo & (M_TRANSFORM)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled) { if( (!params.colorappearance.enabled )) { TMatrix wprof, wiprof; From a15fe1de3eb19c6e3e18ac75156098913567d3e8 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Fri, 19 Feb 2016 21:52:02 +0100 Subject: [PATCH 4/7] Cbdl before b&w, fix ciecam02 issue and clean the code a bit --- rtengine/dcrop.cc | 87 ++++++++++++-------------------- rtengine/improccoordinator.cc | 95 ++++++++++++++--------------------- rtengine/improcfun.cc | 2 - rtengine/simpleprocess.cc | 86 ++++++++++++------------------- 4 files changed, 104 insertions(+), 166 deletions(-) diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 36a0f62d0..cc993b811 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -714,70 +714,49 @@ void Crop::update (int todo) if ((todo & (M_TRANSFORM)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled) { - if( (!params.colorappearance.enabled )) { - TMatrix wprof, wiprof; - wprof = iccStore->workingSpaceMatrix( params.icm.working ); - wiprof = iccStore->workingSpaceInverseMatrix( params.icm.working ); - double wip[3][3] = { - {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, - {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, - {wiprof[2][0], wiprof[2][1], wiprof[2][2]} - }; + TMatrix wprof = iccStore->workingSpaceMatrix( params.icm.working ); + const float wp[3][3] = { + {static_cast(wprof[0][0]), static_cast(wprof[0][1]), static_cast(wprof[0][2])}, + {static_cast(wprof[1][0]), static_cast(wprof[1][1]), static_cast(wprof[1][2])}, + {static_cast(wprof[2][0]), static_cast(wprof[2][1]), static_cast(wprof[2][2])} + }; - double wp[3][3] = { - {wprof[0][0], wprof[0][1], wprof[0][2]}, - {wprof[1][0], wprof[1][1], wprof[1][2]}, - {wprof[2][0], wprof[2][1], wprof[2][2]} - }; - - int W = baseCrop->getWidth(); - int H = baseCrop->getHeight(); - LabImage * labcbdl; - labcbdl = new LabImage(W, H); -#ifndef _DEBUG - #pragma omp parallel for schedule(dynamic, 10) + const int W = baseCrop->getWidth(); + const int H = baseCrop->getHeight(); + LabImage labcbdl(W, H); +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) #endif - for(int i = 0; i < H; i++) { - for(int j = 0; j < W; j++) { - float r = baseCrop->r(i, j); - float g = baseCrop->g(i, j); - float b = baseCrop->b(i, j); - float X, Y, Z; - float L, aa, bb; - Color::rgbxyz(r, g, b, X, Y, Z, wp); - //convert Lab - Color::XYZ2Lab(X, Y, Z, L, aa, bb); - labcbdl->L[i][j] = L; - labcbdl->a[i][j] = aa; - labcbdl->b[i][j] = bb; - } + //convert RGB => Lab + for(int i = 0; i < H; i++) { + for(int j = 0; j < W; j++) { + float X, Y, Z; + Color::rgbxyz(baseCrop->r(i, j), baseCrop->g(i, j), baseCrop->b(i, j), X, Y, Z, wp); + Color::XYZ2Lab(X, Y, Z, labcbdl.L[i][j], labcbdl.a[i][j], labcbdl.b[i][j]); } + } - parent->ipf.dirpyrequalizer (labcbdl, skip, 0); + parent->ipf.dirpyrequalizer (&labcbdl, skip, 0); + TMatrix wiprof = iccStore->workingSpaceInverseMatrix( params.icm.working ); + const float wip[3][3] = { + {static_cast(wiprof[0][0]), static_cast(wiprof[0][1]), static_cast(wiprof[0][2])}, + {static_cast(wiprof[1][0]), static_cast(wiprof[1][1]), static_cast(wiprof[1][2])}, + {static_cast(wiprof[2][0]), static_cast(wiprof[2][1]), static_cast(wiprof[2][2])} + }; -#ifndef _DEBUG - #pragma omp parallel for schedule(dynamic, 10) +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) #endif - for(int i = 0; i < H; i++) { - for(int j = 0; j < W; j++) { - float L = labcbdl->L[i][j]; - float a = labcbdl->a[i][j]; - float b = labcbdl->b[i][j]; - float x1, y1, z1; - float R, G, B; - Color::Lab2XYZ(L, a, b, x1, y1, z1); - Color::xyz2rgb(x1, y1, z1, R, G, B, wip); - baseCrop->r(i, j) = R; - baseCrop->g(i, j) = G; - baseCrop->b(i, j) = B; - } + //convert Lab => RGB + for(int i = 0; i < H; i++) { + for(int j = 0; j < W; j++) { + float X, Y, Z; + Color::Lab2XYZ(labcbdl.L[i][j], labcbdl.a[i][j], labcbdl.b[i][j], X, Y, Z); + Color::xyz2rgb(X, Y, Z, baseCrop->r(i, j), baseCrop->g(i, j), baseCrop->b(i, j), wip); } - - delete labcbdl; - } } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 84b4412ba..bcb2c05ff 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -388,77 +388,58 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) ipf.transform (orig_prev, oprevi, 0, 0, 0, 0, pW, pH, fw, fh, imgsrc->getMetaData()->getFocalLen(), imgsrc->getMetaData()->getFocalLen35mm(), imgsrc->getMetaData()->getFocusDist(), imgsrc->getRotateDegree(), false); - readyphase++; - - progress ("Preparing shadow/highlight map...", 100 * readyphase / numofphases); if ((todo & (M_TRANSFORM)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled) { - if(((!params.colorappearance.enabled))) { - TMatrix wprof, wiprof; - wprof = iccStore->workingSpaceMatrix( params.icm.working ); - wiprof = iccStore->workingSpaceInverseMatrix( params.icm.working ); - double wip[3][3] = { - {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, - {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, - {wiprof[2][0], wiprof[2][1], wiprof[2][2]} - }; + TMatrix wprof = iccStore->workingSpaceMatrix( params.icm.working ); + const float wp[3][3] = { + {static_cast(wprof[0][0]), static_cast(wprof[0][1]), static_cast(wprof[0][2])}, + {static_cast(wprof[1][0]), static_cast(wprof[1][1]), static_cast(wprof[1][2])}, + {static_cast(wprof[2][0]), static_cast(wprof[2][1]), static_cast(wprof[2][2])} + }; - double wp[3][3] = { - {wprof[0][0], wprof[0][1], wprof[0][2]}, - {wprof[1][0], wprof[1][1], wprof[1][2]}, - {wprof[2][0], wprof[2][1], wprof[2][2]} - }; - - int W = oprevi->getWidth(); - int H = oprevi->getHeight(); - LabImage * labcbdl; - labcbdl = new LabImage(W, H); -#ifndef _DEBUG - #pragma omp parallel for schedule(dynamic, 10) + const int W = oprevi->getWidth(); + const int H = oprevi->getHeight(); + LabImage labcbdl(W, H); +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) #endif - for(int i = 0; i < H; i++) { - for(int j = 0; j < W; j++) { - float r = oprevi->r(i, j); - float g = oprevi->g(i, j); - float b = oprevi->b(i, j); - float X, Y, Z; - float L, aa, bb; - Color::rgbxyz(r, g, b, X, Y, Z, wp); - //convert Lab - Color::XYZ2Lab(X, Y, Z, L, aa, bb); - labcbdl->L[i][j] = L; - labcbdl->a[i][j] = aa; - labcbdl->b[i][j] = bb; - } + //convert RGB => Lab + for(int i = 0; i < H; i++) { + for(int j = 0; j < W; j++) { + float X, Y, Z; + Color::rgbxyz(oprevi->r(i, j), oprevi->g(i, j), oprevi->b(i, j), X, Y, Z, wp); + Color::XYZ2Lab(X, Y, Z, labcbdl.L[i][j], labcbdl.a[i][j], labcbdl.b[i][j]); } + } - ipf.dirpyrequalizer (labcbdl, scale, 0); + ipf.dirpyrequalizer (&labcbdl, scale, 0); -#ifndef _DEBUG - #pragma omp parallel for schedule(dynamic, 10) + TMatrix wiprof = iccStore->workingSpaceInverseMatrix( params.icm.working ); + const float wip[3][3] = { + {static_cast(wiprof[0][0]), static_cast(wiprof[0][1]), static_cast(wiprof[0][2])}, + {static_cast(wiprof[1][0]), static_cast(wiprof[1][1]), static_cast(wiprof[1][2])}, + {static_cast(wiprof[2][0]), static_cast(wiprof[2][1]), static_cast(wiprof[2][2])} + }; + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) #endif - for(int i = 0; i < H; i++) { - for(int j = 0; j < W; j++) { - float L = labcbdl->L[i][j]; - float a = labcbdl->a[i][j]; - float b = labcbdl->b[i][j]; - float x1, y1, z1; - float R, G, B; - Color::Lab2XYZ(L, a, b, x1, y1, z1); - Color::xyz2rgb(x1, y1, z1, R, G, B, wip); - oprevi->r(i, j) = R; - oprevi->g(i, j) = G; - oprevi->b(i, j) = B; - } + for(int i = 0; i < H; i++) { + for(int j = 0; j < W; j++) { + float X, Y, Z; + Color::Lab2XYZ(labcbdl.L[i][j], labcbdl.a[i][j], labcbdl.b[i][j], X, Y, Z); + Color::xyz2rgb(X, Y, Z, oprevi->r(i, j), oprevi->g(i, j), oprevi->b(i, j), wip); } - - delete labcbdl; - } } + + + readyphase++; + progress ("Preparing shadow/highlight map...", 100 * readyphase / numofphases); + if ((todo & M_BLURMAP) && params.sh.enabled) { double radius = sqrt (double(pW * pW + pH * pH)) / 2.0; double shradius = params.sh.radius; diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 87c51dd64..df8821a4b 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -6539,8 +6539,6 @@ void ImProcFunctions::badpixlab(LabImage* lab, double rad, int thr, int mode, fl void ImProcFunctions::dirpyrequalizer (LabImage* lab, int scale, int mode) { - printf("mode=%d\n", mode); - if (params->dirpyrequalizer.enabled && lab->W >= 8 && lab->H >= 8) { float b_l = static_cast(params->dirpyrequalizer.hueskin.value[0]) / 100.0f; float t_l = static_cast(params->dirpyrequalizer.hueskin.value[1]) / 100.0f; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 06bd755e4..1d171e09a 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -741,69 +741,49 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p if (params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled) { - if(((!params.colorappearance.enabled))) { - TMatrix wprof, wiprof; - wprof = iccStore->workingSpaceMatrix( params.icm.working ); - wiprof = iccStore->workingSpaceInverseMatrix( params.icm.working ); - double wip[3][3] = { - {wiprof[0][0], wiprof[0][1], wiprof[0][2]}, - {wiprof[1][0], wiprof[1][1], wiprof[1][2]}, - {wiprof[2][0], wiprof[2][1], wiprof[2][2]} - }; + TMatrix wprof = iccStore->workingSpaceMatrix( params.icm.working ); + const float wp[3][3] = { + {static_cast(wprof[0][0]), static_cast(wprof[0][1]), static_cast(wprof[0][2])}, + {static_cast(wprof[1][0]), static_cast(wprof[1][1]), static_cast(wprof[1][2])}, + {static_cast(wprof[2][0]), static_cast(wprof[2][1]), static_cast(wprof[2][2])} + }; - double wp[3][3] = { - {wprof[0][0], wprof[0][1], wprof[0][2]}, - {wprof[1][0], wprof[1][1], wprof[1][2]}, - {wprof[2][0], wprof[2][1], wprof[2][2]} - }; + const int W = baseImg->getWidth(); + const int H = baseImg->getHeight(); + LabImage labcbdl(W, H); - int W = baseImg->getWidth(); - int H = baseImg->getHeight(); - LabImage * labcbdl; - labcbdl = new LabImage(W, H); -#ifndef _DEBUG - #pragma omp parallel for schedule(dynamic, 10) +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) #endif - for(int i = 0; i < H; i++) { - for(int j = 0; j < W; j++) { - float r = baseImg->r(i, j); - float g = baseImg->g(i, j); - float b = baseImg->b(i, j); - float X, Y, Z; - float L, aa, bb; - Color::rgbxyz(r, g, b, X, Y, Z, wp); - //convert Lab - Color::XYZ2Lab(X, Y, Z, L, aa, bb); - labcbdl->L[i][j] = L; - labcbdl->a[i][j] = aa; - labcbdl->b[i][j] = bb; - } + for(int i = 0; i < H; i++) { + for(int j = 0; j < W; j++) { + float X, Y, Z; + Color::rgbxyz(baseImg->r(i, j), baseImg->g(i, j), baseImg->b(i, j), X, Y, Z, wp); + //convert Lab + Color::XYZ2Lab(X, Y, Z, labcbdl.L[i][j], labcbdl.a[i][j], labcbdl.b[i][j]); } + } - ipf.dirpyrequalizer (labcbdl, 1, 0); + ipf.dirpyrequalizer (&labcbdl, 1, 0); -#ifndef _DEBUG - #pragma omp parallel for schedule(dynamic, 10) + TMatrix wiprof = iccStore->workingSpaceInverseMatrix( params.icm.working ); + const float wip[3][3] = { + {static_cast(wiprof[0][0]), static_cast(wiprof[0][1]), static_cast(wiprof[0][2])}, + {static_cast(wiprof[1][0]), static_cast(wiprof[1][1]), static_cast(wiprof[1][2])}, + {static_cast(wiprof[2][0]), static_cast(wiprof[2][1]), static_cast(wiprof[2][2])} + }; + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) #endif - for(int i = 0; i < H; i++) { - for(int j = 0; j < W; j++) { - float L = labcbdl->L[i][j]; - float a = labcbdl->a[i][j]; - float b = labcbdl->b[i][j]; - float x1, y1, z1; - float R, G, B; - Color::Lab2XYZ(L, a, b, x1, y1, z1); - Color::xyz2rgb(x1, y1, z1, R, G, B, wip); - baseImg->r(i, j) = R; - baseImg->g(i, j) = G; - baseImg->b(i, j) = B; - } + for(int i = 0; i < H; i++) { + for(int j = 0; j < W; j++) { + float X, Y, Z; + Color::Lab2XYZ(labcbdl.L[i][j], labcbdl.a[i][j], labcbdl.b[i][j], X, Y, Z); + Color::xyz2rgb(X, Y, Z, baseImg->r(i, j), baseImg->g(i, j), baseImg->b(i, j), wip); } - - delete labcbdl; - } } From 51de80b558c73db9b79fb76f0f9caff337e0326a Mon Sep 17 00:00:00 2001 From: heckflosse Date: Tue, 1 Mar 2016 19:16:34 +0100 Subject: [PATCH 5/7] Fixed bug with combination of cbdl and ciecam, cleaned code, made SSE version for lab2rgb --- rtdata/languages/default | 8 ++-- rtengine/dcrop.cc | 47 ++----------------- rtengine/imagedimensions.h | 4 +- rtengine/improccoordinator.cc | 50 ++------------------ rtengine/improcfun.cc | 88 +++++++++++++++++++++++++++++------ rtengine/improcfun.h | 4 +- rtengine/refreshmap.cc | 2 +- rtengine/simpleprocess.cc | 48 ++----------------- 8 files changed, 99 insertions(+), 152 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 553fc4a4b..69cc20327 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1204,11 +1204,11 @@ TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending TP_BWMIX_TCMODE_STANDARD;B&W Standard TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard TP_BWMIX_VAL;L -TP_CACORRECTION_BLUE;Blue -TP_CACORRECTION_LABEL;Chromatic Aberration Correction -TP_CACORRECTION_RED;Red +TP_CBDL_METHOD_TOOLTIP;Choose whether the Contrast by Detail Levels tool is to be positioned after the Black-and-White tool, which makes it work in L*a*b* space, or before it, which makes it work in RGB space. +TP_CBDL_AFT;After Black-and-White +TP_CBDL_BEF;Before Black-and-White TP_CBDL_METHOD;Process located -TP_CBDL_METHOD_TOOLTIP;"After Black and White" located the tool in L*a*b process.\n"Before Black and White" located the tool at the beginning of rgb process.\nObviously this can lead to differences. +TP_CBDL_METHOD_TOOLTIP;"After Black and White" located the tool in L*a*b process.\n"Before Black and White" located the tool at the beginning of rgb process.\nObviously this can lead to differences. TP_CBDL_AFT;After Black and White TP_CBDL_BEF;Before Black and White TP_CHMIXER_BLUE;Blue channel diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index cc993b811..4a0e928de 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -712,52 +712,15 @@ void Crop::update (int todo) transCrop = NULL; } - if ((todo & (M_TRANSFORM)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled) { - - TMatrix wprof = iccStore->workingSpaceMatrix( params.icm.working ); - const float wp[3][3] = { - {static_cast(wprof[0][0]), static_cast(wprof[0][1]), static_cast(wprof[0][2])}, - {static_cast(wprof[1][0]), static_cast(wprof[1][1]), static_cast(wprof[1][2])}, - {static_cast(wprof[2][0]), static_cast(wprof[2][1]), static_cast(wprof[2][2])} - }; + if ((todo & (M_TRANSFORM)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) { const int W = baseCrop->getWidth(); const int H = baseCrop->getHeight(); LabImage labcbdl(W, H); -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif + parent->ipf.rgb2lab(*baseCrop, labcbdl, params.icm.working); + parent->ipf.dirpyrequalizer (&labcbdl, skip); + parent->ipf.lab2rgb(labcbdl, *baseCrop, params.icm.working); - //convert RGB => Lab - for(int i = 0; i < H; i++) { - for(int j = 0; j < W; j++) { - float X, Y, Z; - Color::rgbxyz(baseCrop->r(i, j), baseCrop->g(i, j), baseCrop->b(i, j), X, Y, Z, wp); - Color::XYZ2Lab(X, Y, Z, labcbdl.L[i][j], labcbdl.a[i][j], labcbdl.b[i][j]); - } - } - - parent->ipf.dirpyrequalizer (&labcbdl, skip, 0); - - TMatrix wiprof = iccStore->workingSpaceInverseMatrix( params.icm.working ); - const float wip[3][3] = { - {static_cast(wiprof[0][0]), static_cast(wiprof[0][1]), static_cast(wiprof[0][2])}, - {static_cast(wiprof[1][0]), static_cast(wiprof[1][1]), static_cast(wiprof[1][2])}, - {static_cast(wiprof[2][0]), static_cast(wiprof[2][1]), static_cast(wiprof[2][2])} - }; - -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - - //convert Lab => RGB - for(int i = 0; i < H; i++) { - for(int j = 0; j < W; j++) { - float X, Y, Z; - Color::Lab2XYZ(labcbdl.L[i][j], labcbdl.a[i][j], labcbdl.b[i][j], X, Y, Z); - Color::xyz2rgb(X, Y, Z, baseCrop->r(i, j), baseCrop->g(i, j), baseCrop->b(i, j), wip); - } - } } // blurmap for shadow & highlights @@ -889,7 +852,7 @@ void Crop::update (int todo) if(params.dirpyrequalizer.cbdlMethod == "aft") { if(((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled))) { - parent->ipf.dirpyrequalizer (labnCrop, skip, 1); + parent->ipf.dirpyrequalizer (labnCrop, skip); // parent->ipf.Lanczoslab (labnCrop,labnCrop , 1.f/skip); } } diff --git a/rtengine/imagedimensions.h b/rtengine/imagedimensions.h index 0b50d71c1..e3b98f7c5 100644 --- a/rtengine/imagedimensions.h +++ b/rtengine/imagedimensions.h @@ -48,11 +48,11 @@ public: { return height; } - int getWidth () + int getWidth () const { return width; } - int getHeight () + int getHeight () const { return height; } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index bcb2c05ff..2f14c1ded 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -388,55 +388,15 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) ipf.transform (orig_prev, oprevi, 0, 0, 0, 0, pW, pH, fw, fh, imgsrc->getMetaData()->getFocalLen(), imgsrc->getMetaData()->getFocalLen35mm(), imgsrc->getMetaData()->getFocusDist(), imgsrc->getRotateDegree(), false); - - if ((todo & (M_TRANSFORM)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled) { - TMatrix wprof = iccStore->workingSpaceMatrix( params.icm.working ); - const float wp[3][3] = { - {static_cast(wprof[0][0]), static_cast(wprof[0][1]), static_cast(wprof[0][2])}, - {static_cast(wprof[1][0]), static_cast(wprof[1][1]), static_cast(wprof[1][2])}, - {static_cast(wprof[2][0]), static_cast(wprof[2][1]), static_cast(wprof[2][2])} - }; - + if ((todo & (M_TRANSFORM)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) { const int W = oprevi->getWidth(); const int H = oprevi->getHeight(); LabImage labcbdl(W, H); -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - - //convert RGB => Lab - for(int i = 0; i < H; i++) { - for(int j = 0; j < W; j++) { - float X, Y, Z; - Color::rgbxyz(oprevi->r(i, j), oprevi->g(i, j), oprevi->b(i, j), X, Y, Z, wp); - Color::XYZ2Lab(X, Y, Z, labcbdl.L[i][j], labcbdl.a[i][j], labcbdl.b[i][j]); - } - } - - ipf.dirpyrequalizer (&labcbdl, scale, 0); - - TMatrix wiprof = iccStore->workingSpaceInverseMatrix( params.icm.working ); - const float wip[3][3] = { - {static_cast(wiprof[0][0]), static_cast(wiprof[0][1]), static_cast(wiprof[0][2])}, - {static_cast(wiprof[1][0]), static_cast(wiprof[1][1]), static_cast(wiprof[1][2])}, - {static_cast(wiprof[2][0]), static_cast(wiprof[2][1]), static_cast(wiprof[2][2])} - }; - -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - - for(int i = 0; i < H; i++) { - for(int j = 0; j < W; j++) { - float X, Y, Z; - Color::Lab2XYZ(labcbdl.L[i][j], labcbdl.a[i][j], labcbdl.b[i][j], X, Y, Z); - Color::xyz2rgb(X, Y, Z, oprevi->r(i, j), oprevi->g(i, j), oprevi->b(i, j), wip); - } - } + ipf.rgb2lab(*oprevi, labcbdl, params.icm.working); + ipf.dirpyrequalizer (&labcbdl, scale); + ipf.lab2rgb(labcbdl, *oprevi, params.icm.working); } - - readyphase++; progress ("Preparing shadow/highlight map...", 100 * readyphase / numofphases); @@ -710,7 +670,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) if(params.dirpyrequalizer.cbdlMethod == "aft") { if(((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) ) { progress ("Pyramid wavelet...", 100 * readyphase / numofphases); - ipf.dirpyrequalizer (nprevl, scale, 1); + ipf.dirpyrequalizer (nprevl, scale); //ipf.Lanczoslab (ip_wavelet(LabImage * lab, LabImage * dst, const procparams::EqualizerParams & eqparams), nprevl, 1.f/scale); readyphase++; } diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index df8821a4b..79a0bb36c 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -52,17 +52,6 @@ namespace rtengine using namespace procparams; -#undef ABS -#undef CLIPS -#undef CLIPC - -#define ABS(a) ((a)<0?-(a):(a)) -#define CLIPS(a) ((a)>-32768?((a)<32767?(a):32767):-32768) -#define CLIPC(a) ((a)>-32000?((a)<32000?(a):32000):-32000) -#define CLIP2(a) ((a)0.0?((a)<65535.5?(a):65535.5):0.0) - - extern const Settings* settings; LUTf ImProcFunctions::cachef; LUTf ImProcFunctions::gamma2curve; @@ -6537,7 +6526,7 @@ void ImProcFunctions::badpixlab(LabImage* lab, double rad, int thr, int mode, fl } } -void ImProcFunctions::dirpyrequalizer (LabImage* lab, int scale, int mode) +void ImProcFunctions::dirpyrequalizer (LabImage* lab, int scale) { if (params->dirpyrequalizer.enabled && lab->W >= 8 && lab->H >= 8) { float b_l = static_cast(params->dirpyrequalizer.hueskin.value[0]) / 100.0f; @@ -7146,8 +7135,79 @@ double ImProcFunctions::getAutoDistor (const Glib::ustring &fname, int thumb_si } } +void ImProcFunctions::rgb2lab(const Imagefloat &src, LabImage &dst, const Glib::ustring &workingSpace) +{ + TMatrix wprof = iccStore->workingSpaceMatrix( workingSpace ); + const float wp[3][3] = { + {static_cast(wprof[0][0]), static_cast(wprof[0][1]), static_cast(wprof[0][2])}, + {static_cast(wprof[1][0]), static_cast(wprof[1][1]), static_cast(wprof[1][2])}, + {static_cast(wprof[2][0]), static_cast(wprof[2][1]), static_cast(wprof[2][2])} + }; + + const int W = src.getWidth(); + const int H = src.getHeight(); + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for(int i = 0; i < H; i++) { + for(int j = 0; j < W; j++) { + float X, Y, Z; + Color::rgbxyz(src.r(i, j), src.g(i, j), src.b(i, j), X, Y, Z, wp); + //convert Lab + Color::XYZ2Lab(X, Y, Z, dst.L[i][j], dst.a[i][j], dst.b[i][j]); + } + } +} + +SSEFUNCTION void ImProcFunctions::lab2rgb(const LabImage &src, Imagefloat &dst, const Glib::ustring &workingSpace) +{ + TMatrix wiprof = iccStore->workingSpaceInverseMatrix( workingSpace ); + const float wip[3][3] = { + {static_cast(wiprof[0][0]), static_cast(wiprof[0][1]), static_cast(wiprof[0][2])}, + {static_cast(wiprof[1][0]), static_cast(wiprof[1][1]), static_cast(wiprof[1][2])}, + {static_cast(wiprof[2][0]), static_cast(wiprof[2][1]), static_cast(wiprof[2][2])} + }; + + const int W = dst.getWidth(); + const int H = dst.getHeight(); +#ifdef __SSE2__ + vfloat wipv[3][3]; + + for(int i = 0; i < 3; i++) { + for(int j = 0; j < 3; j++) { + wipv[i][j] = F2V(wiprof[i][j]); + } + } +#endif + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for(int i = 0; i < H; i++) { + int j = 0; +#ifdef __SSE2__ + for(; j < W - 3; j += 4) { + vfloat X, Y, Z; + vfloat R,G,B; + Color::Lab2XYZ(LVFU(src.L[i][j]), LVFU(src.a[i][j]), LVFU(src.b[i][j]), X, Y, Z); + Color::xyz2rgb(X, Y, Z, R, G, B, wipv); + STVFU(dst.r(i, j), R); + STVFU(dst.g(i, j), G); + STVFU(dst.b(i, j), B); + } + +#endif + for(; j < W; j++) { + float X, Y, Z; + Color::Lab2XYZ(src.L[i][j], src.a[i][j], src.b[i][j], X, Y, Z); + Color::xyz2rgb(X, Y, Z, dst.r(i, j), dst.g(i, j), dst.b(i, j), wip); + } + } +} + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% } -#undef PIX_SORT -#undef med3x3 diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index f69f04e19..133c59f6e 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -284,7 +284,7 @@ public: void impulse_nrcam (CieImage* ncie, double thresh, float **buffers[3]); void dirpyrdenoise (LabImage* src);//Emil's pyramid denoise - void dirpyrequalizer (LabImage* lab, int scale, int mode);//Emil's wavelet + void dirpyrequalizer (LabImage* lab, int scale);//Emil's wavelet void EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params& cp, int W_L, int H_L, float max0, float min0); @@ -384,6 +384,8 @@ public: static void getAutoExp (LUTu & histogram, int histcompr, double defgain, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh); static double getAutoDistor (const Glib::ustring& fname, int thumb_size); double getTransformAutoFill (int oW, int oH, const LCPMapper *pLCPMap = NULL); + void rgb2lab(const Imagefloat &src, LabImage &dst, const Glib::ustring &workingSpace); + void lab2rgb(const LabImage &src, Imagefloat &dst, const Glib::ustring &workingSpace); }; } #endif diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 292a54133..1bcaf3fa3 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -200,7 +200,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // EvLLCCurve LUMINANCECURVE, // EvLLCredsk ALLNORAW, // EvDPDNLdetail - LUMINANCECURVE, // EvCATEnabled + ALLNORAW, // EvCATEnabled LUMINANCECURVE, // EvCATDegree LUMINANCECURVE, // EvCATMethodsur LUMINANCECURVE, // EvCATAdapscen diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 1d171e09a..c03addb42 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -740,51 +740,13 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p } - if (params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled) { - TMatrix wprof = iccStore->workingSpaceMatrix( params.icm.working ); - const float wp[3][3] = { - {static_cast(wprof[0][0]), static_cast(wprof[0][1]), static_cast(wprof[0][2])}, - {static_cast(wprof[1][0]), static_cast(wprof[1][1]), static_cast(wprof[1][2])}, - {static_cast(wprof[2][0]), static_cast(wprof[2][1]), static_cast(wprof[2][2])} - }; - + if (params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled) { const int W = baseImg->getWidth(); const int H = baseImg->getHeight(); LabImage labcbdl(W, H); - -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - - for(int i = 0; i < H; i++) { - for(int j = 0; j < W; j++) { - float X, Y, Z; - Color::rgbxyz(baseImg->r(i, j), baseImg->g(i, j), baseImg->b(i, j), X, Y, Z, wp); - //convert Lab - Color::XYZ2Lab(X, Y, Z, labcbdl.L[i][j], labcbdl.a[i][j], labcbdl.b[i][j]); - } - } - - ipf.dirpyrequalizer (&labcbdl, 1, 0); - - TMatrix wiprof = iccStore->workingSpaceInverseMatrix( params.icm.working ); - const float wip[3][3] = { - {static_cast(wiprof[0][0]), static_cast(wiprof[0][1]), static_cast(wiprof[0][2])}, - {static_cast(wiprof[1][0]), static_cast(wiprof[1][1]), static_cast(wiprof[1][2])}, - {static_cast(wiprof[2][0]), static_cast(wiprof[2][1]), static_cast(wiprof[2][2])} - }; - -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - - for(int i = 0; i < H; i++) { - for(int j = 0; j < W; j++) { - float X, Y, Z; - Color::Lab2XYZ(labcbdl.L[i][j], labcbdl.a[i][j], labcbdl.b[i][j], X, Y, Z); - Color::xyz2rgb(X, Y, Z, baseImg->r(i, j), baseImg->g(i, j), baseImg->b(i, j), wip); - } - } + ipf.rgb2lab(*baseImg, labcbdl, params.icm.working); + ipf.dirpyrequalizer (&labcbdl, 1); + ipf.lab2rgb(labcbdl, *baseImg, params.icm.working); } // update blurmap @@ -1034,7 +996,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p // directional pyramid wavelet if(params.dirpyrequalizer.cbdlMethod == "aft") { if((params.colorappearance.enabled && !settings->autocielab) || !params.colorappearance.enabled) { - ipf.dirpyrequalizer (labView, 1, 2); //TODO: this is the luminance tonecurve, not the RGB one + ipf.dirpyrequalizer (labView, 1); //TODO: this is the luminance tonecurve, not the RGB one } } From 755f7568bb55d6aac5197fb85ae9e4f6128d0a53 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Tue, 1 Mar 2016 19:30:48 +0100 Subject: [PATCH 6/7] removed big block of inactive code which I forgot to remove in last commit --- rtengine/improcfun.cc | 42 ------------------------------------------ 1 file changed, 42 deletions(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 79a0bb36c..144a16aa2 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -4218,48 +4218,6 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *e } } - /* //Film Simulations - if ( colorLUT ) { - for (int i = istart, ti = 0; i < tH; i++, ti++) { - for (int j = jstart, tj = 0; j < tW; j++, tj++) { - float &sourceR = rtemp[ti * TS + tj]; - float &sourceG = gtemp[ti * TS + tj]; - float &sourceB = btemp[ti * TS + tj]; - - if (!clutAndWorkingProfilesAreSame) { - //convert from working to clut profile - float x, y, z; - Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, work2xyz ); - Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2clut ); - } - - //appply gamma sRGB (default RT) - sourceR = CLIP( Color::gamma_srgb( sourceR ) ); - sourceG = CLIP( Color::gamma_srgb( sourceG ) ); - sourceB = CLIP( Color::gamma_srgb( sourceB ) ); - - float r, g, b; - colorLUT->getRGB( sourceR, sourceG, sourceB, r, g, b ); - // apply strength - sourceR = r * filmSimCorrectedStrength + sourceR * filmSimSourceStrength; - sourceG = g * filmSimCorrectedStrength + sourceG * filmSimSourceStrength; - sourceB = b * filmSimCorrectedStrength + sourceB * filmSimSourceStrength; - // apply inverse gamma sRGB - sourceR = Color::igamma_srgb( sourceR ); - sourceG = Color::igamma_srgb( sourceG ); - sourceB = Color::igamma_srgb( sourceB ); - - if (!clutAndWorkingProfilesAreSame) { - //convert from clut to working profile - float x, y, z; - Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, clut2xyz ); - Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2work ); - } - - } - } - } - */ //black and white if(blackwhite) { if (hasToneCurvebw1) { From 9df905aa1414ffe206f3f8fbde9f85db8992da19 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Tue, 1 Mar 2016 20:21:51 +0100 Subject: [PATCH 7/7] Set default method for cbdl to 'before b&w' --- rtengine/procparams.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index fcdd9fa0f..4dd0bd9f3 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1219,9 +1219,9 @@ void ProcParams::setDefaults () dirpyrequalizer.enabled = false; dirpyrequalizer.gamutlab = false; - dirpyrequalizer.cbdlMethod = "aft"; + dirpyrequalizer.cbdlMethod = "bef"; + - for(int i = 0; i < 6; i ++) { dirpyrequalizer.mult[i] = 1.0; }