FastLED 3.9.15
Loading...
Searching...
No Matches

◆ nsgif_data_scan()

nsgif_error fl::third_party::nsgif_data_scan ( nsgif_t * gif,
fl::size size,
const fl::u8 * data )

Scan the source image data.

This is used to feed the source data into LibNSGIF. This must be called before calling nsgif_frame_decode.

It can be called multiple times with, with increasing sizes. If it is called several times, as more data is available (e.g. slow network fetch) the data already given to nsgif_data_scan must be provided each time.

Once all the data has been provided, call nsgif_data_complete.

For example, if you call nsgif_data_scan with 25 bytes of data, and then fetch another 10 bytes, you would need to call nsgif_data_scan with a size of 35 bytes, and the whole 35 bytes must be contiguous memory. It is safe to realloc the source buffer between calls to nsgif_data_scan. (The actual data pointer is allowed to be different.)

If an error occurs, all previously scanned frames are retained.

Note that an error returned from this function is purely informational. So long as at least one frame is available, you can display frames.

Parameters
[in]gifThe nsgif_t object.
[in]sizeNumber of bytes in data.
[in]dataRaw source GIF data.
Returns
NSGIF_OK on success, or appropriate error otherwise.

Definition at line 1616 of file gif.cpp.hpp.

1620{
1621 const fl::u8 *nsgif_data;
1622 nsgif_error ret;
1623 fl::u32 frames;
1624
1625 if (gif->data_complete) {
1627 }
1628
1629 /* Initialize values */
1630 gif->buf_len = size;
1631 gif->buf = data;
1632
1633 /* Get our current processing position */
1634 nsgif_data = gif->buf + gif->buf_pos;
1635
1636 /* See if we should initialise the GIF */
1637 if (gif->buf_pos == 0) {
1638 /* We want everything to be NULL before we start so we've no
1639 * chance of freeing bad pointers (paranoia)
1640 */
1641 gif->frame_image = nullptr;
1642 gif->frames = nullptr;
1643 gif->frame_holders = 0;
1644
1645 /* The caller may have been lazy and not reset any values */
1646 gif->info.frame_count = 0;
1647 gif->frame_count_partial = 0;
1650
1651 ret = nsgif__parse_header(gif, &nsgif_data, false);
1652 if (ret != NSGIF_OK) {
1653 return ret;
1654 }
1655
1656 ret = nsgif__parse_logical_screen_descriptor(gif, &nsgif_data);
1657 if (ret != NSGIF_OK) {
1658 return ret;
1659 }
1660
1661 /* Remember we've done this now */
1662 gif->buf_pos = nsgif_data - gif->buf;
1663
1664 /* Some broken GIFs report the size as the screen size they
1665 * were created in. As such, we detect for the common cases and
1666 * set the sizes as 0 if they are found which results in the
1667 * GIF being the maximum size of the frames.
1668 */
1669 if (((gif->info.width == 640) && (gif->info.height == 480)) ||
1670 ((gif->info.width == 640) && (gif->info.height == 512)) ||
1671 ((gif->info.width == 800) && (gif->info.height == 600)) ||
1672 ((gif->info.width == 1024) && (gif->info.height == 768)) ||
1673 ((gif->info.width == 1280) && (gif->info.height == 1024)) ||
1674 ((gif->info.width == 1600) && (gif->info.height == 1200)) ||
1675 ((gif->info.width == 0) || (gif->info.height == 0)) ||
1676 ((gif->info.width > 2048) || (gif->info.height > 2048))) {
1677 gif->info.width = 1;
1678 gif->info.height = 1;
1679 }
1680
1681 /* Set the first colour to a value that will never occur in
1682 * reality so we know if we've processed it
1683 */
1685
1686 /* Check if the GIF has no frame data (13-byte header + 1-byte
1687 * termination block) Although generally useless, the GIF
1688 * specification does not expressly prohibit this
1689 */
1690 if (gif->buf_len == gif->buf_pos + 1) {
1691 if (nsgif_data[0] == NSGIF_TRAILER) {
1692 return NSGIF_OK;
1693 }
1694 }
1695 }
1696
1697 /* Do the colour map if we haven't already. As the top byte is always
1698 * 0xff or 0x00 depending on the transparency we know if it's been
1699 * filled in.
1700 */
1702 /* Check for a global colour map signified by bit 7 */
1703 if (gif->info.global_palette) {
1704 fl::size remaining = gif->buf + gif->buf_len - nsgif_data;
1705 fl::size used;
1706
1709 &gif->colour_layout,
1710 gif->colour_table_size,
1711 nsgif_data, remaining, &used, true);
1712 if (ret != NSGIF_OK) {
1713 return ret;
1714 }
1715
1716 nsgif_data += used;
1717 gif->buf_pos = (nsgif_data - gif->buf);
1718 } else {
1719 /* Create a default colour table with the first two
1720 * colours as black and white. */
1721 fl::u8 *entry = (fl::u8 *)gif->global_colour_table;
1722
1723 /* Black */
1724 entry[gif->colour_layout.r] = 0x00;
1725 entry[gif->colour_layout.g] = 0x00;
1726 entry[gif->colour_layout.b] = 0x00;
1727 entry[gif->colour_layout.a] = 0xFF;
1728
1729 entry += sizeof(fl::u32);
1730
1731 /* White */
1732 entry[gif->colour_layout.r] = 0xFF;
1733 entry[gif->colour_layout.g] = 0xFF;
1734 entry[gif->colour_layout.b] = 0xFF;
1735 entry[gif->colour_layout.a] = 0xFF;
1736
1737 gif->colour_table_size = 2;
1738 }
1739
1740 if (gif->info.global_palette &&
1741 gif->bg_index < gif->colour_table_size) {
1742 fl::size bg_idx = gif->bg_index;
1743 gif->info.background = gif->global_colour_table[bg_idx];
1744 } else {
1745 gif->info.background = gif->global_colour_table[0];
1746 }
1747 }
1748
1749 if (gif->lzw_ctx == nullptr) {
1750 struct lzw_ctx *lzw_ctx_ptr = nullptr;
1751 lzw_result res = lzw_context_create(&lzw_ctx_ptr);
1752 gif->lzw_ctx = lzw_ctx_ptr;
1753 if (res != LZW_OK) {
1754 return nsgif__error_from_lzw(res);
1755 }
1756 }
1757
1758 /* Try to initialise all frames. */
1759 do {
1760 frames = gif->info.frame_count;
1761 ret = nsgif__process_frame(gif, frames, false);
1762 } while (gif->info.frame_count > frames);
1763
1764 if (ret == NSGIF_ERR_END_OF_DATA && gif->info.frame_count > 0) {
1765 ret = NSGIF_OK;
1766 }
1767
1768 return ret;
1769}
unsigned char u8
Definition coder.h:132
lzw_result lzw_context_create(struct lzw_ctx **ctx) FL_NOEXCEPT
Create an LZW decompression context.
Definition lzw.cpp.hpp:104
static nsgif_error nsgif__parse_logical_screen_descriptor(struct nsgif *gif, const fl::u8 **pos) FL_NOEXCEPT
Read Logical Screen Descriptor.
Definition gif.cpp.hpp:1592
nsgif_error
LibNSGIF return codes.
Definition nsgif.hpp:58
@ NSGIF_ERR_DATA_COMPLETE
Can't supply more data after calling nsgif_data_complete.
Definition nsgif.hpp:92
@ NSGIF_ERR_END_OF_DATA
Unexpected end of GIF source data.
Definition nsgif.hpp:87
@ NSGIF_OK
Success.
Definition nsgif.hpp:62
static nsgif_error nsgif__parse_header(struct nsgif *gif, const fl::u8 **pos, bool strict) FL_NOEXCEPT
Read GIF header.
Definition gif.cpp.hpp:1544
lzw_result
LZW decoding response codes.
Definition lzw.h:33
@ LZW_OK
Success.
Definition lzw.h:34
static nsgif_error nsgif__colour_table_extract(fl::u32 colour_table[NSGIF_MAX_COLOURS], const struct nsgif_colour_layout *layout, fl::size colour_table_entries, const fl::u8 *data, fl::size data_len, fl::size *used, bool decode) FL_NOEXCEPT
Extract a GIF colour table into a LibNSGIF colour table buffer.
Definition gif.cpp.hpp:1115
static nsgif_error nsgif__error_from_lzw(lzw_result l_res) FL_NOEXCEPT
Convert an LZW result code to equivalent GIF result code.
Definition gif.cpp.hpp:182
static nsgif_error nsgif__process_frame(struct nsgif *gif, fl::u32 frame_idx, bool decode) FL_NOEXCEPT
Attempts to initialise the next frame.
Definition gif.cpp.hpp:1323
fl::u32 colour_table_size
size of global colour table (in entries)
Definition gif.cpp.hpp:122
nsgif_bitmap_t * frame_image
currently decoded image; stored as bitmap from bitmap_create callback
Definition gif.cpp.hpp:86
fl::u32 global_colour_table[NSGIF_MAX_COLOURS]
global colour table
Definition gif.cpp.hpp:129
fl::u8 b
Byte offset within pixel to blue component.
Definition gif.cpp.hpp:66
nsgif_frame * frames
decoded frames
Definition gif.cpp.hpp:79
fl::u8 g
Byte offset within pixel to green component.
Definition gif.cpp.hpp:65
fl::u32 decoded_frame
current frame decoded to bitmap
Definition gif.cpp.hpp:83
fl::size buf_pos
current index into GIF data
Definition gif.cpp.hpp:111
fl::u32 background
background colour in same pixel format as nsgif_bitmap_t.
Definition nsgif.hpp:392
fl::u32 frame_count
number of frames decoded
Definition nsgif.hpp:388
fl::u8 r
Byte offset within pixel to red component.
Definition gif.cpp.hpp:64
fl::u32 width
width of GIF (may increase during decoding)
Definition nsgif.hpp:384
fl::u32 height
height of GIF (may increase during decoding)
Definition nsgif.hpp:386
fl::size buf_len
total number of bytes of GIF data available
Definition gif.cpp.hpp:113
struct nsgif_colour_layout colour_layout
Client's colour component order.
Definition gif.cpp.hpp:127
void * lzw_ctx
LZW decode context.
Definition gif.cpp.hpp:75
bool global_palette
whether the GIF has a global colour table
Definition nsgif.hpp:394
fl::u32 frame
current frame
Definition gif.cpp.hpp:81
fl::u32 bg_index
background index
Definition gif.cpp.hpp:118
struct nsgif_info info
Definition gif.cpp.hpp:72
fl::u32 frame_count_partial
number of frames partially decoded
Definition gif.cpp.hpp:100
fl::u8 a
Byte offset within pixel to alpha component.
Definition gif.cpp.hpp:67
bool data_complete
Whether all the GIF data has been supplied, or if there may be more to come.
Definition gif.cpp.hpp:106
const fl::u8 * buf
pointer to GIF data
Definition gif.cpp.hpp:109
fl::u32 frame_holders
current number of frame holders
Definition gif.cpp.hpp:116
LZW decompression context.
Definition lzw.cpp.hpp:72
#define NSGIF_TRAILER
Definition gif.cpp.hpp:174
#define NSGIF_FRAME_INVALID
Internal flag that a frame is invalid/unprocessed.
Definition gif.cpp.hpp:162
#define NSGIF_PROCESS_COLOURS
Internal flag that the colour table needs to be processed.
Definition gif.cpp.hpp:159

References FL_NOEXCEPT, lzw_context_create(), LZW_OK, nsgif__colour_table_extract(), nsgif__error_from_lzw(), nsgif__parse_header(), nsgif__parse_logical_screen_descriptor(), nsgif__process_frame(), NSGIF_ERR_DATA_COMPLETE, NSGIF_ERR_END_OF_DATA, NSGIF_FRAME_INVALID, NSGIF_OK, NSGIF_PROCESS_COLOURS, and NSGIF_TRAILER.

Referenced by fl::third_party::SoftwareGifDecoder::loadMoreData().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: