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