First version of the iphone client that actually works, for at least a subset
[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 Google Inc. 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         }
122       }
123       // We can tolerate up to 3 bits of error since no two version info codewords will
124       // differ in less than 4 bits.
125       if (bestDifference <= 3) {
126         return getVersionForNumber(bestVersion);
127       }
128       // If we didn't find a close enough match, fail
129       return 0;
130     }
131     
132     Ref<BitMatrix> Version::buildFunctionPattern() {
133       int dimension = getDimensionForVersion();
134       Ref<BitMatrix> functionPattern(new BitMatrix(dimension));
135       
136       // Top left finder pattern + separator + format
137       functionPattern->setRegion(0, 0, 9, 9);
138       // Top right finder pattern + separator + format
139       functionPattern->setRegion(0, dimension - 8, 9, 8);
140       // Bottom left finder pattern + separator + format
141       functionPattern->setRegion(dimension - 8, 0, 8, 9);
142       
143       // Alignment patterns
144       size_t max = alignmentPatternCenters_.size();
145       for (size_t x = 0; x < max; x++) {
146         int i = alignmentPatternCenters_[x] - 2;
147         for (size_t y = 0; y < max; y++) {
148           if ((x == 0 && (y == 0 || y == max - 1)) || 
149               (x == max - 1 && y == 0)) {
150             // No alignment patterns near the three finder patterns
151             continue;
152           }
153           functionPattern->setRegion(i, alignmentPatternCenters_[y] - 2, 5, 5);
154         }
155       }
156       
157       // Vertical timing pattern
158       functionPattern->setRegion(9, 6, dimension - 17, 1);
159       // Horizontal timing pattern
160       functionPattern->setRegion(6, 9, 1, dimension - 17);
161       
162       if (versionNumber_ > 6) {
163         // Version info, top right
164         functionPattern->setRegion(0, dimension - 11, 6, 3);
165         // Version info, bottom left
166         functionPattern->setRegion(dimension - 11, 0, 3, 6);
167       }
168       
169       cout << "version " << versionNumber_ << " built function pattern:\n";
170       cout << *functionPattern;
171       
172       return functionPattern;
173     }
174     
175     static valarray<int> *intArray(size_t n ...) {
176       va_list ap;
177       va_start(ap, n);
178       valarray<int> *result = new valarray<int>(n);
179       for (size_t i = 0; i < n; i++) {
180         (*result)[i] = va_arg(ap, int);
181       }
182       va_end(ap);
183       return result;
184     }
185     
186     int Version::buildVersions() {
187       VERSIONS.push_back(new Version(1, intArray(0),
188                                      new ECBlocks(7, new ECB(1, 19)),
189                                      new ECBlocks(10, new ECB(1, 16)),
190                                      new ECBlocks(13, new ECB(1, 13)),
191                                      new ECBlocks(17, new ECB(1, 9))));
192       VERSIONS.push_back(new Version(2, intArray(2, 6, 18),
193                                      new ECBlocks(10, new ECB(1, 34)),
194                                      new ECBlocks(16, new ECB(1, 28)),
195                                      new ECBlocks(22, new ECB(1, 22)),
196                                      new ECBlocks(28, new ECB(1, 16))));
197       VERSIONS.push_back(new Version(3, intArray(2, 6, 22),
198                                      new ECBlocks(15, new ECB(1, 55)),
199                                      new ECBlocks(26, new ECB(1, 44)),
200                                      new ECBlocks(18, new ECB(2, 17)),
201                                      new ECBlocks(22, new ECB(2, 13))));
202       VERSIONS.push_back(new Version(4, intArray(2, 6, 26),
203                                      new ECBlocks(20, new ECB(1, 80)),
204                                      new ECBlocks(18, new ECB(2, 32)),
205                                      new ECBlocks(26, new ECB(2, 24)),
206                                      new ECBlocks(16, new ECB(4, 9))));
207       VERSIONS.push_back(new Version(5, intArray(2, 6, 30),
208                                      new ECBlocks(26, new ECB(1, 108)),
209                                      new ECBlocks(24, new ECB(2, 43)),
210                                      new ECBlocks(18, new ECB(2, 15),
211                                                   new ECB(2, 16)),
212                                      new ECBlocks(22, new ECB(2, 11),
213                                                   new ECB(2, 12))));
214       VERSIONS.push_back(new Version(6, intArray(2, 6, 34),
215                                      new ECBlocks(18, new ECB(2, 68)),
216                                      new ECBlocks(16, new ECB(4, 27)),
217                                      new ECBlocks(24, new ECB(4, 19)),
218                                      new ECBlocks(28, new ECB(4, 15))));
219       VERSIONS.push_back(new Version(7, intArray(3, 6, 22, 38),
220                                      new ECBlocks(20, new ECB(2, 78)),
221                                      new ECBlocks(18, new ECB(4, 31)),
222                                      new ECBlocks(18, new ECB(2, 14),
223                                                   new ECB(4, 15)),
224                                      new ECBlocks(26, new ECB(4, 13),
225                                                   new ECB(1, 14))));
226       VERSIONS.push_back(new Version(8, intArray(3, 6, 24, 42),
227                                      new ECBlocks(24, new ECB(2, 97)),
228                                      new ECBlocks(22, new ECB(2, 38),
229                                                   new ECB(2, 39)),
230                                      new ECBlocks(22, new ECB(4, 18),
231                                                   new ECB(2, 19)),
232                                      new ECBlocks(26, new ECB(4, 14),
233                                                   new ECB(2, 15))));
234       VERSIONS.push_back(new Version(9, intArray(3, 6, 26, 46),
235                                      new ECBlocks(30, new ECB(2, 116)),
236                                      new ECBlocks(22, new ECB(3, 36),
237                                                   new ECB(2, 37)),
238                                      new ECBlocks(20, new ECB(4, 16),
239                                                   new ECB(4, 17)),
240                                      new ECBlocks(24, new ECB(4, 12),
241                                                   new ECB(4, 13))));
242       VERSIONS.push_back(new Version(10, intArray(3, 6, 28, 50),
243                                      new ECBlocks(18, new ECB(2, 68),
244                                                   new ECB(2, 69)),
245                                      new ECBlocks(26, new ECB(4, 43),
246                                                   new ECB(1, 44)),
247                                      new ECBlocks(24, new ECB(6, 19),
248                                                   new ECB(2, 20)),
249                                      new ECBlocks(28, new ECB(6, 15),
250                                                   new ECB(2, 16))));
251       VERSIONS.push_back(new Version(11, intArray(3, 6, 30, 54),
252                                      new ECBlocks(20, new ECB(4, 81)),
253                                      new ECBlocks(30, new ECB(1, 50),
254                                                   new ECB(4, 51)),
255                                      new ECBlocks(28, new ECB(4, 22),
256                                                   new ECB(4, 23)),
257                                      new ECBlocks(24, new ECB(3, 12),
258                                                   new ECB(8, 13))));
259       VERSIONS.push_back(new Version(12, intArray(3, 6, 32, 58),
260                                      new ECBlocks(24, new ECB(2, 92),
261                                                   new ECB(2, 93)),
262                                      new ECBlocks(22, new ECB(6, 36),
263                                                   new ECB(2, 37)),
264                                      new ECBlocks(26, new ECB(4, 20),
265                                                   new ECB(6, 21)),
266                                      new ECBlocks(28, new ECB(7, 14),
267                                                   new ECB(4, 15))));
268       VERSIONS.push_back(new Version(13, intArray(3, 6, 34, 62),
269                                      new ECBlocks(26, new ECB(4, 107)),
270                                      new ECBlocks(22, new ECB(8, 37),
271                                                   new ECB(1, 38)),
272                                      new ECBlocks(24, new ECB(8, 20),
273                                                   new ECB(4, 21)),
274                                      new ECBlocks(22, new ECB(12, 11),
275                                                   new ECB(4, 12))));
276       VERSIONS.push_back(new Version(14, intArray(4, 6, 26, 46, 66),
277                                      new ECBlocks(30, new ECB(3, 115),
278                                                   new ECB(1, 116)),
279                                      new ECBlocks(24, new ECB(4, 40),
280                                                   new ECB(5, 41)),
281                                      new ECBlocks(20, new ECB(11, 16),
282                                                   new ECB(5, 17)),
283                                      new ECBlocks(24, new ECB(11, 12),
284                                                   new ECB(5, 13))));
285       VERSIONS.push_back(new Version(15, intArray(4, 6, 26, 48, 70),
286                                      new ECBlocks(22, new ECB(5, 87),
287                                                   new ECB(1, 88)),
288                                      new ECBlocks(24, new ECB(5, 41),
289                                                   new ECB(5, 42)),
290                                      new ECBlocks(30, new ECB(5, 24),
291                                                   new ECB(7, 25)),
292                                      new ECBlocks(24, new ECB(11, 12),
293                                                   new ECB(7, 13))));
294       VERSIONS.push_back(new Version(16, intArray(4, 6, 26, 50, 74),
295                                      new ECBlocks(24, new ECB(5, 98),
296                                                   new ECB(1, 99)),
297                                      new ECBlocks(28, new ECB(7, 45),
298                                                   new ECB(3, 46)),
299                                      new ECBlocks(24, new ECB(15, 19),
300                                                   new ECB(2, 20)),
301                                      new ECBlocks(30, new ECB(3, 15),
302                                                   new ECB(13, 16))));
303       VERSIONS.push_back(new Version(17, intArray(4, 6, 30, 54, 78),
304                                      new ECBlocks(28, new ECB(1, 107),
305                                                   new ECB(5, 108)),
306                                      new ECBlocks(28, new ECB(10, 46),
307                                                   new ECB(1, 47)),
308                                      new ECBlocks(28, new ECB(1, 22),
309                                                   new ECB(15, 23)),
310                                      new ECBlocks(28, new ECB(2, 14),
311                                                   new ECB(17, 15))));
312       VERSIONS.push_back(new Version(18, intArray(4, 6, 30, 56, 82),
313                                      new ECBlocks(30, new ECB(5, 120),
314                                                   new ECB(1, 121)),
315                                      new ECBlocks(26, new ECB(9, 43),
316                                                   new ECB(4, 44)),
317                                      new ECBlocks(28, new ECB(17, 22),
318                                                   new ECB(1, 23)),
319                                      new ECBlocks(28, new ECB(2, 14),
320                                                   new ECB(19, 15))));
321       VERSIONS.push_back(new Version(19, intArray(4, 6, 30, 58, 86),
322                                      new ECBlocks(28, new ECB(3, 113),
323                                                   new ECB(4, 114)),
324                                      new ECBlocks(26, new ECB(3, 44),
325                                                   new ECB(11, 45)),
326                                      new ECBlocks(26, new ECB(17, 21),
327                                                   new ECB(4, 22)),
328                                      new ECBlocks(26, new ECB(9, 13),
329                                                   new ECB(16, 14))));
330       VERSIONS.push_back(new Version(20, intArray(4, 6, 34, 62, 90),
331                                      new ECBlocks(28, new ECB(3, 107),
332                                                   new ECB(5, 108)),
333                                      new ECBlocks(26, new ECB(3, 41),
334                                                   new ECB(13, 42)),
335                                      new ECBlocks(30, new ECB(15, 24),
336                                                   new ECB(5, 25)),
337                                      new ECBlocks(28, new ECB(15, 15),
338                                                   new ECB(10, 16))));
339       VERSIONS.push_back(new Version(21, intArray(5, 6, 28, 50, 72, 94),
340                                      new ECBlocks(28, new ECB(4, 116),
341                                                   new ECB(4, 117)),
342                                      new ECBlocks(26, new ECB(17, 42)),
343                                      new ECBlocks(28, new ECB(17, 22),
344                                                   new ECB(6, 23)),
345                                      new ECBlocks(30, new ECB(19, 16),
346                                                   new ECB(6, 17))));
347       VERSIONS.push_back(new Version(22, intArray(5, 6, 26, 50, 74, 98),
348                                      new ECBlocks(28, new ECB(2, 111),
349                                                   new ECB(7, 112)),
350                                      new ECBlocks(28, new ECB(17, 46)),
351                                      new ECBlocks(30, new ECB(7, 24),
352                                                   new ECB(16, 25)),
353                                      new ECBlocks(24, new ECB(34, 13))));
354       VERSIONS.push_back(new Version(23, intArray(5, 6, 30, 54, 74, 102),
355                                      new ECBlocks(30, new ECB(4, 121),
356                                                   new ECB(5, 122)),
357                                      new ECBlocks(28, new ECB(4, 47),
358                                                   new ECB(14, 48)),
359                                      new ECBlocks(30, new ECB(11, 24),
360                                                   new ECB(14, 25)),
361                                      new ECBlocks(30, new ECB(16, 15),
362                                                   new ECB(14, 16))));
363       VERSIONS.push_back(new Version(24, intArray(5, 6, 28, 54, 80, 106),
364                                      new ECBlocks(30, new ECB(6, 117),
365                                                   new ECB(4, 118)),
366                                      new ECBlocks(28, new ECB(6, 45),
367                                                   new ECB(14, 46)),
368                                      new ECBlocks(30, new ECB(11, 24),
369                                                   new ECB(16, 25)),
370                                      new ECBlocks(30, new ECB(30, 16),
371                                                   new ECB(2, 17))));
372       VERSIONS.push_back(new Version(25, intArray(5, 6, 32, 58, 84, 110),
373                                      new ECBlocks(26, new ECB(8, 106),
374                                                   new ECB(4, 107)),
375                                      new ECBlocks(28, new ECB(8, 47),
376                                                   new ECB(13, 48)),
377                                      new ECBlocks(30, new ECB(7, 24),
378                                                   new ECB(22, 25)),
379                                      new ECBlocks(30, new ECB(22, 15),
380                                                   new ECB(13, 16))));
381       VERSIONS.push_back(new Version(26, intArray(5, 6, 30, 58, 86, 114),
382                                      new ECBlocks(28, new ECB(10, 114),
383                                                   new ECB(2, 115)),
384                                      new ECBlocks(28, new ECB(19, 46),
385                                                   new ECB(4, 47)),
386                                      new ECBlocks(28, new ECB(28, 22),
387                                                   new ECB(6, 23)),
388                                      new ECBlocks(30, new ECB(33, 16),
389                                                   new ECB(4, 17))));
390       VERSIONS.push_back(new Version(27, intArray(5, 6, 34, 62, 90, 118),
391                                      new ECBlocks(30, new ECB(8, 122),
392                                                   new ECB(4, 123)),
393                                      new ECBlocks(28, new ECB(22, 45),
394                                                   new ECB(3, 46)),
395                                      new ECBlocks(30, new ECB(8, 23),
396                                                   new ECB(26, 24)),
397                                      new ECBlocks(30, new ECB(12, 15),
398                                                   new ECB(28, 16))));
399       VERSIONS.push_back(new Version(28, intArray(6, 6, 26, 50, 74, 98, 122),
400                                      new ECBlocks(30, new ECB(3, 117),
401                                                   new ECB(10, 118)),
402                                      new ECBlocks(28, new ECB(3, 45),
403                                                   new ECB(23, 46)),
404                                      new ECBlocks(30, new ECB(4, 24),
405                                                   new ECB(31, 25)),
406                                      new ECBlocks(30, new ECB(11, 15),
407                                                   new ECB(31, 16))));
408       VERSIONS.push_back(new Version(29, intArray(6, 6, 30, 54, 78, 102, 126),
409                                      new ECBlocks(30, new ECB(7, 116),
410                                                   new ECB(7, 117)),
411                                      new ECBlocks(28, new ECB(21, 45),
412                                                   new ECB(7, 46)),
413                                      new ECBlocks(30, new ECB(1, 23),
414                                                   new ECB(37, 24)),
415                                      new ECBlocks(30, new ECB(19, 15),
416                                                   new ECB(26, 16))));
417       VERSIONS.push_back(new Version(30, intArray(6, 6, 26, 52, 78, 104, 130),
418                                      new ECBlocks(30, new ECB(5, 115),
419                                                   new ECB(10, 116)),
420                                      new ECBlocks(28, new ECB(19, 47),
421                                                   new ECB(10, 48)),
422                                      new ECBlocks(30, new ECB(15, 24),
423                                                   new ECB(25, 25)),
424                                      new ECBlocks(30, new ECB(23, 15),
425                                                   new ECB(25, 16))));
426       VERSIONS.push_back(new Version(31, intArray(6, 6, 30, 56, 82, 108, 134),
427                                      new ECBlocks(30, new ECB(13, 115),
428                                                   new ECB(3, 116)),
429                                      new ECBlocks(28, new ECB(2, 46),
430                                                   new ECB(29, 47)),
431                                      new ECBlocks(30, new ECB(42, 24),
432                                                   new ECB(1, 25)),
433                                      new ECBlocks(30, new ECB(23, 15),
434                                                   new ECB(28, 16))));
435       VERSIONS.push_back(new Version(32, intArray(6, 6, 34, 60, 86, 112, 138),
436                                      new ECBlocks(30, new ECB(17, 115)),
437                                      new ECBlocks(28, new ECB(10, 46),
438                                                   new ECB(23, 47)),
439                                      new ECBlocks(30, new ECB(10, 24),
440                                                   new ECB(35, 25)),
441                                      new ECBlocks(30, new ECB(19, 15),
442                                                   new ECB(35, 16))));
443       VERSIONS.push_back(new Version(33, intArray(6, 6, 30, 58, 86, 114, 142),
444                                      new ECBlocks(30, new ECB(17, 115),
445                                                   new ECB(1, 116)),
446                                      new ECBlocks(28, new ECB(14, 46),
447                                                   new ECB(21, 47)),
448                                      new ECBlocks(30, new ECB(29, 24),
449                                                   new ECB(19, 25)),
450                                      new ECBlocks(30, new ECB(11, 15),
451                                                   new ECB(46, 16))));
452       VERSIONS.push_back(new Version(34, intArray(6, 6, 34, 62, 90, 118, 146),
453                                      new ECBlocks(30, new ECB(13, 115),
454                                                   new ECB(6, 116)),
455                                      new ECBlocks(28, new ECB(14, 46),
456                                                   new ECB(23, 47)),
457                                      new ECBlocks(30, new ECB(44, 24),
458                                                   new ECB(7, 25)),
459                                      new ECBlocks(30, new ECB(59, 16),
460                                                   new ECB(1, 17))));
461       VERSIONS.push_back(new Version(35, intArray(7, 6, 30, 54, 78, 
462                                                   102, 126, 150),
463                                      new ECBlocks(30, new ECB(12, 121),
464                                                   new ECB(7, 122)),
465                                      new ECBlocks(28, new ECB(12, 47),
466                                                   new ECB(26, 48)),
467                                      new ECBlocks(30, new ECB(39, 24),
468                                                   new ECB(14, 25)),
469                                      new ECBlocks(30, new ECB(22, 15),
470                                                   new ECB(41, 16))));
471       VERSIONS.push_back(new Version(36, intArray(7, 6, 24, 50, 76,
472                                                   102, 128, 154),
473                                      new ECBlocks(30, new ECB(6, 121),
474                                                   new ECB(14, 122)),
475                                      new ECBlocks(28, new ECB(6, 47),
476                                                   new ECB(34, 48)),
477                                      new ECBlocks(30, new ECB(46, 24),
478                                                   new ECB(10, 25)),
479                                      new ECBlocks(30, new ECB(2, 15),
480                                                   new ECB(64, 16))));
481       VERSIONS.push_back(new Version(37, intArray(7, 6, 28, 54, 80, 
482                                                   106, 132, 158),
483                                      new ECBlocks(30, new ECB(17, 122),
484                                                   new ECB(4, 123)),
485                                      new ECBlocks(28, new ECB(29, 46),
486                                                   new ECB(14, 47)),
487                                      new ECBlocks(30, new ECB(49, 24),
488                                                   new ECB(10, 25)),
489                                      new ECBlocks(30, new ECB(24, 15),
490                                                   new ECB(46, 16))));
491       VERSIONS.push_back(new Version(38, intArray(7, 6, 32, 58, 84, 
492                                                   110, 136, 162),
493                                      new ECBlocks(30, new ECB(4, 122),
494                                                   new ECB(18, 123)),
495                                      new ECBlocks(28, new ECB(13, 46),
496                                                   new ECB(32, 47)),
497                                      new ECBlocks(30, new ECB(48, 24),
498                                                   new ECB(14, 25)),
499                                      new ECBlocks(30, new ECB(42, 15),
500                                                   new ECB(32, 16))));
501       VERSIONS.push_back(new Version(39, intArray(7, 6, 26, 54, 82, 
502                                                   110, 138, 166),
503                                      new ECBlocks(30, new ECB(20, 117),
504                                                   new ECB(4, 118)),
505                                      new ECBlocks(28, new ECB(40, 47),
506                                                   new ECB(7, 48)),
507                                      new ECBlocks(30, new ECB(43, 24),
508                                                   new ECB(22, 25)),
509                                      new ECBlocks(30, new ECB(10, 15),
510                                                   new ECB(67, 16))));
511       VERSIONS.push_back(new Version(40, intArray(7, 6, 30, 58, 86, 
512                                                   114, 142, 170),
513                                      new ECBlocks(30, new ECB(19, 118),
514                                                   new ECB(6, 119)),
515                                      new ECBlocks(28, new ECB(18, 47),
516                                                   new ECB(31, 48)),
517                                      new ECBlocks(30, new ECB(34, 24),
518                                                   new ECB(34, 25)),
519                                      new ECBlocks(30, new ECB(20, 15),
520                                                   new ECB(61, 16))));
521       return VERSIONS.size();
522     }
523   }  
524 }