mirror of
https://github.com/zxing/zxing.git
synced 2024-11-10 04:54:04 -08:00
Issue 1758 correct corner case of mask pattern penalty 3
git-svn-id: https://zxing.googlecode.com/svn/trunk@2866 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
99f4f03f9a
commit
8d18bab224
|
@ -63,61 +63,61 @@ final class MaskUtil {
|
|||
}
|
||||
|
||||
/**
|
||||
* Apply mask penalty rule 3 and return the penalty. Find consecutive cells of 00001011101 or
|
||||
* 10111010000, and give penalty to them. If we find patterns like 000010111010000, we give
|
||||
* penalties twice (i.e. 40 * 2).
|
||||
* Apply mask penalty rule 3 and return the penalty. Find consecutive runs of 1:1:3:1:1:4
|
||||
* starting with black, or 4:1:1:3:1:1 starting with white, and give penalty to them. If we
|
||||
* find patterns like 000010111010000, we give penalty once.
|
||||
*/
|
||||
static int applyMaskPenaltyRule3(ByteMatrix matrix) {
|
||||
int penalty = 0;
|
||||
int numPenalties = 0;
|
||||
byte[][] array = matrix.getArray();
|
||||
int width = matrix.getWidth();
|
||||
int height = matrix.getHeight();
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
// Tried to simplify following conditions but failed.
|
||||
if (x + 6 < width &&
|
||||
array[y][x] == 1 &&
|
||||
array[y][x + 1] == 0 &&
|
||||
array[y][x + 2] == 1 &&
|
||||
array[y][x + 3] == 1 &&
|
||||
array[y][x + 4] == 1 &&
|
||||
array[y][x + 5] == 0 &&
|
||||
array[y][x + 6] == 1 &&
|
||||
((x + 10 < width &&
|
||||
array[y][x + 7] == 0 &&
|
||||
array[y][x + 8] == 0 &&
|
||||
array[y][x + 9] == 0 &&
|
||||
array[y][x + 10] == 0) ||
|
||||
(x - 4 >= 0 &&
|
||||
array[y][x - 1] == 0 &&
|
||||
array[y][x - 2] == 0 &&
|
||||
array[y][x - 3] == 0 &&
|
||||
array[y][x - 4] == 0))) {
|
||||
penalty += N3;
|
||||
byte[] arrayY = array[y]; // We can at least optimize this access
|
||||
if (x + 8 < width &&
|
||||
arrayY[x] == 0 &&
|
||||
arrayY[x + 1] == 1 &&
|
||||
arrayY[x + 2] == 0 &&
|
||||
arrayY[x + 3] == 1 &&
|
||||
arrayY[x + 4] == 1 &&
|
||||
arrayY[x + 5] == 1 &&
|
||||
arrayY[x + 6] == 0 &&
|
||||
arrayY[x + 7] == 1 &&
|
||||
arrayY[x + 8] == 0 &&
|
||||
((x + 11 < width &&
|
||||
arrayY[x + 9] == 0 &&
|
||||
arrayY[x + 10] == 0 &&
|
||||
arrayY[x + 11] == 0) ||
|
||||
(x - 3 >= 0 &&
|
||||
arrayY[x - 1] == 0 &&
|
||||
arrayY[x - 2] == 0 &&
|
||||
arrayY[x - 3] == 0))) {
|
||||
numPenalties++;
|
||||
}
|
||||
if (y + 6 < height &&
|
||||
array[y][x] == 1 &&
|
||||
array[y + 1][x] == 0 &&
|
||||
array[y + 2][x] == 1 &&
|
||||
array[y + 3][x] == 1 &&
|
||||
array[y + 4][x] == 1 &&
|
||||
array[y + 5][x] == 0 &&
|
||||
array[y + 6][x] == 1 &&
|
||||
((y + 10 < height &&
|
||||
array[y + 7][x] == 0 &&
|
||||
array[y + 8][x] == 0 &&
|
||||
if (y + 8 < height &&
|
||||
array[y][x] == 0 &&
|
||||
array[y + 1][x] == 1 &&
|
||||
array[y + 2][x] == 0 &&
|
||||
array[y + 3][x] == 1 &&
|
||||
array[y + 4][x] == 1 &&
|
||||
array[y + 5][x] == 1 &&
|
||||
array[y + 6][x] == 0 &&
|
||||
array[y + 7][x] == 1 &&
|
||||
array[y + 8][x] == 0 &&
|
||||
((y + 11 < height &&
|
||||
array[y + 9][x] == 0 &&
|
||||
array[y + 10][x] == 0) ||
|
||||
(y - 4 >= 0 &&
|
||||
array[y + 10][x] == 0 &&
|
||||
array[y + 11][x] == 0) ||
|
||||
(y - 3 >= 0 &&
|
||||
array[y - 1][x] == 0 &&
|
||||
array[y - 2][x] == 0 &&
|
||||
array[y - 3][x] == 0 &&
|
||||
array[y - 4][x] == 0))) {
|
||||
penalty += N3;
|
||||
array[y - 3][x] == 0))) {
|
||||
numPenalties++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return penalty;
|
||||
return numPenalties * N3;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,8 +138,7 @@ final class MaskUtil {
|
|||
}
|
||||
}
|
||||
int numTotalCells = matrix.getHeight() * matrix.getWidth();
|
||||
double darkRatio = (double) numDarkCells / numTotalCells;
|
||||
int fivePercentVariances = (int) (Math.abs(darkRatio - 0.5) * 20.0); // * 100.0 / 5.0
|
||||
int fivePercentVariances = Math.abs(numDarkCells * 2 - numTotalCells) * 10 / numTotalCells;
|
||||
return fivePercentVariances * N4;
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 189 B |
Binary file not shown.
Before Width: | Height: | Size: 280 B |
|
@ -128,18 +128,6 @@ public final class QRCodeWriterTestCase extends Assert {
|
|||
public void testRegressionTest() throws Exception {
|
||||
compareToGoldenFile("http://www.google.com/", ErrorCorrectionLevel.M, 99,
|
||||
"renderer-test-01.png");
|
||||
|
||||
compareToGoldenFile("12345", ErrorCorrectionLevel.L, 58, "renderer-test-02.png");
|
||||
|
||||
// Test in Katakana in Shift_JIS.
|
||||
// TODO: this test is bogus now that byte mode has been basically fixed to assuming ISO-8859-1 encoding
|
||||
// The real solution is to implement Kanji mode, in which case the golden file will be wrong again
|
||||
/*
|
||||
compareToGoldenFile(
|
||||
new String(new byte[] {(byte)0x83, 0x65, (byte)0x83, 0x58, (byte)0x83, 0x67}, "Shift_JIS"),
|
||||
ErrorCorrectionLevel.H, 145,
|
||||
"renderer-test-03.png");
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -137,29 +137,29 @@ public final class EncoderTestCase extends Assert {
|
|||
" mode: BYTE\n" +
|
||||
" ecLevel: H\n" +
|
||||
" version: 1\n" +
|
||||
" maskPattern: 3\n" +
|
||||
" maskPattern: 0\n" +
|
||||
" matrix:\n" +
|
||||
" 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1\n" +
|
||||
" 1 0 0 0 0 0 1 0 0 0 1 0 1 0 1 0 0 0 0 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 1 0 1 0 0 1 0 1 1 1 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 1 1 0 1 0 1 0 1 1 1 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 0 1\n" +
|
||||
" 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1\n" +
|
||||
" 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 1 1 1 1 1 1\n" +
|
||||
" 1 0 0 0 0 0 1 0 0 1 1 0 1 0 1 0 0 0 0 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 1 0 1 1 0 1 0 1 1 1 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 1 1 1 1 0 0 1 0 1 1 1 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 0 0 1 0 0 1 0 1 1 1 0 1\n" +
|
||||
" 1 0 0 0 0 0 1 0 0 1 1 1 1 0 1 0 0 0 0 0 1\n" +
|
||||
" 1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1\n" +
|
||||
" 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0\n" +
|
||||
" 0 0 1 1 0 0 1 1 1 1 0 0 0 1 1 0 1 0 0 0 0\n" +
|
||||
" 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 1 0 1 1 1 0\n" +
|
||||
" 0 1 0 1 0 1 1 1 0 1 0 1 0 0 0 0 0 1 1 1 1\n" +
|
||||
" 1 1 0 0 1 0 0 1 1 0 0 1 1 1 1 0 1 0 1 1 0\n" +
|
||||
" 0 0 0 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 1 0 0\n" +
|
||||
" 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 1 1 0 0 0 1\n" +
|
||||
" 1 1 1 1 1 1 1 0 1 1 1 0 1 0 1 1 0 0 1 0 0\n" +
|
||||
" 1 0 0 0 0 0 1 0 0 0 1 0 0 1 1 1 1 1 1 0 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 1 0 0 0 0 1 1 0 0 0 0 0\n" +
|
||||
" 1 0 1 1 1 0 1 0 1 1 1 0 1 0 0 0 1 1 0 0 0\n" +
|
||||
" 1 0 1 1 1 0 1 0 1 1 0 0 0 1 0 0 1 0 0 0 0\n" +
|
||||
" 1 0 0 0 0 0 1 0 0 0 0 1 1 0 1 0 1 0 1 1 0\n" +
|
||||
" 1 1 1 1 1 1 1 0 0 1 0 1 1 1 0 1 1 0 0 0 0\n" +
|
||||
" 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0\n" +
|
||||
" 0 0 1 0 1 1 1 0 1 1 0 0 1 1 0 0 0 1 0 0 1\n" +
|
||||
" 1 1 1 1 1 1 0 1 0 0 1 0 1 1 0 1 0 0 0 0 0\n" +
|
||||
" 1 1 0 1 1 0 1 1 0 1 1 0 1 0 0 0 1 0 0 1 1\n" +
|
||||
" 1 1 0 1 0 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 0\n" +
|
||||
" 0 0 1 1 0 0 1 1 0 0 1 0 0 0 1 0 1 0 1 0 1\n" +
|
||||
" 0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 0 1 0 0 1 0\n" +
|
||||
" 1 1 1 1 1 1 1 0 0 1 1 0 0 1 0 1 0 0 0 1 1\n" +
|
||||
" 1 0 0 0 0 0 1 0 1 0 1 1 1 0 1 1 1 0 0 1 1\n" +
|
||||
" 1 0 1 1 1 0 1 0 1 1 1 1 1 0 1 1 1 1 1 0 0\n" +
|
||||
" 1 0 1 1 1 0 1 0 0 0 0 1 1 0 0 1 0 0 0 0 0\n" +
|
||||
" 1 0 1 1 1 0 1 0 1 0 1 0 0 1 1 1 0 0 0 0 1\n" +
|
||||
" 1 0 0 0 0 0 1 0 0 1 0 1 1 1 0 1 1 0 1 0 1\n" +
|
||||
" 1 1 1 1 1 1 1 0 0 1 0 1 0 0 1 1 1 0 1 1 1\n" +
|
||||
">>\n";
|
||||
assertEquals(expected, qrCode.toString());
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ public final class MaskUtilTestCase extends Assert {
|
|||
@Test
|
||||
public void testApplyMaskPenaltyRule3() {
|
||||
// Horizontal 00001011101.
|
||||
ByteMatrix matrix = new ByteMatrix(11, 1);
|
||||
ByteMatrix matrix = new ByteMatrix(12, 1);
|
||||
matrix.set(0, 0, 0);
|
||||
matrix.set(1, 0, 0);
|
||||
matrix.set(2, 0, 0);
|
||||
|
@ -103,23 +103,25 @@ public final class MaskUtilTestCase extends Assert {
|
|||
matrix.set(8, 0, 1);
|
||||
matrix.set(9, 0, 0);
|
||||
matrix.set(10, 0, 1);
|
||||
matrix.set(11, 0, 0);
|
||||
assertEquals(40, MaskUtil.applyMaskPenaltyRule3(matrix));
|
||||
// Horizontal 10111010000.
|
||||
matrix = new ByteMatrix(11, 1);
|
||||
matrix.set(0, 0, 1);
|
||||
matrix.set(1, 0, 0);
|
||||
matrix.set(2, 0, 1);
|
||||
matrix = new ByteMatrix(12, 1);
|
||||
matrix.set(0, 0, 0);
|
||||
matrix.set(1, 0, 1);
|
||||
matrix.set(2, 0, 0);
|
||||
matrix.set(3, 0, 1);
|
||||
matrix.set(4, 0, 1);
|
||||
matrix.set(5, 0, 0);
|
||||
matrix.set(6, 0, 1);
|
||||
matrix.set(7, 0, 0);
|
||||
matrix.set(5, 0, 1);
|
||||
matrix.set(6, 0, 0);
|
||||
matrix.set(7, 0, 1);
|
||||
matrix.set(8, 0, 0);
|
||||
matrix.set(9, 0, 0);
|
||||
matrix.set(10, 0, 0);
|
||||
matrix.set(11, 0, 0);
|
||||
assertEquals(40, MaskUtil.applyMaskPenaltyRule3(matrix));
|
||||
// Vertical 00001011101.
|
||||
matrix = new ByteMatrix(1, 11);
|
||||
matrix = new ByteMatrix(1, 12);
|
||||
matrix.set(0, 0, 0);
|
||||
matrix.set(0, 1, 0);
|
||||
matrix.set(0, 2, 0);
|
||||
|
@ -131,20 +133,22 @@ public final class MaskUtilTestCase extends Assert {
|
|||
matrix.set(0, 8, 1);
|
||||
matrix.set(0, 9, 0);
|
||||
matrix.set(0, 10, 1);
|
||||
matrix.set(0, 11, 0);
|
||||
assertEquals(40, MaskUtil.applyMaskPenaltyRule3(matrix));
|
||||
// Vertical 10111010000.
|
||||
matrix = new ByteMatrix(1, 11);
|
||||
matrix.set(0, 0, 1);
|
||||
matrix.set(0, 1, 0);
|
||||
matrix.set(0, 2, 1);
|
||||
matrix = new ByteMatrix(1, 12);
|
||||
matrix.set(0, 0, 0);
|
||||
matrix.set(0, 1, 1);
|
||||
matrix.set(0, 2, 0);
|
||||
matrix.set(0, 3, 1);
|
||||
matrix.set(0, 4, 1);
|
||||
matrix.set(0, 5, 0);
|
||||
matrix.set(0, 6, 1);
|
||||
matrix.set(0, 7, 0);
|
||||
matrix.set(0, 5, 1);
|
||||
matrix.set(0, 6, 0);
|
||||
matrix.set(0, 7, 1);
|
||||
matrix.set(0, 8, 0);
|
||||
matrix.set(0, 9, 0);
|
||||
matrix.set(0, 10, 0);
|
||||
matrix.set(0, 11, 0);
|
||||
assertEquals(40, MaskUtil.applyMaskPenaltyRule3(matrix));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue