Turn on Data Matrix, including separate scan option in Android
[zxing.git] / core / src / com / google / zxing / MultiFormatReader.java
1 /*
2  * Copyright 2007 ZXing authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.google.zxing;
18
19 import com.google.zxing.datamatrix.DataMatrixReader;
20 import com.google.zxing.oned.MultiFormatOneDReader;
21 import com.google.zxing.pdf417.PDF417Reader;
22 import com.google.zxing.qrcode.QRCodeReader;
23
24 import java.util.Hashtable;
25 import java.util.Vector;
26
27 /**
28  * MultiFormatReader is a convenience class and the main entry point into the library for most uses.
29  * By default it attempts to decode all barcode formats that the library supports. Optionally, you
30  * can provide a hints object to request different behavior, for example only decoding QR codes.
31  *
32  * @author Sean Owen
33  * @author dswitkin@google.com (Daniel Switkin)
34  */
35 public final class MultiFormatReader implements Reader {
36
37   private Hashtable hints;
38   private Vector readers;
39
40   /**
41    * This version of decode honors the intent of Reader.decode(BinaryBitmap) in that it
42    * passes null as a hint to the decoders. However, that makes it inefficient to call repeatedly.
43    * Use setHints() followed by decodeWithState() for continuous scan applications.
44    *
45    * @param image The pixel data to decode
46    * @return The contents of the image
47    * @throws NotFoundException Any errors which occurred
48    */
49   public Result decode(BinaryBitmap image) throws NotFoundException {
50     setHints(null);
51     return decodeInternal(image);
52   }
53
54   /**
55    * Decode an image using the hints provided. Does not honor existing state.
56    *
57    * @param image The pixel data to decode
58    * @param hints The hints to use, clearing the previous state.
59    * @return The contents of the image
60    * @throws NotFoundException Any errors which occurred
61    */
62   public Result decode(BinaryBitmap image, Hashtable hints) throws NotFoundException {
63     setHints(hints);
64     return decodeInternal(image);
65   }
66
67   /**
68    * Decode an image using the state set up by calling setHints() previously. Continuous scan
69    * clients will get a <b>large</b> speed increase by using this instead of decode().
70    *
71    * @param image The pixel data to decode
72    * @return The contents of the image
73    * @throws NotFoundException Any errors which occurred
74    */
75   public Result decodeWithState(BinaryBitmap image) throws NotFoundException {
76     // Make sure to set up the default state so we don't crash
77     if (readers == null) {
78       setHints(null);
79     }
80     return decodeInternal(image);
81   }
82
83   /**
84    * This method adds state to the MultiFormatReader. By setting the hints once, subsequent calls
85    * to decodeWithState(image) can reuse the same set of readers without reallocating memory. This
86    * is important for performance in continuous scan clients.
87    *
88    * @param hints The set of hints to use for subsequent calls to decode(image)
89    */
90   public void setHints(Hashtable hints) {
91     this.hints = hints;
92
93     boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
94     Vector formats = hints == null ? null : (Vector) hints.get(DecodeHintType.POSSIBLE_FORMATS);
95     readers = new Vector();
96     if (formats != null) {
97       boolean addOneDReader =
98           formats.contains(BarcodeFormat.UPC_A) ||
99               formats.contains(BarcodeFormat.UPC_E) ||
100               formats.contains(BarcodeFormat.EAN_13) ||
101               formats.contains(BarcodeFormat.EAN_8) ||
102               //formats.contains(BarcodeFormat.CODABAR) ||
103               formats.contains(BarcodeFormat.CODE_39) ||
104               formats.contains(BarcodeFormat.CODE_93) ||
105               formats.contains(BarcodeFormat.CODE_128) ||
106               formats.contains(BarcodeFormat.ITF) ||
107               formats.contains(BarcodeFormat.RSS14) ||
108               formats.contains(BarcodeFormat.RSS_EXPANDED);
109       // Put 1D readers upfront in "normal" mode
110       if (addOneDReader && !tryHarder) {
111         readers.addElement(new MultiFormatOneDReader(hints));
112       }
113       if (formats.contains(BarcodeFormat.QR_CODE)) {
114         readers.addElement(new QRCodeReader());
115       }
116       if (formats.contains(BarcodeFormat.DATA_MATRIX)) {
117         readers.addElement(new DataMatrixReader());
118       }
119       if (formats.contains(BarcodeFormat.PDF417)) {
120          readers.addElement(new PDF417Reader());
121        }
122       // At end in "try harder" mode
123       if (addOneDReader && tryHarder) {
124         readers.addElement(new MultiFormatOneDReader(hints));
125       }
126     }
127     if (readers.isEmpty()) {
128       if (!tryHarder) {
129         readers.addElement(new MultiFormatOneDReader(hints));
130       }
131       readers.addElement(new QRCodeReader());
132
133       readers.addElement(new DataMatrixReader());
134
135       // TODO: Enable once PDF417 has passed QA
136       //readers.addElement(new PDF417Reader());
137
138       if (tryHarder) {
139         readers.addElement(new MultiFormatOneDReader(hints));
140       }
141     }
142   }
143
144   public void reset() {
145     int size = readers.size();
146     for (int i = 0; i < size; i++) {
147       Reader reader = (Reader) readers.elementAt(i);
148       reader.reset();
149     }
150   }
151
152   private Result decodeInternal(BinaryBitmap image) throws NotFoundException {
153     int size = readers.size();
154     for (int i = 0; i < size; i++) {
155       Reader reader = (Reader) readers.elementAt(i);
156       try {
157         return reader.decode(image, hints);
158       } catch (ReaderException re) {
159         // continue
160       }
161     }
162
163     throw NotFoundException.getNotFoundInstance();
164   }
165
166 }