diff --git a/CMakeLists.txt b/CMakeLists.txt index 637cc1b9f..b027ea5f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -392,7 +392,7 @@ if(WITH_PROF) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg") endif() -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wuninitialized -Wno-deprecated-declarations -Wno-unused-result") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wuninitialized -Wcast-qual -Wno-deprecated-declarations -Wno-unused-result") if(OPTION_OMP) find_package(OpenMP) if(OPENMP_FOUND) diff --git a/rtdata/dcpprofiles/camera_model_aliases.json b/rtdata/dcpprofiles/camera_model_aliases.json index 61fc2bf57..32db0db52 100644 --- a/rtdata/dcpprofiles/camera_model_aliases.json +++ b/rtdata/dcpprofiles/camera_model_aliases.json @@ -16,6 +16,8 @@ "Canon EOS 1000D": ["Canon EOS Kiss Digital F", "Canon EOS DIGITAL REBEL XS"], "Canon EOS 1200D": ["Canon EOS Kiss X70", "Canon EOS REBEL T5"], "Canon EOS 1300D": ["Canon EOS Kiss X80", "Canon EOS Rebel T6"], + "Canon EOS 2000D": ["Canon EOS 1500D", "Canon EOS Kiss X90", "Canon EOS Rebel T7"], + "Canon EOS 4000D": ["Canon EOS 3000D", "Canon EOS Rebel T100"], "MINOLTA DYNAX 5D": ["Minolta Maxxum 5D", "Minolta Alpha 5D", "Minolta Alpha Sweet"], "MINOLTA DYNAX 7D": ["Minolta Maxxum 7D", "Minolta Alpha 7D"], diff --git a/rtengine/EdgePreservingDecomposition.cc b/rtengine/EdgePreservingDecomposition.cc index 6bda5d437..85b7ce243 100644 --- a/rtengine/EdgePreservingDecomposition.cc +++ b/rtengine/EdgePreservingDecomposition.cc @@ -401,13 +401,10 @@ bool MultiDiagonalSymmetricMatrix::CreateIncompleteCholeskyFactorization(int Max //How many diagonals in the decomposition? MaxFillAbove++; //Conceptually, now "fill" includes an existing diagonal. Simpler in the math that follows. - int j, mic, fp; - mic = 1; - fp = 1; + int mic = 1; for(int ii = 1; ii < m; ii++) { - fp = rtengine::min(StartRows[ii] - StartRows[ii - 1], MaxFillAbove); //Guaranteed positive since StartRows must be created in increasing order. - mic = mic + fp; + mic += rtengine::min(StartRows[ii] - StartRows[ii - 1], MaxFillAbove); //Guaranteed positive since StartRows must be created in increasing order. } //Initialize the decomposition - setup memory, start rows, etc. @@ -421,7 +418,7 @@ bool MultiDiagonalSymmetricMatrix::CreateIncompleteCholeskyFactorization(int Max for(int ii = 1; ii < m; ii++) { //Set j to the number of diagonals to be created corresponding to a diagonal on this source matrix... - j = rtengine::min(StartRows[ii] - StartRows[ii - 1], MaxFillAbove); + int j = rtengine::min(StartRows[ii] - StartRows[ii - 1], MaxFillAbove); //...and create those diagonals. I want to take a moment to tell you about how much I love minimalistic loops: very much. while(j-- != 0) @@ -491,7 +488,7 @@ bool MultiDiagonalSymmetricMatrix::CreateIncompleteCholeskyFactorization(int Max findmap[j] = FindIndex( icStartRows[j]); } - for(j = 0; j < n; j++) { + for(int j = 0; j < n; j++) { //Calculate d for this column. d[j] = Diagonals[0][j]; @@ -557,12 +554,11 @@ void MultiDiagonalSymmetricMatrix::CholeskyBackSolve(float* RESTRICT x, float* R float* RESTRICT *d = IncompleteCholeskyFactorization->Diagonals; int* RESTRICT s = IncompleteCholeskyFactorization->StartRows; int M = IncompleteCholeskyFactorization->m, N = IncompleteCholeskyFactorization->n; - int i, j; if(M != DIAGONALSP1) { // can happen in theory - for(j = 0; j < N; j++) { + for(int j = 0; j < N; j++) { float sub = b[j]; // using local var to reduce memory writes, gave a big speedup - i = 1; + int i = 1; int c = j - s[i]; while(c >= 0) { @@ -574,9 +570,9 @@ void MultiDiagonalSymmetricMatrix::CholeskyBackSolve(float* RESTRICT x, float* R x[j] = sub; // only one memory-write per j } } else { // that's the case almost every time - for(j = 0; j <= s[M - 1]; j++) { + for(int j = 0; j <= s[M - 1]; j++) { float sub = b[j]; // using local var to reduce memory writes, gave a big speedup - i = 1; + int i = 1; int c = j - s[1]; while(c >= 0) { @@ -588,7 +584,7 @@ void MultiDiagonalSymmetricMatrix::CholeskyBackSolve(float* RESTRICT x, float* R x[j] = sub; // only one memory-write per j } - for(j = s[M - 1] + 1; j < N; j++) { + for(int j = s[M - 1] + 1; j < N; j++) { float sub = b[j]; // using local var to reduce memory writes, gave a big speedup for(int i = DIAGONALSP1 - 1; i > 0; i--) { // using a constant upperbound allows the compiler to unroll this loop (gives a good speedup) @@ -605,14 +601,15 @@ void MultiDiagonalSymmetricMatrix::CholeskyBackSolve(float* RESTRICT x, float* R #pragma omp parallel for #endif - for(j = 0; j < N; j++) { + for(int j = 0; j < N; j++) { x[j] = x[j] / d[0][j]; } if(M != DIAGONALSP1) { // can happen in theory + int j = N; while(j-- > 0) { float sub = x[j]; // using local var to reduce memory writes, gave a big speedup - i = 1; + int i = 1; int c = j + s[1]; while(c < N) { @@ -624,9 +621,9 @@ void MultiDiagonalSymmetricMatrix::CholeskyBackSolve(float* RESTRICT x, float* R x[j] = sub; // only one memory-write per j } } else { // that's the case almost every time - for(j = N - 1; j >= (N - 1) - s[M - 1]; j--) { + for(int j = N - 1; j >= (N - 1) - s[M - 1]; j--) { float sub = x[j]; // using local var to reduce memory writes, gave a big speedup - i = 1; + int i = 1; int c = j + s[1]; while(c < N) { @@ -638,7 +635,7 @@ void MultiDiagonalSymmetricMatrix::CholeskyBackSolve(float* RESTRICT x, float* R x[j] = sub; // only one memory-write per j } - for(j = (N - 2) - s[M - 1]; j >= 0; j--) { + for(int j = (N - 2) - s[M - 1]; j >= 0; j--) { float sub = x[j]; // using local var to reduce memory writes, gave a big speedup for(int i = DIAGONALSP1 - 1; i > 0; i--) { // using a constant upperbound allows the compiler to unroll this loop (gives a good speedup) diff --git a/rtengine/StopWatch.h b/rtengine/StopWatch.h index 9e4400b94..5eb103da4 100644 --- a/rtengine/StopWatch.h +++ b/rtengine/StopWatch.h @@ -18,10 +18,10 @@ * * Author: reine */ +#pragma once -#ifndef STOPWATCH_H -#define STOPWATCH_H #include +#include #include "mytime.h" #ifdef BENCHMARK @@ -36,45 +36,34 @@ class StopWatch { public: - explicit StopWatch( const char* msg, bool microseconds = false ) : microseconds(microseconds) + explicit StopWatch(const char* msg, bool microSeconds = false) : message(msg), unit(microSeconds ? " us" : " ms"), divisor(microSeconds ? 1 : 1000) { - message = msg; start(); stopped = false; } ~StopWatch() { - if(!stopped) { + if (!stopped) { stop(); } } void start() { startTime.set(); - }; + } void stop() { stopTime.set(); - if(!microseconds) { - long elapsedTime = stopTime.etime(startTime) / 1000; - std::cout << message << " took " << elapsedTime << " ms" << std::endl; - } else { - long elapsedTime = stopTime.etime(startTime); - std::cout << message << " took " << elapsedTime << " us" << std::endl; - } + const long elapsedTime = stopTime.etime(startTime) / divisor; + std::cout << message << " took " << elapsedTime << unit << std::endl; stopped = true; } - void stop(const char *msg) - { - message = msg; - stop(); - }; + private: - bool microseconds; MyTime startTime; MyTime stopTime; - const char *message; + const std::string message; + const std::string unit; + const int divisor; bool stopped; }; - -#endif /* STOPWATCH_H */ diff --git a/rtengine/ahd_demosaic_RT.cc b/rtengine/ahd_demosaic_RT.cc index de331fd53..13cbd4d2a 100644 --- a/rtengine/ahd_demosaic_RT.cc +++ b/rtengine/ahd_demosaic_RT.cc @@ -40,7 +40,7 @@ void RawImageSource::ahd_demosaic() { BENCHFUN - constexpr int dir[4] = { -1, 1, -TS, TS }; + constexpr int dirs[4] = { -1, 1, -TS, TS }; float xyz_cam[3][3]; LUTf cbrt(65536); @@ -55,9 +55,10 @@ void RawImageSource::ahd_demosaic() constexpr float d65_white[3] = { 0.950456, 1, 1.088754 }; double progress = 0.0; + if (plistener) { plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), M("TP_RAW_AHD"))); - plistener->setProgress (0.0); + plistener->setProgress (progress); } for (int i = 0; i < 65536; i++) { @@ -65,16 +66,17 @@ void RawImageSource::ahd_demosaic() cbrt[i] = r > 0.008856 ? std::cbrt(r) : 7.787 * r + 16 / 116.0; } - for (int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { for (unsigned int j = 0; j < 3; j++) { xyz_cam[i][j] = 0; for (int k = 0; k < 3; k++) { xyz_cam[i][j] += xyz_rgb[i][k] * imatrices.rgb_cam[k][j] / d65_white[i]; } } - + } border_interpolate2(W, H, 5, rawData, red, green, blue); + #ifdef _OPENMP #pragma omp parallel #endif @@ -153,9 +155,9 @@ void RawImageSource::ahd_demosaic() auto lix = &lab[d][tr][tc]; for (int i = 0; i < 4; i++) { - ldiff[d][i] = std::fabs(lix[0][0] - lix[dir[i]][0]); - abdiff[d][i] = SQR(lix[0][1] - lix[dir[i]][1]) - + SQR(lix[0][2] - lix[dir[i]][2]); + ldiff[d][i] = std::fabs(lix[0][0] - lix[dirs[i]][0]); + abdiff[d][i] = SQR(lix[0][1] - lix[dirs[i]][1]) + + SQR(lix[0][2] - lix[dirs[i]][2]); } } diff --git a/rtengine/amaze_demosaic_RT.cc b/rtengine/amaze_demosaic_RT.cc index ffb68dbdd..47aa45c14 100644 --- a/rtengine/amaze_demosaic_RT.cc +++ b/rtengine/amaze_demosaic_RT.cc @@ -49,11 +49,11 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c stop.reset(new StopWatch("amaze demosaic")); } - volatile double progress = 0.0; + double progress = 0.0; if (plistener) { - plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), M("TP_RAW_AMAZE"))); - plistener->setProgress (0.0); + plistener->setProgressStr(Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), M("TP_RAW_AMAZE"))); + plistener->setProgress(progress); } const int width = winw, height = winh; @@ -768,7 +768,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c //if both agree on interpolation direction, choose the one with strongest directional discrimination; //otherwise, choose the u/d and l/r difference fluctuation weights - if ((0.5 - varwt) * (0.5 - diffwt) > 0 && fabsf(0.5 - diffwt) < fabsf(0.5 - varwt)) { + if ((0.5f - varwt) * (0.5f - diffwt) > 0.f && fabsf(0.5f - diffwt) < fabsf(0.5f - varwt)) { hvwt[indx >> 1] = varwt; } else { hvwt[indx >> 1] = diffwt; @@ -1236,7 +1236,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c //first ask if one gets more directional discrimination from nearby B/R sites float pmwtalt = xdivf(pmwt[(indx - m1) >> 1] + pmwt[(indx + p1) >> 1] + pmwt[(indx - p1) >> 1] + pmwt[(indx + m1) >> 1], 2); - if (fabsf(0.5 - pmwt[indx1]) < fabsf(0.5 - pmwtalt)) { + if (fabsf(0.5f - pmwt[indx1]) < fabsf(0.5f - pmwtalt)) { pmwt[indx1] = pmwtalt; //a better result was obtained from the neighbours } @@ -1304,7 +1304,7 @@ void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh, c for (int cc = 12 + (FC(rr, 2) & 1), indx = rr * ts + cc, indx1 = indx >> 1; cc < cc1 - 12; cc += 2, indx += 2, indx1++) { - if (fabsf(0.5 - pmwt[indx >> 1]) < fabsf(0.5 - hvwt[indx >> 1]) ) { + if (fabsf(0.5f - pmwt[indx >> 1]) < fabsf(0.5f - hvwt[indx >> 1]) ) { continue; } diff --git a/rtengine/array2D.h b/rtengine/array2D.h index 48a789bf8..84728f043 100644 --- a/rtengine/array2D.h +++ b/rtengine/array2D.h @@ -214,6 +214,12 @@ public: return ptr; } + // use as pointer to T** + operator const T* const *() + { + return ptr; + } + // use as pointer to data operator T*() { diff --git a/rtengine/camconst.json b/rtengine/camconst.json index 9551d5e16..4dbfe80f9 100644 --- a/rtengine/camconst.json +++ b/rtengine/camconst.json @@ -48,7 +48,7 @@ Examples: // For new models that are still not supported by the dcraw version used in current RT, we have to fill all the // alternate names or else RT will not recognize the alternate model names. // For models supported by dcraw, filling the alternate names is simply desired (for better user info). - // The format of multiple naming is to write all names in brackets i.e instead of + // The format of multiple naming is to write all names in brackets i.e instead of // "make_model": "Canon EOS 550D", // type // "make_model": [ "Canon EOS 550D", "Canon EOS Rebel T2i", "Canon EOS Kiss X4" ], @@ -115,9 +115,9 @@ How to Measure White Levels: dcraw provides the default values used by RawTherapee, but often provides too high white levels, and only provides a single value regardless of color channel, ISO or aperture. If you open an image with a large clipped area and that is rendered in a pink/magenta color rather than white it usually means that the white level constant is too high. You can - fix this by adjusting the"Raw White Point" in the raw tab inside RawTherapee, or permanently fix it by measuring and + fix this by adjusting white-point correction in the Raw tab > Raw White Points, or permanently fix it by measuring and providing a more exact white level in camconst.json so RawTherapee gets to know from start where the camera actually - clips. Providing a complete and detailed white-level profile can be a quite large and complicated effort. As an + clips. Providing a complete and detailed white-level profile can be a quite large and complicated effort. As an alternative you can provide a simpler profile.We suggest one of the following alternatives in rising difficulty (and generally diminishing return): A) Provide a single white-level value measured on the native ISO (base ISO). For many cameras this will actually be @@ -159,7 +159,7 @@ How to Measure White Levels: histogram. While it's common to with very little variation, say only +/-2 units, some can have +/-500 or more (some may have different variation depending on ISO). There can also be camera-to-camera variation. - If the white level is set too high RawTherapee will not think the pixels are clipped and you can get discoloured + If the white level is set too high RawTherapee will not think the pixels are clipped and you can get discolored highlights (usually pink), this is what we want to avoid. If white level is set too low RawTherapee will clip early, ie you lose a little highlight detail, but the color is rendered correctly and highlight reconstruction can work properly, so this is not as bad. This is why we want conservative values. @@ -167,21 +167,21 @@ How to Measure White Levels: By conservative values we mean that if you see a white level of most often 15760 and occasionally 15759 (i.e. very small variation of white level which is a common case), you set the white level around 50-100 14-bit units below or 10-20 12-bit units. Say at 15700 in this example, or 4080 instead of 4095 for 12-bit raws. This way we get a little margin - from noise and camera variation. Since sensor raw values are linear, you lose, for example, + from noise and camera variation. Since sensor raw values are linear, you lose, for example, log2(1-50/15760) = -0.005 stops of detail, i.e. irrelevant. Thus it is better to provide RawTherapee with knowledge where the image clips rather than keeping that last 0.005 stop of highlight information and risking that clipping will not be detected properly. It is very usual for white level to be a bell distribution instead of a candle when the camera applies long exposure noise reduction (LENR) by subtracting a black frame and/or when the system is destabilized due to temperature. Some models have - always a bell distribution at WL. If you have a fuzzy white level look at the linear histogram; you will probably see a + always a bell distribution at WL. If you have a fuzzy white level look at the linear histogram; you will probably see a normal/Gaussian distribution (bell shape) noise peak at clipping and probably also a peak at a hard raw data clip level usually at or close to a power of two - 1, such as 4095 or 16383. Then you pick a value just before the bell shape rises, i.e. to the left of the bell meaning that you cut away the whole fuzzy noise peak. If a little of the starting edge - of the noise will be included it's not harmful, but 99% of it should be above. This would mean that it's better to + of the noise will be included it's not harmful, but 99% of it should be above. This would mean that it's better to measure white level on long exposure/high temp raws but since this if difficult and time consuming we choose to measure - on normal raws and cover the abnormalities with the conservative WL values. A more detailed approach when we only have - non-LENR measures is to subtract a value according to per ISO read noise. We can find data regarding read noise (stdev + on normal raws and cover the abnormalities with the conservative WL values. A more detailed approach when we only have + non-LENR measures is to subtract a value according to per ISO read noise. We can find data regarding read noise (stdev of Gaussian distribution) at http://www.photonstophotos.net/Charts/RN_ADU.htm . We find the per ISO tead_noise and subtract from the measured value 6*read_noise. This gives confidence that 99.5% of the bell is clipped out. @@ -201,7 +201,7 @@ How to Measure White Levels: need a margin on white_max as it clips there as a result of an in-camera math operation. Note that aperture scaling can be quite small, for the 5D mark II it's only 0.2 stop down to f/1.2 and then it can be - discussed if it's worthwhile to care. The "worst" cameras scale about 0.6 stops though, and then it's more valuable to + discussed if it's worthwhile to care. The "worst" cameras scale about 0.6 stops though, and then it's more valuable to compensate. If you skip aperture scaling RawTherapee will clip the files a little bit too early and you miss that last fraction of highlight detail, but you get no processing problems. Setting un-conservative scale factors can on the other hand cause a too high white level and break highlight processing, so be careful. @@ -209,7 +209,7 @@ How to Measure White Levels: Scaling can vary slightly depending on ISO (if white levels vary) so make sure to provide conservative scalings so regardless of ISO you don't get a too high white level. We recommend to keep a small margin here also white levels, i.e. 0.5% lower or so. For example if base (not conservative!) white level is 15750 and the scaled is 16221 we have a - scaling factor of 16221/15750=1.0299 i.e. +2.9% we set the factor to 1.025 to keep a margin. The abnormal cases are + scaling factor of 16221/15750=1.0299 i.e. +2.9% we set the factor to 1.025 to keep a margin. The abnormal cases are already covered by setting conservative per ISO White levels. The scale factor you provide here is applied on the white level before black level subtraction (if any), i.e. directly on @@ -239,10 +239,10 @@ How to Measure White Levels: You can use RawTherapee for analysis too, it's safer as you are using it's own raw decoder but it's not as user-friendly: enable verbose mode in options so you get output on the console. When you load a file you will see a - message of current black and white levels and if they came from dcraw or camconst.json. If you're adjusting an existing + message of current black and white levels and if they came from dcraw or camconst.json. If you're adjusting an existing camconst.json value you can just read what it is in the file and not need to enable verbose output. - Reset exposure sliders to neutral, and zoom in on a large clipped highlight. Move around the mouse pointer within, it + Reset exposure sliders to neutral, and zoom in on a large clipped highlight. Move around the mouse pointer within, it should show stable 100% on R G B. If so, the white level is not too high, it could however be too low. To test that, go to the raw tab and adjust the "white point linear correction factor", reduce it until one of the channels is no longer 100%, and then increase in steps of 0.01 until all are 100 again. Usually you play around in the range 0.90 to 0.99, i.e. @@ -438,7 +438,7 @@ Camera constants: { "iso": [ 160 ], "levels": 13000 }, // nominal f8-13105 { "iso": [ 320, 640, 1250, 2500 ], "levels": 13300 }, // G1,G2 F4.0-13422-F2.8-13562-13616 { "iso": [ 5000, 10000, 20000 ], "levels": 13200 }, // G1,G2 F4.0-13422-F2.8-13562-13616 - { "iso": [ 400, 500, 800, 1000, 1600, 2000, 3200, 4000 ], "levels": 16100 }, // nominal 16383, + { "iso": [ 400, 500, 800, 1000, 1600, 2000, 3200, 4000 ], "levels": 16100 }, // nominal 16383, { "iso": [ 6400, 8000, 12800, 16000, 25600, 32000 ], "levels": 16000 }, // R,G1,G2 16383, LENR? { "iso": [ 40000, 51200, 102400 ], "levels": 15800 } // 16383, LENR? ], @@ -462,7 +462,7 @@ Camera constants: "make_model": [ "Canon EOS 5DS R", "Canon EOS 5DS" ], //"dcraw_matrix": [ 6848,-1661,-221,-3904,10931,3434,-470,1251,6039 ], // DNG_V9.0 A "dcraw_matrix": [ 6250,-711,-808,-5153,12794,2636,-1249,2198,5610 ], // DNG_V9.0 D65 - "raw_crop": [ 192, 96, 8696, 5800 ], // 800, 300, 7500, 4700 - 160,64,8730x5800 - sensor 8896x5920 top64, left160, official crop left196, top100, right 8883, bottom 5891, 8688X5792 + "raw_crop": [ 192, 96, 8696, 5800 ], // 800, 300, 7500, 4700 - 160,64,8730x5800 - sensor 8896x5920 top64, left160, official crop left196, top100, right 8883, bottom 5891, 8688X5792 "masked_areas": [ 100, 40, 5892, 158 ], // left out 40 first columns from calculations because possibly the BL is still imbalanced there "ranges": { "white": [ @@ -497,7 +497,7 @@ Camera constants: { "iso": [ 160, 320, 640, 1250, 2500 ], "levels": 13100 }, // typical 13225 { "iso": [ 5000, 10000 ], "levels": 13000 }, // typical 13225 { "iso": [ 20000 ], "levels": 12800 }, // typical 13225 - { "iso": [ 51200, 102400 ], "levels": 15900 } // typical 16383 + { "iso": [ 51200, 102400 ], "levels": 15900 } // typical 16383 ], "white_max": 16383, "aperture_scaling": [ @@ -522,7 +522,7 @@ Camera constants: "dcraw_matrix": [ 6875,-970,-932,-4691,12459,2501,-874,1953,5809 ], // DNG v_9.12 D65 "raw_crop": [ 120, 44, 6264, 4180 ], // fullraw size 6384x4224 useful 120,44,6264x4180 // "raw_crop": [ 128, 52, 6248, 4168 ], // official jpeg crop 120+12,44+12,6240x4160 - "masked_areas": [ 44, 4, 4220, 116 ], + "masked_areas": [ 44, 4, 4220, 116 ], "ranges": { "white": [ { "iso": [ 50, 100, 125, 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200 ], "levels": 16300 }, // typical 16383 @@ -532,7 +532,7 @@ Camera constants: { "iso": [ 320, 640, 1250, 2500 ], "levels": 13250 }, // typical 13337 { "iso": [ 5000, 10000 ], "levels": 13100 }, // typical 13367 { "iso": [ 20000, 40000 ], "levels": 12900 }, // typical 13367 - { "iso": [ 51200, 102400 ], "levels": 15900 } // typical 16383 + { "iso": [ 51200, 102400 ], "levels": 15900 } // typical 16383 ], "white_max": 16383, "aperture_scaling": [ @@ -588,8 +588,8 @@ Camera constants: { "iso": [ 100, 125 ], "levels": 13500 }, // typical 13583 - LENR 13550 { "iso": [ 160, 320, 640, 1250, 2500, 5000 ], "levels": 12500 }, // typical 12559 { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000 ], "levels": 15200 }, // typical 15303 - LENR 15270,15260,15240,15220, - { "iso": [ 6400, 8000, 10000, 12800, 16000, 20000, 25600 ], "levels": 15100 }, // typical G1,G2 15303, R,B = 15430 LENR 15200 .. 15100 - { "iso": 51200, "levels": 16300 } // typical 16383 red 16371 + { "iso": [ 6400, 8000, 10000, 12800, 16000, 20000, 25600 ], "levels": 15100 }, // typical G1,G2 15303, R,B = 15430 LENR 15200 .. 15100 + { "iso": 51200, "levels": 16300 } // typical 16383 red 16371 ], "white_max": 16383, "aperture_scaling": [ @@ -620,7 +620,7 @@ Camera constants: { "iso": [ 200, 400 ], "levels": 16100 }, // typical 16224 { "iso": 800, "levels": 15900 }, // gaussian histogram 15900-16224 { "iso": 1600, "levels": 14900 }, // gaussian histogram 14900-15750 - { "iso": 1250, "levels": 11900 } // gaussian histogram 11900-12500 + { "iso": 1250, "levels": 11900 } // gaussian histogram 11900-12500 ], "white_max": 16383, "aperture_scaling": [ @@ -1082,9 +1082,9 @@ Camera constants: "masked_areas": [ 40, 16, 4000, 54 ], "ranges": { "white": [ - { "iso": [ 100, 125, 160 ], "levels": 16300 }, // 16383 - { "iso": [ 320, 640, 1250, 2500, 5000, 10000 ], "levels": 12600 }, // 12632..14500 - { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000 ], "levels": 15000 }, // 15095, 15488 + { "iso": [ 100, 125, 160 ], "levels": 16300 }, // 16383 + { "iso": [ 320, 640, 1250, 2500, 5000, 10000 ], "levels": 12600 }, // 12632..14500 + { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000 ], "levels": 15000 }, // 15095, 15488 { "iso": [ 6400, 8000, 12800, 25600 ], "levels": 16200 } // 16383 ], "white_max": 16383, @@ -1104,10 +1104,10 @@ Camera constants: }, { // Quality C, White Levels not properly indicated, aperture scaling..missing factors are guessed - "make_model": [ "Canon EOS M5","Canon EOS M6" ], + "make_model": [ "Canon EOS M5","Canon EOS M6" ], "dcraw_matrix": [ 8532,-701,-1167,-4095,11879,2508,-797,2424,7010 ], // DNG_V9.8 D65 "raw_crop": [ 264, 36, 6024, 4020 ], // full size 6288x4056, - //"raw_crop": [ 272, 44, 6008, 4008 ], // matched to official crop 276,48,6275,4047 - official jpeg 6000X4000 + //"raw_crop": [ 272, 44, 6008, 4008 ], // matched to official crop 276,48,6275,4047 - official jpeg 6000X4000 "masked_areas": [ 40, 96, 4000, 260 ], "ranges": { "white": [ @@ -1116,9 +1116,9 @@ Camera constants: { "iso": [ 320 ], "levels": 13100 }, // nominal green 13200, 13528-14466-14380-14368 - blue13262-14186, { "iso": [ 640, 1250 ], "levels": 13200 }, // iso 640 G1,G2 13260-13450 - blue13230-13430 -iso 1250 13430 { "iso": [ 2500, 5000, 10000 ], "levels": 13000 }, // - { "iso": [ 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 6400 ], "levels": 16100 }, // 16383 - // { "iso": [ 1600 ], "levels": 15000 }, // one sample of m6 = 15100 !! - // { "iso": [ 6400 ], "levels": 15500 }, // one sample of m6 = 15600 !! + { "iso": [ 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 6400 ], "levels": 16100 }, // 16383 + // { "iso": [ 1600 ], "levels": 15000 }, // one sample of m6 = 15100 !! + // { "iso": [ 6400 ], "levels": 15500 }, // one sample of m6 = 15600 !! { "iso": [ 8000, 12800, 16000, 25600 ], "levels": 16000 } // R,G1,G2 16383, B 16243 ], "white_max": 16383, @@ -1176,7 +1176,7 @@ Camera constants: "dcraw_matrix": [ 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 ], // D65 matrix from adobe dcp //"raw_crop": [ 80, 50, 4400, 3316 ], // full frame 4480x3366 borders 80,50 - much shade in corners, no/wrong auto distortion //"raw_crop": [ 104, 144, 4360, 3128 ], // Mixed best average frame, width is 4352 from 3/2, height 3120 from 4/3 - auto distortion does not work correctly - //"raw_crop": [ 200, 144, 4168, 3128 ], // Optional official 4/3 frame 4160x3120, 4pix borders, Left Border 204-4, Top Border 148-4 + //"raw_crop": [ 200, 144, 4168, 3128 ], // Optional official 4/3 frame 4160x3120, 4pix borders, Left Border 204-4, Top Border 148-4 "raw_crop": [ 104, 252, 4360, 2912 ], // Default official 3/2 frame 4352x2904, 4pix borders, Left Border 108-4, Top border 256-4 "masked_areas": [ 148, 2, 3340, 78 ], "ranges": { "white": 16300 } @@ -1346,8 +1346,8 @@ Camera constants: { // Quality C, only raw crop "make_model": [ "FUJIFILM X-T3", "FUJIFILM X-T30" ], "raw_crop": [ 0, 5, 6252, 4176] - }, - + }, + { // Quality B "make_model": "FUJIFILM X30", "dcraw_matrix": [ 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 ], // DNG_v8.7 D65 @@ -1622,14 +1622,14 @@ Camera constants: "ranges": { "white": 3980 } // 12-bit files. }, - { // Quality C, only colour matrix and PDAF lines info + { // Quality C, only color matrix and PDAF lines info "make_model" : "Nikon Z 7", "dcraw_matrix" : [10405,-3755,-1270,-5461,13787,1793,-1040,2015,6785], // Adobe DNG Converter 11.0 ColorMatrix2 "pdaf_pattern" : [0, 12], "pdaf_offset" : 29 }, - { // Quality C, only colour matrix and PDAF lines info + { // Quality C, only color matrix and PDAF lines info "make_model" : "Nikon Z 6", "dcraw_matrix" : [8210, -2534, -683, -5355, 13338, 2212, -1143, 1929, 6464], // Adobe DNG Converter 11.1 Beta ColorMatrix2 "pdaf_pattern" : [0, 12], @@ -1725,9 +1725,15 @@ Camera constants: { // Quality B, "make_model": "OLYMPUS TG-5", "dcraw_matrix": [ 10899,-3833,-1082,-2112,10736,1575,-267,1452,5269 ], // DNG_V9.12 D65 + "raw_crop": [ 0, 0, -18, 0 ], // 18 pixels at right are garbage "ranges": { "white": 4050 } // safe for worst case detected, nominal is 4093 }, + { // Quality C, only raw crop + "make_model": "OLYMPUS TG-6", + "raw_crop": [ 0, 0, -24, 0 ] // 24 pixels at right are garbage + }, + { // Quality C, only green equilibration "make_model" : ["OLYMPUS E-3", "OLYMPUS E-520"], "global_green_equilibration" : true @@ -1753,6 +1759,15 @@ Camera constants: } }, + { // Quality C, only color matrix + "make_model" : "Panasonic DC-GF10", + "dcraw_matrix": [ 7610, -2780, -576, -4614, 12195, 2733, -1375, 2393, 6490 ], // ColorMatrix2 from Adobe DNG Converter 11.3 + "raw_crop": [ 0, 0, 4600, 0 ], // SensorWidth=4816 SensorHeight=3464. Width=4600 to match DNG. + "ranges": { + "black": 15 + } + }, + { // Quality B, CameraPhone, some samples are missing but has the same sensor as FZ1000 .. "make_model": [ "Panasonic DMC-CM1", "Panasonic DMC-CM10" ], "dcraw_matrix": [ 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 ], // dcp_v8.7 d65 @@ -1800,7 +1815,7 @@ Camera constants: { // Quality B, "make_model": [ "Panasonic DMC-FZ2500", "Panasonic DMC-FZ2000", "Panasonic DMC-FZH1" ], - "dcraw_matrix": [ 7386,-2443,-743,-3437,11864,1757,-608,1660,4766 ], // dcp_v9.8 d65 + "dcraw_matrix": [ 7386,-2443,-743,-3437,11864,1757,-608,1660,4766 ], // dcp_v9.8 d65 "ranges": { "black": 15, // 15 is BL offset. dcraw/RT read the base BL from Exif and calculates total BL = BLbase+BLoffset "white": [ @@ -1891,7 +1906,8 @@ Camera constants: "dcraw_matrix": [ 7122,-2092,-419,-4643,11769,3283,-1363,2413,5944 ], // RT "ranges": { "black": 15, // 15 is BL offset. dcraw/RT read the base black from Exif and calculates total BL = BLbase+BLoffset - "white": 4060 } // Exif:4095 normal distribution 4080-4095, 4070-4095 on long exposure NR + "white": 4060 // Exif:4095 normal distribution 4080-4095, 4070-4095 on long exposure NR + } }, { // Quality A, Replicated from rawimage.cc @@ -1911,7 +1927,8 @@ Camera constants: "dcraw_matrix": [ 7694,-1791,-745,-4917,12818,2332,-1221,2322,7197 ], // Colin Walker "ranges": { "black": 15, // 15 is BL offset. dcraw/RT read the base black from Exif and calculates total BL = BLbase+BLoffset - "white": 4050 } // Exif:4095 normal distribution 4080-4095, 4050-4095 on long exposure NR + "white": 4050 // Exif:4095 normal distribution 4080-4095, 4050-4095 on long exposure NR + } }, { // Quality A, Replicated from rawimage.cc @@ -1919,7 +1936,8 @@ Camera constants: "dcraw_matrix": [ 8074,-1846,-861,-5026,12999,2239,-1320,2375,7422 ], // Colin Walker "ranges": { "black": 15, // 15 is BL offset. dcraw/RT read the base black from Exif and calculates total BL = BLbase+BLoffset - "white": 4050 } // Exif:4095 normal distribution 4080-4095, 4050-4095 on long exposure NR + "white": 4050 // Exif:4095 normal distribution 4080-4095, 4050-4095 on long exposure NR + } }, { // Quality A, Replicated from rawimage.cc @@ -2232,7 +2250,7 @@ Camera constants: } }, - { // Quality B, corrections for raw crop vs dcraw9.21, matched to Samsung's default + { // Quality B, corrections for raw crop vs dcraw9.21, matched to Samsung's default "make_model": "Samsung NX mini", "dcraw_matrix": [ 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 ], // dng 8.6 d65 "raw_crop": [ 128, 36, 5480, 3656 ], // jpeg 5472x3648 - full raw: 5664 x 3710 - Samsung's official crop: 132, 40, 5604, 3688 @@ -2255,8 +2273,8 @@ Camera constants: { "iso": 100, "levels": 16000 }, // 16000 typical 16084, LE 16120 and 16383, LENR 16280 { "iso": [ 200, 400, 800, 1600, 3200, 6400, 12800 ], "levels": 16300 }, // 16383 { "iso": [ 25600, 51200 ], "levels": 16300 } // 16383 - ] - } + ] + } }, { // Quality C, corrections for frame size, black and white levels not declared properly @@ -2295,7 +2313,7 @@ Camera constants: //"dcraw_matrix": [ 5666,139,-892,3780,5428,270,1366,9757,4526 ], // experimental inverted icc sunny8161 //"dcraw_matrix": [ 10288,-2449,-1718,8976,1868,-1608,7011,5039,-249 ], // experimental inverted icc tungsten8130 wp11 //"dcraw_matrix": [ 5864,679,-1491,2963,7635,-919,-640,13738,2790 ], // experimental inverted icc sunny8160 - //"dcraw_matrix": [ 14032,-2231,-1016,-5263,14816,170,-112,183,9113 ], // hardcoded + //"dcraw_matrix": [ 14032,-2231,-1016,-5263,14816,170,-112,183,9113 ], // hardcoded "ranges": { "black": 16, "white": 4070 }, // BL is 16 or 31, should be measured at the horizontal black stripe at the top "raw_crop": [ 12, 52, -110, -8 ] // for small size all numbers/2 }, @@ -2379,7 +2397,7 @@ Camera constants: "ranges": { "black": 512, "white": 16300 }, // contributed by Horshak from https://www.dpreview.com/forums/post/60873077 "pdaf_pattern" : [ 0,12,36,54,72,90,114,126,144,162,180,204,216,240,252,270,294,306,324,342,366,384,396,414,432,450,474,492,504,522,540,564,576,594,606,630 ], - "pdaf_offset" : 3 + "pdaf_offset" : 3 }, { // Quality A, correction for frame width @@ -2414,8 +2432,8 @@ Camera constants: { // Quality C, color matrix copied from ILCE-9, LongExposures 2-3sec only "make_model": "Sony ILCE-7M3", "dcraw_matrix": [ 6389,-1703,-378,-4562,12265,2587,-670,1489,6550 ], // ILCE-9, DNG_v9.12 D65 - // "raw_crop": [ 8, 8, 6008, 4008 ], // full raw frame 6048x4024 Dcraw auto identify 6024x4024, jpeg 12,12,6000x4000 - // "ranges": { "black": 512, "white": 16300 } + // "raw_crop": [ 8, 8, 6008, 4008 ], // full raw frame 6048x4024 Dcraw auto identify 6024x4024, jpeg 12,12,6000x4000 + // "ranges": { "black": 512, "white": 16300 } "ranges": { "black": 512, "white": [ diff --git a/rtengine/cfa_linedn_RT.cc b/rtengine/cfa_linedn_RT.cc index b5d171034..a7b789caf 100644 --- a/rtengine/cfa_linedn_RT.cc +++ b/rtengine/cfa_linedn_RT.cc @@ -54,15 +54,15 @@ void RawImageSource::CLASS cfa_linedn(float noise, bool horizontal, bool vertica // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + double progress = 0.0; if (plistener) { - plistener->setProgressStr ("PROGRESSBAR_LINEDENOISE"); - plistener->setProgress (0.0); + plistener->setProgressStr("PROGRESSBAR_LINEDENOISE"); + plistener->setProgress(progress); } // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% float noisevar = SQR(3 * noise * 65535); // _noise_ (as a fraction of saturation) is input to the algorithm float noisevarm4 = 4.0f * noisevar; - volatile double progress = 0.0; float* RawDataTmp = (float*)malloc( width * height * sizeof(float)); #ifdef _OPENMP #pragma omp parallel diff --git a/rtengine/color.cc b/rtengine/color.cc index 3f2a75788..7c12c0ca5 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -2016,45 +2016,6 @@ void Color::Lch2Luv(float c, float h, float &u, float &v) v = c * sincosval.y; } -// NOT TESTED -void Color::XYZ2Luv (float X, float Y, float Z, float &L, float &u, float &v) -{ - - X /= 65535.f; - Y /= 65535.f; - Z /= 65535.f; - - if (Y > float(eps)) { - L = 116.f * std::cbrt(Y) - 16.f; - } else { - L = float(kappa) * Y; - } - - u = 13.f * L * float(u0); - v = 13.f * L * float(v0); -} - -// NOT TESTED -void Color::Luv2XYZ (float L, float u, float v, float &X, float &Y, float &Z) -{ - if (L > float(epskap)) { - float t = (L + 16.f) / 116.f; - Y = t * t * t; - } else { - Y = L / float(kappa); - } - - float a = ((52.f * L) / (u + 13.f * L * float(u0)) - 1.f) / 3.f; - float d = Y * (((39 * L) / (v + 13 * float(v0))) - 5.f); - float b = -5.f * Y; - X = (d - b) / (a + 1.f / 3.f); - - Z = X * a + b; - - X *= 65535.f; - Y *= 65535.f; - Z *= 65535.f; -} /* * Gamut mapping algorithm diff --git a/rtengine/color.h b/rtengine/color.h index fb4eea458..5bf178636 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -240,20 +240,20 @@ public: static inline void rgb2slfloat(float r, float g, float b, float &s, float &l) { - float m = min(r, g, b); - float M = max(r, g, b); - float C = M - m; + float minVal = min(r, g, b); + float maxVal = max(r, g, b); + float C = maxVal - minVal; - l = (M + m) * 7.6295109e-6f; // (0.5f / 65535.f) + l = (maxVal + minVal) * 7.6295109e-6f; // (0.5f / 65535.f) if (C < 0.65535f) { // 0.00001f * 65535.f s = 0.f; } else { if (l <= 0.5f) { - s = C / (M + m); + s = C / (maxVal + minVal); } else { - s = C / (131070.f - (M + m)); // 131070.f = 2.f * 65535.f + s = C / (131070.f - (maxVal + minVal)); // 131070.f = 2.f * 65535.f } } } @@ -261,11 +261,11 @@ public: static inline void rgb2hslfloat(float r, float g, float b, float &h, float &s, float &l) { - float m = min(r, g, b); - float M = max(r, g, b); - float C = M - m; + float minVal = min(r, g, b); + float maxVal = max(r, g, b); + float C = maxVal - minVal; - l = (M + m) * 7.6295109e-6f; // (0.5f / 65535.f) + l = (maxVal + minVal) * 7.6295109e-6f; // (0.5f / 65535.f) if (C < 0.65535f) { // 0.00001f * 65535.f h = 0.f; @@ -273,14 +273,14 @@ public: } else { if (l <= 0.5f) { - s = C / (M + m); + s = C / (maxVal + minVal); } else { - s = C / (131070.f - (M + m)); // 131070.f = 2.f * 65535.f + s = C / (131070.f - (maxVal + minVal)); // 131070.f = 2.f * 65535.f } - if ( r == M ) { + if ( r == maxVal ) { h = (g - b); - } else if ( g == M ) { + } else if ( g == maxVal ) { h = (2.f * C) + (b - r); } else { h = (4.f * C) + (r - g); @@ -686,32 +686,6 @@ public: static void Lch2Luv(float c, float h, float &u, float &v); - /** - * @brief Convert the XYZ values to Luv values - * Warning: this method has never been used/tested so far - * @param x X coordinate [0 ; 65535] ; can be negative or superior to 65535 - * @param y Y coordinate [0 ; 65535] ; can be negative or superior to 65535 - * @param z Z coordinate [0 ; 65535] ; can be negative or superior to 65535 - * @param L 'L' channel [0 ; 32768] (return value) - * @param u 'u' channel [-42000 ; 42000] ; can be more than 42000 (return value) - * @param v 'v' channel [-42000 ; 42000] ; can be more than 42000 (return value) - */ - static void XYZ2Luv (float X, float Y, float Z, float &L, float &u, float &v); - - - /** - * @brief Convert the Luv values to XYZ values - * Warning: this method has never been used/tested so far - * @param L 'L' channel [0 ; 32768] - * @param u 'u' channel [-42000 ; 42000] ; can be more than 42000 - * @param v 'v' channel [-42000 ; 42000] ; can be more than 42000 - * @param x X coordinate [0 ; 65535] ; can be negative or superior to 65535 (return value) - * @param y Y coordinate [0 ; 65535] ; can be negative or superior to 65535 (return value) - * @param z Z coordinate [0 ; 65535] ; can be negative or superior to 65535 (return value) - */ - static void Luv2XYZ (float L, float u, float v, float &X, float &Y, float &Z); - - /** * @brief Return "f" in function of CIE's kappa and epsilon constants * @param f f can be fx fy fz where: diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc index a7a769d93..a22caddb8 100644 --- a/rtengine/colortemp.cc +++ b/rtengine/colortemp.cc @@ -1088,11 +1088,11 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, //}; gmul /= green; //printf("rmul=%f gmul=%f bmul=%f\n",rmul, gmul, bmul); - double max = rtengine::max(rmul, gmul, bmul); + double maxRGB = rtengine::max(rmul, gmul, bmul); - rmul /= max; - gmul /= max; - bmul /= max; + rmul /= maxRGB; + gmul /= maxRGB; + bmul /= maxRGB; if(settings->CRI_color != 0) { //activate if CRi_color !=0 @@ -1104,7 +1104,6 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, // and calcul with : blackbody at equivalent temp of lamp // CRI_color-1 = display Lab values of color CRI_color -1 const double whiteD50[3] = {0.9646019585, 1.0, 0.8244507152}; //calculate with this tool : spect 5nm - double CAM02BB00, CAM02BB01, CAM02BB02, CAM02BB10, CAM02BB11, CAM02BB12, CAM02BB20, CAM02BB21, CAM02BB22; //for CIECAT02 double Xchk[50], Ychk[50], Zchk[50]; //50 : I think it's a good limit for number of color : for CRI and Palette double Xcam02[50], Ycam02[50], Zcam02[50]; @@ -1113,9 +1112,6 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, const double epsilon = 0.008856; //Lab double xr[50], yr[50], zr[50]; - double fx[50], fy[50], fz[50]; - double x, y, z; - double Ywb = 1.0; int illum; int numero_color = settings->CRI_color - 1; @@ -1223,6 +1219,9 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, } if (CRI_type) { + double x, y, z; + double Ywb = 1.0; + const double* spect_illum[] = { Daylight5300_spect, Cloudy6200_spect, Shade7600_spect, A2856_spect, FluoF1_spect, FluoF2_spect, FluoF3_spect, FluoF4_spect, FluoF5_spect, FluoF6_spect, FluoF7_spect, FluoF8_spect, FluoF9_spect, FluoF10_spect, FluoF11_spect, @@ -1281,6 +1280,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, //calculate Matrix CAM02 : better than Von Kries and Bradford==> for Lamp double adap = 1.0; + double CAM02BB00, CAM02BB01, CAM02BB02, CAM02BB10, CAM02BB11, CAM02BB12, CAM02BB20, CAM02BB21, CAM02BB22; //for CIECAT02 cieCAT02(Xwb, Ywb, Zwb, CAM02BB00, CAM02BB01, CAM02BB02, CAM02BB10, CAM02BB11, CAM02BB12, CAM02BB20, CAM02BB21, CAM02BB22, adap); //here new value of X,Y,Z for lamp with chromatic CAM02 adaptation @@ -1306,6 +1306,7 @@ void ColorTemp::temp2mul (double temp, double green, double equal, double& rmul, //now conversion to Lab // Lamp + double fx[50], fy[50], fz[50]; for(int i = 0; i < N_c; i++) { xr[i] = Xcam02Lamp[i] / whiteD50[0]; diff --git a/rtengine/cplx_wavelet_dec.h b/rtengine/cplx_wavelet_dec.h index ccecef819..fab6119d9 100644 --- a/rtengine/cplx_wavelet_dec.h +++ b/rtengine/cplx_wavelet_dec.h @@ -45,7 +45,6 @@ private: static const int maxlevels = 10;//should be greater than any conceivable order of decimation int lvltot, subsamp; - int numThreads; int m_w, m_h;//dimensions int wavfilt_len, wavfilt_offset; @@ -97,7 +96,7 @@ public: template wavelet_decomposition::wavelet_decomposition(E * src, int width, int height, int maxlvl, int subsampling, int skipcrop, int numThreads, int Daub4Len) - : coeff0(nullptr), memoryAllocationFailed(false), lvltot(0), subsamp(subsampling), numThreads(numThreads), m_w(width), m_h(height) + : coeff0(nullptr), memoryAllocationFailed(false), lvltot(0), subsamp(subsampling), m_w(width), m_h(height) { //initialize wavelet filters diff --git a/rtengine/curves.cc b/rtengine/curves.cc index f03a43e60..ef2a5bf92 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -641,15 +641,15 @@ void CurveFactory::complexCurve (double ecomp, double black, double hlcompr, dou } // gamma correction - float val = Color::gammatab_srgb1[0]; + float val0 = Color::gammatab_srgb1[0]; // apply brightness curve if (brightcurve) { - val = brightcurve->getVal(val); // TODO: getVal(double) is very slow! Optimize with a LUTf + val0 = brightcurve->getVal(val0); // TODO: getVal(double) is very slow! Optimize with a LUTf } // store result in a temporary array - dcurve[0] = LIM01(val); + dcurve[0] = LIM01(val0); for (int i = 1; i < 0x10000; i++) { @@ -1508,10 +1508,10 @@ void ColorGradientCurve::SetXYZ(const Curve *pCurve, const double xyz_rgb[3][3], Color::gamutLchonly(h1, Lr, c1, RR, GG, BB, xyz_rgb, false, 0.15f, 0.96f); #endif L1 = Lr * 327.68f; - float a, b, X, Y, Z; + float La, Lb, X, Y, Z; // converting back to rgb - Color::Lch2Lab(c1, h1, a, b); - Color::Lab2XYZ(L1, a, b, X, Y, Z); + Color::Lch2Lab(c1, h1, La, Lb); + Color::Lab2XYZ(L1, La, Lb, X, Y, Z); lut1[i] = X; lut2[i] = Y; lut3[i] = Z; @@ -1822,12 +1822,12 @@ float PerceptualToneCurve::calculateToneCurveContrastValue() const { // look at midtone slope const float xd = 0.07; - const float tx[] = { 0.30, 0.35, 0.40, 0.45 }; // we only look in the midtone range + const float tx0[] = { 0.30, 0.35, 0.40, 0.45 }; // we only look in the midtone range - for (size_t i = 0; i < sizeof(tx) / sizeof(tx[0]); i++) { - float x0 = tx[i] - xd; + for (size_t i = 0; i < sizeof(tx0) / sizeof(tx0[0]); i++) { + float x0 = tx0[i] - xd; float y0 = CurveFactory::gamma2(lutToneCurve[CurveFactory::igamma2(x0) * 65535.f] / 65535.f) - k * x0; - float x1 = tx[i] + xd; + float x1 = tx0[i] + xd; float y1 = CurveFactory::gamma2(lutToneCurve[CurveFactory::igamma2(x1) * 65535.f] / 65535.f) - k * x1; float slope = 1.0 + (y1 - y0) / (x1 - x0); @@ -1967,15 +1967,15 @@ void PerceptualToneCurve::BatchApply(const size_t start, const size_t end, float saturated_scale_factor = 1.f; } else if (C < hilim) { // S-curve transition between low and high limit - float x = (C - lolim) / (hilim - lolim); // x = [0..1], 0 at lolim, 1 at hilim + float cx = (C - lolim) / (hilim - lolim); // x = [0..1], 0 at lolim, 1 at hilim - if (x < 0.5f) { - x = 2.f * SQR(x); + if (cx < 0.5f) { + cx = 2.f * SQR(cx); } else { - x = 1.f - 2.f * SQR(1 - x); + cx = 1.f - 2.f * SQR(1.f - cx); } - saturated_scale_factor = (1.f - x) + saturated_scale_factor * x; + saturated_scale_factor = (1.f - cx) + saturated_scale_factor * cx; } else { // do nothing, high saturation color, keep scale factor } @@ -1995,15 +1995,15 @@ void PerceptualToneCurve::BatchApply(const size_t start, const size_t end, float // do nothing, keep scale factor } else if (nL < hilim) { // S-curve transition - float x = (nL - lolim) / (hilim - lolim); // x = [0..1], 0 at lolim, 1 at hilim + float cx = (nL - lolim) / (hilim - lolim); // x = [0..1], 0 at lolim, 1 at hilim - if (x < 0.5f) { - x = 2.f * SQR(x); + if (cx < 0.5f) { + cx = 2.f * SQR(cx); } else { - x = 1.f - 2.f * SQR(1 - x); + cx = 1.f - 2.f * SQR(1 - cx); } - dark_scale_factor = dark_scale_factor * (1.0f - x) + x; + dark_scale_factor = dark_scale_factor * (1.0f - cx) + cx; } else { dark_scale_factor = 1.f; } @@ -2021,15 +2021,15 @@ void PerceptualToneCurve::BatchApply(const size_t start, const size_t end, float // do nothing, keep scale factor } else if (J < hilim) { // S-curve transition - float x = (J - lolim) / (hilim - lolim); + float cx = (J - lolim) / (hilim - lolim); - if (x < 0.5f) { - x = 2.f * SQR(x); + if (cx < 0.5f) { + cx = 2.f * SQR(cx); } else { - x = 1.f - 2.f * SQR(1 - x); + cx = 1.f - 2.f * SQR(1 - cx); } - dark_scale_factor = dark_scale_factor * (1.f - x) + x; + dark_scale_factor = dark_scale_factor * (1.f - cx) + cx; } else { dark_scale_factor = 1.f; } @@ -2089,15 +2089,15 @@ void PerceptualToneCurve::BatchApply(const size_t start, const size_t end, float keep = 1.f; } else if (sat_scale < hilim) { // S-curve transition - float x = (sat_scale - lolim) / (hilim - lolim); // x = [0..1], 0 at lolim, 1 at hilim + float cx = (sat_scale - lolim) / (hilim - lolim); // x = [0..1], 0 at lolim, 1 at hilim - if (x < 0.5f) { - x = 2.f * SQR(x); + if (cx < 0.5f) { + cx = 2.f * SQR(cx); } else { - x = 1.f - 2.f * SQR(1 - x); + cx = 1.f - 2.f * SQR(1 - cx); } - keep = (1.f - x) + keep * x; + keep = (1.f - cx) + keep * cx; } else { // do nothing, very high increase, keep minimum amount } diff --git a/rtengine/curves.h b/rtengine/curves.h index deed5d0fe..55068630a 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -31,7 +31,7 @@ #include "../rtgui/mydiagonalcurve.h" #include "color.h" #include "pipettebuffer.h" - +#include "noncopyable.h" #include "LUT.h" #define CURVES_MIN_POLY_POINTS 1000 @@ -468,7 +468,7 @@ protected: void NURBS_set (); public: - DiagonalCurve (const std::vector& points, int ppn = CURVES_MIN_POLY_POINTS); + explicit DiagonalCurve (const std::vector& points, int ppn = CURVES_MIN_POLY_POINTS); ~DiagonalCurve () override; double getVal (double t) const override; @@ -479,7 +479,7 @@ public: }; }; -class FlatCurve : public Curve +class FlatCurve : public Curve, public rtengine::NonCopyable { private: @@ -493,7 +493,7 @@ private: public: - FlatCurve (const std::vector& points, bool isPeriodic = true, int ppn = CURVES_MIN_POLY_POINTS); + explicit FlatCurve (const std::vector& points, bool isPeriodic = true, int ppn = CURVES_MIN_POLY_POINTS); ~FlatCurve () override; double getVal (double t) const override; diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc index 56855b604..6c948717a 100644 --- a/rtengine/dcp.cc +++ b/rtengine/dcp.cc @@ -334,8 +334,6 @@ double xyCoordToTemperature(const std::array& white_xy) // Search for line pair coordinate is between. double last_dt = 0.0; - double last_dv = 0.0; - double last_du = 0.0; for (uint32_t index = 1; index <= 30; ++index) { // Convert slope to delta-u and delta-v, with length 1. @@ -371,23 +369,11 @@ double xyCoordToTemperature(const std::array& white_xy) // Interpolate the temperature. res = 1.0e6 / (temp_table[index - 1].r * f + temp_table[index].r * (1.0 - f)); - - // Find delta from black body point to test coordinate. - uu = u - (temp_table [index - 1].u * f + temp_table [index].u * (1.0 - f)); - vv = v - (temp_table [index - 1].v * f + temp_table [index].v * (1.0 - f)); - // Interpolate vectors along slope. - du = du * (1.0 - f) + last_du * f; - dv = dv * (1.0 - f) + last_dv * f; - len = sqrt (du * du + dv * dv); - du /= len; - dv /= len; break; } // Try next line pair. last_dt = dt; - last_du = du; - last_dv = dv; } return res; diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc index 280b692e7..a4450a69a 100644 --- a/rtengine/dcraw.cc +++ b/rtengine/dcraw.cc @@ -240,7 +240,7 @@ int CLASS fcol (int row, int col) #ifndef __GLIBC__ char *my_memmem (char *haystack, size_t haystacklen, - char *needle, size_t needlelen) + const char *needle, size_t needlelen) { char *c; for (c = haystack; c <= haystack + haystacklen - needlelen; c++) @@ -9233,8 +9233,8 @@ void CLASS identify() fseek (ifp, 0, SEEK_SET); fread (head, 1, 32, ifp); /* RT: changed string constant */ - if ((cp = (char *) memmem (head, 32, (char*)"MMMM", 4)) || - (cp = (char *) memmem (head, 32, (char*)"IIII", 4))) { + if ((cp = (char *) memmem (head, 32, "MMMM", 4)) || + (cp = (char *) memmem (head, 32, "IIII", 4))) { parse_phase_one (cp-head); if (cp-head && parse_tiff(0)) apply_tiff(); } else if (order == 0x4949 || order == 0x4d4d) { diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 23b9034ec..fc6e838d4 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -205,10 +205,8 @@ void Crop::update(int todo) } int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; - int kall = 2; - parent->ipf.Tile_calc(tilesize, overlap, kall, widIm, heiIm, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); - kall = 0; + parent->ipf.Tile_calc(tilesize, overlap, 2, widIm, heiIm, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); float *min_b = new float [9]; float *min_r = new float [9]; @@ -654,10 +652,9 @@ void Crop::update(int todo) if (todo & M_LINDENOISE) { if (skip == 1 && denoiseParams.enabled) { - int kall = 0; float nresi, highresi; - parent->ipf.RGB_denoise(kall, origCrop, origCrop, calclum, parent->denoiseInfoStore.ch_M, parent->denoiseInfoStore.max_r, parent->denoiseInfoStore.max_b, parent->imgsrc->isRAW(), /*Roffset,*/ denoiseParams, parent->imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, noiseCCurve, nresi, highresi); + parent->ipf.RGB_denoise(0, origCrop, origCrop, calclum, parent->denoiseInfoStore.ch_M, parent->denoiseInfoStore.max_r, parent->denoiseInfoStore.max_b, parent->imgsrc->isRAW(), /*Roffset,*/ denoiseParams, parent->imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, noiseCCurve, nresi, highresi); if (parent->adnListener) { parent->adnListener->noiseChanged(nresi, highresi); @@ -888,9 +885,6 @@ void Crop::update(int todo) if (skip == 1) { if ((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { parent->ipf.impulsedenoise(labnCrop); - } - - if ((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { parent->ipf.defringe(labnCrop); } @@ -903,7 +897,6 @@ void Crop::update(int todo) } // if (skip==1) { - WaveletParams WaveParams = params.wavelet; if (params.dirpyrequalizer.cbdlMethod == "aft") { if (((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled))) { @@ -912,81 +905,81 @@ void Crop::update(int todo) } } - int kall = 0; - int minwin = min(labnCrop->W, labnCrop->H); - int maxlevelcrop = 10; - - // if(cp.mul[9]!=0)maxlevelcrop=10; - // adap maximum level wavelet to size of crop - if (minwin * skip < 1024) { - maxlevelcrop = 9; //sampling wavelet 512 - } - - if (minwin * skip < 512) { - maxlevelcrop = 8; //sampling wavelet 256 - } - - if (minwin * skip < 256) { - maxlevelcrop = 7; //sampling 128 - } - - if (minwin * skip < 128) { - maxlevelcrop = 6; - } - - if (minwin < 64) { - maxlevelcrop = 5; - } - - int realtile; - - if (params.wavelet.Tilesmethod == "big") { - realtile = 22; - } else { /*if (params.wavelet.Tilesmethod == "lit")*/ - realtile = 12; - } - - int tilesize = 128 * realtile; - int overlap = (int) tilesize * 0.125f; - - int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; - - parent->ipf.Tile_calc(tilesize, overlap, kall, labnCrop->W, labnCrop->H, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); - //now we have tile dimensions, overlaps - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - int minsizetile = min(tilewidth, tileheight); - int maxlev2 = 10; - - if (minsizetile < 1024 && maxlevelcrop == 10) { - maxlev2 = 9; - } - - if (minsizetile < 512) { - maxlev2 = 8; - } - - if (minsizetile < 256) { - maxlev2 = 7; - } - - if (minsizetile < 128) { - maxlev2 = 6; - } - - int maxL = min(maxlev2, maxlevelcrop); - - if (parent->awavListener) { - parent->awavListener->wavChanged(float (maxL)); - } - if ((params.wavelet.enabled)) { + WaveletParams WaveParams = params.wavelet; + int kall = 0; + int minwin = min(labnCrop->W, labnCrop->H); + int maxlevelcrop = 10; + + // if(cp.mul[9]!=0)maxlevelcrop=10; + // adap maximum level wavelet to size of crop + if (minwin * skip < 1024) { + maxlevelcrop = 9; //sampling wavelet 512 + } + + if (minwin * skip < 512) { + maxlevelcrop = 8; //sampling wavelet 256 + } + + if (minwin * skip < 256) { + maxlevelcrop = 7; //sampling 128 + } + + if (minwin * skip < 128) { + maxlevelcrop = 6; + } + + if (minwin < 64) { + maxlevelcrop = 5; + } + + int realtile; + + if (params.wavelet.Tilesmethod == "big") { + realtile = 22; + } else /*if (params.wavelet.Tilesmethod == "lit")*/ { + realtile = 12; + } + + int tilesize = 128 * realtile; + int overlap = (int) tilesize * 0.125f; + + int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; + + parent->ipf.Tile_calc(tilesize, overlap, kall, labnCrop->W, labnCrop->H, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); + //now we have tile dimensions, overlaps + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + int minsizetile = min(tilewidth, tileheight); + int maxlev2 = 10; + + if (minsizetile < 1024 && maxlevelcrop == 10) { + maxlev2 = 9; + } + + if (minsizetile < 512) { + maxlev2 = 8; + } + + if (minsizetile < 256) { + maxlev2 = 7; + } + + if (minsizetile < 128) { + maxlev2 = 6; + } + + int maxL = min(maxlev2, maxlevelcrop); + + if (parent->awavListener) { + parent->awavListener->wavChanged(float (maxL)); + } + WavCurve wavCLVCurve; WavOpacityCurveRG waOpacityCurveRG; WavOpacityCurveBY waOpacityCurveBY; WavOpacityCurveW waOpacityCurveW; WavOpacityCurveWL waOpacityCurveWL; LUTf wavclCurve; - LUTu dummy; params.wavelet.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); LabImage *unshar = nullptr; diff --git a/rtengine/dfmanager.cc b/rtengine/dfmanager.cc index c41c8a180..311921c52 100644 --- a/rtengine/dfmanager.cc +++ b/rtengine/dfmanager.cc @@ -328,8 +328,8 @@ void DFManager::init(const Glib::ustring& pathname) } else { printf( "%s: MEAN of \n ", i.key().c_str()); - for( std::list::iterator iter = i.pathNames.begin(); iter != i.pathNames.end(); ++iter ) { - printf( "%s, ", iter->c_str() ); + for(std::list::iterator path = i.pathNames.begin(); path != i.pathNames.end(); ++path) { + printf("%s, ", path->c_str()); } printf("\n"); diff --git a/rtengine/diagonalcurves.cc b/rtengine/diagonalcurves.cc index b4c88fd68..dd85b87de 100644 --- a/rtengine/diagonalcurves.cc +++ b/rtengine/diagonalcurves.cc @@ -230,7 +230,6 @@ void DiagonalCurve::NURBS_set () poly_x.clear(); poly_y.clear(); unsigned int sc_xsize = j - 1; - j = 0; // adding the initial horizontal segment, if any if (x[0] > 0.) { @@ -314,18 +313,13 @@ inline void catmull_rom_spline(int n_points, double space = (t2-t1) / n_points; - double t; - int i; - double c, d, A1_x, A1_y, A2_x, A2_y, A3_x, A3_y; - double B1_x, B1_y, B2_x, B2_y, C_x, C_y; - res_x.push_back(p1_x); res_y.push_back(p1_y); // special case, a segment at 0 or 1 is computed exactly if (p1_y == p2_y && (p1_y == 0 || p1_y == 1)) { - for (i = 1; i < n_points-1; ++i) { - t = p1_x + space * i; + for (int i = 1; i < n_points-1; ++i) { + double t = p1_x + space * i; if (t >= p2_x) { break; } @@ -333,38 +327,38 @@ inline void catmull_rom_spline(int n_points, res_y.push_back(p1_y); } } else { - for (i = 1; i < n_points-1; ++i) { - t = t1 + space * i; + for (int i = 1; i < n_points-1; ++i) { + double t = t1 + space * i; - c = (t1 - t)/(t1 - t0); - d = (t - t0)/(t1 - t0); - A1_x = c * p0_x + d * p1_x; - A1_y = c * p0_y + d * p1_y; + double c = (t1 - t)/(t1 - t0); + double d = (t - t0)/(t1 - t0); + double A1_x = c * p0_x + d * p1_x; + double A1_y = c * p0_y + d * p1_y; c = (t2 - t)/(t2 - t1); d = (t - t1)/(t2 - t1); - A2_x = c * p1_x + d * p2_x; - A2_y = c * p1_y + d * p2_y; + double A2_x = c * p1_x + d * p2_x; + double A2_y = c * p1_y + d * p2_y; c = (t3 - t)/(t3 - t2); d = (t - t2)/(t3 - t2); - A3_x = c * p2_x + d * p3_x; - A3_y = c * p2_y + d * p3_y; + double A3_x = c * p2_x + d * p3_x; + double A3_y = c * p2_y + d * p3_y; c = (t2 - t)/(t2 - t0); d = (t - t0)/(t2 - t0); - B1_x = c * A1_x + d * A2_x; - B1_y = c * A1_y + d * A2_y; + double B1_x = c * A1_x + d * A2_x; + double B1_y = c * A1_y + d * A2_y; c = (t3 - t)/(t3 - t1); d = (t - t1)/(t3 - t1); - B2_x = c * A2_x + d * A3_x; - B2_y = c * A2_y + d * A3_y; + double B2_x = c * A2_x + d * A3_x; + double B2_y = c * A2_y + d * A3_y; c = (t2 - t)/(t2 - t1); d = (t - t1)/(t2 - t1); - C_x = c * B1_x + d * B2_x; - C_y = c * B1_y + d * B2_y; + double C_x = c * B1_x + d * B2_x; + double C_y = c * B1_y + d * B2_y; res_x.push_back(C_x); res_y.push_back(C_y); @@ -512,7 +506,6 @@ double DiagonalCurve::getVal (double t) const ++d; } return LIM01(*(poly_y.begin() + d)); - break; } case DCT_NURBS : { diff --git a/rtengine/dirpyr_equalizer.cc b/rtengine/dirpyr_equalizer.cc index 4a30b48a8..94826e06e 100644 --- a/rtengine/dirpyr_equalizer.cc +++ b/rtengine/dirpyr_equalizer.cc @@ -16,7 +16,7 @@ * * (C) 2010 Emil Martinec * - */ +*/ #include #include @@ -25,404 +25,55 @@ #include "rt_math.h" #include "opthelper.h" -#define RANGEFN(i) ((1000.0f / (i + 1000.0f))) -#define DIRWT(i1,j1,i,j) ( domker[(i1-i)/scale+halfwin][(j1-j)/scale+halfwin] * RANGEFN(fabsf((data_fine[i1][j1]-data_fine[i][j]))) ) - -namespace rtengine -{ - -constexpr int maxlevel = 6; -constexpr float noise = 2000; - -//sequence of scales -constexpr int scales[maxlevel] = {1, 2, 4, 8, 16, 32}; -extern const Settings* settings; - -//sequence of scales - -void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, int srcwidth, int srcheight, float ** l_a, float ** l_b, const double * mult, const double dirpyrThreshold, const double skinprot, float b_l, float t_l, float t_r, int scaleprev) -{ - int lastlevel = maxlevel; - - float atten123 = (float) settings->level123_cbdl; - - if(atten123 > 50.f) { - atten123 = 50.f; - } - - if(atten123 < 0.f) { - atten123 = 0.f; - } - - float atten0 = (float) settings->level0_cbdl; - - if(atten0 > 40.f) { - atten123 = 40.f; - } - - if(atten0 < 0.f) { - atten0 = 0.f; - } - - if((t_r - t_l) < 0.55f) { - t_l = t_r + 0.55f; //avoid too small range - } - - - while (lastlevel > 0 && fabs(mult[lastlevel - 1] - 1) < 0.001) { - lastlevel--; - //printf("last level to process %d \n",lastlevel); - } - - if (lastlevel == 0) { - return; - } - - int level; - float multi[maxlevel] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f}; - float scalefl[maxlevel]; - - for(int lv = 0; lv < maxlevel; lv++) { - scalefl[lv] = ((float) scales[lv]) / (float) scaleprev; - - if(lv >= 1) { - if(scalefl[lv] < 1.f) { - multi[lv] = (atten123 * ((float) mult[lv] - 1.f) / 100.f) + 1.f; //modulate action if zoom < 100% - } else { - multi[lv] = (float) mult[lv]; - } - } else { - if(scalefl[lv] < 1.f) { - multi[lv] = (atten0 * ((float) mult[lv] - 1.f) / 100.f) + 1.f; //modulate action if zoom < 100% - } else { - multi[lv] = (float) mult[lv]; - } - } - - } - - multi_array2D dirpyrlo (srcwidth, srcheight); - - level = 0; - - //int thresh = 100 * mult[5]; - int scale = (int)(scales[level]) / scaleprev; - - if(scale < 1) { - scale = 1; - } - - - dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, scale); - - level = 1; - - while(level < lastlevel) { - - scale = (int)(scales[level]) / scaleprev; - - if(scale < 1) { - scale = 1; - } - - dirpyr_channel(dirpyrlo[level - 1], dirpyrlo[level], srcwidth, srcheight, level, scale); - - level ++; - } - - float **tmpHue = nullptr, **tmpChr = nullptr; - - if(skinprot != 0.f) { - // precalculate hue and chroma, use SSE, if available - // by precalculating these values we can greatly reduce the number of calculations in idirpyr_eq_channel() - // but we need two additional buffers for this preprocessing - tmpHue = new float*[srcheight]; - - for (int i = 0; i < srcheight; i++) { - tmpHue[i] = new float[srcwidth]; - } - -#ifdef __SSE2__ -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for(int i = 0; i < srcheight; i++) { - int j; - - for(j = 0; j < srcwidth - 3; j += 4) { - _mm_storeu_ps(&tmpHue[i][j], xatan2f(LVFU(l_b[i][j]), LVFU(l_a[i][j]))); - } - - for(; j < srcwidth; j++) { - tmpHue[i][j] = xatan2f(l_b[i][j], l_a[i][j]); - } - } - -#else -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for(int i = 0; i < srcheight; i++) { - for(int j = 0; j < srcwidth; j++) { - tmpHue[i][j] = xatan2f(l_b[i][j], l_a[i][j]); - } - } - -#endif - tmpChr = new float*[srcheight]; - - for (int i = 0; i < srcheight; i++) { - tmpChr[i] = new float[srcwidth]; - } - -#ifdef __SSE2__ -#ifdef _OPENMP - #pragma omp parallel -#endif - { - __m128 div = _mm_set1_ps(327.68f); -#ifdef _OPENMP - #pragma omp for -#endif - - for(int i = 0; i < srcheight; i++) { - int j; - - for(j = 0; j < srcwidth - 3; j += 4) { - _mm_storeu_ps(&tmpChr[i][j], vsqrtf(SQRV(LVFU(l_b[i][j])) + SQRV(LVFU(l_a[i][j]))) / div); - } - - for(; j < srcwidth; j++) { - tmpChr[i][j] = sqrtf(SQR((l_b[i][j])) + SQR((l_a[i][j]))) / 327.68f; - } - } - } -#else -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for(int i = 0; i < srcheight; i++) { - for(int j = 0; j < srcwidth; j++) { - tmpChr[i][j] = sqrtf(SQR((l_b[i][j])) + SQR((l_a[i][j]))) / 327.68f; - } - } - -#endif - } - - // with the current implementation of idirpyr_eq_channel we can safely use the buffer from last level as buffer, saves some memory - float ** buffer = dirpyrlo[lastlevel - 1]; - - for(int level = lastlevel - 1; level > 0; level--) { - idirpyr_eq_channel(dirpyrlo[level], dirpyrlo[level - 1], buffer, srcwidth, srcheight, level, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, b_l, t_l, t_r); - } - - scale = scales[0]; - - idirpyr_eq_channel(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, tmpHue, tmpChr, skinprot, b_l, t_l, t_r); - - if(skinprot != 0.f) { - for (int i = 0; i < srcheight; i++) { - delete [] tmpChr[i]; - } - - delete [] tmpChr; - - for (int i = 0; i < srcheight; i++) { - delete [] tmpHue[i]; - } - - delete [] tmpHue; - } - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int i = 0; i < srcheight; i++) - for (int j = 0; j < srcwidth; j++) { - dst[i][j] = /*CLIP*/(buffer[i][j]); // TODO: Really a clip necessary? - } +namespace { +float rangeFn(float i) { + return 1.f / (i + 1000.f); } - - -void ImProcFunctions :: dirpyr_equalizercam (CieImage *ncie, float ** src, float ** dst, int srcwidth, int srcheight, float ** h_p, float ** C_p, const double * mult, const double dirpyrThreshold, const double skinprot, bool execdir, float b_l, float t_l, float t_r, int scaleprev) -{ - int lastlevel = maxlevel; - - if(settings->verbose) { - printf("CAM dirpyr scaleprev=%i\n", scaleprev); - } - - float atten123 = (float) settings->level123_cbdl; - - if(atten123 > 50.f) { - atten123 = 50.f; - } - - if(atten123 < 0.f) { - atten123 = 0.f; - } - -// printf("atten=%f\n",atten); - float atten0 = (float) settings->level0_cbdl; - - if(atten0 > 40.f) { - atten123 = 40.f; - } - - if(atten0 < 0.f) { - atten0 = 0.f; - } - - if((t_r - t_l) < 0.55f) { - t_l = t_r + 0.55f; //avoid too small range - } - - while (fabs(mult[lastlevel - 1] - 1) < 0.001 && lastlevel > 0) { - lastlevel--; - //printf("last level to process %d \n",lastlevel); - } - - if (lastlevel == 0) { - return; - } - - int level; - - float multi[maxlevel] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f}; - float scalefl[maxlevel]; - - for(int lv = 0; lv < maxlevel; lv++) { - scalefl[lv] = ((float) scales[lv]) / (float) scaleprev; - - // if(scalefl[lv] < 1.f) multi[lv] = 1.f; else multi[lv]=(float) mult[lv]; - if (lv >= 1) { - if(scalefl[lv] < 1.f) { - multi[lv] = (atten123 * ((float) mult[lv] - 1.f) / 100.f) + 1.f; - } else { - multi[lv] = (float) mult[lv]; - } - } else { - if(scalefl[lv] < 1.f) { - multi[lv] = (atten0 * ((float) mult[lv] - 1.f) / 100.f) + 1.f; - } else { - multi[lv] = (float) mult[lv]; - } - } - - - } - - if(settings->verbose) { - printf("CAM CbDL mult0=%f 1=%f 2=%f 3=%f 4=%f 5=%f\n", multi[0], multi[1], multi[2], multi[3], multi[4], multi[5]); - } - - - - - multi_array2D dirpyrlo (srcwidth, srcheight); - - level = 0; - - int scale = (int)(scales[level]) / scaleprev; - - if(scale < 1) { - scale = 1; - } - - dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, scale); - - level = 1; - - while(level < lastlevel) { - scale = (int)(scales[level]) / scaleprev; - - if(scale < 1) { - scale = 1; - } - - dirpyr_channel(dirpyrlo[level - 1], dirpyrlo[level], srcwidth, srcheight, level, scale); - - level ++; - } - - - // with the current implementation of idirpyr_eq_channel we can safely use the buffer from last level as buffer, saves some memory - float ** buffer = dirpyrlo[lastlevel - 1]; - - for(int level = lastlevel - 1; level > 0; level--) { - idirpyr_eq_channelcam(dirpyrlo[level], dirpyrlo[level - 1], buffer, srcwidth, srcheight, level, multi, dirpyrThreshold , h_p, C_p, skinprot, b_l, t_l, t_r); - } - - idirpyr_eq_channelcam(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, h_p, C_p, skinprot, b_l, t_l, t_r); - - - if(execdir) { -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - - for (int i = 0; i < srcheight; i++) - for (int j = 0; j < srcwidth; j++) { - if(ncie->J_p[i][j] > 8.f && ncie->J_p[i][j] < 92.f) { - dst[i][j] = /*CLIP*/( buffer[i][j] ); // TODO: Really a clip necessary? - } else { - dst[i][j] = src[i][j]; - } - } - } else { - for (int i = 0; i < srcheight; i++) - for (int j = 0; j < srcwidth; j++) { - dst[i][j] = /*CLIP*/( buffer[i][j] ); // TODO: Really a clip necessary? - } - } -} - -void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** data_coarse, int width, int height, int level, int scale) +void dirpyr_channel(const float * const * data_fine, float ** data_coarse, int width, int height, int level, int scale) { // scale is spacing of directional averaging weights // calculate weights, compute directionally weighted average - if(level > 1) { + if (level > 1) { //generate domain kernel - int domker[5][5] = {{1, 1, 1, 1, 1}, {1, 2, 2, 2, 1}, {1, 2, 2, 2, 1}, {1, 2, 2, 2, 1}, {1, 1, 1, 1, 1}}; - // int domker[5][5] = {{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1}}; - static const int halfwin = 2; - const int scalewin = halfwin * scale; + // multiplied each value of domker by 1000 to avoid multiplication by 1000 inside the loop +#ifdef __SSE2__ + const float domkerv[5][5][4] ALIGNED16 = {{{1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}}, + {{1000, 1000, 1000, 1000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {1000, 1000, 1000, 1000}}, + {{1000, 1000, 1000, 1000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {1000, 1000, 1000, 1000}}, + {{1000, 1000, 1000, 1000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {1000, 1000, 1000, 1000}}, + {{1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}}}; +#endif + const float domker[5][5] = {{1000, 1000, 1000, 1000, 1000}, + {1000, 2000, 2000, 2000, 1000}, + {1000, 2000, 2000, 2000, 1000}, + {1000, 2000, 2000, 2000, 1000}, + {1000, 1000, 1000, 1000, 1000}}; + constexpr int halfwin = 2; #ifdef _OPENMP #pragma omp parallel #endif { + const int scalewin = halfwin * scale; #ifdef __SSE2__ - __m128 thousandv = _mm_set1_ps( 1000.0f ); - __m128 dirwtv, valv, normv, dftemp1v, dftemp2v; -// multiplied each value of domkerv by 1000 to avoid multiplication by 1000 inside the loop - float domkerv[5][5][4] ALIGNED16 = {{{1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}}, {{1000, 1000, 1000, 1000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {1000, 1000, 1000, 1000}}, {{1000, 1000, 1000, 1000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {1000, 1000, 1000, 1000}}, {{1000, 1000, 1000, 1000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {2000, 2000, 2000, 2000}, {1000, 1000, 1000, 1000}}, {{1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}, {1000, 1000, 1000, 1000}}}; -#endif // __SSE2__ - - int j; -#ifdef _OPENMP - #pragma omp for //schedule (dynamic,8) + const vfloat thousandv = F2V(1000.f); #endif - for(int i = 0; i < height; i++) { - float dirwt; +#ifdef _OPENMP + #pragma omp for +#endif - for(j = 0; j < scalewin; j++) { + for (int i = 0; i < height; i++) { + int j; + for (j = 0; j < scalewin; j++) { float val = 0.f; float norm = 0.f; - - for(int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) { + for (int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) { for (int jnbr = max(0, j - scalewin); jnbr <= j + scalewin; jnbr += scale) { - //printf("i=%d ",(inbr-i)/scale+halfwin); - dirwt = DIRWT(inbr, jnbr, i, j); + const float dirwt = domker[(inbr - i) / scale + halfwin][(jnbr - j)/ scale + halfwin] * rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); val += dirwt * data_fine[inbr][jnbr]; norm += dirwt; } @@ -433,174 +84,125 @@ void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** data_coarse, i #ifdef __SSE2__ - for(; j < width - scalewin - 3; j += 4) { - valv = _mm_setzero_ps(); - normv = _mm_setzero_ps(); - dftemp1v = LVFU(data_fine[i][j]); + for (; j < width - scalewin - 3; j += 4) { + vfloat valv = ZEROV; + vfloat normv = ZEROV; + const vfloat dftemp1v = LVFU(data_fine[i][j]); - for(int inbr = MAX(0, i - scalewin); inbr <= MIN(height - 1, i + scalewin); inbr += scale) { - int indexihlp = (inbr - i) / scale + halfwin; - - for (int jnbr = j - scalewin, indexjhlp = 0; jnbr <= j + scalewin; jnbr += scale, indexjhlp++) { - dftemp2v = LVFU(data_fine[inbr][jnbr]); - dirwtv = LVF(domkerv[indexihlp][indexjhlp]) / (vabsf(dftemp1v - dftemp2v) + thousandv); + for (int inbr = MAX(0, i - scalewin); inbr <= MIN(height - 1, i + scalewin); inbr += scale) { + const int indexihlp = (inbr - i) / scale + halfwin; + for (int jnbr = j - scalewin, indexjhlp = 0; jnbr <= j + scalewin; jnbr += scale, ++indexjhlp) { + const vfloat dftemp2v = LVFU(data_fine[inbr][jnbr]); + const vfloat dirwtv = LVF(domkerv[indexihlp][indexjhlp]) / (vabsf(dftemp1v - dftemp2v) + thousandv); valv += dirwtv * dftemp2v; normv += dirwtv; } } - - _mm_storeu_ps( &data_coarse[i][j], valv / normv); //low pass filter + STVFU(data_coarse[i][j], valv / normv); //low pass filter } - - for(; j < width - scalewin; j++) { - float val = 0.f; - float norm = 0.f; - - for(int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) { - for (int jnbr = j - scalewin; jnbr <= j + scalewin; jnbr += scale) { - dirwt = DIRWT(inbr, jnbr, i, j); - val += dirwt * data_fine[inbr][jnbr]; - norm += dirwt; - } - } - - data_coarse[i][j] = val / norm; //low pass filter - } - -#else - - for(; j < width - scalewin; j++) { - float val = 0.f; - float norm = 0.f; - - for(int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) { - for (int jnbr = j - scalewin; jnbr <= j + scalewin; jnbr += scale) { - dirwt = DIRWT(inbr, jnbr, i, j); - val += dirwt * data_fine[inbr][jnbr]; - norm += dirwt; - } - } - - data_coarse[i][j] = val / norm; //low pass filter - } - #endif - - for(; j < width; j++) { + for (; j < width - scalewin; j++) { float val = 0.f; float norm = 0.f; - for(int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) { - for (int jnbr = j - scalewin; jnbr <= min(width - 1, j + scalewin); jnbr += scale) { - dirwt = DIRWT(inbr, jnbr, i, j); + for (int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) { + for (int jnbr = j - scalewin; jnbr <= j + scalewin; jnbr += scale) { + const float dirwt = domker[(inbr - i) / scale + halfwin][(jnbr - j)/ scale + halfwin] * rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); val += dirwt * data_fine[inbr][jnbr]; norm += dirwt; } } + data_coarse[i][j] = val / norm; //low pass filter + } + for (; j < width; j++) { + float val = 0.f; + float norm = 0.f; + + for (int inbr = max(0, i - scalewin); inbr <= min(height - 1, i + scalewin); inbr += scale) { + for (int jnbr = j - scalewin; jnbr <= min(width - 1, j + scalewin); jnbr += scale) { + const float dirwt = domker[(inbr - i) / scale + halfwin][(jnbr - j)/ scale + halfwin] * rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); + val += dirwt * data_fine[inbr][jnbr]; + norm += dirwt; + } + } data_coarse[i][j] = val / norm; //low pass filter } } } } else { // level <=1 means that all values of domker would be 1.0f, so no need for multiplication -// const int scalewin = scale; #ifdef _OPENMP #pragma omp parallel #endif { #ifdef __SSE2__ - __m128 thousandv = _mm_set1_ps( 1000.0f ); - __m128 dirwtv, valv, normv, dftemp1v, dftemp2v; -#endif // __SSE2__ - int j; + const vfloat thousandv = F2V(1000.0f); +#endif #ifdef _OPENMP #pragma omp for schedule(dynamic,16) #endif - for(int i = 0; i < height; i++) + for (int i = 0; i < height; i++) { - float dirwt; - - for(j = 0; j < scale; j++) { + int j = 0; + for (; j < scale; j++) { float val = 0.f; float norm = 0.f; - for(int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) { + for (int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) { for (int jnbr = max(0, j - scale); jnbr <= j + scale; jnbr += scale) { - dirwt = RANGEFN(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); + const float dirwt = rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); val += dirwt * data_fine[inbr][jnbr]; norm += dirwt; } } - data_coarse[i][j] = val / norm; //low pass filter } #ifdef __SSE2__ - for(; j < width - scale - 3; j += 4) { - valv = _mm_setzero_ps(); - normv = _mm_setzero_ps(); - dftemp1v = LVFU(data_fine[i][j]); + for (; j < width - scale - 3; j += 4) { + vfloat valv = ZEROV; + vfloat normv = ZEROV; + const vfloat dftemp1v = LVFU(data_fine[i][j]); - for(int inbr = MAX(0, i - scale); inbr <= MIN(height - 1, i + scale); inbr += scale) { + for (int inbr = MAX(0, i - scale); inbr <= MIN(height - 1, i + scale); inbr += scale) { for (int jnbr = j - scale; jnbr <= j + scale; jnbr += scale) { - dftemp2v = LVFU(data_fine[inbr][jnbr]); - dirwtv = thousandv / (vabsf(dftemp2v - dftemp1v) + thousandv); + const vfloat dftemp2v = LVFU(data_fine[inbr][jnbr]); + const vfloat dirwtv = thousandv / (vabsf(dftemp2v - dftemp1v) + thousandv); valv += dirwtv * dftemp2v; normv += dirwtv; } } - - _mm_storeu_ps( &data_coarse[i][j], valv / normv); //low pass filter + STVFU(data_coarse[i][j], valv / normv); //low pass filter } - - for(; j < width - scale; j++) { - float val = 0.f; - float norm = 0.f; - - for(int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) { - for (int jnbr = j - scale; jnbr <= j + scale; jnbr += scale) { - dirwt = RANGEFN(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); - val += dirwt * data_fine[inbr][jnbr]; - norm += dirwt; - } - } - - data_coarse[i][j] = val / norm; //low pass filter - } - -#else - - for(; j < width - scale; j++) { - float val = 0.f; - float norm = 0.f; - - for(int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) { - for (int jnbr = j - scale; jnbr <= j + scale; jnbr += scale) { - dirwt = RANGEFN(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); - val += dirwt * data_fine[inbr][jnbr]; - norm += dirwt; - } - } - - data_coarse[i][j] = val / norm; //low pass filter - } - #endif - for(; j < width; j++) { + for (; j < width - scale; j++) { float val = 0.f; float norm = 0.f; - for(int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) { - for (int jnbr = j - scale; jnbr <= min(width - 1, j + scale); jnbr += scale) { - dirwt = RANGEFN(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); + for (int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) { + for (int jnbr = j - scale; jnbr <= j + scale; jnbr += scale) { + const float dirwt = rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); val += dirwt * data_fine[inbr][jnbr]; norm += dirwt; } } + data_coarse[i][j] = val / norm; //low pass filter + } + for (; j < width; j++) { + float val = 0.f; + float norm = 0.f; + + for (int inbr = max(0, i - scale); inbr <= min(height - 1, i + scale); inbr += scale) { + for (int jnbr = j - scale; jnbr <= min(width - 1, j + scale); jnbr += scale) { + const float dirwt = rangeFn(fabsf(data_fine[inbr][jnbr] - data_fine[i][j])); + val += dirwt * data_fine[inbr][jnbr]; + norm += dirwt; + } + } data_coarse[i][j] = val / norm; //low pass filter } } @@ -608,218 +210,297 @@ void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** data_coarse, i } } -void ImProcFunctions::idirpyr_eq_channel(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float mult[maxlevel], const double dirpyrThreshold, float ** hue, float ** chrom, const double skinprot, float b_l, float t_l, float t_r) +void fillLut(LUTf &irangefn, int level, double dirpyrThreshold, float mult, float skinprot) { + + float multbis; + if (level == 4 && mult > 1.f) { + multbis = 1.f + 0.65f * (mult - 1.f); + } else if (level == 5 && mult > 1.f) { + multbis = 1.f + 0.45f * (mult - 1.f); + } else { + multbis = mult; //multbis to reduce artifacts for high values mult + } + + const float offs = skinprot == 0.f ? 0.f : -1.f; + constexpr float noise = 2000.f; + const float noisehi = 1.33f * noise * dirpyrThreshold / expf(level * log(3.0)), noiselo = 0.66f * noise * dirpyrThreshold / expf(level * log(3.0)); + + for (int i = 0; i < 0x20000; i++) { + if (abs(i - 0x10000) > noisehi || multbis < 1.0) { + irangefn[i] = multbis + offs; + } else { + if (abs(i - 0x10000) < noiselo) { + irangefn[i] = 1.f + offs; + } else { + irangefn[i] = 1.f + offs + (multbis - 1.f) * (noisehi - abs(i - 0x10000)) / (noisehi - noiselo + 0.01f); + } + } + } +} + +void idirpyr_eq_channel(const float * const * data_coarse, const float * const * data_fine, float ** buffer, int width, int height, int level, float mult, const double dirpyrThreshold, const float * const * hue, const float * const * chrom, const double skinprot, float b_l, float t_l, float t_r) { const float skinprotneg = -skinprot; const float factorHard = (1.f - skinprotneg / 100.f); - float offs; + LUTf irangefn(0x20000); + fillLut(irangefn, level, dirpyrThreshold, mult, skinprot); - if(skinprot == 0.f) { - offs = 0.f; - } else { - offs = -1.f; - } - - float multbis[maxlevel]; - - multbis[level] = mult[level]; //multbis to reduce artifacts for high values mult - - if(level == 4 && mult[level] > 1.f) { - multbis[level] = 1.f + 0.65f * (mult[level] - 1.f); - } - - if(level == 5 && mult[level] > 1.f) { - multbis[level] = 1.f + 0.45f * (mult[level] - 1.f); - } - - LUTf irangefn (0x20000); - { - const float noisehi = 1.33f * noise * dirpyrThreshold / expf(level * log(3.0)), noiselo = 0.66f * noise * dirpyrThreshold / expf(level * log(3.0)); - //printf("level=%i multlev=%f noisehi=%f noiselo=%f skinprot=%f\n",level,mult[level], noisehi, noiselo, skinprot); - - for (int i = 0; i < 0x20000; i++) { - if (abs(i - 0x10000) > noisehi || multbis[level] < 1.0) { - irangefn[i] = multbis[level] + offs; - } else { - if (abs(i - 0x10000) < noiselo) { - irangefn[i] = 1.f + offs ; - } else { - irangefn[i] = 1.f + offs + (multbis[level] - 1.f) * (noisehi - abs(i - 0x10000)) / (noisehi - noiselo + 0.01f) ; - } - } - } - } - - if(skinprot == 0.f) + if (!skinprot) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif - for(int i = 0; i < height; i++) { - for(int j = 0; j < width; j++) { - float hipass = (data_fine[i][j] - data_coarse[i][j]); + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + const float hipass = data_fine[i][j] - data_coarse[i][j]; buffer[i][j] += irangefn[hipass + 0x10000] * hipass; } } - else if(skinprot > 0.f) + } else if (skinprot > 0.f) { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif - for(int i = 0; i < height; i++) { - for(int j = 0; j < width; j++) { + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { float scale = 1.f; - float hipass = (data_fine[i][j] - data_coarse[i][j]); - // These values are precalculated now - float modhue = hue[i][j]; - float modchro = chrom[i][j]; - Color::SkinSatCbdl ((data_fine[i][j]) / 327.68f, modhue, modchro, skinprot, scale, true, b_l, t_l, t_r); - buffer[i][j] += (1.f + (irangefn[hipass + 0x10000]) * scale) * hipass ; + const float hipass = data_fine[i][j] - data_coarse[i][j]; + rtengine::Color::SkinSatCbdl(data_fine[i][j] / 327.68f, hue[i][j], chrom[i][j], skinprot, scale, true, b_l, t_l, t_r); + buffer[i][j] += (1.f + (irangefn[hipass + 0x10000]) * scale) * hipass; } } - else + } else { #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif - for(int i = 0; i < height; i++) { - for(int j = 0; j < width; j++) { + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { float scale = 1.f; - float hipass = (data_fine[i][j] - data_coarse[i][j]); - // These values are precalculated now - float modhue = hue[i][j]; - float modchro = chrom[i][j]; - Color::SkinSatCbdl ((data_fine[i][j]) / 327.68f, modhue, modchro, skinprotneg, scale, false, b_l, t_l, t_r); - float correct = irangefn[hipass + 0x10000]; + const float hipass = data_fine[i][j] - data_coarse[i][j]; + rtengine::Color::SkinSatCbdl(data_fine[i][j] / 327.68f, hue[i][j], chrom[i][j], skinprotneg, scale, false, b_l, t_l, t_r); + const float correct = irangefn[hipass + 0x10000]; if (scale == 1.f) {//image hard - buffer[i][j] += (1.f + (correct) * (factorHard)) * hipass ; + buffer[i][j] += (1.f + correct * factorHard) * hipass; } else { //image soft with scale < 1 ==> skin - buffer[i][j] += (1.f + (correct)) * hipass ; + buffer[i][j] += (1.f + correct) * hipass; } } } + } } - -void ImProcFunctions::idirpyr_eq_channelcam(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float mult[maxlevel], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, const double skinprot, float b_l, float t_l, float t_r) +void idirpyr_eq_channelcam(const float * const * data_coarse, const float * const * data_fine, float ** buffer, int width, int height, int level, float mult, const double dirpyrThreshold, const float * const * h_p, const float * const * C_p, const double skinprot, float b_l, float t_l, float t_r) { const float skinprotneg = -skinprot; - const float factorHard = (1.f - skinprotneg / 100.f); + const float factorHard = 1.f - skinprotneg / 100.f; - float offs; + LUTf irangefn(0x20000); + fillLut(irangefn, level, dirpyrThreshold, mult, skinprot); - if(skinprot == 0.f) { - offs = 0.f; + if (!skinprot) { +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + const float hipass = data_fine[i][j] - data_coarse[i][j]; + buffer[i][j] += irangefn[hipass + 0x10000] * hipass; + } + } + } else if (skinprot > 0.f) { +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + const float hipass = data_fine[i][j] - data_coarse[i][j]; + float scale = 1.f; + rtengine::Color::SkinSatCbdlCam(data_fine[i][j] / 327.68f, h_p[i][j] , C_p[i][j], skinprot, scale, true, b_l, t_l, t_r); + buffer[i][j] += (1.f + (irangefn[hipass + 0x10000]) * scale) * hipass; + } + } } else { - offs = -1.f; - } - - float multbis[maxlevel]; - - multbis[level] = mult[level]; //multbis to reduce artifacts for high values mult - - if(level == 4 && mult[level] > 1.f) { - multbis[level] = 1.f + 0.65f * (mult[level] - 1.f); - } - - if(level == 5 && mult[level] > 1.f) { - multbis[level] = 1.f + 0.45f * (mult[level] - 1.f); - } - - LUTf irangefn (0x20000); - { - const float noisehi = 1.33f * noise * dirpyrThreshold / expf(level * log(3.0)), noiselo = 0.66f * noise * dirpyrThreshold / expf(level * log(3.0)); - - //printf("level=%i multlev=%f noisehi=%f noiselo=%f skinprot=%f\n",level,mult[level], noisehi, noiselo, skinprot); - for (int i = 0; i < 0x20000; i++) { - if (abs(i - 0x10000) > noisehi || multbis[level] < 1.0) { - irangefn[i] = multbis[level] + offs; - } else { - if (abs(i - 0x10000) < noiselo) { - irangefn[i] = 1.f + offs ; - } else { - irangefn[i] = 1.f + offs + (multbis[level] - 1.f) * (noisehi - abs(i - 0x10000)) / (noisehi - noiselo + 0.01f) ; - } - } - } - } - - if(skinprot == 0.f) #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif - for(int i = 0; i < height; i++) { - for(int j = 0; j < width; j++) { - float hipass = (data_fine[i][j] - data_coarse[i][j]); - buffer[i][j] += irangefn[hipass + 0x10000] * hipass ; - } - } - else if(skinprot > 0.f) -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - for(int i = 0; i < height; i++) { - for(int j = 0; j < width; j++) { - float hipass = (data_fine[i][j] - data_coarse[i][j]); + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + const float hipass = data_fine[i][j] - data_coarse[i][j]; float scale = 1.f; - Color::SkinSatCbdlCam ((data_fine[i][j]) / 327.68f, l_a_h[i][j] , l_b_c[i][j], skinprot, scale, true, b_l, t_l, t_r); - buffer[i][j] += (1.f + (irangefn[hipass + 0x10000]) * scale) * hipass ; - } - } - else -#ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) -#endif - for(int i = 0; i < height; i++) { - for(int j = 0; j < width; j++) { - float hipass = (data_fine[i][j] - data_coarse[i][j]); - float scale = 1.f; - float correct; - correct = irangefn[hipass + 0x10000]; - Color::SkinSatCbdlCam ((data_fine[i][j]) / 327.68f, l_a_h[i][j], l_b_c[i][j] , skinprotneg, scale, false, b_l, t_l, t_r); + const float correct = irangefn[hipass + 0x10000]; + rtengine::Color::SkinSatCbdlCam(data_fine[i][j] / 327.68f, h_p[i][j], C_p[i][j], skinprotneg, scale, false, b_l, t_l, t_r); if (scale == 1.f) {//image hard - buffer[i][j] += (1.f + (correct) * factorHard) * hipass ; - + buffer[i][j] += (1.f + correct * factorHard) * hipass; } else { //image soft - buffer[i][j] += (1.f + (correct)) * hipass ; + buffer[i][j] += (1.f + correct) * hipass; } } } + } +} - // if(gamutlab) { - // ImProcFunctions::badpixcam (buffer[i][j], 6.0, 10, 2);//for bad pixels - // } +} - /* if(gamutlab) {//disabled - float Lprov1=(buffer[i][j])/327.68f; - float R,G,B; - #ifdef _DEBUG - bool neg=false; - bool more_rgb=false; - //gamut control : Lab values are in gamut - Color::gamutLchonly(modhue,Lprov1,modchro, R, G, B, wip, highlight, 0.15f, 0.96f, neg, more_rgb); - #else - //gamut control : Lab values are in gamut - Color::gamutLchonly(modhue,Lprov1,modchro, R, G, B, wip, highlight, 0.15f, 0.96f); - #endif - // Color::gamutLchonly(modhue,Lprov1,modchro, R, G, B, wip, highlight, 0.15f, 0.96f);//gamut control in Lab mode ..not in CIECAM - buffer[i][j]=Lprov1*327.68f; - float2 sincosval = xsincosf(modhue); - l_a_h[i][j]=327.68f*modchro*sincosval.y; - l_b_c[i][j]=327.68f*modchro*sincosval.x; +namespace rtengine +{ + +extern const Settings* settings; + +void ImProcFunctions::dirpyr_equalizer(const float * const * src, float ** dst, int srcwidth, int srcheight, const float * const * l_a, const float * const * l_b, const double * mult, const double dirpyrThreshold, const double skinprot, float b_l, float t_l, float t_r, int scaleprev) +{ + //sequence of scales + constexpr int maxlevel = 6; + constexpr int scales[maxlevel] = {1, 2, 4, 8, 16, 32}; + const float atten123 = rtengine::LIM(settings->level123_cbdl, 0.f, 50.f); + const float atten0 = rtengine::LIM(settings->level0_cbdl, 0.f, 40.f); + + int lastlevel = maxlevel; + while (lastlevel > 0 && fabs(mult[lastlevel - 1] - 1) < 0.001) { + --lastlevel; + } + + if (lastlevel == 0) { + return; + } + + float multi[maxlevel]; + + for (int lv = 0; lv < maxlevel; ++lv) { + if (scales[lv] < scaleprev) { + const float factor = lv >= 1 ? atten123 : atten0; + multi[lv] = (factor * ((float) mult[lv] - 1.f) / 100.f) + 1.f; //modulate action if zoom < 100% + } else { + multi[lv] = mult[lv]; + } + } + + multi_array2D dirpyrlo (srcwidth, srcheight); + + dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, std::max(scales[0] / scaleprev, 1)); + + for (int level = 1; level < lastlevel; ++level) { + dirpyr_channel(dirpyrlo[level - 1], dirpyrlo[level], srcwidth, srcheight, level, std::max(scales[level] / scaleprev, 1)); + } + + array2D tmpHue, tmpChr; + + if (skinprot) { + // precalculate hue and chroma, use SSE, if available + // by precalculating these values we can greatly reduce the number of calculations in idirpyr_eq_channel() + // but we need two additional buffers for this preprocessing + tmpHue(srcwidth, srcheight); + tmpChr(srcwidth, srcheight); + +#ifdef _OPENMP + #pragma omp parallel +#endif + { +#ifdef __SSE2__ + const vfloat div = F2V(327.68f); +#endif +#ifdef _OPENMP + #pragma omp for +#endif + + for (int i = 0; i < srcheight; i++) { + int j = 0; +#ifdef __SSE2__ + for (; j < srcwidth - 3; j += 4) { + const vfloat lav = LVFU(l_a[i][j]); + const vfloat lbv = LVFU(l_b[i][j]); + STVFU(tmpHue[i][j], xatan2f(lbv, lav)); + STVFU(tmpChr[i][j], vsqrtf(SQRV(lbv) + SQRV(lav)) / div); + } +#endif + for (; j < srcwidth; j++) { + tmpHue[i][j] = xatan2f(l_b[i][j], l_a[i][j]); + tmpChr[i][j] = sqrtf(SQR((l_b[i][j])) + SQR((l_a[i][j]))) / 327.68f; + } } - */ + } + } + + // with the current implementation of idirpyr_eq_channel we can safely use the buffer from last level as buffer, saves some memory + float** buffer = dirpyrlo[lastlevel - 1]; + + for (int level = lastlevel - 1; level > 0; --level) { + idirpyr_eq_channel(dirpyrlo[level], dirpyrlo[level - 1], buffer, srcwidth, srcheight, level, multi[level], dirpyrThreshold, tmpHue, tmpChr, skinprot, b_l, t_l, t_r); + } + + idirpyr_eq_channel(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi[0], dirpyrThreshold, tmpHue, tmpChr, skinprot, b_l, t_l, t_r); + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int i = 0; i < srcheight; i++) { + for (int j = 0; j < srcwidth; j++) { + dst[i][j] = buffer[i][j]; + } + } } -// float hipass = (data_fine[i][j]-data_coarse[i][j]); -// buffer[i][j] += irangefn[hipass+0x10000] * hipass ; +void ImProcFunctions::dirpyr_equalizercam(const CieImage *ncie, float ** src, float ** dst, int srcwidth, int srcheight, const float * const * h_p, const float * const * C_p, const double * mult, const double dirpyrThreshold, const double skinprot, float b_l, float t_l, float t_r, int scaleprev) +{ -#undef DIRWT_L -#undef DIRWT_AB + //sequence of scales + constexpr int maxlevel = 6; + constexpr int scales[maxlevel] = {1, 2, 4, 8, 16, 32}; + const float atten123 = rtengine::LIM(settings->level123_cbdl, 0.f, 50.f); + const float atten0 = rtengine::LIM(settings->level0_cbdl, 0.f, 40.f); -#undef NRWT_L -#undef NRWT_AB + int lastlevel = maxlevel; + while (fabs(mult[lastlevel - 1] - 1) < 0.001 && lastlevel > 0) { + --lastlevel; + } + if (lastlevel == 0) { + return; + } + + float multi[maxlevel]; + + for (int lv = 0; lv < maxlevel; lv++) { + if (scales[lv] < scaleprev) { + const float factor = lv >= 1 ? atten123 : atten0; + multi[lv] = (factor * ((float) mult[lv] - 1.f) / 100.f) + 1.f; + } else { + multi[lv] = mult[lv]; + } + } + + multi_array2D dirpyrlo (srcwidth, srcheight); + + dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, std::max(scales[0] / scaleprev, 1)); + + for (int level = 1; level < lastlevel; ++level) { + dirpyr_channel(dirpyrlo[level - 1], dirpyrlo[level], srcwidth, srcheight, level, std::max(scales[level] / scaleprev, 1)); + } + + // with the current implementation of idirpyr_eq_channel we can safely use the buffer from last level as buffer, saves some memory + float ** buffer = dirpyrlo[lastlevel - 1]; + + for (int level = lastlevel - 1; level > 0; --level) { + idirpyr_eq_channelcam(dirpyrlo[level], dirpyrlo[level - 1], buffer, srcwidth, srcheight, level, multi[level], dirpyrThreshold , h_p, C_p, skinprot, b_l, t_l, t_r); + } + + idirpyr_eq_channelcam(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi[0], dirpyrThreshold, h_p, C_p, skinprot, b_l, t_l, t_r); + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int i = 0; i < srcheight; i++) { + for (int j = 0; j < srcwidth; j++) { + if (ncie->J_p[i][j] > 8.f && ncie->J_p[i][j] < 92.f) { + dst[i][j] = buffer[i][j]; + } else { + dst[i][j] = src[i][j]; + } + } + } } +} diff --git a/rtengine/ex1simple.cc b/rtengine/ex1simple.cc deleted file mode 100644 index ddaa89177..000000000 --- a/rtengine/ex1simple.cc +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * 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 "rtengine.h" -#include -//#include -#include - -class PListener : - public rtengine::ProgressListener -{ -public: - void setProgressStr(const Glib::ustring& str) - { - std::cout << str << std::endl; - } - void setProgress (double p) - { - std::cout << p << std::endl; - } - void setProgressState(bool inProcessing) - { - } - void error(const Glib::ustring& descr) - { - } -}; - -int main (int argc, char* argv[]) -{ - if (argc < 4) { - std::cout << "Usage: rtcmd " << std::endl; - exit(1); - } - - Glib::thread_init (); - - // create and fill settings - rtengine::Settings* s = rtengine::Settings::create (); - s->demosaicMethod = "hphd"; - s->colorCorrectionSteps = 2; - s->iccDirectory = ""; - s->colorimetricIntent = 1; - s->monitorProfile = ""; - // init rtengine - rtengine::init (s); - // the settings can be modified later through the "s" pointer without calling any api function - - // Create a listener object. Any class is appropriate that inherits from rtengine::ProgressListener - PListener pl; - - // Load the image given in the first command line parameter - rtengine::InitialImage* ii; - int errorCode; - ii = rtengine::InitialImage::load (argv[1], true, errorCode, &pl); - - if (!ii) { - ii = rtengine::InitialImage::load (argv[1], false, errorCode, &pl); - } - - if (!ii) { - std::cout << "Input file not supported." << std::endl; - exit(2); - } - - // create an instance of ProcParams structure that holds the image processing settings. You find the memory map in a separate file and the non-basic types like strings and vectors can be manipulated through helper functions - rtengine::procparams::ProcParams params; - params.load (argv[2]); - - /* First, simplest scenario. Develop image and save it in a file */ - // create a processing job with the loaded image and the current processing parameters - rtengine::ProcessingJob* job = ProcessingJob::create (i, params); - // process image. The error is given back in errorcode. - rtengine::IImage16* res = rtengine::processImage (job, errorCode, &pl); - // save image to disk - res->saveToFile (argv[3]); - // through "res" you can access width/height and pixel data, too -} - diff --git a/rtengine/ffmanager.cc b/rtengine/ffmanager.cc index 6e4977076..56660a82a 100644 --- a/rtengine/ffmanager.cc +++ b/rtengine/ffmanager.cc @@ -277,8 +277,8 @@ void FFManager::init(const Glib::ustring& pathname) } else { printf( "%s: MEAN of \n ", i.key().c_str()); - for( std::list::iterator iter = i.pathNames.begin(); iter != i.pathNames.end(); ++iter ) { - printf( "%s, ", iter->c_str() ); + for(std::list::iterator path = i.pathNames.begin(); path != i.pathNames.end(); ++path) { + printf("%s, ", path->c_str()); } printf("\n"); diff --git a/rtengine/helpersse2.h b/rtengine/helpersse2.h index 74780cf48..e8c489b04 100644 --- a/rtengine/helpersse2.h +++ b/rtengine/helpersse2.h @@ -29,7 +29,7 @@ typedef __m128 vfloat; typedef __m128i vint2; // -#define LVF(x) _mm_load_ps((float*)&x) +#define LVF(x) _mm_load_ps((const float*)&x) #define LVFU(x) _mm_loadu_ps(&x) #define STVF(x,y) _mm_store_ps(&x,y) #define STVFU(x,y) _mm_storeu_ps(&x,y) diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc index b0a7e6229..7134ac34f 100644 --- a/rtengine/hilite_recon.cc +++ b/rtengine/hilite_recon.cc @@ -970,8 +970,8 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue for (int c = 0; c < 3; ++c) { lab[i2][c] = 0; - for (int j = 0; j < 3; ++j) { - lab[i2][c] += trans[c][j] * cam[i2][j]; + for (int j2 = 0; j2 < 3; ++j2) { + lab[i2][c] += trans[c][j2] * cam[i2][j2]; } } @@ -996,8 +996,8 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue for (int c = 0; c < 3; ++c) { cam[0][c] = 0.f; - for (int j = 0; j < 3; ++j) { - cam[0][c] += itrans[c][j] * lab[0][j]; + for (int j2 = 0; j2 < 3; ++j2) { + cam[0][c] += itrans[c][j2] * lab[0][j2]; } } @@ -1081,12 +1081,11 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue //now correct clipped channels if (pixel[0] > max_f[0] && pixel[1] > max_f[1] && pixel[2] > max_f[2]) { //all channels clipped - const float Y = 0.299f * clipfix[0] + 0.587f * clipfix[1] + 0.114f * clipfix[2]; - const float factor = whitept / Y; - red[i + miny][j + minx] = clipfix[0] * factor; - green[i + miny][j + minx] = clipfix[1] * factor; - blue[i + miny][j + minx] = clipfix[2] * factor; + const float mult = whitept / (0.299f * clipfix[0] + 0.587f * clipfix[1] + 0.114f * clipfix[2]); + red[i + miny][j + minx] = clipfix[0] * mult; + green[i + miny][j + minx] = clipfix[1] * mult; + blue[i + miny][j + minx] = clipfix[2] * mult; } else {//some channels clipped const float notclipped[3] = { pixel[0] <= max_f[0] ? 1.f : 0.f, @@ -1113,11 +1112,11 @@ void RawImageSource::HLRecovery_inpaint(float** red, float** green, float** blue Y = 0.299f * red[i + miny][j + minx] + 0.587f * green[i + miny][j + minx] + 0.114f * blue[i + miny][j + minx]; if (Y > whitept) { - const float factor = whitept / Y; + const float mult = whitept / Y; - red[i + miny][j + minx] *= factor; - green[i + miny][j + minx] *= factor; - blue[i + miny][j + minx] *= factor; + red[i + miny][j + minx] *= mult; + green[i + miny][j + minx] *= mult; + blue[i + miny][j + minx] *= mult; } } } diff --git a/rtengine/histmatching.cc b/rtengine/histmatching.cc index e48f2017a..f9268ea5d 100644 --- a/rtengine/histmatching.cc +++ b/rtengine/histmatching.cc @@ -329,8 +329,8 @@ void RawImageSource::getAutoMatchedToneCurve(const ColorManagementParams &cp, st int tw = target->getWidth(), th = target->getHeight(); float thumb_ratio = float(std::max(sw, sh)) / float(std::min(sw, sh)); float target_ratio = float(std::max(tw, th)) / float(std::min(tw, th)); - int cx = 0, cy = 0; if (std::abs(thumb_ratio - target_ratio) > 0.01) { + int cx = 0, cy = 0; if (thumb_ratio > target_ratio) { // crop the height int ch = th - (tw * float(sh) / float(sw)); diff --git a/rtengine/image16.cc b/rtengine/image16.cc index c0e97557a..7d4d3e41d 100644 --- a/rtengine/image16.cc +++ b/rtengine/image16.cc @@ -74,7 +74,7 @@ void Image16::getScanline(int row, unsigned char* buffer, int bps, bool isFloat) } } -void Image16::setScanline(int row, unsigned char* buffer, int bps, unsigned int numSamples) +void Image16::setScanline(int row, const unsigned char* buffer, int bps, unsigned int numSamples) { if (data == nullptr) { @@ -101,7 +101,7 @@ void Image16::setScanline(int row, unsigned char* buffer, int bps, unsigned int } case (IIOSF_UNSIGNED_SHORT): { - unsigned short* sbuffer = (unsigned short*) buffer; + const unsigned short* sbuffer = (const unsigned short*) buffer; int ix = 0; for (int i = 0; i < width; ++i) { diff --git a/rtengine/image16.h b/rtengine/image16.h index 9762af990..f31626939 100644 --- a/rtengine/image16.h +++ b/rtengine/image16.h @@ -56,7 +56,7 @@ public: } void getScanline(int row, unsigned char* buffer, int bps, bool isFloat = false) const override; - void setScanline(int row, unsigned char* buffer, int bps, unsigned int numSamples) override; + void setScanline(int row, const unsigned char* buffer, int bps, unsigned int numSamples) override; // functions inherited from IImage16: MyMutex& getMutex() override diff --git a/rtengine/image8.cc b/rtengine/image8.cc index 513b0049e..850ec87c0 100644 --- a/rtengine/image8.cc +++ b/rtengine/image8.cc @@ -55,7 +55,7 @@ void Image8::getScanline (int row, unsigned char* buffer, int bps, bool isFloat) } } -void Image8::setScanline (int row, unsigned char* buffer, int bps, unsigned int numSamples) +void Image8::setScanline (int row, const unsigned char* buffer, int bps, unsigned int numSamples) { if (data == nullptr) { @@ -74,7 +74,7 @@ void Image8::setScanline (int row, unsigned char* buffer, int bps, unsigned int break; case (IIOSF_UNSIGNED_SHORT): { - unsigned short* sbuffer = (unsigned short*) buffer; + const unsigned short* sbuffer = (const unsigned short*) buffer; for (int i = 0, ix = row * width * 3; i < width * 3; ++i, ++ix) { data[ix] = uint16ToUint8Rounded(sbuffer[i]); diff --git a/rtengine/image8.h b/rtengine/image8.h index 8928cf85b..57852b7af 100644 --- a/rtengine/image8.h +++ b/rtengine/image8.h @@ -53,7 +53,7 @@ public: } void getScanline (int row, unsigned char* buffer, int bps, bool isFloat = false) const override; - void setScanline (int row, unsigned char* buffer, int bps, unsigned int numSamples) override; + void setScanline (int row, const unsigned char* buffer, int bps, unsigned int numSamples) override; // functions inherited from IImage*: MyMutex& getMutex () override diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index faa7ad5ed..b074cdbb2 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -258,7 +258,6 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* tag = exif->getTag("SubjectDistance"); if (tag) { - int num, denom; tag->toRational(num, denom); } else { // Second try, XMP data @@ -524,8 +523,7 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* focal_len = flt->toDouble (); } } else if ((flt = mnote->getTagP ("FocalLength"))) { - rtexif::Tag* flt = mnote->getTag ("FocalLength"); - focal_len = flt->toDouble (); + focal_len = mnote->getTag("FocalLength")->toDouble (); } if (mnote->getTag ("FocalLengthIn35mmFilm")) { diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h index d06820296..774547487 100644 --- a/rtengine/imagedata.h +++ b/rtengine/imagedata.h @@ -98,7 +98,7 @@ private: unsigned int dcrawFrameCount; public: - FramesData (const Glib::ustring& fname, std::unique_ptr rml = nullptr, bool firstFrameOnly = false); + explicit FramesData (const Glib::ustring& fname, std::unique_ptr rml = nullptr, bool firstFrameOnly = false); ~FramesData () override; void setDCRawFrameCount (unsigned int frameCount); diff --git a/rtengine/imagefloat.cc b/rtengine/imagefloat.cc index d98a817a2..793915604 100644 --- a/rtengine/imagefloat.cc +++ b/rtengine/imagefloat.cc @@ -45,7 +45,7 @@ Imagefloat::~Imagefloat () } // Call this method to handle floating points input values of different size -void Imagefloat::setScanline (int row, unsigned char* buffer, int bps, unsigned int numSamples) +void Imagefloat::setScanline (int row, const unsigned char* buffer, int bps, unsigned int numSamples) { if (data == nullptr) { @@ -58,7 +58,7 @@ void Imagefloat::setScanline (int row, unsigned char* buffer, int bps, unsigned switch (sampleFormat) { case (IIOSF_FLOAT16): { int ix = 0; - uint16_t* sbuffer = (uint16_t*) buffer; + const uint16_t* sbuffer = (const uint16_t*) buffer; for (int i = 0; i < width; i++) { r(row, i) = 65535.f * DNG_HalfToFloat(sbuffer[ix++]); @@ -71,7 +71,7 @@ void Imagefloat::setScanline (int row, unsigned char* buffer, int bps, unsigned //case (IIOSF_FLOAT24): case (IIOSF_FLOAT32): { int ix = 0; - float* sbuffer = (float*) buffer; + const float* sbuffer = (const float*) buffer; for (int i = 0; i < width; i++) { r(row, i) = 65535.f * sbuffer[ix++]; @@ -85,7 +85,7 @@ void Imagefloat::setScanline (int row, unsigned char* buffer, int bps, unsigned case (IIOSF_LOGLUV24): case (IIOSF_LOGLUV32): { int ix = 0; - float* sbuffer = (float*) buffer; + const float* sbuffer = (const float*) buffer; float xyzvalues[3], rgbvalues[3]; for (int i = 0; i < width; i++) { diff --git a/rtengine/imagefloat.h b/rtengine/imagefloat.h index e1e5086b8..805971e7a 100644 --- a/rtengine/imagefloat.h +++ b/rtengine/imagefloat.h @@ -62,7 +62,7 @@ public: } void getScanline (int row, unsigned char* buffer, int bps, bool isFloat = false) const override; - void setScanline (int row, unsigned char* buffer, int bps, unsigned int numSamples) override; + void setScanline (int row, const unsigned char* buffer, int bps, unsigned int numSamples) override; // functions inherited from IImagefloat: MyMutex& getMutex () override diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc index 3b0fdcf6d..1e4f8c008 100644 --- a/rtengine/imageio.cc +++ b/rtengine/imageio.cc @@ -89,7 +89,7 @@ void ImageIO::setMetadata (const rtexif::TagDirectory* eroot) } if (eroot) { - rtexif::TagDirectory* td = ((rtexif::TagDirectory*)eroot)->clone (nullptr); + rtexif::TagDirectory* td = eroot->clone (nullptr); // make IPTC and XMP pass through td->keepTag(0x83bb); // IPTC @@ -113,7 +113,7 @@ void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const rtengine::pr } if (eroot) { - exifRoot = ((rtexif::TagDirectory*)eroot)->clone (nullptr); + exifRoot = eroot->clone (nullptr); } if (iptc != nullptr) { @@ -140,7 +140,7 @@ void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const rtengine::pr for (unsigned int j = 0; j < i->second.size(); j++) { IptcDataSet * ds = iptc_dataset_new (); iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, IPTC_TAG_KEYWORDS); - iptc_dataset_set_data (ds, (unsigned char*)i->second.at(j).c_str(), min(static_cast(64), i->second.at(j).bytes()), IPTC_DONT_VALIDATE); + iptc_dataset_set_data (ds, (const unsigned char*)i->second.at(j).c_str(), min(static_cast(64), i->second.at(j).bytes()), IPTC_DONT_VALIDATE); iptc_data_add_dataset (iptc, ds); iptc_dataset_unref (ds); } @@ -150,7 +150,7 @@ void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const rtengine::pr for (unsigned int j = 0; j < i->second.size(); j++) { IptcDataSet * ds = iptc_dataset_new (); iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, IPTC_TAG_SUPPL_CATEGORY); - iptc_dataset_set_data (ds, (unsigned char*)i->second.at(j).c_str(), min(static_cast(32), i->second.at(j).bytes()), IPTC_DONT_VALIDATE); + iptc_dataset_set_data (ds, (const unsigned char*)i->second.at(j).c_str(), min(static_cast(32), i->second.at(j).bytes()), IPTC_DONT_VALIDATE); iptc_data_add_dataset (iptc, ds); iptc_dataset_unref (ds); } @@ -162,7 +162,7 @@ void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const rtengine::pr if (i->first == strTags[j].field && !(i->second.empty())) { IptcDataSet * ds = iptc_dataset_new (); iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, strTags[j].tag); - iptc_dataset_set_data (ds, (unsigned char*)i->second.at(0).c_str(), min(strTags[j].size, i->second.at(0).bytes()), IPTC_DONT_VALIDATE); + iptc_dataset_set_data (ds, (const unsigned char*)i->second.at(0).c_str(), min(strTags[j].size, i->second.at(0).bytes()), IPTC_DONT_VALIDATE); iptc_data_add_dataset (iptc, ds); iptc_dataset_unref (ds); } @@ -910,12 +910,12 @@ int ImageIO::loadPPMFromMemory(const char* buffer, int width, int height, bool s char swapped[line_length]; for ( int row = 0; row < height; ++row ) { - ::rtengine::swab(((char*)buffer) + (row * line_length), swapped, line_length); + ::rtengine::swab(((const char*)buffer) + (row * line_length), swapped, line_length); setScanline(row, (unsigned char*)&swapped[0], bps); } } else { for ( int row = 0; row < height; ++row ) { - setScanline(row, ((unsigned char*)buffer) + (row * line_length), bps); + setScanline(row, ((const unsigned char*)buffer) + (row * line_length), bps); } } diff --git a/rtengine/imageio.h b/rtengine/imageio.h index 05a11655a..fd2cbc2b9 100644 --- a/rtengine/imageio.h +++ b/rtengine/imageio.h @@ -81,7 +81,7 @@ public: virtual void getStdImage (const ColorTemp &ctemp, int tran, Imagefloat* image, PreviewProps pp) const = 0; virtual int getBPS () const = 0; virtual void getScanline (int row, unsigned char* buffer, int bps, bool isFloat = false) const = 0; - virtual void setScanline (int row, unsigned char* buffer, int bps, unsigned int numSamples = 3) = 0; + virtual void setScanline (int row, const unsigned char* buffer, int bps, unsigned int numSamples = 3) = 0; virtual const char* getType () const = 0; int load (const Glib::ustring &fname); diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 8d9c6a052..ad028fe63 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -1720,7 +1720,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int pW, int pw float t_l = static_cast (params->dirpyrequalizer.hueskin.getTopLeft()) / 100.0f; float t_r = static_cast (params->dirpyrequalizer.hueskin.getTopRight()) / 100.0f; lab->deleteLab(); - dirpyr_equalizercam (ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, true, b_l, t_l, t_r, scale); //contrast by detail adapted to CIECAM + dirpyr_equalizercam (ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, b_l, t_l, t_r, scale); //contrast by detail adapted to CIECAM lab->reallocLab(); } @@ -2255,7 +2255,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer bool hasColorToningLabGrid = params->colorToning.enabled && params->colorToning.method == "LabGrid"; // float satLimit = float(params->colorToning.satProtectionThreshold)/100.f*0.7f+0.3f; // float satLimitOpacity = 1.f-(float(params->colorToning.saturatedOpacity)/100.f); - float strProtect = (float (params->colorToning.strength) / 100.f); + float strProtect = pow_F((float (params->colorToning.strength) / 100.f), 0.4f); /* // Debug output - Color LUTf points @@ -2793,7 +2793,6 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer const float krh = rh / (rh + gh + bh); const float kgh = gh / (rh + gh + bh); const float kbh = bh / (rh + gh + bh); - strProtect = pow_F(strProtect, 0.4f); constexpr int mode = 0; for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { @@ -2806,7 +2805,6 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer else if (params->colorToning.method == "Splitco") { constexpr float reducac = 0.3f; constexpr int mode = 0; - strProtect = pow_F(strProtect, 0.4f); for (int i = istart, ti = 0; i < tH; i++, ti++) { for (int j = jstart, tj = 0; j < tW; j++, tj++) { const float r = rtemp[ti * TS + tj]; @@ -3483,7 +3481,6 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer const float krh = rh / (rh + gh + bh); const float kgh = gh / (rh + gh + bh); const float kbh = bh / (rh + gh + bh); - strProtect = pow_F(strProtect, 0.4f); constexpr int mode = 1; #ifdef _OPENMP #pragma omp parallel for schedule(dynamic, 5) @@ -3789,11 +3786,12 @@ void ImProcFunctions::toningsmh(float r, float g, float b, float &ro, float &go, { const float corr = 20000.f * RedLow * kl * rlo; + if (RedLow > 0.f) { + r += corr; + } else { g -= corr; b -= corr; - } else { - r += corr; } // r = CLIP(r); @@ -3803,27 +3801,28 @@ void ImProcFunctions::toningsmh(float r, float g, float b, float &ro, float &go, { const float corr = 20000.f * GreenLow * kl * rlo; + if (GreenLow > 0.f) { + g += corr; + } else { r -= corr; b -= corr; - } else { - g += corr; } // r = CLIP(r); - // b = CLIP(b); // g = CLIP(g); + // b = CLIP(b); } { - const float corr = 20000.f * BlueLow * kl * rlob; + const float corr = 20000.f * BlueLow * kl * rlo; if (BlueLow > 0.f) { + b += corr; + } else { r -= corr; g -= corr; - } else { - b += corr; } // r = CLIP(r); diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 68aff736b..24a5d60a8 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -200,7 +200,7 @@ public: double lumimul[3]; - ImProcFunctions(const ProcParams* iparams, bool imultiThread = true) + explicit ImProcFunctions(const ProcParams* iparams, bool imultiThread = true) : monitorTransform(nullptr), params(iparams), scale(1), multiThread(imultiThread), lumimul{} {} ~ImProcFunctions(); bool needsLuminanceOnly() @@ -332,11 +332,8 @@ public: float MadRgb(const float * DataList, int datalen); // pyramid wavelet - void dirpyr_equalizer(float ** src, float ** dst, int srcwidth, int srcheight, float ** l_a, float ** l_b, const double * mult, const double dirpyrThreshold, const double skinprot, float b_l, float t_l, float t_r, int scale); //Emil's directional pyramid wavelet - void dirpyr_equalizercam(CieImage* ncie, float ** src, float ** dst, int srcwidth, int srcheight, float ** h_p, float ** C_p, const double * mult, const double dirpyrThreshold, const double skinprot, bool execdir, float b_l, float t_l, float t_r, int scale); //Emil's directional pyramid wavelet - void dirpyr_channel(float ** data_fine, float ** data_coarse, int width, int height, int level, int scale); - void idirpyr_eq_channel(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float multi[6], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, const double skinprot, float b_l, float t_l, float t_r); - void idirpyr_eq_channelcam(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float multi[6], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, const double skinprot, float b_l, float t_l, float t_r); + void dirpyr_equalizer(const float * const * src, float ** dst, int srcwidth, int srcheight, const float * const * l_a, const float * const * l_b, const double * mult, double dirpyrThreshold, double skinprot, float b_l, float t_l, float t_r, int scale); //Emil's directional pyramid wavelet + void dirpyr_equalizercam(const CieImage* ncie, float ** src, float ** dst, int srcwidth, int srcheight, const float * const * h_p, const float * const * C_p, const double * mult, const double dirpyrThreshold, const double skinprot, float b_l, float t_l, float t_r, int scale); //Emil's directional pyramid wavelet void defringe(LabImage* lab); void defringecam(CieImage* ncie); void badpixcam(CieImage* ncie, double rad, int thr, int mode, float chrom, bool hotbad); diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index c1092e335..42a5f92b3 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -228,12 +228,12 @@ void ImProcFunctions::dehaze(Imagefloat *img) array2D dark(W, H); int patchsize = max(int(5 / scale), 2); - int npatches = 0; float ambient[3]; array2D &t_tilde = dark; float max_t = 0.f; { + int npatches = 0; array2D R(W, H); array2D G(W, H); array2D B(W, H); diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc index 8790f003c..8b5a2cb71 100644 --- a/rtengine/iplab2rgb.cc +++ b/rtengine/iplab2rgb.cc @@ -356,24 +356,19 @@ void ImProcFunctions::workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, { const TMatrix wprof = ICCStore::getInstance()->workingSpaceMatrix(params->icm.workingProfile); - double dx = Color::D50x; - double dz = Color::D50z; - { - dx = dz = 1.0; - } const float toxyz[3][3] = { { - static_cast(wprof[0][0] / (dx * (normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50x - static_cast(wprof[0][1] / (dx * (normalizeIn ? 65535.0 : 1.0))), - static_cast(wprof[0][2] / (dx * (normalizeIn ? 65535.0 : 1.0))) + static_cast(wprof[0][0] / ((normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50x + static_cast(wprof[0][1] / ((normalizeIn ? 65535.0 : 1.0))), + static_cast(wprof[0][2] / ((normalizeIn ? 65535.0 : 1.0))) }, { static_cast(wprof[1][0] / (normalizeIn ? 65535.0 : 1.0)), static_cast(wprof[1][1] / (normalizeIn ? 65535.0 : 1.0)), static_cast(wprof[1][2] / (normalizeIn ? 65535.0 : 1.0)) }, { - static_cast(wprof[2][0] / (dz * (normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50z - static_cast(wprof[2][1] / (dz * (normalizeIn ? 65535.0 : 1.0))), - static_cast(wprof[2][2] / (dz * (normalizeIn ? 65535.0 : 1.0))) + static_cast(wprof[2][0] / ((normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50z + static_cast(wprof[2][1] / ((normalizeIn ? 65535.0 : 1.0))), + static_cast(wprof[2][2] / ((normalizeIn ? 65535.0 : 1.0))) } }; diff --git a/rtengine/ipresize.cc b/rtengine/ipresize.cc index 823beb23e..2a66e68cb 100644 --- a/rtengine/ipresize.cc +++ b/rtengine/ipresize.cc @@ -186,8 +186,8 @@ void ImProcFunctions::Lanczos (const Imagefloat* src, Imagefloat* dst, float sca void ImProcFunctions::Lanczos (const LabImage* src, LabImage* dst, float scale) { const float delta = 1.0f / scale; - const float a = 3.0f; - const float sc = min (scale, 1.0f); + constexpr float a = 3.0f; + const float sc = min(scale, 1.0f); const int support = static_cast (2.0f * a / sc) + 1; // storage for precomputed parameters for horizontal interpolation @@ -268,66 +268,61 @@ void ImProcFunctions::Lanczos (const LabImage* src, LabImage* dst, float scale) } // Do vertical interpolation. Store results. + int j = 0; #ifdef __SSE2__ - int j; __m128 Lv, av, bv, wkv; for (j = 0; j < src->W - 3; j += 4) { - Lv = _mm_setzero_ps(); - av = _mm_setzero_ps(); - bv = _mm_setzero_ps(); + Lv = ZEROV; + av = ZEROV; + bv = ZEROV; for (int ii = ii0; ii < ii1; ii++) { int k = ii - ii0; - wkv = _mm_set1_ps (w[k]); - Lv += wkv * LVFU (src->L[ii][j]); - av += wkv * LVFU (src->a[ii][j]); - bv += wkv * LVFU (src->b[ii][j]); + wkv = F2V(w[k]); + Lv += wkv * LVFU(src->L[ii][j]); + av += wkv * LVFU(src->a[ii][j]); + bv += wkv * LVFU(src->b[ii][j]); } - STVF (lL[j], Lv); - STVF (la[j], av); - STVF (lb[j], bv); + STVF(lL[j], Lv); + STVF(la[j], av); + STVF(lb[j], bv); } - -#else - int j = 0; #endif - for (; j < src->W; j++) { - float L = 0.0f, a = 0.0f, b = 0.0f; + for (; j < src->W; ++j) { + float Ll = 0.0f, La = 0.0f, Lb = 0.0f; - for (int ii = ii0; ii < ii1; ii++) { + for (int ii = ii0; ii < ii1; ++ii) { int k = ii - ii0; - L += w[k] * src->L[ii][j]; - a += w[k] * src->a[ii][j]; - b += w[k] * src->b[ii][j]; + Ll += w[k] * src->L[ii][j]; + La += w[k] * src->a[ii][j]; + Lb += w[k] * src->b[ii][j]; } - lL[j] = L; - la[j] = a; - lb[j] = b; + lL[j] = Ll; + la[j] = La; + lb[j] = Lb; } // Do horizontal interpolation - for (int j = 0; j < dst->W; j++) { + for (int x = 0; x < dst->W; ++x) { + float * wh = wwh + support * x; + float Ll = 0.0f, La = 0.0f, Lb = 0.0f; - float * wh = wwh + support * j; + for (int jj = jj0[x]; jj < jj1[x]; ++jj) { + int k = jj - jj0[x]; - float L = 0.0f, a = 0.0f, b = 0.0f; - - for (int jj = jj0[j]; jj < jj1[j]; jj++) { - int k = jj - jj0[j]; - - L += wh[k] * lL[jj]; - a += wh[k] * la[jj]; - b += wh[k] * lb[jj]; + Ll += wh[k] * lL[jj]; + La += wh[k] * la[jj]; + Lb += wh[k] * lb[jj]; } - dst->L[i][j] = L; - dst->a[i][j] = a; - dst->b[i][j] = b; + dst->L[i][x] = Ll; + dst->a[i][x] = La; + dst->b[i][x] = Lb; } } } diff --git a/rtengine/ipshadowshighlights.cc b/rtengine/ipshadowshighlights.cc index 96b8e84ef..ed0d2464b 100644 --- a/rtengine/ipshadowshighlights.cc +++ b/rtengine/ipshadowshighlights.cc @@ -106,10 +106,10 @@ void ImProcFunctions::shadowsHighlights(LabImage *lab, bool ena, int labmode, in #pragma omp parallel for if (multiThread) #endif for (int l = 0; l < 32768; ++l) { - auto base = pow_F(l / 32768.f, gamma); + auto val = pow_F(l / 32768.f, gamma); // get a bit more contrast in the shadows - base = sh_contrast.getVal(base); - f[l] = base * 32768.f; + val = sh_contrast.getVal(val); + f[l] = val * 32768.f; } } else { #ifdef _OPENMP @@ -119,10 +119,10 @@ void ImProcFunctions::shadowsHighlights(LabImage *lab, bool ena, int labmode, in float l, a, b; float R = c, G = c, B = c; rgb2lab(R, G, B, l, a, b); - auto base = pow_F(l / 32768.f, gamma); + auto val = pow_F(l / 32768.f, gamma); // get a bit more contrast in the shadows - base = sh_contrast.getVal(base); - l = base * 32768.f; + val = sh_contrast.getVal(val); + l = val * 32768.f; lab2rgb(l, a, b, R, G, B); f[c] = G; } @@ -133,8 +133,8 @@ void ImProcFunctions::shadowsHighlights(LabImage *lab, bool ena, int labmode, in #pragma omp parallel for if (multiThread) #endif for (int l = 0; l < 32768; ++l) { - auto base = pow_F(l / 32768.f, gamma); - f[l] = base * 32768.f; + auto val = pow_F(l / 32768.f, gamma); + f[l] = val * 32768.f; } } else { #ifdef _OPENMP @@ -144,8 +144,8 @@ void ImProcFunctions::shadowsHighlights(LabImage *lab, bool ena, int labmode, in float l, a, b; float R = c, G = c, B = c; rgb2lab(R, G, B, l, a, b); - auto base = pow_F(l / 32768.f, gamma); - l = base * 32768.f; + auto val = pow_F(l / 32768.f, gamma); + l = val * 32768.f; lab2rgb(l, a, b, R, G, B); f[c] = G; } diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index beca624a8..5b1e7c458 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -435,12 +435,7 @@ static void calcGradientParams (int oW, int oH, const GradientParams& gradient, if (gp.transpose) { gp.bright_top = !gp.bright_top; - } - - if (gp.transpose) { - int tmp = w; - w = h; - h = tmp; + std::swap(w, h); } gp.scale = 1.0 / pow (2, gradient_stops); diff --git a/rtengine/lcp.cc b/rtengine/lcp.cc index 7156f17e2..cf025ddbe 100644 --- a/rtengine/lcp.cc +++ b/rtengine/lcp.cc @@ -234,8 +234,6 @@ rtengine::LCPProfile::LCPProfile(const Glib::ustring& fname) : pCurCommon(nullptr), aPersModel{} { - const int BufferSize = 8192; - char buf[BufferSize]; XML_Parser parser = XML_ParserCreate(nullptr); @@ -250,6 +248,8 @@ rtengine::LCPProfile::LCPProfile(const Glib::ustring& fname) : FILE* const pFile = g_fopen(fname.c_str (), "rb"); if (pFile) { + constexpr int BufferSize = 8192; + char buf[BufferSize]; bool done; do { @@ -362,9 +362,8 @@ void rtengine::LCPProfile::calcParams( const float focDist = aPersModel[pm]->focDist; const float focDistLog = std::log(focDist) + euler; - double meanErr = 0.0; - if (aPersModel[pm]->hasModeData(mode)) { + double meanErr = 0.0; double lowMeanErr = 0.0; double highMeanErr = 0.0; diff --git a/rtengine/mytime.h b/rtengine/mytime.h index f73d563d2..a0ce15bc7 100644 --- a/rtengine/mytime.h +++ b/rtengine/mytime.h @@ -16,8 +16,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#ifndef _MYTIME_ -#define _MYTIME_ +#pragma once #ifdef WIN32 #include @@ -58,11 +57,11 @@ public: t.tv_sec = tv.tv_sec; t.tv_nsec = tv.tv_usec * 1000; #else - clock_gettime (CLOCK_REALTIME, &t); + clock_gettime(CLOCK_REALTIME, &t); #endif } - int etime (MyTime a) + int etime (const MyTime &a) const { #ifndef WIN32 return (t.tv_sec - a.t.tv_sec) * 1000000 + (t.tv_nsec - a.t.tv_nsec) / 1000; @@ -71,6 +70,3 @@ public: #endif } }; - - -#endif diff --git a/rtengine/pdaflinesfilter.h b/rtengine/pdaflinesfilter.h index b1f7bf650..3ae406ec8 100644 --- a/rtengine/pdaflinesfilter.h +++ b/rtengine/pdaflinesfilter.h @@ -20,12 +20,14 @@ #pragma once -#include "rawimagesource.h" #include +#include "rawimagesource.h" +#include "noncopyable.h" namespace rtengine { -class PDAFLinesFilter { +class PDAFLinesFilter: public rtengine::NonCopyable +{ public: explicit PDAFLinesFilter(RawImage *ri); ~PDAFLinesFilter(); diff --git a/rtengine/pipettebuffer.cc b/rtengine/pipettebuffer.cc index 34a52a5c0..4ad8afad1 100644 --- a/rtengine/pipettebuffer.cc +++ b/rtengine/pipettebuffer.cc @@ -176,9 +176,11 @@ void PipetteBuffer::getPipetteData(int x, int y, const int squareSize) } } - dataProvider->setPipetteVal1(-1.f); - dataProvider->setPipetteVal2(-1.f); - dataProvider->setPipetteVal3(-1.f); + if (dataProvider) { + dataProvider->setPipetteVal1(-1.f); + dataProvider->setPipetteVal2(-1.f); + dataProvider->setPipetteVal3(-1.f); + } } } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 87720dee6..165187e6f 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -65,7 +65,7 @@ Glib::ustring relativePathIfInside(const Glib::ustring &procparams_fname, bool f return embedded_fname; } - Glib::ustring prefix = ""; + Glib::ustring prefix; if (embedded_fname.length() > 5 && embedded_fname.substr(0, 5) == "file:") { embedded_fname = embedded_fname.substr(5); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 4b115755f..0dbfb0d95 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1644,8 +1644,8 @@ class PartialProfile : { public: PartialProfile(bool createInstance = false, bool paramsEditedValue = false); - PartialProfile(ProcParams* pp, ParamsEdited* pe = nullptr, bool fullCopy = false); - PartialProfile(const ProcParams* pp, const ParamsEdited* pe = nullptr); + explicit PartialProfile(ProcParams* pp, ParamsEdited* pe = nullptr, bool fullCopy = false); + explicit PartialProfile(const ProcParams* pp, const ParamsEdited* pe = nullptr); void deleteInstance(); void clearGeneral(); int load(const Glib::ustring& fName); diff --git a/rtengine/profilestore.cc b/rtengine/profilestore.cc index 437ef6ec6..776dd7caa 100644 --- a/rtengine/profilestore.cc +++ b/rtengine/profilestore.cc @@ -261,12 +261,12 @@ bool ProfileStore::parseDir (Glib::ustring& realPath, Glib::ustring& virtualPath return fileFound; } -int ProfileStore::findFolderId (const Glib::ustring &path) +int ProfileStore::findFolderId (const Glib::ustring &path) const { // initialization must have been done when calling this - for (std::vector::iterator i = folders.begin(); i != folders.end(); ++i) { - if (*i == path) { - return i - folders.begin(); + for (size_t i = 0; i < folders.size(); ++i) { + if (folders[i] == path) { + return i; } } @@ -454,7 +454,7 @@ const PartialProfile* ProfileStore::getDefaultPartialProfile (bool isRaw) return pProf; } -const Glib::ustring ProfileStore::getPathFromId (int folderId) +const Glib::ustring ProfileStore::getPathFromId (int folderId) const { // initialization must have been done when calling this return folders.at (folderId); @@ -535,7 +535,7 @@ PartialProfile *ProfileStore::loadDynamicProfile (const FramesMetaData *im) return ret; } -ProfileStoreEntry::ProfileStoreEntry() : label (""), type (PSET_FOLDER), parentFolderId (0), folderId (0) {} +ProfileStoreEntry::ProfileStoreEntry() : type (PSET_FOLDER), parentFolderId (0), folderId (0) {} ProfileStoreEntry::ProfileStoreEntry (Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder) : label (label), type (type), parentFolderId (parentFolder), folderId (folder) {} diff --git a/rtengine/profilestore.h b/rtengine/profilestore.h index 5b4c94b20..d8c193935 100644 --- a/rtengine/profilestore.h +++ b/rtengine/profilestore.h @@ -185,7 +185,7 @@ public: bool init (bool loadAll = true); void parseProfiles (); - int findFolderId (const Glib::ustring &path); + int findFolderId (const Glib::ustring &path) const; const ProfileStoreEntry* findEntryFromFullPath (Glib::ustring path); const rtengine::procparams::PartialProfile* getProfile (Glib::ustring path); const rtengine::procparams::PartialProfile* getProfile (const ProfileStoreEntry* entry); @@ -193,13 +193,13 @@ public: void releaseFileList (); const rtengine::procparams::ProcParams* getDefaultProcParams (bool isRaw); const rtengine::procparams::PartialProfile* getDefaultPartialProfile (bool isRaw); - const Glib::ustring getPathFromId (int folderId); - const ProfileStoreEntry* getInternalDefaultPSE() + const Glib::ustring getPathFromId (int folderId) const; + const ProfileStoreEntry* getInternalDefaultPSE() const { return internalDefaultEntry; } - const ProfileStoreEntry* getInternalDynamicPSE() + const ProfileStoreEntry* getInternalDynamicPSE() const { return internalDynamicEntry; } diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 9f310508f..e8eb17c31 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -429,6 +429,7 @@ RawImageSource::RawImageSource () , plistener(nullptr) , scale_mul{} , c_black{} + , c_white{} , cblacksom{} , ref_pre_mul{} , refwb_red(0.0) @@ -4930,9 +4931,7 @@ void RawImageSource::getRawValues(int x, int y, int rotate, int &R, int &G, int ynew = H - 1 - ynew; } else if (rotate == 270) { std::swap(xnew,ynew); - ynew = H - 1 - ynew; xnew = W - 1 - xnew; - ynew = H - 1 - ynew; } xnew = LIM(xnew, 0, W - 1); diff --git a/rtengine/rcd_demosaic.cc b/rtengine/rcd_demosaic.cc index 904daea71..95c5b4792 100644 --- a/rtengine/rcd_demosaic.cc +++ b/rtengine/rcd_demosaic.cc @@ -49,11 +49,11 @@ void RawImageSource::rcd_demosaic(size_t chunkSize, bool measure) stop.reset(new StopWatch("rcd demosaic")); } - volatile double progress = 0.0; + double progress = 0.0; if (plistener) { plistener->setProgressStr(Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), M("TP_RAW_RCD"))); - plistener->setProgress(0); + plistener->setProgress(progress); } constexpr int rcdBorder = 9; diff --git a/rtengine/rtetest.cc b/rtengine/rtetest.cc deleted file mode 100644 index bd81dbb0d..000000000 --- a/rtengine/rtetest.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of RawTherapee. - * - * Copyright (c) 2004-2010 Gabor Horvath - * - * 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 "rtengine.h" -#include -//#include -#include - -class PListener : - public rtengine::ProgressListener -{ -public: - void setProgressStr(const Glib::ustring& str) - { - std::cout << str << std::endl; - } - void setProgress(double p) - { - std::cout << p << std::endl; - } - void setProgressState(bool inProcessing) - { - } - void error(const Glib::ustring& descr) - { - } -}; - -int main (int argc, char* argv[]) -{ - if (argc < 4) { - std::cout << "Usage: rtcmd " << std::endl; - exit(1); - } - - rtengine::Settings s; - s.demosaicMethod = "hphd"; - s.colorCorrectionSteps = 2; - s.iccDirectory = ""; - s.colorimetricIntent = 1; - s.monitorProfile = ""; - - Glib::thread_init (); - rtengine::init (s, ""); - PListener pl; - - rtengine::InitialImage* ii; - int errorCode; - ii = rtengine::InitialImage::load (argv[1], true, errorCode, &pl); - - if (!ii) { - ii = rtengine::InitialImage::load (argv[1], false, errorCode, &pl); - } - - if (!ii) { - std::cout << "Input file not supported." << std::endl; - exit(2); - } - - rtengine::procparams::ProcParams params; - params.load (argv[2]); - - rtengine::ProcessingJob* job = ProcessingJob::create (ii, params); - rtengine::IImage16* res = rtengine::processImage (job, errorCode, &pl); - res->saveToFile (argv[3]); -} - diff --git a/rtengine/rtlensfun.cc b/rtengine/rtlensfun.cc index 3cea8c484..5f0ffdd91 100644 --- a/rtengine/rtlensfun.cc +++ b/rtengine/rtlensfun.cc @@ -132,7 +132,7 @@ Glib::ustring LFModifier::getDisplayString() const return "NONE"; } else { Glib::ustring ret; - Glib::ustring sep = ""; + Glib::ustring sep; if (flags_ & LF_MODIFY_DISTORTION) { ret += "distortion"; sep = ", "; diff --git a/rtengine/tmo_fattal02.cc b/rtengine/tmo_fattal02.cc index 32755319e..76da1f03d 100644 --- a/rtengine/tmo_fattal02.cc +++ b/rtengine/tmo_fattal02.cc @@ -476,14 +476,14 @@ void tmo_fattal02 (size_t width, Array2Df* H = new Array2Df (width, height); float temp = 100.f / maxLum; - float eps = 1e-4f; #ifdef _OPENMP #pragma omp parallel if(multithread) #endif { + const float eps = 1e-4f; #ifdef __SSE2__ - vfloat epsv = F2V (eps); - vfloat tempv = F2V (temp); + const vfloat epsv = F2V(eps); + const vfloat tempv = F2V(temp); #endif #ifdef _OPENMP #pragma omp for schedule(dynamic,16) @@ -926,13 +926,13 @@ void solve_pde_fft (Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread)/* // a solution which has no positive values: U_new(x,y)=U(x,y)-max // (not really needed but good for numerics as we later take exp(U)) //DEBUG_STR << "solve_pde_fft: removing constant from solution" << std::endl; - float max = 0.f; + float maxVal = 0.f; #ifdef _OPENMP - #pragma omp parallel for reduction(max:max) if(multithread) + #pragma omp parallel for reduction(max:maxVal) if(multithread) #endif for (int i = 0; i < width * height; i++) { - max = std::max (max, (*U) (i)); + maxVal = std::max(maxVal, (*U)(i)); } #ifdef _OPENMP @@ -940,7 +940,7 @@ void solve_pde_fft (Array2Df *F, Array2Df *U, Array2Df *buf, bool multithread)/* #endif for (int i = 0; i < width * height; i++) { - (*U) (i) -= max; + (*U) (i) -= maxVal; } } diff --git a/rtengine/xtrans_demosaic.cc b/rtengine/xtrans_demosaic.cc index cd925fc33..866bc9714 100644 --- a/rtengine/xtrans_demosaic.cc +++ b/rtengine/xtrans_demosaic.cc @@ -39,9 +39,9 @@ const float d65_white[3] = { 0.950456, 1, 1.088754 }; void RawImageSource::cielab (const float (*rgb)[3], float* l, float* a, float *b, const int width, const int height, const int labWidth, const float xyz_cam[3][3]) { static LUTf cbrt(0x14000); - static bool cbrtinit = false; if (!rgb) { + static bool cbrtinit = false; if(!cbrtinit) { #pragma omp parallel for for (int i = 0; i < 0x14000; i++) { @@ -291,8 +291,6 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab, #endif { int progressCounter = 0; - int c; - float color[3][6]; float *buffer = (float *) malloc ((ts * ts * (ndir * 4 + 3) + 128) * sizeof(float)); float (*rgb)[ts][ts][3] = (float(*)[ts][ts][3]) buffer; @@ -521,6 +519,7 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab, /* Interpolate red and blue values for solitary green pixels: */ int sgstartcol = (left - sgcol + 4) / 3 * 3 + sgcol; + float color[3][6]; for (int row = (top - sgrow + 4) / 3 * 3 + sgrow; row < mrow - 2; row += 3) { for (int col = sgstartcol, h = fcol(row, col + 1); col < mcol - 2; col += 3, h ^= 2) { @@ -564,7 +563,7 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab, } int coloffset = (RightShift[row % 3] == 1 ? 3 : 1); - c = (row - sgrow) % 3 ? ts : 1; + int c = ((row - sgrow) % 3) ? ts : 1; int h = 3 * (c ^ ts ^ 1); if(coloffset == 3) { @@ -629,13 +628,13 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab, if (hex[d] + hex[d + 1]) { float g = 3 * rix[0][1] - 2 * rix[hex[d]][1] - rix[hex[d + 1]][1]; - for (c = 0; c < 4; c += 2) { + for (int c = 0; c < 4; c += 2) { rix[0][c] = CLIP((g + 2 * rix[hex[d]][c] + rix[hex[d + 1]][c]) * 0.33333333f); } } else { float g = 2 * rix[0][1] - rix[hex[d]][1] - rix[hex[d + 1]][1]; - for (c = 0; c < 4; c += 2) { + for (int c = 0; c < 4; c += 2) { rix[0][c] = CLIP((g + rix[hex[d]][c] + rix[hex[d + 1]][c]) * 0.5f); } } @@ -656,10 +655,7 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab, // (presumably coming from original AHD) and converts taking // camera matrix into account. We use this in RT. for (int d = 0; d < ndir; d++) { - float *l = &lab[0][0][0]; - float *a = &lab[1][0][0]; - float *b = &lab[2][0][0]; - cielab(&rgb[d][4][4], l, a, b, ts, mrow - 8, ts - 8, xyz_cam); + cielab(&rgb[d][4][4], &lab[0][0][0], &lab[1][0][0], &lab[2][0][0], ts, mrow - 8, ts - 8, xyz_cam); int f = dir[d & 3]; f = f == 1 ? 1 : f - 8; @@ -704,7 +700,7 @@ void RawImageSource::xtrans_interpolate (const int passes, const bool useCieLab, // which appears less good with specular highlights vfloat redv, greenv, bluev; vconvertrgbrgbrgbrgb2rrrrggggbbbb(rgb[d][row][col], redv, greenv, bluev); - vfloat yv = zd2627v * redv + zd6780v * bluev + zd0593v * greenv; + vfloat yv = zd2627v * redv + zd6780v * greenv + zd0593v * bluev; STVFU(yuv[0][row - 4][col - 4], yv); STVFU(yuv[1][row - 4][col - 4], (bluev - yv) * zd56433v); STVFU(yuv[2][row - 4][col - 4], (redv - yv) * zd67815v); diff --git a/rtexif/nikonattribs.cc b/rtexif/nikonattribs.cc index 1c6ead006..678b4b568 100644 --- a/rtexif/nikonattribs.cc +++ b/rtexif/nikonattribs.cc @@ -380,7 +380,7 @@ public: } } - std::string EffectiveMaxApertureString = ""; + std::string EffectiveMaxApertureString; if (!d100) { int EffectiveMaxApertureValue; diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc index 312cbd1c7..dcc0ed56d 100644 --- a/rtexif/rtexif.cc +++ b/rtexif/rtexif.cc @@ -673,7 +673,7 @@ int TagDirectory::calculateSize () return size; } -TagDirectory* TagDirectory::clone (TagDirectory* parent) +TagDirectory* TagDirectory::clone (TagDirectory* parent) const { TagDirectory* td = new TagDirectory (parent, attribs, order); @@ -857,7 +857,7 @@ TagDirectoryTable::TagDirectoryTable (TagDirectory* p, FILE* f, int memsize, int } } } -TagDirectory* TagDirectoryTable::clone (TagDirectory* parent) +TagDirectory* TagDirectoryTable::clone (TagDirectory* parent) const { TagDirectory* td = new TagDirectoryTable (parent, values, valuesSize, zeroOffset, defaultType, attribs, order); @@ -1382,7 +1382,7 @@ bool Tag::parseMakerNote (FILE* f, int base, ByteOrder bom ) return true; } -Tag* Tag::clone (TagDirectory* parent) +Tag* Tag::clone (TagDirectory* parent) const { Tag* t = new Tag (parent, attrib); @@ -1397,7 +1397,7 @@ Tag* Tag::clone (TagDirectory* parent) t->value = new unsigned char [valuesize]; memcpy (t->value, value, valuesize); } else { - value = nullptr; + t->value = nullptr; } t->makerNoteKind = makerNoteKind; diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h index 43b296746..0ee18ec7e 100644 --- a/rtexif/rtexif.h +++ b/rtexif/rtexif.h @@ -180,7 +180,7 @@ public: virtual int calculateSize (); virtual int write (int start, unsigned char* buffer); - virtual TagDirectory* clone (TagDirectory* parent); + virtual TagDirectory* clone (TagDirectory* parent) const; void applyChange (const std::string &field, const Glib::ustring &value); virtual void printAll (unsigned int level = 0) const; // reentrant debug function, keep level=0 on first call ! @@ -190,7 +190,7 @@ public: }; // a table of tags: id are offset from beginning and not identifiers -class TagDirectoryTable: public TagDirectory +class TagDirectoryTable: public TagDirectory, public rtengine::NonCopyable { protected: unsigned char *values; // Tags values are saved internally here @@ -204,7 +204,7 @@ public: ~TagDirectoryTable() override; int calculateSize () override; int write (int start, unsigned char* buffer) override; - TagDirectory* clone (TagDirectory* parent) override; + TagDirectory* clone (TagDirectory* parent) const override; }; // a class representing a single tag @@ -310,7 +310,7 @@ public: // functions for writing int calculateSize (); int write (int offs, int dataOffs, unsigned char* buffer); - Tag* clone (TagDirectory* parent); + Tag* clone (TagDirectory* parent) const; // to control if the tag shall be written bool getKeep () @@ -405,7 +405,6 @@ public: // Get the value as a double virtual double toDouble (const Tag* t, int ofs = 0) { - double ud, dd; switch (t->getType()) { case SBYTE: @@ -428,10 +427,11 @@ public: return (double) ((int)sget4 (t->getValue() + ofs, t->getOrder())); case SRATIONAL: - case RATIONAL: - ud = (int)sget4 (t->getValue() + ofs, t->getOrder()); - dd = (int)sget4 (t->getValue() + ofs + 4, t->getOrder()); - return dd == 0. ? 0. : (double)ud / (double)dd; + case RATIONAL: { + const double dividend = (int)sget4 (t->getValue() + ofs, t->getOrder()); + const double divisor = (int)sget4 (t->getValue() + ofs + 4, t->getOrder()); + return divisor == 0. ? 0. : dividend / divisor; + } case FLOAT: return double (sget4 (t->getValue() + ofs, t->getOrder())); diff --git a/rtgui/adjuster.cc b/rtgui/adjuster.cc index 0d2c2961f..5a3f783db 100644 --- a/rtgui/adjuster.cc +++ b/rtgui/adjuster.cc @@ -631,21 +631,21 @@ void Adjuster::setSliderValue(double val) if (val >= logPivot) { double range = vMax - logPivot; double x = (val - logPivot) / range; - val = (vMin + mid) + std::log(x * (logBase - 1.0) + 1.0) / std::log(logBase) * mid; + val = (vMin + mid) + std::log1p(x * (logBase - 1.0)) / std::log(logBase) * mid; } else { double range = logPivot - vMin; double x = (logPivot - val) / range; - val = (vMin + mid) - std::log(x * (logBase - 1.0) + 1.0) / std::log(logBase) * mid; + val = (vMin + mid) - std::log1p(x * (logBase - 1.0)) / std::log(logBase) * mid; } } else { if (val >= logPivot) { double range = vMax - logPivot; double x = (val - logPivot) / range; - val = logPivot + std::log(x * (logBase - 1.0) + 1.0) / std::log(logBase) * range; + val = logPivot + std::log1p(x * (logBase - 1.0)) / std::log(logBase) * range; } else { double range = logPivot - vMin; double x = (logPivot - val) / range; - val = logPivot - std::log(x * (logBase - 1.0) + 1.0) / std::log(logBase) * range; + val = logPivot - std::log1p(x * (logBase - 1.0)) / std::log(logBase) * range; } } } diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 239057b87..3fb2cd438 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -811,7 +811,7 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam break; } - Glib::ustring tok = ""; + Glib::ustring tok; while ((i < origFileName.size()) && !(origFileName[i] == '\\' || origFileName[i] == '/')) { tok = tok + origFileName[i++]; @@ -857,7 +857,7 @@ Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileNam // constructing full output path // printf ("path=|%s|\n", options.savePath.c_str()); - Glib::ustring path = ""; + Glib::ustring path; if (options.saveUsePathTemplate) { unsigned int ix = 0; diff --git a/rtgui/batchqueue.h b/rtgui/batchqueue.h index 95d92aef2..6f1b8f7f8 100644 --- a/rtgui/batchqueue.h +++ b/rtgui/batchqueue.h @@ -29,6 +29,7 @@ #include "options.h" #include "threadutils.h" #include "thumbbrowserbase.h" +#include "../rtengine/noncopyable.h" class BatchQueueListener { @@ -44,7 +45,8 @@ class FileCatalog; class BatchQueue final : public ThumbBrowserBase, public rtengine::BatchProcessingListener, - public LWButtonListener + public LWButtonListener, + public rtengine::NonCopyable { public: explicit BatchQueue (FileCatalog* aFileCatalog); diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc index 23982095c..78e3991c7 100644 --- a/rtgui/batchqueueentry.cc +++ b/rtgui/batchqueueentry.cc @@ -40,7 +40,6 @@ BatchQueueEntry::BatchQueueEntry (rtengine::ProcessingJob* pjob, const rtengine: job(pjob), params(new rtengine::procparams::ProcParams(pparams)), progress(0), - outFileName(""), sequence(0), forceFormatOpts(false), fast_pipeline(job->fastPipeline()), diff --git a/rtgui/batchqueueentry.h b/rtgui/batchqueueentry.h index 0ea56e403..4972eaf7a 100644 --- a/rtgui/batchqueueentry.h +++ b/rtgui/batchqueueentry.h @@ -26,6 +26,7 @@ #include "thumbbrowserentrybase.h" #include "thumbnail.h" #include "bqentryupdater.h" +#include "../rtengine/noncopyable.h" class BatchQueueEntry; struct BatchQueueEntryIdleHelper { @@ -34,7 +35,7 @@ struct BatchQueueEntryIdleHelper { int pending; }; -class BatchQueueEntry : public ThumbBrowserEntryBase, public BQEntryUpdateListener +class BatchQueueEntry : public ThumbBrowserEntryBase, public BQEntryUpdateListener, public rtengine::NonCopyable { guint8* opreview; diff --git a/rtgui/bqentryupdater.cc b/rtgui/bqentryupdater.cc index f5adf56f9..46aedc869 100644 --- a/rtgui/bqentryupdater.cc +++ b/rtgui/bqentryupdater.cc @@ -100,13 +100,12 @@ void BatchQueueEntryUpdater::processThread () break; } - rtengine::IImage8* img = nullptr; bool newBuffer = false; if (current.thumbnail && current.pparams) { // the thumbnail and the pparams are provided, it means that we have to build the original preview image double tmpscale; - img = current.thumbnail->processThumbImage (*current.pparams, current.oh, tmpscale); + rtengine::IImage8* img = current.thumbnail->processThumbImage (*current.pparams, current.oh, tmpscale); //current.thumbnail->decreaseRef (); // WARNING: decreasing refcount (and maybe deleting) thumbnail, with or without processed image if (img) { diff --git a/rtgui/browserfilter.cc b/rtgui/browserfilter.cc index ab4c843a4..cd3af072e 100644 --- a/rtgui/browserfilter.cc +++ b/rtgui/browserfilter.cc @@ -19,11 +19,11 @@ #include "browserfilter.h" BrowserFilter::BrowserFilter () : - showTrash (true), - showNotTrash (true), - showOriginal (false), - multiselect (false), - exifFilterEnabled (false) + showTrash(true), + showNotTrash(true), + showOriginal(false), + exifFilterEnabled(false), + matchEqual(true) { for (int i = 0; i < 6; i++) { showRanked[i] = true; diff --git a/rtgui/browserfilter.h b/rtgui/browserfilter.h index 8880a364d..ac9818ce5 100644 --- a/rtgui/browserfilter.h +++ b/rtgui/browserfilter.h @@ -33,13 +33,11 @@ public: bool showOriginal; bool showEdited[2]; bool showRecentlySaved[2]; - bool multiselect; - - Glib::ustring queryString; - Glib::ustring queryFileName; bool exifFilterEnabled; + bool matchEqual; ExifFilterSettings exifFilter; + std::vector vFilterStrings; BrowserFilter (); }; diff --git a/rtgui/coordinateadjuster.cc b/rtgui/coordinateadjuster.cc index 2525a07e5..5065606d9 100644 --- a/rtgui/coordinateadjuster.cc +++ b/rtgui/coordinateadjuster.cc @@ -23,7 +23,7 @@ #include "curveeditorgroup.h" Axis::Axis() - : label(""), decimal(5), increment(0.001), pageIncrement(0.01), rangeLowerBound(0.), rangeUpperBound(1.) + : decimal(5), increment(0.001), pageIncrement(0.01), rangeLowerBound(0.), rangeUpperBound(1.) {} Axis::Axis(Glib::ustring label, unsigned int decimal, double increment, double pageIncrement, double valMin = 0.0, double valMax = 1.0) diff --git a/rtgui/crop.cc b/rtgui/crop.cc index 781a916a1..a8b12819e 100644 --- a/rtgui/crop.cc +++ b/rtgui/crop.cc @@ -1400,24 +1400,19 @@ void Crop::cropResized (int &x, int &y, int& x2, int& y2) y2 = maxh - 1; } - int X, Y; int W; if (x < x2) { W = x2 - x + 1; - X = x; } else { W = x - x2 + 1; - X = x2; } - int H; + int Y; if (y < y2) { - H = y2 - y + 1; Y = y; } else { - H = y - y2 + 1; Y = y2; } @@ -1425,6 +1420,7 @@ void Crop::cropResized (int &x, int &y, int& x2, int& y2) W = maxw; } + int H; if (fixr->get_active()) { double r = getRatio (); @@ -1457,6 +1453,7 @@ void Crop::cropResized (int &x, int &y, int& x2, int& y2) } } + int X; if (x < x2) { W = x2 - x + 1; X = x; diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index b29aa5eeb..5839a5edb 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -2198,8 +2198,6 @@ void CropWindow::updateHoveredPicker (rtengine::Coord *imgPos) } rtengine::Coord cropPos; - float r=0.f, g=0.f, b=0.f; - float rpreview=0.f, gpreview=0.f, bpreview=0.f; if (imgPos) { imageCoordToCropImage(imgPos->x, imgPos->y, cropPos.x, cropPos.y); hoveredPicker->setPosition (*imgPos); @@ -2215,6 +2213,8 @@ void CropWindow::updateHoveredPicker (rtengine::Coord *imgPos) MyMutex::MyLock lock(cropHandler.cimg); if (validity == LockableColorPicker::Validity::INSIDE) { + float r=0.f, g=0.f, b=0.f; + float rpreview=0.f, gpreview=0.f, bpreview=0.f; cropHandler.colorPick(cropPos, r, g, b, rpreview, gpreview, bpreview, hoveredPicker->getSize()); hoveredPicker->setRGB (r, g, b, rpreview, gpreview, bpreview); } diff --git a/rtgui/cropwindow.h b/rtgui/cropwindow.h index 6e2097d3b..26edf69ee 100644 --- a/rtgui/cropwindow.h +++ b/rtgui/cropwindow.h @@ -31,6 +31,7 @@ #include "cursormanager.h" #include "editbuffer.h" #include "editcoordsys.h" +#include "../rtengine/noncopyable.h" class CropWindow; @@ -45,7 +46,7 @@ public: }; class ImageArea; -class CropWindow : public LWButtonListener, public CropDisplayHandler, public EditCoordSystem, public ObjectMOBuffer +class CropWindow : public LWButtonListener, public CropDisplayHandler, public EditCoordSystem, public ObjectMOBuffer, public rtengine::NonCopyable { static bool initialized; diff --git a/rtgui/curveeditor.h b/rtgui/curveeditor.h index 1227edc0f..e38d3f205 100644 --- a/rtgui/curveeditor.h +++ b/rtgui/curveeditor.h @@ -25,6 +25,7 @@ #include "editcallbacks.h" #include "mydiagonalcurve.h" #include "myflatcurve.h" +#include "../rtengine/noncopyable.h" class CurveEditorGroup; class CurveEditorSubGroup; @@ -38,7 +39,7 @@ class CurveEditorSubGroup; /** @brief This class is an interface between RT and the curve editor group * It handles the methods related to a specific curve. It is created by CurveEditorGroup::addCurve */ -class CurveEditor : public EditSubscriber +class CurveEditor : public EditSubscriber, public rtengine::NonCopyable { friend class CurveEditorGroup; diff --git a/rtgui/curveeditorgroup.cc b/rtgui/curveeditorgroup.cc index 10aff907c..495e4324b 100644 --- a/rtgui/curveeditorgroup.cc +++ b/rtgui/curveeditorgroup.cc @@ -397,7 +397,7 @@ void CurveEditorGroup::setUnChanged (bool uc, CurveEditor* ce) } } -CurveEditorSubGroup::CurveEditorSubGroup(Glib::ustring& curveDir) : curveDir(curveDir), lastFilename(""), valLinear(0), valUnchanged(0), parent(nullptr) +CurveEditorSubGroup::CurveEditorSubGroup(Glib::ustring& curveDir) : curveDir(curveDir), valLinear(0), valUnchanged(0), parent(nullptr) { leftBar = nullptr; bottomBar = nullptr; diff --git a/rtgui/curveeditorgroup.h b/rtgui/curveeditorgroup.h index 80a1a95a4..ae0ebee07 100644 --- a/rtgui/curveeditorgroup.h +++ b/rtgui/curveeditorgroup.h @@ -70,7 +70,7 @@ public: * dialogs. */ - CurveEditorGroup(Glib::ustring& curveDir, Glib::ustring groupLabel = ""); + explicit CurveEditorGroup(Glib::ustring& curveDir, Glib::ustring groupLabel = ""); ~CurveEditorGroup() override; void newLine(); void curveListComplete(); diff --git a/rtgui/diagonalcurveeditorsubgroup.h b/rtgui/diagonalcurveeditorsubgroup.h index 54f424dc6..68047e0c2 100644 --- a/rtgui/diagonalcurveeditorsubgroup.h +++ b/rtgui/diagonalcurveeditorsubgroup.h @@ -21,10 +21,11 @@ #include #include "curveeditorgroup.h" +#include "../rtengine/noncopyable.h" class DiagonalCurveEditor; -class DiagonalCurveEditorSubGroup : public CurveEditorSubGroup, public SHCListener, public AdjusterListener +class DiagonalCurveEditorSubGroup : public CurveEditorSubGroup, public SHCListener, public AdjusterListener, public rtengine::NonCopyable { friend class DiagonalCurveEditor; diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc index c59561903..1f8e83c3e 100644 --- a/rtgui/editorpanel.cc +++ b/rtgui/editorpanel.cc @@ -1377,7 +1377,7 @@ void EditorPanel::info_toggled () infoString = M ("QINFO_NOEXIF"); } - iareapanel->imageArea->setInfoText (infoString); + iareapanel->imageArea->setInfoText (std::move(infoString)); iareapanel->imageArea->infoEnabled (info->get_active ()); } diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h index de5360646..7fe79b827 100644 --- a/rtgui/editorpanel.h +++ b/rtgui/editorpanel.h @@ -34,6 +34,7 @@ #include "navigator.h" #include "progressconnector.h" #include "filepanel.h" +#include "../rtengine/noncopyable.h" class EditorPanel; class MyProgressBar; @@ -52,7 +53,8 @@ class EditorPanel final : public rtengine::ProgressListener, public ThumbnailListener, public HistoryBeforeLineListener, - public rtengine::HistogramListener + public rtengine::HistogramListener, + public rtengine::NonCopyable { public: explicit EditorPanel (FilePanel* filePanel = nullptr); diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc index 6c196e575..f9324e90c 100644 --- a/rtgui/exifpanel.cc +++ b/rtgui/exifpanel.cc @@ -632,7 +632,7 @@ Glib::ustring ExifPanel::getSelection (bool onlyeditable) Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (rows[0]); - Glib::ustring ret = ""; + Glib::ustring ret; bool first = true; bool editable = false; diff --git a/rtgui/favoritbrowser.cc b/rtgui/favoritbrowser.cc index 0e1b4490b..09deacfab 100644 --- a/rtgui/favoritbrowser.cc +++ b/rtgui/favoritbrowser.cc @@ -20,7 +20,7 @@ #include "multilangmgr.h" #include "rtimage.h" -FavoritBrowser::FavoritBrowser () : listener (NULL), lastSelectedDir ("") +FavoritBrowser::FavoritBrowser () : listener (NULL) { scrollw = Gtk::manage (new Gtk::ScrolledWindow ()); diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index eb85613ee..88220a688 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -18,6 +18,7 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ +#include #include #include @@ -622,7 +623,7 @@ void FileBrowser::addEntry_ (FileBrowserEntry* entry) initEntry(entry); } - redraw(false); + redraw(entry); } FileBrowserEntry* FileBrowser::delEntry (const Glib::ustring& fname) @@ -839,10 +840,10 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) } for (size_t i = 0; i < mselected.size(); i++) { - rtengine::procparams::ProcParams pp = mselected[i]->thumbnail->getProcParams(); - pp.raw.dark_frame = fc.get_filename(); - pp.raw.df_autoselect = false; - mselected[i]->thumbnail->setProcParams(pp, nullptr, FILEBROWSER, false); + rtengine::procparams::ProcParams lpp = mselected[i]->thumbnail->getProcParams(); + lpp.raw.dark_frame = fc.get_filename(); + lpp.raw.df_autoselect = false; + mselected[i]->thumbnail->setProcParams(lpp, nullptr, FILEBROWSER, false); } if (bppcl) { @@ -915,10 +916,10 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) } for (size_t i = 0; i < mselected.size(); i++) { - rtengine::procparams::ProcParams pp = mselected[i]->thumbnail->getProcParams(); - pp.raw.ff_file = fc.get_filename(); - pp.raw.ff_AutoSelect = false; - mselected[i]->thumbnail->setProcParams(pp, nullptr, FILEBROWSER, false); + rtengine::procparams::ProcParams lpp = mselected[i]->thumbnail->getProcParams(); + lpp.raw.ff_file = fc.get_filename(); + lpp.raw.ff_AutoSelect = false; + mselected[i]->thumbnail->setProcParams(lpp, nullptr, FILEBROWSER, false); } if (bppcl) { @@ -1078,17 +1079,17 @@ void FileBrowser::partPasteProfile () bppcl->beginBatchPParamsChange(mselected.size()); } - for (unsigned int i = 0; i < mselected.size(); i++) { + for (auto entry : mselected) { // copying read only clipboard PartialProfile to a temporary one, initialized to the thumb's ProcParams - mselected[i]->thumbnail->createProcParamsForUpdate(false, false); // this can execute customprofilebuilder to generate param file + entry->thumbnail->createProcParamsForUpdate(false, false); // this can execute customprofilebuilder to generate param file const rtengine::procparams::PartialProfile& cbPartProf = clipboard.getPartialProfile(); - rtengine::procparams::PartialProfile pastedPartProf(&mselected[i]->thumbnail->getProcParams (), nullptr); + rtengine::procparams::PartialProfile pastedPartProf(&entry->thumbnail->getProcParams (), nullptr); // pushing the selected values of the clipboard PartialProfile to the temporary PartialProfile partialPasteDlg.applyPaste (pastedPartProf.pparams, pastedPartProf.pedited, cbPartProf.pparams, cbPartProf.pedited); // applying the temporary PartialProfile to the thumb's ProcParams - mselected[i]->thumbnail->setProcParams (*pastedPartProf.pparams, pastedPartProf.pedited, FILEBROWSER); + entry->thumbnail->setProcParams (*pastedPartProf.pparams, pastedPartProf.pedited, FILEBROWSER); pastedPartProf.deleteInstance(); } @@ -1469,12 +1470,12 @@ void FileBrowser::applyFilter (const BrowserFilter& filter) redraw (); } -bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry complies filter +bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) const // true -> entry complies filter { FileBrowserEntry* entry = static_cast(entryb); - if (filter.showOriginal && entry->getOriginal() != nullptr) { + if (filter.showOriginal && entry->getOriginal()) { return false; } @@ -1493,44 +1494,22 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry return false; } - // return false is query is not satisfied - if (!filter.queryFileName.empty()) { + // return false if query is not satisfied + if (!filter.vFilterStrings.empty()) { // check if image's FileName contains queryFileName (case insensitive) // TODO should we provide case-sensitive search option via preferences? - Glib::ustring FileName; - FileName = Glib::path_get_basename (entry->thumbnail->getFileName()); - FileName = FileName.uppercase(); - //printf("FileBrowser::checkFilter FileName = '%s'; find() result= %i \n",FileName.c_str(), FileName.find(filter.queryFileName.uppercase())); - - Glib::ustring decodedQueryFileName; - bool MatchEqual; - - // Determine the match mode - check if the first 2 characters are equal to "!=" - if (filter.queryFileName.find("!=") == 0) { - decodedQueryFileName = filter.queryFileName.substr (2, filter.queryFileName.length() - 2); - MatchEqual = false; - } else { - decodedQueryFileName = filter.queryFileName; - MatchEqual = true; - } - - // Consider that queryFileName consist of comma separated values (FilterString) - // Evaluate if ANY of these FilterString are contained in the filename - // This will construct OR filter within the filter.queryFileName + std::string FileName = Glib::path_get_basename(entry->thumbnail->getFileName()); + std::transform(FileName.begin(), FileName.end(), FileName.begin(), ::toupper); int iFilenameMatch = 0; - std::vector vFilterStrings = Glib::Regex::split_simple(",", decodedQueryFileName.uppercase()); - for(size_t i = 0; i < vFilterStrings.size(); i++) { - // ignore empty vFilterStrings. Otherwise filter will always return true if - // e.g. filter.queryFileName ends on "," and will stop being a filter - if (!vFilterStrings.at(i).empty()) { - if (FileName.find(vFilterStrings.at(i)) != Glib::ustring::npos) { - iFilenameMatch++; - } + for (const auto& filter : filter.vFilterStrings) { + if (FileName.find(filter) != std::string::npos) { + ++iFilenameMatch; + break; } } - if (MatchEqual) { + if (filter.matchEqual) { if (iFilenameMatch == 0) { //none of the vFilterStrings found in FileName return false; } @@ -1539,10 +1518,10 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry return false; } } + } - /*experimental Regex support, this is unlikely to be useful to photographers*/ - //bool matchfound=Glib::Regex::match_simple(filter.queryFileName.uppercase(),FileName); - //if (!matchfound) return false; + if (!filter.exifFilterEnabled) { + return true; } // check exif filter @@ -1550,17 +1529,12 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry double tol = 0.01; double tol2 = 1e-8; - if (!filter.exifFilterEnabled) { - return true; - } - - Glib::ustring camera(cfs->getCamera()); - - if (!cfs->exifValid) - return (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(camera) > 0) + if (!cfs->exifValid) { + return (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(cfs->getCamera()) > 0) && (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens) > 0) && (!filter.exifFilter.filterFiletype || filter.exifFilter.filetypes.count(cfs->filetype) > 0) && (!filter.exifFilter.filterExpComp || filter.exifFilter.expcomp.count(cfs->expcomp) > 0); + } return (!filter.exifFilter.filterShutter || (rtengine::FramesMetaData::shutterFromString(rtengine::FramesMetaData::shutterToString(cfs->shutter)) >= filter.exifFilter.shutterFrom - tol2 && rtengine::FramesMetaData::shutterFromString(rtengine::FramesMetaData::shutterToString(cfs->shutter)) <= filter.exifFilter.shutterTo + tol2)) @@ -1568,7 +1542,7 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry && (!filter.exifFilter.filterFocalLen || (cfs->focalLen >= filter.exifFilter.focalFrom - tol && cfs->focalLen <= filter.exifFilter.focalTo + tol)) && (!filter.exifFilter.filterISO || (cfs->iso >= filter.exifFilter.isoFrom && cfs->iso <= filter.exifFilter.isoTo)) && (!filter.exifFilter.filterExpComp || filter.exifFilter.expcomp.count(cfs->expcomp) > 0) - && (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(camera) > 0) + && (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(cfs->getCamera()) > 0) && (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens) > 0) && (!filter.exifFilter.filterFiletype || filter.exifFilter.filetypes.count(cfs->filetype) > 0); } diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h index b208a854d..03c7fc86c 100644 --- a/rtgui/filebrowser.h +++ b/rtgui/filebrowser.h @@ -30,6 +30,7 @@ #include "exportpanel.h" #include "extprog.h" #include "profilestorecombobox.h" +#include "../rtengine/noncopyable.h" class ProfileStoreLabel; class FileBrowser; @@ -56,7 +57,8 @@ public: class FileBrowser : public ThumbBrowserBase, public LWButtonListener, public ExportPanelListener, - public ProfileStoreListener + public ProfileStoreListener, + public rtengine::NonCopyable { private: typedef sigc::signal type_trash_changed; @@ -168,7 +170,7 @@ public: void buttonPressed (LWButton* button, int actionCode, void* actionData) override; void redrawNeeded (LWButton* button) override; - bool checkFilter (ThumbBrowserEntryBase* entry) override; + bool checkFilter (ThumbBrowserEntryBase* entry) const override; void rightClicked (ThumbBrowserEntryBase* entry) override; void doubleClicked (ThumbBrowserEntryBase* entry) override; bool keyPressed (GdkEventKey* event) override; diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index 4b1764824..8b518335c 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -251,32 +251,32 @@ void FileBrowserEntry::_updateImage(rtengine::IImage8* img, double s, const rten bool newLandscape = img->getWidth() > img->getHeight(); bool rotated = false; - if (preh == img->getHeight ()) { + if (preh == img->getHeight()) { + const bool resize = !preview || prew != img->getWidth(); prew = img->getWidth (); GThreadLock lock; // Check if image has been rotated since last time - rotated = preview != nullptr && newLandscape != landscape; + rotated = preview && newLandscape != landscape; - guint8* temp = preview; - preview = nullptr; - delete [] temp; - temp = new guint8 [prew * preh * 3]; - memcpy (temp, img->getData(), prew * preh * 3); - preview = temp; + if (resize) { + delete [] preview; + preview = new guint8 [prew * preh * 3]; + } + memcpy(preview, img->getData(), prew * preh * 3); updateBackBuffer (); } landscape = newLandscape; - img->free (); + img->free(); - if (parent != nullptr) { + if (parent) { if (rotated) { parent->thumbRearrangementNeeded(); } else if (redrawRequests == 0) { - parent->redrawNeeded (this); + parent->redrawNeeded(this); } } } diff --git a/rtgui/filebrowserentry.h b/rtgui/filebrowserentry.h index 5122de55f..bd3a266aa 100644 --- a/rtgui/filebrowserentry.h +++ b/rtgui/filebrowserentry.h @@ -34,6 +34,7 @@ #include "thumbimageupdater.h" #include "thumbnail.h" #include "thumbnaillistener.h" +#include "../rtengine/noncopyable.h" class FileBrowserEntry; @@ -46,7 +47,8 @@ struct FileBrowserEntryIdleHelper { class FileThumbnailButtonSet; class FileBrowserEntry : public ThumbBrowserEntryBase, public ThumbnailListener, - public ThumbImageUpdateListener + public ThumbImageUpdateListener, + public rtengine::NonCopyable { double scale; diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index dbe540cb4..6eb8faab1 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -457,8 +457,6 @@ FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : hScrollPos[i] = 0; vScrollPos[i] = 0; } - - selectedDirectory = ""; } FileCatalog::~FileCatalog() @@ -804,28 +802,28 @@ void FileCatalog::previewsFinishedUI () { GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected - redrawAll (); + redrawAll(); previewsToLoad = 0; if (filterPanel) { - filterPanel->set_sensitive (true); + filterPanel->set_sensitive(true); - if ( !hasValidCurrentEFS ) { - MyMutex::MyLock lock(dirEFSMutex); + if (!hasValidCurrentEFS) { + MyMutex::MyLock myLock(dirEFSMutex); currentEFS = dirEFS; - filterPanel->setFilter ( dirEFS, true ); + filterPanel->setFilter(dirEFS, true); } else { - filterPanel->setFilter ( currentEFS, false ); + filterPanel->setFilter(currentEFS, false); } } if (exportPanel) { - exportPanel->set_sensitive (true); + exportPanel->set_sensitive(true); } // restart anything that might have been loaded low quality fileBrowser->refreshQuickThumbImages(); - fileBrowser->applyFilter (getFilter()); // refresh total image count + fileBrowser->applyFilter(getFilter()); // refresh total image count _refreshProgressBar(); } filepanel->loadingThumbs(M("PROGRESSBAR_READY"), 0); @@ -1603,7 +1601,6 @@ BrowserFilter FileCatalog::getFilter () anyRankFilterActive || anyCLabelFilterActive || anyEditedFilterActive; } - filter.multiselect = false; /* * Step 2 @@ -1619,7 +1616,6 @@ BrowserFilter FileCatalog::getFilter () (anyEditedFilterActive && anyRecentlySavedFilterActive) || (anySupplementaryActive && (anyRankFilterActive || anyCLabelFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive))) { - filter.multiselect = true; filter.showRanked[0] = anyRankFilterActive ? bUnRanked->get_active () : true; filter.showCLabeled[0] = anyCLabelFilterActive ? bUnCLabeled->get_active () : true; @@ -1656,14 +1652,28 @@ BrowserFilter FileCatalog::getFilter () //TODO could use date:;iso: etc // default will be filename - /* // this is for safe execution if getFilter is called before Query object is instantiated - Glib::ustring tempQuery; - tempQuery=""; - if (Query) tempQuery = Query->get_text(); - */ - filter.queryString = Query->get_text(); // full query string from Query Entry - filter.queryFileName = Query->get_text(); // for now Query is only by file name + Glib::ustring decodedQueryFileName = Query->get_text(); // for now Query is only by file name + // Determine the match mode - check if the first 2 characters are equal to "!=" + if (decodedQueryFileName.find("!=") == 0) { + decodedQueryFileName = decodedQueryFileName.substr(2); + filter.matchEqual = false; + } else { + filter.matchEqual = true; + } + + // Consider that queryFileName consist of comma separated values (FilterString) + // Evaluate if ANY of these FilterString are contained in the filename + // This will construct OR filter within the queryFileName + filter.vFilterStrings.clear(); + const std::vector filterStrings = Glib::Regex::split_simple(",", decodedQueryFileName.uppercase()); + for (const auto& entry : filterStrings) { + // ignore empty filterStrings. Otherwise filter will always return true if + // e.g. queryFileName ends on "," and will stop being a filter + if (!entry.empty()) { + filter.vFilterStrings.push_back(entry); + } + } return filter; } diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h index 2f3054bcf..0ff2fb1e8 100644 --- a/rtgui/filecatalog.h +++ b/rtgui/filecatalog.h @@ -32,6 +32,7 @@ #include "previewloader.h" #include "multilangmgr.h" #include "threadutils.h" +#include "../rtengine/noncopyable.h" class FilePanel; /* @@ -44,7 +45,8 @@ class FileCatalog : public Gtk::VBox, public PreviewLoaderListener, public FilterPanelListener, public FileBrowserListener, - public ExportPanelListener + public ExportPanelListener, + public rtengine::NonCopyable { public: typedef sigc::slot DirSelectionSlot; diff --git a/rtgui/filepanel.h b/rtgui/filepanel.h index df61cb60d..0385c48d3 100644 --- a/rtgui/filepanel.h +++ b/rtgui/filepanel.h @@ -31,12 +31,14 @@ #include "filterpanel.h" #include "exportpanel.h" #include "progressconnector.h" +#include "../rtengine/noncopyable.h" class RTWindow; class FilePanel final : public Gtk::HPaned, - public FileSelectionListener + public FileSelectionListener, + public rtengine::NonCopyable { public: FilePanel (); diff --git a/rtgui/filmnegative.h b/rtgui/filmnegative.h index e967f535c..a1efdc455 100644 --- a/rtgui/filmnegative.h +++ b/rtgui/filmnegative.h @@ -28,8 +28,6 @@ #include "toolpanel.h" #include "wbprovider.h" -#include "../rtengine/noncopyable.h" - class FilmNegProvider { public: @@ -39,7 +37,6 @@ public: }; class FilmNegative : - public rtengine::NonCopyable, public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, diff --git a/rtgui/flatcurveeditorsubgroup.h b/rtgui/flatcurveeditorsubgroup.h index ab2abedfb..f931bf660 100644 --- a/rtgui/flatcurveeditorsubgroup.h +++ b/rtgui/flatcurveeditorsubgroup.h @@ -21,10 +21,11 @@ #include #include "curveeditorgroup.h" +#include "../rtengine/noncopyable.h" class FlatCurveEditor; -class FlatCurveEditorSubGroup: public CurveEditorSubGroup +class FlatCurveEditorSubGroup: public CurveEditorSubGroup, public rtengine::NonCopyable { friend class FlatCurveEditor; diff --git a/rtgui/flatfield.cc b/rtgui/flatfield.cc index 25482909e..f69b90170 100644 --- a/rtgui/flatfield.cc +++ b/rtgui/flatfield.cc @@ -86,7 +86,6 @@ FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_L flatFieldFileReset->signal_clicked().connect( sigc::mem_fun(*this, &FlatField::flatFieldFile_Reset), true ); flatFieldAutoSelectconn = flatFieldAutoSelect->signal_toggled().connect ( sigc::mem_fun(*this, &FlatField::flatFieldAutoSelectChanged), true); flatFieldBlurTypeconn = flatFieldBlurType->signal_changed().connect( sigc::mem_fun(*this, &FlatField::flatFieldBlurTypeChanged) ); - lastShortcutPath = ""; // Set filename filters b_filter_asCurrent = false; diff --git a/rtgui/gradient.cc b/rtgui/gradient.cc index d7b2cb7c2..3f13dfe4d 100644 --- a/rtgui/gradient.cc +++ b/rtgui/gradient.cc @@ -422,9 +422,7 @@ bool Gradient::button1Pressed(int modifierKey) double diagonal = sqrt(double(imW) * double(imW) + double(imH) * double(imH)); // trick to get the correct angle (clockwise/counter-clockwise) - int p = centerPos.y; - centerPos.y = currPos.y; - currPos.y = p; + std::swap(centerPos.y, currPos.y); draggedPoint = currPos - centerPos; // compute the projected value of the dragged point diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index eb3704076..ec0bf6588 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -298,17 +298,14 @@ void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int cr->line_to (rectx1, recty1); cr->stroke (); cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); - std::valarray ds (1); - ds[0] = 4; - cr->set_dash (ds, 0); + cr->set_dash (std::valarray({4}), 0); cr->move_to (rectx1, recty1); cr->line_to (rectx2, recty1); cr->line_to (rectx2, recty2); cr->line_to (rectx1, recty2); cr->line_to (rectx1, recty1); cr->stroke (); - ds.resize (0); - cr->set_dash (ds, 0); + cr->set_dash (std::valarray(), 0); if (cparams.guide != "Rule of diagonals" && cparams.guide != "Golden Triangle 1" && cparams.guide != "Golden Triangle 2") { // draw guide lines @@ -446,14 +443,11 @@ void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int cr->line_to (rectx2, recty2); cr->stroke (); cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); - std::valarray ds (1); - ds[0] = 4; - cr->set_dash (ds, 0); + cr->set_dash (std::valarray({4}), 0); cr->move_to (rectx1, recty1); cr->line_to (rectx2, recty2); cr->stroke (); - ds.resize (0); - cr->set_dash (ds, 0); + cr->set_dash (std::valarray(), 0); double height = recty2 - recty1; double width = rectx2 - rectx1; @@ -470,14 +464,11 @@ void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int cr->line_to (rectx1 + x, recty1 + y); cr->stroke (); cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); - ds.resize (1); - ds[0] = 4; - cr->set_dash (ds, 0); + cr->set_dash (std::valarray({4}), 0); cr->move_to (rectx1, recty2); cr->line_to (rectx1 + x, recty1 + y); cr->stroke (); - ds.resize (0); - cr->set_dash (ds, 0); + cr->set_dash (std::valarray(), 0); x = width - (a * b) / height; y = (b * (d - a)) / width; @@ -486,14 +477,11 @@ void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int cr->line_to (rectx1 + x, recty1 + y); cr->stroke (); cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); - ds.resize (1); - ds[0] = 4; - cr->set_dash (ds, 0); + cr->set_dash (std::valarray({4}), 0); cr->move_to (rectx2, recty1); cr->line_to (rectx1 + x, recty1 + y); cr->stroke (); - ds.resize (0); - cr->set_dash (ds, 0); + cr->set_dash (std::valarray(), 0); } } @@ -675,12 +663,6 @@ MyExpander::MyExpander(bool useEnabled, Glib::ustring titleLabel) : statusImage->set_can_focus(false); - Glib::ustring str("-"); - - if (!titleLabel.empty()) { - str = titleLabel; - } - label = Gtk::manage(new Gtk::Label()); setExpandAlignProperties(label, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER); label->set_markup(Glib::ustring("") + escapeHtmlChars(titleLabel) + Glib::ustring("")); @@ -970,38 +952,27 @@ bool MyScrolledWindow::on_scroll_event (GdkEventScroll* event) Gtk::Scrollbar *scroll = get_vscrollbar(); if (adjust && scroll) { - double upper = adjust->get_upper(); - double lower = adjust->get_lower(); + const double upperBound = adjust->get_upper(); + const double lowerBound = adjust->get_lower(); double value = adjust->get_value(); double step = adjust->get_step_increment(); double value2 = 0.; -// printf("MyScrolledwindow::on_scroll_event / delta_x=%.5f, delta_y=%.5f, direction=%d, type=%d, send_event=%d\n", -// event->delta_x, event->delta_y, (int)event->direction, (int)event->type, event->send_event); - if (event->direction == GDK_SCROLL_DOWN) { - value2 = value + step; - - if (value2 > upper) { - value2 = upper; - } + value2 = rtengine::min(value + step, upperBound); if (value2 != value) { scroll->set_value(value2); } } else if (event->direction == GDK_SCROLL_UP) { - value2 = value - step; - - if (value2 < lower) { - value2 = lower; - } + value2 = rtengine::max(value - step, lowerBound); if (value2 != value) { scroll->set_value(value2); } } else if (event->direction == GDK_SCROLL_SMOOTH) { if (abs(event->delta_y) > 0.1) { - value2 = rtengine::LIM(value + (event->delta_y > 0 ? step : -step), lower, upper); + value2 = rtengine::LIM(value + (event->delta_y > 0 ? step : -step), lowerBound, upperBound); } if (value2 != value) { scroll->set_value(value2); @@ -1050,8 +1021,8 @@ bool MyScrolledToolbar::on_scroll_event (GdkEventScroll* event) Gtk::Scrollbar *scroll = get_hscrollbar(); if (adjust && scroll) { - double upper = adjust->get_upper(); - double lower = adjust->get_lower(); + const double upperBound = adjust->get_upper(); + const double lowerBound = adjust->get_lower(); double value = adjust->get_value(); double step = adjust->get_step_increment() * 2; double value2 = 0.; @@ -1060,20 +1031,20 @@ bool MyScrolledToolbar::on_scroll_event (GdkEventScroll* event) // event->delta_x, event->delta_y, (int)event->direction, (int)event->type, event->send_event); if (event->direction == GDK_SCROLL_DOWN) { - value2 = rtengine::min(value + step, upper); + value2 = rtengine::min(value + step, upperBound); if (value2 != value) { scroll->set_value(value2); } } else if (event->direction == GDK_SCROLL_UP) { - value2 = rtengine::max(value - step, lower); + value2 = rtengine::max(value - step, lowerBound); if (value2 != value) { scroll->set_value(value2); } } else if (event->direction == GDK_SCROLL_SMOOTH) { if (event->delta_x) { // if the user use a pad, it can scroll horizontally - value2 = rtengine::LIM(value + (event->delta_x > 0 ? 30 : -30), lower, upper); + value2 = rtengine::LIM(value + (event->delta_x > 0 ? 30 : -30), lowerBound, upperBound); } else if (event->delta_y) { - value2 = rtengine::LIM(value + (event->delta_y > 0 ? 30 : -30), lower, upper); + value2 = rtengine::LIM(value + (event->delta_y > 0 ? 30 : -30), lowerBound, upperBound); } if (value2 != value) { scroll->set_value(value2); @@ -1604,7 +1575,7 @@ bool BackBuffer::setDrawRectangle(Glib::RefPtr window, int newX, in x = newX; y = newY; - if (newH > 0) { + if (newW > 0) { w = newW; } if (newH > 0) { @@ -1637,7 +1608,7 @@ bool BackBuffer::setDrawRectangle(Cairo::Format format, int newX, int newY, int x = newX; y = newY; - if (newH > 0) { + if (newW > 0) { w = newW; } if (newH > 0) { diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index e4c38f347..73cd27171 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -400,7 +400,7 @@ protected: void set_none(); public: - MyFileChooserButton(const Glib::ustring &title, Gtk::FileChooserAction action=Gtk::FILE_CHOOSER_ACTION_OPEN); + explicit MyFileChooserButton(const Glib::ustring &title, Gtk::FileChooserAction action=Gtk::FILE_CHOOSER_ACTION_OPEN); sigc::signal &signal_selection_changed(); sigc::signal &signal_file_set(); diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc index 49960b2db..12da0cc0d 100644 --- a/rtgui/histogrampanel.cc +++ b/rtgui/histogrampanel.cc @@ -464,7 +464,6 @@ void HistogramRGBArea::updateBackBuffer (int r, int g, int b, const Glib::ustrin if (surface) { Cairo::RefPtr cc = Cairo::Context::create(surface); - Glib::RefPtr style = get_style_context(); cc->set_source_rgba (0., 0., 0., 0.); cc->set_operator (Cairo::OPERATOR_CLEAR); @@ -616,7 +615,6 @@ void HistogramRGBArea::on_realize () { Gtk::DrawingArea::on_realize(); - Glib::RefPtr window = get_window(); add_events(Gdk::BUTTON_PRESS_MASK); } @@ -984,7 +982,6 @@ void HistogramArea::on_realize () { Gtk::DrawingArea::on_realize(); - Glib::RefPtr window = get_window(); add_events(Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK); } @@ -1037,8 +1034,6 @@ void HistogramArea::drawMarks(Cairo::RefPtr &cr, bool HistogramArea::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) { - Glib::RefPtr window = get_window(); - if (get_width() != oldwidth || get_height() != oldheight || isDirty ()) { updateBackBuffer (); } diff --git a/rtgui/histogrampanel.h b/rtgui/histogrampanel.h index f34b07c39..f66d2e654 100644 --- a/rtgui/histogrampanel.h +++ b/rtgui/histogrampanel.h @@ -28,6 +28,7 @@ #include "guiutils.h" #include "pointermotionlistener.h" +#include "../rtengine/noncopyable.h" class HistogramArea; struct HistogramAreaIdleHelper { @@ -51,7 +52,7 @@ public: double log (double vsize, double val); }; -class HistogramRGBArea : public Gtk::DrawingArea, public BackBuffer, private HistogramScaling +class HistogramRGBArea : public Gtk::DrawingArea, public BackBuffer, private HistogramScaling, public rtengine::NonCopyable { private: typedef const double (*TMatrix)[3]; @@ -114,7 +115,7 @@ public: virtual void toggleButtonMode() = 0; }; -class HistogramArea : public Gtk::DrawingArea, public BackBuffer, private HistogramScaling +class HistogramArea : public Gtk::DrawingArea, public BackBuffer, private HistogramScaling, public rtengine::NonCopyable { public: typedef sigc::signal type_signal_factor_changed; @@ -172,7 +173,7 @@ private: void get_preferred_width_for_height_vfunc (int height, int &minimum_width, int &natural_width) const override; }; -class HistogramPanel : public Gtk::Grid, public PointerMotionListener, public DrawModeListener +class HistogramPanel : public Gtk::Grid, public PointerMotionListener, public DrawModeListener, public rtengine::NonCopyable { protected: diff --git a/rtgui/iccprofilecreator.cc b/rtgui/iccprofilecreator.cc index 0ab1ac61d..ed880bd0e 100644 --- a/rtgui/iccprofilecreator.cc +++ b/rtgui/iccprofilecreator.cc @@ -674,8 +674,6 @@ void ICCProfileCreator::savePressed() //necessary for V2 profile if (!v2except) { - std::string is_RTv4 = ""; - //used partially for v4, and in case of if we want to back to old manner for v2 if (primariesPreset == "ACES-AP0" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.ACESp0)) { sNewProfile = options.rtSettings.ACESp0; @@ -687,11 +685,9 @@ void ICCProfileCreator::savePressed() sNewProfile = options.rtSettings.adobe; sPrimariesPreset = "Medium"; } else if (primariesPreset == "ProPhoto" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.prophoto)) { - is_RTv4 = options.rtSettings.prophoto.substr(0, 4); - - if (is_RTv4 == "RTv4") { + if (options.rtSettings.prophoto.substr(0, 4) == "RTv4") { options.rtSettings.prophoto = "RTv2_Large"; - }; + } sNewProfile = options.rtSettings.prophoto; @@ -703,32 +699,26 @@ void ICCProfileCreator::savePressed() sNewProfile = options.rtSettings.srgb; sPrimariesPreset = "sRGB"; } else if (primariesPreset == "Widegamut" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.widegamut)) { - is_RTv4 = options.rtSettings.widegamut.substr(0, 4); - - if (is_RTv4 == "RTv4") { + if (options.rtSettings.widegamut.substr(0, 4) == "RTv4") { options.rtSettings.widegamut = "RTv2_Wide"; - }; + } sNewProfile = options.rtSettings.widegamut; sPrimariesPreset = "Wide"; } else if (primariesPreset == "BestRGB" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.best)) { - is_RTv4 = options.rtSettings.best.substr(0, 4); - - if (is_RTv4 == "RTv4") { + if (options.rtSettings.best.substr(0, 4) == "RTv4") { options.rtSettings.best = "RTv2_Best"; - }; + } sNewProfile = options.rtSettings.best; sPrimariesPreset = "Best"; } else if (primariesPreset == "BetaRGB" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.beta)) { sNewProfile = options.rtSettings.beta; - is_RTv4 = options.rtSettings.beta.substr(0, 4); - - if (is_RTv4 == "RTv4") { + if (options.rtSettings.beta.substr(0, 4) == "RTv4") { options.rtSettings.widegamut = "RTv2_Beta"; - }; + } sPrimariesPreset = "Beta"; } else if (primariesPreset == "BruceRGB" && rtengine::ICCStore::getInstance()->outputProfileExist(options.rtSettings.bruce)) { diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc index e7efa20e9..a6857eaa9 100644 --- a/rtgui/icmpanel.cc +++ b/rtgui/icmpanel.cc @@ -34,7 +34,7 @@ using namespace rtengine::procparams; extern Options options; -ICMPanel::ICMPanel() : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunchanged(nullptr), icmplistener(nullptr), lastRefFilename(""), camName("") +ICMPanel::ICMPanel() : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunchanged(nullptr), icmplistener(nullptr) { auto m = ProcEventMapper::getInstance(); EvICMprimariMethod = m->newEvent(GAMMA, "HISTORY_MSG_ICM_OUTPUT_PRIMARIES"); @@ -304,8 +304,6 @@ ICMPanel::ICMPanel() : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iuncha ipDialog->set_show_hidden(true); // ProgramData is hidden on Windows #endif - oldip = ""; - wprofnamesconn = wProfNames->signal_changed().connect(sigc::mem_fun(*this, &ICMPanel::wpChanged)); oprofnamesconn = oProfNames->signal_changed().connect(sigc::mem_fun(*this, &ICMPanel::opChanged)); orendintentconn = oRendIntent->signal_changed().connect(sigc::mem_fun(*this, &ICMPanel::oiChanged)); @@ -617,8 +615,6 @@ void ICMPanel::write(ProcParams* pp, ParamsEdited* pedited) } else { pp->icm.inputProfile = ""; // just a directory } - - Glib::ustring p = Glib::path_get_dirname(ipDialog->get_filename()); } pp->icm.workingProfile = wProfNames->get_active_text(); diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc index 886d9ff5b..24b793fd9 100644 --- a/rtgui/imagearea.cc +++ b/rtgui/imagearea.cc @@ -29,7 +29,6 @@ ImageArea::ImageArea (ImageAreaPanel* p) : parent(p), fullImageWidth(0), fullImageHeight(0) { - infotext = ""; cropgl = nullptr; pmlistener = nullptr; pmhlistener = nullptr; @@ -148,7 +147,7 @@ void ImageArea::on_style_updated () void ImageArea::setInfoText (Glib::ustring text) { - infotext = text; + infotext = std::move(text); Glib::RefPtr context = get_pango_context () ; Pango::FontDescription fontd(get_style_context()->get_font()); @@ -160,7 +159,7 @@ void ImageArea::setInfoText (Glib::ustring text) // create text layout Glib::RefPtr ilayout = create_pango_layout(""); - ilayout->set_markup(text); + ilayout->set_markup(infotext); // get size of the text block int iw, ih; diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index a183a3419..85c5f463d 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -83,7 +83,6 @@ InspectorBuffer::~InspectorBuffer() { Inspector::Inspector () : currImage(nullptr), zoom(0.0), active(false) { - Glib::RefPtr style = get_style_context(); set_name("Inspector"); } @@ -115,7 +114,6 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) // compute the displayed area rtengine::Coord availableSize; rtengine::Coord topLeft; - rtengine::Coord displayedSize; rtengine::Coord dest(0, 0); availableSize.x = win->get_width(); availableSize.y = win->get_height(); @@ -125,7 +123,6 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) if (imW < availableSize.x) { // center the image in the available space along X topLeft.x = 0; - displayedSize.x = availableSize.x; dest.x = (availableSize.x - imW) / 2; } else { // partial image display @@ -139,7 +136,6 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) if (imH < availableSize.y) { // center the image in the available space along Y topLeft.y = 0; - displayedSize.y = availableSize.y; dest.y = (availableSize.y - imH) / 2; } else { // partial image display diff --git a/rtgui/main-cli.cc b/rtgui/main-cli.cc index cbea1d477..f71d7099d 100644 --- a/rtgui/main-cli.cc +++ b/rtgui/main-cli.cc @@ -256,7 +256,7 @@ int processLineParams ( int argc, char **argv ) { rtengine::procparams::PartialProfile *rawParams = nullptr, *imgParams = nullptr; std::vector inputFiles; - Glib::ustring outputPath = ""; + Glib::ustring outputPath; std::vector processingParams; bool outputDirectory = false; bool leaveUntouched = false; @@ -271,7 +271,7 @@ int processLineParams ( int argc, char **argv ) int subsampling = 3; int bits = -1; bool isFloat = false; - std::string outputType = ""; + std::string outputType; unsigned errors = 0; for ( int iArg = 1; iArg < argc; iArg++) { diff --git a/rtgui/metadatapanel.cc b/rtgui/metadatapanel.cc index ee97a7dfe..fed7622ea 100644 --- a/rtgui/metadatapanel.cc +++ b/rtgui/metadatapanel.cc @@ -26,9 +26,8 @@ using namespace rtengine; using namespace rtengine::procparams; -MetaDataPanel::MetaDataPanel() +MetaDataPanel::MetaDataPanel() : EvMetaDataMode(ProcEventMapper::getInstance()->newEvent(M_VOID, "HISTORY_MSG_METADATA_MODE")) { - EvMetaDataMode = ProcEventMapper::getInstance()->newEvent(M_VOID, "HISTORY_MSG_METADATA_MODE"); Gtk::HBox *box = Gtk::manage(new Gtk::HBox()); box->pack_start(*Gtk::manage(new Gtk::Label(M("TP_METADATA_MODE") + ": ")), Gtk::PACK_SHRINK, 4); diff --git a/rtgui/mycurve.h b/rtgui/mycurve.h index 82dd4a1a4..81a747bcd 100644 --- a/rtgui/mycurve.h +++ b/rtgui/mycurve.h @@ -28,6 +28,7 @@ #include "../rtengine/LUT.h" #include "guiutils.h" #include "options.h" +#include "../rtengine/noncopyable.h" #define RADIUS 3.5 /** radius of the control points ; must be x.5 to target the center of a pixel */ #define CBAR_WIDTH 10 /** inner width of the colored bar (border excluded) */ @@ -55,7 +56,7 @@ enum SnapToType { class MyCurveIdleHelper; class CurveEditor; -class MyCurve : public Gtk::DrawingArea, public BackBuffer, public ColorCaller, public CoordinateProvider +class MyCurve : public Gtk::DrawingArea, public BackBuffer, public ColorCaller, public CoordinateProvider, public rtengine::NonCopyable { friend class MyCurveIdleHelper; diff --git a/rtgui/mydiagonalcurve.cc b/rtgui/mydiagonalcurve.cc index a3e7b9375..cb96c039f 100644 --- a/rtgui/mydiagonalcurve.cc +++ b/rtgui/mydiagonalcurve.cc @@ -637,13 +637,8 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) setDirty(true); draw (lit_point); new_type = CSArrow; - retval = true; } } - - if (buttonPressed) { - retval = true; - } } else { // if (edited_point > -1) if (event->button.button == 3) { // do we edit another point? @@ -679,7 +674,6 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) newBoundaries.at(1).minVal = 0.; newBoundaries.at(1).maxVal = 1.; - retval = true; editedPos.at(0) = curve.x.at(edited_point); editedPos.at(1) = curve.y.at(edited_point); coordinateAdjuster->switchAdjustedPoint(editedPos, newBoundaries); @@ -691,12 +685,9 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) stopNumericalAdjustment(); } } - - retval = true; } } } - retval = true; } diff --git a/rtgui/myflatcurve.cc b/rtgui/myflatcurve.cc index 9796141d5..ebd0a9d0c 100644 --- a/rtgui/myflatcurve.cc +++ b/rtgui/myflatcurve.cc @@ -556,7 +556,7 @@ bool MyFlatCurve::getHandles(int n) if (!n) { // first point, the left handle is then computed with the last point's right handle prevX = curve.x.at(N - 1) - 1.0; - nextX = curve.x.at(n + 1); + nextX = curve.x.at(1); } else if (n == N - 1) { // last point, the right handle is then computed with the first point's left handle prevX = curve.x.at(n - 1); @@ -745,7 +745,6 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) newBoundaries.at(2).maxVal = 1.; newBoundaries.at(3).minVal = 0.; newBoundaries.at(3).maxVal = 1.; - retval = true; editedPos.at(0) = curve.x.at(edited_point); editedPos.at(1) = curve.y.at(edited_point); editedPos.at(2) = curve.leftTangent.at(edited_point); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 6e6c0cc5a..af984ba33 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1132,20 +1132,17 @@ void ParamsEdited::initFrom(const std::vector& wavelet.expnoise = wavelet.expnoise && p.wavelet.expnoise == other.wavelet.expnoise; wavelet.expclari = wavelet.expclari && p.wavelet.expclari == other.wavelet.expclari; - for (int i = 0; i < 9; i++) { - wavelet.c[i] = wavelet.c[i] && p.wavelet.c[i] == other.wavelet.c[i]; - } - - for (int i = 0; i < 9; i++) { - wavelet.ch[i] = wavelet.ch[i] && p.wavelet.ch[i] == other.wavelet.ch[i]; + for (int level = 0; level < 9; ++level) { + wavelet.c[level] = wavelet.c[level] && p.wavelet.c[level] == other.wavelet.c[level]; + wavelet.ch[level] = wavelet.ch[level] && p.wavelet.ch[level] == other.wavelet.ch[level]; } 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]; + for (int level = 0; level < 6; ++level) { + dirpyrequalizer.mult[level] = dirpyrequalizer.mult[level] && p.dirpyrequalizer.mult[level] == other.dirpyrequalizer.mult[level]; } dirpyrequalizer.threshold = dirpyrequalizer.threshold && p.dirpyrequalizer.threshold == other.dirpyrequalizer.threshold; diff --git a/rtgui/placesbrowser.cc b/rtgui/placesbrowser.cc index 9935064ee..6fb04ac53 100644 --- a/rtgui/placesbrowser.cc +++ b/rtgui/placesbrowser.cc @@ -230,15 +230,15 @@ void PlacesBrowser::refreshPlacesList () } for (size_t i = 0; i < options.favoriteDirs.size(); i++) { - Glib::RefPtr hfile = Gio::File::create_for_path (options.favoriteDirs[i]); + Glib::RefPtr fav = Gio::File::create_for_path (options.favoriteDirs[i]); - if (hfile && hfile->query_exists()) { + if (fav && fav->query_exists()) { try { - if (auto info = hfile->query_info ()) { + if (auto info = fav->query_info ()) { Gtk::TreeModel::Row newrow = *(placesModel->append()); newrow[placesColumns.label] = info->get_display_name (); newrow[placesColumns.icon] = info->get_icon (); - newrow[placesColumns.root] = hfile->get_parse_name (); + newrow[placesColumns.root] = fav->get_parse_name (); newrow[placesColumns.type] = 5; newrow[placesColumns.rowSeparator] = false; } diff --git a/rtgui/popupcommon.h b/rtgui/popupcommon.h index f939dbe96..92d6a6214 100644 --- a/rtgui/popupcommon.h +++ b/rtgui/popupcommon.h @@ -47,7 +47,7 @@ public: type_signal_item_selected signal_item_selected(); Gtk::Grid* buttonGroup; // this is the widget to be packed - PopUpCommon (Gtk::Button* button, const Glib::ustring& label = ""); + explicit PopUpCommon (Gtk::Button* button, const Glib::ustring& label = ""); virtual ~PopUpCommon (); bool addEntry (const Glib::ustring& fileName, const Glib::ustring& label); int getEntryCount () const; diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 2269c6749..e44ad602e 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -56,6 +56,7 @@ Glib::RefPtr fontcss; Preferences::Preferences (RTWindow *rtwindow) : Gtk::Dialog (M ("MAIN_BUTTON_PREFERENCES"), *rtwindow, true) + , regex(Glib::Regex::create (THEMEREGEXSTR, Glib::RegexCompileFlags::REGEX_CASELESS)) , splash (nullptr) , rprofiles (nullptr) , iprofiles (nullptr) @@ -63,7 +64,6 @@ Preferences::Preferences (RTWindow *rtwindow) , newFont (false) , newCPFont (false) { - regex = Glib::Regex::create (THEMEREGEXSTR, Glib::RegexCompileFlags::REGEX_CASELESS); moptions.copyFrom (&options); diff --git a/rtgui/previewhandler.h b/rtgui/previewhandler.h index fcd0a0c5f..7a93ed480 100644 --- a/rtgui/previewhandler.h +++ b/rtgui/previewhandler.h @@ -28,6 +28,7 @@ #include "guiutils.h" #include "../rtengine/rtengine.h" +#include "../rtengine/noncopyable.h" class PreviewListener { @@ -44,7 +45,7 @@ struct PreviewHandlerIdleHelper { int pending; }; -class PreviewHandler : public rtengine::PreviewImageListener +class PreviewHandler : public rtengine::PreviewImageListener, public rtengine::NonCopyable { private: friend int setImageUI (void* data); diff --git a/rtgui/profilepanel.cc b/rtgui/profilepanel.cc index af39695fa..c969d13c0 100644 --- a/rtgui/profilepanel.cc +++ b/rtgui/profilepanel.cc @@ -42,7 +42,7 @@ void ProfilePanel::cleanup () delete partialProfileDlg; } -ProfilePanel::ProfilePanel () : storedPProfile(nullptr), lastFilename(""), imagePath(""), lastSavedPSE(nullptr), customPSE(nullptr) +ProfilePanel::ProfilePanel () : storedPProfile(nullptr), lastSavedPSE(nullptr), customPSE(nullptr) { tpc = nullptr; diff --git a/rtgui/profilepanel.h b/rtgui/profilepanel.h index b0fb42ab7..bc42f96c3 100644 --- a/rtgui/profilepanel.h +++ b/rtgui/profilepanel.h @@ -28,8 +28,9 @@ #include "guiutils.h" #include "profilestorecombobox.h" #include "rtimage.h" +#include "../rtengine/noncopyable.h" -class ProfilePanel : public Gtk::Grid, public PParamsChangeListener, public ProfileStoreListener +class ProfilePanel : public Gtk::Grid, public PParamsChangeListener, public ProfileStoreListener, public rtengine::NonCopyable { private: diff --git a/rtgui/profilestorecombobox.cc b/rtgui/profilestorecombobox.cc index 96bbc32fa..ae84bd951 100644 --- a/rtgui/profilestorecombobox.cc +++ b/rtgui/profilestorecombobox.cc @@ -37,23 +37,22 @@ ProfileStoreComboBox::ProfileStoreComboBox () setPreferredWidth (50, 120); } -Glib::ustring ProfileStoreComboBox::getCurrentLabel() +Glib::ustring ProfileStoreComboBox::getCurrentLabel() const { - Glib::ustring currLabel; - Gtk::TreeModel::iterator currRow = get_active(); + const Gtk::TreeModel::const_iterator currRow = get_active(); if (currRow) { const ProfileStoreEntry *currEntry = (*currRow)[methodColumns.profileStoreEntry]; return currEntry->label; } - return currLabel; + return {}; } -const ProfileStoreEntry* ProfileStoreComboBox::getSelectedEntry() +const ProfileStoreEntry* ProfileStoreComboBox::getSelectedEntry() const { - Gtk::TreeModel::iterator currRow_ = get_active(); - Gtk::TreeModel::Row currRow = *currRow_; + const Gtk::TreeModel::const_iterator currRow_ = get_active(); + const Gtk::TreeModel::Row currRow = *currRow_; if (currRow) { return currRow[methodColumns.profileStoreEntry]; @@ -145,18 +144,16 @@ void ProfileStoreComboBox::updateProfileList () cellRenderer->property_ellipsize_set() = true; } -Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry_ (Gtk::TreeModel::Children childs, const ProfileStoreEntry *pse) +Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry_ (Gtk::TreeModel::Children childs, const ProfileStoreEntry *pse) const { - Gtk::TreeModel::Row row; - Gtk::TreeIter rowInSubLevel; - for (Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { - row = *iter; + for (const auto& iter : childs) { + const Gtk::TreeModel::Row row = *iter; // Hombre: is there a smarter way of knowing if this row has childs? const ProfileStoreEntry *pse_ = row[methodColumns.profileStoreEntry]; if (pse_->type == PSET_FOLDER) { - rowInSubLevel = findRowFromEntry_ (iter->children(), pse); + const Gtk::TreeIter rowInSubLevel = findRowFromEntry_ (iter->children(), pse); if (rowInSubLevel) { // entry found @@ -171,30 +168,27 @@ Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry_ (Gtk::TreeModel::Children return childs.end(); } -Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry (const ProfileStoreEntry *pse) +Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry (const ProfileStoreEntry *pse) const { Gtk::TreeModel::Children childs = refTreeModel->children(); if (pse) { - Gtk::TreeIter row = findRowFromEntry_ (childs, pse); - return row; + return findRowFromEntry_ (childs, pse); } return childs.end(); } -Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath_ (Gtk::TreeModel::Children childs, int parentFolderId, Glib::ustring &name) +Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath_ (Gtk::TreeModel::Children childs, int parentFolderId, const Glib::ustring &name) const { - Gtk::TreeModel::Row row; - Gtk::TreeIter rowInSubLevel; - for (Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { - row = *iter; + for (const auto iter : childs) { + const Gtk::TreeModel::Row row = *iter; // Hombre: is there a smarter way of knowing if this row has childs? const ProfileStoreEntry *pse = row[methodColumns.profileStoreEntry]; if (pse->type == PSET_FOLDER) { - rowInSubLevel = findRowFromFullPath_ (iter->children(), parentFolderId, name); + const Gtk::TreeIter rowInSubLevel = findRowFromFullPath_ (iter->children(), parentFolderId, name); if (rowInSubLevel) { // entry found @@ -209,88 +203,77 @@ Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath_ (Gtk::TreeModel::Childr return childs.end(); } -Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath (Glib::ustring path) +Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath (const Glib::ustring &path) const { - Gtk::TreeIter row; - ProfileStore *profileStore = ProfileStore::getInstance(); if (path.empty()) { - return row; + return {}; } + const ProfileStore *profileStore = ProfileStore::getInstance(); + if (path == DEFPROFILE_INTERNAL) { - row = findRowFromEntry (profileStore->getInternalDefaultPSE()); - return row; + return findRowFromEntry (profileStore->getInternalDefaultPSE()); } if (path == DEFPROFILE_DYNAMIC) { - row = findRowFromEntry (profileStore->getInternalDynamicPSE()); - return row; + return findRowFromEntry (profileStore->getInternalDynamicPSE()); } // removing the filename - Glib::ustring fName = Glib::path_get_basename (path); + const Glib::ustring fName = Glib::path_get_basename(path); if (!fName.empty()) { - path = path.substr (0, path.length() - fName.length()); - } else { - // path is malformed; - return row; + int parentFolderId = profileStore->findFolderId (Glib::path_get_dirname (path.substr (0, path.length() - fName.length()))); + // 1. find the path in the folder list + if (parentFolderId != -1) { + return findRowFromFullPath_ (refTreeModel->children(), parentFolderId, fName); + } } - path = Glib::path_get_dirname (path); - int parentFolderId = profileStore->findFolderId (path); - - // 1. find the path in the folder list - if (parentFolderId != -1) { - row = findRowFromFullPath_ (refTreeModel->children(), parentFolderId, fName); - } - - return row; + return {}; } /** @brief Get the absolute full path of the active row entry. * @return The absolute full path of the active row entry, or the "Internal" keyword, * or an empty string if the ComboBox is in an invalid state */ -Glib::ustring ProfileStoreComboBox::getFullPathFromActiveRow() +Glib::ustring ProfileStoreComboBox::getFullPathFromActiveRow() const { - Glib::ustring path; - Gtk::TreeModel::iterator currRowI = get_active(); - ProfileStore *profileStore = ProfileStore::getInstance(); + const Gtk::TreeModel::const_iterator currRowI = get_active(); if (!currRowI) { - return path; + return {}; } Gtk::TreeModel::Row currRow = *currRowI; if (currRow) { - const ProfileStoreEntry *currEntry = currRow[methodColumns.profileStoreEntry]; if (!currEntry) { - return path; + return {}; } + const ProfileStore *profileStore = ProfileStore::getInstance(); if (currEntry == profileStore->getInternalDefaultPSE()) { - return Glib::ustring (DEFPROFILE_INTERNAL); + return DEFPROFILE_INTERNAL; } if (currEntry == profileStore->getInternalDynamicPSE()) { - return Glib::ustring (DEFPROFILE_DYNAMIC); + return DEFPROFILE_DYNAMIC; } - path = Glib::build_filename (profileStore->getPathFromId (currEntry->parentFolderId), currEntry->label); + return Glib::build_filename (profileStore->getPathFromId (currEntry->parentFolderId), currEntry->label); } - return path; + return {}; } -bool ProfileStoreComboBox::setActiveRowFromFullPath (Glib::ustring path) +bool ProfileStoreComboBox::setActiveRowFromFullPath (const Glib::ustring &path) { if (!path.empty()) { - Gtk::TreeIter row = findRowFromFullPath (path); + const Gtk::TreeIter row = findRowFromFullPath (path); if (row) { set_active (row); @@ -304,7 +287,7 @@ bool ProfileStoreComboBox::setActiveRowFromFullPath (Glib::ustring path) bool ProfileStoreComboBox::setActiveRowFromEntry (const ProfileStoreEntry *pse) { if (pse) { - Gtk::TreeIter row = findRowFromEntry (pse); + const Gtk::TreeIter row = findRowFromEntry (pse); if (row) { set_active (row); @@ -321,16 +304,13 @@ bool ProfileStoreComboBox::setInternalEntry () } /** @brief Get the row from the first level of the tree that match the provided name */ -Gtk::TreeIter ProfileStoreComboBox::getRowFromLabel (Glib::ustring name) +Gtk::TreeIter ProfileStoreComboBox::getRowFromLabel (const Glib::ustring &name) const { - Gtk::TreeIter row; - Gtk::TreeModel::Children childs = refTreeModel->children(); + const Gtk::TreeModel::Children childs = refTreeModel->children(); if (!name.empty()) { - Gtk::TreeModel::Row currRow; - - for (Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { - currRow = *iter; + for (const auto iter : childs) { + const Gtk::TreeModel::Row currRow = *iter; const ProfileStoreEntry *pse = currRow[methodColumns.profileStoreEntry]; if (pse->label == name) { diff --git a/rtgui/profilestorecombobox.h b/rtgui/profilestorecombobox.h index 9c31ad60a..3796e0471 100644 --- a/rtgui/profilestorecombobox.h +++ b/rtgui/profilestorecombobox.h @@ -24,7 +24,6 @@ #include #include "../rtengine/rtengine.h" -#include "../rtengine/noncopyable.h" #include "../rtengine/profilestore.h" #include "threadutils.h" @@ -35,7 +34,7 @@ /** * @brief subclass of Gtk::Label with extra fields for Combobox and Menu, to link with a ProfileStoreEntry */ -class ProfileStoreLabel : public Gtk::Label +class ProfileStoreLabel final : public Gtk::Label { public: @@ -44,7 +43,7 @@ public: #ifndef NDEBUG ProfileStoreLabel() : Gtk::Label ("*** error ***"), entry (nullptr) {} #else - ProfileStoreLabel() : Gtk::Label (""), entry (NULL) {} + ProfileStoreLabel() : Gtk::Label (""), entry (nullptr) {} #endif /** @brief Create a new ProfileStoreLabel @@ -55,11 +54,11 @@ public: ProfileStoreLabel (const ProfileStoreLabel &other); }; -class ProfileStoreComboBox : public MyComboBox +class ProfileStoreComboBox final : public MyComboBox { -protected: - class MethodColumns : public Gtk::TreeModel::ColumnRecord +private: + class MethodColumns final : public Gtk::TreeModel::ColumnRecord { public: Gtk::TreeModelColumn label; @@ -74,21 +73,22 @@ protected: Glib::RefPtr refTreeModel; MethodColumns methodColumns; void refreshProfileList_ (Gtk::TreeModel::Row *parentRow, int parentFolderId, bool initial, const std::vector *entryList); - Gtk::TreeIter findRowFromEntry_ (Gtk::TreeModel::Children childs, const ProfileStoreEntry *pse); - Gtk::TreeIter findRowFromFullPath_ (Gtk::TreeModel::Children childs, int parentFolderId, Glib::ustring &name); + Gtk::TreeIter findRowFromEntry_ (Gtk::TreeModel::Children childs, const ProfileStoreEntry *pse) const; + Gtk::TreeIter findRowFromFullPath_ (Gtk::TreeModel::Children childs, int parentFolderId, const Glib::ustring &name) const; + Gtk::TreeIter findRowFromEntry (const ProfileStoreEntry *pse) const; + Gtk::TreeIter findRowFromFullPath (const Glib::ustring &path) const; + public: ProfileStoreComboBox(); void updateProfileList(); - Glib::ustring getCurrentLabel(); - const ProfileStoreEntry* getSelectedEntry(); - Gtk::TreeIter findRowFromEntry (const ProfileStoreEntry *pse); - Gtk::TreeIter findRowFromFullPath (Glib::ustring path); - Glib::ustring getFullPathFromActiveRow (); - bool setActiveRowFromFullPath (Glib::ustring oldPath); + Glib::ustring getCurrentLabel() const; + const ProfileStoreEntry* getSelectedEntry() const; + Glib::ustring getFullPathFromActiveRow () const; + bool setActiveRowFromFullPath (const Glib::ustring &oldPath); bool setActiveRowFromEntry (const ProfileStoreEntry *pse); bool setInternalEntry (); - Gtk::TreeIter getRowFromLabel (Glib::ustring name); + Gtk::TreeIter getRowFromLabel (const Glib::ustring &name) const; Gtk::TreeIter addRow (const ProfileStoreEntry *profileStoreEntry); void deleteRow (const ProfileStoreEntry *profileStoreEntry); }; diff --git a/rtgui/rgbcurves.cc b/rtgui/rgbcurves.cc index 560ee7e57..81d997add 100644 --- a/rtgui/rgbcurves.cc +++ b/rtgui/rgbcurves.cc @@ -23,7 +23,7 @@ using namespace rtengine; using namespace rtengine::procparams; -RGBCurves::RGBCurves () : FoldableToolPanel(this, "rgbcurves", M("TP_RGBCURVES_LABEL"), false, true) +RGBCurves::RGBCurves () : FoldableToolPanel(this, "rgbcurves", M("TP_RGBCURVES_LABEL"), false, true), lastLumamode(false) { lumamode = Gtk::manage (new Gtk::CheckButton (M("TP_RGBCURVES_LUMAMODE"))); diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc index cd687f252..3fdf743f5 100644 --- a/rtgui/rtimage.cc +++ b/rtgui/rtimage.cc @@ -37,12 +37,8 @@ int RTImage::scaleBack = 0; RTImage::RTImage () {} -RTImage::RTImage (RTImage &other) +RTImage::RTImage (RTImage &other) : surface(other.surface), pixbuf(other.pixbuf) { - dpiBack = other.dpiBack; - scaleBack = other.scaleBack; - pixbuf = other.pixbuf; - surface = other.surface; if (pixbuf) { set(pixbuf); } else if (surface) { diff --git a/rtgui/rtimage.h b/rtgui/rtimage.h index 5679f6edc..244d0030a 100644 --- a/rtgui/rtimage.h +++ b/rtgui/rtimage.h @@ -38,11 +38,11 @@ protected: public: RTImage (); RTImage (RTImage &other); - RTImage (Glib::RefPtr &pixbuf); - RTImage (Cairo::RefPtr &surf); - RTImage(Cairo::RefPtr other); - RTImage (Glib::RefPtr &other); - RTImage (const Glib::ustring& fileName, const Glib::ustring& rtlFileName = Glib::ustring()); + explicit RTImage (Glib::RefPtr &pixbuf); + explicit RTImage (Cairo::RefPtr &surf); + explicit RTImage(Cairo::RefPtr other); + explicit RTImage (Glib::RefPtr &other); + explicit RTImage (const Glib::ustring& fileName, const Glib::ustring& rtlFileName = Glib::ustring()); void setImage (const Glib::ustring& fileName, const Glib::ustring& rtlFileName = Glib::ustring()); void changeImage (const Glib::ustring& imageName); diff --git a/rtgui/rtscalable.cc b/rtgui/rtscalable.cc index aaa10bd21..079ece8d2 100644 --- a/rtgui/rtscalable.cc +++ b/rtgui/rtscalable.cc @@ -220,7 +220,7 @@ Cairo::RefPtr RTScalable::loadImage(const Glib::ustring &fn GError **error = nullptr; RsvgHandle *handle = rsvg_handle_new_from_data((unsigned const char*)updatedSVG.c_str(), updatedSVG.length(), error); - if (handle == nullptr) { + if (error && !handle) { std::cerr << "ERROR: Can't use the provided data for \"" << fname << "\" to create a RsvgHandle:" << std::endl << Glib::ustring((*error)->message) << std::endl; Cairo::RefPtr surf = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, 10, 10); diff --git a/rtgui/rtsurface.h b/rtgui/rtsurface.h index c314ab1c1..b442b7493 100644 --- a/rtgui/rtsurface.h +++ b/rtgui/rtsurface.h @@ -30,7 +30,7 @@ class RTSurface : { public: RTSurface(); - RTSurface(const Glib::ustring& fileName, const Glib::ustring& rtlFileName = {}); + explicit RTSurface(const Glib::ustring& fileName, const Glib::ustring& rtlFileName = {}); void setImage(const Glib::ustring& fileName, const Glib::ustring& rtlFileName = {}); diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index 6158cb76a..85b902727 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -173,8 +173,8 @@ RTWindow::RTWindow () } else { Glib::RefPtr style = Gtk::StyleContext::create(); Pango::FontDescription pfd = style->get_font(Gtk::STATE_FLAG_NORMAL); - int pt; if (pfd.get_set_fields() & Pango::FONT_MASK_SIZE) { + int pt; int fontSize = pfd.get_size(); bool isPix = pfd.get_size_is_absolute(); int resolution = (int)style->get_screen()->get_resolution(); @@ -254,8 +254,6 @@ RTWindow::RTWindow () #if defined(__APPLE__) { osxApp = (GtkosxApplication *)g_object_new (GTKOSX_TYPE_APPLICATION, NULL); - gboolean falseval = FALSE; - gboolean trueval = TRUE; RTWindow *rtWin = this; g_signal_connect (osxApp, "NSApplicationBlockTermination", G_CALLBACK (osx_should_quit_cb), rtWin); g_signal_connect (osxApp, "NSApplicationWillTerminate", G_CALLBACK (osx_will_quit_cb), rtWin); diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h index 5b58ab0eb..d037d8875 100644 --- a/rtgui/rtwindow.h +++ b/rtgui/rtwindow.h @@ -29,8 +29,9 @@ #if defined(__APPLE__) #include #endif +#include "../rtengine/noncopyable.h" -class RTWindow : public Gtk::Window, public rtengine::ProgressListener +class RTWindow : public Gtk::Window, public rtengine::ProgressListener, public rtengine::NonCopyable { private: diff --git a/rtgui/saveformatpanel.h b/rtgui/saveformatpanel.h index e25210b97..7d7210282 100644 --- a/rtgui/saveformatpanel.h +++ b/rtgui/saveformatpanel.h @@ -23,6 +23,7 @@ #include "adjuster.h" #include "guiutils.h" #include "options.h" +#include "../rtengine/noncopyable.h" class FormatChangeListener { @@ -31,7 +32,7 @@ public: virtual void formatChanged(const Glib::ustring& format) = 0; }; -class SaveFormatPanel : public Gtk::Grid, public AdjusterListener +class SaveFormatPanel : public Gtk::Grid, public AdjusterListener, public rtengine::NonCopyable { protected: diff --git a/rtgui/splash.cc b/rtgui/splash.cc index d608ccd97..36b796c4d 100644 --- a/rtgui/splash.cc +++ b/rtgui/splash.cc @@ -27,15 +27,13 @@ extern Glib::ustring creditsPath; extern Glib::ustring licensePath; extern Glib::ustring versionString; -SplashImage::SplashImage () +SplashImage::SplashImage () : surface(RTImage::createImgSurfFromFile("splash.png")) { - surface = RTImage::createImgSurfFromFile ("splash.png"); } bool SplashImage::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) { - Glib::RefPtr window = get_window(); cr->set_source(surface, 0., 0.); cr->rectangle(0, 0, surface->get_width(), surface->get_height()); cr->fill(); diff --git a/rtgui/thresholdselector.cc b/rtgui/thresholdselector.cc index e1e6fc36f..9b5250862 100644 --- a/rtgui/thresholdselector.cc +++ b/rtgui/thresholdselector.cc @@ -30,7 +30,7 @@ ThresholdSelector::ThresholdSelector(double minValueBottom, double maxValueBottom, double defBottom, Glib::ustring labelBottom, unsigned int precisionBottom, double minValueTop, double maxValueTop, double defTop, Glib::ustring labelTop, unsigned int precisionTop, ThresholdCurveProvider* curveProvider) - : coloredBar(RTO_Left2Right) + : separatedLabelBottom(std::move(labelBottom)), separatedLabelTop(std::move(labelTop)), coloredBar(RTO_Left2Right) { positions[TS_BOTTOMLEFT] = defPos[TS_BOTTOMLEFT] = defBottom; positions[TS_TOPLEFT] = defPos[TS_TOPLEFT] = defTop; @@ -40,8 +40,6 @@ ThresholdSelector::ThresholdSelector(double minValueBottom, double maxValueBotto this->precisionBottom = precisionBottom; doubleThresh = false; - separatedLabelBottom = labelBottom; - separatedLabelTop = labelTop; bgCurveProvider = curveProvider; separatedSliders = true; @@ -66,9 +64,6 @@ ThresholdSelector::ThresholdSelector(double minValue, double maxValue, double de this->precisionBottom = precision; doubleThresh = false; - separatedLabelBottom = ""; - separatedLabelTop = ""; - #ifndef NDEBUG if (startAtOne) { @@ -106,9 +101,6 @@ ThresholdSelector::ThresholdSelector(double minValue, double maxValue, double de this->precisionBottom = precision; doubleThresh = true; - separatedLabelBottom = ""; - separatedLabelTop = ""; - #ifndef NDEBUG if (startAtOne) { @@ -329,14 +321,13 @@ void ThresholdSelector::updateBackBuffer() if (pts.size() >= 4) { std::vector::iterator i = pts.begin(); - double x = *i; ++i; double y = *i; ++i; cr->move_to (xStart, ih*y + yStart); for (; i < pts.end(); ) { - x = *i; + double x = *i; ++i; y = *i; ++i; diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc index 20a7d3e44..caf7d7b97 100644 --- a/rtgui/thumbbrowserbase.cc +++ b/rtgui/thumbbrowserbase.cc @@ -28,7 +28,7 @@ using namespace std; ThumbBrowserBase::ThumbBrowserBase () - : location(THLOC_FILEBROWSER), inspector(nullptr), isInspectorActive(false), eventTime(0), lastClicked(nullptr), anchor(nullptr), previewHeight(options.thumbSize), numOfCols(1), arrangement(TB_Horizontal) + : location(THLOC_FILEBROWSER), inspector(nullptr), isInspectorActive(false), eventTime(0), lastClicked(nullptr), anchor(nullptr), previewHeight(options.thumbSize), numOfCols(1), lastRowHeight(0), arrangement(TB_Horizontal) { inW = -1; inH = -1; @@ -44,6 +44,8 @@ ThumbBrowserBase::ThumbBrowserBase () show_all (); + vscroll.get_adjustment()->set_lower(0); + hscroll.get_adjustment()->set_lower(0); vscroll.signal_value_changed().connect( sigc::mem_fun(*this, &ThumbBrowserBase::scrollChanged) ); hscroll.signal_value_changed().connect( sigc::mem_fun(*this, &ThumbBrowserBase::scrollChanged) ); @@ -223,21 +225,21 @@ void ThumbBrowserBase::selectSet (ThumbBrowserEntryBase* clicked) static void scrollToEntry (double& h, double& v, int iw, int ih, ThumbBrowserEntryBase* entry) { - const int hmin = entry->getX (); - const int hmax = hmin + entry->getEffectiveWidth () - iw; - const int vmin = entry->getY (); - const int vmax = vmin + entry->getEffectiveHeight () - ih; + const int hMin = entry->getX(); + const int hMax = hMin + entry->getEffectiveWidth() - iw; + const int vMin = entry->getY(); + const int vMax = vMin + entry->getEffectiveHeight() - ih; - if (hmin < 0) { - h += hmin; - } else if (hmax > 0) { - h += hmax; + if (hMin < 0) { + h += hMin; + } else if (hMax > 0) { + h += hMax; } - if(vmin < 0) { - v += vmin; - } else if (vmax > 0) { - v += vmax; + if (vMin < 0) { + v += vMin; + } else if (vMax > 0) { + v += vMax; } } @@ -545,7 +547,6 @@ void ThumbBrowserBase::configScrollBars () auto ha = hscroll.get_adjustment(); int iw = internal.get_width(); ha->set_upper(inW); - ha->set_lower(0); ha->set_step_increment(!fd.empty() ? fd[0]->getEffectiveWidth() : 0); ha->set_page_increment(iw); ha->set_page_size(iw); @@ -560,7 +561,6 @@ void ThumbBrowserBase::configScrollBars () auto va = vscroll.get_adjustment(); va->set_upper(inH); - va->set_lower(0); const auto height = !fd.empty() ? fd[0]->getEffectiveHeight() : 0; va->set_step_increment(height); va->set_page_increment(height == 0 ? ih : (ih / height) * height); @@ -574,8 +574,22 @@ void ThumbBrowserBase::configScrollBars () } } -void ThumbBrowserBase::arrangeFiles(bool checkfilter) +void ThumbBrowserBase::arrangeFiles(ThumbBrowserEntryBase* entry) { + + if (fd.empty()) { + // nothing to arrange + resizeThumbnailArea(0, 0); + return; + } + if(entry && entry->filtered) { + // a filtered entry was added, nothing to arrange, but has to be marked not drawable + MYREADERLOCK(l, entryRW); + entry->drawable = false; + MYREADERLOCK_RELEASE(l); + return; + } + MYREADERLOCK(l, entryRW); // GUI already locked by ::redraw, the only caller of this method for now. @@ -583,17 +597,22 @@ void ThumbBrowserBase::arrangeFiles(bool checkfilter) //GThreadLock lock; int rowHeight = 0; - for (const auto entry : fd) { - if (checkfilter) { - // apply filter - entry->filtered = !checkFilter(entry); - } + if (entry) { + // we got the reference to the added entry, makes calculation of rowHeight O(1) + lastRowHeight = rowHeight = std::max(lastRowHeight, entry->getMinimalHeight()); + } else { - // compute size of the items - if (!entry->filtered) { - rowHeight = std::max(entry->getMinimalHeight(), rowHeight); + lastRowHeight = 0; + for (const auto thumb : fd) { + // apply filter + thumb->filtered = !checkFilter(thumb); + // compute max rowHeight + if (!thumb->filtered) { + rowHeight = std::max(thumb->getMinimalHeight(), rowHeight); + } } } + if (arrangement == TB_Horizontal) { numOfCols = 1; @@ -601,7 +620,6 @@ void ThumbBrowserBase::arrangeFiles(bool checkfilter) for (unsigned int ct = 0; ct < fd.size(); ++ct) { // arrange items in the column - int curry = 0; for (; ct < fd.size() && fd[ct]->filtered; ++ct) { fd[ct]->drawable = false; @@ -610,10 +628,9 @@ void ThumbBrowserBase::arrangeFiles(bool checkfilter) if (ct < fd.size()) { const int maxw = fd[ct]->getMinimalWidth(); - fd[ct]->setPosition(currx, curry, maxw, rowHeight); + fd[ct]->setPosition(currx, 0, maxw, rowHeight); fd[ct]->drawable = true; currx += maxw; - curry += rowHeight; } } @@ -624,14 +641,16 @@ void ThumbBrowserBase::arrangeFiles(bool checkfilter) const int availWidth = internal.get_width(); // initial number of columns + int oldNumOfCols = numOfCols; numOfCols = 0; int colsWidth = 0; for (unsigned int i = 0; i < fd.size(); ++i) { if (!fd[i]->filtered && colsWidth + fd[i]->getMinimalWidth() <= availWidth) { - colsWidth += fd[numOfCols]->getMinimalWidth(); + colsWidth += fd[i]->getMinimalWidth(); ++numOfCols; if(colsWidth > availWidth) { + --numOfCols; break; } } @@ -667,8 +686,73 @@ void ThumbBrowserBase::arrangeFiles(bool checkfilter) // arrange files int curry = 0; + size_t ct = 0; + if (entry) { + std::vector oldColWidths; + if (oldNumOfCols == numOfCols) { + for (; oldNumOfCols > 0; --oldNumOfCols) { + // compute old column widths + oldColWidths.assign(oldNumOfCols, 0); + + for (unsigned int i = 0, j = 0; i < fd.size(); ++i) { + if (fd[i] != entry && !fd[i]->filtered && fd[i]->getMinimalWidth() > oldColWidths[j % oldNumOfCols]) { + oldColWidths[j % oldNumOfCols] = fd[i]->getMinimalWidth(); + } + + if (fd[i] != entry && !fd[i]->filtered) { + ++j; + } + } + if (oldNumOfCols == 1 || std::accumulate(oldColWidths.begin(), oldColWidths.end(), 0) < availWidth) { + break; + } + } + } + + bool arrangeAll = true; + if (oldNumOfCols == numOfCols) { + arrangeAll = false; + for (int i = 0; i < numOfCols; ++i) { + if(colWidths[i] != oldColWidths[i]) { + arrangeAll = true; + break; + } + } + } + if (!arrangeAll) { + int j = 0; + // Find currently added entry + for (; ct < fd.size() && fd[ct] != entry; j += !fd[ct]->filtered, ++ct) { + } + //Calculate the position of currently added entry + const int row = j / numOfCols; + const int col = j % numOfCols; + curry = row * rowHeight; + int currx = 0; + for (int c = 0; c < col; ++c) { + currx += colWidths[c]; + } + // arrange all entries in the row beginning with the currently added one + for (int i = col; ct < fd.size() && i < numOfCols; ++i, ++ct) { + for (; ct < fd.size() && fd[ct]->filtered; ++ct) { + fd[ct]->drawable = false; + } + if (ct < fd.size()) { + fd[ct]->setPosition(currx, curry, colWidths[i], rowHeight); + fd[ct]->drawable = true; + currx += colWidths[i]; + } + } + + if (currx > 0) { // there were thumbnails placed in the row + curry += rowHeight; + } + } + } + + // arrange remaining entries, if any, that's the most expensive part + for (; ct < fd.size();) { - for (unsigned int ct = 0; ct < fd.size();) { // arrange items in the row int currx = 0; @@ -691,7 +775,7 @@ void ThumbBrowserBase::arrangeFiles(bool checkfilter) MYREADERLOCK_RELEASE(l); // This will require a Writer access - resizeThumbnailArea (colsWidth, curry); + resizeThumbnailArea(colsWidth, curry); } } @@ -779,7 +863,6 @@ void ThumbBrowserBase::on_style_updated () ThumbBrowserBase::Internal::Internal () : ofsX(0), ofsY(0), parent(nullptr), dirty(true) { - Glib::RefPtr style = get_style_context(); set_name("FileCatalog"); } @@ -985,11 +1068,11 @@ bool ThumbBrowserBase::Internal::on_scroll_event (GdkEventScroll* event) } -void ThumbBrowserBase::redraw (bool checkfilter) +void ThumbBrowserBase::redraw (ThumbBrowserEntryBase* entry) { GThreadLock lock; - arrangeFiles(checkfilter); + arrangeFiles(entry); queue_draw(); } diff --git a/rtgui/thumbbrowserbase.h b/rtgui/thumbbrowserbase.h index 953ec44ec..aefd72044 100644 --- a/rtgui/thumbbrowserbase.h +++ b/rtgui/thumbbrowserbase.h @@ -175,12 +175,13 @@ protected: int previewHeight; int numOfCols; + int lastRowHeight; Arrangement arrangement; std::set editedFiles; - void arrangeFiles (bool checkfilter = true); + void arrangeFiles (ThumbBrowserEntryBase* entry = nullptr); void zoomChanged (bool zoomIn); public: @@ -202,7 +203,7 @@ public: return fd; } void on_style_updated () override; - void redraw (bool checkfilter = true); // arrange files and draw area + void redraw (ThumbBrowserEntryBase* entry = nullptr); // arrange files and draw area void refreshThumbImages (); // refresh thumbnail sizes, re-generate thumbnail images, arrange and draw void refreshQuickThumbImages (); // refresh thumbnail sizes, re-generate thumbnail images, arrange and draw void refreshEditedState (const std::set& efiles); @@ -215,7 +216,7 @@ public: void setArrangement (Arrangement a); void enableTabMode(bool enable); // set both thumb sizes and arrangements - virtual bool checkFilter (ThumbBrowserEntryBase* entry) + virtual bool checkFilter (ThumbBrowserEntryBase* entry) const { return true; } diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc index 6ac3d629b..79291c423 100644 --- a/rtgui/thumbnail.cc +++ b/rtgui/thumbnail.cc @@ -232,8 +232,6 @@ const ProcParams& Thumbnail::getProcParamsU () rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool returnParams, bool force, bool flaggingMode) { - static int index = 0; // Will act as unique identifier during the session - // try to load the last saved parameters from the cache or from the paramfile file ProcParams* ldprof = nullptr; @@ -285,6 +283,7 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu imageMetaData = rtengine::FramesMetaData::fromFile (fname, nullptr, true); } + static int index = 0; // Will act as unique identifier during the session Glib::ustring tmpFileName( Glib::build_filename(options.cacheBaseDir, Glib::ustring::compose("CPB_temp_%1.txt", index++)) ); const rtexif::TagDirectory* exifDir = nullptr; @@ -474,6 +473,7 @@ void Thumbnail::setProcParams (const ProcParams& pp, ParamsEdited* pe, int whoCh || pparams->filmSimulation != pp.filmSimulation || pparams->softlight != pp.softlight || pparams->dehaze != pp.dehaze + || pparams->filmNegative != pp.filmNegative || whoChangedIt == FILEBROWSER || whoChangedIt == BATCHEDITOR; @@ -1019,9 +1019,7 @@ int Thumbnail::getRank () const void Thumbnail::setRank (int rank) { - if (pparams->rank != rank) { - pparams->rank = rank; - } + pparams->rank = rank; pparamsValid = true; } diff --git a/rtgui/toolpanel.h b/rtgui/toolpanel.h index 2da5f1bba..1d3630c6d 100644 --- a/rtgui/toolpanel.h +++ b/rtgui/toolpanel.h @@ -26,6 +26,7 @@ #include "guiutils.h" #include "multilangmgr.h" #include "paramsedited.h" +#include "../rtengine/noncopyable.h" class ToolPanel; class FoldableToolPanel; @@ -51,7 +52,7 @@ public: ToolParamBlock(); }; -class ToolPanel +class ToolPanel : public rtengine::NonCopyable { protected: diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 5569861ae..a1b26b29f 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -83,6 +83,7 @@ #include "dehaze.h" #include "guiutils.h" #include "filmnegative.h" +#include "../rtengine/noncopyable.h" class ImageEditorCoordinator; @@ -99,7 +100,8 @@ class ToolPanelCoordinator : public ICMPanelListener, public ImageAreaToolListener, public rtengine::ImageTypeListener, - public FilmNegProvider + public FilmNegProvider, + public rtengine::NonCopyable { protected: WhiteBalance* whitebalance; diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc index 761dc5e04..aa3443829 100644 --- a/rtgui/whitebalance.cc +++ b/rtgui/whitebalance.cc @@ -382,7 +382,6 @@ void WhiteBalance::adjusterChanged(Adjuster* a, double newval) return; } - Glib::ustring colLabel = row[methodColumns.colLabel]; const std::pair ppMethod = findWBEntry (row[methodColumns.colLabel], WBLT_GUI); const std::pair wbCustom = findWBEntry ("Custom", WBLT_PP); diff --git a/tools/camconst_creator.ods b/tools/camconst_creator.ods new file mode 100644 index 000000000..954abe6ac Binary files /dev/null and b/tools/camconst_creator.ods differ