mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-10-07 15:23:22 +02:00
149 lines
3.6 KiB
C++
149 lines
3.6 KiB
C++
#include "bitstream.h"
|
|
#include "nodfile.h"
|
|
|
|
bool NODFile::init(Handle &hdl)
|
|
{
|
|
quint16 hdrLen;
|
|
|
|
if (!(seek(hdl, _gmpOffset) && readUInt16(hdl, hdrLen)))
|
|
return false;
|
|
|
|
if (hdrLen >= 0x7b) {
|
|
if (!(seek(hdl, _gmpOffset + 0x21) && readUInt8(hdl, _blockShift)
|
|
&& readUInt8(hdl, _nodeShift)))
|
|
return false;
|
|
if (!(seek(hdl, _gmpOffset + 0x67) && readUInt32(hdl, _blockOffset)
|
|
&& readUInt32(hdl, _blockSize) && readUInt16(hdl, _blockRecordSize)
|
|
&& readUInt32(hdl, _indexOffset) && readUInt32(hdl, _indexSize)
|
|
&& readUInt16(hdl, _indexRecordSize) && readUInt32(hdl, _indexFlags)))
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
quint32 NODFile::indexIdSize(Handle &hdl)
|
|
{
|
|
if (!_indexRecordSize && !init(hdl))
|
|
return 0;
|
|
|
|
quint32 indexCount = _indexSize / _indexRecordSize;
|
|
if (indexCount <= 0x100)
|
|
return 1;
|
|
else if (indexCount <= 0x1000)
|
|
return 2;
|
|
else if (indexCount <= 0x1000000)
|
|
return 3;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
bool NODFile::blockInfo(Handle &hdl, quint32 blockIndexId,
|
|
BlockInfo &blockInfo) const
|
|
{
|
|
quint32 blockOffset;
|
|
quint32 offset = _indexRecordSize * blockIndexId + _indexOffset;
|
|
quint32 offsetSize = (_indexFlags & 3) + 1;
|
|
|
|
|
|
Q_ASSERT(offset <= _indexOffset + _indexSize);
|
|
if (!(seek(hdl, offset) && readVUInt32(hdl, offsetSize, blockOffset)))
|
|
return false;
|
|
|
|
blockInfo.offset = (blockOffset << _blockShift) + _blockOffset;
|
|
|
|
if (!(seek(hdl, blockInfo.offset) && readUInt16(hdl, blockInfo.h0)
|
|
&& readUInt32(hdl, blockInfo.h2) && readUInt32(hdl, blockInfo.h6)
|
|
&& readUInt32(hdl, blockInfo.ha) && readUInt16(hdl, blockInfo.he)
|
|
&& readUInt8(hdl, blockInfo.h10) && readUInt8(hdl, blockInfo.h11)
|
|
&& readUInt8(hdl, blockInfo.h12)))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool NODFile::linkInfo(Handle &hdl, const BlockInfo &blockInfo, quint32 linkId,
|
|
LinkInfo &linkInfo) const
|
|
{
|
|
Q_ASSERT(linkId < blockInfo.h10);
|
|
|
|
quint32 infoOffset = ((blockInfo.he * linkId) >> 3) + 0x13
|
|
+ ((blockInfo.h0 >> 0xb) & 1) + blockInfo.offset;
|
|
quint32 s1 = ((blockInfo.h0 >> 2) & 0x1f) + 8;
|
|
quint32 s2 = (blockInfo.h0 >> 7) & 0xf;
|
|
quint32 skip = (blockInfo.he * linkId) & 7;
|
|
|
|
Q_ASSERT(infoOffset <= _blockOffset + _blockSize);
|
|
if (!seek(hdl, infoOffset))
|
|
return false;
|
|
|
|
quint32 unused, flags;
|
|
BitStream1 bs(*this, hdl, _blockOffset + _blockSize - infoOffset);
|
|
if (!(bs.read(skip, unused) && bs.read(0xc, flags)))
|
|
return false;
|
|
|
|
linkInfo.flags = ((flags << 8) & 0xf0000) | (flags & 0xff);
|
|
|
|
if (!(flags << 8 & 0x10000)) {
|
|
if (!bs.read(s1, linkInfo.linkOffset))
|
|
return false;
|
|
} else {
|
|
if (!bs.read(s1 - s2, linkInfo.linkOffset))
|
|
return false;
|
|
linkInfo.linkOffset += blockInfo.ha;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool NODFile::linkType(Handle &hdl, const BlockInfo &blockInfo, quint8 linkId,
|
|
quint32 &type) const
|
|
{
|
|
quint32 offset = ((blockInfo.h10 * blockInfo.he + 7) >> 3) + 0x13 +
|
|
blockInfo.offset + ((blockInfo.h0 >> 0xb) & 1) + (quint32)blockInfo.h11
|
|
* 3;
|
|
quint32 low = 0;
|
|
quint32 high = blockInfo.h12 - 1;
|
|
quint32 pos;
|
|
quint16 val;
|
|
|
|
if (high > 1) {
|
|
do {
|
|
pos = (low + high) / 2;
|
|
|
|
if (!seek(hdl, offset + _blockRecordSize * pos))
|
|
return false;
|
|
if (!readUInt16(hdl, val))
|
|
return false;
|
|
|
|
quint32 tmp = pos;
|
|
if ((val >> 8) <= linkId) {
|
|
low = pos;
|
|
tmp = high;
|
|
}
|
|
high = tmp;
|
|
} while (low + 1 < high);
|
|
}
|
|
|
|
if (!seek(hdl, offset + _blockRecordSize * low))
|
|
return false;
|
|
if (!readUInt16(hdl, val))
|
|
return false;
|
|
|
|
type = val & 0x3f;
|
|
|
|
if ((low < high) && (pos != high)) {
|
|
if (!seek(hdl, offset + _blockRecordSize * high))
|
|
return false;
|
|
if (!readUInt16(hdl, val))
|
|
return false;
|
|
if ((val >> 8) <= linkId) {
|
|
type = (val & 0x3f);
|
|
}
|
|
}
|
|
|
|
type *= 256;
|
|
|
|
return true;
|
|
}
|