diff --git a/extern/zxing-core/src/main/java/com/google/zxing/ChecksumException.java b/extern/zxing-core/src/main/java/com/google/zxing/ChecksumException.java index dedb4be99..77bb908d2 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/ChecksumException.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/ChecksumException.java @@ -30,8 +30,23 @@ public final class ChecksumException extends ReaderException { // do nothing } - public static ChecksumException getChecksumInstance() { - return instance; + private ChecksumException(Throwable cause) { + super(cause); } + public static ChecksumException getChecksumInstance() { + if (isStackTrace) { + return new ChecksumException(); + } else { + return instance; + } + } + + public static ChecksumException getChecksumInstance(Throwable cause) { + if (isStackTrace) { + return new ChecksumException(cause); + } else { + return instance; + } + } } \ No newline at end of file diff --git a/extern/zxing-core/src/main/java/com/google/zxing/EncodeHintType.java b/extern/zxing-core/src/main/java/com/google/zxing/EncodeHintType.java index 5b1961937..b0bbd77a6 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/EncodeHintType.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/EncodeHintType.java @@ -44,12 +44,19 @@ public enum EncodeHintType { /** * Specifies a minimum barcode size (type {@link Dimension}). Only applicable to Data Matrix now. + * + * @deprecated use width/height params in + * {@link com.google.zxing.datamatrix.DataMatrixWriter#encode(String, BarcodeFormat, int, int)} */ + @Deprecated MIN_SIZE, /** * Specifies a maximum barcode size (type {@link Dimension}). Only applicable to Data Matrix now. + * + * @deprecated without replacement */ + @Deprecated MAX_SIZE, /** diff --git a/extern/zxing-core/src/main/java/com/google/zxing/FormatException.java b/extern/zxing-core/src/main/java/com/google/zxing/FormatException.java index 6967e93de..b169bbc99 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/FormatException.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/FormatException.java @@ -28,11 +28,25 @@ public final class FormatException extends ReaderException { private static final FormatException instance = new FormatException(); private FormatException() { - // do nothing + } + + private FormatException(Throwable cause) { + super(cause); } public static FormatException getFormatInstance() { - return instance; + if (isStackTrace) { + return new FormatException(); + } else { + return instance; + } + } + + public static FormatException getFormatInstance(Throwable cause) { + if (isStackTrace) { + return new FormatException(cause); + } else { + return instance; + } } - } \ No newline at end of file diff --git a/extern/zxing-core/src/main/java/com/google/zxing/RGBLuminanceSource.java b/extern/zxing-core/src/main/java/com/google/zxing/RGBLuminanceSource.java index 3f4870744..7c70b35ca 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/RGBLuminanceSource.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/RGBLuminanceSource.java @@ -54,7 +54,7 @@ public final class RGBLuminanceSource extends LuminanceSource { luminances[offset + x] = (byte) r; } else { // Calculate luminance cheaply, favoring green. - luminances[offset + x] = (byte) ((r + g + g + b) >> 2); + luminances[offset + x] = (byte) ((r + 2 * g + b) / 4); } } } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/ReaderException.java b/extern/zxing-core/src/main/java/com/google/zxing/ReaderException.java index 9bb0dd4b9..2253d657d 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/ReaderException.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/ReaderException.java @@ -25,10 +25,17 @@ package com.google.zxing; */ public abstract class ReaderException extends Exception { + // disable stack traces when not running inside test units + protected static final boolean isStackTrace = System.getProperty("surefire.test.class.path") != null; + ReaderException() { // do nothing } + ReaderException(Throwable cause) { + super(cause); + } + // 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. diff --git a/extern/zxing-core/src/main/java/com/google/zxing/ResultPoint.java b/extern/zxing-core/src/main/java/com/google/zxing/ResultPoint.java index e6a6fef40..920cd24c5 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/ResultPoint.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/ResultPoint.java @@ -71,7 +71,7 @@ public class ResultPoint { * Orders an array of three ResultPoints in an order [A,B,C] such that AB is less than AC * and BC is less than AC, and the angle between BC and BA is less than 180 degrees. * - * @param patterns array of three {@link ResultPoint} to order + * @param patterns array of three {@code ResultPoint} to order */ public static void orderBestPatterns(ResultPoint[] patterns) { diff --git a/extern/zxing-core/src/main/java/com/google/zxing/aztec/decoder/Decoder.java b/extern/zxing-core/src/main/java/com/google/zxing/aztec/decoder/Decoder.java index eae9af913..d0304a9a1 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/aztec/decoder/Decoder.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/aztec/decoder/Decoder.java @@ -215,6 +215,9 @@ public final class Decoder { int numDataCodewords = ddata.getNbDatablocks(); int numCodewords = rawbits.length / codewordSize; + if (numCodewords < numDataCodewords) { + throw FormatException.getFormatInstance(); + } int offset = rawbits.length % codewordSize; int numECCodewords = numCodewords - numDataCodewords; @@ -226,8 +229,8 @@ public final class Decoder { try { ReedSolomonDecoder rsDecoder = new ReedSolomonDecoder(gf); rsDecoder.decode(dataWords, numECCodewords); - } catch (ReedSolomonException ignored) { - throw FormatException.getFormatInstance(); + } catch (ReedSolomonException ex) { + throw FormatException.getFormatInstance(ex); } // Now perform the unstuffing operation. @@ -323,7 +326,7 @@ public final class Decoder { for (int i = startIndex; i < startIndex + length; i++) { res <<= 1; if (rawbits[i]) { - res++; + res |= 0x01; } } return res; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/client/result/EmailAddressParsedResult.java b/extern/zxing-core/src/main/java/com/google/zxing/client/result/EmailAddressParsedResult.java index f4af3f6ea..06c4075a4 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/client/result/EmailAddressParsedResult.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/client/result/EmailAddressParsedResult.java @@ -21,24 +21,48 @@ package com.google.zxing.client.result; */ public final class EmailAddressParsedResult extends ParsedResult { - private final String emailAddress; + private final String[] tos; + private final String[] ccs; + private final String[] bccs; private final String subject; private final String body; - private final String mailtoURI; - EmailAddressParsedResult(String emailAddress, - String subject, - String body, - String mailtoURI) { - super(ParsedResultType.EMAIL_ADDRESS); - this.emailAddress = emailAddress; - this.subject = subject; - this.body = body; - this.mailtoURI = mailtoURI; + EmailAddressParsedResult(String to) { + this(new String[] {to}, null, null, null, null); } + EmailAddressParsedResult(String[] tos, + String[] ccs, + String[] bccs, + String subject, + String body) { + super(ParsedResultType.EMAIL_ADDRESS); + this.tos = tos; + this.ccs = ccs; + this.bccs = bccs; + this.subject = subject; + this.body = body; + } + + /** + * @return first elements of {@link #getTos()} or {@code null} if none + * @deprecated use {@link #getTos()} + */ + @Deprecated public String getEmailAddress() { - return emailAddress; + return tos == null || tos.length == 0 ? null : tos[0]; + } + + public String[] getTos() { + return tos; + } + + public String[] getCCs() { + return ccs; + } + + public String[] getBCCs() { + return bccs; } public String getSubject() { @@ -49,14 +73,21 @@ public final class EmailAddressParsedResult extends ParsedResult { return body; } + /** + * @return "mailto:" + * @deprecated without replacement + */ + @Deprecated public String getMailtoURI() { - return mailtoURI; + return "mailto:"; } @Override public String getDisplayResult() { StringBuilder result = new StringBuilder(30); - maybeAppend(emailAddress, result); + maybeAppend(tos, result); + maybeAppend(ccs, result); + maybeAppend(bccs, result); maybeAppend(subject, result); maybeAppend(body, result); return result.toString(); diff --git a/extern/zxing-core/src/main/java/com/google/zxing/client/result/EmailAddressResultParser.java b/extern/zxing-core/src/main/java/com/google/zxing/client/result/EmailAddressResultParser.java index b5117c12a..d66adf1dd 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/client/result/EmailAddressResultParser.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/client/result/EmailAddressResultParser.java @@ -19,6 +19,7 @@ package com.google.zxing.client.result; import com.google.zxing.Result; import java.util.Map; +import java.util.regex.Pattern; /** * Represents a result that encodes an e-mail address, either as a plain address @@ -28,35 +29,52 @@ import java.util.Map; */ public final class EmailAddressResultParser extends ResultParser { + private static final Pattern COMMA = Pattern.compile(","); + @Override public EmailAddressParsedResult parse(Result result) { String rawText = getMassagedText(result); - String emailAddress; if (rawText.startsWith("mailto:") || rawText.startsWith("MAILTO:")) { // If it starts with mailto:, assume it is definitely trying to be an email address - emailAddress = rawText.substring(7); - int queryStart = emailAddress.indexOf('?'); + String hostEmail = rawText.substring(7); + int queryStart = hostEmail.indexOf('?'); if (queryStart >= 0) { - emailAddress = emailAddress.substring(0, queryStart); + hostEmail = hostEmail.substring(0, queryStart); + } + hostEmail = urlDecode(hostEmail); + String[] tos = null; + if (!hostEmail.isEmpty()) { + tos = COMMA.split(hostEmail); } - emailAddress = urlDecode(emailAddress); Map nameValues = parseNameValuePairs(rawText); + String[] ccs = null; + String[] bccs = null; String subject = null; String body = null; if (nameValues != null) { - if (emailAddress.isEmpty()) { - emailAddress = nameValues.get("to"); + if (tos == null) { + String tosString = nameValues.get("to"); + if (tosString != null) { + tos = COMMA.split(tosString); + } + } + String ccString = nameValues.get("cc"); + if (ccString != null) { + ccs = COMMA.split(ccString); + } + String bccString = nameValues.get("bcc"); + if (bccString != null) { + bccs = COMMA.split(bccString); } subject = nameValues.get("subject"); body = nameValues.get("body"); } - return new EmailAddressParsedResult(emailAddress, subject, body, rawText); + return new EmailAddressParsedResult(tos, ccs, bccs, subject, body); } else { if (!EmailDoCoMoResultParser.isBasicallyValidEmailAddress(rawText)) { return null; } - emailAddress = rawText; - return new EmailAddressParsedResult(emailAddress, null, null, "mailto:" + emailAddress); + return new EmailAddressParsedResult(rawText); } } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/client/result/EmailDoCoMoResultParser.java b/extern/zxing-core/src/main/java/com/google/zxing/client/result/EmailDoCoMoResultParser.java index dfef4e1ab..fc4c28485 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/client/result/EmailDoCoMoResultParser.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/client/result/EmailDoCoMoResultParser.java @@ -37,17 +37,18 @@ public final class EmailDoCoMoResultParser extends AbstractDoCoMoResultParser { if (!rawText.startsWith("MATMSG:")) { return null; } - String[] rawTo = matchDoCoMoPrefixedField("TO:", rawText, true); - if (rawTo == null) { + String[] tos = matchDoCoMoPrefixedField("TO:", rawText, true); + if (tos == null) { return null; } - String to = rawTo[0]; - if (!isBasicallyValidEmailAddress(to)) { - return null; + for (String to : tos) { + if (!isBasicallyValidEmailAddress(to)) { + return null; + } } String subject = matchSingleDoCoMoPrefixedField("SUB:", rawText, false); String body = matchSingleDoCoMoPrefixedField("BODY:", rawText, false); - return new EmailAddressParsedResult(to, subject, body, "mailto:" + to); + return new EmailAddressParsedResult(tos, null, null, subject, body); } /** diff --git a/extern/zxing-core/src/main/java/com/google/zxing/client/result/ResultParser.java b/extern/zxing-core/src/main/java/com/google/zxing/client/result/ResultParser.java index 7cc1d4862..c86f1f7fc 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/client/result/ResultParser.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/client/result/ResultParser.java @@ -116,7 +116,7 @@ public abstract class ResultParser { } protected static String unescapeBackslash(String escaped) { - int backslash = escaped.indexOf((int) '\\'); + int backslash = escaped.indexOf('\\'); if (backslash < 0) { return escaped; } @@ -208,13 +208,13 @@ public abstract class ResultParser { int start = i; // Found the start of a match here boolean more = true; while (more) { - i = rawText.indexOf((int) endChar, i); + i = rawText.indexOf(endChar, i); if (i < 0) { // No terminating end character? uh, done. Set i such that loop terminates and break i = rawText.length(); more = false; - } else if (rawText.charAt(i - 1) == '\\') { - // semicolon was escaped so continue + } else if (countPrecedingBackslashes(rawText, i) % 2 != 0) { + // semicolon was escaped (odd count of preceding backslashes) so continue i++; } else { // found a match @@ -239,6 +239,18 @@ public abstract class ResultParser { return matches.toArray(new String[matches.size()]); } + private static int countPrecedingBackslashes(CharSequence s, int pos) { + int count = 0; + for (int i = pos - 1; i >= 0; i--) { + if (s.charAt(i) == '\\') { + count++; + } else { + break; + } + } + return count; + } + static String matchSinglePrefixedField(String prefix, String rawText, char endChar, boolean trim) { String[] matches = matchPrefixedField(prefix, rawText, endChar, trim); return matches == null ? null : matches[0]; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/client/result/SMTPResultParser.java b/extern/zxing-core/src/main/java/com/google/zxing/client/result/SMTPResultParser.java index 7c69696c0..3279cebc4 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/client/result/SMTPResultParser.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/client/result/SMTPResultParser.java @@ -45,7 +45,10 @@ public final class SMTPResultParser extends ResultParser { subject = subject.substring(0, colon); } } - String mailtoURI = "mailto:" + emailAddress; - return new EmailAddressParsedResult(emailAddress, subject, body, mailtoURI); + return new EmailAddressParsedResult(new String[] {emailAddress}, + null, + null, + subject, + body); } } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/client/result/URIResultParser.java b/extern/zxing-core/src/main/java/com/google/zxing/client/result/URIResultParser.java index 56839822a..2b0feefa4 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/client/result/URIResultParser.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/client/result/URIResultParser.java @@ -28,7 +28,8 @@ import java.util.regex.Pattern; */ public final class URIResultParser extends ResultParser { - private static final Pattern URL_WITH_PROTOCOL_PATTERN = Pattern.compile("[a-zA-Z0-9]{2,}:"); + // See http://www.ietf.org/rfc/rfc2396.txt + private static final Pattern URL_WITH_PROTOCOL_PATTERN = Pattern.compile("[a-zA-Z][a-zA-Z0-9+-.]+:"); private static final Pattern URL_WITHOUT_PROTOCOL_PATTERN = Pattern.compile( "([a-zA-Z0-9\\-]+\\.)+[a-zA-Z]{2,}" + // host name elements "(:\\d{1,5})?" + // maybe port diff --git a/extern/zxing-core/src/main/java/com/google/zxing/common/BitMatrix.java b/extern/zxing-core/src/main/java/com/google/zxing/common/BitMatrix.java index d4f0d9b7b..0816e4587 100755 --- a/extern/zxing-core/src/main/java/com/google/zxing/common/BitMatrix.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/common/BitMatrix.java @@ -51,7 +51,7 @@ public final class BitMatrix implements Cloneable { } this.width = width; this.height = height; - this.rowSize = (width + 31) >> 5; + this.rowSize = (width + 31) / 32; bits = new int[rowSize * height]; } @@ -62,6 +62,66 @@ public final class BitMatrix implements Cloneable { this.bits = bits; } + public static BitMatrix parse(String stringRepresentation, String setString, String unsetString) { + if (stringRepresentation == null) { + throw new IllegalArgumentException(); + } + + boolean[] bits = new boolean[stringRepresentation.length()]; + int bitsPos = 0; + int rowStartPos = 0; + int rowLength = -1; + int nRows = 0; + int pos = 0; + while (pos < stringRepresentation.length()) { + if (stringRepresentation.charAt(pos) == '\n' || + stringRepresentation.charAt(pos) == '\r') { + if (bitsPos > rowStartPos) { + if(rowLength == -1) { + rowLength = bitsPos - rowStartPos; + } + else if (bitsPos - rowStartPos != rowLength) { + throw new IllegalArgumentException("row lengths do not match"); + } + rowStartPos = bitsPos; + nRows++; + } + pos++; + } + else if (stringRepresentation.substring(pos, pos + setString.length()).equals(setString)) { + pos += setString.length(); + bits[bitsPos] = true; + bitsPos++; + } + else if (stringRepresentation.substring(pos, pos + unsetString.length()).equals(unsetString)) { + pos += unsetString.length(); + bits[bitsPos] = false; + bitsPos++; + } else { + throw new IllegalArgumentException( + "illegal character encountered: " + stringRepresentation.substring(pos)); + } + } + + // no EOL at end? + if (bitsPos > rowStartPos) { + if(rowLength == -1) { + rowLength = bitsPos - rowStartPos; + } else if (bitsPos - rowStartPos != rowLength) { + throw new IllegalArgumentException("row lengths do not match"); + } + nRows++; + } + + BitMatrix matrix = new BitMatrix(rowLength, nRows); + for (int i = 0; i < bitsPos; i++) { + if (bits[i]) { + matrix.set(i % rowLength, i / rowLength); + } + } + return matrix; + } + /** *

Gets the requested bit, where true means black.

* @@ -70,7 +130,7 @@ public final class BitMatrix implements Cloneable { * @return value of given bit in matrix */ public boolean get(int x, int y) { - int offset = y * rowSize + (x >> 5); + int offset = y * rowSize + (x / 32); return ((bits[offset] >>> (x & 0x1f)) & 1) != 0; } @@ -81,10 +141,15 @@ public final class BitMatrix implements Cloneable { * @param y The vertical component (i.e. which row) */ public void set(int x, int y) { - int offset = y * rowSize + (x >> 5); + int offset = y * rowSize + (x / 32); bits[offset] |= 1 << (x & 0x1f); } + public void unset(int x, int y) { + int offset = y * rowSize + (x / 32); + bits[offset] &= ~(1 << (x & 0x1f)); + } + /** *

Flips the given bit.

* @@ -92,10 +157,31 @@ public final class BitMatrix implements Cloneable { * @param y The vertical component (i.e. which row) */ public void flip(int x, int y) { - int offset = y * rowSize + (x >> 5); + int offset = y * rowSize + (x / 32); bits[offset] ^= 1 << (x & 0x1f); } + /** + * Exclusive-or (XOR): Flip the bit in this {@code BitMatrix} if the corresponding + * mask bit is set. + * + * @param mask XOR mask + */ + public void xor(BitMatrix mask) { + if (width != mask.getWidth() || height != mask.getHeight() + || rowSize != mask.getRowSize()) { + throw new IllegalArgumentException("input matrix dimensions do not match"); + } + BitArray rowArray = new BitArray(width / 32 + 1); + for (int y = 0; y < height; y++) { + int offset = y * rowSize; + int[] row = mask.getRow(y, rowArray).getBitArray(); + for (int x = 0; x < rowSize; x++) { + bits[offset + x] ^= row[x]; + } + } + } + /** * Clears all bits (sets to false). */ @@ -129,7 +215,7 @@ public final class BitMatrix implements Cloneable { for (int y = top; y < bottom; y++) { int offset = y * rowSize; for (int x = left; x < right; x++) { - bits[offset + (x >> 5)] |= 1 << (x & 0x1f); + bits[offset + (x / 32)] |= 1 << (x & 0x1f); } } } @@ -150,7 +236,7 @@ public final class BitMatrix implements Cloneable { } int offset = y * rowSize; for (int x = 0; x < rowSize; x++) { - row.setBulk(x << 5, bits[offset + x]); + row.setBulk(x * 32, bits[offset + x]); } return row; } @@ -248,7 +334,7 @@ public final class BitMatrix implements Cloneable { return null; } int y = bitsOffset / rowSize; - int x = (bitsOffset % rowSize) << 5; + int x = (bitsOffset % rowSize) * 32; int theBits = bits[bitsOffset]; int bit = 0; @@ -269,7 +355,7 @@ public final class BitMatrix implements Cloneable { } int y = bitsOffset / rowSize; - int x = (bitsOffset % rowSize) << 5; + int x = (bitsOffset % rowSize) * 32; int theBits = bits[bitsOffset]; int bit = 31; @@ -295,6 +381,13 @@ public final class BitMatrix implements Cloneable { return height; } + /** + * @return The row size of the matrix + */ + public int getRowSize() { + return rowSize; + } + @Override public boolean equals(Object o) { if (!(o instanceof BitMatrix)) { @@ -317,12 +410,24 @@ public final class BitMatrix implements Cloneable { @Override public String toString() { + return toString("X ", " "); + } + + public String toString(String setString, String unsetString) { + return toString(setString, unsetString, "\n"); + } + + /** + * @deprecated call {@link #toString(String,String)} only, which uses \n line separator always + */ + @Deprecated + public String toString(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++) { - result.append(get(x, y) ? "X " : " "); + result.append(get(x, y) ? setString : unsetString); } - result.append('\n'); + result.append(lineSeparator); } return result.toString(); } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/common/CharacterSetECI.java b/extern/zxing-core/src/main/java/com/google/zxing/common/CharacterSetECI.java index 141bee866..7c3853ca8 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/common/CharacterSetECI.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/common/CharacterSetECI.java @@ -95,7 +95,7 @@ public enum CharacterSetECI { /** * @param value character set ECI value - * @return {@link CharacterSetECI} representing ECI of given value, or null if it is legal but + * @return {@code CharacterSetECI} representing ECI of given value, or null if it is legal but * unsupported * @throws FormatException if ECI value is invalid */ diff --git a/extern/zxing-core/src/main/java/com/google/zxing/common/DefaultGridSampler.java b/extern/zxing-core/src/main/java/com/google/zxing/common/DefaultGridSampler.java index 4ab43fd68..0ef0fbee1 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/common/DefaultGridSampler.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/common/DefaultGridSampler.java @@ -52,12 +52,12 @@ public final class DefaultGridSampler extends GridSampler { throw NotFoundException.getNotFoundInstance(); } BitMatrix bits = new BitMatrix(dimensionX, dimensionY); - float[] points = new float[dimensionX << 1]; + float[] points = new float[2 * dimensionX]; for (int y = 0; y < dimensionY; y++) { int max = points.length; float iValue = (float) y + 0.5f; for (int x = 0; x < max; x += 2) { - points[x] = (float) (x >> 1) + 0.5f; + points[x] = (float) (x / 2) + 0.5f; points[x + 1] = iValue; } transform.transformPoints(points); @@ -68,7 +68,7 @@ public final class DefaultGridSampler extends GridSampler { for (int x = 0; x < max; x += 2) { if (image.get((int) points[x], (int) points[x + 1])) { // Black(-ish) pixel - bits.set(x >> 1, y); + bits.set(x / 2, y); } } } catch (ArrayIndexOutOfBoundsException aioobe) { diff --git a/extern/zxing-core/src/main/java/com/google/zxing/common/GlobalHistogramBinarizer.java b/extern/zxing-core/src/main/java/com/google/zxing/common/GlobalHistogramBinarizer.java index f9676468b..b4c0edbd8 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/common/GlobalHistogramBinarizer.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/common/GlobalHistogramBinarizer.java @@ -72,7 +72,7 @@ public class GlobalHistogramBinarizer extends Binarizer { for (int x = 1; x < width - 1; x++) { int right = localLuminances[x + 1] & 0xff; // A simple -1 4 -1 box filter with a weight of 2. - int luminance = ((center << 2) - left - right) >> 1; + int luminance = ((center * 4) - left - right) / 2; if (luminance < blackPoint) { row.set(x); } @@ -97,7 +97,7 @@ public class GlobalHistogramBinarizer extends Binarizer { for (int y = 1; y < 5; y++) { int row = height * y / 5; byte[] localLuminances = source.getRow(row, luminances); - int right = (width << 2) / 5; + int right = (width * 4) / 5; for (int x = width / 5; x < right; x++) { int pixel = localLuminances[x] & 0xff; localBuckets[pixel >> LUMINANCE_SHIFT]++; @@ -174,7 +174,7 @@ public class GlobalHistogramBinarizer extends Binarizer { // If there is too little contrast in the image to pick a meaningful black point, throw rather // than waste time trying to decode the image, and risk false positives. - if (secondPeak - firstPeak <= numBuckets >> 4) { + if (secondPeak - firstPeak <= numBuckets / 16) { throw NotFoundException.getNotFoundInstance(); } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/common/HybridBinarizer.java b/extern/zxing-core/src/main/java/com/google/zxing/common/HybridBinarizer.java index ba56db7d0..de2934da4 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/common/HybridBinarizer.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/common/HybridBinarizer.java @@ -211,7 +211,7 @@ public final class HybridBinarizer extends GlobalHistogramBinarizer { // // The default assumption is that the block is light/background. Since no estimate for // the level of dark pixels exists locally, use half the min for the block. - average = min >> 1; + average = min / 2; if (y > 0 && x > 0) { // Correct the "white background" assumption for blocks that have neighbors by comparing @@ -221,8 +221,8 @@ public final class HybridBinarizer extends GlobalHistogramBinarizer { // the boundaries is used for the interior. // The (min < bp) is arbitrary but works better than other heuristics that were tried. - int averageNeighborBlackPoint = (blackPoints[y - 1][x] + (2 * blackPoints[y][x - 1]) + - blackPoints[y - 1][x - 1]) >> 2; + int averageNeighborBlackPoint = + (blackPoints[y - 1][x] + (2 * blackPoints[y][x - 1]) + blackPoints[y - 1][x - 1]) / 4; if (min < averageNeighborBlackPoint) { average = averageNeighborBlackPoint; } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/common/detector/MathUtils.java b/extern/zxing-core/src/main/java/com/google/zxing/common/detector/MathUtils.java index 307d6d30e..82aa03943 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/common/detector/MathUtils.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/common/detector/MathUtils.java @@ -23,13 +23,15 @@ public final class MathUtils { /** * Ends up being a bit faster than {@link Math#round(float)}. This merely rounds its - * argument to the nearest int, where x.5 rounds up to x+1. + * argument to the nearest int, where x.5 rounds up to x+1. Semantics of this shortcut + * differ slightly from {@link Math#round(float)} in that half rounds down for negative + * values. -2.5 rounds to -3, not -2. For purposes here it makes no difference. * * @param d real value to round * @return nearest {@code int} */ public static int round(float d) { - return (int) (d + 0.5f); + return (int) (d + (d < 0.0f ? -0.5f : 0.5f)); } public static float distance(float aX, float aY, float bX, float bY) { diff --git a/extern/zxing-core/src/main/java/com/google/zxing/common/detector/MonochromeRectangleDetector.java b/extern/zxing-core/src/main/java/com/google/zxing/common/detector/MonochromeRectangleDetector.java index 5746b88df..1ce8452ee 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/common/detector/MonochromeRectangleDetector.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/common/detector/MonochromeRectangleDetector.java @@ -50,31 +50,31 @@ public final class MonochromeRectangleDetector { public ResultPoint[] detect() throws NotFoundException { int height = image.getHeight(); int width = image.getWidth(); - int halfHeight = height >> 1; - int halfWidth = width >> 1; - int deltaY = Math.max(1, height / (MAX_MODULES << 3)); - int deltaX = Math.max(1, width / (MAX_MODULES << 3)); + int halfHeight = height / 2; + int halfWidth = width / 2; + int deltaY = Math.max(1, height / (MAX_MODULES * 8)); + int deltaX = Math.max(1, width / (MAX_MODULES * 8)); int top = 0; int bottom = height; int left = 0; int right = width; ResultPoint pointA = findCornerFromCenter(halfWidth, 0, left, right, - halfHeight, -deltaY, top, bottom, halfWidth >> 1); + halfHeight, -deltaY, top, bottom, halfWidth / 2); top = (int) pointA.getY() - 1; ResultPoint pointB = findCornerFromCenter(halfWidth, -deltaX, left, right, - halfHeight, 0, top, bottom, halfHeight >> 1); + halfHeight, 0, top, bottom, halfHeight / 2); left = (int) pointB.getX() - 1; ResultPoint pointC = findCornerFromCenter(halfWidth, deltaX, left, right, - halfHeight, 0, top, bottom, halfHeight >> 1); + halfHeight, 0, top, bottom, halfHeight / 2); right = (int) pointC.getX() + 1; ResultPoint pointD = findCornerFromCenter(halfWidth, 0, left, right, - halfHeight, deltaY, top, bottom, halfWidth >> 1); + halfHeight, deltaY, top, bottom, halfWidth / 2); bottom = (int) pointD.getY() + 1; // Go try to find point A again with better information -- might have been off at first. pointA = findCornerFromCenter(halfWidth, 0, left, right, - halfHeight, -deltaY, top, bottom, halfWidth >> 2); + halfHeight, -deltaY, top, bottom, halfWidth / 4); return new ResultPoint[] { pointA, pointB, pointC, pointD }; } @@ -167,7 +167,7 @@ public final class MonochromeRectangleDetector { */ private int[] blackWhiteRange(int fixedDimension, int maxWhiteRun, int minDim, int maxDim, boolean horizontal) { - int center = (minDim + maxDim) >> 1; + int center = (minDim + maxDim) / 2; // Scan left/up first int start = center; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/common/reedsolomon/GenericGF.java b/extern/zxing-core/src/main/java/com/google/zxing/common/reedsolomon/GenericGF.java index ba6d798c3..9ede5d80a 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/common/reedsolomon/GenericGF.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/common/reedsolomon/GenericGF.java @@ -38,16 +38,13 @@ public final class GenericGF { public static final GenericGF AZTEC_DATA_8 = DATA_MATRIX_FIELD_256; public static final GenericGF MAXICODE_FIELD_64 = AZTEC_DATA_6; - private static final int INITIALIZATION_THRESHOLD = 0; - - private int[] expTable; - private int[] logTable; - private GenericGFPoly zero; - private GenericGFPoly one; + private final int[] expTable; + private final int[] logTable; + private final GenericGFPoly zero; + private final GenericGFPoly one; private final int size; private final int primitive; private final int generatorBase; - private boolean initialized = false; /** * Create a representation of GF(size) using the given primitive polynomial. @@ -64,19 +61,13 @@ public final class GenericGF { this.primitive = primitive; this.size = size; this.generatorBase = b; - - if (size <= INITIALIZATION_THRESHOLD) { - initialize(); - } - } - private void initialize() { expTable = new int[size]; logTable = new int[size]; int x = 1; for (int i = 0; i < size; i++) { expTable[i] = x; - x <<= 1; // x = x * 2; we're assuming the generator alpha is 2 + x *= 2; // we're assuming the generator alpha is 2 if (x >= size) { x ^= primitive; x &= size-1; @@ -88,24 +79,13 @@ public final class GenericGF { // logTable[0] == 0 but this should never be used zero = new GenericGFPoly(this, new int[]{0}); one = new GenericGFPoly(this, new int[]{1}); - initialized = true; } - - private void checkInit() { - if (!initialized) { - initialize(); - } - } - - GenericGFPoly getZero() { - checkInit(); + GenericGFPoly getZero() { return zero; } GenericGFPoly getOne() { - checkInit(); - return one; } @@ -113,8 +93,6 @@ public final class GenericGF { * @return the monomial representing coefficient * x^degree */ GenericGFPoly buildMonomial(int degree, int coefficient) { - checkInit(); - if (degree < 0) { throw new IllegalArgumentException(); } @@ -139,8 +117,6 @@ public final class GenericGF { * @return 2 to the power of a in GF(size) */ int exp(int a) { - checkInit(); - return expTable[a]; } @@ -148,8 +124,6 @@ public final class GenericGF { * @return base 2 log of a in GF(size) */ int log(int a) { - checkInit(); - if (a == 0) { throw new IllegalArgumentException(); } @@ -160,8 +134,6 @@ public final class GenericGF { * @return multiplicative inverse of a */ int inverse(int a) { - checkInit(); - if (a == 0) { throw new ArithmeticException(); } @@ -172,8 +144,6 @@ public final class GenericGF { * @return product of a and b in GF(size) */ int multiply(int a, int b) { - checkInit(); - if (a == 0 || b == 0) { return 0; } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/common/reedsolomon/GenericGFPoly.java b/extern/zxing-core/src/main/java/com/google/zxing/common/reedsolomon/GenericGFPoly.java index 1ccc0358d..8887e0ee1 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/common/reedsolomon/GenericGFPoly.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/common/reedsolomon/GenericGFPoly.java @@ -52,7 +52,7 @@ final class GenericGFPoly { firstNonZero++; } if (firstNonZero == coefficientsLength) { - this.coefficients = field.getZero().coefficients; + this.coefficients = new int[]{0}; } else { this.coefficients = new int[coefficientsLength - firstNonZero]; System.arraycopy(coefficients, diff --git a/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/DataMatrixReader.java b/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/DataMatrixReader.java index f66be4af3..e02d766a1 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/DataMatrixReader.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/DataMatrixReader.java @@ -123,7 +123,7 @@ public final class DataMatrixReader implements Reader { // Push in the "border" by half the module width so that we start // sampling in the middle of the module. Just in case the image is a // little off, this will help recover. - int nudge = moduleSize >> 1; + int nudge = moduleSize / 2; top += nudge; left += nudge; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/DataMatrixWriter.java b/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/DataMatrixWriter.java index 1560f68f1..53b4b68d6 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/DataMatrixWriter.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/DataMatrixWriter.java @@ -60,17 +60,19 @@ public final class DataMatrixWriter implements Writer { // Try to get force shape & min / max size SymbolShapeHint shape = SymbolShapeHint.FORCE_NONE; - Dimension minSize = null; + Dimension minSize = new Dimension(width, height); Dimension maxSize = null; if (hints != null) { SymbolShapeHint requestedShape = (SymbolShapeHint) hints.get(EncodeHintType.DATA_MATRIX_SHAPE); if (requestedShape != null) { shape = requestedShape; } + @SuppressWarnings("deprecation") Dimension requestedMinSize = (Dimension) hints.get(EncodeHintType.MIN_SIZE); if (requestedMinSize != null) { minSize = requestedMinSize; } + @SuppressWarnings("deprecation") Dimension requestedMaxSize = (Dimension) hints.get(EncodeHintType.MAX_SIZE); if (requestedMaxSize != null) { maxSize = requestedMaxSize; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/decoder/DataBlock.java b/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/decoder/DataBlock.java index a91b72a7b..35edd42f5 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/decoder/DataBlock.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/decoder/DataBlock.java @@ -94,8 +94,9 @@ final class DataBlock { int max = result[0].codewords.length; for (int i = longerBlocksNumDataCodewords; i < max; i++) { for (int j = 0; j < numResultBlocks; j++) { - int iOffset = specialVersion && j > 7 ? i - 1 : i; - result[j].codewords[iOffset] = rawCodewords[rawCodewordsOffset++]; + int jOffset = specialVersion ? (j + 8) % numResultBlocks : j; + int iOffset = specialVersion && jOffset > 7 ? i - 1 : i; + result[jOffset].codewords[iOffset] = rawCodewords[rawCodewordsOffset++]; } } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/decoder/DecodedBitStreamParser.java b/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/decoder/DecodedBitStreamParser.java index 8b0816a92..16f2ecb7d 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/decoder/DecodedBitStreamParser.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/decoder/DecodedBitStreamParser.java @@ -71,6 +71,9 @@ final class DecodedBitStreamParser { 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; + // Shift 2 for Text is the same encoding as C40 + private static final char[] TEXT_SHIFT2_SET_CHARS = C40_SHIFT2_SET_CHARS; + private static final char[] TEXT_SHIFT3_SET_CHARS = { '`', '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', '{', '|', '}', '~', (char) 127 @@ -139,7 +142,7 @@ final class DecodedBitStreamParser { return Mode.PAD_ENCODE; } else if (oneByte <= 229) { // 2-digit data 00-99 (Numeric Value + 130) int value = oneByte - 130; - if (value < 10) { // padd with '0' for single digit values + if (value < 10) { // pad with '0' for single digit values result.append('0'); } result.append(value); @@ -319,13 +322,13 @@ final class DecodedBitStreamParser { break; case 2: // Shift 2 for Text is the same encoding as C40 - if (cValue < C40_SHIFT2_SET_CHARS.length) { - char c40char = C40_SHIFT2_SET_CHARS[cValue]; + if (cValue < TEXT_SHIFT2_SET_CHARS.length) { + char textChar = TEXT_SHIFT2_SET_CHARS[cValue]; if (upperShift) { - result.append((char) (c40char + 128)); + result.append((char) (textChar + 128)); upperShift = false; } else { - result.append(c40char); + result.append(textChar); } } else if (cValue == 27) { // FNC1 result.append((char) 29); // translate as ASCII 29 diff --git a/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/detector/Detector.java b/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/detector/Detector.java index 4e4ccf1e4..4e3de8168 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/detector/Detector.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/detector/Detector.java @@ -370,7 +370,7 @@ public final class Detector { int dx = Math.abs(toX - fromX); int dy = Math.abs(toY - fromY); - int error = -dx >> 1; + int error = -dx / 2; int ystep = fromY < toY ? 1 : -1; int xstep = fromX < toX ? 1 : -1; int transitions = 0; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/encoder/ErrorCorrection.java b/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/encoder/ErrorCorrection.java index 8d6d5ff40..d38933498 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/encoder/ErrorCorrection.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/encoder/ErrorCorrection.java @@ -81,7 +81,7 @@ public final class ErrorCorrection { for (int i = 0; i < 255; i++) { ALOG[i] = p; LOG[p] = i; - p <<= 1; + p *= 2; if (p >= 256) { p ^= MODULO_VALUE; } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/encoder/X12Encoder.java b/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/encoder/X12Encoder.java index fca29f250..0184bec49 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/encoder/X12Encoder.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/datamatrix/encoder/X12Encoder.java @@ -72,16 +72,12 @@ final class X12Encoder extends C40Encoder { context.updateSymbolInfo(); int available = context.getSymbolInfo().getDataCapacity() - context.getCodewordCount(); int count = buffer.length(); - if (count == 2) { + context.pos -= count; + if (context.getRemainingCharacters() > 1 || available > 1 || + context.getRemainingCharacters() != available) { context.writeCodeword(HighLevelEncoder.X12_UNLATCH); - context.pos -= 2; - context.signalEncoderChange(HighLevelEncoder.ASCII_ENCODATION); - } else if (count == 1) { - context.pos--; - if (available > 1) { - context.writeCodeword(HighLevelEncoder.X12_UNLATCH); - } - //NOP - No unlatch necessary + } + if (context.getNewEncoding() < 0) { context.signalEncoderChange(HighLevelEncoder.ASCII_ENCODATION); } } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/maxicode/decoder/DecodedBitStreamParser.java b/extern/zxing-core/src/main/java/com/google/zxing/maxicode/decoder/DecodedBitStreamParser.java index f372b49e2..4744d4db2 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/maxicode/decoder/DecodedBitStreamParser.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/maxicode/decoder/DecodedBitStreamParser.java @@ -98,6 +98,9 @@ final class DecodedBitStreamParser { } private static int getInt(byte[] bytes, byte[] x) { + if (x.length == 0) { + throw new IllegalArgumentException(); + } int val = 0; for (int i = 0; i < x.length; i++) { val += getBit(x[i], bytes) << (x.length - i - 1); diff --git a/extern/zxing-core/src/main/java/com/google/zxing/multi/ByQuadrantReader.java b/extern/zxing-core/src/main/java/com/google/zxing/multi/ByQuadrantReader.java index 74186dcc8..06e4b1a28 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/multi/ByQuadrantReader.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/multi/ByQuadrantReader.java @@ -23,6 +23,7 @@ import com.google.zxing.FormatException; import com.google.zxing.NotFoundException; import com.google.zxing.Reader; import com.google.zxing.Result; +import com.google.zxing.ResultPoint; import java.util.Map; @@ -58,30 +59,33 @@ public final class ByQuadrantReader implements Reader { int halfWidth = width / 2; int halfHeight = height / 2; - BinaryBitmap topLeft = image.crop(0, 0, halfWidth, halfHeight); try { - return delegate.decode(topLeft, hints); + // No need to call makeAbsolute as results will be relative to original top left here + return delegate.decode(image.crop(0, 0, halfWidth, halfHeight), hints); } catch (NotFoundException re) { // continue } - BinaryBitmap topRight = image.crop(halfWidth, 0, halfWidth, halfHeight); try { - return delegate.decode(topRight, hints); + Result result = delegate.decode(image.crop(halfWidth, 0, halfWidth, halfHeight), hints); + makeAbsolute(result.getResultPoints(), halfWidth, 0); + return result; } catch (NotFoundException re) { // continue } - BinaryBitmap bottomLeft = image.crop(0, halfHeight, halfWidth, halfHeight); try { - return delegate.decode(bottomLeft, hints); + Result result = delegate.decode(image.crop(0, halfHeight, halfWidth, halfHeight), hints); + makeAbsolute(result.getResultPoints(), 0, halfHeight); + return result; } catch (NotFoundException re) { // continue } - BinaryBitmap bottomRight = image.crop(halfWidth, halfHeight, halfWidth, halfHeight); try { - return delegate.decode(bottomRight, hints); + Result result = delegate.decode(image.crop(halfWidth, halfHeight, halfWidth, halfHeight), hints); + makeAbsolute(result.getResultPoints(), halfWidth, halfHeight); + return result; } catch (NotFoundException re) { // continue } @@ -89,7 +93,9 @@ public final class ByQuadrantReader implements Reader { int quarterWidth = halfWidth / 2; int quarterHeight = halfHeight / 2; BinaryBitmap center = image.crop(quarterWidth, quarterHeight, halfWidth, halfHeight); - return delegate.decode(center, hints); + Result result = delegate.decode(center, hints); + makeAbsolute(result.getResultPoints(), quarterWidth, quarterHeight); + return result; } @Override @@ -97,4 +103,13 @@ public final class ByQuadrantReader implements Reader { delegate.reset(); } + private static void makeAbsolute(ResultPoint[] points, int leftOffset, int topOffset) { + if (points != null) { + for (int i = 0; i < points.length; i++) { + ResultPoint relative = points[i]; + points[i] = new ResultPoint(relative.getX() + leftOffset, relative.getY() + topOffset); + } + } + } + } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/multi/GenericMultipleBarcodeReader.java b/extern/zxing-core/src/main/java/com/google/zxing/multi/GenericMultipleBarcodeReader.java index 276279bb7..b90dc0e31 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/multi/GenericMultipleBarcodeReader.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/multi/GenericMultipleBarcodeReader.java @@ -106,6 +106,9 @@ public final class GenericMultipleBarcodeReader implements MultipleBarcodeReader float maxX = 0.0f; float maxY = 0.0f; for (ResultPoint point : resultPoints) { + if (point == null) { + continue; + } float x = point.getX(); float y = point.getY(); if (x < minX) { @@ -160,7 +163,9 @@ public final class GenericMultipleBarcodeReader implements MultipleBarcodeReader ResultPoint[] newResultPoints = new ResultPoint[oldResultPoints.length]; for (int i = 0; i < oldResultPoints.length; i++) { ResultPoint oldPoint = oldResultPoints[i]; - newResultPoints[i] = new ResultPoint(oldPoint.getX() + xOffset, oldPoint.getY() + yOffset); + if (oldPoint != null) { + newResultPoints[i] = new ResultPoint(oldPoint.getX() + xOffset, oldPoint.getY() + yOffset); + } } Result newResult = new Result(result.getText(), result.getRawBytes(), newResultPoints, result.getBarcodeFormat()); newResult.putAllMetadata(result.getResultMetadata()); diff --git a/extern/zxing-core/src/main/java/com/google/zxing/oned/CodaBarReader.java b/extern/zxing-core/src/main/java/com/google/zxing/oned/CodaBarReader.java index 7c9cbd8ce..d5fd956cb 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/oned/CodaBarReader.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/oned/CodaBarReader.java @@ -37,8 +37,8 @@ public final class CodaBarReader extends OneDReader { // These values are critical for determining how permissive the decoding // will be. All stripe sizes must be within the window these define, as // compared to the average stripe size. - private static final int MAX_ACCEPTABLE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 2.0f); - private static final int PADDING = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 1.5f); + private static final float MAX_ACCEPTABLE = 2.0f; + private static final float PADDING = 1.5f; private static final String ALPHABET_STRING = "0123456789-$:/.+ABCD"; static final char[] ALPHABET = ALPHABET_STRING.toCharArray(); @@ -188,15 +188,14 @@ public final class CodaBarReader extends OneDReader { } // Calculate our allowable size thresholds using fixed-point math. - int[] maxes = new int[4]; - int[] mins = new int[4]; + float[] maxes = new float[4]; + float[] mins = new float[4]; // Define the threshold of acceptability to be the midpoint between the // average small stripe and the average large stripe. No stripe lengths // should be on the "wrong" side of that line. for (int i = 0; i < 2; i++) { - mins[i] = 0; // Accept arbitrarily small "short" stripes. - mins[i + 2] = ((sizes[i] << INTEGER_MATH_SHIFT) / counts[i] + - (sizes[i + 2] << INTEGER_MATH_SHIFT) / counts[i + 2]) >> 1; + mins[i] = 0.0f; // Accept arbitrarily small "short" stripes. + mins[i + 2] = ((float) sizes[i] / counts[i] + (float) sizes[i + 2] / counts[i + 2]) / 2.0f; maxes[i] = mins[i + 2]; maxes[i + 2] = (sizes[i + 2] * MAX_ACCEPTABLE + PADDING) / counts[i + 2]; } @@ -209,7 +208,7 @@ public final class CodaBarReader extends OneDReader { // Even j = bars, while odd j = spaces. Categories 2 and 3 are for // long stripes, while 0 and 1 are for short stripes. int category = (j & 1) + (pattern & 1) * 2; - int size = counters[pos + j] << INTEGER_MATH_SHIFT; + int size = counters[pos + j]; if (size < mins[category] || size > maxes[category]) { throw NotFoundException.getNotFoundInstance(); } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/oned/CodaBarWriter.java b/extern/zxing-core/src/main/java/com/google/zxing/oned/CodaBarWriter.java index 39ac22924..d27a166f1 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/oned/CodaBarWriter.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/oned/CodaBarWriter.java @@ -16,8 +16,6 @@ package com.google.zxing.oned; -import java.util.Arrays; - /** * This class renders CodaBar as {@code boolean[]}. * @@ -28,26 +26,40 @@ public final class CodaBarWriter extends OneDimensionalCodeWriter { private static final char[] START_END_CHARS = {'A', 'B', 'C', 'D'}; private static final char[] ALT_START_END_CHARS = {'T', 'N', '*', 'E'}; private static final char[] CHARS_WHICH_ARE_TEN_LENGTH_EACH_AFTER_DECODED = {'/', ':', '+', '.'}; + private static final char DEFAULT_GUARD = START_END_CHARS[0]; @Override public boolean[] encode(String contents) { if (contents.length() < 2) { - throw new IllegalArgumentException("Codabar should start/end with start/stop symbols"); - } - // Verify input and calculate decoded length. - char firstChar = Character.toUpperCase(contents.charAt(0)); - char lastChar = Character.toUpperCase(contents.charAt(contents.length() - 1)); - boolean startsEndsNormal = - CodaBarReader.arrayContains(START_END_CHARS, firstChar) && - CodaBarReader.arrayContains(START_END_CHARS, lastChar); - boolean startsEndsAlt = - CodaBarReader.arrayContains(ALT_START_END_CHARS, firstChar) && - CodaBarReader.arrayContains(ALT_START_END_CHARS, lastChar); - if (!(startsEndsNormal || startsEndsAlt)) { - throw new IllegalArgumentException( - "Codabar should start/end with " + Arrays.toString(START_END_CHARS) + - ", or start/end with " + Arrays.toString(ALT_START_END_CHARS)); + // Can't have a start/end guard, so tentatively add default guards + contents = DEFAULT_GUARD + contents + DEFAULT_GUARD; + } else { + // Verify input and calculate decoded length. + char firstChar = Character.toUpperCase(contents.charAt(0)); + char lastChar = Character.toUpperCase(contents.charAt(contents.length() - 1)); + boolean startsNormal = CodaBarReader.arrayContains(START_END_CHARS, firstChar); + boolean endsNormal = CodaBarReader.arrayContains(START_END_CHARS, lastChar); + boolean startsAlt = CodaBarReader.arrayContains(ALT_START_END_CHARS, firstChar); + boolean endsAlt = CodaBarReader.arrayContains(ALT_START_END_CHARS, lastChar); + if (startsNormal) { + if (!endsNormal) { + throw new IllegalArgumentException("Invalid start/end guards: " + contents); + } + // else already has valid start/end + } else if (startsAlt) { + if (!endsAlt) { + throw new IllegalArgumentException("Invalid start/end guards: " + contents); + } + // else already has valid start/end + } else { + // Doesn't start with a guard + if (endsNormal || endsAlt) { + throw new IllegalArgumentException("Invalid start/end guards: " + contents); + } + // else doesn't end with guard either, so add a default + contents = DEFAULT_GUARD + contents + DEFAULT_GUARD; + } } // The start character and the end character are decoded to 10 length each. diff --git a/extern/zxing-core/src/main/java/com/google/zxing/oned/Code128Reader.java b/extern/zxing-core/src/main/java/com/google/zxing/oned/Code128Reader.java index 82540c729..5fe6c986c 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/oned/Code128Reader.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/oned/Code128Reader.java @@ -146,8 +146,8 @@ public final class Code128Reader extends OneDReader { {2, 3, 3, 1, 1, 1, 2} }; - private static final int MAX_AVG_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.25f); - private static final int MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.7f); + private static final float MAX_AVG_VARIANCE = 0.25f; + private static final float MAX_INDIVIDUAL_VARIANCE = 0.7f; private static final int CODE_SHIFT = 98; @@ -181,10 +181,10 @@ public final class Code128Reader extends OneDReader { counters[counterPosition]++; } else { if (counterPosition == patternLength - 1) { - int bestVariance = MAX_AVG_VARIANCE; + float bestVariance = MAX_AVG_VARIANCE; int bestMatch = -1; for (int startCode = CODE_START_A; startCode <= CODE_START_C; startCode++) { - int variance = patternMatchVariance(counters, CODE_PATTERNS[startCode], + float variance = patternMatchVariance(counters, CODE_PATTERNS[startCode], MAX_INDIVIDUAL_VARIANCE); if (variance < bestVariance) { bestVariance = variance; @@ -214,11 +214,11 @@ public final class Code128Reader extends OneDReader { private static int decodeCode(BitArray row, int[] counters, int rowOffset) throws NotFoundException { recordPattern(row, rowOffset, counters); - int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept + float bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept int bestMatch = -1; for (int d = 0; d < CODE_PATTERNS.length; d++) { int[] pattern = CODE_PATTERNS[d]; - int variance = patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE); + float variance = patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE); if (variance < bestVariance) { bestVariance = variance; bestMatch = d; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/oned/Code39Reader.java b/extern/zxing-core/src/main/java/com/google/zxing/oned/Code39Reader.java index 685354de7..76eee5717 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/oned/Code39Reader.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/oned/Code39Reader.java @@ -136,7 +136,7 @@ public final class Code39Reader extends OneDReader { int whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize; // If 50% of last pattern size, following last pattern, is not whitespace, fail // (but if it's whitespace to the very end of the image, that's OK) - if (nextStart != end && (whiteSpaceAfterEnd << 1) < lastPatternSize) { + if (nextStart != end && (whiteSpaceAfterEnd * 2) < lastPatternSize) { throw NotFoundException.getNotFoundInstance(); } @@ -192,7 +192,7 @@ public final class Code39Reader extends OneDReader { if (counterPosition == patternLength - 1) { // Look for whitespace before start pattern, >= 50% of width of start pattern if (toNarrowWidePattern(counters) == ASTERISK_ENCODING && - row.isRange(Math.max(0, patternStart - ((i - patternStart) >> 1)), patternStart, false)) { + row.isRange(Math.max(0, patternStart - ((i - patternStart) / 2)), patternStart, false)) { return new int[]{patternStart, i}; } patternStart += counters[0] + counters[1]; @@ -244,7 +244,7 @@ public final class Code39Reader extends OneDReader { if (counter > maxNarrowCounter) { wideCounters--; // totalWideCountersWidth = 3 * average, so this checks if counter >= 3/2 * average - if ((counter << 1) >= totalWideCountersWidth) { + if ((counter * 2) >= totalWideCountersWidth) { return -1; } } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/oned/Code93Reader.java b/extern/zxing-core/src/main/java/com/google/zxing/oned/Code93Reader.java index e79925867..56b2d78de 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/oned/Code93Reader.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/oned/Code93Reader.java @@ -170,20 +170,16 @@ public final class Code93Reader extends OneDReader { } int pattern = 0; for (int i = 0; i < max; i++) { - int scaledShifted = (counters[i] << INTEGER_MATH_SHIFT) * 9 / sum; - int scaledUnshifted = scaledShifted >> INTEGER_MATH_SHIFT; - if ((scaledShifted & 0xFF) > 0x7F) { - scaledUnshifted++; - } - if (scaledUnshifted < 1 || scaledUnshifted > 4) { + int scaled = Math.round(counters[i] * 9.0f / sum); + if (scaled < 1 || scaled > 4) { return -1; } if ((i & 0x01) == 0) { - for (int j = 0; j < scaledUnshifted; j++) { + for (int j = 0; j < scaled; j++) { pattern = (pattern << 1) | 0x01; } } else { - pattern <<= scaledUnshifted; + pattern <<= scaled; } } return pattern; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/oned/ITFReader.java b/extern/zxing-core/src/main/java/com/google/zxing/oned/ITFReader.java index 004cd2777..e57d5a1e1 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/oned/ITFReader.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/oned/ITFReader.java @@ -44,8 +44,8 @@ import java.util.Map; */ public final class ITFReader extends OneDReader { - private static final int MAX_AVG_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.42f); - private static final int MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.78f); + private static final float MAX_AVG_VARIANCE = 0.38f; + private static final float MAX_INDIVIDUAL_VARIANCE = 0.78f; private static final int W = 3; // Pixel width of a wide line private static final int N = 1; // Pixed width of a narrow line @@ -157,7 +157,7 @@ public final class ITFReader extends OneDReader { recordPattern(row, payloadStart, counterDigitPair); // Split them into each array for (int k = 0; k < 5; k++) { - int twoK = k << 1; + int twoK = 2 * k; counterBlack[k] = counterDigitPair[twoK]; counterWhite[k] = counterDigitPair[twoK + 1]; } @@ -188,7 +188,7 @@ public final class ITFReader extends OneDReader { // Determine the width of a narrow line in pixels. We can do this by // getting the width of the start pattern and dividing by 4 because its // made up of 4 narrow lines. - this.narrowLineWidth = (startPattern[1] - startPattern[0]) >> 2; + this.narrowLineWidth = (startPattern[1] - startPattern[0]) / 4; validateQuietZone(row, startPattern[0]); @@ -336,13 +336,12 @@ public final class ITFReader extends OneDReader { * @throws NotFoundException if digit cannot be decoded */ private static int decodeDigit(int[] counters) throws NotFoundException { - - int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept + float bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept int bestMatch = -1; int max = PATTERNS.length; for (int i = 0; i < max; i++) { int[] pattern = PATTERNS[i]; - int variance = patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE); + float variance = patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE); if (variance < bestVariance) { bestVariance = variance; bestMatch = i; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/oned/ITFWriter.java b/extern/zxing-core/src/main/java/com/google/zxing/oned/ITFWriter.java index 03c0287e4..3ce020775 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/oned/ITFWriter.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/oned/ITFWriter.java @@ -63,8 +63,8 @@ public final class ITFWriter extends OneDimensionalCodeWriter { int two = Character.digit(contents.charAt(i+1), 10); int[] encoding = new int[18]; for (int j = 0; j < 5; j++) { - encoding[j << 1] = ITFReader.PATTERNS[one][j]; - encoding[(j << 1) + 1] = ITFReader.PATTERNS[two][j]; + encoding[2 * j] = ITFReader.PATTERNS[one][j]; + encoding[2 * j + 1] = ITFReader.PATTERNS[two][j]; } pos += appendPattern(result, pos, encoding, true); } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/oned/OneDReader.java b/extern/zxing-core/src/main/java/com/google/zxing/oned/OneDReader.java index 0ef3e14e1..1c7a95fd1 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/oned/OneDReader.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/oned/OneDReader.java @@ -41,9 +41,6 @@ import java.util.Map; */ public abstract class OneDReader implements Reader { - protected static final int INTEGER_MATH_SHIFT = 8; - protected static final int PATTERN_MATCH_RESULT_SCALE_FACTOR = 1 << INTEGER_MATH_SHIFT; - @Override public Result decode(BinaryBitmap image) throws NotFoundException, FormatException { return decode(image, null); @@ -122,7 +119,7 @@ public abstract class OneDReader implements Reader { for (int x = 0; x < maxLines; x++) { // Scanning from the middle out. Determine which row we're looking at next: - int rowStepsAboveOrBelow = (x + 1) >> 1; + int rowStepsAboveOrBelow = (x + 1) / 2; boolean isAbove = (x & 0x01) == 0; // i.e. is x even? int rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow); if (rowNumber < 0 || rowNumber >= height) { @@ -248,14 +245,11 @@ public abstract class OneDReader implements Reader { * @param counters observed counters * @param pattern expected pattern * @param maxIndividualVariance The most any counter can differ before we give up - * @return ratio of total variance between counters and pattern compared to total pattern size, - * where the ratio has been multiplied by 256. So, 0 means no variance (perfect match); 256 means - * the total variance between counters and patterns equals the pattern length, higher values mean - * even more variance + * @return ratio of total variance between counters and pattern compared to total pattern size */ - protected static int patternMatchVariance(int[] counters, - int[] pattern, - int maxIndividualVariance) { + protected static float patternMatchVariance(int[] counters, + int[] pattern, + float maxIndividualVariance) { int numCounters = counters.length; int total = 0; int patternLength = 0; @@ -266,21 +260,19 @@ public abstract class OneDReader implements Reader { if (total < patternLength) { // If we don't even have one pixel per unit of bar width, assume this is too small // to reliably match, so fail: - return Integer.MAX_VALUE; + return Float.POSITIVE_INFINITY; } - // We're going to fake floating-point math in integers. We just need to use more bits. - // Scale up patternLength so that intermediate values below like scaledCounter will have - // more "significant digits" - int unitBarWidth = (total << INTEGER_MATH_SHIFT) / patternLength; - maxIndividualVariance = (maxIndividualVariance * unitBarWidth) >> INTEGER_MATH_SHIFT; - int totalVariance = 0; + float unitBarWidth = (float) total / patternLength; + maxIndividualVariance *= unitBarWidth; + + float totalVariance = 0.0f; for (int x = 0; x < numCounters; x++) { - int counter = counters[x] << INTEGER_MATH_SHIFT; - int scaledPattern = pattern[x] * unitBarWidth; - int variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter; + int counter = counters[x]; + float scaledPattern = pattern[x] * unitBarWidth; + float variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter; if (variance > maxIndividualVariance) { - return Integer.MAX_VALUE; + return Float.POSITIVE_INFINITY; } totalVariance += variance; } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/oned/UPCEANReader.java b/extern/zxing-core/src/main/java/com/google/zxing/oned/UPCEANReader.java index c9ddc32c7..677ec9172 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/oned/UPCEANReader.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/oned/UPCEANReader.java @@ -44,8 +44,8 @@ public abstract class UPCEANReader extends OneDReader { // These two values are critical for determining how permissive the decoding will be. // We've arrived at these values through a lot of trial and error. Setting them any higher // lets false positives creep in quickly. - private static final int MAX_AVG_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.48f); - private static final int MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.7f); + private static final float MAX_AVG_VARIANCE = 0.48f; + private static final float MAX_INDIVIDUAL_VARIANCE = 0.7f; /** * Start/end guard pattern. @@ -353,12 +353,12 @@ public abstract class UPCEANReader extends OneDReader { static int decodeDigit(BitArray row, int[] counters, int rowOffset, int[][] patterns) throws NotFoundException { recordPattern(row, rowOffset, counters); - int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept + float bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept int bestMatch = -1; int max = patterns.length; for (int i = 0; i < max; i++) { int[] pattern = patterns[i]; - int variance = patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE); + float variance = patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE); if (variance < bestVariance) { bestVariance = variance; bestMatch = i; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/AbstractRSSReader.java b/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/AbstractRSSReader.java index d23096131..e86b394de 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/AbstractRSSReader.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/AbstractRSSReader.java @@ -21,8 +21,8 @@ import com.google.zxing.oned.OneDReader; public abstract class AbstractRSSReader extends OneDReader { - private static final int MAX_AVG_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.2f); - private static final int MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.45f); + private static final float MAX_AVG_VARIANCE = 0.2f; + private static final float MAX_INDIVIDUAL_VARIANCE = 0.45f; private static final float MIN_FINDER_PATTERN_RATIO = 9.5f / 12.0f; private static final float MAX_FINDER_PATTERN_RATIO = 12.5f / 14.0f; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/RSS14Reader.java b/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/RSS14Reader.java index cb62673bc..604a2aa7a 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/RSS14Reader.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/RSS14Reader.java @@ -228,7 +228,7 @@ public final class RSS14Reader extends AbstractRSSReader { } else if (count > 8) { count = 8; } - int offset = i >> 1; + int offset = i / 2; if ((i & 0x01) == 0) { oddCounts[offset] = count; oddRoundingErrors[offset] = value - count; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/RSSUtils.java b/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/RSSUtils.java index f1fd1798c..fb5a1d020 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/RSSUtils.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/RSSUtils.java @@ -129,7 +129,7 @@ public final class RSSUtils { /* static int[] elements(int[] eDist, int N, int K) { int[] widths = new int[eDist.length + 2]; - int twoK = K << 1; + int twoK = 2 * K; widths[0] = 1; int i; int minEven = 10; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/expanded/BitArrayBuilder.java b/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/expanded/BitArrayBuilder.java index 5fe109c18..0fa4edeec 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/expanded/BitArrayBuilder.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/expanded/BitArrayBuilder.java @@ -40,7 +40,7 @@ final class BitArrayBuilder { } static BitArray buildBitArray(List pairs) { - int charNumber = (pairs.size() << 1) - 1; + int charNumber = (pairs.size() * 2) - 1; if (pairs.get(pairs.size() - 1).getRightChar() == null) { charNumber -= 1; } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/expanded/RSSExpandedReader.java b/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/expanded/RSSExpandedReader.java index 0d283a8d3..3f89e4b79 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/expanded/RSSExpandedReader.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/oned/rss/expanded/RSSExpandedReader.java @@ -639,7 +639,7 @@ public final class RSSExpandedReader extends AbstractRSSReader { } count = 8; } - int offset = i >> 1; + int offset = i / 2; if ((i & 0x01) == 0) { oddCounts[offset] = count; oddRoundingErrors[offset] = value - count; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/pdf417/PDF417Common.java b/extern/zxing-core/src/main/java/com/google/zxing/pdf417/PDF417Common.java index a784ef859..418f54cde 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/pdf417/PDF417Common.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/pdf417/PDF417Common.java @@ -15,6 +15,7 @@ */ package com.google.zxing.pdf417; +import java.util.Arrays; import java.util.Collection; /** @@ -63,38 +64,14 @@ public final class PDF417Common { * @param symbol encoded symbol to translate to a codeword * @return the codeword corresponding to the symbol. */ - public static int getCodeword(long symbol) { - long sym = symbol & 0x3FFFF; - int i = findCodewordIndex(sym); - if (i == -1) { + public static int getCodeword(int symbol) { + int i = Arrays.binarySearch(SYMBOL_TABLE, symbol & 0x3FFFF); + if (i < 0) { return -1; } return (CODEWORD_TABLE[i] - 1) % NUMBER_OF_CODEWORDS; } - /** - * Use a binary search to find the index of the codeword corresponding to - * this symbol. - * - * @param symbol the symbol from the barcode. - * @return the index into the codeword table. - */ - private static int findCodewordIndex(long symbol) { - int first = 0; - int upto = SYMBOL_TABLE.length; - while (first < upto) { - int mid = (first + upto) >>> 1; // Compute mid point. - if (symbol < SYMBOL_TABLE[mid]) { - upto = mid; // continue search in bottom half. - } else if (symbol > SYMBOL_TABLE[mid]) { - first = mid + 1; // continue search in top half. - } else { - return mid; // Found it. return position - } - } - return -1; - } - /** * The sorted table of all possible symbols. Extracted from the PDF417 * specification. The index of a symbol in this table corresponds to the diff --git a/extern/zxing-core/src/main/java/com/google/zxing/pdf417/decoder/DecodedBitStreamParser.java b/extern/zxing-core/src/main/java/com/google/zxing/pdf417/decoder/DecodedBitStreamParser.java index ab97a5597..876b324af 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/pdf417/decoder/DecodedBitStreamParser.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/pdf417/decoder/DecodedBitStreamParser.java @@ -17,10 +17,13 @@ package com.google.zxing.pdf417.decoder; import com.google.zxing.FormatException; +import com.google.zxing.common.CharacterSetECI; import com.google.zxing.common.DecoderResult; import com.google.zxing.pdf417.PDF417ResultMetadata; +import java.io.ByteArrayOutputStream; import java.math.BigInteger; +import java.nio.charset.Charset; import java.util.Arrays; /** @@ -44,6 +47,9 @@ final class DecodedBitStreamParser { private static final int BYTE_COMPACTION_MODE_LATCH = 901; private static final int NUMERIC_COMPACTION_MODE_LATCH = 902; private static final int BYTE_COMPACTION_MODE_LATCH_6 = 924; + private static final int ECI_USER_DEFINED = 925; + private static final int ECI_GENERAL_PURPOSE = 926; + private static final int ECI_CHARSET = 927; private static final int BEGIN_MACRO_PDF417_CONTROL_BLOCK = 928; private static final int BEGIN_MACRO_PDF417_OPTIONAL_FIELD = 923; private static final int MACRO_PDF417_TERMINATOR = 922; @@ -59,7 +65,7 @@ final class DecodedBitStreamParser { private static final int PAL = 29; private static final char[] PUNCT_CHARS = { - ';', '<', '>', '@', '[', '\\', '}', '_', '`', '~', '!', + ';', '<', '>', '@', '[', '\\', ']', '_', '`', '~', '!', '\r', '\t', ',', ':', '\n', '-', '.', '$', '/', '"', '|', '*', '(', ')', '?', '{', '}', '\''}; @@ -68,6 +74,8 @@ final class DecodedBitStreamParser { '\r', '\t', ',', ':', '#', '-', '.', '$', '/', '+', '%', '*', '=', '^'}; + private static final Charset DEFAULT_ENCODING = Charset.forName("ISO-8859-1"); + /** * Table containing values for the exponent of 900. * This is used in the numeric compaction decode algorithm. @@ -90,6 +98,7 @@ final class DecodedBitStreamParser { static DecoderResult decode(int[] codewords, String ecLevel) throws FormatException { StringBuilder result = new StringBuilder(codewords.length * 2); + Charset encoding = DEFAULT_ENCODING; // Get compaction mode int codeIndex = 1; int code = codewords[codeIndex++]; @@ -101,12 +110,27 @@ final class DecodedBitStreamParser { break; case BYTE_COMPACTION_MODE_LATCH: case BYTE_COMPACTION_MODE_LATCH_6: + codeIndex = byteCompaction(code, codewords, encoding, codeIndex, result); + break; case MODE_SHIFT_TO_BYTE_COMPACTION_MODE: - codeIndex = byteCompaction(code, codewords, codeIndex, result); + result.append((char) codewords[codeIndex++]); break; case NUMERIC_COMPACTION_MODE_LATCH: codeIndex = numericCompaction(codewords, codeIndex, result); break; + case ECI_CHARSET: + CharacterSetECI charsetECI = + CharacterSetECI.getCharacterSetECIByValue(codewords[codeIndex++]); + encoding = Charset.forName(charsetECI.name()); + break; + case ECI_GENERAL_PURPOSE: + // Can't do anything with generic ECI; skip its 2 characters + codeIndex += 2; + break; + case ECI_USER_DEFINED: + // Can't do anything with user ECI; skip its 1 character + codeIndex ++; + break; case BEGIN_MACRO_PDF417_CONTROL_BLOCK: codeIndex = decodeMacroBlock(codewords, codeIndex, resultMetadata); break; @@ -197,9 +221,9 @@ final class DecodedBitStreamParser { */ private static int textCompaction(int[] codewords, int codeIndex, StringBuilder result) { // 2 character per codeword - int[] textCompactionData = new int[(codewords[0] - codeIndex) << 1]; + int[] textCompactionData = new int[(codewords[0] - codeIndex) * 2]; // Used to hold the byte compaction value if there is a mode shift - int[] byteCompactionData = new int[(codewords[0] - codeIndex) << 1]; + int[] byteCompactionData = new int[(codewords[0] - codeIndex) * 2]; int index = 0; boolean end = false; @@ -316,6 +340,7 @@ final class DecodedBitStreamParser { priorToShiftMode = subMode; subMode = Mode.PUNCT_SHIFT; } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) { + // TODO Does this need to use the current character encoding? See other occurrences below result.append((char) byteCompactionData[i]); } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) { subMode = Mode.ALPHA; @@ -410,17 +435,22 @@ final class DecodedBitStreamParser { * * @param mode The byte compaction mode i.e. 901 or 924 * @param codewords The array of codewords (data + error) + * @param encoding Currently active character encoding * @param codeIndex The current index into the codeword array. * @param result The decoded data is appended to the result. * @return The next index into the codeword array. */ - private static int byteCompaction(int mode, int[] codewords, int codeIndex, StringBuilder result) { + private static int byteCompaction(int mode, + int[] codewords, + Charset encoding, + int codeIndex, + StringBuilder result) { + ByteArrayOutputStream decodedBytes = new ByteArrayOutputStream(); if (mode == BYTE_COMPACTION_MODE_LATCH) { // Total number of Byte Compaction characters to be encoded // is not a multiple of 6 int count = 0; long value = 0; - char[] decodedData = new char[6]; int[] byteCompactedCodewords = new int[6]; boolean end = false; int nextCode = codewords[codeIndex++]; @@ -444,10 +474,9 @@ final class DecodedBitStreamParser { // Decode every 5 codewords // Convert to Base 256 for (int j = 0; j < 6; ++j) { - decodedData[5 - j] = (char) (value % 256); - value >>= 8; + decodedBytes.write((byte) (value >> (8 * (5 - j)))); } - result.append(decodedData); + value = 0; count = 0; } } @@ -462,7 +491,7 @@ final class DecodedBitStreamParser { // the last group of codewords is interpreted directly // as one byte per codeword, without compaction. for (int i = 0; i < count; i++) { - result.append((char) byteCompactedCodewords[i]); + decodedBytes.write((byte) byteCompactedCodewords[i]); } } else if (mode == BYTE_COMPACTION_MODE_LATCH_6) { @@ -492,16 +521,15 @@ final class DecodedBitStreamParser { if ((count % 5 == 0) && (count > 0)) { // Decode every 5 codewords // Convert to Base 256 - char[] decodedData = new char[6]; for (int j = 0; j < 6; ++j) { - decodedData[5 - j] = (char) (value & 0xFF); - value >>= 8; + decodedBytes.write((byte) (value >> (8 * (5 - j)))); } - result.append(decodedData); + value = 0; count = 0; } } } + result.append(new String(decodedBytes.toByteArray(), encoding)); return codeIndex; } @@ -545,9 +573,11 @@ final class DecodedBitStreamParser { // while in Numeric Compaction mode) serves to terminate the // current Numeric Compaction mode grouping as described in 5.4.4.2, // and then to start a new one grouping. - String s = decodeBase900toBase10(numericCodewords, count); - result.append(s); - count = 0; + if (count > 0) { + String s = decodeBase900toBase10(numericCodewords, count); + result.append(s); + count = 0; + } } } return codeIndex; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/pdf417/decoder/PDF417ScanningDecoder.java b/extern/zxing-core/src/main/java/com/google/zxing/pdf417/decoder/PDF417ScanningDecoder.java index 106573694..56ead37cb 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/pdf417/decoder/PDF417ScanningDecoder.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/pdf417/decoder/PDF417ScanningDecoder.java @@ -326,27 +326,31 @@ public final class PDF417ScanningDecoder { throw ChecksumException.getChecksumInstance(); } - private static BarcodeValue[][] createBarcodeMatrix(DetectionResult detectionResult) { - BarcodeValue[][] barcodeMatrix = new BarcodeValue[detectionResult.getBarcodeRowCount()][detectionResult - .getBarcodeColumnCount() + 2]; + private static BarcodeValue[][] createBarcodeMatrix(DetectionResult detectionResult) throws FormatException { + BarcodeValue[][] barcodeMatrix = + new BarcodeValue[detectionResult.getBarcodeRowCount()][detectionResult.getBarcodeColumnCount() + 2]; for (int row = 0; row < barcodeMatrix.length; row++) { for (int column = 0; column < barcodeMatrix[row].length; column++) { barcodeMatrix[row][column] = new BarcodeValue(); } } - int column = -1; + int column = 0; for (DetectionResultColumn detectionResultColumn : detectionResult.getDetectionResultColumns()) { - column++; - if (detectionResultColumn == null) { - continue; - } - for (Codeword codeword : detectionResultColumn.getCodewords()) { - if (codeword == null || codeword.getRowNumber() == -1) { - continue; + if (detectionResultColumn != null) { + for (Codeword codeword : detectionResultColumn.getCodewords()) { + if (codeword != null) { + int rowNumber = codeword.getRowNumber(); + if (rowNumber >= 0) { + if (rowNumber >= barcodeMatrix.length) { + throw FormatException.getFormatInstance(); + } + barcodeMatrix[rowNumber][column].setValue(codeword.getValue()); + } + } } - barcodeMatrix[codeword.getRowNumber()][column].setValue(codeword.getValue()); } + column++; } return barcodeMatrix; } @@ -416,7 +420,7 @@ public final class PDF417ScanningDecoder { if (leftToRight) { endColumn = startColumn + codewordBitCount; } else { - for (int i = 0; i < moduleBitCount.length >> 1; i++) { + for (int i = 0; i < moduleBitCount.length / 2; i++) { int tmpCount = moduleBitCount[i]; moduleBitCount[i] = moduleBitCount[moduleBitCount.length - 1 - i]; moduleBitCount[moduleBitCount.length - 1 - i] = tmpCount; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/pdf417/decoder/ec/ErrorCorrection.java b/extern/zxing-core/src/main/java/com/google/zxing/pdf417/decoder/ec/ErrorCorrection.java index eb91d0abc..e34cb7fea 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/pdf417/decoder/ec/ErrorCorrection.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/pdf417/decoder/ec/ErrorCorrection.java @@ -62,11 +62,13 @@ public final class ErrorCorrection { } ModulusPoly knownErrors = field.getOne(); - for (int erasure : erasures) { - int b = field.exp(received.length - 1 - erasure); - // Add (1 - bx) term: - ModulusPoly term = new ModulusPoly(field, new int[] { field.subtract(0, b), 1 }); - knownErrors = knownErrors.multiply(term); + if (erasures != null) { + for (int erasure : erasures) { + int b = field.exp(received.length - 1 - erasure); + // Add (1 - bx) term: + ModulusPoly term = new ModulusPoly(field, new int[]{field.subtract(0, b), 1}); + knownErrors = knownErrors.multiply(term); + } } ModulusPoly syndrome = new ModulusPoly(field, S); diff --git a/extern/zxing-core/src/main/java/com/google/zxing/pdf417/decoder/ec/ModulusPoly.java b/extern/zxing-core/src/main/java/com/google/zxing/pdf417/decoder/ec/ModulusPoly.java index d2b96768d..053bbf7a9 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/pdf417/decoder/ec/ModulusPoly.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/pdf417/decoder/ec/ModulusPoly.java @@ -38,7 +38,7 @@ final class ModulusPoly { firstNonZero++; } if (firstNonZero == coefficientsLength) { - this.coefficients = field.getZero().coefficients; + this.coefficients = new int[]{0}; } else { this.coefficients = new int[coefficientsLength - firstNonZero]; System.arraycopy(coefficients, diff --git a/extern/zxing-core/src/main/java/com/google/zxing/pdf417/detector/Detector.java b/extern/zxing-core/src/main/java/com/google/zxing/pdf417/detector/Detector.java index 72a2eec34..1538e4a9c 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/pdf417/detector/Detector.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/pdf417/detector/Detector.java @@ -39,10 +39,8 @@ public final class Detector { private static final int[] INDEXES_START_PATTERN = {0, 4, 1, 5}; private static final int[] INDEXES_STOP_PATTERN = {6, 2, 7, 3}; - private static final int INTEGER_MATH_SHIFT = 8; - private static final int PATTERN_MATCH_RESULT_SCALE_FACTOR = 1 << INTEGER_MATH_SHIFT; - private static final int MAX_AVG_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.42f); - private static final int MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.8f); + private static final float MAX_AVG_VARIANCE = 0.42f; + private static final float MAX_INDIVIDUAL_VARIANCE = 0.8f; // B S B S B S B S Bar/Space pattern // 11111111 0 1 0 1 0 1 000 @@ -310,13 +308,9 @@ public final class Detector { * @param counters observed counters * @param pattern expected pattern * @param maxIndividualVariance The most any counter can differ before we give up - * @return ratio of total variance between counters and pattern compared to - * total pattern size, where the ratio has been multiplied by 256. - * So, 0 means no variance (perfect match); 256 means the total - * variance between counters and patterns equals the pattern length, - * higher values mean even more variance + * @return ratio of total variance between counters and pattern compared to total pattern size */ - private static int patternMatchVariance(int[] counters, int[] pattern, int maxIndividualVariance) { + private static float patternMatchVariance(int[] counters, int[] pattern, float maxIndividualVariance) { int numCounters = counters.length; int total = 0; int patternLength = 0; @@ -327,21 +321,21 @@ public final class Detector { if (total < patternLength) { // If we don't even have one pixel per unit of bar width, assume this // is too small to reliably match, so fail: - return Integer.MAX_VALUE; + return Float.POSITIVE_INFINITY; } // We're going to fake floating-point math in integers. We just need to use more bits. // Scale up patternLength so that intermediate values below like scaledCounter will have // more "significant digits". - int unitBarWidth = (total << INTEGER_MATH_SHIFT) / patternLength; - maxIndividualVariance = (maxIndividualVariance * unitBarWidth) >> INTEGER_MATH_SHIFT; + float unitBarWidth = (float) total / patternLength; + maxIndividualVariance *= unitBarWidth; - int totalVariance = 0; + float totalVariance = 0.0f; for (int x = 0; x < numCounters; x++) { - int counter = counters[x] << INTEGER_MATH_SHIFT; - int scaledPattern = pattern[x] * unitBarWidth; - int variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter; + int counter = counters[x]; + float scaledPattern = pattern[x] * unitBarWidth; + float variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter; if (variance > maxIndividualVariance) { - return Integer.MAX_VALUE; + return Float.POSITIVE_INFINITY; } totalVariance += variance; } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/pdf417/encoder/PDF417HighLevelEncoder.java b/extern/zxing-core/src/main/java/com/google/zxing/pdf417/encoder/PDF417HighLevelEncoder.java index 8a5db252a..ba84c3f44 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/pdf417/encoder/PDF417HighLevelEncoder.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/pdf417/encoder/PDF417HighLevelEncoder.java @@ -25,9 +25,7 @@ import com.google.zxing.common.CharacterSetECI; import java.math.BigInteger; import java.nio.charset.Charset; -import java.nio.charset.UnsupportedCharsetException; import java.util.Arrays; -import java.util.List; /** * PDF417 high-level encoder following the algorithm described in ISO/IEC 15438:2001(E) in @@ -127,7 +125,7 @@ final class PDF417HighLevelEncoder { private static final byte[] MIXED = new byte[128]; private static final byte[] PUNCTUATION = new byte[128]; - private static final List DEFAULT_ENCODING_NAMES = Arrays.asList("Cp437", "IBM437"); + private static final Charset DEFAULT_ENCODING = Charset.forName("ISO-8859-1"); private PDF417HighLevelEncoder() { } @@ -166,7 +164,9 @@ final class PDF417HighLevelEncoder { //the codewords 0..928 are encoded as Unicode characters StringBuilder sb = new StringBuilder(msg.length()); - if (encoding != null || !DEFAULT_ENCODING_NAMES.contains(encoding.name())) { + if (encoding == null) { + encoding = DEFAULT_ENCODING; + } else if (!DEFAULT_ENCODING.equals(encoding)) { CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding.name()); if (eci != null) { encodingECI(eci.getValue(), sb); @@ -183,7 +183,7 @@ final class PDF417HighLevelEncoder { encodeText(msg, p, len, sb, textSubMode); } else if (compaction == Compaction.BYTE) { - bytes = toBytes(msg, encoding); + bytes = msg.getBytes(encoding); encodeBinary(bytes, p, bytes.length, BYTE_COMPACTION, sb); } else if (compaction == Compaction.NUMERIC) { @@ -212,7 +212,7 @@ final class PDF417HighLevelEncoder { p += t; } else { if (bytes == null) { - bytes = toBytes(msg, encoding); + bytes = msg.getBytes(encoding); } int b = determineConsecutiveBinaryCount(msg, bytes, p); if (b == 0) { @@ -236,24 +236,6 @@ final class PDF417HighLevelEncoder { return sb.toString(); } - private static byte[] toBytes(String msg, Charset encoding) throws WriterException { - // Defer instantiating default Charset until needed, since it may be for an unsupported - // encoding. For example the default of Cp437 doesn't seem to exist on Android. - if (encoding == null) { - for (String encodingName : DEFAULT_ENCODING_NAMES) { - try { - encoding = Charset.forName(encodingName); - } catch (UnsupportedCharsetException uce) { - // continue - } - } - if (encoding == null) { - throw new WriterException("No support for any encoding: " + DEFAULT_ENCODING_NAMES); - } - } - return msg.getBytes(encoding); - } - /** * Encode parts of the message using Text Compaction as described in ISO/IEC 15438:2001(E), * chapter 4.4.2. @@ -439,7 +421,7 @@ final class PDF417HighLevelEncoder { StringBuilder tmp = new StringBuilder(count / 3 + 1); BigInteger num900 = BigInteger.valueOf(900); BigInteger num0 = BigInteger.valueOf(0); - while (idx < count - 1) { + while (idx < count) { tmp.setLength(0); int len = Math.min(44, count - idx); String part = '1' + msg.substring(startpos + idx, startpos + idx + len); @@ -572,18 +554,6 @@ final class PDF417HighLevelEncoder { if (numericCount >= 13) { return idx - startpos; } - int textCount = 0; - while (textCount < 5 && isText(ch)) { - textCount++; - int i = idx + textCount; - if (i >= len) { - break; - } - ch = msg.charAt(i); - } - if (textCount >= 5) { - return idx - startpos; - } ch = msg.charAt(idx); //Check if character is encodable diff --git a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/QRCodeReader.java b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/QRCodeReader.java index 96284de3a..310a40926 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/QRCodeReader.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/QRCodeReader.java @@ -159,7 +159,9 @@ public class QRCodeReader implements Reader { left += nudge; // But careful that this does not sample off the edge - int nudgedTooFarRight = left + (int) ((matrixWidth - 1) * moduleSize) - (right - 1); + // "right" is the farthest-right valid pixel location -- right+1 is not necessarily + // This is positive by how much the inner x loop below would be too large + int nudgedTooFarRight = left + (int) ((matrixWidth - 1) * moduleSize) - right; if (nudgedTooFarRight > 0) { if (nudgedTooFarRight > nudge) { // Neither way fits; abort @@ -167,7 +169,8 @@ public class QRCodeReader implements Reader { } left -= nudgedTooFarRight; } - int nudgedTooFarDown = top + (int) ((matrixHeight - 1) * moduleSize) - (bottom - 1); + // See logic above + int nudgedTooFarDown = top + (int) ((matrixHeight - 1) * moduleSize) - bottom; if (nudgedTooFarDown > 0) { if (nudgedTooFarDown > nudge) { // Neither way fits; abort diff --git a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/QRCodeWriter.java b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/QRCodeWriter.java index a4fabf406..f5dcf089e 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/QRCodeWriter.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/QRCodeWriter.java @@ -90,8 +90,8 @@ public final class QRCodeWriter implements Writer { } int inputWidth = input.getWidth(); int inputHeight = input.getHeight(); - int qrWidth = inputWidth + (quietZone << 1); - int qrHeight = inputHeight + (quietZone << 1); + int qrWidth = inputWidth + (quietZone * 2); + int qrHeight = inputHeight + (quietZone * 2); int outputWidth = Math.max(width, qrWidth); int outputHeight = Math.max(height, qrHeight); diff --git a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/decoder/BitMatrixParser.java b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/decoder/BitMatrixParser.java index 7d3d949bd..10cb475a9 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/decoder/BitMatrixParser.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/decoder/BitMatrixParser.java @@ -101,7 +101,7 @@ final class BitMatrixParser { int dimension = bitMatrix.getHeight(); - int provisionalVersion = (dimension - 17) >> 2; + int provisionalVersion = (dimension - 17) / 4; if (provisionalVersion <= 6) { return Version.getVersionForNumber(provisionalVersion); } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/decoder/DataMask.java b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/decoder/DataMask.java index 353c1a826..c1dbbb798 100755 --- a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/decoder/DataMask.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/decoder/DataMask.java @@ -125,7 +125,7 @@ abstract class DataMask { private static final class DataMask100 extends DataMask { @Override boolean isMasked(int i, int j) { - return (((i >>> 1) + (j /3)) & 0x01) == 0; + return (((i / 2) + (j /3)) & 0x01) == 0; } } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/decoder/DecodedBitStreamParser.java b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/decoder/DecodedBitStreamParser.java index 09e8a5745..319495802 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/decoder/DecodedBitStreamParser.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/decoder/DecodedBitStreamParser.java @@ -217,7 +217,7 @@ final class DecodedBitStreamParser { Collection byteSegments, Map hints) throws FormatException { // Don't crash trying to read more bits than we have available. - if (count << 3 > bits.available()) { + if (8 * count > bits.available()) { throw FormatException.getFormatInstance(); } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/decoder/Version.java b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/decoder/Version.java index b649e207e..cc4052508 100755 --- a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/decoder/Version.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/decoder/Version.java @@ -94,7 +94,7 @@ public final class Version { throw FormatException.getFormatInstance(); } try { - return getVersionForNumber((dimension - 17) >> 2); + return getVersionForNumber((dimension - 17) / 4); } catch (IllegalArgumentException ignored) { throw FormatException.getFormatInstance(); } diff --git a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/detector/AlignmentPatternFinder.java b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/detector/AlignmentPatternFinder.java index 95fbc2ecb..b6e1b5dbe 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/detector/AlignmentPatternFinder.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/detector/AlignmentPatternFinder.java @@ -88,13 +88,13 @@ final class AlignmentPatternFinder { int startX = this.startX; int height = this.height; int maxJ = startX + width; - int middleI = startY + (height >> 1); + int middleI = startY + (height / 2); // We are looking for black/white/black modules in 1:1:1 ratio; // this tracks the number of black/white/black modules seen so far int[] stateCount = new int[3]; for (int iGen = 0; iGen < height; iGen++) { // Search from middle outwards - int i = middleI + ((iGen & 0x01) == 0 ? (iGen + 1) >> 1 : -((iGen + 1) >> 1)); + int i = middleI + ((iGen & 0x01) == 0 ? (iGen + 1) / 2 : -((iGen + 1) / 2)); stateCount[0] = 0; stateCount[1] = 0; stateCount[2] = 0; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/detector/Detector.java b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/detector/Detector.java index beae1a6a0..d802a1359 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/detector/Detector.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/detector/Detector.java @@ -201,7 +201,7 @@ public class Detector { float moduleSize) throws NotFoundException { int tltrCentersDimension = MathUtils.round(ResultPoint.distance(topLeft, topRight) / moduleSize); int tlblCentersDimension = MathUtils.round(ResultPoint.distance(topLeft, bottomLeft) / moduleSize); - int dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7; + int dimension = ((tltrCentersDimension + tlblCentersDimension) / 2) + 7; switch (dimension & 0x03) { // mod 4 case 0: dimension++; @@ -318,7 +318,7 @@ public class Detector { int dx = Math.abs(toX - fromX); int dy = Math.abs(toY - fromY); - int error = -dx >> 1; + int error = -dx / 2; int xstep = fromX < toX ? 1 : -1; int ystep = fromY < toY ? 1 : -1; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/detector/FinderPatternFinder.java b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/detector/FinderPatternFinder.java index f35b0af4b..9c0c59f89 100755 --- a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/detector/FinderPatternFinder.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/detector/FinderPatternFinder.java @@ -42,7 +42,6 @@ public class FinderPatternFinder { private static final int CENTER_QUORUM = 2; protected static final int MIN_SKIP = 3; // 1 pixel/module times 3 modules/center protected static final int MAX_MODULES = 57; // support up to version 10 for mobile clients - private static final int INTEGER_MATH_SHIFT = 8; private final BitMatrix image; private final List possibleCenters; @@ -209,14 +208,15 @@ public class FinderPatternFinder { if (totalModuleSize < 7) { return false; } - int moduleSize = (totalModuleSize << INTEGER_MATH_SHIFT) / 7; - int maxVariance = moduleSize / 2; + float moduleSize = totalModuleSize / 7.0f; + float maxVariance = moduleSize / 2.0f; // Allow less than 50% variance from 1-1-3-1-1 proportions - return Math.abs(moduleSize - (stateCount[0] << INTEGER_MATH_SHIFT)) < maxVariance && - Math.abs(moduleSize - (stateCount[1] << INTEGER_MATH_SHIFT)) < maxVariance && - Math.abs(3 * moduleSize - (stateCount[2] << INTEGER_MATH_SHIFT)) < 3 * maxVariance && - Math.abs(moduleSize - (stateCount[3] << INTEGER_MATH_SHIFT)) < maxVariance && - Math.abs(moduleSize - (stateCount[4] << INTEGER_MATH_SHIFT)) < maxVariance; + return + Math.abs(moduleSize - stateCount[0]) < maxVariance && + Math.abs(moduleSize - stateCount[1]) < maxVariance && + Math.abs(3.0f * moduleSize - stateCount[2]) < 3 * maxVariance && + Math.abs(moduleSize - stateCount[3]) < maxVariance && + Math.abs(moduleSize - stateCount[4]) < maxVariance; } private int[] getCrossCheckStateCount() { diff --git a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/encoder/Encoder.java b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/encoder/Encoder.java index 425ca8ed0..ae2fc5456 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/encoder/Encoder.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/encoder/Encoder.java @@ -268,7 +268,7 @@ public final class Encoder { * Terminate bits as described in 8.4.8 and 8.4.9 of JISX0510:2004 (p.24). */ static void terminateBits(int numDataBytes, BitArray bits) throws WriterException { - int capacity = numDataBytes << 3; + int capacity = numDataBytes * 8; if (bits.getSize() > capacity) { throw new WriterException("data bits cannot fit in the QR Code" + bits.getSize() + " > " + capacity); diff --git a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/encoder/MaskUtil.java b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/encoder/MaskUtil.java index 6b0062bca..b2204d4a9 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/encoder/MaskUtil.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/encoder/MaskUtil.java @@ -163,7 +163,7 @@ final class MaskUtil { intermediate = (y + x) % 3; break; case 4: - intermediate = ((y >>> 1) + (x / 3)) & 0x1; + intermediate = ((y / 2) + (x / 3)) & 0x1; break; case 5: temp = y * x; diff --git a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/encoder/MatrixUtil.java b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/encoder/MatrixUtil.java index 37e21fa2b..dac25f8de 100644 --- a/extern/zxing-core/src/main/java/com/google/zxing/qrcode/encoder/MatrixUtil.java +++ b/extern/zxing-core/src/main/java/com/google/zxing/qrcode/encoder/MatrixUtil.java @@ -305,6 +305,9 @@ final class MatrixUtil { // Since all coefficients in the polynomials are 1 or 0, we can do the calculation by bit // operations. We don't care if cofficients are positive or negative. static int calculateBCHCode(int value, int poly) { + if (poly == 0) { + throw new IllegalArgumentException("0 polynomial"); + } // If poly is "1 1111 0010 0101" (version info poly), msbSetInPoly is 13. We'll subtract 1 // from 13 to make it 12. int msbSetInPoly = findMSBSet(poly);