Issue 165
[zxing.git] / cpp / core / src / qrcode / decoder / Version.cpp
1 /*
2  *  Version.cpp
3  *  zxing
4  *
5  *  Created by Christian Brunschen on 14/05/2008.
6  *  Copyright 2008 ZXing authors All rights reserved.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include "Version.h"
22 #include <cstdarg>
23 #include <limits>
24 #include "FormatInformation.h"
25 #include <iostream>
26
27 namespace qrcode {
28   namespace decoder {
29     unsigned int Version::VERSION_DECODE_INFO[] = {
30     0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6,
31     0x0C762, 0x0D847, 0x0E60D, 0x0F928, 0x10B78,
32     0x1145D, 0x12A17, 0x13532, 0x149A6, 0x15683,
33     0x168C9, 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB,
34     0x1B08E, 0x1CC1A, 0x1D33F, 0x1ED75, 0x1F250,
35     0x209D5, 0x216F0, 0x228BA, 0x2379F, 0x24B0B,
36     0x2542E, 0x26A64, 0x27541, 0x28C69
37     };
38     int Version::N_VERSION_DECODE_INFOS = 34;
39     vector<Version*> Version::VERSIONS;
40     static int N_VERSIONS = Version::buildVersions();
41     
42     
43     int Version::getVersionNumber() {
44       return versionNumber_; 
45     }
46     
47     valarray<int> &Version::getAlignmentPatternCenters() { 
48       return alignmentPatternCenters_; 
49     }
50     
51     int Version::getTotalCodewords() { 
52       return totalCodewords_; 
53     }
54     
55     int Version::getDimensionForVersion() { 
56       return 17 + 4 * versionNumber_;
57     }
58     
59     Version::ECBlocks& 
60     Version::getECBlocksForLevel(ErrorCorrectionLevel &ecLevel) {
61       return *ecBlocks_[ecLevel.ordinal()];
62     }
63     
64     Version *Version::getProvisionalVersionForDimension(int dimension) {
65       if (dimension %4 != 1) { 
66         throw new ReaderException("Dimension must be 1 mod 4");
67       }
68       return Version::getVersionForNumber((dimension - 17) >> 2);
69     }
70     
71     Version *Version::getVersionForNumber(int versionNumber) {
72       if (versionNumber < 1 || versionNumber > 40) {
73         throw new ReaderException("versionNumber must be between 1 and 40");
74       }
75       N_VERSIONS;
76       return VERSIONS[versionNumber - 1];
77     }
78     
79     Version::Version(int versionNumber,
80                      valarray<int> *alignmentPatternCenters,
81                      ECBlocks *ecBlocks1,
82                      ECBlocks *ecBlocks2,
83                      ECBlocks *ecBlocks3,
84                      ECBlocks *ecBlocks4) :
85     versionNumber_(versionNumber),
86     alignmentPatternCenters_(*alignmentPatternCenters),
87     ecBlocks_(4)
88     {
89       ecBlocks_[0] = ecBlocks1;
90       ecBlocks_[1] = ecBlocks2;
91       ecBlocks_[2] = ecBlocks3;
92       ecBlocks_[3] = ecBlocks4;
93       
94       int total = 0;
95       int ecCodewords = ecBlocks1->getECCodewords();
96       vector<ECB*> &ecbArray = ecBlocks1->getECBlocks();
97       for (size_t i = 0; i < ecbArray.size(); i++) {
98         ECB *ecBlock = ecbArray[i];
99         total += ecBlock->getCount() * 
100           (ecBlock->getDataCodewords() + ecCodewords);
101       }
102       totalCodewords_ = total;
103     }
104     
105     
106     Version *Version::decodeVersionInformation(unsigned int versionBits) {
107       int bestDifference = numeric_limits<int>::max();
108       size_t bestVersion = 0;
109       for (int i = 0; i < N_VERSION_DECODE_INFOS; i++) {
110         unsigned targetVersion = VERSION_DECODE_INFO[i];
111         // Do the version info bits match exactly? done.
112         if (targetVersion == versionBits) {
113           return getVersionForNumber(i + 7);
114         }
115         // Otherwise see if this is the closest to a real version info bit
116         // string we have seen so far
117         int bitsDifference = 
118           FormatInformation::numBitsDiffering(versionBits, targetVersion);
119         if (bitsDifference < bestDifference) {
120           bestVersion = i + 7;
121           bestDifference = bitsDifference;
122         }
123       }
124       // We can tolerate up to 3 bits of error since no two version info codewords will
125       // differ in less than 4 bits.
126       if (bestDifference <= 3) {
127         return getVersionForNumber(bestVersion);
128       }
129       // If we didn't find a close enough match, fail
130       return 0;
131     }
132     
133     Ref<BitMatrix> Version::buildFunctionPattern() {
134       int dimension = getDimensionForVersion();
135       Ref<BitMatrix> functionPattern(new BitMatrix(dimension));
136       
137       // Top left finder pattern + separator + format
138       functionPattern->setRegion(0, 0, 9, 9);
139       // Top right finder pattern + separator + format
140       functionPattern->setRegion(0, dimension - 8, 9, 8);
141       // Bottom left finder pattern + separator + format
142       functionPattern->setRegion(dimension - 8, 0, 8, 9);
143       
144       // Alignment patterns
145       size_t max = alignmentPatternCenters_.size();
146       for (size_t x = 0; x < max; x++) {
147         int i = alignmentPatternCenters_[x] - 2;
148         for (size_t y = 0; y < max; y++) {
149           if ((x == 0 && (y == 0 || y == max - 1)) || 
150               (x == max - 1 && y == 0)) {
151             // No alignment patterns near the three finder patterns
152             continue;
153           }
154           functionPattern->setRegion(i, alignmentPatternCenters_[y] - 2, 5, 5);
155         }
156       }
157       
158       // Vertical timing pattern
159       functionPattern->setRegion(9, 6, dimension - 17, 1);
160       // Horizontal timing pattern
161       functionPattern->setRegion(6, 9, 1, dimension - 17);
162       
163       if (versionNumber_ > 6) {
164         // Version info, top right
165         functionPattern->setRegion(0, dimension - 11, 6, 3);
166         // Version info, bottom left
167         functionPattern->setRegion(dimension - 11, 0, 3, 6);
168       }
169       
170 #ifdef DEBUG
171       cout << "version " << versionNumber_ << " built function pattern:\n";
172       cout << *functionPattern;
173 #endif
174       
175       return functionPattern;
176     }
177     
178     static valarray<int> *intArray(size_t n ...) {
179       va_list ap;
180       va_start(ap, n);
181       valarray<int> *result = new valarray<int>(n);
182       for (size_t i = 0; i < n; i++) {
183         (*result)[i] = va_arg(ap, int);
184       }
185       va_end(ap);
186       return result;
187     }
188     
189     int Version::buildVersions() {
190       VERSIONS.push_back(new Version(1, intArray(0),
191                                      new ECBlocks(7, new ECB(1, 19)),
192                                      new ECBlocks(10, new ECB(1, 16)),
193                                      new ECBlocks(13, new ECB(1, 13)),
194                                      new ECBlocks(17, new ECB(1, 9))));
195       VERSIONS.push_back(new Version(2, intArray(2, 6, 18),
196                                      new ECBlocks(10, new ECB(1, 34)),
197                                      new ECBlocks(16, new ECB(1, 28)),
198                                      new ECBlocks(22, new ECB(1, 22)),
199                                      new ECBlocks(28, new ECB(1, 16))));
200       VERSIONS.push_back(new Version(3, intArray(2, 6, 22),
201                                      new ECBlocks(15, new ECB(1, 55)),
202                                      new ECBlocks(26, new ECB(1, 44)),
203                                      new ECBlocks(18, new ECB(2, 17)),
204                                      new ECBlocks(22, new ECB(2, 13))));
205       VERSIONS.push_back(new Version(4, intArray(2, 6, 26),
206                                      new ECBlocks(20, new ECB(1, 80)),
207                                      new ECBlocks(18, new ECB(2, 32)),
208                                      new ECBlocks(26, new ECB(2, 24)),
209                                      new ECBlocks(16, new ECB(4, 9))));
210       VERSIONS.push_back(new Version(5, intArray(2, 6, 30),
211                                      new ECBlocks(26, new ECB(1, 108)),
212                                      new ECBlocks(24, new ECB(2, 43)),
213                                      new ECBlocks(18, new ECB(2, 15),
214                                                   new ECB(2, 16)),
215                                      new ECBlocks(22, new ECB(2, 11),
216                                                   new ECB(2, 12))));
217       VERSIONS.push_back(new Version(6, intArray(2, 6, 34),
218                                      new ECBlocks(18, new ECB(2, 68)),
219                                      new ECBlocks(16, new ECB(4, 27)),
220                                      new ECBlocks(24, new ECB(4, 19)),
221                                      new ECBlocks(28, new ECB(4, 15))));
222       VERSIONS.push_back(new Version(7, intArray(3, 6, 22, 38),
223                                      new ECBlocks(20, new ECB(2, 78)),
224                                      new ECBlocks(18, new ECB(4, 31)),
225                                      new ECBlocks(18, new ECB(2, 14),
226                                                   new ECB(4, 15)),
227                                      new ECBlocks(26, new ECB(4, 13),
228                                                   new ECB(1, 14))));
229       VERSIONS.push_back(new Version(8, intArray(3, 6, 24, 42),
230                                      new ECBlocks(24, new ECB(2, 97)),
231                                      new ECBlocks(22, new ECB(2, 38),
232                                                   new ECB(2, 39)),
233                                      new ECBlocks(22, new ECB(4, 18),
234                                                   new ECB(2, 19)),
235                                      new ECBlocks(26, new ECB(4, 14),
236                                                   new ECB(2, 15))));
237       VERSIONS.push_back(new Version(9, intArray(3, 6, 26, 46),
238                                      new ECBlocks(30, new ECB(2, 116)),
239                                      new ECBlocks(22, new ECB(3, 36),
240                                                   new ECB(2, 37)),
241                                      new ECBlocks(20, new ECB(4, 16),
242                                                   new ECB(4, 17)),
243                                      new ECBlocks(24, new ECB(4, 12),
244                                                   new ECB(4, 13))));
245       VERSIONS.push_back(new Version(10, intArray(3, 6, 28, 50),
246                                      new ECBlocks(18, new ECB(2, 68),
247                                                   new ECB(2, 69)),
248                                      new ECBlocks(26, new ECB(4, 43),
249                                                   new ECB(1, 44)),
250                                      new ECBlocks(24, new ECB(6, 19),
251                                                   new ECB(2, 20)),
252                                      new ECBlocks(28, new ECB(6, 15),
253                                                   new ECB(2, 16))));
254       VERSIONS.push_back(new Version(11, intArray(3, 6, 30, 54),
255                                      new ECBlocks(20, new ECB(4, 81)),
256                                      new ECBlocks(30, new ECB(1, 50),
257                                                   new ECB(4, 51)),
258                                      new ECBlocks(28, new ECB(4, 22),
259                                                   new ECB(4, 23)),
260                                      new ECBlocks(24, new ECB(3, 12),
261                                                   new ECB(8, 13))));
262       VERSIONS.push_back(new Version(12, intArray(3, 6, 32, 58),
263                                      new ECBlocks(24, new ECB(2, 92),
264                                                   new ECB(2, 93)),
265                                      new ECBlocks(22, new ECB(6, 36),
266                                                   new ECB(2, 37)),
267                                      new ECBlocks(26, new ECB(4, 20),
268                                                   new ECB(6, 21)),
269                                      new ECBlocks(28, new ECB(7, 14),
270                                                   new ECB(4, 15))));
271       VERSIONS.push_back(new Version(13, intArray(3, 6, 34, 62),
272                                      new ECBlocks(26, new ECB(4, 107)),
273                                      new ECBlocks(22, new ECB(8, 37),
274                                                   new ECB(1, 38)),
275                                      new ECBlocks(24, new ECB(8, 20),
276                                                   new ECB(4, 21)),
277                                      new ECBlocks(22, new ECB(12, 11),
278                                                   new ECB(4, 12))));
279       VERSIONS.push_back(new Version(14, intArray(4, 6, 26, 46, 66),
280                                      new ECBlocks(30, new ECB(3, 115),
281                                                   new ECB(1, 116)),
282                                      new ECBlocks(24, new ECB(4, 40),
283                                                   new ECB(5, 41)),
284                                      new ECBlocks(20, new ECB(11, 16),
285                                                   new ECB(5, 17)),
286                                      new ECBlocks(24, new ECB(11, 12),
287                                                   new ECB(5, 13))));
288       VERSIONS.push_back(new Version(15, intArray(4, 6, 26, 48, 70),
289                                      new ECBlocks(22, new ECB(5, 87),
290                                                   new ECB(1, 88)),
291                                      new ECBlocks(24, new ECB(5, 41),
292                                                   new ECB(5, 42)),
293                                      new ECBlocks(30, new ECB(5, 24),
294                                                   new ECB(7, 25)),
295                                      new ECBlocks(24, new ECB(11, 12),
296                                                   new ECB(7, 13))));
297       VERSIONS.push_back(new Version(16, intArray(4, 6, 26, 50, 74),
298                                      new ECBlocks(24, new ECB(5, 98),
299                                                   new ECB(1, 99)),
300                                      new ECBlocks(28, new ECB(7, 45),
301                                                   new ECB(3, 46)),
302                                      new ECBlocks(24, new ECB(15, 19),
303                                                   new ECB(2, 20)),
304                                      new ECBlocks(30, new ECB(3, 15),
305                                                   new ECB(13, 16))));
306       VERSIONS.push_back(new Version(17, intArray(4, 6, 30, 54, 78),
307                                      new ECBlocks(28, new ECB(1, 107),
308                                                   new ECB(5, 108)),
309                                      new ECBlocks(28, new ECB(10, 46),
310                                                   new ECB(1, 47)),
311                                      new ECBlocks(28, new ECB(1, 22),
312                                                   new ECB(15, 23)),
313                                      new ECBlocks(28, new ECB(2, 14),
314                                                   new ECB(17, 15))));
315       VERSIONS.push_back(new Version(18, intArray(4, 6, 30, 56, 82),
316                                      new ECBlocks(30, new ECB(5, 120),
317                                                   new ECB(1, 121)),
318                                      new ECBlocks(26, new ECB(9, 43),
319                                                   new ECB(4, 44)),
320                                      new ECBlocks(28, new ECB(17, 22),
321                                                   new ECB(1, 23)),
322                                      new ECBlocks(28, new ECB(2, 14),
323                                                   new ECB(19, 15))));
324       VERSIONS.push_back(new Version(19, intArray(4, 6, 30, 58, 86),
325                                      new ECBlocks(28, new ECB(3, 113),
326                                                   new ECB(4, 114)),
327                                      new ECBlocks(26, new ECB(3, 44),
328                                                   new ECB(11, 45)),
329                                      new ECBlocks(26, new ECB(17, 21),
330                                                   new ECB(4, 22)),
331                                      new ECBlocks(26, new ECB(9, 13),
332                                                   new ECB(16, 14))));
333       VERSIONS.push_back(new Version(20, intArray(4, 6, 34, 62, 90),
334                                      new ECBlocks(28, new ECB(3, 107),
335                                                   new ECB(5, 108)),
336                                      new ECBlocks(26, new ECB(3, 41),
337                                                   new ECB(13, 42)),
338                                      new ECBlocks(30, new ECB(15, 24),
339                                                   new ECB(5, 25)),
340                                      new ECBlocks(28, new ECB(15, 15),
341                                                   new ECB(10, 16))));
342       VERSIONS.push_back(new Version(21, intArray(5, 6, 28, 50, 72, 94),
343                                      new ECBlocks(28, new ECB(4, 116),
344                                                   new ECB(4, 117)),
345                                      new ECBlocks(26, new ECB(17, 42)),
346                                      new ECBlocks(28, new ECB(17, 22),
347                                                   new ECB(6, 23)),
348                                      new ECBlocks(30, new ECB(19, 16),
349                                                   new ECB(6, 17))));
350       VERSIONS.push_back(new Version(22, intArray(5, 6, 26, 50, 74, 98),
351                                      new ECBlocks(28, new ECB(2, 111),
352                                                   new ECB(7, 112)),
353                                      new ECBlocks(28, new ECB(17, 46)),
354                                      new ECBlocks(30, new ECB(7, 24),
355                                                   new ECB(16, 25)),
356                                      new ECBlocks(24, new ECB(34, 13))));
357       VERSIONS.push_back(new Version(23, intArray(5, 6, 30, 54, 74, 102),
358                                      new ECBlocks(30, new ECB(4, 121),
359                                                   new ECB(5, 122)),
360                                      new ECBlocks(28, new ECB(4, 47),
361                                                   new ECB(14, 48)),
362                                      new ECBlocks(30, new ECB(11, 24),
363                                                   new ECB(14, 25)),
364                                      new ECBlocks(30, new ECB(16, 15),
365                                                   new ECB(14, 16))));
366       VERSIONS.push_back(new Version(24, intArray(5, 6, 28, 54, 80, 106),
367                                      new ECBlocks(30, new ECB(6, 117),
368                                                   new ECB(4, 118)),
369                                      new ECBlocks(28, new ECB(6, 45),
370                                                   new ECB(14, 46)),
371                                      new ECBlocks(30, new ECB(11, 24),
372                                                   new ECB(16, 25)),
373                                      new ECBlocks(30, new ECB(30, 16),
374                                                   new ECB(2, 17))));
375       VERSIONS.push_back(new Version(25, intArray(5, 6, 32, 58, 84, 110),
376                                      new ECBlocks(26, new ECB(8, 106),
377                                                   new ECB(4, 107)),
378                                      new ECBlocks(28, new ECB(8, 47),
379                                                   new ECB(13, 48)),
380                                      new ECBlocks(30, new ECB(7, 24),
381                                                   new ECB(22, 25)),
382                                      new ECBlocks(30, new ECB(22, 15),
383                                                   new ECB(13, 16))));
384       VERSIONS.push_back(new Version(26, intArray(5, 6, 30, 58, 86, 114),
385                                      new ECBlocks(28, new ECB(10, 114),
386                                                   new ECB(2, 115)),
387                                      new ECBlocks(28, new ECB(19, 46),
388                                                   new ECB(4, 47)),
389                                      new ECBlocks(28, new ECB(28, 22),
390                                                   new ECB(6, 23)),
391                                      new ECBlocks(30, new ECB(33, 16),
392                                                   new ECB(4, 17))));
393       VERSIONS.push_back(new Version(27, intArray(5, 6, 34, 62, 90, 118),
394                                      new ECBlocks(30, new ECB(8, 122),
395                                                   new ECB(4, 123)),
396                                      new ECBlocks(28, new ECB(22, 45),
397                                                   new ECB(3, 46)),
398                                      new ECBlocks(30, new ECB(8, 23),
399                                                   new ECB(26, 24)),
400                                      new ECBlocks(30, new ECB(12, 15),
401                                                   new ECB(28, 16))));
402       VERSIONS.push_back(new Version(28, intArray(6, 6, 26, 50, 74, 98, 122),
403                                      new ECBlocks(30, new ECB(3, 117),
404                                                   new ECB(10, 118)),
405                                      new ECBlocks(28, new ECB(3, 45),
406                                                   new ECB(23, 46)),
407                                      new ECBlocks(30, new ECB(4, 24),
408                                                   new ECB(31, 25)),
409                                      new ECBlocks(30, new ECB(11, 15),
410                                                   new ECB(31, 16))));
411       VERSIONS.push_back(new Version(29, intArray(6, 6, 30, 54, 78, 102, 126),
412                                      new ECBlocks(30, new ECB(7, 116),
413                                                   new ECB(7, 117)),
414                                      new ECBlocks(28, new ECB(21, 45),
415                                                   new ECB(7, 46)),
416                                      new ECBlocks(30, new ECB(1, 23),
417                                                   new ECB(37, 24)),
418                                      new ECBlocks(30, new ECB(19, 15),
419                                                   new ECB(26, 16))));
420       VERSIONS.push_back(new Version(30, intArray(6, 6, 26, 52, 78, 104, 130),
421                                      new ECBlocks(30, new ECB(5, 115),
422                                                   new ECB(10, 116)),
423                                      new ECBlocks(28, new ECB(19, 47),
424                                                   new ECB(10, 48)),
425                                      new ECBlocks(30, new ECB(15, 24),
426                                                   new ECB(25, 25)),
427                                      new ECBlocks(30, new ECB(23, 15),
428                                                   new ECB(25, 16))));
429       VERSIONS.push_back(new Version(31, intArray(6, 6, 30, 56, 82, 108, 134),
430                                      new ECBlocks(30, new ECB(13, 115),
431                                                   new ECB(3, 116)),
432                                      new ECBlocks(28, new ECB(2, 46),
433                                                   new ECB(29, 47)),
434                                      new ECBlocks(30, new ECB(42, 24),
435                                                   new ECB(1, 25)),
436                                      new ECBlocks(30, new ECB(23, 15),
437                                                   new ECB(28, 16))));
438       VERSIONS.push_back(new Version(32, intArray(6, 6, 34, 60, 86, 112, 138),
439                                      new ECBlocks(30, new ECB(17, 115)),
440                                      new ECBlocks(28, new ECB(10, 46),
441                                                   new ECB(23, 47)),
442                                      new ECBlocks(30, new ECB(10, 24),
443                                                   new ECB(35, 25)),
444                                      new ECBlocks(30, new ECB(19, 15),
445                                                   new ECB(35, 16))));
446       VERSIONS.push_back(new Version(33, intArray(6, 6, 30, 58, 86, 114, 142),
447                                      new ECBlocks(30, new ECB(17, 115),
448                                                   new ECB(1, 116)),
449                                      new ECBlocks(28, new ECB(14, 46),
450                                                   new ECB(21, 47)),
451                                      new ECBlocks(30, new ECB(29, 24),
452                                                   new ECB(19, 25)),
453                                      new ECBlocks(30, new ECB(11, 15),
454                                                   new ECB(46, 16))));
455       VERSIONS.push_back(new Version(34, intArray(6, 6, 34, 62, 90, 118, 146),
456                                      new ECBlocks(30, new ECB(13, 115),
457                                                   new ECB(6, 116)),
458                                      new ECBlocks(28, new ECB(14, 46),
459                                                   new ECB(23, 47)),
460                                      new ECBlocks(30, new ECB(44, 24),
461                                                   new ECB(7, 25)),
462                                      new ECBlocks(30, new ECB(59, 16),
463                                                   new ECB(1, 17))));
464       VERSIONS.push_back(new Version(35, intArray(7, 6, 30, 54, 78, 
465                                                   102, 126, 150),
466                                      new ECBlocks(30, new ECB(12, 121),
467                                                   new ECB(7, 122)),
468                                      new ECBlocks(28, new ECB(12, 47),
469                                                   new ECB(26, 48)),
470                                      new ECBlocks(30, new ECB(39, 24),
471                                                   new ECB(14, 25)),
472                                      new ECBlocks(30, new ECB(22, 15),
473                                                   new ECB(41, 16))));
474       VERSIONS.push_back(new Version(36, intArray(7, 6, 24, 50, 76,
475                                                   102, 128, 154),
476                                      new ECBlocks(30, new ECB(6, 121),
477                                                   new ECB(14, 122)),
478                                      new ECBlocks(28, new ECB(6, 47),
479                                                   new ECB(34, 48)),
480                                      new ECBlocks(30, new ECB(46, 24),
481                                                   new ECB(10, 25)),
482                                      new ECBlocks(30, new ECB(2, 15),
483                                                   new ECB(64, 16))));
484       VERSIONS.push_back(new Version(37, intArray(7, 6, 28, 54, 80, 
485                                                   106, 132, 158),
486                                      new ECBlocks(30, new ECB(17, 122),
487                                                   new ECB(4, 123)),
488                                      new ECBlocks(28, new ECB(29, 46),
489                                                   new ECB(14, 47)),
490                                      new ECBlocks(30, new ECB(49, 24),
491                                                   new ECB(10, 25)),
492                                      new ECBlocks(30, new ECB(24, 15),
493                                                   new ECB(46, 16))));
494       VERSIONS.push_back(new Version(38, intArray(7, 6, 32, 58, 84, 
495                                                   110, 136, 162),
496                                      new ECBlocks(30, new ECB(4, 122),
497                                                   new ECB(18, 123)),
498                                      new ECBlocks(28, new ECB(13, 46),
499                                                   new ECB(32, 47)),
500                                      new ECBlocks(30, new ECB(48, 24),
501                                                   new ECB(14, 25)),
502                                      new ECBlocks(30, new ECB(42, 15),
503                                                   new ECB(32, 16))));
504       VERSIONS.push_back(new Version(39, intArray(7, 6, 26, 54, 82, 
505                                                   110, 138, 166),
506                                      new ECBlocks(30, new ECB(20, 117),
507                                                   new ECB(4, 118)),
508                                      new ECBlocks(28, new ECB(40, 47),
509                                                   new ECB(7, 48)),
510                                      new ECBlocks(30, new ECB(43, 24),
511                                                   new ECB(22, 25)),
512                                      new ECBlocks(30, new ECB(10, 15),
513                                                   new ECB(67, 16))));
514       VERSIONS.push_back(new Version(40, intArray(7, 6, 30, 58, 86, 
515                                                   114, 142, 170),
516                                      new ECBlocks(30, new ECB(19, 118),
517                                                   new ECB(6, 119)),
518                                      new ECBlocks(28, new ECB(18, 47),
519                                                   new ECB(31, 48)),
520                                      new ECBlocks(30, new ECB(34, 24),
521                                                   new ECB(34, 25)),
522                                      new ECBlocks(30, new ECB(20, 15),
523                                                   new ECB(61, 16))));
524       return VERSIONS.size();
525     }
526   }  
527 }