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  CiffComponent* cc_ = nullptr;
375 
376 }; // class CiffDirectory
377 
384 class CiffHeader {
385  public:
387  using UniquePtr = std::unique_ptr<CiffHeader>;
388 
390 
391  CiffHeader() = default;
394  virtual ~CiffHeader() = default;
396 
398 
399 
408  void read(const byte* pData, size_t size);
418  void add(uint16_t crwTagId, uint16_t crwDir, DataBuf&& buf);
427  void remove(uint16_t crwTagId, uint16_t crwDir) const;
429 
431  static const char* signature() {
432  return signature_;
433  }
434 
436 
437 
445  void write(Blob& blob) const;
454  void decode(Image& image) const;
455 
457  [[nodiscard]] ByteOrder byteOrder() const {
458  return byteOrder_;
459  }
464  [[nodiscard]] CiffComponent* findComponent(uint16_t crwTagId, uint16_t crwDir) const;
466 
467  private:
468  // DATA
469  static constexpr auto signature_ = "HEAPCCDR";
470 
471  std::unique_ptr<CiffDirectory> pRootDir_;
472  ByteOrder byteOrder_ = littleEndian;
473  uint32_t offset_ = 0;
474  std::vector<byte> pPadding_;
475  uint32_t padded_ = 0;
476 
477 }; // class CiffHeader
478 
483 struct CrwMapping {
484  uint16_t crwTagId_;
485  uint16_t crwDir_;
486  uint32_t size_;
487  uint16_t tag_;
491 };
492 
497 class CrwMap {
498  public:
509  static void decode(const CiffComponent& ciffComponent, Image& image, ByteOrder byteOrder);
519  static void encode(CiffHeader* pHead, const Image& image);
520 
527  static void loadStack(CrwDirs& crwDirs, uint16_t crwDir);
528 
529  private:
531  static const CrwMapping* crwMapping(uint16_t crwDir, uint16_t crwTagId);
532 
542  static void decodeBasic(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
543  ByteOrder byteOrder);
544 
546  static void decode0x0805(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
547  ByteOrder byteOrder);
548 
550  static void decode0x080a(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
551  ByteOrder byteOrder);
552 
554  static void decodeArray(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
555  ByteOrder byteOrder);
556 
558  static void decode0x180e(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
559  ByteOrder byteOrder);
560 
562  static void decode0x1810(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
563  ByteOrder byteOrder);
564 
566  static void decode0x2008(const CiffComponent& ciffComponent, const CrwMapping* pCrwMapping, Image& image,
567  ByteOrder byteOrder);
568 
583  static void encodeBasic(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
584 
586  static void encode0x0805(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
587 
589  static void encode0x080a(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
590 
592  static void encodeArray(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
593 
595  static void encode0x180e(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
596 
598  static void encode0x1810(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
599 
601  static void encode0x2008(const Image& image, const CrwMapping* pCrwMapping, CiffHeader* pHead);
602 
603  // DATA
604  static const CrwMapping crwMapping_[];
605  static const CrwSubDir crwSubDir_[];
606 
607 }; // class CrwMap
608 
609 // *****************************************************************************
610 // template, inline and free functions
611 
617 DataBuf packIfdId(const ExifData& exifData, IfdId ifdId, ByteOrder byteOrder);
618 
619 } // namespace Exiv2::Internal
620 
621 #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:373
Definition: crwimage_int.hpp:23
uint16_t crwTagId_
CRW tag id.
Definition: crwimage_int.hpp:484
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:998
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:489
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:384
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:431
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:457
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:488
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:490
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:820
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:387
Static class providing mapping functionality from CRW entries to image metadata and vice versa...
Definition: crwimage_int.hpp:497
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:483
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:486
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:627
virtual bool doEmpty() const
Implements empty(). Default implementation returns true if size is 0.
Definition: crwimage_int.cpp:619
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:589
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:487
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:830
uint16_t crwDir_
CRW directory tag.
Definition: crwimage_int.hpp:485
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:615