diff options
Diffstat (limited to 'src/plugins/imageformats/jpeg/qjpeghandler.cpp')
-rw-r--r-- | src/plugins/imageformats/jpeg/qjpeghandler.cpp | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp index 1f1675e490..c31e2db3c5 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp +++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp @@ -248,13 +248,12 @@ static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info, static bool read_jpeg_image(QImage *outImage, QSize scaledSize, QRect scaledClipRect, - QRect clipRect, volatile int inQuality, + QRect clipRect, int quality, Rgb888ToRgb32Converter converter, j_decompress_ptr info, struct my_error_mgr* err ) { if (!setjmp(err->setjmp_buffer)) { // -1 means default quality. - int quality = inQuality; if (quality < 0) quality = 75; @@ -529,7 +528,14 @@ static inline void write_icc_profile(const QImage &image, j_compress_ptr cinfo) } } -static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile int sourceQuality, const QString &description, bool optimize, bool progressive) +static bool do_write_jpeg_image(struct jpeg_compress_struct &cinfo, + JSAMPROW *row_pointer, + const QImage &image, + QIODevice *device, + int sourceQuality, + const QString &description, + bool optimize, + bool progressive) { bool success = false; const QVector<QRgb> cmap = image.colorTable(); @@ -537,10 +543,6 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile in if (image.format() == QImage::Format_Invalid || image.format() == QImage::Format_Alpha8) return false; - struct jpeg_compress_struct cinfo; - JSAMPROW row_pointer[1]; - row_pointer[0] = 0; - struct my_jpeg_destination_mgr *iod_dest = new my_jpeg_destination_mgr(device); struct my_error_mgr jerr; @@ -713,6 +715,27 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile in } delete iod_dest; + return success; +} + +static bool write_jpeg_image(const QImage &image, + QIODevice *device, + int sourceQuality, + const QString &description, + bool optimize, + bool progressive) +{ + // protect these objects from the setjmp/longjmp pair inside + // do_write_jpeg_image (by making them non-local). + struct jpeg_compress_struct cinfo; + JSAMPROW row_pointer[1]; + row_pointer[0] = nullptr; + + const bool success = do_write_jpeg_image(cinfo, row_pointer, + image, device, + sourceQuality, description, + optimize, progressive); + delete [] row_pointer[0]; return success; } @@ -728,7 +751,7 @@ public: }; QJpegHandlerPrivate(QJpegHandler *qq) - : quality(75), transformation(QImageIOHandler::TransformationNone), iod_src(0), + : quality(75), transformation(QImageIOHandler::TransformationNone), iod_src(nullptr), rgb888ToRgb32ConverterPtr(qt_convert_rgb888_to_rgb32), state(Ready), optimize(false), progressive(false), q(qq) {} @@ -738,7 +761,7 @@ public: { jpeg_destroy_decompress(&info); delete iod_src; - iod_src = 0; + iod_src = nullptr; } } @@ -931,7 +954,7 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device) QByteArray exifData; - for (jpeg_saved_marker_ptr marker = info.marker_list; marker != NULL; marker = marker->next) { + for (jpeg_saved_marker_ptr marker = info.marker_list; marker != nullptr; marker = marker->next) { if (marker->marker == JPEG_COM) { QString key, value; QString s = QString::fromUtf8((const char *)marker->data, marker->data_length); |