Home | History | Annotate | Download | only in qrcode
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 // Original code is licensed as follows:
      7 /*
      8  * Copyright 2007 ZXing authors
      9  *
     10  * Licensed under the Apache License, Version 2.0 (the "License");
     11  * you may not use this file except in compliance with the License.
     12  * You may obtain a copy of the License at
     13  *
     14  *      http://www.apache.org/licenses/LICENSE-2.0
     15  *
     16  * Unless required by applicable law or agreed to in writing, software
     17  * distributed under the License is distributed on an "AS IS" BASIS,
     18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     19  * See the License for the specific language governing permissions and
     20  * limitations under the License.
     21  */
     22 
     23 #include "xfa/fxbarcode/common/BC_CommonBitMatrix.h"
     24 #include "xfa/fxbarcode/qrcode/BC_QRCoderBitVector.h"
     25 #include "xfa/fxbarcode/qrcode/BC_QRCoderECB.h"
     26 #include "xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.h"
     27 #include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
     28 #include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h"
     29 #include "xfa/fxbarcode/utils.h"
     30 
     31 namespace {
     32 
     33 const uint8_t BITS_SET_IN_HALF_BYTE[] = {0, 1, 1, 2, 1, 2, 2, 3,
     34                                          1, 2, 2, 3, 2, 3, 3, 4};
     35 
     36 int32_t NumBitsDiffering(int32_t a, int32_t b) {
     37   a ^= b;
     38   return BITS_SET_IN_HALF_BYTE[a & 0x0F] +
     39          BITS_SET_IN_HALF_BYTE[(a >> 4) & 0x0F] +
     40          BITS_SET_IN_HALF_BYTE[(a >> 8) & 0x0F] +
     41          BITS_SET_IN_HALF_BYTE[(a >> 12) & 0x0F] +
     42          BITS_SET_IN_HALF_BYTE[(a >> 16) & 0x0F] +
     43          BITS_SET_IN_HALF_BYTE[(a >> 20) & 0x0F] +
     44          BITS_SET_IN_HALF_BYTE[(a >> 24) & 0x0F] +
     45          BITS_SET_IN_HALF_BYTE[(a >> 28) & 0x0F];
     46 }
     47 
     48 }  // namespace
     49 
     50 const int32_t CBC_QRCoderVersion::VERSION_DECODE_INFO[] = {
     51     0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6, 0x0C762, 0x0D847,
     52     0x0E60D, 0x0F928, 0x10B78, 0x1145D, 0x12A17, 0x13532, 0x149A6,
     53     0x15683, 0x168C9, 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB, 0x1B08E,
     54     0x1CC1A, 0x1D33F, 0x1ED75, 0x1F250, 0x209D5, 0x216F0, 0x228BA,
     55     0x2379F, 0x24B0B, 0x2542E, 0x26A64, 0x27541, 0x28C69};
     56 
     57 CFX_ArrayTemplate<CBC_QRCoderVersion*>* CBC_QRCoderVersion::VERSION = nullptr;
     58 
     59 void CBC_QRCoderVersion::Initialize() {
     60   VERSION = new CFX_ArrayTemplate<CBC_QRCoderVersion*>();
     61 }
     62 void CBC_QRCoderVersion::Finalize() {
     63   for (int32_t i = 0; i < VERSION->GetSize(); i++)
     64     delete VERSION->GetAt(i);
     65 
     66   delete VERSION;
     67   VERSION = nullptr;
     68 }
     69 CBC_QRCoderVersion::CBC_QRCoderVersion(int32_t versionNumber,
     70                                        CBC_QRCoderECBlocks* ecBlocks1,
     71                                        CBC_QRCoderECBlocks* ecBlocks2,
     72                                        CBC_QRCoderECBlocks* ecBlocks3,
     73                                        CBC_QRCoderECBlocks* ecBlocks4) {
     74   m_versionNumber = versionNumber;
     75   m_ecBlocksArray.Add(ecBlocks1);
     76   m_ecBlocksArray.Add(ecBlocks2);
     77   m_ecBlocksArray.Add(ecBlocks3);
     78   m_ecBlocksArray.Add(ecBlocks4);
     79   int32_t total = 0;
     80   int32_t ecCodeWords = ecBlocks1->GetECCodeWordsPerBlock();
     81   CFX_ArrayTemplate<CBC_QRCoderECB*>* ecbArray = ecBlocks1->GetECBlocks();
     82   for (int32_t i = 0; i < ecbArray->GetSize(); i++) {
     83     CBC_QRCoderECB* ecBlock = (*ecbArray)[i];
     84     total += ecBlock->GetCount() * (ecBlock->GetDataCodeWords() + ecCodeWords);
     85   }
     86   m_totalCodeWords = total;
     87   switch (versionNumber) {
     88     case 1:
     89       break;
     90     case 2:
     91       m_alignmentPatternCenters.Add(6);
     92       m_alignmentPatternCenters.Add(18);
     93       break;
     94     case 3:
     95       m_alignmentPatternCenters.Add(6);
     96       m_alignmentPatternCenters.Add(22);
     97       break;
     98     case 4:
     99       m_alignmentPatternCenters.Add(6);
    100       m_alignmentPatternCenters.Add(26);
    101       break;
    102     case 5:
    103       m_alignmentPatternCenters.Add(6);
    104       m_alignmentPatternCenters.Add(30);
    105       break;
    106     case 6:
    107       m_alignmentPatternCenters.Add(6);
    108       m_alignmentPatternCenters.Add(34);
    109       break;
    110     case 7:
    111       m_alignmentPatternCenters.Add(6);
    112       m_alignmentPatternCenters.Add(22);
    113       m_alignmentPatternCenters.Add(38);
    114       break;
    115     case 8:
    116       m_alignmentPatternCenters.Add(6);
    117       m_alignmentPatternCenters.Add(24);
    118       m_alignmentPatternCenters.Add(42);
    119       break;
    120     case 9:
    121       m_alignmentPatternCenters.Add(6);
    122       m_alignmentPatternCenters.Add(26);
    123       m_alignmentPatternCenters.Add(46);
    124       break;
    125     case 10:
    126       m_alignmentPatternCenters.Add(6);
    127       m_alignmentPatternCenters.Add(28);
    128       m_alignmentPatternCenters.Add(50);
    129       break;
    130     case 11:
    131       m_alignmentPatternCenters.Add(6);
    132       m_alignmentPatternCenters.Add(30);
    133       m_alignmentPatternCenters.Add(54);
    134       break;
    135     case 12:
    136       m_alignmentPatternCenters.Add(6);
    137       m_alignmentPatternCenters.Add(32);
    138       m_alignmentPatternCenters.Add(58);
    139       break;
    140     case 13:
    141       m_alignmentPatternCenters.Add(6);
    142       m_alignmentPatternCenters.Add(34);
    143       m_alignmentPatternCenters.Add(62);
    144       break;
    145     case 14:
    146       m_alignmentPatternCenters.Add(6);
    147       m_alignmentPatternCenters.Add(26);
    148       m_alignmentPatternCenters.Add(46);
    149       m_alignmentPatternCenters.Add(66);
    150       break;
    151     case 15:
    152       m_alignmentPatternCenters.Add(6);
    153       m_alignmentPatternCenters.Add(26);
    154       m_alignmentPatternCenters.Add(48);
    155       m_alignmentPatternCenters.Add(70);
    156       break;
    157     case 16:
    158       m_alignmentPatternCenters.Add(6);
    159       m_alignmentPatternCenters.Add(26);
    160       m_alignmentPatternCenters.Add(50);
    161       m_alignmentPatternCenters.Add(74);
    162       break;
    163     case 17:
    164       m_alignmentPatternCenters.Add(6);
    165       m_alignmentPatternCenters.Add(30);
    166       m_alignmentPatternCenters.Add(54);
    167       m_alignmentPatternCenters.Add(78);
    168       break;
    169     case 18:
    170       m_alignmentPatternCenters.Add(6);
    171       m_alignmentPatternCenters.Add(30);
    172       m_alignmentPatternCenters.Add(56);
    173       m_alignmentPatternCenters.Add(82);
    174       break;
    175     case 19:
    176       m_alignmentPatternCenters.Add(6);
    177       m_alignmentPatternCenters.Add(30);
    178       m_alignmentPatternCenters.Add(58);
    179       m_alignmentPatternCenters.Add(86);
    180       break;
    181     case 20:
    182       m_alignmentPatternCenters.Add(6);
    183       m_alignmentPatternCenters.Add(34);
    184       m_alignmentPatternCenters.Add(62);
    185       m_alignmentPatternCenters.Add(90);
    186       break;
    187     case 21:
    188       m_alignmentPatternCenters.Add(6);
    189       m_alignmentPatternCenters.Add(28);
    190       m_alignmentPatternCenters.Add(50);
    191       m_alignmentPatternCenters.Add(72);
    192       m_alignmentPatternCenters.Add(94);
    193       break;
    194     case 22:
    195       m_alignmentPatternCenters.Add(6);
    196       m_alignmentPatternCenters.Add(26);
    197       m_alignmentPatternCenters.Add(50);
    198       m_alignmentPatternCenters.Add(74);
    199       m_alignmentPatternCenters.Add(98);
    200       break;
    201     case 23:
    202       m_alignmentPatternCenters.Add(6);
    203       m_alignmentPatternCenters.Add(30);
    204       m_alignmentPatternCenters.Add(54);
    205       m_alignmentPatternCenters.Add(74);
    206       m_alignmentPatternCenters.Add(102);
    207       break;
    208     case 24:
    209       m_alignmentPatternCenters.Add(6);
    210       m_alignmentPatternCenters.Add(28);
    211       m_alignmentPatternCenters.Add(54);
    212       m_alignmentPatternCenters.Add(80);
    213       m_alignmentPatternCenters.Add(106);
    214       break;
    215     case 25:
    216       m_alignmentPatternCenters.Add(6);
    217       m_alignmentPatternCenters.Add(32);
    218       m_alignmentPatternCenters.Add(58);
    219       m_alignmentPatternCenters.Add(84);
    220       m_alignmentPatternCenters.Add(110);
    221       break;
    222     case 26:
    223       m_alignmentPatternCenters.Add(6);
    224       m_alignmentPatternCenters.Add(30);
    225       m_alignmentPatternCenters.Add(58);
    226       m_alignmentPatternCenters.Add(86);
    227       m_alignmentPatternCenters.Add(114);
    228       break;
    229     case 27:
    230       m_alignmentPatternCenters.Add(6);
    231       m_alignmentPatternCenters.Add(34);
    232       m_alignmentPatternCenters.Add(62);
    233       m_alignmentPatternCenters.Add(90);
    234       m_alignmentPatternCenters.Add(118);
    235       break;
    236     case 28:
    237       m_alignmentPatternCenters.Add(6);
    238       m_alignmentPatternCenters.Add(26);
    239       m_alignmentPatternCenters.Add(50);
    240       m_alignmentPatternCenters.Add(74);
    241       m_alignmentPatternCenters.Add(98);
    242       m_alignmentPatternCenters.Add(122);
    243       break;
    244     case 29:
    245       m_alignmentPatternCenters.Add(6);
    246       m_alignmentPatternCenters.Add(30);
    247       m_alignmentPatternCenters.Add(54);
    248       m_alignmentPatternCenters.Add(78);
    249       m_alignmentPatternCenters.Add(102);
    250       m_alignmentPatternCenters.Add(126);
    251       break;
    252     case 30:
    253       m_alignmentPatternCenters.Add(6);
    254       m_alignmentPatternCenters.Add(26);
    255       m_alignmentPatternCenters.Add(52);
    256       m_alignmentPatternCenters.Add(78);
    257       m_alignmentPatternCenters.Add(104);
    258       m_alignmentPatternCenters.Add(130);
    259       break;
    260     case 31:
    261       m_alignmentPatternCenters.Add(6);
    262       m_alignmentPatternCenters.Add(30);
    263       m_alignmentPatternCenters.Add(56);
    264       m_alignmentPatternCenters.Add(82);
    265       m_alignmentPatternCenters.Add(108);
    266       m_alignmentPatternCenters.Add(134);
    267       break;
    268     case 32:
    269       m_alignmentPatternCenters.Add(6);
    270       m_alignmentPatternCenters.Add(34);
    271       m_alignmentPatternCenters.Add(60);
    272       m_alignmentPatternCenters.Add(86);
    273       m_alignmentPatternCenters.Add(112);
    274       m_alignmentPatternCenters.Add(138);
    275       break;
    276     case 33:
    277       m_alignmentPatternCenters.Add(6);
    278       m_alignmentPatternCenters.Add(30);
    279       m_alignmentPatternCenters.Add(58);
    280       m_alignmentPatternCenters.Add(86);
    281       m_alignmentPatternCenters.Add(114);
    282       m_alignmentPatternCenters.Add(142);
    283       break;
    284     case 34:
    285       m_alignmentPatternCenters.Add(6);
    286       m_alignmentPatternCenters.Add(34);
    287       m_alignmentPatternCenters.Add(62);
    288       m_alignmentPatternCenters.Add(90);
    289       m_alignmentPatternCenters.Add(118);
    290       m_alignmentPatternCenters.Add(146);
    291       break;
    292     case 35:
    293       m_alignmentPatternCenters.Add(6);
    294       m_alignmentPatternCenters.Add(30);
    295       m_alignmentPatternCenters.Add(54);
    296       m_alignmentPatternCenters.Add(78);
    297       m_alignmentPatternCenters.Add(102);
    298       m_alignmentPatternCenters.Add(126);
    299       m_alignmentPatternCenters.Add(150);
    300       break;
    301     case 36:
    302       m_alignmentPatternCenters.Add(6);
    303       m_alignmentPatternCenters.Add(24);
    304       m_alignmentPatternCenters.Add(50);
    305       m_alignmentPatternCenters.Add(76);
    306       m_alignmentPatternCenters.Add(102);
    307       m_alignmentPatternCenters.Add(128);
    308       m_alignmentPatternCenters.Add(154);
    309       break;
    310     case 37:
    311       m_alignmentPatternCenters.Add(6);
    312       m_alignmentPatternCenters.Add(28);
    313       m_alignmentPatternCenters.Add(54);
    314       m_alignmentPatternCenters.Add(80);
    315       m_alignmentPatternCenters.Add(106);
    316       m_alignmentPatternCenters.Add(132);
    317       m_alignmentPatternCenters.Add(158);
    318       break;
    319     case 38:
    320       m_alignmentPatternCenters.Add(6);
    321       m_alignmentPatternCenters.Add(32);
    322       m_alignmentPatternCenters.Add(58);
    323       m_alignmentPatternCenters.Add(84);
    324       m_alignmentPatternCenters.Add(110);
    325       m_alignmentPatternCenters.Add(136);
    326       m_alignmentPatternCenters.Add(162);
    327       break;
    328     case 39:
    329       m_alignmentPatternCenters.Add(6);
    330       m_alignmentPatternCenters.Add(26);
    331       m_alignmentPatternCenters.Add(54);
    332       m_alignmentPatternCenters.Add(82);
    333       m_alignmentPatternCenters.Add(110);
    334       m_alignmentPatternCenters.Add(138);
    335       m_alignmentPatternCenters.Add(166);
    336       break;
    337     case 40:
    338       m_alignmentPatternCenters.Add(6);
    339       m_alignmentPatternCenters.Add(30);
    340       m_alignmentPatternCenters.Add(58);
    341       m_alignmentPatternCenters.Add(86);
    342       m_alignmentPatternCenters.Add(114);
    343       m_alignmentPatternCenters.Add(142);
    344       m_alignmentPatternCenters.Add(170);
    345       break;
    346   }
    347 }
    348 
    349 CBC_QRCoderVersion::~CBC_QRCoderVersion() {
    350   for (int32_t i = 0; i < m_ecBlocksArray.GetSize(); ++i)
    351     delete m_ecBlocksArray[i];
    352 }
    353 
    354 int32_t CBC_QRCoderVersion::GetVersionNumber() {
    355   return m_versionNumber;
    356 }
    357 CFX_ArrayTemplate<int32_t>* CBC_QRCoderVersion::GetAlignmentPatternCenters() {
    358   return &m_alignmentPatternCenters;
    359 }
    360 int32_t CBC_QRCoderVersion::GetTotalCodeWords() {
    361   return m_totalCodeWords;
    362 }
    363 int32_t CBC_QRCoderVersion::GetDimensionForVersion() {
    364   return 17 + 4 * m_versionNumber;
    365 }
    366 CBC_QRCoderECBlocks* CBC_QRCoderVersion::GetECBlocksForLevel(
    367     CBC_QRCoderErrorCorrectionLevel* ecLevel) {
    368   return m_ecBlocksArray[ecLevel->Ordinal()];
    369 }
    370 CBC_QRCoderVersion* CBC_QRCoderVersion::GetProvisionalVersionForDimension(
    371     int32_t dimension,
    372     int32_t& e) {
    373   if ((dimension % 4) != 1) {
    374     e = BCExceptionRead;
    375     return nullptr;
    376   }
    377   CBC_QRCoderVersion* qcv = GetVersionForNumber((dimension - 17) >> 2, e);
    378   if (e != BCExceptionNO)
    379     return nullptr;
    380   return qcv;
    381 }
    382 CBC_QRCoderVersion* CBC_QRCoderVersion::DecodeVersionInformation(
    383     int32_t versionBits,
    384     int32_t& e) {
    385   int32_t bestDifference = FXSYS_IntMax;
    386   int32_t bestVersion = 0;
    387   for (int32_t i = 0; i < 34; i++) {
    388     int32_t targetVersion = VERSION_DECODE_INFO[i];
    389     if (targetVersion == versionBits) {
    390       CBC_QRCoderVersion* qcv = GetVersionForNumber(i + 7, e);
    391       if (e != BCExceptionNO)
    392         return nullptr;
    393       return qcv;
    394     }
    395     int32_t bitsDifference = NumBitsDiffering(versionBits, targetVersion);
    396     if (bitsDifference < bestDifference) {
    397       bestVersion = i + 7;
    398       bestDifference = bitsDifference;
    399     }
    400   }
    401   if (bestDifference <= 3) {
    402     CBC_QRCoderVersion* qcv = GetVersionForNumber(bestVersion, e);
    403     if (e != BCExceptionNO)
    404       return nullptr;
    405     return qcv;
    406   }
    407   return nullptr;
    408 }
    409 CBC_CommonBitMatrix* CBC_QRCoderVersion::BuildFunctionPattern(int32_t& e) {
    410   int32_t dimension = GetDimensionForVersion();
    411   CBC_CommonBitMatrix* bitMatrix = new CBC_CommonBitMatrix();
    412   bitMatrix->Init(dimension);
    413   bitMatrix->SetRegion(0, 0, 9, 9, e);
    414   if (e != BCExceptionNO)
    415     return nullptr;
    416   bitMatrix->SetRegion(dimension - 8, 0, 8, 9, e);
    417   if (e != BCExceptionNO)
    418     return nullptr;
    419   bitMatrix->SetRegion(0, dimension - 8, 9, 8, e);
    420   if (e != BCExceptionNO)
    421     return nullptr;
    422   int32_t max = m_alignmentPatternCenters.GetSize();
    423   for (int32_t x = 0; x < max; x++) {
    424     int32_t i = m_alignmentPatternCenters[x] - 2;
    425     for (int32_t y = 0; y < max; y++) {
    426       if ((x == 0 && (y == 0 || y == max - 1)) || (x == max - 1 && y == 0)) {
    427         continue;
    428       }
    429       bitMatrix->SetRegion(m_alignmentPatternCenters[y] - 2, i, 5, 5, e);
    430       if (e != BCExceptionNO)
    431         return nullptr;
    432     }
    433   }
    434   bitMatrix->SetRegion(6, 9, 1, dimension - 17, e);
    435   if (e != BCExceptionNO)
    436     return nullptr;
    437   bitMatrix->SetRegion(9, 6, dimension - 17, 1, e);
    438   if (e != BCExceptionNO)
    439     return nullptr;
    440   if (m_versionNumber > 6) {
    441     bitMatrix->SetRegion(dimension - 11, 0, 3, 6, e);
    442     if (e != BCExceptionNO)
    443       return nullptr;
    444     bitMatrix->SetRegion(0, dimension - 11, 6, 3, e);
    445     if (e != BCExceptionNO)
    446       return nullptr;
    447   }
    448   return bitMatrix;
    449 }
    450 CBC_QRCoderVersion* CBC_QRCoderVersion::GetVersionForNumber(
    451     int32_t versionNumber,
    452     int32_t& e) {
    453   if (VERSION->GetSize() == 0) {
    454     VERSION->Add(new CBC_QRCoderVersion(
    455         1, new CBC_QRCoderECBlocks(7, new CBC_QRCoderECB(1, 19)),
    456         new CBC_QRCoderECBlocks(10, new CBC_QRCoderECB(1, 16)),
    457         new CBC_QRCoderECBlocks(13, new CBC_QRCoderECB(1, 13)),
    458         new CBC_QRCoderECBlocks(17, new CBC_QRCoderECB(1, 9))));
    459     VERSION->Add(new CBC_QRCoderVersion(
    460         2, new CBC_QRCoderECBlocks(10, new CBC_QRCoderECB(1, 34)),
    461         new CBC_QRCoderECBlocks(16, new CBC_QRCoderECB(1, 28)),
    462         new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(1, 22)),
    463         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(1, 16))));
    464     VERSION->Add(new CBC_QRCoderVersion(
    465         3, new CBC_QRCoderECBlocks(15, new CBC_QRCoderECB(1, 55)),
    466         new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(1, 44)),
    467         new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 17)),
    468         new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(2, 13))));
    469     VERSION->Add(new CBC_QRCoderVersion(
    470         4, new CBC_QRCoderECBlocks(20, new CBC_QRCoderECB(1, 80)),
    471         new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 32)),
    472         new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(2, 24)),
    473         new CBC_QRCoderECBlocks(16, new CBC_QRCoderECB(4, 9))));
    474     VERSION->Add(new CBC_QRCoderVersion(
    475         5, new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(1, 108)),
    476         new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(2, 43)),
    477         new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 15),
    478                                 new CBC_QRCoderECB(2, 16)),
    479         new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(2, 11),
    480                                 new CBC_QRCoderECB(2, 12))));
    481     VERSION->Add(new CBC_QRCoderVersion(
    482         6, new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 68)),
    483         new CBC_QRCoderECBlocks(16, new CBC_QRCoderECB(4, 27)),
    484         new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(4, 19)),
    485         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(4, 15))));
    486     VERSION->Add(new CBC_QRCoderVersion(
    487         7, new CBC_QRCoderECBlocks(20, new CBC_QRCoderECB(2, 78)),
    488         new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(4, 31)),
    489         new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 14),
    490                                 new CBC_QRCoderECB(4, 15)),
    491         new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(4, 13),
    492                                 new CBC_QRCoderECB(1, 14))));
    493     VERSION->Add(new CBC_QRCoderVersion(
    494         8, new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(2, 97)),
    495         new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(2, 38),
    496                                 new CBC_QRCoderECB(2, 39)),
    497         new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(4, 18),
    498                                 new CBC_QRCoderECB(2, 19)),
    499         new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(4, 14),
    500                                 new CBC_QRCoderECB(2, 15))));
    501     VERSION->Add(new CBC_QRCoderVersion(
    502         9, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(2, 116)),
    503         new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(3, 36),
    504                                 new CBC_QRCoderECB(2, 37)),
    505         new CBC_QRCoderECBlocks(20, new CBC_QRCoderECB(4, 16),
    506                                 new CBC_QRCoderECB(4, 17)),
    507         new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(4, 12),
    508                                 new CBC_QRCoderECB(4, 13))));
    509     VERSION->Add(new CBC_QRCoderVersion(
    510         10, new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 68),
    511                                     new CBC_QRCoderECB(2, 69)),
    512         new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(4, 43),
    513                                 new CBC_QRCoderECB(1, 44)),
    514         new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(6, 19),
    515                                 new CBC_QRCoderECB(2, 20)),
    516         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(6, 15),
    517                                 new CBC_QRCoderECB(2, 16))));
    518     VERSION->Add(new CBC_QRCoderVersion(
    519         11, new CBC_QRCoderECBlocks(20, new CBC_QRCoderECB(4, 81)),
    520         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(1, 50),
    521                                 new CBC_QRCoderECB(4, 51)),
    522         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(4, 22),
    523                                 new CBC_QRCoderECB(4, 23)),
    524         new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(3, 12),
    525                                 new CBC_QRCoderECB(8, 13))));
    526     VERSION->Add(new CBC_QRCoderVersion(
    527         12, new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(2, 92),
    528                                     new CBC_QRCoderECB(2, 93)),
    529         new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(6, 36),
    530                                 new CBC_QRCoderECB(2, 37)),
    531         new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(4, 20),
    532                                 new CBC_QRCoderECB(6, 21)),
    533         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(7, 14),
    534                                 new CBC_QRCoderECB(4, 15))));
    535     VERSION->Add(new CBC_QRCoderVersion(
    536         13, new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(4, 107)),
    537         new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(8, 37),
    538                                 new CBC_QRCoderECB(1, 38)),
    539         new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(8, 20),
    540                                 new CBC_QRCoderECB(4, 21)),
    541         new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(12, 11),
    542                                 new CBC_QRCoderECB(4, 12))));
    543     VERSION->Add(new CBC_QRCoderVersion(
    544         14, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(3, 115),
    545                                     new CBC_QRCoderECB(1, 116)),
    546         new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(4, 40),
    547                                 new CBC_QRCoderECB(5, 41)),
    548         new CBC_QRCoderECBlocks(20, new CBC_QRCoderECB(11, 16),
    549                                 new CBC_QRCoderECB(5, 17)),
    550         new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(11, 12),
    551                                 new CBC_QRCoderECB(5, 13))));
    552     VERSION->Add(new CBC_QRCoderVersion(
    553         15, new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(5, 87),
    554                                     new CBC_QRCoderECB(1, 88)),
    555         new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(5, 41),
    556                                 new CBC_QRCoderECB(5, 42)),
    557         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(5, 24),
    558                                 new CBC_QRCoderECB(7, 25)),
    559         new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(11, 12),
    560                                 new CBC_QRCoderECB(7, 13))));
    561     VERSION->Add(new CBC_QRCoderVersion(
    562         16, new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(5, 98),
    563                                     new CBC_QRCoderECB(1, 99)),
    564         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(7, 45),
    565                                 new CBC_QRCoderECB(3, 46)),
    566         new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(15, 19),
    567                                 new CBC_QRCoderECB(2, 20)),
    568         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(3, 15),
    569                                 new CBC_QRCoderECB(13, 16))));
    570     VERSION->Add(new CBC_QRCoderVersion(
    571         17, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(1, 107),
    572                                     new CBC_QRCoderECB(5, 108)),
    573         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(10, 46),
    574                                 new CBC_QRCoderECB(1, 47)),
    575         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(1, 22),
    576                                 new CBC_QRCoderECB(15, 23)),
    577         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(2, 14),
    578                                 new CBC_QRCoderECB(17, 15))));
    579     VERSION->Add(new CBC_QRCoderVersion(
    580         18, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(5, 120),
    581                                     new CBC_QRCoderECB(1, 121)),
    582         new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(9, 43),
    583                                 new CBC_QRCoderECB(4, 44)),
    584         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(17, 22),
    585                                 new CBC_QRCoderECB(1, 23)),
    586         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(2, 14),
    587                                 new CBC_QRCoderECB(19, 15))));
    588     VERSION->Add(new CBC_QRCoderVersion(
    589         19, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(3, 113),
    590                                     new CBC_QRCoderECB(4, 114)),
    591         new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(3, 44),
    592                                 new CBC_QRCoderECB(11, 45)),
    593         new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(17, 21),
    594                                 new CBC_QRCoderECB(4, 22)),
    595         new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(9, 13),
    596                                 new CBC_QRCoderECB(16, 14))));
    597     VERSION->Add(new CBC_QRCoderVersion(
    598         20, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(3, 107),
    599                                     new CBC_QRCoderECB(5, 108)),
    600         new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(3, 41),
    601                                 new CBC_QRCoderECB(13, 42)),
    602         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(15, 24),
    603                                 new CBC_QRCoderECB(5, 25)),
    604         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(15, 15),
    605                                 new CBC_QRCoderECB(10, 16))));
    606     VERSION->Add(new CBC_QRCoderVersion(
    607         21, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(4, 116),
    608                                     new CBC_QRCoderECB(4, 117)),
    609         new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(17, 42)),
    610         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(17, 22),
    611                                 new CBC_QRCoderECB(6, 23)),
    612         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(19, 16),
    613                                 new CBC_QRCoderECB(6, 17))));
    614     VERSION->Add(new CBC_QRCoderVersion(
    615         22, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(2, 111),
    616                                     new CBC_QRCoderECB(7, 112)),
    617         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(17, 46)),
    618         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(7, 24),
    619                                 new CBC_QRCoderECB(16, 25)),
    620         new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(34, 13))));
    621     VERSION->Add(new CBC_QRCoderVersion(
    622         23, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(4, 121),
    623                                     new CBC_QRCoderECB(5, 122)),
    624         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(4, 47),
    625                                 new CBC_QRCoderECB(14, 48)),
    626         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(11, 24),
    627                                 new CBC_QRCoderECB(14, 25)),
    628         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(16, 15),
    629                                 new CBC_QRCoderECB(14, 16))));
    630     VERSION->Add(new CBC_QRCoderVersion(
    631         24, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(6, 117),
    632                                     new CBC_QRCoderECB(4, 118)),
    633         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(6, 45),
    634                                 new CBC_QRCoderECB(14, 46)),
    635         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(11, 24),
    636                                 new CBC_QRCoderECB(16, 25)),
    637         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(30, 16),
    638                                 new CBC_QRCoderECB(2, 17))));
    639     VERSION->Add(new CBC_QRCoderVersion(
    640         25, new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(8, 106),
    641                                     new CBC_QRCoderECB(4, 107)),
    642         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(8, 47),
    643                                 new CBC_QRCoderECB(13, 48)),
    644         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(7, 24),
    645                                 new CBC_QRCoderECB(22, 25)),
    646         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(22, 15),
    647                                 new CBC_QRCoderECB(13, 16))));
    648     VERSION->Add(new CBC_QRCoderVersion(
    649         26, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(10, 114),
    650                                     new CBC_QRCoderECB(2, 115)),
    651         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(19, 46),
    652                                 new CBC_QRCoderECB(4, 47)),
    653         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(28, 22),
    654                                 new CBC_QRCoderECB(6, 23)),
    655         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(33, 16),
    656                                 new CBC_QRCoderECB(4, 17))));
    657     VERSION->Add(new CBC_QRCoderVersion(
    658         27, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(8, 122),
    659                                     new CBC_QRCoderECB(4, 123)),
    660         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(22, 45),
    661                                 new CBC_QRCoderECB(3, 46)),
    662         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(8, 23),
    663                                 new CBC_QRCoderECB(26, 24)),
    664         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(12, 15),
    665                                 new CBC_QRCoderECB(28, 16))));
    666     VERSION->Add(new CBC_QRCoderVersion(
    667         28, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(3, 117),
    668                                     new CBC_QRCoderECB(10, 118)),
    669         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(3, 45),
    670                                 new CBC_QRCoderECB(23, 46)),
    671         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(4, 24),
    672                                 new CBC_QRCoderECB(31, 25)),
    673         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(11, 15),
    674                                 new CBC_QRCoderECB(31, 16))));
    675     VERSION->Add(new CBC_QRCoderVersion(
    676         29, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(7, 116),
    677                                     new CBC_QRCoderECB(7, 117)),
    678         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(21, 45),
    679                                 new CBC_QRCoderECB(7, 46)),
    680         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(1, 23),
    681                                 new CBC_QRCoderECB(37, 24)),
    682         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(19, 15),
    683                                 new CBC_QRCoderECB(26, 16))));
    684     VERSION->Add(new CBC_QRCoderVersion(
    685         30, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(5, 115),
    686                                     new CBC_QRCoderECB(10, 116)),
    687         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(19, 47),
    688                                 new CBC_QRCoderECB(10, 48)),
    689         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(15, 24),
    690                                 new CBC_QRCoderECB(25, 25)),
    691         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(23, 15),
    692                                 new CBC_QRCoderECB(25, 16))));
    693     VERSION->Add(new CBC_QRCoderVersion(
    694         31, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(13, 115),
    695                                     new CBC_QRCoderECB(3, 116)),
    696         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(2, 46),
    697                                 new CBC_QRCoderECB(29, 47)),
    698         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(42, 24),
    699                                 new CBC_QRCoderECB(1, 25)),
    700         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(23, 15),
    701                                 new CBC_QRCoderECB(28, 16))));
    702     VERSION->Add(new CBC_QRCoderVersion(
    703         32, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(17, 115)),
    704         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(10, 46),
    705                                 new CBC_QRCoderECB(23, 47)),
    706         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(10, 24),
    707                                 new CBC_QRCoderECB(35, 25)),
    708         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(19, 15),
    709                                 new CBC_QRCoderECB(35, 16))));
    710     VERSION->Add(new CBC_QRCoderVersion(
    711         33, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(17, 115),
    712                                     new CBC_QRCoderECB(1, 116)),
    713         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(14, 46),
    714                                 new CBC_QRCoderECB(21, 47)),
    715         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(29, 24),
    716                                 new CBC_QRCoderECB(19, 25)),
    717         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(11, 15),
    718                                 new CBC_QRCoderECB(46, 16))));
    719     VERSION->Add(new CBC_QRCoderVersion(
    720         34, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(13, 115),
    721                                     new CBC_QRCoderECB(6, 116)),
    722         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(14, 46),
    723                                 new CBC_QRCoderECB(23, 47)),
    724         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(44, 24),
    725                                 new CBC_QRCoderECB(7, 25)),
    726         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(59, 16),
    727                                 new CBC_QRCoderECB(1, 17))));
    728     VERSION->Add(new CBC_QRCoderVersion(
    729         35, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(12, 121),
    730                                     new CBC_QRCoderECB(7, 122)),
    731         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(12, 47),
    732                                 new CBC_QRCoderECB(26, 48)),
    733         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(39, 24),
    734                                 new CBC_QRCoderECB(14, 25)),
    735         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(22, 15),
    736                                 new CBC_QRCoderECB(41, 16))));
    737     VERSION->Add(new CBC_QRCoderVersion(
    738         36, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(6, 121),
    739                                     new CBC_QRCoderECB(14, 122)),
    740         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(6, 47),
    741                                 new CBC_QRCoderECB(34, 48)),
    742         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(46, 24),
    743                                 new CBC_QRCoderECB(10, 25)),
    744         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(2, 15),
    745                                 new CBC_QRCoderECB(64, 16))));
    746     VERSION->Add(new CBC_QRCoderVersion(
    747         37, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(17, 122),
    748                                     new CBC_QRCoderECB(4, 123)),
    749         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(29, 46),
    750                                 new CBC_QRCoderECB(14, 47)),
    751         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(49, 24),
    752                                 new CBC_QRCoderECB(10, 25)),
    753         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(24, 15),
    754                                 new CBC_QRCoderECB(46, 16))));
    755     VERSION->Add(new CBC_QRCoderVersion(
    756         38, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(4, 122),
    757                                     new CBC_QRCoderECB(18, 123)),
    758         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(13, 46),
    759                                 new CBC_QRCoderECB(32, 47)),
    760         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(48, 24),
    761                                 new CBC_QRCoderECB(14, 25)),
    762         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(42, 15),
    763                                 new CBC_QRCoderECB(32, 16))));
    764     VERSION->Add(new CBC_QRCoderVersion(
    765         39, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(20, 117),
    766                                     new CBC_QRCoderECB(4, 118)),
    767         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(40, 47),
    768                                 new CBC_QRCoderECB(7, 48)),
    769         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(43, 24),
    770                                 new CBC_QRCoderECB(22, 25)),
    771         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(10, 15),
    772                                 new CBC_QRCoderECB(67, 16))));
    773     VERSION->Add(new CBC_QRCoderVersion(
    774         40, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(19, 118),
    775                                     new CBC_QRCoderECB(6, 119)),
    776         new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(18, 47),
    777                                 new CBC_QRCoderECB(31, 48)),
    778         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(34, 24),
    779                                 new CBC_QRCoderECB(34, 25)),
    780         new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(20, 15),
    781                                 new CBC_QRCoderECB(61, 16))));
    782   }
    783   if (versionNumber < 1 || versionNumber > 40) {
    784     e = BCExceptionIllegalArgument;
    785     return nullptr;
    786   }
    787   return (*VERSION)[versionNumber - 1];
    788 }
    789 
    790 void CBC_QRCoderVersion::Destroy() {
    791   for (int32_t i = 0; i < VERSION->GetSize(); i++)
    792     delete (*VERSION)[i];
    793   VERSION->RemoveAll();
    794 }
    795