You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

870 lines
35 KiB
C++

// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@file exif.hpp
@brief Encoding and decoding of Exif data
@version $Name: $ $Revision: 1.58 $
@author Andreas Huggel (ahu)
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
@date 09-Jan-04, ahu: created
*/
#ifndef EXIF_HPP_
#define EXIF_HPP_
// *****************************************************************************
// included header files
#include "metadatum.hpp"
#include "types.hpp"
#include "error.hpp"
#include "image.hpp"
#include "value.hpp"
#include "ifd.hpp"
#include "tags.hpp"
// + standard includes
#include <string>
#include <vector>
#include <memory>
// *****************************************************************************
// namespace extensions
/*!
@brief Provides classes and functions to encode and decode Exif and Iptc data.
This namespace corresponds to the <b>libexiv2</b> library.
*/
namespace Exiv2 {
// *****************************************************************************
// class declarations
class ExifData;
class MakerNote;
// *****************************************************************************
// class definitions
/*!
@brief Information related to one Exif tag.
*/
class Exifdatum : public Metadatum {
friend std::ostream& operator<<(std::ostream&, const Exifdatum&);
public:
//! @name Creators
//@{
/*!
@brief Constructor for new tags created by an application. The
%Exifdatum is created from a key / value pair. %Exifdatum copies
(clones) the key and value if one is provided. Alternatively,
a program can create an 'empty' %Exifdatum with only a key
and set the value using setValue().
@param key ExifKey.
@param pValue Pointer to a Exifdatum value.
@throw Error ("Invalid key") if the key cannot be parsed and converted.
*/
explicit Exifdatum(const ExifKey& key, const Value* pValue =0);
//! Constructor to build a Exifdatum from an IFD entry.
Exifdatum(const Entry& e, ByteOrder byteOrder);
//! Copy constructor
Exifdatum(const Exifdatum& rhs);
//! Destructor
virtual ~Exifdatum();
//@}
//! @name Manipulators
//@{
//! Assignment operator
Exifdatum& operator=(const Exifdatum& rhs);
/*!
@brief Set the value. This method copies (clones) the value pointed
to by pValue.
*/
void setValue(const Value* pValue);
/*!
@brief Set the value from an IFD entry.
*/
void setValue(const Entry& e, ByteOrder byteOrder);
/*!
@brief Set the value to the string buf.
Uses Value::read(const std::string& buf). If the Exifdatum does
not have a value yet, then an AsciiValue is created.
*/
void setValue(const std::string& buf);
//@}
//! @name Accessors
//@{
//! Return the key of the %Exifdatum.
std::string key() const
{ return key_.get() == 0 ? "" : key_->key(); }
//! Return the name of the group (the second part of the key)
std::string groupName() const
{ return key_.get() == 0 ? "" : key_->groupName(); }
//! Return the name of the tag (which is also the third part of the key)
std::string tagName() const
{ return key_.get() == 0 ? "" : key_->tagName(); }
//! Return the tag
uint16_t tag() const
{ return key_.get() == 0 ? 0xffff : key_->tag(); }
//! Return the IFD id
IfdId ifdId() const
{ return key_.get() == 0 ? ifdIdNotSet : key_->ifdId(); }
//! Return the name of the IFD
const char* ifdName() const
{ return key_.get() == 0 ? "" : key_->ifdName(); }
//! Return the related image item (deprecated)
std::string ifdItem() const
{ return key_.get() == 0 ? "" : key_->ifdItem(); }
//! Return the index (unique id of this key within the original IFD)
int idx() const
{ return key_.get() == 0 ? 0 : key_->idx(); }
/*!
@brief Write value to a data buffer and return the number
of bytes written.
The user must ensure that the buffer has enough memory. Otherwise
the call results in undefined behaviour.
@param buf Data buffer to write to.
@param byteOrder Applicable byte order (little or big endian).
@return Number of characters written.
*/
long copy(byte* buf, ByteOrder byteOrder) const
{ return value_.get() == 0 ? 0 : value_->copy(buf, byteOrder); }
//! Return the type id of the value
TypeId typeId() const
{ return value_.get() == 0 ? invalidTypeId : value_->typeId(); }
//! Return the name of the type
const char* typeName() const
{ return TypeInfo::typeName(typeId()); }
//! Return the size in bytes of one component of this type
long typeSize() const
{ return TypeInfo::typeSize(typeId()); }
//! Return the number of components in the value
long count() const
{ return value_.get() == 0 ? 0 : value_->count(); }
//! Return the size of the value in bytes
long size() const
{ return value_.get() == 0 ? 0 : value_->size(); }
//! Return the value as a string.
std::string toString() const
{ return value_.get() == 0 ? "" : value_->toString(); }
/*!
@brief Return the n-th component of the value converted to long. The
return value is -1 if the value of the Exifdatum is not set and
the behaviour of the method is undefined if there is no n-th
component.
*/
long toLong(long n =0) const
{ return value_.get() == 0 ? -1 : value_->toLong(n); }
/*!
@brief Return the n-th component of the value converted to float. The
return value is -1 if the value of the Exifdatum is not set and
the behaviour of the method is undefined if there is no n-th
component.
*/
float toFloat(long n =0) const
{ return value_.get() == 0 ? -1 : value_->toFloat(n); }
/*!
@brief Return the n-th component of the value converted to
Rational. The return value is -1/1 if the value of the
Exifdatum is not set and the behaviour of the method is
undefined if there is no n-th component.
*/
Rational toRational(long n =0) const
{ return value_.get() == 0 ? Rational(-1, 1) : value_->toRational(n); }
/*!
@brief Return a pointer to a copy (clone) of the value. The caller
is responsible to delete this copy when it's no longer needed.
This method is provided for users who need full control over the
value. A caller may, e.g., downcast the pointer to the appropriate
subclass of Value to make use of the interface of the subclass to set
or modify its contents.
@return A pointer to a copy (clone) of the value, 0 if the value is
not set.
*/
Value::AutoPtr getValue() const
{ return value_.get() == 0 ? Value::AutoPtr(0) : value_->clone(); }
/*!
@brief Return a constant reference to the value.
This method is provided mostly for convenient and versatile output of
the value which can (to some extent) be formatted through standard
stream manipulators. Do not attempt to write to the value through
this reference.
<b>Example:</b> <br>
@code
ExifData::const_iterator i = exifData.findKey(key);
if (i != exifData.end()) {
std::cout << i->key() << " " << std::hex << i->value() << "\n";
}
@endcode
@return A constant reference to the value.
@throw Error ("Value not set") if the value is not set.
*/
const Value& value() const
{ if (value_.get() != 0) return *value_; throw Error("Value not set"); }
//@}
private:
// DATA
ExifKey::AutoPtr key_; //!< Key
Value::AutoPtr value_; //!< Value
}; // class Exifdatum
/*!
@brief Output operator for Exifdatum types, prints the interpreted
tag value.
*/
std::ostream& operator<<(std::ostream& os, const Exifdatum& md);
/*!
@brief Exif %Thumbnail image. This abstract base class provides the
interface for the thumbnail image that is optionally embedded in
the Exif data.
*/
class Thumbnail {
public:
//! @name Creators
//@{
//! Virtual destructor
virtual ~Thumbnail() {}
//@}
//! @name Manipulators
//@{
/*!
@brief Read the thumbnail from the data buffer buf, using Exif
metadata exifData. Return 0 if successful.
@param buf Data buffer containing the thumbnail data. The buffer must
start with the TIFF header.
@param len Number of bytes in the data buffer.
@param exifData Exif data corresponding to the data buffer.
@param byteOrder The byte order used for the encoding of TIFF
thumbnails. It determines the byte order of the resulting
thumbnail image, if it is in TIFF format. For JPEG thumbnails
the byte order is not used.
@return 0 if successful<br>
-1 if there is no thumbnail image in the Exif data<BR>
1 in case of inconsistent JPEG thumbnail Exif data<BR>
2 in case of inconsistent TIFF thumbnail Exif data
*/
virtual int read(const byte* buf,
long len,
const ExifData& exifData,
ByteOrder byteOrder =littleEndian) =0;
/*!
@brief Update the internal offset and the thumbnail data offsets
in IFD1 assuming the thumbnail data follows immediately after
IFD1.
If the type of the thumbnail image is JPEG, JPEGInterchangeFormat is
set to point directly behind the data area of IFD1. If the type is
TIFF, StripOffsets from the thumbnail image are adjusted to point to
the strips, which have to follow immediately after IFD1. Use copy() to
write the thumbnail image data. The offset of IFD1 must be set
correctly. Changing the size or data size of IFD1 invalidates the
thumbnail data offsets set by this method.
*/
virtual void setOffsets(Ifd& ifd1, ByteOrder byteOrder) =0;
//@}
//! @name Accessors
//@{
/*!
@brief Write thumbnail to file path.
@return 0 if successful;<BR>
-1 if the file couldn't be open;<BR>
4 if writing to the output stream failed.
*/
virtual int write(const std::string& path) const =0;
/*!
@brief Return a short string for the format of the thumbnail
("TIFF", "JPEG").
*/
virtual const char* format() const =0;
/*!
@brief Return the file extension for the format of the thumbnail
(".tif", ".jpg").
*/
virtual const char* extension() const =0;
/*!
@brief Copy the thumbnail image data (without the IFD, if any) to the
data buffer buf. The user must ensure that the buffer has
enough memory. Otherwise the call results in undefined
behaviour. Return the number of characters written.
*/
virtual long copy(byte* buf) const =0;
/*!
@brief Update the Exif data according to the actual thumbnail image.
If the type of the thumbnail image is JPEG, JPEGInterchangeFormat is
set to 0. If the type is TIFF, StripOffsets are set to the offsets of
the IFD of the thumbnail image itself.
*/
virtual void update(ExifData& exifData) const =0;
/*!
@brief Return the position of the thumbnail image data from the
start of the TIFF header in the original Exif data.
*/
virtual long offset() const =0;
/*!
@brief Return the size of the thumbnail image (the size it
would occupy when extracted from the Exif data)
*/
virtual long size() const =0;
/*!
@brief Return the size of the thumbnail data (data only, without the
IFD, in case of a TIFF thumbnail).
*/
virtual long dataSize() const =0;
//@}
protected:
//! @name Manipulators
//@{
/*!
@brief Assignment operator. Protected so that it can only be used
by subclasses but not directly.
*/
Thumbnail& operator=(const Thumbnail& rhs);
//@}
}; // class Thumbnail
//! Exif thumbnail image in TIFF format
class TiffThumbnail : public Thumbnail {
public:
//! @name Creators
//@{
//! Virtual destructor
TiffThumbnail();
//! Virtual destructor
virtual ~TiffThumbnail();
//! Copy constructor
TiffThumbnail(const TiffThumbnail& rhs);
//@}
//! @name Manipulators
//@{
//! Assignment operator.
TiffThumbnail& operator=(const TiffThumbnail& rhs);
int read(const byte* buf,
long len,
const ExifData& exifData,
ByteOrder byteOrder =littleEndian);
void setOffsets(Ifd& ifd1, ByteOrder byteOrder);
//@}
//! @name Accessors
//@{
int write(const std::string& path) const;
const char* format() const;
const char* extension() const;
long copy(byte* buf) const;
void update(ExifData& exifData) const;
long offset() const;
long size() const;
long dataSize() const;
//@}
private:
// DATA
long offset_; // Original offset of the thumbnail data
// from the start of the TIFF header
long size_; //!< Size of the image data
byte* pImage_; //!< Thumbnail image data
TiffHeader tiffHeader_; //!< Thumbnail TIFF Header
Ifd ifd_; //!< Thumbnail IFD (IFD1 of the Exif data)
}; // class TiffThumbnail
//! Exif thumbnail image in JPEG format
class JpegThumbnail : public Thumbnail {
public:
//! @name Creators
//@{
//! Virtual destructor
JpegThumbnail();
//! Virtual destructor
virtual ~JpegThumbnail();
//! Copy constructor
JpegThumbnail(const JpegThumbnail& rhs);
//@}
//! @name Manipulators
//@{
//! Assignment operator.
JpegThumbnail& operator=(const JpegThumbnail& rhs);
int read(const byte* buf,
long len,
const ExifData& exifData,
ByteOrder byteOrder =littleEndian);
void setOffsets(Ifd& ifd1, ByteOrder byteOrder);
//@}
//! @name Accessors
//@{
int write(const std::string& path) const;
const char* format() const;
const char* extension() const;
long copy(byte* buf) const;
void update(ExifData& exifData) const;
long offset() const;
long size() const;
long dataSize() const;
//@}
private:
// DATA
long offset_; // Original offset of the thumbnail data
// from the start of the TIFF header
long size_; // Size of the image data
byte* pImage_; // Thumbnail image data
}; // class JpegThumbnail
//! Container type to hold all metadata
typedef std::vector<Exifdatum> ExifMetadata;
//! Unary predicate that matches a Exifdatum with a given ifd id and idx
class FindMetadatumByIfdIdIdx {
public:
//! Constructor, initializes the object with the ifd id and idx to look for
FindMetadatumByIfdIdIdx(IfdId ifdId, int idx)
: ifdId_(ifdId), idx_(idx) {}
/*!
@brief Returns true if the ifd id and idx of the argument Exifdatum
is equal to that of the object.
*/
bool operator()(const Exifdatum& exifdatum) const
{ return ifdId_ == exifdatum.ifdId() && idx_ == exifdatum.idx(); }
private:
IfdId ifdId_;
int idx_;
}; // class FindMetadatumByIfdIdIdx
/*!
@brief A container for Exif data. This is a top-level class of
the %Exiv2 library.
Provide high-level access to the Exif data of an image:
- read Exif information from JPEG files
- access metadata through keys and standard C++ iterators
- add, modify and delete metadata
- write Exif data to JPEG files
- extract Exif metadata to files, insert from these files
- extract and delete Exif thumbnail (JPEG and TIFF thumbnails)
*/
class ExifData {
//! @name Not implemented
//@{
//! Copying not allowed (Todo: implement me!)
ExifData(const ExifData& rhs);
//! Assignment not allowed (IFD does not have an assignment operator)
ExifData& operator=(const ExifData& rhs);
//@}
public:
//! ExifMetadata iterator type
typedef ExifMetadata::iterator iterator;
//! ExifMetadata const iterator type
typedef ExifMetadata::const_iterator const_iterator;
//! @name Creators
//@{
//! Default constructor
ExifData();
//! Destructor
~ExifData();
//@}
//! @name Manipulators
//@{
/*!
@brief Read the Exif data from file path.
@param path Path to the file
@return 0 if successful;<BR>
3 if the file contains no Exif data;<BR>
the return code of Image::readMetadata()
if the call to this function fails<BR>
the return code of read(const char* buf, long len)
if the call to this function fails
*/
int read(const std::string& path);
/*!
@brief Read the Exif data from a byte buffer. The data buffer
must start with the TIFF header.
@param buf Pointer to the data buffer to read from
@param len Number of bytes in the data buffer
@return 0 if successful.
*/
int read(const byte* buf, long len);
/*!
@brief Write the Exif data to file path. If an Exif data section
already exists in the file, it is replaced. If there is no
metadata and no thumbnail to write, the Exif data section is
deleted from the file. Otherwise, an Exif data section is
created. See copy(byte* buf) for further details.
@return 0 if successful.
*/
int write(const std::string& path);
/*!
@brief Write the Exif data to a binary file. By convention, the
filename extension should be ".exv". This file format contains
the Exif data as it is found in a JPEG file, starting with the
APP1 marker 0xffe1, the size of the data and the string
"Exif\0\0". Exv files can be read with
int read(const std::string& path) just like image Exif data.
*/
int writeExifData(const std::string& path);
/*!
@brief Write the Exif data to a data buffer, return number of bytes
written. The copied data starts with the TIFF header.
Tries to update the original data buffer and write it back with
minimal changes, in a 'non-intrusive' fashion, if possible. In this
case, tag data that ExifData does not understand stand a good chance
to remain valid. (In particular, if the Exif data contains a
Makernote in IFD format, the offsets in its IFD will remain valid.)
<BR>
If 'non-intrusive' writing is not possible, the Exif data will be
re-built from scratch, in which case the absolute position of the
metadata entries within the data buffer may (and in most cases will)
be different from their original position. Furthermore, in this case,
the Exif data is updated with the metadata from the actual thumbnail
image (overriding existing metadata).
@param buf The data buffer to write to. The user must ensure that the
buffer has enough memory. Otherwise the call results in
undefined behaviour.
@return Number of characters written to the buffer.
*/
long copy(byte* buf);
/*!
@brief Add all (IFD) entries in the range from iterator position begin
to iterator position end to the Exif metadata. No duplicate
checks are performed, i.e., it is possible to add multiple
metadata with the same key.
*/
void add(Entries::const_iterator begin,
Entries::const_iterator end,
ByteOrder byteOrder);
/*!
@brief Add a Exifdatum from the supplied key and value pair. This
method copies (clones) key and value. No duplicate checks are
performed, i.e., it is possible to add multiple metadata with
the same key.
*/
void add(const ExifKey& key, const Value* pValue);
/*!
@brief Add a copy of the Exifdatum to the Exif metadata. No
duplicate checks are performed, i.e., it is possible to add
multiple metadata with the same key.
@throw Error ("Inconsistent MakerNote") if Exifdatum is a MakerNote
tag for a different MakerNote than that of the ExifData.
*/
void add(const Exifdatum& Exifdatum);
/*!
@brief Delete the Exifdatum at iterator position pos, return the
position of the next Exifdatum. Note that iterators into
the metadata, including pos, are potentially invalidated
by this call.
*/
iterator erase(iterator pos);
//! Sort metadata by key
void sortByKey();
//! Sort metadata by tag
void sortByTag();
//! Begin of the metadata
iterator begin() { return exifMetadata_.begin(); }
//! End of the metadata
iterator end() { return exifMetadata_.end(); }
/*!
@brief Find a Exifdatum with the given key, return an iterator to it.
If multiple metadata with the same key exist, it is undefined
which of the matching metadata is found.
*/
iterator findKey(const ExifKey& key);
/*!
@brief Find the Exifdatum with the given ifd id and idx, return an
iterator to it.
This method can be used to uniquely identify a Exifdatum that was
created from an IFD or from the makernote (with idx greater than
0). Metadata created by an application (not read from an IFD or a
makernote) all have their idx field set to 0, i.e., they cannot be
uniquely identified with this method. If multiple metadata with the
same key exist, it is undefined which of the matching metadata is
found.
*/
iterator findIfdIdIdx(IfdId ifdId, int idx);
/*!
@brief Delete the thumbnail from the Exif data. Removes all related
(%Thumbnail.*.*, i.e., IFD1) metadata as well.
@return The number of bytes of thumbnail data erased from the original
Exif data. Note that the original image size may differ from
the size of the image after deleting the thumbnail by more
than this number. This is the case if the Exif data contains
extra bytes (often at the end of the Exif block) or gaps and
the thumbnail is not located at the end of the Exif block so
that non-intrusive writing of a truncated Exif block is not
possible. Instead it is in this case necessary to write the
Exif data, without the thumbnail, from the metadata and all
extra bytes and gaps are lost, resulting in a smaller image.
*/
long eraseThumbnail();
//@}
//! @name Accessors
//@{
/*!
@brief Erase the Exif data section from file path.
@param path Path to the file.
@return 0 if successful.
*/
int erase(const std::string& path) const;
//! Begin of the metadata
const_iterator begin() const { return exifMetadata_.begin(); }
//! End of the metadata
const_iterator end() const { return exifMetadata_.end(); }
/*!
@brief Find a Exifdatum with the given key, return a const iterator to
it. If multiple metadata with the same key exist, it is
undefined which of the matching metadata is found.
*/
const_iterator findKey(const ExifKey& key) const;
/*!
@brief Find the Exifdatum with the given ifd id and idx, return an
iterator to it.
This method can be used to uniquely identify a Exifdatum that was
created from an IFD or from the makernote (with idx greater than
0). Metadata created by an application (not read from an IFD or a
makernote) all have their idx field set to 0, i.e., they cannot be
uniquely identified with this method. If multiple metadata with the
same key exist, it is undefined which of the matching metadata is
found.
*/
const_iterator findIfdIdIdx(IfdId ifdId, int idx) const;
//! Get the number of metadata entries
long count() const { return static_cast<long>(exifMetadata_.size()); }
/*!
@brief Return the approximate size of all Exif data (TIFF header plus
metadata). The number returned may be bigger than the actual
size of the Exif data, but it is never smaller. Only copy()
returns the exact size.
*/
long size() const;
//! Returns the byte order as specified in the TIFF header
ByteOrder byteOrder() const { return tiffHeader_.byteOrder(); }
/*!
@brief Write the thumbnail image to a file. A filename extension
is appended to path according to the image type of the
thumbnail, so the path should not include an extension.
This will overwrite an existing file of the same name.
*/
int writeThumbnail(const std::string& path) const
{ return pThumbnail_ ? pThumbnail_->write(path) : 0; }
/*!
@brief Return a short string describing the format of the Exif
thumbnail ("TIFF", "JPEG").
*/
const char* thumbnailFormat() const
{ return pThumbnail_ ? pThumbnail_->format() : ""; }
/*!
@brief Return the file extension for the Exif thumbnail depending
on the format (".tif", ".jpg").
*/
const char* thumbnailExtension() const
{ return pThumbnail_ ? pThumbnail_->extension() : ""; }
/*!
@brief Return the size of the thumbnail image. This is the size that
the thumbnail would occupy when extracted from the Exif data.
*/
long thumbnailSize() const
{ return pThumbnail_ ? pThumbnail_->size() : 0; }
//@}
/*!
@brief Convert the return code from
int read(const std::string& path),
int write(const std::string& path),
int writeExifData(const std::string& path),
int writeThumbnail(const std::string& path) const and
int erase(const std::string& path) const
into an error message.
Todo: Implement global handling of error messages
*/
static std::string strError(int rc, const std::string& path);
private:
//! @name Manipulators
//@{
/*!
@brief Read the thumbnail from the data buffer. Return 0 if successful,
otherwise the thumbnail is deleted.
*/
int readThumbnail();
/*!
@brief Check if the metadata changed and update the internal IFDs and
the MakerNote if the changes are compatible with the existing
data (non-intrusive write support).
@return True if only compatible changes were detected in the metadata
and the internal IFDs and MakerNote (and thus the data buffer)
were updated successfully. Return false, if non-intrusive
writing is not possible. The internal IFDs and the MakerNote
(and thus the data buffer) may or may not be modified in this
case.
*/
bool updateEntries();
/*!
@brief Update the metadata for a range of entries. Called by
updateEntries() for each of the internal IFDs and the MakerNote
(if any).
*/
bool updateRange(const Entries::iterator& begin,
const Entries::iterator& end,
ByteOrder byteOrder);
/*!
@brief Write Exif data to a data buffer the hard way, return number of
bytes written.
Rebuilds the Exif data from scratch, using the TIFF header, metadata
container and thumbnail. In particular, the internal IFDs and the
original data buffer are not used. Furthermore, this method updates
the Exif data with the metadata from the actual thumbnail image
(overriding existing metadata).
*/
long copyFromMetadata(byte* buf);
//@}
//! @name Accessors
//@{
/*!
@brief Check if the metadata is compatible with the internal IFDs for
non-intrusive writing. Return true if compatible, false if not.
@note This function does not detect deleted metadata as incompatible,
although the deletion of metadata is not (yet) a supported
non-intrusive write operation.
*/
bool compatible() const;
/*!
@brief Find the IFD or makernote entry corresponding to ifd id and idx.
@return A pair of which the first part determines if a match was found
and, if true, the second contains an iterator to the entry.
*/
std::pair<bool, Entries::const_iterator>
findEntry(IfdId ifdId, int idx) const;
//! Return a pointer to the internal IFD identified by its IFD id
const Ifd* getIfd(IfdId ifdId) const;
/*!
@brief Check if IFD1, the IFD1 data and thumbnail data are located at
the end of the Exif data. Return true, if they are or if there
is no thumbnail at all, else return false.
*/
bool stdThumbPosition() const;
//@}
// DATA
TiffHeader tiffHeader_;
ExifMetadata exifMetadata_;
//! Pointer to the Exif thumbnail image
Thumbnail* pThumbnail_;
//! Pointer to the MakerNote
std::auto_ptr<MakerNote> makerNote_;
Ifd ifd0_;
Ifd exifIfd_;
Ifd iopIfd_;
Ifd gpsIfd_;
Ifd ifd1_;
long size_; //!< Size of the Exif raw data in bytes
byte* pData_; //!< Exif raw data buffer
/*!
Can be set to false to indicate that non-intrusive writing is not
possible. If it is true (the default), then the compatibility checks
will be performed to determine which writing method to use.
*/
bool compatible_;
}; // class ExifData
// *****************************************************************************
// free functions
/*!
@brief Add all metadata in the range from iterator position begin to
iterator position end, which have an IFD id matching that of the
IFD to the list of directory entries of ifd. No duplicate checks
are performed, i.e., it is possible to add multiple metadata with
the same key to an IFD.
*/
void addToIfd(Ifd& ifd,
ExifMetadata::const_iterator begin,
ExifMetadata::const_iterator end,
ByteOrder byteOrder);
/*!
@brief Add the Exifdatum to the IFD. No duplicate checks are performed,
i.e., it is possible to add multiple metadata with the same key to
an IFD.
*/
void addToIfd(Ifd& ifd, const Exifdatum& exifdatum, ByteOrder byteOrder);
/*!
@brief Add all metadata in the range from iterator position begin to
iterator position end with IFD id 'makerIfd' to the list of
makernote entries of the object pointed to be makerNote. No
duplicate checks are performed, i.e., it is possible to add
multiple metadata with the same key to a makernote.
*/
void addToMakerNote(MakerNote* makerNote,
ExifMetadata::const_iterator begin,
ExifMetadata::const_iterator end,
ByteOrder byteOrder);
/*!
@brief Add the Exifdatum to makerNote, encoded in byte order byteOrder.
No duplicate checks are performed, i.e., it is possible to add
multiple metadata with the same key to a makernote.
*/
void addToMakerNote(MakerNote* makerNote,
const Exifdatum& exifdatum,
ByteOrder byteOrder);
} // namespace Exiv2
#endif // #ifndef EXIF_HPP_