File indexing completed on 2024-04-28 15:39:55
0001 // SPDX-FileCopyrightText: 2003-2010 Jesper K. Pedersen <blackie@kde.org> 0002 // SPDX-FileCopyrightText: 2021-2023 Johannes Zarl-Zierl <johannes@zarl-zierl.at> 0003 // SPDX-FileCopyrightText: 2023 Tobias Leupold <tl at stonemx dot de> 0004 // 0005 // SPDX-License-Identifier: GPL-2.0-or-later 0006 0007 #include "FileInfo.h" 0008 0009 #include <kpabase/FileExtensions.h> 0010 #include <kpabase/SettingsData.h> 0011 #include <kpaexif/Info.h> 0012 0013 #include <Utilities/FastDateTime.h> 0014 #include <QFileInfo> 0015 #include <QRegularExpression> 0016 0017 #include <exiv2/version.hpp> 0018 0019 using namespace DB; 0020 0021 FileInfo FileInfo::read(const DB::FileName &fileName, DB::ExifMode mode) 0022 { 0023 return FileInfo(fileName, mode); 0024 } 0025 0026 DB::FileInfo::FileInfo(const DB::FileName &fileName, DB::ExifMode mode) 0027 : m_angle(0) 0028 , m_fileName(fileName) 0029 { 0030 parseEXIV2(fileName); 0031 0032 if (updateDataFromFileTimeStamp(fileName, mode)) 0033 m_date = QFileInfo(fileName.absolute()).lastModified(); 0034 } 0035 0036 Exiv2::ExifData &DB::FileInfo::getExifData() 0037 { 0038 return m_exifMap; 0039 } 0040 0041 const DB::FileName &DB::FileInfo::getFileName() const 0042 { 0043 return m_fileName; 0044 } 0045 0046 bool DB::FileInfo::updateDataFromFileTimeStamp(const DB::FileName &fileName, DB::ExifMode mode) 0047 { 0048 // If the date is valid from Exif reading, then we should not use the time stamp from the file. 0049 if (m_date.isValid()) 0050 return false; 0051 0052 // If we are not setting date, then we should of course not set the date 0053 if ((mode & EXIFMODE_DATE) == 0) 0054 return false; 0055 0056 // If we are we already have specifies that we want to sent the date (from the ReReadExif dialog), then we of course should. 0057 if ((mode & EXIFMODE_USE_IMAGE_DATE_IF_INVALID_EXIF_DATE) != 0) 0058 return true; 0059 0060 // Always trust for videos (this is a way to say that we should not trust for scaned in images - which makes no sense for videos) 0061 if (KPABase::isVideo(fileName)) 0062 return true; 0063 0064 // Finally use the info from the settings dialog 0065 return Settings::SettingsData::instance()->trustTimeStamps(); 0066 } 0067 0068 void DB::FileInfo::parseEXIV2(const DB::FileName &fileName) 0069 { 0070 m_exifMap = Exif::Info::instance()->metadata(fileName).exif; 0071 0072 // Date 0073 m_date = fetchEXIV2Date(m_exifMap, "Exif.Photo.DateTimeOriginal"); 0074 if (!m_date.isValid()) { 0075 m_date = fetchEXIV2Date(m_exifMap, "Exif.Photo.DateTimeDigitized"); 0076 if (!m_date.isValid()) 0077 m_date = fetchEXIV2Date(m_exifMap, "Exif.Image.DateTime"); 0078 } 0079 0080 // Angle 0081 if (m_exifMap.findKey(Exiv2::ExifKey("Exif.Image.Orientation")) != m_exifMap.end()) { 0082 const Exiv2::Exifdatum &datum = m_exifMap["Exif.Image.Orientation"]; 0083 0084 int orientation = 0; 0085 if (datum.count() > 0) { 0086 #if EXIV2_TEST_VERSION(0, 28, 0) 0087 orientation = datum.toInt64(); 0088 #else 0089 orientation = datum.toLong(); 0090 #endif 0091 } 0092 0093 m_angle = orientationToAngle(orientation); 0094 } 0095 0096 // Description 0097 if (m_exifMap.findKey(Exiv2::ExifKey("Exif.Image.ImageDescription")) != m_exifMap.end()) { 0098 const Exiv2::Exifdatum &datum = m_exifMap["Exif.Image.ImageDescription"]; 0099 m_description = QString::fromLocal8Bit(datum.toString().c_str()).trimmed(); 0100 // some cameras seem to add control characters. Remove them: 0101 m_description.remove(QRegularExpression(QString::fromLatin1("\\p{Cc}"))); 0102 } 0103 } 0104 0105 Utilities::FastDateTime FileInfo::fetchEXIV2Date(Exiv2::ExifData &map, const char *key) 0106 { 0107 try { 0108 if (map.findKey(Exiv2::ExifKey(key)) != map.end()) { 0109 const Exiv2::Exifdatum &datum = map[key]; 0110 return Utilities::FastDateTime::fromString(QString::fromLatin1(datum.toString().c_str()), Qt::ISODate); 0111 } 0112 } catch (...) { 0113 } 0114 0115 return Utilities::FastDateTime(); 0116 } 0117 0118 int DB::FileInfo::orientationToAngle(int orientation) 0119 { 0120 if (orientation == 1 || orientation == 2) 0121 return 0; 0122 else if (orientation == 3 || orientation == 4) 0123 return 180; 0124 else if (orientation == 5 || orientation == 8) 0125 return 270; 0126 else if (orientation == 6 || orientation == 7) 0127 return 90; 0128 0129 return 0; 0130 } 0131 0132 // vi:expandtab:tabstop=4 shiftwidth=4: