Re-added DDS plugin support

Fork of [Qt 5.6 DDS plugin](https://code.qt.io/cgit/qt/qtimageformats.git/tree/src/plugins/imageformats/dds/qddshandler.cpp?h=5.6) under LGPL2.1.

- Merged all files in dds_p.h and dds.cpp
- Added support for Qt 6 image allocation limit
- Added checks for null image and datastream errors
- The plugin is disabled by default

CCBUG: 380956

Closes: #12
This commit is contained in:
Mirco Miranda 2024-12-11 06:45:00 +00:00
parent a531978e2a
commit 87eff569a4
67 changed files with 2110 additions and 1 deletions

View File

@ -7,4 +7,4 @@ Dependencies:
Options:
test-before-installing: True
require-passing-tests-on: [ 'Linux', 'FreeBSD', 'Windows' ]
cmake-options: "-DKIMAGEFORMATS_JXR=ON"
cmake-options: "-DKIMAGEFORMATS_DDS=ON -DKIMAGEFORMATS_JXR=ON"

View File

@ -62,6 +62,9 @@ set_package_properties(libavif PROPERTIES
PURPOSE "Required for the QImage plugin for AVIF images"
)
# DDS plugin disabled by default due to security issues
option(KIMAGEFORMATS_DDS "Enable plugin for DDS format" OFF)
option(KIMAGEFORMATS_HEIF "Enable plugin for HEIF format" OFF)
if(KIMAGEFORMATS_HEIF)
pkg_check_modules(LibHeif IMPORTED_TARGET libheif>=1.10.0)
@ -82,6 +85,7 @@ set_package_properties(LibRaw PROPERTIES
PURPOSE "Required for the QImage plugin for RAW images"
)
# JXR plugin disabled by default due to security issues
option(KIMAGEFORMATS_JXR "Enable plugin for JPEG XR format" OFF)
if(KIMAGEFORMATS_JXR)
find_package(LibJXR)

View File

@ -28,6 +28,7 @@ The following image formats have read-only support:
The following image formats have read and write support:
- AV1 Image File Format (avif)
- DirectDraw Surface (dds)
- Encapsulated PostScript (eps)
- High Efficiency Image File Format (heif)
- JPEG XL (jxl)
@ -51,6 +52,8 @@ better to submit the plugin directly to the Qt Project.
## Duplicated Plugins
### The TGA plugin
The TGA plugin supports more formats than Qt's own TGA plugin;
specifically, the one provided here supports indexed, greyscale and RLE
images (types 1-3 and 9-11), while Qt's plugin only supports type 2
@ -61,6 +64,11 @@ licensing. If anyone were willing to write fresh code to improve Qt's
TGA plugin, it would allow the TGA plugin in this framework to be
removed.
### The DDS plugin
The DDS plugin is a fork from Qt 5.6. It will be activated once the
security issues are resolved.
## License
This framework is licensed under the
@ -114,6 +122,7 @@ plugin ('n/a' means no limit, i.e. the limit depends on the format encoding).
- ANI: n/a
- AVIF: 32,768 x 32,768 pixels, in any case no larger than 256 megapixels
- DDS: n/a
- EXR: 300,000 x 300,000 pixels
- HDR: n/a (large image)
- HEIF: n/a
@ -162,6 +171,11 @@ without using the ICC profile.
JXR, PSD and SCT plugins natively support 4-channel CMYK images when compiled
with Qt 6.8+.
### The DDS plugin
**This plugin is disabled by default. It can be enabled with the
`KIMAGEFORMATS_DDS` build option in the cmake file.**
### The HEIF plugin
**This plugin is disabled by default. It can be enabled with the

View File

@ -76,6 +76,11 @@ kimageformats_read_tests(
tga
)
if(KIMAGEFORMATS_DDS)
kimageformats_read_tests(dds)
kimageformats_write_tests(dds)
endif()
if (KF6Archive_FOUND)
kimageformats_read_tests(
kra

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
autotests/read/dds/rgba.dds Normal file

Binary file not shown.

BIN
autotests/read/dds/rgba.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -31,6 +31,12 @@ endif()
##################################
if(KIMAGEFORMATS_DDS)
kimageformats_add_plugin(kimg_dds SOURCES dds.cpp)
endif()
##################################
if (BUILD_EPS_PLUGIN)
if (TARGET Qt6::PrintSupport)
kimageformats_add_plugin(kimg_eps SOURCES eps.cpp)

1933
src/imageformats/dds.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
{
"Keys": [ "dds" ],
"MimeTypes": [ "image/x-dds" ]
}

143
src/imageformats/dds_p.h Normal file
View File

@ -0,0 +1,143 @@
/*
This file is part of the KDE project
SPDX-FileCopyrightText: 2015 The Qt Company Ltd
SPDX-FileCopyrightText: 2013 Ivan Komissarov
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only
*/
#ifndef QDDSHANDLER_H
#define QDDSHANDLER_H
#include <QImageIOPlugin>
struct DDSPixelFormat
{
enum DDSPixelFormatFlags {
FlagAlphaPixels = 0x00000001,
FlagAlpha = 0x00000002,
FlagFourCC = 0x00000004,
FlagPaletteIndexed4 = 0x00000008,
FlagPaletteIndexed8 = 0x00000020,
FlagRGB = 0x00000040,
FlagYUV = 0x00000200,
FlagLuminance = 0x00020000,
FlagNormal = 0x00080000,
FlagRGBA = FlagAlphaPixels | FlagRGB,
FlagLA = FlagAlphaPixels | FlagLuminance
};
quint32 size;
quint32 flags;
quint32 fourCC;
quint32 rgbBitCount;
quint32 rBitMask;
quint32 gBitMask;
quint32 bBitMask;
quint32 aBitMask;
};
struct DDSHeader
{
enum DDSFlags {
FlagCaps = 0x000001,
FlagHeight = 0x000002,
FlagWidth = 0x000004,
FlagPitch = 0x000008,
FlagPixelFormat = 0x001000,
FlagMipmapCount = 0x020000,
FlagLinearSize = 0x080000,
FlagDepth = 0x800000
};
enum DDSCapsFlags {
CapsComplex = 0x000008,
CapsTexture = 0x001000,
CapsMipmap = 0x400000
};
enum DDSCaps2Flags {
Caps2CubeMap = 0x0200,
Caps2CubeMapPositiveX = 0x0400,
Caps2CubeMapNegativeX = 0x0800,
Caps2CubeMapPositiveY = 0x1000,
Caps2CubeMapNegativeY = 0x2000,
Caps2CubeMapPositiveZ = 0x4000,
Caps2CubeMapNegativeZ = 0x8000,
Caps2Volume = 0x200000
};
enum { ReservedCount = 11 };
quint32 magic;
quint32 size;
quint32 flags;
quint32 height;
quint32 width;
quint32 pitchOrLinearSize;
quint32 depth;
quint32 mipMapCount;
quint32 reserved1[ReservedCount];
DDSPixelFormat pixelFormat;
quint32 caps;
quint32 caps2;
quint32 caps3;
quint32 caps4;
quint32 reserved2;
};
struct DDSHeaderDX10
{
quint32 dxgiFormat;
quint32 resourceDimension;
quint32 miscFlag;
quint32 arraySize;
quint32 reserved;
};
class QDDSHandler : public QImageIOHandler
{
public:
QDDSHandler();
bool canRead() const override;
bool read(QImage *image) override;
bool write(const QImage &image) override;
QVariant option(QImageIOHandler::ImageOption option) const override;
void setOption(ImageOption option, const QVariant &value) override;
bool supportsOption(QImageIOHandler::ImageOption option) const override;
int imageCount() const override;
bool jumpToImage(int imageNumber) override;
static bool canRead(QIODevice *device);
private:
bool ensureScanned() const;
bool verifyHeader(const DDSHeader &dds) const;
private:
enum ScanState {
ScanError = -1,
ScanNotScanned = 0,
ScanSuccess = 1,
};
DDSHeader m_header;
int m_format;
DDSHeaderDX10 m_header10;
int m_currentImage;
mutable ScanState m_scanState;
};
class QDDSPlugin : public QImageIOPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "dds.json")
public:
Capabilities capabilities(QIODevice *device, const QByteArray &format) const;
QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const;
};
#endif // QDDSHANDLER_H