687c9a8710
- write some uint32 instead of uint8 to avoid the check before clamping; - unroll the loop to write data in the buffer - but keep a loop for the last element of a line: it likely doesn't hurt that much since it's executed only for one time for each line; - I tested on a macbook with an Apple chip, and on Firefox nightly the new code is almost 3.5x faster than before (~1.8x with Chrome).
59 lines
2.0 KiB
JavaScript
59 lines
2.0 KiB
JavaScript
/* Copyright 2022 Mozilla Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
import { FeatureTest } from "./util.js";
|
|
|
|
function applyMaskImageData({
|
|
src,
|
|
srcPos = 0,
|
|
dest,
|
|
destPos = 0,
|
|
width,
|
|
height,
|
|
inverseDecode = false,
|
|
}) {
|
|
const opaque = FeatureTest.isLittleEndian ? 0xff000000 : 0x000000ff;
|
|
const [zeroMapping, oneMapping] = !inverseDecode ? [opaque, 0] : [0, opaque];
|
|
const widthInSource = width >> 3;
|
|
const widthRemainder = width & 7;
|
|
const srcLength = src.length;
|
|
dest = new Uint32Array(dest.buffer);
|
|
|
|
for (let i = 0; i < height; i++) {
|
|
for (const max = srcPos + widthInSource; srcPos < max; srcPos++) {
|
|
const elem = srcPos < srcLength ? src[srcPos] : 255;
|
|
dest[destPos++] = elem & 0b10000000 ? oneMapping : zeroMapping;
|
|
dest[destPos++] = elem & 0b1000000 ? oneMapping : zeroMapping;
|
|
dest[destPos++] = elem & 0b100000 ? oneMapping : zeroMapping;
|
|
dest[destPos++] = elem & 0b10000 ? oneMapping : zeroMapping;
|
|
dest[destPos++] = elem & 0b1000 ? oneMapping : zeroMapping;
|
|
dest[destPos++] = elem & 0b100 ? oneMapping : zeroMapping;
|
|
dest[destPos++] = elem & 0b10 ? oneMapping : zeroMapping;
|
|
dest[destPos++] = elem & 0b1 ? oneMapping : zeroMapping;
|
|
}
|
|
if (widthRemainder === 0) {
|
|
continue;
|
|
}
|
|
const elem = srcPos < srcLength ? src[srcPos++] : 255;
|
|
for (let j = 0; j < widthRemainder; j++) {
|
|
dest[destPos++] = elem & (1 << (7 - j)) ? oneMapping : zeroMapping;
|
|
}
|
|
}
|
|
|
|
return { srcPos, destPos };
|
|
}
|
|
|
|
export { applyMaskImageData };
|