// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:typed_data';

import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart' as ui;
import 'package:web_engine_tester/golden_tester.dart';

import '../common/matchers.dart';
import 'common.dart';
import 'test_data.dart';

void main() {
  internalBootstrapBrowserTest(() => testMain);
}

void testMain() {
  group('CanvasKit Images', () {
    setUpCanvasKitTest();

    tearDown(() {
      mockHttpFetchResponseFactory = null;
    });

    _testCkAnimatedImage();
    _testForImageCodecs(useBrowserImageDecoder: false);

    if (browserSupportsImageDecoder) {
      _testForImageCodecs(useBrowserImageDecoder: true);
      _testCkBrowserImageDecoder();
    }

    test('isAvif', () {
      expect(isAvif(Uint8List.fromList(<int>[])), isFalse);
      expect(isAvif(Uint8List.fromList(<int>[1, 2, 3])), isFalse);
      expect(
        isAvif(Uint8List.fromList(<int>[
          0x00, 0x00, 0x00, 0x1c, 0x66, 0x74, 0x79, 0x70,
          0x61, 0x76, 0x69, 0x66, 0x00, 0x00, 0x00, 0x00,
        ])),
        isTrue,
      );
      expect(
        isAvif(Uint8List.fromList(<int>[
          0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70,
          0x61, 0x76, 0x69, 0x66, 0x00, 0x00, 0x00, 0x00,
        ])),
        isTrue,
      );
    });
  }, skip: isSafari);
}

