mirror of
https://invent.kde.org/frameworks/kimageformats.git
synced 2025-06-03 17:08:08 -04:00
The following changes have been made: - Improved writing speed by using scanLine() instead of pixel() - Optimized memory usage on writing by using ScanlineConverter class - Added native write support for RGBA32FPx4, RGBA16FPx4, RGB8, Grayscale8 and Indexed8 uncompressed formats - Grayscale DDS without alpha are loaded in a Grayscale8 image - Fixed warnings about wrong PITCH reported by GIMP on DDSs saved by this plugin - Initial support for loading DX10 formats (R16F, RG16F, RGBA16F, RGBPreMulA16F, R32F, RG32F, RGBA32F, RGBPreMulA32F) - Fixed alignment issues and A8P8 format support of the attached images* Tested using GIMP and [NVIDIA Texture Tools](https://developer.nvidia.com/texture-tools-exporter) plugin for Photoshop. (*) The following images (taken from [here](https://github.com/walbourn/directxtexmedia)) cannot be added to read tests due to license issue: [test8_DWORD.dds](/uploads/449b5a0d886aaf6764af554fe38e2b09/test8_DWORD.dds) [dx5_logo.dds](/uploads/6f5f27df752890b227ef07e0195435d4/dx5_logo.dds) [test888_DWORD.dds](/uploads/c8bc355c5749cf203d47e0b3073ad419/test888_DWORD.dds)
145 lines
3.6 KiB
C++
145 lines
3.6 KiB
C++
/*
|
|
This file is part of the KDE project
|
|
SPDX-FileCopyrightText: 2015 The Qt Company Ltd
|
|
SPDX-FileCopyrightText: 2013 Ivan Komissarov
|
|
SPDX-FileCopyrightText: 2024 Mirco Miranda
|
|
|
|
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 DDSHeaderDX10
|
|
{
|
|
quint32 dxgiFormat = 0;
|
|
quint32 resourceDimension = 0;
|
|
quint32 miscFlag = 0;
|
|
quint32 arraySize = 0;
|
|
quint32 miscFlags2 = 0;
|
|
};
|
|
|
|
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;
|
|
DDSHeaderDX10 header10;
|
|
};
|
|
|
|
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;
|
|
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 override;
|
|
QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const override;
|
|
};
|
|
|
|
#endif // QDDSHANDLER_H
|