/* PIC_RW - Qt PIC Support SPDX-FileCopyrightText: 2007 Ruben Lopez SPDX-License-Identifier: LGPL-2.0-or-later */ #ifndef KIMG_PIC_P_H #define KIMG_PIC_P_H #include #include /** * The magic number at the start of a SoftImage PIC file. */ static const qint32 PIC_MAGIC_NUMBER = 0x5380f634; /** * How fields are distributed over the image. * * This information is not used by this image format code. */ enum PicFields { NoPicture = 0, /**< No picture */ OddScanlines = 1, /**< Odd scanlines */ EvenScanlines = 2, /**< Even scanlines */ BothScanlines = 3, /**< Every scanline */ }; /** * How the data for a channel is encoded. */ enum PicChannelEncoding { Uncompressed = 0, /**< Image is uncompressed */ MixedRLE = 2, /**< Run length compression */ }; /** * What components are encoded in a channel. */ enum PicChannelCode { RED = 0x80, /**< Red channel */ GREEN = 0x40, /**< Green channel */ BLUE = 0x20, /**< Blue channel */ ALPHA = 0x10, /**< Alpha channel */ }; /** * The header for a SoftImage PIC file. * * @private */ struct PicHeader { /** * Construct a valid header for a SoftImage PIC file. * * Note that the comment will be truncated to 80 bytes when written. * * @param _width The width of the image in pixels * @param _height The height of the image in pixels * @param _comment A comment to add to the image */ PicHeader(quint16 _width, quint16 _height, const QByteArray &_comment = QByteArray()) : magic(PIC_MAGIC_NUMBER) , version(3.71f) , comment(_comment) , id("PICT") , width(_width) , height(_height) , ratio(1.0f) , fields(BothScanlines) { } /** Construct an invalid header. */ PicHeader() { } quint32 magic; /**< Should be PIC_MAGIC_NUMBER */ float version; /**< Version of something (header? file format?) (ignored) */ QByteArray comment; /**< A free comment field (truncated to 80 bytes when written) */ QByteArray id; /**< The file format ID (should be "PICT") */ quint16 width; /**< The width of the image in pixels */ quint16 height; /**< The height of the image in pixels */ float ratio; /**< The aspect ratio: width/height of each individual pixel (ignored) */ PicFields fields; /**< The interlace type (ignored) */ /** * Returns true if the @p magic and @p id fields are set correctly. */ bool isValid() const { return magic == PIC_MAGIC_NUMBER && id == "PICT"; } /** * The length of the encoded data, in bytes. */ static const qint64 encodedLength = 104; }; /** * Describes a channel in a SoftImage PIC file. * * @private */ struct PicChannel { quint8 size; /**< Bits per component per pixel. */ quint8 encoding; /**< How the channel's data is encoded. */ quint8 code; /**< Flag field to describe which components are encoded in this channel. */ /** * Constructs a channel description for a SoftImage PIC file. * * @param _encoding How the channel's data is or will be encoded. * @param _code What components are or will be encoded by this * channel. * @param _size The number of bits used to encoded a single component * for a single pixel in this channel (should be 8). */ PicChannel(PicChannelEncoding _encoding, quint8 _code, quint8 _size = 8) : size(_size) , encoding(_encoding) , code(_code) { } /** * Constructs a default channel description for a SoftImage PIC file. * * This will have size set to 8, encoding set to Uncompressed and the code * set to 0 (so that the channel does not encode any information). * * The result of this should not be written to a file without setting the * encoding and channel fields correctly. */ PicChannel() : size(8) { } }; class SoftimagePICHandler : public QImageIOHandler { public: bool canRead() const override; bool read(QImage *image) override; bool write(const QImage &) override; QVariant option(ImageOption option) const override; void setOption(ImageOption option, const QVariant &value) override; bool supportsOption(ImageOption option) const override; static bool canRead(QIODevice *device); enum State { Error, Ready, ReadHeader, ReadChannels, }; SoftimagePICHandler() : m_state(Ready) , m_compression(true) { } bool readHeader(); bool readChannels(); private: State m_state; QDataStream m_dataStream; PicHeader m_header; QList m_channels; // mostly used for writing: bool m_compression; QByteArray m_description; }; class SoftimagePICPlugin : public QImageIOPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "pic.json") public: Capabilities capabilities(QIODevice *device, const QByteArray &format) const override; QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const override; }; #endif // KIMG_PIC_P_H