mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-15 01:59:57 +00:00
Move to makefile for AVIF
This commit is contained in:
59
codecs/avif/dec/avif_dec.cpp
Normal file
59
codecs/avif/dec/avif_dec.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "avif/avif.h"
|
||||
#include <emscripten/bind.h>
|
||||
#include <emscripten/val.h>
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
class RawImage {
|
||||
public:
|
||||
val buffer;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
|
||||
RawImage(val b, uint32_t w, uint32_t h) : buffer(b), width(w), height(h) {}
|
||||
};
|
||||
|
||||
RawImage decode(std::string avifimage) {
|
||||
// point raw.data and raw.size to the contents of an .avif(s)
|
||||
avifROData raw;
|
||||
raw.data = (uint8_t *)avifimage.c_str();
|
||||
raw.size = avifimage.length();
|
||||
|
||||
avifImage *image = avifImageCreateEmpty();
|
||||
avifDecoder *decoder = avifDecoderCreate();
|
||||
avifResult decodeResult = avifDecoderRead(decoder, image, &raw);
|
||||
// image is an independent copy of decoded data, decoder may be destroyed here
|
||||
avifDecoderDestroy(decoder);
|
||||
if (decodeResult != AVIF_RESULT_OK) {
|
||||
return RawImage(val::null(), -1, -1);
|
||||
}
|
||||
|
||||
// Convert to interleaved RGB(A)/BGR(A) using a libavif-allocated buffer.
|
||||
avifRGBImage rgb;
|
||||
avifRGBImageSetDefaults(&rgb, image); // Defaults to AVIF_RGB_FORMAT_RGBA which is what we want.
|
||||
rgb.depth = 8; // Does not need to match image->depth. We always want 8-bit pixels.
|
||||
|
||||
avifRGBImageAllocatePixels(&rgb);
|
||||
avifImageYUVToRGB(image, &rgb);
|
||||
|
||||
// Image has been converted to RGB, we don't need the original anymore.
|
||||
avifImageDestroy(image);
|
||||
|
||||
// We want to create a *copy* of the decoded data to be owned by the JavaScript side.
|
||||
// For that, we perform `new Uint8Array(wasmMemBuffer, wasmPtr, wasmSize).slice()`:
|
||||
auto result = val(typed_memory_view(rgb.rowBytes * rgb.height, rgb.pixels)).call<val>("slice");
|
||||
|
||||
// Now we can safely free the RGB pixels:
|
||||
avifRGBImageFreePixels(&rgb);
|
||||
|
||||
return RawImage(result, rgb.width, rgb.height);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(my_module) {
|
||||
class_<RawImage>("RawImage")
|
||||
.property("buffer", &RawImage::buffer)
|
||||
.property("width", &RawImage::width)
|
||||
.property("height", &RawImage::height);
|
||||
|
||||
function("decode", &decode);
|
||||
}
|
||||
Reference in New Issue
Block a user