diff --git a/README.md b/README.md index 63586e9..be305a7 100644 --- a/README.md +++ b/README.md @@ -415,7 +415,7 @@ The plugin supports the following image data: with color map only. - FORM IMAG (Compact Disc-Interactive): It supports CLut4, CLut7, CLut8, Rle7 and DYuv formats. -- FORM RGFX: It supports uncompressed images only. +- FORM RGFX: It supports uncompressed and ZIP compressed images. - FORM DEEP: It supports uncompressed, RLE and TVDC images. - FOR4 CIMG (Maya Image File Format): It supports 24/48-bit RGB and 32/64-bit RGBA images. diff --git a/autotests/read/iff/sv5_idx8z_rgx.iff b/autotests/read/iff/sv5_idx8z_rgx.iff new file mode 100644 index 0000000..b970325 Binary files /dev/null and b/autotests/read/iff/sv5_idx8z_rgx.iff differ diff --git a/autotests/read/iff/sv5_idx8z_rgx.iff.json b/autotests/read/iff/sv5_idx8z_rgx.iff.json new file mode 100644 index 0000000..133a8de --- /dev/null +++ b/autotests/read/iff/sv5_idx8z_rgx.iff.json @@ -0,0 +1,5 @@ +[ + { + "fileName" : "sv5_idx8_rgx.png" + } +] diff --git a/autotests/read/iff/sv5_rgb16z_rgx.iff b/autotests/read/iff/sv5_rgb16z_rgx.iff new file mode 100644 index 0000000..ec74da7 Binary files /dev/null and b/autotests/read/iff/sv5_rgb16z_rgx.iff differ diff --git a/autotests/read/iff/sv5_rgb16z_rgx.iff.json b/autotests/read/iff/sv5_rgb16z_rgx.iff.json new file mode 100644 index 0000000..52e8b71 --- /dev/null +++ b/autotests/read/iff/sv5_rgb16z_rgx.iff.json @@ -0,0 +1,5 @@ +[ + { + "fileName" : "sv5_rgb16_rgx.png" + } +] diff --git a/autotests/read/iff/sv5_rgb32z_rgx.iff b/autotests/read/iff/sv5_rgb32z_rgx.iff new file mode 100644 index 0000000..9a64f72 Binary files /dev/null and b/autotests/read/iff/sv5_rgb32z_rgx.iff differ diff --git a/autotests/read/iff/sv5_rgb32z_rgx.iff.json b/autotests/read/iff/sv5_rgb32z_rgx.iff.json new file mode 100644 index 0000000..bdec37f --- /dev/null +++ b/autotests/read/iff/sv5_rgb32z_rgx.iff.json @@ -0,0 +1,5 @@ +[ + { + "fileName" : "sv5_rgb32_rgx.png" + } +] diff --git a/autotests/read/iff/sv5_rgb8z_rgx.iff b/autotests/read/iff/sv5_rgb8z_rgx.iff new file mode 100644 index 0000000..9ee8387 Binary files /dev/null and b/autotests/read/iff/sv5_rgb8z_rgx.iff differ diff --git a/autotests/read/iff/sv5_rgb8z_rgx.iff.json b/autotests/read/iff/sv5_rgb8z_rgx.iff.json new file mode 100644 index 0000000..5424071 --- /dev/null +++ b/autotests/read/iff/sv5_rgb8z_rgx.iff.json @@ -0,0 +1,5 @@ +[ + { + "fileName" : "sv5_rgb8_rgx.png" + } +] diff --git a/autotests/read/iff/sv5_rgba16z_rgx.iff b/autotests/read/iff/sv5_rgba16z_rgx.iff new file mode 100644 index 0000000..06bfcaf Binary files /dev/null and b/autotests/read/iff/sv5_rgba16z_rgx.iff differ diff --git a/autotests/read/iff/sv5_rgba16z_rgx.iff.json b/autotests/read/iff/sv5_rgba16z_rgx.iff.json new file mode 100644 index 0000000..ca8a8b7 --- /dev/null +++ b/autotests/read/iff/sv5_rgba16z_rgx.iff.json @@ -0,0 +1,5 @@ +[ + { + "fileName" : "sv5_rgba16_rgx.png" + } +] diff --git a/autotests/read/iff/sv5_rgba32z_rgx.iff b/autotests/read/iff/sv5_rgba32z_rgx.iff new file mode 100644 index 0000000..e272cdb Binary files /dev/null and b/autotests/read/iff/sv5_rgba32z_rgx.iff differ diff --git a/autotests/read/iff/sv5_rgba32z_rgx.iff.json b/autotests/read/iff/sv5_rgba32z_rgx.iff.json new file mode 100644 index 0000000..0db94e6 --- /dev/null +++ b/autotests/read/iff/sv5_rgba32z_rgx.iff.json @@ -0,0 +1,5 @@ +[ + { + "fileName" : "sv5_rgba32_rgx.png" + } +] diff --git a/autotests/read/iff/sv5_rgba8z_rgx.iff b/autotests/read/iff/sv5_rgba8z_rgx.iff new file mode 100644 index 0000000..2c04e40 Binary files /dev/null and b/autotests/read/iff/sv5_rgba8z_rgx.iff differ diff --git a/autotests/read/iff/sv5_rgba8z_rgx.iff.json b/autotests/read/iff/sv5_rgba8z_rgx.iff.json new file mode 100644 index 0000000..8b9c2b6 --- /dev/null +++ b/autotests/read/iff/sv5_rgba8z_rgx.iff.json @@ -0,0 +1,5 @@ +[ + { + "fileName" : "sv5_rgba8_rgx.png" + } +] diff --git a/src/imageformats/chunks.cpp b/src/imageformats/chunks.cpp index b50a6e2..c4665c4 100644 --- a/src/imageformats/chunks.cpp +++ b/src/imageformats/chunks.cpp @@ -3501,6 +3501,17 @@ QByteArray RBODChunk::strideRead(QIODevice *d, qint32 y, const RGHDChunk *header for (auto nextPos = nextChunkPos(); !d->atEnd() && d->pos() < nextPos && planes.size() < readSize;) { if (header->compression() == RGHDChunk::Compression::Uncompressed) { planes = d->read(readSize); + } else if (header->compression() == RGHDChunk::Compression::Zip) { + if (_readBuffer.isEmpty()) { + auto size = nextPos - d->pos(); + if (size < kMaxQVectorSize) { + // I have no control over qUncompress() so, I have to decompress the whole chunk + _readBuffer = qUncompress(deviceRead(d, size)); + // Reset the position to avoid falling into the `d->pos() < nextPos` check + seek(d, 0); + } + } + planes = _readBuffer.mid(y * readSize, readSize); } else { qCDebug(LOG_IFFPLUGIN) << "RBODChunk::strideRead(): unknown compression" << header->compression(); } @@ -3514,6 +3525,7 @@ QByteArray RBODChunk::strideRead(QIODevice *d, qint32 y, const RGHDChunk *header bool RBODChunk::resetStrideRead(QIODevice *d) const { + _readBuffer.clear(); return seek(d); } diff --git a/src/imageformats/chunks_p.h b/src/imageformats/chunks_p.h index 0a7ba46..9efc4d9 100644 --- a/src/imageformats/chunks_p.h +++ b/src/imageformats/chunks_p.h @@ -1964,6 +1964,9 @@ private: QByteArray deinterleave(const QByteArray &planes, qint32 y, const RGHDChunk *header, const RSCMChunk *rcsm = nullptr, const RCOLChunk *rcol = nullptr) const; quint32 strideSize(const RGHDChunk *header) const; + +private: + mutable QByteArray _readBuffer; };