From 4d74ab1be3430e713748ec93ebd919a1fc2f2b78 Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Tue, 29 Jan 2019 22:19:00 +0000 Subject: FreeImage: Add open_memory support --- src/backend_freeimage.c | 65 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/src/backend_freeimage.c b/src/backend_freeimage.c index 0032e31..8a24725 100644 --- a/src/backend_freeimage.c +++ b/src/backend_freeimage.c @@ -11,6 +11,7 @@ #include struct private { + FIMEMORY *memory; FREE_IMAGE_FORMAT format; FIMULTIBITMAP *multibitmap; FIBITMAP *last_frame; @@ -23,6 +24,11 @@ static void source_free(struct imv_source *src) struct private *private = src->private; + if (private->memory) { + FreeImage_CloseMemory(private->memory); + private->memory = NULL; + } + if (private->multibitmap) { FreeImage_CloseMultiBitmap(private->multibitmap, 0); private->multibitmap = NULL; @@ -95,11 +101,21 @@ static void first_frame(struct imv_source *src) int frametime = 0; if (private->format == FIF_GIF) { - private->multibitmap = FreeImage_OpenMultiBitmap(FIF_GIF, src->name, - /* don't create file */ 0, - /* read only */ 1, - /* keep in memory */ 1, - /* flags */ GIF_LOAD256); + if (src->name) { + private->multibitmap = FreeImage_OpenMultiBitmap(FIF_GIF, src->name, + /* don't create file */ 0, + /* read only */ 1, + /* keep in memory */ 1, + /* flags */ GIF_LOAD256); + } else if (private->memory) { + private->multibitmap = FreeImage_LoadMultiBitmapFromMemory(FIF_GIF, + private->memory, + /* flags */ GIF_LOAD256); + } else { + report_error(src); + return; + } + if (!private->multibitmap) { report_error(src); return; @@ -123,7 +139,12 @@ static void first_frame(struct imv_source *src) } else { /* not a gif */ src->num_frames = 1; int flags = (private->format == FIF_JPEG) ? JPEG_EXIFROTATE : 0; - FIBITMAP *fibitmap = FreeImage_Load(private->format, src->name, flags); + FIBITMAP *fibitmap = NULL; + if (src->name) { + fibitmap = FreeImage_Load(private->format, src->name, flags); + } else if (private->memory) { + fibitmap = FreeImage_LoadFromMemory(private->format, private->memory, flags); + } if (!fibitmap) { report_error(src); return; @@ -258,12 +279,44 @@ static enum backend_result open_path(const char *path, struct imv_source **src) return BACKEND_SUCCESS; } +static enum backend_result open_memory(void *data, size_t len, struct imv_source **src) +{ + FIMEMORY *fmem = FreeImage_OpenMemory(data, len); + + FREE_IMAGE_FORMAT fmt = FreeImage_GetFileTypeFromMemory(fmem, 0); + + if (fmt == FIF_UNKNOWN) { + FreeImage_CloseMemory(fmem); + return BACKEND_UNSUPPORTED; + } + + struct private *private = calloc(sizeof(struct private), 1); + private->format = fmt; + private->memory = fmem; + + struct imv_source *source = calloc(sizeof(struct imv_source), 1); + source->name = NULL; + source->width = 0; + source->height = 0; + source->num_frames = 0; + source->load_first_frame = &first_frame; + source->load_next_frame = &next_frame; + source->free = &source_free; + source->callback = NULL; + source->user_data = NULL; + source->private = private; + *src = source; + + return BACKEND_SUCCESS; +} + const struct imv_backend freeimage_backend = { .name = "FreeImage", .description = "Open source image library supporting a large number of formats", .website = "http://freeimage.sourceforge.net/", .license = "FreeImage Public License v1.0", .open_path = &open_path, + .open_memory = &open_memory, }; const struct imv_backend *imv_backend_freeimage(void) -- cgit v1.2.3