summaryrefslogtreecommitdiffstats
path: root/ext/jpeg/gstjpegdec.c
diff options
context:
space:
mode:
authorTim-Philipp Müller <tim@centricular.net>2006-05-22 15:23:05 +0000
committerTim-Philipp Müller <tim@centricular.net>2006-05-22 15:23:05 +0000
commita7157e7467f4d1fddefc8cabfc5971fb18f8b214 (patch)
tree021be34651559622084f27618e9e79171a2419b5 /ext/jpeg/gstjpegdec.c
parentf44640083d8f2efc924301339745573dd8be38a9 (diff)
ext/jpeg/gstjpegdec.c: Fix crashes when the horizontal subsampling is 1.
Original commit message from CVS: * ext/jpeg/gstjpegdec.c: (hresamplecpy1), (gst_jpeg_dec_decode_indirect), (gst_jpeg_dec_chain): Fix crashes when the horizontal subsampling is 1. Fixes #342097.
Diffstat (limited to 'ext/jpeg/gstjpegdec.c')
-rw-r--r--ext/jpeg/gstjpegdec.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/ext/jpeg/gstjpegdec.c b/ext/jpeg/gstjpegdec.c
index 349b8a54..c74f334c 100644
--- a/ext/jpeg/gstjpegdec.c
+++ b/ext/jpeg/gstjpegdec.c
@@ -610,9 +610,24 @@ gst_jpeg_dec_setcaps (GstPad * pad, GstCaps * caps)
return TRUE;
}
+/* yuk */
+static void
+hresamplecpy1 (guint8 * dest, const guint8 * src, guint len)
+{
+ gint i;
+
+ for (i = 0; i < len; ++i) {
+ /* equivalent to: dest[i] = src[i << 1] */
+ *dest = *src;
+ ++dest;
+ ++src;
+ ++src;
+ }
+}
+
static void
gst_jpeg_dec_decode_indirect (GstJpegDec * dec, guchar * base[3],
- guchar * last[3], guint width, guint height, gint r_v)
+ guchar * last[3], guint width, guint height, gint r_v, gint r_h)
{
guchar y[16][MAX_WIDTH];
guchar u[8][MAX_WIDTH / 2];
@@ -626,7 +641,7 @@ gst_jpeg_dec_decode_indirect (GstJpegDec * dec, guchar * base[3],
gint i, j, k;
GST_DEBUG_OBJECT (dec,
- "unadvantageous width, taking slow route involving memcpy");
+ "unadvantageous width or r_h, taking slow route involving memcpy");
for (i = 0; i < height; i += r_v * DCTSIZE) {
jpeg_read_raw_data (&dec->cinfo, scanarray, r_v * DCTSIZE);
@@ -639,8 +654,16 @@ gst_jpeg_dec_decode_indirect (GstJpegDec * dec, guchar * base[3],
if (base[0] < last[0])
base[0] += I420_Y_ROWSTRIDE (width);
}
- memcpy (base[1], u_rows[k], I420_U_ROWSTRIDE (width));
- memcpy (base[2], v_rows[k], I420_V_ROWSTRIDE (width));
+ if (G_LIKELY (r_h == 2)) {
+ memcpy (base[1], u_rows[k], I420_U_ROWSTRIDE (width));
+ memcpy (base[2], v_rows[k], I420_V_ROWSTRIDE (width));
+ } else if (G_UNLIKELY (r_h == 1)) {
+ hresamplecpy1 (base[1], u_rows[k], I420_U_ROWSTRIDE (width));
+ hresamplecpy1 (base[2], v_rows[k], I420_V_ROWSTRIDE (width));
+ } else {
+ /* FIXME: implement (at least we avoid crashing by doing nothing) */
+ }
+
if (r_v == 2 || (k & 1) != 0) {
if (base[1] < last[1] && base[2] < last[2]) {
base[1] += I420_U_ROWSTRIDE (width);
@@ -772,6 +795,7 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
r_h = dec->cinfo.cur_comp_info[0]->h_samp_factor;
r_v = dec->cinfo.cur_comp_info[0]->v_samp_factor;
+ GST_DEBUG ("r_h = %d, r_v = %d", r_h, r_v);
GST_DEBUG ("num_components=%d, comps_in_scan=%d\n",
dec->cinfo.num_components, dec->cinfo.comps_in_scan);
for (i = 0; i < dec->cinfo.comps_in_scan; ++i) {
@@ -879,8 +903,8 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf)
* copy over the data into our final picture buffer, otherwise jpeglib might
* write over the end of a line into the beginning of the next line,
* resulting in blocky artifacts on the left side of the picture. */
- if (width % (dec->cinfo.max_h_samp_factor * DCTSIZE) != 0) {
- gst_jpeg_dec_decode_indirect (dec, base, last, width, height, r_v);
+ if (r_h != 2 || width % (dec->cinfo.max_h_samp_factor * DCTSIZE) != 0) {
+ gst_jpeg_dec_decode_indirect (dec, base, last, width, height, r_v, r_h);
} else {
gst_jpeg_dec_decode_direct (dec, base, last, width, height, r_v);
}