diff options
author | Harry Jeffery <harry@exec64.co.uk> | 2019-02-02 23:44:22 +0000 |
---|---|---|
committer | Harry Jeffery <harry@exec64.co.uk> | 2019-02-02 23:44:22 +0000 |
commit | 09928120e31edbfa63791f0c2f5e14374ae518de (patch) | |
tree | 22d2b402fa8ad1ab0279690df99b9328619a8e3c | |
parent | 469435f4697c2797fa16a8404b5dad4722947b11 (diff) | |
download | imv-09928120e31edbfa63791f0c2f5e14374ae518de.tar.gz |
rsvg: Add open_memory support
-rw-r--r-- | src/backend_librsvg.c | 62 |
1 files changed, 58 insertions, 4 deletions
diff --git a/src/backend_librsvg.c b/src/backend_librsvg.c index 2a08deb..083fb9c 100644 --- a/src/backend_librsvg.c +++ b/src/backend_librsvg.c @@ -14,11 +14,20 @@ #define PATH_MAX 4096 #endif +struct private { + void *data; + size_t len; +}; + static void source_free(struct imv_source *src) { free(src->name); src->name = NULL; + struct private *private = src->private; + free(private); + src->private = NULL; + free(src); } @@ -72,10 +81,18 @@ static void send_bitmap(struct imv_source *src, GdkPixbuf *bitmap) static void load_image(struct imv_source *src) { + RsvgHandle *handle = NULL; GError *error = NULL; - char path[PATH_MAX+8]; - snprintf(path, sizeof path, "file://%s", src->name); - RsvgHandle *handle = rsvg_handle_new_from_file(path, &error); + + struct private *private = src->private; + if (private->data) { + handle = rsvg_handle_new_from_data(private->data, private->len, &error); + } else { + char path[PATH_MAX+8]; + snprintf(path, sizeof path, "file://%s", src->name); + handle = rsvg_handle_new_from_file(path, &error); + } + if (!handle) { report_error(src); return; @@ -113,6 +130,10 @@ static enum backend_result open_path(const char *path, struct imv_source **src) return BACKEND_UNSUPPORTED; } + struct private *private = malloc(sizeof(struct private)); + private->data = NULL; + private->len = 0; + struct imv_source *source = calloc(1, sizeof(struct imv_source)); source->name = strdup(path); @@ -125,7 +146,39 @@ static enum backend_result open_path(const char *path, struct imv_source **src) source->free = &source_free; source->callback = NULL; source->user_data = NULL; - source->private = NULL; + source->private = private; + + *src = source; + return BACKEND_SUCCESS; +} + +static enum backend_result open_memory(void *data, size_t len, struct imv_source **src) +{ + /* Look for an <SVG> tag near the start of the file */ + char header[128]; + memcpy(header, data, sizeof header); + header[(sizeof header) - 1] = 0; + if (!strstr(header, "<SVG") && !strstr(header, "<svg")) { + return BACKEND_UNSUPPORTED; + } + + struct private *private = malloc(sizeof(struct private)); + private->data = data; + private->len = len; + + struct imv_source *source = calloc(1, sizeof(struct imv_source)); + source->name = strdup("-"); + + 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 = private; *src = source; return BACKEND_SUCCESS; @@ -137,6 +190,7 @@ const struct imv_backend librsvg_backend = { .website = "https://wiki.gnome.org/Projects/LibRsvg", .license = "Lesser GNU Public License", .open_path = &open_path, + .open_memory = &open_memory, }; const struct imv_backend *imv_backend_librsvg(void) |