From fa0c89a43a59ab81d50a858781c0a201c53c6427 Mon Sep 17 00:00:00 2001 From: Robin Stuart Date: Mon, 3 Aug 2020 17:13:25 +0100 Subject: [PATCH] Allow transparency in GIF images Thanks to preperation work done by Harald --- backend/gif.c | 33 +++++++++++++++++++++++++-------- docs/manual.txt | 7 ++++--- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/backend/gif.c b/backend/gif.c index c5b19ee3..4a7bf767 100644 --- a/backend/gif.c +++ b/backend/gif.c @@ -43,11 +43,6 @@ #define SSET "0123456789ABCDEF" -/* Index of transparent color, -1 for no transparent color - * This might be set into a variable if transparency is activated as an option - */ -#define TRANSPARENT_INDEX (-1) - typedef struct s_statestruct { unsigned char * pOut; unsigned char *pIn; @@ -290,6 +285,8 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { int paletteBitSize; int paletteSize; statestruct State; + int transparent_index; + int bgindex, fgindex; unsigned char backgroundColourIndex; unsigned char RGBCur[3]; @@ -439,6 +436,9 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { paletteRGB[paletteIndex][2] = RGBCur[2]; paletteCount++; + + if (pixelColour == '0') bgindex = paletteIndex; + if (pixelColour == '1') fgindex = paletteIndex; } /* Add palette index to current colour code */ (State.colourCode)[colourCount] = pixelColour; @@ -447,6 +447,23 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { } State.colourCount = colourCount; + /* Set transparency */ + /* Note: does not allow both transparent foreground and background - + * background takes prioroty */ + transparent_index = -1; + if (strlen(symbol->fgcolour) > 6) { + if ((symbol->fgcolour[6] == '0') && (symbol->fgcolour[7] == '0')) { + // Transparent foreground + transparent_index = fgindex; + } + } + if (strlen(symbol->bgcolour) > 6) { + if ((symbol->bgcolour[6] == '0') && (symbol->bgcolour[7] == '0')) { + // Transparent background + transparent_index = bgindex; + } + } + /* find palette bit size from palette size*/ /* 1,2 -> 1, 3,4 ->2, 5,6,7,8->3 */ @@ -465,7 +482,7 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { /* GIF signature (6) */ memcpy(outbuf, "GIF87a", 6); - if (TRANSPARENT_INDEX != -1) + if (transparent_index != -1) outbuf[4] = '9'; fwrite(outbuf, 6, 1, gif_file); @@ -516,7 +533,7 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { /* A graphic control extension block is used for overlay gifs. * This is necessary to define a transparent color. */ - if (TRANSPARENT_INDEX != -1) { + if (transparent_index != -1) { /* Extension Introducer = '!' */ outbuf[0] = '\x21'; /* Graphic Control Label */ @@ -534,7 +551,7 @@ INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) { outbuf[4] = 0; outbuf[5] = 0; /* Transparent Color Index */ - outbuf[6] = (unsigned char) TRANSPARENT_INDEX; + outbuf[6] = (unsigned char) transparent_index; /* Block Terminator */ outbuf[7] = 0; fwrite(outbuf, 8, 1, gif_file); diff --git a/docs/manual.txt b/docs/manual.txt index 364cb4ac..e622fce2 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -420,7 +420,7 @@ will give different results for PNG and SVG. Experimentation is advised! Also note that these options don't work properly with Maxicode yet. In addition the --nobackground option will simply remove the background from -PNG, SVG, EMF and EPS files. +PNG, GIF, SVG, EMF and EPS files. 4.8 Rotating the Symbol ----------------------- @@ -931,8 +931,9 @@ int main(int argc, char **argv) return 0; } -Background removal for PNG, SVG, EMF and EPS files can be achieved by setting -the background alpha to "00" where the values for R, G and B will be ignored: +Background removal for PNG, GIF, SVG, EMF and EPS files can be achieved by +setting the background alpha to "00" where the values for R, G and B will be +ignored: strcpy(my_symbol->bgcolour, "55555500");