From 2405a09e364ac9fb3a0f910857c4a9c2b2562813 Mon Sep 17 00:00:00 2001 From: Mirco Miranda Date: Sun, 25 Aug 2024 21:00:08 +0000 Subject: [PATCH] RGB: added options support - Added support for `Size` and `Format` options and slightly improved format detection from canRead(). - Removed conversion to ARGB32 on load (improved performace with RGBA images). - Added result checks on writing. With this MR, all plugins have minimal support for options. --- autotests/read/rgb/testcard_rgba.png | Bin 0 -> 16673 bytes autotests/read/rgb/testcard_rgba.rgb | Bin 0 -> 51186 bytes src/imageformats/rgb.cpp | 368 ++++++++++++++++++--------- src/imageformats/rgb_p.h | 8 + 4 files changed, 249 insertions(+), 127 deletions(-) create mode 100644 autotests/read/rgb/testcard_rgba.png create mode 100644 autotests/read/rgb/testcard_rgba.rgb diff --git a/autotests/read/rgb/testcard_rgba.png b/autotests/read/rgb/testcard_rgba.png new file mode 100644 index 0000000000000000000000000000000000000000..cd8df55674e6185b8065d7da3d31f163e0f92309 GIT binary patch literal 16673 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 XnUTxSZ9Y*(s^696HRLK}EW-Z>Sb{Xe literal 0 HcmV?d00001 diff --git a/autotests/read/rgb/testcard_rgba.rgb b/autotests/read/rgb/testcard_rgba.rgb new file mode 100644 index 0000000000000000000000000000000000000000..3d7639566699ae153ba685526ad47406758220d2 GIT binary patch literal 51186 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 S53*pT`dG<=zp0PEvHt_cw=+oq literal 0 HcmV?d00001 diff --git a/src/imageformats/rgb.cpp b/src/imageformats/rgb.cpp index f10251e..224f63d 100644 --- a/src/imageformats/rgb.cpp +++ b/src/imageformats/rgb.cpp @@ -22,6 +22,8 @@ #include "rgb_p.h" #include "util_p.h" +#include + #include #include @@ -72,15 +74,25 @@ private: uint _offset; }; -class SGIImage +class SGIImagePrivate { public: - SGIImage(QIODevice *device); - ~SGIImage(); + SGIImagePrivate(); + ~SGIImagePrivate(); bool readImage(QImage &); bool writeImage(const QImage &); + bool isValid() const; + bool isSupported() const; + + bool peekHeader(QIODevice *device); + + QSize size() const; + QImage::Format format() const; + + void setDevice(QIODevice *device); + private: enum { NORMAL, @@ -91,16 +103,19 @@ private: QIODevice *_dev; QDataStream _stream; - quint8 _rle; - quint8 _bpc; - quint16 _dim; - quint16 _xsize; - quint16 _ysize; - quint16 _zsize; - quint32 _pixmin; - quint32 _pixmax; + quint16 _magic = 0; + quint8 _rle = 0; + quint8 _bpc = 0; + quint16 _dim = 0; + quint16 _xsize = 0; + quint16 _ysize = 0; + quint16 _zsize = 0; + quint32 _pixmin = 0; + quint32 _pixmax = 0; char _imagename[80]; - quint32 _colormap; + quint32 _colormap = 0; + quint8 _unused[404]; + quint32 _unused32 = 0; quint32 *_starttab; quint32 *_lengthtab; @@ -112,24 +127,28 @@ private: bool readData(QImage &); bool getRow(uchar *dest); + bool readHeader(); - void writeHeader(); - void writeRle(); - void writeVerbatim(const QImage &); + static bool readHeader(QDataStream &ds, SGIImagePrivate *sgi); + + bool writeHeader(); + bool writeRle(); + bool writeVerbatim(const QImage &); bool scanData(const QImage &); uint compact(uchar *, uchar *); uchar intensity(uchar); }; -SGIImage::SGIImage(QIODevice *io) - : _starttab(nullptr) +SGIImagePrivate::SGIImagePrivate() + : _dev(nullptr) + , _starttab(nullptr) , _lengthtab(nullptr) { - _dev = io; - _stream.setDevice(_dev); + std::memset(_imagename, 0, sizeof(_imagename)); + std::memset(_unused, 0, sizeof(_unused)); } -SGIImage::~SGIImage() +SGIImagePrivate::~SGIImagePrivate() { delete[] _starttab; delete[] _lengthtab; @@ -137,7 +156,13 @@ SGIImage::~SGIImage() /////////////////////////////////////////////////////////////////////////////// -bool SGIImage::getRow(uchar *dest) +void SGIImagePrivate::setDevice(QIODevice *device) +{ + _dev = device; + _stream.setDevice(_dev); +} + +bool SGIImagePrivate::getRow(uchar *dest) { int n; int i; @@ -180,7 +205,7 @@ bool SGIImage::getRow(uchar *dest) return i == _xsize; } -bool SGIImage::readData(QImage &img) +bool SGIImagePrivate::readData(QImage &img) { QRgb *c; quint32 *start = _starttab; @@ -258,66 +283,9 @@ bool SGIImage::readData(QImage &img) return true; } -bool SGIImage::readImage(QImage &img) +bool SGIImagePrivate::readImage(QImage &img) { - qint8 u8; - qint16 u16; - qint32 u32; - - // qDebug() << "reading rgb "; - - // magic - _stream >> u16; - if (u16 != 0x01da) { - return false; - } - - // verbatim/rle - _stream >> _rle; - // qDebug() << (_rle ? "RLE" : "verbatim"); - if (_rle > 1) { - return false; - } - - // bytes per channel - _stream >> _bpc; - // qDebug() << "bytes per channel: " << int(_bpc); - if (_bpc == 1) { - ; - } else if (_bpc == 2) { - // qDebug() << "dropping least significant byte"; - } else { - return false; - } - - // number of dimensions - _stream >> _dim; - // qDebug() << "dimensions: " << _dim; - if (_dim < 1 || _dim > 3) { - return false; - } - - _stream >> _xsize >> _ysize >> _zsize >> _pixmin >> _pixmax >> u32; - // qDebug() << "x: " << _xsize; - // qDebug() << "y: " << _ysize; - // qDebug() << "z: " << _zsize; - - // name - _stream.readRawData(_imagename, 80); - _imagename[79] = '\0'; - - _stream >> _colormap; - // qDebug() << "colormap: " << _colormap; - if (_colormap != NORMAL) { - return false; // only NORMAL supported - } - - for (int i = 0; i < 404; i++) { - _stream >> u8; - } - - if (_dim == 1) { - // qDebug() << "1-dimensional images aren't supported yet"; + if (!readHeader() || !isSupported()) { return false; } @@ -325,19 +293,13 @@ bool SGIImage::readImage(QImage &img) return false; } - img = imageAlloc(_xsize, _ysize, QImage::Format_RGB32); + img = imageAlloc(size(), format()); if (img.isNull()) { qWarning() << "Failed to allocate image, invalid dimensions?" << QSize(_xsize, _ysize); return false; } - if (_zsize == 0) { - return false; - } - - if (_zsize == 2 || _zsize == 4) { - img = img.convertToFormat(QImage::Format_ARGB32); - } else if (_zsize > 4) { + if (_zsize > 4) { // qDebug() << "using first 4 of " << _zsize << " channels"; // Only let this continue if it won't cause a int overflow later // this is most likely a broken file anyway @@ -435,7 +397,7 @@ QList RLEMap::vector() return v; } -uchar SGIImage::intensity(uchar c) +uchar SGIImagePrivate::intensity(uchar c) { if (c < _pixmin) { _pixmin = c; @@ -446,7 +408,7 @@ uchar SGIImage::intensity(uchar c) return c; } -uint SGIImage::compact(uchar *d, uchar *s) +uint SGIImagePrivate::compact(uchar *d, uchar *s) { uchar *dest = d; uchar *src = s; @@ -489,7 +451,7 @@ uint SGIImage::compact(uchar *d, uchar *s) return dest - d; } -bool SGIImage::scanData(const QImage &img) +bool SGIImagePrivate::scanData(const QImage &img) { quint32 *start = _starttab; QByteArray lineguard(_xsize * 2, 0); @@ -575,13 +537,127 @@ bool SGIImage::scanData(const QImage &img) return true; } -void SGIImage::writeHeader() +bool SGIImagePrivate::isValid() const { - _stream << quint16(0x01da); + // File signature/magic number + if (_magic != 0x01da) { + return false; + } + // Compression, 0 = Uncompressed, 1 = RLE compressed + if (_rle > 1) { + return false; + } + // Bytes per pixel, 1 = 8 bit, 2 = 16 bit + if (_bpc != 1 && _bpc != 2) { + return false; + } + // Image dimension, 3 for RGBA image + if (_dim < 1 || _dim > 3) { + return false; + } + // Number channels in the image file, 4 for RGBA image + if (_zsize < 1) { + return false; + } + return true; +} + +bool SGIImagePrivate::isSupported() const +{ + if (!isValid()) { + return false; + } + if (_colormap != NORMAL) { + return false; // only NORMAL supported + } + if (_dim == 1) { + return false; + } + return true; +} + +bool SGIImagePrivate::peekHeader(QIODevice *device) +{ + qint64 pos = 0; + if (!device->isSequential()) { + pos = device->pos(); + } + + auto ok = false; + QByteArray header; + { // datastream is destroyed before working on device + header = device->read(512); + QDataStream ds(header); + ok = SGIImagePrivate::readHeader(ds, this) && isValid(); + } + + if (!device->isSequential()) { + return device->seek(pos) && ok; + } + + // sequential device undo + auto head = header.data(); + auto readBytes = header.size(); + while (readBytes > 0) { + device->ungetChar(head[readBytes-- - 1]); + } + return ok; +} + +QSize SGIImagePrivate::size() const +{ + return QSize(_xsize, _ysize); +} + +QImage::Format SGIImagePrivate::format() const +{ + if (_zsize == 2 || _zsize == 4) { + return QImage::Format_ARGB32; + } + return QImage::Format_RGB32; +} + +bool SGIImagePrivate::readHeader() +{ + return readHeader(_stream, this); +} + +bool SGIImagePrivate::readHeader(QDataStream &ds, SGIImagePrivate *sgi) +{ + // magic + ds >> sgi->_magic; + + // verbatim/rle + ds >> sgi->_rle; + + // bytes per channel + ds >> sgi->_bpc; + + // number of dimensions + ds >> sgi->_dim; + + ds >> sgi->_xsize >> sgi->_ysize >> sgi->_zsize >> sgi->_pixmin >> sgi->_pixmax >> sgi->_unused32; + + // name + ds.readRawData(sgi->_imagename, 80); + sgi->_imagename[79] = '\0'; + + ds >> sgi->_colormap; + + for (size_t i = 0; i < sizeof(_unused); i++) { + ds >> sgi->_unused[i]; + } + + return ds.status() == QDataStream::Ok; +} + +bool SGIImagePrivate::writeHeader() +{ + _stream << _magic; _stream << _rle << _bpc << _dim; _stream << _xsize << _ysize << _zsize; _stream << _pixmin << _pixmax; - _stream << quint32(0); + _stream << _unused32; for (int i = 0; i < 80; i++) { _imagename[i] = '\0'; @@ -589,16 +665,20 @@ void SGIImage::writeHeader() _stream.writeRawData(_imagename, 80); _stream << _colormap; - for (int i = 0; i < 404; i++) { - _stream << quint8(0); + for (size_t i = 0; i < sizeof(_unused); i++) { + _stream << _unused[i]; } + return _stream.status() == QDataStream::Ok; } -void SGIImage::writeRle() +bool SGIImagePrivate::writeRle() { _rle = 1; // qDebug() << "writing RLE data"; - writeHeader(); + if (!writeHeader()) { + return false; + } + uint i; // write start table @@ -615,13 +695,16 @@ void SGIImage::writeRle() for (i = 0; (int)i < _rlevector.size(); i++) { const_cast(_rlevector[i])->write(_stream); } + + return _stream.status() == QDataStream::Ok; } -void SGIImage::writeVerbatim(const QImage &img) +bool SGIImagePrivate::writeVerbatim(const QImage &img) { _rle = 0; - // qDebug() << "writing verbatim data"; - writeHeader(); + if (!writeHeader()) { + return false; + } const QRgb *c; unsigned x; @@ -635,7 +718,7 @@ void SGIImage::writeVerbatim(const QImage &img) } if (_zsize == 1) { - return; + return _stream.status() == QDataStream::Ok; } if (_zsize != 2) { @@ -654,7 +737,7 @@ void SGIImage::writeVerbatim(const QImage &img) } if (_zsize == 3) { - return; + return _stream.status() == QDataStream::Ok; } } @@ -664,9 +747,11 @@ void SGIImage::writeVerbatim(const QImage &img) _stream << quint8(qAlpha(*c++)); } } + + return _stream.status() == QDataStream::Ok; } -bool SGIImage::writeImage(const QImage &image) +bool SGIImagePrivate::writeImage(const QImage &image) { // qDebug() << "writing "; // TODO add filename QImage img = image; @@ -698,6 +783,7 @@ bool SGIImage::writeImage(const QImage &image) return false; } + _magic = 0x01da; _bpc = 1; _xsize = w; _ysize = h; @@ -722,16 +808,16 @@ bool SGIImage::writeImage(const QImage &image) } if (verbatim_size <= rle_size) { - writeVerbatim(img); - } else { - writeRle(); + return writeVerbatim(img); } - return true; + return writeRle(); } /////////////////////////////////////////////////////////////////////////////// RGBHandler::RGBHandler() + : QImageIOHandler() + , d(new SGIImagePrivate) { } @@ -746,14 +832,54 @@ bool RGBHandler::canRead() const bool RGBHandler::read(QImage *outImage) { - SGIImage sgi(device()); - return sgi.readImage(*outImage); + d->setDevice(device()); + return d->readImage(*outImage); } bool RGBHandler::write(const QImage &image) { - SGIImage sgi(device()); - return sgi.writeImage(image); + d->setDevice(device()); + return d->writeImage(image); +} + +bool RGBHandler::supportsOption(ImageOption option) const +{ + if (option == QImageIOHandler::Size) { + return true; + } + if (option == QImageIOHandler::ImageFormat) { + return true; + } + return false; +} + +QVariant RGBHandler::option(ImageOption option) const +{ + QVariant v; + + if (option == QImageIOHandler::Size) { + auto &&sgi = d; + if (sgi->isSupported()) { + v = QVariant::fromValue(sgi->size()); + } else if (auto dev = device()) { + if (d->peekHeader(dev) && sgi->isSupported()) { + v = QVariant::fromValue(sgi->size()); + } + } + } + + if (option == QImageIOHandler::ImageFormat) { + auto &&sgi = d; + if (sgi->isSupported()) { + v = QVariant::fromValue(sgi->format()); + } else if (auto dev = device()) { + if (d->peekHeader(dev) && sgi->isSupported()) { + v = QVariant::fromValue(sgi->format()); + } + } + } + + return v; } bool RGBHandler::canRead(QIODevice *device) @@ -763,20 +889,8 @@ bool RGBHandler::canRead(QIODevice *device) return false; } - const qint64 oldPos = device->pos(); - const QByteArray head = device->readLine(64); - int readBytes = head.size(); - - if (device->isSequential()) { - while (readBytes > 0) { - device->ungetChar(head[readBytes-- - 1]); - } - - } else { - device->seek(oldPos); - } - - return head.size() >= 4 && head.startsWith("\x01\xda") && (head[2] == 0 || head[2] == 1) && (head[3] == 1 || head[3] == 2); + SGIImagePrivate sgi; + return sgi.peekHeader(device) && sgi.isSupported(); } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/imageformats/rgb_p.h b/src/imageformats/rgb_p.h index 3d7b14c..f47c627 100644 --- a/src/imageformats/rgb_p.h +++ b/src/imageformats/rgb_p.h @@ -9,7 +9,9 @@ #define KIMG_RGB_P_H #include +#include +class SGIImagePrivate; class RGBHandler : public QImageIOHandler { public: @@ -19,7 +21,13 @@ public: bool read(QImage *image) override; bool write(const QImage &image) override; + bool supportsOption(QImageIOHandler::ImageOption option) const override; + QVariant option(QImageIOHandler::ImageOption option) const override; + static bool canRead(QIODevice *device); + +private: + QScopedPointer d; }; class RGBPlugin : public QImageIOPlugin