Simplified read/verify header process

Where possible, QIODevice::peek has been used instead of transactions or instead of using ungetchar() for sequential access devices and seek() for random access devices.

Furthermore:
- RAS format gained the ability of read on sequential devices.
- Removed unused code in XCF (still related to ungetchar and sequential devices).
- These changes should prevent errors like the ones fixed by MR !258
This commit is contained in:
Mirco Miranda
2024-10-06 17:26:25 +00:00
committed by Albert Astals Cid
parent fee0165bef
commit 97120b2537
7 changed files with 51 additions and 180 deletions

View File

@@ -4229,66 +4229,43 @@ bool XCFHandler::canRead(QIODevice *device)
}
const qint64 oldPos = device->pos();
if (!device->isSequential()) {
QDataStream ds(device);
XCFImageFormat::XCFImage::Header header;
bool failed = !XCFImageFormat::readXCFHeader(ds, &header);
ds.setDevice(nullptr);
device->seek(oldPos);
if (failed) {
return false;
}
switch (header.precision) {
case XCFImageFormat::GIMP_PRECISION_HALF_LINEAR:
case XCFImageFormat::GIMP_PRECISION_HALF_NON_LINEAR:
case XCFImageFormat::GIMP_PRECISION_HALF_PERCEPTUAL:
case XCFImageFormat::GIMP_PRECISION_FLOAT_LINEAR:
case XCFImageFormat::GIMP_PRECISION_FLOAT_NON_LINEAR:
case XCFImageFormat::GIMP_PRECISION_FLOAT_PERCEPTUAL:
case XCFImageFormat::GIMP_PRECISION_U8_LINEAR:
case XCFImageFormat::GIMP_PRECISION_U8_NON_LINEAR:
case XCFImageFormat::GIMP_PRECISION_U8_PERCEPTUAL:
case XCFImageFormat::GIMP_PRECISION_U16_LINEAR:
case XCFImageFormat::GIMP_PRECISION_U16_NON_LINEAR:
case XCFImageFormat::GIMP_PRECISION_U16_PERCEPTUAL:
case XCFImageFormat::GIMP_PRECISION_U32_LINEAR:
case XCFImageFormat::GIMP_PRECISION_U32_NON_LINEAR:
case XCFImageFormat::GIMP_PRECISION_U32_PERCEPTUAL:
break;
case XCFImageFormat::GIMP_PRECISION_DOUBLE_LINEAR:
case XCFImageFormat::GIMP_PRECISION_DOUBLE_NON_LINEAR:
case XCFImageFormat::GIMP_PRECISION_DOUBLE_PERCEPTUAL:
default:
qCDebug(XCFPLUGIN) << "unsupported precision" << header.precision;
return false;
}
QDataStream ds(device);
XCFImageFormat::XCFImage::Header header;
bool failed = !XCFImageFormat::readXCFHeader(ds, &header);
ds.setDevice(nullptr);
return true;
}
char head[8];
qint64 readBytes = device->read(head, sizeof(head));
if (readBytes != sizeof(head)) {
if (device->isSequential()) {
while (readBytes > 0) {
device->ungetChar(head[readBytes-- - 1]);
}
} else {
device->seek(oldPos);
}
device->seek(oldPos);
if (failed) {
return false;
}
if (device->isSequential()) {
while (readBytes > 0) {
device->ungetChar(head[readBytes-- - 1]);
}
} else {
device->seek(oldPos);
switch (header.precision) {
case XCFImageFormat::GIMP_PRECISION_HALF_LINEAR:
case XCFImageFormat::GIMP_PRECISION_HALF_NON_LINEAR:
case XCFImageFormat::GIMP_PRECISION_HALF_PERCEPTUAL:
case XCFImageFormat::GIMP_PRECISION_FLOAT_LINEAR:
case XCFImageFormat::GIMP_PRECISION_FLOAT_NON_LINEAR:
case XCFImageFormat::GIMP_PRECISION_FLOAT_PERCEPTUAL:
case XCFImageFormat::GIMP_PRECISION_U8_LINEAR:
case XCFImageFormat::GIMP_PRECISION_U8_NON_LINEAR:
case XCFImageFormat::GIMP_PRECISION_U8_PERCEPTUAL:
case XCFImageFormat::GIMP_PRECISION_U16_LINEAR:
case XCFImageFormat::GIMP_PRECISION_U16_NON_LINEAR:
case XCFImageFormat::GIMP_PRECISION_U16_PERCEPTUAL:
case XCFImageFormat::GIMP_PRECISION_U32_LINEAR:
case XCFImageFormat::GIMP_PRECISION_U32_NON_LINEAR:
case XCFImageFormat::GIMP_PRECISION_U32_PERCEPTUAL:
break;
case XCFImageFormat::GIMP_PRECISION_DOUBLE_LINEAR:
case XCFImageFormat::GIMP_PRECISION_DOUBLE_NON_LINEAR:
case XCFImageFormat::GIMP_PRECISION_DOUBLE_PERCEPTUAL:
default:
qCDebug(XCFPLUGIN) << "unsupported precision" << header.precision;
return false;
}
return qstrncmp(head, "gimp xcf", 8) == 0;
return true;
}
QImageIOPlugin::Capabilities XCFPlugin::capabilities(QIODevice *device, const QByteArray &format) const