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