Exiv2
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 
53  public:
55  using UniquePtr = std::unique_ptr<CiffComponent>;
57  using Components = std::vector<CiffComponent*>;
58 
60 
61  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  }
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  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  }
248  void setOffset(size_t offset) {
249  offset_ = offset;
250  }
252 
254 
255  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 {
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 {
313 
314  public:
316 
317  ~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  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  }
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_;
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
void add(UniquePtr component)
Add a component to the composition.
Definition: crwimage_int.cpp:142
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
A container for Exif data. This is a top-level class of the Exiv2 library. The container holds Exifda...
Definition: exif.hpp:379
Definition: crwimage_int.hpp:23
uint16_t crwTagId_
CRW tag id.
Definition: crwimage_int.hpp:483
void setValue(DataBuf &&buf)
Set the data value of the entry.
Definition: crwimage_int.cpp:440
ByteOrder
Type to express the byte order (little or big endian)
Definition: types.hpp:34
void decode(Image &image, ByteOrder byteOrder) const
Decode metadata from the component and add it to image.
Definition: crwimage_int.cpp:271
virtual void doAdd(UniquePtr component)=0
Implements add()
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
TypeId
Exiv2 value type identifiers.
Definition: types.hpp:70
This class models a CIFF directory of a CRW (Canon Raw data) image.
Definition: crwimage_int.hpp:311
const byte * pData() const
Return a pointer to the data area of this component.
Definition: crwimage_int.hpp:204
CiffHeader()=default
Default constructor.
uint16_t tagId() const
Return the tag id of this component.
Definition: crwimage_int.hpp:209
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
uint8_t byte
1 byte unsigned integer type.
Definition: types.hpp:26
Abstract base class defining the interface for an image. This is the top-level interface to the Exiv2...
Definition: image.hpp:50
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
uint16_t dir() const
Return the tag of the directory containing this component.
Definition: crwimage_int.hpp:174
uint16_t tag() const
Return the tag of this component.
Definition: crwimage_int.hpp:179
size_t size() const
Return the data size of this component.
Definition: crwimage_int.hpp:194
Utility class containing a character array. All it does is to take care of memory allocation and dele...
Definition: types.hpp:124
CrwDecodeFct toExif_
Conversion function.
Definition: crwimage_int.hpp:488
CiffComponent()=default
Default constructor.
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
virtual size_t doWrite(Blob &blob, ByteOrder byteOrder, size_t offset)=0
Implements write()
static const char * signature()
Return a pointer to the Canon CRW signature.
Definition: crwimage_int.hpp:430
std::unique_ptr< CiffComponent > UniquePtr
CiffComponent auto_ptr type.
Definition: crwimage_int.hpp:55
IfdId
Type to specify the IFD to which a metadata belongs.
Definition: tags.hpp:34
void(*)(const Image &, const CrwMapping *, CiffHeader *) CrwEncodeFct
Function pointer for functions to encode CRW entries from Exif tags.
Definition: crwimage_int.hpp:35
ByteOrder byteOrder() const
Return the byte order (little or big endian).
Definition: crwimage_int.hpp:456
DataLocId dataLocation() const
Return the data location for this component.
Definition: crwimage_int.hpp:219
TypeId typeId() const
Return the type id of this component.
Definition: crwimage_int.hpp:214
This class models one directory entry of a CIFF directory of a CRW (Canon Raw data) image...
Definition: crwimage_int.hpp:288
virtual CiffComponent * doFindComponent(uint16_t crwTagId, uint16_t crwDir) const
Implements findComponent(). The default implementation checks the entry.
Definition: crwimage_int.cpp:494
virtual ~CiffHeader()=default
Virtual destructor.
void setOffset(size_t offset)
Set the offset for this component.
Definition: crwimage_int.hpp:248
IfdId ifdId_
Exif Ifd id to map to.
Definition: crwimage_int.hpp:487
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
CrwEncodeFct fromExif_
Reverse conversion function.
Definition: crwimage_int.hpp:489
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
void decode(Image &image) const
Decode the CRW image and add it to image.
Definition: crwimage_int.cpp:265
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
Helper structure for the Matroska tags lookup table.
Definition: matroskavideo.hpp:39
std::unique_ptr< CiffHeader > UniquePtr
CiffHeader auto_ptr type.
Definition: crwimage_int.hpp:386
Static class providing mapping functionality from CRW entries to image metadata and vice versa...
Definition: crwimage_int.hpp:496
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
Structure for a mapping table for conversion of CIFF entries to image metadata and vice versa...
Definition: crwimage_int.hpp:482
virtual void doDecode(Image &image, ByteOrder byteOrder) const =0
Implements decode()
DataLocId
Type to identify where the data is stored in a directory.
Definition: crwimage_int.hpp:41
uint32_t size_
Data size (overwrites the size from the entry)
Definition: crwimage_int.hpp:485
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
virtual bool doEmpty() const
Implements empty(). Default implementation returns true if size is 0.
Definition: crwimage_int.cpp:623
void setDir(uint16_t dir)
Set the directory tag for this component.
Definition: crwimage_int.hpp:137
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
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
virtual void doRemove(CrwDirs &crwDirs, uint16_t crwTagId)
Implements remove(). The default implementation does nothing.
Definition: crwimage_int.cpp:593
void setSize(size_t size)
Set the size of the data area.
Definition: crwimage_int.hpp:244
size_t offset() const
Return the offset to the data from the start of the directory.
Definition: crwimage_int.hpp:199
uint16_t tag_
Exif tag to map to.
Definition: crwimage_int.hpp:486
void readDirectory(const byte *pData, size_t size, ByteOrder byteOrder)
Parse a CIFF directory from a memory buffer.
Definition: crwimage_int.cpp:237
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, it is added along with all directories needed.
Definition: crwimage_int.cpp:510
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
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
virtual ~CiffComponent()=default
Virtual destructor.
std::stack< CrwSubDir > CrwDirs
Stack to hold a path of CRW directories.
Definition: crwimage_int.hpp:38
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
std::vector< byte > Blob
Container for binary data.
Definition: types.hpp:102
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
uint16_t crwDir_
CRW directory tag.
Definition: crwimage_int.hpp:484
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
std::vector< CiffComponent * > Components
Container type to hold all metadata.
Definition: crwimage_int.hpp:57
~CiffDirectory() override
Virtual destructor.
Definition: crwimage_int.cpp:136
Interface class for components of the CIFF directory hierarchy of a CRW (Canon Raw data) image...
Definition: crwimage_int.hpp:52
bool empty() const
Return true if the component is empty, else false.
Definition: crwimage_int.cpp:619