Git Product home page Git Product logo

libjpeg-turbo's Introduction

Background

libjpeg-turbo is a JPEG image codec that uses SIMD instructions to accelerate baseline JPEG compression and decompression on x86, x86-64, Arm, PowerPC, and MIPS systems, as well as progressive JPEG compression on x86, x86-64, and Arm systems. On such systems, libjpeg-turbo is generally 2-6x as fast as libjpeg, all else being equal. On other types of systems, libjpeg-turbo can still outperform libjpeg by a significant amount, by virtue of its highly-optimized Huffman coding routines. In many cases, the performance of libjpeg-turbo rivals that of proprietary high-speed JPEG codecs.

libjpeg-turbo implements both the traditional libjpeg API as well as the less powerful but more straightforward TurboJPEG API. libjpeg-turbo also features colorspace extensions that allow it to compress from/decompress to 32-bit and big-endian pixel buffers (RGBX, XBGR, etc.), as well as a full-featured Java interface.

libjpeg-turbo was originally based on libjpeg/SIMD, an MMX-accelerated derivative of libjpeg v6b developed by Miyasaka Masaru. The TigerVNC and VirtualGL projects made numerous enhancements to the codec in 2009, and in early 2010, libjpeg-turbo spun off into an independent project, with the goal of making high-speed JPEG compression/decompression technology available to a broader range of users and developers. libjpeg-turbo is an ISO/IEC and ITU-T reference implementation of the JPEG standard.

More information about libjpeg-turbo can be found at https://libjpeg-turbo.org.

Funding

libjpeg-turbo is an independent open source project, but we rely on patronage and funded development in order to maintain that independence. The easiest way to ensure that libjpeg-turbo remains community-focused and free of any one organization's agenda is to sponsor our project through GitHub. All sponsorship money goes directly toward funding the labor necessary to maintain libjpeg-turbo, support the user community, and implement bug fixes and strategically important features.

Sponsor libjpeg-turbo

License

libjpeg-turbo is covered by three compatible BSD-style open source licenses. Refer to LICENSE.md for a roll-up of license terms.

Building libjpeg-turbo

Refer to BUILDING.md for complete instructions.

Using libjpeg-turbo

libjpeg-turbo includes two APIs that can be used to compress and decompress JPEG images:

  • TurboJPEG API
    This API provides an easy-to-use interface for compressing and decompressing JPEG images in memory. It also provides some functionality that would not be straightforward to achieve using the underlying libjpeg API, such as generating planar YUV images and performing multiple simultaneous lossless transforms on an image. The Java interface for libjpeg-turbo is written on top of the TurboJPEG API. The TurboJPEG API is recommended for first-time users of libjpeg-turbo. Refer to tjexample.c and TJExample.java for examples of its usage and to http://libjpeg-turbo.org/Documentation/Documentation for API documentation.

  • libjpeg API
    This is the de facto industry-standard API for compressing and decompressing JPEG images. It is more difficult to use than the TurboJPEG API but also more powerful. The libjpeg API implementation in libjpeg-turbo is both API/ABI-compatible and mathematically compatible with libjpeg v6b. It can also optionally be configured to be API/ABI-compatible with libjpeg v7 and v8 (see below.) Refer to cjpeg.c and djpeg.c for examples of its usage and to libjpeg.txt for API documentation.

There is no significant performance advantage to either API when both are used to perform similar operations.

Colorspace Extensions

libjpeg-turbo includes extensions that allow JPEG images to be compressed directly from (and decompressed directly to) buffers that use BGR, BGRX, RGBX, XBGR, and XRGB pixel ordering. This is implemented with ten new colorspace constants:

JCS_EXT_RGB   /* red/green/blue */
JCS_EXT_RGBX  /* red/green/blue/x */
JCS_EXT_BGR   /* blue/green/red */
JCS_EXT_BGRX  /* blue/green/red/x */
JCS_EXT_XBGR  /* x/blue/green/red */
JCS_EXT_XRGB  /* x/red/green/blue */
JCS_EXT_RGBA  /* red/green/blue/alpha */
JCS_EXT_BGRA  /* blue/green/red/alpha */
JCS_EXT_ABGR  /* alpha/blue/green/red */
JCS_EXT_ARGB  /* alpha/red/green/blue */

Setting cinfo.in_color_space (compression) or cinfo.out_color_space (decompression) to one of these values will cause libjpeg-turbo to read the red, green, and blue values from (or write them to) the appropriate position in the pixel when compressing from/decompressing to an RGB buffer.

Your application can check for the existence of these extensions at compile time with:

#ifdef JCS_EXTENSIONS

At run time, attempting to use these extensions with a libjpeg implementation that does not support them will result in a "Bogus input colorspace" error. Applications can trap this error in order to test whether run-time support is available for the colorspace extensions.

When using the RGBX, BGRX, XBGR, and XRGB colorspaces during decompression, the X byte is undefined, and in order to ensure the best performance, libjpeg-turbo can set that byte to whatever value it wishes. If an application expects the X byte to be used as an alpha channel, then it should specify JCS_EXT_RGBA, JCS_EXT_BGRA, JCS_EXT_ABGR, or JCS_EXT_ARGB. When these colorspace constants are used, the X byte is guaranteed to be 0xFF, which is interpreted as opaque.

Your application can check for the existence of the alpha channel colorspace extensions at compile time with:

#ifdef JCS_ALPHA_EXTENSIONS

jcstest.c, located in the libjpeg-turbo source tree, demonstrates how to check for the existence of the colorspace extensions at compile time and run time.

libjpeg v7 and v8 API/ABI Emulation

With libjpeg v7 and v8, new features were added that necessitated extending the compression and decompression structures. Unfortunately, due to the exposed nature of those structures, extending them also necessitated breaking backward ABI compatibility with previous libjpeg releases. Thus, programs that were built to use libjpeg v7 or v8 did not work with libjpeg-turbo, since it is based on the libjpeg v6b code base. Although libjpeg v7 and v8 are not as widely used as v6b, enough programs (including a few Linux distros) made the switch that there was a demand to emulate the libjpeg v7 and v8 ABIs in libjpeg-turbo. It should be noted, however, that this feature was added primarily so that applications that had already been compiled to use libjpeg v7+ could take advantage of accelerated baseline JPEG encoding/decoding without recompiling. libjpeg-turbo does not claim to support all of the libjpeg v7+ features, nor to produce identical output to libjpeg v7+ in all cases (see below.)

By passing an argument of -DWITH_JPEG7=1 or -DWITH_JPEG8=1 to cmake, you can build a version of libjpeg-turbo that emulates the libjpeg v7 or v8 ABI, so that programs that are built against libjpeg v7 or v8 can be run with libjpeg-turbo. The following section describes which libjpeg v7+ features are supported and which aren't.

Support for libjpeg v7 and v8 Features

Fully supported

  • libjpeg API: IDCT scaling extensions in decompressor
    libjpeg-turbo supports IDCT scaling with scaling factors of 1/8, 1/4, 3/8, 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 and 1/2 are SIMD-accelerated.)

  • libjpeg API: Arithmetic coding

  • libjpeg API: In-memory source and destination managers
    See notes below.

  • cjpeg: Separate quality settings for luminance and chrominance
    Note that the libpjeg v7+ API was extended to accommodate this feature only for convenience purposes. It has always been possible to implement this feature with libjpeg v6b (see rdswitch.c for an example.)

  • cjpeg: 32-bit BMP support

  • cjpeg: -rgb option

  • jpegtran: Lossless cropping

  • jpegtran: -perfect option

  • jpegtran: Forcing width/height when performing lossless crop

  • rdjpgcom: -raw option

  • rdjpgcom: Locale awareness

Not supported

NOTE: As of this writing, extensive research has been conducted into the usefulness of DCT scaling as a means of data reduction and SmartScale as a means of quality improvement. Readers are invited to peruse the research at http://www.libjpeg-turbo.org/About/SmartScale and draw their own conclusions, but it is the general belief of our project that these features have not demonstrated sufficient usefulness to justify inclusion in libjpeg-turbo.

  • libjpeg API: DCT scaling in compressor
    cinfo.scale_num and cinfo.scale_denom are silently ignored. There is no technical reason why DCT scaling could not be supported when emulating the libjpeg v7+ API/ABI, but without the SmartScale extension (see below), only scaling factors of 1/2, 8/15, 4/7, 8/13, 2/3, 8/11, 4/5, and 8/9 would be available, which is of limited usefulness.

  • libjpeg API: SmartScale
    cinfo.block_size is silently ignored. SmartScale is an extension to the JPEG format that allows for DCT block sizes other than 8x8. Providing support for this new format would be feasible (particularly without full acceleration.) However, until/unless the format becomes either an official industry standard or, at minimum, an accepted solution in the community, we are hesitant to implement it, as there is no sense of whether or how it might change in the future. It is our belief that SmartScale has not demonstrated sufficient usefulness as a lossless format nor as a means of quality enhancement, and thus our primary interest in providing this feature would be as a means of supporting additional DCT scaling factors.

  • libjpeg API: Fancy downsampling in compressor
    cinfo.do_fancy_downsampling is silently ignored. This requires the DCT scaling feature, which is not supported.

  • jpegtran: Scaling
    This requires both the DCT scaling and SmartScale features, which are not supported.

  • Lossless RGB JPEG files
    This requires the SmartScale feature, which is not supported.

