Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions lib/ui/painting.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2129,8 +2129,9 @@ Future<void> _decodeImageFromListAsync(Uint8List list,

/// Convert an array of pixel values into an [Image] object.
///
/// The `pixels` parameter is the pixel data in the encoding described by
/// `format`.
/// The `pixels` parameter is the pixel data. They are packed in bytes in the
/// order described by `format`, then grouped in rows, from left to right,
/// then top to bottom.
///
/// The `rowBytes` parameter is the number of bytes consumed by each row of
/// pixels in the data buffer. If unspecified, it defaults to `width` multiplied
Expand Down Expand Up @@ -5637,8 +5638,9 @@ class ImageDescriptor extends NativeFieldWrapperClass1 {

/// Creates an image descriptor from raw image pixels.
///
/// The `pixels` parameter is the pixel data in the encoding described by
/// `format`.
/// The `pixels` parameter is the pixel data. They are packed in bytes in the
/// order described by `pixelFormat`, then grouped in rows, from left to right,
/// then top to bottom.
///
/// The `rowBytes` parameter is the number of bytes consumed by each row of
/// pixels in the data buffer. If unspecified, it defaults to `width` multiplied
Expand Down
31 changes: 31 additions & 0 deletions lib/web_ui/test/html/image_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,32 @@ Future<Image> _encodeToHtmlThenDecode(
return (await (await descriptor.instantiateCodec()).getNextFrame()).image;
}

// This utility function detects how the current Web engine decodes pixel data.
//
// The HTML renderer uses the BMP format to display pixel data, but it used to
// use a wrong implementation. The bug has been fixed, but the fix breaks apps
// that had to provide incorrect data to work around this issue. This function
// is used in the migration guide to assist libraries that would like to run on
// both pre- and post-patch engines by testing the current behavior on a single
// pixel, making use the fact that the patch fixes the pixel order.
//
// The `format` argument is used for testing. In the actual code it should be
// replaced by `PixelFormat.rgba8888`.
//
// See also:
//
// * Patch: https://github.com/flutter/engine/pull/29448
// * Migration guide: https://docs.flutter.dev/release/breaking-changes/raw-images-on-web-uses-correct-origin-and-colors
Future<bool> rawImageUsesCorrectBehavior(PixelFormat format) async {
final ImageDescriptor descriptor = ImageDescriptor.raw(
await ImmutableBuffer.fromUint8List(Uint8List.fromList(<int>[0xED, 0, 0, 0xFF])),
width: 1, height: 1, pixelFormat: format);
final Image image = (await (await descriptor.instantiateCodec()).getNextFrame()).image;
final Uint8List resultPixels = Uint8List.sublistView(
(await image.toByteData(format: ImageByteFormat.rawStraightRgba))!);
return resultPixels[0] == 0xED;
}

Future<void> testMain() async {
test('Correctly encodes an opaque image', () async {
// A 2x2 testing image without transparency.
Expand Down Expand Up @@ -145,4 +171,9 @@ Future<void> testMain() async {
);
expect(actualPixels, listEqual(benchmarkPixels, tolerance: 1));
});

test('The behavior detector works correctly', () async {
expect(await rawImageUsesCorrectBehavior(PixelFormat.rgba8888), true);
expect(await rawImageUsesCorrectBehavior(PixelFormat.bgra8888), false);
});
}