X-Git-Url: http://git.rot13.org/?p=zxing.git;a=blobdiff_plain;f=core%2Fsrc%2Fcom%2Fgoogle%2Fzxing%2FMultiFormatReader.java;h=0e70341fd59a7cd1b6a0a17d92aadc48d9c82cf3;hp=815c78609bb3aa652d52577c1873466e9b9a8a1c;hb=2d9efc5f0d19d70fb4f240f506bc23992ab3fde6;hpb=324c4749d7fc3e6823d48921ef3e7ae81ca9cd0f diff --git a/core/src/com/google/zxing/MultiFormatReader.java b/core/src/com/google/zxing/MultiFormatReader.java index 815c7860..0e70341f 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,58 +16,151 @@ 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 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); } - public Result decode(MonochromeBitmapSource image, Hashtable hints) - throws ReaderException { - Hashtable possibleFormats = hints == null ? null : (Hashtable) hints.get(DecodeHintType.POSSIBLE_FORMATS); + /** + * 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); + } - boolean tryOneD; - boolean tryQR; - if (possibleFormats == null) { - tryOneD = true; - tryQR = true; - } else { - tryOneD = possibleFormats.contains(BarcodeFormat.ONED); - tryQR = possibleFormats.contains(BarcodeFormat.QR_CODE); - } - if (!(tryOneD || tryQR)) { - throw new ReaderException("POSSIBLE_FORMATS specifies no supported types"); + /** + * 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); + } - // UPC is much faster to decode, so try it first. - if (tryOneD) { - try { - return new MultiFormatOneDReader().decode(image, hints); - } catch (ReaderException re) { + /** + * 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 formats = hints == null ? null : (Vector) hints.get(DecodeHintType.POSSIBLE_FORMATS); + readers = new Vector(); + if (formats != null) { + boolean addOneDReader = + formats.contains(BarcodeFormat.UPC_A) || + formats.contains(BarcodeFormat.UPC_E) || + formats.contains(BarcodeFormat.EAN_13) || + formats.contains(BarcodeFormat.EAN_8) || + 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(hints)); + } + if (formats.contains(BarcodeFormat.QR_CODE)) { + readers.addElement(new QRCodeReader()); + } + if (formats.contains(BarcodeFormat.DATAMATRIX)) { + 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(hints)); + } + } + if (readers.isEmpty()) { + if (!tryHarder) { + readers.addElement(new MultiFormatOneDReader(hints)); + } + readers.addElement(new QRCodeReader()); + + // TODO re-enable once Data Matrix is ready + // readers.addElement(new DataMatrixReader()); + + // TODO: Enable once PDF417 has passed QA + //readers.addElement(new PDF417Reader()); + + if (tryHarder) { + 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(); + } + } - // Then fall through to QR codes. - if (tryQR) { + 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 new QRCodeReader().decode(image, hints); + return reader.decode(image, hints); } catch (ReaderException re) { + // continue } } - throw new ReaderException("No barcode was detected in this image."); + throw NotFoundException.getNotFoundInstance(); } }