Exiv2
types.hpp
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 #ifndef TYPES_HPP_
4 #define TYPES_HPP_
5 
6 #include "exiv2lib_export.h"
7 
8 // included header files
9 #include "config.h"
10 #include "slice.hpp"
11 
12 // standard includes
13 #include <algorithm>
14 #include <cstdint>
15 #include <limits>
16 #include <sstream>
17 #include <vector>
18 
19 // *****************************************************************************
20 // namespace extensions
21 namespace Exiv2 {
22 // *****************************************************************************
23 // type definitions
24 
26 using byte = uint8_t;
27 
29 using URational = std::pair<uint32_t, uint32_t>;
31 using Rational = std::pair<int32_t, int32_t>;
32 
34 enum ByteOrder {
35  invalidByteOrder,
36  littleEndian,
37  bigEndian,
38 };
39 
42  wmIntrusive,
43  wmNonIntrusive,
44 };
45 
47 enum MetadataId {
48  mdNone = 0,
49  mdExif = 1,
50  mdIptc = 2,
51  mdComment = 4,
52  mdXmp = 8,
53  mdIccProfile = 16,
54 };
55 
57 enum AccessMode {
58  amNone = 0,
59  amRead = 1,
60  amWrite = 2,
61  amReadWrite = 3,
62 };
63 
70 enum TypeId {
76  signedByte = 6,
77  undefined = 7,
79  signedLong = 9,
81  tiffFloat = 11,
82  tiffDouble = 12,
83  tiffIfd = 13,
86  tiffIfd8 = 18,
87  string = 0x10000,
88  date = 0x10001,
89  time = 0x10002,
90  comment = 0x10003,
91  directory = 0x10004,
92  xmpText = 0x10005,
93  xmpAlt = 0x10006,
94  xmpBag = 0x10007,
95  xmpSeq = 0x10008,
96  langAlt = 0x10009,
97  invalidTypeId = 0x1fffe,
98  lastTypeId = 0x1ffff,
99 };
100 
102 using Blob = std::vector<byte>;
103 
104 // *****************************************************************************
105 // class definitions
106 
108 class EXIV2API TypeInfo {
109  public:
111  static const char* typeName(TypeId typeId);
113  static TypeId typeId(const std::string& typeName);
115  static size_t typeSize(TypeId typeId);
116 };
117 
124 struct EXIV2API DataBuf {
126 
127  DataBuf() = default;
130  explicit DataBuf(size_t size);
132  DataBuf(const byte* pData, size_t size);
134 
136 
137 
142  void alloc(size_t size);
146  void resize(size_t size);
147 
149  void reset();
151 
152  using iterator = std::vector<byte>::iterator;
153  using const_iterator = std::vector<byte>::const_iterator;
154 
155  iterator begin() noexcept {
156  return pData_.begin();
157  }
158  [[nodiscard]] const_iterator cbegin() const noexcept {
159  return pData_.cbegin();
160  }
161  iterator end() noexcept {
162  return pData_.end();
163  }
164  [[nodiscard]] const_iterator cend() const noexcept {
165  return pData_.end();
166  }
167 
168  [[nodiscard]] size_t size() const {
169  return pData_.size();
170  }
171 
172  [[nodiscard]] uint8_t read_uint8(size_t offset) const;
173  void write_uint8(size_t offset, uint8_t x);
174 
175  [[nodiscard]] uint16_t read_uint16(size_t offset, ByteOrder byteOrder) const;
176  void write_uint16(size_t offset, uint16_t x, ByteOrder byteOrder);
177 
178  [[nodiscard]] uint32_t read_uint32(size_t offset, ByteOrder byteOrder) const;
179  void write_uint32(size_t offset, uint32_t x, ByteOrder byteOrder);
180 
181  [[nodiscard]] uint64_t read_uint64(size_t offset, ByteOrder byteOrder) const;
182  void write_uint64(size_t offset, uint64_t x, ByteOrder byteOrder);
183 
185  int cmpBytes(size_t offset, const void* buf, size_t bufsize) const;
186 
188  [[nodiscard]] byte* data(size_t offset = 0);
189 
191  [[nodiscard]] const byte* c_data(size_t offset = 0) const;
192 
194  [[nodiscard]] const char* c_str(size_t offset = 0) const;
195 
196  [[nodiscard]] bool empty() const {
197  return pData_.empty();
198  }
199 
200  private:
201  std::vector<byte> pData_;
202 };
203 
217 EXIV2API Slice<byte*> makeSlice(DataBuf& buf, size_t begin, size_t end);
218 
220 EXIV2API Slice<const byte*> makeSlice(const DataBuf& buf, size_t begin, size_t end);
221 
222 // *****************************************************************************
223 // free functions
224 
226 EXIV2API uint16_t getUShort(const byte* buf, ByteOrder byteOrder);
228 template <typename T>
229 uint16_t getUShort(const Slice<T>& buf, ByteOrder byteOrder) {
230  if (byteOrder == littleEndian) {
231  return static_cast<byte>(buf.at(1)) << 8 | static_cast<byte>(buf.at(0));
232  }
233  return static_cast<byte>(buf.at(0)) << 8 | static_cast<byte>(buf.at(1));
234 }
235 
237 EXIV2API uint32_t getULong(const byte* buf, ByteOrder byteOrder);
239 EXIV2API uint64_t getULongLong(const byte* buf, ByteOrder byteOrder);
241 EXIV2API URational getURational(const byte* buf, ByteOrder byteOrder);
243 EXIV2API int16_t getShort(const byte* buf, ByteOrder byteOrder);
245 EXIV2API int32_t getLong(const byte* buf, ByteOrder byteOrder);
247 EXIV2API Rational getRational(const byte* buf, ByteOrder byteOrder);
249 EXIV2API float getFloat(const byte* buf, ByteOrder byteOrder);
251 EXIV2API double getDouble(const byte* buf, ByteOrder byteOrder);
252 
254 EXIV2API std::ostream& operator<<(std::ostream& os, const Rational& r);
256 EXIV2API std::istream& operator>>(std::istream& is, Rational& r);
258 EXIV2API std::ostream& operator<<(std::ostream& os, const URational& r);
260 EXIV2API std::istream& operator>>(std::istream& is, URational& r);
261 
266 EXIV2API size_t us2Data(byte* buf, uint16_t s, ByteOrder byteOrder);
271 EXIV2API size_t ul2Data(byte* buf, uint32_t l, ByteOrder byteOrder);
276 EXIV2API size_t ull2Data(byte* buf, uint64_t l, ByteOrder byteOrder);
281 EXIV2API size_t ur2Data(byte* buf, URational l, ByteOrder byteOrder);
286 EXIV2API size_t s2Data(byte* buf, int16_t s, ByteOrder byteOrder);
291 EXIV2API size_t l2Data(byte* buf, int32_t l, ByteOrder byteOrder);
296 EXIV2API size_t r2Data(byte* buf, Rational l, ByteOrder byteOrder);
301 EXIV2API size_t f2Data(byte* buf, float f, ByteOrder byteOrder);
306 EXIV2API size_t d2Data(byte* buf, double d, ByteOrder byteOrder);
307 
313 EXIV2API void hexdump(std::ostream& os, const byte* buf, size_t len, size_t offset = 0);
314 
320 EXIV2API bool isHex(const std::string& str, size_t size = 0, const std::string& prefix = "");
321 
327 EXIV2API int exifTime(const char* buf, tm* tm);
328 
333 EXIV2API const char* exvGettext(const char* str);
334 
347 EXIV2API int64_t parseInt64(const std::string& s, bool& ok);
348 
361 EXIV2API uint32_t parseUint32(const std::string& s, bool& ok);
362 
375 EXIV2API float parseFloat(const std::string& s, bool& ok);
376 
391 EXIV2API Rational parseRational(const std::string& s, bool& ok);
392 
399 EXIV2API Rational floatToRationalCast(float f);
400 
401 // *****************************************************************************
402 // template and inline definitions
403 
448 template <typename T, typename K, int N>
449 const T* find(T (&src)[N], const K& key) {
450  auto rc = std::find(src, src + N, key);
451  return rc == src + N ? nullptr : rc;
452 }
453 
455 template <typename T>
456 std::string toStringHelper(const T& arg, std::true_type) {
457  return std::to_string(arg);
458 }
459 
460 template <typename T>
461 std::string toStringHelper(const T& arg, std::false_type) {
462  std::ostringstream os;
463  os << arg;
464  return os.str();
465 }
466 template <typename T>
467 std::string toString(const T& arg) {
468  return toStringHelper(arg, std::is_integral<T>());
469 }
470 
482 template <typename T>
483 T stringTo(const std::string& s, bool& ok) {
484  std::istringstream is(s);
485  T tmp = T();
486  ok = static_cast<bool>(is >> tmp);
487  std::string rest;
488  is >> std::skipws >> rest;
489  if (!rest.empty())
490  ok = false;
491  return tmp;
492 }
493 
501 template <>
502 bool stringTo<bool>(const std::string& s, bool& ok);
503 
504 } // namespace Exiv2
505 
506 #endif // #ifndef TYPES_HPP_
Exif SHORT type, 16-bit (2-byte) unsigned integer.
Definition: types.hpp:73
Exif SLONG type, a 32-bit (4-byte) signed (twos-complement) integer.
Definition: types.hpp:79
EXIV2API Rational floatToRationalCast(float f)
Very simple conversion of a float to a Rational.
Definition: types.cpp:607
Slice (= view) for STL containers.
Definition: slice.hpp:421
EXIV2API size_t us2Data(byte *buf, uint16_t s, ByteOrder byteOrder)
Convert an unsigned short to data, write the data to the buffer, return number of bytes written...
Definition: types.cpp:331
Exif SRATIONAL type, two SLONGs: numerator and denominator of a fraction.
Definition: types.hpp:80
ByteOrder
Type to express the byte order (little or big endian)
Definition: types.hpp:34
IPTC time type.
Definition: types.hpp:89
bool stringTo< bool >(const std::string &s, bool &ok)
Specialization of stringTo(const std::string& s, bool& ok) for bool.
Definition: types.cpp:513
TypeId
Exiv2 value type identifiers.
Definition: types.hpp:70
EXIV2API size_t f2Data(byte *buf, float f, ByteOrder byteOrder)
Convert a single precision floating point (IEEE 754 binary32) float to data, write the data to the bu...
Definition: types.cpp:410
EXIV2API double getDouble(const byte *buf, ByteOrder byteOrder)
Read an 8 byte double precision floating point value (IEEE 754 binary64) from the data buffer...
Definition: types.cpp:308
EXIV2API int64_t parseInt64(const std::string &s, bool &ok)
Return a int64_t set to the value represented by s.
Definition: types.cpp:530
EXIV2API int16_t getShort(const byte *buf, ByteOrder byteOrder)
Read a 2 byte signed short value from the data buffer.
Definition: types.cpp:276
uint8_t byte
1 byte unsigned integer type.
Definition: types.hpp:26
Invalid type id.
Definition: types.hpp:97
MetadataId
An identifier for each type of metadata.
Definition: types.hpp:47
EXIV2API Rational parseRational(const std::string &s, bool &ok)
Return a Rational set to the value represented by s.
Definition: types.cpp:586
std::string toStringHelper(const T &arg, std::true_type)
Utility function to convert the argument of any type to a string.
Definition: types.hpp:456
Utility class containing a character array. All it does is to take care of memory allocation and dele...
Definition: types.hpp:124
Exif UNDEFINED type, an 8-bit byte that may contain anything.
Definition: types.hpp:77
XMP bag type.
Definition: types.hpp:94
WriteMethod
Type to indicate write method used by TIFF parsers.
Definition: types.hpp:41
Exif LONG type, 32-bit (4-byte) unsigned integer.
Definition: types.hpp:74
const T * find(T(&src)[N], const K &key)
Find an element that matches key in the array src.
Definition: types.hpp:449
TIFF IFD type, 32-bit (4-byte) unsigned integer.
Definition: types.hpp:83
EXIV2API URational getURational(const byte *buf, ByteOrder byteOrder)
Read an 8 byte unsigned rational value from the data buffer.
Definition: types.cpp:270
EXIV2API std::istream & operator>>(std::istream &is, Rational &r)
Input operator for our fake rational.
Definition: types.cpp:234
Exif SBYTE type, an 8-bit signed (twos-complement) integer.
Definition: types.hpp:76
std::pair< int32_t, int32_t > Rational
8 byte signed rational type.
Definition: types.hpp:31
EXIV2API size_t r2Data(byte *buf, Rational l, ByteOrder byteOrder)
Convert a signed rational to data, write the data to the buffer, return number of bytes written...
Definition: types.cpp:404
EXIV2API const char * exvGettext(const char *str)
Translate a string using the gettext framework. This wrapper hides all the implementation details fro...
Definition: types.cpp:504
Exif RATIONAL type, two LONGs: numerator and denominator of a fraction.
Definition: types.hpp:75
EXIV2API int exifTime(const char *buf, tm *tm)
Converts a string in the form "%Y:%m:%d %H:%M:%S", e.g., "2007:05:24 12:31:55" to broken down time fo...
Definition: types.cpp:484
Exif ASCII type, 8-bit byte.
Definition: types.hpp:72
EXIV2API size_t l2Data(byte *buf, int32_t l, ByteOrder byteOrder)
Convert a signed long to data, write the data to the buffer, return number of bytes written...
Definition: types.cpp:389
TIFF DOUBLE type, double precision (8-byte) IEEE format.
Definition: types.hpp:82
TIFF IFD type, 64-bit (8-byte) unsigned integer.
Definition: types.hpp:86
Exif LONG LONG type, 64-bit (8-byte) signed integer.
Definition: types.hpp:85
Exif BYTE type, 8-bit unsigned integer.
Definition: types.hpp:71
Exif SSHORT type, a 16-bit (2-byte) signed (twos-complement) integer.
Definition: types.hpp:78
AccessMode
An identifier for each mode of metadata support.
Definition: types.hpp:57
EXIV2API bool isHex(const std::string &str, size_t size=0, const std::string &prefix="")
Return true if str is a hex number starting with prefix followed by size hex digits, false otherwise. If size is 0, any number of digits is allowed and all are checked.
Definition: types.cpp:475
EXIV2API float parseFloat(const std::string &s, bool &ok)
Return a float set to the value represented by s.
Definition: types.cpp:564
TIFF FLOAT type, single precision (4-byte) IEEE format.
Definition: types.hpp:81
EXIV2API uint32_t parseUint32(const std::string &s, bool &ok)
Return a uint32_t set to the value represented by s.
Definition: types.cpp:556
EXIV2API size_t ur2Data(byte *buf, URational l, ByteOrder byteOrder)
Convert an unsigned rational to data, write the data to the buffer, return number of bytes written...
Definition: types.cpp:372
Slice< T > makeSlice(T &cont, size_t begin, size_t end)
Return a new slice with the given bounds.
Definition: slice.hpp:533
EXIV2API int32_t getLong(const byte *buf, ByteOrder byteOrder)
Read a 4 byte signed long value from the data buffer.
Definition: types.cpp:283
EXIV2API uint32_t getULong(const byte *buf, ByteOrder byteOrder)
Read a 4 byte unsigned long value from the data buffer.
Definition: types.cpp:250
EXIV2API size_t ull2Data(byte *buf, uint64_t l, ByteOrder byteOrder)
Convert an uint64_t to data, write the data to the buffer, return number of bytes written...
Definition: types.cpp:357
XMP text type.
Definition: types.hpp:92
Class CrwImage to access Canon CRW images. References: The Canon RAW (CRW) File Format by Phil Harv...
Definition: asfvideo.hpp:15
T stringTo(const std::string &s, bool &ok)
Utility function to convert a string to a value of type T.
Definition: types.hpp:483
value_type & at(size_t index)
Definition: slice.hpp:174
std::pair< uint32_t, uint32_t > URational
8 byte unsigned rational type.
Definition: types.hpp:29
EXIV2API std::ostream & operator<<(std::ostream &os, const DataSet &dataSet)
Output operator for dataSet.
Definition: datasets.cpp:590
XMP sequence type.
Definition: types.hpp:95
EXIV2API size_t d2Data(byte *buf, double d, ByteOrder byteOrder)
Convert a double precision floating point (IEEE 754 binary64) double to data, write the data to the b...
Definition: types.cpp:422
Exiv2 type for the Exif user comment.
Definition: types.hpp:90
EXIV2API uint64_t getULongLong(const byte *buf, ByteOrder byteOrder)
Read a 8 byte unsigned long value from the data buffer.
Definition: types.cpp:257
IPTC date type.
Definition: types.hpp:88
EXIV2API size_t s2Data(byte *buf, int16_t s, ByteOrder byteOrder)
Convert a signed short to data, write the data to the buffer, return number of bytes written...
Definition: types.cpp:378
XMP language alternative type.
Definition: types.hpp:96
std::vector< byte > Blob
Container for binary data.
Definition: types.hpp:102
EXIV2API Rational getRational(const byte *buf, ByteOrder byteOrder)
Read an 8 byte signed rational value from the data buffer.
Definition: types.cpp:290
Type information lookup functions. Implemented as a static class.
Definition: types.hpp:108
Exiv2 type for a CIFF directory.
Definition: types.hpp:91
Exif LONG LONG type, 64-bit (8-byte) unsigned integer.
Definition: types.hpp:84
XMP alternative type.
Definition: types.hpp:93
EXIV2API size_t ul2Data(byte *buf, uint32_t l, ByteOrder byteOrder)
Convert an unsigned long to data, write the data to the buffer, return number of bytes written...
Definition: types.cpp:342
Last type id.
Definition: types.hpp:98
EXIV2API float getFloat(const byte *buf, ByteOrder byteOrder)
Read a 4 byte single precision floating point value (IEEE 754 binary32) from the data buffer...
Definition: types.cpp:296
EXIV2API uint16_t getUShort(const byte *buf, ByteOrder byteOrder)
Read a 2 byte unsigned short value from the data buffer.
Definition: types.cpp:246
EXIV2API void hexdump(std::ostream &os, const byte *buf, size_t len, size_t offset=0)
Print len bytes from buf in hex and ASCII format to the given stream, prefixed with the position in t...
Definition: types.cpp:454