Optimized genericComposeSMask

Declaring the composition and backgdrop functions outside of genericComposeSMask
is more efficient.
This commit is contained in:
p01 2014-06-02 14:54:40 +02:00
parent 412febe4a4
commit e0bf7e2151

View File

@ -601,49 +601,54 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
}
}
function composeSMaskBackdrop(bytes, r0, g0, b0) {
var length = bytes.length;
for (var i = 3; i < length; i += 4) {
var alpha = bytes[i];
if (alpha === 0) {
bytes[i - 3] = r0;
bytes[i - 2] = g0;
bytes[i - 1] = b0;
} else if (alpha < 255) {
var alpha_ = 255 - alpha;
bytes[i - 3] = (bytes[i - 3] * alpha + r0 * alpha_) >> 8;
bytes[i - 2] = (bytes[i - 2] * alpha + g0 * alpha_) >> 8;
bytes[i - 1] = (bytes[i - 1] * alpha + b0 * alpha_) >> 8;
}
}
}
function composeSMaskAlpha(maskData, layerData) {
var length = maskData.length;
var scale = 1 / 255;
for (var i = 3; i < length; i += 4) {
var alpha = maskData[i];
layerData[i] = (layerData[i] * alpha * scale) | 0;
}
}
function composeSMaskLuminosity(maskData, layerData) {
var length = maskData.length;
for (var i = 3; i < length; i += 4) {
var y = ((maskData[i - 3] * 77) + // * 0.3 / 255 * 0x10000
(maskData[i - 2] * 152) + // * 0.59 ....
(maskData[i - 1] * 28)) | 0; // * 0.11 ....
layerData[i] = (layerData[i] * y) >> 16;
}
}
function genericComposeSMask(maskCtx, layerCtx, width, height,
subtype, backdrop) {
var addBackdropFn;
if (backdrop) {
addBackdropFn = function (r0, g0, b0, bytes) {
var length = bytes.length;
for (var i = 3; i < length; i += 4) {
var alpha = bytes[i] / 255;
if (alpha === 0) {
bytes[i - 3] = r0;
bytes[i - 2] = g0;
bytes[i - 1] = b0;
} else if (alpha < 1) {
var alpha_ = 1 - alpha;
bytes[i - 3] = (bytes[i - 3] * alpha + r0 * alpha_) | 0;
bytes[i - 2] = (bytes[i - 2] * alpha + g0 * alpha_) | 0;
bytes[i - 1] = (bytes[i - 1] * alpha + b0 * alpha_) | 0;
}
}
}.bind(null, backdrop[0], backdrop[1], backdrop[2]);
} else {
addBackdropFn = function () {};
}
var hasBackdrop = backdrop !== undefined;
var r0 = hasBackdrop ? backdrop[0] : 0;
var g0 = hasBackdrop ? backdrop[1] : 0;
var b0 = hasBackdrop ? backdrop[2] : 0;
var composeFn;
if (subtype === 'Luminosity') {
composeFn = function (maskDataBytes, layerDataBytes) {
var length = maskDataBytes.length;
for (var i = 3; i < length; i += 4) {
var y = ((maskDataBytes[i - 3] * 77) + // * 0.3 / 255 * 0x10000
(maskDataBytes[i - 2] * 152) + // * 0.59 ....
(maskDataBytes[i - 1] * 28)) | 0; // * 0.11 ....
layerDataBytes[i] = (layerDataBytes[i] * y) >> 16;
}
};
composeFn = composeSMaskLuminosity;
} else {
composeFn = function (maskDataBytes, layerDataBytes) {
var length = maskDataBytes.length;
for (var i = 3; i < length; i += 4) {
var alpha = maskDataBytes[i];
layerDataBytes[i] = (layerDataBytes[i] * alpha / 255) | 0;
}
};
composeFn = composeSMaskAlpha;
}
// processing image in chunks to save memory
@ -654,7 +659,9 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
var maskData = maskCtx.getImageData(0, row, width, chunkHeight);
var layerData = layerCtx.getImageData(0, row, width, chunkHeight);
addBackdropFn(maskData.data);
if (hasBackdrop) {
composeSMaskBackdrop(maskData.data, r0, g0, b0);
}
composeFn(maskData.data, layerData.data);
maskCtx.putImageData(layerData, 0, row);