GUI: add CMYK painting support
This commit adds a CMYK 8bpp format to QImage. The idea is to enable the transport of CMYK images inside Qt, for instance to be loaded/saved from files or painted on CMYK capable paint devices (e.g. PDF). Also, rasterization support *from* a CMYK image is added (on top of a RGB surface), as well as CMYK image scaling/conversion. Conversion and rasterization between CMYK and RGB isn't particularly optimized nor it honors any colorspaces yet. The overall idea is to match 1:1 the existing behavior of CMYK QColor (which get naively changed to RGB; there isn't colorspace support in QPainter yet). There are no plans to add rasterization *towards* CMYK. Image save/load in native CMYK formats will be added in future commits. This work has been kindly sponsored by the QGIS project (https://qgis.org/). [ChangeLog][QtGui] Support for 8-bit CMYK images has been added. Change-Id: I4b024cd4c15119c669b6ddd450418a9e425587f8 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
This commit is contained in:
parent
9a92e26dcd
commit
2a54229f90
@ -170,6 +170,7 @@ qt_internal_add_module(Gui
|
|||||||
painting/qcolortrclut.cpp painting/qcolortrclut_p.h
|
painting/qcolortrclut.cpp painting/qcolortrclut_p.h
|
||||||
painting/qcompositionfunctions.cpp
|
painting/qcompositionfunctions.cpp
|
||||||
painting/qcosmeticstroker.cpp painting/qcosmeticstroker_p.h
|
painting/qcosmeticstroker.cpp painting/qcosmeticstroker_p.h
|
||||||
|
painting/qcmyk_p.h
|
||||||
painting/qdatabuffer_p.h
|
painting/qdatabuffer_p.h
|
||||||
painting/qdrawhelper_p.h
|
painting/qdrawhelper_p.h
|
||||||
painting/qdrawhelper_x86_p.h
|
painting/qdrawhelper_x86_p.h
|
||||||
|
@ -304,6 +304,7 @@ bool QImageData::checkForAlphaPixels() const
|
|||||||
case QImage::Format_RGBX64:
|
case QImage::Format_RGBX64:
|
||||||
case QImage::Format_RGBX16FPx4:
|
case QImage::Format_RGBX16FPx4:
|
||||||
case QImage::Format_RGBX32FPx4:
|
case QImage::Format_RGBX32FPx4:
|
||||||
|
case QImage::Format_CMYK32:
|
||||||
break;
|
break;
|
||||||
case QImage::Format_Invalid:
|
case QImage::Format_Invalid:
|
||||||
case QImage::NImageFormats:
|
case QImage::NImageFormats:
|
||||||
@ -360,7 +361,7 @@ bool QImageData::checkForAlphaPixels() const
|
|||||||
refer to the \l{How to Create Qt Plugins}{Plugin HowTo}.
|
refer to the \l{How to Create Qt Plugins}{Plugin HowTo}.
|
||||||
|
|
||||||
\warning Painting on a QImage with the format
|
\warning Painting on a QImage with the format
|
||||||
QImage::Format_Indexed8 is not supported.
|
QImage::Format_Indexed8 or QImage::Format_CMYK32 is not supported.
|
||||||
|
|
||||||
\tableofcontents
|
\tableofcontents
|
||||||
|
|
||||||
@ -742,8 +743,9 @@ bool QImageData::checkForAlphaPixels() const
|
|||||||
\value Format_RGBA32FPx4 The image is stored using a 4 32-bit floating point RGBA format (32FP-32FP-32FP-32FP). (added in Qt 6.2)
|
\value Format_RGBA32FPx4 The image is stored using a 4 32-bit floating point RGBA format (32FP-32FP-32FP-32FP). (added in Qt 6.2)
|
||||||
\value Format_RGBA32FPx4_Premultiplied The image is stored using a premultiplied 4 32-bit floating point
|
\value Format_RGBA32FPx4_Premultiplied The image is stored using a premultiplied 4 32-bit floating point
|
||||||
RGBA format (32FP-32FP-32FP-32FP). (added in Qt 6.2)
|
RGBA format (32FP-32FP-32FP-32FP). (added in Qt 6.2)
|
||||||
|
\value Format_CMYK32 The image is stored using a 32 bit CMYK format (0xCCMMYYKK). (added in Qt 6.8)
|
||||||
|
|
||||||
\note Drawing into a QImage with QImage::Format_Indexed8 is not
|
\note Drawing into a QImage with format QImage::Format_Indexed8 or QImage::Format_CMYK32 is not
|
||||||
supported.
|
supported.
|
||||||
|
|
||||||
\note Avoid most rendering directly to most of these formats using QPainter. Rendering
|
\note Avoid most rendering directly to most of these formats using QPainter. Rendering
|
||||||
@ -5727,6 +5729,19 @@ static constexpr QPixelFormat pixelformats[] = {
|
|||||||
/*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
|
/*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
|
||||||
/*INTERPRETATION*/ QPixelFormat::FloatingPoint,
|
/*INTERPRETATION*/ QPixelFormat::FloatingPoint,
|
||||||
/*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
|
/*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
|
||||||
|
//QImage::Format_CMYK32:
|
||||||
|
QPixelFormat(QPixelFormat::CMYK,
|
||||||
|
/*RED*/ 8,
|
||||||
|
/*GREEN*/ 8,
|
||||||
|
/*BLUE*/ 8,
|
||||||
|
/*FOURTH*/ 8,
|
||||||
|
/*FIFTH*/ 0,
|
||||||
|
/*ALPHA*/ 0,
|
||||||
|
/*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
|
||||||
|
/*ALPHA POSITION*/ QPixelFormat::AtBeginning,
|
||||||
|
/*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
|
||||||
|
/*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
|
||||||
|
/*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
|
||||||
};
|
};
|
||||||
static_assert(sizeof(pixelformats) / sizeof(*pixelformats) == QImage::NImageFormats);
|
static_assert(sizeof(pixelformats) / sizeof(*pixelformats) == QImage::NImageFormats);
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ public:
|
|||||||
Format_RGBX32FPx4,
|
Format_RGBX32FPx4,
|
||||||
Format_RGBA32FPx4,
|
Format_RGBA32FPx4,
|
||||||
Format_RGBA32FPx4_Premultiplied,
|
Format_RGBA32FPx4_Premultiplied,
|
||||||
|
Format_CMYK32,
|
||||||
#ifndef Q_QDOC
|
#ifndef Q_QDOC
|
||||||
NImageFormats
|
NImageFormats
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <private/qguiapplication_p.h>
|
#include <private/qguiapplication_p.h>
|
||||||
#include <private/qcolortransform_p.h>
|
#include <private/qcolortransform_p.h>
|
||||||
#include <private/qcolortrclut_p.h>
|
#include <private/qcolortrclut_p.h>
|
||||||
|
#include <private/qcmyk_p.h>
|
||||||
#include <private/qdrawhelper_p.h>
|
#include <private/qdrawhelper_p.h>
|
||||||
#include <private/qendian_p.h>
|
#include <private/qendian_p.h>
|
||||||
#include <private/qpixellayout_p.h>
|
#include <private/qpixellayout_p.h>
|
||||||
@ -2454,6 +2455,34 @@ static bool convert_Grayscale8_to_Indexed8_inplace(QImageData *data, Qt::ImageCo
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <bool SourceIsPremultiplied>
|
||||||
|
static void convert_ARGB32_to_CMYK32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
|
||||||
|
{
|
||||||
|
Q_ASSERT(src->format == QImage::Format_RGB32 ||
|
||||||
|
src->format == QImage::Format_ARGB32 ||
|
||||||
|
src->format == QImage::Format_ARGB32_Premultiplied);
|
||||||
|
Q_ASSERT(dest->format == QImage::Format_CMYK32);
|
||||||
|
Q_ASSERT(src->width == dest->width);
|
||||||
|
Q_ASSERT(src->height == dest->height);
|
||||||
|
|
||||||
|
const uchar *src_data = src->data;
|
||||||
|
uchar *dest_data = dest->data;
|
||||||
|
for (int y = 0; y < src->height; ++y) {
|
||||||
|
const QRgb *srcRgba = reinterpret_cast<const QRgb *>(src_data);
|
||||||
|
uint *destCmyk = reinterpret_cast<uint *>(dest_data);
|
||||||
|
|
||||||
|
for (int x = 0; x < src->width; ++x) {
|
||||||
|
QRgb sourcePixel = srcRgba[x];
|
||||||
|
if constexpr (SourceIsPremultiplied)
|
||||||
|
sourcePixel = qUnpremultiply(sourcePixel);
|
||||||
|
|
||||||
|
destCmyk[x] = QCmyk32::fromRgba(sourcePixel).toUint();
|
||||||
|
}
|
||||||
|
|
||||||
|
src_data += src->bytes_per_line;;
|
||||||
|
dest_data += dest->bytes_per_line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// first index source, second dest
|
// first index source, second dest
|
||||||
Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormats] = {};
|
Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormats] = {};
|
||||||
@ -2590,6 +2619,11 @@ static void qInitImageConversions()
|
|||||||
qimage_converter_map[QImage::Format_RGBX32FPx4][QImage::Format_RGBA32FPx4] = convert_passthrough;
|
qimage_converter_map[QImage::Format_RGBX32FPx4][QImage::Format_RGBA32FPx4] = convert_passthrough;
|
||||||
qimage_converter_map[QImage::Format_RGBX32FPx4][QImage::Format_RGBA32FPx4_Premultiplied] = convert_passthrough;
|
qimage_converter_map[QImage::Format_RGBX32FPx4][QImage::Format_RGBA32FPx4_Premultiplied] = convert_passthrough;
|
||||||
|
|
||||||
|
qimage_converter_map[QImage::Format_CMYK32][QImage::Format_CMYK32] = convert_passthrough;
|
||||||
|
qimage_converter_map[QImage::Format_RGB32][QImage::Format_CMYK32] = convert_ARGB32_to_CMYK32<false>;
|
||||||
|
qimage_converter_map[QImage::Format_ARGB32][QImage::Format_CMYK32] = convert_ARGB32_to_CMYK32<false>;
|
||||||
|
qimage_converter_map[QImage::Format_ARGB32_Premultiplied][QImage::Format_CMYK32] = convert_ARGB32_to_CMYK32<true>;
|
||||||
|
|
||||||
// Inline converters:
|
// Inline converters:
|
||||||
qimage_inplace_converter_map[QImage::Format_Indexed8][QImage::Format_Grayscale8] =
|
qimage_inplace_converter_map[QImage::Format_Indexed8][QImage::Format_Grayscale8] =
|
||||||
convert_Indexed8_to_Grayscale8_inplace;
|
convert_Indexed8_to_Grayscale8_inplace;
|
||||||
|
@ -195,6 +195,9 @@ inline int qt_depthForFormat(QImage::Format format)
|
|||||||
case QImage::Format_RGBA32FPx4_Premultiplied:
|
case QImage::Format_RGBA32FPx4_Premultiplied:
|
||||||
depth = 128;
|
depth = 128;
|
||||||
break;
|
break;
|
||||||
|
case QImage::Format_CMYK32:
|
||||||
|
depth = 32;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return depth;
|
return depth;
|
||||||
}
|
}
|
||||||
@ -248,6 +251,7 @@ inline QImage::Format qt_opaqueVersion(QImage::Format format)
|
|||||||
case QImage::Format_RGBX32FPx4:
|
case QImage::Format_RGBX32FPx4:
|
||||||
case QImage::Format_Grayscale8:
|
case QImage::Format_Grayscale8:
|
||||||
case QImage::Format_Grayscale16:
|
case QImage::Format_Grayscale16:
|
||||||
|
case QImage::Format_CMYK32:
|
||||||
return format;
|
return format;
|
||||||
case QImage::Format_Mono:
|
case QImage::Format_Mono:
|
||||||
case QImage::Format_MonoLSB:
|
case QImage::Format_MonoLSB:
|
||||||
@ -311,6 +315,7 @@ inline QImage::Format qt_alphaVersion(QImage::Format format)
|
|||||||
case QImage::Format_Alpha8:
|
case QImage::Format_Alpha8:
|
||||||
case QImage::Format_Grayscale8:
|
case QImage::Format_Grayscale8:
|
||||||
case QImage::Format_Invalid:
|
case QImage::Format_Invalid:
|
||||||
|
case QImage::Format_CMYK32:
|
||||||
case QImage::NImageFormats:
|
case QImage::NImageFormats:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
88
src/gui/painting/qcmyk_p.h
Normal file
88
src/gui/painting/qcmyk_p.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
// Copyright (C) 2023 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 QCMYK_P_H
|
||||||
|
#define QCMYK_P_H
|
||||||
|
|
||||||
|
//
|
||||||
|
// W A R N I N G
|
||||||
|
// -------------
|
||||||
|
//
|
||||||
|
// This file is not part of the Qt API. It exists purely as an
|
||||||
|
// implementation detail. This header file may change from version to
|
||||||
|
// version without notice, or even be removed.
|
||||||
|
//
|
||||||
|
// We mean it.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <QtGui/private/qtguiglobal_p.h>
|
||||||
|
#include <QtGui/qcolor.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QCmyk32
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
uint m_cmyk = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QCmyk32() = default;
|
||||||
|
|
||||||
|
constexpr QCmyk32(int cyan, int magenta, int yellow, int black) :
|
||||||
|
#if QT_BYTE_ORDER == Q_BIG_ENDIAN
|
||||||
|
m_cmyk(cyan << 24 | magenta << 16 | yellow << 8 | black)
|
||||||
|
#else
|
||||||
|
m_cmyk(cyan | magenta << 8 | yellow << 16 | black << 24)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#if QT_BYTE_ORDER == Q_BIG_ENDIAN
|
||||||
|
constexpr int cyan() const noexcept { return (m_cmyk >> 24) & 0xff; }
|
||||||
|
constexpr int magenta() const noexcept { return (m_cmyk >> 16) & 0xff; }
|
||||||
|
constexpr int yellow() const noexcept { return (m_cmyk >> 8) & 0xff; }
|
||||||
|
constexpr int black() const noexcept { return (m_cmyk ) & 0xff; }
|
||||||
|
#else
|
||||||
|
constexpr int cyan() const noexcept { return (m_cmyk ) & 0xff; }
|
||||||
|
constexpr int magenta() const noexcept { return (m_cmyk >> 8) & 0xff; }
|
||||||
|
constexpr int yellow() const noexcept { return (m_cmyk >> 16) & 0xff; }
|
||||||
|
constexpr int black() const noexcept { return (m_cmyk >> 24) & 0xff; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QColor toColor() const noexcept
|
||||||
|
{
|
||||||
|
return QColor::fromCmyk(cyan(), magenta(), yellow(), black());
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr uint toUint() const noexcept
|
||||||
|
{
|
||||||
|
return m_cmyk;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static QCmyk32 fromCmyk32(uint cmyk) noexcept
|
||||||
|
{
|
||||||
|
QCmyk32 result;
|
||||||
|
result.m_cmyk = cmyk;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QCmyk32 fromRgba(QRgb rgba) noexcept
|
||||||
|
{
|
||||||
|
const QColor c = QColor(rgba).toCmyk();
|
||||||
|
return QCmyk32(c.cyan(), c.magenta(), c.yellow(), c.black());
|
||||||
|
}
|
||||||
|
|
||||||
|
static QCmyk32 fromColor(const QColor &color) noexcept
|
||||||
|
{
|
||||||
|
QColor c = color.toCmyk();
|
||||||
|
return QCmyk32(c.cyan(), c.magenta(), c.yellow(), c.black());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(QCmyk32) == sizeof(int));
|
||||||
|
static_assert(alignof(QCmyk32) == alignof(int));
|
||||||
|
static_assert(std::is_standard_layout_v<QCmyk32>);
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QCMYK_P_H
|
@ -176,7 +176,7 @@ static void QT_FASTCALL convertRGBA32FPMToRGBA64PM(QRgba64 *buffer, int count)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Convert64Func convert64ToRGBA64PM[QImage::NImageFormats] = {
|
static Convert64Func convert64ToRGBA64PM[] = {
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
@ -213,7 +213,10 @@ static Convert64Func convert64ToRGBA64PM[QImage::NImageFormats] = {
|
|||||||
convertRGBA32FPMToRGBA64PM,
|
convertRGBA32FPMToRGBA64PM,
|
||||||
convertRGBA32FToRGBA64PM,
|
convertRGBA32FToRGBA64PM,
|
||||||
convertRGBA32FPMToRGBA64PM,
|
convertRGBA32FPMToRGBA64PM,
|
||||||
|
nullptr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(std::size(convert64ToRGBA64PM) == QImage::NImageFormats);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if QT_CONFIG(raster_fp)
|
#if QT_CONFIG(raster_fp)
|
||||||
@ -247,7 +250,7 @@ static void QT_FASTCALL convertRGBA16FToRGBA32F(QRgbaFloat32 *buffer, const quin
|
|||||||
qFloatFromFloat16((float *)buffer, (const qfloat16 *)src, count * 4);
|
qFloatFromFloat16((float *)buffer, (const qfloat16 *)src, count * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Convert64ToFPFunc convert64ToRGBA32F[QImage::NImageFormats] = {
|
static Convert64ToFPFunc convert64ToRGBA32F[] = {
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
@ -284,8 +287,11 @@ static Convert64ToFPFunc convert64ToRGBA32F[QImage::NImageFormats] = {
|
|||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
|
nullptr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(std::size(convert64ToRGBA32F) == QImage::NImageFormats);
|
||||||
|
|
||||||
static void convertRGBA32FToRGBA32FPM(QRgbaFloat32 *buffer, int count)
|
static void convertRGBA32FToRGBA32FPM(QRgbaFloat32 *buffer, int count)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
@ -353,7 +359,7 @@ static uint *QT_FASTCALL destFetchUndefined(uint *buffer, QRasterBuffer *, int,
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DestFetchProc destFetchProc[QImage::NImageFormats] =
|
static DestFetchProc destFetchProc[] =
|
||||||
{
|
{
|
||||||
nullptr, // Format_Invalid
|
nullptr, // Format_Invalid
|
||||||
destFetchMono, // Format_Mono,
|
destFetchMono, // Format_Mono,
|
||||||
@ -391,8 +397,11 @@ static DestFetchProc destFetchProc[QImage::NImageFormats] =
|
|||||||
destFetch, // Format_RGBX32FPx4
|
destFetch, // Format_RGBX32FPx4
|
||||||
destFetch, // Format_RGBA32FPx4
|
destFetch, // Format_RGBA32FPx4
|
||||||
destFetch, // Format_RGBA32FPx4_Premultiplied
|
destFetch, // Format_RGBA32FPx4_Premultiplied
|
||||||
|
destFetch, // Format_CMYK32
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(std::size(destFetchProc) == QImage::NImageFormats);
|
||||||
|
|
||||||
#if QT_CONFIG(raster_64bit)
|
#if QT_CONFIG(raster_64bit)
|
||||||
static QRgba64 *QT_FASTCALL destFetch64(QRgba64 *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length)
|
static QRgba64 *QT_FASTCALL destFetch64(QRgba64 *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length)
|
||||||
{
|
{
|
||||||
@ -410,7 +419,7 @@ static QRgba64 * QT_FASTCALL destFetch64Undefined(QRgba64 *buffer, QRasterBuffer
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DestFetchProc64 destFetchProc64[QImage::NImageFormats] =
|
static DestFetchProc64 destFetchProc64[] =
|
||||||
{
|
{
|
||||||
nullptr, // Format_Invalid
|
nullptr, // Format_Invalid
|
||||||
nullptr, // Format_Mono,
|
nullptr, // Format_Mono,
|
||||||
@ -448,7 +457,10 @@ static DestFetchProc64 destFetchProc64[QImage::NImageFormats] =
|
|||||||
destFetch64, // Format_RGBX32FPx4
|
destFetch64, // Format_RGBX32FPx4
|
||||||
destFetch64, // Format_RGBA32FPx4
|
destFetch64, // Format_RGBA32FPx4
|
||||||
destFetch64, // Format_RGBA32FPx4_Premultiplied
|
destFetch64, // Format_RGBA32FPx4_Premultiplied
|
||||||
|
destFetch64, // Format_CMYK32
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(std::size(destFetchProc64) == QImage::NImageFormats);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if QT_CONFIG(raster_fp)
|
#if QT_CONFIG(raster_fp)
|
||||||
@ -466,7 +478,7 @@ static QRgbaFloat32 *QT_FASTCALL destFetchFPUndefined(QRgbaFloat32 *buffer, QRas
|
|||||||
{
|
{
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
static DestFetchProcFP destFetchProcFP[QImage::NImageFormats] =
|
static DestFetchProcFP destFetchProcFP[] =
|
||||||
{
|
{
|
||||||
nullptr, // Format_Invalid
|
nullptr, // Format_Invalid
|
||||||
nullptr, // Format_Mono,
|
nullptr, // Format_Mono,
|
||||||
@ -504,7 +516,10 @@ static DestFetchProcFP destFetchProcFP[QImage::NImageFormats] =
|
|||||||
destFetchRGBFP, // Format_RGBX32FPx4
|
destFetchRGBFP, // Format_RGBX32FPx4
|
||||||
destFetchFP, // Format_RGBA32FPx4
|
destFetchFP, // Format_RGBA32FPx4
|
||||||
destFetchRGBFP, // Format_RGBA32FPx4_Premultiplied
|
destFetchRGBFP, // Format_RGBA32FPx4_Premultiplied
|
||||||
|
destFetchFP, // Format_CMYK32
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(std::size(destFetchProcFP) == QImage::NImageFormats);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -657,7 +672,7 @@ static void QT_FASTCALL destStoreGray16(QRasterBuffer *rasterBuffer, int x, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static DestStoreProc destStoreProc[QImage::NImageFormats] =
|
static DestStoreProc destStoreProc[] =
|
||||||
{
|
{
|
||||||
nullptr, // Format_Invalid
|
nullptr, // Format_Invalid
|
||||||
destStoreMono, // Format_Mono,
|
destStoreMono, // Format_Mono,
|
||||||
@ -695,8 +710,11 @@ static DestStoreProc destStoreProc[QImage::NImageFormats] =
|
|||||||
destStore, // Format_RGBX32FPx4
|
destStore, // Format_RGBX32FPx4
|
||||||
destStore, // Format_RGBA32FPx4
|
destStore, // Format_RGBA32FPx4
|
||||||
destStore, // Format_RGBA32FPx4_Premultiplied
|
destStore, // Format_RGBA32FPx4_Premultiplied
|
||||||
|
destStore, // Format_CMYK32
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(std::size(destStoreProc) == QImage::NImageFormats);
|
||||||
|
|
||||||
#if QT_CONFIG(raster_64bit)
|
#if QT_CONFIG(raster_64bit)
|
||||||
static void QT_FASTCALL destStore64(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
|
static void QT_FASTCALL destStore64(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
|
||||||
{
|
{
|
||||||
@ -757,7 +775,7 @@ static void QT_FASTCALL destStore64Gray16(QRasterBuffer *rasterBuffer, int x, in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static DestStoreProc64 destStoreProc64[QImage::NImageFormats] =
|
static DestStoreProc64 destStoreProc64[] =
|
||||||
{
|
{
|
||||||
nullptr, // Format_Invalid
|
nullptr, // Format_Invalid
|
||||||
nullptr, // Format_Mono,
|
nullptr, // Format_Mono,
|
||||||
@ -795,7 +813,10 @@ static DestStoreProc64 destStoreProc64[QImage::NImageFormats] =
|
|||||||
destStore64, // Format_RGBX32FPx4
|
destStore64, // Format_RGBX32FPx4
|
||||||
destStore64, // Format_RGBA32FPx4
|
destStore64, // Format_RGBA32FPx4
|
||||||
destStore64, // Format_RGBA32FPx4_Premultiplied
|
destStore64, // Format_RGBA32FPx4_Premultiplied
|
||||||
|
destStore64, // Format_CMYK32
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(std::size(destStoreProc64) == QImage::NImageFormats);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if QT_CONFIG(raster_fp)
|
#if QT_CONFIG(raster_fp)
|
||||||
@ -3070,7 +3091,7 @@ static const QRgbaFloat32 *QT_FASTCALL fetchTransformedBilinearFP(QRgbaFloat32 *
|
|||||||
#endif // QT_CONFIG(raster_fp)
|
#endif // QT_CONFIG(raster_fp)
|
||||||
|
|
||||||
// FetchUntransformed can have more specialized methods added depending on SIMD features.
|
// FetchUntransformed can have more specialized methods added depending on SIMD features.
|
||||||
static SourceFetchProc sourceFetchUntransformed[QImage::NImageFormats] = {
|
static SourceFetchProc sourceFetchUntransformed[] = {
|
||||||
nullptr, // Invalid
|
nullptr, // Invalid
|
||||||
fetchUntransformed, // Mono
|
fetchUntransformed, // Mono
|
||||||
fetchUntransformed, // MonoLsb
|
fetchUntransformed, // MonoLsb
|
||||||
@ -3107,9 +3128,12 @@ static SourceFetchProc sourceFetchUntransformed[QImage::NImageFormats] = {
|
|||||||
fetchUntransformed, // RGBX32Px4
|
fetchUntransformed, // RGBX32Px4
|
||||||
fetchUntransformed, // RGBA32FPx4
|
fetchUntransformed, // RGBA32FPx4
|
||||||
fetchUntransformed, // RGBA32FPx4_Premultiplied
|
fetchUntransformed, // RGBA32FPx4_Premultiplied
|
||||||
|
fetchUntransformed, // CMYK32
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SourceFetchProc sourceFetchGeneric[NBlendTypes] = {
|
static_assert(std::size(sourceFetchUntransformed) == QImage::NImageFormats);
|
||||||
|
|
||||||
|
static const SourceFetchProc sourceFetchGeneric[] = {
|
||||||
fetchUntransformed, // Untransformed
|
fetchUntransformed, // Untransformed
|
||||||
fetchUntransformed, // Tiled
|
fetchUntransformed, // Tiled
|
||||||
fetchTransformed<BlendTransformed, QPixelLayout::BPPNone>, // Transformed
|
fetchTransformed<BlendTransformed, QPixelLayout::BPPNone>, // Transformed
|
||||||
@ -3118,7 +3142,9 @@ static const SourceFetchProc sourceFetchGeneric[NBlendTypes] = {
|
|||||||
fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPPNone> // TransformedBilinearTiled
|
fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPPNone> // TransformedBilinearTiled
|
||||||
};
|
};
|
||||||
|
|
||||||
static SourceFetchProc sourceFetchARGB32PM[NBlendTypes] = {
|
static_assert(std::size(sourceFetchGeneric) == NBlendTypes);
|
||||||
|
|
||||||
|
static SourceFetchProc sourceFetchARGB32PM[] = {
|
||||||
fetchUntransformedARGB32PM, // Untransformed
|
fetchUntransformedARGB32PM, // Untransformed
|
||||||
fetchUntransformedARGB32PM, // Tiled
|
fetchUntransformedARGB32PM, // Tiled
|
||||||
fetchTransformed<BlendTransformed, QPixelLayout::BPP32>, // Transformed
|
fetchTransformed<BlendTransformed, QPixelLayout::BPP32>, // Transformed
|
||||||
@ -3127,7 +3153,9 @@ static SourceFetchProc sourceFetchARGB32PM[NBlendTypes] = {
|
|||||||
fetchTransformedBilinearARGB32PM<BlendTransformedBilinearTiled> // BilinearTiled
|
fetchTransformedBilinearARGB32PM<BlendTransformedBilinearTiled> // BilinearTiled
|
||||||
};
|
};
|
||||||
|
|
||||||
static SourceFetchProc sourceFetchAny16[NBlendTypes] = {
|
static_assert(std::size(sourceFetchARGB32PM) == NBlendTypes);
|
||||||
|
|
||||||
|
static SourceFetchProc sourceFetchAny16[] = {
|
||||||
fetchUntransformed, // Untransformed
|
fetchUntransformed, // Untransformed
|
||||||
fetchUntransformed, // Tiled
|
fetchUntransformed, // Tiled
|
||||||
fetchTransformed<BlendTransformed, QPixelLayout::BPP16>, // Transformed
|
fetchTransformed<BlendTransformed, QPixelLayout::BPP16>, // Transformed
|
||||||
@ -3136,7 +3164,9 @@ static SourceFetchProc sourceFetchAny16[NBlendTypes] = {
|
|||||||
fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPP16> // TransformedBilinearTiled
|
fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPP16> // TransformedBilinearTiled
|
||||||
};
|
};
|
||||||
|
|
||||||
static SourceFetchProc sourceFetchAny32[NBlendTypes] = {
|
static_assert(std::size(sourceFetchAny16) == NBlendTypes);
|
||||||
|
|
||||||
|
static SourceFetchProc sourceFetchAny32[] = {
|
||||||
fetchUntransformed, // Untransformed
|
fetchUntransformed, // Untransformed
|
||||||
fetchUntransformed, // Tiled
|
fetchUntransformed, // Tiled
|
||||||
fetchTransformed<BlendTransformed, QPixelLayout::BPP32>, // Transformed
|
fetchTransformed<BlendTransformed, QPixelLayout::BPP32>, // Transformed
|
||||||
@ -3145,6 +3175,8 @@ static SourceFetchProc sourceFetchAny32[NBlendTypes] = {
|
|||||||
fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPP32> // TransformedBilinearTiled
|
fetchTransformedBilinear<BlendTransformedBilinearTiled, QPixelLayout::BPP32> // TransformedBilinearTiled
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(std::size(sourceFetchAny32) == NBlendTypes);
|
||||||
|
|
||||||
static inline SourceFetchProc getSourceFetch(TextureBlendType blendType, QImage::Format format)
|
static inline SourceFetchProc getSourceFetch(TextureBlendType blendType, QImage::Format format)
|
||||||
{
|
{
|
||||||
if (format == QImage::Format_RGB32 || format == QImage::Format_ARGB32_Premultiplied)
|
if (format == QImage::Format_RGB32 || format == QImage::Format_ARGB32_Premultiplied)
|
||||||
@ -3159,7 +3191,7 @@ static inline SourceFetchProc getSourceFetch(TextureBlendType blendType, QImage:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if QT_CONFIG(raster_64bit)
|
#if QT_CONFIG(raster_64bit)
|
||||||
static const SourceFetchProc64 sourceFetchGeneric64[NBlendTypes] = {
|
static const SourceFetchProc64 sourceFetchGeneric64[] = {
|
||||||
fetchUntransformed64, // Untransformed
|
fetchUntransformed64, // Untransformed
|
||||||
fetchUntransformed64, // Tiled
|
fetchUntransformed64, // Tiled
|
||||||
fetchTransformed64<BlendTransformed>, // Transformed
|
fetchTransformed64<BlendTransformed>, // Transformed
|
||||||
@ -3168,7 +3200,9 @@ static const SourceFetchProc64 sourceFetchGeneric64[NBlendTypes] = {
|
|||||||
fetchTransformedBilinear64<BlendTransformedBilinearTiled> // BilinearTiled
|
fetchTransformedBilinear64<BlendTransformedBilinearTiled> // BilinearTiled
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SourceFetchProc64 sourceFetchRGBA64PM[NBlendTypes] = {
|
static_assert(std::size(sourceFetchGeneric64) == NBlendTypes);
|
||||||
|
|
||||||
|
static const SourceFetchProc64 sourceFetchRGBA64PM[] = {
|
||||||
fetchUntransformedRGBA64PM, // Untransformed
|
fetchUntransformedRGBA64PM, // Untransformed
|
||||||
fetchUntransformedRGBA64PM, // Tiled
|
fetchUntransformedRGBA64PM, // Tiled
|
||||||
fetchTransformed64<BlendTransformed>, // Transformed
|
fetchTransformed64<BlendTransformed>, // Transformed
|
||||||
@ -3177,6 +3211,8 @@ static const SourceFetchProc64 sourceFetchRGBA64PM[NBlendTypes] = {
|
|||||||
fetchTransformedBilinear64<BlendTransformedBilinearTiled> // BilinearTiled
|
fetchTransformedBilinear64<BlendTransformedBilinearTiled> // BilinearTiled
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(std::size(sourceFetchRGBA64PM) == NBlendTypes);
|
||||||
|
|
||||||
static inline SourceFetchProc64 getSourceFetch64(TextureBlendType blendType, QImage::Format format)
|
static inline SourceFetchProc64 getSourceFetch64(TextureBlendType blendType, QImage::Format format)
|
||||||
{
|
{
|
||||||
if (format == QImage::Format_RGBX64 || format == QImage::Format_RGBA64_Premultiplied)
|
if (format == QImage::Format_RGBX64 || format == QImage::Format_RGBA64_Premultiplied)
|
||||||
@ -3186,7 +3222,7 @@ static inline SourceFetchProc64 getSourceFetch64(TextureBlendType blendType, QIm
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if QT_CONFIG(raster_fp)
|
#if QT_CONFIG(raster_fp)
|
||||||
static const SourceFetchProcFP sourceFetchGenericFP[NBlendTypes] = {
|
static const SourceFetchProcFP sourceFetchGenericFP[] = {
|
||||||
fetchUntransformedFP, // Untransformed
|
fetchUntransformedFP, // Untransformed
|
||||||
fetchUntransformedFP, // Tiled
|
fetchUntransformedFP, // Tiled
|
||||||
fetchTransformedFP<BlendTransformed>, // Transformed
|
fetchTransformedFP<BlendTransformed>, // Transformed
|
||||||
@ -3195,6 +3231,8 @@ static const SourceFetchProcFP sourceFetchGenericFP[NBlendTypes] = {
|
|||||||
fetchTransformedBilinearFP<BlendTransformedBilinearTiled> // BilinearTiled
|
fetchTransformedBilinearFP<BlendTransformedBilinearTiled> // BilinearTiled
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(std::size(sourceFetchGenericFP) == NBlendTypes);
|
||||||
|
|
||||||
static inline SourceFetchProcFP getSourceFetchFP(TextureBlendType blendType, QImage::Format /*format*/)
|
static inline SourceFetchProcFP getSourceFetchFP(TextureBlendType blendType, QImage::Format /*format*/)
|
||||||
{
|
{
|
||||||
return sourceFetchGenericFP[blendType];
|
return sourceFetchGenericFP[blendType];
|
||||||
@ -3612,7 +3650,6 @@ static inline Operator getOperator(const QSpanData *data, const QT_FT_Span *span
|
|||||||
{
|
{
|
||||||
Operator op;
|
Operator op;
|
||||||
bool solidSource = false;
|
bool solidSource = false;
|
||||||
|
|
||||||
switch(data->type) {
|
switch(data->type) {
|
||||||
case QSpanData::Solid:
|
case QSpanData::Solid:
|
||||||
solidSource = data->solidColor.alphaF() >= 1.0f;
|
solidSource = data->solidColor.alphaF() >= 1.0f;
|
||||||
@ -5962,7 +5999,7 @@ static void qt_rectfill_fp32x4(QRasterBuffer *rasterBuffer,
|
|||||||
// Map table for destination image format. Contains function pointers
|
// Map table for destination image format. Contains function pointers
|
||||||
// for blends of various types unto the destination
|
// for blends of various types unto the destination
|
||||||
|
|
||||||
DrawHelper qDrawHelper[QImage::NImageFormats] =
|
DrawHelper qDrawHelper[] =
|
||||||
{
|
{
|
||||||
// Format_Invalid,
|
// Format_Invalid,
|
||||||
{ nullptr, nullptr, nullptr, nullptr, nullptr },
|
{ nullptr, nullptr, nullptr, nullptr, nullptr },
|
||||||
@ -6239,6 +6276,8 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(std::size(qDrawHelper) == QImage::NImageFormats);
|
||||||
|
|
||||||
#if !defined(Q_PROCESSOR_X86)
|
#if !defined(Q_PROCESSOR_X86)
|
||||||
void qt_memfill64(quint64 *dest, quint64 color, qsizetype count)
|
void qt_memfill64(quint64 *dest, quint64 color, qsizetype count)
|
||||||
{
|
{
|
||||||
|
@ -1765,9 +1765,12 @@ bool QPainter::begin(QPaintDevice *pd)
|
|||||||
qWarning("QPainter::begin: Cannot paint on a null image");
|
qWarning("QPainter::begin: Cannot paint on a null image");
|
||||||
qt_cleanup_painter_state(d);
|
qt_cleanup_painter_state(d);
|
||||||
return false;
|
return false;
|
||||||
} else if (img->format() == QImage::Format_Indexed8) {
|
} else if (img->format() == QImage::Format_Indexed8 ||
|
||||||
// Painting on indexed8 images is not supported.
|
img->format() == QImage::Format_CMYK32) {
|
||||||
qWarning("QPainter::begin: Cannot paint on an image with the QImage::Format_Indexed8 format");
|
// Painting on these formats is not supported.
|
||||||
|
qWarning() << "QPainter::begin: Cannot paint on an image with the"
|
||||||
|
<< img->format()
|
||||||
|
<< "format";
|
||||||
qt_cleanup_painter_state(d);
|
qt_cleanup_painter_state(d);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "qpixellayout_p.h"
|
#include "qpixellayout_p.h"
|
||||||
#include "qrgba64_p.h"
|
#include "qrgba64_p.h"
|
||||||
#include <QtCore/private/qsimd_p.h>
|
#include <QtCore/private/qsimd_p.h>
|
||||||
|
#include <QtGui/private/qcmyk_p.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -1657,6 +1658,66 @@ static const QRgba64 *QT_FASTCALL fetchRGBA32FPMToRGBA64PM(QRgba64 *buffer, cons
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const uint *qt_convertCMYK32ToARGB32PM(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 convertCMYK32ToARGB32PM(uint *buffer, int count, const QList<QRgb> *)
|
||||||
|
{
|
||||||
|
qt_convertCMYK32ToARGB32PM(buffer, buffer, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const QRgba64 *QT_FASTCALL convertCMYK32ToToRGBA64PM(QRgba64 *buffer, const uint *src, int count,
|
||||||
|
const QList<QRgb> *, QDitherInfo *)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
buffer[i] = qPremultiply(QCmyk32::fromCmyk32(src[i]).toColor().rgba64());
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const uint *QT_FASTCALL fetchCMYK32ToARGB32PM(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] = qPremultiply(QCmyk32::fromCmyk32(s[i]).toColor().rgba());
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const QRgba64 *QT_FASTCALL fetchCMYK32ToRGBA64PM(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] = qPremultiply(QCmyk32::fromCmyk32(s[i]).toColor().rgba64());
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void QT_FASTCALL storeCMYKFromARGB32PM(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 storeCMYKFromRGB32(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:
|
// Note:
|
||||||
// convertToArgb32() assumes that no color channel is less than 4 bits.
|
// convertToArgb32() assumes that no color channel is less than 4 bits.
|
||||||
// storeRGBFromARGB32PM() assumes that no color channel is more than 8 bits.
|
// storeRGBFromARGB32PM() assumes that no color channel is more than 8 bits.
|
||||||
@ -1779,6 +1840,10 @@ QPixelLayout qPixelLayouts[] = {
|
|||||||
convertPassThrough, nullptr,
|
convertPassThrough, nullptr,
|
||||||
fetchRGB32FToRGB32, fetchRGBA32FPMToRGBA64PM,
|
fetchRGB32FToRGB32, fetchRGBA32FPMToRGBA64PM,
|
||||||
storeRGB32FFromRGB32, storeRGB32FFromRGB32 }, // Format_RGBA32FPx4_Premultiplied
|
storeRGB32FFromRGB32, storeRGB32FFromRGB32 }, // Format_RGBA32FPx4_Premultiplied
|
||||||
|
{ false, false, QPixelLayout::BPP32, nullptr,
|
||||||
|
convertCMYK32ToARGB32PM, convertCMYK32ToToRGBA64PM,
|
||||||
|
fetchCMYK32ToARGB32PM, fetchCMYK32ToRGBA64PM,
|
||||||
|
storeCMYKFromARGB32PM, storeCMYKFromRGB32 }, // Format_CMYK32
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(std::size(qPixelLayouts) == QImage::NImageFormats);
|
static_assert(std::size(qPixelLayouts) == QImage::NImageFormats);
|
||||||
@ -1916,6 +1981,14 @@ static void QT_FASTCALL storeRGBA32FPMFromRGBA64PM(uchar *dest, const QRgba64 *s
|
|||||||
d[i] = qConvertRgb64ToRgbaF32(src[i]);
|
d[i] = qConvertRgb64ToRgbaF32(src[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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[] = {
|
ConvertAndStorePixelsFunc64 qStoreFromRGBA64PM[] = {
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
@ -1953,6 +2026,7 @@ ConvertAndStorePixelsFunc64 qStoreFromRGBA64PM[] = {
|
|||||||
storeRGBX32FFromRGBA64PM,
|
storeRGBX32FFromRGBA64PM,
|
||||||
storeRGBA32FFromRGBA64PM,
|
storeRGBA32FFromRGBA64PM,
|
||||||
storeRGBA32FPMFromRGBA64PM,
|
storeRGBA32FPMFromRGBA64PM,
|
||||||
|
storeCMYKFromRGBA64PM,
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(std::size(qStoreFromRGBA64PM) == QImage::NImageFormats);
|
static_assert(std::size(qStoreFromRGBA64PM) == QImage::NImageFormats);
|
||||||
@ -2002,6 +2076,15 @@ static const QRgbaFloat32 * QT_FASTCALL convertRGB30ToRGBA32F(QRgbaFloat32 *buff
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const QRgbaFloat32 * QT_FASTCALL convertCMYKToRGBA32F(QRgbaFloat32 *buffer, const uint *src, int count,
|
||||||
|
const QList<QRgb> *, QDitherInfo *)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
QRgbaFloat32::fromArgb32(QCmyk32::fromCmyk32(src[i]).toColor().rgba());
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
ConvertToFPFunc qConvertToRGBA32F[] = {
|
ConvertToFPFunc qConvertToRGBA32F[] = {
|
||||||
nullptr,
|
nullptr,
|
||||||
convertIndexedTo<QRgbaFloat32>,
|
convertIndexedTo<QRgbaFloat32>,
|
||||||
@ -2039,6 +2122,7 @@ ConvertToFPFunc qConvertToRGBA32F[] = {
|
|||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
|
convertCMYKToRGBA32F,
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(std::size(qConvertToRGBA32F) == QImage::NImageFormats);
|
static_assert(std::size(qConvertToRGBA32F) == QImage::NImageFormats);
|
||||||
@ -2107,6 +2191,16 @@ static const QRgbaFloat32 *QT_FASTCALL fetchRGBA32F(QRgbaFloat32 *, const uchar
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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[] = {
|
FetchAndConvertPixelsFuncFP qFetchToRGBA32F[] = {
|
||||||
nullptr,
|
nullptr,
|
||||||
fetchIndexedToRGBA32F<QPixelLayout::BPP1MSB>,
|
fetchIndexedToRGBA32F<QPixelLayout::BPP1MSB>,
|
||||||
@ -2144,6 +2238,7 @@ FetchAndConvertPixelsFuncFP qFetchToRGBA32F[] = {
|
|||||||
fetchRGBA32F,
|
fetchRGBA32F,
|
||||||
fetchRGBA32FToRGBA32F,
|
fetchRGBA32FToRGBA32F,
|
||||||
fetchRGBA32F,
|
fetchRGBA32F,
|
||||||
|
fetchCMYKToRGBA32F,
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(std::size(qFetchToRGBA32F) == QImage::NImageFormats);
|
static_assert(std::size(qFetchToRGBA32F) == QImage::NImageFormats);
|
||||||
@ -2284,6 +2379,16 @@ static void QT_FASTCALL storeRGBA32FPMFromRGBA32F(uchar *dest, const QRgbaFloat3
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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[] = {
|
ConvertAndStorePixelsFuncFP qStoreFromRGBA32F[] = {
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
@ -2321,6 +2426,7 @@ ConvertAndStorePixelsFuncFP qStoreFromRGBA32F[] = {
|
|||||||
storeRGBX32FFromRGBA32F,
|
storeRGBX32FFromRGBA32F,
|
||||||
storeRGBA32FFromRGBA32F,
|
storeRGBA32FFromRGBA32F,
|
||||||
storeRGBA32FPMFromRGBA32F,
|
storeRGBA32FPMFromRGBA32F,
|
||||||
|
storeCMYKFromRGBA32F,
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(std::size(qStoreFromRGBA32F) == QImage::NImageFormats);
|
static_assert(std::size(qStoreFromRGBA32F) == QImage::NImageFormats);
|
||||||
|
@ -321,7 +321,9 @@ static QLatin1String formatToString(QImage::Format format)
|
|||||||
return QLatin1String("RGBA32FPx4");
|
return QLatin1String("RGBA32FPx4");
|
||||||
case QImage::Format_RGBA32FPx4_Premultiplied:
|
case QImage::Format_RGBA32FPx4_Premultiplied:
|
||||||
return QLatin1String("RGBA32FPx4pm");
|
return QLatin1String("RGBA32FPx4pm");
|
||||||
default:
|
case QImage::Format_CMYK32:
|
||||||
|
return QLatin1String("CMYK32");
|
||||||
|
case QImage::NImageFormats:
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
@ -1507,6 +1509,8 @@ void tst_QImage::setPixelWithAlpha_data()
|
|||||||
continue;
|
continue;
|
||||||
if (c == QImage::Format_Alpha8)
|
if (c == QImage::Format_Alpha8)
|
||||||
continue;
|
continue;
|
||||||
|
if (c == QImage::Format_CMYK32)
|
||||||
|
continue;
|
||||||
QTest::newRow(qPrintable(formatToString(QImage::Format(c)))) << QImage::Format(c);
|
QTest::newRow(qPrintable(formatToString(QImage::Format(c)))) << QImage::Format(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2568,7 +2572,8 @@ void tst_QImage::rgbSwapped_data()
|
|||||||
for (int i = QImage::Format_Indexed8; i < QImage::NImageFormats; ++i) {
|
for (int i = QImage::Format_Indexed8; i < QImage::NImageFormats; ++i) {
|
||||||
if (i == QImage::Format_Alpha8
|
if (i == QImage::Format_Alpha8
|
||||||
|| i == QImage::Format_Grayscale8
|
|| i == QImage::Format_Grayscale8
|
||||||
|| i == QImage::Format_Grayscale16) {
|
|| i == QImage::Format_Grayscale16
|
||||||
|
|| i == QImage::Format_CMYK32) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
QTest::addRow("%s", formatToString(QImage::Format(i)).data()) << QImage::Format(i);
|
QTest::addRow("%s", formatToString(QImage::Format(i)).data()) << QImage::Format(i);
|
||||||
@ -3050,13 +3055,15 @@ void tst_QImage::inplaceRgbConversion_data()
|
|||||||
for (int i = QImage::Format_RGB32; i < QImage::NImageFormats; ++i) {
|
for (int i = QImage::Format_RGB32; i < QImage::NImageFormats; ++i) {
|
||||||
if (i == QImage::Format_Alpha8
|
if (i == QImage::Format_Alpha8
|
||||||
|| i == QImage::Format_Grayscale8
|
|| i == QImage::Format_Grayscale8
|
||||||
|| i == QImage::Format_Grayscale16) {
|
|| i == QImage::Format_Grayscale16
|
||||||
|
|| i == QImage::Format_CMYK32) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (int j = QImage::Format_RGB32; j < QImage::NImageFormats; ++j) {
|
for (int j = QImage::Format_RGB32; j < QImage::NImageFormats; ++j) {
|
||||||
if (j == QImage::Format_Alpha8
|
if (j == QImage::Format_Alpha8
|
||||||
|| j == QImage::Format_Grayscale8
|
|| j == QImage::Format_Grayscale8
|
||||||
|| j == QImage::Format_Grayscale16) {
|
|| j == QImage::Format_Grayscale16
|
||||||
|
|| j == QImage::Format_CMYK32) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (i == j)
|
if (i == j)
|
||||||
@ -3345,7 +3352,8 @@ void tst_QImage::invertPixelsRGB_data()
|
|||||||
for (int i = QImage::Format_RGB32; i < QImage::NImageFormats; ++i) {
|
for (int i = QImage::Format_RGB32; i < QImage::NImageFormats; ++i) {
|
||||||
if (i == QImage::Format_Alpha8
|
if (i == QImage::Format_Alpha8
|
||||||
|| i == QImage::Format_Grayscale8
|
|| i == QImage::Format_Grayscale8
|
||||||
|| i == QImage::Format_Grayscale16) {
|
|| i == QImage::Format_Grayscale16
|
||||||
|
|| i == QImage::Format_CMYK32) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
QTest::addRow("%s", formatToString(QImage::Format(i)).data()) << QImage::Format(i);
|
QTest::addRow("%s", formatToString(QImage::Format(i)).data()) << QImage::Format(i);
|
||||||
|
@ -2784,7 +2784,7 @@ void tst_QPainter::monoImages()
|
|||||||
for (int i = 1; i < QImage::NImageFormats; ++i) {
|
for (int i = 1; i < QImage::NImageFormats; ++i) {
|
||||||
for (int j = 0; j < numColorPairs; ++j) {
|
for (int j = 0; j < numColorPairs; ++j) {
|
||||||
const QImage::Format format = QImage::Format(i);
|
const QImage::Format format = QImage::Format(i);
|
||||||
if (format == QImage::Format_Indexed8)
|
if (format == QImage::Format_Indexed8 || format == QImage::Format_CMYK32)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
QImage img(2, 2, format);
|
QImage img(2, 2, format);
|
||||||
@ -3554,9 +3554,13 @@ void tst_QPainter::drawImage_data()
|
|||||||
|
|
||||||
for (int srcFormat = QImage::Format_Mono; srcFormat < QImage::NImageFormats; ++srcFormat) {
|
for (int srcFormat = QImage::Format_Mono; srcFormat < QImage::NImageFormats; ++srcFormat) {
|
||||||
for (int dstFormat = QImage::Format_Mono; dstFormat < QImage::NImageFormats; ++dstFormat) {
|
for (int dstFormat = QImage::Format_Mono; dstFormat < QImage::NImageFormats; ++dstFormat) {
|
||||||
// Indexed8 can't be painted to, and Alpha8 can't hold a color.
|
// Indexed8 and CMYK32 can't be painted to, and Alpha8 can't hold a color.
|
||||||
if (dstFormat == QImage::Format_Indexed8 || dstFormat == QImage::Format_Alpha8)
|
if (dstFormat == QImage::Format_Indexed8 ||
|
||||||
|
dstFormat == QImage::Format_CMYK32 ||
|
||||||
|
dstFormat == QImage::Format_Alpha8) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (int odd_x = 0; odd_x <= 1; ++odd_x) {
|
for (int odd_x = 0; odd_x <= 1; ++odd_x) {
|
||||||
for (int odd_width = 0; odd_width <= 1; ++odd_width) {
|
for (int odd_width = 0; odd_width <= 1; ++odd_width) {
|
||||||
QTest::addRow("srcFormat %d, dstFormat %d, odd x: %d, odd width: %d",
|
QTest::addRow("srcFormat %d, dstFormat %d, odd x: %d, odd width: %d",
|
||||||
|
@ -173,6 +173,7 @@ const char *PaintCommands::imageFormatTable[] = {
|
|||||||
"RGBx32FPx4",
|
"RGBx32FPx4",
|
||||||
"RGBA32FPx4",
|
"RGBA32FPx4",
|
||||||
"RGBA32FPx4_Premultiplied",
|
"RGBA32FPx4_Premultiplied",
|
||||||
|
"CMYK32",
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *PaintCommands::renderHintTable[] = {
|
const char *PaintCommands::renderHintTable[] = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user