From 950ed43623c92ddaca29a8bd976d78cccd77bd9a Mon Sep 17 00:00:00 2001 From: Mirco Miranda Date: Wed, 12 Jun 2024 22:42:08 +0000 Subject: [PATCH] PXR: Pixar raster read only support Limited read only support to Pixar raster as supported by Photoshop (RGB and Gray 8-bit only). --- README.md | 1 + autotests/CMakeLists.txt | 1 + autotests/read/pxr/testcard_gray.png | Bin 0 -> 5529 bytes autotests/read/pxr/testcard_gray.pxr | Bin 0 -> 66560 bytes autotests/read/pxr/testcard_rgb.png | Bin 0 -> 11750 bytes autotests/read/pxr/testcard_rgb.pxr | Bin 0 -> 197632 bytes src/imageformats/CMakeLists.txt | 4 + src/imageformats/pxr.cpp | 267 +++++++++++++++++++++++++++ src/imageformats/pxr.json | 4 + src/imageformats/pxr_p.h | 37 ++++ 10 files changed, 314 insertions(+) create mode 100644 autotests/read/pxr/testcard_gray.png create mode 100644 autotests/read/pxr/testcard_gray.pxr create mode 100644 autotests/read/pxr/testcard_rgb.png create mode 100644 autotests/read/pxr/testcard_rgb.pxr create mode 100644 src/imageformats/pxr.cpp create mode 100644 src/imageformats/pxr.json create mode 100644 src/imageformats/pxr_p.h diff --git a/README.md b/README.md index 91c3f1e..ff5afe2 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ The following image formats have read-only support: - Gimp (xcf) - Krita (kra) - OpenRaster (ora) +- Pixar raster (pxr) - Photoshop documents (psd, psb, pdd, psdt) - Radiance HDR (hdr) - Sun Raster (im1, im8, im24, im32, ras, sun) diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index 5e300b1..4367eac 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -67,6 +67,7 @@ kimageformats_read_tests( hdr pcx psd + pxr qoi ras rgb diff --git a/autotests/read/pxr/testcard_gray.png b/autotests/read/pxr/testcard_gray.png new file mode 100644 index 0000000000000000000000000000000000000000..aceba2af393d020ea552a94ea3a0c75a039605b8 GIT binary patch literal 5529 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 bhmgMlQPX#0%;|@z00000NkvXXu0mjf=Mrzt literal 0 HcmV?d00001 diff --git a/autotests/read/pxr/testcard_gray.pxr b/autotests/read/pxr/testcard_gray.pxr new file mode 100644 index 0000000000000000000000000000000000000000..3855248e5dbfe96a13ea1447acefa9d54efedbb7 GIT binary patch literal 66560 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 literal 0 HcmV?d00001 diff --git a/autotests/read/pxr/testcard_rgb.png b/autotests/read/pxr/testcard_rgb.png new file mode 100644 index 0000000000000000000000000000000000000000..d1721f55e3770c99b9e082d5d723a89f939e5281 GIT binary patch literal 11750 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 T?Kcj09NrgFN|J@*M*jZ~mbZ6g literal 0 HcmV?d00001 diff --git a/autotests/read/pxr/testcard_rgb.pxr b/autotests/read/pxr/testcard_rgb.pxr new file mode 100644 index 0000000000000000000000000000000000000000..c981a9bef49f36cce6e99931cdf4b7c1a140699d GIT binary patch literal 197632 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 + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#include "pxr_p.h" +#include "util_p.h" + +#include +#include +#include + +Q_DECLARE_LOGGING_CATEGORY(LOG_PXRPLUGIN) +Q_LOGGING_CATEGORY(LOG_PXRPLUGIN, "kf.imageformats.plugins.pxr", QtWarningMsg) + +class PxrHeader +{ +private: + QByteArray m_rawHeader; + + quint16 ui16(quint8 c1, quint8 c2) const { + return (quint16(c2) << 8) | quint16(c1); + } + + quint32 ui32(quint8 c1, quint8 c2, quint8 c3, quint8 c4) const { + return (quint32(c4) << 24) | (quint32(c3) << 16) | (quint32(c2) << 8) | quint32(c1); + } + +public: + PxrHeader() + { + + } + + bool isValid() const + { + return (m_rawHeader.size() == 512 && + m_rawHeader.startsWith(QByteArray::fromRawData("\x80\xE8\x00\x00", 4))); + } + + bool isSupported() const + { + return format() != QImage::Format_Invalid; + } + + qint32 width() const + { + if (!isValid()) { + return 0; + } + return qint32(ui16(m_rawHeader.at(418), m_rawHeader.at(419))); + } + + qint32 height() const + { + if (!isValid()) { + return 0; + } + return qint32(ui16(m_rawHeader.at(416), m_rawHeader.at(417))); + } + + QSize size() const + { + return QSize(width(), height()); + } + + qint32 channel() const + { + if (!isValid()) { + return 0; + } + return qint32(ui16(m_rawHeader.at(424), m_rawHeader.at(425))); + } + + qint32 depth() const + { + if (!isValid()) { + return 0; + } + return qint32(ui16(m_rawHeader.at(426), m_rawHeader.at(427))); + } + + // supposing the image offset (always 1024 on sample files) + qint32 offset() const + { + if (!isValid()) { + return 0; + } + return qint32(ui16(m_rawHeader.at(428), m_rawHeader.at(429))); + } + + QImage::Format format() const + { + if (channel() == 14 && depth() == 2) { + return QImage::Format_RGB888; + } + if (channel() == 8 && depth() == 2) { + return QImage::Format_Grayscale8; + } + return QImage::Format_Invalid; + } + + qsizetype strideSize() const + { + if (format() == QImage::Format_RGB888) { + return width() * 3; + } + if (format() == QImage::Format_Grayscale8) { + return width(); + } + return 0; + } + + bool read(QIODevice *d) + { + m_rawHeader = d->read(512); + return isValid(); + } + + bool peek(QIODevice *d) + { + d->startTransaction(); + auto ok = read(d); + d->rollbackTransaction(); + return ok; + } + + bool jumpToImageData(QIODevice *d) const + { + if (d->isSequential()) { + if (auto sz = std::max(offset() - qint32(m_rawHeader.size()), 0)) { + return d->read(sz).size() == sz; + } + return true; + } + return d->seek(offset()); + } +}; + +PXRHandler::PXRHandler() +{ +} + +bool PXRHandler::canRead() const +{ + if (canRead(device())) { + setFormat("pxr"); + return true; + } + return false; +} + +bool PXRHandler::canRead(QIODevice *device) +{ + if (!device) { + qCWarning(LOG_PXRPLUGIN) << "PXRHandler::canRead() called with no device"; + return false; + } + + PxrHeader h; + if (!h.peek(device)) { + return false; + } + + return h.isSupported(); +} + +bool PXRHandler::read(QImage *image) +{ + PxrHeader header; + + if (!header.read(device())) { + qCWarning(LOG_PXRPLUGIN) << "PXRHandler::read() invalid header"; + return false; + } + + auto img = imageAlloc(header.size(), header.format()); + if (img.isNull()) { + qCWarning(LOG_PXRPLUGIN) << "PXRHandler::read() error while allocating the image"; + return false; + } + + auto d = device(); + if (!header.jumpToImageData(d)) { + qCWarning(LOG_PXRPLUGIN) << "PXRHandler::read() error while seeking image data"; + return false; + } + + auto size = std::min(img.bytesPerLine(), header.strideSize()); + for (auto y = 0, h = img.height(); y < h; ++y) { + auto line = reinterpret_cast(img.scanLine(y)); + if (d->read(line, size) != size) { + qCWarning(LOG_PXRPLUGIN) << "PXRHandler::read() error while reading image scanline"; + return false; + } + } + + *image = img; + return true; +} + +bool PXRHandler::supportsOption(ImageOption option) const +{ + if (option == QImageIOHandler::Size) { + return true; + } + if (option == QImageIOHandler::ImageFormat) { + return true; + } + return false; +} + +QVariant PXRHandler::option(ImageOption option) const +{ + QVariant v; + + if (option == QImageIOHandler::Size) { + if (auto d = device()) { + PxrHeader h; + if (h.peek(d)) { + v = QVariant::fromValue(h.size()); + } + } + } + + if (option == QImageIOHandler::ImageFormat) { + if (auto d = device()) { + PxrHeader h; + if (h.peek(d)) { + v = QVariant::fromValue(h.format()); + } + } + } + + return v; +} + +QImageIOPlugin::Capabilities PXRPlugin::capabilities(QIODevice *device, const QByteArray &format) const +{ + if (format == "pxr") { + return Capabilities(CanRead); + } + if (!format.isEmpty()) { + return {}; + } + if (!device->isOpen()) { + return {}; + } + + Capabilities cap; + if (device->isReadable() && PXRHandler::canRead(device)) { + cap |= CanRead; + } + return cap; +} + +QImageIOHandler *PXRPlugin::create(QIODevice *device, const QByteArray &format) const +{ + QImageIOHandler *handler = new PXRHandler; + handler->setDevice(device); + handler->setFormat(format); + return handler; +} + +#include "moc_pxr_p.cpp" diff --git a/src/imageformats/pxr.json b/src/imageformats/pxr.json new file mode 100644 index 0000000..d7f617f --- /dev/null +++ b/src/imageformats/pxr.json @@ -0,0 +1,4 @@ +{ + "Keys": [ "pxr" ], + "MimeTypes": [ "image/x-pxr" ] +} diff --git a/src/imageformats/pxr_p.h b/src/imageformats/pxr_p.h new file mode 100644 index 0000000..ddf38bb --- /dev/null +++ b/src/imageformats/pxr_p.h @@ -0,0 +1,37 @@ +/* + This file is part of the KDE project + SPDX-FileCopyrightText: 2024 Mirco Miranda + + SPDX-License-Identifier: LGPL-2.0-or-later +*/ + +#ifndef KIMG_PXR_P_H +#define KIMG_PXR_P_H + +#include + +class PXRHandler : public QImageIOHandler +{ +public: + PXRHandler(); + + bool canRead() const override; + bool read(QImage *image) override; + + bool supportsOption(QImageIOHandler::ImageOption option) const override; + QVariant option(QImageIOHandler::ImageOption option) const override; + + static bool canRead(QIODevice *device); +}; + +class PXRPlugin : public QImageIOPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "pxr.json") + +public: + Capabilities capabilities(QIODevice *device, const QByteArray &format) const override; + QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const override; +}; + +#endif // KIMG_PXR_P_H