]> granicus.if.org Git - libjpeg-turbo/commitdiff
Fix negative shift with IFAST FDCT and qual=100
authorDRC <information@libjpeg-turbo.org>
Sat, 29 Aug 2015 23:05:43 +0000 (18:05 -0500)
committerDRC <information@libjpeg-turbo.org>
Sat, 29 Aug 2015 23:10:58 +0000 (18:10 -0500)
With certain images, compressing using quality=100 and the fast integer
forward DCT will cause the divisor passed to compute_reciprocal() to be
1.  In those cases, the library already disables the SIMD quantization
algorithm to avoid 16-bit overflow.  However, compute_reciprocal()
doesn't properly handle the divisor==1 case, so we need to use special
values in that case so that the C quantization algorithm will behave
like an identity function.

ChangeLog.txt
jcdctmgr.c

index 07a7ff7b24e13da741ad1de9330a8cedd610be72..c8b554b09660877a28446964a45b71398862db5f 100644 (file)
@@ -6,6 +6,11 @@ negative width or height was used as an input image (Windows bitmaps can have
 a negative height if they are stored in top-down order, but such files are
 rare and not supported by libjpeg-turbo.)
 
+[2] Fixed an issue whereby, under certain circumstances, libjpeg-turbo would
+incorrectly encode certain JPEG images when quality=100 and the fast integer
+forward DCT were used.  This was known to cause 'make test' to fail when the
+library was built with '-march=haswell' on x86 systems.
+
 
 1.4.1
 =====
index 7d4d3a0673417f433f9fbebc421ae342e6f0fd84..4cac666483985063e7c28439616758a911183f5f 100644 (file)
@@ -6,7 +6,7 @@
  * libjpeg-turbo Modifications:
  * Copyright (C) 1999-2006, MIYASAKA Masaru.
  * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
- * Copyright (C) 2011, 2014 D. R. Commander
+ * Copyright (C) 2011, 2014-2015 D. R. Commander
  * For conditions of distribution and use, see the accompanying README file.
  *
  * This file contains the forward-DCT management logic.
@@ -175,6 +175,19 @@ compute_reciprocal (UINT16 divisor, DCTELEM * dtbl)
   UDCTELEM c;
   int b, r;
 
+  if (divisor == 1) {
+    /* divisor == 1 means unquantized, so these reciprocal/correction/shift
+     * values will cause the C quantization algorithm to act like the
+     * identity function.  Since only the C quantization algorithm is used in
+     * these cases, the scale value is irrelevant.
+     */
+    dtbl[DCTSIZE2 * 0] = (DCTELEM) 1;                       /* reciprocal */
+    dtbl[DCTSIZE2 * 1] = (DCTELEM) 0;                       /* correction */
+    dtbl[DCTSIZE2 * 2] = (DCTELEM) 1;                       /* scale */
+    dtbl[DCTSIZE2 * 3] = (DCTELEM) (-sizeof(DCTELEM) * 8);  /* shift */
+    return 0;
+  }
+
   b = flss(divisor) - 1;
   r  = sizeof(DCTELEM) * 8 + b;
 
@@ -395,7 +408,8 @@ quantize (JCOEFPTR coef_block, DCTELEM * divisors, DCTELEM * workspace)
 
 #if BITS_IN_JSAMPLE == 8
 
-  UDCTELEM recip, corr, shift;
+  UDCTELEM recip, corr;
+  int shift;
   UDCTELEM2 product;
 
   for (i = 0; i < DCTSIZE2; i++) {