// 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*, 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 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 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 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 ByteString& content,
                     CBC_QRCoderBitVector* bits,
                     ByteString encoding,
                     int32_t& e) {
  for (size_t i = 0; i < content.GetLength(); i++)
    bits->AppendBits(content[i], 8);
}

void AppendKanjiBytes(const 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 ByteString& content,
                 CBC_QRCoderMode* mode,
                 CBC_QRCoderBitVector* bits,
                 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 && tmp >= 0 &&
          element1.second.GetLength() < static_cast<size_t>(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 && tmp >= 0 &&
          element1.second.GetLength() < static_cast<size_t>(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 && tmp >= 0 &&
          element1.second.GetLength() < static_cast<size_t>(tmp)) {
        element2.second = element1.second + element2.second;
        result->erase(result->begin() + i);
        i--;
        mergeNum++;
      }
    }
  }
  if (mergeNum != 0)
    MergeString(result, versionNum, e);
}

void SplitString(const ByteString& content,
                 std::vector<ModeStringPair>* result) {
  size_t 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;

  size_t 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 _FX_PLATFORM_ == _FX_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)});
  }
  if (index < content.GetLength())
    SplitString(content.Right(content.GetLength() - index), result);
}

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

  bool hasNumeric = false;
  bool hasAlphaNumeric = false;
  for (size_t 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 WideString& content,
                                const CBC_QRCoderErrorCorrectionLevel* ecLevel,
                                CBC_QRCoder* qrCode) {
  ByteString encoding = "utf8";
  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());
  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();
}
