[Scummvm-git-logs] scummvm master -> 96d411445fbc681a6573169c388609a53b37aeb4
lephilousophe
noreply at scummvm.org
Sat Nov 1 11:46:55 UTC 2025
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
96d411445f IMAGE: Gracefully handle JPEG decompression failures
Commit: 96d411445fbc681a6573169c388609a53b37aeb4
https://github.com/scummvm/scummvm/commit/96d411445fbc681a6573169c388609a53b37aeb4
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2025-11-01T12:46:51+01:00
Commit Message:
IMAGE: Gracefully handle JPEG decompression failures
This can happen when the JPEG file is corrupted but also when compiling
against libjpeg-turbo and running using original libjpeg shared object.
In this case a fallback is attempted on the supported everywhere JCS_RGB
format.
Changed paths:
image/jpeg.cpp
diff --git a/image/jpeg.cpp b/image/jpeg.cpp
index eaf4f4f9c60..617d4d434bc 100644
--- a/image/jpeg.cpp
+++ b/image/jpeg.cpp
@@ -40,6 +40,8 @@ extern "C" {
#include <jpeglib.h>
#include <jerror.h>
}
+
+#include <setjmp.h>
#endif
namespace Image {
@@ -170,9 +172,24 @@ void jpeg_scummvm_src(j_decompress_ptr cinfo, Common::SeekableReadStream *stream
source->stream = stream;
}
+struct jpeg_error_mgr_ext : public jpeg_error_mgr {
+ jmp_buf jmp;
+ bool jmp_valid;
+};
+
void errorExit(j_common_ptr cinfo) {
+ jpeg_error_mgr_ext *err = (jpeg_error_mgr_ext *)cinfo->err;
+
char buffer[JMSG_LENGTH_MAX];
(*cinfo->err->format_message)(cinfo, buffer);
+
+ if (err->jmp_valid) {
+ /* We will jump back to the loading stream function
+ * but, before, warn the user */
+ warning("libjpeg: %s", buffer);
+ longjmp(err->jmp, 1);
+ }
+
// This function is not allowed to return to the caller, thus we simply
// error out with our error handling here.
error("libjpeg: %s", buffer);
@@ -232,7 +249,8 @@ bool JPEGDecoder::loadStream(Common::SeekableReadStream &stream) {
destroy();
jpeg_decompress_struct cinfo;
- jpeg_error_mgr jerr;
+ jpeg_error_mgr_ext jerr;
+ jerr.jmp_valid = false;
// Initialize error handling callbacks
cinfo.err = jpeg_std_error(&jerr);
@@ -250,6 +268,13 @@ bool JPEGDecoder::loadStream(Common::SeekableReadStream &stream) {
// Initialize our buffer handling
jpeg_scummvm_src(&cinfo, &stream);
+ if (setjmp(jerr.jmp)) {
+ /* File is invalid */
+ jpeg_destroy_decompress(&cinfo);
+ return false;
+ }
+ jerr.jmp_valid = true;
+
// Read the file header
jpeg_read_header(&cinfo, TRUE);
@@ -283,9 +308,29 @@ bool JPEGDecoder::loadStream(Common::SeekableReadStream &stream) {
cinfo.out_color_space = JCS_CMYK;
}
+ if (setjmp(jerr.jmp)) {
+ /* Output color space seems invalid
+ * Try again with the most basic one */
+ if (_colorSpace == kColorSpaceRGB && cinfo.num_components == 3) {
+ warning("Falling back to RGB slow path");
+ cinfo.out_color_space = JCS_RGB;
+ }
+ if (setjmp(jerr.jmp)) {
+ /* There is something definitely wrong here */
+ jpeg_destroy_decompress(&cinfo);
+ return false;
+ }
+ }
+
// Actually start decompressing the image
jpeg_start_decompress(&cinfo);
+ if (setjmp(jerr.jmp)) {
+ /* Something went wrong */
+ jpeg_destroy_decompress(&cinfo);
+ return false;
+ }
+
// Allocate buffers for the output data
switch (_colorSpace) {
case kColorSpaceRGB: {
More information about the Scummvm-git-logs
mailing list