| <!DOCTYPE html> |
| <body> |
| <script src="../../../resources/testharness.js"></script> |
| <script src="../../../resources/testharnessreport.js"></script> |
| <script> |
| test(drawThenGetImageData, |
| 'tests creating ImageData using several methods, calling putImageData, and reading back the color.'); |
| |
| function populate_array(data, data_color_space, data_storage_format) { |
| for (var i = 0; i < data.length / 4; ++i) { |
| var color_srgb_f32 = [50/255., 100/255., 150/255., 1.0]; |
| var color_p3_f32 = [0.24304, 0.38818, 0.57227, 1.0]; |
| var color_rec2020_f32 = [0.34106, 0.41553, 0.59180, 1.0]; |
| |
| if (data_color_space == 'srgb') |
| data_color = color_srgb_f32; |
| else if (data_color_space == 'display-p3') |
| data_color = color_p3_f32; |
| else if (data_color_space == 'rec2020') |
| data_color = color_rec2020_f32; |
| |
| var multiplier = 1; |
| if (data_storage_format == 'uint8') |
| multiplier = 255; |
| if (data_storage_format == 'uint16') |
| multiplier = 65535; |
| if (data_storage_format == 'float32') |
| multiplier = 1.0; |
| |
| data[4*i + 0] = multiplier * data_color[0]; |
| data[4*i + 1] = multiplier * data_color[1]; |
| data[4*i + 2] = multiplier * data_color[2]; |
| data[4*i + 3] = multiplier * data_color[3]; |
| } |
| } |
| |
| function run_test(canvas_color_space, canvas_pixel_format, data_color_space, data_storage_format) { |
| var canvas = document.createElement('canvas'); |
| canvas.width = 20; |
| canvas.height = 16; |
| var ctx = canvas.getContext('2d', {colorSpace:canvas_color_space, pixelFormat:canvas_pixel_format}); |
| |
| const num_subtests = 5; |
| const data_width = Math.floor(canvas.width / num_subtests); |
| const data_height = canvas.height; |
| subtest_name = ''; |
| |
| // Create an ImageData using createImageData and populate its data array. |
| { |
| var data_to_put = ctx.createImageData(data_width, data_height, {colorSpace:data_color_space, storageFormat:data_storage_format}); |
| populate_array(data_to_put.data, data_color_space, data_storage_format); |
| ctx.putImageData(data_to_put, 0 * data_width, 0); |
| subtest_name = 'createImageData'; |
| } |
| |
| // Create an ImageData using a constructor and populate its data array. |
| { |
| var data_to_put = new ImageData(data_width, data_height, {colorSpace:data_color_space, storageFormat:data_storage_format}); |
| populate_array(data_to_put.data, data_color_space, data_storage_format); |
| ctx.putImageData(data_to_put, 1 * data_width, 0); |
| subtest_name = 'constructor with width,height'; |
| } |
| |
| // Create and populate an array, then use that array to create an ImageData. |
| { |
| var length = 4 * data_width * data_height; |
| var data = []; |
| if (data_storage_format == 'uint8') |
| data = new Uint8ClampedArray(length); |
| if (data_storage_format == 'uint16') |
| data = new Uint16Array(length); |
| if (data_storage_format == 'float32') |
| data = new Float32Array(length); |
| populate_array(data, data_color_space, data_storage_format); |
| |
| var data_to_put = new ImageData(data, data_width, data_height, {colorSpace:data_color_space, storageFormat:data_storage_format}); |
| ctx.putImageData(data_to_put, 2 * data_width, 0); |
| subtest_name = 'constructor with data,width,height,settings'; |
| } |
| |
| // Create and populate an array, then use that array to create an ImageData |
| // without specifying the height. Note that this will also not specify the |
| // ImageDataSettings, so the color space will implicitly be sRGB. |
| { |
| var length = 4 * data_width * data_height; |
| var data = []; |
| if (data_storage_format == 'uint8') |
| data = new Uint8ClampedArray(length); |
| if (data_storage_format == 'uint16') |
| data = new Uint16Array(length); |
| if (data_storage_format == 'float32') |
| data = new Float32Array(length); |
| populate_array(data, 'srgb', data_storage_format); |
| |
| var data_to_put = new ImageData(data, data_width); |
| ctx.putImageData(data_to_put, 3 * data_width, 0); |
| subtest_name = 'constructor with data,width'; |
| } |
| |
| // Create and populate an array, then use that array to create an ImageData |
| // specifying the height but not ImageDataSettings. Note that this will also |
| // not specify the ImageDataSettings, so the color space will implicitly be |
| // sRGB. |
| { |
| var length = 4 * data_width * data_height; |
| var data = []; |
| if (data_storage_format == 'uint8') |
| data = new Uint8ClampedArray(length); |
| if (data_storage_format == 'uint16') |
| data = new Uint16Array(length); |
| if (data_storage_format == 'float32') |
| data = new Float32Array(length); |
| populate_array(data, 'srgb', data_storage_format); |
| |
| var data_to_put = new ImageData(data, data_width, data_height); |
| ctx.putImageData(data_to_put, 4 * data_width, 0); |
| subtest_name = 'constructor with data,width'; |
| } |
| |
| // Read back as 8-bit sRGB. |
| for (var j = 0; j < num_subtests; ++j) { |
| var data_from_get = ctx.getImageData(data_width * (j + 0.5), data_height / 2, 1, 1); |
| var passed = true; |
| var pixel_expected = [50, 100, 150, 255]; |
| var pixel_actual = data_from_get.data; |
| for (var i = 0; i < 4; ++i) { |
| var epsilon = 2; |
| if (Math.abs(pixel_actual[i] - pixel_expected[i]) > epsilon) |
| passed = false; |
| } |
| if (!passed) { |
| console.log('Failure! ' + subtest_name); |
| console.log(' Canvas: ' + canvas_color_space + ',' + canvas_pixel_format); |
| console.log(' ImageData: ' + data_color_space + ',' + data_storage_format); |
| console.log(' Expected: ' + pixel_expected); |
| console.log(' Actual: ' + [pixel_actual[0], pixel_actual[1], pixel_actual[2], pixel_actual[3]]); |
| console.log(' Epsilon: ' + epsilon); |
| } |
| } |
| |
| return passed; |
| } |
| |
| function drawThenGetImageData() { |
| color_spaces = ['srgb', 'display-p3', 'rec2020']; |
| canvas_pixel_formats = ['uint8', 'float16']; |
| image_data_pixel_formats = ['uint8', 'uint16', 'float32']; |
| var passed = true; |
| for (var i = 0; i < 3; ++i) { |
| for (var j = 0; j < 2; ++j) { |
| for (var k = 0; k < 3; ++k) { |
| for (var l = 0; l < 3; ++l) { |
| if (!run_test(color_spaces[i], |
| canvas_pixel_formats[j], |
| color_spaces[k], |
| image_data_pixel_formats[l])) { |
| passed = false; |
| } |
| } |
| } |
| } |
| } |
| assert_true(passed); |
| } |
| </script> |
| </body> |