1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-24 11:45:53 +01:00

Properly read variable length values

Code cleanup
This commit is contained in:
Martin Tůma 2019-09-18 08:37:33 +02:00
parent c2abf2c146
commit cdb641b204
4 changed files with 61 additions and 38 deletions

View File

@ -73,6 +73,22 @@ bool RGNFile::BitStream::readDelta(int bits, int sign, bool extraBit,
return true; return true;
} }
bool RGNFile::BitStream::sign(int &val)
{
quint32 bit;
val = 0;
if (!read(1, bit))
return false;
if (bit) {
if (!read(1, bit))
return false;
val = bit ? -1 : 1;
}
return true;
}
bool RGNFile::BitStream::finish() bool RGNFile::BitStream::finish()
{ {
while (_length--) while (_length--)
@ -116,23 +132,7 @@ bool RGNFile::init()
return true; return true;
} }
bool RGNFile::sign(BitStream &bs, int &val) static int bitSize(quint8 baseSize, bool variableSign, bool extraBit)
{
quint32 bit;
val = 0;
if (!bs.read(1, bit))
return false;
if (bit) {
if (!bs.read(1, bit))
return false;
val = bit ? -1 : 1;
}
return true;
}
int RGNFile::bitSize(quint8 baseSize, bool variableSign, bool extraBit)
{ {
int bits = 2; int bits = 2;
if (baseSize <= 9) if (baseSize <= 9)
@ -192,7 +192,7 @@ bool RGNFile::polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
BitStream bs(*this, hdl, len); BitStream bs(*this, hdl, len);
int lonSign, latSign; int lonSign, latSign;
if (!sign(bs, lonSign) || !sign(bs, latSign)) if (!bs.sign(lonSign) || !bs.sign(latSign))
return false; return false;
bool extraBit = labelPtr & 0x400000; bool extraBit = labelPtr & 0x400000;
int lonBits = bitSize(bitstreamInfo & 0x0F, !lonSign, extraBit); int lonBits = bitSize(bitstreamInfo & 0x0F, !lonSign, extraBit);
@ -238,10 +238,9 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
const SubDiv *subdiv, const Segment &segment, LBLFile *lbl, Handle &lblHdl, const SubDiv *subdiv, const Segment &segment, LBLFile *lbl, Handle &lblHdl,
QList<IMG::Poly> *polys) const QList<IMG::Poly> *polys) const
{ {
quint32 labelPtr; quint32 labelPtr, len;
quint8 type, subtype, len8, len82, bitstreamInfo; quint8 type, subtype, bitstreamInfo;
qint16 lon, lat; qint16 lon, lat;
quint16 len;
if (!seek(hdl, segment.start())) if (!seek(hdl, segment.start()))
@ -251,7 +250,8 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
IMG::Poly poly; IMG::Poly poly;
if (!(readByte(hdl, type) && readByte(hdl, subtype) if (!(readByte(hdl, type) && readByte(hdl, subtype)
&& readInt16(hdl, lon) && readInt16(hdl, lat) && readByte(hdl, len8))) && readInt16(hdl, lon) && readInt16(hdl, lat)
&& readVUInt32(hdl, len) && readByte(hdl, bitstreamInfo)))
return false; return false;
if (subtype & 0x80) { if (subtype & 0x80) {
@ -259,15 +259,6 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
return false; return false;
} }
if (len8 & 0x01)
len = (len8>>1) - 1;
else {
if (!readByte(hdl, len82))
return false;
len = ((len8 | ((quint16)len82<<8))>>2) - 1;
}
if (!readByte(hdl, bitstreamInfo))
return false;
poly.type = 0x10000 + (quint16(type) << 8) + (subtype & 0x1F); poly.type = 0x10000 + (quint16(type) << 8) + (subtype & 0x1F);
RectC br; RectC br;
@ -279,7 +270,7 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl,
BitStream bs(*this, hdl, len); BitStream bs(*this, hdl, len);
int lonSign, latSign; int lonSign, latSign;
if (!sign(bs, lonSign) || !sign(bs, latSign)) if (!bs.sign(lonSign) || !bs.sign(latSign))
return false; return false;
quint32 extraBit; quint32 extraBit;
bs.read(1, extraBit); bs.read(1, extraBit);

View File

@ -56,11 +56,12 @@ private:
class BitStream { class BitStream {
public: public:
BitStream(const SubFile &file, Handle &hdl, quint16 length) BitStream(const SubFile &file, Handle &hdl, quint32 length)
: _file(file), _hdl(hdl), _length(length), _remaining(0) {} : _file(file), _hdl(hdl), _length(length), _remaining(0) {}
bool read(int bits, quint32 &val); bool read(int bits, quint32 &val);
bool readDelta(int bits, int sign, bool extraBit, qint32 &delta); bool readDelta(int bits, int sign, bool extraBit, qint32 &delta);
bool sign(int &val);
bool hasNext(int bits) const bool hasNext(int bits) const
{return _length * 8 + _remaining >= (quint32)bits;} {return _length * 8 + _remaining >= (quint32)bits;}
bool finish(); bool finish();
@ -68,16 +69,12 @@ private:
private: private:
const SubFile &_file; const SubFile &_file;
Handle &_hdl; Handle &_hdl;
quint16 _length; quint32 _length, _remaining;
quint32 _remaining;
quint8 _data; quint8 _data;
}; };
bool init(); bool init();
static bool sign(BitStream &bs, int &val);
static int bitSize(quint8 baseSize, bool variableSign, bool extraBit);
QVector<Segment> segments(Handle &hdl, const SubDiv *subdiv) const; QVector<Segment> segments(Handle &hdl, const SubDiv *subdiv) const;
bool polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv, bool polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv,
const Segment &segment, LBLFile *lbl, Handle &lblHdl, NETFile *net, const Segment &segment, LBLFile *lbl, Handle &lblHdl, NETFile *net,

View File

@ -66,6 +66,39 @@ bool SubFile::readByte(Handle &handle, quint8 &val) const
} }
} }
bool SubFile::readVUInt32(Handle &hdl, quint32 &val) const
{
quint8 bytes, shift, b;
if (!readByte(hdl, b))
return false;
if ((b & 1) == 0) {
if ((b & 2) == 0) {
bytes = ((b >> 2) & 1) ^ 3;
shift = 5;
} else {
shift = 6;
bytes = 1;
}
} else {
shift = 7;
bytes = 0;
}
val = b >> (8 - shift);
for (int i = 1; i <= bytes; i++) {
if (!readByte(hdl, b))
return false;
val |= (((quint32)b) << (i * 8)) >> (8 - shift);
}
val--;
return true;
}
QString SubFile::fileName() const QString SubFile::fileName() const
{ {
return _file ? _file->fileName() : _img->fileName(); return _file ? _file->fileName() : _img->fileName();

View File

@ -81,6 +81,8 @@ public:
return true; return true;
} }
bool readVUInt32(Handle &hdl, quint32 &val) const;
quint16 offset() const {return _blocks->first();} quint16 offset() const {return _blocks->first();}
QString fileName() const; QString fileName() const;