summaryrefslogtreecommitdiff
path: root/fxbarcode/qrcode
diff options
context:
space:
mode:
authorDan Sinclair <dsinclair@chromium.org>2017-03-29 15:18:41 -0400
committerChromium commit bot <commit-bot@chromium.org>2017-03-29 21:01:07 +0000
commite778668fe92b8c60e0537ee48f79d5af6c1a2f1e (patch)
treece7ce115b6f7306a6363f4a3d26d0de2c5646aea /fxbarcode/qrcode
parentb929ab0886a2b0ceb701989ef126e5b0cabf6997 (diff)
downloadpdfium-e778668fe92b8c60e0537ee48f79d5af6c1a2f1e.tar.xz
Move xfa/fxbarcode fxbarcode/
Nothing in fxbarcode/ depends on XFA code. This CL moves xfa/fxbarcode to be fxbarcode/ and creates a static_library for fxbarcode which is depend on by the xfa library. Change-Id: I0b708737b07efb94b769a5238d92af92bc62880d Reviewed-on: https://pdfium-review.googlesource.com/3291 Reviewed-by: Tom Sepez <tsepez@chromium.org> Commit-Queue: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'fxbarcode/qrcode')
-rw-r--r--fxbarcode/qrcode/BC_QRCodeWriter.cpp122
-rw-r--r--fxbarcode/qrcode/BC_QRCodeWriter.h45
-rw-r--r--fxbarcode/qrcode/BC_QRCoder.cpp145
-rw-r--r--fxbarcode/qrcode/BC_QRCoder.h63
-rw-r--r--fxbarcode/qrcode/BC_QRCoderBitVector.cpp127
-rw-r--r--fxbarcode/qrcode/BC_QRCoderBitVector.h35
-rw-r--r--fxbarcode/qrcode/BC_QRCoderBlockPair.cpp44
-rw-r--r--fxbarcode/qrcode/BC_QRCoderBlockPair.h28
-rw-r--r--fxbarcode/qrcode/BC_QRCoderECB.cpp35
-rw-r--r--fxbarcode/qrcode/BC_QRCoderECB.h24
-rw-r--r--fxbarcode/qrcode/BC_QRCoderECBlocks.cpp63
-rw-r--r--fxbarcode/qrcode/BC_QRCoderECBlocks.h34
-rw-r--r--fxbarcode/qrcode/BC_QRCoderEncoder.cpp970
-rw-r--r--fxbarcode/qrcode/BC_QRCoderEncoder.h140
-rw-r--r--fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.cpp84
-rw-r--r--fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h41
-rw-r--r--fxbarcode/qrcode/BC_QRCoderMaskUtil.cpp198
-rw-r--r--fxbarcode/qrcode/BC_QRCoderMaskUtil.h27
-rw-r--r--fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp506
-rw-r--r--fxbarcode/qrcode/BC_QRCoderMatrixUtil.h87
-rw-r--r--fxbarcode/qrcode/BC_QRCoderMode.cpp174
-rw-r--r--fxbarcode/qrcode/BC_QRCoderMode.h53
-rw-r--r--fxbarcode/qrcode/BC_QRCoderVersion.cpp794
-rw-r--r--fxbarcode/qrcode/BC_QRCoderVersion.h57
24 files changed, 3896 insertions, 0 deletions
diff --git a/fxbarcode/qrcode/BC_QRCodeWriter.cpp b/fxbarcode/qrcode/BC_QRCodeWriter.cpp
new file mode 100644
index 0000000000..ac23462ed8
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCodeWriter.cpp
@@ -0,0 +1,122 @@
+// 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/BC_TwoDimWriter.h"
+#include "fxbarcode/common/BC_CommonByteMatrix.h"
+#include "fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h"
+#include "fxbarcode/qrcode/BC_QRCodeWriter.h"
+#include "fxbarcode/qrcode/BC_QRCoder.h"
+#include "fxbarcode/qrcode/BC_QRCoderEncoder.h"
+#include "fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
+#include "fxbarcode/qrcode/BC_QRCoderMode.h"
+#include "fxbarcode/qrcode/BC_QRCoderVersion.h"
+
+CBC_QRCodeWriter::CBC_QRCodeWriter() {
+ m_bFixedSize = true;
+ m_iCorrectLevel = 1;
+ m_iVersion = 0;
+}
+
+CBC_QRCodeWriter::~CBC_QRCodeWriter() {}
+
+void CBC_QRCodeWriter::ReleaseAll() {
+ delete CBC_ReedSolomonGF256::QRCodeField;
+ CBC_ReedSolomonGF256::QRCodeField = nullptr;
+ delete CBC_ReedSolomonGF256::DataMatrixField;
+ CBC_ReedSolomonGF256::DataMatrixField = nullptr;
+ CBC_QRCoderMode::Destroy();
+ CBC_QRCoderErrorCorrectionLevel::Destroy();
+ CBC_QRCoderVersion::Destroy();
+}
+
+bool CBC_QRCodeWriter::SetVersion(int32_t version) {
+ if (version < 0 || version > 40) {
+ return false;
+ }
+ m_iVersion = version;
+ return true;
+}
+
+bool CBC_QRCodeWriter::SetErrorCorrectionLevel(int32_t level) {
+ if (level < 0 || level > 3) {
+ return false;
+ }
+ m_iCorrectLevel = level;
+ return true;
+}
+
+uint8_t* CBC_QRCodeWriter::Encode(const CFX_WideString& contents,
+ int32_t ecLevel,
+ int32_t& outWidth,
+ int32_t& outHeight,
+ int32_t& e) {
+ CBC_QRCoderErrorCorrectionLevel* ec = nullptr;
+ switch (ecLevel) {
+ case 0:
+ ec = CBC_QRCoderErrorCorrectionLevel::L;
+ break;
+ case 1:
+ ec = CBC_QRCoderErrorCorrectionLevel::M;
+ break;
+ case 2:
+ ec = CBC_QRCoderErrorCorrectionLevel::Q;
+ break;
+ case 3:
+ ec = CBC_QRCoderErrorCorrectionLevel::H;
+ break;
+ default: {
+ e = BCExceptionUnSupportEclevel;
+ return nullptr;
+ }
+ }
+ CBC_QRCoder qr;
+ if (m_iVersion > 0 && m_iVersion < 41) {
+ CFX_ByteString byteStr = contents.UTF8Encode();
+ CBC_QRCoderEncoder::Encode(byteStr, ec, &qr, e, m_iVersion);
+ } else {
+ CBC_QRCoderEncoder::Encode(contents, ec, &qr, e);
+ }
+ if (e != BCExceptionNO)
+ return nullptr;
+ outWidth = qr.GetMatrixWidth();
+ outHeight = qr.GetMatrixWidth();
+ uint8_t* result = FX_Alloc2D(uint8_t, outWidth, outHeight);
+ FXSYS_memcpy(result, qr.GetMatrix()->GetArray(), outWidth * outHeight);
+ return result;
+}
+
+uint8_t* CBC_QRCodeWriter::Encode(const CFX_ByteString& contents,
+ BCFORMAT format,
+ int32_t& outWidth,
+ int32_t& outHeight,
+ int32_t hints,
+ int32_t& e) {
+ return nullptr;
+}
+
+uint8_t* CBC_QRCodeWriter::Encode(const CFX_ByteString& contents,
+ BCFORMAT format,
+ int32_t& outWidth,
+ int32_t& outHeight,
+ int32_t& e) {
+ return nullptr;
+}
diff --git a/fxbarcode/qrcode/BC_QRCodeWriter.h b/fxbarcode/qrcode/BC_QRCodeWriter.h
new file mode 100644
index 0000000000..185e10aa37
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCodeWriter.h
@@ -0,0 +1,45 @@
+// 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
+
+#ifndef FXBARCODE_QRCODE_BC_QRCODEWRITER_H_
+#define FXBARCODE_QRCODE_BC_QRCODEWRITER_H_
+
+#include "fxbarcode/BC_TwoDimWriter.h"
+
+class CBC_TwoDimWriter;
+class CBC_QRCodeWriter : public CBC_TwoDimWriter {
+ public:
+ CBC_QRCodeWriter();
+ ~CBC_QRCodeWriter() override;
+
+ uint8_t* Encode(const CFX_WideString& contents,
+ int32_t ecLevel,
+ int32_t& outWidth,
+ int32_t& outHeight,
+ int32_t& e);
+ uint8_t* Encode(const CFX_ByteString& contents,
+ BCFORMAT format,
+ int32_t& outWidth,
+ int32_t& outHeight,
+ int32_t hints,
+ int32_t& e);
+ uint8_t* Encode(const CFX_ByteString& contents,
+ BCFORMAT format,
+ int32_t& outWidth,
+ int32_t& outHeight,
+ int32_t& e);
+ bool SetVersion(int32_t version);
+
+ // CBC_TwoDimWriter
+ bool SetErrorCorrectionLevel(int32_t level) override;
+
+ static void ReleaseAll();
+
+ private:
+ int32_t m_iVersion;
+};
+
+#endif // FXBARCODE_QRCODE_BC_QRCODEWRITER_H_
diff --git a/fxbarcode/qrcode/BC_QRCoder.cpp b/fxbarcode/qrcode/BC_QRCoder.cpp
new file mode 100644
index 0000000000..93f0d00455
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoder.cpp
@@ -0,0 +1,145 @@
+// 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 <utility>
+
+#include "fxbarcode/common/BC_CommonByteMatrix.h"
+#include "fxbarcode/qrcode/BC_QRCoder.h"
+#include "fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
+#include "fxbarcode/qrcode/BC_QRCoderMode.h"
+#include "fxbarcode/utils.h"
+
+CBC_QRCoder::CBC_QRCoder()
+ : m_mode(nullptr),
+ m_ecLevel(nullptr),
+ m_version(-1),
+ m_matrixWidth(-1),
+ m_maskPattern(-1),
+ m_numTotalBytes(-1),
+ m_numDataBytes(-1),
+ m_numECBytes(-1),
+ m_numRSBlocks(-1) {}
+
+CBC_QRCoder::~CBC_QRCoder() {}
+
+CBC_QRCoderMode* CBC_QRCoder::GetMode() const {
+ return m_mode;
+}
+
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoder::GetECLevel() const {
+ return m_ecLevel;
+}
+
+int32_t CBC_QRCoder::GetVersion() const {
+ return m_version;
+}
+
+int32_t CBC_QRCoder::GetMatrixWidth() const {
+ return m_matrixWidth;
+}
+
+int32_t CBC_QRCoder::GetMaskPattern() const {
+ return m_maskPattern;
+}
+
+int32_t CBC_QRCoder::GetNumTotalBytes() const {
+ return m_numTotalBytes;
+}
+
+int32_t CBC_QRCoder::GetNumDataBytes() const {
+ return m_numDataBytes;
+}
+
+int32_t CBC_QRCoder::GetNumECBytes() const {
+ return m_numECBytes;
+}
+
+int32_t CBC_QRCoder::GetNumRSBlocks() const {
+ return m_numRSBlocks;
+}
+
+CBC_CommonByteMatrix* CBC_QRCoder::GetMatrix() const {
+ return m_matrix.get();
+}
+
+int32_t CBC_QRCoder::At(int32_t x, int32_t y, int32_t& e) {
+ int32_t value = m_matrix->Get(x, y);
+ if (!(value == 0 || value == 1)) {
+ e = BCExceptionValueMustBeEither0or1;
+ return 0;
+ }
+ return value;
+}
+
+bool CBC_QRCoder::IsValid() {
+ return m_mode && m_ecLevel && m_version != -1 && m_matrixWidth != -1 &&
+ m_maskPattern != -1 && m_numTotalBytes != -1 && m_numDataBytes != -1 &&
+ m_numECBytes != -1 && m_numRSBlocks != -1 &&
+ IsValidMaskPattern(m_maskPattern) &&
+ m_numTotalBytes == m_numDataBytes + m_numECBytes && m_matrix &&
+ m_matrixWidth == m_matrix->GetWidth() &&
+ m_matrix->GetWidth() == m_matrix->GetHeight();
+}
+
+void CBC_QRCoder::SetMode(CBC_QRCoderMode* value) {
+ m_mode = value;
+}
+
+void CBC_QRCoder::SetECLevel(CBC_QRCoderErrorCorrectionLevel* ecLevel) {
+ m_ecLevel = ecLevel;
+}
+
+void CBC_QRCoder::SetVersion(int32_t version) {
+ m_version = version;
+}
+
+void CBC_QRCoder::SetMatrixWidth(int32_t width) {
+ m_matrixWidth = width;
+}
+
+void CBC_QRCoder::SetMaskPattern(int32_t pattern) {
+ m_maskPattern = pattern;
+}
+
+void CBC_QRCoder::SetNumDataBytes(int32_t bytes) {
+ m_numDataBytes = bytes;
+}
+
+void CBC_QRCoder::SetNumTotalBytes(int32_t value) {
+ m_numTotalBytes = value;
+}
+
+void CBC_QRCoder::SetNumRSBlocks(int32_t block) {
+ m_numRSBlocks = block;
+}
+
+void CBC_QRCoder::SetNumECBytes(int32_t value) {
+ m_numECBytes = value;
+}
+
+bool CBC_QRCoder::IsValidMaskPattern(int32_t maskPattern) {
+ return maskPattern >= 0 && maskPattern < kNumMaskPatterns;
+}
+
+void CBC_QRCoder::SetMatrix(std::unique_ptr<CBC_CommonByteMatrix> pMatrix) {
+ m_matrix = std::move(pMatrix);
+}
diff --git a/fxbarcode/qrcode/BC_QRCoder.h b/fxbarcode/qrcode/BC_QRCoder.h
new file mode 100644
index 0000000000..0925a8e5cd
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoder.h
@@ -0,0 +1,63 @@
+// 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
+
+#ifndef FXBARCODE_QRCODE_BC_QRCODER_H_
+#define FXBARCODE_QRCODE_BC_QRCODER_H_
+
+#include <memory>
+
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRCoderMode;
+class CBC_CommonByteMatrix;
+
+class CBC_QRCoder {
+ public:
+ static constexpr int32_t kNumMaskPatterns = 8;
+
+ CBC_QRCoder();
+ virtual ~CBC_QRCoder();
+
+ static bool IsValidMaskPattern(int32_t maskPattern);
+
+ CBC_QRCoderMode* GetMode() const;
+ CBC_QRCoderErrorCorrectionLevel* GetECLevel() const;
+ int32_t GetVersion() const;
+ int32_t GetMatrixWidth() const;
+ int32_t GetMaskPattern() const;
+ int32_t GetNumTotalBytes() const;
+ int32_t GetNumDataBytes() const;
+ int32_t GetNumECBytes() const;
+ int32_t GetNumRSBlocks() const;
+ CBC_CommonByteMatrix* GetMatrix() const;
+
+ int32_t At(int32_t x, int32_t y, int32_t& e);
+ bool IsValid();
+
+ void SetMode(CBC_QRCoderMode* value);
+ void SetECLevel(CBC_QRCoderErrorCorrectionLevel* ecLevel);
+ void SetVersion(int32_t version);
+ void SetMatrixWidth(int32_t width);
+ void SetMaskPattern(int32_t pattern);
+ void SetNumDataBytes(int32_t bytes);
+ void SetNumTotalBytes(int32_t value);
+ void SetNumECBytes(int32_t value);
+ void SetNumRSBlocks(int32_t block);
+ void SetMatrix(std::unique_ptr<CBC_CommonByteMatrix> pMatrix);
+
+ private:
+ CBC_QRCoderMode* m_mode;
+ CBC_QRCoderErrorCorrectionLevel* m_ecLevel;
+ int32_t m_version;
+ int32_t m_matrixWidth;
+ int32_t m_maskPattern;
+ int32_t m_numTotalBytes;
+ int32_t m_numDataBytes;
+ int32_t m_numECBytes;
+ int32_t m_numRSBlocks;
+ std::unique_ptr<CBC_CommonByteMatrix> m_matrix;
+};
+
+#endif // FXBARCODE_QRCODE_BC_QRCODER_H_
diff --git a/fxbarcode/qrcode/BC_QRCoderBitVector.cpp b/fxbarcode/qrcode/BC_QRCoderBitVector.cpp
new file mode 100644
index 0000000000..08222093a5
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderBitVector.cpp
@@ -0,0 +1,127 @@
+// 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 2007 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 "core/fxcrt/fx_memory.h"
+#include "fxbarcode/qrcode/BC_QRCoderBitVector.h"
+#include "fxbarcode/utils.h"
+
+CBC_QRCoderBitVector::CBC_QRCoderBitVector() {
+ m_sizeInBits = 0;
+ m_size = 32;
+}
+void CBC_QRCoderBitVector::Init() {
+ m_array = FX_Alloc(uint8_t, m_size);
+}
+CBC_QRCoderBitVector::~CBC_QRCoderBitVector() {
+ FX_Free(m_array);
+}
+void CBC_QRCoderBitVector::Clear() {
+ FX_Free(m_array);
+ m_sizeInBits = 0;
+ m_size = 32;
+ m_array = FX_Alloc(uint8_t, m_size);
+}
+int32_t CBC_QRCoderBitVector::At(int32_t index, int32_t& e) {
+ if (index < 0 || index >= m_sizeInBits) {
+ e = BCExceptionBadIndexException;
+ return 0;
+ }
+ int32_t value = m_array[index >> 3] & 0xff;
+ return (value >> (7 - (index & 0x7))) & 1;
+}
+int32_t CBC_QRCoderBitVector::sizeInBytes() {
+ return (m_sizeInBits + 7) >> 3;
+}
+int32_t CBC_QRCoderBitVector::Size() {
+ return m_sizeInBits;
+}
+void CBC_QRCoderBitVector::AppendBit(int32_t bit, int32_t& e) {
+ if (!(bit == 0 || bit == 1)) {
+ e = BCExceptionBadValueException;
+ return;
+ }
+ int32_t numBitsInLastByte = m_sizeInBits & 0x7;
+ if (numBitsInLastByte == 0) {
+ AppendByte(0);
+ m_sizeInBits -= 8;
+ }
+ m_array[m_sizeInBits >> 3] |= (bit << (7 - numBitsInLastByte));
+ ++m_sizeInBits;
+}
+void CBC_QRCoderBitVector::AppendBits(int32_t value,
+ int32_t numBits,
+ int32_t& e) {
+ if (numBits < 0 || numBits > 32) {
+ e = BCExceptionBadNumBitsException;
+ return;
+ }
+ int32_t numBitsLeft = numBits;
+ while (numBitsLeft > 0) {
+ if ((m_sizeInBits & 0x7) == 0 && numBitsLeft >= 8) {
+ int32_t newByte = (value >> (numBitsLeft - 8)) & 0xff;
+ AppendByte(newByte);
+ numBitsLeft -= 8;
+ } else {
+ int32_t bit = (value >> (numBitsLeft - 1)) & 1;
+ AppendBit(bit, e);
+ if (e != BCExceptionNO)
+ return;
+ --numBitsLeft;
+ }
+ }
+}
+void CBC_QRCoderBitVector::AppendBitVector(CBC_QRCoderBitVector* bits,
+ int32_t& e) {
+ int32_t size = bits->Size();
+ for (int32_t i = 0; i < size; i++) {
+ int32_t num = bits->At(i, e);
+ if (e != BCExceptionNO)
+ return;
+ AppendBit(num, e);
+ if (e != BCExceptionNO)
+ return;
+ }
+}
+void CBC_QRCoderBitVector::XOR(CBC_QRCoderBitVector* other, int32_t& e) {
+ if (m_sizeInBits != other->Size()) {
+ e = BCExceptioncanNotOperatexorOperator;
+ return;
+ }
+ int32_t sizeInBytes = (m_sizeInBits + 7) >> 3;
+ for (int32_t i = 0; i < sizeInBytes; ++i) {
+ m_array[i] ^= (other->GetArray())[i];
+ }
+}
+uint8_t* CBC_QRCoderBitVector::GetArray() {
+ return m_array;
+}
+void CBC_QRCoderBitVector::AppendByte(int32_t value) {
+ if ((m_sizeInBits >> 3) == m_size) {
+ uint8_t* newArray = FX_Alloc(uint8_t, m_size << 1);
+ FXSYS_memcpy(newArray, m_array, m_size);
+ FX_Free(m_array);
+ m_array = newArray;
+ m_size = m_size << 1;
+ }
+ m_array[m_sizeInBits >> 3] = (uint8_t)value;
+ m_sizeInBits += 8;
+}
diff --git a/fxbarcode/qrcode/BC_QRCoderBitVector.h b/fxbarcode/qrcode/BC_QRCoderBitVector.h
new file mode 100644
index 0000000000..59c4360c1e
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderBitVector.h
@@ -0,0 +1,35 @@
+// 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
+
+#ifndef FXBARCODE_QRCODE_BC_QRCODERBITVECTOR_H_
+#define FXBARCODE_QRCODE_BC_QRCODERBITVECTOR_H_
+
+#include <stdint.h>
+
+class CBC_QRCoderBitVector {
+ private:
+ int32_t m_sizeInBits;
+ uint8_t* m_array;
+ int32_t m_size;
+
+ void AppendByte(int32_t value);
+
+ public:
+ CBC_QRCoderBitVector();
+ virtual ~CBC_QRCoderBitVector();
+ int32_t At(int32_t index, int32_t& e);
+ int32_t Size();
+ int32_t sizeInBytes();
+ void AppendBit(int32_t bit, int32_t& e);
+ void AppendBits(int32_t value, int32_t numBits, int32_t& e);
+ void AppendBitVector(CBC_QRCoderBitVector* bits, int32_t& e);
+ void XOR(CBC_QRCoderBitVector* other, int32_t& e);
+ uint8_t* GetArray();
+ void Clear();
+ virtual void Init();
+};
+
+#endif // FXBARCODE_QRCODE_BC_QRCODERBITVECTOR_H_
diff --git a/fxbarcode/qrcode/BC_QRCoderBlockPair.cpp b/fxbarcode/qrcode/BC_QRCoderBlockPair.cpp
new file mode 100644
index 0000000000..9d2a1f8375
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderBlockPair.cpp
@@ -0,0 +1,44 @@
+// 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_QRCoderBlockPair.h"
+
+#include <utility>
+
+#include "fxbarcode/common/BC_CommonByteArray.h"
+
+CBC_QRCoderBlockPair::CBC_QRCoderBlockPair(
+ std::unique_ptr<CBC_CommonByteArray> data,
+ std::unique_ptr<CBC_CommonByteArray> errorCorrection)
+ : m_dataBytes(std::move(data)),
+ m_errorCorrectionBytes(std::move(errorCorrection)) {}
+
+CBC_QRCoderBlockPair::~CBC_QRCoderBlockPair() {}
+
+const CBC_CommonByteArray* CBC_QRCoderBlockPair::GetDataBytes() const {
+ return m_dataBytes.get();
+}
+
+const CBC_CommonByteArray* CBC_QRCoderBlockPair::GetErrorCorrectionBytes()
+ const {
+ return m_errorCorrectionBytes.get();
+}
diff --git a/fxbarcode/qrcode/BC_QRCoderBlockPair.h b/fxbarcode/qrcode/BC_QRCoderBlockPair.h
new file mode 100644
index 0000000000..7c24d9f5ec
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderBlockPair.h
@@ -0,0 +1,28 @@
+// 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
+
+#ifndef FXBARCODE_QRCODE_BC_QRCODERBLOCKPAIR_H_
+#define FXBARCODE_QRCODE_BC_QRCODERBLOCKPAIR_H_
+
+#include <memory>
+
+class CBC_CommonByteArray;
+
+class CBC_QRCoderBlockPair {
+ public:
+ CBC_QRCoderBlockPair(std::unique_ptr<CBC_CommonByteArray> data,
+ std::unique_ptr<CBC_CommonByteArray> errorCorrection);
+ virtual ~CBC_QRCoderBlockPair();
+
+ const CBC_CommonByteArray* GetDataBytes() const;
+ const CBC_CommonByteArray* GetErrorCorrectionBytes() const;
+
+ private:
+ std::unique_ptr<CBC_CommonByteArray> m_dataBytes;
+ std::unique_ptr<CBC_CommonByteArray> m_errorCorrectionBytes;
+};
+
+#endif // FXBARCODE_QRCODE_BC_QRCODERBLOCKPAIR_H_
diff --git a/fxbarcode/qrcode/BC_QRCoderECB.cpp b/fxbarcode/qrcode/BC_QRCoderECB.cpp
new file mode 100644
index 0000000000..65fbe33447
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderECB.cpp
@@ -0,0 +1,35 @@
+// 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 2007 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_QRCoderECB.h"
+
+CBC_QRCoderECB::CBC_QRCoderECB(int32_t count, int32_t dataCodeWords) {
+ m_dataCodeWords = dataCodeWords;
+ m_count = count;
+}
+CBC_QRCoderECB::~CBC_QRCoderECB() {}
+int32_t CBC_QRCoderECB::GetCount() {
+ return m_count;
+}
+int32_t CBC_QRCoderECB::GetDataCodeWords() {
+ return m_dataCodeWords;
+}
diff --git a/fxbarcode/qrcode/BC_QRCoderECB.h b/fxbarcode/qrcode/BC_QRCoderECB.h
new file mode 100644
index 0000000000..b774a3c19c
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderECB.h
@@ -0,0 +1,24 @@
+// 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
+
+#ifndef FXBARCODE_QRCODE_BC_QRCODERECB_H_
+#define FXBARCODE_QRCODE_BC_QRCODERECB_H_
+
+#include <stdint.h>
+
+class CBC_QRCoderECB {
+ private:
+ int32_t m_count;
+ int32_t m_dataCodeWords;
+
+ public:
+ CBC_QRCoderECB(int32_t count, int32_t dataCodeWords);
+ virtual ~CBC_QRCoderECB();
+ int32_t GetCount();
+ int32_t GetDataCodeWords();
+};
+
+#endif // FXBARCODE_QRCODE_BC_QRCODERECB_H_
diff --git a/fxbarcode/qrcode/BC_QRCoderECBlocks.cpp b/fxbarcode/qrcode/BC_QRCoderECBlocks.cpp
new file mode 100644
index 0000000000..e07197df93
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderECBlocks.cpp
@@ -0,0 +1,63 @@
+// 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 2007 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_QRCoderECB.h"
+#include "fxbarcode/qrcode/BC_QRCoderECBlocks.h"
+
+CBC_QRCoderECBlocks::CBC_QRCoderECBlocks(int32_t ecCodeWordsPerBlock,
+ CBC_QRCoderECB* ecBlocks)
+ : m_ecCodeWordsPerBlock(ecCodeWordsPerBlock) {
+ m_ecBlocksArray.push_back(ecBlocks);
+}
+
+CBC_QRCoderECBlocks::CBC_QRCoderECBlocks(int32_t ecCodeWordsPerBlock,
+ CBC_QRCoderECB* ecBlocks1,
+ CBC_QRCoderECB* ecBlocks2)
+ : m_ecCodeWordsPerBlock(ecCodeWordsPerBlock) {
+ m_ecBlocksArray.push_back(ecBlocks1);
+ m_ecBlocksArray.push_back(ecBlocks2);
+}
+
+CBC_QRCoderECBlocks::~CBC_QRCoderECBlocks() {
+ for (size_t i = 0; i < m_ecBlocksArray.size(); i++)
+ delete m_ecBlocksArray[i];
+}
+
+int32_t CBC_QRCoderECBlocks::GetECCodeWordsPerBlock() const {
+ return m_ecCodeWordsPerBlock;
+}
+
+int32_t CBC_QRCoderECBlocks::GetNumBlocks() const {
+ int32_t total = 0;
+ for (size_t i = 0; i < m_ecBlocksArray.size(); i++)
+ total += m_ecBlocksArray[i]->GetCount();
+
+ return total;
+}
+
+int32_t CBC_QRCoderECBlocks::GetTotalECCodeWords() const {
+ return m_ecCodeWordsPerBlock * GetNumBlocks();
+}
+
+std::vector<CBC_QRCoderECB*>* CBC_QRCoderECBlocks::GetECBlocks() {
+ return &m_ecBlocksArray;
+}
diff --git a/fxbarcode/qrcode/BC_QRCoderECBlocks.h b/fxbarcode/qrcode/BC_QRCoderECBlocks.h
new file mode 100644
index 0000000000..bf4f76dc84
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderECBlocks.h
@@ -0,0 +1,34 @@
+// 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
+
+#ifndef FXBARCODE_QRCODE_BC_QRCODERECBLOCKS_H_
+#define FXBARCODE_QRCODE_BC_QRCODERECBLOCKS_H_
+
+#include <vector>
+
+#include "core/fxcrt/fx_basic.h"
+
+class CBC_QRCoderECB;
+
+class CBC_QRCoderECBlocks {
+ public:
+ CBC_QRCoderECBlocks(int32_t ecCodeWordsPerBlock, CBC_QRCoderECB* ecBlocks);
+ CBC_QRCoderECBlocks(int32_t ecCodeWordsPerBlock,
+ CBC_QRCoderECB* ecBlocks1,
+ CBC_QRCoderECB* ecBlocks2);
+ ~CBC_QRCoderECBlocks();
+
+ int32_t GetECCodeWordsPerBlock() const;
+ int32_t GetNumBlocks() const;
+ int32_t GetTotalECCodeWords() const;
+ std::vector<CBC_QRCoderECB*>* GetECBlocks();
+
+ private:
+ int32_t m_ecCodeWordsPerBlock;
+ std::vector<CBC_QRCoderECB*> m_ecBlocksArray;
+};
+
+#endif // FXBARCODE_QRCODE_BC_QRCODERECBLOCKS_H_
diff --git a/fxbarcode/qrcode/BC_QRCoderEncoder.cpp b/fxbarcode/qrcode/BC_QRCoderEncoder.cpp
new file mode 100644
index 0000000000..b07b700c51
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderEncoder.cpp
@@ -0,0 +1,970 @@
+// 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"
+
+namespace {
+
+const int8_t g_alphaNumericTable[] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1,
+ -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1};
+
+} // namespace
+
+CBC_QRCoderEncoder::CBC_QRCoderEncoder() {}
+
+CBC_QRCoderEncoder::~CBC_QRCoderEncoder() {}
+
+void CBC_QRCoderEncoder::Encode(const CFX_ByteString& content,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoder* qrCode,
+ int32_t& e,
+ int32_t versionSpecify) {
+ if (versionSpecify == 0) {
+ EncodeWithAutoVersion(content, ecLevel, qrCode, e);
+ if (e != BCExceptionNO)
+ return;
+ } else if (versionSpecify > 0 && versionSpecify <= 40) {
+ EncodeWithSpecifyVersion(content, ecLevel, qrCode, versionSpecify, e);
+ if (e != BCExceptionNO)
+ return;
+ } else {
+ e = BCExceptionVersionMust1_40;
+ if (e != BCExceptionNO)
+ return;
+ }
+}
+
+void CBC_QRCoderEncoder::AppendECI(CBC_QRCoderBitVector* bits) {}
+
+void CBC_QRCoderEncoder::AppendDataModeLenghInfo(
+ const std::vector<std::pair<CBC_QRCoderMode*, CFX_ByteString>>&
+ splitResults,
+ CBC_QRCoderBitVector& headerAndDataBits,
+ CBC_QRCoderMode* tempMode,
+ CBC_QRCoder* qrCode,
+ CFX_ByteString& encoding,
+ int32_t& e) {
+ for (const auto& splitResult : splitResults) {
+ tempMode = splitResult.first;
+ if (tempMode == CBC_QRCoderMode::sGBK) {
+ AppendModeInfo(tempMode, &headerAndDataBits, e);
+ if (e != BCExceptionNO)
+ return;
+ AppendLengthInfo(splitResult.second.GetLength(), qrCode->GetVersion(),
+ tempMode, &headerAndDataBits, e);
+ if (e != BCExceptionNO)
+ return;
+ AppendBytes(splitResult.second, tempMode, &headerAndDataBits, encoding,
+ e);
+ if (e != BCExceptionNO)
+ return;
+ } else if (tempMode == CBC_QRCoderMode::sBYTE) {
+ std::vector<uint8_t> bytes;
+ CBC_UtilCodingConvert::LocaleToUtf8(splitResult.second, bytes);
+ AppendModeInfo(tempMode, &headerAndDataBits, e);
+ if (e != BCExceptionNO)
+ return;
+ AppendLengthInfo(bytes.size(), qrCode->GetVersion(), tempMode,
+ &headerAndDataBits, e);
+ if (e != BCExceptionNO)
+ return;
+ Append8BitBytes(bytes, &headerAndDataBits, e);
+ if (e != BCExceptionNO)
+ return;
+ } else if (tempMode == CBC_QRCoderMode::sALPHANUMERIC) {
+ AppendModeInfo(tempMode, &headerAndDataBits, e);
+ if (e != BCExceptionNO)
+ return;
+ AppendLengthInfo(splitResult.second.GetLength(), qrCode->GetVersion(),
+ tempMode, &headerAndDataBits, e);
+ if (e != BCExceptionNO)
+ return;
+ AppendBytes(splitResult.second, tempMode, &headerAndDataBits, encoding,
+ e);
+ if (e != BCExceptionNO)
+ return;
+ } else if (tempMode == CBC_QRCoderMode::sNUMERIC) {
+ AppendModeInfo(tempMode, &headerAndDataBits, e);
+ if (e != BCExceptionNO)
+ return;
+ AppendLengthInfo(splitResult.second.GetLength(), qrCode->GetVersion(),
+ tempMode, &headerAndDataBits, e);
+ if (e != BCExceptionNO)
+ return;
+ AppendBytes(splitResult.second, tempMode, &headerAndDataBits, encoding,
+ e);
+ if (e != BCExceptionNO)
+ return;
+ } else {
+ e = BCExceptionUnknown;
+ return;
+ }
+ }
+}
+
+void CBC_QRCoderEncoder::SplitString(
+ const CFX_ByteString& content,
+ std::vector<std::pair<CBC_QRCoderMode*, CFX_ByteString>>* result) {
+ int32_t index = 0, flag = 0;
+ while (
+ (((uint8_t)content[index] >= 0xA1 && (uint8_t)content[index] <= 0xAA) ||
+ ((uint8_t)content[index] >= 0xB0 && (uint8_t)content[index] <= 0xFA)) &&
+ (index < content.GetLength())) {
+ index += 2;
+ }
+ if (index != flag) {
+ result->push_back({CBC_QRCoderMode::sGBK, content.Mid(flag, index - flag)});
+ }
+ flag = index;
+ if (index >= content.GetLength()) {
+ return;
+ }
+ while (
+ GetAlphaNumericCode((uint8_t)content[index]) == -1 &&
+ !(((uint8_t)content[index] >= 0xA1 && (uint8_t)content[index] <= 0xAA) ||
+ ((uint8_t)content[index] >= 0xB0 && (uint8_t)content[index] <= 0xFA)) &&
+ (index < content.GetLength())) {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+ if (IsDBCSLeadByte((uint8_t)content[index]))
+#else
+ if ((uint8_t)content[index] > 127)
+#endif
+ {
+ index += 2;
+ } else {
+ index++;
+ }
+ }
+ if (index != flag) {
+ result->push_back(
+ {CBC_QRCoderMode::sBYTE, content.Mid(flag, index - flag)});
+ }
+ flag = index;
+ if (index >= content.GetLength()) {
+ return;
+ }
+ while (FXSYS_Isdigit((uint8_t)content[index]) &&
+ (index < content.GetLength())) {
+ index++;
+ }
+ if (index != flag) {
+ result->push_back(
+ {CBC_QRCoderMode::sNUMERIC, content.Mid(flag, index - flag)});
+ }
+ flag = index;
+ if (index >= content.GetLength()) {
+ return;
+ }
+ while (GetAlphaNumericCode((uint8_t)content[index]) != -1 &&
+ (index < content.GetLength())) {
+ index++;
+ }
+ if (index != flag) {
+ result->push_back(
+ {CBC_QRCoderMode::sALPHANUMERIC, content.Mid(flag, index - flag)});
+ }
+ flag = index;
+ if (index < content.GetLength())
+ SplitString(content.Mid(index, content.GetLength() - index), result);
+}
+
+int32_t CBC_QRCoderEncoder::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 <= 40)
+ 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 <= 40)
+ 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 <= 40)
+ return 9;
+ e = BCExceptionNoSuchVersion;
+ return 0;
+ }
+ return -1;
+}
+
+void CBC_QRCoderEncoder::MergeString(
+ std::vector<std::pair<CBC_QRCoderMode*, CFX_ByteString>>* 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) {
+ return;
+ }
+ MergeString(result, versionNum, e);
+ if (e != BCExceptionNO)
+ return;
+}
+
+void CBC_QRCoderEncoder::InitQRCode(int32_t numInputBytes,
+ int32_t versionNumber,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoderMode* mode,
+ CBC_QRCoder* qrCode,
+ int32_t& e) {
+ qrCode->SetECLevel(ecLevel);
+ qrCode->SetMode(mode);
+ CBC_QRCoderVersion* version =
+ CBC_QRCoderVersion::GetVersionForNumber(versionNumber, e);
+ if (e != BCExceptionNO)
+ return;
+ int32_t numBytes = version->GetTotalCodeWords();
+ CBC_QRCoderECBlocks* ecBlocks = version->GetECBlocksForLevel(ecLevel);
+ int32_t numEcBytes = ecBlocks->GetTotalECCodeWords();
+ int32_t numRSBlocks = ecBlocks->GetNumBlocks();
+ int32_t numDataBytes = numBytes - numEcBytes;
+ if (numDataBytes < numInputBytes + 3) {
+ e = BCExceptionCannotFindBlockInfo;
+ return;
+ }
+ qrCode->SetVersion(versionNumber);
+ qrCode->SetNumTotalBytes(numBytes);
+ qrCode->SetNumDataBytes(numDataBytes);
+ qrCode->SetNumRSBlocks(numRSBlocks);
+ qrCode->SetNumECBytes(numEcBytes);
+ qrCode->SetMatrixWidth(version->GetDimensionForVersion());
+}
+
+void CBC_QRCoderEncoder::EncodeWithSpecifyVersion(
+ const CFX_ByteString& content,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoder* qrCode,
+ int32_t versionSpecify,
+ int32_t& e) {
+ CFX_ByteString encoding = "utf8";
+ CBC_QRCoderMode* mode = CBC_QRCoderMode::sBYTE;
+ std::vector<std::pair<CBC_QRCoderMode*, CFX_ByteString>> splitResult;
+ CBC_QRCoderBitVector dataBits;
+ dataBits.Init();
+ SplitString(content, &splitResult);
+ MergeString(&splitResult, versionSpecify, e);
+ if (e != BCExceptionNO)
+ return;
+ CBC_QRCoderMode* tempMode = nullptr;
+ for (const auto& result : splitResult) {
+ AppendBytes(result.second, result.first, &dataBits, encoding, e);
+ if (e != BCExceptionNO)
+ return;
+ }
+ int32_t numInputBytes = dataBits.sizeInBytes();
+ CBC_QRCoderBitVector headerAndDataBits;
+ headerAndDataBits.Init();
+ InitQRCode(numInputBytes, versionSpecify, ecLevel, mode, qrCode, e);
+ if (e != BCExceptionNO)
+ return;
+
+ AppendDataModeLenghInfo(splitResult, headerAndDataBits, tempMode, qrCode,
+ encoding, e);
+ if (e != BCExceptionNO)
+ return;
+
+ numInputBytes = headerAndDataBits.sizeInBytes();
+ TerminateBits(qrCode->GetNumDataBytes(), &headerAndDataBits, e);
+ if (e != BCExceptionNO)
+ return;
+
+ CBC_QRCoderBitVector finalBits;
+ finalBits.Init();
+ InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(),
+ qrCode->GetNumDataBytes(), qrCode->GetNumRSBlocks(),
+ &finalBits, e);
+ if (e != BCExceptionNO)
+ return;
+
+ std::unique_ptr<CBC_CommonByteMatrix> matrix(new CBC_CommonByteMatrix(
+ qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth()));
+ matrix->Init();
+ int32_t maskPattern = ChooseMaskPattern(
+ &finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), matrix.get(), e);
+ if (e != BCExceptionNO)
+ return;
+
+ qrCode->SetMaskPattern(maskPattern);
+ CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(),
+ qrCode->GetVersion(),
+ qrCode->GetMaskPattern(), matrix.get(), e);
+ if (e != BCExceptionNO)
+ return;
+
+ qrCode->SetMatrix(std::move(matrix));
+ if (!qrCode->IsValid())
+ e = BCExceptionInvalidQRCode;
+}
+
+void CBC_QRCoderEncoder::EncodeWithAutoVersion(
+ const CFX_ByteString& content,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoder* qrCode,
+ int32_t& e) {
+ CFX_ByteString encoding = "utf8";
+ CBC_QRCoderMode* mode = CBC_QRCoderMode::sBYTE;
+ std::vector<std::pair<CBC_QRCoderMode*, CFX_ByteString>> splitResult;
+ CBC_QRCoderBitVector dataBits;
+ dataBits.Init();
+ SplitString(content, &splitResult);
+ MergeString(&splitResult, 8, e);
+ if (e != BCExceptionNO)
+ return;
+ CBC_QRCoderMode* tempMode = nullptr;
+ for (const auto& result : splitResult) {
+ AppendBytes(result.second, result.first, &dataBits, encoding, e);
+ if (e != BCExceptionNO)
+ return;
+ }
+ int32_t numInputBytes = dataBits.sizeInBytes();
+ InitQRCode(numInputBytes, ecLevel, mode, qrCode, e);
+ if (e != BCExceptionNO)
+ return;
+ CBC_QRCoderBitVector headerAndDataBits;
+ headerAndDataBits.Init();
+ tempMode = nullptr;
+ int32_t versionNum = qrCode->GetVersion();
+sign:
+ AppendDataModeLenghInfo(splitResult, headerAndDataBits, tempMode, qrCode,
+ encoding, e);
+ if (e != BCExceptionNO) {
+ goto catchException;
+ }
+ numInputBytes = headerAndDataBits.sizeInBytes();
+ TerminateBits(qrCode->GetNumDataBytes(), &headerAndDataBits, e);
+ if (e != BCExceptionNO) {
+ goto catchException;
+ }
+catchException:
+ if (e != BCExceptionNO) {
+ int32_t e1 = BCExceptionNO;
+ InitQRCode(numInputBytes, ecLevel, mode, qrCode, e1);
+ if (e1 != BCExceptionNO) {
+ e = e1;
+ return;
+ }
+ versionNum++;
+ if (versionNum <= 40) {
+ headerAndDataBits.Clear();
+ e = BCExceptionNO;
+ goto sign;
+ } else {
+ return;
+ }
+ }
+
+ CBC_QRCoderBitVector finalBits;
+ finalBits.Init();
+ InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(),
+ qrCode->GetNumDataBytes(), qrCode->GetNumRSBlocks(),
+ &finalBits, e);
+ if (e != BCExceptionNO)
+ return;
+
+ std::unique_ptr<CBC_CommonByteMatrix> matrix(new CBC_CommonByteMatrix(
+ qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth()));
+ matrix->Init();
+ int32_t maskPattern = ChooseMaskPattern(
+ &finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), matrix.get(), e);
+ if (e != BCExceptionNO)
+ return;
+
+ qrCode->SetMaskPattern(maskPattern);
+ CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(),
+ qrCode->GetVersion(),
+ qrCode->GetMaskPattern(), matrix.get(), e);
+ if (e != BCExceptionNO)
+ return qrCode->SetMatrix(std::move(matrix));
+
+ if (!qrCode->IsValid())
+ e = BCExceptionInvalidQRCode;
+}
+
+void CBC_QRCoderEncoder::Encode(const CFX_WideString& content,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoder* qrCode,
+ int32_t& e) {
+ CFX_ByteString encoding = "utf8";
+ CFX_ByteString utf8Data;
+ CBC_UtilCodingConvert::UnicodeToUTF8(content, utf8Data);
+ CBC_QRCoderMode* mode = ChooseMode(utf8Data, encoding);
+ CBC_QRCoderBitVector dataBits;
+ dataBits.Init();
+ AppendBytes(utf8Data, mode, &dataBits, encoding, e);
+ if (e != BCExceptionNO)
+ return;
+ int32_t numInputBytes = dataBits.sizeInBytes();
+ InitQRCode(numInputBytes, ecLevel, mode, qrCode, e);
+ if (e != BCExceptionNO)
+ return;
+ CBC_QRCoderBitVector headerAndDataBits;
+ headerAndDataBits.Init();
+ AppendModeInfo(mode, &headerAndDataBits, e);
+ if (e != BCExceptionNO)
+ return;
+ int32_t numLetters = mode == CBC_QRCoderMode::sBYTE ? dataBits.sizeInBytes()
+ : content.GetLength();
+ AppendLengthInfo(numLetters, qrCode->GetVersion(), mode, &headerAndDataBits,
+ e);
+ if (e != BCExceptionNO)
+ return;
+ headerAndDataBits.AppendBitVector(&dataBits, e);
+ if (e != BCExceptionNO)
+ return TerminateBits(qrCode->GetNumDataBytes(), &headerAndDataBits, e);
+ if (e != BCExceptionNO)
+ return;
+ CBC_QRCoderBitVector finalBits;
+ finalBits.Init();
+ InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(),
+ qrCode->GetNumDataBytes(), qrCode->GetNumRSBlocks(),
+ &finalBits, e);
+ if (e != BCExceptionNO)
+ return;
+
+ std::unique_ptr<CBC_CommonByteMatrix> matrix(new CBC_CommonByteMatrix(
+ qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth()));
+ matrix->Init();
+ int32_t maskPattern = ChooseMaskPattern(
+ &finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), matrix.get(), e);
+ if (e != BCExceptionNO)
+ return;
+
+ qrCode->SetMaskPattern(maskPattern);
+ CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(),
+ qrCode->GetVersion(),
+ qrCode->GetMaskPattern(), matrix.get(), e);
+ if (e != BCExceptionNO)
+ return qrCode->SetMatrix(std::move(matrix));
+
+ if (!qrCode->IsValid())
+ e = BCExceptionInvalidQRCode;
+}
+
+void CBC_QRCoderEncoder::TerminateBits(int32_t numDataBytes,
+ CBC_QRCoderBitVector* bits,
+ int32_t& e) {
+ int32_t capacity = numDataBytes << 3;
+ if (bits->Size() > capacity) {
+ e = BCExceptionDataTooMany;
+ return;
+ }
+ for (int32_t i = 0; i < 4 && bits->Size() < capacity; ++i) {
+ bits->AppendBit(0, e);
+ if (e != BCExceptionNO)
+ return;
+ }
+ 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, e);
+ if (e != BCExceptionNO)
+ return;
+ }
+ }
+ if (bits->Size() % 8 != 0) {
+ e = BCExceptionDigitLengthMustBe8;
+ return;
+ }
+ int32_t numPaddingBytes = numDataBytes - bits->sizeInBytes();
+ for (int32_t k = 0; k < numPaddingBytes; ++k) {
+ if (k % 2 == 0) {
+ bits->AppendBits(0xec, 8, e);
+ if (e != BCExceptionNO)
+ return;
+ } else {
+ bits->AppendBits(0x11, 8, e);
+ if (e != BCExceptionNO)
+ return;
+ }
+ }
+ if (bits->Size() != capacity)
+ e = BCExceptionBitsNotEqualCacity;
+}
+
+int32_t CBC_QRCoderEncoder::ChooseMaskPattern(
+ CBC_QRCoderBitVector* bits,
+ 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;
+}
+
+int32_t CBC_QRCoderEncoder::CalculateMaskPenalty(CBC_CommonByteMatrix* matrix) {
+ int32_t penalty = 0;
+ penalty += CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule1(matrix);
+ penalty += CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule2(matrix);
+ penalty += CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule3(matrix);
+ penalty += CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule4(matrix);
+ return penalty;
+}
+
+CBC_QRCoderMode* CBC_QRCoderEncoder::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 (int32_t i = 0; i < content.GetLength(); i++) {
+ if (isdigit((uint8_t)content[i])) {
+ hasNumeric = true;
+ } else if (GetAlphaNumericCode((uint8_t)content[i]) != -1) {
+ hasAlphaNumeric = true;
+ } else {
+ return CBC_QRCoderMode::sBYTE;
+ }
+ }
+ if (hasAlphaNumeric) {
+ return CBC_QRCoderMode::sALPHANUMERIC;
+ } else if (hasNumeric) {
+ return CBC_QRCoderMode::sNUMERIC;
+ }
+ return CBC_QRCoderMode::sBYTE;
+}
+
+int32_t CBC_QRCoderEncoder::GetAlphaNumericCode(int32_t code) {
+ return (code >= 0 && code < 96) ? g_alphaNumericTable[code] : -1;
+}
+
+void CBC_QRCoderEncoder::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;
+}
+
+void CBC_QRCoderEncoder::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, e);
+ if (e != BCExceptionNO)
+ return;
+ i += 3;
+ } else if (i + 1 < length) {
+ int32_t num2 = content[i + 1] - '0';
+ bits->AppendBits(num1 * 10 + num2, 7, e);
+ if (e != BCExceptionNO)
+ return;
+ i += 2;
+ } else {
+ bits->AppendBits(num1, 4, e);
+ if (e != BCExceptionNO)
+ return;
+ i++;
+ }
+ }
+}
+
+void CBC_QRCoderEncoder::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, e);
+ if (e != BCExceptionNO)
+ return;
+ i += 2;
+ } else {
+ bits->AppendBits(code1, 6, e);
+ if (e != BCExceptionNO)
+ return;
+ i++;
+ }
+ }
+}
+
+void CBC_QRCoderEncoder::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)((uint8_t)content[i] << 8 | (uint8_t)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, e);
+ if (e != BCExceptionNO)
+ return;
+ }
+}
+
+void CBC_QRCoderEncoder::Append8BitBytes(const CFX_ByteString& content,
+ CBC_QRCoderBitVector* bits,
+ CFX_ByteString encoding,
+ int32_t& e) {
+ for (int32_t i = 0; i < content.GetLength(); i++) {
+ bits->AppendBits(content[i], 8, e);
+ if (e != BCExceptionNO)
+ return;
+ }
+}
+
+void CBC_QRCoderEncoder::Append8BitBytes(std::vector<uint8_t>& bytes,
+ CBC_QRCoderBitVector* bits,
+ int32_t& e) {
+ for (size_t i = 0; i < bytes.size(); i++) {
+ bits->AppendBits(bytes[i], 8, e);
+ if (e != BCExceptionNO)
+ return;
+ }
+}
+
+void CBC_QRCoderEncoder::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)((uint8_t)(content[i] << 8) | (uint8_t)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, e);
+ if (e != BCExceptionNO)
+ return;
+ }
+}
+
+void CBC_QRCoderEncoder::InitQRCode(int32_t numInputBytes,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoderMode* mode,
+ CBC_QRCoder* qrCode,
+ int32_t& e) {
+ qrCode->SetECLevel(ecLevel);
+ qrCode->SetMode(mode);
+ for (int32_t versionNum = 1; versionNum <= 40; versionNum++) {
+ CBC_QRCoderVersion* version =
+ CBC_QRCoderVersion::GetVersionForNumber(versionNum, e);
+ if (e != BCExceptionNO)
+ return;
+ int32_t numBytes = version->GetTotalCodeWords();
+ CBC_QRCoderECBlocks* 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(versionNum);
+ qrCode->SetNumTotalBytes(numBytes);
+ qrCode->SetNumDataBytes(numDataBytes);
+ qrCode->SetNumRSBlocks(numRSBlocks);
+ qrCode->SetNumECBytes(numEcBytes);
+ qrCode->SetMatrixWidth(version->GetDimensionForVersion());
+ return;
+ }
+ }
+ e = BCExceptionCannotFindBlockInfo;
+}
+
+void CBC_QRCoderEncoder::AppendModeInfo(CBC_QRCoderMode* mode,
+ CBC_QRCoderBitVector* bits,
+ int32_t& e) {
+ bits->AppendBits(mode->GetBits(), 4, e);
+ if (mode == CBC_QRCoderMode::sGBK)
+ bits->AppendBits(1, 4, e);
+}
+
+void CBC_QRCoderEncoder::AppendLengthInfo(int32_t numLetters,
+ int32_t version,
+ CBC_QRCoderMode* mode,
+ CBC_QRCoderBitVector* bits,
+ int32_t& e) {
+ CBC_QRCoderVersion* qcv = CBC_QRCoderVersion::GetVersionForNumber(version, e);
+ if (e != BCExceptionNO)
+ return;
+ int32_t numBits = mode->GetCharacterCountBits(qcv, e);
+ if (e != BCExceptionNO)
+ return;
+ if (numBits > ((1 << numBits) - 1)) {
+ return;
+ }
+ if (mode == CBC_QRCoderMode::sGBK) {
+ bits->AppendBits(numLetters / 2, numBits, e);
+ if (e != BCExceptionNO)
+ return;
+ }
+ bits->AppendBits(numLetters, numBits, e);
+}
+
+void CBC_QRCoderEncoder::InterleaveWithECBytes(CBC_QRCoderBitVector* bits,
+ int32_t numTotalBytes,
+ int32_t numDataBytes,
+ int32_t numRSBlocks,
+ CBC_QRCoderBitVector* result,
+ int32_t& e) {
+ if (bits->sizeInBytes() != numDataBytes) {
+ e = BCExceptionBitsBytesNotMatch;
+ return;
+ }
+ int32_t dataBytesOffset = 0;
+ int32_t maxNumDataBytes = 0;
+ int32_t maxNumEcBytes = 0;
+ std::vector<CBC_QRCoderBlockPair*> blocks;
+ int32_t i;
+ for (i = 0; i < numRSBlocks; i++) {
+ int32_t numDataBytesInBlock;
+ int32_t numEcBytesInBlosk;
+ GetNumDataBytesAndNumECBytesForBlockID(numTotalBytes, numDataBytes,
+ numRSBlocks, i, numDataBytesInBlock,
+ numEcBytesInBlosk);
+ std::unique_ptr<CBC_CommonByteArray> dataBytes(new CBC_CommonByteArray);
+ dataBytes->Set(bits->GetArray(), dataBytesOffset, numDataBytesInBlock);
+ std::unique_ptr<CBC_CommonByteArray> ecBytes(
+ GenerateECBytes(dataBytes.get(), numEcBytesInBlosk, e));
+ if (e != BCExceptionNO)
+ return;
+ maxNumDataBytes = std::max(maxNumDataBytes, dataBytes->Size());
+ maxNumEcBytes = std::max(maxNumEcBytes, ecBytes->Size());
+ blocks.push_back(
+ new CBC_QRCoderBlockPair(std::move(dataBytes), std::move(ecBytes)));
+ dataBytesOffset += numDataBytesInBlock;
+ }
+ if (numDataBytes != dataBytesOffset) {
+ e = BCExceptionBytesNotMatchOffset;
+ return;
+ }
+ 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, e);
+ if (e != BCExceptionNO)
+ return;
+ }
+ }
+ }
+ 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, e);
+ if (e != BCExceptionNO)
+ return;
+ }
+ }
+ }
+ for (size_t k = 0; k < blocks.size(); k++) {
+ delete blocks[k];
+ }
+ if (numTotalBytes != result->sizeInBytes())
+ e = BCExceptionSizeInBytesDiffer;
+}
+
+void CBC_QRCoderEncoder::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;
+ }
+}
+
+CBC_CommonByteArray* CBC_QRCoderEncoder::GenerateECBytes(
+ CBC_CommonByteArray* dataBytes,
+ int32_t numEcBytesInBlock,
+ int32_t& e) {
+ 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();
+ encode.Encode(&toEncode, numEcBytesInBlock, e);
+ if (e != BCExceptionNO)
+ return nullptr;
+ CBC_CommonByteArray* ecBytes = new CBC_CommonByteArray(numEcBytesInBlock);
+ for (int32_t j = 0; j < numEcBytesInBlock; j++) {
+ ecBytes->Set(j, toEncode[numDataBytes + j]);
+ }
+ return ecBytes;
+}
diff --git a/fxbarcode/qrcode/BC_QRCoderEncoder.h b/fxbarcode/qrcode/BC_QRCoderEncoder.h
new file mode 100644
index 0000000000..f46a64e9a9
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderEncoder.h
@@ -0,0 +1,140 @@
+// 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
+
+#ifndef FXBARCODE_QRCODE_BC_QRCODERENCODER_H_
+#define FXBARCODE_QRCODE_BC_QRCODERENCODER_H_
+
+#include <utility>
+#include <vector>
+
+#include "core/fxcrt/fx_basic.h"
+#include "core/fxcrt/fx_string.h"
+
+class CBC_QRCoder;
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRCoderMode;
+class CBC_QRCoderBitVector;
+class CBC_CommonByteArray;
+class CBC_CommonByteMatrix;
+
+class CBC_QRCoderEncoder {
+ public:
+ CBC_QRCoderEncoder();
+ virtual ~CBC_QRCoderEncoder();
+
+ static void Encode(const CFX_ByteString& content,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoder* qrCode,
+ int32_t& e,
+ int32_t versionSpecify = 0);
+ static void Encode(const CFX_WideString& content,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoder* qrCode,
+ int32_t& e);
+ static void EncodeWithSpecifyVersion(const CFX_ByteString& content,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoder* qrCode,
+ int32_t versionSpecify,
+ int32_t& e);
+ static void EncodeWithAutoVersion(const CFX_ByteString& content,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoder* qrCode,
+ int32_t& e);
+ static CBC_QRCoderMode* ChooseMode(const CFX_ByteString& content,
+ CFX_ByteString encoding);
+ static int32_t GetAlphaNumericCode(int32_t code);
+ static void AppendECI(CBC_QRCoderBitVector* bits);
+ static void AppendBytes(const CFX_ByteString& content,
+ CBC_QRCoderMode* mode,
+ CBC_QRCoderBitVector* bits,
+ CFX_ByteString encoding,
+ int32_t& e);
+ static void AppendNumericBytes(const CFX_ByteString& content,
+ CBC_QRCoderBitVector* bits,
+ int32_t& e);
+ static void AppendAlphaNumericBytes(const CFX_ByteString& content,
+ CBC_QRCoderBitVector* bits,
+ int32_t& e);
+ static void Append8BitBytes(const CFX_ByteString& content,
+ CBC_QRCoderBitVector* bits,
+ CFX_ByteString encoding,
+ int32_t& e);
+ static void Append8BitBytes(std::vector<uint8_t>& bytes,
+ CBC_QRCoderBitVector* bits,
+ int32_t& e);
+ static void AppendKanjiBytes(const CFX_ByteString& content,
+ CBC_QRCoderBitVector* bits,
+ int32_t& e);
+ static void AppendGBKBytes(const CFX_ByteString& content,
+ CBC_QRCoderBitVector* bits,
+ int32_t& e);
+ static void InitQRCode(int32_t numInputBytes,
+ int32_t versionNumber,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoderMode* mode,
+ CBC_QRCoder* qrCode,
+ int32_t& e);
+ static void InitQRCode(int32_t numInputBytes,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoderMode* mode,
+ CBC_QRCoder* qrCode,
+ int32_t& e);
+ static void AppendModeInfo(CBC_QRCoderMode* mode,
+ CBC_QRCoderBitVector* bits,
+ int32_t& e);
+ static void AppendLengthInfo(int32_t numLetters,
+ int32_t version,
+ CBC_QRCoderMode* mode,
+ CBC_QRCoderBitVector* bits,
+ int32_t& e);
+
+ static void InterleaveWithECBytes(CBC_QRCoderBitVector* bits,
+ int32_t numTotalBytes,
+ int32_t numDataBytes,
+ int32_t numRSBlocks,
+ CBC_QRCoderBitVector* result,
+ int32_t& e);
+ static void GetNumDataBytesAndNumECBytesForBlockID(
+ int32_t numTotalBytes,
+ int32_t numDataBytes,
+ int32_t numRSBlocks,
+ int32_t blockID,
+ int32_t& numDataBytesInBlock,
+ int32_t& numECBytesInBlocks);
+ static CBC_CommonByteArray* GenerateECBytes(CBC_CommonByteArray* dataBytes,
+ int32_t numEcBytesInBlock,
+ int32_t& e);
+ static int32_t ChooseMaskPattern(CBC_QRCoderBitVector* bits,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ int32_t version,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e);
+ static int32_t CalculateMaskPenalty(CBC_CommonByteMatrix* matrix);
+ static void TerminateBits(int32_t numDataBytes,
+ CBC_QRCoderBitVector* bits,
+ int32_t& e);
+ static int32_t GetSpanByVersion(CBC_QRCoderMode* modeFirst,
+ CBC_QRCoderMode* modeSecond,
+ int32_t versionNum,
+ int32_t& e);
+ static void MergeString(
+ std::vector<std::pair<CBC_QRCoderMode*, CFX_ByteString>>* result,
+ int32_t versionNum,
+ int32_t& e);
+ static void SplitString(
+ const CFX_ByteString& content,
+ std::vector<std::pair<CBC_QRCoderMode*, CFX_ByteString>>* result);
+ static void AppendDataModeLenghInfo(
+ const std::vector<std::pair<CBC_QRCoderMode*, CFX_ByteString>>&
+ splitResult,
+ CBC_QRCoderBitVector& headerAndDataBits,
+ CBC_QRCoderMode* tempMode,
+ CBC_QRCoder* qrCode,
+ CFX_ByteString& encoding,
+ int32_t& e);
+};
+
+#endif // FXBARCODE_QRCODE_BC_QRCODERENCODER_H_
diff --git a/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.cpp b/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.cpp
new file mode 100644
index 0000000000..6fb3233705
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.cpp
@@ -0,0 +1,84 @@
+// 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 2007 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_QRCoderErrorCorrectionLevel.h"
+
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::L = nullptr;
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::M = nullptr;
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::Q = nullptr;
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::H = nullptr;
+
+CBC_QRCoderErrorCorrectionLevel::CBC_QRCoderErrorCorrectionLevel(
+ int32_t ordinal,
+ int32_t bits,
+ const char* name)
+ : m_ordinal(ordinal), m_bits(bits), m_name(name) {}
+
+CBC_QRCoderErrorCorrectionLevel::~CBC_QRCoderErrorCorrectionLevel() {}
+
+void CBC_QRCoderErrorCorrectionLevel::Initialize() {
+ L = new CBC_QRCoderErrorCorrectionLevel(0, 0x01, "L");
+ M = new CBC_QRCoderErrorCorrectionLevel(1, 0x00, "M");
+ Q = new CBC_QRCoderErrorCorrectionLevel(2, 0x03, "Q");
+ H = new CBC_QRCoderErrorCorrectionLevel(3, 0x02, "H");
+}
+
+void CBC_QRCoderErrorCorrectionLevel::Finalize() {
+ delete L;
+ delete M;
+ delete Q;
+ delete H;
+}
+
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::ForBits(
+ int32_t bits) {
+ switch (bits) {
+ case 0x00:
+ return M;
+ case 0x01:
+ return L;
+ case 0x02:
+ return H;
+ case 0x03:
+ return Q;
+ default:
+ return nullptr;
+ }
+}
+void CBC_QRCoderErrorCorrectionLevel::Destroy() {
+ if (L) {
+ delete CBC_QRCoderErrorCorrectionLevel::L;
+ L = nullptr;
+ }
+ if (M) {
+ delete CBC_QRCoderErrorCorrectionLevel::M;
+ M = nullptr;
+ }
+ if (H) {
+ delete CBC_QRCoderErrorCorrectionLevel::H;
+ H = nullptr;
+ }
+ if (Q) {
+ delete CBC_QRCoderErrorCorrectionLevel::Q;
+ Q = nullptr;
+ }
+}
diff --git a/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h b/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h
new file mode 100644
index 0000000000..e153c64395
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h
@@ -0,0 +1,41 @@
+// 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
+
+#ifndef FXBARCODE_QRCODE_BC_QRCODERERRORCORRECTIONLEVEL_H_
+#define FXBARCODE_QRCODE_BC_QRCODERERRORCORRECTIONLEVEL_H_
+
+#include "core/fxcrt/fx_string.h"
+
+class CBC_QRCoderErrorCorrectionLevel {
+ public:
+ static CBC_QRCoderErrorCorrectionLevel* L;
+ static CBC_QRCoderErrorCorrectionLevel* M;
+ static CBC_QRCoderErrorCorrectionLevel* Q;
+ static CBC_QRCoderErrorCorrectionLevel* H;
+
+ static void Initialize();
+ static void Finalize();
+ static void Destroy();
+ static CBC_QRCoderErrorCorrectionLevel* ForBits(int32_t bits);
+
+ ~CBC_QRCoderErrorCorrectionLevel();
+
+ int32_t Ordinal() const { return m_ordinal; }
+ int32_t GetBits() const { return m_bits; }
+ CFX_ByteString GetName() const { return m_name; }
+
+ private:
+ CBC_QRCoderErrorCorrectionLevel(int32_t ordinal,
+ int32_t bits,
+ const char* name);
+ CBC_QRCoderErrorCorrectionLevel();
+
+ int32_t m_ordinal;
+ int32_t m_bits;
+ CFX_ByteString m_name;
+};
+
+#endif // FXBARCODE_QRCODE_BC_QRCODERERRORCORRECTIONLEVEL_H_
diff --git a/fxbarcode/qrcode/BC_QRCoderMaskUtil.cpp b/fxbarcode/qrcode/BC_QRCoderMaskUtil.cpp
new file mode 100644
index 0000000000..cdf1e4caf9
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderMaskUtil.cpp
@@ -0,0 +1,198 @@
+// 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/common/BC_CommonByteMatrix.h"
+#include "fxbarcode/qrcode/BC_QRCoder.h"
+#include "fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
+#include "fxbarcode/qrcode/BC_QRCoderMaskUtil.h"
+#include "fxbarcode/utils.h"
+
+CBC_QRCoderMaskUtil::CBC_QRCoderMaskUtil() {}
+CBC_QRCoderMaskUtil::~CBC_QRCoderMaskUtil() {}
+int32_t CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule1(
+ CBC_CommonByteMatrix* matrix) {
+ return ApplyMaskPenaltyRule1Internal(matrix, true) +
+ ApplyMaskPenaltyRule1Internal(matrix, false);
+}
+
+int32_t CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule2(
+ CBC_CommonByteMatrix* matrix) {
+ int32_t penalty = 0;
+ uint8_t* array = matrix->GetArray();
+ int32_t width = matrix->GetWidth();
+ int32_t height = matrix->GetHeight();
+ for (int32_t y = 0; y < height - 1; y++) {
+ for (int32_t x = 0; x < width - 1; x++) {
+ int32_t value = array[y * width + x];
+ if (value == array[y * width + x + 1] &&
+ value == array[(y + 1) * width + x] &&
+ value == array[(y + 1) * width + x + 1]) {
+ penalty++;
+ }
+ }
+ }
+ return 3 * penalty;
+}
+
+int32_t CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule3(
+ CBC_CommonByteMatrix* matrix) {
+ int32_t penalty = 0;
+ uint8_t* array = matrix->GetArray();
+ int32_t width = matrix->GetWidth();
+ int32_t height = matrix->GetHeight();
+ for (int32_t y = 0; y < height; ++y) {
+ for (int32_t x = 0; x < width; ++x) {
+ if (x == 0 &&
+ ((y >= 0 && y <= 6) || (y >= height - 7 && y <= height - 1))) {
+ continue;
+ }
+ if (x == width - 7 && (y >= 0 && y <= 6)) {
+ continue;
+ }
+ if (y == 0 &&
+ ((x >= 0 && x <= 6) || (x >= width - 7 && x <= width - 1))) {
+ continue;
+ }
+ if (y == height - 7 && (x >= 0 && x <= 6)) {
+ continue;
+ }
+ if (x + 6 < width && array[y * width + x] == 1 &&
+ array[y * width + x + 1] == 0 && array[y * width + x + 2] == 1 &&
+ array[y * width + x + 3] == 1 && array[y * width + x + 4] == 1 &&
+ array[y * width + x + 5] == 0 && array[y * width + x + 6] == 1 &&
+ ((x + 10 < width && array[y * width + x + 7] == 0 &&
+ array[y * width + x + 8] == 0 && array[y * width + x + 9] == 0 &&
+ array[y * width + x + 10] == 0) ||
+ (x - 4 >= 0 && array[y * width + x - 1] == 0 &&
+ array[y * width + x - 2] == 0 && array[y * width + x - 3] == 0 &&
+ array[y * width + x - 4] == 0))) {
+ penalty += 40;
+ }
+ if (y + 6 < height && array[y * width + x] == 1 &&
+ array[(y + 1) * width + x] == 0 && array[(y + 2) * width + x] == 1 &&
+ array[(y + 3) * width + x] == 1 && array[(y + 4) * width + x] == 1 &&
+ array[(y + 5) * width + x] == 0 && array[(y + 6) * width + x] == 1 &&
+ ((y + 10 < height && array[(y + 7) * width + x] == 0 &&
+ array[(y + 8) * width + x] == 0 &&
+ array[(y + 9) * width + x] == 0 &&
+ array[(y + 10) * width + x] == 0) ||
+ (y - 4 >= 0 && array[(y - 1) * width + x] == 0 &&
+ array[(y - 2) * width + x] == 0 &&
+ array[(y - 3) * width + x] == 0 &&
+ array[(y - 4) * width + x] == 0))) {
+ penalty += 40;
+ }
+ }
+ }
+ return penalty;
+}
+int32_t CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule4(
+ CBC_CommonByteMatrix* matrix) {
+ int32_t numDarkCells = 0;
+ uint8_t* array = matrix->GetArray();
+ int32_t width = matrix->GetWidth();
+ int32_t height = matrix->GetHeight();
+ for (int32_t y = 0; y < height; ++y) {
+ for (int32_t x = 0; x < width; ++x) {
+ if (array[y * width + x] == 1) {
+ numDarkCells += 1;
+ }
+ }
+ }
+ int32_t numTotalCells = matrix->GetHeight() * matrix->GetWidth();
+ double darkRatio = (double)numDarkCells / numTotalCells;
+ return abs((int32_t)(darkRatio * 100 - 50) / 5) * 5 * 10;
+}
+bool CBC_QRCoderMaskUtil::GetDataMaskBit(int32_t maskPattern,
+ int32_t x,
+ int32_t y,
+ int32_t& e) {
+ if (!CBC_QRCoder::IsValidMaskPattern(maskPattern)) {
+ e = (BCExceptionInvalidateMaskPattern);
+ return false;
+ }
+ int32_t intermediate = 0, temp = 0;
+ switch (maskPattern) {
+ case 0:
+ intermediate = (y + x) & 0x1;
+ break;
+ case 1:
+ intermediate = y & 0x1;
+ break;
+ case 2:
+ intermediate = x % 3;
+ break;
+ case 3:
+ intermediate = (y + x) % 3;
+ break;
+ case 4:
+ intermediate = ((y >> 1) + (x / 3)) & 0x1;
+ break;
+ case 5:
+ temp = y * x;
+ intermediate = (temp & 0x1) + (temp % 3);
+ break;
+ case 6:
+ temp = y * x;
+ intermediate = (((temp & 0x1) + (temp % 3)) & 0x1);
+ break;
+ case 7:
+ temp = y * x;
+ intermediate = (((temp % 3) + ((y + x) & 0x1)) & 0x1);
+ break;
+ default: {
+ e = BCExceptionInvalidateMaskPattern;
+ return false;
+ }
+ }
+ return intermediate == 0;
+}
+int32_t CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule1Internal(
+ CBC_CommonByteMatrix* matrix,
+ bool isHorizontal) {
+ int32_t penalty = 0;
+ int32_t numSameBitCells = 0;
+ int32_t prevBit = -1;
+ int32_t width = matrix->GetWidth();
+ int32_t height = matrix->GetHeight();
+ int32_t iLimit = isHorizontal ? height : width;
+ int32_t jLimit = isHorizontal ? width : height;
+ uint8_t* array = matrix->GetArray();
+ for (int32_t i = 0; i < iLimit; ++i) {
+ for (int32_t j = 0; j < jLimit; ++j) {
+ int32_t bit = isHorizontal ? array[i * width + j] : array[j * width + i];
+ if (bit == prevBit) {
+ numSameBitCells += 1;
+ if (numSameBitCells == 5) {
+ penalty += 3;
+ } else if (numSameBitCells > 5) {
+ penalty += 1;
+ }
+ } else {
+ numSameBitCells = 1;
+ prevBit = bit;
+ }
+ }
+ numSameBitCells = 0;
+ }
+ return penalty;
+}
diff --git a/fxbarcode/qrcode/BC_QRCoderMaskUtil.h b/fxbarcode/qrcode/BC_QRCoderMaskUtil.h
new file mode 100644
index 0000000000..63fccbb8e4
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderMaskUtil.h
@@ -0,0 +1,27 @@
+// 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
+
+#ifndef FXBARCODE_QRCODE_BC_QRCODERMASKUTIL_H_
+#define FXBARCODE_QRCODE_BC_QRCODERMASKUTIL_H_
+class CBC_CommonByteMatrix;
+class CBC_QRCoderMaskUtil {
+ public:
+ CBC_QRCoderMaskUtil();
+ virtual ~CBC_QRCoderMaskUtil();
+ static bool GetDataMaskBit(int32_t maskPattern,
+ int32_t x,
+ int32_t y,
+ int32_t& e);
+
+ static int32_t ApplyMaskPenaltyRule1(CBC_CommonByteMatrix* matrix);
+ static int32_t ApplyMaskPenaltyRule2(CBC_CommonByteMatrix* matrix);
+ static int32_t ApplyMaskPenaltyRule3(CBC_CommonByteMatrix* matrix);
+ static int32_t ApplyMaskPenaltyRule4(CBC_CommonByteMatrix* matrix);
+ static int32_t ApplyMaskPenaltyRule1Internal(CBC_CommonByteMatrix* matrix,
+ bool isHorizontal);
+};
+
+#endif // FXBARCODE_QRCODE_BC_QRCODERMASKUTIL_H_
diff --git a/fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp b/fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp
new file mode 100644
index 0000000000..b6ffaa00fc
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp
@@ -0,0 +1,506 @@
+// 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/common/BC_CommonByteMatrix.h"
+#include "fxbarcode/qrcode/BC_QRCoder.h"
+#include "fxbarcode/qrcode/BC_QRCoderBitVector.h"
+#include "fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
+#include "fxbarcode/qrcode/BC_QRCoderMaskUtil.h"
+#include "fxbarcode/qrcode/BC_QRCoderMatrixUtil.h"
+#include "fxbarcode/utils.h"
+
+const int32_t CBC_QRCoderMatrixUtil::POSITION_DETECTION_PATTERN[7][7] = {
+ {1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 0, 0, 1}, {1, 0, 1, 1, 1, 0, 1},
+ {1, 0, 1, 1, 1, 0, 1}, {1, 0, 1, 1, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 1},
+ {1, 1, 1, 1, 1, 1, 1}};
+const int32_t CBC_QRCoderMatrixUtil::HORIZONTAL_SEPARATION_PATTERN[1][8] = {
+ {0, 0, 0, 0, 0, 0, 0, 0}};
+const int32_t CBC_QRCoderMatrixUtil::VERTICAL_SEPARATION_PATTERN[7][1] = {
+ {0}, {0}, {0}, {0}, {0}, {0}, {0}};
+const int32_t CBC_QRCoderMatrixUtil::POSITION_ADJUSTMENT_PATTERN[5][5] = {
+ {1, 1, 1, 1, 1},
+ {1, 0, 0, 0, 1},
+ {1, 0, 1, 0, 1},
+ {1, 0, 0, 0, 1},
+ {1, 1, 1, 1, 1}};
+const int32_t
+ CBC_QRCoderMatrixUtil::POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[40][7] =
+ // NOLINTNEXTLINE
+ {
+ {-1, -1, -1, -1, -1, -1, -1}, {6, 18, -1, -1, -1, -1, -1},
+ {6, 22, -1, -1, -1, -1, -1}, {6, 26, -1, -1, -1, -1, -1},
+ {6, 30, -1, -1, -1, -1, -1}, {6, 34, -1, -1, -1, -1, -1},
+ {6, 22, 38, -1, -1, -1, -1}, {6, 24, 42, -1, -1, -1, -1},
+ {6, 26, 46, -1, -1, -1, -1}, {6, 28, 50, -1, -1, -1, -1},
+ {6, 30, 54, -1, -1, -1, -1}, {6, 32, 58, -1, -1, -1, -1},
+ {6, 34, 62, -1, -1, -1, -1}, {6, 26, 46, 66, -1, -1, -1},
+ {6, 26, 48, 70, -1, -1, -1}, {6, 26, 50, 74, -1, -1, -1},
+ {6, 30, 54, 78, -1, -1, -1}, {6, 30, 56, 82, -1, -1, -1},
+ {6, 30, 58, 86, -1, -1, -1}, {6, 34, 62, 90, -1, -1, -1},
+ {6, 28, 50, 72, 94, -1, -1}, {6, 26, 50, 74, 98, -1, -1},
+ {6, 30, 54, 78, 102, -1, -1}, {6, 28, 54, 80, 106, -1, -1},
+ {6, 32, 58, 84, 110, -1, -1}, {6, 30, 58, 86, 114, -1, -1},
+ {6, 34, 62, 90, 118, -1, -1}, {6, 26, 50, 74, 98, 122, -1},
+ {6, 30, 54, 78, 102, 126, -1}, {6, 26, 52, 78, 104, 130, -1},
+ {6, 30, 56, 82, 108, 134, -1}, {6, 34, 60, 86, 112, 138, -1},
+ {6, 30, 58, 86, 114, 142, -1}, {6, 34, 62, 90, 118, 146, -1},
+ {6, 30, 54, 78, 102, 126, 150}, {6, 24, 50, 76, 102, 128, 154},
+ {6, 28, 54, 80, 106, 132, 158}, {6, 32, 58, 84, 110, 136, 162},
+ {6, 26, 54, 82, 110, 138, 166}, {6, 30, 58, 86, 114, 142, 170},
+};
+const int32_t CBC_QRCoderMatrixUtil::TYPE_INFO_COORDINATES[15][2] = {
+ {8, 0}, {8, 1}, {8, 2}, {8, 3}, {8, 4}, {8, 5}, {8, 7}, {8, 8},
+ {7, 8}, {5, 8}, {4, 8}, {3, 8}, {2, 8}, {1, 8}, {0, 8},
+};
+const int32_t CBC_QRCoderMatrixUtil::VERSION_INFO_POLY = 0x1f25;
+const int32_t CBC_QRCoderMatrixUtil::TYPE_INFO_POLY = 0x0537;
+const int32_t CBC_QRCoderMatrixUtil::TYPE_INFO_MASK_PATTERN = 0x5412;
+
+void CBC_QRCoderMatrixUtil::ClearMatrix(CBC_CommonByteMatrix* matrix,
+ int32_t& e) {
+ if (!matrix) {
+ e = BCExceptionNullPointer;
+ return;
+ }
+ matrix->clear((uint8_t)-1);
+}
+void CBC_QRCoderMatrixUtil::BuildMatrix(
+ CBC_QRCoderBitVector* dataBits,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ int32_t version,
+ int32_t maskPattern,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e) {
+ if (!matrix) {
+ e = BCExceptionNullPointer;
+ return;
+ }
+ ClearMatrix(matrix, e);
+ if (e != BCExceptionNO)
+ return;
+ EmbedBasicPatterns(version, matrix, e);
+ if (e != BCExceptionNO)
+ return;
+ EmbedTypeInfo(ecLevel, maskPattern, matrix, e);
+ if (e != BCExceptionNO)
+ return;
+ MaybeEmbedVersionInfo(version, matrix, e);
+ if (e != BCExceptionNO)
+ return;
+ EmbedDataBits(dataBits, maskPattern, matrix, e);
+ if (e != BCExceptionNO)
+ return;
+}
+void CBC_QRCoderMatrixUtil::EmbedBasicPatterns(int32_t version,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e) {
+ if (!matrix) {
+ e = BCExceptionNullPointer;
+ return;
+ }
+ EmbedPositionDetectionPatternsAndSeparators(matrix, e);
+ if (e != BCExceptionNO)
+ return;
+ EmbedDarkDotAtLeftBottomCorner(matrix, e);
+ if (e != BCExceptionNO)
+ return;
+ MaybeEmbedPositionAdjustmentPatterns(version, matrix, e);
+ if (e != BCExceptionNO)
+ return;
+ EmbedTimingPatterns(matrix, e);
+ if (e != BCExceptionNO)
+ return;
+}
+void CBC_QRCoderMatrixUtil::EmbedTypeInfo(
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ int32_t maskPattern,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e) {
+ if (!matrix) {
+ e = BCExceptionNullPointer;
+ return;
+ }
+ CBC_QRCoderBitVector typeInfoBits;
+ typeInfoBits.Init();
+ MakeTypeInfoBits(ecLevel, maskPattern, &typeInfoBits, e);
+ if (e != BCExceptionNO)
+ return;
+ for (int32_t i = 0; i < typeInfoBits.Size(); i++) {
+ int32_t bit = typeInfoBits.At(typeInfoBits.Size() - 1 - i, e);
+ if (e != BCExceptionNO)
+ return;
+ int32_t x1 = TYPE_INFO_COORDINATES[i][0];
+ int32_t y1 = TYPE_INFO_COORDINATES[i][1];
+ matrix->Set(x1, y1, bit);
+ if (i < 8) {
+ int32_t x2 = matrix->GetWidth() - i - 1;
+ int32_t y2 = 8;
+ matrix->Set(x2, y2, bit);
+ } else {
+ int32_t x2 = 8;
+ int32_t y2 = matrix->GetHeight() - 7 + (i - 8);
+ matrix->Set(x2, y2, bit);
+ }
+ }
+}
+void CBC_QRCoderMatrixUtil::MaybeEmbedVersionInfo(int32_t version,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e) {
+ if (!matrix) {
+ e = BCExceptionNullPointer;
+ return;
+ }
+ if (version < 7) {
+ return;
+ }
+ CBC_QRCoderBitVector versionInfoBits;
+ versionInfoBits.Init();
+ MakeVersionInfoBits(version, &versionInfoBits, e);
+ if (e != BCExceptionNO)
+ return;
+ int32_t bitIndex = 6 * 3 - 1;
+ for (int32_t i = 0; i < 6; i++) {
+ for (int32_t j = 0; j < 3; j++) {
+ int32_t bit = versionInfoBits.At(bitIndex, e);
+ if (e != BCExceptionNO)
+ return;
+ bitIndex--;
+ matrix->Set(i, matrix->GetHeight() - 11 + j, bit);
+ matrix->Set(matrix->GetHeight() - 11 + j, i, bit);
+ }
+ }
+}
+void CBC_QRCoderMatrixUtil::EmbedDataBits(CBC_QRCoderBitVector* dataBits,
+ int32_t maskPattern,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e) {
+ if (!matrix || !dataBits) {
+ e = BCExceptionNullPointer;
+ return;
+ }
+ int32_t bitIndex = 0;
+ int32_t direction = -1;
+ int32_t x = matrix->GetWidth() - 1;
+ int32_t y = matrix->GetHeight() - 1;
+ while (x > 0) {
+ if (x == 6) {
+ x -= 1;
+ }
+ while (y >= 0 && y < matrix->GetHeight()) {
+ if (y == 6) {
+ y += direction;
+ continue;
+ }
+ for (int32_t i = 0; i < 2; i++) {
+ int32_t xx = x - i;
+ if (!IsEmpty(matrix->Get(xx, y))) {
+ continue;
+ }
+ int32_t bit;
+ if (bitIndex < dataBits->Size()) {
+ bit = dataBits->At(bitIndex, e);
+ if (e != BCExceptionNO)
+ return;
+ bitIndex++;
+ } else {
+ bit = 0;
+ }
+ if (maskPattern != -1) {
+ bool bol = CBC_QRCoderMaskUtil::GetDataMaskBit(maskPattern, xx, y, e);
+ if (e != BCExceptionNO)
+ return;
+ if (bol) {
+ bit ^= 0x01;
+ }
+ }
+ matrix->Set(xx, y, bit);
+ }
+ y += direction;
+ }
+ direction = -direction;
+ y += direction;
+ x -= 2;
+ }
+ if (bitIndex != dataBits->Size()) {
+ return;
+ }
+}
+int32_t CBC_QRCoderMatrixUtil::CalculateBCHCode(int32_t value, int32_t poly) {
+ int32_t msbSetInPoly = FindMSBSet(poly);
+ value <<= msbSetInPoly - 1;
+ while (FindMSBSet(value) >= msbSetInPoly) {
+ value ^= poly << (FindMSBSet(value) - msbSetInPoly);
+ }
+ return value;
+}
+void CBC_QRCoderMatrixUtil::MakeTypeInfoBits(
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ int32_t maskPattern,
+ CBC_QRCoderBitVector* bits,
+ int32_t& e) {
+ if (!bits) {
+ e = BCExceptionNullPointer;
+ return;
+ }
+ if (!CBC_QRCoder::IsValidMaskPattern(maskPattern)) {
+ e = BCExceptionBadMask;
+ return;
+ }
+ int32_t typeInfo = (ecLevel->GetBits() << 3) | maskPattern;
+ if (e != BCExceptionNO)
+ return;
+ bits->AppendBits(typeInfo, 5, e);
+ int32_t bchCode = CalculateBCHCode(typeInfo, TYPE_INFO_POLY);
+ if (e != BCExceptionNO)
+ return;
+ bits->AppendBits(bchCode, 10, e);
+ CBC_QRCoderBitVector maskBits;
+ maskBits.Init();
+ maskBits.AppendBits(TYPE_INFO_MASK_PATTERN, 15, e);
+ if (e != BCExceptionNO)
+ return;
+ bits->XOR(&maskBits, e);
+ if (e != BCExceptionNO)
+ return;
+ if (bits->Size() != 15)
+ e = BCExceptionBitSizeNot15;
+}
+
+void CBC_QRCoderMatrixUtil::MakeVersionInfoBits(int32_t version,
+ CBC_QRCoderBitVector* bits,
+ int32_t& e) {
+ if (!bits) {
+ e = BCExceptionNullPointer;
+ return;
+ }
+ bits->AppendBits(version, 6, e);
+ if (e != BCExceptionNO)
+ return;
+
+ int32_t bchCode = CalculateBCHCode(version, VERSION_INFO_POLY);
+ bits->AppendBits(bchCode, 12, e);
+ if (e != BCExceptionNO)
+ return;
+
+ if (bits->Size() != 18)
+ e = BCExceptionBitSizeNot18;
+}
+
+bool CBC_QRCoderMatrixUtil::IsEmpty(int32_t value) {
+ return (uint8_t)value == 0xff;
+}
+bool CBC_QRCoderMatrixUtil::IsValidValue(int32_t value) {
+ return ((uint8_t)value == 0xff || (uint8_t)value == 0x00 ||
+ (uint8_t)value == 0x01);
+}
+
+void CBC_QRCoderMatrixUtil::EmbedTimingPatterns(CBC_CommonByteMatrix* matrix,
+ int32_t& e) {
+ if (!matrix) {
+ e = BCExceptionNullPointer;
+ return;
+ }
+ for (int32_t i = 8; i < matrix->GetWidth() - 8; i++) {
+ int32_t bit = (i + 1) % 2;
+ if (!IsValidValue(matrix->Get(i, 6))) {
+ e = BCExceptionInvalidateImageData;
+ return;
+ }
+ if (IsEmpty(matrix->Get(i, 6))) {
+ matrix->Set(i, 6, bit);
+ }
+ if (!IsValidValue(matrix->Get(6, i))) {
+ e = BCExceptionInvalidateImageData;
+ return;
+ }
+ if (IsEmpty(matrix->Get(6, i))) {
+ matrix->Set(6, i, bit);
+ }
+ }
+}
+void CBC_QRCoderMatrixUtil::EmbedDarkDotAtLeftBottomCorner(
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e) {
+ if (!matrix) {
+ e = BCExceptionNullPointer;
+ return;
+ }
+ if (matrix->Get(8, matrix->GetHeight() - 8) == 0) {
+ e = BCExceptionHeight_8BeZero;
+ return;
+ }
+ matrix->Set(8, matrix->GetHeight() - 8, 1);
+}
+void CBC_QRCoderMatrixUtil::EmbedHorizontalSeparationPattern(
+ int32_t xStart,
+ int32_t yStart,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e) {
+ if (!matrix) {
+ e = BCExceptionNullPointer;
+ return;
+ }
+ for (int32_t x = 0; x < 8; x++) {
+ if (!IsEmpty(matrix->Get(xStart + x, yStart))) {
+ e = BCExceptionInvalidateData;
+ return;
+ }
+ matrix->Set(xStart + x, yStart, HORIZONTAL_SEPARATION_PATTERN[0][x]);
+ }
+}
+void CBC_QRCoderMatrixUtil::EmbedVerticalSeparationPattern(
+ int32_t xStart,
+ int32_t yStart,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e) {
+ if (!matrix) {
+ e = BCExceptionNullPointer;
+ return;
+ }
+ for (int32_t y = 0; y < 7; y++) {
+ if (!IsEmpty(matrix->Get(xStart, yStart + y))) {
+ e = BCExceptionInvalidateData;
+ return;
+ }
+ matrix->Set(xStart, yStart + y, VERTICAL_SEPARATION_PATTERN[y][0]);
+ }
+}
+void CBC_QRCoderMatrixUtil::EmbedPositionAdjustmentPattern(
+ int32_t xStart,
+ int32_t yStart,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e) {
+ if (!matrix) {
+ e = BCExceptionNullPointer;
+ if (e != BCExceptionNO)
+ return;
+ }
+ for (int32_t y = 0; y < 5; y++) {
+ for (int32_t x = 0; x < 5; x++) {
+ if (!IsEmpty(matrix->Get(xStart + x, y + yStart))) {
+ e = BCExceptionInvalidateData;
+ return;
+ }
+ matrix->Set(xStart + x, yStart + y, POSITION_ADJUSTMENT_PATTERN[y][x]);
+ }
+ }
+}
+void CBC_QRCoderMatrixUtil::EmbedPositionDetectionPattern(
+ int32_t xStart,
+ int32_t yStart,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e) {
+ if (!matrix) {
+ e = BCExceptionNullPointer;
+ return;
+ }
+ for (int32_t y = 0; y < 7; y++) {
+ for (int32_t x = 0; x < 7; x++) {
+ if (!IsEmpty(matrix->Get(xStart + x, yStart + y))) {
+ e = BCExceptionInvalidateData;
+ return;
+ }
+ matrix->Set(xStart + x, yStart + y, POSITION_DETECTION_PATTERN[y][x]);
+ }
+ }
+}
+void CBC_QRCoderMatrixUtil::EmbedPositionDetectionPatternsAndSeparators(
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e) {
+ if (!matrix) {
+ e = BCExceptionNullPointer;
+ return;
+ }
+ int32_t pdpWidth = 7;
+ EmbedPositionDetectionPattern(0, 0, matrix, e);
+ if (e != BCExceptionNO)
+ return;
+ EmbedPositionDetectionPattern(matrix->GetWidth() - pdpWidth, 0, matrix, e);
+ if (e != BCExceptionNO)
+ return;
+ EmbedPositionDetectionPattern(0, matrix->GetWidth() - pdpWidth, matrix, e);
+ if (e != BCExceptionNO)
+ return;
+ int32_t hspWidth = 8;
+ EmbedHorizontalSeparationPattern(0, hspWidth - 1, matrix, e);
+ if (e != BCExceptionNO)
+ return;
+ EmbedHorizontalSeparationPattern(matrix->GetWidth() - hspWidth, hspWidth - 1,
+ matrix, e);
+ if (e != BCExceptionNO)
+ return;
+ EmbedHorizontalSeparationPattern(0, matrix->GetWidth() - hspWidth, matrix, e);
+ if (e != BCExceptionNO)
+ return;
+ int32_t vspSize = 7;
+ EmbedVerticalSeparationPattern(vspSize, 0, matrix, e);
+ if (e != BCExceptionNO)
+ return;
+ EmbedVerticalSeparationPattern(matrix->GetHeight() - vspSize - 1, 0, matrix,
+ e);
+ if (e != BCExceptionNO)
+ return;
+ EmbedVerticalSeparationPattern(vspSize, matrix->GetHeight() - vspSize, matrix,
+ e);
+ if (e != BCExceptionNO)
+ return;
+}
+void CBC_QRCoderMatrixUtil::MaybeEmbedPositionAdjustmentPatterns(
+ int32_t version,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e) {
+ if (!matrix) {
+ e = BCExceptionNullPointer;
+ return;
+ }
+ if (version < 2) {
+ return;
+ }
+ int32_t index = version - 1;
+ int32_t const* coordinates =
+ &(POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index][0]);
+ int32_t numCoordinate = 7;
+ for (int32_t i = 0; i < numCoordinate; i++) {
+ for (int32_t j = 0; j < numCoordinate; j++) {
+ int32_t y = coordinates[i];
+ int32_t x = coordinates[j];
+ if (x == -1 || y == -1) {
+ continue;
+ }
+ if (IsEmpty(matrix->Get(x, y))) {
+ EmbedPositionAdjustmentPattern(x - 2, y - 2, matrix, e);
+ if (e != BCExceptionNO)
+ return;
+ }
+ }
+ }
+}
+int32_t CBC_QRCoderMatrixUtil::FindMSBSet(int32_t value) {
+ int32_t numDigits = 0;
+ while (value != 0) {
+ value >>= 1;
+ ++numDigits;
+ }
+ return numDigits;
+}
+CBC_QRCoderMatrixUtil::CBC_QRCoderMatrixUtil() {}
+CBC_QRCoderMatrixUtil::~CBC_QRCoderMatrixUtil() {}
diff --git a/fxbarcode/qrcode/BC_QRCoderMatrixUtil.h b/fxbarcode/qrcode/BC_QRCoderMatrixUtil.h
new file mode 100644
index 0000000000..3535c43c74
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderMatrixUtil.h
@@ -0,0 +1,87 @@
+// 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
+
+#ifndef FXBARCODE_QRCODE_BC_QRCODERMATRIXUTIL_H_
+#define FXBARCODE_QRCODE_BC_QRCODERMATRIXUTIL_H_
+
+class CBC_CommonByteMatrix;
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRCoderBitVector;
+class CBC_QRCoderMatrixUtil {
+ private:
+ static const int32_t POSITION_DETECTION_PATTERN[7][7];
+ static const int32_t VERTICAL_SEPARATION_PATTERN[7][1];
+ static const int32_t HORIZONTAL_SEPARATION_PATTERN[1][8];
+ static const int32_t POSITION_ADJUSTMENT_PATTERN[5][5];
+ static const int32_t POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[40][7];
+ static const int32_t TYPE_INFO_COORDINATES[15][2];
+ static const int32_t VERSION_INFO_POLY;
+ static const int32_t TYPE_INFO_POLY;
+ static const int32_t TYPE_INFO_MASK_PATTERN;
+
+ public:
+ CBC_QRCoderMatrixUtil();
+ virtual ~CBC_QRCoderMatrixUtil();
+ static void ClearMatrix(CBC_CommonByteMatrix* matrix, int32_t& e);
+ static void BuildMatrix(CBC_QRCoderBitVector* dataBits,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ int32_t version,
+ int32_t maskPattern,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e);
+ static void EmbedBasicPatterns(int32_t version,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e);
+ static void EmbedTypeInfo(CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ int32_t maskPattern,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e);
+ static void EmbedDataBits(CBC_QRCoderBitVector* dataBits,
+ int32_t maskPattern,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e);
+ static void MaybeEmbedVersionInfo(int32_t version,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e);
+ static int32_t FindMSBSet(int32_t value);
+ static int32_t CalculateBCHCode(int32_t code, int32_t poly);
+ static void MakeTypeInfoBits(CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ int32_t maskPattern,
+ CBC_QRCoderBitVector* bits,
+ int32_t& e);
+ static void MakeVersionInfoBits(int32_t version,
+ CBC_QRCoderBitVector* bits,
+ int32_t& e);
+ static bool IsEmpty(int32_t value);
+ static bool IsValidValue(int32_t value);
+ static void EmbedTimingPatterns(CBC_CommonByteMatrix* matrix, int32_t& e);
+ static void EmbedDarkDotAtLeftBottomCorner(CBC_CommonByteMatrix* matrix,
+ int32_t& e);
+ static void EmbedHorizontalSeparationPattern(int32_t xStart,
+ int32_t yStart,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e);
+ static void EmbedVerticalSeparationPattern(int32_t xStart,
+ int32_t yStart,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e);
+ static void EmbedPositionAdjustmentPattern(int32_t xStart,
+ int32_t yStart,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e);
+ static void EmbedPositionDetectionPattern(int32_t xStart,
+ int32_t yStart,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e);
+ static void EmbedPositionDetectionPatternsAndSeparators(
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e);
+ static void MaybeEmbedPositionAdjustmentPatterns(int32_t version,
+ CBC_CommonByteMatrix* matrix,
+ int32_t& e);
+};
+
+#endif // FXBARCODE_QRCODE_BC_QRCODERMATRIXUTIL_H_
diff --git a/fxbarcode/qrcode/BC_QRCoderMode.cpp b/fxbarcode/qrcode/BC_QRCoderMode.cpp
new file mode 100644
index 0000000000..3127145465
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderMode.cpp
@@ -0,0 +1,174 @@
+// 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 2007 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_QRCoderMode.h"
+
+#include <utility>
+
+#include "fxbarcode/qrcode/BC_QRCoderVersion.h"
+#include "fxbarcode/utils.h"
+
+CBC_QRCoderMode* CBC_QRCoderMode::sBYTE = nullptr;
+CBC_QRCoderMode* CBC_QRCoderMode::sNUMERIC = nullptr;
+CBC_QRCoderMode* CBC_QRCoderMode::sALPHANUMERIC = nullptr;
+CBC_QRCoderMode* CBC_QRCoderMode::sKANJI = nullptr;
+CBC_QRCoderMode* CBC_QRCoderMode::sECI = nullptr;
+CBC_QRCoderMode* CBC_QRCoderMode::sGBK = nullptr;
+CBC_QRCoderMode* CBC_QRCoderMode::sTERMINATOR = nullptr;
+CBC_QRCoderMode* CBC_QRCoderMode::sFNC1_FIRST_POSITION = nullptr;
+CBC_QRCoderMode* CBC_QRCoderMode::sFNC1_SECOND_POSITION = nullptr;
+CBC_QRCoderMode* CBC_QRCoderMode::sSTRUCTURED_APPEND = nullptr;
+
+CBC_QRCoderMode::CBC_QRCoderMode(std::vector<int32_t> charCountBits,
+ int32_t bits,
+ CFX_ByteString name)
+ : m_characterCountBitsForVersions(std::move(charCountBits)),
+ m_bits(bits),
+ m_name(name) {}
+
+CBC_QRCoderMode::~CBC_QRCoderMode() {}
+
+void CBC_QRCoderMode::Initialize() {
+ sBYTE = new CBC_QRCoderMode({8, 16, 16}, 0x4, "BYTE");
+ sALPHANUMERIC = new CBC_QRCoderMode({9, 11, 13}, 0x2, "ALPHANUMERIC");
+ sECI = new CBC_QRCoderMode(std::vector<int32_t>(), 0x7, "ECI");
+ sKANJI = new CBC_QRCoderMode({8, 10, 12}, 0x8, "KANJI");
+ sNUMERIC = new CBC_QRCoderMode({10, 12, 14}, 0x1, "NUMERIC");
+ sGBK = new CBC_QRCoderMode({8, 10, 12}, 0x0D, "GBK");
+ sTERMINATOR = new CBC_QRCoderMode(std::vector<int32_t>(), 0x00, "TERMINATOR");
+ sFNC1_FIRST_POSITION =
+ new CBC_QRCoderMode(std::vector<int32_t>(), 0x05, "FNC1_FIRST_POSITION");
+ sFNC1_SECOND_POSITION =
+ new CBC_QRCoderMode(std::vector<int32_t>(), 0x09, "FNC1_SECOND_POSITION");
+ sSTRUCTURED_APPEND =
+ new CBC_QRCoderMode(std::vector<int32_t>(), 0x03, "STRUCTURED_APPEND");
+}
+
+void CBC_QRCoderMode::Finalize() {
+ delete sBYTE;
+ delete sALPHANUMERIC;
+ delete sECI;
+ delete sKANJI;
+ delete sNUMERIC;
+ delete sGBK;
+ delete sTERMINATOR;
+ delete sFNC1_FIRST_POSITION;
+ delete sFNC1_SECOND_POSITION;
+ delete sSTRUCTURED_APPEND;
+}
+
+CBC_QRCoderMode* CBC_QRCoderMode::ForBits(int32_t bits, int32_t& e) {
+ switch (bits) {
+ case 0x0:
+ return sTERMINATOR;
+ case 0x1:
+ return sNUMERIC;
+ case 0x2:
+ return sALPHANUMERIC;
+ case 0x3:
+ return sSTRUCTURED_APPEND;
+ case 0x4:
+ return sBYTE;
+ case 0x5:
+ return sFNC1_FIRST_POSITION;
+ case 0x7:
+ return sECI;
+ case 0x8:
+ return sKANJI;
+ case 0x9:
+ return sFNC1_SECOND_POSITION;
+ case 0x0D:
+ return sGBK;
+ default:
+ e = BCExceptionUnsupportedMode;
+ return nullptr;
+ }
+}
+
+int32_t CBC_QRCoderMode::GetBits() const {
+ return m_bits;
+}
+
+CFX_ByteString CBC_QRCoderMode::GetName() const {
+ return m_name;
+}
+
+int32_t CBC_QRCoderMode::GetCharacterCountBits(CBC_QRCoderVersion* version,
+ int32_t& e) const {
+ if (m_characterCountBitsForVersions.empty()) {
+ e = BCExceptionCharacterNotThisMode;
+ return 0;
+ }
+ int32_t number = version->GetVersionNumber();
+ int32_t offset;
+ if (number <= 9) {
+ offset = 0;
+ } else if (number <= 26) {
+ offset = 1;
+ } else {
+ offset = 2;
+ }
+ return m_characterCountBitsForVersions[offset];
+}
+
+void CBC_QRCoderMode::Destroy() {
+ if (sBYTE) {
+ delete CBC_QRCoderMode::sBYTE;
+ sBYTE = nullptr;
+ }
+ if (sNUMERIC) {
+ delete CBC_QRCoderMode::sNUMERIC;
+ sNUMERIC = nullptr;
+ }
+ if (sALPHANUMERIC) {
+ delete CBC_QRCoderMode::sALPHANUMERIC;
+ sALPHANUMERIC = nullptr;
+ }
+ if (sKANJI) {
+ delete CBC_QRCoderMode::sKANJI;
+ sKANJI = nullptr;
+ }
+ if (sECI) {
+ delete CBC_QRCoderMode::sECI;
+ sECI = nullptr;
+ }
+ if (sGBK) {
+ delete CBC_QRCoderMode::sGBK;
+ sGBK = nullptr;
+ }
+ if (sTERMINATOR) {
+ delete CBC_QRCoderMode::sTERMINATOR;
+ sTERMINATOR = nullptr;
+ }
+ if (sFNC1_FIRST_POSITION) {
+ delete CBC_QRCoderMode::sFNC1_FIRST_POSITION;
+ sFNC1_FIRST_POSITION = nullptr;
+ }
+ if (sFNC1_SECOND_POSITION) {
+ delete CBC_QRCoderMode::sFNC1_SECOND_POSITION;
+ sFNC1_SECOND_POSITION = nullptr;
+ }
+ if (sSTRUCTURED_APPEND) {
+ delete CBC_QRCoderMode::sSTRUCTURED_APPEND;
+ sSTRUCTURED_APPEND = nullptr;
+ }
+}
diff --git a/fxbarcode/qrcode/BC_QRCoderMode.h b/fxbarcode/qrcode/BC_QRCoderMode.h
new file mode 100644
index 0000000000..4402e3fe26
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderMode.h
@@ -0,0 +1,53 @@
+// 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
+
+#ifndef FXBARCODE_QRCODE_BC_QRCODERMODE_H_
+#define FXBARCODE_QRCODE_BC_QRCODERMODE_H_
+
+#include <stdint.h>
+
+#include <vector>
+
+#include "core/fxcrt/fx_string.h"
+
+class CBC_QRCoderVersion;
+
+class CBC_QRCoderMode {
+ public:
+ virtual ~CBC_QRCoderMode();
+
+ static void Initialize();
+ static void Finalize();
+ static CBC_QRCoderMode* ForBits(int32_t bits, int32_t& e);
+ static void Destroy();
+
+ int32_t GetCharacterCountBits(CBC_QRCoderVersion* version, int32_t& e) const;
+ int32_t GetBits() const;
+ CFX_ByteString GetName() const;
+
+ static CBC_QRCoderMode* sBYTE;
+ static CBC_QRCoderMode* sNUMERIC;
+ static CBC_QRCoderMode* sALPHANUMERIC;
+ static CBC_QRCoderMode* sKANJI;
+ static CBC_QRCoderMode* sECI;
+ static CBC_QRCoderMode* sGBK;
+ static CBC_QRCoderMode* sTERMINATOR;
+ static CBC_QRCoderMode* sFNC1_FIRST_POSITION;
+ static CBC_QRCoderMode* sFNC1_SECOND_POSITION;
+ static CBC_QRCoderMode* sSTRUCTURED_APPEND;
+
+ private:
+ CBC_QRCoderMode();
+ CBC_QRCoderMode(std::vector<int32_t> charCountBits,
+ int32_t bits,
+ CFX_ByteString name);
+
+ std::vector<int32_t> m_characterCountBitsForVersions;
+ const int32_t m_bits;
+ const CFX_ByteString m_name;
+};
+
+#endif // FXBARCODE_QRCODE_BC_QRCODERMODE_H_
diff --git a/fxbarcode/qrcode/BC_QRCoderVersion.cpp b/fxbarcode/qrcode/BC_QRCoderVersion.cpp
new file mode 100644
index 0000000000..ff7cbc4007
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderVersion.cpp
@@ -0,0 +1,794 @@
+// 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 2007 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/common/BC_CommonBitMatrix.h"
+#include "fxbarcode/qrcode/BC_QRCoderBitVector.h"
+#include "fxbarcode/qrcode/BC_QRCoderECB.h"
+#include "fxbarcode/qrcode/BC_QRCoderECBlocks.h"
+#include "fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
+#include "fxbarcode/qrcode/BC_QRCoderVersion.h"
+#include "fxbarcode/utils.h"
+
+namespace {
+
+const uint8_t BITS_SET_IN_HALF_BYTE[] = {0, 1, 1, 2, 1, 2, 2, 3,
+ 1, 2, 2, 3, 2, 3, 3, 4};
+
+int32_t NumBitsDiffering(int32_t a, int32_t b) {
+ a ^= b;
+ return BITS_SET_IN_HALF_BYTE[a & 0x0F] +
+ BITS_SET_IN_HALF_BYTE[(a >> 4) & 0x0F] +
+ BITS_SET_IN_HALF_BYTE[(a >> 8) & 0x0F] +
+ BITS_SET_IN_HALF_BYTE[(a >> 12) & 0x0F] +
+ BITS_SET_IN_HALF_BYTE[(a >> 16) & 0x0F] +
+ BITS_SET_IN_HALF_BYTE[(a >> 20) & 0x0F] +
+ BITS_SET_IN_HALF_BYTE[(a >> 24) & 0x0F] +
+ BITS_SET_IN_HALF_BYTE[(a >> 28) & 0x0F];
+}
+
+} // namespace
+
+const int32_t CBC_QRCoderVersion::VERSION_DECODE_INFO[] = {
+ 0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6, 0x0C762, 0x0D847,
+ 0x0E60D, 0x0F928, 0x10B78, 0x1145D, 0x12A17, 0x13532, 0x149A6,
+ 0x15683, 0x168C9, 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB, 0x1B08E,
+ 0x1CC1A, 0x1D33F, 0x1ED75, 0x1F250, 0x209D5, 0x216F0, 0x228BA,
+ 0x2379F, 0x24B0B, 0x2542E, 0x26A64, 0x27541, 0x28C69};
+
+std::vector<CBC_QRCoderVersion*>* CBC_QRCoderVersion::VERSION = nullptr;
+
+void CBC_QRCoderVersion::Initialize() {
+ VERSION = new std::vector<CBC_QRCoderVersion*>();
+}
+void CBC_QRCoderVersion::Finalize() {
+ for (size_t i = 0; i < VERSION->size(); i++)
+ delete (*VERSION)[i];
+
+ delete VERSION;
+ VERSION = nullptr;
+}
+CBC_QRCoderVersion::CBC_QRCoderVersion(int32_t versionNumber,
+ CBC_QRCoderECBlocks* ecBlocks1,
+ CBC_QRCoderECBlocks* ecBlocks2,
+ CBC_QRCoderECBlocks* ecBlocks3,
+ CBC_QRCoderECBlocks* ecBlocks4) {
+ m_versionNumber = versionNumber;
+ m_ecBlocksArray.push_back(ecBlocks1);
+ m_ecBlocksArray.push_back(ecBlocks2);
+ m_ecBlocksArray.push_back(ecBlocks3);
+ m_ecBlocksArray.push_back(ecBlocks4);
+ int32_t total = 0;
+ int32_t ecCodeWords = ecBlocks1->GetECCodeWordsPerBlock();
+ std::vector<CBC_QRCoderECB*>* ecbArray = ecBlocks1->GetECBlocks();
+ for (size_t i = 0; i < ecbArray->size(); i++) {
+ CBC_QRCoderECB* ecBlock = (*ecbArray)[i];
+ total += ecBlock->GetCount() * (ecBlock->GetDataCodeWords() + ecCodeWords);
+ }
+ m_totalCodeWords = total;
+ switch (versionNumber) {
+ case 1:
+ break;
+ case 2:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(18);
+ break;
+ case 3:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(22);
+ break;
+ case 4:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(26);
+ break;
+ case 5:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(30);
+ break;
+ case 6:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(34);
+ break;
+ case 7:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(22);
+ m_alignmentPatternCenters.push_back(38);
+ break;
+ case 8:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(24);
+ m_alignmentPatternCenters.push_back(42);
+ break;
+ case 9:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(26);
+ m_alignmentPatternCenters.push_back(46);
+ break;
+ case 10:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(28);
+ m_alignmentPatternCenters.push_back(50);
+ break;
+ case 11:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(30);
+ m_alignmentPatternCenters.push_back(54);
+ break;
+ case 12:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(32);
+ m_alignmentPatternCenters.push_back(58);
+ break;
+ case 13:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(34);
+ m_alignmentPatternCenters.push_back(62);
+ break;
+ case 14:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(26);
+ m_alignmentPatternCenters.push_back(46);
+ m_alignmentPatternCenters.push_back(66);
+ break;
+ case 15:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(26);
+ m_alignmentPatternCenters.push_back(48);
+ m_alignmentPatternCenters.push_back(70);
+ break;
+ case 16:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(26);
+ m_alignmentPatternCenters.push_back(50);
+ m_alignmentPatternCenters.push_back(74);
+ break;
+ case 17:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(30);
+ m_alignmentPatternCenters.push_back(54);
+ m_alignmentPatternCenters.push_back(78);
+ break;
+ case 18:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(30);
+ m_alignmentPatternCenters.push_back(56);
+ m_alignmentPatternCenters.push_back(82);
+ break;
+ case 19:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(30);
+ m_alignmentPatternCenters.push_back(58);
+ m_alignmentPatternCenters.push_back(86);
+ break;
+ case 20:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(34);
+ m_alignmentPatternCenters.push_back(62);
+ m_alignmentPatternCenters.push_back(90);
+ break;
+ case 21:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(28);
+ m_alignmentPatternCenters.push_back(50);
+ m_alignmentPatternCenters.push_back(72);
+ m_alignmentPatternCenters.push_back(94);
+ break;
+ case 22:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(26);
+ m_alignmentPatternCenters.push_back(50);
+ m_alignmentPatternCenters.push_back(74);
+ m_alignmentPatternCenters.push_back(98);
+ break;
+ case 23:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(30);
+ m_alignmentPatternCenters.push_back(54);
+ m_alignmentPatternCenters.push_back(74);
+ m_alignmentPatternCenters.push_back(102);
+ break;
+ case 24:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(28);
+ m_alignmentPatternCenters.push_back(54);
+ m_alignmentPatternCenters.push_back(80);
+ m_alignmentPatternCenters.push_back(106);
+ break;
+ case 25:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(32);
+ m_alignmentPatternCenters.push_back(58);
+ m_alignmentPatternCenters.push_back(84);
+ m_alignmentPatternCenters.push_back(110);
+ break;
+ case 26:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(30);
+ m_alignmentPatternCenters.push_back(58);
+ m_alignmentPatternCenters.push_back(86);
+ m_alignmentPatternCenters.push_back(114);
+ break;
+ case 27:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(34);
+ m_alignmentPatternCenters.push_back(62);
+ m_alignmentPatternCenters.push_back(90);
+ m_alignmentPatternCenters.push_back(118);
+ break;
+ case 28:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(26);
+ m_alignmentPatternCenters.push_back(50);
+ m_alignmentPatternCenters.push_back(74);
+ m_alignmentPatternCenters.push_back(98);
+ m_alignmentPatternCenters.push_back(122);
+ break;
+ case 29:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(30);
+ m_alignmentPatternCenters.push_back(54);
+ m_alignmentPatternCenters.push_back(78);
+ m_alignmentPatternCenters.push_back(102);
+ m_alignmentPatternCenters.push_back(126);
+ break;
+ case 30:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(26);
+ m_alignmentPatternCenters.push_back(52);
+ m_alignmentPatternCenters.push_back(78);
+ m_alignmentPatternCenters.push_back(104);
+ m_alignmentPatternCenters.push_back(130);
+ break;
+ case 31:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(30);
+ m_alignmentPatternCenters.push_back(56);
+ m_alignmentPatternCenters.push_back(82);
+ m_alignmentPatternCenters.push_back(108);
+ m_alignmentPatternCenters.push_back(134);
+ break;
+ case 32:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(34);
+ m_alignmentPatternCenters.push_back(60);
+ m_alignmentPatternCenters.push_back(86);
+ m_alignmentPatternCenters.push_back(112);
+ m_alignmentPatternCenters.push_back(138);
+ break;
+ case 33:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(30);
+ m_alignmentPatternCenters.push_back(58);
+ m_alignmentPatternCenters.push_back(86);
+ m_alignmentPatternCenters.push_back(114);
+ m_alignmentPatternCenters.push_back(142);
+ break;
+ case 34:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(34);
+ m_alignmentPatternCenters.push_back(62);
+ m_alignmentPatternCenters.push_back(90);
+ m_alignmentPatternCenters.push_back(118);
+ m_alignmentPatternCenters.push_back(146);
+ break;
+ case 35:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(30);
+ m_alignmentPatternCenters.push_back(54);
+ m_alignmentPatternCenters.push_back(78);
+ m_alignmentPatternCenters.push_back(102);
+ m_alignmentPatternCenters.push_back(126);
+ m_alignmentPatternCenters.push_back(150);
+ break;
+ case 36:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(24);
+ m_alignmentPatternCenters.push_back(50);
+ m_alignmentPatternCenters.push_back(76);
+ m_alignmentPatternCenters.push_back(102);
+ m_alignmentPatternCenters.push_back(128);
+ m_alignmentPatternCenters.push_back(154);
+ break;
+ case 37:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(28);
+ m_alignmentPatternCenters.push_back(54);
+ m_alignmentPatternCenters.push_back(80);
+ m_alignmentPatternCenters.push_back(106);
+ m_alignmentPatternCenters.push_back(132);
+ m_alignmentPatternCenters.push_back(158);
+ break;
+ case 38:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(32);
+ m_alignmentPatternCenters.push_back(58);
+ m_alignmentPatternCenters.push_back(84);
+ m_alignmentPatternCenters.push_back(110);
+ m_alignmentPatternCenters.push_back(136);
+ m_alignmentPatternCenters.push_back(162);
+ break;
+ case 39:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(26);
+ m_alignmentPatternCenters.push_back(54);
+ m_alignmentPatternCenters.push_back(82);
+ m_alignmentPatternCenters.push_back(110);
+ m_alignmentPatternCenters.push_back(138);
+ m_alignmentPatternCenters.push_back(166);
+ break;
+ case 40:
+ m_alignmentPatternCenters.push_back(6);
+ m_alignmentPatternCenters.push_back(30);
+ m_alignmentPatternCenters.push_back(58);
+ m_alignmentPatternCenters.push_back(86);
+ m_alignmentPatternCenters.push_back(114);
+ m_alignmentPatternCenters.push_back(142);
+ m_alignmentPatternCenters.push_back(170);
+ break;
+ }
+}
+
+CBC_QRCoderVersion::~CBC_QRCoderVersion() {
+ for (size_t i = 0; i < m_ecBlocksArray.size(); ++i)
+ delete m_ecBlocksArray[i];
+}
+
+int32_t CBC_QRCoderVersion::GetVersionNumber() {
+ return m_versionNumber;
+}
+std::vector<int32_t>* CBC_QRCoderVersion::GetAlignmentPatternCenters() {
+ return &m_alignmentPatternCenters;
+}
+int32_t CBC_QRCoderVersion::GetTotalCodeWords() {
+ return m_totalCodeWords;
+}
+int32_t CBC_QRCoderVersion::GetDimensionForVersion() {
+ return 17 + 4 * m_versionNumber;
+}
+CBC_QRCoderECBlocks* CBC_QRCoderVersion::GetECBlocksForLevel(
+ CBC_QRCoderErrorCorrectionLevel* ecLevel) {
+ return m_ecBlocksArray[ecLevel->Ordinal()];
+}
+CBC_QRCoderVersion* CBC_QRCoderVersion::GetProvisionalVersionForDimension(
+ int32_t dimension,
+ int32_t& e) {
+ if ((dimension % 4) != 1) {
+ e = BCExceptionRead;
+ return nullptr;
+ }
+ CBC_QRCoderVersion* qcv = GetVersionForNumber((dimension - 17) >> 2, e);
+ if (e != BCExceptionNO)
+ return nullptr;
+ return qcv;
+}
+CBC_QRCoderVersion* CBC_QRCoderVersion::DecodeVersionInformation(
+ int32_t versionBits,
+ int32_t& e) {
+ int32_t bestDifference = FXSYS_IntMax;
+ int32_t bestVersion = 0;
+ for (int32_t i = 0; i < 34; i++) {
+ int32_t targetVersion = VERSION_DECODE_INFO[i];
+ if (targetVersion == versionBits) {
+ CBC_QRCoderVersion* qcv = GetVersionForNumber(i + 7, e);
+ if (e != BCExceptionNO)
+ return nullptr;
+ return qcv;
+ }
+ int32_t bitsDifference = NumBitsDiffering(versionBits, targetVersion);
+ if (bitsDifference < bestDifference) {
+ bestVersion = i + 7;
+ bestDifference = bitsDifference;
+ }
+ }
+ if (bestDifference <= 3) {
+ CBC_QRCoderVersion* qcv = GetVersionForNumber(bestVersion, e);
+ if (e != BCExceptionNO)
+ return nullptr;
+ return qcv;
+ }
+ return nullptr;
+}
+CBC_CommonBitMatrix* CBC_QRCoderVersion::BuildFunctionPattern(int32_t& e) {
+ int32_t dimension = GetDimensionForVersion();
+ CBC_CommonBitMatrix* bitMatrix = new CBC_CommonBitMatrix();
+ bitMatrix->Init(dimension);
+ bitMatrix->SetRegion(0, 0, 9, 9, e);
+ if (e != BCExceptionNO)
+ return nullptr;
+ bitMatrix->SetRegion(dimension - 8, 0, 8, 9, e);
+ if (e != BCExceptionNO)
+ return nullptr;
+ bitMatrix->SetRegion(0, dimension - 8, 9, 8, e);
+ if (e != BCExceptionNO)
+ return nullptr;
+ size_t max = m_alignmentPatternCenters.size();
+ for (size_t x = 0; x < max; x++) {
+ int32_t i = m_alignmentPatternCenters[x] - 2;
+ for (size_t y = 0; y < max; y++) {
+ if ((x == 0 && (y == 0 || y == max - 1)) || (x == max - 1 && y == 0)) {
+ continue;
+ }
+ bitMatrix->SetRegion(m_alignmentPatternCenters[y] - 2, i, 5, 5, e);
+ if (e != BCExceptionNO)
+ return nullptr;
+ }
+ }
+ bitMatrix->SetRegion(6, 9, 1, dimension - 17, e);
+ if (e != BCExceptionNO)
+ return nullptr;
+ bitMatrix->SetRegion(9, 6, dimension - 17, 1, e);
+ if (e != BCExceptionNO)
+ return nullptr;
+ if (m_versionNumber > 6) {
+ bitMatrix->SetRegion(dimension - 11, 0, 3, 6, e);
+ if (e != BCExceptionNO)
+ return nullptr;
+ bitMatrix->SetRegion(0, dimension - 11, 6, 3, e);
+ if (e != BCExceptionNO)
+ return nullptr;
+ }
+ return bitMatrix;
+}
+CBC_QRCoderVersion* CBC_QRCoderVersion::GetVersionForNumber(
+ int32_t versionNumber,
+ int32_t& e) {
+ if (VERSION->empty()) {
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 1, new CBC_QRCoderECBlocks(7, new CBC_QRCoderECB(1, 19)),
+ new CBC_QRCoderECBlocks(10, new CBC_QRCoderECB(1, 16)),
+ new CBC_QRCoderECBlocks(13, new CBC_QRCoderECB(1, 13)),
+ new CBC_QRCoderECBlocks(17, new CBC_QRCoderECB(1, 9))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 2, new CBC_QRCoderECBlocks(10, new CBC_QRCoderECB(1, 34)),
+ new CBC_QRCoderECBlocks(16, new CBC_QRCoderECB(1, 28)),
+ new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(1, 22)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(1, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 3, new CBC_QRCoderECBlocks(15, new CBC_QRCoderECB(1, 55)),
+ new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(1, 44)),
+ new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 17)),
+ new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(2, 13))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 4, new CBC_QRCoderECBlocks(20, new CBC_QRCoderECB(1, 80)),
+ new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 32)),
+ new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(2, 24)),
+ new CBC_QRCoderECBlocks(16, new CBC_QRCoderECB(4, 9))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 5, new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(1, 108)),
+ new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(2, 43)),
+ new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 15),
+ new CBC_QRCoderECB(2, 16)),
+ new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(2, 11),
+ new CBC_QRCoderECB(2, 12))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 6, new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 68)),
+ new CBC_QRCoderECBlocks(16, new CBC_QRCoderECB(4, 27)),
+ new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(4, 19)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(4, 15))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 7, new CBC_QRCoderECBlocks(20, new CBC_QRCoderECB(2, 78)),
+ new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(4, 31)),
+ new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 14),
+ new CBC_QRCoderECB(4, 15)),
+ new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(4, 13),
+ new CBC_QRCoderECB(1, 14))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 8, new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(2, 97)),
+ new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(2, 38),
+ new CBC_QRCoderECB(2, 39)),
+ new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(4, 18),
+ new CBC_QRCoderECB(2, 19)),
+ new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(4, 14),
+ new CBC_QRCoderECB(2, 15))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 9, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(2, 116)),
+ new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(3, 36),
+ new CBC_QRCoderECB(2, 37)),
+ new CBC_QRCoderECBlocks(20, new CBC_QRCoderECB(4, 16),
+ new CBC_QRCoderECB(4, 17)),
+ new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(4, 12),
+ new CBC_QRCoderECB(4, 13))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 10, new CBC_QRCoderECBlocks(18, new CBC_QRCoderECB(2, 68),
+ new CBC_QRCoderECB(2, 69)),
+ new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(4, 43),
+ new CBC_QRCoderECB(1, 44)),
+ new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(6, 19),
+ new CBC_QRCoderECB(2, 20)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(6, 15),
+ new CBC_QRCoderECB(2, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 11, new CBC_QRCoderECBlocks(20, new CBC_QRCoderECB(4, 81)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(1, 50),
+ new CBC_QRCoderECB(4, 51)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(4, 22),
+ new CBC_QRCoderECB(4, 23)),
+ new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(3, 12),
+ new CBC_QRCoderECB(8, 13))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 12, new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(2, 92),
+ new CBC_QRCoderECB(2, 93)),
+ new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(6, 36),
+ new CBC_QRCoderECB(2, 37)),
+ new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(4, 20),
+ new CBC_QRCoderECB(6, 21)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(7, 14),
+ new CBC_QRCoderECB(4, 15))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 13, new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(4, 107)),
+ new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(8, 37),
+ new CBC_QRCoderECB(1, 38)),
+ new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(8, 20),
+ new CBC_QRCoderECB(4, 21)),
+ new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(12, 11),
+ new CBC_QRCoderECB(4, 12))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 14, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(3, 115),
+ new CBC_QRCoderECB(1, 116)),
+ new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(4, 40),
+ new CBC_QRCoderECB(5, 41)),
+ new CBC_QRCoderECBlocks(20, new CBC_QRCoderECB(11, 16),
+ new CBC_QRCoderECB(5, 17)),
+ new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(11, 12),
+ new CBC_QRCoderECB(5, 13))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 15, new CBC_QRCoderECBlocks(22, new CBC_QRCoderECB(5, 87),
+ new CBC_QRCoderECB(1, 88)),
+ new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(5, 41),
+ new CBC_QRCoderECB(5, 42)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(5, 24),
+ new CBC_QRCoderECB(7, 25)),
+ new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(11, 12),
+ new CBC_QRCoderECB(7, 13))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 16, new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(5, 98),
+ new CBC_QRCoderECB(1, 99)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(7, 45),
+ new CBC_QRCoderECB(3, 46)),
+ new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(15, 19),
+ new CBC_QRCoderECB(2, 20)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(3, 15),
+ new CBC_QRCoderECB(13, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 17, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(1, 107),
+ new CBC_QRCoderECB(5, 108)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(10, 46),
+ new CBC_QRCoderECB(1, 47)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(1, 22),
+ new CBC_QRCoderECB(15, 23)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(2, 14),
+ new CBC_QRCoderECB(17, 15))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 18, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(5, 120),
+ new CBC_QRCoderECB(1, 121)),
+ new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(9, 43),
+ new CBC_QRCoderECB(4, 44)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(17, 22),
+ new CBC_QRCoderECB(1, 23)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(2, 14),
+ new CBC_QRCoderECB(19, 15))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 19, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(3, 113),
+ new CBC_QRCoderECB(4, 114)),
+ new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(3, 44),
+ new CBC_QRCoderECB(11, 45)),
+ new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(17, 21),
+ new CBC_QRCoderECB(4, 22)),
+ new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(9, 13),
+ new CBC_QRCoderECB(16, 14))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 20, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(3, 107),
+ new CBC_QRCoderECB(5, 108)),
+ new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(3, 41),
+ new CBC_QRCoderECB(13, 42)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(15, 24),
+ new CBC_QRCoderECB(5, 25)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(15, 15),
+ new CBC_QRCoderECB(10, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 21, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(4, 116),
+ new CBC_QRCoderECB(4, 117)),
+ new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(17, 42)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(17, 22),
+ new CBC_QRCoderECB(6, 23)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(19, 16),
+ new CBC_QRCoderECB(6, 17))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 22, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(2, 111),
+ new CBC_QRCoderECB(7, 112)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(17, 46)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(7, 24),
+ new CBC_QRCoderECB(16, 25)),
+ new CBC_QRCoderECBlocks(24, new CBC_QRCoderECB(34, 13))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 23, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(4, 121),
+ new CBC_QRCoderECB(5, 122)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(4, 47),
+ new CBC_QRCoderECB(14, 48)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(11, 24),
+ new CBC_QRCoderECB(14, 25)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(16, 15),
+ new CBC_QRCoderECB(14, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 24, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(6, 117),
+ new CBC_QRCoderECB(4, 118)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(6, 45),
+ new CBC_QRCoderECB(14, 46)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(11, 24),
+ new CBC_QRCoderECB(16, 25)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(30, 16),
+ new CBC_QRCoderECB(2, 17))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 25, new CBC_QRCoderECBlocks(26, new CBC_QRCoderECB(8, 106),
+ new CBC_QRCoderECB(4, 107)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(8, 47),
+ new CBC_QRCoderECB(13, 48)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(7, 24),
+ new CBC_QRCoderECB(22, 25)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(22, 15),
+ new CBC_QRCoderECB(13, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 26, new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(10, 114),
+ new CBC_QRCoderECB(2, 115)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(19, 46),
+ new CBC_QRCoderECB(4, 47)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(28, 22),
+ new CBC_QRCoderECB(6, 23)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(33, 16),
+ new CBC_QRCoderECB(4, 17))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 27, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(8, 122),
+ new CBC_QRCoderECB(4, 123)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(22, 45),
+ new CBC_QRCoderECB(3, 46)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(8, 23),
+ new CBC_QRCoderECB(26, 24)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(12, 15),
+ new CBC_QRCoderECB(28, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 28, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(3, 117),
+ new CBC_QRCoderECB(10, 118)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(3, 45),
+ new CBC_QRCoderECB(23, 46)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(4, 24),
+ new CBC_QRCoderECB(31, 25)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(11, 15),
+ new CBC_QRCoderECB(31, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 29, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(7, 116),
+ new CBC_QRCoderECB(7, 117)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(21, 45),
+ new CBC_QRCoderECB(7, 46)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(1, 23),
+ new CBC_QRCoderECB(37, 24)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(19, 15),
+ new CBC_QRCoderECB(26, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 30, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(5, 115),
+ new CBC_QRCoderECB(10, 116)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(19, 47),
+ new CBC_QRCoderECB(10, 48)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(15, 24),
+ new CBC_QRCoderECB(25, 25)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(23, 15),
+ new CBC_QRCoderECB(25, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 31, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(13, 115),
+ new CBC_QRCoderECB(3, 116)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(2, 46),
+ new CBC_QRCoderECB(29, 47)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(42, 24),
+ new CBC_QRCoderECB(1, 25)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(23, 15),
+ new CBC_QRCoderECB(28, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 32, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(17, 115)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(10, 46),
+ new CBC_QRCoderECB(23, 47)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(10, 24),
+ new CBC_QRCoderECB(35, 25)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(19, 15),
+ new CBC_QRCoderECB(35, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 33, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(17, 115),
+ new CBC_QRCoderECB(1, 116)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(14, 46),
+ new CBC_QRCoderECB(21, 47)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(29, 24),
+ new CBC_QRCoderECB(19, 25)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(11, 15),
+ new CBC_QRCoderECB(46, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 34, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(13, 115),
+ new CBC_QRCoderECB(6, 116)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(14, 46),
+ new CBC_QRCoderECB(23, 47)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(44, 24),
+ new CBC_QRCoderECB(7, 25)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(59, 16),
+ new CBC_QRCoderECB(1, 17))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 35, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(12, 121),
+ new CBC_QRCoderECB(7, 122)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(12, 47),
+ new CBC_QRCoderECB(26, 48)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(39, 24),
+ new CBC_QRCoderECB(14, 25)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(22, 15),
+ new CBC_QRCoderECB(41, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 36, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(6, 121),
+ new CBC_QRCoderECB(14, 122)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(6, 47),
+ new CBC_QRCoderECB(34, 48)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(46, 24),
+ new CBC_QRCoderECB(10, 25)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(2, 15),
+ new CBC_QRCoderECB(64, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 37, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(17, 122),
+ new CBC_QRCoderECB(4, 123)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(29, 46),
+ new CBC_QRCoderECB(14, 47)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(49, 24),
+ new CBC_QRCoderECB(10, 25)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(24, 15),
+ new CBC_QRCoderECB(46, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 38, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(4, 122),
+ new CBC_QRCoderECB(18, 123)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(13, 46),
+ new CBC_QRCoderECB(32, 47)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(48, 24),
+ new CBC_QRCoderECB(14, 25)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(42, 15),
+ new CBC_QRCoderECB(32, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 39, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(20, 117),
+ new CBC_QRCoderECB(4, 118)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(40, 47),
+ new CBC_QRCoderECB(7, 48)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(43, 24),
+ new CBC_QRCoderECB(22, 25)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(10, 15),
+ new CBC_QRCoderECB(67, 16))));
+ VERSION->push_back(new CBC_QRCoderVersion(
+ 40, new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(19, 118),
+ new CBC_QRCoderECB(6, 119)),
+ new CBC_QRCoderECBlocks(28, new CBC_QRCoderECB(18, 47),
+ new CBC_QRCoderECB(31, 48)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(34, 24),
+ new CBC_QRCoderECB(34, 25)),
+ new CBC_QRCoderECBlocks(30, new CBC_QRCoderECB(20, 15),
+ new CBC_QRCoderECB(61, 16))));
+ }
+ if (versionNumber < 1 || versionNumber > 40) {
+ e = BCExceptionIllegalArgument;
+ return nullptr;
+ }
+ return (*VERSION)[versionNumber - 1];
+}
+
+void CBC_QRCoderVersion::Destroy() {
+ for (size_t i = 0; i < VERSION->size(); i++)
+ delete (*VERSION)[i];
+ VERSION->clear();
+}
diff --git a/fxbarcode/qrcode/BC_QRCoderVersion.h b/fxbarcode/qrcode/BC_QRCoderVersion.h
new file mode 100644
index 0000000000..78ded0d30c
--- /dev/null
+++ b/fxbarcode/qrcode/BC_QRCoderVersion.h
@@ -0,0 +1,57 @@
+// 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
+
+#ifndef FXBARCODE_QRCODE_BC_QRCODERVERSION_H_
+#define FXBARCODE_QRCODE_BC_QRCODERVERSION_H_
+
+#include <vector>
+
+#include "core/fxcrt/fx_basic.h"
+
+class CBC_CommonBitMatrix;
+class CBC_QRCoderECBlocks;
+class CBC_QRCoderErrorCorrectionLevel;
+
+class CBC_QRCoderVersion {
+ public:
+ virtual ~CBC_QRCoderVersion();
+ static void Initialize();
+ static void Finalize();
+
+ int32_t GetVersionNumber();
+ int32_t GetTotalCodeWords();
+ int32_t GetDimensionForVersion();
+ CBC_CommonBitMatrix* BuildFunctionPattern(int32_t& e);
+ std::vector<int32_t>* GetAlignmentPatternCenters();
+ CBC_QRCoderECBlocks* GetECBlocksForLevel(
+ CBC_QRCoderErrorCorrectionLevel* ecLevel);
+ static CBC_QRCoderVersion* GetVersionForNumber(int32_t versionNumber,
+ int32_t& e);
+ static CBC_QRCoderVersion* GetProvisionalVersionForDimension(
+ int32_t dimension,
+ int32_t& e);
+ static CBC_QRCoderVersion* DecodeVersionInformation(int32_t versionBits,
+ int32_t& e);
+ static void Destroy();
+
+ private:
+ CBC_QRCoderVersion();
+ CBC_QRCoderVersion(int32_t versionNumber,
+ CBC_QRCoderECBlocks* ecBlocks1,
+ CBC_QRCoderECBlocks* ecBlocks2,
+ CBC_QRCoderECBlocks* ecBlocks3,
+ CBC_QRCoderECBlocks* ecBlocks4);
+
+ static const int32_t VERSION_DECODE_INFO[34];
+ static std::vector<CBC_QRCoderVersion*>* VERSION;
+
+ int32_t m_versionNumber;
+ int32_t m_totalCodeWords;
+ std::vector<int32_t> m_alignmentPatternCenters;
+ std::vector<CBC_QRCoderECBlocks*> m_ecBlocksArray;
+};
+
+#endif // FXBARCODE_QRCODE_BC_QRCODERVERSION_H_