diff options
Diffstat (limited to 'src/gui/painting/qpixellayout.cpp')
-rw-r--r-- | src/gui/painting/qpixellayout.cpp | 176 |
1 files changed, 128 insertions, 48 deletions
diff --git a/src/gui/painting/qpixellayout.cpp b/src/gui/painting/qpixellayout.cpp index 99fb229fba..4f2f0ae13a 100644 --- a/src/gui/painting/qpixellayout.cpp +++ b/src/gui/painting/qpixellayout.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module 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) 2021 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 <qglobal.h> @@ -43,6 +7,7 @@ #include "qpixellayout_p.h" #include "qrgba64_p.h" #include <QtCore/private/qsimd_p.h> +#include <QtGui/private/qcmyk_p.h> QT_BEGIN_NAMESPACE @@ -248,8 +213,7 @@ inline void QT_FASTCALL storePixel<QPixelLayout::BPP24>(uchar *dest, int index, template <QPixelLayout::BPP bpp> static inline uint QT_FASTCALL fetchPixel(const uchar *, int) { - Q_UNREACHABLE(); - return 0; + Q_UNREACHABLE_RETURN(0); } template <> @@ -1224,10 +1188,12 @@ static const QRgba64 *QT_FASTCALL fetchRGBA64ToRGBA64PM(QRgba64 *buffer, const u const QRgba64 *s = reinterpret_cast<const QRgba64 *>(src) + index; #ifdef __SSE2__ for (int i = 0; i < count; ++i) { + const auto a = s[i].alpha(); __m128i vs = _mm_loadl_epi64((const __m128i *)(s + i)); __m128i va = _mm_shufflelo_epi16(vs, _MM_SHUFFLE(3, 3, 3, 3)); vs = multiplyAlpha65535(vs, va); _mm_storel_epi64((__m128i *)(buffer + i), vs); + buffer[i].setAlpha(a); } #else for (int i = 0; i < count; ++i) @@ -1692,11 +1658,71 @@ static const QRgba64 *QT_FASTCALL fetchRGBA32FPMToRGBA64PM(QRgba64 *buffer, cons return buffer; } +inline const uint *qt_convertCMYK8888ToARGB32PM(uint *buffer, const uint *src, int count) +{ + UNALIASED_CONVERSION_LOOP(buffer, src, count, [](uint s) { + const QColor color = QCmyk32::fromCmyk32(s).toColor(); + return color.rgba(); + }); + return buffer; +} + +static void QT_FASTCALL convertCMYK8888ToARGB32PM(uint *buffer, int count, const QList<QRgb> *) +{ + qt_convertCMYK8888ToARGB32PM(buffer, buffer, count); +} + +static const QRgba64 *QT_FASTCALL convertCMYK8888ToToRGBA64PM(QRgba64 *buffer, const uint *src, int count, + const QList<QRgb> *, QDitherInfo *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = QCmyk32::fromCmyk32(src[i]).toColor().rgba64(); + return buffer; +} + +static const uint *QT_FASTCALL fetchCMYK8888ToARGB32PM(uint *buffer, const uchar *src, int index, int count, + const QList<QRgb> *, QDitherInfo *) +{ + const uint *s = reinterpret_cast<const uint *>(src) + index; + for (int i = 0; i < count; ++i) + buffer[i] = QCmyk32::fromCmyk32(s[i]).toColor().rgba(); + return buffer; +} + +static const QRgba64 *QT_FASTCALL fetchCMYK8888ToRGBA64PM(QRgba64 *buffer, const uchar *src, int index, int count, + const QList<QRgb> *, QDitherInfo *) +{ + const uint *s = reinterpret_cast<const uint *>(src) + index; + for (int i = 0; i < count; ++i) + buffer[i] = QCmyk32::fromCmyk32(s[i]).toColor().rgba64(); + return buffer; +} + +static void QT_FASTCALL storeCMYK8888FromARGB32PM(uchar *dest, const uint *src, int index, int count, + const QList<QRgb> *, QDitherInfo *) +{ + uint *d = reinterpret_cast<uint *>(dest) + index; + for (int i = 0; i < count; ++i) { + QColor c = qUnpremultiply(src[i]); + d[i] = QCmyk32::fromColor(c).toUint(); + } +} + +static void QT_FASTCALL storeCMYK8888FromRGB32(uchar *dest, const uint *src, int index, int count, + const QList<QRgb> *, QDitherInfo *) +{ + uint *d = reinterpret_cast<uint *>(dest) + index; + for (int i = 0; i < count; ++i) { + QColor c = src[i]; + d[i] = QCmyk32::fromColor(c).toUint(); + } +} + // Note: // convertToArgb32() assumes that no color channel is less than 4 bits. // storeRGBFromARGB32PM() assumes that no color channel is more than 8 bits. // QImage::rgbSwapped() assumes that the red and blue color channels have the same number of bits. -QPixelLayout qPixelLayouts[QImage::NImageFormats] = { +QPixelLayout qPixelLayouts[] = { { false, false, QPixelLayout::BPPNone, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }, // Format_Invalid { false, false, QPixelLayout::BPP1MSB, nullptr, convertIndexedToARGB32PM, convertIndexedTo<QRgba64>, @@ -1814,9 +1840,13 @@ QPixelLayout qPixelLayouts[QImage::NImageFormats] = { convertPassThrough, nullptr, fetchRGB32FToRGB32, fetchRGBA32FPMToRGBA64PM, storeRGB32FFromRGB32, storeRGB32FFromRGB32 }, // Format_RGBA32FPx4_Premultiplied + { false, false, QPixelLayout::BPP32, nullptr, + convertCMYK8888ToARGB32PM, convertCMYK8888ToToRGBA64PM, + fetchCMYK8888ToARGB32PM, fetchCMYK8888ToRGBA64PM, + storeCMYK8888FromARGB32PM, storeCMYK8888FromRGB32 }, // Format_CMYK8888 }; -static_assert(sizeof(qPixelLayouts) / sizeof(*qPixelLayouts) == QImage::NImageFormats); +static_assert(std::size(qPixelLayouts) == QImage::NImageFormats); static void QT_FASTCALL convertFromRgb64(uint *dest, const QRgba64 *src, int length) { @@ -1951,7 +1981,15 @@ static void QT_FASTCALL storeRGBA32FPMFromRGBA64PM(uchar *dest, const QRgba64 *s d[i] = qConvertRgb64ToRgbaF32(src[i]); } -ConvertAndStorePixelsFunc64 qStoreFromRGBA64PM[QImage::NImageFormats] = { +static void QT_FASTCALL storeCMYKFromRGBA64PM(uchar *dest, const QRgba64 *src, int index, int count, + const QList<QRgb> *, QDitherInfo *) +{ + uint *d = reinterpret_cast<uint *>(dest) + index; + for (int i = 0; i < count; ++i) + d[i] = QCmyk32::fromColor(QColor(src[i])).toUint(); +} + +ConvertAndStorePixelsFunc64 qStoreFromRGBA64PM[] = { nullptr, nullptr, nullptr, @@ -1988,8 +2026,11 @@ ConvertAndStorePixelsFunc64 qStoreFromRGBA64PM[QImage::NImageFormats] = { storeRGBX32FFromRGBA64PM, storeRGBA32FFromRGBA64PM, storeRGBA32FPMFromRGBA64PM, + storeCMYKFromRGBA64PM, }; +static_assert(std::size(qStoreFromRGBA64PM) == QImage::NImageFormats); + #if QT_CONFIG(raster_fp) static void QT_FASTCALL convertToRgbaF32(QRgbaFloat32 *dest, const uint *src, int length) { @@ -2035,7 +2076,16 @@ static const QRgbaFloat32 * QT_FASTCALL convertRGB30ToRGBA32F(QRgbaFloat32 *buff return buffer; } -ConvertToFPFunc qConvertToRGBA32F[QImage::NImageFormats] = { +static const QRgbaFloat32 * QT_FASTCALL convertCMYKToRGBA32F(QRgbaFloat32 *buffer, const uint *src, int count, + const QList<QRgb> *, QDitherInfo *) +{ + for (int i = 0; i < count; ++i) + buffer[i] = QRgbaFloat32::fromArgb32(QCmyk32::fromCmyk32(src[i]).toColor().rgba()); + + return buffer; +} + +ConvertToFPFunc qConvertToRGBA32F[] = { nullptr, convertIndexedTo<QRgbaFloat32>, convertIndexedTo<QRgbaFloat32>, @@ -2072,8 +2122,11 @@ ConvertToFPFunc qConvertToRGBA32F[QImage::NImageFormats] = { nullptr, nullptr, nullptr, + convertCMYKToRGBA32F, }; +static_assert(std::size(qConvertToRGBA32F) == QImage::NImageFormats); + static const QRgbaFloat32 *QT_FASTCALL fetchRGBX64ToRGBA32F(QRgbaFloat32 *buffer, const uchar *src, int index, int count, const QList<QRgb> *, QDitherInfo *) { @@ -2138,7 +2191,17 @@ static const QRgbaFloat32 *QT_FASTCALL fetchRGBA32F(QRgbaFloat32 *, const uchar return s; } -FetchAndConvertPixelsFuncFP qFetchToRGBA32F[QImage::NImageFormats] = { +static const QRgbaFloat32 *QT_FASTCALL fetchCMYKToRGBA32F(QRgbaFloat32 *buffer, const uchar *src, int index, int count, + const QList<QRgb> *, QDitherInfo *) +{ + const uint *s = reinterpret_cast<const uint *>(src) + index; + for (int i = 0; i < count; ++i) + buffer[i] = QRgbaFloat32::fromArgb32(QCmyk32::fromCmyk32(s[i]).toColor().rgba()); + + return buffer; +} + +FetchAndConvertPixelsFuncFP qFetchToRGBA32F[] = { nullptr, fetchIndexedToRGBA32F<QPixelLayout::BPP1MSB>, fetchIndexedToRGBA32F<QPixelLayout::BPP1LSB>, @@ -2175,8 +2238,11 @@ FetchAndConvertPixelsFuncFP qFetchToRGBA32F[QImage::NImageFormats] = { fetchRGBA32F, fetchRGBA32FToRGBA32F, fetchRGBA32F, + fetchCMYKToRGBA32F, }; +static_assert(std::size(qFetchToRGBA32F) == QImage::NImageFormats); + static void QT_FASTCALL convertFromRgba32f(uint *dest, const QRgbaFloat32 *src, int length) { for (int i = 0; i < length; ++i) @@ -2263,7 +2329,7 @@ static void QT_FASTCALL storeRGBX16FFromRGBA32F(uchar *dest, const QRgbaFloat32 QRgbaFloat16 *d = reinterpret_cast<QRgbaFloat16 *>(dest) + index; for (int i = 0; i < count; ++i) { auto s = src[i].unpremultiplied(); - d[i] = QRgbaFloat16{ s.r, s.g, s.b, 1.0f }; + d[i] = QRgbaFloat16{ qfloat16(s.r), qfloat16(s.g), qfloat16(s.b), qfloat16(1.0f) }; } } @@ -2273,7 +2339,7 @@ static void QT_FASTCALL storeRGBA16FFromRGBA32F(uchar *dest, const QRgbaFloat32 QRgbaFloat16 *d = reinterpret_cast<QRgbaFloat16 *>(dest) + index; for (int i = 0; i < count; ++i) { auto s = src[i].unpremultiplied(); - d[i] = QRgbaFloat16{ s.r, s.g, s.b, s.a }; + d[i] = QRgbaFloat16{ qfloat16(s.r), qfloat16(s.g), qfloat16(s.b), qfloat16(s.a) }; } } @@ -2313,7 +2379,17 @@ static void QT_FASTCALL storeRGBA32FPMFromRGBA32F(uchar *dest, const QRgbaFloat3 } } -ConvertAndStorePixelsFuncFP qStoreFromRGBA32F[QImage::NImageFormats] = { +static void QT_FASTCALL storeCMYKFromRGBA32F(uchar *dest, const QRgbaFloat32 *src, int index, int count, + const QList<QRgb> *, QDitherInfo *) +{ + uint *d = reinterpret_cast<uint *>(dest) + index; + for (int i = 0; i < count; ++i) { + // Yikes, this really needs enablers in QColor and friends + d[i] = QCmyk32::fromColor(QColor(src[i].toArgb32())).toUint(); + } +} + +ConvertAndStorePixelsFuncFP qStoreFromRGBA32F[] = { nullptr, nullptr, nullptr, @@ -2350,7 +2426,11 @@ ConvertAndStorePixelsFuncFP qStoreFromRGBA32F[QImage::NImageFormats] = { storeRGBX32FFromRGBA32F, storeRGBA32FFromRGBA32F, storeRGBA32FPMFromRGBA32F, + storeCMYKFromRGBA32F, }; + +static_assert(std::size(qStoreFromRGBA32F) == QImage::NImageFormats); + #endif // QT_CONFIG(raster_fp) QT_END_NAMESPACE |