diff options
author | Michael Drake <tlsa@netsurf-browser.org> | 2022-02-26 17:39:10 +0000 |
---|---|---|
committer | Michael Drake <tlsa@netsurf-browser.org> | 2022-02-26 17:39:49 +0000 |
commit | 41d8bcf828af44c775454e46ce751f9ac1a3684e (patch) | |
tree | dc04b272b85d34c1b3a9407a9ae365a4e5a2fdf3 | |
parent | 7ee51c0f6025238640cfa55faa36cd73e12489c7 (diff) | |
download | libnsgif-41d8bcf828af44c775454e46ce751f9ac1a3684e.tar.gz libnsgif-41d8bcf828af44c775454e46ce751f9ac1a3684e.tar.bz2 |
Docs: Update README for new API.
-rw-r--r-- | README.md | 148 |
1 files changed, 114 insertions, 34 deletions
@@ -1,36 +1,116 @@ -libnsgif - Decoding GIF files +LibNSGIF: NetSurf GIF decoder ============================= -The functions provided by this library allow for efficient progressive -GIF decoding. Whilst the initialisation does not ensure that there is -sufficient image data to complete the entire frame, it does ensure -that the information provided is valid. Any subsequent attempts to -decode an initialised GIF are guaranteed to succeed, and any bytes of -the image not present are assumed to be totally transparent. - -To begin decoding a GIF, the 'gif' structure must be initialised with -the 'gif_data' and 'buffer_size' set to their initial values. The -'buffer_position' should initially be 0, and will be internally -updated as the decoding commences. The caller should then repeatedly -call gif_initialise() with the structure until the function returns 1, -or no more data is avaliable. - -Once the initialisation has begun, the decoder completes the variables -'frame_count' and 'frame_count_partial'. The former being the total -number of frames that have been successfully initialised, and the -latter being the number of frames that a partial amount of data is -available for. This assists the caller in managing the animation -whilst decoding is continuing. - -To decode a frame, the caller must use gif_decode_frame() which -updates the current 'frame_image' to reflect the desired frame. The -required 'disposal_method' is also updated to reflect how the frame -should be plotted. The caller must not assume that the current -'frame_image' will be valid between calls if initialisation is still -occuring, and should either always request that the frame is decoded -(no processing will occur if the 'decoded_frame' has not been -invalidated by initialisation) or perform the check itself. - -It should be noted that gif_finalise() should always be called, even -if no frames were initialised. Additionally, it is the responsibility -of the caller to free 'gif_data'. +LibNSGIF is a C library for decoding GIF format images and animations. +It is licenced under the MIT licence. + +This library aims to provide a simple API for robust decoding of GIF files. + +Details +------- + +The GIF source data is scanned prior to decoding, allowing for efficient +decoding. The scanning phase will scan currently available data and will +resume from where it left off when called with additional data. + +Only one frame is ever fully decoded to a bitmap at a time, reducing memory +usage for large GIFs. + +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. + +To load a GIF, first create an nsgif object with `nsgif_create()`. + +```c + err = nsgif_create(&bitmap_callbacks, &gif); + if (err != NSGIF_OK) { + fprintf(stderr, "%s\n", nsgif_strerror(err)); + // Handle error + } +``` + +Now you can load the GIF source data into the nsgif object with +`nsgif_data_scan()`: + +```c + err = nsgif_data_scan(gif, size, data); + if (err != NSGIF_OK) { + fprintf(stderr, "%s\n", nsgif_strerror(err)); + // Handle error + } +``` + +This scans the source data and decodes information about each frame, however +it doesn't decode any of the bitmap data for the frames. The client may call +`nsgif_data_scan()` multiple times as source data is fetched. Once the +function has returned `NSGIF_OK` it has enough data to display at least one +frame. The early frames can be decoded before the later frames are scanned. +Frames have to be scanned before they can be decoded. + +To decode the frames, you can call `nsgif_get_info()` to get the frame_count, +and then call `nsgif_frame_decode()` for each frame, and manage the animation, +and non-displayable frames yourself, or you can use the helper function, +`nsgif_frame_prepare()`: + +```c + err = nsgif_frame_prepare(gif, &area, &delay_cs, &frame_new); + if (err != NSGIF_OK) { + fprintf(stderr, "%s\n", nsgif_strerror(err)); + // Handle error + } + + // Update our bitmap to know it should be showing `frame_new` now. + // Trigger redraw of `area` of image. + + if (delay_cs != NSGIF_INFINITE) { + // Schedule next frame in delay_cs. + } +``` + +This will return the number of the next frame to be decoded, the delay in cs +before the next frame should be decoded, and the area of the bitmap that needs +to be redrawn. + +> **Note**: GIF frames may only occupy a portion of the overall bitmap, and only +> redrawing the area that has changed may be more efficient than redrawing the +> whole thing. The returned area comprises both any region that has been +> changed in the disposal of the previous frame and the new frame. + +GIF files can limit the number of animation loops to a finite number or they +may only have one frame. In either of these cases, the returned delay is +`NSGIF_INFINITE` indicating that the animation is complete. Subsequent calls +to `nsgif_frame_prepare()` will return `NSGIF_ERR_ANIMATION_END`. + +To force the repeat of an animation, call `nsgif_reset()`. + +One reason for the two-step decoding of frames is that it enables deferred +decoding. You can call `nsgif_frame_prepare()` and cause a redraw of that +portion of your document. If the GIF is off screen (another tab, or scrolled +out of sight), there is no need to decode it at all. + +Once the bitmap is needed for a redraw, you can decode the correct frame +on-demand with: + +```c + err = nsgif_frame_decode(gif, frame_new, &bitmap); + if (err != NSGIF_OK) { + fprintf(stderr, "%s\n", nsgif_strerror(err)); + // Handle error + } +``` + +Note that this will be a no-op if the requested frame already happens to be +the decoded frame. + +Once you are done with the GIF, free up the nsgif object with: + +```c + nsgif_destroy(gif); +``` |