Coverage Report

Created: 2026-10-14 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/exiv2/include/exiv2/iptc.hpp
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
3
/*!
4
  @file    iptc.hpp
5
  @brief   Encoding and decoding of IPTC data
6
 */
7
#ifndef EXIV2_IPTC_HPP
8
#define EXIV2_IPTC_HPP
9
10
// *****************************************************************************
11
#include "exiv2lib_export.h"
12
13
// included header files
14
#include "datasets.hpp"
15
#include "metadatum.hpp"
16
17
// *****************************************************************************
18
// namespace extensions
19
namespace Exiv2 {
20
// *****************************************************************************
21
// class declarations
22
class ExifData;
23
24
// *****************************************************************************
25
// class definitions
26
27
/*!
28
  @brief An IPTC metadatum ("dataset"), consisting of an IptcKey and a
29
         Value and methods to manipulate these.
30
31
         This is referred in the standard as a property.
32
 */
33
class EXIV2API Iptcdatum : public Metadatum {
34
 public:
35
  //! @name Creators
36
  //@{
37
  /*!
38
    @brief Constructor for new tags created by an application. The
39
           %Iptcdatum is created from a key / value pair. %Iptcdatum
40
           copies (clones) the value if one is provided. Alternatively, a
41
           program can create an 'empty' %Iptcdatum with only a key and
42
           set the value using setValue().
43
44
    @param key The key of the %Iptcdatum.
45
    @param pValue Pointer to a %Iptcdatum value.
46
    @throw Error if the key cannot be parsed and converted
47
           to a tag number and record id.
48
   */
49
  explicit Iptcdatum(const IptcKey& key, const Value* pValue = nullptr);
50
  //! Copy constructor
51
  Iptcdatum(const Iptcdatum& rhs);
52
  //! Destructor
53
  ~Iptcdatum() override;
54
  //@}
55
56
  //! @name Manipulators
57
  //@{
58
  //! Assignment operator
59
  Iptcdatum& operator=(const Iptcdatum& rhs);
60
  /*!
61
    @brief Assign \em value to the %Iptcdatum. The type of the new Value
62
           is set to UShortValue.
63
   */
64
  Iptcdatum& operator=(const uint16_t& value);
65
  /*!
66
    @brief Assign \em value to the %Iptcdatum.
67
           Calls setValue(const std::string&).
68
   */
69
  Iptcdatum& operator=(const std::string& value);
70
  /*!
71
    @brief Assign \em value to the %Iptcdatum.
72
           Calls setValue(const Value*).
73
   */
74
  Iptcdatum& operator=(const Value& value);
75
  void setValue(const Value* pValue) override;
76
  /*!
77
    @brief Set the value to the string \em value, using
78
           Value::read(const std::string&).
79
           If the %Iptcdatum does not have a Value yet, then a %Value of
80
           the correct type for this %Iptcdatum is created. If that
81
           fails (because of an unknown dataset), a StringValue is
82
           created. Return 0 if the value was read successfully.
83
   */
84
  int setValue(const std::string& value) override;
85
  //@}
86
87
  //! @name Accessors
88
  //@{
89
  size_t copy(byte* buf, ByteOrder byteOrder) const override;
90
  std::ostream& write(std::ostream& os, const ExifData* pMetadata = nullptr) const override;
91
  /*!
92
    @brief Return the key of the Iptcdatum. The key is of the form
93
           '<b>Iptc</b>.recordName.datasetName'. Note however that the key
94
           is not necessarily unique, i.e., an IptcData object may contain
95
           multiple metadata with the same key.
96
   */
97
  [[nodiscard]] std::string key() const override;
98
  /*!
99
     @brief Return the name of the record
100
     @return record name
101
     @deprecated This function is deprecated.
102
   */
103
  [[deprecated]] [[nodiscard]] std::string recordName() const;
104
  /*!
105
     @brief Return the record id
106
     @return record id
107
   */
108
  [[nodiscard]] uint16_t record() const;
109
  [[nodiscard]] const char* familyName() const override;
110
  [[nodiscard]] std::string groupName() const override;
111
  /*!
112
     @brief Return the name of the tag (aka dataset)
113
     @return tag name
114
   */
115
  [[nodiscard]] std::string tagName() const override;
116
  [[nodiscard]] std::string tagLabel() const override;
117
  [[nodiscard]] std::string tagDesc() const override;
118
  //! Return the tag (aka dataset) number
119
  [[nodiscard]] uint16_t tag() const override;
120
  [[nodiscard]] TypeId typeId() const override;
121
  [[nodiscard]] const char* typeName() const override;
122
  [[nodiscard]] size_t typeSize() const override;
123
  [[nodiscard]] size_t count() const override;
124
  [[nodiscard]] size_t size() const override;
125
  [[nodiscard]] std::string toString() const override;
126
  [[nodiscard]] std::string toString(size_t n) const override;
127
  [[nodiscard]] int64_t toInt64(size_t n = 0) const override;
128
  [[nodiscard]] float toFloat(size_t n = 0) const override;
129
  [[nodiscard]] Rational toRational(size_t n = 0) const override;
130
  [[nodiscard]] std::unique_ptr<Value> getValue() const override;
131
  [[nodiscard]] const Value& value() const override;
132
  //@}
133
134
 private:
135
  // DATA
136
  IptcKey::UniquePtr key_;        //!< Key
137
  std::unique_ptr<Value> value_;  //!< Value
138
139
};  // class Iptcdatum
140
141
//! Container type to hold all metadata
142
using IptcMetadata = std::vector<Iptcdatum>;
143
144
/*!
145
  @brief A container for IPTC data. This is a top-level class of the %Exiv2 library.
146
147
  Provide high-level access to the IPTC data of an image:
148
  - read IPTC information from JPEG files
149
  - access metadata through keys and standard C++ iterators
150
  - add, modify and delete metadata
151
  - write IPTC data to JPEG files
152
  - extract IPTC metadata to files, insert from these files
153
*/
154
class EXIV2API IptcData {
155
 public:
156
  //! IptcMetadata iterator type
157
  using iterator = IptcMetadata::iterator;
158
  //! IptcMetadata const iterator type
159
  using const_iterator = IptcMetadata::const_iterator;
160
161
  // Use the compiler generated constructors and assignment operator
162
163
  //! @name Manipulators
164
  //@{
165
  /*!
166
    @brief Returns a reference to the %Iptcdatum that is associated with a
167
           particular \em key. If %IptcData does not already contain such
168
           an %Iptcdatum, operator[] adds object \em Iptcdatum(key).
169
170
    @note  Since operator[] might insert a new element, it can't be a const
171
           member function.
172
   */
173
  Iptcdatum& operator[](const std::string& key);
174
  /*!
175
    @brief Add an %Iptcdatum from the supplied key and value pair. This
176
           method copies (clones) the value. A check for non-repeatable
177
           datasets is performed.
178
    @return 0 if successful;<BR>
179
            6 if the dataset already exists and is not repeatable
180
   */
181
  int add(const IptcKey& key, const Value* value);
182
  /*!
183
    @brief Add a copy of the Iptcdatum to the IPTC metadata. A check
184
           for non-repeatable datasets is performed.
185
    @return 0 if successful;<BR>
186
           6 if the dataset already exists and is not repeatable;<BR>
187
   */
188
  int add(const Iptcdatum& iptcDatum);
189
  /*!
190
    @brief Delete the Iptcdatum at iterator position pos, return the
191
           position of the next Iptcdatum. Note that iterators into
192
           the metadata, including pos, are potentially invalidated
193
           by this call.
194
   */
195
  iterator erase(iterator pos);
196
  /*!
197
    @brief Delete all Iptcdatum instances resulting in an empty container.
198
   */
199
69.0k
  void clear() {
200
69.0k
    iptcMetadata_.clear();
201
69.0k
  }
202
  //! Sort metadata by key
203
  void sortByKey();
204
  //! Sort metadata by tag (aka dataset)
205
  void sortByTag();
206
  //! Begin of the metadata
207
0
  iterator begin() {
208
0
    return iptcMetadata_.begin();
209
0
  }
210
  //! End of the metadata
211
2.00k
  iterator end() {
212
2.00k
    return iptcMetadata_.end();
213
2.00k
  }
214
  /*!
215
    @brief Find the first Iptcdatum with the given key, return an iterator
216
           to it.
217
   */
218
  iterator findKey(const IptcKey& key);
219
  /*!
220
    @brief Find the first Iptcdatum with the given record and dataset it,
221
          return a const iterator to it.
222
   */
223
  iterator findId(uint16_t dataset, uint16_t record = IptcDataSets::application2);
224
  //@}
225
226
  //! @name Accessors
227
  //@{
228
  //! Begin of the metadata
229
0
  [[nodiscard]] const_iterator begin() const {
230
0
    return iptcMetadata_.begin();
231
0
  }
232
  //! End of the metadata
233
0
  [[nodiscard]] const_iterator end() const {
234
0
    return iptcMetadata_.end();
235
0
  }
236
  /*!
237
    @brief Find the first Iptcdatum with the given key, return a const
238
           iterator to it.
239
   */
240
  [[nodiscard]] const_iterator findKey(const IptcKey& key) const;
241
  /*!
242
    @brief Find the first Iptcdatum with the given record and dataset
243
           number, return a const iterator to it.
244
   */
245
  [[nodiscard]] const_iterator findId(uint16_t dataset, uint16_t record = IptcDataSets::application2) const;
246
  //! Return true if there is no IPTC metadata
247
21.3k
  [[nodiscard]] bool empty() const {
248
21.3k
    return iptcMetadata_.empty();
249
21.3k
  }
250
251
  //! Get the number of metadata entries
252
0
  [[nodiscard]] size_t count() const {
253
0
    return iptcMetadata_.size();
254
0
  }
255
256
  //! @brief Return the exact size of all contained IPTC metadata
257
  [[nodiscard]] size_t size() const;
258
259
  //! @brief Return the metadata charset name or 0
260
  [[nodiscard]] const char* detectCharset() const;
261
262
  //!  @brief dump iptc formatted binary data (used by printStructure kpsRecursive)
263
  static void printStructure(std::ostream& out, const Slice<byte*>& bytes, size_t depth);
264
  //@}
265
266
 private:
267
  // DATA
268
  IptcMetadata iptcMetadata_;
269
};  // class IptcData
270
271
/*!
272
  @brief Stateless parser class for IPTC data. Images use this class to
273
         decode and encode binary IPTC data.
274
 */
275
class EXIV2API IptcParser {
276
 public:
277
  /*!
278
    @brief Decode binary IPTC data in IPTC IIM4 format from a buffer \em pData
279
           of length \em size to the provided metadata container.
280
281
    @param iptcData Metadata container to add the decoded IPTC datasets to.
282
    @param pData    Pointer to the data buffer to read from.
283
    @param size     Number of bytes in the data buffer.
284
285
    @return 0 if successful;<BR>
286
            5 if the binary IPTC data is invalid or corrupt
287
   */
288
  static int decode(IptcData& iptcData, const byte* pData, size_t size);
289
290
  /*!
291
    @brief Encode the IPTC datasets from \em iptcData to a binary representation in IPTC IIM4 format.
292
293
    Convert the IPTC datasets to binary format and return it.  Caller owns
294
    the returned buffer. The copied data follows the IPTC IIM4 standard.
295
296
    @return Data buffer containing the binary IPTC data in IPTC IIM4 format.
297
   */
298
  static DataBuf encode(const IptcData& iptcData);
299
300
 private:
301
  // Constant data
302
  static constexpr byte marker_ = 0x1C;  // Dataset marker
303
304
};  // class IptcParser
305
306
}  // namespace Exiv2
307
308
#endif  // EXIV2_IPTC_HPP