Merge libjpeg-turbo 2.0.5

* tag '2.0.5':
  TurboJPEG: Make global error handling thread-safe
  ChangeLog.md: Add missing sub-header for 2.0.5
  ChangeLog.md: List CVE ID fixed by previous commit
  rdppm.c: Fix buf overrun caused by bad binary PPM
  Build: Add missing jpegtran-icc test dependency
  rdswitch.c: Eliminate spaces before semicolons
  TJCompressor.compress(int): Fix YUV-to-JPEG error
  Bump version to 2.0.5; Document previous commit
  MIPS DSPr2: Work around various 'make test' errors
  MIPS DSPr2: Fix compiler warning with -mdspr2
  MIPS SIMD: Always honor JSIMD_FORCE* env vars
  Test: Honor CMAKE_CROSSCOMPILING_EMULATOR variable
This commit is contained in:
Kornel Lesiński
2020-08-15 18:11:20 +01:00
11 changed files with 174 additions and 73 deletions

View File

@@ -5,7 +5,7 @@ if(CMAKE_EXECUTABLE_SUFFIX)
endif() endif()
project(mozjpeg C) project(mozjpeg C)
set(VERSION 4.0.0) set(VERSION 4.0.1)
string(REPLACE "." ";" VERSION_TRIPLET ${VERSION}) string(REPLACE "." ";" VERSION_TRIPLET ${VERSION})
list(GET VERSION_TRIPLET 0 VERSION_MAJOR) list(GET VERSION_TRIPLET 0 VERSION_MAJOR)
list(GET VERSION_TRIPLET 1 VERSION_MINOR) list(GET VERSION_TRIPLET 1 VERSION_MINOR)
@@ -453,6 +453,21 @@ if(NOT INLINE_WORKS)
endif() endif()
message(STATUS "INLINE = ${INLINE} (FORCE_INLINE = ${FORCE_INLINE})") message(STATUS "INLINE = ${INLINE} (FORCE_INLINE = ${FORCE_INLINE})")
if(WITH_TURBOJPEG)
if(MSVC)
set(THREAD_LOCAL "__declspec(thread)")
else()
set(THREAD_LOCAL "__thread")
endif()
check_c_source_compiles("${THREAD_LOCAL} int i; int main(void) { i = 0; return i; }" HAVE_THREAD_LOCAL)
if(HAVE_THREAD_LOCAL)
message(STATUS "THREAD_LOCAL = ${THREAD_LOCAL}")
else()
message(WARNING "Thread-local storage is not available. The TurboJPEG API library's global error handler will not be thread-safe.")
unset(THREAD_LOCAL)
endif()
endif()
if(UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/conftest.map "VERS_1 { global: *; };") file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/conftest.map "VERS_1 { global: *; };")
set(CMAKE_REQUIRED_FLAGS set(CMAKE_REQUIRED_FLAGS
@@ -923,12 +938,18 @@ foreach(libtype ${TEST_LIBTYPES})
set(suffix -static) set(suffix -static)
endif() endif()
if(WITH_TURBOJPEG) if(WITH_TURBOJPEG)
add_test(tjunittest-${libtype} tjunittest${suffix}) add_test(tjunittest-${libtype}
add_test(tjunittest-${libtype}-alloc tjunittest${suffix} -alloc) ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix})
add_test(tjunittest-${libtype}-yuv tjunittest${suffix} -yuv) add_test(tjunittest-${libtype}-alloc
add_test(tjunittest-${libtype}-yuv-alloc tjunittest${suffix} -yuv -alloc) ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -alloc)
add_test(tjunittest-${libtype}-yuv-nopad tjunittest${suffix} -yuv -noyuvpad) add_test(tjunittest-${libtype}-yuv
add_test(tjunittest-${libtype}-bmp tjunittest${suffix} -bmp) ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -yuv)
add_test(tjunittest-${libtype}-yuv-alloc
${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -yuv -alloc)
add_test(tjunittest-${libtype}-yuv-nopad
${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -yuv -noyuvpad)
add_test(tjunittest-${libtype}-bmp
${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -bmp)
set(MD5_PPM_GRAY_TILE 89d3ca21213d9d864b50b4e4e7de4ca6) set(MD5_PPM_GRAY_TILE 89d3ca21213d9d864b50b4e4e7de4ca6)
set(MD5_PPM_420_8x8_TILE 847fceab15c5b7b911cb986cf0f71de3) set(MD5_PPM_420_8x8_TILE 847fceab15c5b7b911cb986cf0f71de3)
@@ -953,22 +974,23 @@ foreach(libtype ${TEST_LIBTYPES})
${CMAKE_COMMAND} -E copy_if_different ${TESTIMAGES}/testorig.ppm ${CMAKE_COMMAND} -E copy_if_different ${TESTIMAGES}/testorig.ppm
testout_tile.ppm) testout_tile.ppm)
add_test(tjbench-${libtype}-tile add_test(tjbench-${libtype}-tile
tjbench${suffix} testout_tile.ppm 95 -rgb -quiet -tile -benchtime 0.01 ${CMAKE_CROSSCOMPILING_EMULATOR} tjbench${suffix} testout_tile.ppm 95
-warmup 0) -rgb -quiet -tile -benchtime 0.01 -warmup 0)
set_tests_properties(tjbench-${libtype}-tile set_tests_properties(tjbench-${libtype}-tile
PROPERTIES DEPENDS tjbench-${libtype}-tile-cp) PROPERTIES DEPENDS tjbench-${libtype}-tile-cp)
foreach(tile 8 16 32 64 128) foreach(tile 8 16 32 64 128)
add_test(tjbench-${libtype}-tile-gray-${tile}x${tile}-cmp add_test(tjbench-${libtype}-tile-gray-${tile}x${tile}-cmp
${MD5CMP} ${MD5_PPM_GRAY_TILE} ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP} ${MD5_PPM_GRAY_TILE}
testout_tile_GRAY_Q95_${tile}x${tile}.ppm) testout_tile_GRAY_Q95_${tile}x${tile}.ppm)
foreach(subsamp 420 422) foreach(subsamp 420 422)
add_test(tjbench-${libtype}-tile-${subsamp}-${tile}x${tile}-cmp add_test(tjbench-${libtype}-tile-${subsamp}-${tile}x${tile}-cmp
${MD5CMP} ${MD5_PPM_${subsamp}_${tile}x${tile}_TILE} ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP}
${MD5_PPM_${subsamp}_${tile}x${tile}_TILE}
testout_tile_${subsamp}_Q95_${tile}x${tile}.ppm) testout_tile_${subsamp}_Q95_${tile}x${tile}.ppm)
endforeach() endforeach()
add_test(tjbench-${libtype}-tile-444-${tile}x${tile}-cmp add_test(tjbench-${libtype}-tile-444-${tile}x${tile}-cmp
${MD5CMP} ${MD5_PPM_444_TILE} ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP} ${MD5_PPM_444_TILE}
testout_tile_444_Q95_${tile}x${tile}.ppm) testout_tile_444_Q95_${tile}x${tile}.ppm)
foreach(subsamp gray 420 422 444) foreach(subsamp gray 420 422 444)
set_tests_properties(tjbench-${libtype}-tile-${subsamp}-${tile}x${tile}-cmp set_tests_properties(tjbench-${libtype}-tile-${subsamp}-${tile}x${tile}-cmp
@@ -980,19 +1002,22 @@ foreach(libtype ${TEST_LIBTYPES})
${CMAKE_COMMAND} -E copy_if_different ${TESTIMAGES}/testorig.ppm ${CMAKE_COMMAND} -E copy_if_different ${TESTIMAGES}/testorig.ppm
testout_tilem.ppm) testout_tilem.ppm)
add_test(tjbench-${libtype}-tilem add_test(tjbench-${libtype}-tilem
tjbench${suffix} testout_tilem.ppm 95 -rgb -fastupsample -quiet -tile ${CMAKE_CROSSCOMPILING_EMULATOR} tjbench${suffix} testout_tilem.ppm 95
-benchtime 0.01 -warmup 0) -rgb -fastupsample -quiet -tile -benchtime 0.01 -warmup 0)
set_tests_properties(tjbench-${libtype}-tilem set_tests_properties(tjbench-${libtype}-tilem
PROPERTIES DEPENDS tjbench-${libtype}-tilem-cp) PROPERTIES DEPENDS tjbench-${libtype}-tilem-cp)
add_test(tjbench-${libtype}-tile-420m-8x8-cmp add_test(tjbench-${libtype}-tile-420m-8x8-cmp
${MD5CMP} ${MD5_PPM_420M_8x8_TILE} testout_tilem_420_Q95_8x8.ppm) ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP} ${MD5_PPM_420M_8x8_TILE}
testout_tilem_420_Q95_8x8.ppm)
add_test(tjbench-${libtype}-tile-422m-8x8-cmp add_test(tjbench-${libtype}-tile-422m-8x8-cmp
${MD5CMP} ${MD5_PPM_422M_8x8_TILE} testout_tilem_422_Q95_8x8.ppm) ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP} ${MD5_PPM_422M_8x8_TILE}
testout_tilem_422_Q95_8x8.ppm)
foreach(tile 16 32 64 128) foreach(tile 16 32 64 128)
foreach(subsamp 420 422) foreach(subsamp 420 422)
add_test(tjbench-${libtype}-tile-${subsamp}m-${tile}x${tile}-cmp add_test(tjbench-${libtype}-tile-${subsamp}m-${tile}x${tile}-cmp
${MD5CMP} ${MD5_PPM_${subsamp}M_TILE} ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP}
${MD5_PPM_${subsamp}M_TILE}
testout_tilem_${subsamp}_Q95_${tile}x${tile}.ppm) testout_tilem_${subsamp}_Q95_${tile}x${tile}.ppm)
endforeach() endforeach()
endforeach() endforeach()
@@ -1010,9 +1035,10 @@ foreach(libtype ${TEST_LIBTYPES})
macro(add_bittest PROG NAME ARGS OUTFILE INFILE MD5SUM) macro(add_bittest PROG NAME ARGS OUTFILE INFILE MD5SUM)
add_test(${PROG}-${libtype}-${NAME} add_test(${PROG}-${libtype}-${NAME}
${PROG}${suffix} ${ARGS} -outfile ${OUTFILE} ${INFILE}) ${CMAKE_CROSSCOMPILING_EMULATOR} ${PROG}${suffix} ${ARGS}
-outfile ${OUTFILE} ${INFILE})
add_test(${PROG}-${libtype}-${NAME}-cmp add_test(${PROG}-${libtype}-${NAME}-cmp
${MD5CMP} ${MD5SUM} ${OUTFILE}) ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP} ${MD5SUM} ${OUTFILE})
set_tests_properties(${PROG}-${libtype}-${NAME}-cmp PROPERTIES set_tests_properties(${PROG}-${libtype}-${NAME}-cmp PROPERTIES
DEPENDS ${PROG}-${libtype}-${NAME}) DEPENDS ${PROG}-${libtype}-${NAME})
if(${ARGC} GREATER 6) if(${ARGC} GREATER 6)
@@ -1033,12 +1059,14 @@ foreach(libtype ${TEST_LIBTYPES})
${MD5_PPM_RGB_ISLOW} cjpeg-${libtype}-rgb-islow) ${MD5_PPM_RGB_ISLOW} cjpeg-${libtype}-rgb-islow)
add_test(djpeg-${libtype}-rgb-islow-icc-cmp add_test(djpeg-${libtype}-rgb-islow-icc-cmp
${MD5CMP} b06a39d730129122e85c1363ed1bbc9e testout_rgb_islow.icc) ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP}
b06a39d730129122e85c1363ed1bbc9e testout_rgb_islow.icc)
set_tests_properties(djpeg-${libtype}-rgb-islow-icc-cmp PROPERTIES set_tests_properties(djpeg-${libtype}-rgb-islow-icc-cmp PROPERTIES
DEPENDS djpeg-${libtype}-rgb-islow) DEPENDS djpeg-${libtype}-rgb-islow)
add_bittest(jpegtran icc "-copy;all;-icc;${TESTIMAGES}/test2.icc" add_bittest(jpegtran icc "-copy;all;-icc;${TESTIMAGES}/test2.icc"
testout_rgb_islow2.jpg testout_rgb_islow.jpg ${MD5_JPEG_RGB_ISLOW2}) testout_rgb_islow2.jpg testout_rgb_islow.jpg
${MD5_JPEG_RGB_ISLOW2} cjpeg-${libtype}-rgb-islow)
if(NOT WITH_12BIT) if(NOT WITH_12BIT)
# CC: RGB->RGB565 SAMP: fullsize IDCT: islow ENT: huff # CC: RGB->RGB565 SAMP: fullsize IDCT: islow ENT: huff
@@ -1251,7 +1279,7 @@ foreach(libtype ${TEST_LIBTYPES})
# Context rows: Yes Intra-iMCU row: No iMCU row prefetch: No ENT: prog huff # Context rows: Yes Intra-iMCU row: No iMCU row prefetch: No ENT: prog huff
add_test(cjpeg-${libtype}-420-islow-prog add_test(cjpeg-${libtype}-420-islow-prog
cjpeg${suffix} -dct int -prog ${CMAKE_CROSSCOMPILING_EMULATOR} cjpeg${suffix} -dct int -prog
-outfile testout_420_islow_prog.jpg ${TESTIMAGES}/testorig.ppm) -outfile testout_420_islow_prog.jpg ${TESTIMAGES}/testorig.ppm)
add_bittest(djpeg 420-islow-prog-crop62x62_71_71 add_bittest(djpeg 420-islow-prog-crop62x62_71_71
"-dct;int;-crop;62x62+71+71;-ppm" "-dct;int;-crop;62x62+71+71;-ppm"
@@ -1268,7 +1296,7 @@ foreach(libtype ${TEST_LIBTYPES})
# Context rows: No Intra-iMCU row: Yes ENT: huff # Context rows: No Intra-iMCU row: Yes ENT: huff
add_test(cjpeg-${libtype}-444-islow add_test(cjpeg-${libtype}-444-islow
cjpeg${suffix} -dct int -sample 1x1 ${CMAKE_CROSSCOMPILING_EMULATOR} cjpeg${suffix} -dct int -sample 1x1
-outfile testout_444_islow.jpg ${TESTIMAGES}/testorig.ppm) -outfile testout_444_islow.jpg ${TESTIMAGES}/testorig.ppm)
add_bittest(djpeg 444-islow-skip1_6 "-dct;int;-skip;1,6;-ppm" add_bittest(djpeg 444-islow-skip1_6 "-dct;int;-skip;1,6;-ppm"
testout_444_islow_skip1,6.ppm testout_444_islow.jpg testout_444_islow_skip1,6.ppm testout_444_islow.jpg
@@ -1276,7 +1304,7 @@ foreach(libtype ${TEST_LIBTYPES})
# Context rows: No Intra-iMCU row: No ENT: prog huff # Context rows: No Intra-iMCU row: No ENT: prog huff
add_test(cjpeg-${libtype}-444-islow-prog add_test(cjpeg-${libtype}-444-islow-prog
cjpeg${suffix} -dct int -prog -sample 1x1 ${CMAKE_CROSSCOMPILING_EMULATOR} cjpeg${suffix} -dct int -prog -sample 1x1
-outfile testout_444_islow_prog.jpg ${TESTIMAGES}/testorig.ppm) -outfile testout_444_islow_prog.jpg ${TESTIMAGES}/testorig.ppm)
add_bittest(djpeg 444-islow-prog-crop98x98_13_13 add_bittest(djpeg 444-islow-prog-crop98x98_13_13
"-dct;int;-crop;98x98+13+13;-ppm" "-dct;int;-crop;98x98+13+13;-ppm"
@@ -1286,8 +1314,9 @@ foreach(libtype ${TEST_LIBTYPES})
# Context rows: No Intra-iMCU row: No ENT: arith # Context rows: No Intra-iMCU row: No ENT: arith
if(WITH_ARITH_ENC) if(WITH_ARITH_ENC)
add_test(cjpeg-${libtype}-444-islow-ari add_test(cjpeg-${libtype}-444-islow-ari
cjpeg${suffix} -dct int -arithmetic -sample 1x1 ${CMAKE_CROSSCOMPILING_EMULATOR} cjpeg${suffix} -dct int -arithmetic
-outfile testout_444_islow_ari.jpg ${TESTIMAGES}/testorig.ppm) -sample 1x1 -outfile testout_444_islow_ari.jpg
${TESTIMAGES}/testorig.ppm)
if(WITH_ARITH_DEC) if(WITH_ARITH_DEC)
add_bittest(djpeg 444-islow-ari-crop37x37_0_0 add_bittest(djpeg 444-islow-ari-crop37x37_0_0
"-dct;int;-crop;37x37+0+0;-ppm" "-dct;int;-crop;37x37+0+0;-ppm"

View File

@@ -1,3 +1,33 @@
2.0.5
=====
### Significant changes relative to 2.0.4:
1. Worked around issues in the MIPS DSPr2 SIMD extensions that caused failures
in the libjpeg-turbo regression tests. Specifically, the
`jsimd_h2v1_downsample_dspr2()` and `jsimd_h2v2_downsample_dspr2()` functions
in the MIPS DSPr2 SIMD extensions are now disabled until/unless they can be
fixed, and other functions that are incompatible with big endian MIPS CPUs are
disabled when building libjpeg-turbo for such CPUs.
2. Fixed an oversight in the `TJCompressor.compress(int)` method in the
TurboJPEG Java API that caused an error ("java.lang.IllegalStateException: No
source image is associated with this instance") when attempting to use that
method to compress a YUV image.
3. Fixed an issue (CVE-2020-13790) in the PPM reader that caused a buffer
overrun in cjpeg, TJBench, or the `tjLoadImage()` function if one of the values
in a binary PPM/PGM input file exceeded the maximum value defined in the file's
header and that maximum value was less than 255. libjpeg-turbo 1.5.0 already
included a similar fix for binary PPM/PGM files with maximum values greater
than 255.
4. The TurboJPEG API library's global error handler, which is used in functions
such as `tjBufSize()` and `tjLoadImage()` that do not require a TurboJPEG
instance handle, is now thread-safe on platforms that support thread-local
storage.
2.0.4 2.0.4
===== =====
@@ -562,10 +592,10 @@ application was linked against.
3. Fixed a couple of issues in the PPM reader that would cause buffer overruns 3. Fixed a couple of issues in the PPM reader that would cause buffer overruns
in cjpeg if one of the values in a binary PPM/PGM input file exceeded the in cjpeg if one of the values in a binary PPM/PGM input file exceeded the
maximum value defined in the file's header. libjpeg-turbo 1.4.2 already maximum value defined in the file's header and that maximum value was greater
included a similar fix for ASCII PPM/PGM files. Note that these issues were than 255. libjpeg-turbo 1.4.2 already included a similar fix for ASCII PPM/PGM
not security bugs, since they were confined to the cjpeg program and did not files. Note that these issues were not security bugs, since they were confined
affect any of the libjpeg-turbo libraries. to the cjpeg program and did not affect any of the libjpeg-turbo libraries.
4. Fixed an issue whereby attempting to decompress a JPEG file with a corrupt 4. Fixed an issue whereby attempting to decompress a JPEG file with a corrupt
header using the `tjDecompressToYUV2()` function would cause the function to header using the `tjDecompressToYUV2()` function would cause the function to

View File

@@ -2129,7 +2129,7 @@ If you choose option 1, <code>*jpegSize</code> should be set to the size of your
<p>Returns a descriptive error message explaining why the last command failed. </p> <p>Returns a descriptive error message explaining why the last command failed. </p>
<dl class="params"><dt>Parameters</dt><dd> <dl class="params"><dt>Parameters</dt><dd>
<table class="params"> <table class="params">
<tr><td class="paramname">handle</td><td>a handle to a TurboJPEG compressor, decompressor, or transformer instance, or NULL if the error was generated by a global function (but note that retrieving the error message for a global function is not thread-safe.)</td></tr> <tr><td class="paramname">handle</td><td>a handle to a TurboJPEG compressor, decompressor, or transformer instance, or NULL if the error was generated by a global function (but note that retrieving the error message for a global function is thread-safe only on platforms that support thread-local storage.)</td></tr>
</table> </table>
</dd> </dd>
</dl> </dl>

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C)2011-2015, 2018 D. R. Commander. All Rights Reserved. * Copyright (C)2011-2015, 2018, 2020 D. R. Commander. All Rights Reserved.
* Copyright (C)2015 Viktor Szathmáry. All Rights Reserved. * Copyright (C)2015 Viktor Szathmáry. All Rights Reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -377,8 +377,15 @@ public class TJCompressor implements Closeable {
* #getCompressedSize} to obtain the size of the JPEG image. * #getCompressedSize} to obtain the size of the JPEG image.
*/ */
public byte[] compress(int flags) throws TJException { public byte[] compress(int flags) throws TJException {
checkSourceImage(); byte[] buf;
byte[] buf = new byte[TJ.bufSize(srcWidth, srcHeight, subsamp)]; if (srcYUVImage != null) {
buf = new byte[TJ.bufSize(srcYUVImage.getWidth(),
srcYUVImage.getHeight(),
srcYUVImage.getSubsamp())];
} else {
checkSourceImage();
buf = new byte[TJ.bufSize(srcWidth, srcHeight, subsamp)];
}
compress(buf, flags); compress(buf, flags);
return buf; return buf;
} }

View File

@@ -7,6 +7,9 @@
/* How to obtain function inlining. */ /* How to obtain function inlining. */
#define INLINE @INLINE@ #define INLINE @INLINE@
/* How to obtain thread-local storage */
#define THREAD_LOCAL @THREAD_LOCAL@
/* Define to the full name of this package. */ /* Define to the full name of this package. */
#define PACKAGE_NAME "@CMAKE_PROJECT_NAME@" #define PACKAGE_NAME "@CMAKE_PROJECT_NAME@"

View File

@@ -51,7 +51,7 @@ boolean memsrc = FALSE; /* for -memsrc switch */
LOCAL(void) LOCAL(void)
usage (void) usage(void)
/* complain about bad command line */ /* complain about bad command line */
{ {
fprintf(stderr, "usage: %s [switches] ", progname); fprintf(stderr, "usage: %s [switches] ", progname);
@@ -105,7 +105,7 @@ usage (void)
LOCAL(void) LOCAL(void)
select_transform (JXFORM_CODE transform) select_transform(JXFORM_CODE transform)
/* Silly little routine to detect multiple transform options, /* Silly little routine to detect multiple transform options,
* which we can't handle. * which we can't handle.
*/ */
@@ -128,7 +128,7 @@ select_transform (JXFORM_CODE transform)
LOCAL(int) LOCAL(int)
parse_switches (j_compress_ptr cinfo, int argc, char **argv, parse_switches(j_compress_ptr cinfo, int argc, char **argv,
int last_file_arg_seen, boolean for_real) int last_file_arg_seen, boolean for_real)
/* Parse optional switches. /* Parse optional switches.
* Returns argv[] index of first file-name argument (== argc if none). * Returns argv[] index of first file-name argument (== argc if none).
@@ -208,7 +208,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
#if TRANSFORMS_SUPPORTED #if TRANSFORMS_SUPPORTED
if (++argn >= argc) /* advance to next argument */ if (++argn >= argc) /* advance to next argument */
usage(); usage();
if (! jtransform_parse_crop_spec(&transformoption, argv[argn])) { if (!jtransform_parse_crop_spec(&transformoption, argv[argn])) {
fprintf(stderr, "%s: bogus -crop argument '%s'\n", fprintf(stderr, "%s: bogus -crop argument '%s'\n",
progname, argv[argn]); progname, argv[argn]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@@ -223,7 +223,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
/* On first -d, print version identification */ /* On first -d, print version identification */
static boolean printed_version = FALSE; static boolean printed_version = FALSE;
if (! printed_version) { if (!printed_version) {
fprintf(stderr, "%s version %s (build %s)\n", fprintf(stderr, "%s version %s (build %s)\n",
PACKAGE_NAME, VERSION, BUILD); PACKAGE_NAME, VERSION, BUILD);
fprintf(stderr, "%s\n\n", JCOPYRIGHT); fprintf(stderr, "%s\n\n", JCOPYRIGHT);
@@ -327,10 +327,10 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
if (lval < 0 || lval > 65535L) if (lval < 0 || lval > 65535L)
usage(); usage();
if (ch == 'b' || ch == 'B') { if (ch == 'b' || ch == 'B') {
cinfo->restart_interval = (unsigned int) lval; cinfo->restart_interval = (unsigned int)lval;
cinfo->restart_in_rows = 0; /* else prior '-restart n' overrides me */ cinfo->restart_in_rows = 0; /* else prior '-restart n' overrides me */
} else { } else {
cinfo->restart_in_rows = (int) lval; cinfo->restart_in_rows = (int)lval;
/* restart_interval will be computed during startup */ /* restart_interval will be computed during startup */
} }
@@ -399,7 +399,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
#ifdef C_MULTISCAN_FILES_SUPPORTED #ifdef C_MULTISCAN_FILES_SUPPORTED
if (scansarg != NULL) /* process -scans if it was present */ if (scansarg != NULL) /* process -scans if it was present */
if (! read_scan_script(cinfo, scansarg)) if (!read_scan_script(cinfo, scansarg))
usage(); usage();
#endif #endif
@@ -414,7 +414,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
*/ */
int int
main (int argc, char **argv) main(int argc, char **argv)
{ {
struct jpeg_decompress_struct srcinfo; struct jpeg_decompress_struct srcinfo;
struct jpeg_compress_struct dstinfo; struct jpeg_compress_struct dstinfo;
@@ -468,14 +468,14 @@ main (int argc, char **argv)
#ifdef TWO_FILE_COMMANDLINE #ifdef TWO_FILE_COMMANDLINE
/* Must have either -outfile switch or explicit output file name */ /* Must have either -outfile switch or explicit output file name */
if (outfilename == NULL) { if (outfilename == NULL) {
if (file_index != argc-2) { if (file_index != argc - 2) {
fprintf(stderr, "%s: must name one input and one output file\n", fprintf(stderr, "%s: must name one input and one output file\n",
progname); progname);
usage(); usage();
} }
outfilename = argv[file_index+1]; outfilename = argv[file_index + 1];
} else { } else {
if (file_index != argc-1) { if (file_index != argc - 1) {
fprintf(stderr, "%s: must name one input and one output file\n", fprintf(stderr, "%s: must name one input and one output file\n",
progname); progname);
usage(); usage();
@@ -483,7 +483,7 @@ main (int argc, char **argv)
} }
#else #else
/* Unix style: expect zero or one file name */ /* Unix style: expect zero or one file name */
if (file_index < argc-1) { if (file_index < argc - 1) {
fprintf(stderr, "%s: only one input file\n", progname); fprintf(stderr, "%s: only one input file\n", progname);
usage(); usage();
} }
@@ -531,7 +531,7 @@ main (int argc, char **argv)
} }
#ifdef PROGRESS_REPORT #ifdef PROGRESS_REPORT
start_progress_monitor((j_common_ptr) &dstinfo, &progress); start_progress_monitor((j_common_ptr)&dstinfo, &progress);
#endif #endif
/* Specify data source for decompression */ /* Specify data source for decompression */
@@ -567,7 +567,7 @@ main (int argc, char **argv)
jcopy_markers_setup(&srcinfo, copyoption); jcopy_markers_setup(&srcinfo, copyoption);
/* Read file header */ /* Read file header */
(void) jpeg_read_header(&srcinfo, TRUE); (void)jpeg_read_header(&srcinfo, TRUE);
/* Any space needed by a transform option must be requested before /* Any space needed by a transform option must be requested before
* jpeg_read_coefficients so that memory allocation will be done right. * jpeg_read_coefficients so that memory allocation will be done right.
@@ -601,7 +601,7 @@ main (int argc, char **argv)
/* Close input file, if we opened it. /* Close input file, if we opened it.
* Note: we assume that jpeg_read_coefficients consumed all input * Note: we assume that jpeg_read_coefficients consumed all input
* until JPEG_REACHED_EOI, and that jpeg_finish_decompress will * until JPEG_REACHED_EOI, and that jpeg_finish_decompress will
* only consume more while (! cinfo->inputctl->eoi_reached). * only consume more while (!cinfo->inputctl->eoi_reached).
* We cannot call jpeg_finish_decompress here since we still need the * We cannot call jpeg_finish_decompress here since we still need the
* virtual arrays allocated from the source object for processing. * virtual arrays allocated from the source object for processing.
*/ */
@@ -676,7 +676,7 @@ main (int argc, char **argv)
#endif #endif
jpeg_destroy_compress(&dstinfo); jpeg_destroy_compress(&dstinfo);
(void) jpeg_finish_decompress(&srcinfo); (void)jpeg_finish_decompress(&srcinfo);
jpeg_destroy_decompress(&srcinfo); jpeg_destroy_decompress(&srcinfo);
/* Close output file, if we opened it */ /* Close output file, if we opened it */
@@ -684,14 +684,13 @@ main (int argc, char **argv)
fclose(fp); fclose(fp);
#ifdef PROGRESS_REPORT #ifdef PROGRESS_REPORT
end_progress_monitor((j_common_ptr) &dstinfo); end_progress_monitor((j_common_ptr)&dstinfo);
#endif #endif
free(inbuffer); free(inbuffer);
free(outbuffer); free(outbuffer);
if (icc_profile != NULL) free(icc_profile);
free(icc_profile);
/* All done. */ /* All done. */
exit(jsrcerr.num_warnings + jdsterr.num_warnings ? exit(jsrcerr.num_warnings + jdsterr.num_warnings ?

View File

@@ -5,7 +5,7 @@
* Copyright (C) 1991-1997, Thomas G. Lane. * Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2009 by Bill Allombert, Guido Vollbeding. * Modified 2009 by Bill Allombert, Guido Vollbeding.
* libjpeg-turbo Modifications: * libjpeg-turbo Modifications:
* Copyright (C) 2015-2017, D. R. Commander. * Copyright (C) 2015-2017, 2020, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg * For conditions of distribution and use, see the accompanying README.ijg
* file. * file.
* *
@@ -720,7 +720,7 @@ start_input_ppm(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* On 16-bit-int machines we have to be careful of maxval = 65535 */ /* On 16-bit-int machines we have to be careful of maxval = 65535 */
source->rescale = (JSAMPLE *) source->rescale = (JSAMPLE *)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
(size_t)(((long)maxval + 1L) * (size_t)(((long)MAX(maxval, 255) + 1L) *
sizeof(JSAMPLE))); sizeof(JSAMPLE)));
half_maxval = maxval / 2; half_maxval = maxval / 2;
for (val = 0; val <= (long)maxval; val++) { for (val = 0; val <= (long)maxval; val++) {

View File

@@ -541,8 +541,8 @@ set_quality_ratings (j_compress_ptr cinfo, char *arg, boolean force_baseline)
#else #else
q_scale_factor[tblno] = jpeg_float_quality_scaling(val); q_scale_factor[tblno] = jpeg_float_quality_scaling(val);
#endif #endif
while (*arg && *arg++ != ',') /* advance to next segment of arg string */ while (*arg && *arg++ != ','); /* advance to next segment of arg
; string */
} else { } else {
/* reached end of parameter, set remaining factors to last value */ /* reached end of parameter, set remaining factors to last value */
#if JPEG_LIB_VERSION >= 70 #if JPEG_LIB_VERSION >= 70
@@ -592,8 +592,8 @@ set_quant_slots (j_compress_ptr cinfo, char *arg)
return FALSE; return FALSE;
} }
cinfo->comp_info[ci].quant_tbl_no = val; cinfo->comp_info[ci].quant_tbl_no = val;
while (*arg && *arg++ != ',') /* advance to next segment of arg string */ while (*arg && *arg++ != ','); /* advance to next segment of arg
; string */
} else { } else {
/* reached end of parameter, set remaining components to last table */ /* reached end of parameter, set remaining components to last table */
cinfo->comp_info[ci].quant_tbl_no = val; cinfo->comp_info[ci].quant_tbl_no = val;
@@ -626,8 +626,8 @@ set_sample_factors (j_compress_ptr cinfo, char *arg)
} }
cinfo->comp_info[ci].h_samp_factor = val1; cinfo->comp_info[ci].h_samp_factor = val1;
cinfo->comp_info[ci].v_samp_factor = val2; cinfo->comp_info[ci].v_samp_factor = val2;
while (*arg && *arg++ != ',') /* advance to next segment of arg string */ while (*arg && *arg++ != ','); /* advance to next segment of arg
; string */
} else { } else {
/* reached end of parameter, set remaining components to 1x1 sampling */ /* reached end of parameter, set remaining components to 1x1 sampling */
cinfo->comp_info[ci].h_samp_factor = 1; cinfo->comp_info[ci].h_samp_factor = 1;

View File

@@ -2,7 +2,7 @@
* jsimd_mips.c * jsimd_mips.c
* *
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2009-2011, 2014, 2016, 2018, D. R. Commander. * Copyright (C) 2009-2011, 2014, 2016, 2018, 2020, D. R. Commander.
* Copyright (C) 2013-2014, MIPS Technologies, Inc., California. * Copyright (C) 2013-2014, MIPS Technologies, Inc., California.
* Copyright (C) 2015-2016, 2018, Matthieu Darbois. * Copyright (C) 2015-2016, 2018, Matthieu Darbois.
* *
@@ -29,9 +29,9 @@
static unsigned int simd_support = ~0; static unsigned int simd_support = ~0;
#if defined(__linux__) #if !(defined(__mips_dsp) && (__mips_dsp_rev >= 2)) && defined(__linux__)
LOCAL(int) LOCAL(void)
parse_proc_cpuinfo(const char *search_string) parse_proc_cpuinfo(const char *search_string)
{ {
const char *file_name = "/proc/cpuinfo"; const char *file_name = "/proc/cpuinfo";
@@ -45,13 +45,12 @@ parse_proc_cpuinfo(const char *search_string)
if (strstr(cpuinfo_line, search_string) != NULL) { if (strstr(cpuinfo_line, search_string) != NULL) {
fclose(f); fclose(f);
simd_support |= JSIMD_DSPR2; simd_support |= JSIMD_DSPR2;
return 1; return;
} }
} }
fclose(f); fclose(f);
} }
/* Did not find string in the proc file, or not Linux ELF. */ /* Did not find string in the proc file, or not Linux ELF. */
return 0;
} }
#endif #endif
@@ -73,14 +72,13 @@ init_simd(void)
simd_support = 0; simd_support = 0;
#if defined(__MIPSEL__) && defined(__mips_dsp) && (__mips_dsp_rev >= 2) #if defined(__mips_dsp) && (__mips_dsp_rev >= 2)
simd_support |= JSIMD_DSPR2; simd_support |= JSIMD_DSPR2;
#elif defined(__linux__) #elif defined(__linux__)
/* We still have a chance to use MIPS DSPR2 regardless of globally used /* We still have a chance to use MIPS DSPR2 regardless of globally used
* -mdspr2 options passed to gcc by performing runtime detection via * -mdspr2 options passed to gcc by performing runtime detection via
* /proc/cpuinfo parsing on linux */ * /proc/cpuinfo parsing on linux */
if (!parse_proc_cpuinfo("MIPS 74K")) parse_proc_cpuinfo("MIPS 74K");
return;
#endif #endif
#ifndef NO_GETENV #ifndef NO_GETENV
@@ -340,8 +338,13 @@ jsimd_can_h2v2_downsample(void)
if (sizeof(JDIMENSION) != 4) if (sizeof(JDIMENSION) != 4)
return 0; return 0;
/* FIXME: jsimd_h2v2_downsample_dspr2() fails some of the TJBench tiling
* regression tests, probably because the DSPr2 SIMD implementation predates
* those tests. */
#if 0
if (simd_support & JSIMD_DSPR2) if (simd_support & JSIMD_DSPR2)
return 1; return 1;
#endif
return 0; return 0;
} }
@@ -376,8 +379,13 @@ jsimd_can_h2v1_downsample(void)
if (sizeof(JDIMENSION) != 4) if (sizeof(JDIMENSION) != 4)
return 0; return 0;
/* FIXME: jsimd_h2v1_downsample_dspr2() fails some of the TJBench tiling
* regression tests, probably because the DSPr2 SIMD implementation predates
* those tests. */
#if 0
if (simd_support & JSIMD_DSPR2) if (simd_support & JSIMD_DSPR2)
return 1; return 1;
#endif
return 0; return 0;
} }
@@ -441,8 +449,10 @@ jsimd_can_h2v1_upsample(void)
if (sizeof(JDIMENSION) != 4) if (sizeof(JDIMENSION) != 4)
return 0; return 0;
#if defined(__MIPSEL__)
if (simd_support & JSIMD_DSPR2) if (simd_support & JSIMD_DSPR2)
return 1; return 1;
#endif
return 0; return 0;
} }
@@ -503,8 +513,10 @@ jsimd_can_h2v2_fancy_upsample(void)
if (sizeof(JDIMENSION) != 4) if (sizeof(JDIMENSION) != 4)
return 0; return 0;
#if defined(__MIPSEL__)
if (simd_support & JSIMD_DSPR2) if (simd_support & JSIMD_DSPR2)
return 1; return 1;
#endif
return 0; return 0;
} }
@@ -520,8 +532,10 @@ jsimd_can_h2v1_fancy_upsample(void)
if (sizeof(JDIMENSION) != 4) if (sizeof(JDIMENSION) != 4)
return 0; return 0;
#if defined(__MIPSEL__)
if (simd_support & JSIMD_DSPR2) if (simd_support & JSIMD_DSPR2)
return 1; return 1;
#endif
return 0; return 0;
} }
@@ -669,8 +683,10 @@ jsimd_can_convsamp(void)
if (sizeof(DCTELEM) != 2) if (sizeof(DCTELEM) != 2)
return 0; return 0;
#if defined(__MIPSEL__)
if (simd_support & JSIMD_DSPR2) if (simd_support & JSIMD_DSPR2)
return 1; return 1;
#endif
return 0; return 0;
} }
@@ -727,8 +743,10 @@ jsimd_can_fdct_islow(void)
if (sizeof(DCTELEM) != 2) if (sizeof(DCTELEM) != 2)
return 0; return 0;
#if defined(__MIPSEL__)
if (simd_support & JSIMD_DSPR2) if (simd_support & JSIMD_DSPR2)
return 1; return 1;
#endif
return 0; return 0;
} }
@@ -744,8 +762,10 @@ jsimd_can_fdct_ifast(void)
if (sizeof(DCTELEM) != 2) if (sizeof(DCTELEM) != 2)
return 0; return 0;
#if defined(__MIPSEL__)
if (simd_support & JSIMD_DSPR2) if (simd_support & JSIMD_DSPR2)
return 1; return 1;
#endif
return 0; return 0;
} }
@@ -872,8 +892,10 @@ jsimd_can_idct_4x4(void)
if (sizeof(ISLOW_MULT_TYPE) != 2) if (sizeof(ISLOW_MULT_TYPE) != 2)
return 0; return 0;
#if defined(__MIPSEL__)
if (simd_support & JSIMD_DSPR2) if (simd_support & JSIMD_DSPR2)
return 1; return 1;
#endif
return 0; return 0;
} }
@@ -1017,8 +1039,10 @@ jsimd_can_idct_ifast(void)
if (IFAST_SCALE_BITS != 2) if (IFAST_SCALE_BITS != 2)
return 0; return 0;
#if defined(__MIPSEL__)
if (simd_support & JSIMD_DSPR2) if (simd_support & JSIMD_DSPR2)
return 1; return 1;
#endif
return 0; return 0;
} }

