mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-06-01 14:22:41 -06:00
154 lines
5.4 KiB
C++
154 lines
5.4 KiB
C++
/******************************************************************************
|
|
* $Id: xritheaderparser.cpp 15066 2008-07-28 20:21:59Z mloskot $
|
|
*
|
|
* 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 "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 seeked 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 = 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;
|
|
}
|
|
}
|