merge with dev
This commit is contained in:
commit
ba7a61c391
@ -787,6 +787,7 @@ HISTORY_MSG_SH_COLORSPACE;S/H - Colorspace
|
|||||||
HISTORY_MSG_SOFTLIGHT_ENABLED;Soft light
|
HISTORY_MSG_SOFTLIGHT_ENABLED;Soft light
|
||||||
HISTORY_MSG_SOFTLIGHT_STRENGTH;Soft light - Strength
|
HISTORY_MSG_SOFTLIGHT_STRENGTH;Soft light - Strength
|
||||||
HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - Anchor
|
HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - Anchor
|
||||||
|
HISTORY_MSG_TRANS_Method;Geometry - Method
|
||||||
HISTORY_MSG_WAVCLARI;Clarity
|
HISTORY_MSG_WAVCLARI;Clarity
|
||||||
HISTORY_MSG_WAVUSHAMET;Clarity method
|
HISTORY_MSG_WAVUSHAMET;Clarity method
|
||||||
HISTORY_MSG_WAVMERGEL;Merge L
|
HISTORY_MSG_WAVMERGEL;Merge L
|
||||||
@ -1786,6 +1787,8 @@ TP_LABCURVE_RSTPRO_TOOLTIP;Works on the Chromaticity slider and the CC curve.
|
|||||||
TP_LENSGEOM_AUTOCROP;Auto-Crop
|
TP_LENSGEOM_AUTOCROP;Auto-Crop
|
||||||
TP_LENSGEOM_FILL;Auto-fill
|
TP_LENSGEOM_FILL;Auto-fill
|
||||||
TP_LENSGEOM_LABEL;Lens / Geometry
|
TP_LENSGEOM_LABEL;Lens / Geometry
|
||||||
|
TP_LENSGEOM_LIN;Linear
|
||||||
|
TP_LENSGEOM_LOG;Logarithmic
|
||||||
TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected
|
TP_LENSPROFILE_CORRECTION_AUTOMATCH;Automatically selected
|
||||||
TP_LENSPROFILE_CORRECTION_LCPFILE;LCP file
|
TP_LENSPROFILE_CORRECTION_LCPFILE;LCP file
|
||||||
TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected
|
TP_LENSPROFILE_CORRECTION_MANUAL;Manually selected
|
||||||
|
@ -131,6 +131,11 @@ inline void gauss3x3div (float** RESTRICT src, float** RESTRICT dst, float** RES
|
|||||||
const float c00 = kernel[1][1];
|
const float c00 = kernel[1][1];
|
||||||
|
|
||||||
for (int i = 1; i < tileSize - 1; i++) {
|
for (int i = 1; i < tileSize - 1; i++) {
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang loop vectorize(assume_safety)
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#pragma GCC ivdep
|
||||||
|
#endif
|
||||||
for (int j = 1; j < tileSize - 1; j++) {
|
for (int j = 1; j < tileSize - 1; j++) {
|
||||||
const float val = c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) +
|
const float val = c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) +
|
||||||
c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) +
|
c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) +
|
||||||
@ -151,6 +156,11 @@ inline void gauss5x5div (float** RESTRICT src, float** RESTRICT dst, float** RES
|
|||||||
|
|
||||||
for (int i = 2; i < tileSize - 2; ++i) {
|
for (int i = 2; i < tileSize - 2; ++i) {
|
||||||
// I tried hand written SSE code but gcc vectorizes better
|
// I tried hand written SSE code but gcc vectorizes better
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang loop vectorize(assume_safety)
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#pragma GCC ivdep
|
||||||
|
#endif
|
||||||
for (int j = 2; j < tileSize - 2; ++j) {
|
for (int j = 2; j < tileSize - 2; ++j) {
|
||||||
const float val = c21 * ((src[i - 2][j - 1] + src[i - 2][j + 1]) + (src[i - 1][j - 2] + src[i - 1][j + 2]) + (src[i + 1][j - 2] + src[i + 1][j + 2]) + (src[i + 2][j - 1] + src[i + 2][j + 1])) +
|
const float val = c21 * ((src[i - 2][j - 1] + src[i - 2][j + 1]) + (src[i - 1][j - 2] + src[i - 1][j + 2]) + (src[i + 1][j - 2] + src[i + 1][j + 2]) + (src[i + 2][j - 1] + src[i + 2][j + 1])) +
|
||||||
c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) +
|
c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) +
|
||||||
@ -177,6 +187,11 @@ inline void gauss7x7div(float** RESTRICT src, float** RESTRICT dst, float** REST
|
|||||||
|
|
||||||
for (int i = 3; i < tileSize - 3; ++i) {
|
for (int i = 3; i < tileSize - 3; ++i) {
|
||||||
// I tried hand written SSE code but gcc vectorizes better
|
// I tried hand written SSE code but gcc vectorizes better
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang loop vectorize(assume_safety)
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#pragma GCC ivdep
|
||||||
|
#endif
|
||||||
for (int j = 3; j < tileSize - 3; ++j) {
|
for (int j = 3; j < tileSize - 3; ++j) {
|
||||||
const float val = c31 * ((src[i - 3][j - 1] + src[i - 3][j + 1]) + (src[i - 1][j - 3] + src[i - 1][j + 3]) + (src[i + 1][j - 3] + src[i + 1][j + 3]) + (src[i + 3][j - 1] + src[i + 3][j + 1])) +
|
const float val = c31 * ((src[i - 3][j - 1] + src[i - 3][j + 1]) + (src[i - 1][j - 3] + src[i - 1][j + 3]) + (src[i + 1][j - 3] + src[i + 1][j + 3]) + (src[i + 3][j - 1] + src[i + 3][j + 1])) +
|
||||||
c30 * (src[i - 3][j] + src[i][j - 3] + src[i][j + 3] + src[i + 3][j]) +
|
c30 * (src[i - 3][j] + src[i][j - 3] + src[i][j + 3] + src[i + 3][j]) +
|
||||||
@ -199,6 +214,11 @@ inline void gauss3x3mult(float** RESTRICT src, float** RESTRICT dst, const int t
|
|||||||
const float c00 = kernel[1][1];
|
const float c00 = kernel[1][1];
|
||||||
|
|
||||||
for (int i = 1; i < tileSize - 1; i++) {
|
for (int i = 1; i < tileSize - 1; i++) {
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang loop vectorize(assume_safety)
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#pragma GCC ivdep
|
||||||
|
#endif
|
||||||
for (int j = 1; j < tileSize - 1; j++) {
|
for (int j = 1; j < tileSize - 1; j++) {
|
||||||
const float val = c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) +
|
const float val = c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) +
|
||||||
c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) +
|
c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) +
|
||||||
@ -220,6 +240,11 @@ inline void gauss5x5mult (float** RESTRICT src, float** RESTRICT dst, const int
|
|||||||
|
|
||||||
for (int i = 2; i < tileSize - 2; ++i) {
|
for (int i = 2; i < tileSize - 2; ++i) {
|
||||||
// I tried hand written SSE code but gcc vectorizes better
|
// I tried hand written SSE code but gcc vectorizes better
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang loop vectorize(assume_safety)
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#pragma GCC ivdep
|
||||||
|
#endif
|
||||||
for (int j = 2; j < tileSize - 2; ++j) {
|
for (int j = 2; j < tileSize - 2; ++j) {
|
||||||
const float val = c21 * ((src[i - 2][j - 1] + src[i - 2][j + 1]) + (src[i - 1][j - 2] + src[i - 1][j + 2]) + (src[i + 1][j - 2] + src[i + 1][j + 2]) + (src[i + 2][j - 1] + src[i + 2][j + 1])) +
|
const float val = c21 * ((src[i - 2][j - 1] + src[i - 2][j + 1]) + (src[i - 1][j - 2] + src[i - 1][j + 2]) + (src[i + 1][j - 2] + src[i + 1][j + 2]) + (src[i + 2][j - 1] + src[i + 2][j + 1])) +
|
||||||
c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) +
|
c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) +
|
||||||
@ -246,6 +271,11 @@ inline void gauss7x7mult(float** RESTRICT src, float** RESTRICT dst, const int t
|
|||||||
|
|
||||||
for (int i = 3; i < tileSize - 3; ++i) {
|
for (int i = 3; i < tileSize - 3; ++i) {
|
||||||
// I tried hand written SSE code but gcc vectorizes better
|
// I tried hand written SSE code but gcc vectorizes better
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang loop vectorize(assume_safety)
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#pragma GCC ivdep
|
||||||
|
#endif
|
||||||
for (int j = 3; j < tileSize - 3; ++j) {
|
for (int j = 3; j < tileSize - 3; ++j) {
|
||||||
const float val = c31 * ((src[i - 3][j - 1] + src[i - 3][j + 1]) + (src[i - 1][j - 3] + src[i - 1][j + 3]) + (src[i + 1][j - 3] + src[i + 1][j + 3]) + (src[i + 3][j - 1] + src[i + 3][j + 1])) +
|
const float val = c31 * ((src[i - 3][j - 1] + src[i - 3][j + 1]) + (src[i - 1][j - 3] + src[i - 1][j + 3]) + (src[i + 1][j - 3] + src[i + 1][j + 3]) + (src[i + 3][j - 1] + src[i + 3][j + 1])) +
|
||||||
c30 * (src[i - 3][j] + src[i][j - 3] + src[i][j + 3] + src[i + 3][j]) +
|
c30 * (src[i - 3][j] + src[i][j - 3] + src[i][j + 3] + src[i + 3][j]) +
|
||||||
@ -495,28 +525,25 @@ float calcRadiusXtrans(const float * const *rawData, int W, int H, float lowerLi
|
|||||||
|
|
||||||
bool checkForStop(float** tmpIThr, float** iterCheck, int fullTileSize, int border)
|
bool checkForStop(float** tmpIThr, float** iterCheck, int fullTileSize, int border)
|
||||||
{
|
{
|
||||||
bool stopped = false;
|
for (int ii = border; ii < fullTileSize - border; ++ii) {
|
||||||
for (int ii = border; !stopped && ii < fullTileSize - border; ++ii) {
|
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
for (int jj = border; jj < fullTileSize - border; jj += 4) {
|
for (int jj = border; jj < fullTileSize - border; jj += 4) {
|
||||||
if (_mm_movemask_ps((vfloat)vmaskf_lt(LVFU(tmpIThr[ii][jj]), LVFU(iterCheck[ii - border][jj - border])))) {
|
if (UNLIKELY(_mm_movemask_ps((vfloat)vmaskf_lt(LVFU(tmpIThr[ii][jj]), LVFU(iterCheck[ii - border][jj - border]))))) {
|
||||||
stopped = true;
|
return true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
for (int jj = border; jj < fullTileSize - border; ++jj) {
|
for (int jj = border; jj < fullTileSize - border; ++jj) {
|
||||||
if (tmpIThr[ii][jj] < iterCheck[ii - border][jj - border]) {
|
if (tmpIThr[ii][jj] < iterCheck[ii - border][jj - border]) {
|
||||||
stopped = true;
|
return true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return stopped;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureDeconvSharpening (float ** clipmask, float** luminance, float** oldLuminance, const float * const * blend, int W, int H, double sigma, double sigmaCornerOffset, int iterations, bool checkIterStop, rtengine::ProgressListener* plistener, double startVal, double endVal)
|
void CaptureDeconvSharpening (float** luminance, const float* const * oldLuminance, const float * const * blend, int W, int H, double sigma, double sigmaCornerOffset, int iterations, bool checkIterStop, rtengine::ProgressListener* plistener, double startVal, double endVal)
|
||||||
{
|
{
|
||||||
BENCHFUN
|
BENCHFUN
|
||||||
const bool is5x5 = (sigma <= 0.84 && sigmaCornerOffset == 0.0);
|
const bool is5x5 = (sigma <= 0.84 && sigmaCornerOffset == 0.0);
|
||||||
@ -541,6 +568,7 @@ BENCHFUN
|
|||||||
|
|
||||||
double progress = startVal;
|
double progress = startVal;
|
||||||
const double progressStep = (endVal - startVal) * rtengine::SQR(tileSize) / (W * H);
|
const double progressStep = (endVal - startVal) * rtengine::SQR(tileSize) / (W * H);
|
||||||
|
|
||||||
constexpr float minBlend = 0.01f;
|
constexpr float minBlend = 0.01f;
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
@ -567,14 +595,14 @@ BENCHFUN
|
|||||||
if (checkIterStop) {
|
if (checkIterStop) {
|
||||||
for (int k = 0, ii = endOfCol ? H - fullTileSize + border : i; k < tileSize; ++k, ++ii) {
|
for (int k = 0, ii = endOfCol ? H - fullTileSize + border : i; k < tileSize; ++k, ++ii) {
|
||||||
for (int l = 0, jj = endOfRow ? W - fullTileSize + border : j; l < tileSize; ++l, ++jj) {
|
for (int l = 0, jj = endOfRow ? W - fullTileSize + border : j; l < tileSize; ++l, ++jj) {
|
||||||
iterCheck[k][l] = oldLuminance[ii][jj] * clipmask[ii][jj] * 0.5f;
|
iterCheck[k][l] = oldLuminance[ii][jj] * blend[ii][jj] * 0.5f;
|
||||||
maxVal = std::max(maxVal, clipmask[ii][jj]);
|
maxVal = std::max(maxVal, blend[ii][jj]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int k = 0, ii = endOfCol ? H - fullTileSize + border : i; k < tileSize; ++k, ++ii) {
|
for (int k = 0, ii = endOfCol ? H - fullTileSize + border : i; k < tileSize; ++k, ++ii) {
|
||||||
for (int l = 0, jj = endOfRow ? W - fullTileSize + border : j; l < tileSize; ++l, ++jj) {
|
for (int l = 0, jj = endOfRow ? W - fullTileSize + border : j; l < tileSize; ++l, ++jj) {
|
||||||
maxVal = std::max(maxVal, clipmask[ii][jj]);
|
maxVal = std::max(maxVal, blend[ii][jj]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -593,14 +621,14 @@ BENCHFUN
|
|||||||
if (checkIterStop) {
|
if (checkIterStop) {
|
||||||
for (int ii = 0; ii < tileSize; ++ii) {
|
for (int ii = 0; ii < tileSize; ++ii) {
|
||||||
for (int jj = 0; jj < tileSize; ++jj) {
|
for (int jj = 0; jj < tileSize; ++jj) {
|
||||||
iterCheck[ii][jj] = oldLuminance[i + ii][j + jj] * clipmask[i + ii][j + jj] * 0.5f;
|
iterCheck[ii][jj] = oldLuminance[i + ii][j + jj] * blend[i + ii][j + jj] * 0.5f;
|
||||||
maxVal = std::max(maxVal, clipmask[i + ii][j + jj]);
|
maxVal = std::max(maxVal, blend[i + ii][j + jj]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int ii = 0; ii < tileSize; ++ii) {
|
for (int ii = 0; ii < tileSize; ++ii) {
|
||||||
for (int jj = 0; jj < tileSize; ++jj) {
|
for (int jj = 0; jj < tileSize; ++jj) {
|
||||||
maxVal = std::max(maxVal, clipmask[i + ii][j + jj]);
|
maxVal = std::max(maxVal, blend[i + ii][j + jj]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -615,23 +643,22 @@ BENCHFUN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool stopped = false;
|
|
||||||
if (is3x3) {
|
if (is3x3) {
|
||||||
for (int k = 0; k < iterations && !stopped; ++k) {
|
for (int k = 0; k < iterations; ++k) {
|
||||||
// apply 3x3 gaussian blur and divide luminance by result of gaussian blur
|
// apply 3x3 gaussian blur and divide luminance by result of gaussian blur
|
||||||
gauss3x3div(tmpIThr, tmpThr, lumThr, fullTileSize, kernel3);
|
gauss3x3div(tmpIThr, tmpThr, lumThr, fullTileSize, kernel3);
|
||||||
gauss3x3mult(tmpThr, tmpIThr, fullTileSize, kernel3);
|
gauss3x3mult(tmpThr, tmpIThr, fullTileSize, kernel3);
|
||||||
if (checkIterStop) {
|
if (checkIterStop && k < iterations - 1 && checkForStop(tmpIThr, iterCheck, fullTileSize, border)) {
|
||||||
stopped = checkForStop(tmpIThr, iterCheck, fullTileSize, border);
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (is5x5) {
|
} else if (is5x5) {
|
||||||
for (int k = 0; k < iterations && !stopped; ++k) {
|
for (int k = 0; k < iterations; ++k) {
|
||||||
// apply 5x5 gaussian blur and divide luminance by result of gaussian blur
|
// apply 5x5 gaussian blur and divide luminance by result of gaussian blur
|
||||||
gauss5x5div(tmpIThr, tmpThr, lumThr, fullTileSize, kernel5);
|
gauss5x5div(tmpIThr, tmpThr, lumThr, fullTileSize, kernel5);
|
||||||
gauss5x5mult(tmpThr, tmpIThr, fullTileSize, kernel5);
|
gauss5x5mult(tmpThr, tmpIThr, fullTileSize, kernel5);
|
||||||
if (checkIterStop) {
|
if (checkIterStop && k < iterations - 1 && checkForStop(tmpIThr, iterCheck, fullTileSize, border)) {
|
||||||
stopped = checkForStop(tmpIThr, iterCheck, fullTileSize, border);
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -642,34 +669,34 @@ BENCHFUN
|
|||||||
if (sigmaTile > 0.84) { // have to use 7x7 kernel
|
if (sigmaTile > 0.84) { // have to use 7x7 kernel
|
||||||
float lkernel7[7][7];
|
float lkernel7[7][7];
|
||||||
compute7x7kernel(static_cast<float>(sigma) + distanceFactor * distance, lkernel7);
|
compute7x7kernel(static_cast<float>(sigma) + distanceFactor * distance, lkernel7);
|
||||||
for (int k = 0; k < iterations && !stopped; ++k) {
|
for (int k = 0; k < iterations; ++k) {
|
||||||
// apply 7x7 gaussian blur and divide luminance by result of gaussian blur
|
// apply 7x7 gaussian blur and divide luminance by result of gaussian blur
|
||||||
gauss7x7div(tmpIThr, tmpThr, lumThr, fullTileSize, lkernel7);
|
gauss7x7div(tmpIThr, tmpThr, lumThr, fullTileSize, lkernel7);
|
||||||
gauss7x7mult(tmpThr, tmpIThr, fullTileSize, lkernel7);
|
gauss7x7mult(tmpThr, tmpIThr, fullTileSize, lkernel7);
|
||||||
if (checkIterStop) {
|
if (checkIterStop && k < iterations - 1 && checkForStop(tmpIThr, iterCheck, fullTileSize, border)) {
|
||||||
stopped = checkForStop(tmpIThr, iterCheck, fullTileSize, border);
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // can use 5x5 kernel
|
} else { // can use 5x5 kernel
|
||||||
float lkernel7[5][5];
|
float lkernel5[5][5];
|
||||||
compute5x5kernel(static_cast<float>(sigma) + distanceFactor * distance, lkernel7);
|
compute5x5kernel(static_cast<float>(sigma) + distanceFactor * distance, lkernel5);
|
||||||
for (int k = 0; k < iterations && !stopped; ++k) {
|
for (int k = 0; k < iterations; ++k) {
|
||||||
// apply 7x7 gaussian blur and divide luminance by result of gaussian blur
|
// apply 7x7 gaussian blur and divide luminance by result of gaussian blur
|
||||||
gauss5x5div(tmpIThr, tmpThr, lumThr, fullTileSize, lkernel7);
|
gauss5x5div(tmpIThr, tmpThr, lumThr, fullTileSize, lkernel5);
|
||||||
gauss5x5mult(tmpThr, tmpIThr, fullTileSize, lkernel7);
|
gauss5x5mult(tmpThr, tmpIThr, fullTileSize, lkernel5);
|
||||||
if (checkIterStop) {
|
if (checkIterStop && k < iterations - 1 && checkForStop(tmpIThr, iterCheck, fullTileSize, border)) {
|
||||||
stopped = checkForStop(tmpIThr, iterCheck, fullTileSize, border);
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int k = 0; k < iterations && !stopped; ++k) {
|
for (int k = 0; k < iterations; ++k) {
|
||||||
// apply 7x7 gaussian blur and divide luminance by result of gaussian blur
|
// apply 7x7 gaussian blur and divide luminance by result of gaussian blur
|
||||||
gauss7x7div(tmpIThr, tmpThr, lumThr, fullTileSize, kernel7);
|
gauss7x7div(tmpIThr, tmpThr, lumThr, fullTileSize, kernel7);
|
||||||
gauss7x7mult(tmpThr, tmpIThr, fullTileSize, kernel7);
|
gauss7x7mult(tmpThr, tmpIThr, fullTileSize, kernel7);
|
||||||
if (checkIterStop) {
|
if (checkIterStop && k < iterations - 1 && checkForStop(tmpIThr, iterCheck, fullTileSize, border)) {
|
||||||
stopped = checkForStop(tmpIThr, iterCheck, fullTileSize, border);
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -689,12 +716,12 @@ BENCHFUN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (plistener) {
|
if (plistener) {
|
||||||
if (++progresscounter % 16 == 0) {
|
if (++progresscounter % 32 == 0) {
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp critical(csprogress)
|
#pragma omp critical(csprogress)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
progress += 16.0 * progressStep;
|
progress += 32.0 * progressStep;
|
||||||
progress = rtengine::min(progress, endVal);
|
progress = rtengine::min(progress, endVal);
|
||||||
plistener->setProgress(progress);
|
plistener->setProgress(progress);
|
||||||
}
|
}
|
||||||
@ -721,6 +748,7 @@ void RawImageSource::captureSharpening(const procparams::CaptureSharpeningParams
|
|||||||
plistener->setProgress(0.0);
|
plistener->setProgress(0.0);
|
||||||
}
|
}
|
||||||
BENCHFUN
|
BENCHFUN
|
||||||
|
|
||||||
constexpr float xyz_rgb[3][3] = { // XYZ from RGB
|
constexpr float xyz_rgb[3][3] = { // XYZ from RGB
|
||||||
{ 0.412453, 0.357580, 0.180423 },
|
{ 0.412453, 0.357580, 0.180423 },
|
||||||
{ 0.212671, 0.715160, 0.072169 },
|
{ 0.212671, 0.715160, 0.072169 },
|
||||||
@ -799,8 +827,7 @@ BENCHFUN
|
|||||||
plistener->setProgress(0.1);
|
plistener->setProgress(0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
array2D<float>& blend = red; // red will be overridden anyway => we can use its buffer to store the blend mask
|
buildBlendMask(L, clipMask, W, H, contrast, sharpeningParams.autoContrast, clipMask);
|
||||||
buildBlendMask(L, blend, W, H, contrast, sharpeningParams.autoContrast, clipMask);
|
|
||||||
if (plistener) {
|
if (plistener) {
|
||||||
plistener->setProgress(0.2);
|
plistener->setProgress(0.2);
|
||||||
}
|
}
|
||||||
@ -810,7 +837,7 @@ BENCHFUN
|
|||||||
#endif
|
#endif
|
||||||
for (int i = 0; i < H; ++i) {
|
for (int i = 0; i < H; ++i) {
|
||||||
for (int j = 0; j < W; ++j) {
|
for (int j = 0; j < W; ++j) {
|
||||||
red[i][j] = green[i][j] = blue[i][j] = blend[i][j] * 16384.f;
|
red[i][j] = green[i][j] = blue[i][j] = clipMask[i][j] * 16384.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (plistener) {
|
if (plistener) {
|
||||||
@ -847,18 +874,18 @@ BENCHFUN
|
|||||||
if (plistener) {
|
if (plistener) {
|
||||||
plistener->setProgress(0.1);
|
plistener->setProgress(0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
// calculate contrast based blend factors to reduce sharpening in regions with low contrast
|
||||||
array2D<float>& blend = clipMask; // we can share blend and clipMask buffer here
|
buildBlendMask(L, clipMask, W, H, contrast, sharpeningParams.autoContrast, clipMask);
|
||||||
buildBlendMask(L, blend, W, H, contrast, sharpeningParams.autoContrast, clipMask);
|
|
||||||
if (plistener) {
|
if (plistener) {
|
||||||
plistener->setProgress(0.2);
|
plistener->setProgress(0.2);
|
||||||
}
|
}
|
||||||
conrastThreshold = contrast * 100.f;
|
conrastThreshold = contrast * 100.f;
|
||||||
|
CaptureDeconvSharpening(YNew, YOld, clipMask, W, H, radius, sharpeningParams.deconvradiusOffset, sharpeningParams.deconviter, sharpeningParams.deconvitercheck, plistener, 0.2, 0.9);
|
||||||
CaptureDeconvSharpening(clipMask, YNew, YOld, blend, W, H, radius, sharpeningParams.deconvradiusOffset, sharpeningParams.deconviter, sharpeningParams.deconvitercheck, plistener, 0.2, 0.9);
|
|
||||||
if (plistener) {
|
if (plistener) {
|
||||||
plistener->setProgress(0.9);
|
plistener->setProgress(0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel for schedule(dynamic, 16)
|
#pragma omp parallel for schedule(dynamic, 16)
|
||||||
#endif
|
#endif
|
||||||
@ -866,7 +893,7 @@ BENCHFUN
|
|||||||
int j = 0;
|
int j = 0;
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
for (; j < W - 3; j += 4) {
|
for (; j < W - 3; j += 4) {
|
||||||
const vfloat factor = vmaxf(LVFU(YNew[i][j]), ZEROV) / vmaxf(LVFU(YOld[i][j]), F2V(0.00001f));
|
const vfloat factor = LVFU(YNew[i][j]) / vmaxf(LVFU(YOld[i][j]), F2V(0.00001f));
|
||||||
STVFU(red[i][j], LVFU(redVals[i][j]) * factor);
|
STVFU(red[i][j], LVFU(redVals[i][j]) * factor);
|
||||||
STVFU(green[i][j], LVFU(greenVals[i][j]) * factor);
|
STVFU(green[i][j], LVFU(greenVals[i][j]) * factor);
|
||||||
STVFU(blue[i][j], LVFU(blueVals[i][j]) * factor);
|
STVFU(blue[i][j], LVFU(blueVals[i][j]) * factor);
|
||||||
@ -874,7 +901,7 @@ BENCHFUN
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
for (; j < W; ++j) {
|
for (; j < W; ++j) {
|
||||||
const float factor = std::max(YNew[i][j], 0.f) / std::max(YOld[i][j], 0.00001f);
|
const float factor = YNew[i][j] / std::max(YOld[i][j], 0.00001f);
|
||||||
red[i][j] = redVals[i][j] * factor;
|
red[i][j] = redVals[i][j] * factor;
|
||||||
green[i][j] = greenVals[i][j] * factor;
|
green[i][j] = greenVals[i][j] * factor;
|
||||||
blue[i][j] = blueVals[i][j] * factor;
|
blue[i][j] = blueVals[i][j] * factor;
|
||||||
|
@ -174,8 +174,6 @@ void Crop::update(int todo)
|
|||||||
int widIm = parent->fw;//full image
|
int widIm = parent->fw;//full image
|
||||||
int heiIm = parent->fh;
|
int heiIm = parent->fh;
|
||||||
|
|
||||||
bool needstransform = parent->ipf.needsTransform();
|
|
||||||
|
|
||||||
if (todo & (M_INIT | M_LINDENOISE | M_HDR)) {
|
if (todo & (M_INIT | M_LINDENOISE | M_HDR)) {
|
||||||
MyMutex::MyLock lock(parent->minit); // Also used in improccoord
|
MyMutex::MyLock lock(parent->minit); // Also used in improccoord
|
||||||
|
|
||||||
@ -767,6 +765,7 @@ void Crop::update(int todo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool needstransform = parent->ipf.needsTransform(skips(parent->fw, skip), skips(parent->fh, skip), parent->imgsrc->getRotateDegree(), parent->imgsrc->getMetaData());
|
||||||
// transform
|
// transform
|
||||||
if (needstransform || ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled)) {
|
if (needstransform || ((todo & (M_TRANSFORM | M_RGBCURVE)) && params.dirpyrequalizer.cbdlMethod == "bef" && params.dirpyrequalizer.enabled && !params.colorappearance.enabled)) {
|
||||||
if (!transCrop) {
|
if (!transCrop) {
|
||||||
@ -785,10 +784,7 @@ void Crop::update(int todo)
|
|||||||
baseCrop = transCrop;
|
baseCrop = transCrop;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (transCrop) {
|
|
||||||
delete transCrop;
|
delete transCrop;
|
||||||
}
|
|
||||||
|
|
||||||
transCrop = nullptr;
|
transCrop = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1338,6 +1334,7 @@ bool Crop::setCropSizes(int rcx, int rcy, int rcw, int rch, int skip, bool inter
|
|||||||
|
|
||||||
parent->ipf.transCoord(parent->fw, parent->fh, bx1, by1, bw, bh, orx, ory, orw, orh);
|
parent->ipf.transCoord(parent->fw, parent->fh, bx1, by1, bw, bh, orx, ory, orw, orh);
|
||||||
|
|
||||||
|
if (parent->ipf.needsTransform(skips(parent->fw, skip), skips(parent->fh, skip), parent->imgsrc->getRotateDegree(), parent->imgsrc->getMetaData())) {
|
||||||
if (check_need_larger_crop_for_lcp_distortion(parent->fw, parent->fh, orx, ory, orw, orh, *parent->params)) {
|
if (check_need_larger_crop_for_lcp_distortion(parent->fw, parent->fh, orx, ory, orw, orh, *parent->params)) {
|
||||||
// TODO - this is an estimate of the max distortion relative to the image size. ATM it is hardcoded to be 15%, which seems enough. If not, need to revise
|
// TODO - this is an estimate of the max distortion relative to the image size. ATM it is hardcoded to be 15%, which seems enough. If not, need to revise
|
||||||
int dW = int (double (parent->fw) * 0.15 / (2 * skip));
|
int dW = int (double (parent->fw) * 0.15 / (2 * skip));
|
||||||
@ -1372,7 +1369,7 @@ bool Crop::setCropSizes(int rcx, int rcy, int rcw, int rch, int skip, bool inter
|
|||||||
orw = min(x2 - x1, parent->fw - orx);
|
orw = min(x2 - x1, parent->fw - orx);
|
||||||
orh = min(y2 - y1, parent->fh - ory);
|
orh = min(y2 - y1, parent->fh - ory);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
leftBorder = skips(rqx1 - bx1, skip);
|
leftBorder = skips(rqx1 - bx1, skip);
|
||||||
upperBorder = skips(rqy1 - by1, skip);
|
upperBorder = skips(rqy1 - by1, skip);
|
||||||
|
|
||||||
|
@ -106,7 +106,18 @@ void guidedFilter(const array2D<float> &guide, const array2D<float> &src, array2
|
|||||||
const auto f_subsample =
|
const auto f_subsample =
|
||||||
[multithread](array2D<float> &d, const array2D<float> &s) -> void
|
[multithread](array2D<float> &d, const array2D<float> &s) -> void
|
||||||
{
|
{
|
||||||
|
if (d.width() == s.width() && d.height() == s.height()) {
|
||||||
|
#ifdef _OPENMP
|
||||||
|
#pragma omp parallel for if (multithread)
|
||||||
|
#endif
|
||||||
|
for (int y = 0; y < s.height(); ++y) {
|
||||||
|
for (int x = 0; x < s.width(); ++x) {
|
||||||
|
d[y][x] = s[y][x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
rescaleBilinear(s, d, multithread);
|
rescaleBilinear(s, d, multithread);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto f_mean =
|
const auto f_mean =
|
||||||
|
@ -551,7 +551,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange)
|
|||||||
oprevi = orig_prev;
|
oprevi = orig_prev;
|
||||||
|
|
||||||
// Remove transformation if unneeded
|
// Remove transformation if unneeded
|
||||||
bool needstransform = ipf.needsTransform();
|
bool needstransform = ipf.needsTransform(fw, fh, imgsrc->getRotateDegree(), imgsrc->getMetaData());
|
||||||
|
|
||||||
if ((needstransform || ((todo & (M_TRANSFORM | M_RGBCURVE)) && params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled && !params->colorappearance.enabled))) {
|
if ((needstransform || ((todo & (M_TRANSFORM | M_RGBCURVE)) && params->dirpyrequalizer.cbdlMethod == "bef" && params->dirpyrequalizer.enabled && !params->colorappearance.enabled))) {
|
||||||
assert(oprevi);
|
assert(oprevi);
|
||||||
@ -1565,7 +1565,7 @@ void ImProcCoordinator::saveInputICCReference(const Glib::ustring& fname, bool a
|
|||||||
imgsrc->getImage(currWB, tr, im, pp, ppar.toneCurve, ppar.raw);
|
imgsrc->getImage(currWB, tr, im, pp, ppar.toneCurve, ppar.raw);
|
||||||
ImProcFunctions ipf(&ppar, true);
|
ImProcFunctions ipf(&ppar, true);
|
||||||
|
|
||||||
if (ipf.needsTransform()) {
|
if (ipf.needsTransform(fW, fH, imgsrc->getRotateDegree(), imgsrc->getMetaData())) {
|
||||||
Imagefloat* trImg = new Imagefloat(fW, fH);
|
Imagefloat* trImg = new Imagefloat(fW, fH);
|
||||||
ipf.transform(im, trImg, 0, 0, 0, 0, fW, fH, fW, fH,
|
ipf.transform(im, trImg, 0, 0, 0, 0, fW, fH, fW, fH,
|
||||||
imgsrc->getMetaData(), imgsrc->getRotateDegree(), true);
|
imgsrc->getMetaData(), imgsrc->getRotateDegree(), true);
|
||||||
|
@ -84,8 +84,8 @@ class ImProcFunctions
|
|||||||
void calcVignettingParams(int oW, int oH, const procparams::VignettingParams& vignetting, double &w2, double &h2, double& maxRadius, double &v, double &b, double &mul);
|
void calcVignettingParams(int oW, int oH, const procparams::VignettingParams& vignetting, double &w2, double &h2, double& maxRadius, double &v, double &b, double &mul);
|
||||||
|
|
||||||
void transformLuminanceOnly(Imagefloat* original, Imagefloat* transformed, int cx, int cy, int oW, int oH, int fW, int fH);
|
void transformLuminanceOnly(Imagefloat* original, Imagefloat* transformed, int cx, int cy, int oW, int oH, int fW, int fH);
|
||||||
void transformGeneral(bool highQuality, Imagefloat *original, Imagefloat *transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LensCorrection *pLCPMap);
|
void transformGeneral(bool highQuality, Imagefloat *original, Imagefloat *transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LensCorrection *pLCPMap, bool useOriginalBuffer);
|
||||||
void transformLCPCAOnly(Imagefloat *original, Imagefloat *transformed, int cx, int cy, const LensCorrection *pLCPMap);
|
void transformLCPCAOnly(Imagefloat *original, Imagefloat *transformed, int cx, int cy, const LensCorrection *pLCPMap, bool useOriginalBuffer);
|
||||||
|
|
||||||
bool needsCA() const;
|
bool needsCA() const;
|
||||||
bool needsDistortion() const;
|
bool needsDistortion() const;
|
||||||
@ -119,7 +119,7 @@ public:
|
|||||||
}
|
}
|
||||||
void setScale(double iscale);
|
void setScale(double iscale);
|
||||||
|
|
||||||
bool needsTransform() const;
|
bool needsTransform(int oW, int oH, int rawRotationDeg, const FramesMetaData *metadata) const;
|
||||||
bool needsPCVignetting() const;
|
bool needsPCVignetting() const;
|
||||||
|
|
||||||
void firstAnalysis(const Imagefloat* const working, const procparams::ProcParams ¶ms, LUTu & vhist16);
|
void firstAnalysis(const Imagefloat* const working, const procparams::ProcParams ¶ms, LUTu & vhist16);
|
||||||
@ -156,7 +156,7 @@ public:
|
|||||||
// void colorCurve (LabImage* lold, LabImage* lnew);
|
// void colorCurve (LabImage* lold, LabImage* lnew);
|
||||||
void sharpening(LabImage* lab, const procparams::SharpeningParams &sharpenParam, bool showMask = false);
|
void sharpening(LabImage* lab, const procparams::SharpeningParams &sharpenParam, bool showMask = false);
|
||||||
void sharpeningcam(CieImage* ncie, float** buffer, bool showMask = false);
|
void sharpeningcam(CieImage* ncie, float** buffer, bool showMask = false);
|
||||||
void transform(Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const FramesMetaData *metadata, int rawRotationDeg, bool fullImage);
|
void transform(Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const FramesMetaData *metadata, int rawRotationDeg, bool fullImage, bool useOriginalBuffer = false);
|
||||||
float resizeScale(const procparams::ProcParams* params, int fw, int fh, int &imw, int &imh);
|
float resizeScale(const procparams::ProcParams* params, int fw, int fh, int &imw, int &imh);
|
||||||
void lab2monitorRgb(LabImage* lab, Image8* image);
|
void lab2monitorRgb(LabImage* lab, Image8* image);
|
||||||
void resize(Imagefloat* src, Imagefloat* dst, float dScale);
|
void resize(Imagefloat* src, Imagefloat* dst, float dScale);
|
||||||
|
@ -86,6 +86,29 @@ float normn (float a, float b, int n)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void logEncode(rtengine::Imagefloat *src, rtengine::Imagefloat *dest, bool multiThread) {
|
||||||
|
|
||||||
|
#ifdef _OPENMP
|
||||||
|
#pragma omp parallel for schedule(dynamic, 16) if(multiThread)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int y = 0; y < src->getHeight(); ++y) {
|
||||||
|
int x = 0;
|
||||||
|
#ifdef __SSE2__
|
||||||
|
for (; x < src->getWidth() - 3; x += 4) {
|
||||||
|
STVFU(dest->r(y, x), xlogf1(LVFU(src->r(y, x))));
|
||||||
|
STVFU(dest->g(y, x), xlogf1(LVFU(src->g(y, x))));
|
||||||
|
STVFU(dest->b(y, x), xlogf1(LVFU(src->b(y, x))));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
for (; x < src->getWidth(); ++x) {
|
||||||
|
dest->r(y, x) = xlogf1(src->r(y, x));
|
||||||
|
dest->g(y, x) = xlogf1(src->g(y, x));
|
||||||
|
dest->b(y, x) = xlogf1(src->b(y, x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
inline void interpolateTransformCubic(rtengine::Imagefloat* src, int xs, int ys, float Dx, float Dy, float &r, float &g, float &b, float mul)
|
inline void interpolateTransformCubic(rtengine::Imagefloat* src, int xs, int ys, float Dx, float Dy, float &r, float &g, float &b, float mul)
|
||||||
{
|
{
|
||||||
@ -111,6 +134,33 @@ inline void interpolateTransformCubic(rtengine::Imagefloat* src, int xs, int ys,
|
|||||||
g = vhadd(weight * gv);
|
g = vhadd(weight * gv);
|
||||||
b = vhadd(weight * bv);
|
b = vhadd(weight * bv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void interpolateTransformCubicLog(rtengine::Imagefloat* src, int xs, int ys, float Dx, float Dy, float &r, float &g, float &b, float mul)
|
||||||
|
{
|
||||||
|
constexpr float A = -0.85f;
|
||||||
|
|
||||||
|
// Vertical
|
||||||
|
const float t1Vert = A * (Dy - Dy * Dy);
|
||||||
|
const float t2Vert = (3.f - 2.f * Dy) * Dy * Dy;
|
||||||
|
const vfloat w3Vert = F2V(t1Vert * Dy);
|
||||||
|
const vfloat w2Vert = F2V(t1Vert * Dy - t1Vert + t2Vert);
|
||||||
|
const vfloat w1Vert = F2V(1.f - (t1Vert * Dy) - t2Vert);
|
||||||
|
const vfloat w0Vert = F2V(t1Vert - (t1Vert * Dy));
|
||||||
|
|
||||||
|
const vfloat rv = (w0Vert * LVFU(src->r(ys, xs)) + w1Vert * LVFU(src->r(ys + 1, xs))) + (w2Vert * LVFU(src->r(ys + 2, xs)) + w3Vert * LVFU(src->r(ys + 3, xs)));
|
||||||
|
const vfloat gv = (w0Vert * LVFU(src->g(ys, xs)) + w1Vert * LVFU(src->g(ys + 1, xs))) + (w2Vert * LVFU(src->g(ys + 2, xs)) + w3Vert * LVFU(src->g(ys + 3, xs)));
|
||||||
|
const vfloat bv = (w0Vert * LVFU(src->b(ys, xs)) + w1Vert * LVFU(src->b(ys + 1, xs))) + (w2Vert * LVFU(src->b(ys + 2, xs)) + w3Vert * LVFU(src->b(ys + 3, xs)));
|
||||||
|
|
||||||
|
// Horizontal
|
||||||
|
const float t1Hor = A * (Dx - Dx * Dx);
|
||||||
|
const float t2Hor = (3.f - 2.f * Dx) * Dx * Dx;
|
||||||
|
const vfloat weight = _mm_set_ps(t1Hor * Dx, t1Hor * Dx - t1Hor + t2Hor, 1.f - (t1Hor * Dx) - t2Hor, t1Hor - (t1Hor * Dx));
|
||||||
|
const vfloat tempv = _mm_setr_ps(vhadd(weight * rv), vhadd(weight * gv), vhadd(weight * bv), 0.f);
|
||||||
|
const vfloat resultv = xexpf(tempv);
|
||||||
|
r = mul * resultv[0];
|
||||||
|
g = mul * resultv[1];
|
||||||
|
b = mul * resultv[2];
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
inline void interpolateTransformCubic(rtengine::Imagefloat* src, int xs, int ys, float Dx, float Dy, float &r, float &g, float &b, float mul)
|
inline void interpolateTransformCubic(rtengine::Imagefloat* src, int xs, int ys, float Dx, float Dy, float &r, float &g, float &b, float mul)
|
||||||
{
|
{
|
||||||
@ -143,6 +193,38 @@ inline void interpolateTransformCubic(rtengine::Imagefloat* src, int xs, int ys,
|
|||||||
g = mul * (gv[0] * w0Hor + gv[1] * w1Hor + gv[2] * w2Hor + gv[3] * w3Hor);
|
g = mul * (gv[0] * w0Hor + gv[1] * w1Hor + gv[2] * w2Hor + gv[3] * w3Hor);
|
||||||
b = mul * (bv[0] * w0Hor + bv[1] * w1Hor + bv[2] * w2Hor + bv[3] * w3Hor);
|
b = mul * (bv[0] * w0Hor + bv[1] * w1Hor + bv[2] * w2Hor + bv[3] * w3Hor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void interpolateTransformCubicLog(rtengine::Imagefloat* src, int xs, int ys, float Dx, float Dy, float &r, float &g, float &b, float mul)
|
||||||
|
{
|
||||||
|
constexpr float A = -0.85f;
|
||||||
|
|
||||||
|
// Vertical
|
||||||
|
const float t1Vert = A * (Dy - Dy * Dy);
|
||||||
|
const float t2Vert = (3.f - 2.f * Dy) * Dy * Dy;
|
||||||
|
const float w3Vert = t1Vert * Dy;
|
||||||
|
const float w2Vert = t1Vert * Dy - t1Vert + t2Vert;
|
||||||
|
const float w1Vert = 1.f - (t1Vert * Dy) - t2Vert;
|
||||||
|
const float w0Vert = t1Vert - (t1Vert * Dy);
|
||||||
|
|
||||||
|
float rv[4], gv[4], bv[4];
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
rv[i] = w0Vert * src->r(ys, xs + i) + w1Vert * src->r(ys + 1, xs + i) + w2Vert * src->r(ys + 2, xs + i) + w3Vert * src->r(ys + 3, xs + i);
|
||||||
|
gv[i] = w0Vert * src->g(ys, xs + i) + w1Vert * src->g(ys + 1, xs + i) + w2Vert * src->g(ys + 2, xs + i) + w3Vert * src->g(ys + 3, xs + i);
|
||||||
|
bv[i] = w0Vert * src->b(ys, xs + i) + w1Vert * src->b(ys + 1, xs + i) + w2Vert * src->b(ys + 2, xs + i) + w3Vert * src->b(ys + 3, xs + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Horizontal
|
||||||
|
const float t1Hor = A * (Dx - Dx * Dx);
|
||||||
|
const float t2Hor = (3.f - 2.f * Dx) * Dx * Dx;
|
||||||
|
const float w3Hor = t1Hor * Dx;
|
||||||
|
const float w2Hor = t1Hor * Dx - t1Hor + t2Hor;
|
||||||
|
const float w1Hor = 1.f - (t1Hor * Dx) - t2Hor;
|
||||||
|
const float w0Hor = t1Hor - (t1Hor * Dx);
|
||||||
|
|
||||||
|
r = mul * xexpf(rv[0] * w0Hor + rv[1] * w1Hor + rv[2] * w2Hor + rv[3] * w3Hor);
|
||||||
|
g = mul * xexpf(gv[0] * w0Hor + gv[1] * w1Hor + gv[2] * w2Hor + gv[3] * w3Hor);
|
||||||
|
b = mul * xexpf(bv[0] * w0Hor + bv[1] * w1Hor + bv[2] * w2Hor + bv[3] * w3Hor);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
inline void interpolateTransformChannelsCubic(const float* const* src, int xs, int ys, float Dx, float Dy, float& dest, float mul)
|
inline void interpolateTransformChannelsCubic(const float* const* src, int xs, int ys, float Dx, float Dy, float& dest, float mul)
|
||||||
@ -165,6 +247,27 @@ inline void interpolateTransformChannelsCubic(const float* const* src, int xs, i
|
|||||||
const vfloat weight = _mm_set_ps(t1Hor * Dx, t1Hor * Dx - t1Hor + t2Hor, 1.f - (t1Hor * Dx) - t2Hor, t1Hor - (t1Hor * Dx));
|
const vfloat weight = _mm_set_ps(t1Hor * Dx, t1Hor * Dx - t1Hor + t2Hor, 1.f - (t1Hor * Dx) - t2Hor, t1Hor - (t1Hor * Dx));
|
||||||
dest = mul * vhadd(weight * cv);
|
dest = mul * vhadd(weight * cv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void interpolateTransformChannelsCubicLog(const float* const* src, int xs, int ys, float Dx, float Dy, float& dest, float mul)
|
||||||
|
{
|
||||||
|
constexpr float A = -0.85f;
|
||||||
|
|
||||||
|
// Vertical
|
||||||
|
const float t1Vert = A * (Dy - Dy * Dy);
|
||||||
|
const float t2Vert = (3.f - 2.f * Dy) * Dy * Dy;
|
||||||
|
const vfloat w3Vert = F2V(t1Vert * Dy);
|
||||||
|
const vfloat w2Vert = F2V(t1Vert * Dy - t1Vert + t2Vert);
|
||||||
|
const vfloat w1Vert = F2V(1.f - (t1Vert * Dy) - t2Vert);
|
||||||
|
const vfloat w0Vert = F2V(t1Vert - (t1Vert * Dy));
|
||||||
|
|
||||||
|
const vfloat cv = (w0Vert * LVFU(src[ys][xs]) + w1Vert * LVFU(src[ys + 1][xs])) + (w2Vert * LVFU(src[ys + 2][xs]) + w3Vert * LVFU(src[ys + 3][xs]));
|
||||||
|
|
||||||
|
// Horizontal
|
||||||
|
const float t1Hor = A * (Dx - Dx * Dx);
|
||||||
|
const float t2Hor = (3.f - 2.f * Dx) * Dx * Dx;
|
||||||
|
const vfloat weight = _mm_set_ps(t1Hor * Dx, t1Hor * Dx - t1Hor + t2Hor, 1.f - (t1Hor * Dx) - t2Hor, t1Hor - (t1Hor * Dx));
|
||||||
|
dest = mul * xexpf(vhadd(weight * cv));
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
inline void interpolateTransformChannelsCubic(const float* const* src, int xs, int ys, float Dx, float Dy, float& dest, float mul)
|
inline void interpolateTransformChannelsCubic(const float* const* src, int xs, int ys, float Dx, float Dy, float& dest, float mul)
|
||||||
{
|
{
|
||||||
@ -193,6 +296,34 @@ inline void interpolateTransformChannelsCubic(const float* const* src, int xs, i
|
|||||||
|
|
||||||
dest = mul * (cv[0] * w0Hor + cv[1] * w1Hor + cv[2] * w2Hor + cv[3] * w3Hor);
|
dest = mul * (cv[0] * w0Hor + cv[1] * w1Hor + cv[2] * w2Hor + cv[3] * w3Hor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void interpolateTransformChannelsCubicLog(const float* const* src, int xs, int ys, float Dx, float Dy, float& dest, float mul)
|
||||||
|
{
|
||||||
|
constexpr float A = -0.85f;
|
||||||
|
|
||||||
|
// Vertical
|
||||||
|
const float t1Vert = A * (Dy - Dy * Dy);
|
||||||
|
const float t2Vert = (3.f - 2.f * Dy) * Dy * Dy;
|
||||||
|
const float w3Vert = t1Vert * Dy;
|
||||||
|
const float w2Vert = t1Vert * Dy - t1Vert + t2Vert;
|
||||||
|
const float w1Vert = 1.f - (t1Vert * Dy) - t2Vert;
|
||||||
|
const float w0Vert = t1Vert - (t1Vert * Dy);
|
||||||
|
|
||||||
|
float cv[4];
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
cv[i] = w0Vert * src[ys][xs + i] + w1Vert * src[ys + 1][xs + i] + w2Vert * src[ys + 2][xs + i] + w3Vert * src[ys + 3][xs + i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Horizontal
|
||||||
|
const float t1Hor = A * (Dx - Dx * Dx);
|
||||||
|
const float t2Hor = (3.f - 2.f * Dx) * Dx * Dx;
|
||||||
|
const float w3Hor = t1Hor * Dx;
|
||||||
|
const float w2Hor = t1Hor * Dx - t1Hor + t2Hor;
|
||||||
|
const float w1Hor = 1.f - (t1Hor * Dx) - t2Hor;
|
||||||
|
const float w0Hor = t1Hor - (t1Hor * Dx);
|
||||||
|
|
||||||
|
dest = mul * xexpf(cv[0] * w0Hor + cv[1] * w1Hor + cv[2] * w2Hor + cv[3] * w3Hor);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -405,7 +536,7 @@ bool ImProcFunctions::transCoord (int W, int H, int x, int y, int w, int h, int&
|
|||||||
|
|
||||||
void ImProcFunctions::transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH,
|
void ImProcFunctions::transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH,
|
||||||
const FramesMetaData *metadata,
|
const FramesMetaData *metadata,
|
||||||
int rawRotationDeg, bool fullImage)
|
int rawRotationDeg, bool fullImage, bool useOriginalBuffer)
|
||||||
{
|
{
|
||||||
double focalLen = metadata->getFocalLen();
|
double focalLen = metadata->getFocalLen();
|
||||||
double focalLen35mm = metadata->getFocalLen35mm();
|
double focalLen35mm = metadata->getFocalLen35mm();
|
||||||
@ -453,10 +584,10 @@ void ImProcFunctions::transform (Imagefloat* original, Imagefloat* transformed,
|
|||||||
dest = tmpimg.get();
|
dest = tmpimg.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
transformGeneral(highQuality, original, dest, cx, cy, sx, sy, oW, oH, fW, fH, pLCPMap.get());
|
transformGeneral(highQuality, original, dest, cx, cy, sx, sy, oW, oH, fW, fH, pLCPMap.get(), useOriginalBuffer);
|
||||||
|
|
||||||
if (highQuality && dest != transformed) {
|
if (highQuality && dest != transformed) {
|
||||||
transformLCPCAOnly(dest, transformed, cx, cy, pLCPMap.get());
|
transformLCPCAOnly(dest, transformed, cx, cy, pLCPMap.get(), useOriginalBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -845,8 +976,9 @@ void ImProcFunctions::transformLuminanceOnly (Imagefloat* original, Imagefloat*
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, Imagefloat *transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LensCorrection *pLCPMap)
|
void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, Imagefloat *transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LensCorrection *pLCPMap, bool useOriginalBuffer)
|
||||||
{
|
{
|
||||||
|
|
||||||
// set up stuff, depending on the mode we are
|
// set up stuff, depending on the mode we are
|
||||||
const bool enableLCPDist = pLCPMap && params->lensProf.useDist;
|
const bool enableLCPDist = pLCPMap && params->lensProf.useDist;
|
||||||
const bool enableCA = highQuality && needsCA();
|
const bool enableCA = highQuality && needsCA();
|
||||||
@ -874,11 +1006,6 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I
|
|||||||
calcPCVignetteParams(fW, fH, oW, oH, params->pcvignette, params->crop, pcv);
|
calcPCVignetteParams(fW, fH, oW, oH, params->pcvignette, params->crop, pcv);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::array<const float* const*, 3> chOrig = {
|
|
||||||
original->r.ptrs,
|
|
||||||
original->g.ptrs,
|
|
||||||
original->b.ptrs
|
|
||||||
};
|
|
||||||
const std::array<float* const*, 3> chTrans = {
|
const std::array<float* const*, 3> chTrans = {
|
||||||
transformed->r.ptrs,
|
transformed->r.ptrs,
|
||||||
transformed->g.ptrs,
|
transformed->g.ptrs,
|
||||||
@ -922,9 +1049,27 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I
|
|||||||
const double ascale = params->commonTrans.autofill ? getTransformAutoFill(oW, oH, pLCPMap) : 1.0;
|
const double ascale = params->commonTrans.autofill ? getTransformAutoFill(oW, oH, pLCPMap) : 1.0;
|
||||||
|
|
||||||
const bool darkening = (params->vignetting.amount <= 0.0);
|
const bool darkening = (params->vignetting.amount <= 0.0);
|
||||||
|
const bool useLog = params->commonTrans.method == "log" && highQuality;
|
||||||
const double centerFactorx = cx - w2;
|
const double centerFactorx = cx - w2;
|
||||||
const double centerFactory = cy - h2;
|
const double centerFactory = cy - h2;
|
||||||
|
|
||||||
|
std::unique_ptr<Imagefloat> tempLog;
|
||||||
|
if (useLog) {
|
||||||
|
if (!useOriginalBuffer) {
|
||||||
|
tempLog.reset(new Imagefloat(original->getWidth(), original->getHeight()));
|
||||||
|
logEncode(original, tempLog.get(), multiThread);
|
||||||
|
original = tempLog.get();
|
||||||
|
} else {
|
||||||
|
logEncode(original, original, multiThread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::array<const float* const*, 3> chOrig = {
|
||||||
|
original->r.ptrs,
|
||||||
|
original->g.ptrs,
|
||||||
|
original->b.ptrs
|
||||||
|
};
|
||||||
|
|
||||||
// main cycle
|
// main cycle
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel for schedule(dynamic, 16) if(multiThread)
|
#pragma omp parallel for schedule(dynamic, 16) if(multiThread)
|
||||||
@ -1011,15 +1156,23 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I
|
|||||||
|
|
||||||
if (yc > 0 && yc < original->getHeight() - 2 && xc > 0 && xc < original->getWidth() - 2) {
|
if (yc > 0 && yc < original->getHeight() - 2 && xc > 0 && xc < original->getWidth() - 2) {
|
||||||
// all interpolation pixels inside image
|
// all interpolation pixels inside image
|
||||||
if (enableCA) {
|
if (!highQuality) {
|
||||||
interpolateTransformChannelsCubic(chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], vignmul);
|
|
||||||
} else if (!highQuality) {
|
|
||||||
transformed->r(y, x) = vignmul * (original->r(yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->r(yc, xc + 1) * Dx * (1.0 - Dy) + original->r(yc + 1, xc) * (1.0 - Dx) * Dy + original->r(yc + 1, xc + 1) * Dx * Dy);
|
transformed->r(y, x) = vignmul * (original->r(yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->r(yc, xc + 1) * Dx * (1.0 - Dy) + original->r(yc + 1, xc) * (1.0 - Dx) * Dy + original->r(yc + 1, xc + 1) * Dx * Dy);
|
||||||
transformed->g(y, x) = vignmul * (original->g(yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->g(yc, xc + 1) * Dx * (1.0 - Dy) + original->g(yc + 1, xc) * (1.0 - Dx) * Dy + original->g(yc + 1, xc + 1) * Dx * Dy);
|
transformed->g(y, x) = vignmul * (original->g(yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->g(yc, xc + 1) * Dx * (1.0 - Dy) + original->g(yc + 1, xc) * (1.0 - Dx) * Dy + original->g(yc + 1, xc + 1) * Dx * Dy);
|
||||||
transformed->b(y, x) = vignmul * (original->b(yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->b(yc, xc + 1) * Dx * (1.0 - Dy) + original->b(yc + 1, xc) * (1.0 - Dx) * Dy + original->b(yc + 1, xc + 1) * Dx * Dy);
|
transformed->b(y, x) = vignmul * (original->b(yc, xc) * (1.0 - Dx) * (1.0 - Dy) + original->b(yc, xc + 1) * Dx * (1.0 - Dy) + original->b(yc + 1, xc) * (1.0 - Dx) * Dy + original->b(yc + 1, xc + 1) * Dx * Dy);
|
||||||
|
} else if (!useLog) {
|
||||||
|
if (enableCA) {
|
||||||
|
interpolateTransformChannelsCubic(chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], vignmul);
|
||||||
} else {
|
} else {
|
||||||
interpolateTransformCubic(original, xc - 1, yc - 1, Dx, Dy, transformed->r(y, x), transformed->g(y, x), transformed->b(y, x), vignmul);
|
interpolateTransformCubic(original, xc - 1, yc - 1, Dx, Dy, transformed->r(y, x), transformed->g(y, x), transformed->b(y, x), vignmul);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (enableCA) {
|
||||||
|
interpolateTransformChannelsCubicLog(chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], vignmul);
|
||||||
|
} else {
|
||||||
|
interpolateTransformCubicLog(original, xc - 1, yc - 1, Dx, Dy, transformed->r(y, x), transformed->g(y, x), transformed->b(y, x), vignmul);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// edge pixels
|
// edge pixels
|
||||||
const int y1 = LIM(yc, 0, original->getHeight() - 1);
|
const int y1 = LIM(yc, 0, original->getHeight() - 1);
|
||||||
@ -1027,6 +1180,15 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I
|
|||||||
const int x1 = LIM(xc, 0, original->getWidth() - 1);
|
const int x1 = LIM(xc, 0, original->getWidth() - 1);
|
||||||
const int x2 = LIM(xc + 1, 0, original->getWidth() - 1);
|
const int x2 = LIM(xc + 1, 0, original->getWidth() - 1);
|
||||||
|
|
||||||
|
if (useLog) {
|
||||||
|
if (enableCA) {
|
||||||
|
chTrans[c][y][x] = vignmul * xexpf(chOrig[c][y1][x1] * (1.0 - Dx) * (1.0 - Dy) + chOrig[c][y1][x2] * Dx * (1.0 - Dy) + chOrig[c][y2][x1] * (1.0 - Dx) * Dy + chOrig[c][y2][x2] * Dx * Dy);
|
||||||
|
} else {
|
||||||
|
transformed->r(y, x) = vignmul * xexpf(original->r(y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->r(y1, x2) * Dx * (1.0 - Dy) + original->r(y2, x1) * (1.0 - Dx) * Dy + original->r(y2, x2) * Dx * Dy);
|
||||||
|
transformed->g(y, x) = vignmul * xexpf(original->g(y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->g(y1, x2) * Dx * (1.0 - Dy) + original->g(y2, x1) * (1.0 - Dx) * Dy + original->g(y2, x2) * Dx * Dy);
|
||||||
|
transformed->b(y, x) = vignmul * xexpf(original->b(y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->b(y1, x2) * Dx * (1.0 - Dy) + original->b(y2, x1) * (1.0 - Dx) * Dy + original->b(y2, x2) * Dx * Dy);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (enableCA) {
|
if (enableCA) {
|
||||||
chTrans[c][y][x] = vignmul * (chOrig[c][y1][x1] * (1.0 - Dx) * (1.0 - Dy) + chOrig[c][y1][x2] * Dx * (1.0 - Dy) + chOrig[c][y2][x1] * (1.0 - Dx) * Dy + chOrig[c][y2][x2] * Dx * Dy);
|
chTrans[c][y][x] = vignmul * (chOrig[c][y1][x1] * (1.0 - Dx) * (1.0 - Dy) + chOrig[c][y1][x2] * Dx * (1.0 - Dy) + chOrig[c][y2][x1] * (1.0 - Dx) * Dy + chOrig[c][y2][x2] * Dx * Dy);
|
||||||
} else {
|
} else {
|
||||||
@ -1035,6 +1197,7 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I
|
|||||||
transformed->b(y, x) = vignmul * (original->b(y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->b(y1, x2) * Dx * (1.0 - Dy) + original->b(y2, x1) * (1.0 - Dx) * Dy + original->b(y2, x2) * Dx * Dy);
|
transformed->b(y, x) = vignmul * (original->b(y1, x1) * (1.0 - Dx) * (1.0 - Dy) + original->b(y1, x2) * Dx * (1.0 - Dy) + original->b(y2, x1) * (1.0 - Dx) * Dy + original->b(y2, x2) * Dx * Dy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (enableCA) {
|
if (enableCA) {
|
||||||
// not valid (source pixel x,y not inside source image, etc.)
|
// not valid (source pixel x,y not inside source image, etc.)
|
||||||
@ -1051,19 +1214,24 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ImProcFunctions::transformLCPCAOnly(Imagefloat *original, Imagefloat *transformed, int cx, int cy, const LensCorrection *pLCPMap)
|
void ImProcFunctions::transformLCPCAOnly(Imagefloat *original, Imagefloat *transformed, int cx, int cy, const LensCorrection *pLCPMap, bool useOriginalBuffer)
|
||||||
{
|
{
|
||||||
assert(pLCPMap && params->lensProf.useCA && pLCPMap->isCACorrectionAvailable());
|
assert(pLCPMap && params->lensProf.useCA && pLCPMap->isCACorrectionAvailable());
|
||||||
|
const bool useLog = params->commonTrans.method == "log";
|
||||||
|
|
||||||
float** chOrig[3];
|
float** chTrans[3] = {transformed->r.ptrs, transformed->g.ptrs, transformed->b.ptrs};
|
||||||
chOrig[0] = original->r.ptrs;
|
|
||||||
chOrig[1] = original->g.ptrs;
|
|
||||||
chOrig[2] = original->b.ptrs;
|
|
||||||
|
|
||||||
float** chTrans[3];
|
std::unique_ptr<Imagefloat> tempLog;
|
||||||
chTrans[0] = transformed->r.ptrs;
|
if (useLog) {
|
||||||
chTrans[1] = transformed->g.ptrs;
|
if (!useOriginalBuffer) {
|
||||||
chTrans[2] = transformed->b.ptrs;
|
tempLog.reset(new Imagefloat(original->getWidth(), original->getHeight()));
|
||||||
|
logEncode(original, tempLog.get(), multiThread);
|
||||||
|
original = tempLog.get();
|
||||||
|
} else {
|
||||||
|
logEncode(original, original, multiThread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float** chOrig[3] = {original->r.ptrs, original->g.ptrs, original->b.ptrs};
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel for if (multiThread)
|
#pragma omp parallel for if (multiThread)
|
||||||
@ -1089,15 +1257,22 @@ void ImProcFunctions::transformLCPCAOnly(Imagefloat *original, Imagefloat *trans
|
|||||||
// multiplier for vignetting correction
|
// multiplier for vignetting correction
|
||||||
if (yc > 0 && yc < original->getHeight() - 2 && xc > 0 && xc < original->getWidth() - 2) {
|
if (yc > 0 && yc < original->getHeight() - 2 && xc > 0 && xc < original->getWidth() - 2) {
|
||||||
// all interpolation pixels inside image
|
// all interpolation pixels inside image
|
||||||
|
if (!useLog) {
|
||||||
interpolateTransformChannelsCubic(chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], 1.0);
|
interpolateTransformChannelsCubic(chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], 1.0);
|
||||||
|
} else {
|
||||||
|
interpolateTransformChannelsCubicLog(chOrig[c], xc - 1, yc - 1, Dx, Dy, chTrans[c][y][x], 1.0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// edge pixels
|
// edge pixels
|
||||||
int y1 = LIM (yc, 0, original->getHeight() - 1);
|
int y1 = LIM (yc, 0, original->getHeight() - 1);
|
||||||
int y2 = LIM (yc + 1, 0, original->getHeight() - 1);
|
int y2 = LIM (yc + 1, 0, original->getHeight() - 1);
|
||||||
int x1 = LIM (xc, 0, original->getWidth() - 1);
|
int x1 = LIM (xc, 0, original->getWidth() - 1);
|
||||||
int x2 = LIM (xc + 1, 0, original->getWidth() - 1);
|
int x2 = LIM (xc + 1, 0, original->getWidth() - 1);
|
||||||
|
if (!useLog) {
|
||||||
chTrans[c][y][x] = (chOrig[c][y1][x1] * (1.0 - Dx) * (1.0 - Dy) + chOrig[c][y1][x2] * Dx * (1.0 - Dy) + chOrig[c][y2][x1] * (1.0 - Dx) * Dy + chOrig[c][y2][x2] * Dx * Dy);
|
chTrans[c][y][x] = (chOrig[c][y1][x1] * (1.0 - Dx) * (1.0 - Dy) + chOrig[c][y1][x2] * Dx * (1.0 - Dy) + chOrig[c][y2][x1] * (1.0 - Dx) * Dy + chOrig[c][y2][x2] * Dx * Dy);
|
||||||
|
} else {
|
||||||
|
chTrans[c][y][x] = xexpf(chOrig[c][y1][x1] * (1.0 - Dx) * (1.0 - Dy) + chOrig[c][y1][x2] * Dx * (1.0 - Dy) + chOrig[c][y2][x1] * (1.0 - Dx) * Dy + chOrig[c][y2][x2] * Dx * Dy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// not valid (source pixel x,y not inside source image, etc.)
|
// not valid (source pixel x,y not inside source image, etc.)
|
||||||
@ -1178,9 +1353,14 @@ bool ImProcFunctions::needsLensfun() const
|
|||||||
return params->lensProf.useLensfun();
|
return params->lensProf.useLensfun();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImProcFunctions::needsTransform () const
|
bool ImProcFunctions::needsTransform (int oW, int oH, int rawRotationDeg, const FramesMetaData *metadata) const
|
||||||
{
|
{
|
||||||
return needsCA () || needsDistortion () || needsRotation () || needsPerspective () || needsGradient () || needsPCVignetting () || needsVignetting () || needsLCP() || needsLensfun();
|
bool needsLf = needsLensfun();
|
||||||
|
if (needsLf) {
|
||||||
|
std::unique_ptr<const LensCorrection> pLCPMap = LFDatabase::getInstance()->findModifier(params->lensProf, metadata, oW, oH, params->coarse, rawRotationDeg);
|
||||||
|
needsLf = pLCPMap.get();
|
||||||
|
}
|
||||||
|
return needsCA () || needsDistortion () || needsRotation () || needsPerspective () || needsGradient () || needsPCVignetting () || needsVignetting () || needsLCP() || needsLf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1732,13 +1732,14 @@ bool CoarseTransformParams::operator !=(const CoarseTransformParams& other) cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
CommonTransformParams::CommonTransformParams() :
|
CommonTransformParams::CommonTransformParams() :
|
||||||
|
method("log"),
|
||||||
autofill(true)
|
autofill(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommonTransformParams::operator ==(const CommonTransformParams& other) const
|
bool CommonTransformParams::operator ==(const CommonTransformParams& other) const
|
||||||
{
|
{
|
||||||
return autofill == other.autofill;
|
return method == other.method && autofill == other.autofill;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommonTransformParams::operator !=(const CommonTransformParams& other) const
|
bool CommonTransformParams::operator !=(const CommonTransformParams& other) const
|
||||||
@ -3344,6 +3345,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
|
|||||||
saveToKeyfile(!pedited || pedited->coarse.vflip, "Coarse Transformation", "VerticalFlip", coarse.vflip, keyFile);
|
saveToKeyfile(!pedited || pedited->coarse.vflip, "Coarse Transformation", "VerticalFlip", coarse.vflip, keyFile);
|
||||||
|
|
||||||
// Common properties for transformations
|
// Common properties for transformations
|
||||||
|
saveToKeyfile(!pedited || pedited->commonTrans.method, "Common Properties for Transformations", "Method", commonTrans.method, keyFile);
|
||||||
saveToKeyfile(!pedited || pedited->commonTrans.autofill, "Common Properties for Transformations", "AutoFill", commonTrans.autofill, keyFile);
|
saveToKeyfile(!pedited || pedited->commonTrans.autofill, "Common Properties for Transformations", "AutoFill", commonTrans.autofill, keyFile);
|
||||||
|
|
||||||
// Rotation
|
// Rotation
|
||||||
@ -4393,6 +4395,11 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (keyFile.has_group("Common Properties for Transformations")) {
|
if (keyFile.has_group("Common Properties for Transformations")) {
|
||||||
|
if (keyFile.has_key("Common Properties for Transformations", "Method")) {
|
||||||
|
assignFromKeyfile(keyFile, "Common Properties for Transformations", "Method", pedited, commonTrans.method, pedited->commonTrans.method);
|
||||||
|
} else {
|
||||||
|
commonTrans.method = "lin";
|
||||||
|
}
|
||||||
assignFromKeyfile(keyFile, "Common Properties for Transformations", "AutoFill", pedited, commonTrans.autofill, pedited->commonTrans.autofill);
|
assignFromKeyfile(keyFile, "Common Properties for Transformations", "AutoFill", pedited, commonTrans.autofill, pedited->commonTrans.autofill);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -837,6 +837,7 @@ struct CoarseTransformParams {
|
|||||||
* Common transformation parameters
|
* Common transformation parameters
|
||||||
*/
|
*/
|
||||||
struct CommonTransformParams {
|
struct CommonTransformParams {
|
||||||
|
Glib::ustring method;
|
||||||
bool autofill;
|
bool autofill;
|
||||||
|
|
||||||
CommonTransformParams();
|
CommonTransformParams();
|
||||||
|
@ -1247,12 +1247,12 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, eSensorT
|
|||||||
ipf.ToneMapFattal02(baseImg);
|
ipf.ToneMapFattal02(baseImg);
|
||||||
|
|
||||||
// perform transform
|
// perform transform
|
||||||
if (ipf.needsTransform()) {
|
|
||||||
Imagefloat* trImg = new Imagefloat (fw, fh);
|
|
||||||
int origFW;
|
int origFW;
|
||||||
int origFH;
|
int origFH;
|
||||||
double tscale = 0.0;
|
double tscale = 0.0;
|
||||||
getDimensions (origFW, origFH, tscale);
|
getDimensions (origFW, origFH, tscale);
|
||||||
|
if (ipf.needsTransform(origFW * tscale + 0.5, origFH * tscale + 0.5, 0, metadata)) {
|
||||||
|
Imagefloat* trImg = new Imagefloat (fw, fh);
|
||||||
ipf.transform (baseImg, trImg, 0, 0, 0, 0, fw, fh, origFW * tscale + 0.5, origFH * tscale + 0.5, metadata, 0, true); // Raw rotate degree not detectable here
|
ipf.transform (baseImg, trImg, 0, 0, 0, 0, fw, fh, origFW * tscale + 0.5, origFH * tscale + 0.5, metadata, 0, true); // Raw rotate degree not detectable here
|
||||||
delete baseImg;
|
delete baseImg;
|
||||||
baseImg = trImg;
|
baseImg = trImg;
|
||||||
|
@ -880,7 +880,7 @@ private:
|
|||||||
ipf.ToneMapFattal02(baseImg);
|
ipf.ToneMapFattal02(baseImg);
|
||||||
|
|
||||||
// perform transform (excepted resizing)
|
// perform transform (excepted resizing)
|
||||||
if (ipf.needsTransform()) {
|
if (ipf.needsTransform(fw, fh, imgsrc->getRotateDegree(), imgsrc->getMetaData())) {
|
||||||
Imagefloat* trImg = nullptr;
|
Imagefloat* trImg = nullptr;
|
||||||
|
|
||||||
if (ipf.needsLuminanceOnly()) {
|
if (ipf.needsLuminanceOnly()) {
|
||||||
@ -890,7 +890,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
ipf.transform(baseImg, trImg, 0, 0, 0, 0, fw, fh, fw, fh,
|
ipf.transform(baseImg, trImg, 0, 0, 0, 0, fw, fh, fw, fh,
|
||||||
imgsrc->getMetaData(), imgsrc->getRotateDegree(), true);
|
imgsrc->getMetaData(), imgsrc->getRotateDegree(), true, true);
|
||||||
|
|
||||||
if (trImg != baseImg) {
|
if (trImg != baseImg) {
|
||||||
delete baseImg;
|
delete baseImg;
|
||||||
|
@ -532,7 +532,7 @@ __inline double xlog(double d) {
|
|||||||
|
|
||||||
x = x * t + 0.693147180559945286226764 * e;
|
x = x * t + 0.693147180559945286226764 * e;
|
||||||
|
|
||||||
if (xisinf(d)) x = rtengine::RT_INFINITY;
|
if (xispinf(d)) x = rtengine::RT_INFINITY;
|
||||||
if (d < 0) x = rtengine::RT_NAN;
|
if (d < 0) x = rtengine::RT_NAN;
|
||||||
if (d == 0) x = -rtengine::RT_INFINITY;
|
if (d == 0) x = -rtengine::RT_INFINITY;
|
||||||
|
|
||||||
@ -864,7 +864,7 @@ __inline double xlog10(double a) {
|
|||||||
double2 d = mul_dd(logk(a), dd(0.43429448190325176116, 6.6494347733425473126e-17));
|
double2 d = mul_dd(logk(a), dd(0.43429448190325176116, 6.6494347733425473126e-17));
|
||||||
double x = d.x + d.y;
|
double x = d.x + d.y;
|
||||||
|
|
||||||
if (xisinf(a)) x = rtengine::RT_INFINITY;
|
if (xispinf(a)) x = rtengine::RT_INFINITY;
|
||||||
if (a < 0) x = rtengine::RT_NAN;
|
if (a < 0) x = rtengine::RT_NAN;
|
||||||
if (a == 0) x = -rtengine::RT_INFINITY;
|
if (a == 0) x = -rtengine::RT_INFINITY;
|
||||||
|
|
||||||
@ -875,7 +875,7 @@ __inline double xlog1p(double a) {
|
|||||||
double2 d = logk2(add2_ss(a, 1));
|
double2 d = logk2(add2_ss(a, 1));
|
||||||
double x = d.x + d.y;
|
double x = d.x + d.y;
|
||||||
|
|
||||||
if (xisinf(a)) x = rtengine::RT_INFINITY;
|
if (xispinf(a)) x = rtengine::RT_INFINITY;
|
||||||
if (a < -1) x = rtengine::RT_NAN;
|
if (a < -1) x = rtengine::RT_NAN;
|
||||||
if (a == -1) x = -rtengine::RT_INFINITY;
|
if (a == -1) x = -rtengine::RT_INFINITY;
|
||||||
|
|
||||||
@ -894,6 +894,15 @@ __inline double xlog1p(double a) {
|
|||||||
|
|
||||||
#define R_LN2f 1.442695040888963407359924681001892137426645954152985934135449406931f
|
#define R_LN2f 1.442695040888963407359924681001892137426645954152985934135449406931f
|
||||||
|
|
||||||
|
#ifdef __SSE2__
|
||||||
|
__inline int xrintf(float x) {
|
||||||
|
return _mm_cvt_ss2si(_mm_set_ss(x));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
__inline int xrintf(float x) {
|
||||||
|
return x + (x < 0 ? -0.5f : 0.5f);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
__inline int32_t floatToRawIntBits(float d) {
|
__inline int32_t floatToRawIntBits(float d) {
|
||||||
union {
|
union {
|
||||||
float f;
|
float f;
|
||||||
@ -980,7 +989,7 @@ __inline float xsinf(float d) {
|
|||||||
int q;
|
int q;
|
||||||
float u, s;
|
float u, s;
|
||||||
|
|
||||||
q = rint(d * rtengine::RT_1_PI_F);
|
q = xrintf(d * rtengine::RT_1_PI_F);
|
||||||
|
|
||||||
d = mlaf(q, -PI4_Af*4, d);
|
d = mlaf(q, -PI4_Af*4, d);
|
||||||
d = mlaf(q, -PI4_Bf*4, d);
|
d = mlaf(q, -PI4_Bf*4, d);
|
||||||
@ -1009,7 +1018,7 @@ __inline float xcosf(float d) {
|
|||||||
int q;
|
int q;
|
||||||
float u, s;
|
float u, s;
|
||||||
|
|
||||||
q = 1 + 2*rint(d * rtengine::RT_1_PI_F - 0.5f);
|
q = 1 + 2*xrintf(d * rtengine::RT_1_PI_F - 0.5f);
|
||||||
|
|
||||||
d = mlaf(q, -PI4_Af*2, d);
|
d = mlaf(q, -PI4_Af*2, d);
|
||||||
d = mlaf(q, -PI4_Bf*2, d);
|
d = mlaf(q, -PI4_Bf*2, d);
|
||||||
@ -1041,7 +1050,7 @@ __inline float2 xsincosf(float d) {
|
|||||||
float u, s, t;
|
float u, s, t;
|
||||||
float2 r;
|
float2 r;
|
||||||
|
|
||||||
q = rint(d * rtengine::RT_2_PI_F);
|
q = xrintf(d * rtengine::RT_2_PI_F);
|
||||||
|
|
||||||
s = d;
|
s = d;
|
||||||
|
|
||||||
@ -1083,7 +1092,7 @@ __inline float xtanf(float d) {
|
|||||||
int q;
|
int q;
|
||||||
float u, s, x;
|
float u, s, x;
|
||||||
|
|
||||||
q = rint(d * (float)(2 * rtengine::RT_1_PI));
|
q = xrintf(d * (float)(2 * rtengine::RT_1_PI));
|
||||||
|
|
||||||
x = d;
|
x = d;
|
||||||
|
|
||||||
@ -1199,17 +1208,41 @@ __inline float xlogf(float d) {
|
|||||||
|
|
||||||
x = x * t + 0.693147180559945286226764f * e;
|
x = x * t + 0.693147180559945286226764f * e;
|
||||||
|
|
||||||
if (xisinff(d)) x = rtengine::RT_INFINITY_F;
|
if (xispinff(d)) x = rtengine::RT_INFINITY_F;
|
||||||
if (d < 0) x = rtengine::RT_NAN_F;
|
if (d < 0) x = rtengine::RT_NAN_F;
|
||||||
if (d == 0) x = -rtengine::RT_INFINITY_F;
|
if (d == 0) x = -rtengine::RT_INFINITY_F;
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__inline float xlogf1(float d) { // does xlogf(vmaxf(d, 1.f)) but faster
|
||||||
|
float x, x2, t, m;
|
||||||
|
int e;
|
||||||
|
|
||||||
|
e = ilogbp1f(d * 0.7071f);
|
||||||
|
m = ldexpkf(d, -e);
|
||||||
|
|
||||||
|
x = (m-1.0f) / (m+1.0f);
|
||||||
|
x2 = x * x;
|
||||||
|
|
||||||
|
t = 0.2371599674224853515625f;
|
||||||
|
t = mlaf(t, x2, 0.285279005765914916992188f);
|
||||||
|
t = mlaf(t, x2, 0.400005519390106201171875f);
|
||||||
|
t = mlaf(t, x2, 0.666666567325592041015625f);
|
||||||
|
t = mlaf(t, x2, 2.0f);
|
||||||
|
|
||||||
|
x = x * t + 0.693147180559945286226764f * e;
|
||||||
|
|
||||||
|
if (xispinff(d)) x = rtengine::RT_INFINITY_F;
|
||||||
|
if (d <= 1.f) x = 0;
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
__inline float xexpf(float d) {
|
__inline float xexpf(float d) {
|
||||||
if(d<=-104.0f) return 0.0f;
|
if(d<=-104.0f) return 0.0f;
|
||||||
|
|
||||||
int q = rint(d * R_LN2f);
|
int q = xrintf(d * R_LN2f);
|
||||||
float s, u;
|
float s, u;
|
||||||
|
|
||||||
s = mlaf(q, -L2Uf, d);
|
s = mlaf(q, -L2Uf, d);
|
||||||
|
@ -1253,6 +1253,30 @@ static INLINE vfloat xlogf(vfloat d) {
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static INLINE vfloat xlogf1(vfloat d) { // does xlogf(vmaxf(d, 1.f)) but faster
|
||||||
|
vfloat x, x2, t, m;
|
||||||
|
vint2 e;
|
||||||
|
|
||||||
|
e = vilogbp1f(vmulf(d, vcast_vf_f(0.7071f)));
|
||||||
|
m = vldexpf(d, vsubi2(vcast_vi2_i(0), e));
|
||||||
|
|
||||||
|
x = vdivf(vaddf(vcast_vf_f(-1.0f), m), vaddf(vcast_vf_f(1.0f), m));
|
||||||
|
x2 = vmulf(x, x);
|
||||||
|
|
||||||
|
t = vcast_vf_f(0.2371599674224853515625f);
|
||||||
|
t = vmlaf(t, x2, vcast_vf_f(0.285279005765914916992188f));
|
||||||
|
t = vmlaf(t, x2, vcast_vf_f(0.400005519390106201171875f));
|
||||||
|
t = vmlaf(t, x2, vcast_vf_f(0.666666567325592041015625f));
|
||||||
|
t = vmlaf(t, x2, vcast_vf_f(2.0f));
|
||||||
|
|
||||||
|
x = vaddf(vmulf(x, t), vmulf(vcast_vf_f(0.693147180559945286226764f), vcast_vf_vi2(e)));
|
||||||
|
|
||||||
|
x = vself(vmaskf_ispinf(d), vcast_vf_f(INFINITYf), x);
|
||||||
|
x = vselfnotzero(vmaskf_le(d, vcast_vf_f(1.f)), x);
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
static INLINE vfloat xlogf0(vfloat d) {
|
static INLINE vfloat xlogf0(vfloat d) {
|
||||||
vfloat x, x2, t, m;
|
vfloat x, x2, t, m;
|
||||||
vint2 e;
|
vint2 e;
|
||||||
|
10
rtgui/epd.cc
10
rtgui/epd.cc
@ -69,12 +69,13 @@ void EdgePreservingDecompositionUI::read(const ProcParams *pp, const ParamsEdite
|
|||||||
|
|
||||||
setEnabled(pp->epd.enabled);
|
setEnabled(pp->epd.enabled);
|
||||||
strength->set_sensitive (true);
|
strength->set_sensitive (true);
|
||||||
|
gamma->set_sensitive (true);
|
||||||
/*
|
/*
|
||||||
if(pp->wavelet.enabled) {
|
if(pp->wavelet.enabled) {
|
||||||
if(pp->wavelet.tmrs == 0) {
|
if(pp->wavelet.tmrs == 0 || pp->wavelet.TMmethod == "cont") {
|
||||||
strength->set_sensitive (true);
|
strength->set_sensitive (true);
|
||||||
gamma->set_sensitive (true);
|
gamma->set_sensitive (true);
|
||||||
} else {
|
} else if(pp->wavelet.tmrs != 0 && pp->wavelet.TMmethod == "tm") {
|
||||||
strength->set_sensitive (false);
|
strength->set_sensitive (false);
|
||||||
gamma->set_sensitive (false);
|
gamma->set_sensitive (false);
|
||||||
}
|
}
|
||||||
@ -98,12 +99,13 @@ void EdgePreservingDecompositionUI::write(ProcParams *pp, ParamsEdited *pedited)
|
|||||||
pp->epd.reweightingIterates = reweightingIterates->getValue();
|
pp->epd.reweightingIterates = reweightingIterates->getValue();
|
||||||
pp->epd.enabled = getEnabled();
|
pp->epd.enabled = getEnabled();
|
||||||
strength->set_sensitive (true);
|
strength->set_sensitive (true);
|
||||||
|
gamma->set_sensitive (true);
|
||||||
/*
|
/*
|
||||||
if(pp->wavelet.enabled) {
|
if(pp->wavelet.enabled) {
|
||||||
if(pp->wavelet.tmrs == 0) {
|
if(pp->wavelet.tmrs == 0 || pp->wavelet.TMmethod == "cont") {
|
||||||
strength->set_sensitive (true);
|
strength->set_sensitive (true);
|
||||||
gamma->set_sensitive (true);
|
gamma->set_sensitive (true);
|
||||||
} else {
|
} else if(pp->wavelet.tmrs != 0 && pp->wavelet.TMmethod == "tm") {
|
||||||
strength->set_sensitive (false);
|
strength->set_sensitive (false);
|
||||||
gamma->set_sensitive (false);
|
gamma->set_sensitive (false);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "filterpanel.h"
|
#include "filterpanel.h"
|
||||||
#include "multilangmgr.h"
|
#include "multilangmgr.h"
|
||||||
@ -107,8 +107,8 @@ FilterPanel::FilterPanel () : listener (nullptr)
|
|||||||
scamera->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
|
scamera->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
|
||||||
scamera->set_size_request(-1, 80);
|
scamera->set_size_request(-1, 80);
|
||||||
scamera->add(*camera);
|
scamera->add(*camera);
|
||||||
cvb->pack_start (*scamera, Gtk::PACK_SHRINK, 0);
|
cvb->pack_start (*scamera, Gtk::PACK_EXPAND_WIDGET, 0);
|
||||||
pack_start (*cvb, Gtk::PACK_SHRINK, 4);
|
pack_start (*cvb, Gtk::PACK_EXPAND_WIDGET, 4);
|
||||||
|
|
||||||
enaLens = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_LENS") + ":"));
|
enaLens = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_LENS") + ":"));
|
||||||
Gtk::VBox* lvb = Gtk::manage(new Gtk::VBox ());
|
Gtk::VBox* lvb = Gtk::manage(new Gtk::VBox ());
|
||||||
@ -119,8 +119,8 @@ FilterPanel::FilterPanel () : listener (nullptr)
|
|||||||
slens->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
|
slens->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
|
||||||
slens->set_size_request(-1, 80);
|
slens->set_size_request(-1, 80);
|
||||||
slens->add(*lens);
|
slens->add(*lens);
|
||||||
lvb->pack_start (*slens, Gtk::PACK_SHRINK, 0);
|
lvb->pack_start (*slens, Gtk::PACK_EXPAND_WIDGET, 0);
|
||||||
pack_start (*lvb, Gtk::PACK_SHRINK, 4);
|
pack_start (*lvb, Gtk::PACK_EXPAND_WIDGET, 4);
|
||||||
|
|
||||||
enaFiletype = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_FILETYPE") + ":"));
|
enaFiletype = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_FILETYPE") + ":"));
|
||||||
Gtk::VBox* ftvb = Gtk::manage(new Gtk::VBox ());
|
Gtk::VBox* ftvb = Gtk::manage(new Gtk::VBox ());
|
||||||
@ -131,8 +131,8 @@ FilterPanel::FilterPanel () : listener (nullptr)
|
|||||||
sfiletype->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
|
sfiletype->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
|
||||||
sfiletype->set_size_request(-1, 80);
|
sfiletype->set_size_request(-1, 80);
|
||||||
sfiletype->add(*filetype);
|
sfiletype->add(*filetype);
|
||||||
ftvb->pack_start (*sfiletype, Gtk::PACK_SHRINK, 0);
|
ftvb->pack_start (*sfiletype, Gtk::PACK_EXPAND_WIDGET, 0);
|
||||||
pack_start (*ftvb, Gtk::PACK_SHRINK, 4);
|
pack_start (*ftvb, Gtk::PACK_EXPAND_WIDGET, 4);
|
||||||
|
|
||||||
// add panel ending
|
// add panel ending
|
||||||
Gtk::VBox* vboxpe = Gtk::manage (new Gtk::VBox ());
|
Gtk::VBox* vboxpe = Gtk::manage (new Gtk::VBox ());
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "lensgeom.h"
|
#include "lensgeom.h"
|
||||||
|
|
||||||
|
#include "eventmapper.h"
|
||||||
#include "guiutils.h"
|
#include "guiutils.h"
|
||||||
#include "rtimage.h"
|
#include "rtimage.h"
|
||||||
|
|
||||||
@ -28,6 +30,18 @@ using namespace rtengine::procparams;
|
|||||||
LensGeometry::LensGeometry () : FoldableToolPanel(this, "lensgeom", M("TP_LENSGEOM_LABEL")), rlistener(nullptr), lastFill(false)
|
LensGeometry::LensGeometry () : FoldableToolPanel(this, "lensgeom", M("TP_LENSGEOM_LABEL")), rlistener(nullptr), lastFill(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
auto m = ProcEventMapper::getInstance();
|
||||||
|
EvTransMethod = m->newEvent(TRANSFORM, "HISTORY_MSG_TRANS_METHOD");
|
||||||
|
|
||||||
|
Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ());
|
||||||
|
hb1->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_RAW_DMETHOD") + ": ")), Gtk::PACK_SHRINK, 4);
|
||||||
|
method = Gtk::manage (new MyComboBoxText ());
|
||||||
|
method->append(M("TP_LENSGEOM_LOG"));
|
||||||
|
method->append(M("TP_LENSGEOM_LIN"));
|
||||||
|
method->set_active(0);
|
||||||
|
hb1->pack_end (*method, Gtk::PACK_EXPAND_WIDGET, 4);
|
||||||
|
pack_start( *hb1, Gtk::PACK_SHRINK, 4);
|
||||||
|
|
||||||
fill = Gtk::manage (new Gtk::CheckButton (M("TP_LENSGEOM_FILL")));
|
fill = Gtk::manage (new Gtk::CheckButton (M("TP_LENSGEOM_FILL")));
|
||||||
pack_start (*fill);
|
pack_start (*fill);
|
||||||
|
|
||||||
@ -39,6 +53,7 @@ LensGeometry::LensGeometry () : FoldableToolPanel(this, "lensgeom", M("TP_LENSGE
|
|||||||
packBox = Gtk::manage (new ToolParamBlock ());
|
packBox = Gtk::manage (new ToolParamBlock ());
|
||||||
pack_start (*packBox);
|
pack_start (*packBox);
|
||||||
|
|
||||||
|
method->connect(method->signal_changed().connect(sigc::mem_fun(*this, &LensGeometry::methodChanged)));
|
||||||
autoCrop->signal_pressed().connect(sigc::mem_fun(*this, &LensGeometry::autoCropPressed));
|
autoCrop->signal_pressed().connect(sigc::mem_fun(*this, &LensGeometry::autoCropPressed));
|
||||||
fillConn = fill->signal_toggled().connect(sigc::mem_fun(*this, &LensGeometry::fillPressed));
|
fillConn = fill->signal_toggled().connect(sigc::mem_fun(*this, &LensGeometry::fillPressed));
|
||||||
|
|
||||||
@ -55,8 +70,14 @@ void LensGeometry::read (const ProcParams* pp, const ParamsEdited* pedited)
|
|||||||
{
|
{
|
||||||
|
|
||||||
disableListener ();
|
disableListener ();
|
||||||
|
method->block (true);
|
||||||
|
method->set_active(pp->commonTrans.method == "log" ? 0 : 1);
|
||||||
|
|
||||||
if (pedited) {
|
if (pedited) {
|
||||||
|
if(!pedited->commonTrans.method) {
|
||||||
|
method->set_active_text(M("GENERAL_UNCHANGED"));
|
||||||
|
}
|
||||||
|
|
||||||
fill->set_inconsistent (!pedited->commonTrans.autofill);
|
fill->set_inconsistent (!pedited->commonTrans.autofill);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,15 +88,20 @@ void LensGeometry::read (const ProcParams* pp, const ParamsEdited* pedited)
|
|||||||
|
|
||||||
lastFill = pp->commonTrans.autofill;
|
lastFill = pp->commonTrans.autofill;
|
||||||
|
|
||||||
|
method->block (false);
|
||||||
enableListener ();
|
enableListener ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LensGeometry::write (ProcParams* pp, ParamsEdited* pedited)
|
void LensGeometry::write (ProcParams* pp, ParamsEdited* pedited)
|
||||||
{
|
{
|
||||||
|
int currentRow = method->get_active_row_number();
|
||||||
|
if( currentRow >= 0 && method->get_active_text() != M("GENERAL_UNCHANGED")) {
|
||||||
|
pp->commonTrans.method = currentRow == 0 ? "log" : "lin";
|
||||||
|
}
|
||||||
pp->commonTrans.autofill = fill->get_active ();
|
pp->commonTrans.autofill = fill->get_active ();
|
||||||
|
|
||||||
if (pedited) {
|
if (pedited) {
|
||||||
|
pedited->commonTrans.method = method->get_active_text() != M("GENERAL_UNCHANGED");
|
||||||
pedited->commonTrans.autofill = !fill->get_inconsistent();
|
pedited->commonTrans.autofill = !fill->get_inconsistent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,6 +141,14 @@ void LensGeometry::fillPressed ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LensGeometry::methodChanged ()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (listener && method->get_active_row_number() >= 0) {
|
||||||
|
listener->panelChanged(EvTransMethod, method->get_active_text());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LensGeometry::setBatchMode (bool batchMode)
|
void LensGeometry::setBatchMode (bool batchMode)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ class LensGeometry final :
|
|||||||
{
|
{
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
MyComboBoxText* method;
|
||||||
Gtk::Button* autoCrop;
|
Gtk::Button* autoCrop;
|
||||||
LensGeomListener* rlistener;
|
LensGeomListener* rlistener;
|
||||||
Gtk::CheckButton* fill;
|
Gtk::CheckButton* fill;
|
||||||
@ -36,6 +37,7 @@ protected:
|
|||||||
sigc::connection fillConn;
|
sigc::connection fillConn;
|
||||||
ToolParamBlock* packBox;
|
ToolParamBlock* packBox;
|
||||||
|
|
||||||
|
rtengine::ProcEvent EvTransMethod;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LensGeometry ();
|
LensGeometry ();
|
||||||
@ -50,6 +52,7 @@ public:
|
|||||||
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override;
|
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = nullptr) override;
|
||||||
void setBatchMode (bool batchMode) override;
|
void setBatchMode (bool batchMode) override;
|
||||||
|
|
||||||
|
void methodChanged();
|
||||||
void fillPressed ();
|
void fillPressed ();
|
||||||
void autoCropPressed ();
|
void autoCropPressed ();
|
||||||
void setLensGeomListener (LensGeomListener* l)
|
void setLensGeomListener (LensGeomListener* l)
|
||||||
|
@ -586,6 +586,9 @@ void LensProfilePanel::onCorrModeChanged(const Gtk::RadioButton* rbChanged)
|
|||||||
|
|
||||||
LensProfilePanel::LFDbHelper::LFDbHelper()
|
LensProfilePanel::LFDbHelper::LFDbHelper()
|
||||||
{
|
{
|
||||||
|
lensfunCameraModel = Gtk::TreeStore::create(lensfunModelCam);
|
||||||
|
lensfunLensModel = Gtk::TreeStore::create(lensfunModelLens);
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel sections if (!settings->verbose)
|
#pragma omp parallel sections if (!settings->verbose)
|
||||||
#endif
|
#endif
|
||||||
@ -594,14 +597,12 @@ LensProfilePanel::LFDbHelper::LFDbHelper()
|
|||||||
#pragma omp section
|
#pragma omp section
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
lensfunCameraModel = Gtk::TreeStore::create(lensfunModelCam);
|
|
||||||
fillLensfunCameras();
|
fillLensfunCameras();
|
||||||
}
|
}
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp section
|
#pragma omp section
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
lensfunLensModel = Gtk::TreeStore::create(lensfunModelLens);
|
|
||||||
fillLensfunLenses();
|
fillLensfunLenses();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -321,6 +321,7 @@ void ParamsEdited::set(bool v)
|
|||||||
coarse.rotate = v;
|
coarse.rotate = v;
|
||||||
coarse.hflip = v;
|
coarse.hflip = v;
|
||||||
coarse.vflip = v;
|
coarse.vflip = v;
|
||||||
|
commonTrans.method = v;
|
||||||
commonTrans.autofill = v;
|
commonTrans.autofill = v;
|
||||||
rotate.degree = v;
|
rotate.degree = v;
|
||||||
distortion.amount = v;
|
distortion.amount = v;
|
||||||
@ -915,6 +916,7 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
|
|||||||
coarse.rotate = coarse.rotate && p.coarse.rotate == other.coarse.rotate;
|
coarse.rotate = coarse.rotate && p.coarse.rotate == other.coarse.rotate;
|
||||||
coarse.hflip = coarse.hflip && p.coarse.hflip == other.coarse.hflip;
|
coarse.hflip = coarse.hflip && p.coarse.hflip == other.coarse.hflip;
|
||||||
coarse.vflip = coarse.vflip && p.coarse.vflip == other.coarse.vflip;
|
coarse.vflip = coarse.vflip && p.coarse.vflip == other.coarse.vflip;
|
||||||
|
commonTrans.method = commonTrans.method && p.commonTrans.method == other.commonTrans.method;
|
||||||
commonTrans.autofill = commonTrans.autofill && p.commonTrans.autofill == other.commonTrans.autofill;
|
commonTrans.autofill = commonTrans.autofill && p.commonTrans.autofill == other.commonTrans.autofill;
|
||||||
rotate.degree = rotate.degree && p.rotate.degree == other.rotate.degree;
|
rotate.degree = rotate.degree && p.rotate.degree == other.rotate.degree;
|
||||||
distortion.amount = distortion.amount && p.distortion.amount == other.distortion.amount;
|
distortion.amount = distortion.amount && p.distortion.amount == other.distortion.amount;
|
||||||
@ -2287,6 +2289,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
|
|||||||
toEdit.coarse.vflip = mods.coarse.vflip;
|
toEdit.coarse.vflip = mods.coarse.vflip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (commonTrans.method) {
|
||||||
|
toEdit.commonTrans.method = mods.commonTrans.method;
|
||||||
|
}
|
||||||
|
|
||||||
if (commonTrans.autofill) {
|
if (commonTrans.autofill) {
|
||||||
toEdit.commonTrans.autofill = mods.commonTrans.autofill;
|
toEdit.commonTrans.autofill = mods.commonTrans.autofill;
|
||||||
}
|
}
|
||||||
|
@ -365,6 +365,7 @@ struct CoarseTransformParamsEdited {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct CommonTransformParamsEdited {
|
struct CommonTransformParamsEdited {
|
||||||
|
bool method;
|
||||||
bool autofill;
|
bool autofill;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user