private static int chooseMaskPattern(BitArray bits, ErrorCorrectionLevel ecLevel, int 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; }
public static void buildMatrix(BitArray dataBits, ErrorCorrectionLevel ecLevel, int version, int maskPattern, ByteMatrix matrix) throws WriterException { clearMatrix(matrix); embedBasicPatterns(version, matrix); // Type information appear with any version. embedTypeInfo(ecLevel, maskPattern, matrix); // Version info appear if version >= 7. maybeEmbedVersionInfo(version, matrix); // Data should be embedded at end. embedDataBits(dataBits, maskPattern, matrix); }
static void embedBasicPatterns(Version version, ByteMatrix matrix) throws WriterException { // Let's get started with embedding big squares at corners. embedPositionDetectionPatternsAndSeparators(matrix); // Then, embed the dark dot at the left bottom corner. embedDarkDotAtLeftBottomCorner(matrix); // Position adjustment patterns appear if version >= 2. maybeEmbedPositionAdjustmentPatterns(version, matrix); // Timing patterns should be embedded after position adj. patterns. embedTimingPatterns(matrix); }
private static void maybeEmbedPositionAdjustmentPatterns(int version, ByteMatrix matrix) throws WriterException { if (version < 2) { // The patterns appear if version >= 2 return; } int index = version - 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 embedPositionDetectionPatternsAndSeparators(ByteMatrix matrix) throws WriterException { // Embed three big squares at corners. int pdpWidth = POSITION_DETECTION_PATTERN[0].length; // Left top corner. embedPositionDetectionPattern(0, 0, matrix); // Right top corner. embedPositionDetectionPattern(matrix.getWidth() - pdpWidth, 0, matrix); // Left bottom corner. embedPositionDetectionPattern(0, matrix.getWidth() - pdpWidth, matrix); // Embed horizontal separation patterns around the squares. int hspWidth = 8; // Left top corner. embedHorizontalSeparationPattern(0, hspWidth - 1, matrix); // Right top corner. embedHorizontalSeparationPattern(matrix.getWidth() - hspWidth, hspWidth - 1, matrix); // Left bottom corner. embedHorizontalSeparationPattern(0, matrix.getWidth() - hspWidth, matrix); // Embed vertical separation patterns around the squares. int vspSize = 7; // Left top corner. embedVerticalSeparationPattern(vspSize, 0, matrix); // Right top corner. embedVerticalSeparationPattern(matrix.getHeight() - vspSize - 1, 0, matrix); // Left bottom corner. embedVerticalSeparationPattern(vspSize, matrix.getHeight() - vspSize, matrix); }
public static void makeVersionInfoBits(int version, BitArray bits) throws WriterException { bits.appendBits(version, 6); int bchCode = calculateBCHCode(version, VERSION_INFO_POLY); bits.appendBits(bchCode, 12); if (bits.getSize() != 18) { // Just in case. throw new WriterException("should not happen but we got: " + bits.getSize()); } }
private static void embedPositionDetectionPatternsAndSeparators(ByteMatrix matrix) throws WriterException { // Embed three big squares at corners. int pdpWidth = POSITION_DETECTION_PATTERN[0].length; // Left top corner. embedPositionDetectionPattern(0, 0, matrix); // Right top corner. embedPositionDetectionPattern(matrix.getWidth() - pdpWidth, 0, matrix); // Left bottom corner. embedPositionDetectionPattern(0, matrix.getWidth() - pdpWidth, matrix); // Embed horizontal separation patterns around the squares. int hspWidth = HORIZONTAL_SEPARATION_PATTERN[0].length; // Left top corner. embedHorizontalSeparationPattern(0, hspWidth - 1, matrix); // Right top corner. embedHorizontalSeparationPattern(matrix.getWidth() - hspWidth, hspWidth - 1, matrix); // Left bottom corner. embedHorizontalSeparationPattern(0, matrix.getWidth() - hspWidth, matrix); // Embed vertical separation patterns around the squares. int vspSize = VERTICAL_SEPARATION_PATTERN.length; // Left top corner. embedVerticalSeparationPattern(vspSize, 0, matrix); // Right top corner. embedVerticalSeparationPattern(matrix.getHeight() - vspSize - 1, 0, matrix); // Left bottom corner. embedVerticalSeparationPattern(vspSize, matrix.getHeight() - vspSize, matrix); }
private static void maybeEmbedPositionAdjustmentPatterns(int version, ByteMatrix matrix) throws WriterException { if (version < 2) { // The patterns appear if version >= 2 return; } int index = version - 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); } } } }
public static void makeVersionInfoBits(int version, BitArray bits) throws WriterException { bits.appendBits(version, 6); int bchCode = calculateBCHCode(version, VERSION_INFO_POLY); bits.appendBits(bchCode, 12); if (bits.getSize() != 18) { // Just in case. throw new WriterException("should not happen but we got: " + bits.getSize()); } }
public static void buildMatrix(BitArray dataBits, ErrorCorrectionLevel ecLevel, int version, int maskPattern, ByteMatrix matrix) throws WriterException { clearMatrix(matrix); embedBasicPatterns(version, matrix); // Type information appear with any version. embedTypeInfo(ecLevel, maskPattern, matrix); // Version info appear if version >= 7. maybeEmbedVersionInfo(version, matrix); // Data should be embedded at end. embedDataBits(dataBits, maskPattern, matrix); }
static void embedBasicPatterns(Version version, ByteMatrix matrix) throws WriterException { // Let's get started with embedding big squares at corners. embedPositionDetectionPatternsAndSeparators(matrix); // Then, embed the dark dot at the left bottom corner. embedDarkDotAtLeftBottomCorner(matrix); // Position adjustment patterns appear if version >= 2. maybeEmbedPositionAdjustmentPatterns(version, matrix); // Timing patterns should be embedded after position adj. patterns. embedTimingPatterns(matrix); }
private static void embedPositionDetectionPatternsAndSeparators(ByteMatrix matrix) throws WriterException { // Embed three big squares at corners. int pdpWidth = POSITION_DETECTION_PATTERN[0].length; // Left top corner. embedPositionDetectionPattern(0, 0, matrix); // Right top corner. embedPositionDetectionPattern(matrix.getWidth() - pdpWidth, 0, matrix); // Left bottom corner. embedPositionDetectionPattern(0, matrix.getWidth() - pdpWidth, matrix); // Embed horizontal separation patterns around the squares. int hspWidth = 8; // Left top corner. embedHorizontalSeparationPattern(0, hspWidth - 1, matrix); // Right top corner. embedHorizontalSeparationPattern(matrix.getWidth() - hspWidth, hspWidth - 1, matrix); // Left bottom corner. embedHorizontalSeparationPattern(0, matrix.getWidth() - hspWidth, matrix); // Embed vertical separation patterns around the squares. int vspSize = 7; // Left top corner. embedVerticalSeparationPattern(vspSize, 0, matrix); // Right top corner. embedVerticalSeparationPattern(matrix.getHeight() - vspSize - 1, 0, matrix); // Left bottom corner. embedVerticalSeparationPattern(vspSize, matrix.getHeight() - vspSize, 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); } } } } }
static void makeVersionInfoBits(Version version, BitArray bits) throws WriterException { bits.appendBits(version.getVersionNumber(), 6); int bchCode = calculateBCHCode(version.getVersionNumber(), VERSION_INFO_POLY); bits.appendBits(bchCode, 12); if (bits.getSize() != 18) { // Just in case. throw new WriterException("should not happen but we got: " + bits.getSize()); } }
private static int chooseMaskPattern(BitArray bits, ErrorCorrectionLevel ecLevel, int 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; }
static void buildMatrix(BitArray dataBits, ErrorCorrectionLevel ecLevel, Version version, int maskPattern, ByteMatrix matrix) throws WriterException { clearMatrix(matrix); embedBasicPatterns(version, matrix); // Type information appear with any version. embedTypeInfo(ecLevel, maskPattern, matrix); // Version info appear if version >= 7. maybeEmbedVersionInfo(version, matrix); // Data should be embedded at end. embedDataBits(dataBits, maskPattern, matrix); }
public static void embedBasicPatterns(int version, ByteMatrix matrix) throws WriterException { // Let's get started with embedding big squares at corners. embedPositionDetectionPatternsAndSeparators(matrix); // Then, embed the dark dot at the left bottom corner. embedDarkDotAtLeftBottomCorner(matrix); // Position adjustment patterns appear if version >= 2. maybeEmbedPositionAdjustmentPatterns(version, matrix); // Timing patterns should be embedded after position adj. patterns. embedTimingPatterns(matrix); }
private static void embedPositionDetectionPatternsAndSeparators(ByteMatrix matrix) throws WriterException { // Embed three big squares at corners. int pdpWidth = POSITION_DETECTION_PATTERN[0].length; // Left top corner. embedPositionDetectionPattern(0, 0, matrix); // Right top corner. embedPositionDetectionPattern(matrix.getWidth() - pdpWidth, 0, matrix); // Left bottom corner. embedPositionDetectionPattern(0, matrix.getWidth() - pdpWidth, matrix); // Embed horizontal separation patterns around the squares. int hspWidth = HORIZONTAL_SEPARATION_PATTERN[0].length; // Left top corner. embedHorizontalSeparationPattern(0, hspWidth - 1, matrix); // Right top corner. embedHorizontalSeparationPattern(matrix.getWidth() - hspWidth, hspWidth - 1, matrix); // Left bottom corner. embedHorizontalSeparationPattern(0, matrix.getWidth() - hspWidth, matrix); // Embed vertical separation patterns around the squares. int vspSize = VERTICAL_SEPARATION_PATTERN.length; // Left top corner. embedVerticalSeparationPattern(vspSize, 0, matrix); // Right top corner. embedVerticalSeparationPattern(matrix.getHeight() - vspSize - 1, 0, matrix); // Left bottom corner. embedVerticalSeparationPattern(vspSize, matrix.getHeight() - vspSize, 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); } } } } }
static void makeVersionInfoBits(Version version, BitArray bits) throws WriterException { bits.appendBits(version.getVersionNumber(), 6); int bchCode = calculateBCHCode(version.getVersionNumber(), VERSION_INFO_POLY); bits.appendBits(bchCode, 12); if (bits.getSize() != 18) { // Just in case. throw new WriterException("should not happen but we got: " + bits.getSize()); } }