diff options
-rw-r--r-- | src/gif.c | 93 | ||||
-rw-r--r-- | src/main.c | 7 |
2 files changed, 73 insertions, 27 deletions
@@ -2,11 +2,15 @@ #include <stdio.h> #include <string.h> +#include <assert.h> + #include "meh.h" #define GIF87a 0 #define GIF89a 1 +#define MAX_CODES 4096 + unsigned char *loadgif(FILE *infile, int *bufwidth, int *bufheight){ int version; unsigned char *palette; @@ -89,12 +93,13 @@ unsigned char *loadgif(FILE *infile, int *bufwidth, int *bufheight){ } buf = malloc((*bufwidth) * (*bufheight) * 3); + memset(buf, 0, (*bufwidth) * (*bufheight) * 3); { unsigned int initcodesize, curcodesize; unsigned int clearcode, endcode, newcode; int bytesleft = 0; - int i; + int i = 0; /* Get code size */ initcodesize = fgetc(infile); @@ -108,36 +113,39 @@ unsigned char *loadgif(FILE *infile, int *bufwidth, int *bufheight){ newcode = endcode + 1; int count = 0; + int byte0 = -1, byte1 = -1, byteshift = 0; + unsigned int suffix[MAX_CODES * 3]; + unsigned int prefix[MAX_CODES]; + int length[MAX_CODES]; + + goto clear; for(;;){ - int byte0 = -1, byte1 = -1, byteshift = 0; - if(1){ - bytesleft = fgetc(infile); - printf("%i\n", bytesleft); - if(bytesleft < 0){ - printf("unexpected EOF (0)\n"); - return NULL; - }else if(bytesleft == 0) - break; - } - printf("start %i, %i\n", count++, bytesleft); for(;;){ + count++; + int a, b, c; int code; /* get code */ while(byte1 == -1){ + if(!bytesleft){ + bytesleft = fgetc(infile); + if(bytesleft < 0){ + printf("unexpected EOF (0)\n"); + return NULL; + }else if(bytesleft == 0) + break; + } if((byte1 = fgetc(infile)) == EOF){ printf("unexpected EOF (1)\n"); return NULL; } if(byte0 == -1){ byte0 = byte1; + byte1 = -1; } bytesleft--; } - if(bytesleft < 0){ - break; - } - code = (byte0 | byte1 << 8) >> byteshift & ((1 << curcodesize) - 1); + code = ((byte0 | (byte1 << 8)) >> byteshift) & ((1 << curcodesize) - 1); byteshift += curcodesize; while(byteshift >= 8){ byte0 = byte1; @@ -146,19 +154,54 @@ unsigned char *loadgif(FILE *infile, int *bufwidth, int *bufheight){ } if(code == clearcode){ - printf("clearcode\n"); +clear: + printf("%i. clear\n", count); curcodesize = initcodesize + 1; - newcode = endcode + 1; + newcode = endcode; /* endcode is also used as a sentinel */ + for(a = 0; a < clearcode; a++){ + length[a] = 0; + prefix[a] = 0; + + suffix[a*3] = palette[a*3]; + suffix[a*3+1] = palette[a*3+1]; + suffix[a*3+2] = palette[a*3+2]; + } + }else if(code == endcode){ - printf("endcode with %i bytes left\n", bytesleft); - break; + printf("%i. endcode\n", count); + return buf; }else{ + assert(newcode < MAX_CODES); + printf("newcode: %x\n", newcode); + if(code <= newcode){ + printf("%i. dict\n", count); + prefix[newcode+1] = i; + length[newcode+1] = length[code] + 1; + for(a = prefix[code]; a < prefix[code] + length[code]; a++){ + buf[i*3] = buf[a*3]; + buf[i*3+1] = buf[a*3+1]; + buf[i*3+2] = buf[a*3+2]; + i++; + } + buf[i*3] = suffix[code*3]; + buf[i*3+1] = suffix[code*3+1]; + buf[i*3+2] = suffix[code*3+1]; + i++; + + suffix[newcode*3 + 3] = suffix[newcode*3] = buf[prefix[newcode+1] * 3]; + suffix[newcode*3 + 4] = suffix[newcode*3 + 1] = buf[prefix[newcode+1] * 3 + 1]; + suffix[newcode*3 + 5] = suffix[newcode*3 + 2] = buf[prefix[newcode+1] * 3 + 2]; + printf("codes[%x] = {%x,%x,%x}\n", newcode, prefix[newcode], length[newcode], suffix[newcode]); + }else{ + printf("code > newcode (%x > %x)\n", code, newcode); + return buf; + //exit(1); + } + newcode++; - } - - /* process code */ - if(newcode == 1 << curcodesize){ - curcodesize++; + if(newcode == 1 << curcodesize){ + curcodesize++; + } } } } @@ -27,8 +27,8 @@ static int popcount(unsigned long mask){ #else int y; - y = (mask >> 1) &033333333333; - y = mask - y - ((y >>1) & 033333333333); + y = (mask >> 1) & 033333333333; + y = mask - y - ((y >> 1) & 033333333333); return (((y + (y >> 3)) & 030707070707) % 077); #endif } @@ -193,6 +193,7 @@ void run(struct imagenode *image){ XNextEvent(display, &event); switch(event.type){ case MapNotify: + printf("map\n"); break; case ConfigureNotify: if(width != event.xconfigure.width || height != event.xconfigure.height){ @@ -202,9 +203,11 @@ void run(struct imagenode *image){ width = event.xconfigure.width; height = event.xconfigure.height; } + printf("%i, %i\n", width, height); break; case Expose: redraw = 1; + printf("expose\n"); break; case KeyPress: switch(XLookupKeysym(&event.xkey, 0)){ |