diff --git a/cpp/BitBuffer.cpp b/cpp/BitBuffer.cpp index ee2d277..e22e9d3 100644 --- a/cpp/BitBuffer.cpp +++ b/cpp/BitBuffer.cpp @@ -31,14 +31,6 @@ BitBuffer::BitBuffer() : std::vector() {} -std::vector BitBuffer::getBytes() const { - std::vector result(size() / 8 + (size() % 8 == 0 ? 0 : 1)); - for (std::size_t i = 0; i < size(); i++) - result[i >> 3] |= (*this)[i] ? 1 << (7 - (i & 7)) : 0; - return result; -} - - void BitBuffer::appendBits(std::uint32_t val, int len) { if (len < 0 || len > 31 || val >> len != 0) throw std::domain_error("Value out of range"); diff --git a/cpp/BitBuffer.hpp b/cpp/BitBuffer.hpp index bccabf1..f30913a 100644 --- a/cpp/BitBuffer.hpp +++ b/cpp/BitBuffer.hpp @@ -41,12 +41,7 @@ class BitBuffer final : public std::vector { - /*---- Methods ----*/ - - // Returns a vector representing this buffer's bits packed into bytes in big endian. If the - // bit length isn't a multiple of 8, then the remaining bits of the final byte are all '0'. - public: std::vector getBytes() const; - + /*---- Method ----*/ // Appends the given number of low-order bits of the given value // to this buffer. Requires 0 <= len <= 31 and val < 2^len. diff --git a/cpp/QrCode.cpp b/cpp/QrCode.cpp index ce2de59..f6c8da6 100644 --- a/cpp/QrCode.cpp +++ b/cpp/QrCode.cpp @@ -109,8 +109,13 @@ QrCode QrCode::encodeSegments(const vector &segs, Ecc ecl, for (uint8_t padByte = 0xEC; bb.size() < dataCapacityBits; padByte ^= 0xEC ^ 0x11) bb.appendBits(padByte, 8); + // Pack bits into bytes in big endian + vector dataCodewords(bb.size() / 8); + for (size_t i = 0; i < bb.size(); i++) + dataCodewords[i >> 3] |= (bb.at(i) ? 1 : 0) << (7 - (i & 7)); + // Create the QR Code object - return QrCode(version, ecl, bb.getBytes(), mask); + return QrCode(version, ecl, dataCodewords, mask); } diff --git a/java/io/nayuki/qrcodegen/BitBuffer.java b/java/io/nayuki/qrcodegen/BitBuffer.java index 4ede5cd..624d129 100644 --- a/java/io/nayuki/qrcodegen/BitBuffer.java +++ b/java/io/nayuki/qrcodegen/BitBuffer.java @@ -77,21 +77,6 @@ public final class BitBuffer implements Cloneable { } - /** - * Returns an array representing this buffer's bits packed into bytes in big endian. If the - * bit length isn't a multiple of 8, then the remaining bits of the final byte are all '0'. - * @return a new byte array (not {@code null}) representing this bit sequence - */ - public byte[] getBytes() { - byte[] result = new byte[(bitLength + 7) >>> 3]; // Round up to whole byte, won't overflow - for (int i = 0; i < bitLength; i++) { - if (data.get(i)) - result[i >>> 3] |= 1 << (7 - (i & 7)); - } - return result; - } - - /** * Appends the specified number of low-order bits of the specified value to this * buffer. Requires 0 ≤ len ≤ 31 and 0 ≤ val < 2len. diff --git a/java/io/nayuki/qrcodegen/QrCode.java b/java/io/nayuki/qrcodegen/QrCode.java index a63b721..eba69ec 100644 --- a/java/io/nayuki/qrcodegen/QrCode.java +++ b/java/io/nayuki/qrcodegen/QrCode.java @@ -184,8 +184,13 @@ public final class QrCode { for (int padByte = 0xEC; bb.bitLength() < dataCapacityBits; padByte ^= 0xEC ^ 0x11) bb.appendBits(padByte, 8); + // Pack bits into bytes in big endian + byte[] dataCodewords = new byte[bb.bitLength() / 8]; + for (int i = 0; i < bb.bitLength(); i++) + dataCodewords[i >>> 3] |= bb.getBit(i) << (7 - (i & 7)); + // Create the QR Code object - return new QrCode(version, ecl, bb.getBytes(), mask); + return new QrCode(version, ecl, dataCodewords, mask); } diff --git a/javascript/qrcodegen.js b/javascript/qrcodegen.js index 2b4a470..b4a6d89 100644 --- a/javascript/qrcodegen.js +++ b/javascript/qrcodegen.js @@ -617,8 +617,16 @@ var qrcodegen = new function() { for (var padByte = 0xEC; bb.length < dataCapacityBits; padByte ^= 0xEC ^ 0x11) bb.appendBits(padByte, 8); + // Pack bits into bytes in big endian + var dataCodewords = []; + while (dataCodewords.length * 8 < bb.length) + dataCodewords.push(0); + bb.forEach(function(bit, i) { + dataCodewords[i >>> 3] |= bit << (7 - (i & 7)); + }); + // Create the QR Code object - return new this(version, ecl, bb.getBytes(), mask); + return new this(version, ecl, dataCodewords, mask); }; @@ -996,18 +1004,6 @@ var qrcodegen = new function() { function BitBuffer() { Array.call(this); - // Returns a new array representing this buffer's bits packed into bytes in big endian. If the - // bit length isn't a multiple of 8, then the remaining bits of the final byte are all '0'. - this.getBytes = function() { - var result = []; - while (result.length * 8 < this.length) - result.push(0); - this.forEach(function(bit, i) { - result[i >>> 3] |= bit << (7 - (i & 7)); - }); - return result; - }; - // Appends the given number of low-order bits of the given value // to this buffer. Requires 0 <= len <= 31 and 0 <= val < 2^len. this.appendBits = function(val, len) { diff --git a/python/qrcodegen.py b/python/qrcodegen.py index 51a93d0..0be9a2d 100644 --- a/python/qrcodegen.py +++ b/python/qrcodegen.py @@ -154,8 +154,13 @@ class QrCode(object): break bb.append_bits(padbyte, 8) + # Pack bits into bytes in big endian + datacodewords = [0] * (len(bb) // 8) + for (i, bit) in enumerate(bb): + datacodewords[i >> 3] |= bit << (7 - (i & 7)) + # Create the QR Code object - return QrCode(version, ecl, bb.get_bytes(), mask) + return QrCode(version, ecl, datacodewords, mask) # ---- Constructor (low level) ---- @@ -872,14 +877,6 @@ class _ReedSolomonGenerator(object): class _BitBuffer(list): """An appendable sequence of bits (0s and 1s). Mainly used by QrSegment.""" - def get_bytes(self): - """Returns a new list representing this buffer's bits packed into bytes in big endian. If the - bit length isn't a multiple of 8, then the remaining bits of the final byte are all '0'.""" - result = [0] * ((len(self) + 7) // 8) - for (i, bit) in enumerate(self): - result[i >> 3] |= bit << (7 - (i & 7)) - return result - def append_bits(self, val, n): """Appends the given number of low-order bits of the given value to this buffer. Requires n >= 0 and 0 <= val < 2^n.""" diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 8cd84c6..e17e8b0 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -182,13 +182,14 @@ impl QrCode { bb.append_bits(*padbyte, 8); } - let mut bytes = vec![0u8; bb.0.len() / 8]; + // Pack bits into bytes in big endian + let mut datacodewords = vec![0u8; bb.0.len() / 8]; for (i, bit) in bb.0.iter().enumerate() { - bytes[i >> 3] |= (*bit as u8) << (7 - (i & 7)); + datacodewords[i >> 3] |= (*bit as u8) << (7 - (i & 7)); } // Create the QR Code object - Some(QrCode::encode_codewords(version, ecl, &bytes, mask)) + Some(QrCode::encode_codewords(version, ecl, &datacodewords, mask)) } diff --git a/typescript/qrcodegen.ts b/typescript/qrcodegen.ts index 9b59dbf..20d9869 100644 --- a/typescript/qrcodegen.ts +++ b/typescript/qrcodegen.ts @@ -137,8 +137,15 @@ namespace qrcodegen { for (let padByte = 0xEC; bb.length < dataCapacityBits; padByte ^= 0xEC ^ 0x11) bb.appendBits(padByte, 8); + // Pack bits into bytes in big endian + let dataCodewords: Array = []; + while (dataCodewords.length * 8 < bb.length) + dataCodewords.push(0); + bb.forEach((b: bit, i: int) => + dataCodewords[i >>> 3] |= b << (7 - (i & 7))); + // Create the QR Code object - return new QrCode(version, ecl, bb.getBytes(), mask); + return new QrCode(version, ecl, dataCodewords, mask); } @@ -928,18 +935,6 @@ namespace qrcodegen { */ class BitBuffer extends Array { - // Returns a new array representing this buffer's bits packed into bytes in big endian. If the - // bit length isn't a multiple of 8, then the remaining bits of the final byte are all '0'. - public getBytes(): Array { - let result: Array = []; - while (result.length * 8 < this.length) - result.push(0); - this.forEach((b: bit, i: int) => - result[i >>> 3] |= b << (7 - (i & 7))); - return result; - } - - // Appends the given number of low-order bits of the given value // to this buffer. Requires 0 <= len <= 31 and 0 <= val < 2^len. public appendBits(val: int, len: int): void {