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
|
||||
* significant bit is bit 0.
|
||||
|
|
|
@ -82,7 +82,7 @@ public abstract class AbstractUPCEANReader extends AbstractOneDReader implements
|
|||
nextStart = startRange[1];
|
||||
// As a check, we want to see some white in front of this "start pattern",
|
||||
// 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;
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ public abstract class AbstractUPCEANReader extends AbstractOneDReader implements
|
|||
|
||||
// Check for whitespace after the pattern
|
||||
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");
|
||||
}
|
||||
|
||||
|
@ -115,18 +115,6 @@ public abstract class AbstractUPCEANReader extends AbstractOneDReader implements
|
|||
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
|
||||
* whether the checksum is correct or not.
|
||||
|
|
|
@ -63,4 +63,25 @@ public final class BitArrayTestCase extends TestCase {
|
|||
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