File: exiv2wrapper.cpp

package info (click to toggle)
pineapple-pictures 1.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,424 kB
  • sloc: cpp: 3,794; xml: 339; sh: 8; makefile: 2
file content (138 lines) | stat: -rw-r--r-- 3,832 bytes parent folder | download
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;
}