Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Side by Side Diff: xfa/src/fxbarcode/qrcode/BC_QRDetector.cpp

Issue 1803723002: Move xfa/src up to xfa/. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Rebase to master Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 // Original code is licensed as follows:
7 /*
8 * Copyright 2007 ZXing authors
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 */
22
23 #include "xfa/src/fxbarcode/qrcode/BC_QRDetector.h"
24
25 #include <algorithm>
26 #include <memory>
27
28 #include "xfa/src/fxbarcode/BC_ResultPoint.h"
29 #include "xfa/src/fxbarcode/common/BC_CommonBitMatrix.h"
30 #include "xfa/src/fxbarcode/qrcode/BC_FinderPatternInfo.h"
31 #include "xfa/src/fxbarcode/qrcode/BC_QRAlignmentPatternFinder.h"
32 #include "xfa/src/fxbarcode/qrcode/BC_QRCoderVersion.h"
33 #include "xfa/src/fxbarcode/qrcode/BC_QRDetectorResult.h"
34 #include "xfa/src/fxbarcode/qrcode/BC_QRFinderPattern.h"
35 #include "xfa/src/fxbarcode/qrcode/BC_QRFinderPatternFinder.h"
36 #include "xfa/src/fxbarcode/qrcode/BC_QRGridSampler.h"
37
38 CBC_QRDetector::CBC_QRDetector(CBC_CommonBitMatrix* image) : m_image(image) {}
39 CBC_QRDetector::~CBC_QRDetector() {}
40 CBC_QRDetectorResult* CBC_QRDetector::Detect(int32_t hints, int32_t& e) {
41 CBC_QRFinderPatternFinder finder(m_image);
42 std::unique_ptr<CBC_QRFinderPatternInfo> info(finder.Find(hints, e));
43 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
44 CBC_QRDetectorResult* qdr = ProcessFinderPatternInfo(info.get(), e);
45 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
46 return qdr;
47 }
48 CBC_QRDetectorResult* CBC_QRDetector::ProcessFinderPatternInfo(
49 CBC_QRFinderPatternInfo* info,
50 int32_t& e) {
51 std::unique_ptr<CBC_QRFinderPattern> topLeft(info->GetTopLeft());
52 std::unique_ptr<CBC_QRFinderPattern> topRight(info->GetTopRight());
53 std::unique_ptr<CBC_QRFinderPattern> bottomLeft(info->GetBottomLeft());
54 FX_FLOAT moduleSize =
55 CalculateModuleSize(topLeft.get(), topRight.get(), bottomLeft.get());
56 if (moduleSize < 1.0f) {
57 e = BCExceptionRead;
58 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
59 }
60 int32_t dimension = ComputeDimension(topLeft.get(), topRight.get(),
61 bottomLeft.get(), moduleSize, e);
62 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
63 CBC_QRCoderVersion* provisionalVersion =
64 CBC_QRCoderVersion::GetProvisionalVersionForDimension(dimension, e);
65 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
66 int32_t modulesBetweenFPCenters =
67 provisionalVersion->GetDimensionForVersion() - 7;
68 CBC_QRAlignmentPattern* alignmentPattern = NULL;
69 if (provisionalVersion->GetAlignmentPatternCenters()->GetSize() > 0) {
70 FX_FLOAT bottomRightX =
71 topRight->GetX() - topLeft->GetX() + bottomLeft->GetX();
72 FX_FLOAT bottomRightY =
73 topRight->GetY() - topLeft->GetY() + bottomLeft->GetY();
74 FX_FLOAT correctionToTopLeft =
75 1.0f - 3.0f / (FX_FLOAT)modulesBetweenFPCenters;
76 FX_FLOAT xtemp = (topLeft->GetX() +
77 correctionToTopLeft * (bottomRightX - topLeft->GetX()));
78 int32_t estAlignmentX = (int32_t)xtemp;
79 FX_FLOAT ytemp = (topLeft->GetY() +
80 correctionToTopLeft * (bottomRightY - topLeft->GetY()));
81 int32_t estAlignmentY = (int32_t)ytemp;
82 for (int32_t i = 4; i <= 16; i <<= 1) {
83 CBC_QRAlignmentPattern* temp = FindAlignmentInRegion(
84 moduleSize, estAlignmentX, estAlignmentY, (FX_FLOAT)i, e);
85 alignmentPattern = temp;
86 break;
87 }
88 }
89 CBC_CommonBitMatrix* bits =
90 SampleGrid(m_image, topLeft.get(), topRight.get(), bottomLeft.get(),
91 (CBC_ResultPoint*)(alignmentPattern), dimension, e);
92 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
93 CFX_PtrArray* points = new CFX_PtrArray;
94 if (alignmentPattern == NULL) {
95 points->Add(bottomLeft.release());
96 points->Add(topLeft.release());
97 points->Add(topRight.release());
98 } else {
99 points->Add(bottomLeft.release());
100 points->Add(topLeft.release());
101 points->Add(topRight.release());
102 points->Add(alignmentPattern);
103 }
104 return new CBC_QRDetectorResult(bits, points);
105 }
106 CBC_CommonBitMatrix* CBC_QRDetector::SampleGrid(
107 CBC_CommonBitMatrix* image,
108 CBC_ResultPoint* topLeft,
109 CBC_ResultPoint* topRight,
110 CBC_ResultPoint* bottomLeft,
111 CBC_ResultPoint* alignmentPattern,
112 int32_t dimension,
113 int32_t& e) {
114 FX_FLOAT dimMinusThree = (FX_FLOAT)dimension - 3.5f;
115 FX_FLOAT bottomRightX;
116 FX_FLOAT bottomRightY;
117 FX_FLOAT sourceBottomRightX;
118 FX_FLOAT sourceBottomRightY;
119 if (alignmentPattern) {
120 bottomRightX = alignmentPattern->GetX();
121 bottomRightY = alignmentPattern->GetY();
122 sourceBottomRightX = sourceBottomRightY = dimMinusThree - 3.0f;
123 } else {
124 bottomRightX = (topRight->GetX() - topLeft->GetX()) + bottomLeft->GetX();
125 bottomRightY = (topRight->GetY() - topLeft->GetY()) + bottomLeft->GetY();
126 sourceBottomRightX = sourceBottomRightY = dimMinusThree;
127 }
128 CBC_QRGridSampler& sampler = CBC_QRGridSampler::GetInstance();
129 CBC_CommonBitMatrix* cbm = sampler.SampleGrid(
130 image, dimension, dimension, 3.5f, 3.5f, dimMinusThree, 3.5f,
131 sourceBottomRightX, sourceBottomRightY, 3.5f, dimMinusThree,
132 topLeft->GetX(), topLeft->GetY(), topRight->GetX(), topRight->GetY(),
133 bottomRightX, bottomRightY, bottomLeft->GetX(), bottomLeft->GetY(), e);
134 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
135 return cbm;
136 }
137 int32_t CBC_QRDetector::ComputeDimension(CBC_ResultPoint* topLeft,
138 CBC_ResultPoint* topRight,
139 CBC_ResultPoint* bottomLeft,
140 FX_FLOAT moduleSize,
141 int32_t& e) {
142 int32_t tltrCentersDimension = Round(
143 CBC_QRFinderPatternFinder::Distance(topLeft, topRight) / moduleSize);
144 int32_t tlblCentersDimension = Round(
145 CBC_QRFinderPatternFinder::Distance(topLeft, bottomLeft) / moduleSize);
146 int32_t dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7;
147 switch (dimension & 0x03) {
148 case 0:
149 dimension++;
150 break;
151 case 2:
152 dimension--;
153 break;
154 case 3: {
155 e = BCExceptionRead;
156 BC_EXCEPTION_CHECK_ReturnValue(e, 0);
157 }
158 }
159 return dimension;
160 }
161 FX_FLOAT CBC_QRDetector::CalculateModuleSize(CBC_ResultPoint* topLeft,
162 CBC_ResultPoint* topRight,
163 CBC_ResultPoint* bottomLeft) {
164 return (CalculateModuleSizeOneWay(topLeft, topRight) +
165 CalculateModuleSizeOneWay(topLeft, bottomLeft)) /
166 2.0f;
167 }
168 FX_FLOAT CBC_QRDetector::CalculateModuleSizeOneWay(
169 CBC_ResultPoint* pattern,
170 CBC_ResultPoint* otherPattern) {
171 FX_FLOAT moduleSizeEst1 = SizeOfBlackWhiteBlackRunBothWays(
172 (int32_t)pattern->GetX(), (int32_t)pattern->GetY(),
173 (int32_t)otherPattern->GetX(), (int32_t)otherPattern->GetY());
174 FX_FLOAT moduleSizeEst2 = SizeOfBlackWhiteBlackRunBothWays(
175 (int32_t)otherPattern->GetX(), (int32_t)otherPattern->GetY(),
176 (int32_t)pattern->GetX(), (int32_t)pattern->GetY());
177 if (FXSYS_isnan(moduleSizeEst1)) {
178 return moduleSizeEst2;
179 }
180 if (FXSYS_isnan(moduleSizeEst2)) {
181 return moduleSizeEst1;
182 }
183 return (moduleSizeEst1 + moduleSizeEst2) / 14.0f;
184 }
185 int32_t CBC_QRDetector::Round(FX_FLOAT d) {
186 return (int32_t)(d + 0.5f);
187 }
188 FX_FLOAT CBC_QRDetector::SizeOfBlackWhiteBlackRunBothWays(int32_t fromX,
189 int32_t fromY,
190 int32_t toX,
191 int32_t toY) {
192 FX_FLOAT result = SizeOfBlackWhiteBlackRun(fromX, fromY, toX, toY);
193 int32_t otherToX = fromX - (toX - fromX);
194 if (otherToX < 0) {
195 otherToX = -1;
196 } else if (otherToX >= m_image->GetWidth()) {
197 otherToX = m_image->GetWidth();
198 }
199 int32_t otherToY = fromY - (toY - fromY);
200 if (otherToY < 0) {
201 otherToY = -1;
202 } else if (otherToY >= m_image->GetHeight()) {
203 otherToY = m_image->GetHeight();
204 }
205 result += SizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY);
206 return result - 1.0f;
207 }
208 FX_FLOAT CBC_QRDetector::SizeOfBlackWhiteBlackRun(int32_t fromX,
209 int32_t fromY,
210 int32_t toX,
211 int32_t toY) {
212 FX_BOOL steep = FXSYS_abs(toY - fromY) > FXSYS_abs(toX - fromX);
213 if (steep) {
214 int32_t temp = fromX;
215 fromX = fromY;
216 fromY = temp;
217 temp = toX;
218 toX = toY;
219 toY = temp;
220 }
221 int32_t dx = FXSYS_abs(toX - fromX);
222 int32_t dy = FXSYS_abs(toY - fromY);
223 int32_t error = -dx >> 1;
224 int32_t ystep = fromY < toY ? 1 : -1;
225 int32_t xstep = fromX < toX ? 1 : -1;
226 int32_t state = 0;
227 for (int32_t x = fromX, y = fromY; x != toX; x += xstep) {
228 int32_t realX = steep ? y : x;
229 int32_t realY = steep ? x : y;
230 if (state == 1) {
231 if (m_image->Get(realX, realY)) {
232 state++;
233 }
234 } else {
235 if (!m_image->Get(realX, realY)) {
236 state++;
237 }
238 }
239 if (state == 3) {
240 int32_t diffX = x - fromX;
241 int32_t diffY = y - fromY;
242 return (FX_FLOAT)sqrt((double)(diffX * diffX + diffY * diffY));
243 }
244 error += dy;
245 if (error > 0) {
246 y += ystep;
247 error -= dx;
248 }
249 }
250 int32_t diffX = toX - fromX;
251 int32_t diffY = toY - fromY;
252 return (FX_FLOAT)sqrt((double)(diffX * diffX + diffY * diffY));
253 }
254 CBC_QRAlignmentPattern* CBC_QRDetector::FindAlignmentInRegion(
255 FX_FLOAT overallEstModuleSize,
256 int32_t estAlignmentX,
257 int32_t estAlignmentY,
258 FX_FLOAT allowanceFactor,
259 int32_t& e) {
260 int32_t allowance = (int32_t)(allowanceFactor * overallEstModuleSize);
261 int32_t alignmentAreaLeftX = std::max(0, estAlignmentX - allowance);
262 int32_t alignmentAreaRightX =
263 std::min(m_image->GetWidth() - 1, estAlignmentX + allowance);
264 if (alignmentAreaRightX - alignmentAreaLeftX < overallEstModuleSize * 3) {
265 e = BCExceptionRead;
266 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
267 }
268 int32_t alignmentAreaTopY = std::max(0, estAlignmentY - allowance);
269 int32_t alignmentAreaBottomY =
270 std::min(m_image->GetHeight() - 1, estAlignmentY + allowance);
271 CBC_QRAlignmentPatternFinder alignmentFinder(
272 m_image, alignmentAreaLeftX, alignmentAreaTopY,
273 alignmentAreaRightX - alignmentAreaLeftX,
274 alignmentAreaBottomY - alignmentAreaTopY, overallEstModuleSize);
275 CBC_QRAlignmentPattern* qap = alignmentFinder.Find(e);
276 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
277 return qap;
278 }
OLDNEW
« no previous file with comments | « xfa/src/fxbarcode/qrcode/BC_QRDetector.h ('k') | xfa/src/fxbarcode/qrcode/BC_QRDetectorResult.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698