michael@0: ******************************************************************************* michael@0: ** Background michael@0: ******************************************************************************* michael@0: michael@0: libjpeg-turbo is a JPEG image codec that uses SIMD instructions (MMX, SSE2, michael@0: NEON) to accelerate baseline JPEG compression and decompression on x86, x86-64, michael@0: and ARM systems. On such systems, libjpeg-turbo is generally 2-4x as fast as michael@0: libjpeg, all else being equal. On other types of systems, libjpeg-turbo can michael@0: still outperform libjpeg by a significant amount, by virtue of its michael@0: highly-optimized Huffman coding routines. In many cases, the performance of michael@0: libjpeg-turbo rivals that of proprietary high-speed JPEG codecs. michael@0: michael@0: libjpeg-turbo implements both the traditional libjpeg API as well as the less michael@0: powerful but more straightforward TurboJPEG API. libjpeg-turbo also features michael@0: colorspace extensions that allow it to compress from/decompress to 32-bit and michael@0: big-endian pixel buffers (RGBX, XBGR, etc.), as well as a full-featured Java michael@0: interface. michael@0: michael@0: libjpeg-turbo was originally based on libjpeg/SIMD, an MMX-accelerated michael@0: derivative of libjpeg v6b developed by Miyasaka Masaru. The TigerVNC and michael@0: VirtualGL projects made numerous enhancements to the codec in 2009, and in michael@0: early 2010, libjpeg-turbo spun off into an independent project, with the goal michael@0: of making high-speed JPEG compression/decompression technology available to a michael@0: broader range of users and developers. michael@0: michael@0: michael@0: ******************************************************************************* michael@0: ** License michael@0: ******************************************************************************* michael@0: michael@0: Most of libjpeg-turbo inherits the non-restrictive, BSD-style license used by michael@0: libjpeg (see README.) The TurboJPEG wrapper (both C and Java versions) and michael@0: associated test programs bear a similar license, which is reproduced below: michael@0: michael@0: Redistribution and use in source and binary forms, with or without michael@0: modification, are permitted provided that the following conditions are met: michael@0: michael@0: - Redistributions of source code must retain the above copyright notice, michael@0: this list of conditions and the following disclaimer. michael@0: - Redistributions in binary form must reproduce the above copyright notice, michael@0: this list of conditions and the following disclaimer in the documentation michael@0: and/or other materials provided with the distribution. michael@0: - Neither the name of the libjpeg-turbo Project nor the names of its michael@0: contributors may be used to endorse or promote products derived from this michael@0: software without specific prior written permission. michael@0: michael@0: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", michael@0: AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE michael@0: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE michael@0: ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE michael@0: LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR michael@0: CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF michael@0: SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS michael@0: INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN michael@0: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) michael@0: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE michael@0: POSSIBILITY OF SUCH DAMAGE. michael@0: michael@0: michael@0: ******************************************************************************* michael@0: ** Using libjpeg-turbo michael@0: ******************************************************************************* michael@0: michael@0: libjpeg-turbo includes two APIs that can be used to compress and decompress michael@0: JPEG images: michael@0: michael@0: TurboJPEG API: This API provides an easy-to-use interface for compressing michael@0: and decompressing JPEG images in memory. It also provides some functionality michael@0: that would not be straightforward to achieve using the underlying libjpeg michael@0: API, such as generating planar YUV images and performing multiple michael@0: simultaneous lossless transforms on an image. The Java interface for michael@0: libjpeg-turbo is written on top of the TurboJPEG API. michael@0: michael@0: libjpeg API: This is the de facto industry-standard API for compressing and michael@0: decompressing JPEG images. It is more difficult to use than the TurboJPEG michael@0: API but also more powerful. The libjpeg API implementation in libjpeg-turbo michael@0: is both API/ABI-compatible and mathematically compatible with libjpeg v6b. michael@0: It can also optionally be configured to be API/ABI-compatible with libjpeg v7 michael@0: and v8 (see below.) michael@0: michael@0: There is no significant performance advantage to either API when both are used michael@0: to perform similar operations. michael@0: michael@0: ====================== michael@0: Installation Directory michael@0: ====================== michael@0: michael@0: This document assumes that libjpeg-turbo will be installed in the default michael@0: directory (/opt/libjpeg-turbo on Un*x and Mac systems and michael@0: c:\libjpeg-turbo[-gcc][64] on Windows systems. If your installation of michael@0: libjpeg-turbo resides in a different directory, then adjust the instructions michael@0: accordingly. michael@0: michael@0: ============================= michael@0: Replacing libjpeg at Run Time michael@0: ============================= michael@0: michael@0: Un*x michael@0: ---- michael@0: michael@0: If a Un*x application is dynamically linked with libjpeg, then you can replace michael@0: libjpeg with libjpeg-turbo at run time by manipulating LD_LIBRARY_PATH. michael@0: For instance: michael@0: michael@0: [Using libjpeg] michael@0: > time cjpeg vgl_5674_0098.jpg michael@0: real 0m0.392s michael@0: user 0m0.074s michael@0: sys 0m0.020s michael@0: michael@0: [Using libjpeg-turbo] michael@0: > export LD_LIBRARY_PATH=/opt/libjpeg-turbo/{lib}:$LD_LIBRARY_PATH michael@0: > time cjpeg vgl_5674_0098.jpg michael@0: real 0m0.109s michael@0: user 0m0.029s michael@0: sys 0m0.010s michael@0: michael@0: ({lib} = lib32 or lib64, depending on whether you wish to use the 32-bit or the michael@0: 64-bit version of libjpeg-turbo.) michael@0: michael@0: System administrators can also replace the libjpeg symlinks in /usr/lib* with michael@0: links to the libjpeg-turbo dynamic library located in /opt/libjpeg-turbo/{lib}. michael@0: This will effectively accelerate every application that uses the libjpeg michael@0: dynamic library on the system. michael@0: michael@0: Windows michael@0: ------- michael@0: michael@0: If a Windows application is dynamically linked with libjpeg, then you can michael@0: replace libjpeg with libjpeg-turbo at run time by backing up the application's michael@0: copy of jpeg62.dll, jpeg7.dll, or jpeg8.dll (assuming the application has its michael@0: own local copy of this library) and copying the corresponding DLL from michael@0: libjpeg-turbo into the application's install directory. The official michael@0: libjpeg-turbo binary packages only provide jpeg62.dll. If the application uses michael@0: jpeg7.dll or jpeg8.dll instead, then it will be necessary to build michael@0: libjpeg-turbo from source (see "libjpeg v7 and v8 API/ABI Emulation" below.) michael@0: michael@0: The following information is specific to the official libjpeg-turbo binary michael@0: packages for Visual C++: michael@0: michael@0: -- jpeg62.dll requires the Visual C++ 2008 C run-time DLL (msvcr90.dll). michael@0: msvcr90.dll ships with more recent versions of Windows, but users of older michael@0: Windows releases can obtain it from the Visual C++ 2008 Redistributable michael@0: Package, which is available as a free download from Microsoft's web site. michael@0: michael@0: -- Features of the libjpeg API that require passing a C run-time structure, michael@0: such as a file handle, from an application to the library will probably not michael@0: work with jpeg62.dll, unless the application is also built to use the Visual michael@0: C++ 2008 C run-time DLL. In particular, this affects jpeg_stdio_dest() and michael@0: jpeg_stdio_src(). michael@0: michael@0: Mac michael@0: --- michael@0: michael@0: Mac applications typically embed their own copies of the libjpeg dylib inside michael@0: the (hidden) application bundle, so it is not possible to globally replace michael@0: libjpeg on OS X systems. Replacing the application's version of the libjpeg michael@0: dylib would generally involve copying libjpeg.*.dylib from libjpeg-turbo into michael@0: the appropriate place in the application bundle and using install_name_tool to michael@0: repoint the libjpeg-turbo dylib to its new directory. This requires an michael@0: advanced knowledge of OS X and would not survive an upgrade or a re-install of michael@0: the application. Thus, it is not recommended for most users. michael@0: michael@0: ======================================== michael@0: Using libjpeg-turbo in Your Own Programs michael@0: ======================================== michael@0: michael@0: For the most part, libjpeg-turbo should work identically to libjpeg, so in michael@0: most cases, an application can be built against libjpeg and then run against michael@0: libjpeg-turbo. On Un*x systems and Cygwin, you can build against libjpeg-turbo michael@0: instead of libjpeg by setting michael@0: michael@0: CPATH=/opt/libjpeg-turbo/include michael@0: and michael@0: LIBRARY_PATH=/opt/libjpeg-turbo/{lib} michael@0: michael@0: ({lib} = lib32 or lib64, depending on whether you are building a 32-bit or a michael@0: 64-bit application.) michael@0: michael@0: If using MinGW, then set michael@0: michael@0: CPATH=/c/libjpeg-turbo-gcc[64]/include michael@0: and michael@0: LIBRARY_PATH=/c/libjpeg-turbo-gcc[64]/lib michael@0: michael@0: Building against libjpeg-turbo is useful, for instance, if you want to build an michael@0: application that leverages the libjpeg-turbo colorspace extensions (see below.) michael@0: On Un*x systems, you would still need to manipulate LD_LIBRARY_PATH or create michael@0: appropriate symlinks to use libjpeg-turbo at run time. On such systems, you michael@0: can pass -R /opt/libjpeg-turbo/{lib} to the linker to force the use of michael@0: libjpeg-turbo at run time rather than libjpeg (also useful if you want to michael@0: leverage the colorspace extensions), or you can link against the libjpeg-turbo michael@0: static library. michael@0: michael@0: To force a Un*x or MinGW application to link against the static version of michael@0: libjpeg-turbo, you can use the following linker options: michael@0: michael@0: -Wl,-Bstatic -ljpeg -Wl,-Bdynamic michael@0: michael@0: On OS X, simply add /opt/libjpeg-turbo/lib/libjpeg.a to the linker command michael@0: line. michael@0: michael@0: To build Visual C++ applications using libjpeg-turbo, add michael@0: c:\libjpeg-turbo[64]\include to the system or user INCLUDE environment michael@0: variable and c:\libjpeg-turbo[64]\lib to the system or user LIB environment michael@0: variable, and then link against either jpeg.lib (to use the DLL version of michael@0: libjpeg-turbo) or jpeg-static.lib (to use the static version of libjpeg-turbo.) michael@0: michael@0: ===================== michael@0: Colorspace Extensions michael@0: ===================== michael@0: michael@0: libjpeg-turbo includes extensions that allow JPEG images to be compressed michael@0: directly from (and decompressed directly to) buffers that use BGR, BGRX, michael@0: RGBX, XBGR, and XRGB pixel ordering. This is implemented with ten new michael@0: colorspace constants: michael@0: michael@0: JCS_EXT_RGB /* red/green/blue */ michael@0: JCS_EXT_RGBX /* red/green/blue/x */ michael@0: JCS_EXT_BGR /* blue/green/red */ michael@0: JCS_EXT_BGRX /* blue/green/red/x */ michael@0: JCS_EXT_XBGR /* x/blue/green/red */ michael@0: JCS_EXT_XRGB /* x/red/green/blue */ michael@0: JCS_EXT_RGBA /* red/green/blue/alpha */ michael@0: JCS_EXT_BGRA /* blue/green/red/alpha */ michael@0: JCS_EXT_ABGR /* alpha/blue/green/red */ michael@0: JCS_EXT_ARGB /* alpha/red/green/blue */ michael@0: michael@0: Setting cinfo.in_color_space (compression) or cinfo.out_color_space michael@0: (decompression) to one of these values will cause libjpeg-turbo to read the michael@0: red, green, and blue values from (or write them to) the appropriate position in michael@0: the pixel when compressing from/decompressing to an RGB buffer. michael@0: michael@0: Your application can check for the existence of these extensions at compile michael@0: time with: michael@0: michael@0: #ifdef JCS_EXTENSIONS michael@0: michael@0: At run time, attempting to use these extensions with a libjpeg implementation michael@0: that does not support them will result in a "Bogus input colorspace" error. michael@0: Applications can trap this error in order to test whether run-time support is michael@0: available for the colorspace extensions. michael@0: michael@0: When using the RGBX, BGRX, XBGR, and XRGB colorspaces during decompression, the michael@0: X byte is undefined, and in order to ensure the best performance, libjpeg-turbo michael@0: can set that byte to whatever value it wishes. If an application expects the X michael@0: byte to be used as an alpha channel, then it should specify JCS_EXT_RGBA, michael@0: JCS_EXT_BGRA, JCS_EXT_ABGR, or JCS_EXT_ARGB. When these colorspace constants michael@0: are used, the X byte is guaranteed to be 0xFF, which is interpreted as opaque. michael@0: michael@0: Your application can check for the existence of the alpha channel colorspace michael@0: extensions at compile time with: michael@0: michael@0: #ifdef JCS_ALPHA_EXTENSIONS michael@0: michael@0: jcstest.c, located in the libjpeg-turbo source tree, demonstrates how to check michael@0: for the existence of the colorspace extensions at compile time and run time. michael@0: michael@0: =================================== michael@0: libjpeg v7 and v8 API/ABI Emulation michael@0: =================================== michael@0: michael@0: With libjpeg v7 and v8, new features were added that necessitated extending the michael@0: compression and decompression structures. Unfortunately, due to the exposed michael@0: nature of those structures, extending them also necessitated breaking backward michael@0: ABI compatibility with previous libjpeg releases. Thus, programs that were michael@0: built to use libjpeg v7 or v8 did not work with libjpeg-turbo, since it is michael@0: based on the libjpeg v6b code base. Although libjpeg v7 and v8 are still not michael@0: as widely used as v6b, enough programs (including a few Linux distros) made michael@0: the switch that there was a demand to emulate the libjpeg v7 and v8 ABIs michael@0: in libjpeg-turbo. It should be noted, however, that this feature was added michael@0: primarily so that applications that had already been compiled to use libjpeg michael@0: v7+ could take advantage of accelerated baseline JPEG encoding/decoding michael@0: without recompiling. libjpeg-turbo does not claim to support all of the michael@0: libjpeg v7+ features, nor to produce identical output to libjpeg v7+ in all michael@0: cases (see below.) michael@0: michael@0: By passing an argument of --with-jpeg7 or --with-jpeg8 to configure, or an michael@0: argument of -DWITH_JPEG7=1 or -DWITH_JPEG8=1 to cmake, you can build a version michael@0: of libjpeg-turbo that emulates the libjpeg v7 or v8 ABI, so that programs michael@0: that are built against libjpeg v7 or v8 can be run with libjpeg-turbo. The michael@0: following section describes which libjpeg v7+ features are supported and which michael@0: aren't. michael@0: michael@0: Support for libjpeg v7 and v8 Features: michael@0: --------------------------------------- michael@0: michael@0: Fully supported: michael@0: michael@0: -- libjpeg: IDCT scaling extensions in decompressor michael@0: libjpeg-turbo supports IDCT scaling with scaling factors of 1/8, 1/4, 3/8, michael@0: 1/2, 5/8, 3/4, 7/8, 9/8, 5/4, 11/8, 3/2, 13/8, 7/4, 15/8, and 2/1 (only 1/4 michael@0: and 1/2 are SIMD-accelerated.) michael@0: michael@0: -- libjpeg: arithmetic coding michael@0: michael@0: -- libjpeg: In-memory source and destination managers michael@0: See notes below. michael@0: michael@0: -- cjpeg: Separate quality settings for luminance and chrominance michael@0: Note that the libpjeg v7+ API was extended to accommodate this feature only michael@0: for convenience purposes. It has always been possible to implement this michael@0: feature with libjpeg v6b (see rdswitch.c for an example.) michael@0: michael@0: -- cjpeg: 32-bit BMP support michael@0: michael@0: -- cjpeg: -rgb option michael@0: michael@0: -- jpegtran: lossless cropping michael@0: michael@0: -- jpegtran: -perfect option michael@0: michael@0: -- jpegtran: forcing width/height when performing lossless crop michael@0: michael@0: -- rdjpgcom: -raw option michael@0: michael@0: -- rdjpgcom: locale awareness michael@0: michael@0: michael@0: Not supported: michael@0: michael@0: NOTE: As of this writing, extensive research has been conducted into the michael@0: usefulness of DCT scaling as a means of data reduction and SmartScale as a michael@0: means of quality improvement. The reader is invited to peruse the research at michael@0: http://www.libjpeg-turbo.org/About/SmartScale and draw his/her own conclusions, michael@0: but it is the general belief of our project that these features have not michael@0: demonstrated sufficient usefulness to justify inclusion in libjpeg-turbo. michael@0: michael@0: -- libjpeg: DCT scaling in compressor michael@0: cinfo.scale_num and cinfo.scale_denom are silently ignored. michael@0: There is no technical reason why DCT scaling could not be supported when michael@0: emulating the libjpeg v7+ API/ABI, but without the SmartScale extension (see michael@0: below), only scaling factors of 1/2, 8/15, 4/7, 8/13, 2/3, 8/11, 4/5, and michael@0: 8/9 would be available, which is of limited usefulness. michael@0: michael@0: -- libjpeg: SmartScale michael@0: cinfo.block_size is silently ignored. michael@0: SmartScale is an extension to the JPEG format that allows for DCT block michael@0: sizes other than 8x8. Providing support for this new format would be michael@0: feasible (particularly without full acceleration.) However, until/unless michael@0: the format becomes either an official industry standard or, at minimum, an michael@0: accepted solution in the community, we are hesitant to implement it, as michael@0: there is no sense of whether or how it might change in the future. It is michael@0: our belief that SmartScale has not demonstrated sufficient usefulness as a michael@0: lossless format nor as a means of quality enhancement, and thus, our primary michael@0: interest in providing this feature would be as a means of supporting michael@0: additional DCT scaling factors. michael@0: michael@0: -- libjpeg: Fancy downsampling in compressor michael@0: cinfo.do_fancy_downsampling is silently ignored. michael@0: This requires the DCT scaling feature, which is not supported. michael@0: michael@0: -- jpegtran: Scaling michael@0: This requires both the DCT scaling and SmartScale features, which are not michael@0: supported. michael@0: michael@0: -- Lossless RGB JPEG files michael@0: This requires the SmartScale feature, which is not supported. michael@0: michael@0: What About libjpeg v9? michael@0: ---------------------- michael@0: michael@0: libjpeg v9 introduced yet another field to the JPEG compression structure michael@0: (color_transform), thus making the ABI backward incompatible with that of michael@0: libjpeg v8. This new field was introduced solely for the purpose of supporting michael@0: lossless SmartScale encoding. Further, there was actually no reason to extend michael@0: the API in this manner, as the color transform could have just as easily been michael@0: activated by way of a new JPEG colorspace constant, thus preserving backward michael@0: ABI compatibility. michael@0: michael@0: Our research (see link above) has shown that lossless SmartScale does not michael@0: generally accomplish anything that can't already be accomplished better with michael@0: existing, standard lossless formats. Thus, at this time, it is our belief that michael@0: there is not sufficient technical justification for software to upgrade from michael@0: libjpeg v8 to libjpeg v9, and therefore, not sufficient technical justification michael@0: for us to emulate the libjpeg v9 ABI. michael@0: michael@0: ===================================== michael@0: In-Memory Source/Destination Managers michael@0: ===================================== michael@0: michael@0: By default, libjpeg-turbo 1.3 and later includes the jpeg_mem_src() and michael@0: jpeg_mem_dest() functions, even when not emulating the libjpeg v8 API/ABI. michael@0: Previously, it was necessary to build libjpeg-turbo from source with libjpeg v8 michael@0: API/ABI emulation in order to use the in-memory source/destination managers, michael@0: but several projects requested that those functions be included when emulating michael@0: the libjpeg v6b API/ABI as well. This allows the use of those functions by michael@0: programs that need them without breaking ABI compatibility for programs that michael@0: don't, and it allows those functions to be provided in the "official" michael@0: libjpeg-turbo binaries. michael@0: michael@0: Those who are concerned about maintaining strict conformance with the libjpeg michael@0: v6b or v7 API can pass an argument of --without-mem-srcdst to configure or michael@0: an argument of -DWITH_MEM_SRCDST=0 to CMake prior to building libjpeg-turbo. michael@0: This will restore the pre-1.3 behavior, in which jpeg_mem_src() and michael@0: jpeg_mem_dest() are only included when emulating the libjpeg v8 API/ABI. michael@0: michael@0: On Un*x systems, including the in-memory source/destination managers changes michael@0: the dynamic library version from 62.0.0 to 62.1.0 if using libjpeg v6b API/ABI michael@0: emulation and from 7.0.0 to 7.1.0 if using libjpeg v7 API/ABI emulation. michael@0: michael@0: Note that, on most Un*x systems, the dynamic linker will not look for a michael@0: function in a library until that function is actually used. Thus, if a program michael@0: is built against libjpeg-turbo 1.3+ and uses jpeg_mem_src() or jpeg_mem_dest(), michael@0: that program will not fail if run against an older version of libjpeg-turbo or michael@0: against libjpeg v7- until the program actually tries to call jpeg_mem_src() or michael@0: jpeg_mem_dest(). Such is not the case on Windows. If a program is built michael@0: against the libjpeg-turbo 1.3+ DLL and uses jpeg_mem_src() or jpeg_mem_dest(), michael@0: then it must use the libjpeg-turbo 1.3+ DLL at run time. michael@0: michael@0: Both cjpeg and djpeg have been extended to allow testing the in-memory michael@0: source/destination manager functions. See their respective man pages for more michael@0: details. michael@0: michael@0: michael@0: ******************************************************************************* michael@0: ** Mathematical Compatibility michael@0: ******************************************************************************* michael@0: michael@0: For the most part, libjpeg-turbo should produce identical output to libjpeg michael@0: v6b. The one exception to this is when using the floating point DCT/IDCT, in michael@0: which case the outputs of libjpeg v6b and libjpeg-turbo are not guaranteed to michael@0: be identical (the accuracy of the floating point DCT/IDCT is constant when michael@0: using libjpeg-turbo's SIMD extensions, but otherwise, it can depend heavily on michael@0: the compiler and compiler settings.) michael@0: michael@0: While libjpeg-turbo does emulate the libjpeg v8 API/ABI, under the hood, it is michael@0: still using the same algorithms as libjpeg v6b, so there are several specific michael@0: cases in which libjpeg-turbo cannot be expected to produce the same output as michael@0: libjpeg v8: michael@0: michael@0: -- When decompressing using scaling factors of 1/2 and 1/4, because libjpeg v8 michael@0: implements those scaling algorithms a bit differently than libjpeg v6b does, michael@0: and libjpeg-turbo's SIMD extensions are based on the libjpeg v6b behavior. michael@0: michael@0: -- When using chrominance subsampling, because libjpeg v8 implements this michael@0: with its DCT/IDCT scaling algorithms rather than with a separate michael@0: downsampling/upsampling algorithm. michael@0: michael@0: -- When using the floating point IDCT, for the reasons stated above and also michael@0: because the floating point IDCT algorithm was modified in libjpeg v8a to michael@0: improve accuracy. michael@0: michael@0: -- When decompressing using a scaling factor > 1 and merged (AKA "non-fancy" or michael@0: "non-smooth") chrominance upsampling, because libjpeg v8 does not support michael@0: merged upsampling with scaling factors > 1. michael@0: michael@0: michael@0: ******************************************************************************* michael@0: ** Performance Pitfalls michael@0: ******************************************************************************* michael@0: michael@0: =============== michael@0: Restart Markers michael@0: =============== michael@0: michael@0: The optimized Huffman decoder in libjpeg-turbo does not handle restart markers michael@0: in a way that makes the rest of the libjpeg infrastructure happy, so it is michael@0: necessary to use the slow Huffman decoder when decompressing a JPEG image that michael@0: has restart markers. This can cause the decompression performance to drop by michael@0: as much as 20%, but the performance will still be much greater than that of michael@0: libjpeg. Many consumer packages, such as PhotoShop, use restart markers when michael@0: generating JPEG images, so images generated by those programs will experience michael@0: this issue. michael@0: michael@0: =============================================== michael@0: Fast Integer Forward DCT at High Quality Levels michael@0: =============================================== michael@0: michael@0: The algorithm used by the SIMD-accelerated quantization function cannot produce michael@0: correct results whenever the fast integer forward DCT is used along with a JPEG michael@0: quality of 98-100. Thus, libjpeg-turbo must use the non-SIMD quantization michael@0: function in those cases. This causes performance to drop by as much as 40%. michael@0: It is therefore strongly advised that you use the slow integer forward DCT michael@0: whenever encoding images with a JPEG quality of 98 or higher.