28 #include <libopenraw/debug.h> 30 #include "metavalue.hpp" 32 #include "ifdfilecontainer.hpp" 33 #include "ifdentry.hpp" 36 using namespace Debug;
42 IfdEntry::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 %ld bytes\n",
54 m_count, container_size);
55 m_count = container_size / unit_size;
70 void convert(Internals::IfdEntry* e, std::vector<MetaValue::value_t> & values)
72 auto result = e->getArray<T>();
74 std::vector<T> v = result.unwrap();
75 values.insert(values.end(), v.cbegin(), v.cend());
80 template <
class T,
class T2>
81 void convert(Internals::IfdEntry* e, std::vector<MetaValue::value_t> & values)
83 auto result = e->getArray<T>();
85 std::vector<T> v = result.unwrap();
86 for(
const auto & elem : v) {
87 values.push_back(T2(elem));
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());
157 return m_container.endian();
163 bool success =
false;
164 size_t data_size = unit_size * m_count;
165 if (data_size <= 4) {
177 m_dataptr = (uint8_t*)realloc(m_dataptr, data_size);
178 success = (m_container.
fetchData(m_dataptr,
180 data_size) == data_size);
185 uint32_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);
223 Rational::operator double()
const 228 return (
double)num / (double)denom;
231 SRational::operator double()
const 236 return (
double)num / (double)denom;
size_t fetchData(void *buf, off_t offset, size_t buf_size)
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard. I guess it failed.
static T get(IfdEntry &e, uint32_t idx=0, bool ignore_type=false) noexcept(false)
int exifOffsetCorrection() const
static size_t type_unit_size(IFD::ExifTagType _type)
bool loadData(size_t unit_size)