|
XenevaOS
|
GIF image decoder. More...
#include <assert.h>#include <stdint.h>#include <stdlib.h>#include <string.h>#include <stdbool.h>#include "lzw.h"#include "nsgif.h"
Classes | |
| struct | nsgif_frame |
| struct | nsgif_colour_layout |
| struct | nsgif |
Macros | |
| #define | NSGIF_FRAME_DELAY_MIN 2 |
| #define | NSGIF_FRAME_DELAY_DEFAULT 10 |
| #define | NSGIF_ARRAY_LEN(_a) ((sizeof(_a)) / (sizeof(*_a))) |
| #define | NSGIF_PROCESS_COLOURS 0xaa000000 |
| #define | NSGIF_FRAME_INVALID UINT32_MAX |
| #define | NSGIF_TRANSPARENT_COLOUR 0x00 |
| #define | NSGIF_NO_TRANSPARENCY (0xFFFFFFFFu) |
| #define | NSGIF_COLOUR_TABLE_MASK 0x80 |
| #define | NSGIF_COLOUR_TABLE_SIZE_MASK 0x07 |
| #define | NSGIF_BLOCK_TERMINATOR 0x00 |
| #define | NSGIF_TRAILER 0x3b |
Typedefs | |
| typedef struct nsgif_frame | nsgif_frame |
GIF image decoder.
The GIF format is thoroughly documented; a full description can be found at http://www.w3.org/Graphics/GIF/spec-gif89a.txt
| #define NSGIF_ARRAY_LEN | ( | _a | ) | ((sizeof(_a)) / (sizeof(*_a))) |
Helper macro to get number of elements in an array.
| [in] | _a | Array to count elements of. |
| #define NSGIF_BLOCK_TERMINATOR 0x00 |
| #define NSGIF_COLOUR_TABLE_MASK 0x80 |
| #define NSGIF_COLOUR_TABLE_SIZE_MASK 0x07 |
| #define NSGIF_FRAME_DELAY_DEFAULT 10 |
Default frame delay to apply.
Used when a frame delay lower than the minimum is requested.
| #define NSGIF_FRAME_DELAY_MIN 2 |
Default minimum allowable frame delay in cs.
| #define NSGIF_FRAME_INVALID UINT32_MAX |
Internal flag that a frame is invalid/unprocessed
| #define NSGIF_NO_TRANSPARENCY (0xFFFFFFFFu) |
No transparency
| #define NSGIF_PROCESS_COLOURS 0xaa000000 |
Internal flag that the colour table needs to be processed
| #define NSGIF_TRAILER 0x3b |
| #define NSGIF_TRANSPARENT_COLOUR 0x00 |
Transparent colour
| typedef struct nsgif_frame nsgif_frame |
GIF frame data
| nsgif_error nsgif_create | ( | const nsgif_bitmap_cb_vt * | bitmap_vt, |
| nsgif_bitmap_fmt_t | bitmap_fmt, | ||
| nsgif_t ** | gif_out | ||
| ) |
Create the NSGIF object.
| [in] | bitmap_vt | Bitmap operation functions v-table. |
| [in] | bitmap_fmt | Bitmap pixel format specification. |
| [out] | gif_out | Return nsgif_t object on success. |
| void nsgif_data_complete | ( | nsgif_t * | gif | ) |
Tell libnsgif that all the gif data has been provided.
Call this after calling nsgif_data_scan with the the entire GIF source data. You can call nsgif_data_scan multiple times up until this is called, and after this is called, nsgif_data_scan will return an error.
You can decode a GIF before this is called, however, it will fail to decode any truncated final frame data and will not perform loops when driven via nsgif_frame_prepare (because it doesn't know if there will be more frames supplied in future data).
| [in] | gif | The nsgif_t object. |
| nsgif_error nsgif_data_scan | ( | nsgif_t * | gif, |
| size_t | size, | ||
| const uint8_t * | 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.
| [in] | gif | The nsgif_t object. |
| [in] | size | Number of bytes in data. |
| [in] | data | Raw source GIF data. |
| void nsgif_destroy | ( | nsgif_t * | gif | ) |
Free a NSGIF object.
| [in] | gif | The NSGIF to free. |
| nsgif_error nsgif_frame_decode | ( | nsgif_t * | gif, |
| uint32_t | frame, | ||
| nsgif_bitmap_t ** | bitmap | ||
| ) |
Decodes a GIF frame.
| [in] | gif | The nsgif_t object. |
| [in] | frame | The frame number to decode. |
| [out] | bitmap | On success, returns pointer to the client-allocated, nsgif-owned client bitmap structure. |
| nsgif_error nsgif_frame_prepare | ( | nsgif_t * | gif, |
| nsgif_rect_t * | area, | ||
| uint32_t * | delay_cs, | ||
| uint32_t * | frame_new | ||
| ) |
Prepare to show a frame.
If this is the last frame of an animation with a finite loop count, the returned delay_cs will be NSGIF_INFINITE, indicating that the frame should be shown forever.
Note that if nsgif_data_complete has not been called on this gif, animated GIFs will not loop back to the start. Instead it will return NSGIF_ERR_END_OF_DATA.
| [in] | gif | The nsgif_t object. |
| [out] | area | The area in pixels that must be redrawn. |
| [out] | delay_cs | Time to wait after frame_new before next frame in cs. |
| [out] | frame_new | The frame to decode. |
| const nsgif_frame_info_t * nsgif_get_frame_info | ( | const nsgif_t * | gif, |
| uint32_t | frame | ||
| ) |
| const nsgif_info_t * nsgif_get_info | ( | const nsgif_t * | gif | ) |
| void nsgif_global_palette | ( | const nsgif_t * | gif, |
| uint32_t | table[NSGIF_MAX_COLOURS], | ||
| size_t * | entries | ||
| ) |
Get the global colour palette.
If the GIF has no global colour table, this will return the default colour palette.
Colours in same pixel format as nsgif_bitmap_t.
| [in] | gif | The nsgif_t object. |
| [out] | table | Client buffer to hold the colour table. |
| [out] | entries | The number of used entries in the colour table. |
| bool nsgif_local_palette | ( | const nsgif_t * | gif, |
| uint32_t | frame, | ||
| uint32_t | table[NSGIF_MAX_COLOURS], | ||
| size_t * | entries | ||
| ) |
Get the local colour palette for a frame.
Frames may have no local palette. In this case they use the global palette. This function returns false if the frame has no local palette.
Colours in same pixel format as nsgif_bitmap_t.
| [in] | gif | The nsgif_t object. |
| [in] | frame | The frame to get the palette for. |
| [out] | table | Client buffer to hold the colour table. |
| [out] | entries | The number of used entries in the colour table. |
| nsgif_error nsgif_reset | ( | nsgif_t * | gif | ) |
Reset a GIF animation.
Some animations are only meant to loop N times, and then show the final frame forever. This function resets the loop and frame counters, so that the animation can be replayed without the overhead of recreating the nsgif_t object and rescanning the raw data.
| [in] | gif | A nsgif_t object. |
Configure handling of small frame delays.
Historically people created GIFs with a tiny frame delay, however the slow hardware of the time meant they actually played much slower. As computers sped up, to prevent animations playing faster than intended, decoders came to ignore overly small frame delays.
By default a nsgif_frame_prepare() managed animation will override frame delays of less than 2 centiseconds with a default frame delay of 10 centiseconds. This matches the behaviour of web browsers and other renderers.
Both the minimum and the default values can be overridden for a given GIF by the client. To get frame delays exactly as specified by the GIF file, set delay_min to zero.
Note that this does not affect the frame delay in the frame info (nsgif_frame_info_t) structure, which will always contain values specified by the GIF.
| [in] | gif | The nsgif_t object to configure. |
| [in] | delay_min | The minimum frame delay in centiseconds. |
| [in] | delay_default | The delay to use if a frame delay is less than delay_min. |
| const char * nsgif_str_disposal | ( | enum nsgif_disposal | disposal | ) |
Convert a disposal method to a string.
| [in] | disposal | The disposal method to convert. |
| const char * nsgif_strerror | ( | nsgif_error | err | ) |
Convert an error code to a string.
| [in] | err | The error code to convert. |