# # rgb2gif transparency patch for libungif-4.1.0 by candy # # NO WARRANTY # # Install: # cd /usr/ports/graphics/libungif # make patch # cd work/libungif-4.1.0 # patch -p < this_patch # cd ../.. # make all && make install --- lib/egif_lib.c.orig Fri Feb 18 17:09:02 2000 +++ lib/egif_lib.c Fri Feb 18 17:09:40 2000 @@ -819,3 +819,20 @@ return(GIF_OK); } + +int +EGifPutGraphicControlExtension(GifFileType *GifFile, int DisposalMethod, int UserInputFlag, int TransparentColorFlag, int DelayTime, int TransparentColorIndex) +{ + GifByteType buf[4]; + buf[0] = 0x21; /* Extension Introducer */ + buf[1] = 0xf9; /* Graphic ControlLabel */ + buf[2] = 4; /* Block Size */ + buf[3] = ((DisposalMethod & 7) << 2) | (!!UserInputFlag << 1) | !!TransparentColorFlag; + WRITE(GifFile, buf, 4); + EGifPutWord((DelayTime & 0xffff), GifFile); + buf[0] = TransparentColorIndex; + buf[1] = 0x00; /* Block Terminator */ + WRITE(GifFile, buf, 2); + return GIF_OK; +} + --- util/rgb2gif.c.orig Mon Sep 7 04:15:33 1998 +++ util/rgb2gif.c Fri Feb 18 17:27:43 2000 @@ -32,6 +32,7 @@ #include #include #include "gif_lib.h" +extern int EGifPutGraphicControlExtension(GifFileType *GifFile, int DisposalMethod, int UserInputFlag, int TransparentColorFlag, int DelayTime, int TransparentColorIndex); #include "getarg.h" #define PROGRAM_NAME "RGB2Gif" @@ -58,7 +59,7 @@ static char *CtrlStr = PROGRAM_NAME - " q%- c%-#Colors!d 1%- s!-Width|Height!d!d h%- RGBFile!*s"; + " q%- c%-#Colors!d 1%- s!-Width|Height!d!d h%- t%-TransparentColor!s RGBFile!*s"; #endif /* SYSV */ /* Make some variables global, so we could access them faster: */ @@ -68,6 +69,7 @@ OneFileFlag = FALSE, HelpFlag = FALSE, ColorMapSize = 256; +static long TransparentColor = -1; static void LoadRGB(char *FileName, int OneFileFlag, @@ -80,6 +82,35 @@ int ExpColorMapSize, int Width, int Height); static void QuitGifError(GifFileType *GifFile); +static long +parse_color_name(const char *name) +{ + long rgb = -1; + int err = -1; + if (name[0] == '#') { + if (strlen(name + 1) == 6) { + const unsigned char *p = (const unsigned char *)name + 1; + int i; + unsigned char ppp[3]; + err = 0; + for (i = 0; i < 3; i++) { + if (isxdigit(p[i * 2]) && isxdigit(p[i * 2 + 1])) { + char buf[3]; + buf[0] = p[i * 2]; + buf[1] = p[i * 2 + 1]; + buf[3] = '\0'; + ppp[i] = strtoul(buf, 0, 16); + } + else + err = -1; + } + if (err == 0) + rgb = ((unsigned long)ppp[0] << 16) | ((unsigned long)ppp[1] << 8) | ppp[2]; + } + } + return rgb; +} + /****************************************************************************** * Interpret the command line and scan the given GIF file. * ******************************************************************************/ @@ -90,10 +121,13 @@ GifByteType *RedBuffer = NULL, *GreenBuffer = NULL, *BlueBuffer = NULL, *OutputBuffer = NULL; ColorMapObject *OutputColorMap = NULL; + int TransparentFlag = 0; + char *TransparentColorName = NULL; if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuietPrint, &ColorFlag, &ExpNumOfColors, &OneFileFlag, &SizeFlag, &Width, &Height, &HelpFlag, + &TransparentFlag, &TransparentColorName, &NumFiles, &FileName)) != FALSE || (NumFiles > 1 && !HelpFlag)) { if (Error) @@ -109,6 +143,13 @@ GAPrintHowTo(CtrlStr); exit(0); } + if (TransparentFlag) { + TransparentColor = parse_color_name(TransparentColorName); + if (TransparentColor < 0) { + fprintf(stderr, "color name should be '#RRGGBB'\n"); + exit(1); + } + } ColorMapSize = 1 << ExpNumOfColors; @@ -135,6 +176,7 @@ free((char *) BlueBuffer); SaveGif(OutputBuffer, OutputColorMap, ExpNumOfColors, Width, Height); + exit(0); } /****************************************************************************** @@ -244,6 +286,32 @@ } } +static int +lookup_color(const ColorMapObject *ColorMap, long rgb) +{ + int i = 0, found = -1; + while (i < ColorMap->ColorCount && found < 0) { + long col = ((unsigned long)ColorMap->Colors[i].Red << 16) | ((unsigned long)ColorMap->Colors[i].Green << 8) | ColorMap->Colors[i].Blue; + if (col == rgb) + found = i; + i++; + } + return found; +} + +static int +EGifPutGraphExt(GifFileType *GifFile, const ColorMapObject *ColorMap) +{ + int err = GIF_OK; + if (TransparentColor >= 0 && ColorMap != NULL) { + int idx = lookup_color(ColorMap, TransparentColor); + if (idx >= 0) { + err = EGifPutGraphicControlExtension(GifFile, 0, 0, 1, 0, idx); + } + } + return err; +} + /****************************************************************************** * Save the GIF resulting image. * ******************************************************************************/ @@ -262,6 +330,7 @@ if (EGifPutScreenDesc(GifFile, Width, Height, ExpColorMapSize, 0, OutputColorMap) == GIF_ERROR || + EGifPutGraphExt(GifFile, OutputColorMap) == GIF_ERROR || EGifPutImageDesc(GifFile, 0, 0, Width, Height, FALSE, NULL) == GIF_ERROR)