From fc97cfe4a795586ea5036ab38bae3227e37959d8 Mon Sep 17 00:00:00 2001 From: DRC Date: Fri, 18 Feb 2011 05:42:10 +0000 Subject: [PATCH] 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 --- common/jpeg/CMakeLists.txt | 2 + common/jpeg/Makefile.am | 6 +- common/jpeg/README-turbo.txt | 128 ++++++++++++++++++++-------------- common/jpeg/configure.ac | 2 +- common/jpeg/jccolor.c | 2 +- common/jpeg/jcdctmgr.c | 18 +++-- common/jpeg/testimgfst100.jpg | Bin 0 -> 18884 bytes common/jpeg/turbojpegl.c | 3 +- 8 files changed, 100 insertions(+), 61 deletions(-) create mode 100644 common/jpeg/testimgfst100.jpg diff --git a/common/jpeg/CMakeLists.txt b/common/jpeg/CMakeLists.txt index cd867e72..e148c9c1 100644 --- a/common/jpeg/CMakeLists.txt +++ b/common/jpeg/CMakeLists.txt @@ -93,6 +93,8 @@ add_test(cjpeg-int cjpeg -dct int -outfile testoutint.jpg ${CMAKE_CURRENT_SOURCE add_test(cjpeg-int-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_CURRENT_SOURCE_DIR}/testimgint.jpg testoutint.jpg) add_test(cjpeg-fast cjpeg -dct fast -opt -outfile testoutfst.jpg ${CMAKE_CURRENT_SOURCE_DIR}/testorig.ppm) add_test(cjpeg-fast-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_CURRENT_SOURCE_DIR}/testimgfst.jpg testoutfst.jpg) +add_test(cjpeg-fast-100 cjpeg -dct fast -quality 100 -opt -outfile testoutfst100.jpg ${CMAKE_CURRENT_SOURCE_DIR}/testorig.ppm) +add_test(cjpeg-fast-100-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_CURRENT_SOURCE_DIR}/testimgfst100.jpg testoutfst100.jpg) add_test(cjpeg-float cjpeg -dct float -outfile testoutflt.jpg ${CMAKE_CURRENT_SOURCE_DIR}/testorig.ppm) if(WITH_SIMD) add_test(cjpeg-float-cmp ${CMAKE_COMMAND} -E compare_files ${CMAKE_CURRENT_SOURCE_DIR}/testimgflt.jpg testoutflt.jpg) diff --git a/common/jpeg/Makefile.am b/common/jpeg/Makefile.am index 3e43874e..cfd8281a 100644 --- a/common/jpeg/Makefile.am +++ b/common/jpeg/Makefile.am @@ -63,7 +63,7 @@ DOCS= jconfig.doc README README-turbo.txt LICENSE.txt LGPL.txt \ TESTFILES= testorig.jpg testorig.ppm testimg.bmp testimgflt.jpg \ testimgfst.jpg testimgint.jpg testimgp.jpg testimgflt.ppm testimgfst.ppm \ - testimgint.ppm testimgflt-nosimd.jpg + testimgint.ppm testimgflt-nosimd.jpg testimgfst100.jpg EXTRA_DIST = win $(DOCS) $(TESTFILES) CMakeLists.txt @@ -77,9 +77,11 @@ test: testclean all ./jpegut ./cjpeg -dct int -outfile testoutint.jpg $(srcdir)/testorig.ppm ./cjpeg -dct fast -opt -outfile testoutfst.jpg $(srcdir)/testorig.ppm + ./cjpeg -dct fast -quality 100 -opt -outfile testoutfst100.jpg $(srcdir)/testorig.ppm ./cjpeg -dct float -outfile testoutflt.jpg $(srcdir)/testorig.ppm cmp $(srcdir)/testimgint.jpg testoutint.jpg cmp $(srcdir)/testimgfst.jpg testoutfst.jpg + cmp $(srcdir)/testimgfst100.jpg testoutfst100.jpg cmp $(srcdir)/testimgflt.jpg testoutflt.jpg ./djpeg -dct int -fast -ppm -outfile testoutint.ppm $(srcdir)/testorig.jpg ./djpeg -dct fast -ppm -outfile testoutfst.ppm $(srcdir)/testorig.jpg @@ -100,9 +102,11 @@ test: testclean all ./jpegut ./cjpeg -dct int -outfile testoutint.jpg $(srcdir)/testorig.ppm ./cjpeg -dct fast -opt -outfile testoutfst.jpg $(srcdir)/testorig.ppm + ./cjpeg -dct fast -quality 100 -opt -outfile testoutfst100.jpg $(srcdir)/testorig.ppm ./cjpeg -dct float -outfile testoutflt.jpg $(srcdir)/testorig.ppm cmp $(srcdir)/testimgint.jpg testoutint.jpg cmp $(srcdir)/testimgfst.jpg testoutfst.jpg + cmp $(srcdir)/testimgfst100.jpg testoutfst100.jpg cmp $(srcdir)/testimgflt-nosimd.jpg testoutflt.jpg ./djpeg -dct int -fast -ppm -outfile testoutint.ppm $(srcdir)/testorig.jpg ./djpeg -dct fast -ppm -outfile testoutfst.ppm $(srcdir)/testorig.jpg diff --git a/common/jpeg/README-turbo.txt b/common/jpeg/README-turbo.txt index 40350d04..f340fd6c 100755 --- a/common/jpeg/README-turbo.txt +++ b/common/jpeg/README-turbo.txt @@ -5,7 +5,7 @@ libjpeg-turbo is a high-speed version of libjpeg for x86 and x86-64 processors which uses SIMD instructions (MMX, SSE2, etc.) to accelerate baseline JPEG compression and decompression. libjpeg-turbo is generally 2-4x as fast -as the unmodified version of libjpeg, all else being equal. +as the unmodified version of libjpeg v6b, all else being equal. libjpeg-turbo was originally based on libjpeg/SIMD by Miyasaka Masaru, but the TigerVNC and VirtualGL projects made numerous enhancements to the codec, @@ -25,21 +25,21 @@ libraries can be used as drop-in replacements for libjpeg on most systems. ** License ******************************************************************************* -Some of the optimizations to the Huffman encoder (jchuff.c) and decoder -(jdhuff.c) were borrowed from VirtualGL, and thus any distribution of -libjpeg-turbo which includes those optimizations must, as a whole, be subject -to the terms of the wxWindows Library Licence, Version 3.1. A copy of this -license can be found in this directory under LICENSE.txt. The wxWindows -Library License is based on the LGPL but includes provisions which allow the -Library to be statically linked into proprietary libraries and applications -without requiring the resulting binaries to be distributed under the terms of -the LGPL. +The TurboJPEG/OSS wrapper, as well as some of the optimizations to the Huffman +encoder (jchuff.c) and decoder (jdhuff.c), were borrowed from VirtualGL, and +thus any distribution of libjpeg-turbo which includes those files must, as a +whole, be subject to the terms of the wxWindows Library Licence, Version 3.1. +A copy of this license can be found in this directory under LICENSE.txt. The +wxWindows Library License is based on the LGPL but includes provisions which +allow the Library to be statically linked into proprietary libraries and +applications without requiring the resulting binaries to be distributed under +the terms of the LGPL. -The rest of the source code, apart from the Huffman codec optimizations, falls -under a less restrictive, BSD-style license (see README.) You can choose to -distribute libjpeg-turbo, as a whole, under this BSD-style license by simply -replacing the optimized jchuff.c and jdhuff.c with their unoptimized -counterparts from the libjpeg v6b source. +The rest of the source code, apart from TurboJPEG/OSS and the Huffman codec +optimizations, falls under a less restrictive, BSD-style license (see README.) +You can choose to distribute libjpeg-turbo, as a whole, under this BSD-style +license by simply removing TurboJPEG/OSS and replacing the optimized jchuff.c +and jdhuff.c with their unoptimized counterparts from the libjpeg v6b source. ******************************************************************************* @@ -51,7 +51,7 @@ Replacing libjpeg at Run Time ============================= If a Unix application is dynamically linked with libjpeg, then you can replace -libjpeg with libjpeg-turbo at run time by manipulating the LD_LIBRARY_PATH. +libjpeg with libjpeg-turbo at run time by manipulating LD_LIBRARY_PATH. For instance: [Using libjpeg] @@ -75,36 +75,36 @@ links to the libjpeg dynamic library located in /opt/libjpeg-turbo/{lib}. This will effectively accelerate every dynamically linked libjpeg application on the system. -The Windows distribution of the libjpeg-turbo SDK installs jpeg62.dll into -c:\libjpeg-turbo\bin, and the PATH environment variable can be modified such -that this directory is searched before any others that might contain +The libjpeg-turbo SDK for Visual C++ installs jpeg62.dll into +c:\libjpeg-turbo[64]\bin, and the PATH environment variable can be modified +such that this directory is searched before any others that might contain jpeg62.dll. However, if jpeg62.dll also exists in an application's install directory, then Windows will load the application's version of it first. Thus, if an application ships with jpeg62.dll, then back up the application's version -of jpeg62.dll and copy c:\libjpeg-turbo\bin\jpeg62.dll into the application's -install directory to accelerate it. +of jpeg62.dll and copy c:\libjpeg-turbo[64]\bin\jpeg62.dll into the +application's install directory to accelerate it. -The version of jpeg62.dll distributed in the libjpeg-turbo SDK requires the -Visual C++ 2008 C run time DLL (msvcr90.dll). This library ships with more -recent versions of Windows, but users of older versions can obtain it from the -Visual C++ 2008 Redistributable Package, which is available as a free download -from Microsoft's web site. +The version of jpeg62.dll distributed in the libjpeg-turbo SDK for Visual C++ +requires the Visual C++ 2008 C run time DLL (msvcr90.dll). msvcr90.dll ships +with more recent versions of Windows, but users of older Windows releases can +obtain it from the Visual C++ 2008 Redistributable Package, which is available +as a free download from Microsoft's web site. NOTE: Features of libjpeg which require passing a C run time structure, such as a file handle, from an application to libjpeg will probably not work with -the distributed version of jpeg62.dll unless the application is also built to -use the Visual C++ 2008 C run time DLL. In particular, this affects -jpeg_stdio_dest() and jpeg_stdio_src(). +the version of jpeg62.dll distributed in the libjpeg-turbo SDK for Visual C++, +unless the application is also built to use the Visual C++ 2008 C run time DLL. +In particular, this affects jpeg_stdio_dest() and jpeg_stdio_src(). Mac applications typically embed their own copies of libjpeg.62.dylib inside the (hidden) application bundle, so it is not possible to globally replace libjpeg on OS X systems. If an application uses a shared library version of libjpeg, then it may be possible to replace the application's version of it. -This would generally involve copying libjpeg.62.dylib into the appropriate -place in the application bundle and using install_name_tool to repoint the -dylib to the new directory. This requires an advanced knowledge of OS X and -would not survive an upgrade or a re-install of the application. Thus, it is -not recommended for most users. +This would generally involve copying libjpeg.62.dylib from libjpeg-turbo into +the appropriate place in the application bundle and using install_name_tool to +repoint the dylib to the new directory. This requires an advanced knowledge of +OS X and would not survive an upgrade or a re-install of the application. +Thus, it is not recommended for most users. ======================= Replacing TurboJPEG/IPP @@ -115,8 +115,8 @@ VirtualGL 2.1.x and TurboVNC 0.6 (and prior.) libjpeg-turbo contains a wrapper library (TurboJPEG/OSS) that emulates the TurboJPEG API using libjpeg-turbo instead of the closed source Intel Performance Primitives. You can replace the TurboJPEG/IPP package on Linux systems with the libjpeg-turbo package in order -to make existing releases of VirtualGL 2.1.x and TurboVNC use the new codec at -run time. Note that the 64-bit libjpeg-turbo packages contain only 64-bit +to make existing releases of VirtualGL 2.1.x and TurboVNC 0.x use the new codec +at run time. Note that the 64-bit libjpeg-turbo packages contain only 64-bit binaries, whereas the TurboJPEG/IPP 64-bit packages contained both 64-bit and 32-bit binaries. Thus, to replace a TurboJPEG/IPP 64-bit package, install both the 64-bit and 32-bit versions of libjpeg-turbo. @@ -132,8 +132,8 @@ Using libjpeg-turbo in Your Own Programs For the most part, libjpeg-turbo should work identically to libjpeg, so in most cases, an application can be built against libjpeg and then run against -libjpeg-turbo. On Unix systems, you can build against libjpeg-turbo instead -of libjpeg by setting +libjpeg-turbo. On Unix systems (including Cygwin), you can build against +libjpeg-turbo instead of libjpeg by setting CPATH=/opt/libjpeg-turbo/include and @@ -142,12 +142,6 @@ of libjpeg by setting ({lib} = lib32 or lib64, depending on whether you are building a 32-bit or a 64-bit application.) -If using Cygwin, then set - - CPATH=/cygdrive/c/libjpeg-turbo-gcc[64]/include - and - LIBRARY_PATH=/cygdrive/c/libjpeg-turbo-gcc[64]/lib - If using MinGW, then set CPATH=/c/libjpeg-turbo-gcc[64]/include @@ -156,11 +150,11 @@ If using MinGW, then set Building against libjpeg-turbo is useful, for instance, if you want to build an application that leverages the libjpeg-turbo colorspace extensions (see below.) -On Linux and Solaris systems, you would still need to manipulate the -LD_LIBRARY_PATH or sym links appropriately to use libjpeg-turbo at run time. -On such systems, you can pass -R /opt/libjpeg-turbo/{lib} to the linker to -force the use of libjpeg-turbo at run time rather than libjpeg (also useful if -you want to leverage the colorspace extensions), or you can link against the +On Linux and Solaris systems, you would still need to manipulate +LD_LIBRARY_PATH or create appropriate sym links to use libjpeg-turbo at run +time. On such systems, you can pass -R /opt/libjpeg-turbo/{lib} to the linker +to force the use of libjpeg-turbo at run time rather than libjpeg (also useful +if you want to leverage the colorspace extensions), or you can link against the libjpeg-turbo static library. To force a Linux, Solaris, or MinGW application to link against the static @@ -172,8 +166,8 @@ On OS X, simply add /opt/libjpeg-turbo/lib/libjpeg.a to the linker command line (this also works on Linux and Solaris.) To build Visual C++ applications using libjpeg-turbo, add -c:\libjpeg-turbo[64]\include to your system or user INCLUDE environment -variable and c:\libjpeg-turbo[64]\lib to your system or user LIB environment +c:\libjpeg-turbo[64]\include to the system or user INCLUDE environment +variable and c:\libjpeg-turbo[64]\lib to the system or user LIB environment variable, and then link against either jpeg.lib (to use jpeg62.dll) or jpeg-static.lib (to use the static version of libjpeg-turbo.) @@ -182,8 +176,8 @@ Colorspace Extensions ===================== libjpeg-turbo includes extensions which allow JPEG images to be compressed -directly from (and decompressed directly to) buffers which use BGR, BGRA, -RGBA, ABGR, and ARGB pixel ordering. This is implemented with six new +directly from (and decompressed directly to) buffers which use BGR, BGRX, +RGBX, XBGR, and XRGB pixel ordering. This is implemented with six new colorspace constants: JCS_EXT_RGB /* red/green/blue */ @@ -205,3 +199,31 @@ time with: At run time, attempting to use these extensions with a version of libjpeg that doesn't support them will result in a "Bogus input colorspace" error. + + +******************************************************************************* +** Performance pitfalls +******************************************************************************* + +=============== +Restart Markers +=============== + +The optimized Huffman decoder in libjpeg-turbo does not handle restart markers +in a way that makes libjpeg happy, so it is necessary to use the slow Huffman +decoder when decompressing a JPEG image that has restart markers. This can +cause the decompression performance to drop by as much as 20%, but the +performance will still be much much greater than that of libjpeg v6b. Many +consumer packages, such as PhotoShop, use restart markers when generating JPEG +images, so images generated by those programs will experience this issue. + +=============================================== +Fast Integer Forward DCT at High Quality Levels +=============================================== + +The algorithm used by the SIMD-accelerated quantization function cannot produce +correct results whenever the fast integer forward DCT is used along with a JPEG +quality of 98-100. Thus, libjpeg-turbo must use the non-SIMD quantization +function in those cases. This causes performance to drop by as much as 40%. +It is therefore strongly advised that you use the slow integer forward DCT +whenever encoding images with a JPEG quality of 98 or higher. diff --git a/common/jpeg/configure.ac b/common/jpeg/configure.ac index 9384d395..050cebda 100644 --- a/common/jpeg/configure.ac +++ b/common/jpeg/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.56]) -AC_INIT([libjpeg-turbo], [1.0.1]) +AC_INIT([libjpeg-turbo], [1.0.2]) AM_INIT_AUTOMAKE([-Wall foreign dist-bzip2]) diff --git a/common/jpeg/jccolor.c b/common/jpeg/jccolor.c index 2e2bfd2a..05da6041 100644 --- a/common/jpeg/jccolor.c +++ b/common/jpeg/jccolor.c @@ -122,7 +122,7 @@ const unsigned char green_lut[256] = { 113, 113, 114, 114, 115, 116, 116, 117, 117, 118, 119, 119, 120, 120, 121, 122, 122, 123, 123, 124, 124, 125, 126, 126, 127, 127, 128, 129, 129, 130, 130, 131, 131, 132, 133, 133, - 34, 134, 135, 136, 136, 137, 137, 138, 139, 139, 140, 140, + 134, 134, 135, 136, 136, 137, 137, 138, 139, 139, 140, 140, 141, 141, 142, 143, 143, 144, 144, 145, 146, 146, 147, 147, 148, 149, 149, 150 }; diff --git a/common/jpeg/jcdctmgr.c b/common/jpeg/jcdctmgr.c index 156957ab..711f9dab 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 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/common/jpeg/testimgfst100.jpg b/common/jpeg/testimgfst100.jpg new file mode 100644 index 0000000000000000000000000000000000000000..36d9b75e64c75d12f01447ab77faddff16b6b4d0 GIT binary patch literal 18884 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 GkN?>`nbk=E literal 0 HcmV?d00001 diff --git a/common/jpeg/turbojpegl.c b/common/jpeg/turbojpegl.c index 2150a2d3..eeaedd17 100644 --- a/common/jpeg/turbojpegl.c +++ b/common/jpeg/turbojpegl.c @@ -166,7 +166,8 @@ DLLEXPORT int DLLCALL tjCompress(tjhandle h, jpeg_set_colorspace(&j->cinfo, JCS_GRAYSCALE); else jpeg_set_colorspace(&j->cinfo, JCS_YCbCr); - j->cinfo.dct_method = JDCT_FASTEST; + if(qual>=96) j->cinfo.dct_method=JDCT_ISLOW; + else j->cinfo.dct_method=JDCT_FASTEST; j->cinfo.comp_info[0].h_samp_factor=hsampfactor[jpegsub]; j->cinfo.comp_info[1].h_samp_factor=1; -- 2.39.5