Alpha status TIFF image and parser, not yet added to Makefile
parent
23d1c91788
commit
ef30cbbd50
@ -0,0 +1,226 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2006 Andreas Huggel <ahuggel@gmx.net>
|
||||
*
|
||||
* This program is part of the Exiv2 distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
File: tiffimage.cpp
|
||||
Version: $Rev$
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 15-Mar-06, ahu: created
|
||||
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Id: tiffparser.cpp 675 2006-01-25 04:16:58Z ahuggel $");
|
||||
|
||||
// Define DEBUG to output debug information to std::cerr, e.g, by calling make
|
||||
// like this: make DEFS=-DDEBUG tiffparser.o
|
||||
//#define DEBUG
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#ifdef _MSC_VER
|
||||
# include "exv_msvc.h"
|
||||
#else
|
||||
# include "exv_conf.h"
|
||||
#endif
|
||||
|
||||
#include "tiffimage.hpp"
|
||||
#include "tiffparser.hpp"
|
||||
#include "image.hpp"
|
||||
#include "error.hpp"
|
||||
#include "futils.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
// *****************************************************************************
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
const TiffStructure TiffImage::tiffStructure_[] = {
|
||||
{ Tag::root, Group::none, newTiffDirectory, Group::ifd0 },
|
||||
{ 0x8769, Group::ifd0, newTiffSubIfd, Group::exif },
|
||||
{ 0x8825, Group::ifd0, newTiffSubIfd, Group::gps },
|
||||
{ 0xa005, Group::exif, newTiffSubIfd, Group::iop },
|
||||
{ Tag::next, Group::ifd0, newTiffDirectory, Group::ifd0 },
|
||||
// End of list marker
|
||||
{ Tag::none, Group::none, 0, Group::none }
|
||||
};
|
||||
|
||||
TiffImage::TiffImage(BasicIo::AutoPtr io, bool create)
|
||||
: Image(mdExif | mdComment), io_(io)
|
||||
{
|
||||
if (create) {
|
||||
IoCloser closer(*io_);
|
||||
io_->open();
|
||||
}
|
||||
} // TiffImage::TiffImage
|
||||
|
||||
bool TiffImage::good() const
|
||||
{
|
||||
if (io_->open() != 0) return false;
|
||||
IoCloser closer(*io_);
|
||||
return isThisType(*io_, false);
|
||||
}
|
||||
|
||||
void TiffImage::clearMetadata()
|
||||
{
|
||||
clearExifData();
|
||||
clearComment();
|
||||
}
|
||||
|
||||
void TiffImage::setMetadata(const Image& image)
|
||||
{
|
||||
setExifData(image.exifData());
|
||||
setComment(image.comment());
|
||||
}
|
||||
|
||||
void TiffImage::clearExifData()
|
||||
{
|
||||
exifData_.clear();
|
||||
}
|
||||
|
||||
void TiffImage::setExifData(const ExifData& exifData)
|
||||
{
|
||||
exifData_ = exifData;
|
||||
}
|
||||
|
||||
void TiffImage::clearIptcData()
|
||||
{
|
||||
// not supported
|
||||
}
|
||||
|
||||
void TiffImage::setIptcData(const IptcData& /*iptcData*/)
|
||||
{
|
||||
// not supported
|
||||
}
|
||||
|
||||
void TiffImage::clearComment()
|
||||
{
|
||||
comment_.erase();
|
||||
}
|
||||
|
||||
void TiffImage::setComment(const std::string& comment)
|
||||
{
|
||||
comment_ = comment;
|
||||
}
|
||||
|
||||
void TiffImage::readMetadata()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << "Reading TIFF file " << io_->path() << "\n";
|
||||
#endif
|
||||
if (io_->open() != 0) {
|
||||
throw Error(9, io_->path(), strError());
|
||||
}
|
||||
IoCloser closer(*io_);
|
||||
// Ensure that this is the correct image type
|
||||
if (!isThisType(*io_, false)) {
|
||||
if (io_->error() || io_->eof()) throw Error(14);
|
||||
throw Error(33);
|
||||
}
|
||||
clearMetadata();
|
||||
|
||||
// Read the image into a memory buffer
|
||||
long len = io_->size();
|
||||
DataBuf buf(len);
|
||||
io_->read(buf.pData_, len);
|
||||
if (io_->error() || io_->eof()) throw Error(14);
|
||||
|
||||
TiffParser::decode(this, tiffStructure_, buf.pData_, buf.size_);
|
||||
} // TiffImage::readMetadata
|
||||
|
||||
void TiffImage::writeMetadata()
|
||||
{
|
||||
/*
|
||||
|
||||
Todo: implement me!
|
||||
|
||||
#ifdef DEBUG
|
||||
std::cerr << "Writing TIFF file " << io_->path() << "\n";
|
||||
#endif
|
||||
// Read existing image
|
||||
DataBuf buf;
|
||||
if (io_->open() == 0) {
|
||||
IoCloser closer(*io_);
|
||||
// Ensure that this is the correct image type
|
||||
if (isThisType(*io_, false)) {
|
||||
// Read the image into a memory buffer
|
||||
buf.alloc(io_->size());
|
||||
io_->read(buf.pData_, buf.size_);
|
||||
if (io_->error() || io_->eof()) {
|
||||
buf.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse image, starting with a TIFF header component
|
||||
TiffHeade2::AutoPtr head(new TiffHeade2);
|
||||
if (buf.size_ != 0) {
|
||||
head->read(buf.pData_, buf.size_);
|
||||
}
|
||||
|
||||
Blob blob;
|
||||
TiffParser::encode(blob, head.get(), this);
|
||||
|
||||
// Write new buffer to file
|
||||
BasicIo::AutoPtr tempIo(io_->temporary()); // may throw
|
||||
assert (tempIo.get() != 0);
|
||||
tempIo->write(&blob[0], static_cast<long>(blob.size()));
|
||||
io_->close();
|
||||
io_->transfer(*tempIo); // may throw
|
||||
*/
|
||||
} // TiffImage::writeMetadata
|
||||
|
||||
bool TiffImage::isThisType(BasicIo& iIo, bool advance) const
|
||||
{
|
||||
return isTiffType(iIo, advance);
|
||||
}
|
||||
|
||||
// *************************************************************************
|
||||
// free functions
|
||||
|
||||
Image::AutoPtr newTiffInstance(BasicIo::AutoPtr io, bool create)
|
||||
{
|
||||
Image::AutoPtr image(new TiffImage(io, create));
|
||||
if (!image->good()) {
|
||||
image.reset();
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
bool isTiffType(BasicIo& iIo, bool advance)
|
||||
{
|
||||
const uint32_t len = 8;
|
||||
byte buf[len];
|
||||
iIo.read(buf, len);
|
||||
if (iIo.error() || iIo.eof()) {
|
||||
return false;
|
||||
}
|
||||
TiffHeade2 tiffHeader;
|
||||
bool rc = tiffHeader.read(buf, len);
|
||||
if (!advance || !rc) {
|
||||
iIo.seek(-len, BasicIo::cur);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
} // namespace Exiv2
|
@ -0,0 +1,191 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2006 Andreas Huggel <ahuggel@gmx.net>
|
||||
*
|
||||
* This program is part of the Exiv2 distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*!
|
||||
@file tiffimage.hpp
|
||||
@brief Class TiffImage
|
||||
@version $Rev$
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 15-Mar-06, ahu: created
|
||||
*/
|
||||
#ifndef TIFFIMAGE_HPP_
|
||||
#define TIFFIMAGE_HPP_
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "exif.hpp"
|
||||
#include "iptc.hpp"
|
||||
#include "image.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
// *****************************************************************************
|
||||
// class declarations
|
||||
|
||||
struct TiffStructure;
|
||||
|
||||
// *****************************************************************************
|
||||
// type definitions
|
||||
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
// Add TIFF to the supported image formats
|
||||
namespace ImageType {
|
||||
const int tiff = 4; //!< TIFF image type (see class TiffImage)
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Class to access raw TIFF images. Only Exif metadata and a comment
|
||||
are supported. TIFF format does not contain IPTC metadata.
|
||||
*/
|
||||
class TiffImage : public Image {
|
||||
friend bool isTiffType(BasicIo& iIo, bool advance);
|
||||
|
||||
//! @name NOT Implemented
|
||||
//@{
|
||||
//! Copy constructor
|
||||
TiffImage(const TiffImage& rhs);
|
||||
//! Assignment operator
|
||||
TiffImage& operator=(const TiffImage& rhs);
|
||||
//@}
|
||||
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
/*!
|
||||
@brief Constructor that can either open an existing TIFF image or create
|
||||
a new image from scratch. If a new image is to be created, any
|
||||
existing data is overwritten. Since the constructor can not return
|
||||
a result, callers should check the good() method after object
|
||||
construction to determine success or failure.
|
||||
@param io An auto-pointer that owns a BasicIo instance used for
|
||||
reading and writing image metadata. \b Important: The constructor
|
||||
takes ownership of the passed in BasicIo instance through the
|
||||
auto-pointer. Callers should not continue to use the BasicIo
|
||||
instance after it is passed to this method. Use the Image::io()
|
||||
method to get a temporary reference.
|
||||
@param create Specifies if an existing image should be read (false)
|
||||
or if a new file should be created (true).
|
||||
*/
|
||||
TiffImage(BasicIo::AutoPtr io, bool create);
|
||||
//! Destructor
|
||||
~TiffImage() {}
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
void readMetadata();
|
||||
/*!
|
||||
@brief Todo: Write metadata back to the image. This method is not
|
||||
yet implemented.
|
||||
*/
|
||||
void writeMetadata();
|
||||
void setExifData(const ExifData& exifData);
|
||||
void clearExifData();
|
||||
/*!
|
||||
@brief Not supported. TIFF format does not contain IPTC metadata.
|
||||
Calling this function will do nothing.
|
||||
*/
|
||||
void setIptcData(const IptcData& iptcData);
|
||||
/*!
|
||||
@brief Not supported. TIFF format does not contain IPTC metadata.
|
||||
Calling this function will do nothing.
|
||||
*/
|
||||
void clearIptcData();
|
||||
void setComment(const std::string& comment);
|
||||
void clearComment();
|
||||
void setMetadata(const Image& image);
|
||||
void clearMetadata();
|
||||
ExifData& exifData() { return exifData_; }
|
||||
IptcData& iptcData() { return iptcData_; }
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
bool good() const;
|
||||
const ExifData& exifData() const { return exifData_; }
|
||||
const IptcData& iptcData() const { return iptcData_; }
|
||||
std::string comment() const { return comment_; }
|
||||
BasicIo& io() const { return *io_; }
|
||||
//@}
|
||||
|
||||
private:
|
||||
//! @name Accessors
|
||||
//@{
|
||||
/*!
|
||||
@brief Determine if the content of the BasicIo instance is a TIFF image.
|
||||
|
||||
The advance flag determines if the read position in the stream is
|
||||
moved (see below). This applies only if the type matches and the
|
||||
function returns true. If the type does not match, the stream
|
||||
position is not changed. However, if reading from the stream fails,
|
||||
the stream position is undefined. Consult the stream state to obtain
|
||||
more information in this case.
|
||||
|
||||
@param iIo BasicIo instance to read from.
|
||||
@param advance Flag indicating whether the position of the io
|
||||
should be advanced by the number of characters read to
|
||||
analyse the data (true) or left at its original
|
||||
position (false). This applies only if the type matches.
|
||||
@return true if the data matches the type of this class;<BR>
|
||||
false if the data does not match
|
||||
*/
|
||||
bool isThisType(BasicIo& iIo, bool advance) const;
|
||||
/*!
|
||||
@brief Todo: Write TIFF header. Not implemented yet.
|
||||
*/
|
||||
int writeHeader(BasicIo& oIo) const;
|
||||
//@}
|
||||
|
||||
// DATA
|
||||
BasicIo::AutoPtr io_; //!< Image data io pointer
|
||||
ExifData exifData_; //!< Exif data container
|
||||
IptcData iptcData_; //!< IPTC data container
|
||||
std::string comment_; //!< User comment
|
||||
|
||||
static const TiffStructure tiffStructure_[]; //<! TIFF structure
|
||||
|
||||
}; // class TiffImage
|
||||
|
||||
// *****************************************************************************
|
||||
// template, inline and free functions
|
||||
|
||||
// These could be static private functions on Image subclasses but then
|
||||
// ImageFactory needs to be made a friend.
|
||||
/*!
|
||||
@brief Create a new TiffImage instance and return an auto-pointer to it.
|
||||
Caller owns the returned object and the auto-pointer ensures that
|
||||
it will be deleted.
|
||||
*/
|
||||
Image::AutoPtr newTiffInstance(BasicIo::AutoPtr io, bool create);
|
||||
|
||||
//! Check if the file iIo is a TIFF image.
|
||||
bool isTiffType(BasicIo& iIo, bool advance);
|
||||
|
||||
} // namespace Exiv2
|
||||
|
||||
#endif // #ifndef TIFFIMAGE_HPP_
|
@ -0,0 +1,411 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2006 Andreas Huggel <ahuggel@gmx.net>
|
||||
*
|
||||
* This program is part of the Exiv2 distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
File: tiffparser.cpp
|
||||
Version: $Rev$
|
||||
Author(s): Andreas Huggel (ahu) <ahuggel@gmx.net>
|
||||
History: 15-Mar-06, ahu: created
|
||||
|
||||
*/
|
||||
// *****************************************************************************
|
||||
#include "rcsid.hpp"
|
||||
EXIV2_RCSID("@(#) $Id: tiffparser.cpp 675 2006-01-25 04:16:58Z ahuggel $");
|
||||
|
||||
// Define DEBUG to output debug information to std::cerr, e.g, by calling make
|
||||
// like this: make DEFS=-DDEBUG tiffparser.o
|
||||
//#define DEBUG
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#ifdef _MSC_VER
|
||||
# include "exv_msvc.h"
|
||||
#else
|
||||
# include "exv_conf.h"
|
||||
#endif
|
||||
|
||||
#include "tiffparser.hpp"
|
||||
#include "image.hpp"
|
||||
#include "exif.hpp"
|
||||
#include "tags.hpp"
|
||||
#include "error.hpp"
|
||||
#include "futils.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cassert>
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
|
||||
Todo:
|
||||
|
||||
+ Fix CiffHeader according to TiffHeade2
|
||||
+ Combine Error(15) and Error(33), add format argument %1
|
||||
+ Search crwimage for todos, fix writeMetadata comment
|
||||
+ rename all Ciff stuff to Crw for easier reference
|
||||
|
||||
-------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
// *****************************************************************************
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
void TiffParser::decode(Image* pImage,
|
||||
const TiffStructure* pTiffStructure,
|
||||
const byte* pData,
|
||||
uint32_t size)
|
||||
{
|
||||
assert(pImage != 0);
|
||||
assert(pData != 0);
|
||||
|
||||
TiffHeade2 tiffHeader;
|
||||
if (!tiffHeader.read(pData, size) || tiffHeader.offset() >= size) {
|
||||
throw Error(3, "TIFF");
|
||||
}
|
||||
|
||||
TiffComponent::AutoPtr rootDir
|
||||
= create(Tag::root, Group::none, pTiffStructure);
|
||||
if (0 == rootDir.get()) return;
|
||||
rootDir->read(pData, size, tiffHeader.offset(), tiffHeader.byteOrder());
|
||||
|
||||
#ifdef DEBUG
|
||||
tiffHeader.print(std::cerr);
|
||||
rootDir->print(std::cerr, tiffHeader.byteOrder());
|
||||
#endif
|
||||
|
||||
rootDir->decode(*pImage, tiffHeader.byteOrder());
|
||||
|
||||
} // TiffParser::decode
|
||||
|
||||
TiffComponent::AutoPtr TiffParser::create(int32_t tag,
|
||||
uint16_t group,
|
||||
const TiffStructure* pTiffStructure)
|
||||
{
|
||||
const TiffStructure* ts = 0;
|
||||
for (int i = 0; pTiffStructure[i].tag_ != Tag::none; ++i) {
|
||||
if (tag == pTiffStructure[i].tag_ && group == pTiffStructure[i].group_) {
|
||||
ts = &pTiffStructure[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
TiffComponent::AutoPtr tc(0);
|
||||
if (ts && ts->newTiffCompFct_) {
|
||||
tc = ts->newTiffCompFct_(ts->newGroup_, pTiffStructure);
|
||||
}
|
||||
if (!ts) {
|
||||
tc = TiffComponent::AutoPtr(new TiffEntry);
|
||||
}
|
||||
return tc;
|
||||
} // TiffParser::create
|
||||
|
||||
TiffDirectory::~TiffDirectory()
|
||||
{
|
||||
Components::iterator b = components_.begin();
|
||||
Components::iterator e = components_.end();
|
||||
for (Components::iterator i = b; i != e; ++i) {
|
||||
delete *i;
|
||||
}
|
||||
delete pNext_;
|
||||
} // TiffDirectory::~TiffDirectory
|
||||
|
||||
TiffEntryBase::~TiffEntryBase()
|
||||
{
|
||||
if (isAllocated_) delete[] pData_;
|
||||
} // TiffEntryBase::~TiffEntryBase
|
||||
|
||||
const uint16_t TiffHeade2::tag_ = 42;
|
||||
|
||||
bool TiffHeade2::read(const byte* pData, uint32_t size)
|
||||
{
|
||||
if (size < 8) return false;
|
||||
|
||||
if (pData[0] == 0x49 && pData[1] == 0x49) {
|
||||
byteOrder_ = littleEndian;
|
||||
}
|
||||
else if (pData[0] == 0x4d && pData[1] == 0x4d) {
|
||||
byteOrder_ = bigEndian;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
if (tag_ != getUShort(pData + 2, byteOrder_)) return false;
|
||||
offset_ = getULong(pData + 4, byteOrder_);
|
||||
|
||||
return true;
|
||||
} // TiffHeade2::read
|
||||
|
||||
void TiffComponent::read(const byte* pData,
|
||||
uint32_t size,
|
||||
uint32_t start,
|
||||
ByteOrder byteOrder)
|
||||
{
|
||||
doRead(pData, size, start, byteOrder);
|
||||
} // TiffComponent::read
|
||||
|
||||
void TiffEntryBase::doRead(const byte* pData,
|
||||
uint32_t size,
|
||||
uint32_t start,
|
||||
ByteOrder byteOrder)
|
||||
{
|
||||
if (size - start < 12) throw Error(3, "TIFF");
|
||||
const byte* p = pData + start;
|
||||
tag_ = getUShort(p, byteOrder);
|
||||
p += 2;
|
||||
type_ = getUShort(p, byteOrder);
|
||||
// todo: check type
|
||||
p += 2;
|
||||
count_ = getULong(p, byteOrder);
|
||||
p += 4;
|
||||
offset_ = getULong(p, byteOrder);
|
||||
#ifdef DEBUG
|
||||
std::cout << "TiffEntryBase for "
|
||||
<< "tag 0x" << std::hex << tag_
|
||||
<< ", type " << std::dec << type_
|
||||
<< ", count " << count_
|
||||
<< ", offset 0x" << std::hex << offset_
|
||||
<< std::dec"\n";
|
||||
#endif
|
||||
size_ = TypeInfo::typeSize(typeId()) * count();
|
||||
if (size_ > 4) {
|
||||
if (size < offset() + size_) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Warning: Upper boundary of data for "
|
||||
<< "directory " << group() << ", " // todo: ExifTags::ifdName(ifdId_)
|
||||
<< " entry 0x" << std::setw(4)
|
||||
<< std::setfill('0') << std::hex << tag()
|
||||
<< " is out of bounds:\n"
|
||||
<< " Offset = 0x" << std::setw(8)
|
||||
<< std::setfill('0') << std::hex << offset()
|
||||
<< ", size = " << std::dec << size_
|
||||
<< ", exceeds buffer size by "
|
||||
<< offset() + size_ - size
|
||||
<< " Bytes; adjusting the size\n";
|
||||
#endif
|
||||
size_ = size - offset();
|
||||
// todo: adjust count_, make size_ a multiple of typeSize
|
||||
}
|
||||
pData_ = pData + offset();
|
||||
}
|
||||
else {
|
||||
pData_ = pData + start + 8;
|
||||
}
|
||||
|
||||
} // TiffEntryBase::doRead
|
||||
|
||||
void TiffEntry::doRead(const byte* pData,
|
||||
uint32_t size,
|
||||
uint32_t start,
|
||||
ByteOrder byteOrder)
|
||||
{
|
||||
TiffEntryBase::doRead(pData, size, start, byteOrder);
|
||||
} // TiffEntry::doRead
|
||||
|
||||
void TiffDirectory::doRead(const byte* pData,
|
||||
uint32_t size,
|
||||
uint32_t start,
|
||||
ByteOrder byteOrder)
|
||||
{
|
||||
if (size < start + 2) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Error: "
|
||||
<< "Directory " << group() << ": " // todo: ExifTags::ifdName(ifdId_)
|
||||
<< " IFD exceeds data buffer, cannot read entry count.\n";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
uint32_t o = start;
|
||||
const uint16_t n = getUShort(pData + o, byteOrder);
|
||||
o += 2;
|
||||
|
||||
for (uint16_t i = 0; i < n; ++i) {
|
||||
if (size < o + 12) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Error: "
|
||||
<< "Directory " << group() << ": " // todo: ExifTags::ifdName(ifdId_)
|
||||
<< " IFD entry " << i
|
||||
<< " lies outside of the data buffer.\n";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
uint16_t tag = getUShort(pData + o, byteOrder);
|
||||
TiffComponent::AutoPtr tc
|
||||
= TiffParser::create(tag, group(), pTiffStructure());
|
||||
tc->read(pData, size, o, byteOrder);
|
||||
components_.push_back(tc.release());
|
||||
o += 12;
|
||||
}
|
||||
if (size < o + 4) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
std::cerr << "Error: "
|
||||
<< "Directory " << group() << ": " // todo: ExifTags::ifdName(ifdId_)
|
||||
<< " IFD exceeds data buffer, cannot read next pointer.\n";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
uint32_t next = getLong(pData + o, byteOrder);
|
||||
if (next) {
|
||||
pNext_ = TiffParser::create(Tag::next, group(), pTiffStructure()).release();
|
||||
pNext_->read(pData, size, next, byteOrder);
|
||||
}
|
||||
|
||||
} // TiffDirectory::doRead
|
||||
|
||||
void TiffSubIfd::doRead(const byte* pData,
|
||||
uint32_t size,
|
||||
uint32_t start,
|
||||
ByteOrder byteOrder)
|
||||
{
|
||||
TiffEntryBase::doRead(pData, size, start, byteOrder);
|
||||
if (typeId() == unsignedLong && count() >= 1) {
|
||||
uint32_t offset = getULong(this->pData(), byteOrder);
|
||||
ifd_.read(pData, size, offset, byteOrder);
|
||||
}
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
else {
|
||||
std::cerr << "Warning: "
|
||||
<< "Directory " << group() << ", " // todo: ExifTags::ifdName(ifdId_)
|
||||
<< " entry 0x" << std::setw(4)
|
||||
<< std::setfill('0') << std::hex << tag()
|
||||
<< " doesn't look like a sub-IFD.";
|
||||
}
|
||||
#endif
|
||||
} // TiffSubIfd::read
|
||||
|
||||
void TiffComponent::decode(Image& image, ByteOrder byteOrder) const
|
||||
{
|
||||
doDecode(image, byteOrder);
|
||||
} // TiffComponent::decode
|
||||
|
||||
void TiffEntryBase::doDecode(Image& image, ByteOrder byteOrder) const
|
||||
{
|
||||
ExifKey k(tag(), "Image"); // todo needs ifdItem
|
||||
TypeId t = typeId();
|
||||
Value::AutoPtr v = Value::create(t);
|
||||
v->read(pData_, size_, byteOrder);
|
||||
image.exifData().add(k, v.get());
|
||||
} // TiffEntryBase::doDecode
|
||||
|
||||
void TiffEntry::doDecode(Image& image, ByteOrder byteOrder) const
|
||||
{
|
||||
TiffEntryBase::doDecode(image, byteOrder);
|
||||
} // TiffEntry::doDecode
|
||||
|
||||
void TiffDirectory::doDecode(Image& image, ByteOrder byteOrder) const
|
||||
{
|
||||
Components::const_iterator b = components_.begin();
|
||||
Components::const_iterator e = components_.end();
|
||||
for (Components::const_iterator i = b; i != e; ++i) {
|
||||
(*i)->decode(image, byteOrder);
|
||||
}
|
||||
if (pNext_) pNext_->decode(image, byteOrder);
|
||||
} // TiffDirectory::doDecode
|
||||
|
||||
void TiffSubIfd::doDecode(Image& image, ByteOrder byteOrder) const
|
||||
{
|
||||
ifd_.decode(image, byteOrder);
|
||||
} // TiffSubIfd::doDecode
|
||||
|
||||
void TiffHeade2::print(std::ostream& os, const std::string& prefix) const
|
||||
{
|
||||
os << prefix
|
||||
<< "Header, offset = 0x" << std::setw(8) << std::setfill('0')
|
||||
<< std::hex << std::right << offset_ << "\n";
|
||||
} // TiffHeade2::print
|
||||
|
||||
void TiffComponent::print(std::ostream& os,
|
||||
ByteOrder byteOrder,
|
||||
const std::string& prefix) const
|
||||
{
|
||||
doPrint(os, byteOrder, prefix);
|
||||
} // TiffComponent::print
|
||||
|
||||
void TiffEntryBase::doPrint(std::ostream& os,
|
||||
ByteOrder byteOrder,
|
||||
const std::string& prefix) const
|
||||
{
|
||||
os << prefix
|
||||
<< "tag = 0x" << std::setw(4) << std::setfill('0')
|
||||
<< std::hex << std::right << tag()
|
||||
<< ", type = " << TypeInfo::typeName(typeId())
|
||||
<< ", count = " << std::dec << count()
|
||||
<< ", offset = " << offset() << "\n";
|
||||
|
||||
TypeId t = typeId();
|
||||
Value::AutoPtr v = Value::create(t);
|
||||
v->read(pData_, size_, byteOrder);
|
||||
if (v->size() < 100) {
|
||||
os << prefix << *v << "\n";
|
||||
}
|
||||
} // TiffEntryBase::doPrint
|
||||
|
||||
void TiffEntry::doPrint(std::ostream& os,
|
||||
ByteOrder byteOrder,
|
||||
const std::string& prefix) const
|
||||
{
|
||||
TiffEntryBase::doPrint(os, byteOrder, prefix);
|
||||
} // TiffEntry::doPrint
|
||||
|
||||
void TiffDirectory::doPrint(std::ostream& os,
|
||||
ByteOrder byteOrder,
|
||||
const std::string& prefix) const
|
||||
{
|
||||
os << prefix << "Directory " << group()
|
||||
<< " with " << components_.size() << " entries.\n";
|
||||
Components::const_iterator b = components_.begin();
|
||||
Components::const_iterator e = components_.end();
|
||||
for (Components::const_iterator i = b; i != e; ++i) {
|
||||
(*i)->print(os, byteOrder, prefix + " ");
|
||||
}
|
||||
if (pNext_) {
|
||||
os << prefix << "Next directory:\n";
|
||||
pNext_->print(os, byteOrder, prefix);
|
||||
}
|
||||
else {
|
||||
os << prefix << "No next directory.\n";
|
||||
}
|
||||
} // TiffDirectory::doPrint
|
||||
|
||||
void TiffSubIfd::doPrint(std::ostream& os,
|
||||
ByteOrder byteOrder,
|
||||
const std::string& prefix) const
|
||||
{
|
||||
TiffEntryBase::doPrint(os, byteOrder, prefix);
|
||||
ifd_.print(os, byteOrder, prefix);
|
||||
} // TiffSubIfd::doPrint
|
||||
|
||||
// *************************************************************************
|
||||
// free functions
|
||||
|
||||
TiffComponent::AutoPtr newTiffDirectory(uint16_t group,
|
||||
const TiffStructure* pTiffStructure)
|
||||
{
|
||||
return TiffComponent::AutoPtr(new TiffDirectory(group, pTiffStructure));
|
||||
}
|
||||
|
||||
TiffComponent::AutoPtr newTiffSubIfd(uint16_t group,
|
||||
const TiffStructure* pTiffStructure)
|
||||
{
|
||||
return TiffComponent::AutoPtr(new TiffSubIfd(group, pTiffStructure));
|
||||
}
|
||||
|
||||
} // namespace Exiv2
|
@ -0,0 +1,491 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2006 Andreas Huggel <ahuggel@gmx.net>
|
||||
*
|
||||
* This program is part of the Exiv2 distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*!
|
||||
@file tiffparser.hpp
|
||||
@brief Class TiffParser to parse TIFF data.
|
||||
@version $Rev$
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 15-Mar-06, ahu: created
|
||||
*/
|
||||
#ifndef TIFFPARSER_HPP_
|
||||
#define TIFFPARSER_HPP_
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "exif.hpp"
|
||||
#include "iptc.hpp"
|
||||
#include "image.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <iostream>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
// *****************************************************************************
|
||||
// class declarations
|
||||
|
||||
struct TiffStructure;
|
||||
|
||||
// *****************************************************************************
|
||||
// type definitions
|
||||
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
/*!
|
||||
Known TIFF groups
|
||||
|
||||
Todo: what exactly are these and where should they go?
|
||||
Are they going to be mapped to the second part of an Exif key or are they
|
||||
the second part of the key?
|
||||
*/
|
||||
namespace Group {
|
||||
const uint16_t none = 0; //!< Dummy group
|
||||
const uint16_t ifd0 = 1; //!< Exif IFD0
|
||||
const uint16_t ifd1 = 2; //!< Thumbnail IFD
|
||||
const uint16_t exif = 3; //!< Exif IFD
|
||||
const uint16_t gps = 4; //!< GPS IFD
|
||||
const uint16_t iop = 5; //!< Interoperability IFD
|
||||
const uint16_t makernote = 256; //!< Makernote
|
||||
const uint16_t canonmn = 257; //!< Canon makernote
|
||||
}
|
||||
|
||||
/*!
|
||||
Known TIFF tags
|
||||
|
||||
Todo: Same Q as above...
|
||||
*/
|
||||
namespace Tag {
|
||||
const int32_t none = -1; //!< Dummy tag
|
||||
const int32_t root = -2; //!< Special tag: root IFD
|
||||
const int32_t next = -3; //!< Special tag: next IFD
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Interface class for components of a TIFF directory hierarchy. Both
|
||||
TIFF directories as well as entries implement this interface. This
|
||||
class is implemented as NVI (non-virtual interface).
|
||||
*/
|
||||
class TiffComponent {
|
||||
public:
|
||||
//! TiffComponent auto_ptr type
|
||||
typedef std::auto_ptr<TiffComponent> AutoPtr;
|
||||
//! Container type to hold all metadata
|
||||
typedef std::vector<TiffComponent*> Components;
|
||||
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Constructor
|
||||
TiffComponent(uint16_t group, const TiffStructure* pTiffStructure)
|
||||
: group_(group), pTiffStructure_(pTiffStructure) {}
|
||||
|
||||
//! Virtual destructor.
|
||||
virtual ~TiffComponent() {}
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Read a component from a data buffer
|
||||
|
||||
@param pData Pointer to the data buffer, starting with a TIFF header.
|
||||
@param size Number of bytes in the data buffer.
|
||||
@param start Component starts at \em pData + \em start.
|
||||
@param byteOrder Applicable byte order (little or big endian).
|
||||
|
||||
@throw Error If the component cannot be parsed.
|
||||
*/
|
||||
void read(const byte* pData,
|
||||
uint32_t size,
|
||||
uint32_t start,
|
||||
ByteOrder byteOrder);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
//*! Return the group id of this component
|
||||
uint16_t group() const { return group_; }
|
||||
//*! Return the TIFF structure
|
||||
const TiffStructure* pTiffStructure() const { return pTiffStructure_; }
|
||||
/*!
|
||||
@brief Decode metadata from the component and add it to
|
||||
\em image.
|
||||
|
||||
@param image Image to add the metadata to
|
||||
@param byteOrder Byte order
|
||||
*/
|
||||
void decode(Image& image, ByteOrder byteOrder) const;
|
||||
/*!
|
||||
@brief Print debug info about a component to \em os.
|
||||
|
||||
@param os Output stream to write to
|
||||
@param byteOrder Byte order
|
||||
@param prefix Prefix to be written before each line of output
|
||||
*/
|
||||
void print(std::ostream& os,
|
||||
ByteOrder byteOrder,
|
||||
const std::string& prefix ="") const;
|
||||
//@}
|
||||
|
||||
protected:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
//! Implements read().
|
||||
virtual void doRead(const byte* pData,
|
||||
uint32_t size,
|
||||
uint32_t start,
|
||||
ByteOrder byteOrder) =0;
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
//! Implements decode()
|
||||
virtual void doDecode(Image& image,
|
||||
ByteOrder byteOrder) const =0;
|
||||
//! Implements print()
|
||||
virtual void doPrint(std::ostream& os,
|
||||
ByteOrder byteOrder,
|
||||
const std::string& prefix) const =0;
|
||||
//@}
|
||||
|
||||
private:
|
||||
// DATA
|
||||
uint16_t group_; //!< Group id for this component
|
||||
const TiffStructure* pTiffStructure_; //!< TIFF structure for this component
|
||||
|
||||
}; // class TiffComponent
|
||||
|
||||
/*!
|
||||
@brief This baseclass provides the common functionality of an IFD directory entry
|
||||
and defines the interface for derived concrete entries.
|
||||
|
||||
todo: make sure this class is an ABC
|
||||
*/
|
||||
class TiffEntryBase : public TiffComponent {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default constructor
|
||||
TiffEntryBase()
|
||||
: TiffComponent(Group::none, 0),
|
||||
tag_(0), type_(0), count_(0), offset_(0),
|
||||
size_(0), pData_(0), isAllocated_(false) {}
|
||||
//! Virtual destructor.
|
||||
virtual ~TiffEntryBase();
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
//! Return the tag of this entry.
|
||||
uint16_t tag() const { return tag_; }
|
||||
//! Return the Exiv2 type which corresponds to the field type.
|
||||
TypeId typeId() const { return TypeId(type_); }
|
||||
//! Return the number of components in this entry.
|
||||
uint32_t count() const { return count_; }
|
||||
//! Return the offset relative to the start of the TIFF header.
|
||||
uint32_t offset() const { return offset_; }
|
||||
//! Return the size of this component in bytes
|
||||
uint32_t size() const { return size_; }
|
||||
//! Return a pointer to the data area of this component
|
||||
const byte* pData() const { return pData_; }
|
||||
//@}
|
||||
|
||||
protected:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
//! Implements read().
|
||||
virtual void doRead(const byte* pData,
|
||||
uint32_t size,
|
||||
uint32_t start,
|
||||
ByteOrder byteOrder);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
//! Implements decode() for a TIFF IFD entry
|
||||
virtual void doDecode(Image& image, ByteOrder byteOrder) const;
|
||||
//! Implements print() for a TIFF IFD entry
|
||||
virtual void doPrint(std::ostream& os,
|
||||
ByteOrder byteOrder,
|
||||
const std::string& prefix) const;
|
||||
//@}
|
||||
|
||||
private:
|
||||
// DATA
|
||||
uint16_t tag_; //!< Tag that identifies the field
|
||||
uint16_t type_; //!< Field Type
|
||||
uint32_t count_; //!< The number of values of the indicated Type
|
||||
uint32_t offset_; //!< Offset to the data area from start of the TIFF header
|
||||
/*!
|
||||
Size of the data buffer holding the value in bytes, there is no
|
||||
minimum size.
|
||||
*/
|
||||
uint32_t size_;
|
||||
const byte* pData_; //!< Pointer to the data area
|
||||
bool isAllocated_; //!< True if this entry owns the value data
|
||||
|
||||
}; // class TiffEntryBase
|
||||
|
||||
/*!
|
||||
@brief A standard TIFF IFD entry. The value is kept in a data buffer.
|
||||
*/
|
||||
class TiffEntry : public TiffEntryBase {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Virtual destructor.
|
||||
virtual ~TiffEntry() {}
|
||||
//@}
|
||||
|
||||
private:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
//! Implements read().
|
||||
virtual void doRead(const byte* pData,
|
||||
uint32_t size,
|
||||
uint32_t start,
|
||||
ByteOrder byteOrder);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
virtual void doDecode(Image& image, ByteOrder byteOrder) const;
|
||||
//! Implements print() for a TIFF IFD entry
|
||||
virtual void doPrint(std::ostream& os,
|
||||
ByteOrder byteOrder,
|
||||
const std::string& prefix) const;
|
||||
//@}
|
||||
|
||||
}; // class TiffEntry
|
||||
|
||||
//! This class models a TIFF directory (%Ifd).
|
||||
class TiffDirectory : public TiffComponent {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default constructor
|
||||
TiffDirectory(uint16_t group, const TiffStructure* pTiffStructure)
|
||||
: TiffComponent(group, pTiffStructure), pNext_(0) {}
|
||||
//! Virtual destructor
|
||||
virtual ~TiffDirectory();
|
||||
//@}
|
||||
|
||||
private:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
virtual void doRead(const byte* pData,
|
||||
uint32_t size,
|
||||
uint32_t start,
|
||||
ByteOrder byteOrder);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
virtual void doDecode(Image& image,
|
||||
ByteOrder byteOrder) const;
|
||||
|
||||
virtual void doPrint(std::ostream& os,
|
||||
ByteOrder byteOrder,
|
||||
const std::string& prefix) const;
|
||||
//@}
|
||||
|
||||
private:
|
||||
// DATA
|
||||
Components components_; //!< List of components in this directory
|
||||
TiffComponent* pNext_; //!< Pointer to the next IFD
|
||||
|
||||
}; // class TiffDirectory
|
||||
|
||||
//! This class models a TIFF sub-directory (%SubIfd).
|
||||
class TiffSubIfd : public TiffEntryBase {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default constructor
|
||||
TiffSubIfd(uint16_t group, const TiffStructure* pTiffStructure)
|
||||
: ifd_(group, pTiffStructure) {}
|
||||
//! Virtual destructor
|
||||
virtual ~TiffSubIfd() {}
|
||||
//@}
|
||||
|
||||
private:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
virtual void doRead(const byte* pData,
|
||||
uint32_t size,
|
||||
uint32_t start,
|
||||
ByteOrder byteOrder);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
virtual void doDecode(Image& image,
|
||||
ByteOrder byteOrder) const;
|
||||
|
||||
virtual void doPrint(std::ostream& os,
|
||||
ByteOrder byteOrder,
|
||||
const std::string& prefix) const;
|
||||
//@}
|
||||
|
||||
private:
|
||||
// DATA
|
||||
TiffDirectory ifd_; //!< The subdirectory
|
||||
|
||||
}; // class TiffDirectory
|
||||
|
||||
/*!
|
||||
@brief This class models a TIFF header structure.
|
||||
*/
|
||||
class TiffHeade2 {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default constructor
|
||||
TiffHeade2()
|
||||
: byteOrder_ (littleEndian),
|
||||
offset_ (0x00000008)
|
||||
{}
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Read the TIFF header from a data buffer. Return false if the
|
||||
data buffer does not contain a TIFF header, else true.
|
||||
|
||||
@param pData Pointer to the data buffer.
|
||||
@param size Number of bytes in the data buffer.
|
||||
*/
|
||||
bool read(const byte* pData, uint32_t size);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
/*!
|
||||
@brief Write the TIFF header to the binary image \em blob.
|
||||
This method appends to the blob.
|
||||
|
||||
@param blob Binary image to add to.
|
||||
|
||||
@throw Error If the header cannot be written.
|
||||
*/
|
||||
void write(Blob& blob) const;
|
||||
/*!
|
||||
@brief Print debug info for the TIFF header to \em os.
|
||||
|
||||
@param os Output stream to write to.
|
||||
@param prefix Prefix to be written before each line of output.
|
||||
*/
|
||||
void print(std::ostream& os, const std::string& prefix ="") const;
|
||||
//! Return the byte order (little or big endian).
|
||||
ByteOrder byteOrder() const { return byteOrder_; }
|
||||
//! Return the offset to the start of the root directory
|
||||
uint32_t offset() const { return offset_; }
|
||||
//@}
|
||||
|
||||
private:
|
||||
// DATA
|
||||
ByteOrder byteOrder_; //!< Applicable byte order
|
||||
uint32_t offset_; //!< Offset to the start of the root dir
|
||||
|
||||
static const uint16_t tag_; //!< 42, identifies the buffer as TIFF data
|
||||
|
||||
}; // class TiffHeade2
|
||||
|
||||
/*!
|
||||
Type for a function pointer for functions to create TIFF components.
|
||||
Todo: This may eventually need to also have access to the image or parse tree
|
||||
in order to make decisions based on the value of other tags.
|
||||
*/
|
||||
typedef TiffComponent::AutoPtr (*NewTiffCompFct)(uint16_t group,
|
||||
const TiffStructure* tiffStructure);
|
||||
|
||||
/*!
|
||||
Table describing the TIFF structure of an image format for reading and writing.
|
||||
Different tables can be used to support different TIFF based image formats.
|
||||
*/
|
||||
struct TiffStructure {
|
||||
int32_t tag_; //!< Tag
|
||||
uint16_t group_; //!< Group that contains the tag
|
||||
NewTiffCompFct newTiffCompFct_; //!< Function to create the correct TIFF component
|
||||
uint16_t newGroup_; //!< Group of the newly created component
|
||||
};
|
||||
|
||||
/*!
|
||||
Stateless parser class for data in TIFF format.
|
||||
*/
|
||||
class TiffParser {
|
||||
public:
|
||||
/*!
|
||||
@brief Decode TIFF metadata from a data buffer \em pData of length
|
||||
\em size into \em image.
|
||||
|
||||
This is the entry point to access image data in TIFF format. The
|
||||
parser uses classes TiffHeade2, TiffEntry, TiffDirectory.
|
||||
|
||||
@param pImage Pointer to the %Exiv2 TIFF image to hold the
|
||||
metadata read from the buffer.
|
||||
@param pTiffStructure Pointer to a table describing the TIFF structure
|
||||
used to decode the data.
|
||||
@param pData Pointer to the data buffer. Must point to data
|
||||
in TIFF format; no checks are performed.
|
||||
@param size Length of the data buffer.
|
||||
|
||||
@throw Error If the data buffer cannot be parsed.
|
||||
*/
|
||||
static void decode( Image* pImage,
|
||||
const TiffStructure* pTiffStructure,
|
||||
const byte* pData,
|
||||
uint32_t size);
|
||||
/*!
|
||||
@brief Create the appropriate TiffComponent to handle the \em tag in
|
||||
\em group.
|
||||
|
||||
Uses table \em pTiffStructure to derive the correct component. If a
|
||||
tag, group tupel is not found in the table, a TiffEntry is created. If
|
||||
the pointer that is returned is 0, then the tag should be ignored.
|
||||
*/
|
||||
static TiffComponent::AutoPtr create( int32_t tag,
|
||||
uint16_t group,
|
||||
const TiffStructure* pTiffStructure);
|
||||
}; // class TiffParser
|
||||
|
||||
// *****************************************************************************
|
||||
// template, inline and free functions
|
||||
|
||||
//!< Function to create and initialize a new TIFF directory
|
||||
TiffComponent::AutoPtr newTiffDirectory(uint16_t group,
|
||||
const TiffStructure* pTiffStructure);
|
||||
|
||||
//!< Function to create and initialize a new TIFF sub-directory
|
||||
TiffComponent::AutoPtr newTiffSubIfd(uint16_t group,
|
||||
const TiffStructure* pTiffStructure);
|
||||
|
||||
} // namespace Exiv2
|
||||
|
||||
#endif // #ifndef TIFFPARSER_HPP_
|
Loading…
Reference in New Issue