mirror of
https://invent.kde.org/frameworks/kimageformats.git
synced 2025-07-22 04:54:19 -04:00
iff: Support ILBM (PBM)
It's another variant of IFF where the pixel data is stored contiguously rather than interleaved.
This commit is contained in:
@ -547,9 +547,9 @@ bool BODYChunk::isValid() const
|
|||||||
return chunkId() == BODYChunk::defaultChunkId();
|
return chunkId() == BODYChunk::defaultChunkId();
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray BODYChunk::strideRead(QIODevice *d, const BMHDChunk *header, const CAMGChunk *camg, const CMAPChunk *cmap) const
|
QByteArray BODYChunk::strideRead(QIODevice *d, const FORMChunk *form, const BMHDChunk *header, const CAMGChunk *camg, const CMAPChunk *cmap) const
|
||||||
{
|
{
|
||||||
if (!isValid() || header == nullptr) {
|
if (!isValid() || form == nullptr || header == nullptr) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,7 +571,11 @@ QByteArray BODYChunk::strideRead(QIODevice *d, const BMHDChunk *header, const CA
|
|||||||
|
|
||||||
auto planes = _readBuffer.left(readSize);
|
auto planes = _readBuffer.left(readSize);
|
||||||
_readBuffer.remove(0, readSize);
|
_readBuffer.remove(0, readSize);
|
||||||
return BODYChunk::deinterleave(planes, header, camg, cmap);
|
if (form->formType() == FORMChunk::FormType::Pbm) {
|
||||||
|
return planes;
|
||||||
|
} else {
|
||||||
|
return BODYChunk::deinterleave(planes, header, camg, cmap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BODYChunk::resetStrideRead(QIODevice *d) const
|
bool BODYChunk::resetStrideRead(QIODevice *d) const
|
||||||
@ -773,15 +777,21 @@ bool FORMChunk::innerReadStructure(QIODevice *d)
|
|||||||
if (bytes() < 4) {
|
if (bytes() < 4) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_type = d->read(4);
|
const auto type = d->read(4);
|
||||||
auto ok = true;
|
auto ok = false;
|
||||||
if (_type == QByteArray("ILBM")) {
|
if (type == QByteArrayLiteral("ILBM")) {
|
||||||
|
_type = FormType::Ilbm;
|
||||||
|
} else if (type == QByteArrayLiteral("PBM ")) {
|
||||||
|
_type = FormType::Pbm;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_type != FormType::Unknown) {
|
||||||
setChunks(IFFChunk::innerFromDevice(d, &ok, alignBytes(), recursionCounter()));
|
setChunks(IFFChunk::innerFromDevice(d, &ok, alignBytes(), recursionCounter()));
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray FORMChunk::formType() const
|
FORMChunk::FormType FORMChunk::formType() const
|
||||||
{
|
{
|
||||||
return _type;
|
return _type;
|
||||||
}
|
}
|
||||||
|
@ -451,6 +451,7 @@ protected:
|
|||||||
virtual bool innerReadStructure(QIODevice *d) override;
|
virtual bool innerReadStructure(QIODevice *d) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FORMChunk;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief The BODYChunk class
|
* \brief The BODYChunk class
|
||||||
@ -476,7 +477,7 @@ public:
|
|||||||
* \return The scanline as requested for QImage.
|
* \return The scanline as requested for QImage.
|
||||||
* \warning Call resetStrideRead() once before this one.
|
* \warning Call resetStrideRead() once before this one.
|
||||||
*/
|
*/
|
||||||
QByteArray strideRead(QIODevice *d, const BMHDChunk *header, const CAMGChunk *camg = nullptr, const CMAPChunk *cmap = nullptr) const;
|
QByteArray strideRead(QIODevice *d, const FORMChunk *form, const BMHDChunk *header, const CAMGChunk *camg = nullptr, const CMAPChunk *cmap = nullptr) const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief resetStrideRead
|
* \brief resetStrideRead
|
||||||
@ -500,9 +501,13 @@ private:
|
|||||||
*/
|
*/
|
||||||
class FORMChunk : public IFFChunk
|
class FORMChunk : public IFFChunk
|
||||||
{
|
{
|
||||||
QByteArray _type;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum class FormType {
|
||||||
|
Unknown,
|
||||||
|
Ilbm,
|
||||||
|
Pbm,
|
||||||
|
};
|
||||||
|
|
||||||
virtual ~FORMChunk() override;
|
virtual ~FORMChunk() override;
|
||||||
FORMChunk();
|
FORMChunk();
|
||||||
FORMChunk(const FORMChunk& other) = default;
|
FORMChunk(const FORMChunk& other) = default;
|
||||||
@ -512,7 +517,7 @@ public:
|
|||||||
|
|
||||||
bool isSupported() const;
|
bool isSupported() const;
|
||||||
|
|
||||||
QByteArray formType() const;
|
FormType formType() const;
|
||||||
|
|
||||||
QImage::Format format() const;
|
QImage::Format format() const;
|
||||||
|
|
||||||
@ -522,8 +527,10 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool innerReadStructure(QIODevice *d) override;
|
virtual bool innerReadStructure(QIODevice *d) override;
|
||||||
};
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
FormType _type = FormType::Unknown;
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief The FOR4Chunk class
|
* \brief The FOR4Chunk class
|
||||||
|
@ -74,7 +74,7 @@ IFFHandler::IFFHandler()
|
|||||||
bool IFFHandler::canRead() const
|
bool IFFHandler::canRead() const
|
||||||
{
|
{
|
||||||
if (canRead(device())) {
|
if (canRead(device())) {
|
||||||
setFormat("iff");
|
setFormat("iff"); // TODO ilbm based on header?
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -192,7 +192,7 @@ bool IFFHandler::readStandardImage(QImage *image)
|
|||||||
}
|
}
|
||||||
for (auto y = 0, h = img.height(); y < h; ++y) {
|
for (auto y = 0, h = img.height(); y < h; ++y) {
|
||||||
auto line = reinterpret_cast<char*>(img.scanLine(y));
|
auto line = reinterpret_cast<char*>(img.scanLine(y));
|
||||||
auto ba = body->strideRead(device(), header, camg, cmap);
|
auto ba = body->strideRead(device(), form, header, camg, cmap);
|
||||||
if (ba.isEmpty()) {
|
if (ba.isEmpty()) {
|
||||||
qCWarning(LOG_IFFPLUGIN) << "IFFHandler::readStandardImage() error while reading image scanline";
|
qCWarning(LOG_IFFPLUGIN) << "IFFHandler::readStandardImage() error while reading image scanline";
|
||||||
return false;
|
return false;
|
||||||
@ -334,7 +334,7 @@ QVariant IFFHandler::option(ImageOption option) const
|
|||||||
|
|
||||||
QImageIOPlugin::Capabilities IFFPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
QImageIOPlugin::Capabilities IFFPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
||||||
{
|
{
|
||||||
if (format == "iff") {
|
if (format == "iff" || format == "ilbm") {
|
||||||
return Capabilities(CanRead);
|
return Capabilities(CanRead);
|
||||||
}
|
}
|
||||||
if (!format.isEmpty()) {
|
if (!format.isEmpty()) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"Keys": [ "iff" ],
|
"Keys": [ "iff", "ilbm" ],
|
||||||
"MimeTypes": [ "application/x-iff" ]
|
"MimeTypes": [ "application/x-iff", "application/x-ilbm" ]
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user