2015-08-03 14:44:25 (UTC-03:00)
Marcel Rodrigues <marcelgmr@gmail.com>
Add README.
diff --git a/README b/README new file mode 100644 index 0000000..506c792 --- /dev/null +++ b/README @@ -0,0 +1,114 @@ +GIF encoder +=========== + +This is a small C99 library that can be used to create GIF animations. + +Features +-------- + + * user-defined palette of any depth from 1 up to 8 + * each frame has its own (user-specified) delay time + * flexible looping options: no loop, N repetitions, infinite loop + * GIF size optimization: only stores frame differences + * memory efficient: saves frames to file as soon as possible + * small and portable: less than 300 lines of C99 + + +Limitations +----------- + + * no frame-local palettes (incompatible with size optimization) + * no interlacing + + +Documentation +------------- + +There are only three functions declared in "gifenc.h": new_gif(), add_frame() +and close_gif(). + +The new_gif() function receives GIF global options and returns a GIF handler: + + GIF *new_gif( + const char *fname, /* GIF file name */ + uint16_t width, uint16_t height, /* frame size */ + uint8_t *palette, int depth, /* color table */ + int loop /* looping information */ + ); + +The `palette` parameter must point to an array of color data. Each entry is a +24-bits RGB color, stored as three contiguous bytes: the first is the red value +(0-255), then green, then blue. Entries are stored in a contiguous byte array. + +The `depth` parameter specifies how many colors are present in the given +palette. The number of color entries must be 2 ^ depth, where 1 <= depth <= 8. + + uint8_t palette[] = { + 0x00, 0x00, 0x00, /* entry 0: black */ + 0xFF, 0xFF, 0xFF, /* entry 1: white */ + 0xFF, 0x00, 0x00, /* entry 2: red */ + 0x00, 0x00, 0xFF, /* entry 3: blue */ + }; + int depth = 2; /* palette has 1 << 2 (i.e. 4) entries */ + +If the `loop` parameter is zero, the resulting GIF will loop forever. If it is a +positive number, the animation will be played that nuumber of times. If `loop` +is negative, no looping information is stored in the GIF file (for most GIF +viewers, this is equivalent to `loop` == 1, i.e., "play once"). + +The add_frame() function reads pixel data from a buffer and saves the resulting +frame to the file associated with the given GIF handler: + + void add_frame(GIF *gif, uint16_t delay); + +The `delay` parameter specifies how long the frame will be shown, in hundreths +of a second. For example, `delay` == 100 means "show this frame for one second" +and `delay` == 25 means "show this frame for a quarter of a second". Note that +short delays may not be supported by some GIF viewers: it's recommended to keep +a minimum of `delay` == 6. + +Pixel data is read from `gif->frame`, which points to a memory block like this: + + uint8_t _frame_[gif->width * gif->height]; + +Note that the address of `gif->frame` changes between calls to add_frame() (*). +For this reason, each frame must be written in its entirety to the current +address, even if one only wants to change a few pixels from the last frame. The +encoder will automatically detect the diferrence between two consecutive frames +in order to minimize the size of the output. + +Each byte in the frame buffer represents a pixel. The value of each pixel is an +index to a palette entry. For example, given the example palette above, we can +create a frame displaying a red-on-black "F" letter like this: + + uint8_t pixels[] = { + 2, 2, 2, 2, + 2, 0, 0, 0, + 2, 0, 0, 0, + 2, 2, 2, 0, + 2, 0, 0, 0, + 2, 0, 0, 0, + 2, 0, 0, 0 + }; + GIF *gif = new_gif("E.gif", 4, 7, palette, depth, loop); + memcpy(gif->frame, pixels, sizeof(pixels)); + add_frame(gif, delay); + close_gif(gif); + +The function close_gif() finishes writting GIF data to the file associated with +the given GIF handle and does memory clean-up. This function must be called once +after all desired frames have been added, in order to correctly save the GIF +file. After calling this function, the GIF handler cannot be used anymore. + + void close_gif(GIF* gif); + +(*) The encoder keeps two frame buffers internally, in order to implement the +size optimization. The address of `gif->frame` alternates between those two +buffers after each call to add_frame(). + + +Copying +------- + +All of the source code and documentation for gifenc is released into the +public domain and provided without warranty of any kind.