diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index a24d7ccde75..8998db301d2 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -4693,6 +4693,8 @@ QImage QImage::smoothScaled(int w, int h) const src.convertTo(QImage::Format_RGBA32FPx4_Premultiplied); break; #endif + case QImage::Format_CMYK8888: + break; default: if (src.hasAlphaChannel()) src.convertTo(QImage::Format_ARGB32_Premultiplied); @@ -4835,6 +4837,9 @@ QImage Q_TRACE_INSTRUMENT(qtgui) QImage::transformed(const QTransform &matrix, Q // with scaling smoothly more than 2x down. if (hd * 2 < hs || wd * 2 < ws) nonpaintable_scale_xform = true; + // We cannot paint on a CMYK image, so don't try to do so + if (format() == QImage::Format_CMYK8888) + nonpaintable_scale_xform = true; } else { if (mat.type() <= QTransform::TxRotate && mat.m11() == 0 && mat.m22() == 0) { if (mat.m12() == 1. && mat.m21() == -1.) @@ -4866,6 +4871,7 @@ QImage Q_TRACE_INSTRUMENT(qtgui) QImage::transformed(const QTransform &matrix, Q case QImage::Format_RGBX64: case QImage::Format_RGBA64_Premultiplied: #endif + case QImage::Format_CMYK8888: // Use smoothScaled for scaling when we can do so without conversion. if (mat.m11() > 0.0F && mat.m22() > 0.0F) return smoothScaled(wd, hd); @@ -4936,7 +4942,7 @@ QImage Q_TRACE_INSTRUMENT(qtgui) QImage::transformed(const QTransform &matrix, Q } else memset(dImage.bits(), 0x00, dImage.d->nbytes); - if (target_format >= QImage::Format_RGB32) { + if (target_format >= QImage::Format_RGB32 && target_format != QImage::Format_CMYK8888) { // Prevent QPainter from applying devicePixelRatio corrections QImage sImage = (devicePixelRatio() != 1) ? QImage(constBits(), width(), height(), format()) : *this; if (sImage.d != d diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp index a636635fd5d..eb5f12389fd 100644 --- a/src/gui/painting/qimagescale.cpp +++ b/src/gui/painting/qimagescale.cpp @@ -1208,7 +1208,7 @@ QImage qSmoothScaleImage(const QImage &src, int dw, int dh) dw, dh, dw, src.bytesPerLine() / 8); else #endif - if (src.hasAlphaChannel()) + if (src.hasAlphaChannel() || src.format() == QImage::Format_CMYK8888) qt_qimageScaleAARGBA(scaleinfo, (unsigned int *)buffer.scanLine(0), dw, dh, dw, src.bytesPerLine() / 4); else diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 3e3d0a49bc0..9d3311c13c9 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -110,6 +111,8 @@ private slots: void smoothScaleFormats(); void smoothScaleNoConversion_data(); void smoothScaleNoConversion(); + void smoothScale_CMYK_data(); + void smoothScale_CMYK(); void transformed_data(); void transformed(); @@ -2091,6 +2094,76 @@ void tst_QImage::smoothScaleNoConversion() QVERIFY(img.hasAlphaChannel()); } +void tst_QImage::smoothScale_CMYK_data() +{ + QTest::addColumn("size"); + + const int sizes[] = { 2, 3, 4, 6, 7, 8, 10, 16, 20, 32, 40, 64, 100, 101, 128 }; + for (int size : sizes) + QTest::addRow("%d x %d", size, size) << size; +} + +void tst_QImage::smoothScale_CMYK() +{ + QFETCH(int, size); + QImage img(size, size, QImage::Format_CMYK8888); + QCmyk32 expected(31, 63, 127, 127); + img.fill(expected.toUint()); + + auto getCmykPixel = [](const QImage &image, int x, int y) { + Q_ASSERT(image.format() == QImage::Format_CMYK8888); + const uint *line = reinterpret_cast(image.scanLine(y)); + const uint pixel = line[x]; + return QCmyk32::fromCmyk32(pixel); + }; + + // scale x down, y down + QImage scaled = img.scaled(QSize(1, 1), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + QCmyk32 pixel = getCmykPixel(scaled, 0, 0); + QCOMPARE(pixel, expected); + + // scale x down, y up + scaled = img.scaled(QSize(1, size * 2), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + for (int y = 0; y < scaled.height(); ++y) { + pixel = getCmykPixel(scaled, 0, y); + QCOMPARE(pixel, expected); + } + + // scale x up, y down + scaled = img.scaled(QSize(size * 2, 1), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + for (int x = 0; x < scaled.width(); ++x) { + pixel = getCmykPixel(scaled, x, 0); + QCOMPARE(pixel, expected); + } + + // scale x up + scaled = img.scaled(QSize(size, size * 2), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + for (int y = 0; y < scaled.height(); ++y) { + for (int x = 0; x < scaled.width(); ++x) { + pixel = getCmykPixel(scaled, x, y); + QCOMPARE(pixel, expected); + } + } + + // scale y up + scaled = img.scaled(QSize(size * 2, size), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + for (int y = 0; y < scaled.height(); ++y) { + for (int x = 0; x < scaled.width(); ++x) { + pixel = getCmykPixel(scaled, x, y); + QCOMPARE(pixel, expected); + } + } + + // scale x up, y up + scaled = img.scaled(QSize(size * 2, size * 2), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + for (int y = 0; y < scaled.height(); ++y) { + for (int x = 0; x < scaled.width(); ++x) { + pixel = getCmykPixel(scaled, x, y); + QCOMPARE(pixel, expected); + } + } +} + static int count(const QImage &img, int x, int y, int dx, int dy, QRgb pixel) { int i = 0;