gif

read/write GIFs
git clone git://bvnf.space/gm.git
Log | Files | Refs | README

commit f30dbdf7867e888d08480a141af3b0572fd09084
parent f9bcb3eb69976b7eefa42da8438f659e502e2b37
Author: phoebos <ben@bvnf.space>
Date:   Wed,  1 Sep 2021 22:36:39 +0100

image block header handling

Diffstat:
Mgif.c | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 58 insertions(+), 4 deletions(-)

diff --git a/gif.c b/gif.c @@ -39,6 +39,14 @@ struct Gif { }; struct Image { struct Color_table *lct; + uint16_t left, top, width, height; + unsigned char flags; /* AB000CCC + A: 0 -> use GCT, ignore C + 1 -> LCT follows, use C + B: 0 -> image is in Sequential order + 1 -> image is in Interlaced order + C+1: bits per pixel for this image + */ unsigned char *pixels; }; @@ -51,10 +59,56 @@ print_colortable(struct Color_table *c){ } } +/* gif_decode_image should be called with buf pointing to the separator + * character, ','. gct should be a pointer to the global color table. + */ int -gif_decode_image(struct Image *img, unsigned char *buf){ - (void) img; - (void) buf; +gif_decode_image(struct Image *img, struct Color_table *gct, unsigned char *buf){ + if (*buf++ != ','){ + fprintf(stderr, "not an image block\n"); + return FAIL_GIF; + } + struct Color_table *ct = gct; + + /* Get the top, left, width, and height from the beginning of buf. + * They are all 2 byte numbers with the LSB first. */ + uint16_t *tmp; + tmp = (uint16_t *)buf; + img->left = *tmp; + buf += 2; + tmp = (uint16_t *)buf; + img->top = *tmp; + buf += 2; + tmp = (uint16_t *)buf; + img->width = *tmp; + buf += 2; + tmp = (uint16_t *)buf; + img->height = *tmp; + buf += 2; + + fprintf(stderr, "image block starts at %d,%d with dimensions %d,%d\n", + img->left, img->top, img->width, img->height); + + img->flags = *buf++; + + if (img->flags && 0x80) { + /* local color table follows */ + fprintf(stderr, "using LCT(%d), ", img->flags && 7); + } else { + /* use GCT */ + fprintf(stderr, "using GCT, "); + } + + if (img->flags && 0x40) { + /* image is interlaced */ + fprintf(stderr, "interlaced\n"); + /* TODO */ + return -1; + } else { + /* image is sequential */ + fprintf(stderr, "sequential\n"); + } + return 0; } @@ -122,7 +176,7 @@ gif_decode(unsigned char *buf, size_t len){ img = malloc(sizeof(struct Image)); img->lct = malloc(sizeof(struct Color_table)); img->lct->len = g.gct->len; - gif_decode_image(img, buf); + gif_decode_image(img, g.gct, buf); } break; case ';':