mirror of
https://invent.kde.org/frameworks/kimageformats.git
synced 2025-05-28 00:30:23 -04:00
Fixes for sequential devices
This commit is contained in:
parent
49bd131eef
commit
c96ad6ba8a
BIN
autotests/read/pcx/indexed8.pcx
Normal file
BIN
autotests/read/pcx/indexed8.pcx
Normal file
Binary file not shown.
BIN
autotests/read/pcx/indexed8.png
Normal file
BIN
autotests/read/pcx/indexed8.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
@ -9,6 +9,7 @@
|
|||||||
#include <QCommandLineParser>
|
#include <QCommandLineParser>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QImageReader>
|
#include <QImageReader>
|
||||||
@ -18,6 +19,44 @@
|
|||||||
|
|
||||||
#include "fuzzyeq.cpp"
|
#include "fuzzyeq.cpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The SequentialFile class
|
||||||
|
* Class to make a file a sequential device. This class is used to check if the plugins could works
|
||||||
|
* on a sequential device such as a socket.
|
||||||
|
*/
|
||||||
|
class SequentialFile : public QFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SequentialFile()
|
||||||
|
: QFile()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
explicit SequentialFile(const QString &name)
|
||||||
|
: QFile(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#ifndef QT_NO_QOBJECT
|
||||||
|
explicit SequentialFile(QObject *parent)
|
||||||
|
: QFile(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
SequentialFile(const QString &name, QObject *parent)
|
||||||
|
: QFile(name, parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool isSequential() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 size() const override
|
||||||
|
{
|
||||||
|
return bytesAvailable();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static void writeImageData(const char *name, const QString &filename, const QImage &image)
|
static void writeImageData(const char *name, const QString &filename, const QImage &image)
|
||||||
{
|
{
|
||||||
QFile file(filename);
|
QFile file(filename);
|
||||||
@ -56,7 +95,7 @@ int main(int argc, char **argv)
|
|||||||
QCoreApplication::removeLibraryPath(QStringLiteral(PLUGIN_DIR));
|
QCoreApplication::removeLibraryPath(QStringLiteral(PLUGIN_DIR));
|
||||||
QCoreApplication::addLibraryPath(QStringLiteral(PLUGIN_DIR));
|
QCoreApplication::addLibraryPath(QStringLiteral(PLUGIN_DIR));
|
||||||
QCoreApplication::setApplicationName(QStringLiteral("readtest"));
|
QCoreApplication::setApplicationName(QStringLiteral("readtest"));
|
||||||
QCoreApplication::setApplicationVersion(QStringLiteral("1.0.0"));
|
QCoreApplication::setApplicationVersion(QStringLiteral("1.1.0"));
|
||||||
|
|
||||||
QCommandLineParser parser;
|
QCommandLineParser parser;
|
||||||
parser.setApplicationDescription(QStringLiteral("Performs basic image conversion checking."));
|
parser.setApplicationDescription(QStringLiteral("Performs basic image conversion checking."));
|
||||||
@ -98,6 +137,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
int passed = 0;
|
int passed = 0;
|
||||||
int failed = 0;
|
int failed = 0;
|
||||||
|
int skipped = 0;
|
||||||
|
|
||||||
QTextStream(stdout) << "********* "
|
QTextStream(stdout) << "********* "
|
||||||
<< "Starting basic read tests for " << suffix << " images *********\n";
|
<< "Starting basic read tests for " << suffix << " images *********\n";
|
||||||
@ -111,72 +151,88 @@ int main(int argc, char **argv)
|
|||||||
QTextStream(stdout) << "QImageReader::supportedImageFormats: " << formatStrings.join(", ") << "\n";
|
QTextStream(stdout) << "QImageReader::supportedImageFormats: " << formatStrings.join(", ") << "\n";
|
||||||
|
|
||||||
const QFileInfoList lstImgDir = imgdir.entryInfoList();
|
const QFileInfoList lstImgDir = imgdir.entryInfoList();
|
||||||
for (const QFileInfo &fi : lstImgDir) {
|
// Launch 2 runs for each test: first run on a random device, second run on a sequential device
|
||||||
if (!fi.suffix().compare("png", Qt::CaseInsensitive)) {
|
for (int seq = 0; seq < 2; ++seq) {
|
||||||
continue;
|
if (seq) {
|
||||||
}
|
QTextStream(stdout) << "* Run on SEQUENTIAL device (SKIP = no sequential support and it's OK)\n";
|
||||||
int suffixPos = fi.filePath().count() - suffix.count();
|
|
||||||
QString inputfile = fi.filePath();
|
|
||||||
QString expfile = fi.filePath().replace(suffixPos, suffix.count(), QStringLiteral("png"));
|
|
||||||
QString expfilename = QFileInfo(expfile).fileName();
|
|
||||||
|
|
||||||
QImageReader inputReader(inputfile, format);
|
|
||||||
QImageReader expReader(expfile, "png");
|
|
||||||
|
|
||||||
QImage inputImage;
|
|
||||||
QImage expImage;
|
|
||||||
|
|
||||||
if (!expReader.read(&expImage)) {
|
|
||||||
QTextStream(stdout) << "ERROR: " << fi.fileName() << ": could not load " << expfilename << ": " << expReader.errorString() << "\n";
|
|
||||||
++failed;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!inputReader.canRead()) {
|
|
||||||
QTextStream(stdout) << "FAIL : " << fi.fileName() << ": failed can read: " << inputReader.errorString() << "\n";
|
|
||||||
++failed;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!inputReader.read(&inputImage)) {
|
|
||||||
QTextStream(stdout) << "FAIL : " << fi.fileName() << ": failed to load: " << inputReader.errorString() << "\n";
|
|
||||||
++failed;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (expImage.width() != inputImage.width()) {
|
|
||||||
QTextStream(stdout) << "FAIL : " << fi.fileName() << ": width was " << inputImage.width() << " but " << expfilename << " width was "
|
|
||||||
<< expImage.width() << "\n";
|
|
||||||
++failed;
|
|
||||||
} else if (expImage.height() != inputImage.height()) {
|
|
||||||
QTextStream(stdout) << "FAIL : " << fi.fileName() << ": height was " << inputImage.height() << " but " << expfilename << " height was "
|
|
||||||
<< expImage.height() << "\n";
|
|
||||||
++failed;
|
|
||||||
} else {
|
} else {
|
||||||
QImage::Format inputFormat = preferredFormat(inputImage.format());
|
QTextStream(stdout) << "* Run on RANDOM device\n";
|
||||||
QImage::Format expFormat = preferredFormat(expImage.format());
|
}
|
||||||
QImage::Format cmpFormat = inputFormat == expFormat ? inputFormat : QImage::Format_ARGB32;
|
for (const QFileInfo &fi : lstImgDir) {
|
||||||
|
if (!fi.suffix().compare("png", Qt::CaseInsensitive)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int suffixPos = fi.filePath().count() - suffix.count();
|
||||||
|
QString inputfile = fi.filePath();
|
||||||
|
QString expfile = fi.filePath().replace(suffixPos, suffix.count(), QStringLiteral("png"));
|
||||||
|
QString expfilename = QFileInfo(expfile).fileName();
|
||||||
|
|
||||||
if (inputImage.format() != cmpFormat) {
|
std::unique_ptr<QIODevice> inputDevice(seq ? new SequentialFile(inputfile) : new QFile(inputfile));
|
||||||
QTextStream(stdout) << "INFO : " << fi.fileName() << ": converting " << fi.fileName() << " from " << formatToString(inputImage.format())
|
QImageReader inputReader(inputDevice.get(), format);
|
||||||
<< " to " << formatToString(cmpFormat) << '\n';
|
QImageReader expReader(expfile, "png");
|
||||||
inputImage = inputImage.convertToFormat(cmpFormat);
|
|
||||||
}
|
QImage inputImage;
|
||||||
if (expImage.format() != cmpFormat) {
|
QImage expImage;
|
||||||
QTextStream(stdout) << "INFO : " << fi.fileName() << ": converting " << expfilename << " from " << formatToString(expImage.format()) << " to "
|
|
||||||
<< formatToString(cmpFormat) << '\n';
|
if (!expReader.read(&expImage)) {
|
||||||
expImage = expImage.convertToFormat(cmpFormat);
|
QTextStream(stdout) << "ERROR: " << fi.fileName() << ": could not load " << expfilename << ": " << expReader.errorString() << "\n";
|
||||||
}
|
|
||||||
if (fuzzyeq(inputImage, expImage, fuzziness)) {
|
|
||||||
QTextStream(stdout) << "PASS : " << fi.fileName() << "\n";
|
|
||||||
++passed;
|
|
||||||
} else {
|
|
||||||
QTextStream(stdout) << "FAIL : " << fi.fileName() << ": differs from " << expfilename << "\n";
|
|
||||||
writeImageData("expected data", fi.fileName() + QLatin1String("-expected.data"), expImage);
|
|
||||||
writeImageData("actual data", fi.fileName() + QLatin1String("-actual.data"), inputImage);
|
|
||||||
++failed;
|
++failed;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!inputReader.canRead()) {
|
||||||
|
// All plugins must pass the test on a random device.
|
||||||
|
// canRead() must also return false if the plugin is unable to run on a sequential device.
|
||||||
|
if (inputDevice->isSequential()) {
|
||||||
|
QTextStream(stdout) << "SKIP : " << fi.fileName() << ": cannot read on a sequential device\n";
|
||||||
|
++skipped;
|
||||||
|
} else {
|
||||||
|
QTextStream(stdout) << "FAIL : " << fi.fileName() << ": failed can read: " << inputReader.errorString() << "\n";
|
||||||
|
++failed;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!inputReader.read(&inputImage)) {
|
||||||
|
QTextStream(stdout) << "FAIL : " << fi.fileName() << ": failed to load: " << inputReader.errorString() << "\n";
|
||||||
|
++failed;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (expImage.width() != inputImage.width()) {
|
||||||
|
QTextStream(stdout) << "FAIL : " << fi.fileName() << ": width was " << inputImage.width() << " but " << expfilename << " width was "
|
||||||
|
<< expImage.width() << "\n";
|
||||||
|
++failed;
|
||||||
|
} else if (expImage.height() != inputImage.height()) {
|
||||||
|
QTextStream(stdout) << "FAIL : " << fi.fileName() << ": height was " << inputImage.height() << " but " << expfilename << " height was "
|
||||||
|
<< expImage.height() << "\n";
|
||||||
|
++failed;
|
||||||
|
} else {
|
||||||
|
QImage::Format inputFormat = preferredFormat(inputImage.format());
|
||||||
|
QImage::Format expFormat = preferredFormat(expImage.format());
|
||||||
|
QImage::Format cmpFormat = inputFormat == expFormat ? inputFormat : QImage::Format_ARGB32;
|
||||||
|
|
||||||
|
if (inputImage.format() != cmpFormat) {
|
||||||
|
QTextStream(stdout) << "INFO : " << fi.fileName() << ": converting " << fi.fileName() << " from " << formatToString(inputImage.format())
|
||||||
|
<< " to " << formatToString(cmpFormat) << '\n';
|
||||||
|
inputImage = inputImage.convertToFormat(cmpFormat);
|
||||||
|
}
|
||||||
|
if (expImage.format() != cmpFormat) {
|
||||||
|
QTextStream(stdout) << "INFO : " << fi.fileName() << ": converting " << expfilename << " from " << formatToString(expImage.format())
|
||||||
|
<< " to " << formatToString(cmpFormat) << '\n';
|
||||||
|
expImage = expImage.convertToFormat(cmpFormat);
|
||||||
|
}
|
||||||
|
if (fuzzyeq(inputImage, expImage, fuzziness)) {
|
||||||
|
QTextStream(stdout) << "PASS : " << fi.fileName() << "\n";
|
||||||
|
++passed;
|
||||||
|
} else {
|
||||||
|
QTextStream(stdout) << "FAIL : " << fi.fileName() << ": differs from " << expfilename << "\n";
|
||||||
|
writeImageData("expected data", fi.fileName() + QLatin1String("-expected.data"), expImage);
|
||||||
|
writeImageData("actual data", fi.fileName() + QLatin1String("-actual.data"), inputImage);
|
||||||
|
++failed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QTextStream(stdout) << "Totals: " << passed << " passed, " << failed << " failed\n";
|
QTextStream(stdout) << "Totals: " << passed << " passed, " << skipped << " skipped, " << failed << " failed\n";
|
||||||
QTextStream(stdout) << "********* "
|
QTextStream(stdout) << "********* "
|
||||||
<< "Finished basic read tests for " << suffix << " images *********\n";
|
<< "Finished basic read tests for " << suffix << " images *********\n";
|
||||||
|
|
||||||
|
@ -57,6 +57,9 @@ bool KraHandler::canRead(QIODevice *device)
|
|||||||
qWarning("KraHandler::canRead() called with no device");
|
qWarning("KraHandler::canRead() called with no device");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (device->isSequential()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
char buff[57];
|
char buff[57];
|
||||||
if (device->peek(buff, sizeof(buff)) == sizeof(buff)) {
|
if (device->peek(buff, sizeof(buff)) == sizeof(buff)) {
|
||||||
|
@ -56,6 +56,9 @@ bool OraHandler::canRead(QIODevice *device)
|
|||||||
qWarning("OraHandler::canRead() called with no device");
|
qWarning("OraHandler::canRead() called with no device");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (device->isSequential()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
char buff[54];
|
char buff[54];
|
||||||
if (device->peek(buff, sizeof(buff)) == sizeof(buff)) {
|
if (device->peek(buff, sizeof(buff)) == sizeof(buff)) {
|
||||||
|
@ -174,7 +174,7 @@ static QDataStream &operator>>(QDataStream &s, PCXHEADER &ph)
|
|||||||
|
|
||||||
// Skip the rest of the header
|
// Skip the rest of the header
|
||||||
quint8 byte;
|
quint8 byte;
|
||||||
while (s.device()->pos() < 128) {
|
for (auto i = 0; i < 54; ++i) {
|
||||||
s >> byte;
|
s >> byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -684,12 +684,6 @@ bool PCXHandler::canRead(QIODevice *device)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We do not support sequential images
|
|
||||||
// We need to know the current position to properly read the header
|
|
||||||
if (device->isSequential()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 oldPos = device->pos();
|
qint64 oldPos = device->pos();
|
||||||
|
|
||||||
char head[1];
|
char head[1];
|
||||||
|
@ -1249,6 +1249,9 @@ bool PSDHandler::canRead(QIODevice *device)
|
|||||||
qWarning("PSDHandler::canRead() called with no device");
|
qWarning("PSDHandler::canRead() called with no device");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (device->isSequential()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
qint64 oldPos = device->pos();
|
qint64 oldPos = device->pos();
|
||||||
|
|
||||||
|
@ -855,6 +855,14 @@ int RAWHandler::currentImageNumber() const
|
|||||||
|
|
||||||
bool RAWHandler::canRead(QIODevice *device)
|
bool RAWHandler::canRead(QIODevice *device)
|
||||||
{
|
{
|
||||||
|
if (!device) {
|
||||||
|
qWarning("RAWHandler::canRead() called with no device");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (device->isSequential()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
device->startTransaction();
|
device->startTransaction();
|
||||||
|
|
||||||
std::unique_ptr<LibRaw> rawProcessor(new LibRaw);
|
std::unique_ptr<LibRaw> rawProcessor(new LibRaw);
|
||||||
|
@ -3341,6 +3341,9 @@ bool XCFHandler::canRead(QIODevice *device)
|
|||||||
qCDebug(XCFPLUGIN) << "XCFHandler::canRead() called with no device";
|
qCDebug(XCFPLUGIN) << "XCFHandler::canRead() called with no device";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (device->isSequential()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
qint64 oldPos = device->pos();
|
qint64 oldPos = device->pos();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user