Changed Ifd::read() to allow it to access the complete Exif data buffer. Corresponding changes done to makernotes. Fixes bug #424.
This commit is contained in:
parent
1a2183c2ea
commit
5823ceaff3
@ -213,10 +213,11 @@ namespace Exiv2 {
|
||||
|
||||
int CanonMakerNote::read(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder,
|
||||
long offset)
|
||||
long start,
|
||||
ByteOrder byteOrder,
|
||||
long shift)
|
||||
{
|
||||
int rc = IfdMakerNote::read(buf, len, byteOrder, offset);
|
||||
int rc = IfdMakerNote::read(buf, len, start, byteOrder, shift);
|
||||
if (rc) return rc;
|
||||
|
||||
// Decode camera settings 1 and add settings as additional entries
|
||||
@ -337,7 +338,7 @@ namespace Exiv2 {
|
||||
void CanonMakerNote::updateBase(byte* pNewBase)
|
||||
{
|
||||
byte* pBase = ifd_.updateBase(pNewBase);
|
||||
if (absOffset_ && !alloc_) {
|
||||
if (absShift_ && !alloc_) {
|
||||
Entries::iterator end = entries_.end();
|
||||
for (Entries::iterator pos = entries_.begin(); pos != end; ++pos) {
|
||||
pos->updateBase(pBase, pNewBase);
|
||||
|
||||
@ -111,8 +111,9 @@ namespace Exiv2 {
|
||||
//@{
|
||||
int read(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder,
|
||||
long offset);
|
||||
long start,
|
||||
ByteOrder byteOrder,
|
||||
long shift);
|
||||
long copy(byte* buf, ByteOrder byteOrder, long offset);
|
||||
void add(const Entry& entry);
|
||||
Entries::iterator begin() { return entries_.begin(); }
|
||||
|
||||
@ -128,10 +128,10 @@ int read(const std::string& path)
|
||||
|
||||
// Read IFD0
|
||||
Ifd ifd0(ifd0Id);
|
||||
rc = ifd0.read(exifData.pData_ + tiffHeader.offset(),
|
||||
size - tiffHeader.offset(),
|
||||
tiffHeader.byteOrder(),
|
||||
tiffHeader.offset());
|
||||
rc = ifd0.read(exifData.pData_,
|
||||
size,
|
||||
tiffHeader.offset(),
|
||||
tiffHeader.byteOrder());
|
||||
if (rc) return rc;
|
||||
ifd0.print(std::cout);
|
||||
|
||||
|
||||
17
src/exif.cpp
17
src/exif.cpp
@ -477,10 +477,7 @@ namespace Exiv2 {
|
||||
delete pIfd0_;
|
||||
pIfd0_ = new Ifd(ifd0Id, 0, false);
|
||||
assert(pIfd0_ != 0);
|
||||
rc = pIfd0_->read(pData_ + pTiffHeader_->offset(),
|
||||
size_ - pTiffHeader_->offset(),
|
||||
byteOrder(),
|
||||
pTiffHeader_->offset());
|
||||
rc = pIfd0_->read(pData_, size_, pTiffHeader_->offset(), byteOrder());
|
||||
if (rc) return rc;
|
||||
|
||||
delete pExifIfd_;
|
||||
@ -508,10 +505,9 @@ namespace Exiv2 {
|
||||
}
|
||||
// Read the MakerNote
|
||||
if (pMakerNote_) {
|
||||
rc = pMakerNote_->read(pos->data(),
|
||||
pos->size(),
|
||||
byteOrder(),
|
||||
pExifIfd_->offset() + pos->offset());
|
||||
rc = pMakerNote_->read(pData_, size_,
|
||||
pExifIfd_->offset() + pos->offset(),
|
||||
byteOrder());
|
||||
if (rc) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Warning: Failed to read Makernote, rc = "
|
||||
@ -546,10 +542,7 @@ namespace Exiv2 {
|
||||
assert(pIfd1_ != 0);
|
||||
// Read IFD1
|
||||
if (pIfd0_->next()) {
|
||||
rc = pIfd1_->read(pData_ + pIfd0_->next(),
|
||||
size_ - pIfd0_->next(),
|
||||
byteOrder(),
|
||||
pIfd0_->next());
|
||||
rc = pIfd1_->read(pData_, size_, pIfd0_->next(), byteOrder());
|
||||
if (rc) return rc;
|
||||
}
|
||||
// Find and delete ExifIFD sub-IFD of IFD1
|
||||
|
||||
@ -91,7 +91,7 @@ namespace Exiv2 {
|
||||
: IfdMakerNote(fujiIfdId, alloc)
|
||||
{
|
||||
byteOrder_ = littleEndian;
|
||||
absOffset_ = false;
|
||||
absShift_ = false;
|
||||
byte buf[] = {
|
||||
'F', 'U', 'J', 'I', 'F', 'I', 'L', 'M', 0x0c, 0x00, 0x00, 0x00
|
||||
};
|
||||
@ -111,9 +111,9 @@ namespace Exiv2 {
|
||||
|
||||
header_.alloc(12);
|
||||
memcpy(header_.pData_, buf, header_.size_);
|
||||
// Read the offset relative to the start of the makernote from the header
|
||||
// Note: we ignore the byteOrder paramter
|
||||
adjOffset_ = getUShort(header_.pData_ + 8, byteOrder_);
|
||||
// Read offset to the IFD relative to the start of the makernote
|
||||
// from the header. Note that we ignore the byteOrder paramter
|
||||
start_ = getUShort(header_.pData_ + 8, byteOrder_);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ try {
|
||||
};
|
||||
|
||||
Exiv2::Ifd ifd(Exiv2::ifd0Id, 0, false);
|
||||
int rc = ifd.read(buf+1, len-1, Exiv2::bigEndian, 1);
|
||||
int rc = ifd.read(buf, len, 1, Exiv2::bigEndian);
|
||||
if (rc) {
|
||||
std::cout << "Ifd::read (1) failed, rc = " << rc << "\n";
|
||||
return rc;
|
||||
@ -58,9 +58,9 @@ try {
|
||||
pos->setValue(2, 6, data, 6);
|
||||
|
||||
Exiv2::DataBuf db(1024);
|
||||
rc = ifd.copy(db.pData_, Exiv2::bigEndian);
|
||||
rc = ifd.copy(db.pData_ + 1, Exiv2::bigEndian);
|
||||
std::cout << "Wrote " << rc << " characters to data buffer\n";
|
||||
rc = ifd.read(db.pData_, len, Exiv2::bigEndian, 1);
|
||||
rc = ifd.read(db.pData_, len, 1, Exiv2::bigEndian);
|
||||
if (rc) {
|
||||
std::cout << "Ifd::read (1a) failed, rc = " << rc << "\n";
|
||||
return rc;
|
||||
@ -88,7 +88,7 @@ try {
|
||||
};
|
||||
|
||||
Exiv2::Ifd ifd2(Exiv2::ifd0Id, 0, false);
|
||||
rc = ifd2.read(buf2 + 22, len2 - 22, Exiv2::bigEndian, 22);
|
||||
rc = ifd2.read(buf2, len2, 22, Exiv2::bigEndian);
|
||||
if (rc) {
|
||||
std::cout << "Ifd::read (2) failed, rc = " << rc << "\n";
|
||||
return rc;
|
||||
@ -111,31 +111,31 @@ try {
|
||||
std::cout << "\nTest boundary checks, the following reads should generate warnings or errors\n";
|
||||
|
||||
std::cout << "--- read (3)" << std::endl;
|
||||
rc = ifd.read(buf+1, len-1-1, Exiv2::bigEndian, 1);
|
||||
rc = ifd.read(buf, len-1, 1, Exiv2::bigEndian);
|
||||
if (rc) {
|
||||
std::cout << "Ifd::read (3) failed, rc = " << rc << "\n";
|
||||
}
|
||||
|
||||
std::cout << "--- read (4)" << std::endl;
|
||||
rc = ifd.read(buf+1, len-1-21, Exiv2::bigEndian, 1);
|
||||
rc = ifd.read(buf, len-17, 1, Exiv2::bigEndian);
|
||||
if (rc) {
|
||||
std::cout << "Ifd::read (4) failed, rc = " << rc << "\n";
|
||||
}
|
||||
|
||||
std::cout << "--- read (5)" << std::endl;
|
||||
rc = ifd.read(buf+1, len-1-22, Exiv2::bigEndian, 1);
|
||||
rc = ifd.read(buf, len-16, 1, Exiv2::bigEndian);
|
||||
if (rc) {
|
||||
std::cout << "Ifd::read (5) failed, rc = " << rc << "\n";
|
||||
}
|
||||
|
||||
std::cout << "--- read (6)" << std::endl;
|
||||
rc = ifd.read(buf+1, len-1-23, Exiv2::bigEndian, 1);
|
||||
rc = ifd.read(buf, len-23, 1, Exiv2::bigEndian);
|
||||
if (rc) {
|
||||
std::cout << "Ifd::read (6) failed, rc = " << rc << "\n";
|
||||
}
|
||||
|
||||
std::cout << "--- read (7)" << std::endl;
|
||||
rc = ifd2.read(buf2+22, len2-22-1, Exiv2::bigEndian, 22);
|
||||
rc = ifd2.read(buf2, len2-1, 22, Exiv2::bigEndian);
|
||||
if (rc) {
|
||||
std::cout << "Ifd::read (7) failed, rc = " << rc << "\n";
|
||||
}
|
||||
@ -176,7 +176,7 @@ try {
|
||||
long len3 = ifd3.copy(ibuf.pData_, Exiv2::bigEndian);
|
||||
|
||||
Exiv2::Ifd ifd4(Exiv2::ifd0Id, 0, false);
|
||||
rc = ifd4.read(ibuf.pData_, len3, Exiv2::bigEndian, 0);
|
||||
rc = ifd4.read(ibuf.pData_, len3, 0, Exiv2::bigEndian);
|
||||
if (rc) {
|
||||
std::cout << "Ifd::read (8) failed, rc = " << rc << "\n";
|
||||
}
|
||||
@ -186,7 +186,7 @@ try {
|
||||
std::cout << "\nMove data buffer\n";
|
||||
|
||||
Exiv2::Ifd ifd5(Exiv2::ifd0Id, 0, false);
|
||||
rc = ifd5.read(buf+1, len-1, Exiv2::bigEndian, 1);
|
||||
rc = ifd5.read(buf, len, 1, Exiv2::bigEndian);
|
||||
if (rc) {
|
||||
std::cout << "Ifd::read (1) failed, rc = " << rc << "\n";
|
||||
return rc;
|
||||
|
||||
69
src/ifd.cpp
69
src/ifd.cpp
@ -296,20 +296,21 @@ namespace Exiv2 {
|
||||
}
|
||||
}
|
||||
|
||||
int Ifd::read(const byte* buf, long len, ByteOrder byteOrder, long offset)
|
||||
int Ifd::read(const byte* buf,
|
||||
long len,
|
||||
long start,
|
||||
ByteOrder byteOrder,
|
||||
long shift)
|
||||
{
|
||||
// Todo: This is a hack to work around bug #424 - fix it properly!
|
||||
if (ifdId_ == olympusIfdId) len = 65535;
|
||||
|
||||
int rc = 0;
|
||||
long o = 0;
|
||||
long o = start;
|
||||
Ifd::PreEntries preEntries;
|
||||
|
||||
if (len < 2) rc = 6;
|
||||
if (len < o + 2) rc = 6;
|
||||
if (rc == 0) {
|
||||
offset_ = offset;
|
||||
int n = getUShort(buf, byteOrder);
|
||||
o = 2;
|
||||
offset_ = start - shift;
|
||||
int n = getUShort(buf + o, byteOrder);
|
||||
o += 2;
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (len < o + 12) {
|
||||
@ -326,7 +327,7 @@ namespace Exiv2 {
|
||||
pe.type_ = getUShort(buf + o + 2, byteOrder);
|
||||
pe.count_ = getULong(buf + o + 4, byteOrder);
|
||||
pe.size_ = pe.count_ * TypeInfo::typeSize(TypeId(pe.type_));
|
||||
pe.offsetLoc_ = o + 8;
|
||||
pe.offsetLoc_ = o + 8 - shift;
|
||||
pe.offset_ = pe.size_ > 4 ? getLong(buf + o + 8, byteOrder) : 0;
|
||||
preEntries.push_back(pe);
|
||||
o += 12;
|
||||
@ -352,10 +353,6 @@ namespace Exiv2 {
|
||||
}
|
||||
}
|
||||
// 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 (rc == 0 && preEntries.size() > 0) {
|
||||
// Find the entry with the smallest offset
|
||||
Ifd::PreEntries::const_iterator i = std::min_element(
|
||||
@ -363,23 +360,31 @@ namespace Exiv2 {
|
||||
// Only do something if there is at least one entry with data
|
||||
// outside the IFD directory itself.
|
||||
if (i->size_ > 4) {
|
||||
if (offset_ == 0) {
|
||||
// Set the 'guessed' IFD offset
|
||||
offset_ = i->offset_
|
||||
- (2 + 12 * static_cast<long>(preEntries.size())
|
||||
+ (hasNext_ ? 4 : 0));
|
||||
}
|
||||
// Set the offset of the first data entry outside of the IFD
|
||||
if (i->offset_ - offset_ >= len) {
|
||||
if (i->offset_ + shift < 0) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Error: Offset of the 1st data entry of "
|
||||
<< ExifTags::ifdName(ifdId_)
|
||||
<< " is out of bounds:\n"
|
||||
<< " Offset = 0x" << std::setw(8)
|
||||
<< std::setfill('0') << std::hex
|
||||
<< i->offset_ - offset_
|
||||
<< i->offset_ - offset_ // relative to start of IFD
|
||||
<< ", is before start of buffer by "
|
||||
<< std::dec << -1 * (i->offset_ + shift)
|
||||
<< " Bytes\n";
|
||||
#endif
|
||||
rc = 6;
|
||||
}
|
||||
else if (i->offset_ + shift + i->size_ > len) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Error: Upper boundary of the 1st data entry of "
|
||||
<< ExifTags::ifdName(ifdId_)
|
||||
<< " is out of bounds:\n"
|
||||
<< " Offset = 0x" << std::setw(8)
|
||||
<< std::setfill('0') << std::hex
|
||||
<< i->offset_ - offset_ // relative to start of IFD
|
||||
<< ", exceeds buffer size by "
|
||||
<< std::dec << i->offset_ - len
|
||||
<< std::dec << i->offset_ + shift + i->size_ - len
|
||||
<< " Bytes\n";
|
||||
#endif
|
||||
rc = 6;
|
||||
@ -402,9 +407,9 @@ namespace Exiv2 {
|
||||
e.setIfdId(ifdId_);
|
||||
e.setIdx(++idx);
|
||||
e.setTag(i->tag_);
|
||||
long tmpOffset =
|
||||
i->size_ > 4 ? i->offset_ - offset_ : i->offsetLoc_;
|
||||
if (tmpOffset + i->size_ > len) {
|
||||
long tmpOffset = // still from the start of the TIFF header
|
||||
i->size_ > 4 ? i->offset_ : i->offsetLoc_;
|
||||
if (tmpOffset + shift + i->size_ > len) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Warning: Upper boundary of data for "
|
||||
<< ExifTags::ifdName(ifdId_)
|
||||
@ -412,10 +417,10 @@ namespace Exiv2 {
|
||||
<< " is out of bounds:\n"
|
||||
<< " Offset = 0x" << std::setw(8)
|
||||
<< std::setfill('0') << std::hex
|
||||
<< tmpOffset
|
||||
<< tmpOffset - offset_ // relative to start of IFD
|
||||
<< ", size = " << std::dec << i->size_
|
||||
<< ", exceeds buffer size by "
|
||||
<< tmpOffset + i->size_ - len
|
||||
<< tmpOffset + shift + i->size_ - len
|
||||
<< " Bytes; Truncating the data.\n";
|
||||
#endif
|
||||
// Truncate the entry
|
||||
@ -424,14 +429,14 @@ namespace Exiv2 {
|
||||
tmpOffset = i->offsetLoc_;
|
||||
}
|
||||
// Set the offset to the data, relative to start of IFD
|
||||
e.setOffset(tmpOffset);
|
||||
e.setOffset(tmpOffset - offset_);
|
||||
// Set the size to at least for bytes to accomodate offset-data
|
||||
e.setValue(i->type_, i->count_, buf + e.offset(),
|
||||
e.setValue(i->type_, i->count_, buf + start + e.offset(),
|
||||
std::max(long(4), i->size_));
|
||||
this->add(e);
|
||||
}
|
||||
}
|
||||
if (!alloc_) pBase_ = const_cast<byte*>(buf) - offset_;
|
||||
if (!alloc_) pBase_ = const_cast<byte*>(buf + shift);
|
||||
if (rc) this->clear();
|
||||
|
||||
return rc;
|
||||
@ -478,7 +483,7 @@ namespace Exiv2 {
|
||||
rc = 6;
|
||||
}
|
||||
else {
|
||||
rc = dest.read(buf + offset, len - offset, byteOrder, offset);
|
||||
rc = dest.read(buf, len, offset, byteOrder);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
|
||||
31
src/ifd.hpp
31
src/ifd.hpp
@ -375,22 +375,24 @@ namespace Exiv2 {
|
||||
/*!
|
||||
@brief Read a complete IFD and its data from a data buffer
|
||||
|
||||
@param buf Pointer to the data to decode. The buffer must start with the
|
||||
IFD data (unlike the readSubIfd() method).
|
||||
@param len Number of bytes in the data buffer
|
||||
@param buf Pointer to the Exif data buffer that contains the IFD to
|
||||
decode. Usually, the buffer will contain all Exif data
|
||||
starting from the TIFF header.
|
||||
@param len Number of bytes in the Exif data buffer.
|
||||
@param start IFD starts at buf + start.
|
||||
@param byteOrder Applicable byte order (little or big endian).
|
||||
@param offset (Optional) offset of the IFD from the start of the TIFF
|
||||
header, if known. If not given, the offset will be guessed
|
||||
using the assumption that the smallest offset of all IFD
|
||||
directory entries points to a data buffer immediately follwing
|
||||
the IFD.
|
||||
@param shift IFD offsets are relative to buf + shift.
|
||||
|
||||
@return 0 if successful;<BR>
|
||||
6 if the data buffer is too small, e.g., if an offset points
|
||||
beyond the provided buffer. The IFD is cleared in this
|
||||
case.
|
||||
*/
|
||||
int read(const byte* buf, long len, ByteOrder byteOrder, long offset =0);
|
||||
int read(const byte* buf,
|
||||
long len,
|
||||
long start,
|
||||
ByteOrder byteOrder,
|
||||
long shift =0);
|
||||
/*!
|
||||
@brief Copy the IFD to a data array, update the offsets of the IFD and
|
||||
all its entries, return the number of bytes written.
|
||||
@ -480,7 +482,7 @@ namespace Exiv2 {
|
||||
|
||||
@param dest References the destination IFD.
|
||||
@param buf The data buffer to read from. The buffer must contain all Exif
|
||||
data starting from the TIFF header (unlike the read() method).
|
||||
data starting from the TIFF header.
|
||||
@param len Number of bytes in the data buffer
|
||||
@param byteOrder Applicable byte order (little or big endian).
|
||||
@param tag Tag to look for.
|
||||
@ -563,7 +565,7 @@ namespace Exiv2 {
|
||||
Entries entries_;
|
||||
//! IFD Id
|
||||
IfdId ifdId_;
|
||||
//! Pointer to IFD from the start of the TIFF header
|
||||
//! Pointer to IFD
|
||||
byte* pBase_;
|
||||
//! Offset of the IFD from the start of the TIFF header
|
||||
long offset_;
|
||||
@ -571,9 +573,12 @@ namespace Exiv2 {
|
||||
long dataOffset_;
|
||||
//! Indicates whether the IFD has a next pointer
|
||||
bool hasNext_;
|
||||
//! Pointer to the offset of next IFD from the start of the TIFF header
|
||||
//! Pointer to the offset of next IFD
|
||||
byte* pNext_;
|
||||
//! The offset of the next IFD as data value (always in sync with *pNext_)
|
||||
/*!
|
||||
The offset of the next IFD from the start of the TIFF header as data
|
||||
value (always in sync with *pNext_)
|
||||
*/
|
||||
uint32_t next_;
|
||||
|
||||
}; // class Ifd
|
||||
|
||||
@ -140,7 +140,7 @@ int main()
|
||||
};
|
||||
|
||||
Ifd ifd(Exiv2::iopIfdId, 0, false);
|
||||
int ret = ifd.read(buf, len, bigEndian, 1);
|
||||
int ret = ifd.read(buf, len, 0, bigEndian, 1);
|
||||
if (ret) {
|
||||
std::cout << "Ifd::read failed, ret = " << ret << "\n";
|
||||
return ret;
|
||||
|
||||
@ -66,39 +66,37 @@ namespace Exiv2 {
|
||||
|
||||
IfdMakerNote::IfdMakerNote(IfdId ifdId, bool alloc, bool hasNext)
|
||||
: MakerNote(alloc),
|
||||
absOffset_(true), adjOffset_(0), ifd_(ifdId, 0, alloc, hasNext)
|
||||
absShift_(true), shift_(0), start_(0), ifd_(ifdId, 0, alloc, hasNext)
|
||||
{
|
||||
}
|
||||
|
||||
IfdMakerNote::IfdMakerNote(const IfdMakerNote& rhs)
|
||||
: MakerNote(rhs), absOffset_(rhs.absOffset_), adjOffset_(rhs.adjOffset_),
|
||||
header_(rhs.header_.size_), ifd_(rhs.ifd_)
|
||||
: MakerNote(rhs), absShift_(rhs.absShift_), shift_(rhs.shift_),
|
||||
start_(rhs.start_), header_(rhs.header_.size_), ifd_(rhs.ifd_)
|
||||
{
|
||||
memcpy(header_.pData_, rhs.header_.pData_, header_.size_);
|
||||
}
|
||||
|
||||
int IfdMakerNote::read(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder,
|
||||
long offset)
|
||||
long start,
|
||||
ByteOrder byteOrder,
|
||||
long shift)
|
||||
{
|
||||
// Remember the offset
|
||||
offset_ = offset;
|
||||
offset_ = start - shift;
|
||||
// Set byte order if none is set yet
|
||||
if (byteOrder_ == invalidByteOrder) byteOrder_ = byteOrder;
|
||||
// Read and check the header (and set offset adjustment)
|
||||
int rc = readHeader(buf, len, byteOrder);
|
||||
int rc = readHeader(buf + start, len - start, byteOrder);
|
||||
if (rc == 0) {
|
||||
rc = checkHeader();
|
||||
}
|
||||
// Adjust the offset
|
||||
offset = absOffset_ ? offset + adjOffset_ : adjOffset_;
|
||||
// Adjust shift
|
||||
long newShift = absShift_ ? shift + shift_ : start + shift_;
|
||||
// Read the makernote IFD
|
||||
if (rc == 0) {
|
||||
rc = ifd_.read(buf + headerSize(),
|
||||
len - headerSize(),
|
||||
byteOrder_,
|
||||
offset);
|
||||
rc = ifd_.read(buf, len, start + start_, byteOrder_, newShift);
|
||||
}
|
||||
if (rc == 0) {
|
||||
// IfdMakerNote currently does not support multiple IFDs
|
||||
@ -111,7 +109,7 @@ namespace Exiv2 {
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_MAKERNOTE
|
||||
hexdump(std::cerr, buf, len, offset);
|
||||
hexdump(std::cerr, buf + start, len - start);
|
||||
if (rc == 0) ifd_.print(std::cerr);
|
||||
#endif
|
||||
|
||||
@ -125,7 +123,7 @@ namespace Exiv2 {
|
||||
// Set byte order if none is set yet
|
||||
if (byteOrder_ == invalidByteOrder) byteOrder_ = byteOrder;
|
||||
// Adjust the offset
|
||||
offset = absOffset_ ? offset + adjOffset_ : adjOffset_;
|
||||
offset = absShift_ ? offset + start_ - shift_ : start_ - shift_;
|
||||
|
||||
long len = 0;
|
||||
len += copyHeader(buf);
|
||||
@ -144,7 +142,7 @@ namespace Exiv2 {
|
||||
|
||||
void IfdMakerNote::updateBase(byte* pNewBase)
|
||||
{
|
||||
if (absOffset_) {
|
||||
if (absShift_) {
|
||||
ifd_.updateBase(pNewBase);
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,15 +117,24 @@ namespace Exiv2 {
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Read the makernote, including the makernote header, from
|
||||
character buffer buf of length len at position offset (from the
|
||||
start of the TIFF header) and encoded in byte order byteOrder.
|
||||
Return 0 if successful.
|
||||
*/
|
||||
@brief Read the makernote, including the makernote header, from the
|
||||
Exif data buffer.
|
||||
|
||||
@param buf Pointer to the Exif data buffer that contains the
|
||||
MakerNote to decode. The buffer should contain all Exif
|
||||
data starting from the TIFF header.
|
||||
@param len Number of bytes in the Exif data buffer
|
||||
@param start MakerNote starts at buf + start.
|
||||
@param byteOrder Applicable byte order (little or big endian).
|
||||
@param shift IFD offsets are relative to buf + shift.
|
||||
|
||||
@return 0 if successful.
|
||||
*/
|
||||
virtual int read(const byte* buf,
|
||||
long len,
|
||||
long start,
|
||||
ByteOrder byteOrder,
|
||||
long offset) =0;
|
||||
long shift =0) =0;
|
||||
/*!
|
||||
@brief Copy (write) the makerNote to the character buffer buf at
|
||||
position offset (from the start of the TIFF header), encoded
|
||||
@ -256,13 +265,14 @@ namespace Exiv2 {
|
||||
//@{
|
||||
virtual int read(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder,
|
||||
long offset);
|
||||
long start,
|
||||
ByteOrder byteOrder,
|
||||
long shift);
|
||||
/*!
|
||||
@brief Read the makernote header from the makernote databuffer. This
|
||||
method must set the offset adjustment (adjOffset_), if needed
|
||||
(assuming that the required information is in the header).
|
||||
Return 0 if successful.
|
||||
method must set the offset to the start of the IFD (start_), if
|
||||
needed (assuming that the required information is in the header).
|
||||
Return 0 if successful.
|
||||
@note The default implementation does nothing, assuming there is no
|
||||
header
|
||||
*/
|
||||
@ -309,20 +319,22 @@ namespace Exiv2 {
|
||||
protected:
|
||||
// DATA
|
||||
/*!
|
||||
@brief True: Adjustment of the IFD offsets is to be added to the
|
||||
offset from the start of the TIFF header (i.e., the
|
||||
start of the Exif data section),
|
||||
False: Adjustment of the IFD offsets is a suitable absolute
|
||||
value. Ignore the offset from the start of the TIFF
|
||||
header.
|
||||
@brief True: IFD offsets are relative to the start of the TIFF
|
||||
header (i.e., the start of the Exif data section)
|
||||
+ shift_
|
||||
False: IFD offsets are relative to the start of the
|
||||
makernote + shift_
|
||||
*/
|
||||
bool absOffset_;
|
||||
bool absShift_;
|
||||
/*!
|
||||
@brief Adjustment of the IFD offsets relative to the start of the
|
||||
TIFF header or to the start of the makernote, depending on
|
||||
the setting of absOffset_.
|
||||
@brief Adjustment for IFD offsets, see absShift_.
|
||||
*/
|
||||
long adjOffset_;
|
||||
long shift_;
|
||||
/*!
|
||||
@brief Start of the makernote IFD relative to the start of the
|
||||
makernote.
|
||||
*/
|
||||
long start_;
|
||||
//! Data buffer for the makernote header
|
||||
DataBuf header_;
|
||||
//! The makernote IFD
|
||||
|
||||
@ -250,7 +250,7 @@ namespace Exiv2 {
|
||||
|
||||
header_.alloc(8);
|
||||
memcpy(header_.pData_, buf, header_.size_);
|
||||
adjOffset_ = 8;
|
||||
start_ = 8;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -463,7 +463,7 @@ namespace Exiv2 {
|
||||
Nikon3MakerNote::Nikon3MakerNote(bool alloc)
|
||||
: IfdMakerNote(nikon3IfdId, alloc)
|
||||
{
|
||||
absOffset_ = false;
|
||||
absShift_ = false;
|
||||
byte buf[] = {
|
||||
'N', 'i', 'k', 'o', 'n', '\0',
|
||||
0x02, 0x10, 0x00, 0x00, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08
|
||||
@ -477,8 +477,8 @@ namespace Exiv2 {
|
||||
}
|
||||
|
||||
int Nikon3MakerNote::readHeader(const byte* buf,
|
||||
long len,
|
||||
ByteOrder byteOrder)
|
||||
long len,
|
||||
ByteOrder byteOrder)
|
||||
{
|
||||
if (len < 18) return 1;
|
||||
|
||||
@ -487,7 +487,8 @@ namespace Exiv2 {
|
||||
TiffHeader tiffHeader;
|
||||
tiffHeader.read(header_.pData_ + 10);
|
||||
byteOrder_ = tiffHeader.byteOrder();
|
||||
adjOffset_ = tiffHeader.offset();
|
||||
start_ = 10 + tiffHeader.offset();
|
||||
shift_ = 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -158,8 +158,7 @@ namespace Exiv2 {
|
||||
header_.alloc(8);
|
||||
memcpy(header_.pData_, buf, header_.size_);
|
||||
// Adjust the offset of the IFD for the prefix
|
||||
adjOffset_ = 8;
|
||||
|
||||
start_ = 8;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -115,7 +115,7 @@ namespace Exiv2 {
|
||||
header_.alloc(12);
|
||||
memcpy(header_.pData_, buf, header_.size_);
|
||||
// Adjust the offset of the IFD for the prefix
|
||||
adjOffset_ = 12;
|
||||
start_ = 12;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -115,7 +115,7 @@ namespace Exiv2 {
|
||||
header_.alloc(10);
|
||||
memcpy(header_.pData_, buf, header_.size_);
|
||||
// Adjust the offset of the IFD for the prefix
|
||||
adjOffset_ = 10;
|
||||
start_ = 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -93,7 +93,7 @@ namespace Exiv2 {
|
||||
header_.alloc(12);
|
||||
memcpy(header_.pData_, buf, header_.size_);
|
||||
// Adjust the offset of the IFD for the prefix
|
||||
adjOffset_ = 12;
|
||||
start_ = 12;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -80,8 +80,6 @@ Adjusting `Exif.Image.DateTime' by -43261 s to 2001:04:05 23:50:39
|
||||
Adjusting `Exif.Photo.DateTimeOriginal' by -43261 s to 2001:04:05 23:50:39
|
||||
Adjusting `Exif.Photo.DateTimeDigitized' by -43261 s to 2001:04:05 23:50:39
|
||||
File 6/12: exiv2-canon-eos-300d.jpg
|
||||
Warning: Upper boundary of data for Makernote entry 25 is out of bounds:
|
||||
Offset = 0x00000568, size = 48, exceeds buffer size by 24 Bytes; Truncating the data.
|
||||
Adjusting `Exif.Image.DateTime' by -43261 s to 2003:09:25 20:18:50
|
||||
Adjusting `Exif.Photo.DateTimeOriginal' by -43261 s to 2003:09:25 20:18:50
|
||||
Adjusting `Exif.Photo.DateTimeDigitized' by -43261 s to 2003:09:25 20:18:50
|
||||
@ -120,8 +118,6 @@ Renaming file to ./20040329_224245.jpg
|
||||
File 5/12: exiv2-nikon-e950.jpg
|
||||
Renaming file to ./20010405_235039.jpg
|
||||
File 6/12: exiv2-canon-eos-300d.jpg
|
||||
Warning: Upper boundary of data for Makernote entry 25 is out of bounds:
|
||||
Offset = 0x00000568, size = 48, exceeds buffer size by 24 Bytes; Truncating the data.
|
||||
Renaming file to ./20030925_201850.jpg
|
||||
File 7/12: exiv2-kodak-dc210.jpg
|
||||
Renaming file to ./20001026_044550.jpg
|
||||
@ -240,8 +236,6 @@ Copyright :
|
||||
Exif comment :
|
||||
|
||||
File 6 /12: 20030925_201850.jpg
|
||||
Warning: Upper boundary of data for Makernote entry 25 is out of bounds:
|
||||
Offset = 0x00000568, size = 48, exceeds buffer size by 24 Bytes; Truncating the data.
|
||||
Filename : 20030925_201850.jpg
|
||||
Filesize : 17033 Bytes
|
||||
Camera make : Canon
|
||||
@ -759,8 +753,6 @@ Exif.Thumbnail.ResolutionUnit Short 1 inch
|
||||
Exif.Thumbnail.JPEGInterchangeFormat Long 1 0
|
||||
Exif.Thumbnail.JPEGInterchangeFormatLength Long 1 4662
|
||||
File 6/12: 20030925_201850.jpg
|
||||
Warning: Upper boundary of data for Makernote entry 25 is out of bounds:
|
||||
Offset = 0x00000568, size = 48, exceeds buffer size by 24 Bytes; Truncating the data.
|
||||
Exif.Image.Make Ascii 6 Canon
|
||||
Exif.Image.Model Ascii 23 Canon EOS 300D DIGITAL
|
||||
Exif.Image.Orientation Short 1 right, top
|
||||
@ -823,7 +815,7 @@ Exif.Canon.0x00b4 Short 1 1
|
||||
Exif.Canon.0x0012 Short 24 7 7 3072 2048 3072 2048 151 151 1014 608 0 0 0 64928 64522 0 0 65030 0 506 0 0 8 65535
|
||||
Exif.Canon.0x0013 Short 4 0 159 7 112
|
||||
Exif.Canon.0x0000 Short 5 0 0 0 0 0
|
||||
Exif.Canon.0x00b6 Long 0
|
||||
Exif.Canon.0x00b6 Long 12 24 2 380376 1536 1024 2449882 3072000 892 2048000 595 65540 262146
|
||||
Exif.CanonCs1.Macro Short 1 (0)
|
||||
Exif.CanonCs1.Selftimer Short 1 Off
|
||||
Exif.CanonCs1.Quality Short 1 Fine
|
||||
@ -1304,8 +1296,6 @@ Exif.Thumbnail.DateTime Ascii 20 2005:05:27 17:19:34
|
||||
Exif.Thumbnail.JPEGInterchangeFormat Long 1 0
|
||||
Exif.Thumbnail.JPEGInterchangeFormatLength Long 1 15605
|
||||
exiv2-empty.jpg: No Exif data found in the file
|
||||
Warning: Upper boundary of data for Makernote entry 25 is out of bounds:
|
||||
Offset = 0x00000568, size = 48, exceeds buffer size by 24 Bytes; Truncating the data.
|
||||
|
||||
Extract Exif data --------------------------------------------------------
|
||||
File 1/12: exiv2-empty.jpg
|
||||
@ -1318,8 +1308,6 @@ Writing Exif data from 20040329_224245.jpg to ./20040329_224245.exv
|
||||
File 5/12: 20010405_235039.jpg
|
||||
Writing Exif data from 20010405_235039.jpg to ./20010405_235039.exv
|
||||
File 6/12: 20030925_201850.jpg
|
||||
Warning: Upper boundary of data for Makernote entry 25 is out of bounds:
|
||||
Offset = 0x00000568, size = 48, exceeds buffer size by 24 Bytes; Truncating the data.
|
||||
Writing Exif data from 20030925_201850.jpg to ./20030925_201850.exv
|
||||
File 7/12: 20001026_044550.jpg
|
||||
Writing Exif data from 20001026_044550.jpg to ./20001026_044550.exv
|
||||
@ -1347,8 +1335,6 @@ Writing JPEG thumbnail (8930 Bytes) to file ./20040329_224245-thumb.jpg
|
||||
File 5/12: 20010405_235039.jpg
|
||||
Writing JPEG thumbnail (4662 Bytes) to file ./20010405_235039-thumb.jpg
|
||||
File 6/12: 20030925_201850.jpg
|
||||
Warning: Upper boundary of data for Makernote entry 25 is out of bounds:
|
||||
Offset = 0x00000568, size = 48, exceeds buffer size by 24 Bytes; Truncating the data.
|
||||
Writing JPEG thumbnail (9728 Bytes) to file ./20030925_201850-thumb.jpg
|
||||
File 7/12: 20001026_044550.jpg
|
||||
Writing TIFF thumbnail (20916 Bytes) to file ./20001026_044550-thumb.tif
|
||||
@ -1363,8 +1349,6 @@ Writing JPEG thumbnail (10308 Bytes) to file ./20050218_212016-thumb.jpg
|
||||
File 12/12: 20050527_051833.jpg
|
||||
Writing JPEG thumbnail (15605 Bytes) to file ./20050527_051833-thumb.jpg
|
||||
exiv2-empty.exv: No Exif data found in the file
|
||||
Warning: Upper boundary of data for Makernote entry 25 is out of bounds:
|
||||
Offset = 0x00000568, size = 48, exceeds buffer size by 24 Bytes; Truncating the data.
|
||||
|
||||
Compare image data and extracted data ------------------------------------
|
||||
1,2c1,2
|
||||
@ -1425,8 +1409,6 @@ Erasing 9038 Bytes of thumbnail data
|
||||
File 5/12: 20010405_235039.jpg
|
||||
Erasing 4756 Bytes of thumbnail data
|
||||
File 6/12: 20030925_201850.jpg
|
||||
Warning: Upper boundary of data for Makernote entry 25 is out of bounds:
|
||||
Offset = 0x00000568, size = 48, exceeds buffer size by 24 Bytes; Truncating the data.
|
||||
Erasing 9858 Bytes of thumbnail data
|
||||
File 7/12: 20001026_044550.jpg
|
||||
Erasing 20910 Bytes of thumbnail data
|
||||
@ -1451,8 +1433,6 @@ File 4/12: 20040329_224245.jpg
|
||||
File 5/12: 20010405_235039.jpg
|
||||
20010405_235039.jpg: Image does not contain an Exif thumbnail
|
||||
File 6/12: 20030925_201850.jpg
|
||||
Warning: Upper boundary of data for Makernote entry 25 is out of bounds:
|
||||
Offset = 0x00000568, size = 48, exceeds buffer size by 24 Bytes; Truncating the data.
|
||||
20030925_201850.jpg: Image does not contain an Exif thumbnail
|
||||
File 7/12: 20001026_044550.jpg
|
||||
20001026_044550.jpg: Image does not contain an Exif thumbnail
|
||||
@ -1478,8 +1458,6 @@ Erasing Exif data from the file
|
||||
File 5/12: 20010405_235039.jpg
|
||||
Erasing Exif data from the file
|
||||
File 6/12: 20030925_201850.jpg
|
||||
Warning: Upper boundary of data for Makernote entry 25 is out of bounds:
|
||||
Offset = 0x00000568, size = 48, exceeds buffer size by 24 Bytes; Truncating the data.
|
||||
Erasing Exif data from the file
|
||||
File 7/12: 20001026_044550.jpg
|
||||
Erasing Exif data from the file
|
||||
@ -1530,8 +1508,6 @@ Writing Exif data from ./20040329_224245.exv to 20040329_224245.jpg
|
||||
File 5/12: 20010405_235039.jpg
|
||||
Writing Exif data from ./20010405_235039.exv to 20010405_235039.jpg
|
||||
File 6/12: 20030925_201850.jpg
|
||||
Warning: Upper boundary of data for Makernote entry 25 is out of bounds:
|
||||
Offset = 0x00000568, size = 48, exceeds buffer size by 24 Bytes; Truncating the data.
|
||||
Writing Exif data from ./20030925_201850.exv to 20030925_201850.jpg
|
||||
File 7/12: 20001026_044550.jpg
|
||||
Writing Exif data from ./20001026_044550.exv to 20001026_044550.jpg
|
||||
@ -1547,8 +1523,6 @@ Writing Exif data from ./20050218_212016.exv to 20050218_212016.jpg
|
||||
File 12/12: 20050527_051833.jpg
|
||||
Writing Exif data from ./20050527_051833.exv to 20050527_051833.jpg
|
||||
exiv2-empty.exv: No Exif data found in the file
|
||||
Warning: Upper boundary of data for Makernote entry 25 is out of bounds:
|
||||
Offset = 0x00000568, size = 48, exceeds buffer size by 24 Bytes; Truncating the data.
|
||||
|
||||
Compare original and inserted image data ---------------------------------
|
||||
1,2c1,2
|
||||
|
||||
@ -66,16 +66,14 @@ Test boundary checks, the following reads should generate warnings or errors
|
||||
Warning: Upper boundary of data for IFD0 entry 3 is out of bounds:
|
||||
Offset = 0x00000043, size = 9, exceeds buffer size by 1 Bytes; Truncating the data.
|
||||
--- read (4)
|
||||
Warning: Upper boundary of data for IFD0 entry 1 is out of bounds:
|
||||
Offset = 0x00000036, size = 6, exceeds buffer size by 5 Bytes; Truncating the data.
|
||||
Warning: Upper boundary of data for IFD0 entry 2 is out of bounds:
|
||||
Offset = 0x0000003c, size = 7, exceeds buffer size by 12 Bytes; Truncating the data.
|
||||
Warning: Upper boundary of data for IFD0 entry 3 is out of bounds:
|
||||
Offset = 0x00000043, size = 9, exceeds buffer size by 21 Bytes; Truncating the data.
|
||||
--- read (5)
|
||||
Error: Offset of the 1st data entry of IFD0 is out of bounds:
|
||||
Error: Upper boundary of the 1st data entry of IFD0 is out of bounds:
|
||||
Offset = 0x00000036, exceeds buffer size by 1 Bytes
|
||||
Ifd::read (5) failed, rc = 6
|
||||
Ifd::read (4) failed, rc = 6
|
||||
--- read (5)
|
||||
Warning: Upper boundary of data for IFD0 entry 2 is out of bounds:
|
||||
Offset = 0x0000003c, size = 7, exceeds buffer size by 7 Bytes; Truncating the data.
|
||||
Warning: Upper boundary of data for IFD0 entry 3 is out of bounds:
|
||||
Offset = 0x00000043, size = 9, exceeds buffer size by 16 Bytes; Truncating the data.
|
||||
--- read (6)
|
||||
Error: IFD0 memory of the pointer to the next IFD lies outside of the IFD memory buffer.
|
||||
Ifd::read (6) failed, rc = 6
|
||||
|
||||
Loading…
Reference in New Issue
Block a user