git-svn-id: http://zxing.googlecode.com/svn/trunk@818 59b500cc-1b3d-0410-9834-0bbf25f...
[zxing.git] / csharp / MultiFormatReader.cs
1 /*\r
2 * Licensed under the Apache License, Version 2.0 (the "License");\r
3 * you may not use this file except in compliance with the License.\r
4 * You may obtain a copy of the License at\r
5 *\r
6 *      http://www.apache.org/licenses/LICENSE-2.0\r
7 *\r
8 * Unless required by applicable law or agreed to in writing, software\r
9 * distributed under the License is distributed on an "AS IS" BASIS,\r
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
11 * See the License for the specific language governing permissions and\r
12 * limitations under the License.\r
13 */\r
14 \r
15 using System;\r
16 using System.Collections;\r
17 using com.google.zxing.qrcode;\r
18 using com.google.zxing.oned;\r
19 \r
20 namespace com.google.zxing\r
21 {\r
22     public sealed class MultiFormatReader : Reader\r
23     { \r
24           private Hashtable hints;\r
25           private ArrayList readers;\r
26 \r
27           /**\r
28            * This version of decode honors the intent of Reader.decode(MonochromeBitmapSource) in that it\r
29            * passes null as a hint to the decoders. However, that makes it inefficient to call repeatedly.\r
30            * Use setHints() followed by decodeWithState() for continuous scan applications.\r
31            *\r
32            * @param image The pixel data to decode\r
33            * @return The contents of the image\r
34            * @throws ReaderException Any errors which occurred\r
35            */\r
36           public Result decode(MonochromeBitmapSource image){\r
37               try{\r
38                 setHints(null);\r
39                 return decodeInternal(image);\r
40               }\r
41               catch(Exception e){\r
42                 throw new ReaderException(e.Message);\r
43               }           \r
44           }\r
45 \r
46           /**\r
47            * Decode an image using the hints provided. Does not honor existing state.\r
48            *\r
49            * @param image The pixel data to decode\r
50            * @param hints The hints to use, clearing the previous state.\r
51            * @return The contents of the image\r
52            * @throws ReaderException Any errors which occurred\r
53            */\r
54           public Result decode(MonochromeBitmapSource image, Hashtable hints){\r
55               try{\r
56                  setHints(hints);\r
57                  return decodeInternal(image);\r
58               }catch(Exception e){\r
59                 throw new ReaderException (e.Message);\r
60               }           \r
61           }\r
62 \r
63           /**\r
64            * Decode an image using the state set up by calling setHints() previously. Continuous scan\r
65            * clients will get a <b>large</b> speed increase by using this instead of decode().\r
66            *\r
67            * @param image The pixel data to decode\r
68            * @return The contents of the image\r
69            * @throws ReaderException Any errors which occurred\r
70            */\r
71           public Result decodeWithState(MonochromeBitmapSource image){\r
72               try{\r
73                 // Make sure to set up the default state so we don't crash\r
74                 if (readers == null) {\r
75                   setHints(null);\r
76                 }\r
77                 return decodeInternal(image);\r
78               }catch(Exception e){\r
79                 throw new ReaderException(e.Message);\r
80               }            \r
81           }\r
82 \r
83           /**\r
84            * This method adds state to the MultiFormatReader. By setting the hints once, subsequent calls\r
85            * to decodeWithState(image) can reuse the same set of readers without reallocating memory. This\r
86            * is important for performance in continuous scan clients.\r
87            *\r
88            * @param hints The set of hints to use for subsequent calls to decode(image)\r
89            */\r
90           public void setHints(Hashtable hints) {\r
91               this.hints = hints;\r
92 \r
93               bool tryHarder = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER);\r
94 \r
95               ArrayList possibleFormats = hints == null ? null : (ArrayList)hints[(DecodeHintType.POSSIBLE_FORMATS)];\r
96               readers = new ArrayList();\r
97               if (possibleFormats != null)\r
98               {\r
99                   bool addOneDReader =\r
100                   possibleFormats.Contains(BarcodeFormat.UPC_A) ||\r
101                       possibleFormats.Contains(BarcodeFormat.UPC_E) ||\r
102                       possibleFormats.Contains(BarcodeFormat.EAN_13) ||\r
103                       possibleFormats.Contains(BarcodeFormat.EAN_8) ||\r
104                       possibleFormats.Contains(BarcodeFormat.CODE_39) ||\r
105                       possibleFormats.Contains(BarcodeFormat.CODE_128);\r
106                   // Put 1D readers upfront in "normal" mode\r
107 \r
108                   if (addOneDReader && !tryHarder)\r
109                   {\r
110                       readers.Add(new MultiFormatOneDReader(hints));\r
111                   }\r
112 \r
113                   if (possibleFormats.Contains(BarcodeFormat.QR_CODE))\r
114                   {\r
115                       readers.Add(new QRCodeReader());\r
116                   }\r
117                   // TODO re-enable once Data Matrix is ready\r
118                   if (possibleFormats.Contains(BarcodeFormat.DATAMATRIX)) {\r
119                     //readers.Add(new DataMatrixReader());\r
120                   }\r
121                   // At end in "try harder" mode\r
122                   if (addOneDReader && tryHarder)\r
123                   {\r
124                       readers.Add(new MultiFormatOneDReader(hints));\r
125                   }\r
126               }\r
127 \r
128               if (readers.Count == 0)\r
129               {\r
130                   if (!tryHarder)\r
131                   {\r
132                       //readers.Add(new MultiFormatOneDReader(hints));\r
133                   }\r
134                   readers.Add(new QRCodeReader());\r
135                   // TODO re-enable once Data Matrix is ready\r
136                   // readers.addElement(new DataMatrixReader());\r
137                   if (tryHarder)\r
138                   {\r
139                       //readers.Add(new MultiFormatOneDReader(hints));\r
140                   }\r
141               }\r
142           }\r
143 \r
144           private Result decodeInternal(MonochromeBitmapSource image) {\r
145               try\r
146               {\r
147                   int size = readers.Count;\r
148                   for (int i = 0; i < size; i++)\r
149                   {\r
150                       Reader reader = (Reader)readers[i];\r
151                       try\r
152                       {\r
153                           return reader.decode(image, hints);\r
154                       }\r
155                       catch (ReaderException re)\r
156                       {\r
157                           // continue\r
158                       }\r
159                   }\r
160 \r
161                   throw new ReaderException("");\r
162               }\r
163               catch (Exception e) {\r
164                   throw new ReaderException(e.Message);\r
165               }\r
166           }\r
167     \r
168     \r
169     }\r
170 }