From 5efd6300dc3c4891a8ac928151c3484f9bc7d8fc Mon Sep 17 00:00:00 2001 From: James Zern Date: Thu, 11 Jan 2024 18:02:16 -0800 Subject: [PATCH] mv SharpYuvEstimate420Risk to extras/ There's no need for this in libsharpyuv currently. This avoids an ABI bump and library size increase. Change-Id: I3e4c79052fdb4d628a2d36491547233dd0b6dc34 --- Android.mk | 1 - Makefile.vc | 2 +- build.gradle | 1 - extras/Makefile.am | 1 + extras/extras.c | 166 ++++++++++++++++++++- extras/extras.h | 35 ++++- {sharpyuv => extras}/sharpyuv_risk_table.c | 0 {sharpyuv => extras}/sharpyuv_risk_table.h | 6 +- makefile.unix | 2 +- sharpyuv/Makefile.am | 1 - sharpyuv/sharpyuv.c | 105 +------------ sharpyuv/sharpyuv.h | 32 +--- sharpyuv/sharpyuv_dsp.c | 62 -------- sharpyuv/sharpyuv_dsp.h | 10 -- 14 files changed, 207 insertions(+), 217 deletions(-) rename {sharpyuv => extras}/sharpyuv_risk_table.c (100%) rename {sharpyuv => extras}/sharpyuv_risk_table.h (88%) diff --git a/Android.mk b/Android.mk index a0342b9a..f1e9ad80 100644 --- a/Android.mk +++ b/Android.mk @@ -42,7 +42,6 @@ sharpyuv_srcs := \ sharpyuv/sharpyuv_dsp.c \ sharpyuv/sharpyuv_gamma.c \ sharpyuv/sharpyuv_neon.$(NEON) \ - sharpyuv/sharpyuv_risk_table.c \ sharpyuv/sharpyuv_sse2.c \ dec_srcs := \ diff --git a/Makefile.vc b/Makefile.vc index 32c2db37..985a5c6c 100644 --- a/Makefile.vc +++ b/Makefile.vc @@ -185,7 +185,6 @@ SHARPYUV_OBJS = \ $(DIROBJ)\sharpyuv\sharpyuv_dsp.obj \ $(DIROBJ)\sharpyuv\sharpyuv_gamma.obj \ $(DIROBJ)\sharpyuv\sharpyuv_neon.obj \ - $(DIROBJ)\sharpyuv\sharpyuv_risk_table.obj \ $(DIROBJ)\sharpyuv\sharpyuv_sse2.obj \ DEC_OBJS = \ @@ -322,6 +321,7 @@ ENC_OBJS = \ EXTRAS_OBJS = \ $(DIROBJ)\extras\extras.obj \ $(DIROBJ)\extras\quality_estimate.obj \ + $(DIROBJ)\extras\sharpyuv_risk_table.obj \ IMAGEIO_UTIL_OBJS = \ $(DIROBJ)\imageio\imageio_util.obj \ diff --git a/build.gradle b/build.gradle index b83bcb96..14ceebf7 100644 --- a/build.gradle +++ b/build.gradle @@ -112,7 +112,6 @@ model { include "sharpyuv_dsp.c" include "sharpyuv_gamma.c" include "sharpyuv_neon.c" - include "sharpyuv_risk_table.c" include "sharpyuv_sse2.c" srcDir "src/dec" include "alpha_dec.c" diff --git a/extras/Makefile.am b/extras/Makefile.am index 7e29888b..d5a9af49 100644 --- a/extras/Makefile.am +++ b/extras/Makefile.am @@ -7,6 +7,7 @@ noinst_HEADERS += ../src/webp/types.h libwebpextras_la_SOURCES = libwebpextras_la_SOURCES += extras.c extras.h quality_estimate.c +libwebpextras_la_SOURCES += sharpyuv_risk_table.c sharpyuv_risk_table.h libwebpextras_la_CPPFLAGS = $(AM_CPPFLAGS) libwebpextras_la_LDFLAGS = -lm diff --git a/extras/extras.c b/extras/extras.c index afe5b704..ba9f4bc9 100644 --- a/extras/extras.c +++ b/extras/extras.c @@ -11,12 +11,18 @@ // #include "extras/extras.h" -#include "webp/format_constants.h" -#include "src/dsp/dsp.h" #include +#include #include +#include "extras/sharpyuv_risk_table.h" +#include "sharpyuv/sharpyuv.h" +#include "src/dsp/dsp.h" +#include "src/utils/utils.h" +#include "webp/format_constants.h" +#include "webp/types.h" + #define XTRA_MAJ_VERSION 1 #define XTRA_MIN_VERSION 3 #define XTRA_REV_VERSION 2 @@ -160,3 +166,159 @@ int WebPUnmultiplyARGB(WebPPicture* pic) { } //------------------------------------------------------------------------------ +// 420 risk metric + +#define YUV_FIX 16 // fixed-point precision for RGB->YUV +static const int kYuvHalf = 1 << (YUV_FIX - 1); + +// Maps a value in [0, (256 << YUV_FIX) - 1] to [0, +// precomputed_scores_table_sampling - 1]. It is important that the extremal +// values are preserved and 1:1 mapped: +// ConvertValue(0) = 0 +// ConvertValue((256 << 16) - 1) = rgb_sampling_size - 1 +static int SharpYuvConvertValueToSampledIdx(int v, int rgb_sampling_size) { + v = (v + kYuvHalf) >> YUV_FIX; + v = (v < 0) ? 0 : (v > 255) ? 255 : v; + return (v * (rgb_sampling_size - 1)) / 255; +} + +#undef YUV_FIX + +// For each pixel, computes the index to look up that color in a precomputed +// risk score table where the YUV space is subsampled to a size of +// precomputed_scores_table_sampling^3 (see sharpyuv_risk_table.h) +static int SharpYuvConvertToYuvSharpnessIndex( + int r, int g, int b, const SharpYuvConversionMatrix* matrix, + int precomputed_scores_table_sampling) { + const int y = SharpYuvConvertValueToSampledIdx( + matrix->rgb_to_y[0] * r + matrix->rgb_to_y[1] * g + + matrix->rgb_to_y[2] * b + matrix->rgb_to_y[3], + precomputed_scores_table_sampling); + const int u = SharpYuvConvertValueToSampledIdx( + matrix->rgb_to_u[0] * r + matrix->rgb_to_u[1] * g + + matrix->rgb_to_u[2] * b + matrix->rgb_to_u[3], + precomputed_scores_table_sampling); + const int v = SharpYuvConvertValueToSampledIdx( + matrix->rgb_to_v[0] * r + matrix->rgb_to_v[1] * g + + matrix->rgb_to_v[2] * b + matrix->rgb_to_v[3], + precomputed_scores_table_sampling); + return y + u * precomputed_scores_table_sampling + + v * precomputed_scores_table_sampling * + precomputed_scores_table_sampling; +} + +static void SharpYuvRowToYuvSharpnessIndex( + const uint8_t* r_ptr, const uint8_t* g_ptr, const uint8_t* b_ptr, + int rgb_step, int rgb_bit_depth, int width, uint16_t* dst, + const SharpYuvConversionMatrix* matrix, + int precomputed_scores_table_sampling) { + int i; + assert(rgb_bit_depth == 8); + (void)rgb_bit_depth; // Unused for now. + for (i = 0; i < width; + ++i, r_ptr += rgb_step, g_ptr += rgb_step, b_ptr += rgb_step) { + dst[i] = + SharpYuvConvertToYuvSharpnessIndex(r_ptr[0], g_ptr[0], b_ptr[0], matrix, + precomputed_scores_table_sampling); + } +} + +#define SAFE_ALLOC(W, H, T) ((T*)WebPSafeMalloc((uint64_t)(W) * (H), sizeof(T))) + +static int DoEstimateRisk(const uint8_t* r_ptr, const uint8_t* g_ptr, + const uint8_t* b_ptr, int rgb_step, int rgb_stride, + int rgb_bit_depth, int width, int height, + const SharpYuvOptions* options, + const uint8_t precomputed_scores_table[], + int precomputed_scores_table_sampling, + float* score_out) { + const int sampling3 = precomputed_scores_table_sampling * + precomputed_scores_table_sampling * + precomputed_scores_table_sampling; + const int kNoiseLevel = 4; + double total_score = 0; + double count = 0; + // Rows of indices in + uint16_t* row1 = SAFE_ALLOC(width, 1, uint16_t); + uint16_t* row2 = SAFE_ALLOC(width, 1, uint16_t); + uint16_t* tmp; + int i, j; + + if (row1 == NULL || row2 == NULL) { + WebPFree(row1); + WebPFree(row2); + return 0; + } + + // Convert the first row ahead. + SharpYuvRowToYuvSharpnessIndex(r_ptr, g_ptr, b_ptr, rgb_step, rgb_bit_depth, + width, row2, options->yuv_matrix, + precomputed_scores_table_sampling); + + for (j = 1; j < height; ++j) { + r_ptr += rgb_stride; + g_ptr += rgb_stride; + b_ptr += rgb_stride; + // Swap row 1 and row 2. + tmp = row1; + row1 = row2; + row2 = tmp; + // Convert the row below. + SharpYuvRowToYuvSharpnessIndex(r_ptr, g_ptr, b_ptr, rgb_step, rgb_bit_depth, + width, row2, options->yuv_matrix, + precomputed_scores_table_sampling); + for (i = 0; i < width - 1; ++i) { + const int idx0 = row1[i + 0]; + const int idx1 = row1[i + 1]; + const int idx2 = row2[i + 0]; + const int score = precomputed_scores_table[idx0 + sampling3 * idx1] + + precomputed_scores_table[idx0 + sampling3 * idx2] + + precomputed_scores_table[idx1 + sampling3 * idx2]; + if (score > kNoiseLevel) { + total_score += score; + count += 1.0; + } + } + } + if (count > 0.) total_score /= count; + + // If less than 1% of pixels were evaluated -> below noise level. + if (100. * count / (width * height) < 1.) total_score = 0.; + + // Rescale to [0:100] + total_score = (total_score > 25.) ? 100. : total_score * 100. / 25.; + + WebPFree(row1); + WebPFree(row2); + + *score_out = (float)total_score; + return 1; +} + +#undef SAFE_ALLOC + +int SharpYuvEstimate420Risk(const void* r_ptr, const void* g_ptr, + const void* b_ptr, int rgb_step, int rgb_stride, + int rgb_bit_depth, int width, int height, + const SharpYuvOptions* options, float* score) { + if (width < 1 || height < 1 || width == INT_MAX || height == INT_MAX || + r_ptr == NULL || g_ptr == NULL || b_ptr == NULL || options == NULL || + score == NULL) { + return 0; + } + if (rgb_bit_depth != 8) { + return 0; + } + + if (width <= 4 || height <= 4) { + *score = 0.0f; // too small, no real risk. + return 1; + } + + return DoEstimateRisk( + (const uint8_t*)r_ptr, (const uint8_t*)g_ptr, (const uint8_t*)b_ptr, + rgb_step, rgb_stride, rgb_bit_depth, width, height, options, + kSharpYuvPrecomputedRisk, kSharpYuvPrecomputedRiskYuvSampling, score); +} + +//------------------------------------------------------------------------------ diff --git a/extras/extras.h b/extras/extras.h index c084682f..3cc9d700 100644 --- a/extras/extras.h +++ b/extras/extras.h @@ -17,9 +17,10 @@ extern "C" { #endif +#include "sharpyuv/sharpyuv.h" #include "webp/encode.h" -#define WEBP_EXTRAS_ABI_VERSION 0x0002 // MAJOR(8b) + MINOR(8b) +#define WEBP_EXTRAS_ABI_VERSION 0x0003 // MAJOR(8b) + MINOR(8b) //------------------------------------------------------------------------------ @@ -70,6 +71,38 @@ WEBP_EXTERN int VP8EstimateQuality(const uint8_t* const data, size_t size); //------------------------------------------------------------------------------ +// Computes a score between 0 and 100 which represents the risk of having visual +// quality loss from converting an RGB image to YUV420. +// A low score, typically < 40, means there is a low risk of artifacts from +// chroma subsampling and a simple averaging algorithm can be used instead of +// the more expensive SharpYuvConvert function. +// A medium score, typically >= 40 and < 70, means that simple chroma +// subsampling will produce artifacts and it may be advisable to use the more +// costly SharpYuvConvert for YUV420 conversion. +// A high score, typically >= 70, means there is a very high risk of artifacts +// from chroma subsampling even with SharpYuvConvert, and best results might be +// achieved by using YUV444. +// If not using SharpYuvConvert, a threshold of about 50 can be used to decide +// between (simple averaging) 420 and 444. +// r_ptr, g_ptr, b_ptr: pointers to the source r, g and b channels. Should point +// to uint8_t buffers if rgb_bit_depth is 8, or uint16_t buffers otherwise. +// rgb_step: distance in bytes between two horizontally adjacent pixels on the +// r, g and b channels. If rgb_bit_depth is > 8, it should be a +// multiple of 2. +// rgb_stride: distance in bytes between two vertically adjacent pixels on the +// r, g, and b channels. If rgb_bit_depth is > 8, it should be a +// multiple of 2. +// rgb_bit_depth: number of bits for each r/g/b value. Only a value of 8 is +// currently supported. +// width, height: width and height of the image in pixels +// Returns 0 on failure. +WEBP_EXTERN int SharpYuvEstimate420Risk( + const void* r_ptr, const void* g_ptr, const void* b_ptr, int rgb_step, + int rgb_stride, int rgb_bit_depth, int width, int height, + const SharpYuvOptions* options, float* score); + +//------------------------------------------------------------------------------ + #ifdef __cplusplus } // extern "C" #endif diff --git a/sharpyuv/sharpyuv_risk_table.c b/extras/sharpyuv_risk_table.c similarity index 100% rename from sharpyuv/sharpyuv_risk_table.c rename to extras/sharpyuv_risk_table.c diff --git a/sharpyuv/sharpyuv_risk_table.h b/extras/sharpyuv_risk_table.h similarity index 88% rename from sharpyuv/sharpyuv_risk_table.h rename to extras/sharpyuv_risk_table.h index 81e52ae7..32f276e3 100644 --- a/sharpyuv/sharpyuv_risk_table.h +++ b/extras/sharpyuv_risk_table.h @@ -9,8 +9,8 @@ // // Precomputed data for 420 risk estimation. -#ifndef WEBP_SHARPYUV_SHARPYUV_RISK_TABLE_H_ -#define WEBP_SHARPYUV_SHARPYUV_RISK_TABLE_H_ +#ifndef WEBP_EXTRAS_SHARPYUV_RISK_TABLE_H_ +#define WEBP_EXTRAS_SHARPYUV_RISK_TABLE_H_ #include "src/webp/types.h" @@ -24,4 +24,4 @@ extern const int kSharpYuvPrecomputedRiskYuvSampling; // Table size: kSharpYuvPrecomputedRiskYuvSampling^6 bytes or 114 KiB extern const uint8_t kSharpYuvPrecomputedRisk[]; -#endif // WEBP_SHARPYUV_SHARPYUV_RISK_TABLE_H_ +#endif // WEBP_EXTRAS_SHARPYUV_RISK_TABLE_H_ diff --git a/makefile.unix b/makefile.unix index 7eff6fa0..70f97ff2 100644 --- a/makefile.unix +++ b/makefile.unix @@ -133,7 +133,6 @@ SHARPYUV_OBJS = \ sharpyuv/sharpyuv_dsp.o \ sharpyuv/sharpyuv_gamma.o \ sharpyuv/sharpyuv_neon.o \ - sharpyuv/sharpyuv_risk_table.o \ sharpyuv/sharpyuv_sse2.o \ DEC_OBJS = \ @@ -292,6 +291,7 @@ UTILS_ENC_OBJS = \ EXTRA_OBJS = \ extras/extras.o \ extras/quality_estimate.o \ + extras/sharpyuv_risk_table.o \ LIBWEBPDECODER_OBJS = $(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS) LIBWEBP_OBJS = $(LIBWEBPDECODER_OBJS) $(ENC_OBJS) \ diff --git a/sharpyuv/Makefile.am b/sharpyuv/Makefile.am index 07a1c7f0..8d9ba7ca 100644 --- a/sharpyuv/Makefile.am +++ b/sharpyuv/Makefile.am @@ -30,7 +30,6 @@ libsharpyuv_la_SOURCES += sharpyuv_cpu.c sharpyuv_cpu.h libsharpyuv_la_SOURCES += sharpyuv_csp.c sharpyuv_csp.h libsharpyuv_la_SOURCES += sharpyuv_dsp.c sharpyuv_dsp.h libsharpyuv_la_SOURCES += sharpyuv_gamma.c sharpyuv_gamma.h -libsharpyuv_la_SOURCES += sharpyuv_risk_table.c sharpyuv_risk_table.h libsharpyuv_la_SOURCES += sharpyuv.c sharpyuv.h libsharpyuv_la_CPPFLAGS = $(AM_CPPFLAGS) diff --git a/sharpyuv/sharpyuv.c b/sharpyuv/sharpyuv.c index a76a3569..7cbf668f 100644 --- a/sharpyuv/sharpyuv.c +++ b/sharpyuv/sharpyuv.c @@ -23,7 +23,6 @@ #include "sharpyuv/sharpyuv_cpu.h" #include "sharpyuv/sharpyuv_dsp.h" #include "sharpyuv/sharpyuv_gamma.h" -#include "sharpyuv/sharpyuv_risk_table.h" //------------------------------------------------------------------------------ @@ -436,6 +435,8 @@ static int DoSharpArgbToYuv(const uint8_t* r_ptr, const uint8_t* g_ptr, return ok; } +#undef SAFE_ALLOC + #if defined(WEBP_USE_THREAD) && !defined(_WIN32) #include // NOLINT @@ -571,105 +572,3 @@ int SharpYuvConvertWithOptions(const void* r_ptr, const void* g_ptr, } //------------------------------------------------------------------------------ -// 420 risk metric - -static int DoEstimateRisk(const uint8_t* r_ptr, const uint8_t* g_ptr, - const uint8_t* b_ptr, int rgb_step, int rgb_stride, - int rgb_bit_depth, int width, int height, - const SharpYuvOptions* options, - const uint8_t precomputed_scores_table[], - int precomputed_scores_table_sampling, - float* score_out) { - const int sampling3 = precomputed_scores_table_sampling * - precomputed_scores_table_sampling * - precomputed_scores_table_sampling; - const int kNoiseLevel = 4; - double total_score = 0; - double count = 0; - // Rows of indices in - uint16_t* row1 = SAFE_ALLOC(width, 1, uint16_t); - uint16_t* row2 = SAFE_ALLOC(width, 1, uint16_t); - uint16_t* tmp; - int i, j; - - if (row1 == NULL || row2 == NULL) { - free(row1); - free(row2); - return 0; - } - - // Convert the first row ahead. - SharpYuvRowToYuvSharpnessIndex(r_ptr, g_ptr, b_ptr, rgb_step, rgb_bit_depth, - width, row2, options->yuv_matrix, - precomputed_scores_table_sampling); - - for (j = 1; j < height; ++j) { - r_ptr += rgb_stride; - g_ptr += rgb_stride; - b_ptr += rgb_stride; - // Swap row 1 and row 2. - tmp = row1; - row1 = row2; - row2 = tmp; - // Convert the row below. - SharpYuvRowToYuvSharpnessIndex(r_ptr, g_ptr, b_ptr, rgb_step, rgb_bit_depth, - width, row2, options->yuv_matrix, - precomputed_scores_table_sampling); - for (i = 0; i < width - 1; ++i) { - const int idx0 = row1[i + 0]; - const int idx1 = row1[i + 1]; - const int idx2 = row2[i + 0]; - const int score = precomputed_scores_table[idx0 + sampling3 * idx1] + - precomputed_scores_table[idx0 + sampling3 * idx2] + - precomputed_scores_table[idx1 + sampling3 * idx2]; - if (score > kNoiseLevel) { - total_score += score; - count += 1.0; - } - } - } - if (count > 0.) total_score /= count; - - // If less than 1% of pixels were evaluated -> below noise level. - if (100. * count / (width * height) < 1.) total_score = 0.; - - // Rescale to [0:100] - total_score = (total_score > 25.) ? 100. : total_score * 100. / 25.; - - free(row1); - free(row2); - - *score_out = (float)total_score; - return 1; -} - -int SharpYuvEstimate420Risk(const void* r_ptr, const void* g_ptr, - const void* b_ptr, int rgb_step, int rgb_stride, - int rgb_bit_depth, int width, int height, - const SharpYuvOptions* options, float* score) { - if (width < 1 || height < 1 || width == INT_MAX || height == INT_MAX || - r_ptr == NULL || g_ptr == NULL || b_ptr == NULL || options == NULL || - score == NULL) { - return 0; - } - if (rgb_bit_depth != 8) { - return 0; - } - - if (width <= 4 || height <= 4) { - *score = 0.0f; // too small, no real risk. - return 1; - } - - // The address of the function pointer is used to avoid a read race. - SharpYuvInit((VP8CPUInfo)&SharpYuvGetCPUInfo); - - return DoEstimateRisk( - (const uint8_t*)r_ptr, (const uint8_t*)g_ptr, (const uint8_t*)b_ptr, - rgb_step, rgb_stride, rgb_bit_depth, width, height, options, - kSharpYuvPrecomputedRisk, kSharpYuvPrecomputedRiskYuvSampling, score); -} - -#undef SAFE_ALLOC - -//------------------------------------------------------------------------------ diff --git a/sharpyuv/sharpyuv.h b/sharpyuv/sharpyuv.h index 0027300f..23a69ce3 100644 --- a/sharpyuv/sharpyuv.h +++ b/sharpyuv/sharpyuv.h @@ -53,7 +53,7 @@ extern "C" { // SharpYUV API version following the convention from semver.org #define SHARPYUV_VERSION_MAJOR 0 -#define SHARPYUV_VERSION_MINOR 5 +#define SHARPYUV_VERSION_MINOR 4 #define SHARPYUV_VERSION_PATCH 0 // Version as a uint32_t. The major number is the high 8 bits. // The minor number is the middle 8 bits. The patch number is the low 16 bits. @@ -164,36 +164,6 @@ SHARPYUV_EXTERN int SharpYuvConvertWithOptions( int u_stride, void* v_ptr, int v_stride, int yuv_bit_depth, int width, int height, const SharpYuvOptions* options); -// Computes a score between 0 and 100 which represents the risk of having visual -// quality loss from converting an RGB image to YUV420. -// A low score, typically < 40, means there is a low risk of artifacts from -// chroma subsampling and a simple averaging algorithm can be used instead of -// the more expensive SharpYuvConvert function. -// A medium score, typically >= 40 and < 70, means that simple chroma -// subsampling will produce artifacts and it may be advisable to use the more -// costly SharpYuvConvert for YUV420 conversion. -// A high score, typically >= 70, means there is a very high risk of artifacts -// from chroma subsampling even with SharpYuvConvert, and best results might be -// achieved by using YUV444. -// If not using SharpYuvConvert, a threshold of about 50 can be used to decide -// between (simple averaging) 420 and 444. -// r_ptr, g_ptr, b_ptr: pointers to the source r, g and b channels. Should point -// to uint8_t buffers if rgb_bit_depth is 8, or uint16_t buffers otherwise. -// rgb_step: distance in bytes between two horizontally adjacent pixels on the -// r, g and b channels. If rgb_bit_depth is > 8, it should be a -// multiple of 2. -// rgb_stride: distance in bytes between two vertically adjacent pixels on the -// r, g, and b channels. If rgb_bit_depth is > 8, it should be a -// multiple of 2. -// rgb_bit_depth: number of bits for each r/g/b value. Only a value of 8 is -// currently supported. -// width, height: width and height of the image in pixels -// Returns 0 on failure. -SHARPYUV_EXTERN int SharpYuvEstimate420Risk( - const void* r_ptr, const void* g_ptr, const void* b_ptr, int rgb_step, - int rgb_stride, int rgb_bit_depth, int width, int height, - const SharpYuvOptions* options, float* score); - // TODO(b/194336375): Add YUV444 to YUV420 conversion. Maybe also add 422 // support (it's rarely used in practice, especially for images). diff --git a/sharpyuv/sharpyuv_dsp.c b/sharpyuv/sharpyuv_dsp.c index af379722..94a40ec6 100644 --- a/sharpyuv/sharpyuv_dsp.c +++ b/sharpyuv/sharpyuv_dsp.c @@ -16,7 +16,6 @@ #include #include -#include "sharpyuv/sharpyuv.h" #include "sharpyuv/sharpyuv_cpu.h" #include "src/webp/types.h" @@ -64,58 +63,6 @@ static void SharpYuvFilterRow_C(const int16_t* A, const int16_t* B, int len, } #endif // !WEBP_NEON_OMIT_C_CODE -#define YUV_FIX 16 // fixed-point precision for RGB->YUV -static const int kYuvHalf = 1 << (YUV_FIX - 1); - -// Maps a value in [0, (256 << YUV_FIX) - 1] to [0, -// precomputed_scores_table_sampling - 1]. It is important that the extremal -// values are preserved and 1:1 mapped: -// ConvertValue(0) = 0 -// ConvertValue((256 << 16) - 1) = rgb_sampling_size - 1 -static int SharpYuvConvertValueToSampledIdx(int v, int rgb_sampling_size) { - v = (v + kYuvHalf) >> YUV_FIX; - v = (v < 0) ? 0 : (v > 255) ? 255 : v; - return (v * (rgb_sampling_size - 1)) / 255; -} - -#undef YUV_FIX - -static int SharpYuvConvertToYuvSharpnessIndex( - int r, int g, int b, const SharpYuvConversionMatrix* matrix, - int precomputed_scores_table_sampling) { - const int y = SharpYuvConvertValueToSampledIdx( - matrix->rgb_to_y[0] * r + matrix->rgb_to_y[1] * g + - matrix->rgb_to_y[2] * b + matrix->rgb_to_y[3], - precomputed_scores_table_sampling); - const int u = SharpYuvConvertValueToSampledIdx( - matrix->rgb_to_u[0] * r + matrix->rgb_to_u[1] * g + - matrix->rgb_to_u[2] * b + matrix->rgb_to_u[3], - precomputed_scores_table_sampling); - const int v = SharpYuvConvertValueToSampledIdx( - matrix->rgb_to_v[0] * r + matrix->rgb_to_v[1] * g + - matrix->rgb_to_v[2] * b + matrix->rgb_to_v[3], - precomputed_scores_table_sampling); - return y + u * precomputed_scores_table_sampling + - v * precomputed_scores_table_sampling * - precomputed_scores_table_sampling; -} - -static void SharpYuvRowToYuvSharpnessIndex_C( - const uint8_t* r_ptr, const uint8_t* g_ptr, const uint8_t* b_ptr, - int rgb_step, int rgb_bit_depth, int width, uint16_t* dst, - const SharpYuvConversionMatrix* matrix, - int precomputed_scores_table_sampling) { - int i; - assert(rgb_bit_depth == 8); - (void)rgb_bit_depth; // Unused for now. - for (i = 0; i < width; - ++i, r_ptr += rgb_step, g_ptr += rgb_step, b_ptr += rgb_step) { - dst[i] = - SharpYuvConvertToYuvSharpnessIndex(r_ptr[0], g_ptr[0], b_ptr[0], matrix, - precomputed_scores_table_sampling); - } -} - //----------------------------------------------------------------------------- uint64_t (*SharpYuvUpdateY)(const uint16_t* src, const uint16_t* ref, @@ -124,13 +71,6 @@ void (*SharpYuvUpdateRGB)(const int16_t* src, const int16_t* ref, int16_t* dst, int len); void (*SharpYuvFilterRow)(const int16_t* A, const int16_t* B, int len, const uint16_t* best_y, uint16_t* out, int bit_depth); -void (*SharpYuvRowToYuvSharpnessIndex)(const uint8_t* r_ptr, - const uint8_t* g_ptr, - const uint8_t* b_ptr, int rgb_step, - int rgb_bit_depth, int width, - uint16_t* dst, - const SharpYuvConversionMatrix* matrix, - int precomputed_scores_table_sampling); extern VP8CPUInfo SharpYuvGetCPUInfo; extern void InitSharpYuvSSE2(void); @@ -142,8 +82,6 @@ void SharpYuvInitDsp(void) { SharpYuvUpdateRGB = SharpYuvUpdateRGB_C; SharpYuvFilterRow = SharpYuvFilterRow_C; #endif - // There is only a C version for now so always include it. - SharpYuvRowToYuvSharpnessIndex = SharpYuvRowToYuvSharpnessIndex_C; if (SharpYuvGetCPUInfo != NULL) { #if defined(WEBP_HAVE_SSE2) diff --git a/sharpyuv/sharpyuv_dsp.h b/sharpyuv/sharpyuv_dsp.h index ea238153..805fbadb 100644 --- a/sharpyuv/sharpyuv_dsp.h +++ b/sharpyuv/sharpyuv_dsp.h @@ -12,7 +12,6 @@ #ifndef WEBP_SHARPYUV_SHARPYUV_DSP_H_ #define WEBP_SHARPYUV_SHARPYUV_DSP_H_ -#include "sharpyuv/sharpyuv.h" #include "sharpyuv/sharpyuv_cpu.h" #include "src/webp/types.h" @@ -24,15 +23,6 @@ extern void (*SharpYuvFilterRow)(const int16_t* A, const int16_t* B, int len, const uint16_t* best_y, uint16_t* out, int bit_depth); -// For each pixel, computes the index to look up that color in a precomputed -// risk score table where the YUV space is subsampled to a size of -// precomputed_scores_table_sampling^3 (see sharpyuv_risk_table.h) -extern void (*SharpYuvRowToYuvSharpnessIndex)( - const uint8_t* r_ptr, const uint8_t* g_ptr, const uint8_t* b_ptr, - int rgb_step, int rgb_bit_depth, int width, uint16_t* dst, - const SharpYuvConversionMatrix* matrix, - int precomputed_scores_table_sampling); - void SharpYuvInitDsp(void); #endif // WEBP_SHARPYUV_SHARPYUV_DSP_H_