public abstract class AbstractOneDReader implements OneDReader {
private static final int INTEGER_MATH_SHIFT = 8;
+ public static final int PATTERN_MATCH_RESULT_SCALE_FACTOR = 256;
public final Result decode(MonochromeBitmapSource image) throws ReaderException {
return decode(image, null);
*
* @param counters observed counters
* @param pattern expected pattern
+ * @param maxIndividualVariance
* @return ratio of total variance between counters and pattern compared to total pattern size,
* where the ratio has been multiplied by 256. So, 0 means no variance (perfect match); 256 means
* the total variance between counters and patterns equals the pattern length, higher values mean
* even more variance
*/
- static int patternMatchVariance(int[] counters, int[] pattern) {
+ static int patternMatchVariance(int[] counters, int[] pattern, int maxIndividualVariance) {
int numCounters = counters.length;
int total = 0;
int patternLength = 0;
// We're going to fake floating-point math in integers. We just need to use more bits.
// Scale up patternLength so that intermediate values below like scaledCounter will have
// more "significant digits"
- patternLength <<= INTEGER_MATH_SHIFT;
- int patternRatio = patternLength / total;
+ int unitBarWidth = (total << INTEGER_MATH_SHIFT) / patternLength;
+ maxIndividualVariance *= unitBarWidth;
int totalVariance = 0;
for (int x = 0; x < numCounters; x++) {
- int scaledCounter = counters[x] * patternRatio;
- int width = pattern[x] << INTEGER_MATH_SHIFT;
- totalVariance += scaledCounter > width ? scaledCounter - width : width - scaledCounter;
+ int counter = counters[x] << INTEGER_MATH_SHIFT;
+ int scaledPattern = pattern[x] * unitBarWidth;
+ int variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter;
+ if (variance > maxIndividualVariance) {
+ return Integer.MAX_VALUE;
+ }
+ totalVariance += variance;
}
- return (totalVariance << 8) / patternLength;
+ return totalVariance / total;
}
// This declaration should not be necessary, since this class is