Added rendering fix from beyonddeath
[zxing.git] / csharp / datamatrix / decoder / Version.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Linq;\r
4 using System.Text;\r
5 \r
6 namespace com.google.zxing.datamatrix.decoder\r
7 {\r
8     public sealed class Version\r
9     {\r
10           private static  Version[] VERSIONS = buildVersions();\r
11           private  int versionNumber;\r
12           private  int symbolSizeRows;\r
13           private  int symbolSizeColumns;\r
14           private  int dataRegionSizeRows;\r
15           private  int dataRegionSizeColumns;\r
16           private  ECBlocks ecBlocks;\r
17           private  int totalCodewords;\r
18 \r
19           private Version(int versionNumber,\r
20                           int symbolSizeRows,\r
21                           int symbolSizeColumns,\r
22                           int dataRegionSizeRows,\r
23                           int dataRegionSizeColumns,\r
24                           ECBlocks ecBlocks) {\r
25             this.versionNumber = versionNumber;\r
26             this.symbolSizeRows = symbolSizeRows;\r
27             this.symbolSizeColumns = symbolSizeColumns;\r
28             this.dataRegionSizeRows = dataRegionSizeRows;\r
29             this.dataRegionSizeColumns = dataRegionSizeColumns;\r
30             this.ecBlocks = ecBlocks;\r
31             \r
32             // Calculate the total number of codewords\r
33             int total = 0;\r
34             int ecCodewords = ecBlocks.getECCodewords();\r
35             ECB[] ecbArray = ecBlocks.getECBlocks();\r
36             for (int i = 0; i < ecbArray.Length; i++) {\r
37               ECB ecBlock = ecbArray[i];\r
38               total += ecBlock.getCount() * (ecBlock.getDataCodewords() + ecCodewords);\r
39             }\r
40             this.totalCodewords = total;\r
41           }\r
42 \r
43           public int getVersionNumber() {\r
44             return versionNumber;\r
45           }\r
46 \r
47           public int getSymbolSizeRows() {\r
48             return symbolSizeRows;\r
49           }\r
50           \r
51           public int getSymbolSizeColumns() {\r
52             return symbolSizeColumns;\r
53           }\r
54           \r
55           public int getDataRegionSizeRows() {\r
56             return dataRegionSizeRows;\r
57           }\r
58           \r
59           public int getDataRegionSizeColumns() {\r
60             return dataRegionSizeColumns;\r
61           }\r
62           \r
63           public int getTotalCodewords() {\r
64             return totalCodewords;\r
65           }\r
66           \r
67           public ECBlocks getECBlocks() {\r
68             return ecBlocks;\r
69           }\r
70 \r
71           /**\r
72            * <p>Deduces version information from Data Matrix dimensions.</p>\r
73            *\r
74            * @param numRows Number of rows in modules\r
75            * @param numColumns Number of columns in modules\r
76            * @return {@link Version} for a Data Matrix Code of those dimensions\r
77            * @throws ReaderException if dimensions do correspond to a valid Data Matrix size\r
78            */\r
79           public static Version getVersionForDimensions(int numRows, int numColumns) {\r
80             if ((numRows & 0x01) != 0 || (numColumns & 0x01) != 0) {\r
81               throw new ReaderException();\r
82             }\r
83             \r
84             // TODO(bbrown): This is doing a linear search through the array of versions.\r
85             // If we interleave the rectangular versions with the square versions we could\r
86             // do a binary search.\r
87             int numVersions = VERSIONS.Length;\r
88             for (int i = 0; i < numVersions; ++i){\r
89               Version version = VERSIONS[i];\r
90               if (version.symbolSizeRows == numRows && version.symbolSizeColumns == numColumns) {\r
91                 return version;\r
92               }\r
93             }\r
94             \r
95             throw new ReaderException();\r
96           }\r
97 \r
98           /**\r
99            * <p>Encapsulates a set of error-correction blocks in one symbol version. Most versions will\r
100            * use blocks of differing sizes within one version, so, this encapsulates the parameters for\r
101            * each set of blocks. It also holds the number of error-correction codewords per block since it\r
102            * will be the same across all blocks within one version.</p>\r
103            */\r
104           public  class ECBlocks {\r
105             private  int ecCodewords;\r
106             private  ECB[] ecBlocks;\r
107 \r
108             public ECBlocks(int ecCodewords, ECB ecBlocks) {\r
109               this.ecCodewords = ecCodewords;\r
110               this.ecBlocks = new ECB[] { ecBlocks };\r
111             }\r
112 \r
113             public ECBlocks(int ecCodewords, ECB ecBlocks1, ECB ecBlocks2) {\r
114               this.ecCodewords = ecCodewords;\r
115               this.ecBlocks = new ECB[] { ecBlocks1, ecBlocks2 };\r
116             }\r
117 \r
118             public int getECCodewords() {\r
119               return ecCodewords;\r
120             }\r
121 \r
122             public ECB[] getECBlocks() {\r
123               return ecBlocks;\r
124             }\r
125           }\r
126 \r
127           /**\r
128            * <p>Encapsualtes the parameters for one error-correction block in one symbol version.\r
129            * This includes the number of data codewords, and the number of times a block with these\r
130            * parameters is used consecutively in the Data Matrix code version's format.</p>\r
131            */\r
132           public  class ECB {\r
133             private  int count;\r
134             private  int dataCodewords;\r
135 \r
136             public ECB(int count, int dataCodewords) {\r
137               this.count = count;\r
138               this.dataCodewords = dataCodewords;\r
139             }\r
140 \r
141             public int getCount() {\r
142               return count;\r
143             }\r
144 \r
145             public int getDataCodewords() {\r
146               return dataCodewords;\r
147             }\r
148           }\r
149 \r
150           public String toString() {\r
151               return versionNumber.ToString();\r
152           }\r
153 \r
154           /**\r
155            * See ISO 16022:2006 5.5.1 Table 7\r
156            */\r
157           private static Version[] buildVersions() {\r
158             return new Version[]{\r
159                 new Version(1, 10, 10, 8, 8,\r
160                     new ECBlocks(5, new ECB(1, 3))),\r
161                 new Version(2, 12, 12, 10, 10,\r
162                     new ECBlocks(7, new ECB(1, 5))),\r
163                 new Version(3, 14, 14, 12, 12,\r
164                     new ECBlocks(10, new ECB(1, 8))),\r
165                 new Version(4, 16, 16, 14, 14,\r
166                     new ECBlocks(12, new ECB(1, 12))),\r
167                 new Version(5, 18, 18, 16, 16,\r
168                     new ECBlocks(14, new ECB(1, 18))),\r
169                 new Version(6, 20, 20, 18, 18,\r
170                     new ECBlocks(18, new ECB(1, 22))),\r
171                 new Version(7, 22, 22, 20, 20,\r
172                     new ECBlocks(20, new ECB(1, 30))),\r
173                 new Version(8, 24, 24, 22, 22,\r
174                     new ECBlocks(24, new ECB(1, 36))),\r
175                 new Version(9, 26, 26, 24, 24,\r
176                     new ECBlocks(28, new ECB(1, 44))),\r
177                 new Version(10, 32, 32, 14, 14,\r
178                     new ECBlocks(36, new ECB(1, 62))),\r
179                 new Version(11, 36, 36, 16, 16,\r
180                     new ECBlocks(42, new ECB(1, 86))),\r
181                 new Version(12, 40, 40, 18, 18,\r
182                     new ECBlocks(48, new ECB(1, 114))),\r
183                 new Version(13, 44, 44, 20, 20,\r
184                     new ECBlocks(56, new ECB(1, 144))),\r
185                 new Version(14, 48, 48, 22, 22,\r
186                     new ECBlocks(68, new ECB(1, 174))),\r
187                 new Version(15, 52, 52, 24, 24,\r
188                     new ECBlocks(42, new ECB(2, 102))),\r
189                 new Version(16, 64, 64, 14, 14,\r
190                     new ECBlocks(56, new ECB(2, 140))),\r
191                 new Version(17, 72, 72, 16, 16,\r
192                     new ECBlocks(36, new ECB(4, 92))),\r
193                 new Version(18, 80, 80, 18, 18,\r
194                     new ECBlocks(48, new ECB(4, 114))),\r
195                 new Version(19, 88, 88, 20, 20,\r
196                     new ECBlocks(56, new ECB(4, 144))),\r
197                 new Version(20, 96, 96, 22, 22,\r
198                     new ECBlocks(68, new ECB(4, 174))),\r
199                 new Version(21, 104, 104, 24, 24,\r
200                     new ECBlocks(56, new ECB(6, 136))),\r
201                 new Version(22, 120, 120, 18, 18,\r
202                     new ECBlocks(68, new ECB(6, 175))),\r
203                 new Version(23, 132, 132, 20, 20,\r
204                     new ECBlocks(62, new ECB(8, 163))),\r
205                 new Version(24, 144, 144, 22, 22,\r
206                     new ECBlocks(62, new ECB(8, 156), new ECB(2, 155))),\r
207                 new Version(25, 8, 18, 6, 16,\r
208                     new ECBlocks(7, new ECB(1, 5))),\r
209                 new Version(26, 8, 32, 6, 14,\r
210                     new ECBlocks(11, new ECB(1, 10))),\r
211                 new Version(27, 12, 26, 10, 24,\r
212                     new ECBlocks(14, new ECB(1, 16))),\r
213                 new Version(28, 12, 36, 10, 16,\r
214                     new ECBlocks(18, new ECB(1, 22))),\r
215                 new Version(29, 16, 36, 10, 16,\r
216                     new ECBlocks(24, new ECB(1, 32))),\r
217                 new Version(30, 16, 48, 14, 22,\r
218                     new ECBlocks(28, new ECB(1, 49)))\r
219             };\r
220           }\r
221     }\r
222 }\r