36 |
36 |
#include "exif.hpp"
|
37 |
37 |
#include "iptc.hpp"
|
38 |
38 |
#include "xmp.hpp"
|
|
39 |
#include "futils.hpp"
|
39 |
40 |
#include "convert.hpp"
|
40 |
41 |
|
41 |
42 |
// + standard includes
|
... | ... | |
47 |
48 |
# define snprintf _snprintf
|
48 |
49 |
#endif
|
49 |
50 |
|
|
51 |
#ifdef EXV_HAVE_ICONV
|
|
52 |
# include <iconv.h>
|
|
53 |
# include <errno.h>
|
|
54 |
#endif
|
|
55 |
|
50 |
56 |
// Adobe XMP Toolkit
|
51 |
57 |
#ifdef EXV_HAVE_XMP_TOOLKIT
|
52 |
58 |
# define TXMP_STRING_TYPE std::string
|
... | ... | |
66 |
72 |
The return code indicates if the operation was successful.
|
67 |
73 |
*/
|
68 |
74 |
bool getTextValue(std::string& value, const Exiv2::XmpData::iterator& pos);
|
|
75 |
|
|
76 |
/*!
|
|
77 |
@brief Convert string charset with iconv.
|
|
78 |
*/
|
|
79 |
bool convertStringCharset(std::string &str, const char* from, const char* to);
|
|
80 |
|
69 |
81 |
}
|
70 |
82 |
|
71 |
83 |
// *****************************************************************************
|
... | ... | |
97 |
109 |
//! Constructor for Exif tags and XMP properties.
|
98 |
110 |
Converter(ExifData& exifData, XmpData& xmpData);
|
99 |
111 |
//! Constructor for Iptc tags and XMP properties.
|
100 |
|
Converter(IptcData& iptcData, XmpData& xmpData);
|
|
112 |
Converter(IptcData& iptcData, XmpData& xmpData, const char *iptcCharset = 0);
|
101 |
113 |
//@}
|
102 |
114 |
|
103 |
115 |
//! @name Manipulators
|
... | ... | |
277 |
289 |
ExifData *exifData_;
|
278 |
290 |
IptcData *iptcData_;
|
279 |
291 |
XmpData *xmpData_;
|
|
292 |
const char *iptcCharset_;
|
280 |
293 |
|
281 |
294 |
}; // class Converter
|
282 |
295 |
|
... | ... | |
411 |
424 |
};
|
412 |
425 |
|
413 |
426 |
Converter::Converter(ExifData& exifData, XmpData& xmpData)
|
414 |
|
: erase_(false), overwrite_(true), exifData_(&exifData), iptcData_(0), xmpData_(&xmpData)
|
|
427 |
: erase_(false), overwrite_(true), exifData_(&exifData), iptcData_(0), xmpData_(&xmpData), iptcCharset_(0)
|
415 |
428 |
{
|
416 |
429 |
}
|
417 |
430 |
|
418 |
|
Converter::Converter(IptcData& iptcData, XmpData& xmpData)
|
419 |
|
: erase_(false), overwrite_(true), exifData_(0), iptcData_(&iptcData), xmpData_(&xmpData)
|
|
431 |
Converter::Converter(IptcData& iptcData, XmpData& xmpData, const char *iptcCharset)
|
|
432 |
: erase_(false), overwrite_(true), exifData_(0), iptcData_(&iptcData), xmpData_(&xmpData), iptcCharset_(iptcCharset)
|
420 |
433 |
{
|
421 |
434 |
}
|
422 |
435 |
|
... | ... | |
1056 |
1069 |
++pos;
|
1057 |
1070 |
continue;
|
1058 |
1071 |
}
|
|
1072 |
if (iptcCharset_) convertStringCharset(value, iptcCharset_, "UTF-8");
|
1059 |
1073 |
(*xmpData_)[to] = value;
|
1060 |
1074 |
if (erase_) {
|
1061 |
1075 |
pos = iptcData_->erase(pos);
|
... | ... | |
1208 |
1222 |
#endif
|
1209 |
1223 |
}
|
1210 |
1224 |
|
|
1225 |
|
1211 |
1226 |
// *************************************************************************
|
1212 |
1227 |
// free functions
|
1213 |
1228 |
void copyExifToXmp(const ExifData& exifData, XmpData& xmpData)
|
... | ... | |
1242 |
1257 |
converter.syncExifWithXmp();
|
1243 |
1258 |
}
|
1244 |
1259 |
|
1245 |
|
void copyIptcToXmp(const IptcData& iptcData, XmpData& xmpData)
|
|
1260 |
void copyIptcToXmp(const IptcData& iptcData, XmpData& xmpData, const char *iptcCharset)
|
1246 |
1261 |
{
|
1247 |
|
Converter converter(const_cast<IptcData&>(iptcData), xmpData);
|
|
1262 |
if (!iptcCharset) iptcCharset = iptcData.detectCharset();
|
|
1263 |
if (!iptcCharset) iptcCharset = "ISO-8859-1";
|
|
1264 |
|
|
1265 |
Converter converter(const_cast<IptcData&>(iptcData), xmpData, iptcCharset);
|
1248 |
1266 |
converter.cnvToXmp();
|
1249 |
1267 |
}
|
1250 |
1268 |
|
1251 |
|
void moveIptcToXmp(IptcData& iptcData, XmpData& xmpData)
|
|
1269 |
void moveIptcToXmp(IptcData& iptcData, XmpData& xmpData, const char *iptcCharset)
|
1252 |
1270 |
{
|
1253 |
|
Converter converter(const_cast<IptcData&>(iptcData), xmpData);
|
|
1271 |
if (!iptcCharset) iptcCharset = iptcData.detectCharset();
|
|
1272 |
if (!iptcCharset) iptcCharset = "ISO-8859-1";
|
|
1273 |
Converter converter(const_cast<IptcData&>(iptcData), xmpData, iptcCharset);
|
1254 |
1274 |
converter.setErase();
|
1255 |
1275 |
converter.cnvToXmp();
|
1256 |
1276 |
}
|
... | ... | |
1259 |
1279 |
{
|
1260 |
1280 |
Converter converter(iptcData, const_cast<XmpData&>(xmpData));
|
1261 |
1281 |
converter.cnvFromXmp();
|
|
1282 |
iptcData["Iptc.Envelope.CharacterSet"] = "\033%G"; // indicate UTF-8 encoding
|
1262 |
1283 |
}
|
1263 |
1284 |
|
1264 |
1285 |
void moveXmpToIptc(XmpData& xmpData, IptcData& iptcData)
|
... | ... | |
1266 |
1287 |
Converter converter(iptcData, const_cast<XmpData&>(xmpData));
|
1267 |
1288 |
converter.setErase();
|
1268 |
1289 |
converter.cnvFromXmp();
|
|
1290 |
iptcData["Iptc.Envelope.CharacterSet"] = "\033%G"; // indicate UTF-8 encoding
|
1269 |
1291 |
}
|
1270 |
1292 |
|
1271 |
1293 |
} // namespace Exiv2
|
... | ... | |
1301 |
1323 |
return pos->value().ok();
|
1302 |
1324 |
}
|
1303 |
1325 |
|
|
1326 |
bool convertStringCharset(std::string &str, const char* from, const char* to)
|
|
1327 |
{
|
|
1328 |
if (std::string(from) == to) return true; // nothing to do
|
|
1329 |
#if defined EXV_HAVE_ICONV
|
|
1330 |
bool ret = true;
|
|
1331 |
iconv_t cd;
|
|
1332 |
cd = iconv_open(to, from);
|
|
1333 |
if (cd == (iconv_t)(-1)) {
|
|
1334 |
#ifndef SUPPRESS_WARNINGS
|
|
1335 |
std::cerr << "Warning: iconv_open: " << Exiv2::strError() << "\n";
|
|
1336 |
#endif
|
|
1337 |
return false;
|
|
1338 |
}
|
|
1339 |
std::string outstr;
|
|
1340 |
char *inptr = const_cast<char *>(str.c_str());
|
|
1341 |
size_t inbytesleft = str.length();
|
|
1342 |
|
|
1343 |
while (inbytesleft) {
|
|
1344 |
char outbuf[100];
|
|
1345 |
char *outptr = outbuf;
|
|
1346 |
size_t outbytesleft = sizeof(outbuf) - 1;
|
|
1347 |
size_t rc = iconv(cd,
|
|
1348 |
&inptr,
|
|
1349 |
&inbytesleft,
|
|
1350 |
&outptr,
|
|
1351 |
&outbytesleft);
|
|
1352 |
if (rc == size_t(-1) && errno != E2BIG) {
|
|
1353 |
#ifndef SUPPRESS_WARNINGS
|
|
1354 |
std::cerr << "Warning: iconv: "
|
|
1355 |
<< Exiv2::strError()
|
|
1356 |
<< " inbytesleft = " << inbytesleft << "\n";
|
|
1357 |
#endif
|
|
1358 |
ret = false;
|
|
1359 |
break;
|
|
1360 |
}
|
|
1361 |
*outptr = '\0';
|
|
1362 |
outstr.append(outbuf);
|
|
1363 |
}
|
|
1364 |
if (cd != (iconv_t)(-1)) {
|
|
1365 |
iconv_close(cd);
|
|
1366 |
}
|
|
1367 |
|
|
1368 |
if (ret) str = outstr;
|
|
1369 |
return ret;
|
|
1370 |
#else // !EXV_HAVE_ICONV
|
|
1371 |
return false;
|
|
1372 |
#endif // EXV_HAVE_ICONV
|
|
1373 |
}
|
|
1374 |
|
1304 |
1375 |
}
|