From: DRC Date: Fri, 18 Feb 2011 01:45:24 +0000 (+0000) Subject: The SIMD quantization algorithm does not produce correct results with the fast forwar... X-Git-Tag: 1.1.0~37 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=72abc29722c11c71375440608efc71f713bb834b;p=libjpeg-turbo The SIMD quantization algorithm does not produce correct results with the fast forward integer DCT and JPEG qualities >= 98, so for now, use the non-SIMD quantization function under those circumstances. git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.1.x@378 632fc199-4ca6-4c93-a231-07263d6284db --- diff --git a/ChangeLog.txt b/ChangeLog.txt index 0097c41..14d251a 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,15 +1,19 @@ 1.1.0 ===== -[1] Since the fast integer forward DCT seems to degrade for JPEG qualities -greater than 95, TurboJPEG/OSS will now automatically use the slow integer -forward DCT when generating JPEG images of quality 96 or greater. This -reduces compression performance by as much as 15% for these high-quality images -but is necessary to ensure that the images are perceptually lossless. +[1] The algorithm used by the SIMD quantization function cannot produce correct +results when the JPEG quality is >= 98 and the fast integer forward DCT is +used. Thus, the non-SIMD quantization function is now used for those cases. -[2] Ported jpgtest.cxx to pure C to avoid the need for a C++ compiler. +[2] Despite the above, the fast integer forward DCT still degrades somewhat for +JPEG qualities greater than 95, so TurboJPEG/OSS will now automatically use the +slow integer forward DCT when generating JPEG images of quality 96 or greater. +This reduces compression performance by as much as 15% for these high-quality +images but is necessary to ensure that the images are perceptually lossless. -[3] Fixed visual artifacts in grayscale JPEG compression caused by a typo in +[3] Ported jpgtest.cxx to pure C to avoid the need for a C++ compiler. + +[4] Fixed visual artifacts in grayscale JPEG compression caused by a typo in the RGB-to-chrominance lookup tables. diff --git a/Makefile.am b/Makefile.am index adfa5c0..ca69a38 100644 --- a/Makefile.am +++ b/Makefile.am @@ -129,6 +129,8 @@ test: testclean all cmp $(srcdir)/testimgint.jpg testoutint.jpg ./cjpeg -dct fast -opt -outfile testoutfst.jpg $(srcdir)/testorig.ppm cmp $(srcdir)/testimgfst.jpg testoutfst.jpg + ./cjpeg -dct fast -quality 100 -opt -outfile testoutfst100.jpg $(srcdir)/testorig.ppm + cmp $(srcdir)/testimgfst100.jpg testoutfst100.jpg ./cjpeg -dct float -outfile testoutflt.jpg $(srcdir)/testorig.ppm if WITH_SIMD cmp $(srcdir)/testimgflt.jpg testoutflt.jpg diff --git a/jcdctmgr.c b/jcdctmgr.c index 156957a..711f9da 100644 --- a/jcdctmgr.c +++ b/jcdctmgr.c @@ -4,6 +4,7 @@ * Copyright (C) 1994-1996, Thomas G. Lane. * Copyright (C) 1999-2006, MIYASAKA Masaru. * Copyright 2009 Pierre Ossman 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 @@ typedef JMETHOD(void, float_quantize_method_ptr, (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 @@ flss (UINT16 val) * 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 @@ compute_reciprocal (UINT16 divisor, DCTELEM * dtbl) 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 @@ start_pass_fdctmgr (j_compress_ptr cinfo) } 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 @@ start_pass_fdctmgr (j_compress_ptr cinfo) } 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; diff --git a/testimgfst100.jpg b/testimgfst100.jpg new file mode 100644 index 0000000..36d9b75 Binary files /dev/null and b/testimgfst100.jpg differ