doDecode(image, hints) {
        const width = image.getWidth();
        const height = image.getHeight();
        let row = new BitArray(width);
        const tryHarder = hints && (hints.get(DecodeHintType.TRY_HARDER) === true);
        const rowStep = Math.max(1, height >> (tryHarder ? 8 : 5));
        let maxLines;
        if (tryHarder) {
            maxLines = height; // Look at the whole image, not just the center
        }
        else {
            maxLines = 15; // 15 rows spaced 1/32 apart is roughly the middle half of the image
        }
        const middle = Math.trunc(height / 2);
        for (let x = 0; x < maxLines; x++) {
            // Scanning from the middle out. Determine which row we're looking at next:
            const rowStepsAboveOrBelow = Math.trunc((x + 1) / 2);
            const isAbove = (x & 0x01) === 0; // i.e. is x even?
            const rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
            if (rowNumber < 0 || rowNumber >= height) {
                // Oops, if we run off the top or bottom, stop
                break;
            }
            // Estimate black point for this row and load it:
            try {
                row = image.getBlackRow(rowNumber, row);
            }
            catch (ignored) {
                continue;
            }
            // 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 (let attempt = 0; attempt < 2; attempt++) {
                if (attempt === 1) { // trying again?
                    row.reverse(); // reverse the row and continue
                    // This means we will only ever draw result points *once* in the life of this method
                    // since we want to avoid drawing the wrong points after flipping the row, and,
                    // don't want to clutter with noise from every single row scan -- just the scans
                    // that start on the center line.
                    if (hints && (hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK) === true)) {
                        const newHints = new Map();
                        hints.forEach((hint, key) => newHints.set(key, hint));
                        newHints.delete(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
                        hints = newHints;
                    }
                }
                try {
                    // Look for a barcode
                    const result = this.decodeRow(rowNumber, row, hints);
                    // We found our barcode
                    if (attempt === 1) {
                        // But it was upside down, so note that
                        result.putMetadata(ResultMetadataType.ORIENTATION, 180);
                        // And remember to flip the result points horizontally.
                        const points = result.getResultPoints();
                        if (points !== null) {
                            points[0] = new ResultPoint(width - points[0].getX() - 1, points[0].getY());
                            points[1] = new ResultPoint(width - points[1].getX() - 1, points[1].getY());
                        }
                    }
                    return result;
                }
                catch (re) {
                    // continue -- just couldn't decode this row
                }
            }
        }
        throw new NotFoundException();
    }
/**
     * We're going to examine rows from the middle outward, searching alternately above and below the
     * middle, and farther out each time. rowStep is the number of rows between each successive
     * attempt above and below the middle. So we'd scan row middle, then middle - rowStep, then
     * middle + rowStep, then middle - (2 * rowStep), etc.
     * rowStep is bigger as the image is taller, but is always at least 1. We've somewhat arbitrarily
     * decided that moving up and down by about 1/16 of the image is pretty good; we try more of the
     * image if "trying harder".
     *
     * @param image The image to decode
     * @param hints Any hints that were requested
     * @return The contents of the decoded barcode
     * @throws NotFoundException Any spontaneous errors which occur
     */
We're going to examine rows from the middle outward, searching alternately above and below the
middle, and farther out each time. rowStep is the number of rows between each successive
attempt above and below the middle. So we'd scan row middle, then middle - rowStep, then
middle + rowStep, then middle - (2 * rowStep), etc.
rowStep is bigger as the image is taller, but is always at least 1. We've somewhat arbitrarily
decided that moving up and down by about 1/16 of the image is pretty good; we try more of the
image if "trying harder".

