1b8bc0d8aSopenharmony_ci/* exif.hxx
2b8bc0d8aSopenharmony_ci *
3b8bc0d8aSopenharmony_ci * Copyright  2002,2003 Hans Meine <hans_meine@gmx.net>
4b8bc0d8aSopenharmony_ci *
5b8bc0d8aSopenharmony_ci * This library is free software; you can redistribute it and/or
6b8bc0d8aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
7b8bc0d8aSopenharmony_ci * License as published by the Free Software Foundation; either
8b8bc0d8aSopenharmony_ci * version 2 of the License, or (at your option) any later version.
9b8bc0d8aSopenharmony_ci *
10b8bc0d8aSopenharmony_ci * This library is distributed in the hope that it will be useful,
11b8bc0d8aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
12b8bc0d8aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13b8bc0d8aSopenharmony_ci * Lesser General Public License for more details.
14b8bc0d8aSopenharmony_ci *
15b8bc0d8aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
16b8bc0d8aSopenharmony_ci * License along with this library; if not, write to the
17b8bc0d8aSopenharmony_ci * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18b8bc0d8aSopenharmony_ci * Boston, MA  02110-1301  USA.
19b8bc0d8aSopenharmony_ci */
20b8bc0d8aSopenharmony_ci
21b8bc0d8aSopenharmony_ci#ifndef EXIF_HXX
22b8bc0d8aSopenharmony_ci#define EXIF_HXX
23b8bc0d8aSopenharmony_ci
24b8bc0d8aSopenharmony_ci#include <libexif/exif-entry.h>
25b8bc0d8aSopenharmony_ci#include <libexif/exif-content.h>
26b8bc0d8aSopenharmony_ci#include <libexif/exif-ifd.h>
27b8bc0d8aSopenharmony_ci#include <libexif/exif-data.h>
28b8bc0d8aSopenharmony_ci#include <libexif/exif-format.h>
29b8bc0d8aSopenharmony_ci#include <libexif/exif-utils.h>
30b8bc0d8aSopenharmony_ci#include <stdexcept>
31b8bc0d8aSopenharmony_ci#include <string>
32b8bc0d8aSopenharmony_ci
33b8bc0d8aSopenharmony_cinamespace Exif {
34b8bc0d8aSopenharmony_ci
35b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
36b8bc0d8aSopenharmony_cistruct InvalidIndex : std::runtime_error
37b8bc0d8aSopenharmony_ci{
38b8bc0d8aSopenharmony_ci    InvalidIndex(const std::string& s)
39b8bc0d8aSopenharmony_ci    : std::runtime_error(s) {}
40b8bc0d8aSopenharmony_ci};
41b8bc0d8aSopenharmony_ci
42b8bc0d8aSopenharmony_cistruct InvalidFormat : std::runtime_error
43b8bc0d8aSopenharmony_ci{
44b8bc0d8aSopenharmony_ci    InvalidFormat(const std::string& s)
45b8bc0d8aSopenharmony_ci    : std::runtime_error(s) {}
46b8bc0d8aSopenharmony_ci};
47b8bc0d8aSopenharmony_ci
48b8bc0d8aSopenharmony_cistruct IOError : std::runtime_error
49b8bc0d8aSopenharmony_ci{
50b8bc0d8aSopenharmony_ci    IOError(const std::string& s)
51b8bc0d8aSopenharmony_ci    : std::runtime_error(s) {}
52b8bc0d8aSopenharmony_ci};
53b8bc0d8aSopenharmony_ci#endif // EXIF_NO_EXCEPTIONS
54b8bc0d8aSopenharmony_ci
55b8bc0d8aSopenharmony_cistruct Entry
56b8bc0d8aSopenharmony_ci{
57b8bc0d8aSopenharmony_ci    ExifEntry *entry_;
58b8bc0d8aSopenharmony_ci
59b8bc0d8aSopenharmony_ci        // construct an empty entry, FIXME: is this needed in the public API?
60b8bc0d8aSopenharmony_ci    Entry()
61b8bc0d8aSopenharmony_ci    : entry_(exif_entry_new())
62b8bc0d8aSopenharmony_ci    {}
63b8bc0d8aSopenharmony_ci
64b8bc0d8aSopenharmony_ci        // construct an entry for the given tag
65b8bc0d8aSopenharmony_ci    Entry(ExifTag tag)
66b8bc0d8aSopenharmony_ci    : entry_(exif_entry_new())
67b8bc0d8aSopenharmony_ci    {
68b8bc0d8aSopenharmony_ci        exif_entry_initialize(entry_, tag);
69b8bc0d8aSopenharmony_ci    }
70b8bc0d8aSopenharmony_ci
71b8bc0d8aSopenharmony_ci        // copy constructor
72b8bc0d8aSopenharmony_ci    Entry(Entry const &other)
73b8bc0d8aSopenharmony_ci    : entry_(other.entry_)
74b8bc0d8aSopenharmony_ci    {
75b8bc0d8aSopenharmony_ci        exif_entry_ref(entry_);
76b8bc0d8aSopenharmony_ci    }
77b8bc0d8aSopenharmony_ci
78b8bc0d8aSopenharmony_ci        // internal, do not use directly
79b8bc0d8aSopenharmony_ci    Entry(ExifEntry *entry)
80b8bc0d8aSopenharmony_ci    : entry_(entry)
81b8bc0d8aSopenharmony_ci    {
82b8bc0d8aSopenharmony_ci        exif_entry_ref(entry_);
83b8bc0d8aSopenharmony_ci    }
84b8bc0d8aSopenharmony_ci
85b8bc0d8aSopenharmony_ci    ~Entry()
86b8bc0d8aSopenharmony_ci    {
87b8bc0d8aSopenharmony_ci        exif_entry_unref(entry_);
88b8bc0d8aSopenharmony_ci    }
89b8bc0d8aSopenharmony_ci
90b8bc0d8aSopenharmony_ci    Entry &operator=(Entry const &other)
91b8bc0d8aSopenharmony_ci    {
92b8bc0d8aSopenharmony_ci        exif_entry_unref(entry_);
93b8bc0d8aSopenharmony_ci        entry_ = other.entry_;
94b8bc0d8aSopenharmony_ci        exif_entry_ref(entry_);
95b8bc0d8aSopenharmony_ci        return *this;
96b8bc0d8aSopenharmony_ci    }
97b8bc0d8aSopenharmony_ci
98b8bc0d8aSopenharmony_ci    ExifTag tag() const
99b8bc0d8aSopenharmony_ci    {
100b8bc0d8aSopenharmony_ci        return entry_->tag;
101b8bc0d8aSopenharmony_ci    }
102b8bc0d8aSopenharmony_ci
103b8bc0d8aSopenharmony_ci/*
104b8bc0d8aSopenharmony_ci    void setTag(ExifTag tag)
105b8bc0d8aSopenharmony_ci    {
106b8bc0d8aSopenharmony_ci        entry_->tag = tag;
107b8bc0d8aSopenharmony_ci    }
108b8bc0d8aSopenharmony_ci*/
109b8bc0d8aSopenharmony_ci
110b8bc0d8aSopenharmony_ci    ExifFormat format() const
111b8bc0d8aSopenharmony_ci    {
112b8bc0d8aSopenharmony_ci        return entry_->format;
113b8bc0d8aSopenharmony_ci    }
114b8bc0d8aSopenharmony_ci
115b8bc0d8aSopenharmony_ci/*
116b8bc0d8aSopenharmony_ci    void setFormat(ExifFormat format)
117b8bc0d8aSopenharmony_ci    {
118b8bc0d8aSopenharmony_ci        entry_->format = format;
119b8bc0d8aSopenharmony_ci    }
120b8bc0d8aSopenharmony_ci*/
121b8bc0d8aSopenharmony_ci
122b8bc0d8aSopenharmony_ci    unsigned long components() const
123b8bc0d8aSopenharmony_ci    {
124b8bc0d8aSopenharmony_ci        return entry_->components;
125b8bc0d8aSopenharmony_ci    }
126b8bc0d8aSopenharmony_ci
127b8bc0d8aSopenharmony_ci/*
128b8bc0d8aSopenharmony_ci    void setComponents(unsigned long components)
129b8bc0d8aSopenharmony_ci    {
130b8bc0d8aSopenharmony_ci        entry_->components = components;
131b8bc0d8aSopenharmony_ci    }
132b8bc0d8aSopenharmony_ci
133b8bc0d8aSopenharmony_ci    void initialize(ExifTag tag)
134b8bc0d8aSopenharmony_ci    {
135b8bc0d8aSopenharmony_ci        exif_entry_initialize(entry_, tag);
136b8bc0d8aSopenharmony_ci    }
137b8bc0d8aSopenharmony_ci*/
138b8bc0d8aSopenharmony_ci
139b8bc0d8aSopenharmony_ci    ExifByte getByte(unsigned int index) const
140b8bc0d8aSopenharmony_ci    {
141b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
142b8bc0d8aSopenharmony_ci        if(entry_->format != EXIF_FORMAT_BYTE)
143b8bc0d8aSopenharmony_ci            throw InvalidFormat(
144b8bc0d8aSopenharmony_ci                "Exif::Entry::getByte(): Format is not EXIF_FORMAT_BYTE");
145b8bc0d8aSopenharmony_ci        if(index >= components())
146b8bc0d8aSopenharmony_ci            throw InvalidIndex(
147b8bc0d8aSopenharmony_ci                "Exif::getByte: component index out of range");
148b8bc0d8aSopenharmony_ci#endif
149b8bc0d8aSopenharmony_ci        return *(entry_->data
150b8bc0d8aSopenharmony_ci                 + index * exif_format_get_size(entry_->format));
151b8bc0d8aSopenharmony_ci    }
152b8bc0d8aSopenharmony_ci
153b8bc0d8aSopenharmony_ci    const ExifAscii getAscii() const
154b8bc0d8aSopenharmony_ci    {
155b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
156b8bc0d8aSopenharmony_ci        if(entry_->format != EXIF_FORMAT_ASCII)
157b8bc0d8aSopenharmony_ci            throw InvalidFormat(
158b8bc0d8aSopenharmony_ci                "Exif::Entry::getAscii(): Format is not EXIF_FORMAT_ASCII");
159b8bc0d8aSopenharmony_ci#endif
160b8bc0d8aSopenharmony_ci        return (ExifAscii)entry_->data;
161b8bc0d8aSopenharmony_ci    }
162b8bc0d8aSopenharmony_ci
163b8bc0d8aSopenharmony_ci    ExifShort getShort(unsigned int index) const
164b8bc0d8aSopenharmony_ci    {
165b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
166b8bc0d8aSopenharmony_ci        if(entry_->format != EXIF_FORMAT_SHORT)
167b8bc0d8aSopenharmony_ci            throw InvalidFormat(
168b8bc0d8aSopenharmony_ci                "Exif::Entry::getShort(): Format is not EXIF_FORMAT_SHORT");
169b8bc0d8aSopenharmony_ci        if(index >= components())
170b8bc0d8aSopenharmony_ci            throw InvalidIndex(
171b8bc0d8aSopenharmony_ci                "Exif::getShort: component index out of range");
172b8bc0d8aSopenharmony_ci#endif
173b8bc0d8aSopenharmony_ci        return exif_get_short(entry_->data
174b8bc0d8aSopenharmony_ci                              + index * exif_format_get_size(entry_->format),
175b8bc0d8aSopenharmony_ci                              exif_data_get_byte_order(entry_->parent->parent));
176b8bc0d8aSopenharmony_ci    }
177b8bc0d8aSopenharmony_ci
178b8bc0d8aSopenharmony_ci    ExifLong getLong(unsigned int index) const
179b8bc0d8aSopenharmony_ci    {
180b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
181b8bc0d8aSopenharmony_ci        if(entry_->format != EXIF_FORMAT_LONG)
182b8bc0d8aSopenharmony_ci            throw InvalidFormat(
183b8bc0d8aSopenharmony_ci                "Exif::Entry::getLong(): Format is not EXIF_FORMAT_LONG");
184b8bc0d8aSopenharmony_ci        if(index >= components())
185b8bc0d8aSopenharmony_ci            throw InvalidIndex(
186b8bc0d8aSopenharmony_ci                "Exif::getLong: component index out of range");
187b8bc0d8aSopenharmony_ci#endif
188b8bc0d8aSopenharmony_ci        return exif_get_long(entry_->data
189b8bc0d8aSopenharmony_ci                             + index * exif_format_get_size(entry_->format),
190b8bc0d8aSopenharmony_ci                             exif_data_get_byte_order(entry_->parent->parent));
191b8bc0d8aSopenharmony_ci    }
192b8bc0d8aSopenharmony_ci
193b8bc0d8aSopenharmony_ci    ExifSLong getSLong(unsigned int index) const
194b8bc0d8aSopenharmony_ci    {
195b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
196b8bc0d8aSopenharmony_ci        if(entry_->format != EXIF_FORMAT_SLONG)
197b8bc0d8aSopenharmony_ci            throw InvalidFormat(
198b8bc0d8aSopenharmony_ci                "Exif::Entry::getSLong(): Format is not EXIF_FORMAT_SLONG");
199b8bc0d8aSopenharmony_ci        if(index >= components())
200b8bc0d8aSopenharmony_ci            throw InvalidIndex(
201b8bc0d8aSopenharmony_ci                "Exif::getSLong: component index out of range");
202b8bc0d8aSopenharmony_ci#endif
203b8bc0d8aSopenharmony_ci        return exif_get_slong(entry_->data
204b8bc0d8aSopenharmony_ci                              + index * exif_format_get_size(entry_->format),
205b8bc0d8aSopenharmony_ci                              exif_data_get_byte_order(entry_->parent->parent));
206b8bc0d8aSopenharmony_ci    }
207b8bc0d8aSopenharmony_ci
208b8bc0d8aSopenharmony_ci    ExifRational getRational(unsigned int index) const
209b8bc0d8aSopenharmony_ci    {
210b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
211b8bc0d8aSopenharmony_ci        if(entry_->format != EXIF_FORMAT_RATIONAL)
212b8bc0d8aSopenharmony_ci            throw InvalidFormat(
213b8bc0d8aSopenharmony_ci                "Exif::Entry::getRational(): Format is not EXIF_FORMAT_RATIONAL");
214b8bc0d8aSopenharmony_ci        if(index >= components())
215b8bc0d8aSopenharmony_ci            throw InvalidIndex(
216b8bc0d8aSopenharmony_ci                "Exif::getRational: component index out of range");
217b8bc0d8aSopenharmony_ci#endif
218b8bc0d8aSopenharmony_ci        return exif_get_rational(entry_->data
219b8bc0d8aSopenharmony_ci                                 + index * exif_format_get_size(entry_->format),
220b8bc0d8aSopenharmony_ci                                 exif_data_get_byte_order(entry_->parent->parent));
221b8bc0d8aSopenharmony_ci    }
222b8bc0d8aSopenharmony_ci
223b8bc0d8aSopenharmony_ci    ExifSRational getSRational(unsigned int index) const
224b8bc0d8aSopenharmony_ci    {
225b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
226b8bc0d8aSopenharmony_ci        if(entry_->format != EXIF_FORMAT_SRATIONAL)
227b8bc0d8aSopenharmony_ci            throw InvalidFormat(
228b8bc0d8aSopenharmony_ci                "Exif::Entry::getSRational(): Format is not EXIF_FORMAT_SRATIONAL");
229b8bc0d8aSopenharmony_ci        if(index >= components())
230b8bc0d8aSopenharmony_ci            throw InvalidIndex(
231b8bc0d8aSopenharmony_ci                "Exif::getSRational: component index out of range");
232b8bc0d8aSopenharmony_ci#endif
233b8bc0d8aSopenharmony_ci        return exif_get_srational(entry_->data
234b8bc0d8aSopenharmony_ci                                  + index * exif_format_get_size(entry_->format),
235b8bc0d8aSopenharmony_ci                                  exif_data_get_byte_order(entry_->parent->parent));
236b8bc0d8aSopenharmony_ci    }
237b8bc0d8aSopenharmony_ci
238b8bc0d8aSopenharmony_ci    void setByte(unsigned int index, ExifByte value) const
239b8bc0d8aSopenharmony_ci    {
240b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
241b8bc0d8aSopenharmony_ci        if(entry_->format != EXIF_FORMAT_BYTE)
242b8bc0d8aSopenharmony_ci            throw InvalidFormat(
243b8bc0d8aSopenharmony_ci                "Exif::Entry::setByte(): Format is not EXIF_FORMAT_BYTE");
244b8bc0d8aSopenharmony_ci        if(index >= components())
245b8bc0d8aSopenharmony_ci            throw InvalidIndex(
246b8bc0d8aSopenharmony_ci                "Exif::setByte: component index out of range");
247b8bc0d8aSopenharmony_ci#endif
248b8bc0d8aSopenharmony_ci        *(entry_->data
249b8bc0d8aSopenharmony_ci          + index * exif_format_get_size(entry_->format)) = value;
250b8bc0d8aSopenharmony_ci    }
251b8bc0d8aSopenharmony_ci
252b8bc0d8aSopenharmony_ci/*
253b8bc0d8aSopenharmony_ci    const ExifAscii setAscii() const
254b8bc0d8aSopenharmony_ci    {
255b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
256b8bc0d8aSopenharmony_ci        if(entry_->format != EXIF_FORMAT_ASCII)
257b8bc0d8aSopenharmony_ci            throw InvalidFormat(
258b8bc0d8aSopenharmony_ci                "Exif::Entry::setAscii(): Format is not EXIF_FORMAT_ASCII");
259b8bc0d8aSopenharmony_ci#endif
260b8bc0d8aSopenharmony_ci        return (ExifAscii)entry_->data;
261b8bc0d8aSopenharmony_ci    }
262b8bc0d8aSopenharmony_ci*/
263b8bc0d8aSopenharmony_ci
264b8bc0d8aSopenharmony_ci    void setShort(unsigned int index, ExifShort value) const
265b8bc0d8aSopenharmony_ci    {
266b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
267b8bc0d8aSopenharmony_ci        if(entry_->format != EXIF_FORMAT_SHORT)
268b8bc0d8aSopenharmony_ci            throw InvalidFormat(
269b8bc0d8aSopenharmony_ci                "Exif::Entry::setShort(): Format is not EXIF_FORMAT_SHORT");
270b8bc0d8aSopenharmony_ci        if(index >= components())
271b8bc0d8aSopenharmony_ci            throw InvalidIndex(
272b8bc0d8aSopenharmony_ci                "Exif::setShort: component index out of range");
273b8bc0d8aSopenharmony_ci#endif
274b8bc0d8aSopenharmony_ci        return exif_set_short(entry_->data
275b8bc0d8aSopenharmony_ci                              + index * exif_format_get_size(entry_->format),
276b8bc0d8aSopenharmony_ci                              exif_data_get_byte_order(entry_->parent->parent),
277b8bc0d8aSopenharmony_ci                              value);
278b8bc0d8aSopenharmony_ci    }
279b8bc0d8aSopenharmony_ci
280b8bc0d8aSopenharmony_ci    void setLong(unsigned int index, ExifLong value) const
281b8bc0d8aSopenharmony_ci    {
282b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
283b8bc0d8aSopenharmony_ci        if(entry_->format != EXIF_FORMAT_LONG)
284b8bc0d8aSopenharmony_ci            throw InvalidFormat(
285b8bc0d8aSopenharmony_ci                "Exif::Entry::setLong(): Format is not EXIF_FORMAT_LONG");
286b8bc0d8aSopenharmony_ci        if(index >= components())
287b8bc0d8aSopenharmony_ci            throw InvalidIndex(
288b8bc0d8aSopenharmony_ci                "Exif::setLong: component index out of range");
289b8bc0d8aSopenharmony_ci#endif
290b8bc0d8aSopenharmony_ci        return exif_set_long(entry_->data
291b8bc0d8aSopenharmony_ci                             + index * exif_format_get_size(entry_->format),
292b8bc0d8aSopenharmony_ci                             exif_data_get_byte_order(entry_->parent->parent),
293b8bc0d8aSopenharmony_ci                             value);
294b8bc0d8aSopenharmony_ci    }
295b8bc0d8aSopenharmony_ci
296b8bc0d8aSopenharmony_ci    void setSLong(unsigned int index, ExifSLong value) const
297b8bc0d8aSopenharmony_ci    {
298b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
299b8bc0d8aSopenharmony_ci        if(entry_->format != EXIF_FORMAT_SLONG)
300b8bc0d8aSopenharmony_ci            throw InvalidFormat(
301b8bc0d8aSopenharmony_ci                "Exif::Entry::setSLong(): Format is not EXIF_FORMAT_SLONG");
302b8bc0d8aSopenharmony_ci        if(index >= components())
303b8bc0d8aSopenharmony_ci            throw InvalidIndex(
304b8bc0d8aSopenharmony_ci                "Exif::setSLong: component index out of range");
305b8bc0d8aSopenharmony_ci#endif
306b8bc0d8aSopenharmony_ci        return exif_set_slong(entry_->data
307b8bc0d8aSopenharmony_ci                              + index * exif_format_get_size(entry_->format),
308b8bc0d8aSopenharmony_ci                              exif_data_get_byte_order(entry_->parent->parent),
309b8bc0d8aSopenharmony_ci                              value);
310b8bc0d8aSopenharmony_ci    }
311b8bc0d8aSopenharmony_ci
312b8bc0d8aSopenharmony_ci    void setRational(unsigned int index, ExifRational value) const
313b8bc0d8aSopenharmony_ci    {
314b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
315b8bc0d8aSopenharmony_ci        if(entry_->format != EXIF_FORMAT_RATIONAL)
316b8bc0d8aSopenharmony_ci            throw InvalidFormat(
317b8bc0d8aSopenharmony_ci                "Exif::Entry::setRational(): Format is not EXIF_FORMAT_RATIONAL");
318b8bc0d8aSopenharmony_ci        if(index >= components())
319b8bc0d8aSopenharmony_ci            throw InvalidIndex(
320b8bc0d8aSopenharmony_ci                "Exif::setRational: component index out of range");
321b8bc0d8aSopenharmony_ci#endif
322b8bc0d8aSopenharmony_ci        return exif_set_rational(entry_->data
323b8bc0d8aSopenharmony_ci                                 + index * exif_format_get_size(entry_->format),
324b8bc0d8aSopenharmony_ci                                 exif_data_get_byte_order(entry_->parent->parent),
325b8bc0d8aSopenharmony_ci                                 value);
326b8bc0d8aSopenharmony_ci    }
327b8bc0d8aSopenharmony_ci
328b8bc0d8aSopenharmony_ci    void setSRational(unsigned int index, ExifSRational value) const
329b8bc0d8aSopenharmony_ci    {
330b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
331b8bc0d8aSopenharmony_ci        if(entry_->format != EXIF_FORMAT_SRATIONAL)
332b8bc0d8aSopenharmony_ci            throw InvalidFormat(
333b8bc0d8aSopenharmony_ci                "Exif::Entry::setSRational(): Format is not EXIF_FORMAT_SRATIONAL");
334b8bc0d8aSopenharmony_ci        if(index >= components())
335b8bc0d8aSopenharmony_ci            throw InvalidIndex(
336b8bc0d8aSopenharmony_ci                "Exif::setSRational: component index out of range");
337b8bc0d8aSopenharmony_ci#endif
338b8bc0d8aSopenharmony_ci        return exif_set_srational(entry_->data
339b8bc0d8aSopenharmony_ci                                  + index * exif_format_get_size(entry_->format),
340b8bc0d8aSopenharmony_ci                                  exif_data_get_byte_order(entry_->parent->parent),
341b8bc0d8aSopenharmony_ci                                  value);
342b8bc0d8aSopenharmony_ci    }
343b8bc0d8aSopenharmony_ci
344b8bc0d8aSopenharmony_ci    const char *value()
345b8bc0d8aSopenharmony_ci    {
346b8bc0d8aSopenharmony_ci        return exif_entry_get_value(entry_);
347b8bc0d8aSopenharmony_ci    }
348b8bc0d8aSopenharmony_ci
349b8bc0d8aSopenharmony_ci    const char *briefValue()
350b8bc0d8aSopenharmony_ci    {
351b8bc0d8aSopenharmony_ci        return exif_entry_get_value_brief(entry_);
352b8bc0d8aSopenharmony_ci    }
353b8bc0d8aSopenharmony_ci
354b8bc0d8aSopenharmony_ci    void dump(unsigned int indent = 0) const
355b8bc0d8aSopenharmony_ci    {
356b8bc0d8aSopenharmony_ci        exif_entry_dump(entry_, indent);
357b8bc0d8aSopenharmony_ci    }
358b8bc0d8aSopenharmony_ci};
359b8bc0d8aSopenharmony_ci
360b8bc0d8aSopenharmony_cistruct Content
361b8bc0d8aSopenharmony_ci{
362b8bc0d8aSopenharmony_ci    ExifContent *content_;
363b8bc0d8aSopenharmony_ci
364b8bc0d8aSopenharmony_ci    Content()
365b8bc0d8aSopenharmony_ci    : content_(exif_content_new())
366b8bc0d8aSopenharmony_ci    {}
367b8bc0d8aSopenharmony_ci
368b8bc0d8aSopenharmony_ci    Content(Content const &other)
369b8bc0d8aSopenharmony_ci    : content_(other.content_)
370b8bc0d8aSopenharmony_ci    {
371b8bc0d8aSopenharmony_ci        exif_content_ref(content_);
372b8bc0d8aSopenharmony_ci    }
373b8bc0d8aSopenharmony_ci
374b8bc0d8aSopenharmony_ci        // internal, do not use directly
375b8bc0d8aSopenharmony_ci    Content(ExifContent *content)
376b8bc0d8aSopenharmony_ci    : content_(content)
377b8bc0d8aSopenharmony_ci    {
378b8bc0d8aSopenharmony_ci        exif_content_ref(content_);
379b8bc0d8aSopenharmony_ci    }
380b8bc0d8aSopenharmony_ci
381b8bc0d8aSopenharmony_ci    ~Content()
382b8bc0d8aSopenharmony_ci    {
383b8bc0d8aSopenharmony_ci        exif_content_unref(content_);
384b8bc0d8aSopenharmony_ci    }
385b8bc0d8aSopenharmony_ci
386b8bc0d8aSopenharmony_ci    Content &operator=(Content const &other)
387b8bc0d8aSopenharmony_ci    {
388b8bc0d8aSopenharmony_ci        exif_content_unref(content_);
389b8bc0d8aSopenharmony_ci        content_ = other.content_;
390b8bc0d8aSopenharmony_ci        exif_content_ref(content_);
391b8bc0d8aSopenharmony_ci        return *this;
392b8bc0d8aSopenharmony_ci    }
393b8bc0d8aSopenharmony_ci
394b8bc0d8aSopenharmony_ci    Entry operator[](ExifTag tag)
395b8bc0d8aSopenharmony_ci    {
396b8bc0d8aSopenharmony_ci        ExifEntry *result = exif_content_get_entry(content_, tag);
397b8bc0d8aSopenharmony_ci        if(result)
398b8bc0d8aSopenharmony_ci            return Entry(result);
399b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
400b8bc0d8aSopenharmony_ci        throw InvalidIndex(
401b8bc0d8aSopenharmony_ci            "Exif::Content: IFD does not contain given tag");
402b8bc0d8aSopenharmony_ci#endif
403b8bc0d8aSopenharmony_ci        return Entry();
404b8bc0d8aSopenharmony_ci    }
405b8bc0d8aSopenharmony_ci
406b8bc0d8aSopenharmony_ci    Entry operator[](unsigned int index)
407b8bc0d8aSopenharmony_ci    {
408b8bc0d8aSopenharmony_ci        if(index < size())
409b8bc0d8aSopenharmony_ci            return Entry(content_->entries[index]);
410b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
411b8bc0d8aSopenharmony_ci        throw InvalidIndex(
412b8bc0d8aSopenharmony_ci            "Exif::Content: numeric entry index out of range");
413b8bc0d8aSopenharmony_ci#endif // EXIF_NO_EXCEPTIONS
414b8bc0d8aSopenharmony_ci        return Entry();
415b8bc0d8aSopenharmony_ci    }
416b8bc0d8aSopenharmony_ci
417b8bc0d8aSopenharmony_ci    unsigned int size() const
418b8bc0d8aSopenharmony_ci    {
419b8bc0d8aSopenharmony_ci        // FIXME: content_ should never be NULL, so this is unneeded!?
420b8bc0d8aSopenharmony_ci        return content_ ? content_->count : 0;
421b8bc0d8aSopenharmony_ci    }
422b8bc0d8aSopenharmony_ci
423b8bc0d8aSopenharmony_ci    void add(Entry &entry)
424b8bc0d8aSopenharmony_ci    {
425b8bc0d8aSopenharmony_ci        exif_content_add_entry(content_, entry.entry_);
426b8bc0d8aSopenharmony_ci    }
427b8bc0d8aSopenharmony_ci
428b8bc0d8aSopenharmony_ci    void remove(Entry &entry)
429b8bc0d8aSopenharmony_ci    {
430b8bc0d8aSopenharmony_ci        exif_content_remove_entry(content_, entry.entry_);
431b8bc0d8aSopenharmony_ci    }
432b8bc0d8aSopenharmony_ci
433b8bc0d8aSopenharmony_ci        // for your convenience
434b8bc0d8aSopenharmony_ci    const char *value(ExifTag tag)
435b8bc0d8aSopenharmony_ci    {
436b8bc0d8aSopenharmony_ci        return exif_content_get_value(content_, tag);
437b8bc0d8aSopenharmony_ci    }
438b8bc0d8aSopenharmony_ci
439b8bc0d8aSopenharmony_ci        // for your convenience
440b8bc0d8aSopenharmony_ci    const char *briefValue(ExifTag tag)
441b8bc0d8aSopenharmony_ci    {
442b8bc0d8aSopenharmony_ci        return exif_content_get_value_brief(content_, tag);
443b8bc0d8aSopenharmony_ci    }
444b8bc0d8aSopenharmony_ci
445b8bc0d8aSopenharmony_ci    void dump(unsigned int indent = 0) const
446b8bc0d8aSopenharmony_ci    {
447b8bc0d8aSopenharmony_ci        exif_content_dump(content_, indent);
448b8bc0d8aSopenharmony_ci    }
449b8bc0d8aSopenharmony_ci};
450b8bc0d8aSopenharmony_ci
451b8bc0d8aSopenharmony_cistruct Data
452b8bc0d8aSopenharmony_ci{
453b8bc0d8aSopenharmony_ci    ExifData *data_;
454b8bc0d8aSopenharmony_ci
455b8bc0d8aSopenharmony_ci    Data()
456b8bc0d8aSopenharmony_ci    : data_(exif_data_new())
457b8bc0d8aSopenharmony_ci    {}
458b8bc0d8aSopenharmony_ci
459b8bc0d8aSopenharmony_ci    Data(const char *path, bool *success = 0)
460b8bc0d8aSopenharmony_ci    : data_(exif_data_new_from_file(path))
461b8bc0d8aSopenharmony_ci    {
462b8bc0d8aSopenharmony_ci        if(success)
463b8bc0d8aSopenharmony_ci            *success = data_;
464b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
465b8bc0d8aSopenharmony_ci        else
466b8bc0d8aSopenharmony_ci            if(!data_)
467b8bc0d8aSopenharmony_ci                throw IOError("Exif::Data: Could not load file");
468b8bc0d8aSopenharmony_ci#endif // EXIF_NO_EXCEPTIONS
469b8bc0d8aSopenharmony_ci        if(!data_)
470b8bc0d8aSopenharmony_ci            exif_data_new();
471b8bc0d8aSopenharmony_ci    }
472b8bc0d8aSopenharmony_ci
473b8bc0d8aSopenharmony_ci    Data(const unsigned char *data,
474b8bc0d8aSopenharmony_ci         unsigned int size)
475b8bc0d8aSopenharmony_ci    : data_(exif_data_new_from_data(data, size))
476b8bc0d8aSopenharmony_ci    {}
477b8bc0d8aSopenharmony_ci
478b8bc0d8aSopenharmony_ci    Data(Data const &other)
479b8bc0d8aSopenharmony_ci    : data_(other.data_)
480b8bc0d8aSopenharmony_ci    {
481b8bc0d8aSopenharmony_ci        exif_data_ref(data_);
482b8bc0d8aSopenharmony_ci    }
483b8bc0d8aSopenharmony_ci
484b8bc0d8aSopenharmony_ci    ~Data()
485b8bc0d8aSopenharmony_ci    {
486b8bc0d8aSopenharmony_ci        exif_data_unref(data_);
487b8bc0d8aSopenharmony_ci    }
488b8bc0d8aSopenharmony_ci
489b8bc0d8aSopenharmony_ci    Data &operator=(Data const &other)
490b8bc0d8aSopenharmony_ci    {
491b8bc0d8aSopenharmony_ci        exif_data_unref(data_);
492b8bc0d8aSopenharmony_ci        data_ = other.data_;
493b8bc0d8aSopenharmony_ci        exif_data_ref(data_);
494b8bc0d8aSopenharmony_ci        return *this;
495b8bc0d8aSopenharmony_ci    }
496b8bc0d8aSopenharmony_ci
497b8bc0d8aSopenharmony_ci    void save(unsigned char **d, unsigned int *size)
498b8bc0d8aSopenharmony_ci    {
499b8bc0d8aSopenharmony_ci        exif_data_save_data(data_, d, size);
500b8bc0d8aSopenharmony_ci    }
501b8bc0d8aSopenharmony_ci
502b8bc0d8aSopenharmony_ci    unsigned int size() const
503b8bc0d8aSopenharmony_ci    {
504b8bc0d8aSopenharmony_ci        return EXIF_IFD_COUNT;
505b8bc0d8aSopenharmony_ci    }
506b8bc0d8aSopenharmony_ci
507b8bc0d8aSopenharmony_ci    Content operator[](unsigned int index)
508b8bc0d8aSopenharmony_ci    {
509b8bc0d8aSopenharmony_ci        if(index < size())
510b8bc0d8aSopenharmony_ci            return Content(data_->ifd[index]);
511b8bc0d8aSopenharmony_ci#ifndef EXIF_NO_EXCEPTIONS
512b8bc0d8aSopenharmony_ci        throw InvalidIndex(
513b8bc0d8aSopenharmony_ci            "Exif::Data: IFD index out of range");
514b8bc0d8aSopenharmony_ci#endif // EXIF_NO_EXCEPTIONS
515b8bc0d8aSopenharmony_ci        return Content();
516b8bc0d8aSopenharmony_ci    }
517b8bc0d8aSopenharmony_ci
518b8bc0d8aSopenharmony_ci    ExifByteOrder byteOrder() const
519b8bc0d8aSopenharmony_ci    {
520b8bc0d8aSopenharmony_ci        return exif_data_get_byte_order(data_);
521b8bc0d8aSopenharmony_ci    }
522b8bc0d8aSopenharmony_ci
523b8bc0d8aSopenharmony_ci    void setByteOrder(ExifByteOrder bo) const
524b8bc0d8aSopenharmony_ci    {
525b8bc0d8aSopenharmony_ci        exif_data_set_byte_order(data_, bo);
526b8bc0d8aSopenharmony_ci    }
527b8bc0d8aSopenharmony_ci
528b8bc0d8aSopenharmony_ci    void dump()
529b8bc0d8aSopenharmony_ci    {
530b8bc0d8aSopenharmony_ci        exif_data_dump(data_);
531b8bc0d8aSopenharmony_ci    }
532b8bc0d8aSopenharmony_ci};
533b8bc0d8aSopenharmony_ci
534b8bc0d8aSopenharmony_ci} // namespace Exif
535b8bc0d8aSopenharmony_ci
536b8bc0d8aSopenharmony_ci#endif // EXIF_HXX
537