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 2008 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/src/fxbarcode/barcode.h"
     24 #include "xfa/src/fxbarcode/common/BC_CommonByteMatrix.h"
     25 #include "BC_QRCoderErrorCorrectionLevel.h"
     26 #include "BC_QRCoder.h"
     27 #include "BC_QRCoderMaskUtil.h"
     28 #include "BC_QRCoderMatrixUtil.h"
     29 #include "BC_QRCoderBitVector.h"
     30 const int32_t CBC_QRCoderMatrixUtil::POSITION_DETECTION_PATTERN[7][7] = {
     31     {1, 1, 1, 1, 1, 1, 1},
     32     {1, 0, 0, 0, 0, 0, 1},
     33     {1, 0, 1, 1, 1, 0, 1},
     34     {1, 0, 1, 1, 1, 0, 1},
     35     {1, 0, 1, 1, 1, 0, 1},
     36     {1, 0, 0, 0, 0, 0, 1},
     37     {1, 1, 1, 1, 1, 1, 1}};
     38 const int32_t CBC_QRCoderMatrixUtil::HORIZONTAL_SEPARATION_PATTERN[1][8] = {
     39     {0, 0, 0, 0, 0, 0, 0, 0}};
     40 const int32_t CBC_QRCoderMatrixUtil::VERTICAL_SEPARATION_PATTERN[7][1] =
     41     {{0}, {0}, {0}, {0}, {0}, {0}, {0}};
     42 const int32_t CBC_QRCoderMatrixUtil::POSITION_ADJUSTMENT_PATTERN[5][5] = {
     43     {1, 1, 1, 1, 1},
     44     {1, 0, 0, 0, 1},
     45     {1, 0, 1, 0, 1},
     46     {1, 0, 0, 0, 1},
     47     {1, 1, 1, 1, 1}};
     48 const int32_t
     49     CBC_QRCoderMatrixUtil::POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[40][7] =
     50         {
     51             {-1, -1, -1, -1, -1, -1, -1},   {6, 18, -1, -1, -1, -1, -1},
     52             {6, 22, -1, -1, -1, -1, -1},    {6, 26, -1, -1, -1, -1, -1},
     53             {6, 30, -1, -1, -1, -1, -1},    {6, 34, -1, -1, -1, -1, -1},
     54             {6, 22, 38, -1, -1, -1, -1},    {6, 24, 42, -1, -1, -1, -1},
     55             {6, 26, 46, -1, -1, -1, -1},    {6, 28, 50, -1, -1, -1, -1},
     56             {6, 30, 54, -1, -1, -1, -1},    {6, 32, 58, -1, -1, -1, -1},
     57             {6, 34, 62, -1, -1, -1, -1},    {6, 26, 46, 66, -1, -1, -1},
     58             {6, 26, 48, 70, -1, -1, -1},    {6, 26, 50, 74, -1, -1, -1},
     59             {6, 30, 54, 78, -1, -1, -1},    {6, 30, 56, 82, -1, -1, -1},
     60             {6, 30, 58, 86, -1, -1, -1},    {6, 34, 62, 90, -1, -1, -1},
     61             {6, 28, 50, 72, 94, -1, -1},    {6, 26, 50, 74, 98, -1, -1},
     62             {6, 30, 54, 78, 102, -1, -1},   {6, 28, 54, 80, 106, -1, -1},
     63             {6, 32, 58, 84, 110, -1, -1},   {6, 30, 58, 86, 114, -1, -1},
     64             {6, 34, 62, 90, 118, -1, -1},   {6, 26, 50, 74, 98, 122, -1},
     65             {6, 30, 54, 78, 102, 126, -1},  {6, 26, 52, 78, 104, 130, -1},
     66             {6, 30, 56, 82, 108, 134, -1},  {6, 34, 60, 86, 112, 138, -1},
     67             {6, 30, 58, 86, 114, 142, -1},  {6, 34, 62, 90, 118, 146, -1},
     68             {6, 30, 54, 78, 102, 126, 150}, {6, 24, 50, 76, 102, 128, 154},
     69             {6, 28, 54, 80, 106, 132, 158}, {6, 32, 58, 84, 110, 136, 162},
     70             {6, 26, 54, 82, 110, 138, 166}, {6, 30, 58, 86, 114, 142, 170},
     71 };
     72 const int32_t CBC_QRCoderMatrixUtil::TYPE_INFO_COORDINATES[15][2] = {
     73     {8, 0}, {8, 1}, {8, 2}, {8, 3}, {8, 4}, {8, 5}, {8, 7}, {8, 8},
     74     {7, 8}, {5, 8}, {4, 8}, {3, 8}, {2, 8}, {1, 8}, {0, 8},
     75 };
     76 const int32_t CBC_QRCoderMatrixUtil::VERSION_INFO_POLY = 0x1f25;
     77 const int32_t CBC_QRCoderMatrixUtil::TYPE_INFO_POLY = 0x0537;
     78 const int32_t CBC_QRCoderMatrixUtil::TYPE_INFO_MASK_PATTERN = 0x5412;
     79 void CBC_QRCoderMatrixUtil::ClearMatrix(CBC_CommonByteMatrix* matrix,
     80                                         int32_t& e) {
     81   if (matrix == NULL) {
     82     e = BCExceptionNullPointer;
     83     BC_EXCEPTION_CHECK_ReturnVoid(e);
     84   }
     85   matrix->clear((uint8_t)-1);
     86 }
     87 void CBC_QRCoderMatrixUtil::BuildMatrix(
     88     CBC_QRCoderBitVector* dataBits,
     89     CBC_QRCoderErrorCorrectionLevel* ecLevel,
     90     int32_t version,
     91     int32_t maskPattern,
     92     CBC_CommonByteMatrix* matrix,
     93     int32_t& e) {
     94   if (matrix == NULL) {
     95     e = BCExceptionNullPointer;
     96     BC_EXCEPTION_CHECK_ReturnVoid(e);
     97   }
     98   ClearMatrix(matrix, e);
     99   BC_EXCEPTION_CHECK_ReturnVoid(e);
    100   EmbedBasicPatterns(version, matrix, e);
    101   BC_EXCEPTION_CHECK_ReturnVoid(e);
    102   EmbedTypeInfo(ecLevel, maskPattern, matrix, e);
    103   BC_EXCEPTION_CHECK_ReturnVoid(e);
    104   MaybeEmbedVersionInfo(version, matrix, e);
    105   BC_EXCEPTION_CHECK_ReturnVoid(e);
    106   EmbedDataBits(dataBits, maskPattern, matrix, e);
    107   BC_EXCEPTION_CHECK_ReturnVoid(e);
    108 }
    109 void CBC_QRCoderMatrixUtil::EmbedBasicPatterns(int32_t version,
    110                                                CBC_CommonByteMatrix* matrix,
    111                                                int32_t& e) {
    112   if (matrix == NULL) {
    113     e = BCExceptionNullPointer;
    114     BC_EXCEPTION_CHECK_ReturnVoid(e);
    115   }
    116   EmbedPositionDetectionPatternsAndSeparators(matrix, e);
    117   BC_EXCEPTION_CHECK_ReturnVoid(e);
    118   EmbedDarkDotAtLeftBottomCorner(matrix, e);
    119   BC_EXCEPTION_CHECK_ReturnVoid(e);
    120   MaybeEmbedPositionAdjustmentPatterns(version, matrix, e);
    121   BC_EXCEPTION_CHECK_ReturnVoid(e);
    122   EmbedTimingPatterns(matrix, e);
    123   BC_EXCEPTION_CHECK_ReturnVoid(e);
    124 }
    125 void CBC_QRCoderMatrixUtil::EmbedTypeInfo(
    126     CBC_QRCoderErrorCorrectionLevel* ecLevel,
    127     int32_t maskPattern,
    128     CBC_CommonByteMatrix* matrix,
    129     int32_t& e) {
    130   if (matrix == NULL) {
    131     e = BCExceptionNullPointer;
    132     BC_EXCEPTION_CHECK_ReturnVoid(e);
    133   }
    134   CBC_QRCoderBitVector typeInfoBits;
    135   typeInfoBits.Init();
    136   MakeTypeInfoBits(ecLevel, maskPattern, &typeInfoBits, e);
    137   BC_EXCEPTION_CHECK_ReturnVoid(e);
    138   for (int32_t i = 0; i < typeInfoBits.Size(); i++) {
    139     int32_t bit = typeInfoBits.At(typeInfoBits.Size() - 1 - i, e);
    140     BC_EXCEPTION_CHECK_ReturnVoid(e);
    141     int32_t x1 = TYPE_INFO_COORDINATES[i][0];
    142     int32_t y1 = TYPE_INFO_COORDINATES[i][1];
    143     matrix->Set(x1, y1, bit);
    144     if (i < 8) {
    145       int32_t x2 = matrix->GetWidth() - i - 1;
    146       int32_t y2 = 8;
    147       matrix->Set(x2, y2, bit);
    148     } else {
    149       int32_t x2 = 8;
    150       int32_t y2 = matrix->GetHeight() - 7 + (i - 8);
    151       matrix->Set(x2, y2, bit);
    152     }
    153   }
    154 }
    155 void CBC_QRCoderMatrixUtil::MaybeEmbedVersionInfo(int32_t version,
    156                                                   CBC_CommonByteMatrix* matrix,
    157                                                   int32_t& e) {
    158   if (matrix == NULL) {
    159     e = BCExceptionNullPointer;
    160     BC_EXCEPTION_CHECK_ReturnVoid(e);
    161   }
    162   if (version < 7) {
    163     return;
    164   }
    165   CBC_QRCoderBitVector versionInfoBits;
    166   versionInfoBits.Init();
    167   MakeVersionInfoBits(version, &versionInfoBits, e);
    168   BC_EXCEPTION_CHECK_ReturnVoid(e);
    169   int32_t bitIndex = 6 * 3 - 1;
    170   for (int32_t i = 0; i < 6; i++) {
    171     for (int32_t j = 0; j < 3; j++) {
    172       int32_t bit = versionInfoBits.At(bitIndex, e);
    173       BC_EXCEPTION_CHECK_ReturnVoid(e);
    174       bitIndex--;
    175       matrix->Set(i, matrix->GetHeight() - 11 + j, bit);
    176       matrix->Set(matrix->GetHeight() - 11 + j, i, bit);
    177     }
    178   }
    179 }
    180 void CBC_QRCoderMatrixUtil::EmbedDataBits(CBC_QRCoderBitVector* dataBits,
    181                                           int32_t maskPattern,
    182                                           CBC_CommonByteMatrix* matrix,
    183                                           int32_t& e) {
    184   if (matrix == NULL || dataBits == NULL) {
    185     e = BCExceptionNullPointer;
    186     BC_EXCEPTION_CHECK_ReturnVoid(e);
    187   }
    188   int32_t bitIndex = 0;
    189   int32_t direction = -1;
    190   int32_t x = matrix->GetWidth() - 1;
    191   int32_t y = matrix->GetHeight() - 1;
    192   while (x > 0) {
    193     if (x == 6) {
    194       x -= 1;
    195     }
    196     while (y >= 0 && y < matrix->GetHeight()) {
    197       if (y == 6) {
    198         y += direction;
    199         continue;
    200       }
    201       for (int32_t i = 0; i < 2; i++) {
    202         int32_t xx = x - i;
    203         if (!IsEmpty(matrix->Get(xx, y))) {
    204           continue;
    205         }
    206         int32_t bit;
    207         if (bitIndex < dataBits->Size()) {
    208           bit = dataBits->At(bitIndex, e);
    209           BC_EXCEPTION_CHECK_ReturnVoid(e);
    210           bitIndex++;
    211         } else {
    212           bit = 0;
    213         }
    214         if (maskPattern != -1) {
    215           FX_BOOL bol =
    216               CBC_QRCoderMaskUtil::GetDataMaskBit(maskPattern, xx, y, e);
    217           BC_EXCEPTION_CHECK_ReturnVoid(e);
    218           if (bol) {
    219             bit ^= 0x01;
    220           }
    221         }
    222         matrix->Set(xx, y, bit);
    223       }
    224       y += direction;
    225     }
    226     direction = -direction;
    227     y += direction;
    228     x -= 2;
    229   }
    230   if (bitIndex != dataBits->Size()) {
    231     return;
    232   }
    233 }
    234 int32_t CBC_QRCoderMatrixUtil::CalculateBCHCode(int32_t value, int32_t poly) {
    235   int32_t msbSetInPoly = FindMSBSet(poly);
    236   value <<= msbSetInPoly - 1;
    237   while (FindMSBSet(value) >= msbSetInPoly) {
    238     value ^= poly << (FindMSBSet(value) - msbSetInPoly);
    239   }
    240   return value;
    241 }
    242 void CBC_QRCoderMatrixUtil::MakeTypeInfoBits(
    243     CBC_QRCoderErrorCorrectionLevel* ecLevel,
    244     int32_t maskPattern,
    245     CBC_QRCoderBitVector* bits,
    246     int32_t& e) {
    247   if (bits == NULL) {
    248     e = BCExceptionNullPointer;
    249     BC_EXCEPTION_CHECK_ReturnVoid(e);
    250   }
    251   if (!CBC_QRCoder::IsValidMaskPattern(maskPattern)) {
    252     e = BCExceptionBadMask;
    253     BC_EXCEPTION_CHECK_ReturnVoid(e);
    254   }
    255   int32_t typeInfo = (ecLevel->GetBits() << 3) | maskPattern;
    256   BC_EXCEPTION_CHECK_ReturnVoid(e);
    257   bits->AppendBits(typeInfo, 5, e);
    258   int32_t bchCode = CalculateBCHCode(typeInfo, TYPE_INFO_POLY);
    259   BC_EXCEPTION_CHECK_ReturnVoid(e);
    260   bits->AppendBits(bchCode, 10, e);
    261   CBC_QRCoderBitVector maskBits;
    262   maskBits.Init();
    263   maskBits.AppendBits(TYPE_INFO_MASK_PATTERN, 15, e);
    264   BC_EXCEPTION_CHECK_ReturnVoid(e);
    265   bits->XOR(&maskBits, e);
    266   BC_EXCEPTION_CHECK_ReturnVoid(e);
    267   if (bits->Size() != 15) {
    268     e = BCExceptionBitSizeNot15;
    269     BC_EXCEPTION_CHECK_ReturnVoid(e);
    270   }
    271 }
    272 void CBC_QRCoderMatrixUtil::MakeVersionInfoBits(int32_t version,
    273                                                 CBC_QRCoderBitVector* bits,
    274                                                 int32_t& e) {
    275   if (bits == NULL) {
    276     e = BCExceptionNullPointer;
    277     BC_EXCEPTION_CHECK_ReturnVoid(e);
    278   }
    279   bits->AppendBits(version, 6, e);
    280   BC_EXCEPTION_CHECK_ReturnVoid(e);
    281   int32_t bchCode = CalculateBCHCode(version, VERSION_INFO_POLY);
    282   bits->AppendBits(bchCode, 12, e);
    283   BC_EXCEPTION_CHECK_ReturnVoid(e);
    284   if (bits->Size() != 18) {
    285     e = BCExceptionBitSizeNot18;
    286     BC_EXCEPTION_CHECK_ReturnVoid(e);
    287   }
    288 }
    289 FX_BOOL CBC_QRCoderMatrixUtil::IsEmpty(int32_t value) {
    290   return (uint8_t)value == 0xff;
    291 }
    292 FX_BOOL CBC_QRCoderMatrixUtil::IsValidValue(int32_t value) {
    293   return ((uint8_t)value == 0xff || (uint8_t)value == 0x00 ||
    294           (uint8_t)value == 0x01);
    295 }
    296 void CBC_QRCoderMatrixUtil::EmbedTimingPatterns(CBC_CommonByteMatrix* matrix,
    297                                                 int32_t& e) {
    298   if (matrix == NULL) {
    299     e = BCExceptionNullPointer;
    300     BC_EXCEPTION_CHECK_ReturnVoid(e);
    301   }
    302   for (int32_t i = 8; i < matrix->GetWidth() - 8; i++) {
    303     int32_t bit = (i + 1) % 2;
    304     if (!IsValidValue(matrix->Get(i, 6))) {
    305       e = BCExceptionInvalidateImageData;
    306       BC_EXCEPTION_CHECK_ReturnVoid(e);
    307     }
    308     if (IsEmpty(matrix->Get(i, 6))) {
    309       matrix->Set(i, 6, bit);
    310     }
    311     if (!IsValidValue(matrix->Get(6, i))) {
    312       e = BCExceptionInvalidateImageData;
    313       BC_EXCEPTION_CHECK_ReturnVoid(e);
    314     }
    315     if (IsEmpty(matrix->Get(6, i))) {
    316       matrix->Set(6, i, bit);
    317     }
    318   }
    319 }
    320 void CBC_QRCoderMatrixUtil::EmbedDarkDotAtLeftBottomCorner(
    321     CBC_CommonByteMatrix* matrix,
    322     int32_t& e) {
    323   if (matrix == NULL) {
    324     e = BCExceptionNullPointer;
    325     BC_EXCEPTION_CHECK_ReturnVoid(e);
    326   }
    327   if (matrix->Get(8, matrix->GetHeight() - 8) == 0) {
    328     e = BCExceptionHeight_8BeZero;
    329     BC_EXCEPTION_CHECK_ReturnVoid(e);
    330   }
    331   matrix->Set(8, matrix->GetHeight() - 8, 1);
    332 }
    333 void CBC_QRCoderMatrixUtil::EmbedHorizontalSeparationPattern(
    334     int32_t xStart,
    335     int32_t yStart,
    336     CBC_CommonByteMatrix* matrix,
    337     int32_t& e) {
    338   if (matrix == NULL) {
    339     e = BCExceptionNullPointer;
    340     BC_EXCEPTION_CHECK_ReturnVoid(e);
    341   }
    342   for (int32_t x = 0; x < 8; x++) {
    343     if (!IsEmpty(matrix->Get(xStart + x, yStart))) {
    344       e = BCExceptionInvalidateData;
    345       BC_EXCEPTION_CHECK_ReturnVoid(e)
    346     }
    347     matrix->Set(xStart + x, yStart, HORIZONTAL_SEPARATION_PATTERN[0][x]);
    348   }
    349 }
    350 void CBC_QRCoderMatrixUtil::EmbedVerticalSeparationPattern(
    351     int32_t xStart,
    352     int32_t yStart,
    353     CBC_CommonByteMatrix* matrix,
    354     int32_t& e) {
    355   if (matrix == NULL) {
    356     e = BCExceptionNullPointer;
    357     BC_EXCEPTION_CHECK_ReturnVoid(e);
    358   }
    359   for (int32_t y = 0; y < 7; y++) {
    360     if (!IsEmpty(matrix->Get(xStart, yStart + y))) {
    361       e = BCExceptionInvalidateData;
    362       BC_EXCEPTION_CHECK_ReturnVoid(e);
    363     }
    364     matrix->Set(xStart, yStart + y, VERTICAL_SEPARATION_PATTERN[y][0]);
    365   }
    366 }
    367 void CBC_QRCoderMatrixUtil::EmbedPositionAdjustmentPattern(
    368     int32_t xStart,
    369     int32_t yStart,
    370     CBC_CommonByteMatrix* matrix,
    371     int32_t& e) {
    372   if (matrix == NULL) {
    373     e = BCExceptionNullPointer;
    374     BC_EXCEPTION_CHECK_ReturnVoid(e);
    375   }
    376   for (int32_t y = 0; y < 5; y++) {
    377     for (int32_t x = 0; x < 5; x++) {
    378       if (!IsEmpty(matrix->Get(xStart + x, y + yStart))) {
    379         e = BCExceptionInvalidateData;
    380         BC_EXCEPTION_CHECK_ReturnVoid(e);
    381       }
    382       matrix->Set(xStart + x, yStart + y, POSITION_ADJUSTMENT_PATTERN[y][x]);
    383     }
    384   }
    385 }
    386 void CBC_QRCoderMatrixUtil::EmbedPositionDetectionPattern(
    387     int32_t xStart,
    388     int32_t yStart,
    389     CBC_CommonByteMatrix* matrix,
    390     int32_t& e) {
    391   if (matrix == NULL) {
    392     e = BCExceptionNullPointer;
    393     BC_EXCEPTION_CHECK_ReturnVoid(e);
    394   }
    395   for (int32_t y = 0; y < 7; y++) {
    396     for (int32_t x = 0; x < 7; x++) {
    397       if (!IsEmpty(matrix->Get(xStart + x, yStart + y))) {
    398         e = BCExceptionInvalidateData;
    399         BC_EXCEPTION_CHECK_ReturnVoid(e);
    400       }
    401       matrix->Set(xStart + x, yStart + y, POSITION_DETECTION_PATTERN[y][x]);
    402     }
    403   }
    404 }
    405 void CBC_QRCoderMatrixUtil::EmbedPositionDetectionPatternsAndSeparators(
    406     CBC_CommonByteMatrix* matrix,
    407     int32_t& e) {
    408   if (matrix == NULL) {
    409     e = BCExceptionNullPointer;
    410     BC_EXCEPTION_CHECK_ReturnVoid(e);
    411   }
    412   int32_t pdpWidth = 7;
    413   EmbedPositionDetectionPattern(0, 0, matrix, e);
    414   BC_EXCEPTION_CHECK_ReturnVoid(e);
    415   EmbedPositionDetectionPattern(matrix->GetWidth() - pdpWidth, 0, matrix, e);
    416   BC_EXCEPTION_CHECK_ReturnVoid(e);
    417   EmbedPositionDetectionPattern(0, matrix->GetWidth() - pdpWidth, matrix, e);
    418   BC_EXCEPTION_CHECK_ReturnVoid(e);
    419   int32_t hspWidth = 8;
    420   EmbedHorizontalSeparationPattern(0, hspWidth - 1, matrix, e);
    421   BC_EXCEPTION_CHECK_ReturnVoid(e);
    422   EmbedHorizontalSeparationPattern(matrix->GetWidth() - hspWidth, hspWidth - 1,
    423                                    matrix, e);
    424   BC_EXCEPTION_CHECK_ReturnVoid(e);
    425   EmbedHorizontalSeparationPattern(0, matrix->GetWidth() - hspWidth, matrix, e);
    426   BC_EXCEPTION_CHECK_ReturnVoid(e);
    427   int32_t vspSize = 7;
    428   EmbedVerticalSeparationPattern(vspSize, 0, matrix, e);
    429   BC_EXCEPTION_CHECK_ReturnVoid(e);
    430   EmbedVerticalSeparationPattern(matrix->GetHeight() - vspSize - 1, 0, matrix,
    431                                  e);
    432   BC_EXCEPTION_CHECK_ReturnVoid(e);
    433   EmbedVerticalSeparationPattern(vspSize, matrix->GetHeight() - vspSize, matrix,
    434                                  e);
    435   BC_EXCEPTION_CHECK_ReturnVoid(e);
    436 }
    437 void CBC_QRCoderMatrixUtil::MaybeEmbedPositionAdjustmentPatterns(
    438     int32_t version,
    439     CBC_CommonByteMatrix* matrix,
    440     int32_t& e) {
    441   if (matrix == NULL) {
    442     e = BCExceptionNullPointer;
    443     BC_EXCEPTION_CHECK_ReturnVoid(e);
    444   }
    445   if (version < 2) {
    446     return;
    447   }
    448   int32_t index = version - 1;
    449   int32_t const* coordinates =
    450       &(POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index][0]);
    451   int32_t numCoordinate = 7;
    452   for (int32_t i = 0; i < numCoordinate; i++) {
    453     for (int32_t j = 0; j < numCoordinate; j++) {
    454       int32_t y = coordinates[i];
    455       int32_t x = coordinates[j];
    456       if (x == -1 || y == -1) {
    457         continue;
    458       }
    459       if (IsEmpty(matrix->Get(x, y))) {
    460         EmbedPositionAdjustmentPattern(x - 2, y - 2, matrix, e);
    461         BC_EXCEPTION_CHECK_ReturnVoid(e);
    462       }
    463     }
    464   }
    465 }
    466 int32_t CBC_QRCoderMatrixUtil::FindMSBSet(int32_t value) {
    467   int32_t numDigits = 0;
    468   while (value != 0) {
    469     value >>= 1;
    470     ++numDigits;
    471   }
    472   return numDigits;
    473 }
    474 CBC_QRCoderMatrixUtil::CBC_QRCoderMatrixUtil() {}
    475 CBC_QRCoderMatrixUtil::~CBC_QRCoderMatrixUtil() {}
    476