diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | generic/tkImgGIF.c | 75 | ||||
-rw-r--r-- | tests/imgPhoto.test | 55 |
3 files changed, 76 insertions, 61 deletions
@@ -1,3 +1,10 @@ +2000-07-05 Eric Melski <ericm@scriptics.com> + + * tests/imgPhoto.test: Added test for GIF writing code [Bug: 5823]. + + * generic/tkImgGIF.c: Applied patch from Jan Nijtmans to fix a + problem with the GIF writing code [Bug: 5823]. + 2000-07-05 Eric Melski <ericm@ajubasolutions.com> * library/msgs/nl.msg: Dutch message catalog for dialogs, from Jan diff --git a/generic/tkImgGIF.c b/generic/tkImgGIF.c index 6770f06..3ab6753 100644 --- a/generic/tkImgGIF.c +++ b/generic/tkImgGIF.c @@ -2,8 +2,8 @@ * tkImgGIF.c -- * * A photo image file handler for GIF files. Reads 87a and 89a GIF - * files. At present, there only is a file write function. GIF images may be - * read using the -data option of the photo image. The data may be + * files. At present, there only is a file write function. GIF images + * may be read using the -data option of the photo image. The data may be * given as a binary string in a Tcl_Obj or by representing * the data as BASE64 encoded ascii. Derived from the giftoppm code * found in the pbmplus package and tkImgFmtPPM.c in the tk4.0b2 @@ -29,7 +29,7 @@ * | provided "as is" without express or implied warranty. | * +-------------------------------------------------------------------+ * - * RCS: @(#) $Id: tkImgGIF.c,v 1.15 2000/05/30 17:51:50 ericm Exp $ + * RCS: @(#) $Id: tkImgGIF.c,v 1.16 2000/07/05 23:30:06 ericm Exp $ */ /* @@ -1328,15 +1328,15 @@ static unsigned char mapa[MAXCOLORMAPSIZE][3]; * Definition of new functions to write GIFs */ -static int color _ANSI_ARGS_((int red,int green, int blue)); +static int color _ANSI_ARGS_((int red,int green, int blue, + unsigned char mapa[MAXCOLORMAPSIZE][3])); static void compress _ANSI_ARGS_((int init_bits, Tcl_Channel handle, ifunptr readValue)); static int nuevo _ANSI_ARGS_((int red, int green ,int blue, unsigned char mapa[MAXCOLORMAPSIZE][3])); -static int savemap _ANSI_ARGS_((Tk_PhotoImageBlock *blockPtr, +static void savemap _ANSI_ARGS_((Tk_PhotoImageBlock *blockPtr, unsigned char mapa[MAXCOLORMAPSIZE][3])); static int ReadValue _ANSI_ARGS_((void)); -static int no_bits _ANSI_ARGS_((int colors)); static int FileWriteGIF (interp, filename, format, blockPtr) @@ -1355,9 +1355,6 @@ FileWriteGIF (interp, filename, format, blockPtr) if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") != TCL_OK) { return TCL_ERROR; } - if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary") != TCL_OK) { - return TCL_ERROR; - } result = CommonWriteGIF(interp, chan, format, blockPtr); if (Tcl_Close(interp, chan) == TCL_ERROR) { @@ -1376,12 +1373,10 @@ CommonWriteGIF(interp, handle, format, blockPtr) Tk_PhotoImageBlock *blockPtr; { int resolution; - long numcolormap; long width,height,x; unsigned char c; unsigned int top,left; - int num; top = 0; left = 0; @@ -1412,11 +1407,12 @@ CommonWriteGIF(interp, handle, format, blockPtr) height=blockPtr->height; pixelo=blockPtr->pixelPtr + blockPtr->offset[0]; pixelPitch=blockPtr->pitch; - if ((num=savemap(blockPtr,mapa))<0) { + savemap(blockPtr,mapa); + if (num>=MAXCOLORMAPSIZE) { Tcl_AppendResult(interp, "too many colors", (char *) NULL); return TCL_ERROR; } - if (num<3) num=3; + if (num<2) num=2; c=LSB(width); Mputc(c,handle); c=MSB(width); @@ -1426,11 +1422,14 @@ CommonWriteGIF(interp, handle, format, blockPtr) c=MSB(height); Mputc(c,handle); - c= (1 << 7) | (no_bits(num) << 4) | (no_bits(num)); + resolution = 0; + while (num >> resolution) { + resolution++; + } + c = 111 + resolution * 17; Mputc(c,handle); - resolution = no_bits(num)+1; - numcolormap=1 << resolution; + num = 1 << resolution; /* background color */ @@ -1441,7 +1440,7 @@ CommonWriteGIF(interp, handle, format, blockPtr) Mputc(c,handle); - for (x=0; x<numcolormap ;x++) { + for (x=0; x<num ;x++) { c = mapa[x][CM_RED]; Mputc(c,handle); c = mapa[x][CM_GREEN]; @@ -1499,10 +1498,11 @@ CommonWriteGIF(interp, handle, format, blockPtr) } static int -color(red, green, blue) +color(red, green, blue, mapa) int red; int green; int blue; + unsigned char mapa[MAXCOLORMAPSIZE][3]; { int x; for (x=(alphaOffset != 0);x<=MAXCOLORMAPSIZE;x++) { @@ -1521,7 +1521,7 @@ nuevo(red, green, blue, mapa) unsigned char mapa[MAXCOLORMAPSIZE][3]; { int x; - for (x=(alphaOffset != 0);x<num;x++) { + for (x=(alphaOffset != 0);x<=num;x++) { if ((mapa[x][CM_RED]==red) && (mapa[x][CM_GREEN]==green) && (mapa[x][CM_BLUE]==blue)) { return 0; @@ -1530,7 +1530,7 @@ nuevo(red, green, blue, mapa) return 1; } -static int +static void savemap(blockPtr,mapa) Tk_PhotoImageBlock *blockPtr; unsigned char mapa[MAXCOLORMAPSIZE][3]; @@ -1540,12 +1540,12 @@ savemap(blockPtr,mapa) unsigned char red,green,blue; if (alphaOffset) { - num = 1; + num = 0; mapa[0][CM_RED] = 0xd9; mapa[0][CM_GREEN] = 0xd9; mapa[0][CM_BLUE] = 0xd9; } else { - num = 0; + num = -1; } for(y=0;y<blockPtr->height;y++) { @@ -1557,19 +1557,19 @@ savemap(blockPtr,mapa) green = colores[greenOffset]; blue = colores[blueOffset]; if (nuevo(red,green,blue,mapa)) { - if (num>255) - return -1; - + num++; + if (num>=MAXCOLORMAPSIZE) { + return; + } mapa[num][CM_RED]=red; mapa[num][CM_GREEN]=green; mapa[num][CM_BLUE]=blue; - num++; } } colores += pixelSize; } } - return num-1; + return; } static int @@ -1583,7 +1583,7 @@ ReadValue() if (alphaOffset && (pixelo[alphaOffset]==0)) { col = 0; } else { - col = color(pixelo[0],pixelo[greenOffset],pixelo[blueOffset]); + col = color(pixelo[0],pixelo[greenOffset],pixelo[blueOffset], mapa); } pixelo += pixelSize; if (--ssize <= 0) { @@ -1595,25 +1595,6 @@ ReadValue() return col; } -/* - * Return the number of bits ( -1 ) to represent a given - * number of colors ( ex: 256 colors => 7 ). - */ - -static int -no_bits( colors ) -int colors; -{ - register int bits = 0; - - colors--; - while ( colors >> bits ) { - bits++; - } - - return (bits-1); -} - /*----------------------------------------------------------------------- diff --git a/tests/imgPhoto.test b/tests/imgPhoto.test index 99d3832..0bad47f 100644 --- a/tests/imgPhoto.test +++ b/tests/imgPhoto.test @@ -9,7 +9,7 @@ # # Author: Paul Mackerras (paulus@cs.anu.edu.au) # -# RCS: @(#) $Id: imgPhoto.test,v 1.7 1999/12/14 06:53:13 hobbs Exp $ +# RCS: @(#) $Id: imgPhoto.test,v 1.8 2000/07/05 23:30:07 ericm Exp $ if {[lsearch [namespace children] ::tcltest] == -1} { source [file join [pwd] [file dirname [info script]] defs.tcl] @@ -436,6 +436,46 @@ test imgPhoto-13.1 {check separation of images in different interpreters} { interp delete x2 } {} + +test imgPhoto-14.1 {GIF writes work correctly} { + set data "R0lGODlhYwA5APcAAAAAAIAAAACAAICAAAAAgIAAgACAgICAgAysnGy8hKzM +hASs3MTcjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwP8AAAD/ +AP//AAAA//8A/wD//////ywAAAAAYwA5AAAI/wAZCBxIsKDBgwgTKlzIsKHD +hxAjSpxIsaLFixgzatzIsaPHjyBDihxJsqTJkyhTqlzJsqXLlzBjypxJs6bN +mzhz6tzJs6fPn0CDCh1KtKhRiwoSKEXAtGlTpUqPGkyagOmCq1edNsWalWkC +BUSXIuDqFepBqFWtZv3KU+zYrkrBSqT6dgECtjOTbu16NwFHvV3lshRLti/J +qlgRCE6ZuO9ik4Dt+k0ZVyZiyVIvXr77ODPEy5g9T4zMWfTEzXdNz1VbWvXn +uqldP1TAOrbshqBb314Y2W7n3Qdpv7UNPCHpycUVbv6dnODy5sqzQldIe8H0 +hciva9/Ovbv37+BzBgEEADs= +" + set photo [image create photo -data $data] + set filename [file join $::tcltest::workingDir imgPhoto-14.1.gif] + if {[file exists $filename]} { + catch {file delete -force $filename} + } + $photo write $filename -format gif + set photo2 [image create photo -file $filename] + set result [string equal [$photo data] [$photo2 data]] + image delete $photo $photo2 + catch {file delete -force $filename} + set result +} 1 + destroy .c eval image delete [image names] @@ -445,16 +485,3 @@ if {[info exists removeREADME]} { } ::tcltest::cleanupTests return - - - - - - - - - - - - - |