Fix getNextFrame (#21422)

This commit is contained in:
Dan Field 2020-09-25 17:26:59 -07:00 committed by GitHub
parent f1961e5209
commit 08cf7256d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 18 deletions

View File

@ -1905,8 +1905,6 @@ class Codec extends NativeFieldWrapperClass2 {
int get repetitionCount => _cachedRepetitionCount ??= _repetitionCount;
int get _repetitionCount native 'Codec_repetitionCount';
FrameInfo? _cachedFrame;
/// Fetches the next animation frame.
///
/// Wraps back to the first frame after returning the last frame.
@ -1916,24 +1914,20 @@ class Codec extends NativeFieldWrapperClass2 {
/// The caller of this method is responsible for disposing the
/// [FrameInfo.image] on the returned object.
Future<FrameInfo> getNextFrame() async {
if (_cachedFrame == null || frameCount != 1) {
final Completer<void> completer = Completer<void>.sync();
final String? error = _getNextFrame((_Image? image, int durationMilliseconds) {
if (image == null) {
throw Exception('Codec failed to produce an image, possibly due to invalid image data.');
}
_cachedFrame = FrameInfo._(
image: Image._(image),
duration: Duration(milliseconds: durationMilliseconds),
);
completer.complete();
});
if (error != null) {
throw Exception(error);
final Completer<FrameInfo> completer = Completer<FrameInfo>.sync();
final String? error = _getNextFrame((_Image? image, int durationMilliseconds) {
if (image == null) {
throw Exception('Codec failed to produce an image, possibly due to invalid image data.');
}
await completer.future;
completer.complete(FrameInfo._(
image: Image._(image),
duration: Duration(milliseconds: durationMilliseconds),
));
});
if (error != null) {
throw Exception(error);
}
return _cachedFrame!;
return await completer.future;
}
/// Returns an error message on failure, null on success.

View File

@ -114,6 +114,18 @@ void main() {
expect(frame2.image.isCloneOf(frame.image), false);
});
test('getNextFrame does not return a disposed image', () async {
final Uint8List bytes = await readFile('2x2.png');
final Codec codec = await instantiateImageCodec(bytes);
final FrameInfo frame = await codec.getNextFrame();
frame.image.dispose();
final FrameInfo frame2 = await codec.getNextFrame();
expect(frame2.image.clone()..dispose(), isNotNull);
frame2.image.dispose();
});
}
Future<Uint8List> readFile(String fileName) async {