<!DOCTYPE HTML>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>

// This test examines the color managed ImageBitmapRenderingContext.
//  - We first draw on 2D canvas with different color space and alpha
//    properties.
//  - Next, the canvas is used as a source image to create an ImageBitmap.
//    Different colorSpaceConversion values are tested when creating the
//    intermediate ImageBitmap object.
//  - Next, ImageBitmap is transferred to an ImageBitmapRenderingContext.
//  - Since we cannot read back pixels from ImageBitmapRenderingContext, we
//    draw it to another 2D canvas and read back the pixels.
//  - Finally, we compare the pixels read from the first 2D canvas with those
//    read from the final 2D canvas. We expect them to match with some
//    tolerance.

function testPixels(actualPixels, expectedPixels, testScenario)
{
    var tolerance = 0;
    if (testScenario.pixelFormat == "float16")
        tolerance = 0.01;

    assert_array_approx_equals(actualPixels, expectedPixels, tolerance);
}

function generateFillStyle(red, green, blue, alpha) {
    return "rgba(" + red + "," + green + "," + blue + "," + alpha + ")";
}

function generateExpectedResult(testScenario, canvas)
{
    var ctx = canvas.getContext('2d', {colorSpace: testScenario.colorSpace,
                                       pixelFormat: testScenario.pixelFormat});
    ctx.fillStyle = generateFillStyle(155, 27, 27, testScenario.alpha);
    ctx.fillRect(0, 0, 1, 1);
    ctx.fillStyle = generateFillStyle(27, 155, 27, testScenario.alpha);
    ctx.fillRect(1, 0, 1, 1);
    ctx.fillStyle = generateFillStyle(27, 27, 155, testScenario.alpha);
    ctx.fillRect(0, 1, 1, 1);
    ctx.fillStyle = generateFillStyle(27, 27, 27, testScenario.alpha);
    ctx.fillRect(1, 1, 1, 1);
    return ctx.getImageData(0, 0, 2, 2).dataUnion;
}

function generateTestName(testScenario) {
    var str = "Testing ImageBitmapRenderingContext:" +
              " Source color space: " + testScenario.colorSpace +
              ", pixel format: " + testScenario.pixelFormat +
              ", alpha: " + testScenario.alpha +
              ", intermediate color space: " +
              testScenario.colorSpaceConversion;
    return str;
}

function runTransferFromImageBitmapTest(testScenario) {
    var canvas = document.createElement("canvas");
    canvas.width = 2;
    canvas.height = 2;
    var expectedPixels = generateExpectedResult(testScenario, canvas);

    promise_test(function() {
        var options = {colorSpaceConversion: testScenario.colorSpaceConversion};
        var promise = createImageBitmap(canvas, options);
        return Promise.all([promise]).then(([imagebitmap]) => {
            var dstCanvas = document.createElement("canvas");
            dstCanvas.width = 2;
            dstCanvas.height = 2;
            var dstCtx = dstCanvas.getContext('bitmaprenderer');
            dstCtx.transferFromImageBitmap(imagebitmap);

            // ImageBitmapRenderingContext does not have ImageData, so we draw
            // it on another canvas and read back the data.
            var finalCanvas = document.createElement("canvas");
            finalCanvas.width = 2;
            finalCanvas.height = 2;
            var ctx = finalCanvas.getContext('2d',
                {colorSpace: testScenario.colorSpace,
                 pixelFormat: testScenario.pixelFormat});
            ctx.drawImage(dstCanvas, 0, 0);
            var actualPixels = ctx.getImageData(0, 0, 2, 2).dataUnion;
            testPixels(actualPixels, expectedPixels, testScenario);
        });
       }, generateTestName(testScenario));
}


function runAllTests() {
    var colorSpaces = [
        {colorSpace: 'srgb', pixelFormat: 'uint8'},
        {colorSpace: 'srgb', pixelFormat: 'float16'},
        ];
    var alphaValues = [0.5, 1];
    var colorSpaceConversions = ['none', 'default'];

    var testScenarios = [];
    for (var i = 0; i < colorSpaces.length; i++)
        for (var j = 0; j < alphaValues.length; j++)
            for (var k = 0; k < colorSpaceConversions.length; k++) {
                var testScenario = {};
                testScenario.colorSpace = colorSpaces[i].colorSpace;
                testScenario.pixelFormat = colorSpaces[i].pixelFormat;
                testScenario.alpha = alphaValues[j];
                testScenario.colorSpaceConversion = colorSpaceConversions[k];
                testScenarios.push(testScenario);
            }

    for (var i = 0; i < testScenarios.length; i++)
        runTransferFromImageBitmapTest(testScenarios[i]);
}

runAllTests();

</script>