void _testForImageCodecs({required bool useBrowserImageDecoder}) {
  final String mode = useBrowserImageDecoder ? 'webcodecs' : 'wasm';
  final List<String> warnings = <String>[];
  late void Function(String) oldPrintWarning;

  group('($mode)', () {
    setUp(() {
      browserSupportsImageDecoder = useBrowserImageDecoder;
      warnings.clear();
    });

    setUpAll(() {
      oldPrintWarning = printWarning;
      printWarning = (String warning) {
        warnings.add(warning);
      };
    });

    tearDown(() {
      debugResetBrowserSupportsImageDecoder();
    });

    tearDownAll(() {
      printWarning = oldPrintWarning;
    });

    test('CkAnimatedImage can be explicitly disposed of', () {
      final CkAnimatedImage image = CkAnimatedImage.decodeFromBytes(kTransparentImage, 'test');
      expect(image.debugDisposed, isFalse);
      image.dispose();
      expect(image.debugDisposed, isTrue);

      // Disallow usage after disposal
      expect(() => image.frameCount, throwsAssertionError);
      expect(() => image.repetitionCount, throwsAssertionError);
      expect(() => image.getNextFrame(), throwsAssertionError);

      // Disallow double-dispose.
      expect(() => image.dispose(), throwsAssertionError);
      testCollector.collectNow();
    });

    test('CkAnimatedImage remembers last animation position after resurrection', () async {
      browserSupportsFinalizationRegistry = false;

      final CkAnimatedImage image = CkAnimatedImage.decodeFromBytes(kAnimatedGif, 'test');
      expect(image.frameCount, 3);
      expect(image.repetitionCount, -1);

      final ui.FrameInfo frame1 = await image.getNextFrame();
      await expectFrameData(frame1, <int>[255, 0, 0, 255]);
      final ui.FrameInfo frame2 = await image.getNextFrame();
      await expectFrameData(frame2, <int>[0, 255, 0, 255]);

      // Pretend that the image is temporarily deleted.
      image.delete();
      image.didDelete();

      // Check that we got the 3rd frame after resurrection.
      final ui.FrameInfo frame3 = await image.getNextFrame();
      await expectFrameData(frame3, <int>[0, 0, 255, 255]);

      testCollector.collectNow();
    });

    test('CkImage toString', () {
      final SkImage skImage =
          canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage)!
              .makeImageAtCurrentFrame();
      final CkImage image = CkImage(skImage);
      expect(image.toString(), '[1×1]');
      image.dispose();
      testCollector.collectNow();
    });

    test('CkImage can be explicitly disposed of', () {
      final SkImage skImage =
          canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage)!
              .makeImageAtCurrentFrame();
      final CkImage image = CkImage(skImage);
      expect(image.debugDisposed, isFalse);
      expect(image.box.isDisposed, isFalse);
      image.dispose();
      expect(image.debugDisposed, isTrue);
      expect(image.box.isDisposed, isTrue);

      // Disallow double-dispose.
      expect(() => image.dispose(), throwsAssertionError);
      testCollector.collectNow();
    });

    test('CkImage can be explicitly disposed of when cloned', () async {
      final SkImage skImage =
          canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage)!
              .makeImageAtCurrentFrame();
      final CkImage image = CkImage(skImage);
      final CountedRef<CkImage, SkImage> box = image.box;
      expect(box.refCount, 1);
      expect(box.debugGetStackTraces().length, 1);

      final CkImage clone = image.clone();
      expect(box.refCount, 2);
      expect(box.debugGetStackTraces().length, 2);

      expect(image.isCloneOf(clone), isTrue);
      expect(box.isDisposed, isFalse);

      testCollector.collectNow();
      expect(skImage.isDeleted(), isFalse);
      image.dispose();
      expect(box.refCount, 1);
      expect(box.isDisposed, isFalse);

      testCollector.collectNow();
      expect(skImage.isDeleted(), isFalse);
      clone.dispose();
      expect(box.refCount, 0);
      expect(box.isDisposed, isTrue);

      testCollector.collectNow();
      expect(skImage.isDeleted(), isTrue);
      expect(box.debugGetStackTraces().length, 0);
      testCollector.collectNow();
    });

    test('CkImage toByteData', () async {
      final SkImage skImage =
          canvasKit.MakeAnimatedImageFromEncoded(kTransparentImage)!
              .makeImageAtCurrentFrame();
      final CkImage image = CkImage(skImage);
      expect((await image.toByteData()).lengthInBytes, greaterThan(0));
      expect((await image.toByteData(format: ui.ImageByteFormat.png)).lengthInBytes, greaterThan(0));
      testCollector.collectNow();
    });

    test('toByteData with decodeImageFromPixels on videoFrame formats', () async {
      // This test ensures that toByteData() returns pixels that can be used by decodeImageFromPixels
      // for the following videoFrame formats:
      // [BGRX, I422, I420, I444, BGRA]
      final HttpFetchResponse listingResponse = await httpFetch('/test_images/');
      final List<String> testFiles = (await listingResponse.json() as List<dynamic>).cast<String>();

      Future<ui.Image> testDecodeFromPixels(Uint8List pixels, int width, int height) async {
        final Completer<ui.Image> completer = Completer<ui.Image>();
        ui.decodeImageFromPixels(
          pixels,
          width,
          height,
          ui.PixelFormat.rgba8888,
          (ui.Image image) {
            completer.complete(image);
          },
        );
        return completer.future;
      }

      // Sanity-check the test file list. If suddenly test files are moved or
      // deleted, and the test server returns an empty list, or is missing some
      // important test files, we want to know.
      expect(testFiles, isNotEmpty);
      expect(testFiles, contains(matches(RegExp(r'.*\.jpg'))));
      expect(testFiles, contains(matches(RegExp(r'.*\.png'))));
      expect(testFiles, contains(matches(RegExp(r'.*\.gif'))));
      expect(testFiles, contains(matches(RegExp(r'.*\.webp'))));
      expect(testFiles, contains(matches(RegExp(r'.*\.bmp'))));

      for (final String testFile in testFiles) {
        final HttpFetchResponse imageResponse = await httpFetch('/test_images/$testFile');
        final Uint8List imageData = await imageResponse.asUint8List();
        final ui.Codec codec = await skiaInstantiateImageCodec(imageData);
        expect(codec.frameCount, greaterThan(0));
        expect(codec.repetitionCount, isNotNull);

        final ui.FrameInfo frame = await codec.getNextFrame();
        final CkImage ckImage = frame.image as CkImage;
        final ByteData imageBytes = await ckImage.toByteData();
        expect(imageBytes.lengthInBytes, greaterThan(0));

        final Uint8List pixels = imageBytes.buffer.asUint8List();
        final ui.Image testImage = await testDecodeFromPixels(pixels, ckImage.width, ckImage.height);
        expect(testImage, isNotNull);
        codec.dispose();
      }
      // TODO(hterkelsen): Firefox and Safari do not currently support ImageDecoder.
      // TODO(jacksongardner): enable on wasm
      // see https://github.com/flutter/flutter/issues/118334
    }, skip: isFirefox || isSafari || isWasm);

    test('CkImage.clone also clones the VideoFrame', () async {
      final CkBrowserImageDecoder image = await CkBrowserImageDecoder.create(
        data: kAnimatedGif,
        debugSource: 'test',
      );
      final ui.FrameInfo frame = await image.getNextFrame();
      final CkImage ckImage = frame.image as CkImage;
      expect(ckImage.videoFrame, isNotNull);

      final CkImage imageClone = ckImage.clone();
      expect(imageClone.videoFrame, isNotNull);

      final ByteData png = await imageClone.toByteData(format: ui.ImageByteFormat.png);
      expect(png, isNotNull);

      // The precise PNG encoding is browser-specific, but we can check the file
      // signature.
      expect(detectContentType(png.buffer.asUint8List()), 'image/png');
      testCollector.collectNow();
    // TODO(hterkelsen): Firefox and Safari do not currently support ImageDecoder.
    }, skip: isFirefox || isSafari);

    test('skiaInstantiateWebImageCodec loads an image from the network',
        () async {
      mockHttpFetchResponseFactory = (String url) async {
        return MockHttpFetchResponse(
          url: url,
          status: 200,
          payload: MockHttpFetchPayload(byteBuffer: kTransparentImage.buffer),
        );
      };

      final ui.Codec codec = await skiaInstantiateWebImageCodec(
          'http://image-server.com/picture.jpg', null);
      expect(codec.frameCount, 1);
      final ui.Image image = (await codec.getNextFrame()).image;
      expect(image.height, 1);
      expect(image.width, 1);
      testCollector.collectNow();
    });

    test('instantiateImageCodec respects target image size',
        () async {
      const List<List<int>> targetSizes = <List<int>>[
        <int>[1, 1],
        <int>[1, 2],
        <int>[2, 3],
        <int>[3, 4],
        <int>[4, 4],
        <int>[10, 20],
      ];

      for (final List<int> targetSize in targetSizes) {
        final int targetWidth = targetSize[0];
        final int targetHeight = targetSize[1];

        final ui.Codec codec = await ui.instantiateImageCodec(
          k4x4PngImage,
          targetWidth: targetWidth,
          targetHeight: targetHeight,
        );

        final ui.Image image = (await codec.getNextFrame()).image;
        expect(image.width, targetWidth);
        expect(image.height, targetHeight);
        image.dispose();
        codec.dispose();
      }

      testCollector.collectNow();
    });

    test('instantiateImageCodec with multi-frame image does not support targetWidth/targetHeight',
        () async {
        final ui.Codec codec = await ui.instantiateImageCodec(
          kAnimatedGif,
          targetWidth: 2,
          targetHeight: 3,
        );
        final ui.Image image = (await codec.getNextFrame()).image;

        expect(
        warnings,
        containsAllInOrder(
          <String>[
            'targetWidth and targetHeight for multi-frame images not supported',
          ],
        ),
      );

        // expect the re-size did not happen, kAnimatedGif is [1x1]
        expect(image.width, 1);
        expect(image.height, 1);
        image.dispose();
        codec.dispose();

        testCollector.collectNow();
    });

    test('skiaInstantiateWebImageCodec throws exception on request error',
        () async {
      mockHttpFetchResponseFactory = (String url) async {
        throw HttpFetchError(url, requestError: 'This is a test request error.');
      };

      try {
        await skiaInstantiateWebImageCodec('url-does-not-matter', null);
        fail('Expected to throw');
      } on ImageCodecException catch (exception) {
        expect(
          exception.toString(),
          'ImageCodecException: Failed to load network image.\n'
          'Image URL: url-does-not-matter\n'
          'Trying to load an image from another domain? Find answers at:\n'
          'https://flutter.dev/docs/development/platform-integration/web-images',
        );
      }
      testCollector.collectNow();
    });

    test('skiaInstantiateWebImageCodec throws exception on HTTP error',
        () async {
      try {
        await skiaInstantiateWebImageCodec('/does-not-exist.jpg', null);
        fail('Expected to throw');
      } on ImageCodecException catch (exception) {
        expect(
          exception.toString(),
          'ImageCodecException: Failed to load network image.\n'
          'Image URL: /does-not-exist.jpg\n'
          'Server response code: 404',
        );
      }
      testCollector.collectNow();
    });

    test('skiaInstantiateWebImageCodec includes URL in the error for malformed image',
        () async {
      mockHttpFetchResponseFactory = (String url) async {
        return MockHttpFetchResponse(
          url: url,
          status: 200,
          payload: MockHttpFetchPayload(byteBuffer: Uint8List(0).buffer),
        );
      };

      try {
        await skiaInstantiateWebImageCodec('http://image-server.com/picture.jpg', null);
        fail('Expected to throw');
      } on ImageCodecException catch (exception) {
        if (!browserSupportsImageDecoder) {
          expect(
            exception.toString(),
            'ImageCodecException: Failed to decode image data.\n'
            'Image source: http://image-server.com/picture.jpg',
          );
        } else {
          expect(
            exception.toString(),
            'ImageCodecException: Failed to detect image file format using the file header.\n'
            'File header was empty.\n'
            'Image source: http://image-server.com/picture.jpg',
          );
        }
      }
      testCollector.collectNow();
    });

    test('Reports error when failing to decode empty image data', () async {
      try {
        await ui.instantiateImageCodec(Uint8List(0));
        fail('Expected to throw');
      } on ImageCodecException catch (exception) {
        if (!browserSupportsImageDecoder) {
          expect(
            exception.toString(),
            'ImageCodecException: Failed to decode image data.\n'
            'Image source: encoded image bytes',
          );
        } else {
          expect(
            exception.toString(),
            'ImageCodecException: Failed to detect image file format using the file header.\n'
            'File header was empty.\n'
            'Image source: encoded image bytes',
          );
        }
      }
    });

    test('Reports error when failing to decode malformed image data', () async {
      try {
        await ui.instantiateImageCodec(Uint8List.fromList(<int>[
          0xFF, 0xD8, 0xFF, 0xDB, 0x00, 0x00, 0x00,
        ]));
        fail('Expected to throw');
      } on ImageCodecException catch (exception) {
        if (!browserSupportsImageDecoder) {
          expect(
            exception.toString(),
            'ImageCodecException: Failed to decode image data.\n'
            'Image source: encoded image bytes'
          );
        } else {
          expect(
            exception.toString(),
            // Browser error message is not checked as it can depend on the
            // browser engine and version.
            matches(RegExp(
              r"ImageCodecException: Failed to decode image using the browser's ImageDecoder API.\n"
              r'Image source: encoded image bytes\n'
              r'Original browser error: .+'
            ))
          );
        }
      }
    });

    test('Includes file header in the error message when fails to detect file type', () async {
      try {
        await ui.instantiateImageCodec(Uint8List.fromList(<int>[
          0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00,
        ]));
        fail('Expected to throw');
      } on ImageCodecException catch (exception) {
        if (!browserSupportsImageDecoder) {
          expect(
            exception.toString(),
            'ImageCodecException: Failed to decode image data.\n'
            'Image source: encoded image bytes'
          );
        } else {
          expect(
            exception.toString(),
            'ImageCodecException: Failed to detect image file format using the file header.\n'
            'File header was [0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x00].\n'
            'Image source: encoded image bytes'
          );
        }
      }
    });

    test('Provides readable error message when image type is unsupported', () async {
      addTearDown(() {
        debugContentTypeDetector = null;
      });
      debugContentTypeDetector = (_) {
        return 'unsupported/image-type';
      };
      try {
        await ui.instantiateImageCodec(Uint8List.fromList(<int>[
          0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00,
        ]));
        fail('Expected to throw');
      } on ImageCodecException catch (exception) {
        if (!browserSupportsImageDecoder) {
          expect(
            exception.toString(),
            'ImageCodecException: Failed to decode image data.\n'
            'Image source: encoded image bytes'
          );
        } else {
          expect(
            exception.toString(),
            "ImageCodecException: Image file format (unsupported/image-type) is not supported by this browser's ImageDecoder API.\n"
            'Image source: encoded image bytes'
          );
        }
      }
    });

    test('decodeImageFromPixels', () async {
      Future<ui.Image> testDecodeFromPixels(int width, int height) async {
        final Completer<ui.Image> completer = Completer<ui.Image>();
        ui.decodeImageFromPixels(
          Uint8List.fromList(List<int>.filled(width * height * 4, 0)),
          width,
          height,
          ui.PixelFormat.rgba8888,
          (ui.Image image) {
            completer.complete(image);
          },
        );
        return completer.future;
      }

      final ui.Image image1 = await testDecodeFromPixels(10, 20);
      expect(image1, isNotNull);
      expect(image1.width, 10);
      expect(image1.height, 20);

      final ui.Image image2 = await testDecodeFromPixels(40, 100);
      expect(image2, isNotNull);
      expect(image2.width, 40);
      expect(image2.height, 100);
    });

    test('decodeImageFromPixels respects target image size', () async {
      Future<ui.Image> testDecodeFromPixels(int width, int height, int targetWidth, int targetHeight) async {
        final Completer<ui.Image> completer = Completer<ui.Image>();
        ui.decodeImageFromPixels(
          Uint8List.fromList(List<int>.filled(width * height * 4, 0)),
          width,
          height,
          ui.PixelFormat.rgba8888,
          (ui.Image image) {
            completer.complete(image);
          },
          targetWidth: targetWidth,
          targetHeight: targetHeight,
        );
        return completer.future;
      }

      const List<List<int>> targetSizes = <List<int>>[
        <int>[1, 1],
        <int>[1, 2],
        <int>[2, 3],
        <int>[3, 4],
        <int>[4, 4],
        <int>[10, 20],
      ];

      for (final List<int> targetSize in targetSizes) {
        final int targetWidth = targetSize[0];
        final int targetHeight = targetSize[1];

        final ui.Image image = await testDecodeFromPixels(10, 20, targetWidth, targetHeight);

        expect(image.width, targetWidth);
        expect(image.height, targetHeight);
        image.dispose();
      }
    });

    test('decodeImageFromPixels upscale when allowUpscaling is false', () async {
      Future<ui.Image> testDecodeFromPixels(int width, int height) async {
        final Completer<ui.Image> completer = Completer<ui.Image>();
        ui.decodeImageFromPixels(
          Uint8List.fromList(List<int>.filled(width * height * 4, 0)),
          width,
          height,
          ui.PixelFormat.rgba8888,
          (ui.Image image) {
            completer.complete(image);
          },
          targetWidth: 20,
          targetHeight: 30,
          allowUpscaling: false
        );
        return completer.future;
      }
      expect(() async => testDecodeFromPixels(10, 20), throwsAssertionError);
    });

    test('Decode test images', () async {
      final HttpFetchResponse listingResponse = await httpFetch('/test_images/');
      final List<String> testFiles = (await listingResponse.json() as List<dynamic>).cast<String>();

      // Sanity-check the test file list. If suddenly test files are moved or
      // deleted, and the test server returns an empty list, or is missing some
      // important test files, we want to know.
      expect(testFiles, isNotEmpty);
      expect(testFiles, contains(matches(RegExp(r'.*\.jpg'))));
      expect(testFiles, contains(matches(RegExp(r'.*\.png'))));
      expect(testFiles, contains(matches(RegExp(r'.*\.gif'))));
      expect(testFiles, contains(matches(RegExp(r'.*\.webp'))));
      expect(testFiles, contains(matches(RegExp(r'.*\.bmp'))));

      for (final String testFile in testFiles) {
        final HttpFetchResponse imageResponse = await httpFetch('/test_images/$testFile');
        final Uint8List imageData = await imageResponse.asUint8List();
        final ui.Codec codec = await skiaInstantiateImageCodec(imageData);
        expect(codec.frameCount, greaterThan(0));
        expect(codec.repetitionCount, isNotNull);
        for (int i = 0; i < codec.frameCount; i++) {
          final ui.FrameInfo frame = await codec.getNextFrame();
          expect(frame.duration, isNotNull);
          expect(frame.image, isNotNull);
        }
        codec.dispose();
      }
    });

    // Reproduces https://skbug.com/12721
    test('decoded image can be read back from picture', () async {
      final HttpFetchResponse imageResponse = await httpFetch('/test_images/mandrill_128.png');
      final Uint8List imageData = await imageResponse.asUint8List();
      final ui.Codec codec = await skiaInstantiateImageCodec(imageData);
      final ui.FrameInfo frame = await codec.getNextFrame();
      final CkImage image = frame.image as CkImage;

      final CkImage snapshot;
      {
        final LayerSceneBuilder sb = LayerSceneBuilder();
        sb.pushOffset(10, 10);
        final CkPictureRecorder recorder = CkPictureRecorder();
        final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
        canvas.drawRect(
          const ui.Rect.fromLTRB(5, 5, 20, 20),
          CkPaint(),
        );
        canvas.drawImage(image, ui.Offset.zero, CkPaint());
        canvas.drawRect(
          const ui.Rect.fromLTRB(90, 90, 105, 105),
          CkPaint(),
        );
        sb.addPicture(ui.Offset.zero, recorder.endRecording());
        sb.pop();
        snapshot = await sb.build().toImage(150, 150) as CkImage;
      }

      {
        final LayerSceneBuilder sb = LayerSceneBuilder();
        final CkPictureRecorder recorder = CkPictureRecorder();
        final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
        canvas.drawImage(snapshot, ui.Offset.zero, CkPaint());
        sb.addPicture(ui.Offset.zero, recorder.endRecording());

        CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);
        await matchGoldenFile(
          'canvaskit_read_back_decoded_image_$mode.png',
          region: const ui.Rect.fromLTRB(0, 0, 150, 150),
        );
      }

      image.dispose();
      codec.dispose();
    });

    // This is a regression test for the issues with transferring textures from
    // one GL context to another, such as:
    //
    //  * https://github.com/flutter/flutter/issues/86809
    //  * https://github.com/flutter/flutter/issues/91881
    test('the same image can be rendered on difference surfaces', () async {
      ui.platformViewRegistry.registerViewFactory(
        'test-platform-view',
        (int viewId) => createDomHTMLDivElement()..id = 'view-0',
      );
      await createPlatformView(0, 'test-platform-view');

      final ui.Codec codec = await ui.instantiateImageCodec(k4x4PngImage);
      final CkImage image = (await codec.getNextFrame()).image as CkImage;

      final LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(4, 4);
      {
        final CkPictureRecorder recorder = CkPictureRecorder();
        final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
        canvas.save();
        canvas.scale(16, 16);
        canvas.drawImage(image, ui.Offset.zero, CkPaint());
        canvas.restore();
        canvas.drawParagraph(makeSimpleText('1'), const ui.Offset(4, 4));
        sb.addPicture(ui.Offset.zero, recorder.endRecording());
      }
      sb.addPlatformView(0, width: 100, height: 100);
      sb.pushOffset(20, 20);
      {
        final CkPictureRecorder recorder = CkPictureRecorder();
        final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
        canvas.save();
        canvas.scale(16, 16);
        canvas.drawImage(image, ui.Offset.zero, CkPaint());
        canvas.restore();
        canvas.drawParagraph(makeSimpleText('2'), const ui.Offset(2, 2));
        sb.addPicture(ui.Offset.zero, recorder.endRecording());
      }
      CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);
      await matchGoldenFile(
        'canvaskit_cross_gl_context_image_$mode.png',
        region: const ui.Rect.fromLTRB(0, 0, 100, 100),
      );

      await disposePlatformView(0);
    });

    test('toImageSync with texture-backed image', () async {
      final HttpFetchResponse imageResponse = await httpFetch('/test_images/mandrill_128.png');
      final Uint8List imageData = await imageResponse.asUint8List();
      final ui.Codec codec = await skiaInstantiateImageCodec(imageData);
      final ui.FrameInfo frame = await codec.getNextFrame();
      final CkImage mandrill = frame.image as CkImage;
      final ui.PictureRecorder recorder = ui.PictureRecorder();
      final ui.Canvas canvas = ui.Canvas(recorder);
      canvas.drawImageRect(
        mandrill,
        const ui.Rect.fromLTWH(0, 0, 128, 128),
        const ui.Rect.fromLTWH(0, 0, 128, 128),
        ui.Paint(),
      );
      final ui.Picture picture = recorder.endRecording();
      final ui.Image image = picture.toImageSync(50, 50);

      expect(image.width, 50);
      expect(image.height, 50);

      final ByteData? data = await image.toByteData();
      expect(data, isNotNull);
      expect(data!.lengthInBytes, 50 * 50 * 4);
      expect(data.buffer.asUint32List().any((int byte) => byte != 0), isTrue);

      final LayerSceneBuilder sb = LayerSceneBuilder();
      sb.pushOffset(0, 0);
      {
        final CkPictureRecorder recorder = CkPictureRecorder();
        final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
        canvas.save();
        canvas.drawImage(image as CkImage, ui.Offset.zero, CkPaint());
        canvas.restore();
        sb.addPicture(ui.Offset.zero, recorder.endRecording());
      }
      CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);
      await matchGoldenFile(
        'canvaskit_picture_texture_toimage.png',
        region: const ui.Rect.fromLTRB(0, 0, 128, 128),
      );
      mandrill.dispose();
      codec.dispose();
    });

    test('decoded image can be read back from picture', () async {
      final HttpFetchResponse imageResponse = await httpFetch('/test_images/mandrill_128.png');
      final Uint8List imageData = await imageResponse.asUint8List();
      final ui.Codec codec = await skiaInstantiateImageCodec(imageData);
      final ui.FrameInfo frame = await codec.getNextFrame();
      final CkImage image = frame.image as CkImage;

      final CkImage snapshot;
      {
        final LayerSceneBuilder sb = LayerSceneBuilder();
        sb.pushOffset(10, 10);
        final CkPictureRecorder recorder = CkPictureRecorder();
        final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
        canvas.drawRect(
          const ui.Rect.fromLTRB(5, 5, 20, 20),
          CkPaint(),
        );
        canvas.drawImage(image, ui.Offset.zero, CkPaint());
        canvas.drawRect(
          const ui.Rect.fromLTRB(90, 90, 105, 105),
          CkPaint(),
        );
        sb.addPicture(ui.Offset.zero, recorder.endRecording());
        sb.pop();
        snapshot = await sb.build().toImage(150, 150) as CkImage;
      }

      {
        final LayerSceneBuilder sb = LayerSceneBuilder();
        final CkPictureRecorder recorder = CkPictureRecorder();
        final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
        canvas.drawImage(snapshot, ui.Offset.zero, CkPaint());
        sb.addPicture(ui.Offset.zero, recorder.endRecording());

        CanvasKitRenderer.instance.rasterizer.draw(sb.build().layerTree);
        await matchGoldenFile(
          'canvaskit_read_back_decoded_image_$mode.png',
          region: const ui.Rect.fromLTRB(0, 0, 150, 150),
        );
      }

      image.dispose();
      codec.dispose();
    });

    test('can detect JPEG from just magic number', () async {
      expect(
        detectContentType(
          Uint8List.fromList(<int>[0xff, 0xd8, 0xff, 0xe2, 0x0c, 0x58, 0x49, 0x43, 0x43, 0x5f])),
        'image/jpeg');
    });
  }, timeout: const Timeout.factor(10)); // These tests can take a while. Allow for a longer timeout.
}

