diff options
author | Michael Drake <tlsa@netsurf-browser.org> | 2022-03-23 17:40:33 +0000 |
---|---|---|
committer | Michael Drake <tlsa@netsurf-browser.org> | 2022-03-23 17:49:25 +0000 |
commit | 508160b28de4899bb86b5ca14616f01e58196e1c (patch) | |
tree | f4d0da4e38e6b5415c57ad11a34da2e427616a7a | |
parent | 617da7327f1247ae6930a814e065531a08cde4b5 (diff) | |
download | libnsgif-508160b28de4899bb86b5ca14616f01e58196e1c.tar.gz libnsgif-508160b28de4899bb86b5ca14616f01e58196e1c.tar.bz2 |
API: GIF: Take client colour layout on nsgif_create().
Map the requested layout to appropriate pixel channel offsets.
-rw-r--r-- | include/nsgif.h | 6 | ||||
-rw-r--r-- | src/gif.c | 96 |
2 files changed, 99 insertions, 3 deletions
diff --git a/include/nsgif.h b/include/nsgif.h index 5fcb608..655486b 100644 --- a/include/nsgif.h +++ b/include/nsgif.h @@ -231,13 +231,15 @@ const char *nsgif_strerror(nsgif_error err); /** * Create the NSGIF object. * - * \param[in] bitmap_vt Bitmap operation functions v-table. - * \param[out] gif_out Return \ref nsgif_t object on success. + * \param[in] bitmap_vt Bitmap operation functions v-table. + * \param[in] bitmap_fmt Bitmap pixel format specification. + * \param[out] gif_out Return \ref nsgif_t object on success. * * \return NSGIF_OK on success, or appropriate error otherwise. */ nsgif_error nsgif_create( const nsgif_bitmap_cb_vt *bitmap_vt, + nsgif_bitmap_fmt_t bitmap_fmt, nsgif_t **gif_out); /** @@ -40,6 +40,14 @@ typedef struct nsgif_frame { uint32_t flags; } nsgif_frame; +/** Pixel format: colour component order. */ +struct nsgif_colour_layout { + uint8_t r; /**< Byte offset within pixel to red component. */ + uint8_t g; /**< Byte offset within pixel to green component. */ + uint8_t b; /**< Byte offset within pixel to blue component. */ + uint8_t a; /**< Byte offset within pixel to alpha component. */ +}; + /** GIF animation data */ struct nsgif { struct nsgif_info info; @@ -83,6 +91,8 @@ struct nsgif { bool global_colours; /** current colour table */ uint32_t *colour_table; + /** Client's colour component order. */ + struct nsgif_colour_layout colour_layout; /** global colour table */ uint32_t global_colour_table[NSGIF_MAX_COLOURS]; /** local colour table */ @@ -1343,8 +1353,90 @@ void nsgif_destroy(nsgif_t *gif) free(gif); } +/** + * Check whether the host is little endian. + * + * Checks whether least significant bit is in the first byte of a `uint16_t`. + * + * \return true if host is little endian. + */ +static inline bool nsgif__host_is_little_endian(void) +{ + static const uint16_t test = 1; + + return ((const uint8_t *) &test)[0] == 1; +} + +static struct nsgif_colour_layout nsgif__bitmap_fmt_to_colour_layout( + nsgif_bitmap_fmt_t bitmap_fmt) +{ + bool le = nsgif__host_is_little_endian(); + + /* Map endian-dependant formats to byte-wise format for the host. */ + switch (bitmap_fmt) { + case NSGIF_BITMAP_FMT_RGBA8888: + bitmap_fmt = (le) ? NSGIF_BITMAP_FMT_A8B8G8R8 + : NSGIF_BITMAP_FMT_R8G8B8A8; + break; + case NSGIF_BITMAP_FMT_BGRA8888: + bitmap_fmt = (le) ? NSGIF_BITMAP_FMT_A8R8G8B8 + : NSGIF_BITMAP_FMT_B8G8R8A8; + break; + case NSGIF_BITMAP_FMT_ARGB8888: + bitmap_fmt = (le) ? NSGIF_BITMAP_FMT_B8G8R8A8 + : NSGIF_BITMAP_FMT_A8R8G8B8; + break; + case NSGIF_BITMAP_FMT_ABGR8888: + bitmap_fmt = (le) ? NSGIF_BITMAP_FMT_R8G8B8A8 + : NSGIF_BITMAP_FMT_A8B8G8R8; + break; + default: + break; + } + + /* Set up colour component order for bitmap format. */ + switch (bitmap_fmt) { + default: + /* Fall through. */ + case NSGIF_BITMAP_FMT_R8G8B8A8: + return (struct nsgif_colour_layout) { + .r = 0, + .g = 1, + .b = 2, + .a = 3, + }; + + case NSGIF_BITMAP_FMT_B8G8R8A8: + return (struct nsgif_colour_layout) { + .b = 0, + .g = 1, + .r = 2, + .a = 3, + }; + + case NSGIF_BITMAP_FMT_A8R8G8B8: + return (struct nsgif_colour_layout) { + .a = 0, + .r = 1, + .g = 2, + .b = 3, + }; + + case NSGIF_BITMAP_FMT_A8B8G8R8: + return (struct nsgif_colour_layout) { + .a = 0, + .b = 1, + .g = 2, + .r = 3, + }; + } +} + /* exported function documented in nsgif.h */ -nsgif_error nsgif_create(const nsgif_bitmap_cb_vt *bitmap_vt, nsgif_t **gif_out) +nsgif_error nsgif_create( + const nsgif_bitmap_cb_vt *bitmap_vt, + nsgif_bitmap_fmt_t bitmap_fmt, + nsgif_t **gif_out) { nsgif_t *gif; @@ -1360,6 +1452,8 @@ nsgif_error nsgif_create(const nsgif_bitmap_cb_vt *bitmap_vt, nsgif_t **gif_out) gif->delay_min = 2; gif->delay_default = 10; + gif->colour_layout = nsgif__bitmap_fmt_to_colour_layout(bitmap_fmt); + *gif_out = gif; return NSGIF_OK; } |