diff --git a/.gitignore b/.gitignore index 7de21ec..e4d3690 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.png -*.so \ No newline at end of file +*.so +*.gif \ No newline at end of file diff --git a/Makefile b/Makefile index 015be88..4b7ab33 100644 --- a/Makefile +++ b/Makefile @@ -1,2 +1,2 @@ libguilecgif.so: guile-cgif.c - $(CC) `pkg-config --cflags cgif cairo guile-3.0` -shared -fPIC -o $@ $^ `pkg-config --libs cgif cairo guile-3.0` + $(CC) `pkg-config --cflags cgif guile-cairo` -g -shared -fPIC -o $@ $^ `pkg-config --libs cgif guile-cairo` diff --git a/cgif.scm b/cgif.scm index b553293..1f4608d 100644 --- a/cgif.scm +++ b/cgif.scm @@ -1,4 +1,4 @@ (define-module (cgif) :export (make-gif)) -(load-extension "./libguilecgif", "init_cgif") +(load-extension "./libguilecgif" "init_cgif") diff --git a/graphgif.scm b/graphgif.scm index 80274ba..36eb38a 100644 --- a/graphgif.scm +++ b/graphgif.scm @@ -1,6 +1,7 @@ (define-module (graphgif)) -(use-modules (cairo)) +(use-modules (cairo) + (cgif)) (re-export (cairo-pattern-create-rgb . create-color)) @@ -44,7 +45,7 @@ (cairo-stroke cr)))) (define-public (draw-abstract-graph graph) - (let* ([surface (cairo-image-surface-create 'argb32 400 400)] + (let* ([surface (cairo-image-surface-create 'rgb24 400 400)] [cr (cairo-create surface)]) (define paint-edges (edge-painter cr graph)) (define paint-nodes (node-painter cr)) @@ -59,7 +60,7 @@ (define-public (write-graph-to-file graph filename) (define my-surface (draw-abstract-graph graph)) - (cairo-surface-write-to-png my-surface filename) + (make-gif `(,my-surface) filename) (cairo-surface-destroy my-surface)) diff --git a/guile-cgif.c b/guile-cgif.c index 9e3f3bc..91e2393 100644 --- a/guile-cgif.c +++ b/guile-cgif.c @@ -1,7 +1,7 @@ #include -#include +#include #include -#include +#include const uint8_t PALETTE[] = { 0xFF, 0xFF, 0xFF, // WHITE @@ -9,8 +9,8 @@ const uint8_t PALETTE[] = { 0xFF, 0x00, 0x00 // RED }; -#define CAIRO_RED 0x00FF0000 -#define CAIRO_BLACK 0x00FFFFFF +#define CAIRO_RED 0x00FF0000 +#define CAIRO_BLACK 0x00000000 void encode_frame(cairo_surface_t *surface, CGIF_FrameConfig *frameconfig) { // TODO pull colors from cairo @@ -20,10 +20,10 @@ void encode_frame(cairo_surface_t *surface, CGIF_FrameConfig *frameconfig) { frameconfig->pImageData = (uint8_t*)calloc(size, sizeof(uint8_t)); if (cairo_image_surface_get_format(surface) == CAIRO_FORMAT_RGB24) { - unsigned char* pen = cairo_image_surface_get_data(surface); + uint32_t* pen = (uint32_t*) cairo_image_surface_get_data(surface); for (size_t i = 0; i < size; i++) { - uint32_t cairo_color = (uint32_t)(*(pen + i * sizeof(uint32_t) * cairo_image_surface_get_stride(surface))); - switch (cairo_color) { + uint32_t cairo_color = pen[i]; + switch (cairo_color & 0x00FFFFFF) { case CAIRO_BLACK: frameconfig->pImageData[i] = 1; break; @@ -37,6 +37,7 @@ void encode_frame(cairo_surface_t *surface, CGIF_FrameConfig *frameconfig) { void make_gif_inner(cairo_surface_t *frames[], size_t n_frames, const char* path) { CGIF_Config cgif_config; + memset(&cgif_config, 0, sizeof(CGIF_Config)); cgif_config.path = path; cgif_config.attrFlags = CGIF_ATTR_IS_ANIMATED | CGIF_ATTR_NO_GLOBAL_TABLE; cgif_config.width = cairo_image_surface_get_width(frames[0]); @@ -50,6 +51,7 @@ void make_gif_inner(cairo_surface_t *frames[], size_t n_frames, const char* path cairo_surface_flush(frame); CGIF_FrameConfig cgif_frameconfig; + memset(&cgif_frameconfig, 0, sizeof(CGIF_FrameConfig)); cgif_frameconfig.attrFlags = CGIF_FRAME_ATTR_USE_LOCAL_TABLE; cgif_frameconfig.delay = 100; @@ -60,16 +62,16 @@ void make_gif_inner(cairo_surface_t *frames[], size_t n_frames, const char* path cgif_close(cgif); } -void make_gif(SCM frames, SCM path) { - size_t c_length = scm_c_array_length(frames); - scm_t_array_handle c_array; - scm_array_get_handle(frames, &c_array); - cairo_surface_t **c_frames = scm_array_handle_uniform_elements(&c_array); +SCM make_gif(SCM frames, SCM path) { + size_t n_frames = scm_to_size_t(scm_length(frames)); + cairo_surface_t **c_frames = (cairo_surface_t **) malloc(sizeof(cairo_surface_t*) * n_frames); + for (size_t i = 0; i < n_frames; i++) { + c_frames[i] = scm_to_cairo_surface(scm_list_ref(frames, scm_from_size_t(i))); + } const char* c_path = scm_to_locale_string(path); - make_gif_inner(c_frames, c_length, c_path); - - scm_array_handle_release(&c_array); + make_gif_inner(c_frames, n_frames, c_path); + return SCM_UNSPECIFIED; } void init_cgif() {