fc324109d5 checked for unsigned int
overflow, but jsize is always a signed int, even when using a 64-bit
JVM. (This reflects the fact that array sizes in Java are always signed
ints.) Thus, array sizes should be checked against INT_MAX, not
UINT_MAX.
In almost all cases, this is a belt-and-suspenders measure. With the
exception of TJCompressor.loadSourceImage(), the array size checks in
question are checking a Java array, which can never have more than
INT_MAX elements. Thus, even if the previous unsigned int overflow
checks failed to catch signed int overflow, the error would have been
caught in a different place. With TJCompressor.loadSourceImage(), it
was possible to load a packed-pixel image large enough that arraySize
overflowed a signed int and caused the NewByteArray() or NewShortArray()
JNI methods to crash the JVM. However, this would have required a
multi-gigabyte packed-pixel image.
This commit also improves the array size checks in
TJCompressor.loadSourceImage() and TJDecompressor.saveImage() so that
they take into account row alignment/pitch.
Fixes#877
If TJPARAM_SAVEMARKERS was set to 2 or 4, TJXOPT_COPYNONE was not
specified, an ICC profile was extracted from the source image, and
another ICC profile was associated with the TurboJPEG instance using
tj3SetICCProfile(), tj3Transform() embedded both profiles in the
destination image. This was mainly problematic because it might have
caused the destination image to exceed the worst-case size reported by
tj3TransformBufSize().
jpegtran would actually embed both ICC profiles as well, except that it
removes ICC profiles from the marker copying option if -icc is
specified. The documented TurboJPEG API behavior is for TJXOPT_COPYNONE
to take precedence over TJPARAM_SAVEMARKERS and for TJPARAM_SAVEMARKERS
to take precedence over the associated ICC profile. It would've been
easier to let the associated ICC profile take precedence, but the intent
of the TurboJPEG 3.1 API design was to allow either the associated or
extracted ICC profile to be selected on a per-transform basis using
TJXOPT_COPYNONE. Basically, if TJPARAM_SAVEMARKERS is 2 or 4 and
TJXOPT_COPYNONE is not specified, that means "always copy the ICC
profile from the source image, even if it doesn't have one."
tj3TransformBufSize() assumes that behavior.
Use try-with-resources statements, where possible, to automatically
close FileInputStream, FileOutputStream, TJCompressor, TJDecompressor,
and TJTransformer instances. We can't rely on the finalize() method in
the TurboJPEG classes anymore, because it has been deprecated and marked
for removal (although, as of this writing, it has yet to be removed.)
- Since the existing run-time API mismatch checks compared constants
that are known at compile time, replace those checks with compile-time
checks. This ensures that an API mismatch is caught early.
- Implement actual run-time API mismatch checks to ensure that tj3Get(),
tj3DecompressHeader(), and tj3LoadImage*() do not return subsampling,
colorspace, or pixel format values that the TurboJPEG Java API can't
handle.
- Check subsampling, colorspace, and transform operation arguments
against the maximum values supported by the TurboJPEG Java API. This
prevents a (currently hypothetical) hard-to-diagnose failure whereby
the C API would not catch out-of-bounds arguments from the Java API if
the JNI library was accidentally used at run time with a newer version
of the TurboJPEG API library that supports more options. (TurboJPEG
3.2 will likely support more subsampling options.)
If CMAKE_INSTALL_*DIR is blank, it means "install these components at
the top level of ${CMAKE_INSTALL_PREFIX}." However, we need to expand
these variables to their full-path equivalents so that CMake doesn't
complain about a missing argument in install*() or try to install the
components in the root directory.
- Use System.mapLibraryName() rather than specifying a platform-specific
shared library prefix and extension.
- Don't try to load libturbojpeg.dylib from /usr/lib on macOS. With
7175e51792 (libjpeg-turbo 1.3.0), we
stopped installing libturbojpeg.dylib under /usr/lib, and such is not
even possible with modern macOS releases. Most likely, that fallback
code remained in libjpeg-turbo 1.3.x because early versions of the
TurboJPEG Java API attempted to allow mixing and matching of versions
between the Java front end and JNI library. (That was a relic of Java
Web Start, the idea being that turbojpeg.jar could be deployed
remotely via JWS and use a client-side installation of the TurboJPEG
API library. Eventually, that strategy became impossible to support.)
- Put a space after (C) in BSD-licensed source files.
- Add missing trailing period in jcphuff-sse2.asm.
- Remove comma after copyright date in src/md5/md5.c.
If the data precision of the PBMPLUS file does not match the target data
precision, then the grayscale or RGB samples are rescaled to the target
data precision. Thus, we need to pass (1 << cinfo->data_precision) - 1
to rgb_to_cmyk() instead of maxval. This commit also modifies
TJUnitTest so that it validates the correctness of upconversion and
downconversion in the PPM reader.
Fixes#841
If loading a 2-to-8-bit image, unset srcBuf12 and srcBuf16. If loading
a 9-to-12-bit image, unset srcBuf8 and srcBuf16. If loading a
13-to-16-bit image, unset srcBuf8 and srcBuf12. Otherwise,
TJCompressor.getSourceBuf() will return srcBuf8 or srcBuf12, in order,
if any previous invocation of TJCompressor.loadSourceImage() set them,
irrespective of the buffer that was set by the most recent invocation.
This probably helps with garbage collection as well, since it signals to
the GC that the unused buffers are really unused.
This is not a security vulnerability, since applications that pass such
values to the Java API would fail regardless, and such a bug would never
make it into the wild. By contrast, a security vulnerability arises
from applications that work correctly with most input data sets but
trigger a library failure, such as a buffer overrun, with one or more
specific input data sets. As with most imaging APIs, the libjpeg-turbo
APIs rely upon the calling application to pass appropriately-sized
buffers and appropriate size/dimension arguments. The failure to do so
is no more the fault of libjpeg-turbo than calling
'buf = malloc(1); buf[2] = 0;' is the fault of the C library.
Buffer size checking is a bonus feature of the Java API that isn't (and
can't be) provided by the C API, so this commit merely hardens the bonus
feature against API abuse, in keeping with the Java paradigm of throwing
an exception rather than crashing due to a caller-imposed buffer
overrun.
- Clarify that YUV encoding performs downsampling as well as color
conversion.
- Clarify that TJPARAM_LOSSLESS is ignored by tj3CompressFromYUV*8().
- Clarify that tj3CompressFromYUV*8() generates only YCbCr or grayscale
JPEG images, i.e. that TJPARAM_COLORSPACE has no effect.
This is subtle, but #include <header.h> searches directories specified
with -I, then system include directories. #include "header.h" searches
the current source directory, then directories specified with -I, then
system include directories.
Using bracketed #include directives for jpeglib.h, jinclude.h, jerror.h,
cdjpeg.h, and turbojpeg.h only worked because the build system
explicitly passed -I{source_directory}/src/ to the compiler. Referring
to 51cee03629, it's better for the source
code to have as few dependencies on our specific build system as
possible.
Since jpeglib.h, jinclude.h, jerror.h, and turbojpeg.h can be installed
in system include directories, it's also better for internal references
to those headers to resolve internally first, to avoid potential
conflicts between the system-installed version of libjpeg-turbo and the
version being built. (Such conflicts would never have occurred with our
build system, but they might have occurred due to misintegration with a
downstream build system.)
Since libjpeg-turbo does not support Exif, the only way it can embed
density information in a JPEG image is by using the JFIF marker, which
is only written if the JPEG colorspace is YCbCr or grayscale.
(Referring to the conversation under #793, we may need to further
restrict that to 8-bit-per-sample JPEG images, because the JFIF spec
requires 8-bit data precision.)
This is just a code readability thing. The logic effectively caused the
data precision to default to 8 if -precision was not specified, but that
was not obvious.
This commit also modifies tjcomptest so that it tests TJComp with no
-precision argument, to ensure that the data precision defaults to 8.
Since the introduction of TJFLAG_NOREALLOC in libjpeg-turbo 1.2.x, the
TurboJPEG C API documentation has (confusingly) stated that:
- if the JPEG buffer pointer points to a pre-allocated buffer, then the
JPEG buffer size must be specified, and
- the JPEG buffer size should be specified if the JPEG buffer is
pre-allocated to an arbitrary size.
The documentation never explicitly stated that the JPEG buffer size
should be specified if the JPEG buffer is pre-allocated to a worst-case
size, but since focus does not imply exclusion, it also never explicitly
stated the reverse. Furthermore, the documentation never stated that
this was contingent upon TJPARAM_NOREALLOC/TJFLAG_NOREALLOC. However,
effectively the compression and lossless transformation functions
ignored the JPEG buffer size(s) passed to them, and assumed that the
JPEG buffer(s) had been allocated to a worst-case size, if
TJPARAM_NOREALLOC/TJFLAG_NOREALLOC was set. This behavior was an
accidental and undocumented throwback to libjpeg-turbo 1.1.x, in which
the tjCompress() function provided no way to specify the JPEG buffer
size. It was always a bad idea for applications to rely upon that
behavior (although our own TJBench application unfortunately did.)
However, if such applications exist in the wild, the new behavior would
constitute a breaking change, so it has been introduced only into
libjpeg-turbo 3.1.x and only into TurboJPEG 3 API functions. The
previous behavior has been retained when calling functions from the
TurboJPEG 2.1.x API and prior versions.
Did I mention that APIs are hard?
With respect to tj3Transform(), this addresses an oversight from
bb1d540a80.
Note to self: A convenience function/method for computing the worst-case
transformed JPEG size for a particular transform would be nice.
- When transforming, the worst-case JPEG buffer size depends on the
subsampling level used in the destination image, since a grayscale
transform might have been applied.
- Parentheses Police
-copynone --> -copy none
Add '-copy all', even though it's the default.
-rgb, -bgr, -rgbx, -bgrx, -xbgr, -xrgb, -gray, -cmyk -->
-pixelformat {rgb|bgr|rgbx|bgrx|xbgr|xrgb|gray|cmyk}
(This is mainly so -gray won't interfere with -grayscale.)
Fix an ArrayIndexOutOfBoundsException that occurred when passing -dct
to the Java version without specifying the DCT algorithm (oversight from
24fbf64d31a0758c63bcc27cf5d92fc5611717d0.)