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;
}
#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
gst_text_overlay_blit_1 (GstTextOverlay * overlay, guchar * dest, gint xpos,
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];
r = pimage[CAIRO_ARGB_R];
a = pimage[CAIRO_ARGB_A];
CAIRO_UNPREMULTIPLY (a, r, g, b);
pimage += 4;
if (a == 0) {
py++;
@ -1067,6 +1075,7 @@ gst_text_overlay_blit_sub2x2cbcr (GstTextOverlay * overlay,
gint i, j;
gint x, cb, cr;
gushort r, g, b, a;
gushort r1, g1, b1, a1;
guchar *pimage1, *pimage2;
guchar *pcb, *pcr;
gint width = overlay->image_width - 2;
@ -1097,25 +1106,41 @@ gst_text_overlay_blit_sub2x2cbcr (GstTextOverlay * overlay,
g = pimage1[CAIRO_ARGB_G];
r = pimage1[CAIRO_ARGB_R];
a = pimage1[CAIRO_ARGB_A];
CAIRO_UNPREMULTIPLY (a, r, g, b);
pimage1 += 4;
b += pimage1[CAIRO_ARGB_B];
g += pimage1[CAIRO_ARGB_G];
r += pimage1[CAIRO_ARGB_R];
a += pimage1[CAIRO_ARGB_A];
b1 = pimage1[CAIRO_ARGB_B];
g1 = pimage1[CAIRO_ARGB_G];
r1 = pimage1[CAIRO_ARGB_R];
a1 = pimage1[CAIRO_ARGB_A];
CAIRO_UNPREMULTIPLY (a1, r1, g1, b1);
b += b1;
g += g1;
r += r1;
a += a1;
pimage1 += 4;
b += pimage2[CAIRO_ARGB_B];
g += pimage2[CAIRO_ARGB_G];
r += pimage2[CAIRO_ARGB_R];
a += pimage2[CAIRO_ARGB_A];
b1 = pimage2[CAIRO_ARGB_B];
g1 = pimage2[CAIRO_ARGB_G];
r1 = pimage2[CAIRO_ARGB_R];
a1 = pimage2[CAIRO_ARGB_A];
CAIRO_UNPREMULTIPLY (a1, r1, g1, b1);
b += b1;
g += g1;
r += r1;
a += a1;
pimage2 += 4;
/* + 2 for rounding */
b += pimage2[CAIRO_ARGB_B] + 2;
g += pimage2[CAIRO_ARGB_G] + 2;
r += pimage2[CAIRO_ARGB_R] + 2;
a += pimage2[CAIRO_ARGB_A] + 2;
b1 = pimage2[CAIRO_ARGB_B];
g1 = pimage2[CAIRO_ARGB_G];
r1 = pimage2[CAIRO_ARGB_R];
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;
b /= 4;
@ -1430,12 +1455,14 @@ gst_text_overlay_blit_UYVY (GstTextOverlay * overlay,
g0 = pimage[CAIRO_ARGB_G];
r0 = pimage[CAIRO_ARGB_R];
a0 = pimage[CAIRO_ARGB_A];
CAIRO_UNPREMULTIPLY (a0, r0, g0, b0);
pimage += 4;
b1 = pimage[CAIRO_ARGB_B];
g1 = pimage[CAIRO_ARGB_G];
r1 = pimage[CAIRO_ARGB_R];
a1 = pimage[CAIRO_ARGB_A];
CAIRO_UNPREMULTIPLY (a1, r1, g1, b1);
pimage += 4;
a0 += a1 + 2;
@ -1501,9 +1528,13 @@ gst_text_overlay_blit_##name (GstTextOverlay * overlay, \
dest = rgb_pixels + (i + ypos) * 4 * overlay->width + xpos * 4; \
for (j = 0; j < w; j++) { \
a = pimage[CAIRO_ARGB_A]; \
b = (pimage[CAIRO_ARGB_B] * a + dest[B] * (255-a)) / 255; \
g = (pimage[CAIRO_ARGB_G] * a + dest[G] * (255-a)) / 255; \
r = (pimage[CAIRO_ARGB_R] * a + dest[R] * (255-a)) / 255; \
b = pimage[CAIRO_ARGB_B]; \
g = pimage[CAIRO_ARGB_G]; \
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[G] = g; \

View file

@ -387,6 +387,12 @@ gst_text_render_fixate_caps (GstPad * pad, GstCaps * caps)
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
gst_text_renderer_image_to_ayuv (GstTextRender * render, guchar * pixbuf,
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];
bitp += 4;
/* Cairo uses pre-multiplied ARGB, unpremultiply it */
CAIRO_UNPREMULTIPLY (a, r, g, b);
*p++ = a;
*p++ = CLAMP ((int) (((19595 * r) >> 16) + ((38470 * g) >> 16) +
((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[3] = bitp[CAIRO_ARGB_B];
/* Cairo uses pre-multiplied ARGB, unpremultiply it */
CAIRO_UNPREMULTIPLY (p[0], p[1], p[2], p[3]);
bitp += 4;
p += 4;
}