From a8b57c466db92391e26cc156c218042e6096495a Mon Sep 17 00:00:00 2001 From: dswitkin Date: Sat, 1 Nov 2008 02:31:05 +0000 Subject: [PATCH] Discovered that our 1D Readers were being reallocated for every row scanned - yikes! I made them reusable across both rows and different scans. This saved 26 ms on the worst case rejection. We can now consistently reject any 240x240 image on Android in 150 ms or less, checking all 7 formats. git-svn-id: https://zxing.googlecode.com/svn/trunk@661 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- core/src/com/google/zxing/MultiFormatReader.java | 14 ++++++++------ .../google/zxing/oned/MultiFormatOneDReader.java | 16 ++++++++++------ .../zxing/oned/MultiFormatUPCEANReader.java | 13 +++++++++---- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/core/src/com/google/zxing/MultiFormatReader.java b/core/src/com/google/zxing/MultiFormatReader.java index 8331cedf8..cb8385df4 100644 --- a/core/src/com/google/zxing/MultiFormatReader.java +++ b/core/src/com/google/zxing/MultiFormatReader.java @@ -62,7 +62,8 @@ public final class MultiFormatReader implements Reader { } /** - * Decode an image using the state set up by calling setHints() previously. + * Decode an image using the state set up by calling setHints() previously. Continuous scan + * clients will get a large speed increase by using this instead of decode(). * * @param image The pixel data to decode * @return The contents of the image @@ -99,7 +100,7 @@ public final class MultiFormatReader implements Reader { possibleFormats.contains(BarcodeFormat.CODE_128); // Put 1D readers upfront in "normal" mode if (addOneDReader && !tryHarder) { - readers.addElement(new MultiFormatOneDReader()); + readers.addElement(new MultiFormatOneDReader(hints)); } if (possibleFormats.contains(BarcodeFormat.QR_CODE)) { readers.addElement(new QRCodeReader()); @@ -110,24 +111,25 @@ public final class MultiFormatReader implements Reader { //} // At end in "try harder" mode if (addOneDReader && tryHarder) { - readers.addElement(new MultiFormatOneDReader()); + readers.addElement(new MultiFormatOneDReader(hints)); } } if (readers.isEmpty()) { if (!tryHarder) { - readers.addElement(new MultiFormatOneDReader()); + readers.addElement(new MultiFormatOneDReader(hints)); } readers.addElement(new QRCodeReader()); // TODO re-enable once Data Matrix is ready // readers.addElement(new DataMatrixReader()); if (tryHarder) { - readers.addElement(new MultiFormatOneDReader()); + readers.addElement(new MultiFormatOneDReader(hints)); } } } private Result decodeInternal(MonochromeBitmapSource image) throws ReaderException { - for (int i = 0; i < readers.size(); i++) { + int size = readers.size(); + for (int i = 0; i < size; i++) { Reader reader = (Reader) readers.elementAt(i); try { return reader.decode(image, hints); diff --git a/core/src/com/google/zxing/oned/MultiFormatOneDReader.java b/core/src/com/google/zxing/oned/MultiFormatOneDReader.java index 46dd2c501..df1ef2780 100644 --- a/core/src/com/google/zxing/oned/MultiFormatOneDReader.java +++ b/core/src/com/google/zxing/oned/MultiFormatOneDReader.java @@ -31,16 +31,17 @@ import java.util.Vector; */ public final class MultiFormatOneDReader extends AbstractOneDReader { - public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws ReaderException { + private Vector readers; + public MultiFormatOneDReader(Hashtable hints) { Vector possibleFormats = hints == null ? null : (Vector) hints.get(DecodeHintType.POSSIBLE_FORMATS); - Vector readers = new Vector(); + readers = new Vector(); if (possibleFormats != null) { if (possibleFormats.contains(BarcodeFormat.EAN_13) || possibleFormats.contains(BarcodeFormat.UPC_A) || possibleFormats.contains(BarcodeFormat.EAN_8) || possibleFormats.contains(BarcodeFormat.UPC_E)) { - readers.addElement(new MultiFormatUPCEANReader()); + readers.addElement(new MultiFormatUPCEANReader(hints)); } if (possibleFormats.contains(BarcodeFormat.CODE_39)) { readers.addElement(new Code39Reader()); @@ -50,12 +51,15 @@ public final class MultiFormatOneDReader extends AbstractOneDReader { } } if (readers.isEmpty()) { - readers.addElement(new MultiFormatUPCEANReader()); + readers.addElement(new MultiFormatUPCEANReader(hints)); readers.addElement(new Code39Reader()); readers.addElement(new Code128Reader()); } + } - for (int i = 0; i < readers.size(); i++) { + public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws ReaderException { + int size = readers.size(); + for (int i = 0; i < size; i++) { OneDReader reader = (OneDReader) readers.elementAt(i); try { return reader.decodeRow(rowNumber, row, hints); @@ -67,4 +71,4 @@ public final class MultiFormatOneDReader extends AbstractOneDReader { throw new ReaderException("No barcode was detected in this image."); } -} \ No newline at end of file +} diff --git a/core/src/com/google/zxing/oned/MultiFormatUPCEANReader.java b/core/src/com/google/zxing/oned/MultiFormatUPCEANReader.java index 26977b044..ce45202d9 100644 --- a/core/src/com/google/zxing/oned/MultiFormatUPCEANReader.java +++ b/core/src/com/google/zxing/oned/MultiFormatUPCEANReader.java @@ -34,9 +34,11 @@ import java.util.Vector; */ public final class MultiFormatUPCEANReader extends AbstractOneDReader { - public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws ReaderException { + private Vector readers; + + public MultiFormatUPCEANReader(Hashtable hints) { Vector possibleFormats = hints == null ? null : (Vector) hints.get(DecodeHintType.POSSIBLE_FORMATS); - Vector readers = new Vector(); + readers = new Vector(); if (possibleFormats != null) { if (possibleFormats.contains(BarcodeFormat.EAN_13)) { readers.addElement(new EAN13Reader()); @@ -56,10 +58,13 @@ public final class MultiFormatUPCEANReader extends AbstractOneDReader { readers.addElement(new EAN8Reader()); readers.addElement(new UPCEReader()); } + } + public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws ReaderException { // Compute this location once and reuse it on multiple implementations int[] startGuardPattern = AbstractUPCEANReader.findStartGuardPattern(row); - for (int i = 0; i < readers.size(); i++) { + int size = readers.size(); + for (int i = 0; i < size; i++) { UPCEANReader reader = (UPCEANReader) readers.elementAt(i); Result result; try { @@ -86,4 +91,4 @@ public final class MultiFormatUPCEANReader extends AbstractOneDReader { throw new ReaderException("No barcode was detected in this image."); } -} \ No newline at end of file +}