Gitweb links:

...log 
http://git.netsurf-browser.org/libnsgif.git/shortlog/b1775d81a7f681ce1e6dc4db4020081789995927
...commit 
http://git.netsurf-browser.org/libnsgif.git/commit/b1775d81a7f681ce1e6dc4db4020081789995927
...tree 
http://git.netsurf-browser.org/libnsgif.git/tree/b1775d81a7f681ce1e6dc4db4020081789995927

The branch, master has been updated
       via  b1775d81a7f681ce1e6dc4db4020081789995927 (commit)
       via  e1c266df7688eced5ea7eaf1df2434dc92b4ccb2 (commit)
       via  193234ec4e48bb6445576e0a9a1702f55234594f (commit)
       via  508160b28de4899bb86b5ca14616f01e58196e1c (commit)
       via  617da7327f1247ae6930a814e065531a08cde4b5 (commit)
      from  61934ff70402ffff91fbea9238cb1833ffa6cec6 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=b1775d81a7f681ce1e6dc4db4020081789995927
commit b1775d81a7f681ce1e6dc4db4020081789995927
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    Tests: Update decoder to set required pixel format.

diff --git a/test/nsgif.c b/test/nsgif.c
index 76d7b8f..a32a0ef 100644
--- a/test/nsgif.c
+++ b/test/nsgif.c
@@ -272,7 +272,7 @@ int main(int argc, char *argv[])
        }
 
        /* create our gif animation */