/// Tests specific to WASM codecs bundled with CanvasKit.
void _testCkAnimatedImage() {
  test('ImageDecoder toByteData(PNG)', () async {
    final CkAnimatedImage image = CkAnimatedImage.decodeFromBytes(kAnimatedGif, 'test');
    final ui.FrameInfo frame = await image.getNextFrame();
    final ByteData? png = await frame.image.toByteData(format: ui.ImageByteFormat.png);
    expect(png, isNotNull);

    // The precise PNG encoding is browser-specific, but we can check the file
    // signature.
    expect(detectContentType(png!.buffer.asUint8List()), 'image/png');
    testCollector.collectNow();
  });

  test('CkAnimatedImage toByteData(RGBA)', () async {
    final CkAnimatedImage image = CkAnimatedImage.decodeFromBytes(kAnimatedGif, 'test');
    const List<List<int>> expectedColors = <List<int>>[
      <int>[255, 0, 0, 255],
      <int>[0, 255, 0, 255],
      <int>[0, 0, 255, 255],
    ];
    for (int i = 0; i < image.frameCount; i++) {
      final ui.FrameInfo frame = await image.getNextFrame();
      final ByteData? rgba = await frame.image.toByteData();
      expect(rgba, isNotNull);
      expect(rgba!.buffer.asUint8List(), expectedColors[i]);
    }
    testCollector.collectNow();
  });
}

