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 }
00086
00087 MRWContainer::MRWContainer(IO::Stream *_file, off_t offset)
00088 : IFDFileContainer(_file, offset)
00089 {
00090
00091 }
00092
00093
00094 MRWContainer::~MRWContainer()
00095 {
00096 }
00097
00098
00099 IFDFileContainer::EndianType
00100 MRWContainer::isMagicHeader(const char *p, int len)
00101 {
00102 if (len < 4) {
00103
00104 return ENDIAN_NULL;
00105 }
00106
00107 if ((p[0] == 0x00) && (p[1] == 'M') &&
00108 (p[2] == 'R') && (p[3] == 'M')) {
00109
00110 Trace(DEBUG1) << "Identified MRW file\n";
00111
00112 return ENDIAN_BIG;
00113 }
00114
00115 Trace(DEBUG1) << "Unidentified MRW file\n";
00116
00117 return ENDIAN_NULL;
00118 }
00119
00120 bool MRWContainer::locateDirsPreHook()
00121 {
00122 char version[9];
00123 off_t position;
00124
00125 Trace(DEBUG1) << "> MRWContainer::locateDirsPreHook()\n";
00126 m_endian = ENDIAN_BIG;
00127
00128
00129 mrm = MRW::DataBlock::Ref (new MRW::DataBlock (m_offset, this));
00130 if (mrm->name() != "MRM") {
00131 Trace(WARNING) << "MRW file begins not with MRM block, "
00132 "but with unrecognized DataBlock :: name == "
00133 << mrm->name() << "\n";
00134 return false;
00135 }
00136
00137
00138
00139
00140 position = mrm->offset() + MRW::DataBlockHeaderLength;
00141 while (position < pixelDataOffset()) {
00142 MRW::DataBlock::Ref ref (new MRW::DataBlock (position, this));
00143 Trace(DEBUG1) << "Loaded DataBlock :: name == " << ref->name() << "\n";
00144 if(!ref || !ref->loaded()) {
00145 break;
00146 }
00147 if (ref->name() == "PRD") {
00148 if (prd != NULL) {
00149 Trace(WARNING) << "File contains duplicate DataBlock :: name == "
00150 << ref->name() << "\n";
00151 }
00152 prd = ref;
00153 }
00154 else if (ref->name() == "TTW") {
00155 if (ttw != NULL) {
00156 Trace(WARNING) << "File contains duplicate DataBlock :: name == "
00157 << ref->name() << "\n";
00158 }
00159 ttw = ref;
00160 }
00161 else if (ref->name() == "WBG") {
00162 if (wbg != NULL) {
00163 Trace(WARNING) << "File contains duplicate DataBlock :: name == "
00164 << ref->name() << "\n";
00165 }
00166 wbg = ref;
00167 }
00168 else if (ref->name() == "RIF") {
00169 if (rif != NULL) {
00170 Trace(WARNING) << "File contains duplicate DataBlock :: name == "
00171 << ref->name() << "\n";
00172 }
00173 rif = ref;
00174 }
00175 else if (ref->name() != "PAD") {
00176 Trace(WARNING) << "File contains unrecognized DataBlock :: name == "
00177 << ref->name() << "\n";
00178 }
00179 position = ref->offset() + MRW::DataBlockHeaderLength + ref->length();
00180 }
00181
00182
00183 if (prd == NULL) {
00184 Trace(WARNING) << "File does NOT contain expected DataBlock :: name == PRD\n";
00185 return false;
00186 }
00187 if (ttw == NULL) {
00188 Trace(WARNING) << "File does NOT contain expected DataBlock :: name == TTW\n";
00189 return false;
00190 }
00191 if (wbg == NULL) {
00192 Trace(WARNING) << "File does NOT contain expected DataBlock :: name == WBG\n";
00193 return false;
00194 }
00195 if (rif == NULL) {
00196 Trace(WARNING) << "File does NOT contain expected DataBlock :: name == RIF\n";
00197 return false;
00198 }
00199
00200
00201 if (fetchData (version, prd->offset()+MRW::DataBlockHeaderLength+MRW::PRD_VERSION, 8) != 8) {
00202
00203 Debug::Trace(DEBUG1) << " Error reading version string\n";
00204 }
00205 version[8] = '\0';
00206 m_version = std::string (version);
00207 Trace(DEBUG1) << " MRW file version == " << m_version << "\n";
00208
00209
00210
00211
00212 m_offset = ttw->offset() + MRW::DataBlockHeaderLength;
00213 if((version[2] != '7') || (version[3] != '3')) {
00214 setExifOffsetCorrection(m_offset);
00215 Trace(DEBUG1) << "setting correction to " << m_offset << "\n";
00216 }
00217 m_file->seek (m_offset, SEEK_SET);
00218 Trace(DEBUG1) << "< MRWContainer\n";
00219
00220 return true;
00221 }
00222
00223 }
00224 }