Speedups for B&W conversion
This commit is contained in:
parent
d9d539cbb3
commit
6d4e82b94f
@ -24,6 +24,8 @@
|
|||||||
#include "sleef.c"
|
#include "sleef.c"
|
||||||
#include "opthelper.h"
|
#include "opthelper.h"
|
||||||
|
|
||||||
|
#define pow_F(a,b) (xexpf(b*xlogf(a)))
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
@ -857,6 +859,14 @@ void Color::xyz2rgb (float x, float y, float z, float &r, float &g, float &b, co
|
|||||||
b = ((rgb_xyz[2][0] * x + rgb_xyz[2][1] * y + rgb_xyz[2][2] * z)) ;
|
b = ((rgb_xyz[2][0] * x + rgb_xyz[2][1] * y + rgb_xyz[2][2] * z)) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Color::xyz2r (float x, float y, float z, float &r, const double rgb_xyz[3][3]) // for black & white we need only r channel
|
||||||
|
{
|
||||||
|
//Transform to output color. Standard sRGB is D65, but internal representation is D50
|
||||||
|
//Note that it is only at this point that we should have need of clipping color data
|
||||||
|
|
||||||
|
r = ((rgb_xyz[0][0] * x + rgb_xyz[0][1] * y + rgb_xyz[0][2] * z)) ;
|
||||||
|
}
|
||||||
|
|
||||||
// same for float
|
// same for float
|
||||||
void Color::xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const float rgb_xyz[3][3])
|
void Color::xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const float rgb_xyz[3][3])
|
||||||
{
|
{
|
||||||
@ -874,19 +884,39 @@ void Color::xyz2rgb (vfloat x, vfloat y, vfloat z, vfloat &r, vfloat &g, vfloat
|
|||||||
}
|
}
|
||||||
#endif // __SSE2__
|
#endif // __SSE2__
|
||||||
|
|
||||||
|
#ifdef __SSE2__
|
||||||
|
void Color::trcGammaBW (float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb)
|
||||||
|
{
|
||||||
|
// correct gamma for black and white image : pseudo TRC curve of ICC profil
|
||||||
|
vfloat rgbv = _mm_set_ps(0.f, b, g, r);
|
||||||
|
vfloat gammabwv = _mm_set_ps(0.f, gammabwb, gammabwg, gammabwr);
|
||||||
|
vfloat c65535v = F2V(65535.f);
|
||||||
|
rgbv /= c65535v;
|
||||||
|
rgbv = vmaxf(rgbv, ZEROV);
|
||||||
|
rgbv = pow_F(rgbv, gammabwv);
|
||||||
|
rgbv *= c65535v;
|
||||||
|
float temp[4] ALIGNED16;
|
||||||
|
STVF(temp[0], rgbv);
|
||||||
|
r = temp[0];
|
||||||
|
g = temp[1];
|
||||||
|
b = temp[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
void Color::trcGammaBW (float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb)
|
void Color::trcGammaBW (float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb)
|
||||||
{
|
{
|
||||||
// correct gamma for black and white image : pseudo TRC curve of ICC profil
|
// correct gamma for black and white image : pseudo TRC curve of ICC profil
|
||||||
b /= 65535.0f;
|
b /= 65535.0f;
|
||||||
b = pow (max(b, 0.0f), gammabwb);
|
b = pow_F (max(b, 0.0f), gammabwb);
|
||||||
b *= 65535.0f;
|
b *= 65535.0f;
|
||||||
r /= 65535.0f;
|
r /= 65535.0f;
|
||||||
r = pow (max(r, 0.0f), gammabwr);
|
r = pow_F (max(r, 0.0f), gammabwr);
|
||||||
r *= 65535.0f;
|
r *= 65535.0f;
|
||||||
g /= 65535.0f;
|
g /= 65535.0f;
|
||||||
g = pow (max(g, 0.0f), gammabwg);
|
g = pow_F (max(g, 0.0f), gammabwg);
|
||||||
g *= 65535.0f;
|
g *= 65535.0f;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/** @brief Compute the B&W constants for the B&W processing and its tool's GUI
|
/** @brief Compute the B&W constants for the B&W processing and its tool's GUI
|
||||||
*
|
*
|
||||||
@ -1492,6 +1522,17 @@ void Color::Lab2XYZ(float L, float a, float b, float &x, float &y, float &z)
|
|||||||
y = (LL > epskap) ? 65535.0f * fy * fy * fy : 65535.0f * LL / kappa;
|
y = (LL > epskap) ? 65535.0f * fy * fy * fy : 65535.0f * LL / kappa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Color::L2XYZ(float L, float &x, float &y, float &z) // for black & white
|
||||||
|
{
|
||||||
|
float LL = L / 327.68f;
|
||||||
|
float fy = (0.00862069f * LL) + 0.137932f; // (L+16)/116
|
||||||
|
float fxz = 65535.f * f2xyz(fy);
|
||||||
|
x = fxz * D50x;
|
||||||
|
z = fxz * D50z;
|
||||||
|
y = (LL > epskap) ? 65535.0f * fy * fy * fy : 65535.0f * LL / kappa;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
void Color::Lab2XYZ(vfloat L, vfloat a, vfloat b, vfloat &x, vfloat &y, vfloat &z)
|
void Color::Lab2XYZ(vfloat L, vfloat a, vfloat b, vfloat &x, vfloat &y, vfloat &z)
|
||||||
{
|
{
|
||||||
|
@ -408,6 +408,7 @@ public:
|
|||||||
* @param rgb_xyz[3][3] transformation matrix to use for the conversion
|
* @param rgb_xyz[3][3] transformation matrix to use for the conversion
|
||||||
*/
|
*/
|
||||||
static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const double rgb_xyz[3][3]);
|
static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const double rgb_xyz[3][3]);
|
||||||
|
static void xyz2r (float x, float y, float z, float &r, const double rgb_xyz[3][3]);
|
||||||
static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const float rgb_xyz[3][3]);
|
static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const float rgb_xyz[3][3]);
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
static void xyz2rgb (vfloat x, vfloat y, vfloat z, vfloat &r, vfloat &g, vfloat &b, const vfloat rgb_xyz[3][3]);
|
static void xyz2rgb (vfloat x, vfloat y, vfloat z, vfloat &r, vfloat &g, vfloat &b, const vfloat rgb_xyz[3][3]);
|
||||||
@ -441,6 +442,7 @@ public:
|
|||||||
* @param z Z coordinate [0 ; 65535] ; can be negative! (return value)
|
* @param z Z coordinate [0 ; 65535] ; can be negative! (return value)
|
||||||
*/
|
*/
|
||||||
static void Lab2XYZ(float L, float a, float b, float &x, float &y, float &z);
|
static void Lab2XYZ(float L, float a, float b, float &x, float &y, float &z);
|
||||||
|
static void L2XYZ(float L, float &x, float &y, float &z);
|
||||||
|
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
static void Lab2XYZ(vfloat L, vfloat a, vfloat b, vfloat &x, vfloat &y, vfloat &z);
|
static void Lab2XYZ(vfloat L, vfloat a, vfloat b, vfloat &x, vfloat &y, vfloat &z);
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
#include "improccoordinator.h"
|
#include "improccoordinator.h"
|
||||||
#include "clutstore.h"
|
#include "clutstore.h"
|
||||||
#include "ciecam02.h"
|
#include "ciecam02.h"
|
||||||
//#define BENCHMARK
|
#define BENCHMARK
|
||||||
#include "StopWatch.h"
|
#include "StopWatch.h"
|
||||||
#include "../rtgui/ppversion.h"
|
#include "../rtgui/ppversion.h"
|
||||||
#include "../rtgui/guiutils.h"
|
#include "../rtgui/guiutils.h"
|
||||||
@ -4127,23 +4127,26 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
|
|||||||
} else if (algm == 1) { //Luminance mixer in Lab mode to avoid artifacts
|
} else if (algm == 1) { //Luminance mixer in Lab mode to avoid artifacts
|
||||||
for (int i = istart, ti = 0; i < tH; i++, ti++) {
|
for (int i = istart, ti = 0; i < tH; i++, ti++) {
|
||||||
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
|
for (int j = jstart, tj = 0; j < tW; j++, tj++) {
|
||||||
//rgb=>lab
|
//rgb => xyz
|
||||||
float r = rtemp[ti * TS + tj];
|
|
||||||
float g = gtemp[ti * TS + tj];
|
|
||||||
float b = btemp[ti * TS + tj];
|
|
||||||
float X, Y, Z;
|
float X, Y, Z;
|
||||||
|
Color::rgbxyz(rtemp[ti * TS + tj], gtemp[ti * TS + tj], btemp[ti * TS + tj], X, Y, Z, wp);
|
||||||
|
//xyz => Lab
|
||||||
float L, aa, bb;
|
float L, aa, bb;
|
||||||
Color::rgbxyz(r, g, b, X, Y, Z, wp);
|
|
||||||
//convert Lab
|
|
||||||
Color::XYZ2Lab(X, Y, Z, L, aa, bb);
|
Color::XYZ2Lab(X, Y, Z, L, aa, bb);
|
||||||
//end rgb=>lab
|
float CC = sqrtf(SQR(aa) + SQR(bb)) / 327.68f; //CC chromaticity in 0..180 or more
|
||||||
//lab ==> Ch
|
|
||||||
float CC = sqrt(SQR(aa / 327.68f) + SQR(bb / 327.68f)); //CC chromaticity in 0..180 or more
|
|
||||||
float HH = xatan2f(bb, aa); // HH hue in -3.141 +3.141
|
float HH = xatan2f(bb, aa); // HH hue in -3.141 +3.141
|
||||||
float l_r;//Luminance Lab in 0..1
|
float2 sincosval;
|
||||||
l_r = L / 32768.f;
|
|
||||||
|
if(CC == 0.0f) {
|
||||||
|
sincosval.y = 1.f;
|
||||||
|
sincosval.x = 0.0f;
|
||||||
|
} else {
|
||||||
|
sincosval.y = aa / (CC * 327.68f);
|
||||||
|
sincosval.x = bb / (CC * 327.68f);
|
||||||
|
}
|
||||||
|
|
||||||
if (bwlCurveEnabled) {
|
if (bwlCurveEnabled) {
|
||||||
|
L /= 32768.f;
|
||||||
double hr = Color::huelab_to_huehsv2(HH);
|
double hr = Color::huelab_to_huehsv2(HH);
|
||||||
float valparam = float((bwlCurve->getVal(hr) - 0.5f) * 2.0f); //get l_r=f(H)
|
float valparam = float((bwlCurve->getVal(hr) - 0.5f) * 2.0f); //get l_r=f(H)
|
||||||
float kcc = (CC / 70.f); //take Chroma into account...70 "middle" of chromaticity (arbitrary and simple), one can imagine other algorithme
|
float kcc = (CC / 70.f); //take Chroma into account...70 "middle" of chromaticity (arbitrary and simple), one can imagine other algorithme
|
||||||
@ -4151,47 +4154,35 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
|
|||||||
valparam *= kcc;
|
valparam *= kcc;
|
||||||
|
|
||||||
if(valparam > 0.f) {
|
if(valparam > 0.f) {
|
||||||
l_r = (1.f - valparam) * l_r + valparam * (1.f - SQR(SQR(SQR(SQR(1.f - min(l_r, 1.0f)))))); // SQR (SQR((SQR) to increase action in low light
|
L = (1.f - valparam) * L + valparam * (1.f - SQR(SQR(SQR(SQR(1.f - min(L, 1.0f)))))); // SQR (SQR((SQR) to increase action in low light
|
||||||
} else {
|
} else {
|
||||||
l_r *= (1.f + valparam); //for negative
|
L *= (1.f + valparam); //for negative
|
||||||
}
|
}
|
||||||
|
L *= 32768.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
L = l_r * 32768.f;
|
|
||||||
float RR, GG, BB;
|
float RR, GG, BB;
|
||||||
float Lr;
|
L /= 327.68f;
|
||||||
Lr = L / 327.68f; //for gamutlch
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
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, Lr, CC, RR, GG, BB, wip, highlight, 0.15f, 0.96f, neg, more_rgb);
|
Color::gamutLchonly(HH, sincosval, L, CC, RR, GG, BB, wip, highlight, 0.15f, 0.96f, neg, more_rgb);
|
||||||
#else
|
#else
|
||||||
//gamut control : Lab values are in gamut
|
//gamut control : Lab values are in gamut
|
||||||
Color::gamutLchonly(HH, Lr, CC, RR, GG, BB, wip, highlight, 0.15f, 0.96f);
|
Color::gamutLchonly(HH, sincosval, L, CC, RR, GG, BB, wip, highlight, 0.15f, 0.96f);
|
||||||
#endif
|
#endif
|
||||||
//convert CH ==> ab
|
L *= 327.68f;
|
||||||
L = Lr * 327.68f;
|
//convert l => rgb
|
||||||
// float a_,b_;
|
Color::L2XYZ(L, X, Y, Z);
|
||||||
// a_=0.f;//grey
|
float newRed; // We use the red channel for bw
|
||||||
// b_=0.f;//grey
|
Color::xyz2r(X, Y, Z, newRed, wip);
|
||||||
//convert lab=>rgb
|
rtemp[ti * TS + tj] = gtemp[ti * TS + tj] = btemp[ti * TS + tj] = newRed;
|
||||||
Color::Lab2XYZ(L, 0.f, 0.f, X, Y, Z);
|
|
||||||
float rr_, gg_, bb_;
|
|
||||||
Color::xyz2rgb(X, Y, Z, rr_, gg_, bb_, wip);
|
|
||||||
rtemp[ti * TS + tj] = gtemp[ti * TS + tj] = btemp[ti * TS + tj] = rr_;
|
|
||||||
// tmpImage->r(i,j) = tmpImage->g(i,j) = tmpImage->b(i,j) = CLIP(val[0]*kcorec);
|
|
||||||
|
|
||||||
if (hasgammabw) {
|
if (hasgammabw) {
|
||||||
|
//gamma correction: pseudo TRC curve
|
||||||
Color::trcGammaBW (rtemp[ti * TS + tj], gtemp[ti * TS + tj], btemp[ti * TS + tj], gammabwr, gammabwg, gammabwb);
|
Color::trcGammaBW (rtemp[ti * TS + tj], gtemp[ti * TS + tj], btemp[ti * TS + tj], gammabwr, gammabwg, gammabwb);
|
||||||
}
|
}
|
||||||
|
|
||||||
//gamma correction: pseudo TRC curve
|
|
||||||
// if (hasgammabw)
|
|
||||||
// Color::trcGammaBW (rr_, gg_, bb_, gammabwr, gammabwg, gammabwb);
|
|
||||||
// rtemp[ti*TS+tj] = rr_;
|
|
||||||
// gtemp[ti*TS+tj] = gg_;
|
|
||||||
// btemp[ti*TS+tj] = bb_;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user