sharpyuv: cleanup/cosmetic changes

Remove unused constants.
Use ALL_CAPS for defines and kCamelCase for static const values.
Change some defines into static constants if they are not used in array sizes.

Change-Id: I036b0f99215fd0414a33f099bd6b809ff8ee4541
This commit is contained in:
Maryla 2022-05-09 14:25:27 +02:00
parent dc3841e077
commit 0c8b0e67a4
3 changed files with 56 additions and 76 deletions

View File

@ -22,43 +22,33 @@
#include "src/dsp/cpu.h" #include "src/dsp/cpu.h"
#include "sharpyuv/sharpyuv_dsp.h" #include "sharpyuv/sharpyuv_dsp.h"
//------------------------------------------------------------------------------
// Code for gamma correction
// gamma-compensates loss of resolution during chroma subsampling
#define kGamma 0.80 // for now we use a different gamma value than kGammaF
#define kGammaFix 12 // fixed-point precision for linear values
#define kGammaScale ((1 << kGammaFix) - 1)
#define kGammaTabFix 7 // fixed-point fractional bits precision
#define kGammaTabScale (1 << kGammaTabFix)
#define kGammaTabRounder (kGammaTabScale >> 1)
#define kGammaTabSize (1 << (kGammaFix - kGammaTabFix))
enum {
YUV_FIX = 16, // fixed-point precision for RGB->YUV
YUV_HALF = 1 << (YUV_FIX - 1),
};
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Sharp RGB->YUV conversion // Sharp RGB->YUV conversion
static const int kNumIterations = 4; static const int kNumIterations = 4;
static const int kMinDimensionIterativeConversion = 4; static const int kMinDimensionIterativeConversion = 4;
#define YUV_FIX 16 // fixed-point precision for RGB->YUV
static const int kYuvHalf = 1 << (YUV_FIX - 1);
// We could use SFIX=0 and only uint8_t for fixed_y_t, but it produces some // We could use SFIX=0 and only uint8_t for fixed_y_t, but it produces some
// banding sometimes. Better use extra precision. // banding sometimes. Better use extra precision.
#define SFIX 2 // fixed-point precision of RGB and Y/W #define SFIX 2 // fixed-point precision of RGB and Y/W
#define MAX_Y_T ((256 << SFIX) - 1)
typedef int16_t fixed_t; // signed type with extra SFIX precision for UV typedef int16_t fixed_t; // signed type with extra SFIX precision for UV
typedef uint16_t fixed_y_t; // unsigned type with extra SFIX precision for W typedef uint16_t fixed_y_t; // unsigned type with extra SFIX precision for W
#define SHALF (1 << SFIX >> 1) static const int kSfixHalf = (1 << SFIX >> 1);
#define MAX_Y_T ((256 << SFIX) - 1) static const int kYuvRounder = (1 << (YUV_FIX + SFIX - 1));
#define SROUNDER (1 << (YUV_FIX + SFIX - 1))
// We use tables of different size and precision for the Rec709 / BT2020 //------------------------------------------------------------------------------
// transfer function. // Code for gamma correction
#define kGammaF (1./0.45)
static uint32_t kLinearToGammaTabS[kGammaTabSize + 2]; // Gamma correction compensates loss of resolution during chroma subsampling.
static const double kGammaF = 1./0.45;
#define GAMMA_TAB_FIX 5
#define GAMMA_TAB_SIZE (1 << GAMMA_TAB_FIX)
static uint32_t kLinearToGammaTabS[GAMMA_TAB_SIZE + 2];
#define GAMMA_TO_LINEAR_BITS 14 #define GAMMA_TO_LINEAR_BITS 14
static uint32_t kGammaToLinearTabS[MAX_Y_T + 1]; // size scales with Y_FIX static uint32_t kGammaToLinearTabS[MAX_Y_T + 1]; // size scales with Y_FIX
static volatile int kGammaTablesSOk = 0; static volatile int kGammaTablesSOk = 0;
@ -68,7 +58,7 @@ static void InitGammaTablesS(void) {
if (!kGammaTablesSOk) { if (!kGammaTablesSOk) {
int v; int v;
const double norm = 1. / MAX_Y_T; const double norm = 1. / MAX_Y_T;
const double scale = 1. / kGammaTabSize; const double scale = 1. / GAMMA_TAB_SIZE;
const double a = 0.09929682680944; const double a = 0.09929682680944;
const double thresh = 0.018053968510807; const double thresh = 0.018053968510807;
const double final_scale = 1 << GAMMA_TO_LINEAR_BITS; const double final_scale = 1 << GAMMA_TO_LINEAR_BITS;
@ -83,7 +73,7 @@ static void InitGammaTablesS(void) {
} }
kGammaToLinearTabS[v] = (uint32_t)(value * final_scale + .5); kGammaToLinearTabS[v] = (uint32_t)(value * final_scale + .5);
} }
for (v = 0; v <= kGammaTabSize; ++v) { for (v = 0; v <= GAMMA_TAB_SIZE; ++v) {
const double g = scale * v; const double g = scale * v;
double value; double value;
if (g <= thresh) { if (g <= thresh) {
@ -96,7 +86,7 @@ static void InitGammaTablesS(void) {
(uint32_t)(MAX_Y_T * value) + (1 << GAMMA_TO_LINEAR_BITS >> 1); (uint32_t)(MAX_Y_T * value) + (1 << GAMMA_TO_LINEAR_BITS >> 1);
} }
// to prevent small rounding errors to cause read-overflow: // to prevent small rounding errors to cause read-overflow:
kLinearToGammaTabS[kGammaTabSize + 1] = kLinearToGammaTabS[kGammaTabSize]; kLinearToGammaTabS[GAMMA_TAB_SIZE + 1] = kLinearToGammaTabS[GAMMA_TAB_SIZE];
kGammaTablesSOk = 1; kGammaTablesSOk = 1;
} }
} }
@ -108,7 +98,7 @@ static WEBP_INLINE uint32_t GammaToLinearS(int v) {
static WEBP_INLINE uint32_t LinearToGammaS(uint32_t value) { static WEBP_INLINE uint32_t LinearToGammaS(uint32_t value) {
// 'value' is in GAMMA_TO_LINEAR_BITS fractional precision // 'value' is in GAMMA_TO_LINEAR_BITS fractional precision
const uint32_t v = value * kGammaTabSize; const uint32_t v = value * GAMMA_TAB_SIZE;
const uint32_t tab_pos = v >> GAMMA_TO_LINEAR_BITS; const uint32_t tab_pos = v >> GAMMA_TO_LINEAR_BITS;
// fractional part, in GAMMA_TO_LINEAR_BITS fixed-point precision // fractional part, in GAMMA_TO_LINEAR_BITS fixed-point precision
const uint32_t x = v - (tab_pos << GAMMA_TO_LINEAR_BITS); // fractional part const uint32_t x = v - (tab_pos << GAMMA_TO_LINEAR_BITS); // fractional part
@ -134,7 +124,7 @@ static fixed_y_t clip_y(int y) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
static int RGBToGray(int r, int g, int b) { static int RGBToGray(int r, int g, int b) {
const int luma = 13933 * r + 46871 * g + 4732 * b + YUV_HALF; const int luma = 13933 * r + 46871 * g + 4732 * b + kYuvHalf;
return (luma >> YUV_FIX); return (luma >> YUV_FIX);
} }
@ -195,7 +185,7 @@ static WEBP_INLINE fixed_y_t Filter2(int A, int B, int W0) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
static WEBP_INLINE fixed_y_t UpLift(uint8_t a) { // 8bit -> SFIX static WEBP_INLINE fixed_y_t UpLift(uint8_t a) { // 8bit -> SFIX
return ((fixed_y_t)a << SFIX) | SHALF; return ((fixed_y_t)a << SFIX) | kSfixHalf;
} }
static void ImportOneRow(const uint8_t* const r_ptr, static void ImportOneRow(const uint8_t* const r_ptr,
@ -255,7 +245,7 @@ static void InterpolateTwoRows(const fixed_y_t* const best_y,
static WEBP_INLINE uint8_t RGBToYUVComponent(int r, int g, int b, static WEBP_INLINE uint8_t RGBToYUVComponent(int r, int g, int b,
const int coeffs[4]) { const int coeffs[4]) {
const int luma = coeffs[0] * r + coeffs[1] * g + coeffs[2] * b + const int luma = coeffs[0] * r + coeffs[1] * g + coeffs[2] * b +
(coeffs[3] << SFIX) + SROUNDER; (coeffs[3] << SFIX) + kYuvRounder;
return clip_8b((luma >> (YUV_FIX + SFIX))); return clip_8b((luma >> (YUV_FIX + SFIX)));
} }

View File

@ -28,35 +28,35 @@ void SharpYuvComputeConversionMatrix(const SharpYuvColorSpace* yuv_color_space,
const int shift = yuv_color_space->bits - 8; const int shift = yuv_color_space->bits - 8;
const float denom = (float)((1 << yuv_color_space->bits) - 1); const float denom = (float)((1 << yuv_color_space->bits) - 1);
float scaleY = 1.0f; float scale_y = 1.0f;
float addY = 0.0f; float addY = 0.0f;
float scaleU = cr; float scale_u = cr;
float scaleV = cb; float scale_v = cb;
float addUV = (float)(128 << shift); float add_uv = (float)(128 << shift);
assert(yuv_color_space->bits >= 8); assert(yuv_color_space->bits >= 8);
if (yuv_color_space->range == kSharpYuvRangeLimited) { if (yuv_color_space->range == kSharpYuvRangeLimited) {
scaleY *= (219 << shift) / denom; scale_y *= (219 << shift) / denom;
scaleU *= (224 << shift) / denom; scale_u *= (224 << shift) / denom;
scaleV *= (224 << shift) / denom; scale_v *= (224 << shift) / denom;
addY = (float)(16 << shift); addY = (float)(16 << shift);
} }
matrix->rgb_to_y[0] = ToFixed16(kr * scaleY); matrix->rgb_to_y[0] = ToFixed16(kr * scale_y);
matrix->rgb_to_y[1] = ToFixed16(kg * scaleY); matrix->rgb_to_y[1] = ToFixed16(kg * scale_y);
matrix->rgb_to_y[2] = ToFixed16(kb * scaleY); matrix->rgb_to_y[2] = ToFixed16(kb * scale_y);
matrix->rgb_to_y[3] = ToFixed16(addY); matrix->rgb_to_y[3] = ToFixed16(addY);
matrix->rgb_to_u[0] = ToFixed16(-kr * scaleU); matrix->rgb_to_u[0] = ToFixed16(-kr * scale_u);
matrix->rgb_to_u[1] = ToFixed16(-kg * scaleU); matrix->rgb_to_u[1] = ToFixed16(-kg * scale_u);
matrix->rgb_to_u[2] = ToFixed16((1 - kb) * scaleU); matrix->rgb_to_u[2] = ToFixed16((1 - kb) * scale_u);
matrix->rgb_to_u[3] = ToFixed16(addUV); matrix->rgb_to_u[3] = ToFixed16(add_uv);
matrix->rgb_to_v[0] = ToFixed16((1 - kr) * scaleV); matrix->rgb_to_v[0] = ToFixed16((1 - kr) * scale_v);
matrix->rgb_to_v[1] = ToFixed16(-kg * scaleV); matrix->rgb_to_v[1] = ToFixed16(-kg * scale_v);
matrix->rgb_to_v[2] = ToFixed16(-kb * scaleV); matrix->rgb_to_v[2] = ToFixed16(-kb * scale_v);
matrix->rgb_to_v[3] = ToFixed16(addUV); matrix->rgb_to_v[3] = ToFixed16(add_uv);
} }
// Matrices are in YUV_FIX fixed point precision. // Matrices are in YUV_FIX fixed point precision.

View File

@ -83,16 +83,16 @@ int WebPPictureHasTransparency(const WebPPicture* picture) {
#if defined(USE_GAMMA_COMPRESSION) #if defined(USE_GAMMA_COMPRESSION)
// gamma-compensates loss of resolution during chroma subsampling // Gamma correction compensates loss of resolution during chroma subsampling.
#define kGamma 0.80 // for now we use a different gamma value than kGammaF #define GAMMA_FIX 12 // fixed-point precision for linear values
#define kGammaFix 12 // fixed-point precision for linear values #define GAMMA_TAB_FIX 7 // fixed-point fractional bits precision
#define kGammaScale ((1 << kGammaFix) - 1) #define GAMMA_TAB_SIZE (1 << (GAMMA_FIX - GAMMA_TAB_FIX))
#define kGammaTabFix 7 // fixed-point fractional bits precision static const double kGamma = 0.80;
#define kGammaTabScale (1 << kGammaTabFix) static const int kGammaScale = ((1 << GAMMA_FIX) - 1);
#define kGammaTabRounder (kGammaTabScale >> 1) static const int kGammaTabScale = (1 << GAMMA_TAB_FIX);
#define kGammaTabSize (1 << (kGammaFix - kGammaTabFix)) static const int kGammaTabRounder = (1 << GAMMA_TAB_FIX >> 1);
static int kLinearToGammaTab[kGammaTabSize + 1]; static int kLinearToGammaTab[GAMMA_TAB_SIZE + 1];
static uint16_t kGammaToLinearTab[256]; static uint16_t kGammaToLinearTab[256];
static volatile int kGammaTablesOk = 0; static volatile int kGammaTablesOk = 0;
static void InitGammaTables(void); static void InitGammaTables(void);
@ -100,13 +100,13 @@ static void InitGammaTables(void);
WEBP_DSP_INIT_FUNC(InitGammaTables) { WEBP_DSP_INIT_FUNC(InitGammaTables) {
if (!kGammaTablesOk) { if (!kGammaTablesOk) {
int v; int v;
const double scale = (double)(1 << kGammaTabFix) / kGammaScale; const double scale = (double)(1 << GAMMA_TAB_FIX) / kGammaScale;
const double norm = 1. / 255.; const double norm = 1. / 255.;
for (v = 0; v <= 255; ++v) { for (v = 0; v <= 255; ++v) {
kGammaToLinearTab[v] = kGammaToLinearTab[v] =
(uint16_t)(pow(norm * v, kGamma) * kGammaScale + .5); (uint16_t)(pow(norm * v, kGamma) * kGammaScale + .5);
} }
for (v = 0; v <= kGammaTabSize; ++v) { for (v = 0; v <= GAMMA_TAB_SIZE; ++v) {
kLinearToGammaTab[v] = (int)(255. * pow(scale * v, 1. / kGamma) + .5); kLinearToGammaTab[v] = (int)(255. * pow(scale * v, 1. / kGamma) + .5);
} }
kGammaTablesOk = 1; kGammaTablesOk = 1;
@ -118,12 +118,12 @@ static WEBP_INLINE uint32_t GammaToLinear(uint8_t v) {
} }
static WEBP_INLINE int Interpolate(int v) { static WEBP_INLINE int Interpolate(int v) {
const int tab_pos = v >> (kGammaTabFix + 2); // integer part const int tab_pos = v >> (GAMMA_TAB_FIX + 2); // integer part
const int x = v & ((kGammaTabScale << 2) - 1); // fractional 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 << 2) - x); // interpolate const int y = v1 * x + v0 * ((kGammaTabScale << 2) - x); // interpolate
assert(tab_pos + 1 < kGammaTabSize + 1); assert(tab_pos + 1 < GAMMA_TAB_SIZE + 1);
return y; return y;
} }
@ -131,7 +131,7 @@ static WEBP_INLINE int Interpolate(int v) {
// U/V value, suitable for RGBToU/V calls. // U/V value, suitable for RGBToU/V calls.
static WEBP_INLINE int LinearToGamma(uint32_t base_value, int shift) { static WEBP_INLINE int LinearToGamma(uint32_t base_value, int shift) {
const int y = Interpolate(base_value << shift); // final uplifted value const int y = Interpolate(base_value << shift); // final uplifted value
return (y + kGammaTabRounder) >> kGammaTabFix; // descale return (y + kGammaTabRounder) >> GAMMA_TAB_FIX; // descale
} }
#else #else
@ -167,16 +167,6 @@ static int RGBToV(int r, int g, int b, VP8Random* const rg) {
static const int kMinDimensionIterativeConversion = 4; static const int kMinDimensionIterativeConversion = 4;
// We could use SFIX=0 and only uint8_t for fixed_y_t, but it produces some
// banding sometimes. Better use extra precision.
#define SFIX 2 // fixed-point precision of RGB and Y/W
typedef int16_t fixed_t; // signed type with extra SFIX precision for UV
typedef uint16_t fixed_y_t; // unsigned type with extra SFIX precision for W
#define SHALF (1 << SFIX >> 1)
#define MAX_Y_T ((256 << SFIX) - 1)
#define SROUNDER (1 << (YUV_FIX + SFIX - 1))
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Main function // Main function
@ -234,8 +224,8 @@ static const int kAlphaFix = 19;
// and constant are adjusted very tightly to fit 32b arithmetic. // and constant are adjusted very tightly to fit 32b arithmetic.
// In particular, they use the fact that the operands for 'v / a' are actually // In particular, they use the fact that the operands for 'v / a' are actually
// derived as v = (a0.p0 + a1.p1 + a2.p2 + a3.p3) and a = a0 + a1 + a2 + a3 // derived as v = (a0.p0 + a1.p1 + a2.p2 + a3.p3) and a = a0 + a1 + a2 + a3
// with ai in [0..255] and pi in [0..1<<kGammaFix). The constraint to avoid // with ai in [0..255] and pi in [0..1<<GAMMA_FIX). The constraint to avoid
// overflow is: kGammaFix + kAlphaFix <= 31. // overflow is: GAMMA_FIX + kAlphaFix <= 31.
static const uint32_t kInvAlpha[4 * 0xff + 1] = { static const uint32_t kInvAlpha[4 * 0xff + 1] = {
0, /* alpha = 0 */ 0, /* alpha = 0 */
524288, 262144, 174762, 131072, 104857, 87381, 74898, 65536, 524288, 262144, 174762, 131072, 104857, 87381, 74898, 65536,
@ -512,7 +502,7 @@ static int ImportYUVAFromRGBA(const uint8_t* r_ptr,
if (has_alpha) { if (has_alpha) {
assert(step == 4); assert(step == 4);
#if defined(USE_GAMMA_COMPRESSION) && defined(USE_INVERSE_ALPHA_TABLE) #if defined(USE_GAMMA_COMPRESSION) && defined(USE_INVERSE_ALPHA_TABLE)
assert(kAlphaFix + kGammaFix <= 31); assert(kAlphaFix + GAMMA_FIX <= 31);
#endif #endif
} }