#945: Set the makernote 'state' before post-processing Makernote components during reading.

v0.27.3
Andreas Huggel 12 years ago
parent b23614d572
commit dc6cd4cf67

@ -1949,8 +1949,7 @@ namespace Exiv2 {
TiffComponent::AutoPtr rootDir = TiffCreator::create(root, ifdIdNotSet); TiffComponent::AutoPtr rootDir = TiffCreator::create(root, ifdIdNotSet);
if (0 != rootDir.get()) { if (0 != rootDir.get()) {
rootDir->setStart(pData + pHeader->offset()); rootDir->setStart(pData + pHeader->offset());
TiffRwState::AutoPtr state( TiffRwState state(pHeader->byteOrder(), 0);
new TiffRwState(pHeader->byteOrder(), 0));
TiffReader reader(pData, size, rootDir.get(), state); TiffReader reader(pData, size, rootDir.get(), state);
rootDir->accept(reader); rootDir->accept(reader);
reader.postProcess(); reader.postProcess();

@ -1135,15 +1135,16 @@ namespace Exiv2 {
TiffReader::TiffReader(const byte* pData, TiffReader::TiffReader(const byte* pData,
uint32_t size, uint32_t size,
TiffComponent* pRoot, TiffComponent* pRoot,
TiffRwState::AutoPtr state) TiffRwState state)
: pData_(pData), : pData_(pData),
size_(size), size_(size),
pLast_(pData + size), pLast_(pData + size),
pRoot_(pRoot), pRoot_(pRoot),
pState_(state.release()), origState_(state),
pOrigState_(pState_), mnState_(state),
postProc_(false) postProc_(false)
{ {
pState_ = &origState_;
assert(pData_); assert(pData_);
assert(size_ > 0); assert(size_ > 0);
@ -1151,35 +1152,37 @@ namespace Exiv2 {
TiffReader::~TiffReader() TiffReader::~TiffReader()
{ {
if (pOrigState_ != pState_) delete pOrigState_;
delete pState_;
} }
void TiffReader::resetState() { void TiffReader::setOrigState()
if (pOrigState_ != pState_) delete pState_; {
pState_ = pOrigState_; pState_ = &origState_;
} }
void TiffReader::changeState(TiffRwState::AutoPtr state) void TiffReader::setMnState(const TiffRwState* state)
{ {
if (state.get() != 0) { if (state != 0) {
// invalidByteOrder indicates 'no change' // invalidByteOrder indicates 'no change'
if (state->byteOrder_ == invalidByteOrder) state->byteOrder_ = pState_->byteOrder_; if (state->byteOrder() == invalidByteOrder) {
if (pOrigState_ != pState_) delete pState_; mnState_ = TiffRwState(origState_.byteOrder(), state->baseOffset());
pState_ = state.release(); }
else {
mnState_ = *state;
}
} }
pState_ = &mnState_;
} }
ByteOrder TiffReader::byteOrder() const ByteOrder TiffReader::byteOrder() const
{ {
assert(pState_); assert(pState_);
return pState_->byteOrder_; return pState_->byteOrder();
} }
uint32_t TiffReader::baseOffset() const uint32_t TiffReader::baseOffset() const
{ {
assert(pState_); assert(pState_);
return pState_->baseOffset_; return pState_->baseOffset();
} }
void TiffReader::readDataEntryBase(TiffDataEntryBase* object) void TiffReader::readDataEntryBase(TiffDataEntryBase* object)
@ -1244,11 +1247,13 @@ namespace Exiv2 {
void TiffReader::postProcess() void TiffReader::postProcess()
{ {
setMnState(); // All components to be post-processed must be from the Makernote
postProc_ = true; postProc_ = true;
for (PostList::const_iterator pos = postList_.begin(); pos != postList_.end(); ++pos) { for (PostList::const_iterator pos = postList_.begin(); pos != postList_.end(); ++pos) {
(*pos)->accept(*this); (*pos)->accept(*this);
} }
postProc_ = false; postProc_ = false;
setOrigState();
} }
void TiffReader::visitDirectory(TiffDirectory* object) void TiffReader::visitDirectory(TiffDirectory* object)
@ -1432,17 +1437,15 @@ namespace Exiv2 {
// Modify reader for Makernote peculiarities, byte order and offset // Modify reader for Makernote peculiarities, byte order and offset
object->mnOffset_ = static_cast<uint32_t>(object->start() - pData_); object->mnOffset_ = static_cast<uint32_t>(object->start() - pData_);
TiffRwState::AutoPtr state( TiffRwState state(object->byteOrder(), object->baseOffset());
new TiffRwState(object->byteOrder(), object->baseOffset()) setMnState(&state);
);
changeState(state);
} // TiffReader::visitIfdMakernote } // TiffReader::visitIfdMakernote
void TiffReader::visitIfdMakernoteEnd(TiffIfdMakernote* /*object*/) void TiffReader::visitIfdMakernoteEnd(TiffIfdMakernote* /*object*/)
{ {
// Reset state (byte order, create function, offset) back to that for the image // Reset state (byte order, create function, offset) back to that for the image
resetState(); setOrigState();
} // TiffReader::visitIfdMakernoteEnd } // TiffReader::visitIfdMakernoteEnd
void TiffReader::readTiffEntry(TiffEntryBase* object) void TiffReader::readTiffEntry(TiffEntryBase* object)

@ -586,11 +586,7 @@ namespace Exiv2 {
makernotes). makernotes).
*/ */
class TiffRwState { class TiffRwState {
friend class TiffReader;
public: public:
//! TiffRWState auto_ptr type
typedef std::auto_ptr<TiffRwState> AutoPtr;
//! @name Creators //! @name Creators
//@{ //@{
//! Constructor. //! Constructor.
@ -623,7 +619,7 @@ namespace Exiv2 {
private: private:
ByteOrder byteOrder_; ByteOrder byteOrder_;
const uint32_t baseOffset_; uint32_t baseOffset_;
}; // TiffRwState }; // TiffRwState
/*! /*!
@ -647,7 +643,7 @@ namespace Exiv2 {
TiffReader(const byte* pData, TiffReader(const byte* pData,
uint32_t size, uint32_t size,
TiffComponent* pRoot, TiffComponent* pRoot,
TiffRwState::AutoPtr state); TiffRwState state);
//! Virtual destructor //! Virtual destructor
virtual ~TiffReader(); virtual ~TiffReader();
@ -682,10 +678,15 @@ namespace Exiv2 {
void readTiffEntry(TiffEntryBase* object); void readTiffEntry(TiffEntryBase* object);
//! Read a TiffDataEntryBase from the data buffer //! Read a TiffDataEntryBase from the data buffer
void readDataEntryBase(TiffDataEntryBase* object); void readDataEntryBase(TiffDataEntryBase* object);
//! Set the \em state class. Assumes ownership of the object passed in. /*!
void changeState(TiffRwState::AutoPtr state); @brief Set the \em state of the reader to one suitable for the Makernote.
//! Reset the state to the original state as set in the constructor.
void resetState(); Uses the \em state passed in, if any, and remembers it for use during
subsequent calls without any argument.
*/
void setMnState(const TiffRwState* state =0);
//! Set the state to the original state as set in the constructor.
void setOrigState();
//! Check IFD directory pointer \em start for circular reference //! Check IFD directory pointer \em start for circular reference
bool circularReference(const byte* start, IfdId group); bool circularReference(const byte* start, IfdId group);
//! Return the next idx sequence number for \em group //! Return the next idx sequence number for \em group
@ -721,8 +722,9 @@ namespace Exiv2 {
const uint32_t size_; //!< Size of the buffer const uint32_t size_; //!< Size of the buffer
const byte* pLast_; //!< Pointer to the last byte const byte* pLast_; //!< Pointer to the last byte
TiffComponent* const pRoot_; //!< Root element of the composite TiffComponent* const pRoot_; //!< Root element of the composite
TiffRwState* pState_; //!< State class TiffRwState* pState_; //!< Pointer to the state in effect (origState_ or mnState_)
TiffRwState* pOrigState_; //!< State class as set in the c'tor TiffRwState origState_; //!< State class as set in the c'tor
TiffRwState mnState_; //!< State class as set in the c'tor or by setMnState()
DirList dirList_; //!< List of IFD pointers and their groups DirList dirList_; //!< List of IFD pointers and their groups
IdxSeq idxSeq_; //!< Sequences for group, used for the entry's idx IdxSeq idxSeq_; //!< Sequences for group, used for the entry's idx
PostList postList_; //!< List of components with deferred reading PostList postList_; //!< List of components with deferred reading

Loading…
Cancel
Save