Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Image encoders & decoders built with WebAssembly.
Module | Encoder | Decoder |
---|---|---|
jpeg | MozJPEG | |
png | OxiPNG + imagequant | image-png |
qoi | qoi | |
webp | libwebp | |
heic | libheif + x265 | libheif + libde265 |
avif | libavif + aom | |
jxl | libjxl | |
wp2 | libwebp2 |
[!WARNING] Since libheif does not support specify thread count for x265 encoder, The
encode
of theheic
module only work on webworker, and has performance issue.
icodec is aimed at the web platform and has some limitations:
Requirement: The target environment must support WebAssembly SIMD.
pnpm add icodec
Use in browser:
// All codec modules (see the table above) are named export.
import { avif, jxl } from "icodec";
const response = await fetch("https://raw.githubusercontent.com/Kaciras/icodec/master/test/snapshot/image.avif")
// This should be called once before you invoke `decode()`
await avif.loadDecoder();
// Decode AVIF to ImageData.
const image = avif.decode(await response.arrayBuffer());
// This should be called once before you invoke `encode()`
await jxl.loadEncoder();
// Encode the image to JPEG XL.
const encoded = jxl.encode(image, /*{ options }*/);
To use icodec in Node, just change the import specifier to icodec/node
, and loadEncoder
/loadDecoder
will use readFileSync
instead of fetch
.
import { avif, jxl } from "icodec/node";
If your bundler requires special handing of WebAssembly, you can pass the URL of WASM files to load*
function. WASM files are exported in the format icodec/<codec>-<enc|dec>.wasm
.
icodec is tree-shakable, with a bundler the unused code and wasm file can be eliminated from loading.
import { avif, jxl } from "icodec";
// Example for Vite
import AVIFEncWASM from "icodec/avif-enc.wasm?url";
import JxlDecWASM from "icodec/jxl-dec.wasm?url";
await avif.loadDecoder(AVIFEncWASM);
await jxl.loadEncoder(JxlDecWASM);
Type of each codec module:
/**
* Provides a uniform type for codec modules that support encoding.
*
* @example
* import { wp2, ICodecModule } from "icodec";
*
* const encoder: ICodecModule<wp2.Options> = wp2;
*/
interface ICodecModule<T = any> {
/**
* The default options of `encode` function.
*/
defaultOptions: Required<T>;
/**
* The MIME type string of the format.
*/
mimeType: string;
/**
* File extension (without the dot) of this format.
*/
extension: string;
/**
* Load the decoder WASM file, must be called once before decode.
*
* @param source If pass a string, it's the URL of WASM file to fetch,
* else it will be treated as the WASM bytes.
* @return the underlying WASM module, which is not part of
* the public API and can be changed at any time.
*/
loadDecoder(source?: WasmSource): Promise<any>;
/**
* Convert the image to raw RGBA data.
*/
decode(input: Uint8Array): ImageData;
/**
* Load the encoder WASM file, must be called once before encode.
*
* @param source If pass a string, it's the URL of WASM file to fetch,
* else it will be treated as the WASM bytes.
* @return the underlying WASM module, which is not part of
* the public API and can be changed at any time.
*/
loadEncoder(source?: WasmSource): Promise<any>;
/**
* Encode an image with RGBA pixels data.
*/
encode(image: ImageDataLike, options?: T): Uint8Array;
}
The png
module exports extra members:
/**
* Reduces the colors used in the image at a slight loss, using a combination
* of vector quantization algorithms.
*
* Can be used before other compression algorithm to boost compression ratio.
*/
declare function reduceColors(image: ImageDataLike, options?: QuantizeOptions): Uint8Array;
Decode & Encode test/snapshot/image.*
files, time.SD
is Standard Deviation of the time.
This benchmark ignores extra code size introduced by icodec, which in practice needs to be taken into account.
Decode on Edge browser.
No. | Name | codec | time | time.SD |
---|---|---|---|---|
0 | icodec | avif | 3.22 ms | 8.24 us |
1 | 2d | avif | 1.50 ms | 3.13 us |
2 | WebGL | avif | 3.08 ms | 26.33 us |
3 | icodec | heic | 3.06 ms | 16.84 us |
4 | icodec | jpeg | 727.85 us | 1.65 us |
5 | 2d | jpeg | 601.21 us | 3.51 us |
6 | WebGL | jpeg | 1,876.96 us | 8.85 us |
7 | icodec | jxl | 3.57 ms | 17.73 us |
8 | icodec | png | 419.48 us | 2,901.49 ns |
9 | 2d | png | 573.07 us | 801.34 ns |
10 | WebGL | png | 1,835.78 us | 16,278.04 ns |
11 | icodec | qoi | 444.00 us | 1.08 us |
12 | icodec | webp | 792.57 us | 1.58 us |
13 | 2d | webp | 805.07 us | 4.04 us |
14 | WebGL | webp | 2,156.43 us | 36.42 us |
15 | icodec | wp2 | 2.59 ms | 12.10 us |
Decode on Node, vs Sharp.
No. | Name | codec | time | time.SD |
---|---|---|---|---|
0 | icodec | avif | 2.95 ms | 6.46 us |
1 | Sharp | avif | 2.54 ms | 7.16 us |
2 | icodec | jpeg | 471.99 us | 2.99 us |
3 | Sharp | jpeg | 842.17 us | 1.50 us |
4 | icodec | jxl | 3.03 ms | 7.62 us |
5 | icodec | png | 186.18 us | 1.94 us |
6 | Sharp | png | 645.95 us | 1.78 us |
7 | icodec | qoi | 200.62 us | 1.41 us |
8 | icodec | webp | 557.32 us | 2.92 us |
9 | Sharp | webp | 1,708.96 us | 12.14 us |
10 | icodec | wp2 | 2.27 ms | 1.99 us |
Encode on Node, vs Sharp. Note that icodec and Sharp do not use the same code, so the output images are not exactly equal.
No. | Name | codec | time | time.SD |
---|---|---|---|---|
0 | icodec | avif | 2.97 ms | 9.51 us |
1 | Sharp | avif | 2.61 ms | 8.28 us |
2 | icodec | jpeg | 479.30 us | 2.10 us |
3 | Sharp | jpeg | 894.27 us | 2.11 us |
4 | icodec | jxl | 3.18 ms | 114.32 us |
5 | icodec | png | 189.39 us | 1.36 us |
6 | Sharp | png | 689.49 us | 2.36 us |
7 | icodec | qoi | 204.42 us | 1.26 us |
8 | icodec | webp | 555.51 us | 1.59 us |
9 | Sharp | webp | 1,773.42 us | 10.45 us |
10 | icodec | wp2 | 2.34 ms | 50.14 us |
To build WASM modules, you will need to install:
Run the build script:
node scripts/build.js
TODOs:
Rnn tests:
pnpm exec tsc
node --test test/test-*.js
Start web demo:
node scripts/start-demo.js
FAQs
Image encoders & decoders built with WebAssembly
The npm package icodec receives a total of 2 weekly downloads. As such, icodec popularity was classified as not popular.
We found that icodec demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.