X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=core%2Fsrc%2Fcom%2Fgoogle%2Fzxing%2Foned%2FITFReader.java;h=b380972d83d44e90002436e3d7c84405cfd3ab16;hb=25232481808167a95813df19c47d088e28922634;hp=49f065db39c2e5c287d649afaa46809cb0d68722;hpb=2b5462851c42d6dd33d4cd433b134129989c1dee;p=zxing.git diff --git a/core/src/com/google/zxing/oned/ITFReader.java b/core/src/com/google/zxing/oned/ITFReader.java index 49f065db..b380972d 100644 --- a/core/src/com/google/zxing/oned/ITFReader.java +++ b/core/src/com/google/zxing/oned/ITFReader.java @@ -17,28 +17,28 @@ package com.google.zxing.oned; import com.google.zxing.BarcodeFormat; -import com.google.zxing.ReaderException; +import com.google.zxing.DecodeHintType; +import com.google.zxing.FormatException; +import com.google.zxing.NotFoundException; import com.google.zxing.Result; import com.google.zxing.ResultPoint; -import com.google.zxing.DecodeHintType; import com.google.zxing.common.BitArray; -import com.google.zxing.common.GenericResultPoint; import java.util.Hashtable; /** *

Implements decoding of the ITF format.

* - *

"ITF" stands for Interleaved Two of Five. This Reader will scan ITF barcode with 6, 10 or 14 digits. - * The checksum is optional and is not applied by this Reader. The consumer of the decoded value - * will have to apply a checksum if required.

+ *

"ITF" stands for Interleaved Two of Five. This Reader will scan ITF barcode with 6, 10 or 14 + * digits. The checksum is optional and is not applied by this Reader. The consumer of the decoded + * value will have to apply a checksum if required.

* *

http://en.wikipedia.org/wiki/Interleaved_2_of_5 * is a great reference for Interleaved 2 of 5 information.

* * @author kevin.osullivan@sita.aero, SITA Lab. */ -public final class ITFReader extends AbstractOneDReader { +public final class ITFReader extends OneDReader { private static final int MAX_AVG_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.42f); private static final int MAX_INDIVIDUAL_VARIANCE = (int) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.8f); @@ -46,7 +46,7 @@ public final class ITFReader extends AbstractOneDReader { private static final int W = 3; // Pixel width of a wide line private static final int N = 1; // Pixed width of a narrow line - private static final int[] DEFAULT_ALLOWED_LENGTHS = { 6, 10, 14 }; + private static final int[] DEFAULT_ALLOWED_LENGTHS = { 6, 10, 14, 44 }; // Stores the actual narrow line width of the image being decoded. private int narrowLineWidth = -1; @@ -63,7 +63,7 @@ public final class ITFReader extends AbstractOneDReader { /** * Patterns of Wide / Narrow lines to indicate each digit */ - private static final int[][] PATTERNS = { + static final int[][] PATTERNS = { {N, N, W, W, N}, // 0 {W, N, N, N, W}, // 1 {N, W, N, N, W}, // 2 @@ -76,19 +76,21 @@ public final class ITFReader extends AbstractOneDReader { {N, W, N, W, N} // 9 }; - public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws ReaderException { - - StringBuffer result = new StringBuffer(20); + public Result decodeRow(int rowNumber, BitArray row, Hashtable hints) throws FormatException, NotFoundException { // Find out where the Middle section (payload) starts & ends int[] startRange = decodeStart(row); int[] endRange = decodeEnd(row); + StringBuffer result = new StringBuffer(20); decodeMiddle(row, startRange[1], endRange[0], result); - String resultString = result.toString(); - int[] allowedLengths = (int[]) hints.get(DecodeHintType.ALLOWED_LENGTHS); + int[] allowedLengths = null; + if (hints != null) { + allowedLengths = (int[]) hints.get(DecodeHintType.ALLOWED_LENGTHS); + + } if (allowedLengths == null) { allowedLengths = DEFAULT_ALLOWED_LENGTHS; } @@ -105,14 +107,14 @@ public final class ITFReader extends AbstractOneDReader { } if (!lengthOK) { - throw ReaderException.getInstance(); + throw FormatException.getFormatInstance(); } return new Result( resultString, null, // no natural byte representation for these barcodes - new ResultPoint[] { new GenericResultPoint(startRange[1], (float) rowNumber), - new GenericResultPoint(startRange[0], (float) rowNumber)}, + new ResultPoint[] { new ResultPoint(startRange[1], (float) rowNumber), + new ResultPoint(endRange[0], (float) rowNumber)}, BarcodeFormat.ITF); } @@ -120,9 +122,10 @@ public final class ITFReader extends AbstractOneDReader { * @param row row of black/white values to search * @param payloadStart offset of start pattern * @param resultString {@link StringBuffer} to append decoded chars to - * @throws ReaderException if decoding could not complete successfully + * @throws NotFoundException if decoding could not complete successfully */ - static void decodeMiddle(BitArray row, int payloadStart, int payloadEnd, StringBuffer resultString) throws ReaderException { + private static void decodeMiddle(BitArray row, int payloadStart, int payloadEnd, + StringBuffer resultString) throws NotFoundException { // Digits are interleaved in pairs - 5 black lines for one digit, and the // 5 @@ -161,9 +164,9 @@ public final class ITFReader extends AbstractOneDReader { * @param row row of black/white values to search * @return Array, containing index of start of 'start block' and end of * 'start block' - * @throws ReaderException + * @throws NotFoundException */ - int[] decodeStart(BitArray row) throws ReaderException { + int[] decodeStart(BitArray row) throws NotFoundException { int endStart = skipWhiteSpace(row); int[] startPattern = findGuardPattern(row, endStart, START_PATTERN); @@ -190,9 +193,9 @@ public final class ITFReader extends AbstractOneDReader { * * @param row bit array representing the scanned barcode. * @param startPattern index into row of the start or end pattern. - * @throws ReaderException if the quiet zone cannot be found, a ReaderException is thrown. + * @throws NotFoundException if the quiet zone cannot be found, a ReaderException is thrown. */ - private void validateQuietZone(BitArray row, int startPattern) throws ReaderException { + private void validateQuietZone(BitArray row, int startPattern) throws NotFoundException { int quietCount = this.narrowLineWidth * 10; // expect to find this many pixels of quiet zone @@ -204,7 +207,7 @@ public final class ITFReader extends AbstractOneDReader { } if (quietCount != 0) { // Unable to find the necessary number of quiet zone pixels. - throw ReaderException.getInstance(); + throw NotFoundException.getNotFoundInstance(); } } @@ -213,9 +216,9 @@ public final class ITFReader extends AbstractOneDReader { * * @param row row of black/white values to search * @return index of the first black line. - * @throws ReaderException Throws exception if no black lines are found in the row + * @throws NotFoundException Throws exception if no black lines are found in the row */ - private static int skipWhiteSpace(BitArray row) throws ReaderException { + private static int skipWhiteSpace(BitArray row) throws NotFoundException { int width = row.getSize(); int endStart = 0; while (endStart < width) { @@ -225,7 +228,7 @@ public final class ITFReader extends AbstractOneDReader { endStart++; } if (endStart == width) { - throw ReaderException.getInstance(); + throw NotFoundException.getNotFoundInstance(); } return endStart; @@ -237,40 +240,35 @@ public final class ITFReader extends AbstractOneDReader { * @param row row of black/white values to search * @return Array, containing index of start of 'end block' and end of 'end * block' - * @throws ReaderException + * @throws NotFoundException */ - int[] decodeEnd(BitArray row) throws ReaderException { + int[] decodeEnd(BitArray row) throws NotFoundException { // For convenience, reverse the row and then // search from 'the start' for the end block row.reverse(); - - int endStart = skipWhiteSpace(row); - int[] endPattern; try { - endPattern = findGuardPattern(row, endStart, END_PATTERN_REVERSED); - } catch (ReaderException e) { - // Put our row of data back the right way before throwing + int endStart = skipWhiteSpace(row); + int[] endPattern = findGuardPattern(row, endStart, END_PATTERN_REVERSED); + + // The start & end patterns must be pre/post fixed by a quiet zone. This + // zone must be at least 10 times the width of a narrow line. + // ref: http://www.barcode-1.net/i25code.html + validateQuietZone(row, endPattern[0]); + + // Now recalculate the indices of where the 'endblock' starts & stops to + // accommodate + // the reversed nature of the search + int temp = endPattern[0]; + endPattern[0] = row.getSize() - endPattern[1]; + endPattern[1] = row.getSize() - temp; + + return endPattern; + } finally { + // Put the row back the right way. row.reverse(); - throw e; } - - // The start & end patterns must be pre/post fixed by a quiet zone. This - // zone must be at least 10 times the width of a narrow line. - // ref: http://www.barcode-1.net/i25code.html - validateQuietZone(row, endPattern[0]); - - // Now recalc the indicies of where the 'endblock' starts & stops to - // accomodate - // the reversed nature of the search - int temp = endPattern[0]; - endPattern[0] = row.getSize() - endPattern[1]; - endPattern[1] = row.getSize() - temp; - - // Put the row back the righ way. - row.reverse(); - return endPattern; } /** @@ -280,13 +278,12 @@ public final class ITFReader extends AbstractOneDReader { * being searched for as a pattern * @return start/end horizontal offset of guard pattern, as an array of two * ints - * @throws ReaderException if pattern is not found + * @throws NotFoundException if pattern is not found */ - static int[] findGuardPattern(BitArray row, int rowOffset, int[] pattern) throws ReaderException { - - // TODO: This is very similar to implementation in AbstractUPCEANReader. Consider if they can be merged to - // a single method. + private static int[] findGuardPattern(BitArray row, int rowOffset, int[] pattern) throws NotFoundException { + // TODO: This is very similar to implementation in UPCEANReader. Consider if they can be + // merged to a single method. int patternLength = pattern.length; int[] counters = new int[patternLength]; int width = row.getSize(); @@ -296,7 +293,7 @@ public final class ITFReader extends AbstractOneDReader { int patternStart = rowOffset; for (int x = rowOffset; x < width; x++) { boolean pixel = row.get(x); - if ((!pixel && isWhite) || (pixel && !isWhite)) { + if (pixel ^ isWhite) { counters[counterPosition]++; } else { if (counterPosition == patternLength - 1) { @@ -317,7 +314,7 @@ public final class ITFReader extends AbstractOneDReader { isWhite = !isWhite; } } - throw ReaderException.getInstance(); + throw NotFoundException.getNotFoundInstance(); } /** @@ -326,9 +323,9 @@ public final class ITFReader extends AbstractOneDReader { * * @param counters the counts of runs of observed black/white/black/... values * @return The decoded digit - * @throws ReaderException if digit cannot be decoded + * @throws NotFoundException if digit cannot be decoded */ - private static int decodeDigit(int[] counters) throws ReaderException { + private static int decodeDigit(int[] counters) throws NotFoundException { int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept int bestMatch = -1; @@ -344,8 +341,8 @@ public final class ITFReader extends AbstractOneDReader { if (bestMatch >= 0) { return bestMatch; } else { - throw ReaderException.getInstance(); + throw NotFoundException.getNotFoundInstance(); } } -} \ No newline at end of file +}