Updated all language versions to add getBit() helper function and refactor existing arithmetic code to use it.

This commit is contained in:
Project Nayuki 2018-04-13 19:48:59 +00:00
parent 092ffb1171
commit 693304b8c3
8 changed files with 96 additions and 59 deletions

View File

@ -82,6 +82,7 @@ static long getPenaltyScore(const uint8_t qrcode[]);
testable bool getModule(const uint8_t qrcode[], int x, int y);
testable void setModule(uint8_t qrcode[], int x, int y, bool isBlack);
testable void setModuleBounded(uint8_t qrcode[], int x, int y, bool isBlack);
static bool getBit(int x, int i);
testable int calcSegmentBitLength(enum qrcodegen_Mode mode, size_t numChars);
testable int getTotalBits(const struct qrcodegen_Segment segs[], size_t len, int version);
@ -442,19 +443,19 @@ static void drawFormatBits(enum qrcodegen_Ecc ecl, enum qrcodegen_Mask mask, uin
// Draw first copy
for (int i = 0; i <= 5; i++)
setModule(qrcode, 8, i, ((data >> i) & 1) != 0);
setModule(qrcode, 8, 7, ((data >> 6) & 1) != 0);
setModule(qrcode, 8, 8, ((data >> 7) & 1) != 0);
setModule(qrcode, 7, 8, ((data >> 8) & 1) != 0);
setModule(qrcode, 8, i, getBit(data, i));
setModule(qrcode, 8, 7, getBit(data, 6));
setModule(qrcode, 8, 8, getBit(data, 7));
setModule(qrcode, 7, 8, getBit(data, 8));
for (int i = 9; i < 15; i++)
setModule(qrcode, 14 - i, 8, ((data >> i) & 1) != 0);
setModule(qrcode, 14 - i, 8, getBit(data, i));
// Draw second copy
int qrsize = qrcodegen_getSize(qrcode);
for (int i = 0; i <= 7; i++)
setModule(qrcode, qrsize - 1 - i, 8, ((data >> i) & 1) != 0);
setModule(qrcode, qrsize - 1 - i, 8, getBit(data, i));
for (int i = 8; i < 15; i++)
setModule(qrcode, 8, qrsize - 15 + i, ((data >> i) & 1) != 0);
setModule(qrcode, 8, qrsize - 15 + i, getBit(data, i));
setModule(qrcode, 8, qrsize - 8, true);
}
@ -505,7 +506,7 @@ static void drawCodewords(const uint8_t data[], int dataLen, uint8_t qrcode[]) {
bool upward = ((right + 1) & 2) == 0;
int y = upward ? qrsize - 1 - vert : vert; // Actual y coordinate
if (!getModule(qrcode, x, y) && i < dataLen * 8) {
bool black = ((data[i >> 3] >> (7 - (i & 7))) & 1) != 0;
bool black = getBit(data[i >> 3], 7 - (i & 7));
setModule(qrcode, x, y, black);
i++;
}
@ -657,9 +658,7 @@ testable bool getModule(const uint8_t qrcode[], int x, int y) {
int qrsize = qrcode[0];
assert(21 <= qrsize && qrsize <= 177 && 0 <= x && x < qrsize && 0 <= y && y < qrsize);
int index = y * qrsize + x;
int bitIndex = index & 7;
int byteIndex = (index >> 3) + 1;
return ((qrcode[byteIndex] >> bitIndex) & 1) != 0;
return getBit(qrcode[(index >> 3) + 1], index & 7);
}
@ -685,6 +684,12 @@ testable void setModuleBounded(uint8_t qrcode[], int x, int y, bool isBlack) {
}
// Returns true iff the i'th bit of x is set to 1.
static bool getBit(int x, int i) {
return ((x >> i) & 1) != 0;
}
/*---- Segment handling ----*/

View File

@ -228,18 +228,18 @@ void QrCode::drawFormatBits(int mask) {
// Draw first copy
for (int i = 0; i <= 5; i++)
setFunctionModule(8, i, ((data >> i) & 1) != 0);
setFunctionModule(8, 7, ((data >> 6) & 1) != 0);
setFunctionModule(8, 8, ((data >> 7) & 1) != 0);
setFunctionModule(7, 8, ((data >> 8) & 1) != 0);
setFunctionModule(8, i, getBit(data, i));
setFunctionModule(8, 7, getBit(data, 6));
setFunctionModule(8, 8, getBit(data, 7));
setFunctionModule(7, 8, getBit(data, 8));
for (int i = 9; i < 15; i++)
setFunctionModule(14 - i, 8, ((data >> i) & 1) != 0);
setFunctionModule(14 - i, 8, getBit(data, i));
// Draw second copy
for (int i = 0; i <= 7; i++)
setFunctionModule(size - 1 - i, 8, ((data >> i) & 1) != 0);
setFunctionModule(size - 1 - i, 8, getBit(data, i));
for (int i = 8; i < 15; i++)
setFunctionModule(8, size - 15 + i, ((data >> i) & 1) != 0);
setFunctionModule(8, size - 15 + i, getBit(data, i));
setFunctionModule(8, size - 8, true);
}
@ -258,7 +258,7 @@ void QrCode::drawVersion() {
// Draw two copies
for (int i = 0; i < 18; i++) {
bool bit = ((data >> i) & 1) != 0;
bool bit = getBit(data, i);
int a = size - 11 + i % 3, b = i / 3;
setFunctionModule(a, b, bit);
setFunctionModule(b, a, bit);
@ -351,7 +351,7 @@ void QrCode::drawCodewords(const vector<uint8_t> &data) {
bool upward = ((right + 1) & 2) == 0;
int y = upward ? size - 1 - vert : vert; // Actual y coordinate
if (!isFunction.at(y).at(x) && i < data.size() * 8) {
modules.at(y).at(x) = ((data.at(i >> 3) >> (7 - (i & 7))) & 1) != 0;
modules.at(y).at(x) = getBit(data.at(i >> 3), 7 - static_cast<int>(i & 7));
i++;
}
// If there are any remainder bits (0 to 7), they are already
@ -535,6 +535,11 @@ int QrCode::getNumDataCodewords(int ver, Ecc ecl) {
}
bool QrCode::getBit(long x, int i) {
return ((x >> i) & 1) != 0;
}
/*---- Tables of constants ----*/
const int QrCode::PENALTY_N1 = 3;

View File

@ -245,6 +245,10 @@ class QrCode final {
private: static int getNumDataCodewords(int ver, Ecc ecl);
// Returns true iff the i'th bit of x is set to 1.
private: static bool getBit(long x, int i);
/*---- Private tables of constants ----*/
// For use in getPenaltyScore(), when evaluating which mask is best.

View File

@ -99,7 +99,7 @@ public final class BitBuffer implements Cloneable {
if (len < 0 || len > 31 || val >>> len != 0)
throw new IllegalArgumentException("Value out of range");
for (int i = len - 1; i >= 0; i--, bitLength++) // Append bit by bit
data.set(bitLength, ((val >>> i) & 1) != 0);
data.set(bitLength, QrCode.getBit(val, i));
}

View File

@ -359,18 +359,18 @@ public final class QrCode {
// Draw first copy
for (int i = 0; i <= 5; i++)
setFunctionModule(8, i, ((data >>> i) & 1) != 0);
setFunctionModule(8, 7, ((data >>> 6) & 1) != 0);
setFunctionModule(8, 8, ((data >>> 7) & 1) != 0);
setFunctionModule(7, 8, ((data >>> 8) & 1) != 0);
setFunctionModule(8, i, getBit(data, i));
setFunctionModule(8, 7, getBit(data, 6));
setFunctionModule(8, 8, getBit(data, 7));
setFunctionModule(7, 8, getBit(data, 8));
for (int i = 9; i < 15; i++)
setFunctionModule(14 - i, 8, ((data >>> i) & 1) != 0);
setFunctionModule(14 - i, 8, getBit(data, i));
// Draw second copy
for (int i = 0; i <= 7; i++)
setFunctionModule(size - 1 - i, 8, ((data >>> i) & 1) != 0);
setFunctionModule(size - 1 - i, 8, getBit(data, i));
for (int i = 8; i < 15; i++)
setFunctionModule(8, size - 15 + i, ((data >>> i) & 1) != 0);
setFunctionModule(8, size - 15 + i, getBit(data, i));
setFunctionModule(8, size - 8, true);
}
@ -391,7 +391,7 @@ public final class QrCode {
// Draw two copies
for (int i = 0; i < 18; i++) {
boolean bit = ((data >>> i) & 1) != 0;
boolean bit = getBit(data, i);
int a = size - 11 + i % 3, b = i / 3;
setFunctionModule(a, b, bit);
setFunctionModule(b, a, bit);
@ -489,7 +489,7 @@ public final class QrCode {
boolean upward = ((right + 1) & 2) == 0;
int y = upward ? size - 1 - vert : vert; // Actual y coordinate
if (!isFunction[y][x] && i < data.length * 8) {
modules[y][x] = ((data[i >>> 3] >>> (7 - (i & 7))) & 1) != 0;
modules[y][x] = getBit(data[i >>> 3], 7 - (i & 7));
i++;
}
// If there are any remainder bits (0 to 7), they are already
@ -702,6 +702,12 @@ public final class QrCode {
}
// Returns true iff the i'th bit of x is set to 1.
static boolean getBit(int x, int i) {
return ((x >>> i) & 1) != 0;
}
/*---- Private tables of constants ----*/
// For use in getPenaltyScore(), when evaluating which mask is best.

View File

@ -250,18 +250,18 @@ var qrcodegen = new function() {
// Draw first copy
for (var i = 0; i <= 5; i++)
setFunctionModule(8, i, ((data >>> i) & 1) != 0);
setFunctionModule(8, 7, ((data >>> 6) & 1) != 0);
setFunctionModule(8, 8, ((data >>> 7) & 1) != 0);
setFunctionModule(7, 8, ((data >>> 8) & 1) != 0);
setFunctionModule(8, i, getBit(data, i));
setFunctionModule(8, 7, getBit(data, 6));
setFunctionModule(8, 8, getBit(data, 7));
setFunctionModule(7, 8, getBit(data, 8));
for (var i = 9; i < 15; i++)
setFunctionModule(14 - i, 8, ((data >>> i) & 1) != 0);
setFunctionModule(14 - i, 8, getBit(data, i));
// Draw second copy
for (var i = 0; i <= 7; i++)
setFunctionModule(size - 1 - i, 8, ((data >>> i) & 1) != 0);
setFunctionModule(size - 1 - i, 8, getBit(data, i));
for (var i = 8; i < 15; i++)
setFunctionModule(8, size - 15 + i, ((data >>> i) & 1) != 0);
setFunctionModule(8, size - 15 + i, getBit(data, i));
setFunctionModule(8, size - 8, true);
}
@ -282,7 +282,7 @@ var qrcodegen = new function() {
// Draw two copies
for (var i = 0; i < 18; i++) {
var bit = ((data >>> i) & 1) != 0;
var bit = getBit(data, i);
var a = size - 11 + i % 3, b = Math.floor(i / 3);
setFunctionModule(a, b, bit);
setFunctionModule(b, a, bit);
@ -381,7 +381,7 @@ var qrcodegen = new function() {
var upward = ((right + 1) & 2) == 0;
var y = upward ? size - 1 - vert : vert; // Actual y coordinate
if (!isFunction[y][x] && i < data.length * 8) {
modules[y][x] = ((data[i >>> 3] >>> (7 - (i & 7))) & 1) != 0;
modules[y][x] = getBit(data[i >>> 3], 7 - (i & 7));
i++;
}
// If there are any remainder bits (0 to 7), they are already
@ -499,6 +499,12 @@ var qrcodegen = new function() {
result += QrCode.PENALTY_N4;
return result;
}
// Returns true iff the i'th bit of x is set to 1.
function getBit(x, i) {
return ((x >>> i) & 1) != 0;
}
};

View File

@ -279,18 +279,18 @@ class QrCode(object):
# Draw first copy
for i in range(0, 6):
self._set_function_module(8, i, (data >> i) & 1 != 0)
self._set_function_module(8, 7, (data >> 6) & 1 != 0)
self._set_function_module(8, 8, (data >> 7) & 1 != 0)
self._set_function_module(7, 8, (data >> 8) & 1 != 0)
self._set_function_module(8, i, _get_bit(data, i))
self._set_function_module(8, 7, _get_bit(data, 6))
self._set_function_module(8, 8, _get_bit(data, 7))
self._set_function_module(7, 8, _get_bit(data, 8))
for i in range(9, 15):
self._set_function_module(14 - i, 8, (data >> i) & 1 != 0)
self._set_function_module(14 - i, 8, _get_bit(data, i))
# Draw second copy
for i in range(0, 8):
self._set_function_module(self._size - 1 - i, 8, (data >> i) & 1 != 0)
self._set_function_module(self._size - 1 - i, 8, _get_bit(data, i))
for i in range(8, 15):
self._set_function_module(8, self._size - 15 + i, (data >> i) & 1 != 0)
self._set_function_module(8, self._size - 15 + i, _get_bit(data, i))
self._set_function_module(8, self._size - 8, True)
@ -309,7 +309,7 @@ class QrCode(object):
# Draw two copies
for i in range(18):
bit = (data >> i) & 1 != 0
bit = _get_bit(data, i)
a, b = self._size - 11 + i % 3, i // 3
self._set_function_module(a, b, bit)
self._set_function_module(b, a, bit)
@ -396,7 +396,7 @@ class QrCode(object):
upward = (right + 1) & 2 == 0
y = (self._size - 1 - vert) if upward else vert # Actual y coordinate
if not self._isfunction[y][x] and i < len(data) * 8:
self._modules[y][x] = (data[i >> 3] >> (7 - (i & 7))) & 1 != 0
self._modules[y][x] = _get_bit(data[i >> 3], 7 - (i & 7))
i += 1
# If there are any remainder bits (0 to 7), they are already
# set to 0/false/white when the grid of modules was initialized
@ -834,3 +834,8 @@ class _BitBuffer(list):
if n < 0 or val >> n != 0:
raise ValueError("Value out of range")
self.extend(((val >> i) & 1) for i in reversed(range(n)))
def _get_bit(x, i):
"""Returns true iff the i'th bit of x is set to 1."""
return (x >> i) & 1 != 0

View File

@ -315,21 +315,21 @@ impl QrCode {
// Draw first copy
for i in 0 .. 6 {
self.set_function_module(8, i, (data >> i) & 1 != 0);
self.set_function_module(8, i, get_bit(data, i));
}
self.set_function_module(8, 7, (data >> 6) & 1 != 0);
self.set_function_module(8, 8, (data >> 7) & 1 != 0);
self.set_function_module(7, 8, (data >> 8) & 1 != 0);
self.set_function_module(8, 7, get_bit(data, 6));
self.set_function_module(8, 8, get_bit(data, 7));
self.set_function_module(7, 8, get_bit(data, 8));
for i in 9 .. 15 {
self.set_function_module(14 - i, 8, (data >> i) & 1 != 0);
self.set_function_module(14 - i, 8, get_bit(data, i));
}
// Draw second copy
for i in 0 .. 8 {
self.set_function_module(size - 1 - i, 8, (data >> i) & 1 != 0);
self.set_function_module(size - 1 - i, 8, get_bit(data, i));
}
for i in 8 .. 15 {
self.set_function_module(8, size - 15 + i, (data >> i) & 1 != 0);
self.set_function_module(8, size - 15 + i, get_bit(data, i));
}
self.set_function_module(8, size - 8, true);
}
@ -352,7 +352,7 @@ impl QrCode {
// Draw two copies
for i in 0 .. 18 {
let bit: bool = (data >> i) & 1 != 0;
let bit: bool = get_bit(data, i);
let a: i32 = self.size - 11 + i % 3;
let b: i32 = i / 3;
self.set_function_module(a, b, bit);
@ -458,7 +458,7 @@ impl QrCode {
let upward: bool = (right + 1) & 2 == 0;
let y: i32 = if upward { self.size - 1 - vert } else { vert }; // Actual y coordinate
if !self.isfunction[(y * self.size + x) as usize] && i < data.len() * 8 {
*self.module_mut(x, y) = (data[i >> 3] >> (7 - (i & 7))) & 1 != 0;
*self.module_mut(x, y) = get_bit(data[i >> 3] as u32, 7 - ((i & 7) as i32));
i += 1;
}
// If there are any remainder bits (0 to 7), they are already
@ -1081,8 +1081,8 @@ impl BitBuffer {
// to this sequence. Requires 0 <= val < 2^len.
pub fn append_bits(&mut self, val: u32, len: u8) {
assert!(len < 32 && (val >> len) == 0 || len == 32, "Value out of range");
for i in (0 .. len).rev() { // Append bit by bit
self.0.push((val >> i) & 1 != 0);
for i in (0 .. len as i32).rev() { // Append bit by bit
self.0.push(get_bit(val, i));
}
}
}
@ -1119,3 +1119,9 @@ impl Mask {
self.0
}
}
// Returns true iff the i'th bit of x is set to 1.
fn get_bit(x: u32, i: i32) -> bool {
(x >> i) & 1 != 0
}