#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);
if (0 != rootDir.get()) {
rootDir->setStart(pData + pHeader->offset());
TiffRwState::AutoPtr state(
new TiffRwState(pHeader->byteOrder(), 0));
TiffRwState state(pHeader->byteOrder(), 0);
TiffReader reader(pData, size, rootDir.get(), state);
rootDir->accept(reader);
reader.postProcess();

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

@ -586,11 +586,7 @@ namespace Exiv2 {
makernotes).
*/
class TiffRwState {
friend class TiffReader;
public:
//! TiffRWState auto_ptr type
typedef std::auto_ptr<TiffRwState> AutoPtr;
//! @name Creators
//@{
//! Constructor.
@ -623,7 +619,7 @@ namespace Exiv2 {
private:
ByteOrder byteOrder_;
const uint32_t baseOffset_;
uint32_t baseOffset_;
}; // TiffRwState
/*!
@ -647,7 +643,7 @@ namespace Exiv2 {
TiffReader(const byte* pData,
uint32_t size,
TiffComponent* pRoot,
TiffRwState::AutoPtr state);
TiffRwState state);
//! Virtual destructor
virtual ~TiffReader();
@ -682,10 +678,15 @@ namespace Exiv2 {
void readTiffEntry(TiffEntryBase* object);
//! Read a TiffDataEntryBase from the data buffer
void readDataEntryBase(TiffDataEntryBase* object);
//! Set the \em state class. Assumes ownership of the object passed in.
void changeState(TiffRwState::AutoPtr state);
//! Reset the state to the original state as set in the constructor.
void resetState();
/*!
@brief Set the \em state of the reader to one suitable for the Makernote.
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
bool circularReference(const byte* start, IfdId 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 byte* pLast_; //!< Pointer to the last byte
TiffComponent* const pRoot_; //!< Root element of the composite
TiffRwState* pState_; //!< State class
TiffRwState* pOrigState_; //!< State class as set in the c'tor
TiffRwState* pState_; //!< Pointer to the state in effect (origState_ or mnState_)
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
IdxSeq idxSeq_; //!< Sequences for group, used for the entry's idx
PostList postList_; //!< List of components with deferred reading

Loading…
Cancel
Save