TurboJPEG: Add lossless JPEG detection capability

Add a new TurboJPEG C API function (tjDecompressHeader4()) and Java API
method (TJDecompressor.getFlags()) that return the bitwise OR of any
flags that are relevant to the JPEG image being decompressed (currently
TJFLAG_PROGRESSIVE, TJFLAG_ARITHMETIC, TJFLAG_LOSSLESS, and their Java
equivalents.)  This allows a calling program to determine whether the
image being decompressed is a lossless JPEG image, which means that the
decompression scaling feature will not be available and that a
full-sized destination buffer should be allocated.

More specifically, this fixes a buffer overrun in TJBench, TJExample,
and the decompress* fuzz targets that occurred when attempting (in vain)
to decompress a lossless JPEG image with decompression scaling enabled.
This commit is contained in:
DRC
2022-11-21 20:57:39 -06:00
parent b85b028d2b
commit 98ff1fd103
32 changed files with 481 additions and 283 deletions

View File

@@ -168,11 +168,16 @@ final class TJBench {
TJDecompressor tjd;
double elapsed, elapsedDecode;
int ps = TJ.getPixelSize(pf), i, iter = 0;
int scaledw = sf.getScaled(w);
int scaledh = sf.getScaled(h);
int pitch = scaledw * ps;
int scaledw, scaledh, pitch;
YUVImage yuvImage = null;
if ((flags & TJ.FLAG_LOSSLESS) != 0)
sf = new TJScalingFactor(1, 1);
scaledw = sf.getScaled(w);
scaledh = sf.getScaled(h);
pitch = scaledw * ps;
if (jpegQual > 0)
qualStr = new String("_Q" + jpegQual);
@@ -498,7 +503,7 @@ final class TJBench {
// Original image
int w = 0, h = 0, ntilesw = 1, ntilesh = 1, subsamp = -1, cs = -1;
// Transformed image
int tw, th, ttilew, ttileh, tntilesw, tntilesh, tsubsamp;
int tw, th, ttilew, ttileh, tntilesw, tntilesh, tsubsamp, jpegFlags;
FileInputStream fis = new FileInputStream(fileName);
if (fis.getChannel().size() > (long)Integer.MAX_VALUE)
@@ -521,6 +526,10 @@ final class TJBench {
h = tjt.getHeight();
subsamp = tjt.getSubsamp();
cs = tjt.getColorspace();
jpegFlags = tjt.getFlags();
if ((jpegFlags & TJ.FLAG_LOSSLESS) != 0)
sf = new TJScalingFactor(1, 1);
if (quiet == 1) {
System.out.println("All performance values in Mpixels/sec\n");