summaryrefslogtreecommitdiff
path: root/xfa/src/fxbarcode/qrcode
diff options
context:
space:
mode:
authorBo Xu <bo_xu@foxitsoftware.com>2015-01-09 17:27:21 -0800
committerBo Xu <bo_xu@foxitsoftware.com>2015-01-09 17:27:21 -0800
commita902979f7c6a39fbdd8e9fc1b2ce00553b655eeb (patch)
tree854a51dbf1577ee8493db769ba7c8ab07cc72140 /xfa/src/fxbarcode/qrcode
parent5f21e9ddd181fc344f8d6070351858f98a25547e (diff)
downloadpdfium-a902979f7c6a39fbdd8e9fc1b2ce00553b655eeb.tar.xz
Organize barcode codes into modules.
Previously all the files in barcode are lumped together. The naming of some files are inconsistent, leading to difficult understanding of the structure. Now files are grouped based on different barcode type like in zxing. This also matches what it looks like in other xfa folders. The file names in each folder could be further modified to be consistent. R=tsepez@chromium.org Review URL: https://codereview.chromium.org/842043002
Diffstat (limited to 'xfa/src/fxbarcode/qrcode')
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_FinderPatternInfo.cpp48
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_FinderPatternInfo.h24
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRAlignmentPattern.cpp52
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRAlignmentPattern.h24
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.cpp187
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.h32
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRBitMatrixParser.cpp185
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRBitMatrixParser.h31
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCodeReader.cpp111
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCodeReader.h35
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCodeWriter.cpp103
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCodeWriter.h28
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoder.cpp168
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoder.h55
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderBitVector.cpp141
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderBitVector.h32
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderBlockPair.cpp49
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderBlockPair.h23
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderDecoder.cpp128
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderDecoder.h29
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderECB.cpp40
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderECB.h21
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderECBlocks.cpp65
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderECBlocks.h25
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderEncoder.cpp876
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderEncoder.h60
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.cpp97
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h32
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderFormatInformation.cpp119
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderFormatInformation.h29
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderMaskUtil.cpp208
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderMaskUtil.h24
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp490
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderMatrixUtil.h50
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderMode.cpp178
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderMode.h40
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderVersion.cpp777
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRCoderVersion.h42
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRDataBlock.cpp104
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRDataBlock.h27
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRDataMask.cpp149
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRDataMask.h25
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.cpp254
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.h35
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRDetector.cpp264
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRDetector.h41
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRDetectorResult.cpp51
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRDetectorResult.h23
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRFinderPattern.cpp71
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRFinderPattern.h29
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRFinderPatternFinder.cpp451
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRFinderPatternFinder.h45
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRGridSampler.cpp128
-rw-r--r--xfa/src/fxbarcode/qrcode/BC_QRGridSampler.h33
54 files changed, 6388 insertions, 0 deletions
diff --git a/xfa/src/fxbarcode/qrcode/BC_FinderPatternInfo.cpp b/xfa/src/fxbarcode/qrcode/BC_FinderPatternInfo.cpp
new file mode 100644
index 0000000000..b3c6f3f8a3
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_FinderPatternInfo.cpp
@@ -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
+// 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 "../barcode.h"
+#include "../BC_ResultPoint.h"
+#include "BC_QRFinderPattern.h"
+#include "BC_FinderPatternInfo.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/src/fxbarcode/qrcode/BC_FinderPatternInfo.h b/xfa/src/fxbarcode/qrcode/BC_FinderPatternInfo.h
new file mode 100644
index 0000000000..bac9291947
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_FinderPatternInfo.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 _BC_FINDERPATTERNINFO_H_
+#define _BC_FINDERPATTERNINFO_H_
+class CBC_QRFinderPattern;
+class CBC_QRFinderPatternInfo;
+class CBC_QRFinderPatternInfo : public CFX_Object
+{
+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
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRAlignmentPattern.cpp b/xfa/src/fxbarcode/qrcode/BC_QRAlignmentPattern.cpp
new file mode 100644
index 0000000000..e1ee168e72
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRAlignmentPattern.cpp
@@ -0,0 +1,52 @@
+// 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 "../barcode.h"
+#include "../BC_ResultPoint.h"
+#include "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 FX_NEW CBC_QRAlignmentPattern(m_x, m_y, m_moduleSize);
+}
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRAlignmentPattern.h b/xfa/src/fxbarcode/qrcode/BC_QRAlignmentPattern.h
new file mode 100644
index 0000000000..a52687b6b7
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRAlignmentPattern.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 _BC_QRALIGNMENTPATTERN_H_
+#define _BC_QRALIGNMENTPATTERN_H_
+class CBC_CommonBitArray;
+class CBC_ResultPoint;
+class CBC_REAI013x0x1xDecoder;
+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
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.cpp b/xfa/src/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.cpp
new file mode 100644
index 0000000000..669a0fbf7e
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.cpp
@@ -0,0 +1,187 @@
+// 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 "../barcode.h"
+#include "../BC_ResultPoint.h"
+#include "../common/BC_CommonBitMatrix.h"
+#include "BC_QRAlignmentPattern.h"
+#include "BC_QRAlignmentPatternFinder.h"
+CBC_QRAlignmentPatternFinder::CBC_QRAlignmentPatternFinder(CBC_CommonBitMatrix *image,
+ FX_INT32 startX,
+ FX_INT32 startY,
+ FX_INT32 width,
+ FX_INT32 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 (FX_INT32 i = 0; i < m_possibleCenters.GetSize(); i++) {
+ delete (CBC_QRAlignmentPattern*)m_possibleCenters[i];
+ }
+ m_possibleCenters.RemoveAll();
+}
+CBC_QRAlignmentPattern *CBC_QRAlignmentPatternFinder::Find(FX_INT32 &e)
+{
+ FX_INT32 startX = m_startX;
+ FX_INT32 height = m_height;
+ FX_INT32 maxJ = startX + m_width;
+ FX_INT32 middleI = m_startY + (height >> 1);
+ CFX_Int32Array stateCount;
+ stateCount.SetSize(3);
+ for (FX_INT32 iGen = 0; iGen < height; iGen++) {
+ FX_INT32 i = middleI + ((iGen & 0x01) == 0 ? ((iGen + 1) >> 1) : -((iGen + 1) >> 1));
+ stateCount[0] = 0;
+ stateCount[1] = 0;
+ stateCount[2] = 0;
+ FX_INT32 j = startX;
+ while (j < maxJ && !m_image->Get(j, i)) {
+ j++;
+ }
+ FX_INT32 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 != NULL) {
+ 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 != NULL) {
+ 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, FX_INT32 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 (FX_INT32 i = 0; i < 3; i++) {
+ if (fabs(moduleSize - stateCount[i]) >= maxVariance) {
+ return false;
+ }
+ }
+ return TRUE;
+}
+FX_FLOAT CBC_QRAlignmentPatternFinder::CrossCheckVertical(FX_INT32 startI, FX_INT32 centerJ, FX_INT32 maxCount, FX_INT32 originalStateCountTotal)
+{
+ CBC_CommonBitMatrix *image = m_image;
+ FX_INT32 maxI = m_image->GetHeight();
+ CFX_Int32Array stateCount;
+ stateCount.Copy(m_crossCheckStateCount);
+ stateCount[0] = 0;
+ stateCount[1] = 0;
+ stateCount[2] = 0;
+ FX_INT32 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();
+ }
+ FX_INT32 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, FX_INT32 i, FX_INT32 j)
+{
+ FX_INT32 stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
+ FX_FLOAT centerJ = CenterFromEnd(stateCount, j);
+ FX_FLOAT centerI = CrossCheckVertical(i, (FX_INT32) centerJ, 2 * stateCount[1], stateCountTotal);
+ if (!FXSYS_isnan(centerI)) {
+ FX_FLOAT estimatedModuleSize = (FX_FLOAT) (stateCount[0] + stateCount[1] + stateCount[2]) / 3.0f;
+ FX_INT32 max = m_possibleCenters.GetSize();
+ for (FX_INT32 index = 0; index < max; index++) {
+ CBC_QRAlignmentPattern *center = (CBC_QRAlignmentPattern *)(m_possibleCenters[index]);
+ if (center->AboutEquals(estimatedModuleSize, centerI, centerJ)) {
+ return FX_NEW CBC_QRAlignmentPattern(centerJ, centerI, estimatedModuleSize);
+ }
+ }
+ m_possibleCenters.Add(FX_NEW CBC_QRAlignmentPattern(centerJ, centerI, estimatedModuleSize));
+ }
+ return NULL;
+}
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.h b/xfa/src/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.h
new file mode 100644
index 0000000000..5471c4e62a
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.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 _BC_QRALIGNMENTPATTERNFINDER_H_
+#define _BC_QRALIGNMENTPATTERNFINDER_H_
+class CBC_CommonBitMatrix;
+class CBC_QRAlignmentPattern;
+class CBC_QRAlignmentPatternFinder;
+class CBC_QRAlignmentPatternFinder : public CFX_Object
+{
+private:
+ CBC_CommonBitMatrix *m_image;
+ CFX_PtrArray m_possibleCenters;
+ FX_INT32 m_startX;
+ FX_INT32 m_startY;
+ FX_INT32 m_width;
+ FX_INT32 m_height;
+ FX_FLOAT m_moduleSize;
+ CFX_Int32Array m_crossCheckStateCount;
+public:
+ CBC_QRAlignmentPatternFinder(CBC_CommonBitMatrix *image, FX_INT32 startX, FX_INT32 startY, FX_INT32 width, FX_INT32 height, FX_FLOAT moduleSize);
+ virtual ~CBC_QRAlignmentPatternFinder();
+ FX_BOOL FoundPatternCross(const CFX_Int32Array &stateCount);
+ FX_FLOAT CrossCheckVertical(FX_INT32 startI, FX_INT32 startJ, FX_INT32 maxCount, FX_INT32 originalStateCountTotal);
+ CBC_QRAlignmentPattern* Find(FX_INT32 &e);
+ CBC_QRAlignmentPattern *HandlePossibleCenter(const CFX_Int32Array &stateCount, FX_INT32 i, FX_INT32 j);
+ static FX_FLOAT CenterFromEnd(const CFX_Int32Array &stateCount, FX_INT32 end);
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRBitMatrixParser.cpp b/xfa/src/fxbarcode/qrcode/BC_QRBitMatrixParser.cpp
new file mode 100644
index 0000000000..7c85c58367
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRBitMatrixParser.cpp
@@ -0,0 +1,185 @@
+// 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 "../barcode.h"
+#include "../common/BC_CommonBitMatrix.h"
+#include "BC_QRCoderVersion.h"
+#include "BC_QRCoderFormatInformation.h"
+#include "BC_QRDataMask.h"
+#include "BC_QRBitMatrixParser.h"
+CBC_QRBitMatrixParser::CBC_QRBitMatrixParser()
+{
+}
+void CBC_QRBitMatrixParser::Init(CBC_CommonBitMatrix *bitMatrix, FX_INT32 &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()
+{
+ if(m_parsedFormatInfo != NULL) {
+ delete m_parsedFormatInfo;
+ m_parsedFormatInfo = NULL;
+ }
+ m_version = NULL;
+}
+CBC_QRCoderFormatInformation* CBC_QRBitMatrixParser::ReadFormatInformation(FX_INT32 &e)
+{
+ if(m_parsedFormatInfo != NULL) {
+ return m_parsedFormatInfo;
+ }
+ FX_INT32 formatInfoBits = 0;
+ FX_INT32 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(FX_INT32 i = 5; i >= 0; i--) {
+ formatInfoBits = CopyBit(i, 8, formatInfoBits);
+ }
+ m_parsedFormatInfo = CBC_QRCoderFormatInformation::DecodeFormatInformation(formatInfoBits);
+ if(m_parsedFormatInfo != NULL) {
+ return m_parsedFormatInfo;
+ }
+ FX_INT32 dimension = m_bitMatrix->GetDimension(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ formatInfoBits = 0;
+ FX_INT32 iMin = dimension - 8;
+ for(j = dimension - 1; j >= iMin; j--) {
+ formatInfoBits = CopyBit(j, 8, formatInfoBits);
+ }
+ for(FX_INT32 k = dimension - 7; k < dimension; k++) {
+ formatInfoBits = CopyBit(8, k , formatInfoBits);
+ }
+ m_parsedFormatInfo = CBC_QRCoderFormatInformation::DecodeFormatInformation(formatInfoBits);
+ if(m_parsedFormatInfo != NULL) {
+ return m_parsedFormatInfo;
+ }
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return NULL;
+}
+CBC_QRCoderVersion* CBC_QRBitMatrixParser::ReadVersion(FX_INT32 &e)
+{
+ if(m_version != NULL) {
+ return m_version;
+ }
+ FX_INT32 dimension = m_bitMatrix->GetDimension(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 provisionVersion = (dimension - 17) >> 2;
+ if(provisionVersion <= 6) {
+ CBC_QRCoderVersion* qrv = CBC_QRCoderVersion::GetVersionForNumber(provisionVersion, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return qrv;
+ }
+ FX_INT32 versionBits = 0;
+ for (FX_INT32 i = 5; i >= 0; i--) {
+ FX_INT32 jMin = dimension - 11;
+ for (FX_INT32 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 != NULL && m_version->GetDimensionForVersion() == dimension) {
+ return m_version;
+ }
+ versionBits = 0;
+ for (FX_INT32 j = 5; j >= 0; j--) {
+ FX_INT32 iMin = dimension - 11;
+ for (FX_INT32 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 != NULL && m_version->GetDimensionForVersion() == dimension) {
+ return m_version;
+ }
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return NULL;
+}
+FX_INT32 CBC_QRBitMatrixParser::CopyBit(FX_INT32 i, FX_INT32 j, FX_INT32 versionBits)
+{
+ return m_bitMatrix->Get(j, i) ? (versionBits << 1) | 0x1 : versionBits << 1;
+}
+CFX_ByteArray* CBC_QRBitMatrixParser::ReadCodewords(FX_INT32 &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((FX_INT32)(formatInfo->GetDataMask()), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 dimension = m_bitMatrix->GetDimension(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ dataMask->UnmaskBitMatirx(m_bitMatrix, dimension);
+ CBC_CommonBitMatrix* cbm = version->BuildFunctionPattern(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_CommonBitMatrix > functionPattern(cbm);
+ FX_BOOL readingUp = TRUE;
+ CFX_ByteArray * temp = FX_NEW CFX_ByteArray;
+ temp->SetSize(version->GetTotalCodeWords());
+ CBC_AutoPtr<CFX_ByteArray> result(temp);
+ FX_INT32 resultOffset = 0;
+ FX_INT32 currentByte = 0;
+ FX_INT32 bitsRead = 0;
+ for(FX_INT32 j = dimension - 1; j > 0; j -= 2) {
+ if(j == 6) {
+ j--;
+ }
+ for(FX_INT32 count = 0; count < dimension; count++) {
+ FX_INT32 i = readingUp ? dimension - 1 - count : count;
+ for(FX_INT32 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++] = (FX_BYTE) 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/src/fxbarcode/qrcode/BC_QRBitMatrixParser.h b/xfa/src/fxbarcode/qrcode/BC_QRBitMatrixParser.h
new file mode 100644
index 0000000000..2e176f63d3
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRBitMatrixParser.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 _BC_QRABITMATRIXPARSER_H_
+#define _BC_QRABITMATRIXPARSER_H_
+class CBC_CommonBitMatrix ;
+class CBC_QRCoderVersion;
+class CBC_QRCoderFormatInformation;
+class CBC_QRDataMask;
+class CBC_QRBitMatrixParser;
+class CBC_QRBitMatrixParser : public CFX_Object
+{
+private:
+ CBC_CommonBitMatrix *m_bitMatrix;
+ CBC_CommonBitMatrix *m_tempBitMatrix;
+ CBC_QRCoderVersion *m_version;
+ CBC_QRCoderFormatInformation *m_parsedFormatInfo;
+ FX_INT32 m_dimension;
+public:
+ CBC_QRBitMatrixParser();
+ virtual ~CBC_QRBitMatrixParser();
+ CBC_QRCoderFormatInformation *ReadFormatInformation(FX_INT32 &e);
+ CBC_QRCoderVersion *ReadVersion(FX_INT32 &e);
+ FX_INT32 CopyBit(FX_INT32 i, FX_INT32 j, FX_INT32 versionBits);
+ CFX_ByteArray *ReadCodewords(FX_INT32 &e);
+ virtual void Init(CBC_CommonBitMatrix *bitMatrix, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCodeReader.cpp b/xfa/src/fxbarcode/qrcode/BC_QRCodeReader.cpp
new file mode 100644
index 0000000000..f12c4e0ad3
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCodeReader.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 "../barcode.h"
+#include "../BC_Reader.h"
+#include "../BC_LuminanceSource.h"
+#include "../BC_BufferedImageLuminanceSource.h"
+#include "../BC_Binarizer.h"
+#include "../BC_BinaryBitmap.h"
+#include "../BC_ResultPoint.h"
+#include "../common/BC_GlobalHistogramBinarizer.h"
+#include "../common/BC_CommonDecoderResult.h"
+#include "../common/reedsolomon/BC_ReedSolomonGF256.h"
+#include "BC_QRCodeReader.h"
+#include "BC_QRCodeReader.h"
+#include "BC_QRCoderMode.h"
+#include "BC_QRCoderDecoder.h"
+#include "BC_QRDetector.h"
+#include "BC_QRDetectorResult.h"
+#include "BC_QRCoderErrorCorrectionLevel.h"
+#include "BC_QRDataMask.h"
+#include "BC_QRCodeReader.h"
+#include "BC_QRCoderVersion.h"
+CBC_QRCodeReader::CBC_QRCodeReader(): m_decoder(NULL)
+{
+}
+void CBC_QRCodeReader::Init()
+{
+ m_decoder = FX_NEW CBC_QRCoderDecoder;
+ m_decoder->Init();
+}
+CBC_QRCodeReader::~CBC_QRCodeReader()
+{
+ if(m_decoder != NULL) {
+ delete m_decoder;
+ }
+ m_decoder = NULL;
+}
+CFX_ByteString CBC_QRCodeReader::Decode(CBC_BinaryBitmap *image, FX_INT32 hints, FX_INT32 &e)
+{
+ CBC_CommonBitMatrix *matrix = image->GetMatrix(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ CBC_QRDetector detector(matrix);
+ CBC_QRDetectorResult* qdr = detector.Detect(hints, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ CBC_AutoPtr<CBC_QRDetectorResult> detectorResult(qdr);
+ CBC_CommonDecoderResult* qdr2 = m_decoder->Decode(detectorResult->GetBits(), 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ CBC_AutoPtr<CBC_CommonDecoderResult> decodeResult(qdr2);
+ return (decodeResult->GetText());
+}
+CFX_ByteString CBC_QRCodeReader::Decode(const CFX_WideString &filename, FX_INT32 hints, FX_INT32 byteModeDecode, FX_INT32 &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, FX_INT32 hints, FX_INT32 byteModeDecode, FX_INT32 &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, FX_INT32 &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/src/fxbarcode/qrcode/BC_QRCodeReader.h b/xfa/src/fxbarcode/qrcode/BC_QRCodeReader.h
new file mode 100644
index 0000000000..71a1ad3dd6
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCodeReader.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 _BC_QRCODEREADER_H_
+#define _BC_QRCODEREADER_H_
+class CBC_QRDetector;
+class CBC_BinaryBitmap;
+class CBC_QRCoderDecoder;
+class CBC_ResultPoint;
+class CBC_ReedSolomonGF256;
+class CBC_QRCoderVersion;
+class CBC_QRDetector;
+class CBC_QRDetectorResult;
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRCoderMode;
+class CBC_QRDataMask;
+class CBC_QRCodeReader;
+class CBC_QRCodeReader : public CBC_Reader
+{
+private:
+ CBC_QRCoderDecoder *m_decoder;
+public:
+ CBC_QRCodeReader();
+ virtual ~CBC_QRCodeReader();
+ CFX_ByteString Decode(CFX_DIBitmap *pBitmap, FX_INT32 hints, FX_INT32 byteModeDecode, FX_INT32 &e);
+ CFX_ByteString Decode(const CFX_WideString &filename, FX_INT32 hints, FX_INT32 byteModeDecode, FX_INT32 &e);
+ static void ReleaseAll();
+ CFX_ByteString Decode(CBC_BinaryBitmap *image, FX_INT32 hints, FX_INT32 &e);
+ CFX_ByteString Decode(CBC_BinaryBitmap *image, FX_INT32 &e);
+ virtual void Init();
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCodeWriter.cpp b/xfa/src/fxbarcode/qrcode/BC_QRCodeWriter.cpp
new file mode 100644
index 0000000000..ccc0220d6c
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCodeWriter.cpp
@@ -0,0 +1,103 @@
+// 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 "../barcode.h"
+#include "../BC_TwoDimWriter.h"
+#include "../BC_Reader.h"
+#include "../common/BC_CommonByteMatrix.h"
+#include "BC_QRCodeWriter.h"
+#include "BC_QRCoderEncoder.h"
+#include "BC_QRCoder.h"
+#include "BC_QRCodeReader.h"
+#include "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(FX_INT32 version)
+{
+ if (version < 0 || version > 40) {
+ return FALSE;
+ }
+ m_iVersion = version;
+ return TRUE;
+}
+FX_BOOL CBC_QRCodeWriter::SetErrorCorrectionLevel(FX_INT32 level)
+{
+ if (level < 0 || level > 3) {
+ return FALSE;
+ }
+ m_iCorrectLevel = level;
+ return TRUE;
+}
+FX_BYTE* CBC_QRCodeWriter::Encode(const CFX_WideString& contents, FX_INT32 ecLevel, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &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();
+ FX_BYTE* result = FX_Alloc(FX_BYTE, outWidth * outWidth);
+ FXSYS_memcpy32(result, qr.GetMatrix()->GetArray(), outWidth * outHeight);
+ return result;
+}
+FX_BYTE *CBC_QRCodeWriter::Encode(const CFX_ByteString& contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e)
+{
+ return NULL;
+}
+FX_BYTE* CBC_QRCodeWriter::Encode(const CFX_ByteString& contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)
+{
+ return NULL;
+}
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCodeWriter.h b/xfa/src/fxbarcode/qrcode/BC_QRCodeWriter.h
new file mode 100644
index 0000000000..bf0ca71996
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCodeWriter.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 _BC_QRCODERWRITER_H_
+#define _BC_QRCODERWRITER_H_
+#include "../BC_TwoDimWriter.h"
+class CBC_TwoDimWriter;
+class CBC_MultiBarCodes;
+class CBC_QRCoderWriter;
+class CBC_QRCodeWriter : public CBC_TwoDimWriter
+{
+public:
+ CBC_QRCodeWriter();
+ virtual ~CBC_QRCodeWriter();
+ FX_BYTE* Encode(const CFX_WideString& contents, FX_INT32 ecLevel, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e);
+ FX_BYTE* Encode(const CFX_ByteString& contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e);
+ FX_BYTE* Encode(const CFX_ByteString& contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e);
+ FX_BOOL SetVersion(FX_INT32 version);
+ FX_BOOL SetErrorCorrectionLevel(FX_INT32 level);
+ static void ReleaseAll();
+private:
+
+ FX_INT32 m_iVersion;
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoder.cpp b/xfa/src/fxbarcode/qrcode/BC_QRCoder.cpp
new file mode 100644
index 0000000000..f650f83b48
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoder.cpp
@@ -0,0 +1,168 @@
+// 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 "../barcode.h"
+#include "../common/BC_CommonByteMatrix.h"
+#include "BC_QRCoderErrorCorrectionLevel.h"
+#include "BC_QRCoderMode.h"
+#include "BC_QRCoder.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()
+{
+ if(m_matrix != NULL) {
+ delete m_matrix;
+ m_matrix = NULL;
+ }
+ 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;
+}
+CBC_QRCoderMode* CBC_QRCoder::GetMode()
+{
+ return m_mode;
+}
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoder::GetECLevel()
+{
+ return m_ecLevel;
+}
+FX_INT32 CBC_QRCoder::GetVersion()
+{
+ return m_version;
+}
+FX_INT32 CBC_QRCoder::GetMatrixWidth()
+{
+ return m_matrixWidth;
+}
+FX_INT32 CBC_QRCoder::GetMaskPattern()
+{
+ return m_maskPattern;
+}
+FX_INT32 CBC_QRCoder::GetNumTotalBytes()
+{
+ return m_numTotalBytes;
+}
+FX_INT32 CBC_QRCoder::GetNumDataBytes()
+{
+ return m_numDataBytes;
+}
+FX_INT32 CBC_QRCoder::GetNumECBytes()
+{
+ return m_numECBytes;
+}
+FX_INT32 CBC_QRCoder::GetNumRSBlocks()
+{
+ return m_numRSBlocks;
+}
+CBC_CommonByteMatrix* CBC_QRCoder::GetMatrix()
+{
+ return m_matrix;
+}
+FX_INT32 CBC_QRCoder::At(FX_INT32 x, FX_INT32 y, FX_INT32 &e)
+{
+ FX_INT32 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 != 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 &&
+ IsValidMaskPattern(m_maskPattern) &&
+ m_numTotalBytes == m_numDataBytes + m_numECBytes &&
+ m_matrix != NULL &&
+ 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(FX_INT32 version)
+{
+ m_version = version;
+}
+void CBC_QRCoder::SetMatrixWidth(FX_INT32 width)
+{
+ m_matrixWidth = width;
+}
+void CBC_QRCoder::SetMaskPattern(FX_INT32 pattern)
+{
+ m_maskPattern = pattern;
+}
+void CBC_QRCoder::SetNumDataBytes(FX_INT32 bytes)
+{
+ m_numDataBytes = bytes;
+}
+void CBC_QRCoder::SetNumTotalBytes(FX_INT32 value)
+{
+ m_numTotalBytes = value;
+}
+void CBC_QRCoder::SetNumRSBlocks(FX_INT32 block)
+{
+ m_numRSBlocks = block;
+}
+void CBC_QRCoder::SetNumECBytes(FX_INT32 value)
+{
+ m_numECBytes = value;
+}
+FX_BOOL CBC_QRCoder::IsValidMaskPattern(FX_INT32 maskPattern)
+{
+ return maskPattern >= 0 && maskPattern < NUM_MASK_PATTERNS;
+}
+void CBC_QRCoder::SetMatrix(CBC_CommonByteMatrix* value)
+{
+ m_matrix = value;
+}
+const FX_INT32 CBC_QRCoder::NUM_MASK_PATTERNS = 8;
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoder.h b/xfa/src/fxbarcode/qrcode/BC_QRCoder.h
new file mode 100644
index 0000000000..89ce140fbd
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoder.h
@@ -0,0 +1,55 @@
+// 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 _BC_QRCODER_H_
+#define _BC_QRCODER_H_
+class CBC_QRCoderErrorCorrectionLevel ;
+class CBC_QRCoderMode;
+class CBC_CommonByteMatrix;
+class CBC_QRCoder;
+class CBC_QRCoder : public CFX_Object
+{
+private:
+ CBC_QRCoderMode* m_mode;
+ CBC_QRCoderErrorCorrectionLevel* m_ecLevel;
+ FX_INT32 m_version;
+ FX_INT32 m_matrixWidth;
+ FX_INT32 m_maskPattern;
+ FX_INT32 m_numTotalBytes;
+ FX_INT32 m_numDataBytes;
+ FX_INT32 m_numECBytes;
+ FX_INT32 m_numRSBlocks;
+ CBC_CommonByteMatrix* m_matrix;
+public:
+ const static FX_INT32 NUM_MASK_PATTERNS;
+ CBC_QRCoder();
+ virtual ~CBC_QRCoder();
+ CBC_QRCoderMode* GetMode();
+ CBC_QRCoderErrorCorrectionLevel* GetECLevel();
+ FX_INT32 GetVersion();
+ FX_INT32 GetMatrixWidth();
+ FX_INT32 GetMaskPattern();
+ FX_INT32 GetNumTotalBytes();
+ FX_INT32 GetNumDataBytes();
+ FX_INT32 GetNumECBytes();
+ FX_INT32 GetNumRSBlocks();
+ CBC_CommonByteMatrix* GetMatrix();
+ FX_INT32 At(FX_INT32 x, FX_INT32 y, FX_INT32 &e);
+ FX_BOOL IsValid();
+
+ void SetMode(CBC_QRCoderMode* value);
+ void SetECLevel(CBC_QRCoderErrorCorrectionLevel* ecLevel);
+ void SetVersion(FX_INT32 version);
+ void SetMatrixWidth(FX_INT32 width);
+ void SetMaskPattern(FX_INT32 pattern);
+ void SetNumDataBytes(FX_INT32 bytes);
+ void SetNumTotalBytes(FX_INT32 value);
+ void SetNumECBytes(FX_INT32 value);
+ void SetNumRSBlocks(FX_INT32 block);
+ void SetMatrix(CBC_CommonByteMatrix* value);
+ static FX_BOOL IsValidMaskPattern(FX_INT32 maskPattern);
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderBitVector.cpp b/xfa/src/fxbarcode/qrcode/BC_QRCoderBitVector.cpp
new file mode 100644
index 0000000000..b7a0a1c3a7
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderBitVector.cpp
@@ -0,0 +1,141 @@
+// 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 "../barcode.h"
+#include "BC_QRCoderBitVector.h"
+CBC_QRCoderBitVector::CBC_QRCoderBitVector()
+{
+ m_sizeInBits = 0;
+ m_size = 32;
+}
+void CBC_QRCoderBitVector::Init()
+{
+ m_array = FX_Alloc(FX_BYTE, m_size);
+}
+CBC_QRCoderBitVector::~CBC_QRCoderBitVector()
+{
+ if(m_array != NULL) {
+ FX_Free(m_array);
+ }
+ m_size = 0;
+ m_sizeInBits = 0;
+}
+void CBC_QRCoderBitVector::Clear()
+{
+ if(m_array != NULL) {
+ FX_Free(m_array);
+ m_array = NULL;
+ }
+ m_sizeInBits = 0;
+ m_size = 32;
+ m_array = FX_Alloc(FX_BYTE, m_size);
+}
+FX_INT32 CBC_QRCoderBitVector::At(FX_INT32 index, FX_INT32 &e)
+{
+ if(index < 0 || index >= m_sizeInBits) {
+ e = BCExceptionBadIndexException;
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ }
+ FX_INT32 value = m_array[index >> 3] & 0xff;
+ return (value >> (7 - (index & 0x7))) & 1;
+}
+FX_INT32 CBC_QRCoderBitVector::sizeInBytes()
+{
+ return (m_sizeInBits + 7) >> 3;
+}
+FX_INT32 CBC_QRCoderBitVector::Size()
+{
+ return m_sizeInBits;
+}
+void CBC_QRCoderBitVector::AppendBit(FX_INT32 bit, FX_INT32 &e)
+{
+ if(!(bit == 0 || bit == 1)) {
+ e = BCExceptionBadValueException;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 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(FX_INT32 value, FX_INT32 numBits, FX_INT32 &e)
+{
+ if (numBits < 0 || numBits > 32) {
+ e = BCExceptionBadNumBitsException;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 numBitsLeft = numBits;
+ while (numBitsLeft > 0) {
+ if ((m_sizeInBits & 0x7) == 0 && numBitsLeft >= 8) {
+ FX_INT32 newByte = (value >> (numBitsLeft - 8)) & 0xff;
+ AppendByte(newByte);
+ numBitsLeft -= 8;
+ } else {
+ FX_INT32 bit = (value >> (numBitsLeft - 1)) & 1;
+ AppendBit(bit, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ --numBitsLeft;
+ }
+ }
+}
+void CBC_QRCoderBitVector::AppendBitVector(CBC_QRCoderBitVector *bits, FX_INT32 &e)
+{
+ FX_INT32 size = bits->Size();
+ for(FX_INT32 i = 0; i < size; i++) {
+ FX_INT32 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, FX_INT32 &e)
+{
+ if(m_sizeInBits != other->Size()) {
+ e = BCExceptioncanNotOperatexorOperator;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 sizeInBytes = (m_sizeInBits + 7) >> 3;
+ for(FX_INT32 i = 0; i < sizeInBytes; ++i) {
+ m_array[i] ^= (other->GetArray())[i];
+ }
+}
+FX_BYTE* CBC_QRCoderBitVector::GetArray()
+{
+ return m_array;
+}
+void CBC_QRCoderBitVector::AppendByte(FX_INT32 value)
+{
+ if((m_sizeInBits >> 3) == m_size) {
+ FX_BYTE* newArray = FX_Alloc(FX_BYTE, m_size << 1);
+ FXSYS_memcpy32(newArray, m_array, m_size);
+ if(m_array != NULL) {
+ FX_Free(m_array);
+ }
+ m_array = newArray;
+ m_size = m_size << 1;
+ }
+ m_array[m_sizeInBits >> 3] = (FX_BYTE) value;
+ m_sizeInBits += 8;
+}
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderBitVector.h b/xfa/src/fxbarcode/qrcode/BC_QRCoderBitVector.h
new file mode 100644
index 0000000000..6e9abba6c9
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderBitVector.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 _BC_QRECODERBITVECTOR_H_
+#define _BC_QRECODERBITVECTOR_H_
+class CBC_QRCoderBitVector;
+class CBC_QRCoderBitVector : public CFX_Object
+{
+private:
+ FX_INT32 m_sizeInBits;
+ FX_BYTE *m_array;
+ FX_INT32 m_size;
+
+ void AppendByte(FX_INT32 value);
+public:
+ CBC_QRCoderBitVector();
+ virtual ~CBC_QRCoderBitVector();
+ FX_INT32 At(FX_INT32 index, FX_INT32 &e);
+ FX_INT32 Size();
+ FX_INT32 sizeInBytes();
+ void AppendBit(FX_INT32 bit, FX_INT32 &e);
+ void AppendBits(FX_INT32 value, FX_INT32 numBits, FX_INT32 &e);
+ void AppendBitVector(CBC_QRCoderBitVector *bits, FX_INT32 &e);
+ void XOR(CBC_QRCoderBitVector *other, FX_INT32 &e);
+ FX_BYTE* GetArray();
+ void Clear();
+ virtual void Init();
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderBlockPair.cpp b/xfa/src/fxbarcode/qrcode/BC_QRCoderBlockPair.cpp
new file mode 100644
index 0000000000..da7e8a509e
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderBlockPair.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 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 "../barcode.h"
+#include "../common/BC_CommonByteArray.h"
+#include "BC_QRCoderBlockPair.h"
+CBC_QRCoderBlockPair::CBC_QRCoderBlockPair(CBC_CommonByteArray* data, CBC_CommonByteArray* errorCorrection)
+{
+ m_dataBytes = data;
+ m_errorCorrectionBytes = errorCorrection;
+}
+CBC_QRCoderBlockPair::~CBC_QRCoderBlockPair()
+{
+ if(m_dataBytes != NULL) {
+ delete m_dataBytes;
+ m_dataBytes = NULL;
+ }
+ if(m_errorCorrectionBytes != NULL) {
+ delete m_errorCorrectionBytes;
+ m_errorCorrectionBytes = NULL;
+ }
+}
+CBC_CommonByteArray* CBC_QRCoderBlockPair::GetDataBytes()
+{
+ return m_dataBytes;
+}
+CBC_CommonByteArray* CBC_QRCoderBlockPair::GetErrorCorrectionBytes()
+{
+ return m_errorCorrectionBytes;
+}
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderBlockPair.h b/xfa/src/fxbarcode/qrcode/BC_QRCoderBlockPair.h
new file mode 100644
index 0000000000..234ac1a776
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderBlockPair.h
@@ -0,0 +1,23 @@
+// 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 _BC_QRCODERBLOCKPAIR_H_
+#define _BC_QRCODERBLOCKPAIR_H_
+class CBC_CommonByteArray;
+class CBC_QRCoderBlockPair;
+class CBC_QRCoderBlockPair : public CFX_Object
+{
+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
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderDecoder.cpp b/xfa/src/fxbarcode/qrcode/BC_QRCoderDecoder.cpp
new file mode 100644
index 0000000000..6f16db6ad8
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderDecoder.cpp
@@ -0,0 +1,128 @@
+// 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 "../barcode.h"
+#include "../common/BC_CommonBitMatrix.h"
+#include "../common/BC_CommonDecoderResult.h"
+#include "../common/reedsolomon/BC_ReedSolomonDecoder.h"
+#include "../common/reedsolomon/BC_ReedSolomonGF256.h"
+#include "BC_QRBitMatrixParser.h"
+#include "BC_QRDataBlock.h"
+#include "BC_QRDecodedBitStreamParser.h"
+#include "BC_QRCoderVersion.h"
+#include "BC_QRCoderFormatInformation.h"
+#include "BC_QRCoderDecoder.h"
+CBC_QRCoderDecoder::CBC_QRCoderDecoder()
+{
+ m_rsDecoder = NULL;
+}
+
+void CBC_QRCoderDecoder::Init()
+{
+ m_rsDecoder = FX_NEW CBC_ReedSolomonDecoder(CBC_ReedSolomonGF256::QRCodeFild);
+}
+CBC_QRCoderDecoder::~CBC_QRCoderDecoder()
+{
+ if(m_rsDecoder != NULL) {
+ delete m_rsDecoder;
+ }
+ m_rsDecoder = NULL;
+}
+CBC_CommonDecoderResult* CBC_QRCoderDecoder::Decode(FX_BOOL* image, FX_INT32 width, FX_INT32 height, FX_INT32 &e)
+{
+ CBC_CommonBitMatrix bits;
+ bits.Init(width);
+ for(FX_INT32 i = 0; i < width; i++) {
+ for(FX_INT32 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, FX_INT32 byteModeDecode, FX_INT32 &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();
+ CFX_ByteArray* ba = parser.ReadCodewords(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CFX_ByteArray > codewords(ba);
+ CFX_PtrArray *dataBlocks = CBC_QRDataBlock::GetDataBlocks(codewords.get(), version, ecLevel, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 totalBytes = 0;
+ for (FX_INT32 i = 0; i < dataBlocks->GetSize(); i++) {
+ totalBytes += ((CBC_QRDataBlock*) ((*dataBlocks)[i]))->GetNumDataCodewords();
+ }
+ CFX_ByteArray resultBytes;
+ FX_INT32 resultOffset = 0;
+ for (FX_INT32 j = 0; j < dataBlocks->GetSize(); j++) {
+ CBC_QRDataBlock *dataBlock = (CBC_QRDataBlock *)((*dataBlocks)[j]);
+ CFX_ByteArray* codewordBytes = dataBlock->GetCodewords();
+ FX_INT32 numDataCodewords = dataBlock->GetNumDataCodewords();
+ CorrectErrors(codewordBytes, numDataCodewords, e);
+ if (e != BCExceptionNO) {
+ for(FX_INT32 k = 0; k < dataBlocks->GetSize(); k++) {
+ delete (CBC_QRDataBlock*)(*dataBlocks)[k];
+ }
+ dataBlocks->RemoveAll();
+ delete dataBlocks;
+ dataBlocks = NULL;
+ return NULL;
+ }
+ for(FX_INT32 i = 0; i < numDataCodewords; i++) {
+ resultBytes.Add((*codewordBytes)[i]);
+ }
+ }
+ for(FX_INT32 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, FX_INT32 numDataCodewords, FX_INT32 &e)
+{
+ FX_INT32 numCodewords = codewordBytes->GetSize();
+ CFX_Int32Array codewordsInts;
+ codewordsInts.SetSize(numCodewords);
+ for(FX_INT32 i = 0; i < numCodewords; i++) {
+ codewordsInts[i] = (FX_INT32)((*codewordBytes)[i] & 0xff);
+ }
+ FX_INT32 numECCodewords = codewordBytes->GetSize() - numDataCodewords;
+ m_rsDecoder->Decode(&codewordsInts, numECCodewords, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ for(FX_INT32 k = 0; k < numDataCodewords; k++) {
+ (*codewordBytes)[k] = (FX_BYTE) codewordsInts[k];
+ }
+}
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderDecoder.h b/xfa/src/fxbarcode/qrcode/BC_QRCoderDecoder.h
new file mode 100644
index 0000000000..355af78180
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderDecoder.h
@@ -0,0 +1,29 @@
+// 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 _BC_QRCODERDECODER_H_
+#define _BC_QRCODERDECODER_H_
+class CBC_CommonBitMatrix;
+class CBC_ReedSolomonDecoder;
+class CBC_CommonDecoderResult;
+class CBC_QRBitMatrixParser;
+class CBC_QRCoderVersion;
+class CBC_QRDataBlock;
+class CBC_QRCoderDecoder;
+class CBC_QRCoderDecoder : public CFX_Object
+{
+private:
+ CBC_ReedSolomonDecoder *m_rsDecoder;
+public:
+ CBC_QRCoderDecoder();
+ virtual ~CBC_QRCoderDecoder();
+
+ CBC_CommonDecoderResult* Decode(FX_BOOL* image, FX_INT32 width, FX_INT32 height, FX_INT32 &e);
+ CBC_CommonDecoderResult* Decode(CBC_CommonBitMatrix* bits, FX_INT32 byteModeDecode, FX_INT32 &e);
+ void CorrectErrors(CFX_ByteArray* codewordBytes, FX_INT32 numDataCodewords, FX_INT32 &e);
+ virtual void Init();
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderECB.cpp b/xfa/src/fxbarcode/qrcode/BC_QRCoderECB.cpp
new file mode 100644
index 0000000000..a475cecb37
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderECB.cpp
@@ -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
+// 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 "../barcode.h"
+#include "BC_QRCoderECB.h"
+CBC_QRCoderECB::CBC_QRCoderECB(FX_INT32 count, FX_INT32 dataCodeWords)
+{
+ m_dataCodeWords = dataCodeWords;
+ m_count = count;
+}
+CBC_QRCoderECB::~CBC_QRCoderECB()
+{
+}
+FX_INT32 CBC_QRCoderECB::GetCount()
+{
+ return m_count;
+}
+FX_INT32 CBC_QRCoderECB::GetDataCodeWords()
+{
+ return m_dataCodeWords;
+}
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderECB.h b/xfa/src/fxbarcode/qrcode/BC_QRCoderECB.h
new file mode 100644
index 0000000000..c6494b75cd
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderECB.h
@@ -0,0 +1,21 @@
+// 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 _BC_QRCODERECB_H_
+#define _BC_QRCODERECB_H_
+class CBC_QRCoderECB;
+class CBC_QRCoderECB : public CFX_Object
+{
+private:
+ FX_INT32 m_count;
+ FX_INT32 m_dataCodeWords;
+public:
+ CBC_QRCoderECB(FX_INT32 count, FX_INT32 dataCodeWords);
+ virtual ~CBC_QRCoderECB();
+ FX_INT32 GetCount();
+ FX_INT32 GetDataCodeWords();
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderECBlocks.cpp b/xfa/src/fxbarcode/qrcode/BC_QRCoderECBlocks.cpp
new file mode 100644
index 0000000000..22485fe733
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderECBlocks.cpp
@@ -0,0 +1,65 @@
+// 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 "../barcode.h"
+#include "BC_QRCoderECB.h"
+#include "BC_QRCoderECBlocks.h"
+CBC_QRCoderECBlocks::CBC_QRCoderECBlocks(FX_INT32 ecCodeWordsPerBlock, CBC_QRCoderECB* ecBlocks)
+{
+ m_ecCodeWordsPerBlock = ecCodeWordsPerBlock;
+ m_ecBlocks.Add(ecBlocks);
+}
+CBC_QRCoderECBlocks::CBC_QRCoderECBlocks(FX_INT32 ecCodeWordsPerBlock,
+ CBC_QRCoderECB* ecBlocks1,
+ CBC_QRCoderECB* ecBlocks2)
+{
+ m_ecCodeWordsPerBlock = ecCodeWordsPerBlock;
+ m_ecBlocks.Add(ecBlocks1);
+ m_ecBlocks.Add(ecBlocks2);
+}
+CBC_QRCoderECBlocks::~CBC_QRCoderECBlocks()
+{
+ for (FX_INT32 i = 0 ; i < m_ecBlocks.GetSize(); i++) {
+ delete ( (CBC_QRCoderECB*)(m_ecBlocks[i]) ) ;
+ }
+ m_ecBlocks.RemoveAll();
+}
+FX_INT32 CBC_QRCoderECBlocks::GetECCodeWordsPerBlock()
+{
+ return m_ecCodeWordsPerBlock;
+}
+FX_INT32 CBC_QRCoderECBlocks::GetNumBlocks()
+{
+ FX_INT32 total = 0;
+ for(FX_INT32 i = 0; i < m_ecBlocks.GetSize(); i++) {
+ total += ( (CBC_QRCoderECB*)(m_ecBlocks[i]) )->GetCount();
+ }
+ return total;
+}
+FX_INT32 CBC_QRCoderECBlocks::GetTotalECCodeWords()
+{
+ return m_ecCodeWordsPerBlock * GetNumBlocks();
+}
+CFX_PtrArray* CBC_QRCoderECBlocks::GetECBlocks()
+{
+ return &m_ecBlocks;
+}
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderECBlocks.h b/xfa/src/fxbarcode/qrcode/BC_QRCoderECBlocks.h
new file mode 100644
index 0000000000..385837510a
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderECBlocks.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 _BC_QRCODERECBLOCKS_H_
+#define _BC_QRCODERECBLOCKS_H_
+class CBC_QRCoderECB;
+class CBC_QRCoderECBlocks;
+class CBC_QRCoderECBlocks : public CFX_Object
+{
+private:
+ FX_INT32 m_ecCodeWordsPerBlock;
+ CFX_PtrArray m_ecBlocks;
+public:
+ CBC_QRCoderECBlocks(FX_INT32 ecCodeWordsPerBlock, CBC_QRCoderECB* ecBlocks);
+ CBC_QRCoderECBlocks(FX_INT32 ecCodeWordsPerBlock, CBC_QRCoderECB* ecBlocks1, CBC_QRCoderECB* ecBlocks2);
+ virtual ~CBC_QRCoderECBlocks();
+ FX_INT32 GetECCodeWordsPerBlock();
+ FX_INT32 GetNumBlocks();
+ FX_INT32 GetTotalECCodeWords();
+ CFX_PtrArray* GetECBlocks();
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderEncoder.cpp b/xfa/src/fxbarcode/qrcode/BC_QRCoderEncoder.cpp
new file mode 100644
index 0000000000..e072dc337e
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderEncoder.cpp
@@ -0,0 +1,876 @@
+// 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 "../barcode.h"
+#include "../BC_UtilCodingConvert.h"
+#include "../common/BC_CommonByteArray.h"
+#include "../common/BC_CommonByteMatrix.h"
+#include "../common/reedsolomon/BC_ReedSolomon.h"
+#include "../common/reedsolomon/BC_ReedSolomonGF256.h"
+#include "BC_QRCoder.h"
+#include "BC_QRCoderEncoder.h"
+#include "BC_QRCoderMode.h"
+#include "BC_QRCoderEncoder.h"
+#include "BC_QRCoderECBlocks.h"
+#include "BC_QRCoderVersion.h"
+#include "BC_QRCoderBlockPair.h"
+#include "BC_QRCoderMaskUtil.h"
+#include "BC_QRCoderMatrixUtil.h"
+#include "BC_QRCoderBitVector.h"
+const FX_INT32 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 CFX_Object
+{
+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, FX_INT32 &e, FX_INT32 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, FX_INT32 &e)
+{
+ for(FX_INT32 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)
+{
+ FX_INT32 index = 0, flag = 0;
+ while((((FX_BYTE)content[index] >= 0xA1 && (FX_BYTE)content[index] <= 0xAA) ||
+ ((FX_BYTE)content[index] >= 0xB0 && (FX_BYTE)content[index] <= 0xFA)) && (index < content.GetLength())) {
+ index += 2;
+ }
+ if(index != flag) {
+ result.Add(FX_NEW Make_Pair(CBC_QRCoderMode::sGBK, content.Mid(flag, index - flag)));
+ }
+ flag = index;
+ if(index >= content.GetLength()) {
+ return;
+ }
+ while(GetAlphaNumericCode((FX_BYTE)content[index]) == -1
+ && !(((FX_BYTE)content[index] >= 0xA1 && (FX_BYTE)content[index] <= 0xAA) ||
+ ((FX_BYTE)content[index] >= 0xB0 && (FX_BYTE)content[index] <= 0xFA))
+ && (index < content.GetLength())) {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+ if(IsDBCSLeadByte((FX_BYTE)content[index]))
+#else
+ if((FX_BYTE)content[index] > 127)
+#endif
+ {
+ index += 2;
+ } else {
+ index++;
+ }
+ }
+ if(index != flag) {
+ result.Add(FX_NEW Make_Pair(CBC_QRCoderMode::sBYTE, content.Mid(flag, index - flag)));
+ }
+ flag = index;
+ if(index >= content.GetLength()) {
+ return;
+ }
+ while(FXSYS_Isdigit((FX_BYTE)content[index]) && (index < content.GetLength())) {
+ index++;
+ }
+ if(index != flag) {
+ result.Add(FX_NEW Make_Pair(CBC_QRCoderMode::sNUMERIC, content.Mid(flag, index - flag)));
+ }
+ flag = index;
+ if(index >= content.GetLength()) {
+ return;
+ }
+ while(GetAlphaNumericCode((FX_BYTE)content[index]) != -1 && (index < content.GetLength())) {
+ index++;
+ }
+ if(index != flag) {
+ result.Add(FX_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);
+}
+FX_INT32 CBC_QRCoderEncoder::GetSpanByVersion(CBC_QRCoderMode *modeFirst, CBC_QRCoderMode *modeSecond, FX_INT32 versionNum, FX_INT32 &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, FX_INT32 versionNum, FX_INT32 &e)
+{
+ Make_Pair *first = NULL;
+ Make_Pair *second = NULL;
+ size_t mergeNum = 0;
+ FX_INT32 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) {
+ FX_INT32 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) {
+ FX_INT32 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(FX_INT32 numInputBytes, FX_INT32 versionNumber,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel, CBC_QRCoderMode* mode, CBC_QRCoder* qrCode, FX_INT32 &e)
+{
+ qrCode->SetECLevel(ecLevel);
+ qrCode->SetMode(mode);
+ CBC_QRCoderVersion* version = CBC_QRCoderVersion::GetVersionForNumber(versionNumber, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 numBytes = version->GetTotalCodeWords();
+ CBC_QRCoderECBlocks* ecBlocks = version->GetECBlocksForLevel(ecLevel);
+ FX_INT32 numEcBytes = ecBlocks->GetTotalECCodeWords();
+ FX_INT32 numRSBlocks = ecBlocks->GetNumBlocks();
+ FX_INT32 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, FX_INT32 versionSpecify, FX_INT32 &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(FX_INT32 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(FX_INT32 y = 0; y < splitResult.GetSize(); y++) {
+ delete (Make_Pair*)splitResult[y];
+ }
+ splitResult.RemoveAll();
+ return;
+ }
+ }
+ FX_INT32 numInputBytes = dataBits.sizeInBytes();
+ CBC_QRCoderBitVector headerAndDataBits;
+ headerAndDataBits.Init();
+ InitQRCode(numInputBytes, versionSpecify, ecLevel, mode, qrCode, e);
+ if(e != BCExceptionNO) {
+ for(FX_INT32 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(FX_INT32 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(FX_INT32 k = 0; k < splitResult.GetSize(); k++) {
+ delete (Make_Pair*)splitResult[k];
+ }
+ splitResult.RemoveAll();
+ return ;
+ }
+ for(FX_INT32 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);
+ CBC_CommonByteMatrix* pDecoder = FX_NEW CBC_CommonByteMatrix(qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth());
+ pDecoder->Init();
+ CBC_AutoPtr<CBC_CommonByteMatrix> matrix(pDecoder);
+ FX_INT32 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, FX_INT32 &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(FX_INT32 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(FX_INT32 l = 0; l < splitResult.GetSize(); l++) {
+ delete (Make_Pair*)splitResult[l];
+ }
+ splitResult.RemoveAll();
+ return;
+ }
+ }
+ FX_INT32 numInputBytes = dataBits.sizeInBytes();
+ InitQRCode(numInputBytes, ecLevel, mode, qrCode, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e)
+ CBC_QRCoderBitVector headerAndDataBits;
+ headerAndDataBits.Init();
+ tempMode = NULL;
+ FX_INT32 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) {
+ FX_INT32 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 (FX_INT32 j = 0; j < splitResult.GetSize(); j++) {
+ delete (Make_Pair*)splitResult[j];
+ }
+ splitResult.RemoveAll();
+ return;
+ }
+ }
+ for (FX_INT32 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);
+ CBC_CommonByteMatrix* pDecoder = FX_NEW CBC_CommonByteMatrix(qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth());
+ pDecoder->Init();
+ CBC_AutoPtr<CBC_CommonByteMatrix> matrix(pDecoder);
+ FX_INT32 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, FX_INT32 &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);
+ FX_INT32 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);
+ FX_INT32 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);
+ CBC_CommonByteMatrix* pDecoder = FX_NEW CBC_CommonByteMatrix(qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth());
+ pDecoder->Init();
+ CBC_AutoPtr<CBC_CommonByteMatrix> matrix(pDecoder);
+ FX_INT32 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(FX_INT32 numDataBytes, CBC_QRCoderBitVector* bits, FX_INT32 &e)
+{
+ FX_INT32 capacity = numDataBytes << 3;
+ if(bits->Size() > capacity) {
+ e = BCExceptionDataTooMany;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ for (FX_INT32 i = 0; i < 4 && bits->Size() < capacity; ++i) {
+ bits->AppendBit(0, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 numBitsInLastByte = bits->Size() % 8;
+ if (numBitsInLastByte > 0) {
+ FX_INT32 numPaddingBits = 8 - numBitsInLastByte;
+ for (FX_INT32 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);
+ }
+ FX_INT32 numPaddingBytes = numDataBytes - bits->sizeInBytes();
+ for (FX_INT32 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);
+ }
+}
+FX_INT32 CBC_QRCoderEncoder::ChooseMaskPattern(CBC_QRCoderBitVector* bits, CBC_QRCoderErrorCorrectionLevel* ecLevel, FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ FX_INT32 minPenalty = 65535;
+ FX_INT32 bestMaskPattern = -1;
+ for(FX_INT32 maskPattern = 0; maskPattern < CBC_QRCoder::NUM_MASK_PATTERNS; maskPattern++) {
+ CBC_QRCoderMatrixUtil::BuildMatrix(bits, ecLevel, version, maskPattern, matrix, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ FX_INT32 penalty = CalculateMaskPenalty(matrix);
+ if(penalty < minPenalty) {
+ minPenalty = penalty;
+ bestMaskPattern = maskPattern;
+ }
+ }
+ return bestMaskPattern;
+}
+FX_INT32 CBC_QRCoderEncoder::CalculateMaskPenalty(CBC_CommonByteMatrix* matrix)
+{
+ FX_INT32 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(FX_INT32 i = 0; i < content.GetLength(); i++) {
+ if(isdigit((FX_BYTE)content[i])) {
+ hasNumeric = TRUE;
+ } else if(GetAlphaNumericCode((FX_BYTE)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;
+}
+FX_INT32 CBC_QRCoderEncoder::GetAlphaNumericCode(FX_INT32 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, FX_INT32 &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, FX_INT32 &e)
+{
+ FX_INT32 length = content.GetLength();
+ FX_INT32 i = 0;
+ while(i < length) {
+ FX_INT32 num1 = content[i] - '0';
+ if(i + 2 < length) {
+ FX_INT32 num2 = content[i + 1] - '0';
+ FX_INT32 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) {
+ FX_INT32 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, FX_INT32 &e)
+{
+ FX_INT32 length = content.GetLength();
+ FX_INT32 i = 0;
+ while(i < length) {
+ FX_INT32 code1 = GetAlphaNumericCode(content[i]);
+ if(code1 == -1) {
+ e = BCExceptionInvalidateCharacter;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ if(i + 1 < length) {
+ FX_INT32 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, FX_INT32 &e)
+{
+ FX_INT32 length = content.GetLength();
+ FX_DWORD value = 0;
+ for(FX_INT32 i = 0; i < length; i += 2) {
+ value = (FX_DWORD)((FX_BYTE)content[i] << 8 | (FX_BYTE)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, FX_INT32 &e)
+{
+ for(FX_INT32 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, FX_INT32 &e)
+{
+ for(FX_INT32 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, FX_INT32 &e)
+{
+ CFX_ByteArray bytes;
+ FX_DWORD value = 0, h = 0;
+ for(FX_INT32 i = 0; i < bytes.GetSize(); i += 2) {
+ value = (FX_DWORD)((FX_BYTE)(content[i] << 8) | (FX_BYTE)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(FX_INT32 numInputBytes, CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoderMode* mode, CBC_QRCoder* qrCode, FX_INT32 &e)
+{
+ qrCode->SetECLevel(ecLevel);
+ qrCode->SetMode(mode);
+ for(FX_INT32 versionNum = 1; versionNum <= 40; versionNum++) {
+ CBC_QRCoderVersion* version = CBC_QRCoderVersion::GetVersionForNumber(versionNum, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 numBytes = version->GetTotalCodeWords();
+ CBC_QRCoderECBlocks* ecBlocks = version->GetECBlocksForLevel(ecLevel);
+ FX_INT32 numEcBytes = ecBlocks->GetTotalECCodeWords();
+ FX_INT32 numRSBlocks = ecBlocks->GetNumBlocks();
+ FX_INT32 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, FX_INT32 &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(FX_INT32 numLetters, FX_INT32 version, CBC_QRCoderMode* mode, CBC_QRCoderBitVector* bits, FX_INT32 &e)
+{
+ CBC_QRCoderVersion* qcv = CBC_QRCoderVersion::GetVersionForNumber(version, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 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, FX_INT32 numTotalBytes, FX_INT32 numDataBytes, FX_INT32 numRSBlocks, CBC_QRCoderBitVector* result, FX_INT32 &e)
+{
+ if(bits->sizeInBytes() != numDataBytes) {
+ e = BCExceptionBitsBytesNotMatch;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 dataBytesOffset = 0;
+ FX_INT32 maxNumDataBytes = 0;
+ FX_INT32 maxNumEcBytes = 0;
+ CFX_PtrArray blocks;
+ FX_INT32 i;
+ for(i = 0; i < numRSBlocks; i++) {
+ FX_INT32 numDataBytesInBlock;
+ FX_INT32 numEcBytesInBlosk;
+ GetNumDataBytesAndNumECBytesForBlockID(numTotalBytes, numDataBytes, numRSBlocks, i,
+ numDataBytesInBlock, numEcBytesInBlosk);
+ CBC_CommonByteArray* dataBytes = FX_NEW CBC_CommonByteArray;
+ dataBytes->Set(bits->GetArray(), dataBytesOffset, numDataBytesInBlock);
+ CBC_CommonByteArray* ecBytes = GenerateECBytes(dataBytes, numEcBytesInBlosk, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ blocks.Add(FX_NEW CBC_QRCoderBlockPair(dataBytes, ecBytes));
+ maxNumDataBytes = FX_MAX(maxNumDataBytes, dataBytes->Size());
+ maxNumEcBytes = FX_MAX(maxNumEcBytes, ecBytes->Size());
+ dataBytesOffset += numDataBytesInBlock;
+ }
+ if(numDataBytes != dataBytesOffset) {
+ e = BCExceptionBytesNotMatchOffset;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ for(FX_INT32 x = 0; x < maxNumDataBytes; x++) {
+ for(FX_INT32 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(FX_INT32 y = 0; y < maxNumEcBytes; y++) {
+ for(FX_INT32 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(FX_INT32 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(FX_INT32 numTotalBytes, FX_INT32 numDataBytes,
+ FX_INT32 numRSBlocks, FX_INT32 blockID,
+ FX_INT32 &numDataBytesInBlock, FX_INT32& numECBytesInBlock)
+{
+ if(blockID >= numRSBlocks) {
+ return;
+ }
+ FX_INT32 numRsBlocksInGroup2 = numTotalBytes % numRSBlocks;
+ FX_INT32 numRsBlocksInGroup1 = numRSBlocks - numRsBlocksInGroup2;
+ FX_INT32 numTotalBytesInGroup1 = numTotalBytes / numRSBlocks;
+ FX_INT32 numTotalBytesInGroup2 = numTotalBytesInGroup1 + 1;
+ FX_INT32 numDataBytesInGroup1 = numDataBytes / numRSBlocks;
+ FX_INT32 numDataBytesInGroup2 = numDataBytesInGroup1 + 1;
+ FX_INT32 numEcBytesInGroup1 = numTotalBytesInGroup1 - numDataBytesInGroup1;
+ FX_INT32 numEcBytesInGroup2 = numTotalBytesInGroup2 - numDataBytesInGroup2;
+ if (blockID < numRsBlocksInGroup1) {
+ numDataBytesInBlock = numDataBytesInGroup1;
+ numECBytesInBlock = numEcBytesInGroup1;
+ } else {
+ numDataBytesInBlock = numDataBytesInGroup2;
+ numECBytesInBlock = numEcBytesInGroup2;
+ }
+}
+CBC_CommonByteArray* CBC_QRCoderEncoder::GenerateECBytes(CBC_CommonByteArray* dataBytes, FX_INT32 numEcBytesInBlock, FX_INT32 &e)
+{
+ FX_INT32 numDataBytes = dataBytes->Size();
+ CFX_Int32Array toEncode;
+ toEncode.SetSize(numDataBytes + numEcBytesInBlock);
+ for(FX_INT32 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 = FX_NEW CBC_CommonByteArray(numEcBytesInBlock);
+ for(FX_INT32 j = 0; j < numEcBytesInBlock; j++) {
+ ecBytes->Set(j, toEncode[numDataBytes + j]);
+ }
+ return ecBytes;
+}
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderEncoder.h b/xfa/src/fxbarcode/qrcode/BC_QRCoderEncoder.h
new file mode 100644
index 0000000000..8dea2a6477
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderEncoder.h
@@ -0,0 +1,60 @@
+// 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 _BC_QRCODERENCODER_H_
+#define _BC_QRCODERENCODER_H_
+class Make_Pair;
+class CBC_QRCoder;
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRCoderMode;
+class CBC_QRCoderBitVector;
+class CBC_CommonByteArray;
+class CBC_CommonByteMatrix;
+class CBC_QRCoderEncoder;
+class CBC_QRCoderEncoder : public CFX_Object
+{
+private:
+ const static FX_INT32 m_alphaNumbericTable[96];
+public:
+ CBC_QRCoderEncoder();
+ virtual ~CBC_QRCoderEncoder();
+
+ static void Encode(const CFX_ByteString &content, CBC_QRCoderErrorCorrectionLevel* ecLevel, CBC_QRCoder *qrCode, FX_INT32 &e, FX_INT32 versionSpecify = 0);
+ static void Encode(const CFX_WideString &content, CBC_QRCoderErrorCorrectionLevel* ecLevel, CBC_QRCoder *qrCode, FX_INT32 &e);
+ static void EncodeWithSpecifyVersion(const CFX_ByteString &content, CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoder *qrCode, FX_INT32 versionSpecify, FX_INT32 &e);
+ static void EncodeWithAutoVersion(const CFX_ByteString &content, CBC_QRCoderErrorCorrectionLevel* ecLevel, CBC_QRCoder *qrCode, FX_INT32 &e);
+ static CBC_QRCoderMode* ChooseMode(const CFX_ByteString & content, CFX_ByteString encoding);
+ static FX_INT32 GetAlphaNumericCode(FX_INT32 code);
+ static void AppendECI(CBC_QRCoderBitVector* bits);
+ static void AppendBytes(const CFX_ByteString &content, CBC_QRCoderMode* mode, CBC_QRCoderBitVector* bits, CFX_ByteString encoding, FX_INT32 &e);
+ static void AppendNumericBytes(const CFX_ByteString &content, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+ static void AppendAlphaNumericBytes(const CFX_ByteString &content, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+ static void Append8BitBytes(const CFX_ByteString &content, CBC_QRCoderBitVector* bits, CFX_ByteString encoding, FX_INT32 &e);
+ static void Append8BitBytes(CFX_ByteArray &bytes, CBC_QRCoderBitVector *bits, FX_INT32 &e);
+ static void AppendKanjiBytes(const CFX_ByteString &content, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+ static void AppendGBKBytes(const CFX_ByteString &content, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+ static void InitQRCode(FX_INT32 numInputBytes, FX_INT32 versionNumber,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel, CBC_QRCoderMode* mode, CBC_QRCoder* qrCode, FX_INT32 &e);
+ static void InitQRCode(FX_INT32 numInputBytes, CBC_QRCoderErrorCorrectionLevel* ecLevel, CBC_QRCoderMode* mode, CBC_QRCoder* qrCode, FX_INT32 &e);
+ static void AppendModeInfo(CBC_QRCoderMode* mode, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+ static void AppendLengthInfo(FX_INT32 numLetters, FX_INT32 version, CBC_QRCoderMode* mode, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+
+ static void InterleaveWithECBytes(CBC_QRCoderBitVector* bits, FX_INT32 numTotalBytes, FX_INT32 numDataBytes, FX_INT32 numRSBlocks, CBC_QRCoderBitVector* result, FX_INT32 &e);
+ static void GetNumDataBytesAndNumECBytesForBlockID(FX_INT32 numTotalBytes, FX_INT32 numDataBytes,
+ FX_INT32 numRSBlocks, FX_INT32 blockID,
+ FX_INT32 &numDataBytesInBlock, FX_INT32& numECBytesInBlocks);
+ static CBC_CommonByteArray* GenerateECBytes(CBC_CommonByteArray* dataBytes, FX_INT32 numEcBytesInBlock, FX_INT32 &e);
+ static FX_INT32 ChooseMaskPattern(CBC_QRCoderBitVector* bits, CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static FX_INT32 CalculateMaskPenalty(CBC_CommonByteMatrix* matrix);
+ static void TerminateBits(FX_INT32 numDataBytes, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+ static FX_INT32 GetSpanByVersion(CBC_QRCoderMode *modeFirst, CBC_QRCoderMode *modeSecond, FX_INT32 versionNum, FX_INT32 &e);
+ static void MergeString(CFX_PtrArray &result, FX_INT32 versionNum, FX_INT32 &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, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.cpp b/xfa/src/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.cpp
new file mode 100644
index 0000000000..f8aae491da
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.cpp
@@ -0,0 +1,97 @@
+// 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 "../barcode.h"
+#include "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(FX_INT32 ordinal, FX_INT32 bits, FX_CHAR* name)
+{
+ m_name += name;
+ m_ordinal = ordinal;
+ m_bits = bits;
+}
+CBC_QRCoderErrorCorrectionLevel::~CBC_QRCoderErrorCorrectionLevel()
+{
+}
+void CBC_QRCoderErrorCorrectionLevel::Initialize()
+{
+ L = FX_NEW CBC_QRCoderErrorCorrectionLevel(0, 0x01, (FX_CHAR*)"L");
+ M = FX_NEW CBC_QRCoderErrorCorrectionLevel(1, 0x00, (FX_CHAR*)"M");
+ Q = FX_NEW CBC_QRCoderErrorCorrectionLevel(2, 0x03, (FX_CHAR*)"Q");
+ H = FX_NEW CBC_QRCoderErrorCorrectionLevel(3, 0x02, (FX_CHAR*)"H");
+}
+void CBC_QRCoderErrorCorrectionLevel::Finalize()
+{
+ delete L;
+ delete M;
+ delete Q;
+ delete H;
+}
+FX_INT32 CBC_QRCoderErrorCorrectionLevel::Ordinal()
+{
+ return m_ordinal;
+}
+FX_INT32 CBC_QRCoderErrorCorrectionLevel::GetBits()
+{
+ return m_bits;
+}
+CFX_ByteString CBC_QRCoderErrorCorrectionLevel::GetName()
+{
+ return m_name;
+}
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::ForBits(FX_INT32 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/src/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h b/xfa/src/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h
new file mode 100644
index 0000000000..2c0ad7b0b7
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.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 _BC_QRCODERERRORCORRECTIONLEVEL_H_
+#define _BC_QRCODERERRORCORRECTIONLEVEL_H_
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRCoderErrorCorrectionLevel : public CFX_Object
+{
+private:
+ FX_INT32 m_ordinal;
+ FX_INT32 m_bits;
+ CFX_ByteString m_name;
+ CBC_QRCoderErrorCorrectionLevel(FX_INT32 ordinal, FX_INT32 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();
+ FX_INT32 Ordinal();
+ FX_INT32 GetBits();
+ CFX_ByteString GetName();
+ static void Destroy();
+ static CBC_QRCoderErrorCorrectionLevel* ForBits(FX_INT32 bits);
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderFormatInformation.cpp b/xfa/src/fxbarcode/qrcode/BC_QRCoderFormatInformation.cpp
new file mode 100644
index 0000000000..5a205480ae
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderFormatInformation.cpp
@@ -0,0 +1,119 @@
+// 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 "../barcode.h"
+#include "BC_QRCoderErrorCorrectionLevel.h"
+#include "BC_QRCoderFormatInformation.h"
+const FX_INT32 CBC_QRCoderFormatInformation::FORMAT_INFO_MASK_QR = 0X5412;
+const FX_INT32 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 FX_INT32 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(FX_INT32 formatInfo)
+{
+ m_errorCorrectLevl = CBC_QRCoderErrorCorrectionLevel::ForBits((formatInfo >> 3) & 0x03);
+ m_dataMask = (FX_BYTE) (formatInfo & 0x07);
+}
+CBC_QRCoderFormatInformation::~CBC_QRCoderFormatInformation()
+{
+}
+FX_INT32 CBC_QRCoderFormatInformation::NumBitsDiffering(FX_INT32 a, FX_INT32 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];
+}
+FX_BYTE CBC_QRCoderFormatInformation::GetDataMask()
+{
+ return m_dataMask;
+}
+CBC_QRCoderErrorCorrectionLevel *CBC_QRCoderFormatInformation::GetErrorCorrectionLevel()
+{
+ return m_errorCorrectLevl;
+}
+CBC_QRCoderFormatInformation* CBC_QRCoderFormatInformation::DecodeFormatInformation(FX_INT32 maskedFormatInfo)
+{
+ CBC_QRCoderFormatInformation* formatInfo = DoDecodeFormatInformation(maskedFormatInfo);
+ if(formatInfo != NULL) {
+ return formatInfo;
+ }
+ return DoDecodeFormatInformation(maskedFormatInfo ^ FORMAT_INFO_MASK_QR);
+}
+CBC_QRCoderFormatInformation* CBC_QRCoderFormatInformation::DoDecodeFormatInformation(FX_INT32 maskedFormatInfo)
+{
+ FX_INT32 bestDifference = (FX_INT32)FXSYS_nan();
+ FX_INT32 bestFormatInfo = 0;
+ for(FX_INT32 i = 0; i < 32; i++) {
+ FX_INT32 const* decodeInfo = &FORMAT_INFO_DECODE_LOOKUP[i][0];
+ FX_INT32 targetInfo = decodeInfo[0];
+ if(targetInfo == maskedFormatInfo) {
+ return FX_NEW CBC_QRCoderFormatInformation(decodeInfo[1]);
+ }
+ FX_INT32 bitsDifference = NumBitsDiffering(maskedFormatInfo, targetInfo);
+ if(bitsDifference < bestDifference) {
+ bestFormatInfo = decodeInfo[1];
+ bestDifference = bitsDifference;
+ }
+ }
+ if(bestDifference <= 3) {
+ return FX_NEW CBC_QRCoderFormatInformation(bestFormatInfo);
+ }
+ return NULL;
+}
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderFormatInformation.h b/xfa/src/fxbarcode/qrcode/BC_QRCoderFormatInformation.h
new file mode 100644
index 0000000000..9d828c8380
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderFormatInformation.h
@@ -0,0 +1,29 @@
+// 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 _BC_QRCODERFORMATINFORMATION_H_
+#define _BC_QRCODERFORMATINFORMATION_H_
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRCoderFormatInformation;
+class CBC_QRCoderFormatInformation : public CFX_Object
+{
+private:
+ const static FX_INT32 FORMAT_INFO_MASK_QR;
+ const static FX_INT32 FORMAT_INFO_DECODE_LOOKUP[32][2];
+ const static FX_INT32 BITS_SET_IN_HALF_BYTE[16];
+ CBC_QRCoderErrorCorrectionLevel* m_errorCorrectLevl;
+ FX_BYTE m_dataMask;
+public:
+ CBC_QRCoderFormatInformation(FX_INT32 formatInfo);
+ virtual ~CBC_QRCoderFormatInformation();
+ FX_BYTE GetDataMask();
+ CBC_QRCoderErrorCorrectionLevel* GetErrorCorrectionLevel();
+
+ static FX_INT32 NumBitsDiffering(FX_INT32 a, FX_INT32 b);
+ static CBC_QRCoderFormatInformation* DecodeFormatInformation(FX_INT32 maskedFormatInfo);
+ static CBC_QRCoderFormatInformation* DoDecodeFormatInformation(FX_INT32 maskedFormatInfo);
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderMaskUtil.cpp b/xfa/src/fxbarcode/qrcode/BC_QRCoderMaskUtil.cpp
new file mode 100644
index 0000000000..bc01eff442
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderMaskUtil.cpp
@@ -0,0 +1,208 @@
+// 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 "../barcode.h"
+#include "../common/BC_CommonByteMatrix.h"
+#include "BC_QRCoderErrorCorrectionLevel.h"
+#include "BC_QRCoder.h"
+#include "BC_QRCoderMaskUtil.h"
+CBC_QRCoderMaskUtil::CBC_QRCoderMaskUtil()
+{
+}
+CBC_QRCoderMaskUtil::~CBC_QRCoderMaskUtil()
+{
+}
+FX_INT32 CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule1(CBC_CommonByteMatrix* matrix)
+{
+ return ApplyMaskPenaltyRule1Internal(matrix, TRUE) +
+ ApplyMaskPenaltyRule1Internal(matrix, FALSE);
+}
+FX_INT32 CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule2(CBC_CommonByteMatrix* matrix)
+{
+ FX_INT32 penalty = 0;
+ FX_BYTE* array = matrix->GetArray();
+ FX_INT32 width = matrix->GetWidth();
+ FX_INT32 height = matrix->GetHeight();
+ for(FX_INT32 y = 0; y < height - 1; y++) {
+ for(FX_INT32 x = 0; x < width - 1; x++) {
+ FX_INT32 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;
+}
+FX_INT32 CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule3(CBC_CommonByteMatrix* matrix)
+{
+ FX_INT32 penalty = 0;
+ FX_BYTE* array = matrix->GetArray();
+ FX_INT32 width = matrix->GetWidth();
+ FX_INT32 height = matrix->GetHeight();
+ for (FX_INT32 y = 0; y < height; ++y) {
+ for (FX_INT32 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;
+}
+FX_INT32 CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule4(CBC_CommonByteMatrix* matrix)
+{
+ FX_INT32 numDarkCells = 0;
+ FX_BYTE* array = matrix->GetArray();
+ FX_INT32 width = matrix->GetWidth();
+ FX_INT32 height = matrix->GetHeight();
+ for (FX_INT32 y = 0; y < height; ++y) {
+ for (FX_INT32 x = 0; x < width; ++x) {
+ if (array[y * width + x] == 1) {
+ numDarkCells += 1;
+ }
+ }
+ }
+ FX_INT32 numTotalCells = matrix->GetHeight() * matrix->GetWidth();
+ double darkRatio = (double) numDarkCells / numTotalCells;
+ return abs( (FX_INT32) (darkRatio * 100 - 50) / 5 ) * 5 * 10;
+}
+FX_BOOL CBC_QRCoderMaskUtil::GetDataMaskBit(FX_INT32 maskPattern, FX_INT32 x, FX_INT32 y, FX_INT32 &e)
+{
+ if(!CBC_QRCoder::IsValidMaskPattern(maskPattern)) {
+ e = (BCExceptionInvalidateMaskPattern);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ }
+ FX_INT32 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;
+}
+FX_INT32 CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule1Internal(CBC_CommonByteMatrix* matrix, FX_BOOL isHorizontal)
+{
+ FX_INT32 penalty = 0;
+ FX_INT32 numSameBitCells = 0;
+ FX_INT32 prevBit = -1;
+ FX_INT32 width = matrix->GetWidth();
+ FX_INT32 height = matrix->GetHeight();
+ FX_INT32 iLimit = isHorizontal ? height : width;
+ FX_INT32 jLimit = isHorizontal ? width : height;
+ FX_BYTE* array = matrix->GetArray();
+ for (FX_INT32 i = 0; i < iLimit; ++i) {
+ for (FX_INT32 j = 0; j < jLimit; ++j) {
+ FX_INT32 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/src/fxbarcode/qrcode/BC_QRCoderMaskUtil.h b/xfa/src/fxbarcode/qrcode/BC_QRCoderMaskUtil.h
new file mode 100644
index 0000000000..134d344e72
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderMaskUtil.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 _BC_QRCODERMASKUTIL_H_
+#define _BC_QRCODERMASKUTIL_H_
+class CBC_CommonByteMatrix;
+class CBC_QRCoderMaskUtil;
+class CBC_QRCoderMaskUtil : public CFX_Object
+{
+public:
+ CBC_QRCoderMaskUtil();
+ virtual ~CBC_QRCoderMaskUtil();
+ static FX_BOOL GetDataMaskBit(FX_INT32 maskPattern, FX_INT32 x, FX_INT32 y, FX_INT32 &e);
+
+ static FX_INT32 ApplyMaskPenaltyRule1(CBC_CommonByteMatrix* matrix);
+ static FX_INT32 ApplyMaskPenaltyRule2(CBC_CommonByteMatrix* matrix);
+ static FX_INT32 ApplyMaskPenaltyRule3(CBC_CommonByteMatrix* matrix);
+ static FX_INT32 ApplyMaskPenaltyRule4(CBC_CommonByteMatrix* matrix);
+ static FX_INT32 ApplyMaskPenaltyRule1Internal(CBC_CommonByteMatrix* matrix, FX_BOOL isHorizontal);
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp b/xfa/src/fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp
new file mode 100644
index 0000000000..4c2db5e34e
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp
@@ -0,0 +1,490 @@
+// 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 "../barcode.h"
+#include "../common/BC_CommonByteMatrix.h"
+#include "BC_QRCoderErrorCorrectionLevel.h"
+#include "BC_QRCoder.h"
+#include "BC_QRCoderMaskUtil.h"
+#include "BC_QRCoderMatrixUtil.h"
+#include "BC_QRCoderBitVector.h"
+const FX_INT32 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 FX_INT32 CBC_QRCoderMatrixUtil::HORIZONTAL_SEPARATION_PATTERN[1][8] = {
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+const FX_INT32 CBC_QRCoderMatrixUtil::VERTICAL_SEPARATION_PATTERN[7][1] = {
+ 0, 0, 0, 0, 0, 0, 0
+};
+const FX_INT32 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 FX_INT32 CBC_QRCoderMatrixUtil::POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[40][7] = {
+ { -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 FX_INT32 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 FX_INT32 CBC_QRCoderMatrixUtil::VERSION_INFO_POLY = 0x1f25;
+const FX_INT32 CBC_QRCoderMatrixUtil::TYPE_INFO_POLY = 0x0537;
+const FX_INT32 CBC_QRCoderMatrixUtil::TYPE_INFO_MASK_PATTERN = 0x5412;
+void CBC_QRCoderMatrixUtil::ClearMatrix(CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ matrix->clear((FX_BYTE) - 1);
+}
+void CBC_QRCoderMatrixUtil::BuildMatrix(CBC_QRCoderBitVector* dataBits,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ FX_INT32 version, FX_INT32 maskPattern,
+ CBC_CommonByteMatrix* matrix, FX_INT32 &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(FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &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,
+ FX_INT32 maskPattern, CBC_CommonByteMatrix *matrix, FX_INT32 &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(FX_INT32 i = 0; i < typeInfoBits.Size(); i++) {
+ FX_INT32 bit = typeInfoBits.At(typeInfoBits.Size() - 1 - i, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 x1 = TYPE_INFO_COORDINATES[i][0];
+ FX_INT32 y1 = TYPE_INFO_COORDINATES[i][1];
+ matrix->Set(x1, y1, bit);
+ if(i < 8) {
+ FX_INT32 x2 = matrix->GetWidth() - i - 1;
+ FX_INT32 y2 = 8;
+ matrix->Set(x2, y2, bit);
+ } else {
+ FX_INT32 x2 = 8;
+ FX_INT32 y2 = matrix->GetHeight() - 7 + (i - 8);
+ matrix->Set(x2, y2, bit);
+ }
+ }
+}
+void CBC_QRCoderMatrixUtil::MaybeEmbedVersionInfo(FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &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);
+ FX_INT32 bitIndex = 6 * 3 - 1;
+ for(FX_INT32 i = 0; i < 6; i++) {
+ for(FX_INT32 j = 0; j < 3; j++) {
+ FX_INT32 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,
+ FX_INT32 maskPattern, CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL || dataBits == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 bitIndex = 0;
+ FX_INT32 direction = -1;
+ FX_INT32 x = matrix->GetWidth() - 1;
+ FX_INT32 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(FX_INT32 i = 0; i < 2; i++) {
+ FX_INT32 xx = x - i;
+ if(!IsEmpty(matrix->Get(xx, y))) {
+ continue;
+ }
+ FX_INT32 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;
+ }
+}
+FX_INT32 CBC_QRCoderMatrixUtil::CalculateBCHCode(FX_INT32 value, FX_INT32 poly)
+{
+ FX_INT32 msbSetInPoly = FindMSBSet(poly);
+ value <<= msbSetInPoly - 1;
+ while(FindMSBSet(value) >= msbSetInPoly) {
+ value ^= poly << (FindMSBSet(value) - msbSetInPoly);
+ }
+ return value;
+}
+void CBC_QRCoderMatrixUtil::MakeTypeInfoBits(CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ FX_INT32 maskPattern, CBC_QRCoderBitVector* bits, FX_INT32 &e)
+{
+ if(bits == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ if(!CBC_QRCoder::IsValidMaskPattern(maskPattern)) {
+ e = BCExceptionBadMask;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 typeInfo = (ecLevel->GetBits() << 3) | maskPattern;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ bits->AppendBits(typeInfo, 5, e);
+ FX_INT32 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(FX_INT32 version, CBC_QRCoderBitVector* bits, FX_INT32 &e)
+{
+ if(bits == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ bits->AppendBits(version, 6, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 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(FX_INT32 value)
+{
+ return (FX_BYTE)value == 0xff;
+}
+FX_BOOL CBC_QRCoderMatrixUtil::IsValidValue(FX_INT32 value)
+{
+ return ((FX_BYTE)value == 0xff || (FX_BYTE)value == 0x00 || (FX_BYTE)value == 0x01);
+}
+void CBC_QRCoderMatrixUtil::EmbedTimingPatterns(CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ for(FX_INT32 i = 8; i < matrix->GetWidth() - 8; i++) {
+ FX_INT32 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, FX_INT32 &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(FX_INT32 xStart, FX_INT32 yStart,
+ CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ for(FX_INT32 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(FX_INT32 xStart, FX_INT32 yStart,
+ CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ for(FX_INT32 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(FX_INT32 xStart, FX_INT32 yStart,
+ CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ for(FX_INT32 y = 0; y < 5; y++) {
+ for(FX_INT32 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 (FX_INT32 xStart, FX_INT32 yStart,
+ CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ for(FX_INT32 y = 0; y < 7; y++) {
+ for(FX_INT32 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, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 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);
+ FX_INT32 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);
+ FX_INT32 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(FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ if(version < 2) {
+ return;
+ }
+ FX_INT32 index = version - 1;
+ FX_INT32 const* coordinates = &(POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index][0]);
+ FX_INT32 numCoordinate = 7;
+ for(FX_INT32 i = 0; i < numCoordinate; i++) {
+ for(FX_INT32 j = 0; j < numCoordinate; j++) {
+ FX_INT32 y = coordinates[i];
+ FX_INT32 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);
+ }
+ }
+ }
+}
+FX_INT32 CBC_QRCoderMatrixUtil::FindMSBSet(FX_INT32 value)
+{
+ FX_INT32 numDigits = 0;
+ while(value != 0) {
+ value >>= 1;
+ ++numDigits;
+ }
+ return numDigits;
+}
+CBC_QRCoderMatrixUtil::CBC_QRCoderMatrixUtil()
+{
+}
+CBC_QRCoderMatrixUtil::~CBC_QRCoderMatrixUtil()
+{
+}
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderMatrixUtil.h b/xfa/src/fxbarcode/qrcode/BC_QRCoderMatrixUtil.h
new file mode 100644
index 0000000000..23a9d88128
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderMatrixUtil.h
@@ -0,0 +1,50 @@
+// 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 _BC_QRCODERMATRIXUTIL_H_
+#define _BC_QRCODERMATRIXUTIL_H_
+class CBC_CommonByteMatrix;
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRCoderBitVector;
+class CBC_QRCoderMatrixUtil;
+class CBC_QRCoderMatrixUtil : public CFX_Object
+{
+private:
+ const static FX_INT32 POSITION_DETECTION_PATTERN[7][7];
+ const static FX_INT32 VERTICAL_SEPARATION_PATTERN[7][1];
+ const static FX_INT32 HORIZONTAL_SEPARATION_PATTERN[1][8];
+ const static FX_INT32 POSITION_ADJUSTMENT_PATTERN[5][5];
+ const static FX_INT32 POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[40][7];
+ const static FX_INT32 TYPE_INFO_COORDINATES[15][2];
+ const static FX_INT32 VERSION_INFO_POLY;
+ const static FX_INT32 TYPE_INFO_POLY;
+ const static FX_INT32 TYPE_INFO_MASK_PATTERN;
+public:
+ CBC_QRCoderMatrixUtil();
+ virtual ~CBC_QRCoderMatrixUtil();
+ static void ClearMatrix(CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void BuildMatrix(CBC_QRCoderBitVector* dataBits, CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ FX_INT32 version, FX_INT32 maskPattern, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void EmbedBasicPatterns(FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void EmbedTypeInfo(CBC_QRCoderErrorCorrectionLevel* ecLevel, FX_INT32 maskPattern, CBC_CommonByteMatrix *matrix, FX_INT32 &e);
+ static void EmbedDataBits(CBC_QRCoderBitVector* dataBits, FX_INT32 maskPattern, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void MaybeEmbedVersionInfo(FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static FX_INT32 FindMSBSet(FX_INT32 value);
+ static FX_INT32 CalculateBCHCode(FX_INT32 code, FX_INT32 poly);
+ static void MakeTypeInfoBits(CBC_QRCoderErrorCorrectionLevel* ecLevel, FX_INT32 maskPattern, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+ static void MakeVersionInfoBits(FX_INT32 version, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+ static FX_BOOL IsEmpty(FX_INT32 value);
+ static FX_BOOL IsValidValue(FX_INT32 value);
+ static void EmbedTimingPatterns(CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void EmbedDarkDotAtLeftBottomCorner(CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void EmbedHorizontalSeparationPattern(FX_INT32 xStart, FX_INT32 yStart, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void EmbedVerticalSeparationPattern(FX_INT32 xStart, FX_INT32 yStart, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void EmbedPositionAdjustmentPattern(FX_INT32 xStart, FX_INT32 yStart, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void EmbedPositionDetectionPattern(FX_INT32 xStart, FX_INT32 yStart, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void EmbedPositionDetectionPatternsAndSeparators(CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void MaybeEmbedPositionAdjustmentPatterns(FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderMode.cpp b/xfa/src/fxbarcode/qrcode/BC_QRCoderMode.cpp
new file mode 100644
index 0000000000..00c7e47cb7
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderMode.cpp
@@ -0,0 +1,178 @@
+// 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 "../barcode.h"
+#include "BC_QRCoderVersion.h"
+#include "BC_QRCoderMode.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(FX_INT32 *characterCountBitsForVersions,
+ FX_INT32 x1, FX_INT32 x2, FX_INT32 x3,
+ FX_INT32 bits, CFX_ByteString name)
+{
+ m_characterCountBitsForVersions = characterCountBitsForVersions;
+ if (m_characterCountBitsForVersions != NULL) {
+ m_characterCountBitsForVersions[0] = x1;
+ m_characterCountBitsForVersions[1] = x2;
+ m_characterCountBitsForVersions[2] = x3;
+ }
+ m_name += name;
+ m_bits = bits;
+}
+CBC_QRCoderMode::~CBC_QRCoderMode()
+{
+ if(m_characterCountBitsForVersions != NULL) {
+ FX_Free(m_characterCountBitsForVersions);
+ }
+}
+void CBC_QRCoderMode::Initialize()
+{
+ sBYTE = FX_NEW CBC_QRCoderMode(FX_Alloc(FX_INT32, 3), 8, 16, 16, 0x4, "BYTE");
+ sALPHANUMERIC = FX_NEW CBC_QRCoderMode(FX_Alloc(FX_INT32, 3), 9, 11, 13, 0x2, "ALPHANUMERIC");
+ sECI = FX_NEW CBC_QRCoderMode(NULL, 0, 0, 0, 0x7, "ECI");
+ sKANJI = FX_NEW CBC_QRCoderMode(FX_Alloc(FX_INT32, 3), 8, 10, 12, 0x8, "KANJI");
+ sNUMERIC = FX_NEW CBC_QRCoderMode(FX_Alloc(FX_INT32, 3), 10, 12, 14, 0x1, "NUMERIC");
+ sGBK = FX_NEW CBC_QRCoderMode(FX_Alloc(FX_INT32, 3), 8, 10, 12, 0x0D, "GBK");
+ sTERMINATOR = FX_NEW CBC_QRCoderMode(FX_Alloc(FX_INT32, 3), 0, 0, 0, 0x00, "TERMINATOR");
+ sFNC1_FIRST_POSITION = FX_NEW CBC_QRCoderMode(NULL, 0, 0, 0, 0x05, "FNC1_FIRST_POSITION");
+ sFNC1_SECOND_POSITION = FX_NEW CBC_QRCoderMode(NULL, 0, 0, 0, 0x09, "FNC1_SECOND_POSITION");
+ sSTRUCTURED_APPEND = FX_NEW CBC_QRCoderMode(FX_Alloc(FX_INT32, 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(FX_INT32 bits, FX_INT32 &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;
+}
+FX_INT32 CBC_QRCoderMode::GetBits()
+{
+ return m_bits;
+}
+CFX_ByteString CBC_QRCoderMode::GetName()
+{
+ return m_name;
+}
+FX_INT32 CBC_QRCoderMode::GetCharacterCountBits(CBC_QRCoderVersion* version, FX_INT32 &e)
+{
+ if(m_characterCountBitsForVersions == NULL) {
+ e = BCExceptionCharacterNotThisMode;
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ }
+ FX_INT32 number = version->GetVersionNumber();
+ FX_INT32 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/src/fxbarcode/qrcode/BC_QRCoderMode.h b/xfa/src/fxbarcode/qrcode/BC_QRCoderMode.h
new file mode 100644
index 0000000000..71cea9fc78
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderMode.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 _BC_QRCODERMODE_H_
+#define _BC_QRCODERMODE_H_
+class CBC_QRCoderVersion;
+class CBC_QRCoderMode;
+class CBC_QRCoderMode : public CFX_Object
+{
+private:
+ FX_INT32* m_characterCountBitsForVersions;
+ FX_INT32 m_bits;
+ CFX_ByteString m_name;
+ CBC_QRCoderMode(FX_INT32 *characterCountBitsForVersions, FX_INT32 x1, FX_INT32 x2, FX_INT32 x3, FX_INT32 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(FX_INT32 bits, FX_INT32 &e);
+ FX_INT32 GetCharacterCountBits(CBC_QRCoderVersion* version, FX_INT32 &e);
+ FX_INT32 GetBits();
+ CFX_ByteString GetName();
+ static void Destroy();
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderVersion.cpp b/xfa/src/fxbarcode/qrcode/BC_QRCoderVersion.cpp
new file mode 100644
index 0000000000..9ff54f2a13
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderVersion.cpp
@@ -0,0 +1,777 @@
+// 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 "../barcode.h"
+#include "../utils.h"
+#include "../common/BC_CommonBitMatrix.h"
+#include "BC_QRCoderECB.h"
+#include "BC_QRCoderFormatInformation.h"
+#include "BC_QRCoderErrorCorrectionLevel.h"
+#include "BC_QRCoderBitVector.h"
+#include "BC_QRCoderECBlocks.h"
+#include "BC_QRCoderVersion.h"
+const FX_INT32 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 = FX_NEW CFX_PtrArray();
+}
+void CBC_QRCoderVersion::Finalize()
+{
+ for(FX_INT32 i = 0 ; i < VERSION->GetSize(); i++) {
+ CBC_QRCoderVersion* v = (CBC_QRCoderVersion*)(VERSION->GetAt(i));
+ delete v;
+ }
+ delete VERSION;
+}
+CBC_QRCoderVersion::CBC_QRCoderVersion(FX_INT32 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);
+ FX_INT32 total = 0;
+ FX_INT32 ecCodeWords = ecBlocks1->GetECCodeWordsPerBlock();
+ CFX_PtrArray* ecbArray = ecBlocks1->GetECBlocks();
+ for(FX_INT32 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) {
+ FX_INT32 itBeg = 0;
+ FX_INT32 itEnd = m_ecBlocks.GetSize();
+ while(itBeg != itEnd) {
+ delete ( (CBC_QRCoderECBlocks*)(m_ecBlocks[itBeg]) );
+ itBeg++;
+ }
+ }
+}
+FX_INT32 CBC_QRCoderVersion::GetVersionNumber()
+{
+ return m_versionNumber;
+}
+CFX_Int32Array* CBC_QRCoderVersion::GetAlignmentPatternCenters()
+{
+ return &m_alignmentPatternCenters;
+}
+FX_INT32 CBC_QRCoderVersion::GetTotalCodeWords()
+{
+ return m_totalCodeWords;
+}
+FX_INT32 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(FX_INT32 dimension, FX_INT32 &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(FX_INT32 versionBits, FX_INT32 &e)
+{
+ FX_INT32 bestDifference = FXSYS_IntMax;
+ FX_INT32 bestVersion = 0;
+ for (FX_INT32 i = 0; i < 34; i++) {
+ FX_INT32 targetVersion = VERSION_DECODE_INFO[i];
+ if(targetVersion == versionBits) {
+ CBC_QRCoderVersion* qcv = GetVersionForNumber(i + 7, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return qcv;
+ }
+ FX_INT32 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(FX_INT32 &e)
+{
+ FX_INT32 dimension = GetDimensionForVersion();
+ CBC_CommonBitMatrix* bitMatrix = FX_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);
+ FX_INT32 max = m_alignmentPatternCenters.GetSize();
+ for (FX_INT32 x = 0; x < max; x++) {
+ FX_INT32 i = m_alignmentPatternCenters[x] - 2;
+ for (FX_INT32 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(FX_INT32 versionNumber, FX_INT32 &e)
+{
+ if(VERSION->GetSize() == 0) {
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(1,
+ FX_NEW CBC_QRCoderECBlocks(7, FX_NEW CBC_QRCoderECB(1, 19)),
+ FX_NEW CBC_QRCoderECBlocks(10, FX_NEW CBC_QRCoderECB(1, 16)),
+ FX_NEW CBC_QRCoderECBlocks(13, FX_NEW CBC_QRCoderECB(1, 13)),
+ FX_NEW CBC_QRCoderECBlocks(17, FX_NEW CBC_QRCoderECB(1, 9))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(2,
+ FX_NEW CBC_QRCoderECBlocks(10, FX_NEW CBC_QRCoderECB(1, 34)),
+ FX_NEW CBC_QRCoderECBlocks(16, FX_NEW CBC_QRCoderECB(1, 28)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(1, 22)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(1, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(3,
+ FX_NEW CBC_QRCoderECBlocks(15, FX_NEW CBC_QRCoderECB(1, 55)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(1, 44)),
+ FX_NEW CBC_QRCoderECBlocks(18, FX_NEW CBC_QRCoderECB(2, 17)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(2, 13))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(4,
+ FX_NEW CBC_QRCoderECBlocks(20, FX_NEW CBC_QRCoderECB(1, 80)),
+ FX_NEW CBC_QRCoderECBlocks(18, FX_NEW CBC_QRCoderECB(2, 32)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(2, 24)),
+ FX_NEW CBC_QRCoderECBlocks(16, FX_NEW CBC_QRCoderECB(4, 9))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(5,
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(1, 108)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(2, 43)),
+ FX_NEW CBC_QRCoderECBlocks(18, FX_NEW CBC_QRCoderECB(2, 15),
+ FX_NEW CBC_QRCoderECB(2, 16)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(2, 11),
+ FX_NEW CBC_QRCoderECB(2, 12))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(6,
+ FX_NEW CBC_QRCoderECBlocks(18, FX_NEW CBC_QRCoderECB(2, 68)),
+ FX_NEW CBC_QRCoderECBlocks(16, FX_NEW CBC_QRCoderECB(4, 27)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(4, 19)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(4, 15))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(7,
+ FX_NEW CBC_QRCoderECBlocks(20, FX_NEW CBC_QRCoderECB(2, 78)),
+ FX_NEW CBC_QRCoderECBlocks(18, FX_NEW CBC_QRCoderECB(4, 31)),
+ FX_NEW CBC_QRCoderECBlocks(18, FX_NEW CBC_QRCoderECB(2, 14),
+ FX_NEW CBC_QRCoderECB(4, 15)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(4, 13),
+ FX_NEW CBC_QRCoderECB(1, 14))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(8,
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(2, 97)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(2, 38),
+ FX_NEW CBC_QRCoderECB(2, 39)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(4, 18),
+ FX_NEW CBC_QRCoderECB(2, 19)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(4, 14),
+ FX_NEW CBC_QRCoderECB(2, 15))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(9,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(2, 116)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(3, 36),
+ FX_NEW CBC_QRCoderECB(2, 37)),
+ FX_NEW CBC_QRCoderECBlocks(20, FX_NEW CBC_QRCoderECB(4, 16),
+ FX_NEW CBC_QRCoderECB(4, 17)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(4, 12),
+ FX_NEW CBC_QRCoderECB(4, 13))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(10,
+ FX_NEW CBC_QRCoderECBlocks(18, FX_NEW CBC_QRCoderECB(2, 68),
+ FX_NEW CBC_QRCoderECB(2, 69)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(4, 43),
+ FX_NEW CBC_QRCoderECB(1, 44)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(6, 19),
+ FX_NEW CBC_QRCoderECB(2, 20)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(6, 15),
+ FX_NEW CBC_QRCoderECB(2, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(11,
+ FX_NEW CBC_QRCoderECBlocks(20, FX_NEW CBC_QRCoderECB(4, 81)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(1, 50),
+ FX_NEW CBC_QRCoderECB(4, 51)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(4, 22),
+ FX_NEW CBC_QRCoderECB(4, 23)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(3, 12),
+ FX_NEW CBC_QRCoderECB(8, 13))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(12,
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(2, 92),
+ FX_NEW CBC_QRCoderECB(2, 93)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(6, 36),
+ FX_NEW CBC_QRCoderECB(2, 37)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(4, 20),
+ FX_NEW CBC_QRCoderECB(6, 21)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(7, 14),
+ FX_NEW CBC_QRCoderECB(4, 15))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(13,
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(4, 107)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(8, 37),
+ FX_NEW CBC_QRCoderECB(1, 38)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(8, 20),
+ FX_NEW CBC_QRCoderECB(4, 21)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(12, 11),
+ FX_NEW CBC_QRCoderECB(4, 12))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(14,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(3, 115),
+ FX_NEW CBC_QRCoderECB(1, 116)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(4, 40),
+ FX_NEW CBC_QRCoderECB(5, 41)),
+ FX_NEW CBC_QRCoderECBlocks(20, FX_NEW CBC_QRCoderECB(11, 16),
+ FX_NEW CBC_QRCoderECB(5, 17)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(11, 12),
+ FX_NEW CBC_QRCoderECB(5, 13))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(15,
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(5, 87),
+ FX_NEW CBC_QRCoderECB(1, 88)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(5, 41),
+ FX_NEW CBC_QRCoderECB(5, 42)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(5, 24),
+ FX_NEW CBC_QRCoderECB(7, 25)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(11, 12),
+ FX_NEW CBC_QRCoderECB(7, 13))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(16,
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(5, 98),
+ FX_NEW CBC_QRCoderECB(1, 99)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(7, 45),
+ FX_NEW CBC_QRCoderECB(3, 46)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(15, 19),
+ FX_NEW CBC_QRCoderECB(2, 20)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(3, 15),
+ FX_NEW CBC_QRCoderECB(13, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(17,
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(1, 107),
+ FX_NEW CBC_QRCoderECB(5, 108)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(10, 46),
+ FX_NEW CBC_QRCoderECB(1, 47)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(1, 22),
+ FX_NEW CBC_QRCoderECB(15, 23)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(2, 14),
+ FX_NEW CBC_QRCoderECB(17, 15))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(18,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(5, 120),
+ FX_NEW CBC_QRCoderECB(1, 121)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(9, 43),
+ FX_NEW CBC_QRCoderECB(4, 44)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(17, 22),
+ FX_NEW CBC_QRCoderECB(1, 23)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(2, 14),
+ FX_NEW CBC_QRCoderECB(19, 15))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(19,
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(3, 113),
+ FX_NEW CBC_QRCoderECB(4, 114)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(3, 44),
+ FX_NEW CBC_QRCoderECB(11, 45)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(17, 21),
+ FX_NEW CBC_QRCoderECB(4, 22)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(9, 13),
+ FX_NEW CBC_QRCoderECB(16, 14))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(20,
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(3, 107),
+ FX_NEW CBC_QRCoderECB(5, 108)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(3, 41),
+ FX_NEW CBC_QRCoderECB(13, 42)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(15, 24),
+ FX_NEW CBC_QRCoderECB(5, 25)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(15, 15),
+ FX_NEW CBC_QRCoderECB(10, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(21,
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(4, 116),
+ FX_NEW CBC_QRCoderECB(4, 117)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(17, 42)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(17, 22),
+ FX_NEW CBC_QRCoderECB(6, 23)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(19, 16),
+ FX_NEW CBC_QRCoderECB(6, 17))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(22,
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(2, 111),
+ FX_NEW CBC_QRCoderECB(7, 112)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(17, 46)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(7, 24),
+ FX_NEW CBC_QRCoderECB(16, 25)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(34, 13))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(23,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(4, 121),
+ FX_NEW CBC_QRCoderECB(5, 122)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(4, 47),
+ FX_NEW CBC_QRCoderECB(14, 48)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(11, 24),
+ FX_NEW CBC_QRCoderECB(14, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(16, 15),
+ FX_NEW CBC_QRCoderECB(14, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(24,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(6, 117),
+ FX_NEW CBC_QRCoderECB(4, 118)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(6, 45),
+ FX_NEW CBC_QRCoderECB(14, 46)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(11, 24),
+ FX_NEW CBC_QRCoderECB(16, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(30, 16),
+ FX_NEW CBC_QRCoderECB(2, 17))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(25,
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(8, 106),
+ FX_NEW CBC_QRCoderECB(4, 107)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(8, 47),
+ FX_NEW CBC_QRCoderECB(13, 48)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(7, 24),
+ FX_NEW CBC_QRCoderECB(22, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(22, 15),
+ FX_NEW CBC_QRCoderECB(13, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(26,
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(10, 114),
+ FX_NEW CBC_QRCoderECB(2, 115)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(19, 46),
+ FX_NEW CBC_QRCoderECB(4, 47)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(28, 22),
+ FX_NEW CBC_QRCoderECB(6, 23)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(33, 16),
+ FX_NEW CBC_QRCoderECB(4, 17))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(27,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(8, 122),
+ FX_NEW CBC_QRCoderECB(4, 123)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(22, 45),
+ FX_NEW CBC_QRCoderECB(3, 46)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(8, 23),
+ FX_NEW CBC_QRCoderECB(26, 24)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(12, 15),
+ FX_NEW CBC_QRCoderECB(28, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(28,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(3, 117),
+ FX_NEW CBC_QRCoderECB(10, 118)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(3, 45),
+ FX_NEW CBC_QRCoderECB(23, 46)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(4, 24),
+ FX_NEW CBC_QRCoderECB(31, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(11, 15),
+ FX_NEW CBC_QRCoderECB(31, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(29,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(7, 116),
+ FX_NEW CBC_QRCoderECB(7, 117)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(21, 45),
+ FX_NEW CBC_QRCoderECB(7, 46)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(1, 23),
+ FX_NEW CBC_QRCoderECB(37, 24)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(19, 15),
+ FX_NEW CBC_QRCoderECB(26, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(30,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(5, 115),
+ FX_NEW CBC_QRCoderECB(10, 116)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(19, 47),
+ FX_NEW CBC_QRCoderECB(10, 48)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(15, 24),
+ FX_NEW CBC_QRCoderECB(25, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(23, 15),
+ FX_NEW CBC_QRCoderECB(25, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(31,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(13, 115),
+ FX_NEW CBC_QRCoderECB(3, 116)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(2, 46),
+ FX_NEW CBC_QRCoderECB(29, 47)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(42, 24),
+ FX_NEW CBC_QRCoderECB(1, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(23, 15),
+ FX_NEW CBC_QRCoderECB(28, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(32,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(17, 115)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(10, 46),
+ FX_NEW CBC_QRCoderECB(23, 47)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(10, 24),
+ FX_NEW CBC_QRCoderECB(35, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(19, 15),
+ FX_NEW CBC_QRCoderECB(35, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(33,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(17, 115),
+ FX_NEW CBC_QRCoderECB(1, 116)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(14, 46),
+ FX_NEW CBC_QRCoderECB(21, 47)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(29, 24),
+ FX_NEW CBC_QRCoderECB(19, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(11, 15),
+ FX_NEW CBC_QRCoderECB(46, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(34,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(13, 115),
+ FX_NEW CBC_QRCoderECB(6, 116)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(14, 46),
+ FX_NEW CBC_QRCoderECB(23, 47)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(44, 24),
+ FX_NEW CBC_QRCoderECB(7, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(59, 16),
+ FX_NEW CBC_QRCoderECB(1, 17))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(35,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(12, 121),
+ FX_NEW CBC_QRCoderECB(7, 122)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(12, 47),
+ FX_NEW CBC_QRCoderECB(26, 48)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(39, 24),
+ FX_NEW CBC_QRCoderECB(14, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(22, 15),
+ FX_NEW CBC_QRCoderECB(41, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(36,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(6, 121),
+ FX_NEW CBC_QRCoderECB(14, 122)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(6, 47),
+ FX_NEW CBC_QRCoderECB(34, 48)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(46, 24),
+ FX_NEW CBC_QRCoderECB(10, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(2, 15),
+ FX_NEW CBC_QRCoderECB(64, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(37,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(17, 122),
+ FX_NEW CBC_QRCoderECB(4, 123)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(29, 46),
+ FX_NEW CBC_QRCoderECB(14, 47)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(49, 24),
+ FX_NEW CBC_QRCoderECB(10, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(24, 15),
+ FX_NEW CBC_QRCoderECB(46, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(38,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(4, 122),
+ FX_NEW CBC_QRCoderECB(18, 123)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(13, 46),
+ FX_NEW CBC_QRCoderECB(32, 47)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(48, 24),
+ FX_NEW CBC_QRCoderECB(14, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(42, 15),
+ FX_NEW CBC_QRCoderECB(32, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(39,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(20, 117),
+ FX_NEW CBC_QRCoderECB(4, 118)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(40, 47),
+ FX_NEW CBC_QRCoderECB(7, 48)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(43, 24),
+ FX_NEW CBC_QRCoderECB(22, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(10, 15),
+ FX_NEW CBC_QRCoderECB(67, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(40,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(19, 118),
+ FX_NEW CBC_QRCoderECB(6, 119)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(18, 47),
+ FX_NEW CBC_QRCoderECB(31, 48)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(34, 24),
+ FX_NEW CBC_QRCoderECB(34, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(20, 15),
+ FX_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()
+{
+ FX_INT32 i;
+ for(i = 0; i < VERSION->GetSize(); i++) {
+ delete ( (CBC_QRCoderVersion*)(*VERSION)[i] );
+ }
+}
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRCoderVersion.h b/xfa/src/fxbarcode/qrcode/BC_QRCoderVersion.h
new file mode 100644
index 0000000000..b693dd6dd7
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRCoderVersion.h
@@ -0,0 +1,42 @@
+// 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 _BC_QRCODERVERSION_H_
+#define _BC_QRCODERVERSION_H_
+class CBC_QRCoderECBlocks;
+class CBC_CommonBitMatrix;
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRCoderVersion;
+class CBC_QRCoderVersion : public CFX_Object
+{
+private:
+ const static FX_INT32 VERSION_DECODE_INFO[34];
+ static CFX_PtrArray *VERSION;
+ FX_INT32 m_versionNumber;
+ FX_INT32 m_totalCodeWords;
+ CFX_Int32Array m_alignmentPatternCenters;
+ CFX_PtrArray m_ecBlocks;
+
+ CBC_QRCoderVersion();
+ CBC_QRCoderVersion(FX_INT32 versionNumber, CBC_QRCoderECBlocks* ecBlocks1, CBC_QRCoderECBlocks* ecBlocks2,
+ CBC_QRCoderECBlocks* ecBlocks3, CBC_QRCoderECBlocks* ecBlocks4);
+public:
+ virtual ~CBC_QRCoderVersion();
+ static void Initialize();
+ static void Finalize();
+
+ FX_INT32 GetVersionNumber();
+ FX_INT32 GetTotalCodeWords();
+ FX_INT32 GetDimensionForVersion();
+ CBC_CommonBitMatrix *BuildFunctionPattern(FX_INT32 &e);
+ CFX_Int32Array* GetAlignmentPatternCenters();
+ CBC_QRCoderECBlocks* GetECBlocksForLevel(CBC_QRCoderErrorCorrectionLevel *ecLevel);
+ static CBC_QRCoderVersion* GetVersionForNumber(FX_INT32 versionNumber, FX_INT32 &e);
+ static CBC_QRCoderVersion* GetProvisionalVersionForDimension(FX_INT32 dimension, FX_INT32 &e);
+ static CBC_QRCoderVersion* DecodeVersionInformation(FX_INT32 versionBits, FX_INT32 &e);
+ static void Destroy();
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRDataBlock.cpp b/xfa/src/fxbarcode/qrcode/BC_QRDataBlock.cpp
new file mode 100644
index 0000000000..87c14deac9
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRDataBlock.cpp
@@ -0,0 +1,104 @@
+// 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 "../barcode.h"
+#include "BC_QRCoderECBlocks.h"
+#include "BC_QRCoderECB.h"
+#include "BC_QRDataBlock.h"
+#include "BC_QRCoderVersion.h"
+CBC_QRDataBlock::CBC_QRDataBlock(FX_INT32 numDataCodewords, CFX_ByteArray *codewords)
+ : m_numDataCodewords(numDataCodewords)
+ , m_codewords(codewords)
+{
+}
+CBC_QRDataBlock::~CBC_QRDataBlock()
+{
+ if(m_codewords != NULL) {
+ delete m_codewords;
+ m_codewords = NULL;
+ }
+}
+FX_INT32 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, FX_INT32 &e)
+{
+ if(rawCodewords->GetSize() != version->GetTotalCodeWords()) {
+ e = BCExceptionIllegalArgument;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ CBC_QRCoderECBlocks *ecBlocks = version->GetECBlocksForLevel(ecLevel);
+ FX_INT32 totalBlocks = 0;
+ CFX_PtrArray* ecBlockArray = ecBlocks->GetECBlocks();
+ FX_INT32 i = 0;
+ for(i = 0; i < ecBlockArray->GetSize(); i++) {
+ totalBlocks += ((CBC_QRCoderECB*)(*ecBlockArray)[i])->GetCount();
+ }
+ CFX_PtrArray *datablock = FX_NEW CFX_PtrArray();
+ datablock->SetSize(totalBlocks);
+ CBC_AutoPtr<CFX_PtrArray > result(datablock);
+ FX_INT32 numResultBlocks = 0;
+ for(FX_INT32 j = 0; j < ecBlockArray->GetSize(); j++) {
+ CBC_QRCoderECB *ecBlock = (CBC_QRCoderECB*)(*ecBlockArray)[j];
+ for(FX_INT32 k = 0; k < ecBlock->GetCount(); k++) {
+ FX_INT32 numDataCodewords = ecBlock->GetDataCodeWords();
+ FX_INT32 numBlockCodewords = ecBlocks->GetECCodeWordsPerBlock() + numDataCodewords;
+ CFX_ByteArray *bytearray = FX_NEW CFX_ByteArray();
+ bytearray->SetSize(numBlockCodewords);
+ (*result)[numResultBlocks++] = FX_NEW CBC_QRDataBlock(numDataCodewords, bytearray);
+ }
+ }
+ FX_INT32 shorterBlocksTotalCodewords = ((CBC_QRDataBlock*)(*result)[0])->m_codewords->GetSize();
+ FX_INT32 longerBlocksStartAt = result->GetSize() - 1;
+ while(longerBlocksStartAt >= 0) {
+ FX_INT32 numCodewords = ((CBC_QRDataBlock*)(*result)[longerBlocksStartAt])->m_codewords->GetSize();
+ if(numCodewords == shorterBlocksTotalCodewords) {
+ break;
+ }
+ longerBlocksStartAt--;
+ }
+ longerBlocksStartAt++;
+ FX_INT32 shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks->GetECCodeWordsPerBlock();
+ FX_INT32 rawCodewordsOffset = 0;
+ FX_INT32 x = 0;
+ for(FX_INT32 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++];
+ }
+ FX_INT32 max = ((CBC_QRDataBlock*)(*result)[0])->m_codewords->GetSize();
+ for(i = shorterBlocksNumDataCodewords; i < max; i++) {
+ for(FX_INT32 y = 0; y < numResultBlocks; y++) {
+ FX_INT32 iOffset = y < longerBlocksStartAt ? i : i + 1;
+ (*(((CBC_QRDataBlock*)(*result)[y])->m_codewords))[iOffset] = (*rawCodewords)[rawCodewordsOffset++];
+ }
+ }
+ return result.release();
+}
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRDataBlock.h b/xfa/src/fxbarcode/qrcode/BC_QRDataBlock.h
new file mode 100644
index 0000000000..4f68c7a9f3
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRDataBlock.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 _BC_QRDATABLOCK_H_
+#define _BC_QRDATABLOCK_H_
+class CBC_QRCoderVersion;
+class CBC_QRCoderECBlocks;
+class CBC_QRCoderECB;
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRDataBlock;
+class CBC_QRDataBlock : public CFX_Object
+{
+private:
+ FX_INT32 m_numDataCodewords;
+ CFX_ByteArray *m_codewords;
+ CBC_QRDataBlock(FX_INT32 numDataCodewords, CFX_ByteArray *codewords);
+public:
+ virtual ~CBC_QRDataBlock();
+ FX_INT32 GetNumDataCodewords();
+ CFX_ByteArray* GetCodewords();
+ static CFX_PtrArray *GetDataBlocks(CFX_ByteArray* rawCodewords,
+ CBC_QRCoderVersion *version, CBC_QRCoderErrorCorrectionLevel* ecLevel, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRDataMask.cpp b/xfa/src/fxbarcode/qrcode/BC_QRDataMask.cpp
new file mode 100644
index 0000000000..fd81b20f1b
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRDataMask.cpp
@@ -0,0 +1,149 @@
+// 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 "../barcode.h"
+#include "../common/BC_CommonBitMatrix.h"
+#include "BC_QRDataMask.h"
+static FX_INT32 N_DATA_MASKS = 0;
+CFX_PtrArray* CBC_QRDataMask::DATA_MASKS = NULL;
+void CBC_QRDataMask::Initialize()
+{
+ DATA_MASKS = FX_NEW CFX_PtrArray();
+ N_DATA_MASKS = BuildDataMasks();
+}
+void CBC_QRDataMask::Finalize()
+{
+ Destroy();
+ delete DATA_MASKS;
+}
+void CBC_QRDataMask::Destroy()
+{
+ FX_INT32 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, FX_INT32 dimension)
+{
+ for(FX_INT32 i = 0; i < dimension; i++) {
+ for(FX_INT32 j = 0; j < dimension; j++) {
+ if(IsMasked(i, j)) {
+ bits->Flip(j, i);
+ }
+ }
+ }
+}
+CBC_QRDataMask* CBC_QRDataMask::ForReference(FX_INT32 reference, FX_INT32 &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(FX_INT32 x, FX_INT32 y)
+ {
+ return ((x + y) % 2) == 0;
+ }
+};
+class DataMask001 : public CBC_QRDataMask
+{
+public:
+ FX_BOOL IsMasked(FX_INT32 x, FX_INT32 y)
+ {
+ return (x % 2) == 0;
+ }
+};
+class DataMask010 : public CBC_QRDataMask
+{
+public:
+ FX_BOOL IsMasked(FX_INT32 x, FX_INT32 y)
+ {
+ return y % 3 == 0;
+ }
+};
+class DataMask011 : public CBC_QRDataMask
+{
+public:
+ FX_BOOL IsMasked(FX_INT32 x, FX_INT32 y)
+ {
+ return (x + y) % 3 == 0;
+ }
+};
+class DataMask100 : public CBC_QRDataMask
+{
+public:
+ FX_BOOL IsMasked(FX_INT32 x, FX_INT32 y)
+ {
+ return (((x >> 1) + (y / 3)) % 2) == 0;
+ }
+};
+class DataMask101 : public CBC_QRDataMask
+{
+public:
+ FX_BOOL IsMasked(FX_INT32 x, FX_INT32 y)
+ {
+ size_t temp = x * y;
+ return (temp % 2) + (temp % 3) == 0;
+ }
+};
+class DataMask110 : public CBC_QRDataMask
+{
+public:
+ FX_BOOL IsMasked(FX_INT32 x, FX_INT32 y)
+ {
+ size_t temp = x * y;
+ return (((temp % 2) + (temp % 3)) % 2) == 0;
+ }
+};
+class DataMask111 : public CBC_QRDataMask
+{
+public:
+ FX_BOOL IsMasked(FX_INT32 x, FX_INT32 y)
+ {
+ return ((((x + y) % 2) + ((x * y) % 3)) % 2) == 0;
+ }
+};
+FX_INT32 CBC_QRDataMask::BuildDataMasks()
+{
+ DATA_MASKS->Add(FX_NEW DataMask000);
+ DATA_MASKS->Add(FX_NEW DataMask001);
+ DATA_MASKS->Add(FX_NEW DataMask010);
+ DATA_MASKS->Add(FX_NEW DataMask011);
+ DATA_MASKS->Add(FX_NEW DataMask100);
+ DATA_MASKS->Add(FX_NEW DataMask101);
+ DATA_MASKS->Add(FX_NEW DataMask110);
+ DATA_MASKS->Add(FX_NEW DataMask111);
+ return DATA_MASKS->GetSize();
+}
+CBC_QRDataMask::CBC_QRDataMask()
+{
+}
+CBC_QRDataMask::~CBC_QRDataMask()
+{
+}
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRDataMask.h b/xfa/src/fxbarcode/qrcode/BC_QRDataMask.h
new file mode 100644
index 0000000000..6fcc09d556
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRDataMask.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 _BC_QRDATAMASK_H_
+#define _BC_QRDATAMASK_H_
+class CBC_CommonBitMatrix;
+class CBC_QRDataMask;
+class CBC_QRDataMask : public CFX_Object
+{
+public:
+ static CFX_PtrArray *DATA_MASKS;
+ CBC_QRDataMask();
+ virtual ~CBC_QRDataMask();
+ static void Initialize();
+ static void Finalize();
+ virtual FX_BOOL IsMasked(FX_INT32 i, FX_INT32 j) = 0;
+ void UnmaskBitMatirx(CBC_CommonBitMatrix *bits, FX_INT32 dimension);
+ static CBC_QRDataMask* ForReference(FX_INT32 reference, FX_INT32 &e);
+ static FX_INT32 BuildDataMasks();
+ static void Destroy();
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.cpp b/xfa/src/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.cpp
new file mode 100644
index 0000000000..0fe4d1b2b6
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.cpp
@@ -0,0 +1,254 @@
+// 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 "../barcode.h"
+#include "../BC_UtilCodingConvert.h"
+#include "../common/BC_CommonBitSource.h"
+#include "../common/BC_CommonECI.h"
+#include "../common/BC_CommonCharacterSetECI.h"
+#include "../common/BC_CommonDecoderResult.h"
+#include "BC_QRCoderMode.h"
+#include "BC_QRDecodedBitStreamParser.h"
+FX_LPCSTR 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, FX_INT32 byteModeDecode, FX_INT32 &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 {
+ FX_INT32 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) {
+ FX_INT32 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);
+ }
+ FX_INT32 numBits = mode->GetCharacterCountBits(version, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 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 = FX_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, FX_INT32 count, FX_INT32 &e)
+{
+ CFX_ByteString buffer;
+ FX_INT32 offset = 0;
+ while (count > 0) {
+ FX_INT32 twoBytes = bits->ReadBits(13, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 assembledTwoBytes = ((twoBytes / 0x060) << 8) | (twoBytes % 0x060);
+ if (assembledTwoBytes <= 0x0095d) {
+ assembledTwoBytes += 0x0a1a1;
+ } else {
+ assembledTwoBytes += 0x0a6a1;
+ }
+ buffer += (FX_BYTE) (assembledTwoBytes >> 8);
+ buffer += (FX_BYTE) assembledTwoBytes;
+ count--;
+ }
+ CBC_UtilCodingConvert::LocaleToUtf8(buffer, result);
+}
+void CBC_QRDecodedBitStreamParser::DecodeKanjiSegment(CBC_CommonBitSource* bits, CFX_ByteString &result, FX_INT32 count, FX_INT32 &e)
+{
+ CFX_ByteString buffer;
+ while (count > 0) {
+ FX_INT32 twoBytes = bits->ReadBits(13, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 assembledTwoBytes = ((twoBytes / 0x0c0) << 8) | (twoBytes % 0x0c0);
+ if (assembledTwoBytes <= 0x01f00) {
+ assembledTwoBytes += 0x08140;
+ } else {
+ assembledTwoBytes += 0x0c140;
+ }
+ buffer += (FX_BYTE) (assembledTwoBytes >> 8);
+ buffer += (FX_BYTE) assembledTwoBytes;
+ count--;
+ }
+ CBC_UtilCodingConvert::LocaleToUtf8(buffer, result);
+}
+void CBC_QRDecodedBitStreamParser::DecodeByteSegment(CBC_CommonBitSource* bits, CFX_ByteString &result, FX_INT32 count,
+ CBC_CommonCharacterSetECI *currentCharacterSetECI,
+ CFX_Int32Array *byteSegments, FX_INT32 byteModeDecode, FX_INT32 &e)
+{
+ if(count < 0) {
+ e = BCExceptionNotFound;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ if((count << 3) > bits->Available()) {
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_BYTE *readBytes = FX_Alloc(FX_BYTE, count);
+ FXSYS_memset32(readBytes, 0x00, count);
+ for(FX_INT32 i = 0; i < count; i++) {
+ readBytes[i] = (FX_BYTE) 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, FX_INT32 count, FX_BOOL fac1InEffect, FX_INT32 &e)
+{
+ FX_INT32 start = result.GetLength();
+ while(count > 1) {
+ FX_INT32 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) {
+ FX_INT32 itemp = bits->ReadBits(6, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[itemp]);
+ }
+ if(fac1InEffect) {
+ for(FX_INT32 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, FX_INT32 count, FX_INT32 &e)
+{
+ while(count >= 3) {
+ FX_INT32 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) {
+ FX_INT32 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) {
+ FX_INT32 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;
+}
+FX_INT32 CBC_QRDecodedBitStreamParser::ParseECIValue(CBC_CommonBitSource* bits, FX_INT32 &e)
+{
+ FX_INT32 firstByte = bits->ReadBits(8, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ if((firstByte & 0x80) == 0) {
+ return firstByte & 0x7f;
+ } else if((firstByte & 0xc0) == 0x80) {
+ FX_INT32 secondByte = bits->ReadBits(8, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ return ((firstByte & 0x3f) << 8) | secondByte;
+ } else if((firstByte & 0xe0) == 0xc0) {
+ FX_INT32 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/src/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.h b/xfa/src/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.h
new file mode 100644
index 0000000000..b64485f788
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRDecodedBitStreamParser.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 _BC_QRDECODEDBITSTREAMPARSER_H_
+#define _BC_QRDECODEDBITSTREAMPARSER_H_
+class CBC_CommonDecoderResult;
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_CommonBitSource;
+class CBC_QRCoderVersion;
+class CBC_CommonCharacterSetECI;
+class CBC_QRDecodedBitStreamParser;
+class CBC_QRDecodedBitStreamParser : public CFX_Object
+{
+private:
+ const static FX_CHAR ALPHANUMERIC_CHARS[45];
+ static FX_LPCSTR UTF_8;
+ CBC_QRDecodedBitStreamParser();
+public:
+ virtual ~CBC_QRDecodedBitStreamParser();
+ static CBC_CommonDecoderResult* Decode(CFX_ByteArray *bytes, CBC_QRCoderVersion *version,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel, FX_INT32 byteModeDecode, FX_INT32 &e);
+
+ static const CFX_ByteString GuessEncoding(CFX_ByteArray* bytes);
+ static FX_INT32 ParseECIValue(CBC_CommonBitSource* bits, FX_INT32 &e);
+ static void DecodeGBKSegment(CBC_CommonBitSource* bits, CFX_ByteString &result, FX_INT32 count, FX_INT32 &e);
+ static void DecodeKanjiSegment(CBC_CommonBitSource* bits, CFX_ByteString &result, FX_INT32 count, FX_INT32 &e);
+ static void DecodeNumericSegment(CBC_CommonBitSource* bits, CFX_ByteString &result, FX_INT32 count, FX_INT32 &e);
+ static void DecodeAlphanumericSegment(CBC_CommonBitSource* bits, CFX_ByteString &result, FX_INT32 count, FX_BOOL fac1InEffect, FX_INT32 &e);
+ static void DecodeByteSegment(CBC_CommonBitSource* bits, CFX_ByteString &result, FX_INT32 count, CBC_CommonCharacterSetECI *currentCharacterSetECI,
+ CFX_Int32Array *byteSegments, FX_INT32 byteModeDecode, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRDetector.cpp b/xfa/src/fxbarcode/qrcode/BC_QRDetector.cpp
new file mode 100644
index 0000000000..01d90832b9
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRDetector.cpp
@@ -0,0 +1,264 @@
+// 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 "../barcode.h"
+#include "../common/BC_CommonBitMatrix.h"
+#include "../BC_ResultPoint.h"
+#include "BC_QRFinderPattern.h"
+#include "BC_QRCoderVersion.h"
+#include "BC_FinderPatternInfo.h"
+#include "BC_QRGridSampler.h"
+#include "BC_QRAlignmentPatternFinder.h"
+#include "BC_QRFinderPatternFinder.h"
+#include "BC_QRDetectorResult.h"
+#include "BC_QRDetector.h"
+CBC_QRDetector::CBC_QRDetector(CBC_CommonBitMatrix *image): m_image(image)
+{
+}
+CBC_QRDetector::~CBC_QRDetector()
+{
+}
+CBC_QRDetectorResult *CBC_QRDetector::Detect(FX_INT32 hints, FX_INT32 &e)
+{
+ CBC_QRFinderPatternFinder finder(m_image);
+ CBC_QRFinderPatternInfo* qpi = finder.Find(hints, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_QRFinderPatternInfo> info(qpi);
+ CBC_QRDetectorResult* qdr = ProcessFinderPatternInfo(info.get(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return qdr;
+}
+CBC_QRDetectorResult* CBC_QRDetector::ProcessFinderPatternInfo(CBC_QRFinderPatternInfo *info, FX_INT32 &e)
+{
+ CBC_AutoPtr<CBC_QRFinderPattern> topLeft(info->GetTopLeft());
+ CBC_AutoPtr<CBC_QRFinderPattern> topRight(info->GetTopRight());
+ CBC_AutoPtr<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);
+ }
+ FX_INT32 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);
+ FX_INT32 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()));
+ FX_INT32 estAlignmentX = (FX_INT32)xtemp ;
+ FX_FLOAT ytemp = (topLeft->GetY() + correctionToTopLeft * (bottomRightY - topLeft->GetY()));
+ FX_INT32 estAlignmentY = (FX_INT32)ytemp;
+ for(FX_INT32 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 = FX_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 FX_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,
+ FX_INT32 dimension, FX_INT32 &e)
+{
+ FX_FLOAT dimMinusThree = (FX_FLOAT) dimension - 3.5f;
+ FX_FLOAT bottomRightX;
+ FX_FLOAT bottomRightY;
+ FX_FLOAT sourceBottomRightX;
+ FX_FLOAT sourceBottomRightY;
+ if (alignmentPattern != NULL) {
+ 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;
+}
+FX_INT32 CBC_QRDetector::ComputeDimension(CBC_ResultPoint *topLeft, CBC_ResultPoint *topRight,
+ CBC_ResultPoint *bottomLeft, FX_FLOAT moduleSize, FX_INT32 &e)
+{
+ FX_INT32 tltrCentersDimension = Round(CBC_QRFinderPatternFinder::Distance(topLeft, topRight) / moduleSize);
+ FX_INT32 tlblCentersDimension = Round(CBC_QRFinderPatternFinder::Distance(topLeft, bottomLeft) / moduleSize);
+ FX_INT32 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((FX_INT32) pattern->GetX(),
+ (FX_INT32) pattern->GetY(),
+ (FX_INT32) otherPattern->GetX(),
+ (FX_INT32) otherPattern->GetY());
+ FX_FLOAT moduleSizeEst2 = SizeOfBlackWhiteBlackRunBothWays((FX_INT32) otherPattern->GetX(),
+ (FX_INT32) otherPattern->GetY(),
+ (FX_INT32) pattern->GetX(),
+ (FX_INT32) pattern->GetY());
+ if (FXSYS_isnan(moduleSizeEst1)) {
+ return moduleSizeEst2;
+ }
+ if (FXSYS_isnan(moduleSizeEst2)) {
+ return moduleSizeEst1;
+ }
+ return (moduleSizeEst1 + moduleSizeEst2) / 14.0f;
+}
+FX_INT32 CBC_QRDetector::Round(FX_FLOAT d)
+{
+ return (FX_INT32)(d + 0.5f);
+}
+FX_FLOAT CBC_QRDetector::SizeOfBlackWhiteBlackRunBothWays(FX_INT32 fromX, FX_INT32 fromY, FX_INT32 toX, FX_INT32 toY)
+{
+ FX_FLOAT result = SizeOfBlackWhiteBlackRun(fromX, fromY, toX, toY);
+ FX_INT32 otherToX = fromX - (toX - fromX);
+ if (otherToX < 0) {
+ otherToX = -1;
+ } else if (otherToX >= m_image->GetWidth()) {
+ otherToX = m_image->GetWidth();
+ }
+ FX_INT32 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(FX_INT32 fromX, FX_INT32 fromY, FX_INT32 toX, FX_INT32 toY)
+{
+ FX_BOOL steep = FXSYS_abs(toY - fromY) > FXSYS_abs(toX - fromX);
+ if (steep) {
+ FX_INT32 temp = fromX;
+ fromX = fromY;
+ fromY = temp;
+ temp = toX;
+ toX = toY;
+ toY = temp;
+ }
+ FX_INT32 dx = FXSYS_abs(toX - fromX);
+ FX_INT32 dy = FXSYS_abs(toY - fromY);
+ FX_INT32 error = -dx >> 1;
+ FX_INT32 ystep = fromY < toY ? 1 : -1;
+ FX_INT32 xstep = fromX < toX ? 1 : -1;
+ FX_INT32 state = 0;
+ for (FX_INT32 x = fromX, y = fromY; x != toX; x += xstep) {
+ FX_INT32 realX = steep ? y : x;
+ FX_INT32 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) {
+ FX_INT32 diffX = x - fromX;
+ FX_INT32 diffY = y - fromY;
+ return (FX_FLOAT) sqrt((double) (diffX * diffX + diffY * diffY));
+ }
+ error += dy;
+ if (error > 0) {
+ y += ystep;
+ error -= dx;
+ }
+ }
+ FX_INT32 diffX = toX - fromX;
+ FX_INT32 diffY = toY - fromY;
+ return (FX_FLOAT) sqrt((double) (diffX * diffX + diffY * diffY));
+}
+CBC_QRAlignmentPattern *CBC_QRDetector::FindAlignmentInRegion(FX_FLOAT overallEstModuleSize, FX_INT32 estAlignmentX,
+ FX_INT32 estAlignmentY, FX_FLOAT allowanceFactor, FX_INT32 &e)
+{
+ FX_INT32 allowance = (FX_INT32) (allowanceFactor * overallEstModuleSize);
+ FX_INT32 alignmentAreaLeftX = FX_MAX(0, estAlignmentX - allowance);
+ FX_INT32 alignmentAreaRightX = FX_MIN(m_image->GetWidth() - 1, estAlignmentX + allowance);
+ if (alignmentAreaRightX - alignmentAreaLeftX < overallEstModuleSize * 3) {
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ FX_INT32 alignmentAreaTopY = FX_MAX(0, estAlignmentY - allowance);
+ FX_INT32 alignmentAreaBottomY = FX_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/src/fxbarcode/qrcode/BC_QRDetector.h b/xfa/src/fxbarcode/qrcode/BC_QRDetector.h
new file mode 100644
index 0000000000..60c301cb7b
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRDetector.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 _BC_QRDETECTOR_H_
+#define _BC_QRDETECTOR_H_
+class CBC_ResultPoint;
+class CBC_CommonBitMatrix;
+class CBC_QRDetectorResult;
+class CBC_QRFinderPatternInfo;
+class CBC_QRAlignmentPattern;
+class CBC_QRFinderPatternFinder;
+class CBC_QRCoderVersion;
+class CBC_QRGridSampler;
+class CBC_QRAlignmentPatternFinder;
+class CBC_QRAlignmentPattern;
+class CBC_QRDetector;
+class CBC_QRDetector
+{
+private:
+ CBC_CommonBitMatrix *m_image;
+public:
+ CBC_QRDetector(CBC_CommonBitMatrix *image);
+ virtual ~CBC_QRDetector();
+
+ CBC_CommonBitMatrix* GetImage();
+ CBC_QRDetectorResult* Detect(FX_INT32 hints, FX_INT32 &e);
+ CBC_QRDetectorResult* ProcessFinderPatternInfo(CBC_QRFinderPatternInfo *info, FX_INT32 &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(FX_INT32 fromX, FX_INT32 fromY, FX_INT32 toX, FX_INT32 toY);
+ FX_FLOAT SizeOfBlackWhiteBlackRun(FX_INT32 fromX, FX_INT32 fromY, FX_INT32 toX, FX_INT32 toY);
+ CBC_QRAlignmentPattern* FindAlignmentInRegion(FX_FLOAT overallEstModuleSize, FX_INT32 estAlignmentX, FX_INT32 estAlignmentY, FX_FLOAT allowanceFactor, FX_INT32 &e);
+ static FX_INT32 Round(FX_FLOAT d);
+ static FX_INT32 ComputeDimension(CBC_ResultPoint *topLeft, CBC_ResultPoint *topRight, CBC_ResultPoint *bottomLeft, FX_FLOAT moduleSize, FX_INT32 &e);
+ static CBC_CommonBitMatrix* SampleGrid(CBC_CommonBitMatrix *image, CBC_ResultPoint *topLeft, CBC_ResultPoint *topRight,
+ CBC_ResultPoint *bottomLeft, CBC_ResultPoint* alignmentPattern, FX_INT32 dimension, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRDetectorResult.cpp b/xfa/src/fxbarcode/qrcode/BC_QRDetectorResult.cpp
new file mode 100644
index 0000000000..369dc3a527
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRDetectorResult.cpp
@@ -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
+// 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 "../barcode.h"
+#include "../BC_ResultPoint.h"
+#include "../common/BC_CommonBitMatrix.h"
+#include "BC_QRDetectorResult.h"
+CBC_QRDetectorResult::CBC_QRDetectorResult(CBC_CommonBitMatrix *bits, CFX_PtrArray *points):
+ m_bits(bits), m_points(points)
+{
+}
+CBC_QRDetectorResult::~CBC_QRDetectorResult()
+{
+ for(FX_INT32 i = 0; i < m_points->GetSize(); i++) {
+ delete (CBC_ResultPoint*) (*m_points)[i];
+ }
+ m_points->RemoveAll();
+ delete m_points;
+ m_points = NULL;
+ if(m_bits != NULL) {
+ delete m_bits;
+ }
+ m_bits = NULL;
+}
+CBC_CommonBitMatrix* CBC_QRDetectorResult::GetBits()
+{
+ return m_bits;
+}
+CFX_PtrArray *CBC_QRDetectorResult::GetPoints()
+{
+ return m_points;
+}
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRDetectorResult.h b/xfa/src/fxbarcode/qrcode/BC_QRDetectorResult.h
new file mode 100644
index 0000000000..13f6d3dc46
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRDetectorResult.h
@@ -0,0 +1,23 @@
+// 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 _BC_QRDETECTORRESULT_H_
+#define _BC_QRDETECTORRESULT_H_
+class CBC_CommonBitMatrix;
+class CBC_ResultPoint;
+class CBC_QRDetectorResult;
+class CBC_QRDetectorResult : public CFX_Object
+{
+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
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRFinderPattern.cpp b/xfa/src/fxbarcode/qrcode/BC_QRFinderPattern.cpp
new file mode 100644
index 0000000000..8d1385e99a
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRFinderPattern.cpp
@@ -0,0 +1,71 @@
+// 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 "../barcode.h"
+#include "../BC_ResultPoint.h"
+#include "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 = FX_NEW CBC_QRFinderPattern(m_x, m_y, m_estimatedModuleSize);
+ temp->m_count = m_count;
+ return temp;
+}
+FX_FLOAT CBC_QRFinderPattern::GetEstimatedModuleSize()
+{
+ return m_estimatedModuleSize;
+}
+FX_INT32 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/src/fxbarcode/qrcode/BC_QRFinderPattern.h b/xfa/src/fxbarcode/qrcode/BC_QRFinderPattern.h
new file mode 100644
index 0000000000..af88a727d9
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRFinderPattern.h
@@ -0,0 +1,29 @@
+// 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 _BC_QRFINDERPATTERN_H_
+#define _BC_QRFINDERPATTERN_H_
+class CBC_ResultPoint;
+class CBC_QRFinderPattern;
+class CBC_QRFinderPattern : public CBC_ResultPoint
+{
+private:
+ FX_FLOAT m_estimatedModuleSize;
+ FX_INT32 m_count;
+public:
+ CBC_QRFinderPattern(FX_FLOAT x, FX_FLOAT posY, FX_FLOAT estimatedModuleSize);
+ virtual ~CBC_QRFinderPattern();
+
+ FX_INT32 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
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRFinderPatternFinder.cpp b/xfa/src/fxbarcode/qrcode/BC_QRFinderPatternFinder.cpp
new file mode 100644
index 0000000000..da2d1231f8
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRFinderPatternFinder.cpp
@@ -0,0 +1,451 @@
+// 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 "../barcode.h"
+#include "../BC_ResultPoint.h"
+#include "../common/BC_CommonBitMatrix.h"
+#include "BC_QRFinderPatternFinder.h"
+#include "BC_FinderPatternInfo.h"
+#include "BC_QRFinderPattern.h"
+const FX_INT32 CBC_QRFinderPatternFinder::CENTER_QUORUM = 2;
+const FX_INT32 CBC_QRFinderPatternFinder::MIN_SKIP = 3;
+const FX_INT32 CBC_QRFinderPatternFinder::MAX_MODULES = 57;
+const FX_INT32 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(FX_INT32 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)
+ {
+ }
+ FX_INT32 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:
+ FX_INT32 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(FX_INT32 hint, FX_INT32 &e)
+{
+ FX_INT32 maxI = m_image->GetHeight();
+ FX_INT32 maxJ = m_image->GetWidth();
+ FX_INT32 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(FX_INT32 i = iSkip - 1; i < maxI && !done; i += iSkip) {
+ stateCount[0] = 0;
+ stateCount[1] = 0;
+ stateCount[2] = 0;
+ stateCount[3] = 0;
+ stateCount[4] = 0;
+ FX_INT32 currentState = 0;
+ for(FX_INT32 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 {
+ FX_INT32 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();
+ }
+ }
+ }
+ }
+ CFX_PtrArray* ptr = SelectBestpatterns(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CFX_PtrArray > patternInfo(ptr);
+ 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, FX_INT32 end)
+{
+ return (FX_FLOAT)(end - stateCount[4] - stateCount[3]) - stateCount[2] / 2.0f;
+}
+FX_BOOL CBC_QRFinderPatternFinder::FoundPatternCross(const CFX_Int32Array &stateCount)
+{
+ FX_INT32 totalModuleSize = 0;
+ for (FX_INT32 i = 0; i < 5; i++) {
+ FX_INT32 count = stateCount[i];
+ if (count == 0) {
+ return FALSE;
+ }
+ totalModuleSize += count;
+ }
+ if (totalModuleSize < 7) {
+ return FALSE;
+ }
+ FX_INT32 moduleSize = (totalModuleSize << INTEGER_MATH_SHIFT) / 7;
+ FX_INT32 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(FX_INT32 startI, FX_INT32 centerJ, FX_INT32 maxCount,
+ FX_INT32 originalStateCountTotal)
+{
+ CBC_CommonBitMatrix *image = m_image;
+ FX_INT32 maxI = image->GetHeight();
+ CFX_Int32Array &stateCount = GetCrossCheckStateCount();
+ FX_INT32 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();
+ }
+ FX_INT32 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(FX_INT32 startJ, FX_INT32 centerI, FX_INT32 maxCount, FX_INT32 originalStateCountTotal)
+{
+ CBC_CommonBitMatrix *image = m_image;
+ FX_INT32 maxJ = image->GetWidth();
+ CFX_Int32Array &stateCount = GetCrossCheckStateCount();
+ FX_INT32 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();
+ }
+ FX_INT32 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, FX_INT32 i, FX_INT32 j)
+{
+ FX_INT32 stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
+ FX_FLOAT centerJ = CenterFromEnd(stateCount, j);
+ FX_FLOAT centerI = CrossCheckVertical(i, (FX_INT32) centerJ, stateCount[2], stateCountTotal);
+ if(!FXSYS_isnan(centerI)) {
+ centerJ = CrossCheckHorizontal((FX_INT32) centerJ, (FX_INT32) centerI, stateCount[2], stateCountTotal);
+ if(!FXSYS_isnan(centerJ)) {
+ FX_FLOAT estimatedModuleSize = (FX_FLOAT) stateCountTotal / 7.0f;
+ FX_BOOL found = FALSE;
+ FX_INT32 max = m_possibleCenters.GetSize();
+ for(FX_INT32 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(FX_NEW CBC_QRFinderPattern(centerJ, centerI, estimatedModuleSize));
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+FX_INT32 CBC_QRFinderPatternFinder::FindRowSkip()
+{
+ FX_INT32 max = m_possibleCenters.GetSize();
+ if (max <= 1) {
+ return 0;
+ }
+ FinderPattern *firstConfirmedCenter = NULL;
+ for (FX_INT32 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 (FX_INT32) ((fabs(firstConfirmedCenter->GetX() - center->GetX()) -
+ fabs(firstConfirmedCenter->GetY() - center->GetY())) / 2);
+ }
+ }
+ }
+ return 0;
+}
+FX_BOOL CBC_QRFinderPatternFinder::HaveMultiplyConfirmedCenters()
+{
+ FX_INT32 confirmedCount = 0;
+ FX_FLOAT totalModuleSize = 0.0f;
+ FX_INT32 max = m_possibleCenters.GetSize();
+ FX_INT32 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(FX_LPVOID a, FX_LPVOID b)
+{
+ return ((CBC_QRFinderPattern*)b)->GetCount() < ((CBC_QRFinderPattern*)a)->GetCount();
+}
+CFX_PtrArray *CBC_QRFinderPatternFinder::SelectBestpatterns(FX_INT32 &e)
+{
+ FX_INT32 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(FX_INT32 i = 0; i < startSize; i++) {
+ totalModuleSize += ((CBC_QRFinderPattern*)m_possibleCenters[i])->GetEstimatedModuleSize();
+ }
+ average = totalModuleSize / (FX_FLOAT)startSize;
+ for(FX_INT32 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 = FX_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/src/fxbarcode/qrcode/BC_QRFinderPatternFinder.h b/xfa/src/fxbarcode/qrcode/BC_QRFinderPatternFinder.h
new file mode 100644
index 0000000000..7470b553ee
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRFinderPatternFinder.h
@@ -0,0 +1,45 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRFINDERPATTERNFINDER_H_
+#define _BC_QRFINDERPATTERNFINDER_H_
+class CBC_CommonBitMatrix;
+class CBC_QRFinderPattern;
+class CBC_ResultPoint;
+class CBC_QRFinderPatternInfo;
+class CBC_QRFinderPatternFinder;
+class CBC_QRFinderPatternFinder : public CFX_Object
+{
+private:
+ const static FX_INT32 CENTER_QUORUM;
+ const static FX_INT32 MIN_SKIP;
+ const static FX_INT32 MAX_MODULES;
+ const static FX_INT32 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();
+ FX_INT32 FindRowSkip();
+ CBC_CommonBitMatrix* GetImage();
+ CBC_QRFinderPatternInfo* Find(FX_INT32 hint, FX_INT32 &e);
+
+ CFX_Int32Array &GetCrossCheckStateCount();
+ CFX_PtrArray *GetPossibleCenters();
+ CFX_PtrArray *SelectBestpatterns(FX_INT32 &e);
+
+ FX_BOOL HandlePossibleCenter(const CFX_Int32Array &stateCount, FX_INT32 i, FX_INT32 j);
+ FX_BOOL HaveMultiplyConfirmedCenters();
+ FX_FLOAT CenterFromEnd(const CFX_Int32Array &stateCount, FX_INT32 end);
+ FX_FLOAT CrossCheckVertical(FX_INT32 startI, FX_INT32 centerJ, FX_INT32 maxCount, FX_INT32 originalStateCountTotal);
+ FX_FLOAT CrossCheckHorizontal(FX_INT32 startJ, FX_INT32 CenterI, FX_INT32 maxCOunt, FX_INT32 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
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRGridSampler.cpp b/xfa/src/fxbarcode/qrcode/BC_QRGridSampler.cpp
new file mode 100644
index 0000000000..8783078690
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRGridSampler.cpp
@@ -0,0 +1,128 @@
+// 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 "../barcode.h"
+#include "../common/BC_CommonPerspectiveTransform.h"
+#include "../common/BC_CommonBitMatrix.h"
+#include "BC_QRGridSampler.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, FX_INT32 &e)
+{
+ FX_INT32 width = image->GetWidth();
+ FX_INT32 height = image->GetHeight();
+ FX_BOOL nudged = TRUE;
+ FX_INT32 offset;
+ for (offset = 0; offset < points->GetSize() && nudged; offset += 2) {
+ FX_INT32 x = (FX_INT32) (*points)[offset];
+ FX_INT32 y = (FX_INT32) (*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) {
+ FX_INT32 x = (FX_INT32) (*points)[offset];
+ FX_INT32 y = (FX_INT32) (*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, FX_INT32 dimensionX, FX_INT32 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, FX_INT32 &e)
+{
+ CBC_AutoPtr<CBC_CommonPerspectiveTransform> transform(CBC_CommonPerspectiveTransform::QuadrilateralToQuadrilateral(
+ p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY,
+ p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY));
+ CBC_CommonBitMatrix *tempBitM = FX_NEW CBC_CommonBitMatrix();
+ tempBitM->Init(dimensionX, dimensionY);
+ CBC_AutoPtr<CBC_CommonBitMatrix> bits(tempBitM);
+ CFX_FloatArray points;
+ points.SetSize(dimensionX << 1);
+ for (FX_INT32 y = 0; y < dimensionY; y++) {
+ FX_INT32 max = points.GetSize();
+ FX_FLOAT iValue = (FX_FLOAT) (y + 0.5f);
+ FX_INT32 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((FX_INT32) points[x], (FX_INT32) points[x + 1])) {
+ bits->Set(x >> 1, y);
+ }
+ }
+ }
+ return bits.release();
+}
diff --git a/xfa/src/fxbarcode/qrcode/BC_QRGridSampler.h b/xfa/src/fxbarcode/qrcode/BC_QRGridSampler.h
new file mode 100644
index 0000000000..0b8c7d3ab7
--- /dev/null
+++ b/xfa/src/fxbarcode/qrcode/BC_QRGridSampler.h
@@ -0,0 +1,33 @@
+// 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 _BC_QRGRIDSAMPLER_H_
+#define _BC_QRGRIDSAMPLER_H_
+class CBC_CommonBitMatrix;
+class CBC_CommonPerspectiveTransform;
+class CBC_CommonDefaultGridSampler;
+class CBC_QRGridSampler;
+class CBC_QRGridSampler
+{
+private:
+ static CBC_QRGridSampler m_gridSampler;
+public:
+ CBC_QRGridSampler();
+ virtual ~CBC_QRGridSampler();
+ virtual CBC_CommonBitMatrix* SampleGrid(CBC_CommonBitMatrix *image, FX_INT32 dimensionX, FX_INT32 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, FX_INT32 &e);
+
+ static CBC_QRGridSampler &GetInstance();
+ static void CheckAndNudgePoints(CBC_CommonBitMatrix *image, CFX_FloatArray *points, FX_INT32 &e);
+};
+#endif