Bugfix: Set offset to the next IFD directly in the underlying data buffer in non-alloc mode

v0.27.3
Andreas Huggel 22 years ago
parent 532b0c33a7
commit f7c55fcb64

@ -20,14 +20,14 @@
*/
/*
File: ifd.cpp
Version: $Name: $ $Revision: 1.13 $
Version: $Name: $ $Revision: 1.14 $
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.13 $ $RCSfile: ifd.cpp,v $")
EXIV2_RCSID("@(#) $Name: $ $Revision: 1.14 $ $RCSfile: ifd.cpp,v $")
// *****************************************************************************
// included header files
@ -156,18 +156,41 @@ namespace Exif {
} // Entry::component
Ifd::Ifd(IfdId ifdId)
: alloc_(true), ifdId_(ifdId), offset_(0), next_(0)
: alloc_(true), ifdId_(ifdId), offset_(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), next_(0)
: alloc_(true), ifdId_(ifdId), offset_(offset), 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), next_(0)
: alloc_(alloc), ifdId_(ifdId), offset_(offset), pNext_(0), next_(0)
{
if (alloc_) {
pNext_ = new char[4];
memset(pNext_, 0x0, 4);
}
}
Ifd::~Ifd()
{
if (alloc_) delete[] pNext_;
}
Ifd::Ifd(const Ifd& rhs)
: alloc_(rhs.alloc_), entries_(rhs.entries_), ifdId_(rhs.ifdId_),
offset_(rhs.offset_), pNext_(rhs.pNext_), next_(rhs.next_)
{
if (alloc_ && rhs.pNext_) {
pNext_ = new char[4];
memcpy(pNext_, rhs.pNext_, 4);
}
}
int Ifd::read(const char* buf, ByteOrder byteOrder, long offset)
@ -190,6 +213,12 @@ namespace Exif {
preEntries.push_back(pe);
o += 12;
}
if (alloc_) {
memcpy(pNext_, buf + o, 4);
}
else {
pNext_ = const_cast<char*>(buf + o);
}
next_ = getULong(buf+o, byteOrder);
// Guess the offset of the IFD, if it was not given. The guess is based
@ -304,7 +333,13 @@ namespace Exif {
}
// Add the offset to the next IFD to the data buffer
o += ul2Data(buf + o, next_, byteOrder);
if (pNext_) {
memcpy(buf + o, pNext_, 4);
}
else {
memset(buf + o, 0x0, 4);
}
o += 4;
// Add the data of all IFD entries to the data buffer
for (i = b; i != e; ++i) {
@ -320,10 +355,22 @@ namespace Exif {
void Ifd::clear()
{
entries_.clear();
next_ = 0;
if (alloc_) {
memset(pNext_, 0x0, 4);
}
else {
pNext_ = 0;
}
offset_ = 0;
} // Ifd::clear
void Ifd::setNext(uint32 next, ByteOrder byteOrder)
{
assert(pNext_);
ul2Data(pNext_, next, byteOrder);
next_ = next;
}
void Ifd::add(const Entry& entry)
{
assert(alloc_ == entry.alloc());
@ -407,7 +454,7 @@ namespace Exif {
}
os << prefix << "Next IFD: 0x"
<< std::setw(8) << std::setfill('0') << std::hex
<< std::right << next_ << "\n";
<< std::right << next() << "\n";
// Print data of IFD entries
for (i = b; i != e; ++i) {
if (i->size() > 4) {

@ -21,7 +21,7 @@
/*!
@file ifd.hpp
@brief Encoding and decoding of IFD (Image File Directory) data
@version $Name: $ $Revision: 1.11 $
@version $Name: $ $Revision: 1.12 $
@author Andreas Huggel (ahu)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@date 09-Jan-04, ahu: created
@ -265,6 +265,12 @@ namespace Exif {
and the same data buffer.
*/
class Ifd {
//! @name Not implemented
//@{
//! Assignment not allowed (memory management mode alloc_ is const)
Ifd& operator=(const Ifd& rhs);
//@}
public:
//! @name Creators
//@{
@ -285,6 +291,10 @@ namespace Exif {
memory management is required for the Entries.
*/
Ifd(IfdId ifdId, uint32 offset, bool alloc);
//! Copy constructor
Ifd(const Ifd& rhs);
//! Destructor
~Ifd();
//@}
//! Entries const iterator type
@ -356,8 +366,11 @@ namespace Exif {
entries.
*/
void clear();
//! Set the offset of the next IFD
void setNext(uint32 next) { next_ = next; }
/*!
@brief Set the offset of the next IFD. Byte order is needed to update
the underlying data buffer in non-alloc mode.
*/
void setNext(uint32 next, ByteOrder byteOrder);
/*!
@brief Add the entry to the IFD. No duplicate-check is performed,
i.e., it is possible to add multiple entries with the same tag.
@ -402,7 +415,7 @@ namespace Exif {
//! Get the offset of the IFD from the start of the TIFF header
long offset() const { return offset_; }
//! Get the offset to the next IFD from the start of the TIFF header
long next() const { return next_; }
uint32 next() const { return next_; }
//! Get the number of directory entries in the IFD
long count() const { return entries_.size(); }
//! Get the size of this IFD in bytes (IFD only, without data)
@ -438,12 +451,21 @@ namespace Exif {
//! Container for 'pre-entries'
typedef std::vector<PreEntry> PreEntries;
const bool alloc_; // True: requires memory allocation and deallocation,
// False: no memory management needed.
Entries entries_; // IFD entries
IfdId ifdId_; // IFD Id
long offset_; // offset of the IFD from the start of TIFF header
long next_; // offset of next IFD from the start of the TIFF header
/*!
True: requires memory allocation and deallocation,
False: no memory management needed.
*/
const bool alloc_;
//! IFD entries
Entries entries_;
//! IFD Id
IfdId ifdId_;
//! 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
char* pNext_;
// The offset of the next IFD as data value (always in sync with *pNext_)
uint32 next_;
}; // class Ifd

Loading…
Cancel
Save