Class ITFReader

  • All Implemented Interfaces:
    Reader

    public final class ITFReader
    extends OneDReader

    Implements decoding of the ITF format, or Interleaved Two of Five.

    This Reader will scan ITF barcodes of certain lengths only. At the moment it reads length 6, 8, 10, 12, 14, 16, 18, 20, 24, and 44 as these have appeared "in the wild". Not all lengths are scanned, especially shorter ones, to avoid false positives. This in turn is due to a lack of required checksum function.

    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.

    • Field Detail

      • MAX_INDIVIDUAL_VARIANCE

        private static final float MAX_INDIVIDUAL_VARIANCE
        See Also:
        Constant Field Values
      • DEFAULT_ALLOWED_LENGTHS

        private static final int[] DEFAULT_ALLOWED_LENGTHS
        Valid ITF lengths. Anything longer than the largest value is also allowed.
      • narrowLineWidth

        private int narrowLineWidth
      • START_PATTERN

        private static final int[] START_PATTERN
        Start/end guard pattern. Note: The end pattern is reversed because the row is reversed before searching for the END_PATTERN
      • END_PATTERN_REVERSED

        private static final int[][] END_PATTERN_REVERSED
      • PATTERNS

        private static final int[][] PATTERNS
        Patterns of Wide / Narrow lines to indicate each digit
    • Constructor Detail

      • ITFReader

        public ITFReader()
    • Method Detail

      • decodeRow

        public Result decodeRow​(int rowNumber,
                                BitArray row,
                                java.util.Map<DecodeHintType,​?> hints)
                         throws FormatException,
                                NotFoundException
        Description copied from class: OneDReader

        Attempts to decode a one-dimensional barcode format given a single row of an image.

        Specified by:
        decodeRow in class OneDReader
        Parameters:
        rowNumber - row number from top of the row
        row - the black/white pixel data of the row
        hints - decode hints
        Returns:
        Result containing encoded string and start/end of barcode
        Throws:
        FormatException - if a potential barcode is found but format is invalid
        NotFoundException - if no potential barcode is found
      • decodeMiddle

        private static void decodeMiddle​(BitArray row,
                                         int payloadStart,
                                         int payloadEnd,
                                         java.lang.StringBuilder resultString)
                                  throws NotFoundException
        Parameters:
        row - row of black/white values to search
        payloadStart - offset of start pattern
        resultString - StringBuilder to append decoded chars to
        Throws:
        NotFoundException - if decoding could not complete successfully
      • decodeStart

        private int[] decodeStart​(BitArray row)
                           throws NotFoundException
        Identify where the start of the middle / payload section starts.
        Parameters:
        row - row of black/white values to search
        Returns:
        Array, containing index of start of 'start block' and end of 'start block'
        Throws:
        NotFoundException
      • validateQuietZone

        private void validateQuietZone​(BitArray row,
                                       int startPattern)
                                throws NotFoundException
        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. Scan back until we either get to the start of the barcode or match the necessary number of quiet zone pixels. Note: Its assumed the row is reversed when using this method to find quiet zone after the end pattern. ref: http://www.barcode-1.net/i25code.html
        Parameters:
        row - bit array representing the scanned barcode.
        startPattern - index into row of the start or end pattern.
        Throws:
        NotFoundException - if the quiet zone cannot be found
      • skipWhiteSpace

        private static int skipWhiteSpace​(BitArray row)
                                   throws NotFoundException
        Skip all whitespace until we get to the first black line.
        Parameters:
        row - row of black/white values to search
        Returns:
        index of the first black line.
        Throws:
        NotFoundException - Throws exception if no black lines are found in the row
      • decodeEnd

        private int[] decodeEnd​(BitArray row)
                         throws NotFoundException
        Identify where the end of the middle / payload section ends.
        Parameters:
        row - row of black/white values to search
        Returns:
        Array, containing index of start of 'end block' and end of 'end block'
        Throws:
        NotFoundException
      • findGuardPattern

        private static int[] findGuardPattern​(BitArray row,
                                              int rowOffset,
                                              int[] pattern)
                                       throws NotFoundException
        Parameters:
        row - row of black/white values to search
        rowOffset - position to start search
        pattern - pattern of counts of number of black and white pixels that are being searched for as a pattern
        Returns:
        start/end horizontal offset of guard pattern, as an array of two ints
        Throws:
        NotFoundException - if pattern is not found
      • decodeDigit

        private static int decodeDigit​(int[] counters)
                                throws NotFoundException
        Attempts to decode a sequence of ITF black/white lines into single digit.
        Parameters:
        counters - the counts of runs of observed black/white/black/... values
        Returns:
        The decoded digit
        Throws:
        NotFoundException - if digit cannot be decoded