From 286ba7cf6418a8d34f03336f1245dfa46ec19b71 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 23 Apr 2012 23:18:24 +0200 Subject: [PATCH] libv4lconvert: Drop Pixart JPEG frames with changing chrominance setting Sometimes the pac7302 switches chrominance setting halfway though a frame, with a quite ugly looking result, so lets drop such frames. Signed-off-by: Hans de Goede --- lib/libv4lconvert/tinyjpeg-internal.h | 1 + lib/libv4lconvert/tinyjpeg.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/lib/libv4lconvert/tinyjpeg-internal.h b/lib/libv4lconvert/tinyjpeg-internal.h index 4041251..dcbcf27 100644 --- a/lib/libv4lconvert/tinyjpeg-internal.h +++ b/lib/libv4lconvert/tinyjpeg-internal.h @@ -104,6 +104,7 @@ struct jdec_private { unsigned int current_cid; /* For planar JPEG */ #endif unsigned char marker; /* for PJPG (Pixart JPEG) */ + unsigned char first_marker; /* for PJPG (Pixart JPEG) */ /* Temp space used after the IDCT to store each components */ uint8_t Y[64 * 4], Cr[64], Cb[64]; diff --git a/lib/libv4lconvert/tinyjpeg.c b/lib/libv4lconvert/tinyjpeg.c index dd77d0f..8fc484e 100644 --- a/lib/libv4lconvert/tinyjpeg.c +++ b/lib/libv4lconvert/tinyjpeg.c @@ -1387,6 +1387,16 @@ static void pixart_decode_MCU_2x1_3planes(struct jdec_private *priv) look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, 8, marker); + /* Sometimes the pac7302 switches chrominance setting halfway though a + frame, with a quite ugly looking result, so we drop such frames. */ + if (priv->first_marker == 0) + priv->first_marker = marker; + else if ((marker & 0x80) != (priv->first_marker & 0x80)) { + snprintf(priv->error_string, sizeof(priv->error_string), + "Pixart JPEG error: chrominance changed halfway\n"); + longjmp(priv->jump_state, -EIO); + } + /* Pixart JPEG MCU-s are preceded by a marker indicating the quality setting with which the MCU is compressed, IOW the MCU-s may have a different quantization table per MCU. So if the marker changes we @@ -2224,6 +2234,7 @@ int tinyjpeg_decode(struct jdec_private *priv, int pixfmt) return length; priv->stream = priv->stream_filtered; priv->stream_end = priv->stream + length; + priv->first_marker = 0; decode_mcu_table = pixart_decode_mcu_3comp_table; } -- 2.7.4