-       err = nsgif_create(&bitmap_callbacks, &gif);
+       err = nsgif_create(&bitmap_callbacks, NSGIF_BITMAP_FMT_R8G8B8A8, &gif);
        if (err != NSGIF_OK) {
                warning("nsgif_create", err);
                return EXIT_FAILURE;


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=e1c266df7688eced5ea7eaf1df2434dc92b4ccb2
commit e1c266df7688eced5ea7eaf1df2434dc92b4ccb2
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    Docs: Mention colour formats in README.

diff --git a/README.md b/README.md
index 63ccdc7..e6219aa 100644
--- a/README.md
+++ b/README.md
@@ -22,14 +22,17 @@ Using
 LibNSGIF allows the client to allocate the bitmap into which the GIF is
 decoded. The client can have an arbitrary bitmap structure, that is simply
 a void pointer to LibNSGIF. The client must provide a callback table for
-interacting with bitmaps. This table must include as a minimum functions to
-create and destroy bitmaps, and a function to get a pointer to the bitmap's
-pixel data buffer.
+interacting with bitmaps, and the required client bitmap pixel format.
+The bitmap table must include as a minimum functions to create and destroy
+bitmaps, and a function to get a pointer to the bitmap's pixel data buffer.
+
+LibNSGIF always decodes to a 32bpp, 8 bits per channel bitmap pixel format,
+however it allows the client to control the colour component ordering.
 
 To load a GIF, first create an nsgif object with `nsgif_create()`.
 
 ```c
-       err = nsgif_create(&bitmap_callbacks, &gif);
+       err = nsgif_create(&bitmap_callbacks, NSGIF_BITMAP_FMT_R8G8B8A8, &gif);
        if (err != NSGIF_OK) {
                fprintf(stderr, "%s\n", nsgif_strerror(err));
                // Handle error


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=193234ec4e48bb6445576e0a9a1702f55234594f
commit 193234ec4e48bb6445576e0a9a1702f55234594f
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    GIF: Build colour tables using colours with client channel ordering.

diff --git a/src/gif.c b/src/gif.c
index f2a304b..6d10898 100644
--- a/src/gif.c
+++ b/src/gif.c
@@ -1052,6 +1052,7 @@ static nsgif_error nsgif__parse_image_descriptor(
 static nsgif_error nsgif__colour_table_extract(
                struct nsgif *gif,
                uint32_t colour_table[NSGIF_MAX_COLOURS],
+               const struct nsgif_colour_layout *layout,
                size_t colour_table_entries,
                const uint8_t **pos,
                bool decode)
@@ -1070,16 +1071,16 @@ static nsgif_error nsgif__colour_table_extract(
                while (count--) {
                        /* Gif colour map contents are r,g,b.
                         *
-                        * We want to pack them bytewise into the
-                        * colour table, such that the red component
-                        * is in byte 0 and the alpha component is in
-                        * byte 3.
+                        * We want to pack them bytewise into the colour table,
+                        * according to the client colour layout.
                         */
 
-                       *entry++ = *data++; /* r */
-                       *entry++ = *data++; /* g */
-                       *entry++ = *data++; /* b */
-                       *entry++ = 0xff;    /* a */
+                       entry[layout->r] = *data++;
+                       entry[layout->g] = *data++;
+                       entry[layout->b] = *data++;
+                       entry[layout->a] = 0xff;
+
+                       entry += sizeof(uint32_t);
                }
        }
 
@@ -1114,7 +1115,8 @@ static nsgif_error nsgif__parse_colour_table(
                return NSGIF_OK;
        }
 
-       ret = nsgif__colour_table_extract(gif, gif->local_colour_table,
+       ret = nsgif__colour_table_extract(gif,
+                       gif->local_colour_table, &gif->colour_layout,
                        2 << (frame->flags & NSGIF_COLOUR_TABLE_SIZE_MASK),
                        pos, decode);
        if (ret != NSGIF_OK) {
@@ -1629,6 +1631,7 @@ nsgif_error nsgif_data_scan(
                if (gif->global_colours) {
                        ret = nsgif__colour_table_extract(gif,
                                        gif->global_colour_table,
+                                       &gif->colour_layout,
                                        gif->colour_table_size,
                                        &nsgif_data, true);
                        if (ret != NSGIF_OK) {
@@ -1638,15 +1641,22 @@ nsgif_error nsgif_data_scan(
                        gif->buf_pos = (nsgif_data - gif->buf);
                } else {
                        /* Create a default colour table with the first two
-                        * colours as black and white
-                        */
-                       uint32_t *entry = gif->global_colour_table;
-
-                       entry[0] = 0x00000000;
-                       /* Force Alpha channel to opaque */
-                       ((uint8_t *) entry)[3] = 0xff;
-
-                       entry[1] = 0xffffffff;
+                        * colours as black and white. */
+                       uint8_t *entry = (uint8_t *)gif->global_colour_table;
+
+                       /* Black */
+                       entry[gif->colour_layout.r] = 0x00;
+                       entry[gif->colour_layout.g] = 0x00;
+                       entry[gif->colour_layout.b] = 0x00;
+                       entry[gif->colour_layout.a] = 0xFF;
+
+                       entry += sizeof(uint32_t);
+
+                       /* White */
+                       entry[gif->colour_layout.r] = 0xFF;
+                       entry[gif->colour_layout.g] = 0xFF;
+                       entry[gif->colour_layout.b] = 0xFF;
+                       entry[gif->colour_layout.a] = 0xFF;
                }
 
                if (gif->global_colours &&


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=508160b28de4899bb86b5ca14616f01e58196e1c
commit 508160b28de4899bb86b5ca14616f01e58196e1c
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    API: GIF: Take client colour layout on nsgif_create().
    
    Map the requested layout to appropriate pixel channel offsets.

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;
 }


commitdiff 
http://git.netsurf-browser.org/libnsgif.git/commit/?id=617da7327f1247ae6930a814e065531a08cde4b5
commit 617da7327f1247ae6930a814e065531a08cde4b5
Author: Michael Drake <t...@netsurf-browser.org>
Commit: Michael Drake <t...@netsurf-browser.org>

    API: Add enum for colour component order selection.
    
    This will allow the client to choose the colour component order
    for decoded bitmaps.

diff --git a/include/nsgif.h b/include/nsgif.h
index 54dcd71..5fcb608 100644
--- a/include/nsgif.h
+++ b/include/nsgif.h
@@ -99,14 +99,69 @@ typedef enum {
 } nsgif_error;
 
 /**
+ * NSGIF \ref nsgif_bitmap_t pixel format.
+ *
+ * All pixel formats are 32 bits per pixel (bpp). The different formats
+ * allow control over the ordering of the colour channels. All colour
+ * channels are 8 bits wide.
+ *
+ * Note that the GIF file format only supports an on/off mask, so the
+ * alpha (A) component (opacity) will always have a value of `0` (fully
+ * transparent) or `255` (fully opaque).
+ */
+typedef enum nsgif_bitmap_fmt {
+       /** Bite-wise RGBA: Byte order: 0xRR, 0xGG, 0xBB, 0xAA. */
+       NSGIF_BITMAP_FMT_R8G8B8A8,
+
+       /** Bite-wise BGRA: Byte order: 0xBB, 0xGG, 0xRR, 0xAA. */
+       NSGIF_BITMAP_FMT_B8G8R8A8,
+
+       /** Bite-wise ARGB: Byte order: 0xAA, 0xRR, 0xGG, 0xBB. */
+       NSGIF_BITMAP_FMT_A8R8G8B8,
+
+       /** Bite-wise ABGR: Byte order: 0xAA, 0xBB, 0xGG, 0xRR. */
+       NSGIF_BITMAP_FMT_A8B8G8R8,
+
+       /**
+        * 32-bit RGBA (0xRRGGBBAA).
+        *
+        * * On little endian host, same as \ref NSGIF_BITMAP_FMT_A8B8G8R8.
+        * * On big endian host, same as \ref NSGIF_BITMAP_FMT_R8G8B8A8.
+        */
+       NSGIF_BITMAP_FMT_RGBA8888,
+
+       /**
+        * 32-bit BGRA (0xBBGGRRAA).
+        *
+        * * On little endian host, same as \ref NSGIF_BITMAP_FMT_A8R8G8B8.
+        * * On big endian host, same as \ref NSGIF_BITMAP_FMT_B8G8R8A8.
+        */
+       NSGIF_BITMAP_FMT_BGRA8888,
+
+       /**
+        * 32-bit ARGB (0xAARRGGBB).
+        *
+        * * On little endian host, same as \ref NSGIF_BITMAP_FMT_B8G8R8A8.
+        * * On big endian host, same as \ref NSGIF_BITMAP_FMT_A8R8G8B8.
+        */
+       NSGIF_BITMAP_FMT_ARGB8888,
+
+       /**
+        * 32-bit BGRA (0xAABBGGRR).
+        *
+        * * On little endian host, same as \ref NSGIF_BITMAP_FMT_R8G8B8A8.
+        * * On big endian host, same as \ref NSGIF_BITMAP_FMT_A8B8G8R8.
+        */
+       NSGIF_BITMAP_FMT_ABGR8888,
+} nsgif_bitmap_fmt_t;
+
+/**
  * Client bitmap type.
  *
  * These are client-created and destroyed, via the \ref bitmap callbacks,
  * but they are owned by a \ref nsgif_t.
  *
- * The pixel buffer is is 32bpp, treated as individual bytes in the component
- * order RR GG BB AA. For example, a 1x1 image with a single orange pixel would
- * be encoded as the following sequence of bytes: 0xff, 0x88, 0x00, 0x00.
+ * See \ref nsgif_bitmap_fmt for pixel format information.
  */
 typedef void nsgif_bitmap_t;
 


-----------------------------------------------------------------------

Summary of changes:
 README.md       |   11 +++--
 include/nsgif.h |   67 ++++++++++++++++++++++++--
 src/gif.c       |  142 +++++++++++++++++++++++++++++++++++++++++++++++--------
 test/nsgif.c    |    2 +-
 4 files changed, 193 insertions(+), 29 deletions(-)

diff --git a/README.md b/README.md
index 63ccdc7..e6219aa 100644
--- a/README.md
+++ b/README.md
@@ -22,14 +22,17 @@ Using
 LibNSGIF allows the client to allocate the bitmap into which the GIF is
 decoded. The client can have an arbitrary bitmap structure, that is simply
 a void pointer to LibNSGIF. The client must provide a callback table for
-interacting with bitmaps. This table must include as a minimum functions to
-create and destroy bitmaps, and a function to get a pointer to the bitmap's
-pixel data buffer.
+interacting with bitmaps, and the required client bitmap pixel format.
+The bitmap table must include as a minimum functions to create and destroy
+bitmaps, and a function to get a pointer to the bitmap's pixel data buffer.
+
+LibNSGIF always decodes to a 32bpp, 8 bits per channel bitmap pixel format,
+however it allows the client to control the colour component ordering.
 
 To load a GIF, first create an nsgif object with `nsgif_create()`.
 
 ```c
-       err = nsgif_create(&bitmap_callbacks, &gif);
+       err = nsgif_create(&bitmap_callbacks, NSGIF_BITMAP_FMT_R8G8B8A8, &gif);
        if (err != NSGIF_OK) {
                fprintf(stderr, "%s\n", nsgif_strerror(err));
                // Handle error
diff --git a/include/nsgif.h b/include/nsgif.h
index 54dcd71..655486b 100644
--- a/include/nsgif.h
+++ b/include/nsgif.h
@@ -99,14 +99,69 @@ typedef enum {
 } nsgif_error;
 
 /**
+ * NSGIF \ref nsgif_bitmap_t pixel format.
+ *
+ * All pixel formats are 32 bits per pixel (bpp). The different formats
+ * allow control over the ordering of the colour channels. All colour
+ * channels are 8 bits wide.
+ *
+ * Note that the GIF file format only supports an on/off mask, so the
+ * alpha (A) component (opacity) will always have a value of `0` (fully
+ * transparent) or `255` (fully opaque).
+ */
+typedef enum nsgif_bitmap_fmt {
+       /** Bite-wise RGBA: Byte order: 0xRR, 0xGG, 0xBB, 0xAA. */
+       NSGIF_BITMAP_FMT_R8G8B8A8,
+
+       /** Bite-wise BGRA: Byte order: 0xBB, 0xGG, 0xRR, 0xAA. */
+       NSGIF_BITMAP_FMT_B8G8R8A8,
+
+       /** Bite-wise ARGB: Byte order: 0xAA, 0xRR, 0xGG, 0xBB. */
+       NSGIF_BITMAP_FMT_A8R8G8B8,
+
+       /** Bite-wise ABGR: Byte order: 0xAA, 0xBB, 0xGG, 0xRR. */
+       NSGIF_BITMAP_FMT_A8B8G8R8,
+
+       /**
+        * 32-bit RGBA (0xRRGGBBAA).
+        *
+        * * On little endian host, same as \ref NSGIF_BITMAP_FMT_A8B8G8R8.
+        * * On big endian host, same as \ref NSGIF_BITMAP_FMT_R8G8B8A8.
+        */
+       NSGIF_BITMAP_FMT_RGBA8888,
+
+       /**
+        * 32-bit BGRA (0xBBGGRRAA).
+        *
+        * * On little endian host, same as \ref NSGIF_BITMAP_FMT_A8R8G8B8.
+        * * On big endian host, same as \ref NSGIF_BITMAP_FMT_B8G8R8A8.
+        */
+       NSGIF_BITMAP_FMT_BGRA8888,
+
+       /**
+        * 32-bit ARGB (0xAARRGGBB).
+        *
+        * * On little endian host, same as \ref NSGIF_BITMAP_FMT_B8G8R8A8.
+        * * On big endian host, same as \ref NSGIF_BITMAP_FMT_A8R8G8B8.
+        */
+       NSGIF_BITMAP_FMT_ARGB8888,
+
+       /**
+        * 32-bit BGRA (0xAABBGGRR).
+        *
+        * * On little endian host, same as \ref NSGIF_BITMAP_FMT_R8G8B8A8.
+        * * On big endian host, same as \ref NSGIF_BITMAP_FMT_A8B8G8R8.
+        */
+       NSGIF_BITMAP_FMT_ABGR8888,
+} nsgif_bitmap_fmt_t;
+
+/**
  * Client bitmap type.
  *
  * These are client-created and destroyed, via the \ref bitmap callbacks,
  * but they are owned by a \ref nsgif_t.
  *
- * The pixel buffer is is 32bpp, treated as individual bytes in the component
- * order RR GG BB AA. For example, a 1x1 image with a single orange pixel would
- * be encoded as the following sequence of bytes: 0xff, 0x88, 0x00, 0x00.
+ * See \ref nsgif_bitmap_fmt for pixel format information.
  */
 typedef void nsgif_bitmap_t;
 
@@ -176,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..6d10898 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 */
@@ -1042,6 +1052,7 @@ static nsgif_error nsgif__parse_image_descriptor(
 static nsgif_error nsgif__colour_table_extract(
                struct nsgif *gif,
                uint32_t colour_table[NSGIF_MAX_COLOURS],
+               const struct nsgif_colour_layout *layout,
                size_t colour_table_entries,
                const uint8_t **pos,
                bool decode)
@@ -1060,16 +1071,16 @@ static nsgif_error nsgif__colour_table_extract(
                while (count--) {
                        /* Gif colour map contents are r,g,b.
                         *
-                        * We want to pack them bytewise into the
-                        * colour table, such that the red component
-                        * is in byte 0 and the alpha component is in
-                        * byte 3.
+                        * We want to pack them bytewise into the colour table,
+                        * according to the client colour layout.
                         */
 
-                       *entry++ = *data++; /* r */
-                       *entry++ = *data++; /* g */
-                       *entry++ = *data++; /* b */
-                       *entry++ = 0xff;    /* a */
+                       entry[layout->r] = *data++;
+                       entry[layout->g] = *data++;
+                       entry[layout->b] = *data++;
+                       entry[layout->a] = 0xff;
+
+                       entry += sizeof(uint32_t);
                }
        }
 
@@ -1104,7 +1115,8 @@ static nsgif_error nsgif__parse_colour_table(
                return NSGIF_OK;
        }
 
-       ret = nsgif__colour_table_extract(gif, gif->local_colour_table,
+       ret = nsgif__colour_table_extract(gif,
+                       gif->local_colour_table, &gif->colour_layout,
                        2 << (frame->flags & NSGIF_COLOUR_TABLE_SIZE_MASK),
                        pos, decode);
        if (ret != NSGIF_OK) {
@@ -1343,8 +1355,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 +1454,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;
 }
@@ -1535,6 +1631,7 @@ nsgif_error nsgif_data_scan(
                if (gif->global_colours) {
                        ret = nsgif__colour_table_extract(gif,
                                        gif->global_colour_table,
+                                       &gif->colour_layout,
                                        gif->colour_table_size,
                                        &nsgif_data, true);
                        if (ret != NSGIF_OK) {
@@ -1544,15 +1641,22 @@ nsgif_error nsgif_data_scan(
                        gif->buf_pos = (nsgif_data - gif->buf);
                } else {
                        /* Create a default colour table with the first two
-                        * colours as black and white
-                        */
-                       uint32_t *entry = gif->global_colour_table;
-
-                       entry[0] = 0x00000000;
-                       /* Force Alpha channel to opaque */
-                       ((uint8_t *) entry)[3] = 0xff;
-
-                       entry[1] = 0xffffffff;
+                        * colours as black and white. */
+                       uint8_t *entry = (uint8_t *)gif->global_colour_table;
+
+                       /* Black */
+                       entry[gif->colour_layout.r] = 0x00;
+                       entry[gif->colour_layout.g] = 0x00;
+                       entry[gif->colour_layout.b] = 0x00;
+                       entry[gif->colour_layout.a] = 0xFF;
+
+                       entry += sizeof(uint32_t);
+
+                       /* White */
+                       entry[gif->colour_layout.r] = 0xFF;
+                       entry[gif->colour_layout.g] = 0xFF;
+                       entry[gif->colour_layout.b] = 0xFF;
+                       entry[gif->colour_layout.a] = 0xFF;
                }
 
                if (gif->global_colours &&
diff --git a/test/nsgif.c b/test/nsgif.c
index 76d7b8f..a32a0ef 100644
--- a/test/nsgif.c
+++ b/test/nsgif.c
@@ -272,7 +272,7 @@ int main(int argc, char *argv[])
        }
 
        /* create our gif animation */
-       err = nsgif_create(&bitmap_callbacks, &gif);
+       err = nsgif_create(&bitmap_callbacks, NSGIF_BITMAP_FMT_R8G8B8A8, &gif);
        if (err != NSGIF_OK) {
                warning("nsgif_create", err);
                return EXIT_FAILURE;


-- 
NetSurf GIF Decoder
_______________________________________________
netsurf-commits mailing list -- netsurf-commits@netsurf-browser.org
To unsubscribe send an email to netsurf-commits-le...@netsurf-browser.org

Reply via email to