1 // Copyright 2014 PDFium Authors. All rights reserved.
\r
2 // Use of this source code is governed by a BSD-style license that can be
\r
3 // found in the LICENSE file.
\r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
\r
8 #include "include/BC_PDF417Codeword.h"
\r
9 #include "include/BC_PDF417BarcodeMetadata.h"
\r
10 #include "include/BC_PDF417BoundingBox.h"
\r
11 #include "include/BC_PDF417DetectionResultColumn.h"
\r
12 #include "include/BC_PDF417Common.h"
\r
13 #include "include/BC_PDF417DetectionResultRowIndicatorColumn.h"
\r
14 #include "include/BC_PDF417DetectionResult.h"
\r
15 FX_INT32 CBC_DetectionResult::ADJUST_ROW_NUMBER_SKIP = 2;
\r
16 CBC_DetectionResult::CBC_DetectionResult(CBC_BarcodeMetadata* barcodeMetadata, CBC_BoundingBox* boundingBox)
\r
18 m_barcodeMetadata = barcodeMetadata;
\r
19 m_barcodeColumnCount = barcodeMetadata->getColumnCount();
\r
20 m_boundingBox = boundingBox;
\r
21 m_detectionResultColumns.SetSize(m_barcodeColumnCount + 2);
\r
22 for (FX_INT32 i = 0; i < m_barcodeColumnCount + 2; i++) {
\r
23 m_detectionResultColumns[i] = NULL;
\r
26 CBC_DetectionResult::~CBC_DetectionResult()
\r
28 delete m_boundingBox;
\r
29 delete m_barcodeMetadata;
\r
30 m_detectionResultColumns.RemoveAll();
\r
32 CFX_PtrArray& CBC_DetectionResult::getDetectionResultColumns()
\r
34 adjustIndicatorColumnRowNumbers((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt(0));
\r
35 adjustIndicatorColumnRowNumbers((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt(m_barcodeColumnCount + 1));
\r
36 FX_INT32 unadjustedCodewordCount = CBC_PDF417Common::MAX_CODEWORDS_IN_BARCODE;
\r
37 FX_INT32 previousUnadjustedCount;
\r
39 previousUnadjustedCount = unadjustedCodewordCount;
\r
40 unadjustedCodewordCount = adjustRowNumbers();
\r
41 } while (unadjustedCodewordCount > 0 && unadjustedCodewordCount < previousUnadjustedCount);
\r
42 return m_detectionResultColumns;
\r
44 void CBC_DetectionResult::setBoundingBox(CBC_BoundingBox* boundingBox)
\r
46 m_boundingBox = boundingBox;
\r
48 CBC_BoundingBox* CBC_DetectionResult::getBoundingBox()
\r
50 return m_boundingBox;
\r
52 void CBC_DetectionResult::setDetectionResultColumn(FX_INT32 barcodeColumn, CBC_DetectionResultColumn* detectionResultColumn)
\r
54 m_detectionResultColumns[barcodeColumn] = detectionResultColumn;
\r
56 CBC_DetectionResultColumn* CBC_DetectionResult::getDetectionResultColumn(FX_INT32 barcodeColumn)
\r
58 return (CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn];
\r
60 CFX_ByteString CBC_DetectionResult::toString()
\r
62 CBC_DetectionResultColumn* rowIndicatorColumn = (CBC_DetectionResultColumn*)m_detectionResultColumns[0];
\r
63 if (rowIndicatorColumn == NULL) {
\r
64 rowIndicatorColumn = (CBC_DetectionResultColumn*)m_detectionResultColumns[m_barcodeColumnCount + 1];
\r
66 CFX_ByteString result;
\r
67 for (FX_INT32 codewordsRow = 0; codewordsRow < rowIndicatorColumn->getCodewords()->GetSize(); codewordsRow++) {
\r
68 result += (FX_CHAR) codewordsRow;
\r
69 for (FX_INT32 barcodeColumn = 0; barcodeColumn < m_barcodeColumnCount + 2; barcodeColumn++) {
\r
70 if (m_detectionResultColumns[barcodeColumn] == NULL) {
\r
74 CBC_Codeword* codeword = (CBC_Codeword*)((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn])->getCodewords()->GetAt(codewordsRow);
\r
75 if (codeword == NULL) {
\r
79 result += codeword->getRowNumber();
\r
80 result += codeword->getValue();
\r
85 void CBC_DetectionResult::adjustIndicatorColumnRowNumbers(CBC_DetectionResultColumn* detectionResultColumn)
\r
87 if (detectionResultColumn != NULL) {
\r
88 ((CBC_DetectionResultRowIndicatorColumn*)detectionResultColumn)->adjustCompleteIndicatorColumnRowNumbers(*m_barcodeMetadata);
\r
91 FX_INT32 CBC_DetectionResult::adjustRowNumbers()
\r
93 FX_INT32 unadjustedCount = adjustRowNumbersByRow();
\r
94 if (unadjustedCount == 0) {
\r
97 for (FX_INT32 barcodeColumn = 1; barcodeColumn < m_barcodeColumnCount + 1; barcodeColumn++) {
\r
98 CFX_PtrArray* codewords = ((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn])->getCodewords();
\r
99 for (FX_INT32 codewordsRow = 0; codewordsRow < codewords->GetSize(); codewordsRow++) {
\r
100 if (codewords->GetAt(codewordsRow) == NULL) {
\r
103 if (!((CBC_Codeword*)codewords->GetAt(codewordsRow))->hasValidRowNumber()) {
\r
104 adjustRowNumbers(barcodeColumn, codewordsRow, codewords);
\r
108 return unadjustedCount;
\r
110 FX_INT32 CBC_DetectionResult::adjustRowNumbersByRow()
\r
112 adjustRowNumbersFromBothRI();
\r
113 FX_INT32 unadjustedCount = adjustRowNumbersFromLRI();
\r
114 return unadjustedCount + adjustRowNumbersFromRRI();
\r
116 FX_INT32 CBC_DetectionResult::adjustRowNumbersFromBothRI()
\r
118 if (m_detectionResultColumns[0] == NULL || m_detectionResultColumns[m_barcodeColumnCount + 1] == NULL) {
\r
121 CFX_PtrArray* LRIcodewords = ((CBC_DetectionResultColumn*)m_detectionResultColumns[0])->getCodewords();
\r
122 CFX_PtrArray* RRIcodewords = ((CBC_DetectionResultColumn*)m_detectionResultColumns[m_barcodeColumnCount + 1])->getCodewords();
\r
123 for (FX_INT32 codewordsRow = 0; codewordsRow < LRIcodewords->GetSize(); codewordsRow++) {
\r
124 if (LRIcodewords->GetAt(codewordsRow) != NULL &&
\r
125 RRIcodewords->GetAt(codewordsRow) != NULL &&
\r
126 ((CBC_Codeword*)LRIcodewords->GetAt(codewordsRow))->getRowNumber() == ((CBC_Codeword*)RRIcodewords->GetAt(codewordsRow))->getRowNumber()) {
\r
127 for (FX_INT32 barcodeColumn = 1; barcodeColumn <= m_barcodeColumnCount; barcodeColumn++) {
\r
128 CBC_Codeword* codeword = (CBC_Codeword*)((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn])->getCodewords()->GetAt(codewordsRow);
\r
129 if (codeword == NULL) {
\r
132 codeword->setRowNumber(((CBC_Codeword*)LRIcodewords->GetAt(codewordsRow))->getRowNumber());
\r
133 if (!codeword->hasValidRowNumber()) {
\r
134 ((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn])->getCodewords()->SetAt(codewordsRow, NULL);
\r
141 FX_INT32 CBC_DetectionResult::adjustRowNumbersFromRRI()
\r
143 if (m_detectionResultColumns[m_barcodeColumnCount + 1] == NULL) {
\r
146 FX_INT32 unadjustedCount = 0;
\r
147 CFX_PtrArray* codewords = ((CBC_DetectionResultColumn*) m_detectionResultColumns.GetAt(m_barcodeColumnCount + 1))->getCodewords();
\r
148 for (FX_INT32 codewordsRow = 0; codewordsRow < codewords->GetSize(); codewordsRow++) {
\r
149 if (codewords->GetAt(codewordsRow) == NULL) {
\r
152 FX_INT32 rowIndicatorRowNumber = ((CBC_Codeword*)codewords->GetAt(codewordsRow))->getRowNumber();
\r
153 FX_INT32 invalidRowCounts = 0;
\r
154 for (FX_INT32 barcodeColumn = m_barcodeColumnCount + 1; barcodeColumn > 0 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; barcodeColumn--) {
\r
155 CBC_Codeword* codeword = (CBC_Codeword*)((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt(barcodeColumn))->getCodewords()->GetAt(codewordsRow);
\r
156 if (codeword != NULL) {
\r
157 invalidRowCounts = adjustRowNumberIfValid(rowIndicatorRowNumber, invalidRowCounts, codeword);
\r
158 if (!codeword->hasValidRowNumber()) {
\r
164 return unadjustedCount;
\r
166 FX_INT32 CBC_DetectionResult::adjustRowNumbersFromLRI()
\r
168 if (m_detectionResultColumns[0] == NULL) {
\r
171 FX_INT32 unadjustedCount = 0;
\r
172 CFX_PtrArray* codewords = ((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt(0))->getCodewords();
\r
173 for (FX_INT32 codewordsRow = 0; codewordsRow < codewords->GetSize(); codewordsRow++) {
\r
174 if (codewords->GetAt(codewordsRow) == NULL) {
\r
177 FX_INT32 rowIndicatorRowNumber = ((CBC_Codeword*)codewords->GetAt(codewordsRow))->getRowNumber();
\r
178 FX_INT32 invalidRowCounts = 0;
\r
179 for (FX_INT32 barcodeColumn = 1; barcodeColumn < m_barcodeColumnCount + 1 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; barcodeColumn++) {
\r
180 CBC_Codeword* codeword = (CBC_Codeword*)((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn])->getCodewords()->GetAt(codewordsRow);
\r
181 if (codeword != NULL) {
\r
182 invalidRowCounts = adjustRowNumberIfValid(rowIndicatorRowNumber, invalidRowCounts, codeword);
\r
183 if (!codeword->hasValidRowNumber()) {
\r
189 return unadjustedCount;
\r
191 FX_INT32 CBC_DetectionResult::adjustRowNumberIfValid(FX_INT32 rowIndicatorRowNumber, FX_INT32 invalidRowCounts, CBC_Codeword* codeword)
\r
193 if (codeword == NULL) {
\r
194 return invalidRowCounts;
\r
196 if (!codeword->hasValidRowNumber()) {
\r
197 if (codeword->isValidRowNumber(rowIndicatorRowNumber)) {
\r
198 codeword->setRowNumber(rowIndicatorRowNumber);
\r
199 invalidRowCounts = 0;
\r
201 ++invalidRowCounts;
\r
204 return invalidRowCounts;
\r
206 void CBC_DetectionResult::adjustRowNumbers(FX_INT32 barcodeColumn, FX_INT32 codewordsRow, CFX_PtrArray* codewords)
\r
208 CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordsRow);
\r
209 CFX_PtrArray* previousColumnCodewords = ((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt(barcodeColumn - 1))->getCodewords();
\r
210 CFX_PtrArray* nextColumnCodewords = previousColumnCodewords;
\r
211 if (m_detectionResultColumns[barcodeColumn + 1] != NULL) {
\r
212 nextColumnCodewords = ((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn + 1])->getCodewords();
\r
214 CFX_PtrArray otherCodewords;
\r
215 otherCodewords.SetSize(14);
\r
216 otherCodewords[2] = previousColumnCodewords->GetAt(codewordsRow);
\r
217 otherCodewords[3] = nextColumnCodewords->GetAt(codewordsRow);
\r
218 if (codewordsRow > 0) {
\r
219 otherCodewords[0] = codewords->GetAt(codewordsRow - 1);
\r
220 otherCodewords[4] = previousColumnCodewords->GetAt(codewordsRow - 1);
\r
221 otherCodewords[5] = nextColumnCodewords->GetAt(codewordsRow - 1);
\r
223 if (codewordsRow > 1) {
\r
224 otherCodewords[8] = codewords->GetAt(codewordsRow - 2);
\r
225 otherCodewords[10] = previousColumnCodewords->GetAt(codewordsRow - 2);
\r
226 otherCodewords[11] = nextColumnCodewords->GetAt(codewordsRow - 2);
\r
228 if (codewordsRow < codewords->GetSize() - 1) {
\r
229 otherCodewords[1] = codewords->GetAt(codewordsRow + 1);
\r
230 otherCodewords[6] = previousColumnCodewords->GetAt(codewordsRow + 1);
\r
231 otherCodewords[7] = nextColumnCodewords->GetAt(codewordsRow + 1);
\r
233 if (codewordsRow < codewords->GetSize() - 2) {
\r
234 otherCodewords[9] = codewords->GetAt(codewordsRow + 2);
\r
235 otherCodewords[12] = previousColumnCodewords->GetAt(codewordsRow + 2);
\r
236 otherCodewords[13] = nextColumnCodewords->GetAt(codewordsRow + 2);
\r
238 for (FX_INT32 i = 0; i < otherCodewords.GetSize(); i++) {
\r
239 CBC_Codeword* otherCodeword = (CBC_Codeword*)otherCodewords.GetAt(i);
\r
240 if (adjustRowNumber(codeword, otherCodeword)) {
\r
245 FX_BOOL CBC_DetectionResult::adjustRowNumber(CBC_Codeword* codeword, CBC_Codeword* otherCodeword)
\r
247 if (otherCodeword == NULL) {
\r
250 if (otherCodeword->hasValidRowNumber() && otherCodeword->getBucket() == codeword->getBucket()) {
\r
251 codeword->setRowNumber(otherCodeword->getRowNumber());
\r
256 FX_INT32 CBC_DetectionResult::getBarcodeColumnCount()
\r
258 return m_barcodeColumnCount;
\r
260 FX_INT32 CBC_DetectionResult::getBarcodeRowCount()
\r
262 return m_barcodeMetadata->getRowCount();
\r
264 FX_INT32 CBC_DetectionResult::getBarcodeECLevel()
\r
266 return m_barcodeMetadata->getErrorCorrectionLevel();
\r