libv4lconvert: Drop Pixart JPEG frames with changing chrominance setting
authorHans de Goede <hdegoede@redhat.com>
Mon, 23 Apr 2012 21:18:24 +0000 (23:18 +0200)
committerHans de Goede <hdegoede@redhat.com>
Wed, 25 Apr 2012 14:40:27 +0000 (16:40 +0200)
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 <hdegoede@redhat.com>
lib/libv4lconvert/tinyjpeg-internal.h
lib/libv4lconvert/tinyjpeg.c

index 4041251..dcbcf27 100644 (file)
@@ -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];
index dd77d0f..8fc484e 100644 (file)
@@ -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;
        }