What About libjpeg v9?

libjpeg v9 introduced yet another field to the JPEG compression structure (color_transform), thus making the ABI backward incompatible with that of libjpeg v8. This new field was introduced solely for the purpose of supporting lossless SmartScale encoding. Furthermore, there was actually no reason to extend the API in this manner, as the color transform could have just as easily been activated by way of a new JPEG colorspace constant, thus preserving backward ABI compatibility.

Our research (see link above) has shown that lossless SmartScale does not generally accomplish anything that can't already be accomplished better with existing, standard lossless formats. Therefore, at this time it is our belief that there is not sufficient technical justification for software projects to upgrade from libjpeg v8 to libjpeg v9, and thus there is not sufficient technical justification for us to emulate the libjpeg v9 ABI.

In-Memory Source/Destination Managers

By default, libjpeg-turbo 1.3 and later includes the jpeg_mem_src() and jpeg_mem_dest() functions, even when not emulating the libjpeg v8 API/ABI. Previously, it was necessary to build libjpeg-turbo from source with libjpeg v8 API/ABI emulation in order to use the in-memory source/destination managers, but several projects requested that those functions be included when emulating the libjpeg v6b API/ABI as well. This allows the use of those functions by programs that need them, without breaking ABI compatibility for programs that don't, and it allows those functions to be provided in the "official" libjpeg-turbo binaries.

Note that, on most Un*x systems, the dynamic linker will not look for a function in a library until that function is actually used. Thus, if a program is built against libjpeg-turbo 1.3+ and uses jpeg_mem_src() or jpeg_mem_dest(), that program will not fail if run against an older version of libjpeg-turbo or against libjpeg v7- until the program actually tries to call jpeg_mem_src() or jpeg_mem_dest(). Such is not the case on Windows. If a program is built against the libjpeg-turbo 1.3+ DLL and uses jpeg_mem_src() or jpeg_mem_dest(), then it must use the libjpeg-turbo 1.3+ DLL at run time.

Both cjpeg and djpeg have been extended to allow testing the in-memory source/destination manager functions. See their respective man pages for more details.

Mathematical Compatibility

For the most part, libjpeg-turbo should produce identical output to libjpeg v6b. There are two exceptions:

  1. When decompressing a JPEG image that uses 4:4:0 chrominance subsampling, the outputs of libjpeg v6b and libjpeg-turbo can differ because libjpeg-turbo implements a "fancy" (smooth) 4:4:0 upsampling algorithm and libjpeg did not.

  2. When using the floating point DCT/IDCT, the outputs of libjpeg v6b and libjpeg-turbo can differ for the following reasons:

    • The SSE/SSE2 floating point DCT implementation in libjpeg-turbo is ever so slightly more accurate than the implementation in libjpeg v6b, but not by any amount perceptible to human vision (generally in the range of 0.01 to 0.08 dB gain in PNSR.)

    • When not using the SIMD extensions, libjpeg-turbo uses the more accurate (and slightly faster) floating point IDCT algorithm introduced in libjpeg v8a as opposed to the algorithm used in libjpeg v6b. It should be noted, however, that this algorithm basically brings the accuracy of the floating point IDCT in line with the accuracy of the accurate integer IDCT. The floating point DCT/IDCT algorithms are mainly a legacy feature, and they do not produce significantly more accuracy than the accurate integer algorithms. (To put numbers on this, the typical difference in PNSR between the two algorithms is less than 0.10 dB, whereas changing the quality level by 1 in the upper range of the quality scale is typically more like a 1.0 dB difference.)

    • If the floating point algorithms in libjpeg-turbo are not implemented using SIMD instructions on a particular platform, then the accuracy of the floating point DCT/IDCT can depend on the compiler settings.

While libjpeg-turbo does emulate the libjpeg v8 API/ABI, under the hood it is still using the same algorithms as libjpeg v6b, so there are several specific cases in which libjpeg-turbo cannot be expected to produce the same output as libjpeg v8:

  • When decompressing using scaling factors of 1/2 and 1/4, because libjpeg v8 implements those scaling algorithms differently than libjpeg v6b does, and libjpeg-turbo's SIMD extensions are based on the libjpeg v6b behavior.

  • When using chrominance subsampling, because libjpeg v8 implements this with its DCT/IDCT scaling algorithms rather than with a separate downsampling/upsampling algorithm. In our testing, the subsampled/upsampled output of libjpeg v8 is less accurate than that of libjpeg v6b for this reason.

  • When decompressing using a scaling factor > 1 and merged (AKA "non-fancy" or "non-smooth") chrominance upsampling, because libjpeg v8 does not support merged upsampling with scaling factors > 1.

Performance Pitfalls

Restart Markers

The optimized Huffman decoder in libjpeg-turbo does not handle restart markers in a way that makes the rest of the libjpeg infrastructure 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 greater than that of libjpeg. 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 accurate integer forward DCT whenever encoding images with a JPEG quality of 98 or higher.

Memory Debugger Pitfalls

Valgrind and Memory Sanitizer (MSan) can generate false positives (specifically, incorrect reports of uninitialized memory accesses) when used with libjpeg-turbo's SIMD extensions. It is generally recommended that the SIMD extensions be disabled, either by passing an argument of -DWITH_SIMD=0 to cmake when configuring the build or by setting the environment variable JSIMD_FORCENONE to 1 at run time, when testing libjpeg-turbo with Valgrind, MSan, or other memory debuggers.

libjpeg-turbo's People

Contributors

arichardson avatar cendioossman avatar dcommander avatar dwatteau avatar fbossen avatar fhanau avatar flygoat avatar jcowgill avatar jwright-arm avatar kleisauke avatar kornelski avatar ksmurchison avatar luzpaz avatar martynjacques-arm avatar masal64 avatar mattsarett avatar mayeut avatar modbw avatar neheb avatar nyg avatar oerdnj avatar orivej avatar pkasting avatar pkubaj avatar programmax avatar richard-townsend-arm avatar robertocr avatar rouault avatar stephengroat avatar y-guyon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libjpeg-turbo's Issues

jpeglib.h uses FILE but does not include stdio.h

libjepg-turbo installs the header file jpeglib.h which uses "FILE"

 jpeglib.h:EXTERN(void) jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile);
 jpeglib.h:EXTERN(void) jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile);

but does NOT include <stdio.h> which leads to compilation errors when included in compiling other software eg

 In file included from /usr/include/libmng_types.h:210:0,
                  from /usr/include/libmng.h:386,
                  from /var/tmp/root/mplayer-configure--4021/tmp.c:1:
 /usr/local/X11R6/include/jpeglib.h:914:53: error: unknown type name 'FILE'
  EXTERN(void) jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile);
                                                      ^
 /usr/local/X11R6/include/jpeglib.h:915:54: error: unknown type name 'FILE'
EXTERN(void) jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile);
                                                  ^

Including the stdio header file resolves the problem.

 --- jpeglib.h.orig 2015-09-11 17:40:00.539706398 +0100
 +++ jpeglib.h  2015-09-11 17:40:00.539706398 +0100
 @@ -28,6 +28,8 @@
  #endif
  #include "jmorecfg.h"           /* seldom changed options */

 +#include <stdio.h>
 +

 #ifdef __cplusplus
  #ifndef DONT_USE_EXTERN_C

"Progressive mode" is always "optimized" (Huffman)

Long in short, when using cjpeg or jpegtran, I found that when -progressive switch is enabled, -optimize (Huffman) will always be applied too even when we don't use that parameter, i.e. using -progressive and -progressive -optimize will give out identical results (bit-accurate).

After a quick search, I believe it's doing so because of

if (cinfo->progressive_mode && !cinfo->arith_code) /* TEMPORARY HACK ??? */

Now I was just curious (not questioning), what's the reason to do so?

I found this relavant dicussion in the maillist but it didn't explain too much.

Cheers.

Improve Huffman encode performance with LLVM

Apparently, LLVM doesn't do as good of a job as GCC at optimizing the Huffman encoder in libjpeg-turbo. At least the Apple version of LLVM falls somewhat short of GCC 4.x and 5.x, causing an overall performance drop of about 15-20% when compressing JPEG images with a version of libjpeg-turbo that was built with LLVM. I haven't tested LLVM on Linux to see whether this is also true. It may be possible to coax the compiler into producing better performance by restructuring the code, or it may be necessary to use hand-tuned assembly on the inner Huffman loops. It would certainly be cleaner to avoid assembly. Also, since ARM is using LLVM, if we can figure out how to make the code perform better under that compiler, it would probably improve performance under iOS.

v1.4.1 does not install needed header file jinclude.h

As per the resolution of issue #17

"libjpeg requires that you include jinclude.h before including jpeglib.h."

libjpeg-turbo v1.4.1 source has the file jinclude.h but does not install it from the make install command.

 export DESTDIR=/var/tmp/libjpeg-turbo

