mirror of
https://github.com/zxing/zxing.git
synced 2025-02-02 05:41:08 -08:00
Small optimization to check ranges of bits set in BitArray in bulk
git-svn-id: https://zxing.googlecode.com/svn/trunk@176 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
51bb41ed24
commit
9f0cd86114
|
@ -73,6 +73,50 @@ public final class BitArray {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Efficient method to check if a range of bits is set, or not set.
|
||||||
|
*
|
||||||
|
* @param start start of range, inclusive.
|
||||||
|
* @param end end of range, exclusive
|
||||||
|
* @param value if true, checks that bits in range are set, otherwise checks that they are not set
|
||||||
|
* @return true iff all bits are set or not set in range, according to value argument
|
||||||
|
* @throws IllegalArgumentException if end is less than or equal to start
|
||||||
|
*/
|
||||||
|
public boolean isRange(int start, int end, boolean value) {
|
||||||
|
if (end < start) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
if (end == start) {
|
||||||
|
return true; // empty range matches
|
||||||
|
}
|
||||||
|
end--; // will be easier to treat this as the last actually set bit -- inclusive
|
||||||
|
int firstInt = start >> 5;
|
||||||
|
int lastInt = end >> 5;
|
||||||
|
for (int i = firstInt; i <= lastInt; i++) {
|
||||||
|
int firstBit = i > firstInt ? 0 : start & 0x1F;
|
||||||
|
int lastBit = i < lastInt ? 31 : end & 0x1F;
|
||||||
|
int mask;
|
||||||
|
if (firstBit == 0 && lastBit == 31) {
|
||||||
|
mask = -1;
|
||||||
|
} else {
|
||||||
|
mask = 0;
|
||||||
|
for (int j = firstBit; j <= lastBit; j++) {
|
||||||
|
mask |= 1 << j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (value) {
|
||||||
|
if ((bits[i] & mask) != mask) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((bits[i] & mask) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return underlying array of ints. The first element holds the first 32 bits, and the least
|
* @return underlying array of ints. The first element holds the first 32 bits, and the least
|
||||||
* significant bit is bit 0.
|
* significant bit is bit 0.
|
||||||
|
|
|
@ -82,7 +82,7 @@ public abstract class AbstractUPCEANReader extends AbstractOneDReader implements
|
||||||
nextStart = startRange[1];
|
nextStart = startRange[1];
|
||||||
// As a check, we want to see some white in front of this "start pattern",
|
// As a check, we want to see some white in front of this "start pattern",
|
||||||
// maybe as wide as the start pattern itself?
|
// maybe as wide as the start pattern itself?
|
||||||
foundStart = isWhiteRange(row, Math.max(0, start - 2 * (startRange[1] - start)), start);
|
foundStart = row.isRange(Math.max(0, start - 2 * (startRange[1] - start)), start, false);
|
||||||
}
|
}
|
||||||
return startRange;
|
return startRange;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ public abstract class AbstractUPCEANReader extends AbstractOneDReader implements
|
||||||
|
|
||||||
// Check for whitespace after the pattern
|
// Check for whitespace after the pattern
|
||||||
int end = endRange[1];
|
int end = endRange[1];
|
||||||
if (!isWhiteRange(row, end, Math.min(row.getSize(), end + 2 * (end - endRange[0])))) {
|
if (!row.isRange(end, Math.min(row.getSize(), end + 2 * (end - endRange[0])), false)) {
|
||||||
throw new ReaderException("Pattern not followed by whitespace");
|
throw new ReaderException("Pattern not followed by whitespace");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,18 +115,6 @@ public abstract class AbstractUPCEANReader extends AbstractOneDReader implements
|
||||||
new GenericResultPoint((float) (endRange[1] - endRange[0]) / 2.0f, (float) rowNumber)});
|
new GenericResultPoint((float) (endRange[1] - endRange[0]) / 2.0f, (float) rowNumber)});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true iff row consists of white values in the range [start,end)
|
|
||||||
*/
|
|
||||||
protected static boolean isWhiteRange(BitArray row, int start, int end) {
|
|
||||||
for (int i = start; i < end; i++) {
|
|
||||||
if (row.get(i)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the UPC/EAN checksum on a string of digits, and reports
|
* Computes the UPC/EAN checksum on a string of digits, and reports
|
||||||
* whether the checksum is correct or not.
|
* whether the checksum is correct or not.
|
||||||
|
|
|
@ -63,4 +63,25 @@ public final class BitArrayTestCase extends TestCase {
|
||||||
assertEquals(Integer.MIN_VALUE, ints[1]);
|
assertEquals(Integer.MIN_VALUE, ints[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIsRange() {
|
||||||
|
BitArray array = new BitArray(64);
|
||||||
|
assertTrue(array.isRange(0, 64, false));
|
||||||
|
assertFalse(array.isRange(0, 64, true));
|
||||||
|
array.set(32);
|
||||||
|
assertTrue(array.isRange(32, 33, true));
|
||||||
|
array.set(31);
|
||||||
|
assertTrue(array.isRange(31, 33, true));
|
||||||
|
array.set(34);
|
||||||
|
assertFalse(array.isRange(31, 35, true));
|
||||||
|
for (int i = 0; i < 31; i++) {
|
||||||
|
array.set(i);
|
||||||
|
}
|
||||||
|
assertTrue(array.isRange(0, 33, true));
|
||||||
|
for (int i = 33; i < 64; i++) {
|
||||||
|
array.set(i);
|
||||||
|
}
|
||||||
|
assertTrue(array.isRange(0, 64, true));
|
||||||
|
assertFalse(array.isRange(0, 64, false));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue