pango: Unpremultiply Cairo's ARGB to match GStreamers ARGB

This commit is contained in:
Sebastian Dröge 2009-10-01 10:37:38 +02:00
parent a8d7e6a490
commit 7c6c74e4a3
2 changed files with 58 additions and 15 deletions

View file

@ -1013,6 +1013,12 @@ gst_text_overlay_adjust_values_with_fontdesc (GstTextOverlay * overlay,
overlay->outline_offset = MINIMUM_OUTLINE_OFFSET; overlay->outline_offset = MINIMUM_OUTLINE_OFFSET;
} }
#define CAIRO_UNPREMULTIPLY(a,r,g,b) G_STMT_START { \
b = (a > 0) ? MIN ((b * 255 + a / 2) / a, 255) : 0; \
g = (a > 0) ? MIN ((g * 255 + a / 2) / a, 255) : 0; \
r = (a > 0) ? MIN ((r * 255 + a / 2) / a, 255) : 0; \
} G_STMT_END
static inline void static inline void
gst_text_overlay_blit_1 (GstTextOverlay * overlay, guchar * dest, gint xpos, gst_text_overlay_blit_1 (GstTextOverlay * overlay, guchar * dest, gint xpos,
gint ypos, guchar * text_image, guint dest_stride) gint ypos, guchar * text_image, guint dest_stride)
@ -1047,6 +1053,8 @@ gst_text_overlay_blit_1 (GstTextOverlay * overlay, guchar * dest, gint xpos,
g = pimage[CAIRO_ARGB_G]; g = pimage[CAIRO_ARGB_G];
r = pimage[CAIRO_ARGB_R]; r = pimage[CAIRO_ARGB_R];
a = pimage[CAIRO_ARGB_A]; a = pimage[CAIRO_ARGB_A];
CAIRO_UNPREMULTIPLY (a, r, g, b);
pimage += 4; pimage += 4;
if (a == 0) { if (a == 0) {
py++; py++;
@ -1067,6 +1075,7 @@ gst_text_overlay_blit_sub2x2cbcr (GstTextOverlay * overlay,
gint i, j; gint i, j;
gint x, cb, cr; gint x, cb, cr;
gushort r, g, b, a; gushort r, g, b, a;
gushort r1, g1, b1, a1;
guchar *pimage1, *pimage2; guchar *pimage1, *pimage2;
guchar *pcb, *pcr; guchar *pcb, *pcr;
gint width = overlay->image_width - 2; gint width = overlay->image_width - 2;
@ -1097,25 +1106,41 @@ gst_text_overlay_blit_sub2x2cbcr (GstTextOverlay * overlay,
g = pimage1[CAIRO_ARGB_G]; g = pimage1[CAIRO_ARGB_G];
r = pimage1[CAIRO_ARGB_R]; r = pimage1[CAIRO_ARGB_R];
a = pimage1[CAIRO_ARGB_A]; a = pimage1[CAIRO_ARGB_A];
CAIRO_UNPREMULTIPLY (a, r, g, b);
pimage1 += 4; pimage1 += 4;
b += pimage1[CAIRO_ARGB_B]; b1 = pimage1[CAIRO_ARGB_B];
g += pimage1[CAIRO_ARGB_G]; g1 = pimage1[CAIRO_ARGB_G];
r += pimage1[CAIRO_ARGB_R]; r1 = pimage1[CAIRO_ARGB_R];
a += pimage1[CAIRO_ARGB_A]; a1 = pimage1[CAIRO_ARGB_A];
CAIRO_UNPREMULTIPLY (a1, r1, g1, b1);
b += b1;
g += g1;
r += r1;
a += a1;
pimage1 += 4; pimage1 += 4;
b += pimage2[CAIRO_ARGB_B]; b1 = pimage2[CAIRO_ARGB_B];
g += pimage2[CAIRO_ARGB_G]; g1 = pimage2[CAIRO_ARGB_G];
r += pimage2[CAIRO_ARGB_R]; r1 = pimage2[CAIRO_ARGB_R];
a += pimage2[CAIRO_ARGB_A]; a1 = pimage2[CAIRO_ARGB_A];
CAIRO_UNPREMULTIPLY (a1, r1, g1, b1);
b += b1;
g += g1;
r += r1;
a += a1;
pimage2 += 4; pimage2 += 4;
/* + 2 for rounding */ /* + 2 for rounding */
b += pimage2[CAIRO_ARGB_B] + 2; b1 = pimage2[CAIRO_ARGB_B];
g += pimage2[CAIRO_ARGB_G] + 2; g1 = pimage2[CAIRO_ARGB_G];
r += pimage2[CAIRO_ARGB_R] + 2; r1 = pimage2[CAIRO_ARGB_R];
a += pimage2[CAIRO_ARGB_A] + 2; a1 = pimage2[CAIRO_ARGB_A];
CAIRO_UNPREMULTIPLY (a1, r1, g1, b1);
b += b1 + 2;
g += g1 + 2;
r += r1 + 2;
a += a1 + 2;
pimage2 += 4; pimage2 += 4;
b /= 4; b /= 4;
@ -1430,12 +1455,14 @@ gst_text_overlay_blit_UYVY (GstTextOverlay * overlay,
g0 = pimage[CAIRO_ARGB_G]; g0 = pimage[CAIRO_ARGB_G];
r0 = pimage[CAIRO_ARGB_R]; r0 = pimage[CAIRO_ARGB_R];
a0 = pimage[CAIRO_ARGB_A]; a0 = pimage[CAIRO_ARGB_A];
CAIRO_UNPREMULTIPLY (a0, r0, g0, b0);
pimage += 4; pimage += 4;
b1 = pimage[CAIRO_ARGB_B]; b1 = pimage[CAIRO_ARGB_B];
g1 = pimage[CAIRO_ARGB_G]; g1 = pimage[CAIRO_ARGB_G];
r1 = pimage[CAIRO_ARGB_R]; r1 = pimage[CAIRO_ARGB_R];
a1 = pimage[CAIRO_ARGB_A]; a1 = pimage[CAIRO_ARGB_A];
CAIRO_UNPREMULTIPLY (a1, r1, g1, b1);
pimage += 4; pimage += 4;
a0 += a1 + 2; a0 += a1 + 2;
@ -1501,9 +1528,13 @@ gst_text_overlay_blit_##name (GstTextOverlay * overlay, \
dest = rgb_pixels + (i + ypos) * 4 * overlay->width + xpos * 4; \ dest = rgb_pixels + (i + ypos) * 4 * overlay->width + xpos * 4; \
for (j = 0; j < w; j++) { \ for (j = 0; j < w; j++) { \
a = pimage[CAIRO_ARGB_A]; \ a = pimage[CAIRO_ARGB_A]; \
b = (pimage[CAIRO_ARGB_B] * a + dest[B] * (255-a)) / 255; \ b = pimage[CAIRO_ARGB_B]; \
g = (pimage[CAIRO_ARGB_G] * a + dest[G] * (255-a)) / 255; \ g = pimage[CAIRO_ARGB_G]; \
r = (pimage[CAIRO_ARGB_R] * a + dest[R] * (255-a)) / 255; \ r = pimage[CAIRO_ARGB_R]; \
CAIRO_UNPREMULTIPLY (a, r, g, b); \
b = (b*a + dest[B] * (255-a)) / 255; \
g = (g*a + dest[G] * (255-a)) / 255; \
r = (r*a + dest[R] * (255-a)) / 255; \
\ \
dest[B] = b; \ dest[B] = b; \
dest[G] = g; \ dest[G] = g; \

View file

@ -387,6 +387,12 @@ gst_text_render_fixate_caps (GstPad * pad, GstCaps * caps)
gst_object_unref (render); gst_object_unref (render);
} }
#define CAIRO_UNPREMULTIPLY(a,r,g,b) G_STMT_START { \
b = (a > 0) ? MIN ((b * 255 + a / 2) / a, 255) : 0; \
g = (a > 0) ? MIN ((g * 255 + a / 2) / a, 255) : 0; \
r = (a > 0) ? MIN ((r * 255 + a / 2) / a, 255) : 0; \
} G_STMT_END
static void static void
gst_text_renderer_image_to_ayuv (GstTextRender * render, guchar * pixbuf, gst_text_renderer_image_to_ayuv (GstTextRender * render, guchar * pixbuf,
int xpos, int ypos, int stride) int xpos, int ypos, int stride)
@ -410,6 +416,9 @@ gst_text_renderer_image_to_ayuv (GstTextRender * render, guchar * pixbuf,
a = bitp[CAIRO_ARGB_A]; a = bitp[CAIRO_ARGB_A];
bitp += 4; bitp += 4;
/* Cairo uses pre-multiplied ARGB, unpremultiply it */
CAIRO_UNPREMULTIPLY (a, r, g, b);
*p++ = a; *p++ = a;
*p++ = CLAMP ((int) (((19595 * r) >> 16) + ((38470 * g) >> 16) + *p++ = CLAMP ((int) (((19595 * r) >> 16) + ((38470 * g) >> 16) +
((7471 * b) >> 16)), 0, 255); ((7471 * b) >> 16)), 0, 255);
@ -441,6 +450,9 @@ gst_text_renderer_image_to_argb (GstTextRender * render, guchar * pixbuf,
p[2] = bitp[CAIRO_ARGB_G]; p[2] = bitp[CAIRO_ARGB_G];
p[3] = bitp[CAIRO_ARGB_B]; p[3] = bitp[CAIRO_ARGB_B];
/* Cairo uses pre-multiplied ARGB, unpremultiply it */
CAIRO_UNPREMULTIPLY (p[0], p[1], p[2], p[3]);
bitp += 4; bitp += 4;
p += 4; p += 4;
} }