private static int chooseMaskPattern(BitArray bits, ErrorCorrectionLevel ecLevel, Version version, ByteMatrix matrix) throws WriterException { int minPenalty = Integer.MAX_VALUE; // Lower penalty is better. int bestMaskPattern = -1; // We try all mask patterns to choose the best one. for (int maskPattern = 0; maskPattern < QRCode.NUM_MASK_PATTERNS; maskPattern++) { MatrixUtil.buildMatrix(bits, ecLevel, version, maskPattern, matrix); int penalty = calculateMaskPenalty(matrix); if (penalty < minPenalty) { minPenalty = penalty; bestMaskPattern = maskPattern; } } return bestMaskPattern; }
private static Version chooseVersion(int numInputBits, ErrorCorrectionLevel ecLevel) throws WriterException { // In the following comments, we use numbers of Version 7-H. for (int versionNum = 1; versionNum <= 40; versionNum++) { Version version = Version.getVersionForNumber(versionNum); // numBytes = 196 int numBytes = version.getTotalCodewords(); // getNumECBytes = 130 Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel); int numEcBytes = ecBlocks.getTotalECCodewords(); // getNumDataBytes = 196 - 130 = 66 int numDataBytes = numBytes - numEcBytes; int totalInputBytes = (numInputBits + 7) / 8; if (numDataBytes >= totalInputBytes) { return version; } } throw new WriterException("Data too big"); }
static void maybeEmbedVersionInfo(Version version, ByteMatrix matrix) throws WriterException { if (version.getVersionNumber() < 7) { // Version info is necessary if version >= 7. return; // Don't need version info. } BitArray versionInfoBits = new BitArray(); makeVersionInfoBits(version, versionInfoBits); int bitIndex = 6 * 3 - 1; // It will decrease from 17 to 0. for (int i = 0; i < 6; ++i) { for (int j = 0; j < 3; ++j) { // Place bits in LSB (least significant bit) to MSB order. boolean bit = versionInfoBits.get(bitIndex); bitIndex--; // Left bottom corner. matrix.set(i, matrix.getHeight() - 11 + j, bit); // Right bottom corner. matrix.set(matrix.getHeight() - 11 + j, i, bit); } } }
private static void maybeEmbedPositionAdjustmentPatterns(Version version, ByteMatrix matrix) { if (version.getVersionNumber() < 2) { // The patterns appear if version >= 2 return; } int index = version.getVersionNumber() - 1; int[] coordinates = POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index]; int numCoordinates = POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index].length; for (int i = 0; i < numCoordinates; ++i) { for (int j = 0; j < numCoordinates; ++j) { int y = coordinates[i]; int x = coordinates[j]; if (x == -1 || y == -1) { continue; } // If the cell is unset, we embed the position adjustment pattern here. if (isEmpty(matrix.get(x, y))) { // -2 is necessary since the x/y coordinates point to the center of the pattern, not the // left top corner. embedPositionAdjustmentPattern(x - 2, y - 2, matrix); } } } }
private static void maybeEmbedPositionAdjustmentPatterns(Version version, ByteMatrix matrix) { if (version.getVersionNumber() >= 2) { int index = version.getVersionNumber() - 1; int[] coordinates = POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index]; int numCoordinates = POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index].length; for (int i = 0; i < numCoordinates; i++) { for (int j = 0; j < numCoordinates; j++) { int y = coordinates[i]; int x = coordinates[j]; if (!(x == -1 || y == -1 || !isEmpty(matrix.get(x, y)))) { embedPositionAdjustmentPattern(x - 2, y - 2, matrix); } } } } }
private static void maybeEmbedPositionAdjustmentPatterns(Version version, ByteMatrix matrix) { if (version.getVersionNumber() < 2) { // The patterns appear if version >= 2 return; } int index = version.getVersionNumber() - 1; int[] coordinates = POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index]; for (int y : coordinates) { if (y >= 0) { for (int x : coordinates) { if (x >= 0 && isEmpty(matrix.get(x, y))) { // If the cell is unset, we embed the position adjustment pattern here. // -2 is necessary since the x/y coordinates point to the center of the pattern, not the // left top corner. embedPositionAdjustmentPattern(x - 2, y - 2, matrix); } } } } }