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

KDE's Doxygen guidelines are available online.