14.23: WebP import
This commit is contained in:
13 files changed
+93
-16
No files matched your search
@@ -323,7 +323,7 @@ void ContentViewTests::theImporterPicksFilesAndClearsItsFlag()
|
||||
QTest::qWait(50);
|
||||
QCOMPARE(int(session.document().value().layers.size()), 2);
|
||||
desk.typeBeforeCancel.clear();
|
||||
const QString panel = "panel|Open|open|file|||1 many Images (*.jpg *.jpeg *.png *.heic *.tif *.tiff *.psd *.psb *.svg *.svgz " + RawImporter::globs().join(" ") + ")";
|
||||
const QString panel = "panel|Open|open|file|||1 many Images (*.jpg *.jpeg *.png *.heic *.tif *.tiff *.webp *.psd *.psb *.svg *.svgz " + RawImporter::globs().join(" ") + ")";
|
||||
QCOMPARE(desk.seen.mid(0, 2), (QStringList{panel, panel}));
|
||||
QCOMPARE(desk.seen.size(), 3);
|
||||
// The flag cleared from elsewhere takes the panel down.
|
||||
|
||||
@@ -71,7 +71,7 @@ void DesktopIntegrationTests::theEntryOpensSwiftsDocumentTypes()
|
||||
QCOMPARE(keys.value("Terminal"), QString("false"));
|
||||
QVERIFY(keys.value("Categories").split(QLatin1Char(';')).contains("Graphics"));
|
||||
// Swift's two document types: its projects, then four pictures.
|
||||
QCOMPARE(keys.value("MimeType"), QString("application/x-compositor-project;image/png;image/jpeg;image/heic;image/tiff;image/vnd.adobe.photoshop;image/x-photoshop-large-image;image/svg+xml;image/svg+xml-compressed;image/x-dcraw;"));
|
||||
QCOMPARE(keys.value("MimeType"), QString("application/x-compositor-project;image/png;image/jpeg;image/heic;image/tiff;image/webp;image/vnd.adobe.photoshop;image/x-photoshop-large-image;image/svg+xml;image/svg+xml-compressed;image/x-dcraw;"));
|
||||
// Each SVG suffix's type as the system names it.
|
||||
for (const char *name : {"icon.svg", "icon.svgz"}) {
|
||||
const QString type = QMimeDatabase().mimeTypeForFile(QString::fromLatin1(name), QMimeDatabase::MatchExtension).name();
|
||||
|
||||
@@ -173,7 +173,7 @@ void ImageFileDropTests::aPictureIsCopiedToAFileFirst()
|
||||
|
||||
void ImageFileDropTests::whatCannotBeReadIsSaid()
|
||||
{
|
||||
const QString said = "Some dropped items couldn’t be read. Drag JPEG, PNG, HEIC, TIFF, or Photoshop (PSD) files from the file manager.";
|
||||
const QString said = "Some dropped items couldn’t be read. Drag JPEG, PNG, HEIC, TIFF, WebP, or Photoshop (PSD) files from the file manager.";
|
||||
EditorSession session;
|
||||
bool done = false;
|
||||
std::unique_ptr<QMimeData> link(files({}, {QUrl("https://example.com/page")}));
|
||||
@@ -354,7 +354,7 @@ void ImageFileDropTests::aPictureThatCannotBeKeptIsUnreadable()
|
||||
ImageFileDrop::importProviders(data, session, std::nullopt, nullptr, std::nullopt, [&done] { done = true; });
|
||||
QCOMPARE(setrlimit(RLIMIT_FSIZE, &room), 0);
|
||||
QTRY_VERIFY(done);
|
||||
QCOMPARE(session.importError(), std::optional<QString>("Some dropped items couldn’t be read. Drag JPEG, PNG, HEIC, TIFF, or Photoshop (PSD) files from the file manager."));
|
||||
QCOMPARE(session.importError(), std::optional<QString>("Some dropped items couldn’t be read. Drag JPEG, PNG, HEIC, TIFF, WebP, or Photoshop (PSD) files from the file manager."));
|
||||
QVERIFY(!session.document());
|
||||
QCOMPARE(dropped(), before);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
// The session cases of Swift's ImageImportTests, and the queue.
|
||||
namespace {
|
||||
const QString unreadable = QStringLiteral("The image could not be read. It may be damaged or unavailable.");
|
||||
const QString unsupported = QStringLiteral("Choose a JPEG, PNG, HEIC, TIFF, or Photoshop (PSD) file.");
|
||||
const QString unsupported = QStringLiteral("Choose a JPEG, PNG, HEIC, TIFF, WebP, or Photoshop (PSD) file.");
|
||||
const QString tooLarge = QStringLiteral("This import exceeds the current %1-megapixel document budget or 30,000-pixel side limit.").arg(DocumentLimits::documentBudgetMegapixels());
|
||||
|
||||
// A 64 by 32 PNG, as Swift's fixture is.
|
||||
|
||||
@@ -385,8 +385,7 @@ void ImageImportTests::limitsAndInvalidFiles()
|
||||
const QByteArray gif = QByteArray::fromHex("47494638396101000100800000000000ffffff21f90401000000002c00000000010001000002024401003b");
|
||||
const QByteArray avif = QByteArray::fromHex("0000001c667479706176696600000000617669666d6966316d696166");
|
||||
const QList<std::pair<QString, QByteArray>> unwanted{{"tiny.gif", gif}, {"tiny.avif", avif},
|
||||
{"fixture.bmp", encoded(block(QImage::Format_RGB888, red, Qt::white), "bmp")},
|
||||
{"fixture.webp", encoded(block(QImage::Format_RGB888, red, Qt::white), "webp")}};
|
||||
{"fixture.bmp", encoded(block(QImage::Format_RGB888, red, Qt::white), "bmp")}};
|
||||
for (const auto &[name, data] : unwanted) {
|
||||
QTest::ignoreMessage(QtWarningMsg, refusal);
|
||||
QVERIFY2(importError(written(folder, name, data)) == std::optional(ImageImportError::Kind::unsupported), qPrintable(name));
|
||||
@@ -460,7 +459,7 @@ void ImageImportTests::thumbnailsAreSmoothed()
|
||||
void ImageImportTests::errorsCarrySwiftsDescriptions()
|
||||
{
|
||||
QCOMPARE(QString(ImageImportError(ImageImportError::Kind::unreadable).what()), QString("The image could not be read. It may be damaged or unavailable."));
|
||||
QCOMPARE(QString(ImageImportError(ImageImportError::Kind::unsupported).what()), QString("Choose a JPEG, PNG, HEIC, TIFF, or Photoshop (PSD) file."));
|
||||
QCOMPARE(QString(ImageImportError(ImageImportError::Kind::unsupported).what()), QString("Choose a JPEG, PNG, HEIC, TIFF, WebP, or Photoshop (PSD) file."));
|
||||
QCOMPARE(QString(ImageImportError(ImageImportError::Kind::tooLarge).what()),
|
||||
QStringLiteral("This import exceeds the current %1-megapixel document budget or 30,000-pixel side limit.").arg(DocumentLimits::documentBudgetMegapixels()));
|
||||
QCOMPARE(ImageImportError(ImageImportError::Kind::tooLarge).kind, ImageImportError::Kind::tooLarge);
|
||||
|
||||
@@ -131,6 +131,7 @@ compositor_test(HighDpiCanvasTests)
|
||||
compositor_test(HistoryTests)
|
||||
compositor_test(ImageImportSessionTests)
|
||||
compositor_test(ImageImportTests)
|
||||
compositor_test(WebPImportTests)
|
||||
compositor_test(ImageSizeTests)
|
||||
compositor_test(JPEGExportTests)
|
||||
compositor_test(LayerAppearanceControlsTests)
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
#include "Document/EditorSession.h"
|
||||
#include "IO/ImageFileDrop.h"
|
||||
#include "IO/ImageImporter.h"
|
||||
#include <QColorSpace>
|
||||
#include <QMimeData>
|
||||
#include <QTemporaryDir>
|
||||
#include <QtTest>
|
||||
|
||||
// Swift 1.4.9's WebP import (`5724099`).
|
||||
class WebPImportTests : public QObject {
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void webPImportPreservesTransparency_data();
|
||||
void webPImportPreservesTransparency();
|
||||
void aDroppedPictureTakesWebPAfterTIFF();
|
||||
};
|
||||
|
||||
void WebPImportTests::webPImportPreservesTransparency_data()
|
||||
{
|
||||
// 64 by 32: red left, clear right.
|
||||
QTest::addColumn<QByteArray>("encoded");
|
||||
QTest::newRow("lossless") << QByteArray("UklGRiYAAABXRUJQVlA4TBkAAAAvP8AHEA8Q8x/zHwyxYDJ/6RB6I/ofVfANAA==");
|
||||
QTest::newRow("lossy") << QByteArray("UklGRoYAAABXRUJQVlA4WAoAAAAQAAAAPwAAHwAAQUxQSBQAAAABDzD/ERFCLJjMXzqE3oj+RxV8A1ZQOCBMAAAA8AMAnQEqQAAgAD4xFolDIiEhFgQAIAMEsYBmu0A/AD8AADKMNAliwAD+96KX/9eiUqpf3sP/+Fmfwsz+Fmf/Cc2fv90UD4A2eDkAAA==");
|
||||
}
|
||||
|
||||
void WebPImportTests::webPImportPreservesTransparency()
|
||||
{
|
||||
QFETCH(QByteArray, encoded);
|
||||
const QByteArray bytes = QByteArray::fromBase64(encoded);
|
||||
QTemporaryDir folder;
|
||||
// The bytes decide, as everywhere: no suffix needed.
|
||||
const QString path = folder.filePath(QStringLiteral("picture"));
|
||||
QFile file(path);
|
||||
QVERIFY(file.open(QIODevice::WriteOnly) && file.write(bytes) == bytes.size());
|
||||
file.close();
|
||||
const ImportedImage result = ImageImporter::decode(path);
|
||||
const QImage image = result.image();
|
||||
QCOMPARE(image.size(), QSize(64, 32));
|
||||
QCOMPARE(image.colorSpace(), QColorSpace(QColorSpace::SRgb));
|
||||
QCOMPARE(image.format(), QImage::Format_RGBA8888_Premultiplied);
|
||||
QVERIFY(result.thumbnail.width() <= 96 && result.thumbnail.height() <= 96);
|
||||
const uchar *row = image.constScanLine(0);
|
||||
QVERIFY(row[0] >= 250 && row[3] == 255);
|
||||
QCOMPARE(int(row[63 * 4 + 3]), 0);
|
||||
// Past its budget it is too large.
|
||||
QTest::ignoreMessage(QtWarningMsg, QRegularExpression("^cannot import "));
|
||||
try {
|
||||
ImageImporter::decode(path, 10);
|
||||
QFAIL("an over-budget WebP decoded");
|
||||
} catch (const ImageImportError &error) {
|
||||
QCOMPARE(error.kind, ImageImportError::Kind::tooLarge);
|
||||
}
|
||||
// A dropped WebP picture opens a document of its own.
|
||||
EditorSession session;
|
||||
QMimeData data;
|
||||
data.setData(QStringLiteral("image/webp"), bytes);
|
||||
bool done = false;
|
||||
ImageFileDrop::importProviders(data, session, std::nullopt, nullptr, std::nullopt, [&done] { done = true; });
|
||||
QTRY_VERIFY(done);
|
||||
QCOMPARE(session.document().value().size(), QSizeF(64, 32));
|
||||
QCOMPARE(session.document().value().layers.size(), size_t(1));
|
||||
QVERIFY(!session.importError());
|
||||
}
|
||||
|
||||
void WebPImportTests::aDroppedPictureTakesWebPAfterTIFF()
|
||||
{
|
||||
QMimeData data;
|
||||
data.setData(QStringLiteral("image/vnd.adobe.photoshop"), "psd");
|
||||
data.setData(QStringLiteral("image/webp"), "webp");
|
||||
QCOMPARE(ImageFileDrop::providers(data).front()->formats(), QStringList{"image/webp"});
|
||||
data.setData(QStringLiteral("image/tiff"), "tiff");
|
||||
QCOMPARE(ImageFileDrop::providers(data).front()->formats(), QStringList{"image/tiff"});
|
||||
}
|
||||
|
||||
QTEST_MAIN(WebPImportTests)
|
||||
#include "WebPImportTests.moc"
|
||||
Reference in new issue
Block a user