Move xfa/src up to xfa/.

This CL moves the xfa/src files up to the xfa/ directory and fixes the includes,
include guards, and build files.

R=tsepez@chromium.org

Review URL: https://codereview.chromium.org/1803723002 .
diff --git a/xfa/fxbarcode/qrcode/BC_FinderPatternInfo.cpp b/xfa/fxbarcode/qrcode/BC_FinderPatternInfo.cpp
new file mode 100644
index 0000000..25dc28b
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_FinderPatternInfo.cpp
@@ -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
+// 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 "xfa/fxbarcode/BC_ResultPoint.h"
+#include "xfa/fxbarcode/qrcode/BC_FinderPatternInfo.h"
+#include "xfa/fxbarcode/qrcode/BC_QRFinderPattern.h"
+
+CBC_QRFinderPatternInfo::CBC_QRFinderPatternInfo(CFX_PtrArray* patternCenters) {
+  m_bottomLeft = (CBC_QRFinderPattern*)(*patternCenters)[0];
+  m_topLeft = (CBC_QRFinderPattern*)(*patternCenters)[1];
+  m_topRight = (CBC_QRFinderPattern*)(*patternCenters)[2];
+}
+CBC_QRFinderPatternInfo::~CBC_QRFinderPatternInfo() {}
+CBC_QRFinderPattern* CBC_QRFinderPatternInfo::GetBottomLeft() {
+  return m_bottomLeft;
+}
+CBC_QRFinderPattern* CBC_QRFinderPatternInfo::GetTopLeft() {
+  return m_topLeft;
+}
+CBC_QRFinderPattern* CBC_QRFinderPatternInfo::GetTopRight() {
+  return m_topRight;
+}
diff --git a/xfa/fxbarcode/qrcode/BC_FinderPatternInfo.h b/xfa/fxbarcode/qrcode/BC_FinderPatternInfo.h
new file mode 100644
index 0000000..0acb106
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_FinderPatternInfo.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 XFA_FXBARCODE_QRCODE_BC_FINDERPATTERNINFO_H_
+#define XFA_FXBARCODE_QRCODE_BC_FINDERPATTERNINFO_H_
+
+#include "core/include/fxcrt/fx_basic.h"
+
+class CBC_QRFinderPattern;
+
+class CBC_QRFinderPatternInfo {
+ private:
+  CBC_QRFinderPattern* m_bottomLeft;
+  CBC_QRFinderPattern* m_topLeft;
+  CBC_QRFinderPattern* m_topRight;
+
+ public:
+  CBC_QRFinderPatternInfo(CFX_PtrArray* patternCenters);
+  virtual ~CBC_QRFinderPatternInfo();
+  CBC_QRFinderPattern* GetBottomLeft();
+  CBC_QRFinderPattern* GetTopLeft();
+  CBC_QRFinderPattern* GetTopRight();
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_FINDERPATTERNINFO_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRAlignmentPattern.cpp b/xfa/fxbarcode/qrcode/BC_QRAlignmentPattern.cpp
new file mode 100644
index 0000000..4d5a36e
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRAlignmentPattern.cpp
@@ -0,0 +1,49 @@
+// 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 "xfa/fxbarcode/BC_ResultPoint.h"
+#include "xfa/fxbarcode/qrcode/BC_QRAlignmentPattern.h"
+
+CBC_QRAlignmentPattern::CBC_QRAlignmentPattern(FX_FLOAT posX,
+                                               FX_FLOAT posY,
+                                               FX_FLOAT estimateModuleSize)
+    : CBC_ResultPoint(posX, posY), m_moduleSize(estimateModuleSize) {}
+CBC_QRAlignmentPattern::~CBC_QRAlignmentPattern() {}
+FX_FLOAT CBC_QRAlignmentPattern::GetX() {
+  return m_x;
+}
+FX_FLOAT CBC_QRAlignmentPattern::GetY() {
+  return m_y;
+}
+FX_BOOL CBC_QRAlignmentPattern::AboutEquals(FX_FLOAT moduleSize,
+                                            FX_FLOAT i,
+                                            FX_FLOAT j) {
+  if ((FXSYS_fabs(i - GetY()) <= moduleSize) &&
+      (FXSYS_fabs(j - GetX()) <= moduleSize)) {
+    FX_FLOAT moduleSizeDiff = FXSYS_fabs(moduleSize - m_moduleSize);
+    return (moduleSizeDiff <= 1.0f) || (moduleSizeDiff / m_moduleSize <= 1.0f);
+  }
+  return FALSE;
+}
+CBC_QRAlignmentPattern* CBC_QRAlignmentPattern::Clone() {
+  return new CBC_QRAlignmentPattern(m_x, m_y, m_moduleSize);
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRAlignmentPattern.h b/xfa/fxbarcode/qrcode/BC_QRAlignmentPattern.h
new file mode 100644
index 0000000..9a4e80c
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRAlignmentPattern.h
@@ -0,0 +1,25 @@
+// 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 XFA_FXBARCODE_QRCODE_BC_QRALIGNMENTPATTERN_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRALIGNMENTPATTERN_H_
+class CBC_ResultPoint;
+class CBC_QRAlignmentPattern : public CBC_ResultPoint {
+ private:
+  FX_FLOAT m_moduleSize;
+
+ public:
+  CBC_QRAlignmentPattern(FX_FLOAT posX,
+                         FX_FLOAT posY,
+                         FX_FLOAT estimateModuleSize);
+  virtual ~CBC_QRAlignmentPattern();
+  FX_BOOL AboutEquals(FX_FLOAT moduleSize, FX_FLOAT i, FX_FLOAT j);
+  FX_FLOAT GetX();
+  FX_FLOAT GetY();
+  CBC_QRAlignmentPattern* Clone();
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRALIGNMENTPATTERN_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.cpp b/xfa/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.cpp
new file mode 100644
index 0000000..8c462bf
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.cpp
@@ -0,0 +1,200 @@
+// 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 "xfa/fxbarcode/BC_ResultPoint.h"
+#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h"
+#include "xfa/fxbarcode/qrcode/BC_QRAlignmentPattern.h"
+#include "xfa/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.h"
+
+CBC_QRAlignmentPatternFinder::CBC_QRAlignmentPatternFinder(
+    CBC_CommonBitMatrix* image,
+    int32_t startX,
+    int32_t startY,
+    int32_t width,
+    int32_t height,
+    FX_FLOAT moduleSize)
+    : m_image(image),
+      m_startX(startX),
+      m_startY(startY),
+      m_width(width),
+      m_height(height),
+      m_moduleSize(moduleSize) {
+  m_crossCheckStateCount.SetSize(3);
+}
+CBC_QRAlignmentPatternFinder::~CBC_QRAlignmentPatternFinder() {
+  for (int32_t i = 0; i < m_possibleCenters.GetSize(); i++) {
+    delete (CBC_QRAlignmentPattern*)m_possibleCenters[i];
+  }
+  m_possibleCenters.RemoveAll();
+}
+CBC_QRAlignmentPattern* CBC_QRAlignmentPatternFinder::Find(int32_t& e) {
+  int32_t startX = m_startX;
+  int32_t height = m_height;
+  int32_t maxJ = startX + m_width;
+  int32_t middleI = m_startY + (height >> 1);
+  CFX_Int32Array stateCount;
+  stateCount.SetSize(3);
+  for (int32_t iGen = 0; iGen < height; iGen++) {
+    int32_t i =
+        middleI + ((iGen & 0x01) == 0 ? ((iGen + 1) >> 1) : -((iGen + 1) >> 1));
+    stateCount[0] = 0;
+    stateCount[1] = 0;
+    stateCount[2] = 0;
+    int32_t j = startX;
+    while (j < maxJ && !m_image->Get(j, i)) {
+      j++;
+    }
+    int32_t currentState = 0;
+    while (j < maxJ) {
+      if (m_image->Get(j, i)) {
+        if (currentState == 1) {
+          stateCount[currentState]++;
+        } else {
+          if (currentState == 2) {
+            if (FoundPatternCross(stateCount)) {
+              CBC_QRAlignmentPattern* confirmed =
+                  HandlePossibleCenter(stateCount, i, j);
+              if (confirmed) {
+                return confirmed;
+              }
+            }
+            stateCount[0] = stateCount[2];
+            stateCount[1] = 1;
+            stateCount[2] = 0;
+            currentState = 1;
+          } else {
+            stateCount[++currentState]++;
+          }
+        }
+      } else {
+        if (currentState == 1) {
+          currentState++;
+        }
+        stateCount[currentState]++;
+      }
+      j++;
+    }
+    if (FoundPatternCross(stateCount)) {
+      CBC_QRAlignmentPattern* confirmed =
+          HandlePossibleCenter(stateCount, i, maxJ);
+      if (confirmed) {
+        return confirmed;
+      }
+    }
+  }
+  if (m_possibleCenters.GetSize() != 0) {
+    return ((CBC_QRAlignmentPattern*)(m_possibleCenters[0]))->Clone();
+  }
+  e = BCExceptionRead;
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  return NULL;
+}
+FX_FLOAT CBC_QRAlignmentPatternFinder::CenterFromEnd(
+    const CFX_Int32Array& stateCount,
+    int32_t end) {
+  return (FX_FLOAT)(end - stateCount[2]) - stateCount[1] / 2.0f;
+}
+FX_BOOL CBC_QRAlignmentPatternFinder::FoundPatternCross(
+    const CFX_Int32Array& stateCount) {
+  FX_FLOAT moduleSize = m_moduleSize;
+  FX_FLOAT maxVariance = moduleSize / 2.0f;
+  for (int32_t i = 0; i < 3; i++) {
+    if (fabs(moduleSize - stateCount[i]) >= maxVariance) {
+      return false;
+    }
+  }
+  return TRUE;
+}
+FX_FLOAT CBC_QRAlignmentPatternFinder::CrossCheckVertical(
+    int32_t startI,
+    int32_t centerJ,
+    int32_t maxCount,
+    int32_t originalStateCountTotal) {
+  int32_t maxI = m_image->GetHeight();
+  CFX_Int32Array stateCount;
+  stateCount.Copy(m_crossCheckStateCount);
+  stateCount[0] = 0;
+  stateCount[1] = 0;
+  stateCount[2] = 0;
+  int32_t i = startI;
+  while (i >= 0 && m_image->Get(centerJ, i) && stateCount[1] <= maxCount) {
+    stateCount[1]++;
+    i--;
+  }
+  if (i < 0 || stateCount[1] > maxCount) {
+    return FXSYS_nan();
+  }
+  while (i >= 0 && !m_image->Get(centerJ, i) && stateCount[0] <= maxCount) {
+    stateCount[0]++;
+    i--;
+  }
+  if (stateCount[0] > maxCount) {
+    return FXSYS_nan();
+  }
+  i = startI + 1;
+  while (i < maxI && m_image->Get(centerJ, i) && stateCount[1] <= maxCount) {
+    stateCount[1]++;
+    i++;
+  }
+  if (i == maxI || stateCount[1] > maxCount) {
+    return FXSYS_nan();
+  }
+  while (i < maxI && !m_image->Get(centerJ, i) && stateCount[2] <= maxCount) {
+    stateCount[2]++;
+    i++;
+  }
+  if (stateCount[2] > maxCount) {
+    return FXSYS_nan();
+  }
+  int32_t stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
+  if (5 * abs(stateCountTotal - originalStateCountTotal) >=
+      originalStateCountTotal) {
+    return FXSYS_nan();
+  }
+  return FoundPatternCross(stateCount) ? CenterFromEnd(stateCount, i)
+                                       : FXSYS_nan();
+}
+CBC_QRAlignmentPattern* CBC_QRAlignmentPatternFinder::HandlePossibleCenter(
+    const CFX_Int32Array& stateCount,
+    int32_t i,
+    int32_t j) {
+  int32_t stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
+  FX_FLOAT centerJ = CenterFromEnd(stateCount, j);
+  FX_FLOAT centerI = CrossCheckVertical(i, (int32_t)centerJ, 2 * stateCount[1],
+                                        stateCountTotal);
+  if (!FXSYS_isnan(centerI)) {
+    FX_FLOAT estimatedModuleSize =
+        (FX_FLOAT)(stateCount[0] + stateCount[1] + stateCount[2]) / 3.0f;
+    int32_t max = m_possibleCenters.GetSize();
+    for (int32_t index = 0; index < max; index++) {
+      CBC_QRAlignmentPattern* center =
+          (CBC_QRAlignmentPattern*)(m_possibleCenters[index]);
+      if (center->AboutEquals(estimatedModuleSize, centerI, centerJ)) {
+        return new CBC_QRAlignmentPattern(centerJ, centerI,
+                                          estimatedModuleSize);
+      }
+    }
+    m_possibleCenters.Add(
+        new CBC_QRAlignmentPattern(centerJ, centerI, estimatedModuleSize));
+  }
+  return NULL;
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.h b/xfa/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.h
new file mode 100644
index 0000000..0b1a2a7
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.h
@@ -0,0 +1,47 @@
+// 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 XFA_FXBARCODE_QRCODE_BC_QRALIGNMENTPATTERNFINDER_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRALIGNMENTPATTERNFINDER_H_
+
+#include "core/include/fxcrt/fx_basic.h"
+#include "xfa/fxbarcode/utils.h"
+
+class CBC_CommonBitMatrix;
+class CBC_QRAlignmentPattern;
+
+class CBC_QRAlignmentPatternFinder {
+ private:
+  CBC_CommonBitMatrix* m_image;
+  CFX_PtrArray m_possibleCenters;
+  int32_t m_startX;
+  int32_t m_startY;
+  int32_t m_width;
+  int32_t m_height;
+  FX_FLOAT m_moduleSize;
+  CFX_Int32Array m_crossCheckStateCount;
+
+ public:
+  CBC_QRAlignmentPatternFinder(CBC_CommonBitMatrix* image,
+                               int32_t startX,
+                               int32_t startY,
+                               int32_t width,
+                               int32_t height,
+                               FX_FLOAT moduleSize);
+  virtual ~CBC_QRAlignmentPatternFinder();
+  FX_BOOL FoundPatternCross(const CFX_Int32Array& stateCount);
+  FX_FLOAT CrossCheckVertical(int32_t startI,
+                              int32_t startJ,
+                              int32_t maxCount,
+                              int32_t originalStateCountTotal);
+  CBC_QRAlignmentPattern* Find(int32_t& e);
+  CBC_QRAlignmentPattern* HandlePossibleCenter(const CFX_Int32Array& stateCount,
+                                               int32_t i,
+                                               int32_t j);
+  static FX_FLOAT CenterFromEnd(const CFX_Int32Array& stateCount, int32_t end);
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRALIGNMENTPATTERNFINDER_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRBitMatrixParser.cpp b/xfa/fxbarcode/qrcode/BC_QRBitMatrixParser.cpp
new file mode 100644
index 0000000..5380358
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRBitMatrixParser.cpp
@@ -0,0 +1,183 @@
+// 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 "xfa/fxbarcode/qrcode/BC_QRBitMatrixParser.h"
+
+#include <memory>
+
+#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h"
+#include "xfa/fxbarcode/qrcode/BC_QRDataMask.h"
+#include "xfa/fxbarcode/utils.h"
+
+CBC_QRBitMatrixParser::CBC_QRBitMatrixParser() {}
+void CBC_QRBitMatrixParser::Init(CBC_CommonBitMatrix* bitMatrix, int32_t& e) {
+  m_dimension = bitMatrix->GetDimension(e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  m_tempBitMatrix = bitMatrix;
+  if (m_dimension < 21 || (m_dimension & 0x03) != 1) {
+    e = BCExceptionRead;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  m_bitMatrix = m_tempBitMatrix;
+  m_parsedFormatInfo = NULL;
+  m_version = NULL;
+}
+CBC_QRBitMatrixParser::~CBC_QRBitMatrixParser() {
+  delete m_parsedFormatInfo;
+}
+CBC_QRCoderFormatInformation* CBC_QRBitMatrixParser::ReadFormatInformation(
+    int32_t& e) {
+  if (m_parsedFormatInfo) {
+    return m_parsedFormatInfo;
+  }
+  int32_t formatInfoBits = 0;
+  int32_t j;
+  for (j = 0; j < 6; j++) {
+    formatInfoBits = CopyBit(8, j, formatInfoBits);
+  }
+  formatInfoBits = CopyBit(8, 7, formatInfoBits);
+  formatInfoBits = CopyBit(8, 8, formatInfoBits);
+  formatInfoBits = CopyBit(7, 8, formatInfoBits);
+  for (int32_t i = 5; i >= 0; i--) {
+    formatInfoBits = CopyBit(i, 8, formatInfoBits);
+  }
+  m_parsedFormatInfo =
+      CBC_QRCoderFormatInformation::DecodeFormatInformation(formatInfoBits);
+  if (m_parsedFormatInfo) {
+    return m_parsedFormatInfo;
+  }
+  int32_t dimension = m_bitMatrix->GetDimension(e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  formatInfoBits = 0;
+  int32_t iMin = dimension - 8;
+  for (j = dimension - 1; j >= iMin; j--) {
+    formatInfoBits = CopyBit(j, 8, formatInfoBits);
+  }
+  for (int32_t k = dimension - 7; k < dimension; k++) {
+    formatInfoBits = CopyBit(8, k, formatInfoBits);
+  }
+  m_parsedFormatInfo =
+      CBC_QRCoderFormatInformation::DecodeFormatInformation(formatInfoBits);
+  if (m_parsedFormatInfo) {
+    return m_parsedFormatInfo;
+  }
+  e = BCExceptionRead;
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  return NULL;
+}
+CBC_QRCoderVersion* CBC_QRBitMatrixParser::ReadVersion(int32_t& e) {
+  if (m_version) {
+    return m_version;
+  }
+  int32_t dimension = m_bitMatrix->GetDimension(e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  int32_t provisionVersion = (dimension - 17) >> 2;
+  if (provisionVersion <= 6) {
+    CBC_QRCoderVersion* qrv =
+        CBC_QRCoderVersion::GetVersionForNumber(provisionVersion, e);
+    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+    return qrv;
+  }
+  int32_t versionBits = 0;
+  for (int32_t i = 5; i >= 0; i--) {
+    int32_t jMin = dimension - 11;
+    for (int32_t j = dimension - 9; j >= jMin; j--) {
+      versionBits = CopyBit(i, j, versionBits);
+    }
+  }
+  m_version = CBC_QRCoderVersion::DecodeVersionInformation(versionBits, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  if (m_version && m_version->GetDimensionForVersion() == dimension) {
+    return m_version;
+  }
+  versionBits = 0;
+  for (int32_t j = 5; j >= 0; j--) {
+    int32_t iMin = dimension - 11;
+    for (int32_t i = dimension - 9; i >= iMin; i--) {
+      versionBits = CopyBit(i, j, versionBits);
+    }
+  }
+  m_version = CBC_QRCoderVersion::DecodeVersionInformation(versionBits, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  if (m_version && m_version->GetDimensionForVersion() == dimension) {
+    return m_version;
+  }
+  e = BCExceptionRead;
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  return NULL;
+}
+int32_t CBC_QRBitMatrixParser::CopyBit(int32_t i,
+                                       int32_t j,
+                                       int32_t versionBits) {
+  return m_bitMatrix->Get(j, i) ? (versionBits << 1) | 0x1 : versionBits << 1;
+}
+CFX_ByteArray* CBC_QRBitMatrixParser::ReadCodewords(int32_t& e) {
+  CBC_QRCoderFormatInformation* formatInfo = ReadFormatInformation(e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL) CBC_QRCoderVersion* version =
+      ReadVersion(e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  CBC_QRDataMask* dataMask =
+      CBC_QRDataMask::ForReference((int32_t)(formatInfo->GetDataMask()), e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  int32_t dimension = m_bitMatrix->GetDimension(e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  dataMask->UnmaskBitMatirx(m_bitMatrix, dimension);
+  std::unique_ptr<CBC_CommonBitMatrix> functionPattern(
+      version->BuildFunctionPattern(e));
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  FX_BOOL readingUp = TRUE;
+  std::unique_ptr<CFX_ByteArray> result(new CFX_ByteArray);
+  result->SetSize(version->GetTotalCodeWords());
+  int32_t resultOffset = 0;
+  int32_t currentByte = 0;
+  int32_t bitsRead = 0;
+  for (int32_t j = dimension - 1; j > 0; j -= 2) {
+    if (j == 6) {
+      j--;
+    }
+    for (int32_t count = 0; count < dimension; count++) {
+      int32_t i = readingUp ? dimension - 1 - count : count;
+      for (int32_t col = 0; col < 2; col++) {
+        if (!functionPattern->Get(j - col, i)) {
+          bitsRead++;
+          currentByte <<= 1;
+          if (m_bitMatrix->Get(j - col, i)) {
+            currentByte |= 1;
+          }
+          if (bitsRead == 8) {
+            (*result)[resultOffset++] = (uint8_t)currentByte;
+            bitsRead = 0;
+            currentByte = 0;
+          }
+        }
+      }
+    }
+    readingUp ^= TRUE;
+  }
+  if (resultOffset != version->GetTotalCodeWords()) {
+    e = BCExceptionRead;
+    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  }
+  return result.release();
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRBitMatrixParser.h b/xfa/fxbarcode/qrcode/BC_QRBitMatrixParser.h
new file mode 100644
index 0000000..6bb1064
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRBitMatrixParser.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 XFA_FXBARCODE_QRCODE_BC_QRBITMATRIXPARSER_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRBITMATRIXPARSER_H_
+
+#include "core/include/fxcrt/fx_basic.h"
+
+class CBC_CommonBitMatrix;
+class CBC_QRCoderVersion;
+class CBC_QRCoderFormatInformation;
+
+class CBC_QRBitMatrixParser {
+ private:
+  CBC_CommonBitMatrix* m_bitMatrix;
+  CBC_CommonBitMatrix* m_tempBitMatrix;
+  CBC_QRCoderVersion* m_version;
+  CBC_QRCoderFormatInformation* m_parsedFormatInfo;
+  int32_t m_dimension;
+
+ public:
+  CBC_QRBitMatrixParser();
+  virtual ~CBC_QRBitMatrixParser();
+  CBC_QRCoderFormatInformation* ReadFormatInformation(int32_t& e);
+  CBC_QRCoderVersion* ReadVersion(int32_t& e);
+  int32_t CopyBit(int32_t i, int32_t j, int32_t versionBits);
+  CFX_ByteArray* ReadCodewords(int32_t& e);
+  virtual void Init(CBC_CommonBitMatrix* bitMatrix, int32_t& e);
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRBITMATRIXPARSER_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRCodeReader.cpp b/xfa/fxbarcode/qrcode/BC_QRCodeReader.cpp
new file mode 100644
index 0000000..716b6c1
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCodeReader.cpp
@@ -0,0 +1,108 @@
+// 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 "xfa/fxbarcode/qrcode/BC_QRCodeReader.h"
+
+#include <memory>
+
+#include "xfa/fxbarcode/BC_Binarizer.h"
+#include "xfa/fxbarcode/BC_BinaryBitmap.h"
+#include "xfa/fxbarcode/BC_BufferedImageLuminanceSource.h"
+#include "xfa/fxbarcode/BC_LuminanceSource.h"
+#include "xfa/fxbarcode/BC_Reader.h"
+#include "xfa/fxbarcode/BC_ResultPoint.h"
+#include "xfa/fxbarcode/common/BC_CommonDecoderResult.h"
+#include "xfa/fxbarcode/common/BC_GlobalHistogramBinarizer.h"
+#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderDecoder.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderMode.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h"
+#include "xfa/fxbarcode/qrcode/BC_QRDataMask.h"
+#include "xfa/fxbarcode/qrcode/BC_QRDetector.h"
+#include "xfa/fxbarcode/qrcode/BC_QRDetectorResult.h"
+
+CBC_QRCodeReader::CBC_QRCodeReader() : m_decoder(NULL) {}
+void CBC_QRCodeReader::Init() {
+  m_decoder = new CBC_QRCoderDecoder;
+  m_decoder->Init();
+}
+CBC_QRCodeReader::~CBC_QRCodeReader() {
+  delete m_decoder;
+}
+CFX_ByteString CBC_QRCodeReader::Decode(CBC_BinaryBitmap* image,
+                                        int32_t hints,
+                                        int32_t& e) {
+  CBC_CommonBitMatrix* matrix = image->GetMatrix(e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, "");
+  CBC_QRDetector detector(matrix);
+  std::unique_ptr<CBC_QRDetectorResult> detectorResult(
+      detector.Detect(hints, e));
+  BC_EXCEPTION_CHECK_ReturnValue(e, "");
+  std::unique_ptr<CBC_CommonDecoderResult> decodeResult(
+      m_decoder->Decode(detectorResult->GetBits(), 0, e));
+  BC_EXCEPTION_CHECK_ReturnValue(e, "");
+  return (decodeResult->GetText());
+}
+CFX_ByteString CBC_QRCodeReader::Decode(const CFX_WideString& filename,
+                                        int32_t hints,
+                                        int32_t byteModeDecode,
+                                        int32_t& e) {
+  CBC_BufferedImageLuminanceSource source(filename);
+  source.Init(e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, "");
+  CBC_GlobalHistogramBinarizer binarizer(&source);
+  CBC_BinaryBitmap bitmap(&binarizer);
+  CFX_ByteString bs = Decode(&bitmap, hints, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, "");
+  return bs;
+}
+CFX_ByteString CBC_QRCodeReader::Decode(CFX_DIBitmap* pBitmap,
+                                        int32_t hints,
+                                        int32_t byteModeDecode,
+                                        int32_t& e) {
+  CBC_BufferedImageLuminanceSource source(pBitmap);
+  CBC_GlobalHistogramBinarizer binarizer(&source);
+  CBC_BinaryBitmap bitmap(&binarizer);
+  CFX_ByteString bs = Decode(&bitmap, hints, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, "");
+  return bs;
+}
+CFX_ByteString CBC_QRCodeReader::Decode(CBC_BinaryBitmap* image, int32_t& e) {
+  CFX_ByteString bs = Decode(image, 0, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, "");
+  return bs;
+}
+void CBC_QRCodeReader::ReleaseAll() {
+  if (CBC_ReedSolomonGF256::QRCodeFild) {
+    delete CBC_ReedSolomonGF256::QRCodeFild;
+    CBC_ReedSolomonGF256::QRCodeFild = NULL;
+  }
+  if (CBC_ReedSolomonGF256::DataMatrixField) {
+    delete CBC_ReedSolomonGF256::DataMatrixField;
+    CBC_ReedSolomonGF256::DataMatrixField = NULL;
+  }
+  CBC_QRCoderMode::Destroy();
+  CBC_QRCoderErrorCorrectionLevel::Destroy();
+  CBC_QRDataMask::Destroy();
+  CBC_QRCoderVersion::Destroy();
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRCodeReader.h b/xfa/fxbarcode/qrcode/BC_QRCodeReader.h
new file mode 100644
index 0000000..72dd453
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCodeReader.h
@@ -0,0 +1,40 @@
+// 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 XFA_FXBARCODE_QRCODE_BC_QRCODEREADER_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRCODEREADER_H_
+
+#include <stdint.h>
+
+#include "core/include/fxcrt/fx_string.h"
+#include "xfa/fxbarcode/BC_Reader.h"
+
+class CBC_BinaryBitmap;
+class CBC_QRCoderDecoder;
+class CFX_DIBitmap;
+
+class CBC_QRCodeReader : public CBC_Reader {
+ private:
+  CBC_QRCoderDecoder* m_decoder;
+
+ public:
+  CBC_QRCodeReader();
+  virtual ~CBC_QRCodeReader();
+  CFX_ByteString Decode(CFX_DIBitmap* pBitmap,
+                        int32_t hints,
+                        int32_t byteModeDecode,
+                        int32_t& e);
+  CFX_ByteString Decode(const CFX_WideString& filename,
+                        int32_t hints,
+                        int32_t byteModeDecode,
+                        int32_t& e);
+  static void ReleaseAll();
+  CFX_ByteString Decode(CBC_BinaryBitmap* image, int32_t hints, int32_t& e);
+  CFX_ByteString Decode(CBC_BinaryBitmap* image, int32_t& e);
+  virtual void Init();
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRCODEREADER_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRCodeWriter.cpp b/xfa/fxbarcode/qrcode/BC_QRCodeWriter.cpp
new file mode 100644
index 0000000..cd4340e
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCodeWriter.cpp
@@ -0,0 +1,107 @@
+// 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 "xfa/fxbarcode/BC_Reader.h"
+#include "xfa/fxbarcode/BC_TwoDimWriter.h"
+#include "xfa/fxbarcode/common/BC_CommonByteMatrix.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCodeReader.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCodeWriter.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoder.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderEncoder.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
+
+CBC_QRCodeWriter::CBC_QRCodeWriter() {
+  m_bFixedSize = TRUE;
+  m_iCorrectLevel = 1;
+  m_iVersion = 0;
+}
+CBC_QRCodeWriter::~CBC_QRCodeWriter() {}
+void CBC_QRCodeWriter::ReleaseAll() {
+  CBC_QRCodeReader::ReleaseAll();
+}
+FX_BOOL CBC_QRCodeWriter::SetVersion(int32_t version) {
+  if (version < 0 || version > 40) {
+    return FALSE;
+  }
+  m_iVersion = version;
+  return TRUE;
+}
+FX_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 = NULL;
+  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;
+      BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+    }
+  }
+  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);
+  }
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  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 NULL;
+}
+uint8_t* CBC_QRCodeWriter::Encode(const CFX_ByteString& contents,
+                                  BCFORMAT format,
+                                  int32_t& outWidth,
+                                  int32_t& outHeight,
+                                  int32_t& e) {
+  return NULL;
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRCodeWriter.h b/xfa/fxbarcode/qrcode/BC_QRCodeWriter.h
new file mode 100644
index 0000000..c68c6c0
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCodeWriter.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 XFA_FXBARCODE_QRCODE_BC_QRCODEWRITER_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRCODEWRITER_H_
+
+#include "xfa/fxbarcode/BC_TwoDimWriter.h"
+
+class CBC_TwoDimWriter;
+class CBC_QRCodeWriter : public CBC_TwoDimWriter {
+ public:
+  CBC_QRCodeWriter();
+  virtual ~CBC_QRCodeWriter();
+  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);
+  FX_BOOL SetVersion(int32_t version);
+  FX_BOOL SetErrorCorrectionLevel(int32_t level);
+  static void ReleaseAll();
+
+ private:
+  int32_t m_iVersion;
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRCODEWRITER_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoder.cpp b/xfa/fxbarcode/qrcode/BC_QRCoder.cpp
new file mode 100644
index 0000000..9e9ad06
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoder.cpp
@@ -0,0 +1,124 @@
+// 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 "xfa/fxbarcode/common/BC_CommonByteMatrix.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoder.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderMode.h"
+#include "xfa/fxbarcode/utils.h"
+
+CBC_QRCoder::CBC_QRCoder() {
+  m_mode = NULL;
+  m_ecLevel = NULL;
+  m_version = -1;
+  m_matrixWidth = -1;
+  m_maskPattern = -1;
+  m_numTotalBytes = -1;
+  m_numDataBytes = -1;
+  m_numECBytes = -1;
+  m_numRSBlocks = -1;
+  m_matrix = NULL;
+}
+CBC_QRCoder::~CBC_QRCoder() {
+  delete m_matrix;
+}
+CBC_QRCoderMode* CBC_QRCoder::GetMode() {
+  return m_mode;
+}
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoder::GetECLevel() {
+  return m_ecLevel;
+}
+int32_t CBC_QRCoder::GetVersion() {
+  return m_version;
+}
+int32_t CBC_QRCoder::GetMatrixWidth() {
+  return m_matrixWidth;
+}
+int32_t CBC_QRCoder::GetMaskPattern() {
+  return m_maskPattern;
+}
+int32_t CBC_QRCoder::GetNumTotalBytes() {
+  return m_numTotalBytes;
+}
+int32_t CBC_QRCoder::GetNumDataBytes() {
+  return m_numDataBytes;
+}
+int32_t CBC_QRCoder::GetNumECBytes() {
+  return m_numECBytes;
+}
+int32_t CBC_QRCoder::GetNumRSBlocks() {
+  return m_numRSBlocks;
+}
+CBC_CommonByteMatrix* CBC_QRCoder::GetMatrix() {
+  return m_matrix;
+}
+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;
+    BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+  }
+  return value;
+}
+FX_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;
+}
+FX_BOOL CBC_QRCoder::IsValidMaskPattern(int32_t maskPattern) {
+  return maskPattern >= 0 && maskPattern < NUM_MASK_PATTERNS;
+}
+void CBC_QRCoder::SetMatrix(CBC_CommonByteMatrix* value) {
+  m_matrix = value;
+}
+const int32_t CBC_QRCoder::NUM_MASK_PATTERNS = 8;
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoder.h b/xfa/fxbarcode/qrcode/BC_QRCoder.h
new file mode 100644
index 0000000..bbf7bd4
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoder.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 XFA_FXBARCODE_QRCODE_BC_QRCODER_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRCODER_H_
+
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRCoderMode;
+class CBC_CommonByteMatrix;
+
+class CBC_QRCoder {
+ 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;
+  CBC_CommonByteMatrix* m_matrix;
+
+ public:
+  static const int32_t NUM_MASK_PATTERNS;
+  CBC_QRCoder();
+  virtual ~CBC_QRCoder();
+  CBC_QRCoderMode* GetMode();
+  CBC_QRCoderErrorCorrectionLevel* GetECLevel();
+  int32_t GetVersion();
+  int32_t GetMatrixWidth();
+  int32_t GetMaskPattern();
+  int32_t GetNumTotalBytes();
+  int32_t GetNumDataBytes();
+  int32_t GetNumECBytes();
+  int32_t GetNumRSBlocks();
+  CBC_CommonByteMatrix* GetMatrix();
+  int32_t At(int32_t x, int32_t y, int32_t& e);
+  FX_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(CBC_CommonByteMatrix* value);
+  static FX_BOOL IsValidMaskPattern(int32_t maskPattern);
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRCODER_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderBitVector.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderBitVector.cpp
new file mode 100644
index 0000000..a225f61
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderBitVector.cpp
@@ -0,0 +1,124 @@
+// 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/include/fxcrt/fx_memory.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderBitVector.h"
+#include "xfa/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;
+    BC_EXCEPTION_CHECK_ReturnValue(e, 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;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  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;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  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);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+      --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);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+    AppendBit(num, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e)
+  }
+}
+void CBC_QRCoderBitVector::XOR(CBC_QRCoderBitVector* other, int32_t& e) {
+  if (m_sizeInBits != other->Size()) {
+    e = BCExceptioncanNotOperatexorOperator;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  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/xfa/fxbarcode/qrcode/BC_QRCoderBitVector.h b/xfa/fxbarcode/qrcode/BC_QRCoderBitVector.h
new file mode 100644
index 0000000..7742541
--- /dev/null
+++ b/xfa/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 XFA_FXBARCODE_QRCODE_BC_QRCODERBITVECTOR_H_
+#define XFA_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  // XFA_FXBARCODE_QRCODE_BC_QRCODERBITVECTOR_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderBlockPair.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderBlockPair.cpp
new file mode 100644
index 0000000..b8a032a
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderBlockPair.cpp
@@ -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
+// 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 "xfa/fxbarcode/common/BC_CommonByteArray.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderBlockPair.h"
+
+CBC_QRCoderBlockPair::CBC_QRCoderBlockPair(
+    CBC_CommonByteArray* data,
+    CBC_CommonByteArray* errorCorrection) {
+  m_dataBytes = data;
+  m_errorCorrectionBytes = errorCorrection;
+}
+CBC_QRCoderBlockPair::~CBC_QRCoderBlockPair() {
+  delete m_dataBytes;
+  delete m_errorCorrectionBytes;
+}
+CBC_CommonByteArray* CBC_QRCoderBlockPair::GetDataBytes() {
+  return m_dataBytes;
+}
+CBC_CommonByteArray* CBC_QRCoderBlockPair::GetErrorCorrectionBytes() {
+  return m_errorCorrectionBytes;
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderBlockPair.h b/xfa/fxbarcode/qrcode/BC_QRCoderBlockPair.h
new file mode 100644
index 0000000..5427436
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderBlockPair.h
@@ -0,0 +1,25 @@
+// 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 XFA_FXBARCODE_QRCODE_BC_QRCODERBLOCKPAIR_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRCODERBLOCKPAIR_H_
+
+class CBC_CommonByteArray;
+class CBC_QRCoderBlockPair {
+ private:
+  CBC_CommonByteArray* m_dataBytes;
+  CBC_CommonByteArray* m_errorCorrectionBytes;
+
+ public:
+  CBC_QRCoderBlockPair(CBC_CommonByteArray* data,
+                       CBC_CommonByteArray* errorCorrection);
+  virtual ~CBC_QRCoderBlockPair();
+
+  CBC_CommonByteArray* GetDataBytes();
+  CBC_CommonByteArray* GetErrorCorrectionBytes();
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRCODERBLOCKPAIR_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderDecoder.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderDecoder.cpp
new file mode 100644
index 0000000..1966146
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderDecoder.cpp
@@ -0,0 +1,129 @@
+// 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 "xfa/fxbarcode/qrcode/BC_QRCoderDecoder.h"
+
+#include <memory>
+
+#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h"
+#include "xfa/fxbarcode/common/BC_CommonDecoderResult.h"
+#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonDecoder.h"
+#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h"
+#include "xfa/fxbarcode/qrcode/BC_QRBitMatrixParser.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h"
+#include "xfa/fxbarcode/qrcode/BC_QRDataBlock.h"
+#include "xfa/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.h"
+
+CBC_QRCoderDecoder::CBC_QRCoderDecoder() {
+  m_rsDecoder = NULL;
+}
+
+void CBC_QRCoderDecoder::Init() {
+  m_rsDecoder = new CBC_ReedSolomonDecoder(CBC_ReedSolomonGF256::QRCodeFild);
+}
+CBC_QRCoderDecoder::~CBC_QRCoderDecoder() {
+  delete m_rsDecoder;
+}
+CBC_CommonDecoderResult* CBC_QRCoderDecoder::Decode(FX_BOOL* image,
+                                                    int32_t width,
+                                                    int32_t height,
+                                                    int32_t& e) {
+  CBC_CommonBitMatrix bits;
+  bits.Init(width);
+  for (int32_t i = 0; i < width; i++) {
+    for (int32_t j = 0; j < height; j++) {
+      if (image[i * width + j]) {
+        bits.Set(j, i);
+      }
+    }
+  }
+  CBC_CommonDecoderResult* cdr = Decode(&bits, height, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  return cdr;
+}
+CBC_CommonDecoderResult* CBC_QRCoderDecoder::Decode(CBC_CommonBitMatrix* bits,
+                                                    int32_t byteModeDecode,
+                                                    int32_t& e) {
+  CBC_QRBitMatrixParser parser;
+  parser.Init(bits, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  CBC_QRCoderVersion* version = parser.ReadVersion(e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  CBC_QRCoderFormatInformation* temp = parser.ReadFormatInformation(e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  CBC_QRCoderErrorCorrectionLevel* ecLevel = temp->GetErrorCorrectionLevel();
+  std::unique_ptr<CFX_ByteArray> codewords(parser.ReadCodewords(e));
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  CFX_PtrArray* dataBlocks =
+      CBC_QRDataBlock::GetDataBlocks(codewords.get(), version, ecLevel, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  int32_t totalBytes = 0;
+  for (int32_t i = 0; i < dataBlocks->GetSize(); i++) {
+    totalBytes += ((CBC_QRDataBlock*)((*dataBlocks)[i]))->GetNumDataCodewords();
+  }
+  CFX_ByteArray resultBytes;
+  for (int32_t j = 0; j < dataBlocks->GetSize(); j++) {
+    CBC_QRDataBlock* dataBlock = (CBC_QRDataBlock*)((*dataBlocks)[j]);
+    CFX_ByteArray* codewordBytes = dataBlock->GetCodewords();
+    int32_t numDataCodewords = dataBlock->GetNumDataCodewords();
+    CorrectErrors(codewordBytes, numDataCodewords, e);
+    if (e != BCExceptionNO) {
+      for (int32_t k = 0; k < dataBlocks->GetSize(); k++) {
+        delete (CBC_QRDataBlock*)(*dataBlocks)[k];
+      }
+      dataBlocks->RemoveAll();
+      delete dataBlocks;
+      dataBlocks = NULL;
+      return NULL;
+    }
+    for (int32_t i = 0; i < numDataCodewords; i++) {
+      resultBytes.Add((*codewordBytes)[i]);
+    }
+  }
+  for (int32_t k = 0; k < dataBlocks->GetSize(); k++) {
+    delete (CBC_QRDataBlock*)(*dataBlocks)[k];
+  }
+  dataBlocks->RemoveAll();
+  delete dataBlocks;
+  dataBlocks = NULL;
+  CBC_CommonDecoderResult* cdr = CBC_QRDecodedBitStreamParser::Decode(
+      &resultBytes, version, ecLevel, byteModeDecode, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  return cdr;
+}
+void CBC_QRCoderDecoder::CorrectErrors(CFX_ByteArray* codewordBytes,
+                                       int32_t numDataCodewords,
+                                       int32_t& e) {
+  int32_t numCodewords = codewordBytes->GetSize();
+  CFX_Int32Array codewordsInts;
+  codewordsInts.SetSize(numCodewords);
+  for (int32_t i = 0; i < numCodewords; i++) {
+    codewordsInts[i] = (int32_t)((*codewordBytes)[i] & 0xff);
+  }
+  int32_t numECCodewords = codewordBytes->GetSize() - numDataCodewords;
+  m_rsDecoder->Decode(&codewordsInts, numECCodewords, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  for (int32_t k = 0; k < numDataCodewords; k++) {
+    (*codewordBytes)[k] = (uint8_t)codewordsInts[k];
+  }
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderDecoder.h b/xfa/fxbarcode/qrcode/BC_QRCoderDecoder.h
new file mode 100644
index 0000000..b6c381c
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderDecoder.h
@@ -0,0 +1,37 @@
+// 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 XFA_FXBARCODE_QRCODE_BC_QRCODERDECODER_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRCODERDECODER_H_
+
+#include "core/include/fxcrt/fx_basic.h"
+
+class CBC_CommonBitMatrix;
+class CBC_ReedSolomonDecoder;
+class CBC_CommonDecoderResult;
+
+class CBC_QRCoderDecoder {
+ private:
+  CBC_ReedSolomonDecoder* m_rsDecoder;
+
+ public:
+  CBC_QRCoderDecoder();
+  virtual ~CBC_QRCoderDecoder();
+
+  CBC_CommonDecoderResult* Decode(FX_BOOL* image,
+                                  int32_t width,
+                                  int32_t height,
+                                  int32_t& e);
+  CBC_CommonDecoderResult* Decode(CBC_CommonBitMatrix* bits,
+                                  int32_t byteModeDecode,
+                                  int32_t& e);
+  void CorrectErrors(CFX_ByteArray* codewordBytes,
+                     int32_t numDataCodewords,
+                     int32_t& e);
+  virtual void Init();
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRCODERDECODER_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderECB.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderECB.cpp
new file mode 100644
index 0000000..2b5a2a6
--- /dev/null
+++ b/xfa/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 "xfa/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/xfa/fxbarcode/qrcode/BC_QRCoderECB.h b/xfa/fxbarcode/qrcode/BC_QRCoderECB.h
new file mode 100644
index 0000000..25b0b20
--- /dev/null
+++ b/xfa/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 XFA_FXBARCODE_QRCODE_BC_QRCODERECB_H_
+#define XFA_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  // XFA_FXBARCODE_QRCODE_BC_QRCODERECB_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.cpp
new file mode 100644
index 0000000..eb6d194
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.cpp
@@ -0,0 +1,59 @@
+// 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 "xfa/fxbarcode/qrcode/BC_QRCoderECB.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.h"
+
+CBC_QRCoderECBlocks::CBC_QRCoderECBlocks(int32_t ecCodeWordsPerBlock,
+                                         CBC_QRCoderECB* ecBlocks) {
+  m_ecCodeWordsPerBlock = ecCodeWordsPerBlock;
+  m_ecBlocks.Add(ecBlocks);
+}
+CBC_QRCoderECBlocks::CBC_QRCoderECBlocks(int32_t ecCodeWordsPerBlock,
+                                         CBC_QRCoderECB* ecBlocks1,
+                                         CBC_QRCoderECB* ecBlocks2) {
+  m_ecCodeWordsPerBlock = ecCodeWordsPerBlock;
+  m_ecBlocks.Add(ecBlocks1);
+  m_ecBlocks.Add(ecBlocks2);
+}
+CBC_QRCoderECBlocks::~CBC_QRCoderECBlocks() {
+  for (int32_t i = 0; i < m_ecBlocks.GetSize(); i++) {
+    delete ((CBC_QRCoderECB*)(m_ecBlocks[i]));
+  }
+  m_ecBlocks.RemoveAll();
+}
+int32_t CBC_QRCoderECBlocks::GetECCodeWordsPerBlock() {
+  return m_ecCodeWordsPerBlock;
+}
+int32_t CBC_QRCoderECBlocks::GetNumBlocks() {
+  int32_t total = 0;
+  for (int32_t i = 0; i < m_ecBlocks.GetSize(); i++) {
+    total += ((CBC_QRCoderECB*)(m_ecBlocks[i]))->GetCount();
+  }
+  return total;
+}
+int32_t CBC_QRCoderECBlocks::GetTotalECCodeWords() {
+  return m_ecCodeWordsPerBlock * GetNumBlocks();
+}
+CFX_PtrArray* CBC_QRCoderECBlocks::GetECBlocks() {
+  return &m_ecBlocks;
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.h b/xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.h
new file mode 100644
index 0000000..c1a5b34
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.h
@@ -0,0 +1,31 @@
+// 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 XFA_FXBARCODE_QRCODE_BC_QRCODERECBLOCKS_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRCODERECBLOCKS_H_
+
+#include "core/include/fxcrt/fx_basic.h"
+
+class CBC_QRCoderECB;
+
+class CBC_QRCoderECBlocks {
+ private:
+  int32_t m_ecCodeWordsPerBlock;
+  CFX_PtrArray m_ecBlocks;
+
+ public:
+  CBC_QRCoderECBlocks(int32_t ecCodeWordsPerBlock, CBC_QRCoderECB* ecBlocks);
+  CBC_QRCoderECBlocks(int32_t ecCodeWordsPerBlock,
+                      CBC_QRCoderECB* ecBlocks1,
+                      CBC_QRCoderECB* ecBlocks2);
+  virtual ~CBC_QRCoderECBlocks();
+  int32_t GetECCodeWordsPerBlock();
+  int32_t GetNumBlocks();
+  int32_t GetTotalECCodeWords();
+  CFX_PtrArray* GetECBlocks();
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRCODERECBLOCKS_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.cpp
new file mode 100644
index 0000000..0360ef0
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.cpp
@@ -0,0 +1,961 @@
+// 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 "xfa/fxbarcode/qrcode/BC_QRCoderEncoder.h"
+
+#include <algorithm>
+#include <memory>
+
+#include "xfa/fxbarcode/BC_UtilCodingConvert.h"
+#include "xfa/fxbarcode/common/BC_CommonByteArray.h"
+#include "xfa/fxbarcode/common/BC_CommonByteMatrix.h"
+#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomon.h"
+#include "xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoder.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderBitVector.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderBlockPair.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderMode.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h"
+
+const int32_t CBC_QRCoderEncoder::m_alphaNumbericTable[] = {
+    -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};
+
+CBC_QRCoderEncoder::CBC_QRCoderEncoder() {}
+CBC_QRCoderEncoder::~CBC_QRCoderEncoder() {}
+class Make_Pair {
+ public:
+  CBC_QRCoderMode* m_mode;
+  CFX_ByteString m_string;
+
+ private:
+  Make_Pair(const Make_Pair& mode_string) {}
+  Make_Pair& operator=(Make_Pair& mode_string) {
+    if (this == &mode_string) {
+      return *this;
+    }
+    m_mode = mode_string.m_mode;
+    m_string = mode_string.m_string;
+    return *this;
+  }
+
+ public:
+  Make_Pair(CBC_QRCoderMode* mode, const CFX_ByteString& str)
+      : m_mode(mode), m_string(str) {}
+  ~Make_Pair() {}
+};
+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);
+    BC_EXCEPTION_CHECK_ReturnVoid(e)
+  } else if (versionSpecify > 0 && versionSpecify <= 40) {
+    EncodeWithSpecifyVersion(content, ecLevel, qrCode, versionSpecify, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  } else {
+    e = BCExceptionVersionMust1_40;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+}
+void CBC_QRCoderEncoder::AppendECI(CBC_QRCoderBitVector* bits) {}
+void CBC_QRCoderEncoder::AppendDataModeLenghInfo(
+    CFX_PtrArray& splitResult,
+    CBC_QRCoderBitVector& headerAndDataBits,
+    CBC_QRCoderMode* tempMode,
+    CBC_QRCoder* qrCode,
+    CFX_ByteString& encoding,
+    int32_t& e) {
+  for (int32_t i = 0; i < splitResult.GetSize(); i++) {
+    tempMode = ((Make_Pair*)splitResult[i])->m_mode;
+    if (tempMode == CBC_QRCoderMode::sGBK) {
+      AppendModeInfo(tempMode, &headerAndDataBits, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+      AppendLengthInfo(((Make_Pair*)splitResult[i])->m_string.GetLength(),
+                       qrCode->GetVersion(), tempMode, &headerAndDataBits, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+      AppendBytes(((Make_Pair*)splitResult[i])->m_string, tempMode,
+                  &headerAndDataBits, encoding, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    } else if (tempMode == CBC_QRCoderMode::sBYTE) {
+      CFX_ByteArray bytes;
+      CBC_UtilCodingConvert::LocaleToUtf8(
+          ((Make_Pair*)splitResult[i])->m_string, bytes);
+      AppendModeInfo(tempMode, &headerAndDataBits, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+      AppendLengthInfo(bytes.GetSize(), qrCode->GetVersion(), tempMode,
+                       &headerAndDataBits, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+      Append8BitBytes(bytes, &headerAndDataBits, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    } else if (tempMode == CBC_QRCoderMode::sALPHANUMERIC) {
+      AppendModeInfo(tempMode, &headerAndDataBits, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+      AppendLengthInfo(((Make_Pair*)splitResult[i])->m_string.GetLength(),
+                       qrCode->GetVersion(), tempMode, &headerAndDataBits, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+      AppendBytes(((Make_Pair*)splitResult[i])->m_string, tempMode,
+                  &headerAndDataBits, encoding, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    } else if (tempMode == CBC_QRCoderMode::sNUMERIC) {
+      AppendModeInfo(tempMode, &headerAndDataBits, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+      AppendLengthInfo(((Make_Pair*)splitResult[i])->m_string.GetLength(),
+                       qrCode->GetVersion(), tempMode, &headerAndDataBits, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+      AppendBytes(((Make_Pair*)splitResult[i])->m_string, tempMode,
+                  &headerAndDataBits, encoding, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    } else {
+      e = BCExceptionUnknown;
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    }
+  }
+}
+void CBC_QRCoderEncoder::SplitString(const CFX_ByteString& content,
+                                     CFX_PtrArray& 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.Add(
+        new Make_Pair(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.Add(
+        new Make_Pair(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.Add(new Make_Pair(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.Add(new Make_Pair(CBC_QRCoderMode::sALPHANUMERIC,
+                             content.Mid(flag, index - flag)));
+  }
+  flag = index;
+  if (index >= content.GetLength()) {
+    return;
+  }
+  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;
+    } else if (versionNum >= 10 && versionNum <= 26) {
+      return 15;
+    } else if (versionNum >= 27 && versionNum <= 40) {
+      return 16;
+    } else {
+      e = BCExceptionNoSuchVersion;
+      BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+    }
+  } else if ((modeSecond == CBC_QRCoderMode::sALPHANUMERIC) &&
+             (modeFirst == CBC_QRCoderMode::sNUMERIC)) {
+    if (versionNum >= 1 && versionNum <= 9) {
+      return 13;
+    } else if (versionNum >= 10 && versionNum <= 26) {
+      return 15;
+    } else if (versionNum >= 27 && versionNum <= 40) {
+      return 17;
+    } else {
+      e = BCExceptionNoSuchVersion;
+      BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+    }
+  } else if ((modeSecond == CBC_QRCoderMode::sBYTE) &&
+             (modeFirst == CBC_QRCoderMode::sNUMERIC)) {
+    if (versionNum >= 1 && versionNum <= 9) {
+      return 6;
+    } else if (versionNum >= 10 && versionNum <= 26) {
+      return 8;
+    } else if (versionNum >= 27 && versionNum <= 40) {
+      return 9;
+    } else {
+      e = BCExceptionNoSuchVersion;
+      BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+    }
+  }
+  return -1;
+}
+void CBC_QRCoderEncoder::MergeString(CFX_PtrArray& result,
+                                     int32_t versionNum,
+                                     int32_t& e) {
+  Make_Pair* first = NULL;
+  Make_Pair* second = NULL;
+  size_t mergeNum = 0;
+  int32_t i;
+  for (i = 0; ((i < result.GetSize()) && (i + 1 < result.GetSize())); i++) {
+    first = (Make_Pair*)result[i];
+    second = (Make_Pair*)result[i + 1];
+    if (first->m_mode == CBC_QRCoderMode::sALPHANUMERIC) {
+      int32_t tmp = GetSpanByVersion(CBC_QRCoderMode::sALPHANUMERIC,
+                                     CBC_QRCoderMode::sBYTE, versionNum, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+      if ((second->m_mode == CBC_QRCoderMode::sBYTE) &&
+          (first->m_string.GetLength() < tmp)) {
+        CFX_ByteString str = first->m_string + second->m_string;
+        second->m_string = str;
+        delete first;
+        result.RemoveAt(i);
+        i--;
+        mergeNum++;
+      }
+    } else if (first->m_mode == CBC_QRCoderMode::sBYTE) {
+      if (second->m_mode == CBC_QRCoderMode::sBYTE) {
+        first->m_string += second->m_string;
+        delete second;
+        result.RemoveAt(i + 1);
+        i--;
+        mergeNum++;
+      }
+    } else if (first->m_mode == CBC_QRCoderMode::sNUMERIC) {
+      int32_t tmp = GetSpanByVersion(CBC_QRCoderMode::sNUMERIC,
+                                     CBC_QRCoderMode::sBYTE, versionNum, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+      if ((second->m_mode == CBC_QRCoderMode::sBYTE) &&
+          (first->m_string.GetLength() < tmp)) {
+        CFX_ByteString str = first->m_string + second->m_string;
+        second->m_string = str;
+        delete first;
+        result.RemoveAt(i);
+        i--;
+        mergeNum++;
+      }
+      tmp = GetSpanByVersion(CBC_QRCoderMode::sNUMERIC,
+                             CBC_QRCoderMode::sALPHANUMERIC, versionNum, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+      if ((second->m_mode == CBC_QRCoderMode::sALPHANUMERIC) &&
+          (first->m_string.GetLength() < tmp)) {
+        CFX_ByteString str = first->m_string + second->m_string;
+        second->m_string = str;
+        delete first;
+        result.RemoveAt(i);
+        i--;
+        mergeNum++;
+      }
+    }
+  }
+  if (mergeNum == 0) {
+    return;
+  }
+  MergeString(result, versionNum, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+}
+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);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  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(versionNumber);
+    qrCode->SetNumTotalBytes(numBytes);
+    qrCode->SetNumDataBytes(numDataBytes);
+    qrCode->SetNumRSBlocks(numRSBlocks);
+    qrCode->SetNumECBytes(numEcBytes);
+    qrCode->SetMatrixWidth(version->GetDimensionForVersion());
+    return;
+  }
+  e = BCExceptionCannotFindBlockInfo;
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+}
+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;
+  CFX_PtrArray splitResult;
+  CBC_QRCoderBitVector dataBits;
+  dataBits.Init();
+  SplitString(content, splitResult);
+  MergeString(splitResult, versionSpecify, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e) CBC_QRCoderMode* tempMode = NULL;
+  for (int32_t i = 0; i < splitResult.GetSize(); i++) {
+    AppendBytes(((Make_Pair*)splitResult[i])->m_string,
+                ((Make_Pair*)splitResult[i])->m_mode, &dataBits, encoding, e);
+    if (e != BCExceptionNO) {
+      for (int32_t y = 0; y < splitResult.GetSize(); y++) {
+        delete (Make_Pair*)splitResult[y];
+      }
+      splitResult.RemoveAll();
+      return;
+    }
+  }
+  int32_t numInputBytes = dataBits.sizeInBytes();
+  CBC_QRCoderBitVector headerAndDataBits;
+  headerAndDataBits.Init();
+  InitQRCode(numInputBytes, versionSpecify, ecLevel, mode, qrCode, e);
+  if (e != BCExceptionNO) {
+    for (int32_t k = 0; k < splitResult.GetSize(); k++) {
+      delete (Make_Pair*)splitResult[k];
+    }
+    splitResult.RemoveAll();
+    return;
+  }
+  AppendDataModeLenghInfo(splitResult, headerAndDataBits, tempMode, qrCode,
+                          encoding, e);
+  if (e != BCExceptionNO) {
+    for (int32_t k = 0; k < splitResult.GetSize(); k++) {
+      delete (Make_Pair*)splitResult[k];
+    }
+    splitResult.RemoveAll();
+    return;
+  }
+  numInputBytes = headerAndDataBits.sizeInBytes();
+  TerminateBits(qrCode->GetNumDataBytes(), &headerAndDataBits, e);
+  if (e != BCExceptionNO) {
+    for (int32_t k = 0; k < splitResult.GetSize(); k++) {
+      delete (Make_Pair*)splitResult[k];
+    }
+    splitResult.RemoveAll();
+    return;
+  }
+  for (int32_t j = 0; j < splitResult.GetSize(); j++) {
+    delete (Make_Pair*)splitResult[j];
+  }
+  splitResult.RemoveAll();
+  CBC_QRCoderBitVector finalBits;
+  finalBits.Init();
+  InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(),
+                        qrCode->GetNumDataBytes(), qrCode->GetNumRSBlocks(),
+                        &finalBits, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  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);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  qrCode->SetMaskPattern(maskPattern);
+  CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(),
+                                     qrCode->GetVersion(),
+                                     qrCode->GetMaskPattern(), matrix.get(), e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  qrCode->SetMatrix(matrix.release());
+  if (!qrCode->IsValid()) {
+    e = BCExceptionInvalidQRCode;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+}
+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;
+  CFX_PtrArray splitResult;
+  CBC_QRCoderBitVector dataBits;
+  dataBits.Init();
+  SplitString(content, splitResult);
+  MergeString(splitResult, 8, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  CBC_QRCoderMode* tempMode = NULL;
+  for (int32_t i = 0; i < splitResult.GetSize(); i++) {
+    AppendBytes(((Make_Pair*)splitResult[i])->m_string,
+                ((Make_Pair*)splitResult[i])->m_mode, &dataBits, encoding, e);
+    if (e != BCExceptionNO) {
+      for (int32_t l = 0; l < splitResult.GetSize(); l++) {
+        delete (Make_Pair*)splitResult[l];
+      }
+      splitResult.RemoveAll();
+      return;
+    }
+  }
+  int32_t numInputBytes = dataBits.sizeInBytes();
+  InitQRCode(numInputBytes, ecLevel, mode, qrCode, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e) CBC_QRCoderBitVector headerAndDataBits;
+  headerAndDataBits.Init();
+  tempMode = NULL;
+  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 {
+      for (int32_t j = 0; j < splitResult.GetSize(); j++) {
+        delete (Make_Pair*)splitResult[j];
+      }
+      splitResult.RemoveAll();
+      return;
+    }
+  }
+  for (int32_t k = 0; k < splitResult.GetSize(); k++) {
+    delete (Make_Pair*)splitResult[k];
+  }
+  splitResult.RemoveAll();
+  CBC_QRCoderBitVector finalBits;
+  finalBits.Init();
+  InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(),
+                        qrCode->GetNumDataBytes(), qrCode->GetNumRSBlocks(),
+                        &finalBits, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  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);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  qrCode->SetMaskPattern(maskPattern);
+  CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(),
+                                     qrCode->GetVersion(),
+                                     qrCode->GetMaskPattern(), matrix.get(), e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e) qrCode->SetMatrix(matrix.release());
+  if (!qrCode->IsValid()) {
+    e = BCExceptionInvalidQRCode;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+}
+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);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  int32_t numInputBytes = dataBits.sizeInBytes();
+  InitQRCode(numInputBytes, ecLevel, mode, qrCode, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  CBC_QRCoderBitVector headerAndDataBits;
+  headerAndDataBits.Init();
+  AppendModeInfo(mode, &headerAndDataBits, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  int32_t numLetters = mode == CBC_QRCoderMode::sBYTE ? dataBits.sizeInBytes()
+                                                      : content.GetLength();
+  AppendLengthInfo(numLetters, qrCode->GetVersion(), mode, &headerAndDataBits,
+                   e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  headerAndDataBits.AppendBitVector(&dataBits, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e)
+      TerminateBits(qrCode->GetNumDataBytes(), &headerAndDataBits, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  CBC_QRCoderBitVector finalBits;
+  finalBits.Init();
+  InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(),
+                        qrCode->GetNumDataBytes(), qrCode->GetNumRSBlocks(),
+                        &finalBits, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  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);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  qrCode->SetMaskPattern(maskPattern);
+  CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(),
+                                     qrCode->GetVersion(),
+                                     qrCode->GetMaskPattern(), matrix.get(), e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e) qrCode->SetMatrix(matrix.release());
+  if (!qrCode->IsValid()) {
+    e = BCExceptionInvalidQRCode;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+}
+void CBC_QRCoderEncoder::TerminateBits(int32_t numDataBytes,
+                                       CBC_QRCoderBitVector* bits,
+                                       int32_t& e) {
+  int32_t capacity = numDataBytes << 3;
+  if (bits->Size() > capacity) {
+    e = BCExceptionDataTooMany;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  for (int32_t i = 0; i < 4 && bits->Size() < capacity; ++i) {
+    bits->AppendBit(0, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  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);
+      BC_EXCEPTION_CHECK_ReturnVoid(e)
+    }
+  }
+  if (bits->Size() % 8 != 0) {
+    e = BCExceptionDigitLengthMustBe8;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  int32_t numPaddingBytes = numDataBytes - bits->sizeInBytes();
+  for (int32_t k = 0; k < numPaddingBytes; ++k) {
+    if (k % 2 == 0) {
+      bits->AppendBits(0xec, 8, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    } else {
+      bits->AppendBits(0x11, 8, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    }
+  }
+  if (bits->Size() != capacity) {
+    e = BCExceptionBitsNotEqualCacity;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+}
+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::NUM_MASK_PATTERNS;
+       maskPattern++) {
+    CBC_QRCoderMatrixUtil::BuildMatrix(bits, ecLevel, version, maskPattern,
+                                       matrix, e);
+    BC_EXCEPTION_CHECK_ReturnValue(e, 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;
+  }
+  FX_BOOL hasNumeric = FALSE;
+  FX_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) {
+  if (code < 96 && code >= 0) {
+    return m_alphaNumbericTable[code];
+  }
+  return -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);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  } else if (mode == CBC_QRCoderMode::sALPHANUMERIC) {
+    AppendAlphaNumericBytes(content, bits, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  } else if (mode == CBC_QRCoderMode::sBYTE) {
+    Append8BitBytes(content, bits, encoding, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  } else if (mode == CBC_QRCoderMode::sKANJI) {
+    AppendKanjiBytes(content, bits, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  } else if (mode == CBC_QRCoderMode::sGBK) {
+    AppendGBKBytes(content, bits, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  } else {
+    e = BCExceptionUnsupportedMode;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+}
+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);
+      BC_EXCEPTION_CHECK_ReturnVoid(e) i += 3;
+    } else if (i + 1 < length) {
+      int32_t num2 = content[i + 1] - '0';
+      bits->AppendBits(num1 * 10 + num2, 7, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e) i += 2;
+    } else {
+      bits->AppendBits(num1, 4, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+      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;
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    }
+    if (i + 1 < length) {
+      int32_t code2 = GetAlphaNumericCode(content[i + 1]);
+      if (code2 == -1) {
+        e = BCExceptionInvalidateCharacter;
+        BC_EXCEPTION_CHECK_ReturnVoid(e);
+      }
+      bits->AppendBits(code1 * 45 + code2, 11, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+      i += 2;
+    } else {
+      bits->AppendBits(code1, 6, e);
+      BC_EXCEPTION_CHECK_ReturnVoid(e) i++;
+    }
+  }
+}
+void CBC_QRCoderEncoder::AppendGBKBytes(const CFX_ByteString& content,
+                                        CBC_QRCoderBitVector* bits,
+                                        int32_t& e) {
+  int32_t length = content.GetLength();
+  FX_DWORD value = 0;
+  for (int32_t i = 0; i < length; i += 2) {
+    value = (FX_DWORD)((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;
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    }
+    value = (FX_DWORD)((value >> 8) * 0x60) + (FX_DWORD)(value & 0xff);
+    bits->AppendBits(value, 13, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+}
+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);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+}
+void CBC_QRCoderEncoder::Append8BitBytes(CFX_ByteArray& bytes,
+                                         CBC_QRCoderBitVector* bits,
+                                         int32_t& e) {
+  for (int32_t i = 0; i < bytes.GetSize(); i++) {
+    bits->AppendBits(bytes[i], 8, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+}
+void CBC_QRCoderEncoder::AppendKanjiBytes(const CFX_ByteString& content,
+                                          CBC_QRCoderBitVector* bits,
+                                          int32_t& e) {
+  CFX_ByteArray bytes;
+  FX_DWORD value = 0;
+  for (int32_t i = 0; i < bytes.GetSize(); i += 2) {
+    value = (FX_DWORD)((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;
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    }
+    value = (FX_DWORD)((value >> 8) * 0xc0) + (FX_DWORD)(value & 0xff);
+    bits->AppendBits(value, 13, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+}
+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);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+    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;
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+}
+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);
+    BC_EXCEPTION_CHECK_ReturnVoid(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);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  int32_t numBits = mode->GetCharacterCountBits(qcv, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  if (numBits > ((1 << numBits) - 1)) {
+    return;
+  }
+  if (mode == CBC_QRCoderMode::sGBK) {
+    bits->AppendBits(numLetters / 2, numBits, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  bits->AppendBits(numLetters, numBits, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(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;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  int32_t dataBytesOffset = 0;
+  int32_t maxNumDataBytes = 0;
+  int32_t maxNumEcBytes = 0;
+  CFX_PtrArray blocks;
+  int32_t i;
+  for (i = 0; i < numRSBlocks; i++) {
+    int32_t numDataBytesInBlock;
+    int32_t numEcBytesInBlosk;
+    GetNumDataBytesAndNumECBytesForBlockID(numTotalBytes, numDataBytes,
+                                           numRSBlocks, i, numDataBytesInBlock,
+                                           numEcBytesInBlosk);
+    CBC_CommonByteArray* dataBytes = new CBC_CommonByteArray;
+    dataBytes->Set(bits->GetArray(), dataBytesOffset, numDataBytesInBlock);
+    CBC_CommonByteArray* ecBytes =
+        GenerateECBytes(dataBytes, numEcBytesInBlosk, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+    blocks.Add(new CBC_QRCoderBlockPair(dataBytes, ecBytes));
+    maxNumDataBytes = std::max(maxNumDataBytes, dataBytes->Size());
+    maxNumEcBytes = std::max(maxNumEcBytes, ecBytes->Size());
+    dataBytesOffset += numDataBytesInBlock;
+  }
+  if (numDataBytes != dataBytesOffset) {
+    e = BCExceptionBytesNotMatchOffset;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  for (int32_t x = 0; x < maxNumDataBytes; x++) {
+    for (int32_t j = 0; j < blocks.GetSize(); j++) {
+      CBC_CommonByteArray* dataBytes =
+          ((CBC_QRCoderBlockPair*)blocks[j])->GetDataBytes();
+      if (x < dataBytes->Size()) {
+        result->AppendBits(dataBytes->At(x), 8, e);
+        BC_EXCEPTION_CHECK_ReturnVoid(e);
+      }
+    }
+  }
+  for (int32_t y = 0; y < maxNumEcBytes; y++) {
+    for (int32_t l = 0; l < blocks.GetSize(); l++) {
+      CBC_CommonByteArray* ecBytes =
+          ((CBC_QRCoderBlockPair*)blocks[l])->GetErrorCorrectionBytes();
+      if (y < ecBytes->Size()) {
+        result->AppendBits(ecBytes->At(y), 8, e);
+        BC_EXCEPTION_CHECK_ReturnVoid(e);
+      }
+    }
+  }
+  for (int32_t k = 0; k < blocks.GetSize(); k++) {
+    delete (CBC_QRCoderBlockPair*)blocks[k];
+  }
+  if (numTotalBytes != result->sizeInBytes()) {
+    e = BCExceptionSizeInBytesDiffer;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+}
+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();
+  CFX_Int32Array toEncode;
+  toEncode.SetSize(numDataBytes + numEcBytesInBlock);
+  for (int32_t i = 0; i < numDataBytes; i++) {
+    toEncode[i] = (dataBytes->At(i));
+  }
+  CBC_ReedSolomonEncoder encode(CBC_ReedSolomonGF256::QRCodeFild);
+  encode.Init();
+  encode.Encode(&toEncode, numEcBytesInBlock, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  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/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.h b/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.h
new file mode 100644
index 0000000..8330dc2
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.h
@@ -0,0 +1,133 @@
+// 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 XFA_FXBARCODE_QRCODE_BC_QRCODERENCODER_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRCODERENCODER_H_
+
+#include "core/include/fxcrt/fx_basic.h"
+#include "core/include/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 {
+ private:
+  static const int32_t m_alphaNumbericTable[96];
+
+ 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(CFX_ByteArray& 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(CFX_PtrArray& result, int32_t versionNum, int32_t& e);
+  static void SplitString(const CFX_ByteString& content, CFX_PtrArray& result);
+  static void AppendDataModeLenghInfo(CFX_PtrArray& splitResult,
+                                      CBC_QRCoderBitVector& headerAndDataBits,
+                                      CBC_QRCoderMode* tempMode,
+                                      CBC_QRCoder* qrCode,
+                                      CFX_ByteString& encoding,
+                                      int32_t& e);
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRCODERENCODER_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.cpp
new file mode 100644
index 0000000..a1ce747
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.cpp
@@ -0,0 +1,92 @@
+// 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 "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
+
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::L = NULL;
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::M = NULL;
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::Q = NULL;
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::H = NULL;
+
+CBC_QRCoderErrorCorrectionLevel::CBC_QRCoderErrorCorrectionLevel(
+    int32_t ordinal,
+    int32_t bits,
+    FX_CHAR* name) {
+  m_name += name;
+  m_ordinal = ordinal;
+  m_bits = bits;
+}
+CBC_QRCoderErrorCorrectionLevel::~CBC_QRCoderErrorCorrectionLevel() {}
+void CBC_QRCoderErrorCorrectionLevel::Initialize() {
+  L = new CBC_QRCoderErrorCorrectionLevel(0, 0x01, (FX_CHAR*)"L");
+  M = new CBC_QRCoderErrorCorrectionLevel(1, 0x00, (FX_CHAR*)"M");
+  Q = new CBC_QRCoderErrorCorrectionLevel(2, 0x03, (FX_CHAR*)"Q");
+  H = new CBC_QRCoderErrorCorrectionLevel(3, 0x02, (FX_CHAR*)"H");
+}
+void CBC_QRCoderErrorCorrectionLevel::Finalize() {
+  delete L;
+  delete M;
+  delete Q;
+  delete H;
+}
+int32_t CBC_QRCoderErrorCorrectionLevel::Ordinal() {
+  return m_ordinal;
+}
+int32_t CBC_QRCoderErrorCorrectionLevel::GetBits() {
+  return m_bits;
+}
+CFX_ByteString CBC_QRCoderErrorCorrectionLevel::GetName() {
+  return m_name;
+}
+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 NULL;
+  }
+}
+void CBC_QRCoderErrorCorrectionLevel::Destroy() {
+  if (L) {
+    delete CBC_QRCoderErrorCorrectionLevel::L;
+    L = NULL;
+  }
+  if (M) {
+    delete CBC_QRCoderErrorCorrectionLevel::M;
+    M = NULL;
+  }
+  if (H) {
+    delete CBC_QRCoderErrorCorrectionLevel::H;
+    H = NULL;
+  }
+  if (Q) {
+    delete CBC_QRCoderErrorCorrectionLevel::Q;
+    Q = NULL;
+  }
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h b/xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h
new file mode 100644
index 0000000..377137a
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.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 XFA_FXBARCODE_QRCODE_BC_QRCODERERRORCORRECTIONLEVEL_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRCODERERRORCORRECTIONLEVEL_H_
+
+#include "core/include/fxcrt/fx_string.h"
+
+class CBC_QRCoderErrorCorrectionLevel {
+ private:
+  int32_t m_ordinal;
+  int32_t m_bits;
+  CFX_ByteString m_name;
+  CBC_QRCoderErrorCorrectionLevel(int32_t ordinal, int32_t bits, FX_CHAR* name);
+  CBC_QRCoderErrorCorrectionLevel();
+
+ public:
+  static CBC_QRCoderErrorCorrectionLevel* L;
+  static CBC_QRCoderErrorCorrectionLevel* M;
+  static CBC_QRCoderErrorCorrectionLevel* Q;
+  static CBC_QRCoderErrorCorrectionLevel* H;
+  virtual ~CBC_QRCoderErrorCorrectionLevel();
+  static void Initialize();
+  static void Finalize();
+  int32_t Ordinal();
+  int32_t GetBits();
+  CFX_ByteString GetName();
+  static void Destroy();
+  static CBC_QRCoderErrorCorrectionLevel* ForBits(int32_t bits);
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRCODERERRORCORRECTIONLEVEL_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.cpp
new file mode 100644
index 0000000..da647a9
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.cpp
@@ -0,0 +1,95 @@
+// 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 "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.h"
+#include "xfa/fxbarcode/utils.h"
+
+const int32_t CBC_QRCoderFormatInformation::FORMAT_INFO_MASK_QR = 0X5412;
+const int32_t CBC_QRCoderFormatInformation::FORMAT_INFO_DECODE_LOOKUP[32][2] = {
+    {0x5412, 0x00}, {0x5125, 0x01}, {0x5E7C, 0x02}, {0x5B4B, 0x03},
+    {0x45F9, 0x04}, {0x40CE, 0x05}, {0x4F97, 0x06}, {0x4AA0, 0x07},
+    {0x77C4, 0x08}, {0x72F3, 0x09}, {0x7DAA, 0x0A}, {0x789D, 0x0B},
+    {0x662F, 0x0C}, {0x6318, 0x0D}, {0x6C41, 0x0E}, {0x6976, 0x0F},
+    {0x1689, 0x10}, {0x13BE, 0x11}, {0x1CE7, 0x12}, {0x19D0, 0x13},
+    {0x0762, 0x14}, {0x0255, 0x15}, {0x0D0C, 0x16}, {0x083B, 0x17},
+    {0x355F, 0x18}, {0x3068, 0x19}, {0x3F31, 0x1A}, {0x3A06, 0x1B},
+    {0x24B4, 0x1C}, {0x2183, 0x1D}, {0x2EDA, 0x1E}, {0x2BED, 0x1F},
+};
+const int32_t CBC_QRCoderFormatInformation::BITS_SET_IN_HALF_BYTE[] = {
+    0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
+
+CBC_QRCoderFormatInformation::CBC_QRCoderFormatInformation(int32_t formatInfo) {
+  m_errorCorrectLevl =
+      CBC_QRCoderErrorCorrectionLevel::ForBits((formatInfo >> 3) & 0x03);
+  m_dataMask = (uint8_t)(formatInfo & 0x07);
+}
+CBC_QRCoderFormatInformation::~CBC_QRCoderFormatInformation() {}
+int32_t CBC_QRCoderFormatInformation::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];
+}
+uint8_t CBC_QRCoderFormatInformation::GetDataMask() {
+  return m_dataMask;
+}
+CBC_QRCoderErrorCorrectionLevel*
+CBC_QRCoderFormatInformation::GetErrorCorrectionLevel() {
+  return m_errorCorrectLevl;
+}
+CBC_QRCoderFormatInformation*
+CBC_QRCoderFormatInformation::DecodeFormatInformation(
+    int32_t maskedFormatInfo) {
+  CBC_QRCoderFormatInformation* formatInfo =
+      DoDecodeFormatInformation(maskedFormatInfo);
+  if (formatInfo)
+    return formatInfo;
+  return DoDecodeFormatInformation(maskedFormatInfo ^ FORMAT_INFO_MASK_QR);
+}
+CBC_QRCoderFormatInformation*
+CBC_QRCoderFormatInformation::DoDecodeFormatInformation(
+    int32_t maskedFormatInfo) {
+  int32_t bestDifference = (int32_t)FXSYS_nan();
+  int32_t bestFormatInfo = 0;
+  for (int32_t i = 0; i < 32; i++) {
+    int32_t const* decodeInfo = &FORMAT_INFO_DECODE_LOOKUP[i][0];
+    int32_t targetInfo = decodeInfo[0];
+    if (targetInfo == maskedFormatInfo) {
+      return new CBC_QRCoderFormatInformation(decodeInfo[1]);
+    }
+    int32_t bitsDifference = NumBitsDiffering(maskedFormatInfo, targetInfo);
+    if (bitsDifference < bestDifference) {
+      bestFormatInfo = decodeInfo[1];
+      bestDifference = bitsDifference;
+    }
+  }
+  if (bestDifference <= 3) {
+    return new CBC_QRCoderFormatInformation(bestFormatInfo);
+  }
+  return NULL;
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.h b/xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.h
new file mode 100644
index 0000000..8f15901
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.h
@@ -0,0 +1,32 @@
+// 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 XFA_FXBARCODE_QRCODE_BC_QRCODERFORMATINFORMATION_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRCODERFORMATINFORMATION_H_
+
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRCoderFormatInformation {
+ private:
+  static const int32_t FORMAT_INFO_MASK_QR;
+  static const int32_t FORMAT_INFO_DECODE_LOOKUP[32][2];
+  static const int32_t BITS_SET_IN_HALF_BYTE[16];
+  CBC_QRCoderErrorCorrectionLevel* m_errorCorrectLevl;
+  uint8_t m_dataMask;
+
+ public:
+  CBC_QRCoderFormatInformation(int32_t formatInfo);
+  virtual ~CBC_QRCoderFormatInformation();
+  uint8_t GetDataMask();
+  CBC_QRCoderErrorCorrectionLevel* GetErrorCorrectionLevel();
+
+  static int32_t NumBitsDiffering(int32_t a, int32_t b);
+  static CBC_QRCoderFormatInformation* DecodeFormatInformation(
+      int32_t maskedFormatInfo);
+  static CBC_QRCoderFormatInformation* DoDecodeFormatInformation(
+      int32_t maskedFormatInfo);
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRCODERFORMATINFORMATION_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.cpp
new file mode 100644
index 0000000..4d845c4
--- /dev/null
+++ b/xfa/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 "xfa/fxbarcode/common/BC_CommonByteMatrix.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoder.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.h"
+#include "xfa/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;
+}
+FX_BOOL CBC_QRCoderMaskUtil::GetDataMaskBit(int32_t maskPattern,
+                                            int32_t x,
+                                            int32_t y,
+                                            int32_t& e) {
+  if (!CBC_QRCoder::IsValidMaskPattern(maskPattern)) {
+    e = (BCExceptionInvalidateMaskPattern);
+    BC_EXCEPTION_CHECK_ReturnValue(e, 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;
+      BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+    }
+  }
+  return intermediate == 0;
+}
+int32_t CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule1Internal(
+    CBC_CommonByteMatrix* matrix,
+    FX_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/xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.h b/xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.h
new file mode 100644
index 0000000..35032a3
--- /dev/null
+++ b/xfa/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 XFA_FXBARCODE_QRCODE_BC_QRCODERMASKUTIL_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRCODERMASKUTIL_H_
+class CBC_CommonByteMatrix;
+class CBC_QRCoderMaskUtil {
+ public:
+  CBC_QRCoderMaskUtil();
+  virtual ~CBC_QRCoderMaskUtil();
+  static FX_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,
+                                               FX_BOOL isHorizontal);
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRCODERMASKUTIL_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp
new file mode 100644
index 0000000..65cf036
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp
@@ -0,0 +1,474 @@
+// 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 "xfa/fxbarcode/common/BC_CommonByteMatrix.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoder.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderBitVector.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.h"
+#include "xfa/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 == NULL) {
+    e = BCExceptionNullPointer;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  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 == NULL) {
+    e = BCExceptionNullPointer;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  ClearMatrix(matrix, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  EmbedBasicPatterns(version, matrix, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  EmbedTypeInfo(ecLevel, maskPattern, matrix, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  MaybeEmbedVersionInfo(version, matrix, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  EmbedDataBits(dataBits, maskPattern, matrix, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+}
+void CBC_QRCoderMatrixUtil::EmbedBasicPatterns(int32_t version,
+                                               CBC_CommonByteMatrix* matrix,
+                                               int32_t& e) {
+  if (matrix == NULL) {
+    e = BCExceptionNullPointer;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  EmbedPositionDetectionPatternsAndSeparators(matrix, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  EmbedDarkDotAtLeftBottomCorner(matrix, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  MaybeEmbedPositionAdjustmentPatterns(version, matrix, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  EmbedTimingPatterns(matrix, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+}
+void CBC_QRCoderMatrixUtil::EmbedTypeInfo(
+    CBC_QRCoderErrorCorrectionLevel* ecLevel,
+    int32_t maskPattern,
+    CBC_CommonByteMatrix* matrix,
+    int32_t& e) {
+  if (matrix == NULL) {
+    e = BCExceptionNullPointer;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  CBC_QRCoderBitVector typeInfoBits;
+  typeInfoBits.Init();
+  MakeTypeInfoBits(ecLevel, maskPattern, &typeInfoBits, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  for (int32_t i = 0; i < typeInfoBits.Size(); i++) {
+    int32_t bit = typeInfoBits.At(typeInfoBits.Size() - 1 - i, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+    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 == NULL) {
+    e = BCExceptionNullPointer;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  if (version < 7) {
+    return;
+  }
+  CBC_QRCoderBitVector versionInfoBits;
+  versionInfoBits.Init();
+  MakeVersionInfoBits(version, &versionInfoBits, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  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);
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+      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 == NULL || dataBits == NULL) {
+    e = BCExceptionNullPointer;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  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);
+          BC_EXCEPTION_CHECK_ReturnVoid(e);
+          bitIndex++;
+        } else {
+          bit = 0;
+        }
+        if (maskPattern != -1) {
+          FX_BOOL bol =
+              CBC_QRCoderMaskUtil::GetDataMaskBit(maskPattern, xx, y, e);
+          BC_EXCEPTION_CHECK_ReturnVoid(e);
+          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 == NULL) {
+    e = BCExceptionNullPointer;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  if (!CBC_QRCoder::IsValidMaskPattern(maskPattern)) {
+    e = BCExceptionBadMask;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  int32_t typeInfo = (ecLevel->GetBits() << 3) | maskPattern;
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  bits->AppendBits(typeInfo, 5, e);
+  int32_t bchCode = CalculateBCHCode(typeInfo, TYPE_INFO_POLY);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  bits->AppendBits(bchCode, 10, e);
+  CBC_QRCoderBitVector maskBits;
+  maskBits.Init();
+  maskBits.AppendBits(TYPE_INFO_MASK_PATTERN, 15, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  bits->XOR(&maskBits, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  if (bits->Size() != 15) {
+    e = BCExceptionBitSizeNot15;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+}
+void CBC_QRCoderMatrixUtil::MakeVersionInfoBits(int32_t version,
+                                                CBC_QRCoderBitVector* bits,
+                                                int32_t& e) {
+  if (bits == NULL) {
+    e = BCExceptionNullPointer;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  bits->AppendBits(version, 6, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  int32_t bchCode = CalculateBCHCode(version, VERSION_INFO_POLY);
+  bits->AppendBits(bchCode, 12, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  if (bits->Size() != 18) {
+    e = BCExceptionBitSizeNot18;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+}
+FX_BOOL CBC_QRCoderMatrixUtil::IsEmpty(int32_t value) {
+  return (uint8_t)value == 0xff;
+}
+FX_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 == NULL) {
+    e = BCExceptionNullPointer;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  for (int32_t i = 8; i < matrix->GetWidth() - 8; i++) {
+    int32_t bit = (i + 1) % 2;
+    if (!IsValidValue(matrix->Get(i, 6))) {
+      e = BCExceptionInvalidateImageData;
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    }
+    if (IsEmpty(matrix->Get(i, 6))) {
+      matrix->Set(i, 6, bit);
+    }
+    if (!IsValidValue(matrix->Get(6, i))) {
+      e = BCExceptionInvalidateImageData;
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    }
+    if (IsEmpty(matrix->Get(6, i))) {
+      matrix->Set(6, i, bit);
+    }
+  }
+}
+void CBC_QRCoderMatrixUtil::EmbedDarkDotAtLeftBottomCorner(
+    CBC_CommonByteMatrix* matrix,
+    int32_t& e) {
+  if (matrix == NULL) {
+    e = BCExceptionNullPointer;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  if (matrix->Get(8, matrix->GetHeight() - 8) == 0) {
+    e = BCExceptionHeight_8BeZero;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  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 == NULL) {
+    e = BCExceptionNullPointer;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  for (int32_t x = 0; x < 8; x++) {
+    if (!IsEmpty(matrix->Get(xStart + x, yStart))) {
+      e = BCExceptionInvalidateData;
+      BC_EXCEPTION_CHECK_ReturnVoid(e)
+    }
+    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 == NULL) {
+    e = BCExceptionNullPointer;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  for (int32_t y = 0; y < 7; y++) {
+    if (!IsEmpty(matrix->Get(xStart, yStart + y))) {
+      e = BCExceptionInvalidateData;
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    }
+    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 == NULL) {
+    e = BCExceptionNullPointer;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  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;
+        BC_EXCEPTION_CHECK_ReturnVoid(e);
+      }
+      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 == NULL) {
+    e = BCExceptionNullPointer;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  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;
+        BC_EXCEPTION_CHECK_ReturnVoid(e);
+      }
+      matrix->Set(xStart + x, yStart + y, POSITION_DETECTION_PATTERN[y][x]);
+    }
+  }
+}
+void CBC_QRCoderMatrixUtil::EmbedPositionDetectionPatternsAndSeparators(
+    CBC_CommonByteMatrix* matrix,
+    int32_t& e) {
+  if (matrix == NULL) {
+    e = BCExceptionNullPointer;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  int32_t pdpWidth = 7;
+  EmbedPositionDetectionPattern(0, 0, matrix, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  EmbedPositionDetectionPattern(matrix->GetWidth() - pdpWidth, 0, matrix, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  EmbedPositionDetectionPattern(0, matrix->GetWidth() - pdpWidth, matrix, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  int32_t hspWidth = 8;
+  EmbedHorizontalSeparationPattern(0, hspWidth - 1, matrix, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  EmbedHorizontalSeparationPattern(matrix->GetWidth() - hspWidth, hspWidth - 1,
+                                   matrix, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  EmbedHorizontalSeparationPattern(0, matrix->GetWidth() - hspWidth, matrix, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  int32_t vspSize = 7;
+  EmbedVerticalSeparationPattern(vspSize, 0, matrix, e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  EmbedVerticalSeparationPattern(matrix->GetHeight() - vspSize - 1, 0, matrix,
+                                 e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+  EmbedVerticalSeparationPattern(vspSize, matrix->GetHeight() - vspSize, matrix,
+                                 e);
+  BC_EXCEPTION_CHECK_ReturnVoid(e);
+}
+void CBC_QRCoderMatrixUtil::MaybeEmbedPositionAdjustmentPatterns(
+    int32_t version,
+    CBC_CommonByteMatrix* matrix,
+    int32_t& e) {
+  if (matrix == NULL) {
+    e = BCExceptionNullPointer;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  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);
+        BC_EXCEPTION_CHECK_ReturnVoid(e);
+      }
+    }
+  }
+}
+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/xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.h b/xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.h
new file mode 100644
index 0000000..feb0bb4
--- /dev/null
+++ b/xfa/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 XFA_FXBARCODE_QRCODE_BC_QRCODERMATRIXUTIL_H_
+#define XFA_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 FX_BOOL IsEmpty(int32_t value);
+  static FX_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  // XFA_FXBARCODE_QRCODE_BC_QRCODERMATRIXUTIL_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderMode.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderMode.cpp
new file mode 100644
index 0000000..2abdab5
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderMode.cpp
@@ -0,0 +1,179 @@
+// 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 "xfa/fxbarcode/qrcode/BC_QRCoderMode.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h"
+#include "xfa/fxbarcode/utils.h"
+
+CBC_QRCoderMode* CBC_QRCoderMode::sBYTE = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sNUMERIC = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sALPHANUMERIC = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sKANJI = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sECI = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sGBK = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sTERMINATOR = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sFNC1_FIRST_POSITION = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sFNC1_SECOND_POSITION = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sSTRUCTURED_APPEND = NULL;
+
+CBC_QRCoderMode::CBC_QRCoderMode(int32_t* characterCountBitsForVersions,
+                                 int32_t x1,
+                                 int32_t x2,
+                                 int32_t x3,
+                                 int32_t bits,
+                                 CFX_ByteString name) {
+  m_characterCountBitsForVersions = characterCountBitsForVersions;
+  if (m_characterCountBitsForVersions) {
+    m_characterCountBitsForVersions[0] = x1;
+    m_characterCountBitsForVersions[1] = x2;
+    m_characterCountBitsForVersions[2] = x3;
+  }
+  m_name += name;
+  m_bits = bits;
+}
+CBC_QRCoderMode::~CBC_QRCoderMode() {
+  FX_Free(m_characterCountBitsForVersions);
+}
+void CBC_QRCoderMode::Initialize() {
+  sBYTE = new CBC_QRCoderMode(FX_Alloc(int32_t, 3), 8, 16, 16, 0x4, "BYTE");
+  sALPHANUMERIC =
+      new CBC_QRCoderMode(FX_Alloc(int32_t, 3), 9, 11, 13, 0x2, "ALPHANUMERIC");
+  sECI = new CBC_QRCoderMode(NULL, 0, 0, 0, 0x7, "ECI");
+  sKANJI = new CBC_QRCoderMode(FX_Alloc(int32_t, 3), 8, 10, 12, 0x8, "KANJI");
+  sNUMERIC =
+      new CBC_QRCoderMode(FX_Alloc(int32_t, 3), 10, 12, 14, 0x1, "NUMERIC");
+  sGBK = new CBC_QRCoderMode(FX_Alloc(int32_t, 3), 8, 10, 12, 0x0D, "GBK");
+  sTERMINATOR =
+      new CBC_QRCoderMode(FX_Alloc(int32_t, 3), 0, 0, 0, 0x00, "TERMINATOR");
+  sFNC1_FIRST_POSITION =
+      new CBC_QRCoderMode(NULL, 0, 0, 0, 0x05, "FNC1_FIRST_POSITION");
+  sFNC1_SECOND_POSITION =
+      new CBC_QRCoderMode(NULL, 0, 0, 0, 0x09, "FNC1_SECOND_POSITION");
+  sSTRUCTURED_APPEND = new CBC_QRCoderMode(FX_Alloc(int32_t, 3), 0, 0, 0, 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;
+      BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+    }
+  }
+  return NULL;
+}
+int32_t CBC_QRCoderMode::GetBits() {
+  return m_bits;
+}
+CFX_ByteString CBC_QRCoderMode::GetName() {
+  return m_name;
+}
+int32_t CBC_QRCoderMode::GetCharacterCountBits(CBC_QRCoderVersion* version,
+                                               int32_t& e) {
+  if (m_characterCountBitsForVersions == NULL) {
+    e = BCExceptionCharacterNotThisMode;
+    BC_EXCEPTION_CHECK_ReturnValue(e, 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 = NULL;
+  }
+  if (sNUMERIC) {
+    delete CBC_QRCoderMode::sNUMERIC;
+    sNUMERIC = NULL;
+  }
+  if (sALPHANUMERIC) {
+    delete CBC_QRCoderMode::sALPHANUMERIC;
+    sALPHANUMERIC = NULL;
+  }
+  if (sKANJI) {
+    delete CBC_QRCoderMode::sKANJI;
+    sKANJI = NULL;
+  }
+  if (sECI) {
+    delete CBC_QRCoderMode::sECI;
+    sECI = NULL;
+  }
+  if (sGBK) {
+    delete CBC_QRCoderMode::sGBK;
+    sGBK = NULL;
+  }
+  if (sTERMINATOR) {
+    delete CBC_QRCoderMode::sTERMINATOR;
+    sTERMINATOR = NULL;
+  }
+  if (sFNC1_FIRST_POSITION) {
+    delete CBC_QRCoderMode::sFNC1_FIRST_POSITION;
+    sFNC1_FIRST_POSITION = NULL;
+  }
+  if (sFNC1_SECOND_POSITION) {
+    delete CBC_QRCoderMode::sFNC1_SECOND_POSITION;
+    sFNC1_SECOND_POSITION = NULL;
+  }
+  if (sSTRUCTURED_APPEND) {
+    delete CBC_QRCoderMode::sSTRUCTURED_APPEND;
+    sSTRUCTURED_APPEND = NULL;
+  }
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderMode.h b/xfa/fxbarcode/qrcode/BC_QRCoderMode.h
new file mode 100644
index 0000000..e36f7a1
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderMode.h
@@ -0,0 +1,51 @@
+// 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 XFA_FXBARCODE_QRCODE_BC_QRCODERMODE_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRCODERMODE_H_
+
+#include <stdint.h>
+
+#include "core/include/fxcrt/fx_string.h"
+
+class CBC_QRCoderVersion;
+
+class CBC_QRCoderMode {
+ private:
+  int32_t* m_characterCountBitsForVersions;
+  int32_t m_bits;
+  CFX_ByteString m_name;
+  CBC_QRCoderMode(int32_t* characterCountBitsForVersions,
+                  int32_t x1,
+                  int32_t x2,
+                  int32_t x3,
+                  int32_t bits,
+                  CFX_ByteString name);
+  CBC_QRCoderMode();
+
+ public:
+  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;
+  virtual ~CBC_QRCoderMode();
+
+  static void Initialize();
+  static void Finalize();
+  static CBC_QRCoderMode* ForBits(int32_t bits, int32_t& e);
+  int32_t GetCharacterCountBits(CBC_QRCoderVersion* version, int32_t& e);
+  int32_t GetBits();
+  CFX_ByteString GetName();
+  static void Destroy();
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRCODERMODE_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderVersion.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderVersion.cpp
new file mode 100644
index 0000000..1ff557e
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderVersion.cpp
@@ -0,0 +1,769 @@
+// 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 "xfa/fxbarcode/common/BC_CommonBitMatrix.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderBitVector.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderECB.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderFormatInformation.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h"
+#include "xfa/fxbarcode/utils.h"
+
+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};
+CFX_PtrArray* CBC_QRCoderVersion::VERSION = NULL;
+
+void CBC_QRCoderVersion::Initialize() {
+  VERSION = new CFX_PtrArray();
+}
+void CBC_QRCoderVersion::Finalize() {
+  for (int32_t i = 0; i < VERSION->GetSize(); i++) {
+    CBC_QRCoderVersion* v = (CBC_QRCoderVersion*)(VERSION->GetAt(i));
+    delete v;
+  }
+  delete VERSION;
+}
+CBC_QRCoderVersion::CBC_QRCoderVersion(int32_t versionNumber,
+                                       CBC_QRCoderECBlocks* ecBlocks1,
+                                       CBC_QRCoderECBlocks* ecBlocks2,
+                                       CBC_QRCoderECBlocks* ecBlocks3,
+                                       CBC_QRCoderECBlocks* ecBlocks4) {
+  m_versionNumber = versionNumber;
+  m_ecBlocks.Add(ecBlocks1);
+  m_ecBlocks.Add(ecBlocks2);
+  m_ecBlocks.Add(ecBlocks3);
+  m_ecBlocks.Add(ecBlocks4);
+  int32_t total = 0;
+  int32_t ecCodeWords = ecBlocks1->GetECCodeWordsPerBlock();
+  CFX_PtrArray* ecbArray = ecBlocks1->GetECBlocks();
+  for (int32_t i = 0; i < ecbArray->GetSize(); i++) {
+    CBC_QRCoderECB* ecBlock = (CBC_QRCoderECB*)((*ecbArray)[i]);
+    total += ecBlock->GetCount() * (ecBlock->GetDataCodeWords() + ecCodeWords);
+  }
+  m_totalCodeWords = total;
+  switch (versionNumber) {
+    case 1:
+      break;
+    case 2:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(18);
+      break;
+    case 3:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(22);
+      break;
+    case 4:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(26);
+      break;
+    case 5:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(30);
+      break;
+    case 6:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(34);
+      break;
+    case 7:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(22);
+      m_alignmentPatternCenters.Add(38);
+      break;
+    case 8:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(24);
+      m_alignmentPatternCenters.Add(42);
+      break;
+    case 9:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(26);
+      m_alignmentPatternCenters.Add(46);
+      break;
+    case 10:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(28);
+      m_alignmentPatternCenters.Add(50);
+      break;
+    case 11:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(30);
+      m_alignmentPatternCenters.Add(54);
+      break;
+    case 12:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(32);
+      m_alignmentPatternCenters.Add(58);
+      break;
+    case 13:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(34);
+      m_alignmentPatternCenters.Add(62);
+      break;
+    case 14:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(26);
+      m_alignmentPatternCenters.Add(46);
+      m_alignmentPatternCenters.Add(66);
+      break;
+    case 15:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(26);
+      m_alignmentPatternCenters.Add(48);
+      m_alignmentPatternCenters.Add(70);
+      break;
+    case 16:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(26);
+      m_alignmentPatternCenters.Add(50);
+      m_alignmentPatternCenters.Add(74);
+      break;
+    case 17:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(30);
+      m_alignmentPatternCenters.Add(54);
+      m_alignmentPatternCenters.Add(78);
+      break;
+    case 18:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(30);
+      m_alignmentPatternCenters.Add(56);
+      m_alignmentPatternCenters.Add(82);
+      break;
+    case 19:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(30);
+      m_alignmentPatternCenters.Add(58);
+      m_alignmentPatternCenters.Add(86);
+      break;
+    case 20:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(34);
+      m_alignmentPatternCenters.Add(62);
+      m_alignmentPatternCenters.Add(90);
+      break;
+    case 21:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(28);
+      m_alignmentPatternCenters.Add(50);
+      m_alignmentPatternCenters.Add(72);
+      m_alignmentPatternCenters.Add(94);
+      break;
+    case 22:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(26);
+      m_alignmentPatternCenters.Add(50);
+      m_alignmentPatternCenters.Add(74);
+      m_alignmentPatternCenters.Add(98);
+      break;
+    case 23:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(30);
+      m_alignmentPatternCenters.Add(54);
+      m_alignmentPatternCenters.Add(74);
+      m_alignmentPatternCenters.Add(102);
+      break;
+    case 24:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(28);
+      m_alignmentPatternCenters.Add(54);
+      m_alignmentPatternCenters.Add(80);
+      m_alignmentPatternCenters.Add(106);
+      break;
+    case 25:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(32);
+      m_alignmentPatternCenters.Add(58);
+      m_alignmentPatternCenters.Add(84);
+      m_alignmentPatternCenters.Add(110);
+      break;
+    case 26:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(30);
+      m_alignmentPatternCenters.Add(58);
+      m_alignmentPatternCenters.Add(86);
+      m_alignmentPatternCenters.Add(114);
+      break;
+    case 27:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(34);
+      m_alignmentPatternCenters.Add(62);
+      m_alignmentPatternCenters.Add(90);
+      m_alignmentPatternCenters.Add(118);
+      break;
+    case 28:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(26);
+      m_alignmentPatternCenters.Add(50);
+      m_alignmentPatternCenters.Add(74);
+      m_alignmentPatternCenters.Add(98);
+      m_alignmentPatternCenters.Add(122);
+      break;
+    case 29:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(30);
+      m_alignmentPatternCenters.Add(54);
+      m_alignmentPatternCenters.Add(78);
+      m_alignmentPatternCenters.Add(102);
+      m_alignmentPatternCenters.Add(126);
+      break;
+    case 30:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(26);
+      m_alignmentPatternCenters.Add(52);
+      m_alignmentPatternCenters.Add(78);
+      m_alignmentPatternCenters.Add(104);
+      m_alignmentPatternCenters.Add(130);
+      break;
+    case 31:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(30);
+      m_alignmentPatternCenters.Add(56);
+      m_alignmentPatternCenters.Add(82);
+      m_alignmentPatternCenters.Add(108);
+      m_alignmentPatternCenters.Add(134);
+      break;
+    case 32:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(34);
+      m_alignmentPatternCenters.Add(60);
+      m_alignmentPatternCenters.Add(86);
+      m_alignmentPatternCenters.Add(112);
+      m_alignmentPatternCenters.Add(138);
+      break;
+    case 33:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(30);
+      m_alignmentPatternCenters.Add(58);
+      m_alignmentPatternCenters.Add(86);
+      m_alignmentPatternCenters.Add(114);
+      m_alignmentPatternCenters.Add(142);
+      break;
+    case 34:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(34);
+      m_alignmentPatternCenters.Add(62);
+      m_alignmentPatternCenters.Add(90);
+      m_alignmentPatternCenters.Add(118);
+      m_alignmentPatternCenters.Add(146);
+      break;
+    case 35:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(30);
+      m_alignmentPatternCenters.Add(54);
+      m_alignmentPatternCenters.Add(78);
+      m_alignmentPatternCenters.Add(102);
+      m_alignmentPatternCenters.Add(126);
+      m_alignmentPatternCenters.Add(150);
+      break;
+    case 36:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(24);
+      m_alignmentPatternCenters.Add(50);
+      m_alignmentPatternCenters.Add(76);
+      m_alignmentPatternCenters.Add(102);
+      m_alignmentPatternCenters.Add(128);
+      m_alignmentPatternCenters.Add(154);
+      break;
+    case 37:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(28);
+      m_alignmentPatternCenters.Add(54);
+      m_alignmentPatternCenters.Add(80);
+      m_alignmentPatternCenters.Add(106);
+      m_alignmentPatternCenters.Add(132);
+      m_alignmentPatternCenters.Add(158);
+      break;
+    case 38:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(32);
+      m_alignmentPatternCenters.Add(58);
+      m_alignmentPatternCenters.Add(84);
+      m_alignmentPatternCenters.Add(110);
+      m_alignmentPatternCenters.Add(136);
+      m_alignmentPatternCenters.Add(162);
+      break;
+    case 39:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(26);
+      m_alignmentPatternCenters.Add(54);
+      m_alignmentPatternCenters.Add(82);
+      m_alignmentPatternCenters.Add(110);
+      m_alignmentPatternCenters.Add(138);
+      m_alignmentPatternCenters.Add(166);
+      break;
+    case 40:
+      m_alignmentPatternCenters.Add(6);
+      m_alignmentPatternCenters.Add(30);
+      m_alignmentPatternCenters.Add(58);
+      m_alignmentPatternCenters.Add(86);
+      m_alignmentPatternCenters.Add(114);
+      m_alignmentPatternCenters.Add(142);
+      m_alignmentPatternCenters.Add(170);
+      break;
+  }
+}
+CBC_QRCoderVersion::~CBC_QRCoderVersion() {
+  if (m_ecBlocks.GetSize() != 0) {
+    int32_t itBeg = 0;
+    int32_t itEnd = m_ecBlocks.GetSize();
+    while (itBeg != itEnd) {
+      delete ((CBC_QRCoderECBlocks*)(m_ecBlocks[itBeg]));
+      itBeg++;
+    }
+  }
+}
+int32_t CBC_QRCoderVersion::GetVersionNumber() {
+  return m_versionNumber;
+}
+CFX_Int32Array* 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 (CBC_QRCoderECBlocks*)m_ecBlocks[ecLevel->Ordinal()];
+}
+CBC_QRCoderVersion* CBC_QRCoderVersion::GetProvisionalVersionForDimension(
+    int32_t dimension,
+    int32_t& e) {
+  if ((dimension % 4) != 1) {
+    e = BCExceptionRead;
+    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  }
+  CBC_QRCoderVersion* qcv = GetVersionForNumber((dimension - 17) >> 2, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  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);
+      BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+      return qcv;
+    }
+    int32_t bitsDifference = CBC_QRCoderFormatInformation::NumBitsDiffering(
+        versionBits, targetVersion);
+    if (bitsDifference < bestDifference) {
+      bestVersion = i + 7;
+      bestDifference = bitsDifference;
+    }
+  }
+  if (bestDifference <= 3) {
+    CBC_QRCoderVersion* qcv = GetVersionForNumber(bestVersion, e);
+    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+    return qcv;
+  }
+  return NULL;
+}
+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);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  bitMatrix->SetRegion(dimension - 8, 0, 8, 9, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  bitMatrix->SetRegion(0, dimension - 8, 9, 8, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  int32_t max = m_alignmentPatternCenters.GetSize();
+  for (int32_t x = 0; x < max; x++) {
+    int32_t i = m_alignmentPatternCenters[x] - 2;
+    for (int32_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);
+      BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+    }
+  }
+  bitMatrix->SetRegion(6, 9, 1, dimension - 17, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  bitMatrix->SetRegion(9, 6, dimension - 17, 1, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  if (m_versionNumber > 6) {
+    bitMatrix->SetRegion(dimension - 11, 0, 3, 6, e);
+    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+    bitMatrix->SetRegion(0, dimension - 11, 6, 3, e);
+    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  }
+  return bitMatrix;
+}
+CBC_QRCoderVersion* CBC_QRCoderVersion::GetVersionForNumber(
+    int32_t versionNumber,
+    int32_t& e) {
+  if (VERSION->GetSize() == 0) {
+    VERSION->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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->Add(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;
+    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  }
+  return (CBC_QRCoderVersion*)(*VERSION)[versionNumber - 1];
+}
+void CBC_QRCoderVersion::Destroy() {
+  int32_t i;
+  for (i = 0; i < VERSION->GetSize(); i++) {
+    delete ((CBC_QRCoderVersion*)(*VERSION)[i]);
+  }
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderVersion.h b/xfa/fxbarcode/qrcode/BC_QRCoderVersion.h
new file mode 100644
index 0000000..dd2b0c6
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRCoderVersion.h
@@ -0,0 +1,54 @@
+// 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 XFA_FXBARCODE_QRCODE_BC_QRCODERVERSION_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRCODERVERSION_H_
+
+#include "core/include/fxcrt/fx_basic.h"
+
+class CBC_QRCoderECBlocks;
+class CBC_CommonBitMatrix;
+class CBC_QRCoderErrorCorrectionLevel;
+
+class CBC_QRCoderVersion {
+ private:
+  static const int32_t VERSION_DECODE_INFO[34];
+  static CFX_PtrArray* VERSION;
+  int32_t m_versionNumber;
+  int32_t m_totalCodeWords;
+  CFX_Int32Array m_alignmentPatternCenters;
+  CFX_PtrArray m_ecBlocks;
+
+  CBC_QRCoderVersion();
+  CBC_QRCoderVersion(int32_t versionNumber,
+                     CBC_QRCoderECBlocks* ecBlocks1,
+                     CBC_QRCoderECBlocks* ecBlocks2,
+                     CBC_QRCoderECBlocks* ecBlocks3,
+                     CBC_QRCoderECBlocks* ecBlocks4);
+
+ 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);
+  CFX_Int32Array* 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();
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRCODERVERSION_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRDataBlock.cpp b/xfa/fxbarcode/qrcode/BC_QRDataBlock.cpp
new file mode 100644
index 0000000..9805ac9
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRDataBlock.cpp
@@ -0,0 +1,111 @@
+// 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 "xfa/fxbarcode/qrcode/BC_QRDataBlock.h"
+
+#include <memory>
+
+#include "xfa/fxbarcode/qrcode/BC_QRCoderECB.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderECBlocks.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h"
+#include "xfa/fxbarcode/utils.h"
+
+CBC_QRDataBlock::CBC_QRDataBlock(int32_t numDataCodewords,
+                                 CFX_ByteArray* codewords)
+    : m_numDataCodewords(numDataCodewords), m_codewords(codewords) {}
+CBC_QRDataBlock::~CBC_QRDataBlock() {
+  delete m_codewords;
+}
+int32_t CBC_QRDataBlock::GetNumDataCodewords() {
+  return m_numDataCodewords;
+}
+CFX_ByteArray* CBC_QRDataBlock::GetCodewords() {
+  return m_codewords;
+}
+CFX_PtrArray* CBC_QRDataBlock::GetDataBlocks(
+    CFX_ByteArray* rawCodewords,
+    CBC_QRCoderVersion* version,
+    CBC_QRCoderErrorCorrectionLevel* ecLevel,
+    int32_t& e) {
+  if (rawCodewords->GetSize() != version->GetTotalCodeWords()) {
+    e = BCExceptionIllegalArgument;
+    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  }
+  CBC_QRCoderECBlocks* ecBlocks = version->GetECBlocksForLevel(ecLevel);
+  int32_t totalBlocks = 0;
+  CFX_PtrArray* ecBlockArray = ecBlocks->GetECBlocks();
+  int32_t i = 0;
+  for (i = 0; i < ecBlockArray->GetSize(); i++) {
+    totalBlocks += ((CBC_QRCoderECB*)(*ecBlockArray)[i])->GetCount();
+  }
+  std::unique_ptr<CFX_PtrArray> result(new CFX_PtrArray());
+  result->SetSize(totalBlocks);
+  int32_t numResultBlocks = 0;
+  for (int32_t j = 0; j < ecBlockArray->GetSize(); j++) {
+    CBC_QRCoderECB* ecBlock = (CBC_QRCoderECB*)(*ecBlockArray)[j];
+    for (int32_t k = 0; k < ecBlock->GetCount(); k++) {
+      int32_t numDataCodewords = ecBlock->GetDataCodeWords();
+      int32_t numBlockCodewords =
+          ecBlocks->GetECCodeWordsPerBlock() + numDataCodewords;
+      CFX_ByteArray* bytearray = new CFX_ByteArray();
+      bytearray->SetSize(numBlockCodewords);
+      (*result)[numResultBlocks++] =
+          new CBC_QRDataBlock(numDataCodewords, bytearray);
+    }
+  }
+  int32_t shorterBlocksTotalCodewords =
+      ((CBC_QRDataBlock*)(*result)[0])->m_codewords->GetSize();
+  int32_t longerBlocksStartAt = result->GetSize() - 1;
+  while (longerBlocksStartAt >= 0) {
+    int32_t numCodewords = ((CBC_QRDataBlock*)(*result)[longerBlocksStartAt])
+                               ->m_codewords->GetSize();
+    if (numCodewords == shorterBlocksTotalCodewords) {
+      break;
+    }
+    longerBlocksStartAt--;
+  }
+  longerBlocksStartAt++;
+  int32_t shorterBlocksNumDataCodewords =
+      shorterBlocksTotalCodewords - ecBlocks->GetECCodeWordsPerBlock();
+  int32_t rawCodewordsOffset = 0;
+  int32_t x = 0;
+  for (int32_t k = 0; k < shorterBlocksNumDataCodewords; k++) {
+    for (x = 0; x < numResultBlocks; x++) {
+      (*(((CBC_QRDataBlock*)(*result)[x])->m_codewords))[k] =
+          (*rawCodewords)[rawCodewordsOffset++];
+    }
+  }
+  for (x = longerBlocksStartAt; x < numResultBlocks; x++) {
+    (*(((CBC_QRDataBlock*)(*result)[x])
+           ->m_codewords))[shorterBlocksNumDataCodewords] =
+        (*rawCodewords)[rawCodewordsOffset++];
+  }
+  int32_t max = ((CBC_QRDataBlock*)(*result)[0])->m_codewords->GetSize();
+  for (i = shorterBlocksNumDataCodewords; i < max; i++) {
+    for (int32_t y = 0; y < numResultBlocks; y++) {
+      int32_t iOffset = y < longerBlocksStartAt ? i : i + 1;
+      (*(((CBC_QRDataBlock*)(*result)[y])->m_codewords))[iOffset] =
+          (*rawCodewords)[rawCodewordsOffset++];
+    }
+  }
+  return result.release();
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRDataBlock.h b/xfa/fxbarcode/qrcode/BC_QRDataBlock.h
new file mode 100644
index 0000000..8e11ab8
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRDataBlock.h
@@ -0,0 +1,30 @@
+// 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 XFA_FXBARCODE_QRCODE_BC_QRDATABLOCK_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRDATABLOCK_H_
+
+#include "core/include/fxcrt/fx_basic.h"
+
+class CBC_QRCoderVersion;
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRDataBlock {
+ private:
+  int32_t m_numDataCodewords;
+  CFX_ByteArray* m_codewords;
+  CBC_QRDataBlock(int32_t numDataCodewords, CFX_ByteArray* codewords);
+
+ public:
+  virtual ~CBC_QRDataBlock();
+  int32_t GetNumDataCodewords();
+  CFX_ByteArray* GetCodewords();
+  static CFX_PtrArray* GetDataBlocks(CFX_ByteArray* rawCodewords,
+                                     CBC_QRCoderVersion* version,
+                                     CBC_QRCoderErrorCorrectionLevel* ecLevel,
+                                     int32_t& e);
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRDATABLOCK_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRDataMask.cpp b/xfa/fxbarcode/qrcode/BC_QRDataMask.cpp
new file mode 100644
index 0000000..20f9406
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRDataMask.cpp
@@ -0,0 +1,118 @@
+// 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 "xfa/fxbarcode/common/BC_CommonBitMatrix.h"
+#include "xfa/fxbarcode/qrcode/BC_QRDataMask.h"
+#include "xfa/fxbarcode/utils.h"
+
+static int32_t N_DATA_MASKS = 0;
+CFX_PtrArray* CBC_QRDataMask::DATA_MASKS = NULL;
+
+void CBC_QRDataMask::Initialize() {
+  DATA_MASKS = new CFX_PtrArray();
+  N_DATA_MASKS = BuildDataMasks();
+}
+void CBC_QRDataMask::Finalize() {
+  Destroy();
+  delete DATA_MASKS;
+}
+void CBC_QRDataMask::Destroy() {
+  int32_t i;
+  for (i = 0; i < N_DATA_MASKS; i++) {
+    CBC_QRDataMask* p = (CBC_QRDataMask*)(*DATA_MASKS)[i];
+    if (p) {
+      delete p;
+    }
+  }
+}
+void CBC_QRDataMask::UnmaskBitMatirx(CBC_CommonBitMatrix* bits,
+                                     int32_t dimension) {
+  for (int32_t i = 0; i < dimension; i++) {
+    for (int32_t j = 0; j < dimension; j++) {
+      if (IsMasked(i, j)) {
+        bits->Flip(j, i);
+      }
+    }
+  }
+}
+CBC_QRDataMask* CBC_QRDataMask::ForReference(int32_t reference, int32_t& e) {
+  if (reference < 0 || reference > 7) {
+    e = BCExceptionReferenceMustBeBetween0And7;
+    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  }
+  return (CBC_QRDataMask*)(*DATA_MASKS)[reference];
+}
+class DataMask000 : public CBC_QRDataMask {
+ public:
+  FX_BOOL IsMasked(int32_t x, int32_t y) { return ((x + y) % 2) == 0; }
+};
+class DataMask001 : public CBC_QRDataMask {
+ public:
+  FX_BOOL IsMasked(int32_t x, int32_t y) { return (x % 2) == 0; }
+};
+class DataMask010 : public CBC_QRDataMask {
+ public:
+  FX_BOOL IsMasked(int32_t x, int32_t y) { return y % 3 == 0; }
+};
+class DataMask011 : public CBC_QRDataMask {
+ public:
+  FX_BOOL IsMasked(int32_t x, int32_t y) { return (x + y) % 3 == 0; }
+};
+class DataMask100 : public CBC_QRDataMask {
+ public:
+  FX_BOOL IsMasked(int32_t x, int32_t y) {
+    return (((x >> 1) + (y / 3)) % 2) == 0;
+  }
+};
+class DataMask101 : public CBC_QRDataMask {
+ public:
+  FX_BOOL IsMasked(int32_t x, int32_t y) {
+    size_t temp = x * y;
+    return (temp % 2) + (temp % 3) == 0;
+  }
+};
+class DataMask110 : public CBC_QRDataMask {
+ public:
+  FX_BOOL IsMasked(int32_t x, int32_t y) {
+    size_t temp = x * y;
+    return (((temp % 2) + (temp % 3)) % 2) == 0;
+  }
+};
+class DataMask111 : public CBC_QRDataMask {
+ public:
+  FX_BOOL IsMasked(int32_t x, int32_t y) {
+    return ((((x + y) % 2) + ((x * y) % 3)) % 2) == 0;
+  }
+};
+int32_t CBC_QRDataMask::BuildDataMasks() {
+  DATA_MASKS->Add(new DataMask000);
+  DATA_MASKS->Add(new DataMask001);
+  DATA_MASKS->Add(new DataMask010);
+  DATA_MASKS->Add(new DataMask011);
+  DATA_MASKS->Add(new DataMask100);
+  DATA_MASKS->Add(new DataMask101);
+  DATA_MASKS->Add(new DataMask110);
+  DATA_MASKS->Add(new DataMask111);
+  return DATA_MASKS->GetSize();
+}
+CBC_QRDataMask::CBC_QRDataMask() {}
+CBC_QRDataMask::~CBC_QRDataMask() {}
diff --git a/xfa/fxbarcode/qrcode/BC_QRDataMask.h b/xfa/fxbarcode/qrcode/BC_QRDataMask.h
new file mode 100644
index 0000000..5893149
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRDataMask.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 XFA_FXBARCODE_QRCODE_BC_QRDATAMASK_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRDATAMASK_H_
+
+#include "core/include/fxcrt/fx_basic.h"
+
+class CBC_CommonBitMatrix;
+
+class CBC_QRDataMask {
+ public:
+  static CFX_PtrArray* DATA_MASKS;
+  CBC_QRDataMask();
+  virtual ~CBC_QRDataMask();
+  static void Initialize();
+  static void Finalize();
+  virtual FX_BOOL IsMasked(int32_t i, int32_t j) = 0;
+  void UnmaskBitMatirx(CBC_CommonBitMatrix* bits, int32_t dimension);
+  static CBC_QRDataMask* ForReference(int32_t reference, int32_t& e);
+  static int32_t BuildDataMasks();
+  static void Destroy();
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRDATAMASK_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.cpp b/xfa/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.cpp
new file mode 100644
index 0000000..8919c3a
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.cpp
@@ -0,0 +1,273 @@
+// 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 "xfa/fxbarcode/BC_UtilCodingConvert.h"
+#include "xfa/fxbarcode/common/BC_CommonBitSource.h"
+#include "xfa/fxbarcode/common/BC_CommonCharacterSetECI.h"
+#include "xfa/fxbarcode/common/BC_CommonDecoderResult.h"
+#include "xfa/fxbarcode/common/BC_CommonECI.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderMode.h"
+#include "xfa/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.h"
+
+const FX_CHAR* CBC_QRDecodedBitStreamParser::UTF_8 = "utf8";
+const FX_CHAR CBC_QRDecodedBitStreamParser::ALPHANUMERIC_CHARS[45] = {
+    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
+    'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+    'U', 'V', 'W', 'X', 'Y', 'Z', ' ', '$', '%', '*', '+', '-', '.', '/', ':'};
+
+CBC_QRDecodedBitStreamParser::CBC_QRDecodedBitStreamParser() {}
+CBC_QRDecodedBitStreamParser::~CBC_QRDecodedBitStreamParser() {}
+CBC_CommonDecoderResult* CBC_QRDecodedBitStreamParser::Decode(
+    CFX_ByteArray* bytes,
+    CBC_QRCoderVersion* version,
+    CBC_QRCoderErrorCorrectionLevel* ecLevel,
+    int32_t byteModeDecode,
+    int32_t& e) {
+  CBC_CommonBitSource bits(bytes);
+  CFX_ByteString result;
+  CBC_CommonCharacterSetECI* currentCharacterSetECI = NULL;
+  FX_BOOL fc1Infact = FALSE;
+  CFX_Int32Array byteSegments;
+  CBC_QRCoderMode* mode = NULL;
+  do {
+    if (bits.Available() < 4) {
+      mode = CBC_QRCoderMode::sTERMINATOR;
+    } else {
+      int32_t iTemp1 = bits.ReadBits(4, e);
+      BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+      mode = CBC_QRCoderMode::ForBits(iTemp1, e);
+      BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+      if (mode == NULL) {
+        e = BCExceptionUnSupportMode;
+        BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+      }
+    }
+    if (!(mode == CBC_QRCoderMode::sTERMINATOR)) {
+      if (mode == CBC_QRCoderMode::sFNC1_FIRST_POSITION ||
+          mode == CBC_QRCoderMode::sFNC1_SECOND_POSITION) {
+        fc1Infact = TRUE;
+      } else if (mode == CBC_QRCoderMode::sSTRUCTURED_APPEND) {
+        bits.ReadBits(16, e);
+        BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+      } else if (mode == CBC_QRCoderMode::sECI) {
+        int32_t value = ParseECIValue(&bits, e);
+        BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+        currentCharacterSetECI =
+            CBC_CommonCharacterSetECI::GetCharacterSetECIByValue(value);
+      } else {
+        if (mode == CBC_QRCoderMode::sGBK) {
+          bits.ReadBits(4, e);
+          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+        }
+        int32_t numBits = mode->GetCharacterCountBits(version, e);
+        BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+        int32_t count = bits.ReadBits(numBits, e);
+        BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+        if (mode == CBC_QRCoderMode::sNUMERIC) {
+          DecodeNumericSegment(&bits, result, count, e);
+          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+        } else if (mode == CBC_QRCoderMode::sALPHANUMERIC) {
+          DecodeAlphanumericSegment(&bits, result, count, fc1Infact, e);
+          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+        } else if (mode == CBC_QRCoderMode::sBYTE) {
+          DecodeByteSegment(&bits, result, count, currentCharacterSetECI,
+                            &byteSegments, byteModeDecode, e);
+          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+        } else if (mode == CBC_QRCoderMode::sGBK) {
+          DecodeGBKSegment(&bits, result, count, e);
+          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+        } else if (mode == CBC_QRCoderMode::sKANJI) {
+          DecodeKanjiSegment(&bits, result, count, e);
+          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+        } else {
+          e = BCExceptionUnSupportMode;
+          BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+        }
+      }
+    }
+  } while (!(mode == CBC_QRCoderMode::sTERMINATOR));
+  CBC_CommonDecoderResult* tempCd = new CBC_CommonDecoderResult();
+  tempCd->Init(*bytes, result, byteSegments, ecLevel, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  return tempCd;
+}
+void CBC_QRDecodedBitStreamParser::DecodeGBKSegment(CBC_CommonBitSource* bits,
+                                                    CFX_ByteString& result,
+                                                    int32_t count,
+                                                    int32_t& e) {
+  CFX_ByteString buffer;
+  while (count > 0) {
+    int32_t twoBytes = bits->ReadBits(13, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+    int32_t assembledTwoBytes = ((twoBytes / 0x060) << 8) | (twoBytes % 0x060);
+    if (assembledTwoBytes <= 0x0095d) {
+      assembledTwoBytes += 0x0a1a1;
+    } else {
+      assembledTwoBytes += 0x0a6a1;
+    }
+    buffer += (uint8_t)(assembledTwoBytes >> 8);
+    buffer += (uint8_t)assembledTwoBytes;
+    count--;
+  }
+  CBC_UtilCodingConvert::LocaleToUtf8(buffer, result);
+}
+void CBC_QRDecodedBitStreamParser::DecodeKanjiSegment(CBC_CommonBitSource* bits,
+                                                      CFX_ByteString& result,
+                                                      int32_t count,
+                                                      int32_t& e) {
+  CFX_ByteString buffer;
+  while (count > 0) {
+    int32_t twoBytes = bits->ReadBits(13, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+    int32_t assembledTwoBytes = ((twoBytes / 0x0c0) << 8) | (twoBytes % 0x0c0);
+    if (assembledTwoBytes <= 0x01f00) {
+      assembledTwoBytes += 0x08140;
+    } else {
+      assembledTwoBytes += 0x0c140;
+    }
+    buffer += (uint8_t)(assembledTwoBytes >> 8);
+    buffer += (uint8_t)assembledTwoBytes;
+    count--;
+  }
+  CBC_UtilCodingConvert::LocaleToUtf8(buffer, result);
+}
+void CBC_QRDecodedBitStreamParser::DecodeByteSegment(
+    CBC_CommonBitSource* bits,
+    CFX_ByteString& result,
+    int32_t count,
+    CBC_CommonCharacterSetECI* currentCharacterSetECI,
+    CFX_Int32Array* byteSegments,
+    int32_t byteModeDecode,
+    int32_t& e) {
+  if (count < 0) {
+    e = BCExceptionNotFound;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  if ((count << 3) > bits->Available()) {
+    e = BCExceptionRead;
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  uint8_t* readBytes = FX_Alloc(uint8_t, count);
+  FXSYS_memset(readBytes, 0x00, count);
+  for (int32_t i = 0; i < count; i++) {
+    readBytes[i] = (uint8_t)bits->ReadBits(8, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+  }
+  CFX_ByteString bs(readBytes, count);
+  result += bs;
+  FX_Free(readBytes);
+}
+void CBC_QRDecodedBitStreamParser::DecodeAlphanumericSegment(
+    CBC_CommonBitSource* bits,
+    CFX_ByteString& result,
+    int32_t count,
+    FX_BOOL fac1InEffect,
+    int32_t& e) {
+  int32_t start = result.GetLength();
+  while (count > 1) {
+    int32_t nextTwoCharsBits = bits->ReadBits(11, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+    BC_FX_ByteString_Append(result, 1,
+                            ALPHANUMERIC_CHARS[nextTwoCharsBits / 45]);
+    BC_FX_ByteString_Append(result, 1,
+                            ALPHANUMERIC_CHARS[nextTwoCharsBits % 45]);
+    count -= 2;
+  }
+  if (count == 1) {
+    int32_t itemp = bits->ReadBits(6, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+    BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[itemp]);
+  }
+  if (fac1InEffect) {
+    for (int32_t i = start; i < result.GetLength(); i++) {
+      if (result[i] == '%') {
+        if ((i < result.GetLength() - 1) && result[i + 1] == '%') {
+          result.Delete(i + 1, 1);
+        } else {
+          result.SetAt(i, (FX_CHAR)0x1d);
+        }
+      }
+    }
+  }
+}
+void CBC_QRDecodedBitStreamParser::DecodeNumericSegment(
+    CBC_CommonBitSource* bits,
+    CFX_ByteString& result,
+    int32_t count,
+    int32_t& e) {
+  while (count >= 3) {
+    int32_t threeDigitsBits = bits->ReadBits(10, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+    if (threeDigitsBits >= 1000) {
+      e = BCExceptionRead;
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    }
+    BC_FX_ByteString_Append(result, 1,
+                            ALPHANUMERIC_CHARS[threeDigitsBits / 100]);
+    BC_FX_ByteString_Append(result, 1,
+                            ALPHANUMERIC_CHARS[(threeDigitsBits / 10) % 10]);
+    BC_FX_ByteString_Append(result, 1,
+                            ALPHANUMERIC_CHARS[threeDigitsBits % 10]);
+    count -= 3;
+  }
+  if (count == 2) {
+    int32_t twoDigitBits = bits->ReadBits(7, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+    if (twoDigitBits >= 100) {
+      e = BCExceptionRead;
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    }
+    BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[twoDigitBits / 10]);
+    BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[twoDigitBits % 10]);
+  } else if (count == 1) {
+    int32_t digitBits = bits->ReadBits(4, e);
+    BC_EXCEPTION_CHECK_ReturnVoid(e);
+    if (digitBits >= 10) {
+      e = BCExceptionRead;
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    }
+    BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[digitBits]);
+  }
+}
+const CFX_ByteString CBC_QRDecodedBitStreamParser::GuessEncoding(
+    CFX_ByteArray* bytes) {
+  return *UTF_8;
+}
+int32_t CBC_QRDecodedBitStreamParser::ParseECIValue(CBC_CommonBitSource* bits,
+                                                    int32_t& e) {
+  int32_t firstByte = bits->ReadBits(8, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+  if ((firstByte & 0x80) == 0) {
+    return firstByte & 0x7f;
+  } else if ((firstByte & 0xc0) == 0x80) {
+    int32_t secondByte = bits->ReadBits(8, e);
+    BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+    return ((firstByte & 0x3f) << 8) | secondByte;
+  } else if ((firstByte & 0xe0) == 0xc0) {
+    int32_t secondThirdByte = bits->ReadBits(16, e);
+    BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+    return ((firstByte & 0x1f) << 16) | secondThirdByte;
+  }
+  e = BCExceptionBadECI;
+  BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+  return 0;
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.h b/xfa/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.h
new file mode 100644
index 0000000..0943bc0
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.h
@@ -0,0 +1,59 @@
+// 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 XFA_FXBARCODE_QRCODE_BC_QRDECODEDBITSTREAMPARSER_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRDECODEDBITSTREAMPARSER_H_
+
+class CBC_CommonDecoderResult;
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_CommonBitSource;
+class CBC_QRCoderVersion;
+class CBC_CommonCharacterSetECI;
+class CBC_QRDecodedBitStreamParser {
+ private:
+  static const FX_CHAR ALPHANUMERIC_CHARS[45];
+  static const FX_CHAR* UTF_8;
+  CBC_QRDecodedBitStreamParser();
+
+ public:
+  virtual ~CBC_QRDecodedBitStreamParser();
+  static CBC_CommonDecoderResult* Decode(
+      CFX_ByteArray* bytes,
+      CBC_QRCoderVersion* version,
+      CBC_QRCoderErrorCorrectionLevel* ecLevel,
+      int32_t byteModeDecode,
+      int32_t& e);
+
+  static const CFX_ByteString GuessEncoding(CFX_ByteArray* bytes);
+  static int32_t ParseECIValue(CBC_CommonBitSource* bits, int32_t& e);
+  static void DecodeGBKSegment(CBC_CommonBitSource* bits,
+                               CFX_ByteString& result,
+                               int32_t count,
+                               int32_t& e);
+  static void DecodeKanjiSegment(CBC_CommonBitSource* bits,
+                                 CFX_ByteString& result,
+                                 int32_t count,
+                                 int32_t& e);
+  static void DecodeNumericSegment(CBC_CommonBitSource* bits,
+                                   CFX_ByteString& result,
+                                   int32_t count,
+                                   int32_t& e);
+  static void DecodeAlphanumericSegment(CBC_CommonBitSource* bits,
+                                        CFX_ByteString& result,
+                                        int32_t count,
+                                        FX_BOOL fac1InEffect,
+                                        int32_t& e);
+  static void DecodeByteSegment(
+      CBC_CommonBitSource* bits,
+      CFX_ByteString& result,
+      int32_t count,
+      CBC_CommonCharacterSetECI* currentCharacterSetECI,
+      CFX_Int32Array* byteSegments,
+      int32_t byteModeDecode,
+      int32_t& e);
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRDECODEDBITSTREAMPARSER_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRDetector.cpp b/xfa/fxbarcode/qrcode/BC_QRDetector.cpp
new file mode 100644
index 0000000..030ee43
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRDetector.cpp
@@ -0,0 +1,278 @@
+// 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 "xfa/fxbarcode/qrcode/BC_QRDetector.h"
+
+#include <algorithm>
+#include <memory>
+
+#include "xfa/fxbarcode/BC_ResultPoint.h"
+#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h"
+#include "xfa/fxbarcode/qrcode/BC_FinderPatternInfo.h"
+#include "xfa/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.h"
+#include "xfa/fxbarcode/qrcode/BC_QRCoderVersion.h"
+#include "xfa/fxbarcode/qrcode/BC_QRDetectorResult.h"
+#include "xfa/fxbarcode/qrcode/BC_QRFinderPattern.h"
+#include "xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.h"
+#include "xfa/fxbarcode/qrcode/BC_QRGridSampler.h"
+
+CBC_QRDetector::CBC_QRDetector(CBC_CommonBitMatrix* image) : m_image(image) {}
+CBC_QRDetector::~CBC_QRDetector() {}
+CBC_QRDetectorResult* CBC_QRDetector::Detect(int32_t hints, int32_t& e) {
+  CBC_QRFinderPatternFinder finder(m_image);
+  std::unique_ptr<CBC_QRFinderPatternInfo> info(finder.Find(hints, e));
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  CBC_QRDetectorResult* qdr = ProcessFinderPatternInfo(info.get(), e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  return qdr;
+}
+CBC_QRDetectorResult* CBC_QRDetector::ProcessFinderPatternInfo(
+    CBC_QRFinderPatternInfo* info,
+    int32_t& e) {
+  std::unique_ptr<CBC_QRFinderPattern> topLeft(info->GetTopLeft());
+  std::unique_ptr<CBC_QRFinderPattern> topRight(info->GetTopRight());
+  std::unique_ptr<CBC_QRFinderPattern> bottomLeft(info->GetBottomLeft());
+  FX_FLOAT moduleSize =
+      CalculateModuleSize(topLeft.get(), topRight.get(), bottomLeft.get());
+  if (moduleSize < 1.0f) {
+    e = BCExceptionRead;
+    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  }
+  int32_t dimension = ComputeDimension(topLeft.get(), topRight.get(),
+                                       bottomLeft.get(), moduleSize, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  CBC_QRCoderVersion* provisionalVersion =
+      CBC_QRCoderVersion::GetProvisionalVersionForDimension(dimension, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  int32_t modulesBetweenFPCenters =
+      provisionalVersion->GetDimensionForVersion() - 7;
+  CBC_QRAlignmentPattern* alignmentPattern = NULL;
+  if (provisionalVersion->GetAlignmentPatternCenters()->GetSize() > 0) {
+    FX_FLOAT bottomRightX =
+        topRight->GetX() - topLeft->GetX() + bottomLeft->GetX();
+    FX_FLOAT bottomRightY =
+        topRight->GetY() - topLeft->GetY() + bottomLeft->GetY();
+    FX_FLOAT correctionToTopLeft =
+        1.0f - 3.0f / (FX_FLOAT)modulesBetweenFPCenters;
+    FX_FLOAT xtemp = (topLeft->GetX() +
+                      correctionToTopLeft * (bottomRightX - topLeft->GetX()));
+    int32_t estAlignmentX = (int32_t)xtemp;
+    FX_FLOAT ytemp = (topLeft->GetY() +
+                      correctionToTopLeft * (bottomRightY - topLeft->GetY()));
+    int32_t estAlignmentY = (int32_t)ytemp;
+    for (int32_t i = 4; i <= 16; i <<= 1) {
+      CBC_QRAlignmentPattern* temp = FindAlignmentInRegion(
+          moduleSize, estAlignmentX, estAlignmentY, (FX_FLOAT)i, e);
+      alignmentPattern = temp;
+      break;
+    }
+  }
+  CBC_CommonBitMatrix* bits =
+      SampleGrid(m_image, topLeft.get(), topRight.get(), bottomLeft.get(),
+                 (CBC_ResultPoint*)(alignmentPattern), dimension, e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  CFX_PtrArray* points = new CFX_PtrArray;
+  if (alignmentPattern == NULL) {
+    points->Add(bottomLeft.release());
+    points->Add(topLeft.release());
+    points->Add(topRight.release());
+  } else {
+    points->Add(bottomLeft.release());
+    points->Add(topLeft.release());
+    points->Add(topRight.release());
+    points->Add(alignmentPattern);
+  }
+  return new CBC_QRDetectorResult(bits, points);
+}
+CBC_CommonBitMatrix* CBC_QRDetector::SampleGrid(
+    CBC_CommonBitMatrix* image,
+    CBC_ResultPoint* topLeft,
+    CBC_ResultPoint* topRight,
+    CBC_ResultPoint* bottomLeft,
+    CBC_ResultPoint* alignmentPattern,
+    int32_t dimension,
+    int32_t& e) {
+  FX_FLOAT dimMinusThree = (FX_FLOAT)dimension - 3.5f;
+  FX_FLOAT bottomRightX;
+  FX_FLOAT bottomRightY;
+  FX_FLOAT sourceBottomRightX;
+  FX_FLOAT sourceBottomRightY;
+  if (alignmentPattern) {
+    bottomRightX = alignmentPattern->GetX();
+    bottomRightY = alignmentPattern->GetY();
+    sourceBottomRightX = sourceBottomRightY = dimMinusThree - 3.0f;
+  } else {
+    bottomRightX = (topRight->GetX() - topLeft->GetX()) + bottomLeft->GetX();
+    bottomRightY = (topRight->GetY() - topLeft->GetY()) + bottomLeft->GetY();
+    sourceBottomRightX = sourceBottomRightY = dimMinusThree;
+  }
+  CBC_QRGridSampler& sampler = CBC_QRGridSampler::GetInstance();
+  CBC_CommonBitMatrix* cbm = sampler.SampleGrid(
+      image, dimension, dimension, 3.5f, 3.5f, dimMinusThree, 3.5f,
+      sourceBottomRightX, sourceBottomRightY, 3.5f, dimMinusThree,
+      topLeft->GetX(), topLeft->GetY(), topRight->GetX(), topRight->GetY(),
+      bottomRightX, bottomRightY, bottomLeft->GetX(), bottomLeft->GetY(), e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  return cbm;
+}
+int32_t CBC_QRDetector::ComputeDimension(CBC_ResultPoint* topLeft,
+                                         CBC_ResultPoint* topRight,
+                                         CBC_ResultPoint* bottomLeft,
+                                         FX_FLOAT moduleSize,
+                                         int32_t& e) {
+  int32_t tltrCentersDimension = Round(
+      CBC_QRFinderPatternFinder::Distance(topLeft, topRight) / moduleSize);
+  int32_t tlblCentersDimension = Round(
+      CBC_QRFinderPatternFinder::Distance(topLeft, bottomLeft) / moduleSize);
+  int32_t dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7;
+  switch (dimension & 0x03) {
+    case 0:
+      dimension++;
+      break;
+    case 2:
+      dimension--;
+      break;
+    case 3: {
+      e = BCExceptionRead;
+      BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+    }
+  }
+  return dimension;
+}
+FX_FLOAT CBC_QRDetector::CalculateModuleSize(CBC_ResultPoint* topLeft,
+                                             CBC_ResultPoint* topRight,
+                                             CBC_ResultPoint* bottomLeft) {
+  return (CalculateModuleSizeOneWay(topLeft, topRight) +
+          CalculateModuleSizeOneWay(topLeft, bottomLeft)) /
+         2.0f;
+}
+FX_FLOAT CBC_QRDetector::CalculateModuleSizeOneWay(
+    CBC_ResultPoint* pattern,
+    CBC_ResultPoint* otherPattern) {
+  FX_FLOAT moduleSizeEst1 = SizeOfBlackWhiteBlackRunBothWays(
+      (int32_t)pattern->GetX(), (int32_t)pattern->GetY(),
+      (int32_t)otherPattern->GetX(), (int32_t)otherPattern->GetY());
+  FX_FLOAT moduleSizeEst2 = SizeOfBlackWhiteBlackRunBothWays(
+      (int32_t)otherPattern->GetX(), (int32_t)otherPattern->GetY(),
+      (int32_t)pattern->GetX(), (int32_t)pattern->GetY());
+  if (FXSYS_isnan(moduleSizeEst1)) {
+    return moduleSizeEst2;
+  }
+  if (FXSYS_isnan(moduleSizeEst2)) {
+    return moduleSizeEst1;
+  }
+  return (moduleSizeEst1 + moduleSizeEst2) / 14.0f;
+}
+int32_t CBC_QRDetector::Round(FX_FLOAT d) {
+  return (int32_t)(d + 0.5f);
+}
+FX_FLOAT CBC_QRDetector::SizeOfBlackWhiteBlackRunBothWays(int32_t fromX,
+                                                          int32_t fromY,
+                                                          int32_t toX,
+                                                          int32_t toY) {
+  FX_FLOAT result = SizeOfBlackWhiteBlackRun(fromX, fromY, toX, toY);
+  int32_t otherToX = fromX - (toX - fromX);
+  if (otherToX < 0) {
+    otherToX = -1;
+  } else if (otherToX >= m_image->GetWidth()) {
+    otherToX = m_image->GetWidth();
+  }
+  int32_t otherToY = fromY - (toY - fromY);
+  if (otherToY < 0) {
+    otherToY = -1;
+  } else if (otherToY >= m_image->GetHeight()) {
+    otherToY = m_image->GetHeight();
+  }
+  result += SizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY);
+  return result - 1.0f;
+}
+FX_FLOAT CBC_QRDetector::SizeOfBlackWhiteBlackRun(int32_t fromX,
+                                                  int32_t fromY,
+                                                  int32_t toX,
+                                                  int32_t toY) {
+  FX_BOOL steep = FXSYS_abs(toY - fromY) > FXSYS_abs(toX - fromX);
+  if (steep) {
+    int32_t temp = fromX;
+    fromX = fromY;
+    fromY = temp;
+    temp = toX;
+    toX = toY;
+    toY = temp;
+  }
+  int32_t dx = FXSYS_abs(toX - fromX);
+  int32_t dy = FXSYS_abs(toY - fromY);
+  int32_t error = -dx >> 1;
+  int32_t ystep = fromY < toY ? 1 : -1;
+  int32_t xstep = fromX < toX ? 1 : -1;
+  int32_t state = 0;
+  for (int32_t x = fromX, y = fromY; x != toX; x += xstep) {
+    int32_t realX = steep ? y : x;
+    int32_t realY = steep ? x : y;
+    if (state == 1) {
+      if (m_image->Get(realX, realY)) {
+        state++;
+      }
+    } else {
+      if (!m_image->Get(realX, realY)) {
+        state++;
+      }
+    }
+    if (state == 3) {
+      int32_t diffX = x - fromX;
+      int32_t diffY = y - fromY;
+      return (FX_FLOAT)sqrt((double)(diffX * diffX + diffY * diffY));
+    }
+    error += dy;
+    if (error > 0) {
+      y += ystep;
+      error -= dx;
+    }
+  }
+  int32_t diffX = toX - fromX;
+  int32_t diffY = toY - fromY;
+  return (FX_FLOAT)sqrt((double)(diffX * diffX + diffY * diffY));
+}
+CBC_QRAlignmentPattern* CBC_QRDetector::FindAlignmentInRegion(
+    FX_FLOAT overallEstModuleSize,
+    int32_t estAlignmentX,
+    int32_t estAlignmentY,
+    FX_FLOAT allowanceFactor,
+    int32_t& e) {
+  int32_t allowance = (int32_t)(allowanceFactor * overallEstModuleSize);
+  int32_t alignmentAreaLeftX = std::max(0, estAlignmentX - allowance);
+  int32_t alignmentAreaRightX =
+      std::min(m_image->GetWidth() - 1, estAlignmentX + allowance);
+  if (alignmentAreaRightX - alignmentAreaLeftX < overallEstModuleSize * 3) {
+    e = BCExceptionRead;
+    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  }
+  int32_t alignmentAreaTopY = std::max(0, estAlignmentY - allowance);
+  int32_t alignmentAreaBottomY =
+      std::min(m_image->GetHeight() - 1, estAlignmentY + allowance);
+  CBC_QRAlignmentPatternFinder alignmentFinder(
+      m_image, alignmentAreaLeftX, alignmentAreaTopY,
+      alignmentAreaRightX - alignmentAreaLeftX,
+      alignmentAreaBottomY - alignmentAreaTopY, overallEstModuleSize);
+  CBC_QRAlignmentPattern* qap = alignmentFinder.Find(e);
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  return qap;
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRDetector.h b/xfa/fxbarcode/qrcode/BC_QRDetector.h
new file mode 100644
index 0000000..4c17184
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRDetector.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 XFA_FXBARCODE_QRCODE_BC_QRDETECTOR_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRDETECTOR_H_
+
+#include "core/include/fxcrt/fx_basic.h"
+
+class CBC_ResultPoint;
+class CBC_CommonBitMatrix;
+class CBC_QRDetectorResult;
+class CBC_QRFinderPatternInfo;
+class CBC_QRAlignmentPattern;
+
+class CBC_QRDetector {
+ private:
+  CBC_CommonBitMatrix* m_image;
+
+ public:
+  CBC_QRDetector(CBC_CommonBitMatrix* image);
+  virtual ~CBC_QRDetector();
+
+  CBC_CommonBitMatrix* GetImage();
+  CBC_QRDetectorResult* Detect(int32_t hints, int32_t& e);
+  CBC_QRDetectorResult* ProcessFinderPatternInfo(CBC_QRFinderPatternInfo* info,
+                                                 int32_t& e);
+  FX_FLOAT CalculateModuleSize(CBC_ResultPoint* topLeft,
+                               CBC_ResultPoint* topRight,
+                               CBC_ResultPoint* bottomLeft);
+  FX_FLOAT CalculateModuleSizeOneWay(CBC_ResultPoint* pattern,
+                                     CBC_ResultPoint* otherPattern);
+  FX_FLOAT SizeOfBlackWhiteBlackRunBothWays(int32_t fromX,
+                                            int32_t fromY,
+                                            int32_t toX,
+                                            int32_t toY);
+  FX_FLOAT SizeOfBlackWhiteBlackRun(int32_t fromX,
+                                    int32_t fromY,
+                                    int32_t toX,
+                                    int32_t toY);
+  CBC_QRAlignmentPattern* FindAlignmentInRegion(FX_FLOAT overallEstModuleSize,
+                                                int32_t estAlignmentX,
+                                                int32_t estAlignmentY,
+                                                FX_FLOAT allowanceFactor,
+                                                int32_t& e);
+  static int32_t Round(FX_FLOAT d);
+  static int32_t ComputeDimension(CBC_ResultPoint* topLeft,
+                                  CBC_ResultPoint* topRight,
+                                  CBC_ResultPoint* bottomLeft,
+                                  FX_FLOAT moduleSize,
+                                  int32_t& e);
+  static CBC_CommonBitMatrix* SampleGrid(CBC_CommonBitMatrix* image,
+                                         CBC_ResultPoint* topLeft,
+                                         CBC_ResultPoint* topRight,
+                                         CBC_ResultPoint* bottomLeft,
+                                         CBC_ResultPoint* alignmentPattern,
+                                         int32_t dimension,
+                                         int32_t& e);
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRDETECTOR_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRDetectorResult.cpp b/xfa/fxbarcode/qrcode/BC_QRDetectorResult.cpp
new file mode 100644
index 0000000..18e5d9a
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRDetectorResult.cpp
@@ -0,0 +1,43 @@
+// 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 "xfa/fxbarcode/BC_ResultPoint.h"
+#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h"
+#include "xfa/fxbarcode/qrcode/BC_QRDetectorResult.h"
+
+CBC_QRDetectorResult::CBC_QRDetectorResult(CBC_CommonBitMatrix* bits,
+                                           CFX_PtrArray* points)
+    : m_bits(bits), m_points(points) {}
+CBC_QRDetectorResult::~CBC_QRDetectorResult() {
+  for (int32_t i = 0; i < m_points->GetSize(); i++) {
+    delete (CBC_ResultPoint*)(*m_points)[i];
+  }
+  m_points->RemoveAll();
+  delete m_points;
+  delete m_bits;
+}
+CBC_CommonBitMatrix* CBC_QRDetectorResult::GetBits() {
+  return m_bits;
+}
+CFX_PtrArray* CBC_QRDetectorResult::GetPoints() {
+  return m_points;
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRDetectorResult.h b/xfa/fxbarcode/qrcode/BC_QRDetectorResult.h
new file mode 100644
index 0000000..c6145ec
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRDetectorResult.h
@@ -0,0 +1,26 @@
+// 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 XFA_FXBARCODE_QRCODE_BC_QRDETECTORRESULT_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRDETECTORRESULT_H_
+
+#include "core/include/fxcrt/fx_basic.h"
+
+class CBC_CommonBitMatrix;
+
+class CBC_QRDetectorResult {
+ private:
+  CBC_CommonBitMatrix* m_bits;
+  CFX_PtrArray* m_points;
+
+ public:
+  CBC_QRDetectorResult(CBC_CommonBitMatrix* bits, CFX_PtrArray* points);
+  virtual ~CBC_QRDetectorResult();
+  CBC_CommonBitMatrix* GetBits();
+  CFX_PtrArray* GetPoints();
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRDETECTORRESULT_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRFinderPattern.cpp b/xfa/fxbarcode/qrcode/BC_QRFinderPattern.cpp
new file mode 100644
index 0000000..5039920
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRFinderPattern.cpp
@@ -0,0 +1,68 @@
+// 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 "xfa/fxbarcode/BC_ResultPoint.h"
+#include "xfa/fxbarcode/qrcode/BC_QRFinderPattern.h"
+
+CBC_QRFinderPattern::CBC_QRFinderPattern(FX_FLOAT x,
+                                         FX_FLOAT posY,
+                                         FX_FLOAT estimatedModuleSize)
+    : CBC_ResultPoint(x, posY),
+      m_estimatedModuleSize(estimatedModuleSize),
+      m_count(1) {}
+CBC_QRFinderPattern::~CBC_QRFinderPattern() {
+  m_count = 0;
+  m_x = 0.0f;
+  m_y = 0.0f;
+  m_estimatedModuleSize = 0.0f;
+}
+CBC_QRFinderPattern* CBC_QRFinderPattern::Clone() {
+  CBC_QRFinderPattern* temp =
+      new CBC_QRFinderPattern(m_x, m_y, m_estimatedModuleSize);
+  temp->m_count = m_count;
+  return temp;
+}
+FX_FLOAT CBC_QRFinderPattern::GetEstimatedModuleSize() {
+  return m_estimatedModuleSize;
+}
+int32_t CBC_QRFinderPattern::GetCount() {
+  return m_count;
+}
+void CBC_QRFinderPattern::IncrementCount() {
+  m_count++;
+}
+FX_BOOL CBC_QRFinderPattern::AboutEquals(FX_FLOAT moduleSize,
+                                         FX_FLOAT i,
+                                         FX_FLOAT j) {
+  if ((fabs(i - GetY()) <= moduleSize) && (fabs(j - GetX()) <= moduleSize)) {
+    FX_FLOAT moduleSizeDiff = fabs(moduleSize - m_estimatedModuleSize);
+    return (moduleSizeDiff <= 1.0f) ||
+           (moduleSizeDiff / m_estimatedModuleSize <= 1.0f);
+  }
+  return false;
+}
+FX_FLOAT CBC_QRFinderPattern::GetX() {
+  return m_x;
+}
+FX_FLOAT CBC_QRFinderPattern::GetY() {
+  return m_y;
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRFinderPattern.h b/xfa/fxbarcode/qrcode/BC_QRFinderPattern.h
new file mode 100644
index 0000000..bf3adff
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRFinderPattern.h
@@ -0,0 +1,31 @@
+// 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 XFA_FXBARCODE_QRCODE_BC_QRFINDERPATTERN_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRFINDERPATTERN_H_
+
+class CBC_ResultPoint;
+class CBC_QRFinderPattern;
+class CBC_QRFinderPattern : public CBC_ResultPoint {
+ private:
+  FX_FLOAT m_estimatedModuleSize;
+  int32_t m_count;
+
+ public:
+  CBC_QRFinderPattern(FX_FLOAT x, FX_FLOAT posY, FX_FLOAT estimatedModuleSize);
+  virtual ~CBC_QRFinderPattern();
+
+  int32_t GetCount();
+  FX_FLOAT GetX();
+  FX_FLOAT GetY();
+  FX_FLOAT GetEstimatedModuleSize();
+  void IncrementCount();
+  FX_BOOL AboutEquals(FX_FLOAT moduleSize, FX_FLOAT i, FX_FLOAT j);
+  CBC_QRFinderPattern* Clone();
+};
+typedef CBC_QRFinderPattern FinderPattern;
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRFINDERPATTERN_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.cpp b/xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.cpp
new file mode 100644
index 0000000..5ccbd98
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.cpp
@@ -0,0 +1,477 @@
+// 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 "xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.h"
+
+#include <memory>
+
+#include "core/include/fxcrt/fx_basic.h"
+#include "xfa/fxbarcode/BC_ResultPoint.h"
+#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h"
+#include "xfa/fxbarcode/qrcode/BC_FinderPatternInfo.h"
+#include "xfa/fxbarcode/qrcode/BC_QRFinderPattern.h"
+#include "xfa/fxbarcode/utils.h"
+
+const int32_t CBC_QRFinderPatternFinder::CENTER_QUORUM = 2;
+const int32_t CBC_QRFinderPatternFinder::MIN_SKIP = 3;
+const int32_t CBC_QRFinderPatternFinder::MAX_MODULES = 57;
+const int32_t CBC_QRFinderPatternFinder::INTEGER_MATH_SHIFT = 8;
+
+CBC_QRFinderPatternFinder::CBC_QRFinderPatternFinder(
+    CBC_CommonBitMatrix* image) {
+  m_image = image;
+  m_crossCheckStateCount.SetSize(5);
+  m_hasSkipped = FALSE;
+}
+CBC_QRFinderPatternFinder::~CBC_QRFinderPatternFinder() {
+  for (int32_t i = 0; i < m_possibleCenters.GetSize(); i++) {
+    delete (CBC_QRFinderPattern*)m_possibleCenters[i];
+  }
+  m_possibleCenters.RemoveAll();
+}
+class ClosestToAverageComparator {
+ private:
+  FX_FLOAT m_averageModuleSize;
+
+ public:
+  ClosestToAverageComparator(FX_FLOAT averageModuleSize)
+      : m_averageModuleSize(averageModuleSize) {}
+  int32_t operator()(FinderPattern* a, FinderPattern* b) {
+    FX_FLOAT dA =
+        (FX_FLOAT)fabs(a->GetEstimatedModuleSize() - m_averageModuleSize);
+    FX_FLOAT dB =
+        (FX_FLOAT)fabs(b->GetEstimatedModuleSize() - m_averageModuleSize);
+    return dA < dB ? -1 : dA > dB ? 1 : 0;
+  }
+};
+class CenterComparator {
+ public:
+  int32_t operator()(FinderPattern* a, FinderPattern* b) {
+    return b->GetCount() - a->GetCount();
+  }
+};
+CBC_CommonBitMatrix* CBC_QRFinderPatternFinder::GetImage() {
+  return m_image;
+}
+CFX_Int32Array& CBC_QRFinderPatternFinder::GetCrossCheckStateCount() {
+  m_crossCheckStateCount[0] = 0;
+  m_crossCheckStateCount[1] = 0;
+  m_crossCheckStateCount[2] = 0;
+  m_crossCheckStateCount[3] = 0;
+  m_crossCheckStateCount[4] = 0;
+  return m_crossCheckStateCount;
+}
+CFX_PtrArray* CBC_QRFinderPatternFinder::GetPossibleCenters() {
+  return &m_possibleCenters;
+}
+CBC_QRFinderPatternInfo* CBC_QRFinderPatternFinder::Find(int32_t hint,
+                                                         int32_t& e) {
+  int32_t maxI = m_image->GetHeight();
+  int32_t maxJ = m_image->GetWidth();
+  int32_t iSkip = (3 * maxI) / (4 * MAX_MODULES);
+  if (iSkip < MIN_SKIP || 0) {
+    iSkip = MIN_SKIP;
+  }
+  FX_BOOL done = FALSE;
+  CFX_Int32Array stateCount;
+  stateCount.SetSize(5);
+  for (int32_t i = iSkip - 1; i < maxI && !done; i += iSkip) {
+    stateCount[0] = 0;
+    stateCount[1] = 0;
+    stateCount[2] = 0;
+    stateCount[3] = 0;
+    stateCount[4] = 0;
+    int32_t currentState = 0;
+    for (int32_t j = 0; j < maxJ; j++) {
+      if (m_image->Get(j, i)) {
+        if ((currentState & 1) == 1) {
+          currentState++;
+        }
+        stateCount[currentState]++;
+      } else {
+        if ((currentState & 1) == 0) {
+          if (currentState == 4) {
+            if (FoundPatternCross(stateCount)) {
+              FX_BOOL confirmed = HandlePossibleCenter(stateCount, i, j);
+              if (confirmed) {
+                iSkip = 2;
+                if (m_hasSkipped) {
+                  done = HaveMultiplyConfirmedCenters();
+                } else {
+                  int32_t rowSkip = FindRowSkip();
+                  if (rowSkip > stateCount[2]) {
+                    i += rowSkip - stateCount[2] - iSkip;
+                    j = maxJ - 1;
+                  }
+                }
+              } else {
+                do {
+                  j++;
+                } while (j < maxJ && !m_image->Get(j, i));
+                j--;
+              }
+              currentState = 0;
+              stateCount[0] = 0;
+              stateCount[1] = 0;
+              stateCount[2] = 0;
+              stateCount[3] = 0;
+              stateCount[4] = 0;
+            } else {
+              stateCount[0] = stateCount[2];
+              stateCount[1] = stateCount[3];
+              stateCount[2] = stateCount[4];
+              stateCount[3] = 1;
+              stateCount[4] = 0;
+              currentState = 3;
+            }
+          } else {
+            stateCount[++currentState]++;
+          }
+        } else {
+          stateCount[currentState]++;
+        }
+      }
+    }
+    if (FoundPatternCross(stateCount)) {
+      FX_BOOL confirmed = HandlePossibleCenter(stateCount, i, maxJ);
+      if (confirmed) {
+        iSkip = stateCount[0];
+        if (m_hasSkipped) {
+          done = HaveMultiplyConfirmedCenters();
+        }
+      }
+    }
+  }
+  std::unique_ptr<CFX_PtrArray> patternInfo(SelectBestpatterns(e));
+  BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  OrderBestPatterns(patternInfo.get());
+  return new CBC_QRFinderPatternInfo(patternInfo.get());
+}
+void CBC_QRFinderPatternFinder::OrderBestPatterns(CFX_PtrArray* patterns) {
+  FX_FLOAT abDistance = Distance((CBC_ResultPoint*)(*patterns)[0],
+                                 (CBC_ResultPoint*)(*patterns)[1]);
+  FX_FLOAT bcDistance = Distance((CBC_ResultPoint*)(*patterns)[1],
+                                 (CBC_ResultPoint*)(*patterns)[2]);
+  FX_FLOAT acDistance = Distance((CBC_ResultPoint*)(*patterns)[0],
+                                 (CBC_ResultPoint*)(*patterns)[2]);
+  CBC_QRFinderPattern *topLeft, *topRight, *bottomLeft;
+  if (bcDistance >= abDistance && bcDistance >= acDistance) {
+    topLeft = (CBC_QRFinderPattern*)(*patterns)[0];
+    topRight = (CBC_QRFinderPattern*)(*patterns)[1];
+    bottomLeft = (CBC_QRFinderPattern*)(*patterns)[2];
+  } else if (acDistance >= bcDistance && acDistance >= abDistance) {
+    topLeft = (CBC_QRFinderPattern*)(*patterns)[1];
+    topRight = (CBC_QRFinderPattern*)(*patterns)[0];
+    bottomLeft = (CBC_QRFinderPattern*)(*patterns)[2];
+  } else {
+    topLeft = (CBC_QRFinderPattern*)(*patterns)[2];
+    topRight = (CBC_QRFinderPattern*)(*patterns)[0];
+    bottomLeft = (CBC_QRFinderPattern*)(*patterns)[1];
+  }
+  if ((bottomLeft->GetY() - topLeft->GetY()) *
+          (topRight->GetX() - topLeft->GetX()) <
+      (bottomLeft->GetX() - topLeft->GetX()) *
+          (topRight->GetY() - topLeft->GetY())) {
+    CBC_QRFinderPattern* temp = topRight;
+    topRight = bottomLeft;
+    bottomLeft = temp;
+  }
+  (*patterns)[0] = bottomLeft;
+  (*patterns)[1] = topLeft;
+  (*patterns)[2] = topRight;
+}
+FX_FLOAT CBC_QRFinderPatternFinder::Distance(CBC_ResultPoint* point1,
+                                             CBC_ResultPoint* point2) {
+  FX_FLOAT dx = point1->GetX() - point2->GetX();
+  FX_FLOAT dy = point1->GetY() - point2->GetY();
+  return (FX_FLOAT)FXSYS_sqrt(dx * dx + dy * dy);
+}
+FX_FLOAT CBC_QRFinderPatternFinder::CenterFromEnd(
+    const CFX_Int32Array& stateCount,
+    int32_t end) {
+  return (FX_FLOAT)(end - stateCount[4] - stateCount[3]) - stateCount[2] / 2.0f;
+}
+FX_BOOL CBC_QRFinderPatternFinder::FoundPatternCross(
+    const CFX_Int32Array& stateCount) {
+  int32_t totalModuleSize = 0;
+  for (int32_t i = 0; i < 5; i++) {
+    int32_t count = stateCount[i];
+    if (count == 0) {
+      return FALSE;
+    }
+    totalModuleSize += count;
+  }
+  if (totalModuleSize < 7) {
+    return FALSE;
+  }
+  int32_t moduleSize = (totalModuleSize << INTEGER_MATH_SHIFT) / 7;
+  int32_t maxVariance = moduleSize / 2;
+  return FXSYS_abs(moduleSize - (stateCount[0] << INTEGER_MATH_SHIFT)) <
+             maxVariance &&
+         FXSYS_abs(moduleSize - (stateCount[1] << INTEGER_MATH_SHIFT)) <
+             maxVariance &&
+         FXSYS_abs(3 * moduleSize - (stateCount[2] << INTEGER_MATH_SHIFT)) <
+             3 * maxVariance &&
+         FXSYS_abs(moduleSize - (stateCount[3] << INTEGER_MATH_SHIFT)) <
+             maxVariance &&
+         FXSYS_abs(moduleSize - (stateCount[4] << INTEGER_MATH_SHIFT)) <
+             maxVariance;
+}
+FX_FLOAT CBC_QRFinderPatternFinder::CrossCheckVertical(
+    int32_t startI,
+    int32_t centerJ,
+    int32_t maxCount,
+    int32_t originalStateCountTotal) {
+  CBC_CommonBitMatrix* image = m_image;
+  int32_t maxI = image->GetHeight();
+  CFX_Int32Array& stateCount = GetCrossCheckStateCount();
+  int32_t i = startI;
+  while (i >= 0 && image->Get(centerJ, i)) {
+    stateCount[2]++;
+    i--;
+  }
+  if (i < 0) {
+    return FXSYS_nan();
+  }
+  while (i >= 0 && !image->Get(centerJ, i) && stateCount[1] <= maxCount) {
+    stateCount[1]++;
+    i--;
+  }
+  if (i < 0 || stateCount[1] > maxCount) {
+    return FXSYS_nan();
+  }
+  while (i >= 0 && image->Get(centerJ, i) && stateCount[0] <= maxCount) {
+    stateCount[0]++;
+    i--;
+  }
+  if (stateCount[0] > maxCount) {
+    return FXSYS_nan();
+  }
+  i = startI + 1;
+  while (i < maxI && image->Get(centerJ, i)) {
+    stateCount[2]++;
+    i++;
+  }
+  if (i == maxI) {
+    return FXSYS_nan();
+  }
+  while (i < maxI && !image->Get(centerJ, i) && stateCount[3] < maxCount) {
+    stateCount[3]++;
+    i++;
+  }
+  if (i == maxI || stateCount[3] >= maxCount) {
+    return FXSYS_nan();
+  }
+  while (i < maxI && image->Get(centerJ, i) && stateCount[4] < maxCount) {
+    stateCount[4]++;
+    i++;
+  }
+  if (stateCount[4] >= maxCount) {
+    return FXSYS_nan();
+  }
+  int32_t stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] +
+                            stateCount[3] + stateCount[4];
+  if (5 * FXSYS_abs(stateCountTotal - originalStateCountTotal) >=
+      originalStateCountTotal) {
+    return FXSYS_nan();
+  }
+  return FoundPatternCross(stateCount) ? CenterFromEnd(stateCount, i)
+                                       : FXSYS_nan();
+}
+FX_FLOAT CBC_QRFinderPatternFinder::CrossCheckHorizontal(
+    int32_t startJ,
+    int32_t centerI,
+    int32_t maxCount,
+    int32_t originalStateCountTotal) {
+  CBC_CommonBitMatrix* image = m_image;
+  int32_t maxJ = image->GetWidth();
+  CFX_Int32Array& stateCount = GetCrossCheckStateCount();
+  int32_t j = startJ;
+  while (j >= 0 && image->Get(j, centerI)) {
+    stateCount[2]++;
+    j--;
+  }
+  if (j < 0) {
+    return FXSYS_nan();
+  }
+  while (j >= 0 && !image->Get(j, centerI) && stateCount[1] <= maxCount) {
+    stateCount[1]++;
+    j--;
+  }
+  if (j < 0 || stateCount[1] > maxCount) {
+    return FXSYS_nan();
+  }
+  while (j >= 0 && image->Get(j, centerI) && stateCount[0] <= maxCount) {
+    stateCount[0]++;
+    j--;
+  }
+  if (stateCount[0] > maxCount) {
+    return FXSYS_nan();
+  }
+  j = startJ + 1;
+  while (j < maxJ && image->Get(j, centerI)) {
+    stateCount[2]++;
+    j++;
+  }
+  if (j == maxJ) {
+    return FXSYS_nan();
+  }
+  while (j < maxJ && !image->Get(j, centerI) && stateCount[3] < maxCount) {
+    stateCount[3]++;
+    j++;
+  }
+  if (j == maxJ || stateCount[3] >= maxCount) {
+    return FXSYS_nan();
+  }
+  while (j < maxJ && image->Get(j, centerI) && stateCount[4] < maxCount) {
+    stateCount[4]++;
+    j++;
+  }
+  if (stateCount[4] >= maxCount) {
+    return FXSYS_nan();
+  }
+  int32_t stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] +
+                            stateCount[3] + stateCount[4];
+  if (5 * FXSYS_abs(stateCountTotal - originalStateCountTotal) >=
+      originalStateCountTotal) {
+    return FXSYS_nan();
+  }
+  return FoundPatternCross(stateCount) ? CenterFromEnd(stateCount, j)
+                                       : FXSYS_nan();
+}
+FX_BOOL CBC_QRFinderPatternFinder::HandlePossibleCenter(
+    const CFX_Int32Array& stateCount,
+    int32_t i,
+    int32_t j) {
+  int32_t stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] +
+                            stateCount[3] + stateCount[4];
+  FX_FLOAT centerJ = CenterFromEnd(stateCount, j);
+  FX_FLOAT centerI =
+      CrossCheckVertical(i, (int32_t)centerJ, stateCount[2], stateCountTotal);
+  if (!FXSYS_isnan(centerI)) {
+    centerJ = CrossCheckHorizontal((int32_t)centerJ, (int32_t)centerI,
+                                   stateCount[2], stateCountTotal);
+    if (!FXSYS_isnan(centerJ)) {
+      FX_FLOAT estimatedModuleSize = (FX_FLOAT)stateCountTotal / 7.0f;
+      FX_BOOL found = FALSE;
+      int32_t max = m_possibleCenters.GetSize();
+      for (int32_t index = 0; index < max; index++) {
+        CBC_QRFinderPattern* center =
+            (CBC_QRFinderPattern*)(m_possibleCenters[index]);
+        if (center->AboutEquals(estimatedModuleSize, centerI, centerJ)) {
+          center->IncrementCount();
+          found = TRUE;
+          break;
+        }
+      }
+      if (!found) {
+        m_possibleCenters.Add(
+            new CBC_QRFinderPattern(centerJ, centerI, estimatedModuleSize));
+      }
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+int32_t CBC_QRFinderPatternFinder::FindRowSkip() {
+  int32_t max = m_possibleCenters.GetSize();
+  if (max <= 1) {
+    return 0;
+  }
+  FinderPattern* firstConfirmedCenter = NULL;
+  for (int32_t i = 0; i < max; i++) {
+    CBC_QRFinderPattern* center = (CBC_QRFinderPattern*)m_possibleCenters[i];
+    if (center->GetCount() >= CENTER_QUORUM) {
+      if (firstConfirmedCenter == NULL) {
+        firstConfirmedCenter = center;
+      } else {
+        m_hasSkipped = TRUE;
+        return (int32_t)((fabs(firstConfirmedCenter->GetX() - center->GetX()) -
+                          fabs(firstConfirmedCenter->GetY() - center->GetY())) /
+                         2);
+      }
+    }
+  }
+  return 0;
+}
+FX_BOOL CBC_QRFinderPatternFinder::HaveMultiplyConfirmedCenters() {
+  int32_t confirmedCount = 0;
+  FX_FLOAT totalModuleSize = 0.0f;
+  int32_t max = m_possibleCenters.GetSize();
+  int32_t i;
+  for (i = 0; i < max; i++) {
+    CBC_QRFinderPattern* pattern = (CBC_QRFinderPattern*)m_possibleCenters[i];
+    if (pattern->GetCount() >= CENTER_QUORUM) {
+      confirmedCount++;
+      totalModuleSize += pattern->GetEstimatedModuleSize();
+    }
+  }
+  if (confirmedCount < 3) {
+    return FALSE;
+  }
+  FX_FLOAT average = totalModuleSize / (FX_FLOAT)max;
+  FX_FLOAT totalDeviation = 0.0f;
+  for (i = 0; i < max; i++) {
+    CBC_QRFinderPattern* pattern = (CBC_QRFinderPattern*)m_possibleCenters[i];
+    totalDeviation += fabs(pattern->GetEstimatedModuleSize() - average);
+  }
+  return totalDeviation <= 0.05f * totalModuleSize;
+}
+inline FX_BOOL centerComparator(void* a, void* b) {
+  return ((CBC_QRFinderPattern*)b)->GetCount() <
+         ((CBC_QRFinderPattern*)a)->GetCount();
+}
+CFX_PtrArray* CBC_QRFinderPatternFinder::SelectBestpatterns(int32_t& e) {
+  int32_t startSize = m_possibleCenters.GetSize();
+  if (m_possibleCenters.GetSize() < 3) {
+    e = BCExceptionRead;
+    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+  }
+  FX_FLOAT average = 0.0f;
+  if (startSize > 3) {
+    FX_FLOAT totalModuleSize = 0.0f;
+    for (int32_t i = 0; i < startSize; i++) {
+      totalModuleSize += ((CBC_QRFinderPattern*)m_possibleCenters[i])
+                             ->GetEstimatedModuleSize();
+    }
+    average = totalModuleSize / (FX_FLOAT)startSize;
+    for (int32_t j = 0;
+         j < m_possibleCenters.GetSize() && m_possibleCenters.GetSize() > 3;
+         j++) {
+      CBC_QRFinderPattern* pattern = (CBC_QRFinderPattern*)m_possibleCenters[j];
+      if (fabs(pattern->GetEstimatedModuleSize() - average) > 0.2f * average) {
+        delete pattern;
+        m_possibleCenters.RemoveAt(j);
+        j--;
+      }
+    }
+  }
+  if (m_possibleCenters.GetSize() > 3) {
+    BC_FX_PtrArray_Sort(m_possibleCenters, centerComparator);
+  }
+  CFX_PtrArray* vec = new CFX_PtrArray();
+  vec->SetSize(3);
+  (*vec)[0] = ((CBC_QRFinderPattern*)m_possibleCenters[0])->Clone();
+  (*vec)[1] = ((CBC_QRFinderPattern*)m_possibleCenters[1])->Clone();
+  (*vec)[2] = ((CBC_QRFinderPattern*)m_possibleCenters[2])->Clone();
+  return vec;
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.h b/xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.h
new file mode 100644
index 0000000..058f65d
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRFinderPatternFinder.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 XFA_FXBARCODE_QRCODE_BC_QRFINDERPATTERNFINDER_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRFINDERPATTERNFINDER_H_
+
+#include "core/include/fxcrt/fx_basic.h"
+
+class CBC_CommonBitMatrix;
+class CBC_QRFinderPattern;
+class CBC_ResultPoint;
+class CBC_QRFinderPatternInfo;
+
+class CBC_QRFinderPatternFinder {
+ private:
+  static const int32_t CENTER_QUORUM;
+  static const int32_t MIN_SKIP;
+  static const int32_t MAX_MODULES;
+  static const int32_t INTEGER_MATH_SHIFT;
+  FX_BOOL m_hasSkipped;
+  CBC_CommonBitMatrix* m_image;
+  CFX_Int32Array m_crossCheckStateCount;
+  CFX_PtrArray m_possibleCenters;
+
+ public:
+  CBC_QRFinderPatternFinder(CBC_CommonBitMatrix* image);
+  virtual ~CBC_QRFinderPatternFinder();
+  int32_t FindRowSkip();
+  CBC_CommonBitMatrix* GetImage();
+  CBC_QRFinderPatternInfo* Find(int32_t hint, int32_t& e);
+
+  CFX_Int32Array& GetCrossCheckStateCount();
+  CFX_PtrArray* GetPossibleCenters();
+  CFX_PtrArray* SelectBestpatterns(int32_t& e);
+
+  FX_BOOL HandlePossibleCenter(const CFX_Int32Array& stateCount,
+                               int32_t i,
+                               int32_t j);
+  FX_BOOL HaveMultiplyConfirmedCenters();
+  FX_FLOAT CenterFromEnd(const CFX_Int32Array& stateCount, int32_t end);
+  FX_FLOAT CrossCheckVertical(int32_t startI,
+                              int32_t centerJ,
+                              int32_t maxCount,
+                              int32_t originalStateCountTotal);
+  FX_FLOAT CrossCheckHorizontal(int32_t startJ,
+                                int32_t CenterI,
+                                int32_t maxCOunt,
+                                int32_t originalStateCountTotal);
+  static void OrderBestPatterns(CFX_PtrArray* patterns);
+  static FX_BOOL FoundPatternCross(const CFX_Int32Array& stateCount);
+  static FX_FLOAT Distance(CBC_ResultPoint* point1, CBC_ResultPoint* point2);
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRFINDERPATTERNFINDER_H_
diff --git a/xfa/fxbarcode/qrcode/BC_QRGridSampler.cpp b/xfa/fxbarcode/qrcode/BC_QRGridSampler.cpp
new file mode 100644
index 0000000..881e74a
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRGridSampler.cpp
@@ -0,0 +1,139 @@
+// 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 "xfa/fxbarcode/qrcode/BC_QRGridSampler.h"
+
+#include <memory>
+
+#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h"
+#include "xfa/fxbarcode/common/BC_CommonPerspectiveTransform.h"
+#include "xfa/fxbarcode/utils.h"
+
+CBC_QRGridSampler CBC_QRGridSampler::m_gridSampler;
+
+CBC_QRGridSampler::CBC_QRGridSampler() {}
+CBC_QRGridSampler::~CBC_QRGridSampler() {}
+CBC_QRGridSampler& CBC_QRGridSampler::GetInstance() {
+  return m_gridSampler;
+}
+void CBC_QRGridSampler::CheckAndNudgePoints(CBC_CommonBitMatrix* image,
+                                            CFX_FloatArray* points,
+                                            int32_t& e) {
+  int32_t width = image->GetWidth();
+  int32_t height = image->GetHeight();
+  FX_BOOL nudged = TRUE;
+  int32_t offset;
+  for (offset = 0; offset < points->GetSize() && nudged; offset += 2) {
+    int32_t x = (int32_t)(*points)[offset];
+    int32_t y = (int32_t)(*points)[offset + 1];
+    if (x < -1 || x > width || y < -1 || y > height) {
+      e = BCExceptionRead;
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    }
+    nudged = FALSE;
+    if (x == -1) {
+      (*points)[offset] = 0.0f;
+      nudged = TRUE;
+    } else if (x == width) {
+      (*points)[offset] = (FX_FLOAT)(width - 1);
+      nudged = TRUE;
+    }
+    if (y == -1) {
+      (*points)[offset + 1] = 0.0f;
+      nudged = TRUE;
+    } else if (y == height) {
+      (*points)[offset + 1] = (FX_FLOAT)(height - 1);
+      nudged = TRUE;
+    }
+  }
+  nudged = TRUE;
+  for (offset = (*points).GetSize() - 2; offset >= 0 && nudged; offset -= 2) {
+    int32_t x = (int32_t)(*points)[offset];
+    int32_t y = (int32_t)(*points)[offset + 1];
+    if (x < -1 || x > width || y < -1 || y > height) {
+      e = BCExceptionRead;
+      BC_EXCEPTION_CHECK_ReturnVoid(e);
+    }
+    nudged = FALSE;
+    if (x == -1) {
+      (*points)[offset] = 0.0f;
+      nudged = TRUE;
+    } else if (x == width) {
+      (*points)[offset] = (FX_FLOAT)(width - 1);
+      nudged = TRUE;
+    }
+    if (y == -1) {
+      (*points)[offset + 1] = 0.0f;
+      nudged = TRUE;
+    } else if (y == height) {
+      (*points)[offset + 1] = (FX_FLOAT)(height - 1);
+      nudged = TRUE;
+    }
+  }
+}
+CBC_CommonBitMatrix* CBC_QRGridSampler::SampleGrid(CBC_CommonBitMatrix* image,
+                                                   int32_t dimensionX,
+                                                   int32_t dimensionY,
+                                                   FX_FLOAT p1ToX,
+                                                   FX_FLOAT p1ToY,
+                                                   FX_FLOAT p2ToX,
+                                                   FX_FLOAT p2ToY,
+                                                   FX_FLOAT p3ToX,
+                                                   FX_FLOAT p3ToY,
+                                                   FX_FLOAT p4ToX,
+                                                   FX_FLOAT p4ToY,
+                                                   FX_FLOAT p1FromX,
+                                                   FX_FLOAT p1FromY,
+                                                   FX_FLOAT p2FromX,
+                                                   FX_FLOAT p2FromY,
+                                                   FX_FLOAT p3FromX,
+                                                   FX_FLOAT p3FromY,
+                                                   FX_FLOAT p4FromX,
+                                                   FX_FLOAT p4FromY,
+                                                   int32_t& e) {
+  std::unique_ptr<CBC_CommonPerspectiveTransform> transform(
+      CBC_CommonPerspectiveTransform::QuadrilateralToQuadrilateral(
+          p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY, p1FromX,
+          p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY));
+  std::unique_ptr<CBC_CommonBitMatrix> bits(new CBC_CommonBitMatrix());
+  bits->Init(dimensionX, dimensionY);
+  CFX_FloatArray points;
+  points.SetSize(dimensionX << 1);
+  for (int32_t y = 0; y < dimensionY; y++) {
+    int32_t max = points.GetSize();
+    FX_FLOAT iValue = (FX_FLOAT)(y + 0.5f);
+    int32_t x;
+    for (x = 0; x < max; x += 2) {
+      points[x] = (FX_FLOAT)((x >> 1) + 0.5f);
+      points[x + 1] = iValue;
+    }
+    transform->TransformPoints(&points);
+    CheckAndNudgePoints(image, &points, e);
+    BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+    for (x = 0; x < max; x += 2) {
+      if (image->Get((int32_t)points[x], (int32_t)points[x + 1])) {
+        bits->Set(x >> 1, y);
+      }
+    }
+  }
+  return bits.release();
+}
diff --git a/xfa/fxbarcode/qrcode/BC_QRGridSampler.h b/xfa/fxbarcode/qrcode/BC_QRGridSampler.h
new file mode 100644
index 0000000..4e10c56
--- /dev/null
+++ b/xfa/fxbarcode/qrcode/BC_QRGridSampler.h
@@ -0,0 +1,48 @@
+// 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 XFA_FXBARCODE_QRCODE_BC_QRGRIDSAMPLER_H_
+#define XFA_FXBARCODE_QRCODE_BC_QRGRIDSAMPLER_H_
+
+#include "core/include/fxcrt/fx_basic.h"
+
+class CBC_CommonBitMatrix;
+
+class CBC_QRGridSampler {
+ private:
+  static CBC_QRGridSampler m_gridSampler;
+
+ public:
+  CBC_QRGridSampler();
+  virtual ~CBC_QRGridSampler();
+  virtual CBC_CommonBitMatrix* SampleGrid(CBC_CommonBitMatrix* image,
+                                          int32_t dimensionX,
+                                          int32_t dimensionY,
+                                          FX_FLOAT p1ToX,
+                                          FX_FLOAT p1ToY,
+                                          FX_FLOAT p2ToX,
+                                          FX_FLOAT p2ToY,
+                                          FX_FLOAT p3ToX,
+                                          FX_FLOAT p3ToY,
+                                          FX_FLOAT p4ToX,
+                                          FX_FLOAT p4ToY,
+                                          FX_FLOAT p1FromX,
+                                          FX_FLOAT p1FromY,
+                                          FX_FLOAT p2FromX,
+                                          FX_FLOAT p2FromY,
+                                          FX_FLOAT p3FromX,
+                                          FX_FLOAT p3FromY,
+                                          FX_FLOAT p4FromX,
+                                          FX_FLOAT p4FromY,
+                                          int32_t& e);
+
+  static CBC_QRGridSampler& GetInstance();
+  static void CheckAndNudgePoints(CBC_CommonBitMatrix* image,
+                                  CFX_FloatArray* points,
+                                  int32_t& e);
+};
+
+#endif  // XFA_FXBARCODE_QRCODE_BC_QRGRIDSAMPLER_H_