From patchwork Wed Apr 11 08:43:12 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jean-Francois Moine X-Patchwork-Id: 10647 Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1SHt8K-0005Rp-0S for patchwork@linuxtv.org; Wed, 11 Apr 2012 10:42:32 +0200 X-tubIT-Incoming-IP: 209.132.180.67 Received: from vger.kernel.org ([209.132.180.67]) by mail.tu-berlin.de (exim-4.75/mailfrontend-4) with esmtp for id 1SHt8J-0002S8-Ad; Wed, 11 Apr 2012 10:42:31 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754178Ab2DKIm3 (ORCPT ); Wed, 11 Apr 2012 04:42:29 -0400 Received: from smtp1-g21.free.fr ([212.27.42.1]:34919 "EHLO smtp1-g21.free.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751175Ab2DKIm1 convert rfc822-to-8bit (ORCPT ); Wed, 11 Apr 2012 04:42:27 -0400 Received: from tele (unknown [IPv6:2a01:e35:2f5c:9de0:212:bfff:fe1e:9ce4]) by smtp1-g21.free.fr (Postfix) with ESMTP id DC9199400E5; Wed, 11 Apr 2012 10:42:18 +0200 (CEST) Date: Wed, 11 Apr 2012 10:43:12 +0200 From: Jean-Francois Moine To: Hans de Goede Cc: linux-media@vger.kernel.org Subject: [PATCH] tinyjpeg: Dynamic luminance quantization table for Pixart JPEG Message-ID: <20120411104312.35d8a7b5@tele> X-Mailer: Claws Mail 3.8.0 (GTK+ 2.24.10; x86_64-pc-linux-gnu) Mime-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-PMX-Version: 5.6.1.2065439, Antispam-Engine: 2.7.2.376379, Antispam-Data: 2012.4.11.83016 X-PMX-Spam: Gauge=IIIIIIII, Probability=8%, Report=' HTML_00_01 0.05, HTML_00_10 0.05, MIME_LOWER_CASE 0.05, MSGID_ADDED_BY_MTA 0.05, BODY_SIZE_4000_4999 0, BODY_SIZE_5000_LESS 0, BODY_SIZE_7000_LESS 0, CT_TEXT_PLAIN_UTF8_CAPS 0, INVALID_MSGID_NO_FQDN 0, URI_ENDS_IN_HTML 0, __ANY_URI 0, __CP_MEDIA_BODY 0, __CP_POSSIBLE_EXPLOIT_SUBJ 0, __CP_URI_IN_BODY 0, __CT 0, __CTE 0, __CT_TEXT_PLAIN 0, __HAS_MSGID 0, __HAS_X_MAILER 0, __HAS_X_MAILING_LIST 0, __MIME_TEXT_ONLY 0, __MIME_VERSION 0, __SANE_MSGID 0, __SUBJ_ALPHA_END 0, __TO_MALFORMED_2 0, __URI_NO_WWW 0, __URI_NS ' In PJPG blocks, a marker gives the quantization tables to use for image decoding. This patch dynamically updates the luminance table when the marker changes. Note that the values of this table have been guessed from a small number of images and that they may not work fine in some situations, but, in most cases, the images are better rendered. Signed-off-by: Jean-François Moine diff --git a/lib/libv4lconvert/tinyjpeg-internal.h b/lib/libv4lconvert/tinyjpeg-internal.h index 702a2a2..4041251 100644 --- a/lib/libv4lconvert/tinyjpeg-internal.h +++ b/lib/libv4lconvert/tinyjpeg-internal.h @@ -103,6 +103,7 @@ struct jdec_private { #if SANITY_CHECK unsigned int current_cid; /* For planar JPEG */ #endif + unsigned char 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 2c2d4af..d986a45 100644 --- a/lib/libv4lconvert/tinyjpeg.c +++ b/lib/libv4lconvert/tinyjpeg.c @@ -1376,6 +1376,8 @@ static void decode_MCU_2x1_3planes(struct jdec_private *priv) IDCT(&priv->component_infos[cCr], priv->Cr, 8); } +static void build_quantization_table(float *qtable, const unsigned char *ref_table); + static void pixart_decode_MCU_2x1_3planes(struct jdec_private *priv) { unsigned char marker; @@ -1384,10 +1386,8 @@ static void pixart_decode_MCU_2x1_3planes(struct jdec_private *priv) /* I think the marker indicates which quantization table to use, iow a Pixart JPEG may have a different quantization table per MCU, most MCU's have 0x44 as marker for which our special Pixart quantization - tables are correct. Unfortunately with a 7302 some blocks also have 0x48, - and sometimes even other values. As 0x48 is quite common too, we really - need to find out the correct table for that, as currently the blocks - with a 0x48 marker look wrong. During normal operation the marker stays + tables are correct. [jfm: snip] + During normal operation the marker stays within the range below, if it gets out of this range we're most likely decoding garbage */ if (marker < 0x20 || marker > 0x7f) { @@ -1396,6 +1396,53 @@ static void pixart_decode_MCU_2x1_3planes(struct jdec_private *priv) (unsigned int)marker); longjmp(priv->jump_state, -EIO); } + + /* rebuild the Y quantization table when the marker changes */ + if (marker != priv->marker) { + unsigned char quant_new[64]; + int i, j; + /* + * table to rebuild the Y quantization table + * index 1 = marker / 4 + * index 2 = 4 end indexes in the quantization table + * values = 0x08, 0x10, 0x20, 0x40, 0x63 + * jfm: The values have been guessed from 4 images, so, + * better values may be found... + */ + static const unsigned char q_tb[12][4] = { + { 6, 28, 43, 64 }, /* 68 */ + { 6, 24, 40, 60 }, + { 4, 18, 30, 55 }, + { 2, 10, 20, 50 }, /* 80 */ + { 1, 6, 15, 46 }, + { 1, 4, 15, 37 }, + { 1, 3, 15, 30 }, + { 1, 2, 15, 21 }, + { 1, 1, 15, 18 }, /* 100 */ + { 1, 1, 15, 16 }, + { 1, 1, 15, 15 }, + { 1, 1, 10, 10 }, + }; + + priv->marker = marker; + j = marker - 68; + if (j < 0) + j = 0; + j >>= 2; + if (j > sizeof q_tb / sizeof q_tb[0]) + j = sizeof q_tb / sizeof q_tb[0] - 1; + for (i = 0; i < q_tb[j][0]; i++) + quant_new[i] = 0x08; + for (; i < q_tb[j][1]; i++) + quant_new[i] = 0x10; + for (; i < q_tb[j][2]; i++) + quant_new[i] = 0x20; + for (; i < q_tb[j][3]; i++) + quant_new[i] = 0x40; + for (; i < 64; i++) + quant_new[i] = 0x63; + build_quantization_table(priv->Q_tables[0], quant_new); + } skip_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, 8); // Y @@ -1948,6 +1995,7 @@ static int parse_JFIF(struct jdec_private *priv, const unsigned char *stream) if (!priv->default_huffman_table_initialized) { build_quantization_table(priv->Q_tables[0], pixart_quantization[0]); build_quantization_table(priv->Q_tables[1], pixart_quantization[1]); + priv->marker = 68; /* common starting marker */ } }