1/*
2 SPDX-FileCopyrightText: 2022 Kai Uwe Broulik <kde@broulik.de>
3
4 SPDX-License-Identifier: LGPL-2.1-or-later
5*/
6
7#include "pngextractor.h"
8#include "propertyinfo.h"
9
10#include <QImageReader>
11
12using namespace KFileMetaData;
13
14// Keywords specified in https://www.w3.org/TR/PNG/#11keywords
15static const struct {
16 QString key;
17 Property::Property property;
18} s_textMapping[] = {
19 // Short (one line) title or caption for image
20 {QStringLiteral("Title"), .property: Property::Title},
21 // Name of image's creator
22 {QStringLiteral("Author"), .property: Property::Author},
23 // Description of image (possibly long)
24 // Unfortunately, QImage puts all text keys with spaces, such as
25 // "Raw profile type exif", into the "Description" key,
26 // (cf. qt_getImageTextFromDescription), overriding the actual
27 // PNG description, and making it useless.
28 //{QStringLiteral("Description"), Property::Description},
29 // Copyright notice
30 {QStringLiteral("Copyright"), .property: Property::Copyright},
31 // Time of original image creation
32 {QStringLiteral("Creation Time"), .property: Property::CreationDate},
33 // Software used to create the image
34 {QStringLiteral("Software"), .property: Property::Generator},
35 // Disclaimer - Legal disclaimer
36 // Warning - Warning of nature of content
37 // Source - Device used to create the image
38 // Miscellaneous comment
39 {QStringLiteral("Comment"), .property: Property::Comment},
40};
41
42PngExtractor::PngExtractor(QObject* parent)
43 : ExtractorPlugin(parent)
44{
45}
46
47QStringList PngExtractor::mimetypes() const
48{
49 return {
50 QStringLiteral("image/png")
51 };
52}
53
54void PngExtractor::extract(ExtractionResult* result)
55{
56 QImageReader reader(result->inputUrl(), "png");
57 if (!reader.canRead()) {
58 return;
59 }
60
61 result->addType(type: Type::Image);
62
63 if (!result->inputFlags().testFlag(flag: ExtractionResult::ExtractMetaData)) {
64 return;
65 }
66
67 for (const auto &mapping : s_textMapping) {
68 QString text = reader.text(key: mapping.key);
69 if (text.isEmpty()) {
70 // Spec says, keywords are case-sensitive but of course the real world looks different.
71 text = reader.text(key: mapping.key.toLower());
72 }
73 if (text.isEmpty()) {
74 continue;
75 }
76
77 const auto propertyInfo = PropertyInfo(mapping.property);
78
79 if (propertyInfo.valueType() == QMetaType::QDateTime) {
80 // "For the Creation Time keyword, the date format defined in section 5.2.14 of RFC 1123 is suggested"
81 // which in turn references RFC822...
82 const QDateTime dt = QDateTime::fromString(string: text, format: Qt::RFC2822Date);
83
84 if (!dt.isValid()) {
85 continue;
86 }
87
88 result->add(property: mapping.property, value: dt);
89 continue;
90 }
91
92 result->add(property: mapping.property, value: text);
93 }
94}
95
96#include "moc_pngextractor.cpp"
97

source code of kfilemetadata/src/extractors/pngextractor.cpp