(just to put the test run installation into an obvious scratch directory)

 make V=1 install

 /bin/mkdir -p '/var/tmp/libjpeg-turbo/usr/local/X11R6/include'
  /usr/bin/install -c -m 644 jerror.h jmorecfg.h jpeglib.h turbojpeg.h '/var/tmp/libjpeg-turbo/usr  /local/X11R6/include'
  /bin/mkdir -p '/var/tmp/libjpeg-turbo/usr/local/X11R6/share/man/man1'
  /usr/bin/install -c -m 644 cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 wrjpgcom.1 '/var/tmp/libjpeg-turbo/usr/local/X11R6/share/man/man1'
  /bin/mkdir -p '/var/tmp/libjpeg-turbo/usr/local/X11R6/include'
 /usr/bin/install -c -m 644 jconfig.h '/var/tmp/libjpeg-turbo/usr/local/X11R6/include'
 make[2]: Leaving directory '/usr/src/build/libjpeg-turbo-1.4.1'

 ls -aFls /var/tmp/libjpeg-turbo/usr/local/X11R6/include/
 total 160
  4 drwxr-xr-x 2 root root  4096 2015-09-11 22:21 ./
  4 drwxr-xr-x 6 root root  4096 2015-09-11 22:21 ../
  4 -rw-r--r-- 1 root root  2211 2015-09-11 22:21 jconfig.h
 16 -rw-r--r-- 1 root root 15081 2015-09-11 22:21 jerror.h
 16 -rw-r--r-- 1 root root 13507 2015-09-11 22:21 jmorecfg.h
 52 -rw-r--r-- 1 root root 49594 2015-09-11 22:21 jpeglib.h
 64 -rw-r--r-- 1 root root 64668 2015-09-11 22:21 turbojpeg.h

So as you can see above, no jinclude.h file is installed.

Therefore jinclude.h needs to be added to the list of header files to install in the target include directory, appending it in Makefile.am to whichever is more appropriate of

 include_HEADERS = jerror.h jmorecfg.h jpeglib.h

or

 nodist_include_HEADERS = jconfig.h

libjpeg-turbo cross-compile to Android fails

I have encountered two issues that I think can't be sidestepped using any of the current CMake options.

The first is that -DUSE_SETMODE is hard-coded, for some executables that are always built. Many platforms do not have setmode(), and I've even found that some platforms have a setmode() with an incompatible prototype.

The second issue is that the installation stage assumes executable filenames have a .exe extension.

Attached is a patch which resolves these problems. I have not tested on other platforms. But, the nature of the patch is such that you'll know if it worked simply by whether the build succeeds.

libjpeg-turbo-1.4.2.patch.zip

CMake cache variable NASM has wrong type

PATCH-libjpeg-turbo-1.4.2-cmake.txt
The NASM cache variable (created by simd/CMakeLists.txt) should have type FILEPATH since it refers to the nasm executable, not just the directory containing the executable.
In cmake-gui the wrong type causes problems because the UI does not make it easy to select a file when it believes a path is called for.

Build failing using Xcode7 (I would like to build using bitcode enabled)

I used the following script to build the library for iOS :

#!/bin/bash

autoreconf -fiv


mkdir libs
mkdir libs/ios
mkdir libs/ios/device
mkdir libs/ios/simulator

cd src

COMPILER_TOOL="xcodebuild"
IOS_SIMULATOR_VERSION_OF_THE_CURRENT_ENVIRONMENT=`"$COMPILER_TOOL" -showsdks | grep -E "^\s+iOS\s+\d+" | awk '{print $2}'`
echo "IOS_SIMULATOR_VERSION_OF_THE_CURRENT_ENVIRONMENT determined by create_iOS_SimulatorBuild : $IOS_SIMULATOR_VERSION_OF_THE_CURRENT_ENVIRONMENT"

IOS_PLATFORMDIR=/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform
IOS_SYSROOT=$IOS_PLATFORMDIR/Developer/SDKs/iPhoneOS$IOS_SIMULATOR_VERSION_OF_THE_CURRENT_ENVIRONMENT.sdk
IOS_SIMULATOR_PLATFORMDIR=/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneSimulator.platform
IOS_SIMULATOR_SYSROOT=$IOS_SIMULATOR_PLATFORMDIR/Developer/SDKs/iPhoneSimulator$IOS_SIMULATOR_VERSION_OF_THE_CURRENT_ENVIRONMENT.sdk
IOS_GCC=/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang

 echo $IOS_SIMULATOR_SYSROOT;

# armv7
echo "--- Building for armv7 ---"
make clean
IOS_CFLAGS="-arch armv7 -miphoneos-version-min=8.0"
./configure --host arm-apple-darwin10 \
    CC="$IOS_GCC" LD="$IOS_GCC" \
    CFLAGS="-mfloat-abi=softfp -isysroot $IOS_SYSROOT -O3 $IOS_CFLAGS" \
    LDFLAGS="-mfloat-abi=softfp -isysroot $IOS_SYSROOT $IOS_CFLAGS" \
    CCASFLAGS="-no-integrated-as $IOS_CFLAGS"
make
mv -v .libs/libturbojpeg.a ../libs/libturbojpeg_armv7_a

# armv7s
echo "--- Building for armv7s ---"
make clean
IOS_CFLAGS="-arch armv7s -miphoneos-version-min=8.0"
./configure --host arm-apple-darwin10 \
    CC="$IOS_GCC" LD="$IOS_GCC" \
    CFLAGS="-mfloat-abi=softfp -isysroot $IOS_SYSROOT -O3 $IOS_CFLAGS" \
    LDFLAGS="-mfloat-abi=softfp -isysroot $IOS_SYSROOT $IOS_CFLAGS" \
    CCASFLAGS="-no-integrated-as $IOS_CFLAGS"
make
mv -v .libs/libturbojpeg.a ../libs/libturbojpeg_armv7s_a

# arm64
echo "--- Building for arm64 ---"
make clean
IOS_CFLAGS="-arch arm64 -miphoneos-version-min=8.0"
./configure --host aarch64-apple-darwin \
    CC="$IOS_GCC" LD="$IOS_GCC" \
    CFLAGS="-isysroot $IOS_SYSROOT -O3 $IOS_CFLAGS" \
    LDFLAGS="-isysroot $IOS_SYSROOT $IOS_CFLAGS"
make
mv -v .libs/libturbojpeg.a ../libs/libturbojpeg_arm64_a


# i386 (32-bit Build on 64-bit OS X ==> i686)
echo "--- Building for i386 (32-bit Build on 64-bit OS X ==> i686) ---"
make clean
./configure --host i686-apple-darwin CFLAGS='-O3 -m32' LDFLAGS=-m32
make
 mv -v .libs/libturbojpeg.a ../libs/libturbojpeg_x86_a


 # x86_64
 echo "--- Building for x86_64 ---"
 make clean
 ./configure --host x86_64-apple-darwin NASM=/opt/local/bin/nasm
 make
  mv -v .libs/libturbojpeg.a ../libs/libturbojpeg_x86_64_a

# # lipo
cd ..
xcrun -sdk iphoneos lipo -arch armv7 libs/libturbojpeg_armv7_a -arch armv7s libs/libturbojpeg_armv7s_a -arch arm64 libs/libturbojpeg_arm64_a -create -output libs/ios/device/libturbojpeg.a
xcrun -sdk iphoneos lipo -arch i386 libs/libturbojpeg_x86_a -arch x86_64 libs/libturbojpeg_x86_64_a -create -output libs/ios/simulator/libturbojpeg.a

rm -f libs/*_a

Unfortunately this does not work any more. 😞

The errors I can see are similar :
"file was built for armv7 which is not the architecture being linked (x86_64)"

Do you have any idea abot how could I fix this?

Thanks!

565 dithering behavior depends on client memory alignment

This isn't a fix/feature request. I want to document a strange behavior that I was unaware of (and maybe others will be interested to know as well).

Looking at ycc_rgb565D_convert_internal() in jdcol565.c (or any of the 565 conversion functions with dithering), you'll notice that it dithers two pixels at a time in the main loop, with an if statement before the loop to handle a single, non 32-bit aligned pixel before the loop, if necessary.

What is interesting is that, depending on whether the input memory is aligned to 32-bits, the result of the dithering will be different (because DITHER_ROTATE() will be called at different intervals). This is not really a bug, given that, regardless of the input memory alignment, the output image looks fine (and differences are indistinguishable to my eye).

But it is strange to me that the outputs are not identical, especially because of the lengths libjpeg-turbo goes to in order to ensure pixel compliance with 6b in its more traditional modes.

Just to be clear, I'm not advocating any action here. This is an FYI. We're not currently planning to use dithering with 565, I'm not aware if there are other users of turbo that may be using this functionality (or care that the output is not always identical).

How can we compile it with GPU support

I saw there is nvcc in configure file, does that mean we can use CUDA to compile it, then it will support GPU ?

I try, but failed, is there any guide ?

cannot find file io.h only with cmake

I am getting error cannot find include io.h when only using cmake build in any liunx system.

If this is a windows only stuff shouldn't it be wrapped around and ifdef WIN32 ?

sorry for not attaching the exact error message now. It was only my other system.
steps to reproduce are:
download libjpeg-turbo-1.4.1.tar.gz from sourceforge
mkdir build && cd build
cmake /path/to/libjpeg-turbo

Add further partial decoding optimization

As I've advocated previously, the ability to decode image subsets efficiently is a useful feature. The idea is that if we only need to display a subset of an image, we will improve performance by decoding only that subset (rather than decoding the entire image and then cropping).

In http://sourceforge.net/p/libjpeg-turbo/patches/70/, we added the ability the skip rows when decoding. This significantly improved partial decoding performance, especially when we only care about the bottom portion of an image.

However, we are still non-optimal when dealing with very wide or panorama images. It seems quite wasteful to decode entire rows at a time when we are only interested in a small portion of the width.

I'd like to propose an API to optimize partial decodes by adding the ability to read partial scanlines. I envision that this could be done in a way that makes minimal changes to the code path for regular decodes. We would just need to need to keep track of alternate width counters etc.

The API might look something like this:

/*

  • Call this before starting to read scanlines, and each subsequent call to jpeg_read_scanlines() will only
  • read the indicated portion of the row, rather than the entire row.
    *
  • This cannot be called or undone once the decode is in progress.
    */
    GLOBAL(void) jpeg_partial_decode(j_decompress_ptr cinfo, JDIMENSION start_x, JDIMENSION width);

