File indexing completed on 2024-05-05 03:54:34

0001 /*
0002     SPDX-FileCopyrightText: 2014 Vishesh Handa <me@vhanda.in>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-or-later
0005 */
0006 
0007 #include "simpleextractionresult.h"
0008 #include "indexerextractortestsconfig.h"
0009 #include "extractors/exiv2extractor.h"
0010 #include "mimeutils.h"
0011 
0012 #include <QTest>
0013 #include <QMimeDatabase>
0014 #include <QTimeZone>
0015 
0016 using namespace KFileMetaData;
0017 
0018 class Exiv2ExtractorTest : public QObject
0019 {
0020     Q_OBJECT
0021 
0022 private Q_SLOTS:
0023     void testNoExtraction();
0024     void test();
0025     void testGPS();
0026     void testJpegJxlProperties();
0027     void testJpegJxlProperties_data();
0028     void testHeifProperties();
0029 };
0030 
0031 namespace {
0032 QString testFilePath(const QString& fileName)
0033 {
0034     return QLatin1String(INDEXER_TESTS_SAMPLE_FILES_PATH) + QLatin1Char('/') + fileName;
0035 }
0036 
0037 }
0038 
0039 void Exiv2ExtractorTest::testNoExtraction()
0040 {
0041     Exiv2Extractor plugin{this};
0042 
0043     QString fileName = testFilePath(QStringLiteral("test.jpg"));
0044     QMimeDatabase mimeDb;
0045     QString mimeType = MimeUtils::strictMimeType(fileName, mimeDb).name();
0046     QVERIFY(plugin.mimetypes().contains(mimeType));
0047 
0048     SimpleExtractionResult result(fileName, mimeType, ExtractionResult::ExtractNothing);
0049     plugin.extract(&result);
0050 
0051     QCOMPARE(result.types().size(), 1);
0052     QCOMPARE(result.types().constFirst(), Type::Image);
0053     QCOMPARE(result.properties().size(), 0);
0054 }
0055 
0056 void Exiv2ExtractorTest::test()
0057 {
0058     using namespace KFileMetaData::Property;
0059 
0060     Exiv2Extractor plugin{this};
0061 
0062     QString fileName = testFilePath(QStringLiteral("test.jpg"));
0063     QMimeDatabase mimeDb;
0064     QString mimeType = MimeUtils::strictMimeType(fileName, mimeDb).name();
0065     QVERIFY(plugin.mimetypes().contains(mimeType));
0066 
0067     SimpleExtractionResult result(fileName, mimeType);
0068     plugin.extract(&result);
0069 
0070     QCOMPARE(result.types().size(), 1);
0071     QCOMPARE(result.types().constFirst(), Type::Image);
0072 
0073     QCOMPARE(result.properties().value(Artist).toString(), QStringLiteral("Artist"));
0074     QCOMPARE(result.properties().value(Description).toString(), QStringLiteral("Description"));
0075     QCOMPARE(result.properties().value(Copyright).toString(), QStringLiteral("Copyright"));
0076     QCOMPARE(result.properties().value(Generator).toString(), QStringLiteral("digiKam-5.9.0"));
0077 }
0078 
0079 void Exiv2ExtractorTest::testGPS()
0080 {
0081     using namespace KFileMetaData::Property;
0082 
0083     Exiv2Extractor plugin{this};
0084 
0085     SimpleExtractionResult result(testFilePath("test.jpg"), "image/jpeg");
0086     plugin.extract(&result);
0087 
0088     QCOMPARE(result.properties().value(PhotoGpsLatitude).toDouble(), 41.411);
0089     QCOMPARE(result.properties().value(PhotoGpsLongitude).toDouble(), 2.173);
0090     QCOMPARE(result.properties().value(PhotoGpsAltitude).toDouble(), 12.2);
0091 
0092     SimpleExtractionResult resultEmpty(testFilePath("test_no_gps.jpg"), "image/jpeg");
0093     plugin.extract(&resultEmpty);
0094     QVERIFY(!resultEmpty.properties().contains(PhotoGpsLatitude));
0095     QVERIFY(!resultEmpty.properties().contains(PhotoGpsLongitude));
0096     QVERIFY(!resultEmpty.properties().contains(PhotoGpsAltitude));
0097 
0098     SimpleExtractionResult resultZero(testFilePath("test_zero_gps.jpg"), "image/jpeg");
0099     plugin.extract(&resultZero);
0100     QVERIFY(resultZero.properties().contains(PhotoGpsLatitude));
0101     QVERIFY(resultZero.properties().contains(PhotoGpsLongitude));
0102     QVERIFY(resultZero.properties().contains(PhotoGpsAltitude));
0103     QCOMPARE(resultZero.properties().value(PhotoGpsLatitude).toDouble(), 0.0);
0104     QCOMPARE(resultZero.properties().value(PhotoGpsLongitude).toDouble(), 0.0);
0105     QCOMPARE(resultZero.properties().value(PhotoGpsAltitude).toDouble(), 0.0);
0106 }
0107 
0108 void Exiv2ExtractorTest::testJpegJxlProperties()
0109 {
0110     QFETCH(QString, fileName);
0111     QFETCH(QString, mimeType);
0112 
0113     Exiv2Extractor plugin{this};
0114 
0115     if ((mimeType == QStringLiteral("image/jxl")) && !plugin.mimetypes().contains("image/jxl")) {
0116         QSKIP("BMFF support required for JXL");
0117     }
0118     QVERIFY(plugin.mimetypes().contains(mimeType));
0119 
0120     SimpleExtractionResult result(testFilePath(fileName), mimeType);
0121     plugin.extract(&result);
0122 
0123     QCOMPARE(result.types().size(), 1);
0124     QCOMPARE(result.types().constFirst(), Type::Image);
0125 
0126     const auto properties = result.properties();
0127     QCOMPARE(properties.size(), 29);
0128 
0129     auto verifyProperty = [&properties](KFileMetaData::Property::Property prop, const QVariant &value)
0130     {
0131     if (value.canConvert<float>()) {
0132         QCOMPARE(properties.value(prop).toFloat(), value.toFloat());
0133     } else {
0134         QCOMPARE(properties.value(prop), value);
0135     }
0136     };
0137 
0138     verifyProperty(Property::Artist, QStringLiteral("Artist"));
0139     verifyProperty(Property::Description, QStringLiteral("Description"));
0140     verifyProperty(Property::Copyright, QStringLiteral("Copyright"));
0141     verifyProperty(Property::Generator, QStringLiteral("digikam-5.9.0"));
0142     verifyProperty(Property::PhotoGpsLatitude, 41.411f);
0143     verifyProperty(Property::PhotoGpsLongitude, 2.173f);
0144     verifyProperty(Property::PhotoGpsAltitude, 12.2f);
0145     verifyProperty(Property::Width, 8);
0146     verifyProperty(Property::Height, 14);
0147     verifyProperty(Property::Manufacturer, QStringLiteral("LGE"));
0148     verifyProperty(Property::Model, QStringLiteral("Nexus 5"));
0149     verifyProperty(Property::ImageDateTime, QDateTime(QDate(2014, 10, 04), QTime(13, 47, 43.000), QTimeZone::UTC));
0150     verifyProperty(Property::PhotoFlash, 0);
0151     verifyProperty(Property::PhotoPixelXDimension, 8);
0152     verifyProperty(Property::PhotoPixelYDimension, 14);
0153     verifyProperty(Property::PhotoDateTimeOriginal, QDateTime(QDate(2014, 10, 04), QTime(13, 47, 43.000), QTimeZone::UTC));
0154     verifyProperty(Property::PhotoFocalLength, 4.f);
0155     verifyProperty(Property::PhotoFocalLengthIn35mmFilm, 10.f);
0156     verifyProperty(Property::PhotoExposureTime, 0.0027027f);
0157     verifyProperty(Property::PhotoFNumber, 1.f);
0158     verifyProperty(Property::PhotoApertureValue, 0.f);
0159     verifyProperty(Property::PhotoExposureBiasValue, 0.f);
0160     verifyProperty(Property::PhotoWhiteBalance, 0);
0161     verifyProperty(Property::PhotoMeteringMode, 1);
0162     verifyProperty(Property::PhotoISOSpeedRatings, 100);
0163     verifyProperty(Property::PhotoSaturation, 0);
0164     verifyProperty(Property::PhotoSharpness, 0);
0165     verifyProperty(Property::Title, QStringLiteral("Title"));
0166     verifyProperty(Property::Subject, QStringLiteral("Subject"));
0167 }
0168 
0169 void Exiv2ExtractorTest::testJpegJxlProperties_data()
0170 {
0171     QTest::addColumn<QString>("fileName");
0172     QTest::addColumn<QString>("mimeType");
0173 
0174     QTest::addRow("jpeg") << QStringLiteral("test.jpg") << QStringLiteral("image/jpeg");
0175     QTest::addRow("jxl") << QStringLiteral("test.jxl") << QStringLiteral("image/jxl");
0176     QTest::addRow("webp") << QStringLiteral("test.webp") << QStringLiteral("image/webp");
0177 }
0178 
0179 void Exiv2ExtractorTest::testHeifProperties()
0180 {
0181     Exiv2Extractor plugin{this};
0182 
0183     if (!plugin.mimetypes().contains("image/heif")) {
0184         QSKIP("BMFF support required for HEIF");
0185     }
0186 
0187     SimpleExtractionResult result(testFilePath("test.heif"), "image/heif");
0188     plugin.extract(&result);
0189 
0190     QCOMPARE(result.types().size(), 1);
0191     QCOMPARE(result.types().constFirst(), Type::Image);
0192 
0193     const auto properties = result.properties();
0194     QCOMPARE(properties.size(), 23);
0195 
0196     auto verifyProperty = [&properties](KFileMetaData::Property::Property prop, const QVariant &value)
0197     {
0198     if (value.canConvert<float>()) {
0199         QCOMPARE(properties.value(prop).toFloat(), value.toFloat());
0200     } else {
0201         QCOMPARE(properties.value(prop), value);
0202     }
0203     };
0204 
0205     verifyProperty(Property::Artist, QStringLiteral("Artist"));
0206     verifyProperty(Property::Description, QStringLiteral("Description"));
0207     verifyProperty(Property::Copyright, QStringLiteral("Copyright"));
0208     verifyProperty(Property::Generator, QStringLiteral("digikam-5.9.0"));
0209     verifyProperty(Property::PhotoGpsLatitude, 51.3331f);
0210     verifyProperty(Property::PhotoGpsLongitude, -0.705575f);
0211     verifyProperty(Property::PhotoGpsAltitude, 0.f);
0212     verifyProperty(Property::Width, 750);
0213     verifyProperty(Property::Height, 1000);
0214     verifyProperty(Property::Manufacturer, QStringLiteral("samsung"));
0215     verifyProperty(Property::Model, QStringLiteral("SM-J610N"));
0216     verifyProperty(Property::ImageDateTime, QDateTime(QDate(2022, 03, 24), QTime(18, 20, 07.000), QTimeZone::UTC));
0217     verifyProperty(Property::PhotoFlash, 0);
0218     verifyProperty(Property::PhotoPixelXDimension, 750);
0219     verifyProperty(Property::PhotoPixelYDimension, 1000);
0220     verifyProperty(Property::PhotoDateTimeOriginal, QDateTime(QDate(2020, 03, 31), QTime(11, 14, 30.000), QTimeZone::UTC));
0221     verifyProperty(Property::PhotoFocalLength, 3.6f);
0222     verifyProperty(Property::PhotoFocalLengthIn35mmFilm, 26.f);
0223     verifyProperty(Property::PhotoExposureTime, 0.00429185f);
0224     verifyProperty(Property::PhotoFNumber, 1.9f);
0225     verifyProperty(Property::PhotoApertureValue, 1.85f);
0226     verifyProperty(Property::PhotoExposureBiasValue, 0.f);
0227     verifyProperty(Property::PhotoWhiteBalance, 0);
0228     verifyProperty(Property::PhotoMeteringMode, 2);
0229     verifyProperty(Property::PhotoISOSpeedRatings, 40);
0230     verifyProperty(Property::PhotoSaturation, 0);
0231     verifyProperty(Property::PhotoSharpness, 0);
0232 }
0233 
0234 QTEST_GUILESS_MAIN(Exiv2ExtractorTest)
0235 
0236 #include "exiv2extractortest.moc"