Loading...
Searching...
No Matches
crwimage_int.hpp
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef EXIV2_CRWIMAGE_INT_HPP
#define EXIV2_CRWIMAGE_INT_HPP
// *****************************************************************************
// included header files
#include "image.hpp"
#include "tags_int.hpp"
// + standard includes
#include <stack>
#include <vector>
// *****************************************************************************
// namespace extensions
namespace Exiv2::Internal {
// *****************************************************************************
// class declarations
class CiffHeader;
class CiffComponent;
struct CrwMapping;
struct CrwSubDir {
uint16_t dir;
uint16_t parent;
};
// *****************************************************************************
// type definitions
using CrwDecodeFct = void (*)(const CiffComponent&, const CrwMapping*, Image&, ByteOrder);
using CrwEncodeFct = void (*)(const Image&, const CrwMapping*, CiffHeader*);
using CrwDirs = std::stack<CrwSubDir>;
enum class DataLocId { valueData, directoryData, lastDataLocId };
// *****************************************************************************
// class definitions
class CiffComponent {
public:
using UniquePtr = std::unique_ptr<CiffComponent>;
using Components = std::vector<CiffComponent*>;
CiffComponent() = default;
CiffComponent(uint16_t tag, uint16_t dir);
CiffComponent(const CiffComponent&) = delete;
CiffComponent& operator=(const CiffComponent&) = delete;
virtual ~CiffComponent() = default;
// Default assignment operator is fine
void add(UniquePtr component);
CiffComponent* add(CrwDirs& crwDirs, uint16_t crwTagId);
void remove(CrwDirs& crwDirs, uint16_t crwTagId);
void read(const byte* pData, size_t size, uint32_t start, ByteOrder byteOrder);
size_t write(Blob& blob, ByteOrder byteOrder, size_t offset);
size_t writeValueData(Blob& blob, size_t offset);
void setDir(uint16_t dir) {
dir_ = dir;
}
void setValue(DataBuf&& buf);
static TypeId typeId(uint16_t tag);
static DataLocId dataLocation(uint16_t tag);
void decode(Image& image, ByteOrder byteOrder) const;
void print(std::ostream& os, ByteOrder byteOrder, const std::string& prefix = "") const;
void writeDirEntry(Blob& blob, ByteOrder byteOrder) const;
[[nodiscard]] uint16_t dir() const {
return dir_;
}
[[nodiscard]] uint16_t tag() const {
return tag_;
}
[[nodiscard]] bool empty() const;
[[nodiscard]] size_t size() const {
return size_;
}
[[nodiscard]] size_t offset() const {
return offset_;
}
[[nodiscard]] const byte* pData() const {
return pData_;
}
[[nodiscard]] uint16_t tagId() const {
return tag_ & 0x3fff;
}
[[nodiscard]] TypeId typeId() const {
return typeId(tag_);
}
[[nodiscard]] DataLocId dataLocation() const {
return dataLocation(tag_);
}
[[nodiscard]] CiffComponent* findComponent(uint16_t crwTagId, uint16_t crwDir) const;
protected:
virtual void doAdd(UniquePtr component) = 0;
virtual CiffComponent* doAdd(CrwDirs& crwDirs, uint16_t crwTagId);
virtual void doRemove(CrwDirs& crwDirs, uint16_t crwTagId);
virtual void doRead(const byte* pData, size_t size, uint32_t start, ByteOrder byteOrder);
virtual size_t doWrite(Blob& blob, ByteOrder byteOrder, size_t offset) = 0;
void setSize(size_t size) {
size_ = size;
}
void setOffset(size_t offset) {
offset_ = offset;
}
virtual void doDecode(Image& image, ByteOrder byteOrder) const = 0;
virtual void doPrint(std::ostream& os, ByteOrder byteOrder, const std::string& prefix) const;
[[nodiscard]] virtual bool doEmpty() const;
[[nodiscard]] virtual CiffComponent* doFindComponent(uint16_t crwTagId, uint16_t crwDir) const;
private:
// DATA
uint16_t dir_ = 0;
uint16_t tag_ = 0;
size_t size_ = 0;
size_t offset_ = 0;
// Notes on the ownership model of pData_: pData_ is a always a read-only
// pointer to a buffer owned by somebody else. Usually it is a pointer
// into a copy of the image that was memory-mapped in CrwImage::readMetadata().
// However, if CiffComponent::setValue() is used, then it is a pointer into
// the storage_ DataBuf below.
const byte* pData_ = nullptr;
// This DataBuf is only used when CiffComponent::setValue is called.
// Otherwise, it remains empty.
DataBuf storage_;
}; // class CiffComponent
class CiffEntry : public CiffComponent {
using CiffComponent::CiffComponent;
using CiffComponent::doAdd;
// See base class comment
void doAdd(UniquePtr component) override;
size_t doWrite(Blob& blob, ByteOrder byteOrder, size_t offset) override;
// See base class comment
void doDecode(Image& image, ByteOrder byteOrder) const override;
}; // class CiffEntry
class CiffDirectory : public CiffComponent {
using CiffComponent::CiffComponent;
public:
~CiffDirectory() override;
CiffDirectory(const CiffDirectory&) = delete;
CiffDirectory& operator=(const CiffDirectory&) = delete;
// Default assignment operator is fine
void readDirectory(const byte* pData, size_t size, ByteOrder byteOrder);
private:
// See base class comment
void doAdd(UniquePtr component) override;
// See base class comment
CiffComponent* doAdd(CrwDirs& crwDirs, uint16_t crwTagId) override;
// See base class comment
void doRemove(CrwDirs& crwDirs, uint16_t crwTagId) override;
size_t doWrite(Blob& blob, ByteOrder byteOrder, size_t offset) override;
// See base class comment
void doRead(const byte* pData, size_t size, uint32_t start, ByteOrder byteOrder) override;
// See base class comment
void doDecode(Image& image, ByteOrder byteOrder) const override;
// See base class comment
void doPrint(std::ostream& os, ByteOrder byteOrder, const std::string& prefix) const override;
[[nodiscard]] bool doEmpty() const override;
// See base class comment
[[nodiscard]] CiffComponent* doFindComponent(uint16_t crwTagId, uint16_t crwDir) const override;
// DATA
Components components_;
UniquePtr m_; // used by recursive doAdd
}; // class CiffDirectory
class CiffHeader {
public:
using UniquePtr = std::unique_ptr<CiffHeader>;
CiffHeader() = default;
virtual ~CiffHeader() = default;
void read(const byte* pData, size_t size);
void add(uint16_t crwTagId, uint16_t crwDir, DataBuf&& buf);
void remove(uint16_t crwTagId, uint16_t crwDir) const;
static const char* signature() {
return signature_;
}
void write(Blob& blob) const;
void decode(Image& image) const;
[[nodiscard]] ByteOrder byteOrder() const {
return byteOrder_;
}
[[nodiscard]] CiffComponent* findComponent(uint16_t crwTagId, uint16_t crwDir) const;
private:
// DATA
static constexpr auto signature_ = "HEAPCCDR";
std::unique_ptr<CiffDirectory> pRootDir_;
ByteOrder byteOrder_ = littleEndian;
uint32_t offset_ = 0;
std::vector<byte> pPadding_;
uint32_t padded_ = 0;
}; // class CiffHeader
struct CrwMapping {
uint16_t crwTagId_;
uint16_t crwDir_;
uint32_t size_;
uint16_t tag_;
IfdId ifdId_;
CrwDecodeFct toExif_;
CrwEncodeFct fromExif_;
};
class CrwMap {
public:
static void decode(const CiffComponent& ciffComponent, Image& image, ByteOrder byteOrder);
static void encode(CiffHeader* pHead, const Image& image);
static void loadStack(CrwDirs& crwDirs, uint16_t crwDir);
private:
static const CrwMapping* crwMapping(uint16_t crwDir, uint16_t crwTagId);
static void decodeBasic(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
ByteOrder byteOrder);
static void decode0x0805(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
ByteOrder byteOrder);
static void decode0x080a(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
ByteOrder byteOrder);
static void decodeArray(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
ByteOrder byteOrder);
static void decode0x180e(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
ByteOrder byteOrder);
static void decode0x1810(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
ByteOrder byteOrder);
static void decode0x2008(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
ByteOrder byteOrder);
static void encodeBasic(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
static void encode0x0805(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
static void encode0x080a(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
static void encodeArray(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
static void encode0x180e(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
static void encode0x1810(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
static void encode0x2008(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
// DATA
static const CrwMapping crwMapping_[];
static const CrwSubDir crwSubDir_[];
}; // class CrwMap
// *****************************************************************************
// template, inline and free functions
DataBuf packIfdId(const ExifData& exifData, IfdId ifdId, ByteOrder byteOrder);
} // namespace Exiv2::Internal
#endif // EXIV2_CRWIMAGE_INT_HPP
Exiv2::ExifData
A container for Exif data. This is a top-level class of the Exiv2 library. The container holds Exifda...
Definition exif.hpp:379
Exiv2::Image
Abstract base class defining the interface for an image. This is the top-level interface to the Exiv2...
Definition image.hpp:50
Exiv2::Internal::CiffComponent
Interface class for components of the CIFF directory hierarchy of a CRW (Canon Raw data) image....
Definition crwimage_int.hpp:52
Exiv2::Internal::CiffComponent::writeDirEntry
void writeDirEntry(Blob &blob, ByteOrder byteOrder) const
Write a directory entry for the component to the blob. If the size of the data is not larger than 8 b...
Definition crwimage_int.cpp:380
Exiv2::Internal::CiffComponent::read
void read(const byte *pData, size_t size, uint32_t start, ByteOrder byteOrder)
Read a component from a data buffer.
Definition crwimage_int.cpp:181
Exiv2::Internal::CiffComponent::pData
const byte * pData() const
Return a pointer to the data area of this component.
Definition crwimage_int.hpp:204
Exiv2::Internal::CiffComponent::setSize
void setSize(size_t size)
Set the size of the data area.
Definition crwimage_int.hpp:244
Exiv2::Internal::CiffComponent::doFindComponent
virtual CiffComponent * doFindComponent(uint16_t crwTagId, uint16_t crwDir) const
Implements findComponent(). The default implementation checks the entry.
Definition crwimage_int.cpp:494
Exiv2::Internal::CiffComponent::doPrint
virtual void doPrint(std::ostream &os, ByteOrder byteOrder, const std::string &prefix) const
Implements print(). The default implementation prints the entry.
Definition crwimage_int.cpp:418
Exiv2::Internal::CiffComponent::typeId
TypeId typeId() const
Return the type id of this component.
Definition crwimage_int.hpp:214
Exiv2::Internal::CiffComponent::add
void add(UniquePtr component)
Add a component to the composition.
Definition crwimage_int.cpp:142
Exiv2::Internal::CiffComponent::empty
bool empty() const
Return true if the component is empty, else false.
Definition crwimage_int.cpp:619
Exiv2::Internal::CiffComponent::doWrite
virtual size_t doWrite(Blob &blob, ByteOrder byteOrder, size_t offset)=0
Implements write()
Exiv2::Internal::CiffComponent::size
size_t size() const
Return the data size of this component.
Definition crwimage_int.hpp:194
Exiv2::Internal::CiffComponent::write
size_t write(Blob &blob, ByteOrder byteOrder, size_t offset)
Write the metadata from the raw metadata component to the binary image blob. This method may append t...
Definition crwimage_int.cpp:314
Exiv2::Internal::CiffComponent::doRemove
virtual void doRemove(CrwDirs &crwDirs, uint16_t crwTagId)
Implements remove(). The default implementation does nothing.
Definition crwimage_int.cpp:593
Exiv2::Internal::CiffComponent::CiffComponent
CiffComponent()=default
Default constructor.
Exiv2::Internal::CiffComponent::doAdd
virtual void doAdd(UniquePtr component)=0
Implements add()
Exiv2::Internal::CiffComponent::dataLocation
DataLocId dataLocation() const
Return the data location for this component.
Definition crwimage_int.hpp:219
Exiv2::Internal::CiffComponent::UniquePtr
std::unique_ptr< CiffComponent > UniquePtr
CiffComponent auto_ptr type.
Definition crwimage_int.hpp:55
Exiv2::Internal::CiffComponent::Components
std::vector< CiffComponent * > Components
Container type to hold all metadata.
Definition crwimage_int.hpp:57
Exiv2::Internal::CiffComponent::setOffset
void setOffset(size_t offset)
Set the offset for this component.
Definition crwimage_int.hpp:248
Exiv2::Internal::CiffComponent::doEmpty
virtual bool doEmpty() const
Implements empty(). Default implementation returns true if size is 0.
Definition crwimage_int.cpp:623
Exiv2::Internal::CiffComponent::doDecode
virtual void doDecode(Image &image, ByteOrder byteOrder) const =0
Implements decode()
Exiv2::Internal::CiffComponent::remove
void remove(CrwDirs &crwDirs, uint16_t crwTagId)
Remove crwTagId from the parse tree, if it exists yet. crwDirs contains the path of subdirectories,...
Definition crwimage_int.cpp:589
Exiv2::Internal::CiffComponent::setDir
void setDir(uint16_t dir)
Set the directory tag for this component.
Definition crwimage_int.hpp:137
Exiv2::Internal::CiffComponent::findComponent
CiffComponent * findComponent(uint16_t crwTagId, uint16_t crwDir) const
Finds crwTagId in directory crwDir, returning a pointer to the component or 0 if not found.
Definition crwimage_int.cpp:490
Exiv2::Internal::CiffComponent::decode
void decode(Image &image, ByteOrder byteOrder) const
Decode metadata from the component and add it to image.
Definition crwimage_int.cpp:271
Exiv2::Internal::CiffComponent::tagId
uint16_t tagId() const
Return the tag id of this component.
Definition crwimage_int.hpp:209
Exiv2::Internal::CiffComponent::tag
uint16_t tag() const
Return the tag of this component.
Definition crwimage_int.hpp:179
Exiv2::Internal::CiffComponent::print
void print(std::ostream &os, ByteOrder byteOrder, const std::string &prefix="") const
Print debug info about a component to os.
Definition crwimage_int.cpp:414
Exiv2::Internal::CiffComponent::~CiffComponent
virtual ~CiffComponent()=default
Virtual destructor.
Exiv2::Internal::CiffComponent::dir
uint16_t dir() const
Return the tag of the directory containing this component.
Definition crwimage_int.hpp:174
Exiv2::Internal::CiffComponent::offset
size_t offset() const
Return the offset to the data from the start of the directory.
Definition crwimage_int.hpp:199
Exiv2::Internal::CiffComponent::doRead
virtual void doRead(const byte *pData, size_t size, uint32_t start, ByteOrder byteOrder)
Implements read(). The default implementation reads a directory entry.
Definition crwimage_int.cpp:185
Exiv2::Internal::CiffComponent::setValue
void setValue(DataBuf &&buf)
Set the data value of the entry.
Definition crwimage_int.cpp:440
Exiv2::Internal::CiffComponent::writeValueData
size_t writeValueData(Blob &blob, size_t offset)
Writes the entry's value if size is larger than eight bytes. If needed, the value is padded with one ...
Definition crwimage_int.cpp:322
Exiv2::Internal::CiffDirectory
This class models a CIFF directory of a CRW (Canon Raw data) image.
Definition crwimage_int.hpp:311
Exiv2::Internal::CiffDirectory::~CiffDirectory
~CiffDirectory() override
Virtual destructor.
Definition crwimage_int.cpp:136
Exiv2::Internal::CiffDirectory::readDirectory
void readDirectory(const byte *pData, size_t size, ByteOrder byteOrder)
Parse a CIFF directory from a memory buffer.
Definition crwimage_int.cpp:237
Exiv2::Internal::CiffEntry
This class models one directory entry of a CIFF directory of a CRW (Canon Raw data) image.
Definition crwimage_int.hpp:288
Exiv2::Internal::CiffHeader
This class models the header of a CRW (Canon Raw data) image. It is the head of a CIFF parse tree,...
Definition crwimage_int.hpp:383
Exiv2::Internal::CiffHeader::remove
void remove(uint16_t crwTagId, uint16_t crwDir) const
Remove entry crwTagId in directory crwDir from the parse tree. If it's the last entry in the director...
Definition crwimage_int.cpp:580
Exiv2::Internal::CiffHeader::add
void add(uint16_t crwTagId, uint16_t crwDir, DataBuf &&buf)
Set the value of entry crwTagId in directory crwDir to buf. If this tag doesn't exist,...
Definition crwimage_int.cpp:510
Exiv2::Internal::CiffHeader::byteOrder
ByteOrder byteOrder() const
Return the byte order (little or big endian).
Definition crwimage_int.hpp:456
Exiv2::Internal::CiffHeader::CiffHeader
CiffHeader()=default
Default constructor.
Exiv2::Internal::CiffHeader::decode
void decode(Image &image) const
Decode the CRW image and add it to image.
Definition crwimage_int.cpp:265
Exiv2::Internal::CiffHeader::read
void read(const byte *pData, size_t size)
Read the CRW image from a data buffer, starting with the Ciff header.
Definition crwimage_int.cpp:154
Exiv2::Internal::CiffHeader::~CiffHeader
virtual ~CiffHeader()=default
Virtual destructor.
Exiv2::Internal::CiffHeader::UniquePtr
std::unique_ptr< CiffHeader > UniquePtr
CiffHeader auto_ptr type.
Definition crwimage_int.hpp:386
Exiv2::Internal::CiffHeader::write
void write(Blob &blob) const
Write the CRW image to the binary image blob, starting with the Ciff header. This method appends to t...
Definition crwimage_int.cpp:285
Exiv2::Internal::CiffHeader::signature
static const char * signature()
Return a pointer to the Canon CRW signature.
Definition crwimage_int.hpp:430
Exiv2::Internal::CiffHeader::findComponent
CiffComponent * findComponent(uint16_t crwTagId, uint16_t crwDir) const
Finds crwTagId in directory crwDir in the parse tree, returning a pointer to the component or 0 if no...
Definition crwimage_int.cpp:484
Exiv2::Internal::CrwMap
Static class providing mapping functionality from CRW entries to image metadata and vice versa.
Definition crwimage_int.hpp:496
Exiv2::Internal::CrwMap::decode
static void decode(const CiffComponent &ciffComponent, Image &image, ByteOrder byteOrder)
Decode image metadata from a CRW entry, convert and add it to the image metadata. This function conve...
Definition crwimage_int.cpp:631
Exiv2::Internal::CrwMap::encode
static void encode(CiffHeader *pHead, const Image &image)
Encode image metadata from image into the CRW parse tree. This function converts all Exif metadata th...
Definition crwimage_int.cpp:834
Exiv2::Internal::CrwMap::loadStack
static void loadStack(CrwDirs &crwDirs, uint16_t crwDir)
Load the stack: loop through the CRW subdirs hierarchy and push all directories on the path from crwD...
Definition crwimage_int.cpp:824
Exiv2::Internal
Helper structure for the Matroska tags lookup table.
Definition matroskavideo.hpp:39
Exiv2::Internal::packIfdId
DataBuf packIfdId(const ExifData &exifData, IfdId ifdId, ByteOrder byteOrder)
Pack the tag values of all ifdId tags in exifData into a data buffer. This function is used to pack C...
Definition crwimage_int.cpp:1002
Exiv2::Internal::CrwEncodeFct
void(*)(const Image &, const CrwMapping *, CiffHeader *) CrwEncodeFct
Function pointer for functions to encode CRW entries from Exif tags.
Definition crwimage_int.hpp:35
Exiv2::Internal::CrwDecodeFct
void(*)(const CiffComponent &, const CrwMapping *, Image &, ByteOrder) CrwDecodeFct
Function pointer for functions to decode Exif tags from a CRW entry.
Definition crwimage_int.hpp:32
Exiv2::Internal::DataLocId
DataLocId
Type to identify where the data is stored in a directory.
Definition crwimage_int.hpp:41
Exiv2::Internal::CrwDirs
std::stack< CrwSubDir > CrwDirs
Stack to hold a path of CRW directories.
Definition crwimage_int.hpp:38
Exiv2::IfdId
IfdId
Type to specify the IFD to which a metadata belongs.
Definition tags.hpp:34
Exiv2::TypeId
TypeId
Exiv2 value type identifiers.
Definition types.hpp:70
Exiv2::ByteOrder
ByteOrder
Type to express the byte order (little or big endian)
Definition types.hpp:34
Exiv2::Blob
std::vector< byte > Blob
Container for binary data.
Definition types.hpp:102
Exiv2::DataBuf
Utility class containing a character array. All it does is to take care of memory allocation and dele...
Definition types.hpp:124
Exiv2::Internal::CrwMapping
Structure for a mapping table for conversion of CIFF entries to image metadata and vice versa.
Definition crwimage_int.hpp:482
Exiv2::Internal::CrwMapping::toExif_
CrwDecodeFct toExif_
Conversion function.
Definition crwimage_int.hpp:488
Exiv2::Internal::CrwMapping::ifdId_
IfdId ifdId_
Exif Ifd id to map to.
Definition crwimage_int.hpp:487
Exiv2::Internal::CrwMapping::tag_
uint16_t tag_
Exif tag to map to.
Definition crwimage_int.hpp:486
Exiv2::Internal::CrwMapping::size_
uint32_t size_
Data size (overwrites the size from the entry)
Definition crwimage_int.hpp:485
Exiv2::Internal::CrwMapping::crwDir_
uint16_t crwDir_
CRW directory tag.
Definition crwimage_int.hpp:484
Exiv2::Internal::CrwMapping::fromExif_
CrwEncodeFct fromExif_
Reverse conversion function.
Definition crwimage_int.hpp:489
Exiv2::Internal::CrwMapping::crwTagId_
uint16_t crwTagId_
CRW tag id.
Definition crwimage_int.hpp:483
Exiv2::Internal::CrwSubDir
Definition crwimage_int.hpp:23