@param image The image to decode
@param hints Any hints that were requested
@return The contents of the decoded barcode
@throws NotFoundException Any spontaneous errors which occur
We ' re going to examine rows from the middle outward searching alternately above and below the middle and farther out each time . rowStep is the number of rows between each successive attempt above and below the middle . So we ' d scan row middle then middle - rowStep then middle + rowStep then middle - ( 2 * rowStep ) etc . rowStep is bigger as the image is taller but is always at least 1 . We ' ve somewhat arbitrarily decided that moving up and down by about 1 / 16 of the image is pretty good ; we try more of the image if " trying harder " . @param image The image to decode @param hints Any hints that were requested @return The contents of the decoded barcode @throws NotFoundException Any spontaneous errors which occur
doDecode(image, hints) {
        const width = image.getWidth();
        const height = image.getHeight();
        let row = new BitArray(width);
        const tryHarder = hints && (hints.get(DecodeHintType.TRY_HARDER) === true);
        const rowStep = Math.max(1, height >> (tryHarder ? 8 : 5));
        let maxLines;
        if (tryHarder) {
            maxLines = height; 
        }
        else {
            maxLines = 15; 
        }
        const middle = Math.trunc(height / 2);
        for (let x = 0; x < maxLines; x++) {
            const rowStepsAboveOrBelow = Math.trunc((x + 1) / 2);
            const isAbove = (x & 0x01) === 0; 
            const rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
            if (rowNumber < 0 || rowNumber >= height) {
                break;
            }
            try {
                row = image.getBlackRow(rowNumber, row);
            }
            catch (ignored) {
                continue;
            }
            for (let attempt = 0; attempt < 2; attempt++) {
                if (attempt === 1) { 
                    row.reverse(); 
                    if (hints && (hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK) === true)) {
                        const newHints = new Map();
                        hints.forEach((hint, key) => newHints.set(key, hint));
                        newHints.delete(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
                        hints = newHints;
                    }
                }
                try {
                    const result = this.decodeRow(rowNumber, row, hints);
                    if (attempt === 1) {
                        result.putMetadata(ResultMetadataType.ORIENTATION, 180);
                        const points = result.getResultPoints();
                        if (points !== null) {
                            points[0] = new ResultPoint(width - points[0].getX() - 1, points[0].getY());
                            points[1] = new ResultPoint(width - points[1].getX() - 1, points[1].getY());
                        }
                    }
                    return result;
                }
                catch (re) {
                }
            }
        }
        throw new NotFoundException();
    }
doDecode ( image , hints ) { const width = image . getWidth ( ) ; const height = image . getHeight ( ) ; let row = new BitArray ( width ) ; const tryHarder = hints && ( hints . get ( DecodeHintType . TRY_HARDER ) === true ) ; const rowStep = Math . max ( 1 , height >> ( tryHarder ? 8 : 5 ) ) ; let maxLines ; if ( tryHarder ) { maxLines = height ; } else { maxLines = 15 ; } const middle = Math . trunc ( height / 2 ) ; for ( let x = 0 ; x < maxLines ; x ++ ) { const rowStepsAboveOrBelow = Math . trunc ( ( x + 1 ) / 2 ) ; const isAbove = ( x & 0x01 ) === 0 ; const rowNumber = middle + rowStep * ( isAbove ? rowStepsAboveOrBelow : - rowStepsAboveOrBelow ) ; if ( rowNumber < 0 || rowNumber >= height ) { break ; } try { row = image . getBlackRow ( rowNumber , row ) ; } catch ( ignored ) { continue ; } for ( let attempt = 0 ; attempt < 2 ; attempt ++ ) { if ( attempt === 1 ) { row . reverse ( ) ; if ( hints && ( hints . get ( DecodeHintType . NEED_RESULT_POINT_CALLBACK ) === true ) ) { const newHints = new Map ( ) ; hints . forEach ( ( hint , key ) => newHints . set ( key , hint ) ) ; newHints . delete ( DecodeHintType . NEED_RESULT_POINT_CALLBACK ) ; hints = newHints ; } } try { const result = this . decodeRow ( rowNumber , row , hints ) ; if ( attempt === 1 ) { result . putMetadata ( ResultMetadataType . ORIENTATION , 180 ) ; const points = result . getResultPoints ( ) ; if ( points !== null ) { points [ 0 ] = new ResultPoint ( width - points [ 0 ] . getX ( ) - 1 , points [ 0 ] . getY ( ) ) ; points [ 1 ] = new ResultPoint ( width - points [ 1 ] . getX ( ) - 1 , points [ 1 ] . getY ( ) ) ; } } return result ; } catch ( re ) { } } } throw new NotFoundException ( ) ; }
We're going to examine rows from the middle outward, searching alternately above and below the
 middle, and farther out each time.
We ' re going to examine rows from the middle outward searching alternately above and below the middle and farther out each time .
// Look at the whole image, not just the center // 15 rows spaced 1/32 apart is roughly the middle half of the image // Scanning from the middle out. Determine which row we're looking at next: // i.e. is x even? // Oops, if we run off the top or bottom, stop // Estimate black point for this row and load it: // While we have the image data in a BitArray, it's fairly cheap to reverse it in place to // handle decoding upside down barcodes. // trying again? // reverse the row and continue // This means we will only ever draw result points *once* in the life of this method // since we want to avoid drawing the wrong points after flipping the row, and, // don't want to clutter with noise from every single row scan -- just the scans // that start on the center line. // Look for a barcode // We found our barcode // But it was upside down, so note that // And remember to flip the result points horizontally. // continue -- just couldn't decode this row