summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2022-05-01 12:59:25 +0100
committerMichael Drake <tlsa@netsurf-browser.org>2022-05-01 12:59:25 +0100
commitc40d6f536473c4ee5fd310b50697ac7d0816d6e5 (patch)
tree0e296ea006a5e68f90849ffc135006dd0fe68c20
parent75ed38539447571ec961c985c8a1e9cbd76573e2 (diff)
downloadlibnsgif-c40d6f536473c4ee5fd310b50697ac7d0816d6e5.tar.gz
libnsgif-c40d6f536473c4ee5fd310b50697ac7d0816d6e5.tar.bz2
API: Add optional bitmap rowspan callback.
-rw-r--r--include/nsgif.h17
-rw-r--r--src/gif.c14
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);