Capture sharpening: removed unused code, also small speedup for 5x5 and 7x7 gauss
This commit is contained in:
@@ -1804,84 +1804,6 @@ public:
|
|||||||
return (hr);
|
return (hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void RGB2YCbCr(float* R, float* G, float* B, float* Y, float* Cb, float *Cr, float gamma, int W) {
|
|
||||||
gamma = 1.f / gamma;
|
|
||||||
int i = 0;
|
|
||||||
#ifdef __SSE2__
|
|
||||||
const vfloat gammav = F2V(gamma);
|
|
||||||
const vfloat c1v = F2V(0.2627f);
|
|
||||||
const vfloat c2v = F2V(0.6780f);
|
|
||||||
const vfloat c3v = F2V(0.0593f);
|
|
||||||
const vfloat c4v = F2V(1.f - 0.0593f);
|
|
||||||
const vfloat c5v = F2V(1.f - 0.2627f);
|
|
||||||
for (; i < W - 3; i += 4) {
|
|
||||||
const vfloat Rv = vmaxf(LVFU(R[i]), ZEROV);
|
|
||||||
const vfloat Gv = vmaxf(LVFU(G[i]), ZEROV);
|
|
||||||
const vfloat Bv = vmaxf(LVFU(B[i]), ZEROV);
|
|
||||||
STVFU(Y[i], pow_F(c1v * Rv + c2v * Gv + c3v * Bv, gammav));
|
|
||||||
STVFU(Cb[i], c4v * Bv - (c1v * Rv + c2v * Gv));
|
|
||||||
STVFU(Cr[i], c5v * Rv - (c2v * Gv + c3v * Bv));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
for (; i < W; ++i) {
|
|
||||||
const float r = std::max(R[i], 0.f);
|
|
||||||
const float g = std::max(G[i], 0.f);
|
|
||||||
const float b = std::max(B[i], 0.f);
|
|
||||||
Y[i] = pow_F(0.2627f * r + 0.6780f * g + 0.0593f * b, gamma);
|
|
||||||
Cb[i] = (1.f - 0.0593f) * b - (0.2627f * r + 0.6780f * g);
|
|
||||||
Cr[i] = (1.f - 0.2627f) * r - (0.6780f * g + 0.0593f * b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void YCbCr2RGB(float* Y, float* Cb, float* Cr, float* R, float* G, float* B, float gamma, int W) {
|
|
||||||
int i = 0;
|
|
||||||
#ifdef __SSE2__
|
|
||||||
const vfloat gammav = F2V(gamma);
|
|
||||||
const vfloat c1v = F2V(0.0593f / 0.6780f);
|
|
||||||
const vfloat c2v = F2V(0.2627f / 0.6780f);
|
|
||||||
|
|
||||||
for (; i < W - 3; i += 4) {
|
|
||||||
const vfloat Yv = pow_F(LVFU(Y[i]), gammav);
|
|
||||||
const vfloat Crv = LVFU(Cr[i]);
|
|
||||||
const vfloat Cbv = LVFU(Cb[i]);
|
|
||||||
STVFU(R[i], vmaxf(Yv + Crv, ZEROV));
|
|
||||||
STVFU(G[i], vmaxf(Yv - c1v * Cbv - c2v * Crv, ZEROV));
|
|
||||||
STVFU(B[i], vmaxf(Yv + Cbv, ZEROV));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
for (; i < W; ++i) {
|
|
||||||
const float y = pow_F(Y[i], gamma);
|
|
||||||
const float cr = Cr[i];
|
|
||||||
const float cb = Cb[i];
|
|
||||||
R[i] = std::max(y + cr, 0.f);
|
|
||||||
G[i] = std::max(y - (0.0593f / 0.6780f) * cb - (0.2627f / 0.6780f) * cr, 0.f);
|
|
||||||
B[i] = std::max(y + cb, 0.f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void RGB2Y(float* R, float* G, float* B, float* Y, float gamma, int W) {
|
|
||||||
gamma = 1.f / gamma;
|
|
||||||
int i = 0;
|
|
||||||
#ifdef __SSE2__
|
|
||||||
const vfloat gammav = F2V(gamma);
|
|
||||||
const vfloat c1v = F2V(0.2627f);
|
|
||||||
const vfloat c2v = F2V(0.6780f);
|
|
||||||
const vfloat c3v = F2V(0.0593f);
|
|
||||||
for (; i < W - 3; i += 4) {
|
|
||||||
const vfloat Rv = vmaxf(LVFU(R[i]), ZEROV);
|
|
||||||
const vfloat Gv = vmaxf(LVFU(G[i]), ZEROV);
|
|
||||||
const vfloat Bv = vmaxf(LVFU(B[i]), ZEROV);
|
|
||||||
STVFU(Y[i], pow_F(c1v * Rv + c2v * Gv + c3v * Bv, gammav));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
for (; i < W; ++i) {
|
|
||||||
const float r = std::max(R[i], 0.f);
|
|
||||||
const float g = std::max(G[i], 0.f);
|
|
||||||
const float b = std::max(B[i], 0.f);
|
|
||||||
Y[i] = pow_F(0.2627f * r + 0.6780f * g + 0.0593f * b, gamma);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void RGB2Y(const float* R, const float* G, const float* B, float* Y1, float * Y2, float gamma, int W) {
|
static inline void RGB2Y(const float* R, const float* G, const float* B, float* Y1, float * Y2, float gamma, int W) {
|
||||||
gamma = 1.f / gamma;
|
gamma = 1.f / gamma;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@@ -272,52 +272,16 @@ template<class T> void gauss7x7div (T** RESTRICT src, T** RESTRICT dst, T** REST
|
|||||||
dst[i][0] = dst[i][1] = dst[i][2] = 1.f;
|
dst[i][0] = dst[i][1] = dst[i][2] = 1.f;
|
||||||
// I tried hand written SSE code but gcc vectorizes better
|
// I tried hand written SSE code but gcc vectorizes better
|
||||||
for (int j = 3; j < W - 3; ++j) {
|
for (int j = 3; j < W - 3; ++j) {
|
||||||
float val = src[i - 3][j - 1] * c31;
|
const float val = c31 * (src[i - 3][j - 1] + src[i - 3][j + 1] + src[i - 1][j - 3] + src[i - 1][j + 3] + src[i + 1][j - 3] + src[i + 1][j + 3] + src[i + 3][j - 1] + src[i + 3][j + 1]) +
|
||||||
val += src[i - 3][j - 0] * c30;
|
c30 * (src[i - 3][j] + src[i][j - 3] + src[i][j + 3] + src[i + 3][j]) +
|
||||||
val += src[i - 3][j + 1] * c31;
|
c22 * (src[i - 2][j - 2] + src[i - 2][j + 2] + src[i + 2][j - 2] + src[i + 2][j + 2]) +
|
||||||
|
c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] * c21 + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) +
|
||||||
|
c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) +
|
||||||
|
c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) +
|
||||||
|
c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) +
|
||||||
|
c00 * src[i][j];
|
||||||
|
|
||||||
val += src[i - 2][j - 2] * c22;
|
dst[i][j] = divBuffer[i][j] / std::max(val, 0.00001f);
|
||||||
val += src[i - 2][j - 1] * c21;
|
|
||||||
val += src[i - 2][j - 0] * c20;
|
|
||||||
val += src[i - 2][j + 1] * c21;
|
|
||||||
val += src[i - 2][j + 2] * c22;
|
|
||||||
|
|
||||||
val += src[i - 1][j - 3] * c31;
|
|
||||||
val += src[i - 1][j - 2] * c21;
|
|
||||||
val += src[i - 1][j - 1] * c11;
|
|
||||||
val += src[i - 1][j - 0] * c10;
|
|
||||||
val += src[i - 1][j + 1] * c11;
|
|
||||||
val += src[i - 1][j + 2] * c21;
|
|
||||||
val += src[i - 1][j + 3] * c31;
|
|
||||||
|
|
||||||
val += src[i][j - 3] * c30;
|
|
||||||
val += src[i][j - 2] * c20;
|
|
||||||
val += src[i][j - 1] * c10;
|
|
||||||
val += src[i][j - 0] * c00;
|
|
||||||
val += src[i][j + 1] * c10;
|
|
||||||
val += src[i][j + 2] * c20;
|
|
||||||
val += src[i][j + 3] * c30;
|
|
||||||
|
|
||||||
val += src[i + 1][j - 3] * c31;
|
|
||||||
val += src[i + 1][j - 2] * c21;
|
|
||||||
val += src[i + 1][j - 1] * c11;
|
|
||||||
val += src[i + 1][j - 0] * c10;
|
|
||||||
val += src[i + 1][j + 1] * c11;
|
|
||||||
val += src[i + 1][j + 2] * c21;
|
|
||||||
val += src[i + 1][j + 3] * c31;
|
|
||||||
|
|
||||||
val += src[i + 2][j - 2] * c22;
|
|
||||||
val += src[i + 2][j - 1] * c21;
|
|
||||||
val += src[i + 2][j - 0] * c20;
|
|
||||||
val += src[i + 2][j + 1] * c21;
|
|
||||||
val += src[i + 2][j + 2] * c22;
|
|
||||||
|
|
||||||
val += src[i + 3][j - 1] * c31;
|
|
||||||
val += src[i + 3][j - 0] * c30;
|
|
||||||
val += src[i + 3][j + 1] * c31;
|
|
||||||
|
|
||||||
val = val > 0.f ? val : 1.f;
|
|
||||||
dst[i][j] = std::max(divBuffer[i][j] / val, 0.f);
|
|
||||||
}
|
}
|
||||||
dst[i][W - 3] = dst[i][W - 2] = dst[i][W - 1] = 1.f;
|
dst[i][W - 3] = dst[i][W - 2] = dst[i][W - 1] = 1.f;
|
||||||
}
|
}
|
||||||
@@ -360,34 +324,13 @@ template<class T> void gauss5x5div (T** RESTRICT src, T** RESTRICT dst, T** REST
|
|||||||
dst[i][0] = dst[i][1] = 1.f;
|
dst[i][0] = dst[i][1] = 1.f;
|
||||||
// I tried hand written SSE code but gcc vectorizes better
|
// I tried hand written SSE code but gcc vectorizes better
|
||||||
for (int j = 2; j < W - 2; ++j) {
|
for (int j = 2; j < W - 2; ++j) {
|
||||||
float val = src[i - 2][j - 1] * c21;
|
const float val = c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) +
|
||||||
val += src[i - 2][j - 0] * c20;
|
c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) +
|
||||||
val += src[i - 2][j + 1] * c21;
|
c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) +
|
||||||
|
c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) +
|
||||||
|
c00 * src[i][j];
|
||||||
|
|
||||||
val += src[i - 1][j - 2] * c21;
|
dst[i][j] = divBuffer[i][j] / std::max(val, 0.00001f);
|
||||||
val += src[i - 1][j - 1] * c11;
|
|
||||||
val += src[i - 1][j - 0] * c10;
|
|
||||||
val += src[i - 1][j + 1] * c11;
|
|
||||||
val += src[i - 1][j + 2] * c21;
|
|
||||||
|
|
||||||
val += src[i - 0][j - 2] * c20;
|
|
||||||
val += src[i - 0][j - 1] * c10;
|
|
||||||
val += src[i - 0][j - 0] * c00;
|
|
||||||
val += src[i - 0][j + 1] * c10;
|
|
||||||
val += src[i - 0][j + 2] * c20;
|
|
||||||
|
|
||||||
val += src[i + 1][j - 2] * c21;
|
|
||||||
val += src[i + 1][j - 1] * c11;
|
|
||||||
val += src[i + 1][j - 0] * c10;
|
|
||||||
val += src[i + 1][j + 1] * c11;
|
|
||||||
val += src[i + 1][j + 2] * c21;
|
|
||||||
|
|
||||||
val += src[i + 2][j - 1] * c21;
|
|
||||||
val += src[i + 2][j - 0] * c20;
|
|
||||||
val += src[i + 2][j + 1] * c21;
|
|
||||||
|
|
||||||
val = val > 0.f ? val : 1.f;
|
|
||||||
dst[i][j] = std::max(divBuffer[i][j] / val, 0.f);
|
|
||||||
}
|
}
|
||||||
dst[i][W - 2] = dst[i][W - 1] = 1.f;
|
dst[i][W - 2] = dst[i][W - 1] = 1.f;
|
||||||
}
|
}
|
||||||
@@ -431,49 +374,14 @@ template<class T> void gauss7x7mult (T** RESTRICT src, T** RESTRICT dst, const i
|
|||||||
for (int i = 3; i < H - 3; ++i) {
|
for (int i = 3; i < H - 3; ++i) {
|
||||||
// I tried hand written SSE code but gcc vectorizes better
|
// I tried hand written SSE code but gcc vectorizes better
|
||||||
for (int j = 3; j < W - 3; ++j) {
|
for (int j = 3; j < W - 3; ++j) {
|
||||||
float val = src[i - 3][j - 1] * c31;
|
const float val = c31 * (src[i - 3][j - 1] + src[i - 3][j + 1] + src[i - 1][j - 3] + src[i - 1][j + 3] + src[i + 1][j - 3] + src[i + 1][j + 3] + src[i + 3][j - 1] + src[i + 3][j + 1]) +
|
||||||
val += src[i - 3][j - 0] * c30;
|
c30 * (src[i - 3][j] + src[i][j - 3] + src[i][j + 3] + src[i + 3][j]) +
|
||||||
val += src[i - 3][j + 1] * c31;
|
c22 * (src[i - 2][j - 2] + src[i - 2][j + 2] + src[i + 2][j - 2] + src[i + 2][j + 2]) +
|
||||||
|
c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] * c21 + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) +
|
||||||
val += src[i - 2][j - 2] * c22;
|
c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) +
|
||||||
val += src[i - 2][j - 1] * c21;
|
c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) +
|
||||||
val += src[i - 2][j - 0] * c20;
|
c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) +
|
||||||
val += src[i - 2][j + 1] * c21;
|
c00 * src[i][j];
|
||||||
val += src[i - 2][j + 2] * c22;
|
|
||||||
|
|
||||||
val += src[i - 1][j - 3] * c31;
|
|
||||||
val += src[i - 1][j - 2] * c21;
|
|
||||||
val += src[i - 1][j - 1] * c11;
|
|
||||||
val += src[i - 1][j - 0] * c10;
|
|
||||||
val += src[i - 1][j + 1] * c11;
|
|
||||||
val += src[i - 1][j + 2] * c21;
|
|
||||||
val += src[i - 1][j + 3] * c31;
|
|
||||||
|
|
||||||
val += src[i][j - 3] * c30;
|
|
||||||
val += src[i][j - 2] * c20;
|
|
||||||
val += src[i][j - 1] * c10;
|
|
||||||
val += src[i][j - 0] * c00;
|
|
||||||
val += src[i][j + 1] * c10;
|
|
||||||
val += src[i][j + 2] * c20;
|
|
||||||
val += src[i][j + 3] * c30;
|
|
||||||
|
|
||||||
val += src[i + 1][j - 3] * c31;
|
|
||||||
val += src[i + 1][j - 2] * c21;
|
|
||||||
val += src[i + 1][j - 1] * c11;
|
|
||||||
val += src[i + 1][j - 0] * c10;
|
|
||||||
val += src[i + 1][j + 1] * c11;
|
|
||||||
val += src[i + 1][j + 2] * c21;
|
|
||||||
val += src[i + 1][j + 3] * c31;
|
|
||||||
|
|
||||||
val += src[i + 2][j - 2] * c22;
|
|
||||||
val += src[i + 2][j - 1] * c21;
|
|
||||||
val += src[i + 2][j - 0] * c20;
|
|
||||||
val += src[i + 2][j + 1] * c21;
|
|
||||||
val += src[i + 2][j + 2] * c22;
|
|
||||||
|
|
||||||
val += src[i + 3][j - 1] * c31;
|
|
||||||
val += src[i + 3][j - 0] * c30;
|
|
||||||
val += src[i + 3][j + 1] * c31;
|
|
||||||
|
|
||||||
dst[i][j] *= val;
|
dst[i][j] *= val;
|
||||||
}
|
}
|
||||||
@@ -499,31 +407,11 @@ template<class T> void gauss5x5mult (T** RESTRICT src, T** RESTRICT dst, const i
|
|||||||
for (int i = 2; i < H - 2; ++i) {
|
for (int i = 2; i < H - 2; ++i) {
|
||||||
// I tried hand written SSE code but gcc vectorizes better
|
// I tried hand written SSE code but gcc vectorizes better
|
||||||
for (int j = 2; j < W - 2; ++j) {
|
for (int j = 2; j < W - 2; ++j) {
|
||||||
float val = src[i - 2][j - 1] * c21;
|
const float val = c21 * (src[i - 2][j - 1] + src[i - 2][j + 1] + src[i - 1][j - 2] + src[i - 1][j + 2] + src[i + 1][j - 2] + src[i + 1][j + 2] + src[i + 2][j - 1] + src[i + 2][j + 1]) +
|
||||||
val += src[i - 2][j - 0] * c20;
|
c20 * (src[i - 2][j] + src[i][j - 2] + src[i][j + 2] + src[i + 2][j]) +
|
||||||
val += src[i - 2][j + 1] * c21;
|
c11 * (src[i - 1][j - 1] + src[i - 1][j + 1] + src[i + 1][j - 1] + src[i + 1][j + 1]) +
|
||||||
|
c10 * (src[i - 1][j] + src[i][j - 1] + src[i][j + 1] + src[i + 1][j]) +
|
||||||
val += src[i - 1][j - 2] * c21;
|
c00 * src[i][j];
|
||||||
val += src[i - 1][j - 1] * c11;
|
|
||||||
val += src[i - 1][j - 0] * c10;
|
|
||||||
val += src[i - 1][j + 1] * c11;
|
|
||||||
val += src[i - 1][j + 2] * c21;
|
|
||||||
|
|
||||||
val += src[i - 0][j - 2] * c20;
|
|
||||||
val += src[i - 0][j - 1] * c10;
|
|
||||||
val += src[i - 0][j - 0] * c00;
|
|
||||||
val += src[i - 0][j + 1] * c10;
|
|
||||||
val += src[i - 0][j + 2] * c20;
|
|
||||||
|
|
||||||
val += src[i + 1][j - 2] * c21;
|
|
||||||
val += src[i + 1][j - 1] * c11;
|
|
||||||
val += src[i + 1][j - 0] * c10;
|
|
||||||
val += src[i + 1][j + 1] * c11;
|
|
||||||
val += src[i + 1][j + 2] * c21;
|
|
||||||
|
|
||||||
val += src[i + 2][j - 1] * c21;
|
|
||||||
val += src[i + 2][j - 0] * c20;
|
|
||||||
val += src[i + 2][j + 1] * c21;
|
|
||||||
|
|
||||||
dst[i][j] *= val;
|
dst[i][j] *= val;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user