未验证 提交 b63e9114 编写于 作者: Y Yegor 提交者: GitHub

Better handle image codec instantiation failure (#22809)

上级 1c2a8f90
...@@ -44,7 +44,7 @@ class CanvasKit { ...@@ -44,7 +44,7 @@ class CanvasKit {
external SkTextDirectionEnum get TextDirection; external SkTextDirectionEnum get TextDirection;
external SkFontWeightEnum get FontWeight; external SkFontWeightEnum get FontWeight;
external SkFontSlantEnum get FontSlant; external SkFontSlantEnum get FontSlant;
external SkAnimatedImage MakeAnimatedImageFromEncoded(Uint8List imageData); external SkAnimatedImage? MakeAnimatedImageFromEncoded(Uint8List imageData);
external SkShaderNamespace get Shader; external SkShaderNamespace get Shader;
external SkMaskFilterNamespace get MaskFilter; external SkMaskFilterNamespace get MaskFilter;
external SkColorFilterNamespace get ColorFilter; external SkColorFilterNamespace get ColorFilter;
......
...@@ -6,10 +6,9 @@ ...@@ -6,10 +6,9 @@
part of engine; part of engine;
/// Instantiates a [ui.Codec] backed by an `SkAnimatedImage` from Skia. /// Instantiates a [ui.Codec] backed by an `SkAnimatedImage` from Skia.
void skiaInstantiateImageCodec(Uint8List list, Callback<ui.Codec> callback, ui.Codec skiaInstantiateImageCodec(Uint8List list,
[int? width, int? height, int? format, int? rowBytes]) { [int? width, int? height, int? format, int? rowBytes]) {
final CkAnimatedImage codec = CkAnimatedImage.decodeFromBytes(list); return CkAnimatedImage.decodeFromBytes(list);
callback(codec);
} }
/// Instantiates a [ui.Codec] backed by an `SkAnimatedImage` from Skia after /// Instantiates a [ui.Codec] backed by an `SkAnimatedImage` from Skia after
...@@ -49,7 +48,11 @@ class CkAnimatedImage extends ManagedSkiaObject<SkAnimatedImage> implements ui.C ...@@ -49,7 +48,11 @@ class CkAnimatedImage extends ManagedSkiaObject<SkAnimatedImage> implements ui.C
@override @override
SkAnimatedImage createDefault() { SkAnimatedImage createDefault() {
return canvasKit.MakeAnimatedImageFromEncoded(_bytes); final SkAnimatedImage? animatedImage = canvasKit.MakeAnimatedImageFromEncoded(_bytes);
if (animatedImage == null) {
throw Exception('Failed to decode image');
}
return animatedImage;
} }
@override @override
......
...@@ -452,20 +452,14 @@ Future<Codec> instantiateImageCodec( ...@@ -452,20 +452,14 @@ Future<Codec> instantiateImageCodec(
int? targetWidth, int? targetWidth,
int? targetHeight, int? targetHeight,
bool allowUpscaling = true, bool allowUpscaling = true,
}) { }) async {
return _futurize<Codec>((engine.Callback<Codec> callback) =>
// TODO: Implement targetWidth and targetHeight support.
_instantiateImageCodec(list, callback));
}
String? _instantiateImageCodec(Uint8List list, engine.Callback<Codec> callback) {
if (engine.useCanvasKit) { if (engine.useCanvasKit) {
engine.skiaInstantiateImageCodec(list, callback); // TODO: Implement targetWidth and targetHeight support.
return null; return engine.skiaInstantiateImageCodec(list);
} else {
final html.Blob blob = html.Blob(<dynamic>[list.buffer]);
return engine.HtmlBlobCodec(blob);
} }
final html.Blob blob = html.Blob(<dynamic>[list.buffer]);
callback(engine.HtmlBlobCodec(blob));
return null;
} }
Future<Codec> webOnlyInstantiateImageCodecFromUrl(Uri uri, Future<Codec> webOnlyInstantiateImageCodecFromUrl(Uri uri,
...@@ -565,12 +559,9 @@ Future<Codec> _createBmp( ...@@ -565,12 +559,9 @@ Future<Codec> _createBmp(
} }
} }
final Completer<Codec> codecCompleter = Completer<Codec>(); return instantiateImageCodec(
_instantiateImageCodec(
bmpData.buffer.asUint8List(), bmpData.buffer.asUint8List(),
(Codec codec) => codecCompleter.complete(codec),
); );
return codecCompleter.future;
} }
void decodeImageFromPixels( void decodeImageFromPixels(
...@@ -587,16 +578,13 @@ void decodeImageFromPixels( ...@@ -587,16 +578,13 @@ void decodeImageFromPixels(
if (engine.useCanvasKit) { if (engine.useCanvasKit) {
engine.skiaInstantiateImageCodec( engine.skiaInstantiateImageCodec(
pixels, pixels,
(Codec codec) {
codec.getNextFrame().then((FrameInfo info) {
callback(info.image);
});
},
width, width,
height, height,
format.index, format.index,
rowBytes, rowBytes,
); ).getNextFrame().then((FrameInfo info) {
callback(info.image);
});
return; return;
} }
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
// @dart = 2.6 // @dart = 2.6
import 'dart:html' show ProgressEvent; import 'dart:html' show ProgressEvent;
import 'dart:typed_data';
import 'package:test/bootstrap/browser.dart'; import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
...@@ -114,6 +115,15 @@ void testMain() { ...@@ -114,6 +115,15 @@ void testMain() {
expect((await image.toByteData(format: ui.ImageByteFormat.png)).lengthInBytes, greaterThan(0)); expect((await image.toByteData(format: ui.ImageByteFormat.png)).lengthInBytes, greaterThan(0));
testCollector.collectNow(); 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 // TODO: https://github.com/flutter/flutter/issues/60040
}, skip: isIosSafari); }, skip: isIosSafari);
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册