aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarry Jeffery <harry@exec64.co.uk>2019-02-02 23:44:22 +0000
committerHarry Jeffery <harry@exec64.co.uk>2019-02-02 23:44:22 +0000
commit09928120e31edbfa63791f0c2f5e14374ae518de (patch)
tree22d2b402fa8ad1ab0279690df99b9328619a8e3c
parent469435f4697c2797fa16a8404b5dad4722947b11 (diff)
downloadimv-09928120e31edbfa63791f0c2f5e14374ae518de.tar.gz
rsvg: Add open_memory support
-rw-r--r--src/backend_librsvg.c62
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)