diff --git a/src/backend_libtiff.c b/src/backend_libtiff.c index 4a0f9cd..6d196b8 100644 --- a/src/backend_libtiff.c +++ b/src/backend_libtiff.c @@ -57,6 +57,22 @@ static void free_private(void *raw_private) free(private); } +static uint8_t *convert_tiff_bitmap_to_rgba_inplace( + uint32_t *bitmap, size_t len) +{ + uint8_t *buf = (uint8_t *)bitmap; + + for (size_t i = 0; i < len; i++) { + uint32_t tmp = bitmap[i]; + buf[4 * i + 0] = TIFFGetR(tmp); + buf[4 * i + 1] = TIFFGetG(tmp); + buf[4 * i + 2] = TIFFGetB(tmp); + buf[4 * i + 3] = TIFFGetA(tmp); + } + + return buf; +} + static void load_image(void *raw_private, struct imv_image **image, int *frametime) { *image = NULL; @@ -81,7 +97,8 @@ static void load_image(void *raw_private, struct imv_image **image, int *frameti struct imv_bitmap *bmp = malloc(sizeof *bmp); bmp->width = private->width; bmp->height = private->height; - bmp->data = bitmap; + bmp->data = convert_tiff_bitmap_to_rgba_inplace( + bitmap, imv_bitmap_size(bmp) / sizeof(uint32_t)); *image = imv_image_create_from_bitmap(bmp); } diff --git a/src/bitmap.c b/src/bitmap.c index 9f84052..45483fb 100644 --- a/src/bitmap.c +++ b/src/bitmap.c @@ -1,7 +1,15 @@ #include "bitmap.h" +#include +#include #include +size_t imv_bitmap_size(struct imv_bitmap* bmp) +{ + assert((size_t)bmp->width <= SIZE_MAX / bmp->height / BYTES_PER_CHANNEL); + return (size_t)bmp->width * bmp->height * BYTES_PER_CHANNEL; +} + void imv_bitmap_free(struct imv_bitmap *bmp) { free(bmp->data); diff --git a/src/bitmap.h b/src/bitmap.h index 87591d1..9d1dcca 100644 --- a/src/bitmap.h +++ b/src/bitmap.h @@ -1,12 +1,20 @@ #ifndef IMV_BITMAP_H #define IMV_BITMAP_H +#include +#include + +#define BYTES_PER_CHANNEL 4 + struct imv_bitmap { int width; int height; unsigned char *data; }; +/* Gets the size of the `data` buffer in bytes. */ +size_t imv_bitmap_size(struct imv_bitmap *bmp); + /* Clean up a bitmap */ void imv_bitmap_free(struct imv_bitmap *bmp);