X-Git-Url: http://git.rot13.org/?p=zxing.git;a=blobdiff_plain;f=core%2Fsrc%2Fcom%2Fgoogle%2Fzxing%2FMultiFormatReader.java;h=42a97fe7cb09e9cb65d8f261f68c02937515982e;hp=6b2c2401fefbd2911fe80174ae6093995938df83;hb=5d9dd201546fdc3263d966f598b02770edba5a6d;hpb=adfeb7f7bbcea109c07075807f42b98a94e29efe diff --git a/core/src/com/google/zxing/MultiFormatReader.java b/core/src/com/google/zxing/MultiFormatReader.java index 6b2c2401..42a97fe7 100644 --- a/core/src/com/google/zxing/MultiFormatReader.java +++ b/core/src/com/google/zxing/MultiFormatReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2007 Google Inc. + * Copyright 2007 ZXing authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,67 +16,142 @@ package com.google.zxing; +import com.google.zxing.datamatrix.DataMatrixReader; import com.google.zxing.oned.MultiFormatOneDReader; +import com.google.zxing.pdf417.PDF417Reader; import com.google.zxing.qrcode.QRCodeReader; -import com.google.zxing.datamatrix.DataMatrixReader; import java.util.Hashtable; import java.util.Vector; /** - *

This implementation can detect barcodes in one of several formats within - * an image, and then decode what it finds. This implementation supports all - * barcode formats that this library supports.

+ * MultiFormatReader is a convenience class and the main entry point into the library for most uses. + * By default it attempts to decode all barcode formats that the library supports. Optionally, you + * can provide a hints object to request different behavior, for example only decoding QR codes. * - * @author srowen@google.com (Sean Owen), dswitkin@google.com (Daniel Switkin) + * @author Sean Owen + * @author dswitkin@google.com (Daniel Switkin) */ public final class MultiFormatReader implements Reader { - public Result decode(MonochromeBitmapSource image) throws ReaderException { - return decode(image, null); + private Hashtable hints; + private Vector readers; + + /** + * This version of decode honors the intent of Reader.decode(BinaryBitmap) in that it + * passes null as a hint to the decoders. However, that makes it inefficient to call repeatedly. + * Use setHints() followed by decodeWithState() for continuous scan applications. + * + * @param image The pixel data to decode + * @return The contents of the image + * @throws NotFoundException Any errors which occurred + */ + public Result decode(BinaryBitmap image) throws NotFoundException { + setHints(null); + return decodeInternal(image); + } + + /** + * Decode an image using the hints provided. Does not honor existing state. + * + * @param image The pixel data to decode + * @param hints The hints to use, clearing the previous state. + * @return The contents of the image + * @throws NotFoundException Any errors which occurred + */ + public Result decode(BinaryBitmap image, Hashtable hints) throws NotFoundException { + setHints(hints); + return decodeInternal(image); + } + + /** + * 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 + * @throws NotFoundException Any errors which occurred + */ + public Result decodeWithState(BinaryBitmap image) throws NotFoundException { + // Make sure to set up the default state so we don't crash + if (readers == null) { + setHints(null); + } + return decodeInternal(image); } - public Result decode(MonochromeBitmapSource image, Hashtable hints) throws ReaderException { + /** + * This method adds state to the MultiFormatReader. By setting the hints once, subsequent calls + * to decodeWithState(image) can reuse the same set of readers without reallocating memory. This + * is important for performance in continuous scan clients. + * + * @param hints The set of hints to use for subsequent calls to decode(image) + */ + public void setHints(Hashtable hints) { + this.hints = hints; boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER); - Vector possibleFormats = hints == null ? null : (Vector) hints.get(DecodeHintType.POSSIBLE_FORMATS); - Vector readers = new Vector(); - if (possibleFormats != null) { + Vector formats = hints == null ? null : (Vector) hints.get(DecodeHintType.POSSIBLE_FORMATS); + readers = new Vector(); + if (formats != null) { boolean addOneDReader = - possibleFormats.contains(BarcodeFormat.UPC_A) || - possibleFormats.contains(BarcodeFormat.UPC_E) || - possibleFormats.contains(BarcodeFormat.EAN_13) || - possibleFormats.contains(BarcodeFormat.EAN_8) || - possibleFormats.contains(BarcodeFormat.CODE_39) || - possibleFormats.contains(BarcodeFormat.CODE_128); + formats.contains(BarcodeFormat.UPC_A) || + formats.contains(BarcodeFormat.UPC_E) || + formats.contains(BarcodeFormat.EAN_13) || + formats.contains(BarcodeFormat.EAN_8) || + //formats.contains(BarcodeFormat.CODABAR) || + formats.contains(BarcodeFormat.CODE_39) || + formats.contains(BarcodeFormat.CODE_93) || + formats.contains(BarcodeFormat.CODE_128) || + formats.contains(BarcodeFormat.ITF) || + formats.contains(BarcodeFormat.RSS14) || + formats.contains(BarcodeFormat.RSS_EXPANDED); // 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)) { + if (formats.contains(BarcodeFormat.QR_CODE)) { readers.addElement(new QRCodeReader()); } - if (possibleFormats.contains(BarcodeFormat.DATAMATRIX)) { + if (formats.contains(BarcodeFormat.DATA_MATRIX)) { readers.addElement(new DataMatrixReader()); } + if (formats.contains(BarcodeFormat.PDF417)) { + readers.addElement(new PDF417Reader()); + } // 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()); + + readers.addElement(new DataMatrixReader()); + + // TODO: Enable once PDF417 has passed QA + //readers.addElement(new PDF417Reader()); + if (tryHarder) { - readers.addElement(new MultiFormatOneDReader()); + readers.addElement(new MultiFormatOneDReader(hints)); } } + } + + public void reset() { + int size = readers.size(); + for (int i = 0; i < size; i++) { + Reader reader = (Reader) readers.elementAt(i); + reader.reset(); + } + } - for (int i = 0; i < readers.size(); i++) { + private Result decodeInternal(BinaryBitmap image) throws NotFoundException { + int size = readers.size(); + for (int i = 0; i < size; i++) { Reader reader = (Reader) readers.elementAt(i); try { return reader.decode(image, hints); @@ -85,7 +160,7 @@ public final class MultiFormatReader implements Reader { } } - throw new ReaderException("No barcode was detected in this image."); + throw NotFoundException.getNotFoundInstance(); } }