View File

@@ -1,5 +1,7 @@
/* /*
* Copyright (C)2009-2019 D. R. Commander. All Rights Reserved. * Copyright (C)2009-2020 D. R. Commander. All Rights Reserved.
* mozjpeg Modifications:
* Copyright (C) 2014, Mozilla Corporation.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
@@ -43,6 +45,7 @@
#include "transupp.h" #include "transupp.h"
#include "./jpegcomp.h" #include "./jpegcomp.h"
#include "./cdjpeg.h" #include "./cdjpeg.h"
#include "jconfigint.h"
extern void jpeg_mem_dest_tj(j_compress_ptr, unsigned char **, unsigned long *, extern void jpeg_mem_dest_tj(j_compress_ptr, unsigned char **, unsigned long *,
boolean); boolean);
@@ -55,7 +58,7 @@ extern void jpeg_mem_src_tj(j_decompress_ptr, const unsigned char *,
/* Error handling (based on example in example.txt) */ /* Error handling (based on example in example.txt) */
static char errStr[JMSG_LENGTH_MAX] = "No error"; static THREAD_LOCAL char errStr[JMSG_LENGTH_MAX] = "No error";
struct my_error_mgr { struct my_error_mgr {
struct jpeg_error_mgr pub; struct jpeg_error_mgr pub;
@@ -243,6 +246,8 @@ static int setCompDefaults(struct jpeg_compress_struct *cinfo, int pixelFormat,
cinfo->in_color_space = pf2cs[pixelFormat]; cinfo->in_color_space = pf2cs[pixelFormat];
cinfo->input_components = tjPixelSize[pixelFormat]; cinfo->input_components = tjPixelSize[pixelFormat];
if((env=getenv("TJ_REVERT"))!=NULL && strlen(env)>0 && !strcmp(env, "1"))
cinfo->master->compress_profile=JCP_FASTEST;
jpeg_set_defaults(cinfo); jpeg_set_defaults(cinfo);
#ifndef NO_GETENV #ifndef NO_GETENV
@@ -289,6 +294,10 @@ static int setCompDefaults(struct jpeg_compress_struct *cinfo, int pixelFormat,
jpeg_simple_progression(cinfo); jpeg_simple_progression(cinfo);
#endif #endif
/* Set scan pattern again as colorspace might have changed */
if(cinfo->master->compress_profile == JCP_MAX_COMPRESSION)
jpeg_simple_progression(cinfo);
cinfo->comp_info[0].h_samp_factor = tjMCUWidth[subsamp] / 8; cinfo->comp_info[0].h_samp_factor = tjMCUWidth[subsamp] / 8;
cinfo->comp_info[1].h_samp_factor = 1; cinfo->comp_info[1].h_samp_factor = 1;
cinfo->comp_info[2].h_samp_factor = 1; cinfo->comp_info[2].h_samp_factor = 1;

View File

@@ -1650,7 +1650,7 @@ DLLEXPORT void tjFree(unsigned char *buffer);
* @param handle a handle to a TurboJPEG compressor, decompressor, or * @param handle a handle to a TurboJPEG compressor, decompressor, or
* transformer instance, or NULL if the error was generated by a global * transformer instance, or NULL if the error was generated by a global
* function (but note that retrieving the error message for a global function * function (but note that retrieving the error message for a global function
* is not thread-safe.) * is thread-safe only on platforms that support thread-local storage.)
* *
* @return a descriptive error message explaining why the last command failed. * @return a descriptive error message explaining why the last command failed.
*/ */