C# port, add datamatrix code
[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 using com.google.zxing.datamatrix;\r
20 \r
21 namespace com.google.zxing\r
22 {\r
23     public sealed class MultiFormatReader : Reader\r
24     { \r
25           private Hashtable hints;\r
26           private ArrayList readers;\r
27 \r
28           /**\r
29            * This version of decode honors the intent of Reader.decode(MonochromeBitmapSource) in that it\r
30            * passes null as a hint to the decoders. However, that makes it inefficient to call repeatedly.\r
31            * Use setHints() followed by decodeWithState() for continuous scan applications.\r
32            *\r
33            * @param image The pixel data to decode\r
34            * @return The contents of the image\r
35            * @throws ReaderException Any errors which occurred\r
36            */\r
37           public Result decode(MonochromeBitmapSource image){\r
38               try{\r
39                 setHints(null);\r
40                 return decodeInternal(image);\r
41               }\r
42               catch(Exception e){\r
43                 throw new ReaderException(e.Message);\r
44               }           \r
45           }\r
46 \r
47           /**\r
48            * Decode an image using the hints provided. Does not honor existing state.\r
49            *\r
50            * @param image The pixel data to decode\r
51            * @param hints The hints to use, clearing the previous state.\r
52            * @return The contents of the image\r
53            * @throws ReaderException Any errors which occurred\r
54            */\r
55           public Result decode(MonochromeBitmapSource image, Hashtable hints){\r
56               try{\r
57                  setHints(hints);\r
58                  return decodeInternal(image);\r
59               }catch(Exception e){\r
60                 throw new ReaderException (e.Message);\r
61               }           \r
62           }\r
63 \r
64           /**\r
65            * Decode an image using the state set up by calling setHints() previously. Continuous scan\r
66            * clients will get a <b>large</b> speed increase by using this instead of decode().\r
67            *\r
68            * @param image The pixel data to decode\r
69            * @return The contents of the image\r
70            * @throws ReaderException Any errors which occurred\r
71            */\r
72           public Result decodeWithState(MonochromeBitmapSource image){\r
73               try{\r
74                 // Make sure to set up the default state so we don't crash\r
75                 if (readers == null) {\r
76                   setHints(null);\r
77                 }\r
78                 return decodeInternal(image);\r
79               }catch(Exception e){\r
80                 throw new ReaderException(e.Message);\r
81               }            \r
82           }\r
83 \r
84           /**\r
85            * This method adds state to the MultiFormatReader. By setting the hints once, subsequent calls\r
86            * to decodeWithState(image) can reuse the same set of readers without reallocating memory. This\r
87            * is important for performance in continuous scan clients.\r
88            *\r
89            * @param hints The set of hints to use for subsequent calls to decode(image)\r
90            */\r
91           public void setHints(Hashtable hints) {\r
92               this.hints = hints;\r
93 \r
94               bool tryHarder = hints != null && hints.ContainsKey(DecodeHintType.TRY_HARDER);\r
95 \r
96               ArrayList possibleFormats = hints == null ? null : (ArrayList)hints[(DecodeHintType.POSSIBLE_FORMATS)];\r
97               readers = new ArrayList();\r
98               if (possibleFormats != null)\r
99               {\r
100                   bool addOneDReader =\r
101                   possibleFormats.Contains(BarcodeFormat.UPC_A) ||\r
102                       possibleFormats.Contains(BarcodeFormat.UPC_E) ||\r
103                       possibleFormats.Contains(BarcodeFormat.EAN_13) ||\r
104                       possibleFormats.Contains(BarcodeFormat.EAN_8) ||\r
105                       possibleFormats.Contains(BarcodeFormat.CODE_39) ||\r
106                       possibleFormats.Contains(BarcodeFormat.CODE_128);\r
107                   // Put 1D readers upfront in "normal" mode\r
108 \r
109                   if (addOneDReader && !tryHarder)\r
110                   {\r
111                       readers.Add(new MultiFormatOneDReader(hints));\r
112                   }\r
113 \r
114                   if (possibleFormats.Contains(BarcodeFormat.QR_CODE))\r
115                   {\r
116                       readers.Add(new QRCodeReader());\r
117                   }\r
118                   // TODO re-enable once Data Matrix is ready\r
119                   if (possibleFormats.Contains(BarcodeFormat.DATAMATRIX)) {\r
120                     readers.Add(new DataMatrixReader());\r
121                   }\r
122                   // At end in "try harder" mode\r
123                   if (addOneDReader && tryHarder)\r
124                   {\r
125                       readers.Add(new MultiFormatOneDReader(hints));\r
126                   }\r
127               }\r
128 \r
129               if (readers.Count == 0)\r
130               {\r
131                   if (!tryHarder)\r
132                   {\r
133                       readers.Add(new MultiFormatOneDReader(hints));\r
134                   }\r
135                   readers.Add(new QRCodeReader());\r
136                   // TODO re-enable once Data Matrix is ready\r
137                     readers.Add(new DataMatrixReader());\r
138                   if (tryHarder)\r
139                   {\r
140                       readers.Add(new MultiFormatOneDReader(hints));\r
141                   }\r
142               }\r
143           }\r
144 \r
145           private Result decodeInternal(MonochromeBitmapSource image) {\r
146               try\r
147               {\r
148                   int size = readers.Count;\r
149                   for (int i = 0; i < size; i++)\r
150                   {\r
151                       Reader reader = (Reader)readers[i];\r
152                       try\r
153                       {\r
154                           return reader.decode(image, hints);\r
155                       }\r
156                       catch (ReaderException re)\r
157                       {\r
158                           // continue\r
159                       }\r
160                   }\r
161 \r
162                   throw new ReaderException("");\r
163               }\r
164               catch (Exception e) {\r
165                   throw new ReaderException(e.Message);\r
166               }\r
167           }\r
168     \r
169     \r
170     }\r
171 }