encodeCompressedPng function

Uint8List encodeCompressedPng(
  1. int width,
  2. int height,
  3. Uint8List rgba
)

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();
}