14d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Copyright 2014 PDFium Authors. All rights reserved.
24d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Use of this source code is governed by a BSD-style license that can be
34d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// found in the LICENSE file.
44d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
54d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
64d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Original code is licensed as follows:
74d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/*
84d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Copyright 2008 ZXing authors
94d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Licensed under the Apache License, Version 2.0 (the "License");
114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * you may not use this file except in compliance with the License.
124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * You may obtain a copy of the License at
134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *      http://www.apache.org/licenses/LICENSE-2.0
154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *
164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Unless required by applicable law or agreed to in writing, software
174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * distributed under the License is distributed on an "AS IS" BASIS,
184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * See the License for the specific language governing permissions and
204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * limitations under the License.
214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */
224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
23d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "fxbarcode/common/BC_CommonByteMatrix.h"
24d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "fxbarcode/qrcode/BC_QRCoder.h"
25d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "fxbarcode/qrcode/BC_QRCoderBitVector.h"
26d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
27d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "fxbarcode/qrcode/BC_QRCoderMaskUtil.h"
28d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "fxbarcode/qrcode/BC_QRCoderMatrixUtil.h"
29d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "fxbarcode/utils.h"
304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconst int32_t CBC_QRCoderMatrixUtil::POSITION_DETECTION_PATTERN[7][7] = {
324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    {1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 0, 1},
334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    {1, 0, 1, 1, 1, 0, 1}, {1, 0, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 1},
344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    {1, 1, 1, 1, 1, 1, 1}};
354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconst int32_t CBC_QRCoderMatrixUtil::HORIZONTAL_SEPARATION_PATTERN[1][8] = {
364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    {0, 0, 0, 0, 0, 0, 0, 0}};
374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconst int32_t CBC_QRCoderMatrixUtil::VERTICAL_SEPARATION_PATTERN[7][1] = {
384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    {0}, {0}, {0}, {0}, {0}, {0}, {0}};
394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconst int32_t CBC_QRCoderMatrixUtil::POSITION_ADJUSTMENT_PATTERN[5][5] = {
404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    {1, 1, 1, 1, 1},
414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    {1, 0, 0, 0, 1},
424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    {1, 0, 1, 0, 1},
434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    {1, 0, 0, 0, 1},
444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    {1, 1, 1, 1, 1}};
454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconst int32_t
464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    CBC_QRCoderMatrixUtil::POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[40][7] =
474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        // NOLINTNEXTLINE
484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    {
494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {-1, -1, -1, -1, -1, -1, -1},   {6, 18, -1, -1, -1, -1, -1},
504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 22, -1, -1, -1, -1, -1},    {6, 26, -1, -1, -1, -1, -1},
514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 30, -1, -1, -1, -1, -1},    {6, 34, -1, -1, -1, -1, -1},
524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 22, 38, -1, -1, -1, -1},    {6, 24, 42, -1, -1, -1, -1},
534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 26, 46, -1, -1, -1, -1},    {6, 28, 50, -1, -1, -1, -1},
544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 30, 54, -1, -1, -1, -1},    {6, 32, 58, -1, -1, -1, -1},
554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 34, 62, -1, -1, -1, -1},    {6, 26, 46, 66, -1, -1, -1},
564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 26, 48, 70, -1, -1, -1},    {6, 26, 50, 74, -1, -1, -1},
574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 30, 54, 78, -1, -1, -1},    {6, 30, 56, 82, -1, -1, -1},
584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 30, 58, 86, -1, -1, -1},    {6, 34, 62, 90, -1, -1, -1},
594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 28, 50, 72, 94, -1, -1},    {6, 26, 50, 74, 98, -1, -1},
604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 30, 54, 78, 102, -1, -1},   {6, 28, 54, 80, 106, -1, -1},
614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 32, 58, 84, 110, -1, -1},   {6, 30, 58, 86, 114, -1, -1},
624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 34, 62, 90, 118, -1, -1},   {6, 26, 50, 74, 98, 122, -1},
634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 30, 54, 78, 102, 126, -1},  {6, 26, 52, 78, 104, 130, -1},
644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 30, 56, 82, 108, 134, -1},  {6, 34, 60, 86, 112, 138, -1},
654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 30, 58, 86, 114, 142, -1},  {6, 34, 62, 90, 118, 146, -1},
664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 30, 54, 78, 102, 126, 150}, {6, 24, 50, 76, 102, 128, 154},
674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 28, 54, 80, 106, 132, 158}, {6, 32, 58, 84, 110, 136, 162},
684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        {6, 26, 54, 82, 110, 138, 166}, {6, 30, 58, 86, 114, 142, 170},
694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann};
704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconst int32_t CBC_QRCoderMatrixUtil::TYPE_INFO_COORDINATES[15][2] = {
714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    {8, 0}, {8, 1}, {8, 2}, {8, 3}, {8, 4}, {8, 5}, {8, 7}, {8, 8},
724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    {7, 8}, {5, 8}, {4, 8}, {3, 8}, {2, 8}, {1, 8}, {0, 8},
734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann};
744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconst int32_t CBC_QRCoderMatrixUtil::VERSION_INFO_POLY = 0x1f25;
754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconst int32_t CBC_QRCoderMatrixUtil::TYPE_INFO_POLY = 0x0537;
764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconst int32_t CBC_QRCoderMatrixUtil::TYPE_INFO_MASK_PATTERN = 0x5412;
774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann
784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBC_QRCoderMatrixUtil::ClearMatrix(CBC_CommonByteMatrix* matrix,
794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                        int32_t& e) {
804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!matrix) {
814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionNullPointer;
8233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  matrix->clear((uint8_t)-1);
854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBC_QRCoderMatrixUtil::BuildMatrix(
874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    CBC_QRCoderBitVector* dataBits,
88d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    const CBC_QRCoderErrorCorrectionLevel* ecLevel,
894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t version,
904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t maskPattern,
914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    CBC_CommonByteMatrix* matrix,
924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t& e) {
934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!matrix) {
944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionNullPointer;
9533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  ClearMatrix(matrix, e);
9833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
9933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
1004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  EmbedBasicPatterns(version, matrix, e);
10133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
10233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
1034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  EmbedTypeInfo(ecLevel, maskPattern, matrix, e);
10433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
10533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
1064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  MaybeEmbedVersionInfo(version, matrix, e);
10733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
10833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
1094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  EmbedDataBits(dataBits, maskPattern, matrix, e);
11033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
11133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
1124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
1134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBC_QRCoderMatrixUtil::EmbedBasicPatterns(int32_t version,
1144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                               CBC_CommonByteMatrix* matrix,
1154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                               int32_t& e) {
1164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!matrix) {
1174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionNullPointer;
11833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
1194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
1204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  EmbedPositionDetectionPatternsAndSeparators(matrix, e);
12133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
12233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
1234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  EmbedDarkDotAtLeftBottomCorner(matrix, e);
12433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
12533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
1264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  MaybeEmbedPositionAdjustmentPatterns(version, matrix, e);
12733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
12833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
1294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  EmbedTimingPatterns(matrix, e);
13033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
13133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
1324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
133d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
1344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBC_QRCoderMatrixUtil::EmbedTypeInfo(
135d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    const CBC_QRCoderErrorCorrectionLevel* ecLevel,
1364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t maskPattern,
1374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    CBC_CommonByteMatrix* matrix,
1384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t& e) {
1394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!matrix) {
1404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionNullPointer;
14133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
1424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
1434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CBC_QRCoderBitVector typeInfoBits;
1444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  MakeTypeInfoBits(ecLevel, maskPattern, &typeInfoBits, e);
14533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
14633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
147d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
148d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  for (size_t i = 0; i < typeInfoBits.Size(); i++) {
1494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t bit = typeInfoBits.At(typeInfoBits.Size() - 1 - i, e);
15033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    if (e != BCExceptionNO)
15133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann      return;
1524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t x1 = TYPE_INFO_COORDINATES[i][0];
1534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t y1 = TYPE_INFO_COORDINATES[i][1];
1544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    matrix->Set(x1, y1, bit);
1554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (i < 8) {
1564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int32_t x2 = matrix->GetWidth() - i - 1;
1574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int32_t y2 = 8;
1584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      matrix->Set(x2, y2, bit);
1594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    } else {
1604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int32_t x2 = 8;
1614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int32_t y2 = matrix->GetHeight() - 7 + (i - 8);
1624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      matrix->Set(x2, y2, bit);
1634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
1644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
1654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
166d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
1674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBC_QRCoderMatrixUtil::MaybeEmbedVersionInfo(int32_t version,
1684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                                  CBC_CommonByteMatrix* matrix,
1694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                                  int32_t& e) {
1704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!matrix) {
1714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionNullPointer;
17233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
1734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
1744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (version < 7) {
1754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return;
1764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
1774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CBC_QRCoderBitVector versionInfoBits;
1784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  MakeVersionInfoBits(version, &versionInfoBits, e);
17933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
18033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
1814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t bitIndex = 6 * 3 - 1;
1824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (int32_t i = 0; i < 6; i++) {
1834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    for (int32_t j = 0; j < 3; j++) {
1844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int32_t bit = versionInfoBits.At(bitIndex, e);
18533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann      if (e != BCExceptionNO)
18633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann        return;
1874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      bitIndex--;
1884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      matrix->Set(i, matrix->GetHeight() - 11 + j, bit);
1894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      matrix->Set(matrix->GetHeight() - 11 + j, i, bit);
1904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
1914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
1924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
1934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBC_QRCoderMatrixUtil::EmbedDataBits(CBC_QRCoderBitVector* dataBits,
1944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                          int32_t maskPattern,
1954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                          CBC_CommonByteMatrix* matrix,
1964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                          int32_t& e) {
1974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!matrix || !dataBits) {
1984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionNullPointer;
19933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
2004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
201d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t bitIndex = 0;
2024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t direction = -1;
2034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t x = matrix->GetWidth() - 1;
2044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t y = matrix->GetHeight() - 1;
2054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  while (x > 0) {
2064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (x == 6) {
2074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      x -= 1;
2084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
2094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    while (y >= 0 && y < matrix->GetHeight()) {
2104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (y == 6) {
2114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        y += direction;
2124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        continue;
2134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
2144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      for (int32_t i = 0; i < 2; i++) {
2154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        int32_t xx = x - i;
2164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (!IsEmpty(matrix->Get(xx, y))) {
2174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          continue;
2184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
2194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        int32_t bit;
2204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (bitIndex < dataBits->Size()) {
2214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          bit = dataBits->At(bitIndex, e);
22233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann          if (e != BCExceptionNO)
22333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann            return;
2244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          bitIndex++;
2254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        } else {
2264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          bit = 0;
2274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
2284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        if (maskPattern != -1) {
2294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          bool bol = CBC_QRCoderMaskUtil::GetDataMaskBit(maskPattern, xx, y, e);
23033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann          if (e != BCExceptionNO)
23133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann            return;
2324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          if (bol) {
2334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann            bit ^= 0x01;
2344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          }
2354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        }
2364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        matrix->Set(xx, y, bit);
2374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
2384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      y += direction;
2394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
2404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    direction = -direction;
2414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    y += direction;
2424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    x -= 2;
2434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
2444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (bitIndex != dataBits->Size()) {
2454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return;
2464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
2474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
2484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint32_t CBC_QRCoderMatrixUtil::CalculateBCHCode(int32_t value, int32_t poly) {
2494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t msbSetInPoly = FindMSBSet(poly);
2504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  value <<= msbSetInPoly - 1;
2514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  while (FindMSBSet(value) >= msbSetInPoly) {
2524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    value ^= poly << (FindMSBSet(value) - msbSetInPoly);
2534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
2544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return value;
2554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
2564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBC_QRCoderMatrixUtil::MakeTypeInfoBits(
257d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    const CBC_QRCoderErrorCorrectionLevel* ecLevel,
2584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t maskPattern,
2594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    CBC_QRCoderBitVector* bits,
2604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t& e) {
2614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!bits) {
2624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionNullPointer;
26333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
2644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
2654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!CBC_QRCoder::IsValidMaskPattern(maskPattern)) {
2664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionBadMask;
26733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
2684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
2694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t typeInfo = (ecLevel->GetBits() << 3) | maskPattern;
270d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bits->AppendBits(typeInfo, 5);
2714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t bchCode = CalculateBCHCode(typeInfo, TYPE_INFO_POLY);
272d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bits->AppendBits(bchCode, 10);
2734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  CBC_QRCoderBitVector maskBits;
274d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  maskBits.AppendBits(TYPE_INFO_MASK_PATTERN, 15);
275d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!bits->XOR(&maskBits)) {
276d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    e = BCExceptionGeneric;
27733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
278d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
279d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ASSERT(bits->Size() == 15);
2804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
28133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann
2824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBC_QRCoderMatrixUtil::MakeVersionInfoBits(int32_t version,
2834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                                CBC_QRCoderBitVector* bits,
2844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                                int32_t& e) {
2854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!bits) {
2864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionNullPointer;
28733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
2884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
28933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann
290d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bits->AppendBits(version, 6);
2914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t bchCode = CalculateBCHCode(version, VERSION_INFO_POLY);
292d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bits->AppendBits(bchCode, 12);
293d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ASSERT(bits->Size() == 18);
2944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
29533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann
2964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CBC_QRCoderMatrixUtil::IsEmpty(int32_t value) {
2974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return (uint8_t)value == 0xff;
2984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
2994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CBC_QRCoderMatrixUtil::IsValidValue(int32_t value) {
3004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return ((uint8_t)value == 0xff || (uint8_t)value == 0x00 ||
3014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann          (uint8_t)value == 0x01);
3024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
30333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann
3044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBC_QRCoderMatrixUtil::EmbedTimingPatterns(CBC_CommonByteMatrix* matrix,
3054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                                int32_t& e) {
3064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!matrix) {
3074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionNullPointer;
30833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
3094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
3104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (int32_t i = 8; i < matrix->GetWidth() - 8; i++) {
3114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t bit = (i + 1) % 2;
3124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (!IsValidValue(matrix->Get(i, 6))) {
3134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      e = BCExceptionInvalidateImageData;
31433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann      return;
3154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
3164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (IsEmpty(matrix->Get(i, 6))) {
3174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      matrix->Set(i, 6, bit);
3184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
3194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (!IsValidValue(matrix->Get(6, i))) {
3204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      e = BCExceptionInvalidateImageData;
32133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann      return;
3224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
3234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (IsEmpty(matrix->Get(6, i))) {
3244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      matrix->Set(6, i, bit);
3254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
3264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
3274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
3284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBC_QRCoderMatrixUtil::EmbedDarkDotAtLeftBottomCorner(
3294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    CBC_CommonByteMatrix* matrix,
3304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t& e) {
3314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!matrix) {
3324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionNullPointer;
33333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
3344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
3354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (matrix->Get(8, matrix->GetHeight() - 8) == 0) {
3364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionHeight_8BeZero;
33733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
3384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
3394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  matrix->Set(8, matrix->GetHeight() - 8, 1);
3404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
3414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBC_QRCoderMatrixUtil::EmbedHorizontalSeparationPattern(
3424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t xStart,
3434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t yStart,
3444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    CBC_CommonByteMatrix* matrix,
3454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t& e) {
3464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!matrix) {
3474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionNullPointer;
34833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
3494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
3504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (int32_t x = 0; x < 8; x++) {
3514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (!IsEmpty(matrix->Get(xStart + x, yStart))) {
3524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      e = BCExceptionInvalidateData;
35333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann      return;
3544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
3554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    matrix->Set(xStart + x, yStart, HORIZONTAL_SEPARATION_PATTERN[0][x]);
3564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
3574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
3584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBC_QRCoderMatrixUtil::EmbedVerticalSeparationPattern(
3594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t xStart,
3604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t yStart,
3614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    CBC_CommonByteMatrix* matrix,
3624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t& e) {
3634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!matrix) {
3644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionNullPointer;
36533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
3664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
3674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (int32_t y = 0; y < 7; y++) {
3684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    if (!IsEmpty(matrix->Get(xStart, yStart + y))) {
3694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      e = BCExceptionInvalidateData;
37033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann      return;
3714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
3724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    matrix->Set(xStart, yStart + y, VERTICAL_SEPARATION_PATTERN[y][0]);
3734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
3744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
3754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBC_QRCoderMatrixUtil::EmbedPositionAdjustmentPattern(
3764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t xStart,
3774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t yStart,
3784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    CBC_CommonByteMatrix* matrix,
3794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t& e) {
3804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!matrix) {
3814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionNullPointer;
38233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    if (e != BCExceptionNO)
38333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann      return;
3844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
3854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (int32_t y = 0; y < 5; y++) {
3864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    for (int32_t x = 0; x < 5; x++) {
3874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (!IsEmpty(matrix->Get(xStart + x, y + yStart))) {
3884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        e = BCExceptionInvalidateData;
38933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann        return;
3904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
3914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      matrix->Set(xStart + x, yStart + y, POSITION_ADJUSTMENT_PATTERN[y][x]);
3924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
3934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
3944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
3954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBC_QRCoderMatrixUtil::EmbedPositionDetectionPattern(
3964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t xStart,
3974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t yStart,
3984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    CBC_CommonByteMatrix* matrix,
3994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t& e) {
4004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!matrix) {
4014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionNullPointer;
40233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
4034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
4044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (int32_t y = 0; y < 7; y++) {
4054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    for (int32_t x = 0; x < 7; x++) {
4064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (!IsEmpty(matrix->Get(xStart + x, yStart + y))) {
4074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        e = BCExceptionInvalidateData;
40833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann        return;
4094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
4104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      matrix->Set(xStart + x, yStart + y, POSITION_DETECTION_PATTERN[y][x]);
4114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
4124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
4134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
4144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBC_QRCoderMatrixUtil::EmbedPositionDetectionPatternsAndSeparators(
4154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    CBC_CommonByteMatrix* matrix,
4164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t& e) {
4174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!matrix) {
4184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionNullPointer;
41933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
4204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
4214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t pdpWidth = 7;
4224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  EmbedPositionDetectionPattern(0, 0, matrix, e);
42333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
42433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
4254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  EmbedPositionDetectionPattern(matrix->GetWidth() - pdpWidth, 0, matrix, e);
42633357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
42733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
4284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  EmbedPositionDetectionPattern(0, matrix->GetWidth() - pdpWidth, matrix, e);
42933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
43033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
4314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t hspWidth = 8;
4324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  EmbedHorizontalSeparationPattern(0, hspWidth - 1, matrix, e);
43333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
43433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
4354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  EmbedHorizontalSeparationPattern(matrix->GetWidth() - hspWidth, hspWidth - 1,
4364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                   matrix, e);
43733357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
43833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
4394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  EmbedHorizontalSeparationPattern(0, matrix->GetWidth() - hspWidth, matrix, e);
44033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
44133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
4424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t vspSize = 7;
4434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  EmbedVerticalSeparationPattern(vspSize, 0, matrix, e);
44433357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
44533357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
4464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  EmbedVerticalSeparationPattern(matrix->GetHeight() - vspSize - 1, 0, matrix,
4474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                 e);
44833357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
44933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
4504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  EmbedVerticalSeparationPattern(vspSize, matrix->GetHeight() - vspSize, matrix,
4514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann                                 e);
45233357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann  if (e != BCExceptionNO)
45333357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
4544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
4554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBC_QRCoderMatrixUtil::MaybeEmbedPositionAdjustmentPatterns(
4564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t version,
4574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    CBC_CommonByteMatrix* matrix,
4584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    int32_t& e) {
4594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (!matrix) {
4604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    e = BCExceptionNullPointer;
46133357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann    return;
4624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
4634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  if (version < 2) {
4644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    return;
4654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
4664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t index = version - 1;
4674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t const* coordinates =
4684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      &(POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index][0]);
4694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t numCoordinate = 7;
4704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  for (int32_t i = 0; i < numCoordinate; i++) {
4714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    for (int32_t j = 0; j < numCoordinate; j++) {
4724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int32_t y = coordinates[i];
4734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      int32_t x = coordinates[j];
4744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (x == -1 || y == -1) {
4754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        continue;
4764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
4774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      if (IsEmpty(matrix->Get(x, y))) {
4784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann        EmbedPositionAdjustmentPattern(x - 2, y - 2, matrix, e);
47933357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann        if (e != BCExceptionNO)
48033357cad1fd1321a2b38d2963e2585f27ce980a2Philip P. Moltmann          return;
4814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann      }
4824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    }
4834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
4844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
4854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint32_t CBC_QRCoderMatrixUtil::FindMSBSet(int32_t value) {
4864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  int32_t numDigits = 0;
4874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  while (value != 0) {
4884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    value >>= 1;
4894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann    ++numDigits;
4904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  }
4914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann  return numDigits;
4924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}
4934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCBC_QRCoderMatrixUtil::CBC_QRCoderMatrixUtil() {}
4944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCBC_QRCoderMatrixUtil::~CBC_QRCoderMatrixUtil() {}
495