mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Simplified pieces of code (#601)
* Simplify code in bit-twiddling methods, using APIs introduced in Java 5. * Align code by adjusting whitespace and adding `+0`. * Convert qrcode DataMask to enum to reduce source code size, which shouldn't change behavior. * Simplify lists of character constants using string initializer instead of array. * Remove redundant `+ 0` operations from a recent change. * Delete the function DataMask.forReference() and inline the logic into all its callers.
This commit is contained in:
parent
c2eb20d976
commit
7cf49565c2
|
@ -64,15 +64,11 @@ final class DecodedBitStreamParser {
|
|||
private static final int PS = 29;
|
||||
private static final int PAL = 29;
|
||||
|
||||
private static final char[] PUNCT_CHARS = {
|
||||
';', '<', '>', '@', '[', '\\', ']', '_', '`', '~', '!',
|
||||
'\r', '\t', ',', ':', '\n', '-', '.', '$', '/', '"', '|', '*',
|
||||
'(', ')', '?', '{', '}', '\''};
|
||||
private static final char[] PUNCT_CHARS =
|
||||
";<>@[\\]_`~!\r\t,:\n-.$/\"|*()?{}'".toCharArray();
|
||||
|
||||
private static final char[] MIXED_CHARS = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '&',
|
||||
'\r', '\t', ',', ':', '#', '-', '.', '$', '/', '+', '%', '*',
|
||||
'=', '^'};
|
||||
private static final char[] MIXED_CHARS =
|
||||
"0123456789&\r\t,:#-.$/+%*=^".toCharArray();
|
||||
|
||||
private static final Charset DEFAULT_ENCODING = Charset.forName("ISO-8859-1");
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ final class BitMatrixParser {
|
|||
|
||||
// Get the data mask for the format used in this QR Code. This will exclude
|
||||
// some bits from reading as we wind through the bit matrix.
|
||||
DataMask dataMask = DataMask.forReference(formatInfo.getDataMask());
|
||||
DataMask dataMask = DataMask.values()[formatInfo.getDataMask()];
|
||||
int dimension = bitMatrix.getHeight();
|
||||
dataMask.unmaskBitMatrix(bitMatrix, dimension);
|
||||
|
||||
|
@ -211,7 +211,7 @@ final class BitMatrixParser {
|
|||
if (parsedFormatInfo == null) {
|
||||
return; // We have no format information, and have no data mask
|
||||
}
|
||||
DataMask dataMask = DataMask.forReference(parsedFormatInfo.getDataMask());
|
||||
DataMask dataMask = DataMask.values()[parsedFormatInfo.getDataMask()];
|
||||
int dimension = bitMatrix.getHeight();
|
||||
dataMask.unmaskBitMatrix(bitMatrix, dimension);
|
||||
}
|
||||
|
|
|
@ -29,24 +29,96 @@ import com.google.zxing.common.BitMatrix;
|
|||
*
|
||||
* @author Sean Owen
|
||||
*/
|
||||
abstract class DataMask {
|
||||
enum DataMask {
|
||||
|
||||
/**
|
||||
* See ISO 18004:2006 6.8.1
|
||||
*/
|
||||
private static final DataMask[] DATA_MASKS = {
|
||||
new DataMask000(),
|
||||
new DataMask001(),
|
||||
new DataMask010(),
|
||||
new DataMask011(),
|
||||
new DataMask100(),
|
||||
new DataMask101(),
|
||||
new DataMask110(),
|
||||
new DataMask111(),
|
||||
|
||||
/**
|
||||
* 000: mask bits for which (x + y) mod 2 == 0
|
||||
*/
|
||||
DATA_MASK_000() {
|
||||
@Override
|
||||
boolean isMasked(int i, int j) {
|
||||
return ((i + j) & 0x01) == 0;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 001: mask bits for which x mod 2 == 0
|
||||
*/
|
||||
DATA_MASK_001() {
|
||||
@Override
|
||||
boolean isMasked(int i, int j) {
|
||||
return (i & 0x01) == 0;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 010: mask bits for which y mod 3 == 0
|
||||
*/
|
||||
DATA_MASK_010() {
|
||||
@Override
|
||||
boolean isMasked(int i, int j) {
|
||||
return j % 3 == 0;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 011: mask bits for which (x + y) mod 3 == 0
|
||||
*/
|
||||
DATA_MASK_011() {
|
||||
@Override
|
||||
boolean isMasked(int i, int j) {
|
||||
return (i + j) % 3 == 0;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 100: mask bits for which (x/2 + y/3) mod 2 == 0
|
||||
*/
|
||||
DATA_MASK_100() {
|
||||
@Override
|
||||
boolean isMasked(int i, int j) {
|
||||
return (((i / 2) + (j /3)) & 0x01) == 0;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 101: mask bits for which xy mod 2 + xy mod 3 == 0
|
||||
*/
|
||||
DATA_MASK_101() {
|
||||
@Override
|
||||
boolean isMasked(int i, int j) {
|
||||
int temp = i * j;
|
||||
return (temp & 0x01) + (temp % 3) == 0;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 110: mask bits for which (xy mod 2 + xy mod 3) mod 2 == 0
|
||||
*/
|
||||
DATA_MASK_110() {
|
||||
@Override
|
||||
boolean isMasked(int i, int j) {
|
||||
int temp = i * j;
|
||||
return (((temp & 0x01) + (temp % 3)) & 0x01) == 0;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 111: mask bits for which ((x+y)mod 2 + xy mod 3) mod 2 == 0
|
||||
*/
|
||||
DATA_MASK_111() {
|
||||
@Override
|
||||
boolean isMasked(int i, int j) {
|
||||
return ((((i + j) & 0x01) + ((i * j) % 3)) & 0x01) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
private DataMask() {
|
||||
}
|
||||
// End of enum constants.
|
||||
|
||||
|
||||
/**
|
||||
* <p>Implementations of this method reverse the data masking process applied to a QR Code and
|
||||
|
@ -67,97 +139,4 @@ abstract class DataMask {
|
|||
|
||||
abstract boolean isMasked(int i, int j);
|
||||
|
||||
/**
|
||||
* @param reference a value between 0 and 7 indicating one of the eight possible
|
||||
* data mask patterns a QR Code may use
|
||||
* @return DataMask encapsulating the data mask pattern
|
||||
*/
|
||||
static DataMask forReference(int reference) {
|
||||
if (reference < 0 || reference > 7) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return DATA_MASKS[reference];
|
||||
}
|
||||
|
||||
/**
|
||||
* 000: mask bits for which (x + y) mod 2 == 0
|
||||
*/
|
||||
private static final class DataMask000 extends DataMask {
|
||||
@Override
|
||||
boolean isMasked(int i, int j) {
|
||||
return ((i + j) & 0x01) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 001: mask bits for which x mod 2 == 0
|
||||
*/
|
||||
private static final class DataMask001 extends DataMask {
|
||||
@Override
|
||||
boolean isMasked(int i, int j) {
|
||||
return (i & 0x01) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 010: mask bits for which y mod 3 == 0
|
||||
*/
|
||||
private static final class DataMask010 extends DataMask {
|
||||
@Override
|
||||
boolean isMasked(int i, int j) {
|
||||
return j % 3 == 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 011: mask bits for which (x + y) mod 3 == 0
|
||||
*/
|
||||
private static final class DataMask011 extends DataMask {
|
||||
@Override
|
||||
boolean isMasked(int i, int j) {
|
||||
return (i + j) % 3 == 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 100: mask bits for which (x/2 + y/3) mod 2 == 0
|
||||
*/
|
||||
private static final class DataMask100 extends DataMask {
|
||||
@Override
|
||||
boolean isMasked(int i, int j) {
|
||||
return (((i / 2) + (j /3)) & 0x01) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 101: mask bits for which xy mod 2 + xy mod 3 == 0
|
||||
*/
|
||||
private static final class DataMask101 extends DataMask {
|
||||
@Override
|
||||
boolean isMasked(int i, int j) {
|
||||
int temp = i * j;
|
||||
return (temp & 0x01) + (temp % 3) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 110: mask bits for which (xy mod 2 + xy mod 3) mod 2 == 0
|
||||
*/
|
||||
private static final class DataMask110 extends DataMask {
|
||||
@Override
|
||||
boolean isMasked(int i, int j) {
|
||||
int temp = i * j;
|
||||
return (((temp & 0x01) + (temp % 3)) & 0x01) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 111: mask bits for which ((x+y)mod 2 + xy mod 3) mod 2 == 0
|
||||
*/
|
||||
private static final class DataMask111 extends DataMask {
|
||||
@Override
|
||||
boolean isMasked(int i, int j) {
|
||||
return ((((i + j) & 0x01) + ((i * j) % 3)) & 0x01) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,12 +42,8 @@ final class DecodedBitStreamParser {
|
|||
/**
|
||||
* See ISO 18004:2006, 6.4.4 Table 5
|
||||
*/
|
||||
private static final char[] ALPHANUMERIC_CHARS = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
|
||||
'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
|
||||
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
' ', '$', '%', '*', '+', '-', '.', '/', ':'
|
||||
};
|
||||
private static final char[] ALPHANUMERIC_CHARS =
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:".toCharArray();
|
||||
private static final int GB2312_SUBSET = 1;
|
||||
|
||||
private DecodedBitStreamParser() {
|
||||
|
|
|
@ -66,12 +66,6 @@ final class FormatInformation {
|
|||
{0x2BED, 0x1F},
|
||||
};
|
||||
|
||||
/**
|
||||
* Offset i holds the number of 1 bits in the binary representation of i
|
||||
*/
|
||||
private static final int[] BITS_SET_IN_HALF_BYTE =
|
||||
{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
|
||||
|
||||
private final ErrorCorrectionLevel errorCorrectionLevel;
|
||||
private final byte dataMask;
|
||||
|
||||
|
@ -83,17 +77,7 @@ final class FormatInformation {
|
|||
}
|
||||
|
||||
static int numBitsDiffering(int a, int b) {
|
||||
a ^= b; // a now has a 1 bit exactly where its bit differs with b's
|
||||
// Count bits set quickly with a series of lookups:
|
||||
return
|
||||
BITS_SET_IN_HALF_BYTE[a & 0x0F] +
|
||||
BITS_SET_IN_HALF_BYTE[(a >>> 4) & 0x0F] +
|
||||
BITS_SET_IN_HALF_BYTE[(a >>> 8) & 0x0F] +
|
||||
BITS_SET_IN_HALF_BYTE[(a >>> 12) & 0x0F] +
|
||||
BITS_SET_IN_HALF_BYTE[(a >>> 16) & 0x0F] +
|
||||
BITS_SET_IN_HALF_BYTE[(a >>> 20) & 0x0F] +
|
||||
BITS_SET_IN_HALF_BYTE[(a >>> 24) & 0x0F] +
|
||||
BITS_SET_IN_HALF_BYTE[(a >>> 28) & 0x0F];
|
||||
return Integer.bitCount(a ^ b);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -77,23 +77,23 @@ final class MaskUtil {
|
|||
byte[] arrayY = array[y]; // We can at least optimize this access
|
||||
if (x + 6 < width &&
|
||||
arrayY[x] == 1 &&
|
||||
arrayY[x + 1] == 0 &&
|
||||
arrayY[x + 2] == 1 &&
|
||||
arrayY[x + 3] == 1 &&
|
||||
arrayY[x + 4] == 1 &&
|
||||
arrayY[x + 5] == 0 &&
|
||||
arrayY[x + 6] == 1 &&
|
||||
arrayY[x + 1] == 0 &&
|
||||
arrayY[x + 2] == 1 &&
|
||||
arrayY[x + 3] == 1 &&
|
||||
arrayY[x + 4] == 1 &&
|
||||
arrayY[x + 5] == 0 &&
|
||||
arrayY[x + 6] == 1 &&
|
||||
(isWhiteHorizontal(arrayY, x - 4, x) || isWhiteHorizontal(arrayY, x + 7, x + 11))) {
|
||||
numPenalties++;
|
||||
}
|
||||
if (y + 6 < height &&
|
||||
array[y][x] == 1 &&
|
||||
array[y + 1][x] == 0 &&
|
||||
array[y + 2][x] == 1 &&
|
||||
array[y + 3][x] == 1 &&
|
||||
array[y + 4][x] == 1 &&
|
||||
array[y + 5][x] == 0 &&
|
||||
array[y + 6][x] == 1 &&
|
||||
array[y][x] == 1 &&
|
||||
array[y + 1][x] == 0 &&
|
||||
array[y + 2][x] == 1 &&
|
||||
array[y + 3][x] == 1 &&
|
||||
array[y + 4][x] == 1 &&
|
||||
array[y + 5][x] == 0 &&
|
||||
array[y + 6][x] == 1 &&
|
||||
(isWhiteVertical(array, x, y - 4, y) || isWhiteVertical(array, x, y + 7, y + 11))) {
|
||||
numPenalties++;
|
||||
}
|
||||
|
|
|
@ -271,12 +271,7 @@ final class MatrixUtil {
|
|||
// - findMSBSet(1) => 1
|
||||
// - findMSBSet(255) => 8
|
||||
static int findMSBSet(int value) {
|
||||
int numDigits = 0;
|
||||
while (value != 0) {
|
||||
value >>>= 1;
|
||||
++numDigits;
|
||||
}
|
||||
return numDigits;
|
||||
return 32 - Integer.numberOfLeadingZeros(value);
|
||||
}
|
||||
|
||||
// Calculate BCH (Bose-Chaudhuri-Hocquenghem) code for "value" using polynomial "poly". The BCH
|
||||
|
|
|
@ -106,7 +106,7 @@ public final class DataMaskTestCase extends Assert {
|
|||
}
|
||||
|
||||
private static void testMaskAcrossDimensions(int reference, MaskCondition condition) {
|
||||
DataMask mask = DataMask.forReference(reference);
|
||||
DataMask mask = DataMask.values()[reference];
|
||||
for (int version = 1; version <= 40; version++) {
|
||||
int dimension = 17 + 4 * version;
|
||||
testMask(mask, dimension, condition);
|
||||
|
|
|
@ -192,7 +192,7 @@ public final class MaskUtilTestCase extends Assert {
|
|||
{1, 0, 1, 0, 1, 0},
|
||||
{0, 1, 0, 1, 0, 1},
|
||||
};
|
||||
assertTrue(TestGetDataMaskBitInternal(0, mask0));
|
||||
assertTrue(TestGetDataMaskBitInternal(0, mask0));
|
||||
int[][] mask1 = {
|
||||
{1, 1, 1, 1, 1, 1},
|
||||
{0, 0, 0, 0, 0, 0},
|
||||
|
@ -201,7 +201,7 @@ public final class MaskUtilTestCase extends Assert {
|
|||
{1, 1, 1, 1, 1, 1},
|
||||
{0, 0, 0, 0, 0, 0},
|
||||
};
|
||||
assertTrue(TestGetDataMaskBitInternal(1, mask1));
|
||||
assertTrue(TestGetDataMaskBitInternal(1, mask1));
|
||||
int[][] mask2 = {
|
||||
{1, 0, 0, 1, 0, 0},
|
||||
{1, 0, 0, 1, 0, 0},
|
||||
|
|
Loading…
Reference in a new issue