/src/exiv2/include/exiv2/exif.hpp
Line | Count | Source |
1 | | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | | |
3 | | /*! |
4 | | @file exif.hpp |
5 | | @brief Encoding and decoding of Exif data |
6 | | @author Andreas Huggel (ahu) |
7 | | <a href="mailto:ahuggel@gmx.net">ahuggel@gmx.net</a> |
8 | | @date 09-Jan-04, ahu: created |
9 | | */ |
10 | | #ifndef EXIV2_EXIF_HPP |
11 | | #define EXIV2_EXIF_HPP |
12 | | |
13 | | // ***************************************************************************** |
14 | | #include "exiv2lib_export.h" |
15 | | |
16 | | // included header files |
17 | | #include "config.h" |
18 | | #include "metadatum.hpp" |
19 | | |
20 | | // + standard includes |
21 | | #include <list> |
22 | | |
23 | | // ***************************************************************************** |
24 | | // namespace extensions |
25 | | /*! |
26 | | @brief Provides classes and functions to encode and decode Exif and Iptc data. |
27 | | The <b>libexiv2</b> API consists of the objects of this namespace. |
28 | | */ |
29 | | namespace Exiv2 { |
30 | | // ***************************************************************************** |
31 | | // class declarations |
32 | | class ExifData; |
33 | | class ExifKey; |
34 | | enum class IfdId : uint32_t; |
35 | | |
36 | | // ***************************************************************************** |
37 | | // class definitions |
38 | | |
39 | | /*! |
40 | | @brief An Exif metadatum, consisting of an ExifKey and a Value and |
41 | | methods to manipulate these. |
42 | | */ |
43 | | class EXIV2API Exifdatum : public Metadatum { |
44 | | template <typename T> |
45 | | friend Exifdatum& setValue(Exifdatum&, const T&); |
46 | | |
47 | | public: |
48 | | //! @name Creators |
49 | | //@{ |
50 | | /*! |
51 | | @brief Constructor for new tags created by an application. The |
52 | | %Exifdatum is created from a \em key / value pair. %Exifdatum copies |
53 | | (clones) the \em key and value if one is provided. Alternatively, |
54 | | a program can create an 'empty' %Exifdatum with only a key |
55 | | and set the value using setValue(). |
56 | | |
57 | | @param key %ExifKey. |
58 | | @param pValue Pointer to an %Exifdatum value. |
59 | | @throw Error if the key cannot be parsed and converted. |
60 | | */ |
61 | | explicit Exifdatum(const ExifKey& key, const Value* pValue = nullptr); |
62 | | //! Copy constructor |
63 | | Exifdatum(const Exifdatum& rhs); |
64 | | //! Destructor |
65 | | ~Exifdatum() override; |
66 | | //@} |
67 | | |
68 | | //! @name Manipulators |
69 | | //@{ |
70 | | //! Assignment operator |
71 | | Exifdatum& operator=(const Exifdatum& rhs); |
72 | | /*! |
73 | | @brief Assign \em value to the %Exifdatum. The type of the new Value |
74 | | is set to UShortValue. |
75 | | */ |
76 | | Exifdatum& operator=(const uint16_t& value); |
77 | | /*! |
78 | | @brief Assign \em value to the %Exifdatum. The type of the new Value |
79 | | is set to ULongValue. |
80 | | */ |
81 | | Exifdatum& operator=(const uint32_t& value); |
82 | | /*! |
83 | | @brief Assign \em value to the %Exifdatum. The type of the new Value |
84 | | is set to URationalValue. |
85 | | */ |
86 | | Exifdatum& operator=(const URational& value); |
87 | | /*! |
88 | | @brief Assign \em value to the %Exifdatum. The type of the new Value |
89 | | is set to ShortValue. |
90 | | */ |
91 | | Exifdatum& operator=(const int16_t& value); |
92 | | /*! |
93 | | @brief Assign \em value to the %Exifdatum. The type of the new Value |
94 | | is set to LongValue. |
95 | | */ |
96 | | Exifdatum& operator=(const int32_t& value); |
97 | | /*! |
98 | | @brief Assign \em value to the %Exifdatum. The type of the new Value |
99 | | is set to RationalValue. |
100 | | */ |
101 | | Exifdatum& operator=(const Rational& value); |
102 | | /*! |
103 | | @brief Assign \em value to the %Exifdatum. |
104 | | Calls setValue(const std::string&). |
105 | | */ |
106 | | Exifdatum& operator=(const std::string& value); |
107 | | /*! |
108 | | @brief Assign \em value to the %Exifdatum. |
109 | | Calls setValue(const Value*). |
110 | | */ |
111 | | Exifdatum& operator=(const Value& value); |
112 | | void setValue(const Value* pValue) override; |
113 | | /*! |
114 | | @brief Set the value to the string \em value. Uses Value::read(const |
115 | | std::string&). If the %Exifdatum does not have a Value yet, |
116 | | then a %Value of the correct type for this %Exifdatum is |
117 | | created. An AsciiValue is created for unknown tags. Return |
118 | | 0 if the value was read successfully. |
119 | | */ |
120 | | int setValue(const std::string& value) override; |
121 | | /*! |
122 | | @brief Set the data area by copying (cloning) the buffer pointed to |
123 | | by \em buf. |
124 | | |
125 | | Values may have a data area, which can contain additional |
126 | | information besides the actual value. This method is used to set such |
127 | | a data area. |
128 | | |
129 | | @param buf Pointer to the source data area |
130 | | @param len Size of the data area |
131 | | @return Return -1 if the %Exifdatum does not have a value yet or the |
132 | | value has no data area, else 0. |
133 | | */ |
134 | | int setDataArea(const byte* buf, size_t len) const; |
135 | | //@} |
136 | | |
137 | | //! @name Accessors |
138 | | //@{ |
139 | | //! Return the key of the %Exifdatum. |
140 | | [[nodiscard]] std::string key() const override; |
141 | | [[nodiscard]] const char* familyName() const override; |
142 | | [[nodiscard]] std::string groupName() const override; |
143 | | [[nodiscard]] std::string tagName() const override; |
144 | | [[nodiscard]] std::string tagLabel() const override; |
145 | | [[nodiscard]] std::string tagDesc() const override; |
146 | | [[nodiscard]] uint16_t tag() const override; |
147 | | //! Return the IFD id as an integer. (Do not use, this is meant for library internal use.) |
148 | | [[nodiscard]] IfdId ifdId() const; |
149 | | //! Return the name of the IFD |
150 | | [[nodiscard]] const char* ifdName() const; |
151 | | //! Return the index (unique id of this key within the original IFD) |
152 | | [[nodiscard]] int idx() const; |
153 | | /*! |
154 | | @brief Write value to a data buffer and return the number |
155 | | of bytes written. |
156 | | |
157 | | The user must ensure that the buffer has enough memory. Otherwise |
158 | | the call results in undefined behaviour. |
159 | | |
160 | | @param buf Data buffer to write to. |
161 | | @param byteOrder Applicable byte order (little or big endian). |
162 | | @return Number of characters written. |
163 | | */ |
164 | | size_t copy(byte* buf, ByteOrder byteOrder) const override; |
165 | | std::ostream& write(std::ostream& os, const ExifData* pMetadata = nullptr) const override; |
166 | | //! Return the type id of the value |
167 | | [[nodiscard]] TypeId typeId() const override; |
168 | | //! Return the name of the type |
169 | | [[nodiscard]] const char* typeName() const override; |
170 | | //! Return the size in bytes of one component of this type |
171 | | [[nodiscard]] size_t typeSize() const override; |
172 | | //! Return the number of components in the value |
173 | | [[nodiscard]] size_t count() const override; |
174 | | //! Return the size of the value in bytes |
175 | | [[nodiscard]] size_t size() const override; |
176 | | //! Return the value as a string. |
177 | | [[nodiscard]] std::string toString() const override; |
178 | | [[nodiscard]] std::string toString(size_t n) const override; |
179 | | [[nodiscard]] int64_t toInt64(size_t n = 0) const override; |
180 | | [[nodiscard]] float toFloat(size_t n = 0) const override; |
181 | | [[nodiscard]] Rational toRational(size_t n = 0) const override; |
182 | | [[nodiscard]] std::unique_ptr<Value> getValue() const override; |
183 | | [[nodiscard]] const Value& value() const override; |
184 | | //! Return the size of the data area. |
185 | | [[nodiscard]] size_t sizeDataArea() const; |
186 | | /*! |
187 | | @brief Return a copy of the data area of the value. The caller owns |
188 | | this copy and %DataBuf ensures that it will be deleted. |
189 | | |
190 | | Values may have a data area, which can contain additional |
191 | | information besides the actual value. This method is used to access |
192 | | such a data area. |
193 | | |
194 | | @return A %DataBuf containing a copy of the data area or an empty |
195 | | %DataBuf if the value does not have a data area assigned or the |
196 | | value is not set. |
197 | | */ |
198 | | [[nodiscard]] DataBuf dataArea() const; |
199 | | //@} |
200 | | |
201 | | private: |
202 | | // DATA |
203 | | std::unique_ptr<ExifKey> key_; //!< Key |
204 | | std::unique_ptr<Value> value_; //!< Value |
205 | | |
206 | | }; // class Exifdatum |
207 | | |
208 | | /*! |
209 | | @brief Access to a Exif %thumbnail image. This class provides higher level |
210 | | accessors to the thumbnail image that is optionally embedded in IFD1 |
211 | | of the Exif data. These methods do not write to the Exif metadata. |
212 | | Manipulators are provided in subclass ExifThumb. |
213 | | |
214 | | @note Various other preview and thumbnail images may be contained in an |
215 | | image, depending on its format and the camera make and model. This |
216 | | class only provides access to the Exif thumbnail as specified in the |
217 | | Exif standard. |
218 | | */ |
219 | | class EXIV2API ExifThumbC { |
220 | | public: |
221 | | //! @name Creators |
222 | | //@{ |
223 | | //! Constructor. |
224 | | explicit ExifThumbC(const ExifData& exifData); |
225 | | //@} |
226 | | |
227 | | //! @name Accessors |
228 | | //@{ |
229 | | /*! |
230 | | @brief Return the thumbnail image in a %DataBuf. The caller owns the |
231 | | data buffer and %DataBuf ensures that it will be deleted. |
232 | | */ |
233 | | [[nodiscard]] DataBuf copy() const; |
234 | | #ifdef EXV_ENABLE_FILESYSTEM |
235 | | /*! |
236 | | @brief Write the thumbnail image to a file. |
237 | | |
238 | | A filename extension is appended to \em path according to the image |
239 | | type of the thumbnail, so \em path should not include an extension. |
240 | | The function will overwrite an existing file of the same name. |
241 | | |
242 | | @param path File name of the thumbnail without extension. |
243 | | @return The number of bytes written. |
244 | | */ |
245 | | [[nodiscard]] size_t writeFile(const std::string& path) const; |
246 | | #endif |
247 | | /*! |
248 | | @brief Return the MIME type of the thumbnail, either \c "image/tiff" |
249 | | or \c "image/jpeg". |
250 | | */ |
251 | | [[nodiscard]] const char* mimeType() const; |
252 | | /*! |
253 | | @brief Return the file extension for the format of the thumbnail |
254 | | (".tif" or ".jpg"). |
255 | | */ |
256 | | [[nodiscard]] const char* extension() const; |
257 | | //@} |
258 | | |
259 | | private: |
260 | | // DATA |
261 | | const ExifData& exifData_; //!< Const reference to the Exif metadata. |
262 | | |
263 | | }; // class ExifThumb |
264 | | |
265 | | /*! |
266 | | @brief Access and modify an Exif %thumbnail image. This class implements |
267 | | manipulators to set and erase the thumbnail image that is optionally |
268 | | embedded in IFD1 of the Exif data. Accessors are provided by the |
269 | | base class, ExifThumbC. |
270 | | |
271 | | @note Various other preview and thumbnail images may be contained in an |
272 | | image, depending on its format and the camera make and model. This |
273 | | class only provides access to the Exif thumbnail as specified in the |
274 | | Exif standard. |
275 | | */ |
276 | | class EXIV2API ExifThumb : public ExifThumbC { |
277 | | public: |
278 | | //! @name Creators |
279 | | //@{ |
280 | | //! Constructor. |
281 | | explicit ExifThumb(ExifData& exifData); |
282 | | //@} |
283 | | |
284 | | //! @name Manipulators |
285 | | //@{ |
286 | | #ifdef EXV_ENABLE_FILESYSTEM |
287 | | /*! |
288 | | @brief Set the Exif thumbnail to the JPEG image \em path. Set |
289 | | XResolution, YResolution and ResolutionUnit to \em xres, |
290 | | \em yres and \em unit, respectively. |
291 | | |
292 | | This results in the minimal thumbnail tags being set for a JPEG |
293 | | thumbnail, as mandated by the Exif standard. |
294 | | |
295 | | @throw Error if reading the file fails. |
296 | | |
297 | | @note No checks on the file format or size are performed. |
298 | | @note Additional existing Exif thumbnail tags are not modified. |
299 | | @note The JPEG image inserted as thumbnail image should not |
300 | | itself contain Exif data (or other metadata), as existing |
301 | | applications may have problems with that. (The preview |
302 | | application that comes with OS X for one.) - David Harvey. |
303 | | */ |
304 | | void setJpegThumbnail(const std::string& path, URational xres, URational yres, uint16_t unit); |
305 | | #endif |
306 | | /*! |
307 | | @brief Set the Exif thumbnail to the JPEG image pointed to by \em buf, |
308 | | and size \em size. Set XResolution, YResolution and |
309 | | ResolutionUnit to \em xres, \em yres and \em unit, respectively. |
310 | | |
311 | | This results in the minimal thumbnail tags being set for a JPEG |
312 | | thumbnail, as mandated by the Exif standard. |
313 | | |
314 | | @throw Error if reading the file fails. |
315 | | |
316 | | @note No checks on the image format or size are performed. |
317 | | @note Additional existing Exif thumbnail tags are not modified. |
318 | | @note The JPEG image inserted as thumbnail image should not |
319 | | itself contain Exif data (or other metadata), as existing |
320 | | applications may have problems with that. (The preview |
321 | | application that comes with OS X for one.) - David Harvey. |
322 | | */ |
323 | | void setJpegThumbnail(const byte* buf, size_t size, URational xres, URational yres, uint16_t unit); |
324 | | #ifdef EXV_ENABLE_FILESYSTEM |
325 | | /*! |
326 | | @brief Set the Exif thumbnail to the JPEG image \em path. |
327 | | |
328 | | This sets only the Compression, JPEGInterchangeFormat and |
329 | | JPEGInterchangeFormatLength tags, which is not all the thumbnail |
330 | | Exif information mandatory according to the Exif standard. (But it's |
331 | | enough to work with the thumbnail.) |
332 | | |
333 | | @throw Error if reading the file fails. |
334 | | |
335 | | @note No checks on the file format or size are performed. |
336 | | @note Additional existing Exif thumbnail tags are not modified. |
337 | | */ |
338 | | void setJpegThumbnail(const std::string& path); |
339 | | #endif |
340 | | /*! |
341 | | @brief Set the Exif thumbnail to the JPEG image pointed to by \em buf, |
342 | | and size \em size. |
343 | | |
344 | | This sets only the Compression, JPEGInterchangeFormat and |
345 | | JPEGInterchangeFormatLength tags, which is not all the thumbnail |
346 | | Exif information mandatory according to the Exif standard. (But it's |
347 | | enough to work with the thumbnail.) |
348 | | |
349 | | @note No checks on the image format or size are performed. |
350 | | @note Additional existing Exif thumbnail tags are not modified. |
351 | | */ |
352 | | void setJpegThumbnail(const byte* buf, size_t size); |
353 | | /*! |
354 | | @brief Delete the thumbnail from the Exif data. Removes all |
355 | | Exif.%Thumbnail.*, i.e., Exif IFD1 tags. |
356 | | */ |
357 | | void erase(); |
358 | | //@} |
359 | | |
360 | | private: |
361 | | // DATA |
362 | | ExifData& exifData_; //!< Reference to the related Exif metadata. |
363 | | |
364 | | }; // class ExifThumb |
365 | | |
366 | | //! Container type to hold all metadata |
367 | | using ExifMetadata = std::list<Exifdatum>; |
368 | | |
369 | | /*! |
370 | | @brief A container for Exif data. This is a top-level class of the %Exiv2 |
371 | | library. The container holds Exifdatum objects. |
372 | | |
373 | | Provide high-level access to the Exif data of an image: |
374 | | - read Exif information from JPEG files |
375 | | - access metadata through keys and standard C++ iterators |
376 | | - add, modify and delete metadata |
377 | | - write Exif data to JPEG files |
378 | | - extract Exif metadata to files, insert from these files |
379 | | - extract and delete Exif thumbnail (JPEG and TIFF thumbnails) |
380 | | */ |
381 | | class EXIV2API ExifData { |
382 | | public: |
383 | | //! ExifMetadata iterator type |
384 | | using iterator = ExifMetadata::iterator; |
385 | | //! ExifMetadata const iterator type |
386 | | using const_iterator = ExifMetadata::const_iterator; |
387 | | |
388 | | //! @name Manipulators |
389 | | //@{ |
390 | | /*! |
391 | | @brief Returns a reference to the %Exifdatum that is associated with a |
392 | | particular \em key. If %ExifData does not already contain such |
393 | | an %Exifdatum, operator[] adds object \em Exifdatum(key). |
394 | | |
395 | | @note Since operator[] might insert a new element, it can't be a const |
396 | | member function. |
397 | | */ |
398 | | Exifdatum& operator[](const std::string& key); |
399 | | /*! |
400 | | @brief Add an Exifdatum from the supplied key and value pair. This |
401 | | method copies (clones) key and value. No duplicate checks are |
402 | | performed, i.e., it is possible to add multiple metadata with |
403 | | the same key. |
404 | | */ |
405 | | void add(const ExifKey& key, const Value* pValue); |
406 | | /*! |
407 | | @brief Add a copy of the \em exifdatum to the Exif metadata. No |
408 | | duplicate checks are performed, i.e., it is possible to add |
409 | | multiple metadata with the same key. |
410 | | |
411 | | @throw Error if the makernote cannot be created |
412 | | */ |
413 | | void add(const Exifdatum& exifdatum); |
414 | | /*! |
415 | | @brief Delete the Exifdatum at iterator position \em pos, return the |
416 | | position of the next exifdatum. Note that iterators into |
417 | | the metadata, including \em pos, are potentially invalidated |
418 | | by this call. |
419 | | */ |
420 | | iterator erase(iterator pos); |
421 | | /*! |
422 | | @brief Remove all elements of the range \em beg, \em end, return the |
423 | | position of the next element. Note that iterators into |
424 | | the metadata are potentially invalidated by this call. |
425 | | */ |
426 | | iterator erase(iterator beg, iterator end); |
427 | | /*! |
428 | | @brief Delete all Exifdatum instances resulting in an empty container. |
429 | | Note that this also removes thumbnails. |
430 | | */ |
431 | | void clear(); |
432 | | //! Sort metadata by key |
433 | | void sortByKey(); |
434 | | //! Sort metadata by tag |
435 | | void sortByTag(); |
436 | | //! Begin of the metadata |
437 | 5.46k | iterator begin() { |
438 | 5.46k | return exifMetadata_.begin(); |
439 | 5.46k | } |
440 | | //! End of the metadata |
441 | 405k | iterator end() { |
442 | 405k | return exifMetadata_.end(); |
443 | 405k | } |
444 | | /*! |
445 | | @brief Find the first Exifdatum with the given \em key, return an |
446 | | iterator to it. |
447 | | */ |
448 | | iterator findKey(const ExifKey& key); |
449 | | //@} |
450 | | |
451 | | //! @name Accessors |
452 | | //@{ |
453 | | //! Begin of the metadata |
454 | 2.73k | [[nodiscard]] const_iterator begin() const { |
455 | 2.73k | return exifMetadata_.begin(); |
456 | 2.73k | } |
457 | | //! End of the metadata |
458 | 96.1k | [[nodiscard]] const_iterator end() const { |
459 | 96.1k | return exifMetadata_.end(); |
460 | 96.1k | } |
461 | | /*! |
462 | | @brief Find the first Exifdatum with the given \em key, return a const |
463 | | iterator to it. |
464 | | */ |
465 | | [[nodiscard]] const_iterator findKey(const ExifKey& key) const; |
466 | | //! Return true if there is no Exif metadata |
467 | 36 | [[nodiscard]] bool empty() const { |
468 | 36 | return exifMetadata_.empty(); |
469 | 36 | } |
470 | | //! Get the number of metadata entries |
471 | 0 | [[nodiscard]] size_t count() const { |
472 | 0 | return exifMetadata_.size(); |
473 | 0 | } |
474 | | //@} |
475 | | |
476 | | private: |
477 | | // DATA |
478 | | ExifMetadata exifMetadata_; |
479 | | }; // class ExifData |
480 | | |
481 | | /*! |
482 | | @brief Stateless parser class for Exif data. Images use this class to |
483 | | decode and encode binary Exif data. |
484 | | |
485 | | @note Encode is lossy and is not the inverse of decode. |
486 | | */ |
487 | | class EXIV2API ExifParser { |
488 | | public: |
489 | | /*! |
490 | | @brief Decode metadata from a buffer \em pData of length \em size |
491 | | with binary Exif data to the provided metadata container. |
492 | | |
493 | | The buffer must start with a TIFF header. Return byte order |
494 | | in which the data is encoded. |
495 | | |
496 | | @param exifData Exif metadata container. |
497 | | @param pData Pointer to the data buffer. Must point to data in |
498 | | binary Exif format; no checks are performed. |
499 | | @param size Length of the data buffer |
500 | | @return Byte order in which the data is encoded. |
501 | | */ |
502 | | static ByteOrder decode(ExifData& exifData, const byte* pData, size_t size); |
503 | | /*! |
504 | | @brief Encode Exif metadata from the provided metadata to binary Exif |
505 | | format. |
506 | | |
507 | | The original binary Exif data in the memory block \em pData, \em size |
508 | | is parsed and updated in-place if possible ("non-intrusive" |
509 | | writing). If that is not possible (e.g., if new tags were added), the |
510 | | entire Exif structure is re-written to the \em blob ("intrusive" |
511 | | writing). The return value indicates which write method was used. If |
512 | | it is \c wmNonIntrusive, the original memory \em pData, \em size |
513 | | contains the result and \em blob is empty. If the return value is |
514 | | \c wmIntrusive, a new Exif structure was created and returned in |
515 | | \em blob. The memory block \em pData, \em size may be partly updated in |
516 | | this case and should not be used anymore. |
517 | | |
518 | | Encode is a lossy operation. It attempts to fit the Exif data into a |
519 | | binary block suitable as the payload of a JPEG APP1 Exif segment, |
520 | | which can be at most 65527 bytes large. Encode omits IFD0 tags that |
521 | | are "not recorded" in compressed images according to the Exif 2.2 |
522 | | specification. It also doesn't write tags in groups which do not occur |
523 | | in JPEG images. If the resulting binary block is larger than allowed, |
524 | | it further deletes specific large preview tags, unknown tags larger |
525 | | than 4kB and known tags larger than 40kB. The operation succeeds even |
526 | | if the end result is still larger than the allowed size. Application |
527 | | should therefore always check the size of the \em blob. |
528 | | |
529 | | @param blob Container for the binary Exif data if "intrusive" |
530 | | writing is necessary. Empty otherwise. |
531 | | @param pData Pointer to the binary Exif data buffer. Must |
532 | | point to data in Exif format; no checks are |
533 | | performed. Will be modified if "non-intrusive" |
534 | | writing is possible. |
535 | | @param size Length of the data buffer. |
536 | | @param byteOrder Byte order to use. |
537 | | @param exifData Exif metadata container. |
538 | | |
539 | | @return Write method used. |
540 | | */ |
541 | | static WriteMethod encode(Blob& blob, const byte* pData, size_t size, ByteOrder byteOrder, ExifData& exifData); |
542 | | /*! |
543 | | @brief Encode metadata from the provided metadata to Exif format. |
544 | | |
545 | | Encode Exif metadata from the \em ExifData container to binary Exif |
546 | | format in the \em blob, encoded in \em byteOrder. |
547 | | |
548 | | This simpler encode method uses "intrusive" writing, i.e., it builds |
549 | | the binary representation of the metadata from scratch. It does not |
550 | | attempt "non-intrusive", i.e., in-place updating. It's better to use |
551 | | the other encode() method, if the metadata is already available in |
552 | | binary format, in order to allow for "non-intrusive" updating of the |
553 | | existing binary representation. |
554 | | |
555 | | This is just an inline wrapper for |
556 | | ExifParser::encode(blob, 0, 0, byteOrder, exifData). |
557 | | |
558 | | @param blob Container for the binary Exif data. |
559 | | @param byteOrder Byte order to use. |
560 | | @param exifData Exif metadata container. |
561 | | */ |
562 | 0 | static void encode(Blob& blob, ByteOrder byteOrder, ExifData& exifData) { |
563 | 0 | encode(blob, nullptr, 0, byteOrder, exifData); |
564 | 0 | } |
565 | | |
566 | | }; // class ExifParser |
567 | | |
568 | | } // namespace Exiv2 |
569 | | |
570 | | #endif // EXIV2_EXIF_HPP |