Skip to content

Commit

Permalink
move to singleton ReaderException for a bit more performance
Browse files Browse the repository at this point in the history
git-svn-id: http://zxing.googlecode.com/svn/trunk@714 59b500cc-1b3d-0410-9834-0bbf25fbcc57
  • Loading branch information
srowen committed Nov 17, 2008
1 parent a8392ed commit 1170ad0
Show file tree
Hide file tree
Showing 30 changed files with 109 additions and 105 deletions.
Expand Up @@ -47,7 +47,7 @@ public AWTImageMonochromeBitmapSource(Image image) throws ReaderException {
try {
grabber.grabPixels();
} catch (InterruptedException ie) {
throw new ReaderException("Interrupted while reading pixels");
throw ReaderException.getInstance();
}
}

Expand Down
30 changes: 18 additions & 12 deletions core/src/com/google/zxing/ReaderException.java
Expand Up @@ -23,19 +23,25 @@
*
* @author Sean Owen
*/
public final class ReaderException extends Exception {

// TODO: Currently we throw up to 400 ReaderExceptions while scanning a single 240x240 image before
// rejecting it. This involves a lot of overhead and memory allocation, and affects both performance
// and latency on continuous scan clients. In the future, we should change all the decoders not to
// throw exceptions for routine events, like not finding a barcode on a given row. Instead, we
// should return error codes back to the callers, and simply delete this class. In the mean time, I
// have altered this class to be as lightweight as possible, by ignoring the exception string, and
// by disabling the generation of stack traces, which is especially time consuming. These are just
// temporary measures, pending the big cleanup.
public final class ReaderException extends java.lang.Throwable {

public ReaderException(String message) {
// Do not pass message to Throwable, let it get optimized out
// TODO: Currently we throw up to 400 ReaderExceptions while scanning a single 240x240 image before
// rejecting it. This involves a lot of overhead and memory allocation, and affects both performance
// and latency on continuous scan clients. In the future, we should change all the decoders not to
// throw exceptions for routine events, like not finding a barcode on a given row. Instead, we
// should return error codes back to the callers, and simply delete this class. In the mean time, I
// have altered this class to be as lightweight as possible, by ignoring the exception string, and
// by disabling the generation of stack traces, which is especially time consuming. These are just
// temporary measures, pending the big cleanup.

private static final ReaderException instance = new ReaderException();

private ReaderException() {
// do nothing
}

public static ReaderException getInstance() {
return instance;
}

// Prevent stack traces from being taken
Expand Down
2 changes: 1 addition & 1 deletion core/src/com/google/zxing/common/BlackPointEstimator.java
Expand Up @@ -88,7 +88,7 @@ public static int estimate(int[] histogram) throws ReaderException{
// for 1D formats, which are relatively lenient.
// We arbitrarily say "close" is "<= 1/16 of the total histogram buckets apart"
if (secondPeak - firstPeak <= numBuckets >> 4) {
throw new ReaderException("Too little dynamic range in luminance");
throw ReaderException.getInstance();
}

// Find a valley between them that is low and closer to the white peak
Expand Down
2 changes: 1 addition & 1 deletion core/src/com/google/zxing/common/DefaultGridSampler.java
Expand Up @@ -67,7 +67,7 @@ public BitMatrix sampleGrid(MonochromeBitmapSource image,
// This results in an ugly runtime exception despite our clever checks above -- can't have that.
// We could check each point's coordinates but that feels duplicative. We settle for
// catching and wrapping ArrayIndexOutOfBoundsException.
throw new ReaderException(aioobe.toString());
throw ReaderException.getInstance();
}
}
return bits;
Expand Down
4 changes: 2 additions & 2 deletions core/src/com/google/zxing/common/GridSampler.java
Expand Up @@ -122,7 +122,7 @@ protected static void checkAndNudgePoints(MonochromeBitmapSource image, float[]
int x = (int) points[offset];
int y = (int) points[offset + 1];
if (x < -1 || x > width || y < -1 || y > height) {
throw new ReaderException("Transformed point out of bounds at " + x + ',' + y);
throw ReaderException.getInstance();
}
nudged = false;
if (x == -1) {
Expand All @@ -146,7 +146,7 @@ protected static void checkAndNudgePoints(MonochromeBitmapSource image, float[]
int x = (int) points[offset];
int y = (int) points[offset + 1];
if (x < -1 || x > width || y < -1 || y > height) {
throw new ReaderException("Transformed point out of bounds at " + x + ',' + y);
throw ReaderException.getInstance();
}
nudged = false;
if (x == -1) {
Expand Down
11 changes: 5 additions & 6 deletions core/src/com/google/zxing/datamatrix/DataMatrixReader.java
Expand Up @@ -92,7 +92,7 @@ private static BitMatrix extractPureBits(MonochromeBitmapSource image) throws Re
borderWidth++;
}
if (borderWidth == minDimension) {
throw new ReaderException("No black pixels found along diagonal");
throw ReaderException.getInstance();
}

// And then keep tracking across the top-left black module to determine module size
Expand All @@ -101,7 +101,7 @@ private static BitMatrix extractPureBits(MonochromeBitmapSource image) throws Re
moduleEnd++;
}
if (moduleEnd == width) {
throw new ReaderException("No end to black pixels found along row");
throw ReaderException.getInstance();
}

int moduleSize = moduleEnd - borderWidth;
Expand All @@ -112,14 +112,13 @@ private static BitMatrix extractPureBits(MonochromeBitmapSource image) throws Re
columnEndOfSymbol--;
}
if (columnEndOfSymbol < 0) {
throw new ReaderException("Can't find end of bottommost black module");
throw ReaderException.getInstance();
}
columnEndOfSymbol++;

// Make sure width of barcode is a multiple of module size
if ((columnEndOfSymbol - borderWidth) % moduleSize != 0) {
throw new ReaderException("Bad module size / width: " + moduleSize +
" / " + (columnEndOfSymbol - borderWidth));
throw ReaderException.getInstance();
}
int dimension = (columnEndOfSymbol - borderWidth) / moduleSize;

Expand All @@ -130,7 +129,7 @@ private static BitMatrix extractPureBits(MonochromeBitmapSource image) throws Re

int sampleDimension = borderWidth + (dimension - 1) * moduleSize;
if (sampleDimension >= width || sampleDimension >= height) {
throw new ReaderException("Estimated pure image size is beyond image boundaries");
throw ReaderException.getInstance();
}

// Now just read off the bits
Expand Down
Expand Up @@ -35,7 +35,7 @@ final class BitMatrixParser {
BitMatrixParser(BitMatrix bitMatrix) throws ReaderException {
int dimension = bitMatrix.getDimension();
if (dimension < 10 || dimension > 144 || (dimension & 0x01) != 0) {
throw new ReaderException("Invalid dimension (" + dimension + ") Must be 0 mod 2 and >= 10 and <= 144");
throw ReaderException.getInstance();
}

version = readVersion(bitMatrix);
Expand Down Expand Up @@ -141,7 +141,7 @@ byte[] readCodewords() throws ReaderException {
} while ((row < numRows) || (column < numColumns));

if (resultOffset != version.getTotalCodewords()) {
throw new ReaderException("Did not read all codewords");
throw ReaderException.getInstance();
}
return result;
}
Expand Down
Expand Up @@ -102,7 +102,7 @@ static DecoderResult decode(byte[] bytes) throws ReaderException {
decodeBase256Segment(bits, result, byteSegments);
break;
default:
throw new ReaderException("Unsupported mode indicator");
throw ReaderException.getInstance();
}
mode = ASCII_ENCODE;
}
Expand All @@ -122,7 +122,7 @@ private static int decodeAsciiSegment(BitSource bits, StringBuffer result, Strin
do {
int oneByte = bits.readBits(8);
if (oneByte == 0) {
throw new ReaderException("0 is an invalid ASCII codeword");
throw ReaderException.getInstance();
} else if (oneByte <= 128) { // ASCII data (ASCII value + 1)
oneByte = upperShift ? (oneByte + 128) : oneByte;
upperShift = false;
Expand All @@ -141,11 +141,11 @@ private static int decodeAsciiSegment(BitSource bits, StringBuffer result, Strin
} else if (oneByte == 231) { // Latch to Base 256 encodation
return BASE256_ENCODE;
} else if (oneByte == 232) { // FNC1
throw new ReaderException("Currently not supporting FNC1");
throw ReaderException.getInstance();
} else if (oneByte == 233) { // Structured Append
throw new ReaderException("Currently not supporting Structured Append");
throw ReaderException.getInstance();
} else if (oneByte == 234) { // Reader Programming
throw new ReaderException("Currently not supporting Reader Programming");
throw ReaderException.getInstance();
} else if (oneByte == 235) { // Upper Shift (shift to Extended ASCII)
upperShift = true;
} else if (oneByte == 236) { // 05 Macro
Expand All @@ -162,9 +162,9 @@ private static int decodeAsciiSegment(BitSource bits, StringBuffer result, Strin
return EDIFACT_ENCODE;
} else if (oneByte == 241) { // ECI Character
// TODO(bbrown): I think we need to support ECI
throw new ReaderException("Currently not supporting ECI Character");
throw ReaderException.getInstance();
} else if (oneByte >= 242) { // Not to be used in ASCII encodation
throw new ReaderException(oneByte + " should not be used in ASCII encodation");
throw ReaderException.getInstance();
}
} while (bits.available() > 0);
return ASCII_ENCODE;
Expand Down Expand Up @@ -226,11 +226,11 @@ private static void decodeC40Segment(BitSource bits, StringBuffer result) throws
result.append(C40_SHIFT2_SET_CHARS[cValue]);
}
} else if (cValue == 27) { // FNC1
throw new ReaderException("Currently not supporting FNC1");
throw ReaderException.getInstance();
} else if (cValue == 30) { // Upper Shift
upperShift = true;
} else {
throw new ReaderException(cValue + " is not valid in the C40 Shift 2 set");
throw ReaderException.getInstance();
}
shift = 0;
break;
Expand All @@ -244,7 +244,7 @@ private static void decodeC40Segment(BitSource bits, StringBuffer result) throws
shift = 0;
break;
default:
throw new ReaderException("Invalid shift value");
throw ReaderException.getInstance();
}
}
} while (bits.available() > 0);
Expand Down Expand Up @@ -307,11 +307,11 @@ private static void decodeTextSegment(BitSource bits, StringBuffer result) throw
result.append(C40_SHIFT2_SET_CHARS[cValue]);
}
} else if (cValue == 27) { // FNC1
throw new ReaderException("Currently not supporting FNC1");
throw ReaderException.getInstance();
} else if (cValue == 30) { // Upper Shift
upperShift = true;
} else {
throw new ReaderException(cValue + " is not valid in the C40 Shift 2 set");
throw ReaderException.getInstance();
}
shift = 0;
break;
Expand All @@ -325,7 +325,7 @@ private static void decodeTextSegment(BitSource bits, StringBuffer result) throw
shift = 0;
break;
default:
throw new ReaderException("Invalid shift value");
throw ReaderException.getInstance();
}
}
} while (bits.available() > 0);
Expand Down Expand Up @@ -366,7 +366,7 @@ private static void decodeAnsiX12Segment(BitSource bits, StringBuffer result) th
} else if (cValue < 40) { // A - Z
result.append((char) (cValue + 51));
} else {
throw new ReaderException(cValue + " is not valid in the ANSI X12 set");
throw ReaderException.getInstance();
}
}
} while (bits.available() > 0);
Expand Down
2 changes: 1 addition & 1 deletion core/src/com/google/zxing/datamatrix/decoder/Decoder.java
Expand Up @@ -119,7 +119,7 @@ private void correctErrors(byte[] codewordBytes, int numDataCodewords) throws Re
try {
rsDecoder.decode(codewordsInts, numECCodewords);
} catch (ReedSolomonException rse) {
throw new ReaderException(rse.toString());
throw ReaderException.getInstance();
}
// Copy back into array of bytes -- only need to worry about the bytes that were data
// We don't care about errors in the error-correction codewords
Expand Down
4 changes: 2 additions & 2 deletions core/src/com/google/zxing/datamatrix/decoder/Version.java
Expand Up @@ -98,7 +98,7 @@ ECBlocks getECBlocks() {
*/
public static Version getVersionForDimensions(int numRows, int numColumns) throws ReaderException {
if ((numRows & 0x01) != 0 || (numColumns & 0x01) != 0) {
throw new ReaderException("Dimension must be 0 mod 2");
throw ReaderException.getInstance();
}

// TODO(bbrown): This is doing a linear search through the array of versions.
Expand All @@ -112,7 +112,7 @@ public static Version getVersionForDimensions(int numRows, int numColumns) throw
}
}

