decode method

  1. @override
Image? decode(
  1. Uint8List bytes, {
  2. int? frame,
})
override

Decode the file and extract a single image from it. If the file is animated, and frame is specified, that particular frame will be decoded. Otherwise if the image is animated and frame is null, the returned Image will include all frames. If there was a problem decoding the Image, null will be returned.

Implementation

@override
Image? decode(Uint8List bytes, {int? frame}) {
  if (startDecode(bytes) == null) {
    return null;
  }

  if (info!.numFrames == 1 || frame != null) {
    return decodeFrame(frame ?? 0);
  }

  Image? firstImage;
  Image? lastImage;
  for (var i = 0; i < info!.numFrames; ++i) {
    final frame = info!.frames[i];
    final image = decodeFrame(i);
    if (image == null) {
      return null;
    }

    image.frameDuration = frame.duration * 10; // Convert to MS

    if (firstImage == null || lastImage == null) {
      firstImage = image;
      lastImage = image;
      image.loopCount = _repeat;
      continue;
    }

    if (image.width == lastImage.width &&
        image.height == lastImage.height &&
        frame.x == 0 &&
        frame.y == 0 &&
        frame.disposal == 2) {
      lastImage = image;
      firstImage.addFrame(lastImage);
      continue;
    }

    final colorMap =
        (frame.colorMap != null) ? frame.colorMap! : info!.globalColorMap!;

    final nextImage = Image(
        width: lastImage.width,
        height: lastImage.height,
        numChannels: 1,
        palette: colorMap.getPalette());

    if (frame.disposal == 2) {
      nextImage.clear(colorMap.color(info!.backgroundColor!.r as int));
    } else if (frame.disposal != 3) {
      final nextBytes = nextImage.toUint8List();
      final lastBytes = lastImage.toUint8List();
      final lp = lastImage.palette!;
      for (var i = 0, l = nextBytes.length; i < l; ++i) {
        final lc = lastBytes[i];
        final nc = colorMap.findColor(
            lp.getRed(lc), lp.getGreen(lc), lp.getBlue(lc), lp.getAlpha(lc));
        if (nc != -1) {
          nextBytes[i] = nc;
        }
      }
    }

    nextImage.frameDuration = image.frameDuration;

    for (final p in image) {
      if (p.a != 0) {
        nextImage.setPixel(p.x + frame.x, p.y + frame.y, p);
      }
    }

    firstImage.addFrame(nextImage);
    lastImage = nextImage;
  }

  return firstImage;
}