summaryrefslogtreecommitdiffstats
path: root/src/plugins/imageformats/jpeg
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/imageformats/jpeg')
-rw-r--r--src/plugins/imageformats/jpeg/.prev_CMakeLists.txt94
-rw-r--r--src/plugins/imageformats/jpeg/CMakeLists.txt99
-rw-r--r--src/plugins/imageformats/jpeg/jpeg.pro18
-rw-r--r--src/plugins/imageformats/jpeg/main.cpp54
-rw-r--r--src/plugins/imageformats/jpeg/main.h58
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler.cpp202
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler_p.h40
7 files changed, 151 insertions, 414 deletions
diff --git a/src/plugins/imageformats/jpeg/.prev_CMakeLists.txt b/src/plugins/imageformats/jpeg/.prev_CMakeLists.txt
deleted file mode 100644
index 95b3aceff5..0000000000
--- a/src/plugins/imageformats/jpeg/.prev_CMakeLists.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-# Generated from jpeg.pro.
-
-#####################################################################
-## QJpegPlugin Plugin:
-#####################################################################
-
-qt_internal_add_plugin(QJpegPlugin
- OUTPUT_NAME qjpeg
- TYPE imageformats
- SOURCES
- main.cpp main.h
- qjpeghandler.cpp qjpeghandler_p.h
- PUBLIC_LIBRARIES
- Qt::Core
- Qt::CorePrivate
- Qt::Gui
- Qt::GuiPrivate
-)
-
-#### Keys ignored in scope 1:.:.:jpeg.pro:<TRUE>:
-# OTHER_FILES = "jpeg.json"
-
-## Scopes:
-#####################################################################
-
-qt_extend_target(QJpegPlugin CONDITION QT_FEATURE_system_jpeg
- PUBLIC_LIBRARIES
- JPEG::JPEG
-)
-
-qt_extend_target(QJpegPlugin CONDITION NOT QT_FEATURE_system_jpeg
- SOURCES
- ../../../3rdparty/libjpeg/src/jaricom.c
- ../../../3rdparty/libjpeg/src/jcapimin.c
- ../../../3rdparty/libjpeg/src/jcapistd.c
- ../../../3rdparty/libjpeg/src/jcarith.c
- ../../../3rdparty/libjpeg/src/jccoefct.c
- ../../../3rdparty/libjpeg/src/jccolor.c
- ../../../3rdparty/libjpeg/src/jcdctmgr.c
- ../../../3rdparty/libjpeg/src/jchuff.c
- ../../../3rdparty/libjpeg/src/jcinit.c
- ../../../3rdparty/libjpeg/src/jcmainct.c
- ../../../3rdparty/libjpeg/src/jcmarker.c
- ../../../3rdparty/libjpeg/src/jcmaster.c
- ../../../3rdparty/libjpeg/src/jcomapi.c
- ../../../3rdparty/libjpeg/src/jcparam.c
- ../../../3rdparty/libjpeg/src/jcphuff.c
- ../../../3rdparty/libjpeg/src/jcprepct.c
- ../../../3rdparty/libjpeg/src/jcsample.c
- ../../../3rdparty/libjpeg/src/jctrans.c
- ../../../3rdparty/libjpeg/src/jdapimin.c
- ../../../3rdparty/libjpeg/src/jdapistd.c
- ../../../3rdparty/libjpeg/src/jdarith.c
- ../../../3rdparty/libjpeg/src/jdatadst.c
- ../../../3rdparty/libjpeg/src/jdatasrc.c
- ../../../3rdparty/libjpeg/src/jdcoefct.c
- ../../../3rdparty/libjpeg/src/jdcolor.c
- ../../../3rdparty/libjpeg/src/jddctmgr.c
- ../../../3rdparty/libjpeg/src/jdhuff.c
- ../../../3rdparty/libjpeg/src/jdinput.c
- ../../../3rdparty/libjpeg/src/jdmainct.c
- ../../../3rdparty/libjpeg/src/jdmarker.c
- ../../../3rdparty/libjpeg/src/jdmaster.c
- ../../../3rdparty/libjpeg/src/jdmerge.c
- ../../../3rdparty/libjpeg/src/jdphuff.c
- ../../../3rdparty/libjpeg/src/jdpostct.c
- ../../../3rdparty/libjpeg/src/jdsample.c
- ../../../3rdparty/libjpeg/src/jdtrans.c
- ../../../3rdparty/libjpeg/src/jerror.c
- ../../../3rdparty/libjpeg/src/jfdctflt.c
- ../../../3rdparty/libjpeg/src/jfdctfst.c
- ../../../3rdparty/libjpeg/src/jfdctint.c
- ../../../3rdparty/libjpeg/src/jidctflt.c
- ../../../3rdparty/libjpeg/src/jidctfst.c
- ../../../3rdparty/libjpeg/src/jidctint.c
- ../../../3rdparty/libjpeg/src/jidctred.c
- ../../../3rdparty/libjpeg/src/jmemmgr.c
- ../../../3rdparty/libjpeg/src/jmemnobs.c
- ../../../3rdparty/libjpeg/src/jquant1.c
- ../../../3rdparty/libjpeg/src/jquant2.c
- ../../../3rdparty/libjpeg/src/jsimd_none.c
- ../../../3rdparty/libjpeg/src/jutils.c
- INCLUDE_DIRECTORIES
- ../../../3rdparty/libjpeg
- ../../../3rdparty/libjpeg/src
-)
-
-#### Keys ignored in scope 5:.:../../../3rdparty:../../../3rdparty/libjpeg.pri:GCC:
-# QMAKE_CFLAGS_WARN_ON = "-Wno-unused-parameter" "-Wno-main"
-
-qt_extend_target(QJpegPlugin CONDITION MSVC AND NOT QT_FEATURE_system_jpeg
- DEFINES
- _CRT_SECURE_NO_WARNINGS
-)
diff --git a/src/plugins/imageformats/jpeg/CMakeLists.txt b/src/plugins/imageformats/jpeg/CMakeLists.txt
index 52c3aa6911..6b077a7647 100644
--- a/src/plugins/imageformats/jpeg/CMakeLists.txt
+++ b/src/plugins/imageformats/jpeg/CMakeLists.txt
@@ -1,6 +1,7 @@
-# Generated from jpeg.pro.
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
-qt_find_package(JPEG) # special case
+qt_find_package(WrapJpeg PROVIDED_TARGETS WrapJpeg::WrapJpeg)
#####################################################################
## QJpegPlugin Plugin:
@@ -8,97 +9,21 @@ qt_find_package(JPEG) # special case
qt_internal_add_plugin(QJpegPlugin
OUTPUT_NAME qjpeg
- TYPE imageformats
+ PLUGIN_TYPE imageformats
SOURCES
- main.cpp main.h
+ main.cpp
qjpeghandler.cpp qjpeghandler_p.h
- PUBLIC_LIBRARIES
+ LIBRARIES
Qt::Core
Qt::CorePrivate
Qt::Gui
Qt::GuiPrivate
+ WrapJpeg::WrapJpeg
)
-#### Keys ignored in scope 1:.:.:jpeg.pro:<TRUE>:
-# OTHER_FILES = "jpeg.json"
-
-## Scopes:
-#####################################################################
-
-qt_extend_target(QJpegPlugin CONDITION QT_FEATURE_system_jpeg
- PUBLIC_LIBRARIES
- JPEG::JPEG
-)
-
-qt_extend_target(QJpegPlugin CONDITION NOT QT_FEATURE_system_jpeg
- SOURCES
- ../../../3rdparty/libjpeg/src/jaricom.c
- ../../../3rdparty/libjpeg/src/jcapimin.c
- ../../../3rdparty/libjpeg/src/jcapistd.c
- ../../../3rdparty/libjpeg/src/jcarith.c
- ../../../3rdparty/libjpeg/src/jccoefct.c
- ../../../3rdparty/libjpeg/src/jccolor.c
- ../../../3rdparty/libjpeg/src/jcdctmgr.c
- ../../../3rdparty/libjpeg/src/jchuff.c
- ../../../3rdparty/libjpeg/src/jcinit.c
- ../../../3rdparty/libjpeg/src/jcmainct.c
- ../../../3rdparty/libjpeg/src/jcmarker.c
- ../../../3rdparty/libjpeg/src/jcmaster.c
- ../../../3rdparty/libjpeg/src/jcomapi.c
- ../../../3rdparty/libjpeg/src/jcparam.c
- ../../../3rdparty/libjpeg/src/jcphuff.c
- ../../../3rdparty/libjpeg/src/jcprepct.c
- ../../../3rdparty/libjpeg/src/jcsample.c
- ../../../3rdparty/libjpeg/src/jctrans.c
- ../../../3rdparty/libjpeg/src/jdapimin.c
- ../../../3rdparty/libjpeg/src/jdapistd.c
- ../../../3rdparty/libjpeg/src/jdarith.c
- ../../../3rdparty/libjpeg/src/jdatadst.c
- ../../../3rdparty/libjpeg/src/jdatasrc.c
- ../../../3rdparty/libjpeg/src/jdcoefct.c
- ../../../3rdparty/libjpeg/src/jdcolor.c
- ../../../3rdparty/libjpeg/src/jddctmgr.c
- ../../../3rdparty/libjpeg/src/jdhuff.c
- ../../../3rdparty/libjpeg/src/jdinput.c
- ../../../3rdparty/libjpeg/src/jdmainct.c
- ../../../3rdparty/libjpeg/src/jdmarker.c
- ../../../3rdparty/libjpeg/src/jdmaster.c
- ../../../3rdparty/libjpeg/src/jdmerge.c
- ../../../3rdparty/libjpeg/src/jdphuff.c
- ../../../3rdparty/libjpeg/src/jdpostct.c
- ../../../3rdparty/libjpeg/src/jdsample.c
- ../../../3rdparty/libjpeg/src/jdtrans.c
- ../../../3rdparty/libjpeg/src/jerror.c
- ../../../3rdparty/libjpeg/src/jfdctflt.c
- ../../../3rdparty/libjpeg/src/jfdctfst.c
- ../../../3rdparty/libjpeg/src/jfdctint.c
- ../../../3rdparty/libjpeg/src/jidctflt.c
- ../../../3rdparty/libjpeg/src/jidctfst.c
- ../../../3rdparty/libjpeg/src/jidctint.c
- ../../../3rdparty/libjpeg/src/jidctred.c
- ../../../3rdparty/libjpeg/src/jmemmgr.c
- ../../../3rdparty/libjpeg/src/jmemnobs.c
- ../../../3rdparty/libjpeg/src/jquant1.c
- ../../../3rdparty/libjpeg/src/jquant2.c
- ../../../3rdparty/libjpeg/src/jsimd_none.c
- ../../../3rdparty/libjpeg/src/jutils.c
- INCLUDE_DIRECTORIES
- ../../../3rdparty/libjpeg
- ../../../3rdparty/libjpeg/src
-)
-
-# special case begin
-if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU"
- OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang"
- OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
- target_compile_options(QJpegPlugin PRIVATE "-Wno-unused-parameter")
+# Fails to build on Windows with a static Qt, PCH enabled and
+# the vendored libjpeg sources, due to 'boolean'
+# redefinition in jmorecfg.h and rpcndr.h.
+if(WIN32 AND NOT BUILD_SHARED_LIBS)
+ qt_update_ignore_pch_source(QJpegPlugin "qjpeghandler.cpp")
endif()
-# special case end
-
-#### Keys ignored in scope 5:.:../../../3rdparty:../../../3rdparty/libjpeg.pri:GCC:
-# QMAKE_CFLAGS_WARN_ON = "-Wno-unused-parameter" "-Wno-main"
-
-qt_extend_target(QJpegPlugin CONDITION MSVC AND NOT QT_FEATURE_system_jpeg
- DEFINES
- _CRT_SECURE_NO_WARNINGS
-)
diff --git a/src/plugins/imageformats/jpeg/jpeg.pro b/src/plugins/imageformats/jpeg/jpeg.pro
deleted file mode 100644
index 89476e62f5..0000000000
--- a/src/plugins/imageformats/jpeg/jpeg.pro
+++ /dev/null
@@ -1,18 +0,0 @@
-TARGET = qjpeg
-
-QT += core-private gui-private
-
-SOURCES += main.cpp qjpeghandler.cpp
-HEADERS += main.h qjpeghandler_p.h
-
-qtConfig(system-jpeg) {
- QMAKE_USE += libjpeg
-} else {
- include($$PWD/../../../3rdparty/libjpeg.pri)
-}
-
-OTHER_FILES += jpeg.json
-
-PLUGIN_TYPE = imageformats
-PLUGIN_CLASS_NAME = QJpegPlugin
-load(qt_plugin)
diff --git a/src/plugins/imageformats/jpeg/main.cpp b/src/plugins/imageformats/jpeg/main.cpp
index 83f13c4a9d..c869d07650 100644
--- a/src/plugins/imageformats/jpeg/main.cpp
+++ b/src/plugins/imageformats/jpeg/main.cpp
@@ -1,43 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-#include "main.h"
+#include <qimageiohandler.h>
+#include <qstringlist.h>
#ifdef QT_NO_IMAGEFORMAT_JPEG
#undef QT_NO_IMAGEFORMAT_JPEG
@@ -46,6 +11,15 @@
QT_BEGIN_NAMESPACE
+class QJpegPlugin : public QImageIOPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "jpeg.json")
+public:
+ Capabilities capabilities(QIODevice *device, const QByteArray &format) const override;
+ QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const override;
+};
+
QImageIOPlugin::Capabilities QJpegPlugin::capabilities(QIODevice *device, const QByteArray &format) const
{
if (format == "jpeg" || format == "jpg")
@@ -72,3 +46,5 @@ QImageIOHandler *QJpegPlugin::create(QIODevice *device, const QByteArray &format
}
QT_END_NAMESPACE
+
+#include "main.moc"
diff --git a/src/plugins/imageformats/jpeg/main.h b/src/plugins/imageformats/jpeg/main.h
deleted file mode 100644
index 1845c8c124..0000000000
--- a/src/plugins/imageformats/jpeg/main.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qimageiohandler.h>
-#include <qstringlist.h>
-
-#ifdef QT_NO_IMAGEFORMAT_JPEG
-#undef QT_NO_IMAGEFORMAT_JPEG
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QJpegPlugin : public QImageIOPlugin
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "jpeg.json")
-public:
- Capabilities capabilities(QIODevice *device, const QByteArray &format) const override;
- QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const override;
-};
-
-QT_END_NAMESPACE
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
index 72d932445e..59b73587c5 100644
--- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp
+++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qjpeghandler_p.h"
@@ -45,6 +9,7 @@
#include <qdebug.h>
#include <qimage.h>
#include <qlist.h>
+#include <qloggingcategory.h>
#include <qmath.h>
#include <qvariant.h>
#include <private/qicc_p.h>
@@ -60,13 +25,6 @@
// including jpeglib.h seems to be a little messy
extern "C" {
-// jpeglib.h->jmorecfg.h tries to typedef int boolean; but this conflicts with
-// some Windows headers that may or may not have been included
-#ifdef HAVE_BOOLEAN
-# undef HAVE_BOOLEAN
-#endif
-#define boolean jboolean
-
#define XMD_H // shut JPEGlib up
#include <jpeglib.h>
#ifdef const
@@ -75,6 +33,9 @@ extern "C" {
}
QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcJpeg, "qt.gui.imageio.jpeg")
+
QT_WARNING_DISABLE_GCC("-Wclobbered")
Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32(quint32 *dst, const uchar *src, int len);
@@ -88,10 +49,8 @@ extern "C" {
static void my_error_exit (j_common_ptr cinfo)
{
+ (*cinfo->err->output_message)(cinfo);
my_error_mgr* myerr = (my_error_mgr*) cinfo->err;
- char buffer[JMSG_LENGTH_MAX];
- (*cinfo->err->format_message)(cinfo, buffer);
- qWarning("%s", buffer);
longjmp(myerr->setjmp_buffer, 1);
}
@@ -99,7 +58,7 @@ static void my_output_message(j_common_ptr cinfo)
{
char buffer[JMSG_LENGTH_MAX];
(*cinfo->err->format_message)(cinfo, buffer);
- qWarning("%s", buffer);
+ qCWarning(lcJpeg,"%s", buffer);
}
}
@@ -213,9 +172,14 @@ inline static bool read_jpeg_format(QImage::Format &format, j_decompress_ptr cin
format = QImage::Format_Grayscale8;
break;
case 3:
- case 4:
format = QImage::Format_RGB32;
break;
+ case 4:
+ if (cinfo->out_color_space == JCS_CMYK)
+ format = QImage::Format_CMYK8888;
+ else
+ format = QImage::Format_RGB32;
+ break;
default:
result = false;
break;
@@ -233,9 +197,14 @@ static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info,
format = QImage::Format_Grayscale8;
break;
case 3:
- case 4:
format = QImage::Format_RGB32;
break;
+ case 4:
+ if (info->out_color_space == JCS_CMYK)
+ format = QImage::Format_CMYK8888;
+ else
+ format = QImage::Format_RGB32;
+ break;
default:
return false; // unsupported format
}
@@ -247,7 +216,7 @@ static bool read_jpeg_image(QImage *outImage,
QSize scaledSize, QRect scaledClipRect,
QRect clipRect, int quality,
Rgb888ToRgb32Converter converter,
- j_decompress_ptr info, struct my_error_mgr* err )
+ j_decompress_ptr info, struct my_error_mgr* err, bool invertCMYK)
{
if (!setjmp(err->setjmp_buffer)) {
// -1 means default quality.
@@ -330,7 +299,7 @@ static bool read_jpeg_image(QImage *outImage,
}
// If high quality not required, use fast decompression
- if( quality < HIGH_QUALITY_THRESHOLD ) {
+ if ( quality < HIGH_QUALITY_THRESHOLD ) {
info->dct_method = JDCT_IFAST;
info->do_fancy_upsampling = FALSE;
}
@@ -356,7 +325,7 @@ static bool read_jpeg_image(QImage *outImage,
// Allocate memory for the clipped QImage.
if (!ensureValidImage(outImage, info, clip.size()))
- longjmp(err->setjmp_buffer, 1);
+ return false;
// Avoid memcpy() overhead if grayscale with no clipping.
bool quickGray = (info->output_components == 1 &&
@@ -389,14 +358,15 @@ static bool read_jpeg_image(QImage *outImage,
QRgb *out = (QRgb*)outImage->scanLine(y);
converter(out, in, clip.width());
} else if (info->out_color_space == JCS_CMYK) {
- // Convert CMYK->RGB.
uchar *in = rows[0] + clip.x() * 4;
- QRgb *out = (QRgb*)outImage->scanLine(y);
- for (int i = 0; i < clip.width(); ++i) {
- int k = in[3];
- *out++ = qRgb(k * in[0] / 255, k * in[1] / 255,
- k * in[2] / 255);
- in += 4;
+ quint32 *out = (quint32*)outImage->scanLine(y);
+ if (invertCMYK) {
+ for (int i = 0; i < clip.width(); ++i) {
+ *out++ = 0xffffffffu - (in[0] | in[1] << 8 | in[2] << 16 | in[3] << 24);
+ in += 4;
+ }
+ } else {
+ memcpy(out, in, clip.width() * 4);
}
} else if (info->output_components == 1) {
// Grayscale.
@@ -432,8 +402,10 @@ static bool read_jpeg_image(QImage *outImage,
*outImage = outImage->copy(scaledClipRect);
return !outImage->isNull();
}
- else
+ else {
+ my_output_message(j_common_ptr(info));
return false;
+ }
}
struct my_jpeg_destination_mgr : public jpeg_destination_mgr {
@@ -498,7 +470,7 @@ static inline void set_text(const QImage &image, j_compress_ptr cinfo, const QSt
if (!comment.isEmpty())
comment += ": ";
comment += it.value().toUtf8();
- if (comment.length() > maxMarkerSize)
+ if (comment.size() > maxMarkerSize)
comment.truncate(maxMarkerSize);
jpeg_write_marker(cinfo, JPEG_COM, (const JOCTET *)comment.constData(), comment.size());
}
@@ -532,7 +504,8 @@ static bool do_write_jpeg_image(struct jpeg_compress_struct &cinfo,
int sourceQuality,
const QString &description,
bool optimize,
- bool progressive)
+ bool progressive,
+ bool invertCMYK)
{
bool success = false;
const QList<QRgb> cmap = image.colorTable();
@@ -572,10 +545,15 @@ static bool do_write_jpeg_image(struct jpeg_compress_struct &cinfo,
cinfo.in_color_space = gray ? JCS_GRAYSCALE : JCS_RGB;
break;
case QImage::Format_Grayscale8:
+ case QImage::Format_Grayscale16:
gray = true;
cinfo.input_components = 1;
cinfo.in_color_space = JCS_GRAYSCALE;
break;
+ case QImage::Format_CMYK8888:
+ cinfo.input_components = 4;
+ cinfo.in_color_space = JCS_CMYK;
+ break;
default:
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
@@ -608,7 +586,7 @@ static bool do_write_jpeg_image(struct jpeg_compress_struct &cinfo,
jpeg_start_compress(&cinfo, TRUE);
set_text(image, &cinfo, description);
- if (cinfo.in_color_space == JCS_RGB)
+ if (cinfo.in_color_space == JCS_RGB || cinfo.in_color_space == JCS_CMYK)
write_icc_profile(image, &cinfo);
row_pointer[0] = new uchar[cinfo.image_width*cinfo.input_components];
@@ -670,6 +648,12 @@ static bool do_write_jpeg_image(struct jpeg_compress_struct &cinfo,
case QImage::Format_Grayscale8:
memcpy(row, image.constScanLine(cinfo.next_scanline), w);
break;
+ case QImage::Format_Grayscale16:
+ {
+ QImage rowImg = image.copy(0, cinfo.next_scanline, w, 1).convertToFormat(QImage::Format_Grayscale8);
+ memcpy(row, rowImg.constScanLine(0), w);
+ }
+ break;
case QImage::Format_RGB888:
memcpy(row, image.constScanLine(cinfo.next_scanline), w * 3);
break;
@@ -686,6 +670,17 @@ static bool do_write_jpeg_image(struct jpeg_compress_struct &cinfo,
}
}
break;
+ case QImage::Format_CMYK8888: {
+ auto *cmykIn = reinterpret_cast<const quint32 *>(image.constScanLine(cinfo.next_scanline));
+ auto *cmykOut = reinterpret_cast<quint32 *>(row);
+ if (invertCMYK) {
+ for (int i = 0; i < w; ++i)
+ cmykOut[i] = 0xffffffffu - cmykIn[i];
+ } else {
+ memcpy(cmykOut, cmykIn, w * 4);
+ }
+ break;
+ }
default:
{
// (Testing shows that this way is actually faster than converting to RGB888 + memcpy)
@@ -707,6 +702,7 @@ static bool do_write_jpeg_image(struct jpeg_compress_struct &cinfo,
jpeg_destroy_compress(&cinfo);
success = true;
} else {
+ my_output_message(j_common_ptr(&cinfo));
jpeg_destroy_compress(&cinfo);
success = false;
}
@@ -720,7 +716,8 @@ static bool write_jpeg_image(const QImage &image,
int sourceQuality,
const QString &description,
bool optimize,
- bool progressive)
+ bool progressive,
+ bool invertCMYK)
{
// protect these objects from the setjmp/longjmp pair inside
// do_write_jpeg_image (by making them non-local).
@@ -731,7 +728,7 @@ static bool write_jpeg_image(const QImage &image,
const bool success = do_write_jpeg_image(cinfo, row_pointer,
image, device,
sourceQuality, description,
- optimize, progressive);
+ optimize, progressive, invertCMYK);
delete [] row_pointer[0];
return success;
@@ -754,7 +751,7 @@ public:
~QJpegHandlerPrivate()
{
- if(iod_src)
+ if (iod_src)
{
jpeg_destroy_decompress(&info);
delete iod_src;
@@ -776,6 +773,21 @@ public:
QStringList readTexts;
QByteArray iccProfile;
+ // Photoshop historically invertes the quantities in CMYK JPEG files:
+ // 0 means 100% ink, 255 means no ink. Every reader does the same,
+ // for compatibility reasons.
+ // Use such an interpretation by default, but also offer the alternative
+ // of not inverting the channels.
+ // This is just a "fancy" API; it could be reduced to a boolean setting
+ // for CMYK files.
+ enum class SubType {
+ Automatic,
+ Inverted_CMYK,
+ CMYK,
+ NSubTypes
+ };
+ SubType subType = SubType::Automatic;
+
struct jpeg_decompress_struct info;
struct my_jpeg_source_mgr * iod_src;
struct my_error_mgr err;
@@ -790,6 +802,14 @@ public:
QJpegHandler *q;
};
+static const char SupportedJPEGSubtypes[][14] = {
+ "Automatic",
+ "Inverted_CMYK",
+ "CMYK"
+};
+
+static_assert(std::size(SupportedJPEGSubtypes) == size_t(QJpegHandlerPrivate::SubType::NSubTypes));
+
static bool readExifHeader(QDataStream &stream)
{
char prefix[6];
@@ -913,7 +933,7 @@ static QImageIOHandler::Transformations exif2Qt(int exifOrientation)
case 8: // rotate 270 CW
return QImageIOHandler::TransformationRotate270;
}
- qWarning("Invalid EXIF orientation");
+ qCWarning(lcJpeg, "Invalid EXIF orientation");
return QImageIOHandler::TransformationNone;
}
@@ -922,7 +942,7 @@ static QImageIOHandler::Transformations exif2Qt(int exifOrientation)
*/
bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device)
{
- if(state == Ready)
+ if (state == Ready)
{
state = Error;
iod_src = new my_jpeg_source_mgr(device);
@@ -989,24 +1009,25 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device)
state = ReadHeader;
return true;
}
- else
- {
+ else {
+ my_output_message(j_common_ptr(&info));
return false;
}
}
- else if(state == Error)
+ else if (state == Error)
return false;
return true;
}
bool QJpegHandlerPrivate::read(QImage *image)
{
- if(state == Ready)
+ if (state == Ready)
readJpegHeader(q->device());
- if(state == ReadHeader)
+ if (state == ReadHeader)
{
- bool success = read_jpeg_image(image, scaledSize, scaledClipRect, clipRect, quality, rgb888ToRgb32ConverterPtr, &info, &err);
+ const bool invertCMYK = subType != QJpegHandlerPrivate::SubType::CMYK;
+ bool success = read_jpeg_image(image, scaledSize, scaledClipRect, clipRect, quality, rgb888ToRgb32ConverterPtr, &info, &err, invertCMYK);
if (success) {
for (int i = 0; i < readTexts.size()-1; i+=2)
image->setText(readTexts.at(i), readTexts.at(i+1));
@@ -1057,7 +1078,7 @@ QJpegHandler::~QJpegHandler()
bool QJpegHandler::canRead() const
{
- if(d->state == QJpegHandlerPrivate::Ready && !canRead(device()))
+ if (d->state == QJpegHandlerPrivate::Ready && !canRead(device()))
return false;
if (d->state != QJpegHandlerPrivate::Error && d->state != QJpegHandlerPrivate::ReadingEnd) {
@@ -1071,7 +1092,7 @@ bool QJpegHandler::canRead() const
bool QJpegHandler::canRead(QIODevice *device)
{
if (!device) {
- qWarning("QJpegHandler::canRead() called with no device");
+ qCWarning(lcJpeg, "QJpegHandler::canRead() called with no device");
return false;
}
@@ -1092,13 +1113,14 @@ extern void qt_imageTransform(QImage &src, QImageIOHandler::Transformations orie
bool QJpegHandler::write(const QImage &image)
{
+ const bool invertCMYK = d->subType != QJpegHandlerPrivate::SubType::CMYK;
if (d->transformation != QImageIOHandler::TransformationNone) {
// We don't support writing EXIF headers so apply the transform to the data.
QImage img = image;
qt_imageTransform(img, d->transformation);
- return write_jpeg_image(img, device(), d->quality, d->description, d->optimize, d->progressive);
+ return write_jpeg_image(img, device(), d->quality, d->description, d->optimize, d->progressive, invertCMYK);
}
- return write_jpeg_image(image, device(), d->quality, d->description, d->optimize, d->progressive);
+ return write_jpeg_image(image, device(), d->quality, d->description, d->optimize, d->progressive, invertCMYK);
}
bool QJpegHandler::supportsOption(ImageOption option) const
@@ -1109,6 +1131,8 @@ bool QJpegHandler::supportsOption(ImageOption option) const
|| option == ClipRect
|| option == Description
|| option == Size
+ || option == SubType
+ || option == SupportedSubTypes
|| option == ImageFormat
|| option == OptimizedWrite
|| option == ProgressiveScanWrite
@@ -1132,6 +1156,13 @@ QVariant QJpegHandler::option(ImageOption option) const
case Size:
d->readJpegHeader(device());
return d->size;
+ case SubType:
+ return QByteArray(SupportedJPEGSubtypes[int(d->subType)]);
+ case SupportedSubTypes: {
+ QByteArrayList list(std::begin(SupportedJPEGSubtypes),
+ std::end(SupportedJPEGSubtypes));
+ return QVariant::fromValue(list);
+ }
case ImageFormat:
d->readJpegHeader(device());
return d->format;
@@ -1167,6 +1198,16 @@ void QJpegHandler::setOption(ImageOption option, const QVariant &value)
case Description:
d->description = value.toString();
break;
+ case SubType: {
+ const QByteArray subType = value.toByteArray();
+ for (size_t i = 0; i < std::size(SupportedJPEGSubtypes); ++i) {
+ if (subType == SupportedJPEGSubtypes[i]) {
+ d->subType = QJpegHandlerPrivate::SubType(i);
+ break;
+ }
+ }
+ break;
+ }
case OptimizedWrite:
d->optimize = value.toBool();
break;
@@ -1177,6 +1218,7 @@ void QJpegHandler::setOption(ImageOption option, const QVariant &value)
int transformation = value.toInt();
if (transformation > 0 && transformation < 8)
d->transformation = QImageIOHandler::Transformations(transformation);
+ break;
}
default:
break;
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler_p.h b/src/plugins/imageformats/jpeg/qjpeghandler_p.h
index 43ca17317a..e246f7a6e1 100644
--- a/src/plugins/imageformats/jpeg/qjpeghandler_p.h
+++ b/src/plugins/imageformats/jpeg/qjpeghandler_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QJPEGHANDLER_P_H
#define QJPEGHANDLER_P_H