mirror of
https://github.com/webmproject/libwebp.git
synced 2024-11-20 04:18:26 +01:00
simplify smart RGB->YUV conversion code
* use the same TFIX == YFIX precision (2bits) * use int instead of float in LinearToGammaF() output is visually equivalent. Code is a little faster. Change-Id: Ie3cfebca351dbcbd924b3d00801d6523dca6981f
This commit is contained in:
parent
0d5b334ee8
commit
0f027a72bf
@ -165,7 +165,7 @@ static const int kMinDimensionIterativeConversion = 4;
|
|||||||
|
|
||||||
typedef int16_t fixed_t; // signed type with extra TFIX precision for UV
|
typedef int16_t fixed_t; // signed type with extra TFIX precision for UV
|
||||||
typedef uint16_t fixed_y_t; // unsigned type with extra YFIX precision for W
|
typedef uint16_t fixed_y_t; // unsigned type with extra YFIX precision for W
|
||||||
#define TFIX 6 // fixed-point precision of RGB
|
#define TFIX 2 // fixed-point precision of RGB
|
||||||
#define YFIX 2 // fixed point precision for Y/W
|
#define YFIX 2 // fixed point precision for Y/W
|
||||||
|
|
||||||
#define THALF ((1 << TFIX) >> 1)
|
#define THALF ((1 << TFIX) >> 1)
|
||||||
@ -203,14 +203,14 @@ static WEBP_INLINE float GammaToLinearF(int v) {
|
|||||||
return kGammaToLinearTabF[v];
|
return kGammaToLinearTabF[v];
|
||||||
}
|
}
|
||||||
|
|
||||||
static WEBP_INLINE float LinearToGammaF(float value) {
|
static WEBP_INLINE int LinearToGammaF(float value) {
|
||||||
const float v = value * kGammaTabSize;
|
const float v = value * kGammaTabSize;
|
||||||
const int tab_pos = (int)v;
|
const int tab_pos = (int)v;
|
||||||
const float x = v - (float)tab_pos; // fractional part
|
const float x = v - (float)tab_pos; // fractional part
|
||||||
const float v0 = kLinearToGammaTabF[tab_pos + 0];
|
const float v0 = kLinearToGammaTabF[tab_pos + 0];
|
||||||
const float v1 = kLinearToGammaTabF[tab_pos + 1];
|
const float v1 = kLinearToGammaTabF[tab_pos + 1];
|
||||||
const float y = v1 * x + v0 * (1.f - x); // interpolate
|
const float y = v1 * x + v0 * (1.f - x); // interpolate
|
||||||
return y;
|
return (int)(y + .5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -220,8 +220,8 @@ static WEBP_INLINE float GammaToLinearF(int v) {
|
|||||||
const float norm = 1.f / MAX_Y_T;
|
const float norm = 1.f / MAX_Y_T;
|
||||||
return norm * v;
|
return norm * v;
|
||||||
}
|
}
|
||||||
static WEBP_INLINE float LinearToGammaF(float value) {
|
static WEBP_INLINE int LinearToGammaF(float value) {
|
||||||
return MAX_Y_T * value;
|
return (int)(MAX_Y_T * value + .5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // USE_GAMMA_COMPRESSION
|
#endif // USE_GAMMA_COMPRESSION
|
||||||
@ -229,25 +229,8 @@ static WEBP_INLINE float LinearToGammaF(float value) {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
// precision: YFIX -> TFIX
|
// precision: YFIX -> TFIX
|
||||||
static WEBP_INLINE int FixedYToW(int v) {
|
static WEBP_INLINE int FixedYToW(int v) { return v; }
|
||||||
#if TFIX == YFIX
|
static WEBP_INLINE int FixedWToY(int v) { return v; }
|
||||||
return v;
|
|
||||||
#elif TFIX >= YFIX
|
|
||||||
return v << (TFIX - YFIX);
|
|
||||||
#else
|
|
||||||
return v >> (YFIX - TFIX);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static WEBP_INLINE int FixedWToY(int v) {
|
|
||||||
#if TFIX == YFIX
|
|
||||||
return v;
|
|
||||||
#elif YFIX >= TFIX
|
|
||||||
return v << (YFIX - TFIX);
|
|
||||||
#else
|
|
||||||
return v >> (TFIX - YFIX);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t clip_8b(fixed_t v) {
|
static uint8_t clip_8b(fixed_t v) {
|
||||||
return (!(v & ~0xff)) ? (uint8_t)v : (v < 0) ? 0u : 255u;
|
return (!(v & ~0xff)) ? (uint8_t)v : (v < 0) ? 0u : 255u;
|
||||||
@ -275,7 +258,7 @@ static float RGBToGrayF(float r, float g, float b) {
|
|||||||
return 0.299f * r + 0.587f * g + 0.114f * b;
|
return 0.299f * r + 0.587f * g + 0.114f * b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float ScaleDown(int a, int b, int c, int d) {
|
static int ScaleDown(int a, int b, int c, int d) {
|
||||||
const float A = GammaToLinearF(a);
|
const float A = GammaToLinearF(a);
|
||||||
const float B = GammaToLinearF(b);
|
const float B = GammaToLinearF(b);
|
||||||
const float C = GammaToLinearF(c);
|
const float C = GammaToLinearF(c);
|
||||||
@ -289,7 +272,7 @@ static WEBP_INLINE void UpdateW(const fixed_y_t* src, fixed_y_t* dst, int len) {
|
|||||||
const float G = GammaToLinearF(src[1]);
|
const float G = GammaToLinearF(src[1]);
|
||||||
const float B = GammaToLinearF(src[2]);
|
const float B = GammaToLinearF(src[2]);
|
||||||
const float Y = RGBToGrayF(R, G, B);
|
const float Y = RGBToGrayF(R, G, B);
|
||||||
*dst++ = (fixed_y_t)(LinearToGammaF(Y) + .5);
|
*dst++ = (fixed_y_t)LinearToGammaF(Y);
|
||||||
src += 3;
|
src += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -298,13 +281,13 @@ static WEBP_INLINE void UpdateChroma(const fixed_y_t* src1,
|
|||||||
const fixed_y_t* src2,
|
const fixed_y_t* src2,
|
||||||
fixed_t* dst, fixed_y_t* tmp, int len) {
|
fixed_t* dst, fixed_y_t* tmp, int len) {
|
||||||
while (len--> 0) {
|
while (len--> 0) {
|
||||||
const float r = ScaleDown(src1[0], src1[3], src2[0], src2[3]);
|
const int r = ScaleDown(src1[0], src1[3], src2[0], src2[3]);
|
||||||
const float g = ScaleDown(src1[1], src1[4], src2[1], src2[4]);
|
const int g = ScaleDown(src1[1], src1[4], src2[1], src2[4]);
|
||||||
const float b = ScaleDown(src1[2], src1[5], src2[2], src2[5]);
|
const int b = ScaleDown(src1[2], src1[5], src2[2], src2[5]);
|
||||||
const float W = RGBToGrayF(r, g, b);
|
const int W = RGBToGray(r, g, b);
|
||||||
dst[0] = (fixed_t)FixedYToW((int)(r - W));
|
dst[0] = (fixed_t)FixedYToW(r - W);
|
||||||
dst[1] = (fixed_t)FixedYToW((int)(g - W));
|
dst[1] = (fixed_t)FixedYToW(g - W);
|
||||||
dst[2] = (fixed_t)FixedYToW((int)(b - W));
|
dst[2] = (fixed_t)FixedYToW(b - W);
|
||||||
dst += 3;
|
dst += 3;
|
||||||
src1 += 6;
|
src1 += 6;
|
||||||
src2 += 6;
|
src2 += 6;
|
||||||
|
Loading…
Reference in New Issue
Block a user