aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier <dev.git@javispedro.com>2015-06-15 15:41:05 +0200
committerJavier <dev.git@javispedro.com>2015-06-15 15:41:05 +0200
commit08fbafb85b54adbbdfb12b06155e6d330fec9bb7 (patch)
tree93252d74c58f17a2201902ac3ca3f5ff2be37873
parent16158add8ffeb1f38855c3c01dafb436d6e8d8f1 (diff)
downloadscribiu-08fbafb85b54adbbdfb12b06155e6d330fec9bb7.tar.gz
scribiu-08fbafb85b54adbbdfb12b06155e6d330fec9bb7.zip
fix missing sign extension
-rw-r--r--bitreader.cc23
-rw-r--r--bitreader.h2
-rw-r--r--stfreader.cc4
3 files changed, 27 insertions, 2 deletions
diff --git a/bitreader.cc b/bitreader.cc
index dc92223..8b78bb7 100644
--- a/bitreader.cc
+++ b/bitreader.cc
@@ -18,6 +18,17 @@
#include "bitreader.h"
+namespace
+{
+inline qint64 signExtend(quint64 x, int n)
+{
+ if (n < 64 && (x & (1 << (n-1)))) {
+ x |= -(1LL << n);
+ }
+ return x;
+}
+}
+
BitReader::BitReader(QIODevice *device)
: child(device), buf(0), avail(0)
{
@@ -38,6 +49,12 @@ quint64 BitReader::readBits(int n)
return x;
}
+qint64 BitReader::readSignedBits(int n)
+{
+ quint64 x = readBits(n);
+ return signExtend(x, n);
+}
+
quint64 BitReader::peekBits(int n)
{
while (n > avail) {
@@ -51,6 +68,12 @@ quint64 BitReader::peekBits(int n)
return x;
}
+qint64 BitReader::peekSignedBits(int n)
+{
+ quint64 x = peekBits(n);
+ return signExtend(x, n);
+}
+
void BitReader::skipUntilNextByte()
{
int skip = avail % 8;
diff --git a/bitreader.h b/bitreader.h
index c5ebf3f..327bc04 100644
--- a/bitreader.h
+++ b/bitreader.h
@@ -28,7 +28,9 @@ public:
~BitReader();
quint64 readBits(int n);
+ qint64 readSignedBits(int n);
quint64 peekBits(int n);
+ qint64 peekSignedBits(int n);
void skipUntilNextByte();
diff --git a/stfreader.cc b/stfreader.cc
index 7d78635..09967cc 100644
--- a/stfreader.cc
+++ b/stfreader.cc
@@ -130,8 +130,8 @@ bool StfReader::parseV1(BitReader& br)
pa = p1 - p0;
} else {
do_delta = true;
- delta.setX(br.readBits(8));
- delta.setY(br.readBits(8));
+ delta.setX(br.readSignedBits(8));
+ delta.setY(br.readSignedBits(8));
}
} else {
do_delta = true;