| 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 |
}
|