Merge branch 'dev' into spot-removal-tool
This commit is contained in:
commit
883e73454d
@ -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)
|
||||
|
@ -18,10 +18,10 @@
|
||||
*
|
||||
* Author: reine
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifndef STOPWATCH_H
|
||||
#define STOPWATCH_H
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#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 */
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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*()
|
||||
{
|
||||
|
@ -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],
|
||||
@ -1759,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
|
||||
@ -1806,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": [
|
||||
@ -1897,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
|
||||
@ -1917,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
|
||||
@ -1925,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
|
||||
@ -2238,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
|
||||
@ -2261,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
|
||||
@ -2301,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
|
||||
},
|
||||
@ -2385,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
|
||||
@ -2420,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": [
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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];
|
||||
|
@ -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<typename E>
|
||||
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
|
||||
|
@ -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<float>(val);
|
||||
dcurve[0] = LIM01<float>(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
|
||||
}
|
||||
|
@ -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<double>& points, int ppn = CURVES_MIN_POLY_POINTS);
|
||||
explicit DiagonalCurve (const std::vector<double>& 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<double>& points, bool isPeriodic = true, int ppn = CURVES_MIN_POLY_POINTS);
|
||||
explicit FlatCurve (const std::vector<double>& points, bool isPeriodic = true, int ppn = CURVES_MIN_POLY_POINTS);
|
||||
~FlatCurve () override;
|
||||
|
||||
double getVal (double t) const override;
|
||||
|
@ -334,8 +334,6 @@ double xyCoordToTemperature(const std::array<double, 2>& 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<double, 2>& 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;
|
||||
|
@ -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];
|
||||
@ -661,10 +659,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);
|
||||
@ -915,9 +912,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);
|
||||
}
|
||||
|
||||
@ -930,7 +924,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))) {
|
||||
@ -939,81 +932,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);
|
||||
|
||||
|
@ -328,8 +328,8 @@ void DFManager::init(const Glib::ustring& pathname)
|
||||
} else {
|
||||
printf( "%s: MEAN of \n ", i.key().c_str());
|
||||
|
||||
for( std::list<Glib::ustring>::iterator iter = i.pathNames.begin(); iter != i.pathNames.end(); ++iter ) {
|
||||
printf( "%s, ", iter->c_str() );
|
||||
for(std::list<Glib::ustring>::iterator path = i.pathNames.begin(); path != i.pathNames.end(); ++path) {
|
||||
printf("%s, ", path->c_str());
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
@ -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 : {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,94 +0,0 @@
|
||||
/*
|
||||
* This file is part of RawTherapee.
|
||||
*
|
||||
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "rtengine.h"
|
||||
#include <iostream>
|
||||
//#include <giomm.h>
|
||||
#include <helpers.h>
|
||||
|
||||
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 <infile> <paramfile> <outfile>" << 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
|
||||
}
|
||||
|
@ -277,8 +277,8 @@ void FFManager::init(const Glib::ustring& pathname)
|
||||
} else {
|
||||
printf( "%s: MEAN of \n ", i.key().c_str());
|
||||
|
||||
for( std::list<Glib::ustring>::iterator iter = i.pathNames.begin(); iter != i.pathNames.end(); ++iter ) {
|
||||
printf( "%s, ", iter->c_str() );
|
||||
for(std::list<Glib::ustring>::iterator path = i.pathNames.begin(); path != i.pathNames.end(); ++path) {
|
||||
printf("%s, ", path->c_str());
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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")) {
|
||||
|
@ -98,7 +98,7 @@ private:
|
||||
unsigned int dcrawFrameCount;
|
||||
|
||||
public:
|
||||
FramesData (const Glib::ustring& fname, std::unique_ptr<RawMetaDataLocation> rml = nullptr, bool firstFrameOnly = false);
|
||||
explicit FramesData (const Glib::ustring& fname, std::unique_ptr<RawMetaDataLocation> rml = nullptr, bool firstFrameOnly = false);
|
||||
~FramesData () override;
|
||||
|
||||
void setDCRawFrameCount (unsigned int frameCount);
|
||||
|
@ -1720,7 +1720,7 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int pW, int pw
|
||||
float t_l = static_cast<float> (params->dirpyrequalizer.hueskin.getTopLeft()) / 100.0f;
|
||||
float t_r = static_cast<float> (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)
|
||||
@ -3788,11 +3785,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);
|
||||
@ -3802,27 +3800,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);
|
||||
|
@ -201,7 +201,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()
|
||||
@ -336,11 +336,8 @@ public:
|
||||
void removeSpots (Imagefloat* img, ImageSource* imgsrc, const std::vector<SpotEntry> &entries, const PreviewProps &pp, const ColorTemp &currWB, const ColorManagementParams *cmp, int tr);
|
||||
|
||||
// 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);
|
||||
|
@ -228,12 +228,12 @@ void ImProcFunctions::dehaze(Imagefloat *img)
|
||||
array2D<float> dark(W, H);
|
||||
|
||||
int patchsize = max(int(5 / scale), 2);
|
||||
int npatches = 0;
|
||||
float ambient[3];
|
||||
array2D<float> &t_tilde = dark;
|
||||
float max_t = 0.f;
|
||||
|
||||
{
|
||||
int npatches = 0;
|
||||
array2D<float> R(W, H);
|
||||
array2D<float> G(W, H);
|
||||
array2D<float> B(W, H);
|
||||
|
@ -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<float>(wprof[0][0] / (dx * (normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50x
|
||||
static_cast<float>(wprof[0][1] / (dx * (normalizeIn ? 65535.0 : 1.0))),
|
||||
static_cast<float>(wprof[0][2] / (dx * (normalizeIn ? 65535.0 : 1.0)))
|
||||
static_cast<float>(wprof[0][0] / ((normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50x
|
||||
static_cast<float>(wprof[0][1] / ((normalizeIn ? 65535.0 : 1.0))),
|
||||
static_cast<float>(wprof[0][2] / ((normalizeIn ? 65535.0 : 1.0)))
|
||||
}, {
|
||||
static_cast<float>(wprof[1][0] / (normalizeIn ? 65535.0 : 1.0)),
|
||||
static_cast<float>(wprof[1][1] / (normalizeIn ? 65535.0 : 1.0)),
|
||||
static_cast<float>(wprof[1][2] / (normalizeIn ? 65535.0 : 1.0))
|
||||
}, {
|
||||
static_cast<float>(wprof[2][0] / (dz * (normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50z
|
||||
static_cast<float>(wprof[2][1] / (dz * (normalizeIn ? 65535.0 : 1.0))),
|
||||
static_cast<float>(wprof[2][2] / (dz * (normalizeIn ? 65535.0 : 1.0)))
|
||||
static_cast<float>(wprof[2][0] / ((normalizeIn ? 65535.0 : 1.0))), //I have suppressed / Color::D50z
|
||||
static_cast<float>(wprof[2][1] / ((normalizeIn ? 65535.0 : 1.0))),
|
||||
static_cast<float>(wprof[2][2] / ((normalizeIn ? 65535.0 : 1.0)))
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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<int> (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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,10 +106,10 @@ void ImProcFunctions::shadowsHighlights(LabImage *lab)
|
||||
#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)
|
||||
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)
|
||||
#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)
|
||||
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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -16,8 +16,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _MYTIME_
|
||||
#define _MYTIME_
|
||||
#pragma once
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
@ -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
|
||||
|
@ -20,12 +20,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "rawimagesource.h"
|
||||
#include <vector>
|
||||
#include "rawimagesource.h"
|
||||
#include "noncopyable.h"
|
||||
|
||||
namespace rtengine {
|
||||
|
||||
class PDAFLinesFilter {
|
||||
class PDAFLinesFilter: public rtengine::NonCopyable
|
||||
{
|
||||
public:
|
||||
explicit PDAFLinesFilter(RawImage *ri);
|
||||
~PDAFLinesFilter();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -1671,8 +1671,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);
|
||||
|
@ -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<Glib::ustring>::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) {}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
* This file is part of RawTherapee.
|
||||
*
|
||||
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "rtengine.h"
|
||||
#include <iostream>
|
||||
//#include <giomm.h>
|
||||
#include <helpers.h>
|
||||
|
||||
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 <infile> <paramfile> <outfile>" << 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]);
|
||||
}
|
||||
|
@ -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 = ", ";
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -380,7 +380,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
std::string EffectiveMaxApertureString = "";
|
||||
std::string EffectiveMaxApertureString;
|
||||
|
||||
if (!d100) {
|
||||
int EffectiveMaxApertureValue;
|
||||
|
@ -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
|
||||
@ -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()));
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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()),
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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<std::string> vFilterStrings;
|
||||
|
||||
BrowserFilter ();
|
||||
};
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -21,10 +21,11 @@
|
||||
|
||||
#include <gtkmm.h>
|
||||
#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;
|
||||
|
@ -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 ());
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 ());
|
||||
|
@ -18,6 +18,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
#include <glibmm.h>
|
||||
@ -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<FileBrowserEntry*>(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<Glib::ustring> 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);
|
||||
}
|
||||
|
@ -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<void> 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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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:<value>;iso:<value> 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<Glib::ustring> 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;
|
||||
}
|
||||
|
||||
|
@ -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<void, const Glib::ustring&> DirSelectionSlot;
|
||||
|
@ -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 ();
|
||||
|
@ -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,
|
||||
|
@ -21,10 +21,11 @@
|
||||
|
||||
#include <gtkmm.h>
|
||||
#include "curveeditorgroup.h"
|
||||
#include "../rtengine/noncopyable.h"
|
||||
|
||||
class FlatCurveEditor;
|
||||
|
||||
class FlatCurveEditorSubGroup: public CurveEditorSubGroup
|
||||
class FlatCurveEditorSubGroup: public CurveEditorSubGroup, public rtengine::NonCopyable
|
||||
{
|
||||
|
||||
friend class FlatCurveEditor;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -298,17 +298,14 @@ void drawCrop (Cairo::RefPtr<Cairo::Context> 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<double> ds (1);
|
||||
ds[0] = 4;
|
||||
cr->set_dash (ds, 0);
|
||||
cr->set_dash (std::valarray<double>({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<double>(), 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<Cairo::Context> 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<double> ds (1);
|
||||
ds[0] = 4;
|
||||
cr->set_dash (ds, 0);
|
||||
cr->set_dash (std::valarray<double>({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<double>(), 0);
|
||||
|
||||
double height = recty2 - recty1;
|
||||
double width = rectx2 - rectx1;
|
||||
@ -470,14 +464,11 @@ void drawCrop (Cairo::RefPtr<Cairo::Context> 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<double>({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<double>(), 0);
|
||||
|
||||
x = width - (a * b) / height;
|
||||
y = (b * (d - a)) / width;
|
||||
@ -486,14 +477,11 @@ void drawCrop (Cairo::RefPtr<Cairo::Context> 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<double>({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<double>(), 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("<b>") + escapeHtmlChars(titleLabel) + Glib::ustring("</b>"));
|
||||
@ -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<double>(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<double>(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<double>(value + (event->delta_y > 0 ? step : -step), lower, upper);
|
||||
value2 = rtengine::LIM<double>(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<double>(value + step, upper);
|
||||
value2 = rtengine::min<double>(value + step, upperBound);
|
||||
if (value2 != value) {
|
||||
scroll->set_value(value2);
|
||||
}
|
||||
} else if (event->direction == GDK_SCROLL_UP) {
|
||||
value2 = rtengine::max<double>(value - step, lower);
|
||||
value2 = rtengine::max<double>(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<double>(value + (event->delta_x > 0 ? 30 : -30), lower, upper);
|
||||
value2 = rtengine::LIM<double>(value + (event->delta_x > 0 ? 30 : -30), lowerBound, upperBound);
|
||||
} else if (event->delta_y) {
|
||||
value2 = rtengine::LIM<double>(value + (event->delta_y > 0 ? 30 : -30), lower, upper);
|
||||
value2 = rtengine::LIM<double>(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<Gdk::Window> 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) {
|
||||
|
@ -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<void> &signal_selection_changed();
|
||||
sigc::signal<void> &signal_file_set();
|
||||
|
@ -464,7 +464,6 @@ void HistogramRGBArea::updateBackBuffer (int r, int g, int b, const Glib::ustrin
|
||||
|
||||
if (surface) {
|
||||
Cairo::RefPtr<Cairo::Context> cc = Cairo::Context::create(surface);
|
||||
Glib::RefPtr<Gtk::StyleContext> 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<Gdk::Window> window = get_window();
|
||||
add_events(Gdk::BUTTON_PRESS_MASK);
|
||||
}
|
||||
|
||||
@ -984,7 +982,6 @@ void HistogramArea::on_realize ()
|
||||
{
|
||||
|
||||
Gtk::DrawingArea::on_realize();
|
||||
Glib::RefPtr<Gdk::Window> 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<Cairo::Context> &cr,
|
||||
bool HistogramArea::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr)
|
||||
{
|
||||
|
||||
Glib::RefPtr<Gdk::Window> window = get_window();
|
||||
|
||||
if (get_width() != oldwidth || get_height() != oldheight || isDirty ()) {
|
||||
updateBackBuffer ();
|
||||
}
|
||||
|
@ -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<void, double> 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:
|
||||
|
@ -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)) {
|
||||
|
@ -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();
|
||||
|
@ -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<Pango::Context> 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<Pango::Layout> ilayout = create_pango_layout("");
|
||||
ilayout->set_markup(text);
|
||||
ilayout->set_markup(infotext);
|
||||
|
||||
// get size of the text block
|
||||
int iw, ih;
|
||||
|
@ -83,7 +83,6 @@ InspectorBuffer::~InspectorBuffer() {
|
||||
|
||||
Inspector::Inspector () : currImage(nullptr), zoom(0.0), active(false)
|
||||
{
|
||||
Glib::RefPtr<Gtk::StyleContext> 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
|
||||
|
@ -256,7 +256,7 @@ int processLineParams ( int argc, char **argv )
|
||||
{
|
||||
rtengine::procparams::PartialProfile *rawParams = nullptr, *imgParams = nullptr;
|
||||
std::vector<Glib::ustring> inputFiles;
|
||||
Glib::ustring outputPath = "";
|
||||
Glib::ustring outputPath;
|
||||
std::vector<rtengine::procparams::PartialProfile*> 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++) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -1118,20 +1118,17 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
|
||||
wavelet.exptoning = wavelet.exptoning && p.wavelet.exptoning == other.wavelet.exptoning;
|
||||
wavelet.expnoise = wavelet.expnoise && p.wavelet.expnoise == other.wavelet.expnoise;
|
||||
|
||||
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;
|
||||
|
@ -230,15 +230,15 @@ void PlacesBrowser::refreshPlacesList ()
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < options.favoriteDirs.size(); i++) {
|
||||
Glib::RefPtr<Gio::File> hfile = Gio::File::create_for_path (options.favoriteDirs[i]);
|
||||
Glib::RefPtr<Gio::File> 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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -56,6 +56,7 @@ Glib::RefPtr<Gtk::CssProvider> 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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user