Added delete targets for different types of metadata

Added insert thumbnail option
Various fixes
v0.27.3
Andreas Huggel 21 years ago
parent 10e7d7d86c
commit e99ecbd345

@ -676,16 +676,38 @@ namespace Action {
int Erase::run(const std::string& path) int Erase::run(const std::string& path)
try { try {
path_ = path; path_ = path;
Exiv2::ExifData exifData;
int rc = exifData.read(path); Exiv2::Image::AutoPtr image
= Exiv2::ImageFactory::instance().open(path_);
if (image.get() == 0) {
std::cerr << path_
<< ": The file contains data of an unknown image type\n";
return -2;
}
int rc = image->readMetadata();
if (rc) { if (rc) {
std::cerr << Exiv2::ExifData::strError(rc, path) << "\n"; std::cerr << Exiv2::ExifData::strError(rc, path_) << "\n";
return rc; }
// Thumbnail must be before Exif
if (0 == rc && Params::instance().target_ & Params::ctThumb) {
rc = eraseThumbnail(image.get());
} }
switch (Params::instance().target_) { if (0 == rc && Params::instance().target_ & Params::ctExif) {
case Params::ctExif: rc = eraseExifData(exifData); break; rc = eraseExifData(image.get());
case Params::ctThumb: rc = eraseThumbnail(exifData); break;
} }
if (0 == rc && Params::instance().target_ & Params::ctIptc) {
rc = eraseIptcData(image.get());
}
if (0 == rc && Params::instance().target_ & Params::ctComment) {
rc = eraseComment(image.get());
}
if (0 == rc) {
rc = image->writeMetadata();
if (rc) {
std::cerr << Exiv2::ExifData::strError(rc, path_) << "\n";
}
}
return rc; return rc;
} }
catch(const Exiv2::Error& e) catch(const Exiv2::Error& e)
@ -695,37 +717,57 @@ namespace Action {
return 1; return 1;
} // Erase::run } // Erase::run
int Erase::eraseThumbnail(Exiv2::ExifData& exifData) const int Erase::eraseThumbnail(Exiv2::Image* image) const
{ {
if (image->sizeExifData() == 0) {
return 0;
}
int rc = 0; int rc = 0;
std::string thumbExt = exifData.thumbnailExtension(); Exiv2::ExifData exifData;
if (thumbExt.empty()) { rc = exifData.read(image->exifData(), image->sizeExifData());
std::cerr << path_ << ": Image does not contain an Exif thumbnail\n"; if (rc) {
std::cerr << Exiv2::ExifData::strError(rc, path_) << "\n";
} }
else { if (0 == rc) {
long delta = exifData.eraseThumbnail(); std::string thumbExt = exifData.thumbnailExtension();
if (Params::instance().verbose_) { if (!thumbExt.empty()) {
std::cout << "Erasing " << delta << " Bytes of thumbnail data" long delta = exifData.eraseThumbnail();
<< std::endl; if (Params::instance().verbose_) {
} std::cout << "Erasing " << delta
rc = exifData.write(path_); << " Bytes of thumbnail data" << std::endl;
if (rc) { }
std::cerr << Exiv2::ExifData::strError(rc, path_) << "\n"; Exiv2::DataBuf buf(exifData.copy());
image->setExifData(buf.pData_, buf.size_);
} }
} }
return rc; return rc;
} }
int Erase::eraseExifData(Exiv2::ExifData& exifData) const int Erase::eraseExifData(Exiv2::Image* image) const
{ {
if (Params::instance().verbose_) { if (Params::instance().verbose_ && image->sizeExifData() > 0) {
std::cout << "Erasing Exif data from the file" << std::endl; std::cout << "Erasing Exif data from the file" << std::endl;
} }
int rc = exifData.erase(path_); image->clearExifData();
if (rc) { return 0;
std::cerr << Exiv2::ExifData::strError(rc, path_) << "\n"; }
int Erase::eraseIptcData(Exiv2::Image* image) const
{
if (Params::instance().verbose_ && image->sizeIptcData() > 0) {
std::cout << "Erasing Iptc data from the file" << std::endl;
} }
return rc; image->clearIptcData();
return 0;
}
int Erase::eraseComment(Exiv2::Image* image) const
{
if (Params::instance().verbose_ && image->comment().size() > 0) {
std::cout << "Erasing Jpeg comment from the file" << std::endl;
}
image->clearComment();
return 0;
} }
Erase::AutoPtr Erase::clone() const Erase::AutoPtr Erase::clone() const
@ -815,9 +857,19 @@ namespace Action {
int Insert::run(const std::string& path) int Insert::run(const std::string& path)
try { try {
std::string exvPath = Util::dirname(path) + SEPERATOR_STR int rc = 0;
+ Util::basename(path, true) + ".exv"; if (Params::instance().target_ & Params::ctThumb) {
return metacopy(exvPath, path); rc = insertThumbnail(path);
}
if ( rc == 0
&& Params::instance().target_ & Params::ctExif
|| Params::instance().target_ & Params::ctIptc
|| Params::instance().target_ & Params::ctComment) {
std::string exvPath = Util::dirname(path) + SEPERATOR_STR
+ Util::basename(path, true) + ".exv";
rc = metacopy(exvPath, path);
}
return rc;
} }
catch(const Exiv2::Error& e) catch(const Exiv2::Error& e)
{ {
@ -826,6 +878,26 @@ namespace Action {
return 1; return 1;
} // Insert::run } // Insert::run
int Insert::insertThumbnail(const std::string& path) const
{
std::string thumbPath = Util::dirname(path) + SEPERATOR_STR
+ Util::basename(path, true) + "-thumb.jpg";
if (!Util::fileExists(thumbPath, true)) {
std::cerr << thumbPath
<< ": Failed to open the file\n";
return -1;
}
Exiv2::ExifData exifData;
int rc = exifData.read(path);
if (rc) {
std::cerr << Exiv2::ExifData::strError(rc, path) << "\n";
return rc;
}
exifData.setJpegThumbnail(thumbPath);
return exifData.write(path);
} // Insert::insertThumbnail
Insert::AutoPtr Insert::clone() const Insert::AutoPtr Insert::clone() const
{ {
return AutoPtr(clone_()); return AutoPtr(clone_());

@ -42,6 +42,7 @@
namespace Exiv2 { namespace Exiv2 {
class ExifData; class ExifData;
class Image;
} }
// ***************************************************************************** // *****************************************************************************
@ -222,11 +223,19 @@ namespace Action {
/*! /*!
@brief Delete the thumbnail image, incl IFD1 metadata from the file. @brief Delete the thumbnail image, incl IFD1 metadata from the file.
*/ */
int eraseThumbnail(Exiv2::ExifData& exifData) const; int eraseThumbnail(Exiv2::Image* image) const;
/*! /*!
@brief Erase the complete Exif data block from the file. @brief Erase the complete Exif data block from the file.
*/ */
int eraseExifData(Exiv2::ExifData& exifData) const; int eraseExifData(Exiv2::Image* image) const;
/*!
@brief Erase all Iptc data from the file.
*/
int eraseIptcData(Exiv2::Image* image) const;
/*!
@brief Erase Jpeg comment from the file.
*/
int eraseComment(Exiv2::Image* image) const;
private: private:
virtual Erase* clone_() const; virtual Erase* clone_() const;
@ -268,6 +277,13 @@ namespace Action {
typedef std::auto_ptr<Insert> AutoPtr; typedef std::auto_ptr<Insert> AutoPtr;
AutoPtr clone() const; AutoPtr clone() const;
/*!
@brief Insert a Jpeg thumbnail image from a file into file \path.
The filename of the thumbanail is expected to be the image
filename (\em path) minus its suffix plus "-thumb.jpg".
*/
int insertThumbnail(const std::string& path) const;
private: private:
virtual Insert* clone_() const; virtual Insert* clone_() const;

@ -162,17 +162,18 @@ void Params::help(std::ostream& os) const
<< " h : hexdump of the Exif data\n" << " h : hexdump of the Exif data\n"
<< " i : Iptc data values\n" << " i : Iptc data values\n"
<< " c : Jpeg comment\n" << " c : Jpeg comment\n"
<< " -d tgt Delete target for the `delete' action. Possible targets are\n" << " -d tgt Delete target(s) for the `delete' action. Possible targets are:\n"
<< " `e' to delete the whole Exif section (the default) and `t'\n" << " a : all supported metadata (the default)\n"
<< " to delete only the Exif thumbnail from the files.\n" << " e : Exif section\n"
<< " -i tgt Insert target(s) for the `insert' action. Possible targets are:\n" << " t : Exif thumbnail only\n"
<< " a : all supported metadata (default)\n"
<< " e : Exif data\n"
<< " i : Iptc data\n" << " i : Iptc data\n"
<< " c : Jpeg comment\n" << " c : Jpeg comment\n"
<< " to delete only the Exif thumbnail from the files.\n"
<< " -i tgt Insert target(s) for the `insert' action. Possible targets are\n"
<< " the same as those for the -d option. Only Jpeg thumbnails can\n"
<< " <file>-thumb.jpg can be inserted.\n"
<< " -e tgt Extract target(s) for the `extract' action. Possible targets\n" << " -e tgt Extract target(s) for the `extract' action. Possible targets\n"
<< " are the same as those for the -i option plus:\n" << " are the same as those for the -d option.\n"
<< " t : extract the Exif thumbnail to an image file\n"
<< " -r fmt Filename format for the `rename' action. The format string\n" << " -r fmt Filename format for the `rename' action. The format string\n"
<< " follows strftime(3). Default filename format is " << " follows strftime(3). Default filename format is "
<< format_ << ".\n\n"; << format_ << ".\n\n";
@ -258,20 +259,18 @@ int Params::option(int opt, const std::string& optarg, int optopt)
switch (action_) { switch (action_) {
case Action::none: case Action::none:
action_ = Action::erase; action_ = Action::erase;
switch (optarg[0]) { target_ = 0;
case 'e': target_ = ctExif; break; // fallthrough
case 't': target_ = ctThumb; break; case Action::erase:
default: rc = parseCommonTargets(optarg, "erase");
std::cerr << progname() << ": Unrecognized delete target `" if (rc > 0) {
<< optarg << "'\n"; target_ |= rc;
rc = 0;
}
else {
rc = 1; rc = 1;
break;
} }
break; break;
case Action::erase:
std::cerr << progname()
<< ": Ignoring surplus option -d" << optarg << "\n";
break;
default: default:
std::cerr << progname() std::cerr << progname()
<< ": Option -d is not compatible with a previous option\n"; << ": Option -d is not compatible with a previous option\n";
@ -378,7 +377,6 @@ int Params::nonoption(const std::string& argv)
} }
action = true; action = true;
action_ = Action::erase; action_ = Action::erase;
target_ = ctExif;
} }
if (argv == "ex" || argv == "extract") { if (argv == "ex" || argv == "extract") {
if (action_ != Action::none && action_ != Action::extract) { if (action_ != Action::none && action_ != Action::extract) {
@ -489,7 +487,7 @@ namespace {
{ {
int rc = 0; int rc = 0;
int target = 0; int target = 0;
for (size_t i = 0; i < optarg.size(); ++i) { for (size_t i = 0; rc == 0 && i < optarg.size(); ++i) {
switch (optarg[i]) { switch (optarg[i]) {
case 'e': target |= Params::ctExif; break; case 'e': target |= Params::ctExif; break;
case 'i': target |= Params::ctIptc; break; case 'i': target |= Params::ctIptc; break;
@ -500,7 +498,7 @@ namespace {
| Params::ctComment; break; | Params::ctComment; break;
default: default:
std::cerr << Params::instance().progname() << ": Unrecognized " std::cerr << Params::instance().progname() << ": Unrecognized "
<< action << " target `" << optarg << "'\n"; << action << " target `" << optarg[i] << "'\n";
rc = -1; rc = -1;
break; break;
} }

@ -37,17 +37,18 @@ Options:
h : hexdump of the Exif data h : hexdump of the Exif data
i : Iptc data values i : Iptc data values
c : Jpeg comment c : Jpeg comment
-d tgt Delete target for the `delete' action. Possible targets are -d tgt Delete target(s) for the `delete' action. Possible targets are:
`e' to delete the whole Exif section (the default) and `t' a : all supported metadata (the default)
to delete only the Exif thumbnail from the files. e : Exif section
-i tgt Insert target(s) for the `insert' action. Possible targets are: t : Exif thumbnail only
a : all supported metadata (default)
e : Exif data
i : Iptc data i : Iptc data
c : Jpeg comment c : Jpeg comment
to delete only the Exif thumbnail from the files.
-i tgt Insert target(s) for the `insert' action. Possible targets are
the same as those for the -d option. Only Jpeg thumbnails can
<file>-thumb.jpg can be inserted.
-e tgt Extract target(s) for the `extract' action. Possible targets -e tgt Extract target(s) for the `extract' action. Possible targets
are the same as those for the -i option plus: are the same as those for the -d option.
t : extract the Exif thumbnail to an image file
-r fmt Filename format for the `rename' action. The format string -r fmt Filename format for the `rename' action. The format string
follows strftime(3). Default filename format is %Y%m%d_%H%M%S. follows strftime(3). Default filename format is %Y%m%d_%H%M%S.
@ -991,63 +992,64 @@ Compare image data and extracted data ------------------------------------
Delete Thumbnail --------------------------------------------------------- Delete Thumbnail ---------------------------------------------------------
File 1/9: exiv2-empty.jpg File 1/9: exiv2-empty.jpg
exiv2-empty.jpg: No Exif data found in the file
File 2/9: 20031214_000043.jpg File 2/9: 20031214_000043.jpg
Erasing Exif data from the file Erasing 6200 Bytes of thumbnail data
File 3/9: 20000506_020544.jpg File 3/9: 20000506_020544.jpg
Erasing Exif data from the file Erasing 7923 Bytes of thumbnail data
File 4/9: 20040329_224245.jpg File 4/9: 20040329_224245.jpg
Erasing Exif data from the file Erasing 9038 Bytes of thumbnail data
File 5/9: 20010405_235039.jpg File 5/9: 20010405_235039.jpg
Erasing Exif data from the file Erasing 4756 Bytes of thumbnail data
File 6/9: 20030925_201850.jpg File 6/9: 20030925_201850.jpg
Warning: Upper boundary of data for Makernote entry 25 is out of bounds: Warning: Upper boundary of data for Makernote entry 25 is out of bounds:
Offset = 1384, size = 48, exceeds buffer size by 24 Bytes; Truncating the data. Offset = 1384, size = 48, exceeds buffer size by 24 Bytes; Truncating the data.
Erasing Exif data from the file Erasing 9858 Bytes of thumbnail data
File 7/9: 20001026_044550.jpg File 7/9: 20001026_044550.jpg
Erasing Exif data from the file Erasing 20910 Bytes of thumbnail data
File 8/9: 20030926_111535.jpg File 8/9: 20030926_111535.jpg
Erasing Exif data from the file Erasing 9696 Bytes of thumbnail data
File 9/9: 20040316_075137.jpg File 9/9: 20040316_075137.jpg
Erasing Exif data from the file Erasing 12104 Bytes of thumbnail data
File 1/9: exiv2-empty.jpg File 1/9: exiv2-empty.jpg
exiv2-empty.jpg: No Exif data found in the file exiv2-empty.jpg: No Exif data found in the file
File 2/9: 20031214_000043.jpg File 2/9: 20031214_000043.jpg
20031214_000043.jpg: No Exif data found in the file 20031214_000043.jpg: Image does not contain an Exif thumbnail
File 3/9: 20000506_020544.jpg File 3/9: 20000506_020544.jpg
20000506_020544.jpg: No Exif data found in the file 20000506_020544.jpg: Image does not contain an Exif thumbnail
File 4/9: 20040329_224245.jpg File 4/9: 20040329_224245.jpg
20040329_224245.jpg: No Exif data found in the file 20040329_224245.jpg: Image does not contain an Exif thumbnail
File 5/9: 20010405_235039.jpg File 5/9: 20010405_235039.jpg
20010405_235039.jpg: No Exif data found in the file 20010405_235039.jpg: Image does not contain an Exif thumbnail
File 6/9: 20030925_201850.jpg File 6/9: 20030925_201850.jpg
20030925_201850.jpg: No Exif data found in the file Warning: Upper boundary of data for Makernote entry 25 is out of bounds:
Offset = 1384, size = 48, exceeds buffer size by 24 Bytes; Truncating the data.
20030925_201850.jpg: Image does not contain an Exif thumbnail
File 7/9: 20001026_044550.jpg File 7/9: 20001026_044550.jpg
20001026_044550.jpg: No Exif data found in the file 20001026_044550.jpg: Image does not contain an Exif thumbnail
File 8/9: 20030926_111535.jpg File 8/9: 20030926_111535.jpg
20030926_111535.jpg: No Exif data found in the file 20030926_111535.jpg: Image does not contain an Exif thumbnail
File 9/9: 20040316_075137.jpg File 9/9: 20040316_075137.jpg
20040316_075137.jpg: No Exif data found in the file 20040316_075137.jpg: Image does not contain an Exif thumbnail
Delete Exif data --------------------------------------------------------- Delete Exif data ---------------------------------------------------------
File 1/9: exiv2-empty.jpg File 1/9: exiv2-empty.jpg
exiv2-empty.jpg: No Exif data found in the file
File 2/9: 20031214_000043.jpg File 2/9: 20031214_000043.jpg
20031214_000043.jpg: No Exif data found in the file Erasing Exif data from the file
File 3/9: 20000506_020544.jpg File 3/9: 20000506_020544.jpg
20000506_020544.jpg: No Exif data found in the file Erasing Exif data from the file
File 4/9: 20040329_224245.jpg File 4/9: 20040329_224245.jpg
20040329_224245.jpg: No Exif data found in the file Erasing Exif data from the file
File 5/9: 20010405_235039.jpg File 5/9: 20010405_235039.jpg
20010405_235039.jpg: No Exif data found in the file Erasing Exif data from the file
File 6/9: 20030925_201850.jpg File 6/9: 20030925_201850.jpg
20030925_201850.jpg: No Exif data found in the file Erasing Exif data from the file
File 7/9: 20001026_044550.jpg File 7/9: 20001026_044550.jpg
20001026_044550.jpg: No Exif data found in the file Erasing Exif data from the file
Erasing Jpeg comment from the file
File 8/9: 20030926_111535.jpg File 8/9: 20030926_111535.jpg
20030926_111535.jpg: No Exif data found in the file Erasing Exif data from the file
File 9/9: 20040316_075137.jpg File 9/9: 20040316_075137.jpg
20040316_075137.jpg: No Exif data found in the file Erasing Exif data from the file
File 1/9: exiv2-empty.jpg File 1/9: exiv2-empty.jpg
exiv2-empty.jpg: No Exif data found in the file exiv2-empty.jpg: No Exif data found in the file
File 2/9: 20031214_000043.jpg File 2/9: 20031214_000043.jpg

Loading…
Cancel
Save