XenevaOS
Loading...
Searching...
No Matches
Classes | Macros | Typedefs | Functions
gif.c File Reference

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"
Include dependency graph for gif.c:

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
 

Functions

void nsgif_destroy (nsgif_t *gif)
 
nsgif_error nsgif_create (const nsgif_bitmap_cb_vt *bitmap_vt, nsgif_bitmap_fmt_t bitmap_fmt, nsgif_t **gif_out)
 
void nsgif_set_frame_delay_behaviour (nsgif_t *gif, uint16_t delay_min, uint16_t delay_default)
 
nsgif_error nsgif_data_scan (nsgif_t *gif, size_t size, const uint8_t *data)
 
void nsgif_data_complete (nsgif_t *gif)
 
nsgif_error nsgif_reset (nsgif_t *gif)
 
nsgif_error nsgif_frame_prepare (nsgif_t *gif, nsgif_rect_t *area, uint32_t *delay_cs, uint32_t *frame_new)
 
nsgif_error nsgif_frame_decode (nsgif_t *gif, uint32_t frame, nsgif_bitmap_t **bitmap)
 
const nsgif_info_t * nsgif_get_info (const nsgif_t *gif)
 
const nsgif_frame_info_t * nsgif_get_frame_info (const nsgif_t *gif, uint32_t frame)
 
void nsgif_global_palette (const nsgif_t *gif, uint32_t table[NSGIF_MAX_COLOURS], size_t *entries)
 
bool nsgif_local_palette (const nsgif_t *gif, uint32_t frame, uint32_t table[NSGIF_MAX_COLOURS], size_t *entries)
 
const char * nsgif_strerror (nsgif_error err)
 
const char * nsgif_str_disposal (enum nsgif_disposal disposal)
 

Detailed Description

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

Todo:
Plain text and comment extensions should be implemented.

Macro Definition Documentation

◆ NSGIF_ARRAY_LEN

#define NSGIF_ARRAY_LEN (   _a)    ((sizeof(_a)) / (sizeof(*_a)))

Helper macro to get number of elements in an array.

Parameters
[in]_aArray to count elements of.
Returns
NUlber of elements in array.

◆ NSGIF_BLOCK_TERMINATOR

#define NSGIF_BLOCK_TERMINATOR   0x00

◆ NSGIF_COLOUR_TABLE_MASK

#define NSGIF_COLOUR_TABLE_MASK   0x80

◆ NSGIF_COLOUR_TABLE_SIZE_MASK

#define NSGIF_COLOUR_TABLE_SIZE_MASK   0x07

◆ NSGIF_FRAME_DELAY_DEFAULT

#define NSGIF_FRAME_DELAY_DEFAULT   10

Default frame delay to apply.

Used when a frame delay lower than the minimum is requested.

◆ NSGIF_FRAME_DELAY_MIN

#define NSGIF_FRAME_DELAY_MIN   2

Default minimum allowable frame delay in cs.

◆ NSGIF_FRAME_INVALID

#define NSGIF_FRAME_INVALID   UINT32_MAX

Internal flag that a frame is invalid/unprocessed

◆ NSGIF_NO_TRANSPARENCY

#define NSGIF_NO_TRANSPARENCY   (0xFFFFFFFFu)

No transparency

◆ NSGIF_PROCESS_COLOURS

#define NSGIF_PROCESS_COLOURS   0xaa000000

Internal flag that the colour table needs to be processed

◆ NSGIF_TRAILER

#define NSGIF_TRAILER   0x3b

◆ NSGIF_TRANSPARENT_COLOUR

#define NSGIF_TRANSPARENT_COLOUR   0x00

Transparent colour

Typedef Documentation

◆ nsgif_frame

typedef struct nsgif_frame nsgif_frame

GIF frame data

Function Documentation

◆ nsgif_create()

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.

Parameters
[in]bitmap_vtBitmap operation functions v-table.
[in]bitmap_fmtBitmap pixel format specification.
[out]gif_outReturn nsgif_t object on success.
Returns
NSGIF_OK on success, or appropriate error otherwise.

◆ nsgif_data_complete()

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).

Parameters
[in]gifThe nsgif_t object.

◆ nsgif_data_scan()

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.

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.

◆ nsgif_destroy()

void nsgif_destroy ( nsgif_t *  gif)

Free a NSGIF object.

Parameters
[in]gifThe NSGIF to free.

◆ nsgif_frame_decode()

nsgif_error nsgif_frame_decode ( nsgif_t *  gif,
uint32_t  frame,
nsgif_bitmap_t **  bitmap 
)

Decodes a GIF frame.

Parameters
[in]gifThe nsgif_t object.
[in]frameThe frame number to decode.
[out]bitmapOn success, returns pointer to the client-allocated, nsgif-owned client bitmap structure.
Returns
NSGIF_OK on success, or appropriate error otherwise.

◆ nsgif_frame_prepare()

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.

Parameters
[in]gifThe nsgif_t object.
[out]areaThe area in pixels that must be redrawn.
[out]delay_csTime to wait after frame_new before next frame in cs.
[out]frame_newThe frame to decode.
Returns
NSGIF_OK on success, or appropriate error otherwise.

◆ nsgif_get_frame_info()

const nsgif_frame_info_t * nsgif_get_frame_info ( const nsgif_t *  gif,
uint32_t  frame 
)

Get information about a GIF from an nsgif_t object.

Parameters
[in]gifThe nsgif_t object to get frame info for.
[in]frameThe frame number to get info for.
Returns
The gif frame info, or NULL on error.

◆ nsgif_get_info()

const nsgif_info_t * nsgif_get_info ( const nsgif_t *  gif)

Get information about a GIF from an nsgif_t object.

Parameters
[in]gifThe nsgif_t object to get info for.
Returns
The gif info, or NULL on error.

◆ nsgif_global_palette()

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.

Parameters
[in]gifThe nsgif_t object.
[out]tableClient buffer to hold the colour table.
[out]entriesThe number of used entries in the colour table.

◆ nsgif_local_palette()

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.

Parameters
[in]gifThe nsgif_t object.
[in]frameThe frame to get the palette for.
[out]tableClient buffer to hold the colour table.
[out]entriesThe number of used entries in the colour table.
Returns
true if a palette is returned, false otherwise.

◆ nsgif_reset()

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.

Parameters
[in]gifA nsgif_t object.
Returns
NSGIF_OK on success, or appropriate error otherwise.

◆ nsgif_set_frame_delay_behaviour()

void nsgif_set_frame_delay_behaviour ( nsgif_t *  gif,
uint16_t  delay_min,
uint16_t  delay_default 
)

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.

Parameters
[in]gifThe nsgif_t object to configure.
[in]delay_minThe minimum frame delay in centiseconds.
[in]delay_defaultThe delay to use if a frame delay is less than delay_min.

◆ nsgif_str_disposal()

const char * nsgif_str_disposal ( enum nsgif_disposal  disposal)

Convert a disposal method to a string.

Parameters
[in]disposalThe disposal method to convert.
Returns
String representation of given disposal method.

◆ nsgif_strerror()

const char * nsgif_strerror ( nsgif_error  err)

Convert an error code to a string.

Parameters
[in]errThe error code to convert.
Returns
String representation of given error code.