mrwcontainer.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "debug.h"
00023 #include "mrwcontainer.h"
00024 #include "io/file.h"
00025
00026
00027 using namespace Debug;
00028
00029 namespace OpenRaw {
00030
00031 namespace Internals {
00032
00033 namespace MRW {
00034
00035 DataBlock::DataBlock(off_t start, MRWContainer * _container)
00036 : m_start(start),
00037 m_container(_container),
00038 m_loaded(false)
00039 {
00040 Trace(DEBUG2) << "> DataBlock start == " << start << "\n";
00041 if (m_container->fetchData (m_name, m_start, 4) != 4) {
00042
00043 Trace(WARNING) << " Error reading block name " << start << "\n";
00044 return;
00045 }
00046 if (!m_container->readInt32 (m_container->file(), m_length)) {
00047
00048 Trace(WARNING) << " Error reading block length " << start << "\n";
00049 return;
00050 }
00051 Trace(DEBUG1) << " DataBlock " << name()
00052 << ", length " << m_length
00053 << " at " << m_start << "\n";
00054 Trace(DEBUG2) << "< DataBlock\n";
00055 m_loaded = true;
00056 }
00057
00058 int8_t DataBlock::int8_val (off_t off)
00059 {
00060 int8_t ret;
00061 MRWContainer *mc = m_container;
00062 mc->file()->seek (m_start + DataBlockHeaderLength + off, SEEK_SET);
00063 mc->readInt8 (mc->file(), ret);
00064 return ret;
00065 }
00066
00067 uint8_t DataBlock::uint8_val (off_t off)
00068 {
00069 uint8_t ret;
00070 MRWContainer *mc = m_container;
00071 mc->file()->seek (m_start + DataBlockHeaderLength + off, SEEK_SET);
00072 mc->readUInt8 (mc->file(), ret);
00073 return ret;
00074 }
00075
00076 uint16_t DataBlock::uint16_val (off_t off)
00077 {
00078 uint16_t ret;
00079 MRWContainer *mc = m_container;
00080 mc->file()->seek (m_start + DataBlockHeaderLength + off, SEEK_SET);
00081 mc->readUInt16 (mc->file(), ret);
00082 return ret;
00083 }
00084
00085 std::string DataBlock::string_val(off_t off)
00086 {
00087 char buf[9];
00088 size_t s;
00089 MRWContainer *mc = m_container;
00090 s = mc->fetchData(buf, m_start + DataBlockHeaderLength + off, 8);
00091 if(s == 8) {
00092 buf[8] = 0;
00093 }
00094 else {
00095 *buf = 0;
00096 }
00097 return buf;
00098 }
00099 }
00100
00101 MRWContainer::MRWContainer(IO::Stream *_file, off_t offset)
00102 : IFDFileContainer(_file, offset)
00103 {
00104
00105 }
00106
00107
00108 MRWContainer::~MRWContainer()
00109 {
00110 }
00111
00112
00113 IFDFileContainer::EndianType
00114 MRWContainer::isMagicHeader(const char *p, int len)
00115 {
00116 if (len < 4) {
00117
00118 return ENDIAN_NULL;
00119 }
00120
00121 if ((p[0] == 0x00) && (p[1] == 'M') &&
00122 (p[2] == 'R') && (p[3] == 'M')) {
00123
00124 Trace(DEBUG1) << "Identified MRW file\n";
00125
00126 return ENDIAN_BIG;
00127 }
00128
00129 Trace(DEBUG1) << "Unidentified MRW file\n";
00130
00131 return ENDIAN_NULL;
00132 }
00133
00134 bool MRWContainer::locateDirsPreHook()
00135 {
00136 char version[9];
00137 off_t position;
00138
00139 Trace(DEBUG1) << "> MRWContainer::locateDirsPreHook()\n";
00140 m_endian = ENDIAN_BIG;
00141
00142
00143 mrm = MRW::DataBlock::Ref (new MRW::DataBlock (m_offset, this));
00144 if (mrm->name() != "MRM") {
00145 Trace(WARNING) << "MRW file begins not with MRM block, "
00146 "but with unrecognized DataBlock :: name == "
00147 << mrm->name() << "\n";
00148 return false;
00149 }
00150
00151
00152
00153
00154 position = mrm->offset() + MRW::DataBlockHeaderLength;
00155 while (position < pixelDataOffset()) {
00156 MRW::DataBlock::Ref ref (new MRW::DataBlock (position, this));
00157 Trace(DEBUG1) << "Loaded DataBlock :: name == " << ref->name() << "\n";
00158 if(!ref || !ref->loaded()) {
00159 break;
00160 }
00161 if (ref->name() == "PRD") {
00162 if (prd != NULL) {
00163 Trace(WARNING) << "File contains duplicate DataBlock :: name == "
00164 << ref->name() << "\n";
00165 }
00166 prd = ref;
00167 }
00168 else if (ref->name() == "TTW") {
00169 if (ttw != NULL) {
00170 Trace(WARNING) << "File contains duplicate DataBlock :: name == "
00171 << ref->name() << "\n";
00172 }
00173 ttw = ref;
00174 }
00175 else if (ref->name() == "WBG") {
00176 if (wbg != NULL) {
00177 Trace(WARNING) << "File contains duplicate DataBlock :: name == "
00178 << ref->name() << "\n";
00179 }
00180 wbg = ref;
00181 }
00182 else if (ref->name() == "RIF") {
00183 if (rif != NULL) {
00184 Trace(WARNING) << "File contains duplicate DataBlock :: name == "
00185 << ref->name() << "\n";
00186 }
00187 rif = ref;
00188 }
00189 else if (ref->name() != "PAD") {
00190 Trace(WARNING) << "File contains unrecognized DataBlock :: name == "
00191 << ref->name() << "\n";
00192 }
00193 position = ref->offset() + MRW::DataBlockHeaderLength + ref->length();
00194 }
00195
00196
00197 if (prd == NULL) {
00198 Trace(WARNING) << "File does NOT contain expected DataBlock :: name == PRD\n";
00199 return false;
00200 }
00201 if (ttw == NULL) {
00202 Trace(WARNING) << "File does NOT contain expected DataBlock :: name == TTW\n";
00203 return false;
00204 }
00205 if (wbg == NULL) {
00206 Trace(WARNING) << "File does NOT contain expected DataBlock :: name == WBG\n";
00207 return false;
00208 }
00209 if (rif == NULL) {
00210 Trace(WARNING) << "File does NOT contain expected DataBlock :: name == RIF\n";
00211 return false;
00212 }
00213
00214
00215 if (fetchData (version, prd->offset()+MRW::DataBlockHeaderLength+MRW::PRD_VERSION, 8) != 8) {
00216
00217 Debug::Trace(DEBUG1) << " Error reading version string\n";
00218 }
00219 version[8] = '\0';
00220 m_version = std::string (version);
00221 Trace(DEBUG1) << " MRW file version == " << m_version << "\n";
00222
00223
00224
00225
00226 m_offset = ttw->offset() + MRW::DataBlockHeaderLength;
00227 if((version[2] != '7') || (version[3] != '3')) {
00228 setExifOffsetCorrection(m_offset);
00229 Trace(DEBUG1) << "setting correction to " << m_offset << "\n";
00230 }
00231 m_file->seek (m_offset, SEEK_SET);
00232 Trace(DEBUG1) << "< MRWContainer\n";
00233
00234 return true;
00235 }
00236
00237 }
00238 }