Tweaked and simplified Java, JavaScript, Python code.

This commit is contained in:
Nayuki Minase 2016-04-12 05:17:45 +00:00
parent 3c6cc5eabc
commit 53454449c4
4 changed files with 27 additions and 21 deletions

View File

@ -66,7 +66,7 @@ final class BitBuffer {
// Appends the given number of bits of the given value to this sequence. // Appends the given number of bits of the given value to this sequence.
// If 0 <= len <= 31, then this requires 0 <= val < 2^len. // If 0 <= len <= 31, then this requires 0 <= val < 2^len.
public void appendBits(int val, int len) { public void appendBits(int val, int len) {
if (len < 0 || len > 32 || len < 32 && (val & ((1 << len) - 1)) != val) if (len < 0 || len > 32 || len < 32 && (val >>> len) != 0)
throw new IllegalArgumentException("Value out of range"); throw new IllegalArgumentException("Value out of range");
ensureCapacity(bitLength + len); ensureCapacity(bitLength + len);
for (int i = len - 1; i >= 0; i--, bitLength++) // Append bit by bit for (int i = len - 1; i >= 0; i--, bitLength++) // Append bit by bit
@ -88,7 +88,7 @@ final class BitBuffer {
// Expands the buffer if necessary, so that it can hold at least the given bit length. // Expands the buffer if necessary, so that it can hold at least the given bit length.
private void ensureCapacity(int newBitLen) { private void ensureCapacity(int newBitLen) {
while (data.length < newBitLen) while (data.length * 8 < newBitLen)
data = Arrays.copyOf(data, data.length * 2); data = Arrays.copyOf(data, data.length * 2);
} }

View File

@ -613,9 +613,9 @@ public final class QrCode {
for (int y = 0; y < size - 1; y++) { for (int y = 0; y < size - 1; y++) {
for (int x = 0; x < size - 1; x++) { for (int x = 0; x < size - 1; x++) {
boolean color = modules[y][x]; boolean color = modules[y][x];
if ( color == modules[y][x + 1] && if ( color == modules[y][x + 1] &&
color == modules[y + 1][x] && color == modules[y + 1][x] &&
color == modules[y + 1][x + 1]) color == modules[y + 1][x + 1])
result += PENALTY_N2; result += PENALTY_N2;
} }
} }
@ -694,7 +694,7 @@ public final class QrCode {
result -= 64 * 3; // Subtract the three finders with separators result -= 64 * 3; // Subtract the three finders with separators
result -= 15 * 2 + 1; // Subtract the format information and black module result -= 15 * 2 + 1; // Subtract the format information and black module
result -= (size - 16) * 2; // Subtract the timing patterns result -= (size - 16) * 2; // Subtract the timing patterns
// The four lines above are equivalent to: int result = (16 * ver + 128) * ver + 64; // The five lines above are equivalent to: int result = (16 * ver + 128) * ver + 64;
if (ver >= 2) { if (ver >= 2) {
int numAlign = ver / 7 + 2; int numAlign = ver / 7 + 2;
result -= (numAlign - 1) * (numAlign - 1) * 25; // Subtract alignment patterns not overlapping with timing patterns result -= (numAlign - 1) * (numAlign - 1) * 25; // Subtract alignment patterns not overlapping with timing patterns
@ -711,6 +711,8 @@ public final class QrCode {
// QR Code of the given version number and error correction level, with remainder bits discarded. // QR Code of the given version number and error correction level, with remainder bits discarded.
// This stateless pure function could be implemented as a (40*4)-cell lookup table. // This stateless pure function could be implemented as a (40*4)-cell lookup table.
private static int getNumDataCodewords(int ver, Ecc ecl) { private static int getNumDataCodewords(int ver, Ecc ecl) {
if (ver < 1 || ver > 40)
throw new IllegalArgumentException("Version number out of range");
return getNumRawDataModules(ver) / 8 - NUM_ERROR_CORRECTION_CODEWORDS[ecl.ordinal()][ver]; return getNumRawDataModules(ver) / 8 - NUM_ERROR_CORRECTION_CODEWORDS[ecl.ordinal()][ver];
} }
@ -759,13 +761,13 @@ public final class QrCode {
// Constructor. // Constructor.
private Ecc(int fb) { private Ecc(int fb) {
formatBits = fb; formatBits = fb;
} }
} }
/*---- Private helper class ----*/ /*---- Private helper class ----*/
/** /**
* Computes the Reed-Solomon error correction codewords for a sequence of data codewords * Computes the Reed-Solomon error correction codewords for a sequence of data codewords
* at a given degree. Objects are immutable, and the state only depends on the degree. * at a given degree. Objects are immutable, and the state only depends on the degree.
@ -843,7 +845,7 @@ public final class QrCode {
// Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result // Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result
// are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8. // are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8.
private static int multiply(int x, int y) { private static int multiply(int x, int y) {
if ((x & 0xFF) != x || (y & 0xFF) != y) if (x >>> 8 != 0 || y >>> 8 != 0)
throw new IllegalArgumentException("Byte out of range"); throw new IllegalArgumentException("Byte out of range");
// Russian peasant multiplication // Russian peasant multiplication
int z = 0; int z = 0;
@ -851,7 +853,7 @@ public final class QrCode {
z = (z << 1) ^ ((z >>> 7) * 0x11D); z = (z << 1) ^ ((z >>> 7) * 0x11D);
z ^= ((y >>> i) & 1) * x; z ^= ((y >>> i) & 1) * x;
} }
if ((z & 0xFF) != z) if (z >>> 8 != 0)
throw new AssertionError(); throw new AssertionError();
return z; return z;
} }

View File

@ -566,10 +566,10 @@ var qrcodegen = new function() {
// 2*2 blocks of modules having same color // 2*2 blocks of modules having same color
for (var y = 0; y < size - 1; y++) { for (var y = 0; y < size - 1; y++) {
for (var x = 0; x < size - 1; x++) { for (var x = 0; x < size - 1; x++) {
var color = modules[y][x]; var color = modules[y][x];
if ( color == modules[y][x + 1] && if ( color == modules[y][x + 1] &&
color == modules[y + 1][x] && color == modules[y + 1][x] &&
color == modules[y + 1][x + 1]) color == modules[y + 1][x + 1])
result += QrCode.PENALTY_N2; result += QrCode.PENALTY_N2;
} }
} }
@ -658,6 +658,8 @@ var qrcodegen = new function() {
// QR Code of the given version number and error correction level, with remainder bits discarded. // QR Code of the given version number and error correction level, with remainder bits discarded.
// This stateless pure function could be implemented as a (40*4)-cell lookup table. // This stateless pure function could be implemented as a (40*4)-cell lookup table.
QrCode.getNumDataCodewords = function(ver, ecl) { QrCode.getNumDataCodewords = function(ver, ecl) {
if (ver < 1 || ver > 40)
throw "Version number out of range";
return Math.floor(QrCode.getNumRawDataModules(ver) / 8) - QrCode.NUM_ERROR_CORRECTION_CODEWORDS[ecl.ordinal][ver]; return Math.floor(QrCode.getNumRawDataModules(ver) / 8) - QrCode.NUM_ERROR_CORRECTION_CODEWORDS[ecl.ordinal][ver];
}; };
@ -890,7 +892,7 @@ var qrcodegen = new function() {
// This static function returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and // This static function returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and
// result are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8. // result are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8.
ReedSolomonGenerator.multiply = function(x, y) { ReedSolomonGenerator.multiply = function(x, y) {
if ((x & 0xFF) != x || (y & 0xFF) != y) if (x >>> 8 != 0 || y >>> 8 != 0)
throw "Byte out of range"; throw "Byte out of range";
// Russian peasant multiplication // Russian peasant multiplication
var z = 0; var z = 0;
@ -898,7 +900,7 @@ var qrcodegen = new function() {
z = (z << 1) ^ ((z >>> 7) * 0x11D); z = (z << 1) ^ ((z >>> 7) * 0x11D);
z ^= ((y >>> i) & 1) * x; z ^= ((y >>> i) & 1) * x;
} }
if ((z & 0xFF) != z) if (z >>> 8 != 0)
throw "Assertion error"; throw "Assertion error";
return z; return z;
}; };
@ -940,7 +942,7 @@ var qrcodegen = new function() {
// Appends the given number of bits of the given value to this sequence. // Appends the given number of bits of the given value to this sequence.
// If 0 <= len <= 31, then this requires 0 <= val < 2^len. // If 0 <= len <= 31, then this requires 0 <= val < 2^len.
this.appendBits = function(val, len) { this.appendBits = function(val, len) {
if (len < 0 || len > 32 || len < 32 && (val & ((1 << len) - 1)) != val) if (len < 0 || len > 32 || len < 32 && (val >>> len) != 0)
throw "Value out of range"; throw "Value out of range";
for (var i = len - 1; i >= 0; i--) // Append bit by bit for (var i = len - 1; i >= 0; i--) // Append bit by bit
bitData.push((val >>> i) & 1); bitData.push((val >>> i) & 1);

View File

@ -548,6 +548,8 @@ class QrCode(object):
"""Returns the number of 8-bit data (i.e. not error correction) codewords contained in any """Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
QR Code of the given version number and error correction level, with remainder bits discarded. QR Code of the given version number and error correction level, with remainder bits discarded.
This stateless pure function could be implemented as a (40*4)-cell lookup table.""" This stateless pure function could be implemented as a (40*4)-cell lookup table."""
if not 1 <= ver <= 40:
raise ValueError("Version number out of range")
return QrCode._get_num_raw_data_modules(ver) // 8 - QrCode._NUM_ERROR_CORRECTION_CODEWORDS[ecl.ordinal][ver] return QrCode._get_num_raw_data_modules(ver) // 8 - QrCode._NUM_ERROR_CORRECTION_CODEWORDS[ecl.ordinal][ver]
@ -588,14 +590,14 @@ class QrCode(object):
# ---- Public helper enumeration ---- # ---- Public helper enumeration ----
class Ecc(object): class Ecc(object):
"""Represents the error correction level used in a QR Code symbol.""" """Represents the error correction level used in a QR Code symbol."""
# Private constructor # Private constructor
def __init__(self, i, fb): def __init__(self, i, fb):
self.ordinal = i # In the range 0 to 3 (unsigned 2-bit integer) self.ordinal = i # In the range 0 to 3 (unsigned 2-bit integer)
self.formatbits = fb # In the range 0 to 3 (unsigned 2-bit integer) self.formatbits = fb # In the range 0 to 3 (unsigned 2-bit integer)
# Create the class constants outside the class # Create the class constants outside the class
Ecc.LOW = Ecc(0, 1) Ecc.LOW = Ecc(0, 1)
Ecc.MEDIUM = Ecc(1, 0) Ecc.MEDIUM = Ecc(1, 0)
@ -765,14 +767,14 @@ class _ReedSolomonGenerator(object):
def multiply(x, y): def multiply(x, y):
"""Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result """Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result
are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8.""" are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8."""
if x & 0xFF != x or y & 0xFF != y: if x >> 8 != 0 or y >> 8 != 0:
raise ValueError("Byte out of range") raise ValueError("Byte out of range")
# Russian peasant multiplication # Russian peasant multiplication
z = 0 z = 0
for i in reversed(range(8)): for i in reversed(range(8)):
z = (z << 1) ^ ((z >> 7) * 0x11D) z = (z << 1) ^ ((z >> 7) * 0x11D)
z ^= ((y >> i) & 1) * x z ^= ((y >> i) & 1) * x
assert z & 0xFF == z assert z >> 8 == 0
return z return z