libopenraw
|
00001 /* 00002 * libopenraw - ifdentry.cpp 00003 * 00004 * Copyright (C) 2006-2008 Hubert Figuiere 00005 * 00006 * This library is free software: you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public License 00008 * as published by the Free Software Foundation, either version 3 of 00009 * the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library. If not, see 00018 * <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 00022 #include <cassert> 00023 #include <string> 00024 00025 #include "exception.h" 00026 #include "endianutils.h" 00027 00028 #include "ifdfilecontainer.h" 00029 #include "ifdentry.h" 00030 #include "ifd.h" 00031 00032 namespace OpenRaw { 00033 namespace Internals { 00034 00035 00036 IFDEntry::IFDEntry(uint16_t _id, int16_t _type, 00037 int32_t _count, uint32_t _data, 00038 IFDFileContainer &_container) 00039 : m_id(_id), m_type(_type), 00040 m_count(_count), m_data(_data), 00041 m_loaded(false), m_dataptr(NULL), 00042 m_container(_container) 00043 { 00044 } 00045 00046 00047 IFDEntry::~IFDEntry() 00048 { 00049 if (m_dataptr) { 00050 free(m_dataptr); 00051 } 00052 } 00053 00054 RawContainer::EndianType IFDEntry::endian() const 00055 { 00056 return m_container.endian(); 00057 } 00058 00059 00060 bool IFDEntry::loadData(size_t unit_size) 00061 { 00062 bool success = false; 00063 size_t data_size = unit_size * m_count; 00064 if (data_size <= 4) { 00065 m_dataptr = NULL; 00066 success = true; 00067 } 00068 else { 00069 off_t _offset; 00070 if (endian() == RawContainer::ENDIAN_LITTLE) { 00071 _offset = IFDTypeTrait<uint32_t>::EL((uint8_t*)&m_data); 00072 } 00073 else { 00074 _offset = IFDTypeTrait<uint32_t>::BE((uint8_t*)&m_data); 00075 } 00076 m_dataptr = (uint8_t*)realloc(m_dataptr, data_size); 00077 success = (m_container.fetchData(m_dataptr, 00078 _offset, 00079 data_size) == data_size); 00080 } 00081 return success; 00082 } 00083 00084 template <> 00085 const uint16_t IFDTypeTrait<uint8_t>::type = IFD::EXIF_FORMAT_BYTE; 00086 template <> 00087 const size_t IFDTypeTrait<uint8_t>::size = 1; 00088 00089 template <> 00090 const uint16_t IFDTypeTrait<uint16_t>::type = IFD::EXIF_FORMAT_SHORT; 00091 template <> 00092 const size_t IFDTypeTrait<uint16_t>::size = 2; 00093 00094 #if defined(__APPLE_CC__) 00095 // Apple broken g++ version or linker seems to choke. 00096 template <> 00097 const uint16_t IFDTypeTrait<unsigned long>::type = IFD::EXIF_FORMAT_LONG; 00098 template <> 00099 const size_t IFDTypeTrait<unsigned long>::size = 4; 00100 #endif 00101 template <> 00102 const uint16_t IFDTypeTrait<uint32_t>::type = IFD::EXIF_FORMAT_LONG; 00103 template <> 00104 const size_t IFDTypeTrait<uint32_t>::size = 4; 00105 00106 template <> 00107 const uint16_t IFDTypeTrait<std::string>::type = IFD::EXIF_FORMAT_ASCII; 00108 template <> 00109 const size_t IFDTypeTrait<std::string>::size = 1; 00110 } 00111 }