EVOLUTION-MANAGER
Edit File: xritheaderparser.cpp
/****************************************************************************** * * Purpose: Implementation of XRITHeaderParser class. Parse the header * of the combined XRIT header/data files. * Author: Bas Retsios, retsios@itc.nl * ****************************************************************************** * Copyright (c) 2007, ITC * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ******************************************************************************/ #include "cpl_port.h" // Must be first. #include "xritheaderparser.h" #include <cstdlib> // malloc, free #include <cstring> // memcpy CPL_CVSID("$Id: xritheaderparser.cpp 35929 2016-10-25 16:09:00Z goatbar $"); ////////////////////////////////////////////////////////////////////// // Construction/Destruction // // Upon successful parsing of a header in ifile, isValid() returns true // and ifile is sought to the beginning of the image data ////////////////////////////////////////////////////////////////////// XRITHeaderParser::XRITHeaderParser(std::ifstream & ifile) : m_isValid(false) , m_isPrologue(false) , m_dataSize(0) , m_nrBitsPerPixel(0) , m_nrColumns(0) , m_nrRows(0) , m_scanNorth(false) { const unsigned int probeSize = 8; unsigned char probeBuf[probeSize]; ifile.read((char*)probeBuf, probeSize); // Probe file by reading first 8 bytes if (probeBuf[0] == 0 && probeBuf[1] == 0 && probeBuf[2] == 16) // Check for primary header record { long totalHeaderLength = parseInt32(&probeBuf[4]); if ((totalHeaderLength >= 10) && (totalHeaderLength <= 10000)) // Check for valid header length { unsigned char * buf = (unsigned char*)std::malloc(totalHeaderLength); std::memcpy(buf, probeBuf, probeSize); // save what we have already read when probing ifile.read((char*)buf + probeSize, totalHeaderLength - probeSize); // read the rest of the header section parseHeader(buf, totalHeaderLength); std::free(buf); m_isValid = true; } } if (!m_isValid) // seek back to original position { #if _MSC_VER > 1000 && _MSC_VER < 1300 ifile.seekg(-probeSize, std::ios_base::seekdir::cur); #else ifile.seekg(-probeSize, std::ios_base::cur); #endif } } XRITHeaderParser::~XRITHeaderParser() {} int XRITHeaderParser::parseInt16(unsigned char * num) { return (num[0]<<8) | num[1]; } long XRITHeaderParser::parseInt32(unsigned char * num) { return (num[0]<<24) | (num[1]<<16) | (num[2]<<8) | num[3]; } void XRITHeaderParser::parseHeader(unsigned char * buf, long totalHeaderLength) { int remainingHeaderLength = static_cast<int>(totalHeaderLength); while (remainingHeaderLength > 0) { int headerType = buf[0]; int headerRecordLength = parseInt16(&buf[1]); if (headerRecordLength > remainingHeaderLength) break; switch(headerType) { case 0: // primary header { int fileTypeCode = buf[3]; // 0 = image data file, 128 = prologue if (fileTypeCode == 128) m_isPrologue = true; long dataFieldLengthH = parseInt32(&buf[8]); // length of data field in bits (High DWORD) long dataFieldLengthL = parseInt32(&buf[12]); // length of data field in bits (Low DWORD) m_dataSize = (dataFieldLengthH << 5) + (dataFieldLengthL >> 3); // combine and convert bits to bytes } break; case 1: // image structure m_nrBitsPerPixel = buf[3]; // NB, number of bits per pixel m_nrColumns = parseInt16(&buf[4]); // NC, number of columns m_nrRows = parseInt16(&buf[6]); // NL, number of lines break; case 2: // image navigation { /*long cfac =*/ parseInt32(&buf[35]); // column scaling factor long lfac = parseInt32(&buf[39]); // line scaling factor /*long coff =*/ parseInt32(&buf[43]); // column offset /*long loff =*/ parseInt32(&buf[47]); // line offset if (lfac >= 0) m_scanNorth = true; else m_scanNorth = false; } break; case 3: // image data function case 4: // annotation case 5: // time stamp case 6: // ancillary text case 7: // key header case 128: // image segment identification case 129: // encryption key message header case 130: // image compensation information header case 131: // image observation time header case 132: // image quality information header break; default: // ignore unknown header type break; } buf += headerRecordLength; remainingHeaderLength -= headerRecordLength; } }