commit f30dbdf7867e888d08480a141af3b0572fd09084
parent f9bcb3eb69976b7eefa42da8438f659e502e2b37
Author: phoebos <ben@bvnf.space>
Date: Wed, 1 Sep 2021 22:36:39 +0100
image block header handling
Diffstat:
M | gif.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 ';':