mirror of
https://invent.kde.org/frameworks/kimageformats.git
synced 2025-06-03 17:08:08 -04:00
SCT: added read only support
I keep adding old formats to ensure interoperability with as many programs as possible... This plugin adds read-only support for the Scitex SCT format only. This format is also supported by Photoshop in read and write (SCT test cases were created by Photoshop). [Scitex HandShake Formats Specifications](/uploads/a3e213e48349d898b260375d6c052521/Scitex_HandShake_Formats.pdf)
This commit is contained in:
parent
d233e80dbb
commit
4dedd88c08
@ -22,6 +22,7 @@ The following image formats have read-only support:
|
|||||||
- Portable FloatMap (pfm)
|
- Portable FloatMap (pfm)
|
||||||
- Photoshop documents (psd, psb, pdd, psdt)
|
- Photoshop documents (psd, psb, pdd, psdt)
|
||||||
- Radiance HDR (hdr)
|
- Radiance HDR (hdr)
|
||||||
|
- Scitex CT (sct)
|
||||||
- Sun Raster (im1, im8, im24, im32, ras, sun)
|
- Sun Raster (im1, im8, im24, im32, ras, sun)
|
||||||
|
|
||||||
The following image formats have read and write support:
|
The following image formats have read and write support:
|
||||||
@ -127,6 +128,7 @@ plugin ('n/a' means no limit, i.e. the limit depends on the format encoding).
|
|||||||
- RAS: n/a (large image)
|
- RAS: n/a (large image)
|
||||||
- RAW: n/a (depends on the RAW format loaded)
|
- RAW: n/a (depends on the RAW format loaded)
|
||||||
- RGB: 65,535 x 65,535 pixels
|
- RGB: 65,535 x 65,535 pixels
|
||||||
|
- SCT: 300,000 x 300,000 pixels
|
||||||
- TGA: 65,535 x 65,535 pixels
|
- TGA: 65,535 x 65,535 pixels
|
||||||
- XCF: 300,000 x 300,000 pixels
|
- XCF: 300,000 x 300,000 pixels
|
||||||
|
|
||||||
@ -157,7 +159,7 @@ been used or the maximum size of the image that can be saved has been limited.
|
|||||||
PSD plugin loads CMYK, Lab and Multichannel images and converts them to RGB
|
PSD plugin loads CMYK, Lab and Multichannel images and converts them to RGB
|
||||||
without using the ICC profile.
|
without using the ICC profile.
|
||||||
|
|
||||||
JXR and PSD plugins natively support 4-channel CMYK images when compiled
|
JXR, PSD and SCT plugins natively support 4-channel CMYK images when compiled
|
||||||
with Qt 6.8+.
|
with Qt 6.8+.
|
||||||
|
|
||||||
### The HEIF plugin
|
### The HEIF plugin
|
||||||
|
@ -72,6 +72,7 @@ kimageformats_read_tests(
|
|||||||
qoi
|
qoi
|
||||||
ras
|
ras
|
||||||
rgb
|
rgb
|
||||||
|
sct
|
||||||
tga
|
tga
|
||||||
)
|
)
|
||||||
|
|
||||||
|
BIN
autotests/read/sct/cmyk.sct
Normal file
BIN
autotests/read/sct/cmyk.sct
Normal file
Binary file not shown.
11
autotests/read/sct/cmyk.sct.json
Normal file
11
autotests/read/sct/cmyk.sct.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"minQtVersion" : "6.8.0",
|
||||||
|
"fileName" : "cmyk.tif"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"maxQtVersion" : "6.7.99",
|
||||||
|
"unsupportedFormat" : true,
|
||||||
|
"comment" : "Qt versions lower than 6.8 do not support CMYK format so this test should be skipped."
|
||||||
|
}
|
||||||
|
]
|
BIN
autotests/read/sct/cmyk.tif
Normal file
BIN
autotests/read/sct/cmyk.tif
Normal file
Binary file not shown.
BIN
autotests/read/sct/gray.png
Normal file
BIN
autotests/read/sct/gray.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
BIN
autotests/read/sct/gray.sct
Normal file
BIN
autotests/read/sct/gray.sct
Normal file
Binary file not shown.
BIN
autotests/read/sct/rgb.png
Normal file
BIN
autotests/read/sct/rgb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
BIN
autotests/read/sct/rgb.sct
Normal file
BIN
autotests/read/sct/rgb.sct
Normal file
Binary file not shown.
@ -107,6 +107,10 @@ kimageformats_add_plugin(kimg_rgb SOURCES rgb.cpp)
|
|||||||
|
|
||||||
##################################
|
##################################
|
||||||
|
|
||||||
|
kimageformats_add_plugin(kimg_sct SOURCES scitex.cpp)
|
||||||
|
|
||||||
|
##################################
|
||||||
|
|
||||||
kimageformats_add_plugin(kimg_tga SOURCES tga.cpp)
|
kimageformats_add_plugin(kimg_tga SOURCES tga.cpp)
|
||||||
|
|
||||||
##################################
|
##################################
|
||||||
|
459
src/imageformats/scitex.cpp
Normal file
459
src/imageformats/scitex.cpp
Normal file
@ -0,0 +1,459 @@
|
|||||||
|
/*
|
||||||
|
This file is part of the KDE project
|
||||||
|
SPDX-FileCopyrightText: 2024 Mirco Miranda <mircomir@outlook.com>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "scitex_p.h"
|
||||||
|
#include "scanlineconverter_p.h"
|
||||||
|
#include "util_p.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
#include <QIODevice>
|
||||||
|
#include <QBuffer>
|
||||||
|
#include <QImage>
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(LOG_IFFPLUGIN)
|
||||||
|
Q_LOGGING_CATEGORY(LOG_IFFPLUGIN, "kf.imageformats.plugins.scitex", QtWarningMsg)
|
||||||
|
|
||||||
|
#define CTRLBLOCK_SIZE 256
|
||||||
|
#define PRMSBLOCK_SIZE_CT 256
|
||||||
|
|
||||||
|
// For file stored on disk, each block is followed by 768 pads
|
||||||
|
#define HEADER_SIZE_CT (CTRLBLOCK_SIZE + PRMSBLOCK_SIZE_CT + 768 + 768)
|
||||||
|
|
||||||
|
#define FILETYPE_CT "CT"
|
||||||
|
#define FILETYPE_LW "LW"
|
||||||
|
#define FILETYPE_BM "BM"
|
||||||
|
#define FILETYPE_PG "PG"
|
||||||
|
#define FILETYPE_TX "TX"
|
||||||
|
|
||||||
|
class ScitexCtrlBlock
|
||||||
|
{
|
||||||
|
using pchar_t = char *;
|
||||||
|
public:
|
||||||
|
ScitexCtrlBlock() {}
|
||||||
|
ScitexCtrlBlock(const ScitexCtrlBlock& other) = default;
|
||||||
|
ScitexCtrlBlock& operator =(const ScitexCtrlBlock& other) = default;
|
||||||
|
|
||||||
|
bool load(QIODevice *device)
|
||||||
|
{
|
||||||
|
auto ok = (device && device->isOpen());
|
||||||
|
ok = ok && device->read(pchar_t(_name.data()), _name.size()) == qint64(_name.size());
|
||||||
|
ok = ok && device->read(pchar_t(_fileType.data()), _fileType.size()) == qint64(_fileType.size());
|
||||||
|
ok = ok && device->read(pchar_t(_blockSize.data()), _blockSize.size()) == qint64(_blockSize.size());
|
||||||
|
ok = ok && device->read(pchar_t(_reserved.data()), _reserved.size()) == qint64(_reserved.size());
|
||||||
|
ok = ok && device->read(pchar_t(&_count), sizeof(_count)) == qint64(sizeof(_count));
|
||||||
|
ok = ok && device->read(pchar_t(_padding.data()), _padding.size()) == qint64(_padding.size());
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString name() const
|
||||||
|
{
|
||||||
|
return QString::fromLatin1(pchar_t(_name.data()), _name.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString fileType() const
|
||||||
|
{
|
||||||
|
return QString::fromLatin1(pchar_t(_fileType.data()), _fileType.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
quint8 sequenceCount() const
|
||||||
|
{
|
||||||
|
return _count;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<quint8, 80> _name = {};
|
||||||
|
std::array<quint8, 2> _fileType = {};
|
||||||
|
std::array<quint8, 12> _blockSize = {};
|
||||||
|
std::array<quint8, 12> _reserved = {};
|
||||||
|
quint8 _count = 0;
|
||||||
|
std::array<quint8, 149> _padding = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScitexParamsBlock
|
||||||
|
{
|
||||||
|
using pchar_t = char *;
|
||||||
|
public:
|
||||||
|
ScitexParamsBlock() {}
|
||||||
|
ScitexParamsBlock(const ScitexParamsBlock& other) = default;
|
||||||
|
ScitexParamsBlock& operator =(const ScitexParamsBlock& other) = default;
|
||||||
|
|
||||||
|
bool load(QIODevice *device)
|
||||||
|
{
|
||||||
|
auto ok = (device && device->isOpen());
|
||||||
|
ok = ok && device->read(pchar_t(&_unitsOfMeasurement), sizeof(_unitsOfMeasurement)) == qint64(sizeof(_unitsOfMeasurement));
|
||||||
|
ok = ok && device->read(pchar_t(&_numOfColorSeparations), sizeof(_numOfColorSeparations)) == qint64(sizeof(_numOfColorSeparations));
|
||||||
|
ok = ok && device->read(pchar_t(_separationBitMask.data()), _separationBitMask.size()) == qint64(_separationBitMask.size());
|
||||||
|
ok = ok && device->read(pchar_t(_heightInUnits.data()), _heightInUnits.size()) == qint64(_heightInUnits.size());
|
||||||
|
ok = ok && device->read(pchar_t(_widthInUnits.data()), _widthInUnits.size()) == qint64(_widthInUnits.size());
|
||||||
|
ok = ok && device->read(pchar_t(_heightInPixels.data()), _heightInPixels.size()) == qint64(_heightInPixels.size());
|
||||||
|
ok = ok && device->read(pchar_t(_widthInPixels.data()), _widthInPixels.size()) == qint64(_widthInPixels.size());
|
||||||
|
ok = ok && device->read(pchar_t(&_scanDirection), sizeof(_scanDirection)) == qint64(sizeof(_scanDirection));
|
||||||
|
ok = ok && device->read(pchar_t(_reserved.data()), _reserved.size()) == qint64(_reserved.size());
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint8 colorCount() const
|
||||||
|
{
|
||||||
|
return _numOfColorSeparations;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 bitMask() const
|
||||||
|
{
|
||||||
|
return ((_separationBitMask.at(0) << 8) | _separationBitMask.at(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
quint8 _unitsOfMeasurement = 0;
|
||||||
|
quint8 _numOfColorSeparations = 0;
|
||||||
|
std::array<quint8, 2> _separationBitMask = {};
|
||||||
|
std::array<quint8, 14> _heightInUnits = {};
|
||||||
|
std::array<quint8, 14> _widthInUnits = {};
|
||||||
|
std::array<quint8, 12> _heightInPixels = {};
|
||||||
|
std::array<quint8, 12> _widthInPixels = {};
|
||||||
|
quint8 _scanDirection = 0;
|
||||||
|
std::array<quint8, 199> _reserved = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScitexHandlerPrivate
|
||||||
|
{
|
||||||
|
using pchar_t = char *;
|
||||||
|
public:
|
||||||
|
ScitexHandlerPrivate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~ScitexHandlerPrivate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief isSupported
|
||||||
|
* \return If the plugin can load it.
|
||||||
|
*/
|
||||||
|
bool isSupported() const
|
||||||
|
{
|
||||||
|
if (!isValid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Set a reasonable upper limit
|
||||||
|
if (width() > 300000 || height() > 300000) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return m_cb.fileType() == QStringLiteral(FILETYPE_CT) && format() != QImage::Format_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief isValid
|
||||||
|
* \return True if is a valid Scitex image file.
|
||||||
|
*/
|
||||||
|
bool isValid() const
|
||||||
|
{
|
||||||
|
if (width() == 0 || height() == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QStringList ft = {
|
||||||
|
QStringLiteral(FILETYPE_CT),
|
||||||
|
QStringLiteral(FILETYPE_LW),
|
||||||
|
QStringLiteral(FILETYPE_BM),
|
||||||
|
QStringLiteral(FILETYPE_PG),
|
||||||
|
QStringLiteral(FILETYPE_TX)
|
||||||
|
};
|
||||||
|
return ft.contains(m_cb.fileType());
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage::Format format() const
|
||||||
|
{
|
||||||
|
auto format = QImage::Format_Invalid;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||||
|
if (m_pb.colorCount() == 4) {
|
||||||
|
if (m_pb.bitMask() == 15)
|
||||||
|
format = QImage::Format_CMYK8888;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (m_pb.colorCount() == 3) {
|
||||||
|
if (m_pb.bitMask() == 7)
|
||||||
|
format = QImage::Format_RGB888;
|
||||||
|
}
|
||||||
|
if (m_pb.colorCount() == 1) {
|
||||||
|
if (m_pb.bitMask() == 8)
|
||||||
|
format = QImage::Format_Grayscale8;
|
||||||
|
}
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint32 width() const
|
||||||
|
{
|
||||||
|
auto ok = false;
|
||||||
|
auto&& px = m_pb._widthInPixels;
|
||||||
|
auto v = QString::fromLatin1(pchar_t(px.data()), px.size()).toUInt(&ok);
|
||||||
|
return ok ? v : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint32 height() const
|
||||||
|
{
|
||||||
|
auto ok = false;
|
||||||
|
auto&& px = m_pb._heightInPixels;
|
||||||
|
auto v = QString::fromLatin1(pchar_t(px.data()), px.size()).toUInt(&ok);
|
||||||
|
return ok ? v : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint32 dotsPerMeterX() const {
|
||||||
|
auto ok = false;
|
||||||
|
auto&& res = m_pb._widthInUnits;
|
||||||
|
auto v = QString::fromLatin1(pchar_t(res.data()), res.size()).toDouble(&ok);
|
||||||
|
if (ok && v > 0) {
|
||||||
|
if (m_pb._unitsOfMeasurement) { // Inches
|
||||||
|
return qRound(width() / v / 25.4 * 1000);
|
||||||
|
}
|
||||||
|
// Millimeters
|
||||||
|
return qRound(width() / v * 1000);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint32 dotsPerMeterY() const {
|
||||||
|
auto ok = false;
|
||||||
|
auto&& res = m_pb._heightInUnits;
|
||||||
|
auto v = QString::fromLatin1(pchar_t(res.data()), res.size()).toDouble(&ok);
|
||||||
|
if (ok && v > 0) {
|
||||||
|
if (m_pb._unitsOfMeasurement) { // Inches
|
||||||
|
return qRound(width() / v / 25.4 * 1000);
|
||||||
|
}
|
||||||
|
// Millimeters
|
||||||
|
return qRound(width() / v * 1000);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImageIOHandler::Transformation transformation() const
|
||||||
|
{
|
||||||
|
auto t = QImageIOHandler::TransformationNone;
|
||||||
|
switch (m_pb._scanDirection) {
|
||||||
|
case 1:
|
||||||
|
t = QImageIOHandler::TransformationFlip;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
t = QImageIOHandler::TransformationMirror;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
t = QImageIOHandler::TransformationRotate180;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
t = QImageIOHandler::TransformationFlipAndRotate90;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
t = QImageIOHandler::TransformationRotate270;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
t = QImageIOHandler::TransformationRotate90;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
t = QImageIOHandler::TransformationMirrorAndRotate90;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
t = QImageIOHandler::TransformationNone;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool peekHeader(QIODevice *device)
|
||||||
|
{
|
||||||
|
if (device == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto ba = device->peek(HEADER_SIZE_CT);
|
||||||
|
if (ba.size() != HEADER_SIZE_CT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QBuffer b;
|
||||||
|
b.setData(ba);
|
||||||
|
if (!b.open(QIODevice::ReadOnly)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return loadHeader(&b);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool loadHeader(QIODevice *device) {
|
||||||
|
if (device == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!m_cb.load(device)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto pad1 = device->read(768);
|
||||||
|
if (pad1.size() != 768) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!m_pb.load(device)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto pad2 = device->read(768);
|
||||||
|
if (pad2.size() != 768) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScitexCtrlBlock m_cb;
|
||||||
|
ScitexParamsBlock m_pb;
|
||||||
|
};
|
||||||
|
|
||||||
|
ScitexHandler::ScitexHandler()
|
||||||
|
: QImageIOHandler()
|
||||||
|
, d(new ScitexHandlerPrivate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScitexHandler::canRead() const
|
||||||
|
{
|
||||||
|
if (canRead(device())) {
|
||||||
|
setFormat("sct");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScitexHandler::canRead(QIODevice *device)
|
||||||
|
{
|
||||||
|
if (!device) {
|
||||||
|
qWarning("ScitexHandler::canRead() called with no device");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ScitexHandlerPrivate hp;
|
||||||
|
if (hp.peekHeader(device)) {
|
||||||
|
return hp.isSupported();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScitexHandler::read(QImage *image)
|
||||||
|
{
|
||||||
|
auto dev = device();
|
||||||
|
if (dev == nullptr) {
|
||||||
|
qWarning("ScitexHandler::read() called with no device");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!d->loadHeader(dev)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!d->isSupported()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto img = imageAlloc(d->width(), d->height(), d->format());
|
||||||
|
if (img.isNull()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto hres = d->dotsPerMeterX();
|
||||||
|
if (hres > 0) {
|
||||||
|
img.setDotsPerMeterX(hres);
|
||||||
|
}
|
||||||
|
auto vres = d->dotsPerMeterY();
|
||||||
|
if (vres > 0) {
|
||||||
|
img.setDotsPerMeterY(vres);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray line(img.width() * d->m_pb.colorCount(), char());
|
||||||
|
if (img.bytesPerLine() < line.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (qint32 y = 0, h = img.height(); y < h; ++y) {
|
||||||
|
if (dev->read(line.data(), line.size()) != line.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto scanLine = img.scanLine(y);
|
||||||
|
for (qint32 c = 0, cc = d->m_pb.colorCount(); c < cc; ++c) {
|
||||||
|
for (qint32 x = 0, w = img.width(); x < w; ++x) {
|
||||||
|
scanLine[x * cc + c] = cc == 4 ? uchar(255) - uchar(line.at(c * w + x)) : uchar(line.at(c * w + x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*image = img;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScitexHandler::supportsOption(ImageOption option) const
|
||||||
|
{
|
||||||
|
if (option == QImageIOHandler::Size) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option == QImageIOHandler::ImageFormat) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option == QImageIOHandler::ImageTransformation) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ScitexHandler::option(ImageOption option) const
|
||||||
|
{
|
||||||
|
QVariant v;
|
||||||
|
|
||||||
|
if (option == QImageIOHandler::Size) {
|
||||||
|
if (!d->isValid()) {
|
||||||
|
d->peekHeader(device());
|
||||||
|
}
|
||||||
|
if (d->isSupported()) {
|
||||||
|
v = QSize(d->width(), d->height());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option == QImageIOHandler::ImageFormat) {
|
||||||
|
if (!d->isValid()) {
|
||||||
|
d->peekHeader(device());
|
||||||
|
}
|
||||||
|
if (d->isSupported()) {
|
||||||
|
v = d->format();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option == QImageIOHandler::ImageTransformation) {
|
||||||
|
if (!d->isValid()) {
|
||||||
|
d->peekHeader(device());
|
||||||
|
}
|
||||||
|
if (d->isSupported()) {
|
||||||
|
v = int(d->transformation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImageIOPlugin::Capabilities ScitexPlugin::capabilities(QIODevice *device, const QByteArray &format) const
|
||||||
|
{
|
||||||
|
if (format == "sct") {
|
||||||
|
return Capabilities(CanRead);
|
||||||
|
}
|
||||||
|
if (!format.isEmpty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (!device->isOpen()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Capabilities cap;
|
||||||
|
if (device->isReadable() && ScitexHandler::canRead(device)) {
|
||||||
|
cap |= CanRead;
|
||||||
|
}
|
||||||
|
return cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImageIOHandler *ScitexPlugin::create(QIODevice *device, const QByteArray &format) const
|
||||||
|
{
|
||||||
|
QImageIOHandler *handler = new ScitexHandler;
|
||||||
|
handler->setDevice(device);
|
||||||
|
handler->setFormat(format);
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
4
src/imageformats/scitex.json
Normal file
4
src/imageformats/scitex.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"Keys": [ "sct" ],
|
||||||
|
"MimeTypes": [ "image/x-sct" ]
|
||||||
|
}
|
42
src/imageformats/scitex_p.h
Normal file
42
src/imageformats/scitex_p.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
This file is part of the KDE project
|
||||||
|
SPDX-FileCopyrightText: 2024 Mirco Miranda <mircomir@outlook.com>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SIMG_SCITEX_P_H
|
||||||
|
#define SIMG_SCITEX_P_H
|
||||||
|
|
||||||
|
#include <QImageIOPlugin>
|
||||||
|
#include <QScopedPointer>
|
||||||
|
|
||||||
|
class ScitexHandlerPrivate;
|
||||||
|
class ScitexHandler : public QImageIOHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScitexHandler();
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const QScopedPointer<ScitexHandlerPrivate> d;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScitexPlugin : public QImageIOPlugin
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "scitex.json")
|
||||||
|
|
||||||
|
public:
|
||||||
|
Capabilities capabilities(QIODevice *device, const QByteArray &format) const override;
|
||||||
|
QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SIMG_SCITEX_P_H
|
Loading…
x
Reference in New Issue
Block a user