#include <exiv2/exiv2.hpp>
#include "metacopy.hpp"
int main(int argc, char* const argv[]) {
try {
Params params;
if (params.getopt(argc, argv)) {
params.usage();
return 1;
}
if (params.help_) {
params.help();
return 2;
}
Exiv2::FileIo fileIo(params.read_);
auto memIo = std::make_unique<Exiv2::MemIo>();
memIo->transfer(fileIo);
readImg->readMetadata();
if (params.preserve_) {
writeImg->readMetadata();
}
if (params.iptc_) {
writeImg->setIptcData(readImg->iptcData());
}
if (params.exif_) {
writeImg->setExifData(readImg->exifData());
}
if (params.comment_) {
writeImg->setComment(readImg->comment());
}
if (params.xmp_) {
writeImg->setXmpData(readImg->xmpData());
}
try {
writeImg->writeMetadata();
std::cerr << params.progname() << ": Could not write metadata to (" << params.write_ << ")\n";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
std::cerr << "Caught Exiv2 exception '" << e << "'\n";
return EXIT_FAILURE;
}
}
int Params::option(int opt, const std::string& , int optopt) {
int rc = 0;
switch (opt) {
case 'h': {
help_ = true;
break;
}
case 'i': {
iptc_ = true;
break;
}
case 'e': {
exif_ = true;
break;
}
case 'c': {
comment_ = true;
break;
}
case 'x': {
xmp_ = true;
break;
}
case 'p': {
preserve_ = true;
break;
}
case 'a': {
iptc_ = true;
exif_ = true;
comment_ = true;
xmp_ = true;
break;
}
case ':': {
std::cerr << progname() << ": Option -" << static_cast<char>(optopt) << " requires an argument\n";
rc = 1;
break;
}
case '?': {
std::cerr << progname() << ": Unrecognized option -" << static_cast<char>(optopt) << "\n";
rc = 1;
break;
}
default: {
std::cerr << progname() << ": getopt returned unexpected character code " << std::hex << opt << "\n";
rc = 1;
break;
}
}
return rc;
}
int Params::nonoption(const std::string& argv) {
if (!write_.empty()) {
std::cerr << progname() << ": Unexpected extra argument (" << argv << ")\n";
return 1;
}
if (first_)
read_ = argv;
else
write_ = argv;
first_ = false;
return 0;
}
int Params::getopt(int argc, char* const argv[]) {
int rc = Util::Getopt::getopt(argc, argv, optstring_);
if (!help_) {
if (rc == 0 && read_.empty()) {
std::cerr << progname() << ": Read and write files must be specified\n";
rc = 1;
}
if (rc == 0 && write_.empty()) {
std::cerr << progname() << ": Write file must be specified\n";
rc = 1;
}
if (preserve_ && iptc_ && exif_ && comment_ && xmp_) {
std::cerr << progname() << ": Option -p has no effect when all metadata types are specified.\n";
rc = 1;
}
}
return rc;
}
void Params::usage(std::ostream& os) const {
os << "\nReads and writes raw metadata. Use -h option for help.\n"
<< "Usage: " << progname() << " [-iecxaph] readfile writefile\n";
}
void Params::help(std::ostream& os) const {
usage(os);
os << "\nOptions:\n"
<< " -i Read Iptc data from readfile and write to writefile.\n"
<< " -e Read Exif data from readfile and write to writefile.\n"
<< " -c Read Jpeg comment from readfile and write to writefile.\n"
<< " -x Read XMP data from readfile and write to writefile.\n"
<< " -a Read all metadata from readfile and write to writefile.\n"
<< " -p Preserve existing metadata in writefile if not replaced.\n"
<< " -h Display this help and exit.\n\n";
}
Simple error class used for exceptions. An output operator is provided to print errors to a stream.
Definition: error.hpp:235
static Image::UniquePtr open(const std::string &path, bool useCurl=true)
Create an Image subclass of the appropriate type by reading the specified file. Image type is derived...
static void terminate()
Terminate the XMP Toolkit and unregister custom namespaces.
static bool initialize(XmpParser::XmpLockFct xmpLockFct=nullptr, void *pLockData=nullptr)
Initialize the XMP Toolkit.