352a2ee
From 7b9ee388ca510e818dc9f248c8cd6c2ffe40fa94 Mon Sep 17 00:00:00 2001
352a2ee
From: Hans de Goede <hdegoede@redhat.com>
352a2ee
Date: Mon, 23 Apr 2012 23:03:40 +0200
352a2ee
Subject: [PATCH 04/12] libv4lconvert: Dynamic quantization tables for Pixart
352a2ee
 JPEG
352a2ee
MIME-Version: 1.0
352a2ee
Content-Type: text/plain; charset=UTF-8
352a2ee
Content-Transfer-Encoding: 8bit
352a2ee
352a2ee
Inspired by a patch from Jean-Fran├žois Moine <moinejf@free.fr>, I've spend
352a2ee
4 days on a row investigating (through trial and error) Pixart's JPEG
352a2ee
compression. This patch accumulates what I've learned from this, giving 2
352a2ee
important improvements:
352a2ee
1) Support for properly decompressing pac7302 generated images where some
352a2ee
   of the MCU-s are compressed with a lower quality / higher quantization
352a2ee
   values
352a2ee
2) Proper chrominance quantization tables for Pixart JPEG, getting rid of
352a2ee
   the sometimes horribly over saturation our decompression code was causing
352a2ee
352a2ee
The support for dynamic quantization tables this patch adds also allows us to
352a2ee
enable lower compression ratios in the kernel driver when running at a lower
352a2ee
framerate, resulting in better image quality.
352a2ee
352a2ee
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
352a2ee
---
352a2ee
 lib/libv4lconvert/tinyjpeg-internal.h |    1 +
352a2ee
 lib/libv4lconvert/tinyjpeg.c          |   77 ++++++++++++++++++++++-----------
352a2ee
 2 files changed, 53 insertions(+), 25 deletions(-)
