Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decoder for webp #50

Merged
merged 2 commits into from
Jun 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added codecs/example.webp
Binary file not shown.
2 changes: 2 additions & 0 deletions codecs/webp_dec/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/*.wasm
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weren't we going to start checking the wasm in?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that’s currently only in the testing branch. I’ll move that to master once this lands.

/*.js
42 changes: 42 additions & 0 deletions codecs/webp_dec/README.md
Original file line number Diff line number Diff line change
@@ -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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"a buffer"


### `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 changes: 44 additions & 0 deletions codecs/webp_dec/example.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!doctype html>
<script src='webp_dec.js'></script>
<script>
const Module = webp_dec();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not going to review this file in terms of project types, but isn't this not-a-constructor, so should start with a lower-case?

The reason I ask, is I saw @developit doing a similar thing in the options PR. I'm worried I've missed out on some change to consensus I always thought it was:

ThisIsAClass
THIS_IS_A_PRIMITIVE_CONSTANT
thisIsEverythingElse

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s mostly this way ’cause that’s how all the Emscripten code examples are written. By default, Emscripten glue creates a global called Module. We set a flag so that instead it registers a function that returns that Module, hence the naming. It’s nbd to change that, tho

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind so much for this example. I'd want to rename it if it was part of the main JS though. Was mostly just curious.


async function loadFile(src) {
const resp = await fetch(src);
return await resp.arrayBuffer();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just return here is fine. The await is redundant.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh cool. I thought it would make the stack trace look different, but it doesn’t. TIL.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

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>
Loading