libopenraw
ifdentry.cpp
1 /*
2  * libopenraw - ifdentry.cpp
3  *
4  * Copyright (C) 2006-2008 Hubert Figuiere
5  *
6  * This library is free software: you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License
8  * as published by the Free Software Foundation, either version 3 of
9  * the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library. If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
21 
22 #include <cassert>
23 #include <string>
24 
25 #include "exception.h"
26 #include "endianutils.h"
27 
28 #include "ifdfilecontainer.h"
29 #include "ifdentry.h"
30 #include "ifd.h"
31 
32 namespace OpenRaw {
33  namespace Internals {
34 
35 
36  IFDEntry::IFDEntry(uint16_t _id, int16_t _type,
37  int32_t _count, uint32_t _data,
38  IFDFileContainer &_container)
39  : m_id(_id), m_type(_type),
40  m_count(_count), m_data(_data),
41  m_loaded(false), m_dataptr(NULL),
42  m_container(_container)
43  {
44  }
45 
46 
47  IFDEntry::~IFDEntry()
48  {
49  if (m_dataptr) {
50  free(m_dataptr);
51  }
52  }
53 
54  RawContainer::EndianType IFDEntry::endian() const
55  {
56  return m_container.endian();
57  }
58 
59 
60  bool IFDEntry::loadData(size_t unit_size)
61  {
62  bool success = false;
63  size_t data_size = unit_size * m_count;
64  if (data_size <= 4) {
65  m_dataptr = NULL;
66  success = true;
67  }
68  else {
69  off_t _offset;
70  if (endian() == RawContainer::ENDIAN_LITTLE) {
71  _offset = IFDTypeTrait<uint32_t>::EL((uint8_t*)&m_data);
72  }
73  else {
74  _offset = IFDTypeTrait<uint32_t>::BE((uint8_t*)&m_data);
75  }
76  m_dataptr = (uint8_t*)realloc(m_dataptr, data_size);
77  success = (m_container.fetchData(m_dataptr,
78  _offset,
79  data_size) == data_size);
80  }
81  return success;
82  }
83 
84  template <>
85  const uint16_t IFDTypeTrait<uint8_t>::type = IFD::EXIF_FORMAT_BYTE;
86  template <>
87  const size_t IFDTypeTrait<uint8_t>::size = 1;
88 
89  template <>
90  const uint16_t IFDTypeTrait<uint16_t>::type = IFD::EXIF_FORMAT_SHORT;
91  template <>
92  const size_t IFDTypeTrait<uint16_t>::size = 2;
93 
94 #if defined(__APPLE_CC__)
95 // Apple broken g++ version or linker seems to choke.
96  template <>
97  const uint16_t IFDTypeTrait<unsigned long>::type = IFD::EXIF_FORMAT_LONG;
98  template <>
99  const size_t IFDTypeTrait<unsigned long>::size = 4;
100 #endif
101  template <>
102  const uint16_t IFDTypeTrait<uint32_t>::type = IFD::EXIF_FORMAT_LONG;
103  template <>
104  const size_t IFDTypeTrait<uint32_t>::size = 4;
105 
106  template <>
107  const uint16_t IFDTypeTrait<std::string>::type = IFD::EXIF_FORMAT_ASCII;
108  template <>
109  const size_t IFDTypeTrait<std::string>::size = 1;
110  }
111 }