diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c index c09de83..9c1735c 100644 --- a/ext/pango/gsttextoverlay.c +++ b/ext/pango/gsttextoverlay.c @@ -138,11 +138,32 @@ GST_DEBUG_CATEGORY (pango_debug); ret = CLAMP (ret, 0, 255); \ } +#define COMP_R(ret, y, u, v) \ +{ \ + ret = (int) (y + (91882 * ((v - 128)) >> 16)); \ +} + +#define COMP_G(ret, y, u, v) \ +{ \ + ret = (int) (y - ((22553 * (u-128)) >> 16) - ((46801 * (v-128)) >> 16)); \ +} + +#define COMP_B(ret, y, u, v) \ +{ \ + ret = (int) (y + ((116130 * (u-128)) >> 16)); \ +} + #define BLEND(ret, alpha, v0, v1) \ { \ ret = (v0 * alpha + v1 * (255 - alpha)) / 255; \ } +#define OVER(ret, alphaA, Ca, alphaB, Cb, alphaNew) \ +{ \ + ret = (Ca * alphaA + Cb * alphaB * (255 - alphaA) / 255) / alphaNew; \ + ret = CLAMP (ret, 0, 255); \ +} + #if G_BYTE_ORDER == G_LITTLE_ENDIAN # define CAIRO_ARGB_A 3 # define CAIRO_ARGB_R 2 @@ -1611,8 +1632,7 @@ static inline void gst_text_overlay_blit_AYUV (GstTextOverlay * overlay, guint8 * rgb_pixels, gint xpos, gint ypos) { - int a, r, g, b; - int y, u, v; + int a, r, g, b, a1, r1, g1, b1; int i, j; int h, w; guchar *pimage, *dest; @@ -1643,14 +1663,22 @@ gst_text_overlay_blit_AYUV (GstTextOverlay * overlay, CAIRO_UNPREMULTIPLY (a, r, g, b); - COMP_Y (y, r, g, b); - COMP_U (u, r, g, b); - COMP_V (v, r, g, b); - - a = (a * dest[0] + 128) >> 8; - BLEND (dest[1], a, y, dest[1]); - BLEND (dest[2], a, u, dest[2]); - BLEND (dest[3], a, v, dest[3]); + // convert background to rgb + COMP_R (r1, dest[1], dest[2], dest[3]); + COMP_G (g1, dest[1], dest[2], dest[3]); + COMP_B (b1, dest[1], dest[2], dest[3]); + + // preform text "OVER" background alpha compositing + a1 = a + (dest[0] * (255 - a)) / 255 + 1; // add 1 to prevent divide by 0 + OVER (r1, a, r, dest[0], r1, a1); + OVER (g1, a, g, dest[0], g1, a1); + OVER (b1, a, b, dest[0], b1, a1); + dest[0] = a1 - 1; // remove the 1 we added now that we are done with calcs + + // convert back to YUV + COMP_Y (dest[1], r1, g1, b1); + COMP_U (dest[2], r1, g1, b1); + COMP_V (dest[3], r1, g1, b1); pimage += 4; dest += 4;