1 /* gif.h - Interface to the LCDF GIF library. 2 Copyright (C) 1997-2021 Eddie Kohler, ekohler@gmail.com 3 This file is part of the LCDF GIF library. 4 5 The GIF library is free software. It is distributed under the GNU General 6 Public License, version 2; you can copy, distribute, or alter it at will, 7 as long as this notice is kept intact and this source code is made 8 available. There is no warranty, express or implied. */ 9 10 #ifndef LCDF_GIF_H /* -*- mode: c -*- */ 11 #define LCDF_GIF_H 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <lcdf/inttypes.h> 15 #ifdef __cplusplus 16 extern "C" { 17 #endif 18 19 /* NOTE: You should define the types uint8_t, uint16_t and uint32_t before 20 including this file, probably by #including <inttypes.h>. */ 21 22 #define GIF_MAJOR_VERSION 2 23 #define GIF_MINOR_VERSION 0 24 #define GIF_VERSION "2.0" 25 26 typedef struct Gif_Stream Gif_Stream; 27 typedef struct Gif_Image Gif_Image; 28 typedef struct Gif_Colormap Gif_Colormap; 29 typedef struct Gif_Comment Gif_Comment; 30 typedef struct Gif_Extension Gif_Extension; 31 typedef struct Gif_Record Gif_Record; 32 33 typedef uint16_t Gif_Code; 34 #define GIF_MAX_CODE_BITS 12 35 #define GIF_MAX_CODE 0x1000 36 #define GIF_MAX_BLOCK 255 37 38 39 /** GIF_STREAM **/ 40 41 struct Gif_Stream { 42 Gif_Image **images; 43 int nimages; 44 int imagescap; 45 46 Gif_Colormap *global; 47 uint16_t background; /* 256 means no background */ 48 49 uint16_t screen_width; 50 uint16_t screen_height; 51 long loopcount; /* -1 means no loop count */ 52 53 Gif_Comment* end_comment; 54 Gif_Extension* end_extension_list; 55 56 unsigned errors; 57 uint32_t user_flags; 58 59 const char* landmark; 60 int refcount; 61 }; 62 63 Gif_Stream * Gif_NewStream(void); 64 void Gif_DeleteStream(Gif_Stream *); 65 66 Gif_Stream * Gif_CopyStreamSkeleton(Gif_Stream *); 67 Gif_Stream * Gif_CopyStreamImages(Gif_Stream *); 68 69 #define Gif_ScreenWidth(gfs) ((gfs)->screen_width) 70 #define Gif_ScreenHeight(gfs) ((gfs)->screen_height) 71 #define Gif_ImageCount(gfs) ((gfs)->nimages) 72 73 #define GIF_UNOPTIMIZE_SIMPLEST_DISPOSAL 1 74 #define GIF_MAX_SCREEN_WIDTH 65535 75 #define GIF_MAX_SCREEN_HEIGHT 65535 76 77 void Gif_CalculateScreenSize(Gif_Stream *, int force); 78 int Gif_Unoptimize(Gif_Stream *); 79 int Gif_FullUnoptimize(Gif_Stream *, int flags); 80 81 82 /** GIF_IMAGE **/ 83 84 struct Gif_Image { 85 uint8_t **img; /* img[y][x] == image byte (x,y) */ 86 uint8_t *image_data; 87 88 uint16_t width; 89 uint16_t height; 90 uint16_t left; 91 uint16_t top; 92 uint16_t delay; 93 uint8_t disposal; 94 uint8_t interlace; 95 96 short transparent; /* -1 means no transparent index */ 97 Gif_Colormap *local; 98 99 char* identifier; 100 Gif_Comment* comment; 101 Gif_Extension* extension_list; 102 103 void (*free_image_data)(void *); 104 105 uint32_t compressed_len; 106 uint32_t compressed_errors; 107 uint8_t* compressed; 108 void (*free_compressed)(void *); 109 110 uint32_t user_flags; 111 void* user_data; 112 void (*free_user_data)(void *); 113 int refcount; 114 115 }; 116 117 #define GIF_DISPOSAL_NONE 0 118 #define GIF_DISPOSAL_ASIS 1 119 #define GIF_DISPOSAL_BACKGROUND 2 120 #define GIF_DISPOSAL_PREVIOUS 3 121 122 Gif_Image * Gif_NewImage(void); 123 void Gif_DeleteImage(Gif_Image *gfi); 124 125 int Gif_AddImage(Gif_Stream *gfs, Gif_Image *gfi); 126 void Gif_RemoveImage(Gif_Stream *gfs, int i); 127 Gif_Image * Gif_CopyImage(Gif_Image *gfi); 128 void Gif_MakeImageEmpty(Gif_Image* gfi); 129 130 Gif_Image * Gif_GetImage(Gif_Stream *gfs, int i); 131 Gif_Image * Gif_GetNamedImage(Gif_Stream *gfs, const char *name); 132 int Gif_ImageNumber(Gif_Stream *gfs, Gif_Image *gfi); 133 134 #define Gif_ImageWidth(gfi) ((gfi)->width) 135 #define Gif_ImageHeight(gfi) ((gfi)->height) 136 #define Gif_ImageDelay(gfi) ((gfi)->delay) 137 #define Gif_ImageUserData(gfi) ((gfi)->userdata) 138 #define Gif_SetImageUserData(gfi, v) ((gfi)->userdata = v) 139 int Gif_ImageColorBound(const Gif_Image* gfi); 140 141 typedef void (*Gif_ReadErrorHandler)(Gif_Stream* gfs, 142 Gif_Image* gfi, 143 int is_error, 144 const char* error_text); 145 146 typedef struct { 147 int flags; 148 int loss; 149 void *padding[7]; 150 } Gif_CompressInfo; 151 152 #define Gif_UncompressImage(gfs, gfi) Gif_FullUncompressImage((gfs),(gfi),0) 153 int Gif_FullUncompressImage(Gif_Stream* gfs, Gif_Image* gfi, 154 Gif_ReadErrorHandler handler); 155 int Gif_CompressImage(Gif_Stream *gfs, Gif_Image *gfi); 156 int Gif_FullCompressImage(Gif_Stream *gfs, Gif_Image *gfi, 157 const Gif_CompressInfo *gcinfo); 158 void Gif_ReleaseUncompressedImage(Gif_Image *gfi); 159 void Gif_ReleaseCompressedImage(Gif_Image *gfi); 160 int Gif_SetUncompressedImage(Gif_Image *gfi, uint8_t *data, 161 void (*free_data)(void *), int data_interlaced); 162 int Gif_CreateUncompressedImage(Gif_Image* gfi, int data_interlaced); 163 164 int Gif_ClipImage(Gif_Image *gfi, int l, int t, int w, int h); 165 166 void Gif_InitCompressInfo(Gif_CompressInfo *gcinfo); 167 168 169 /** GIF_COLORMAP **/ 170 171 typedef struct { 172 uint8_t haspixel; /* semantics assigned by user */ 173 uint8_t gfc_red; /* red component (0-255) */ 174 uint8_t gfc_green; /* green component (0-255) */ 175 uint8_t gfc_blue; /* blue component (0-255) */ 176 uint32_t pixel; /* semantics assigned by user */ 177 } Gif_Color; 178 179 180 struct Gif_Colormap { 181 int ncol; 182 int capacity; 183 uint32_t user_flags; 184 int refcount; 185 Gif_Color *col; 186 }; 187 188 Gif_Colormap * Gif_NewColormap(void); 189 Gif_Colormap * Gif_NewFullColormap(int count, int capacity); 190 void Gif_DeleteColormap(Gif_Colormap *); 191 192 Gif_Colormap * Gif_CopyColormap(Gif_Colormap *); 193 194 int Gif_ColorEq(Gif_Color *, Gif_Color *); 195 #define GIF_COLOREQ(c1, c2) \ 196 ((c1)->gfc_red==(c2)->gfc_red && (c1)->gfc_green==(c2)->gfc_green && \ 197 (c1)->gfc_blue==(c2)->gfc_blue) 198 #define GIF_SETCOLOR(c, r, g, b) \ 199 ((c)->gfc_red = (r), (c)->gfc_green = (g), (c)->gfc_blue = (b)) 200 201 int Gif_FindColor(Gif_Colormap *, Gif_Color *); 202 int Gif_AddColor(Gif_Colormap *, Gif_Color *, int look_from); 203 204 205 /** GIF_COMMENT **/ 206 207 struct Gif_Comment { 208 char **str; 209 int *len; 210 int count; 211 int cap; 212 }; 213 214 Gif_Comment * Gif_NewComment(void); 215 void Gif_DeleteComment(Gif_Comment *); 216 int Gif_AddCommentTake(Gif_Comment *, char *, int); 217 int Gif_AddComment(Gif_Comment *, const char *, int); 218 219 220 /** GIF_EXTENSION **/ 221 222 struct Gif_Extension { 223 int kind; /* negative kinds are reserved */ 224 char* appname; 225 int applength; 226 uint8_t* data; 227 uint32_t length; 228 int packetized; 229 230 Gif_Stream *stream; 231 Gif_Image *image; 232 Gif_Extension *next; 233 void (*free_data)(void *); 234 }; 235 236 237 Gif_Extension* Gif_NewExtension(int kind, const char* appname, int applength); 238 void Gif_DeleteExtension(Gif_Extension* gfex); 239 Gif_Extension* Gif_CopyExtension(Gif_Extension* gfex); 240 int Gif_AddExtension(Gif_Stream* gfs, Gif_Image* gfi, 241 Gif_Extension* gfex); 242 243 244 /** READING AND WRITING **/ 245 246 struct Gif_Record { 247 const unsigned char *data; 248 uint32_t length; 249 }; 250 251 #define GIF_READ_COMPRESSED 1 252 #define GIF_READ_UNCOMPRESSED 2 253 #define GIF_READ_CONST_RECORD 4 254 #define GIF_READ_TRAILING_GARBAGE_OK 8 255 #define GIF_WRITE_CAREFUL_MIN_CODE_SIZE 1 256 #define GIF_WRITE_EAGER_CLEAR 2 257 #define GIF_WRITE_OPTIMIZE 4 258 #define GIF_WRITE_SHRINK 8 259 260 void Gif_SetErrorHandler(Gif_ReadErrorHandler handler); 261 Gif_Stream* Gif_ReadFile(FILE* f); 262 Gif_Stream* Gif_FullReadFile(FILE* f, int flags, const char* landmark, 263 Gif_ReadErrorHandler handler); 264 Gif_Stream* Gif_ReadRecord(const Gif_Record* record); 265 Gif_Stream* Gif_FullReadRecord(const Gif_Record* record, int flags, 266 const char* landmark, 267 Gif_ReadErrorHandler handler); 268 int Gif_WriteFile(Gif_Stream *gfs, FILE *f); 269 int Gif_FullWriteFile(Gif_Stream *gfs, 270 const Gif_CompressInfo *gcinfo, FILE *f); 271 272 #define Gif_ReadFile(f) Gif_FullReadFile((f),GIF_READ_UNCOMPRESSED,0,0) 273 #define Gif_ReadRecord(r) Gif_FullReadRecord((r),GIF_READ_UNCOMPRESSED,0,0) 274 #define Gif_CompressImage(s, i) Gif_FullCompressImage((s),(i),0) 275 #define Gif_WriteFile(s, f) Gif_FullWriteFile((s),0,(f)) 276 277 typedef struct Gif_Writer Gif_Writer; 278 Gif_Writer* Gif_IncrementalWriteFileInit(Gif_Stream* gfs, const Gif_CompressInfo* gcinfo, FILE *f); 279 int Gif_IncrementalWriteImage(Gif_Writer* grr, Gif_Stream* gfs, Gif_Image* gfi); 280 int Gif_IncrementalWriteComplete(Gif_Writer* grr, Gif_Stream* gfs); 281 282 283 /** HOOKS AND MISCELLANEOUS **/ 284 285 int Gif_InterlaceLine(int y, int height); 286 char * Gif_CopyString(const char *); 287 288 #define GIF_T_STREAM (0) 289 #define GIF_T_IMAGE (1) 290 #define GIF_T_COLORMAP (2) 291 typedef void (*Gif_DeletionHookFunc)(int, void *, void *); 292 int Gif_AddDeletionHook(int, Gif_DeletionHookFunc, void *); 293 void Gif_RemoveDeletionHook(int, Gif_DeletionHookFunc, void *); 294 295 #ifdef GIF_DEBUGGING 296 #define GIF_DEBUG(x) Gif_Debug x 297 void Gif_Debug(char *x, ...); 298 #else 299 #define GIF_DEBUG(x) 300 #endif 301 302 void* Gif_Realloc(void* p, size_t s, size_t n, 303 const char* file, int line); 304 void Gif_Free(void* p); 305 #if !GIF_ALLOCATOR_DEFINED 306 # define Gif_Free free 307 #endif 308 309 #ifndef Gif_New 310 # define Gif_New(t) ((t*) Gif_Realloc(0, sizeof(t), 1, __FILE__, __LINE__)) 311 # define Gif_NewArray(t, n) ((t*) Gif_Realloc(0, sizeof(t), (n), __FILE__, __LINE__)) 312 # define Gif_ReArray(p, t, n) ((p)=(t*) Gif_Realloc((void*) (p), sizeof(t), (n), __FILE__, __LINE__)) 313 # define Gif_Delete(p) Gif_Free((void*) (p)) 314 # define Gif_DeleteArray(p) Gif_Free((void*) (p)) 315 #endif 316 317 #ifdef __cplusplus 318 } 319 #endif 320 #endif 321