* Consolidated exiv2 tool print code

* Added option to print all metadata (-pa)
* Added control for type of metadata printed with -P
* API change, class Metadatum and derived classes: Added familyName() and groupName() to the Metadatum API
v0.27.3
Andreas Huggel 17 years ago
parent 62d2c0227b
commit f90d554489

@ -224,12 +224,10 @@ namespace Action {
path_ = path; path_ = path;
int rc = 0; int rc = 0;
switch (Params::instance().printMode_) { switch (Params::instance().printMode_) {
case Params::pmSummary: rc = printSummary(); break; case Params::pmSummary: rc = printSummary(); break;
case Params::pmList: rc = printList(); break; case Params::pmList: rc = printList(); break;
case Params::pmIptc: rc = printIptc(); break; case Params::pmComment: rc = printComment(); break;
case Params::pmXmp: rc = printXmp(); break; case Params::pmPreview: rc = printPreviewList(); break;
case Params::pmComment: rc = printComment(); break;
case Params::pmPreview: rc = printPreviewList(); break;
} }
return rc; return rc;
} }
@ -628,207 +626,174 @@ namespace Action {
int Print::printList() int Print::printList()
{ {
int rc = 0;
if (!Exiv2::fileExists(path_, true)) { if (!Exiv2::fileExists(path_, true)) {
std::cerr << path_ std::cerr << path_
<< ": " << _("Failed to open the file\n"); << ": " << _("Failed to open the file\n");
return -1; rc = -1;
} }
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path_); Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path_);
assert(image.get() != 0); assert(image.get() != 0);
image->readMetadata(); image->readMetadata();
Exiv2::ExifData& exifData = image->exifData();
if (exifData.empty()) {
std::cerr << path_
<< ": " << _("No Exif data found in the file\n");
return -3;
}
Exiv2::ExifData::const_iterator md;
bool const manyFiles = Params::instance().files_.size() > 1; bool const manyFiles = Params::instance().files_.size() > 1;
for (md = exifData.begin(); md != exifData.end(); ++md) { // Set defaults for metadata types and data columns
if ( Params::instance().unknown_ if (Params::instance().printTags_ == Exiv2::mdNone) {
&& md->tagName().substr(0, 2) == "0x") { Params::instance().printTags_ = Exiv2::mdExif | Exiv2::mdIptc | Exiv2::mdXmp;
continue; }
} if (Params::instance().printItems_ == 0) {
if (manyFiles) { Params::instance().printItems_ = Params::prKey | Params::prType | Params::prCount | Params::prTrans;
std::cout << std::setfill(' ') << std::left << std::setw(20) }
<< path_ << " "; if (Params::instance().printTags_ & Exiv2::mdExif) {
} Exiv2::ExifData& exifData = image->exifData();
bool first = true; for (Exiv2::ExifData::const_iterator md = exifData.begin();
if (Params::instance().printItems_ & Params::prTag) { md != exifData.end(); ++md) {
if (!first) std::cout << " "; printMetadatum(*md, image.get(), manyFiles);
first = false;
std::cout << "0x" << std::setw(4) << std::setfill('0')
<< std::right << std::hex
<< md->tag();
}
if (Params::instance().printItems_ & Params::prGroup) {
if (!first) std::cout << " ";
first = false;
std::cout << std::setw(12) << std::setfill(' ') << std::left
<< md->groupName();
}
if (Params::instance().printItems_ & Params::prKey) {
if (!first) std::cout << " ";
first = false;
std::cout << std::setfill(' ') << std::left << std::setw(44)
<< md->key();
}
if (Params::instance().printItems_ & Params::prName) {
if (!first) std::cout << " ";
first = false;
std::cout << std::setw(27) << std::setfill(' ') << std::left
<< md->tagName();
} }
if (Params::instance().printItems_ & Params::prLabel) { if (exifData.empty()) {
if (!first) std::cout << " "; if (Params::instance().verbose_) {
first = false; std::cerr << path_ << ": " << _("No Exif data found in the file\n");
std::cout << std::setw(30) << std::setfill(' ') << std::left
<< md->tagLabel();
}
if (Params::instance().printItems_ & Params::prType) {
if (!first) std::cout << " ";
first = false;
std::cout << std::setw(9) << std::setfill(' ') << std::left;
const char* tn = md->typeName();
if (tn) {
std::cout << tn;
}
else {
std::ostringstream os;
os << "0x" << std::setw(4) << std::setfill('0') << std::hex << md->typeId();
std::cout << os.str();
} }
rc = -3;
} }
if (Params::instance().printItems_ & Params::prCount) { }
if (!first) std::cout << " "; if (Params::instance().printTags_ & Exiv2::mdIptc) {
first = false; Exiv2::IptcData& iptcData = image->iptcData();
std::cout << std::dec << std::setw(3) for (Exiv2::IptcData::const_iterator md = iptcData.begin();
<< std::setfill(' ') << std::right md != iptcData.end(); ++md) {
<< md->count(); printMetadatum(*md, image.get(), manyFiles);
}
if (Params::instance().printItems_ & Params::prSize) {
if (!first) std::cout << " ";
first = false;
std::cout << std::dec << std::setw(3)
<< std::setfill(' ') << std::right
<< md->size();
} }
if (Params::instance().printItems_ & Params::prValue) { if (iptcData.empty()) {
if (!first) std::cout << " "; if (Params::instance().verbose_) {
first = false; std::cerr << path_ << ": " << _("No IPTC data found in the file\n");
if ( Params::instance().binary_
&& md->typeId() == Exiv2::undefined
&& md->size() > 100) {
std::cout << _("(Binary value suppressed)") << std::endl;
continue;
} }
std::cout << std::dec << md->value(); rc = -3;
} }
if (Params::instance().printItems_ & Params::prTrans) { }
if (!first) std::cout << " "; if (Params::instance().printTags_ & Exiv2::mdXmp) {
first = false; Exiv2::XmpData& xmpData = image->xmpData();
if ( Params::instance().binary_ for (Exiv2::XmpData::const_iterator md = xmpData.begin();
&& md->typeId() == Exiv2::undefined md != xmpData.end(); ++md) {
&& md->size() > 100) { printMetadatum(*md, image.get(), manyFiles);
std::cout << _("(Binary value suppressed)") << std::endl;
continue;
}
std::cout << std::dec << md->print(&exifData);
} }
if (Params::instance().printItems_ & Params::prHex) { if (xmpData.empty()) {
if (!first) std::cout << std::endl; if (Params::instance().verbose_) {
first = false; std::cerr << path_ << ": " << _("No XMP data found in the file\n");
if ( Params::instance().binary_
&& md->typeId() == Exiv2::undefined
&& md->size() > 100) {
std::cout << _("(Binary value suppressed)") << std::endl;
continue;
} }
Exiv2::DataBuf buf(md->size()); rc = -3;
md->copy(buf.pData_, image->byteOrder());
Exiv2::hexdump(std::cout, buf.pData_, buf.size_);
} }
std::cout << std::endl;
} }
return rc;
return 0;
} // Print::printList } // Print::printList
int Print::printIptc() void Print::printMetadatum(const Exiv2::Metadatum& md,
{ const Exiv2::Image* pImage,
if (!Exiv2::fileExists(path_, true)) { bool const manyFiles)
std::cerr << path_ {
<< ": " << _("Failed to open the file\n"); if ( Params::instance().unknown_
return -1; && md.tagName().substr(0, 2) == "0x") {
} return;
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path_); }
assert(image.get() != 0); if (manyFiles) {
image->readMetadata(); std::cout << std::setfill(' ') << std::left << std::setw(20)
Exiv2::IptcData& iptcData = image->iptcData(); << path_ << " ";
if (iptcData.empty()) { }
std::cerr << path_ bool first = true;
<< ": " << _("No IPTC data found in the file\n"); if (Params::instance().printItems_ & Params::prTag) {
return -3; if (!first) std::cout << " ";
} first = false;
Exiv2::IptcData::const_iterator end = iptcData.end(); std::cout << "0x" << std::setw(4) << std::setfill('0')
Exiv2::IptcData::const_iterator md; << std::right << std::hex
bool const manyFiles = Params::instance().files_.size() > 1; << md.tag();
for (md = iptcData.begin(); md != end; ++md) { }
std::cout << std::setfill(' ') << std::left; if (Params::instance().printItems_ & Params::prGroup) {
if (manyFiles) { if (!first) std::cout << " ";
std::cout << std::setw(20) << path_ << " "; first = false;
std::cout << std::setw(12) << std::setfill(' ') << std::left
<< md.groupName();
}
if (Params::instance().printItems_ & Params::prKey) {
if (!first) std::cout << " ";
first = false;
std::cout << std::setfill(' ') << std::left << std::setw(44)
<< md.key();
}
if (Params::instance().printItems_ & Params::prName) {
if (!first) std::cout << " ";
first = false;
std::cout << std::setw(27) << std::setfill(' ') << std::left
<< md.tagName();
}
if (Params::instance().printItems_ & Params::prLabel) {
if (!first) std::cout << " ";
first = false;
std::cout << std::setw(30) << std::setfill(' ') << std::left
<< md.tagLabel();
}
if (Params::instance().printItems_ & Params::prType) {
if (!first) std::cout << " ";
first = false;
std::cout << std::setw(9) << std::setfill(' ') << std::left;
const char* tn = md.typeName();
if (tn) {
std::cout << tn;
}
else {
std::ostringstream os;
os << "0x" << std::setw(4) << std::setfill('0') << std::hex << md.typeId();
std::cout << os.str();
} }
std::cout << std::setw(44)
<< md->key() << " "
<< std::setw(9) << std::setfill(' ') << std::left
<< md->typeName() << " "
<< std::dec << std::setw(3)
<< std::setfill(' ') << std::right
<< md->count() << " "
<< std::dec << md->value()
<< std::endl;
}
return 0;
} // Print::printIptc
int Print::printXmp()
{
if (!Exiv2::fileExists(path_, true)) {
std::cerr << path_
<< ": " << _("Failed to open the file\n");
return -1;
} }
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(path_); if (Params::instance().printItems_ & Params::prCount) {
assert(image.get() != 0); if (!first) std::cout << " ";
image->readMetadata(); first = false;
Exiv2::XmpData& xmpData = image->xmpData(); std::cout << std::dec << std::setw(3)
if (xmpData.empty()) { << std::setfill(' ') << std::right
std::cerr << path_ << md.count();
<< ": " << _("No XMP data found in the file\n");
return -3;
} }
Exiv2::XmpData::const_iterator end = xmpData.end(); if (Params::instance().printItems_ & Params::prSize) {
Exiv2::XmpData::const_iterator md; if (!first) std::cout << " ";
bool const manyFiles = Params::instance().files_.size() > 1; first = false;
for (md = xmpData.begin(); md != end; ++md) { std::cout << std::dec << std::setw(3)
std::cout << std::setfill(' ') << std::left;
if (manyFiles) {
std::cout << std::setw(20) << path_ << " ";
}
std::cout << std::setw(44)
<< md->key() << " "
<< std::setw(9) << std::setfill(' ') << std::left
<< md->typeName() << " "
<< std::dec << std::setw(3)
<< std::setfill(' ') << std::right << std::setfill(' ') << std::right
<< md->count() << " " << md.size();
<< std::dec << *md }
<< std::endl; if (Params::instance().printItems_ & Params::prValue) {
if (!first) std::cout << " ";
first = false;
if ( Params::instance().binary_
&& md.typeId() == Exiv2::undefined
&& md.size() > 100) {
std::cout << _("(Binary value suppressed)") << std::endl;
return;
}
std::cout << std::dec << md.value();
}
if (Params::instance().printItems_ & Params::prTrans) {
if (!first) std::cout << " ";
first = false;
if ( Params::instance().binary_
&& md.typeId() == Exiv2::undefined
&& md.size() > 100) {
std::cout << _("(Binary value suppressed)") << std::endl;
return;
}
std::cout << std::dec << md.print(&pImage->exifData());
}
if (Params::instance().printItems_ & Params::prHex) {
if (!first) std::cout << std::endl;
first = false;
if ( Params::instance().binary_
&& md.typeId() == Exiv2::undefined
&& md.size() > 100) {
std::cout << _("(Binary value suppressed)") << std::endl;
return;
}
Exiv2::DataBuf buf(md.size());
md.copy(buf.pData_, pImage->byteOrder());
Exiv2::hexdump(std::cout, buf.pData_, buf.size_);
} }
std::cout << std::endl;
return 0; } // Print::printMetadatum
} // Print::printXmp
int Print::printComment() int Print::printComment()
{ {

@ -48,6 +48,7 @@
namespace Exiv2 { namespace Exiv2 {
class ExifData; class ExifData;
class Image; class Image;
class Metadatum;
class PreviewImage; class PreviewImage;
} }
@ -165,14 +166,14 @@ namespace Action {
int printComment(); int printComment();
//! Print list of available preview images //! Print list of available preview images
int printPreviewList(); int printPreviewList();
//! Print uninterpreted Iptc information
int printIptc();
//! print uninterpreted XMP information
int printXmp();
//! Print Exif summary information //! Print Exif summary information
int printSummary(); int printSummary();
//! Print the list of Exif data in user defined format //! Print Exif, IPTC and XMP metadata in user defined format
int printList(); int printList();
//! Print a metadatum in a user defined format
void printMetadatum(const Exiv2::Metadatum& md,
const Exiv2::Image* pImage,
bool const manyFiles);
//! Print the label for a summary line //! Print the label for a summary line
void printLabel(const std::string& label) const; void printLabel(const std::string& label) const;
/*! /*!

@ -158,6 +158,8 @@ namespace Exiv2 {
//! Return the key of the %Exifdatum. //! Return the key of the %Exifdatum.
std::string key() const std::string key() const
{ return key_.get() == 0 ? "" : key_->key(); } { return key_.get() == 0 ? "" : key_->key(); }
const char* familyName() const
{ return key_.get() == 0 ? "" : key_->familyName(); }
std::string groupName() const std::string groupName() const
{ return key_.get() == 0 ? "" : key_->groupName(); } { return key_.get() == 0 ? "" : key_->groupName(); }
std::string tagName() const std::string tagName() const

@ -3,7 +3,7 @@
.\" First parameter, NAME, should be all caps .\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1) .\" other parameters are allowed: see man(7), man(1)
.TH EXIV2 1 "Dec 7th, 2008" .TH EXIV2 1 "Dec 8th, 2008"
.\" Please adjust this date whenever revising the manpage. .\" Please adjust this date whenever revising the manpage.
.\" .\"
.\" Some roff macros, for reference: .\" Some roff macros, for reference:
@ -141,23 +141,32 @@ Print mode for the 'print' action. Possible modes are:
.br .br
s : print a summary of the Exif metadata (the default) s : print a summary of the Exif metadata (the default)
.br .br
t : interpreted (translated) Exif data (shortcut for -Pkyct) a : print Exif, IPTC and XMP metadata (shortcut for -Pkyct)
.br .br
v : plain Exif data values (shortcut for -Pxgnycv) t : interpreted (translated) Exif tags (-PEkyct)
.br .br
h : hexdump of the Exif data (shortcut for -Pxgnycsh) v : plain Exif tag values (-PExgnycv)
.br .br
i : IPTC data values h : hexdump of the Exif data (-PExgnycsh)
.br .br
x : XMP properties i : IPTC datasets (-PIkyct)
.br
x : XMP properties (-PXkyct)
.br .br
c : JPEG comment c : JPEG comment
.br .br
p : list available image previews, sorted by preview image size in pixels p : list available image previews, sorted by preview image size in pixels
.TP .TP
.B \-P \fIcols\fP .B \-P \fIflgs\fP
Print columns for the Exif taglist ('print' action), allows detailed Print flags for fine control of the tag list ('print' action). Allows
control of the print output. Valid are: control of the type of metadata as well as data columns included in
the print output. Valid flags are:
.br
E : include Exif tags in the list
.br
I : IPTC datasets
.br
X : XMP properties
.br .br
x : print a column with the tag value x : print a column with the tag value
.br .br

@ -263,14 +263,18 @@ void Params::help(std::ostream& os) const
<< _(" -D day Day adjustment with the 'adjust' action.\n") << _(" -D day Day adjustment with the 'adjust' action.\n")
<< _(" -p mode Print mode for the 'print' action. Possible modes are:\n") << _(" -p mode Print mode for the 'print' action. Possible modes are:\n")
<< _(" s : print a summary of the Exif metadata (the default)\n") << _(" s : print a summary of the Exif metadata (the default)\n")
<< _(" t : interpreted (translated) Exif data (shortcut for -Pkyct)\n") << _(" a : print Exif, IPTC and XMP metadata (shortcut for -Pkyct)\n")
<< _(" v : plain Exif data values (shortcut for -Pxgnycv)\n") << _(" t : interpreted (translated) Exif data (-PEkyct)\n")
<< _(" h : hexdump of the Exif data (shortcut for -Pxgnycsh)\n") << _(" v : plain Exif data values (-PExgnycv)\n")
<< _(" i : IPTC data values\n") << _(" h : hexdump of the Exif data (-PExgnycsh)\n")
<< _(" x : XMP properties\n") << _(" i : IPTC data values (-PIkyct)\n")
<< _(" x : XMP properties (-PXkyct)\n")
<< _(" c : JPEG comment\n") << _(" c : JPEG comment\n")
<< _(" p : list available previews\n") << _(" p : list available previews\n")
<< _(" -P cols Print columns for the Exif taglist ('print' action). Valid are:\n") << _(" -P flgs Print flags for fine control of tag lists ('print' action):\n")
<< _(" E : include Exif tags in the list\n")
<< _(" I : IPTC datasets\n")
<< _(" X : XMP properties\n")
<< _(" x : print a column with the tag value\n") << _(" x : print a column with the tag value\n")
<< _(" g : group name\n") << _(" g : group name\n")
<< _(" k : key\n") << _(" k : key\n")
@ -335,7 +339,7 @@ int Params::option(int opt, const std::string& optarg, int optopt)
case 'O': rc = evalYodAdjust(yodMonth, optarg); break; case 'O': rc = evalYodAdjust(yodMonth, optarg); break;
case 'D': rc = evalYodAdjust(yodDay, optarg); break; case 'D': rc = evalYodAdjust(yodDay, optarg); break;
case 'p': rc = evalPrint(optarg); break; case 'p': rc = evalPrint(optarg); break;
case 'P': rc = evalPrintCols(optarg); break; case 'P': rc = evalPrintFlags(optarg); break;
case 'd': rc = evalDelete(optarg); break; case 'd': rc = evalDelete(optarg); break;
case 'e': rc = evalExtract(optarg); break; case 'e': rc = evalExtract(optarg); break;
case 'i': rc = evalInsert(optarg); break; case 'i': rc = evalInsert(optarg); break;
@ -466,11 +470,12 @@ int Params::evalPrint(const std::string& optarg)
case Action::none: case Action::none:
switch (optarg[0]) { switch (optarg[0]) {
case 's': printMode_ = pmSummary; break; case 's': printMode_ = pmSummary; break;
case 't': rc = evalPrintCols("kyct"); break; case 'a': rc = evalPrintFlags("kyct"); break;
case 'v': rc = evalPrintCols("xgnycv"); break; case 't': rc = evalPrintFlags("Ekyct"); break;
case 'h': rc = evalPrintCols("xgnycsh"); break; case 'v': rc = evalPrintFlags("Exgnycv"); break;
case 'i': printMode_ = pmIptc; break; case 'h': rc = evalPrintFlags("Exgnycsh"); break;
case 'x': printMode_ = pmXmp; break; case 'i': rc = evalPrintFlags("Ikyct"); break;
case 'x': rc = evalPrintFlags("Xkyct"); break;
case 'c': printMode_ = pmComment; break; case 'c': printMode_ = pmComment; break;
case 'p': printMode_ = pmPreview; break; case 'p': printMode_ = pmPreview; break;
default: default:
@ -493,15 +498,18 @@ int Params::evalPrint(const std::string& optarg)
return rc; return rc;
} // Params::evalPrint } // Params::evalPrint
int Params::evalPrintCols(const std::string& optarg) int Params::evalPrintFlags(const std::string& optarg)
{ {
int rc = 0; int rc = 0;
printMode_ = pmList;
switch (action_) { switch (action_) {
case Action::none: case Action::none:
action_ = Action::print; action_ = Action::print;
printMode_ = pmList;
for (std::size_t i = 0; i < optarg.length(); ++i) { for (std::size_t i = 0; i < optarg.length(); ++i) {
switch (optarg[i]) { switch (optarg[i]) {
case 'E': printTags_ |= Exiv2::mdExif; break;
case 'I': printTags_ |= Exiv2::mdIptc; break;
case 'X': printTags_ |= Exiv2::mdXmp; break;
case 'x': printItems_ |= prTag; break; case 'x': printItems_ |= prTag; break;
case 'g': printItems_ |= prGroup; break; case 'g': printItems_ |= prGroup; break;
case 'k': printItems_ |= prKey; break; case 'k': printItems_ |= prKey; break;
@ -532,7 +540,7 @@ int Params::evalPrintCols(const std::string& optarg)
break; break;
} }
return rc; return rc;
} // Params::evalPrintCols } // Params::evalPrintFlags
int Params::evalDelete(const std::string& optarg) int Params::evalDelete(const std::string& optarg)
{ {

@ -126,9 +126,14 @@ public:
void cleanup(); void cleanup();
//! Enumerates print modes //! Enumerates print modes
enum PrintMode { pmSummary, pmList, pmIptc, pmXmp, pmComment, pmPreview }; enum PrintMode {
pmSummary,
pmList,
pmComment,
pmPreview
};
//! Individual items to print //! Individual items to print, bitmap
enum PrintItem { enum PrintItem {
prTag = 1, prTag = 1,
prGroup = 2, prGroup = 2,
@ -180,6 +185,7 @@ public:
bool adjust_; //!< Adjustment flag. bool adjust_; //!< Adjustment flag.
PrintMode printMode_; //!< Print mode. PrintMode printMode_; //!< Print mode.
unsigned long printItems_; //!< Print items. unsigned long printItems_; //!< Print items.
unsigned long printTags_; //!< Print tags (bitmap of MetadataId flags).
//! %Action (integer rather than TaskType to avoid dependency). //! %Action (integer rather than TaskType to avoid dependency).
int action_; int action_;
int target_; //!< What common target to process. int target_; //!< What common target to process.
@ -224,6 +230,7 @@ private:
adjust_(false), adjust_(false),
printMode_(pmSummary), printMode_(pmSummary),
printItems_(0), printItems_(0),
printTags_(Exiv2::mdNone),
action_(0), action_(0),
target_(ctExif|ctIptc|ctComment|ctXmp), target_(ctExif|ctIptc|ctComment|ctXmp),
adjustment_(0), adjustment_(0),
@ -245,7 +252,7 @@ private:
int evalAdjust(const std::string& optarg); int evalAdjust(const std::string& optarg);
int evalYodAdjust(const Yod& yod, const std::string& optarg); int evalYodAdjust(const Yod& yod, const std::string& optarg);
int evalPrint(const std::string& optarg); int evalPrint(const std::string& optarg);
int evalPrintCols(const std::string& optarg); int evalPrintFlags(const std::string& optarg);
int evalDelete(const std::string& optarg); int evalDelete(const std::string& optarg);
int evalExtract(const std::string& optarg); int evalExtract(const std::string& optarg);
int evalInsert(const std::string& optarg); int evalInsert(const std::string& optarg);

@ -124,7 +124,7 @@ namespace Exiv2 {
*/ */
std::string key() const { return key_.get() == 0 ? "" : key_->key(); } std::string key() const { return key_.get() == 0 ? "" : key_->key(); }
/*! /*!
@brief Return the name of the record @brief Return the name of the record (deprecated)
@return record name @return record name
*/ */
std::string recordName() const std::string recordName() const
@ -135,6 +135,10 @@ namespace Exiv2 {
*/ */
uint16_t record() const uint16_t record() const
{ return key_.get() == 0 ? 0 : key_->record(); } { return key_.get() == 0 ? 0 : key_->record(); }
const char* familyName() const
{ return key_.get() == 0 ? "" : key_->familyName(); }
std::string groupName() const
{ return key_.get() == 0 ? "" : key_->groupName(); }
/*! /*!
@brief Return the name of the tag (aka dataset) @brief Return the name of the tag (aka dataset)
@return tag name @return tag name

@ -203,11 +203,15 @@ namespace Exiv2 {
) const =0; ) const =0;
/*! /*!
@brief Return the key of the metadatum. The key is of the form @brief Return the key of the metadatum. The key is of the form
'familyName.ifdItem.tagName'. Note however that the key 'familyName.groupName.tagName'. Note however that the key
is not necessarily unique, i.e., an ExifData object may is not necessarily unique, e.g., an ExifData object may
contain multiple metadata with the same key. contain multiple metadata with the same key.
*/ */
virtual std::string key() const =0; virtual std::string key() const =0;
//! Return the name of the metadata family (which is also the first part of the key)
virtual const char* familyName() const =0;
//! Return the name of the metadata group (which is also the second part of the key)
virtual std::string groupName() const =0;
//! Return the name of the tag (which is also the third part of the key) //! Return the name of the tag (which is also the third part of the key)
virtual std::string tagName() const =0; virtual std::string tagName() const =0;
//! Return a label for the tag //! Return a label for the tag

@ -168,6 +168,11 @@ namespace Exiv2 {
return p_->key_.get() == 0 ? "" : p_->key_->key(); return p_->key_.get() == 0 ? "" : p_->key_->key();
} }
const char* Xmpdatum::familyName() const
{
return p_->key_.get() == 0 ? "" : p_->key_->familyName();
}
std::string Xmpdatum::groupName() const std::string Xmpdatum::groupName() const
{ {
return p_->key_.get() == 0 ? "" : p_->key_->groupName(); return p_->key_.get() == 0 ? "" : p_->key_->groupName();

@ -132,6 +132,7 @@ namespace Exiv2 {
contain multiple metadata with the same key. contain multiple metadata with the same key.
*/ */
std::string key() const; std::string key() const;
const char* familyName() const;
//! Return the (preferred) schema namespace prefix. //! Return the (preferred) schema namespace prefix.
std::string groupName() const; std::string groupName() const;
//! Return the property name. //! Return the property name.

@ -30,7 +30,7 @@ $exiv2 -M'set Exif.Image.ImageDescription The Exif image description' h.jpg
rm -f h.xmp rm -f h.xmp
$exiv2 -eX h.jpg $exiv2 -eX h.jpg
$exiv2 -px h.xmp $exiv2 -px h.xmp
$exiv2 -Pkycv h.xmp $exiv2 -PEkycv h.xmp
$exiv2 -pi h.xmp $exiv2 -pi h.xmp
# 2) Convert XMP x-default langAlt value back to Exif ImageDescription # 2) Convert XMP x-default langAlt value back to Exif ImageDescription
@ -41,7 +41,7 @@ echo ==========
\cp h.xmp i.xmp \cp h.xmp i.xmp
$exiv2 -iX i.jpg $exiv2 -iX i.jpg
$exiv2 -px i.jpg $exiv2 -px i.jpg
$exiv2 -Pkycv i.jpg $exiv2 -PEkycv i.jpg
$exiv2 -pi i.jpg $exiv2 -pi i.jpg
# 3) Convert XMP single non-x-default langAlt value to Exif ImageDescription # 3) Convert XMP single non-x-default langAlt value to Exif ImageDescription
@ -52,7 +52,7 @@ sed s/x-default/de-DE/ i.xmp > j.xmp
\cp $IMG j.jpg \cp $IMG j.jpg
$exiv2 -iX j.jpg $exiv2 -iX j.jpg
$exiv2 -px j.jpg $exiv2 -px j.jpg
$exiv2 -Pkycv j.jpg $exiv2 -PEkycv j.jpg
$exiv2 -pi j.jpg $exiv2 -pi j.jpg
# 4) This shouldn't work: No x-default, more than one language # 4) This shouldn't work: No x-default, more than one language
@ -63,8 +63,8 @@ sed 's,<rdf:li xml:lang="de-DE">The Exif image description</rdf:li>,<rdf:li xml:
\cp $IMG k.jpg \cp $IMG k.jpg
$exiv2 -iX k.jpg $exiv2 -iX k.jpg
$exiv2 -px k.jpg $exiv2 -px k.jpg
$exiv2 -Pkycv k.jpg $exiv2 -v -PEkycv k.jpg
$exiv2 -pi k.jpg $exiv2 -v -pi k.jpg
# 5) Add a default language to the XMP file and convert to Exif and IPTC # 5) Add a default language to the XMP file and convert to Exif and IPTC
echo echo
@ -76,7 +76,7 @@ grep x-default l.xmp
\cp $IMG l.jpg \cp $IMG l.jpg
$exiv2 -iX l.jpg $exiv2 -iX l.jpg
$exiv2 -px l.jpg $exiv2 -px l.jpg
$exiv2 -Pkycv l.jpg $exiv2 -PEkycv l.jpg
$exiv2 -pi l.jpg $exiv2 -pi l.jpg
# 6) Convert an Exif user comment to XMP # 6) Convert an Exif user comment to XMP
@ -85,12 +85,12 @@ echo Testcase 6
echo ========== echo ==========
\cp $IMG m.jpg \cp $IMG m.jpg
$exiv2 -M'set Exif.Photo.UserComment charset=Jis This is a JIS encoded Exif user comment. Or was it?' m.jpg $exiv2 -M'set Exif.Photo.UserComment charset=Jis This is a JIS encoded Exif user comment. Or was it?' m.jpg
$exiv2 -Pkycv m.jpg $exiv2 -PEkycv m.jpg
rm -f m.xmp rm -f m.xmp
$exiv2 -eX m.jpg $exiv2 -eX m.jpg
$exiv2 -px m.xmp $exiv2 -px m.xmp
$exiv2 -Pkycv m.xmp $exiv2 -PEkycv m.xmp
$exiv2 -pi m.xmp $exiv2 -v -pi m.xmp
# 7) And back to Exif # 7) And back to Exif
echo echo
@ -100,8 +100,8 @@ echo ==========
\cp m.xmp n.xmp \cp m.xmp n.xmp
$exiv2 -iX n.jpg $exiv2 -iX n.jpg
$exiv2 -px n.jpg $exiv2 -px n.jpg
$exiv2 -Pkycv n.jpg $exiv2 -PEkycv n.jpg
$exiv2 -pi n.jpg $exiv2 -v -pi n.jpg
# 8) Convert IPTC keywords to XMP # 8) Convert IPTC keywords to XMP
echo echo
@ -115,7 +115,7 @@ $exiv2 -pi o.jpg
rm -f o.xmp rm -f o.xmp
$exiv2 -eX o.jpg $exiv2 -eX o.jpg
$exiv2 -px o.xmp $exiv2 -px o.xmp
$exiv2 -Pkycv o.xmp $exiv2 -v -PEkycv o.xmp
$exiv2 -pi o.xmp $exiv2 -pi o.xmp
# 9) And back to IPTC # 9) And back to IPTC
@ -126,7 +126,7 @@ echo ==========
\cp o.xmp p.xmp \cp o.xmp p.xmp
$exiv2 -iX p.jpg $exiv2 -iX p.jpg
$exiv2 -px p.jpg $exiv2 -px p.jpg
$exiv2 -Pkycv p.jpg $exiv2 -v -PEkycv p.jpg
$exiv2 -pi p.jpg $exiv2 -pi p.jpg
# 10) Convert an Exif tag to an XMP text value # 10) Convert an Exif tag to an XMP text value
@ -135,12 +135,12 @@ echo Testcase 10
echo =========== echo ===========
\cp $IMG q.jpg \cp $IMG q.jpg
$exiv2 -M'set Exif.Image.Software Exiv2' q.jpg $exiv2 -M'set Exif.Image.Software Exiv2' q.jpg
$exiv2 -Pkycv q.jpg $exiv2 -PEkycv q.jpg
rm -f q.xmp rm -f q.xmp
$exiv2 -eX q.jpg $exiv2 -eX q.jpg
$exiv2 -px q.xmp $exiv2 -px q.xmp
$exiv2 -Pkycv q.xmp $exiv2 -PEkycv q.xmp
$exiv2 -pi q.xmp $exiv2 -v -pi q.xmp
# 11) And back to Exif # 11) And back to Exif
echo echo
@ -150,8 +150,8 @@ echo ===========
\cp q.xmp r.xmp \cp q.xmp r.xmp
$exiv2 -iX r.jpg $exiv2 -iX r.jpg
$exiv2 -px r.jpg $exiv2 -px r.jpg
$exiv2 -Pkycv r.jpg $exiv2 -PEkycv r.jpg
$exiv2 -pi r.jpg $exiv2 -v -pi r.jpg
# 12) Convert an IPTC dataset to an XMP text value # 12) Convert an IPTC dataset to an XMP text value
echo echo
@ -163,7 +163,7 @@ $exiv2 -pi s.jpg
rm -f s.xmp rm -f s.xmp
$exiv2 -eX s.jpg $exiv2 -eX s.jpg
$exiv2 -px s.xmp $exiv2 -px s.xmp
$exiv2 -Pkycv s.xmp $exiv2 -v -PEkycv s.xmp
$exiv2 -pi s.xmp $exiv2 -pi s.xmp
# 13) And back to IPTC # 13) And back to IPTC
@ -174,7 +174,7 @@ echo ===========
\cp s.xmp t.xmp \cp s.xmp t.xmp
$exiv2 -iX t.jpg $exiv2 -iX t.jpg
$exiv2 -px t.jpg $exiv2 -px t.jpg
$exiv2 -Pkycv t.jpg $exiv2 -v -PEkycv t.jpg
$exiv2 -pi t.jpg $exiv2 -pi t.jpg
# 10) Convert a few other tags of interest from Exif/Iptc to XMP # 10) Convert a few other tags of interest from Exif/Iptc to XMP
@ -193,12 +193,12 @@ $exiv2 -M'set Exif.GPSInfo.GPSVersionID 2 2 0 1' u.jpg
$exiv2 -M'set Exif.GPSInfo.GPSTimeStamp 1/1 2/1 999999999/1000000000' u.jpg $exiv2 -M'set Exif.GPSInfo.GPSTimeStamp 1/1 2/1 999999999/1000000000' u.jpg
$exiv2 -M'set Iptc.Application2.DateCreated 2007-05-09' u.jpg $exiv2 -M'set Iptc.Application2.DateCreated 2007-05-09' u.jpg
$exiv2 -Pkycv u.jpg $exiv2 -PEkycv u.jpg
$exiv2 -pi u.jpg $exiv2 -pi u.jpg
rm -f u.xmp rm -f u.xmp
$exiv2 -eX u.jpg $exiv2 -eX u.jpg
$exiv2 -px u.xmp $exiv2 -px u.xmp
$exiv2 -Pkycv u.xmp $exiv2 -PEkycv u.xmp
$exiv2 -pi u.xmp $exiv2 -pi u.xmp
# 15) And back to Exif/IPTC # 15) And back to Exif/IPTC
@ -210,7 +210,7 @@ echo ===========
$exiv2 -M'set Xmp.tiff.DateTime 2003-12-14T12:01:44Z' v.xmp $exiv2 -M'set Xmp.tiff.DateTime 2003-12-14T12:01:44Z' v.xmp
$exiv2 -iX v.jpg $exiv2 -iX v.jpg
$exiv2 -px v.jpg $exiv2 -px v.jpg
$exiv2 -Pkycv v.jpg $exiv2 -PEkycv v.jpg
$exiv2 -pi v.jpg $exiv2 -pi v.jpg
) > $results 2>&1 ) > $results 2>&1

@ -21,7 +21,9 @@ Testcase 4
Warning: Failed to convert Xmp.dc.description to Iptc.Application2.Caption Warning: Failed to convert Xmp.dc.description to Iptc.Application2.Caption
Warning: Failed to convert Xmp.dc.description to Exif.Image.ImageDescription Warning: Failed to convert Xmp.dc.description to Exif.Image.ImageDescription
Xmp.dc.description LangAlt 2 lang="de-DE" The Exif image description, lang="it-IT" Ciao bella Xmp.dc.description LangAlt 2 lang="de-DE" The Exif image description, lang="it-IT" Ciao bella
File 1/1: k.jpg
k.jpg: No Exif data found in the file k.jpg: No Exif data found in the file
File 1/1: k.jpg
k.jpg: No IPTC data found in the file k.jpg: No IPTC data found in the file
Testcase 5 Testcase 5
@ -39,6 +41,7 @@ Exif.Image.ExifTag Long 1 26
Exif.Photo.UserComment Undefined 59 charset="Jis" This is a JIS encoded Exif user comment. Or was it? Exif.Photo.UserComment Undefined 59 charset="Jis" This is a JIS encoded Exif user comment. Or was it?
Xmp.exif.UserComment LangAlt 1 lang="x-default" This is a JIS encoded Exif user comment. Or was it? Xmp.exif.UserComment LangAlt 1 lang="x-default" This is a JIS encoded Exif user comment. Or was it?
Exif.Photo.UserComment Undefined 59 charset="Unicode" This is a JIS encoded Exif user comment. Or was it? Exif.Photo.UserComment Undefined 59 charset="Unicode" This is a JIS encoded Exif user comment. Or was it?
File 1/1: m.xmp
m.xmp: No IPTC data found in the file m.xmp: No IPTC data found in the file
Testcase 7 Testcase 7
@ -46,6 +49,7 @@ Testcase 7
Xmp.exif.UserComment LangAlt 1 lang="x-default" This is a JIS encoded Exif user comment. Or was it? Xmp.exif.UserComment LangAlt 1 lang="x-default" This is a JIS encoded Exif user comment. Or was it?
Exif.Image.ExifTag Long 1 26 Exif.Image.ExifTag Long 1 26
Exif.Photo.UserComment Undefined 59 charset="Unicode" This is a JIS encoded Exif user comment. Or was it? Exif.Photo.UserComment Undefined 59 charset="Unicode" This is a JIS encoded Exif user comment. Or was it?
File 1/1: n.jpg
n.jpg: No IPTC data found in the file n.jpg: No IPTC data found in the file
Testcase 8 Testcase 8
@ -54,6 +58,7 @@ Iptc.Application2.Keywords String 3 Sex
Iptc.Application2.Keywords String 5 Drugs Iptc.Application2.Keywords String 5 Drugs
Iptc.Application2.Keywords String 11 Rock'n'roll Iptc.Application2.Keywords String 11 Rock'n'roll
Xmp.dc.subject XmpBag 3 Sex, Drugs, Rock'n'roll Xmp.dc.subject XmpBag 3 Sex, Drugs, Rock'n'roll
File 1/1: o.xmp
o.xmp: No Exif data found in the file o.xmp: No Exif data found in the file
Iptc.Application2.Keywords String 3 Sex Iptc.Application2.Keywords String 3 Sex
Iptc.Application2.Keywords String 5 Drugs Iptc.Application2.Keywords String 5 Drugs
@ -62,6 +67,7 @@ Iptc.Application2.Keywords String 11 Rock'n'roll
Testcase 9 Testcase 9
========== ==========
Xmp.dc.subject XmpBag 3 Sex, Drugs, Rock'n'roll Xmp.dc.subject XmpBag 3 Sex, Drugs, Rock'n'roll
File 1/1: p.jpg
p.jpg: No Exif data found in the file p.jpg: No Exif data found in the file
Iptc.Application2.Keywords String 3 Sex Iptc.Application2.Keywords String 3 Sex
Iptc.Application2.Keywords String 5 Drugs Iptc.Application2.Keywords String 5 Drugs
@ -72,24 +78,28 @@ Testcase 10
Exif.Image.Software Ascii 6 Exiv2 Exif.Image.Software Ascii 6 Exiv2
Xmp.tiff.Software XmpText 5 Exiv2 Xmp.tiff.Software XmpText 5 Exiv2
Exif.Image.Software Ascii 6 Exiv2 Exif.Image.Software Ascii 6 Exiv2
File 1/1: q.xmp
q.xmp: No IPTC data found in the file q.xmp: No IPTC data found in the file
Testcase 11 Testcase 11
=========== ===========
Xmp.tiff.Software XmpText 5 Exiv2 Xmp.tiff.Software XmpText 5 Exiv2
Exif.Image.Software Ascii 6 Exiv2 Exif.Image.Software Ascii 6 Exiv2
File 1/1: r.jpg
r.jpg: No IPTC data found in the file r.jpg: No IPTC data found in the file
Testcase 12 Testcase 12
=========== ===========
Iptc.Application2.LocationName String 12 Kuala Lumpur Iptc.Application2.LocationName String 12 Kuala Lumpur
Xmp.iptc.Location XmpText 12 Kuala Lumpur Xmp.iptc.Location XmpText 12 Kuala Lumpur
File 1/1: s.xmp
s.xmp: No Exif data found in the file s.xmp: No Exif data found in the file
Iptc.Application2.LocationName String 12 Kuala Lumpur Iptc.Application2.LocationName String 12 Kuala Lumpur
Testcase 13 Testcase 13
=========== ===========
Xmp.iptc.Location XmpText 12 Kuala Lumpur Xmp.iptc.Location XmpText 12 Kuala Lumpur
File 1/1: t.jpg
t.jpg: No Exif data found in the file t.jpg: No Exif data found in the file
Iptc.Application2.LocationName String 12 Kuala Lumpur Iptc.Application2.LocationName String 12 Kuala Lumpur

@ -62,14 +62,18 @@ Options:
-D day Day adjustment with the 'adjust' action. -D day Day adjustment with the 'adjust' action.
-p mode Print mode for the 'print' action. Possible modes are: -p mode Print mode for the 'print' action. Possible modes are:
s : print a summary of the Exif metadata (the default) s : print a summary of the Exif metadata (the default)
t : interpreted (translated) Exif data (shortcut for -Pkyct) a : print Exif, IPTC and XMP metadata (shortcut for -Pkyct)
v : plain Exif data values (shortcut for -Pxgnycv) t : interpreted (translated) Exif data (-PEkyct)
h : hexdump of the Exif data (shortcut for -Pxgnycsh) v : plain Exif data values (-PExgnycv)
i : IPTC data values h : hexdump of the Exif data (-PExgnycsh)
x : XMP properties i : IPTC data values (-PIkyct)
x : XMP properties (-PXkyct)
c : JPEG comment c : JPEG comment
p : list available previews p : list available previews
-P cols Print columns for the Exif taglist ('print' action). Valid are: -P flgs Print flags for fine control of tag lists ('print' action):
E : include Exif tags in the list
I : IPTC datasets
X : XMP properties
x : print a column with the tag value x : print a column with the tag value
g : group name g : group name
k : key k : key

Loading…
Cancel
Save