The major complication I see with this is that many of the SIMD color conversion routines expect their memory to be 16-byte aligned (and AVX2 will expect 32-byte alignment). So start_x must be a multiple of 16 (or 32) for this to work without significantly altering the SIMD routines.

I think we can get around this by requiring that start_x be a multiple of the necessary alignment - maybe return a bool? Or we can make start_x and width JDIMENSION*, so libjpeg-turbo can adjust them to values that are supported?

Would this be an optimization that you would be interested in? If so, do you have thoughts on the API?

I would write the initial version of the patch, and we would be able to compensate for time spent integrating and testing.

Accelerate DCT and IDCT algorithms using AVX2 instructions

Newer Intel/AMD chips provide support for AVX2 (256-bit integer SIMD) instructions, so developing new versions of the libjpeg-turbo SIMD algorithms that take advantage of this technology should improve the performance of libjpeg-turbo (although by how much is unknown.) Because AVX2 doesn't increase the number of available registers, the best approach is probably to continue using hand-tuned NASM code in order to avoid unexpected register exhaustion. 256-bit SIMD would allow the row multiply operations in the DCT/IDCT algorithms to be executed in a single instruction instead of 3 or 4, and it will allow twice the data parallelism in the color conversion and up/downsampling routines. What effect this will have on overall performance is unknown. Huffman coding takes up something like 40-50%, so only 50-60% is available for optimization. My gut says that we can probably achieve an overall performance boost of about 30% relative to the current SSE2 implementation, which would mean that libjpeg-turbo would be 2.5-7x as fast as libjpeg rather than 2-5x as fast.

support CFLAGS with nasm configure script for crosscompiling

trying to crosscompile for the specific platform gives the issue
error: cannot find -lc
cannot find -ldl
collect2: error: ld returned 1 exit status
with linking flags
however the sysroot exported via CFLAGS and changing the
try_nasm='${CC-cc} -o conftest${ac_exeext} $LDFLAGS conftest.o $LIBS 1>&5'
to
try_nasm='${CC-cc} ${CFLAGS} -o conftest${ac_exeext} $LDFLAGS conftest.o $LIBS 1>&5'
in resulting configure script make the thing works

Modify autotools build system to use a flat Makefile

This will improve build performance on Un*x systems and allow parallel make to be more effective with our build. Furthermore, since a flat Makefile would require the subdir-objects extension, it will allow us to re-organize the SIMD code into separate subdirectories for each architecture. The downside is that using this extension will necessitate the use of a later version of autotools in order to process the source, so it won't be possible to autoreconf the source on some of the systems we support (such as RHEL 5) without installing autotools from source. However, it should still be possible to build the processed source on those older systems, and we can provide a convenience script for downloading and installing a recent autotools.

NASM/YASM dependency for libjpeg-turbo

DRC, can you a little provide a little background libjpeg-turbo's NASM/YASM dependency?

I know the basics - this tool is required to compile the x86 and x86-64 assembly code in libjpeg-turbo. I'm guessing because the assembly code uses a NASM specific syntax?

Within Android, there is pretty strong opposition to adding yet another assembler/compiler tool. So much so, that we'd rather rewrite the assembly to be compliant with gcc/clang.

Do you know if there is any reason why the code couldn't be rewritten to be compiled by standard tools? If we could provide some manpower from Intel to rewrite the code, would you be interested in accepting these contributions?

Preserve frame pointers

Please provide the binary distribution compiled with preserving frame pointers (gcc -fno-omit-frame-pointer). Due to the larger number of registers on newer architectures, this should pose minimal overhead, however it would aid in providing coherent stack traces in profiling tools (such as linux perf). These are very useful in production systems as well.

Scaling during decompression - fractional edge pixels

Is there a way to know what fraction of a pixel the right/bottom edge pixels represent?

Say you take a 65x65 pixel image and scale it 1/4, you would get a 17x17 pixel result (possibly 18x18 uncropped, if the original was 72x72 in terms of whole blocks). The 17th pixels would only represent 1/4th of a pixel, however. (I'm assuming here that edge pixels are duplicated to fill the remaining part of a given block prior to averaging).

This could be calculated after the fact with sufficient knowledge of libjpeg-turbo internals, but perhaps it is already exposed somewhere?

This value is useful if one is later performing true image resampling, where the pixel weight can be plugged into the contribution calculations and subsequently be compensated for - perfectly.

Windows 10/ARM support

There is some demand for this, in the context of supporting libjpeg-turbo on Windows phones. It will require significant effort in order to set up the Windows build system to automatically convert the GNU assembler (GAS) syntax of the current ARM assembly code into ARMASM syntax (fortunately, our old friend gas-preprocessor.pl can do this, although my history with that program suggests that some modifications will likely be required.) Windows Phone or tablet hardware will be required in order to test and validate the build.

tjDecompressToYUV2 can jump to an uninitialized stack frame

tjDecompressToYUV2 doesn't call setjmp on setjmp_buffer. Its therefore possible for the error handling to return to an uninitialized stack frame (i.e. to wherever it was last set, which will probably have been destroyed). Looks like the following is missing after the arguments are validated:

if(setjmp(this->jerr.setjmp_buffer))
{
        /* If we get here, the JPEG code has signaled an error. */
        return -1;
}

Please find a patch below:
tjDecompressToYUV2.txt

Uninitialized values in the parsing and processing of jpeg files

Hello,

I have found some uninitialized values in the parsing and processing of jpeg files using libjpeg-turbo (tested in Ubuntu 14.04 using libjpeg-turbo 8.0.2). According to valgrind, these values are coming from a heap allocation, so they can potentially allow to leak some private information from previously free buffers. (this is a particularly bad problem in big applications like browsers). A small test case is available here:

https://gist.github.com/gaa-cifasis/c759307cbc0936562b72/raw/dca16e5867adb02c4f6629aee5fbccb1eeb6c33a/uninitialized.jpeg.gz

and the complete valgrind report is here:

$ valgrind --track-origins=yes djpeg uninitialized.jpeg > /dev/null

Corrupt JPEG data: premature end of data segment
==5414== Syscall param write(buf) points to uninitialised byte(s)
==5414== at 0x5177870: __write_nocancel (syscall-template.S:81)
==5414== by 0x5105002: _IO_file_write@@GLIBC_2.2.5 (fileops.c:1261)
==5414== by 0x51064DB: _IO_do_write@@GLIBC_2.2.5 (fileops.c:538)
==5414== by 0x510488F: _IO_file_sync@@GLIBC_2.2.5 (fileops.c:892)
==5414== by 0x50F9F51: fflush (iofflush.c:41)
==5414== by 0x404214: ??? (in /usr/bin/djpeg)
==5414== by 0x4013B9: ??? (in /usr/bin/djpeg)
==5414== by 0x50ADEC4: (below main) (libc-start.c:287)
==5414== Address 0x4026034 is not stack'd, malloc'd or (recently) free'd
==5414== Uninitialised value was created by a heap allocation
==5414== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5414== by 0x4E639F3: alloc_large (in /usr/lib/x86_64-linux-gnu/libjpeg.so.8.0.2)
==5414== by 0x4E63C56: alloc_sarray (in /usr/lib/x86_64-linux-gnu/libjpeg.so.8.0.2)
==5414== by 0x4E534A7: jinit_d_main_controller (in /usr/lib/x86_64-linux-gnu/libjpeg.so.8.0.2)
==5414== by 0x4E56AF5: jinit_master_decompress (in /usr/lib/x86_64-linux-gnu/libjpeg.so.8.0.2)
==5414== by 0x4E4D4E4: jpeg_start_decompress (in /usr/lib/x86_64-linux-gnu/libjpeg.so.8.0.2)
==5414== by 0x401356: ??? (in /usr/bin/djpeg)
==5414== by 0x50ADEC4: (below main) (libc-start.c:287)

This test case was found using QuickFuzz

Regards,
Gustavo

windows x64 static library for libjpeg-turbo with Visual Studio 2015

The prebuilt binaries get linkage errors with Visual Studio 2015

Error   LNK2019 unresolved external symbol _snprintf_s referenced in function   setDecompDefaults   XIO E:\xio6\XIO\Intermediate\ProjectFiles\turbojpeg-static.lib(turbojpeg.c.obj) 


Error   LNK2019 unresolved external symbol __iob_func referenced in function output_message XIO E:\xio6\XIO\Intermediate\ProjectFiles\turbojpeg-static.lib(jerror.c.obj)    1   

The Cmake generated VS solution also produces link errors although it seems to be due to misconfiguration in that case) , e.g:

