Added Key, ExifKey and IptcKey class hierarchy
Changed Exif keys to 'Exif.ifdItem.tagName'
This commit is contained in:
parent
84a121bbe2
commit
0147a77c7b
111
src/actions.cpp
111
src/actions.cpp
@ -20,13 +20,13 @@
|
||||
*/
|
||||
/*
|
||||
File: actions.cpp
|
||||
Version: $Name: $ $Revision: 1.32 $
|
||||
Version: $Name: $ $Revision: 1.33 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 08-Dec-03, ahu: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.32 $ $RCSfile: actions.cpp,v $");
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.33 $ $RCSfile: actions.cpp,v $");
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -163,25 +163,26 @@ namespace Action {
|
||||
}
|
||||
|
||||
// Camera make
|
||||
printTag(exifData, "Image.OtherTags.Make", "Camera make");
|
||||
printTag(exifData, "Exif.Image.Make", "Camera make");
|
||||
|
||||
// Camera model
|
||||
printTag(exifData, "Image.OtherTags.Model", "Camera model");
|
||||
printTag(exifData, "Exif.Image.Model", "Camera model");
|
||||
|
||||
// Image Timestamp
|
||||
printTag(exifData, "Image.DateTime.DateTimeOriginal", "Image timestamp");
|
||||
printTag(exifData, "Exif.Photo.DateTimeOriginal", "Image timestamp");
|
||||
|
||||
// Image number
|
||||
// Todo: Image number for cameras other than Canon
|
||||
printTag(exifData, "Makernote.Canon.ImageNumber", "Image number");
|
||||
printTag(exifData, "Exif.Canon.ImageNumber", "Image number");
|
||||
|
||||
// Exposure time
|
||||
// From ExposureTime, failing that, try ShutterSpeedValue
|
||||
std::cout << std::setw(align_) << std::setfill(' ') << std::left
|
||||
<< "Exposure time" << ": ";
|
||||
Exiv2::ExifData::const_iterator md;
|
||||
if (0 == printTag(exifData, "Image.CaptureConditions.ExposureTime")) {
|
||||
md = exifData.findKey("Image.CaptureConditions.ShutterSpeedValue");
|
||||
if (0 == printTag(exifData, "Exif.Photo.ExposureTime")) {
|
||||
md = exifData.findKey(
|
||||
Exiv2::ExifKey("Exif.Photo.ShutterSpeedValue"));
|
||||
if (md != exifData.end()) {
|
||||
double tmp = exp(log(2.0) * md->toFloat()) + 0.5;
|
||||
if (tmp > 1) {
|
||||
@ -198,8 +199,9 @@ namespace Action {
|
||||
// Get if from FNumber and, failing that, try ApertureValue
|
||||
std::cout << std::setw(align_) << std::setfill(' ') << std::left
|
||||
<< "Aperture" << ": ";
|
||||
if (0 == printTag(exifData, "Image.CaptureConditions.FNumber")) {
|
||||
md = exifData.findKey("Image.CaptureConditions.ApertureValue");
|
||||
if (0 == printTag(exifData, "Exif.Photo.FNumber")) {
|
||||
md = exifData.findKey(
|
||||
Exiv2::ExifKey("Exif.Photo.ApertureValue"));
|
||||
if (md != exifData.end()) {
|
||||
std::cout << std::fixed << std::setprecision(1)
|
||||
<< "F" << exp(log(2.0) * md->toFloat() / 2);
|
||||
@ -208,16 +210,16 @@ namespace Action {
|
||||
std::cout << "\n";
|
||||
|
||||
// Exposure bias
|
||||
printTag(exifData, "Image.CaptureConditions.ExposureBiasValue", "Exposure bias");
|
||||
printTag(exifData, "Exif.Photo.ExposureBiasValue", "Exposure bias");
|
||||
|
||||
// Flash
|
||||
printTag(exifData, "Image.CaptureConditions.Flash", "Flash");
|
||||
printTag(exifData, "Exif.Photo.Flash", "Flash");
|
||||
|
||||
// Todo: Flash bias, flash energy
|
||||
// Todo: Implement this for other cameras
|
||||
std::cout << std::setw(align_) << std::setfill(' ') << std::left
|
||||
<< "Flash bias" << ": ";
|
||||
md = exifData.findKey("Makernote.Canon.CameraSettings2");
|
||||
md = exifData.findKey(Exiv2::ExifKey("Exif.Canon.CameraSettings2"));
|
||||
if (md != exifData.end() && md->count() >= 15) {
|
||||
Exiv2::CanonMakerNote::print0x0004_15(std::cout, md->toLong(15));
|
||||
}
|
||||
@ -227,8 +229,9 @@ namespace Action {
|
||||
// Todo: Calculate 35 mm equivalent a la jhead
|
||||
std::cout << std::setw(align_) << std::setfill(' ') << std::left
|
||||
<< "Focal length" << ": ";
|
||||
if (1 == printTag(exifData, "Image.CaptureConditions.FocalLength")) {
|
||||
md = exifData.findKey("Image.CaptureConditions.FocalLengthIn35mmFilm");
|
||||
if (1 == printTag(exifData, "Exif.Photo.FocalLength")) {
|
||||
md = exifData.findKey(
|
||||
Exiv2::ExifKey("Exif.Photo.FocalLengthIn35mmFilm"));
|
||||
if (md != exifData.end()) {
|
||||
std::cout << " (35 mm equivalent: " << *md << ")";
|
||||
}
|
||||
@ -238,8 +241,9 @@ namespace Action {
|
||||
// Subject distance
|
||||
std::cout << std::setw(align_) << std::setfill(' ') << std::left
|
||||
<< "Subject distance" << ": ";
|
||||
if (0 == printTag(exifData, "Image.CaptureConditions.SubjectDistance")) {
|
||||
md = exifData.findKey("Makernote.Canon.CameraSettings2");
|
||||
if (0 == printTag(exifData, "Exif.Photo.SubjectDistance")) {
|
||||
md = exifData.findKey(
|
||||
Exiv2::ExifKey("Exif.Canon.CameraSettings2"));
|
||||
if (md != exifData.end() && md->count() >= 19) {
|
||||
Exiv2::CanonMakerNote::print0x0004_19(std::cout, md->toLong(19));
|
||||
}
|
||||
@ -251,20 +255,21 @@ namespace Action {
|
||||
std::cout << std::setw(align_) << std::setfill(' ') << std::left
|
||||
<< "ISO speed" << ": ";
|
||||
bool done = false;
|
||||
if (0 == printTag(exifData, "Image.CaptureConditions.ISOSpeedRatings")) {
|
||||
md = exifData.findKey("Makernote.Canon.CameraSettings1");
|
||||
if (0 == printTag(exifData, "Exif.Photo.ISOSpeedRatings")) {
|
||||
md = exifData.findKey(
|
||||
Exiv2::ExifKey("Exif.Canon.CameraSettings1"));
|
||||
if (md != exifData.end() && md->count() >= 16) {
|
||||
Exiv2::CanonMakerNote::print0x0001_16(std::cout, md->toLong(16));
|
||||
done = true;
|
||||
}
|
||||
if (!done) {
|
||||
done = printTag(exifData, "Makernote.Nikon1.ISOSpeed");
|
||||
done = printTag(exifData, "Exif.Nikon1.ISOSpeed");
|
||||
}
|
||||
if (!done) {
|
||||
done = printTag(exifData, "Makernote.Nikon2.ISOSpeed");
|
||||
done = printTag(exifData, "Exif.Nikon2.ISOSpeed");
|
||||
}
|
||||
if (!done) {
|
||||
done = printTag(exifData, "Makernote.Nikon3.ISOSpeed");
|
||||
done = printTag(exifData, "Exif.Nikon3.ISOSpeed");
|
||||
}
|
||||
}
|
||||
std::cout << "\n";
|
||||
@ -273,8 +278,9 @@ namespace Action {
|
||||
// From ExposureProgram or Canon Makernote
|
||||
std::cout << std::setw(align_) << std::setfill(' ') << std::left
|
||||
<< "Exposure mode" << ": ";
|
||||
if (0 == printTag(exifData, "Image.CaptureConditions.ExposureProgram")) {
|
||||
md = exifData.findKey("Makernote.Canon.CameraSettings1");
|
||||
if (0 == printTag(exifData, "Exif.Photo.ExposureProgram")) {
|
||||
md = exifData.findKey(
|
||||
Exiv2::ExifKey("Exif.Canon.CameraSettings1"));
|
||||
if (md != exifData.end() && md->count() >= 20) {
|
||||
Exiv2::CanonMakerNote::print0x0001_20(std::cout, md->toLong(20));
|
||||
}
|
||||
@ -282,20 +288,21 @@ namespace Action {
|
||||
std::cout << "\n";
|
||||
|
||||
// Metering mode
|
||||
printTag(exifData, "Image.CaptureConditions.MeteringMode", "Metering mode");
|
||||
printTag(exifData, "Exif.Photo.MeteringMode", "Metering mode");
|
||||
|
||||
// Macro mode
|
||||
// Todo: Implement this for other cameras
|
||||
std::cout << std::setw(align_) << std::setfill(' ') << std::left
|
||||
<< "Macro mode" << ": ";
|
||||
done = false;
|
||||
md = exifData.findKey("Makernote.Canon.CameraSettings1");
|
||||
md = exifData.findKey(
|
||||
Exiv2::ExifKey("Exif.Canon.CameraSettings1"));
|
||||
if (md != exifData.end() && md->count() >= 1) {
|
||||
Exiv2::CanonMakerNote::print0x0001_01(std::cout, md->toLong(1));
|
||||
done = true;
|
||||
}
|
||||
if (!done) {
|
||||
done = printTag(exifData, "Makernote.Fujifilm.Macro");
|
||||
done = printTag(exifData, "Exif.Fujifilm.Macro");
|
||||
}
|
||||
std::cout << "\n";
|
||||
|
||||
@ -304,25 +311,25 @@ namespace Action {
|
||||
std::cout << std::setw(align_) << std::setfill(' ') << std::left
|
||||
<< "Image quality" << ": ";
|
||||
done = false;
|
||||
md = exifData.findKey("Makernote.Canon.CameraSettings1");
|
||||
md = exifData.findKey(Exiv2::ExifKey("Exif.Canon.CameraSettings1"));
|
||||
if (md != exifData.end() && md->count() >= 3) {
|
||||
Exiv2::CanonMakerNote::print0x0001_03(std::cout, md->toLong(3));
|
||||
done = true;
|
||||
}
|
||||
if (!done) {
|
||||
done = printTag(exifData, "Makernote.Fujifilm.Quality");
|
||||
done = printTag(exifData, "Exif.Fujifilm.Quality");
|
||||
}
|
||||
if (!done) {
|
||||
done = printTag(exifData, "Makernote.Sigma.Quality");
|
||||
done = printTag(exifData, "Exif.Sigma.Quality");
|
||||
}
|
||||
if (!done) {
|
||||
done = printTag(exifData, "Makernote.Nikon1.Quality");
|
||||
done = printTag(exifData, "Exif.Nikon1.Quality");
|
||||
}
|
||||
if (!done) {
|
||||
done = printTag(exifData, "Makernote.Nikon2.Quality");
|
||||
done = printTag(exifData, "Exif.Nikon2.Quality");
|
||||
}
|
||||
if (!done) {
|
||||
done = printTag(exifData, "Makernote.Nikon3.Quality");
|
||||
done = printTag(exifData, "Exif.Nikon3.Quality");
|
||||
}
|
||||
std::cout << "\n";
|
||||
|
||||
@ -331,9 +338,9 @@ namespace Action {
|
||||
<< "Exif Resolution" << ": ";
|
||||
long xdim = 0;
|
||||
long ydim = 0;
|
||||
md = exifData.findKey("Image.ImageConfig.PixelXDimension");
|
||||
md = exifData.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension"));
|
||||
if (md != exifData.end()) xdim = md->toLong();
|
||||
md = exifData.findKey("Image.ImageConfig.PixelYDimension");
|
||||
md = exifData.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension"));
|
||||
if (md != exifData.end()) ydim = md->toLong();
|
||||
if (xdim != 0 && ydim != 0) {
|
||||
std::cout << xdim << " x " << ydim;
|
||||
@ -345,25 +352,25 @@ namespace Action {
|
||||
std::cout << std::setw(align_) << std::setfill(' ') << std::left
|
||||
<< "White balance" << ": ";
|
||||
done = false;
|
||||
md = exifData.findKey("Makernote.Canon.CameraSettings2");
|
||||
md = exifData.findKey(Exiv2::ExifKey("Exif.Canon.CameraSettings2"));
|
||||
if (md != exifData.end() && md->count() >= 7) {
|
||||
Exiv2::CanonMakerNote::print0x0004_07(std::cout, md->toLong(7));
|
||||
done = true;
|
||||
}
|
||||
if (!done) {
|
||||
done = printTag(exifData, "Makernote.Fujifilm.WhiteBalance");
|
||||
done = printTag(exifData, "Exif.Fujifilm.WhiteBalance");
|
||||
}
|
||||
if (!done) {
|
||||
done = printTag(exifData, "Makernote.Sigma.WhiteBalance");
|
||||
done = printTag(exifData, "Exif.Sigma.WhiteBalance");
|
||||
}
|
||||
if (!done) {
|
||||
done = printTag(exifData, "Makernote.Nikon1.WhiteBalance");
|
||||
done = printTag(exifData, "Exif.Nikon1.WhiteBalance");
|
||||
}
|
||||
if (!done) {
|
||||
done = printTag(exifData, "Makernote.Nikon2.WhiteBalance");
|
||||
done = printTag(exifData, "Exif.Nikon2.WhiteBalance");
|
||||
}
|
||||
if (!done) {
|
||||
done = printTag(exifData, "Makernote.Nikon3.WhiteBalance");
|
||||
done = printTag(exifData, "Exif.Nikon3.WhiteBalance");
|
||||
}
|
||||
std::cout << "\n";
|
||||
|
||||
@ -381,10 +388,10 @@ namespace Action {
|
||||
std::cout << "\n";
|
||||
|
||||
// Copyright
|
||||
printTag(exifData, "Image.OtherTags.Copyright", "Copyright");
|
||||
printTag(exifData, "Exif.Image.Copyright", "Copyright");
|
||||
|
||||
// Exif Comment
|
||||
printTag(exifData, "Image.UserInfo.UserComment", "Exif comment");
|
||||
printTag(exifData, "Exif.Photo.UserComment", "Exif comment");
|
||||
std::cout << std::endl;
|
||||
|
||||
} // Print::printSummary
|
||||
@ -399,7 +406,8 @@ namespace Action {
|
||||
std::cout << std::setw(align_) << std::setfill(' ') << std::left
|
||||
<< label << ": ";
|
||||
}
|
||||
Exiv2::ExifData::const_iterator md = exifData.findKey(key);
|
||||
Exiv2::ExifKey ek(key);
|
||||
Exiv2::ExifData::const_iterator md = exifData.findKey(ek);
|
||||
if (md != exifData.end()) {
|
||||
std::cout << *md;
|
||||
rc = 1;
|
||||
@ -484,7 +492,7 @@ namespace Action {
|
||||
std::cerr << Exiv2::ExifData::strError(rc, path) << "\n";
|
||||
return rc;
|
||||
}
|
||||
std::string key = "Image.DateTime.DateTimeOriginal";
|
||||
Exiv2::ExifKey key("Exif.Photo.DateTimeOriginal");
|
||||
Exiv2::ExifData::iterator md = exifData.findKey(key);
|
||||
if (md == exifData.end()) {
|
||||
std::cerr << "Metadatum with key `" << key << "' "
|
||||
@ -753,9 +761,9 @@ namespace Action {
|
||||
std::cerr << Exiv2::ExifData::strError(rc, path) << "\n";
|
||||
return rc;
|
||||
}
|
||||
rc = adjustDateTime(exifData, "Image.OtherTags.DateTime", path);
|
||||
rc += adjustDateTime(exifData, "Image.DateTime.DateTimeOriginal", path);
|
||||
rc += adjustDateTime(exifData, "Image.DateTime.DateTimeDigitized", path);
|
||||
rc = adjustDateTime(exifData, "Exif.Image.DateTime", path);
|
||||
rc += adjustDateTime(exifData, "Exif.Photo.DateTimeOriginal", path);
|
||||
rc += adjustDateTime(exifData, "Exif.Photo.DateTimeDigitized", path);
|
||||
if (rc) return 1;
|
||||
rc = exifData.write(path);
|
||||
if (rc) {
|
||||
@ -784,7 +792,8 @@ namespace Action {
|
||||
const std::string& key,
|
||||
const std::string& path) const
|
||||
{
|
||||
Exiv2::ExifData::iterator md = exifData.findKey(key);
|
||||
Exiv2::ExifKey ek(key);
|
||||
Exiv2::ExifData::iterator md = exifData.findKey(ek);
|
||||
if (md == exifData.end()) {
|
||||
// Key not found. That's ok, we do nothing.
|
||||
return 0;
|
||||
@ -792,7 +801,7 @@ namespace Action {
|
||||
std::string timeStr = md->toString();
|
||||
if (timeStr == "" || timeStr[0] == ' ') {
|
||||
std::cerr << path << ": Timestamp of metadatum with key `"
|
||||
<< key << "' not set\n";
|
||||
<< ek << "' not set\n";
|
||||
return 1;
|
||||
}
|
||||
time_t time = str2Time(timeStr);
|
||||
@ -802,7 +811,7 @@ namespace Action {
|
||||
return 1;
|
||||
}
|
||||
if (Params::instance().verbose_) {
|
||||
std::cout << "Adjusting `" << key << "' by"
|
||||
std::cout << "Adjusting `" << ek << "' by"
|
||||
<< (adjustment_ < 0 ? " " : " +")
|
||||
<< adjustment_ << " s to ";
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
Abstract: Sample program showing how to add, modify and delete Exif metadata.
|
||||
|
||||
File: addmoddel.cpp
|
||||
Version: $Name: $ $Revision: 1.3 $
|
||||
Version: $Name: $ $Revision: 1.4 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 26-Jan-04, ahu: created
|
||||
*/
|
||||
@ -28,7 +28,7 @@ try {
|
||||
// Set the value to a string
|
||||
v->read("1999:12:31 23:59:59");
|
||||
// Add the value together with its key to the Exif data container
|
||||
std::string key = "Image.DateTime.DateTimeOriginal";
|
||||
Exiv2::ExifKey key("Exif.Photo.DateTimeOriginal");
|
||||
exifData.add(key, v);
|
||||
|
||||
std::cout << "Added key \"" << key << "\", value \"" << *v << "\"\n";
|
||||
@ -43,7 +43,7 @@ try {
|
||||
rv->value_.push_back(std::make_pair(2,3));
|
||||
rv->value_.push_back(std::make_pair(3,4));
|
||||
// Add the key and value pair to the Exif data
|
||||
key = "Image.ImageCharacteristics.PrimaryChromaticities";
|
||||
key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities");
|
||||
exifData.add(key, rv);
|
||||
|
||||
std::cout << "Added key \"" << key << "\", value \"" << *rv << "\"\n";
|
||||
@ -54,7 +54,7 @@ try {
|
||||
// Modify Exif data
|
||||
|
||||
// Find the timestamp metadatum by its key
|
||||
key = "Image.DateTime.DateTimeOriginal";
|
||||
key = Exiv2::ExifKey("Exif.Photo.DateTimeOriginal");
|
||||
Exiv2::ExifData::iterator pos = exifData.findKey(key);
|
||||
if (pos == exifData.end()) throw Exiv2::Error("Key not found");
|
||||
// Modify the value
|
||||
@ -65,7 +65,7 @@ try {
|
||||
<< "\", new value \"" << pos->value() << "\"\n";
|
||||
|
||||
// Find the other key
|
||||
key = "Image.ImageCharacteristics.PrimaryChromaticities";
|
||||
key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities");
|
||||
pos = exifData.findKey(key);
|
||||
if (pos == exifData.end()) throw Exiv2::Error("Key not found");
|
||||
// Get a pointer to a copy of the value
|
||||
@ -86,7 +86,7 @@ try {
|
||||
// Delete metadata from the Exif data container
|
||||
|
||||
// Delete the metadatum at iterator position pos
|
||||
key = "Image.ImageCharacteristics.PrimaryChromaticities";
|
||||
key = Exiv2::ExifKey("Exif.Image.PrimaryChromaticities");
|
||||
pos = exifData.findKey(key);
|
||||
if (pos == exifData.end()) throw Exiv2::Error("Key not found");
|
||||
exifData.erase(pos);
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
File: canonmn.cpp
|
||||
Version: $Name: $ $Revision: 1.12 $
|
||||
Version: $Name: $ $Revision: 1.13 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 18-Feb-04, ahu: created
|
||||
07-Mar-04, ahu: isolated as a separate component
|
||||
@ -30,7 +30,7 @@
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.12 $ $RCSfile: canonmn.cpp,v $");
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.13 $ $RCSfile: canonmn.cpp,v $");
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -68,7 +68,7 @@ namespace Exiv2 {
|
||||
};
|
||||
|
||||
CanonMakerNote::CanonMakerNote(bool alloc)
|
||||
: IfdMakerNote(canonMnTagInfo, alloc), sectionName_("Canon")
|
||||
: IfdMakerNote(canonMnTagInfo, alloc), ifdItem_("Canon")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
@brief Canon MakerNote implemented according to the specification
|
||||
<a href="http://www.burren.cx/david/canon.html">
|
||||
EXIF MakerNote of Canon</a> by David Burren
|
||||
@version $Name: $ $Revision: 1.9 $
|
||||
@version $Name: $ $Revision: 1.10 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 18-Feb-04, ahu: created<BR>
|
||||
@ -98,8 +98,8 @@ namespace Exiv2 {
|
||||
//! @name Accessors
|
||||
//@{
|
||||
CanonMakerNote* clone(bool alloc =true) const;
|
||||
//! Return the name of the makernote section ("Canon")
|
||||
std::string sectionName(uint16 tag) const { return sectionName_; }
|
||||
//! Return the name of the makernote item ("Canon")
|
||||
std::string ifdItem() const { return ifdItem_; }
|
||||
std::ostream& printTag(std::ostream& os,
|
||||
uint16 tag,
|
||||
const Value& value) const;
|
||||
@ -193,8 +193,8 @@ namespace Exiv2 {
|
||||
*/
|
||||
static const RegisterMakerNote register_;
|
||||
|
||||
//! The section name (second part of the key) used for makernote tags
|
||||
std::string sectionName_;
|
||||
//! The item name (second part of the key) used for makernote tags
|
||||
std::string ifdItem_;
|
||||
|
||||
}; // class CanonMakerNote
|
||||
|
||||
|
||||
@ -20,13 +20,13 @@
|
||||
*/
|
||||
/*
|
||||
File: datasets.cpp
|
||||
Version: $Name: $ $Revision: 1.3 $
|
||||
Version: $Name: $ $Revision: 1.4 $
|
||||
Author(s): Brad Schick (brad) <schick@robotbattle.com>
|
||||
History: 24-Jul-04, brad: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.3 $ $RCSfile: datasets.cpp,v $");
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.4 $ $RCSfile: datasets.cpp,v $");
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -162,6 +162,8 @@ namespace Exiv2 {
|
||||
0
|
||||
};
|
||||
|
||||
const char* IptcDataSets::familyName_ = "Iptc";
|
||||
|
||||
int IptcDataSets::dataSetIdx(uint16 number, uint16 recordId)
|
||||
{
|
||||
if( recordId != envelope && recordId != application2 ) return -1;
|
||||
@ -248,13 +250,15 @@ namespace Exiv2 {
|
||||
|
||||
std::string IptcDataSets::makeKey(const DataSet& dataSet)
|
||||
{
|
||||
return "Iptc." + std::string(recordName(dataSet.recordId_))
|
||||
return std::string(familyName())
|
||||
+ "." + std::string(recordName(dataSet.recordId_))
|
||||
+ "." + dataSet.name_;
|
||||
}
|
||||
|
||||
std::string IptcDataSets::makeKey(uint16 number, uint16 recordId)
|
||||
{
|
||||
return "Iptc." + std::string(recordName(recordId))
|
||||
return std::string(familyName())
|
||||
+ "." + std::string(recordName(recordId))
|
||||
+ "." + std::string(dataSetName(number, recordId));
|
||||
}
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
/*!
|
||||
@file datasets.hpp
|
||||
@brief Iptc dataSet and type information
|
||||
@version $Name: $ $Revision: 1.2 $
|
||||
@version $Name: $ $Revision: 1.3 $
|
||||
@author Brad Schick (brad) <schick@robotbattle.com>
|
||||
@date 24-Jul-04, brad: created
|
||||
*/
|
||||
@ -171,7 +171,10 @@ namespace Exiv2 {
|
||||
static const uint16 PreviewVersion = 201;
|
||||
static const uint16 Preview = 202;
|
||||
//@}
|
||||
|
||||
|
||||
private:
|
||||
static const char* familyName_;
|
||||
|
||||
private:
|
||||
//! Prevent construction: not implemented.
|
||||
IptcDataSets() {}
|
||||
@ -181,6 +184,8 @@ namespace Exiv2 {
|
||||
IptcDataSets& operator=(const IptcDataSets& rhs);
|
||||
|
||||
public:
|
||||
//! Return an identifier for Iptc datasets
|
||||
static const char* familyName() { return familyName_; }
|
||||
/*!
|
||||
@brief Return the name of the dataset.
|
||||
@param number The dataset number
|
||||
@ -240,12 +245,12 @@ namespace Exiv2 {
|
||||
static uint16 recordId(const std::string& recordName);
|
||||
/*!
|
||||
@brief Return the key for the dataSet number and record id. The key is
|
||||
of the form 'recordName.dataSetName'.
|
||||
of the form '<b>Iptc</b>.recordName.dataSetName'.
|
||||
*/
|
||||
static std::string makeKey(uint16 number, uint16 recordId);
|
||||
/*!
|
||||
@brief Return the key for the dataSet. The key is of the form
|
||||
'recordName.dataSetName'.
|
||||
'<b>Iptc</b>.recordName.dataSetName'.
|
||||
*/
|
||||
static std::string makeKey(const DataSet& dataSet);
|
||||
/*!
|
||||
|
||||
200
src/exif.cpp
200
src/exif.cpp
@ -20,14 +20,14 @@
|
||||
*/
|
||||
/*
|
||||
File: exif.cpp
|
||||
Version: $Name: $ $Revision: 1.53 $
|
||||
Version: $Name: $ $Revision: 1.54 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 26-Jan-04, ahu: created
|
||||
11-Feb-04, ahu: isolated as a component
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.53 $ $RCSfile: exif.cpp,v $");
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.54 $ $RCSfile: exif.cpp,v $");
|
||||
|
||||
// Define DEBUG_MAKERNOTE to output debug information to std::cerr
|
||||
#undef DEBUG_MAKERNOTE
|
||||
@ -73,37 +73,127 @@ namespace {
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
Exifdatum::Exifdatum(const Entry& e, ByteOrder byteOrder)
|
||||
ExifKey::ExifKey(const std::string& key)
|
||||
: idx_(0), pMakerNote_(0), key_(key)
|
||||
{
|
||||
decomposeKey();
|
||||
}
|
||||
|
||||
ExifKey::ExifKey(const Entry& e)
|
||||
: tag_(e.tag()), ifdId_(e.ifdId()), idx_(e.idx()),
|
||||
pMakerNote_(e.makerNote()), pValue_(0), key_(makeKey(e))
|
||||
pMakerNote_(e.makerNote()), key_(makeKey(e))
|
||||
{
|
||||
}
|
||||
|
||||
ExifKey::ExifKey(const ExifKey& rhs)
|
||||
: tag_(rhs.tag_), ifdId_(rhs.ifdId_), idx_(rhs.idx_),
|
||||
pMakerNote_(rhs.pMakerNote_), key_(rhs.key_)
|
||||
{
|
||||
}
|
||||
|
||||
ExifKey& ExifKey::operator=(const ExifKey& rhs)
|
||||
{
|
||||
if (this == &rhs) return *this;
|
||||
Key::operator=(rhs);
|
||||
tag_ = rhs.tag_;
|
||||
ifdId_ = rhs.ifdId_;
|
||||
idx_ = rhs.idx_;
|
||||
pMakerNote_ = rhs.pMakerNote_;
|
||||
key_ = rhs.key_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ExifKey::setMakerNote(MakerNote* pMakerNote)
|
||||
{
|
||||
if (ifdId_ == makerIfd && pMakerNote_ != pMakerNote) {
|
||||
pMakerNote_ = pMakerNote;
|
||||
decomposeKey();
|
||||
}
|
||||
}
|
||||
|
||||
std::string ExifKey::tagName() const
|
||||
{
|
||||
if (ifdId_ == makerIfd && pMakerNote_ != 0) {
|
||||
return pMakerNote_->tagName(tag_);
|
||||
}
|
||||
return ExifTags::tagName(tag(), ifdId());
|
||||
}
|
||||
|
||||
uint16 ExifKey::tag() const
|
||||
{
|
||||
if (tag_ == 0xffff) throw Error("Invalid key");
|
||||
return tag_;
|
||||
}
|
||||
|
||||
IfdId ExifKey::ifdId() const
|
||||
{
|
||||
if (ifdId_ == ifdIdNotSet) throw Error("Invalid key");
|
||||
return ifdId_;
|
||||
}
|
||||
|
||||
ExifKey* ExifKey::clone() const
|
||||
{
|
||||
return new ExifKey(*this);
|
||||
}
|
||||
|
||||
std::string ExifKey::sectionName() const
|
||||
{
|
||||
if (ifdId_ == makerIfd && pMakerNote_ != 0) {
|
||||
return pMakerNote_->ifdItem();
|
||||
}
|
||||
return ExifTags::sectionName(tag(), ifdId());
|
||||
}
|
||||
|
||||
void ExifKey::decomposeKey()
|
||||
{
|
||||
std::pair<uint16, IfdId> p;
|
||||
if (ifdId_ == makerIfd && pMakerNote_ != 0) {
|
||||
p.first = pMakerNote_->decomposeKey(key_);
|
||||
if (p.first == 0xffff) throw Error("Invalid key");
|
||||
p.second = makerIfd;
|
||||
}
|
||||
else {
|
||||
p = ExifTags::decomposeKey(key_);
|
||||
// If it's couldn't be parsed, we assume it is an incomplete
|
||||
// makernote key (pMakerNote_ not set)
|
||||
if (p.second == ifdIdNotSet) p.second = makerIfd;
|
||||
// No checks as this could still be an incomplete makernote key
|
||||
}
|
||||
tag_ = p.first;
|
||||
ifdId_ = p.second;
|
||||
}
|
||||
|
||||
std::ostream& ExifKey::printTag(std::ostream& os, const Value& value) const
|
||||
{
|
||||
if (ifdId_ == makerIfd && pMakerNote_ != 0) {
|
||||
return pMakerNote_->printTag(os, tag(), value);
|
||||
}
|
||||
return ExifTags::printTag(os, tag(), ifdId(), value);
|
||||
}
|
||||
|
||||
Exifdatum::Exifdatum(const Entry& e, ByteOrder byteOrder)
|
||||
: pKey_(new ExifKey(e)), pValue_(0)
|
||||
{
|
||||
pValue_ = Value::create(TypeId(e.type()));
|
||||
pValue_->read(e.data(), e.count() * e.typeSize(), byteOrder);
|
||||
}
|
||||
|
||||
Exifdatum::Exifdatum(const std::string& key,
|
||||
const Value* value,
|
||||
MakerNote* makerNote)
|
||||
: idx_(0), pMakerNote_(makerNote), pValue_(0), key_(key)
|
||||
Exifdatum::Exifdatum(const ExifKey& key, const Value* pValue)
|
||||
: pKey_(key.clone()), pValue_(0)
|
||||
{
|
||||
if (value) pValue_ = value->clone();
|
||||
std::pair<uint16, IfdId> p = decomposeKey(key, makerNote);
|
||||
if (p.first == 0xffff) throw Error("Invalid key");
|
||||
tag_ = p.first;
|
||||
if (p.second == ifdIdNotSet) throw Error("Invalid key");
|
||||
ifdId_ = p.second;
|
||||
if (pValue) pValue_ = pValue->clone();
|
||||
}
|
||||
|
||||
Exifdatum::~Exifdatum()
|
||||
{
|
||||
delete pKey_;
|
||||
delete pValue_;
|
||||
// do *not* delete the MakerNote
|
||||
}
|
||||
|
||||
Exifdatum::Exifdatum(const Exifdatum& rhs)
|
||||
: Metadatum(rhs), tag_(rhs.tag_), ifdId_(rhs.ifdId_), idx_(rhs.idx_),
|
||||
pMakerNote_(rhs.pMakerNote_), pValue_(0), key_(rhs.key_)
|
||||
: Metadatum(rhs), pKey_(0), pValue_(0)
|
||||
{
|
||||
if (rhs.pKey_ != 0) pKey_ = rhs.pKey_->clone(); // deep copy
|
||||
if (rhs.pValue_ != 0) pValue_ = rhs.pValue_->clone(); // deep copy
|
||||
}
|
||||
|
||||
@ -111,14 +201,15 @@ namespace Exiv2 {
|
||||
{
|
||||
if (this == &rhs) return *this;
|
||||
Metadatum::operator=(rhs);
|
||||
tag_ = rhs.tag_;
|
||||
ifdId_ = rhs.ifdId_;
|
||||
idx_ = rhs.idx_;
|
||||
pMakerNote_ = rhs.pMakerNote_;
|
||||
|
||||
delete pKey_;
|
||||
pKey_ = 0;
|
||||
if (rhs.pKey_ != 0) pKey_ = rhs.pKey_->clone(); // deep copy
|
||||
|
||||
delete pValue_;
|
||||
pValue_ = 0;
|
||||
if (rhs.pValue_ != 0) pValue_ = rhs.pValue_->clone(); // deep copy
|
||||
key_ = rhs.key_;
|
||||
|
||||
return *this;
|
||||
} // Exifdatum::operator=
|
||||
|
||||
@ -141,22 +232,6 @@ namespace Exiv2 {
|
||||
pValue_->read(buf);
|
||||
}
|
||||
|
||||
std::string Exifdatum::tagName() const
|
||||
{
|
||||
if (ifdId_ == makerIfd && pMakerNote_ != 0) {
|
||||
return pMakerNote_->tagName(tag_);
|
||||
}
|
||||
return ExifTags::tagName(tag_, ifdId_);
|
||||
}
|
||||
|
||||
std::string Exifdatum::sectionName() const
|
||||
{
|
||||
if (ifdId_ == makerIfd && pMakerNote_ != 0) {
|
||||
return pMakerNote_->sectionName(tag_);
|
||||
}
|
||||
return ExifTags::sectionName(tag_, ifdId_);
|
||||
}
|
||||
|
||||
TiffThumbnail::TiffThumbnail()
|
||||
: offset_(0), size_(0), pImage_(0), ifd_(ifd1, 0, false)
|
||||
{
|
||||
@ -229,17 +304,16 @@ namespace Exiv2 {
|
||||
buflen += ifd1.size() + ifd1.dataSize();
|
||||
if (len < buflen) rc = 1;
|
||||
}
|
||||
std::string key;
|
||||
ExifData::const_iterator offsets;
|
||||
ExifData::const_iterator sizes;
|
||||
if (rc == 0) {
|
||||
// Copy thumbnail image data, remember the offsets used
|
||||
key = "Thumbnail.RecordingOffset.StripOffsets";
|
||||
ExifKey key("Exif.Thumbnail.StripOffsets");
|
||||
offsets = exifData.findKey(key);
|
||||
if (offsets == exifData.end()) rc = 2;
|
||||
}
|
||||
if (rc == 0) {
|
||||
key = "Thumbnail.RecordingOffset.StripByteCounts";
|
||||
ExifKey key("Exif.Thumbnail.StripByteCounts");
|
||||
sizes = exifData.findKey(key);
|
||||
if (sizes == exifData.end()) rc = 2;
|
||||
}
|
||||
@ -426,12 +500,12 @@ namespace Exiv2 {
|
||||
const ExifData& exifData,
|
||||
ByteOrder byteOrder)
|
||||
{
|
||||
std::string key = "Thumbnail.RecordingOffset.JPEGInterchangeFormat";
|
||||
ExifKey key("Exif.Thumbnail.JPEGInterchangeFormat");
|
||||
ExifData::const_iterator pos = exifData.findKey(key);
|
||||
if (pos == exifData.end()) return 2;
|
||||
long offset = pos->toLong();
|
||||
key = "Thumbnail.RecordingOffset.JPEGInterchangeFormatLength";
|
||||
pos = exifData.findKey(key);
|
||||
ExifKey key2("Exif.Thumbnail.JPEGInterchangeFormatLength");
|
||||
pos = exifData.findKey(key2);
|
||||
if (pos == exifData.end()) return 2;
|
||||
long size = pos->toLong();
|
||||
if (len < offset + size) return 1;
|
||||
@ -466,7 +540,7 @@ namespace Exiv2 {
|
||||
|
||||
void JpegThumbnail::update(ExifData& exifData) const
|
||||
{
|
||||
std::string key = "Thumbnail.RecordingOffset.JPEGInterchangeFormat";
|
||||
ExifKey key("Exif.Thumbnail.JPEGInterchangeFormat");
|
||||
ExifData::iterator pos = exifData.findKey(key);
|
||||
if (pos == exifData.end()) {
|
||||
Value* value = Value::create(unsignedLong);
|
||||
@ -476,13 +550,13 @@ namespace Exiv2 {
|
||||
}
|
||||
pos->setValue(toString(offset_));
|
||||
|
||||
key = "Thumbnail.RecordingOffset.JPEGInterchangeFormatLength";
|
||||
pos = exifData.findKey(key);
|
||||
ExifKey key2("Exif.Thumbnail.JPEGInterchangeFormatLength");
|
||||
pos = exifData.findKey(key2);
|
||||
if (pos == exifData.end()) {
|
||||
Value *value = Value::create(unsignedLong);
|
||||
exifData.add(key, value);
|
||||
exifData.add(key2, value);
|
||||
delete value;
|
||||
pos = exifData.findKey(key);
|
||||
pos = exifData.findKey(key2);
|
||||
}
|
||||
pos->setValue(toString(size_));
|
||||
|
||||
@ -600,7 +674,7 @@ namespace Exiv2 {
|
||||
if (rc) {
|
||||
// Todo: How to handle debug output like this
|
||||
std::cerr << "Warning: Failed to read "
|
||||
<< pMakerNote_->sectionName(0)
|
||||
<< pMakerNote_->ifdItem()
|
||||
<< " Makernote, rc = " << rc << "\n";
|
||||
|
||||
delete pMakerNote_;
|
||||
@ -896,9 +970,12 @@ namespace Exiv2 {
|
||||
}
|
||||
}
|
||||
|
||||
void ExifData::add(const std::string& key, Value* value)
|
||||
void ExifData::add(const ExifKey& key, Value* pValue)
|
||||
{
|
||||
add(Exifdatum(key, value));
|
||||
// Todo: Implement a more suitable ExifKey c'tor
|
||||
ExifKey k(key);
|
||||
k.setMakerNote(pMakerNote_);
|
||||
add(Exifdatum(k, pValue));
|
||||
}
|
||||
|
||||
void ExifData::add(const Exifdatum& exifdatum)
|
||||
@ -907,16 +984,16 @@ namespace Exiv2 {
|
||||
exifMetadata_.push_back(exifdatum);
|
||||
}
|
||||
|
||||
ExifData::const_iterator ExifData::findKey(const std::string& key) const
|
||||
ExifData::const_iterator ExifData::findKey(const ExifKey& key) const
|
||||
{
|
||||
return std::find_if(exifMetadata_.begin(), exifMetadata_.end(),
|
||||
FindMetadatumByKey(key));
|
||||
FindMetadatumByKey(key.key()));
|
||||
}
|
||||
|
||||
ExifData::iterator ExifData::findKey(const std::string& key)
|
||||
ExifData::iterator ExifData::findKey(const ExifKey& key)
|
||||
{
|
||||
return std::find_if(exifMetadata_.begin(), exifMetadata_.end(),
|
||||
FindMetadatumByKey(key));
|
||||
FindMetadatumByKey(key.key()));
|
||||
}
|
||||
|
||||
ExifData::const_iterator ExifData::findIfdIdIdx(IfdId ifdId, int idx) const
|
||||
@ -1019,7 +1096,8 @@ namespace Exiv2 {
|
||||
delete pThumbnail_;
|
||||
pThumbnail_ = 0;
|
||||
int rc = -1;
|
||||
const_iterator pos = findKey("Thumbnail.ImageStructure.Compression");
|
||||
const_iterator pos
|
||||
= findKey(ExifKey("Exif.Thumbnail.Compression"));
|
||||
if (pos != end()) {
|
||||
long compression = pos->toLong();
|
||||
if (compression == 6) {
|
||||
@ -1200,7 +1278,7 @@ namespace Exiv2 {
|
||||
error += "Exif data contains a broken IFD";
|
||||
break;
|
||||
case 7:
|
||||
error += "Unsupported Exif or GPS data found in IFD 1";
|
||||
error += "Unsupported Exif or GPS data found in IFD1";
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1272,13 +1350,9 @@ namespace Exiv2 {
|
||||
makerNote->add(e);
|
||||
} // addToMakerNote
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Exifdatum& md)
|
||||
{
|
||||
if (md.ifdId() == makerIfd && md.makerNote() != 0) {
|
||||
return md.makerNote()->printTag(os, md.tag(), md.value());
|
||||
}
|
||||
return ExifTags::printTag(os, md.tag(), md.ifdId(), md.value());
|
||||
return md.pKey_->printTag(os, md.value());
|
||||
}
|
||||
|
||||
std::string makeKey(const Entry& entry)
|
||||
|
||||
196
src/exif.hpp
196
src/exif.hpp
@ -21,7 +21,7 @@
|
||||
/*!
|
||||
@file exif.hpp
|
||||
@brief Encoding and decoding of Exif data
|
||||
@version $Name: $ $Revision: 1.49 $
|
||||
@version $Name: $ $Revision: 1.50 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 09-Jan-04, ahu: created
|
||||
@ -60,30 +60,117 @@ namespace Exiv2 {
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
//! Concrete keys for Exif metadata.
|
||||
class ExifKey : public Key {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor to create an Exif key from a key string.
|
||||
|
||||
@param key The key string.
|
||||
@throw Error ("Invalid key") if the key cannot be parsed into three
|
||||
parts or the first part of the key is not '<b>Exif</b>'.
|
||||
*/
|
||||
explicit ExifKey(const std::string& key);
|
||||
//! Constructor to build an ExifKey from an IFD entry.
|
||||
explicit ExifKey(const Entry& e);
|
||||
//! Copy constructor
|
||||
ExifKey(const ExifKey& rhs);
|
||||
// A destructor is not needed, as we do *not* delete the makernote
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Assignment operator.
|
||||
*/
|
||||
ExifKey& operator=(const ExifKey& rhs);
|
||||
//! Set the makernote pointer.
|
||||
void setMakerNote(MakerNote* pMakerNote);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
virtual std::string key() const { return key_; }
|
||||
virtual const char* familyName() const { return ExifTags::familyName(); }
|
||||
/*!
|
||||
@brief Return the name of the group (the second part of the key).
|
||||
For Exif keys, the group name is the IFD name.
|
||||
*/
|
||||
virtual std::string groupName() const { return ifdName(); }
|
||||
virtual std::string tagName() const;
|
||||
/*!
|
||||
@brief Return the tag.
|
||||
@throw Error ("Invalid key") if the tag is not set.
|
||||
*/
|
||||
virtual uint16 tag() const;
|
||||
virtual ExifKey* clone() const;
|
||||
|
||||
//! Interpret and print the value of an Exif tag
|
||||
std::ostream& printTag(std::ostream& os, const Value& value) const;
|
||||
/*!
|
||||
@brief Return the IFD id
|
||||
@throw Error ("Invalid key") if the IFD id is not set.
|
||||
*/
|
||||
IfdId ifdId() const;
|
||||
//! Return the name of the IFD
|
||||
const char* ifdName() const { return ExifTags::ifdName(ifdId()); }
|
||||
//! Return the related image item
|
||||
const char* ifdItem() const { return ExifTags::ifdItem(ifdId()); }
|
||||
//! Return the name of the Exif section (deprecated)
|
||||
std::string sectionName() const;
|
||||
//! Return the index (unique id of this key within the original IFD)
|
||||
int idx() const { return idx_; }
|
||||
//! Return the pointer to the associated MakerNote
|
||||
MakerNote* makerNote() const { return pMakerNote_; }
|
||||
//@}
|
||||
|
||||
protected:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Parse and convert the key string into tag, and IFD Id.
|
||||
Forwards the request to MakerNote::decomposeKey if necessary.
|
||||
Updates key_ and ifdId_ if the string can be decomposed,
|
||||
or throws Error ("Invalid key").
|
||||
|
||||
@throw Error ("Invalid key") if pMakerNote_ is ot 0 and the key
|
||||
cannot be parsed into family name, group name and tag name
|
||||
parts.
|
||||
*/
|
||||
void decomposeKey();
|
||||
//@}
|
||||
|
||||
private:
|
||||
// DATA
|
||||
uint16 tag_; //!< Tag value
|
||||
IfdId ifdId_; //!< The IFD associated with this tag
|
||||
int idx_; //!< Unique id of an entry within one IFD
|
||||
MakerNote* pMakerNote_; //!< Pointer to the associated MakerNote
|
||||
std::string key_; //!< Key
|
||||
}; // class ExifKey
|
||||
|
||||
/*!
|
||||
@brief Information related to one Exif tag.
|
||||
*/
|
||||
class Exifdatum : public Metadatum {
|
||||
friend std::ostream& operator<<(std::ostream&, const Exifdatum&);
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor for new tags created by an application. The
|
||||
Exifdatum is created from a key / value pair. %Exifdatum copies
|
||||
(clones) the value if one is provided. Alternatively, a program
|
||||
can create an 'empty' Exifdatum with only a key and set the
|
||||
value using setValue().
|
||||
%Exifdatum is created from a key / value pair. %Exifdatum copies
|
||||
(clones) the key and value if one is provided. Alternatively,
|
||||
a program can create an 'empty' %Exifdatum with only a key
|
||||
and set the value using setValue().
|
||||
|
||||
@param key The key of the Exifdatum.
|
||||
@param value Pointer to a Exifdatum value.
|
||||
@param makerNote Pointer to the associated MakerNote (only needed for
|
||||
MakerNote tags).
|
||||
@throw Error ("Invalid key") if the key cannot be parsed and converted
|
||||
to a tag number and an IFD id or the section name does not match.
|
||||
@param key ExifKey.
|
||||
@param pValue Pointer to a Exifdatum value.
|
||||
@throw Error ("Invalid key") if the key cannot be parsed and converted.
|
||||
*/
|
||||
explicit Exifdatum(const std::string& key,
|
||||
const Value* value =0,
|
||||
MakerNote* makerNote =0);
|
||||
explicit Exifdatum(const ExifKey& key, const Value* pValue =0);
|
||||
//! Constructor to build a Exifdatum from an IFD entry.
|
||||
Exifdatum(const Entry& e, ByteOrder byteOrder);
|
||||
//! Copy constructor
|
||||
@ -115,6 +202,30 @@ namespace Exiv2 {
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
//! Return the key of the %Exifdatum.
|
||||
std::string key() const
|
||||
{ return pKey_ == 0 ? "" : pKey_->key(); }
|
||||
//! Return the name of the group (the second part of the key)
|
||||
std::string groupName() const
|
||||
{ return pKey_ == 0 ? "" : pKey_->groupName(); }
|
||||
//! Return the name of the tag (which is also the third part of the key)
|
||||
std::string tagName() const
|
||||
{ return pKey_ == 0 ? "" : pKey_->tagName(); }
|
||||
//! Return the tag
|
||||
uint16 tag() const
|
||||
{ return pKey_ == 0 ? 0xffff : pKey_->tag(); }
|
||||
//! Return the IFD id
|
||||
IfdId ifdId() const
|
||||
{ return pKey_ == 0 ? ifdIdNotSet : pKey_->ifdId(); }
|
||||
//! Return the name of the IFD
|
||||
const char* ifdName() const
|
||||
{ return pKey_ == 0 ? "" : pKey_->ifdName(); }
|
||||
//! Return the related image item (deprecated)
|
||||
const char* ifdItem() const
|
||||
{ return pKey_ == 0 ? "" : pKey_->ifdItem(); }
|
||||
//! Return the index (unique id of this key within the original IFD)
|
||||
int idx() const
|
||||
{ return pKey_ == 0 ? 0 : pKey_->idx(); }
|
||||
/*!
|
||||
@brief Write value to a data buffer and return the number
|
||||
of bytes written.
|
||||
@ -128,40 +239,21 @@ namespace Exiv2 {
|
||||
*/
|
||||
long copy(byte* buf, ByteOrder byteOrder) const
|
||||
{ return pValue_ == 0 ? 0 : pValue_->copy(buf, byteOrder); }
|
||||
/*!
|
||||
@brief Return the key of the Exifdatum. The key is of the form
|
||||
'ifdItem.sectionName.tagName'. Note however that the key
|
||||
is not necessarily unique, i.e., an ExifData may contain
|
||||
multiple metadata with the same key.
|
||||
*/
|
||||
std::string key() const { return key_; }
|
||||
//! Return the related image item (the first part of the key)
|
||||
const char* ifdItem() const { return ExifTags::ifdItem(ifdId_); }
|
||||
//! Return the name of the section (the second part of the key)
|
||||
std::string sectionName() const;
|
||||
//! Return the name of the tag (which is also the third part of the key)
|
||||
std::string tagName() const;
|
||||
//! Return the tag
|
||||
uint16 tag() const { return tag_; }
|
||||
//! Return the type id of the value
|
||||
TypeId typeId() const
|
||||
{ return pValue_ == 0 ? invalidTypeId : pValue_->typeId(); }
|
||||
//! Return the name of the type
|
||||
const char* typeName() const { return TypeInfo::typeName(typeId()); }
|
||||
const char* typeName() const
|
||||
{ return TypeInfo::typeName(typeId()); }
|
||||
//! Return the size in bytes of one component of this type
|
||||
long typeSize() const { return TypeInfo::typeSize(typeId()); }
|
||||
long typeSize() const
|
||||
{ return TypeInfo::typeSize(typeId()); }
|
||||
//! Return the number of components in the value
|
||||
long count() const { return pValue_ == 0 ? 0 : pValue_->count(); }
|
||||
long count() const
|
||||
{ return pValue_ == 0 ? 0 : pValue_->count(); }
|
||||
//! Return the size of the value in bytes
|
||||
long size() const { return pValue_ == 0 ? 0 : pValue_->size(); }
|
||||
//! Return the IFD id
|
||||
IfdId ifdId() const { return ifdId_; }
|
||||
//! Return the name of the IFD
|
||||
const char* ifdName() const { return ExifTags::ifdName(ifdId_); }
|
||||
//! Return the index (unique id of this Exifdatum within the original IFD)
|
||||
int idx() const { return idx_; }
|
||||
//! Return the pointer to the associated MakerNote
|
||||
MakerNote* makerNote() const { return pMakerNote_; }
|
||||
long size() const
|
||||
{ return pValue_ == 0 ? 0 : pValue_->size(); }
|
||||
//! Return the value as a string.
|
||||
std::string toString() const
|
||||
{ return pValue_ == 0 ? "" : pValue_->toString(); }
|
||||
@ -201,7 +293,8 @@ namespace Exiv2 {
|
||||
@return A pointer to a copy (clone) of the value, 0 if the value is
|
||||
not set.
|
||||
*/
|
||||
Value* getValue() const { return pValue_ == 0 ? 0 : pValue_->clone(); }
|
||||
Value* getValue() const
|
||||
{ return pValue_ == 0 ? 0 : pValue_->clone(); }
|
||||
/*!
|
||||
@brief Return a constant reference to the value.
|
||||
|
||||
@ -227,17 +320,13 @@ namespace Exiv2 {
|
||||
|
||||
private:
|
||||
// DATA
|
||||
uint16 tag_; //!< Tag value
|
||||
IfdId ifdId_; //!< The IFD associated with this tag
|
||||
int idx_; //!< Unique id of an entry within one IFD
|
||||
MakerNote* pMakerNote_; //!< Pointer to the associated MakerNote
|
||||
ExifKey* pKey_; //!< Key
|
||||
Value* pValue_; //!< Pointer to the value
|
||||
std::string key_; //!< Key
|
||||
|
||||
}; // class Exifdatum
|
||||
|
||||
/*!
|
||||
@brief Output operator for Exifdatum types, printing the interpreted
|
||||
@brief Output operator for Exifdatum types, prints the interpreted
|
||||
tag value.
|
||||
*/
|
||||
std::ostream& operator<<(std::ostream& os, const Exifdatum& md);
|
||||
@ -579,11 +668,12 @@ namespace Exiv2 {
|
||||
ByteOrder byteOrder);
|
||||
/*!
|
||||
@brief Add a Exifdatum from the supplied key and value pair. This
|
||||
method copies (clones) the value. No duplicate checks are
|
||||
method copies (clones) key and value and adds a pointer to
|
||||
the MakerNote to the cloned key. No duplicate checks are
|
||||
performed, i.e., it is possible to add multiple metadata with
|
||||
the same key.
|
||||
*/
|
||||
void add(const std::string& key, Value* value);
|
||||
void add(const ExifKey& key, Value* pValue);
|
||||
/*!
|
||||
@brief Add a copy of the Exifdatum to the Exif metadata. No
|
||||
duplicate checks are performed, i.e., it is possible to add
|
||||
@ -610,7 +700,7 @@ namespace Exiv2 {
|
||||
If multiple metadata with the same key exist, it is undefined
|
||||
which of the matching metadata is found.
|
||||
*/
|
||||
iterator findKey(const std::string& key);
|
||||
iterator findKey(const ExifKey& key);
|
||||
/*!
|
||||
@brief Find the Exifdatum with the given ifd id and idx, return an
|
||||
iterator to it.
|
||||
@ -659,7 +749,7 @@ namespace Exiv2 {
|
||||
it. If multiple metadata with the same key exist, it is
|
||||
undefined which of the matching metadata is found.
|
||||
*/
|
||||
const_iterator findKey(const std::string& key) const;
|
||||
const_iterator findKey(const ExifKey& key) const;
|
||||
/*!
|
||||
@brief Find the Exifdatum with the given ifd id and idx, return an
|
||||
iterator to it.
|
||||
@ -863,7 +953,7 @@ namespace Exiv2 {
|
||||
ByteOrder byteOrder);
|
||||
/*!
|
||||
@brief Return a key for the entry. The key is of the form
|
||||
'ifdItem.sectionName.tagName'. This function knows about
|
||||
'<b>Exif</b>.ifdItem.tagName'. This function knows about
|
||||
MakerNotes, i.e., it will invoke MakerNote::makeKey if necessary.
|
||||
*/
|
||||
std::string makeKey(const Entry& entry);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
Abstract : Sample program showing how to set the Exif comment of an image
|
||||
|
||||
File: exifcomment.cpp
|
||||
Version : $Name: $ $Revision: 1.3 $
|
||||
Version : $Name: $ $Revision: 1.4 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History : 10-May-04, ahu: created
|
||||
*/
|
||||
@ -33,7 +33,7 @@ try {
|
||||
|
||||
/*
|
||||
There are two pitfalls that we need to consider when setting the Exif user
|
||||
comment (Image.UserInfo.UserComment) of an image:
|
||||
comment (Exif.Photo.UserComment) of an image:
|
||||
|
||||
First, the type of the Exif user comment tag is "undefined" (and not
|
||||
ASCII) according to the Exif standard. This means that in Exiv2, we have
|
||||
@ -60,7 +60,7 @@ try {
|
||||
8 + static_cast<long>(comment.size()));
|
||||
|
||||
// Set the Exif comment
|
||||
std::string key = "Image.UserInfo.UserComment";
|
||||
Exiv2::ExifKey key("Exif.Photo.UserComment");
|
||||
Exiv2::ExifData::iterator pos = exifData.findKey(key);
|
||||
if (pos != exifData.end()) {
|
||||
// Use the existing Exif UserComment metadatum if there is one
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
File: fujimn.cpp
|
||||
Version: $Name: $ $Revision: 1.9 $
|
||||
Version: $Name: $ $Revision: 1.10 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 18-Feb-04, ahu: created
|
||||
07-Mar-04, ahu: isolated as a separate component
|
||||
@ -31,7 +31,7 @@
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.9 $ $RCSfile: fujimn.cpp,v $");
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.10 $ $RCSfile: fujimn.cpp,v $");
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -78,7 +78,7 @@ namespace Exiv2 {
|
||||
};
|
||||
|
||||
FujiMakerNote::FujiMakerNote(bool alloc)
|
||||
: IfdMakerNote(fujiMnTagInfo, alloc), sectionName_("Fujifilm")
|
||||
: IfdMakerNote(fujiMnTagInfo, alloc), ifdItem_("Fujifilm")
|
||||
{
|
||||
byteOrder_ = littleEndian;
|
||||
absOffset_ = false;
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
in Appendix 4: Makernote of Fujifilm of the document
|
||||
<a href="http://park2.wakwak.com/%7Etsuruzoh/Computer/Digicams/exif-e.html">
|
||||
Exif file format</a> by TsuruZoh Tachibanaya
|
||||
@version $Name: $ $Revision: 1.6 $
|
||||
@version $Name: $ $Revision: 1.7 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 11-Feb-04, ahu: created
|
||||
@ -106,8 +106,8 @@ namespace Exiv2 {
|
||||
//@{
|
||||
int checkHeader() const;
|
||||
FujiMakerNote* clone(bool alloc =true) const;
|
||||
//! Return the name of the makernote section ("Fujifilm")
|
||||
std::string sectionName(uint16 tag) const { return sectionName_; }
|
||||
//! Return the name of the makernote item ("Fujifilm")
|
||||
std::string ifdItem() const { return ifdItem_; }
|
||||
std::ostream& printTag(std::ostream& os,
|
||||
uint16 tag,
|
||||
const Value& value) const;
|
||||
@ -157,8 +157,8 @@ namespace Exiv2 {
|
||||
*/
|
||||
static const RegisterMakerNote register_;
|
||||
|
||||
//! The section name (second part of the key) used for makernote tags
|
||||
std::string sectionName_;
|
||||
//! The item name (second part of the key) used for makernote tags
|
||||
std::string ifdItem_;
|
||||
|
||||
}; // class FujiMakerNote
|
||||
|
||||
|
||||
99
src/iptc.cpp
99
src/iptc.cpp
@ -20,13 +20,13 @@
|
||||
*/
|
||||
/*
|
||||
File: iptc.cpp
|
||||
Version: $Name: $ $Revision: 1.2 $
|
||||
Version: $Name: $ $Revision: 1.3 $
|
||||
Author(s): Brad Schick (brad) <schick@robotbattle.com>
|
||||
History: 31-July-04, brad: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.2 $ $RCSfile: iptc.cpp,v $");
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.3 $ $RCSfile: iptc.cpp,v $");
|
||||
|
||||
// Define DEBUG_MAKERNOTE to output debug information to std::cerr
|
||||
#undef DEBUG_MAKERNOTE
|
||||
@ -48,27 +48,63 @@ EXIV2_RCSID("@(#) $Name: $ $Revision: 1.2 $ $RCSfile: iptc.cpp,v $");
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
Iptcdatum::Iptcdatum(const std::string& key,
|
||||
const Value* value)
|
||||
: pValue_(0), key_(key), modified_(false)
|
||||
IptcKey::IptcKey(const std::string& key)
|
||||
: key_(key)
|
||||
{
|
||||
if (value) pValue_ = value->clone();
|
||||
std::pair<uint16, uint16> p = decomposeKey(key);
|
||||
decomposeKey();
|
||||
}
|
||||
|
||||
IptcKey::IptcKey(uint16 tag, uint16 record)
|
||||
: tag_(tag), record_(record), key_(IptcDataSets::makeKey(tag, record))
|
||||
{
|
||||
}
|
||||
|
||||
IptcKey::IptcKey(const IptcKey& rhs)
|
||||
: tag_(rhs.tag_), record_(rhs.record_), key_(rhs.key_)
|
||||
{
|
||||
}
|
||||
|
||||
IptcKey& IptcKey::operator=(const IptcKey& rhs)
|
||||
{
|
||||
if (this == &rhs) return *this;
|
||||
Key::operator=(rhs);
|
||||
tag_ = rhs.tag_;
|
||||
record_ = rhs.record_;
|
||||
key_ = rhs.key_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
IptcKey* IptcKey::clone() const
|
||||
{
|
||||
return new IptcKey(*this);
|
||||
}
|
||||
|
||||
void IptcKey::decomposeKey()
|
||||
{
|
||||
std::pair<uint16, uint16> p = IptcDataSets::decomposeKey(key_);
|
||||
if (p.first == 0xffff) throw Error("Invalid key");
|
||||
tag_ = p.first;
|
||||
if (p.second == IptcDataSets::invalidRecord) throw Error("Invalid key");
|
||||
tag_ = p.first;
|
||||
record_ = p.second;
|
||||
}
|
||||
|
||||
Iptcdatum::Iptcdatum(const Iptcdatum& rhs)
|
||||
: Metadatum(rhs), tag_(rhs.tag_), record_(rhs.record_),
|
||||
pValue_(0), key_(rhs.key_), modified_(false)
|
||||
Iptcdatum::Iptcdatum(const IptcKey& key,
|
||||
const Value* value)
|
||||
: pKey_(key.clone()), pValue_(0), modified_(false)
|
||||
{
|
||||
if (value) pValue_ = value->clone();
|
||||
}
|
||||
|
||||
Iptcdatum::Iptcdatum(const Iptcdatum& rhs)
|
||||
: Metadatum(rhs), pKey_(0), pValue_(0), modified_(false)
|
||||
{
|
||||
if (rhs.pKey_ != 0) pKey_ = rhs.pKey_->clone(); // deep copy
|
||||
if (rhs.pValue_ != 0) pValue_ = rhs.pValue_->clone(); // deep copy
|
||||
}
|
||||
|
||||
Iptcdatum::~Iptcdatum()
|
||||
{
|
||||
delete pKey_;
|
||||
delete pValue_;
|
||||
}
|
||||
|
||||
@ -77,12 +113,15 @@ namespace Exiv2 {
|
||||
if (this == &rhs) return *this;
|
||||
Metadatum::operator=(rhs);
|
||||
modified_ = true;
|
||||
tag_ = rhs.tag_;
|
||||
record_ = rhs.record_;
|
||||
|
||||
delete pKey_;
|
||||
pKey_ = 0;
|
||||
if (rhs.pKey_ != 0) pKey_ = rhs.pKey_->clone(); // deep copy
|
||||
|
||||
delete pValue_;
|
||||
pValue_ = 0;
|
||||
if (rhs.pValue_ != 0) pValue_ = rhs.pValue_->clone(); // deep copy
|
||||
key_ = rhs.key_;
|
||||
|
||||
return *this;
|
||||
} // Iptcdatum::operator=
|
||||
|
||||
@ -100,16 +139,6 @@ namespace Exiv2 {
|
||||
pValue_->read(buf);
|
||||
}
|
||||
|
||||
std::string Iptcdatum::tagName() const
|
||||
{
|
||||
return IptcDataSets::dataSetName(tag_, record_);
|
||||
}
|
||||
|
||||
std::string Iptcdatum::recordName() const
|
||||
{
|
||||
return IptcDataSets::recordName(record_);
|
||||
}
|
||||
|
||||
const byte IptcData::marker_ = 0x1C; // Dataset marker
|
||||
|
||||
IptcData::IptcData()
|
||||
@ -206,7 +235,7 @@ namespace Exiv2 {
|
||||
val = Value::create(undefined);
|
||||
val->read(data, sizeData, bigEndian);
|
||||
}
|
||||
std::string key = makeKey(dataSet, record);
|
||||
IptcKey key(dataSet, record);
|
||||
add(key, val);
|
||||
delete val;
|
||||
return 0;
|
||||
@ -346,7 +375,7 @@ namespace Exiv2 {
|
||||
return exvImage.writeMetadata();
|
||||
} // IptcData::writeIptcData
|
||||
|
||||
int IptcData::add(const std::string& key, Value* value)
|
||||
int IptcData::add(const IptcKey& key, Value* value)
|
||||
{
|
||||
return add(Iptcdatum(key, value));
|
||||
}
|
||||
@ -364,16 +393,16 @@ namespace Exiv2 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
IptcData::const_iterator IptcData::findKey(const std::string& key) const
|
||||
IptcData::const_iterator IptcData::findKey(const IptcKey& key) const
|
||||
{
|
||||
return std::find_if(iptcMetadata_.begin(), iptcMetadata_.end(),
|
||||
FindMetadatumByKey(key));
|
||||
FindMetadatumByKey(key.key()));
|
||||
}
|
||||
|
||||
IptcData::iterator IptcData::findKey(const std::string& key)
|
||||
IptcData::iterator IptcData::findKey(const IptcKey& key)
|
||||
{
|
||||
return std::find_if(iptcMetadata_.begin(), iptcMetadata_.end(),
|
||||
FindMetadatumByKey(key));
|
||||
FindMetadatumByKey(key.key()));
|
||||
}
|
||||
|
||||
IptcData::const_iterator IptcData::findId(uint16 dataset, uint16 record) const
|
||||
@ -453,14 +482,4 @@ namespace Exiv2 {
|
||||
return os << md.value();
|
||||
}
|
||||
|
||||
std::string makeKey(uint16 number, uint16 record)
|
||||
{
|
||||
return IptcDataSets::makeKey(number, record);
|
||||
}
|
||||
|
||||
std::pair<uint16, uint16> decomposeKey(const std::string& key)
|
||||
{
|
||||
return IptcDataSets::decomposeKey(key);
|
||||
}
|
||||
|
||||
} // namespace Exiv2
|
||||
|
||||
144
src/iptc.hpp
144
src/iptc.hpp
@ -21,7 +21,7 @@
|
||||
/*!
|
||||
@file iptc.hpp
|
||||
@brief Encoding and decoding of Iptc data
|
||||
@version $Name: $ $Revision: 1.3 $
|
||||
@version $Name: $ $Revision: 1.4 $
|
||||
@author Brad Schick (brad)
|
||||
<a href="mailto:schick@robotbattle.com">schick@robotbattle.com</a>
|
||||
@date 31-Jul-04, brad: created
|
||||
@ -48,6 +48,82 @@ namespace Exiv2 {
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
//! Concrete keys for Iptc metadata.
|
||||
class IptcKey : public Key {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor to create an Iptc key from a key string.
|
||||
|
||||
@param key The key string.
|
||||
@throw Error ("Invalid key") if the first part of the key is not
|
||||
'Iptc' or the remaining parts of the key cannot be parsed and
|
||||
converted to a record name and a dataset name.
|
||||
*/
|
||||
explicit IptcKey(const std::string& key);
|
||||
/*!
|
||||
@brief Constructor to create an Iptc key from dataset and record ids.
|
||||
@param tag Dataset id
|
||||
@param record Record id
|
||||
*/
|
||||
IptcKey(uint16 tag, uint16 record);
|
||||
//! Copy constructor
|
||||
IptcKey(const IptcKey& rhs);
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Assignment operator.
|
||||
*/
|
||||
IptcKey& operator=(const IptcKey& rhs);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
virtual std::string key() const { return key_; }
|
||||
virtual const char* familyName() const
|
||||
{ return IptcDataSets::familyName(); }
|
||||
/*!
|
||||
@brief Return the name of the group (the second part of the key).
|
||||
For Iptc keys, the group name is the record name.
|
||||
*/
|
||||
virtual std::string groupName() const { return recordName(); }
|
||||
virtual std::string tagName() const
|
||||
{ return IptcDataSets::dataSetName(tag_, record_); }
|
||||
virtual uint16 tag() const { return tag_; }
|
||||
virtual IptcKey* clone() const;
|
||||
|
||||
//! Return the name of the record
|
||||
const char* recordName() const
|
||||
{ return IptcDataSets::recordName(record_); }
|
||||
//! Return the record id
|
||||
uint16 record() const { return record_; }
|
||||
//@}
|
||||
|
||||
protected:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Parse and convert the key string into dataset and record id.
|
||||
Updates tag_ and record_ if the string can be decomposed,
|
||||
or throws Error ("Invalid key").
|
||||
|
||||
@throw Error ("Invalid key") if the key cannot be parsed into
|
||||
family name, group name and tag name parts.
|
||||
*/
|
||||
void decomposeKey();
|
||||
//@}
|
||||
|
||||
private:
|
||||
// DATA
|
||||
uint16 tag_; //!< Tag value
|
||||
uint16 record_; //!< Record value
|
||||
std::string key_; //!< Key
|
||||
|
||||
}; // class IptcKey
|
||||
|
||||
/*!
|
||||
@brief Information related to one Iptc dataset.
|
||||
*/
|
||||
@ -57,17 +133,17 @@ namespace Exiv2 {
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor for new tags created by an application. The
|
||||
Iptcdatum is created from a key / value pair. %Iptcdatum copies
|
||||
(clones) the value if one is provided. Alternatively, a program
|
||||
can create an 'empty' Iptcdatum with only a key and set the
|
||||
value using setValue().
|
||||
%Iptcdatum is created from a key / value pair. %Iptcdatum
|
||||
copies (clones) the value if one is provided. Alternatively, a
|
||||
program can create an 'empty' %Iptcdatum with only a key and
|
||||
set the value using setValue().
|
||||
|
||||
@param key The key of the Iptcdatum.
|
||||
@param value Pointer to a Iptcdatum value.
|
||||
@param key The key of the %Iptcdatum.
|
||||
@param value Pointer to a %Iptcdatum value.
|
||||
@throw Error ("Invalid key") if the key cannot be parsed and converted
|
||||
to a tag number and record id.
|
||||
*/
|
||||
explicit Iptcdatum(const std::string& key,
|
||||
explicit Iptcdatum(const IptcKey& key,
|
||||
const Value* value =0);
|
||||
//! Copy constructor
|
||||
Iptcdatum(const Iptcdatum& rhs);
|
||||
@ -109,30 +185,34 @@ namespace Exiv2 {
|
||||
{ return pValue_ == 0 ? 0 : pValue_->copy(buf, byteOrder); }
|
||||
/*!
|
||||
@brief Return the key of the Iptcdatum. The key is of the form
|
||||
'Iptc.recordName.datasetName'. Note however that the key
|
||||
'<b>Iptc</b>.recordName.datasetName'. Note however that the key
|
||||
is not necessarily unique, i.e., an IptcData may contain
|
||||
multiple metadata with the same key.
|
||||
*/
|
||||
std::string key() const { return key_; }
|
||||
std::string key() const { return pKey_ == 0 ? "" : pKey_->key(); }
|
||||
/*!
|
||||
@brief Return the name of the record
|
||||
@return record name
|
||||
@throw Error("Unknown record");
|
||||
*/
|
||||
std::string recordName() const;
|
||||
const char* recordName() const
|
||||
{ return pKey_ == 0 ? "" : pKey_->recordName(); }
|
||||
/*!
|
||||
@brief Return the record id
|
||||
@return record id
|
||||
*/
|
||||
uint16 record() const { return record_; }
|
||||
uint16 record() const
|
||||
{ return pKey_ == 0 ? 0 : pKey_->record(); }
|
||||
/*!
|
||||
@brief Return the name of the tag (aka dataset)
|
||||
@return tag name
|
||||
@throw Error("No dataSet for record Id") if tag is unknown
|
||||
*/
|
||||
std::string tagName() const;
|
||||
std::string tagName() const
|
||||
{ return pKey_ == 0 ? "" : pKey_->tagName(); }
|
||||
//! Return the tag (aka dataset) number
|
||||
uint16 tag() const { return tag_; }
|
||||
uint16 tag() const
|
||||
{ return pKey_ == 0 ? 0 : pKey_->tag(); }
|
||||
//! Return the type id of the value
|
||||
TypeId typeId() const
|
||||
{ return pValue_ == 0 ? invalidTypeId : pValue_->typeId(); }
|
||||
@ -217,10 +297,8 @@ namespace Exiv2 {
|
||||
|
||||
private:
|
||||
// DATA
|
||||
uint16 tag_; //!< Tag value
|
||||
uint16 record_; //!< Record value
|
||||
IptcKey* pKey_; //!< Key
|
||||
Value* pValue_; //!< Pointer to the value
|
||||
std::string key_; //!< Key
|
||||
bool modified_; //!< Change indicator
|
||||
|
||||
}; // class Iptcdatum
|
||||
@ -341,13 +419,13 @@ namespace Exiv2 {
|
||||
*/
|
||||
long copy(byte* buf);
|
||||
/*!
|
||||
@brief Add a Iptcdatum from the supplied key and value pair. This
|
||||
@brief Add an %Iptcdatum from the supplied key and value pair. This
|
||||
method copies (clones) the value. A check for non-repeatable
|
||||
datasets is performed.
|
||||
@return 0 if successful;<BR>
|
||||
6 if the dataset already exists and is not repeatable;<BR>
|
||||
6 if the dataset already exists and is not repeatable
|
||||
*/
|
||||
int add(const std::string& key, Value* value);
|
||||
int add(const IptcKey& key, Value* value);
|
||||
/*!
|
||||
@brief Add a copy of the Iptcdatum to the Iptc metadata. A check
|
||||
for non-repeatable datasets is performed.
|
||||
@ -375,7 +453,7 @@ namespace Exiv2 {
|
||||
If multiple entries with the same key exist, it is undefined
|
||||
which of the matching metadata is found.
|
||||
*/
|
||||
iterator findKey(const std::string& key);
|
||||
iterator findKey(const IptcKey& key);
|
||||
/*!
|
||||
@brief Find a Iptcdatum with the given record and dataset it,
|
||||
return a const iterator to it. If multiple entries with the
|
||||
@ -404,11 +482,11 @@ namespace Exiv2 {
|
||||
//! End of the metadata
|
||||
const_iterator end() const { return iptcMetadata_.end(); }
|
||||
/*!
|
||||
@brief Find a Iptcdatum with the given key, return a const iterator to
|
||||
it. If multiple metadata with the same key exist it is
|
||||
@brief Find an Iptcdatum with the given key, return a const iterator
|
||||
to it. If multiple metadata with the same key exist it is
|
||||
undefined which of the matching metadata is found.
|
||||
*/
|
||||
const_iterator findKey(const std::string& key) const;
|
||||
const_iterator findKey(const IptcKey& key) const;
|
||||
/*!
|
||||
@brief Find a Iptcdatum with the given record and dataset number,
|
||||
return a const iterator to it. If multiple metadata with the
|
||||
@ -473,24 +551,6 @@ namespace Exiv2 {
|
||||
mutable bool modified_;
|
||||
}; // class IptcData
|
||||
|
||||
// *****************************************************************************
|
||||
// free functions
|
||||
|
||||
/*!
|
||||
@brief Return a key for the entry. The key is of the form
|
||||
'Iptc.recordName.datasetName'.
|
||||
@throw Error ("No dataSet for record Id") if the dataset number or
|
||||
record Id is unknown
|
||||
*/
|
||||
std::string makeKey(uint16 number, uint16 record);
|
||||
/*!
|
||||
@brief Return the record and dataset id pair for the key.
|
||||
@return A pair consisting of the record and dataset id.
|
||||
@throw Error ("Invalid key") if the key cannot be parsed into
|
||||
valid record and dataset parts.
|
||||
*/
|
||||
std::pair<uint16, uint16> decomposeKey(const std::string& key);
|
||||
|
||||
} // namespace Exiv2
|
||||
|
||||
#endif // #ifndef IPTC_HPP_
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
This is not designed to be a robust application.
|
||||
|
||||
File : iptctest.cpp
|
||||
Version : $Name: $ $Revision: 1.1 $
|
||||
Version : $Name: $ $Revision: 1.2 $
|
||||
Author(s): Brad Schick (brad) <schick@robotbattle.com>
|
||||
History : 01-Aug-04, brad: created
|
||||
*/
|
||||
@ -118,7 +118,7 @@ void processAdd(const std::string& line, int num)
|
||||
Value *val = Value::create(type);
|
||||
val->read(data);
|
||||
|
||||
int rc = g_iptcData.add(key, val);
|
||||
int rc = g_iptcData.add(IptcKey(key), val);
|
||||
if (rc) {
|
||||
std::string error = IptcData::strError(rc, "Input file");
|
||||
throw Error(error);
|
||||
@ -180,7 +180,7 @@ void processModify(const std::string& line, int num)
|
||||
iter->setValue(val);
|
||||
}
|
||||
else {
|
||||
int rc = g_iptcData.add(key, val);
|
||||
int rc = g_iptcData.add(IptcKey(key), val);
|
||||
if (rc) {
|
||||
std::string error = IptcData::strError(rc, "Input file");
|
||||
throw Error(error);
|
||||
|
||||
@ -20,13 +20,13 @@
|
||||
*/
|
||||
/*
|
||||
File: makernote.cpp
|
||||
Version: $Name: $ $Revision: 1.24 $
|
||||
Version: $Name: $ $Revision: 1.25 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 18-Feb-04, ahu: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.24 $ $RCSfile: makernote.cpp,v $");
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.25 $ $RCSfile: makernote.cpp,v $");
|
||||
|
||||
// Define DEBUG_* to output debug information to std::cerr
|
||||
#undef DEBUG_MAKERNOTE
|
||||
@ -59,28 +59,29 @@ namespace Exiv2 {
|
||||
|
||||
std::string MakerNote::makeKey(uint16 tag) const
|
||||
{
|
||||
return std::string(ExifTags::ifdItem(makerIfd))
|
||||
+ "." + sectionName(tag) + "." + tagName(tag);
|
||||
return std::string(ExifTags::familyName())
|
||||
+ "." + std::string(ifdItem())
|
||||
+ "." + tagName(tag);
|
||||
} // MakerNote::makeKey
|
||||
|
||||
uint16 MakerNote::decomposeKey(const std::string& key) const
|
||||
{
|
||||
// Get the IFD, section name and tag name parts of the key
|
||||
// Get the family, item and tag name parts of the key
|
||||
std::string::size_type pos1 = key.find('.');
|
||||
if (pos1 == std::string::npos) throw Error("Invalid key");
|
||||
std::string ifdItem = key.substr(0, pos1);
|
||||
std::string familyName = key.substr(0, pos1);
|
||||
std::string::size_type pos0 = pos1 + 1;
|
||||
pos1 = key.find('.', pos0);
|
||||
if (pos1 == std::string::npos) throw Error("Invalid key");
|
||||
std::string sectionName = key.substr(pos0, pos1 - pos0);
|
||||
std::string ifdItem = key.substr(pos0, pos1 - pos0);
|
||||
pos0 = pos1 + 1;
|
||||
std::string tagName = key.substr(pos0);
|
||||
if (tagName == "") throw Error("Invalid key");
|
||||
|
||||
if (ifdItem != ExifTags::ifdItem(makerIfd)) return 0xffff;
|
||||
if (familyName != ExifTags::familyName()) return 0xffff;
|
||||
uint16 tag = this->tag(tagName);
|
||||
if (tag == 0xffff) return tag;
|
||||
if (sectionName != this->sectionName(tag)) return 0xffff;
|
||||
if (ifdItem != this->ifdItem()) return 0xffff;
|
||||
|
||||
return tag;
|
||||
} // MakerNote::decomposeKey
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
@file makernote.hpp
|
||||
@brief Contains the Exif %MakerNote interface, IFD %MakerNote and a
|
||||
MakerNote factory
|
||||
@version $Name: $ $Revision: 1.21 $
|
||||
@version $Name: $ $Revision: 1.22 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 18-Feb-04, ahu: created
|
||||
@ -222,8 +222,8 @@ namespace Exiv2 {
|
||||
virtual Entries::const_iterator findIdx(int idx) const =0;
|
||||
//! Return the size of the makernote in bytes
|
||||
virtual long size() const =0;
|
||||
//! Return the name of the makernote section
|
||||
virtual std::string sectionName(uint16 tag) const =0;
|
||||
//! Return the name of the makernote item
|
||||
virtual std::string ifdItem() const =0;
|
||||
//! Interpret and print the value of a makernote tag
|
||||
virtual std::ostream& printTag(std::ostream& os,
|
||||
uint16 tag,
|
||||
@ -327,7 +327,7 @@ namespace Exiv2 {
|
||||
*/
|
||||
virtual long headerSize() const;
|
||||
virtual IfdMakerNote* clone(bool alloc =true) const =0;
|
||||
virtual std::string sectionName(uint16 tag) const =0;
|
||||
virtual std::string ifdItem() const =0;
|
||||
virtual std::ostream& printTag(std::ostream& os,
|
||||
uint16 tag,
|
||||
const Value& value) const =0;
|
||||
|
||||
@ -20,14 +20,15 @@
|
||||
*/
|
||||
/*!
|
||||
@file metadatum.hpp
|
||||
@brief Provides class Metadatum
|
||||
@version $Name: $ $Revision: 1.1 $
|
||||
@brief Provides abstract base classes Metadatum and Key
|
||||
@version $Name: $ $Revision: 1.2 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@author Brad Schick (brad)
|
||||
<a href="mailto:schick@robotbattle.com">schick@robotbattle.com</a>
|
||||
@date 09-Jan-04, ahu: created<BR>
|
||||
31-Jul-04, brad: isolated as a component
|
||||
31-Jul-04, brad: isolated as a component<BR>
|
||||
23-Aug-04, ahu: added Key
|
||||
*/
|
||||
#ifndef METADATUM_HPP_
|
||||
#define METADATUM_HPP_
|
||||
@ -48,10 +49,82 @@ namespace Exiv2 {
|
||||
// class definitions
|
||||
|
||||
/*!
|
||||
@brief Information related to one Exif tag.
|
||||
@brief Abstract base class defining the %Key of a metadatum.
|
||||
Keys are used to identify and group metadata.
|
||||
*/
|
||||
class Key {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Destructor
|
||||
virtual ~Key() {}
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
/*!
|
||||
@brief Return the key of the metadatum as a string. The key is of the
|
||||
form 'familyName.groupName.tagName'. Note however that the
|
||||
key is not necessarily unique, e.g., an ExifData may contain
|
||||
multiple metadata with the same key.
|
||||
*/
|
||||
virtual std::string key() const =0;
|
||||
//! Return an identifier for the type of metadata (the first part of the key)
|
||||
virtual const char* familyName() const =0;
|
||||
//! Return the name of the group (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)
|
||||
virtual std::string tagName() const =0;
|
||||
//! Return the tag number
|
||||
virtual uint16 tag() const =0;
|
||||
/*!
|
||||
@brief Return a pointer to a copy of itself (deep copy).
|
||||
The caller owns this copy and is responsible to delete it!
|
||||
*/
|
||||
virtual Key* clone() const =0;
|
||||
/*!
|
||||
@brief Write the key to an output stream. You do not usually have
|
||||
to use this function; it is used for the implementation of
|
||||
the output operator for %Key,
|
||||
operator<<(std::ostream &os, const Key &key).
|
||||
*/
|
||||
std::ostream& write(std::ostream& os) const { return os << key(); }
|
||||
//@}
|
||||
|
||||
protected:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Assignment operator. Protected so that it can only be used
|
||||
by subclasses but not directly.
|
||||
*/
|
||||
Key& operator=(const Key& rhs) { return *this; }
|
||||
//@}
|
||||
|
||||
}; // class Key
|
||||
|
||||
//! Output operator for Key types
|
||||
inline std::ostream& operator<<(std::ostream& os, const Key& key)
|
||||
{
|
||||
return key.write(os);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Abstract base class defining the interface to access information
|
||||
related to one metadata tag.
|
||||
*/
|
||||
class Metadatum {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default Constructor
|
||||
Metadatum() {}
|
||||
//! Copy constructor
|
||||
Metadatum(const Metadatum& rhs) {}
|
||||
//! Destructor
|
||||
virtual ~Metadatum() {}
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@ -83,7 +156,7 @@ namespace Exiv2 {
|
||||
virtual long copy(byte* buf, ByteOrder byteOrder) const =0;
|
||||
/*!
|
||||
@brief Return the key of the metadatum. The key is of the form
|
||||
'ifdItem.sectionName.tagName'. Note however that the key
|
||||
'familyName.ifdItem.tagName'. Note however that the key
|
||||
is not necessarily unique, i.e., an ExifData may contain
|
||||
multiple metadata with the same key.
|
||||
*/
|
||||
@ -161,19 +234,12 @@ namespace Exiv2 {
|
||||
//@}
|
||||
|
||||
protected:
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default Constructor
|
||||
Metadatum() {}
|
||||
//! Copy constructor
|
||||
Metadatum(const Metadatum& rhs) {}
|
||||
//! Destructor
|
||||
virtual ~Metadatum() {}
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
//! Assignment operator
|
||||
/*!
|
||||
@brief Assignment operator. Protected so that it can only be used
|
||||
by subclasses but not directly.
|
||||
*/
|
||||
Metadatum& operator=(const Metadatum& rhs) { return *this; }
|
||||
//@}
|
||||
|
||||
|
||||
@ -20,14 +20,14 @@
|
||||
*/
|
||||
/*
|
||||
File: nikon1mn.cpp
|
||||
Version: $Name: $ $Revision: 1.4 $
|
||||
Version: $Name: $ $Revision: 1.5 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 17-May-04, ahu: created
|
||||
25-May-04, ahu: combined all Nikon formats in one component
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.4 $ $RCSfile: nikonmn.cpp,v $");
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.5 $ $RCSfile: nikonmn.cpp,v $");
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -73,7 +73,7 @@ namespace Exiv2 {
|
||||
};
|
||||
|
||||
Nikon1MakerNote::Nikon1MakerNote(bool alloc)
|
||||
: IfdMakerNote(nikon1MnTagInfo, alloc), sectionName_("Nikon1")
|
||||
: IfdMakerNote(nikon1MnTagInfo, alloc), ifdItem_("Nikon1")
|
||||
{
|
||||
}
|
||||
|
||||
@ -198,7 +198,7 @@ namespace Exiv2 {
|
||||
};
|
||||
|
||||
Nikon2MakerNote::Nikon2MakerNote(bool alloc)
|
||||
: IfdMakerNote(nikon2MnTagInfo, alloc), sectionName_("Nikon2")
|
||||
: IfdMakerNote(nikon2MnTagInfo, alloc), ifdItem_("Nikon2")
|
||||
{
|
||||
}
|
||||
|
||||
@ -383,7 +383,7 @@ namespace Exiv2 {
|
||||
};
|
||||
|
||||
Nikon3MakerNote::Nikon3MakerNote(bool alloc)
|
||||
: IfdMakerNote(nikon3MnTagInfo, alloc), sectionName_("Nikon3")
|
||||
: IfdMakerNote(nikon3MnTagInfo, alloc), ifdItem_("Nikon3")
|
||||
{
|
||||
absOffset_ = false;
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
<a href="http://park2.wakwak.com/%7Etsuruzoh/Computer/Digicams/exif-e.html">
|
||||
Exif file format</a> by TsuruZoh Tachibanaya.<BR>
|
||||
Format 3: "EXIFutils Field Reference Guide".
|
||||
@version $Name: $ $Revision: 1.3 $
|
||||
@version $Name: $ $Revision: 1.4 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 17-May-04, ahu: created<BR>
|
||||
@ -103,8 +103,8 @@ namespace Exiv2 {
|
||||
//! @name Accessors
|
||||
//@{
|
||||
Nikon1MakerNote* clone(bool alloc =true) const;
|
||||
//! Return the name of the makernote section ("Nikon1")
|
||||
std::string sectionName(uint16 tag) const { return sectionName_; }
|
||||
//! Return the name of the makernote item ("Nikon1")
|
||||
std::string ifdItem() const { return ifdItem_; }
|
||||
std::ostream& printTag(std::ostream& os,
|
||||
uint16 tag,
|
||||
const Value& value) const;
|
||||
@ -149,8 +149,8 @@ namespace Exiv2 {
|
||||
*/
|
||||
static const RegisterMakerNote register_;
|
||||
|
||||
//! The section name (second part of the key) used for makernote tags
|
||||
std::string sectionName_;
|
||||
//! The item name (second part of the key) used for makernote tags
|
||||
std::string ifdItem_;
|
||||
|
||||
}; // class Nikon1MakerNote
|
||||
|
||||
@ -182,8 +182,8 @@ namespace Exiv2 {
|
||||
//@{
|
||||
int checkHeader() const;
|
||||
Nikon2MakerNote* clone(bool alloc =true) const;
|
||||
//! Return the name of the makernote section ("Nikon2")
|
||||
std::string sectionName(uint16 tag) const { return sectionName_; }
|
||||
//! Return the name of the makernote item ("Nikon2")
|
||||
std::string ifdItem() const { return ifdItem_; }
|
||||
std::ostream& printTag(std::ostream& os,
|
||||
uint16 tag,
|
||||
const Value& value) const;
|
||||
@ -206,8 +206,8 @@ namespace Exiv2 {
|
||||
//@}
|
||||
|
||||
private:
|
||||
//! The section name (second part of the key) used for makernote tags
|
||||
std::string sectionName_;
|
||||
//! The item name (second part of the key) used for makernote tags
|
||||
std::string ifdItem_;
|
||||
|
||||
}; // class Nikon2MakerNote
|
||||
|
||||
@ -236,8 +236,8 @@ namespace Exiv2 {
|
||||
//@{
|
||||
int checkHeader() const;
|
||||
Nikon3MakerNote* clone(bool alloc =true) const;
|
||||
//! Return the name of the makernote section ("Nikon3")
|
||||
std::string sectionName(uint16 tag) const { return sectionName_; }
|
||||
//! Return the name of the makernote item ("Nikon3")
|
||||
std::string ifdItem() const { return ifdItem_; }
|
||||
std::ostream& printTag(std::ostream& os,
|
||||
uint16 tag,
|
||||
const Value& value) const;
|
||||
@ -258,8 +258,8 @@ namespace Exiv2 {
|
||||
//@}
|
||||
|
||||
private:
|
||||
//! The section name (second part of the key) used for makernote tags
|
||||
std::string sectionName_;
|
||||
//! The item name (second part of the key) used for makernote tags
|
||||
std::string ifdItem_;
|
||||
|
||||
}; // class Nikon3MakerNote
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
*/
|
||||
/*
|
||||
File: sigmamn.cpp
|
||||
Version: $Name: $ $Revision: 1.8 $
|
||||
Version: $Name: $ $Revision: 1.9 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 02-Apr-04, ahu: created
|
||||
Credits: Sigma and Foveon MakerNote implemented according to the specification
|
||||
@ -29,7 +29,7 @@
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.8 $ $RCSfile: sigmamn.cpp,v $");
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.9 $ $RCSfile: sigmamn.cpp,v $");
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -83,7 +83,7 @@ namespace Exiv2 {
|
||||
};
|
||||
|
||||
SigmaMakerNote::SigmaMakerNote(bool alloc)
|
||||
: IfdMakerNote(sigmaMnTagInfo, alloc), sectionName_("Sigma")
|
||||
: IfdMakerNote(sigmaMnTagInfo, alloc), ifdItem_("Sigma")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
@brief Sigma and Foveon MakerNote implemented according to the specification
|
||||
<a href="http://www.x3f.info/technotes/FileDocs/MakerNoteDoc.html">
|
||||
SIGMA and FOVEON EXIF MakerNote Documentation</a> by Foveon.
|
||||
@version $Name: $ $Revision: 1.6 $
|
||||
@version $Name: $ $Revision: 1.7 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 02-Apr-04, ahu: created
|
||||
@ -105,8 +105,8 @@ namespace Exiv2 {
|
||||
//@{
|
||||
int checkHeader() const;
|
||||
SigmaMakerNote* clone(bool alloc =true) const;
|
||||
//! Return the name of the makernote section ("Sigma")
|
||||
std::string sectionName(uint16 tag) const { return sectionName_; }
|
||||
//! Return the name of the makernote item ("Sigma")
|
||||
std::string ifdItem() const { return ifdItem_; }
|
||||
std::ostream& printTag(std::ostream& os,
|
||||
uint16 tag,
|
||||
const Value& value) const;
|
||||
@ -148,8 +148,8 @@ namespace Exiv2 {
|
||||
*/
|
||||
static const RegisterMakerNote register_;
|
||||
|
||||
//! The section name (second part of the key) used for makernote tags
|
||||
std::string sectionName_;
|
||||
//! The item name (second part of the key) used for makernote tags
|
||||
std::string ifdItem_;
|
||||
|
||||
}; // class SigmaMakerNote
|
||||
|
||||
|
||||
@ -3,13 +3,13 @@
|
||||
Abstract: Print a simple comma separated list of tags defined in Exiv2
|
||||
|
||||
File: taglist.cpp
|
||||
Version: $Name: $ $Revision: 1.8 $
|
||||
Version: $Name: $ $Revision: 1.9 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 07-Jan-04, ahu: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.8 $ $RCSfile: taglist.cpp,v $");
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.9 $ $RCSfile: taglist.cpp,v $");
|
||||
|
||||
#include "makernote.hpp"
|
||||
#include "nikonmn.hpp"
|
||||
@ -33,28 +33,28 @@ try {
|
||||
case 2:
|
||||
{
|
||||
MakerNote* pMakerNote = 0;
|
||||
std::string section(argv[1]);
|
||||
if (section == "Iptc") {
|
||||
std::string item(argv[1]);
|
||||
if (item == "Iptc") {
|
||||
IptcDataSets::dataSetList(std::cout);
|
||||
break;
|
||||
}
|
||||
|
||||
if (section == "Canon") {
|
||||
if (item == "Canon") {
|
||||
pMakerNote = new CanonMakerNote;
|
||||
}
|
||||
else if (section == "Fuji") {
|
||||
else if (item == "Fujifilm") {
|
||||
pMakerNote = new FujiMakerNote;
|
||||
}
|
||||
else if (section == "Sigma") {
|
||||
else if (item == "Sigma") {
|
||||
pMakerNote = new SigmaMakerNote;
|
||||
}
|
||||
else if (section == "Nikon1") {
|
||||
else if (item == "Nikon1") {
|
||||
pMakerNote = new Nikon1MakerNote;
|
||||
}
|
||||
else if (section == "Nikon2") {
|
||||
else if (item == "Nikon2") {
|
||||
pMakerNote = new Nikon2MakerNote;
|
||||
}
|
||||
else if (section == "Nikon3") {
|
||||
else if (item == "Nikon3") {
|
||||
pMakerNote = new Nikon3MakerNote;
|
||||
}
|
||||
|
||||
@ -76,7 +76,8 @@ try {
|
||||
break;
|
||||
}
|
||||
if (rc) {
|
||||
std::cout << "Usage: " << argv[0] << " [SectionName|Iptc]\n"
|
||||
std::cout << "Usage: " << argv[0]
|
||||
<< " [Canon|Fujifilm|Nikon1|Nikon2|Nikon3|Sigma|Iptc]\n"
|
||||
<< "Print Exif tags, MakerNote tags, or Iptc datasets\n";
|
||||
}
|
||||
return rc;
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
################################################################################
|
||||
# File : tags.awk
|
||||
# Version : $Name: $ $Revision: 1.3 $
|
||||
# Version : $Name: $ $Revision: 1.4 $
|
||||
# Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
# History : 07-Feb-04, ahu: created
|
||||
#
|
||||
# Description:
|
||||
# Awk script to convert a taglist to XML format used in the documentation.
|
||||
# $ taglist [SectionName] | awk -f tags.awk > tags.xml
|
||||
# $ taglist [itemName] | awk -f tags.awk > tags.xml
|
||||
################################################################################
|
||||
|
||||
BEGIN {
|
||||
|
||||
79
src/tags.cpp
79
src/tags.cpp
@ -20,13 +20,13 @@
|
||||
*/
|
||||
/*
|
||||
File: tags.cpp
|
||||
Version: $Name: $ $Revision: 1.32 $
|
||||
Version: $Name: $ $Revision: 1.33 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 15-Jan-04, ahu: created
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.32 $ $RCSfile: tags.cpp,v $");
|
||||
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.33 $ $RCSfile: tags.cpp,v $");
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
@ -50,15 +50,16 @@ namespace Exiv2 {
|
||||
{
|
||||
}
|
||||
|
||||
// Important: IFD item must be unique!
|
||||
const IfdInfo ExifTags::ifdInfo_[] = {
|
||||
IfdInfo(ifdIdNotSet, "(Unknown IFD)", "(Unknown data area)"),
|
||||
IfdInfo(ifdIdNotSet, "(Unknown IFD)", "(Unknown item)"),
|
||||
IfdInfo(ifd0, "IFD0", "Image"),
|
||||
IfdInfo(exifIfd, "Exif", "Image"),
|
||||
IfdInfo(gpsIfd, "GPSInfo", "Image"),
|
||||
IfdInfo(exifIfd, "Exif", "Photo"), // just to avoid 'Exif.Exif.*' keys
|
||||
IfdInfo(gpsIfd, "GPSInfo", "GPSInfo"),
|
||||
IfdInfo(makerIfd, "Makernote", "Makernote"),
|
||||
IfdInfo(iopIfd, "Iop", "Image"),
|
||||
IfdInfo(iopIfd, "Iop", "Iop"),
|
||||
IfdInfo(ifd1, "IFD1", "Thumbnail"),
|
||||
IfdInfo(lastIfdId, "(Last IFD info)", "(Last IFD info)")
|
||||
IfdInfo(lastIfdId, "(Last IFD info)", "(Last IFD item)")
|
||||
};
|
||||
|
||||
SectionInfo::SectionInfo(
|
||||
@ -265,6 +266,8 @@ namespace Exiv2 {
|
||||
0
|
||||
};
|
||||
|
||||
const char* ExifTags::familyName_ = "Exif";
|
||||
|
||||
int ExifTags::tagInfoIdx(uint16 tag, IfdId ifdId)
|
||||
{
|
||||
const TagInfo* tagInfo = tagInfos_[ifdId];
|
||||
@ -276,17 +279,6 @@ namespace Exiv2 {
|
||||
return idx;
|
||||
}
|
||||
|
||||
int ExifTags::tagInfoIdx(const std::string& tagName, IfdId ifdId)
|
||||
{
|
||||
const TagInfo* tagInfo = tagInfos_[ifdId];
|
||||
if (tagInfo == 0) return -1;
|
||||
int idx;
|
||||
for (idx = 0; tagInfo[idx].tag_ != 0xffff; ++idx) {
|
||||
if (tagInfo[idx].name_ == tagName) break;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
const char* ExifTags::tagName(uint16 tag, IfdId ifdId)
|
||||
{
|
||||
int idx = tagInfoIdx(tag, ifdId);
|
||||
@ -317,6 +309,17 @@ namespace Exiv2 {
|
||||
return sectionInfo_[tagInfo[idx].sectionId_].desc_;
|
||||
}
|
||||
|
||||
uint16 ExifTags::tag(const std::string& tagName, IfdId ifdId)
|
||||
{
|
||||
const TagInfo* tagInfo = tagInfos_[ifdId];
|
||||
if (tagInfo == 0) return 0xffff;
|
||||
int idx;
|
||||
for (idx = 0; tagInfo[idx].tag_ != 0xffff; ++idx) {
|
||||
if (tagInfo[idx].name_ == tagName) break;
|
||||
}
|
||||
return tagInfo[idx].tag_;
|
||||
}
|
||||
|
||||
const char* ExifTags::ifdName(IfdId ifdId)
|
||||
{
|
||||
return ifdInfo_[ifdId].name_;
|
||||
@ -343,8 +346,8 @@ namespace Exiv2 {
|
||||
|
||||
std::string ExifTags::makeKey(uint16 tag, IfdId ifdId)
|
||||
{
|
||||
return std::string(ifdItem(ifdId))
|
||||
+ "." + std::string(sectionName(tag, ifdId))
|
||||
return std::string(familyName())
|
||||
+ "." + std::string(ifdItem(ifdId))
|
||||
+ "." + std::string(tagName(tag, ifdId));
|
||||
}
|
||||
|
||||
@ -352,41 +355,31 @@ namespace Exiv2 {
|
||||
// we find, it doesn't verify whether this is the only match.
|
||||
std::pair<uint16, IfdId> ExifTags::decomposeKey(const std::string& key)
|
||||
{
|
||||
// Get the IFD, section name and tag name parts of the key
|
||||
// Get the family name, IFD name and tag name parts of the key
|
||||
std::string::size_type pos1 = key.find('.');
|
||||
if (pos1 == std::string::npos) throw Error("Invalid key");
|
||||
std::string ifdItem = key.substr(0, pos1);
|
||||
std::string familyName = key.substr(0, pos1);
|
||||
if (familyName != std::string(ExifTags::familyName())) {
|
||||
throw Error("Invalid key");
|
||||
}
|
||||
std::string::size_type pos0 = pos1 + 1;
|
||||
pos1 = key.find('.', pos0);
|
||||
if (pos1 == std::string::npos) throw Error("Invalid key");
|
||||
std::string sectionName = key.substr(pos0, pos1 - pos0);
|
||||
std::string ifdItem = key.substr(pos0, pos1 - pos0);
|
||||
pos0 = pos1 + 1;
|
||||
std::string tagName = key.substr(pos0);
|
||||
if (tagName == "") throw Error("Invalid key");
|
||||
|
||||
// Check if this is a MakerNote key, stop processing if it is
|
||||
if (ifdItem == ifdInfo_[makerIfd].item_) {
|
||||
return std::make_pair(0xffff, makerIfd);
|
||||
// Find IfdId
|
||||
int i;
|
||||
for (i = int(lastIfdId) - 1; i > 0; --i) {
|
||||
if (ifdInfo_[i].item_ == ifdItem) break;
|
||||
}
|
||||
IfdId ifdId = IfdId(i);
|
||||
|
||||
// Use the parts of the key to find tag and IFD id
|
||||
IfdId ifdId = ifdIdNotSet;
|
||||
uint16 tag = 0xffff;
|
||||
if (ifdId == ifdIdNotSet) return std::make_pair(0xffff, ifdId);
|
||||
|
||||
SectionId s = sectionId(sectionName);
|
||||
if (s == sectionIdNotSet) return std::make_pair(tag, ifdId);
|
||||
|
||||
for (int i = 0; i < lastIfdId; ++i) {
|
||||
if (ifdInfo_[i].item_ == ifdItem) {
|
||||
ifdId = ifdInfo_[i].ifdId_;
|
||||
int k = tagInfoIdx(tagName, ifdId);
|
||||
if (k != -1 && tagInfos_[ifdId][k].sectionId_ == s) {
|
||||
tag = tagInfos_[ifdId][k].tag_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::make_pair(tag, ifdId);
|
||||
return std::make_pair(tag(tagName, ifdId), ifdId);
|
||||
} // ExifTags::decomposeKey
|
||||
|
||||
std::ostream& ExifTags::printTag(std::ostream& os,
|
||||
|
||||
13
src/tags.hpp
13
src/tags.hpp
@ -21,7 +21,7 @@
|
||||
/*!
|
||||
@file tags.hpp
|
||||
@brief Exif tag and type information
|
||||
@version $Name: $ $Revision: 1.24 $
|
||||
@version $Name: $ $Revision: 1.25 $
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 15-Jan-04, ahu: created<BR>
|
||||
@ -72,7 +72,8 @@ namespace Exiv2 {
|
||||
IfdInfo(IfdId ifdId, const char* name, const char* item);
|
||||
IfdId ifdId_; //!< IFD id
|
||||
const char* name_; //!< IFD name
|
||||
const char* item_; //!< Related image item
|
||||
//! Related IFD item. This is also an IFD name, unique for each IFD.
|
||||
const char* item_;
|
||||
};
|
||||
|
||||
//! Contains information pertaining to one section
|
||||
@ -113,6 +114,9 @@ namespace Exiv2 {
|
||||
ExifTags& operator=(const ExifTags& rhs);
|
||||
|
||||
public:
|
||||
//! Return an identifier for Exif metadata
|
||||
static const char* familyName() { return familyName_; }
|
||||
|
||||
/*!
|
||||
@brief Return the name of the tag.
|
||||
@param tag The tag
|
||||
@ -167,7 +171,7 @@ namespace Exiv2 {
|
||||
static SectionId sectionId(const std::string& sectionName);
|
||||
/*!
|
||||
@brief Return the key for the tag and IFD id. The key is of the form
|
||||
'ifdItem.sectionName.tagName'.
|
||||
'<b>Exif</b>.ifdItem.tagName'.
|
||||
*/
|
||||
static std::string makeKey(uint16 tag, IfdId ifdId);
|
||||
/*!
|
||||
@ -187,7 +191,8 @@ namespace Exiv2 {
|
||||
|
||||
private:
|
||||
static int tagInfoIdx(uint16 tag, IfdId ifdId);
|
||||
static int tagInfoIdx(const std::string& tagName, IfdId ifdId);
|
||||
|
||||
static const char* familyName_;
|
||||
|
||||
static const IfdInfo ifdInfo_[];
|
||||
static const SectionInfo sectionInfo_[];
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
Abstract : ExifData write unit tests
|
||||
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
Version : $Name: $ $Revision: 1.7 $
|
||||
Version : $Name: $ $Revision: 1.8 $
|
||||
|
||||
Test procedure:
|
||||
$ rm -f test.jpg thumb.jpg iii ttt;
|
||||
@ -59,77 +59,77 @@ try {
|
||||
std::cerr << "Case 1: ";
|
||||
std::cerr << "Non-intrusive change to the standard Exif metadata\n";
|
||||
testCase(testFile, "test1.jpg", "thumb1",
|
||||
"Image.DateTime.DateTimeOriginal",
|
||||
"Exif.Photo.DateTimeOriginal",
|
||||
"1999:11:22 00:11:22");
|
||||
break;
|
||||
case 2:
|
||||
std::cerr << "Case 2: ";
|
||||
std::cerr << "Non-intrusive change to the makernote metadata\n";
|
||||
testCase(testFile, "test2.jpg", "thumb2",
|
||||
"Makernote.Canon.OwnerName",
|
||||
"Exif.Canon.OwnerName",
|
||||
"Chan YeeSend");
|
||||
break;
|
||||
case 3:
|
||||
std::cerr << "Case 3: ";
|
||||
std::cerr << "Non-intrusive change to the Exif metadata (w/o makernote)\n";
|
||||
testCase(testFile, "test3.jpg", "thumb3",
|
||||
"Image.DateTime.DateTimeOriginal",
|
||||
"Exif.Photo.DateTimeOriginal",
|
||||
"1999:11:22 00:11:22");
|
||||
break;
|
||||
case 4:
|
||||
std::cerr << "Case 4: ";
|
||||
std::cerr << "Intrusive change to the standard Exif metadata\n";
|
||||
testCase(testFile, "test4.jpg", "thumb4",
|
||||
"Image.DateTime.DateTimeOriginal",
|
||||
"Exif.Photo.DateTimeOriginal",
|
||||
"1999:11:22 00:11:22 and twenty seconds");
|
||||
break;
|
||||
case 5:
|
||||
std::cerr << "Case 5: ";
|
||||
std::cerr << "Intrusive change to the Canon makernote metadata\n";
|
||||
testCase(testFile, "test5.jpg", "thumb5",
|
||||
"Makernote.Canon.OwnerName",
|
||||
"Exif.Canon.OwnerName",
|
||||
"Frau Chan YeeSend und Herr Andreas Huggel");
|
||||
break;
|
||||
case 6:
|
||||
std::cerr << "Case 6: ";
|
||||
std::cerr << "Intrusive change to the Exif metadata (w/o makernote)\n";
|
||||
testCase(testFile, "test6.jpg", "thumb6",
|
||||
"Image.DateTime.DateTimeOriginal",
|
||||
"Exif.Photo.DateTimeOriginal",
|
||||
"1999:11:22 00:11:22 and twenty seconds");
|
||||
break;
|
||||
case 7:
|
||||
std::cerr << "Case 7: ";
|
||||
std::cerr << "Intrusive change to the Fujifilm makernote metadata\n";
|
||||
testCase(testFile, "test7.jpg", "thumb7",
|
||||
"Makernote.Fujifilm.Quality",
|
||||
"Exif.Fujifilm.Quality",
|
||||
"Typical Fujifilm Quality");
|
||||
break;
|
||||
case 8:
|
||||
std::cerr << "Case 8: ";
|
||||
std::cerr << "Intrusive change to the Sigma makernote metadata\n";
|
||||
testCase(testFile, "test8.jpg", "thumb8",
|
||||
"Makernote.Sigma.ResolutionMode",
|
||||
"Exif.Sigma.ResolutionMode",
|
||||
"Sigma HI resolution");
|
||||
break;
|
||||
case 9:
|
||||
std::cerr << "Case 9: ";
|
||||
std::cerr << "Intrusive change to the Nikon1 makernote metadata\n";
|
||||
testCase(testFile, "test9.jpg", "thumb9",
|
||||
"Makernote.Nikon1.Quality",
|
||||
"Exif.Nikon1.Quality",
|
||||
"Typical Nikon1 Quality");
|
||||
break;
|
||||
case 10:
|
||||
std::cerr << "Case 10: ";
|
||||
std::cerr << "Intrusive change to the Nikon2 makernote metadata\n";
|
||||
testCase(testFile, "test10.jpg", "thumb10",
|
||||
"Makernote.Nikon2.0x0002",
|
||||
"Exif.Nikon2.0x0002",
|
||||
"Nikon2 Version 2");
|
||||
break;
|
||||
case 11:
|
||||
std::cerr << "Case 11: ";
|
||||
std::cerr << "Intrusive change to the Nikon3 makernote metadata\n";
|
||||
testCase(testFile, "test11.jpg", "thumb11",
|
||||
"Makernote.Nikon3.Quality",
|
||||
"Exif.Nikon3.Quality",
|
||||
"Typical Nikon3 Quality");
|
||||
break;
|
||||
|
||||
@ -159,6 +159,7 @@ void testCase(const std::string& file1,
|
||||
const std::string& key,
|
||||
const std::string& value)
|
||||
{
|
||||
ExifKey ek(key);
|
||||
ExifData ed1;
|
||||
|
||||
std::cerr << "---> Reading file " << file1 << "\n";
|
||||
@ -169,9 +170,9 @@ void testCase(const std::string& file1,
|
||||
}
|
||||
|
||||
std::cerr << "---> Modifying Exif data\n";
|
||||
Exiv2::ExifData::iterator pos = ed1.findKey(key);
|
||||
Exiv2::ExifData::iterator pos = ed1.findKey(ek);
|
||||
if (pos == ed1.end()) {
|
||||
throw Error("Metadatum with key = " + key + " not found");
|
||||
throw Error("Metadatum with key = " + ek.key() + " not found");
|
||||
}
|
||||
pos->setValue(value);
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
Abstract : ExifData write unit tests for Exif data created from scratch
|
||||
|
||||
File : write2-test.cpp
|
||||
Version : $Name: $ $Revision: 1.4 $
|
||||
Version : $Name: $ $Revision: 1.5 $
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History : 26-Jun-04, ahu: created
|
||||
|
||||
@ -31,7 +31,7 @@ try {
|
||||
|
||||
std::cout <<"----- One IFD0 tag\n";
|
||||
Exiv2::ExifData ed1;
|
||||
Exiv2::Exifdatum md1(Exiv2::ExifKey("Image.OtherTags.Model"));
|
||||
Exiv2::Exifdatum md1(Exiv2::ExifKey("Exif.Image.Model"));
|
||||
md1.setValue("Test 1");
|
||||
ed1.add(md1);
|
||||
write(file, ed1);
|
||||
@ -39,7 +39,7 @@ try {
|
||||
|
||||
std::cout <<"\n----- One Exif tag\n";
|
||||
Exiv2::ExifData ed2;
|
||||
Exiv2::Exifdatum md2(Exiv2::ExifKey("Image.DateTime.DateTimeOriginal"));
|
||||
Exiv2::Exifdatum md2(Exiv2::ExifKey("Exif.Photo.DateTimeOriginal"));
|
||||
md2.setValue("Test 2");
|
||||
ed2.add(md2);
|
||||
write(file, ed2);
|
||||
@ -49,7 +49,7 @@ try {
|
||||
|
||||
std::cout <<"\n----- One IOP tag\n";
|
||||
Exiv2::ExifData ed3;
|
||||
Exiv2::Exifdatum md3(Exiv2::ExifKey("Image.Interoperability.InteroperabilityVersion"));
|
||||
Exiv2::Exifdatum md3(Exiv2::ExifKey("Exif.Iop.InteroperabilityVersion"));
|
||||
md3.setValue("Test 3");
|
||||
ed3.add(md3);
|
||||
write(file, ed3);
|
||||
@ -57,7 +57,7 @@ try {
|
||||
|
||||
std::cout <<"\n----- One GPS tag\n";
|
||||
Exiv2::ExifData ed4;
|
||||
Exiv2::Exifdatum md4(Exiv2::ExifKey("Image.GPS.GPSVersionID"));
|
||||
Exiv2::Exifdatum md4(Exiv2::ExifKey("Exif.GPSInfo.GPSVersionID"));
|
||||
md4.setValue("Test 4");
|
||||
ed4.add(md4);
|
||||
write(file, ed4);
|
||||
@ -66,11 +66,11 @@ try {
|
||||
// Todo: Fix this
|
||||
std::cout <<"\n----- One IFD1 tag\n";
|
||||
Exiv2::ExifData ed5;
|
||||
Exiv2::Exifdatum md5(Exiv2::ExifKey("Thumbnail.OtherTags.Artist"));
|
||||
Exiv2::Exifdatum md5(Exiv2::ExifKey("Exif.Thumbnail.Artist"));
|
||||
md5.setValue("Test 5");
|
||||
ed5.add(md5);
|
||||
|
||||
Exiv2::Exifdatum md6(Exiv2::ExifKey("Image.OtherTags.Model"));
|
||||
Exiv2::Exifdatum md6(Exiv2::ExifKey("Exif.Image.Model"));
|
||||
md6.setValue("Test 5 (Fix me!)");
|
||||
ed5.add(md6);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user