throw new ReaderException("Dimensions do not correspond to a valid Data Matrix Version.");
throw ReaderException.getInstance();
}

/**
Expand Down
6 changes: 3 additions & 3 deletions core/src/com/google/zxing/datamatrix/detector/Detector.java
Expand Up @@ -130,7 +130,7 @@ public DetectorResult detect() throws ReaderException {
}

if (maybeTopLeft == null || bottomLeft == null || maybeBottomRight == null) {
throw new ReaderException("Could not find three corners");
throw ReaderException.getInstance();
}

// Bottom left is correct but top left and bottom right might be switched
Expand Down Expand Up @@ -212,7 +212,7 @@ private ResultPoint findCornerFromCenter(int centerI, int di, int minI, int maxI
}
if (range == null) {
if (lastRange == null) {
throw new ReaderException("Center of image not within barcode");
throw ReaderException.getInstance();
}
// lastRange was found
if (dj == 0) {
Expand Down Expand Up @@ -240,7 +240,7 @@ private ResultPoint findCornerFromCenter(int centerI, int di, int minI, int maxI
}
lastRange = range;
}
throw new ReaderException("Couldn't find an end to barcode");
throw ReaderException.getInstance();
}

/**
Expand Down
6 changes: 3 additions & 3 deletions core/src/com/google/zxing/oned/AbstractOneDReader.java
Expand Up @@ -140,7 +140,7 @@ private Result doDecode(MonochromeBitmapSource image, Hashtable hints) throws Re
}
}

throw new ReaderException("No barcode found");
throw ReaderException.getInstance();
}

/**
Expand All @@ -162,7 +162,7 @@ static void recordPattern(BitArray row, int start, int[] counters) throws Reader
}
int end = row.getSize();
if (start >= end) {
throw new ReaderException("Couldn't fully read a pattern");
throw ReaderException.getInstance();
}
boolean isWhite = !row.get(start);
int counterPosition = 0;
Expand All @@ -185,7 +185,7 @@ static void recordPattern(BitArray row, int start, int[] counters) throws Reader
// If we read fully the last section of pixels and filled up our counters -- or filled
// the last counter but ran off the side of the image, OK. Otherwise, a problem.
if (!(counterPosition == numCounters || (counterPosition == numCounters - 1 && i == end))) {
throw new ReaderException("Couldn't fully read a pattern");
throw ReaderException.getInstance();
}
}

Expand Down
12 changes: 6 additions & 6 deletions core/src/com/google/zxing/oned/AbstractUPCEANReader.java
Expand Up @@ -124,12 +124,12 @@ public final Result decodeRow(int rowNumber, BitArray row, int[] startGuardRange
int end = endRange[1];
int quietEnd = end + (end - endRange[0]);
if (quietEnd >= row.getSize() || !row.isRange(end, quietEnd, false)) {
throw new ReaderException("Pattern not followed by whitespace");
throw ReaderException.getInstance();
}

String resultString = result.toString();
if (!checkChecksum(resultString)) {
throw new ReaderException("Checksum failed");
throw ReaderException.getInstance();
}

float left = (float) (startGuardRange[1] + startGuardRange[0]) / 2.0f;
Expand Down Expand Up @@ -162,15 +162,15 @@ boolean checkChecksum(String s) throws ReaderException {
for (int i = length - 2; i >= 0; i -= 2) {
int digit = (int) s.charAt(i) - (int) '0';
if (digit < 0 || digit > 9) {
throw new ReaderException("Illegal character during checksum");
throw ReaderException.getInstance();
}
sum += digit;
}
sum *= 3;
for (int i = length - 1; i >= 0; i -= 2) {
int digit = (int) s.charAt(i) - (int) '0';
if (digit < 0 || digit > 9) {
throw new ReaderException("Illegal character during checksum");
throw ReaderException.getInstance();
}
sum += digit;
}
Expand Down Expand Up @@ -242,7 +242,7 @@ static int[] findGuardPattern(BitArray row, int rowOffset, boolean whiteFirst, i
isWhite = !isWhite;
}
}
throw new ReaderException("Can't find pattern");
throw ReaderException.getInstance();
}

/**
Expand Down Expand Up @@ -274,7 +274,7 @@ static int decodeDigit(BitArray row, int[] counters, int rowOffset, int[][] patt
if (bestMatch >= 0) {
return bestMatch;
} else {
throw new ReaderException("Could not match any digit in pattern");
throw ReaderException.getInstance();
}
}

Expand Down

0 comments on commit 1170ad0

Please sign in to comment.