Error   LNK1181 cannot open input file 'E:\GitHub\libjpeg-turbo\simd\Release\jfdctflt-sse-64.obj'   jpeg-static E:\GitHub\libjpeg-turbo\LINK

Here was my cmake command line:

cmake -G"Visual Studio 14 2015 Win64" .

fatal error: jconfig.h: No such file or directory

Hiya folks,

Trying to run nw-gyp rebuild --target="0.12.3"

And I get the following:
gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ] make: Entering directory '/home/pi/PopcornTV/node_modules/node-images/build' CC(target) Release/obj.target/libpng/gyp/third-party/libpng/png.o CC(target) Release/obj.target/libpng/gyp/third-party/libpng/pngerror.o CC(target) Release/obj.target/libpng/gyp/third-party/libpng/pngget.o CC(target) Release/obj.target/libpng/gyp/third-party/libpng/pngmem.o CC(target) Release/obj.target/libpng/gyp/third-party/libpng/pngpread.o CC(target) Release/obj.target/libpng/gyp/third-party/libpng/pngread.o CC(target) Release/obj.target/libpng/gyp/third-party/libpng/pngrio.o CC(target) Release/obj.target/libpng/gyp/third-party/libpng/pngrtran.o CC(target) Release/obj.target/libpng/gyp/third-party/libpng/pngrutil.o CC(target) Release/obj.target/libpng/gyp/third-party/libpng/pngset.o CC(target) Release/obj.target/libpng/gyp/third-party/libpng/pngtrans.o CC(target) Release/obj.target/libpng/gyp/third-party/libpng/pngwio.o CC(target) Release/obj.target/libpng/gyp/third-party/libpng/pngwrite.o CC(target) Release/obj.target/libpng/gyp/third-party/libpng/pngwtran.o CC(target) Release/obj.target/libpng/gyp/third-party/libpng/pngwutil.o AR(target) Release/obj.target/gyp/gyp/png.a COPY Release/png.a CC(target) Release/obj.target/libjpeg-turbo/gyp/third-party/libjpeg-turbo/bmp.o In file included from ../gyp/third-party/libjpeg-turbo/cdjpeg.h:16:0, from ../gyp/third-party/libjpeg-turbo/bmp.c:33: ../gyp/third-party/libjpeg-turbo/jinclude.h:22:65: fatal error: jconfig.h: No such file or directory compilation terminated. gyp/gyp/libjpeg-turbo.target.mk:161: recipe for target 'Release/obj.target/libjpeg-turbo/gyp/third-party/libjpeg-turbo/bmp.o' failed make: *** [Release/obj.target/libjpeg-turbo/gyp/third-party/libjpeg-turbo/bmp.o] Error 1 make: Leaving directory '/home/pi/PopcornTV/node_modules/node-images/build' gyp ERR! build error gyp ERR! stack Error:makefailed with exit code: 2 gyp ERR! stack at ChildProcess.onExit (/usr/local/lib/node_modules/nw-gyp/lib/build.js:267:23) gyp ERR! stack at ChildProcess.emit (events.js:110:17) gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:1074:12) gyp ERR! System Linux 4.1.6+ gyp ERR! command "node" "/usr/local/bin/nw-gyp" "rebuild" "--target=0.12.3" gyp ERR! cwd /home/pi/PopcornTV/node_modules/node-images gyp ERR! node -v v0.12.6 gyp ERR! nw-gyp -v v0.12.4 gyp ERR! not ok

Not sure if the error is with the actual build or with nw-gyp. It says "file not found". If I look at the directory I can see there is no file there. I can manually add one (by changing the jconfig.h.in filename, but that just adds to further errors).

I'm hoping someone here can either help me fix this or point me to where I can learn more. Your time is much appreciated!

Debian jpeglib62-turbo, but no jpeglib8-turbo

Might be better to ask to Debian community, but found this repo to be more accessible.
Is it true that there is no Debian package for libjpeg8-turbo? I'd like to accelerate Pillow, but I couldn't find it in the packages.

master no longer compiles with -DWITH_JPEG8=ON

Exact cmake command line:

cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE=/home/ismail/github/hacks/mingw/toolchain-x86_64-w64-mingw32.cmake -DCMAKE_INSTALL_PREFIX=/opt/mingw64-static -DBUILD_SHARED_LIBS=OFF -DWITH_JPEG8=ON -DWITH_TURBOJPEG=OFF ..

ends up with:
FAILED: /usr/bin/x86_64-w64-mingw32-gcc -DWITH_SIMD -Djpeg_EXPORTS -I. -I../ -O3 -DNDEBUG -MMD -MT sharedlib/CMakeFiles/jpeg.dir/__/jdapistd.c.obj -MF sharedlib/CMakeFiles/jpeg.dir/__/jdapistd.c.obj.d -o sharedlib/CMakeFiles/jpeg.dir/__/jdapistd.c.obj -c ../jdapistd.c ../jdapistd.c: In function 'jpeg_crop_scanline': ../jdapistd.c:193:16: error: 'struct jpeg_decompress_struct' has no member named 'min_DCT_scaled_size' align = cinfo->min_DCT_scaled_size * cinfo->max_h_samp_factor;

Parallel build with Java enabled fails using autotools build

Parallel build with Java enabled fails using autotools build.
Tested on:
Mac OS X 10.11.3
automake 1.15
autoconf 2.69

Configured with: ../libjpeg-turbo/configure --host i686-apple-darwin --with-java --with-pic --with-simd CFLAGS="-m32 -O3 -mmacosx-version-min=10.5" LDFLAGS="-m32" CC=/usr/local/opt/gcc/bin/gcc-5

Here's the log output:

Matt$ make -j8
/Applications/Xcode.app/Contents/Developer/usr/bin/make  all-recursive
Making all in java
 cd ../../libjpeg-turbo && /bin/sh /Users/Matt/Dev/libjpeg-turbo/libjpeg-turbo/missing automake-1.15 --foreign java/Makefile
 cd .. && /bin/sh ./config.status java/Makefile 
config.status: creating java/Makefile
make[2]: *** No rule to make target `TJExample.class', needed by `turbojpeg.jar'.  Stop.
make[2]: *** Waiting for unfinished jobs....
CLASSPATH=.:../../libjpeg-turbo/java/.${CLASSPATH:+":$CLASSPATH"} javac -d .  -target 1.5 -source 1.5  ../../libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJ.java ../../libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJCompressor.java ../../libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJCustomFilter.java ../../libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJDecompressor.java ../../libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJException.java ../../libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJScalingFactor.java ../../libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJTransform.java ../../libjpeg-turbo/java/org/libjpegturbo/turbojpeg/TJTransformer.java ../../libjpeg-turbo/java/org/libjpegturbo/turbojpeg/YUVImage.java ../../libjpeg-turbo/java/TJExample.java ../../libjpeg-turbo/java/TJUnitTest.java ../../libjpeg-turbo/java/TJBench.java org/libjpegturbo/turbojpeg/TJLoader.java
warning: [options] bootstrap class path not set in conjunction with -source 1.5
warning: [options] source value 1.5 is obsolete and will be removed in a future release
warning: [options] target value 1.5 is obsolete and will be removed in a future release
warning: [options] To suppress warnings about obsolete options, use -Xlint:-options.
4 warnings
echo timestamp > classnoinst.stamp
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2

Replacing the rule turbojpeg.jar: $(JAVA_CLASSES) ${srcdir}/MANIFEST.MF with turbojpeg.jar: classnoinst.stamp ${srcdir}/MANIFEST.MF in java/Makefile.am does the trick but I doubt this is the right way to do it & my knowledge of autotools does not allow me to propose a patch.

Commits for AltiVec SIMD support and partial image decoding are missing in Git repository

Unfortunately I screwed something up when I built the Git repository and applied fake merge data to properly represent all of my previous SVN cherry-picks. Basically all of the trunk commits that were made prior to the Git migration and not cherry-picked onto 1.4.x (including the AltiVec and partial decode features) became orphaned. I was able to recover them with the attached grafts file, but of course applying this grafts file permanently means that the object ID's after b6b3067 will change. I don't know if there's anything for it other than to bite the bullet and rewrite the history. I need those feature commits back in the log.

grafts.txt

low memory implementation for lossless transformation

Hi,
I was looking to open this issue in https://github.com/komakai/libjpeg-turbo
But since I was unable to open an issue there, I am opening it here because this is the next closest repository.
The forked version of the library works great for low memory devices without compromising a great deal on performance.

1.Have the fork being merged into the mainstream libjpeg-turbo?
2.Is there an equivalent low memory implementation for lossless jpeg transformations as well?

Data race in init_simd() - all platforms

As acknowledged in comments, init_simd() is racy in multi-threaded environments, with a potential data race in initializing 'simd_support' variable. The same race is present for all platforms (simd/jsimd_arm64.c, simd/jsimd_x86_64.c, etc).

Although the race looks 'benign', it would be nice to clean this up to avoid noise from tsan or related tools. The only issue I can see is if the environment variables JSIMD_FORCENONE or JSIMD_NOHUFFENC were changed in the middle of the data race, and even then the consequences seem mild - possibly unintended debugging mode for one of the threads.

In our environment, this race shows up in our tsan-instrumented fuzz tests that use libjpeg-turbo. We've worked around the issue by adding _Thread_local to the relevant globals ('simd_support' etc.) but this is not a general solution - not all toolchains are C11 compliant.

