1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
// ***************************************************************** -*- C++ -*-
/*
Abstract : Sample program test the Iptc reading and writing.
This is not designed to be a robust application.
File : iptctest.cpp
Version : $Rev: 1271 $
Author(s): Brad Schick (brad) <brad@robotbattle.com>
History : 01-Aug-04, brad: created
*/
// *****************************************************************************
// included header files
#include <exiv2/image.hpp>
#include <exiv2/iptc.hpp>
#include <exiv2/datasets.hpp>
#include <exiv2/value.hpp>
#include <iostream>
#include <iomanip>
#include <cassert>
using namespace Exiv2;
bool processLine(const std::string& line, int num, IptcData &iptcData);
void processAdd(const std::string& line, int num, IptcData &iptcData);
void processRemove(const std::string& line, int num, IptcData &iptcData);
void processModify(const std::string& line, int num, IptcData &iptcData);
// *****************************************************************************
// Main
int main(int argc, char* const argv[])
{
try {
if (argc != 2) {
std::cout << "Usage: " << argv[0] << " image\n";
std::cout << "Commands read from stdin.\n";
return 1;
}
Image::AutoPtr image = ImageFactory::open(argv[1]);
assert (image.get() != 0);
image->readMetadata();
// Process commands
std::string line;
int num = 0;
std::getline(std::cin, line);
while (line.length() && processLine(line, ++num, image->iptcData())) {
std::getline(std::cin, line);
}
// Save any changes
image->writeMetadata();
return 0;
}
catch (AnyError& e) {
std::cout << "Caught Exiv2 exception '" << e << "'\n";
return -1;
}
}
bool processLine(const std::string& line, int num, IptcData &iptcData)
{
switch (line.at(0)) {
case 'a':
case 'A':
processAdd(line, num, iptcData);
break;
case 'r':
case 'R':
processRemove(line, num, iptcData);
break;
case 'm':
case 'M':
processModify(line, num, iptcData);
break;
case 'q':
case 'Q':
return false;
default:
std::ostringstream os;
os << "Unknown command (" << line.at(0) << ") at line " << num;
throw Error(1, os.str());
}
return true;
}
void processAdd(const std::string& line, int num, IptcData &iptcData)
{
std::string::size_type keyStart = line.find_first_not_of(" \t", 1);
std::string::size_type keyEnd = line.find_first_of(" \t", keyStart+1);
std::string::size_type dataStart = line.find_first_not_of(" \t", keyEnd+1);
if (keyStart == std::string::npos ||
keyEnd == std::string::npos ||
dataStart == std::string::npos) {
std::ostringstream os;
os << "Invalid \'a\' command at line " << num;
throw Error(1, os.str());
}
std::string key(line.substr(keyStart, keyEnd-keyStart));
IptcKey iptcKey(key);
std::string data(line.substr(dataStart));
// if data starts and ends with quotes, remove them
if (data.at(0) == '\"' && data.at(data.size()-1) == '\"') {
data = data.substr(1, data.size()-2);
}
TypeId type = IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record());
Value::AutoPtr value = Value::create(type);
value->read(data);
int rc = iptcData.add(iptcKey, value.get());
if (rc) {
throw Error(1, "Iptc dataset already exists and is not repeatable");
}
}
void processRemove(const std::string& line, int num, IptcData &iptcData)
{
std::string::size_type keyStart = line.find_first_not_of(" \t", 1);
if (keyStart == std::string::npos) {
std::ostringstream os;
os << "Invalid \'r\' command at line " << num;
throw Error(1, os.str());
}
const std::string key( line.substr(keyStart) );
IptcKey iptcKey(key);
IptcData::iterator iter = iptcData.findKey(iptcKey);
if (iter != iptcData.end()) {
iptcData.erase(iter);
}
}
void processModify(const std::string& line, int num, IptcData &iptcData)
{
std::string::size_type keyStart = line.find_first_not_of(" \t", 1);
std::string::size_type keyEnd = line.find_first_of(" \t", keyStart+1);
std::string::size_type dataStart = line.find_first_not_of(" \t", keyEnd+1);
if (keyStart == std::string::npos ||
keyEnd == std::string::npos ||
dataStart == std::string::npos) {
std::ostringstream os;
os << "Invalid \'m\' command at line " << num;
throw Error(1, os.str());
}
std::string key(line.substr(keyStart, keyEnd-keyStart));
IptcKey iptcKey(key);
std::string data(line.substr(dataStart));
// if data starts and ends with quotes, remove them
if (data.at(0) == '\"' && data.at(data.size()-1) == '\"') {
data = data.substr(1, data.size()-2);
}
TypeId type = IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record());
Value::AutoPtr value = Value::create(type);
value->read(data);
IptcData::iterator iter = iptcData.findKey(iptcKey);
if (iter != iptcData.end()) {
iter->setValue(value.get());
}
else {
int rc = iptcData.add(iptcKey, value.get());
if (rc) {
throw Error(1, "Iptc dataset already exists and is not repeatable");
}
}
}
|