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_);
assert(image.get() != 0);
image->readMetadata();
bool const manyFiles = Params::instance().files_.size() > 1;
// Set defaults for metadata types and data columns
if (Params::instance().printTags_ == Exiv2::mdNone) {
Params::instance().printTags_ = Exiv2::mdExif | Exiv2::mdIptc | Exiv2::mdXmp;
@ -504,11 +503,79 @@ namespace Action {
if (Params::instance().printItems_ == 0) {
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) {
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();
md != exifData.end(); ++md) {
printMetadatum(*md, image.get(), manyFiles);
printMetadatum(*md, image);
}
if (exifData.empty()) {
if (Params::instance().verbose_) {
@ -518,10 +585,10 @@ namespace Action {
}
}
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();
md != iptcData.end(); ++md) {
printMetadatum(*md, image.get(), manyFiles);
printMetadatum(*md, image);
}
if (iptcData.empty()) {
if (Params::instance().verbose_) {
@ -531,10 +598,10 @@ namespace Action {
}
}
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();
md != xmpData.end(); ++md) {
printMetadatum(*md, image.get(), manyFiles);
printMetadatum(*md, image);
}
if (xmpData.empty()) {
if (Params::instance().verbose_) {
@ -544,16 +611,15 @@ namespace Action {
}
}
return rc;
} // Print::printList
} // Print::printMetadata
void Print::printMetadatum(const Exiv2::Metadatum& md,
const Exiv2::Image* pImage,
bool const manyFiles)
void Print::printMetadatum(const Exiv2::Metadatum& md, const Exiv2::Image* pImage)
{
if ( Params::instance().unknown_
&& md.tagName().substr(0, 2) == "0x") {
return;
}
bool const manyFiles = Params::instance().files_.size() > 1;
if (manyFiles) {
std::cout << std::setfill(' ') << std::left << std::setw(20)
<< path_ << " ";

@ -61,7 +61,7 @@ namespace Action {
//! Enumerates all tasks
enum TaskType { none, adjust, print, rename, erase, extract, insert,
modify, fixiso };
modify, fixiso, fixcom };
// *****************************************************************************
// class definitions
@ -170,10 +170,12 @@ namespace Action {
int printSummary();
//! Print Exif, IPTC and XMP metadata in user defined format
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
void printMetadatum(const Exiv2::Metadatum& md,
const Exiv2::Image* pImage,
bool const manyFiles);
void printMetadatum(const Exiv2::Metadatum& md, const Exiv2::Image* image);
//! Print the label for a summary line
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")
<< _(" fi | fixiso Copy ISO setting from the Nikon Makernote to the regular\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")
<< _(" -h Display this help and exit.\n")
<< _(" -V Show the program version and exit.\n")
<< _(" -v Be verbose during the program run.\n")
<< _(" -b Show large binary values.\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")
<< _(" -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"
@ -337,6 +341,8 @@ int Params::option(int opt, const std::string& optarg, int optopt)
case 'u': unknown_ = false; break;
case 'f': force_ = true; fileExistsPolicy_ = overwritePolicy; 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 '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_ = 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 everything else fails, assume print as the default action
action_ = Action::print;

@ -116,6 +116,8 @@ public:
typedef std::vector<std::string> Files;
//! Container for preview image numbers
typedef std::set<int> PreviewNumbers;
//! Container for keys
typedef std::vector<std::string> Keys;
/*!
@brief Controls all access to the global Params instance.
@ -202,6 +204,8 @@ public:
std::string suffix_; //!< File extension of the file to insert
Files files_; //!< List of non-option arguments.
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:
//! Pointer to the global Params object.
@ -216,7 +220,7 @@ private:
@brief Default constructor. Note that optstring_ is initialized here.
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),
version_(false),
verbose_(false),

Loading…
Cancel
Save