static calculateBlackPoints(luminances, subWidth /*int*/, subHeight /*int*/, width /*int*/, height /*int*/) {
			const maxYOffset = height - HybridBinarizer.BLOCK_SIZE;
			const maxXOffset = width - HybridBinarizer.BLOCK_SIZE;
			// tslint:disable-next-line:whitespace
			const blackPoints = new Array(subHeight); // subWidth
			for (let y = 0; y < subHeight; y++) {
				blackPoints[y] = new Int32Array(subWidth);
				let yoffset = y << HybridBinarizer.BLOCK_SIZE_POWER;
				if (yoffset > maxYOffset) {
					yoffset = maxYOffset;
				}
				for (let x = 0; x < subWidth; x++) {
					let xoffset = x << HybridBinarizer.BLOCK_SIZE_POWER;
					if (xoffset > maxXOffset) {
						xoffset = maxXOffset;
					}
					let sum = 0;
					let min = 0xFF;
					let max = 0;
					for (let yy = 0, offset = yoffset * width + xoffset; yy < HybridBinarizer.BLOCK_SIZE; yy++, offset += width) {
						for (let xx = 0; xx < HybridBinarizer.BLOCK_SIZE; xx++) {
							const pixel = luminances[offset + xx] & 0xFF;
							sum += pixel;
							// still looking for good contrast
							if (pixel < min) {
								min = pixel;
							}
							if (pixel > max) {
								max = pixel;
							}
						}
						// short-circuit min/max tests once dynamic range is met
						if (max - min > HybridBinarizer.MIN_DYNAMIC_RANGE) {
							// finish the rest of the rows quickly
							for (yy++, offset += width; yy < HybridBinarizer.BLOCK_SIZE; yy++, offset += width) {
								for (let xx = 0; xx < HybridBinarizer.BLOCK_SIZE; xx++) {
									sum += luminances[offset + xx] & 0xFF;
								}
							}
						}
					}
					// The default estimate is the average of the values in the block.
					let average = sum >> (HybridBinarizer.BLOCK_SIZE_POWER * 2);
					if (max - min <= HybridBinarizer.MIN_DYNAMIC_RANGE) {
						// If variation within the block is low, assume this is a block with only light or only
						// dark pixels. In that case we do not want to use the average, as it would divide this
						// low contrast area into black and white pixels, essentially creating data out of noise.
						//
						// The default assumption is that the block is light/background. Since no estimate for
						// the level of dark pixels exists locally, use half the min for the block.
						average = min / 2;
						if (y > 0 && x > 0) {
							// Correct the "white background" assumption for blocks that have neighbors by comparing
							// the pixels in this block to the previously calculated black points. This is based on
							// the fact that dark barcode symbology is always surrounded by some amount of light
							// background for which reasonable black point estimates were made. The bp estimated at
							// the boundaries is used for the interior.
							// The (min < bp) is arbitrary but works better than other heuristics that were tried.
							const averageNeighborBlackPoint = (blackPoints[y - 1][x] + (2 * blackPoints[y][x - 1]) + blackPoints[y - 1][x - 1]) / 4;
							if (min < averageNeighborBlackPoint) {
								average = averageNeighborBlackPoint;
							}
						}
					}
					blackPoints[y][x] = average;
				}
			}
			return blackPoints;
		}
Calculates a single black point for each block of pixels and saves it away.
See the following thread for a discussion of this algorithm:
 http://groups.google.com/group/zxing/browse_thread/thread/d06efa2c35a7ddc0