diff --git a/libvo/csputils.c b/libvo/csputils.c index b0255a00dc..5ddea3ae55 100644 --- a/libvo/csputils.c +++ b/libvo/csputils.c @@ -364,14 +364,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). -void mp_map_color(float matrix[3][4], uint8_t c[3]) +// 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]) { uint8_t in[3] = {c[0], c[1], c[2]}; for (int i = 0; i < 3; i++) { double val = matrix[i][3] * 255; for (int x = 0; x < 3; x++) val += matrix[i][x] * in[x]; - int ival = lrint(val); - c[i] = FFMIN(FFMAX(ival, 0), 255); + int ival = lrint(val * (1 << (bits - 8))); + c[i] = av_clip(ival, 0, (1 << bits) - 1); } } diff --git a/libvo/csputils.h b/libvo/csputils.h index e4fb32e156..1d9ebdc62e 100644 --- a/libvo/csputils.h +++ b/libvo/csputils.h @@ -139,16 +139,7 @@ void mp_gen_gamma_map(unsigned char *map, int size, float gamma); 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); -#define MP_MAP_YUV2RGB_COLOR(m, y, u, v, scale, c) ((m)[c][0] * (y) + \ - (m)[c][1] * (u) + \ - (m)[c][2] * (v) + \ - (m)[c][3] * (scale)) -#define MP_MAP_RGB2YUV_COLOR(minv, r, g, b, scale, c) ((minv)[c][0] * (r) + \ - (minv)[c][1] * (g) + \ - (minv)[c][2] * (b) + \ - (minv)[c][3] * (scale)) void mp_invert_yuv2rgb(float out[3][4], float in[3][4]); - -void mp_map_color(float matrix[3][4], uint8_t c[3]); +void mp_map_color(float matrix[3][4], int bits, int c[3]); #endif /* MPLAYER_CSPUTILS_H */ diff --git a/sub/draw_bmp.c b/sub/draw_bmp.c index 120e581af8..4740bec6c1 100644 --- a/sub/draw_bmp.c +++ b/sub/draw_bmp.c @@ -281,13 +281,8 @@ static void draw_ass(struct mp_draw_sub_cache **cache, struct mp_rect bb, struct mp_image *temp, int bits, struct mp_csp_details *csp, struct sub_bitmaps *sbs) { - struct mp_csp_params cspar = { - .colorspace = *csp, - .brightness = 0, .contrast = 1, - .hue = 0, .saturation = 1, - .rgamma = 1, .ggamma = 1, .bgamma = 1, - .texture_bits = 8, .input_bits = 8 - }; + struct mp_csp_params cspar = MP_CSP_PARAMS_DEFAULTS; + cspar.colorspace = *csp; float yuv2rgb[3][4], rgb2yuv[3][4]; mp_get_yuv2rgb_coeffs(&cspar, yuv2rgb); @@ -305,20 +300,8 @@ static void draw_ass(struct mp_draw_sub_cache **cache, struct mp_rect bb, int g = (sb->libass.color >> 16) & 0xFF; int b = (sb->libass.color >> 8) & 0xFF; int a = 255 - (sb->libass.color & 0xFF); - int color_yuv[4]; - color_yuv[0] = - rint(MP_MAP_RGB2YUV_COLOR(rgb2yuv, r, g, b, 255, 0) - * (1 << (bits - 8))); - color_yuv[1] = - rint(MP_MAP_RGB2YUV_COLOR(rgb2yuv, r, g, b, 255, 1) - * (1 << (bits - 8))); - color_yuv[2] = - rint(MP_MAP_RGB2YUV_COLOR(rgb2yuv, r, g, b, 255, 2) - * (1 << (bits - 8))); - // NOTE: these overflows can actually happen (when subtitles use color - // 0,0,0 while output levels only allows 16,16,16 upwards...) - for (int i = 0; i < 3; i++) - color_yuv[i] = av_clip(color_yuv[i], 0, ((1 << bits) - 1)); + int color_yuv[3] = {r, g, b}; + mp_map_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 84b4113251..3f9e5d701a 100644 --- a/sub/spudec.c +++ b/sub/spudec.c @@ -198,10 +198,10 @@ static void setup_palette(spudec_handle_t *spu, uint32_t palette[256]) alpha = 0; int color = spu->custom ? spu->cuspal[i] : spu->global_palette[spu->palette[i]]; - uint8_t c[3] = {(color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff}; - mp_map_color(cmatrix, c); + int c[3] = {(color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff}; + mp_map_color(cmatrix, 8, c); // R and G swapped, possibly due to vobsub_palette_to_yuv() - palette[i] = (alpha << 24) | (c[2] << 16) | (c[1] << 8) | c[0]; + palette[i] = (alpha << 24u) | (c[2] << 16) | (c[1] << 8) | c[0]; } }