libopenraw  0.3.7
ifdentry.hpp
1 /*
2  * libopenraw - ifdentry.hpp
3  *
4  * Copyright (C) 2006-2020 Hubert Figuière
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 #pragma once
22 
23 #include <stddef.h>
24 #include <stdint.h>
25 #include <string.h>
26 #include <sys/types.h>
27 
28 #include <exception>
29 #include <string>
30 #include <vector>
31 #include <memory>
32 
33 #include "exception.hpp"
34 #include "trace.hpp"
35 #include "endianutils.hpp"
36 #include "rawcontainer.hpp"
37 #include "ifd.hpp"
38 
39 namespace OpenRaw {
40 
41 class MetaValue;
42 
43 namespace Internals {
44 
48 class IfdDir;
49 
50 class IfdEntry;
51 
53 template <typename T>
55 {
56  static const uint16_t type;
57  static const size_t size;
58  static T EL(const uint8_t* d, size_t len) noexcept;
59  static T BE(const uint8_t* d, size_t len) noexcept;
60 };
61 
62 
63 template <>
64 inline uint8_t IfdTypeTrait<uint8_t>::EL(const uint8_t* b, size_t) noexcept
65 {
66  return *b;
67 }
68 
69 template <>
70 inline uint8_t IfdTypeTrait<uint8_t>::BE(const uint8_t* b, size_t) noexcept
71 {
72  return *b;
73 }
74 
75 template <>
76 inline int8_t IfdTypeTrait<int8_t>::EL(const uint8_t* b, size_t) noexcept
77 {
78  return *b;
79 }
80 
81 template <>
82 inline int8_t IfdTypeTrait<int8_t>::BE(const uint8_t* b, size_t) noexcept
83 {
84  return *b;
85 }
86 
87 template <>
88 inline uint16_t IfdTypeTrait<uint16_t>::EL(const uint8_t* b, size_t) noexcept
89 {
90  return EL16(b);
91 }
92 
93 template <>
94 inline uint16_t IfdTypeTrait<uint16_t>::BE(const uint8_t* b, size_t) noexcept
95 {
96  return BE16(b);
97 }
98 
99 template <>
100 inline int16_t IfdTypeTrait<int16_t>::EL(const uint8_t* b, size_t) noexcept
101 {
102  uint16_t uns = EL16(b);
103  return *(int16_t*)&uns;
104 }
105 
106 template <>
107 inline int16_t IfdTypeTrait<int16_t>::BE(const uint8_t* b, size_t) noexcept
108 {
109  uint16_t uns = BE16(b);
110  return *(int16_t*)&uns;
111 }
112 
113 template <>
114 inline uint32_t IfdTypeTrait<uint32_t>::EL(const uint8_t* b, size_t) noexcept
115 {
116  return EL32(b);
117 }
118 
119 template <>
120 inline uint32_t IfdTypeTrait<uint32_t>::BE(const uint8_t* b, size_t) noexcept
121 {
122  return BE32(b);
123 }
124 
125 template <>
126 inline int32_t IfdTypeTrait<int32_t>::EL(const uint8_t* b, size_t) noexcept
127 {
128  return EL32(b);
129 }
130 
131 template <>
132 inline int32_t IfdTypeTrait<int32_t>::BE(const uint8_t* b, size_t) noexcept
133 {
134  return BE32(b);
135 }
136 
137 template <>
138 inline std::string IfdTypeTrait<std::string>::EL(const uint8_t* b, size_t len) noexcept
139 {
140  std::string s;
141  try {
142  s.assign((const char*)b, strnlen((const char*)b, len));
143  }
144  catch(...) {
145  }
146  return s;
147 }
148 
149 template <>
150 inline std::string IfdTypeTrait<std::string>::BE(const uint8_t* b, size_t len) noexcept
151 {
152  std::string s;
153  try {
154  s.assign((const char*)b, strnlen((const char*)b, len));
155  }
156  catch(...) {
157  }
158  return s;
159 }
160 
161 template <>
162 inline IFD::ORRational IfdTypeTrait<IFD::ORRational>::EL(const uint8_t* b, size_t) noexcept
163 {
164  IFD::ORRational r;
165  r.num = EL32(b);
166  r.denom = EL32(b + 4);
167  return r;
168 }
169 
170 template <>
171 inline IFD::ORRational IfdTypeTrait<IFD::ORRational>::BE(const uint8_t* b, size_t) noexcept
172 {
173  IFD::ORRational r;
174  r.num = BE32(b);
175  r.denom = BE32(b + 4);
176  return r;
177 }
178 
179 template <>
180 inline IFD::ORSRational IfdTypeTrait<IFD::ORSRational>::EL(const uint8_t* b, size_t) noexcept
181 {
182  IFD::ORSRational r;
183  r.num = EL32(b);
184  r.denom = EL32(b + 4);
185  return r;
186 }
187 
188 template <>
189 inline IFD::ORSRational IfdTypeTrait<IFD::ORSRational>::BE(const uint8_t* b, size_t) noexcept
190 {
191  IFD::ORSRational r;
192  r.num = BE32(b);
193  r.denom = BE32(b + 4);
194  return r;
195 }
196 
198 class IfdEntry
199 {
200 public:
202  typedef std::shared_ptr<IfdEntry> Ref;
203 
204  IfdEntry(uint16_t _id, int16_t _type, int32_t _count, uint32_t _data,
205  const IfdDir& _dir, bool synthetic = false);
206  virtual ~IfdEntry();
207 
209  int16_t id() const noexcept
210  {
211  return m_id;
212  }
217  int16_t type() const noexcept
218  {
219  return m_type;
220  }
221 
223  uint32_t count() const noexcept
224  {
225  return m_count;
226  }
227 
232  off_t offset() noexcept
233  {
235  return IfdTypeTrait<uint32_t>::EL((uint8_t*)&m_data, sizeof(uint32_t));
236  }
237  return IfdTypeTrait<uint32_t>::BE((uint8_t*)&m_data, sizeof(uint32_t));
238  }
239 
242 
244  const uint8_t* dataptr() const
245  {
246  if (m_dataptr == nullptr) {
247  return (uint8_t*)&m_data;
248  } else {
249  return m_dataptr;
250  }
251  }
252 
256  static size_t typeUnitSize(IFD::ExifTagType _type);
265  bool loadData(size_t unit_size, off_t offset);
266 
274  size_t loadDataInto(uint8_t* dataptr, size_t data_size, off_t offset) const;
276  void setData(const uint8_t* dataptr, size_t data_size);
277 private:
278  uint16_t m_id;
279  uint16_t m_type;
280  uint32_t m_count;
281  uint32_t m_data;
282  bool m_loaded;
283  uint8_t *m_dataptr;
284  const IfdDir& m_dir;
285  template <typename T> friend struct IfdTypeTrait;
286 
287  IfdEntry(const IfdEntry& f) = delete;
288  IfdEntry & operator=(const IfdEntry&) = delete;
289 
290 };
291 
293 }
294 }
295 /*
296  Local Variables:
297  mode:c++
298  c-file-style:"stroustrup"
299  c-file-offsets:((innamespace . 0))
300  tab-width:2
301  c-basic-offset:2
302  indent-tabs-mode:nil
303  fill-column:80
304  End:
305 */
An IFD directory.
Definition: ifddir.hpp:51
An entry in the IfdDir.
Definition: ifdentry.hpp:199
void setData(const uint8_t *dataptr, size_t data_size)
Set the data of the entry.
Definition: ifdentry.cpp:124
size_t loadDataInto(uint8_t *dataptr, size_t data_size, off_t offset) const
Load data into a buffer.
Definition: ifdentry.cpp:96
int16_t id() const noexcept
id (i.e. tag) of the entry
Definition: ifdentry.hpp:209
int16_t type() const noexcept
Type of the entry data.
Definition: ifdentry.hpp:217
uint32_t count() const noexcept
The count of items in the entry.
Definition: ifdentry.hpp:223
static size_t typeUnitSize(IFD::ExifTagType _type)
Unit size for type.
Definition: ifdentry.cpp:67
std::shared_ptr< IfdEntry > Ref
IfdEntry reference (ie shared pointer)
Definition: ifdentry.hpp:202
const uint8_t * dataptr() const
Return the raw data pointer.
Definition: ifdentry.hpp:244
RawContainer::EndianType endian() const
Get the endian from the owning IfdDir.
Definition: ifdentry.cpp:91
bool loadData(size_t unit_size, off_t offset)
Load the data for the entry if m_loaded is false.
Definition: ifdentry.cpp:109
off_t offset() noexcept
The offset of the data.
Definition: ifdentry.hpp:232
EndianType
Define the endian of the container.
ExifTagType
Definition: exif.h:271
Global namespace for libopenraw.
Definition: arwfile.cpp:29
Describe an IFD type.
Definition: ifdentry.hpp:55
static const uint16_t type
Definition: ifdentry.hpp:56
static const size_t size
Definition: ifdentry.hpp:57