From c40d6f536473c4ee5fd310b50697ac7d0816d6e5 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Sun, 1 May 2022 12:59:25 +0100 Subject: API: Add optional bitmap rowspan callback. --- include/nsgif.h | 17 ++++++++++++++++- src/gif.c | 14 ++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/include/nsgif.h b/include/nsgif.h index a02597c..0ea792b 100644 --- a/include/nsgif.h +++ b/include/nsgif.h @@ -162,6 +162,11 @@ typedef enum nsgif_bitmap_fmt { * but they are owned by a \ref nsgif_t. * * See \ref nsgif_bitmap_fmt for pixel format information. + * + * The bitmap may have a row_span greater than the bitmap width, but the + * difference between row span and width must be a whole number of pixels + * (a multiple of four bytes). If row span is greater than width, the + * \ref get_rowspan callback must be provided. */ typedef void nsgif_bitmap_t; @@ -186,7 +191,8 @@ typedef struct nsgif_bitmap_cb_vt { /** * Get pointer to pixel buffer in a bitmap. * - * The pixel buffer must be `width * height * sizeof(uint32_t)`. + * The pixel buffer must be `(width + N) * height * sizeof(uint32_t)`. + * Where `N` is any number greater than or equal to 0. * Note that the returned pointer to uint8_t must be 4-byte aligned. * * \param[in] bitmap The bitmap. @@ -218,6 +224,15 @@ typedef struct nsgif_bitmap_cb_vt { * \param[in] bitmap The bitmap. */ void (*modified)(nsgif_bitmap_t *bitmap); + + /** + * Get row span in pixels. + * + * If this callback is not provided, LibNSGIF will use the width. + * + * \param[in] bitmap The bitmap. + */ + uint32_t (*get_rowspan)(nsgif_bitmap_t *bitmap); } nsgif_bitmap_cb_vt; /** diff --git a/src/gif.c b/src/gif.c index 84d4209..435d0d9 100644 --- a/src/gif.c +++ b/src/gif.c @@ -72,8 +72,11 @@ struct nsgif { uint32_t frame; /** current frame decoded to bitmap */ uint32_t decoded_frame; + /** currently decoded image; stored as bitmap from bitmap_create callback */ nsgif_bitmap_t *frame_image; + /** Row span of frame_image in pixels. */ + uint32_t rowspan; /** Minimum allowable frame delay. */ uint16_t delay_min; @@ -223,6 +226,11 @@ static inline uint32_t* nsgif__bitmap_get( return NULL; } + gif->rowspan = gif->info.width; + if (gif->bitmap.get_rowspan) { + gif->rowspan = gif->bitmap.get_rowspan(gif->frame_image); + } + /* Get the frame data */ assert(gif->bitmap.get_buffer); return (void *)gif->bitmap.get_buffer(gif->frame_image); @@ -463,7 +471,7 @@ static nsgif_error nsgif__decode_complex( uint32_t *frame_scanline; frame_scanline = frame_data + offset_x + - (y + offset_y) * gif->info.width; + (y + offset_y) * gif->rowspan; x = width; while (x > 0) { @@ -594,7 +602,9 @@ static inline nsgif_error nsgif__decode( uint32_t transparency_index = frame->transparency_index; uint32_t *restrict colour_table = gif->colour_table; - if (interlace == false && width == gif->info.width && offset_x == 0) { + if (interlace == false && offset_x == 0 && + width == gif->info.width && + width == gif->rowspan) { ret = nsgif__decode_simple(gif, height, offset_y, data, transparency_index, frame_data, colour_table); -- cgit v1.2.3