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

Side by Side Diff: xfa/src/fxbarcode/src/BC_DataMatrixDetector.cpp

Issue 842043002: Organize barcode codes into modules. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@xfa
Patch Set: rebase Created 5 years, 11 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 2008 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 "barcode.h"
24 #include "include/BC_DataMatrixDetector.h"
25 #include "include/BC_WhiteRectangleDetector.h"
26 #include "include/BC_ResultPoint.h"
27 #include "include/BC_QRFinderPatternFinder.h"
28 #include "include/BC_CommonBitMatrix.h"
29 #include "include/BC_QRDetectorResult.h"
30 #include "include/BC_QRGridSampler.h"
31 const FX_INT32 CBC_DataMatrixDetector::INTEGERS[5] = {0, 1, 2, 3, 4};
32 CBC_DataMatrixDetector::CBC_DataMatrixDetector(CBC_CommonBitMatrix *image):
33 m_image(image), m_rectangleDetector(NULL)
34 {
35 }
36 void CBC_DataMatrixDetector::Init(FX_INT32 &e)
37 {
38 m_rectangleDetector = FX_NEW CBC_WhiteRectangleDetector(m_image);
39 m_rectangleDetector->Init(e);
40 BC_EXCEPTION_CHECK_ReturnVoid(e);
41 }
42 CBC_DataMatrixDetector::~CBC_DataMatrixDetector()
43 {
44 if(m_rectangleDetector != NULL) {
45 delete m_rectangleDetector;
46 }
47 m_rectangleDetector = NULL;
48 }
49 inline FX_BOOL ResultPointsAndTransitionsComparator(FX_LPVOID a, FX_LPVOID b)
50 {
51 return ((CBC_ResultPointsAndTransitions *)b)->GetTransitions() > ((CBC_Resul tPointsAndTransitions *)a)->GetTransitions();
52 }
53 CBC_QRDetectorResult *CBC_DataMatrixDetector::Detect(FX_INT32 &e)
54 {
55 CFX_PtrArray* cornerPoints = m_rectangleDetector->Detect(e);
56 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
57 CBC_ResultPoint *pointA = (CBC_ResultPoint*)(*cornerPoints)[0];
58 CBC_ResultPoint *pointB = (CBC_ResultPoint*)(*cornerPoints)[1];
59 CBC_ResultPoint *pointC = (CBC_ResultPoint*)(*cornerPoints)[2];
60 CBC_ResultPoint *pointD = (CBC_ResultPoint*)(*cornerPoints)[3];
61 delete cornerPoints;
62 cornerPoints = NULL;
63 CFX_PtrArray transitions;
64 transitions.Add(TransitionsBetween(pointA, pointB));
65 transitions.Add(TransitionsBetween(pointA, pointC));
66 transitions.Add(TransitionsBetween(pointB, pointD));
67 transitions.Add(TransitionsBetween(pointC, pointD));
68 BC_FX_PtrArray_Sort(transitions, &ResultPointsAndTransitionsComparator);
69 delete ( (CBC_ResultPointsAndTransitions *)transitions[2] );
70 delete ( (CBC_ResultPointsAndTransitions *)transitions[3] );
71 CBC_ResultPointsAndTransitions *lSideOne = (CBC_ResultPointsAndTransitions*) transitions[0];
72 CBC_ResultPointsAndTransitions *lSideTwo = (CBC_ResultPointsAndTransitions*) transitions[1];
73 CFX_MapPtrTemplate<CBC_ResultPoint*, FX_INT32> pointCount;
74 Increment(pointCount, lSideOne->GetFrom());
75 Increment(pointCount, lSideOne->GetTo());
76 Increment(pointCount, lSideTwo->GetFrom());
77 Increment(pointCount, lSideTwo->GetTo());
78 delete ( (CBC_ResultPointsAndTransitions *)transitions[1] );
79 delete ( (CBC_ResultPointsAndTransitions *)transitions[0] );
80 transitions.RemoveAll();
81 CBC_ResultPoint *maybeTopLeft = NULL;
82 CBC_ResultPoint *bottomLeft = NULL;
83 CBC_ResultPoint *maybeBottomRight = NULL;
84 FX_POSITION itBegin = pointCount.GetStartPosition();
85 while(itBegin != NULL) {
86 CBC_ResultPoint *key = 0;
87 FX_INT32 value = 0;
88 pointCount.GetNextAssoc(itBegin, key, value);
89 if(value == 2) {
90 bottomLeft = key;
91 } else {
92 if (maybeBottomRight == NULL) {
93 maybeBottomRight = key;
94 } else {
95 maybeTopLeft = key;
96 }
97 }
98 }
99 if (maybeTopLeft == NULL || bottomLeft == NULL || maybeBottomRight == NULL) {
100 delete pointA;
101 delete pointB;
102 delete pointC;
103 delete pointD;
104 e = BCExceptionNotFound;
105 return NULL;
106 }
107 CFX_PtrArray corners;
108 corners.SetSize(3);
109 corners[0] = maybeTopLeft;
110 corners[1] = bottomLeft;
111 corners[2] = maybeBottomRight;
112 OrderBestPatterns(&corners);
113 CBC_ResultPoint *bottomRight = (CBC_ResultPoint*)corners[0];
114 bottomLeft = (CBC_ResultPoint*)corners[1];
115 CBC_ResultPoint *topLeft = (CBC_ResultPoint*)corners[2];
116 CBC_ResultPoint *topRight = NULL;
117 FX_INT32 value;
118 if (!pointCount.Lookup(pointA, value)) {
119 topRight = pointA;
120 } else if (!pointCount.Lookup(pointB, value)) {
121 topRight = pointB;
122 } else if (!pointCount.Lookup(pointC, value)) {
123 topRight = pointC;
124 } else {
125 topRight = pointD;
126 }
127 FX_INT32 dimensionTop = CBC_AutoPtr<CBC_ResultPointsAndTransitions>(Transiti onsBetween(topLeft, topRight))->GetTransitions();
128 FX_INT32 dimensionRight = CBC_AutoPtr<CBC_ResultPointsAndTransitions>(Transi tionsBetween(bottomRight, topRight))->GetTransitions();
129 if ((dimensionTop & 0x01) == 1) {
130 dimensionTop++;
131 }
132 dimensionTop += 2;
133 if ((dimensionRight & 0x01) == 1) {
134 dimensionRight++;
135 }
136 dimensionRight += 2;
137 CBC_AutoPtr<CBC_CommonBitMatrix> bits(NULL);
138 CBC_AutoPtr<CBC_ResultPoint> correctedTopRight(NULL);
139 if (4 * dimensionTop >= 7 * dimensionRight || 4 * dimensionRight >= 7 * dime nsionTop) {
140 correctedTopRight =
141 CBC_AutoPtr<CBC_ResultPoint>(CorrectTopRightRectangular(bottomLeft, bottomRight, topLeft, topRight,
142 dimensionTop, dimensionRight));
143 if (correctedTopRight.get() == NULL) {
144 correctedTopRight = CBC_AutoPtr<CBC_ResultPoint>(topRight);
145 } else {
146 delete topRight;
147 topRight = NULL;
148 }
149 dimensionTop = CBC_AutoPtr<CBC_ResultPointsAndTransitions>(TransitionsBe tween(topLeft, correctedTopRight.get()))->GetTransitions();
150 dimensionRight = CBC_AutoPtr<CBC_ResultPointsAndTransitions>(Transitions Between(bottomRight, correctedTopRight.get()))->GetTransitions();
151 if ((dimensionTop & 0x01) == 1) {
152 dimensionTop++;
153 }
154 if ((dimensionRight & 0x01) == 1) {
155 dimensionRight++;
156 }
157 bits = CBC_AutoPtr<CBC_CommonBitMatrix>(SampleGrid(m_image, topLeft, bot tomLeft, bottomRight,
158 correctedTopRight.get(), dimensi onTop, dimensionRight, e));
159 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
160 } else {
161 FX_INT32 dimension = FX_MIN(dimensionRight, dimensionTop);
162 correctedTopRight = CBC_AutoPtr<CBC_ResultPoint>(CorrectTopRight(bottomL eft, bottomRight,
163 topLeft, topRight, dimension));
164 if (correctedTopRight.get() == NULL) {
165 correctedTopRight = CBC_AutoPtr<CBC_ResultPoint>(topRight);
166 } else {
167 delete topRight;
168 topRight = NULL;
169 }
170 FX_INT32 dimensionCorrected = FX_MAX(CBC_AutoPtr<CBC_ResultPointsAndTran sitions>(TransitionsBetween(topLeft, correctedTopRight.get()))->GetTransitions() ,
171 CBC_AutoPtr<CBC_ResultPointsAndTran sitions>(TransitionsBetween(bottomRight, correctedTopRight.get()))->GetTransitio ns());
172 dimensionCorrected++;
173 if ((dimensionCorrected & 0x01) == 1) {
174 dimensionCorrected++;
175 }
176 bits = CBC_AutoPtr<CBC_CommonBitMatrix>(SampleGrid(m_image,
177 topLeft,
178 bottomLeft,
179 bottomRight,
180 correctedTopRight.get(),
181 dimensionCorrected,
182 dimensionCorrected, e));
183 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
184 }
185 CFX_PtrArray *result = FX_NEW CFX_PtrArray;
186 result->SetSize(4);
187 result->Add(topLeft);
188 result->Add(bottomLeft);
189 result->Add(bottomRight);
190 result->Add(correctedTopRight.release());
191 return FX_NEW CBC_QRDetectorResult(bits.release(), result);
192 }
193 CBC_ResultPoint *CBC_DataMatrixDetector::CorrectTopRightRectangular(CBC_ResultPo int *bottomLeft, CBC_ResultPoint *bottomRight, CBC_ResultPoint *topLeft, CBC_Res ultPoint *topRight, FX_INT32 dimensionTop, FX_INT32 dimensionRight)
194 {
195 FX_FLOAT corr = Distance(bottomLeft, bottomRight) / (FX_FLOAT)dimensionTop;
196 FX_INT32 norm = Distance(topLeft, topRight);
197 FX_FLOAT cos = (topRight->GetX() - topLeft->GetX()) / norm;
198 FX_FLOAT sin = (topRight->GetY() - topLeft->GetY()) / norm;
199 CBC_AutoPtr<CBC_ResultPoint> c1(FX_NEW CBC_ResultPoint(topRight->GetX() + co rr * cos, topRight->GetY() + corr * sin));
200 corr = Distance(bottomLeft, topLeft) / (FX_FLOAT)dimensionRight;
201 norm = Distance(bottomRight, topRight);
202 cos = (topRight->GetX() - bottomRight->GetX()) / norm;
203 sin = (topRight->GetY() - bottomRight->GetY()) / norm;
204 CBC_AutoPtr<CBC_ResultPoint> c2(FX_NEW CBC_ResultPoint(topRight->GetX() + co rr * cos, topRight->GetY() + corr * sin));
205 if (!IsValid(c1.get())) {
206 if (IsValid(c2.get())) {
207 return c2.release();
208 }
209 return NULL;
210 } else if (!IsValid(c2.get())) {
211 return c1.release();
212 }
213 FX_INT32 l1 = FXSYS_abs(dimensionTop - CBC_AutoPtr<CBC_ResultPointsAndTransi tions>(TransitionsBetween(topLeft, c1.get()))->GetTransitions()) +
214 FXSYS_abs(dimensionRight - CBC_AutoPtr<CBC_ResultPointsAndTran sitions>(TransitionsBetween(bottomRight, c1.get()))->GetTransitions());
215 FX_INT32 l2 = FXSYS_abs(dimensionTop - CBC_AutoPtr<CBC_ResultPointsAndTransi tions>(TransitionsBetween(topLeft, c2.get()))->GetTransitions()) +
216 FXSYS_abs(dimensionRight - CBC_AutoPtr<CBC_ResultPointsAndTran sitions>(TransitionsBetween(bottomRight, c2.get()))->GetTransitions());
217 if (l1 <= l2) {
218 return c1.release();
219 }
220 return c2.release();
221 }
222 CBC_ResultPoint *CBC_DataMatrixDetector::CorrectTopRight(CBC_ResultPoint *bottom Left, CBC_ResultPoint *bottomRight, CBC_ResultPoint *topLeft, CBC_ResultPoint *t opRight, FX_INT32 dimension)
223 {
224 FX_FLOAT corr = Distance(bottomLeft, bottomRight) / (FX_FLOAT) dimension;
225 FX_INT32 norm = Distance(topLeft, topRight);
226 FX_FLOAT cos = (topRight->GetX() - topLeft->GetX()) / norm;
227 FX_FLOAT sin = (topRight->GetY() - topLeft->GetY()) / norm;
228 CBC_AutoPtr<CBC_ResultPoint> c1(FX_NEW CBC_ResultPoint(topRight->GetX() + co rr * cos, topRight->GetY() + corr * sin));
229 corr = Distance(bottomLeft, bottomRight) / (FX_FLOAT) dimension;
230 norm = Distance(bottomRight, topRight);
231 cos = (topRight->GetX() - bottomRight->GetX()) / norm;
232 sin = (topRight->GetY() - bottomRight->GetY()) / norm;
233 CBC_AutoPtr<CBC_ResultPoint> c2(FX_NEW CBC_ResultPoint(topRight->GetX() + co rr * cos, topRight->GetY() + corr * sin));
234 if (!IsValid(c1.get())) {
235 if (IsValid(c2.get())) {
236 return c2.release();
237 }
238 return NULL;
239 } else if (!IsValid(c2.get())) {
240 return c1.release();
241 }
242 FX_INT32 l1 = FXSYS_abs(CBC_AutoPtr<CBC_ResultPointsAndTransitions>(Transiti onsBetween(topLeft, c1.get()))->GetTransitions() -
243 CBC_AutoPtr<CBC_ResultPointsAndTransitions>(Transiti onsBetween(bottomRight, c1.get()))->GetTransitions());
244 FX_INT32 l2 = FXSYS_abs(CBC_AutoPtr<CBC_ResultPointsAndTransitions>(Transiti onsBetween(topLeft, c2.get()))->GetTransitions() -
245 CBC_AutoPtr<CBC_ResultPointsAndTransitions>(Transiti onsBetween(bottomRight, c2.get()))->GetTransitions());
246 return l1 <= l2 ? c1.release() : c2.release();
247 }
248 FX_BOOL CBC_DataMatrixDetector::IsValid(CBC_ResultPoint *p)
249 {
250 return p->GetX() >= 0 && p->GetX() < m_image->GetWidth() && p->GetY() > 0 && p->GetY() < m_image->GetHeight();
251 }
252 FX_INT32 CBC_DataMatrixDetector::Round(FX_FLOAT d)
253 {
254 return (FX_INT32) (d + 0.5f);
255 }
256 FX_INT32 CBC_DataMatrixDetector::Distance(CBC_ResultPoint *a, CBC_ResultPoint *b )
257 {
258 return Round((FX_FLOAT) sqrt((a->GetX() - b->GetX())
259 * (a->GetX() - b->GetX()) + (a->GetY() - b->Get Y())
260 * (a->GetY() - b->GetY())));
261 }
262 void CBC_DataMatrixDetector::Increment(CFX_MapPtrTemplate<CBC_ResultPoint*, FX_I NT32> &table, CBC_ResultPoint *key)
263 {
264 FX_INT32 value;
265 if(table.Lookup(key, value)) {
266 table.SetAt(key, INTEGERS[value + 1]);
267 } else {
268 table.SetAt(key, INTEGERS[1]);
269 }
270 }
271 CBC_CommonBitMatrix *CBC_DataMatrixDetector::SampleGrid(CBC_CommonBitMatrix *ima ge,
272 CBC_ResultPoint *topLeft,
273 CBC_ResultPoint *bottomLeft,
274 CBC_ResultPoint *bottomRight,
275 CBC_ResultPoint *topRight,
276 FX_INT32 dimensionX, FX_INT32 dimensionY, FX_INT32 &e)
277 {
278 CBC_QRGridSampler &sampler = CBC_QRGridSampler::GetInstance();
279 CBC_CommonBitMatrix* cbm = sampler.SampleGrid(image,
280 dimensionX,
281 dimensionY,
282 0.5f,
283 0.5f,
284 dimensionX - 0.5f,
285 0.5f,
286 dimensionX - 0.5f,
287 dimensionY - 0.5f,
288 0.5f,
289 dimensionY - 0.5f,
290 topLeft->GetX(),
291 topLeft->GetY(),
292 topRight->GetX(),
293 topRight->GetY(),
294 bottomRight->GetX(),
295 bottomRight->GetY(),
296 bottomLeft->GetX(),
297 bottomLeft->GetY(), e);
298 BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
299 return cbm;
300 }
301 CBC_ResultPointsAndTransitions *CBC_DataMatrixDetector::TransitionsBetween(CBC_R esultPoint *from, CBC_ResultPoint *to)
302 {
303 FX_INT32 fromX = (FX_INT32) from->GetX();
304 FX_INT32 fromY = (FX_INT32) from->GetY();
305 FX_INT32 toX = (FX_INT32) to->GetX();
306 FX_INT32 toY = (FX_INT32) to->GetY();
307 FX_BOOL steep = FXSYS_abs(toY - fromY) > FXSYS_abs(toX - fromX);
308 if (steep) {
309 FX_INT32 temp = fromX;
310 fromX = fromY;
311 fromY = temp;
312 temp = toX;
313 toX = toY;
314 toY = temp;
315 }
316 FX_INT32 dx = FXSYS_abs(toX - fromX);
317 FX_INT32 dy = FXSYS_abs(toY - fromY);
318 FX_INT32 error = -dx >> 1;
319 FX_INT32 ystep = fromY < toY ? 1 : -1;
320 FX_INT32 xstep = fromX < toX ? 1 : -1;
321 FX_INT32 transitions = 0;
322 FX_BOOL inBlack = m_image->Get(steep ? fromY : fromX, steep ? fromX : fromY) ;
323 for (FX_INT32 x = fromX, y = fromY; x != toX; x += xstep) {
324 FX_BOOL isBlack = m_image->Get(steep ? y : x, steep ? x : y);
325 if (isBlack != inBlack) {
326 transitions++;
327 inBlack = isBlack;
328 }
329 error += dy;
330 if (error > 0) {
331 if (y == toY) {
332 break;
333 }
334 y += ystep;
335 error -= dx;
336 }
337 }
338 return FX_NEW CBC_ResultPointsAndTransitions(from, to, transitions);
339 }
340 void CBC_DataMatrixDetector::OrderBestPatterns(CFX_PtrArray *patterns)
341 {
342 FX_FLOAT abDistance = (FX_FLOAT)Distance((CBC_ResultPoint*)(*patterns)[0], ( CBC_ResultPoint*)(*patterns)[1]);
343 FX_FLOAT bcDistance = (FX_FLOAT)Distance((CBC_ResultPoint*)(*patterns)[1], ( CBC_ResultPoint*)(*patterns)[2]);
344 FX_FLOAT acDistance = (FX_FLOAT)Distance((CBC_ResultPoint*)(*patterns)[0], ( CBC_ResultPoint*)(*patterns)[2]);
345 CBC_ResultPoint *topLeft, *topRight, *bottomLeft;
346 if (bcDistance >= abDistance && bcDistance >= acDistance) {
347 topLeft = (CBC_ResultPoint*)(*patterns)[0];
348 topRight = (CBC_ResultPoint*)(*patterns)[1];
349 bottomLeft = (CBC_ResultPoint*)(*patterns)[2];
350 } else if (acDistance >= bcDistance && acDistance >= abDistance) {
351 topLeft = (CBC_ResultPoint*)(*patterns)[1];
352 topRight = (CBC_ResultPoint*)(*patterns)[0];
353 bottomLeft = (CBC_ResultPoint*)(*patterns)[2];
354 } else {
355 topLeft = (CBC_ResultPoint*)(*patterns)[2];
356 topRight = (CBC_ResultPoint*)(*patterns)[0];
357 bottomLeft = (CBC_ResultPoint*)(*patterns)[1];
358 }
359 if ((bottomLeft->GetY() - topLeft->GetY()) * (topRight->GetX() - topLeft->Ge tX()) < (bottomLeft->GetX()
360 - topLeft->GetX()) * (topRight->GetY() - topLeft->GetY())) {
361 CBC_ResultPoint *temp = topRight;
362 topRight = bottomLeft;
363 bottomLeft = temp;
364 }
365 (*patterns)[0] = bottomLeft;
366 (*patterns)[1] = topLeft;
367 (*patterns)[2] = topRight;
368 }
OLDNEW
« no previous file with comments | « xfa/src/fxbarcode/src/BC_DataMatrixDecoder.cpp ('k') | xfa/src/fxbarcode/src/BC_DataMatrixReader.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698