fix syntax
This commit is contained in:
144
aseprite.c
144
aseprite.c
@@ -17,24 +17,23 @@ static int check_size_overflow(size_t a, size_t b, size_t c, size_t *result)
|
||||
// Helper function to convert cute_aseprite frame to JS image object
|
||||
static JSValue frame_to_js(JSContext *js, ase_frame_t *frame, int width, int height)
|
||||
{
|
||||
// Create JS object with frame data
|
||||
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, width * 4));
|
||||
JS_SetPropertyStr(js, obj, "depth", JS_NewInt32(js, 8));
|
||||
JS_SetPropertyStr(js, obj, "hdr", JS_NewBool(js, 0));
|
||||
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(obj, JS_NewObject(js));
|
||||
JS_SetPropertyStr(js, obj.val, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, obj.val, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, obj.val, "format", JS_NewString(js, "rgba32"));
|
||||
JS_SetPropertyStr(js, obj.val, "pitch", JS_NewInt32(js, width * 4));
|
||||
JS_SetPropertyStr(js, obj.val, "depth", JS_NewInt32(js, 8));
|
||||
JS_SetPropertyStr(js, obj.val, "hdr", JS_NewBool(js, 0));
|
||||
|
||||
// Copy pixel data
|
||||
size_t pixels_size = width * height * 4;
|
||||
JSValue pixels = js_new_blob_stoned_copy(js, frame->pixels, pixels_size);
|
||||
JS_SetPropertyStr(js, obj, "pixels", pixels);
|
||||
|
||||
JS_SetPropertyStr(js, obj.val, "pixels", js_new_blob_stoned_copy(js, frame->pixels, pixels_size));
|
||||
|
||||
// Add frame duration (in milliseconds)
|
||||
JS_SetPropertyStr(js, obj, "duration", JS_NewInt32(js, frame->duration_milliseconds));
|
||||
|
||||
return obj;
|
||||
JS_SetPropertyStr(js, obj.val, "duration", JS_NewInt32(js, frame->duration_milliseconds));
|
||||
|
||||
JS_RETURN(obj.val);
|
||||
}
|
||||
|
||||
// Aseprite decoding
|
||||
@@ -48,40 +47,39 @@ JSValue js_aseprite_decode(JSContext *js, JSValue this_val, int argc, JSValueCon
|
||||
ase_t *ase = cute_aseprite_load_from_memory(raw, len, NULL);
|
||||
if (!ase)
|
||||
return JS_ThrowReferenceError(js, "failed to parse Aseprite file");
|
||||
|
||||
// Create array for frames
|
||||
JSValue frames_array = JS_NewArray(js);
|
||||
|
||||
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(frames_array, JS_NewArray(js));
|
||||
|
||||
// Convert each frame to JS object
|
||||
for (int i = 0; i < ase->frame_count; i++) {
|
||||
JSValue frame_obj = frame_to_js(js, &ase->frames[i], ase->w, ase->h);
|
||||
JS_SetPropertyUint32(js, frames_array, i, frame_obj);
|
||||
JS_SetPropertyNumber(js, frames_array.val, i, frame_to_js(js, &ase->frames[i], ase->w, ase->h));
|
||||
}
|
||||
|
||||
|
||||
// Create result object
|
||||
JSValue result = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, result, "width", JS_NewInt32(js, ase->w));
|
||||
JS_SetPropertyStr(js, result, "height", JS_NewInt32(js, ase->h));
|
||||
JS_SetPropertyStr(js, result, "frames", frames_array);
|
||||
JS_SetPropertyStr(js, result, "frame_count", JS_NewInt32(js, ase->frame_count));
|
||||
|
||||
JS_ROOT(result, JS_NewObject(js));
|
||||
JS_SetPropertyStr(js, result.val, "width", JS_NewInt32(js, ase->w));
|
||||
JS_SetPropertyStr(js, result.val, "height", JS_NewInt32(js, ase->h));
|
||||
JS_SetPropertyStr(js, result.val, "frames", frames_array.val);
|
||||
JS_SetPropertyStr(js, result.val, "frame_count", JS_NewInt32(js, ase->frame_count));
|
||||
|
||||
// Add palette if present
|
||||
if (ase->palette.entry_count > 0) {
|
||||
JSValue palette_array = JS_NewArray(js);
|
||||
JS_ROOT(palette_array, JS_NewArray(js));
|
||||
for (int i = 0; i < ase->palette.entry_count; i++) {
|
||||
JSValue color = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, color, "r", JS_NewUint32(js, ase->palette.entries[i].color.r));
|
||||
JS_SetPropertyStr(js, color, "g", JS_NewUint32(js, ase->palette.entries[i].color.g));
|
||||
JS_SetPropertyStr(js, color, "b", JS_NewUint32(js, ase->palette.entries[i].color.b));
|
||||
JS_SetPropertyStr(js, color, "a", JS_NewUint32(js, ase->palette.entries[i].color.a));
|
||||
JS_SetPropertyUint32(js, palette_array, i, color);
|
||||
JS_ROOT(color, JS_NewObject(js));
|
||||
JS_SetPropertyStr(js, color.val, "r", JS_NewUint32(js, ase->palette.entries[i].color.r));
|
||||
JS_SetPropertyStr(js, color.val, "g", JS_NewUint32(js, ase->palette.entries[i].color.g));
|
||||
JS_SetPropertyStr(js, color.val, "b", JS_NewUint32(js, ase->palette.entries[i].color.b));
|
||||
JS_SetPropertyStr(js, color.val, "a", JS_NewUint32(js, ase->palette.entries[i].color.a));
|
||||
JS_SetPropertyNumber(js, palette_array.val, i, color.val);
|
||||
}
|
||||
JS_SetPropertyStr(js, result, "palette", palette_array);
|
||||
JS_SetPropertyStr(js, result, "palette_count", JS_NewInt32(js, ase->palette.entry_count));
|
||||
JS_SetPropertyStr(js, result.val, "palette", palette_array.val);
|
||||
JS_SetPropertyStr(js, result.val, "palette_count", JS_NewInt32(js, ase->palette.entry_count));
|
||||
}
|
||||
|
||||
|
||||
cute_aseprite_free(ase);
|
||||
return result;
|
||||
JS_RETURN(result.val);
|
||||
}
|
||||
|
||||
// Aseprite encoding
|
||||
@@ -89,19 +87,19 @@ JSValue js_aseprite_encode(JSContext *js, JSValue this_val, int argc, JSValueCon
|
||||
{
|
||||
if (argc < 1)
|
||||
return JS_ThrowTypeError(js, "encode_aseprite requires an array of frames");
|
||||
|
||||
if (!JS_IsArray(js, argv[0]))
|
||||
|
||||
if (!JS_IsArray(argv[0]))
|
||||
return JS_ThrowTypeError(js, "first argument must be an array of frame objects");
|
||||
|
||||
|
||||
// Get frame array length
|
||||
int frame_count = JS_ArrayLength(js, argv[0]);
|
||||
if (frame_count < 1)
|
||||
return JS_ThrowRangeError(js, "at least one frame is required");
|
||||
|
||||
|
||||
// Get optional parameters
|
||||
int width = 0, height = 0;
|
||||
int tile_width = 0, tile_height = 0;
|
||||
|
||||
|
||||
if (argc > 1) {
|
||||
JSValue width_val = JS_GetPropertyStr(js, argv[1], "width");
|
||||
JSValue height_val = JS_GetPropertyStr(js, argv[1], "height");
|
||||
@@ -109,7 +107,7 @@ JSValue js_aseprite_encode(JSContext *js, JSValue this_val, int argc, JSValueCon
|
||||
if (!JS_IsNull(height_val)) JS_ToInt32(js, &height, height_val);
|
||||
JS_FreeValue(js, width_val);
|
||||
JS_FreeValue(js, height_val);
|
||||
|
||||
|
||||
JSValue tile_w_val = JS_GetPropertyStr(js, argv[1], "tile_width");
|
||||
JSValue tile_h_val = JS_GetPropertyStr(js, argv[1], "tile_height");
|
||||
if (!JS_IsNull(tile_w_val)) JS_ToInt32(js, &tile_width, tile_w_val);
|
||||
@@ -117,16 +115,16 @@ JSValue js_aseprite_encode(JSContext *js, JSValue this_val, int argc, JSValueCon
|
||||
JS_FreeValue(js, tile_w_val);
|
||||
JS_FreeValue(js, tile_h_val);
|
||||
}
|
||||
|
||||
|
||||
// Allocate frames array
|
||||
ase_frame_t *frames = malloc(sizeof(ase_frame_t) * frame_count);
|
||||
if (!frames)
|
||||
return JS_ThrowOutOfMemory(js);
|
||||
|
||||
|
||||
// Process each frame
|
||||
for (int i = 0; i < frame_count; i++) {
|
||||
JSValue frame_val = JS_GetPropertyUint32(js, argv[0], i);
|
||||
|
||||
JSValue frame_val = JS_GetPropertyNumber(js, argv[0], i);
|
||||
|
||||
// Get frame dimensions
|
||||
JSValue frame_w_val = JS_GetPropertyStr(js, frame_val, "width");
|
||||
JSValue frame_h_val = JS_GetPropertyStr(js, frame_val, "height");
|
||||
@@ -140,18 +138,18 @@ JSValue js_aseprite_encode(JSContext *js, JSValue this_val, int argc, JSValueCon
|
||||
}
|
||||
JS_FreeValue(js, frame_w_val);
|
||||
JS_FreeValue(js, frame_h_val);
|
||||
|
||||
|
||||
// Set global dimensions if not specified
|
||||
if (width == 0) width = frame_w;
|
||||
if (height == 0) height = frame_h;
|
||||
|
||||
|
||||
// Get pixel data
|
||||
JSValue pixels_val = JS_GetPropertyStr(js, frame_val, "pixels");
|
||||
size_t pixel_len;
|
||||
void *pixel_data = js_get_blob_data(js, &pixel_len, pixels_val);
|
||||
JS_FreeValue(js, pixels_val);
|
||||
JS_FreeValue(js, frame_val);
|
||||
|
||||
|
||||
if (pixel_data == NULL) {
|
||||
free(frames);
|
||||
return JS_EXCEPTION;
|
||||
@@ -160,15 +158,15 @@ JSValue js_aseprite_encode(JSContext *js, JSValue this_val, int argc, JSValueCon
|
||||
free(frames);
|
||||
return JS_ThrowTypeError(js, "frame %d has no pixel data", i);
|
||||
}
|
||||
|
||||
|
||||
// Validate pixel data size
|
||||
size_t required_size = frame_w * frame_h * 4;
|
||||
if (pixel_len < required_size) {
|
||||
free(frames);
|
||||
return JS_ThrowRangeError(js, "frame %d pixel data too small (need %zu bytes, got %zu)",
|
||||
return JS_ThrowRangeError(js, "frame %d pixel data too small (need %zu bytes, got %zu)",
|
||||
i, required_size, pixel_len);
|
||||
}
|
||||
|
||||
|
||||
// Get frame duration (default 100ms)
|
||||
int duration = 100;
|
||||
JSValue duration_val = JS_GetPropertyStr(js, frame_val, "duration");
|
||||
@@ -176,7 +174,7 @@ JSValue js_aseprite_encode(JSContext *js, JSValue this_val, int argc, JSValueCon
|
||||
JS_ToInt32(js, &duration, duration_val);
|
||||
}
|
||||
JS_FreeValue(js, duration_val);
|
||||
|
||||
|
||||
// Copy pixel data and set frame info
|
||||
frames[i].pixels = malloc(required_size);
|
||||
if (!frames[i].pixels) {
|
||||
@@ -186,17 +184,17 @@ JSValue js_aseprite_encode(JSContext *js, JSValue this_val, int argc, JSValueCon
|
||||
memcpy(frames[i].pixels, pixel_data, required_size);
|
||||
frames[i].duration_milliseconds = duration;
|
||||
}
|
||||
|
||||
|
||||
// Set up aseprite structure
|
||||
ase_t ase = {0};
|
||||
ase.w = width;
|
||||
ase.h = height;
|
||||
ase.frames = frames;
|
||||
ase.frame_count = frame_count;
|
||||
|
||||
|
||||
// Note: tile dimensions would need to be handled differently in cute_aseprite
|
||||
// For now, we'll skip setting tile dimensions as they may not be supported
|
||||
|
||||
|
||||
// Save to memory (Note: cute_aseprite_save_to_memory may not be available)
|
||||
// For now, return a simple implementation
|
||||
int out_len = 0;
|
||||
@@ -205,32 +203,32 @@ JSValue js_aseprite_encode(JSContext *js, JSValue this_val, int argc, JSValueCon
|
||||
free(frames);
|
||||
return JS_ThrowOutOfMemory(js);
|
||||
}
|
||||
|
||||
|
||||
// Placeholder implementation - would need actual cute_aseprite save functionality
|
||||
memset(out_data, 0, 1024);
|
||||
out_len = 1024;
|
||||
|
||||
|
||||
// Clean up frame pixel data
|
||||
for (int i = 0; i < frame_count; i++) {
|
||||
free(frames[i].pixels);
|
||||
}
|
||||
free(frames);
|
||||
|
||||
|
||||
if (!out_data)
|
||||
return JS_ThrowInternalError(js, "failed to encode Aseprite file");
|
||||
|
||||
|
||||
// Create result object
|
||||
JSValue result = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, result, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, result, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, result, "frame_count", JS_NewInt32(js, frame_count));
|
||||
JS_SetPropertyStr(js, result, "format", JS_NewString(js, "aseprite"));
|
||||
|
||||
JSValue compressed_pixels = js_new_blob_stoned_copy(js, out_data, out_len);
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(result, JS_NewObject(js));
|
||||
JS_SetPropertyStr(js, result.val, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, result.val, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, result.val, "frame_count", JS_NewInt32(js, frame_count));
|
||||
JS_SetPropertyStr(js, result.val, "format", JS_NewString(js, "aseprite"));
|
||||
|
||||
JS_SetPropertyStr(js, result.val, "pixels", js_new_blob_stoned_copy(js, out_data, out_len));
|
||||
free(out_data);
|
||||
JS_SetPropertyStr(js, result, "pixels", compressed_pixels);
|
||||
|
||||
return result;
|
||||
|
||||
JS_RETURN(result.val);
|
||||
}
|
||||
|
||||
static const JSCFunctionListEntry js_aseprite_funcs[] = {
|
||||
|
||||
17
dxt.c
17
dxt.c
@@ -115,19 +115,20 @@ JSValue js_dxt_encode(JSContext *js, JSValue this_val, int argc, JSValueConst *a
|
||||
}
|
||||
}
|
||||
|
||||
JSValue result = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, result, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, result, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, result, "format", JS_NewString(js, get_dxt_format_string(compression_type)));
|
||||
JS_SetPropertyStr(js, result, "compression", JS_NewInt32(js, compression_type));
|
||||
JS_SetPropertyStr(js, result, "pixels", js_new_blob_stoned_copy(js, output, output_size));
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(result, JS_NewObject(js));
|
||||
JS_SetPropertyStr(js, result.val, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, result.val, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, result.val, "format", JS_NewString(js, get_dxt_format_string(compression_type)));
|
||||
JS_SetPropertyStr(js, result.val, "compression", JS_NewInt32(js, compression_type));
|
||||
JS_SetPropertyStr(js, result.val, "pixels", js_new_blob_stoned_copy(js, output, output_size));
|
||||
|
||||
free(output);
|
||||
return result;
|
||||
JS_RETURN(result.val);
|
||||
}
|
||||
|
||||
static const JSCFunctionListEntry js_dxt_funcs[] = {
|
||||
MIST_FUNC_DEF(dxt, encode, 2)
|
||||
};
|
||||
|
||||
CELL_USE_FUNCS(js_dxt_funcs)
|
||||
CELL_USE_FUNCS(js_dxt_funcs)
|
||||
|
||||
@@ -37,40 +37,41 @@ function ext_lower(path) {
|
||||
}
|
||||
|
||||
function decode_image(blob, ext) {
|
||||
switch (ext) {
|
||||
case 'png': return png.decode(blob)
|
||||
case 'jpg': case 'jpeg': return jpg.decode(blob)
|
||||
case 'bmp': return bmp.decode(blob)
|
||||
case 'tga': return tga.decode(blob)
|
||||
case 'gif': return gif.decode(blob)
|
||||
case 'psd': return psd.decode(blob)
|
||||
case 'qoi': return qoi.decode(blob)
|
||||
case 'ase': case 'aseprite': return aseprite.decode(blob)
|
||||
default:
|
||||
// Try common decoders as a fallback
|
||||
var decoders = [png.decode, jpg.decode, qoi.decode, aseprite.decode]
|
||||
for (var i = 0; i < length(decoders); i++) {
|
||||
try {
|
||||
var r = decoders[i](blob)
|
||||
if (r) return r
|
||||
} catch (e) {}
|
||||
}
|
||||
return null
|
||||
if (ext == 'png') return png.decode(blob)
|
||||
if (ext == 'jpg' || ext == 'jpeg') return jpg.decode(blob)
|
||||
if (ext == 'bmp') return bmp.decode(blob)
|
||||
if (ext == 'tga') return tga.decode(blob)
|
||||
if (ext == 'gif') return gif.decode(blob)
|
||||
if (ext == 'psd') return psd.decode(blob)
|
||||
if (ext == 'qoi') return qoi.decode(blob)
|
||||
if (ext == 'ase' || ext == 'aseprite') return aseprite.decode(blob)
|
||||
|
||||
// Try common decoders as a fallback
|
||||
var decoders = [png.decode, jpg.decode, qoi.decode, aseprite.decode]
|
||||
var i = 0
|
||||
var r = null
|
||||
var fn = function() {
|
||||
r = decoders[i](blob)
|
||||
} disruption {
|
||||
r = null
|
||||
}
|
||||
for (i = 0; i < length(decoders); i++) {
|
||||
fn()
|
||||
if (r) return r
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function encode_image(img, ext) {
|
||||
switch (ext) {
|
||||
case 'png': return png.encode(img)
|
||||
case 'jpg': case 'jpeg': return jpg.encode(img)
|
||||
case 'bmp': return bmp.encode(img)
|
||||
case 'tga': return tga.encode(img)
|
||||
case 'qoi':
|
||||
if (!img.format) img.format = "rgba32"
|
||||
return qoi.encode(img)
|
||||
default:
|
||||
return null
|
||||
if (ext == 'png') return png.encode(img)
|
||||
if (ext == 'jpg' || ext == 'jpeg') return jpg.encode(img)
|
||||
if (ext == 'bmp') return bmp.encode(img)
|
||||
if (ext == 'tga') return tga.encode(img)
|
||||
if (ext == 'qoi') {
|
||||
if (!img.format) img.format = "rgba32"
|
||||
return qoi.encode(img)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
log.console("Loading input image: " + input_file)
|
||||
|
||||
44
gif.c
44
gif.c
@@ -33,38 +33,38 @@ JSValue js_gif_decode(JSContext *js, JSValue this_val, int argc, JSValueConst *a
|
||||
int pitch = width * 4;
|
||||
size_t frame_size = pitch * height;
|
||||
|
||||
// Create frames array
|
||||
JSValue frames_array = JS_NewArray(js);
|
||||
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(frames_array, JS_NewArray(js));
|
||||
|
||||
for (int i = 0; i < frames_count; i++) {
|
||||
JSValue frame = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, frame, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, frame, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, frame, "format", JS_NewString(js, "rgba32"));
|
||||
JS_SetPropertyStr(js, frame, "pitch", JS_NewInt32(js, pitch));
|
||||
|
||||
JS_ROOT(frame, JS_NewObject(js));
|
||||
JS_SetPropertyStr(js, frame.val, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, frame.val, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, frame.val, "format", JS_NewString(js, "rgba32"));
|
||||
JS_SetPropertyStr(js, frame.val, "pitch", JS_NewInt32(js, pitch));
|
||||
|
||||
void *frame_pixels = (unsigned char*)data + (frame_size * i);
|
||||
JS_SetPropertyStr(js, frame, "pixels", js_new_blob_stoned_copy(js, frame_pixels, frame_size));
|
||||
JS_SetPropertyStr(js, frame, "depth", JS_NewInt32(js, 8));
|
||||
JS_SetPropertyStr(js, frame, "hdr", JS_NewBool(js, 0));
|
||||
|
||||
JS_SetPropertyStr(js, frame.val, "pixels", js_new_blob_stoned_copy(js, frame_pixels, frame_size));
|
||||
JS_SetPropertyStr(js, frame.val, "depth", JS_NewInt32(js, 8));
|
||||
JS_SetPropertyStr(js, frame.val, "hdr", JS_NewBool(js, 0));
|
||||
|
||||
// Add duration in milliseconds (delays are in centiseconds, i.e. 1/100th of a second)
|
||||
int duration_ms = delays ? delays[i] * 10 : 100;
|
||||
JS_SetPropertyStr(js, frame, "duration", JS_NewInt32(js, duration_ms));
|
||||
|
||||
JS_SetPropertyUint32(js, frames_array, i, frame);
|
||||
JS_SetPropertyStr(js, frame.val, "duration", JS_NewInt32(js, duration_ms));
|
||||
|
||||
JS_SetPropertyNumber(js, frames_array.val, i, frame.val);
|
||||
}
|
||||
|
||||
// Create result object
|
||||
JSValue result = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, result, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, result, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, result, "frames", frames_array);
|
||||
JS_SetPropertyStr(js, result, "frame_count", JS_NewInt32(js, frames_count));
|
||||
JS_ROOT(result, JS_NewObject(js));
|
||||
JS_SetPropertyStr(js, result.val, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, result.val, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, result.val, "frames", frames_array.val);
|
||||
JS_SetPropertyStr(js, result.val, "frame_count", JS_NewInt32(js, frames_count));
|
||||
|
||||
stbi_image_free(data);
|
||||
if (delays) stbi_image_free(delays);
|
||||
return result;
|
||||
JS_RETURN(result.val);
|
||||
}
|
||||
|
||||
static const JSCFunctionListEntry js_gif_funcs[] = {
|
||||
|
||||
32
jpg.c
32
jpg.c
@@ -25,17 +25,18 @@ JSValue js_jpg_decode(JSContext *js, JSValue this_val, int argc, JSValueConst *a
|
||||
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));
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(obj, JS_NewObject(js));
|
||||
JS_SetPropertyStr(js, obj.val, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, obj.val, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, obj.val, "format", JS_NewString(js, "rgba32"));
|
||||
JS_SetPropertyStr(js, obj.val, "pitch", JS_NewInt32(js, pitch));
|
||||
JS_SetPropertyStr(js, obj.val, "pixels", js_new_blob_stoned_copy(js, data, pixels_size));
|
||||
JS_SetPropertyStr(js, obj.val, "depth", JS_NewInt32(js, 8));
|
||||
JS_SetPropertyStr(js, obj.val, "hdr", JS_NewBool(js, 0));
|
||||
|
||||
stbi_image_free(data);
|
||||
return obj;
|
||||
JS_RETURN(obj.val);
|
||||
}
|
||||
|
||||
// JPEG encoding
|
||||
@@ -100,14 +101,15 @@ JSValue js_jpg_encode(JSContext *js, JSValue this_val, int argc, JSValueConst *a
|
||||
return JS_ThrowInternalError(js, "failed to encode JPEG");
|
||||
}
|
||||
|
||||
JSValue result = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, result, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, result, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, result, "format", JS_NewString(js, "jpg"));
|
||||
JS_SetPropertyStr(js, result, "pixels", js_new_blob_stoned_copy(js, buf.data, buf.size));
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(result, JS_NewObject(js));
|
||||
JS_SetPropertyStr(js, result.val, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, result.val, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, result.val, "format", JS_NewString(js, "jpg"));
|
||||
JS_SetPropertyStr(js, result.val, "pixels", js_new_blob_stoned_copy(js, buf.data, buf.size));
|
||||
|
||||
free(buf.data);
|
||||
return result;
|
||||
JS_RETURN(result.val);
|
||||
}
|
||||
|
||||
static const JSCFunctionListEntry js_jpg_funcs[] = {
|
||||
|
||||
32
png.c
32
png.c
@@ -25,17 +25,18 @@ JSValue js_png_decode(JSContext *js, JSValue this_val, int argc, JSValueConst *a
|
||||
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));
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(obj, JS_NewObject(js));
|
||||
JS_SetPropertyStr(js, obj.val, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, obj.val, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, obj.val, "format", JS_NewString(js, "rgba32"));
|
||||
JS_SetPropertyStr(js, obj.val, "pitch", JS_NewInt32(js, pitch));
|
||||
JS_SetPropertyStr(js, obj.val, "pixels", js_new_blob_stoned_copy(js, data, pixels_size));
|
||||
JS_SetPropertyStr(js, obj.val, "depth", JS_NewInt32(js, 8));
|
||||
JS_SetPropertyStr(js, obj.val, "hdr", JS_NewBool(js, 0));
|
||||
|
||||
stbi_image_free(data);
|
||||
return obj;
|
||||
JS_RETURN(obj.val);
|
||||
}
|
||||
|
||||
// PNG encoding
|
||||
@@ -84,14 +85,15 @@ JSValue js_png_encode(JSContext *js, JSValue this_val, int argc, JSValueConst *a
|
||||
return JS_ThrowInternalError(js, "failed to encode PNG");
|
||||
}
|
||||
|
||||
JSValue result = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, result, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, result, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, result, "format", JS_NewString(js, "png"));
|
||||
JS_SetPropertyStr(js, result, "pixels", js_new_blob_stoned_copy(js, buf.data, buf.size));
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(result, JS_NewObject(js));
|
||||
JS_SetPropertyStr(js, result.val, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, result.val, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, result.val, "format", JS_NewString(js, "png"));
|
||||
JS_SetPropertyStr(js, result.val, "pixels", js_new_blob_stoned_copy(js, buf.data, buf.size));
|
||||
|
||||
free(buf.data);
|
||||
return result;
|
||||
JS_RETURN(result.val);
|
||||
}
|
||||
|
||||
static const JSCFunctionListEntry js_png_funcs[] = {
|
||||
|
||||
19
psd.c
19
psd.c
@@ -25,17 +25,18 @@ JSValue js_psd_decode(JSContext *js, JSValue this_val, int argc, JSValueConst *a
|
||||
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));
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(obj, JS_NewObject(js));
|
||||
JS_SetPropertyStr(js, obj.val, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, obj.val, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, obj.val, "format", JS_NewString(js, "rgba32"));
|
||||
JS_SetPropertyStr(js, obj.val, "pitch", JS_NewInt32(js, pitch));
|
||||
JS_SetPropertyStr(js, obj.val, "pixels", js_new_blob_stoned_copy(js, data, pixels_size));
|
||||
JS_SetPropertyStr(js, obj.val, "depth", JS_NewInt32(js, 8));
|
||||
JS_SetPropertyStr(js, obj.val, "hdr", JS_NewBool(js, 0));
|
||||
|
||||
stbi_image_free(data);
|
||||
return obj;
|
||||
JS_RETURN(obj.val);
|
||||
}
|
||||
|
||||
static const JSCFunctionListEntry js_psd_funcs[] = {
|
||||
|
||||
88
qoi.c
88
qoi.c
@@ -19,17 +19,17 @@ JSValue js_qoi_encode(JSContext *js, JSValue this_val, int argc, JSValueConst *a
|
||||
{
|
||||
if (argc < 1)
|
||||
return JS_ThrowTypeError(js, "compress_qoi requires an object argument");
|
||||
|
||||
|
||||
// Check if width/height properties exist
|
||||
JSValue width_val = JS_GetPropertyStr(js, argv[0], "width");
|
||||
JSValue height_val = JS_GetPropertyStr(js, argv[0], "height");
|
||||
|
||||
|
||||
if (JS_IsNull(width_val) || JS_IsNull(height_val)) {
|
||||
JS_FreeValue(js, width_val);
|
||||
JS_FreeValue(js, height_val);
|
||||
return JS_ThrowTypeError(js, "compress_qoi requires width and height properties");
|
||||
}
|
||||
|
||||
|
||||
int width, height;
|
||||
if (JS_ToInt32(js, &width, width_val) < 0 || JS_ToInt32(js, &height, height_val) < 0) {
|
||||
JS_FreeValue(js, width_val);
|
||||
@@ -38,49 +38,49 @@ JSValue js_qoi_encode(JSContext *js, JSValue this_val, int argc, JSValueConst *a
|
||||
}
|
||||
JS_FreeValue(js, width_val);
|
||||
JS_FreeValue(js, height_val);
|
||||
|
||||
|
||||
if (width < 1 || height < 1)
|
||||
return JS_ThrowRangeError(js, "width and height must be at least 1");
|
||||
|
||||
|
||||
// Get pixel format
|
||||
JSValue format_val = JS_GetPropertyStr(js, argv[0], "format");
|
||||
const char *format_str = JS_ToCString(js, format_val);
|
||||
JS_FreeValue(js, format_val);
|
||||
|
||||
|
||||
if (!format_str)
|
||||
return JS_ThrowTypeError(js, "Invalid or missing pixel format");
|
||||
|
||||
|
||||
// Determine channels from format string
|
||||
int channels = 4; // Default to RGBA
|
||||
if (strstr(format_str, "rgb") && !strstr(format_str, "a")) {
|
||||
channels = 3; // RGB without alpha
|
||||
}
|
||||
|
||||
|
||||
// Get pixels
|
||||
JSValue pixels_val = JS_GetPropertyStr(js, argv[0], "pixels");
|
||||
size_t pixel_len;
|
||||
void *pixel_data = js_get_blob_data(js, &pixel_len, pixels_val);
|
||||
JS_FreeValue(js, pixels_val);
|
||||
|
||||
|
||||
if (pixel_data == NULL)
|
||||
return JS_EXCEPTION;
|
||||
if (!pixel_data)
|
||||
return JS_ThrowTypeError(js, "blob has no data");
|
||||
|
||||
|
||||
// Validate buffer size
|
||||
size_t required_size = width * height * channels;
|
||||
if (pixel_len < required_size) {
|
||||
JS_FreeCString(js, (char*)format_str);
|
||||
return JS_ThrowRangeError(js, "pixels buffer too small for %dx%d format (need %zu bytes, got %zu)",
|
||||
return JS_ThrowRangeError(js, "pixels buffer too small for %dx%d format (need %zu bytes, got %zu)",
|
||||
width, height, required_size, pixel_len);
|
||||
}
|
||||
|
||||
|
||||
// Get colorspace (optional, default to sRGB)
|
||||
int colorspace = 0; // QOI_SRGB
|
||||
if (argc > 1) {
|
||||
colorspace = JS_ToBool(js, argv[1]);
|
||||
}
|
||||
|
||||
|
||||
// Encode to QOI
|
||||
qoi_desc desc = {
|
||||
.width = width,
|
||||
@@ -88,26 +88,25 @@ JSValue js_qoi_encode(JSContext *js, JSValue this_val, int argc, JSValueConst *a
|
||||
.channels = channels,
|
||||
.colorspace = colorspace
|
||||
};
|
||||
|
||||
|
||||
int out_len;
|
||||
void *qoi_data = qoi_encode(pixel_data, &desc, &out_len);
|
||||
|
||||
|
||||
if (!qoi_data)
|
||||
return JS_ThrowInternalError(js, "QOI encoding failed");
|
||||
|
||||
|
||||
// Create result object
|
||||
JSValue result = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, result, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, result, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, result, "format", JS_NewString(js, "qoi"));
|
||||
JS_SetPropertyStr(js, result, "channels", JS_NewInt32(js, channels));
|
||||
JS_SetPropertyStr(js, result, "colorspace", JS_NewInt32(js, colorspace));
|
||||
|
||||
JSValue compressed_pixels = js_new_blob_stoned_copy(js, qoi_data, out_len);
|
||||
free(qoi_data); // Free the QOI buffer after copying to blob
|
||||
JS_SetPropertyStr(js, result, "pixels", compressed_pixels);
|
||||
|
||||
return result;
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(result, JS_NewObject(js));
|
||||
JS_SetPropertyStr(js, result.val, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, result.val, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, result.val, "format", JS_NewString(js, "qoi"));
|
||||
JS_SetPropertyStr(js, result.val, "channels", JS_NewInt32(js, channels));
|
||||
JS_SetPropertyStr(js, result.val, "colorspace", JS_NewInt32(js, colorspace));
|
||||
JS_SetPropertyStr(js, result.val, "pixels", js_new_blob_stoned_copy(js, qoi_data, out_len));
|
||||
free(qoi_data);
|
||||
|
||||
JS_RETURN(result.val);
|
||||
}
|
||||
|
||||
// QOI decompression/decoding
|
||||
@@ -120,15 +119,15 @@ JSValue js_qoi_decode(JSContext *js, JSValue this_val, int argc, JSValueConst *a
|
||||
|
||||
qoi_desc desc;
|
||||
void *data = qoi_decode(raw, len, &desc, 0); // 0 means use channels from file
|
||||
|
||||
|
||||
if (!data)
|
||||
return JS_NULL; // Return null if not valid QOI
|
||||
|
||||
|
||||
// QOI always decodes to either RGB or RGBA based on the file's channel count
|
||||
int channels = desc.channels;
|
||||
int pitch = desc.width * channels;
|
||||
size_t pixels_size = pitch * desc.height;
|
||||
|
||||
|
||||
// If it's RGB, convert to RGBA for consistency
|
||||
void *rgba_data = data;
|
||||
if (channels == 3) {
|
||||
@@ -137,7 +136,7 @@ JSValue js_qoi_decode(JSContext *js, JSValue this_val, int argc, JSValueConst *a
|
||||
free(data);
|
||||
return JS_ThrowOutOfMemory(js);
|
||||
}
|
||||
|
||||
|
||||
// Convert RGB to RGBA
|
||||
unsigned char *src = (unsigned char*)data;
|
||||
unsigned char *dst = (unsigned char*)rgba_data;
|
||||
@@ -151,20 +150,21 @@ JSValue js_qoi_decode(JSContext *js, JSValue this_val, int argc, JSValueConst *a
|
||||
pitch = desc.width * 4;
|
||||
pixels_size = pitch * desc.height;
|
||||
}
|
||||
|
||||
|
||||
// Create JS object with surface data
|
||||
JSValue obj = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, obj, "width", JS_NewInt32(js, desc.width));
|
||||
JS_SetPropertyStr(js, obj, "height", JS_NewInt32(js, desc.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, rgba_data, pixels_size));
|
||||
JS_SetPropertyStr(js, obj, "depth", JS_NewInt32(js, 8));
|
||||
JS_SetPropertyStr(js, obj, "hdr", JS_NewBool(js, 0));
|
||||
JS_SetPropertyStr(js, obj, "colorspace", JS_NewInt32(js, desc.colorspace));
|
||||
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(obj, JS_NewObject(js));
|
||||
JS_SetPropertyStr(js, obj.val, "width", JS_NewInt32(js, desc.width));
|
||||
JS_SetPropertyStr(js, obj.val, "height", JS_NewInt32(js, desc.height));
|
||||
JS_SetPropertyStr(js, obj.val, "format", JS_NewString(js, "rgba32"));
|
||||
JS_SetPropertyStr(js, obj.val, "pitch", JS_NewInt32(js, pitch));
|
||||
JS_SetPropertyStr(js, obj.val, "pixels", js_new_blob_stoned_copy(js, rgba_data, pixels_size));
|
||||
JS_SetPropertyStr(js, obj.val, "depth", JS_NewInt32(js, 8));
|
||||
JS_SetPropertyStr(js, obj.val, "hdr", JS_NewBool(js, 0));
|
||||
JS_SetPropertyStr(js, obj.val, "colorspace", JS_NewInt32(js, desc.colorspace));
|
||||
|
||||
free(rgba_data);
|
||||
return obj;
|
||||
JS_RETURN(obj.val);
|
||||
}
|
||||
|
||||
static const JSCFunctionListEntry js_qoi_funcs[] = {
|
||||
|
||||
19
resize.c
19
resize.c
@@ -101,16 +101,17 @@ JSValue js_resize_resize(JSContext *js, JSValue this_val, int argc, JSValueConst
|
||||
}
|
||||
|
||||
// Build result object
|
||||
JSValue obj = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, obj, "width", JS_NewInt32(js, dst_width));
|
||||
JS_SetPropertyStr(js, obj, "height", JS_NewInt32(js, dst_height));
|
||||
JS_SetPropertyStr(js, obj, "format", JS_NewString(js, "rgba32"));
|
||||
JS_SetPropertyStr(js, obj, "pitch", JS_NewInt32(js, dst_width * 4));
|
||||
JS_SetPropertyStr(js, obj, "pixels", js_new_blob_stoned_copy(js, dst_pixels, dst_size));
|
||||
JS_SetPropertyStr(js, obj, "depth", JS_NewInt32(js, 8));
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(obj, JS_NewObject(js));
|
||||
JS_SetPropertyStr(js, obj.val, "width", JS_NewInt32(js, dst_width));
|
||||
JS_SetPropertyStr(js, obj.val, "height", JS_NewInt32(js, dst_height));
|
||||
JS_SetPropertyStr(js, obj.val, "format", JS_NewString(js, "rgba32"));
|
||||
JS_SetPropertyStr(js, obj.val, "pitch", JS_NewInt32(js, dst_width * 4));
|
||||
JS_SetPropertyStr(js, obj.val, "pixels", js_new_blob_stoned_copy(js, dst_pixels, dst_size));
|
||||
JS_SetPropertyStr(js, obj.val, "depth", JS_NewInt32(js, 8));
|
||||
|
||||
free(dst_pixels);
|
||||
return obj;
|
||||
JS_RETURN(obj.val);
|
||||
}
|
||||
|
||||
// Convenience function to resize to fit within max dimensions while preserving aspect ratio
|
||||
@@ -192,4 +193,4 @@ static const JSCFunctionListEntry js_resize_funcs[] = {
|
||||
MIST_FUNC_DEF(resize, square, 3)
|
||||
};
|
||||
|
||||
CELL_USE_FUNCS(js_resize_funcs)
|
||||
CELL_USE_FUNCS(js_resize_funcs)
|
||||
|
||||
@@ -49,17 +49,18 @@ JSValue js_##fmt##_decode(JSContext *js, JSValue this_val, int argc, JSValueCons
|
||||
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)); \
|
||||
JS_FRAME(js); \
|
||||
JS_ROOT(obj, JS_NewObject(js)); \
|
||||
JS_SetPropertyStr(js, obj.val, "width", JS_NewInt32(js, width)); \
|
||||
JS_SetPropertyStr(js, obj.val, "height", JS_NewInt32(js, height)); \
|
||||
JS_SetPropertyStr(js, obj.val, "format", JS_NewString(js, "rgba32")); \
|
||||
JS_SetPropertyStr(js, obj.val, "pitch", JS_NewInt32(js, pitch)); \
|
||||
JS_SetPropertyStr(js, obj.val, "pixels", js_new_blob_stoned_copy(js, data, pixels_size)); \
|
||||
JS_SetPropertyStr(js, obj.val, "depth", JS_NewInt32(js, 8)); \
|
||||
JS_SetPropertyStr(js, obj.val, "hdr", JS_NewBool(js, 0)); \
|
||||
\
|
||||
stbi_image_free(data); \
|
||||
return obj; \
|
||||
JS_RETURN(obj.val); \
|
||||
}
|
||||
|
||||
#define IMAGE_ENCODER(fmt) \
|
||||
@@ -109,14 +110,15 @@ JSValue js_##fmt##_encode(JSContext *js, JSValue this_val, int argc, JSValueCons
|
||||
return JS_ThrowInternalError(js, "failed to encode " #fmt); \
|
||||
} \
|
||||
\
|
||||
JSValue result = JS_NewObject(js); \
|
||||
JS_SetPropertyStr(js, result, "width", JS_NewInt32(js, width)); \
|
||||
JS_SetPropertyStr(js, result, "height", JS_NewInt32(js, height)); \
|
||||
JS_SetPropertyStr(js, result, "format", JS_NewString(js, #fmt)); \
|
||||
JS_SetPropertyStr(js, result, "pixels", js_new_blob_stoned_copy(js, buf.data, buf.size)); \
|
||||
JS_FRAME(js); \
|
||||
JS_ROOT(result, JS_NewObject(js)); \
|
||||
JS_SetPropertyStr(js, result.val, "width", JS_NewInt32(js, width)); \
|
||||
JS_SetPropertyStr(js, result.val, "height", JS_NewInt32(js, height)); \
|
||||
JS_SetPropertyStr(js, result.val, "format", JS_NewString(js, #fmt)); \
|
||||
JS_SetPropertyStr(js, result.val, "pixels", js_new_blob_stoned_copy(js, buf.data, buf.size)); \
|
||||
\
|
||||
free(buf.data); \
|
||||
return result; \
|
||||
JS_RETURN(result.val); \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
32
tga.c
32
tga.c
@@ -25,17 +25,18 @@ JSValue js_tga_decode(JSContext *js, JSValue this_val, int argc, JSValueConst *a
|
||||
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));
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(obj, JS_NewObject(js));
|
||||
JS_SetPropertyStr(js, obj.val, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, obj.val, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, obj.val, "format", JS_NewString(js, "rgba32"));
|
||||
JS_SetPropertyStr(js, obj.val, "pitch", JS_NewInt32(js, pitch));
|
||||
JS_SetPropertyStr(js, obj.val, "pixels", js_new_blob_stoned_copy(js, data, pixels_size));
|
||||
JS_SetPropertyStr(js, obj.val, "depth", JS_NewInt32(js, 8));
|
||||
JS_SetPropertyStr(js, obj.val, "hdr", JS_NewBool(js, 0));
|
||||
|
||||
stbi_image_free(data);
|
||||
return obj;
|
||||
JS_RETURN(obj.val);
|
||||
}
|
||||
|
||||
// TGA encoding
|
||||
@@ -85,14 +86,15 @@ JSValue js_tga_encode(JSContext *js, JSValue this_val, int argc, JSValueConst *a
|
||||
return JS_ThrowInternalError(js, "failed to encode TGA");
|
||||
}
|
||||
|
||||
JSValue result = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, result, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, result, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, result, "format", JS_NewString(js, "tga"));
|
||||
JS_SetPropertyStr(js, result, "pixels", js_new_blob_stoned_copy(js, buf.data, buf.size));
|
||||
JS_FRAME(js);
|
||||
JS_ROOT(result, JS_NewObject(js));
|
||||
JS_SetPropertyStr(js, result.val, "width", JS_NewInt32(js, width));
|
||||
JS_SetPropertyStr(js, result.val, "height", JS_NewInt32(js, height));
|
||||
JS_SetPropertyStr(js, result.val, "format", JS_NewString(js, "tga"));
|
||||
JS_SetPropertyStr(js, result.val, "pixels", js_new_blob_stoned_copy(js, buf.data, buf.size));
|
||||
|
||||
free(buf.data);
|
||||
return result;
|
||||
JS_RETURN(result.val);
|
||||
}
|
||||
|
||||
static const JSCFunctionListEntry js_tga_funcs[] = {
|
||||
|
||||
Reference in New Issue
Block a user