// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
// Original code is licensed as follows:
/*
 * Copyright 2008 ZXing authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "fxbarcode/qrcode/BC_QRCoderEncoder.h"

#include <algorithm>
#include <memory>
#include <utility>

#include "fxbarcode/BC_UtilCodingConvert.h"
#include "fxbarcode/common/BC_CommonByteArray.h"
#include "fxbarcode/common/BC_CommonByteMatrix.h"
#include "fxbarcode/common/reedsolomon/BC_ReedSolomon.h"
#include "fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h"
#include "fxbarcode/qrcode/BC_QRCoder.h"
#include "fxbarcode/qrcode/BC_QRCoderBitVector.h"
#include "fxbarcode/qrcode/BC_QRCoderBlockPair.h"
#include "fxbarcode/qrcode/BC_QRCoderECBlocks.h"
#include "fxbarcode/qrcode/BC_QRCoderMaskUtil.h"
#include "fxbarcode/qrcode/BC_QRCoderMatrixUtil.h"
#include "fxbarcode/qrcode/BC_QRCoderMode.h"
#include "fxbarcode/qrcode/BC_QRCoderVersion.h"
#include "third_party/base/ptr_util.h"

using ModeStringPair = std::pair<CBC_QRCoderMode*, CFX_ByteString>;

namespace {

// This is a mapping for an ASCII table, starting at an index of 32.
const int8_t g_alphaNumericTable[] = {
    36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,  // 32-47
    0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  44, -1, -1, -1, -1, -1,  // 48-63
    -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,  // 64-79
    25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35};

int32_t GetAlphaNumericCode(int32_t code) {
  if (code < 32)
    return -1;
  size_t code_index = static_cast<size_t>(code - 32);
  if (code_index >= FX_ArraySize(g_alphaNumericTable))
    return -1;
  return g_alphaNumericTable[code_index];
}

void AppendNumericBytes(const CFX_ByteString& content,
                        CBC_QRCoderBitVector* bits,
                        int32_t& e) {
  int32_t length = content.GetLength();
  int32_t i = 0;
  while (i < length) {
    int32_t num1 = content[i] - '0';
    if (i + 2 < length) {
      int32_t num2 = content[i + 1] - '0';
      int32_t num3 = content[i + 2] - '0';
      bits->AppendBits(num1 * 100 + num2 * 10 + num3, 10);
      i += 3;
    } else if (i + 1 < length) {
      int32_t num2 = content[i + 1] - '0';
      bits->AppendBits(num1 * 10 + num2, 7);
      i += 2;
    } else {
      bits->AppendBits(num1, 4);
      i++;
    }
  }
}

void AppendAlphaNumericBytes(const CFX_ByteString& content,
                             CBC_QRCoderBitVector* bits,
                             int32_t& e) {
  int32_t length = content.GetLength();
  int32_t i = 0;
  while (i < length) {
    int32_t code1 = GetAlphaNumericCode(content[i]);
    if (code1 == -1) {
      e = BCExceptionInvalidateCharacter;
      return;
    }
    if (i + 1 < length) {
      int32_t code2 = GetAlphaNumericCode(content[i + 1]);
      if (code2 == -1) {
        e = BCExceptionInvalidateCharacter;
        return;
      }
      bits->AppendBits(code1 * 45 + code2, 11);
      i += 2;
    } else {
      bits->AppendBits(code1, 6);
      i++;
    }
  }
}

void AppendGBKBytes(const CFX_ByteString& content,
                    CBC_QRCoderBitVector* bits,
                    int32_t& e) {
  int32_t length = content.GetLength();
  uint32_t value = 0;
  for (int32_t i = 0; i < length; i += 2) {
    value = (uint32_t)(content[i] << 8 | content[i + 1]);
    if (value <= 0xAAFE && value >= 0xA1A1) {
      value -= 0xA1A1;
    } else if (value <= 0xFAFE && value >= 0xB0A1) {
      value -= 0xA6A1;
    } else {
      e = BCExceptionInvalidateCharacter;
      return;
    }
    value = (uint32_t)((value >> 8) * 0x60) + (uint32_t)(value & 0xff);
    bits->AppendBits(value, 13);
  }
}

void Append8BitBytes(const CFX_ByteString& content,
                     CBC_QRCoderBitVector* bits,
                     CFX_ByteString encoding,
                     int32_t& e) {
  for (FX_STRSIZE i = 0; i < content.GetLength(); i++)
    bits->AppendBits(content[i], 8);
}

void AppendKanjiBytes(const CFX_ByteString& content,
                      CBC_QRCoderBitVector* bits,
                      int32_t& e) {
  std::vector<uint8_t> bytes;
  uint32_t value = 0;
  for (size_t i = 0; i < bytes.size(); i += 2) {
    value = (uint32_t)((content[i] << 8) | content[i + 1]);
    if (value <= 0x9ffc && value >= 0x8140) {
      value -= 0x8140;
    } else if (value <= 0xebbf && value >= 0xe040) {
      value -= 0xc140;
    } else {
      e = BCExceptionInvalidateCharacter;
      return;
    }
    value = (uint32_t)((value >> 8) * 0xc0) + (uint32_t)(value & 0xff);
    bits->AppendBits(value, 13);
  }
}

void AppendModeInfo(CBC_QRCoderMode* mode, CBC_QRCoderBitVector* bits) {
  bits->AppendBits(mode->GetBits(), 4);
  if (mode == CBC_QRCoderMode::sGBK)
    bits->AppendBits(1, 4);
}

bool AppendLengthInfo(int32_t numLetters,
                      int32_t version,
                      CBC_QRCoderMode* mode,
                      CBC_QRCoderBitVector* bits) {
  int32_t e = BCExceptionNO;
  const auto* qcv = CBC_QRCoderVersion::GetVersionForNumber(version);
  if (!qcv)
    return false;
  int32_t numBits = mode->GetCharacterCountBits(qcv->GetVersionNumber(), e);
  if (e != BCExceptionNO)
    return false;
  if (numBits > ((1 << numBits) - 1))
    return true;

  if (mode == CBC_QRCoderMode::sGBK)
    bits->AppendBits(numLetters / 2, numBits);
  bits->AppendBits(numLetters, numBits);
  return true;
}

void AppendBytes(const CFX_ByteString& content,
                 CBC_QRCoderMode* mode,
                 CBC_QRCoderBitVector* bits,
                 CFX_ByteString encoding,
                 int32_t& e) {
  if (mode == CBC_QRCoderMode::sNUMERIC)
    AppendNumericBytes(content, bits, e);
  else if (mode == CBC_QRCoderMode::sALPHANUMERIC)
    AppendAlphaNumericBytes(content, bits, e);
  else if (mode == CBC_QRCoderMode::sBYTE)
    Append8BitBytes(content, bits, encoding, e);
  else if (mode == CBC_QRCoderMode::sKANJI)
    AppendKanjiBytes(content, bits, e);
  else if (mode == CBC_QRCoderMode::sGBK)
    AppendGBKBytes(content, bits, e);
  else
    e = BCExceptionUnsupportedMode;
}

bool InitQRCode(int32_t numInputBytes,
                const CBC_QRCoderErrorCorrectionLevel* ecLevel,
                CBC_QRCoderMode* mode,
                CBC_QRCoder* qrCode) {
  qrCode->SetECLevel(ecLevel);
  qrCode->SetMode(mode);
  for (int32_t i = 1; i <= CBC_QRCoderVersion::kMaxVersion; ++i) {
    const auto* version = CBC_QRCoderVersion::GetVersionForNumber(i);
    int32_t numBytes = version->GetTotalCodeWords();
    const auto* ecBlocks = version->GetECBlocksForLevel(*ecLevel);
    int32_t numEcBytes = ecBlocks->GetTotalECCodeWords();
    int32_t numRSBlocks = ecBlocks->GetNumBlocks();
    int32_t numDataBytes = numBytes - numEcBytes;
    if (numDataBytes >= numInputBytes + 3) {
      qrCode->SetVersion(i);
      qrCode->SetNumTotalBytes(numBytes);
      qrCode->SetNumDataBytes(numDataBytes);
      qrCode->SetNumRSBlocks(numRSBlocks);
      qrCode->SetNumECBytes(numEcBytes);
      qrCode->SetMatrixWidth(version->GetDimensionForVersion());
      return true;
    }
  }
  return false;
}

std::unique_ptr<CBC_CommonByteArray> GenerateECBytes(
    CBC_CommonByteArray* dataBytes,
    int32_t numEcBytesInBlock) {
  int32_t numDataBytes = dataBytes->Size();
  std::vector<int32_t> toEncode(numDataBytes + numEcBytesInBlock);
  for (int32_t i = 0; i < numDataBytes; ++i)
    toEncode[i] = dataBytes->At(i);
  CBC_ReedSolomonEncoder encode(CBC_ReedSolomonGF256::QRCodeField);
  encode.Init();
  if (!encode.Encode(&toEncode, numEcBytesInBlock))
    return nullptr;
  auto ecBytes = pdfium::MakeUnique<CBC_CommonByteArray>(numEcBytesInBlock);
  for (int32_t i = 0; i < numEcBytesInBlock; ++i)
    ecBytes->Set(i, toEncode[numDataBytes + i]);
  return ecBytes;
}

int32_t GetSpanByVersion(CBC_QRCoderMode* modeFirst,
                         CBC_QRCoderMode* modeSecond,
                         int32_t versionNum,
                         int32_t& e) {
  if (versionNum == 0)
    return 0;

  if (modeFirst == CBC_QRCoderMode::sALPHANUMERIC &&
      modeSecond == CBC_QRCoderMode::sBYTE) {
    if (versionNum >= 1 && versionNum <= 9)
      return 11;
    if (versionNum >= 10 && versionNum <= 26)
      return 15;
    if (versionNum >= 27 && versionNum <= CBC_QRCoderVersion::kMaxVersion)
      return 16;
    e = BCExceptionNoSuchVersion;
    return 0;
  }
  if (modeSecond == CBC_QRCoderMode::sALPHANUMERIC &&
      modeFirst == CBC_QRCoderMode::sNUMERIC) {
    if (versionNum >= 1 && versionNum <= 9)
      return 13;
    if (versionNum >= 10 && versionNum <= 26)
      return 15;
    if (versionNum >= 27 && versionNum <= CBC_QRCoderVersion::kMaxVersion)
      return 17;
    e = BCExceptionNoSuchVersion;
    return 0;
  }
  if (modeSecond == CBC_QRCoderMode::sBYTE &&
      modeFirst == CBC_QRCoderMode::sNUMERIC) {
    if (versionNum >= 1 && versionNum <= 9)
      return 6;
    if (versionNum >= 10 && versionNum <= 26)
      return 8;
    if (versionNum >= 27 && versionNum <= CBC_QRCoderVersion::kMaxVersion)
      return 9;
    e = BCExceptionNoSuchVersion;
    return 0;
  }
  return -1;
}

int32_t CalculateMaskPenalty(CBC_CommonByteMatrix* matrix) {
  return CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule1(matrix) +
         CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule2(matrix) +
         CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule3(matrix) +
         CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule4(matrix);
}

int32_t ChooseMaskPattern(CBC_QRCoderBitVector* bits,
                          const CBC_QRCoderErrorCorrectionLevel* ecLevel,
                          int32_t version,
                          CBC_CommonByteMatrix* matrix,
                          int32_t& e) {
  int32_t minPenalty = 65535;
  int32_t bestMaskPattern = -1;
  for (int32_t maskPattern = 0; maskPattern < CBC_QRCoder::kNumMaskPatterns;
       maskPattern++) {
    CBC_QRCoderMatrixUtil::BuildMatrix(bits, ecLevel, version, maskPattern,
                                       matrix, e);
    if (e != BCExceptionNO)
      return 0;
    int32_t penalty = CalculateMaskPenalty(matrix);
    if (penalty < minPenalty) {
      minPenalty = penalty;
      bestMaskPattern = maskPattern;
    }
  }
  return bestMaskPattern;
}

void GetNumDataBytesAndNumECBytesForBlockID(int32_t numTotalBytes,
                                            int32_t numDataBytes,
                                            int32_t numRSBlocks,
                                            int32_t blockID,
                                            int32_t& numDataBytesInBlock,
                                            int32_t& numECBytesInBlock) {
  if (blockID >= numRSBlocks)
    return;

  int32_t numRsBlocksInGroup2 = numTotalBytes % numRSBlocks;
  int32_t numRsBlocksInGroup1 = numRSBlocks - numRsBlocksInGroup2;
  int32_t numTotalBytesInGroup1 = numTotalBytes / numRSBlocks;
  int32_t numTotalBytesInGroup2 = numTotalBytesInGroup1 + 1;
  int32_t numDataBytesInGroup1 = numDataBytes / numRSBlocks;
  int32_t numDataBytesInGroup2 = numDataBytesInGroup1 + 1;
  int32_t numEcBytesInGroup1 = numTotalBytesInGroup1 - numDataBytesInGroup1;
  int32_t numEcBytesInGroup2 = numTotalBytesInGroup2 - numDataBytesInGroup2;
  if (blockID < numRsBlocksInGroup1) {
    numDataBytesInBlock = numDataBytesInGroup1;
    numECBytesInBlock = numEcBytesInGroup1;
  } else {
    numDataBytesInBlock = numDataBytesInGroup2;
    numECBytesInBlock = numEcBytesInGroup2;
  }
}

bool TerminateBits(int32_t numDataBytes, CBC_QRCoderBitVector* bits) {
  size_t capacity = numDataBytes << 3;
  if (bits->Size() > capacity)
    return false;

  for (int32_t i = 0; i < 4 && bits->Size() < capacity; ++i)
    bits->AppendBit(0);

  int32_t numBitsInLastByte = bits->Size() % 8;
  if (numBitsInLastByte > 0) {
    int32_t numPaddingBits = 8 - numBitsInLastByte;
    for (int32_t j = 0; j < numPaddingBits; ++j)
      bits->AppendBit(0);
  }

  if (bits->Size() % 8 != 0)
    return false;

  int32_t numPaddingBytes = numDataBytes - bits->sizeInBytes();
  for (int32_t k = 0; k < numPaddingBytes; ++k)
    bits->AppendBits(k % 2 ? 0x11 : 0xec, 8);
  return bits->Size() == capacity;
}

void MergeString(std::vector<ModeStringPair>* result,
                 int32_t versionNum,
                 int32_t& e) {
  size_t mergeNum = 0;
  for (size_t i = 0; i + 1 < result->size(); i++) {
    auto& element1 = (*result)[i];
    auto& element2 = (*result)[i + 1];
    if (element1.first == CBC_QRCoderMode::sALPHANUMERIC) {
      int32_t tmp = GetSpanByVersion(CBC_QRCoderMode::sALPHANUMERIC,
                                     CBC_QRCoderMode::sBYTE, versionNum, e);
      if (e != BCExceptionNO)
        return;
      if (element2.first == CBC_QRCoderMode::sBYTE &&
          element1.second.GetLength() < tmp) {
        element2.second = element1.second + element2.second;
        result->erase(result->begin() + i);
        i--;
        mergeNum++;
      }
    } else if (element1.first == CBC_QRCoderMode::sBYTE) {
      if (element2.first == CBC_QRCoderMode::sBYTE) {
        element1.second += element2.second;
        result->erase(result->begin() + i + 1);
        i--;
        mergeNum++;
      }
    } else if (element1.first == CBC_QRCoderMode::sNUMERIC) {
      int32_t tmp = GetSpanByVersion(CBC_QRCoderMode::sNUMERIC,
                                     CBC_QRCoderMode::sBYTE, versionNum, e);
      if (e != BCExceptionNO)
        return;
      if (element2.first == CBC_QRCoderMode::sBYTE &&
          element1.second.GetLength() < tmp) {
        element2.second = element1.second + element2.second;
        result->erase(result->begin() + i);
        i--;
        mergeNum++;
      }
      tmp = GetSpanByVersion(CBC_QRCoderMode::sNUMERIC,
                             CBC_QRCoderMode::sALPHANUMERIC, versionNum, e);
      if (e != BCExceptionNO)
        return;
      if (element2.first == CBC_QRCoderMode::sALPHANUMERIC &&
          element1.second.GetLength() < tmp) {
        element2.second = element1.second + element2.second;
        result->erase(result->begin() + i);
        i--;
        mergeNum++;
      }
    }
  }
  if (mergeNum != 0)
    MergeString(result, versionNum, e);
}

void SplitString(const CFX_ByteString& content,
                 std::vector<ModeStringPair>* result) {
  FX_STRSIZE index = 0;
  while (index < content.GetLength()) {
    uint8_t c = static_cast<uint8_t>(content[index]);
    if (!((c >= 0xA1 && c <= 0xAA) || (c >= 0xB0 && c <= 0xFA)))
      break;
    index += 2;
  }
  if (index)
    result->push_back({CBC_QRCoderMode::sGBK, content.Left(index)});
  if (index >= content.GetLength())
    return;

  FX_STRSIZE flag = index;
  while (GetAlphaNumericCode(content[index]) == -1 &&
         index < content.GetLength()) {
    uint8_t c = static_cast<uint8_t>(content[index]);
    if (((c >= 0xA1 && c <= 0xAA) || (c >= 0xB0 && c <= 0xFA)))
      break;
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    bool high = !!IsDBCSLeadByte(content[index]);
#else
    bool high = content[index] > 127;
#endif
    ++index;
    if (high)
      ++index;
  }
  if (index != flag) {
    result->push_back(
        {CBC_QRCoderMode::sBYTE, content.Mid(flag, index - flag)});
  }
  flag = index;
  if (index >= content.GetLength())
    return;

  while (index < content.GetLength() && isdigit(content[index]))
    ++index;

  if (index != flag) {
    result->push_back(
        {CBC_QRCoderMode::sNUMERIC, content.Mid(flag, index - flag)});
  }
  flag = index;
  if (index >= content.GetLength())
    return;

  while (index < content.GetLength() &&
         GetAlphaNumericCode(content[index]) != -1) {
    ++index;
  }
  if (index != flag) {
    result->push_back(
        {CBC_QRCoderMode::sALPHANUMERIC, content.Mid(flag, index - flag)});
  }
  flag = index;
  if (index < content.GetLength())
    SplitString(content.Right(content.GetLength() - index), result);
}

CBC_QRCoderMode* ChooseMode(const CFX_ByteString& content,
                            CFX_ByteString encoding) {
  if (encoding.Compare("SHIFT_JIS") == 0)
    return CBC_QRCoderMode::sKANJI;

  bool hasNumeric = false;
  bool hasAlphaNumeric = false;
  for (FX_STRSIZE i = 0; i < content.GetLength(); i++) {
    if (isdigit(content[i])) {
      hasNumeric = true;
    } else if (GetAlphaNumericCode(content[i]) != -1) {
      hasAlphaNumeric = true;
    } else {
      return CBC_QRCoderMode::sBYTE;
    }
  }
  if (hasAlphaNumeric)
    return CBC_QRCoderMode::sALPHANUMERIC;
  if (hasNumeric)
    return CBC_QRCoderMode::sNUMERIC;
  return CBC_QRCoderMode::sBYTE;
}

bool InterleaveWithECBytes(CBC_QRCoderBitVector* bits,
                           int32_t numTotalBytes,
                           int32_t numDataBytes,
                           int32_t numRSBlocks,
                           CBC_QRCoderBitVector* result) {
  ASSERT(numTotalBytes >= 0);
  ASSERT(numDataBytes >= 0);
  if (bits->sizeInBytes() != static_cast<size_t>(numDataBytes))
    return false;

  int32_t dataBytesOffset = 0;
  int32_t maxNumDataBytes = 0;
  int32_t maxNumEcBytes = 0;
  std::vector<CBC_QRCoderBlockPair> blocks(numRSBlocks);
  for (int32_t i = 0; i < numRSBlocks; i++) {
    int32_t numDataBytesInBlock;
    int32_t numEcBytesInBlosk;
    GetNumDataBytesAndNumECBytesForBlockID(numTotalBytes, numDataBytes,
                                           numRSBlocks, i, numDataBytesInBlock,
                                           numEcBytesInBlosk);
    auto dataBytes = pdfium::MakeUnique<CBC_CommonByteArray>();
    dataBytes->Set(bits->GetArray(), dataBytesOffset, numDataBytesInBlock);
    std::unique_ptr<CBC_CommonByteArray> ecBytes =
        GenerateECBytes(dataBytes.get(), numEcBytesInBlosk);
    if (!ecBytes)
      return false;

    maxNumDataBytes = std::max(maxNumDataBytes, dataBytes->Size());
    maxNumEcBytes = std::max(maxNumEcBytes, ecBytes->Size());
    blocks[i].SetData(std::move(dataBytes), std::move(ecBytes));
    dataBytesOffset += numDataBytesInBlock;
  }
  if (numDataBytes != dataBytesOffset)
    return false;

  for (int32_t x = 0; x < maxNumDataBytes; x++) {
    for (size_t j = 0; j < blocks.size(); j++) {
      const CBC_CommonByteArray* dataBytes = blocks[j].GetDataBytes();
      if (x < dataBytes->Size())
        result->AppendBits(dataBytes->At(x), 8);
    }
  }
  for (int32_t y = 0; y < maxNumEcBytes; y++) {
    for (size_t l = 0; l < blocks.size(); l++) {
      const CBC_CommonByteArray* ecBytes = blocks[l].GetErrorCorrectionBytes();
      if (y < ecBytes->Size())
        result->AppendBits(ecBytes->At(y), 8);
    }
  }
  return static_cast<size_t>(numTotalBytes) == result->sizeInBytes();
}

}  // namespace

CBC_QRCoderEncoder::CBC_QRCoderEncoder() {}

CBC_QRCoderEncoder::~CBC_QRCoderEncoder() {}

// static
bool CBC_QRCoderEncoder::Encode(const CFX_WideString& content,
                                const CBC_QRCoderErrorCorrectionLevel* ecLevel,
                                CBC_QRCoder* qrCode) {
  CFX_ByteString encoding = "utf8";
  CFX_ByteString utf8Data;
  CBC_UtilCodingConvert::UnicodeToUTF8(content, utf8Data);
  CBC_QRCoderMode* mode = ChooseMode(utf8Data, encoding);
  CBC_QRCoderBitVector dataBits;
  int32_t e = BCExceptionNO;
  AppendBytes(utf8Data, mode, &dataBits, encoding, e);
  if (e != BCExceptionNO)
    return false;
  int32_t numInputBytes = dataBits.sizeInBytes();
  if (!InitQRCode(numInputBytes, ecLevel, mode, qrCode))
    return false;
  CBC_QRCoderBitVector headerAndDataBits;
  AppendModeInfo(mode, &headerAndDataBits);
  int32_t numLetters = mode == CBC_QRCoderMode::sBYTE ? dataBits.sizeInBytes()
                                                      : content.GetLength();
  if (!AppendLengthInfo(numLetters, qrCode->GetVersion(), mode,
                        &headerAndDataBits)) {
    return false;
  }
  headerAndDataBits.AppendBitVector(&dataBits);
  if (!TerminateBits(qrCode->GetNumDataBytes(), &headerAndDataBits))
    return false;
  CBC_QRCoderBitVector finalBits;
  if (!InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(),
                             qrCode->GetNumDataBytes(),
                             qrCode->GetNumRSBlocks(), &finalBits)) {
    return false;
  }

  auto matrix = pdfium::MakeUnique<CBC_CommonByteMatrix>(
      qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth());
  matrix->Init();
  int32_t maskPattern = ChooseMaskPattern(
      &finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), matrix.get(), e);
  if (e != BCExceptionNO)
    return false;

  qrCode->SetMaskPattern(maskPattern);
  CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(),
                                     qrCode->GetVersion(),
                                     qrCode->GetMaskPattern(), matrix.get(), e);
  if (e != BCExceptionNO)
    return false;

  qrCode->SetMatrix(std::move(matrix));
  return qrCode->IsValid();
}
