blob: 1fe8ac5eaebbe3e93387220d7a58f8ed8fdb1e29 [file] [log] [blame]
<!DOCTYPE HTML>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
// No matter what is the color space and pixel format of the color managed
// canvas, toBlob() and toDataURL() always create the blob in sRGB color
// space, and respect the legacy behavior by not including any color space
// information in the blob/data url.
var opaqueReferencePxiels, transparentReferencePixels;
function testPixels(actualPixels, refPixels, testScenario)
{
// Narrowing down the source of expected error:
// - Alpha values should always match.
// - Color components should be acceptably close.
if (testScenario.canvasColorParam.pixelFormat == 'uint8') {
let tolerance_color = 4;
for (let i = 0; i < actualPixels.length; i++) {
// Alpha channel
if (i % 4 == 3)
assert_equals(actualPixels[i], refPixels[i]);
else
assert_approx_equals(actualPixels[i], refPixels[i], tolerance_color);
}
} else {
// For half float backed canvas, we expect the error < 0.01.
let tolerance_color = 0.01;
for (let i = 0; i < actualPixels.length; i++) {
// Alpha channel
if (i % 4 == 3)
assert_equals(actualPixels[i], refPixels[i]);
else
assert_approx_equals(actualPixels[i], refPixels[i], tolerance_color);
}
}
}
function createCanvas(testScenario)
{
var canvas = document.createElement("canvas");
canvas.width = 2;
canvas.height = 2;
return canvas;
}
function generateFillStyle(red, green, blue, alpha) {
return "rgba(" + red + "," + green + "," + blue + "," + alpha + ")";
}
function drawPatternOnCanvsa(ctx, alpha, compositeOverBlack) {
if (compositeOverBlack) {
ctx.fillStyle = generateFillStyle(0, 0, 0, 1);
ctx.fillRect(0, 0, 2, 2);
}
ctx.fillStyle = generateFillStyle(155, 27, 27, alpha);
ctx.fillRect(0, 0, 1, 1);
ctx.fillStyle = generateFillStyle(27, 155, 27, alpha);
ctx.fillRect(1, 0, 1, 1);
ctx.fillStyle = generateFillStyle(27, 27, 155, alpha);
ctx.fillRect(0, 1, 1, 1);
ctx.fillStyle = generateFillStyle(27, 27, 27, alpha);
ctx.fillRect(1, 1, 1, 1);
}
function testScenarioToString(testScenario) {
var str = "mimeType: " + testScenario.encodeOptions.type +
", blobPixelFormat: " + testScenario.encodeOptions.pixelFormat +
", source color space: " + testScenario.canvasColorParam.colorSpace +
", pixel format: " + testScenario.canvasColorParam.pixelFormat +
", alpha: " + testScenario.alpha;
return str;
}
function runConvertToBlobTest(testScenario) {
var srcCanvas = createCanvas(testScenario);
var ctx = srcCanvas.getContext('2d', testScenario.canvasColorParam);
var compositeOverBlack = (testScenario.encodeOptions.type == "image/jpeg");
drawPatternOnCanvsa(ctx, testScenario.alpha, compositeOverBlack);
var refPixels = ctx.getImageData(0, 0, 2, 2).dataUnion;
var t = async_test("Test canvas convertToBlob(): " +
testScenarioToString(testScenario));
var image = new Image();
image.onload = t.step_func_done(function() {
var dstCanvas = createCanvas(testScenario);
var dstCtx = dstCanvas.getContext('2d', testScenario.canvasColorParam);
dstCtx.drawImage(image, 0, 0);
var actualPixels = dstCtx.getImageData(0, 0, 2, 2).dataUnion;
testPixels(actualPixels, refPixels, testScenario);
});
srcCanvas.convertToBlob(testScenario.encodeOptions).then(
t.step_func(function(blob) {
var urlCreator = window.URL || window.webkitURL;
image.src = urlCreator.createObjectURL(blob);
}),
t.step_func_done(function(e) {
assert_false("convertToBlob failed.");
})
);
}
function runAllTests() {
var mimeTypes = ['image/png', 'image/jpeg', 'image/webp'];
var blobPixelFormats = ['uint8', 'uint16'];
var encodeOptionsSet = [];
for (var i = 0; i < mimeTypes.length; i++)
for (var k = 0; k < blobPixelFormats.length; k++) {
var encodeOptions = {};
encodeOptions.quality = 1;
encodeOptions.type = mimeTypes[i];
encodeOptions.pixelFormat = blobPixelFormats[k];
encodeOptionsSet.push(encodeOptions);
}
var canvasColorParams = [
{colorSpace: 'srgb', pixelFormat: 'uint8'},
{colorSpace: 'srgb', pixelFormat: 'float16'},
];
var alphaValues = [0.5, 1];
// The *correct* way to test convertToBlob() is to directly examine the
// image file for the expected color space and pixels. Since this is not
// easy to do in javascript, we use a round-trip test here and leave the
// more thorough testing to unit tests.
var testScenarioSet = [];
for (var i = 0; i < encodeOptionsSet.length; i++)
for (var j = 0; j < canvasColorParams.length; j++)
for (var k = 0; k < alphaValues.length; k++) {
var testScenario = {};
testScenario.encodeOptions = encodeOptionsSet[i];
testScenario.canvasColorParam = canvasColorParams[j];
testScenario.alpha = alphaValues[k];
testScenarioSet.push(testScenario);
}
for (var i = 0; i < testScenarioSet.length; i++)
runConvertToBlobTest(testScenarioSet[i]);
}
test(function() {
runAllTests();
}, "Overall test");
</script>