Merge from libjpeg-turbo 1.0.2, including fixes for errors in generation of grayscale and high-quality JPEGs


git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4294 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/common/jpeg/jcdctmgr.c b/common/jpeg/jcdctmgr.c
index 156957a..711f9da 100644
--- a/common/jpeg/jcdctmgr.c
+++ b/common/jpeg/jcdctmgr.c
@@ -4,6 +4,7 @@
  * Copyright (C) 1994-1996, Thomas G. Lane.
  * Copyright (C) 1999-2006, MIYASAKA Masaru.
  * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ * Copyright (C) 2011 D. R. Commander
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
@@ -39,6 +40,8 @@
                 (JCOEFPTR coef_block, FAST_FLOAT * divisors,
                  FAST_FLOAT * workspace));
 
+METHODDEF(void) quantize (JCOEFPTR, DCTELEM *, DCTELEM *);
+
 typedef struct {
   struct jpeg_forward_dct pub;	/* public fields */
 
@@ -160,7 +163,7 @@
  * of in a consecutive manner, yet again in order to allow SIMD
  * routines.
  */
-LOCAL(void)
+LOCAL(int)
 compute_reciprocal (UINT16 divisor, DCTELEM * dtbl)
 {
   UDCTELEM2 fq, fr;
@@ -189,6 +192,9 @@
   dtbl[DCTSIZE2 * 1] = (DCTELEM) c;       /* correction + roundfactor */
   dtbl[DCTSIZE2 * 2] = (DCTELEM) (1 << (sizeof(DCTELEM)*8*2 - r));  /* scale */
   dtbl[DCTSIZE2 * 3] = (DCTELEM) r - sizeof(DCTELEM)*8; /* shift */
+
+  if(r <= 16) return 0;
+  else return 1;
 }
 
 /*
@@ -232,7 +238,9 @@
       }
       dtbl = fdct->divisors[qtblno];
       for (i = 0; i < DCTSIZE2; i++) {
-	compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i]);
+	if(!compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i])
+	  && fdct->quantize == jsimd_quantize)
+	  fdct->quantize = quantize;
       }
       break;
 #endif
@@ -266,10 +274,12 @@
 	}
 	dtbl = fdct->divisors[qtblno];
 	for (i = 0; i < DCTSIZE2; i++) {
-	  compute_reciprocal(
+	  if(!compute_reciprocal(
 	    DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
 				  (INT32) aanscales[i]),
-		    CONST_BITS-3), &dtbl[i]);
+		    CONST_BITS-3), &dtbl[i])
+	    && fdct->quantize == jsimd_quantize)
+	    fdct->quantize = quantize;
 	}
       }
       break;