decode method
Future<DecodeResult>
decode(
- RequestContext ctx,
- FetchResult fetch
)
Implementation
@override
Future<DecodeResult> decode(RequestContext ctx, FetchResult fetch) async {
final bytes = await fetch.dataSource.bytes();
ctx.cancelToken.throwIfCancelled();
final target = await ctx.request.size?.resolve();
final Map<Object?, Object?>? payload;
try {
payload = await _channel.invokeMapMethod<Object?, Object?>('decode', {
'bytes': bytes,
'targetWidth': target?.width,
'targetHeight': target?.height,
});
} on PlatformException catch (e) {
throw ImageLoadException(
'AVIF decode failed: ${e.message}',
cause: e,
source: ctx.request.source,
);
} on MissingPluginException catch (e) {
throw ImageLoadException(
'AVIF plugin not available on this platform',
cause: e,
source: ctx.request.source,
);
}
if (payload == null) {
throw ImageLoadException('AVIF decode returned nothing',
source: ctx.request.source);
}
final png = payload['png'] as Uint8List?;
if (png == null) {
throw ImageLoadException('AVIF decode returned no image',
source: ctx.request.source);
}
final frameCount = (payload['frameCount'] as int?) ?? 1;
// instantiateImageCodecFromBuffer takes ownership of the buffer and
// disposes it once the codec is built — we must not dispose it ourselves.
final buffer = await ui.ImmutableBuffer.fromUint8List(png);
final codec = await ui.instantiateImageCodecFromBuffer(buffer);
try {
final frame = await codec.getNextFrame();
return DecodeResult(
image: frame.image,
from: fetch.dataSource.from,
mimeType: 'image/avif',
frameCount: frameCount,
);
} finally {
codec.dispose();
}
}