Move character encoding logic out to common, try again to improve its handling of...
[zxing.git] / core / src / com / google / zxing / qrcode / decoder / Version.java
1 /*\r
2  * Copyright 2007 ZXing authors\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *      http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 package com.google.zxing.qrcode.decoder;\r
18 \r
19 import com.google.zxing.FormatException;\r
20 import com.google.zxing.common.BitMatrix;\r
21 \r
22 /**\r
23  * See ISO 18004:2006 Annex D\r
24  *\r
25  * @author Sean Owen\r
26  */\r
27 public final class Version {\r
28 \r
29   /**\r
30    * See ISO 18004:2006 Annex D.\r
31    * Element i represents the raw version bits that specify version i + 7\r
32    */\r
33   private static final int[] VERSION_DECODE_INFO = {\r
34       0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6,\r
35       0x0C762, 0x0D847, 0x0E60D, 0x0F928, 0x10B78,\r
36       0x1145D, 0x12A17, 0x13532, 0x149A6, 0x15683,\r
37       0x168C9, 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB,\r
38       0x1B08E, 0x1CC1A, 0x1D33F, 0x1ED75, 0x1F250,\r
39       0x209D5, 0x216F0, 0x228BA, 0x2379F, 0x24B0B,\r
40       0x2542E, 0x26A64, 0x27541, 0x28C69\r
41   };\r
42 \r
43   private static final Version[] VERSIONS = buildVersions();\r
44 \r
45   private final int versionNumber;\r
46   private final int[] alignmentPatternCenters;\r
47   private final ECBlocks[] ecBlocks;\r
48   private final int totalCodewords;\r
49 \r
50   private Version(int versionNumber,\r
51                   int[] alignmentPatternCenters,\r
52                   ECBlocks ecBlocks1,\r
53                   ECBlocks ecBlocks2,\r
54                   ECBlocks ecBlocks3,\r
55                   ECBlocks ecBlocks4) {\r
56     this.versionNumber = versionNumber;\r
57     this.alignmentPatternCenters = alignmentPatternCenters;\r
58     this.ecBlocks = new ECBlocks[]{ecBlocks1, ecBlocks2, ecBlocks3, ecBlocks4};\r
59     int total = 0;\r
60     int ecCodewords = ecBlocks1.getECCodewordsPerBlock();\r
61     ECB[] ecbArray = ecBlocks1.getECBlocks();\r
62     for (int i = 0; i < ecbArray.length; i++) {\r
63       ECB ecBlock = ecbArray[i];\r
64       total += ecBlock.getCount() * (ecBlock.getDataCodewords() + ecCodewords);\r
65     }\r
66     this.totalCodewords = total;\r
67   }\r
68 \r
69   public int getVersionNumber() {\r
70     return versionNumber;\r
71   }\r
72 \r
73   public int[] getAlignmentPatternCenters() {\r
74     return alignmentPatternCenters;\r
75   }\r
76 \r
77   public int getTotalCodewords() {\r
78     return totalCodewords;\r
79   }\r
80 \r
81   public int getDimensionForVersion() {\r
82     return 17 + 4 * versionNumber;\r
83   }\r
84 \r
85   public ECBlocks getECBlocksForLevel(ErrorCorrectionLevel ecLevel) {\r
86     return ecBlocks[ecLevel.ordinal()];\r
87   }\r
88 \r
89   /**\r
90    * <p>Deduces version information purely from QR Code dimensions.</p>\r
91    *\r
92    * @param dimension dimension in modules\r
93    * @return {@link Version} for a QR Code of that dimension\r
94    * @throws FormatException if dimension is not 1 mod 4\r
95    */\r
96   public static Version getProvisionalVersionForDimension(int dimension) throws FormatException {\r
97     if (dimension % 4 != 1) {\r
98       throw FormatException.getFormatInstance();\r
99     }\r
100     try {\r
101       return getVersionForNumber((dimension - 17) >> 2);\r
102     } catch (IllegalArgumentException iae) {\r
103       throw FormatException.getFormatInstance();\r
104     }\r
105   }\r
106 \r
107   public static Version getVersionForNumber(int versionNumber) {\r
108     if (versionNumber < 1 || versionNumber > 40) {\r
109       throw new IllegalArgumentException();\r
110     }\r
111     return VERSIONS[versionNumber - 1];\r
112   }\r
113 \r
114   static Version decodeVersionInformation(int versionBits) {\r
115     int bestDifference = Integer.MAX_VALUE;\r
116     int bestVersion = 0;\r
117     for (int i = 0; i < VERSION_DECODE_INFO.length; i++) {\r
118       int targetVersion = VERSION_DECODE_INFO[i];\r
119       // Do the version info bits match exactly? done.\r
120       if (targetVersion == versionBits) {\r
121         return getVersionForNumber(i + 7);\r
122       }\r
123       // Otherwise see if this is the closest to a real version info bit string\r
124       // we have seen so far\r
125       int bitsDifference = FormatInformation.numBitsDiffering(versionBits, targetVersion);\r
126       if (bitsDifference < bestDifference) {\r
127         bestVersion = i + 7;\r
128         bestDifference = bitsDifference;\r
129       }\r
130     }\r
131     // We can tolerate up to 3 bits of error since no two version info codewords will\r
132     // differ in less than 4 bits.\r
133     if (bestDifference <= 3) {\r
134       return getVersionForNumber(bestVersion);\r
135     }\r
136     // If we didn't find a close enough match, fail\r
137     return null;\r
138   }\r
139 \r
140   /**\r
141    * See ISO 18004:2006 Annex E\r
142    */\r
143   BitMatrix buildFunctionPattern() {\r
144     int dimension = getDimensionForVersion();\r
145     BitMatrix bitMatrix = new BitMatrix(dimension);\r
146 \r
147     // Top left finder pattern + separator + format\r
148     bitMatrix.setRegion(0, 0, 9, 9);\r
149     // Top right finder pattern + separator + format\r
150     bitMatrix.setRegion(dimension - 8, 0, 8, 9);\r
151     // Bottom left finder pattern + separator + format\r
152     bitMatrix.setRegion(0, dimension - 8, 9, 8);\r
153 \r
154     // Alignment patterns\r
155     int max = alignmentPatternCenters.length;\r
156     for (int x = 0; x < max; x++) {\r
157       int i = alignmentPatternCenters[x] - 2;\r
158       for (int y = 0; y < max; y++) {\r
159         if ((x == 0 && (y == 0 || y == max - 1)) || (x == max - 1 && y == 0)) {\r
160           // No alignment patterns near the three finder paterns\r
161           continue;\r
162         }\r
163         bitMatrix.setRegion(alignmentPatternCenters[y] - 2, i, 5, 5);\r
164       }\r
165     }\r
166 \r
167     // Vertical timing pattern\r
168     bitMatrix.setRegion(6, 9, 1, dimension - 17);\r
169     // Horizontal timing pattern\r
170     bitMatrix.setRegion(9, 6, dimension - 17, 1);\r
171 \r
172     if (versionNumber > 6) {\r
173       // Version info, top right\r
174       bitMatrix.setRegion(dimension - 11, 0, 3, 6);\r
175       // Version info, bottom left\r
176       bitMatrix.setRegion(0, dimension - 11, 6, 3);\r
177     }\r
178 \r
179     return bitMatrix;\r
180   }\r
181 \r
182   /**\r
183    * <p>Encapsulates a set of error-correction blocks in one symbol version. Most versions will\r
184    * use blocks of differing sizes within one version, so, this encapsulates the parameters for\r
185    * each set of blocks. It also holds the number of error-correction codewords per block since it\r
186    * will be the same across all blocks within one version.</p>\r
187    */\r
188   public static final class ECBlocks {\r
189     private final int ecCodewordsPerBlock;\r
190     private final ECB[] ecBlocks;\r
191 \r
192     ECBlocks(int ecCodewordsPerBlock, ECB ecBlocks) {\r
193       this.ecCodewordsPerBlock = ecCodewordsPerBlock;\r
194       this.ecBlocks = new ECB[]{ecBlocks};\r
195     }\r
196 \r
197     ECBlocks(int ecCodewordsPerBlock, ECB ecBlocks1, ECB ecBlocks2) {\r
198       this.ecCodewordsPerBlock = ecCodewordsPerBlock;\r
199       this.ecBlocks = new ECB[]{ecBlocks1, ecBlocks2};\r
200     }\r
201 \r
202     public int getECCodewordsPerBlock() {\r
203       return ecCodewordsPerBlock;\r
204     }\r
205 \r
206     public int getNumBlocks() {\r
207       int total = 0;\r
208       for (int i = 0; i < ecBlocks.length; i++) {\r
209         total += ecBlocks[i].getCount();\r
210       }\r
211       return total;\r
212     }\r
213 \r
214     public int getTotalECCodewords() {\r
215       return ecCodewordsPerBlock * getNumBlocks();\r
216     }\r
217 \r
218     public ECB[] getECBlocks() {\r
219       return ecBlocks;\r
220     }\r
221   }\r
222 \r
223   /**\r
224    * <p>Encapsualtes the parameters for one error-correction block in one symbol version.\r
225    * This includes the number of data codewords, and the number of times a block with these\r
226    * parameters is used consecutively in the QR code version's format.</p>\r
227    */\r
228   public static final class ECB {\r
229     private final int count;\r
230     private final int dataCodewords;\r
231 \r
232     ECB(int count, int dataCodewords) {\r
233       this.count = count;\r
234       this.dataCodewords = dataCodewords;\r
235     }\r
236 \r
237     public int getCount() {\r
238       return count;\r
239     }\r
240 \r
241     public int getDataCodewords() {\r
242       return dataCodewords;\r
243     }\r
244   }\r
245 \r
246   public String toString() {\r
247     return String.valueOf(versionNumber);\r
248   }\r
249 \r
250   /**\r
251    * See ISO 18004:2006 6.5.1 Table 9\r
252    */\r
253   private static Version[] buildVersions() {\r
254     return new Version[]{\r
255         new Version(1, new int[]{},\r
256             new ECBlocks(7, new ECB(1, 19)),\r
257             new ECBlocks(10, new ECB(1, 16)),\r
258             new ECBlocks(13, new ECB(1, 13)),\r
259             new ECBlocks(17, new ECB(1, 9))),\r
260         new Version(2, new int[]{6, 18},\r
261             new ECBlocks(10, new ECB(1, 34)),\r
262             new ECBlocks(16, new ECB(1, 28)),\r
263             new ECBlocks(22, new ECB(1, 22)),\r
264             new ECBlocks(28, new ECB(1, 16))),\r
265         new Version(3, new int[]{6, 22},\r
266             new ECBlocks(15, new ECB(1, 55)),\r
267             new ECBlocks(26, new ECB(1, 44)),\r
268             new ECBlocks(18, new ECB(2, 17)),\r
269             new ECBlocks(22, new ECB(2, 13))),\r
270         new Version(4, new int[]{6, 26},\r
271             new ECBlocks(20, new ECB(1, 80)),\r
272             new ECBlocks(18, new ECB(2, 32)),\r
273             new ECBlocks(26, new ECB(2, 24)),\r
274             new ECBlocks(16, new ECB(4, 9))),\r
275         new Version(5, new int[]{6, 30},\r
276             new ECBlocks(26, new ECB(1, 108)),\r
277             new ECBlocks(24, new ECB(2, 43)),\r
278             new ECBlocks(18, new ECB(2, 15),\r
279                 new ECB(2, 16)),\r
280             new ECBlocks(22, new ECB(2, 11),\r
281                 new ECB(2, 12))),\r
282         new Version(6, new int[]{6, 34},\r
283             new ECBlocks(18, new ECB(2, 68)),\r
284             new ECBlocks(16, new ECB(4, 27)),\r
285             new ECBlocks(24, new ECB(4, 19)),\r
286             new ECBlocks(28, new ECB(4, 15))),\r
287         new Version(7, new int[]{6, 22, 38},\r
288             new ECBlocks(20, new ECB(2, 78)),\r
289             new ECBlocks(18, new ECB(4, 31)),\r
290             new ECBlocks(18, new ECB(2, 14),\r
291                 new ECB(4, 15)),\r
292             new ECBlocks(26, new ECB(4, 13),\r
293                 new ECB(1, 14))),\r
294         new Version(8, new int[]{6, 24, 42},\r
295             new ECBlocks(24, new ECB(2, 97)),\r
296             new ECBlocks(22, new ECB(2, 38),\r
297                 new ECB(2, 39)),\r
298             new ECBlocks(22, new ECB(4, 18),\r
299                 new ECB(2, 19)),\r
300             new ECBlocks(26, new ECB(4, 14),\r
301                 new ECB(2, 15))),\r
302         new Version(9, new int[]{6, 26, 46},\r
303             new ECBlocks(30, new ECB(2, 116)),\r
304             new ECBlocks(22, new ECB(3, 36),\r
305                 new ECB(2, 37)),\r
306             new ECBlocks(20, new ECB(4, 16),\r
307                 new ECB(4, 17)),\r
308             new ECBlocks(24, new ECB(4, 12),\r
309                 new ECB(4, 13))),\r
310         new Version(10, new int[]{6, 28, 50},\r
311             new ECBlocks(18, new ECB(2, 68),\r
312                 new ECB(2, 69)),\r
313             new ECBlocks(26, new ECB(4, 43),\r
314                 new ECB(1, 44)),\r
315             new ECBlocks(24, new ECB(6, 19),\r
316                 new ECB(2, 20)),\r
317             new ECBlocks(28, new ECB(6, 15),\r
318                 new ECB(2, 16))),\r
319         new Version(11, new int[]{6, 30, 54},\r
320             new ECBlocks(20, new ECB(4, 81)),\r
321             new ECBlocks(30, new ECB(1, 50),\r
322                 new ECB(4, 51)),\r
323             new ECBlocks(28, new ECB(4, 22),\r
324                 new ECB(4, 23)),\r
325             new ECBlocks(24, new ECB(3, 12),\r
326                 new ECB(8, 13))),\r
327         new Version(12, new int[]{6, 32, 58},\r
328             new ECBlocks(24, new ECB(2, 92),\r
329                 new ECB(2, 93)),\r
330             new ECBlocks(22, new ECB(6, 36),\r
331                 new ECB(2, 37)),\r
332             new ECBlocks(26, new ECB(4, 20),\r
333                 new ECB(6, 21)),\r
334             new ECBlocks(28, new ECB(7, 14),\r
335                 new ECB(4, 15))),\r
336         new Version(13, new int[]{6, 34, 62},\r
337             new ECBlocks(26, new ECB(4, 107)),\r
338             new ECBlocks(22, new ECB(8, 37),\r
339                 new ECB(1, 38)),\r
340             new ECBlocks(24, new ECB(8, 20),\r
341                 new ECB(4, 21)),\r
342             new ECBlocks(22, new ECB(12, 11),\r
343                 new ECB(4, 12))),\r
344         new Version(14, new int[]{6, 26, 46, 66},\r
345             new ECBlocks(30, new ECB(3, 115),\r
346                 new ECB(1, 116)),\r
347             new ECBlocks(24, new ECB(4, 40),\r
348                 new ECB(5, 41)),\r
349             new ECBlocks(20, new ECB(11, 16),\r
350                 new ECB(5, 17)),\r
351             new ECBlocks(24, new ECB(11, 12),\r
352                 new ECB(5, 13))),\r
353         new Version(15, new int[]{6, 26, 48, 70},\r
354             new ECBlocks(22, new ECB(5, 87),\r
355                 new ECB(1, 88)),\r
356             new ECBlocks(24, new ECB(5, 41),\r
357                 new ECB(5, 42)),\r
358             new ECBlocks(30, new ECB(5, 24),\r
359                 new ECB(7, 25)),\r
360             new ECBlocks(24, new ECB(11, 12),\r
361                 new ECB(7, 13))),\r
362         new Version(16, new int[]{6, 26, 50, 74},\r
363             new ECBlocks(24, new ECB(5, 98),\r
364                 new ECB(1, 99)),\r
365             new ECBlocks(28, new ECB(7, 45),\r
366                 new ECB(3, 46)),\r
367             new ECBlocks(24, new ECB(15, 19),\r
368                 new ECB(2, 20)),\r
369             new ECBlocks(30, new ECB(3, 15),\r
370                 new ECB(13, 16))),\r
371         new Version(17, new int[]{6, 30, 54, 78},\r
372             new ECBlocks(28, new ECB(1, 107),\r
373                 new ECB(5, 108)),\r
374             new ECBlocks(28, new ECB(10, 46),\r
375                 new ECB(1, 47)),\r
376             new ECBlocks(28, new ECB(1, 22),\r
377                 new ECB(15, 23)),\r
378             new ECBlocks(28, new ECB(2, 14),\r
379                 new ECB(17, 15))),\r
380         new Version(18, new int[]{6, 30, 56, 82},\r
381             new ECBlocks(30, new ECB(5, 120),\r
382                 new ECB(1, 121)),\r
383             new ECBlocks(26, new ECB(9, 43),\r
384                 new ECB(4, 44)),\r
385             new ECBlocks(28, new ECB(17, 22),\r
386                 new ECB(1, 23)),\r
387             new ECBlocks(28, new ECB(2, 14),\r
388                 new ECB(19, 15))),\r
389         new Version(19, new int[]{6, 30, 58, 86},\r
390             new ECBlocks(28, new ECB(3, 113),\r
391                 new ECB(4, 114)),\r
392             new ECBlocks(26, new ECB(3, 44),\r
393                 new ECB(11, 45)),\r
394             new ECBlocks(26, new ECB(17, 21),\r
395                 new ECB(4, 22)),\r
396             new ECBlocks(26, new ECB(9, 13),\r
397                 new ECB(16, 14))),\r
398         new Version(20, new int[]{6, 34, 62, 90},\r
399             new ECBlocks(28, new ECB(3, 107),\r
400                 new ECB(5, 108)),\r
401             new ECBlocks(26, new ECB(3, 41),\r
402                 new ECB(13, 42)),\r
403             new ECBlocks(30, new ECB(15, 24),\r
404                 new ECB(5, 25)),\r
405             new ECBlocks(28, new ECB(15, 15),\r
406                 new ECB(10, 16))),\r
407         new Version(21, new int[]{6, 28, 50, 72, 94},\r
408             new ECBlocks(28, new ECB(4, 116),\r
409                 new ECB(4, 117)),\r
410             new ECBlocks(26, new ECB(17, 42)),\r
411             new ECBlocks(28, new ECB(17, 22),\r
412                 new ECB(6, 23)),\r
413             new ECBlocks(30, new ECB(19, 16),\r
414                 new ECB(6, 17))),\r
415         new Version(22, new int[]{6, 26, 50, 74, 98},\r
416             new ECBlocks(28, new ECB(2, 111),\r
417                 new ECB(7, 112)),\r
418             new ECBlocks(28, new ECB(17, 46)),\r
419             new ECBlocks(30, new ECB(7, 24),\r
420                 new ECB(16, 25)),\r
421             new ECBlocks(24, new ECB(34, 13))),\r
422         new Version(23, new int[]{6, 30, 54, 74, 102},\r
423             new ECBlocks(30, new ECB(4, 121),\r
424                 new ECB(5, 122)),\r
425             new ECBlocks(28, new ECB(4, 47),\r
426                 new ECB(14, 48)),\r
427             new ECBlocks(30, new ECB(11, 24),\r
428                 new ECB(14, 25)),\r
429             new ECBlocks(30, new ECB(16, 15),\r
430                 new ECB(14, 16))),\r
431         new Version(24, new int[]{6, 28, 54, 80, 106},\r
432             new ECBlocks(30, new ECB(6, 117),\r
433                 new ECB(4, 118)),\r
434             new ECBlocks(28, new ECB(6, 45),\r
435                 new ECB(14, 46)),\r
436             new ECBlocks(30, new ECB(11, 24),\r
437                 new ECB(16, 25)),\r
438             new ECBlocks(30, new ECB(30, 16),\r
439                 new ECB(2, 17))),\r
440         new Version(25, new int[]{6, 32, 58, 84, 110},\r
441             new ECBlocks(26, new ECB(8, 106),\r
442                 new ECB(4, 107)),\r
443             new ECBlocks(28, new ECB(8, 47),\r
444                 new ECB(13, 48)),\r
445             new ECBlocks(30, new ECB(7, 24),\r
446                 new ECB(22, 25)),\r
447             new ECBlocks(30, new ECB(22, 15),\r
448                 new ECB(13, 16))),\r
449         new Version(26, new int[]{6, 30, 58, 86, 114},\r
450             new ECBlocks(28, new ECB(10, 114),\r
451                 new ECB(2, 115)),\r
452             new ECBlocks(28, new ECB(19, 46),\r
453                 new ECB(4, 47)),\r
454             new ECBlocks(28, new ECB(28, 22),\r
455                 new ECB(6, 23)),\r
456             new ECBlocks(30, new ECB(33, 16),\r
457                 new ECB(4, 17))),\r
458         new Version(27, new int[]{6, 34, 62, 90, 118},\r
459             new ECBlocks(30, new ECB(8, 122),\r
460                 new ECB(4, 123)),\r
461             new ECBlocks(28, new ECB(22, 45),\r
462                 new ECB(3, 46)),\r
463             new ECBlocks(30, new ECB(8, 23),\r
464                 new ECB(26, 24)),\r
465             new ECBlocks(30, new ECB(12, 15),\r
466                 new ECB(28, 16))),\r
467         new Version(28, new int[]{6, 26, 50, 74, 98, 122},\r
468             new ECBlocks(30, new ECB(3, 117),\r
469                 new ECB(10, 118)),\r
470             new ECBlocks(28, new ECB(3, 45),\r
471                 new ECB(23, 46)),\r
472             new ECBlocks(30, new ECB(4, 24),\r
473                 new ECB(31, 25)),\r
474             new ECBlocks(30, new ECB(11, 15),\r
475                 new ECB(31, 16))),\r
476         new Version(29, new int[]{6, 30, 54, 78, 102, 126},\r
477             new ECBlocks(30, new ECB(7, 116),\r
478                 new ECB(7, 117)),\r
479             new ECBlocks(28, new ECB(21, 45),\r
480                 new ECB(7, 46)),\r
481             new ECBlocks(30, new ECB(1, 23),\r
482                 new ECB(37, 24)),\r
483             new ECBlocks(30, new ECB(19, 15),\r
484                 new ECB(26, 16))),\r
485         new Version(30, new int[]{6, 26, 52, 78, 104, 130},\r
486             new ECBlocks(30, new ECB(5, 115),\r
487                 new ECB(10, 116)),\r
488             new ECBlocks(28, new ECB(19, 47),\r
489                 new ECB(10, 48)),\r
490             new ECBlocks(30, new ECB(15, 24),\r
491                 new ECB(25, 25)),\r
492             new ECBlocks(30, new ECB(23, 15),\r
493                 new ECB(25, 16))),\r
494         new Version(31, new int[]{6, 30, 56, 82, 108, 134},\r
495             new ECBlocks(30, new ECB(13, 115),\r
496                 new ECB(3, 116)),\r
497             new ECBlocks(28, new ECB(2, 46),\r
498                 new ECB(29, 47)),\r
499             new ECBlocks(30, new ECB(42, 24),\r
500                 new ECB(1, 25)),\r
501             new ECBlocks(30, new ECB(23, 15),\r
502                 new ECB(28, 16))),\r
503         new Version(32, new int[]{6, 34, 60, 86, 112, 138},\r
504             new ECBlocks(30, new ECB(17, 115)),\r
505             new ECBlocks(28, new ECB(10, 46),\r
506                 new ECB(23, 47)),\r
507             new ECBlocks(30, new ECB(10, 24),\r
508                 new ECB(35, 25)),\r
509             new ECBlocks(30, new ECB(19, 15),\r
510                 new ECB(35, 16))),\r
511         new Version(33, new int[]{6, 30, 58, 86, 114, 142},\r
512             new ECBlocks(30, new ECB(17, 115),\r
513                 new ECB(1, 116)),\r
514             new ECBlocks(28, new ECB(14, 46),\r
515                 new ECB(21, 47)),\r
516             new ECBlocks(30, new ECB(29, 24),\r
517                 new ECB(19, 25)),\r
518             new ECBlocks(30, new ECB(11, 15),\r
519                 new ECB(46, 16))),\r
520         new Version(34, new int[]{6, 34, 62, 90, 118, 146},\r
521             new ECBlocks(30, new ECB(13, 115),\r
522                 new ECB(6, 116)),\r
523             new ECBlocks(28, new ECB(14, 46),\r
524                 new ECB(23, 47)),\r
525             new ECBlocks(30, new ECB(44, 24),\r
526                 new ECB(7, 25)),\r
527             new ECBlocks(30, new ECB(59, 16),\r
528                 new ECB(1, 17))),\r
529         new Version(35, new int[]{6, 30, 54, 78, 102, 126, 150},\r
530             new ECBlocks(30, new ECB(12, 121),\r
531                 new ECB(7, 122)),\r
532             new ECBlocks(28, new ECB(12, 47),\r
533                 new ECB(26, 48)),\r
534             new ECBlocks(30, new ECB(39, 24),\r
535                 new ECB(14, 25)),\r
536             new ECBlocks(30, new ECB(22, 15),\r
537                 new ECB(41, 16))),\r
538         new Version(36, new int[]{6, 24, 50, 76, 102, 128, 154},\r
539             new ECBlocks(30, new ECB(6, 121),\r
540                 new ECB(14, 122)),\r
541             new ECBlocks(28, new ECB(6, 47),\r
542                 new ECB(34, 48)),\r
543             new ECBlocks(30, new ECB(46, 24),\r
544                 new ECB(10, 25)),\r
545             new ECBlocks(30, new ECB(2, 15),\r
546                 new ECB(64, 16))),\r
547         new Version(37, new int[]{6, 28, 54, 80, 106, 132, 158},\r
548             new ECBlocks(30, new ECB(17, 122),\r
549                 new ECB(4, 123)),\r
550             new ECBlocks(28, new ECB(29, 46),\r
551                 new ECB(14, 47)),\r
552             new ECBlocks(30, new ECB(49, 24),\r
553                 new ECB(10, 25)),\r
554             new ECBlocks(30, new ECB(24, 15),\r
555                 new ECB(46, 16))),\r
556         new Version(38, new int[]{6, 32, 58, 84, 110, 136, 162},\r
557             new ECBlocks(30, new ECB(4, 122),\r
558                 new ECB(18, 123)),\r
559             new ECBlocks(28, new ECB(13, 46),\r
560                 new ECB(32, 47)),\r
561             new ECBlocks(30, new ECB(48, 24),\r
562                 new ECB(14, 25)),\r
563             new ECBlocks(30, new ECB(42, 15),\r
564                 new ECB(32, 16))),\r
565         new Version(39, new int[]{6, 26, 54, 82, 110, 138, 166},\r
566             new ECBlocks(30, new ECB(20, 117),\r
567                 new ECB(4, 118)),\r
568             new ECBlocks(28, new ECB(40, 47),\r
569                 new ECB(7, 48)),\r
570             new ECBlocks(30, new ECB(43, 24),\r
571                 new ECB(22, 25)),\r
572             new ECBlocks(30, new ECB(10, 15),\r
573                 new ECB(67, 16))),\r
574         new Version(40, new int[]{6, 30, 58, 86, 114, 142, 170},\r
575             new ECBlocks(30, new ECB(19, 118),\r
576                 new ECB(6, 119)),\r
577             new ECBlocks(28, new ECB(18, 47),\r
578                 new ECB(31, 48)),\r
579             new ECBlocks(30, new ECB(34, 24),\r
580                 new ECB(34, 25)),\r
581             new ECBlocks(30, new ECB(20, 15),\r
582                 new ECB(61, 16)))\r
583     };\r
584   }\r
585 \r
586 }\r