diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2021-12-26 09:16:41 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2021-12-26 09:16:41 +0000 |
commit | e15e137ba527ba97c82149ad8c6bed59088d8616 (patch) | |
tree | d97d0742d8fa448232faad05a7b40ccc18641b68 /converter/other/pamtogif.c | |
parent | 2d31b9e0a06dde404131dbc2300502bfd2698819 (diff) | |
download | netpbm-mirror-e15e137ba527ba97c82149ad8c6bed59088d8616.tar.gz netpbm-mirror-e15e137ba527ba97c82149ad8c6bed59088d8616.tar.xz netpbm-mirror-e15e137ba527ba97c82149ad8c6bed59088d8616.zip |
Release 10.73.38
git-svn-id: http://svn.code.sf.net/p/netpbm/code/super_stable@4219 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/other/pamtogif.c')
-rw-r--r-- | converter/other/pamtogif.c | 144 |
1 files changed, 99 insertions, 45 deletions
diff --git a/converter/other/pamtogif.c b/converter/other/pamtogif.c index d20fa650..592a0472 100644 --- a/converter/other/pamtogif.c +++ b/converter/other/pamtogif.c @@ -24,6 +24,13 @@ static bool verbose; typedef int stringCode; + +enum TransparencyType {TRANS_NONE, TRANS_COLOR, TRANS_ALPHA}; + /* The source of transparency for the GIF: nothing is transparent, + All pixels of a certain color are transparent, or the alpha plane + in the input tells what is transparent. + */ + /* A code to be place in the GIF raster. It represents a string of one or more pixels. You interpret this in the context of a current code size. The lower half of the values representable @@ -89,7 +96,12 @@ struct cmdlineInfo { static unsigned int pamAlphaPlane(struct pam * const pamP) { +/*---------------------------------------------------------------------------- + The number of the alpha plane, or zero if there is no alpha plane, as + indicated by *pamP. + Note that the alpha plane is never zero in any Netpbm tuple type. +-----------------------------------------------------------------------------*/ unsigned int alphaPlane; if (streq(pamP->tuple_type, "RGB_ALPHA")) @@ -440,18 +452,25 @@ gifPixel(struct pam * const pamP, sample const alphaThreshold, struct cmap * const cmapP) { /*---------------------------------------------------------------------------- - Return as *colorIndexP the colormap index of the tuple 'tuple', - whose format is described by *pamP, using colormap *cmapP. + Return the colormap index of the tuple 'tuple', whose format is described + by *pamP, using colormap *cmapP. + + 'alphaPlane' is the number of the plane in 'tuple' to use for transparency, + or zero if we aren't to use any plane for transparency. (note that Caller + cannot specify plane 0 for transparency). + + 'alphaThreshold' is the alpha level below which we consider a pixel + transparent for GIF purposes. - 'alphaThreshold' is the alpha level below which we consider a - pixel transparent for GIF purposes. + If 'alphaPlane' is nonzero, we assume *cmapP contains a transparent + entry. -----------------------------------------------------------------------------*/ int colorIndex; - if (alphaPlane && tuple[alphaPlane] < alphaThreshold && - cmapP->haveTransparent) + if (alphaPlane && tuple[alphaPlane] < alphaThreshold) { + assert(cmapP->haveTransparent); colorIndex = cmapP->transparent; - else { + } else { int found; pnm_lookuptuple(pamP, cmapP->tuplehash, tuple, @@ -1223,6 +1242,14 @@ writeRaster(struct pam * const pamP, Get the raster to write from 'rowReaderP', which gives tuples whose format is described by 'pamP'. + 'alphaPlane' is the number of the plane in the tuples supplied by + 'rowReaderP' that we should use for transparency information, and + 'alphaThreshold' is the value in that plane below which we should consider + the pixel transparent for GIF purposes. + + 'alphaPlane' is zero to indicate we should not use any plane as an alpha + plane (so it's not possible to specify Plane 0 as alpha). + Use the colormap 'cmapP' to generate the raster ('rowReaderP' gives pixel values as RGB samples; the GIF raster is colormap indices). @@ -1438,8 +1465,13 @@ gifEncode(struct pam * const pamP, struct cmap * const cmapP, char const comment[], float const aspect, - bool const lzw) { - + bool const lzw, + bool const usingAlpha) { +/*---------------------------------------------------------------------------- + 'usingAlpha' means use the alpha (transparency) plane, if there is one, to + determine which GIF pixels are transparent. When this is true, the + colormap *cmapP must contain a transparent entry. +-----------------------------------------------------------------------------*/ unsigned int const leftOffset = 0; unsigned int const topOffset = 0; @@ -1451,7 +1483,7 @@ gifEncode(struct pam * const pamP, pixels in the output image. */ - unsigned int const alphaPlane = pamAlphaPlane(pamP); + unsigned int const alphaPlane = usingAlpha ? pamAlphaPlane(pamP) : 0; rowReader * rowReaderP; @@ -1493,9 +1525,22 @@ gifEncode(struct pam * const pamP, static void -reportTransparent(struct cmap * const cmapP) { +reportTransparent(enum TransparencyType const transType, + struct cmap * const cmapP) { if (verbose) { + switch (transType) { + case TRANS_NONE: + pm_message("Not making transparent pixels"); + break; + case TRANS_COLOR: + pm_message("Making pixels of a certain color transparent"); + break; + case TRANS_ALPHA: + pm_message("Making pixels transparent per input alpha mask"); + break; + } + if (cmapP->haveTransparent) { tuple const color = cmapP->color[cmapP->transparent]; pm_message("Color %u (%lu, %lu, %lu) is transparent", @@ -1511,42 +1556,46 @@ reportTransparent(struct cmap * const cmapP) { static void -computeTransparent(char const colorarg[], - bool const usingFakeTrans, - unsigned int const fakeTransparent, - struct cmap * const cmapP) { +computeTransparent(enum TransparencyType const transType, + char const colorarg[], + unsigned int const fakeTransparent, + struct cmap * const cmapP) { /*---------------------------------------------------------------------------- Figure out the color index (index into the colormap) of the color - that is to be transparent in the GIF. + that is to be transparent in the GIF and set it in the colormap. + + 'transType' tells what the source of the transparency is. + + If 'transType' says all pixels of a single foreground color are to be + transparent: - colorarg[] is the string that specifies the color the user wants to - be transparent (e.g. "red", "#fefefe"). Its maxval is the maxval - of the colormap. 'cmap' is the full colormap except that its - 'transparent' component isn't valid. + 'colorarg' is the specification of that color. Its + maxval is the maxval of the colormap. - colorarg[] is a standard Netpbm color specification, except that - may have a "=" prefix, which means it specifies a particular exact - color, as opposed to without the "=", which means "the color that - is closest to this and actually in the image." + colorarg[] is a standard Netpbm color specification (e.g. "red", + "#fefefe"), except that may have a "=" prefix, which means it specifies a + particular exact color, as opposed to without the "=", which means "the + color that is closest to this and actually in the image." - colorarg[] null means the color didn't ask for a particular color - to be transparent. + Establish no transparent color if colorarg[] specifies an exact + color and that color is not in the image. Also issue an + informational message. - Establish no transparent color if colorarg[] specifies an exact - color and that color is not in the image. Also issue an - informational message. + If 'transType' says an input alpha channel will dtermine what pixels are + transparent: - 'usingFakeTrans' means pixels will be transparent because of something - other than their foreground color, and 'fakeTransparent' is the - color map index for transparent colors. + 'fakeTransparent' is the special color map index for transparent pixels. -----------------------------------------------------------------------------*/ - if (colorarg) { + switch (transType) { + case TRANS_COLOR: { const char * colorspec; bool exact; tuple transcolor; int found; int colorindex; + assert(colorarg); + if (colorarg[0] == '=') { colorspec = &colorarg[1]; exact = TRUE; @@ -1570,13 +1619,16 @@ computeTransparent(char const colorarg[], pm_message("Warning: specified transparent color " "does not occur in image."); } - } else if (usingFakeTrans) { + } break; + case TRANS_ALPHA: { cmapP->haveTransparent = TRUE; cmapP->transparent = fakeTransparent; - } else + } break; + case TRANS_NONE: { cmapP->haveTransparent = FALSE; - - reportTransparent(cmapP); + } break; + } /* switch */ + reportTransparent(transType, cmapP); } @@ -1889,13 +1941,13 @@ main(int argc, char *argv[]) { struct pam pam; unsigned int bitsPerPixel; pm_filepos rasterPos; - struct cmap cmap; /* The colormap, with all its accessories */ + enum TransparencyType transType; unsigned int fakeTransparent; /* colormap index of the fake transparency color we're using to - implement the alpha mask. Undefined if we're not doing an alpha - mask. + implement the alpha mask. Defined only if 'transType' is + TRANS_ALPHA. */ pnm_init(&argc, argv); @@ -1916,7 +1968,11 @@ main(int argc, char *argv[]) { assert(cmap.pam.maxval == pam.maxval); - if (pamAlphaPlane(&pam)) { + transType = cmdline.transparent ? TRANS_COLOR : + pamAlphaPlane(&pam) ? TRANS_ALPHA : + TRANS_NONE; + + if (transType == TRANS_ALPHA) { /* Add a fake entry to the end of the colormap for transparency. Make its color black. */ @@ -1925,14 +1981,12 @@ main(int argc, char *argv[]) { bitsPerPixel = cmap.cmapSize == 1 ? 1 : nSignificantBits(cmap.cmapSize-1); - computeTransparent(cmdline.transparent, - !!pamAlphaPlane(&pam), fakeTransparent, &cmap); + computeTransparent(transType, cmdline.transparent, fakeTransparent, &cmap); /* All set, let's do it. */ gifEncode(&pam, stdout, rasterPos, cmdline.interlace, 0, bitsPerPixel, &cmap, cmdline.comment, - cmdline.aspect, !cmdline.nolzw); - + cmdline.aspect, !cmdline.nolzw, !cmdline.transparent); destroyCmap(&cmap); pm_close(ifP); |