| OLD | NEW |
| (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 2013 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 "core/include/fxcrt/fx_basic.h" | |
| 24 #include "xfa/src/fxbarcode/BC_ResultPoint.h" | |
| 25 #include "xfa/src/fxbarcode/pdf417/BC_PDF417BarcodeMetadata.h" | |
| 26 #include "xfa/src/fxbarcode/pdf417/BC_PDF417BarcodeValue.h" | |
| 27 #include "xfa/src/fxbarcode/pdf417/BC_PDF417BoundingBox.h" | |
| 28 #include "xfa/src/fxbarcode/pdf417/BC_PDF417Codeword.h" | |
| 29 #include "xfa/src/fxbarcode/pdf417/BC_PDF417Common.h" | |
| 30 #include "xfa/src/fxbarcode/pdf417/BC_PDF417DetectionResultColumn.h" | |
| 31 #include "xfa/src/fxbarcode/pdf417/BC_PDF417DetectionResultRowIndicatorColumn.h" | |
| 32 #include "xfa/src/fxbarcode/utils.h" | |
| 33 | |
| 34 CBC_DetectionResultRowIndicatorColumn::CBC_DetectionResultRowIndicatorColumn( | |
| 35 CBC_BoundingBox* boundingBox, | |
| 36 FX_BOOL isLeft) | |
| 37 : CBC_DetectionResultColumn(boundingBox) { | |
| 38 m_isLeft = isLeft; | |
| 39 } | |
| 40 CBC_DetectionResultRowIndicatorColumn:: | |
| 41 ~CBC_DetectionResultRowIndicatorColumn() {} | |
| 42 void CBC_DetectionResultRowIndicatorColumn::setRowNumbers() { | |
| 43 for (int32_t i = 0; i < m_codewords->GetSize(); i++) { | |
| 44 CBC_Codeword* codeword = (CBC_Codeword*)m_codewords->GetAt(i); | |
| 45 if (codeword) { | |
| 46 codeword->setRowNumberAsRowIndicatorColumn(); | |
| 47 } | |
| 48 } | |
| 49 } | |
| 50 int32_t | |
| 51 CBC_DetectionResultRowIndicatorColumn::adjustCompleteIndicatorColumnRowNumbers( | |
| 52 CBC_BarcodeMetadata barcodeMetadata) { | |
| 53 CFX_PtrArray* codewords = getCodewords(); | |
| 54 setRowNumbers(); | |
| 55 removeIncorrectCodewords(codewords, barcodeMetadata); | |
| 56 CBC_BoundingBox* boundingBox = getBoundingBox(); | |
| 57 CBC_ResultPoint* top = | |
| 58 m_isLeft ? boundingBox->getTopLeft() : boundingBox->getTopRight(); | |
| 59 CBC_ResultPoint* bottom = | |
| 60 m_isLeft ? boundingBox->getBottomLeft() : boundingBox->getBottomRight(); | |
| 61 int32_t firstRow = imageRowToCodewordIndex((int32_t)top->GetY()); | |
| 62 int32_t lastRow = imageRowToCodewordIndex((int32_t)bottom->GetY()); | |
| 63 FX_FLOAT averageRowHeight = | |
| 64 (lastRow - firstRow) / (FX_FLOAT)barcodeMetadata.getRowCount(); | |
| 65 int32_t barcodeRow = -1; | |
| 66 int32_t maxRowHeight = 1; | |
| 67 int32_t currentRowHeight = 0; | |
| 68 for (int32_t codewordsRow = firstRow; codewordsRow < lastRow; | |
| 69 codewordsRow++) { | |
| 70 if (codewords->GetAt(codewordsRow) == NULL) { | |
| 71 continue; | |
| 72 } | |
| 73 CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordsRow); | |
| 74 int32_t rowDifference = codeword->getRowNumber() - barcodeRow; | |
| 75 if (rowDifference == 0) { | |
| 76 currentRowHeight++; | |
| 77 } else if (rowDifference == 1) { | |
| 78 maxRowHeight = | |
| 79 maxRowHeight > currentRowHeight ? maxRowHeight : currentRowHeight; | |
| 80 currentRowHeight = 1; | |
| 81 barcodeRow = codeword->getRowNumber(); | |
| 82 } else if (rowDifference < 0) { | |
| 83 codewords->SetAt(codewordsRow, NULL); | |
| 84 } else if (codeword->getRowNumber() >= barcodeMetadata.getRowCount()) { | |
| 85 codewords->SetAt(codewordsRow, NULL); | |
| 86 } else if (rowDifference > codewordsRow) { | |
| 87 codewords->SetAt(codewordsRow, NULL); | |
| 88 } else { | |
| 89 int32_t checkedRows; | |
| 90 if (maxRowHeight > 2) { | |
| 91 checkedRows = (maxRowHeight - 2) * rowDifference; | |
| 92 } else { | |
| 93 checkedRows = rowDifference; | |
| 94 } | |
| 95 FX_BOOL closePreviousCodewordFound = checkedRows >= codewordsRow; | |
| 96 for (int32_t i = 1; i <= checkedRows && !closePreviousCodewordFound; | |
| 97 i++) { | |
| 98 closePreviousCodewordFound = codewords->GetAt(codewordsRow - i) != NULL; | |
| 99 } | |
| 100 if (closePreviousCodewordFound) { | |
| 101 codewords->SetAt(codewordsRow, NULL); | |
| 102 } else { | |
| 103 barcodeRow = codeword->getRowNumber(); | |
| 104 currentRowHeight = 1; | |
| 105 } | |
| 106 } | |
| 107 } | |
| 108 return (int32_t)(averageRowHeight + 0.5); | |
| 109 } | |
| 110 CFX_Int32Array* CBC_DetectionResultRowIndicatorColumn::getRowHeights( | |
| 111 int32_t& e) { | |
| 112 CBC_BarcodeMetadata* barcodeMetadata = getBarcodeMetadata(); | |
| 113 if (barcodeMetadata == NULL) { | |
| 114 e = BCExceptionCannotMetadata; | |
| 115 return NULL; | |
| 116 } | |
| 117 adjustIncompleteIndicatorColumnRowNumbers(*barcodeMetadata); | |
| 118 CFX_Int32Array* result = new CFX_Int32Array; | |
| 119 result->SetSize(barcodeMetadata->getRowCount()); | |
| 120 for (int32_t i = 0; i < getCodewords()->GetSize(); i++) { | |
| 121 CBC_Codeword* codeword = (CBC_Codeword*)getCodewords()->GetAt(i); | |
| 122 if (codeword) { | |
| 123 result->SetAt(codeword->getRowNumber(), | |
| 124 result->GetAt(codeword->getRowNumber()) + 1); | |
| 125 } | |
| 126 } | |
| 127 return result; | |
| 128 } | |
| 129 int32_t CBC_DetectionResultRowIndicatorColumn:: | |
| 130 adjustIncompleteIndicatorColumnRowNumbers( | |
| 131 CBC_BarcodeMetadata barcodeMetadata) { | |
| 132 CBC_BoundingBox* boundingBox = getBoundingBox(); | |
| 133 CBC_ResultPoint* top = | |
| 134 m_isLeft ? boundingBox->getTopLeft() : boundingBox->getTopRight(); | |
| 135 CBC_ResultPoint* bottom = | |
| 136 m_isLeft ? boundingBox->getBottomLeft() : boundingBox->getBottomRight(); | |
| 137 int32_t firstRow = imageRowToCodewordIndex((int32_t)top->GetY()); | |
| 138 int32_t lastRow = imageRowToCodewordIndex((int32_t)bottom->GetY()); | |
| 139 FX_FLOAT averageRowHeight = | |
| 140 (lastRow - firstRow) / (FX_FLOAT)barcodeMetadata.getRowCount(); | |
| 141 CFX_PtrArray* codewords = getCodewords(); | |
| 142 int32_t barcodeRow = -1; | |
| 143 int32_t maxRowHeight = 1; | |
| 144 int32_t currentRowHeight = 0; | |
| 145 for (int32_t codewordsRow = firstRow; codewordsRow < lastRow; | |
| 146 codewordsRow++) { | |
| 147 if (codewords->GetAt(codewordsRow) == NULL) { | |
| 148 continue; | |
| 149 } | |
| 150 CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordsRow); | |
| 151 codeword->setRowNumberAsRowIndicatorColumn(); | |
| 152 int32_t rowDifference = codeword->getRowNumber() - barcodeRow; | |
| 153 if (rowDifference == 0) { | |
| 154 currentRowHeight++; | |
| 155 } else if (rowDifference == 1) { | |
| 156 maxRowHeight = | |
| 157 maxRowHeight > currentRowHeight ? maxRowHeight : currentRowHeight; | |
| 158 currentRowHeight = 1; | |
| 159 barcodeRow = codeword->getRowNumber(); | |
| 160 } else if (codeword->getRowNumber() >= barcodeMetadata.getRowCount()) { | |
| 161 codewords->SetAt(codewordsRow, NULL); | |
| 162 } else { | |
| 163 barcodeRow = codeword->getRowNumber(); | |
| 164 currentRowHeight = 1; | |
| 165 } | |
| 166 } | |
| 167 return (int32_t)(averageRowHeight + 0.5); | |
| 168 } | |
| 169 CBC_BarcodeMetadata* | |
| 170 CBC_DetectionResultRowIndicatorColumn::getBarcodeMetadata() { | |
| 171 CFX_PtrArray* codewords = getCodewords(); | |
| 172 CBC_BarcodeValue barcodeColumnCount; | |
| 173 CBC_BarcodeValue barcodeRowCountUpperPart; | |
| 174 CBC_BarcodeValue barcodeRowCountLowerPart; | |
| 175 CBC_BarcodeValue barcodeECLevel; | |
| 176 for (int32_t i = 0; i < codewords->GetSize(); i++) { | |
| 177 CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(i); | |
| 178 if (codeword == NULL) { | |
| 179 continue; | |
| 180 } | |
| 181 codeword->setRowNumberAsRowIndicatorColumn(); | |
| 182 int32_t rowIndicatorValue = codeword->getValue() % 30; | |
| 183 int32_t codewordRowNumber = codeword->getRowNumber(); | |
| 184 if (!m_isLeft) { | |
| 185 codewordRowNumber += 2; | |
| 186 } | |
| 187 switch (codewordRowNumber % 3) { | |
| 188 case 0: | |
| 189 barcodeRowCountUpperPart.setValue(rowIndicatorValue * 3 + 1); | |
| 190 break; | |
| 191 case 1: | |
| 192 barcodeECLevel.setValue(rowIndicatorValue / 3); | |
| 193 barcodeRowCountLowerPart.setValue(rowIndicatorValue % 3); | |
| 194 break; | |
| 195 case 2: | |
| 196 barcodeColumnCount.setValue(rowIndicatorValue + 1); | |
| 197 break; | |
| 198 } | |
| 199 } | |
| 200 if ((barcodeColumnCount.getValue()->GetSize() == 0) || | |
| 201 (barcodeRowCountUpperPart.getValue()->GetSize() == 0) || | |
| 202 (barcodeRowCountLowerPart.getValue()->GetSize() == 0) || | |
| 203 (barcodeECLevel.getValue()->GetSize() == 0) || | |
| 204 barcodeColumnCount.getValue()->GetAt(0) < 1 || | |
| 205 barcodeRowCountUpperPart.getValue()->GetAt(0) + | |
| 206 barcodeRowCountLowerPart.getValue()->GetAt(0) < | |
| 207 CBC_PDF417Common::MIN_ROWS_IN_BARCODE || | |
| 208 barcodeRowCountUpperPart.getValue()->GetAt(0) + | |
| 209 barcodeRowCountLowerPart.getValue()->GetAt(0) > | |
| 210 CBC_PDF417Common::MAX_ROWS_IN_BARCODE) { | |
| 211 return NULL; | |
| 212 } | |
| 213 CBC_BarcodeMetadata* barcodeMetadata = | |
| 214 new CBC_BarcodeMetadata(barcodeColumnCount.getValue()->GetAt(0), | |
| 215 barcodeRowCountUpperPart.getValue()->GetAt(0), | |
| 216 barcodeRowCountLowerPart.getValue()->GetAt(0), | |
| 217 barcodeECLevel.getValue()->GetAt(0)); | |
| 218 removeIncorrectCodewords(codewords, *barcodeMetadata); | |
| 219 return barcodeMetadata; | |
| 220 } | |
| 221 FX_BOOL CBC_DetectionResultRowIndicatorColumn::isLeft() { | |
| 222 return m_isLeft; | |
| 223 } | |
| 224 CFX_ByteString CBC_DetectionResultRowIndicatorColumn::toString() { | |
| 225 return (CFX_ByteString) "IsLeft: " + (CFX_ByteString)m_isLeft + '\n' + | |
| 226 CBC_DetectionResultColumn::toString(); | |
| 227 } | |
| 228 void CBC_DetectionResultRowIndicatorColumn::removeIncorrectCodewords( | |
| 229 CFX_PtrArray* codewords, | |
| 230 CBC_BarcodeMetadata barcodeMetadata) { | |
| 231 for (int32_t codewordRow = 0; codewordRow < codewords->GetSize(); | |
| 232 codewordRow++) { | |
| 233 CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordRow); | |
| 234 if (codeword == NULL) { | |
| 235 continue; | |
| 236 } | |
| 237 int32_t rowIndicatorValue = codeword->getValue() % 30; | |
| 238 int32_t codewordRowNumber = codeword->getRowNumber(); | |
| 239 if (codewordRowNumber > barcodeMetadata.getRowCount()) { | |
| 240 codewords->SetAt(codewordRow, NULL); | |
| 241 continue; | |
| 242 } | |
| 243 if (!m_isLeft) { | |
| 244 codewordRowNumber += 2; | |
| 245 } | |
| 246 switch (codewordRowNumber % 3) { | |
| 247 case 0: | |
| 248 if (rowIndicatorValue * 3 + 1 != | |
| 249 barcodeMetadata.getRowCountUpperPart()) { | |
| 250 codewords->SetAt(codewordRow, NULL); | |
| 251 } | |
| 252 break; | |
| 253 case 1: | |
| 254 if (rowIndicatorValue / 3 != | |
| 255 barcodeMetadata.getErrorCorrectionLevel() || | |
| 256 rowIndicatorValue % 3 != barcodeMetadata.getRowCountLowerPart()) { | |
| 257 codewords->SetAt(codewordRow, NULL); | |
| 258 } | |
| 259 break; | |
| 260 case 2: | |
| 261 if (rowIndicatorValue + 1 != barcodeMetadata.getColumnCount()) { | |
| 262 codewords->SetAt(codewordRow, NULL); | |
| 263 } | |
| 264 break; | |
| 265 } | |
| 266 } | |
| 267 } | |
| OLD | NEW |