File indexing completed on 2024-04-28 15:25:42
0001 /* 0002 PIC_RW - Qt PIC Support 0003 SPDX-FileCopyrightText: 2007 Ruben Lopez <r.lopez@bren.es> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #ifndef KIMG_PIC_P_H 0009 #define KIMG_PIC_P_H 0010 0011 #include <QDataStream> 0012 #include <QImageIOPlugin> 0013 0014 /** 0015 * The magic number at the start of a SoftImage PIC file. 0016 */ 0017 static const qint32 PIC_MAGIC_NUMBER = 0x5380f634; 0018 0019 /** 0020 * How fields are distributed over the image. 0021 * 0022 * This information is not used by this image format code. 0023 */ 0024 enum PicFields { 0025 NoPicture = 0, /**< No picture */ 0026 OddScanlines = 1, /**< Odd scanlines */ 0027 EvenScanlines = 2, /**< Even scanlines */ 0028 BothScanlines = 3, /**< Every scanline */ 0029 }; 0030 0031 /** 0032 * How the data for a channel is encoded. 0033 */ 0034 enum PicChannelEncoding { 0035 Uncompressed = 0, /**< Image is uncompressed */ 0036 MixedRLE = 2, /**< Run length compression */ 0037 }; 0038 0039 /** 0040 * What components are encoded in a channel. 0041 */ 0042 enum PicChannelCode { 0043 RED = 0x80, /**< Red channel */ 0044 GREEN = 0x40, /**< Green channel */ 0045 BLUE = 0x20, /**< Blue channel */ 0046 ALPHA = 0x10, /**< Alpha channel */ 0047 }; 0048 0049 /** 0050 * The header for a SoftImage PIC file. 0051 * 0052 * @private 0053 */ 0054 struct PicHeader { 0055 /** 0056 * Construct a valid header for a SoftImage PIC file. 0057 * 0058 * Note that the comment will be truncated to 80 bytes when written. 0059 * 0060 * @param _width The width of the image in pixels 0061 * @param _height The height of the image in pixels 0062 * @param _comment A comment to add to the image 0063 */ 0064 PicHeader(quint16 _width, quint16 _height, const QByteArray &_comment = QByteArray()) 0065 : magic(PIC_MAGIC_NUMBER) 0066 , version(3.71f) 0067 , comment(_comment) 0068 , id("PICT") 0069 , width(_width) 0070 , height(_height) 0071 , ratio(1.0f) 0072 , fields(BothScanlines) 0073 { 0074 } 0075 /** Construct an invalid header. */ 0076 PicHeader() 0077 { 0078 } 0079 0080 quint32 magic; /**< Should be PIC_MAGIC_NUMBER */ 0081 float version; /**< Version of something (header? file format?) (ignored) */ 0082 QByteArray comment; /**< A free comment field (truncated to 80 bytes when 0083 written) */ 0084 QByteArray id; /**< The file format ID (should be "PICT") */ 0085 quint16 width; /**< The width of the image in pixels */ 0086 quint16 height; /**< The height of the image in pixels */ 0087 float ratio; /**< The aspect ratio: width/height of each individual pixel 0088 (ignored) */ 0089 PicFields fields; /**< The interlace type (ignored) */ 0090 0091 /** 0092 * Returns true if the @p magic and @p id fields are set correctly. 0093 */ 0094 bool isValid() const 0095 { 0096 return magic == PIC_MAGIC_NUMBER && id == "PICT"; 0097 } 0098 0099 /** 0100 * The length of the encoded data, in bytes. 0101 */ 0102 static const qint64 encodedLength = 104; 0103 }; 0104 0105 /** 0106 * Describes a channel in a SoftImage PIC file. 0107 * 0108 * @private 0109 */ 0110 struct PicChannel { 0111 quint8 size; /**< Bits per component per pixel. */ 0112 quint8 encoding; /**< How the channel's data is encoded. */ 0113 quint8 code; /**< Flag field to describe which components are encoded in 0114 this channel. */ 0115 0116 /** 0117 * Constructs a channel description for a SoftImage PIC file. 0118 * 0119 * @param _encoding How the channel's data is or will be encoded. 0120 * @param _code What components are or will be encoded by this 0121 * channel. 0122 * @param _size The number of bits used to encoded a single component 0123 * for a single pixel in this channel (should be 8). 0124 */ 0125 PicChannel(PicChannelEncoding _encoding, quint8 _code, quint8 _size = 8) 0126 : size(_size) 0127 , encoding(_encoding) 0128 , code(_code) 0129 { 0130 } 0131 /** 0132 * Constructs a default channel description for a SoftImage PIC file. 0133 * 0134 * This will have size set to 8, encoding set to Uncompressed and the code 0135 * set to 0 (so that the channel does not encode any information). 0136 * 0137 * The result of this should not be written to a file without setting the 0138 * encoding and channel fields correctly. 0139 */ 0140 PicChannel() 0141 : size(8) 0142 { 0143 } 0144 }; 0145 0146 class SoftimagePICHandler : public QImageIOHandler 0147 { 0148 public: 0149 bool canRead() const override; 0150 bool read(QImage *image) override; 0151 bool write(const QImage &) override; 0152 0153 QVariant option(ImageOption option) const override; 0154 void setOption(ImageOption option, const QVariant &value) override; 0155 bool supportsOption(ImageOption option) const override; 0156 0157 static bool canRead(QIODevice *device); 0158 0159 enum State { 0160 Error, 0161 Ready, 0162 ReadHeader, 0163 ReadChannels, 0164 }; 0165 0166 SoftimagePICHandler() 0167 : m_state(Ready) 0168 , m_compression(true) 0169 { 0170 } 0171 0172 bool readHeader(); 0173 bool readChannels(); 0174 0175 private: 0176 State m_state; 0177 QDataStream m_dataStream; 0178 PicHeader m_header; 0179 QList<PicChannel> m_channels; 0180 // mostly used for writing: 0181 bool m_compression; 0182 QByteArray m_description; 0183 }; 0184 0185 class SoftimagePICPlugin : public QImageIOPlugin 0186 { 0187 Q_OBJECT 0188 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "pic.json") 0189 0190 public: 0191 Capabilities capabilities(QIODevice *device, const QByteArray &format) const override; 0192 QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const override; 0193 }; 0194 0195 #endif // KIMG_PIC_P_H