From d072e857d71150508f308168953753b6c7441009 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 25 Oct 2012 21:23:18 +0200 Subject: csputils: better support for integer color values --- libvo/csputils.c | 22 ++++++++++++++++------ libvo/csputils.h | 6 +++++- sub/draw_bmp.c | 4 +++- sub/spudec.c | 4 +++- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/libvo/csputils.c b/libvo/csputils.c index 5ddea3ae55..5d2711b1ce 100644 --- a/libvo/csputils.c +++ b/libvo/csputils.c @@ -230,6 +230,16 @@ void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float m[3][4]) m[i][COL_Y] *= params->contrast; m[i][COL_C] += (rgblev.max-rgblev.min) * (1 - params->contrast)/2; } + + int in_bits = FFMAX(params->int_bits_in, 1); + int out_bits = FFMAX(params->int_bits_out, 1); + double in_scale = (1 << in_bits) - 1.0; + double out_scale = (1 << out_bits) - 1.0; + for (int i = 0; i < 3; i++) { + m[i][COL_C] *= out_scale; // constant is 1.0 + for (int x = 0; x < 3; x++) + m[i][x] *= out_scale / in_scale; + } } //! size of gamma map use to avoid slow exp function in gen_yuv2rgb_map @@ -364,15 +374,15 @@ void mp_invert_yuv2rgb(float out[3][4], float in[3][4]) // Multiply the color in c with the given matrix. // c is {R, G, B} or {Y, U, V} (depending on input/output and matrix). -// Each component is an unsigned number with the given count of bits. -void mp_map_color(float matrix[3][4], int bits, int c[3]) +// Output is clipped to the given number of bits. +void mp_map_int_color(float matrix[3][4], int clip_bits, int c[3]) { - uint8_t in[3] = {c[0], c[1], c[2]}; + int in[3] = {c[0], c[1], c[2]}; for (int i = 0; i < 3; i++) { - double val = matrix[i][3] * 255; + double val = matrix[i][3]; for (int x = 0; x < 3; x++) val += matrix[i][x] * in[x]; - int ival = lrint(val * (1 << (bits - 8))); - c[i] = av_clip(ival, 0, (1 << bits) - 1); + int ival = lrint(val); + c[i] = av_clip(ival, 0, (1 << clip_bits) - 1); } } diff --git a/libvo/csputils.h b/libvo/csputils.h index 1d9ebdc62e..fc6b492441 100644 --- a/libvo/csputils.h +++ b/libvo/csputils.h @@ -69,8 +69,12 @@ struct mp_csp_params { float rgamma; float ggamma; float bgamma; + // texture_bits/input_bits is for rescaling fixed point input to range [0,1] int texture_bits; int input_bits; + // for scaling integer input and output (if 0, assume range [0,1]) + int int_bits_in; + int int_bits_out; }; #define MP_CSP_PARAMS_DEFAULTS { \ @@ -140,6 +144,6 @@ void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float yuv2rgb[3][4]); void mp_gen_yuv2rgb_map(struct mp_csp_params *params, uint8_t *map, int size); void mp_invert_yuv2rgb(float out[3][4], float in[3][4]); -void mp_map_color(float matrix[3][4], int bits, int c[3]); +void mp_map_int_color(float matrix[3][4], int clip_bits, int c[3]); #endif /* MPLAYER_CSPUTILS_H */ diff --git a/sub/draw_bmp.c b/sub/draw_bmp.c index 4740bec6c1..5f68e17f1d 100644 --- a/sub/draw_bmp.c +++ b/sub/draw_bmp.c @@ -283,6 +283,8 @@ static void draw_ass(struct mp_draw_sub_cache **cache, struct mp_rect bb, { struct mp_csp_params cspar = MP_CSP_PARAMS_DEFAULTS; cspar.colorspace = *csp; + cspar.int_bits_in = bits; + cspar.int_bits_out = 8; float yuv2rgb[3][4], rgb2yuv[3][4]; mp_get_yuv2rgb_coeffs(&cspar, yuv2rgb); @@ -301,7 +303,7 @@ static void draw_ass(struct mp_draw_sub_cache **cache, struct mp_rect bb, int b = (sb->libass.color >> 8) & 0xFF; int a = 255 - (sb->libass.color & 0xFF); int color_yuv[3] = {r, g, b}; - mp_map_color(rgb2yuv, bits, color_yuv); + mp_map_int_color(rgb2yuv, bits, color_yuv); int bytes = (bits + 7) / 8; uint8_t *alpha_p = (uint8_t *)sb->bitmap + src_y * sb->stride + src_x; diff --git a/sub/spudec.c b/sub/spudec.c index 3f9e5d701a..2dd030f54a 100644 --- a/sub/spudec.c +++ b/sub/spudec.c @@ -188,6 +188,8 @@ static void setup_palette(spudec_handle_t *spu, uint32_t palette[256]) { memset(palette, 0, sizeof(palette)); struct mp_csp_params csp = MP_CSP_PARAMS_DEFAULTS; + csp.int_bits_in = 8; + csp.int_bits_out = 8; float cmatrix[3][4]; mp_get_yuv2rgb_coeffs(&csp, cmatrix); for (int i = 0; i < 4; ++i) { @@ -199,7 +201,7 @@ static void setup_palette(spudec_handle_t *spu, uint32_t palette[256]) int color = spu->custom ? spu->cuspal[i] : spu->global_palette[spu->palette[i]]; int c[3] = {(color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff}; - mp_map_color(cmatrix, 8, c); + mp_map_int_color(cmatrix, 8, c); // R and G swapped, possibly due to vobsub_palette_to_yuv() palette[i] = (alpha << 24u) | (c[2] << 16) | (c[1] << 8) | c[0]; } -- cgit v1.2.3