1 /* 2 * Copyright 2004 Richard Wilson <richard.wilson@netsurf-browser.org> 3 * Copyright 2008 Sean Fox <dyntryx@gmail.com> 4 * 5 * This file is part of NetSurf's libnsgif, http://www.netsurf-browser.org/ 6 * Licenced under the MIT License, 7 * http://www.opensource.org/licenses/mit-license.php 8 */ 9 10 /** 11 * \file 12 * Interface to progressive animated GIF file decoding. 13 */ 14 15 #ifndef _LIBNSGIF_H_ 16 #define _LIBNSGIF_H_ 17 18 #include <stdbool.h> 19 #include <inttypes.h> 20 21 /* Error return values */ 22 typedef enum { 23 GIF_WORKING = 1, 24 GIF_OK = 0, 25 GIF_INSUFFICIENT_FRAME_DATA = -1, 26 GIF_FRAME_DATA_ERROR = -2, 27 GIF_INSUFFICIENT_DATA = -3, 28 GIF_DATA_ERROR = -4, 29 GIF_INSUFFICIENT_MEMORY = -5, 30 GIF_FRAME_NO_DISPLAY = -6, 31 GIF_END_OF_FRAME = -7 32 } gif_result; 33 34 /** GIF frame data */ 35 typedef struct gif_frame { 36 /** whether the frame should be displayed/animated */ 37 bool display; 38 /** delay (in cs) before animating the frame */ 39 unsigned int frame_delay; 40 41 /* Internal members are listed below */ 42 43 /** offset (in bytes) to the GIF frame data */ 44 unsigned int frame_pointer; 45 /** whether the frame has previously been used */ 46 bool virgin; 47 /** whether the frame is totally opaque */ 48 bool opaque; 49 /** whether a forcable screen redraw is required */ 50 bool redraw_required; 51 /** how the previous frame should be disposed; affects plotting */ 52 unsigned char disposal_method; 53 /** whether we acknoledge transparency */ 54 bool transparency; 55 /** the index designating a transparent pixel */ 56 unsigned char transparency_index; 57 /** x co-ordinate of redraw rectangle */ 58 unsigned int redraw_x; 59 /** y co-ordinate of redraw rectangle */ 60 unsigned int redraw_y; 61 /** width of redraw rectangle */ 62 unsigned int redraw_width; 63 /** height of redraw rectangle */ 64 unsigned int redraw_height; 65 } gif_frame; 66 67 /* API for Bitmap callbacks */ 68 typedef void* (*gif_bitmap_cb_create)(int width, int height); 69 typedef void (*gif_bitmap_cb_destroy)(void *bitmap); 70 typedef unsigned char* (*gif_bitmap_cb_get_buffer)(void *bitmap); 71 typedef void (*gif_bitmap_cb_set_opaque)(void *bitmap, bool opaque); 72 typedef bool (*gif_bitmap_cb_test_opaque)(void *bitmap); 73 typedef void (*gif_bitmap_cb_modified)(void *bitmap); 74 75 /** Bitmap callbacks function table */ 76 typedef struct gif_bitmap_callback_vt { 77 /** Create a bitmap. */ 78 gif_bitmap_cb_create bitmap_create; 79 /** Free a bitmap. */ 80 gif_bitmap_cb_destroy bitmap_destroy; 81 /** Return a pointer to the pixel data in a bitmap. */ 82 gif_bitmap_cb_get_buffer bitmap_get_buffer; 83 84 /* Members below are optional */ 85 86 /** Sets whether a bitmap should be plotted opaque. */ 87 gif_bitmap_cb_set_opaque bitmap_set_opaque; 88 /** Tests whether a bitmap has an opaque alpha channel. */ 89 gif_bitmap_cb_test_opaque bitmap_test_opaque; 90 /** The bitmap image has changed, so flush any persistant cache. */ 91 gif_bitmap_cb_modified bitmap_modified; 92 } gif_bitmap_callback_vt; 93 94 /** GIF animation data */ 95 typedef struct gif_animation { 96 /** LZW decode context */ 97 void *lzw_ctx; 98 /** callbacks for bitmap functions */ 99 gif_bitmap_callback_vt bitmap_callbacks; 100 /** pointer to GIF data */ 101 unsigned char *gif_data; 102 /** width of GIF (may increase during decoding) */ 103 unsigned int width; 104 /** heigth of GIF (may increase during decoding) */ 105 unsigned int height; 106 /** number of frames decoded */ 107 unsigned int frame_count; 108 /** number of frames partially decoded */ 109 unsigned int frame_count_partial; 110 /** decoded frames */ 111 gif_frame *frames; 112 /** current frame decoded to bitmap */ 113 int decoded_frame; 114 /** currently decoded image; stored as bitmap from bitmap_create callback */ 115 void *frame_image; 116 /** number of times to loop animation */ 117 int loop_count; 118 119 /* Internal members are listed below */ 120 121 /** current index into GIF data */ 122 unsigned int buffer_position; 123 /** total number of bytes of GIF data available */ 124 unsigned int buffer_size; 125 /** current number of frame holders */ 126 unsigned int frame_holders; 127 /** index in the colour table for the background colour */ 128 unsigned int background_index; 129 /** image aspect ratio (ignored) */ 130 unsigned int aspect_ratio; 131 /** size of colour table (in entries) */ 132 unsigned int colour_table_size; 133 /** whether the GIF has a global colour table */ 134 bool global_colours; 135 /** global colour table */ 136 unsigned int *global_colour_table; 137 /** local colour table */ 138 unsigned int *local_colour_table; 139 } gif_animation; 140 141 /** 142 * Initialises necessary gif_animation members. 143 */ 144 void gif_create(gif_animation *gif, gif_bitmap_callback_vt *bitmap_callbacks); 145 146 /** 147 * Initialises any workspace held by the animation and attempts to decode 148 * any information that hasn't already been decoded. 149 * If an error occurs, all previously decoded frames are retained. 150 * 151 * @return Error return value. 152 * - GIF_FRAME_DATA_ERROR for GIF frame data error 153 * - GIF_INSUFFICIENT_FRAME_DATA for insufficient data to process 154 * any more frames 155 * - GIF_INSUFFICIENT_MEMORY for memory error 156 * - GIF_DATA_ERROR for GIF error 157 * - GIF_INSUFFICIENT_DATA for insufficient data to do anything 158 * - GIF_OK for successful decoding 159 * - GIF_WORKING for successful decoding if more frames are expected 160 */ 161 gif_result gif_initialise(gif_animation *gif, size_t size, unsigned char *data); 162 163 /** 164 * Decodes a GIF frame. 165 * 166 * @return Error return value. If a frame does not contain any image data, 167 * GIF_OK is returned and gif->current_error is set to 168 * GIF_FRAME_NO_DISPLAY 169 * - GIF_FRAME_DATA_ERROR for GIF frame data error 170 * - GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the frame 171 * - GIF_DATA_ERROR for GIF error (invalid frame header) 172 * - GIF_INSUFFICIENT_DATA for insufficient data to do anything 173 * - GIF_INSUFFICIENT_MEMORY for insufficient memory to process 174 * - GIF_OK for successful decoding 175 */ 176 gif_result gif_decode_frame(gif_animation *gif, unsigned int frame); 177 178 /** 179 * Releases any workspace held by a gif 180 */ 181 void gif_finalise(gif_animation *gif); 182 183 #endif 184