From 5f3b08cd9452e26e67ee02c9ce0ce128afd8bb31 Mon Sep 17 00:00:00 2001 From: ericm Date: Thu, 27 Jan 2000 16:58:42 +0000 Subject: * generic/tkImgGIF.c: Additional code cleanup (now we only have one decoder! neat!) --- generic/tkImgGIF.c | 207 ++++++++++++----------------------------------------- 1 file changed, 44 insertions(+), 163 deletions(-) diff --git a/generic/tkImgGIF.c b/generic/tkImgGIF.c index 52ba2d7..87a90c7 100644 --- a/generic/tkImgGIF.c +++ b/generic/tkImgGIF.c @@ -29,7 +29,7 @@ * | provided "as is" without express or implied warranty. | * +-------------------------------------------------------------------+ * - * RCS: @(#) $Id: tkImgGIF.c,v 1.9 2000/01/26 21:11:00 ericm Exp $ + * RCS: @(#) $Id: tkImgGIF.c,v 1.10 2000/01/27 16:58:42 ericm Exp $ */ /* @@ -131,8 +131,6 @@ static int GetCode _ANSI_ARGS_((Tcl_Channel chan, int code_size, int flag)); static int GetDataBlock _ANSI_ARGS_((Tcl_Channel chan, unsigned char *buf)); -static int LWZReadByte _ANSI_ARGS_((Tcl_Channel chan, int flag, - int input_code_size)); static int ReadColorMap _ANSI_ARGS_((Tcl_Channel chan, int number, unsigned char buffer[MAXCOLORMAPSIZE][4])); static int ReadGIFHeader _ANSI_ARGS_((Tcl_Channel chan, @@ -229,6 +227,7 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY, Tcl_Obj **objv; Tk_PhotoImageBlock block; unsigned char buf[100]; + unsigned char *trashBuffer = NULL; int bitPixel; unsigned char colorMap[MAXCOLORMAPSIZE][4]; int transparent = -1; @@ -361,37 +360,49 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY, bitPixel = 1<<((buf[8]&0x07)+1); if (index--) { - int x,y; - unsigned char c; /* this is not the image we want to read: skip it. */ - if (BitSet(buf[8], LOCALCOLORMAP)) { - if (!ReadColorMap(chan, bitPixel, 0)) { + if (!ReadColorMap(chan, bitPixel, colorMap)) { Tcl_AppendResult(interp, "error reading color map", (char *) NULL); goto error; } } - /* read data */ - if (!ReadOK(chan,&c,1)) { - goto error; + /* If we've not yet allocated a trash buffer, do so now */ + if (trashBuffer == NULL) { + nBytes = fileWidth * fileHeight * 3; + trashBuffer = + (unsigned char *) ckalloc((unsigned int) nBytes); } - LWZReadByte(chan, 1, c); - - for (y=0; y ReadImage, it would change to FileReadGIF. + * It sure would be nice if ReadImage didn't take 11 parameters! I think + * that if we were smarter, we could avoid doing that. * * Possible further optimizations: we could pull the GetCode function - * directly into ReadImage, which would improve our speed. The reason - * I have not yet done so is because GetCode is still used by LWZReadByte, - * and I don't want to duplicate the code. + * directly into ReadImage, which would improve our speed. * * Results: * Processes a GIF image and loads the pixel data into a memory array. @@ -768,19 +772,18 @@ ReadImage(interp, imagePtr, chan, len, rows, cmap, unsigned char initialCodeSize; int v; int xpos = 0, ypos = 0, pass = 0, i; - char *pixelPtr; + register char *pixelPtr; const static int interlaceStep[] = { 8, 8, 4, 2 }; const static int interlaceStart[] = { 0, 4, 2, 1 }; unsigned short prefix[(1 << MAX_LWZ_BITS)]; unsigned char append[(1 << MAX_LWZ_BITS)]; unsigned char stack[(1 << MAX_LWZ_BITS)*2]; - unsigned char *top; + register unsigned char *top; int codeSize, clearCode, inCode, endCode, oldCode, maxCode, code, firstCode; - /* - * Initialize the decompression routines + * Initialize the decoder */ if (! ReadOK(chan, &initialCodeSize, 1)) { Tcl_AppendResult(interp, "error reading GIF image: ", @@ -920,6 +923,12 @@ ReadImage(interp, imagePtr, chan, len, rows, cmap, if (v < 0) { return TCL_OK; } + + /* + * If pixelPtr is null, we're skipping this image (presumably + * there are more in the file and we will be called to read + * one of them later) + */ *pixelPtr++ = cmap[v][CM_RED]; *pixelPtr++ = cmap[v][CM_GREEN]; *pixelPtr++ = cmap[v][CM_BLUE]; @@ -927,6 +936,7 @@ ReadImage(interp, imagePtr, chan, len, rows, cmap, *pixelPtr++ = cmap[v][CM_ALPHA]; } xpos++; + } /* If interlacing, the next ypos is not just +1 */ @@ -947,135 +957,6 @@ ReadImage(interp, imagePtr, chan, len, rows, cmap, return TCL_OK; } -static int -LWZReadByte(chan, flag, input_code_size) - Tcl_Channel chan; - int flag; - int input_code_size; -{ - static int fresh = 0; - int code, incode; - static int code_size, set_code_size; - static int max_code, max_code_size; - static int firstcode, oldcode; - static int clear_code, end_code; - static int prefix[(1 << MAX_LWZ_BITS)]; - static int append[(1 << MAX_LWZ_BITS)]; - static int stack[(1<<(MAX_LWZ_BITS))*2], *sp; - register int i; - - if (flag) { - set_code_size = input_code_size; - code_size = set_code_size+1; - clear_code = 1 << set_code_size ; - end_code = clear_code + 1; - max_code_size = 2*clear_code; - max_code = clear_code+2; - - /* Init the lwz unpacker */ - GetCode(chan, 0, 1); - - fresh = 1; - - /* Initialize prefix and append tables */ - memset((void *)prefix, 0, (1 << MAX_LWZ_BITS) * sizeof(int)); - memset((void *)append, 0, (1 << MAX_LWZ_BITS) * sizeof(int)); - for (i = 0; i < clear_code; ++i) { - append[i] = i; - } - sp = stack; - - return 0; - } else if (fresh) { - /* - * find the first "real" code and return that. Because of - * how LWZ works, it will necessarily refer to a single char, - * so we need not bother with the stack - */ - fresh = 0; - do { - firstcode = GetCode(chan, code_size, 0); - } while (firstcode == clear_code); - oldcode = firstcode; - return firstcode; - } - - if (sp > stack) { - return *--sp; - } - - while ((code = GetCode(chan, code_size, 0)) >= 0) { - if (code == clear_code) { - memset((void *)prefix, 0, (1 << MAX_LWZ_BITS) * sizeof(int)); - memset((void *)append, 0, (1 << MAX_LWZ_BITS) * sizeof(int)); - for (i = 0; i < clear_code; ++i) { - append[i] = i; - } - - code_size = set_code_size+1; - max_code_size = 2*clear_code; - max_code = clear_code+2; - sp = stack; - firstcode = oldcode = GetCode(chan, code_size, 0); - return firstcode; - - } else if (code == end_code) { - int count; - unsigned char buf[260]; - - if (ZeroDataBlock) { - return -2; - } - - while ((count = GetDataBlock(chan, buf)) > 0) - /* Empty body */; - - if (count != 0) { - return -2; - } - } - - incode = code; - - if (code >= max_code) { - *sp++ = firstcode; - code = oldcode; - } - - while (code >= clear_code) { - *sp++ = append[code]; - if (code == prefix[code]) { - return -2; - - /* - * Used to be this instead, Steve Ball suggested - * the change to just return. - printf("circular table entry BIG ERROR\n"); - */ - } - code = prefix[code]; - } - - *sp++ = firstcode = append[code]; - - if ((code = max_code) <(1<=max_code_size) && (max_code_size < (1< stack) - return *--sp; - } - return code; -} - /* *---------------------------------------------------------------------- -- cgit v0.12