packages feed

libheif-hs-0.1.0.0: cbits/heif_context_write_shim.c

#include <libheif/heif.h>

// Why this file: Haskell cannot marshal FFI functions that return a struct, and the decoder takes 
// a callback that returns a heif_error. This is a helper to address this limitations of the FFI

// Define the simpler signature for your Haskell callback (returns int, not struct)
typedef int (*hs_write_callback)(struct heif_context* ctx, const void* data, size_t size, void* userdata);

// The C trampoline that libheif will actually execute
static struct heif_error c_trampoline(struct heif_context* ctx, const void* data, size_t size, void* userdata) {
    // We expect Haskell to pass its FunPtr inside the userdata parameter!
    hs_write_callback hs_cb = (hs_write_callback)userdata;
    
    // Execute Haskell callback
    int hs_status = hs_cb(ctx, data, size, userdata);
    
    // Wrap the integer result into the struct by value
    struct heif_error err;
    if (hs_status == 0) {
        err.code = heif_error_Ok;
        err.subcode = heif_suberror_Unspecified;
        err.message = 0;
    } else {
        err.code = heif_error_Encoding_error;
        err.subcode = heif_suberror_Unspecified;
        err.message = "Error in Haskell writer callback";
    }
    return err;
}

// Expose the pointer to this C function so Haskell can plug it into heif_writer
void* get_c_trampoline_ptr() {
    return (void*)c_trampoline;
}