dcp speedup cleanup

This commit is contained in:
heckflosse 2016-06-10 18:30:07 +02:00
parent eedb9f39bc
commit b8749f8484
4 changed files with 120 additions and 125 deletions

View File

@ -231,10 +231,14 @@ public:
*/ */
static void rgb2hsv (float r, float g, float b, float &h, float &s, float &v); static void rgb2hsv (float r, float g, float b, float &h, float &s, float &v);
static inline void rgb2hsvdcp(float r, float g, float b, float &h, float &s, float &v) static inline bool rgb2hsvdcp(float r, float g, float b, float &h, float &s, float &v)
{ {
float var_Min = min(r, g, b); float var_Min = min(r, g, b);
if(var_Min < 0.f) {
return false;
} else {
float var_Max = max(r, g, b); float var_Max = max(r, g, b);
float del_Max = var_Max - var_Min; float del_Max = var_Max - var_Min;
v = var_Max / 65535.f; v = var_Max / 65535.f;
@ -259,6 +263,9 @@ public:
h -= 6.f; h -= 6.f;
} }
} }
return true;
}
} }
/** /**
@ -275,8 +282,8 @@ public:
static inline void hsv2rgbdcp (float h, float s, float v, float &r, float &g, float &b) static inline void hsv2rgbdcp (float h, float s, float v, float &r, float &g, float &b)
{ {
// special version for dcp which saves 1 division (in caller) and six multiplications (inside this function) // special version for dcp which saves 1 division (in caller) and six multiplications (inside this function)
int i = h; // sector 0 to 5, floor() is very slow, and h is always >0 int sector = h; // sector 0 to 5, floor() is very slow, and h is always >0
float f = h - i; // fractional part of h float f = h - sector; // fractional part of h
v *= 65535.f; v *= 65535.f;
float vs = v * s; float vs = v * s;
@ -284,32 +291,44 @@ static inline void hsv2rgbdcp (float h, float s, float v, float &r, float &g, fl
float q = v - f * vs; float q = v - f * vs;
float t = p + v - q; float t = p + v - q;
if (i == 1) { switch (sector) {
case 1:
r = q; r = q;
g = v; g = v;
b = p; b = p;
} else if (i == 2) { break;
case 2:
r = p; r = p;
g = v; g = v;
b = t; b = t;
} else if (i == 3) { break;
case 3:
r = p; r = p;
g = q; g = q;
b = v; b = v;
} else if (i == 4) { break;
case 4:
r = t; r = t;
g = p; g = p;
b = v; b = v;
} else if (i == 5) { break;
case 5:
r = v; r = v;
g = p; g = p;
b = q; b = q;
} else { /*i==(0|6)*/ break;
default:
r = v; r = v;
g = t; g = t;
b = p; b = p;
} }
} }
static void hsv2rgb (float h, float s, float v, int &r, int &g, int &b); static void hsv2rgb (float h, float s, float v, int &r, int &g, int &b);

View File

