summaryrefslogtreecommitdiff
path: root/ext/assrender/gstassrender.c
diff options
context:
space:
mode:
authorDavid Schleef <ds@schleef.org>2011-04-14 20:46:52 -0700
committerTim-Philipp Müller <tim.muller@collabora.co.uk>2011-04-16 12:10:14 +0100
commit51e6acad1f6d0bfe9f139bc2d82718f3800a3e2f (patch)
tree5b22a04e5c05908f6e35202e5ab29475c0d27107 /ext/assrender/gstassrender.c
parentb18bf6a018112b3321dbd0ce760fef5820dfec8f (diff)
downloadgstreamer-plugins-bad-51e6acad1f6d0bfe9f139bc2d82718f3800a3e2f.tar.gz
assrender: refactor blitting, avoid writing past end of buffer
Previous blitting code could potentially write past the end of the buffer if the x or y position was odd, and for the same underlying reason, didn't get the chroma registration correct in the odd position case. https://bugzilla.gnome.org/show_bug.cgi?id=647830
Diffstat (limited to 'ext/assrender/gstassrender.c')
-rw-r--r--ext/assrender/gstassrender.c163
1 files changed, 96 insertions, 67 deletions
diff --git a/ext/assrender/gstassrender.c b/ext/assrender/gstassrender.c
index 244e4d8e4..c5a8e1bcd 100644
--- a/ext/assrender/gstassrender.c
+++ b/ext/assrender/gstassrender.c
@@ -618,101 +618,130 @@ blit_i420 (GstAssRender * render, ASS_Image * ass_image, GstBuffer * buffer)
buffer->data + y_offset + ass_image->dst_y * y_stride +
ass_image->dst_x;
dst_u =
- buffer->data + u_offset + ((ass_image->dst_y + 1) / 2) * u_stride +
- (ass_image->dst_x + 1) / 2;
+ buffer->data + u_offset + (ass_image->dst_y / 2) * u_stride +
+ ass_image->dst_x / 2;
dst_v =
- buffer->data + v_offset + ((ass_image->dst_y + 1) / 2) * v_stride +
- (ass_image->dst_x + 1) / 2;
-
- for (y = 0; y < h - 1; y += 2) {
- for (x = 0; x < w - 1; x += 2) {
- k = src[0] * alpha / 255;
- k2 = k;
- dst_y[0] = (k * Y + (255 - k) * dst_y[0]) / 255;
-
- k = src[1] * alpha / 255;
- k2 += k;
- dst_y[1] = (k * Y + (255 - k) * dst_y[1]) / 255;
-
- src += src_stride;
- dst_y += y_stride;
-
- k = src[0] * alpha / 255;
- k2 += k;
- dst_y[0] = (k * Y + (255 - k) * dst_y[0]) / 255;
-
- k = src[1] * alpha / 255;
- k2 += k;
- dst_y[1] = (k * Y + (255 - k) * dst_y[1]) / 255;
+ buffer->data + v_offset + (ass_image->dst_y / 2) * v_stride +
+ ass_image->dst_x / 2;
+
+ for (y = 0; y < h; y++) {
+ dst_y = buffer->data + y_offset + (ass_image->dst_y + y) * y_stride +
+ ass_image->dst_x;
+ for (x = 0; x < w; x++) {
+ k = src[y * ass_image->w + x] * alpha / 255;
+ dst_y[x] = (k * Y + (255 - k) * dst_y[x]) / 255;
+ }
+ }
- k2 /= 4;
+ y = 0;
+ if (ass_image->dst_y & 1) {
+ dst_u =
+ buffer->data + u_offset + (ass_image->dst_y / 2) * u_stride +
+ ass_image->dst_x / 2;
+ dst_v =
+ buffer->data + v_offset + (ass_image->dst_y / 2) * v_stride +
+ ass_image->dst_x / 2;
+ x = 0;
+ if (ass_image->dst_x & 1) {
+ k2 = src[y * ass_image->w + x] * alpha / 255;
+ k2 = (k2 + 2) >> 2;
+ dst_u[0] = (k2 * U + (255 - k2) * dst_u[0]) / 255;
+ dst_v[0] = (k2 * V + (255 - k2) * dst_v[0]) / 255;
+ x++;
+ dst_u++;
+ dst_v++;
+ }
+ for (; x < w - 1; x += 2) {
+ k2 = src[y * ass_image->w + x] * alpha / 255;
+ k2 += src[y * ass_image->w + x + 1] * alpha / 255;
+ k2 = (k2 + 2) >> 2;
dst_u[0] = (k2 * U + (255 - k2) * dst_u[0]) / 255;
dst_v[0] = (k2 * V + (255 - k2) * dst_v[0]) / 255;
dst_u++;
dst_v++;
-
- src += -src_stride + 2;
- dst_y += -y_stride + 2;
}
-
if (x < w) {
- k = src[0] * alpha / 255;
- k2 = k;
- dst_y[0] = (k * Y + (255 - k) * dst_y[0]) / 255;
-
- src += src_stride;
- dst_y += y_stride;
-
- k = src[0] * alpha / 255;
- k2 += k;
- dst_y[0] = (k * Y + (255 - k) * dst_y[0]) / 255;
+ k2 = src[y * ass_image->w + x] * alpha / 255;
+ k2 = (k2 + 2) >> 2;
+ dst_u[0] = (k2 * U + (255 - k2) * dst_u[0]) / 255;
+ dst_v[0] = (k2 * V + (255 - k2) * dst_v[0]) / 255;
+ }
+ }
- k2 /= 2;
+ for (; y < h - 1; y += 2) {
+ dst_u =
+ buffer->data + u_offset + ((ass_image->dst_y + y) / 2) * u_stride +
+ ass_image->dst_x / 2;
+ dst_v =
+ buffer->data + v_offset + ((ass_image->dst_y + y) / 2) * v_stride +
+ ass_image->dst_x / 2;
+ x = 0;
+ if (ass_image->dst_x & 1) {
+ k2 = src[y * ass_image->w + x] * alpha / 255;
+ k2 += src[(y + 1) * ass_image->w + x] * alpha / 255;
+ k2 = (k2 + 2) >> 2;
dst_u[0] = (k2 * U + (255 - k2) * dst_u[0]) / 255;
dst_v[0] = (k2 * V + (255 - k2) * dst_v[0]) / 255;
+ x++;
dst_u++;
dst_v++;
-
- src += -src_stride + 1;
- dst_y += -y_stride + 1;
}
-
- src += src_stride + (src_stride - w);
- dst_y += y_stride + (y_stride - w);
- dst_u += u_stride - w2;
- dst_v += v_stride - w2;
+ for (; x < w - 1; x += 2) {
+ k2 = src[y * ass_image->w + x] * alpha / 255;
+ k2 += src[y * ass_image->w + x + 1] * alpha / 255;
+ k2 += src[(y + 1) * ass_image->w + x] * alpha / 255;
+ k2 += src[(y + 1) * ass_image->w + x + 1] * alpha / 255;
+ k2 = (k2 + 2) >> 2;
+ dst_u[0] = (k2 * U + (255 - k2) * dst_u[0]) / 255;
+ dst_v[0] = (k2 * V + (255 - k2) * dst_v[0]) / 255;
+ dst_u++;
+ dst_v++;
+ }
+ if (x < w) {
+ k2 = src[y * ass_image->w + x] * alpha / 255;
+ k2 += src[(y + 1) * ass_image->w + x] * alpha / 255;
+ k2 = (k2 + 2) >> 2;
+ dst_u[0] = (k2 * U + (255 - k2) * dst_u[0]) / 255;
+ dst_v[0] = (k2 * V + (255 - k2) * dst_v[0]) / 255;
+ }
}
if (y < h) {
- for (x = 0; x < w - 1; x += 2) {
- k = src[0] * alpha / 255;
- k2 = k;
- dst_y[0] = (k * Y + (255 - k) * dst_y[0]) / 255;
-
- k = src[1] * alpha / 255;
- k2 += k;
- dst_y[1] = (k * Y + (255 - k) * dst_y[1]) / 255;
-
- k2 /= 2;
+ dst_u =
+ buffer->data + u_offset + (ass_image->dst_y / 2) * u_stride +
+ ass_image->dst_x / 2;
+ dst_v =
+ buffer->data + v_offset + (ass_image->dst_y / 2) * v_stride +
+ ass_image->dst_x / 2;
+ x = 0;
+ if (ass_image->dst_x & 1) {
+ k2 = src[y * ass_image->w + x] * alpha / 255;
+ k2 = (k2 + 2) >> 2;
+ dst_u[0] = (k2 * U + (255 - k2) * dst_u[0]) / 255;
+ dst_v[0] = (k2 * V + (255 - k2) * dst_v[0]) / 255;
+ x++;
+ dst_u++;
+ dst_v++;
+ }
+ for (; x < w - 1; x += 2) {
+ k2 = src[y * ass_image->w + x] * alpha / 255;
+ k2 += src[y * ass_image->w + x + 1] * alpha / 255;
+ k2 = (k2 + 2) >> 2;
dst_u[0] = (k2 * U + (255 - k2) * dst_u[0]) / 255;
dst_v[0] = (k2 * V + (255 - k2) * dst_v[0]) / 255;
dst_u++;
dst_v++;
-
- src += 2;
- dst_y += 2;
}
-
if (x < w) {
- k = src[0] * alpha / 255;
- k2 = k;
- dst_y[0] = (k * Y + (255 - k) * dst_y[0]) / 255;
-
+ k2 = src[y * ass_image->w + x] * alpha / 255;
+ k2 = (k2 + 2) >> 2;
dst_u[0] = (k2 * U + (255 - k2) * dst_u[0]) / 255;
dst_v[0] = (k2 * V + (255 - k2) * dst_v[0]) / 255;
}
}
+
+
next:
counter++;
ass_image = ass_image->next;