[SCM] exiv2 packaging branch, master, updated. debian/0.25-3.1-3734-gdcbc29a
Maximiliano Curia
maxy at moszumanska.debian.org
Thu Jul 13 17:36:17 UTC 2017
Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-extras/exiv2.git;a=commitdiff;h=0b24a0a
The following commit has been merged in the master branch:
commit 0b24a0ad293e9a8b79d83b25ae41ac27bee3add9
Author: Andreas Huggel <ahuggel at gmx.net>
Date: Fri May 7 05:09:57 2004 +0000
makernote:
Added MakerNote::offset()
Fixed IfdMakerNote::copy() for IfdMakerNote with a prefix
Various doc fixes
ifd:
Fixed Ifd::erase(pos) to return an iterator
Added Ifd::dataOffset()
Various doc fixes
exif:
Added Thumbnail::offset()
Fixed ExifData::eraseThumbnail()
Fixed ExifData::erase(pos) to return an iterator
---
src/exif.cpp | 140 +++++++++++++++++++++++++++++++++++++++++-------------
src/exif.hpp | 83 ++++++++++++++++++++++----------
src/ifd.cpp | 43 ++++++++++-------
src/ifd.hpp | 25 +++++++---
src/makernote.cpp | 30 ++++++++----
src/makernote.hpp | 30 +++++++-----
6 files changed, 251 insertions(+), 100 deletions(-)
diff --git a/src/exif.cpp b/src/exif.cpp
index c571003..2b28adc 100644
--- a/src/exif.cpp
+++ b/src/exif.cpp
@@ -20,14 +20,14 @@
*/
/*
File: exif.cpp
- Version: $Name: $ $Revision: 1.39 $
+ Version: $Name: $ $Revision: 1.40 $
Author(s): Andreas Huggel (ahu) <ahuggel at gmx.net>
History: 26-Jan-04, ahu: created
11-Feb-04, ahu: isolated as a component
*/
// *****************************************************************************
#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Name: $ $Revision: 1.39 $ $RCSfile: exif.cpp,v $")
+EXIV2_RCSID("@(#) $Name: $ $Revision: 1.40 $ $RCSfile: exif.cpp,v $")
// Define DEBUG_MAKERNOTE to output debug information to std::cerr
#undef DEBUG_MAKERNOTE
@@ -159,7 +159,7 @@ namespace Exif {
}
TiffThumbnail::TiffThumbnail()
- : size_(0), pImage_(0), ifd_(ifd1, 0, false)
+ : offset_(0), size_(0), pImage_(0), ifd_(ifd1, 0, false)
{
}
@@ -169,7 +169,8 @@ namespace Exif {
}
TiffThumbnail::TiffThumbnail(const TiffThumbnail& rhs)
- : size_(rhs.size_), pImage_(0), ifd_(ifd1, 0, false)
+ : offset_(rhs.offset_), size_(rhs.size_), pImage_(0),
+ ifd_(ifd1, 0, false)
{
if (rhs.pImage_ && rhs.size_ > 0) {
pImage_ = new char[rhs.size_];
@@ -190,6 +191,7 @@ namespace Exif {
ifd_.read(pNewImage + tiffHeader_.offset(),
tiffHeader_.byteOrder(), tiffHeader_.offset());
}
+ offset_ = rhs.offset_;
size_ = rhs.size_;
delete[] pImage_;
pImage_ = pNewImage;
@@ -212,10 +214,8 @@ namespace Exif {
// Create IFD (without Exif and GPS tags) from metadata
Ifd ifd1(ifd1);
addToIfd(ifd1, exifData.begin(), exifData.end(), tiffHeader.byteOrder());
- Ifd::iterator i = ifd1.findTag(0x8769);
- if (i != ifd1.end()) ifd1.erase(i);
- i = ifd1.findTag(0x8825);
- if (i != ifd1.end()) ifd1.erase(i);
+ ifd1.erase(0x8769);
+ ifd1.erase(0x8825);
// Do not copy the IFD yet, remember the location and leave a gap
long ifdOffset = len;
@@ -229,19 +229,23 @@ namespace Exif {
ExifData::const_iterator sizes = exifData.findKey(key);
if (sizes == exifData.end()) return 2;
std::ostringstream os; // for the new strip offsets
+ long minOffset = 0;
for (long k = 0; k < offsets->count(); ++k) {
long offset = offsets->toLong(k);
long size = sizes->toLong(k);
memcpy(img.pData_ + len, buf + offset, size);
os << len << " ";
len += size;
- }
+ minOffset = offset; // just to initialize minOffset
+ }
+ for (long k = 0; k < offsets->count(); ++k) {
+ minOffset = std::min(minOffset, offsets->toLong(k));
+ }
// Update the IFD with the actual strip offsets (replace existing entry)
Metadatum newOffsets(*offsets);
newOffsets.setValue(os.str());
- i = ifd1.findTag(0x0111);
- if (i != ifd1.end()) ifd1.erase(i);
+ ifd1.erase(0x0111);
addToIfd(ifd1, newOffsets, tiffHeader.byteOrder());
// Finally, sort and copy the IFD
@@ -252,6 +256,7 @@ namespace Exif {
pImage_ = new char[len];
memcpy(pImage_, img.pData_, len);
size_ = len;
+ offset_ = minOffset;
tiffHeader_.read(pImage_);
ifd_.read(pImage_ + tiffHeader_.offset(),
tiffHeader_.byteOrder(), tiffHeader_.offset());
@@ -326,7 +331,12 @@ namespace Exif {
return size_;
}
- void TiffThumbnail::setOffsets(Ifd& ifd1, ByteOrder byteOrder) const
+ long TiffThumbnail::offset() const
+ {
+ return offset_;
+ }
+
+ void TiffThumbnail::setOffsets(Ifd& ifd1, ByteOrder byteOrder)
{
// Adjust the StripOffsets, assuming that the existing TIFF strips
// start immediately after the thumbnail IFD
@@ -336,20 +346,25 @@ namespace Exif {
if (pos == ifd_.end()) throw Error("Bad thumbnail (0x0111)");
Metadatum offsets(*pos, tiffHeader_.byteOrder());
std::ostringstream os;
+ long minOffset = 0;
for (long k = 0; k < offsets.count(); ++k) {
os << offsets.toLong(k) + shift << " ";
+ minOffset = offsets.toLong(k) + shift; // initialize minOffset
}
offsets.setValue(os.str());
+ for (long k = 0; k < offsets.count(); ++k) {
+ minOffset = std::min(minOffset, offsets.toLong(k));
+ }
+ offset_ = minOffset;
// Update the IFD with the re-calculated strip offsets
// (replace existing entry)
- Ifd::iterator i = ifd1.findTag(0x0111);
- if (i != ifd1.end()) ifd1.erase(i);
+ ifd1.erase(0x0111);
addToIfd(ifd1, offsets, byteOrder);
} // TiffThumbnail::setOffsets
JpegThumbnail::JpegThumbnail()
- : size_(0), pImage_(0)
+ : offset_(0), size_(0), pImage_(0)
{
}
@@ -359,7 +374,7 @@ namespace Exif {
}
JpegThumbnail::JpegThumbnail(const JpegThumbnail& rhs)
- : size_(rhs.size_), pImage_(0)
+ : offset_(rhs.offset_), size_(rhs.size_), pImage_(0)
{
if (rhs.pImage_ && rhs.size_ > 0) {
pImage_ = new char[rhs.size_];
@@ -374,6 +389,7 @@ namespace Exif {
pNewImage = new char[rhs.size_];
memcpy(pNewImage, rhs.pImage_, rhs.size_);
}
+ offset_ = rhs.offset_;
size_ = rhs.size_;
delete[] pImage_;
pImage_ = pNewImage;
@@ -396,6 +412,7 @@ namespace Exif {
pImage_ = new char[size];
memcpy(pImage_, buf + offset, size);
size_ = size;
+ offset_ = offset;
return 0;
} // JpegThumbnail::read
@@ -429,7 +446,7 @@ namespace Exif {
delete value;
pos = exifData.findKey(key);
}
- pos->setValue("0");
+ pos->setValue(toString(offset_));
key = "Thumbnail.RecordingOffset.JPEGInterchangeFormatLength";
pos = exifData.findKey(key);
@@ -459,18 +476,24 @@ namespace Exif {
return size_;
}
- void JpegThumbnail::setOffsets(Ifd& ifd1, ByteOrder byteOrder) const
+ long JpegThumbnail::offset() const
+ {
+ return offset_;
+ }
+
+ void JpegThumbnail::setOffsets(Ifd& ifd1, ByteOrder byteOrder)
{
Ifd::iterator pos = ifd1.findTag(0x0201);
if (pos == ifd1.end()) throw Error("Bad thumbnail (0x0201)");
- pos->setValue(ifd1.offset() + ifd1.size() + ifd1.dataSize(), byteOrder);
+ offset_ = ifd1.offset() + ifd1.size() + ifd1.dataSize();
+ pos->setValue(offset_, byteOrder);
}
ExifData::ExifData()
: pThumbnail_(0), pMakerNote_(0), ifd0_(ifd0, 0, false),
exifIfd_(exifIfd, 0, false), iopIfd_(iopIfd, 0, false),
gpsIfd_(gpsIfd, 0, false), ifd1_(ifd1, 0, false),
- size_(0), pData_(0)
+ size_(0), pData_(0), compatible_(true)
{
}
@@ -571,7 +594,6 @@ namespace Exif {
ifd1_.erase(pos);
ret = -99;
}
-
// Copy all entries from the IFDs and the MakerNote to the metadata
metadata_.clear();
add(ifd0_.begin(), ifd0_.end(), byteOrder());
@@ -582,7 +604,6 @@ namespace Exif {
add(iopIfd_.begin(), iopIfd_.end(), byteOrder());
add(gpsIfd_.begin(), gpsIfd_.end(), byteOrder());
add(ifd1_.begin(), ifd1_.end(), byteOrder());
-
// Read the thumbnail
readThumbnail();
@@ -626,7 +647,7 @@ namespace Exif {
// If we can update the internal IFDs and the underlying data buffer
// from the metadata without changing the data size, then it is enough
// to copy the data buffer.
- if (updateEntries()) {
+ if (compatible_ && updateEntries()) {
#ifdef DEBUG_MAKERNOTE
std::cerr << "->>>>>> using non-intrusive writing <<<<<<-
";
#endif
@@ -845,28 +866,79 @@ namespace Exif {
std::sort(metadata_.begin(), metadata_.end(), cmpMetadataByTag);
}
- void ExifData::erase(ExifData::iterator pos)
+ ExifData::iterator ExifData::erase(ExifData::iterator pos)
{
- metadata_.erase(pos);
+ return metadata_.erase(pos);
}
long ExifData::eraseThumbnail()
{
// Delete all Thumbnail.*.* (IFD1) metadata
- for (Metadata::iterator i = begin(); i != end(); ++i) {
- if (i->ifdId() == ifd1) erase(i);
+ Metadata::iterator i = begin();
+ while (i != end()) {
+ if (i->ifdId() == ifd1) {
+ i = erase(i);
+ }
+ else {
+ ++i;
+ }
+ }
+ long delta = 0;
+ if (stdThumbPosition()) {
+ delta = size_;
+ if (size_ > 0 && ifd0_.next() > 0) {
+ // Truncate IFD1 and thumbnail data from the data buffer
+ size_ = ifd0_.next();
+ ifd0_.setNext(0, byteOrder());
+ }
+ delta -= size_;
+ }
+ else {
+ // We will have to write the hard way and re-arrange the data
+ compatible_ = false;
+ delta = ifd1_.size() + ifd1_.dataSize()
+ + pThumbnail_ ? pThumbnail_->size() : 0;
}
- // Truncate IFD1 and thumbnail data from the data buffer
- long delta = size_;
- if (size_ > 0) size_ = ifd0_.next();
- delta -= size_;
- ifd0_.setNext(0, byteOrder());
// Delete the thumbnail itself
- delete pThumbnail_;
- pThumbnail_ = 0;
+ if (pThumbnail_) {
+ delete pThumbnail_;
+ pThumbnail_ = 0;
+ }
return delta;
}
+ bool ExifData::stdThumbPosition() const
+ {
+ // Todo: There is still an invalid assumption here: The data of an IFD
+ // can be stored in multiple non-contiguous blocks. In this case,
+ // dataOffset + dataSize does not point to the end of the IFD data.
+ // in particular, this is potentially the case for the remaining Exif
+ // data in the presence of a known Makernote.
+ bool rc = true;
+ if (pThumbnail_) {
+ long maxOffset;
+ maxOffset = std::max(ifd0_.offset(), ifd0_.dataOffset());
+ maxOffset = std::max(maxOffset, exifIfd_.offset());
+ maxOffset = std::max(maxOffset, exifIfd_.dataOffset()
+ + exifIfd_.dataSize());
+ if (pMakerNote_) {
+ maxOffset = std::max(maxOffset, pMakerNote_->offset()
+ + pMakerNote_->size());
+ }
+ maxOffset = std::max(maxOffset, iopIfd_.offset());
+ maxOffset = std::max(maxOffset, iopIfd_.dataOffset()
+ + iopIfd_.dataSize());
+ maxOffset = std::max(maxOffset, gpsIfd_.offset());
+ maxOffset = std::max(maxOffset, gpsIfd_.dataOffset()
+ + gpsIfd_.dataSize());
+
+ if ( maxOffset > ifd1_.offset()
+ || maxOffset > ifd1_.dataOffset() && ifd1_.dataOffset() > 0
+ || maxOffset > pThumbnail_->offset()) rc = false;
+ }
+ return rc;
+ }
+
int ExifData::readThumbnail()
{
delete pThumbnail_;
diff --git a/src/exif.hpp b/src/exif.hpp
index 47006b3..735e3bb 100644
--- a/src/exif.hpp
+++ b/src/exif.hpp
@@ -21,7 +21,7 @@
/*!
@file exif.hpp
@brief Encoding and decoding of %Exif data
- @version $Name: $ $Revision: 1.37 $
+ @version $Name: $ $Revision: 1.38 $
@author Andreas Huggel (ahu)
<a href="mailto:ahuggel at gmx.net">ahuggel at gmx.net</a>
@date 09-Jan-04, ahu: created
@@ -271,6 +271,20 @@ namespace Exif {
virtual int read(const char* buf,
const ExifData& exifData,
ByteOrder byteOrder =littleEndian) =0;
+ /*!
+ @brief Update the internal offset and the thumbnail data offsets
+ in IFD1 assuming the thumbnail data follows immediately after
+ IFD1.
+
+ If the type of the thumbnail image is JPEG, JPEGInterchangeFormat is
+ set to point directly behind the data area of IFD1. If the type is
+ TIFF, StripOffsets from the thumbnail image are adjusted to point to
+ the strips, which have to follow immediately after IFD1. Use copy() to
+ write the thumbnail image data. The offset of IFD1 must be set
+ correctly. Changing the size or data size of IFD1 invalidates the
+ thumbnail data offsets set by this method.
+ */
+ virtual void setOffsets(Ifd& ifd1, ByteOrder byteOrder) =0;
//@}
//! @name Accessors
@@ -308,18 +322,10 @@ namespace Exif {
*/
virtual void update(ExifData& exifData) const =0;
/*!
- @brief Update the thumbnail data offsets in IFD1 assuming the
- thumbnail data follows immediately after IFD1.
-
- If the type of the thumbnail image is JPEG, JPEGInterchangeFormat is
- set to point directly behind the data area of IFD1. If the type is
- TIFF, StripOffsets from the thumbnail image are adjusted to point to
- the strips, which have to follow immediately after IFD1. Use copy() to
- write the thumbnail image data. The offset of IFD1 must be set
- correctly. Changing the size of IFD1 invalidates the thumbnail data
- offsets set by this method.
+ @brief Return the position of the thumbnail image data from the
+ start of the TIFF header in the original %Exif data.
*/
- virtual void setOffsets(Ifd& ifd1, ByteOrder byteOrder) const =0;
+ virtual long offset() const =0;
/*!
@brief Return the size of the thumbnail image (the size it
would occupy when extracted from the %Exif data)
@@ -364,6 +370,7 @@ namespace Exif {
int read(const char* buf,
const ExifData& exifData,
ByteOrder byteOrder =littleEndian);
+ void setOffsets(Ifd& ifd1, ByteOrder byteOrder);
//@}
//! @name Accessors
@@ -373,13 +380,15 @@ namespace Exif {
const char* extension() const;
long copy(char* buf) const;
void update(ExifData& exifData) const;
- void setOffsets(Ifd& ifd1, ByteOrder byteOrder) const;
+ long offset() const;
long size() const;
long dataSize() const;
//@}
private:
// DATA
+ long offset_; // Original offset of the thumbnail data
+ // from the start of the TIFF header
long size_; //!< Size of the image data
char* pImage_; //!< Thumbnail image data
TiffHeader tiffHeader_; //!< Thumbnail TIFF Header
@@ -407,6 +416,7 @@ namespace Exif {
int read(const char* buf,
const ExifData& exifData,
ByteOrder byteOrder =littleEndian);
+ void setOffsets(Ifd& ifd1, ByteOrder byteOrder);
//@}
//! @name Accessors
@@ -416,13 +426,15 @@ namespace Exif {
const char* extension() const;
long copy(char* buf) const;
void update(ExifData& exifData) const;
- void setOffsets(Ifd& ifd1, ByteOrder byteOrder) const;
+ long offset() const;
long size() const;
long dataSize() const;
//@}
private:
// DATA
+ long offset_; // Original offset of the thumbnail data
+ // from the start of the TIFF header
long size_; // Size of the image data
char* pImage_; // Thumbnail image data
@@ -562,7 +574,7 @@ namespace Exif {
buffer has enough memory. Otherwise the call results in
undefined behaviour.
@return Number of characters written to the buffer.
- */
+ */
long copy(char* buf);
/*!
@brief Add all (IFD) entries in the range from iterator position begin
@@ -586,8 +598,13 @@ namespace Exif {
multiple metadata with the same key.
*/
void add(const Metadatum& metadatum);
- //! Delete the metadatum at iterator position pos
- void erase(iterator pos);
+ /*!
+ @brief Delete the metadatum at iterator position pos, return the
+ position of the next metadatum. Note that iterators into
+ the metadata, including pos, are potentially invalidated
+ by this call.
+ */
+ iterator erase(iterator pos);
//! Sort metadata by key
void sortByKey();
//! Sort metadata by tag
@@ -617,8 +634,8 @@ namespace Exif {
iterator findIfdIdIdx(IfdId ifdId, int idx);
/*!
@brief Delete the thumbnail from the %Exif data. Removes all related
- (Thumbnail.*.*, i.e., IFD1) metadata as well.
- @return The number of bytes truncated from the original %Exif data.
+ (%Thumbnail.*.*, i.e., IFD1) metadata as well.
+ @return The number of bytes erased from the original %Exif data.
*/
long eraseThumbnail();
//@}
@@ -666,18 +683,21 @@ namespace Exif {
//! Returns the byte order as specified in the TIFF header
ByteOrder byteOrder() const { return tiffHeader_.byteOrder(); }
/*!
- @brief Write the thumbnail image to a file. The filename extension
- will be set according to the image type of the thumbnail, so
- the path should not include an extension.
+ @brief Write the thumbnail image to a file. A filename extension
+ is appended to path according to the image type of the
+ thumbnail, so the path should not include an extension.
*/
int writeThumbnail(const std::string& path) const
{ return pThumbnail_ ? pThumbnail_->write(path) : 0; }
- //! Return the file extension of the thumbnail image file
+ /*!
+ @brief Return a short string describing the format of the %Exif
+ thumbnail ("TIFF", "JPEG").
+ */
const char* thumbnailFormat() const
{ return pThumbnail_ ? pThumbnail_->format() : ""; }
/*!
- @brief Return the file extension for the format of the thumbnail
- (".tif", ".jpg").
+ @brief Return the file extension for the %Exif thumbnail depending
+ on the format (".tif", ".jpg").
*/
const char* thumbnailExtension() const
{ return pThumbnail_ ? pThumbnail_->extension() : ""; }
@@ -751,6 +771,12 @@ namespace Exif {
findEntry(IfdId ifdId, int idx) const;
//! Return a pointer to the internal IFD identified by its IFD id
const Ifd* getIfd(IfdId ifdId) const;
+ /*!
+ @brief Check if IFD1, the IFD1 data and thumbnail data are located at
+ the end of the Exif data. Return true, if they are or if there
+ is no thumbnail at all, else return false.
+ */
+ bool stdThumbPosition() const;
//@}
// DATA
@@ -770,6 +796,13 @@ namespace Exif {
long size_; //!< Size of the Exif raw data in bytes
char* pData_; //!< Exif raw data buffer
+ /*!
+ Can be set to false to indicate that non-intrusive writing is not
+ possible. If it is true (the default), then the compatibility checks
+ will be performed to determine which writing method to use.
+ */
+ bool compatible_;
+
}; // class ExifData
// *****************************************************************************
diff --git a/src/ifd.cpp b/src/ifd.cpp
index 89db135..c07176b 100644
--- a/src/ifd.cpp
+++ b/src/ifd.cpp
@@ -20,14 +20,14 @@
*/
/*
File: ifd.cpp
- Version: $Name: $ $Revision: 1.15 $
+ Version: $Name: $ $Revision: 1.16 $
Author(s): Andreas Huggel (ahu) <ahuggel at gmx.net>
History: 26-Jan-04, ahu: created
11-Feb-04, ahu: isolated as a component
*/
// *****************************************************************************
#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Name: $ $Revision: 1.15 $ $RCSfile: ifd.cpp,v $")
+EXIV2_RCSID("@(#) $Name: $ $Revision: 1.16 $ $RCSfile: ifd.cpp,v $")
// *****************************************************************************
// included header files
@@ -156,21 +156,24 @@ namespace Exif {
} // Entry::component
Ifd::Ifd(IfdId ifdId)
- : alloc_(true), ifdId_(ifdId), offset_(0), pNext_(0), next_(0)
+ : alloc_(true), ifdId_(ifdId), offset_(0), dataOffset_(0),
+ pNext_(0), next_(0)
{
pNext_ = new char[4];
memset(pNext_, 0x0, 4);
}
Ifd::Ifd(IfdId ifdId, uint32 offset)
- : alloc_(true), ifdId_(ifdId), offset_(offset), pNext_(0), next_(0)
+ : alloc_(true), ifdId_(ifdId), offset_(offset), dataOffset_(0),
+ pNext_(0), next_(0)
{
pNext_ = new char[4];
memset(pNext_, 0x0, 4);
}
Ifd::Ifd(IfdId ifdId, uint32 offset, bool alloc)
- : alloc_(alloc), ifdId_(ifdId), offset_(offset), pNext_(0), next_(0)
+ : alloc_(alloc), ifdId_(ifdId), offset_(offset), dataOffset_(0),
+ pNext_(0), next_(0)
{
if (alloc_) {
pNext_ = new char[4];
@@ -185,7 +188,8 @@ namespace Exif {
Ifd::Ifd(const Ifd& rhs)
: alloc_(rhs.alloc_), entries_(rhs.entries_), ifdId_(rhs.ifdId_),
- offset_(rhs.offset_), pNext_(rhs.pNext_), next_(rhs.next_)
+ offset_(rhs.offset_), dataOffset_(rhs.dataOffset_),
+ pNext_(rhs.pNext_), next_(rhs.next_)
{
if (alloc_ && rhs.pNext_) {
pNext_ = new char[4];
@@ -221,18 +225,24 @@ namespace Exif {
}
next_ = getULong(buf+o, byteOrder);
- // Guess the offset of the IFD, if it was not given. The guess is based
- // on the assumption that the smallest offset points to a data buffer
- // directly following the IFD. Subsequently all offsets of IFD entries
- // will need to be recalculated.
- if (offset_ == 0 && preEntries.size() > 0) {
+ // Set the offset of the first data entry outside of the IFD.
+ // At the same time we guess the offset of the IFD, if it was not
+ // given. The guess is based on the assumption that the smallest offset
+ // points to a data buffer directly following the IFD. Subsequently all
+ // offsets of IFD entries will need to be recalculated.
+ if (preEntries.size() > 0) {
// Find the entry with the smallest offset
Ifd::PreEntries::const_iterator i = std::min_element(
preEntries.begin(), preEntries.end(), cmpPreEntriesByOffset);
- // Set the 'guessed' IFD offset, the test is needed for the case when
- // all entries have data sizes not exceeding 4.
+ // Only do something if there is at least one entry with data
+ // outside the IFD directory itself.
if (i->size_ > 4) {
- offset_ = i->offset_ - size();
+ if (offset_ == 0) {
+ // Set the 'guessed' IFD offset
+ offset_ = i->offset_ - size();
+ }
+ // Set the offset of the first data entry outside of the IFD
+ dataOffset_ = i->offset_;
}
}
@@ -362,6 +372,7 @@ namespace Exif {
pNext_ = 0;
}
offset_ = 0;
+ dataOffset_ = 0;
} // Ifd::clear
void Ifd::setNext(uint32 next, ByteOrder byteOrder)
@@ -390,9 +401,9 @@ namespace Exif {
return idx;
}
- void Ifd::erase(iterator pos)
+ Ifd::iterator Ifd::erase(iterator pos)
{
- entries_.erase(pos);
+ return entries_.erase(pos);
}
long Ifd::size() const
diff --git a/src/ifd.hpp b/src/ifd.hpp
index c8e0dc6..01b5a4c 100644
--- a/src/ifd.hpp
+++ b/src/ifd.hpp
@@ -21,7 +21,7 @@
/*!
@file ifd.hpp
@brief Encoding and decoding of IFD (Image File Directory) data
- @version $Name: $ $Revision: 1.13 $
+ @version $Name: $ $Revision: 1.14 $
@author Andreas Huggel (ahu)
<a href="mailto:ahuggel at gmx.net">ahuggel at gmx.net</a>
@date 09-Jan-04, ahu: created
@@ -385,8 +385,13 @@ namespace Exif {
of the deleted entry or 0 if no entry with tag was found.
*/
int erase(uint16 tag);
- //! Delete the directory entry at iterator position pos
- void erase(iterator pos);
+ /*!
+ @brief Delete the directory entry at iterator position pos, return the
+ position of the next entry. Note that iterators into the
+ directory, including pos, are potentially invalidated by this
+ call.
+ */
+ iterator erase(iterator pos);
//! Sort the IFD entries by tag
void sortByTag();
//! The first entry
@@ -415,6 +420,12 @@ namespace Exif {
IfdId ifdId() const { return ifdId_; }
//! Get the offset of the IFD from the start of the TIFF header
long offset() const { return offset_; }
+ /*!
+ @brief Get the offset of the first data entry outside of the IFD,
+ return 0 if there is none. The data offset is determined when
+ the IFD is read.
+ */
+ long dataOffset() const { return dataOffset_; }
//! Get the offset to the next IFD from the start of the TIFF header
uint32 next() const { return next_; }
//! Get the number of directory entries in the IFD
@@ -462,11 +473,13 @@ namespace Exif {
Entries entries_;
//! IFD Id
IfdId ifdId_;
- //! offset of the IFD from the start of TIFF header
+ //! Offset of the IFD from the start of TIFF header
long offset_;
- // Pointer to the offset of next IFD from the start of the TIFF header
+ //! Offset of the first data entry outside of the IFD directory
+ long dataOffset_;
+ //! Pointer to the offset of next IFD from the start of the TIFF header
char* pNext_;
- // The offset of the next IFD as data value (always in sync with *pNext_)
+ //! The offset of the next IFD as data value (always in sync with *pNext_)
uint32 next_;
}; // class Ifd
diff --git a/src/makernote.cpp b/src/makernote.cpp
index f9fb06b..16a3926 100644
--- a/src/makernote.cpp
+++ b/src/makernote.cpp
@@ -20,13 +20,13 @@
*/
/*
File: makernote.cpp
- Version: $Name: $ $Revision: 1.15 $
+ Version: $Name: $ $Revision: 1.16 $
Author(s): Andreas Huggel (ahu) <ahuggel at gmx.net>
History: 18-Feb-04, ahu: created
*/
// *****************************************************************************
#include "rcsid.hpp"
-EXIV2_RCSID("@(#) $Name: $ $Revision: 1.15 $ $RCSfile: makernote.cpp,v $")
+EXIV2_RCSID("@(#) $Name: $ $Revision: 1.16 $ $RCSfile: makernote.cpp,v $")
// Define DEBUG_MAKERNOTE to output debug information to std::cerr
#undef DEBUG_MAKERNOTE
@@ -155,6 +155,8 @@ namespace Exif {
ByteOrder byteOrder,
long offset)
{
+ // Remember the offset
+ offset_ = offset;
// Set byte order if none is set yet
if (byteOrder_ == invalidByteOrder) byteOrder_ = byteOrder;
int rc = 0;
@@ -182,7 +184,6 @@ namespace Exif {
i->setMakerNote(this);
}
}
-
#ifdef DEBUG_MAKERNOTE
hexdump(std::cerr, buf, len, offset);
if (rc == 0) ifd_.print(std::cerr);
@@ -193,10 +194,23 @@ namespace Exif {
long IfdMakerNote::copy(char* buf, ByteOrder byteOrder, long offset)
{
+ // Remember the new offset
+ offset_ = offset;
// Set byte order if none is set yet
if (byteOrder_ == invalidByteOrder) byteOrder_ = byteOrder;
- return ifd_.copy(buf, byteOrder_, offset);
- }
+ long len = 0;
+ if (!prefix_.empty()) {
+ // Write the prefix string to the Makernote buffer
+ memcpy(buf, prefix_.data(), prefix_.size());
+ len += prefix_.size();
+ }
+ if (!absOffset_) {
+ // Use offsets relative to the start of the Makernote field
+ offset = 0;
+ }
+ len += ifd_.copy(buf + len, byteOrder_, offset + len);
+ return len;
+ } // IfdMakerNote::copy
Entries::const_iterator IfdMakerNote::findIdx(int idx) const
{
@@ -205,7 +219,7 @@ namespace Exif {
long IfdMakerNote::size() const
{
- return ifd_.size() + ifd_.dataSize();
+ return prefix_.size() + ifd_.size() + ifd_.dataSize();
}
MakerNoteFactory* MakerNoteFactory::pInstance_ = 0;
@@ -229,7 +243,7 @@ namespace Exif {
// Todo: use case insensitive make and model comparisons
- // find or create a registry entry for make
+ // Find or create a registry entry for make
ModelRegistry* modelRegistry = 0;
Registry::const_iterator end1 = registry_.end();
Registry::const_iterator pos1;
@@ -243,7 +257,7 @@ namespace Exif {
modelRegistry = new ModelRegistry;
registry_.push_back(std::make_pair(make, modelRegistry));
}
- // find or create a registry entry for model
+ // Find or create a registry entry for model
ModelRegistry::iterator end2 = modelRegistry->end();
ModelRegistry::iterator pos2;
for (pos2 = modelRegistry->begin(); pos2 != end2; ++pos2) {
diff --git a/src/makernote.hpp b/src/makernote.hpp
index e94b6a5..8b81461 100644
--- a/src/makernote.hpp
+++ b/src/makernote.hpp
@@ -22,7 +22,7 @@
@file makernote.hpp
@brief Contains the %Exif %MakerNote interface, IFD %MakerNote and a
MakerNote factory
- @version $Name: $ $Revision: 1.14 $
+ @version $Name: $ $Revision: 1.15 $
@author Andreas Huggel (ahu)
<a href="mailto:ahuggel at gmx.net">ahuggel at gmx.net</a>
@date 18-Feb-04, ahu: created
@@ -113,7 +113,8 @@ namespace Exif {
for the Entries.
*/
MakerNote(const MnTagInfo* pMnTagInfo =0, bool alloc =true)
- : pMnTagInfo_(pMnTagInfo), alloc_(alloc), byteOrder_(invalidByteOrder) {}
+ : pMnTagInfo_(pMnTagInfo), alloc_(alloc),
+ byteOrder_(invalidByteOrder), offset_(0) {}
//! Virtual destructor.
virtual ~MakerNote() {}
//@}
@@ -160,6 +161,8 @@ namespace Exif {
uint16 decomposeKey(const std::string& key) const;
//! Return the byte order (little or big endian).
ByteOrder byteOrder() const { return byteOrder_; }
+ //! Return the offset of the makernote from the start of the TIFF header
+ long offset() const { return offset_; }
/*!
@brief Return the name of a makernote tag. The default implementation
looks up the makernote info tag array if one is set, else
@@ -208,7 +211,7 @@ namespace Exif {
virtual Entries::const_iterator end() const =0;
//! Find an entry by idx, return a const iterator to the record
virtual Entries::const_iterator findIdx(int idx) const =0;
- //! Return the size of the makernote in bytes.
+ //! 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;
@@ -219,19 +222,23 @@ namespace Exif {
//@}
protected:
+ // DATA
//! Pointer to an array of makernote tag infos
const MnTagInfo* pMnTagInfo_;
/*!
- Memory management
- True: requires memory allocation and deallocation,
- False: no memory management needed.
+ @brief Flag to control the memory management: <BR>
+ True: requires memory allocation and deallocation, <BR>
+ False: no memory management needed.
*/
const bool alloc_;
/*!
- Alternative byte order to use, invalid if the byte order of the
- %Exif block can be used
+ @brief Alternative byte order to use, invalid if the byte order of the
+ %Exif block can be used
*/
ByteOrder byteOrder_;
+ //! Offset of the makernote from the start of the TIFF header
+ long offset_;
+
}; // class MakerNote
/*!
@@ -279,11 +286,12 @@ namespace Exif {
//@}
protected:
- //! Prefix before the start of the IFD
+ // DATA
+ //! String prefix at the beginning of the makernote, before the IFD
std::string prefix_;
/*!
- True: Offsets are from start of the TIFF header
- False: Offsets are from start of the makernote
+ @brief True: Offsets are from start of the TIFF header,
+ False: Offsets are from start of the makernote
*/
bool absOffset_;
//! MakerNote IFD
--
exiv2 packaging
More information about the pkg-kde-commits
mailing list