diff options
Diffstat (limited to 'src/gui/painting')
-rw-r--r-- | src/gui/painting/qcolorspace.cpp | 1 | ||||
-rw-r--r-- | src/gui/painting/qcolortransfertable_p.h | 8 | ||||
-rw-r--r-- | src/gui/painting/qcolortrc_p.h | 2 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper.cpp | 22 | ||||
-rw-r--r-- | src/gui/painting/qicc.cpp | 29 | ||||
-rw-r--r-- | src/gui/painting/qmemrotate.cpp | 42 | ||||
-rw-r--r-- | src/gui/painting/qpainterpath.cpp | 2 | ||||
-rw-r--r-- | src/gui/painting/qpainterpath_p.h | 1 | ||||
-rw-r--r-- | src/gui/painting/qtriangulatingstroker.cpp | 1 |
9 files changed, 62 insertions, 46 deletions
diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp index bce66ca3c5..8b2ea4e04d 100644 --- a/src/gui/painting/qcolorspace.cpp +++ b/src/gui/painting/qcolorspace.cpp @@ -331,6 +331,7 @@ void QColorSpacePrivate::setTransferFunction() } trc[1] = trc[0]; trc[2] = trc[0]; + lut.generated.storeRelease(0); } QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpacePrivate *out) const diff --git a/src/gui/painting/qcolortransfertable_p.h b/src/gui/painting/qcolortransfertable_p.h index 75a2e90288..d6b514193d 100644 --- a/src/gui/painting/qcolortransfertable_p.h +++ b/src/gui/painting/qcolortransfertable_p.h @@ -138,7 +138,7 @@ public: return 1.0f; if (!m_table16.isEmpty()) { float v = x * 65535.0f; - uint32_t i = std::floor(resultLargerThan * (m_tableSize - 1)) + 1; + uint32_t i = std::floor(resultLargerThan * (m_tableSize - 1)); for ( ; i < m_tableSize; ++i) { if (m_table16[i] > v) break; @@ -147,14 +147,14 @@ public: return 1.0f; float y1 = m_table16[i - 1]; float y2 = m_table16[i]; - Q_ASSERT(x >= y1 && x < y2); + Q_ASSERT(v >= y1 && v <= y2); float fr = (v - y1) / (y2 - y1); return (i + fr) * (1.0f / (m_tableSize - 1)); } if (!m_table8.isEmpty()) { float v = x * 255.0f; - uint32_t i = std::floor(resultLargerThan * (m_tableSize - 1)) + 1; + uint32_t i = std::floor(resultLargerThan * (m_tableSize - 1)); for ( ; i < m_tableSize; ++i) { if (m_table8[i] > v) break; @@ -163,7 +163,7 @@ public: return 1.0f; float y1 = m_table8[i - 1]; float y2 = m_table8[i]; - Q_ASSERT(x >= y1 && x < y2); + Q_ASSERT(v >= y1 && v <= y2); float fr = (v - y1) / (y2 - y1); return (i + fr) * (1.0f / (m_tableSize - 1)); } diff --git a/src/gui/painting/qcolortrc_p.h b/src/gui/painting/qcolortrc_p.h index 3ef9d442fc..058be3c7ce 100644 --- a/src/gui/painting/qcolortrc_p.h +++ b/src/gui/painting/qcolortrc_p.h @@ -114,7 +114,7 @@ public: if (x >= 0.0f && x <= 1.0f) return applyInverse(x); if (m_type == Type::Function) - return std::copysign(applyInverse(x), x); + return std::copysign(applyInverse(std::abs(x)), x); if (m_type == Type::Table) return x < 0.0f ? 0.0f : 1.0f; return x; diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 1409c70a0a..a61793508a 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1419,7 +1419,7 @@ static void QT_FASTCALL storeRGB64FromRGB32(uchar *dest, const uint *src, int in { QRgba64 *d = reinterpret_cast<QRgba64 *>(dest) + index; for (int i = 0; i < count; ++i) - d[i] = QRgba64::fromArgb32(src[i]); + d[i] = QRgba64::fromArgb32(src[i] | 0xff000000); } static const uint *QT_FASTCALL fetchRGBA64ToARGB32PM(uint *buffer, const uchar *src, int index, int count, @@ -1431,12 +1431,24 @@ static const uint *QT_FASTCALL fetchRGBA64ToARGB32PM(uint *buffer, const uchar * return buffer; } +template<bool Mask> static void QT_FASTCALL storeRGBA64FromARGB32PM(uchar *dest, const uint *src, int index, int count, const QVector<QRgb> *, QDitherInfo *) { QRgba64 *d = reinterpret_cast<QRgba64 *>(dest) + index; - for (int i = 0; i < count; ++i) + for (int i = 0; i < count; ++i) { d[i] = QRgba64::fromArgb32(src[i]).unpremultiplied(); + if (Mask) + d[i].setAlpha(65535); + } +} + +static void QT_FASTCALL storeRGBA64FromARGB32(uchar *dest, const uint *src, int index, int count, + const QVector<QRgb> *, QDitherInfo *) +{ + QRgba64 *d = reinterpret_cast<QRgba64 *>(dest) + index; + for (int i = 0; i < count; ++i) + d[i] = QRgba64::fromArgb32(src[i]); } // Note: @@ -1523,15 +1535,15 @@ QPixelLayout qPixelLayouts[QImage::NImageFormats] = { { false, false, QPixelLayout::BPP64, nullptr, convertPassThrough, nullptr, fetchRGB64ToRGB32, fetchPassThrough64, - storeRGB64FromRGB32, storeRGB64FromRGB32 }, // Format_RGBX64 + storeRGBA64FromARGB32PM<true>, storeRGB64FromRGB32 }, // Format_RGBX64 { true, false, QPixelLayout::BPP64, nullptr, convertARGB32ToARGB32PM, nullptr, fetchRGBA64ToARGB32PM, fetchRGBA64ToRGBA64PM, - storeRGBA64FromARGB32PM, storeRGB64FromRGB32 }, // Format_RGBA64 + storeRGBA64FromARGB32PM<false>, storeRGB64FromRGB32 }, // Format_RGBA64 { true, true, QPixelLayout::BPP64, nullptr, convertPassThrough, nullptr, fetchRGB64ToRGB32, fetchPassThrough64, - storeRGB64FromRGB32, storeRGB64FromRGB32 }, // Format_RGBA64_Premultiplied + storeRGBA64FromARGB32, storeRGB64FromRGB32 }, // Format_RGBA64_Premultiplied { false, false, QPixelLayout::BPP16, nullptr, convertGrayscale16ToRGB32, convertGrayscale16ToRGBA64, fetchGrayscale16ToRGB32, fetchGrayscale16ToRGBA64, diff --git a/src/gui/painting/qicc.cpp b/src/gui/painting/qicc.cpp index 9209f7ecb0..15e236ac9e 100644 --- a/src/gui/painting/qicc.cpp +++ b/src/gui/painting/qicc.cpp @@ -52,7 +52,7 @@ #include <array> QT_BEGIN_NAMESPACE -Q_LOGGING_CATEGORY(lcIcc, "qt.gui.icc") +Q_LOGGING_CATEGORY(lcIcc, "qt.gui.icc", QtWarningMsg) struct ICCProfileHeader { @@ -165,7 +165,7 @@ struct XYZTagData : GenericTagData { struct CurvTagData : GenericTagData { quint32_be valueCount; - quint16_be value[1]; + // followed by curv values: quint16_be[] }; struct ParaTagData : GenericTagData { @@ -237,18 +237,20 @@ static bool isValidIccProfile(const ICCProfileHeader &header) } if (header.profileClass != uint(ProfileClass::Input) - && header.profileClass != uint(ProfileClass::Display)) { - qCWarning(lcIcc, "Unsupported ICC profile class %x", quint32(header.profileClass)); + && header.profileClass != uint(ProfileClass::Display) + && (header.profileClass != uint(ProfileClass::Output) + || header.inputColorSpace != uint(ColorSpaceType::Gray))) { + qCInfo(lcIcc, "Unsupported ICC profile class 0x%x", quint32(header.profileClass)); return false; } if (header.inputColorSpace != uint(ColorSpaceType::Rgb) && header.inputColorSpace != uint(ColorSpaceType::Gray)) { - qCWarning(lcIcc, "Unsupported ICC input color space %x", quint32(header.inputColorSpace)); + qCInfo(lcIcc, "Unsupported ICC input color space 0x%x", quint32(header.inputColorSpace)); return false; } if (header.pcs != 0x58595a20 /* 'XYZ '*/) { // ### support PCSLAB - qCWarning(lcIcc, "Unsupported ICC profile connection space %x", quint32(header.pcs)); + qCInfo(lcIcc, "Unsupported ICC profile connection space 0x%x", quint32(header.pcs)); return false; } @@ -468,25 +470,26 @@ bool parseTRC(const QByteArray &data, const TagEntry &tagEntry, QColorTrc &gamma const GenericTagData trcData = qFromUnaligned<GenericTagData>(data.constData() + tagEntry.offset); if (trcData.type == quint32(Tag::curv)) { + Q_STATIC_ASSERT(sizeof(CurvTagData) == 12); const CurvTagData curv = qFromUnaligned<CurvTagData>(data.constData() + tagEntry.offset); if (curv.valueCount > (1 << 16)) return false; if (tagEntry.size - 12 < 2 * curv.valueCount) return false; + const auto valueOffset = tagEntry.offset + sizeof(CurvTagData); if (curv.valueCount == 0) { gamma.m_type = QColorTrc::Type::Function; gamma.m_fun = QColorTransferFunction(); // Linear } else if (curv.valueCount == 1) { - float g = curv.value[0] * (1.0f / 256.0f); + const quint16 v = qFromBigEndian<quint16>(data.constData() + valueOffset); gamma.m_type = QColorTrc::Type::Function; - gamma.m_fun = QColorTransferFunction::fromGamma(g); + gamma.m_fun = QColorTransferFunction::fromGamma(v * (1.0f / 256.0f)); } else { QVector<quint16> tabl; tabl.resize(curv.valueCount); static_assert(sizeof(GenericTagData) == 2 * sizeof(quint32_be), "GenericTagData has padding. The following code is a subject to UB."); - const auto offset = tagEntry.offset + sizeof(GenericTagData) + sizeof(quint32_be); - qFromBigEndian<quint16>(data.constData() + offset, curv.valueCount, tabl.data()); + qFromBigEndian<quint16>(data.constData() + valueOffset, curv.valueCount, tabl.data()); QColorTransferTable table = QColorTransferTable(curv.valueCount, std::move(tabl)); QColorTransferFunction curve; if (!table.checkValidity()) { @@ -702,7 +705,7 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace) if (!tagIndex.contains(Tag::rXYZ) || !tagIndex.contains(Tag::gXYZ) || !tagIndex.contains(Tag::bXYZ) || !tagIndex.contains(Tag::rTRC) || !tagIndex.contains(Tag::gTRC) || !tagIndex.contains(Tag::bTRC) || !tagIndex.contains(Tag::wtpt)) { - qCWarning(lcIcc) << "fromIccProfile: Unsupported ICC profile - not three component matrix based"; + qCInfo(lcIcc) << "fromIccProfile: Unsupported ICC profile - not three component matrix based"; return false; } } else { @@ -756,12 +759,12 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace) } else { colorspaceDPtr->primaries = QColorSpace::Primaries::Custom; // Calculate chromaticity from xyz (assuming y == 1.0f). - float y = 1.0f / (1.0f + whitePoint.z - whitePoint.x); + float y = 1.0f / (1.0f + whitePoint.z + whitePoint.x); float x = whitePoint.x * y; QColorSpacePrimaries primaries(QColorSpace::Primaries::SRgb); primaries.whitePoint = QPointF(x,y); if (!primaries.areValid()) { - qCWarning(lcIcc) << "fromIccProfile: Invalid ICC profile - invalid white-point"; + qCWarning(lcIcc, "fromIccProfile: Invalid ICC profile - invalid white-point(%f, %f)", x, y); return false; } colorspaceDPtr->toXyz = primaries.toXyzMatrix(); diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp index 685fbbb37a..b82adb5d35 100644 --- a/src/gui/painting/qmemrotate.cpp +++ b/src/gui/painting/qmemrotate.cpp @@ -43,12 +43,11 @@ QT_BEGIN_NAMESPACE static const int tileSize = 32; -template <class T> -static -inline void qt_memrotate90_tiled(const T *src, int w, int h, int sstride, T *dest, int dstride) +template<class T> +static inline void qt_memrotate90_tiled(const T *src, int w, int h, int isstride, T *dest, int idstride) { - sstride /= sizeof(T); - dstride /= sizeof(T); + const qsizetype sstride = isstride / sizeof(T); + const qsizetype dstride = idstride / sizeof(T); const int pack = sizeof(quint32) / sizeof(T); const int unaligned = @@ -102,11 +101,11 @@ inline void qt_memrotate90_tiled(const T *src, int w, int h, int sstride, T *des } } -template <class T> -static -inline void qt_memrotate90_tiled_unpacked(const T *src, int w, int h, int sstride, T *dest, - int dstride) +template<class T> +static inline void qt_memrotate90_tiled_unpacked(const T *src, int w, int h, int isstride, T *dest, int idstride) { + const qsizetype sstride = isstride; + const qsizetype dstride = idstride; const int numTilesX = (w + tileSize - 1) / tileSize; const int numTilesY = (h + tileSize - 1) / tileSize; @@ -130,12 +129,11 @@ inline void qt_memrotate90_tiled_unpacked(const T *src, int w, int h, int sstrid } } -template <class T> -static -inline void qt_memrotate270_tiled(const T *src, int w, int h, int sstride, T *dest, int dstride) +template<class T> +static inline void qt_memrotate270_tiled(const T *src, int w, int h, int isstride, T *dest, int idstride) { - sstride /= sizeof(T); - dstride /= sizeof(T); + const qsizetype sstride = isstride / sizeof(T); + const qsizetype dstride = idstride / sizeof(T); const int pack = sizeof(quint32) / sizeof(T); const int unaligned = @@ -189,11 +187,11 @@ inline void qt_memrotate270_tiled(const T *src, int w, int h, int sstride, T *de } } -template <class T> -static -inline void qt_memrotate270_tiled_unpacked(const T *src, int w, int h, int sstride, T *dest, - int dstride) +template<class T> +static inline void qt_memrotate270_tiled_unpacked(const T *src, int w, int h, int isstride, T *dest, int idstride) { + const qsizetype sstride = isstride; + const qsizetype dstride = idstride; const int numTilesX = (w + tileSize - 1) / tileSize; const int numTilesY = (h + tileSize - 1) / tileSize; @@ -245,10 +243,12 @@ inline void qt_memrotate90_template<quint64>(const quint64 *src, int w, int h, i qt_memrotate90_tiled_unpacked(src, w, h, sstride, dest, dstride); } -template <class T> -static -inline void qt_memrotate180_template(const T *src, int w, int h, int sstride, T *dest, int dstride) +template<class T> +static inline void qt_memrotate180_template(const T *src, int w, int h, int isstride, T *dest, int idstride) { + const qsizetype sstride = isstride; + const qsizetype dstride = idstride; + const char *s = (const char*)(src) + (h - 1) * sstride; for (int dy = 0; dy < h; ++dy) { T *d = reinterpret_cast<T*>((char *)(dest) + dy * dstride); diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index c61b62fcb2..f9544a3241 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -1372,7 +1372,7 @@ void QPainterPath::addRegion(const QRegion ®ion) */ Qt::FillRule QPainterPath::fillRule() const { - return isEmpty() ? Qt::OddEvenFill : d_func()->fillRule; + return !d_func() ? Qt::OddEvenFill : d_func()->fillRule; } /*! diff --git a/src/gui/painting/qpainterpath_p.h b/src/gui/painting/qpainterpath_p.h index a420e0b3d9..287265653a 100644 --- a/src/gui/painting/qpainterpath_p.h +++ b/src/gui/painting/qpainterpath_p.h @@ -313,7 +313,6 @@ inline void QPainterPathData::clear() elements.clear(); cStart = 0; - fillRule = Qt::OddEvenFill; bounds = {}; controlBounds = {}; diff --git a/src/gui/painting/qtriangulatingstroker.cpp b/src/gui/painting/qtriangulatingstroker.cpp index 9490e11dd9..bdcf49d6c8 100644 --- a/src/gui/painting/qtriangulatingstroker.cpp +++ b/src/gui/painting/qtriangulatingstroker.cpp @@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE void QTriangulatingStroker::endCapOrJoinClosed(const qreal *start, const qreal *cur, bool implicitClose, bool endsAtStart) { + Q_ASSERT(start); if (endsAtStart) { join(start + 2); } else if (implicitClose) { |