diff --git a/autotests/read/dds/earth-cubemap.dds b/autotests/read/dds/earth-cubemap.dds new file mode 100644 index 0000000..5f884de Binary files /dev/null and b/autotests/read/dds/earth-cubemap.dds differ diff --git a/autotests/read/dds/earth-cubemap.license b/autotests/read/dds/earth-cubemap.license new file mode 100644 index 0000000..52af9a8 --- /dev/null +++ b/autotests/read/dds/earth-cubemap.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright (c) 2006 - 2010 The Open Toolkit library. +SPDX-License-Identifier: MIT diff --git a/autotests/read/dds/earth-cubemap.png b/autotests/read/dds/earth-cubemap.png new file mode 100644 index 0000000..895bc6d Binary files /dev/null and b/autotests/read/dds/earth-cubemap.png differ diff --git a/autotests/readtest.cpp b/autotests/readtest.cpp index 4caf043..4c99256 100644 --- a/autotests/readtest.cpp +++ b/autotests/readtest.cpp @@ -263,7 +263,7 @@ int main(int argc, char **argv) } for (const QFileInfo &fi : lstImgDir) { TemplateImage timg(fi); - if (timg.isTemplate()) { + if (timg.isTemplate() || timg.isLicense()) { continue; } diff --git a/autotests/templateimage.cpp b/autotests/templateimage.cpp index 0a29710..f6a2479 100644 --- a/autotests/templateimage.cpp +++ b/autotests/templateimage.cpp @@ -28,6 +28,11 @@ bool TemplateImage::isTemplate() const return false; } +bool TemplateImage::isLicense() const +{ + return !m_fi.suffix().compare(QStringLiteral("license"), Qt::CaseInsensitive); +} + QFileInfo TemplateImage::compareImage(TestFlags &flags, QString& comment) const { auto fi = jsonImage(flags, comment); diff --git a/autotests/templateimage.h b/autotests/templateimage.h index 1674c29..5368982 100644 --- a/autotests/templateimage.h +++ b/autotests/templateimage.h @@ -47,6 +47,12 @@ public: */ bool isTemplate() const; + /*! + * \brief isLicense + * \return True if the file suffix is .license + */ + bool isLicense() const; + /*! * \brief compareImage * \param flags Flags for modifying test behavior (e.g. image format not supported by current Qt version). diff --git a/src/imageformats/dds.cpp b/src/imageformats/dds.cpp index 9cdffa5..efff7ba 100644 --- a/src/imageformats/dds.cpp +++ b/src/imageformats/dds.cpp @@ -403,6 +403,11 @@ QDataStream &operator<<(QDataStream &s, const DDSHeaderDX10 &header) return s; } +inline qsizetype ptrDiff(const void *end, const void *start) +{ + return qsizetype(reinterpret_cast(end) - reinterpret_cast(start)); +} + static inline int maskToShift(quint32 mask) { if (mask == 0) @@ -1633,9 +1638,16 @@ static QImage readCubeMap(QDataStream &s, const DDSHeader &dds, const int fmt) // Copy face on the image. for (quint32 y = 0; y < dds.height; y++) { - const QRgb *src = reinterpret_cast(face.scanLine(y)); + if (y + offset_y >= quint32(image.height())) { + return {}; + } + const QRgb *src = reinterpret_cast(face.constScanLine(y)); QRgb *dst = reinterpret_cast(image.scanLine(y + offset_y)) + offset_x; - memcpy(dst, src, sizeof(QRgb) * dds.width); + qsizetype sz = sizeof(QRgb) * dds.width; + if (ptrDiff(face.bits() + face.sizeInBytes(), src) < sz || ptrDiff(image.bits() + image.sizeInBytes(), dst) < sz) { + return {}; + } + memcpy(dst, src, sz); } } @@ -1777,7 +1789,7 @@ QVariant QDDSHandler::option(QImageIOHandler::ImageOption option) const switch (option) { case QImageIOHandler::Size: - return QSize(m_header.width, m_header.height); + return isCubeMap(m_header) ? QSize(m_header.width * 4, m_header.height * 3) : QSize(m_header.width, m_header.height); case QImageIOHandler::SubType: return formatName(m_format); case QImageIOHandler::SupportedSubTypes: