| <!DOCTYPE HTML> |
| <script src="../../../resources/testharness.js"></script> |
| <script src="../../../resources/testharnessreport.js"></script> |
| <script> |
| |
| // This test is mostly a conformance test which ensures the new 16 bit PNG |
| // decoding capability of Blink PNGImageDecoder conforms to the regular 8 bit |
| // PNG decoding code path. Since we cannot read the decoded image pixels |
| // directly in JS, proper unit tests are added to CanvasRenderingContext2DTest |
| // to verify correct color transformation while drawing. |
| // In this layout test reference pixels are generated by drawing 8 bit sRGB on |
| // wide gamut canvas, and test pixels are generated by drawing 16 bit PNG in |
| // different color spaces on the wide gamut canvas. e-sRGB is intentionally |
| // omitted since it results in < 0, > 1 color component values and does not |
| // match the source pixels. e-sRGB 16 bit PNGs are still covered in unit tests. |
| |
| var testImagesPath = "../../../images/resources/png-16bit/"; |
| |
| // Source of pixel comparison error in these tests: |
| // - color conversion from different color profiles (sRGB, Adobe RGB, Display P3, |
| // ProPhoto and Rec 2020) to target canvas color space (sRGB, e-sRGB, linear RGB, |
| // linear P3, linear Rec 2020). |
| // - e-sRGB source image is not tested here since the color profile attached to |
| // png image by Photoshop is different from what is expected by Skia. Hence, |
| // the pixel results do not match. Still, e-sRGB sources are thoroughly tested |
| // in unit tests. |
| // - comparing the result of drawing 8 bit and 16 bit PNGs with each other. |
| var defaultColorConversionTolerance = 8; |
| var wideGamutColorConversionTolerance = 0.05; |
| |
| function runTest(testScenario) { |
| var _8bitImageSrc = testImagesPath + testScenario._8bitImagePath; |
| var _16bitImageSrc = testImagesPath + testScenario._16bitImagePath; |
| var tolerance = defaultColorConversionTolerance; |
| if (testScenario.canvasColorParams.pixelFormat == 'float16') |
| tolerance = wideGamutColorConversionTolerance; |
| |
| var _8bitImage = new Image(); |
| var _16bitImage = new Image(); |
| var t_image = async_test(testScenarioToString(testScenario)); |
| _8bitImage.onload = t_image.step_func(function() { |
| _16bitImage.onload = function() { |
| var refCanvas = document.createElement("canvas"); |
| refCanvas.width = refCanvas.height = 40000; |
| var refCtx = refCanvas.getContext( |
| '2d', testScenario.canvasColorParams); |
| refCtx.drawImage(_8bitImage, 0, 0); |
| var refImageData = refCtx.getImageData(0, 0, 2, 2); |
| var refPixels = refImageData.data; |
| |
| var testCanvas = document.createElement("canvas"); |
| testCanvas.width = testCanvas.height = 40000; |
| var testCtx = testCanvas.getContext( |
| '2d', testScenario.canvasColorParams); |
| testCtx.drawImage(_16bitImage, 0, 0); |
| var testImageData = testCtx.getImageData(0, 0, 2, 2); |
| var testPixels = testImageData.data; |
| |
| assert_array_approx_equals(refPixels, testPixels, tolerance); |
| |
| t_image.done(); |
| }; |
| _16bitImage.src = _16bitImageSrc; |
| }); |
| _8bitImage.src = _8bitImageSrc; |
| } |
| |
| function runAllTests() { |
| var pngColorSpaces = [ |
| "_sRGB", |
| "_AdobeRGB", |
| "_DisplayP3", |
| "_ProPhoto", |
| "_Rec2020", |
| ]; |
| var pngTransparencyStatus = [ |
| "_opaque", |
| "_transparent", |
| ]; |
| var pngInterlaceStatus = [ |
| "", // non-interlaced |
| "_interlaced", |
| ]; |
| |
| |
| var _8bitPngPrefix = "2x2_8bit"; |
| var _16bitPngPrefix = "2x2_16bit"; |
| |
| var canvasColorParams = [ |
| // When canvas is not half float backed, 16 bit PNGs will be decoded as |
| // 8 bits PNGs (libpng strips 16 bits to 8 bits). |
| {colorSpace: 'srgb', pixelFormat: 'uint8'}, |
| |
| // For half float backed canvases, 16 bit PNGs are decoded as 16 bits, |
| // and then color converted to the canvas color space and color types. |
| // We expect the new 16 bit decoding capability to be compatible with |
| // the regular 8 bits decoding code path. |
| {colorSpace: 'srgb', pixelFormat: 'float16'}, |
| {colorSpace: 'rec2020', pixelFormat: 'float16'}, |
| {colorSpace: 'display-p3', pixelFormat: 'float16'} |
| ]; |
| |
| var testScenarioSet = []; |
| var id = 1; |
| for (var i = 0; i < canvasColorParams.length; i++) { |
| for (var j = 0; j < pngColorSpaces.length; j++) { |
| for (var k = 0; k < pngTransparencyStatus.length; k++) { |
| for (var m = 0; m < pngInterlaceStatus.length; m++) { |
| var testScenario = {}; |
| testScenario.canvasColorParams = canvasColorParams[i]; |
| testScenario._8bitImagePath = _8bitPngPrefix + |
| pngColorSpaces[j] + pngTransparencyStatus[k] + ".png"; |
| testScenario._16bitImagePath = _16bitPngPrefix + |
| pngInterlaceStatus[m] + pngColorSpaces[j] + |
| pngTransparencyStatus[k] + ".png"; |
| testScenarioSet.push(testScenario); |
| } |
| } |
| } |
| } |
| |
| for (var i = 0; i < testScenarioSet.length; i++) |
| runTest(testScenarioSet[i]); |
| } |
| |
| function testScenarioToString(testScenario) { |
| var str = "Canvas color params: " + |
| testScenario.canvasColorParams.colorSpace + ", " + |
| testScenario.canvasColorParams.pixelFormat + ". Testing " + |
| testScenario._8bitImagePath + " vs " + testScenario._16bitImagePath; |
| return str; |
| } |
| |
| runAllTests(); |
| |
| </script> |