diff --git a/src/plugins/imageformats/dds/ddsheader.h b/src/plugins/imageformats/dds/ddsheader.h index 7f6df0613e9adc9c95dbab563f2ce0f1115be7b7..7b2b80ce1f15cbb3169d321ed0755bfb7f7d2f3f 100644 --- a/src/plugins/imageformats/dds/ddsheader.h +++ b/src/plugins/imageformats/dds/ddsheader.h @@ -134,6 +134,9 @@ enum Format { FormatA2B10G10R10_XR_BIAS = 119, FormatBinaryBuffer = 199, + FormatP4, + FormatA4P4, + FormatLast = 0x7fffffff }; @@ -143,6 +146,7 @@ struct DDSPixelFormat FlagAlphaPixels = 0x00000001, FlagAlpha = 0x00000002, FlagFourCC = 0x00000004, + FlagPaletteIndexed4 = 0x00000008, FlagPaletteIndexed8 = 0x00000020, FlagRGB = 0x00000040, FlagYUV = 0x00000200, diff --git a/src/plugins/imageformats/dds/qddshandler.cpp b/src/plugins/imageformats/dds/qddshandler.cpp index c85e75d2fe957e2bd51c100a039053b6ee82a8ec..13bb9aafb77121e8fb56242bafdc658acdbf915b 100644 --- a/src/plugins/imageformats/dds/qddshandler.cpp +++ b/src/plugins/imageformats/dds/qddshandler.cpp @@ -221,7 +221,11 @@ static inline QRgb yuv2rgb(quint8 Y, quint8 U, quint8 V) static Format getFormat(const DDSHeader &dds) { const DDSPixelFormat &format = dds.pixelFormat; - if (format.flags & DDSPixelFormat::FlagFourCC) { + if (format.flags & DDSPixelFormat::FlagPaletteIndexed4) { + return FormatP4; + } else if (format.flags & DDSPixelFormat::FlagPaletteIndexed8) { + return FormatP8; + } else if (format.flags & DDSPixelFormat::FlagFourCC) { for (size_t i = 0; i < knownFourCCsSize; ++i) { if (dds.pixelFormat.fourCC == knownFourCCs[i]) return knownFourCCs[i]; @@ -729,7 +733,7 @@ static QImage readCxV8U8(QDataStream &s, const quint32 width, const quint32 heig return image; } -static QImage readPaletteImage(QDataStream &s, quint32 width, quint32 height) +static QImage readPalette8Image(QDataStream &s, quint32 width, quint32 height) { QImage image(width, height, QImage::Format_Indexed8); for (int i = 0; i < 256; ++i) { @@ -749,6 +753,31 @@ static QImage readPaletteImage(QDataStream &s, quint32 width, quint32 height) return image; } +static QImage readPalette4Image(QDataStream &s, quint32 width, quint32 height) +{ + QImage image(width, height, QImage::Format_Indexed8); + for (int i = 0; i < 16; ++i) { + quint8 r, g, b, a; + s >> r >> g >> b >> a; + image.setColor(i, qRgba(r, g, b, a)); + } + + for (quint32 y = 0; y < height; y++) { + quint8 index; + for (quint32 x = 0; x < width - 1; ) { + s >> index; + image.setPixel(x++, y, (index & 0x0f) >> 0); + image.setPixel(x++, y, (index & 0xf0) >> 4); + } + if (width % 2 == 1) { + s >> index; + image.setPixel(width - 1, y, (index & 0x0f) >> 0); + } + } + + return image; +} + static QImage readARGB16(QDataStream &s, quint32 width, quint32 height) { QImage image(width, height, QImage::Format_ARGB32); @@ -1004,9 +1033,11 @@ static QImage readLayer(QDataStream &s, const DDSHeader &dds, const int format, case FormatA2B10G10R10: return readA2R10G10B10(s, dds, width, height); case FormatP8: - return readPaletteImage(s, width, height); case FormatA8P8: - break; + return readPalette8Image(s, width, height); + case FormatP4: + case FormatA4P4: + return readPalette4Image(s, width, height); case FormatA16B16G16R16: return readARGB16(s, width, height); case FormatV8U8: diff --git a/tests/auto/dds/tst_qdds.cpp b/tests/auto/dds/tst_qdds.cpp index 4464b991d2c65985c084ef1b05bfca51632de78d..eb2584975c79e88cb0d4f451839de2d4528b2afc 100644 --- a/tests/auto/dds/tst_qdds.cpp +++ b/tests/auto/dds/tst_qdds.cpp @@ -108,6 +108,7 @@ void tst_qdds::readImage_data() QTest::newRow("45") << QString("YUY2") << QSize(64, 64); QTest::newRow("46") << QString("RXGB") << QSize(64, 64); QTest::newRow("47") << QString("ATI2") << QSize(64, 64); + QTest::newRow("48") << QString("P4") << QSize(64, 64); } void tst_qdds::readImage() diff --git a/tests/shared/images/dds.qrc b/tests/shared/images/dds.qrc index e19eee95956c01b14f46b6030f245088f807bade..128a38dee0068f552f38ec641f843a83032d9c44 100644 --- a/tests/shared/images/dds.qrc +++ b/tests/shared/images/dds.qrc @@ -28,6 +28,7 @@ <file>dds/L8.dds</file> <file>dds/L16.dds</file> <file>dds/mipmaps.dds</file> + <file>dds/P4.dds</file> <file>dds/P8.dds</file> <file>dds/Q8W8V8U8.dds</file> <file>dds/Q16W16V16U16.dds</file> diff --git a/tests/shared/images/dds/P4.dds b/tests/shared/images/dds/P4.dds new file mode 100644 index 0000000000000000000000000000000000000000..c8c3e904bf3666cd1caae80f8784899769712311 Binary files /dev/null and b/tests/shared/images/dds/P4.dds differ diff --git a/tests/shared/images/dds/P8.dds b/tests/shared/images/dds/P8.dds index 936b870318f85c737daf8bbab821394c44e7c449..4bef9ec321f1b02e59b770285a2621c578c83134 100644 Binary files a/tests/shared/images/dds/P8.dds and b/tests/shared/images/dds/P8.dds differ