mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-15 18:19:47 +00:00
BIN
codecs/example.webp
Normal file
BIN
codecs/example.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
2
codecs/webp_dec/.gitignore
vendored
Normal file
2
codecs/webp_dec/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/*.wasm
|
||||||
|
/*.js
|
||||||
42
codecs/webp_dec/README.md
Normal file
42
codecs/webp_dec/README.md
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# WebP decoder
|
||||||
|
|
||||||
|
- Source: <https://github.com/webmproject/libwebp>
|
||||||
|
- Version: v0.6.1
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
See `example.html`
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
### `int version()`
|
||||||
|
|
||||||
|
Returns the version of libwebp as a number. va.b.c is encoded as 0x0a0b0c
|
||||||
|
|
||||||
|
### `uint8_t* create_buffer(int size)`
|
||||||
|
|
||||||
|
Allocates an buffer for the file data.
|
||||||
|
|
||||||
|
### `void destroy_buffer(uint8_t* p)`
|
||||||
|
|
||||||
|
Frees a buffer created with `create_buffer`.
|
||||||
|
|
||||||
|
### `void decode(uint8_t* img_in, int size)`
|
||||||
|
|
||||||
|
Decodes the given webp file into raw RGBA. The result is implicitly stored and can be accessed using the `get_result_*()` functions.
|
||||||
|
|
||||||
|
### `void free_result()`
|
||||||
|
|
||||||
|
Frees the result created by `decode()`.
|
||||||
|
|
||||||
|
### `int get_result_pointer()`
|
||||||
|
|
||||||
|
Returns the pointer to the start of the buffer holding the encoded data. Length is width x height x 4 bytes.
|
||||||
|
|
||||||
|
### `int get_result_width()`
|
||||||
|
|
||||||
|
Returns the width of the image.
|
||||||
|
|
||||||
|
### `int get_result_height()`
|
||||||
|
|
||||||
|
Returns the height of the image.
|
||||||
44
codecs/webp_dec/example.html
Normal file
44
codecs/webp_dec/example.html
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<script src='webp_dec.js'></script>
|
||||||
|
<script>
|
||||||
|
const Module = webp_dec();
|
||||||
|
|
||||||
|
async function loadFile(src) {
|
||||||
|
const resp = await fetch(src);
|
||||||
|
return await resp.arrayBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
Module.onRuntimeInitialized = async _ => {
|
||||||
|
const api = {
|
||||||
|
version: Module.cwrap('version', 'number', []),
|
||||||
|
create_buffer: Module.cwrap('create_buffer', 'number', ['number', 'number']),
|
||||||
|
destroy_buffer: Module.cwrap('destroy_buffer', '', ['number']),
|
||||||
|
decode: Module.cwrap('decode', '', ['number', 'number']),
|
||||||
|
free_result: Module.cwrap('free_result', '', ['number']),
|
||||||
|
get_result_pointer: Module.cwrap('get_result_pointer', 'number', []),
|
||||||
|
get_result_width: Module.cwrap('get_result_width', 'number', []),
|
||||||
|
get_result_height: Module.cwrap('get_result_height', 'number', []),
|
||||||
|
};
|
||||||
|
const image = await loadFile('../example.webp');
|
||||||
|
const p = api.create_buffer(image.byteLength);
|
||||||
|
Module.HEAP8.set(new Uint8Array(image), p);
|
||||||
|
api.decode(p, image.byteLength);
|
||||||
|
const resultPointer = api.get_result_pointer();
|
||||||
|
if(resultPointer === 0) {
|
||||||
|
throw new Error("Could not decode image");
|
||||||
|
}
|
||||||
|
const resultWidth = api.get_result_width();
|
||||||
|
const resultHeight = api.get_result_height();
|
||||||
|
const resultView = new Uint8Array(Module.HEAP8.buffer, resultPointer, resultWidth * resultHeight * 4);
|
||||||
|
const result = new Uint8ClampedArray(resultView);
|
||||||
|
const imageData = new ImageData(result, resultWidth, resultHeight);
|
||||||
|
api.free_result(resultPointer);
|
||||||
|
api.destroy_buffer(p);
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
canvas.width = resultWidth;
|
||||||
|
canvas.height = resultHeight;
|
||||||
|
document.body.appendChild(canvas);
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
ctx.putImageData(imageData, 0, 0);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
1147
codecs/webp_dec/package-lock.json
generated
Normal file
1147
codecs/webp_dec/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
13
codecs/webp_dec/package.json
Normal file
13
codecs/webp_dec/package.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"name": "webp_dec",
|
||||||
|
"scripts": {
|
||||||
|
"install": "napa",
|
||||||
|
"build": "docker run --rm -v $(pwd):/src trzeci/emscripten emcc -O3 -s WASM=1 -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"cwrap\"]' -s ALLOW_MEMORY_GROWTH=1 -s MODULARIZE=1 -s 'EXPORT_NAME=\"webp_dec\"' -I node_modules/libwebp -o ./webp_dec.js webp_dec.c node_modules/libwebp/src/{dec,dsp,demux,enc,mux,utils}/*.c"
|
||||||
|
},
|
||||||
|
"napa": {
|
||||||
|
"libwebp": "webmproject/libwebp#v0.6.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"napa": "^3.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
51
codecs/webp_dec/webp_dec.c
Normal file
51
codecs/webp_dec/webp_dec.c
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#include "emscripten.h"
|
||||||
|
#include "src/webp/decode.h"
|
||||||
|
#include "src/webp/demux.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE
|
||||||
|
int version() {
|
||||||
|
return WebPGetDecoderVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE
|
||||||
|
uint8_t* create_buffer(int size) {
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE
|
||||||
|
void destroy_buffer(uint8_t* p) {
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
int result[3];
|
||||||
|
EMSCRIPTEN_KEEPALIVE
|
||||||
|
void decode(uint8_t* img_in, int size) {
|
||||||
|
int width, height;
|
||||||
|
uint8_t* img_out = WebPDecodeRGBA(img_in, size, &width, &height);
|
||||||
|
result[0] = (int)img_out;
|
||||||
|
result[1] = width;
|
||||||
|
result[2] = height;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE
|
||||||
|
void free_result() {
|
||||||
|
WebPFree(result[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE
|
||||||
|
int get_result_pointer() {
|
||||||
|
return result[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE
|
||||||
|
int get_result_width() {
|
||||||
|
return result[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_KEEPALIVE
|
||||||
|
int get_result_height() {
|
||||||
|
return result[2];
|
||||||
|
}
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
api.free_result(resultPointer);
|
api.free_result(resultPointer);
|
||||||
api.destroy_buffer(p);
|
api.destroy_buffer(p);
|
||||||
|
|
||||||
const blob = new Blob([result], {type: 'image/jpeg'});
|
const blob = new Blob([result], {type: 'image/webp'});
|
||||||
const blobURL = URL.createObjectURL(blob);
|
const blobURL = URL.createObjectURL(blob);
|
||||||
const img = document.createElement('img');
|
const img = document.createElement('img');
|
||||||
img.src = blobURL;
|
img.src = blobURL;
|
||||||
|
|||||||
Reference in New Issue
Block a user