forked from I2P_Developers/i2p.i2p
Zxing 3.3.0
This commit is contained in:
@@ -207,7 +207,7 @@ Applications:
|
||||
Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
Copyright (c) 2008 Alexander von Gernler. All rights reserved.
|
||||
See licenses/LICENSE-BSD.txt
|
||||
Zxing:
|
||||
Zxing 3.3.0:
|
||||
See licenses/LICENSE-Apache2.0.txt
|
||||
|
||||
Jetty 8.1.21.v20160908:
|
||||
|
||||
@@ -355,3 +355,11 @@
|
||||
3.2.1 (20 Aug 2015)
|
||||
|
||||
- Small bug fixes
|
||||
|
||||
3.3.0 (16 Sep 2016)
|
||||
|
||||
- Minor core API additions like 'Result.getNumBits', raw bytes for Aztec
|
||||
- Small changes for Java 9 compatibility
|
||||
- BS 4.7.6 release with Android API 23 support
|
||||
- TIFF support in online decoder
|
||||
- Many small bug fixes, typo fixes and project build improvements
|
||||
|
||||
@@ -2,5 +2,4 @@ This is a small portion of zxing, including only what's required
|
||||
to generate QR codes. There are no modifications.
|
||||
We've added a build.xml for ant.
|
||||
|
||||
Pulled from https://github.com/zxing/zxing on Jan. 4, 2016,
|
||||
rev 4e3abafe3008e02695f894eccf05f8257fca4ee9 dated Dec. 9, 2015.
|
||||
https://github.com/zxing/zxing/releases Version 3.3.0 Sept. 16, 2016
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<img align="right" src="https://raw.github.com/wiki/zxing/zxing/zxing-logo.png"/>
|
||||
|
||||
##Get Started Developing
|
||||
To get started, please visit: https://github.com/zxing/zxing/wiki/Getting-Started-Developing
|
||||
|
||||
ZXing ("zebra crossing") is an open-source, multi-format 1D/2D barcode image processing
|
||||
library implemented in Java, with ports to other languages.
|
||||
|
||||
@@ -50,6 +53,7 @@ library implemented in Java, with ports to other languages.
|
||||
| [zxing_cpp.rb](https://github.com/glassechidna/zxing_cpp.rb) | bindings for Ruby (not just JRuby), powered by [zxing-cpp](https://github.com/glassechidna/zxing-cpp)
|
||||
| [python-zxing](https://github.com/oostendo/python-zxing) | bindings for Python
|
||||
| [ZXing .NET](http://zxingnet.codeplex.com/) | port to .NET and C#, and related Windows platform
|
||||
| [php-qrcode-detector-decoder](https://github.com/khanamiryan/php-qrcode-detector-decoder) | port to PHP
|
||||
|
||||
### Other related third-party open source projects
|
||||
|
||||
@@ -61,11 +65,10 @@ library implemented in Java, with ports to other languages.
|
||||
|
||||
## Links
|
||||
|
||||
* [Online Decoder](http://zxing.org/w/decode.jspx)
|
||||
* [QR Code Generator](http://zxing.appspot.com/generator)
|
||||
* [Javadoc](http://zxing.github.io/zxing/apidocs/)
|
||||
* [Documentation Site](http://zxing.github.io/zxing/)
|
||||
* [Google+](https://plus.google.com/u/0/b/105889184633382354358/105889184633382354358/posts)
|
||||
* [Online Decoder](https://zxing.org/w/decode.jspx)
|
||||
* [QR Code Generator](https://zxing.appspot.com/generator)
|
||||
* [Javadoc](https://zxing.github.io/zxing/apidocs/)
|
||||
* [Documentation Site](https://zxing.github.io/zxing/)
|
||||
|
||||
## Contacting
|
||||
|
||||
|
||||
@@ -95,4 +95,10 @@ public enum EncodeHintType {
|
||||
* (Type {@link Integer}, or {@link String} representation of the integer value).
|
||||
*/
|
||||
AZTEC_LAYERS,
|
||||
|
||||
/**
|
||||
* Specifies the exact version of QR code to be encoded.
|
||||
* (Type {@link Integer}, or {@link String} representation of the integer value).
|
||||
*/
|
||||
QR_VERSION,
|
||||
}
|
||||
|
||||
@@ -39,10 +39,8 @@ public abstract class ReaderException extends Exception {
|
||||
}
|
||||
|
||||
// Prevent stack traces from being taken
|
||||
// srowen says: huh, my IDE is saying this is not an override. native methods can't be overridden?
|
||||
// This, at least, does not hurt. Because we use a singleton pattern here, it doesn't matter anyhow.
|
||||
@Override
|
||||
public final Throwable fillInStackTrace() {
|
||||
public final synchronized Throwable fillInStackTrace() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ public final class BitArray implements Cloneable {
|
||||
* @param end end of range, exclusive
|
||||
*/
|
||||
public void setRange(int start, int end) {
|
||||
if (end < start) {
|
||||
if (end < start || start < 0 || end > size) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (end == start) {
|
||||
@@ -163,15 +163,8 @@ public final class BitArray implements Cloneable {
|
||||
for (int i = firstInt; i <= lastInt; i++) {
|
||||
int firstBit = i > firstInt ? 0 : start & 0x1F;
|
||||
int lastBit = i < lastInt ? 31 : end & 0x1F;
|
||||
int mask;
|
||||
if (firstBit == 0 && lastBit == 31) {
|
||||
mask = -1;
|
||||
} else {
|
||||
mask = 0;
|
||||
for (int j = firstBit; j <= lastBit; j++) {
|
||||
mask |= 1 << j;
|
||||
}
|
||||
}
|
||||
// Ones from firstBit to lastBit, inclusive
|
||||
int mask = (2 << lastBit) - (1 << firstBit);
|
||||
bits[i] |= mask;
|
||||
}
|
||||
}
|
||||
@@ -193,10 +186,10 @@ public final class BitArray implements Cloneable {
|
||||
* @param end end of range, exclusive
|
||||
* @param value if true, checks that bits in range are set, otherwise checks that they are not set
|
||||
* @return true iff all bits are set or not set in range, according to value argument
|
||||
* @throws IllegalArgumentException if end is less than or equal to start
|
||||
* @throws IllegalArgumentException if end is less than start or the range is not contained in the array
|
||||
*/
|
||||
public boolean isRange(int start, int end, boolean value) {
|
||||
if (end < start) {
|
||||
if (end < start || start < 0 || end > size) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (end == start) {
|
||||
@@ -208,15 +201,8 @@ public final class BitArray implements Cloneable {
|
||||
for (int i = firstInt; i <= lastInt; i++) {
|
||||
int firstBit = i > firstInt ? 0 : start & 0x1F;
|
||||
int lastBit = i < lastInt ? 31 : end & 0x1F;
|
||||
int mask;
|
||||
if (firstBit == 0 && lastBit == 31) {
|
||||
mask = -1;
|
||||
} else {
|
||||
mask = 0;
|
||||
for (int j = firstBit; j <= lastBit; j++) {
|
||||
mask |= 1 << j;
|
||||
}
|
||||
}
|
||||
// Ones from firstBit to lastBit, inclusive
|
||||
int mask = (2 << lastBit) - (1 << firstBit);
|
||||
|
||||
// Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is,
|
||||
// equals the mask, or we're looking for 0s and the masked portion is not all 0s
|
||||
@@ -262,11 +248,11 @@ public final class BitArray implements Cloneable {
|
||||
}
|
||||
|
||||
public void xor(BitArray other) {
|
||||
if (bits.length != other.bits.length) {
|
||||
if (size != other.size) {
|
||||
throw new IllegalArgumentException("Sizes don't match");
|
||||
}
|
||||
for (int i = 0; i < bits.length; i++) {
|
||||
// The last byte could be incomplete (i.e. not have 8 bits in
|
||||
// The last int could be incomplete (i.e. not have 32 bits in
|
||||
// it) but there is no problem since 0 XOR 0 == 0.
|
||||
bits[i] ^= other.bits[i];
|
||||
}
|
||||
@@ -307,10 +293,10 @@ public final class BitArray implements Cloneable {
|
||||
public void reverse() {
|
||||
int[] newBits = new int[bits.length];
|
||||
// reverse all int's first
|
||||
int len = ((size-1) / 32);
|
||||
int len = (size - 1) / 32;
|
||||
int oldBitsLen = len + 1;
|
||||
for (int i = 0; i < oldBitsLen; i++) {
|
||||
long x = (long) bits[i];
|
||||
long x = bits[i];
|
||||
x = ((x >> 1) & 0x55555555L) | ((x & 0x55555555L) << 1);
|
||||
x = ((x >> 2) & 0x33333333L) | ((x & 0x33333333L) << 2);
|
||||
x = ((x >> 4) & 0x0f0f0f0fL) | ((x & 0x0f0f0f0fL) << 4);
|
||||
@@ -321,16 +307,12 @@ public final class BitArray implements Cloneable {
|
||||
// now correct the int's if the bit size isn't a multiple of 32
|
||||
if (size != oldBitsLen * 32) {
|
||||
int leftOffset = oldBitsLen * 32 - size;
|
||||
int mask = 1;
|
||||
for (int i = 0; i < 31 - leftOffset; i++) {
|
||||
mask = (mask << 1) | 1;
|
||||
}
|
||||
int currentInt = (newBits[0] >> leftOffset) & mask;
|
||||
int currentInt = newBits[0] >>> leftOffset;
|
||||
for (int i = 1; i < oldBitsLen; i++) {
|
||||
int nextInt = newBits[i];
|
||||
currentInt |= nextInt << (32 - leftOffset);
|
||||
newBits[i - 1] = currentInt;
|
||||
currentInt = (nextInt >> leftOffset) & mask;
|
||||
currentInt = nextInt >>> leftOffset;
|
||||
}
|
||||
newBits[oldBitsLen - 1] = currentInt;
|
||||
}
|
||||
@@ -372,4 +354,4 @@ public final class BitArray implements Cloneable {
|
||||
return new BitArray(bits.clone(), size);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ public final class BitMatrix implements Cloneable {
|
||||
|
||||
// no EOL at end?
|
||||
if (bitsPos > rowStartPos) {
|
||||
if(rowLength == -1) {
|
||||
if (rowLength == -1) {
|
||||
rowLength = bitsPos - rowStartPos;
|
||||
} else if (bitsPos - rowStartPos != rowLength) {
|
||||
throw new IllegalArgumentException("row lengths do not match");
|
||||
@@ -254,7 +254,7 @@ public final class BitMatrix implements Cloneable {
|
||||
int height = getHeight();
|
||||
BitArray topRow = new BitArray(width);
|
||||
BitArray bottomRow = new BitArray(width);
|
||||
for (int i = 0; i < (height+1) / 2; i++) {
|
||||
for (int i = 0; i < (height + 1) / 2; i++) {
|
||||
topRow = getRow(i, topRow);
|
||||
bottomRow = getRow(height - 1 - i, bottomRow);
|
||||
topRow.reverse();
|
||||
@@ -307,14 +307,11 @@ public final class BitMatrix implements Cloneable {
|
||||
}
|
||||
}
|
||||
|
||||
int width = right - left;
|
||||
int height = bottom - top;
|
||||
|
||||
if (width < 0 || height < 0) {
|
||||
if (right < left || bottom < top) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new int[] {left, top, width, height};
|
||||
return new int[] {left, top, right - left + 1, bottom - top + 1};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -335,7 +332,7 @@ public final class BitMatrix implements Cloneable {
|
||||
|
||||
int theBits = bits[bitsOffset];
|
||||
int bit = 0;
|
||||
while ((theBits << (31-bit)) == 0) {
|
||||
while ((theBits << (31 - bit)) == 0) {
|
||||
bit++;
|
||||
}
|
||||
x += bit;
|
||||
@@ -419,7 +416,7 @@ public final class BitMatrix implements Cloneable {
|
||||
* @return string representation of entire matrix utilizing given strings
|
||||
*/
|
||||
public String toString(String setString, String unsetString) {
|
||||
return toString(setString, unsetString, "\n");
|
||||
return buildToString(setString, unsetString, "\n");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -431,6 +428,10 @@ public final class BitMatrix implements Cloneable {
|
||||
*/
|
||||
@Deprecated
|
||||
public String toString(String setString, String unsetString, String lineSeparator) {
|
||||
return buildToString(setString, unsetString, lineSeparator);
|
||||
}
|
||||
|
||||
private String buildToString(String setString, String unsetString, String lineSeparator) {
|
||||
StringBuilder result = new StringBuilder(height * (width + 1));
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
|
||||
@@ -70,10 +70,10 @@ public final class GenericGF {
|
||||
x *= 2; // we're assuming the generator alpha is 2
|
||||
if (x >= size) {
|
||||
x ^= primitive;
|
||||
x &= size-1;
|
||||
x &= size - 1;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < size-1; i++) {
|
||||
for (int i = 0; i < size - 1; i++) {
|
||||
logTable[expTable[i]] = i;
|
||||
}
|
||||
// logTable[0] == 0 but this should never be used
|
||||
|
||||
@@ -99,7 +99,6 @@ final class GenericGFPoly {
|
||||
// Just return the x^0 coefficient
|
||||
return getCoefficient(0);
|
||||
}
|
||||
int size = coefficients.length;
|
||||
if (a == 1) {
|
||||
// Just the sum of the coefficients
|
||||
int result = 0;
|
||||
@@ -109,6 +108,7 @@ final class GenericGFPoly {
|
||||
return result;
|
||||
}
|
||||
int result = coefficients[0];
|
||||
int size = coefficients.length;
|
||||
for (int i = 1; i < size; i++) {
|
||||
result = GenericGF.addOrSubtract(field.multiply(a, result), coefficients[i]);
|
||||
}
|
||||
|
||||
@@ -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,16 +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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,7 +141,7 @@ final class FormatInformation {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (errorCorrectionLevel.ordinal() << 3) | (int) dataMask;
|
||||
return (errorCorrectionLevel.ordinal() << 3) | dataMask;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -153,7 +153,7 @@ public final class Version {
|
||||
int i = alignmentPatternCenters[x] - 2;
|
||||
for (int y = 0; y < max; y++) {
|
||||
if ((x == 0 && (y == 0 || y == max - 1)) || (x == max - 1 && y == 0)) {
|
||||
// No alignment patterns near the three finder paterns
|
||||
// No alignment patterns near the three finder patterns
|
||||
continue;
|
||||
}
|
||||
bitMatrix.setRegion(alignmentPatternCenters[y] - 2, i, 5, 5);
|
||||
@@ -212,7 +212,7 @@ public final class Version {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Encapsualtes the parameters for one error-correction block in one symbol version.
|
||||
* <p>Encapsulates the parameters for one error-correction block in one symbol version.
|
||||
* This includes the number of data codewords, and the number of times a block with these
|
||||
* parameters is used consecutively in the QR code version's format.</p>
|
||||
*/
|
||||
|
||||
@@ -106,21 +106,17 @@ public final class Encoder {
|
||||
BitArray dataBits = new BitArray();
|
||||
appendBytes(content, mode, dataBits, encoding);
|
||||
|
||||
// Hard part: need to know version to know how many bits length takes. But need to know how many
|
||||
// bits it takes to know version. First we take a guess at version by assuming version will be
|
||||
// the minimum, 1:
|
||||
|
||||
int provisionalBitsNeeded = headerBits.getSize()
|
||||
+ mode.getCharacterCountBits(Version.getVersionForNumber(1))
|
||||
+ dataBits.getSize();
|
||||
Version provisionalVersion = chooseVersion(provisionalBitsNeeded, ecLevel);
|
||||
|
||||
// Use that guess to calculate the right version. I am still not sure this works in 100% of cases.
|
||||
|
||||
int bitsNeeded = headerBits.getSize()
|
||||
+ mode.getCharacterCountBits(provisionalVersion)
|
||||
+ dataBits.getSize();
|
||||
Version version = chooseVersion(bitsNeeded, ecLevel);
|
||||
Version version;
|
||||
if (hints != null && hints.containsKey(EncodeHintType.QR_VERSION)) {
|
||||
int versionNumber = Integer.parseInt(hints.get(EncodeHintType.QR_VERSION).toString());
|
||||
version = Version.getVersionForNumber(versionNumber);
|
||||
int bitsNeeded = calculateBitsNeeded(mode, headerBits, dataBits, version);
|
||||
if (!willFit(bitsNeeded, version, ecLevel)) {
|
||||
throw new WriterException("Data too big for requested version");
|
||||
}
|
||||
} else {
|
||||
version = recommendVersion(ecLevel, mode, headerBits, dataBits);
|
||||
}
|
||||
|
||||
BitArray headerAndDataBits = new BitArray();
|
||||
headerAndDataBits.appendBitArray(headerBits);
|
||||
@@ -161,6 +157,33 @@ public final class Encoder {
|
||||
return qrCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides the smallest version of QR code that will contain all of the provided data.
|
||||
*
|
||||
* @throws WriterException if the data cannot fit in any version
|
||||
*/
|
||||
private static Version recommendVersion(ErrorCorrectionLevel ecLevel,
|
||||
Mode mode,
|
||||
BitArray headerBits,
|
||||
BitArray dataBits) throws WriterException {
|
||||
// Hard part: need to know version to know how many bits length takes. But need to know how many
|
||||
// bits it takes to know version. First we take a guess at version by assuming version will be
|
||||
// the minimum, 1:
|
||||
int provisionalBitsNeeded = calculateBitsNeeded(mode, headerBits, dataBits, Version.getVersionForNumber(1));
|
||||
Version provisionalVersion = chooseVersion(provisionalBitsNeeded, ecLevel);
|
||||
|
||||
// Use that guess to calculate the right version. I am still not sure this works in 100% of cases.
|
||||
int bitsNeeded = calculateBitsNeeded(mode, headerBits, dataBits, provisionalVersion);
|
||||
return chooseVersion(bitsNeeded, ecLevel);
|
||||
}
|
||||
|
||||
private static int calculateBitsNeeded(Mode mode,
|
||||
BitArray headerBits,
|
||||
BitArray dataBits,
|
||||
Version version) {
|
||||
return headerBits.getSize() + mode.getCharacterCountBits(version) + dataBits.getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the code point of the table used in alphanumeric mode or
|
||||
* -1 if there is no corresponding code in the table.
|
||||
@@ -246,9 +269,21 @@ public final class Encoder {
|
||||
}
|
||||
|
||||
private static Version chooseVersion(int numInputBits, ErrorCorrectionLevel ecLevel) throws WriterException {
|
||||
// In the following comments, we use numbers of Version 7-H.
|
||||
for (int versionNum = 1; versionNum <= 40; versionNum++) {
|
||||
Version version = Version.getVersionForNumber(versionNum);
|
||||
if (willFit(numInputBits, version, ecLevel)) {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
throw new WriterException("Data too big");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the number of input bits will fit in a code with the specified version and
|
||||
* error correction level.
|
||||
*/
|
||||
private static boolean willFit(int numInputBits, Version version, ErrorCorrectionLevel ecLevel) {
|
||||
// In the following comments, we use numbers of Version 7-H.
|
||||
// numBytes = 196
|
||||
int numBytes = version.getTotalCodewords();
|
||||
// getNumECBytes = 130
|
||||
@@ -257,11 +292,7 @@ public final class Encoder {
|
||||
// getNumDataBytes = 196 - 130 = 66
|
||||
int numDataBytes = numBytes - numEcBytes;
|
||||
int totalInputBytes = (numInputBits + 7) / 8;
|
||||
if (numDataBytes >= totalInputBytes) {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
throw new WriterException("Data too big");
|
||||
return numDataBytes >= totalInputBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -383,7 +414,7 @@ public final class Encoder {
|
||||
|
||||
int size = numDataBytesInBlock[0];
|
||||
byte[] dataBytes = new byte[size];
|
||||
bits.toBytes(8*dataBytesOffset, dataBytes, 0, size);
|
||||
bits.toBytes(8 * dataBytesOffset, dataBytes, 0, size);
|
||||
byte[] ecBytes = generateECBytes(dataBytes, numEcBytesInBlock[0]);
|
||||
blocks.add(new BlockPair(dataBytes, ecBytes));
|
||||
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
@@ -103,8 +103,10 @@ final class MaskUtil {
|
||||
}
|
||||
|
||||
private static boolean isWhiteHorizontal(byte[] rowArray, int from, int to) {
|
||||
from = Math.max(from, 0);
|
||||
to = Math.min(to, rowArray.length);
|
||||
for (int i = from; i < to; i++) {
|
||||
if (i >= 0 && i < rowArray.length && rowArray[i] == 1) {
|
||||
if (rowArray[i] == 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -112,8 +114,10 @@ final class MaskUtil {
|
||||
}
|
||||
|
||||
private static boolean isWhiteVertical(byte[][] array, int col, int from, int to) {
|
||||
from = Math.max(from, 0);
|
||||
to = Math.min(to, array.length);
|
||||
for (int i = from; i < to; i++) {
|
||||
if (i >= 0 && i < array.length && array[i][col] == 1) {
|
||||
if (array[i][col] == 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user