halve function
image at half size (each side halved, at least 1), every pixel the
average of up to four source pixels. Alpha is always averaged linearly.
Implementation
RgbaImage halve(RgbaImage image, {required bool srgb}) {
final w = math.max(1, image.width >> 1);
final h = math.max(1, image.height >> 1);
final src = image.pixels;
final out = Uint8List(w * h * 4);
for (var y = 0; y < h; y++) {
final y0 = math.min(y * 2, image.height - 1);
final y1 = math.min(y * 2 + 1, image.height - 1);
for (var x = 0; x < w; x++) {
final x0 = math.min(x * 2, image.width - 1);
final x1 = math.min(x * 2 + 1, image.width - 1);
final a = (y0 * image.width + x0) * 4;
final b = (y0 * image.width + x1) * 4;
final c = (y1 * image.width + x0) * 4;
final d = (y1 * image.width + x1) * 4;
final o = (y * w + x) * 4;
for (var ch = 0; ch < 3; ch++) {
if (srgb) {
final sum =
_toLinear[src[a + ch]] +
_toLinear[src[b + ch]] +
_toLinear[src[c + ch]] +
_toLinear[src[d + ch]];
out[o + ch] = _linearToSrgb(sum / 4);
} else {
out[o + ch] =
(src[a + ch] + src[b + ch] + src[c + ch] + src[d + ch] + 2) >> 2;
}
}
out[o + 3] = (src[a + 3] + src[b + 3] + src[c + 3] + src[d + 3] + 2) >> 2;
}
}
return RgbaImage(w, h, out);
}