/// Tests specific to browser image codecs based functionality.
void _testCkBrowserImageDecoder() {
  assert(browserSupportsImageDecoder);

  test('ImageDecoder toByteData(PNG)', () async {
    final CkBrowserImageDecoder image = await CkBrowserImageDecoder.create(
      data: kAnimatedGif,
      debugSource: 'test',
    );
    final ui.FrameInfo frame = await image.getNextFrame();
    final ByteData? png = await frame.image.toByteData(format: ui.ImageByteFormat.png);
    expect(png, isNotNull);

    // The precise PNG encoding is browser-specific, but we can check the file
    // signature.
    expect(detectContentType(png!.buffer.asUint8List()), 'image/png');
    testCollector.collectNow();
  });

  test('ImageDecoder toByteData(RGBA)', () async {
    final CkBrowserImageDecoder image = await CkBrowserImageDecoder.create(
      data: kAnimatedGif,
      debugSource: 'test',
    );
    const List<List<int>> expectedColors = <List<int>>[
      <int>[255, 0, 0, 255],
      <int>[0, 255, 0, 255],
      <int>[0, 0, 255, 255],
    ];
    for (int i = 0; i < image.frameCount; i++) {
      final ui.FrameInfo frame = await image.getNextFrame();
      final ByteData? rgba = await frame.image.toByteData();
      expect(rgba, isNotNull);
      expect(rgba!.buffer.asUint8List(), expectedColors[i]);
    }
    testCollector.collectNow();
    // TODO(jacksongardner): enable on wasm
    // see https://github.com/flutter/flutter/issues/118334
  }, skip: isWasm);

  test('ImageDecoder expires after inactivity', () async {
    const Duration testExpireDuration = Duration(milliseconds: 100);
    debugOverrideWebDecoderExpireDuration(testExpireDuration);

    final CkBrowserImageDecoder image = await CkBrowserImageDecoder.create(
      data: kAnimatedGif,
      debugSource: 'test',
    );

    // ImageDecoder is initialized eagerly to populate `frameCount` and
    // `repetitionCount`.
    final ImageDecoder? decoder1 = image.debugCachedWebDecoder;
    expect(decoder1, isNotNull);
    expect(image.frameCount, 3);
    expect(image.repetitionCount, -1);

    // A frame can be decoded right away.
    final ui.FrameInfo frame1 = await image.getNextFrame();
    await expectFrameData(frame1, <int>[255, 0, 0, 255]);
    expect(frame1, isNotNull);

    // The cached decoder should not yet expire.
    await Future<void>.delayed(testExpireDuration ~/ 2);
    expect(image.debugCachedWebDecoder, same(decoder1));

    // Now it expires.
    await Future<void>.delayed(testExpireDuration);
    expect(image.debugCachedWebDecoder, isNull);

    // A new decoder should be created upon the next frame request.
    final ui.FrameInfo frame2 = await image.getNextFrame();

    // Check that the cached decoder is indeed new.
    final ImageDecoder? decoder2 = image.debugCachedWebDecoder;
    expect(decoder2, isNot(same(decoder1)));
    await expectFrameData(frame2, <int>[0, 255, 0, 255]);

    // Check that the new decoder remembers the last frame index.
    final ui.FrameInfo frame3 = await image.getNextFrame();
    await expectFrameData(frame3, <int>[0, 0, 255, 255]);

    testCollector.collectNow();
    debugRestoreWebDecoderExpireDuration();
    // TODO(jacksongardner): enable on wasm
    // see https://github.com/flutter/flutter/issues/118334
  }, skip: isWasm);
}

Future<void> expectFrameData(ui.FrameInfo frame, List<int> data) async {
  final ByteData frameData = (await frame.image.toByteData())!;
  expect(frameData.buffer.asUint8List(), Uint8List.fromList(data));
}
