freeimage: Fix 16-bit greyscale images and add logging

This commit is contained in:
Harry Jeffery 2019-08-14 19:10:40 +01:00
parent 77e59235fe
commit ff2e28f250

View file

@ -1,6 +1,7 @@
#include "backend_freeimage.h" #include "backend_freeimage.h"
#include "backend.h" #include "backend.h"
#include "source.h" #include "source.h"
#include "log.h"
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
@ -60,15 +61,52 @@ static struct imv_image *to_image(FIBITMAP *in_bmp)
return image; return image;
} }
static void report_error(struct imv_source *src) static FIBITMAP *normalise_bitmap(FIBITMAP *input)
{ {
FIBITMAP *output = NULL;
switch (FreeImage_GetImageType(input)) {
case FIT_RGB16:
case FIT_RGBA16:
case FIT_RGBF:
case FIT_RGBAF:
output = FreeImage_ConvertTo32Bits(input);
FreeImage_Unload(input);
break;
case FIT_UINT16:
case FIT_INT16:
case FIT_UINT32:
case FIT_INT32:
case FIT_FLOAT:
case FIT_DOUBLE:
case FIT_COMPLEX:
output = FreeImage_ConvertTo8Bits(input);
FreeImage_Unload(input);
break;
case FIT_BITMAP:
default:
output = input;
}
imv_log(IMV_DEBUG,
"freeimage: bitmap normalised to 32 bits: before=%p after=%p\n",
input, output);
return output;
}
static void report_error(struct imv_source *src, const char *error)
{
imv_log(IMV_ERROR, "freeimage: %s\n", error);
assert(src->callback); assert(src->callback);
struct imv_source_message msg; struct imv_source_message msg;
msg.source = src; msg.source = src;
msg.user_data = src->user_data; msg.user_data = src->user_data;
msg.image = NULL; msg.image = NULL;
msg.error = "Internal error"; msg.error = error;
pthread_mutex_unlock(&src->busy); pthread_mutex_unlock(&src->busy);
src->callback(&msg); src->callback(&msg);
@ -76,6 +114,7 @@ static void report_error(struct imv_source *src)
static void send_bitmap(struct imv_source *src, FIBITMAP *fibitmap, int frametime) static void send_bitmap(struct imv_source *src, FIBITMAP *fibitmap, int frametime)
{ {
imv_log(IMV_DEBUG, "freeimage: returning bitmap\n");
assert(src->callback); assert(src->callback);
struct imv_source_message msg; struct imv_source_message msg;
@ -95,6 +134,7 @@ static void *first_frame(struct imv_source *src)
if (pthread_mutex_trylock(&src->busy)) { if (pthread_mutex_trylock(&src->busy)) {
return NULL; return NULL;
} }
imv_log(IMV_DEBUG, "freeimage: first_frame called\n");
FIBITMAP *bmp = NULL; FIBITMAP *bmp = NULL;
@ -114,12 +154,12 @@ static void *first_frame(struct imv_source *src)
private->memory, private->memory,
/* flags */ GIF_LOAD256); /* flags */ GIF_LOAD256);
} else { } else {
report_error(src); report_error(src, "src->name and private->memory both NULL");
return NULL; return NULL;
} }
if (!private->multibitmap) { if (!private->multibitmap) {
report_error(src); report_error(src, "first frame already loaded");
return NULL; return NULL;
} }
@ -148,11 +188,11 @@ static void *first_frame(struct imv_source *src)
fibitmap = FreeImage_LoadFromMemory(private->format, private->memory, flags); fibitmap = FreeImage_LoadFromMemory(private->format, private->memory, flags);
} }
if (!fibitmap) { if (!fibitmap) {
report_error(src); report_error(src, "FreeImage_Load returned NULL");
return NULL; return NULL;
} }
bmp = FreeImage_ConvertTo32Bits(fibitmap);
FreeImage_Unload(fibitmap); bmp = normalise_bitmap(fibitmap);
} }
src->width = FreeImage_GetWidth(bmp); src->width = FreeImage_GetWidth(bmp);
@ -263,9 +303,11 @@ static void *next_frame(struct imv_source *src)
static enum backend_result open_path(const char *path, struct imv_source **src) static enum backend_result open_path(const char *path, struct imv_source **src)
{ {
imv_log(IMV_DEBUG, "freeimage: open_path(%s)\n", path);
FREE_IMAGE_FORMAT fmt = FreeImage_GetFileType(path, 0); FREE_IMAGE_FORMAT fmt = FreeImage_GetFileType(path, 0);
if (fmt == FIF_UNKNOWN) { if (fmt == FIF_UNKNOWN) {
imv_log(IMV_DEBUG, "freeimage: unknown file format\n");
return BACKEND_UNSUPPORTED; return BACKEND_UNSUPPORTED;
} }