aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohn Hawthorn <jhawthor@uvic.ca>2008-06-14 00:26:13 -0700
committerJohn Hawthorn <jhawthor@uvic.ca>2008-06-14 00:26:13 -0700
commit1b9ee887b6cb5f6cf0824f2e3b5ff503daa6f0be (patch)
treea1243ded18e8e2ad064fbe2c553acb814a2a8016 /src
parent79117a49ad8b913f16365e5fea4cf50aa9346f7f (diff)
downloadmirror-meh-1b9ee887b6cb5f6cf0824f2e3b5ff503daa6f0be.tar.gz
mirror-meh-1b9ee887b6cb5f6cf0824f2e3b5ff503daa6f0be.tar.bz2
mirror-meh-1b9ee887b6cb5f6cf0824f2e3b5ff503daa6f0be.zip
working gif support
Diffstat (limited to 'src')
-rw-r--r--src/gif.c252
-rw-r--r--src/main.c3
2 files changed, 31 insertions, 224 deletions
diff --git a/src/gif.c b/src/gif.c
index 676fd98..93a4517 100644
--- a/src/gif.c
+++ b/src/gif.c
@@ -4,232 +4,42 @@
#include <assert.h>
-#include "meh.h"
-
-#define GIF87a 0
-#define GIF89a 1
+#include <gif_lib.h>
-#define MAX_CODES 4096
+#include "meh.h"
-unsigned char *loadgif(FILE *infile, int *bufwidth, int *bufheight){
- int version;
- unsigned char *palette;
- int pallen;
- unsigned char *buf = NULL;
- unsigned int bpp;
- {
- /* Read header*/
- unsigned char packed;
- unsigned char header[13];
-
- if(fread(header, 1, 13, infile) != 13)
- return NULL;
- if(!memcmp("GIF89a", header, 6))
- version = GIF89a;
- else if(!memcmp("GIF87a", header, 6))
- version = GIF87a;
- else
- return NULL;
-
- *bufwidth = header[6] | header[7] << 8;
- *bufheight = header[8] | header[9] << 8;
- packed = header[10];
- bpp = (packed & 7) + 1;
+unsigned char *loadgif(FILE *f, int *bufwidth, int *bufheight){
+ GifFileType *gif;
+ SavedImage *img;
+ GifColorType *colormap;
- /* Read colormap */
- if(packed & 0x80){
- printf("Reading palette\n");
- pallen = 1 << bpp;
- printf("pallen: %i\n", pallen);
- palette = malloc(3 * pallen);
- fread(palette, 1, 3 * pallen, infile);
- }
+ unsigned char *buf;
+ if(!(gif = DGifOpenFileHandle(fileno(f)))){
+ return NULL;
}
-
- {
- int blocktype;
- while((blocktype = fgetc(infile)) != EOF){
- if(blocktype == ';'){
- printf("end of file\n");
- break;
- }else if(blocktype == '!'){
- int bytecount, fncode;
- if((fncode = fgetc(infile)) == EOF)
- return NULL;
- while(1){
- bytecount = fgetc(infile);
- printf("Skipping extblock 0x%x\n", fncode);
- if(bytecount == EOF)
- return NULL;
- else if(bytecount > 0)
- fseek(infile, bytecount, SEEK_CUR);
- else
- break;
- }
- }else if(blocktype == ','){
- int imagex, imagey, imagew, imageh;
- unsigned char imagedesc[9];
- if(fread(imagedesc, 1, 9, infile) != 9)
- return NULL;
- if(imagedesc[8] & 0x80){
- printf("ERROR: local palettes not supported\n");
- return NULL;
- }
- if(imagedesc[8] & 0x40){
- printf("ERROR: interlaced images\n");
- return NULL;
- }
-
- imagex = imagedesc[0] | imagedesc[1] << 8;
- imagey = imagedesc[2] | imagedesc[3] << 8;
- imagew = imagedesc[4] | imagedesc[5] << 8;
- imageh = imagedesc[6] | imagedesc[7] << 8;
-
- if(imagex != 0 || imagey != 0 || imagew != *bufwidth || imageh != *bufheight){
- printf("%ix%i %ix%i\n", imagex, imagey, imagew, imageh);
- printf("TODO: allow this sort of thing\n");
- return NULL;
- }
-
- 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 = 0;
-
- /* Get code size */
- initcodesize = fgetc(infile);
- if(initcodesize < 1 || initcodesize > 9){
- printf("bad code size %i\n", initcodesize);
- return NULL;
- }
- curcodesize = initcodesize + 1;
- clearcode = 1 << initcodesize;
- endcode = clearcode + 1;
- 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(;;){
- 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--;
- }
- code = ((byte0 | (byte1 << 8)) >> byteshift) & ((1 << curcodesize) - 1);
- byteshift += curcodesize;
- while(byteshift >= 8){
- byte0 = byte1;
- byte1 = -1;
- byteshift -= 8;
- }
-
- if(code == clearcode){
- if(i){
- buf[(i-1)*3] = 0xff;
- buf[(i-1)*3+1] = 0;
- buf[(i-1)*3+2] = 0;
- }
-clear:
- printf("%i. clear\n", count);
- curcodesize = initcodesize + 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("%i. endcode\n", count);
- return buf;
- }else{
- assert(newcode < MAX_CODES);
- if(code <= newcode){
- 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];
- }else{
- printf("code > newcode (%x > %x)\n", code, newcode);
- return buf;
- //exit(1);
- }
-
- newcode++;
- if(newcode >= 1 << curcodesize){
- buf[(i-1)*3] = 0xff;
- buf[(i-1)*3+1] = 0;
- buf[(i-1)*3+2] = 0xff;
- curcodesize++;
- printf("curcodesize = %i\n", curcodesize);
- if(curcodesize == 11){
- curcodesize = 11;
- }
- }
- }
- }
- }
-
- /*for(i = 0; i < (*bufwidth) * (*bufheight); i++){
- }*/
- printf("good end\n");
- return buf;
- }
-
- break;
- }else{
- printf("Unknown block type %i\n", blocktype);
- return NULL;
- }
- }
+ if(DGifSlurp(gif) == GIF_ERROR){
+ return NULL;
}
-
- printf("end\n");
- return NULL;
+ img = &gif->SavedImages[0];
+ *bufwidth = img->ImageDesc.Width;
+ *bufheight = img->ImageDesc.Height;
+ buf = malloc(img->ImageDesc.Width * img->ImageDesc.Height * 3);
+
+ if(img->ImageDesc.ColorMap)
+ colormap = img->ImageDesc.ColorMap->Colors;
+ else if(gif->SColorMap)
+ colormap = gif->SColorMap->Colors;
+ else
+ return NULL;
+
+ int i, j = 0;
+ for(i = 0; i < img->ImageDesc.Width * img->ImageDesc.Height; i++){
+ unsigned char idx = img->RasterBits[i];
+ buf[j++] = colormap[idx].Red;
+ buf[j++] = colormap[idx].Green;
+ buf[j++] = colormap[idx].Blue;
+ }
+ return buf;
}
diff --git a/src/main.c b/src/main.c
index 41b09ce..c116fab 100644
--- a/src/main.c
+++ b/src/main.c
@@ -206,7 +206,6 @@ void run(struct imagenode *image){
case MapNotify:
break;
case ConfigureNotify:
- printf("ConfigureNotify\n");
if(width != event.xconfigure.width || height != event.xconfigure.height){
if(img){
free(img->data);
@@ -273,7 +272,6 @@ void run(struct imagenode *image){
free(tmp);
}
setaspect(bufwidth, bufheight);
- printf("setaspect\n");
}
if(!img){
if(width * bufheight > height * bufwidth){
@@ -295,7 +293,6 @@ void run(struct imagenode *image){
yoffset = 0;
}
img = create_image_from_buffer(buf, imagewidth, imageheight, bufwidth, bufheight);
- printf("img\n");
assert(img);
}
XFillRectangle(display, window, gc, 0, 0, fillw, fillh);