| Exiv2

Loading...
Searching...
No Matches
crwimage_int.hpp
1// SPDX-License-Identifier: GPL-2.0-or-later
2
3#ifndef EXIV2_CRWIMAGE_INT_HPP
4#define EXIV2_CRWIMAGE_INT_HPP
5
6// *****************************************************************************
7// included header files
8#include "image.hpp"
9#include "tags_int.hpp"
10
11// + standard includes
12#include <stack>
13#include <vector>
14
15// *****************************************************************************
16// namespace extensions
17 namespace Exiv2::Internal {
18// *****************************************************************************
19// class declarations
20 class CiffHeader;
21 class CiffComponent;
22 struct CrwMapping;
23 struct CrwSubDir {
24 uint16_t dir;
25 uint16_t parent;
26};
27
28// *****************************************************************************
29// type definitions
30
32 using CrwDecodeFct = void (*)(const CiffComponent&, const CrwMapping*, Image&, ByteOrder);
33
35 using CrwEncodeFct = void (*)(const Image&, const CrwMapping*, CiffHeader*);
36
38 using CrwDirs = std::stack<CrwSubDir>;
39
41 enum class DataLocId { valueData, directoryData, lastDataLocId };
42
43// *****************************************************************************
44// class definitions
45
52 class CiffComponent {
53 public:
55 using UniquePtr = std::unique_ptr<CiffComponent>;
57 using Components = std::vector<CiffComponent*>;
58
60
61
62 CiffComponent() = default;
64 CiffComponent(uint16_t tag, uint16_t dir);
65 CiffComponent(const CiffComponent&) = delete;
66 CiffComponent& operator=(const CiffComponent&) = delete;
68 virtual ~CiffComponent() = default;
70
72
73 // Default assignment operator is fine
74
76 void add(UniquePtr component);
90 CiffComponent* add(CrwDirs& crwDirs, uint16_t crwTagId);
100 void remove(CrwDirs& crwDirs, uint16_t crwTagId);
111 void read(const byte* pData, size_t size, uint32_t start, ByteOrder byteOrder);
122 size_t write(Blob& blob, ByteOrder byteOrder, size_t offset);
123
134 size_t writeValueData(Blob& blob, size_t offset);
135
137 void setDir(uint16_t dir) {
138 dir_ = dir;
139 }
140
141 void setValue(DataBuf&& buf);
143
145 static TypeId typeId(uint16_t tag);
147 static DataLocId dataLocation(uint16_t tag);
148
150
151
158 void decode(Image& image, ByteOrder byteOrder) const;
166 void print(std::ostream& os, ByteOrder byteOrder, const std::string& prefix = "") const;
172 void writeDirEntry(Blob& blob, ByteOrder byteOrder) const;
174 [[nodiscard]] uint16_t dir() const {
175 return dir_;
176 }
177
179 [[nodiscard]] uint16_t tag() const {
180 return tag_;
181 }
182
184 [[nodiscard]] bool empty() const;
185
194 [[nodiscard]] size_t size() const {
195 return size_;
196 }
197
199 [[nodiscard]] size_t offset() const {
200 return offset_;
201 }
202
204 [[nodiscard]] const byte* pData() const {
205 return pData_;
206 }
207
209 [[nodiscard]] uint16_t tagId() const {
210 return tag_ & 0x3fff;
211 }
212
214 [[nodiscard]] TypeId typeId() const {
215 return typeId(tag_);
216 }
217
219 [[nodiscard]] DataLocId dataLocation() const {
220 return dataLocation(tag_);
221 }
222
227 [[nodiscard]] CiffComponent* findComponent(uint16_t crwTagId, uint16_t crwDir) const;
229
230 protected:
232
233
234 virtual void doAdd(UniquePtr component) = 0;
236 virtual CiffComponent* doAdd(CrwDirs& crwDirs, uint16_t crwTagId);
238 virtual void doRemove(CrwDirs& crwDirs, uint16_t crwTagId);
240 virtual void doRead(const byte* pData, size_t size, uint32_t start, ByteOrder byteOrder);
242 virtual size_t doWrite(Blob& blob, ByteOrder byteOrder, size_t offset) = 0;
244 void setSize(size_t size) {
245 size_ = size;
246 }
247
248 void setOffset(size_t offset) {
249 offset_ = offset;
250 }
251
252
254
255
256 virtual void doDecode(Image& image, ByteOrder byteOrder) const = 0;
258 virtual void doPrint(std::ostream& os, ByteOrder byteOrder, const std::string& prefix) const;
260 [[nodiscard]] virtual bool doEmpty() const;
262 [[nodiscard]] virtual CiffComponent* doFindComponent(uint16_t crwTagId, uint16_t crwDir) const;
264
265 private:
266 // DATA
267 uint16_t dir_ = 0;
268 uint16_t tag_ = 0;
269 size_t size_ = 0;
270 size_t offset_ = 0;
271
272 // Notes on the ownership model of pData_: pData_ is a always a read-only
273 // pointer to a buffer owned by somebody else. Usually it is a pointer
274 // into a copy of the image that was memory-mapped in CrwImage::readMetadata().
275 // However, if CiffComponent::setValue() is used, then it is a pointer into
276 // the storage_ DataBuf below.
277 const byte* pData_ = nullptr;
278
279 // This DataBuf is only used when CiffComponent::setValue is called.
280 // Otherwise, it remains empty.
281 DataBuf storage_;
282}; // class CiffComponent
283
288 class CiffEntry : public CiffComponent {
289 using CiffComponent::CiffComponent;
291
292 using CiffComponent::doAdd;
293 // See base class comment
294 void doAdd(UniquePtr component) override;
299 size_t doWrite(Blob& blob, ByteOrder byteOrder, size_t offset) override;
301
303
304 // See base class comment
305 void doDecode(Image& image, ByteOrder byteOrder) const override;
307
308}; // class CiffEntry
309
311 class CiffDirectory : public CiffComponent {
312 using CiffComponent::CiffComponent;
313
314 public:
316
317
318 ~CiffDirectory() override;
320
321 CiffDirectory(const CiffDirectory&) = delete;
322 CiffDirectory& operator=(const CiffDirectory&) = delete;
323
325
326 // Default assignment operator is fine
327
335 void readDirectory(const byte* pData, size_t size, ByteOrder byteOrder);
337
338 private:
340
341 // See base class comment
342 void doAdd(UniquePtr component) override;
343 // See base class comment
344 CiffComponent* doAdd(CrwDirs& crwDirs, uint16_t crwTagId) override;
345 // See base class comment
346 void doRemove(CrwDirs& crwDirs, uint16_t crwTagId) override;
351 size_t doWrite(Blob& blob, ByteOrder byteOrder, size_t offset) override;
352 // See base class comment
353 void doRead(const byte* pData, size_t size, uint32_t start, ByteOrder byteOrder) override;
355
357
358 // See base class comment
359 void doDecode(Image& image, ByteOrder byteOrder) const override;
360
361 // See base class comment
362 void doPrint(std::ostream& os, ByteOrder byteOrder, const std::string& prefix) const override;
363
365 [[nodiscard]] bool doEmpty() const override;
366
367 // See base class comment
368 [[nodiscard]] CiffComponent* doFindComponent(uint16_t crwTagId, uint16_t crwDir) const override;
370
371 // DATA
372 Components components_;
373 UniquePtr m_; // used by recursive doAdd
374
375}; // class CiffDirectory
376
383 class CiffHeader {
384 public:
386 using UniquePtr = std::unique_ptr<CiffHeader>;
387
389
390
391 CiffHeader() = default;
393 virtual ~CiffHeader() = default;
395
397
398
407 void read(const byte* pData, size_t size);
417 void add(uint16_t crwTagId, uint16_t crwDir, DataBuf&& buf);
426 void remove(uint16_t crwTagId, uint16_t crwDir) const;
428
430 static const char* signature() {
431 return signature_;
432 }
433
435
436
444 void write(Blob& blob) const;
453 void decode(Image& image) const;
454
456 [[nodiscard]] ByteOrder byteOrder() const {
457 return byteOrder_;
458 }
459
463 [[nodiscard]] CiffComponent* findComponent(uint16_t crwTagId, uint16_t crwDir) const;
465
466 private:
467 // DATA
468 static constexpr auto signature_ = "HEAPCCDR";
469
470 std::unique_ptr<CiffDirectory> pRootDir_;
471 ByteOrder byteOrder_ = littleEndian;
472 uint32_t offset_ = 0;
473 std::vector<byte> pPadding_;
474 uint32_t padded_ = 0;
475
476}; // class CiffHeader
477
482 struct CrwMapping {
483 uint16_t crwTagId_;
484 uint16_t crwDir_;
485 uint32_t size_;
486 uint16_t tag_;
487 IfdId ifdId_;
488 CrwDecodeFct toExif_;
489 CrwEncodeFct fromExif_;
490};
491
496 class CrwMap {
497 public:
508 static void decode(const CiffComponent& ciffComponent, Image& image, ByteOrder byteOrder);
518 static void encode(CiffHeader* pHead, const Image& image);
519
526 static void loadStack(CrwDirs& crwDirs, uint16_t crwDir);
527
528 private:
530 static const CrwMapping* crwMapping(uint16_t crwDir, uint16_t crwTagId);
531
541 static void decodeBasic(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
542 ByteOrder byteOrder);
543
545 static void decode0x0805(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
546 ByteOrder byteOrder);
547
549 static void decode0x080a(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
550 ByteOrder byteOrder);
551
553 static void decodeArray(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
554 ByteOrder byteOrder);
555
557 static void decode0x180e(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
558 ByteOrder byteOrder);
559
561 static void decode0x1810(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
562 ByteOrder byteOrder);
563
565 static void decode0x2008(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
566 ByteOrder byteOrder);
567
582 static void encodeBasic(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
583
585 static void encode0x0805(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
586
588 static void encode0x080a(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
589
591 static void encodeArray(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
592
594 static void encode0x180e(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
595
597 static void encode0x1810(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
598
600 static void encode0x2008(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
601
602 // DATA
603 static const CrwMapping crwMapping_[];
604 static const CrwSubDir crwSubDir_[];
605
606}; // class CrwMap
607
608// *****************************************************************************
609// template, inline and free functions
610
616 DataBuf packIfdId(const ExifData& exifData, IfdId ifdId, ByteOrder byteOrder);
617
618} // namespace Exiv2::Internal
619
620#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:621
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:625
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::~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:633
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:836
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:826
Exiv2::Internal
Helper structure for the Matroska tags lookup table.
Definition matroskavideo.hpp:39
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::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:1004
Exiv2::Internal::DataLocId
DataLocId
Type to identify where the data is stored in a directory.
Definition crwimage_int.hpp:41
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::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