From cf91b368cfc0baa7fd06cb080553530241c4f931 Mon Sep 17 00:00:00 2001 From: Yegor Jbanov Date: Tue, 1 Dec 2020 15:47:57 -0800 Subject: [PATCH] Better handle image codec instantiation failure --- .../src/engine/canvaskit/canvaskit_api.dart | 2 +- .../lib/src/engine/canvaskit/image.dart | 11 ++++--- lib/web_ui/lib/src/ui/painting.dart | 32 ++++++------------- lib/web_ui/test/canvaskit/image_test.dart | 10 ++++++ 4 files changed, 28 insertions(+), 27 deletions(-) diff --git a/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart b/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart index b6d3132711055..a5fe4df54d0cd 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart @@ -44,7 +44,7 @@ class CanvasKit { external SkTextDirectionEnum get TextDirection; external SkFontWeightEnum get FontWeight; external SkFontSlantEnum get FontSlant; - external SkAnimatedImage MakeAnimatedImageFromEncoded(Uint8List imageData); + external SkAnimatedImage? MakeAnimatedImageFromEncoded(Uint8List imageData); external SkShaderNamespace get Shader; external SkMaskFilterNamespace get MaskFilter; external SkColorFilterNamespace get ColorFilter; diff --git a/lib/web_ui/lib/src/engine/canvaskit/image.dart b/lib/web_ui/lib/src/engine/canvaskit/image.dart index e4f64121383f7..dbf0f5974296a 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/image.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/image.dart @@ -6,10 +6,9 @@ part of engine; /// Instantiates a [ui.Codec] backed by an `SkAnimatedImage` from Skia. -void skiaInstantiateImageCodec(Uint8List list, Callback callback, +ui.Codec skiaInstantiateImageCodec(Uint8List list, [int? width, int? height, int? format, int? rowBytes]) { - final CkAnimatedImage codec = CkAnimatedImage.decodeFromBytes(list); - callback(codec); + return CkAnimatedImage.decodeFromBytes(list); } /// Instantiates a [ui.Codec] backed by an `SkAnimatedImage` from Skia after @@ -49,7 +48,11 @@ class CkAnimatedImage extends ManagedSkiaObject implements ui.C @override SkAnimatedImage createDefault() { - return canvasKit.MakeAnimatedImageFromEncoded(_bytes); + final SkAnimatedImage? animatedImage = canvasKit.MakeAnimatedImageFromEncoded(_bytes); + if (animatedImage == null) { + throw Exception('Failed to decode image'); + } + return animatedImage; } @override diff --git a/lib/web_ui/lib/src/ui/painting.dart b/lib/web_ui/lib/src/ui/painting.dart index 729b3d0f0b29f..3b3f14694e85b 100644 --- a/lib/web_ui/lib/src/ui/painting.dart +++ b/lib/web_ui/lib/src/ui/painting.dart @@ -452,20 +452,14 @@ Future instantiateImageCodec( int? targetWidth, int? targetHeight, bool allowUpscaling = true, -}) { - return _futurize((engine.Callback callback) => - // TODO: Implement targetWidth and targetHeight support. - _instantiateImageCodec(list, callback)); -} - -String? _instantiateImageCodec(Uint8List list, engine.Callback callback) { +}) async { if (engine.useCanvasKit) { - engine.skiaInstantiateImageCodec(list, callback); - return null; + // TODO: Implement targetWidth and targetHeight support. + return engine.skiaInstantiateImageCodec(list); + } else { + final html.Blob blob = html.Blob([list.buffer]); + return engine.HtmlBlobCodec(blob); } - final html.Blob blob = html.Blob([list.buffer]); - callback(engine.HtmlBlobCodec(blob)); - return null; } Future webOnlyInstantiateImageCodecFromUrl(Uri uri, @@ -565,12 +559,9 @@ Future _createBmp( } } - final Completer codecCompleter = Completer(); - _instantiateImageCodec( + return instantiateImageCodec( bmpData.buffer.asUint8List(), - (Codec codec) => codecCompleter.complete(codec), ); - return codecCompleter.future; } void decodeImageFromPixels( @@ -587,16 +578,13 @@ void decodeImageFromPixels( if (engine.useCanvasKit) { engine.skiaInstantiateImageCodec( pixels, - (Codec codec) { - codec.getNextFrame().then((FrameInfo info) { - callback(info.image); - }); - }, width, height, format.index, rowBytes, - ); + ).getNextFrame().then((FrameInfo info) { + callback(info.image); + }); return; } diff --git a/lib/web_ui/test/canvaskit/image_test.dart b/lib/web_ui/test/canvaskit/image_test.dart index 0f2073b076201..2b046240e6667 100644 --- a/lib/web_ui/test/canvaskit/image_test.dart +++ b/lib/web_ui/test/canvaskit/image_test.dart @@ -4,6 +4,7 @@ // @dart = 2.6 import 'dart:html' show ProgressEvent; +import 'dart:typed_data'; import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; @@ -114,6 +115,15 @@ void testMain() { expect((await image.toByteData(format: ui.ImageByteFormat.png)).lengthInBytes, greaterThan(0)); testCollector.collectNow(); }); + + test('Reports error when failing to decode image', () async { + try { + await ui.instantiateImageCodec(Uint8List(0)); + fail('Expected to throw'); + } on Exception catch (exception) { + expect(exception.toString(), 'Exception: Failed to decode image'); + } + }); // TODO: https://github.com/flutter/flutter/issues/60040 }, skip: isIosSafari); }