1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
// SPDX-FileCopyrightText: 2022 Gary Wang <wzc782970009@gmail.com>
//
// SPDX-License-Identifier: MIT
#include "exiv2wrapper.h"
#ifdef HAVE_EXIV2_VERSION
#include <exiv2/exiv2.hpp>
#else // HAVE_EXIV2_VERSION
namespace Exiv2 {
class Image {};
}
#endif // HAVE_EXIV2_VERSION
#include <sstream>
#include <QFile>
#include <QDebug>
Exiv2Wrapper::Exiv2Wrapper()
{
}
Exiv2Wrapper::~Exiv2Wrapper()
{
}
#ifdef HAVE_EXIV2_VERSION // stupid AppleClang...
template<typename Collection, typename Iterator>
void Exiv2Wrapper::cacheSection(Collection collection)
{
const Collection& exifData = collection;
Iterator it = exifData.begin(), end = exifData.end();
for (; it != end; ++it) {
QString key = QString::fromUtf8(it->key().c_str());
if (it->tagName().substr(0, 2) == "0x") continue;
// We might get exceptions like "No namespace info available for XMP prefix `Item'"
// when trying to get tagLabel() data from a Xmpdatum if the tag is not common-used.
// We don't care for those rare tags so let's just use a try-cache...
try {
QString label = QString::fromLocal8Bit(it->tagLabel().c_str());
std::ostringstream stream;
stream << *it;
QString value = QString::fromUtf8(stream.str().c_str());
m_metadataValue.insert(key, value);
m_metadataLabel.insert(key, label);
qDebug() << key << label << value;
#if EXIV2_TEST_VERSION(0, 28, 0)
} catch (Exiv2::Error & err) {
#else // 0.27.x
} catch (Exiv2::AnyError & err) {
#endif // EXIV2_TEST_VERSION(0, 28, 0)
qWarning() << "Error loading key" << key << ":" << err.what();
}
}
}
#endif // HAVE_EXIV2_VERSION
bool Exiv2Wrapper::load(const QString &filePath)
{
#ifdef HAVE_EXIV2_VERSION
QByteArray filePathByteArray = QFile::encodeName(filePath);
try {
m_exivImage.reset(Exiv2::ImageFactory::open(filePathByteArray.constData()).release());
m_exivImage->readMetadata();
} catch (const Exiv2::Error& error) {
m_errMsg = QString::fromUtf8(error.what());
return false;
}
return true;
#else // HAVE_EXIV2_VERSION
Q_UNUSED(filePath);
return false;
#endif // HAVE_EXIV2_VERSION
}
void Exiv2Wrapper::cacheSections()
{
#ifdef HAVE_EXIV2_VERSION
if (m_exivImage->checkMode(Exiv2::mdExif) & Exiv2::amRead) {
cacheSection<Exiv2::ExifData, Exiv2::ExifData::const_iterator>(m_exivImage->exifData());
}
if (m_exivImage->checkMode(Exiv2::mdIptc) & Exiv2::amRead) {
cacheSection<Exiv2::IptcData, Exiv2::IptcData::const_iterator>(m_exivImage->iptcData());
}
if (m_exivImage->checkMode(Exiv2::mdXmp) & Exiv2::amRead) {
cacheSection<Exiv2::XmpData, Exiv2::XmpData::const_iterator>(m_exivImage->xmpData());
}
// qDebug() << m_metadataValue;
// qDebug() << m_metadataLabel;
#endif // HAVE_EXIV2_VERSION
}
QString Exiv2Wrapper::comment() const
{
#ifdef HAVE_EXIV2_VERSION
return m_exivImage->comment().c_str();
#else // HAVE_EXIV2_VERSION
return QString();
#endif // HAVE_EXIV2_VERSION
}
QString Exiv2Wrapper::label(const QString &key) const
{
return m_metadataLabel.value(key);
}
QString Exiv2Wrapper::value(const QString &key) const
{
return m_metadataValue.value(key);
}
QString Exiv2Wrapper::XmpValue(const QString &rawValue)
{
QString ignored;
return Exiv2Wrapper::XmpValue(rawValue, ignored);
}
QString Exiv2Wrapper::XmpValue(const QString &rawValue, QString &language)
{
if (rawValue.size() > 6 && rawValue.startsWith(QLatin1String("lang=\""))) {
int pos = rawValue.indexOf('"', 6);
if (pos != -1) {
language = rawValue.mid(6, pos - 6);
return (rawValue.mid(pos + 2));
}
}
language.clear();
return rawValue;
}
|