From cdb641b204825143dfbc224648a319e26f8dd7b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Wed, 18 Sep 2019 08:37:33 +0200 Subject: [PATCH] Properly read variable length values Code cleanup --- src/map/IMG/rgnfile.cpp | 55 +++++++++++++++++------------------------ src/map/IMG/rgnfile.h | 9 +++---- src/map/IMG/subfile.cpp | 33 +++++++++++++++++++++++++ src/map/IMG/subfile.h | 2 ++ 4 files changed, 61 insertions(+), 38 deletions(-) diff --git a/src/map/IMG/rgnfile.cpp b/src/map/IMG/rgnfile.cpp index 53618a78..812074f9 100644 --- a/src/map/IMG/rgnfile.cpp +++ b/src/map/IMG/rgnfile.cpp @@ -73,6 +73,22 @@ bool RGNFile::BitStream::readDelta(int bits, int sign, bool extraBit, 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() { while (_length--) @@ -116,23 +132,7 @@ bool RGNFile::init() return true; } -bool RGNFile::sign(BitStream &bs, int &val) -{ - 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) +static int bitSize(quint8 baseSize, bool variableSign, bool extraBit) { int bits = 2; if (baseSize <= 9) @@ -192,7 +192,7 @@ bool RGNFile::polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv, BitStream bs(*this, hdl, len); int lonSign, latSign; - if (!sign(bs, lonSign) || !sign(bs, latSign)) + if (!bs.sign(lonSign) || !bs.sign(latSign)) return false; bool extraBit = labelPtr & 0x400000; 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, QList *polys) const { - quint32 labelPtr; - quint8 type, subtype, len8, len82, bitstreamInfo; + quint32 labelPtr, len; + quint8 type, subtype, bitstreamInfo; qint16 lon, lat; - quint16 len; if (!seek(hdl, segment.start())) @@ -251,7 +250,8 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl, IMG::Poly poly; 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; if (subtype & 0x80) { @@ -259,15 +259,6 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl, 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); RectC br; @@ -279,7 +270,7 @@ bool RGNFile::extPolyObjects(const RectC &rect, Handle &hdl, BitStream bs(*this, hdl, len); int lonSign, latSign; - if (!sign(bs, lonSign) || !sign(bs, latSign)) + if (!bs.sign(lonSign) || !bs.sign(latSign)) return false; quint32 extraBit; bs.read(1, extraBit); diff --git a/src/map/IMG/rgnfile.h b/src/map/IMG/rgnfile.h index 546a9cce..2a38b5c7 100644 --- a/src/map/IMG/rgnfile.h +++ b/src/map/IMG/rgnfile.h @@ -56,11 +56,12 @@ private: class BitStream { 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) {} bool read(int bits, quint32 &val); bool readDelta(int bits, int sign, bool extraBit, qint32 &delta); + bool sign(int &val); bool hasNext(int bits) const {return _length * 8 + _remaining >= (quint32)bits;} bool finish(); @@ -68,16 +69,12 @@ private: private: const SubFile &_file; Handle &_hdl; - quint16 _length; - quint32 _remaining; + quint32 _length, _remaining; quint8 _data; }; bool init(); - static bool sign(BitStream &bs, int &val); - static int bitSize(quint8 baseSize, bool variableSign, bool extraBit); - QVector segments(Handle &hdl, const SubDiv *subdiv) const; bool polyObjects(const RectC &rect, Handle &hdl, const SubDiv *subdiv, const Segment &segment, LBLFile *lbl, Handle &lblHdl, NETFile *net, diff --git a/src/map/IMG/subfile.cpp b/src/map/IMG/subfile.cpp index 82c67dfc..f6e9ae42 100644 --- a/src/map/IMG/subfile.cpp +++ b/src/map/IMG/subfile.cpp @@ -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 { return _file ? _file->fileName() : _img->fileName(); diff --git a/src/map/IMG/subfile.h b/src/map/IMG/subfile.h index 33614857..55b2535a 100644 --- a/src/map/IMG/subfile.h +++ b/src/map/IMG/subfile.h @@ -81,6 +81,8 @@ public: return true; } + bool readVUInt32(Handle &hdl, quint32 &val) const; + quint16 offset() const {return _blocks->first();} QString fileName() const;