diff --git a/src/map/IMG/huffmanstream.cpp b/src/map/IMG/huffmanstream.cpp index 084f6999..f3b8b746 100644 --- a/src/map/IMG/huffmanstream.cpp +++ b/src/map/IMG/huffmanstream.cpp @@ -2,7 +2,7 @@ using namespace IMG; -bool HuffmanStreamF::init(bool line) +bool HuffmanDeltaStreamF::init(bool line) { if (line) { if (!(sign(_lonSign) && sign(_latSign))) @@ -13,7 +13,7 @@ bool HuffmanStreamF::init(bool line) } quint32 eb; - if (!_bs.read(1, eb)) + if (!read(1, eb)) return false; Q_ASSERT(!eb); @@ -23,7 +23,7 @@ bool HuffmanStreamF::init(bool line) return true; } -bool HuffmanStreamR::init() +bool HuffmanDeltaStreamR::init() { if (!(sign(_lonSign) && sign(_latSign))) return false; @@ -31,13 +31,13 @@ bool HuffmanStreamR::init() return true; } -bool HuffmanStreamR::init(int lonSign, int latSign, quint32 data, - quint32 dataSize) +bool HuffmanDeltaStreamR::init(quint32 data, quint32 dataSize) { - _lonSign = lonSign; - _latSign = latSign; _symbolData = data; _symbolDataSize = dataSize; + if (!(sign(_lonSign) && sign(_latSign))) + return false; + return true; } diff --git a/src/map/IMG/huffmanstream.h b/src/map/IMG/huffmanstream.h index c1f92e93..0dcc7ea8 100644 --- a/src/map/IMG/huffmanstream.h +++ b/src/map/IMG/huffmanstream.h @@ -10,51 +10,24 @@ template class HuffmanStream { public: HuffmanStream(BitStream &bitstream, const HuffmanTable &table) - : _bs(bitstream), _table(table), _symbolDataSize(0), _symbolData(0), - _lonSign(0), _latSign(0) {} + : _symbolDataSize(0), _symbolData(0), _bs(bitstream), _table(table) {} bool read(int bits, quint32 &val); bool readSymbol(quint32 &symbol); - bool readNext(qint32 &lonDelta, qint32 &latDelta) - { - if (!(readDelta(_lonSign, lonDelta) && readDelta(_latSign, latDelta))) - return false; - - return (lonDelta || latDelta); - } bool atEnd() const {return _symbolDataSize + _bs.bitsAvailable() < _table.symBits();} bool flush() {return _bs.flush();} protected: - bool sign(int &val); - bool readDelta(int sign, qint32 &delta); - - BitStream &_bs; - const HuffmanTable &_table; quint32 _symbolDataSize; quint32 _symbolData; - int _lonSign, _latSign; + +private: + BitStream &_bs; + const HuffmanTable &_table; }; -template -bool HuffmanStream::sign(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; -} - template bool HuffmanStream::read(int bits, quint32 &val) { @@ -102,18 +75,58 @@ bool HuffmanStream::readSymbol(quint32 &symbol) } template -bool HuffmanStream::readDelta(int sign, qint32 &delta) +class HuffmanDeltaStream : public HuffmanStream +{ +public: + HuffmanDeltaStream(BitStream &bitstream, const HuffmanTable &table) + : HuffmanStream(bitstream, table), _lonSign(0), _latSign(0) {} + + bool readNext(qint32 &lonDelta, qint32 &latDelta) + { + if (!(readDelta(_lonSign, lonDelta) && readDelta(_latSign, latDelta))) + return false; + + return (lonDelta || latDelta); + } + +protected: + bool sign(int &val); + bool readDelta(int sign, qint32 &delta); + + int _lonSign, _latSign; +}; + +template +bool HuffmanDeltaStream::sign(int &val) +{ + quint32 bit; + val = 0; + + if (!this->read(1, bit)) + return false; + if (bit) { + if (!this->read(1, bit)) + return false; + val = bit ? -1 : 1; + } + + return true; +} + +template +bool HuffmanDeltaStream::readDelta(int sign, qint32 &delta) { quint32 symbol; - if (!readSymbol(symbol)) + if (!this->readSymbol(symbol)) return false; if (symbol && !sign) { - if (!_symbolDataSize) + if (!this->_symbolDataSize) return false; else { - sign = ((1U << (_symbolDataSize - 1)) & _symbolData) ? -1 : 1; - _symbolDataSize--; + sign = ((1U << (this->_symbolDataSize - 1)) & this->_symbolData) + ? -1 : 1; + this->_symbolDataSize--; } } delta = sign * symbol; @@ -121,23 +134,23 @@ bool HuffmanStream::readDelta(int sign, qint32 &delta) return true; } -class HuffmanStreamF : public HuffmanStream { +class HuffmanDeltaStreamF : public HuffmanDeltaStream { public: - HuffmanStreamF(BitStream4F &bitstream, const HuffmanTable &table) - : HuffmanStream(bitstream, table) {} + HuffmanDeltaStreamF(BitStream4F &bitstream, const HuffmanTable &table) + : HuffmanDeltaStream(bitstream, table) {} bool init(bool line); bool readOffset(qint32 &lonDelta, qint32 &latDelta) {return (readDelta(1, lonDelta) && readDelta(1, latDelta));} }; -class HuffmanStreamR : public HuffmanStream { +class HuffmanDeltaStreamR : public HuffmanDeltaStream { public: - HuffmanStreamR(BitStream4R &bitstream, const HuffmanTable &table) - : HuffmanStream(bitstream, table) {} + HuffmanDeltaStreamR(BitStream4R &bitstream, const HuffmanTable &table) + : HuffmanDeltaStream(bitstream, table) {} bool init(); - bool init(int lonSign, int latSign, quint32 data, quint32 dataSize); + bool init(quint32 data, quint32 dataSize); }; } diff --git a/src/map/IMG/netfile.cpp b/src/map/IMG/netfile.cpp index 62c3377e..8d3af3d0 100644 --- a/src/map/IMG/netfile.cpp +++ b/src/map/IMG/netfile.cpp @@ -116,7 +116,7 @@ static bool readLine(BitStream4R &bs, const SubDiv *subdiv, poly.boundingRect = RectC(c, c); poly.points.append(QPointF(c.lon(), c.lat())); - HuffmanStreamR stream(bs, *table); + HuffmanDeltaStreamR stream(bs, *table); if (!stream.init()) return false; qint32 lonDelta, latDelta; @@ -164,18 +164,6 @@ static bool skipNodes(const NODFile *nod, SubFile::Handle &nodHdl, return true; } -static int sign(quint32 flags, quint32 &bits) -{ - if (!((flags >> bits) & 1)) { - bits--; - return 0; - } else { - quint32 sb = bits - 1; - bits -= 2; - return ((flags >> sb) & 1) ? -1 : 1; - } -} - static bool readShape(const NODFile *nod, SubFile::Handle &nodHdl, NODFile::AdjacencyInfo &adj, BitStream4R &bs, const HuffmanTable *table, const SubDiv *subdiv, quint32 shift, MapData::Poly &poly, @@ -197,12 +185,8 @@ static bool readShape(const NODFile *nod, SubFile::Handle &nodHdl, bool startWithStream = flags & (1 << (v2b + 6)); bool useEosBit = flags & (1 << (v2b + 5)); - quint32 extraBits = v2b + 4; - int lonSign = sign(flags, extraBits); - int latSign = sign(flags, extraBits); - - HuffmanStreamR stream(bs, *table); - if (!stream.init(lonSign, latSign, flags, extraBits + 1)) + HuffmanDeltaStreamR stream(bs, *table); + if (!stream.init(flags, v2b + 5)) return false; diff --git a/src/map/IMG/rgnfile.cpp b/src/map/IMG/rgnfile.cpp index 0e48cadd..d345032c 100644 --- a/src/map/IMG/rgnfile.cpp +++ b/src/map/IMG/rgnfile.cpp @@ -287,7 +287,7 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift, qint32 lonDelta, latDelta; BitStream4F bs(*this, hdl, len); - HuffmanStreamF stream(bs, *_huffmanTable); + HuffmanDeltaStreamF stream(bs, *_huffmanTable); if (!stream.init(segmentType == Line)) return false;