From c65f6f49039885856ad823dcbe2e8fd3fe2c8210 Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Mon, 21 Jan 2019 22:19:16 +0000 Subject: Make backends optional --- src/backend_freeimage.c | 11 ++++ src/backend_libpng.c | 12 +++- src/backend_librsvg.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++ src/backend_librsvg.h | 9 +++ src/backend_rsvg.c | 141 -------------------------------------------- src/backend_rsvg.h | 9 --- src/main.c | 13 +++- 7 files changed, 196 insertions(+), 153 deletions(-) create mode 100644 src/backend_librsvg.c create mode 100644 src/backend_librsvg.h delete mode 100644 src/backend_rsvg.c delete mode 100644 src/backend_rsvg.h (limited to 'src') diff --git a/src/backend_freeimage.c b/src/backend_freeimage.c index 8849922..9443075 100644 --- a/src/backend_freeimage.c +++ b/src/backend_freeimage.c @@ -6,6 +6,8 @@ #include #include +#ifdef IMV_BACKEND_FREEIMAGE + #include struct private { @@ -269,3 +271,12 @@ struct imv_backend *imv_backend_freeimage(void) backend->free = &backend_free; return backend; } + +#else + +struct imv_backend *imv_backend_freeimage(void) +{ + return NULL; +} + +#endif diff --git a/src/backend_libpng.c b/src/backend_libpng.c index 20606b4..d5a2676 100644 --- a/src/backend_libpng.c +++ b/src/backend_libpng.c @@ -1,12 +1,13 @@ #include "backend_libpng.h" #include "backend.h" #include "source.h" - #include #include #include #include +#ifdef IMV_BACKEND_LIBPNG + #include struct private { @@ -191,3 +192,12 @@ struct imv_backend *imv_backend_libpng(void) backend->free = &backend_free; return backend; } + +#else + +struct imv_backend *imv_backend_libpng(void) +{ + return NULL; +} + +#endif diff --git a/src/backend_librsvg.c b/src/backend_librsvg.c new file mode 100644 index 0000000..416743a --- /dev/null +++ b/src/backend_librsvg.c @@ -0,0 +1,154 @@ +#include "backend_librsvg.h" +#include "backend.h" +#include "source.h" + +#include + +#ifdef IMV_BACKEND_LIBRSVG + +#include + +/* Some systems like GNU/Hurd don't define PATH_MAX */ +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + +static void source_free(struct imv_source *src) +{ + free(src->name); + src->name = NULL; + + free(src); +} + +static struct imv_bitmap *to_imv_bitmap(GdkPixbuf *bitmap) +{ + struct imv_bitmap *bmp = malloc(sizeof(struct imv_bitmap)); + bmp->width = gdk_pixbuf_get_width(bitmap); + bmp->height = gdk_pixbuf_get_height(bitmap); + bmp->format = IMV_ARGB; + size_t len = bmp->width * bmp->height * 4; + bmp->data = malloc(len); + memcpy(bmp->data, gdk_pixbuf_get_pixels(bitmap), len); + return bmp; +} + +static void report_error(struct imv_source *src) +{ + if (!src->callback) { + fprintf(stderr, "imv_source(%s) has no callback configured. " + "Discarding error.\n", src->name); + return; + } + + struct imv_source_message msg; + msg.source = src; + msg.user_data = src->user_data; + msg.bitmap = NULL; + msg.error = "Internal error"; + + src->callback(&msg); +} + + +static void send_bitmap(struct imv_source *src, GdkPixbuf *bitmap) +{ + if (!src->callback) { + fprintf(stderr, "imv_source(%s) has no callback configured. " + "Discarding result.\n", src->name); + return; + } + + struct imv_source_message msg; + msg.source = src; + msg.user_data = src->user_data; + msg.bitmap = to_imv_bitmap(bitmap); + msg.frametime = 0; + msg.error = NULL; + + src->callback(&msg); +} + +static void load_image(struct imv_source *src) +{ + GError *error; + char path[PATH_MAX+8]; + snprintf(path, sizeof path, "file://%s", src->name); + RsvgHandle *handle = rsvg_handle_new_from_file(path, &error); + if (!handle) { + report_error(src); + return; + } + + RsvgDimensionData dim; + rsvg_handle_get_dimensions(handle, &dim); + src->width = dim.width; + src->height = dim.height; + + GdkPixbuf *buf = rsvg_handle_get_pixbuf(handle); + if (!buf) { + rsvg_handle_close(handle, &error); + report_error(src); + return; + } + + rsvg_handle_close(handle, &error); + send_bitmap(src, buf); +} + +static enum backend_result open_path(const char *path, struct imv_source **src) +{ + /* Look for an tag near the start of the file */ + char header[128]; + FILE *f = fopen(path, "rb"); + if (!f) { + return BACKEND_BAD_PATH; + } + fread(header, 1, sizeof header, f); + fclose(f); + + header[(sizeof header) - 1] = 0; + if (!strstr(header, "name = strdup(path); + + source->width = 1024; + source->height = 1024; + source->num_frames = 1; + source->next_frame = 1; + source->load_first_frame = &load_image; + source->load_next_frame = NULL; + source->free = &source_free; + source->callback = NULL; + source->user_data = NULL; + source->private = NULL; + + *src = source; + return BACKEND_SUCCESS; +} + +static void backend_free(struct imv_backend *backend) +{ + free(backend); +} + +struct imv_backend *imv_backend_librsvg(void) +{ + struct imv_backend *backend = malloc(sizeof(struct imv_backend)); + backend->name = "librsvg (LGPL license)"; + backend->open_path = &open_path; + backend->free = &backend_free; + return backend; +} + +#else + +struct imv_backend *imv_backend_librsvg(void) +{ + return NULL; +} + +#endif diff --git a/src/backend_librsvg.h b/src/backend_librsvg.h new file mode 100644 index 0000000..16dd6c8 --- /dev/null +++ b/src/backend_librsvg.h @@ -0,0 +1,9 @@ +#ifndef IMV_BACKEND_RSVG_H +#define IMV_BACKEND_RSVG_H + +struct imv_backend; + +/* Create an instance of the rsvg backend */ +struct imv_backend *imv_backend_librsvg(void); + +#endif diff --git a/src/backend_rsvg.c b/src/backend_rsvg.c deleted file mode 100644 index f259e5c..0000000 --- a/src/backend_rsvg.c +++ /dev/null @@ -1,141 +0,0 @@ -#include "backend_rsvg.h" -#include "backend.h" -#include "source.h" - -#include - -/* Some systems like GNU/Hurd don't define PATH_MAX */ -#ifndef PATH_MAX -#define PATH_MAX 4096 -#endif - -static void source_free(struct imv_source *src) -{ - free(src->name); - src->name = NULL; - - free(src); -} - -static struct imv_bitmap *to_imv_bitmap(GdkPixbuf *bitmap) -{ - struct imv_bitmap *bmp = malloc(sizeof(struct imv_bitmap)); - bmp->width = gdk_pixbuf_get_width(bitmap); - bmp->height = gdk_pixbuf_get_height(bitmap); - bmp->format = IMV_ARGB; - size_t len = bmp->width * bmp->height * 4; - bmp->data = malloc(len); - memcpy(bmp->data, gdk_pixbuf_get_pixels(bitmap), len); - return bmp; -} - -static void report_error(struct imv_source *src) -{ - if (!src->callback) { - fprintf(stderr, "imv_source(%s) has no callback configured. " - "Discarding error.\n", src->name); - return; - } - - struct imv_source_message msg; - msg.source = src; - msg.user_data = src->user_data; - msg.bitmap = NULL; - msg.error = "Internal error"; - - src->callback(&msg); -} - - -static void send_bitmap(struct imv_source *src, GdkPixbuf *bitmap) -{ - if (!src->callback) { - fprintf(stderr, "imv_source(%s) has no callback configured. " - "Discarding result.\n", src->name); - return; - } - - struct imv_source_message msg; - msg.source = src; - msg.user_data = src->user_data; - msg.bitmap = to_imv_bitmap(bitmap); - msg.frametime = 0; - msg.error = NULL; - - src->callback(&msg); -} - -static void load_image(struct imv_source *src) -{ - GError *error; - char path[PATH_MAX+8]; - snprintf(path, sizeof path, "file://%s", src->name); - RsvgHandle *handle = rsvg_handle_new_from_file(path, &error); - if (!handle) { - report_error(src); - return; - } - - RsvgDimensionData dim; - rsvg_handle_get_dimensions(handle, &dim); - src->width = dim.width; - src->height = dim.height; - - GdkPixbuf *buf = rsvg_handle_get_pixbuf(handle); - if (!buf) { - rsvg_handle_close(handle, &error); - report_error(src); - return; - } - - rsvg_handle_close(handle, &error); - send_bitmap(src, buf); -} - -static enum backend_result open_path(const char *path, struct imv_source **src) -{ - /* Look for an tag near the start of the file */ - char header[128]; - FILE *f = fopen(path, "rb"); - if (!f) { - return BACKEND_BAD_PATH; - } - fread(header, 1, sizeof header, f); - fclose(f); - - header[(sizeof header) - 1] = 0; - if (!strstr(header, "name = strdup(path); - - source->width = 1024; - source->height = 1024; - source->num_frames = 1; - source->next_frame = 1; - source->load_first_frame = &load_image; - source->load_next_frame = NULL; - source->free = &source_free; - source->callback = NULL; - source->user_data = NULL; - source->private = NULL; - - *src = source; - return BACKEND_SUCCESS; -} - -static void backend_free(struct imv_backend *backend) -{ - free(backend); -} - -struct imv_backend *imv_backend_rsvg(void) -{ - struct imv_backend *backend = malloc(sizeof(struct imv_backend)); - backend->name = "rsvg (LGPL license)"; - backend->open_path = &open_path; - backend->free = &backend_free; - return backend; -} diff --git a/src/backend_rsvg.h b/src/backend_rsvg.h deleted file mode 100644 index 126892a..0000000 --- a/src/backend_rsvg.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef IMV_BACKEND_RSVG_H -#define IMV_BACKEND_RSVG_H - -struct imv_backend; - -/* Create an instance of the rsvg backend */ -struct imv_backend *imv_backend_rsvg(void); - -#endif diff --git a/src/main.c b/src/main.c index 8b88340..06baced 100644 --- a/src/main.c +++ b/src/main.c @@ -1,9 +1,10 @@ #include "imv.h" #include "backend.h" + #include "backend_freeimage.h" #include "backend_libpng.h" -#include "backend_rsvg.h" +#include "backend_librsvg.h" int main(int argc, char** argv) { @@ -13,9 +14,17 @@ int main(int argc, char** argv) return 1; } - imv_install_backend(imv, imv_backend_rsvg()); +#ifdef IMV_BACKEND_FREEIMAGE imv_install_backend(imv, imv_backend_freeimage()); +#endif + +#ifdef IMV_BACKEND_LIBPNG imv_install_backend(imv, imv_backend_libpng()); +#endif + +#ifdef IMV_BACKEND_LIBRSVG + imv_install_backend(imv, imv_backend_librsvg()); +#endif if(!imv_load_config(imv)) { imv_free(imv); -- cgit v1.2.3