addFrame method

void addFrame(
  1. Image image
)

Implementation

void addFrame(Image image) {
  // PNG can't encode HDR formats, and can only encode formats with fewer
  // than 8 bits if they have a palette. In the case of incompatible
  // formats, convert them to uint8.
  if ((image.isHdrFormat && image.format != Format.uint16) ||
      (image.bitsPerChannel < 8 &&
          !image.hasPalette &&
          image.numChannels > 1)) {
    image = image.convert(format: Format.uint8);
  }

  if (output == null) {
    output = OutputBuffer(bigEndian: true);

    _writeHeader(image);

    if (image.iccProfile != null) {
      _writeICCPChunk(output, image.iccProfile!);
    }

    if (image.hasPalette) {
      if (_globalQuantizer != null) {
        _writePalette(_globalQuantizer!.palette);
      } else {
        _writePalette(image.palette!);
      }
    }

    if (isAnimated) {
      _writeAnimationControlChunk();
    }
  }

  final nc = _numChannels(image);

  final channelBytes = image.format == Format.uint16 ? 2 : 1;

  // Include room for the filter bytes (1 byte per row).
  final filteredImage = Uint8List(
      (image.width * image.height * nc * channelBytes) + image.height);

  _filter(image, filteredImage);

  final compressed = const ZLibEncoder().encode(filteredImage, level: level);

  if (image.textData != null) {
    for (var key in image.textData!.keys) {
      _writeTextChunk(key, image.textData![key]!);
    }
  }

  if (isAnimated) {
    _writeFrameControlChunk(image);
    sequenceNumber++;
  }

  if (sequenceNumber <= 1) {
    _writeChunk(output!, 'IDAT', compressed);
  } else {
    // fdAT chunk
    final fdat = OutputBuffer(bigEndian: true)
      ..writeUint32(sequenceNumber)
      ..writeBytes(compressed);
    _writeChunk(output!, 'fdAT', fdat.getBytes());

    sequenceNumber++;
  }
}