exr: Fix read/write with openexr 3.3

It really wants to have a filename

Also it uses seek and tell a lot so sequential devices are for now not
supported

BUGS: 494571
This commit is contained in:
Albert Astals Cid 2024-10-12 01:42:26 +02:00
parent b5d5abe0ea
commit 7d696a81d2

View File

@ -86,8 +86,8 @@
class K_IStream : public Imf::IStream class K_IStream : public Imf::IStream
{ {
public: public:
K_IStream(QIODevice *dev, const QByteArray &fileName) K_IStream(QIODevice *dev)
: IStream(fileName.data()) : IStream("K_IStream")
, m_dev(dev) , m_dev(dev)
{ {
} }
@ -145,8 +145,8 @@ void K_IStream::clear()
class K_OStream : public Imf::OStream class K_OStream : public Imf::OStream
{ {
public: public:
K_OStream(QIODevice *dev, const QByteArray &fileName) K_OStream(QIODevice *dev)
: OStream(fileName.data()) : OStream("K_OStream")
, m_dev(dev) , m_dev(dev)
{ {
} }
@ -360,7 +360,7 @@ bool EXRHandler::read(QImage *outImage)
} }
} }
K_IStream istr(d, QByteArray()); K_IStream istr(d);
Imf::RgbaInputFile file(istr); Imf::RgbaInputFile file(istr);
auto &&header = file.header(); auto &&header = file.header();
@ -583,7 +583,7 @@ bool EXRHandler::write(const QImage &image)
setMetadata(image, header); setMetadata(image, header);
// write the EXR // write the EXR
K_OStream ostr(device(), QByteArray()); K_OStream ostr(device());
auto channelsType = image.hasAlphaChannel() ? Imf::RgbaChannels::WRITE_RGBA : Imf::RgbaChannels::WRITE_RGB; auto channelsType = image.hasAlphaChannel() ? Imf::RgbaChannels::WRITE_RGBA : Imf::RgbaChannels::WRITE_RGB;
if (image.format() == QImage::Format_Mono || if (image.format() == QImage::Format_Mono ||
image.format() == QImage::Format_MonoLSB || image.format() == QImage::Format_MonoLSB ||
@ -673,7 +673,7 @@ QVariant EXRHandler::option(ImageOption option) const
d->seek(m_startPos); d->seek(m_startPos);
} }
try { try {
K_IStream istr(d, QByteArray()); K_IStream istr(d);
Imf::RgbaInputFile file(istr); Imf::RgbaInputFile file(istr);
if (m_imageNumber > -1) { // set the image to read if (m_imageNumber > -1) { // set the image to read
auto views = viewList(file.header()); auto views = viewList(file.header());
@ -698,7 +698,7 @@ QVariant EXRHandler::option(ImageOption option) const
d->seek(m_startPos); d->seek(m_startPos);
} }
try { try {
K_IStream istr(d, QByteArray()); K_IStream istr(d);
Imf::RgbaInputFile file(istr); Imf::RgbaInputFile file(istr);
v = QVariant::fromValue(imageFormat(file)); v = QVariant::fromValue(imageFormat(file));
} catch (const std::exception &) { } catch (const std::exception &) {
@ -747,7 +747,7 @@ int EXRHandler::imageCount() const
d->startTransaction(); d->startTransaction();
try { try {
K_IStream istr(d, QByteArray()); K_IStream istr(d);
Imf::RgbaInputFile file(istr); Imf::RgbaInputFile file(istr);
auto views = viewList(file.header()); auto views = viewList(file.header());
if (!views.isEmpty()) { if (!views.isEmpty()) {
@ -774,6 +774,13 @@ bool EXRHandler::canRead(QIODevice *device)
return false; return false;
} }
#if OPENEXR_VERSION_MAJOR == 3 && OPENEXR_VERSION_MINOR > 2
// openexpr >= 3.3 uses seek and tell extensively
if (device->isSequential()) {
return false;
}
#endif
const QByteArray head = device->peek(4); const QByteArray head = device->peek(4);
return Imf::isImfMagic(head.data()); return Imf::isImfMagic(head.data());