@@ -65,32 +65,33 @@ class CkBrowserImageDecoder implements ui.Codec {
6565 );
6666 }
6767
68- final _ImageDecoder webDecoder = _ImageDecoder (_ImageDecoderOptions (
69- type: contentType,
70- data: data,
68+ try {
69+ final _ImageDecoder webDecoder = _ImageDecoder (_ImageDecoderOptions (
70+ type: contentType,
71+ data: data,
7172
72- // Flutter always uses premultiplied alpha.
73- premultiplyAlpha: 'premultiply' ,
74- desiredWidth: targetWidth,
75- desiredHeight: targetHeight,
73+ // Flutter always uses premultiplied alpha.
74+ premultiplyAlpha: 'premultiply' ,
75+ desiredWidth: targetWidth,
76+ desiredHeight: targetHeight,
7677
77- // "default" gives the browser the liberty to convert to display-appropriate
78- // color space, typically SRGB, which is what we want.
79- colorSpaceConversion: 'default' ,
78+ // "default" gives the browser the liberty to convert to display-appropriate
79+ // color space, typically SRGB, which is what we want.
80+ colorSpaceConversion: 'default' ,
8081
81- // Flutter doesn't give the developer a way to customize this, so if this
82- // is an animated image we should prefer the animated track.
83- preferAnimation: true ,
84- ));
82+ // Flutter doesn't give the developer a way to customize this, so if this
83+ // is an animated image we should prefer the animated track.
84+ preferAnimation: true ,
85+ ));
8586
86- try {
8787 await js_util.promiseToFuture <void >(webDecoder.tracks.ready);
8888
8989 // Flutter doesn't have an API for progressive loading of images, so we
9090 // wait until the image is fully decoded.
9191 // package:js bindings don't work with getters that return a Promise, which
9292 // is why js_util is used instead.
9393 await js_util.promiseToFuture <void >(js_util.getProperty (webDecoder, 'completed' ));
94+ return CkBrowserImageDecoder ._(webDecoder, debugSource);
9495 } catch (error) {
9596 if (error is html.DomException ) {
9697 if (error.name == html.DomException .NOT_SUPPORTED ) {
@@ -106,7 +107,6 @@ class CkBrowserImageDecoder implements ui.Codec {
106107 'Original browser error: $error '
107108 );
108109 }
109- return CkBrowserImageDecoder ._(webDecoder, debugSource);
110110 }
111111
112112 CkBrowserImageDecoder ._(this .webDecoder, this .debugSource);
@@ -164,6 +164,13 @@ class CkBrowserImageDecoder implements ui.Codec {
164164 frame.displayWidth,
165165 frame.displayHeight,
166166 );
167+ // Duration can be null if the image is not animated. However, Flutter
168+ // requires a non-null value. 0 indicates that the frame is meant to be
169+ // displayed indefinitely, which is fine for a static image.
170+ final Duration duration = Duration (microseconds: frame.duration ?? 0 );
171+
172+ // Do not use the `frame` variable after this line.
173+ frame.close ();
167174
168175 if (skImage == null ) {
169176 throw ImageCodecException (
@@ -172,12 +179,6 @@ class CkBrowserImageDecoder implements ui.Codec {
172179 }
173180
174181 final CkImage image = CkImage (skImage);
175-
176- // Duration can be null if the image is not animated. However, Flutter
177- // requires a non-null value. 0 indicates that the frame is meant to be
178- // displayed indefinitely, which is fine for a static image.
179- final Duration duration = Duration (microseconds: frame.duration ?? 0 );
180-
181182 return Future <ui.FrameInfo >.value (AnimatedImageFrameInfo (duration, image));
182183 }
183184
@@ -254,6 +255,7 @@ class _VideoFrame {
254255 external int get displayWidth;
255256 external int get displayHeight;
256257 external int ? get duration;
258+ external void close ();
257259}
258260
259261/// Corresponds to the browser's `ImageTrackList` type.
0 commit comments