From f06e756c20117dc194fc942477dc173c9fb11cff Mon Sep 17 00:00:00 2001 From: Lawrence37 <45837045+Lawrence37@users.noreply.github.com> Date: Thu, 1 Feb 2024 22:41:56 -0800 Subject: [PATCH] AWB non-raw file fixes (for 5.10) (#6940) * Improve Itcwb with non-raw files * Change pre-dev builds wbrefinement * Change template in pre-dev * Improvment improccordinator.cc * Forgotten observer convert * Reenable wbauto autogrey as 5.8 * Remove wrong code * Missing getrgbloc references * Fixed bug due to bias in queu with temperaure correlation issue 6911 * Simpleprocess queue compatibility tif-jpg * Preserve AWB edits from 5.9 In 5.9 for non-raw files, 1. RGB grey uses the unit multipliers with temperature bias applied. 2. Temperature correlation uses the equivalent of temperature 5000, green 1, and red/blue equalizer 1. * Refactor temperature correlation AWB code * Fix inaccurate RGB grey WB preview after using ITC The RGB grey automatic white balance algorithm caches the multipliers. Temperature correlation automatic white balance also caches results to the same location, but never uses it. This causes the RGB grey method to produce incorrect results in the editor. Removing the temperature correlation cache fixes the issue and does not have side-effects. --------- Co-authored-by: U-PCSPECIALIST01\jdesm --- .github/workflows/appimage.yml | 2 +- .github/workflows/windows.yml | 2 +- rtdata/languages/default | 4 +- rtengine/CMakeLists.txt | 1 + rtengine/imagesource.cc | 275 ++++++++++++++++++++++++++++ rtengine/imagesource.h | 27 +++ rtengine/improccoordinator.cc | 317 ++++++++++----------------------- rtengine/improccoordinator.h | 1 - rtengine/procparams.cc | 23 ++- rtengine/procparams.h | 20 +++ rtengine/rawimagesource.cc | 8 +- rtengine/rtengine.h | 9 +- rtengine/rtthumbnail.cc | 14 +- rtengine/simpleprocess.cc | 267 +++++---------------------- rtengine/stdimagesource.cc | 4 + rtengine/stdimagesource.h | 2 +- rtgui/paramsedited.cc | 6 + rtgui/paramsedited.h | 1 + rtgui/whitebalance.cc | 43 ++++- rtgui/whitebalance.h | 3 +- 20 files changed, 561 insertions(+), 468 deletions(-) create mode 100644 rtengine/imagesource.cc diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 5d36fc444..5f447fe8a 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:wbrefinement"]' jobs: build: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 875dce60e..2e1d3bc69 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -15,7 +15,7 @@ on: workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:wbrefinement"]' jobs: build: diff --git a/rtdata/languages/default b/rtdata/languages/default index e5b5af532..243bfa079 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2039,7 +2039,7 @@ PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles PREFERENCES_WBA;White Balance PREFERENCES_WBACORR;White Balance - Automatic temperature correlation PREFERENCES_WBACORR_TOOLTIP;These settings allow, depending on the images (type of raw file, colorimetry, etc.), an adaptation of the " Temperature correlation " algorithm in order to obtain the best overall results. There is no absolute rule, linking these parameters to the results obtained.\n\nThe settings are of 3 types: \n* those accessible to the user from the GUI.\n* those accessible only in reading from each pp3 file : Itcwb_minsize=20, Itcwb_delta=4 Itcwb_rgreen=1 Itcwb_nopurple=false (See Rawpedia)\n* those accessible to the user in 'options' (see Rawpedia)\n You can use "Awb temperature bias" and "Green refinement" to adjust the results. Each movement of these commands brings a new calculation of temperature, tint and correlation.\n\nPlease note that the 3 indicators 'Correlation factor', 'Patch chroma' and ΔE are given for information only. It is not because one of these indicators is better that the result will necessarily be better. -PREFERENCES_WBAENA;Show White Balance auto Temperature correlation Settings +PREFERENCES_WBAENA;Show White Balance Auto temperature correlation settings PREFERENCES_WBAENACUSTOM;Use Custom temperature & tint PREFERENCES_WBAFORC;Forces Extra algoritm PREFERENCES_WBAGREENDELTA;Delta temperature in green iterate loop (if Force Extra enabled) @@ -4166,7 +4166,7 @@ TP_WBALANCE_ITCWB_CUSTOM;Use Custom temperature & tint TP_WBALANCE_ITCWB_DELTA;Delta temperature in green loop TP_WBALANCE_ITCWB_FGREEN;Find green student TP_WBALANCE_ITCWB_FORCED;Close to full CIE diagram -TP_WBALANCE_ITCWB_FRA;Auto Temperature correlation Settings +TP_WBALANCE_ITCWB_FRA;Auto temperature correlation settings TP_WBALANCE_ITCWB_FRA_TOOLTIP;These settings allow, depending on the images (type of raw, colorimetry, etc.), an adaptation of the 'Temperature correlation' algorithm. There is no absolute rule linking these parameters to the results obtained. TP_WBALANCE_ITCWB_MINSIZEPATCH;Patch minimum size TP_WBALANCE_ITCWB_NOPURPLE;Filter on purple color diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 5a9b2d953..6f329f7be 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -120,6 +120,7 @@ set(RTENGINESOURCEFILES imagedimensions.cc imagefloat.cc imageio.cc + imagesource.cc improccoordinator.cc improcfun.cc impulse_denoise.cc diff --git a/rtengine/imagesource.cc b/rtengine/imagesource.cc new file mode 100644 index 000000000..049c6b562 --- /dev/null +++ b/rtengine/imagesource.cc @@ -0,0 +1,275 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2024 RawTherapee team + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ + +#include "imagesource.h" +#include "procparams.h" + + +namespace rtengine +{ + +void ImageSource::getAutoWBMultipliersItcGreen( + procparams::ProcParams ¶ms, + bool forcewbgrey, + int kcam, + double greenitc, + bool extra, + float &temp0, + float &delta, + int &bia, + int &dread, + int nocam, + float &studgood, + float &minchrom, + int &kmin, + float &minhist, + float &maxhist, + int fh, + int fw, + ColorTemp &currWB, + int tempnotisraw, + double greennotisraw, + bool skipRecalculate, + ColorTemp &autoWB, + double &rm, + double &gm, + double &bm + ) +{ + float tem = 5000.f; + float gre = 1.f; + double tempref0bias = 5000.; + double tempitc = 5000.f; + bool autowb1 = true; + double green_thres = 0.8; + + if (isRAW()) {// only with Raw files + + auto currWBitc = getWB(); + + double greenref = currWBitc.getGreen(); + double tempref0bias0 = currWBitc.getTemp(); + + if (greenref > green_thres && params.wb.itcwb_prim == "srgb") { + forcewbgrey = true; + } + + if (!forcewbgrey && (tempref0bias0 < 3300.f) && (greenref < 1.13f && greenref > 0.88f)) { //seems good with temp and green...To fixe...limits 1.13 and 0.88 + if (settings->verbose) { + printf("Keep camera settings temp=%f green=%f\n", tempref0bias0, greenref); + } + + autowb1 = true; + kcam = 1; + } + + if (autowb1) { + //alternative to camera if camera settings out, using autowb grey to find new ref, then mixed with camera + // kcam = 0; + params.wb.method = "autold"; + tempitc = 5000.f; + greenitc = 1.; + currWBitc = getWB(); + tempref0bias = currWBitc.getTemp(); + double greenref = currWBitc.getGreen(); + bool pargref = true; + bool pargre = true; + + if ((greenref > 1.5f || tempref0bias < 3300.f || tempref0bias > 7700.f || forcewbgrey) && kcam != 1 && !params.wb.itcwb_sampling) { //probably camera out to adjust... + getAutoWBMultipliersitc(extra, tempref0bias, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params.wb, params.icm, params.raw, params.toneCurve); + wbMul2Camera(rm, gm, bm); + wbCamera2Mul(rm, gm, bm); + ColorTemp ct(rm, gm, bm, 1.0, currWB.getObserver()); + tem = ct.getTemp(); + gre = ct.getGreen(); + + if (gre > 1.3f) { + pargre = false; + } + + if (greenref > 1.3f) { + pargref = false; + } + + double deltemp = tem - tempref0bias; + + if (gre > 1.5f && !forcewbgrey) { //probable wrong value + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value + gre = 0.5f + 0.5f * LIM(gre, 0.9f, 1.1f);//empirical formula in case system out + } else { + if (!forcewbgrey) { + gre = 0.2f + 0.8f * LIM(gre, 0.85f, 1.15f); + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value + nocam = 0; + } else {//set temp and green to init itcwb algorithm + double grepro = LIM(greenref, green_thres, 1.15); + gre = 0.5f * grepro + 0.5f * LIM(gre, 0.9f, 1.1f);//empirical green between green camera and autowb grey + + if (abs(deltemp) < 400.) { //arbitraries thresholds to refine + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + + if (deltemp > 0.) { + nocam = 1; + } else { + nocam = 2; + } + } else if (abs(deltemp) < 900.) { //other arbitrary threshold + tem = 0.4 * tem + 0.6 * tempref0bias;//find a mixed value between camera and auto grey + + if (deltemp > 0.) { + nocam = 3; + } else { + nocam = 4; + } + } else if (abs(deltemp) < 1500. && tempref0bias < 4500.f) { + if ((pargre && pargref) || (!pargre && !pargref)) { + tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (pargre && !pargref) { + tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (!pargre && pargref) { + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + } + + nocam = 5; + } else if (abs(deltemp) < 1500. && tempref0bias >= 4500.f) { + if ((pargre && pargref) || (!pargre && !pargref)) { + tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (pargre && !pargref) { + tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (!pargre && pargref) { + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + } + + nocam = 6; + } else if (abs(deltemp) >= 1500. && tempref0bias < 5500.f) { + if (tem >= 4500.f) { + if ((pargre && pargref) || (!pargre && !pargref)) { + tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (pargre && !pargref) { + tem = 0.8 * tem + 0.2 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (!pargre && pargref) { + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + } + + nocam = 7; + } else { + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + nocam = 8; + } + } else if (abs(deltemp) >= 1500. && tempref0bias >= 5500.f) { + if (tem >= 10000.f) { + tem = 0.99 * tem + 0.01 * tempref0bias;//find a mixed value between camera and auto grey + nocam = 9; + } else { + if ((pargre && pargref) || (!pargre && !pargref)) { + tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (pargre && !pargref) { + tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey + } + + if (!pargre && pargref) { + tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey + } + + nocam = 10; + } + } else { + tem = 0.4 * tem + 0.6 * tempref0bias; + nocam = 11; + } + } + } + + tempitc = tem ; + + extra = true; + + if (settings->verbose) { + printf("Using new references AWB grey or mixed Enable Extra - temgrey=%f gregrey=%f tempitc=%f nocam=%i\n", (double) tem, (double) gre, (double) tempitc, nocam); + } + } + } + + params.wb.method = "autitcgreen"; + + } else if (!isRAW()) { // Itcwb and no raw + params.wb.temperature = tempnotisraw; + params.wb.green = greennotisraw; + params.wb.equal = 1.; + } + float greenitc_low = 1.f; + float tempitc_low = 5000.f; + //raw files and autitcgreen + if (isRAW() || !skipRecalculate) { + greenitc = 1.; + auto currWBitc = getWB(); + currWBitc = currWBitc.convertObserver(params.wb.observer);//change the temp/green couple with the same multipliers + + double tempref = currWBitc.getTemp() * (1. + params.wb.tempBias); + double greenref = currWBitc.getGreen(); + greenitc = greenref; + + if ((greenref > 1.5f || tempref0bias < 3300.f || tempref0bias > 7700.f || forcewbgrey) && autowb1 && kcam != 1 && !params.wb.itcwb_sampling) { //probably camera out to adjust = greenref ? tempref0bias ? + tempref = tem * (1. + params.wb.tempBias); + greenref = gre; + } else { + + } + + if(params.wb.itcwb_sampling) { + greenitc_low = greenref; + tempitc_low = tempref; + } + + if (settings->verbose) { + printf("tempref=%f greref=%f tempitc=%f greenitc=%f\n", tempref, greenref, tempitc, greenitc); + } + + getAutoWBMultipliersitc(extra, tempref, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params.wb, params.icm, params.raw, params.toneCurve); + + params.wb.temperature = tempitc; + params.wb.green = greenitc; + if(params.wb.itcwb_sampling) { + params.wb.temperature = tempitc_low; + params.wb.green = greenitc_low; + } + + currWB = ColorTemp(params.wb.temperature, params.wb.green, 1., params.wb.method, params.wb.observer); + currWB.getMultipliers(rm, gm, bm); + autoWB.update(rm, gm, bm, params.wb.equal, params.wb.observer, 0.); //params.wb.tempBias already used before + + } +} + +} // namespace rtengine + diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h index 95fd77d21..50bc38baf 100644 --- a/rtengine/imagesource.h +++ b/rtengine/imagesource.h @@ -118,6 +118,33 @@ public: virtual void convertColorSpace (Imagefloat* image, const procparams::ColorManagementParams &cmp, const ColorTemp &wb) = 0; // DIRTY HACK: this method is derived in rawimagesource and strimagesource, but (...,RAWParams raw) will be used ONLY for raw images virtual void getAutoWBMultipliers (double &rm, double &gm, double &bm) = 0; virtual void getAutoWBMultipliersitc(bool extra, double &tempref, double &greenref, double &tempitc, double & greenitc, float &temp0, float &delta, int &bia, int &dread, int &kcam, int &nocam, float &studgood, float &minchrom, int &kmin, float &minhist, float &maxhist, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const procparams::WBParams & wbpar, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::ToneCurveParams &hrp) = 0; + virtual void getAutoWBMultipliersItcGreen( + procparams::ProcParams ¶ms, + bool forcewbgrey, + int kcam, + double greenitc, + bool extra, + float &temp0, + float &delta, + int &bia, + int &dread, + int nocam, + float &studgood, + float &minchrom, + int &kmin, + float &minhist, + float &maxhist, + int fh, + int fw, + ColorTemp &currWB, + int tempnotisraw, + double greennotisraw, + bool skipRecalculate, + ColorTemp &autoWB, + double &rm, + double &gm, + double &bm + ); virtual ColorTemp getWB () const = 0; virtual ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal, StandardObserver observer) = 0; virtual void WBauto(bool extra, double &tempref, double &greenref, array2D &redloc, array2D &greenloc, array2D &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &temp0, float &delta, int &bia, int &dread, int &kcam, int &nocam, float &studgood, float &minchrom, int &kmin, float &minhist, float &maxhist, bool &twotimes, const procparams::WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw, const procparams::ToneCurveParams &hrp) = 0; diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index ef8dc8dbf..5a5dd12af 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -518,7 +518,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } } - const bool autowb = (params->wb.method == "autold" || params->wb.method == "autitcgreen"); + // const bool autowb = (params->wb.method == "autold" || params->wb.method == "autitcgreen"); if (settings->verbose) { printf("automethod=%s \n", params->wb.method.c_str()); @@ -534,6 +534,24 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } currWB = ColorTemp(params->wb.temperature, params->wb.green, params->wb.equal, params->wb.method, params->wb.observer); + int tempnotisraw = 6501;//D65 with Observer 2° - 6473 with Observer 10° + double greennotisraw = 1.;//D65 with Observer 2° - 0.967 with Observer 10° + + if (!imgsrc->isRAW() && params->wb.method == "autitcgreen") { + if (params->wb.compat_version == 1) { + // ITCWB compatibility version 1 used 5000 K and observer 10 + // degrees for non-raw files. + auto currWBitc = ColorTemp(5000., 1., 1., params->wb.method, StandardObserver::TEN_DEGREES); + currWBitc = currWBitc.convertObserver(params->wb.observer); + tempnotisraw = currWBitc.getTemp(); + greennotisraw = currWBitc.getGreen(); + } else { + auto currWBitc = imgsrc->getWB();//if jpg TIF with another illuminant + currWBitc = currWBitc.convertObserver(params->wb.observer); + tempnotisraw = currWBitc.getTemp(); + greennotisraw = currWBitc.getGreen(); + } + } int dread = 0; int bia = 1; @@ -545,7 +563,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) int kmin = 20; float minhist = 1000000000.f; float maxhist = -1000.f; - double tempitc = 5000.f; double greenitc = 1.; float temp0 = 5000.f; bool extra = false; @@ -556,230 +573,21 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) } else if (params->wb.method == "Camera") { currWB = imgsrc->getWB(); lastAwbauto = ""; //reinitialize auto - } else if (autowb) { - float tem = 5000.f; - float gre = 1.f; - double tempref0bias = 5000.; - tempitc = 5000.f; - bool autowb1 = true; - double green_thres = 0.8; - - if (params->wb.method == "autitcgreen") { - - currWBitc = imgsrc->getWB(); - - double greenref = currWBitc.getGreen(); - double tempref0bias0 = currWBitc.getTemp(); - - if (greenref > green_thres && params->wb.itcwb_prim == "srgb") { - forcewbgrey = true; - } - - if (!forcewbgrey && (tempref0bias0 < 3300.f) && (greenref < 1.13f && greenref > 0.88f)) { //seems good with temp and green...To fixe...limits 1.13 and 0.88 - if (settings->verbose) { - printf("Keep camera settings temp=%f green=%f\n", tempref0bias0, greenref); - } - - autowb1 = true; - kcam = 1; - } - - if (autowb1) { - //alternative to camera if camera settings out, using autowb grey to find new ref, then mixed with camera - // kcam = 0; - params->wb.method = "autold"; - double rm, gm, bm; - tempitc = 5000.f; - greenitc = 1.; - currWBitc = imgsrc->getWB(); - tempref0bias = currWBitc.getTemp(); - double greenref = currWBitc.getGreen(); - bool pargref = true; - bool pargre = true; - - if ((greenref > 1.5f || tempref0bias < 3300.f || tempref0bias > 7700.f || forcewbgrey) && kcam != 1 && !params->wb.itcwb_sampling) { //probably camera out to adjust... - imgsrc->getAutoWBMultipliersitc(extra, tempref0bias, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw, params->toneCurve); - imgsrc->wbMul2Camera(rm, gm, bm); - imgsrc->wbCamera2Mul(rm, gm, bm); - ColorTemp ct(rm, gm, bm, 1.0, currWB.getObserver()); - tem = ct.getTemp(); - gre = ct.getGreen(); - - if (gre > 1.3f) { - pargre = false; - } - - if (greenref > 1.3f) { - pargref = false; - } - - double deltemp = tem - tempref0bias; - - if (gre > 1.5f && !forcewbgrey) { //probable wrong value - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value - gre = 0.5f + 0.5f * LIM(gre, 0.9f, 1.1f);//empirical formula in case system out - } else { - if (!forcewbgrey) { - gre = 0.2f + 0.8f * LIM(gre, 0.85f, 1.15f); - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value - nocam = 0; - } else {//set temp and green to init itcwb algorithm - double grepro = LIM(greenref, green_thres, 1.15); - gre = 0.5f * grepro + 0.5f * LIM(gre, 0.9f, 1.1f);//empirical green between green camera and autowb grey - - if (abs(deltemp) < 400.) { //arbitraries thresholds to refine - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - - if (deltemp > 0.) { - nocam = 1; - } else { - nocam = 2; - } - } else if (abs(deltemp) < 900.) { //other arbitrary threshold - tem = 0.4 * tem + 0.6 * tempref0bias;//find a mixed value between camera and auto grey - - if (deltemp > 0.) { - nocam = 3; - } else { - nocam = 4; - } - } else if (abs(deltemp) < 1500. && tempref0bias < 4500.f) { - if ((pargre && pargref) || (!pargre && !pargref)) { - tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (pargre && !pargref) { - tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (!pargre && pargref) { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - } - - nocam = 5; - } else if (abs(deltemp) < 1500. && tempref0bias >= 4500.f) { - if ((pargre && pargref) || (!pargre && !pargref)) { - tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (pargre && !pargref) { - tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (!pargre && pargref) { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - } - - nocam = 6; - } else if (abs(deltemp) >= 1500. && tempref0bias < 5500.f) { - if (tem >= 4500.f) { - if ((pargre && pargref) || (!pargre && !pargref)) { - tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (pargre && !pargref) { - tem = 0.8 * tem + 0.2 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (!pargre && pargref) { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - } - - nocam = 7; - } else { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - nocam = 8; - } - } else if (abs(deltemp) >= 1500. && tempref0bias >= 5500.f) { - if (tem >= 10000.f) { - tem = 0.99 * tem + 0.01 * tempref0bias;//find a mixed value between camera and auto grey - nocam = 9; - } else { - if ((pargre && pargref) || (!pargre && !pargref)) { - tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (pargre && !pargref) { - tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (!pargre && pargref) { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - } - - nocam = 10; - } - } else { - tem = 0.4 * tem + 0.6 * tempref0bias; - nocam = 11; - } - } - } - - tempitc = tem ; - - extra = true; - - if (settings->verbose) { - printf("Using new references AWB grey or mixed Enable Extra - temgrey=%f gregrey=%f tempitc=%f nocam=%i\n", (double) tem, (double) gre, (double) tempitc, nocam); - } - } - } - - params->wb.method = "autitcgreen"; - - } - float greenitc_low = 1.f; - float tempitc_low = 5000.f; - if (params->wb.method == "autitcgreen" || lastAwbEqual != params->wb.equal || lastAwbObserver != params->wb.observer || lastAwbTempBias != params->wb.tempBias || lastAwbauto != params->wb.method) { + + } else if (params->wb.method == "autold") { + if (lastAwbEqual != params->wb.equal || lastAwbTempBias != params->wb.tempBias || lastAwbauto != params->wb.method) { double rm, gm, bm; - greenitc = 1.; - currWBitc = imgsrc->getWB(); - currWBitc = currWBitc.convertObserver(params->wb.observer);//change the temp/green couple with the same multipliers - - double tempref = currWBitc.getTemp() * (1. + params->wb.tempBias); - double greenref = currWBitc.getGreen(); - greenitc = greenref; - - if ((greenref > 1.5f || tempref0bias < 3300.f || tempref0bias > 7700.f || forcewbgrey) && autowb1 && kcam != 1 && !params->wb.itcwb_sampling) { //probably camera out to adjust = greenref ? tempref0bias ? - tempref = tem * (1. + params->wb.tempBias); - greenref = gre; + if (params->wb.compat_version == 1 && !imgsrc->isRAW()) { + // RGB grey compatibility version 1 used the identity + // multipliers plus temperature bias for non-raw files. + rm = gm = bm = 1.; } else { - - } - - if(params->wb.itcwb_sampling) { - greenitc_low = greenref; - tempitc_low = tempref; - } - - if (settings->verbose && params->wb.method == "autitcgreen") { - printf("tempref=%f greref=%f tempitc=%f greenitc=%f\n", tempref, greenref, tempitc, greenitc); - } - - imgsrc->getAutoWBMultipliersitc(extra, tempref, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params->wb, params->icm, params->raw, params->toneCurve); - - if (params->wb.method == "autitcgreen") { - params->wb.temperature = tempitc; - params->wb.green = greenitc; - if(params->wb.itcwb_sampling) { - params->wb.temperature = tempitc_low; - params->wb.green = greenitc_low; - } - - currWB = ColorTemp(params->wb.temperature, params->wb.green, 1., params->wb.method, params->wb.observer); - currWB.getMultipliers(rm, gm, bm); - autoWB.update(rm, gm, bm, params->wb.equal, params->wb.observer, params->wb.tempBias); + imgsrc->getAutoWBMultipliers(rm, gm, bm); } if (rm != -1.) { - double bias = params->wb.tempBias; - if (params->wb.method == "autitcgreen") { - bias = 0.; - } - autoWB.update(rm, gm, bm, params->wb.equal, params->wb.observer, bias); lastAwbEqual = params->wb.equal; lastAwbObserver = params->wb.observer; @@ -791,6 +599,58 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) lastAwbTempBias = 0.0; lastAwbauto = ""; autoWB.useDefaults(params->wb.equal, params->wb.observer); + + } + + //double rr,gg,bb; + //autoWB.getMultipliers(rr,gg,bb); + } + currWB = autoWB; + // lastAwbauto = ""; //reinitialize auto + } else if (params->wb.method == "autitcgreen") { //(// autowb) { + double rm; + double gm; + double bm; + imgsrc->getAutoWBMultipliersItcGreen( + *params, + forcewbgrey, + kcam, + greenitc, + extra, + temp0, + delta, + bia, + dread, + nocam, + studgood, + minchrom, + kmin, + minhist, + maxhist, + fh, + fw, + currWB, + tempnotisraw, + greennotisraw, + lastAwbEqual == params->wb.equal && lastAwbObserver == params->wb.observer && lastAwbTempBias == params->wb.tempBias && lastAwbauto == params->wb.method, + autoWB, + rm, + gm, + bm); + + if (imgsrc->isRAW() || lastAwbEqual != params->wb.equal || lastAwbObserver != params->wb.observer || lastAwbTempBias != params->wb.tempBias || lastAwbauto != params->wb.method) { + if (rm != -1.) { + autoWB.update(rm, gm, bm, params->wb.equal, params->wb.observer); + lastAwbEqual = params->wb.equal; + lastAwbObserver = params->wb.observer; + lastAwbTempBias = params->wb.tempBias; + lastAwbauto = params->wb.method; + } else { + lastAwbEqual = -1.; + lastAwbObserver = ColorTemp::DEFAULT_OBSERVER; + lastAwbTempBias = 0.0; + lastAwbauto = ""; + autoWB.useDefaults(params->wb.equal, params->wb.observer); } } @@ -822,12 +682,12 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) int met = 0; - if (awbListener) { - if (params->wb.method == "autitcgreen") { + if (awbListener && params->wb.enabled) { + if (params->wb.method == "autitcgreen" && imgsrc->isRAW()) {//Raw files if (params->wb.itcwb_sampling) { dread = 1; studgood = 1.f; - awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, 0, 1, 0, dread, studgood, 0, 0, 0, 0); + awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, 0, 1, 0, dread, studgood, 0, 0, 0, 0, AutoWBListener::AWBMode::TEMP_CORRELATION_RAW); } else { minchrom = LIM(minchrom, 0.f, 0.9f); @@ -836,10 +696,19 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) maxhist = std::max(maxhist, 1000.f); kmin = std::max(kmin, 18); dread = LIM(dread, 10, 239); - awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, temp0, delta, bia, dread, studgood, minchrom, kmin, minhist, maxhist); + awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, temp0, delta, bia, dread, studgood, minchrom, kmin, minhist, maxhist, AutoWBListener::AWBMode::TEMP_CORRELATION_RAW); } + } else if (params->wb.method == "autitcgreen" && !imgsrc->isRAW()) {//non raw files + params->wb.temperature = tempnotisraw; + params->wb.green = greennotisraw; + currWB = ColorTemp(params->wb.temperature, params->wb.green, params->wb.equal, params->wb.method, params->wb.observer); + + awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, -1.f, -1.f, 1, 1, -1.f, -1.f, 1, -1.f, -1.f, AutoWBListener::AWBMode::TEMP_CORRELATION_NON_RAW);//false => hide settings + + } else if (params->wb.method == "autold"){ + awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, -1.f, -1.f, 1, 1, -1.f, -1.f, 1, -1.f, -1.f, AutoWBListener::AWBMode::RGB_GREY); } else { - awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, -1.f, -1.f, 1, 1, -1.f, -1.f, 1, -1.f, -1.f); + awbListener->WBChanged(met, params->wb.temperature, params->wb.green, rw, gw, bw, -1.f, -1.f, 1, 1, -1.f, -1.f, 1, -1.f, -1.f, AutoWBListener::AWBMode::NONE); } } diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 7e4e3bb06..e236aed17 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -78,7 +78,6 @@ protected: ColorTemp autoWB; ColorTemp currWBloc; ColorTemp autoWBloc; - ColorTemp currWBitc; double lastAwbEqual; StandardObserver lastAwbObserver{ColorTemp::DEFAULT_OBSERVER}; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index aa3158c72..f520c6507 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1409,7 +1409,8 @@ WBParams::WBParams() : itcwb_nopurple(false),//keep for settings itcwb_alg(false),//checkbox itcwb_prim("beta"),//combobox - itcwb_sampling(false)//keep for 5.9 and for settings + itcwb_sampling(false),//keep for 5.9 and for settings + compat_version(WBParams::CURRENT_COMPAT_VERSION) { } @@ -1434,6 +1435,7 @@ bool WBParams::isPanningRelatedChange(const WBParams& other) const && itcwb_green == other.itcwb_green && itcwb_prim == other.itcwb_prim && itcwb_alg == other.itcwb_alg + && compat_version == other.compat_version ) ) @@ -1455,7 +1457,8 @@ bool WBParams::operator ==(const WBParams& other) const && itcwb_nopurple == other.itcwb_nopurple && itcwb_alg == other.itcwb_alg && itcwb_prim == other.itcwb_prim - && itcwb_sampling == other.itcwb_sampling; + && itcwb_sampling == other.itcwb_sampling + && compat_version == other.compat_version; } @@ -6314,6 +6317,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wb.itcwb_alg, "White Balance", "Itcwb_alg", wb.itcwb_alg, keyFile); saveToKeyfile(!pedited || pedited->wb.itcwb_prim, "White Balance", "Itcwb_prim", wb.itcwb_prim, keyFile); saveToKeyfile(!pedited || pedited->wb.itcwb_sampling, "White Balance", "Itcwb_sampling", wb.itcwb_sampling, keyFile); + saveToKeyfile(!pedited || pedited->wb.compat_version, "White Balance", "CompatibilityVersion", wb.compat_version, keyFile); // Colorappearance saveToKeyfile(!pedited || pedited->colorappearance.enabled, "Color appearance", "Enabled", colorappearance.enabled, keyFile); @@ -8290,7 +8294,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "White Balance", "Enabled", wb.enabled, pedited->wb.enabled); assignFromKeyfile(keyFile, "White Balance", "Setting", wb.method, pedited->wb.method); if (wb.method == "Auto") { - wb.method = "autold"; + wb.method = "autitcgreen"; //"autold"; } assignFromKeyfile(keyFile, "White Balance", "Temperature", wb.temperature, pedited->wb.temperature); assignFromKeyfile(keyFile, "White Balance", "Green", wb.green, pedited->wb.green); @@ -8315,6 +8319,19 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } assignFromKeyfile(keyFile, "White Balance", "Itcwb_sampling", wb.itcwb_sampling, pedited->wb.itcwb_sampling); + if (!assignFromKeyfile(keyFile, "White Balance", "CompatibilityVersion", wb.compat_version, pedited->wb.compat_version)) { + bool compat_version_edited = true; + if (ppVersion <= 346) { // 5.8 and earlier. + wb.compat_version = 0; + } else if (ppVersion <= 349) { // 5.9. + wb.compat_version = 1; + } else { + compat_version_edited = false; + } + if (pedited) { + pedited->wb.compat_version = pedited->wb.compat_version || compat_version_edited; + } + } } if (keyFile.has_group("Defringing")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 2723cd2f2..6e733e761 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -636,6 +636,8 @@ struct WBEntry { }; struct WBParams { + static constexpr int CURRENT_COMPAT_VERSION = 2; + bool enabled; Glib::ustring method; int temperature; @@ -649,6 +651,24 @@ struct WBParams { bool itcwb_alg; Glib::ustring itcwb_prim; bool itcwb_sampling; + /** + * Used to maintain edits from previous versions of RawTherapee where + * compatibility cannot be maintained simply by converting the parameters, + * for example, when the output depends on the file type. + * + * Version 0: + * - Base version. + * Version 1 (5.9): + * - RGB Gray fixed to (1, 1, 1) RGB multipliers before temperature bias + * for non-raw files. + * - Temperature correlation fixed to temperature 5000, green 1, and equal + * 1 or equivalent for non-raw files. + * Version 2 (5.10): + * - RGB grey restored to version 0. + * - Temperature correlation equivalent to method "Camera" for non-raw + * files. + */ + int compat_version; WBParams(); diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 738ba4e71..ec91bdbe4 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -7407,7 +7407,6 @@ void RawImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int int precision = 3;//must be 3 5 or 9 bool oldsampling = wbpar.itcwb_sampling; - if (oldsampling == true) { precision = 5; } @@ -7692,12 +7691,7 @@ void RawImageSource::getAutoWBMultipliersitc(bool extra, double & tempref, doubl printf("RGB grey AVG: %g %g %g\n", avg_r / std::max(1, rn), avg_g / std::max(1, gn), avg_b / std::max(1, bn)); } - if (wbpar.method == "autitcgreen") { - //not used - redAWBMul = rm = avg_rm * refwb_red; - greenAWBMul = gm = avg_gm * refwb_green; - blueAWBMul = bm = avg_bm * refwb_blue; - } else { + if (wbpar.method != "autitcgreen") { const double reds = avg_r / std::max(1, rn) * refwb_red; const double greens = avg_g / std::max(1, gn) * refwb_green; const double blues = avg_b / std::max(1, bn) * refwb_blue; diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index ba4d2ed60..fb669e1c8 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -458,8 +458,15 @@ public: class AutoWBListener { public: + enum class AWBMode { + NONE, + RGB_GREY, + TEMP_CORRELATION_NON_RAW, + TEMP_CORRELATION_RAW, + }; + virtual ~AutoWBListener() = default; - virtual void WBChanged(int met, double temp, double green, double rw, double gw, double bw, float temp0, float delta, int bia, int dread, float studgood, float minchrom, int kmin, float histmin, float histmax) = 0; + virtual void WBChanged(int met, double temp, double green, double rw, double gw, double bw, float temp0, float delta, int bia, int dread, float studgood, float minchrom, int kmin, float histmin, float histmax, AWBMode aWBMode) = 0; }; class FrameCountListener diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index bc832661a..4337477da 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -1202,7 +1202,19 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT double cam_b = colorMatrix[2][0] * camwbRed + colorMatrix[2][1] * camwbGreen + colorMatrix[2][2] * camwbBlue; currWB = ColorTemp (cam_r, cam_g, cam_b, params.wb.equal, params.wb.observer); } else if (params.wb.method == "autold") { - currWB = ColorTemp (autoWBTemp, autoWBGreen, wbEqual, "Custom", wbObserver); + if (params.wb.compat_version == 1 && !isRaw) { + // RGB grey compatibility version 1 used the identity multipliers + // plus temperature bias for non-raw files. + currWB.update(1., 1., 1., params.wb.equal, params.wb.observer, params.wb.tempBias); + } else { + currWB = ColorTemp(autoWBTemp, autoWBGreen, wbEqual, "Custom", wbObserver); + } + } else if (params.wb.method == "autitcgreen") { + if (params.wb.compat_version == 1 && !isRaw) { + currWB = ColorTemp(5000., 1., 1., params.wb.method, StandardObserver::TEN_DEGREES); + } else { + // TODO: Temperature correlation AWB. + } } double rm, gm, bm; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 319ba7f3b..b82c7fe79 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -275,7 +275,7 @@ private: if (params.wb.method == "autitcgreen" && flush) { imgsrc->getrgbloc(0, 0, fh, fw, 0, 0, fh, fw, params.wb); } - const bool autowb = params.wb.method == "autitcgreen"; + const bool autowb = (params.wb.method == "autitcgreen" && imgsrc->isRAW() && flush); ColorTemp autoWB; int dread = 0; int bia = 1; @@ -295,233 +295,60 @@ private: if (!params.wb.enabled) { currWB = ColorTemp(); - } else if (params.wb.method == "Camera") { + } else if (params.wb.method == "Camera" || (params.wb.method == "autitcgreen" && params.wb.compat_version >= 2 && !imgsrc->isRAW() && flush)) {//Use also Camera settings for Temperature correlation and TIF/Jpg currWB = imgsrc->getWB(); } else if (params.wb.method == "autold") {//for Auto RGB double rm, gm, bm; - imgsrc->getAutoWBMultipliers(rm, gm, bm); + if (params.wb.compat_version == 1 && !imgsrc->isRAW()) { + // RGB grey compatibility version 1 used the identity + // multipliers plus temperature bias for non-raw files. + rm = gm = bm = 1.; + } else { + imgsrc->getAutoWBMultipliers(rm, gm, bm); + } currWB.update(rm, gm, bm, params.wb.equal, params.wb.observer, params.wb.tempBias); - } else if (autowb && flush) {//for auto Itcwb - flush to enable only when batch + } else if (autowb) {//for auto Itcwb - flush to enable only when batch only with Raw files //code similar to that present in improccoordinator.cc - float tem = 5000.f; - float gre = 1.f; - double tempref0bias = 5000.; - tempitc = 5000.f; - bool autowb1 = true; - double green_thres = 0.8; - - { - currWBitc = imgsrc->getWB(); - - double greenref = currWBitc.getGreen(); - double tempref0bias0 = currWBitc.getTemp(); - - if (greenref > green_thres && params.wb.itcwb_prim == "srgb") { - forcewbgrey = true; - } - - if (!forcewbgrey && (tempref0bias0 < 3300.f) && (greenref < 1.13f && greenref > 0.88f)) { //seems good with temp and green...To fixe...limits 1.13 and 0.88 - if (settings->verbose) { - printf("Keep camera settings temp=%f green=%f\n", tempref0bias0, greenref); - } - - autowb1 = true; - kcam = 1; - } - - if (autowb1) { - //alternative to camera if camera settings out, using autowb grey to find new ref, then mixed with camera - // kcam = 0; - params.wb.method = "autold"; - double rm, gm, bm; - tempitc = 5000.f; - greenitc = 1.; - currWBitc = imgsrc->getWB(); - tempref0bias = currWBitc.getTemp(); - double greenref = currWBitc.getGreen(); - bool pargref = true; - bool pargre = true; - - if ((greenref > 1.5f || tempref0bias < 3300.f || tempref0bias > 7700.f || forcewbgrey) && kcam != 1 && !params.wb.itcwb_sampling) { //probably camera out to adjust... - imgsrc->getAutoWBMultipliersitc(extra, tempref0bias, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params.wb, params.icm, params.raw, params.toneCurve); - imgsrc->wbMul2Camera(rm, gm, bm); - imgsrc->wbCamera2Mul(rm, gm, bm); - ColorTemp ct(rm, gm, bm, 1.0, currWB.getObserver()); - tem = ct.getTemp(); - gre = ct.getGreen(); - - if (gre > 1.3f) { - pargre = false; - } - - if (greenref > 1.3f) { - pargref = false; - } - - double deltemp = tem - tempref0bias; - - if (gre > 1.5f && !forcewbgrey) { //probable wrong value - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value - gre = 0.5f + 0.5f * LIM(gre, 0.9f, 1.1f);//empirical formula in case system out - } else { - if (!forcewbgrey) { - gre = 0.2f + 0.8f * LIM(gre, 0.85f, 1.15f); - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value - nocam = 0; - } else {//set temp and green to init itcwb algorithm - double grepro = LIM(greenref, green_thres, 1.15); - gre = 0.5f * grepro + 0.5f * LIM(gre, 0.9f, 1.1f);//empirical green between green camera and autowb grey - - if (abs(deltemp) < 400.) { //arbitraries thresholds to refine - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - - if (deltemp > 0.) { - nocam = 1; - } else { - nocam = 2; - } - } else if (abs(deltemp) < 900.) { //other arbitrary threshold - tem = 0.4 * tem + 0.6 * tempref0bias;//find a mixed value between camera and auto grey - - if (deltemp > 0.) { - nocam = 3; - } else { - nocam = 4; - } - } else if (abs(deltemp) < 1500. && tempref0bias < 4500.f) { - if ((pargre && pargref) || (!pargre && !pargref)) { - tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (pargre && !pargref) { - tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (!pargre && pargref) { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - } - - nocam = 5; - } else if (abs(deltemp) < 1500. && tempref0bias >= 4500.f) { - if ((pargre && pargref) || (!pargre && !pargref)) { - tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (pargre && !pargref) { - tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (!pargre && pargref) { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - } - - nocam = 6; - } else if (abs(deltemp) >= 1500. && tempref0bias < 5500.f) { - if (tem >= 4500.f) { - if ((pargre && pargref) || (!pargre && !pargref)) { - tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (pargre && !pargref) { - tem = 0.8 * tem + 0.2 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (!pargre && pargref) { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - } - - nocam = 7; - } else { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - nocam = 8; - } - } else if (abs(deltemp) >= 1500. && tempref0bias >= 5500.f) { - if (tem >= 10000.f) { - tem = 0.99 * tem + 0.01 * tempref0bias;//find a mixed value between camera and auto grey - nocam = 9; - } else { - if ((pargre && pargref) || (!pargre && !pargref)) { - tem = 0.45 * tem + 0.55 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (pargre && !pargref) { - tem = 0.7 * tem + 0.3 * tempref0bias;//find a mixed value between camera and auto grey - } - - if (!pargre && pargref) { - tem = 0.3 * tem + 0.7 * tempref0bias;//find a mixed value between camera and auto grey - } - - nocam = 10; - } - } else { - tem = 0.4 * tem + 0.6 * tempref0bias; - nocam = 11; - } - } - } - - tempitc = tem ; - - extra = true; - - if (settings->verbose) { - printf("Using new references AWB grey or mixed Enable Extra - temgrey=%f gregrey=%f tempitc=%f nocam=%i\n", (double) tem, (double) gre, (double) tempitc, nocam); - } - } - } - - params.wb.method = "autitcgreen"; - - } - - float greenitc_low = 1.f; - float tempitc_low = 5000.f; - { - double rm, gm, bm; - greenitc = 1.; - currWBitc = imgsrc->getWB(); - currWBitc = currWBitc.convertObserver(params.wb.observer);//change the temp/green couple with the same multipliers - - double tempref = currWBitc.getTemp() * (1. + params.wb.tempBias); - double greenref = currWBitc.getGreen(); - greenitc = greenref; - - if ((greenref > 1.5f || tempref0bias < 3300.f || tempref0bias > 7700.f || forcewbgrey) && autowb1 && kcam != 1 && !params.wb.itcwb_sampling) { //probably camera out to adjust = greenref ? tempref0bias ? - tempref = tem * (1. + params.wb.tempBias); - greenref = gre; - } else { - - } - - if(params.wb.itcwb_sampling) { - greenitc_low = greenref; - tempitc_low = tempref; - } - - if (settings->verbose && params.wb.method == "autitcgreen") { - printf("tempref=%f greref=%f tempitc=%f greenitc=%f\n", tempref, greenref, tempitc, greenitc); - } - - imgsrc->getAutoWBMultipliersitc(extra, tempref, greenref, tempitc, greenitc, temp0, delta, bia, dread, kcam, nocam, studgood, minchrom, kmin, minhist, maxhist, 0, 0, fh, fw, 0, 0, fh, fw, rm, gm, bm, params.wb, params.icm, params.raw, params.toneCurve); - - - params.wb.temperature = tempitc; - params.wb.green = greenitc; - - if(params.wb.itcwb_sampling) { - params.wb.temperature = tempitc_low; - params.wb.green = greenitc_low; - } - - currWB = ColorTemp(params.wb.temperature, params.wb.green, 1., params.wb.method, params.wb.observer); - currWB.getMultipliers(rm, gm, bm); - autoWB.update(rm, gm, bm, params.wb.equal, params.wb.observer, params.wb.tempBias); - - } + double rm; + double gm; + double bm; + imgsrc->getAutoWBMultipliersItcGreen( + params, + forcewbgrey, + kcam, + greenitc, + extra, + temp0, + delta, + bia, + dread, + nocam, + studgood, + minchrom, + kmin, + minhist, + maxhist, + fh, + fw, + currWB, + 0, + 0., + false, + autoWB, + rm, + gm, + bm); currWB = autoWB; + } else if (params.wb.method == "autitcgreen" && params.wb.compat_version == 1 && !imgsrc->isRAW() && flush) { + // ITCWB compatibility version 1 used 5000 K and observer 10 degrees + // for non-raw files. + currWB = ColorTemp(5000., 1., 1., params.wb.method, StandardObserver::TEN_DEGREES); + currWB.convertObserver(params.wb.observer); + params.wb.temperature = currWB.getTemp(); + params.wb.green = currWB.getGreen(); + params.wb.equal = currWB.getEqual(); } //end WB auto diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc index 9363c84cb..435f2f9a0 100644 --- a/rtengine/stdimagesource.cc +++ b/rtengine/stdimagesource.cc @@ -315,6 +315,10 @@ void StdImageSource::WBauto(bool extra, double &tempref, double &greenref, array { } +void StdImageSource::getrgbloc(int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, const procparams::WBParams & wbpar) +{ +} + void StdImageSource::getAutoWBMultipliersitc(bool extra, double &tempref, double &greenref, double &tempitc, double &greenitc, float &temp0, float &delta, int &bia, int &dread, int &kcam, int &nocam, float &studgood, float &minchrom, int &kmin, float &minhist, float &maxhist, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const WBParams & wbpar, const ColorManagementParams &cmp, const RAWParams &raw, const ToneCurveParams &hrp) { if (redAWBMul != -1.) { diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h index 8c2a54a3b..1ffb0158d 100644 --- a/rtengine/stdimagesource.h +++ b/rtengine/stdimagesource.h @@ -59,7 +59,7 @@ public: int load (const Glib::ustring &fname) override; void getWBMults (const ColorTemp &ctemp, const procparams::RAWParams &raw, std::array& scale_mul, float &autoGainComp, float &rm, float &gm, float &bm) const override {}; void getImage (const ColorTemp &ctemp, int tran, Imagefloat* image, const PreviewProps &pp, const procparams::ToneCurveParams &hrp, const procparams::RAWParams &raw) override; - void getrgbloc (int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, const procparams::WBParams & wbpar) override {}; + void getrgbloc (int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, const procparams::WBParams & wbpar) override; ColorTemp getWB () const override { return wb; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index d4795f994..9b039eb66 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -273,6 +273,7 @@ void ParamsEdited::set(bool v) wb.itcwb_alg = v; wb.itcwb_prim = v; wb.itcwb_sampling = v; + wb.compat_version = v; //colorShift.a = v; //colorShift.b = v; //lumaDenoise.enabled = v; @@ -988,6 +989,7 @@ void ParamsEdited::initFrom(const std::vector& wb.itcwb_alg = wb.itcwb_alg && p.wb.itcwb_alg == other.wb.itcwb_alg; wb.itcwb_prim = wb.itcwb_prim && p.wb.itcwb_prim == other.wb.itcwb_prim; wb.itcwb_sampling = wb.itcwb_sampling && p.wb.itcwb_sampling == other.wb.itcwb_sampling; + wb.compat_version = wb.compat_version && p.wb.compat_version == other.wb.compat_version; //colorShift.a = colorShift.a && p.colorShift.a == other.colorShift.a; //colorShift.b = colorShift.b && p.colorShift.b == other.colorShift.b; //lumaDenoise.enabled = lumaDenoise.enabled && p.lumaDenoise.enabled == other.lumaDenoise.enabled; @@ -2896,6 +2898,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wb.temperature = dontforceSet && options.baBehav[ADDSET_WB_TEMPERATURE] ? toEdit.wb.temperature + mods.wb.temperature : mods.wb.temperature; } + if (wb.compat_version) { + toEdit.wb.compat_version = mods.wb.compat_version; + } + //if (colorShift.a) toEdit.colorShift.a = dontforceSet && options.baBehav[ADDSET_CS_BLUEYELLOW] ? toEdit.colorShift.a + mods.colorShift.a : mods.colorShift.a; //if (colorShift.b) toEdit.colorShift.b = dontforceSet && options.baBehav[ADDSET_CS_GREENMAGENTA] ? toEdit.colorShift.b + mods.colorShift.b : mods.colorShift.b; //if (lumaDenoise.enabled) toEdit.lumaDenoise.enabled = mods.lumaDenoise.enabled; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 501617c00..d5b082a90 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -255,6 +255,7 @@ struct WBParamsEdited { bool itcwb_prim; bool itcwb_sampling; bool itcwb_green; + bool compat_version; }; diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc index 2f3686242..f245e42f2 100644 --- a/rtgui/whitebalance.cc +++ b/rtgui/whitebalance.cc @@ -396,8 +396,9 @@ WhiteBalance::WhiteBalance () : FoldableToolPanel(this, TOOL_NAME, M("TP_WBALANC itcwb_prim->set_active(1); itcwb_primconn = itcwb_prim->signal_changed().connect(sigc::mem_fun(*this, &WhiteBalance::itcwb_prim_changed)); itcwb_prim ->set_tooltip_markup (M("TP_WBALANCE_ITCWPRIM_TOOLTIP")); - - + + compatVersionAdjuster.reset(new Adjuster("", 0., procparams::WBParams::CURRENT_COMPAT_VERSION, 1., procparams::WBParams::CURRENT_COMPAT_VERSION)); + /* Gtk::Box* boxgreen = Gtk::manage (new Gtk::Box ()); boxgreen->show (); @@ -624,6 +625,7 @@ void WhiteBalance::optChanged () equal->setEditedState (UnEdited); tempBias->setEditedState (UnEdited); observer10->setEdited(false); + compatVersionAdjuster->setEditedState(UnEdited); } else { unsigned int methodId = findWBEntryId (row[methodColumns.colLabel], WBLT_GUI); const WBEntry& currMethod = WBParams::getWbEntries()[methodId]; @@ -723,6 +725,17 @@ void WhiteBalance::optChanged () break; } + + if (compatVersionAdjuster->getIntValue() == 1 && + (!batchMode || currMethod.type != WBEntry::Type::AUTO)) { + // Safe to upgrade version because method changed. In batch + // mode, this method may be called even if there is no change, + // so it's only safe to upgrade if the new method is not auto. + compatVersionAdjuster->setValue(procparams::WBParams::CURRENT_COMPAT_VERSION); + if (batchMode) { + compatVersionAdjuster->setEditedState(Edited); + } + } } if (listener && getEnabled()) { @@ -768,6 +781,7 @@ void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) lastitcwb_alg = pp->wb.itcwb_alg; itcwb_green->setValue (pp->wb.itcwb_green); + compatVersionAdjuster->setValue(pp->wb.compat_version); itcwb_primconn.block (true); @@ -806,6 +820,7 @@ void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) observer10->setEdited(pedited->wb.observer); itcwb_alg->set_inconsistent (!pedited->wb.itcwb_alg); itcwb_green->setEditedState (pedited->wb.itcwb_green ? Edited : UnEdited); + compatVersionAdjuster->setEditedState(pedited->wb.compat_version ? Edited : UnEdited); } if (pedited && !pedited->wb.method) { @@ -961,6 +976,7 @@ void WhiteBalance::write (ProcParams* pp, ParamsEdited* pedited) pedited->wb.enabled = !get_inconsistent(); pedited->wb.itcwb_prim = itcwb_prim->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wb.itcwb_green = itcwb_green->getEditedState (); + pedited->wb.compat_version = compatVersionAdjuster->getEditedState(); } pp->wb.enabled = getEnabled(); @@ -996,6 +1012,7 @@ void WhiteBalance::write (ProcParams* pp, ParamsEdited* pedited) pp->wb.itcwb_alg = itcwb_alg->get_active (); pp->wb.tempBias = tempBias->getValue (); pp->wb.itcwb_green = itcwb_green->getValue (); + pp->wb.compat_version = compatVersionAdjuster->getIntValue(); } void WhiteBalance::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) @@ -1044,6 +1061,7 @@ void WhiteBalance::setBatchMode (bool batchMode) green->showEditedCB (); equal->showEditedCB (); tempBias->showEditedCB (); + compatVersionAdjuster->showEditedCB(); Gtk::TreeModel::Row row = *(refTreeModel->append()); row[methodColumns.colId] = WBParams::getWbEntries().size(); row[methodColumns.colLabel] = M("GENERAL_UNCHANGED"); @@ -1184,10 +1202,10 @@ inline Gtk::TreeRow WhiteBalance::getActiveMethod () return *(method->get_active()); } -void WhiteBalance::WBChanged(int met, double temperature, double greenVal, double rw, double gw, double bw, float temp0, float delta, int bia, int dread, float studgood, float minchrom, int kmin, float histmin, float histmax) +void WhiteBalance::WBChanged(int met, double temperature, double greenVal, double rw, double gw, double bw, float temp0, float delta, int bia, int dread, float studgood, float minchrom, int kmin, float histmin, float histmax, AWBMode aWBMode) { idle_register.add( - [this, met, temperature, greenVal, rw, gw, bw, temp0, delta, bia, dread, studgood, minchrom, kmin, histmin, histmax]() -> bool + [this, met, temperature, greenVal, rw, gw, bw, temp0, delta, bia, dread, studgood, minchrom, kmin, histmin, histmax, aWBMode]() -> bool { disableListener(); temp->setValue(temperature); @@ -1239,7 +1257,22 @@ void WhiteBalance::WBChanged(int met, double temperature, double greenVal, doubl Glib::ustring::format(std::fixed, std::setprecision(0), histmin), Glib::ustring::format(std::fixed, std::setprecision(0), histmax)) ); - + if (aWBMode == AWBMode::TEMP_CORRELATION_RAW) { + itcwb_green->set_sensitive(true); + tempBias->set_sensitive(true); + itcwb_alg->set_sensitive(true); + itcwb_prim->set_sensitive(true); + } else if (aWBMode == AWBMode::RGB_GREY) { + itcwb_green->set_sensitive(false); + tempBias->set_sensitive(true); + itcwb_alg->set_sensitive(false); + itcwb_prim->set_sensitive(false); + } else { + itcwb_green->set_sensitive(false); + tempBias->set_sensitive(false); + itcwb_alg->set_sensitive(false); + itcwb_prim->set_sensitive(false); + } temp->setDefault(temperature); green->setDefault(greenVal); enableListener(); diff --git a/rtgui/whitebalance.h b/rtgui/whitebalance.h index 060026a48..4667a2fdf 100644 --- a/rtgui/whitebalance.h +++ b/rtgui/whitebalance.h @@ -85,6 +85,7 @@ protected: Gtk::CheckButton* itcwb_alg; MyComboBoxText* itcwb_prim; Adjuster* itcwb_green; + std::unique_ptr compatVersionAdjuster; bool lastitcwb_alg; @@ -142,7 +143,7 @@ public: } void setWB (int temp, double green); void resetWB (); - void WBChanged (int met, double temp, double green, double rw, double gw, double bw, float temp0, float delta, int bia, int dread, float studgood, float minchrom, int kmin, float histmin, float histmax) override; + void WBChanged (int met, double temp, double green, double rw, double gw, double bw, float temp0, float delta, int bia, int dread, float studgood, float minchrom, int kmin, float histmin, float histmax, AWBMode aWBMode) override; void itcwb_alg_toggled (); void itcwb_prim_changed (); void setAdjusterBehavior (bool tempadd, bool greenadd, bool equaladd, bool tempbiasadd);