-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #20 from jerch/faster_decode
faster decoding
- Loading branch information
Showing
42 changed files
with
14,995 additions
and
664 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node | ||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions | ||
|
||
name: Node.js CI | ||
|
||
on: | ||
push: | ||
branches: [ master ] | ||
pull_request: | ||
branches: [ master ] | ||
|
||
jobs: | ||
build: | ||
|
||
runs-on: ubuntu-latest | ||
|
||
strategy: | ||
matrix: | ||
node-version: [12.x, 14.x, 16.x] | ||
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/ | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Use Node.js ${{ matrix.node-version }} | ||
uses: actions/setup-node@v2 | ||
with: | ||
node-version: ${{ matrix.node-version }} | ||
cache: 'npm' | ||
- run: npm ci | ||
- run: npm run build --if-present | ||
- run: npm test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,12 @@ | ||
/dist/ | ||
/lib/ | ||
/lib-esm/ | ||
/node_modules/ | ||
/package-lock.json | ||
/coverage | ||
/.nyc_output | ||
/benchmark | ||
/.vscode | ||
/wasm/decoder.wasm | ||
/wasm/settings.json | ||
/src/wasm.ts | ||
/emsdk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#!/bin/bash | ||
|
||
if [ -d emsdk ]; then | ||
exit 0 | ||
fi | ||
|
||
# pull emscripten on fresh checkout | ||
echo "Fetching emscripten..." | ||
|
||
git clone https://github.com/emscripten-core/emsdk.git | ||
cd emsdk | ||
|
||
# wasm module is only tested with 2.0.25, install by default | ||
./emsdk install 2.0.25 | ||
./emsdk activate 2.0.25 | ||
|
||
cd .. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
const fs = require('fs'); | ||
const LIMITS = require('../wasm/settings.json'); | ||
|
||
const file = ` | ||
export const LIMITS = { | ||
CHUNK_SIZE: ${LIMITS.CHUNK_SIZE}, | ||
PALETTE_SIZE: ${LIMITS.PALETTE_SIZE}, | ||
MAX_WIDTH: ${LIMITS.MAX_WIDTH}, | ||
BYTES: '${fs.readFileSync('wasm/decoder.wasm').toString('base64')}' | ||
}; | ||
`; | ||
fs.writeFileSync('src/wasm.ts', file); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
const { decodeAsync, PALETTE_ANSI_256 } = require('../lib/index'); | ||
const { createCanvas, createImageData } = require('canvas'); | ||
const fs = require('fs'); | ||
const open = require('open'); | ||
|
||
/** | ||
* Note on *_clean.six files: | ||
* | ||
* Normally SIXEL data is embedded in a DCS sequence like this: | ||
* DCS P1 ; P2 ; P3 q <SIXEL DATA> ST | ||
* | ||
* To handle this properly we would have to include an escape | ||
* sequence parser in the example which is beyond the scope. Thus | ||
* the _clean.six files are stripped down to the <SIXEL DATA> part. | ||
*/ | ||
fs.readFile('testfiles/screen_clean.six', (err, data) => { | ||
// example with decodeAsync | ||
// about the used options: | ||
// - palette: | ||
// colors to start with (some older sixel images dont define | ||
// their colors, instead rely on a predefined default palette) | ||
// default is 16 colors of VT340, here we set it to 256 colors of xterm | ||
// - memoryUsage: | ||
// hard limit the pixel memory to avoid running out of memory (default 128 MB) | ||
// note this cannot be approximated from sixel data size without | ||
// parsing (1 kB of sixel data can easily create >10M pixels) | ||
decodeAsync(data, {palette: PALETTE_ANSI_256, memoryLimit: 65536 * 20}) | ||
.then(result => { | ||
// transfer bitmap data to ImageData object | ||
const imageData = createImageData(result.width, result.height); | ||
new Uint32Array(imageData.data.buffer).set(result.data32); | ||
|
||
// draw ImageData to canvas | ||
const canvas = createCanvas(result.width, result.height); | ||
const ctx = canvas.getContext('2d'); | ||
ctx.putImageData(imageData, 0, 0); | ||
|
||
// write to some file and show it | ||
const targetFile = __dirname + '/node_decode_output.png'; | ||
const out = fs.createWriteStream(targetFile); | ||
const stream = canvas.createPNGStream(); | ||
stream.pipe(out); | ||
out.on('finish', () => open(targetFile)); | ||
}); | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
const { introducer, FINALIZER, sixelEncode, decode } = require('../lib/index'); | ||
const fs = require('fs'); | ||
|
||
/** | ||
* Note on *_clean.six files: | ||
* | ||
* Normally SIXEL data is embedded in a DCS sequence like this: | ||
* DCS P1 ; P2 ; P3 q <SIXEL DATA> ST | ||
* | ||
* To handle this properly we would have to include an escape | ||
* sequence parser in the example which is beyond the scope. Thus | ||
* the _clean.six files are stripped down to the <SIXEL DATA> part. | ||
*/ | ||
fs.readFile('testfiles/biplane_clean.six', (err, data) => { | ||
|
||
// decoding with sync version (does not work in browser main, use decodeAsync there) | ||
const img = decode(data); | ||
|
||
// extract colors | ||
const palette = new Set(); | ||
for (let i = 0; i < img.data32.length; ++i) { | ||
palette.add(img.data32[i]); | ||
} | ||
|
||
// encode to sixel again | ||
const sixelData = sixelEncode( | ||
new Uint8Array(img.data32.buffer), | ||
img.width, | ||
img.height, | ||
Array.from(palette) | ||
); | ||
|
||
// write to sixel capable terminal | ||
// `sixelEncode` gives us only the sixel data part, | ||
// to get a full sequence, we need to add the introducer and the finalizer | ||
// (never forget the finalizer or the terminal will "hang") | ||
console.log(introducer(1) + sixelData + FINALIZER); | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
const { decodeAsync, image2sixel } = require('../lib/index'); | ||
const { createCanvas, createImageData } = require('canvas'); | ||
const fs = require('fs'); | ||
const open = require('open'); | ||
|
||
// create some canvas | ||
const width = 204; | ||
const height = 202; | ||
const canvas = createCanvas(width, height); | ||
const ctx = canvas.getContext('2d'); | ||
ctx.fillStyle = 'white'; | ||
ctx.fillRect(0, 0, canvas.width, canvas.height); | ||
|
||
// gradient | ||
const gradient = ctx.createLinearGradient(0, 0, 204, 0); | ||
gradient.addColorStop(0, 'green'); | ||
gradient.addColorStop(.5, 'cyan'); | ||
gradient.addColorStop(1, 'green'); | ||
ctx.fillStyle = gradient; | ||
ctx.fillRect(0, 0, 204, 50); | ||
|
||
// yellow circle | ||
ctx.strokeStyle = 'yellow'; | ||
ctx.beginPath(); | ||
ctx.arc(100, 120, 50, 0, 2 * Math.PI); | ||
ctx.stroke(); | ||
|
||
// line at end - 1 | ||
ctx.translate(0.5,0.5); | ||
ctx.strokeStyle = 'red'; | ||
ctx.beginPath(); | ||
ctx.moveTo(0, 200); | ||
ctx.lineTo(204, 200); | ||
ctx.stroke(); | ||
|
||
// some text | ||
ctx.font = '30px Impact'; | ||
ctx.rotate(0.1); | ||
ctx.fillStyle = 'black'; | ||
ctx.fillText('Awesome!', 50, 100); | ||
|
||
// green underline half opaque | ||
const text = ctx.measureText('Awesome!'); | ||
ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)'; | ||
ctx.lineWidth = 2; | ||
ctx.beginPath(); | ||
ctx.lineTo(50, 102); | ||
ctx.lineTo(50 + text.width, 102); | ||
ctx.stroke(); | ||
|
||
// convert to sixel sequence | ||
const sixelData = image2sixel(ctx.getImageData(0, 0, width, height).data, width, height, 256, 1); | ||
|
||
// output SIXEL data to terminal (Terminal must have SIXEL enabled!) | ||
console.log(sixelData); | ||
|
||
|
||
/** | ||
* For comparison we also output the image to a PNG file. | ||
*/ | ||
|
||
// note: we strip the first 7 bytes, since they belong to the escape sequence introducer | ||
// (should be handled by a proper sequence parser, see node_example_decode_full_sequence.js) | ||
decodeAsync(sixelData.slice(7), {fillColor:0, memoryLimit: 65536 *20}) | ||
.then(result => { | ||
// transfer bitmap data to ImageData object | ||
const imageData = createImageData(result.width, result.height); | ||
new Uint32Array(imageData.data.buffer).set(result.data32); | ||
|
||
// draw ImageData to canvas | ||
const canvas2 = createCanvas(result.width, result.height); | ||
const ctx2 = canvas2.getContext('2d'); | ||
ctx2.putImageData(imageData, 0, 0); | ||
|
||
// write to some file and show it | ||
const targetFile = __dirname + '/node_encode_output.png'; | ||
const out = fs.createWriteStream(targetFile); | ||
const stream = canvas2.createPNGStream(); | ||
stream.pipe(out); | ||
out.on('finish', () => open(targetFile)); | ||
}); |
Oops, something went wrong.