28#include <libopenraw/debug.h>
30#include "metavalue.hpp"
32#include "ifdfilecontainer.hpp"
33#include "ifdentry.hpp"
42IfdEntry::IfdEntry(uint16_t _id, int16_t _type,
43 int32_t _count, uint32_t _data,
44 IfdFileContainer &_container)
45 : m_id(_id), m_type(_type),
46 m_count(_count), m_data(_data),
47 m_loaded(false), m_dataptr(NULL),
48 m_container(_container)
50 auto container_size = m_container.size();
51 auto unit_size = type_unit_size(
static_cast<IFD::ExifTagType
>(m_type));
52 if ((m_count * unit_size) >
static_cast<size_t>(container_size)) {
53 LOGERR(
"Trying to have %u items in a container of %lld bytes\n",
54 m_count, (
long long int)container_size);
55 m_count = container_size / unit_size;
70void convert(Internals::IfdEntry* e, std::vector<MetaValue::value_t> & values)
72 auto result = e->getArray<T>();
74 std::vector<T> v = result.value();
75 values.insert(values.end(), v.cbegin(), v.cend());
80template <
class T,
class T2>
81void convert(Internals::IfdEntry* e, std::vector<MetaValue::value_t> & values)
83 auto result = e->getArray<T>();
85 std::vector<T> v = result.value();
86 for(
const auto & elem : v) {
87 values.push_back(T2(elem));
95size_t IfdEntry::type_unit_size(IFD::ExifTagType _type)
98 case IFD::EXIF_FORMAT_BYTE:
99 case IFD::EXIF_FORMAT_SBYTE:
100 case IFD::EXIF_FORMAT_ASCII:
101 case IFD::EXIF_FORMAT_UNDEFINED:
103 case IFD::EXIF_FORMAT_SHORT:
104 case IFD::EXIF_FORMAT_SSHORT:
106 case IFD::EXIF_FORMAT_LONG:
107 case IFD::EXIF_FORMAT_SLONG:
108 case IFD::EXIF_FORMAT_FLOAT:
110 case IFD::EXIF_FORMAT_RATIONAL:
111 case IFD::EXIF_FORMAT_SRATIONAL:
112 case IFD::EXIF_FORMAT_DOUBLE:
120 std::vector<MetaValue::value_t> values;
123 case Internals::IFD::EXIF_FORMAT_BYTE:
125 convert<uint8_t, uint32_t>(
this, values);
128 case Internals::IFD::EXIF_FORMAT_ASCII:
130 convert<std::string>(
this, values);
133 case Internals::IFD::EXIF_FORMAT_SHORT:
135 convert<uint16_t, uint32_t>(
this, values);
138 case Internals::IFD::EXIF_FORMAT_LONG:
140 convert<uint32_t>(
this, values);
143 case Internals::IFD::EXIF_FORMAT_SRATIONAL:
145 convert<Internals::IFD::SRational, double>(
this, values);
149 LOGDBG1(
"unhandled type %d\n", type());
152 return new MetaValue(values);
155RawContainer::EndianType IfdEntry::endian()
const
157 return m_container.endian();
161bool IfdEntry::loadData(
size_t unit_size)
163 bool success =
false;
164 size_t data_size = unit_size * m_count;
165 if (data_size <= 4) {
171 if (endian() == RawContainer::ENDIAN_LITTLE) {
176 _offset += m_container.exifOffsetCorrection();
177 m_dataptr = (uint8_t*)realloc(m_dataptr, data_size);
178 success = (m_container.fetchData(m_dataptr,
180 data_size) == data_size);
185uint32_t IfdEntry::getIntegerArrayItem(
int idx)
192 case IFD::EXIF_FORMAT_LONG:
195 case IFD::EXIF_FORMAT_SHORT:
198 case IFD::EXIF_FORMAT_RATIONAL:
213 catch(
const std::exception & ex) {
214 LOGERR(
"Exception raised %s fetch integer value for %d\n", ex.what(), m_id);
223Rational::operator double()
const
228 return (
double)num / (double)denom;
231SRational::operator double()
const
236 return (
double)num / (double)denom;
242const uint16_t IfdTypeTrait<uint8_t>::type = IFD::EXIF_FORMAT_BYTE;
244const size_t IfdTypeTrait<uint8_t>::size = 1;
247const uint16_t IfdTypeTrait<uint16_t>::type = IFD::EXIF_FORMAT_SHORT;
249const size_t IfdTypeTrait<uint16_t>::size = 2;
252const uint16_t IfdTypeTrait<IFD::Rational>::type = IFD::EXIF_FORMAT_RATIONAL;
254const size_t IfdTypeTrait<IFD::Rational>::size = 8;
257const uint16_t IfdTypeTrait<IFD::SRational>::type = IFD::EXIF_FORMAT_SRATIONAL;
259const size_t IfdTypeTrait<IFD::SRational>::size = 8;
263const uint16_t IfdTypeTrait<uint32_t>::type = IFD::EXIF_FORMAT_LONG;
265const size_t IfdTypeTrait<uint32_t>::size = 4;
268const uint16_t IfdTypeTrait<std::string>::type = IFD::EXIF_FORMAT_ASCII;
270const size_t IfdTypeTrait<std::string>::size = 1;
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard....