mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-27 06:08:21 +01:00
fix a descaling bug for vertical/horizontal U/V interpolation
RGBToU/V calls expects two extra precision bits, they were only given one by SUM2H and SUM2H macros. For rounding coherency, also changed SUM1 macro. Change-Id: I05f96a46f5d4f17b830d0420eaf79b066cdf78d4
This commit is contained in:
parent
bcb3955c41
commit
cb261f790f
@ -643,12 +643,15 @@ static WEBP_INLINE uint32_t GammaToLinear(uint8_t v) {
|
|||||||
return kGammaToLinearTab[v];
|
return kGammaToLinearTab[v];
|
||||||
}
|
}
|
||||||
|
|
||||||
static WEBP_INLINE int LinearToGamma(uint32_t v, int shift) {
|
// Convert a linear value 'v' to YUV_FIX+2 fixed-point precision
|
||||||
const int tab_pos = v >> (kGammaTabFix + shift); // integer part
|
// U/V value, suitable for RGBToU/V calls.
|
||||||
const int x = v & ((kGammaTabScale << shift) - 1); // fractional part
|
static WEBP_INLINE int LinearToGamma(uint32_t base_value, int shift) {
|
||||||
|
const int v = base_value << shift; // final uplifted value
|
||||||
|
const int tab_pos = v >> (kGammaTabFix + 2); // integer part
|
||||||
|
const int x = v & ((kGammaTabScale << 2) - 1); // fractional part
|
||||||
const int v0 = kLinearToGammaTab[tab_pos];
|
const int v0 = kLinearToGammaTab[tab_pos];
|
||||||
const int v1 = kLinearToGammaTab[tab_pos + 1];
|
const int v1 = kLinearToGammaTab[tab_pos + 1];
|
||||||
const int y = v1 * x + v0 * ((kGammaTabScale << shift) - x); // interpolate
|
const int y = v1 * x + v0 * ((kGammaTabScale << 2) - x); // interpolate
|
||||||
return (y + kGammaTabRounder) >> kGammaTabFix; // descale
|
return (y + kGammaTabRounder) >> kGammaTabFix; // descale
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,7 +659,7 @@ static WEBP_INLINE int LinearToGamma(uint32_t v, int shift) {
|
|||||||
|
|
||||||
static void InitGammaTables(void) {}
|
static void InitGammaTables(void) {}
|
||||||
static WEBP_INLINE uint32_t GammaToLinear(uint8_t v) { return v; }
|
static WEBP_INLINE uint32_t GammaToLinear(uint8_t v) { return v; }
|
||||||
static WEBP_INLINE int LinearToGamma(uint32_t v, int shift) {
|
static WEBP_INLINE int LinearToGamma(uint32_t base_value, int shift) {
|
||||||
(void)shift;
|
(void)shift;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
@ -669,13 +672,14 @@ static WEBP_INLINE int LinearToGamma(uint32_t v, int shift) {
|
|||||||
GammaToLinear((ptr)[0]) + \
|
GammaToLinear((ptr)[0]) + \
|
||||||
GammaToLinear((ptr)[step]) + \
|
GammaToLinear((ptr)[step]) + \
|
||||||
GammaToLinear((ptr)[rgb_stride]) + \
|
GammaToLinear((ptr)[rgb_stride]) + \
|
||||||
GammaToLinear((ptr)[rgb_stride + step]), 2) \
|
GammaToLinear((ptr)[rgb_stride + step]), 0) \
|
||||||
|
|
||||||
#define SUM2H(ptr) \
|
#define SUM2H(ptr) \
|
||||||
LinearToGamma(GammaToLinear((ptr)[0]) + GammaToLinear((ptr)[step]), 1)
|
LinearToGamma(GammaToLinear((ptr)[0]) + GammaToLinear((ptr)[step]), 1)
|
||||||
#define SUM2V(ptr) \
|
#define SUM2V(ptr) \
|
||||||
LinearToGamma(GammaToLinear((ptr)[0]) + GammaToLinear((ptr)[rgb_stride]), 1)
|
LinearToGamma(GammaToLinear((ptr)[0]) + GammaToLinear((ptr)[rgb_stride]), 1)
|
||||||
#define SUM1(ptr) (4 * (ptr)[0])
|
#define SUM1(ptr) \
|
||||||
|
LinearToGamma(GammaToLinear((ptr)[0]), 2)
|
||||||
|
|
||||||
#define RGB_TO_UV(x, y, SUM) { \
|
#define RGB_TO_UV(x, y, SUM) { \
|
||||||
const int src = (2 * (step * (x) + (y) * rgb_stride)); \
|
const int src = (2 * (step * (x) + (y) * rgb_stride)); \
|
||||||
|
Loading…
Reference in New Issue
Block a user