BarcodeMetadata getBarcodeMetadata() { Codeword[] codewords = getCodewords(); BarcodeValue barcodeColumnCount = new BarcodeValue(); BarcodeValue barcodeRowCountUpperPart = new BarcodeValue(); BarcodeValue barcodeRowCountLowerPart = new BarcodeValue(); BarcodeValue barcodeECLevel = new BarcodeValue(); for (Codeword codeword : codewords) { if (codeword == null) { continue; } codeword.setRowNumberAsRowIndicatorColumn(); int rowIndicatorValue = codeword.getValue() % 30; int codewordRowNumber = codeword.getRowNumber(); if (!isLeft) { codewordRowNumber += 2; } switch (codewordRowNumber % 3) { case 0: barcodeRowCountUpperPart.setValue(rowIndicatorValue * 3 + 1); break; case 1: barcodeECLevel.setValue(rowIndicatorValue / 3); barcodeRowCountLowerPart.setValue(rowIndicatorValue % 3); break; case 2: barcodeColumnCount.setValue(rowIndicatorValue + 1); break; } } // Maybe we should check if we have ambiguous values? if ((barcodeColumnCount.getValue().length == 0) || (barcodeRowCountUpperPart.getValue().length == 0) || (barcodeRowCountLowerPart.getValue().length == 0) || (barcodeECLevel.getValue().length == 0) || barcodeColumnCount.getValue()[0] < 1 || barcodeRowCountUpperPart.getValue()[0] + barcodeRowCountLowerPart.getValue()[0] < PDF417Common.MIN_ROWS_IN_BARCODE || barcodeRowCountUpperPart.getValue()[0] + barcodeRowCountLowerPart.getValue()[0] > PDF417Common.MAX_ROWS_IN_BARCODE) { return null; } BarcodeMetadata barcodeMetadata = new BarcodeMetadata( barcodeColumnCount.getValue()[0], barcodeRowCountUpperPart.getValue()[0], barcodeRowCountLowerPart.getValue()[0], barcodeECLevel.getValue()[0]); removeIncorrectCodewords(codewords, barcodeMetadata); return barcodeMetadata; }
private void removeIncorrectCodewords(Codeword[] codewords, BarcodeMetadata barcodeMetadata) { // Remove codewords which do not match the metadata // TODO Maybe we should keep the incorrect codewords for the start and end positions? for (int codewordRow = 0; codewordRow < codewords.length; codewordRow++) { Codeword codeword = codewords[codewordRow]; if (codewords[codewordRow] == null) { continue; } int rowIndicatorValue = codeword.getValue() % 30; int codewordRowNumber = codeword.getRowNumber(); if (codewordRowNumber > barcodeMetadata.getRowCount()) { codewords[codewordRow] = null; continue; } if (!isLeft) { codewordRowNumber += 2; } switch (codewordRowNumber % 3) { case 0: if (rowIndicatorValue * 3 + 1 != barcodeMetadata.getRowCountUpperPart()) { codewords[codewordRow] = null; } break; case 1: if (rowIndicatorValue / 3 != barcodeMetadata.getErrorCorrectionLevel() || rowIndicatorValue % 3 != barcodeMetadata.getRowCountLowerPart()) { codewords[codewordRow] = null; } break; case 2: if (rowIndicatorValue + 1 != barcodeMetadata.getColumnCount()) { codewords[codewordRow] = null; } break; } } }