Clang 3.6 does not recognize .arch directive in jsimd_arm64_neon.S

The error message is:

external/libjpeg-turbo/./simd/jsimd_arm64_neon.S:32:1: error: unknown directive
.arch armv8-a+fp+simd
^

I think that clang 3.4 and above ignore the .arch directive, and now it looks like they've started indicating an error with clang 3.6. I'm not aware that clang has any intent to fix this any time soon.

This can fixed by deleting .arch armv8-a+fp+simd from simd/jsimd_arm64_neon.S. Any thoughts?

unity3d + ios64bit

Hi, i trying to integrate plugin with unity3d
on ios 32bit version it works fine but on 64bit i get this error
https://www.dropbox.com/s/win39u7strx4tp3/Screenshot%202016-02-15%2017.51.11.png?dl=0
uint outputsize variable is seems corrupted, how i can fix this?

this how this function implemented on c# side
private static extern void tjCompress2(IntPtr jpegCompressor, IntPtr srcImage , int width, int picth , int height, int pixelformat, ref IntPtr compressedimage, ref uint outputsize, int subsamp, int quality, int flags);

Change integral types in the C-API to the platform-independent

Hello!
I try to make .Net wrapper for libjpeg-turbo using C API defined in the turbojpeg.h
I've found issue with unsigned long parameters in the jtDecompressHeader3, jtDecompress2, jtTransform functions. The size of unsigned long is platform-dependent (4 bytes for x86 and 8 bytes for x64), but ulong in the .Net world is always 8 bytes.
That mismatch makes writing some ugly code like this:

static int tjDecompress(IntPtr handle, IntPtr jpegBuf, ulong jpegSize, IntPtr dstBuf, int width,
            int pitch, int height, int pixelFormat, int flags)
{
    switch (IntPtr.Size)
    {
        case 4:
            return tjDecompress2_x86(handle, jpegBuf, (uint)jpegSize, dstBuf, width, pitch, height, pixelFormat, flags);
        case 8:
            return tjDecompress2_x64(handle, jpegBuf, jpegSize, dstBuf, width, pitch, height, pixelFormat, flags);

        default:
            throw new InvalidOperationException("Invalid platform. Can not find proper function");
    }
}

