diff --git a/sharpyuv/sharpyuv.h b/sharpyuv/sharpyuv.h index fe958915..e67c2df2 100644 --- a/sharpyuv/sharpyuv.h +++ b/sharpyuv/sharpyuv.h @@ -66,10 +66,17 @@ extern "C" { SHARPYUV_EXTERN int SharpYuvGetVersion(void); // RGB to YUV conversion matrix, in 16 bit fixed point. -// y = rgb_to_y[0] * r + rgb_to_y[1] * g + rgb_to_y[2] * b + rgb_to_y[3] -// u = rgb_to_u[0] * r + rgb_to_u[1] * g + rgb_to_u[2] * b + rgb_to_u[3] -// v = rgb_to_v[0] * r + rgb_to_v[1] * g + rgb_to_v[2] * b + rgb_to_v[3] -// Then y, u and v values are divided by 1<<16 and rounded. +// y_ = rgb_to_y[0] * r + rgb_to_y[1] * g + rgb_to_y[2] * b + rgb_to_y[3] +// u_ = rgb_to_u[0] * r + rgb_to_u[1] * g + rgb_to_u[2] * b + rgb_to_u[3] +// v_ = rgb_to_v[0] * r + rgb_to_v[1] * g + rgb_to_v[2] * b + rgb_to_v[3] +// Then the values are divided by 1<<16 and rounded. +// y = (y_ + (1 << 15)) >> 16 +// u = (u_ + (1 << 15)) >> 16 +// v = (v_ + (1 << 15)) >> 16 +// +// Typically, the offset values rgb_to_y[3], rgb_to_u[3] and rgb_to_v[3] depend +// on the input's bit depth, e.g., rgb_to_u[3] = 1 << (rgb_bit_depth - 1 + 16). +// See also sharpyuv_csp.h to get a predefined matrix or generate a matrix. typedef struct { int rgb_to_y[4]; int rgb_to_u[4]; @@ -127,6 +134,8 @@ typedef enum SharpYuvTransferFunctionType { // adjacent pixels on the y, u and v channels. If yuv_bit_depth > 8, they // should be multiples of 2. // width, height: width and height of the image in pixels +// yuv_matrix: RGB to YUV conversion matrix. The matrix values typically +// depend on the input's rgb_bit_depth. // This function calls SharpYuvConvertWithOptions with a default transfer // function of kSharpYuvTransferFunctionSrgb. SHARPYUV_EXTERN int SharpYuvConvert(const void* r_ptr, const void* g_ptr, diff --git a/sharpyuv/sharpyuv_csp.c b/sharpyuv/sharpyuv_csp.c index 0ad22be9..a1c9269d 100644 --- a/sharpyuv/sharpyuv_csp.c +++ b/sharpyuv/sharpyuv_csp.c @@ -59,31 +59,31 @@ void SharpYuvComputeConversionMatrix(const SharpYuvColorSpace* yuv_color_space, } // Matrices are in YUV_FIX fixed point precision. -// WebP's matrix, similar but not identical to kRec601LimitedMatrix. +// WebP's matrix, similar but not identical to kRec601LimitedMatrix static const SharpYuvConversionMatrix kWebpMatrix = { {16839, 33059, 6420, 16 << 16}, {-9719, -19081, 28800, 128 << 16}, {28800, -24116, -4684, 128 << 16}, }; -// Kr=0.2990f Kb=0.1140f bits=8 range=kSharpYuvRangeLimited +// Kr=0.2990f Kb=0.1140f bit_depth=8 range=kSharpYuvRangeLimited static const SharpYuvConversionMatrix kRec601LimitedMatrix = { {16829, 33039, 6416, 16 << 16}, {-9714, -19071, 28784, 128 << 16}, {28784, -24103, -4681, 128 << 16}, }; -// Kr=0.2990f Kb=0.1140f bits=8 range=kSharpYuvRangeFull +// Kr=0.2990f Kb=0.1140f bit_depth=8 range=kSharpYuvRangeFull static const SharpYuvConversionMatrix kRec601FullMatrix = { {19595, 38470, 7471, 0}, {-11058, -21710, 32768, 128 << 16}, {32768, -27439, -5329, 128 << 16}, }; -// Kr=0.2126f Kb=0.0722f bits=8 range=kSharpYuvRangeLimited +// Kr=0.2126f Kb=0.0722f bit_depth=8 range=kSharpYuvRangeLimited static const SharpYuvConversionMatrix kRec709LimitedMatrix = { {11966, 40254, 4064, 16 << 16}, {-6596, -22189, 28784, 128 << 16}, {28784, -26145, -2639, 128 << 16}, }; -// Kr=0.2126f Kb=0.0722f bits=8 range=kSharpYuvRangeFull +// Kr=0.2126f Kb=0.0722f bit_depth=8 range=kSharpYuvRangeFull static const SharpYuvConversionMatrix kRec709FullMatrix = { {13933, 46871, 4732, 0}, {-7509, -25259, 32768, 128 << 16}, diff --git a/sharpyuv/sharpyuv_csp.h b/sharpyuv/sharpyuv_csp.h index 3214e3ac..efc01053 100644 --- a/sharpyuv/sharpyuv_csp.h +++ b/sharpyuv/sharpyuv_csp.h @@ -41,10 +41,15 @@ SHARPYUV_EXTERN void SharpYuvComputeConversionMatrix( // Enums for precomputed conversion matrices. typedef enum { + // WebP's matrix, similar but not identical to kSharpYuvMatrixRec601Limited kSharpYuvMatrixWebp = 0, + // Kr=0.2990f Kb=0.1140f bit_depth=8 range=kSharpYuvRangeLimited kSharpYuvMatrixRec601Limited, + // Kr=0.2990f Kb=0.1140f bit_depth=8 range=kSharpYuvRangeFull kSharpYuvMatrixRec601Full, + // Kr=0.2126f Kb=0.0722f bit_depth=8 range=kSharpYuvRangeLimited kSharpYuvMatrixRec709Limited, + // Kr=0.2126f Kb=0.0722f bit_depth=8 range=kSharpYuvRangeFull kSharpYuvMatrixRec709Full, kSharpYuvMatrixNum } SharpYuvMatrixType;