clean iptransform ipresize ipvibrance
This commit is contained in:
@@ -27,28 +27,29 @@
|
|||||||
# include <iostream>
|
# include <iostream>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
static inline float Lanc(float x, float a)
|
static inline float Lanc (float x, float a)
|
||||||
{
|
{
|
||||||
if (x * x < 1e-6f) {
|
if (x * x < 1e-6f) {
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
} else if (x * x > a * a) {
|
} else if (x * x > a * a) {
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
} else {
|
} else {
|
||||||
x = static_cast<float>(rtengine::RT_PI) * x;
|
x = static_cast<float> (rtengine::RT_PI) * x;
|
||||||
return a * xsinf(x) * xsinf(x / a) / (x * x);
|
return a * xsinf (x) * xsinf (x / a) / (x * x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImProcFunctions::Lanczos(const Image16* src, Image16* dst, float scale)
|
void ImProcFunctions::Lanczos (const Image16* src, Image16* dst, float scale)
|
||||||
{
|
{
|
||||||
|
|
||||||
const float delta = 1.0f / scale;
|
const float delta = 1.0f / scale;
|
||||||
const float a = 3.0f;
|
const float a = 3.0f;
|
||||||
const float sc = min(scale, 1.0f);
|
const float sc = min (scale, 1.0f);
|
||||||
const int support = static_cast<int>(2.0f * a / sc) + 1;
|
const int support = static_cast<int> (2.0f * a / sc) + 1;
|
||||||
|
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
{
|
{
|
||||||
@@ -67,7 +68,7 @@ void ImProcFunctions::Lanczos(const Image16* src, Image16* dst, float scale)
|
|||||||
for (int j = 0; j < dst->getWidth(); j++) {
|
for (int j = 0; j < dst->getWidth(); j++) {
|
||||||
|
|
||||||
// x coord of the center of pixel on src image
|
// x coord of the center of pixel on src image
|
||||||
float x0 = (static_cast<float>(j) + 0.5f) * delta - 0.5f;
|
float x0 = (static_cast<float> (j) + 0.5f) * delta - 0.5f;
|
||||||
|
|
||||||
// weights for interpolation in horisontal direction
|
// weights for interpolation in horisontal direction
|
||||||
float * w = wwh + j * support;
|
float * w = wwh + j * support;
|
||||||
@@ -75,14 +76,14 @@ void ImProcFunctions::Lanczos(const Image16* src, Image16* dst, float scale)
|
|||||||
// sum of weights used for normalization
|
// sum of weights used for normalization
|
||||||
float ws = 0.0f;
|
float ws = 0.0f;
|
||||||
|
|
||||||
jj0[j] = max(0, static_cast<int>(floorf(x0 - a / sc)) + 1);
|
jj0[j] = max (0, static_cast<int> (floorf (x0 - a / sc)) + 1);
|
||||||
jj1[j] = min(src->getWidth(), static_cast<int>(floorf(x0 + a / sc)) + 1);
|
jj1[j] = min (src->getWidth(), static_cast<int> (floorf (x0 + a / sc)) + 1);
|
||||||
|
|
||||||
// calculate weights
|
// calculate weights
|
||||||
for (int jj = jj0[j]; jj < jj1[j]; jj++) {
|
for (int jj = jj0[j]; jj < jj1[j]; jj++) {
|
||||||
int k = jj - jj0[j];
|
int k = jj - jj0[j];
|
||||||
float z = sc * (x0 - static_cast<float>(jj));
|
float z = sc * (x0 - static_cast<float> (jj));
|
||||||
w[k] = Lanc(z, a);
|
w[k] = Lanc (z, a);
|
||||||
ws += w[k];
|
ws += w[k];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +99,7 @@ void ImProcFunctions::Lanczos(const Image16* src, Image16* dst, float scale)
|
|||||||
for (int i = 0; i < dst->getHeight(); i++) {
|
for (int i = 0; i < dst->getHeight(); i++) {
|
||||||
|
|
||||||
// y coord of the center of pixel on src image
|
// y coord of the center of pixel on src image
|
||||||
float y0 = (static_cast<float>(i) + 0.5f) * delta - 0.5f;
|
float y0 = (static_cast<float> (i) + 0.5f) * delta - 0.5f;
|
||||||
|
|
||||||
// weights for interpolation in y direction
|
// weights for interpolation in y direction
|
||||||
float w[support];
|
float w[support];
|
||||||
@@ -106,14 +107,14 @@ void ImProcFunctions::Lanczos(const Image16* src, Image16* dst, float scale)
|
|||||||
// sum of weights used for normalization
|
// sum of weights used for normalization
|
||||||
float ws = 0.0f;
|
float ws = 0.0f;
|
||||||
|
|
||||||
int ii0 = max(0, static_cast<int>(floorf(y0 - a / sc)) + 1);
|
int ii0 = max (0, static_cast<int> (floorf (y0 - a / sc)) + 1);
|
||||||
int ii1 = min(src->getHeight(), static_cast<int>(floorf(y0 + a / sc)) + 1);
|
int ii1 = min (src->getHeight(), static_cast<int> (floorf (y0 + a / sc)) + 1);
|
||||||
|
|
||||||
// calculate weights for vertical interpolation
|
// calculate weights for vertical interpolation
|
||||||
for (int ii = ii0; ii < ii1; ii++) {
|
for (int ii = ii0; ii < ii1; ii++) {
|
||||||
int k = ii - ii0;
|
int k = ii - ii0;
|
||||||
float z = sc * (y0 - static_cast<float>(ii));
|
float z = sc * (y0 - static_cast<float> (ii));
|
||||||
w[k] = Lanc(z, a);
|
w[k] = Lanc (z, a);
|
||||||
ws += w[k];
|
ws += w[k];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,9 +131,9 @@ void ImProcFunctions::Lanczos(const Image16* src, Image16* dst, float scale)
|
|||||||
for (int ii = ii0; ii < ii1; ii++) {
|
for (int ii = ii0; ii < ii1; ii++) {
|
||||||
int k = ii - ii0;
|
int k = ii - ii0;
|
||||||
|
|
||||||
r += w[k] * src->r(ii, j);
|
r += w[k] * src->r (ii, j);
|
||||||
g += w[k] * src->g(ii, j);
|
g += w[k] * src->g (ii, j);
|
||||||
b += w[k] * src->b(ii, j);
|
b += w[k] * src->b (ii, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
lr[j] = r;
|
lr[j] = r;
|
||||||
@@ -141,7 +142,7 @@ void ImProcFunctions::Lanczos(const Image16* src, Image16* dst, float scale)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do horizontal interpolation
|
// Do horizontal interpolation
|
||||||
for(int j = 0; j < dst->getWidth(); j++) {
|
for (int j = 0; j < dst->getWidth(); j++) {
|
||||||
|
|
||||||
float * wh = wwh + support * j;
|
float * wh = wwh + support * j;
|
||||||
|
|
||||||
@@ -155,9 +156,9 @@ void ImProcFunctions::Lanczos(const Image16* src, Image16* dst, float scale)
|
|||||||
b += wh[k] * lb[jj];
|
b += wh[k] * lb[jj];
|
||||||
}
|
}
|
||||||
|
|
||||||
dst->r(i, j) = CLIP(static_cast<int>(r));
|
dst->r (i, j) = CLIP (static_cast<int> (r));
|
||||||
dst->g(i, j) = CLIP(static_cast<int>(g));
|
dst->g (i, j) = CLIP (static_cast<int> (g));
|
||||||
dst->b(i, j) = CLIP(static_cast<int>(b));
|
dst->b (i, j) = CLIP (static_cast<int> (b));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,12 +172,12 @@ void ImProcFunctions::Lanczos(const Image16* src, Image16* dst, float scale)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SSEFUNCTION void ImProcFunctions::Lanczos(const LabImage* src, LabImage* dst, float scale)
|
SSEFUNCTION void ImProcFunctions::Lanczos (const LabImage* src, LabImage* dst, float scale)
|
||||||
{
|
{
|
||||||
const float delta = 1.0f / scale;
|
const float delta = 1.0f / scale;
|
||||||
const float a = 3.0f;
|
const float a = 3.0f;
|
||||||
const float sc = min(scale, 1.0f);
|
const float sc = min (scale, 1.0f);
|
||||||
const int support = static_cast<int>(2.0f * a / sc) + 1;
|
const int support = static_cast<int> (2.0f * a / sc) + 1;
|
||||||
|
|
||||||
// storage for precomputed parameters for horizontal interpolation
|
// storage for precomputed parameters for horizontal interpolation
|
||||||
float * wwh = new float[support * dst->W];
|
float * wwh = new float[support * dst->W];
|
||||||
@@ -187,7 +188,7 @@ SSEFUNCTION void ImProcFunctions::Lanczos(const LabImage* src, LabImage* dst, fl
|
|||||||
for (int j = 0; j < dst->W; j++) {
|
for (int j = 0; j < dst->W; j++) {
|
||||||
|
|
||||||
// x coord of the center of pixel on src image
|
// x coord of the center of pixel on src image
|
||||||
float x0 = (static_cast<float>(j) + 0.5f) * delta - 0.5f;
|
float x0 = (static_cast<float> (j) + 0.5f) * delta - 0.5f;
|
||||||
|
|
||||||
// weights for interpolation in horizontal direction
|
// weights for interpolation in horizontal direction
|
||||||
float * w = wwh + j * support;
|
float * w = wwh + j * support;
|
||||||
@@ -195,14 +196,14 @@ SSEFUNCTION void ImProcFunctions::Lanczos(const LabImage* src, LabImage* dst, fl
|
|||||||
// sum of weights used for normalization
|
// sum of weights used for normalization
|
||||||
float ws = 0.0f;
|
float ws = 0.0f;
|
||||||
|
|
||||||
jj0[j] = max(0, static_cast<int>(floorf(x0 - a / sc)) + 1);
|
jj0[j] = max (0, static_cast<int> (floorf (x0 - a / sc)) + 1);
|
||||||
jj1[j] = min(src->W, static_cast<int>(floorf(x0 + a / sc)) + 1);
|
jj1[j] = min (src->W, static_cast<int> (floorf (x0 + a / sc)) + 1);
|
||||||
|
|
||||||
// calculate weights
|
// calculate weights
|
||||||
for (int jj = jj0[j]; jj < jj1[j]; jj++) {
|
for (int jj = jj0[j]; jj < jj1[j]; jj++) {
|
||||||
int k = jj - jj0[j];
|
int k = jj - jj0[j];
|
||||||
float z = sc * (x0 - static_cast<float>(jj));
|
float z = sc * (x0 - static_cast<float> (jj));
|
||||||
w[k] = Lanc(z, a);
|
w[k] = Lanc (z, a);
|
||||||
ws += w[k];
|
ws += w[k];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,19 +231,19 @@ SSEFUNCTION void ImProcFunctions::Lanczos(const LabImage* src, LabImage* dst, fl
|
|||||||
|
|
||||||
for (int i = 0; i < dst->H; i++) {
|
for (int i = 0; i < dst->H; i++) {
|
||||||
// y coord of the center of pixel on src image
|
// y coord of the center of pixel on src image
|
||||||
float y0 = (static_cast<float>(i) + 0.5f) * delta - 0.5f;
|
float y0 = (static_cast<float> (i) + 0.5f) * delta - 0.5f;
|
||||||
|
|
||||||
// sum of weights used for normalization
|
// sum of weights used for normalization
|
||||||
float ws = 0.0f;
|
float ws = 0.0f;
|
||||||
|
|
||||||
int ii0 = max(0, static_cast<int>(floorf(y0 - a / sc)) + 1);
|
int ii0 = max (0, static_cast<int> (floorf (y0 - a / sc)) + 1);
|
||||||
int ii1 = min(src->H, static_cast<int>(floorf(y0 + a / sc)) + 1);
|
int ii1 = min (src->H, static_cast<int> (floorf (y0 + a / sc)) + 1);
|
||||||
|
|
||||||
// calculate weights for vertical interpolation
|
// calculate weights for vertical interpolation
|
||||||
for (int ii = ii0; ii < ii1; ii++) {
|
for (int ii = ii0; ii < ii1; ii++) {
|
||||||
int k = ii - ii0;
|
int k = ii - ii0;
|
||||||
float z = sc * (y0 - static_cast<float>(ii));
|
float z = sc * (y0 - static_cast<float> (ii));
|
||||||
w[k] = Lanc(z, a);
|
w[k] = Lanc (z, a);
|
||||||
ws += w[k];
|
ws += w[k];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,15 +264,15 @@ SSEFUNCTION void ImProcFunctions::Lanczos(const LabImage* src, LabImage* dst, fl
|
|||||||
|
|
||||||
for (int ii = ii0; ii < ii1; ii++) {
|
for (int ii = ii0; ii < ii1; ii++) {
|
||||||
int k = ii - ii0;
|
int k = ii - ii0;
|
||||||
wkv = _mm_set1_ps(w[k]);
|
wkv = _mm_set1_ps (w[k]);
|
||||||
Lv += wkv * LVFU(src->L[ii][j]);
|
Lv += wkv * LVFU (src->L[ii][j]);
|
||||||
av += wkv * LVFU(src->a[ii][j]);
|
av += wkv * LVFU (src->a[ii][j]);
|
||||||
bv += wkv * LVFU(src->b[ii][j]);
|
bv += wkv * LVFU (src->b[ii][j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
STVF(lL[j], Lv);
|
STVF (lL[j], Lv);
|
||||||
STVF(la[j], av);
|
STVF (la[j], av);
|
||||||
STVF(lb[j], bv);
|
STVF (lb[j], bv);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@@ -295,7 +296,7 @@ SSEFUNCTION void ImProcFunctions::Lanczos(const LabImage* src, LabImage* dst, fl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do horizontal interpolation
|
// Do horizontal interpolation
|
||||||
for(int j = 0; j < dst->W; j++) {
|
for (int j = 0; j < dst->W; j++) {
|
||||||
|
|
||||||
float * wh = wwh + support * j;
|
float * wh = wwh + support * j;
|
||||||
|
|
||||||
@@ -348,35 +349,35 @@ float ImProcFunctions::resizeScale (const ProcParams* params, int fw, int fh, in
|
|||||||
refh = fh;
|
refh = fh;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(params->resize.dataspec) {
|
switch (params->resize.dataspec) {
|
||||||
case (1):
|
case (1):
|
||||||
// Width
|
// Width
|
||||||
dScale = (double)params->resize.width / (double)refw;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (2):
|
|
||||||
// Height
|
|
||||||
dScale = (double)params->resize.height / (double)refh;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (3):
|
|
||||||
|
|
||||||
// FitBox
|
|
||||||
if ((double)refw / (double)refh > (double)params->resize.width / (double)params->resize.height) {
|
|
||||||
dScale = (double)params->resize.width / (double)refw;
|
dScale = (double)params->resize.width / (double)refw;
|
||||||
} else {
|
break;
|
||||||
|
|
||||||
|
case (2):
|
||||||
|
// Height
|
||||||
dScale = (double)params->resize.height / (double)refh;
|
dScale = (double)params->resize.height / (double)refh;
|
||||||
}
|
break;
|
||||||
|
|
||||||
break;
|
case (3):
|
||||||
|
|
||||||
default:
|
// FitBox
|
||||||
// Scale
|
if ((double)refw / (double)refh > (double)params->resize.width / (double)params->resize.height) {
|
||||||
dScale = params->resize.scale;
|
dScale = (double)params->resize.width / (double)refw;
|
||||||
break;
|
} else {
|
||||||
|
dScale = (double)params->resize.height / (double)refh;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Scale
|
||||||
|
dScale = params->resize.scale;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fabs(dScale - 1.0) <= 1e-5) {
|
if (fabs (dScale - 1.0) <= 1e-5) {
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,8 +389,8 @@ float ImProcFunctions::resizeScale (const ProcParams* params, int fw, int fh, in
|
|||||||
imh = refh;
|
imh = refh;
|
||||||
}
|
}
|
||||||
|
|
||||||
imw = (int)( (double)imw * dScale + 0.5 );
|
imw = (int) ( (double)imw * dScale + 0.5 );
|
||||||
imh = (int)( (double)imh * dScale + 0.5 );
|
imh = (int) ( (double)imh * dScale + 0.5 );
|
||||||
return (float)dScale;
|
return (float)dScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,8 +400,8 @@ void ImProcFunctions::resize (Image16* src, Image16* dst, float dScale)
|
|||||||
time_t t1 = clock();
|
time_t t1 = clock();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(params->resize.method != "Nearest" ) {
|
if (params->resize.method != "Nearest" ) {
|
||||||
Lanczos(src, dst, dScale);
|
Lanczos (src, dst, dScale);
|
||||||
} else {
|
} else {
|
||||||
// Nearest neighbour algorithm
|
// Nearest neighbour algorithm
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
@@ -409,14 +410,14 @@ void ImProcFunctions::resize (Image16* src, Image16* dst, float dScale)
|
|||||||
|
|
||||||
for (int i = 0; i < dst->getHeight(); i++) {
|
for (int i = 0; i < dst->getHeight(); i++) {
|
||||||
int sy = i / dScale;
|
int sy = i / dScale;
|
||||||
sy = LIM(sy, 0, src->getHeight() - 1);
|
sy = LIM (sy, 0, src->getHeight() - 1);
|
||||||
|
|
||||||
for (int j = 0; j < dst->getWidth(); j++) {
|
for (int j = 0; j < dst->getWidth(); j++) {
|
||||||
int sx = j / dScale;
|
int sx = j / dScale;
|
||||||
sx = LIM(sx, 0, src->getWidth() - 1);
|
sx = LIM (sx, 0, src->getWidth() - 1);
|
||||||
dst->r(i, j) = src->r(sy, sx);
|
dst->r (i, j) = src->r (sy, sx);
|
||||||
dst->g(i, j) = src->g(sy, sx);
|
dst->g (i, j) = src->g (sy, sx);
|
||||||
dst->b(i, j) = src->b(sy, sx);
|
dst->b (i, j) = src->b (sy, sx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -424,7 +425,7 @@ void ImProcFunctions::resize (Image16* src, Image16* dst, float dScale)
|
|||||||
#ifdef PROFILE
|
#ifdef PROFILE
|
||||||
time_t t2 = clock();
|
time_t t2 = clock();
|
||||||
std::cout << "Resize: " << params->resize.method << ": "
|
std::cout << "Resize: " << params->resize.method << ": "
|
||||||
<< (float)(t2 - t1) / CLOCKS_PER_SEC << std::endl;
|
<< (float) (t2 - t1) / CLOCKS_PER_SEC << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,22 +25,23 @@
|
|||||||
#include "rt_math.h"
|
#include "rt_math.h"
|
||||||
#include "sleef.c"
|
#include "sleef.c"
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
float pow3(float x)
|
float pow3 (float x)
|
||||||
{
|
{
|
||||||
return x * x * x;
|
return x * x * x;
|
||||||
}
|
}
|
||||||
|
|
||||||
float pow4(float x)
|
float pow4 (float x)
|
||||||
{
|
{
|
||||||
return (x * x) * (x * x);
|
return (x * x) * (x * x);
|
||||||
}
|
}
|
||||||
|
|
||||||
float pown(float x, int n)
|
float pown (float x, int n)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch (n) {
|
switch (n) {
|
||||||
@@ -51,47 +52,47 @@ float pown(float x, int n)
|
|||||||
return x * x;
|
return x * x;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
return pow4(x);
|
return pow4 (x);
|
||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
return (x * x) * pow4(x);
|
return (x * x) * pow4 (x);
|
||||||
|
|
||||||
case 8:
|
case 8:
|
||||||
return pow4(x) * pow4(x);
|
return pow4 (x) * pow4 (x);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return pow_F(x, n);
|
return pow_F (x, n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float normn(float a, float b, int n)
|
float normn (float a, float b, int n)
|
||||||
{
|
{
|
||||||
switch (n) {
|
switch (n) {
|
||||||
case 2:
|
case 2:
|
||||||
return sqrtf(a * a + b * b);
|
return sqrtf (a * a + b * b);
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
return sqrtf(sqrtf(pow4(a) + pow4(b)));
|
return sqrtf (sqrtf (pow4 (a) + pow4 (b)));
|
||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
return sqrtf(xcbrtf(pow3(a) * pow3(a) + pow3(b) * pow3(b)));
|
return sqrtf (xcbrtf (pow3 (a) * pow3 (a) + pow3 (b) * pow3 (b)));
|
||||||
|
|
||||||
case 8:
|
case 8:
|
||||||
return sqrtf(sqrtf(sqrtf(pow4(a) * pow4(a) + pow4(b) * pow4(b))));
|
return sqrtf (sqrtf (sqrtf (pow4 (a) * pow4 (a) + pow4 (b) * pow4 (b))));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return pow_F(pown(a, n) + pown(b, n), 1.f / n);
|
return pow_F (pown (a, n) + pown (b, n), 1.f / n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void correct_distortion(const rtengine::LCPMapper *lcp, double &x, double &y,
|
void correct_distortion (const rtengine::LCPMapper *lcp, double &x, double &y,
|
||||||
int cx, int cy)
|
int cx, int cy)
|
||||||
{
|
{
|
||||||
assert(lcp);
|
assert (lcp);
|
||||||
|
|
||||||
x += cx;
|
x += cx;
|
||||||
y += cy;
|
y += cy;
|
||||||
lcp->correctDistortion(x, y);
|
lcp->correctDistortion (x, y);
|
||||||
x -= cx;
|
x -= cx;
|
||||||
y -= cy;
|
y -= cy;
|
||||||
}
|
}
|
||||||
@@ -127,26 +128,26 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector<Coord2D> &src,
|
|||||||
double oW = W, oH = H;
|
double oW = W, oH = H;
|
||||||
double w2 = (double) oW / 2.0 - 0.5;
|
double w2 = (double) oW / 2.0 - 0.5;
|
||||||
double h2 = (double) oH / 2.0 - 0.5;
|
double h2 = (double) oH / 2.0 - 0.5;
|
||||||
double maxRadius = sqrt( (double)( oW * oW + oH * oH ) ) / 2;
|
double maxRadius = sqrt ( (double) ( oW * oW + oH * oH ) ) / 2;
|
||||||
|
|
||||||
// auxiliary variables for distortion correction
|
// auxiliary variables for distortion correction
|
||||||
bool needsDist = needsDistortion(); // for performance
|
bool needsDist = needsDistortion(); // for performance
|
||||||
double distAmount = params->distortion.amount;
|
double distAmount = params->distortion.amount;
|
||||||
|
|
||||||
// auxiliary variables for rotation
|
// auxiliary variables for rotation
|
||||||
double cost = cos(params->rotate.degree * rtengine::RT_PI / 180.0);
|
double cost = cos (params->rotate.degree * rtengine::RT_PI / 180.0);
|
||||||
double sint = sin(params->rotate.degree * rtengine::RT_PI / 180.0);
|
double sint = sin (params->rotate.degree * rtengine::RT_PI / 180.0);
|
||||||
|
|
||||||
// auxiliary variables for vertical perspective correction
|
// auxiliary variables for vertical perspective correction
|
||||||
double vpdeg = params->perspective.vertical / 100.0 * 45.0;
|
double vpdeg = params->perspective.vertical / 100.0 * 45.0;
|
||||||
double vpalpha = (90.0 - vpdeg) / 180.0 * rtengine::RT_PI;
|
double vpalpha = (90.0 - vpdeg) / 180.0 * rtengine::RT_PI;
|
||||||
double vpteta = fabs(vpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((vpdeg > 0 ? 1.0 : -1.0) * sqrt((-oW * oW * tan(vpalpha) * tan(vpalpha) + (vpdeg > 0 ? 1.0 : -1.0) * oW * tan(vpalpha) * sqrt(16 * maxRadius * maxRadius + oW * oW * tan(vpalpha) * tan(vpalpha))) / (maxRadius * maxRadius * 8)));
|
double vpteta = fabs (vpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((vpdeg > 0 ? 1.0 : -1.0) * sqrt ((-oW * oW * tan (vpalpha) * tan (vpalpha) + (vpdeg > 0 ? 1.0 : -1.0) * oW * tan (vpalpha) * sqrt (16 * maxRadius * maxRadius + oW * oW * tan (vpalpha) * tan (vpalpha))) / (maxRadius * maxRadius * 8)));
|
||||||
double vpcospt = (vpdeg >= 0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta);
|
double vpcospt = (vpdeg >= 0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta);
|
||||||
|
|
||||||
// auxiliary variables for horizontal perspective correction
|
// auxiliary variables for horizontal perspective correction
|
||||||
double hpdeg = params->perspective.horizontal / 100.0 * 45.0;
|
double hpdeg = params->perspective.horizontal / 100.0 * 45.0;
|
||||||
double hpalpha = (90.0 - hpdeg) / 180.0 * rtengine::RT_PI;
|
double hpalpha = (90.0 - hpdeg) / 180.0 * rtengine::RT_PI;
|
||||||
double hpteta = fabs(hpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((hpdeg > 0 ? 1.0 : -1.0) * sqrt((-oH * oH * tan(hpalpha) * tan(hpalpha) + (hpdeg > 0 ? 1.0 : -1.0) * oH * tan(hpalpha) * sqrt(16 * maxRadius * maxRadius + oH * oH * tan(hpalpha) * tan(hpalpha))) / (maxRadius * maxRadius * 8)));
|
double hpteta = fabs (hpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((hpdeg > 0 ? 1.0 : -1.0) * sqrt ((-oH * oH * tan (hpalpha) * tan (hpalpha) + (hpdeg > 0 ? 1.0 : -1.0) * oH * tan (hpalpha) * sqrt (16 * maxRadius * maxRadius + oH * oH * tan (hpalpha) * tan (hpalpha))) / (maxRadius * maxRadius * 8)));
|
||||||
double hpcospt = (hpdeg >= 0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta);
|
double hpcospt = (hpdeg >= 0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta);
|
||||||
|
|
||||||
double ascale = ascaleDef > 0 ? ascaleDef : (params->commonTrans.autofill ? getTransformAutoFill (oW, oH, pLCPMap) : 1.0);
|
double ascale = ascaleDef > 0 ? ascaleDef : (params->commonTrans.autofill ? getTransformAutoFill (oW, oH, pLCPMap) : 1.0);
|
||||||
@@ -155,7 +156,7 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector<Coord2D> &src,
|
|||||||
double x_d = src[i].x, y_d = src[i].y;
|
double x_d = src[i].x, y_d = src[i].y;
|
||||||
|
|
||||||
if (pLCPMap && params->lensProf.useDist) {
|
if (pLCPMap && params->lensProf.useDist) {
|
||||||
correct_distortion(pLCPMap, x_d, y_d, 0, 0);
|
correct_distortion (pLCPMap, x_d, y_d, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
y_d = ascale * (y_d - h2);
|
y_d = ascale * (y_d - h2);
|
||||||
@@ -179,25 +180,25 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector<Coord2D> &src,
|
|||||||
double s = 1;
|
double s = 1;
|
||||||
|
|
||||||
if (needsDist) {
|
if (needsDist) {
|
||||||
double r = sqrt(Dx * Dx + Dy * Dy) / maxRadius; // sqrt is slow
|
double r = sqrt (Dx * Dx + Dy * Dy) / maxRadius; // sqrt is slow
|
||||||
s = 1.0 - distAmount + distAmount * r ;
|
s = 1.0 - distAmount + distAmount * r ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// LCP CA is not reflected in preview (and very small), so don't add it here
|
// LCP CA is not reflected in preview (and very small), so don't add it here
|
||||||
|
|
||||||
red.push_back (Coord2D(Dx * (s + params->cacorrection.red) + w2, Dy * (s + params->cacorrection.red) + h2));
|
red.push_back (Coord2D (Dx * (s + params->cacorrection.red) + w2, Dy * (s + params->cacorrection.red) + h2));
|
||||||
green.push_back (Coord2D(Dx * s + w2, Dy * s + h2));
|
green.push_back (Coord2D (Dx * s + w2, Dy * s + h2));
|
||||||
blue.push_back (Coord2D(Dx * (s + params->cacorrection.blue) + w2, Dy * (s + params->cacorrection.blue) + h2));
|
blue.push_back (Coord2D (Dx * (s + params->cacorrection.blue) + w2, Dy * (s + params->cacorrection.blue) + h2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clip all points and track if they were any corrections
|
// Clip all points and track if they were any corrections
|
||||||
for (size_t i = 0; i < src.size(); i++) {
|
for (size_t i = 0; i < src.size(); i++) {
|
||||||
red[i].x = CLIPTOC(red[i].x, 0, W - 1, clipped);
|
red[i].x = CLIPTOC (red[i].x, 0, W - 1, clipped);
|
||||||
red[i].y = CLIPTOC(red[i].y, 0, H - 1, clipped);
|
red[i].y = CLIPTOC (red[i].y, 0, H - 1, clipped);
|
||||||
green[i].x = CLIPTOC(green[i].x, 0, W - 1, clipped);
|
green[i].x = CLIPTOC (green[i].x, 0, W - 1, clipped);
|
||||||
green[i].y = CLIPTOC(green[i].y, 0, H - 1, clipped);
|
green[i].y = CLIPTOC (green[i].y, 0, H - 1, clipped);
|
||||||
blue[i].x = CLIPTOC(blue[i].x, 0, W - 1, clipped);
|
blue[i].x = CLIPTOC (blue[i].x, 0, W - 1, clipped);
|
||||||
blue[i].y = CLIPTOC(blue[i].y, 0, H - 1, clipped);
|
blue[i].y = CLIPTOC (blue[i].y, 0, H - 1, clipped);
|
||||||
}
|
}
|
||||||
|
|
||||||
return clipped;
|
return clipped;
|
||||||
@@ -264,7 +265,7 @@ bool ImProcFunctions::transCoord (int W, int H, int x, int y, int w, int h, int&
|
|||||||
x1d = transCorners[i].x;
|
x1d = transCorners[i].x;
|
||||||
}
|
}
|
||||||
|
|
||||||
int x1v = (int)(x1d);
|
int x1v = (int) (x1d);
|
||||||
|
|
||||||
double y1d = transCorners[0].y;
|
double y1d = transCorners[0].y;
|
||||||
|
|
||||||
@@ -273,7 +274,7 @@ bool ImProcFunctions::transCoord (int W, int H, int x, int y, int w, int h, int&
|
|||||||
y1d = transCorners[i].y;
|
y1d = transCorners[i].y;
|
||||||
}
|
}
|
||||||
|
|
||||||
int y1v = (int)(y1d);
|
int y1v = (int) (y1d);
|
||||||
|
|
||||||
double x2d = transCorners[0].x;
|
double x2d = transCorners[0].x;
|
||||||
|
|
||||||
@@ -282,7 +283,7 @@ bool ImProcFunctions::transCoord (int W, int H, int x, int y, int w, int h, int&
|
|||||||
x2d = transCorners[i].x;
|
x2d = transCorners[i].x;
|
||||||
}
|
}
|
||||||
|
|
||||||
int x2v = (int)ceil(x2d);
|
int x2v = (int)ceil (x2d);
|
||||||
|
|
||||||
double y2d = transCorners[0].y;
|
double y2d = transCorners[0].y;
|
||||||
|
|
||||||
@@ -291,7 +292,7 @@ bool ImProcFunctions::transCoord (int W, int H, int x, int y, int w, int h, int&
|
|||||||
y2d = transCorners[i].y;
|
y2d = transCorners[i].y;
|
||||||
}
|
}
|
||||||
|
|
||||||
int y2v = (int)ceil(y2d);
|
int y2v = (int)ceil (y2d);
|
||||||
|
|
||||||
xv = x1v;
|
xv = x1v;
|
||||||
yv = y1v;
|
yv = y1v;
|
||||||
@@ -308,17 +309,17 @@ void ImProcFunctions::transform (Imagefloat* original, Imagefloat* transformed,
|
|||||||
LCPMapper *pLCPMap = nullptr;
|
LCPMapper *pLCPMap = nullptr;
|
||||||
|
|
||||||
if (needsLCP()) { // don't check focal length to allow distortion correction for lenses without chip
|
if (needsLCP()) { // don't check focal length to allow distortion correction for lenses without chip
|
||||||
LCPProfile *pLCPProf = lcpStore->getProfile(params->lensProf.lcpFile);
|
LCPProfile *pLCPProf = lcpStore->getProfile (params->lensProf.lcpFile);
|
||||||
|
|
||||||
if (pLCPProf) {
|
if (pLCPProf) {
|
||||||
pLCPMap = new LCPMapper(pLCPProf, focalLen, focalLen35mm,
|
pLCPMap = new LCPMapper (pLCPProf, focalLen, focalLen35mm,
|
||||||
focusDist, 0, false,
|
focusDist, 0, false,
|
||||||
params->lensProf.useDist,
|
params->lensProf.useDist,
|
||||||
oW, oH, params->coarse, rawRotationDeg);
|
oW, oH, params->coarse, rawRotationDeg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(needsCA() || needsDistortion() || needsRotation() || needsPerspective() || needsLCP()) && (needsVignetting() || needsPCVignetting() || needsGradient())) {
|
if (! (needsCA() || needsDistortion() || needsRotation() || needsPerspective() || needsLCP()) && (needsVignetting() || needsPCVignetting() || needsGradient())) {
|
||||||
transformLuminanceOnly (original, transformed, cx, cy, oW, oH, fW, fH);
|
transformLuminanceOnly (original, transformed, cx, cy, oW, oH, fW, fH);
|
||||||
} else if (!needsCA() && scale != 1) {
|
} else if (!needsCA() && scale != 1) {
|
||||||
transformPreview (original, transformed, cx, cy, sx, sy, oW, oH, fW, fH, pLCPMap);
|
transformPreview (original, transformed, cx, cy, sx, sy, oW, oH, fW, fH, pLCPMap);
|
||||||
@@ -332,7 +333,7 @@ void ImProcFunctions::transform (Imagefloat* original, Imagefloat* transformed,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// helper function
|
// helper function
|
||||||
void ImProcFunctions::calcVignettingParams(int oW, int oH, const VignettingParams& vignetting, double &w2, double &h2, double& maxRadius, double &v, double &b, double &mul)
|
void ImProcFunctions::calcVignettingParams (int oW, int oH, const VignettingParams& vignetting, double &w2, double &h2, double& maxRadius, double &v, double &b, double &mul)
|
||||||
{
|
{
|
||||||
// vignette center is a point with coordinates between -1 and +1
|
// vignette center is a point with coordinates between -1 and +1
|
||||||
double x = vignetting.centerX / 100.0;
|
double x = vignetting.centerX / 100.0;
|
||||||
@@ -343,12 +344,12 @@ void ImProcFunctions::calcVignettingParams(int oW, int oH, const VignettingParam
|
|||||||
h2 = (double) oH / 2.0 - 0.5 + y * oH;
|
h2 = (double) oH / 2.0 - 0.5 + y * oH;
|
||||||
|
|
||||||
// max vignette radius in pixels
|
// max vignette radius in pixels
|
||||||
maxRadius = sqrt( (double)( oW * oW + oH * oH ) ) / 2.;
|
maxRadius = sqrt ( (double) ( oW * oW + oH * oH ) ) / 2.;
|
||||||
|
|
||||||
// vignette variables with applied strength
|
// vignette variables with applied strength
|
||||||
v = 1.0 + vignetting.strength * fabs(vignetting.amount) * 3.0 / 400.0;
|
v = 1.0 + vignetting.strength * fabs (vignetting.amount) * 3.0 / 400.0;
|
||||||
b = 1.0 + vignetting.radius * 7.0 / 100.0;
|
b = 1.0 + vignetting.radius * 7.0 / 100.0;
|
||||||
mul = (1.0 - v) / tanh(b);
|
mul = (1.0 - v) / tanh (b);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct grad_params {
|
struct grad_params {
|
||||||
@@ -359,7 +360,7 @@ struct grad_params {
|
|||||||
float top_edge_0;
|
float top_edge_0;
|
||||||
int h;
|
int h;
|
||||||
};
|
};
|
||||||
static void calcGradientParams(int oW, int oH, const GradientParams& gradient, struct grad_params& gp)
|
static void calcGradientParams (int oW, int oH, const GradientParams& gradient, struct grad_params& gp)
|
||||||
{
|
{
|
||||||
int w = oW;
|
int w = oW;
|
||||||
int h = oH;
|
int h = oH;
|
||||||
@@ -371,7 +372,7 @@ static void calcGradientParams(int oW, int oH, const GradientParams& gradient, s
|
|||||||
//fprintf(stderr, "%f %f %f %f %f %d %d\n", gradient_stops, gradient_span, gradient_center_x, gradient_center_y, gradient_angle, w, h);
|
//fprintf(stderr, "%f %f %f %f %f %d %d\n", gradient_stops, gradient_span, gradient_center_x, gradient_center_y, gradient_angle, w, h);
|
||||||
|
|
||||||
// make 0.0 <= gradient_angle < 2 * rtengine::RT_PI
|
// make 0.0 <= gradient_angle < 2 * rtengine::RT_PI
|
||||||
gradient_angle = fmod(gradient_angle, 2 * rtengine::RT_PI);
|
gradient_angle = fmod (gradient_angle, 2 * rtengine::RT_PI);
|
||||||
|
|
||||||
if (gradient_angle < 0.0) {
|
if (gradient_angle < 0.0) {
|
||||||
gradient_angle += 2.0 * rtengine::RT_PI;
|
gradient_angle += 2.0 * rtengine::RT_PI;
|
||||||
@@ -381,21 +382,21 @@ static void calcGradientParams(int oW, int oH, const GradientParams& gradient, s
|
|||||||
gp.transpose = false;
|
gp.transpose = false;
|
||||||
gp.angle_is_zero = false;
|
gp.angle_is_zero = false;
|
||||||
gp.h = h;
|
gp.h = h;
|
||||||
double cosgrad = cos(gradient_angle);
|
double cosgrad = cos (gradient_angle);
|
||||||
|
|
||||||
if (fabs(cosgrad) < 0.707) {
|
if (fabs (cosgrad) < 0.707) {
|
||||||
// we transpose to avoid division by zero at 90 degrees
|
// we transpose to avoid division by zero at 90 degrees
|
||||||
// (actually we could transpose only for 90 degrees, but this way we avoid
|
// (actually we could transpose only for 90 degrees, but this way we avoid
|
||||||
// division with extremely small numbers
|
// division with extremely small numbers
|
||||||
gp.transpose = true;
|
gp.transpose = true;
|
||||||
gradient_angle += 0.5 * rtengine::RT_PI;
|
gradient_angle += 0.5 * rtengine::RT_PI;
|
||||||
cosgrad = cos(gradient_angle);
|
cosgrad = cos (gradient_angle);
|
||||||
double gxc = gradient_center_x;
|
double gxc = gradient_center_x;
|
||||||
gradient_center_x = 1.0 - gradient_center_y;
|
gradient_center_x = 1.0 - gradient_center_y;
|
||||||
gradient_center_y = gxc;
|
gradient_center_y = gxc;
|
||||||
}
|
}
|
||||||
|
|
||||||
gradient_angle = fmod(gradient_angle, 2 * rtengine::RT_PI);
|
gradient_angle = fmod (gradient_angle, 2 * rtengine::RT_PI);
|
||||||
|
|
||||||
if (gradient_angle > 0.5 * rtengine::RT_PI && gradient_angle < rtengine::RT_PI) {
|
if (gradient_angle > 0.5 * rtengine::RT_PI && gradient_angle < rtengine::RT_PI) {
|
||||||
gradient_angle += rtengine::RT_PI;
|
gradient_angle += rtengine::RT_PI;
|
||||||
@@ -405,7 +406,7 @@ static void calcGradientParams(int oW, int oH, const GradientParams& gradient, s
|
|||||||
gp.bright_top = true;
|
gp.bright_top = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fabs(gradient_angle) < 0.001 || fabs(gradient_angle - 2 * rtengine::RT_PI) < 0.001) {
|
if (fabs (gradient_angle) < 0.001 || fabs (gradient_angle - 2 * rtengine::RT_PI) < 0.001) {
|
||||||
gradient_angle = 0;
|
gradient_angle = 0;
|
||||||
gp.angle_is_zero = true;
|
gp.angle_is_zero = true;
|
||||||
}
|
}
|
||||||
@@ -420,7 +421,7 @@ static void calcGradientParams(int oW, int oH, const GradientParams& gradient, s
|
|||||||
h = tmp;
|
h = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
gp.scale = 1.0 / pow(2, gradient_stops);
|
gp.scale = 1.0 / pow (2, gradient_stops);
|
||||||
|
|
||||||
if (gp.bright_top) {
|
if (gp.bright_top) {
|
||||||
gp.topmul = 1.0;
|
gp.topmul = 1.0;
|
||||||
@@ -430,10 +431,10 @@ static void calcGradientParams(int oW, int oH, const GradientParams& gradient, s
|
|||||||
gp.botmul = 1.0;
|
gp.botmul = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
gp.ta = tan(gradient_angle);
|
gp.ta = tan (gradient_angle);
|
||||||
gp.xc = w * gradient_center_x;
|
gp.xc = w * gradient_center_x;
|
||||||
gp.yc = h * gradient_center_y;
|
gp.yc = h * gradient_center_y;
|
||||||
gp.ys = sqrt((float)h * h + (float)w * w) * (gradient_span / cos(gradient_angle));
|
gp.ys = sqrt ((float)h * h + (float)w * w) * (gradient_span / cos (gradient_angle));
|
||||||
gp.ys_inv = 1.0 / gp.ys;
|
gp.ys_inv = 1.0 / gp.ys;
|
||||||
gp.top_edge_0 = gp.yc - gp.ys / 2.0;
|
gp.top_edge_0 = gp.yc - gp.ys / 2.0;
|
||||||
|
|
||||||
@@ -443,18 +444,17 @@ static void calcGradientParams(int oW, int oH, const GradientParams& gradient, s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static float calcGradientFactor(const struct grad_params& gp, int x, int y)
|
static float calcGradientFactor (const struct grad_params& gp, int x, int y)
|
||||||
{
|
{
|
||||||
if (gp.angle_is_zero) {
|
if (gp.angle_is_zero) {
|
||||||
int gy = gp.transpose ? x : y;
|
int gy = gp.transpose ? x : y;
|
||||||
int gx = gp.transpose ? y : x;
|
|
||||||
|
|
||||||
if (gy < gp.top_edge_0) {
|
if (gy < gp.top_edge_0) {
|
||||||
return gp.topmul;
|
return gp.topmul;
|
||||||
} else if (gy >= gp.top_edge_0 + gp.ys) {
|
} else if (gy >= gp.top_edge_0 + gp.ys) {
|
||||||
return gp.botmul;
|
return gp.botmul;
|
||||||
} else {
|
} else {
|
||||||
float val = ((float)(gy - gp.top_edge_0) * gp.ys_inv);
|
float val = ((float) (gy - gp.top_edge_0) * gp.ys_inv);
|
||||||
|
|
||||||
if (gp.bright_top) {
|
if (gp.bright_top) {
|
||||||
val = 1.f - val;
|
val = 1.f - val;
|
||||||
@@ -463,9 +463,9 @@ static float calcGradientFactor(const struct grad_params& gp, int x, int y)
|
|||||||
val *= rtengine::RT_PI_F_2;
|
val *= rtengine::RT_PI_F_2;
|
||||||
|
|
||||||
if (gp.scale < 1.f) {
|
if (gp.scale < 1.f) {
|
||||||
val = pow3(xsinf(val));
|
val = pow3 (xsinf (val));
|
||||||
} else {
|
} else {
|
||||||
val = 1.f - pow3(xcosf(val));
|
val = 1.f - pow3 (xcosf (val));
|
||||||
}
|
}
|
||||||
|
|
||||||
return gp.scale + val * (1.0 - gp.scale);
|
return gp.scale + val * (1.0 - gp.scale);
|
||||||
@@ -480,16 +480,16 @@ static float calcGradientFactor(const struct grad_params& gp, int x, int y)
|
|||||||
} else if (gy >= top_edge + gp.ys) {
|
} else if (gy >= top_edge + gp.ys) {
|
||||||
return gp.botmul;
|
return gp.botmul;
|
||||||
} else {
|
} else {
|
||||||
float val = ((float)(gy - top_edge) * gp.ys_inv);
|
float val = ((float) (gy - top_edge) * gp.ys_inv);
|
||||||
|
|
||||||
val = gp.bright_top ? 1.f - val : val;
|
val = gp.bright_top ? 1.f - val : val;
|
||||||
|
|
||||||
val *= rtengine::RT_PI_F_2;
|
val *= rtengine::RT_PI_F_2;
|
||||||
|
|
||||||
if (gp.scale < 1.f) {
|
if (gp.scale < 1.f) {
|
||||||
val = pow3(xsinf(val));
|
val = pow3 (xsinf (val));
|
||||||
} else {
|
} else {
|
||||||
val = 1.f - pow3(xcosf(val));
|
val = 1.f - pow3 (xcosf (val));
|
||||||
}
|
}
|
||||||
|
|
||||||
return gp.scale + val * (1.0 - gp.scale);
|
return gp.scale + val * (1.0 - gp.scale);
|
||||||
@@ -507,7 +507,7 @@ struct pcv_params {
|
|||||||
float scale;
|
float scale;
|
||||||
float fadeout_mul;
|
float fadeout_mul;
|
||||||
};
|
};
|
||||||
static void calcPCVignetteParams(int fW, int fH, int oW, int oH, const PCVignetteParams& pcvignette, const CropParams &crop, struct pcv_params& pcv)
|
static void calcPCVignetteParams (int fW, int fH, int oW, int oH, const PCVignetteParams& pcvignette, const CropParams &crop, struct pcv_params& pcv)
|
||||||
{
|
{
|
||||||
|
|
||||||
// ellipse formula: (x/a)^2 + (y/b)^2 = 1
|
// ellipse formula: (x/a)^2 + (y/b)^2 = 1
|
||||||
@@ -528,49 +528,49 @@ static void calcPCVignetteParams(int fW, int fH, int oW, int oH, const PCVignett
|
|||||||
pcv.h = oH;
|
pcv.h = oH;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcv.fadeout_mul = 1.0 / (0.05 * sqrtf(oW * oW + oH * oH));
|
pcv.fadeout_mul = 1.0 / (0.05 * sqrtf (oW * oW + oH * oH));
|
||||||
float short_side = (pcv.w < pcv.h) ? pcv.w : pcv.h;
|
float short_side = (pcv.w < pcv.h) ? pcv.w : pcv.h;
|
||||||
float long_side = (pcv.w > pcv.h) ? pcv.w : pcv.h;
|
float long_side = (pcv.w > pcv.h) ? pcv.w : pcv.h;
|
||||||
|
|
||||||
pcv.sep = 2;
|
pcv.sep = 2;
|
||||||
pcv.sepmix = 0;
|
pcv.sepmix = 0;
|
||||||
pcv.oe_a = sqrt(2.0) * long_side * 0.5;
|
pcv.oe_a = sqrt (2.0) * long_side * 0.5;
|
||||||
pcv.oe_b = pcv.oe_a * short_side / long_side;
|
pcv.oe_b = pcv.oe_a * short_side / long_side;
|
||||||
pcv.ie_mul = (1.0 / sqrt(2.0)) * (1.0 - pcv.feather);
|
pcv.ie_mul = (1.0 / sqrt (2.0)) * (1.0 - pcv.feather);
|
||||||
pcv.is_super_ellipse_mode = false;
|
pcv.is_super_ellipse_mode = false;
|
||||||
pcv.is_portrait = (pcv.w < pcv.h);
|
pcv.is_portrait = (pcv.w < pcv.h);
|
||||||
|
|
||||||
if (roundness < 0.5) {
|
if (roundness < 0.5) {
|
||||||
// make super-ellipse of higher and higher degree
|
// make super-ellipse of higher and higher degree
|
||||||
pcv.is_super_ellipse_mode = true;
|
pcv.is_super_ellipse_mode = true;
|
||||||
float sepf = 2 + 4 * powf(1.0 - 2 * roundness, 1.3); // gamma 1.3 used to balance the effect in the 0.0...0.5 roundness range
|
float sepf = 2 + 4 * powf (1.0 - 2 * roundness, 1.3); // gamma 1.3 used to balance the effect in the 0.0...0.5 roundness range
|
||||||
pcv.sep = ((int)sepf) & ~0x1;
|
pcv.sep = ((int)sepf) & ~0x1;
|
||||||
pcv.sepmix = (sepf - pcv.sep) * 0.5; // 0.0 to 1.0
|
pcv.sepmix = (sepf - pcv.sep) * 0.5; // 0.0 to 1.0
|
||||||
pcv.oe1_a = powf(2.0, 1.0 / pcv.sep) * long_side * 0.5;
|
pcv.oe1_a = powf (2.0, 1.0 / pcv.sep) * long_side * 0.5;
|
||||||
pcv.oe1_b = pcv.oe1_a * short_side / long_side;
|
pcv.oe1_b = pcv.oe1_a * short_side / long_side;
|
||||||
pcv.ie1_mul = (1.0 / powf(2.0, 1.0 / pcv.sep)) * (1.0 - pcv.feather);
|
pcv.ie1_mul = (1.0 / powf (2.0, 1.0 / pcv.sep)) * (1.0 - pcv.feather);
|
||||||
pcv.oe2_a = powf(2.0, 1.0 / (pcv.sep + 2)) * long_side * 0.5;
|
pcv.oe2_a = powf (2.0, 1.0 / (pcv.sep + 2)) * long_side * 0.5;
|
||||||
pcv.oe2_b = pcv.oe2_a * short_side / long_side;
|
pcv.oe2_b = pcv.oe2_a * short_side / long_side;
|
||||||
pcv.ie2_mul = (1.0 / powf(2.0, 1.0 / (pcv.sep + 2))) * (1.0 - pcv.feather);
|
pcv.ie2_mul = (1.0 / powf (2.0, 1.0 / (pcv.sep + 2))) * (1.0 - pcv.feather);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roundness > 0.5) {
|
if (roundness > 0.5) {
|
||||||
// scale from fitted ellipse towards circle
|
// scale from fitted ellipse towards circle
|
||||||
float rad = sqrtf(pcv.w * pcv.w + pcv.h * pcv.h) / 2.0;
|
float rad = sqrtf (pcv.w * pcv.w + pcv.h * pcv.h) / 2.0;
|
||||||
float diff_a = rad - pcv.oe_a;
|
float diff_a = rad - pcv.oe_a;
|
||||||
float diff_b = rad - pcv.oe_b;
|
float diff_b = rad - pcv.oe_b;
|
||||||
pcv.oe_a = pcv.oe_a + diff_a * 2 * (roundness - 0.5);
|
pcv.oe_a = pcv.oe_a + diff_a * 2 * (roundness - 0.5);
|
||||||
pcv.oe_b = pcv.oe_b + diff_b * 2 * (roundness - 0.5);
|
pcv.oe_b = pcv.oe_b + diff_b * 2 * (roundness - 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
pcv.scale = powf(2, -pcvignette.strength);
|
pcv.scale = powf (2, -pcvignette.strength);
|
||||||
|
|
||||||
if (pcvignette.strength >= 6.0) {
|
if (pcvignette.strength >= 6.0) {
|
||||||
pcv.scale = 0.0;
|
pcv.scale = 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static float calcPCVignetteFactor(const struct pcv_params& pcv, int x, int y)
|
static float calcPCVignetteFactor (const struct pcv_params& pcv, int x, int y)
|
||||||
{
|
{
|
||||||
|
|
||||||
float fo = 1.f;
|
float fo = 1.f;
|
||||||
@@ -592,25 +592,25 @@ static float calcPCVignetteFactor(const struct pcv_params& pcv, int x, int y)
|
|||||||
dist_y = 0;
|
dist_y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fo = sqrtf(dist_x * dist_x + dist_y * dist_y) * pcv.fadeout_mul;
|
fo = sqrtf (dist_x * dist_x + dist_y * dist_y) * pcv.fadeout_mul;
|
||||||
|
|
||||||
if (fo >= 1.f) {
|
if (fo >= 1.f) {
|
||||||
return 1.f;
|
return 1.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float a = fabs((x - pcv.x1) - pcv.w * 0.5f);
|
float a = fabs ((x - pcv.x1) - pcv.w * 0.5f);
|
||||||
float b = fabs((y - pcv.y1) - pcv.h * 0.5f);
|
float b = fabs ((y - pcv.y1) - pcv.h * 0.5f);
|
||||||
|
|
||||||
if(pcv.is_portrait) {
|
if (pcv.is_portrait) {
|
||||||
std::swap(a, b);
|
std::swap (a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
float dist = normn(a, b, 2);
|
float dist = normn (a, b, 2);
|
||||||
float dist_oe, dist_ie;
|
float dist_oe, dist_ie;
|
||||||
float2 sincosval;
|
float2 sincosval;
|
||||||
|
|
||||||
if(dist == 0.0f) {
|
if (dist == 0.0f) {
|
||||||
sincosval.y = 1.0f; // cos
|
sincosval.y = 1.0f; // cos
|
||||||
sincosval.x = 0.0f; // sin
|
sincosval.x = 0.0f; // sin
|
||||||
} else {
|
} else {
|
||||||
@@ -619,14 +619,14 @@ static float calcPCVignetteFactor(const struct pcv_params& pcv, int x, int y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pcv.is_super_ellipse_mode) {
|
if (pcv.is_super_ellipse_mode) {
|
||||||
float dist_oe1 = pcv.oe1_a * pcv.oe1_b / normn(pcv.oe1_b * sincosval.y, pcv.oe1_a * sincosval.x, pcv.sep);
|
float dist_oe1 = pcv.oe1_a * pcv.oe1_b / normn (pcv.oe1_b * sincosval.y, pcv.oe1_a * sincosval.x, pcv.sep);
|
||||||
float dist_oe2 = pcv.oe2_a * pcv.oe2_b / normn(pcv.oe2_b * sincosval.y, pcv.oe2_a * sincosval.x, pcv.sep + 2);
|
float dist_oe2 = pcv.oe2_a * pcv.oe2_b / normn (pcv.oe2_b * sincosval.y, pcv.oe2_a * sincosval.x, pcv.sep + 2);
|
||||||
float dist_ie1 = pcv.ie1_mul * dist_oe1;
|
float dist_ie1 = pcv.ie1_mul * dist_oe1;
|
||||||
float dist_ie2 = pcv.ie2_mul * dist_oe2;
|
float dist_ie2 = pcv.ie2_mul * dist_oe2;
|
||||||
dist_oe = dist_oe1 * (1.f - pcv.sepmix) + dist_oe2 * pcv.sepmix;
|
dist_oe = dist_oe1 * (1.f - pcv.sepmix) + dist_oe2 * pcv.sepmix;
|
||||||
dist_ie = dist_ie1 * (1.f - pcv.sepmix) + dist_ie2 * pcv.sepmix;
|
dist_ie = dist_ie1 * (1.f - pcv.sepmix) + dist_ie2 * pcv.sepmix;
|
||||||
} else {
|
} else {
|
||||||
dist_oe = pcv.oe_a * pcv.oe_b / sqrtf(SQR(pcv.oe_b * sincosval.y) + SQR(pcv.oe_a * sincosval.x));
|
dist_oe = pcv.oe_a * pcv.oe_b / sqrtf (SQR (pcv.oe_b * sincosval.y) + SQR (pcv.oe_a * sincosval.x));
|
||||||
dist_ie = pcv.ie_mul * dist_oe;
|
dist_ie = pcv.ie_mul * dist_oe;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,9 +642,9 @@ static float calcPCVignetteFactor(const struct pcv_params& pcv, int x, int y)
|
|||||||
val = rtengine::RT_PI_F_2 * (dist - dist_ie) / (dist_oe - dist_ie);
|
val = rtengine::RT_PI_F_2 * (dist - dist_ie) / (dist_oe - dist_ie);
|
||||||
|
|
||||||
if (pcv.scale < 1.f) {
|
if (pcv.scale < 1.f) {
|
||||||
val = pow4(xcosf(val));
|
val = pow4 (xcosf (val));
|
||||||
} else {
|
} else {
|
||||||
val = 1 - pow4(xsinf(val));
|
val = 1 - pow4 (xsinf (val));
|
||||||
}
|
}
|
||||||
|
|
||||||
val = pcv.scale + val * (1.f - pcv.scale);
|
val = pcv.scale + val * (1.f - pcv.scale);
|
||||||
@@ -667,20 +667,20 @@ void ImProcFunctions::transformLuminanceOnly (Imagefloat* original, Imagefloat*
|
|||||||
double vig_w2, vig_h2, maxRadius, v, b, mul;
|
double vig_w2, vig_h2, maxRadius, v, b, mul;
|
||||||
|
|
||||||
if (applyVignetting) {
|
if (applyVignetting) {
|
||||||
calcVignettingParams(oW, oH, params->vignetting, vig_w2, vig_h2, maxRadius, v, b, mul);
|
calcVignettingParams (oW, oH, params->vignetting, vig_w2, vig_h2, maxRadius, v, b, mul);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct grad_params gp;
|
struct grad_params gp;
|
||||||
|
|
||||||
if (applyGradient) {
|
if (applyGradient) {
|
||||||
calcGradientParams(oW, oH, params->gradient, gp);
|
calcGradientParams (oW, oH, params->gradient, gp);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pcv_params pcv;
|
struct pcv_params pcv;
|
||||||
|
|
||||||
if (applyPCVignetting) {
|
if (applyPCVignetting) {
|
||||||
//fprintf(stderr, "%d %d | %d %d | %d %d | %d %d [%d %d]\n", fW, fH, oW, oH, transformed->getWidth(), transformed->getHeight(), cx, cy, params->crop.w, params->crop.h);
|
//fprintf(stderr, "%d %d | %d %d | %d %d | %d %d [%d %d]\n", fW, fH, oW, oH, transformed->getWidth(), transformed->getHeight(), cx, cy, params->crop.w, params->crop.h);
|
||||||
calcPCVignetteParams(fW, fH, oW, oH, params->pcvignette, params->crop, pcv);
|
calcPCVignetteParams (fW, fH, oW, oH, params->pcvignette, params->crop, pcv);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool darkening = (params->vignetting.amount <= 0.0);
|
bool darkening = (params->vignetting.amount <= 0.0);
|
||||||
@@ -694,26 +694,26 @@ void ImProcFunctions::transformLuminanceOnly (Imagefloat* original, Imagefloat*
|
|||||||
|
|
||||||
if (applyVignetting) {
|
if (applyVignetting) {
|
||||||
double vig_x_d = (double) (x + cx) - vig_w2 ;
|
double vig_x_d = (double) (x + cx) - vig_w2 ;
|
||||||
double r = sqrt(vig_x_d * vig_x_d + vig_y_d * vig_y_d);
|
double r = sqrt (vig_x_d * vig_x_d + vig_y_d * vig_y_d);
|
||||||
|
|
||||||
if(darkening) {
|
if (darkening) {
|
||||||
factor /= std::max(v + mul * tanh (b * (maxRadius - r) / maxRadius), 0.001);
|
factor /= std::max (v + mul * tanh (b * (maxRadius - r) / maxRadius), 0.001);
|
||||||
} else {
|
} else {
|
||||||
factor = v + mul * tanh (b * (maxRadius - r) / maxRadius);
|
factor = v + mul * tanh (b * (maxRadius - r) / maxRadius);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applyGradient) {
|
if (applyGradient) {
|
||||||
factor *= calcGradientFactor(gp, cx + x, cy + y);
|
factor *= calcGradientFactor (gp, cx + x, cy + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applyPCVignetting) {
|
if (applyPCVignetting) {
|
||||||
factor *= calcPCVignetteFactor(pcv, cx + x, cy + y);
|
factor *= calcPCVignetteFactor (pcv, cx + x, cy + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
transformed->r(y, x) = original->r(y, x) * factor;
|
transformed->r (y, x) = original->r (y, x) * factor;
|
||||||
transformed->g(y, x) = original->g(y, x) * factor;
|
transformed->g (y, x) = original->g (y, x) * factor;
|
||||||
transformed->b(y, x) = original->b(y, x) * factor;
|
transformed->b (y, x) = original->b (y, x) * factor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -726,18 +726,18 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr
|
|||||||
double h2 = (double) oH / 2.0 - 0.5;
|
double h2 = (double) oH / 2.0 - 0.5;
|
||||||
|
|
||||||
double vig_w2, vig_h2, maxRadius, v, b, mul;
|
double vig_w2, vig_h2, maxRadius, v, b, mul;
|
||||||
calcVignettingParams(oW, oH, params->vignetting, vig_w2, vig_h2, maxRadius, v, b, mul);
|
calcVignettingParams (oW, oH, params->vignetting, vig_w2, vig_h2, maxRadius, v, b, mul);
|
||||||
|
|
||||||
struct grad_params gp;
|
struct grad_params gp;
|
||||||
|
|
||||||
if (needsGradient()) {
|
if (needsGradient()) {
|
||||||
calcGradientParams(oW, oH, params->gradient, gp);
|
calcGradientParams (oW, oH, params->gradient, gp);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pcv_params pcv;
|
struct pcv_params pcv;
|
||||||
|
|
||||||
if (needsPCVignetting()) {
|
if (needsPCVignetting()) {
|
||||||
calcPCVignetteParams(fW, fH, oW, oH, params->pcvignette, params->crop, pcv);
|
calcPCVignetteParams (fW, fH, oW, oH, params->pcvignette, params->crop, pcv);
|
||||||
}
|
}
|
||||||
|
|
||||||
float** chOrig[3];
|
float** chOrig[3];
|
||||||
@@ -761,21 +761,21 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr
|
|||||||
double distAmount = params->distortion.amount;
|
double distAmount = params->distortion.amount;
|
||||||
|
|
||||||
// auxiliary variables for rotation
|
// auxiliary variables for rotation
|
||||||
double cost = cos(params->rotate.degree * rtengine::RT_PI / 180.0);
|
double cost = cos (params->rotate.degree * rtengine::RT_PI / 180.0);
|
||||||
double sint = sin(params->rotate.degree * rtengine::RT_PI / 180.0);
|
double sint = sin (params->rotate.degree * rtengine::RT_PI / 180.0);
|
||||||
|
|
||||||
// auxiliary variables for vertical perspective correction
|
// auxiliary variables for vertical perspective correction
|
||||||
double vpdeg = params->perspective.vertical / 100.0 * 45.0;
|
double vpdeg = params->perspective.vertical / 100.0 * 45.0;
|
||||||
double vpalpha = (90.0 - vpdeg) / 180.0 * rtengine::RT_PI;
|
double vpalpha = (90.0 - vpdeg) / 180.0 * rtengine::RT_PI;
|
||||||
double vpteta = fabs(vpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((vpdeg > 0 ? 1.0 : -1.0) * sqrt((-SQR(oW * tan(vpalpha)) + (vpdeg > 0 ? 1.0 : -1.0) *
|
double vpteta = fabs (vpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((vpdeg > 0 ? 1.0 : -1.0) * sqrt ((-SQR (oW * tan (vpalpha)) + (vpdeg > 0 ? 1.0 : -1.0) *
|
||||||
oW * tan(vpalpha) * sqrt(SQR(4 * maxRadius) + SQR(oW * tan(vpalpha)))) / (SQR(maxRadius) * 8)));
|
oW * tan (vpalpha) * sqrt (SQR (4 * maxRadius) + SQR (oW * tan (vpalpha)))) / (SQR (maxRadius) * 8)));
|
||||||
double vpcospt = (vpdeg >= 0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta);
|
double vpcospt = (vpdeg >= 0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta);
|
||||||
|
|
||||||
// auxiliary variables for horizontal perspective correction
|
// auxiliary variables for horizontal perspective correction
|
||||||
double hpdeg = params->perspective.horizontal / 100.0 * 45.0;
|
double hpdeg = params->perspective.horizontal / 100.0 * 45.0;
|
||||||
double hpalpha = (90.0 - hpdeg) / 180.0 * rtengine::RT_PI;
|
double hpalpha = (90.0 - hpdeg) / 180.0 * rtengine::RT_PI;
|
||||||
double hpteta = fabs(hpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((hpdeg > 0 ? 1.0 : -1.0) * sqrt((-SQR(oH * tan(hpalpha)) + (hpdeg > 0 ? 1.0 : -1.0) *
|
double hpteta = fabs (hpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((hpdeg > 0 ? 1.0 : -1.0) * sqrt ((-SQR (oH * tan (hpalpha)) + (hpdeg > 0 ? 1.0 : -1.0) *
|
||||||
oH * tan(hpalpha) * sqrt(SQR(4 * maxRadius) + SQR(oH * tan(hpalpha)))) / (SQR(maxRadius) * 8)));
|
oH * tan (hpalpha) * sqrt (SQR (4 * maxRadius) + SQR (oH * tan (hpalpha)))) / (SQR (maxRadius) * 8)));
|
||||||
double hpcospt = (hpdeg >= 0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta);
|
double hpcospt = (hpdeg >= 0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta);
|
||||||
|
|
||||||
double ascale = params->commonTrans.autofill ? getTransformAutoFill (oW, oH, true /*fullImage*/ ? pLCPMap : nullptr) : 1.0;
|
double ascale = params->commonTrans.autofill ? getTransformAutoFill (oW, oH, true /*fullImage*/ ? pLCPMap : nullptr) : 1.0;
|
||||||
@@ -799,13 +799,13 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr
|
|||||||
double x_d = x, y_d = y;
|
double x_d = x, y_d = y;
|
||||||
|
|
||||||
if (enableLCPDist) {
|
if (enableLCPDist) {
|
||||||
correct_distortion(pLCPMap, x_d, y_d, cx, cy); // must be first transform
|
correct_distortion (pLCPMap, x_d, y_d, cx, cy); // must be first transform
|
||||||
}
|
}
|
||||||
|
|
||||||
x_d = ascale * (x_d + cx - w2); // centering x coord & scale
|
x_d = ascale * (x_d + cx - w2); // centering x coord & scale
|
||||||
y_d = ascale * (y_d + cy - h2); // centering y coord & scale
|
y_d = ascale * (y_d + cy - h2); // centering y coord & scale
|
||||||
|
|
||||||
double vig_x_d, vig_y_d;
|
double vig_x_d = 0., vig_y_d = 0.;
|
||||||
|
|
||||||
if (needsVignetting()) {
|
if (needsVignetting()) {
|
||||||
vig_x_d = ascale * (x + cx - vig_w2); // centering x coord & scale
|
vig_x_d = ascale * (x + cx - vig_w2); // centering x coord & scale
|
||||||
@@ -830,16 +830,16 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr
|
|||||||
double s = 1;
|
double s = 1;
|
||||||
|
|
||||||
if (needsDist) {
|
if (needsDist) {
|
||||||
double r = sqrt(Dxc * Dxc + Dyc * Dyc) / maxRadius; // sqrt is slow
|
double r = sqrt (Dxc * Dxc + Dyc * Dyc) / maxRadius; // sqrt is slow
|
||||||
s = 1.0 - distAmount + distAmount * r ;
|
s = 1.0 - distAmount + distAmount * r ;
|
||||||
}
|
}
|
||||||
|
|
||||||
double r2;
|
double r2 = 0.;
|
||||||
|
|
||||||
if (needsVignetting()) {
|
if (needsVignetting()) {
|
||||||
double vig_Dx = vig_x_d * cost - vig_y_d * sint;
|
double vig_Dx = vig_x_d * cost - vig_y_d * sint;
|
||||||
double vig_Dy = vig_x_d * sint + vig_y_d * cost;
|
double vig_Dy = vig_x_d * sint + vig_y_d * cost;
|
||||||
r2 = sqrt(vig_Dx * vig_Dx + vig_Dy * vig_Dy);
|
r2 = sqrt (vig_Dx * vig_Dx + vig_Dy * vig_Dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int c = 0; c < (enableCA ? 3 : 1); c++) {
|
for (int c = 0; c < (enableCA ? 3 : 1); c++) {
|
||||||
@@ -852,7 +852,7 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr
|
|||||||
|
|
||||||
// LCP CA
|
// LCP CA
|
||||||
if (enableLCPCA) {
|
if (enableLCPCA) {
|
||||||
pLCPMap->correctCA(Dx, Dy, c);
|
pLCPMap->correctCA (Dx, Dy, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract integer and fractions of source screen coordinates
|
// Extract integer and fractions of source screen coordinates
|
||||||
@@ -870,41 +870,41 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr
|
|||||||
double vignmul = 1.0;
|
double vignmul = 1.0;
|
||||||
|
|
||||||
if (needsVignetting()) {
|
if (needsVignetting()) {
|
||||||
if(darkening) {
|
if (darkening) {
|
||||||
vignmul /= std::max(v + mul * tanh (b * (maxRadius - s * r2) / maxRadius), 0.001);
|
vignmul /= std::max (v + mul * tanh (b * (maxRadius - s * r2) / maxRadius), 0.001);
|
||||||
} else {
|
} else {
|
||||||
vignmul *= (v + mul * tanh (b * (maxRadius - s * r2) / maxRadius));
|
vignmul *= (v + mul * tanh (b * (maxRadius - s * r2) / maxRadius));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsGradient()) {
|
if (needsGradient()) {
|
||||||
vignmul *= calcGradientFactor(gp, cx + x, cy + y);
|
vignmul *= calcGradientFactor (gp, cx + x, cy + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsPCVignetting()) {
|
if (needsPCVignetting()) {
|
||||||
vignmul *= calcPCVignetteFactor(pcv, cx + x, cy + y);
|
vignmul *= calcPCVignetteFactor (pcv, cx + x, cy + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 (enableCA) {
|
||||||
interpolateTransformChannelsCubic (chOrig[c], xc - 1, yc - 1, Dx, Dy, &(chTrans[c][y][x]), vignmul);
|
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 {
|
} 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 (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 {
|
||||||
transformed->r(y, x) = vignmul * (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->r (y, x) = vignmul * (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 * (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->g (y, x) = vignmul * (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 * (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 {
|
||||||
@@ -912,9 +912,9 @@ void ImProcFunctions::transformHighQuality (Imagefloat* original, Imagefloat* tr
|
|||||||
// not valid (source pixel x,y not inside source image, etc.)
|
// not valid (source pixel x,y not inside source image, etc.)
|
||||||
chTrans[c][y][x] = 0;
|
chTrans[c][y][x] = 0;
|
||||||
} else {
|
} else {
|
||||||
transformed->r(y, x) = 0;
|
transformed->r (y, x) = 0;
|
||||||
transformed->g(y, x) = 0;
|
transformed->g (y, x) = 0;
|
||||||
transformed->b(y, x) = 0;
|
transformed->b (y, x) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -930,18 +930,18 @@ void ImProcFunctions::transformPreview (Imagefloat* original, Imagefloat* transf
|
|||||||
double h2 = (double) oH / 2.0 - 0.5;
|
double h2 = (double) oH / 2.0 - 0.5;
|
||||||
|
|
||||||
double vig_w2, vig_h2, maxRadius, v, b, mul;
|
double vig_w2, vig_h2, maxRadius, v, b, mul;
|
||||||
calcVignettingParams(oW, oH, params->vignetting, vig_w2, vig_h2, maxRadius, v, b, mul);
|
calcVignettingParams (oW, oH, params->vignetting, vig_w2, vig_h2, maxRadius, v, b, mul);
|
||||||
|
|
||||||
struct grad_params gp;
|
struct grad_params gp;
|
||||||
|
|
||||||
if (needsGradient()) {
|
if (needsGradient()) {
|
||||||
calcGradientParams(oW, oH, params->gradient, gp);
|
calcGradientParams (oW, oH, params->gradient, gp);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pcv_params pcv;
|
struct pcv_params pcv;
|
||||||
|
|
||||||
if (needsPCVignetting()) {
|
if (needsPCVignetting()) {
|
||||||
calcPCVignetteParams(fW, fH, oW, oH, params->pcvignette, params->crop, pcv);
|
calcPCVignetteParams (fW, fH, oW, oH, params->pcvignette, params->crop, pcv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// auxiliary variables for distortion correction
|
// auxiliary variables for distortion correction
|
||||||
@@ -949,19 +949,19 @@ void ImProcFunctions::transformPreview (Imagefloat* original, Imagefloat* transf
|
|||||||
double distAmount = params->distortion.amount;
|
double distAmount = params->distortion.amount;
|
||||||
|
|
||||||
// auxiliary variables for rotation
|
// auxiliary variables for rotation
|
||||||
double cost = cos(params->rotate.degree * rtengine::RT_PI / 180.0);
|
double cost = cos (params->rotate.degree * rtengine::RT_PI / 180.0);
|
||||||
double sint = sin(params->rotate.degree * rtengine::RT_PI / 180.0);
|
double sint = sin (params->rotate.degree * rtengine::RT_PI / 180.0);
|
||||||
|
|
||||||
// auxiliary variables for vertical perspective correction
|
// auxiliary variables for vertical perspective correction
|
||||||
double vpdeg = params->perspective.vertical / 100.0 * 45.0;
|
double vpdeg = params->perspective.vertical / 100.0 * 45.0;
|
||||||
double vpalpha = (90 - vpdeg) / 180.0 * rtengine::RT_PI;
|
double vpalpha = (90 - vpdeg) / 180.0 * rtengine::RT_PI;
|
||||||
double vpteta = fabs(vpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((vpdeg > 0 ? 1.0 : -1.0) * sqrt((-oW * oW * tan(vpalpha) * tan(vpalpha) + (vpdeg > 0 ? 1.0 : -1.0) * oW * tan(vpalpha) * sqrt(16 * maxRadius * maxRadius + oW * oW * tan(vpalpha) * tan(vpalpha))) / (maxRadius * maxRadius * 8)));
|
double vpteta = fabs (vpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((vpdeg > 0 ? 1.0 : -1.0) * sqrt ((-oW * oW * tan (vpalpha) * tan (vpalpha) + (vpdeg > 0 ? 1.0 : -1.0) * oW * tan (vpalpha) * sqrt (16 * maxRadius * maxRadius + oW * oW * tan (vpalpha) * tan (vpalpha))) / (maxRadius * maxRadius * 8)));
|
||||||
double vpcospt = (vpdeg >= 0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta);
|
double vpcospt = (vpdeg >= 0 ? 1.0 : -1.0) * cos (vpteta), vptanpt = tan (vpteta);
|
||||||
|
|
||||||
// auxiliary variables for horizontal perspective correction
|
// auxiliary variables for horizontal perspective correction
|
||||||
double hpdeg = params->perspective.horizontal / 100.0 * 45.0;
|
double hpdeg = params->perspective.horizontal / 100.0 * 45.0;
|
||||||
double hpalpha = (90 - hpdeg) / 180.0 * rtengine::RT_PI;
|
double hpalpha = (90 - hpdeg) / 180.0 * rtengine::RT_PI;
|
||||||
double hpteta = fabs(hpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((hpdeg > 0 ? 1.0 : -1.0) * sqrt((-oH * oH * tan(hpalpha) * tan(hpalpha) + (hpdeg > 0 ? 1.0 : -1.0) * oH * tan(hpalpha) * sqrt(16 * maxRadius * maxRadius + oH * oH * tan(hpalpha) * tan(hpalpha))) / (maxRadius * maxRadius * 8)));
|
double hpteta = fabs (hpalpha - rtengine::RT_PI / 2) < 3e-4 ? 0.0 : acos ((hpdeg > 0 ? 1.0 : -1.0) * sqrt ((-oH * oH * tan (hpalpha) * tan (hpalpha) + (hpdeg > 0 ? 1.0 : -1.0) * oH * tan (hpalpha) * sqrt (16 * maxRadius * maxRadius + oH * oH * tan (hpalpha) * tan (hpalpha))) / (maxRadius * maxRadius * 8)));
|
||||||
double hpcospt = (hpdeg >= 0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta);
|
double hpcospt = (hpdeg >= 0 ? 1.0 : -1.0) * cos (hpteta), hptanpt = tan (hpteta);
|
||||||
|
|
||||||
double ascale = params->commonTrans.autofill ? getTransformAutoFill (oW, oH, pLCPMap) : 1.0;
|
double ascale = params->commonTrans.autofill ? getTransformAutoFill (oW, oH, pLCPMap) : 1.0;
|
||||||
@@ -976,13 +976,13 @@ void ImProcFunctions::transformPreview (Imagefloat* original, Imagefloat* transf
|
|||||||
double x_d = x, y_d = y;
|
double x_d = x, y_d = y;
|
||||||
|
|
||||||
if (pLCPMap && params->lensProf.useDist) {
|
if (pLCPMap && params->lensProf.useDist) {
|
||||||
correct_distortion(pLCPMap, x_d, y_d, cx, cy); // must be first transform
|
correct_distortion (pLCPMap, x_d, y_d, cx, cy); // must be first transform
|
||||||
}
|
}
|
||||||
|
|
||||||
y_d = ascale * (y_d + cy - h2); // centering y coord & scale
|
y_d = ascale * (y_d + cy - h2); // centering y coord & scale
|
||||||
x_d = ascale * (x_d + cx - w2); // centering x coord & scale
|
x_d = ascale * (x_d + cx - w2); // centering x coord & scale
|
||||||
|
|
||||||
double vig_x_d, vig_y_d;
|
double vig_x_d = 0., vig_y_d = 0.;
|
||||||
|
|
||||||
if (needsVignetting()) {
|
if (needsVignetting()) {
|
||||||
vig_x_d = ascale * (x + cx - vig_w2); // centering x coord & scale
|
vig_x_d = ascale * (x + cx - vig_w2); // centering x coord & scale
|
||||||
@@ -1007,18 +1007,18 @@ void ImProcFunctions::transformPreview (Imagefloat* original, Imagefloat* transf
|
|||||||
double s = 1;
|
double s = 1;
|
||||||
|
|
||||||
if (needsDist) {
|
if (needsDist) {
|
||||||
double r = sqrt(Dx * Dx + Dy * Dy) / maxRadius; // sqrt is slow
|
double r = sqrt (Dx * Dx + Dy * Dy) / maxRadius; // sqrt is slow
|
||||||
s = 1.0 - distAmount + distAmount * r ;
|
s = 1.0 - distAmount + distAmount * r ;
|
||||||
Dx *= s;
|
Dx *= s;
|
||||||
Dy *= s;
|
Dy *= s;
|
||||||
}
|
}
|
||||||
|
|
||||||
double r2;
|
double r2 = 0.;
|
||||||
|
|
||||||
if (needsVignetting()) {
|
if (needsVignetting()) {
|
||||||
double vig_Dx = vig_x_d * cost - vig_y_d * sint;
|
double vig_Dx = vig_x_d * cost - vig_y_d * sint;
|
||||||
double vig_Dy = vig_x_d * sint + vig_y_d * cost;
|
double vig_Dy = vig_x_d * sint + vig_y_d * cost;
|
||||||
r2 = sqrt(vig_Dx * vig_Dx + vig_Dy * vig_Dy);
|
r2 = sqrt (vig_Dx * vig_Dx + vig_Dy * vig_Dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
// de-center
|
// de-center
|
||||||
@@ -1040,41 +1040,41 @@ void ImProcFunctions::transformPreview (Imagefloat* original, Imagefloat* transf
|
|||||||
double vignmul = 1.0;
|
double vignmul = 1.0;
|
||||||
|
|
||||||
if (needsVignetting()) {
|
if (needsVignetting()) {
|
||||||
if(darkening) {
|
if (darkening) {
|
||||||
vignmul /= std::max(v + mul * tanh (b * (maxRadius - s * r2) / maxRadius), 0.001);
|
vignmul /= std::max (v + mul * tanh (b * (maxRadius - s * r2) / maxRadius), 0.001);
|
||||||
} else {
|
} else {
|
||||||
vignmul = v + mul * tanh (b * (maxRadius - s * r2) / maxRadius);
|
vignmul = v + mul * tanh (b * (maxRadius - s * r2) / maxRadius);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsGradient()) {
|
if (needsGradient()) {
|
||||||
vignmul *= calcGradientFactor(gp, cx + x, cy + y);
|
vignmul *= calcGradientFactor (gp, cx + x, cy + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsPCVignetting()) {
|
if (needsPCVignetting()) {
|
||||||
vignmul *= calcPCVignetteFactor(pcv, cx + x, cy + y);
|
vignmul *= calcPCVignetteFactor (pcv, cx + x, cy + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (yc < original->getHeight() - 1 && xc < original->getWidth() - 1) {
|
if (yc < original->getHeight() - 1 && xc < original->getWidth() - 1) {
|
||||||
// all interpolation pixels inside image
|
// all interpolation pixels inside image
|
||||||
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 {
|
} 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);
|
||||||
transformed->r(y, x) = vignmul * (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->r (y, x) = vignmul * (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 * (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->g (y, x) = vignmul * (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 * (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 {
|
||||||
// not valid (source pixel x,y not inside source image, etc.)
|
// not valid (source pixel x,y not inside source image, etc.)
|
||||||
transformed->r(y, x) = 0;
|
transformed->r (y, x) = 0;
|
||||||
transformed->g(y, x) = 0;
|
transformed->g (y, x) = 0;
|
||||||
transformed->b(y, x) = 0;
|
transformed->b (y, x) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1126,12 +1126,12 @@ bool ImProcFunctions::needsPerspective ()
|
|||||||
|
|
||||||
bool ImProcFunctions::needsGradient ()
|
bool ImProcFunctions::needsGradient ()
|
||||||
{
|
{
|
||||||
return params->gradient.enabled && fabs(params->gradient.strength) > 1e-15;
|
return params->gradient.enabled && fabs (params->gradient.strength) > 1e-15;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImProcFunctions::needsPCVignetting ()
|
bool ImProcFunctions::needsPCVignetting ()
|
||||||
{
|
{
|
||||||
return params->pcvignette.enabled && fabs(params->pcvignette.strength) > 1e-15;
|
return params->pcvignette.enabled && fabs (params->pcvignette.strength) > 1e-15;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImProcFunctions::needsVignetting ()
|
bool ImProcFunctions::needsVignetting ()
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
#include <omp.h>
|
#include <omp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
@@ -44,7 +45,7 @@ using namespace procparams;
|
|||||||
|
|
||||||
extern const Settings* settings;
|
extern const Settings* settings;
|
||||||
|
|
||||||
void fillCurveArrayVib(DiagonalCurve* diagCurve, LUTf &outCurve)
|
void fillCurveArrayVib (DiagonalCurve* diagCurve, LUTf &outCurve)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (diagCurve) {
|
if (diagCurve) {
|
||||||
@@ -56,7 +57,7 @@ void fillCurveArrayVib(DiagonalCurve* diagCurve, LUTf &outCurve)
|
|||||||
// change to [0,1] range
|
// change to [0,1] range
|
||||||
// apply custom/parametric/NURBS curve, if any
|
// apply custom/parametric/NURBS curve, if any
|
||||||
// and store result in a temporary array
|
// and store result in a temporary array
|
||||||
outCurve[i] = 65535.f * diagCurve->getVal( double(i) / 65535.0 );
|
outCurve[i] = 65535.f * diagCurve->getVal ( double (i) / 65535.0 );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
outCurve.makeIdentity();
|
outCurve.makeIdentity();
|
||||||
@@ -111,8 +112,8 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
// I use diagonal because I think it's better
|
// I use diagonal because I think it's better
|
||||||
LUTf skin_curve (65536, 0);
|
LUTf skin_curve (65536, 0);
|
||||||
|
|
||||||
if(skinCurveIsSet) {
|
if (skinCurveIsSet) {
|
||||||
fillCurveArrayVib(dcurve, skin_curve);
|
fillCurveArrayVib (dcurve, skin_curve);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dcurve) {
|
if (dcurve) {
|
||||||
@@ -123,10 +124,10 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
|
|
||||||
// skin_curve.dump("skin_curve");
|
// skin_curve.dump("skin_curve");
|
||||||
|
|
||||||
const float chromaPastel = float(params->vibrance.pastels) / 100.0f;
|
const float chromaPastel = float (params->vibrance.pastels) / 100.0f;
|
||||||
const float chromaSatur = float(params->vibrance.saturated) / 100.0f;
|
const float chromaSatur = float (params->vibrance.saturated) / 100.0f;
|
||||||
const float p00 = 0.07f;
|
const float p00 = 0.07f;
|
||||||
const float limitpastelsatur = (static_cast<float>(params->vibrance.psthreshold.value[ThresholdSelector::TS_TOPLEFT]) / 100.0f) * (1.0f - p00) + p00;
|
const float limitpastelsatur = (static_cast<float> (params->vibrance.psthreshold.value[ThresholdSelector::TS_TOPLEFT]) / 100.0f) * (1.0f - p00) + p00;
|
||||||
const float maxdp = (limitpastelsatur - p00) / 4.0f;
|
const float maxdp = (limitpastelsatur - p00) / 4.0f;
|
||||||
const float maxds = (1.0 - limitpastelsatur) / 4.0f;
|
const float maxds = (1.0 - limitpastelsatur) / 4.0f;
|
||||||
const float p0 = p00 + maxdp;
|
const float p0 = p00 + maxdp;
|
||||||
@@ -135,10 +136,10 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
const float s0 = limitpastelsatur + maxds;
|
const float s0 = limitpastelsatur + maxds;
|
||||||
const float s1 = limitpastelsatur + 2.0f * maxds;
|
const float s1 = limitpastelsatur + 2.0f * maxds;
|
||||||
const float s2 = limitpastelsatur + 3.0f * maxds;
|
const float s2 = limitpastelsatur + 3.0f * maxds;
|
||||||
const float transitionweighting = static_cast<float>(params->vibrance.psthreshold.value[ThresholdSelector::TS_BOTTOMLEFT]) / 100.0f;
|
const float transitionweighting = static_cast<float> (params->vibrance.psthreshold.value[ThresholdSelector::TS_BOTTOMLEFT]) / 100.0f;
|
||||||
float chromamean = 0.0f;
|
float chromamean = 0.0f;
|
||||||
|
|
||||||
if(chromaPastel != chromaSatur) {
|
if (chromaPastel != chromaSatur) {
|
||||||
//if sliders pastels and saturated are different: transition with a double linear interpolation: between p2 and limitpastelsatur, and between limitpastelsatur and s0
|
//if sliders pastels and saturated are different: transition with a double linear interpolation: between p2 and limitpastelsatur, and between limitpastelsatur and s0
|
||||||
//modify the "mean" point in function of double threshold => differential transition
|
//modify the "mean" point in function of double threshold => differential transition
|
||||||
chromamean = maxdp * (chromaSatur - chromaPastel) / (s0 - p2) + chromaPastel;
|
chromamean = maxdp * (chromaSatur - chromaPastel) / (s0 - p2) + chromaPastel;
|
||||||
@@ -208,8 +209,8 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
|
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
#endif
|
#endif
|
||||||
printf("vibrance: p0=%1.2f p1=%1.2f p2=%1.2f s0=%1.2f s1=%1.2f s2=%1.2f\n", p0, p1, p2, s0, s1, s2);
|
printf ("vibrance: p0=%1.2f p1=%1.2f p2=%1.2f s0=%1.2f s1=%1.2f s2=%1.2f\n", p0, p1, p2, s0, s1, s2);
|
||||||
printf(" pastel=%f satur=%f limit= %1.2f chromamean=%0.5f\n", 1.0f + chromaPastel, 1.0f + chromaSatur, limitpastelsatur, chromamean);
|
printf (" pastel=%f satur=%f limit= %1.2f chromamean=%0.5f\n", 1.0f + chromaPastel, 1.0f + chromaSatur, limitpastelsatur, chromamean);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma omp for schedule(dynamic, 16)
|
#pragma omp for schedule(dynamic, 16)
|
||||||
@@ -217,12 +218,12 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
for (int i = 0; i < height; i++)
|
for (int i = 0; i < height; i++)
|
||||||
for (int j = 0; j < width; j++) {
|
for (int j = 0; j < width; j++) {
|
||||||
float LL = lab->L[i][j] / 327.68f;
|
float LL = lab->L[i][j] / 327.68f;
|
||||||
float CC = sqrt(SQR(lab->a[i][j]) + SQR(lab->b[i][j])) / 327.68f;
|
float CC = sqrt (SQR (lab->a[i][j]) + SQR (lab->b[i][j])) / 327.68f;
|
||||||
float HH = xatan2f(lab->b[i][j], lab->a[i][j]);
|
float HH = xatan2f (lab->b[i][j], lab->a[i][j]);
|
||||||
|
|
||||||
float satredu = 1.0f; //reduct sat in function of skin
|
float satredu = 1.0f; //reduct sat in function of skin
|
||||||
|
|
||||||
if(protectskins) {
|
if (protectskins) {
|
||||||
Color::SkinSat (LL, HH, CC, satredu);// for skin colors
|
Color::SkinSat (LL, HH, CC, satredu);// for skin colors
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +235,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
float R, G, B;
|
float R, G, B;
|
||||||
float2 sincosval;
|
float2 sincosval;
|
||||||
|
|
||||||
if(CC == 0.0f) {
|
if (CC == 0.0f) {
|
||||||
sincosval.y = 1.f;
|
sincosval.y = 1.f;
|
||||||
sincosval.x = 0.0f;
|
sincosval.x = 0.0f;
|
||||||
} else {
|
} else {
|
||||||
@@ -246,26 +247,26 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
bool neg = false;
|
bool neg = false;
|
||||||
bool more_rgb = false;
|
bool more_rgb = false;
|
||||||
//gamut control : Lab values are in gamut
|
//gamut control : Lab values are in gamut
|
||||||
Color::gamutLchonly(HH, sincosval, Lprov, Chprov, R, G, B, wip, highlight, 0.15f, 0.98f, neg, more_rgb);
|
Color::gamutLchonly (HH, sincosval, Lprov, Chprov, R, G, B, wip, highlight, 0.15f, 0.98f, neg, more_rgb);
|
||||||
|
|
||||||
if(neg) {
|
if (neg) {
|
||||||
negat++;
|
negat++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(more_rgb) {
|
if (more_rgb) {
|
||||||
moreRGB++;
|
moreRGB++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
//gamut control : Lab values are in gamut
|
//gamut control : Lab values are in gamut
|
||||||
Color::gamutLchonly(HH, sincosval, Lprov, Chprov, R, G, B, wip, highlight, 0.15f, 0.98f);
|
Color::gamutLchonly (HH, sincosval, Lprov, Chprov, R, G, B, wip, highlight, 0.15f, 0.98f);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(Chprov > 6.0f) {
|
if (Chprov > 6.0f) {
|
||||||
const float saturation = SAT(R, G, B);
|
const float saturation = SAT (R, G, B);
|
||||||
|
|
||||||
if(saturation > 0.0f) {
|
if (saturation > 0.0f) {
|
||||||
if(satredu != 1.0f) {
|
if (satredu != 1.0f) {
|
||||||
// for skin, no differentiation
|
// for skin, no differentiation
|
||||||
sathue [0] = sathue [1] = sathue [2] = sathue [3] = sathue[4] = 1.0f;
|
sathue [0] = sathue [1] = sathue [2] = sathue [3] = sathue[4] = 1.0f;
|
||||||
sathue2[0] = sathue2[1] = sathue2[2] = sathue2[3] = 1.0f;
|
sathue2[0] = sathue2[1] = sathue2[2] = sathue2[3] = 1.0f;
|
||||||
@@ -274,7 +275,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
//I try to take into account: Munsell response (human vision) and Gamut..(less response for red): preferably using Prophoto or WideGamut
|
//I try to take into account: Munsell response (human vision) and Gamut..(less response for red): preferably using Prophoto or WideGamut
|
||||||
//blue: -1.80 -3.14 green = 2.1 3.14 green-yellow=1.4 2.1 red:0 1.4 blue-purple:-0.7 -1.4 purple: 0 -0.7
|
//blue: -1.80 -3.14 green = 2.1 3.14 green-yellow=1.4 2.1 red:0 1.4 blue-purple:-0.7 -1.4 purple: 0 -0.7
|
||||||
//these values allow a better and differential response
|
//these values allow a better and differential response
|
||||||
if(LL < 20.0f) {//more for blue-purple, blue and red modulate
|
if (LL < 20.0f) { //more for blue-purple, blue and red modulate
|
||||||
if (/*HH> -3.1415f &&*/ HH < -1.5f ) {
|
if (/*HH> -3.1415f &&*/ HH < -1.5f ) {
|
||||||
sathue[0] = 1.3f; //blue
|
sathue[0] = 1.3f; //blue
|
||||||
sathue[1] = 1.2f;
|
sathue[1] = 1.2f;
|
||||||
@@ -285,7 +286,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
sathue2[1] = 1.1f ;
|
sathue2[1] = 1.1f ;
|
||||||
sathue2[2] = 1.05f;
|
sathue2[2] = 1.05f;
|
||||||
sathue2[3] = 1.0f;
|
sathue2[3] = 1.0f;
|
||||||
} else if(/*HH>=-1.5f &&*/ HH < -0.7f ) {
|
} else if (/*HH>=-1.5f &&*/ HH < -0.7f ) {
|
||||||
sathue[0] = 1.6f; //blue purple 1.2 1.1
|
sathue[0] = 1.6f; //blue purple 1.2 1.1
|
||||||
sathue[1] = 1.4f;
|
sathue[1] = 1.4f;
|
||||||
sathue[2] = 1.3f;
|
sathue[2] = 1.3f;
|
||||||
@@ -295,7 +296,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
sathue2[1] = 1.15f;
|
sathue2[1] = 1.15f;
|
||||||
sathue2[2] = 1.1f ;
|
sathue2[2] = 1.1f ;
|
||||||
sathue2[3] = 1.0f;
|
sathue2[3] = 1.0f;
|
||||||
} else if(/*HH>=-0.7f &&*/ HH < 0.0f ) {
|
} else if (/*HH>=-0.7f &&*/ HH < 0.0f ) {
|
||||||
sathue[0] = 1.2f; //purple
|
sathue[0] = 1.2f; //purple
|
||||||
sathue[1] = 1.0f;
|
sathue[1] = 1.0f;
|
||||||
sathue[2] = 1.0f;
|
sathue[2] = 1.0f;
|
||||||
@@ -307,7 +308,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
sathue2[3] = 1.0f;
|
sathue2[3] = 1.0f;
|
||||||
}
|
}
|
||||||
// else if( HH>= 0.0f && HH<= 1.4f ) {sathue[0]=1.1f;sathue[1]=1.1f;sathue[2]=1.1f;sathue[3]=1.0f ;sathue[4]=0.4f;sathue2[0]=1.0f ;sathue2[1]=1.0f ;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//red 0.8 0.7
|
// else if( HH>= 0.0f && HH<= 1.4f ) {sathue[0]=1.1f;sathue[1]=1.1f;sathue[2]=1.1f;sathue[3]=1.0f ;sathue[4]=0.4f;sathue2[0]=1.0f ;sathue2[1]=1.0f ;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//red 0.8 0.7
|
||||||
else if(/*HH>= 0.0f &&*/ HH <= 1.4f ) {
|
else if (/*HH>= 0.0f &&*/ HH <= 1.4f ) {
|
||||||
sathue[0] = 1.3f; //red 0.8 0.7
|
sathue[0] = 1.3f; //red 0.8 0.7
|
||||||
sathue[1] = 1.2f;
|
sathue[1] = 1.2f;
|
||||||
sathue[2] = 1.1f;
|
sathue[2] = 1.1f;
|
||||||
@@ -317,7 +318,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
sathue2[1] = 1.0f ;
|
sathue2[1] = 1.0f ;
|
||||||
sathue2[2] = 1.0f ;
|
sathue2[2] = 1.0f ;
|
||||||
sathue2[3] = 1.0f;
|
sathue2[3] = 1.0f;
|
||||||
} else if(/*HH> 1.4f &&*/ HH <= 2.1f ) {
|
} else if (/*HH> 1.4f &&*/ HH <= 2.1f ) {
|
||||||
sathue[0] = 1.0f; //green yellow 1.2 1.1
|
sathue[0] = 1.0f; //green yellow 1.2 1.1
|
||||||
sathue[1] = 1.0f;
|
sathue[1] = 1.0f;
|
||||||
sathue[2] = 1.0f;
|
sathue[2] = 1.0f;
|
||||||
@@ -349,7 +350,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
sathue2[1] = 1.1f ;
|
sathue2[1] = 1.1f ;
|
||||||
sathue2[2] = 1.05f;
|
sathue2[2] = 1.05f;
|
||||||
sathue2[3] = 1.0f;
|
sathue2[3] = 1.0f;
|
||||||
} else if(/*HH>=-1.5f &&*/ HH < -0.7f ) {
|
} else if (/*HH>=-1.5f &&*/ HH < -0.7f ) {
|
||||||
sathue[0] = 1.3f; //blue purple 1.2 1.1
|
sathue[0] = 1.3f; //blue purple 1.2 1.1
|
||||||
sathue[1] = 1.2f;
|
sathue[1] = 1.2f;
|
||||||
sathue[2] = 1.1f;
|
sathue[2] = 1.1f;
|
||||||
@@ -359,7 +360,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
sathue2[1] = 1.05f;
|
sathue2[1] = 1.05f;
|
||||||
sathue2[2] = 1.0f ;
|
sathue2[2] = 1.0f ;
|
||||||
sathue2[3] = 1.0f;
|
sathue2[3] = 1.0f;
|
||||||
} else if(/*HH>=-0.7f &&*/ HH < 0.0f ) {
|
} else if (/*HH>=-0.7f &&*/ HH < 0.0f ) {
|
||||||
sathue[0] = 1.2f; //purple
|
sathue[0] = 1.2f; //purple
|
||||||
sathue[1] = 1.0f;
|
sathue[1] = 1.0f;
|
||||||
sathue[2] = 1.0f;
|
sathue[2] = 1.0f;
|
||||||
@@ -371,7 +372,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
sathue2[3] = 1.0f;
|
sathue2[3] = 1.0f;
|
||||||
}
|
}
|
||||||
// else if( HH>= 0.0f && HH<= 1.4f ) {sathue[0]=0.8f;sathue[1]=0.8f;sathue[2]=0.8f;sathue[3]=0.8f ;sathue[4]=0.4f;sathue2[0]=0.8f ;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7
|
// else if( HH>= 0.0f && HH<= 1.4f ) {sathue[0]=0.8f;sathue[1]=0.8f;sathue[2]=0.8f;sathue[3]=0.8f ;sathue[4]=0.4f;sathue2[0]=0.8f ;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7
|
||||||
else if(/*HH>= 0.0f &&*/ HH <= 1.4f ) {
|
else if (/*HH>= 0.0f &&*/ HH <= 1.4f ) {
|
||||||
sathue[0] = 1.1f; //red 0.8 0.7
|
sathue[0] = 1.1f; //red 0.8 0.7
|
||||||
sathue[1] = 1.0f;
|
sathue[1] = 1.0f;
|
||||||
sathue[2] = 0.9f;
|
sathue[2] = 0.9f;
|
||||||
@@ -381,7 +382,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
sathue2[1] = 0.8f ;
|
sathue2[1] = 0.8f ;
|
||||||
sathue2[2] = 0.8f ;
|
sathue2[2] = 0.8f ;
|
||||||
sathue2[3] = 0.8f;
|
sathue2[3] = 0.8f;
|
||||||
} else if(/*HH> 1.4f &&*/ HH <= 2.1f ) {
|
} else if (/*HH> 1.4f &&*/ HH <= 2.1f ) {
|
||||||
sathue[0] = 1.1f; //green yellow 1.2 1.1
|
sathue[0] = 1.1f; //green yellow 1.2 1.1
|
||||||
sathue[1] = 1.1f;
|
sathue[1] = 1.1f;
|
||||||
sathue[2] = 1.1f;
|
sathue[2] = 1.1f;
|
||||||
@@ -414,7 +415,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
sathue2[1] = 1.1f ;
|
sathue2[1] = 1.1f ;
|
||||||
sathue2[2] = 1.05f;
|
sathue2[2] = 1.05f;
|
||||||
sathue2[3] = 1.0f;
|
sathue2[3] = 1.0f;
|
||||||
} else if(/*HH>=-1.5f &&*/ HH < -0.7f ) {
|
} else if (/*HH>=-1.5f &&*/ HH < -0.7f ) {
|
||||||
sathue[0] = 1.3f; //blue purple 1.2 1.1
|
sathue[0] = 1.3f; //blue purple 1.2 1.1
|
||||||
sathue[1] = 1.2f;
|
sathue[1] = 1.2f;
|
||||||
sathue[2] = 1.15f;
|
sathue[2] = 1.15f;
|
||||||
@@ -424,7 +425,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
sathue2[1] = 1.05f;
|
sathue2[1] = 1.05f;
|
||||||
sathue2[2] = 1.0f ;
|
sathue2[2] = 1.0f ;
|
||||||
sathue2[3] = 1.0f;
|
sathue2[3] = 1.0f;
|
||||||
} else if(/*HH>=-0.7f &&*/ HH < 0.0f ) {
|
} else if (/*HH>=-0.7f &&*/ HH < 0.0f ) {
|
||||||
sathue[0] = 1.2f; //purple
|
sathue[0] = 1.2f; //purple
|
||||||
sathue[1] = 1.0f;
|
sathue[1] = 1.0f;
|
||||||
sathue[2] = 1.0f ;
|
sathue[2] = 1.0f ;
|
||||||
@@ -436,7 +437,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
sathue2[3] = 1.0f;
|
sathue2[3] = 1.0f;
|
||||||
}
|
}
|
||||||
// else if( HH>= 0.0f && HH<= 1.4f ) {sathue[0]=0.8f;sathue[1]=0.8f;sathue[2]=0.8f ;sathue[3]=0.8f ;sathue[4]=0.3f;sathue2[0]=0.8f ;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7
|
// else if( HH>= 0.0f && HH<= 1.4f ) {sathue[0]=0.8f;sathue[1]=0.8f;sathue[2]=0.8f ;sathue[3]=0.8f ;sathue[4]=0.3f;sathue2[0]=0.8f ;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7
|
||||||
else if(/*HH>= 0.0f &&*/ HH <= 1.4f ) {
|
else if (/*HH>= 0.0f &&*/ HH <= 1.4f ) {
|
||||||
sathue[0] = 1.1f; //red 0.8 0.7
|
sathue[0] = 1.1f; //red 0.8 0.7
|
||||||
sathue[1] = 1.0f;
|
sathue[1] = 1.0f;
|
||||||
sathue[2] = 0.9f ;
|
sathue[2] = 0.9f ;
|
||||||
@@ -446,7 +447,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
sathue2[1] = 0.8f ;
|
sathue2[1] = 0.8f ;
|
||||||
sathue2[2] = 0.8f ;
|
sathue2[2] = 0.8f ;
|
||||||
sathue2[3] = 0.8f;
|
sathue2[3] = 0.8f;
|
||||||
} else if(/*HH> 1.4f &&*/ HH <= 2.1f ) {
|
} else if (/*HH> 1.4f &&*/ HH <= 2.1f ) {
|
||||||
sathue[0] = 1.3f; //green yellow 1.2 1.1
|
sathue[0] = 1.3f; //green yellow 1.2 1.1
|
||||||
sathue[1] = 1.2f;
|
sathue[1] = 1.2f;
|
||||||
sathue[2] = 1.1f ;
|
sathue[2] = 1.1f ;
|
||||||
@@ -478,7 +479,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
sathue2[1] = 0.8f ;
|
sathue2[1] = 0.8f ;
|
||||||
sathue2[2] = 0.8f ;
|
sathue2[2] = 0.8f ;
|
||||||
sathue2[3] = 0.8f;
|
sathue2[3] = 0.8f;
|
||||||
} else if(/*HH>=-1.5f &&*/ HH < -0.7f ) {
|
} else if (/*HH>=-1.5f &&*/ HH < -0.7f ) {
|
||||||
sathue[0] = 1.0f; //blue purple 1.2 1.1
|
sathue[0] = 1.0f; //blue purple 1.2 1.1
|
||||||
sathue[1] = 1.0f;
|
sathue[1] = 1.0f;
|
||||||
sathue[2] = 0.9f;
|
sathue[2] = 0.9f;
|
||||||
@@ -488,7 +489,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
sathue2[1] = 0.8f ;
|
sathue2[1] = 0.8f ;
|
||||||
sathue2[2] = 0.8f ;
|
sathue2[2] = 0.8f ;
|
||||||
sathue2[3] = 0.8f;
|
sathue2[3] = 0.8f;
|
||||||
} else if(/*HH>=-0.7f &&*/ HH < 0.0f ) {
|
} else if (/*HH>=-0.7f &&*/ HH < 0.0f ) {
|
||||||
sathue[0] = 1.2f; //purple
|
sathue[0] = 1.2f; //purple
|
||||||
sathue[1] = 1.0f;
|
sathue[1] = 1.0f;
|
||||||
sathue[2] = 1.0f;
|
sathue[2] = 1.0f;
|
||||||
@@ -500,7 +501,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
sathue2[3] = 0.8f;
|
sathue2[3] = 0.8f;
|
||||||
}
|
}
|
||||||
// else if( HH>= 0.0f && HH<= 1.4f ) {sathue[0]=0.8f;sathue[1]=0.8f;sathue[2]=0.8f;sathue[3]=0.8f;sathue[4]=0.2f;sathue2[0]=0.8f;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7
|
// else if( HH>= 0.0f && HH<= 1.4f ) {sathue[0]=0.8f;sathue[1]=0.8f;sathue[2]=0.8f;sathue[3]=0.8f;sathue[4]=0.2f;sathue2[0]=0.8f;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7
|
||||||
else if(/*HH>= 0.0f &&*/ HH <= 1.4f ) {
|
else if (/*HH>= 0.0f &&*/ HH <= 1.4f ) {
|
||||||
sathue[0] = 1.1f; //red 0.8 0.7
|
sathue[0] = 1.1f; //red 0.8 0.7
|
||||||
sathue[1] = 1.0f;
|
sathue[1] = 1.0f;
|
||||||
sathue[2] = 0.9f;
|
sathue[2] = 0.9f;
|
||||||
@@ -510,7 +511,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
sathue2[1] = 0.8f ;
|
sathue2[1] = 0.8f ;
|
||||||
sathue2[2] = 0.8f ;
|
sathue2[2] = 0.8f ;
|
||||||
sathue2[3] = 0.8f;
|
sathue2[3] = 0.8f;
|
||||||
} else if(/*HH> 1.4f &&*/ HH <= 2.1f ) {
|
} else if (/*HH> 1.4f &&*/ HH <= 2.1f ) {
|
||||||
sathue[0] = 1.6f; //green yellow 1.2 1.1
|
sathue[0] = 1.6f; //green yellow 1.2 1.1
|
||||||
sathue[1] = 1.5f;
|
sathue[1] = 1.5f;
|
||||||
sathue[2] = 1.4f;
|
sathue[2] = 1.4f;
|
||||||
@@ -534,7 +535,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float chmodpastel, chmodsat;
|
float chmodpastel = 0.f, chmodsat = 0.f;
|
||||||
// variables to improve transitions
|
// variables to improve transitions
|
||||||
float pa, pb;// transition = pa*saturation + pb
|
float pa, pb;// transition = pa*saturation + pb
|
||||||
float chl00 = chromaPastel * satredu * sathue[4];
|
float chl00 = chromaPastel * satredu * sathue[4];
|
||||||
@@ -585,16 +586,16 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
chmodsat = pa * saturation + pb;
|
chmodsat = pa * saturation + pb;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(chromaPastel != chromaSatur) {
|
if (chromaPastel != chromaSatur) {
|
||||||
|
|
||||||
// Pastels
|
// Pastels
|
||||||
if(saturation > p2 && saturation < limitpastelsatur) {
|
if (saturation > p2 && saturation < limitpastelsatur) {
|
||||||
float newchromaPastel = chromaPastel_a * saturation + chromaPastel_b;
|
float newchromaPastel = chromaPastel_a * saturation + chromaPastel_b;
|
||||||
chmodpastel = newchromaPastel * satredu * sathue[3];
|
chmodpastel = newchromaPastel * satredu * sathue[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Saturated
|
// Saturated
|
||||||
if(saturation < s0 && saturation >= limitpastelsatur) {
|
if (saturation < s0 && saturation >= limitpastelsatur) {
|
||||||
float newchromaSatur = chromaSatur_a * saturation + chromaSatur_b;
|
float newchromaSatur = chromaSatur_a * saturation + chromaSatur_b;
|
||||||
chmodsat = newchromaSatur * satredu * sathue2[0];
|
chmodsat = newchromaSatur * satredu * sathue2[0];
|
||||||
}
|
}
|
||||||
@@ -603,25 +604,25 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
if (saturation <= limitpastelsatur) {
|
if (saturation <= limitpastelsatur) {
|
||||||
if (chmodpastel > 2.0f ) {
|
if (chmodpastel > 2.0f ) {
|
||||||
chmodpastel = 2.0f; //avoid too big values
|
chmodpastel = 2.0f; //avoid too big values
|
||||||
} else if(chmodpastel < -0.93f) {
|
} else if (chmodpastel < -0.93f) {
|
||||||
chmodpastel = -0.93f; //avoid negative values
|
chmodpastel = -0.93f; //avoid negative values
|
||||||
}
|
}
|
||||||
|
|
||||||
Chprov *= (1.0f + chmodpastel);
|
Chprov *= (1.0f + chmodpastel);
|
||||||
|
|
||||||
if(Chprov < 6.0f) {
|
if (Chprov < 6.0f) {
|
||||||
Chprov = 6.0f;
|
Chprov = 6.0f;
|
||||||
}
|
}
|
||||||
} else { //if (saturation > limitpastelsatur)
|
} else { //if (saturation > limitpastelsatur)
|
||||||
if (chmodsat > 1.8f ) {
|
if (chmodsat > 1.8f ) {
|
||||||
chmodsat = 1.8f; //saturated
|
chmodsat = 1.8f; //saturated
|
||||||
} else if(chmodsat < -0.93f) {
|
} else if (chmodsat < -0.93f) {
|
||||||
chmodsat = -0.93f;
|
chmodsat = -0.93f;
|
||||||
}
|
}
|
||||||
|
|
||||||
Chprov *= 1.0f + chmodsat;
|
Chprov *= 1.0f + chmodsat;
|
||||||
|
|
||||||
if(Chprov < 6.0f) {
|
if (Chprov < 6.0f) {
|
||||||
Chprov = 6.0f;
|
Chprov = 6.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -631,15 +632,15 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
bool hhModified = false;
|
bool hhModified = false;
|
||||||
|
|
||||||
// Vibrance's Skin curve
|
// Vibrance's Skin curve
|
||||||
if(skinCurveIsSet) {
|
if (skinCurveIsSet) {
|
||||||
if (HH > skbeg && HH < skend) {
|
if (HH > skbeg && HH < skend) {
|
||||||
if(Chprov < 60.0f) {//skin hue : todo ==> transition
|
if (Chprov < 60.0f) { //skin hue : todo ==> transition
|
||||||
float HHsk = ask * HH + bsk;
|
float HHsk = ask * HH + bsk;
|
||||||
float Hn = (skin_curve[HHsk] - bsk) / ask;
|
float Hn = (skin_curve[HHsk] - bsk) / ask;
|
||||||
float Hc = (Hn * xx + HH * (1.0f - xx));
|
float Hc = (Hn * xx + HH * (1.0f - xx));
|
||||||
HH = Hc;
|
HH = Hc;
|
||||||
hhModified = true;
|
hhModified = true;
|
||||||
} else if(Chprov < (60.0f + dchr)) { //transition chroma
|
} else if (Chprov < (60.0f + dchr)) { //transition chroma
|
||||||
float HHsk = ask * HH + bsk;
|
float HHsk = ask * HH + bsk;
|
||||||
float Hn = (skin_curve[HHsk] - bsk) / ask;
|
float Hn = (skin_curve[HHsk] - bsk) / ask;
|
||||||
float Hc = (Hn * xx + HH * (1.0f - xx));
|
float Hc = (Hn * xx + HH * (1.0f - xx));
|
||||||
@@ -650,7 +651,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//transition hue
|
//transition hue
|
||||||
else if(HH > (skbeg - dhue) && HH <= skbeg && Chprov < (60.0f + dchr * 0.5f)) {
|
else if (HH > (skbeg - dhue) && HH <= skbeg && Chprov < (60.0f + dchr * 0.5f)) {
|
||||||
float HHsk = ask * skbeg + bsk;
|
float HHsk = ask * skbeg + bsk;
|
||||||
float Hn = (skin_curve[HHsk] - bsk) / ask;
|
float Hn = (skin_curve[HHsk] - bsk) / ask;
|
||||||
float Hcc = (Hn * xx + skbeg * (1.0f - xx));
|
float Hcc = (Hn * xx + skbeg * (1.0f - xx));
|
||||||
@@ -658,7 +659,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
float bdh = Hcc - adh * skbeg;
|
float bdh = Hcc - adh * skbeg;
|
||||||
HH = adh * HH + bdh;
|
HH = adh * HH + bdh;
|
||||||
hhModified = true;
|
hhModified = true;
|
||||||
} else if(HH >= skend && HH < (skend + dhue) && Chprov < (60.0f + dchr * 0.5f)) {
|
} else if (HH >= skend && HH < (skend + dhue) && Chprov < (60.0f + dchr * 0.5f)) {
|
||||||
float HHsk = ask * skend + bsk;
|
float HHsk = ask * skend + bsk;
|
||||||
float Hn = (skin_curve[HHsk] - bsk) / ask;
|
float Hn = (skin_curve[HHsk] - bsk) / ask;
|
||||||
float Hcc = (Hn * xx + skend * (1.0f - xx));
|
float Hcc = (Hn * xx + skend * (1.0f - xx));
|
||||||
@@ -671,8 +672,8 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
|
|
||||||
//Munsell correction
|
//Munsell correction
|
||||||
// float2 sincosval;
|
// float2 sincosval;
|
||||||
if(!avoidcolorshift && hhModified) {
|
if (!avoidcolorshift && hhModified) {
|
||||||
sincosval = xsincosf(HH);
|
sincosval = xsincosf (HH);
|
||||||
}
|
}
|
||||||
|
|
||||||
float aprovn, bprovn;
|
float aprovn, bprovn;
|
||||||
@@ -681,18 +682,18 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
do {
|
do {
|
||||||
inGamut = true;
|
inGamut = true;
|
||||||
|
|
||||||
if(avoidcolorshift) {
|
if (avoidcolorshift) {
|
||||||
float correctionHue = 0.0f;
|
float correctionHue = 0.0f;
|
||||||
float correctlum = 0.0f;
|
float correctlum = 0.0f;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
Color::AllMunsellLch(/*lumaMuns*/false, Lprov, Lprov, HH, Chprov, CC, correctionHue, correctlum, MunsDebugInfo);
|
Color::AllMunsellLch (/*lumaMuns*/false, Lprov, Lprov, HH, Chprov, CC, correctionHue, correctlum, MunsDebugInfo);
|
||||||
#else
|
#else
|
||||||
Color::AllMunsellLch(/*lumaMuns*/false, Lprov, Lprov, HH, Chprov, CC, correctionHue, correctlum);
|
Color::AllMunsellLch (/*lumaMuns*/false, Lprov, Lprov, HH, Chprov, CC, correctionHue, correctlum);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(correctionHue != 0.f || hhModified) {
|
if (correctionHue != 0.f || hhModified) {
|
||||||
sincosval = xsincosf(HH + correctionHue);
|
sincosval = xsincosf (HH + correctionHue);
|
||||||
hhModified = false;
|
hhModified = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -703,14 +704,14 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
float fyy = (0.00862069f * Lprov ) + 0.137932f;
|
float fyy = (0.00862069f * Lprov ) + 0.137932f;
|
||||||
float fxx = (0.002f * aprovn) + fyy;
|
float fxx = (0.002f * aprovn) + fyy;
|
||||||
float fzz = fyy - (0.005f * bprovn);
|
float fzz = fyy - (0.005f * bprovn);
|
||||||
float xx_ = 65535.f * Color::f2xyz(fxx) * Color::D50x;
|
float xx_ = 65535.f * Color::f2xyz (fxx) * Color::D50x;
|
||||||
// float yy_ = 65535.0f * Color::f2xyz(fyy);
|
// float yy_ = 65535.0f * Color::f2xyz(fyy);
|
||||||
float zz_ = 65535.f * Color::f2xyz(fzz) * Color::D50z;
|
float zz_ = 65535.f * Color::f2xyz (fzz) * Color::D50z;
|
||||||
float yy_ = 65535.f * ((Lprov > Color::epskap) ? fyy * fyy*fyy : Lprov / Color::kappa);
|
float yy_ = 65535.f * ((Lprov > Color::epskap) ? fyy * fyy*fyy : Lprov / Color::kappa);
|
||||||
|
|
||||||
Color::xyz2rgb(xx_, yy_, zz_, R, G, B, wip);
|
Color::xyz2rgb (xx_, yy_, zz_, R, G, B, wip);
|
||||||
|
|
||||||
if(R < 0.0f || G < 0.0f || B < 0.0f) {
|
if (R < 0.0f || G < 0.0f || B < 0.0f) {
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
negsat++;
|
negsat++;
|
||||||
#endif
|
#endif
|
||||||
@@ -719,7 +720,7 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if "highlight reconstruction" enabled don't control Gamut for highlights
|
// if "highlight reconstruction" enabled don't control Gamut for highlights
|
||||||
if((!highlight) && (R > 65535.0f || G > 65535.0f || B > 65535.0f)) {
|
if ((!highlight) && (R > 65535.0f || G > 65535.0f || B > 65535.0f)) {
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
moresat++;
|
moresat++;
|
||||||
#endif
|
#endif
|
||||||
@@ -740,11 +741,11 @@ void ImProcFunctions::vibrance (LabImage* lab)
|
|||||||
t2e.set();
|
t2e.set();
|
||||||
|
|
||||||
if (settings->verbose) {
|
if (settings->verbose) {
|
||||||
printf("Vibrance (performed in %d usec):\n", t2e.etime(t1e));
|
printf ("Vibrance (performed in %d usec):\n", t2e.etime (t1e));
|
||||||
printf(" Gamut: G1negat=%iiter G165535=%iiter G2negsat=%iiter G265535=%iiter\n", negat, moreRGB, negsat, moresat);
|
printf (" Gamut: G1negat=%iiter G165535=%iiter G2negsat=%iiter G265535=%iiter\n", negat, moreRGB, negsat, moresat);
|
||||||
|
|
||||||
if (MunsDebugInfo) {
|
if (MunsDebugInfo) {
|
||||||
printf(" Munsell chrominance: MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad depass=%u\n", MunsDebugInfo->maxdhue[0], MunsDebugInfo->maxdhue[1], MunsDebugInfo->maxdhue[2], MunsDebugInfo->maxdhue[3], MunsDebugInfo->depass);
|
printf (" Munsell chrominance: MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad depass=%u\n", MunsDebugInfo->maxdhue[0], MunsDebugInfo->maxdhue[1], MunsDebugInfo->maxdhue[2], MunsDebugInfo->maxdhue[3], MunsDebugInfo->depass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user