[DllImport("turbojpeg.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "tjDecompress2")]
private static extern int tjDecompress2_x86(IntPtr handle, IntPtr jpegBuf, uint jpegSize, IntPtr dstBuf, int width, int pitch, int height, int pixelFormat, int flags);
[DllImport("turbojpeg.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "tjDecompress2")]
private static extern int tjDecompress2_x64(IntPtr handle, IntPtr jpegBuf, ulong jpegSize, IntPtr dstBuf, int width, int pitch, int height, int pixelFormat, int flags);

I think it was much more better to use platform independent types (like int64_t defined in the <inttypes.h>) for public API

Migrating build system to CMake [FEEDBACK REQUESTED FROM COMMUNITY]

Numerous requests, including most recently #21, #29, and #37, have been received for implementing CMake build system support for non-Windows platforms. I've been getting those requests off and on since the project was founded.

I generally prefer CMake to autotools, and it would be convenient to have only one build system. However, there are some things that autotools does better, such as cross-compilation. Referring to my comments in the above issues, there are very good reasons why I absolutely will not entertain the notion of supporting multiple build systems on the same platform, so supporting CMake on non-Windows platforms will mean dropping support for autotools altogether. That's why I'm posting this. I need feedback from the community-- particularly those who are maintaining libjpeg-turbo packages for Linux distros, etc.-- as to whether this will create any significant downstream problems.

I think that most of the cross-compilation issues can be addressed by simply modifying the recipes in BUILDING.md to document the steps necessary to cross-compile libjpeg-turbo under CMake.

If there are no strong objections, I would like this to land in libjpeg-turbo 1.6, so speak now or forever hold your peace. Whether it lands will depend largely on whether I can secure funding, either directly or indirectly through the General Fund for one of my other projects, to implement this the "right way."

The "right way" means:

  • Porting all of the SIMD/assembler detection stuff from acinclude.m4 into CMake
  • Porting Un*x/Mac-specific stuff from autotools to CMake-- including the entire packaging system
  • Modifying our "official build" scripts
  • Modifying the testing framework so that traditional "make test" targets are still available on Un*x and Mac.
  • Extensive testing on all of the platforms we support [Windows (x86 + x86-64) * (VisualC++, MinGW, Cygwin), Linux (x86 + x86-64 + ARMv7 + ARMv8 + PowerPC), Android (x86 + x86-64 + ARM32 + ARM64), iOS (ARMv6 + ARMv7 + ARMv7s + ARMv8), OS X (x86 + x86-64 + PowerPC), FreeBSD (x86 + x86-64), Solaris (x86 + x86-64)]

This is easily 30 hours of work on my part, so not something I can do for free-- at least not in the near term.

I will not entertain any pull requests for this unless the submitter has demonstrated that all of the above steps have been done or unless the submitter is willing to fund my labor to do testing and integration of the patches. Otherwise, it has been my experience that most people who contribute patches test them only on the platforms they care about, so it ends up taking me more time to test and integrate and fix and extend those patches than it would have taken for me to develop them myself.

Possible undefined behavior in jcdctmgr.c's quantize() function

I'm a FreeBSD developer working on maintaining our copy of clang and llvm in the FreeBSD base system. While doing a test build run of all ports, the following libjpeg-turbo test failure was reported to me:

http://package22.nyi.freebsd.org/data/headamd64PR201377-default/2015-08-20_16h45m13s/logs/errors/libjpeg-turbo-1.4.0.log

This failure occurs on FreeBSD/amd64, not on FreeBSD/i386:

./cjpeg -sample 2x2 -quality 100 -dct fast -prog -outfile testout_420_q100_ifast_prog.jpg ./testimages/testorig.ppm
md5/md5cmp 990cbe0329c882420a2094da7e5adade testout_420_q100_ifast_prog.jpg
testout_420_q100_ifast_prog.jpg: FAILED.  Checksum is debb59d009a8010d7d925bf60ffb7e49

Searching the internet for similar test failures, I found this particular ticket, from February 2015:

http://sourceforge.net/p/libjpeg-turbo/bugs/85/

It might seem partially related, since it only occurs when compiling with gcc 4.9.1, and specifying -march=haswell. However, the original reporter also mentions it occurred on a 32-bit system.

In any case, after some analysis (using the Undefined Behavior Sanitizer, among others) it turns out that the quantize() function in jcdctmgr.c uses undefined behavior in some cases.

In particular, it sometimes tries to right-shift a 32-bit unsigned integer by 65551 bits, which is obviously illegal. For example, from a test run with UBSan enabled:

./cjpeg -sample 2x2 -quality 100 -dct fast -prog -outfile testout_420_q100_ifast_prog.jpg ./testimages/testorig.ppm
jcdctmgr.c:415:15: runtime error: shift exponent 65551 is too large for 32-bit type 'UDCTELEM2' (aka 'unsigned int')
jcdctmgr.c:410:15: runtime error: shift exponent 65551 is too large for 32-bit type 'UDCTELEM2' (aka 'unsigned int')

Initially the problem is triggered by the assignment on line 405, because the particular 'divisors' element chosen is -1 (!) at that point:

389 METHODDEF(void)
390 quantize (JCOEFPTR coef_block, DCTELEM * divisors, DCTELEM * workspace)
391 {
...
398   UDCTELEM recip, corr, shift;
...
401   for (i = 0; i < DCTSIZE2; i++) {
...
405     shift = divisors[i + DCTSIZE2 * 3];
...
410       product >>= shift + sizeof(DCTELEM)*8;
...
415       product >>= shift + sizeof(DCTELEM)*8;

Since shift is an unsigned short (in case of this build), it gets assigned 65535. Then, on lines 410 and 415, this causes the right shift of product by 65535 + 2 * 8 = 65551 bits.

Of course, the next question is: how does one of the shift elements of divisors[] become -1? Then we end up in compute_reciprocal(), which does not seem to handle a divisor argument of 1 very well:

171 LOCAL(int)
172 compute_reciprocal (UINT16 divisor, DCTELEM * dtbl)
173 {
174   UDCTELEM2 fq, fr;
175   UDCTELEM c;
176   int b, r;
177
178   b = flss(divisor) - 1;
... if 'divisor' is 1, 'b' becomes 0 ...
179   r  = sizeof(DCTELEM) * 8 + b;
... r becomes 16 ...
180
181   fq = ((UDCTELEM2)1 << r) / divisor;
182   fr = ((UDCTELEM2)1 << r) % divisor;
183
184   c = divisor / 2; /* for rounding */
185
186   if (fr == 0) { /* divisor is power of two */
187     /* fq will be one bit too large to fit in DCTELEM, so adjust */
188     fq >>= 1;
189     r--;
... since 'fr' will be 0, here 'r' becomes 15 ...
190   } else if (fr <= (divisor / 2U)) { /* fractional part is < 0.5 */
191     c++;
192   } else { /* fractional part is > 0.5 */
193     fq++;
194   }
195
196   dtbl[DCTSIZE2 * 0] = (DCTELEM) fq;      /* reciprocal */
197   dtbl[DCTSIZE2 * 1] = (DCTELEM) c;       /* correction + roundfactor */
198   dtbl[DCTSIZE2 * 2] = (DCTELEM) (1 << (sizeof(DCTELEM)*8*2 - r));  /* scale */
199   dtbl[DCTSIZE2 * 3] = (DCTELEM) r - sizeof(DCTELEM)*8; /* shift */
... and finally, this 'dtbl' element becomes -1.

The call to compute_reciprocal() with a divisor argument of 1 is done from start_pass_dctmgr(), in the JDCT_IFAST case:

217 METHODDEF(void)
218 start_pass_fdctmgr (j_compress_ptr cinfo)
219 {
...
259 #ifdef DCT_IFAST_SUPPORTED
260     case JDCT_IFAST:
261       {
...
287         dtbl = fdct->divisors[qtblno];
288         for (i = 0; i < DCTSIZE2; i++) {
289 #if BITS_IN_JSAMPLE == 8
290           if(!compute_reciprocal(
291             DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
292                                   (INT32) aanscales[i]),
293                     CONST_BITS-3), &dtbl[i])

At this point, qtbl->quantval[i] is 1, which appears to be legal, and aanscales[i] is 2446, resulting in a divisor of 1.

So it looks to me like a divisor of 1 is legal, but how should this be handled properly in compute_reciprocal()? The resulting "real" reciprocal should be 1, obviously, but in terms of the function's variables, they should likely be:

b = 0
r = (word size)    [16, in our case]
f = 2^(word size)  [65536, in our case]

Unfortunately, with DCTELEM being a 16-bit short, the resulting f value does not fit! So how to solve this conundrum? I am unsure at this point, and any advice is welcome. :-)

Change of destination manager has no guards against memory corruption if misused

Setting destination to a file, and then changing it to mem dest leads to memory corruption, because previously allocated dest struct size will be too small.

There is a comment that says it's dangerous, but it doesn't try to detect or prevent this.

Initializer function pointer can be used as a magic identifier for the type of the struct, so incorrect use can be easily detected and prevented.

build.md: nasm needed for Visual C++ IDE build

I just wanted to leave some feedback on the build.md file. If this is not the correct place to leave my feedback, I'm sorry.

I just built jpeglib-turbo for the first time. I built it using the Visual C++ 2015 IDE. The build.md file was very helpful, but one step was missing. I had to download nasm, and add the install location to my PATH. May I suggest that this step be added to the build.md description?

Thanks.

Error while executing configure to cross compile libjpeg-turbo for mips(el)

I've tried to build libjpeg-turbo for a small Kingston device running openwrt. After I build successfully different kind of libraries and application for this small device, I've tried to build libjpeg-turbo as well. When I called the configure script I got the following error message and the configure stops processing.

checking whether the linker accepts assembler output... no
configure: error: configuration problem: maybe object file format mismatch.

I ask myself does libjpeg-turbo support mips(el)? Do I have to pass extra options to execute the configure script successfully?

#  ./configure --host=i686-pc-linux-gnu
zsh: datei oder Verzeichnis nicht gefunden:  ./configure
blackhawk% autoreconf -fi                       
libtoolize: putting auxiliary files in `.'.
libtoolize: copying file `./ltmain.sh'
libtoolize: Consider adding `AC_CONFIG_MACRO_DIR([m4])' to configure.ac and
libtoolize: rerunning libtoolize, to keep the correct libtool macros in-tree.
libtoolize: Consider adding `-I m4' to ACLOCAL_AMFLAGS in Makefile.am.
blackhawk% autoreconf -fiv
autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force 
autoreconf: configure.ac: tracing
autoreconf: running: libtoolize --copy --force
libtoolize: putting auxiliary files in `.'.
libtoolize: copying file `./ltmain.sh'
libtoolize: Consider adding `AC_CONFIG_MACRO_DIR([m4])' to configure.ac and
libtoolize: rerunning libtoolize, to keep the correct libtool macros in-tree.
libtoolize: Consider adding `-I m4' to ACLOCAL_AMFLAGS in Makefile.am.
autoreconf: running: /usr/bin/autoconf --force
autoreconf: running: /usr/bin/autoheader --force
autoreconf: running: automake --add-missing --copy --force-missing
autoreconf: Leaving directory `.'
blackhawk%  ./configure --host=i686-pc-linux-gnu
zsh: datei oder Verzeichnis nicht gefunden:  ./configure
blackhawk% pwd
/home/sbrinkmann/Projects/libjpeg-turbo-1.4.2
blackhawk%  ./configure --host=i686-pc-linux-gnu
zsh: datei oder Verzeichnis nicht gefunden:  ./configure
blackhawk% ./configure --host=i686-pc-linux-gnu 
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for i686-pc-linux-gnu-strip... no
checking for strip... strip
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking whether make supports nested variables... (cached) yes
checking for style of include used by make... GNU
checking for i686-pc-linux-gnu-gcc... mipsel-openwrt-linux-gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... yes
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether mipsel-openwrt-linux-gcc accepts -g... yes
checking for mipsel-openwrt-linux-gcc option to accept ISO C89... none needed
checking whether mipsel-openwrt-linux-gcc understands -c and -o together... yes
checking dependency style of mipsel-openwrt-linux-gcc... gcc3
checking how to run the C preprocessor... mipsel-openwrt-linux-gcc -E
checking for i686-pc-linux-gnu-gcc... (cached) mipsel-openwrt-linux-gcc
checking whether we are using the GNU C compiler... (cached) yes
checking whether mipsel-openwrt-linux-gcc accepts -g... (cached) yes
checking for mipsel-openwrt-linux-gcc option to accept ISO C89... (cached) none needed
checking whether mipsel-openwrt-linux-gcc understands -c and -o together... (cached) yes
checking dependency style of mipsel-openwrt-linux-gcc... (cached) gcc3
checking for i686-pc-linux-gnu-ar... no
checking for i686-pc-linux-gnu-lib... no
checking for i686-pc-linux-gnu-link... no
checking for ar... ar
configure: WARNING: using cross tools not prefixed with host triplet
checking the archiver (ar) interface... ar
checking dependency style of mipsel-openwrt-linux-gcc... gcc3
checking build system type... x86_64-unknown-linux-uclibc
checking host system type... i686-pc-linux-gnu
checking how to print strings... printf
checking for a sed that does not truncate output... /bin/sed
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for fgrep... /bin/grep -F
checking for ld used by mipsel-openwrt-linux-gcc... /home/sbrinkmann/Projects/openwrt-14.07/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/mipsel-openwrt-linux-uclibc/bin/ld
checking if the linker (/home/sbrinkmann/Projects/openwrt-14.07/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/mipsel-openwrt-linux-uclibc/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... no
checking for i686-pc-linux-gnu-dumpbin... no
checking for i686-pc-linux-gnu-link... no
checking for dumpbin... no
checking for link... link -dump
checking the name lister (nm) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking whether the shell understands some XSI constructs... yes
checking whether the shell understands "+="... yes
checking how to convert x86_64-unknown-linux-uclibc file names to i686-pc-linux-gnu format... func_convert_file_noop
checking how to convert x86_64-unknown-linux-uclibc file names to toolchain format... func_convert_file_noop
checking for /home/sbrinkmann/Projects/openwrt-14.07/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/mipsel-openwrt-linux-uclibc/bin/ld option to reload object files... -r
checking for i686-pc-linux-gnu-objdump... no
checking for objdump... objdump
checking how to recognize dependent libraries... pass_all
checking for i686-pc-linux-gnu-dlltool... no
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for i686-pc-linux-gnu-ar... ar
checking for archiver @FILE support... @
checking for i686-pc-linux-gnu-strip... strip
checking for i686-pc-linux-gnu-ranlib... no
checking for ranlib... ranlib
checking command to parse nm output from mipsel-openwrt-linux-gcc object... ok
checking for sysroot... no
checking for i686-pc-linux-gnu-mt... no
checking for mt... mt
checking if mt is a manifest tool... no
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking for objdir... .libs
checking if mipsel-openwrt-linux-gcc supports -fno-rtti -fno-exceptions... no
checking for mipsel-openwrt-linux-gcc option to produce PIC... -fPIC -DPIC
checking if mipsel-openwrt-linux-gcc PIC flag -fPIC -DPIC works... yes
checking if mipsel-openwrt-linux-gcc static flag -static works... yes
checking if mipsel-openwrt-linux-gcc supports -c -o file.o... yes
checking if mipsel-openwrt-linux-gcc supports -c -o file.o... (cached) yes
checking whether the mipsel-openwrt-linux-gcc linker (/home/sbrinkmann/Projects/openwrt-14.07/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/mipsel-openwrt-linux-uclibc/bin/ld) supports shared libraries... yes
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... yes
checking whether ln -s works... yes
checking size of size_t... 4
checking whether compiler supports pointers to undefined structures... yes
checking whether __SUNPRO_C is declared... no
checking for ANSI C header files... (cached) yes
checking stddef.h usability... yes
checking stddef.h presence... yes
checking for stddef.h... yes
checking for stdlib.h... (cached) yes
checking locale.h usability... yes
checking locale.h presence... yes
checking for locale.h... yes
checking for string.h... (cached) yes
checking for sys/types.h... (cached) yes
checking for an ANSI C-conforming const... yes
checking whether char is unsigned... no
checking for inline... inline
checking for size_t... yes
checking for unsigned char... yes
checking for unsigned short... yes
checking if right shift is signed... Assuming that right shift is signed on target machine.
checking for memset... yes
checking for memcpy... yes
checking libjpeg API version... 6.2
checking whether to include in-memory source/destination managers... yes
checking libjpeg shared library version... 62.1.0
checking whether the linker supports version scripts... yes (GNU style)
checking whether to use version script when building libjpeg-turbo... yes
checking for inline... inline __attribute__((always_inline))
checking whether to include arithmetic encoding support... yes
checking whether to include arithmetic decoding support... yes
checking whether to use 12-bit samples... no
checking whether to build TurboJPEG C wrapper... yes
checking whether to build TurboJPEG Java wrapper... no
checking if we have SIMD optimisations for cpu type... yes (i386)
checking for nasm... nasm
checking for object file format of host system... ELF
checking for object file format specifier (NAFLAGS) ... -felf -DELF
checking whether the assembler (nasm -felf -DELF) works... yes
checking whether the linker accepts assembler output... no
configure: error: configuration problem: maybe object file format mismatch.

Some further information about the device for which I would like to use libjpeg-turbo.

# cat /proc/cpuinfo
system type     : Ralink MT7620N ver:2 eco:3
machine         : Kingston MLW221
processor       : 0
cpu model       : MIPS 24KEc V5.0
BogoMIPS        : 385.84
wait instruction    : yes
microsecond timers  : yes
tlb_entries     : 32
extra interrupt vector  : yes
hardware watchpoint : yes, count: 4, address/irw mask: [0x0000, 0x0bd0, 0x06e0, 0x0d38]
isa         : mips1 mips2 mips32r1 mips32r2
ASEs implemented    : mips16 dsp
shadow register sets    : 1
kscratch registers  : 0
core            : 0
VCED exceptions     : not available
VCEI exceptions     : not available

Decoding issue with libjpeg-turbo 1.4.2 on ARM64 Android

libjpeg-turbo 1.4.2 does not correctly decode the attached image (original_image) at least on Android when built for arm64-v8a. A section of a screenshot of the wrongly decoded image is also attached (jpegturbo1_4_2_issue).

The issue was observed on a Nexus 9. The lib was built with Android ndk-r10e using Clang. It does use the arm assembly code.

libjpeg-turbo 1.4.0 decodes the same image correctly on the same hardware.

v1.4.2 on windows, mac, iOS does not seem to exhibit this issue either.

Android uses unsigned char rather than signed, maybe that can be a factor.

I tried commenting out a change that looked suspicious in jddctmgr.c but it didn't change the result. The change was a block braced by if (divisor == 1) { .... } in compute_reciprocal(). None of the arm-specific assembler code was changed from 1.4.0 to 1.4.2

I am happy to help bisect this issue on that hardware.

jpegturbo_1_4_2_issue
original_image

Pixel ratio support

Hi,
It seems that there is no way to set the pixel aspect ratio (X_density / Y_density) as we can do with libjpeg. tjCompress2 only expose few arguments and the jpeghandle use blind pointer to tjinstance defined in the turbojpeg.c.
So there is no way to access the "jpeg_compress_struct".

I tried a hack by redefining the tjinstance struct on my side, but in fact the tjCompress2 reset the default values there.

Is there a way to do it?

MIPS SIMD seg fault on 1x1 pixel image

jsimd_h2v2_upsample_mips_dspr2 () walks off the end of a buffer and seg faults on a 1x1 pixel image. The non-SIMD version of the upsample code works fine. The image is attached.
#0 jsimd_h2v2_upsample_mips_dspr2 ()

at .../libjpeg-turbo-1.4.1/simd/jsimd_mips_dspr2.S:1824

#1 0x2cdfb7c8 in sep_upsample (cinfo=0x3e6fe2d8, input_buf=, in_row_group_ctr=0x25a3fd4,

in_row_groups_avail=<optimized out>, output_buf=0x25a54a0, out_row_ctr=0x3e6fe290, out_rows_avail=1)
at .../libjpeg-turbo-1.4.1/jdsample.c:114

#2 0x2cdf2fb4 in process_data_simple_main (cinfo=0x3e6fe2d8, output_buf=0x25a54a0, out_row_ctr=0x3e6fe290,

out_rows_avail=<optimized out>)
at .../libjpeg-turbo-1.4.1/jdmainct.c:370

#3 0x2cdebb08 in jpeg_read_scanlines (cinfo=0x3e6fe2d8, scanlines=0x25a54a0, max_lines=1)

at .../libjpeg-turbo-1.4.1/jdapistd.c:176

...

black_pixel

multiple threads

Hi,

And thank you for this wonderful code.

Right now I'm trying to use jpeg62.dll (1.4.9 version) in a Delphi application for decoding many (almost identical) jpeg files into TBitmaps as fast as possible.
The decoder is very fast (< 1 ms on a 768x768 24 bit image) but moving the data into the bitmap is slow (30..40 ms).
I'm using this code:

//variables
jpeg: jpeg_decompress_struct;
jpeg_err: jpeg_error_mgr;
prow: Prgbarray;
RowD: Prgbarray;

...........

// reading image
jpeg_start_decompress(@jpeg);

// allocate row
GetMem(prow, jpeg.output_width * 3);

//here becomes very slow
inherited SetSize(jpeg.output_width, jpeg.output_height);
inherited PixelFormat := pf24bit;
for y := 0 to jpeg.output_height - 1 do
begin
// reading row
jpeg_read_scanlines(@jpeg, @prow, 1);
rowD := scanline[y];
for x := 0 to jpeg.output_width - 1 do
begin
rowD[x].RgbtRed := prow[x].Rgbtblue;
rowD[x].Rgbtgreen := prow[x].Rgbtgreen;
rowD[x].Rgbtblue := prow[x].RgbtRed;
end;
end;

Is there any way to speed it up?

I thought about using multiple threads.
I already tried decoding separate jpegs into separate bitmaps (each in its own thread), but I got access memory violation.


Debugger Exception Notification

Project Test.exe raised exception class $C0000005 with message 'access violation at 0xfeeefeee: read of address 0xfeeefeee'.

Break Continue Help

I get the exactly same error from all threads.
It's like the decoder is using the same memory range in all threads. Which is weird because the threads are using separate memory.

Any advice?

Thank you in advance.

Best regards,
David

minor error in documentation

int h_samp_factor
int v_samp_factor
        Horizontal and vertical sampling factors for the component; must
        be 1..4 according to the JPEG standard.  Note that larger sampling
        factors indicate a higher-resolution component; many people find
        this behavior quite unintuitive.  The default values are 2,2 for
        luminance components and 1,1 for chrominance components, except
        for grayscale where 1,1 is used.

In particular.

The default values are 2,2 for luminance components and 1,1 for chrominance components, [...].

Which is contradicted elsewhere in the documentation.

    CAUTION: Setting separate quality levels for chrominance and luminance
    is mainly only useful if chrominance subsampling is disabled.  2x2
    chrominance subsampling (AKA "4:2:0") is the default, but you can
    explicitly disable subsampling as follows:

            cinfo->comp_info[0].v_samp_factor = 1;
            cinfo->comp_info[0].h_samp_factor = 1;

And in code.

  case JCS_YCbCr:
    cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
    cinfo->num_components = 3;
    /* JFIF specifies component IDs 1,2,3 */
    /* We default to 2x2 subsamples of chrominance */
    SET_COMP(0, 1, 2,2, 0, 0,0);
    SET_COMP(1, 2, 1,1, 1, 1,1);
    SET_COMP(2, 3, 1,1, 1, 1,1);

Add version strings

Going by the changelog, libjpeg-turbo has a history of buffer overflows and other security critical bugs. It would be nice if we could look at a given binary and determine if it has known vulnerabilities, but right now there are no version strings, which makes this impossible.

Please add a version string, and make sure it is included in the compiled binaries.

cmake building does not seem to work

I cloned the repo and did

cmake .
make

This results in:

/jchuff.c:380:2: error: #error Cannot determine word size
#error Cannot determine word size
^

Where can I submit security bugs to?

I have a few security bugs I've found with fuzzing, would like to report them in a non public manner, along with patches to fix.

Cheers,

Hugh

Add partial decode support to the TurboJPEG API

Thanks in part to a code contribution from Google, the libjpeg API in the evolving libjpeg-turbo 1.5 code base (master branch) can now partially decode JPEG images (more specifically, it can skip ranges of scanlines.)

It would be straightforward to expose this functionality in the TurboJPEG API as well, which might be beneficial for applications needing to decode subsets of large JPEG images, or for mobile applications that need to conserve memory. However, extending the TurboJPEG API to include this functionality will require significant time and effort. In addition to extending the C and Java APIs (and documenting the extensions), it would be necessary to add appropriate unit tests and performance tests.

'make test' failed if choose DCT precision to JDCT_FLOAT

Tested with latest release 1.4.2, select the DCT precision with type JDCT_FLOAT, like this:
249
250 #ifndef JDCT_DEFAULT /* may be overridden in jconfig.h /
251 #define JDCT_DEFAULT JDCT_FLOAT
252 #endif
253 #ifndef JDCT_FASTEST /
may be overridden in jconfig.h */
254 #define JDCT_FASTEST JDCT_FLOAT
255 #endif

The test failed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.