File indexing completed on 2025-04-20 03:39:08
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"