gif

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

commit acf7073c322f297f89a531271169a5603253ed53
parent 1a5017f69e05703dabe5a06e17450422f09c24bf
Author: phoebos <ben@bvnf.space>
Date:   Wed,  1 Sep 2021 22:59:44 +0100

format

Diffstat:
Mgif.c | 115+++++++++++++++++++++++++++++++++++++++++--------------------------------------
1 file changed, 59 insertions(+), 56 deletions(-)

diff --git a/gif.c b/gif.c @@ -5,10 +5,10 @@ * where each pixel is a number corresponding to the index of the color. */ -#include <math.h> #include <fcntl.h> -#include <stdio.h> +#include <math.h> #include <stdint.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -26,13 +26,13 @@ struct Gif { char version[3]; /* 87a or 89a */ uint16_t width; uint16_t height; - unsigned char flags; /* ABBBCDDD - A: global colour table [GCT] flag - B+1: colour resolution (bits per primary colour) - C: GCT sort flag (89a+ only) - D+1: bits used per pixel in GCT - */ - unsigned char background; /* color index in GCT of screen background */ + unsigned char flags; /* ABBBCDDD + A: global colour table [GCT] flag + B+1: colour resolution (bits per primary colour) + C: GCT sort flag (89a+ only) + D+1: bits used per pixel in GCT + */ + unsigned char background; /* color index in GCT of screen background */ unsigned char aspect_ratio; /* 89a+ only */ struct Color_table *gct; unsigned char *pixels; /* array of indices to colors */ @@ -51,11 +51,11 @@ struct Image { }; void -print_colortable(struct Color_table *c){ - for (int i = 0; i < c->len; i++){ - printf("%d: \033[48;2;%d;%d;%dm(%02x;%02x;%02x)\033[0m\n", - i, c->table[i][0], c->table[i][1], c->table[i][2], - c->table[i][0], c->table[i][1], c->table[i][2]); +print_colortable(struct Color_table *c) { + for (int i = 0; i < c->len; i++) { + printf("%d: \033[48;2;%d;%d;%dm(%02x;%02x;%02x)\033[0m\n", i, + c->table[i][0], c->table[i][1], c->table[i][2], c->table[i][0], + c->table[i][1], c->table[i][2]); } } @@ -63,8 +63,9 @@ print_colortable(struct Color_table *c){ * character, ','. gct should be a pointer to the global color table. */ int -gif_decode_image(struct Image *img, struct Color_table *gct, unsigned char *buf){ - if (*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; } @@ -113,8 +114,8 @@ gif_decode_image(struct Image *img, struct Color_table *gct, unsigned char *buf) } int -gif_decode(unsigned char *buf, size_t len){ - struct Gif g = {0 }; +gif_decode(unsigned char *buf, size_t len) { + struct Gif g = {0}; g.gct = malloc(sizeof(struct Color_table)); if (g.gct == NULL) { perror("malloc"); @@ -126,7 +127,8 @@ gif_decode(unsigned char *buf, size_t len){ cur_block = HEAD; (void)cur_block; - if (strncmp((char *)buf, "GIF", 3)) return FAIL_GIF; + if (strncmp((char *)buf, "GIF", 3)) + return FAIL_GIF; buf += 3; len -= 3; strncpy(g.version, (char *)buf, 3); @@ -150,13 +152,13 @@ gif_decode(unsigned char *buf, size_t len){ g.background = *buf++; g.aspect_ratio = *buf++; - g.gct->len = (int)pow(2.0, (double) (g.flags & 7U) + 1); + g.gct->len = (int)pow(2.0, (double)(g.flags & 7U) + 1); fprintf(stderr, "%d colors in GCT\n", g.gct->len); /* if GCT... */ if (g.flags & 0x80) { /* TODO: gif87a.txt L 336? */ - for (int i = 0; i < g.gct->len; i+=1) { + for (int i = 0; i < g.gct->len; i += 1) { rgb c = {*buf++, *buf++, *buf++}; memcpy(g.gct->table[i], c, sizeof(rgb)); } @@ -169,31 +171,31 @@ gif_decode(unsigned char *buf, size_t len){ while (--len) { ++buf; switch (*buf) { - case '!': - if (cur_block != SPEC) { - cur_block = SPEC; + case '!': + if (cur_block != SPEC) { + cur_block = SPEC; + } + break; + case ',': + if (cur_block != IMGE) { + cur_block = IMGE; + img = malloc(sizeof(struct Image)); + if (img == NULL) { + perror("malloc"); + exit(FAIL_SYS); } - break; - case ',': - if (cur_block != IMGE) { - cur_block = IMGE; - img = malloc(sizeof(struct Image)); - if (img == NULL) { - perror("malloc"); - exit(FAIL_SYS); - } - img->lct = malloc(sizeof(struct Color_table)); - if (img->lct == NULL) { - perror("malloc"); - exit(FAIL_SYS); - } - img->lct->len = g.gct->len; - gif_decode_image(img, g.gct, buf); + img->lct = malloc(sizeof(struct Color_table)); + if (img->lct == NULL) { + perror("malloc"); + exit(FAIL_SYS); } - break; - case ';': - /* last char of image section */ - return 0; + img->lct->len = g.gct->len; + gif_decode_image(img, g.gct, buf); + } + break; + case ';': + /* last char of image section */ + return 0; } } free(img); @@ -202,7 +204,7 @@ gif_decode(unsigned char *buf, size_t len){ } int -main(int argc, char **argv){ +main(int argc, char **argv) { int fd; /* only work on one file */ @@ -213,7 +215,8 @@ main(int argc, char **argv){ ++argv; /* stdin */ - if (argc == 1 || **argv == '-') fd = 0; + if (argc == 1 || **argv == '-') + fd = 0; else { /* open named file */ fd = open(*argv, O_RDONLY); @@ -224,7 +227,7 @@ main(int argc, char **argv){ } unsigned char *buf; - buf = (unsigned char *) malloc(BUF_SIZE); + buf = malloc(BUF_SIZE); if (buf == NULL) { perror("malloc"); exit(FAIL_SYS); @@ -250,7 +253,8 @@ main(int argc, char **argv){ buf = tmp; } bytes = read(fd, buf + used, BUF_SIZE); - if (bytes == 0) break; /* EOF */ + if (bytes == 0) + break; /* EOF */ if (bytes < 0) { perror("read"); return FAIL_SYS; @@ -265,16 +269,15 @@ main(int argc, char **argv){ int ret = gif_decode(buf, used); switch (ret) { - case FAIL_GIF: - fprintf(stderr, "error: invalid GIF format\n"); - return FAIL_GIF; - case 0: - break; - default: - return ret; + case FAIL_GIF: + fprintf(stderr, "error: invalid GIF format\n"); + return FAIL_GIF; + case 0: + break; + default: + return ret; } - free(buf); return 0; }