46 lines
1.5 KiB
C
46 lines
1.5 KiB
C
#include "cell.h"
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include "stb_image_common.h"
|
|
|
|
// GIF decoding via stb_image (returns first frame only for animated GIFs)
|
|
JSValue js_gif_decode(JSContext *js, JSValue this_val, int argc, JSValueConst *argv)
|
|
{
|
|
size_t len;
|
|
void *raw = js_get_blob_data(js, &len, argv[0]);
|
|
if (raw == NULL) return JS_EXCEPTION;
|
|
if (!raw) return JS_ThrowReferenceError(js, "could not get GIF data from blob");
|
|
|
|
int n, width, height;
|
|
void *data = stbi_load_from_memory(raw, len, &width, &height, &n, 4);
|
|
|
|
if (!data)
|
|
return JS_ThrowReferenceError(js, "failed to decode GIF: %s", stbi_failure_reason());
|
|
|
|
if (width <= 0 || height <= 0) {
|
|
stbi_image_free(data);
|
|
return JS_ThrowReferenceError(js, "decoded GIF has invalid size: %dx%d", width, height);
|
|
}
|
|
|
|
int pitch = width * 4;
|
|
size_t pixels_size = pitch * height;
|
|
|
|
JSValue obj = JS_NewObject(js);
|
|
JS_SetPropertyStr(js, obj, "width", JS_NewInt32(js, width));
|
|
JS_SetPropertyStr(js, obj, "height", JS_NewInt32(js, height));
|
|
JS_SetPropertyStr(js, obj, "format", JS_NewString(js, "rgba32"));
|
|
JS_SetPropertyStr(js, obj, "pitch", JS_NewInt32(js, pitch));
|
|
JS_SetPropertyStr(js, obj, "pixels", js_new_blob_stoned_copy(js, data, pixels_size));
|
|
JS_SetPropertyStr(js, obj, "depth", JS_NewInt32(js, 8));
|
|
JS_SetPropertyStr(js, obj, "hdr", JS_NewBool(js, 0));
|
|
|
|
stbi_image_free(data);
|
|
return obj;
|
|
}
|
|
|
|
static const JSCFunctionListEntry js_gif_funcs[] = {
|
|
MIST_FUNC_DEF(gif, decode, 1)
|
|
};
|
|
|
|
CELL_USE_FUNCS(js_gif_funcs)
|