Removed CIFF classes from published API, doc tweaks.
This commit is contained in:
parent
cbb52db524
commit
00a3ef321b
@ -56,8 +56,6 @@ include $(top_srcdir)/config/config.mk
|
||||
# Add source files of sample programs to this list
|
||||
BINSRC = addmoddel.cpp \
|
||||
convert-test.cpp \
|
||||
crwedit.cpp \
|
||||
crwparse.cpp \
|
||||
exifcomment.cpp \
|
||||
exifdata-test.cpp \
|
||||
exifprint.cpp \
|
||||
|
||||
@ -94,7 +94,8 @@ ifdef HAVE_LIBZ
|
||||
CCSRC += pngimage.cpp \
|
||||
pngchunk.cpp
|
||||
endif
|
||||
CCSRC += psdimage.cpp \
|
||||
CCSRC += properties.cpp \
|
||||
psdimage.cpp \
|
||||
rafimage.cpp \
|
||||
sigmamn.cpp \
|
||||
pentaxmn.cpp \
|
||||
@ -107,7 +108,6 @@ CCSRC += psdimage.cpp \
|
||||
types.cpp \
|
||||
value.cpp \
|
||||
version.cpp \
|
||||
properties.cpp \
|
||||
xmp.cpp \
|
||||
xmpsidecar.cpp
|
||||
|
||||
@ -117,7 +117,9 @@ CSRC = localtime.c
|
||||
endif
|
||||
|
||||
# Add source files of simple applications to this list
|
||||
BINSRC = taglist.cpp
|
||||
BINSRC = crwedit.cpp \
|
||||
crwparse.cpp \
|
||||
taglist.cpp
|
||||
|
||||
# Source files for the Exiv2 application
|
||||
EXIV2MAIN = exiv2.cpp
|
||||
|
||||
@ -2,17 +2,18 @@
|
||||
// crwedit.cpp, $Rev$
|
||||
// Print the CIFF structure of a CRW file
|
||||
|
||||
#include <exiv2/crwimage.hpp>
|
||||
#include <exiv2/futils.hpp>
|
||||
#include "crwimage.hpp"
|
||||
#include "crwimage_int.hpp"
|
||||
#include "futils.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
void remove(Exiv2::CiffHeader* pHead);
|
||||
void add(Exiv2::CiffHeader* pHead);
|
||||
void remove(Exiv2::Internal::CiffHeader* pHead);
|
||||
void add(Exiv2::Internal::CiffHeader* pHead);
|
||||
void help();
|
||||
void write(const std::string& filename, const Exiv2::CiffHeader* pHead);
|
||||
void write(const std::string& filename, const Exiv2::Internal::CiffHeader* pHead);
|
||||
|
||||
int main(int argc, char* const argv[])
|
||||
try {
|
||||
@ -42,7 +43,7 @@ try {
|
||||
if (io.error() || io.eof()) throw Exiv2::Error(14);
|
||||
|
||||
// Parse the image, starting with a CIFF header component
|
||||
Exiv2::CiffHeader::AutoPtr parseTree(new Exiv2::CiffHeader);
|
||||
Exiv2::Internal::CiffHeader::AutoPtr parseTree(new Exiv2::Internal::CiffHeader);
|
||||
parseTree->read(buf.pData_, buf.size_);
|
||||
|
||||
// Allow user to make changes
|
||||
@ -68,7 +69,7 @@ catch (Exiv2::AnyError& e) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void write(const std::string& filename, const Exiv2::CiffHeader* pHead)
|
||||
void write(const std::string& filename, const Exiv2::Internal::CiffHeader* pHead)
|
||||
{
|
||||
Exiv2::Blob blob;
|
||||
pHead->write(blob);
|
||||
@ -83,7 +84,7 @@ void write(const std::string& filename, const Exiv2::CiffHeader* pHead)
|
||||
io.close();
|
||||
}
|
||||
|
||||
void remove(Exiv2::CiffHeader* pHead)
|
||||
void remove(Exiv2::Internal::CiffHeader* pHead)
|
||||
{
|
||||
uint16_t crwTag, crwDir;
|
||||
std::cout << "crwTag> 0x";
|
||||
@ -102,7 +103,7 @@ void remove(Exiv2::CiffHeader* pHead)
|
||||
}
|
||||
}
|
||||
|
||||
void add(Exiv2::CiffHeader* pHead)
|
||||
void add(Exiv2::Internal::CiffHeader* pHead)
|
||||
{
|
||||
uint16_t crwTag, crwDir;
|
||||
uint32_t size;
|
||||
286
src/crwimage.cpp
286
src/crwimage.cpp
@ -42,6 +42,7 @@ EXIV2_RCSID("@(#) $Id$")
|
||||
#endif
|
||||
|
||||
#include "crwimage.hpp"
|
||||
#include "crwimage_int.hpp"
|
||||
#include "error.hpp"
|
||||
#include "futils.hpp"
|
||||
#include "value.hpp"
|
||||
@ -87,6 +88,153 @@ namespace {
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
using namespace Internal;
|
||||
|
||||
CrwImage::CrwImage(BasicIo::AutoPtr io, bool /*create*/)
|
||||
: Image(ImageType::crw, mdExif | mdComment, io)
|
||||
{
|
||||
} // CrwImage::CrwImage
|
||||
|
||||
int CrwImage::pixelWidth() const
|
||||
{
|
||||
Exiv2::ExifData::const_iterator widthIter = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension"));
|
||||
return (widthIter == exifData_.end()) ? 0 : widthIter->toLong();
|
||||
}
|
||||
|
||||
int CrwImage::pixelHeight() const
|
||||
{
|
||||
Exiv2::ExifData::const_iterator heightIter = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension"));
|
||||
return (heightIter == exifData_.end()) ? 0 : heightIter->toLong();
|
||||
}
|
||||
|
||||
void CrwImage::setIptcData(const IptcData& /*iptcData*/)
|
||||
{
|
||||
// not supported
|
||||
throw(Error(32, "IPTC metadata", "CRW"));
|
||||
}
|
||||
|
||||
void CrwImage::readMetadata()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << "Reading CRW 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 (!isCrwType(*io_, false)) {
|
||||
if (io_->error() || io_->eof()) throw Error(14);
|
||||
throw Error(33);
|
||||
}
|
||||
clearMetadata();
|
||||
CrwParser::decode(this, io_->mmap(), io_->size());
|
||||
|
||||
} // CrwImage::readMetadata
|
||||
|
||||
void CrwImage::writeMetadata()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << "Writing CRW 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 (isCrwType(*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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Blob blob;
|
||||
CrwParser::encode(blob, buf.pData_, buf.size_, 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
|
||||
|
||||
} // CrwImage::writeMetadata
|
||||
|
||||
void CrwParser::decode(CrwImage* pCrwImage, const byte* pData, uint32_t size)
|
||||
{
|
||||
assert(pCrwImage != 0);
|
||||
assert(pData != 0);
|
||||
|
||||
// Parse the image, starting with a CIFF header component
|
||||
CiffHeader::AutoPtr head(new CiffHeader);
|
||||
head->read(pData, size);
|
||||
#ifdef DEBUG
|
||||
head->print(std::cerr);
|
||||
#endif
|
||||
head->decode(*pCrwImage);
|
||||
|
||||
} // CrwParser::decode
|
||||
|
||||
void CrwParser::encode(
|
||||
Blob& blob,
|
||||
const byte* pData,
|
||||
uint32_t size,
|
||||
const CrwImage* pCrwImage
|
||||
)
|
||||
{
|
||||
// Parse image, starting with a CIFF header component
|
||||
CiffHeader::AutoPtr head(new CiffHeader);
|
||||
if (size != 0) {
|
||||
head->read(pData, size);
|
||||
}
|
||||
|
||||
// Encode Exif tags from image into the CRW parse tree and write the
|
||||
// structure to the binary image blob
|
||||
CrwMap::encode(head.get(), *pCrwImage);
|
||||
head->write(blob);
|
||||
|
||||
} // CrwParser::encode
|
||||
|
||||
// *************************************************************************
|
||||
// free functions
|
||||
Image::AutoPtr newCrwInstance(BasicIo::AutoPtr io, bool create)
|
||||
{
|
||||
Image::AutoPtr image(new CrwImage(io, create));
|
||||
if (!image->good()) {
|
||||
image.reset();
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
bool isCrwType(BasicIo& iIo, bool advance)
|
||||
{
|
||||
bool result = true;
|
||||
byte tmpBuf[14];
|
||||
iIo.read(tmpBuf, 14);
|
||||
if (iIo.error() || iIo.eof()) {
|
||||
return false;
|
||||
}
|
||||
if (!( ('I' == tmpBuf[0] && 'I' == tmpBuf[1])
|
||||
|| ('M' == tmpBuf[0] && 'M' == tmpBuf[1]))) {
|
||||
result = false;
|
||||
}
|
||||
if ( true == result
|
||||
&& std::memcmp(tmpBuf + 6, CiffHeader::signature(), 8) != 0) {
|
||||
result = false;
|
||||
}
|
||||
if (!advance || !result) iIo.seek(-14, BasicIo::cur);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace Exiv2
|
||||
|
||||
namespace Exiv2 {
|
||||
namespace Internal {
|
||||
|
||||
/*
|
||||
Mapping table used to decode and encode CIFF tags to/from Exif tags. Only
|
||||
a subset of the Exif tags can be mapped to known tags found in CRW files
|
||||
@ -165,113 +313,6 @@ namespace Exiv2 {
|
||||
{ 0xffff, 0xffff }
|
||||
};
|
||||
|
||||
CrwImage::CrwImage(BasicIo::AutoPtr io, bool /*create*/)
|
||||
: Image(ImageType::crw, mdExif | mdComment, io)
|
||||
{
|
||||
} // CrwImage::CrwImage
|
||||
|
||||
int CrwImage::pixelWidth() const
|
||||
{
|
||||
Exiv2::ExifData::const_iterator widthIter = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension"));
|
||||
return (widthIter == exifData_.end()) ? 0 : widthIter->toLong();
|
||||
}
|
||||
|
||||
int CrwImage::pixelHeight() const
|
||||
{
|
||||
Exiv2::ExifData::const_iterator heightIter = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension"));
|
||||
return (heightIter == exifData_.end()) ? 0 : heightIter->toLong();
|
||||
}
|
||||
|
||||
void CrwImage::setIptcData(const IptcData& /*iptcData*/)
|
||||
{
|
||||
// not supported
|
||||
throw(Error(32, "IPTC metadata", "CRW"));
|
||||
}
|
||||
|
||||
void CrwImage::readMetadata()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << "Reading CRW 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 (!isCrwType(*io_, false)) {
|
||||
if (io_->error() || io_->eof()) throw Error(14);
|
||||
throw Error(33);
|
||||
}
|
||||
clearMetadata();
|
||||
CrwParser::decode(this, io_->mmap(), io_->size());
|
||||
|
||||
} // CrwImage::readMetadata
|
||||
|
||||
void CrwImage::writeMetadata()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << "Writing CRW 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 (isCrwType(*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 CIFF header component
|
||||
CiffHeader::AutoPtr head(new CiffHeader);
|
||||
if (buf.size_ != 0) {
|
||||
head->read(buf.pData_, buf.size_);
|
||||
}
|
||||
|
||||
Blob blob;
|
||||
CrwParser::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
|
||||
|
||||
} // CrwImage::writeMetadata
|
||||
|
||||
void CrwParser::decode(CrwImage* pCrwImage, const byte* pData, uint32_t size)
|
||||
{
|
||||
assert(pCrwImage != 0);
|
||||
assert(pData != 0);
|
||||
|
||||
// Parse the image, starting with a CIFF header component
|
||||
CiffHeader::AutoPtr head(new CiffHeader);
|
||||
head->read(pData, size);
|
||||
#ifdef DEBUG
|
||||
head->print(std::cerr);
|
||||
#endif
|
||||
head->decode(*pCrwImage);
|
||||
|
||||
} // CrwParser::decode
|
||||
|
||||
void CrwParser::encode(Blob& blob, CiffHeader* pHead, const CrwImage* pCrwImage)
|
||||
{
|
||||
assert(pCrwImage != 0);
|
||||
assert(pHead != 0);
|
||||
|
||||
// Encode Exif tags from image into the Crw parse tree and write the structure
|
||||
// to the binary image blob
|
||||
CrwMap::encode(pHead, *pCrwImage);
|
||||
pHead->write(blob);
|
||||
|
||||
} // CrwParser::encode
|
||||
|
||||
const char CiffHeader::signature_[] = "HEAPCCDR";
|
||||
|
||||
CiffHeader::~CiffHeader()
|
||||
@ -1299,35 +1340,6 @@ namespace Exiv2 {
|
||||
|
||||
// *************************************************************************
|
||||
// free functions
|
||||
Image::AutoPtr newCrwInstance(BasicIo::AutoPtr io, bool create)
|
||||
{
|
||||
Image::AutoPtr image(new CrwImage(io, create));
|
||||
if (!image->good()) {
|
||||
image.reset();
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
bool isCrwType(BasicIo& iIo, bool advance)
|
||||
{
|
||||
bool result = true;
|
||||
byte tmpBuf[14];
|
||||
iIo.read(tmpBuf, 14);
|
||||
if (iIo.error() || iIo.eof()) {
|
||||
return false;
|
||||
}
|
||||
if (!( ('I' == tmpBuf[0] && 'I' == tmpBuf[1])
|
||||
|| ('M' == tmpBuf[0] && 'M' == tmpBuf[1]))) {
|
||||
result = false;
|
||||
}
|
||||
if ( true == result
|
||||
&& std::memcmp(tmpBuf + 6, CiffHeader::signature(), 8) != 0) {
|
||||
result = false;
|
||||
}
|
||||
if (!advance || !result) iIo.seek(-14, BasicIo::cur);
|
||||
return result;
|
||||
}
|
||||
|
||||
DataBuf packIfdId(const ExifData& exifData,
|
||||
IfdId ifdId,
|
||||
ByteOrder byteOrder)
|
||||
@ -1351,7 +1363,7 @@ namespace Exiv2 {
|
||||
return buf;
|
||||
}
|
||||
|
||||
} // namespace Exiv2
|
||||
}} // namespace Internal, Exiv2
|
||||
|
||||
// *****************************************************************************
|
||||
// local definitions
|
||||
|
||||
714
src/crwimage.hpp
714
src/crwimage.hpp
@ -20,7 +20,7 @@
|
||||
*/
|
||||
/*!
|
||||
@file crwimage.hpp
|
||||
@brief Class CrwImage to access Canon Crw images.<BR>
|
||||
@brief Class CrwImage to access Canon CRW images.<BR>
|
||||
References:<BR>
|
||||
<a href="http://www.sno.phy.queensu.ca/~phil/exiftool/canon_raw.html">The Canon RAW (CRW) File Format</a> by Phil Harvey
|
||||
@version $Rev$
|
||||
@ -40,8 +40,6 @@
|
||||
// + standard includes
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
@ -51,34 +49,13 @@ namespace Exiv2 {
|
||||
// class declarations
|
||||
class ExifData;
|
||||
class IptcData;
|
||||
class CiffHeader;
|
||||
class CiffComponent;
|
||||
struct CrwMapping;
|
||||
struct CrwSubDir;
|
||||
|
||||
// *****************************************************************************
|
||||
// type definitions
|
||||
|
||||
//! Function pointer for functions to decode Exif tags from a Crw entry
|
||||
typedef void (*CrwDecodeFct)(const CiffComponent&,
|
||||
const CrwMapping*,
|
||||
Image&,
|
||||
ByteOrder);
|
||||
|
||||
//! Function pointer for functions to encode Crw entries from Exif tags
|
||||
typedef void (*CrwEncodeFct)(const Image&,
|
||||
const CrwMapping*,
|
||||
CiffHeader*);
|
||||
|
||||
//! Stack to hold a path of Crw directories
|
||||
typedef std::stack<CrwSubDir> CrwDirs;
|
||||
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
// Add Crw to the supported image formats
|
||||
// Add CRW to the supported image formats
|
||||
namespace ImageType {
|
||||
const int crw = 3; //!< Crw image type (see class CrwImage)
|
||||
const int crw = 3; //!< CRW image type (see class CrwImage)
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -137,687 +114,49 @@ namespace Exiv2 {
|
||||
}; // class CrwImage
|
||||
|
||||
/*!
|
||||
Stateless parser class for Canon Crw images (Ciff format).
|
||||
Stateless parser class for Canon CRW images (Ciff format).
|
||||
*/
|
||||
class CrwParser {
|
||||
public:
|
||||
/*!
|
||||
@brief Decode metadata from a Canon Crw image in data buffer \em pData
|
||||
@brief Decode metadata from a Canon CRW image in data buffer \em pData
|
||||
of length \em size into \em crwImage.
|
||||
|
||||
This is the entry point to access image data in Ciff format. The
|
||||
parser uses classes CiffHeader, CiffEntry, CiffDirectory.
|
||||
|
||||
@param pCrwImage Pointer to the %Exiv2 Crw image to hold the metadata
|
||||
@param pCrwImage Pointer to the %Exiv2 CRW image to hold the metadata
|
||||
read from the buffer.
|
||||
@param pData Pointer to the data buffer. Must point to the data of
|
||||
a Crw image; no checks are performed.
|
||||
a CRW image; no checks are performed.
|
||||
@param size Length of the data buffer.
|
||||
|
||||
@throw Error If the data buffer cannot be parsed.
|
||||
*/
|
||||
static void decode(CrwImage* pCrwImage, const byte* pData, uint32_t size);
|
||||
/*!
|
||||
@brief Encode metadata from the Crw image into a data buffer (the
|
||||
binary Crw image).
|
||||
@brief Encode metadata from the CRW image into a data buffer (the
|
||||
binary CRW image).
|
||||
|
||||
@param blob Data buffer for the binary image (target).
|
||||
@param pCrwImage Pointer to the %Exiv2 Crw image with the metadata to
|
||||
@param pData Pointer to the binary image data buffer. Must
|
||||
point to data in CRW format; no checks are
|
||||
performed.
|
||||
@param size Length of the data buffer.
|
||||
@param pCrwImage Pointer to the %Exiv2 CRW image with the metadata to
|
||||
encode.
|
||||
@param pHead Parse tree containing the existing image.
|
||||
|
||||
@throw Error If the metadata from the Crw image cannot be encoded.
|
||||
@throw Error If the metadata from the CRW image cannot be encoded.
|
||||
*/
|
||||
static void encode(Blob& blob, CiffHeader* pHead, const CrwImage* pCrwImage);
|
||||
static void encode(
|
||||
Blob& blob,
|
||||
const byte* pData,
|
||||
uint32_t size,
|
||||
const CrwImage* pCrwImage
|
||||
);
|
||||
|
||||
}; // class CrwParser
|
||||
|
||||
/*!
|
||||
@brief Interface class for components of the CIFF directory hierarchy of a
|
||||
Crw (Canon Raw data) image. Both CIFF directories as well as
|
||||
entries implement this interface. This class is implemented as NVI
|
||||
(non-virtual interface).
|
||||
*/
|
||||
class CiffComponent {
|
||||
public:
|
||||
//! CiffComponent auto_ptr type
|
||||
typedef std::auto_ptr<CiffComponent> AutoPtr;
|
||||
//! Container type to hold all metadata
|
||||
typedef std::vector<CiffComponent*> Components;
|
||||
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default constructor
|
||||
CiffComponent()
|
||||
: dir_(0), tag_(0), size_(0), offset_(0), pData_(0),
|
||||
isAllocated_(false) {}
|
||||
//! Constructor taking a tag and directory
|
||||
CiffComponent(uint16_t tag, uint16_t dir)
|
||||
: dir_(dir), tag_(tag), size_(0), offset_(0), pData_(0),
|
||||
isAllocated_(false) {}
|
||||
//! Virtual destructor.
|
||||
virtual ~CiffComponent();
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
// Default assignment operator is fine
|
||||
|
||||
//! Add a component to the composition
|
||||
void add(AutoPtr component);
|
||||
/*!
|
||||
@brief Add \em crwTagId to the parse tree, if it doesn't exist
|
||||
yet. \em crwDirs contains the path of subdirectories, starting
|
||||
with the root directory, leading to \em crwTagId. Directories
|
||||
that don't exist yet are added along the way. Returns a pointer
|
||||
to the newly added component.
|
||||
|
||||
@param crwDirs Subdirectory path from root to the subdirectory
|
||||
containing the tag to be added.
|
||||
@param crwTagId Tag to be added.
|
||||
|
||||
@return A pointer to the newly added component.
|
||||
*/
|
||||
CiffComponent* add(CrwDirs& crwDirs, uint16_t crwTagId);
|
||||
/*!
|
||||
@brief Remove \em crwTagId from the parse tree, if it exists yet. \em
|
||||
crwDirs contains the path of subdirectories, starting with the
|
||||
root directory, leading to \em crwTagId.
|
||||
|
||||
@param crwDirs Subdirectory path from root to the subdirectory
|
||||
containing the tag to be removed.
|
||||
@param crwTagId Tag to be removed.
|
||||
*/
|
||||
void remove(CrwDirs& crwDirs, uint16_t crwTagId);
|
||||
/*!
|
||||
@brief Read a component from a data buffer
|
||||
|
||||
@param pData Pointer to the data buffer.
|
||||
@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);
|
||||
/*!
|
||||
@brief Write the metadata from the raw metadata component to the
|
||||
binary image \em blob. This method may append to the blob.
|
||||
|
||||
@param blob Binary image to add metadata to
|
||||
@param byteOrder Byte order
|
||||
@param offset Current offset
|
||||
|
||||
@return New offset
|
||||
*/
|
||||
uint32_t write(Blob& blob, ByteOrder byteOrder, uint32_t offset);
|
||||
/*!
|
||||
@brief Writes the entry's value if size is larger than eight bytes. If
|
||||
needed, the value is padded with one 0 byte to make the number
|
||||
of bytes written to the blob even. The offset of the component
|
||||
is set to the offset passed in.
|
||||
@param blob The binary image to write to.
|
||||
@param offset Offset from the start of the directory for this entry.
|
||||
|
||||
@return New offset.
|
||||
*/
|
||||
uint32_t writeValueData(Blob& blob, uint32_t offset);
|
||||
//! Set the directory tag for this component.
|
||||
void setDir(uint16_t dir) { dir_ = dir; }
|
||||
//! Set the data value of the entry.
|
||||
void setValue(DataBuf buf);
|
||||
//@}
|
||||
|
||||
//! Return the type id for a tag
|
||||
static TypeId typeId(uint16_t tag);
|
||||
//! Return the data location id for a tag
|
||||
static DataLocId dataLocation(uint16_t tag);
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
/*!
|
||||
@brief Decode metadata from the component and add it to
|
||||
\em image.
|
||||
|
||||
@param image Image to add 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;
|
||||
/*!
|
||||
@brief Write a directory entry for the component to the \em blob.
|
||||
If the size of the data is not larger than 8 bytes, the
|
||||
data is written to the directory entry.
|
||||
*/
|
||||
void writeDirEntry(Blob& blob, ByteOrder byteOrder) const;
|
||||
//! Return the tag of the directory containing this component
|
||||
uint16_t dir() const { return dir_; }
|
||||
|
||||
//! Return the tag of this component
|
||||
uint16_t tag() const { return tag_; }
|
||||
|
||||
//! Return true if the component is empty, else false
|
||||
bool empty() const;
|
||||
|
||||
/*!
|
||||
@brief Return the data size of this component
|
||||
|
||||
@note If the data is contained in the directory entry itself,
|
||||
this method returns 8, which is the maximum number
|
||||
of data bytes this component can have. The actual size,
|
||||
i.e., used data bytes, may be less than 8.
|
||||
*/
|
||||
uint32_t size() const { return size_; }
|
||||
|
||||
//! Return the offset to the data from the start of the directory
|
||||
uint32_t offset() const { return offset_; }
|
||||
|
||||
//! Return a pointer to the data area of this component
|
||||
const byte* pData() const { return pData_; }
|
||||
|
||||
//! Return the tag id of this component
|
||||
uint16_t tagId() const { return tag_ & 0x3fff; }
|
||||
|
||||
//! Return the type id of thi component
|
||||
TypeId typeId() const { return typeId(tag_); }
|
||||
|
||||
//! Return the data location for this component
|
||||
DataLocId dataLocation() const { return dataLocation(tag_); }
|
||||
|
||||
/*!
|
||||
@brief Finds \em crwTagId in directory \em crwDir, returning a pointer to
|
||||
the component or 0 if not found.
|
||||
*/
|
||||
CiffComponent* findComponent(uint16_t crwTagId, uint16_t crwDir) const;
|
||||
//@}
|
||||
|
||||
protected:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
//! Implements add()
|
||||
virtual void doAdd(AutoPtr component) =0;
|
||||
//! Implements add(). The default implementation does nothing.
|
||||
virtual CiffComponent* doAdd(CrwDirs& crwDirs, uint16_t crwTagId);
|
||||
//! Implements remove(). The default implementation does nothing.
|
||||
virtual void doRemove(CrwDirs& crwDirs, uint16_t crwTagId);
|
||||
//! Implements read(). The default implementation reads a directory entry.
|
||||
virtual void doRead(const byte* pData,
|
||||
uint32_t size,
|
||||
uint32_t start,
|
||||
ByteOrder byteOrder);
|
||||
//! Implements write()
|
||||
virtual uint32_t doWrite(Blob& blob,
|
||||
ByteOrder byteOrder,
|
||||
uint32_t offset) =0;
|
||||
//! Set the size of the data area.
|
||||
void setSize(uint32_t size) { size_ = size; }
|
||||
//! Set the offset for this component.
|
||||
void setOffset(uint32_t offset) { offset_ = offset; }
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
//! Implements decode()
|
||||
virtual void doDecode(Image& image,
|
||||
ByteOrder byteOrder) const =0;
|
||||
//! Implements print(). The default implementation prints the entry.
|
||||
virtual void doPrint(std::ostream& os,
|
||||
ByteOrder byteOrder,
|
||||
const std::string& prefix) const;
|
||||
//! Implements empty(). Default implementation returns true if size is 0.
|
||||
virtual bool doEmpty() const;
|
||||
//! Implements findComponent(). The default implementation checks the entry.
|
||||
virtual CiffComponent* doFindComponent(uint16_t crwTagId,
|
||||
uint16_t crwDir) const;
|
||||
//@}
|
||||
|
||||
private:
|
||||
// DATA
|
||||
uint16_t dir_; //!< Tag of the directory containing this component
|
||||
uint16_t tag_; //!< Tag of the entry
|
||||
uint32_t size_; //!< Size of the data area
|
||||
uint32_t offset_; //!< Offset to the data area from start of dir
|
||||
const byte* pData_; //!< Pointer to the data area
|
||||
bool isAllocated_; //!< True if this entry owns the value data
|
||||
|
||||
}; // class CiffComponent
|
||||
|
||||
/*!
|
||||
@brief This class models one directory entry of a CIFF directory of
|
||||
a Crw (Canon Raw data) image.
|
||||
*/
|
||||
class CiffEntry : public CiffComponent {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default constructor
|
||||
CiffEntry() {}
|
||||
//! Constructor taking a tag and directory
|
||||
CiffEntry(uint16_t tag, uint16_t dir) : CiffComponent(tag, dir) {}
|
||||
|
||||
//! Virtual destructor.
|
||||
virtual ~CiffEntry() {}
|
||||
//@}
|
||||
|
||||
// Default assignment operator is fine
|
||||
|
||||
private:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
using CiffComponent::doAdd;
|
||||
// See base class comment
|
||||
virtual void doAdd(AutoPtr component);
|
||||
/*!
|
||||
@brief Implements write(). Writes only the value data of the entry,
|
||||
using writeValueData().
|
||||
*/
|
||||
virtual uint32_t doWrite(Blob& blob,
|
||||
ByteOrder byteOrder,
|
||||
uint32_t offset);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
// See base class comment
|
||||
virtual void doDecode(Image& image, ByteOrder byteOrder) const;
|
||||
//@}
|
||||
|
||||
}; // class CiffEntry
|
||||
|
||||
//! This class models a CIFF directory of a Crw (Canon Raw data) image.
|
||||
class CiffDirectory : public CiffComponent {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default constructor
|
||||
CiffDirectory() {}
|
||||
//! Constructor taking a tag and directory
|
||||
CiffDirectory(uint16_t tag, uint16_t dir) : CiffComponent(tag, dir) {}
|
||||
|
||||
//! Virtual destructor
|
||||
virtual ~CiffDirectory();
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
// Default assignment operator is fine
|
||||
|
||||
/*!
|
||||
@brief Parse a CIFF directory from a memory buffer
|
||||
|
||||
@param pData Pointer to the memory buffer containing the directory
|
||||
@param size Size of the memory buffer
|
||||
@param byteOrder Applicable byte order (little or big endian)
|
||||
*/
|
||||
void readDirectory(const byte* pData,
|
||||
uint32_t size,
|
||||
ByteOrder byteOrder);
|
||||
//@}
|
||||
|
||||
private:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
// See base class comment
|
||||
virtual void doAdd(AutoPtr component);
|
||||
// See base class comment
|
||||
virtual CiffComponent* doAdd(CrwDirs& crwDirs, uint16_t crwTagId);
|
||||
// See base class comment
|
||||
virtual void doRemove(CrwDirs& crwDirs, uint16_t crwTagId);
|
||||
/*!
|
||||
@brief Implements write(). Writes the complete Ciff directory to
|
||||
the blob.
|
||||
*/
|
||||
virtual uint32_t doWrite(Blob& blob,
|
||||
ByteOrder byteOrder,
|
||||
uint32_t offset);
|
||||
// See base class comment
|
||||
virtual void doRead(const byte* pData,
|
||||
uint32_t size,
|
||||
uint32_t start,
|
||||
ByteOrder byteOrder);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
// See base class comment
|
||||
virtual void doDecode(Image& image,
|
||||
ByteOrder byteOrder) const;
|
||||
|
||||
// See base class comment
|
||||
virtual void doPrint(std::ostream& os,
|
||||
ByteOrder byteOrder,
|
||||
const std::string& prefix) const;
|
||||
|
||||
//! See base class comment. A directory is empty if it has no components.
|
||||
virtual bool doEmpty() const;
|
||||
|
||||
// See base class comment
|
||||
virtual CiffComponent* doFindComponent(uint16_t crwTagId,
|
||||
uint16_t crwDir) const;
|
||||
//@}
|
||||
|
||||
private:
|
||||
// DATA
|
||||
Components components_; //!< List of components in this dir
|
||||
|
||||
}; // class CiffDirectory
|
||||
|
||||
/*!
|
||||
@brief This class models the header of a Crw (Canon Raw data) image. It
|
||||
is the head of a CIFF parse tree, consisting of CiffDirectory and
|
||||
CiffEntry objects. Most of its methods will walk the parse tree to
|
||||
perform the requested action.
|
||||
*/
|
||||
class CiffHeader {
|
||||
public:
|
||||
//! CiffHeader auto_ptr type
|
||||
typedef std::auto_ptr<CiffHeader> AutoPtr;
|
||||
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default constructor
|
||||
CiffHeader()
|
||||
: pRootDir_ (0),
|
||||
byteOrder_ (littleEndian),
|
||||
offset_ (0x0000001a),
|
||||
pPadding_ (0),
|
||||
padded_ (0)
|
||||
{}
|
||||
//! Virtual destructor
|
||||
virtual ~CiffHeader();
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Read the Crw image from a data buffer, starting with the Ciff
|
||||
header.
|
||||
|
||||
@param pData Pointer to the data buffer.
|
||||
@param size Number of bytes in the data buffer.
|
||||
|
||||
@throw Error If the image cannot be parsed.
|
||||
*/
|
||||
void read(const byte* pData, uint32_t size);
|
||||
/*!
|
||||
@brief Set the value of entry \em crwTagId in directory \em crwDir to
|
||||
\em buf. If this tag doesn't exist, it is added along with all
|
||||
directories needed.
|
||||
|
||||
@param crwTagId Tag to be added.
|
||||
@param crwDir Parent directory of the tag.
|
||||
@param buf Value to be set.
|
||||
*/
|
||||
void add(uint16_t crwTagId, uint16_t crwDir, DataBuf buf);
|
||||
/*!
|
||||
@brief Remove entry \em crwTagId in directory \em crwDir from the parse
|
||||
tree. If it's the last entry in the directory, the directory is
|
||||
removed as well, etc.
|
||||
|
||||
@param crwTagId Tag id to be removed.
|
||||
@param crwDir Parent directory of the tag.
|
||||
*/
|
||||
void remove(uint16_t crwTagId, uint16_t crwDir);
|
||||
//@}
|
||||
|
||||
//! Return a pointer to the Canon Crw signature.
|
||||
static const char* signature() { return signature_; }
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
/*!
|
||||
@brief Write the Crw image to the binary image \em blob, starting with
|
||||
the Ciff header. This method appends to the blob.
|
||||
|
||||
@param blob Binary image to add to.
|
||||
|
||||
@throw Error If the image cannot be written.
|
||||
*/
|
||||
void write(Blob& blob) const;
|
||||
/*!
|
||||
@brief Decode the Crw image and add it to \em image.
|
||||
|
||||
Walk the parse tree and convert CIFF entries to metadata
|
||||
entries which are added to \em image.
|
||||
|
||||
@param image Image to add metadata to
|
||||
*/
|
||||
void decode(Image& image) const;
|
||||
/*!
|
||||
@brief Print debug info for the Crw image 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_; }
|
||||
/*!
|
||||
@brief Finds \em crwTagId in directory \em crwDir in the parse tree,
|
||||
returning a pointer to the component or 0 if not found.
|
||||
*/
|
||||
CiffComponent* findComponent(uint16_t crwTagId, uint16_t crwDir) const;
|
||||
//@}
|
||||
|
||||
private:
|
||||
// DATA
|
||||
static const char signature_[]; //!< Canon Crw signature "HEAPCCDR"
|
||||
|
||||
CiffDirectory* pRootDir_; //!< Pointer to the root directory
|
||||
ByteOrder byteOrder_; //!< Applicable byte order
|
||||
uint32_t offset_; //!< Offset to the start of the root dir
|
||||
byte* pPadding_; //!< Pointer to the (unknown) remainder
|
||||
uint32_t padded_; //!< Number of padding-bytes
|
||||
|
||||
}; // class CiffHeader
|
||||
|
||||
//! Structure for the CIFF directory hierarchy
|
||||
struct CrwSubDir {
|
||||
uint16_t crwDir_; //!< Directory tag
|
||||
uint16_t parent_; //!< Parent directory tag
|
||||
}; // struct CrwSubDir
|
||||
|
||||
/*!
|
||||
@brief Structure for a mapping table for conversion of CIFF entries to
|
||||
image metadata and vice versa.
|
||||
*/
|
||||
struct CrwMapping {
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default constructor
|
||||
CrwMapping(
|
||||
uint16_t crwTagId,
|
||||
uint16_t crwDir,
|
||||
uint32_t size,
|
||||
uint16_t tag,
|
||||
IfdId ifdId,
|
||||
CrwDecodeFct toExif,
|
||||
CrwEncodeFct fromExif)
|
||||
: crwTagId_ (crwTagId),
|
||||
crwDir_ (crwDir),
|
||||
size_ (size),
|
||||
tag_ (tag),
|
||||
ifdId_ (ifdId),
|
||||
toExif_ (toExif),
|
||||
fromExif_ (fromExif)
|
||||
{}
|
||||
//@}
|
||||
|
||||
// DATA
|
||||
uint16_t crwTagId_; //!< Crw tag id
|
||||
uint16_t crwDir_; //!< Crw directory tag
|
||||
uint32_t size_; //!< Data size (overwrites the size from the entry)
|
||||
uint16_t tag_; //!< Exif tag to map to
|
||||
IfdId ifdId_; //!< Exif Ifd id to map to
|
||||
CrwDecodeFct toExif_; //!< Conversion function
|
||||
CrwEncodeFct fromExif_; //!< Reverse conversion function
|
||||
|
||||
}; // struct CrwMapping
|
||||
|
||||
/*!
|
||||
@brief Static class providing mapping functionality from Crw entries
|
||||
to image metadata and vice versa
|
||||
*/
|
||||
class CrwMap {
|
||||
//! @name Not implemented
|
||||
//@{
|
||||
//! Default constructor
|
||||
CrwMap();
|
||||
//@}
|
||||
|
||||
public:
|
||||
/*!
|
||||
@brief Decode image metadata from a Crw entry convert and add it
|
||||
to the image metadata. This function converts only one Crw
|
||||
component.
|
||||
|
||||
@param ciffComponent Source CIFF entry
|
||||
@param image Destination image for the metadata
|
||||
@param byteOrder Byte order in which the data of the entry
|
||||
is encoded
|
||||
*/
|
||||
static void decode(const CiffComponent& ciffComponent,
|
||||
Image& image,
|
||||
ByteOrder byteOrder);
|
||||
/*!
|
||||
@brief Encode image metadata from \em image into the Crw parse tree.
|
||||
This function converts all Exif metadata that %Exiv2 can
|
||||
convert to Crw format, in a loop through the entries of the
|
||||
mapping table.
|
||||
|
||||
@param pHead Destination parse tree.
|
||||
@param image Source image containing the metadata.
|
||||
*/
|
||||
static void encode(CiffHeader* pHead, const Image& image);
|
||||
|
||||
/*!
|
||||
@brief Load the stack: loop through the Crw subdirs hierarchy and push
|
||||
all directories on the path from \em crwDir to root onto the
|
||||
stack \em crwDirs. Requires the subdirs array to be arranged in
|
||||
bottom-up order to be able to finish in only one pass.
|
||||
*/
|
||||
static void loadStack(CrwDirs& crwDirs, uint16_t crwDir);
|
||||
|
||||
private:
|
||||
//! Return conversion information for one \em crwDir and \em crwTagId
|
||||
static const CrwMapping* crwMapping(uint16_t crwDir, uint16_t crwTagId);
|
||||
|
||||
/*!
|
||||
@brief Standard decode function to convert Crw entries to
|
||||
Exif metadata.
|
||||
|
||||
Uses the mapping defined in the conversion structure \em pCrwMapping
|
||||
to convert the data. If the \em size field in the conversion structure
|
||||
is not 0, then it is used instead of the \em size provided by the
|
||||
entry itself.
|
||||
*/
|
||||
static void decodeBasic(const CiffComponent& ciffComponent,
|
||||
const CrwMapping* pCrwMapping,
|
||||
Image& image,
|
||||
ByteOrder byteOrder);
|
||||
|
||||
//! Decode the user comment
|
||||
static void decode0x0805(const CiffComponent& ciffComponent,
|
||||
const CrwMapping* pCrwMapping,
|
||||
Image& image,
|
||||
ByteOrder byteOrder);
|
||||
|
||||
//! Decode camera Make and Model information
|
||||
static void decode0x080a(const CiffComponent& ciffComponent,
|
||||
const CrwMapping* pCrwMapping,
|
||||
Image& image,
|
||||
ByteOrder byteOrder);
|
||||
|
||||
//! Decode Canon Camera Settings 1, 2 and Custom Function arrays
|
||||
static void decodeArray(const CiffComponent& ciffComponent,
|
||||
const CrwMapping* pCrwMapping,
|
||||
Image& image,
|
||||
ByteOrder byteOrder);
|
||||
|
||||
//! Decode the date when the picture was taken
|
||||
static void decode0x180e(const CiffComponent& ciffComponent,
|
||||
const CrwMapping* pCrwMapping,
|
||||
Image& image,
|
||||
ByteOrder byteOrder);
|
||||
|
||||
//! Decode image width and height
|
||||
static void decode0x1810(const CiffComponent& ciffComponent,
|
||||
const CrwMapping* pCrwMapping,
|
||||
Image& image,
|
||||
ByteOrder byteOrder);
|
||||
|
||||
//! Decode the thumbnail image
|
||||
static void decode0x2008(const CiffComponent& ciffComponent,
|
||||
const CrwMapping* pCrwMapping,
|
||||
Image& image,
|
||||
ByteOrder byteOrder);
|
||||
|
||||
/*!
|
||||
@brief Standard encode function to convert Exif metadata to Crw
|
||||
entries.
|
||||
|
||||
This is the basic encode function taking one Exif key and converting
|
||||
it to one Ciff entry. Both are available in the \em pCrwMapping passed
|
||||
in.
|
||||
|
||||
@param image Image with the metadata to encode
|
||||
@param pCrwMapping Pointer to an entry into the \em crwMapping_ table
|
||||
with information on the source and target metadata entries.
|
||||
@param pHead Pointer to the head of the CIFF parse tree into which
|
||||
the metadata from \em image is encoded.
|
||||
*/
|
||||
static void encodeBasic(const Image& image,
|
||||
const CrwMapping* pCrwMapping,
|
||||
CiffHeader* pHead);
|
||||
|
||||
//! Encode the user comment
|
||||
static void encode0x0805(const Image& image,
|
||||
const CrwMapping* pCrwMapping,
|
||||
CiffHeader* pHead);
|
||||
|
||||
//! Encode camera Make and Model information
|
||||
static void encode0x080a(const Image& image,
|
||||
const CrwMapping* pCrwMapping,
|
||||
CiffHeader* pHead);
|
||||
|
||||
//! Encode Canon Camera Settings 1, 2 and Custom Function arrays
|
||||
static void encodeArray(const Image& image,
|
||||
const CrwMapping* pCrwMapping,
|
||||
CiffHeader* pHead);
|
||||
|
||||
//! Encode the date when the picture was taken
|
||||
static void encode0x180e(const Image& image,
|
||||
const CrwMapping* pCrwMapping,
|
||||
CiffHeader* pHead);
|
||||
|
||||
//! Encode image width and height
|
||||
static void encode0x1810(const Image& image,
|
||||
const CrwMapping* pCrwMapping,
|
||||
CiffHeader* pHead);
|
||||
|
||||
//! Encode the thumbnail image
|
||||
static void encode0x2008(const Image& image,
|
||||
const CrwMapping* pCrwMapping,
|
||||
CiffHeader* pHead);
|
||||
private:
|
||||
// DATA
|
||||
static const CrwMapping crwMapping_[]; //!< Metadata conversion table
|
||||
static const CrwSubDir crwSubDir_[]; //!< Ciff directory hierarchy
|
||||
|
||||
}; // class CrwMap
|
||||
|
||||
// *****************************************************************************
|
||||
// template, inline and free functions
|
||||
|
||||
@ -830,18 +169,9 @@ namespace Exiv2 {
|
||||
*/
|
||||
Image::AutoPtr newCrwInstance(BasicIo::AutoPtr io, bool create);
|
||||
|
||||
//! Check if the file iIo is a Crw image.
|
||||
//! Check if the file iIo is a CRW image.
|
||||
bool isCrwType(BasicIo& iIo, bool advance);
|
||||
|
||||
/*!
|
||||
@brief Pack the tag values of all \em ifdId tags in \em exifData into a
|
||||
data buffer. This function is used to pack Canon Camera Settings1,2
|
||||
and Custom Function tags.
|
||||
*/
|
||||
DataBuf packIfdId(const ExifData& exifData,
|
||||
IfdId ifdId,
|
||||
ByteOrder byteOrder);
|
||||
|
||||
} // namespace Exiv2
|
||||
|
||||
#endif // #ifndef CRWIMAGE_HPP_
|
||||
|
||||
749
src/crwimage_int.hpp
Normal file
749
src/crwimage_int.hpp
Normal file
@ -0,0 +1,749 @@
|
||||
// ***************************************************************** -*- C++ -*-
|
||||
/*
|
||||
* Copyright (C) 2004-2008 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 crwimage_int.hpp
|
||||
@brief Internal classes to support CRW/CIFF format.
|
||||
@version $Rev$
|
||||
@author Andreas Huggel (ahu)
|
||||
<a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a>
|
||||
@date 28-Aug-05, ahu: created
|
||||
*/
|
||||
#ifndef CRWIMAGE_INT_HPP_
|
||||
#define CRWIMAGE_INT_HPP_
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "types.hpp"
|
||||
#include "image.hpp"
|
||||
#include "basicio.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
// *****************************************************************************
|
||||
// class declarations
|
||||
class ExifData;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
// *****************************************************************************
|
||||
// class declarations
|
||||
class CiffHeader;
|
||||
class CiffComponent;
|
||||
struct CrwMapping;
|
||||
struct CrwSubDir;
|
||||
|
||||
// *****************************************************************************
|
||||
// type definitions
|
||||
|
||||
//! Function pointer for functions to decode Exif tags from a CRW entry
|
||||
typedef void (*CrwDecodeFct)(const CiffComponent&,
|
||||
const CrwMapping*,
|
||||
Image&,
|
||||
ByteOrder);
|
||||
|
||||
//! Function pointer for functions to encode CRW entries from Exif tags
|
||||
typedef void (*CrwEncodeFct)(const Image&,
|
||||
const CrwMapping*,
|
||||
CiffHeader*);
|
||||
|
||||
//! Stack to hold a path of CRW directories
|
||||
typedef std::stack<CrwSubDir> CrwDirs;
|
||||
|
||||
//! Type to identify where the data is stored in a directory
|
||||
enum DataLocId {
|
||||
invalidDataLocId,
|
||||
valueData,
|
||||
directoryData,
|
||||
lastDataLocId
|
||||
};
|
||||
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
/*!
|
||||
@brief Interface class for components of the CIFF directory hierarchy of a
|
||||
CRW (Canon Raw data) image. Both CIFF directories as well as
|
||||
entries implement this interface. This class is implemented as NVI
|
||||
(non-virtual interface).
|
||||
*/
|
||||
class CiffComponent {
|
||||
public:
|
||||
//! CiffComponent auto_ptr type
|
||||
typedef std::auto_ptr<CiffComponent> AutoPtr;
|
||||
//! Container type to hold all metadata
|
||||
typedef std::vector<CiffComponent*> Components;
|
||||
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default constructor
|
||||
CiffComponent()
|
||||
: dir_(0), tag_(0), size_(0), offset_(0), pData_(0),
|
||||
isAllocated_(false) {}
|
||||
//! Constructor taking a tag and directory
|
||||
CiffComponent(uint16_t tag, uint16_t dir)
|
||||
: dir_(dir), tag_(tag), size_(0), offset_(0), pData_(0),
|
||||
isAllocated_(false) {}
|
||||
//! Virtual destructor.
|
||||
virtual ~CiffComponent();
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
// Default assignment operator is fine
|
||||
|
||||
//! Add a component to the composition
|
||||
void add(AutoPtr component);
|
||||
/*!
|
||||
@brief Add \em crwTagId to the parse tree, if it doesn't exist
|
||||
yet. \em crwDirs contains the path of subdirectories, starting
|
||||
with the root directory, leading to \em crwTagId. Directories
|
||||
that don't exist yet are added along the way. Returns a pointer
|
||||
to the newly added component.
|
||||
|
||||
@param crwDirs Subdirectory path from root to the subdirectory
|
||||
containing the tag to be added.
|
||||
@param crwTagId Tag to be added.
|
||||
|
||||
@return A pointer to the newly added component.
|
||||
*/
|
||||
CiffComponent* add(CrwDirs& crwDirs, uint16_t crwTagId);
|
||||
/*!
|
||||
@brief Remove \em crwTagId from the parse tree, if it exists yet. \em
|
||||
crwDirs contains the path of subdirectories, starting with the
|
||||
root directory, leading to \em crwTagId.
|
||||
|
||||
@param crwDirs Subdirectory path from root to the subdirectory
|
||||
containing the tag to be removed.
|
||||
@param crwTagId Tag to be removed.
|
||||
*/
|
||||
void remove(CrwDirs& crwDirs, uint16_t crwTagId);
|
||||
/*!
|
||||
@brief Read a component from a data buffer
|
||||
|
||||
@param pData Pointer to the data buffer.
|
||||
@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);
|
||||
/*!
|
||||
@brief Write the metadata from the raw metadata component to the
|
||||
binary image \em blob. This method may append to the blob.
|
||||
|
||||
@param blob Binary image to add metadata to
|
||||
@param byteOrder Byte order
|
||||
@param offset Current offset
|
||||
|
||||
@return New offset
|
||||
*/
|
||||
uint32_t write(Blob& blob, ByteOrder byteOrder, uint32_t offset);
|
||||
/*!
|
||||
@brief Writes the entry's value if size is larger than eight bytes. If
|
||||
needed, the value is padded with one 0 byte to make the number
|
||||
of bytes written to the blob even. The offset of the component
|
||||
is set to the offset passed in.
|
||||
@param blob The binary image to write to.
|
||||
@param offset Offset from the start of the directory for this entry.
|
||||
|
||||
@return New offset.
|
||||
*/
|
||||
uint32_t writeValueData(Blob& blob, uint32_t offset);
|
||||
//! Set the directory tag for this component.
|
||||
void setDir(uint16_t dir) { dir_ = dir; }
|
||||
//! Set the data value of the entry.
|
||||
void setValue(DataBuf buf);
|
||||
//@}
|
||||
|
||||
//! Return the type id for a tag
|
||||
static TypeId typeId(uint16_t tag);
|
||||
//! Return the data location id for a tag
|
||||
static DataLocId dataLocation(uint16_t tag);
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
/*!
|
||||
@brief Decode metadata from the component and add it to
|
||||
\em image.
|
||||
|
||||
@param image Image to add 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;
|
||||
/*!
|
||||
@brief Write a directory entry for the component to the \em blob.
|
||||
If the size of the data is not larger than 8 bytes, the
|
||||
data is written to the directory entry.
|
||||
*/
|
||||
void writeDirEntry(Blob& blob, ByteOrder byteOrder) const;
|
||||
//! Return the tag of the directory containing this component
|
||||
uint16_t dir() const { return dir_; }
|
||||
|
||||
//! Return the tag of this component
|
||||
uint16_t tag() const { return tag_; }
|
||||
|
||||
//! Return true if the component is empty, else false
|
||||
bool empty() const;
|
||||
|
||||
/*!
|
||||
@brief Return the data size of this component
|
||||
|
||||
@note If the data is contained in the directory entry itself,
|
||||
this method returns 8, which is the maximum number
|
||||
of data bytes this component can have. The actual size,
|
||||
i.e., used data bytes, may be less than 8.
|
||||
*/
|
||||
uint32_t size() const { return size_; }
|
||||
|
||||
//! Return the offset to the data from the start of the directory
|
||||
uint32_t offset() const { return offset_; }
|
||||
|
||||
//! Return a pointer to the data area of this component
|
||||
const byte* pData() const { return pData_; }
|
||||
|
||||
//! Return the tag id of this component
|
||||
uint16_t tagId() const { return tag_ & 0x3fff; }
|
||||
|
||||
//! Return the type id of thi component
|
||||
TypeId typeId() const { return typeId(tag_); }
|
||||
|
||||
//! Return the data location for this component
|
||||
DataLocId dataLocation() const { return dataLocation(tag_); }
|
||||
|
||||
/*!
|
||||
@brief Finds \em crwTagId in directory \em crwDir, returning a pointer to
|
||||
the component or 0 if not found.
|
||||
*/
|
||||
CiffComponent* findComponent(uint16_t crwTagId, uint16_t crwDir) const;
|
||||
//@}
|
||||
|
||||
protected:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
//! Implements add()
|
||||
virtual void doAdd(AutoPtr component) =0;
|
||||
//! Implements add(). The default implementation does nothing.
|
||||
virtual CiffComponent* doAdd(CrwDirs& crwDirs, uint16_t crwTagId);
|
||||
//! Implements remove(). The default implementation does nothing.
|
||||
virtual void doRemove(CrwDirs& crwDirs, uint16_t crwTagId);
|
||||
//! Implements read(). The default implementation reads a directory entry.
|
||||
virtual void doRead(const byte* pData,
|
||||
uint32_t size,
|
||||
uint32_t start,
|
||||
ByteOrder byteOrder);
|
||||
//! Implements write()
|
||||
virtual uint32_t doWrite(Blob& blob,
|
||||
ByteOrder byteOrder,
|
||||
uint32_t offset) =0;
|
||||
//! Set the size of the data area.
|
||||
void setSize(uint32_t size) { size_ = size; }
|
||||
//! Set the offset for this component.
|
||||
void setOffset(uint32_t offset) { offset_ = offset; }
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
//! Implements decode()
|
||||
virtual void doDecode(Image& image,
|
||||
ByteOrder byteOrder) const =0;
|
||||
//! Implements print(). The default implementation prints the entry.
|
||||
virtual void doPrint(std::ostream& os,
|
||||
ByteOrder byteOrder,
|
||||
const std::string& prefix) const;
|
||||
//! Implements empty(). Default implementation returns true if size is 0.
|
||||
virtual bool doEmpty() const;
|
||||
//! Implements findComponent(). The default implementation checks the entry.
|
||||
virtual CiffComponent* doFindComponent(uint16_t crwTagId,
|
||||
uint16_t crwDir) const;
|
||||
//@}
|
||||
|
||||
private:
|
||||
// DATA
|
||||
uint16_t dir_; //!< Tag of the directory containing this component
|
||||
uint16_t tag_; //!< Tag of the entry
|
||||
uint32_t size_; //!< Size of the data area
|
||||
uint32_t offset_; //!< Offset to the data area from start of dir
|
||||
const byte* pData_; //!< Pointer to the data area
|
||||
bool isAllocated_; //!< True if this entry owns the value data
|
||||
|
||||
}; // class CiffComponent
|
||||
|
||||
/*!
|
||||
@brief This class models one directory entry of a CIFF directory of
|
||||
a CRW (Canon Raw data) image.
|
||||
*/
|
||||
class CiffEntry : public CiffComponent {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default constructor
|
||||
CiffEntry() {}
|
||||
//! Constructor taking a tag and directory
|
||||
CiffEntry(uint16_t tag, uint16_t dir) : CiffComponent(tag, dir) {}
|
||||
|
||||
//! Virtual destructor.
|
||||
virtual ~CiffEntry() {}
|
||||
//@}
|
||||
|
||||
// Default assignment operator is fine
|
||||
|
||||
private:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
using CiffComponent::doAdd;
|
||||
// See base class comment
|
||||
virtual void doAdd(AutoPtr component);
|
||||
/*!
|
||||
@brief Implements write(). Writes only the value data of the entry,
|
||||
using writeValueData().
|
||||
*/
|
||||
virtual uint32_t doWrite(Blob& blob,
|
||||
ByteOrder byteOrder,
|
||||
uint32_t offset);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
// See base class comment
|
||||
virtual void doDecode(Image& image, ByteOrder byteOrder) const;
|
||||
//@}
|
||||
|
||||
}; // class CiffEntry
|
||||
|
||||
//! This class models a CIFF directory of a CRW (Canon Raw data) image.
|
||||
class CiffDirectory : public CiffComponent {
|
||||
public:
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default constructor
|
||||
CiffDirectory() {}
|
||||
//! Constructor taking a tag and directory
|
||||
CiffDirectory(uint16_t tag, uint16_t dir) : CiffComponent(tag, dir) {}
|
||||
|
||||
//! Virtual destructor
|
||||
virtual ~CiffDirectory();
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
// Default assignment operator is fine
|
||||
|
||||
/*!
|
||||
@brief Parse a CIFF directory from a memory buffer
|
||||
|
||||
@param pData Pointer to the memory buffer containing the directory
|
||||
@param size Size of the memory buffer
|
||||
@param byteOrder Applicable byte order (little or big endian)
|
||||
*/
|
||||
void readDirectory(const byte* pData,
|
||||
uint32_t size,
|
||||
ByteOrder byteOrder);
|
||||
//@}
|
||||
|
||||
private:
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
// See base class comment
|
||||
virtual void doAdd(AutoPtr component);
|
||||
// See base class comment
|
||||
virtual CiffComponent* doAdd(CrwDirs& crwDirs, uint16_t crwTagId);
|
||||
// See base class comment
|
||||
virtual void doRemove(CrwDirs& crwDirs, uint16_t crwTagId);
|
||||
/*!
|
||||
@brief Implements write(). Writes the complete Ciff directory to
|
||||
the blob.
|
||||
*/
|
||||
virtual uint32_t doWrite(Blob& blob,
|
||||
ByteOrder byteOrder,
|
||||
uint32_t offset);
|
||||
// See base class comment
|
||||
virtual void doRead(const byte* pData,
|
||||
uint32_t size,
|
||||
uint32_t start,
|
||||
ByteOrder byteOrder);
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
// See base class comment
|
||||
virtual void doDecode(Image& image,
|
||||
ByteOrder byteOrder) const;
|
||||
|
||||
// See base class comment
|
||||
virtual void doPrint(std::ostream& os,
|
||||
ByteOrder byteOrder,
|
||||
const std::string& prefix) const;
|
||||
|
||||
//! See base class comment. A directory is empty if it has no components.
|
||||
virtual bool doEmpty() const;
|
||||
|
||||
// See base class comment
|
||||
virtual CiffComponent* doFindComponent(uint16_t crwTagId,
|
||||
uint16_t crwDir) const;
|
||||
//@}
|
||||
|
||||
private:
|
||||
// DATA
|
||||
Components components_; //!< List of components in this dir
|
||||
|
||||
}; // class CiffDirectory
|
||||
|
||||
/*!
|
||||
@brief This class models the header of a CRW (Canon Raw data) image. It
|
||||
is the head of a CIFF parse tree, consisting of CiffDirectory and
|
||||
CiffEntry objects. Most of its methods will walk the parse tree to
|
||||
perform the requested action.
|
||||
*/
|
||||
class CiffHeader {
|
||||
public:
|
||||
//! CiffHeader auto_ptr type
|
||||
typedef std::auto_ptr<CiffHeader> AutoPtr;
|
||||
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default constructor
|
||||
CiffHeader()
|
||||
: pRootDir_ (0),
|
||||
byteOrder_ (littleEndian),
|
||||
offset_ (0x0000001a),
|
||||
pPadding_ (0),
|
||||
padded_ (0)
|
||||
{}
|
||||
//! Virtual destructor
|
||||
virtual ~CiffHeader();
|
||||
//@}
|
||||
|
||||
//! @name Manipulators
|
||||
//@{
|
||||
/*!
|
||||
@brief Read the CRW image from a data buffer, starting with the Ciff
|
||||
header.
|
||||
|
||||
@param pData Pointer to the data buffer.
|
||||
@param size Number of bytes in the data buffer.
|
||||
|
||||
@throw Error If the image cannot be parsed.
|
||||
*/
|
||||
void read(const byte* pData, uint32_t size);
|
||||
/*!
|
||||
@brief Set the value of entry \em crwTagId in directory \em crwDir to
|
||||
\em buf. If this tag doesn't exist, it is added along with all
|
||||
directories needed.
|
||||
|
||||
@param crwTagId Tag to be added.
|
||||
@param crwDir Parent directory of the tag.
|
||||
@param buf Value to be set.
|
||||
*/
|
||||
void add(uint16_t crwTagId, uint16_t crwDir, DataBuf buf);
|
||||
/*!
|
||||
@brief Remove entry \em crwTagId in directory \em crwDir from the parse
|
||||
tree. If it's the last entry in the directory, the directory is
|
||||
removed as well, etc.
|
||||
|
||||
@param crwTagId Tag id to be removed.
|
||||
@param crwDir Parent directory of the tag.
|
||||
*/
|
||||
void remove(uint16_t crwTagId, uint16_t crwDir);
|
||||
//@}
|
||||
|
||||
//! Return a pointer to the Canon CRW signature.
|
||||
static const char* signature() { return signature_; }
|
||||
|
||||
//! @name Accessors
|
||||
//@{
|
||||
/*!
|
||||
@brief Write the CRW image to the binary image \em blob, starting with
|
||||
the Ciff header. This method appends to the blob.
|
||||
|
||||
@param blob Binary image to add to.
|
||||
|
||||
@throw Error If the image cannot be written.
|
||||
*/
|
||||
void write(Blob& blob) const;
|
||||
/*!
|
||||
@brief Decode the CRW image and add it to \em image.
|
||||
|
||||
Walk the parse tree and convert CIFF entries to metadata
|
||||
entries which are added to \em image.
|
||||
|
||||
@param image Image to add metadata to
|
||||
*/
|
||||
void decode(Image& image) const;
|
||||
/*!
|
||||
@brief Print debug info for the CRW image 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_; }
|
||||
/*!
|
||||
@brief Finds \em crwTagId in directory \em crwDir in the parse tree,
|
||||
returning a pointer to the component or 0 if not found.
|
||||
*/
|
||||
CiffComponent* findComponent(uint16_t crwTagId, uint16_t crwDir) const;
|
||||
//@}
|
||||
|
||||
private:
|
||||
// DATA
|
||||
static const char signature_[]; //!< Canon CRW signature "HEAPCCDR"
|
||||
|
||||
CiffDirectory* pRootDir_; //!< Pointer to the root directory
|
||||
ByteOrder byteOrder_; //!< Applicable byte order
|
||||
uint32_t offset_; //!< Offset to the start of the root dir
|
||||
byte* pPadding_; //!< Pointer to the (unknown) remainder
|
||||
uint32_t padded_; //!< Number of padding-bytes
|
||||
|
||||
}; // class CiffHeader
|
||||
|
||||
//! Structure for the CIFF directory hierarchy
|
||||
struct CrwSubDir {
|
||||
uint16_t crwDir_; //!< Directory tag
|
||||
uint16_t parent_; //!< Parent directory tag
|
||||
}; // struct CrwSubDir
|
||||
|
||||
/*!
|
||||
@brief Structure for a mapping table for conversion of CIFF entries to
|
||||
image metadata and vice versa.
|
||||
*/
|
||||
struct CrwMapping {
|
||||
//! @name Creators
|
||||
//@{
|
||||
//! Default constructor
|
||||
CrwMapping(
|
||||
uint16_t crwTagId,
|
||||
uint16_t crwDir,
|
||||
uint32_t size,
|
||||
uint16_t tag,
|
||||
IfdId ifdId,
|
||||
CrwDecodeFct toExif,
|
||||
CrwEncodeFct fromExif)
|
||||
: crwTagId_ (crwTagId),
|
||||
crwDir_ (crwDir),
|
||||
size_ (size),
|
||||
tag_ (tag),
|
||||
ifdId_ (ifdId),
|
||||
toExif_ (toExif),
|
||||
fromExif_ (fromExif)
|
||||
{}
|
||||
//@}
|
||||
|
||||
// DATA
|
||||
uint16_t crwTagId_; //!< CRW tag id
|
||||
uint16_t crwDir_; //!< CRW directory tag
|
||||
uint32_t size_; //!< Data size (overwrites the size from the entry)
|
||||
uint16_t tag_; //!< Exif tag to map to
|
||||
IfdId ifdId_; //!< Exif Ifd id to map to
|
||||
CrwDecodeFct toExif_; //!< Conversion function
|
||||
CrwEncodeFct fromExif_; //!< Reverse conversion function
|
||||
|
||||
}; // struct CrwMapping
|
||||
|
||||
/*!
|
||||
@brief Static class providing mapping functionality from CRW entries
|
||||
to image metadata and vice versa
|
||||
*/
|
||||
class CrwMap {
|
||||
//! @name Not implemented
|
||||
//@{
|
||||
//! Default constructor
|
||||
CrwMap();
|
||||
//@}
|
||||
|
||||
public:
|
||||
/*!
|
||||
@brief Decode image metadata from a CRW entry, convert and add it
|
||||
to the image metadata. This function converts only one CRW
|
||||
component.
|
||||
|
||||
@param ciffComponent Source CIFF entry
|
||||
@param image Destination image for the metadata
|
||||
@param byteOrder Byte order in which the data of the entry
|
||||
is encoded
|
||||
*/
|
||||
static void decode(const CiffComponent& ciffComponent,
|
||||
Image& image,
|
||||
ByteOrder byteOrder);
|
||||
/*!
|
||||
@brief Encode image metadata from \em image into the CRW parse tree.
|
||||
This function converts all Exif metadata that %Exiv2 can
|
||||
convert to CRW format, in a loop through the entries of the
|
||||
mapping table.
|
||||
|
||||
@param pHead Destination parse tree.
|
||||
@param image Source image containing the metadata.
|
||||
*/
|
||||
static void encode(CiffHeader* pHead, const Image& image);
|
||||
|
||||
/*!
|
||||
@brief Load the stack: loop through the CRW subdirs hierarchy and push
|
||||
all directories on the path from \em crwDir to root onto the
|
||||
stack \em crwDirs. Requires the subdirs array to be arranged in
|
||||
bottom-up order to be able to finish in only one pass.
|
||||
*/
|
||||
static void loadStack(CrwDirs& crwDirs, uint16_t crwDir);
|
||||
|
||||
private:
|
||||
//! Return conversion information for one \em crwDir and \em crwTagId
|
||||
static const CrwMapping* crwMapping(uint16_t crwDir, uint16_t crwTagId);
|
||||
|
||||
/*!
|
||||
@brief Standard decode function to convert CRW entries to
|
||||
Exif metadata.
|
||||
|
||||
Uses the mapping defined in the conversion structure \em pCrwMapping
|
||||
to convert the data. If the \em size field in the conversion structure
|
||||
is not 0, then it is used instead of the \em size provided by the
|
||||
entry itself.
|
||||
*/
|
||||
static void decodeBasic(const CiffComponent& ciffComponent,
|
||||
const CrwMapping* pCrwMapping,
|
||||
Image& image,
|
||||
ByteOrder byteOrder);
|
||||
|
||||
//! Decode the user comment
|
||||
static void decode0x0805(const CiffComponent& ciffComponent,
|
||||
const CrwMapping* pCrwMapping,
|
||||
Image& image,
|
||||
ByteOrder byteOrder);
|
||||
|
||||
//! Decode camera Make and Model information
|
||||
static void decode0x080a(const CiffComponent& ciffComponent,
|
||||
const CrwMapping* pCrwMapping,
|
||||
Image& image,
|
||||
ByteOrder byteOrder);
|
||||
|
||||
//! Decode Canon Camera Settings 1, 2 and Custom Function arrays
|
||||
static void decodeArray(const CiffComponent& ciffComponent,
|
||||
const CrwMapping* pCrwMapping,
|
||||
Image& image,
|
||||
ByteOrder byteOrder);
|
||||
|
||||
//! Decode the date when the picture was taken
|
||||
static void decode0x180e(const CiffComponent& ciffComponent,
|
||||
const CrwMapping* pCrwMapping,
|
||||
Image& image,
|
||||
ByteOrder byteOrder);
|
||||
|
||||
//! Decode image width and height
|
||||
static void decode0x1810(const CiffComponent& ciffComponent,
|
||||
const CrwMapping* pCrwMapping,
|
||||
Image& image,
|
||||
ByteOrder byteOrder);
|
||||
|
||||
//! Decode the thumbnail image
|
||||
static void decode0x2008(const CiffComponent& ciffComponent,
|
||||
const CrwMapping* pCrwMapping,
|
||||
Image& image,
|
||||
ByteOrder byteOrder);
|
||||
|
||||
/*!
|
||||
@brief Standard encode function to convert Exif metadata to Crw
|
||||
entries.
|
||||
|
||||
This is the basic encode function taking one Exif key and converting
|
||||
it to one Ciff entry. Both are available in the \em pCrwMapping passed
|
||||
in.
|
||||
|
||||
@param image Image with the metadata to encode
|
||||
@param pCrwMapping Pointer to an entry into the \em crwMapping_ table
|
||||
with information on the source and target metadata entries.
|
||||
@param pHead Pointer to the head of the CIFF parse tree into which
|
||||
the metadata from \em image is encoded.
|
||||
*/
|
||||
static void encodeBasic(const Image& image,
|
||||
const CrwMapping* pCrwMapping,
|
||||
CiffHeader* pHead);
|
||||
|
||||
//! Encode the user comment
|
||||
static void encode0x0805(const Image& image,
|
||||
const CrwMapping* pCrwMapping,
|
||||
CiffHeader* pHead);
|
||||
|
||||
//! Encode camera Make and Model information
|
||||
static void encode0x080a(const Image& image,
|
||||
const CrwMapping* pCrwMapping,
|
||||
CiffHeader* pHead);
|
||||
|
||||
//! Encode Canon Camera Settings 1, 2 and Custom Function arrays
|
||||
static void encodeArray(const Image& image,
|
||||
const CrwMapping* pCrwMapping,
|
||||
CiffHeader* pHead);
|
||||
|
||||
//! Encode the date when the picture was taken
|
||||
static void encode0x180e(const Image& image,
|
||||
const CrwMapping* pCrwMapping,
|
||||
CiffHeader* pHead);
|
||||
|
||||
//! Encode image width and height
|
||||
static void encode0x1810(const Image& image,
|
||||
const CrwMapping* pCrwMapping,
|
||||
CiffHeader* pHead);
|
||||
|
||||
//! Encode the thumbnail image
|
||||
static void encode0x2008(const Image& image,
|
||||
const CrwMapping* pCrwMapping,
|
||||
CiffHeader* pHead);
|
||||
private:
|
||||
// DATA
|
||||
static const CrwMapping crwMapping_[]; //!< Metadata conversion table
|
||||
static const CrwSubDir crwSubDir_[]; //!< Ciff directory hierarchy
|
||||
|
||||
}; // class CrwMap
|
||||
|
||||
// *****************************************************************************
|
||||
// template, inline and free functions
|
||||
|
||||
/*!
|
||||
@brief Pack the tag values of all \em ifdId tags in \em exifData into a
|
||||
data buffer. This function is used to pack Canon Camera Settings1,2
|
||||
and Custom Function tags.
|
||||
*/
|
||||
DataBuf packIfdId(const ExifData& exifData,
|
||||
IfdId ifdId,
|
||||
ByteOrder byteOrder);
|
||||
|
||||
}} // namespace Internal, Exiv2
|
||||
|
||||
#endif // #ifndef CRWIMAGE_INT_HPP_
|
||||
@ -2,8 +2,9 @@
|
||||
// crwparse.cpp, $Rev$
|
||||
// Print the CIFF structure of a CRW file
|
||||
|
||||
#include <exiv2/crwimage.hpp>
|
||||
#include <exiv2/futils.hpp>
|
||||
#include "crwimage.hpp"
|
||||
#include "crwimage_int.hpp"
|
||||
#include "futils.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@ -34,7 +35,7 @@ try {
|
||||
if (io.error() || io.eof()) throw Exiv2::Error(14);
|
||||
|
||||
// Parse the image, starting with a CIFF header component
|
||||
Exiv2::CiffHeader::AutoPtr parseTree(new Exiv2::CiffHeader);
|
||||
Exiv2::Internal::CiffHeader::AutoPtr parseTree(new Exiv2::Internal::CiffHeader);
|
||||
parseTree->read(buf.pData_, buf.size_);
|
||||
parseTree->print(std::cout);
|
||||
|
||||
@ -46,7 +46,7 @@ namespace Exiv2 {
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
//! Contains information about one record
|
||||
//! Details of an IPTC record.
|
||||
struct RecordInfo {
|
||||
//! Constructor
|
||||
RecordInfo(uint16_t recordId, const char* name, const char* desc);
|
||||
@ -55,7 +55,7 @@ namespace Exiv2 {
|
||||
const char* desc_; //!< Record description
|
||||
};
|
||||
|
||||
//! Dataset information
|
||||
//! Details of an IPTC dataset.
|
||||
struct DataSet {
|
||||
//! Constructor
|
||||
DataSet(
|
||||
@ -84,7 +84,7 @@ namespace Exiv2 {
|
||||
const char* photoshop_; //!< Photoshop string
|
||||
}; // struct DataSet
|
||||
|
||||
//! Container for IPTC dataset information. Implemented as a static class.
|
||||
//! IPTC dataset reference, implemented as a static class.
|
||||
class IptcDataSets {
|
||||
public:
|
||||
/*!
|
||||
|
||||
@ -46,7 +46,7 @@ namespace Exiv2 {
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
//! Helper structure defining an error message
|
||||
//! Helper structure defining an error message.
|
||||
struct ErrMsg {
|
||||
//! Constructor
|
||||
ErrMsg(int code, const char* message)
|
||||
|
||||
@ -57,8 +57,8 @@ namespace Exiv2 {
|
||||
// class definitions
|
||||
|
||||
/*!
|
||||
@brief Information related to one Exif tag. An Exif metadatum consists of
|
||||
an ExifKey and a Value and provides methods to manipulate these.
|
||||
@brief An Exif metadatum, consisting of an ExifKey and a Value and
|
||||
methods to manipulate these.
|
||||
*/
|
||||
class Exifdatum : public Metadatum {
|
||||
template<typename T> friend Exifdatum& setValue(Exifdatum&, const T&);
|
||||
|
||||
@ -49,8 +49,8 @@ namespace Exiv2 {
|
||||
// class definitions
|
||||
|
||||
/*!
|
||||
@brief Information related to one IPTC dataset. An IPTC metadatum consists
|
||||
of an IptcKey and a Value and provides methods to manipulate these.
|
||||
@brief An IPTC metadatum ("dataset"), consisting of an IptcKey and a
|
||||
Value and methods to manipulate these.
|
||||
*/
|
||||
class Iptcdatum : public Metadatum {
|
||||
public:
|
||||
|
||||
@ -46,10 +46,28 @@ EXIV2_RCSID("@(#) $Id$")
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
// *****************************************************************************
|
||||
namespace {
|
||||
|
||||
//! Struct used in the lookup table for pretty print functions
|
||||
struct XmpPrintInfo {
|
||||
//! Comparison operator for key
|
||||
bool operator==(const std::string& key) const
|
||||
{
|
||||
return std::string(key_) == key;
|
||||
}
|
||||
|
||||
const char* key_; //!< XMP key
|
||||
Exiv2::PrintFct printFct_; //!< Print function
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
//! @cond IGNORE
|
||||
extern const XmpPropertyInfo xmpDcInfo[];
|
||||
extern const XmpPropertyInfo xmpDigikamInfo[];
|
||||
extern const XmpPropertyInfo xmpXmpInfo[];
|
||||
@ -690,11 +708,6 @@ namespace Exiv2 {
|
||||
return n == name;
|
||||
}
|
||||
|
||||
bool XmpPrintInfo::operator==(const std::string& key) const
|
||||
{
|
||||
return std::string(key_) == key;
|
||||
}
|
||||
|
||||
XmpProperties::NsRegistry XmpProperties::nsRegistry_;
|
||||
|
||||
const XmpNsInfo* XmpProperties::lookupNsRegistry(const XmpNsInfo::Prefix& prefix)
|
||||
@ -985,5 +998,6 @@ namespace Exiv2 {
|
||||
<< ( property.xmpCategory_ == xmpExternal ? "External" : "Internal" ) << ",\t"
|
||||
<< property.desc_ << "\n";
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
} // namespace Exiv2
|
||||
|
||||
@ -71,15 +71,6 @@ namespace Exiv2 {
|
||||
const char* desc_; //!< Property description
|
||||
};
|
||||
|
||||
//! Struct used in the lookup table for pretty print functions
|
||||
struct XmpPrintInfo {
|
||||
//! Comparison operator for key
|
||||
bool operator==(const std::string& key) const;
|
||||
|
||||
const char* key_; //!< XMP key
|
||||
PrintFct printFct_; //!< Print function
|
||||
};
|
||||
|
||||
//! Structure mapping XMP namespaces and (preferred) prefixes.
|
||||
struct XmpNsInfo {
|
||||
//! For comparison with prefix
|
||||
@ -107,7 +98,7 @@ namespace Exiv2 {
|
||||
const char* desc_; //!< Brief description of the namespace
|
||||
};
|
||||
|
||||
//! Container for XMP property information. Implemented as a static class.
|
||||
//! XMP property reference, implemented as a static class.
|
||||
class XmpProperties {
|
||||
//! Prevent construction: not implemented.
|
||||
XmpProperties();
|
||||
|
||||
@ -72,7 +72,7 @@ namespace Exiv2 {
|
||||
// *****************************************************************************
|
||||
// class definitions
|
||||
|
||||
//! Contains information pertaining to one IFD
|
||||
//! The details of an IFD.
|
||||
struct IfdInfo {
|
||||
struct Item;
|
||||
bool operator==(IfdId ifdId) const; //!< Comparison operator for IFD id
|
||||
@ -90,7 +90,7 @@ namespace Exiv2 {
|
||||
std::string i_; //!< IFD item
|
||||
};
|
||||
|
||||
//! Contains information pertaining to one section
|
||||
//! The details of a section.
|
||||
struct SectionInfo {
|
||||
SectionId sectionId_; //!< Section id
|
||||
const char* name_; //!< Section name (one word)
|
||||
@ -190,7 +190,7 @@ namespace Exiv2 {
|
||||
//! Shortcut for the printTagBitmask template which requires typing the array name only once.
|
||||
#define EXV_PRINT_TAG_BITMASK(array) printTagBitmask<EXV_COUNTOF(array), array>
|
||||
|
||||
//! Container for Exif tag information. Implemented as a static class.
|
||||
//! Exif tag reference, implemented as a static class.
|
||||
class ExifTags {
|
||||
//! Prevent construction: not implemented.
|
||||
ExifTags();
|
||||
|
||||
@ -59,7 +59,6 @@ EXIV2_RCSID("@(#) $Id$")
|
||||
|
||||
Todo:
|
||||
|
||||
+ Support all TIFF data types
|
||||
+ Review boundary checking, is it better to check the offsets?
|
||||
+ Define and implement consistent error handling for recursive hierarchy
|
||||
+ Make TiffImage a template StandardImage, which can be parametrized with
|
||||
@ -83,9 +82,6 @@ EXIV2_RCSID("@(#) $Id$")
|
||||
+ Fix CiffHeader according to TiffHeade2
|
||||
+ Combine Error(15) and Error(33), add format argument %1
|
||||
+ Search crwimage for todos, fix writeMetadata comment
|
||||
+ Add Ciff components to TIFF component hierarchy
|
||||
+ rename all Ciff stuff to Crw for easier reference - not needed when CIFF
|
||||
components are part of the TIFF hierarchy
|
||||
+ rename loadStack to getPath for consistency
|
||||
|
||||
-------------------------------------------------------------------------- */
|
||||
|
||||
@ -132,7 +132,6 @@ namespace Exiv2 {
|
||||
lastTypeId =0x1ffff //!< Last type id.
|
||||
};
|
||||
|
||||
// Todo: decentralize IfdId, so that new ids can be defined elsewhere
|
||||
//! Type to specify the IFD to which a metadata belongs
|
||||
enum IfdId { ifdIdNotSet,
|
||||
ifd0Id, exifIfdId, gpsIfdId, iopIfdId, ifd1Id,
|
||||
@ -145,11 +144,6 @@ namespace Exiv2 {
|
||||
olympusIfdId, panasonicIfdId, pentaxIfdId, sigmaIfdId, sonyIfdId,
|
||||
lastIfdId };
|
||||
|
||||
//! Type to identify where the data is stored in a directory
|
||||
enum DataLocId { invalidDataLocId,
|
||||
valueData, directoryData,
|
||||
lastDataLocId };
|
||||
|
||||
//! Container for binary data
|
||||
typedef std::vector<byte> Blob;
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ fi
|
||||
# ----------------------------------------------------------------------
|
||||
# Main routine
|
||||
(
|
||||
binpath="$VALGRIND ../../samples"
|
||||
binpath="$VALGRIND ../../src"
|
||||
exiv2="$VALGRIND exiv2"
|
||||
cmdfile=cmdfile
|
||||
crwfile=exiv2-canon-powershot-s40.crw
|
||||
|
||||
Loading…
Reference in New Issue
Block a user