gdal/frmts/msg/xritheaderparser.cpp

166 строки
6.1 KiB
C++

/******************************************************************************
*
* 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
//////////////////////////////////////////////////////////////////////
// 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
{
ifile.seekg(-static_cast<int>(probeSize), std::ios_base::cur);
}
}
XRITHeaderParser::~XRITHeaderParser()
{
}
int XRITHeaderParser::parseInt16(unsigned char *num)
{
return (num[0] << 8) | num[1];
}
long XRITHeaderParser::parseInt32(unsigned char *num)
{
int i;
memcpy(&i, num, 4);
CPL_MSBPTR32(&i);
return i;
}
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
{
#if 0
/*long cfac =*/ parseInt32(&buf[35]); // column scaling factor
#endif
long lfac = parseInt32(&buf[39]); // line scaling factor
#if 0
/*long coff =*/ parseInt32(&buf[43]); // column offset
/*long loff =*/ parseInt32(&buf[47]); // line offset
#endif
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;
}
}