blob: b4c144b9bb492031aa3d56c9a3e08782ff5e415d [file] [log] [blame]
<!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>