doDecode(image, hints) {
			const width = image.getWidth();
			const height = image.getHeight();
			let row = new BitArray(width);
			const tryHarder = hints && (hints.get(DecodeHintType$1.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$1.NEED_RESULT_POINT_CALLBACK) === true)) {
							const newHints = new Map();
							hints.forEach((hint, key) => newHints.set(key, hint));
							newHints.delete(DecodeHintType$1.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$1.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