about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2021-10-17 04:36:14 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2021-10-17 04:36:14 +0000
commit1f028a3d66db42414e29bb3c86b690f290e2af85 (patch)
tree298e41f786d0b0df4968065970967a12223df138
parentc49999caa64dc28c155fd4602c82df32b1f27335 (diff)
downloadnetpbm-mirror-1f028a3d66db42414e29bb3c86b690f290e2af85.tar.gz
netpbm-mirror-1f028a3d66db42414e29bb3c86b690f290e2af85.tar.xz
netpbm-mirror-1f028a3d66db42414e29bb3c86b690f290e2af85.zip
Release 10.86.25
git-svn-id: http://svn.code.sf.net/p/netpbm/code/stable@4156 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r--converter/other/pamtogif.c142
-rw-r--r--doc/HISTORY9
-rw-r--r--lib/libpbm2.c4
-rw-r--r--version.mk2
4 files changed, 110 insertions, 47 deletions
diff --git a/converter/other/pamtogif.c b/converter/other/pamtogif.c
index 185ad128..022b7343 100644
--- a/converter/other/pamtogif.c
+++ b/converter/other/pamtogif.c
@@ -24,6 +24,11 @@ static unsigned int const gifMaxval = 255;
 static bool verbose;
 
 
+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.
+
 typedef unsigned int StringCode;
     /* A code to be place in the GIF raster.  It represents
        a string of one or more pixels.  You interpret this in the context
@@ -87,7 +92,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 +450,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.
 
-   'alphaThreshold' is the alpha level below which we consider a
-   pixel transparent for GIF purposes.
+   '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.
+
+   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,
@@ -1269,6 +1286,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).
 
@@ -1489,8 +1514,13 @@ gifEncode(struct pam *  const pamP,
           char          const comment[],
           float         const aspect,
           bool          const lzw,
-          bool          const noclear) {
-
+          bool          const noclear,
+          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;
 
@@ -1502,7 +1532,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;
 
@@ -1544,9 +1574,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",
@@ -1562,42 +1605,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.
 
-   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.
+   If 'transType' says all pixels of a single foreground color are to be
+   transparent:
 
-   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 the specification of that color.  Its
+     maxval is the maxval of the colormap.
 
-   colorarg[] null means the color didn't ask for a particular color
-   to be transparent.
+     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."
 
-   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.
 
-   'usingFakeTrans' means pixels will be transparent because of something
-   other than their foreground color, and 'fakeTransparent' is the
-   color map index for transparent colors.
+   If 'transType' says an input alpha channel will dtermine what pixels are
+   transparent:
+
+     '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;
@@ -1621,13 +1668,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);
 }
 
 
@@ -1940,13 +1990,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);
@@ -1967,7 +2017,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.
         */
@@ -1976,13 +2030,13 @@ 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.noclear);
+              cmdline.aspect, !cmdline.nolzw, cmdline.noclear,
+              !cmdline.transparent);
 
     destroyCmap(&cmap);
 
diff --git a/doc/HISTORY b/doc/HISTORY
index bd80939a..f2a40e42 100644
--- a/doc/HISTORY
+++ b/doc/HISTORY
@@ -4,6 +4,15 @@ Netpbm.
 CHANGE HISTORY 
 --------------
 
+21.10.17 BJH  Release 10.86.25
+
+              pamtogif: Fix bug: doesn't ignore the input alpha mask when user
+              specified -transparent.  Broken in Netpbm 10.37 (December 2006).
+
+              libnetpbm: When validating computable size of width and height,
+              allow for adding up to 10 instead of 2, to account for rounding
+              up to a multiple of 8 in processing bit maps.
+
 21.08.30 BJH  Release 10.86.24
 
               ximtoppm: Fix bug: invalid memory references with pathological
diff --git a/lib/libpbm2.c b/lib/libpbm2.c
index a35004f9..2fec4788 100644
--- a/lib/libpbm2.c
+++ b/lib/libpbm2.c
@@ -72,9 +72,9 @@ validateComputableSize(unsigned int const cols,
    A common operation is adding 1 or 2 to the highest row or
    column number in the image, so we make sure that's possible.
 -----------------------------------------------------------------------------*/
-    if (cols > INT_MAX - 2)
+    if (cols > INT_MAX - 10)
         pm_error("image width (%u) too large to be processed", cols);
-    if (rows > INT_MAX - 2)
+    if (rows > INT_MAX - 10)
         pm_error("image height (%u) too large to be processed", rows);
 }
 
diff --git a/version.mk b/version.mk
index 0766bca8..968ef50f 100644
--- a/version.mk
+++ b/version.mk
@@ -1,3 +1,3 @@
 NETPBM_MAJOR_RELEASE = 10
 NETPBM_MINOR_RELEASE = 86
-NETPBM_POINT_RELEASE = 24
+NETPBM_POINT_RELEASE = 25