Improved ExifParser doc, fixed TiffParser to filter Panasonic raw tags, tweaks.

v0.27.3
Andreas Huggel 17 years ago
parent 3b4f5b8c35
commit b03cbe50fb

@ -45,6 +45,8 @@ EXIV2_RCSID("@(#) $Id$")
#include "error.hpp"
#include "basicio.hpp"
#include "tiffimage.hpp"
#include "tiffimage_int.hpp"
#include "tiffcomposite_int.hpp" // for Tag::root
// + standard includes
#include <iostream>
@ -57,18 +59,6 @@ EXIV2_RCSID("@(#) $Id$")
// *****************************************************************************
namespace {
//! 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
/*!
@brief Exif %Thumbnail image. This abstract base class provides the
@ -166,6 +156,8 @@ namespace {
// class member definitions
namespace Exiv2 {
using namespace Internal;
/*!
@brief Set the value of \em exifDatum to \em value. If the object already
has a value, it is replaced. Otherwise a new ValueType\<T\> value
@ -508,17 +500,20 @@ namespace Exiv2 {
}
// IPTC and XMP are stored elsewhere, not in the Exif APP1 segment.
const IptcData iptcData;
const XmpData xmpData;
const IptcData emptyIptc;
const XmpData emptyXmp;
// Encode and check if the result fits into a JPEG Exif APP1 segment
WriteMethod wm = TiffParser::encode(blob,
pData,
size,
byteOrder,
ed,
iptcData,
xmpData);
std::auto_ptr<TiffHeaderBase> header(new TiffHeader(byteOrder));
WriteMethod wm = TiffParserWorker::encode(blob,
pData,
size,
ed,
emptyIptc,
emptyXmp,
Tag::root,
TiffMapping::findEncoder,
header.get());
if (blob.size() <= 65527) return wm;
// If it doesn't fit, remove additional tags
@ -604,13 +599,16 @@ namespace Exiv2 {
}
// Encode the remaining Exif tags again, don't care if it fits this time
wm = TiffParser::encode(blob,
pData,
size,
byteOrder,
ed,
iptcData,
xmpData);
wm = TiffParserWorker::encode(blob,
pData,
size,
ed,
emptyIptc,
emptyXmp,
Tag::root,
TiffMapping::findEncoder,
header.get());
#ifdef DEBUG
if (wm == wmIntrusive) {
std::cerr << "SIZE OF EXIF DATA IS " << std::dec << blob.size() << " BYTES\n";
@ -712,7 +710,10 @@ namespace {
void eraseIfd(Exiv2::ExifData& ed, Exiv2::IfdId ifdId)
{
ed.erase(std::remove_if(ed.begin(), ed.end(), FindExifdatum(ifdId)), ed.end());
ed.erase(std::remove_if(ed.begin(),
ed.end(),
Exiv2::Internal::FindExifdatum(ifdId)),
ed.end());
}
//! @endcond
}

@ -518,15 +518,24 @@ namespace Exiv2 {
/*!
@brief Stateless parser class for Exif data. Images use this class to
decode and encode binary Exif data. See class TiffParser for details.
decode and encode binary Exif data.
@note Encode is lossy and is not the inverse of decode.
*/
class EXIV2API ExifParser {
public:
/*!
@brief Decode metadata from a buffer \em pData of length \em size
with binary Exif data to the provided metadata container.
Return byte order in which the data is encoded.
See TiffParser::decode().
The buffer must start with a TIFF header. Return byte order
in which the data is encoded.
@param exifData Exif metadata container.
@param pData Pointer to the data buffer. Must point to data in
binary Exif format; no checks are performed.
@param size Length of the data buffer
@return Byte order in which the data is encoded.
*/
static ByteOrder decode(
ExifData& exifData,
@ -534,8 +543,42 @@ namespace Exiv2 {
uint32_t size
);
/*!
@brief Encode metadata from the provided metadata to Exif format.
See TiffParser::encode().
@brief Encode Exif metadata from the provided metadata to binary Exif
format.
The original binary Exif data in the memory block \em pData, \em size
is parsed and updated in-place if possible ("non-intrusive"
writing). If that is not possible (e.g., if new tags were added), the
entire Exif structure is re-written to the \em blob ("intrusive"
writing). The return value indicates which write method was used. If
it is \c wmNonIntrusive, the original memory \em pData, \em size
contains the result and \em blob is empty. If the return value is
\c wmIntrusive, a new Exif structure was created and returned in
\em blob. The memory block \em pData, \em size may be partly updated in
this case and should not be used anymore.
Encode is a lossy operation. It attempts to fit the Exif data into a
binary block suitable as the payload of a JPEG APP1 Exif segment,
which can be at most 65527 bytes large. Encode omits IFD0 tags that
are "not recorded" in compressed images according to the Exif 2.2
specification. It also doesn't write tags in groups which do not occur
in JPEG images. If the resulting binary block is larger than allowed,
it further deletes specific large preview tags and unknown tags. The
operation succeeds even if the end result is still larger than the
allowed size. Application should therefore always check the size of
the \em blob.
@param blob Container for the binary Exif data if "intrusive"
writing is necessary. Empty otherwise.
@param pData Pointer to the binary Exif data buffer. Must
point to data in Exif format; no checks are
performed. Will be modified if "non-intrusive"
writing is possible.
@param size Length of the data buffer.
@param byteOrder Byte order to use.
@param exifData Exif metadata container.
@return Write method used.
*/
static WriteMethod encode(
Blob& blob,
@ -546,10 +589,9 @@ namespace Exiv2 {
);
/*!
@brief Encode metadata from the provided metadata to Exif format.
See TiffParser::encode().
Encode Exif metadata from the \em ExifData container to binary format
in the \em blob encoded in \em byteOrder.
Encode Exif metadata from the \em ExifData container to binary Exif
format in the \em blob, encoded in \em byteOrder.
This simpler encode method uses "intrusive" writing, i.e., it builds
the binary representation of the metadata from scratch. It does not
@ -560,6 +602,11 @@ namespace Exiv2 {
This is just an inline wrapper for
ExifParser::encode(blob, 0, 0, byteOrder, exifData).
@param blob Container for the binary Exif data if "intrusive"
writing is necessary. Empty otherwise.
@param byteOrder Byte order to use.
@param exifData Exif metadata container.
*/
static void encode(
Blob& blob,

@ -208,11 +208,28 @@ namespace Exiv2 {
const XmpData& xmpData
)
{
// Copy to be able to modify the Exif data
ExifData ed = exifData;
// Delete IFDs which do not occur in TIFF images
static const IfdId filteredIfds[] = {
panaRawIfdId
};
for (unsigned int i = 0; i < EXV_COUNTOF(filteredIfds); ++i) {
#ifdef DEBUG
std::cerr << "Warning: Exif IFD " << filteredIfds[i] << " not encoded\n";
#endif
ed.erase(std::remove_if(ed.begin(),
ed.end(),
FindExifdatum(filteredIfds[i])),
ed.end());
}
std::auto_ptr<TiffHeaderBase> header(new TiffHeader(byteOrder));
return TiffParserWorker::encode(blob,
pData,
size,
exifData,
ed,
iptcData,
xmpData,
Tag::root,

@ -338,6 +338,19 @@ namespace Exiv2 {
}; // 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_

@ -56,10 +56,10 @@ EXIV2_RCSID("@(#) $Id$")
// *****************************************************************************
namespace {
//! Unary predicate that matches an Exifdatum with a given group and index.
class FindExifdatum {
class FindExifdatum2 {
public:
//! Constructor, initializes the object with the group and index to look for.
FindExifdatum(uint16_t group, int idx)
FindExifdatum2(uint16_t group, int idx)
: groupName_(Exiv2::Internal::tiffGroupName(group)), idx_(idx) {}
//! Returns true if group and index match.
bool operator()(const Exiv2::Exifdatum& md) const
@ -71,7 +71,7 @@ namespace {
const char* groupName_;
int idx_;
}; // class FindExifdatum
}; // class FindExifdatum2
}
// *****************************************************************************
@ -640,7 +640,7 @@ namespace Exiv2 {
// Try to find exact match (in case of duplicate tags)
ExifData::iterator pos2 =
std::find_if(exifData_.begin(), exifData_.end(),
FindExifdatum(object->group(), object->idx()));
FindExifdatum2(object->group(), object->idx()));
if (pos2 != exifData_.end() && pos2->key() == key.key()) {
ed = &(*pos2);
pos = pos2; // make sure we delete the correct tag below

@ -481,8 +481,8 @@ namespace Exiv2 {
private:
// DATA
ExifData exifData_; //!< Copy of the Exif data to encode
IptcData iptcData_; //!< Copy of the IPTC data to encode
XmpData xmpData_; //!< Copy of the XMP data to encode
const IptcData& iptcData_; //!< IPTC data to encode, just a reference
const XmpData& xmpData_; //!< XMP data to encode, just a reference
bool del_; //!< Indicates if Exif data entries should be deleted after encoding
TiffComponent* pRoot_; //!< Root element of the composite
TiffComponent* pSourceTree_; //!< Parsed source tree for reference

Loading…
Cancel
Save