diff --git a/plugins/impex/tiff/tests/kis_tiff_test.cpp b/plugins/impex/tiff/tests/kis_tiff_test.cpp index 111eafcfd2..fd5d079426 100644 --- a/plugins/impex/tiff/tests/kis_tiff_test.cpp +++ b/plugins/impex/tiff/tests/kis_tiff_test.cpp @@ -1,141 +1,201 @@ /* * Copyright (C) 2007 Cyrille Berger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_tiff_test.h" #include #include #include "filestest.h" #include #include #include "kisexiv2/kis_exiv2.h" #include +#include #ifndef FILES_DATA_DIR #error "FILES_DATA_DIR not set. A directory with the data used for testing the importing of files in krita" #endif const QString TiffMimetype = "image/tiff"; void KisTiffTest::testFiles() { // XXX: make the exiv io backends real plugins KisExiv2::initialize(); QStringList excludes; #ifndef CPU_32_BITS excludes << "flower-minisblack-06.tif"; #endif #ifdef HAVE_LCMS2 excludes << "flower-separated-contig-08.tif" << "flower-separated-contig-16.tif" << "flower-separated-planar-08.tif" << "flower-separated-planar-16.tif" << "flower-minisblack-02.tif" << "flower-minisblack-04.tif" << "flower-minisblack-08.tif" << "flower-minisblack-10.tif" << "flower-minisblack-12.tif" << "flower-minisblack-14.tif" << "flower-minisblack-16.tif" << "flower-minisblack-24.tif" << "flower-minisblack-32.tif" << "jim___dg.tif" << "jim___gg.tif" << "strike.tif"; #endif excludes << "text.tif" << "ycbcr-cat.tif"; TestUtil::testFiles(QString(FILES_DATA_DIR) + "/sources", excludes, QString(), 1); } void KisTiffTest::testRoundTripRGBF16() { // Disabled for now, it's broken because we assumed integers. #if 0 QRect testRect(0,0,1000,1000); QRect fillRect(100,100,100,100); const KoColorSpace *csf16 = KoColorSpaceRegistry::instance()->colorSpace(RGBAColorModelID.id(), Float16BitsColorDepthID.id(), 0); KisDocument *doc0 = qobject_cast(KisPart::instance()->createDocument()); doc0->newImage("test", testRect.width(), testRect.height(), csf16, KoColor(Qt::blue, csf16), QString(), 1.0); QTemporaryFile tmpFile(QDir::tempPath() + QLatin1String("/krita_XXXXXX") + QLatin1String(".tiff")); tmpFile.open(); doc0->setBackupFile(false); doc0->setOutputMimeType("image/tiff"); doc0->setFileBatchMode(true); doc0->saveAs(QUrl::fromLocalFile(tmpFile.fileName())); KisNodeSP layer0 = doc0->image()->root()->firstChild(); Q_ASSERT(layer0); layer0->paintDevice()->fill(fillRect, KoColor(Qt::red, csf16)); KisDocument *doc1 = qobject_cast(KisPart::instance()->createDocument()); KisImportExportManager manager(doc1); doc1->setFileBatchMode(false); KisImportExportErrorCode status; QString s = manager.importDocument(tmpFile.fileName(), QString(), status); dbgKrita << s; Q_ASSERT(doc1->image()); QImage ref0 = doc0->image()->projection()->convertToQImage(0, testRect); QImage ref1 = doc1->image()->projection()->convertToQImage(0, testRect); QCOMPARE(ref0, ref1); #endif } +void KisTiffTest::testSaveTiffColorSpace(QString colorModel, QString colorDepth, QString colorProfile) +{ + KoColorSpaceRegistry registry; + const KoColorSpace *space = KoColorSpaceRegistry::instance()->colorSpace(colorModel, colorDepth, colorProfile); + TestUtil::testExportToColorSpace(QString(FILES_DATA_DIR), TiffMimetype, space, ImportExportCodes::OK, true); +} + +void KisTiffTest::testSaveTiffRgbaColorSpace() +{ + QString profile = "sRGB-elle-V2-srgbtrc"; + testSaveTiffColorSpace(RGBAColorModelID.id(), Integer8BitsColorDepthID.id(), profile); + profile = "sRGB-elle-V2-g10"; + testSaveTiffColorSpace(RGBAColorModelID.id(), Integer16BitsColorDepthID.id(), profile); + testSaveTiffColorSpace(RGBAColorModelID.id(), Float16BitsColorDepthID.id(), profile); + testSaveTiffColorSpace(RGBAColorModelID.id(), Float32BitsColorDepthID.id(), profile); +} + +void KisTiffTest::testSaveTiffGreyAColorSpace() +{ + QString profile = "Gray-D50-elle-V2-srgbtrc"; + testSaveTiffColorSpace(GrayAColorModelID.id(), Integer8BitsColorDepthID.id(), profile); + profile = "Gray-D50-elle-V2-g10"; + testSaveTiffColorSpace(GrayAColorModelID.id(), Integer16BitsColorDepthID.id(), profile); + testSaveTiffColorSpace(GrayAColorModelID.id(), Float16BitsColorDepthID.id(), profile); + testSaveTiffColorSpace(GrayAColorModelID.id(), Float32BitsColorDepthID.id(), profile); + +} + + +void KisTiffTest::testSaveTiffCmykColorSpace() +{ + QString profile = "Chemical proof"; + testSaveTiffColorSpace(CMYKAColorModelID.id(), Integer8BitsColorDepthID.id(), profile); + testSaveTiffColorSpace(CMYKAColorModelID.id(), Integer16BitsColorDepthID.id(), profile); + testSaveTiffColorSpace(CMYKAColorModelID.id(), Float32BitsColorDepthID.id(), profile); +} + +void KisTiffTest::testSaveTiffLabColorSpace() +{ + const QString profile = "Lab identity build-in"; + testSaveTiffColorSpace(LABAColorModelID.id(), Integer8BitsColorDepthID.id(), profile); + testSaveTiffColorSpace(LABAColorModelID.id(), Integer16BitsColorDepthID.id(), profile); + testSaveTiffColorSpace(LABAColorModelID.id(), Float32BitsColorDepthID.id(), profile); +} + + +void KisTiffTest::testSaveTiffYCrCbAColorSpace() +{ + /* + * There is no public/open profile for YCrCbA, so no way to test it... + * + const QString profile = ""; + testSaveTiffColorSpace(YCbCrAColorModelID.id(), Integer8BitsColorDepthID.id(), profile); + testSaveTiffColorSpace(YCbCrAColorModelID.id(), Integer16BitsColorDepthID.id(), profile); + testSaveTiffColorSpace(YCbCrAColorModelID.id(), Float32BitsColorDepthID.id(), profile); + */ +} + + void KisTiffTest::testImportFromWriteonly() { TestUtil::testImportFromWriteonly(QString(FILES_DATA_DIR), TiffMimetype); } void KisTiffTest::testExportToReadonly() { TestUtil::testExportToReadonly(QString(FILES_DATA_DIR), TiffMimetype, true); } void KisTiffTest::testImportIncorrectFormat() { TestUtil::testImportIncorrectFormat(QString(FILES_DATA_DIR), TiffMimetype); } KISTEST_MAIN(KisTiffTest) diff --git a/plugins/impex/tiff/tests/kis_tiff_test.h b/plugins/impex/tiff/tests/kis_tiff_test.h index 11505376f7..873a1caf89 100644 --- a/plugins/impex/tiff/tests/kis_tiff_test.h +++ b/plugins/impex/tiff/tests/kis_tiff_test.h @@ -1,36 +1,43 @@ /* * Copyright (C) 2007 Cyrille Berger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _KIS_TIFF_TEST_H_ #define _KIS_TIFF_TEST_H_ #include class KisTiffTest : public QObject { Q_OBJECT private Q_SLOTS: void testFiles(); void testRoundTripRGBF16(); + void testSaveTiffColorSpace(QString colorModel, QString colorDepth, QString colorProfile); + void testSaveTiffRgbaColorSpace(); + void testSaveTiffGreyAColorSpace(); + void testSaveTiffCmykColorSpace(); + void testSaveTiffLabColorSpace(); + void testSaveTiffYCrCbAColorSpace(); + void testImportFromWriteonly(); void testExportToReadonly(); void testImportIncorrectFormat(); }; #endif diff --git a/sdk/tests/filestest.h b/sdk/tests/filestest.h index 52fcd6b552..e7cb9165c0 100644 --- a/sdk/tests/filestest.h +++ b/sdk/tests/filestest.h @@ -1,369 +1,377 @@ /* * Copyright (C) 2007 Cyrille Berger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef FILESTEST #define FILESTEST #include "testutil.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace TestUtil { void testFiles(const QString& _dirname, const QStringList& exclusions, const QString &resultSuffix = QString(), int fuzzy = 0, int maxNumFailingPixels = 0, bool showDebug = true) { QDir dirSources(_dirname); QStringList failuresFileInfo; QStringList failuresDocImage; QStringList failuresCompare; Q_FOREACH (QFileInfo sourceFileInfo, dirSources.entryInfoList()) { qDebug() << sourceFileInfo.fileName(); if (exclusions.indexOf(sourceFileInfo.fileName()) > -1) { continue; } if (!sourceFileInfo.isHidden() && !sourceFileInfo.isDir()) { QFileInfo resultFileInfo(QString(FILES_DATA_DIR) + "/results/" + sourceFileInfo.fileName() + resultSuffix + ".png"); if (!resultFileInfo.exists()) { failuresFileInfo << resultFileInfo.fileName(); continue; } KisDocument *doc = qobject_cast(KisPart::instance()->createDocument()); KisImportExportManager manager(doc); doc->setFileBatchMode(true); KisImportExportErrorCode status = manager.importDocument(sourceFileInfo.absoluteFilePath(), QString()); Q_UNUSED(status); if (!doc->image()) { failuresDocImage << sourceFileInfo.fileName(); continue; } QString id = doc->image()->colorSpace()->id(); if (id != "GRAYA" && id != "GRAYAU16" && id != "RGBA" && id != "RGBA16") { dbgKrita << "Images need conversion"; doc->image()->convertImageColorSpace(KoColorSpaceRegistry::instance()->rgb8(), KoColorConversionTransformation::IntentAbsoluteColorimetric, KoColorConversionTransformation::NoOptimization); } qApp->processEvents(); doc->image()->waitForDone(); QImage sourceImage = doc->image()->projection()->convertToQImage(0, doc->image()->bounds()); QImage resultImage(resultFileInfo.absoluteFilePath()); resultImage = resultImage.convertToFormat(QImage::Format_ARGB32); sourceImage = sourceImage.convertToFormat(QImage::Format_ARGB32); QPoint pt; if (!TestUtil::compareQImages(pt, resultImage, sourceImage, fuzzy, fuzzy, maxNumFailingPixels, showDebug)) { failuresCompare << sourceFileInfo.fileName() + ": " + QString("Pixel (%1,%2) has different values").arg(pt.x()).arg(pt.y()).toLatin1(); sourceImage.save(sourceFileInfo.fileName() + ".png"); resultImage.save(resultFileInfo.fileName() + ".expected.png"); continue; } delete doc; } } if (failuresCompare.isEmpty() && failuresDocImage.isEmpty() && failuresFileInfo.isEmpty()) { return; } qWarning() << "Comparison failures: " << failuresCompare; qWarning() << "No image failures: " << failuresDocImage; qWarning() << "No comparison image: " << failuresFileInfo; QFAIL("Failed testing files"); } void prepareFile(QFileInfo sourceFileInfo, bool removePermissionToWrite, bool removePermissionToRead) { QFileDevice::Permissions permissionsBefore; if (sourceFileInfo.exists()) { permissionsBefore = QFile::permissions(sourceFileInfo.absoluteFilePath()); ENTER_FUNCTION() << permissionsBefore; } else { QFile file(sourceFileInfo.absoluteFilePath()); bool opened = file.open(QIODevice::ReadWrite); if (!opened) { qDebug() << "The file cannot be opened/created: " << file.error() << file.errorString(); } permissionsBefore = file.permissions(); file.close(); } QFileDevice::Permissions permissionsNow = permissionsBefore; if (removePermissionToRead) { permissionsNow = permissionsBefore & (~QFileDevice::ReadUser & ~QFileDevice::ReadOwner & ~QFileDevice::ReadGroup & ~QFileDevice::ReadOther); } if (removePermissionToWrite) { permissionsNow = permissionsBefore & (~QFileDevice::WriteUser & ~QFileDevice::WriteOwner & ~QFileDevice::WriteGroup & ~QFileDevice::WriteOther); } QFile::setPermissions(sourceFileInfo.absoluteFilePath(), permissionsNow); } void restorePermissionsToReadAndWrite(QFileInfo sourceFileInfo) { QFileDevice::Permissions permissionsNow = sourceFileInfo.permissions(); QFileDevice::Permissions permissionsAfter = permissionsNow | (QFileDevice::ReadUser | QFileDevice::ReadOwner | QFileDevice::ReadGroup | QFileDevice::ReadOther) | (QFileDevice::WriteUser | QFileDevice::WriteOwner | QFileDevice::WriteGroup | QFileDevice::WriteOther); QFile::setPermissions(sourceFileInfo.absoluteFilePath(), permissionsAfter); } void testImportFromWriteonly(const QString& _dirname, QString mimetype = "") { QString writeonlyFilename = _dirname + "writeonlyFile.txt"; QFileInfo sourceFileInfo(writeonlyFilename); prepareFile(sourceFileInfo, false, true); KisDocument *doc = qobject_cast(KisPart::instance()->createDocument()); KisImportExportManager manager(doc); doc->setFileBatchMode(true); KisImportExportErrorCode status = manager.importDocument(sourceFileInfo.absoluteFilePath(), mimetype); qDebug() << "import result = " << status; QString failMessage = ""; bool fail = false; if (status == ImportExportCodes::FileFormatIncorrect) { qDebug() << "Make sure you set the correct mimetype in the test case."; failMessage = "Incorrect status."; fail = true; } qApp->processEvents(); if (doc->image()) { doc->image()->waitForDone(); } delete doc; restorePermissionsToReadAndWrite(sourceFileInfo); QVERIFY(!status.isOk()); if (fail) { QFAIL(failMessage.toUtf8()); } } void testExportToReadonly(const QString& _dirname, QString mimetype = "", bool useDocumentExport=false) { QString readonlyFilename = _dirname + "readonlyFile.txt"; QFileInfo sourceFileInfo(readonlyFilename); prepareFile(sourceFileInfo, true, false); KisDocument *doc = qobject_cast(KisPart::instance()->createDocument()); KisImportExportManager manager(doc); doc->setFileBatchMode(true); KisImportExportErrorCode status = ImportExportCodes::OK; QString failMessage = ""; bool fail = false; { MaskParent p; ENTER_FUNCTION() << doc->image(); doc->setCurrentImage(p.image); if (useDocumentExport) { bool result = doc->exportDocumentSync(QUrl(sourceFileInfo.absoluteFilePath()), mimetype.toUtf8()); status = result ? ImportExportCodes::OK : ImportExportCodes::Failure; } else { status = manager.exportDocument(sourceFileInfo.absoluteFilePath(), sourceFileInfo.absoluteFilePath(), mimetype.toUtf8()); } qDebug() << "export result = " << status; if (!useDocumentExport && status == ImportExportCodes::FileFormatIncorrect) { qDebug() << "Make sure you set the correct mimetype in the test case."; failMessage = "Incorrect status."; fail = true; } qApp->processEvents(); if (doc->image()) { doc->image()->waitForDone(); } } delete doc; restorePermissionsToReadAndWrite(sourceFileInfo); QVERIFY(!status.isOk()); if (fail) { QFAIL(failMessage.toUtf8()); } } void testImportIncorrectFormat(const QString& _dirname, QString mimetype = "") { QString incorrectFormatFilename = _dirname + "incorrectFormatFile.txt"; QFileInfo sourceFileInfo(incorrectFormatFilename); prepareFile(sourceFileInfo, false, false); KisDocument *doc = qobject_cast(KisPart::instance()->createDocument()); KisImportExportManager manager(doc); doc->setFileBatchMode(true); KisImportExportErrorCode status = manager.importDocument(sourceFileInfo.absoluteFilePath(), mimetype); qDebug() << "import result = " << status; qApp->processEvents(); if (doc->image()) { doc->image()->waitForDone(); } delete doc; QVERIFY(!status.isOk()); QVERIFY(status == KisImportExportErrorCode(ImportExportCodes::FileFormatIncorrect) || status == KisImportExportErrorCode(ImportExportCodes::ErrorWhileReading)); // in case the filter doesn't know if it can't read or just parse } void testExportToColorSpace(const QString& _dirname, QString mimetype, const KoColorSpace* space, KisImportExportErrorCode expected, bool useDocumentExport=false) { QString colorspaceFilename = _dirname + "colorspace.txt"; QFileInfo sourceFileInfo(colorspaceFilename); prepareFile(sourceFileInfo, true, true); restorePermissionsToReadAndWrite(sourceFileInfo); KisDocument *doc = qobject_cast(KisPart::instance()->createDocument()); KisImportExportManager manager(doc); doc->setFileBatchMode(true); KisImportExportErrorCode statusExport = ImportExportCodes::OK; KisImportExportErrorCode statusImport = ImportExportCodes::OK; QString failMessage = ""; bool fail = false; { MaskParent p; doc->setCurrentImage(p.image); doc->image()->convertImageColorSpace(space, KoColorConversionTransformation::Intent::IntentPerceptual, KoColorConversionTransformation::ConversionFlag::Empty); if (useDocumentExport) { bool result = doc->exportDocumentSync(QUrl(QString("file:") + QString(colorspaceFilename)), mimetype.toUtf8()); statusExport = result ? ImportExportCodes::OK : ImportExportCodes::Failure; } else { statusExport = manager.exportDocument(colorspaceFilename, colorspaceFilename, mimetype.toUtf8()); } statusImport = manager.importDocument(colorspaceFilename, mimetype.toUtf8()); - QVERIFY(statusImport == ImportExportCodes::OK); - if (*(doc->image()->colorSpace()) != *space) { + if (!(statusImport == ImportExportCodes::OK)) { + fail = true; + failMessage = "Incorrect status"; + } + + bool mismatch = (*(doc->image()->colorSpace()) != *space) || (doc->image()->colorSpace()->profile() != space->profile()); + if (mismatch) { qDebug() << "Document color space = " << (doc->image()->colorSpace())->id(); qDebug() << "Saved color space = " << space->id(); - QVERIFY(*(doc->image()->colorSpace()) == *space); + fail = true; + failMessage = "Mismatch of color spaces"; } if (!useDocumentExport && statusExport == ImportExportCodes::FileFormatIncorrect) { qDebug() << "Make sure you set the correct mimetype in the test case."; failMessage = "Incorrect status."; fail = true; } qApp->processEvents(); if (doc->image()) { doc->image()->waitForDone(); } } delete doc; QFile::remove(colorspaceFilename); + if (fail) { + QFAIL(failMessage.toUtf8()); + } + QVERIFY(statusExport.isOk()); if (!useDocumentExport) { QVERIFY(statusExport == expected); } - if (fail) { - QFAIL(failMessage.toUtf8()); - } + } } #endif