mirror of
https://github.com/zxing/zxing.git
synced 2024-11-10 04:54:04 -08:00
Continuing with the x, y coordinate push, BitMatrix is now standardized. I also converted DataMask back to i, j for now to be consistent with the rest of the QR module, and made sure all the tests still pass.
git-svn-id: https://zxing.googlecode.com/svn/trunk@977 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
4b7e5e6461
commit
7fec06465a
|
@ -17,20 +17,16 @@
|
|||
package com.google.zxing.common;
|
||||
|
||||
/**
|
||||
* <p>Represnts a square matrix of bits. In function arguments below, i is the row position
|
||||
* and j the column position of a bit. The top left bit corresponds to i = 0 and j = 0.</p>
|
||||
* <p>Represents a square matrix of bits. In function arguments below, and throughout the common
|
||||
* module, x is the column position, and y is the row position. The ordering is always x, y.
|
||||
* The origin is at the top-left.</p>
|
||||
*
|
||||
* <p>Internally the bits are represented in a compact 1-D array of 32-bit ints. The
|
||||
* ordering of bits is column-major; that is the bits in this array correspond to
|
||||
* j=0 and i=0..dimension-1 first, then j=1 and i=0..dimension-1, etc.</p>
|
||||
*
|
||||
* <p>Within each int, less-signficant bits correspond to lower values of i and higher rows.
|
||||
* That is, the top-left bit is the least significant bit of the first int.</p>
|
||||
*
|
||||
* <p>This class is a convenient wrapper around this representation, but also exposes the internal
|
||||
* array for efficient access and manipulation.</p>
|
||||
* <p>Internally the bits are represented in a compact 1-D array of 32-bit ints.
|
||||
* The ordering of bits is row-major. Within each int, the least significant bits are used first,
|
||||
* meaning they represent lower x values. This is compatible with BitArray's implementation.</p>
|
||||
*
|
||||
* @author Sean Owen
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
public final class BitMatrix {
|
||||
|
||||
|
@ -51,63 +47,65 @@ public final class BitMatrix {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param i row offset
|
||||
* @param j column offset
|
||||
* <p>Gets the requested bit, where true means black.</p>
|
||||
*
|
||||
* @param x The horizontal component (i.e. which column)
|
||||
* @param y The vertical component (i.e. which row)
|
||||
* @return value of given bit in matrix
|
||||
*/
|
||||
public boolean get(int i, int j) {
|
||||
int offset = i + dimension * j;
|
||||
public boolean get(int x, int y) {
|
||||
int offset = y * dimension + x;
|
||||
return ((bits[offset >> 5] >>> (offset & 0x1F)) & 0x01) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets the given bit to true.</p>
|
||||
*
|
||||
* @param i row offset
|
||||
* @param j column offset
|
||||
* @param x The horizontal component (i.e. which column)
|
||||
* @param y The vertical component (i.e. which row)
|
||||
*/
|
||||
public void set(int i, int j) {
|
||||
int offset = i + dimension * j;
|
||||
public void set(int x, int y) {
|
||||
int offset = y * dimension + x;
|
||||
bits[offset >> 5] |= 1 << (offset & 0x1F);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Flips the given bit.</p>
|
||||
*
|
||||
* @param i row offset
|
||||
* @param j column offset
|
||||
* @param x The horizontal component (i.e. which column)
|
||||
* @param y The vertical component (i.e. which row)
|
||||
*/
|
||||
public void flip(int i, int j) {
|
||||
int offset = i + dimension * j;
|
||||
public void flip(int x, int y) {
|
||||
int offset = y * dimension + x;
|
||||
bits[offset >> 5] ^= 1 << (offset & 0x1F);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets a square region of the bit matrix to true.</p>
|
||||
*
|
||||
* @param topI row offset of region's top-left corner (inclusive)
|
||||
* @param leftJ column offset of region's top-left corner (inclusive)
|
||||
* @param height height of region
|
||||
* @param width width of region
|
||||
* @param left The horizontal position to begin at (inclusive)
|
||||
* @param top The vertical position to begin at (inclusive)
|
||||
* @param width The width of the region
|
||||
* @param height The height of the region
|
||||
*/
|
||||
public void setRegion(int topI, int leftJ, int height, int width) {
|
||||
if (topI < 0 || leftJ < 0) {
|
||||
throw new IllegalArgumentException("topI and leftJ must be nonnegative");
|
||||
public void setRegion(int left, int top, int width, int height) {
|
||||
if (top < 0 || left < 0) {
|
||||
throw new IllegalArgumentException("left and top must be nonnegative");
|
||||
}
|
||||
if (height < 1 || width < 1) {
|
||||
throw new IllegalArgumentException("height and width must be at least 1");
|
||||
}
|
||||
int maxJ = leftJ + width;
|
||||
int maxI = topI + height;
|
||||
if (maxI > dimension || maxJ > dimension) {
|
||||
int right = left + width;
|
||||
int bottom = top + height;
|
||||
if (bottom > dimension || right > dimension) {
|
||||
throw new IllegalArgumentException(
|
||||
"topI + height and leftJ + width must be <= matrix dimension");
|
||||
"top + height and left + width must be <= matrix dimension");
|
||||
}
|
||||
for (int j = leftJ; j < maxJ; j++) {
|
||||
int jOffset = dimension * j;
|
||||
for (int i = topI; i < maxI; i++) {
|
||||
int offset = i + jOffset;
|
||||
bits[offset >> 5] |= 1 << (offset & 0x1F);
|
||||
for (int y = top; y < bottom; y++) {
|
||||
int yoffset = dimension * y;
|
||||
for (int x = left; x < right; x++) {
|
||||
int xoffset = yoffset + x;
|
||||
bits[xoffset >> 5] |= 1 << (xoffset & 0x1F);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -121,9 +119,9 @@ public final class BitMatrix {
|
|||
|
||||
public String toString() {
|
||||
StringBuffer result = new StringBuffer(dimension * (dimension + 1));
|
||||
for (int i = 0; i < dimension; i++) {
|
||||
for (int j = 0; j < dimension; j++) {
|
||||
result.append(get(i, j) ? "X " : " ");
|
||||
for (int y = 0; y < dimension; y++) {
|
||||
for (int x = 0; x < dimension; x++) {
|
||||
result.append(get(x, y) ? "X " : " ");
|
||||
}
|
||||
result.append('\n');
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ public final class DefaultGridSampler extends GridSampler {
|
|||
for (int j = 0; j < max; j += 2) {
|
||||
if (image.isBlack((int) points[j], (int) points[j + 1])) {
|
||||
// Black(-ish) pixel
|
||||
bits.set(i, j >> 1);
|
||||
bits.set(j >> 1, i);
|
||||
}
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException aioobe) {
|
||||
|
|
|
@ -138,7 +138,7 @@ public final class DataMatrixReader implements Reader {
|
|||
int iOffset = borderWidth + i * moduleSize;
|
||||
for (int j = 0; j < dimension; j++) {
|
||||
if (image.isBlack(borderWidth + j * moduleSize, iOffset)) {
|
||||
bits.set(i, j);
|
||||
bits.set(j, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ final class BitMatrixParser {
|
|||
} else {
|
||||
// Sweep upward diagonally to the right
|
||||
do {
|
||||
if ((row < numRows) && (column >= 0) && !readMappingMatrix.get(row, column)) {
|
||||
if ((row < numRows) && (column >= 0) && !readMappingMatrix.get(column, row)) {
|
||||
result[resultOffset++] = (byte) readUtah(row, column, numRows, numColumns);
|
||||
}
|
||||
row -= 2;
|
||||
|
@ -129,7 +129,7 @@ final class BitMatrixParser {
|
|||
|
||||
// Sweep downward diagonally to the left
|
||||
do {
|
||||
if ((row >= 0) && (column < numColumns) && !readMappingMatrix.get(row, column)) {
|
||||
if ((row >= 0) && (column < numColumns) && !readMappingMatrix.get(column, row)) {
|
||||
result[resultOffset++] = (byte) readUtah(row, column, numRows, numColumns);
|
||||
}
|
||||
row += 2;
|
||||
|
@ -165,8 +165,8 @@ final class BitMatrixParser {
|
|||
column += numColumns;
|
||||
row += 4 - ((numColumns + 4) & 0x07);
|
||||
}
|
||||
readMappingMatrix.set(row, column);
|
||||
return mappingBitMatrix.get(row, column);
|
||||
readMappingMatrix.set(column, row);
|
||||
return mappingBitMatrix.get(column, row);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -432,9 +432,9 @@ final class BitMatrixParser {
|
|||
int writeRowOffset = dataRegionRowOffset + i;
|
||||
for (int j = 0; j < dataRegionSizeColumns; ++j) {
|
||||
int readColumnOffset = dataRegionColumn * (dataRegionSizeColumns + 2) + 1 + j;
|
||||
if (bitMatrix.get(readRowOffset, readColumnOffset)) {
|
||||
if (bitMatrix.get(readColumnOffset, readRowOffset)) {
|
||||
int writeColumnOffset = dataRegionColumnOffset + j;
|
||||
bitMatrixWithoutAlignment.set(writeRowOffset, writeColumnOffset);
|
||||
bitMatrixWithoutAlignment.set(writeColumnOffset, writeRowOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public final class Decoder {
|
|||
for (int i = 0; i < dimension; i++) {
|
||||
for (int j = 0; j < dimension; j++) {
|
||||
if (image[i][j]) {
|
||||
bits.set(i, j);
|
||||
bits.set(j, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ public class QRCodeReader implements Reader {
|
|||
int iOffset = borderWidth + i * moduleSize;
|
||||
for (int j = 0; j < dimension; j++) {
|
||||
if (image.isBlack(borderWidth + j * moduleSize, iOffset)) {
|
||||
bits.set(i, j);
|
||||
bits.set(j, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ final class BitMatrixParser {
|
|||
}
|
||||
|
||||
private int copyBit(int i, int j, int versionBits) {
|
||||
return bitMatrix.get(i, j) ? (versionBits << 1) | 0x1 : versionBits << 1;
|
||||
return bitMatrix.get(j, i) ? (versionBits << 1) | 0x1 : versionBits << 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -182,11 +182,11 @@ final class BitMatrixParser {
|
|||
int i = readingUp ? dimension - 1 - count : count;
|
||||
for (int col = 0; col < 2; col++) {
|
||||
// Ignore bits covered by the function pattern
|
||||
if (!functionPattern.get(i, j - col)) {
|
||||
if (!functionPattern.get(j - col, i)) {
|
||||
// Read a bit
|
||||
bitsRead++;
|
||||
currentByte <<= 1;
|
||||
if (bitMatrix.get(i, j - col)) {
|
||||
if (bitMatrix.get(j - col, i)) {
|
||||
currentByte |= 1;
|
||||
}
|
||||
// If we've made a whole byte, save it off
|
||||
|
|
|
@ -56,16 +56,16 @@ abstract class DataMask {
|
|||
* @param dimension dimension of QR Code, represented by bits, being unmasked
|
||||
*/
|
||||
final void unmaskBitMatrix(BitMatrix bits, int dimension) {
|
||||
for (int y = 0; y < dimension; y++) {
|
||||
for (int x = 0; x < dimension; x++) {
|
||||
if (isMasked(x, y)) {
|
||||
bits.flip(x, y);
|
||||
for (int i = 0; i < dimension; i++) {
|
||||
for (int j = 0; j < dimension; j++) {
|
||||
if (isMasked(i, j)) {
|
||||
bits.flip(j, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract boolean isMasked(int x, int y);
|
||||
abstract boolean isMasked(int i, int j);
|
||||
|
||||
/**
|
||||
* @param reference a value between 0 and 7 indicating one of the eight possible
|
||||
|
@ -83,8 +83,8 @@ abstract class DataMask {
|
|||
* 000: mask bits for which (x + y) mod 2 == 0
|
||||
*/
|
||||
private static class DataMask000 extends DataMask {
|
||||
boolean isMasked(int x, int y) {
|
||||
return ((x + y) & 0x01) == 0;
|
||||
boolean isMasked(int i, int j) {
|
||||
return ((i + j) & 0x01) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,8 +92,8 @@ abstract class DataMask {
|
|||
* 001: mask bits for which x mod 2 == 0
|
||||
*/
|
||||
private static class DataMask001 extends DataMask {
|
||||
boolean isMasked(int x, int y) {
|
||||
return (x & 0x01) == 0;
|
||||
boolean isMasked(int i, int j) {
|
||||
return (i & 0x01) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,8 +101,8 @@ abstract class DataMask {
|
|||
* 010: mask bits for which y mod 3 == 0
|
||||
*/
|
||||
private static class DataMask010 extends DataMask {
|
||||
boolean isMasked(int x, int y) {
|
||||
return y % 3 == 0;
|
||||
boolean isMasked(int i, int j) {
|
||||
return j % 3 == 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,8 +110,8 @@ abstract class DataMask {
|
|||
* 011: mask bits for which (x + y) mod 3 == 0
|
||||
*/
|
||||
private static class DataMask011 extends DataMask {
|
||||
boolean isMasked(int x, int y) {
|
||||
return (x + y) % 3 == 0;
|
||||
boolean isMasked(int i, int j) {
|
||||
return (i + j) % 3 == 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,8 +119,8 @@ abstract class DataMask {
|
|||
* 100: mask bits for which (x/2 + y/3) mod 2 == 0
|
||||
*/
|
||||
private static class DataMask100 extends DataMask {
|
||||
boolean isMasked(int x, int y) {
|
||||
return (((x >>> 1) + (y/3)) & 0x01) == 0;
|
||||
boolean isMasked(int i, int j) {
|
||||
return (((i >>> 1) + (j /3)) & 0x01) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,8 +128,8 @@ abstract class DataMask {
|
|||
* 101: mask bits for which xy mod 2 + xy mod 3 == 0
|
||||
*/
|
||||
private static class DataMask101 extends DataMask {
|
||||
boolean isMasked(int x, int y) {
|
||||
int temp = x * y;
|
||||
boolean isMasked(int i, int j) {
|
||||
int temp = i * j;
|
||||
return (temp & 0x01) + (temp % 3) == 0;
|
||||
}
|
||||
}
|
||||
|
@ -138,18 +138,18 @@ abstract class DataMask {
|
|||
* 110: mask bits for which (xy mod 2 + xy mod 3) mod 2 == 0
|
||||
*/
|
||||
private static class DataMask110 extends DataMask {
|
||||
boolean isMasked(int x, int y) {
|
||||
int temp = x * y;
|
||||
boolean isMasked(int i, int j) {
|
||||
int temp = i * j;
|
||||
return (((temp & 0x01) + (temp % 3)) & 0x01) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 111: mask bits for which ((i+j)mod 2 + ij mod 3) mod 2 == 0
|
||||
* 111: mask bits for which ((x+y)mod 2 + xy mod 3) mod 2 == 0
|
||||
*/
|
||||
private static class DataMask111 extends DataMask {
|
||||
boolean isMasked(int x, int y) {
|
||||
return ((((x + y) & 0x01) + ((x * y) % 3)) & 0x01) == 0;
|
||||
boolean isMasked(int i, int j) {
|
||||
return ((((i + j) & 0x01) + ((i * j) % 3)) & 0x01) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public final class Decoder {
|
|||
for (int i = 0; i < dimension; i++) {
|
||||
for (int j = 0; j < dimension; j++) {
|
||||
if (image[i][j]) {
|
||||
bits.set(i, j);
|
||||
bits.set(j, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,9 +147,9 @@ public final class Version {
|
|||
// Top left finder pattern + separator + format
|
||||
bitMatrix.setRegion(0, 0, 9, 9);
|
||||
// Top right finder pattern + separator + format
|
||||
bitMatrix.setRegion(0, dimension - 8, 9, 8);
|
||||
// Bottom left finder pattern + separator + format
|
||||
bitMatrix.setRegion(dimension - 8, 0, 8, 9);
|
||||
// Bottom left finder pattern + separator + format
|
||||
bitMatrix.setRegion(0, dimension - 8, 9, 8);
|
||||
|
||||
// Alignment patterns
|
||||
int max = alignmentPatternCenters.length;
|
||||
|
@ -160,20 +160,20 @@ public final class Version {
|
|||
// No alignment patterns near the three finder paterns
|
||||
continue;
|
||||
}
|
||||
bitMatrix.setRegion(i, alignmentPatternCenters[y] - 2, 5, 5);
|
||||
bitMatrix.setRegion(alignmentPatternCenters[y] - 2, i, 5, 5);
|
||||
}
|
||||
}
|
||||
|
||||
// Vertical timing pattern
|
||||
bitMatrix.setRegion(9, 6, dimension - 17, 1);
|
||||
// Horizontal timing pattern
|
||||
bitMatrix.setRegion(6, 9, 1, dimension - 17);
|
||||
// Horizontal timing pattern
|
||||
bitMatrix.setRegion(9, 6, dimension - 17, 1);
|
||||
|
||||
if (versionNumber > 6) {
|
||||
// Version info, top right
|
||||
bitMatrix.setRegion(0, dimension - 11, 6, 3);
|
||||
// Version info, bottom left
|
||||
bitMatrix.setRegion(dimension - 11, 0, 3, 6);
|
||||
// Version info, bottom left
|
||||
bitMatrix.setRegion(0, dimension - 11, 6, 3);
|
||||
}
|
||||
|
||||
return bitMatrix;
|
||||
|
|
|
@ -29,13 +29,13 @@ public final class BitMatrixTestCase extends TestCase {
|
|||
for (int i = 0; i < 33; i++) {
|
||||
for (int j = 0; j < 33; j++) {
|
||||
if (i * j % 3 == 0) {
|
||||
matrix.set(i, j);
|
||||
matrix.set(j, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 33; i++) {
|
||||
for (int j = 0; j < 33; j++) {
|
||||
assertEquals(i * j % 3 == 0, matrix.get(i, j));
|
||||
assertEquals(i * j % 3 == 0, matrix.get(j, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ public final class BitMatrixTestCase extends TestCase {
|
|||
matrix.setRegion(1, 1, 3, 3);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
for (int j = 0; j < 5; j++) {
|
||||
assertEquals(i >= 1 && i <= 3 && j >= 1 && j <= 3, matrix.get(i, j));
|
||||
assertEquals(i >= 1 && i <= 3 && j >= 1 && j <= 3, matrix.get(j, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ public final class DataMaskTestCase extends TestCase {
|
|||
assertEquals(
|
||||
"(" + i + ',' + j + ')',
|
||||
condition.isMasked(i, j),
|
||||
bits.get(i, j));
|
||||
bits.get(j, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue