summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-10-25 21:23:18 +0200
committerwm4 <wm4@nowhere>2012-10-28 15:31:32 +0100
commitd072e857d71150508f308168953753b6c7441009 (patch)
treee0c2263b183cedce7a7e2532122c4025f012963c
parent65b313a8b0b1a97f7d51f1fec4517adaa9334aa3 (diff)
downloadmpv-d072e857d71150508f308168953753b6c7441009.tar.bz2
mpv-d072e857d71150508f308168953753b6c7441009.tar.xz
csputils: better support for integer color values
-rw-r--r--libvo/csputils.c22
-rw-r--r--libvo/csputils.h6
-rw-r--r--sub/draw_bmp.c4
-rw-r--r--sub/spudec.c4
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];
}