Added -g option to exiv2 utility to 'grep' info for individual tags.

v0.27.3
Andreas Huggel 16 years ago
parent 6d1da85d63
commit f01c919e14

@ -496,7 +496,6 @@ namespace Action {
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();
bool const manyFiles = Params::instance().files_.size() > 1;
// Set defaults for metadata types and data columns // Set defaults for metadata types and data columns
if (Params::instance().printTags_ == Exiv2::mdNone) { if (Params::instance().printTags_ == Exiv2::mdNone) {
Params::instance().printTags_ = Exiv2::mdExif | Exiv2::mdIptc | Exiv2::mdXmp; Params::instance().printTags_ = Exiv2::mdExif | Exiv2::mdIptc | Exiv2::mdXmp;
@ -504,11 +503,79 @@ namespace Action {
if (Params::instance().printItems_ == 0) { if (Params::instance().printItems_ == 0) {
Params::instance().printItems_ = Params::prKey | Params::prType | Params::prCount | Params::prTrans; Params::instance().printItems_ = Params::prKey | Params::prType | Params::prCount | Params::prTrans;
} }
if (!Params::instance().keys_.empty()) {
for (Params::Keys::const_iterator key = Params::instance().keys_.begin();
key != Params::instance().keys_.end(); ++key) {
rc |= grepTag(*key, image.get());
}
}
else {
rc = printMetadata(image.get());
}
return rc;
} // Print::printList
int Print::grepTag(const std::string& key, const Exiv2::Image* image)
{
int rc = 0;
if (key.empty()) return rc;
switch (key[0]) {
case 'E':
if (Params::instance().printTags_ & Exiv2::mdExif) { if (Params::instance().printTags_ & Exiv2::mdExif) {
Exiv2::ExifData& exifData = image->exifData(); Exiv2::ExifKey ek(key);
const Exiv2::ExifData& exifData = image->exifData();
Exiv2::ExifData::const_iterator md = exifData.findKey(ek);
if (md != exifData.end()) printMetadatum(*md, image);
if (exifData.empty()) {
if (Params::instance().verbose_) {
std::cerr << path_ << ": " << _("No Exif data found in the file\n");
}
rc = -3;
}
}
break;
case 'I':
if (Params::instance().printTags_ & Exiv2::mdIptc) {
Exiv2::IptcKey ik(key);
const Exiv2::IptcData& iptcData = image->iptcData();
Exiv2::IptcData::const_iterator md = iptcData.findKey(ik);
if (md != iptcData.end()) printMetadatum(*md, image);
if (iptcData.empty()) {
if (Params::instance().verbose_) {
std::cerr << path_ << ": " << _("No IPTC data found in the file\n");
}
rc = -3;
}
}
break;
case 'X':
if (Params::instance().printTags_ & Exiv2::mdXmp) {
Exiv2::XmpKey xk(key);
const Exiv2::XmpData& xmpData = image->xmpData();
Exiv2::XmpData::const_iterator md = xmpData.findKey(xk);
if (md != xmpData.end()) printMetadatum(*md, image);
if (xmpData.empty()) {
if (Params::instance().verbose_) {
std::cerr << path_ << ": " << _("No XMP data found in the file\n");
}
rc = -3;
}
}
break;
default:
throw Exiv2::Error(1, std::string(_("Invalid key")) + " `" + key + "'");
}
return rc;
} // Print::grepTag
int Print::printMetadata(const Exiv2::Image* image)
{
int rc = 0;
if (Params::instance().printTags_ & Exiv2::mdExif) {
const Exiv2::ExifData& exifData = image->exifData();
for (Exiv2::ExifData::const_iterator md = exifData.begin(); for (Exiv2::ExifData::const_iterator md = exifData.begin();
md != exifData.end(); ++md) { md != exifData.end(); ++md) {
printMetadatum(*md, image.get(), manyFiles); printMetadatum(*md, image);
} }
if (exifData.empty()) { if (exifData.empty()) {
if (Params::instance().verbose_) { if (Params::instance().verbose_) {
@ -518,10 +585,10 @@ namespace Action {
} }
} }
if (Params::instance().printTags_ & Exiv2::mdIptc) { if (Params::instance().printTags_ & Exiv2::mdIptc) {
Exiv2::IptcData& iptcData = image->iptcData(); const Exiv2::IptcData& iptcData = image->iptcData();
for (Exiv2::IptcData::const_iterator md = iptcData.begin(); for (Exiv2::IptcData::const_iterator md = iptcData.begin();
md != iptcData.end(); ++md) { md != iptcData.end(); ++md) {
printMetadatum(*md, image.get(), manyFiles); printMetadatum(*md, image);
} }
if (iptcData.empty()) { if (iptcData.empty()) {
if (Params::instance().verbose_) { if (Params::instance().verbose_) {
@ -531,10 +598,10 @@ namespace Action {
} }
} }
if (Params::instance().printTags_ & Exiv2::mdXmp) { if (Params::instance().printTags_ & Exiv2::mdXmp) {
Exiv2::XmpData& xmpData = image->xmpData(); const Exiv2::XmpData& xmpData = image->xmpData();
for (Exiv2::XmpData::const_iterator md = xmpData.begin(); for (Exiv2::XmpData::const_iterator md = xmpData.begin();
md != xmpData.end(); ++md) { md != xmpData.end(); ++md) {
printMetadatum(*md, image.get(), manyFiles); printMetadatum(*md, image);
} }
if (xmpData.empty()) { if (xmpData.empty()) {
if (Params::instance().verbose_) { if (Params::instance().verbose_) {
@ -544,16 +611,15 @@ namespace Action {
} }
} }
return rc; return rc;
} // Print::printList } // Print::printMetadata
void Print::printMetadatum(const Exiv2::Metadatum& md, void Print::printMetadatum(const Exiv2::Metadatum& md, const Exiv2::Image* pImage)
const Exiv2::Image* pImage,
bool const manyFiles)
{ {
if ( Params::instance().unknown_ if ( Params::instance().unknown_
&& md.tagName().substr(0, 2) == "0x") { && md.tagName().substr(0, 2) == "0x") {
return; return;
} }
bool const manyFiles = Params::instance().files_.size() > 1;
if (manyFiles) { if (manyFiles) {
std::cout << std::setfill(' ') << std::left << std::setw(20) std::cout << std::setfill(' ') << std::left << std::setw(20)
<< path_ << " "; << path_ << " ";

@ -61,7 +61,7 @@ namespace Action {
//! Enumerates all tasks //! Enumerates all tasks
enum TaskType { none, adjust, print, rename, erase, extract, insert, enum TaskType { none, adjust, print, rename, erase, extract, insert,
modify, fixiso }; modify, fixiso, fixcom };
// ***************************************************************************** // *****************************************************************************
// class definitions // class definitions
@ -170,10 +170,12 @@ namespace Action {
int printSummary(); int printSummary();
//! Print Exif, IPTC and XMP metadata in user defined format //! Print Exif, IPTC and XMP metadata in user defined format
int printList(); int printList();
//! Print info for an individual tag specified by its key in a user defined format
int grepTag(const std::string& key, const Exiv2::Image* image);
//! Print all metadata in a user defined format
int printMetadata(const Exiv2::Image* image);
//! Print a metadatum in a user defined format //! Print a metadatum in a user defined format
void printMetadatum(const Exiv2::Metadatum& md, void printMetadatum(const Exiv2::Metadatum& md, const Exiv2::Image* image);
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;
/*! /*!

@ -250,12 +250,16 @@ void Params::help(std::ostream& os) const
" Requires option -c, -m or -M.\n") " Requires option -c, -m or -M.\n")
<< _(" fi | fixiso Copy ISO setting from the Nikon Makernote to the regular\n" << _(" fi | fixiso Copy ISO setting from the Nikon Makernote to the regular\n"
" Exif tag.\n") " Exif tag.\n")
<< _(" fc | fixcom Convert the UNICODE Exif user comment to UCS-2. Its current\n"
" character encoding can be specified with the -n option.\n")
<< _("\nOptions:\n") << _("\nOptions:\n")
<< _(" -h Display this help and exit.\n") << _(" -h Display this help and exit.\n")
<< _(" -V Show the program version and exit.\n") << _(" -V Show the program version and exit.\n")
<< _(" -v Be verbose during the program run.\n") << _(" -v Be verbose during the program run.\n")
<< _(" -b Show large binary values.\n") << _(" -b Show large binary values.\n")
<< _(" -u Show unknown tags.\n") << _(" -u Show unknown tags.\n")
<< _(" -g key Only output info for this key (grep).\n")
<< _(" -n enc Charset to use to decode UNICODE Exif user comments.\n")
<< _(" -k Preserve file timestamps (keep).\n") << _(" -k Preserve file timestamps (keep).\n")
<< _(" -t Also set the file timestamp in 'rename' action (overrides -k).\n") << _(" -t Also set the file timestamp in 'rename' action (overrides -k).\n")
<< _(" -T Only set the file timestamp in 'rename' action, do not rename\n" << _(" -T Only set the file timestamp in 'rename' action, do not rename\n"
@ -337,6 +341,8 @@ int Params::option(int opt, const std::string& optarg, int optopt)
case 'u': unknown_ = false; break; case 'u': unknown_ = false; break;
case 'f': force_ = true; fileExistsPolicy_ = overwritePolicy; break; case 'f': force_ = true; fileExistsPolicy_ = overwritePolicy; break;
case 'F': force_ = true; fileExistsPolicy_ = renamePolicy; break; case 'F': force_ = true; fileExistsPolicy_ = renamePolicy; break;
case 'g': keys_.push_back(optarg); printMode_ = pmList; break;
case 'n': charset_ = optarg; break;
case 'r': rc = evalRename(opt, optarg); break; case 'r': rc = evalRename(opt, optarg); break;
case 't': rc = evalRename(opt, optarg); break; case 't': rc = evalRename(opt, optarg); break;
case 'T': rc = evalRename(opt, optarg); break; case 'T': rc = evalRename(opt, optarg); break;
@ -738,6 +744,15 @@ int Params::nonoption(const std::string& argv)
action = true; action = true;
action_ = Action::fixiso; action_ = Action::fixiso;
} }
if (argv == "fc" || argv == "fixcom") {
if (action_ != Action::none && action_ != Action::fixcom) {
std::cerr << progname() << ": "
<< _("Action fixcom is not compatible with the given options\n");
rc = 1;
}
action = true;
action_ = Action::fixcom;
}
if (action_ == Action::none) { if (action_ == Action::none) {
// if everything else fails, assume print as the default action // if everything else fails, assume print as the default action
action_ = Action::print; action_ = Action::print;

@ -116,6 +116,8 @@ public:
typedef std::vector<std::string> Files; typedef std::vector<std::string> Files;
//! Container for preview image numbers //! Container for preview image numbers
typedef std::set<int> PreviewNumbers; typedef std::set<int> PreviewNumbers;
//! Container for keys
typedef std::vector<std::string> Keys;
/*! /*!
@brief Controls all access to the global Params instance. @brief Controls all access to the global Params instance.
@ -202,6 +204,8 @@ public:
std::string suffix_; //!< File extension of the file to insert std::string suffix_; //!< File extension of the file to insert
Files files_; //!< List of non-option arguments. Files files_; //!< List of non-option arguments.
PreviewNumbers previewNumbers_; //!< List of preview numbers PreviewNumbers previewNumbers_; //!< List of preview numbers
Keys keys_; //!< List of keys to 'grep' from the metadata
std::string charset_; //!< Charset to use for UNICODE Exif user comment
private: private:
//! Pointer to the global Params object. //! Pointer to the global Params object.
@ -216,7 +220,7 @@ private:
@brief Default constructor. Note that optstring_ is initialized here. @brief Default constructor. Note that optstring_ is initialized here.
The c'tor is private to force instantiation through instance(). The c'tor is private to force instantiation through instance().
*/ */
Params() : optstring_(":hVvfbuktTFa:Y:O:D:r:p:P:d:e:i:c:m:M:l:S:"), Params() : optstring_(":hVvfbuktTFa:Y:O:D:r:p:P:d:e:i:c:m:M:l:S:g:n:"),
help_(false), help_(false),
version_(false), version_(false),
verbose_(false), verbose_(false),

Loading…
Cancel
Save