hybrid static method
Implementation
static UBitMatrix hybrid(UGrayImage image) {
if (image.width < 40 || image.height < 40) return global(image);
final int subWidth = (image.width + _blockSize - 1) >> _blockShift;
final int subHeight = (image.height + _blockSize - 1) >> _blockShift;
final Uint8List averages = Uint8List(subWidth * subHeight);
for (int by = 0; by < subHeight; by++) {
int yOffset = by << _blockShift;
if (yOffset + _blockSize > image.height) yOffset = image.height - _blockSize;
for (int bx = 0; bx < subWidth; bx++) {
int xOffset = bx << _blockShift;
if (xOffset + _blockSize > image.width) xOffset = image.width - _blockSize;
int sum = 0;
int min = 255;
int max = 0;
for (int y = 0; y < _blockSize; y++) {
final int rowStart = (yOffset + y) * image.stride + xOffset;
for (int x = 0; x < _blockSize; x++) {
final int pixel = image.data[rowStart + x];
sum += pixel;
if (pixel < min) min = pixel;
if (pixel > max) max = pixel;
}
}
int average = sum >> (_blockShift * 2);
if (max - min <= _minDynamicRange) {
average = min ~/ 2;
if (by > 0 && bx > 0) {
final int neighbours = (averages[(by - 1) * subWidth + bx] + 2 * averages[by * subWidth + bx - 1] + averages[(by - 1) * subWidth + bx - 1]) ~/ 4;
if (min < neighbours) average = neighbours;
}
}
averages[by * subWidth + bx] = average;
}
}
final UBitMatrix matrix = UBitMatrix(image.width, image.height);
for (int by = 0; by < subHeight; by++) {
int yOffset = by << _blockShift;
if (yOffset + _blockSize > image.height) yOffset = image.height - _blockSize;
final int top = _clampBlock(by, subHeight);
for (int bx = 0; bx < subWidth; bx++) {
int xOffset = bx << _blockShift;
if (xOffset + _blockSize > image.width) xOffset = image.width - _blockSize;
final int leftBlock = _clampBlock(bx, subWidth);
int sum = 0;
for (int dy = -2; dy <= 2; dy++) {
final int rowStart = (top + dy) * subWidth;
sum += averages[rowStart + leftBlock - 2] +
averages[rowStart + leftBlock - 1] +
averages[rowStart + leftBlock] +
averages[rowStart + leftBlock + 1] +
averages[rowStart + leftBlock + 2];
}
final int threshold = sum ~/ 25;
for (int y = 0; y < _blockSize; y++) {
final int rowStart = (yOffset + y) * image.stride + xOffset;
for (int x = 0; x < _blockSize; x++) {
if (image.data[rowStart + x] <= threshold) matrix.set(xOffset + x, yOffset + y);
}
}
}
}
return matrix;
}