KExiv2

kexiv2iptc.cpp
1/*
2 SPDX-FileCopyrightText: 2006-2015 Gilles Caulier <caulier dot gilles at gmail dot com>
3 SPDX-FileCopyrightText: 2006-2012 Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
4
5 SPDX-License-Identifier: GPL-2.0-or-later
6*/
7
8// Local includes
9
10#include "kexiv2.h"
11#include "kexiv2_p.h"
12#include "libkexiv2_debug.h"
13
14namespace KExiv2Iface
15{
16
17bool KExiv2::canWriteIptc(const QString& filePath)
18{
19 try
20 {
21#if EXIV2_TEST_VERSION(0,28,0)
22 Exiv2::Image::UniquePtr image =
23#else
24 Exiv2::Image::AutoPtr image =
25#endif
26 Exiv2::ImageFactory::open((const char*)
27 (QFile::encodeName(filePath).constData()));
28
29 Exiv2::AccessMode mode = image->checkMode(Exiv2::mdIptc);
30 return (mode == Exiv2::amWrite || mode == Exiv2::amReadWrite);
31 }
32 catch(Exiv2::Error& e)
33 {
34 std::string s(e.what());
35 qCCritical(LIBKEXIV2_LOG) << "Cannot check Iptc access mode using Exiv2 (Error #"
36#if EXIV2_TEST_VERSION(0,28,0)
37 << Exiv2::Error(e.code()).what()
38#else
39 << e.code() << ": " << s.c_str()
40#endif
41 << ")";
42 }
43 catch(...)
44 {
45 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
46 }
47
48 return false;
49}
50
51bool KExiv2::hasIptc() const
52{
53 return !d->iptcMetadata().empty();
54}
55
57{
58 try
59 {
60 d->iptcMetadata().clear();
61 return true;
62 }
63 catch(Exiv2::Error& e)
64 {
65 d->printExiv2ExceptionError(QString::fromLatin1("Cannot clear Iptc data using Exiv2 "), e);
66 }
67 catch(...)
68 {
69 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
70 }
71
72 return false;
73}
74
75QByteArray KExiv2::getIptc(bool addIrbHeader) const
76{
77 try
78 {
79 if (!d->iptcMetadata().empty())
80 {
81 Exiv2::IptcData& iptc = d->iptcMetadata();
82 Exiv2::DataBuf c2;
83
84 if (addIrbHeader)
85 {
86 c2 = Exiv2::Photoshop::setIptcIrb(nullptr, 0, iptc);
87 }
88 else
89 {
90 c2 = Exiv2::IptcParser::encode(d->iptcMetadata());
91 }
92
93#if EXIV2_TEST_VERSION(0,28,0)
94 QByteArray data((const char*)c2.c_data(), c2.size());
95#else
96 QByteArray data((const char*)c2.pData_, c2.size_);
97#endif
98 return data;
99
100 }
101 }
102 catch(Exiv2::Error& e)
103 {
104 if (!d->filePath.isEmpty())
105 {
106 qCCritical(LIBKEXIV2_LOG) << "From file " << d->filePath.toLatin1().constData();
107 }
108
109 d->printExiv2ExceptionError(QString::fromLatin1("Cannot get Iptc data using Exiv2 "), e);
110 }
111 catch(...)
112 {
113 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
114 }
115
116 return QByteArray();
117}
118
119bool KExiv2::setIptc(const QByteArray& data) const
120{
121 try
122 {
123 if (!data.isEmpty())
124 {
125 Exiv2::IptcParser::decode(d->iptcMetadata(), (const Exiv2::byte*)data.data(), data.size());
126 return (!d->iptcMetadata().empty());
127 }
128 }
129 catch(Exiv2::Error& e)
130 {
131 if (!d->filePath.isEmpty())
132 {
133 qCCritical(LIBKEXIV2_LOG) << "From file " << d->filePath.toLatin1().constData();
134 }
135
136 d->printExiv2ExceptionError(QString::fromLatin1("Cannot set Iptc data using Exiv2 "), e);
137 }
138 catch(...)
139 {
140 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
141 }
142
143 return false;
144}
145
146KExiv2::MetaDataMap KExiv2::getIptcTagsDataList(const QStringList& iptcKeysFilter, bool invertSelection) const
147{
148 if (d->iptcMetadata().empty())
149 return MetaDataMap();
150
151 try
152 {
153 Exiv2::IptcData iptcData = d->iptcMetadata();
154 iptcData.sortByKey();
155
156 QString ifDItemName;
157 MetaDataMap metaDataMap;
158
159 for (Exiv2::IptcData::iterator md = iptcData.begin(); md != iptcData.end(); ++md)
160 {
161 QString key = QString::fromLocal8Bit(md->key().c_str());
162
163 // Decode the tag value with a user friendly output.
164 std::ostringstream os;
165 os << *md;
166
167 QString value;
168
169 if (key == QString::fromLatin1("Iptc.Envelope.CharacterSet"))
170 {
171 value = QString::fromLatin1(iptcData.detectCharset());
172 }
173 else
174 {
175 value = QString::fromUtf8(os.str().c_str());
176 }
177
178 // To make a string just on one line.
180
181 // Some Iptc key are redondancy. check if already one exist...
182 MetaDataMap::iterator it = metaDataMap.find(key);
183
184 // We apply a filter to get only the Iptc tags that we need.
185
186 if (!iptcKeysFilter.isEmpty())
187 {
188 if (!invertSelection)
189 {
190 if (iptcKeysFilter.contains(key.section(QString::fromLatin1("."), 1, 1)))
191 {
192 if (it == metaDataMap.end())
193 {
194 metaDataMap.insert(key, value);
195 }
196 else
197 {
198 QString v = *it;
200 v.append(value);
201 metaDataMap.insert(key, v);
202 }
203 }
204 }
205 else
206 {
207 if (!iptcKeysFilter.contains(key.section(QString::fromLatin1("."), 1, 1)))
208 {
209 if (it == metaDataMap.end())
210 {
211 metaDataMap.insert(key, value);
212 }
213 else
214 {
215 QString v = *it;
217 v.append(value);
218 metaDataMap.insert(key, v);
219 }
220 }
221 }
222 }
223 else // else no filter at all.
224 {
225 if (it == metaDataMap.end())
226 {
227 metaDataMap.insert(key, value);
228 }
229 else
230 {
231 QString v = *it;
233 v.append(value);
234 metaDataMap.insert(key, v);
235 }
236 }
237
238 }
239
240 return metaDataMap;
241 }
242 catch (Exiv2::Error& e)
243 {
244 d->printExiv2ExceptionError(QString::fromLatin1("Cannot parse Iptc metadata using Exiv2 "), e);
245 }
246 catch(...)
247 {
248 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
249 }
250
251 return MetaDataMap();
252}
253
254QString KExiv2::getIptcTagTitle(const char* iptcTagName)
255{
256 try
257 {
258 std::string iptckey(iptcTagName);
259 Exiv2::IptcKey ik(iptckey);
260 return QString::fromLocal8Bit( Exiv2::IptcDataSets::dataSetTitle(ik.tag(), ik.record()) );
261 }
262 catch (Exiv2::Error& e)
263 {
264 d->printExiv2ExceptionError(QString::fromLatin1("Cannot get metadata tag title using Exiv2 "), e);
265 }
266 catch(...)
267 {
268 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
269 }
270
271 return QString();
272}
273
275{
276 try
277 {
278 std::string iptckey(iptcTagName);
279 Exiv2::IptcKey ik(iptckey);
280 return QString::fromLocal8Bit( Exiv2::IptcDataSets::dataSetDesc(ik.tag(), ik.record()) );
281 }
282 catch (Exiv2::Error& e)
283 {
284 d->printExiv2ExceptionError(QString::fromLatin1("Cannot get metadata tag description using Exiv2 "), e);
285 }
286 catch(...)
287 {
288 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
289 }
290
291 return QString();
292}
293
294bool KExiv2::removeIptcTag(const char* iptcTagName, bool setProgramName) const
295{
296 if (!setProgramId(setProgramName))
297 return false;
298
299 try
300 {
301 Exiv2::IptcData::iterator it = d->iptcMetadata().begin();
302 int i = 0;
303
304 while(it != d->iptcMetadata().end())
305 {
306 QString key = QString::fromLocal8Bit(it->key().c_str());
307
308 if (key == QString::fromLatin1(iptcTagName))
309 {
310 it = d->iptcMetadata().erase(it);
311 ++i;
312 }
313 else
314 {
315 ++it;
316 }
317 };
318
319 if (i > 0)
320 return true;
321 }
322 catch(Exiv2::Error& e)
323 {
324 d->printExiv2ExceptionError(QString::fromLatin1("Cannot remove Iptc tag using Exiv2 "), e);
325 }
326 catch(...)
327 {
328 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
329 }
330
331 return false;
332}
333
334bool KExiv2::setIptcTagData(const char* iptcTagName, const QByteArray& data, bool setProgramName) const
335{
336 if (data.isEmpty())
337 return false;
338
339 if (!setProgramId(setProgramName))
340 return false;
341
342 try
343 {
344 Exiv2::DataValue val((Exiv2::byte *)data.data(), data.size());
345 d->iptcMetadata()[iptcTagName] = val;
346 return true;
347 }
348 catch(Exiv2::Error& e)
349 {
350 d->printExiv2ExceptionError(QString::fromLatin1("Cannot set Iptc tag data into image using Exiv2 "), e);
351 }
352 catch(...)
353 {
354 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
355 }
356
357 return false;
358}
359
360QByteArray KExiv2::getIptcTagData(const char* iptcTagName) const
361{
362 try
363 {
364 Exiv2::IptcKey iptcKey(iptcTagName);
365 Exiv2::IptcData iptcData(d->iptcMetadata());
366 Exiv2::IptcData::iterator it = iptcData.findKey(iptcKey);
367
368 if (it != iptcData.end())
369 {
370 char* const s = new char[(*it).size()];
371 (*it).copy((Exiv2::byte*)s, Exiv2::bigEndian);
372 QByteArray data(s, (*it).size());
373 delete [] s;
374 return data;
375 }
376 }
377 catch(Exiv2::Error& e)
378 {
379 d->printExiv2ExceptionError(QString::fromLatin1("Cannot find Iptc key '%1' into image using Exiv2 ").arg(QString::fromLatin1(iptcTagName)), e);
380 }
381 catch(...)
382 {
383 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
384 }
385
386 return QByteArray();
387}
388
389QString KExiv2::getIptcTagString(const char* iptcTagName, bool escapeCR) const
390{
391 try
392 {
393 Exiv2::IptcKey iptcKey(iptcTagName);
394 Exiv2::IptcData iptcData(d->iptcMetadata());
395 Exiv2::IptcData::iterator it = iptcData.findKey(iptcKey);
396
397 if (it != iptcData.end())
398 {
399 std::ostringstream os;
400 os << *it;
401 QString tagValue(QString::fromLatin1(os.str().c_str()));
402
403 if (escapeCR)
404 tagValue.replace(QString::fromLatin1("\n"), QString::fromLatin1(" "));
405
406 return tagValue;
407 }
408 }
409 catch(Exiv2::Error& e)
410 {
411 d->printExiv2ExceptionError(QString::fromLatin1("Cannot find Iptc key '%1' into image using Exiv2 ").arg(QString::fromLatin1(iptcTagName)), e);
412 }
413 catch(...)
414 {
415 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
416 }
417
418 return QString();
419}
420
421bool KExiv2::setIptcTagString(const char* iptcTagName, const QString& value, bool setProgramName) const
422{
423 if (!setProgramId(setProgramName))
424 return false;
425
426 try
427 {
428 d->iptcMetadata()[iptcTagName] = std::string(value.toUtf8().constData());
429
430 // Make sure we have set the charset to UTF-8
431 d->iptcMetadata()["Iptc.Envelope.CharacterSet"] = "\33%G";
432 return true;
433 }
434 catch(Exiv2::Error& e)
435 {
436 d->printExiv2ExceptionError(QString::fromLatin1("Cannot set Iptc tag string into image using Exiv2 "), e);
437 }
438 catch(...)
439 {
440 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
441 }
442
443 return false;
444}
445
446QStringList KExiv2::getIptcTagsStringList(const char* iptcTagName, bool escapeCR) const
447{
448 try
449 {
450 if (!d->iptcMetadata().empty())
451 {
452 QStringList values;
453 Exiv2::IptcData iptcData(d->iptcMetadata());
454
455 for (Exiv2::IptcData::iterator it = iptcData.begin(); it != iptcData.end(); ++it)
456 {
457 QString key = QString::fromLocal8Bit(it->key().c_str());
458
459 if (key == QString::fromLatin1(iptcTagName))
460 {
461 QString tagValue = QString::fromUtf8(it->toString().c_str());
462
463 if (escapeCR)
464 tagValue.replace(QString::fromLatin1("\n"), QString::fromLatin1(" "));
465
466 values.append(tagValue);
467 }
468 }
469
470 return values;
471 }
472 }
473 catch(Exiv2::Error& e)
474 {
475 d->printExiv2ExceptionError(QString::fromLatin1("Cannot find Iptc key '%1' into image using Exiv2 ").arg(QString::fromLatin1(iptcTagName)), e);
476 }
477 catch(...)
478 {
479 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
480 }
481
482 return QStringList();
483}
484
485bool KExiv2::setIptcTagsStringList(const char* iptcTagName, int maxSize,
486 const QStringList& oldValues, const QStringList& newValues,
487 bool setProgramName) const
488{
489 if (!setProgramId(setProgramName))
490 return false;
491
492 try
493 {
494 QStringList oldvals = oldValues;
495 QStringList newvals = newValues;
496
497 qCDebug(LIBKEXIV2_LOG) << d->filePath.toLatin1().constData() << " : " << iptcTagName
498 << " => " << newvals.join(QString::fromLatin1(",")).toLatin1().constData();
499
500 // Remove all old values.
501 Exiv2::IptcData iptcData(d->iptcMetadata());
502 Exiv2::IptcData::iterator it = iptcData.begin();
503
504 while(it != iptcData.end())
505 {
506 QString key = QString::fromLocal8Bit(it->key().c_str());
507 QString val = QString::fromUtf8(it->toString().c_str());
508
509 // Also remove new values to avoid duplicates. They will be added again below.
510 if ( key == QString::fromLatin1(iptcTagName) &&
511 (oldvals.contains(val) || newvals.contains(val))
512 )
513 it = iptcData.erase(it);
514 else
515 ++it;
516 };
517
518 // Add new values.
519
520 Exiv2::IptcKey iptcTag(iptcTagName);
521
522 for (QStringList::iterator it = newvals.begin(); it != newvals.end(); ++it)
523 {
524 QString key = *it;
525 key.truncate(maxSize);
526
527#if EXIV2_TEST_VERSION(0,28,0)
528 Exiv2::Value::UniquePtr val = Exiv2::Value::create(Exiv2::string);
529#else
530 Exiv2::Value::AutoPtr val = Exiv2::Value::create(Exiv2::string);
531#endif
532 val->read(key.toUtf8().constData());
533 iptcData.add(iptcTag, val.get());
534 }
535
536 d->iptcMetadata() = iptcData;
537
538 // Make sure character set is UTF-8
539 setIptcTagString("Iptc.Envelope.CharacterSet", QString::fromLatin1("\33%G"), false);
540
541 return true;
542 }
543 catch(Exiv2::Error& e)
544 {
545 d->printExiv2ExceptionError(QString::fromLatin1("Cannot set Iptc key '%1' into image using Exiv2 ").arg(QString::fromLatin1(iptcTagName)), e);
546 }
547 catch(...)
548 {
549 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
550 }
551
552 return false;
553}
554
556{
557 try
558 {
559 if (!d->iptcMetadata().empty())
560 {
561 QStringList keywords;
562 Exiv2::IptcData iptcData(d->iptcMetadata());
563
564 for (Exiv2::IptcData::iterator it = iptcData.begin(); it != iptcData.end(); ++it)
565 {
566 QString key = QString::fromLocal8Bit(it->key().c_str());
567
568 if (key == QString::fromLatin1("Iptc.Application2.Keywords"))
569 {
570 QString val = QString::fromUtf8(it->toString().c_str());
571 keywords.append(val);
572 }
573 }
574
575 qCDebug(LIBKEXIV2_LOG) << d->filePath << " ==> Read Iptc Keywords: " << keywords;
576
577 return keywords;
578 }
579 }
580 catch(Exiv2::Error& e)
581 {
582 d->printExiv2ExceptionError(QString::fromLatin1("Cannot get Iptc Keywords from image using Exiv2 "), e);
583 }
584 catch(...)
585 {
586 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
587 }
588
589 return QStringList();
590}
591
592bool KExiv2::setIptcKeywords(const QStringList& oldKeywords, const QStringList& newKeywords,
593 bool setProgramName) const
594{
595 if (!setProgramId(setProgramName))
596 return false;
597
598 try
599 {
600 QStringList oldkeys = oldKeywords;
601 QStringList newkeys = newKeywords;
602
603 qCDebug(LIBKEXIV2_LOG) << d->filePath << " ==> New Iptc Keywords: " << newkeys;
604
605 // Remove all old keywords.
606 Exiv2::IptcData iptcData(d->iptcMetadata());
607 Exiv2::IptcData::iterator it = iptcData.begin();
608
609 while(it != iptcData.end())
610 {
611 QString key = QString::fromLocal8Bit(it->key().c_str());
612 QString val = QString::fromUtf8(it->toString().c_str());
613
614 // Also remove new keywords to avoid duplicates. They will be added again below.
615 if ( key == QString::fromLatin1("Iptc.Application2.Keywords") &&
616 (oldKeywords.contains(val) || newKeywords.contains(val))
617 )
618 it = iptcData.erase(it);
619 else
620 ++it;
621 };
622
623 // Add new keywords. Note that Keywords Iptc tag is limited to 64 char but can be redondant.
624
625 Exiv2::IptcKey iptcTag("Iptc.Application2.Keywords");
626
627 for (QStringList::iterator it = newkeys.begin(); it != newkeys.end(); ++it)
628 {
629 QString key = *it;
630 key.truncate(64);
631
632#if EXIV2_TEST_VERSION(0,28,0)
633 Exiv2::Value::UniquePtr val = Exiv2::Value::create(Exiv2::string);
634#else
635 Exiv2::Value::AutoPtr val = Exiv2::Value::create(Exiv2::string);
636#endif
637 val->read(key.toUtf8().constData());
638 iptcData.add(iptcTag, val.get());
639 }
640
641 d->iptcMetadata() = iptcData;
642
643 // Make sure character set is UTF-8
644 setIptcTagString("Iptc.Envelope.CharacterSet", QString::fromLatin1("\33%G"), false);
645
646 return true;
647 }
648 catch(Exiv2::Error& e)
649 {
650 d->printExiv2ExceptionError(QString::fromLatin1("Cannot set Iptc Keywords into image using Exiv2 "), e);
651 }
652 catch(...)
653 {
654 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
655 }
656
657 return false;
658}
659
661{
662 try
663 {
664 if (!d->iptcMetadata().empty())
665 {
666 QStringList subjects;
667 Exiv2::IptcData iptcData(d->iptcMetadata());
668
669 for (Exiv2::IptcData::iterator it = iptcData.begin(); it != iptcData.end(); ++it)
670 {
671 QString key = QString::fromLocal8Bit(it->key().c_str());
672
673 if (key == QString::fromLatin1("Iptc.Application2.Subject"))
674 {
675 QString val(QString::fromLatin1(it->toString().c_str()));
676 subjects.append(val);
677 }
678 }
679
680 return subjects;
681 }
682 }
683 catch(Exiv2::Error& e)
684 {
685 d->printExiv2ExceptionError(QString::fromLatin1("Cannot get Iptc Subjects from image using Exiv2 "), e);
686 }
687 catch(...)
688 {
689 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
690 }
691
692 return QStringList();
693}
694
695bool KExiv2::setIptcSubjects(const QStringList& oldSubjects, const QStringList& newSubjects,
696 bool setProgramName) const
697{
698 if (!setProgramId(setProgramName))
699 return false;
700
701 try
702 {
703 QStringList oldDef = oldSubjects;
704 QStringList newDef = newSubjects;
705
706 // Remove all old subjects.
707 Exiv2::IptcData iptcData(d->iptcMetadata());
708 Exiv2::IptcData::iterator it = iptcData.begin();
709
710 while(it != iptcData.end())
711 {
712 QString key = QString::fromLocal8Bit(it->key().c_str());
713 QString val = QString::fromUtf8(it->toString().c_str());
714
715 if (key == QString::fromLatin1("Iptc.Application2.Subject") && oldDef.contains(val))
716 it = iptcData.erase(it);
717 else
718 ++it;
719 };
720
721 // Add new subjects. Note that Keywords Iptc tag is limited to 236 char but can be redondant.
722
723 Exiv2::IptcKey iptcTag("Iptc.Application2.Subject");
724
725 for (QStringList::iterator it = newDef.begin(); it != newDef.end(); ++it)
726 {
727 QString key = *it;
728 key.truncate(236);
729
730#if EXIV2_TEST_VERSION(0,28,0)
731 Exiv2::Value::UniquePtr val = Exiv2::Value::create(Exiv2::string);
732#else
733 Exiv2::Value::AutoPtr val = Exiv2::Value::create(Exiv2::string);
734#endif
735 val->read(key.toUtf8().constData());
736 iptcData.add(iptcTag, val.get());
737 }
738
739 d->iptcMetadata() = iptcData;
740
741 // Make sure character set is UTF-8
742 setIptcTagString("Iptc.Envelope.CharacterSet", QString::fromLatin1("\33%G"), false);
743
744 return true;
745 }
746 catch(Exiv2::Error& e)
747 {
748 d->printExiv2ExceptionError(QString::fromLatin1("Cannot set Iptc Subjects into image using Exiv2 "), e);
749 }
750 catch(...)
751 {
752 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
753 }
754
755 return false;
756}
757
759{
760 try
761 {
762 if (!d->iptcMetadata().empty())
763 {
764 QStringList subCategories;
765 Exiv2::IptcData iptcData(d->iptcMetadata());
766
767 for (Exiv2::IptcData::iterator it = iptcData.begin(); it != iptcData.end(); ++it)
768 {
769 QString key = QString::fromLocal8Bit(it->key().c_str());
770
771 if (key == QString::fromLatin1("Iptc.Application2.SuppCategory"))
772 {
773 QString val(QString::fromLatin1(it->toString().c_str()));
774 subCategories.append(val);
775 }
776 }
777
778 return subCategories;
779 }
780 }
781 catch(Exiv2::Error& e)
782 {
783 d->printExiv2ExceptionError(QString::fromLatin1("Cannot get Iptc Sub Categories from image using Exiv2 "), e);
784 }
785 catch(...)
786 {
787 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
788 }
789
790 return QStringList();
791}
792
793bool KExiv2::setIptcSubCategories(const QStringList& oldSubCategories, const QStringList& newSubCategories,
794 bool setProgramName) const
795{
796 if (!setProgramId(setProgramName))
797 return false;
798
799 try
800 {
801 QStringList oldkeys = oldSubCategories;
802 QStringList newkeys = newSubCategories;
803
804 // Remove all old Sub Categories.
805 Exiv2::IptcData iptcData(d->iptcMetadata());
806 Exiv2::IptcData::iterator it = iptcData.begin();
807
808 while(it != iptcData.end())
809 {
810 QString key = QString::fromLocal8Bit(it->key().c_str());
811 QString val = QString::fromUtf8(it->toString().c_str());
812
813 if (key == QString::fromLatin1("Iptc.Application2.SuppCategory") && oldSubCategories.contains(val))
814 it = iptcData.erase(it);
815 else
816 ++it;
817 };
818
819 // Add new Sub Categories. Note that SubCategories Iptc tag is limited to 32
820 // characters but can be redondant.
821
822 Exiv2::IptcKey iptcTag("Iptc.Application2.SuppCategory");
823
824 for (QStringList::iterator it = newkeys.begin(); it != newkeys.end(); ++it)
825 {
826 QString key = *it;
827 key.truncate(32);
828
829#if EXIV2_TEST_VERSION(0,28,0)
830 Exiv2::Value::UniquePtr val = Exiv2::Value::create(Exiv2::string);
831#else
832 Exiv2::Value::AutoPtr val = Exiv2::Value::create(Exiv2::string);
833#endif
834 val->read(key.toUtf8().constData());
835 iptcData.add(iptcTag, val.get());
836 }
837
838 d->iptcMetadata() = iptcData;
839
840 // Make sure character set is UTF-8
841 setIptcTagString("Iptc.Envelope.CharacterSet", QString::fromLatin1("\33%G"), false);
842
843 return true;
844 }
845 catch(Exiv2::Error& e)
846 {
847 d->printExiv2ExceptionError(QString::fromLatin1("Cannot set Iptc Sub Categories into image using Exiv2 "), e);
848 }
849 catch(...)
850 {
851 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
852 }
853
854 return false;
855}
856
858{
859 try
860 {
862 tags << Exiv2::IptcDataSets::envelopeRecordList()
863 << Exiv2::IptcDataSets::application2RecordList();
864
865 TagsMap tagsMap;
866
867 for (QList<const Exiv2::DataSet*>::iterator it = tags.begin(); it != tags.end(); ++it)
868 {
869 do
870 {
871 QString key = QLatin1String( Exiv2::IptcKey( (*it)->number_, (*it)->recordId_ ).key().c_str() );
872 QStringList values;
873 values << QString::fromLatin1((*it)->name_) << QString::fromLatin1((*it)->title_) << QString::fromLatin1((*it)->desc_);
874 tagsMap.insert(key, values);
875 ++(*it);
876 }
877 while((*it)->number_ != 0xffff);
878 }
879
880 return tagsMap;
881 }
882 catch(Exiv2::Error& e)
883 {
884 d->printExiv2ExceptionError(QString::fromLatin1("Cannot get Iptc Tags list using Exiv2 "), e);
885 }
886 catch(...)
887 {
888 qCCritical(LIBKEXIV2_LOG) << "Default exception from Exiv2";
889 }
890
891 return TagsMap();
892}
893
894} // NameSpace KExiv2Iface
QStringList getIptcSubjects() const
Return a strings list of Iptc subjects from image.
bool setIptcSubCategories(const QStringList &oldSubCategories, const QStringList &newSubCategories, bool setProgramName=true) const
Set Iptc sub-categories using a list of strings defined by 'newSubCategories' parameter.
virtual bool setProgramId(bool on=true) const
Re-implement this method to set automatically the Program Name and Program Version information in Exi...
Definition kexiv2.cpp:526
QByteArray getIptc(bool addIrbHeader=false) const
Return a Qt byte array copy of Iptc container get from current image.
static bool canWriteIptc(const QString &filePath)
Return 'true' if Iptc can be written in file.
KExiv2::TagsMap getIptcTagsList() const
Return a map of all standard Iptc tags supported by Exiv2.
QStringList getIptcTagsStringList(const char *iptcTagName, bool escapeCR=true) const
Returns a strings list with of multiple Iptc tags from the image.
QStringList getIptcKeywords() const
Return a strings list of Iptc keywords from image.
KExiv2::MetaDataMap getIptcTagsDataList(const QStringList &iptcKeysFilter=QStringList(), bool invertSelection=false) const
Return a map of Iptc tags name/value found in metadata sorted by Iptc keys given by 'iptcKeysFilter'.
QMap< QString, QStringList > TagsMap
A map used to store Tags Key and a list of Tags properties :
Definition kexiv2.h:125
bool setIptcSubjects(const QStringList &oldSubjects, const QStringList &newSubjects, bool setProgramName=true) const
Set Iptc subjects using a list of strings defined by 'newSubjects' parameter.
QMap< QString, QString > MetaDataMap
A map used to store Tags Key and Tags Value.
Definition kexiv2.h:112
bool hasIptc() const
Return 'true' if metadata container in memory as Iptc.
bool setIptcTagString(const char *iptcTagName, const QString &value, bool setProgramName=true) const
Set an Iptc tag content using a string.
bool setIptcTagsStringList(const char *iptcTagName, int maxSize, const QStringList &oldValues, const QStringList &newValues, bool setProgramName=true) const
Set multiple Iptc tags contents using a strings list.
QString getIptcTagTitle(const char *iptcTagName)
Return the Iptc Tag title or a null string.
bool setIptcTagData(const char *iptcTagName, const QByteArray &data, bool setProgramName=true) const
Set an Iptc tag content using a bytes array.
QStringList getIptcSubCategories() const
Return a strings list of Iptc sub-categories from image.
bool setIptc(const QByteArray &data) const
Set the Iptc data using a Qt byte array.
QString getIptcTagString(const char *iptcTagName, bool escapeCR=true) const
Get an Iptc tag content like a string.
bool removeIptcTag(const char *iptcTagName, bool setProgramName=true) const
Remove the all instance of Iptc tags 'iptcTagName' from Iptc metadata.
QString getIptcTagDescription(const char *iptcTagName)
Return the Iptc Tag description or a null string.
QByteArray getIptcTagData(const char *iptcTagName) const
Get an Iptc tag content as a bytes array.
bool clearIptc() const
Clear the Iptc metadata container in memory.
bool setIptcKeywords(const QStringList &oldKeywords, const QStringList &newKeywords, bool setProgramName=true) const
Set Iptc keywords using a list of strings defined by 'newKeywords' parameter.
KExiv2Iface - Exiv2 library interface.
Definition kexiv2.cpp:17
const char * constData() const const
char * data()
bool isEmpty() const const
QByteArray & replace(QByteArrayView before, QByteArrayView after)
qsizetype size() const const
QByteArray encodeName(const QString &fileName)
void append(QList< T > &&value)
iterator begin()
iterator end()
bool isEmpty() const const
iterator end()
iterator find(const Key &key)
iterator insert(const Key &key, const T &value)
QString & append(QChar ch)
QString fromLatin1(QByteArrayView str)
QString fromLocal8Bit(QByteArrayView str)
QString fromUtf8(QByteArrayView str)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
QString section(QChar sep, qsizetype start, qsizetype end, SectionFlags flags) const const
QByteArray toLatin1() const const
QByteArray toUtf8() const const
void truncate(qsizetype position)
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
QString join(QChar separator) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:03:27 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.