3 * Copyright 2002,2003 Hans Meine <hans_meine@gmx.net>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA.
24 #include <libexif/exif-entry.h>
25 #include <libexif/exif-content.h>
26 #include <libexif/exif-ifd.h>
27 #include <libexif/exif-data.h>
28 #include <libexif/exif-format.h>
29 #include <libexif/exif-utils.h>
35 #ifndef EXIF_NO_EXCEPTIONS
36 struct InvalidIndex : std::runtime_error
38 InvalidIndex(const std::string& s)
39 : std::runtime_error(s) {}
42 struct InvalidFormat : std::runtime_error
44 InvalidFormat(const std::string& s)
45 : std::runtime_error(s) {}
48 struct IOError : std::runtime_error
50 IOError(const std::string& s)
51 : std::runtime_error(s) {}
53 #endif // EXIF_NO_EXCEPTIONS
59 // construct an empty entry, FIXME: is this needed in the public API?
61 : entry_(exif_entry_new())
64 // construct an entry for the given tag
66 : entry_(exif_entry_new())
68 exif_entry_initialize(entry_, tag);
72 Entry(Entry const &other)
73 : entry_(other.entry_)
75 exif_entry_ref(entry_);
78 // internal, do not use directly
79 Entry(ExifEntry *entry)
82 exif_entry_ref(entry_);
87 exif_entry_unref(entry_);
90 Entry &operator=(Entry const &other)
92 exif_entry_unref(entry_);
93 entry_ = other.entry_;
94 exif_entry_ref(entry_);
104 void setTag(ExifTag tag)
110 ExifFormat format() const
112 return entry_->format;
116 void setFormat(ExifFormat format)
118 entry_->format = format;
122 unsigned long components() const
124 return entry_->components;
128 void setComponents(unsigned long components)
130 entry_->components = components;
133 void initialize(ExifTag tag)
135 exif_entry_initialize(entry_, tag);
139 ExifByte getByte(unsigned int index) const
141 #ifndef EXIF_NO_EXCEPTIONS
142 if(entry_->format != EXIF_FORMAT_BYTE)
144 "Exif::Entry::getByte(): Format is not EXIF_FORMAT_BYTE");
145 if(index >= components())
147 "Exif::getByte: component index out of range");
149 return *(entry_->data
150 + index * exif_format_get_size(entry_->format));
153 const ExifAscii getAscii() const
155 #ifndef EXIF_NO_EXCEPTIONS
156 if(entry_->format != EXIF_FORMAT_ASCII)
158 "Exif::Entry::getAscii(): Format is not EXIF_FORMAT_ASCII");
160 return (ExifAscii)entry_->data;
163 ExifShort getShort(unsigned int index) const
165 #ifndef EXIF_NO_EXCEPTIONS
166 if(entry_->format != EXIF_FORMAT_SHORT)
168 "Exif::Entry::getShort(): Format is not EXIF_FORMAT_SHORT");
169 if(index >= components())
171 "Exif::getShort: component index out of range");
173 return exif_get_short(entry_->data
174 + index * exif_format_get_size(entry_->format),
175 exif_data_get_byte_order(entry_->parent->parent));
178 ExifLong getLong(unsigned int index) const
180 #ifndef EXIF_NO_EXCEPTIONS
181 if(entry_->format != EXIF_FORMAT_LONG)
183 "Exif::Entry::getLong(): Format is not EXIF_FORMAT_LONG");
184 if(index >= components())
186 "Exif::getLong: component index out of range");
188 return exif_get_long(entry_->data
189 + index * exif_format_get_size(entry_->format),
190 exif_data_get_byte_order(entry_->parent->parent));
193 ExifSLong getSLong(unsigned int index) const
195 #ifndef EXIF_NO_EXCEPTIONS
196 if(entry_->format != EXIF_FORMAT_SLONG)
198 "Exif::Entry::getSLong(): Format is not EXIF_FORMAT_SLONG");
199 if(index >= components())
201 "Exif::getSLong: component index out of range");
203 return exif_get_slong(entry_->data
204 + index * exif_format_get_size(entry_->format),
205 exif_data_get_byte_order(entry_->parent->parent));
208 ExifRational getRational(unsigned int index) const
210 #ifndef EXIF_NO_EXCEPTIONS
211 if(entry_->format != EXIF_FORMAT_RATIONAL)
213 "Exif::Entry::getRational(): Format is not EXIF_FORMAT_RATIONAL");
214 if(index >= components())
216 "Exif::getRational: component index out of range");
218 return exif_get_rational(entry_->data
219 + index * exif_format_get_size(entry_->format),
220 exif_data_get_byte_order(entry_->parent->parent));
223 ExifSRational getSRational(unsigned int index) const
225 #ifndef EXIF_NO_EXCEPTIONS
226 if(entry_->format != EXIF_FORMAT_SRATIONAL)
228 "Exif::Entry::getSRational(): Format is not EXIF_FORMAT_SRATIONAL");
229 if(index >= components())
231 "Exif::getSRational: component index out of range");
233 return exif_get_srational(entry_->data
234 + index * exif_format_get_size(entry_->format),
235 exif_data_get_byte_order(entry_->parent->parent));
238 void setByte(unsigned int index, ExifByte value) const
240 #ifndef EXIF_NO_EXCEPTIONS
241 if(entry_->format != EXIF_FORMAT_BYTE)
243 "Exif::Entry::setByte(): Format is not EXIF_FORMAT_BYTE");
244 if(index >= components())
246 "Exif::setByte: component index out of range");
249 + index * exif_format_get_size(entry_->format)) = value;
253 const ExifAscii setAscii() const
255 #ifndef EXIF_NO_EXCEPTIONS
256 if(entry_->format != EXIF_FORMAT_ASCII)
258 "Exif::Entry::setAscii(): Format is not EXIF_FORMAT_ASCII");
260 return (ExifAscii)entry_->data;
264 void setShort(unsigned int index, ExifShort value) const
266 #ifndef EXIF_NO_EXCEPTIONS
267 if(entry_->format != EXIF_FORMAT_SHORT)
269 "Exif::Entry::setShort(): Format is not EXIF_FORMAT_SHORT");
270 if(index >= components())
272 "Exif::setShort: component index out of range");
274 return exif_set_short(entry_->data
275 + index * exif_format_get_size(entry_->format),
276 exif_data_get_byte_order(entry_->parent->parent),
280 void setLong(unsigned int index, ExifLong value) const
282 #ifndef EXIF_NO_EXCEPTIONS
283 if(entry_->format != EXIF_FORMAT_LONG)
285 "Exif::Entry::setLong(): Format is not EXIF_FORMAT_LONG");
286 if(index >= components())
288 "Exif::setLong: component index out of range");
290 return exif_set_long(entry_->data
291 + index * exif_format_get_size(entry_->format),
292 exif_data_get_byte_order(entry_->parent->parent),
296 void setSLong(unsigned int index, ExifSLong value) const
298 #ifndef EXIF_NO_EXCEPTIONS
299 if(entry_->format != EXIF_FORMAT_SLONG)
301 "Exif::Entry::setSLong(): Format is not EXIF_FORMAT_SLONG");
302 if(index >= components())
304 "Exif::setSLong: component index out of range");
306 return exif_set_slong(entry_->data
307 + index * exif_format_get_size(entry_->format),
308 exif_data_get_byte_order(entry_->parent->parent),
312 void setRational(unsigned int index, ExifRational value) const
314 #ifndef EXIF_NO_EXCEPTIONS
315 if(entry_->format != EXIF_FORMAT_RATIONAL)
317 "Exif::Entry::setRational(): Format is not EXIF_FORMAT_RATIONAL");
318 if(index >= components())
320 "Exif::setRational: component index out of range");
322 return exif_set_rational(entry_->data
323 + index * exif_format_get_size(entry_->format),
324 exif_data_get_byte_order(entry_->parent->parent),
328 void setSRational(unsigned int index, ExifSRational value) const
330 #ifndef EXIF_NO_EXCEPTIONS
331 if(entry_->format != EXIF_FORMAT_SRATIONAL)
333 "Exif::Entry::setSRational(): Format is not EXIF_FORMAT_SRATIONAL");
334 if(index >= components())
336 "Exif::setSRational: component index out of range");
338 return exif_set_srational(entry_->data
339 + index * exif_format_get_size(entry_->format),
340 exif_data_get_byte_order(entry_->parent->parent),
346 return exif_entry_get_value(entry_);
349 const char *briefValue()
351 return exif_entry_get_value_brief(entry_);
354 void dump(unsigned int indent = 0) const
356 exif_entry_dump(entry_, indent);
362 ExifContent *content_;
365 : content_(exif_content_new())
368 Content(Content const &other)
369 : content_(other.content_)
371 exif_content_ref(content_);
374 // internal, do not use directly
375 Content(ExifContent *content)
378 exif_content_ref(content_);
383 exif_content_unref(content_);
386 Content &operator=(Content const &other)
388 exif_content_unref(content_);
389 content_ = other.content_;
390 exif_content_ref(content_);
394 Entry operator[](ExifTag tag)
396 ExifEntry *result = exif_content_get_entry(content_, tag);
398 return Entry(result);
399 #ifndef EXIF_NO_EXCEPTIONS
401 "Exif::Content: IFD does not contain given tag");
406 Entry operator[](unsigned int index)
409 return Entry(content_->entries[index]);
410 #ifndef EXIF_NO_EXCEPTIONS
412 "Exif::Content: numeric entry index out of range");
413 #endif // EXIF_NO_EXCEPTIONS
417 unsigned int size() const
419 // FIXME: content_ should never be NULL, so this is unneeded!?
420 return content_ ? content_->count : 0;
423 void add(Entry &entry)
425 exif_content_add_entry(content_, entry.entry_);
428 void remove(Entry &entry)
430 exif_content_remove_entry(content_, entry.entry_);
433 // for your convenience
434 const char *value(ExifTag tag)
436 return exif_content_get_value(content_, tag);
439 // for your convenience
440 const char *briefValue(ExifTag tag)
442 return exif_content_get_value_brief(content_, tag);
445 void dump(unsigned int indent = 0) const
447 exif_content_dump(content_, indent);
456 : data_(exif_data_new())
459 Data(const char *path, bool *success = 0)
460 : data_(exif_data_new_from_file(path))
464 #ifndef EXIF_NO_EXCEPTIONS
467 throw IOError("Exif::Data: Could not load file");
468 #endif // EXIF_NO_EXCEPTIONS
473 Data(const unsigned char *data,
475 : data_(exif_data_new_from_data(data, size))
478 Data(Data const &other)
481 exif_data_ref(data_);
486 exif_data_unref(data_);
489 Data &operator=(Data const &other)
491 exif_data_unref(data_);
493 exif_data_ref(data_);
497 void save(unsigned char **d, unsigned int *size)
499 exif_data_save_data(data_, d, size);
502 unsigned int size() const
504 return EXIF_IFD_COUNT;
507 Content operator[](unsigned int index)
510 return Content(data_->ifd[index]);
511 #ifndef EXIF_NO_EXCEPTIONS
513 "Exif::Data: IFD index out of range");
514 #endif // EXIF_NO_EXCEPTIONS
518 ExifByteOrder byteOrder() const
520 return exif_data_get_byte_order(data_);
523 void setByteOrder(ExifByteOrder bo) const
525 exif_data_set_byte_order(data_, bo);
530 exif_data_dump(data_);