forked from external-repos/squoosh
Compare commits
63 Commits
v1.3.1
...
assemblysc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41f085438b | ||
|
|
fdbc0932e4 | ||
|
|
2412e925ba | ||
|
|
a676e1a2e9 | ||
|
|
a8265d5350 | ||
|
|
8f5c03e05b | ||
|
|
3a0062276d | ||
|
|
1993cf3f6c | ||
|
|
c97aac31c6 | ||
|
|
507921cbe8 | ||
|
|
887db675c8 | ||
|
|
3917618e4e | ||
|
|
3c42d2e6a4 | ||
|
|
db8777b7f7 | ||
|
|
18c2cddee2 | ||
|
|
3ff9d3a1fa | ||
|
|
6503667c78 | ||
|
|
0fa95f84d4 | ||
|
|
cf91a90270 | ||
|
|
690052f989 | ||
|
|
b3e935f7e4 | ||
|
|
17314ebd29 | ||
|
|
adc437cd51 | ||
|
|
0e97b74510 | ||
|
|
9ffb475cac | ||
|
|
faa2b030c5 | ||
|
|
e3b3b10e2a | ||
|
|
b569cf268c | ||
|
|
b154b77556 | ||
|
|
84c0f30a7c | ||
|
|
16463ff76d | ||
|
|
8314e9e24b | ||
|
|
a33c557818 | ||
|
|
6fbdc65ad0 | ||
|
|
9c9b6c4711 | ||
|
|
46278d04c3 | ||
|
|
c1c16508b5 | ||
|
|
ed1b983711 | ||
|
|
ec23e28eda | ||
|
|
d48b49e8e4 | ||
|
|
14308970c6 | ||
|
|
38e86e1012 | ||
|
|
e9a33af831 | ||
|
|
6a63e5dbb2 | ||
|
|
1e1892a3d5 | ||
|
|
8bff9a2973 | ||
|
|
cbe753dd29 | ||
|
|
b047845b43 | ||
|
|
1bebc75381 | ||
|
|
93c46bfc8d | ||
|
|
a3d0f5963e | ||
|
|
006b82bf05 | ||
|
|
c36e37ac6b | ||
|
|
3cf6d7385a | ||
|
|
9045b2fa97 | ||
|
|
be6f3b9c6d | ||
|
|
5a699b7ce9 | ||
|
|
f366a78e87 | ||
|
|
c63c7ead51 | ||
|
|
ecfa5902cd | ||
|
|
444027b496 | ||
|
|
9c5dcb93c7 | ||
|
|
9594221271 |
124
codecs/rotate/package-lock.json
generated
Normal file
124
codecs/rotate/package-lock.json
generated
Normal file
@@ -0,0 +1,124 @@
|
||||
{
|
||||
"name": "rotate",
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"@protobufjs/utf8": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
|
||||
"integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=",
|
||||
"dev": true
|
||||
},
|
||||
"assemblyscript": {
|
||||
"version": "github:AssemblyScript/assemblyscript#54b02c287c4d42092e4b01cc5d11bce1a53e9fb2",
|
||||
"from": "github:AssemblyScript/assemblyscript",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@protobufjs/utf8": "^1.1.0",
|
||||
"binaryen": "63.0.0-nightly.20190107",
|
||||
"glob": "^7.1.3",
|
||||
"long": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true
|
||||
},
|
||||
"binaryen": {
|
||||
"version": "63.0.0-nightly.20190107",
|
||||
"resolved": "https://registry.npmjs.org/binaryen/-/binaryen-63.0.0-nightly.20190107.tgz",
|
||||
"integrity": "sha512-vck6ZESU9q6DeEK9v/Fk2O8d2jBsSrNlia8jpmdLZv5eqmNWpkNli+QMRa9Ezfb4wi3c+NVMuxT3Ck0g9GYe8A==",
|
||||
"dev": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
|
||||
"integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||
"dev": true
|
||||
},
|
||||
"long": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
|
||||
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==",
|
||||
"dev": true
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
9
codecs/rotate/package.json
Normal file
9
codecs/rotate/package.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "rotate",
|
||||
"scripts": {
|
||||
"build": "mv rotate.{as,ts} && asc rotate.ts -b rotate.wasm --validate -O3 --importMemory && mv rotate.{ts,as}"
|
||||
},
|
||||
"devDependencies": {
|
||||
"assemblyscript": "github:AssemblyScript/assemblyscript"
|
||||
}
|
||||
}
|
||||
64
codecs/rotate/rotate.as
Normal file
64
codecs/rotate/rotate.as
Normal file
@@ -0,0 +1,64 @@
|
||||
export function rotate(inputWidth: i32, inputHeight: i32, rotate: i32): void {
|
||||
const bpp = 4;
|
||||
let offset = inputWidth * inputHeight * bpp;
|
||||
let i = 0;
|
||||
|
||||
// In the straight-copy case, d1 is x, d2 is y.
|
||||
// x starts at 0 and increases.
|
||||
// y starts at 0 and increases.
|
||||
let d1Start = 0;
|
||||
let d1Limit = inputWidth;
|
||||
let d1Advance = 1;
|
||||
let d1Multiplier = 1;
|
||||
let d2Start = 0;
|
||||
let d2Limit = inputHeight;
|
||||
let d2Advance = 1;
|
||||
let d2Multiplier = inputWidth;
|
||||
|
||||
if (rotate === 90) {
|
||||
// d1 is y, d2 is x.
|
||||
// y starts at its max value and decreases.
|
||||
// x starts at 0 and increases.
|
||||
d1Start = inputHeight - 1;
|
||||
d1Limit = inputHeight;
|
||||
d1Advance = -1;
|
||||
d1Multiplier = inputWidth;
|
||||
d2Start = 0;
|
||||
d2Limit = inputWidth;
|
||||
d2Advance = 1;
|
||||
d2Multiplier = 1;
|
||||
} else if (rotate === 180) {
|
||||
// d1 is x, d2 is y.
|
||||
// x starts at its max and decreases.
|
||||
// y starts at its max and decreases.
|
||||
d1Start = inputWidth - 1;
|
||||
d1Limit = inputWidth;
|
||||
d1Advance = -1;
|
||||
d1Multiplier = 1;
|
||||
d2Start = inputHeight - 1;
|
||||
d2Limit = inputHeight;
|
||||
d2Advance = -1;
|
||||
d2Multiplier = inputWidth;
|
||||
} else if (rotate === 270) {
|
||||
// d1 is y, d2 is x.
|
||||
// y starts at 0 and increases.
|
||||
// x starts at its max and decreases.
|
||||
d1Start = 0;
|
||||
d1Limit = inputHeight;
|
||||
d1Advance = 1;
|
||||
d1Multiplier = inputWidth;
|
||||
d2Start = inputWidth - 1;
|
||||
d2Limit = inputWidth;
|
||||
d2Advance = -1;
|
||||
d2Multiplier = 1;
|
||||
}
|
||||
|
||||
for (let d2 = d2Start; d2 >= 0 && d2 < d2Limit; d2 += d2Advance) {
|
||||
let d2offset = d2 * d2Multiplier;
|
||||
for (let d1 = d1Start; d1 >= 0 && d1 < d1Limit; d1 += d1Advance) {
|
||||
let start = ((d1 * d1Multiplier) + d2offset);
|
||||
store<u32>(offset + i * 4, load<u32>(start * 4));
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
codecs/rotate/rotate.wasm
Normal file
BIN
codecs/rotate/rotate.wasm
Normal file
Binary file not shown.
6
codecs/rotate/tsconfig.json
Normal file
6
codecs/rotate/tsconfig.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "./node_modules/assemblyscript/std/assembly.json",
|
||||
"include": [
|
||||
"./**/*.ts"
|
||||
]
|
||||
}
|
||||
912
package-lock.json
generated
912
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
30
package.json
30
package.json
@@ -15,28 +15,28 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "10.12.15",
|
||||
"@types/node": "10.12.18",
|
||||
"@types/pretty-bytes": "5.1.0",
|
||||
"@types/webassembly-js-api": "0.0.2",
|
||||
"@webcomponents/custom-elements": "1.2.1",
|
||||
"@webpack-cli/serve": "0.1.2",
|
||||
"@webpack-cli/serve": "0.1.3",
|
||||
"assets-webpack-plugin": "3.9.7",
|
||||
"chokidar": "2.0.4",
|
||||
"classnames": "2.2.6",
|
||||
"clean-webpack-plugin": "1.0.0",
|
||||
"clean-webpack-plugin": "1.0.1",
|
||||
"comlink": "3.1.1",
|
||||
"copy-webpack-plugin": "4.6.0",
|
||||
"critters-webpack-plugin": "2.1.1",
|
||||
"critters-webpack-plugin": "2.2.0",
|
||||
"css-loader": "1.0.1",
|
||||
"ejs": "2.6.1",
|
||||
"exports-loader": "0.7.0",
|
||||
"file-drop-element": "0.0.9",
|
||||
"file-loader": "2.0.0",
|
||||
"file-loader": "3.0.1",
|
||||
"html-webpack-plugin": "3.2.0",
|
||||
"husky": "1.2.1",
|
||||
"husky": "1.3.1",
|
||||
"idb-keyval": "3.1.0",
|
||||
"linkstate": "1.1.1",
|
||||
"loader-utils": "1.1.0",
|
||||
"loader-utils": "1.2.0",
|
||||
"mini-css-extract-plugin": "0.5.0",
|
||||
"minimatch": "3.0.4",
|
||||
"node-sass": "4.11.0",
|
||||
@@ -45,25 +45,25 @@
|
||||
"preact": "8.4.2",
|
||||
"prerender-loader": "1.2.0",
|
||||
"pretty-bytes": "5.1.0",
|
||||
"progress-bar-webpack-plugin": "1.11.0",
|
||||
"progress-bar-webpack-plugin": "1.12.0",
|
||||
"raw-loader": "1.0.0",
|
||||
"sass-loader": "7.1.0",
|
||||
"script-ext-html-webpack-plugin": "2.1.3",
|
||||
"source-map-loader": "0.2.4",
|
||||
"style-loader": "0.23.1",
|
||||
"terser-webpack-plugin": "1.1.0",
|
||||
"ts-loader": "5.3.1",
|
||||
"tslint": "5.11.0",
|
||||
"terser-webpack-plugin": "1.2.1",
|
||||
"ts-loader": "5.3.3",
|
||||
"tslint": "5.12.1",
|
||||
"tslint-config-airbnb": "5.11.1",
|
||||
"tslint-config-semistandard": "7.0.0",
|
||||
"tslint-react": "3.6.0",
|
||||
"typed-css-modules": "0.3.7",
|
||||
"typescript": "3.2.2",
|
||||
"typescript": "3.2.4",
|
||||
"url-loader": "1.1.2",
|
||||
"webpack": "4.27.1",
|
||||
"webpack": "4.28.0",
|
||||
"webpack-bundle-analyzer": "3.0.3",
|
||||
"webpack-cli": "3.1.2",
|
||||
"webpack-dev-server": "3.1.10",
|
||||
"webpack-cli": "3.2.1",
|
||||
"webpack-dev-server": "3.1.14",
|
||||
"worker-plugin": "3.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,3 +3,10 @@ export interface RotateOptions {
|
||||
}
|
||||
|
||||
export const defaultOptions: RotateOptions = { rotate: 0 };
|
||||
|
||||
export interface RotateModuleInstance {
|
||||
exports: {
|
||||
memory: WebAssembly.Memory;
|
||||
rotate(width: number, height: number, rotate: 0 | 90 | 180 | 270): void;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,76 +1,30 @@
|
||||
import { RotateOptions } from './processor-meta';
|
||||
import wasmUrl from '../../../codecs/rotate/rotate.wasm';
|
||||
import { RotateOptions, RotateModuleInstance } from './processor-meta';
|
||||
|
||||
const bpp = 4;
|
||||
export async function rotate(
|
||||
data: ImageData,
|
||||
opts: RotateOptions,
|
||||
): Promise<ImageData> {
|
||||
const flipDimensions = opts.rotate % 180 !== 0;
|
||||
// Number of wasm memory pages (á 64KiB) needed to store the image twice.
|
||||
const bytesPerImage = data.width * data.height * 4;
|
||||
const numPagesNeeded = Math.ceil(bytesPerImage * 2 / (64 * 1024));
|
||||
const { instance } = (await (WebAssembly as any).instantiateStreaming(
|
||||
fetch(wasmUrl),
|
||||
{
|
||||
env: {
|
||||
memory: new WebAssembly.Memory({ initial: numPagesNeeded }),
|
||||
},
|
||||
},
|
||||
)) as { instance: RotateModuleInstance };
|
||||
|
||||
export function rotate(data: ImageData, opts: RotateOptions): ImageData {
|
||||
const { rotate } = opts;
|
||||
const flipDimensions = rotate % 180 !== 0;
|
||||
const { width: inputWidth, height: inputHeight } = data;
|
||||
const outputWidth = flipDimensions ? inputHeight : inputWidth;
|
||||
const outputHeight = flipDimensions ? inputWidth : inputHeight;
|
||||
const out = new ImageData(outputWidth, outputHeight);
|
||||
let i = 0;
|
||||
const view = new Uint8ClampedArray(instance.exports.memory.buffer);
|
||||
view.set(data.data);
|
||||
|
||||
// In the straight-copy case, d1 is x, d2 is y.
|
||||
// x starts at 0 and increases.
|
||||
// y starts at 0 and increases.
|
||||
let d1Start = 0;
|
||||
let d1Limit = inputWidth;
|
||||
let d1Advance = 1;
|
||||
let d1Multiplier = 1;
|
||||
let d2Start = 0;
|
||||
let d2Limit = inputHeight;
|
||||
let d2Advance = 1;
|
||||
let d2Multiplier = inputWidth;
|
||||
|
||||
if (rotate === 90) {
|
||||
// d1 is y, d2 is x.
|
||||
// y starts at its max value and decreases.
|
||||
// x starts at 0 and increases.
|
||||
d1Start = inputHeight - 1;
|
||||
d1Limit = inputHeight;
|
||||
d1Advance = -1;
|
||||
d1Multiplier = inputWidth;
|
||||
d2Start = 0;
|
||||
d2Limit = inputWidth;
|
||||
d2Advance = 1;
|
||||
d2Multiplier = 1;
|
||||
} else if (rotate === 180) {
|
||||
// d1 is x, d2 is y.
|
||||
// x starts at its max and decreases.
|
||||
// y starts at its max and decreases.
|
||||
d1Start = inputWidth - 1;
|
||||
d1Limit = inputWidth;
|
||||
d1Advance = -1;
|
||||
d1Multiplier = 1;
|
||||
d2Start = inputHeight - 1;
|
||||
d2Limit = inputHeight;
|
||||
d2Advance = -1;
|
||||
d2Multiplier = inputWidth;
|
||||
} else if (rotate === 270) {
|
||||
// d1 is y, d2 is x.
|
||||
// y starts at 0 and increases.
|
||||
// x starts at its max and decreases.
|
||||
d1Start = 0;
|
||||
d1Limit = inputHeight;
|
||||
d1Advance = 1;
|
||||
d1Multiplier = inputWidth;
|
||||
d2Start = inputWidth - 1;
|
||||
d2Limit = inputWidth;
|
||||
d2Advance = -1;
|
||||
d2Multiplier = 1;
|
||||
}
|
||||
|
||||
for (let d2 = d2Start; d2 >= 0 && d2 < d2Limit; d2 += d2Advance) {
|
||||
for (let d1 = d1Start; d1 >= 0 && d1 < d1Limit; d1 += d1Advance) {
|
||||
// Iterate over channels:
|
||||
const start = ((d1 * d1Multiplier) + (d2 * d2Multiplier)) * bpp;
|
||||
for (let j = 0; j < bpp; j += 1) {
|
||||
out.data[i] = data.data[start + j];
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
instance.exports.rotate(data.width, data.height, opts.rotate);
|
||||
return new ImageData(
|
||||
view.slice(bytesPerImage, bytesPerImage * 2),
|
||||
flipDimensions ? data.height : data.width,
|
||||
flipDimensions ? data.width : data.height,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user