summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2022-03-23 17:40:33 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2022-03-23 17:49:25 +0000
commit508160b28de4899bb86b5ca14616f01e58196e1c (patch)
treef4d0da4e38e6b5415c57ad11a34da2e427616a7a
parent617da7327f1247ae6930a814e065531a08cde4b5 (diff)
downloadlibnsgif-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.h6
-rw-r--r--src/gif.c96
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);
/**
diff --git a/src/gif.c b/src/gif.c
index 287b632..f2a304b 100644
--- a/src/gif.c
+++ b/src/gif.c
@@ -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;
}