@ -35,25 +35,6 @@ namespace
{ {
// This sRGB gamma is taken from DNG reference code, with the added linear extension past 1.0, as we run clipless here // This sRGB gamma is taken from DNG reference code, with the added linear extension past 1.0, as we run clipless here
float srgbGammaForward(float x)
{
return
x <= 0.0031308f
? x * 12.92f
: x > 1.0f
? 1.0f + (x - 1.0f) * (1.055f * (1.0f / 2.4f)) // Linear extension
: 1.055f * pow(x, 1.0f / 2.4f) - 0.055f;
}
float srgbGammaInverse(float y)
{
return
y <= 0.0031308f * 12.92f
? y * (1.0f / 12.92f)
: y > 1.0f
? 1.0f + (y - 1.0f) / (1.055f * (1.0f / 2.4f))
: pow ((y + 0.055f) * (1.0f / 1.055f), 2.4f);
}
void invert3x3(const DCPProfile::Matrix& a, DCPProfile::Matrix& b) void invert3x3(const DCPProfile::Matrix& a, DCPProfile::Matrix& b)
{ {
@ -146,7 +127,8 @@ void mapWhiteMatrix(const DCPProfile::Triple& white1, const DCPProfile::Triple&
{ 0.8951, 0.2664, -0.1614 }, { 0.8951, 0.2664, -0.1614 },
{ -0.7502, 1.7135, 0.0367 }, { -0.7502, 1.7135, 0.0367 },
{ 0.0389, -0.0685, 1.0296 } { 0.0389, -0.0685, 1.0296 }
}}; }
};
DCPProfile::Triple w1; DCPProfile::Triple w1;
multiply3x3_v3(mb, white1, w1); multiply3x3_v3(mb, white1, w1);
@ -1019,9 +1001,7 @@ void DCPProfile::apply(
const ColorTemp& white_balance, const ColorTemp& white_balance,
const Triple& pre_mul, const Triple& pre_mul,
const Matrix& cam_wb_matrix, const Matrix& cam_wb_matrix,
bool use_tone_curve, bool apply_hue_sat_map
bool apply_hue_sat_map,
bool apply_look_table
) const ) const
{ {
BENCHFUN BENCHFUN
@ -1036,15 +1016,9 @@ void DCPProfile::apply(
apply_hue_sat_map = false; apply_hue_sat_map = false;
} }
if (look_table.empty()) { if (!apply_hue_sat_map) {
apply_look_table = false; // The fast path: No LUT --> Calculate matrix for direct conversion raw -> working space
} float mat[3][3] = {};
use_tone_curve = use_tone_curve && tone_curve;
if (!apply_hue_sat_map && !apply_look_table && !use_tone_curve) {
// The fast path: No LUT and not tone curve --> Calculate matrix for direct conversion raw>working space
double mat[3][3] = {};
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) { for (int j = 0; j < 3; ++j) {
@ -1058,6 +1032,7 @@ void DCPProfile::apply(
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for #pragma omp parallel for
#endif #endif
for (int y = 0; y < img->height; ++y) { for (int y = 0; y < img->height; ++y) {
for (int x = 0; x < img->width; x++) { for (int x = 0; x < img->width; x++) {
const float& newr = mat[0][0] * img->r(y, x) + mat[0][1] * img->g(y, x) + mat[0][2] * img->b(y, x); const float& newr = mat[0][0] * img->r(y, x) + mat[0][1] * img->g(y, x) + mat[0][2] * img->b(y, x);
@ -1095,18 +1070,19 @@ void DCPProfile::apply(
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,16) #pragma omp parallel for schedule(dynamic,16)
#endif #endif
for (int y = 0; y < img->height; ++y) { for (int y = 0; y < img->height; ++y) {
for (int x = 0; x < img->width; x++) { for (int x = 0; x < img->width; x++) {
float newr = pro_photo[0][0] * img->r(y, x) + pro_photo[0][1] * img->g(y, x) + pro_photo[0][2] * img->b(y, x); float newr = pro_photo[0][0] * img->r(y, x) + pro_photo[0][1] * img->g(y, x) + pro_photo[0][2] * img->b(y, x);
float newg = pro_photo[1][0] * img->r(y, x) + pro_photo[1][1] * img->g(y, x) + pro_photo[1][2] * img->b(y, x); float newg = pro_photo[1][0] * img->r(y, x) + pro_photo[1][1] * img->g(y, x) + pro_photo[1][2] * img->b(y, x);
float newb = pro_photo[2][0] * img->r(y, x) + pro_photo[2][1] * img->g(y, x) + pro_photo[2][2] * img->b(y, x); float newb = pro_photo[2][0] * img->r(y, x) + pro_photo[2][1] * img->g(y, x) + pro_photo[2][2] * img->b(y, x);
// If point is in negative area, just the matrix, but not the LUT // If point is in negative area, just the matrix, but not the LUT. This is checked inside Color::rgb2hsvdcp
if (newr >= 0 && newg >= 0 && newb >= 0) {
float h; float h;
float s; float s;
float v; float v;
Color::rgb2hsvdcp(newr, newg, newb, h , s, v);
if(Color::rgb2hsvdcp(newr, newg, newb, h , s, v)) {
hsdApply(delta_info, delta_base, h, s, v); hsdApply(delta_info, delta_base, h, s, v);
@ -1178,11 +1154,10 @@ void DCPProfile::step2ApplyTile(float* rc, float* gc, float* bc, int width, int
#define FCLIP(a) ((a)>0.0?((a)<65535.5?(a):65535.5):0.0) #define FCLIP(a) ((a)>0.0?((a)<65535.5?(a):65535.5):0.0)
#define CLIP01(a) ((a)>0?((a)<1?(a):1):0) #define CLIP01(a) ((a)>0?((a)<1?(a):1):0)
float exp_scale = 1.0; float exp_scale = as_in.data->bl_scale;
exp_scale *= as_in.data->bl_scale;
if (!as_in.data->use_tone_curve && !as_in.data->apply_look_table) { if (!as_in.data->use_tone_curve && !as_in.data->apply_look_table) {
if (exp_scale == 1.0) { if (exp_scale == 1.f) {
return; return;
} }
@ -1373,7 +1348,8 @@ void DCPProfile::makeXyzCam(const ColorTemp& white_balance, const Triple& pre_mu
{xyz_sRGB[0][0], xyz_sRGB[0][1], xyz_sRGB[0][2]}, {xyz_sRGB[0][0], xyz_sRGB[0][1], xyz_sRGB[0][2]},
{xyz_sRGB[1][0], xyz_sRGB[1][1], xyz_sRGB[1][2]}, {xyz_sRGB[1][0], xyz_sRGB[1][1], xyz_sRGB[1][2]},
{xyz_sRGB[2][0], xyz_sRGB[2][1], xyz_sRGB[2][2]} {xyz_sRGB[2][0], xyz_sRGB[2][1], xyz_sRGB[2][2]}
}}; }
};
multiply3x3(cam_xyz, xyz_srgb, cam_rgb); multiply3x3(cam_xyz, xyz_srgb, cam_rgb);
double camwb_red = cam_rgb[0][0] * r + cam_rgb[0][1] * g + cam_rgb[0][2] * b; double camwb_red = cam_rgb[0][0] * r + cam_rgb[0][1] * g + cam_rgb[0][2] * b;
double camwb_green = cam_rgb[1][0] * r + cam_rgb[1][1] * g + cam_rgb[1][2] * b; double camwb_green = cam_rgb[1][0] * r + cam_rgb[1][1] * g + cam_rgb[1][2] * b;
@ -1502,7 +1478,8 @@ void DCPProfile::makeXyzCam(const ColorTemp& white_balance, const Triple& pre_mu
{camera_white[0], 0, 0}, {camera_white[0], 0, 0},
{0, camera_white[1], 0}, {0, camera_white[1], 0},
{0, 0, camera_white[2]} {0, 0, camera_white[2]}
}}; }
};
Matrix white_diag_inv; Matrix white_diag_inv;
invert3x3(white_diag, white_diag_inv); invert3x3(white_diag, white_diag_inv);
@ -1602,6 +1579,7 @@ std::vector<DCPProfile::HsbModify> DCPProfile::makeHueSatMap(const ColorTemp& wh
: temperature_2; : temperature_2;
double mix; double mix;
if (white_balance.getTemp() <= t1) { if (white_balance.getTemp() <= t1) {
mix = 1.0; mix = 1.0;
} else if (white_balance.getTemp() >= t2) { } else if (white_balance.getTemp() >= t2) {

View File

@ -80,9 +80,7 @@ public:
const ColorTemp& white_balance, const ColorTemp& white_balance,
const Triple& pre_mul, const Triple& pre_mul,
const Matrix& cam_wb_matrix, const Matrix& cam_wb_matrix,
bool use_tone_curve = false, bool apply_hue_sat_map = true
bool apply_hue_sat_map = true,
bool apply_look_table = false
) const; ) const;
void setStep2ApplyState(const Glib::ustring& working_space, bool use_tone_curve, bool apply_look_table, bool apply_baseline_exposure, ApplyState& as_out); void setStep2ApplyState(const Glib::ustring& working_space, bool use_tone_curve, bool apply_look_table, bool apply_baseline_exposure, ApplyState& as_out);
void step2ApplyTile(float* r, float* g, float* b, int width, int height, int tile_width, const ApplyState& as_in) const; void step2ApplyTile(float* r, float* g, float* b, int width, int height, int tile_width, const ApplyState& as_in) const;

View File

@ -3737,7 +3737,7 @@ void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParam
{camMatrix[1][0], camMatrix[1][1], camMatrix[1][2]}, {camMatrix[1][0], camMatrix[1][1], camMatrix[1][2]},
{camMatrix[2][0], camMatrix[2][1], camMatrix[2][2]} {camMatrix[2][0], camMatrix[2][1], camMatrix[2][2]}
}}; }};
dcpProf->apply(im, cmp.dcpIlluminant, cmp.working, wb, pre_mul_row, cam_matrix, false, cmp.applyHueSatMap, false); dcpProf->apply(im, cmp.dcpIlluminant, cmp.working, wb, pre_mul_row, cam_matrix, cmp.applyHueSatMap);
return; return;
} }