encodeCompressedPng function
rgba (width × height, four bytes a pixel, top row first — the same
shape DecodedImage.rgba reads back) written as an 8-bit RGBA PNG.
Implementation
Uint8List encodeCompressedPng(int width, int height, Uint8List rgba) {
const bpp = 4;
final rowBytes = width * bpp;
final filtered = Uint8List(height * (rowBytes + 1));
final previous = Uint8List(rowBytes);
final current = Uint8List(rowBytes);
var out = 0;
for (var y = 0; y < height; y++) {
current.setRange(0, rowBytes, rgba, y * rowBytes);
final best = _bestFilter(current, previous, bpp);
filtered[out++] = best.type;
filtered.setRange(out, out + rowBytes, best.row);
out += rowBytes;
previous.setRange(0, rowBytes, current);
}
final compressed = zlibCompress(filtered);
final result = BytesBuilder();
result.add(_signature);
final ihdr = ByteData(13)
..setUint32(0, width, Endian.big)
..setUint32(4, height, Endian.big)
..setUint8(8, 8) // bit depth
..setUint8(9, 6) // colour type: RGBA
..setUint8(10, 0)
..setUint8(11, 0)
..setUint8(12, 0);
_writeChunk(result, 'IHDR', ihdr.buffer.asUint8List());
_writeChunk(result, 'IDAT', compressed);
_writeChunk(result, 'IEND', const <int>[]);
return result.toBytes();
}