From 42b6135b3e8b71822d7fda399dbefe752c634fab Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 3 Nov 2004 18:54:50 +0000 Subject: gst/alpha/gstalpha.c: Fix stride issues. Does not completely work for odd heights. Original commit message from CVS: * gst/alpha/gstalpha.c: (gst_alpha_method_get_type), (gst_alpha_chroma_key), (gst_alpha_chain): Fix stride issues. Does not completely work for odd heights. --- gst/alpha/gstalpha.c | 74 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 16 deletions(-) (limited to 'gst/alpha') diff --git a/gst/alpha/gstalpha.c b/gst/alpha/gstalpha.c index ece724e9..a976df48 100644 --- a/gst/alpha/gstalpha.c +++ b/gst/alpha/gstalpha.c @@ -44,6 +44,7 @@ typedef enum ALPHA_METHOD_ADD, ALPHA_METHOD_GREEN, ALPHA_METHOD_BLUE, + ALPHA_METHOD_BLACK, } GstAlphaMethod; @@ -143,6 +144,7 @@ gst_alpha_method_get_type (void) {ALPHA_METHOD_ADD, "0", "Add alpha channel"}, {ALPHA_METHOD_GREEN, "1", "Chroma Key green"}, {ALPHA_METHOD_BLUE, "2", "Chroma Key blue"}, + {ALPHA_METHOD_BLACK, "3", "Chroma Key black"}, {0, NULL, NULL}, }; @@ -327,6 +329,8 @@ static int yuv_colors_U[] = { 128, 46, 255 }; static int yuv_colors_V[] = { 128, 21, 107 }; */ +#define ROUND_UP_4(x) (((x) + 3) & ~3) + static void gst_alpha_add (guint8 * src, guint8 * dest, gint width, gint height, gdouble alpha) @@ -335,15 +339,25 @@ gst_alpha_add (guint8 * src, guint8 * dest, gint width, gint height, guint8 *srcY; guint8 *srcU; guint8 *srcV; - gint size; - gint half_width = width / 2; gint i, j; + gint w2, h2; + gint size, size2; + gint stride, stride2; + gint wrap, wrap2; + + stride = ROUND_UP_4 (width); + size = stride * height; + w2 = (width + 1) >> 1; + stride2 = ROUND_UP_4 (w2); + h2 = (height + 1) >> 1; + size2 = stride2 * h2; - size = width * height; + wrap = stride - 2 * (width / 2); + wrap2 = stride2 - width / 2; srcY = src; srcU = srcY + size; - srcV = srcU + size / 4; + srcV = srcU + size2; for (i = 0; i < height; i++) { for (j = 0; j < width / 2; j++) { @@ -357,12 +371,19 @@ gst_alpha_add (guint8 * src, guint8 * dest, gint width, gint height, *dest++ = *srcV++; } if (i % 2 == 0) { - srcU -= half_width; - srcV -= half_width; + srcU -= width / 2; + srcV -= width / 2; + } else { + srcU += wrap2; + srcV += wrap2; } + srcY += wrap; } } +#define ROUND_UP_4(x) (((x) + 3) & ~3) +#define ROUND_UP_2(x) (((x) + 1) & ~1) + static void gst_alpha_chroma_key (gchar * src, gchar * dest, gint width, gint height, gboolean soft, gint target_u, gint target_v, gfloat edge_factor, @@ -374,18 +395,30 @@ gst_alpha_chroma_key (gchar * src, gchar * dest, gint width, gint height, guint8 *dest1, *dest2; gint i, j; gint x, z, u, v; - gint size; - - size = width * height; + gint w2, h2; + gint size, size2; + gint stride, stride2; + gint wrap, wrap2, wrap3; + + stride = ROUND_UP_4 (width); + size = stride * height; + w2 = (width + 1) >> 1; + stride2 = ROUND_UP_4 (w2); + h2 = (height + 1) >> 1; + size2 = stride2 * h2; srcY1 = src; - srcY2 = src + width; + srcY2 = src + stride; srcU = srcY1 + size; - srcV = srcU + size / 4; + srcV = srcU + size2; dest1 = dest; dest2 = dest + width * 4; + wrap = 2 * stride - 2 * (width / 2); + wrap2 = stride2 - width / 2; + wrap3 = 8 * width - 8 * (ROUND_UP_2 (width) / 2); + for (i = 0; i < height / 2; i++) { for (j = 0; j < width / 2; j++) { u = *srcU++; @@ -440,10 +473,12 @@ gst_alpha_chroma_key (gchar * src, gchar * dest, gint width, gint height, *dest2++ = u; *dest2++ = v; } - dest1 += width * 4; - dest2 += width * 4; - srcY1 += width; - srcY2 += width; + dest1 += wrap3; + dest2 += wrap3; + srcY1 += wrap; + srcY2 += wrap; + srcU += wrap2; + srcV += wrap2; } } @@ -504,13 +539,20 @@ gst_alpha_chain (GstPad * pad, GstData * _data) gst_alpha_chroma_key (GST_BUFFER_DATA (buffer), GST_BUFFER_DATA (outbuf), new_width, new_height, - TRUE, alpha->target_cr, alpha->target_cb, 1.0, alpha->alpha); + FALSE, alpha->target_cr, alpha->target_cb, 1.0, alpha->alpha); break; case ALPHA_METHOD_BLUE: gst_alpha_chroma_key (GST_BUFFER_DATA (buffer), GST_BUFFER_DATA (outbuf), new_width, new_height, TRUE, 100, 100, 1.0, alpha->alpha); break; + case ALPHA_METHOD_BLACK: + gst_alpha_chroma_key (GST_BUFFER_DATA (buffer), + GST_BUFFER_DATA (outbuf), + new_width, new_height, TRUE, 129, 129, 1.0, alpha->alpha); + break; + default: + break; } gst_buffer_unref (buffer); -- cgit