mirror of
https://invent.kde.org/frameworks/kimageformats.git
synced 2025-06-03 17:08:08 -04:00
196 lines
5.2 KiB
C++
196 lines
5.2 KiB
C++
/*
|
|
PIC_RW - Qt PIC Support
|
|
SPDX-FileCopyrightText: 2007 Ruben Lopez <r.lopez@bren.es>
|
|
|
|
SPDX-License-Identifier: LGPL-2.0-or-later
|
|
*/
|
|
|
|
#ifndef KIMG_PIC_P_H
|
|
#define KIMG_PIC_P_H
|
|
|
|
#include <QDataStream>
|
|
#include <QImageIOPlugin>
|
|
|
|
/**
|
|
* 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<PicChannel> 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
|