int middle = height >> 1;
int rowStep = Math.max(1, height >> (tryHarder ? 7 : 4));
int maxLines;
- //if (tryHarder || barcodesToSkip > 0) {
if (tryHarder) {
maxLines = height; // Look at the whole image; looking for more than one barcode
} else {
maxLines = 7;
}
- Hashtable lastResults = null;
- boolean skippingSomeBarcodes = hints != null && hints.containsKey(DecodeHintType.SKIP_N_BARCODES);
-
for (int x = 0; x < maxLines; x++) {
// Scanning from the middle out. Determine which row we're looking at next:
}
image.getBlackRow(rowNumber, row, 0, width);
- // We may try twice for each row, if "trying harder":
+ // While we have the image data in a BitArray, it's fairly cheap to reverse it in place to
+ // handle decoding upside down barcodes.
for (int attempt = 0; attempt < 2; attempt++) {
-
if (attempt == 1) { // trying again?
- if (tryHarder) { // only if "trying harder"
- row.reverse(); // reverse the row and continue
- } else {
- break;
- }
+ row.reverse(); // reverse the row and continue
}
-
try {
-
// Look for a barcode
Result result = decodeRow(rowNumber, row, hints);
-
- if (lastResults != null && lastResults.containsKey(result.getText())) {
- // Just saw the last barcode again, proceed
- continue;
- }
-
- if (skippingSomeBarcodes) { // See if we should skip and keep looking
- int oldValue = ((Integer) hints.get(DecodeHintType.SKIP_N_BARCODES)).intValue();
- if (oldValue > 1) {
- hints.put(DecodeHintType.SKIP_N_BARCODES, new Integer(oldValue - 1));
- } else {
- hints.remove(DecodeHintType.SKIP_N_BARCODES);
- skippingSomeBarcodes = false;
- }
- if (lastResults == null) {
- lastResults = new Hashtable(3);
- }
- lastResults.put(result.getText(), Boolean.TRUE); // Remember what we just saw
- } else {
- // We found our barcode
- if (attempt == 1) {
- // But it was upside down, so note that
- result.putMetadata(ResultMetadataType.ORIENTATION, new Integer(180));
- }
- return result;
+ // We found our barcode
+ if (attempt == 1) {
+ // But it was upside down, so note that
+ result.putMetadata(ResultMetadataType.ORIENTATION, new Integer(180));
}
-
+ return result;
} catch (ReaderException re) {
// continue -- just couldn't decode this row
}
-
}
}
throw new ReaderException("No barcode found");
}
+ /**
+ * Records the size of successive runs of white and black pixels in a row, starting at a given point.
+ * The values are recorded in the given array, and the number of runs recorded is equal to the size
+ * of the array. If the row starts on a white pixel at the given start point, then the first count
+ * recorded is the run of white pixels starting from that point; likewise it is the count of a run
+ * of black pixels if the row begin on a black pixels at that point.
+ *
+ * @param row row to count from
+ * @param start offset into row to start at
+ * @param counters array into which to record counts
+ * @throws ReaderException if counters cannot be filled entirely from row before running out of pixels
+ */
static void recordPattern(BitArray row, int start, int[] counters) throws ReaderException {
int numCounters = counters.length;
for (int i = 0; i < numCounters; i++) {
return totalVariance / (float) patternLength;
}
+ // This declaration should not be necessary, since this class is
+ // abstract and so does not have to provide an implementation for every
+ // method of an interface it implements, but it is causing NoSuchMethodError
+ // issues on some Nokia JVMs. So we add this superfluous declaration:
+
+ public abstract Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws ReaderException;
+
}