From 88afca0842b9a945f0ebc6571b7fc5fb008abda9 Mon Sep 17 00:00:00 2001 From: srowen Date: Wed, 11 Jun 2008 19:30:57 +0000 Subject: [PATCH] Unify UPC-A reader into EAN-13 reader since EAN-13 is a superset and we can take advantage of the commonality to improve performance. git-svn-id: https://zxing.googlecode.com/svn/trunk@416 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- .../zxing/oned/MultiFormatUPCEANReader.java | 23 ++++---- .../src/com/google/zxing/oned/UPCAReader.java | 56 +++++++++---------- 2 files changed, 38 insertions(+), 41 deletions(-) diff --git a/core/src/com/google/zxing/oned/MultiFormatUPCEANReader.java b/core/src/com/google/zxing/oned/MultiFormatUPCEANReader.java index b31fbf480..1901902a9 100644 --- a/core/src/com/google/zxing/oned/MultiFormatUPCEANReader.java +++ b/core/src/com/google/zxing/oned/MultiFormatUPCEANReader.java @@ -40,8 +40,7 @@ public final class MultiFormatUPCEANReader extends AbstractOneDReader { if (possibleFormats != null) { if (possibleFormats.contains(BarcodeFormat.EAN_13)) { readers.addElement(new EAN13Reader()); - } - if (possibleFormats.contains(BarcodeFormat.UPC_A)) { + } else if (possibleFormats.contains(BarcodeFormat.UPC_A)) { readers.addElement(new UPCAReader()); } if (possibleFormats.contains(BarcodeFormat.EAN_8)) { @@ -52,8 +51,8 @@ public final class MultiFormatUPCEANReader extends AbstractOneDReader { } } if (readers.isEmpty()) { - readers.addElement(new EAN13Reader()); - readers.addElement(new UPCAReader()); + readers.addElement(new EAN13Reader()); + // UPC-A is covered by EAN-13 readers.addElement(new EAN8Reader()); readers.addElement(new UPCEReader()); } @@ -71,16 +70,14 @@ public final class MultiFormatUPCEANReader extends AbstractOneDReader { // Special case: a 12-digit code encoded in UPC-A is identical to a "0" // followed by those 12 digits encoded as EAN-13. Each will recognize such a code, // UPC-A as a 12-digit string and EAN-13 as a 13-digit string starting with "0". - // Individually these are correct. + // Individually these are correct and their readers will both read such a code + // and correctly call it EAN-13, or UPC-A, respectively. // - // These cases can't be distinguished, so we defer to the UPC-A decoder and - // treat this case as a UPC-A code. But if we let the UPC-A decoder look at - // symbols first, it will recognize any EAN-13 code as a 12-digit string, - // which is wrong. So EAN-13 has to try first. - // - // Here is, therefore, where we implement this logic: - if (result.getBarcodeFormat().equals(BarcodeFormat.EAN_13) && - result.getText().charAt(0) == '0') { + // In this case, if we've been looking for both types, we'd like to call it + // a UPC-A code. But for efficiency we only run the EAN-13 decoder to also read + // UPC-A. So we special case it here, and convert an EAN-13 result to a UPC-A + // result if appropriate. + if (result.getBarcodeFormat().equals(BarcodeFormat.EAN_13) && result.getText().charAt(0) == '0') { return new Result(result.getText().substring(1), null, result.getResultPoints(), BarcodeFormat.UPC_A); } return result; diff --git a/core/src/com/google/zxing/oned/UPCAReader.java b/core/src/com/google/zxing/oned/UPCAReader.java index 14b9044d5..2cfe59e26 100644 --- a/core/src/com/google/zxing/oned/UPCAReader.java +++ b/core/src/com/google/zxing/oned/UPCAReader.java @@ -16,47 +16,47 @@ package com.google.zxing.oned; -import com.google.zxing.ReaderException; import com.google.zxing.BarcodeFormat; +import com.google.zxing.MonochromeBitmapSource; +import com.google.zxing.ReaderException; +import com.google.zxing.Result; import com.google.zxing.common.BitArray; +import java.util.Hashtable; + /** *

Implements decoding of the UPC-A format.

* * @author dswitkin@google.com (Daniel Switkin) * @author srowen@google.com (Sean Owen) */ -public final class UPCAReader extends AbstractUPCEANReader { +public final class UPCAReader implements UPCEANReader { - protected int decodeMiddle(BitArray row, int[] startRange, StringBuffer resultString) throws ReaderException { - int middleStart = decodeDigits(row, startRange[1], resultString); - int[] middleRange = findGuardPattern(row, middleStart, true, MIDDLE_PATTERN); - return decodeDigits(row, middleRange[1], resultString); + private final UPCEANReader ean13Reader = new EAN13Reader(); + + public Result decodeRow(int rowNumber, BitArray row, int[] startGuardRange) throws ReaderException { + return maybeReturnResult(ean13Reader.decodeRow(rowNumber, row, startGuardRange)); } - /** - * @param row row of black/white values to decode - * @param start horizontal offset from which decoding starts - * @param result {@link StringBuffer} to append decoded digits to - * @return horizontal offset of first pixel after the six decoded digits - * @throws ReaderException if six digits could not be decoded from the row - */ - private static int decodeDigits(BitArray row, int start, StringBuffer result) throws ReaderException { - int[] counters = new int[4]; - int end = row.getSize(); - int rowOffset = start; - for (int x = 0; x < 6 && rowOffset < end; x++) { - int bestMatch = decodeDigit(row, counters, rowOffset, L_PATTERNS); - result.append((char) ('0' + bestMatch)); - for (int i = 0; i < counters.length; i++) { - rowOffset += counters[i]; - } + public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws ReaderException { + return maybeReturnResult(ean13Reader.decodeRow(rowNumber, row, hints)); + } + + public Result decode(MonochromeBitmapSource image) throws ReaderException { + return maybeReturnResult(ean13Reader.decode(image)); + } + + public Result decode(MonochromeBitmapSource image, Hashtable hints) throws ReaderException { + return maybeReturnResult(ean13Reader.decode(image, hints)); + } + + private static Result maybeReturnResult(Result result) throws ReaderException { + String text = result.getText(); + if (text.charAt(0) == '0') { + return new Result(text.substring(1), null, result.getResultPoints(), BarcodeFormat.UPC_A); + } else { + throw new ReaderException("Found EAN-13 code but was not a UPC-A code"); } - return rowOffset; - } - - BarcodeFormat getBarcodeFormat() { - return BarcodeFormat.UPC_A; } } \ No newline at end of file