Skip to content

Commit b63e911

Browse files
authored
Better handle image codec instantiation failure (flutter#22809)
1 parent 1c2a8f9 commit b63e911

File tree

4 files changed

+28
-27
lines changed

4 files changed

+28
-27
lines changed

lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class CanvasKit {
4444
external SkTextDirectionEnum get TextDirection;
4545
external SkFontWeightEnum get FontWeight;
4646
external SkFontSlantEnum get FontSlant;
47-
external SkAnimatedImage MakeAnimatedImageFromEncoded(Uint8List imageData);
47+
external SkAnimatedImage? MakeAnimatedImageFromEncoded(Uint8List imageData);
4848
external SkShaderNamespace get Shader;
4949
external SkMaskFilterNamespace get MaskFilter;
5050
external SkColorFilterNamespace get ColorFilter;

lib/web_ui/lib/src/engine/canvaskit/image.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66
part of engine;
77

88
/// Instantiates a [ui.Codec] backed by an `SkAnimatedImage` from Skia.
9-
void skiaInstantiateImageCodec(Uint8List list, Callback<ui.Codec> callback,
9+
ui.Codec skiaInstantiateImageCodec(Uint8List list,
1010
[int? width, int? height, int? format, int? rowBytes]) {
11-
final CkAnimatedImage codec = CkAnimatedImage.decodeFromBytes(list);
12-
callback(codec);
11+
return CkAnimatedImage.decodeFromBytes(list);
1312
}
1413

1514
/// Instantiates a [ui.Codec] backed by an `SkAnimatedImage` from Skia after
@@ -49,7 +48,11 @@ class CkAnimatedImage extends ManagedSkiaObject<SkAnimatedImage> implements ui.C
4948

5049
@override
5150
SkAnimatedImage createDefault() {
52-
return canvasKit.MakeAnimatedImageFromEncoded(_bytes);
51+
final SkAnimatedImage? animatedImage = canvasKit.MakeAnimatedImageFromEncoded(_bytes);
52+
if (animatedImage == null) {
53+
throw Exception('Failed to decode image');
54+
}
55+
return animatedImage;
5356
}
5457

5558
@override

lib/web_ui/lib/src/ui/painting.dart

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -452,20 +452,14 @@ Future<Codec> instantiateImageCodec(
452452
int? targetWidth,
453453
int? targetHeight,
454454
bool allowUpscaling = true,
455-
}) {
456-
return _futurize<Codec>((engine.Callback<Codec> callback) =>
457-
// TODO: Implement targetWidth and targetHeight support.
458-
_instantiateImageCodec(list, callback));
459-
}
460-
461-
String? _instantiateImageCodec(Uint8List list, engine.Callback<Codec> callback) {
455+
}) async {
462456
if (engine.useCanvasKit) {
463-
engine.skiaInstantiateImageCodec(list, callback);
464-
return null;
457+
// TODO: Implement targetWidth and targetHeight support.
458+
return engine.skiaInstantiateImageCodec(list);
459+
} else {
460+
final html.Blob blob = html.Blob(<dynamic>[list.buffer]);
461+
return engine.HtmlBlobCodec(blob);
465462
}
466-
final html.Blob blob = html.Blob(<dynamic>[list.buffer]);
467-
callback(engine.HtmlBlobCodec(blob));
468-
return null;
469463
}
470464

471465
Future<Codec> webOnlyInstantiateImageCodecFromUrl(Uri uri,
@@ -565,12 +559,9 @@ Future<Codec> _createBmp(
565559
}
566560
}
567561

568-
final Completer<Codec> codecCompleter = Completer<Codec>();
569-
_instantiateImageCodec(
562+
return instantiateImageCodec(
570563
bmpData.buffer.asUint8List(),
571-
(Codec codec) => codecCompleter.complete(codec),
572564
);
573-
return codecCompleter.future;
574565
}
575566

576567
void decodeImageFromPixels(
@@ -587,16 +578,13 @@ void decodeImageFromPixels(
587578
if (engine.useCanvasKit) {
588579
engine.skiaInstantiateImageCodec(
589580
pixels,
590-
(Codec codec) {
591-
codec.getNextFrame().then((FrameInfo info) {
592-
callback(info.image);
593-
});
594-
},
595581
width,
596582
height,
597583
format.index,
598584
rowBytes,
599-
);
585+
).getNextFrame().then((FrameInfo info) {
586+
callback(info.image);
587+
});
600588
return;
601589
}
602590

lib/web_ui/test/canvaskit/image_test.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
// @dart = 2.6
66
import 'dart:html' show ProgressEvent;
7+
import 'dart:typed_data';
78

89
import 'package:test/bootstrap/browser.dart';
910
import 'package:test/test.dart';
@@ -114,6 +115,15 @@ void testMain() {
114115
expect((await image.toByteData(format: ui.ImageByteFormat.png)).lengthInBytes, greaterThan(0));
115116
testCollector.collectNow();
116117
});
118+
119+
test('Reports error when failing to decode image', () async {
120+
try {
121+
await ui.instantiateImageCodec(Uint8List(0));
122+
fail('Expected to throw');
123+
} on Exception catch (exception) {
124+
expect(exception.toString(), 'Exception: Failed to decode image');
125+
}
126+
});
117127
// TODO: https://github.com/flutter/flutter/issues/60040
118128
}, skip: isIosSafari);
119129
}

0 commit comments

Comments
 (0)