/** * @param bitMatrix {@link BitMatrix} to parse * @throws FormatException if dimension is < 8 or > 144 or not 0 mod 2 */ BitMatrixParser(BitMatrix bitMatrix) throws FormatException { int dimension = bitMatrix.getHeight(); if (dimension < 8 || dimension > 144 || (dimension & 0x01) != 0) { throw FormatException.getFormatInstance(); } version = readVersion(bitMatrix); this.mappingBitMatrix = extractDataRegion(bitMatrix); this.readMappingMatrix = new BitMatrix(this.mappingBitMatrix.getWidth(), this.mappingBitMatrix.getHeight()); }
/** * Reads the bits in the {@link BitMatrix} representing the mapping matrix (No alignment patterns) * in the correct order in order to reconstitute the codewords bytes contained within the Data * Matrix Code. * * @return bytes encoded within the Data Matrix Code * @throws FormatException if the exact number of bytes expected is not read */ byte[] readCodewords() throws FormatException { byte[] result = new byte[version.getTotalCodewords()]; int resultOffset = 0; int row = 4; int column = 0; int numRows = mappingBitMatrix.getHeight(); int numColumns = mappingBitMatrix.getWidth(); boolean corner1Read = false; boolean corner2Read = false; boolean corner3Read = false; boolean corner4Read = false; // Read all of the codewords do { // Check the four corner cases if ((row == numRows) && (column == 0) && !corner1Read) { result[resultOffset++] = (byte) readCorner1(numRows, numColumns); row -= 2; column += 2; corner1Read = true; } else if ((row == numRows - 2) && (column == 0) && ((numColumns & 0x03) != 0) && !corner2Read) { result[resultOffset++] = (byte) readCorner2(numRows, numColumns); row -= 2; column += 2; corner2Read = true; } else if ((row == numRows + 4) && (column == 2) && ((numColumns & 0x07) == 0) && !corner3Read) { result[resultOffset++] = (byte) readCorner3(numRows, numColumns); row -= 2; column += 2; corner3Read = true; } else if ((row == numRows - 2) && (column == 0) && ((numColumns & 0x07) == 4) && !corner4Read) { result[resultOffset++] = (byte) readCorner4(numRows, numColumns); row -= 2; column += 2; corner4Read = true; } else { // Sweep upward diagonally to the right do { if ((row < numRows) && (column >= 0) && !readMappingMatrix.get(column, row)) { result[resultOffset++] = (byte) readUtah(row, column, numRows, numColumns); } row -= 2; column += 2; } while ((row >= 0) && (column < numColumns)); row += 1; column += 3; // Sweep downward diagonally to the left do { if ((row >= 0) && (column < numColumns) && !readMappingMatrix.get(column, row)) { result[resultOffset++] = (byte) readUtah(row, column, numRows, numColumns); } row += 2; column -= 2; } while ((row < numRows) && (column >= 0)); row += 3; column += 1; } } while ((row < numRows) || (column < numColumns)); if (resultOffset != version.getTotalCodewords()) { throw FormatException.getFormatInstance(); } return result; }