352a2ee
352a2ee
diff --git a/lib/libv4lconvert/tinyjpeg-internal.h b/lib/libv4lconvert/tinyjpeg-internal.h
352a2ee
index 702a2a2..4041251 100644
352a2ee
--- a/lib/libv4lconvert/tinyjpeg-internal.h
352a2ee
+++ b/lib/libv4lconvert/tinyjpeg-internal.h
352a2ee
@@ -103,6 +103,7 @@ struct jdec_private {
352a2ee
 #if SANITY_CHECK
352a2ee
 	unsigned int current_cid;			/* For planar JPEG */
352a2ee
 #endif
352a2ee
+	unsigned char marker;			/* for PJPG (Pixart JPEG) */
352a2ee
 
352a2ee
 	/* Temp space used after the IDCT to store each components */
352a2ee
 	uint8_t Y[64 * 4], Cr[64], Cb[64];
352a2ee
diff --git a/lib/libv4lconvert/tinyjpeg.c b/lib/libv4lconvert/tinyjpeg.c
352a2ee
index 756ad9c..dd77d0f 100644
352a2ee
--- a/lib/libv4lconvert/tinyjpeg.c
352a2ee
+++ b/lib/libv4lconvert/tinyjpeg.c
352a2ee
@@ -205,9 +205,11 @@ static const unsigned char val_ac_chrominance[] = {
352a2ee
 	0xf9, 0xfa
352a2ee
 };
352a2ee
 
352a2ee
-const unsigned char pixart_quantization[][64] = { {
352a2ee
-		0x07, 0x07, 0x08, 0x0a, 0x09, 0x07, 0x0d, 0x0b,
352a2ee
-		0x0c, 0x0d, 0x11, 0x10, 0x0f, 0x12, 0x17, 0x27,
352a2ee
+/* Standard JPEG quantization tables from Annex K of the JPEG standard.
352a2ee
+   Note unlike in Annex K the entries here are in zigzag order! */
352a2ee
+const unsigned char standard_quantization[][64] = { {
352a2ee
+		0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
352a2ee
+		0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
352a2ee
 		0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
352a2ee
 		0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
352a2ee
 		0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
352a2ee
@@ -1376,25 +1378,57 @@ static void decode_MCU_2x1_3planes(struct jdec_private *priv)
352a2ee
 	IDCT(&priv->component_infos[cCr], priv->Cr, 8);
352a2ee
 }
352a2ee
 
352a2ee
+static void build_quantization_table(float *qtable, const unsigned char *ref_table);
352a2ee
+
352a2ee
 static void pixart_decode_MCU_2x1_3planes(struct jdec_private *priv)
352a2ee
 {
352a2ee
 	unsigned char marker;
352a2ee
 
352a2ee
-	look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, 8, marker);
352a2ee
-	/* I think the marker indicates which quantization table to use, iow
352a2ee
-	   a Pixart JPEG may have a different quantization table per MCU, most
352a2ee
-	   MCU's have 0x44 as marker for which our special Pixart quantization
352a2ee
-	   tables are correct. Unfortunately with a 7302 some blocks also have 0x48,
352a2ee
-	   and sometimes even other values. As 0x48 is quite common too, we really
352a2ee
-	   need to find out the correct table for that, as currently the blocks
352a2ee
-	   with a 0x48 marker look wrong. During normal operation the marker stays
352a2ee
-	   within the range below, if it gets out of this range we're most likely
352a2ee
-	   decoding garbage */
352a2ee
-	if (marker < 0x20 || marker > 0x7f) {
352a2ee
-		snprintf(priv->error_string, sizeof(priv->error_string),
352a2ee
-				"Pixart JPEG error: invalid MCU marker: 0x%02x\n",
352a2ee
-				(unsigned int)marker);
352a2ee
-		longjmp(priv->jump_state, -EIO);
352a2ee
+	look_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream,
352a2ee
+		   8, marker);
352a2ee
+
352a2ee
+	/* Pixart JPEG MCU-s are preceded by a marker indicating the quality
352a2ee
+	   setting with which the MCU is compressed, IOW the MCU-s may have a
352a2ee
+	   different quantization table per MCU. So if the marker changes we
352a2ee
+	   need to rebuild the quantization tables. */
352a2ee
+	if (marker != priv->marker) {
352a2ee
+		int i, j, comp;
352a2ee
+		unsigned char qt[64];
352a2ee
+		/* These values have been found by trial and error and seem to
352a2ee
+		   work reasonably. Markers with index 0 - 7 are never
352a2ee
+		   generated by the hardware, so they are likely wrong. */
352a2ee
+		const int qfactor[32] = {
352a2ee
+			 10,   12,  14,  16,  18,  20,  22,  24,
352a2ee
+			 25,   30,  35,  40,  45,  50,  55,  60,
352a2ee
+			 64,   68,  80,  90, 100, 120, 140, 160,
352a2ee
+			180,  200, 220, 240, 260, 280, 300, 320
352a2ee
+		};
352a2ee
+
352a2ee
+		i = (marker & 0x7c) >> 2; /* Bits 0 and 1 are always 0 */
352a2ee
+		comp = qfactor[i];
352a2ee
+
352a2ee
+		/* And another special Pixart feature, the DC quantization
352a2ee
+		   factor is fixed! */
352a2ee
+		qt[0] = 7; 
352a2ee
+		for (i = 1; i < 64; i++) {
352a2ee
+			j = (standard_quantization[0][i] * comp + 50) / 100;
352a2ee
+			qt[i] = (j < 255) ? j : 255;
352a2ee
+		}
352a2ee
+		build_quantization_table(priv->Q_tables[0], qt);
352a2ee
+
352a2ee
+		/* And yet another Pixart JPEG special feature, Pixart JPEG
352a2ee
+		   uses the luminance table for chrominance too! Either
352a2ee
+		   as is or with all values multiplied by 2, this is encoded
352a2ee
+		   in bit 7 of the marker. */
352a2ee
+		if (!(marker & 0x80)) {
352a2ee
+			for (i = 0; i < 64; i++) {
352a2ee
+				j = qt[i] * 2;
352a2ee
+				qt[i] = (j < 255) ? j : 255;
352a2ee
+			}
352a2ee
+		}
352a2ee
+		build_quantization_table(priv->Q_tables[1], qt);
352a2ee
+
352a2ee
+		priv->marker = marker;
352a2ee
 	}
352a2ee
 	skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, 8);
352a2ee
 
352a2ee
@@ -1944,13 +1978,6 @@ static int parse_JFIF(struct jdec_private *priv, const unsigned char *stream)
352a2ee
 			(!dqt_marker_found && !(priv->flags & TINYJPEG_FLAGS_PIXART_JPEG)))
352a2ee
 		goto bogus_jpeg_format;
352a2ee
 
352a2ee
-	if (priv->flags & TINYJPEG_FLAGS_PIXART_JPEG) {
352a2ee
-		if (!priv->default_huffman_table_initialized) {
352a2ee
-			build_quantization_table(priv->Q_tables[0], pixart_quantization[0]);
352a2ee
-			build_quantization_table(priv->Q_tables[1], pixart_quantization[1]);
352a2ee
-		}
352a2ee
-	}
352a2ee
-
352a2ee
 	if (!dht_marker_found) {
352a2ee
 		trace("No Huffman table loaded, using the default one\n");
352a2ee
 		if (build_default_huffman_tables(priv))
352a2ee
-- 
352a2ee
1.7.10
352a2ee