summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2022-02-26 17:39:10 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2022-02-26 17:39:49 +0000
commit41d8bcf828af44c775454e46ce751f9ac1a3684e (patch)
treedc04b272b85d34c1b3a9407a9ae365a4e5a2fdf3
parent7ee51c0f6025238640cfa55faa36cd73e12489c7 (diff)
downloadlibnsgif-41d8bcf828af44c775454e46ce751f9ac1a3684e.tar.gz
libnsgif-41d8bcf828af44c775454e46ce751f9ac1a3684e.tar.bz2
Docs: Update README for new API.
-rw-r--r--README.md148
1 files changed, 114 insertions, 34 deletions
diff --git a/README.md b/README.md
index 498ee46..d821ac6 100644
--- a/README.md
+++ b/README.md
@@ -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);
+```