|
|
|
// ***************************************************************** -*- C++ -*-
|
|
|
|
/*
|
|
|
|
* Copyright (C) 2004-2009 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_int.hpp
|
|
|
|
@brief Internal class TiffParserWorker to parse TIFF data.
|
|
|
|
@version $Rev$
|
|
|
|
@author Andreas Huggel (ahu)
|
|
|
|
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
|
|
|
@date 23-Apr-08, ahu: created
|
|
|
|
*/
|
|
|
|
#ifndef TIFFIMAGE_INT_HPP_
|
|
|
|
#define TIFFIMAGE_INT_HPP_
|
|
|
|
|
|
|
|
// *****************************************************************************
|
|
|
|
// included header files
|
|
|
|
#include "tifffwd_int.hpp"
|
|
|
|
#include "tiffcomposite_int.hpp"
|
|
|
|
#include "image.hpp"
|
|
|
|
#include "types.hpp"
|
|
|
|
|
|
|
|
// + standard includes
|
|
|
|
|
|
|
|
// *****************************************************************************
|
|
|
|
// namespace extensions
|
|
|
|
namespace Exiv2 {
|
|
|
|
/*!
|
|
|
|
@brief Contains internal objects which are not published and are not part
|
|
|
|
of the <b>libexiv2</b> API.
|
|
|
|
*/
|
|
|
|
namespace Internal {
|
|
|
|
|
|
|
|
// *****************************************************************************
|
|
|
|
// class definitions
|
|
|
|
|
|
|
|
/*!
|
|
|
|
@brief Abstract base class defining the interface of an image header.
|
|
|
|
Used internally by classes for TIFF-based images. Default
|
|
|
|
implementation is for the regular TIFF header.
|
|
|
|
*/
|
|
|
|
class TiffHeaderBase {
|
|
|
|
public:
|
|
|
|
//! @name Creators
|
|
|
|
//@{
|
|
|
|
//! Constructor taking \em tag, \em size and default \em byteOrder and \em offset.
|
|
|
|
TiffHeaderBase(uint16_t tag,
|
|
|
|
uint32_t size,
|
|
|
|
ByteOrder byteOrder,
|
|
|
|
uint32_t offset);
|
|
|
|
//! Virtual destructor.
|
|
|
|
virtual ~TiffHeaderBase() =0;
|
|
|
|
//@}
|
|
|
|
|
|
|
|
//! @name Manipulators
|
|
|
|
//@{
|
|
|
|
/*!
|
|
|
|
@brief Read the image header from a data buffer. Return false if the
|
|
|
|
data buffer does not contain an image header of the expected
|
|
|
|
format, else true.
|
|
|
|
|
|
|
|
@param pData Pointer to the data buffer.
|
|
|
|
@param size Number of bytes in the data buffer.
|
|
|
|
@return True if the TIFF header was read successfully. False if the
|
|
|
|
data buffer does not contain a valid TIFF header.
|
|
|
|
*/
|
|
|
|
virtual bool read(const byte* pData, uint32_t size);
|
|
|
|
//! Set the byte order.
|
|
|
|
virtual void setByteOrder(ByteOrder byteOrder);
|
|
|
|
//! Set the offset to the start of the root directory.
|
|
|
|
virtual void setOffset(uint32_t offset);
|
|
|
|
//@}
|
|
|
|
|
|
|
|
//! @name Accessors
|
|
|
|
//@{
|
|
|
|
/*!
|
|
|
|
@brief Return the image header in binary format.
|
|
|
|
The caller owns this data and %DataBuf ensures that it will be deleted.
|
|
|
|
|
|
|
|
@return Binary header data.
|
|
|
|
*/
|
|
|
|
virtual DataBuf write() const;
|
|
|
|
/*!
|
|
|
|
@brief Print debug info for the image header to \em os.
|
|
|
|
|
|
|
|
@param os Output stream to write to.
|
|
|
|
@param prefix Prefix to be written before each line of output.
|
|
|
|
*/
|
|
|
|
virtual void print(std::ostream& os, const std::string& prefix ="") const;
|
|
|
|
//! Return the byte order (little or big endian).
|
|
|
|
virtual ByteOrder byteOrder() const;
|
|
|
|
//! Return the offset to the start of the root directory.
|
|
|
|
virtual uint32_t offset() const;
|
|
|
|
//! Return the size (in bytes) of the image header.
|
|
|
|
virtual uint32_t size() const;
|
|
|
|
//! Return the tag value (magic number) which identifies the buffer as TIFF data
|
|
|
|
virtual uint16_t tag() const;
|
|
|
|
//@}
|
|
|
|
|
|
|
|
private:
|
|
|
|
// DATA
|
|
|
|
const uint16_t tag_; //!< Tag to identify the buffer as TIFF data
|
|
|
|
const uint32_t size_; //!< Size of the header
|
|
|
|
ByteOrder byteOrder_; //!< Applicable byte order
|
|
|
|
uint32_t offset_; //!< Offset to the start of the root dir
|
|
|
|
|
|
|
|
}; // class TiffHeaderBase
|
|
|
|
|
|
|
|
/*!
|
|
|
|
@brief Standard TIFF header structure.
|
|
|
|
*/
|
|
|
|
class TiffHeader : public TiffHeaderBase {
|
|
|
|
public:
|
|
|
|
//! @name Creators
|
|
|
|
//@{
|
|
|
|
//! Default constructor
|
|
|
|
TiffHeader(ByteOrder byteOrder =littleEndian,
|
|
|
|
uint32_t offset =0x00000008);
|
|
|
|
//! Destructor
|
|
|
|
~TiffHeader();
|
|
|
|
//@}
|
|
|
|
}; // class TiffHeader
|
|
|
|
|
|
|
|
/*!
|
|
|
|
@brief Data structure used as a row (element) of a table (array)
|
|
|
|
defining the TIFF component used for each tag in a group.
|
|
|
|
*/
|
|
|
|
struct TiffGroupStruct {
|
|
|
|
//! Search key for TIFF group structure.
|
|
|
|
struct Key {
|
|
|
|
//! Constructor
|
|
|
|
Key(uint32_t e, uint16_t g) : e_(e), g_(g) {}
|
|
|
|
uint32_t e_; //!< Extended tag
|
|
|
|
uint16_t g_; //!< %Group
|
|
|
|
};
|
|
|
|
|
|
|
|
//! Comparison operator to compare a TiffGroupStruct with a TiffGroupStruct::Key
|
|
|
|
bool operator==(const Key& key) const
|
|
|
|
{
|
|
|
|
return key.g_ == group_
|
|
|
|
&& (Tag::all == extendedTag_ || key.e_ == extendedTag_);
|
|
|
|
}
|
|
|
|
//! Return the tag corresponding to the extended tag
|
|
|
|
uint16_t tag() const { return static_cast<uint16_t>(extendedTag_ & 0xffff); }
|
|
|
|
|
|
|
|
// DATA
|
|
|
|
uint32_t extendedTag_; //!< Tag (32 bit so that it can contain special tags)
|
|
|
|
uint16_t group_; //!< Group that contains the tag
|
|
|
|
NewTiffCompFct newTiffCompFct_; //!< Function to create the correct TIFF component
|
|
|
|
};
|
|
|
|
|
|
|
|
/*!
|
|
|
|
@brief Data structure used as a row of the table which describes TIFF trees.
|
|
|
|
Multiple trees are needed as TIFF-based RAW image formats do not always
|
|
|
|
use standard TIFF layout.
|
|
|
|
*/
|
|
|
|
struct TiffTreeStruct {
|
|
|
|
struct Key;
|
|
|
|
//! Comparison operator to compare a TiffTreeStruct with a TiffTreeStruct::Key
|
|
|
|
bool operator==(const Key& key) const;
|
|
|
|
|
|
|
|
// DATA
|
|
|
|
uint32_t root_; //!< Tree root element, identifies a tree
|
|
|
|
uint16_t group_; //!< Each group is a node in the tree
|
|
|
|
uint16_t parentGroup_; //!< Parent group
|
|
|
|
uint32_t parentExtTag_; //!< Parent tag (32 bit so that it can contain special tags)
|
|
|
|
};
|
|
|
|
|
|
|
|
//! Search key for TIFF tree structure.
|
|
|
|
struct TiffTreeStruct::Key {
|
|
|
|
//! Constructor
|
|
|
|
Key(uint32_t r, uint16_t g) : r_(r), g_(g) {}
|
|
|
|
uint32_t r_; //!< Root
|
|
|
|
uint16_t g_; //!< %Group
|
|
|
|
};
|
|
|
|
|
|
|
|
/*!
|
|
|
|
@brief TIFF component factory.
|
|
|
|
*/
|
|
|
|
class TiffCreator {
|
|
|
|
public:
|
|
|
|
/*!
|
|
|
|
@brief Create the TiffComponent for TIFF entry \em extendedTag and
|
|
|
|
\em group. The embedded lookup table is used to find the correct
|
|
|
|
component creation function. If the pointer that is returned
|
|
|
|
is 0, then the TIFF entry should be ignored.
|
|
|
|
*/
|
|
|
|
static std::auto_ptr<TiffComponent> create(uint32_t extendedTag,
|
|
|
|
uint16_t group);
|
|
|
|
/*!
|
|
|
|
@brief Get the path, i.e., a list of extended tag and group pairs, from
|
|
|
|
the \em root TIFF element to the TIFF entry \em extendedTag and
|
|
|
|
\em group.
|
|
|
|
*/
|
|
|
|
static void getPath(TiffPath& tiffPath,
|
|
|
|
uint32_t extendedTag,
|
|
|
|
uint16_t group,
|
|
|
|
uint32_t root);
|
|
|
|
|
|
|
|
private:
|
|
|
|
static const TiffTreeStruct tiffTreeStruct_[]; //<! TIFF tree structure
|
|
|
|
static const TiffGroupStruct tiffGroupStruct_[]; //<! TIFF group structure
|
|
|
|
|
|
|
|
}; // class TiffCreator
|
|
|
|
|
|
|
|
/*!
|
|
|
|
@brief Stateless parser class for data in TIFF format. Images use this
|
|
|
|
class to decode and encode TIFF-based data.
|
|
|
|
*/
|
|
|
|
class TiffParserWorker {
|
|
|
|
public:
|
|
|
|
/*!
|
|
|
|
@brief Decode TIFF metadata from a data buffer \em pData of length
|
|
|
|
\em size into the provided metadata containers.
|
|
|
|
|
|
|
|
This is the entry point to access image data in TIFF format. The
|
|
|
|
parser uses classes TiffHeader and the TiffComponent and TiffVisitor
|
|
|
|
hierarchies.
|
|
|
|
|
|
|
|
@param exifData Exif metadata container.
|
|
|
|
@param iptcData IPTC metadata container.
|
|
|
|
@param xmpData XMP metadata container.
|
|
|
|
@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.
|
|
|
|
@param root Root tag of the TIFF tree for new TIFF components.
|
|
|
|
@param findDecoderFct Function to access special decoding info.
|
|
|
|
@param pHeader Optional pointer to a TIFF header. If not provided,
|
|
|
|
a standard TIFF header is used.
|
|
|
|
|
|
|
|
@return Byte order in which the data is encoded, invalidByteOrder if
|
|
|
|
decoding failed.
|
|
|
|
*/
|
|
|
|
static ByteOrder decode(
|
|
|
|
ExifData& exifData,
|
|
|
|
IptcData& iptcData,
|
|
|
|
XmpData& xmpData,
|
|
|
|
const byte* pData,
|
|
|
|
uint32_t size,
|
|
|
|
uint32_t root,
|
|
|
|
FindDecoderFct findDecoderFct,
|
|
|
|
TiffHeaderBase* pHeader =0);
|
|
|
|
/*!
|
|
|
|
@brief Encode TIFF metadata from the metadata containers into a
|
|
|
|
memory block \em blob.
|
|
|
|
|
|
|
|
1) Parse the binary image, if one is provided, and
|
|
|
|
2) attempt updating the parsed tree in-place ("non-intrusive writing")
|
|
|
|
3) else, create a new tree and write a new TIFF structure ("intrusive
|
|
|
|
writing"). If there is a parsed tree, it is only used to access the
|
|
|
|
image data in this case.
|
|
|
|
*/
|
|
|
|
static WriteMethod encode(
|
|
|
|
BasicIo& io,
|
|
|
|
const byte* pData,
|
|
|
|
uint32_t size,
|
|
|
|
const ExifData& exifData,
|
|
|
|
const IptcData& iptcData,
|
|
|
|
const XmpData& xmpData,
|
|
|
|
uint32_t root,
|
|
|
|
FindEncoderFct findEncoderFct,
|
|
|
|
TiffHeaderBase* pHeader
|
|
|
|
);
|
|
|
|
|
|
|
|
private:
|
|
|
|
/*!
|
|
|
|
@brief Parse TIFF metadata from a data buffer \em pData of length
|
|
|
|
\em size into a TIFF composite structure.
|
|
|
|
|
|
|
|
@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.
|
|
|
|
@param root Root tag of the TIFF tree.
|
|
|
|
@param pHeader Pointer to a TIFF header.
|
|
|
|
@return An auto pointer with the root element of the TIFF
|
|
|
|
composite structure. If \em pData is 0 or \em size
|
|
|
|
is 0, the return value is a 0 pointer.
|
|
|
|
*/
|
|
|
|
static std::auto_ptr<TiffComponent>
|
|
|
|
parse(const byte* pData,
|
|
|
|
uint32_t size,
|
|
|
|
uint32_t root,
|
|
|
|
TiffHeaderBase* pHeader);
|
|
|
|
|
|
|
|
}; // class TiffParserWorker
|
|
|
|
|
|
|
|
/*!
|
|
|
|
@brief Table of TIFF decoding and encoding functions and find functions.
|
|
|
|
This class is separated from the metadata decoder and encoder
|
|
|
|
visitors so that the parser can be parametrized with a different
|
|
|
|
table if needed. This is used, eg., for CR2 format, which uses a
|
|
|
|
different decoder table.
|
|
|
|
*/
|
|
|
|
class TiffMapping {
|
|
|
|
public:
|
|
|
|
/*!
|
|
|
|
@brief Find the decoder function for a key.
|
|
|
|
|
|
|
|
If the returned pointer is 0, the tag should not be decoded,
|
|
|
|
else the decoder function should be used.
|
|
|
|
|
|
|
|
@param make Camera make
|
|
|
|
@param extendedTag Extended tag
|
|
|
|
@param group %Group
|
|
|
|
|
|
|
|
@return Pointer to the decoder function
|
|
|
|
*/
|
|
|
|
static DecoderFct findDecoder(const std::string& make,
|
|
|
|
uint32_t extendedTag,
|
|
|
|
uint16_t group);
|
|
|
|
/*!
|
|
|
|
@brief Find special encoder function for a key.
|
|
|
|
|
|
|
|
If the returned pointer is 0, the tag should be encoded with the
|
|
|
|
encoder function of the TIFF component, else the encoder function
|
|
|
|
should be used.
|
|
|
|
|
|
|
|
@param make Camera make
|
|
|
|
@param extendedTag Extended tag
|
|
|
|
@param group %Group
|
|
|
|
|
|
|
|
@return Pointer to the encoder function
|
|
|
|
*/
|
|
|
|
static EncoderFct findEncoder(
|
|
|
|
const std::string& make,
|
|
|
|
uint32_t extendedTag,
|
|
|
|
uint16_t group
|
|
|
|
);
|
|
|
|
|
|
|
|
private:
|
|
|
|
static const TiffMappingInfo tiffMappingInfo_[]; //<! TIFF mapping table
|
|
|
|
|
|
|
|
}; // class TiffMapping
|
|
|
|
|
|
|
|
//! Unary predicate that matches an Exifdatum with a given IfdId.
|
|
|
|
class FindExifdatum {
|
|
|
|
public:
|
|
|
|
//! Constructor, initializes the object with the IfdId to look for.
|
|
|
|
FindExifdatum(Exiv2::IfdId ifdId) : ifdId_(ifdId) {}
|
|
|
|
//! Returns true if IFD id matches.
|
|
|
|
bool operator()(const Exiv2::Exifdatum& md) const { return ifdId_ == md.ifdId(); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
Exiv2::IfdId ifdId_;
|
|
|
|
|
|
|
|
}; // class FindExifdatum
|
|
|
|
|
|
|
|
}} // namespace Internal, Exiv2
|
|
|
|
|
|
|
|
#endif // #ifndef TIFFIMAGE_INT_HPP_
|