about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2019-09-28 19:34:22 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2019-09-28 19:34:22 +0000
commit860faaae6a58e83623b9620dc0e0f36f3126b251 (patch)
treee09259abd808ac7e9a4c2494e1ccefa0d08ef991
parent2b499210eb2a64c95e6891a8d361b38a8502e063 (diff)
downloadnetpbm-mirror-860faaae6a58e83623b9620dc0e0f36f3126b251.tar.gz
netpbm-mirror-860faaae6a58e83623b9620dc0e0f36f3126b251.tar.xz
netpbm-mirror-860faaae6a58e83623b9620dc0e0f36f3126b251.zip
Promote Development to Advanced
git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@3691 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r--analyzer/pamsumm.c4
-rw-r--r--analyzer/ppmhist.c44
-rw-r--r--converter/other/Makefile27
-rw-r--r--converter/other/pnmtorle.c20
-rw-r--r--converter/other/rletopnm.c78
-rw-r--r--converter/pbm/pbmtolps.c374
-rw-r--r--doc/HISTORY26
-rw-r--r--doc/INSTALL31
-rw-r--r--editor/pnmremap.c14
-rw-r--r--generator/pbmtext.c44
-rw-r--r--lib/libppmcmap.c113
-rw-r--r--lib/pammap.h20
-rw-r--r--lib/ppmcmap.h70
-rw-r--r--lib/util/shhopt.h11
-rw-r--r--other/pamx/Makefile8
-rw-r--r--other/pnmcolormap.c531
-rw-r--r--test/Test-Order4
-rw-r--r--test/lps-roundtrip.ok1
-rwxr-xr-xtest/lps-roundtrip.test22
-rw-r--r--test/pamditherbw.ok22
-rwxr-xr-xtest/pamditherbw.test39
-rw-r--r--test/pamfile.ok8
-rwxr-xr-xtest/pamfile.test16
-rw-r--r--test/pamfind.ok7
-rwxr-xr-xtest/pamfind.test24
-rw-r--r--test/pamgauss.ok12
-rwxr-xr-xtest/pamgauss.test22
-rw-r--r--test/pamhue.ok8
-rwxr-xr-xtest/pamhue.test4
-rw-r--r--test/pamscale-reportonly.ok14
-rwxr-xr-xtest/pamscale-reportonly.test42
-rw-r--r--test/pamseq.ok10
-rwxr-xr-xtest/pamseq.test19
-rw-r--r--test/pamsumm.ok10
-rwxr-xr-xtest/pamsumm.test19
-rw-r--r--test/pbmmake.ok32
-rwxr-xr-xtest/pbmmake.test38
-rw-r--r--test/pbmpage.ok8
-rwxr-xr-xtest/pbmpage.test16
-rw-r--r--test/pbmtext-bdf.ok3
-rwxr-xr-xtest/pbmtext-bdf.test10
-rw-r--r--test/pbmtext-iso88591.ok2
-rwxr-xr-xtest/pbmtext-iso88591.test63
-rw-r--r--test/pbmtext-utf8.ok18
-rwxr-xr-xtest/pbmtext-utf8.test174
-rw-r--r--test/pbmtext.ok23
-rwxr-xr-xtest/pbmtext.test83
-rw-r--r--test/pbmupc.ok20
-rwxr-xr-xtest/pbmupc.test34
-rw-r--r--test/pgmhist.ok10
-rwxr-xr-xtest/pgmhist.test19
-rw-r--r--test/pgmmake.ok20
-rwxr-xr-xtest/pgmmake.test32
-rw-r--r--test/pgmramp.ok12
-rwxr-xr-xtest/pgmramp.test18
-rw-r--r--test/pnmcolormap.ok16
-rwxr-xr-xtest/pnmcolormap.test33
-rw-r--r--test/pnmcrop1.ok24
-rwxr-xr-xtest/pnmcrop1.test8
-rw-r--r--test/pnmpsnr.ok10
-rwxr-xr-xtest/pnmpsnr.test19
-rw-r--r--test/pnmquant.ok18
-rwxr-xr-xtest/pnmquant.test61
-rw-r--r--test/pnmremap1.ok6
-rwxr-xr-xtest/pnmremap1.test25
-rw-r--r--test/ppmforge-parameters.ok12
-rwxr-xr-xtest/ppmforge-parameters.test22
-rw-r--r--test/ppmhist.ok8
-rwxr-xr-xtest/ppmhist.test15
-rw-r--r--test/ppmmake.ok24
-rwxr-xr-xtest/ppmmake.test39
-rw-r--r--test/ppmpat.ok54
-rwxr-xr-xtest/ppmpat.test85
-rw-r--r--test/ps-alt-roundtrip.ok1
-rwxr-xr-xtest/ps-alt-roundtrip.test21
-rw-r--r--urt/rle.h65
-rw-r--r--urt/rle_error.c86
-rw-r--r--urt/rle_getrow.c8
-rw-r--r--urt/rle_hdr.c394
-rw-r--r--version.mk2
80 files changed, 2167 insertions, 1242 deletions
diff --git a/analyzer/pamsumm.c b/analyzer/pamsumm.c
index 9b74e789..03ff6749 100644
--- a/analyzer/pamsumm.c
+++ b/analyzer/pamsumm.c
@@ -58,8 +58,8 @@ parseCommandLine(int argc, const char ** const argv,
     pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
-    if (sumSpec + minSpec + maxSpec > 1)
-        pm_error("You may specify at most one of -sum, -min, and -max");
+    if (sumSpec + minSpec + maxSpec + meanSpec > 1)
+        pm_error("You may specify at most one of -sum, -min, -max, and -mean");
 
     if (sumSpec) {
         cmdlineP->function = FN_ADD;
diff --git a/analyzer/ppmhist.c b/analyzer/ppmhist.c
index c4ab3581..62345fa1 100644
--- a/analyzer/ppmhist.c
+++ b/analyzer/ppmhist.c
@@ -120,25 +120,6 @@ cmpUint(unsigned int const a,
 
 
 #ifndef LITERAL_FN_DEF_MATCH
-static qsort_comparison_fn countcompare;
-#endif
-
-
-static int
-countcompare(const void * const a,
-             const void * const b) {
-/*----------------------------------------------------------------------------
-   This is a 'qsort' collation function.
------------------------------------------------------------------------------*/
-    const struct colorhist_item * const histItem1P = a;
-    const struct colorhist_item * const histItem2P = b;
-
-    return cmpUint(histItem2P->value, histItem1P->value);
-}
-
-
-
-#ifndef LITERAL_FN_DEF_MATCH
 static qsort_comparison_fn rgbcompare;
 #endif
 
@@ -167,6 +148,31 @@ rgbcompare(const void * const a,
 
 
 
+#ifndef LITERAL_FN_DEF_MATCH
+static qsort_comparison_fn countcompare;
+#endif
+
+
+static int
+countcompare(const void * const a,
+             const void * const b) {
+/*----------------------------------------------------------------------------
+   This is a 'qsort' collation function.
+-----------------------------------------------------------------------------*/
+    const struct colorhist_item * const histItem1P = a;
+    const struct colorhist_item * const histItem2P = b;
+
+    int const countComparison = cmpUint(histItem2P->value, histItem1P->value);
+
+    if (countComparison == 0) {
+        /* Counts are the same; use RGB secondary sort */
+        return rgbcompare(a, b);
+    } else
+        return countComparison;
+}
+
+
+
 static pixval
 universalMaxval(pixval const maxval,
                 int    const format) {
diff --git a/converter/other/Makefile b/converter/other/Makefile
index 2be88781..5dfc27ec 100644
--- a/converter/other/Makefile
+++ b/converter/other/Makefile
@@ -7,10 +7,26 @@ VPATH=.:$(SRCDIR)/$(SUBDIR)
 
 include $(BUILDDIR)/config.mk
 
-TEST_PKGCONFIG_LIBXML2 = if $(PKG_CONFIG) libxml-2.0; then echo exists; fi
+# The pkg-config test used to be just 'pkg-config libxml-2.0', without the
+# --exists, and on at least one system, it does the same thing as --exists:
+# exit code 0 if the package exists; 1 if it does not, with no Standard
+# Output.  But we have evidence that on one system, it issues the whole
+# package not found try a different path, blah, blah, blah message that
+# looks like a failure in the build.  We're hoping --exists does not do that.
+# But maybe we didn't do --exists in the first place because it doesn't exist
+# on older pkg-config.  19.09.20.
+#
+# Note that --exists is better for another reason - it fails when the named
+# package exists, but it is unusable because its prerequisite packages don't.
+#
+# Also note that in both cases, the shell command fails if pkg-config
+# doesn't even exist.
+
+TEST_PKGCONFIG_LIBXML2 := \
+  if $(PKG_CONFIG) libxml-2.0 --exists; then echo exists; fi
 
 ifneq ($(shell $(TEST_PKGCONFIG_LIBXML2)),)
-  # pkg-config libxml2 works on this system
+  # pkg-config works and says libxml2 exists on this system
   XML2_LIBS = $(shell $(PKG_CONFIG) libxml-2.0 --libs)
   XML2_CFLAGS = $(shell $(PKG_CONFIG) libxml-2.0 --cflags)
 else
@@ -34,10 +50,11 @@ ifneq ($(TIFFLIB),NONE)
   endif
 endif
 
-TEST_PKGCONFIG_LIBPNG = if $(PKG_CONFIG) libpng$(PNGVER); then echo exists; fi
+TEST_PKGCONFIG_LIBPNG := \
+  if $(PKG_CONFIG) libpng$(PNGVER) --exists; then echo exists; fi
 
 ifneq ($(shell $(TEST_PKGCONFIG_LIBPNG)),)
-  # pkg-config libpng works on this system
+  # pkg-config works and says libpng exists on this system
   HAVE_PNGLIB = Y
   EXTERN_INCLUDES += $(shell $(PKG_CONFIG) libpng$(PNGVER) --cflags)
 else
@@ -193,7 +210,7 @@ tifftopnm pamtotiff pnmtotiffcmyk: \
  $(shell $(LIBOPT)  $(LIBOPTR) $(TIFFLIB) $(TIFFLIB_EXTRALIBS))
 
 ifneq ($(shell $(TEST_PKGCONFIG_LIBPNG)),)
-  # pkg-config libpng works on this system
+  # pkg-config works and says libpng exists on this system
   PNGLIB_LIBOPTS = $(shell $(PKG_CONFIG) libpng$(PNGVER) --libs)
 else
   ifneq ($(shell libpng$(PNGVER)-config --version),)
diff --git a/converter/other/pnmtorle.c b/converter/other/pnmtorle.c
index 8908c356..1882fe5d 100644
--- a/converter/other/pnmtorle.c
+++ b/converter/other/pnmtorle.c
@@ -1,7 +1,7 @@
 /*
  * This is derived from the file of the same name dated June 5, 1995,
  * copied from the Army High Performance Computing Research Center's
- * media-tools.tar.gz package, received from 
+ * media-tools.tar.gz package, received from
  * http://www.arc.umn.edu/gvl-software/media-tools.tar.gz on 2000.04.13.
  *
  * This software is copyrighted as noted below.  It may be freely copied,
@@ -29,8 +29,8 @@
  *              Minnesota Supercomputer Center, Inc.
  * Date:        March 30, 1994
  * Copyright (c) Minnesota Supercomputer Center, Inc.
- * 
- * 2000.04.13 adapted for Netpbm by Bryan Henderson.  Quieted compiler 
+ *
+ * 2000.04.13 adapted for Netpbm by Bryan Henderson.  Quieted compiler
  *            warnings.
  *
  */
@@ -58,7 +58,7 @@ static gray    maxval;
 /*-----------------------------------------------------------------------------
  *                                        Read the pnm image file header.
  */
-static void 
+static void
 read_pnm_header(void) {
 
     pnm_readpnminit(fp, &width, &height, &maxval, &format);
@@ -90,7 +90,7 @@ read_pnm_header(void) {
 
 
 
-static void 
+static void
 write_rle_header(void) {
 
     hdr.xmin    = 0;
@@ -123,7 +123,7 @@ write_rle_header(void) {
 
 
 
-static void 
+static void
 write_rle_data(void) {
 
     unsigned int scan;
@@ -133,12 +133,14 @@ write_rle_data(void) {
     MALLOCARRAY(xelrow, width);
     MALLOCARRAY(scanlines, height);
 
-    RLE_CHECK_ALLOC(hdr.cmd, scanlines, "scanline pointers");
+    if (!scanlines)
+        pm_error("Failed to allocate memory for %u scanline pointers", height);
 
     for (scan = 0; scan < height; ++scan) {
         int rc;
         rc = rle_row_alloc(&hdr, &scanlines[scan]);
-        RLE_CHECK_ALLOC(hdr.cmd, rc >= 0, "pixel memory");
+        if (rc < 0)
+            pm_error("Failed to allocate memory for a scanline");
     }
     /* Loop through the pnm files image window, read data and flip vertically.
      */
@@ -254,7 +256,7 @@ main(int argc, char **  argv) {
             rle_addhist(argv, NULL, &hdr);
             write_rle_header();
             write_rle_data();
-            
+
             pnm_nextimage(fp, &eof);
         }
     }
diff --git a/converter/other/rletopnm.c b/converter/other/rletopnm.c
index 018456c8..97f271dc 100644
--- a/converter/other/rletopnm.c
+++ b/converter/other/rletopnm.c
@@ -1,7 +1,7 @@
 /*
  * This is derived from the file of the same name dated June 5, 1995,
  * copied from the Army High Performance Computing Research Center's
- * media-tools.tar.gz package, received from 
+ * media-tools.tar.gz package, received from
  * http://www.arc.umn.edu/gvl-software/media-tools.tar.gz on 2000.04.13.
  *
  * This software is copyrighted as noted below.  It may be freely copied,
@@ -29,8 +29,8 @@
  *              Minnesota Supercomputer Center, Inc.
  * Date:        March 30, 1994
  * Copyright (c) Minnesota Supercomputer Center 1994
- * 
- * 2000.04.13 adapted for Netpbm by Bryan Henderson.  Quieted compiler 
+ *
+ * 2000.04.13 adapted for Netpbm by Bryan Henderson.  Quieted compiler
  *            warnings.  Added --alpha option.  Accept input on stdin
  *
  */
@@ -105,11 +105,11 @@ parseCommandLine(int argc, char ** argv,
     MALLOCARRAY(option_def, 100);
 
     option_def_index = 0;   /* incremented by OPTENT3 */
-    OPTENT3('h', "headerdump", OPT_FLAG,   
+    OPTENT3('h', "headerdump", OPT_FLAG,
             NULL,                      &cmdlineP->headerdump,     0);
-    OPTENT3('v', "verbose",    OPT_FLAG,   
+    OPTENT3('v', "verbose",    OPT_FLAG,
             NULL,                      &cmdlineP->verbose,        0);
-    OPTENT3(0,   "alphaout",   OPT_STRING, 
+    OPTENT3(0,   "alphaout",   OPT_STRING,
             &cmdlineP->alphaout, &alphaoutSpec,                   0);
 
     opt.opt_table = option_def;
@@ -127,16 +127,16 @@ parseCommandLine(int argc, char ** argv,
     else if (argc - 1 == 1) {
         if (streq(argv[1], "-"))
             cmdlineP->inputFilename = NULL;  /* he wants stdin */
-        else 
+        else
             cmdlineP->inputFilename = strdup(argv[1]);
-    } else 
+    } else
         pm_error("Too many arguments.  The only argument accepted "
                  "is the input file specification");
 
-    if (cmdlineP->alphaout && 
+    if (cmdlineP->alphaout &&
         streq(cmdlineP->alphaout, "-"))
         cmdlineP->alphaStdout = TRUE;
-    else 
+    else
         cmdlineP->alphaStdout = FALSE;
 }
 
@@ -144,7 +144,7 @@ parseCommandLine(int argc, char ** argv,
 
 static void
 reportRleGetSetupError(int const rleGetSetupRc) {
-    
+
     switch (rleGetSetupRc) {
     case -1:
         pm_error("According to the URT library, the input is not "
@@ -168,7 +168,7 @@ reportRleGetSetupError(int const rleGetSetupRc) {
 
 
 
-static void 
+static void
 readRleHeader(FILE * const ifP,
               bool   const headerDump) {
 
@@ -256,7 +256,7 @@ readRleHeader(FILE * const ifP,
 
 
 
-static void 
+static void
 writePpmRaster(FILE * const imageoutFileP,
                FILE * const alphaFileP) {
 
@@ -264,7 +264,7 @@ writePpmRaster(FILE * const imageoutFileP,
     pixval r, g, b;
     pixel *pixelrow;
     gray *alpharow;
-   
+
     int scan;
     int x;
     /*
@@ -274,11 +274,15 @@ writePpmRaster(FILE * const imageoutFileP,
     alpharow = pgm_allocrow(width);
 
     MALLOCARRAY(scanlines, height);
-    RLE_CHECK_ALLOC( hdr.cmd, scanlines, "scanline pointers" );
+    if (!scanlines)
+        pm_error("Failed to allocate memory for %u scanline pointers", height);
 
-    for ( scan = 0; scan < height; scan++ )
-        RLE_CHECK_ALLOC( hdr.cmd, (rle_row_alloc(&hdr, &scanlines[scan]) >= 0),
-                         "pixel memory" );
+    for (scan = 0; scan < height; ++scan) {
+        int rc;
+        rc = rle_row_alloc(&hdr, &scanlines[scan]);
+        if (rc < 0)
+            pm_error("Failed to allocate memory for a scanline");
+    }
     /*
      * Loop through those scan lines.
      */
@@ -295,7 +299,7 @@ writePpmRaster(FILE * const imageoutFileP,
                 PPM_ASSIGN(pixelrow[x], r, g, b);
                 if (hdr.alpha)
                     alpharow[x] = scanline[-1][x];
-                else 
+                else
                     alpharow[x] = 0;
             }
             break;
@@ -305,7 +309,7 @@ writePpmRaster(FILE * const imageoutFileP,
                 g = colormap[scanline[1][x]+256]>>8;
                 b = colormap[scanline[2][x]+512]>>8;
                 PPM_ASSIGN(pixelrow[x], r, g, b);
-                if (hdr.alpha) 
+                if (hdr.alpha)
                     alpharow[x] = colormap[scanline[-1][x]];
                 else
                     alpharow[x] = 0;
@@ -329,7 +333,7 @@ writePpmRaster(FILE * const imageoutFileP,
                 g = colormap[scanline[0][x]+256]>>8;
                 b = colormap[scanline[0][x]+512]>>8;
                 PPM_ASSIGN(pixelrow[x], r, g, b);
-                if (hdr.alpha) 
+                if (hdr.alpha)
                     alpharow[x] = colormap[scanline[-1][x]];
                 else
                     alpharow[x] = 0;
@@ -341,7 +345,7 @@ writePpmRaster(FILE * const imageoutFileP,
         /*
          * Write the scan line.
          */
-        if (imageoutFileP) 
+        if (imageoutFileP)
             ppm_writeppmrow(imageoutFileP, pixelrow, width, RLE_MAXVAL, 0);
         if (alphaFileP)
             pgm_writepgmrow(alphaFileP, alpharow, width, RLE_MAXVAL, 0);
@@ -358,7 +362,7 @@ writePpmRaster(FILE * const imageoutFileP,
 
 
 
-static void 
+static void
 writePgmRaster(FILE * const imageoutFileP,
                FILE * const alphaFileP) {
 /*----------------------------------------------------------------------------
@@ -375,11 +379,15 @@ writePgmRaster(FILE * const imageoutFileP,
     alpharow = pgm_allocrow(width);
 
     MALLOCARRAY(scanlines, height);
-    RLE_CHECK_ALLOC( hdr.cmd, scanlines, "scanline pointers" );
+    if (!scanlines)
+        pm_error("Failed to allocate memory for %u scanline pointers", height);
 
-    for (scan = 0; scan < height; ++scan)
-        RLE_CHECK_ALLOC(hdr.cmd, (rle_row_alloc(&hdr, &scanlines[scan]) >= 0),
-                        "pixel memory" );
+    for (scan = 0; scan < height; ++scan) {
+        int rc;
+        rc = rle_row_alloc(&hdr, &scanlines[scan]);
+        if (rc < 0)
+            pm_error("Failed to allocate memory for a scanline");
+    }
     /*
      * Loop through those scan lines.
      */
@@ -391,12 +399,12 @@ writePgmRaster(FILE * const imageoutFileP,
         scanline = scanlines[scan];
         for (x = 0; x < width; ++x) {
             pixelrow[x] = scanline[0][x];
-            if (hdr.alpha) 
+            if (hdr.alpha)
                 alpharow[x] = scanline[1][x];
             else
                 alpharow[x] = 0;
         }
-        if (imageoutFileP) 
+        if (imageoutFileP)
             pgm_writepgmrow(imageoutFileP, pixelrow, width, RLE_MAXVAL, 0);
         if (alphaFileP)
             pgm_writepgmrow(alphaFileP, alpharow, width, RLE_MAXVAL, 0);
@@ -428,20 +436,20 @@ main(int argc, char ** argv) {
 
     fname = NULL;  /* initial value */
 
-    if (cmdline.inputFilename != NULL ) 
+    if (cmdline.inputFilename != NULL )
         ifP = pm_openr(cmdline.inputFilename);
     else
         ifP = stdin;
 
     if (cmdline.alphaStdout)
         alphaFileP = stdout;
-    else if (cmdline.alphaout == NULL) 
+    else if (cmdline.alphaout == NULL)
         alphaFileP = NULL;
     else {
         alphaFileP = pm_openw(cmdline.alphaout);
     }
 
-    if (cmdline.alphaStdout) 
+    if (cmdline.alphaStdout)
         imageoutFileP = NULL;
     else
         imageoutFileP = stdout;
@@ -461,7 +469,7 @@ main(int argc, char ** argv) {
     if (cmdline.headerdump)
         exit(0);
 
-    /* 
+    /*
      * Write the alpha file header
      */
     if (alphaFileP)
@@ -486,9 +494,9 @@ main(int argc, char ** argv) {
         writePpmRaster(imageoutFileP, alphaFileP);
         break;
     }
-   
+
     pm_close(ifP);
-    if (imageoutFileP) 
+    if (imageoutFileP)
         pm_close(imageoutFileP);
     if (alphaFileP)
         pm_close(alphaFileP);
diff --git a/converter/pbm/pbmtolps.c b/converter/pbm/pbmtolps.c
index dd0342bc..d974fcb2 100644
--- a/converter/pbm/pbmtolps.c
+++ b/converter/pbm/pbmtolps.c
@@ -1,181 +1,253 @@
-/*
- * pbmtolps -- convert a Portable BitMap into Postscript.  The
- * output Postscript uses lines instead of the image operator to
- * generate a (device dependent) picture which will be imaged
- * much faster.
- *
- * The Postscript path length is constrained to be less that 1000
- * points so that no limits are overrun on the Apple Laserwriter
- * and (presumably) no other printers.
- *
- * To do:
- *      make sure encapsulated format is correct
- *      repitition of black-white strips
- *      make it more device independent (is this possible?)
- *
- * Author:
- *      George Phillips <phillips@cs.ubc.ca>
- *      Department of Computer Science
- *      University of British Columbia
- */
-
-#include <string.h>
-#include <stdio.h>
-
+/*=============================================================================
+                             pbmtolps
+===============================================================================
+
+  Convert a PBM image to Postscript.  The output Postscript uses lines instead
+  of the image operator to generate a (device dependent) picture which will be
+  imaged much faster.
+
+  The Postscript path length is constrained to be at most 1000 vertices so that
+  no limits are overrun on the Apple Laserwriter and (presumably) no other
+  printers.  The typical limit is 1500.  See "4.4 Path Construction" and
+  "Appendix B: Implementation Limits" in: PostScript Language Reference Manual
+  https://www.adobe.com/content/dam/acom/en/devnet/actionscript/
+  articles/psrefman.pdf
+
+  To do:
+       make sure encapsulated format is correct
+       repetition of black-white strips
+       make it more device independent (is this possible?)
+
+  Author:
+       George Phillips <phillips@cs.ubc.ca>
+       Department of Computer Science
+       University of British Columbia
+=============================================================================*/
+#include <stdbool.h>
+
+#include "pm_c_util.h"
+#include "mallocvar.h"
 #include "nstring.h"
+#include "shhopt.h"
 #include "pbm.h"
 
 
-static int prev_white = -1;
-static int prev_black = -1;
-static char cmd = '\0';
-static int pointcount = 2;
+static float        const MAX_DPI           = 5000;
+static float        const MIN_DPI           = 10;
+static unsigned int const MAX_PATH_VERTICES = 1000;
 
-#ifdef RUN
-static int run = 1;
-#endif
 
-static char
-morepoints(char cmd, int howmany_pbmtolps) {
-    pointcount += 2;
-    if (pointcount > 1000) {
-        pointcount = 2;
-        cmd += 'm' - 'a';
-    }
-    return(cmd);
+struct CmdlineInfo {
+    /* All the information the user supplied in the command line, in a form
+       easy for the program to use.
+    */
+    const char * inputFileName;  /* File name of input file */
+    unsigned int inputFileSpec;  /* Input file name specified */
+    float        lineWidth;      /* Line width, if specified */
+    unsigned int lineWidthSpec;  /* Line width specified */
+    float        dpi;            /* Resolution in DPI, if specified */
+    unsigned int dpiSpec;        /* Resolution specified */
+};
+
+
+
+static void
+validateDpi(float const dpi) {
+
+    if (dpi > MAX_DPI || dpi < MIN_DPI)
+        pm_error("Specified DPI value out of range (%f)", dpi);
 }
 
 
 
 static void
-addstrip(int const white,
-         int const black) {
-
-    if (cmd) {
-#ifdef RUN
-        if (white == prev_white && black == prev_black)
-            run++;
-        else {
-            if (run == 1)
-#endif
-                printf("%d %d %c ",
-                       prev_black, prev_white, morepoints(cmd, 2));
-#ifdef RUN
-            else
-                                /* of course, we need to give a new command */
-                printf("%d %d %d %c ",
-                       prev_white, prev_black, run,
-                       morepoints(cmd + 'f' - 'a', 2 * run));
-            run = 1;
-        }
-#endif
+parseCommandLine(int                        argc,
+                 const char **        const argv,
+                 struct CmdlineInfo * const cmdlineP) {
+/*----------------------------------------------------------------------------
+   Parse program command line described in Unix standard form by argc
+   and argv.  Return the information in the options as *cmdlineP.
+-----------------------------------------------------------------------------*/
+    optEntry * option_def;  /* malloc'ed */
+        /* Instructions to OptParseOptions3 on how to parse our options.  */
+    optStruct3 opt;
+
+    unsigned int option_def_index;
+
+    MALLOCARRAY_NOFAIL(option_def, 100);
+
+    option_def_index = 0;   /* incremented by OPTENTRY */
+    OPTENT3(0, "linewidth", OPT_FLOAT, &cmdlineP->lineWidth,
+                            &cmdlineP->lineWidthSpec,    0);
+    OPTENT3(0, "dpi",       OPT_FLOAT,  &cmdlineP->dpi,
+                            &cmdlineP->dpiSpec,          0);
+
+    opt.opt_table = option_def;
+    opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
+    opt.allowNegNum = FALSE;  /* We have no parms that are negative numbers */
+
+    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+        /* Uses and sets argc, argv, and some of *cmdlineP and others. */
+
+    if (cmdlineP->dpiSpec)
+        validateDpi(cmdlineP->dpi);
+    else
+        cmdlineP->dpi = 300;
+
+    if (argc-1 < 1)
+        cmdlineP->inputFileName = "-";
+    else {
+        if (argc-1 > 1)
+            pm_error("Program takes zero or one argument (filename).  You "
+                     "specified %u", argc-1);
+        else
+            cmdlineP->inputFileName = argv[1];
     }
 
-    prev_white = white;
-    prev_black = black;
-    cmd = 'a';
+    if (cmdlineP->inputFileName[0] == '-' &&
+        cmdlineP->inputFileName[1] == '\0')
+        cmdlineP->inputFileSpec = false;
+    else
+        cmdlineP->inputFileSpec = true;
+
+    free(option_def);
 }
 
 
 
 static void
-nextline(void) {
-    /* need to check run, should have an outcommand */
-    if (cmd)
-        printf("%d %d %c\n", prev_black, prev_white, morepoints('c', 3));
-    else
-        printf("%c\n", morepoints('b', 1));
-    cmd = '\0';
+validateLineWidth(float const scCols,
+                  float const scRows,
+                  float const lineWidth) {
+
+    if (lineWidth >= scCols || lineWidth >= scRows)
+        pm_error("Absurdly large -linewidth value (%f)", lineWidth);
 }
 
 
 
-int
-main(int argc, char ** argv) {
-    FILE*   fp;
-    bit*    bits;
-    int             row;
-    int             col;
-    int         rows;
-    int             cols;
-    int             format;
-    int             white;
-    int             black;
-    const char*   name;
-    float   dpi = 300.0;
-    float   sc_rows;
-    float   sc_cols;
-    int             i;
-    const char*   const usage = "[ -dpi n ] [ pbmfile ]";
-
-
-	pbm_init(&argc, argv);
-
-    i = 1;
-    if (i < argc && streq(argv[i], "-dpi")) {
-        if (i == argc - 1)
-            pm_usage(usage);
-        sscanf(argv[i + 1], "%f", &dpi);
-        i += 2;
-    }
+static void
+doRaster(FILE *       const ifP,
+         unsigned int const cols,
+         unsigned int const rows,
+         int          const format,
+         FILE *       const ofP) {
 
-    if (i < argc - 1)
-        pm_usage(usage);
+    bit *        bitrow;
+    unsigned int row;
+    unsigned int vertexCt;
+        /* Number of vertices drawn since last stroke command */
 
-    if (i == argc) {
-        name = "noname";
-        fp = stdin;
-    } else {
-        name = argv[i];
-        fp = pm_openr(name);
-    }
-    pbm_readpbminit(fp, &cols, &rows, &format);
-    bits = pbm_allocrow(cols);
-
-    sc_rows = (float)rows / dpi * 72.0;
-    sc_cols = (float)cols / dpi * 72.0;
-
-    puts("%!PS-Adobe-2.0 EPSF-2.0");
-    puts("%%Creator: pbmtolps");
-    printf("%%%%Title: %s\n", name);
-    printf("%%%%BoundingBox: %d %d %d %d\n",
-           (int)(305.5 - sc_cols / 2.0),
-           (int)(395.5 - sc_rows / 2.0),
-           (int)(306.5 + sc_cols / 2.0),
-           (int)(396.5 + sc_rows / 2.0));
-    puts("%%EndComments");
-    puts("%%EndProlog");
-    puts("gsave");
-
-    printf("%f %f translate\n", 306.0 - sc_cols / 2.0, 396.0 + sc_rows / 2.0);
-    printf("72 %f div dup neg scale\n", dpi);
-    puts("/a { 0 rmoveto 0 rlineto } def");
-    puts("/b { 0 row 1 add dup /row exch def moveto } def");
-    puts("/c { a b } def");
-    puts("/m { currentpoint stroke newpath moveto a } def");
-    puts("/n { currentpoint stroke newpath moveto b } def");
-    puts("/o { currentpoint stroke newpath moveto c } def");
-    puts("/row 0 def");
-    puts("newpath 0 0 moveto");
-
-    for (row = 0; row < rows; row++) {
-        pbm_readpbmrow(fp, bits, cols, format);
-        /* output white-strip+black-strip sequences */
-        for (col = 0; col < cols; ) {
-            for (white = 0; col < cols && bits[col] == PBM_WHITE; col++)
-                white++;
-            for (black = 0; col < cols && bits[col] == PBM_BLACK; col++)
-                black++;
+    bitrow = pbm_allocrow(cols);
+
+    for (row = 0, vertexCt = 0; row < rows; ++row) {
+        unsigned int col;
+        bool firstRun;
 
-            if (black != 0)
-                addstrip(white, black);
+        firstRun = true;  /* initial value */
+
+        pbm_readpbmrow(ifP, bitrow, cols, format);
+
+        /* output white-strip + black-strip sequences */
+
+        for (col = 0; col < cols; ) {
+            unsigned int whiteCt;
+            unsigned int blackCt;
+
+            for (whiteCt = 0; col < cols && bitrow[col] == PBM_WHITE; ++col)
+                ++whiteCt;
+            for (blackCt = 0; col < cols && bitrow[col] == PBM_BLACK; ++col)
+                ++blackCt;
+
+            if (blackCt > 0) {
+                if (vertexCt > MAX_PATH_VERTICES) {
+                    printf("m ");
+                    vertexCt = 0;
+                }
+
+                if (firstRun) {
+                    printf("%u %u moveto %u 0 rlineto\n",
+                           whiteCt, row, blackCt);
+                    firstRun = false;
+                } else
+                    printf("%u %u a\n", blackCt, whiteCt);
+
+                vertexCt += 2;
+            }
         }
-        nextline();
     }
-    puts("stroke grestore showpage");
-    puts("%%Trailer");
+    pbm_freerow(bitrow);
+}
+
+
+
+static void
+pbmtolps(FILE *             const ifP,
+         FILE *             const ofP,
+         struct CmdlineInfo const cmdline) {
+
+    const char * const psName =
+        cmdline.inputFileSpec ? cmdline.inputFileName : "noname";
+
+    int          rows;
+    int          cols;
+    int          format;
+    float        scRows, scCols;
+        /* Dimensions of the printed image in points */
+
+    pbm_readpbminit(ifP, &cols, &rows, &format);
+
+    scRows = (float) rows / (cmdline.dpi / 72.0);
+    scCols = (float) cols / (cmdline.dpi / 72.0);
+
+    if (cmdline.lineWidthSpec)
+        validateLineWidth(scCols, scRows, cmdline.lineWidth);
+
+    fputs("%!PS-Adobe-2.0 EPSF-2.0\n", ofP);
+    fputs("%%Creator: pbmtolps\n", ofP);
+    fprintf(ofP, "%%%%Title: %s\n", psName);
+    fprintf(ofP, "%%%%BoundingBox: %d %d %d %d\n",
+           (int)(305.5 - scCols / 2.0),
+           (int)(395.5 - scRows / 2.0),
+           (int)(306.5 + scCols / 2.0),
+           (int)(396.5 + scRows / 2.0));
+    fputs("%%EndComments\n", ofP);
+    fputs("%%EndProlog\n", ofP);
+    fputs("gsave\n", ofP);
+
+    fprintf(ofP, "%f %f translate\n",
+            306.0 - scCols / 2.0, 396.0 + scRows / 2.0);
+    fprintf(ofP, "72 %f div dup neg scale\n", cmdline.dpi);
+
+    if (cmdline.lineWidthSpec)
+        fprintf(ofP, "%f setlinewidth\n", cmdline.lineWidth);
+
+    fputs("/a { 0 rmoveto 0 rlineto } def\n", ofP);
+    fputs("/m { currentpoint stroke newpath moveto } def\n", ofP);
+    fputs("newpath 0 0 moveto\n", ofP);
+
+    doRaster(ifP, cols, rows, format, ofP);
+
+    fputs("stroke grestore showpage\n", ofP);
+    fputs("%%Trailer\n", ofP);
+}
+
+
+
+int
+main(int argc, const char *argv[]) {
+    FILE *  ifP;
+    struct CmdlineInfo cmdline;
+
+    pm_proginit(&argc, argv);
+
+    parseCommandLine(argc, argv, &cmdline);
+
+    ifP = pm_openr(cmdline.inputFileName);
+
+    pbmtolps(ifP, stdout, cmdline);
 
-    pm_close(fp);
+    pm_close(ifP);
 
-    exit(0);
+    return 0;
 }
diff --git a/doc/HISTORY b/doc/HISTORY
index 1fd37630..7dab6eee 100644
--- a/doc/HISTORY
+++ b/doc/HISTORY
@@ -4,14 +4,23 @@ Netpbm.
 CHANGE HISTORY 
 --------------
 
-19.09.28 BJH  Release 10.87.03
+not yet  BJH  Release 10.88.00
 
               pnmquant: Fail if user specifies more than one of -meanpixel,
               -meancolor, and -center, rather than just pick one.
 
-              Build: fix for Cygwin, "no rule to make pm_config.h".
+              pnmremap: Don't output any part of the image if program fails
+              because the maxval of input and map file do not match, in a
+              case where matching maxval is required, i.e. the user specified
+              -firstisdefault or -missingcolor.
+
+              ppmhist: sort secondarily by RGB with -sort=frequency, so
+              output is repeatable.
+
+              pnmcolormap: Add -splitpix, -splitcol, -splitdim.
+              Thanks Vladislav Zavjalov.
 
-19.09.01 BJH  Release 10.87.02
+              pbmtext: fix erroneous failure message with long input text.
 
               jpeg2ktopam, pamtojpeg2k: fix negative array index.  Always
               broken (pamtojpeg2k was new in Netpbm 10.12 (November 2002)).
@@ -25,10 +34,15 @@ CHANGE HISTORY
               jpeg2ktopam: fix null pointer dereference.  Always broken
               (pamtojpeg2k was new in Netpbm 10.12 (November 2002)).
 
-19.08.09 BJH  Release 10.87.01
+              pnmtorle, rletopnm: fix wild pointer dereference when memory
+              allocation fails.  Always broken (programs were added to
+              Netpbm in Release 9.0 (April 2000).
 
-              pnmtorle, rletopnm: fix wild pointer dereference when a memory
-              allocation fails.
+              pamsumm: Fix bug: with -mean and a conflicting option such as
+              -sum, the program ignores one of the options.  It should fail.
+              Always broken (pamsumm was new in Netpbm 10.21 (March 2004).
+
+              Build: fix for Cygwin, "no rule to make pm_config.h".
 
 19.06.28 BJH  Release 10.87.00
 
diff --git a/doc/INSTALL b/doc/INSTALL
index aad0a5e5..3c3bfcbd 100644
--- a/doc/INSTALL
+++ b/doc/INSTALL
@@ -34,7 +34,7 @@ buildtools/debian/README in the source tree.
 The 'configure' program is not GNU Autoconf -- it is a simple program
 specific to Netpbm that prompts you for information about your system.
 If your system is not typical enough, you'll have to do a little more
-work, as described below under "custom installation."
+work, as described below under "custom building."
 
 You need to use GNU Make even if nothing else on your system is GNU,
 because the Netpbm make files exploit many advanced features of GNU
@@ -171,8 +171,8 @@ You do, however, have to tell Configure accurately whether you have the
 library installed and if so, where.
 
 
-INSTALLATION - WINDOWS
-----------------------
+WINDOWS
+-------
 
 For notes on building Netpbm on Windows using Cygwin, see the file
 README.CYGWIN.  With Cygwin, you can build Netpbm programs that use
@@ -223,8 +223,8 @@ and change them to
   #define _XOPEN_SOURCE 0
 
 
-INSTALLATION - MAKING ONLY THE PARTS YOU NEED
----------------------------------------------
+MAKING ONLY THE PARTS YOU NEED
+------------------------------
 
 If you don't need the whole package, but just want one tool in it that you
 heard about, you can make just that one.  For example, to make Pnmtojpeg,
@@ -293,15 +293,20 @@ preprocessor options) are similar.
   $ make CFLAGS=-O0
 
 
-CUSTOM INSTALLATION
--------------------
+AUTOMATED AND CUSTOM INSTALLATION
+---------------------------------
+
+If you want to have a program install Netpbm, don't use 'installnetpbm'.  Just
+write your own program to install from the package that 'make package'
+generates.  That package is just a directory full of files, and you should be
+able to tell by inspection what to do with those files (copy to /bin, etc).
+If not, there is a README file in the package that explains everything.  Your
+install program will probably just be shell script that issues about five
+commands.
 
-If the Installnetpbm program doesn't install the way you want, it is
-easy to install it manually using the package that 'make package'
-generates.  That package is just a directory full of files, and you
-should be able to tell by inspection what to do with those files (copy
-to /bin, etc).  If not, there will be a README file in the package to
-explain everything.
+Likewise, even if you're installing interactively, if the Installnetpbm
+program doesn't install the way you want, just install manually from the
+package, using a few commands such as 'cp'.
 
 
 INSTALLATION - SHARED LIBRARIES
diff --git a/editor/pnmremap.c b/editor/pnmremap.c
index 0038f4d7..0c0096ba 100644
--- a/editor/pnmremap.c
+++ b/editor/pnmremap.c
@@ -1043,13 +1043,6 @@ copyRaster(struct pam *   const inpamP,
     inrow  = pnm_allocpamrow(inpamP);
     outrow = pnm_allocpamrow(&workpam);
 
-    if (outpamP->maxval != inpamP->maxval && defaultColor)
-        pm_error("The maxval of the colormap (%u) is not equal to the "
-                 "maxval of the input image (%u).  This is allowable only "
-                 "if you are doing an approximate mapping (i.e. you don't "
-                 "specify -firstisdefault or -missingcolor)",
-                 (unsigned int)outpamP->maxval, (unsigned int)inpamP->maxval);
-
     selectDepthAdjustment(inpamP, outpamP->depth, &depthAdjustment);
 
     usehash = TRUE;
@@ -1120,6 +1113,13 @@ remap(FILE *             const ifP,
         outpam.width  = inpam.width;
         outpam.height = inpam.height;
 
+        if (outpam.maxval != inpam.maxval && defaultColor)
+            pm_error("The maxval of the colormap (%u) is not equal to the "
+                     "maxval of the input image (%u).  This is allowable only "
+                     "if you are doing an approximate mapping (i.e. you don't "
+                     "specify -firstisdefault or -missingcolor)",
+                     (unsigned int)outpam.maxval, (unsigned int)inpam.maxval);
+
         pnm_writepaminit(&outpam);
 
         /* Set up so input buffers have extra space as needed to
diff --git a/generator/pbmtext.c b/generator/pbmtext.c
index a840d1df..6304c7d4 100644
--- a/generator/pbmtext.c
+++ b/generator/pbmtext.c
@@ -30,7 +30,16 @@
 #include "pbm.h"
 #include "pbmfont.h"
 
-#define  MAXLINECHARS 5000
+/* Max length of input text.  Valid for text which is part of the
+   command line and also for text fed from standard input.
+   Note that newline is counted as a character.
+*/
+#define  MAXLINECHARS 4999
+
+/* We add one slot for the terminating NULL charter
+   and another slot as a margin to detect overruns.
+*/
+#define  LINEBUFSIZE  (MAXLINECHARS + 2)
 
 struct CmdlineInfo {
     /* All the information the user supplied in the command line,
@@ -61,7 +70,7 @@ textFmCmdLine(int argc, const char ** argv) {
     unsigned int i;
     unsigned int totaltextsize;
 
-    MALLOCARRAY(text, MAXLINECHARS+1);
+    MALLOCARRAY(text, LINEBUFSIZE);
 
     if (!text)
         pm_error("Unable to allocate memory for a buffer of up to %u "
@@ -69,13 +78,15 @@ textFmCmdLine(int argc, const char ** argv) {
 
     text[0] = '\0';
 
-    for (i = 1, totaltextsize = 1; i < argc; ++i) {
+    for (i = 1, totaltextsize = 0; i < argc; ++i) {
         if (i > 1) {
             strcat(text, " ");
         }
-        totaltextsize += strlen(argv[i]) + 1;
+        totaltextsize += strlen(argv[i]) + (i > 1 ? 1 : 0);
         if (totaltextsize > MAXLINECHARS)
-            pm_error("input text too long");
+           pm_error("Input text is %u characters.  "
+                    "Cannot process longer than %u",
+                    totaltextsize, (unsigned int) MAXLINECHARS);
         strcat(text, argv[i]);
     }
     MALLOCARRAY(wtext, totaltextsize * sizeof(PM_WCHAR));
@@ -84,7 +95,7 @@ textFmCmdLine(int argc, const char ** argv) {
         pm_error("Unable to allocate memory for a buffer of up to %u "
                  "wide characters of text", totaltextsize);
 
-    for (i = 0; i < totaltextsize; ++i)
+    for (i = 0; i < totaltextsize + 1; ++i)
         wtext[i] = (PM_WCHAR) text[i];
 
     free(text);
@@ -800,7 +811,7 @@ fgetWideString(PM_WCHAR *    const widestring,
     wchar_t * rc;
 
     assert(widestring);
-    assert(size > 0);
+    assert(size > 1);
 
     rc = fgetws(widestring, size, ifP);
 
@@ -838,7 +849,7 @@ fgetNarrowString(PM_WCHAR *    const widestring,
     assert(widestring);
     assert(size > 0);
 
-    MALLOCARRAY_NOFAIL(bufNarrow, MAXLINECHARS+1);
+    MALLOCARRAY_NOFAIL(bufNarrow, LINEBUFSIZE);
 
     rc = fgets(bufNarrow, size, ifP);
 
@@ -871,7 +882,8 @@ fgetNarrowWideString(PM_WCHAR *    const widestring,
                      bool *        const eofP,
                      const char ** const errorP) {
 /*----------------------------------------------------------------------------
-  Return the next line from file *ifP, as *widestring.
+  Return the next line from file *ifP, as *widestring, a buffer 'size'
+  characters long.
 
   Lines are delimited by newline characters and EOF.
 
@@ -963,6 +975,8 @@ getText(PM_WCHAR       const cmdlineText[],
     } else {
         /* Read text from stdin. */
 
+        unsigned int const lineBufTerm = LINEBUFSIZE - 1;
+
         unsigned int maxlines;
             /* Maximum number of lines for which we presently have space in
                the text array
@@ -972,11 +986,13 @@ getText(PM_WCHAR       const cmdlineText[],
         unsigned int lineCount;
         bool         eof;
 
-        MALLOCARRAY(buf, MAXLINECHARS+1);
+        MALLOCARRAY(buf, LINEBUFSIZE);
 
         if (!buf)
             pm_error("Unable to allocate memory for up to %u characters of "
                      "text", MAXLINECHARS);
+        buf[lineBufTerm] = L'\1';  /* Initalize to non-zero value */
+                                   /* to detect input overrun */
 
         maxlines = 50;  /* initial value */
         MALLOCARRAY(textArray, maxlines);
@@ -987,18 +1003,18 @@ getText(PM_WCHAR       const cmdlineText[],
 
         for (lineCount = 0, eof = false; !eof; ) {
             const char * error;
-            fgetNarrowWideString(buf, MAXLINECHARS, stdin, &eof, &error);
+            fgetNarrowWideString(buf, LINEBUFSIZE, stdin, &eof, &error);
             if (error)
                 pm_error("Unable to read line %u from file.  %s",
                          lineCount, error);
             else {
                 if (!eof) {
-                    if (wcslen(buf) + 1 >= MAXLINECHARS)
+                    if (buf[lineBufTerm] == L'\0') /* overrun */
                         pm_error(
                             "Line %u (starting at zero) of input text "
-                            "is longer than %u characters."
+                            "is longer than %u characters. "
                             "Cannot process",
-                            lineCount, (unsigned int) MAXLINECHARS-1);
+                            lineCount, (unsigned int) MAXLINECHARS);
                     if (lineCount >= maxlines) {
                         maxlines *= 2;
                         REALLOCARRAY(textArray, maxlines);
diff --git a/lib/libppmcmap.c b/lib/libppmcmap.c
index f78d0516..0f6439ae 100644
--- a/lib/libppmcmap.c
+++ b/lib/libppmcmap.c
@@ -34,8 +34,8 @@ ppm_hashpixel(pixel const p) {
 
 
 colorhist_vector
-ppm_computecolorhist( pixel ** const pixels, 
-                      const int cols, const int rows, const int maxcolors, 
+ppm_computecolorhist( pixel ** const pixels,
+                      const int cols, const int rows, const int maxcolors,
                       int * const colorsP ) {
 /*----------------------------------------------------------------------------
    Compute a color histogram for the image described by 'pixels',
@@ -45,7 +45,7 @@ ppm_computecolorhist( pixel ** const pixels,
 
    If 'maxcolors' is zero, make the output have 5 spare slots at the end
    for expansion.
-   
+
    If 'maxcolors' is nonzero, make the output have 'maxcolors' slots in
    it, and if there are more colors than that in the image, don't return
    anything except a NULL pointer.
@@ -66,29 +66,36 @@ ppm_computecolorhist( pixel ** const pixels,
 
 
 colorhist_vector
-ppm_computecolorhist2(FILE * const ifp,
-                      const int cols, const int rows, 
-                      const pixval maxval, const int format, 
-                      const int maxcolors, int * const colorsP ) {
+ppm_computecolorhist2(FILE * const ifP,
+                      int    const cols,
+                      int    const rows,
+                      pixval const maxval,
+                      int    const format,
+                      int    const maxcolorCt,
+                      int *  const colorCtP ) {
 
-    colorhash_table cht;
-    colorhist_vector chv;
+    colorhist_vector retval;
+    colorhash_table  cht;
 
-    cht = ppm_computecolorhash2(ifp, cols, rows, maxval, format, 
-                                maxcolors, colorsP);
+    cht = ppm_computecolorhash2(ifP, cols, rows, maxval, format,
+                                maxcolorCt, colorCtP);
     if (cht ==NULL)
-        return NULL;
-    chv = ppm_colorhashtocolorhist(cht, maxcolors);
-    ppm_freecolorhash(cht);
-    return chv;
+        retval = NULL;
+    else {
+        retval = ppm_colorhashtocolorhist(cht, maxcolorCt);
+
+        ppm_freecolorhash(cht);
+    }
+
+    return retval;
 }
 
 
 
 void
-ppm_addtocolorhist( colorhist_vector chv, 
-                    int * const colorsP, const int maxcolors, 
-                    const pixel * const colorP, 
+ppm_addtocolorhist( colorhist_vector chv,
+                    int * const colorsP, const int maxcolors,
+                    const pixel * const colorP,
                     const int value, const int position ) {
     int i, j;
 
@@ -149,16 +156,16 @@ ppm_alloccolorhash(void)  {
 
 
 static void
-readppmrow(FILE *        const fileP, 
-           pixel *       const pixelrow, 
-           int           const cols, 
-           pixval        const maxval, 
+readppmrow(FILE *        const fileP,
+           pixel *       const pixelrow,
+           int           const cols,
+           pixval        const maxval,
            int           const format,
            const char ** const errorP) {
 
     jmp_buf jmpbuf;
     jmp_buf * origJmpbufP;
-    
+
     if (setjmp(jmpbuf) != 0) {
         pm_setjmpbuf(origJmpbufP);
         pm_asprintf(errorP, "Failed to read row of image.");
@@ -168,7 +175,7 @@ readppmrow(FILE *        const fileP,
         ppm_readppmrow(fileP, pixelrow, cols, maxval, format);
 
         *errorP = NULL; /* Would have longjmped if anything went wrong */
-                
+
         pm_setjmpbuf(origJmpbufP);
     }
 }
@@ -213,15 +220,15 @@ buildHashTable(FILE *          const ifP,
         if (ifP) {
             readppmrow(ifP, rowbuffer, cols, maxval, format, errorP);
             pixelrow = rowbuffer;
-        } else 
+        } else
             pixelrow = pixels[row];
 
         for (col = 0; col < cols && !*tooManyColorsP && !*errorP; ++col) {
             const pixel apixel = pixelrow[col];
             const int hash = ppm_hashpixel(apixel);
-            colorhist_list chl; 
+            colorhist_list chl;
 
-            for (chl = cht[hash]; 
+            for (chl = cht[hash];
                  chl && !PPM_EQUAL(chl->ch.color, apixel);
                  chl = chl->next);
 
@@ -251,9 +258,9 @@ buildHashTable(FILE *          const ifP,
 
 
 static void
-computecolorhash(pixel **          const pixels, 
+computecolorhash(pixel **          const pixels,
                  unsigned int      const cols,
-                 unsigned int      const rows, 
+                 unsigned int      const rows,
                  unsigned int      const maxcolors,
                  int *             const nColorsP,
                  FILE *            const ifP,
@@ -271,8 +278,8 @@ computecolorhash(pixel **          const pixels,
       'pixels' is NULL and 'ifP' is non-NULL.  ifP is the stream
       descriptor for the input file, and 'maxval' and 'format' are
       parameters of the image data in it.
-      
-      We return with the file still open and its position undefined.  
+
+      We return with the file still open and its position undefined.
 
    In either case, the image is 'cols' by 'rows'.
 
@@ -288,7 +295,7 @@ computecolorhash(pixel **          const pixels,
         */
 
     MALLOCARRAY(rowbuffer, cols);
-        
+
     if (rowbuffer == NULL)
         pm_asprintf(errorP, "Unable to allocate %u-column row buffer.", cols);
     else {
@@ -303,7 +310,7 @@ computecolorhash(pixel **          const pixels,
             buildHashTable(ifP, pixels, cols, rows, maxval, format, maxcolors,
                            cht, rowbuffer,
                            nColorsP, &tooManyColors, errorP);
-                
+
             if (tooManyColors) {
                 ppm_freecolorhash(cht);
                 *chtP = NULL;
@@ -320,16 +327,16 @@ computecolorhash(pixel **          const pixels,
 
 
 colorhash_table
-ppm_computecolorhash(pixel ** const pixels, 
+ppm_computecolorhash(pixel ** const pixels,
                      int      const cols,
-                     int      const rows, 
+                     int      const rows,
                      int      const maxcolors,
                      int *    const colorsP) {
 
     colorhash_table cht;
     const char * error;
 
-    computecolorhash(pixels, cols, rows, maxcolors, colorsP, 
+    computecolorhash(pixels, cols, rows, maxcolors, colorsP,
                      NULL, 0, 0, &cht, &error);
 
     if (error) {
@@ -345,9 +352,9 @@ ppm_computecolorhash(pixel ** const pixels,
 colorhash_table
 ppm_computecolorhash2(FILE * const ifP,
                       int    const cols,
-                      int    const rows, 
+                      int    const rows,
                       pixval const maxval,
-                      int    const format, 
+                      int    const format,
                       int    const maxcolors,
                       int *  const colorsP ) {
 
@@ -368,8 +375,8 @@ ppm_computecolorhash2(FILE * const ifP,
 
 
 int
-ppm_addtocolorhash(colorhash_table const cht, 
-                   const pixel *   const colorP, 
+ppm_addtocolorhash(colorhash_table const cht,
+                   const pixel *   const colorP,
                    int             const value) {
 /*----------------------------------------------------------------------------
    Add color *colorP to the color hash 'cht' with associated value 'value'.
@@ -397,7 +404,7 @@ ppm_addtocolorhash(colorhash_table const cht,
 
 
 void
-ppm_delfromcolorhash(colorhash_table const cht, 
+ppm_delfromcolorhash(colorhash_table const cht,
                      const pixel *   const colorP) {
 /*----------------------------------------------------------------------------
    Delete the color *colorP from the colorhahs 'cht', if it's there.
@@ -433,7 +440,7 @@ colorHashSize(colorhash_table const cht) {
     nColors = 0;
     for (i = 0; i < HASH_SIZE; ++i) {
         colorhist_list chl;
-        for (chl = cht[i]; chl; chl = chl->next) 
+        for (chl = cht[i]; chl; chl = chl->next)
             ++nColors;
     }
     return nColors;
@@ -445,8 +452,8 @@ colorhist_vector
 ppm_colorhashtocolorhist(colorhash_table const cht, int const maxcolors) {
 
     colorhist_vector chv;
-    colorhist_list chl;
-    unsigned int chvSize;
+    colorhist_list   chl;
+    unsigned int     chvSize;
 
     if (maxcolors == 0)
         /* We leave space for 5 more colors so caller can add in special
@@ -457,7 +464,7 @@ ppm_colorhashtocolorhist(colorhash_table const cht, int const maxcolors) {
         /* Caller is responsible for making sure there are no more
            than 'maxcolors' colors in the colorhash table.  NOTE:
            Before March 2002, the maxcolors == 0 invocation didn't
-           exist.  
+           exist.
         */
         chvSize = maxcolors;
 
@@ -483,7 +490,7 @@ ppm_colorhashtocolorhist(colorhash_table const cht, int const maxcolors) {
 
 
 colorhash_table
-ppm_colorhisttocolorhash(colorhist_vector const chv, 
+ppm_colorhisttocolorhash(colorhist_vector const chv,
                          int              const colors) {
 
     colorhash_table retval;
@@ -499,7 +506,7 @@ ppm_colorhisttocolorhash(colorhist_vector const chv,
         for (i = 0, error = NULL; i < colors && !error; ++i) {
             pixel const color = chv[i].color;
             int const hash = ppm_hashpixel(color);
-            
+
             colorhist_list chl;
 
             for (chl = cht[hash]; chl && !error; chl = chl->next)
@@ -534,7 +541,7 @@ ppm_colorhisttocolorhash(colorhist_vector const chv,
 
 
 int
-ppm_lookupcolor(colorhash_table const cht, 
+ppm_lookupcolor(colorhash_table const cht,
                 const pixel *   const colorP) {
     int hash;
     colorhist_list chl;
@@ -731,7 +738,7 @@ pixelCmp(const void * const a,
 
 void
 ppm_sortcolorrow(pixel * const colorrow,
-                 int     const ncolors, 
+                 int     const ncolors,
                  int (*cmpfunc)(pixel *, pixel *)) {
 
     if (cmpfunc) {
@@ -774,10 +781,10 @@ ppm_addtocolorrow(colorrow, ncolorsP, maxcolors, pixelP)
 
 
 int
-ppm_findclosestcolor(const pixel * const colormap, 
-                     int           const ncolors, 
+ppm_findclosestcolor(const pixel * const colormap,
+                     int           const ncolors,
                      const pixel * const pP) {
-    
+
     /* Search colormap for closest match.       */
 
     int i;
@@ -789,7 +796,7 @@ ppm_findclosestcolor(const pixel * const colormap,
 
     for(i = 0; i < ncolors && bestDist > 0; ++i) {
         unsigned int const dist = PPM_DISTANCE(*pP, colormap[i]);
-        
+
         if (dist < bestDist ) {
             ind = i;
             bestDist = dist;
diff --git a/lib/pammap.h b/lib/pammap.h
index da2e2470..3477b84e 100644
--- a/lib/pammap.h
+++ b/lib/pammap.h
@@ -20,14 +20,14 @@ extern "C" {
 #endif
 
 struct tupleint {
-    /* An ordered pair of a tuple value and an integer, such as you 
+    /* An ordered pair of a tuple value and an integer, such as you
        would find in a tuple table or tuple hash.
 
        Note that this is a variable length structure.
     */
     int value;
-    sample tuple[1];  
-        /* This is actually a variable size array -- its size is the 
+    sample tuple[1];
+        /* This is actually a variable size array -- its size is the
            depth of the tuple in question.  Some compilers do not let us
            declare a variable length array.
         */
@@ -52,20 +52,20 @@ pnm_hashtuple(struct pam * const pamP, tuple const tuple);
 
 void
 pnm_addtotuplehash(struct pam *   const pamP,
-                   tuplehash      const tuplehash, 
+                   tuplehash      const tuplehash,
                    tuple          const tuple,
                    int            const value,
                    int *          const fitsP);
 
 void
 pnm_addtuplefreqoccurrence(struct pam *   const pamP,
-                           tuple          const value, 
+                           tuple          const value,
                            tuplehash      const tuplefreqhash,
                            int *          const firstOccurrenceP);
 
 void
-pnm_lookuptuple(struct pam * const pamP, const tuplehash tuplehash, 
-                const tuple searchval, 
+pnm_lookuptuple(struct pam * const pamP, const tuplehash tuplehash,
+                const tuple searchval,
                 int * const foundP, int * const retvalP);
 
 tupletable
@@ -113,7 +113,7 @@ pnm_computetuplefreqhash(struct pam *   const pamP,
                          unsigned int * const sizeP);
 
 tuplehash
-pnm_computetupletablehash(struct pam * const pamP, 
+pnm_computetupletablehash(struct pam * const pamP,
                           tupletable   const tupletable,
                           unsigned int const tupletableSize);
 
@@ -123,8 +123,8 @@ pnm_tuplehashtotable(const struct pam * const pamP,
                      unsigned int       const maxsize);
 
 char*
-pam_colorname(struct pam *         const pamP, 
-              tuple                const color, 
+pam_colorname(struct pam *         const pamP,
+              tuple                const color,
               enum colornameFormat const format);
 
 #ifdef __cplusplus
diff --git a/lib/ppmcmap.h b/lib/ppmcmap.h
index dd3e5c14..4ce822a6 100644
--- a/lib/ppmcmap.h
+++ b/lib/ppmcmap.h
@@ -16,30 +16,37 @@ extern "C" {
 typedef struct colorhist_item* colorhist_vector;
 struct colorhist_item {
     pixel color;
-    int value;
+    int   value;
 };
 
 typedef struct colorhist_list_item* colorhist_list;
 struct colorhist_list_item {
     struct colorhist_item ch;
-    colorhist_list next;
+    colorhist_list        next;
 };
 
 colorhist_vector
-ppm_computecolorhist( pixel ** const pixels, 
-                      const int cols, const int rows, const int maxcolors, 
-                      int * const colorsP );
+ppm_computecolorhist(pixel ** const pixels,
+                     int      const cols,
+                     int      const rows,
+                     int      const maxcolors,
+                     int *    const colorsP);
 colorhist_vector
-ppm_computecolorhist2(FILE * const ifp,
-                      const int cols, const int rows, 
-                      const pixval maxval, const int format, 
-                      const int maxcolors, int * const colorsP );
+ppm_computecolorhist2(FILE * const ifP,
+                      int    const cols,
+                      int    const rows,
+                      pixval const maxval,
+                      int    const format,
+                      int    const maxcolors,
+                      int *  const colorsP);
 
 void
-ppm_addtocolorhist(colorhist_vector chv, 
-                   int * const colorsP, const int maxcolors, 
-                   const pixel * const colorP, 
-                   const int value, const int position );
+ppm_addtocolorhist(colorhist_vector       chv,
+                   int *            const colorsP,
+                   int              const maxcolors,
+                   const pixel *    const colorP,
+                   int              const value,
+                   int              const position);
 
 void
 ppm_freecolorhist(colorhist_vector const chv);
@@ -50,35 +57,40 @@ ppm_freecolorhist(colorhist_vector const chv);
 typedef colorhist_list* colorhash_table;
 
 colorhash_table
-ppm_computecolorhash( pixel ** const pixels, 
-                      const int cols, const int rows, 
-                      const int maxcolors, int * const colorsP );
+ppm_computecolorhash(pixel ** const pixels,
+                     int      const cols,
+                     int      const rows,
+                     int      const maxcolors,
+                     int *    const colorsP);
 
 colorhash_table
-ppm_computecolorhash2(FILE * const ifp,
-                      const int cols, const int rows, 
-                      const pixval maxval, const int format, 
-                      const int maxcolors, int * const colorsP);
+ppm_computecolorhash2(FILE * const ifP,
+                      int    const cols,
+                      int    const rows,
+                      pixval const maxval,
+                      int    const format,
+                      int    const maxcolors,
+                      int *  const colorsP);
 
 int
-ppm_lookupcolor(colorhash_table const cht, 
+ppm_lookupcolor(colorhash_table const cht,
                 const pixel *   const colorP );
 
 colorhist_vector
-ppm_colorhashtocolorhist(colorhash_table const cht, 
+ppm_colorhashtocolorhist(colorhash_table const cht,
                          int             const maxcolors);
 
 colorhash_table
-ppm_colorhisttocolorhash(colorhist_vector const chv, 
+ppm_colorhisttocolorhash(colorhist_vector const chv,
                          int              const colors);
 
 int
-ppm_addtocolorhash(colorhash_table const cht, 
-                   const pixel *   const colorP, 
+ppm_addtocolorhash(colorhash_table const cht,
+                   const pixel *   const colorP,
                    int             const value);
 
 void
-ppm_delfromcolorhash(colorhash_table const cht, 
+ppm_delfromcolorhash(colorhash_table const cht,
                      const pixel *   const colorP);
 
 
@@ -114,7 +126,7 @@ ppm_colorrowtomapfile(FILE *  const ofP,
 
 void
 ppm_sortcolorrow(pixel * const colorrow,
-                 int     const ncolors, 
+                 int     const ncolors,
                  int (*cmpfunc)(pixel *, pixel *));
 
 int
@@ -124,8 +136,8 @@ ppm_addtocolorrow(pixel * const colorrow,
                   pixel * const pixelP);
 
 int
-ppm_findclosestcolor(const pixel * const colormap, 
-                     int           const ncolors, 
+ppm_findclosestcolor(const pixel * const colormap,
+                     int           const ncolors,
                      const pixel * const pP);
 
 /* standard sort function for ppm_sortcolorrow() */
diff --git a/lib/util/shhopt.h b/lib/util/shhopt.h
index 03f40cc5..b6d4cdfd 100644
--- a/lib/util/shhopt.h
+++ b/lib/util/shhopt.h
@@ -26,7 +26,6 @@ main ( int argc, char **argv ) {
     optEntry * option_def;
     MALLOCARRAY(option_def, 100);
 
-    OPTENT3(0,   "help",     OPT_FLAG,       &help_flag,    &help_spec,   0);
     OPTENT3(0,   "height",   OPT_INT,        &height,       &height_spec, 0);
     OPTENT3('n', "name",     OPT_STRING,     &name,         &name_spec,   0);
     OPTENT3('v', "verbose",  OPT_FLAG,       &verbose_flag, NULL,         0);
@@ -43,8 +42,6 @@ main ( int argc, char **argv ) {
 
 
     printf("argc=%d\n", argc);
-    printf("help_flag=%d\n", help_flag);
-    printf("help_spec=%d\n", help_spec);
     printf("height=%d\n", height);
     printf("height_spec=%d\n", height_spec);
     printf("name='%s'\n", name);
@@ -76,7 +73,7 @@ main ( int argc, char **argv ) {
 
 Now run this program with something like
 
-  myprog -vg --name=Bryan --hei 4 "My first argument" --help
+  myprog -vg --name=Bryan --hei 4 "My first argument" --verbose
 
   or do it with opt.short_allowed=0 and
 
@@ -184,7 +181,7 @@ typedef struct {
 
        unsigned int option_def_index = 0;
        optStruct *option_def = malloc(100*sizeof(optStruct));
-       OPTENTRY('h', "help",     OPT_FLAG, &help_flag, 0);
+       OPTENTRY('h', "verbose",  OPT_FLAG, &verbose_flag, 0);
        OPTENTRY(0,   "alphaout", OPT_STRING, &alpha_filename, 0);
 */
 
@@ -224,11 +221,11 @@ typedef struct {
    Here is an example:
 
        unsigned int option_def_index = 0;
-       unsigned int help_flag;
+       unsigned int verbose_flag;
        const char * alpha_filename
        unsigned int alpha_spec;
        MALLOCARRAY_NOFAIL(option_def, 100);
-       OPTENT3('h', "help",     OPT_FLAG,   &help_flag,      NULL);
+       OPTENT3('h', "verbose",  OPT_FLAG,   &verbose_flag    NULL);
        OPTENT3(0,   "alphaout", OPT_STRING, &alpha_filename, &alpha_spec);
 */
 
diff --git a/other/pamx/Makefile b/other/pamx/Makefile
index e4892540..7fe7b9db 100644
--- a/other/pamx/Makefile
+++ b/other/pamx/Makefile
@@ -9,7 +9,10 @@ include $(BUILDDIR)/config.mk
 
 EXTERN_INCLUDE =
 
-ifeq ($(shell $(PKG_CONFIG) x11 --modversion --silence-errors),)
+TEST_PKGCONFIG_X11 := \
+  if $(PKG_CONFIG) x11 --exists; then echo exists; fi
+
+ifeq ($(shell $(TEST_PKGCONFIG_X11)),)
   # Pkg-config has never heard of X11, or doesn't even exist
 
   ifneq ($(X11LIB),NONE)
@@ -46,7 +49,8 @@ all: $(BINARIES)
 
 include $(SRCDIR)/common.mk
 
-ifeq ($(shell $(PKG_CONFIG) x11 --libs),)
+ifeq ($(shell $(TEST_PKGCONFIG_X11)),)
+  # Pkg-config has never heard of X11, or doesn't even exist
   X11_LIBOPTS = $(shell $(LIBOPT) $(LIBOPTR) $(X11LIB))
 else
   X11_LIBOPTS = $(shell $(PKG_CONFIG) x11 --libs)
diff --git a/other/pnmcolormap.c b/other/pnmcolormap.c
index f687f037..7da3122b 100644
--- a/other/pnmcolormap.c
+++ b/other/pnmcolormap.c
@@ -23,6 +23,7 @@
 
 ******************************************************************************/
 
+#include <assert.h>
 #include <math.h>
 
 #include "pm_config.h"
@@ -33,29 +34,42 @@
 #include "pam.h"
 #include "pammap.h"
 
-enum methodForLargest {LARGE_NORM, LARGE_LUM};
+enum MethodForLargest {LARGE_NORM, LARGE_LUM};
 
-enum methodForRep {REP_CENTER_BOX, REP_AVERAGE_COLORS, REP_AVERAGE_PIXELS};
+enum MethodForRep {REP_CENTER_BOX, REP_AVERAGE_COLORS, REP_AVERAGE_PIXELS};
 
-typedef struct box* boxVector;
-struct box {
-    int ind;
-    int colors;
-    int sum;
+enum MethodForSplit {SPLIT_MAX_PIXELS, SPLIT_MAX_COLORS, SPLIT_MAX_SPREAD};
+
+struct Box {
+    unsigned int index;
+    unsigned int colorCt;
+    unsigned int sum;
+    unsigned int maxdim;
+        /* which dimension has the largest spread.  RGB plane number. */
+    sample       spread;
+        /* spread in dimension 'maxdim' */
+};
+
+struct BoxVector {
+    struct Box * box;  /* malloc'ed array */
+    unsigned int boxCt;
+    unsigned int capacity;
 };
 
-struct cmdlineInfo {
+struct CmdlineInfo {
     /* All the information the user supplied in the command line,
        in a form easy for the program to use.
     */
-    const char *inputFilespec;  /* Filespec of input file */
+    const char * inputFileNm;  /* Name of input file */
     unsigned int allcolors;  /* boolean: select all colors from the input */
     unsigned int newcolors;
         /* Number of colors argument; meaningless if allcolors true */
-    enum methodForLargest methodForLargest;
+    enum MethodForLargest methodForLargest;
         /* -spreadintensity/-spreadluminosity options */
-    enum methodForRep methodForRep;
+    enum MethodForRep methodForRep;
         /* -center/-meancolor/-meanpixel options */
+    enum MethodForSplit methodForSplit;
+        /* -splitpixelct/-splitcolorct/-splitspread options */
     unsigned int sort;
     unsigned int square;
     unsigned int verbose;
@@ -64,8 +78,8 @@ struct cmdlineInfo {
 
 
 static void
-parseCommandLine (int argc, char ** argv,
-                  struct cmdlineInfo *cmdlineP) {
+parseCommandLine (int argc, const char ** argv,
+                  struct CmdlineInfo *cmdlineP) {
 /*----------------------------------------------------------------------------
    parse program command line described in Unix standard form by argc
    and argv.  Return the information in the options as *cmdlineP.
@@ -85,6 +99,7 @@ parseCommandLine (int argc, char ** argv,
 
     unsigned int spreadbrightness, spreadluminosity;
     unsigned int center, meancolor, meanpixel;
+    unsigned int splitpixelct, splitcolorct, splitspread;
 
     MALLOCARRAY_NOFAIL(option_def, 100);
 
@@ -99,6 +114,12 @@ parseCommandLine (int argc, char ** argv,
             NULL,                       &meancolor,        0);
     OPTENT3(0,   "meanpixel",        OPT_FLAG,
             NULL,                       &meanpixel,        0);
+    OPTENT3(0,   "splitpixelct",     OPT_FLAG,
+            NULL,                       &splitpixelct,     0);
+    OPTENT3(0,   "splitcolorct",     OPT_FLAG,
+            NULL,                       &splitcolorct,     0);
+    OPTENT3(0,   "splitspread",      OPT_FLAG,
+            NULL,                       &splitspread,      0);
     OPTENT3(0, "sort",     OPT_FLAG,   NULL,
             &cmdlineP->sort,       0 );
     OPTENT3(0, "square",   OPT_FLAG,   NULL,
@@ -110,7 +131,7 @@ parseCommandLine (int argc, char ** argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We have no parms that are negative numbers */
 
-    pm_optParseOptions3( &argc, argv, opt, sizeof(opt), 0 );
+    pm_optParseOptions3( &argc, (char **)argv, opt, sizeof(opt), 0 );
         /* Uses and sets argc, argv, and some of *cmdline_p and others. */
 
 
@@ -132,15 +153,24 @@ parseCommandLine (int argc, char ** argv,
     else
         cmdlineP->methodForRep = REP_CENTER_BOX;
 
+    if (splitpixelct)
+        cmdlineP->methodForSplit = SPLIT_MAX_PIXELS;
+    else if (splitcolorct)
+        cmdlineP->methodForSplit = SPLIT_MAX_COLORS;
+    else if (splitspread)
+        cmdlineP->methodForSplit = SPLIT_MAX_SPREAD;
+    else
+        cmdlineP->methodForSplit = SPLIT_MAX_PIXELS;
+
     if (argc-1 > 2)
         pm_error("Program takes at most two arguments: number of colors "
                  "and input file specification.  "
                  "You specified %d arguments.", argc-1);
     else {
         if (argc-1 < 2)
-            cmdlineP->inputFilespec = "-";
+            cmdlineP->inputFileNm = "-";
         else
-            cmdlineP->inputFilespec = argv[2];
+            cmdlineP->inputFileNm = argv[2];
 
         if (argc-1 < 1)
             pm_error("You must specify the number of colors in the "
@@ -185,8 +215,13 @@ compareplane(const void * const arg1,
     const struct tupleint * const * const comparandPP  = arg1;
     const struct tupleint * const * const comparatorPP = arg2;
 
-    return (*comparandPP)->tuple[compareplanePlane] -
-        (*comparatorPP)->tuple[compareplanePlane];
+    sample const comparandSample  = (*comparandPP) ->tuple[compareplanePlane];
+    sample const comparatorSample = (*comparatorPP)->tuple[compareplanePlane];
+
+    return
+        comparandSample < comparatorSample ? -1 :
+        comparandSample > comparatorSample ? 1 :
+        0;
 }
 
 
@@ -196,61 +231,82 @@ static qsort_comparison_fn sumcompare;
 #endif
 
 static int
-sumcompare(const void * const b1, const void * const b2) {
-    return(((boxVector)b2)->sum - ((boxVector)b1)->sum);
+sumcompare(const void * const arg1,
+           const void * const arg2) {
+
+    struct Box * const comparandP  = (struct Box *)arg1;
+    struct Box * const comparatorP = (struct Box *)arg2;
+
+    return
+        comparatorP->sum < comparandP->sum ? -1 :
+        comparatorP->sum > comparandP->sum ? 1 :
+        0;
 }
 
 
 
+#ifndef LITERAL_FN_DEF_MATCH
+static qsort_comparison_fn colcompare;
+#endif
 
-/*
-** Here is the fun part, the median-cut colormap generator.  This is based
-** on Paul Heckbert's paper "Color Image Quantization for Frame Buffer
-** Display", SIGGRAPH '82 Proceedings, page 297.
-*/
+static int
+colcompare(const void * const arg1,
+           const void * const arg2) {
 
-static tupletable2
-newColorMap(unsigned int const newcolors,
-            unsigned int const depth) {
+    struct Box * const comparandP  = (struct Box *)arg1;
+    struct Box * const comparatorP = (struct Box *)arg2;
 
-    tupletable2 colormap;
-    unsigned int i;
-    struct pam pam;
+    return
+        comparatorP->colorCt < comparandP->colorCt ? -1 :
+        comparatorP->colorCt > comparandP->colorCt ? 1 :
+        0;
+}
 
-    pam.depth = depth;
 
-    colormap.table = pnm_alloctupletable(&pam, newcolors);
 
-    for (i = 0; i < newcolors; ++i) {
-        unsigned int plane;
-        for (plane = 0; plane < depth; ++plane)
-            colormap.table[i]->tuple[plane] = 0;
-    }
-    colormap.size = newcolors;
+#ifndef LITERAL_FN_DEF_MATCH
+static qsort_comparison_fn spreadcompare;
+#endif
 
-    return colormap;
+static int
+spreadcompare(const void * const arg1,
+              const void * const arg2) {
+
+    struct Box * const comparandP  = (struct Box *)arg1;
+    struct Box * const comparatorP = (struct Box *)arg2;
+
+    return
+        comparatorP->spread < comparandP->spread ? -1 :
+        comparatorP->spread > comparandP->spread ? 1 :
+        0;
 }
 
 
 
-static boxVector
-newBoxVector(int const colors, int const sum, int const newcolors) {
+static void
+sortBoxes(struct BoxVector *  const boxVectorP,
+          enum MethodForSplit const methodForSplit) {
 
-    boxVector bv;
-    MALLOCARRAY(bv, newcolors);
-    if (bv == NULL)
-        pm_error("out of memory allocating box vector table");
+    qsort_comparison_fn * comparisonFn;
 
-    /* Set up the initial box. */
-    bv[0].ind = 0;
-    bv[0].colors = colors;
-    bv[0].sum = sum;
+    switch (methodForSplit){
+    case SPLIT_MAX_PIXELS: comparisonFn = &sumcompare;    break;
+    case SPLIT_MAX_COLORS: comparisonFn = &colcompare;    break;
+    case SPLIT_MAX_SPREAD: comparisonFn = &spreadcompare; break;
+    }
 
-    return bv;
+    qsort((char*) &boxVectorP->box[0], boxVectorP->boxCt, sizeof(struct Box),
+          comparisonFn);
 }
 
 
 
+/*
+** Here is the fun part, the median-cut colormap generator.  This is based
+** on Paul Heckbert's paper "Color Image Quantization for Frame Buffer
+** Display", SIGGRAPH '82 Proceedings, page 297.
+*/
+
 static void
 findBoxBoundaries(tupletable2  const colorfreqtable,
                   unsigned int const depth,
@@ -259,8 +315,8 @@ findBoxBoundaries(tupletable2  const colorfreqtable,
                   sample             minval[],
                   sample             maxval[]) {
 /*----------------------------------------------------------------------------
-  Go through the box finding the minimum and maximum of each
-  component - the boundaries of the box.
+  Go through the box finding the minimum and maximum of each component - the
+  boundaries of the box.
 -----------------------------------------------------------------------------*/
     unsigned int plane;
     unsigned int i;
@@ -282,57 +338,158 @@ findBoxBoundaries(tupletable2  const colorfreqtable,
 
 
 
-static unsigned int
-largestByNorm(sample minval[], sample maxval[], unsigned int const depth) {
-
-    unsigned int largestDimension;
+static void
+findPlaneWithLargestSpreadByNorm(sample         const minval[],
+                                 sample         const maxval[],
+                                 unsigned int   const depth,
+                                 unsigned int * const planeP,
+                                 sample *       const spreadP) {
+
+    unsigned int planeWithLargest;
+    sample       largestSpreadSoFar;
     unsigned int plane;
 
-    sample largestSpreadSoFar = 0;
-    largestDimension = 0;
-    for (plane = 0; plane < depth; ++plane) {
+    for (plane = 0, largestSpreadSoFar = 0; plane < depth; ++plane) {
+
         sample const spread = maxval[plane]-minval[plane];
         if (spread > largestSpreadSoFar) {
-            largestDimension = plane;
             largestSpreadSoFar = spread;
+            planeWithLargest   = plane;
         }
     }
-    return largestDimension;
+    *planeP  = planeWithLargest;
+    *spreadP = largestSpreadSoFar;
 }
 
 
 
-static unsigned int
-largestByLuminosity(sample minval[], sample maxval[],
-                    unsigned int const depth) {
+static void
+findPlaneWithLargestSpreadByLuminosity(sample         const minval[],
+                                       sample         const maxval[],
+                                       unsigned int   const depth,
+                                       unsigned int * const planeP,
+                                       sample *       const spreadP) {
 /*----------------------------------------------------------------------------
    This subroutine presumes that the tuple type is either
    BLACKANDWHITE, GRAYSCALE, or RGB (which implies pamP->depth is 1 or 3).
    To save time, we don't actually check it.
 -----------------------------------------------------------------------------*/
-    unsigned int retval;
-
-    if (depth == 1)
-        retval = 0;
-    else {
+    if (depth == 1){
+        *planeP  = 0;
+        *spreadP = 0;
+    } else {
         /* An RGB tuple */
-        unsigned int largestDimension;
+        unsigned int planeWithLargest;
+        sample       largestSpreadSoFar;
         unsigned int plane;
-        double largestSpreadSoFar;
 
-        largestSpreadSoFar = 0.0;
+        assert(depth >= 3);
 
-        for (plane = 0; plane < 3; ++plane) {
+        for (plane = 0, largestSpreadSoFar = 0; plane < 3; ++plane) {
             double const spread =
                 pnm_lumin_factor[plane] * (maxval[plane]-minval[plane]);
             if (spread > largestSpreadSoFar) {
-                largestDimension = plane;
                 largestSpreadSoFar = spread;
+                planeWithLargest   = plane;
             }
         }
-        retval = largestDimension;
+        *planeP  = planeWithLargest;
+        *spreadP = largestSpreadSoFar;
+    }
+}
+
+
+
+static void
+computeBoxSpread(const struct Box *    const boxP,
+                 tupletable2           const colorfreqtable,
+                 unsigned int          const depth,
+                 enum MethodForLargest const methodForLargest,
+                 unsigned int *        const planeWithLargestP,
+                 sample *              const spreadP
+                 ) {
+/*----------------------------------------------------------------------------
+  Find the spread in the dimension in which it is greatest.
+
+  Return as *planeWithLargestP the number of that plane and as *spreadP the
+  spread in that plane.
+-----------------------------------------------------------------------------*/
+    sample * minval;  /* malloc'ed array */
+    sample * maxval;  /* malloc'ed array */
+
+    MALLOCARRAY_NOFAIL(minval, depth);
+    MALLOCARRAY_NOFAIL(maxval, depth);
+
+    findBoxBoundaries(colorfreqtable, depth, boxP->index, boxP->colorCt,
+                      minval, maxval);
+
+    switch (methodForLargest) {
+    case LARGE_NORM:
+        findPlaneWithLargestSpreadByNorm(minval, maxval, depth,
+                                         planeWithLargestP, spreadP);
+        break;
+    case LARGE_LUM:
+        findPlaneWithLargestSpreadByLuminosity(minval, maxval, depth,
+                                               planeWithLargestP, spreadP);
+        break;
     }
-    return retval;
+    free(minval); free(maxval);
+}
+
+
+
+static unsigned int
+freqTotal(tupletable2 const freqtable) {
+
+    unsigned int i;
+    unsigned int sum;
+
+    for (i = 0, sum = 0; i < freqtable.size; ++i)
+        sum += freqtable.table[i]->value;
+
+    return sum;
+}
+
+
+
+static struct BoxVector
+newBoxVector(tupletable2           const colorfreqtable,
+             unsigned int          const capacity,
+             unsigned int          const depth,
+             enum MethodForLargest const methodForLargest) {
+
+    unsigned int const colorCt = colorfreqtable.size;
+    unsigned int const sum     = freqTotal(colorfreqtable);
+
+    struct BoxVector boxVector;
+
+    MALLOCARRAY(boxVector.box, capacity);
+
+    if (!boxVector.box)
+        pm_error("out of memory allocating box vector table");
+
+    /* Set up the initial box. */
+    boxVector.box[0].index   = 0;
+    boxVector.box[0].colorCt = colorCt;
+    boxVector.box[0].sum     = sum;
+
+    computeBoxSpread(&boxVector.box[0], colorfreqtable, depth,
+                     methodForLargest,
+                     &boxVector.box[0].maxdim,
+                     &boxVector.box[0].spread);
+
+    boxVector.boxCt    = 1;
+    boxVector.capacity = capacity;
+
+    return boxVector;
+}
+
+
+
+static void
+destroyBoxVector(struct BoxVector const boxVector) {
+
+    free(boxVector.box);
 }
 
 
@@ -363,6 +520,30 @@ centerBox(int          const boxStart,
 
 
 
+static tupletable2
+newColorMap(unsigned int const colorCt,
+            unsigned int const depth) {
+
+    tupletable2 colormap;
+    unsigned int i;
+    struct pam pam;
+
+    pam.depth = depth;
+
+    colormap.table = pnm_alloctupletable(&pam, colorCt);
+
+    for (i = 0; i < colorCt; ++i) {
+        unsigned int plane;
+        for (plane = 0; plane < depth; ++plane)
+            colormap.table[i]->tuple[plane] = 0;
+    }
+    colormap.size = colorCt;
+
+    return colormap;
+}
+
+
+
 static void
 averageColors(int          const boxStart,
               int          const boxSize,
@@ -422,12 +603,11 @@ averagePixels(int          const boxStart,
 
 
 static tupletable2
-colormapFromBv(unsigned int      const newcolors,
-               boxVector         const bv,
-               unsigned int      const boxes,
+colormapFromBv(unsigned int      const colorCt,
+               struct BoxVector  const boxVector,
                tupletable2       const colorfreqtable,
                unsigned int      const depth,
-               enum methodForRep const methodForRep) {
+               enum MethodForRep const methodForRep) {
     /*
     ** Ok, we've got enough boxes.  Now choose a representative color for
     ** each box.  There are a number of possible ways to make this choice.
@@ -437,23 +617,29 @@ colormapFromBv(unsigned int      const newcolors,
     ** method is to average all the pixels in the box.
     */
     tupletable2 colormap;
-    unsigned int bi;
+    unsigned int boxIdx;
 
-    colormap = newColorMap(newcolors, depth);
+    colormap = newColorMap(colorCt, depth);
 
-    for (bi = 0; bi < boxes; ++bi) {
+    for (boxIdx = 0; boxIdx < boxVector.boxCt; ++boxIdx) {
         switch (methodForRep) {
         case REP_CENTER_BOX:
-            centerBox(bv[bi].ind, bv[bi].colors, colorfreqtable, depth,
-                      colormap.table[bi]->tuple);
+            centerBox(boxVector.box[boxIdx].index,
+                      boxVector.box[boxIdx].colorCt,
+                      colorfreqtable, depth,
+                      colormap.table[boxIdx]->tuple);
             break;
         case REP_AVERAGE_COLORS:
-            averageColors(bv[bi].ind, bv[bi].colors, colorfreqtable, depth,
-                          colormap.table[bi]->tuple);
+            averageColors(boxVector.box[boxIdx].index,
+                          boxVector.box[boxIdx].colorCt,
+                          colorfreqtable, depth,
+                          colormap.table[boxIdx]->tuple);
             break;
         case REP_AVERAGE_PIXELS:
-            averagePixels(bv[bi].ind, bv[bi].colors, colorfreqtable, depth,
-                          colormap.table[bi]->tuple);
+            averagePixels(boxVector.box[boxIdx].index,
+                          boxVector.box[boxIdx].colorCt,
+                          colorfreqtable, depth,
+                          colormap.table[boxIdx]->tuple);
             break;
         default:
             pm_error("Internal error: invalid value of methodForRep: %d",
@@ -465,107 +651,77 @@ colormapFromBv(unsigned int      const newcolors,
 
 
 
-static unsigned int
-freqTotal(tupletable2 const freqtable) {
-
-    unsigned int i;
-    unsigned int sum;
-
-    sum = 0;
-
-    for (i = 0; i < freqtable.size; ++i)
-        sum += freqtable.table[i]->value;
-
-    return sum;
-}
-
-
 static void
-splitBox(boxVector             const bv,
-         unsigned int *        const boxesP,
-         unsigned int          const bi,
+splitBox(struct BoxVector *    const boxVectorP,
+         unsigned int          const boxIdx,
          tupletable2           const colorfreqtable,
          unsigned int          const depth,
-         enum methodForLargest const methodForLargest) {
+         enum MethodForLargest const methodForLargest,
+         enum MethodForSplit   const methodForSplit) {
 /*----------------------------------------------------------------------------
-   Split Box 'bi' in the box vector bv (so that bv contains one more box
-   than it did as input).  Split it so that each new box represents about
-   half of the pixels in the distribution given by 'colorfreqtable' for
-   the colors in the original box, but with distinct colors in each of the
-   two new boxes.
+   Split Box 'boxIdx' in the box vector 'boxVector' (so that bv contains one
+   more box than it did as input).  Split it so that each new box represents
+   about half of the pixels in the distribution given by 'colorfreqtable' for
+   the colors in the original box, but with distinct colors in each of the two
+   new boxes.
 
    Assume the box contains at least two colors.
 -----------------------------------------------------------------------------*/
-    unsigned int const boxStart = bv[bi].ind;
-    unsigned int const boxSize  = bv[bi].colors;
-    unsigned int const sm       = bv[bi].sum;
+    unsigned int const boxStart = boxVectorP->box[boxIdx].index;
+    unsigned int const boxSize  = boxVectorP->box[boxIdx].colorCt;
+    unsigned int const sum      = boxVectorP->box[boxIdx].sum;
 
-    sample * minval;  /* malloc'ed array */
-    sample * maxval;  /* malloc'ed array */
-
-    unsigned int largestDimension;
-        /* number of the plane with the largest spread */
     unsigned int medianIndex;
     int lowersum;
         /* Number of pixels whose value is "less than" the median */
 
-    MALLOCARRAY_NOFAIL(minval, depth);
-    MALLOCARRAY_NOFAIL(maxval, depth);
-
-    findBoxBoundaries(colorfreqtable, depth, boxStart, boxSize,
-                      minval, maxval);
-
-    /* Find the largest dimension, and sort by that component.  I have
-       included two methods for determining the "largest" dimension;
-       first by simply comparing the range in RGB space, and second by
-       transforming into luminosities before the comparison.
-    */
-    switch (methodForLargest) {
-    case LARGE_NORM:
-        largestDimension = largestByNorm(minval, maxval, depth);
-        break;
-    case LARGE_LUM:
-        largestDimension = largestByLuminosity(minval, maxval, depth);
-        break;
-    }
 
-    /* TODO: I think this sort should go after creating a box,
-       not before splitting.  Because you need the sort to use
-       the REP_CENTER_BOX method of choosing a color to
-       represent the final boxes
+    /* Perhaps this sort should go after creating a box, not before splitting.
+       Because you need the sort to use the REP_CENTER_BOX method of choosing
+       a color to represent the final boxes
     */
 
     /* Set the gross global variable 'compareplanePlane' as a
        parameter to compareplane(), which is called by qsort().
     */
-    compareplanePlane = largestDimension;
+    compareplanePlane = boxVectorP->box[boxIdx].maxdim;
     qsort((char*) &colorfreqtable.table[boxStart], boxSize,
           sizeof(colorfreqtable.table[boxStart]),
           compareplane);
 
     {
-        /* Now find the median based on the counts, so that about half
-           the pixels (not colors, pixels) are in each subdivision.  */
-
+        /* Find the median based on the counts, so that about half the pixels
+           (not colors, pixels) are in each subdivision.
+        */
         unsigned int i;
 
         lowersum = colorfreqtable.table[boxStart]->value; /* initial value */
-        for (i = 1; i < boxSize - 1 && lowersum < sm/2; ++i) {
+        for (i = 1; i < boxSize - 1 && lowersum < sum/2; ++i) {
             lowersum += colorfreqtable.table[boxStart + i]->value;
         }
         medianIndex = i;
     }
     /* Split the box, and sort to bring the biggest boxes to the top.  */
+    {
+        struct Box * const oldBoxP = &boxVectorP->box[boxIdx];
 
-    bv[bi].colors = medianIndex;
-    bv[bi].sum = lowersum;
-    bv[*boxesP].ind = boxStart + medianIndex;
-    bv[*boxesP].colors = boxSize - medianIndex;
-    bv[*boxesP].sum = sm - lowersum;
-    ++(*boxesP);
-    qsort((char*) bv, *boxesP, sizeof(struct box), sumcompare);
+        oldBoxP->colorCt = medianIndex;
+        oldBoxP->sum     = lowersum;
+        computeBoxSpread(oldBoxP, colorfreqtable, depth, methodForLargest,
+                         &oldBoxP->maxdim, &oldBoxP->spread);
+    }
+    {
+        struct Box * const newBoxP = &boxVectorP->box[boxVectorP->boxCt];
+
+        newBoxP->index   = boxStart + medianIndex;
+        newBoxP->colorCt = boxSize - medianIndex;
+        newBoxP->sum     = sum - lowersum;
+        computeBoxSpread(newBoxP, colorfreqtable, depth, methodForLargest,
+                         &newBoxP->maxdim, &newBoxP->spread);
+        ++boxVectorP->boxCt;
+    }
 
-    free(minval); free(maxval);
+    sortBoxes(boxVectorP, methodForSplit);
 }
 
 
@@ -573,12 +729,13 @@ splitBox(boxVector             const bv,
 static void
 mediancut(tupletable2           const colorfreqtable,
           unsigned int          const depth,
-          int                   const newcolors,
-          enum methodForLargest const methodForLargest,
-          enum methodForRep     const methodForRep,
+          int                   const newcolorCt,
+          enum MethodForLargest const methodForLargest,
+          enum MethodForRep     const methodForRep,
+          enum MethodForSplit   const methodForSplit,
           tupletable2 *         const colormapP) {
 /*----------------------------------------------------------------------------
-   Compute a set of only 'newcolors' colors that best represent an
+   Compute a set of only 'newcolorCt' colors that best represent an
    image whose pixels are summarized by the histogram
    'colorfreqtable'.  Each tuple in that table has depth 'depth'.
    colorfreqtable.table[i] tells the number of pixels in the subject image
@@ -586,32 +743,36 @@ mediancut(tupletable2           const colorfreqtable,
 
    As a side effect, sort 'colorfreqtable'.
 -----------------------------------------------------------------------------*/
-    boxVector bv;
-    unsigned int bi;
-    unsigned int boxes;
+    struct BoxVector boxVector;
     bool multicolorBoxesExist;
         /* There is at least one box that contains at least 2 colors; ergo,
            there is more splitting we can do.
         */
 
-    bv = newBoxVector(colorfreqtable.size, freqTotal(colorfreqtable),
-                      newcolors);
-    boxes = 1;
+    boxVector = newBoxVector(colorfreqtable, newcolorCt, depth,
+                             methodForLargest);
+
     multicolorBoxesExist = (colorfreqtable.size > 1);
 
-    /* Main loop: split boxes until we have enough. */
-    while (boxes < newcolors && multicolorBoxesExist) {
-        /* Find the first splittable box. */
-        for (bi = 0; bi < boxes && bv[bi].colors < 2; ++bi);
-        if (bi >= boxes)
+    /* Split boxes until we have enough. */
+    while (boxVector.boxCt < newcolorCt && multicolorBoxesExist) {
+        unsigned int boxIdx;
+
+        for (boxIdx = 0;
+             boxIdx < boxVector.boxCt && boxVector.box[boxIdx].colorCt < 2;
+             ++boxIdx);
+            /* Find the first splittable box. */
+
+        if (boxIdx >= boxVector.boxCt)
             multicolorBoxesExist = FALSE;
         else
-            splitBox(bv, &boxes, bi, colorfreqtable, depth, methodForLargest);
+            splitBox(&boxVector, boxIdx, colorfreqtable, depth,
+                     methodForLargest, methodForSplit);
     }
-    *colormapP = colormapFromBv(newcolors, bv, boxes, colorfreqtable, depth,
-                                methodForRep);
+    *colormapP = colormapFromBv(newcolorCt, boxVector, colorfreqtable,
+                                depth, methodForRep);
 
-    free(bv);
+    destroyBoxVector(boxVector);
 }
 
 
@@ -739,8 +900,9 @@ static void
 computeColorMapFromInput(FILE *                const ifP,
                          bool                  const allColors,
                          int                   const reqColors,
-                         enum methodForLargest const methodForLargest,
-                         enum methodForRep     const methodForRep,
+                         enum MethodForLargest const methodForLargest,
+                         enum MethodForRep     const methodForRep,
+                         enum MethodForSplit   const methodForSplit,
                          int *                 const formatP,
                          struct pam *          const freqPamP,
                          tupletable2 *         const colormapP) {
@@ -778,7 +940,7 @@ computeColorMapFromInput(FILE *                const ifP,
             pm_message("choosing %d colors...", reqColors);
             mediancut(colorfreqtable, freqPamP->depth,
                       reqColors, methodForLargest, methodForRep,
-                      colormapP);
+                      methodForSplit, colormapP);
             pnm_freetupletable2(freqPamP, colorfreqtable);
         }
     }
@@ -933,9 +1095,9 @@ colormapToImage(int                const format,
 
 
 int
-main(int argc, char * argv[] ) {
+main(int argc, const char * argv[] ) {
 
-    struct cmdlineInfo cmdline;
+    struct CmdlineInfo cmdline;
     FILE * ifP;
     int format;
     struct pam colormapPam;
@@ -943,16 +1105,17 @@ main(int argc, char * argv[] ) {
     tuple ** colormapRaster;
     tupletable2 colormap;
 
-    pnm_init(&argc, argv);
+    pm_proginit(&argc, argv);
 
     parseCommandLine(argc, argv, &cmdline);
 
-    ifP = pm_openr(cmdline.inputFilespec);
+    ifP = pm_openr(cmdline.inputFileNm);
 
     computeColorMapFromInput(ifP,
                              cmdline.allcolors, cmdline.newcolors,
                              cmdline.methodForLargest,
                              cmdline.methodForRep,
+                             cmdline.methodForSplit,
                              &format, &colormapPam, &colormap);
 
     pm_close(ifP);
diff --git a/test/Test-Order b/test/Test-Order
index e9ea1b55..2548e501 100644
--- a/test/Test-Order
+++ b/test/Test-Order
@@ -42,6 +42,8 @@ pamsumm.test
 pnmpsnr.test
 pbmminkowski.test
 
+pnmcolormap.test
+
 # Basic (internal) converter tests
 
 pamtopam.test
@@ -70,6 +72,7 @@ pnmpaste-pbm.test
 pbmpscale.test
 pnmremap1.test
 pnmremap2.test
+pnmquant.test
 pnmquantall.test
 pnmtile.test
 ppmbrighten.test
@@ -191,5 +194,6 @@ xwd-roundtrip.test
 
 fiasco-roundtrip.test
 jpeg-roundtrip.test
+lps-roundtrip.test
 tiffcmyk-roundtrip.test
 yuv-roundtrip.test
diff --git a/test/lps-roundtrip.ok b/test/lps-roundtrip.ok
new file mode 100644
index 00000000..02b1d1a9
--- /dev/null
+++ b/test/lps-roundtrip.ok
@@ -0,0 +1 @@
+match
diff --git a/test/lps-roundtrip.test b/test/lps-roundtrip.test
new file mode 100755
index 00000000..f30062a8
--- /dev/null
+++ b/test/lps-roundtrip.test
@@ -0,0 +1,22 @@
+#! /bin/bash
+# This script tests: pbmtolps pstopnm
+# Also requires: gs pamdepth pamscale pnmcrop pnmpsnr
+
+# The ordinary round-trip does not work because of the way ghostscript
+# renders: a line is considered wider than a single pixel and all pixels
+# it touches are set to black if the output is PBM.  To work around this,
+# we tell pstopnm to output PGM at a high resolution (=large dpi value).
+
+
+test_pgm=${tmpdir}/testgrid.pgm
+
+pamdepth 255 testgrid.pbm > ${test_pgm}
+
+pbmtolps -dpi 72 testgrid.pbm | \
+    pstopnm -dpi $((72*12)) -stdout -pgm | \
+    pnmcrop -white | pamscale -xsize=14 -ysize=16 | \
+    pnmpsnr -target=30 - ${test_pgm}
+
+# ghostscript version 8.71: pnmpsnr lumina 33.14dB
+
+rm ${test_pgm}
diff --git a/test/pamditherbw.ok b/test/pamditherbw.ok
index eba3c44c..156b9f07 100644
--- a/test/pamditherbw.ok
+++ b/test/pamditherbw.ok
@@ -15,14 +15,14 @@ Test: Cluster-4
 Test: Cluster-8
 3493215477 33894
 Test: Invalid
-Expected failure 1
-Expected failure 2
-Expected failure 3
-Expected failure 4
-Expected failure 5
-Expected failure 6
-Expected failure 7
-Expected failure 8
-Expected failure 9
-Expected failure 10
-Expected failure 11
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
+Expected failure 5 1
+Expected failure 6 1
+Expected failure 7 1
+Expected failure 8 1
+Expected failure 9 1
+Expected failure 10 1
+Expected failure 11 1
diff --git a/test/pamditherbw.test b/test/pamditherbw.test
index 7b646a88..76e175d7 100755
--- a/test/pamditherbw.test
+++ b/test/pamditherbw.test
@@ -40,21 +40,34 @@ pamditherbw -cluster8 ${test_red} | cksum
 
 echo "Test: Invalid"
 
+test_out=${tmpdir}/test_out
+
 echo 1>&2
 echo "Invalid command-line argument combinations." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-pamditherbw -fs -atkinson       ${test_red} || echo "Expected failure 1"
-pamditherbw -floyd -atkinson    ${test_red} || echo "Expected failure 2"
-pamditherbw -dither8  -cluster3 ${test_red} || echo "Expected failure 3"
-pamditherbw -cluster3 -cluster4 ${test_red} || echo "Expected failure 4"
-pamditherbw -cluster3 -cluster8 ${test_red} || echo "Expected failure 5"
-pamditherbw -cluster4 -cluster8 ${test_red} || echo "Expected failure 6"
-pamditherbw -clump=8            ${test_red} || echo "Expected failure 7"
-pamditherbw -fs -clump=8        ${test_red} || echo "Expected failure 8"
-pamditherbw -hilbert -clump=1   ${test_red} || echo "Expected failure 9"
-pamditherbw -th -value=-1       ${test_red} || echo "Expected failure 10"
-pamditherbw -th -value=1.1      ${test_red} || echo "Expected failure 11"
-
-rm ${test_red}
\ No newline at end of file
+pamditherbw -fs -atkinson       ${test_red} > ${test_out} || \
+ echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+pamditherbw -floyd -atkinson    ${test_red} > ${test_out} || \
+ echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+pamditherbw -dither8  -cluster3 ${test_red} > ${test_out} || \
+ echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+pamditherbw -cluster3 -cluster4 ${test_red} > ${test_out} || \
+ echo -n "Expected failure 4"; test -s ${test_out}; echo " "$?
+pamditherbw -cluster3 -cluster8 ${test_red} > ${test_out} || \
+ echo -n "Expected failure 5"; test -s ${test_out}; echo " "$?
+pamditherbw -cluster4 -cluster8 ${test_red} > ${test_out} || \
+ echo -n "Expected failure 6"; test -s ${test_out}; echo " "$?
+pamditherbw -clump=8            ${test_red} > ${test_out} || \
+ echo -n "Expected failure 7"; test -s ${test_out}; echo " "$?
+pamditherbw -fs -clump=8        ${test_red} > ${test_out} || \
+ echo -n "Expected failure 8"; test -s ${test_out}; echo " "$?
+pamditherbw -hilbert -clump=1   ${test_red} > ${test_out} || \
+ echo -n "Expected failure 9"; test -s ${test_out}; echo " "$?
+pamditherbw -th -value=-1       ${test_red} > ${test_out} || \
+ echo -n "Expected failure 10"; test -s ${test_out}; echo " "$?
+pamditherbw -th -value=1.1      ${test_red} > ${test_out} || \
+ echo -n "Expected failure 11"; test -s ${test_out}; echo " "$?
+
+rm ${test_red} ${test_out}
diff --git a/test/pamfile.ok b/test/pamfile.ok
index b1d68ae1..e222592c 100644
--- a/test/pamfile.ok
+++ b/test/pamfile.ok
@@ -13,7 +13,7 @@ Test 3
 227 149
 testimg.ppm: PPM RAW 227 149 3 255 RGB
 stdin: PBM RAW 14 16 1 1 BLACKANDWHITE
-Test 4
-Expected failure 1
-Expected failure 2
-Expected failure 3
+Test Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
diff --git a/test/pamfile.test b/test/pamfile.test
index 32771bfe..aa3e2895 100755
--- a/test/pamfile.test
+++ b/test/pamfile.test
@@ -20,13 +20,21 @@ pamfile -size testimg.ppm
 pamfile -machine testimg.ppm
 cat testgrid.pbm testimg.ppm testgrid.pbm | pamfile -machine
 
-echo "Test 4"
+echo "Test Invalid"
+
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
 
 echo 1>&2
 echo "Invalid command-line argument combinations." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-pamfile -size -machine  testimg.ppm || echo "Expected failure 1"
-pamfile -count -machine testimg.ppm || echo "Expected failure 2"
-head -n1 testimg.ppm | pamfile || echo "Expected failure 3"
\ No newline at end of file
+pamfile -size -machine  testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+pamfile -count -machine testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+head -n1 testimg.ppm | pamfile > ${test_out} || \
+  echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/pamfind.ok b/test/pamfind.ok
index 9ddddced..de53166e 100644
--- a/test/pamfind.ok
+++ b/test/pamfind.ok
@@ -257,5 +257,8 @@ Locations containing tuple (1)/1:
 Test 3
 okay
 okay
-Test 4
-expected error
+Test Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
diff --git a/test/pamfind.test b/test/pamfind.test
index e55f290c..3b4ffb81 100755
--- a/test/pamfind.test
+++ b/test/pamfind.test
@@ -7,19 +7,19 @@ sorted0_res=${tmpdir}/pamfind_sorted0.res
 sorted1_res=${tmpdir}/pamfind_sorted1.res
 
 # Test 1
-echo Test 1
+echo "Test 1"
 pamfind -color=grey17     testimg.ppm 
 pamfind -target=210,57,41 testimg.ppm
 pamfind -target=50,55,49 -machine testimg.ppm
 
 # Test 2
-echo Test 2
+echo "Test 2"
 pamfind -target=1 testgrid.pbm
 pamfind -target=0 -machine testgrid.pbm
 
 # Test 3
 # The two outputs should be disjoint
-echo Test 3
+echo "Test 3"
 pamfind -target=0 testgrid.pbm | sort > ${sorted0_res}
 pamfind -target=1 testgrid.pbm | sort > ${sorted1_res}
 comm -3 ${sorted0_res}  ${sorted1_res}  |
@@ -33,11 +33,23 @@ rm ${sorted0_res} ${sorted1_res}
 
 # Test 4
 
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
+
 echo 1>&2
 echo "Invalid command-line argument combination." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-echo Test 4
-pamfind -color=black -target=1 testimg.ppm || \
-  echo expected error
+echo "Test Invalid"
+
+pamfind -color=black -target=1,1,1 testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+pamfind -target=0,0 testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+pamfind -target=0,0,0,0 testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+pamfind testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 4"; test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/pamgauss.ok b/test/pamgauss.ok
index eaef2570..e31a2ee8 100644
--- a/test/pamgauss.ok
+++ b/test/pamgauss.ok
@@ -83,9 +83,9 @@ Test 1
 Test 2
 stdin:	PAM, 3 by 3 by 1 maxval 255
     Tuple type: GRAYSCALE
-Test 3.
-Expected error 1
-Expected error 2
-Expected error 3
-Expected error 4
-Expected error 5
+Test Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
+Expected failure 5 1
diff --git a/test/pamgauss.test b/test/pamgauss.test
index 392b5179..bb006ce9 100755
--- a/test/pamgauss.test
+++ b/test/pamgauss.test
@@ -17,15 +17,25 @@ echo "Test 2"
 pamgauss 3 3 -sigma=0.5 -tupletype="GRAYSCALE" | pamfile
 
 
-echo "Test 3."
+echo "Test Invalid"
 
 echo 1>&2
 echo "Invalid command-line argument combinations." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-pamgauss 3 3               | echo "Expected error 1"
-pamgauss 3 3   -sigma=0    | echo "Expected error 2"
-pamgauss 3 3   -sigma=-1.5 | echo "Expected error 3"
-pamgauss 3     -sigma=0.5  | echo "Expected error 4"
-pamgauss 3 3 3 -sigma=0.5  | echo "Expected error 5"
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
+
+pamgauss 3 3               > ${test_out} || \
+   echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+pamgauss 3 3   -sigma=0    > ${test_out} || \
+   echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+pamgauss 3 3   -sigma=-1.5 > ${test_out} || \
+   echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+pamgauss 3     -sigma=0.5  > ${test_out} || \
+   echo -n "Expected failure 4"; test -s ${test_out}; echo " "$?
+pamgauss 3 3 3 -sigma=0.5  > ${test_out} || \
+   echo -n "Expected failure 5"; test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/pamhue.ok b/test/pamhue.ok
index 447759ba..dbef973d 100644
--- a/test/pamhue.ok
+++ b/test/pamhue.ok
@@ -5,21 +5,21 @@
  ----- ----- ----- 	-----	------- 
      0     0     0	    0	      1 
      0     0   255	   29	      1 
-   255   255     0	  226	      1 
-   255   255   255	  255	      1 
      0   255     0	  150	      1 
      0   255   255	  179	      1 
    255     0     0	   76	      1 
    255     0   255	  105	      1 
+   255   255     0	  226	      1 
+   255   255   255	  255	      1 
  Summary: 8 colors: 1 black, 1 white, 0 gray, 6 color
 
    r     g     b   	 lum 	 count  
  ----- ----- ----- 	-----	------- 
      0     0     0	    0	      1 
      0     0   255	   29	      1 
-   255   255     0	  226	      1 
-   255   255   255	  255	      1 
      0   255     0	  150	      1 
      0   255   255	  179	      1 
    255     0     0	   76	      1 
    255     0   255	  105	      1 
+   255   255     0	  226	      1 
+   255   255   255	  255	      1 
diff --git a/test/pamhue.test b/test/pamhue.test
index 544b1d32..18240959 100755
--- a/test/pamhue.test
+++ b/test/pamhue.test
@@ -4,7 +4,7 @@
 
 pamseq -tupletype=RGB 3 1 | pamdepth 255 | pamhue -huechange=60 | cksum
 
-pamseq -tupletype=RGB 3 1 | pamdepth 255 | ppmhist
-pamseq -tupletype=RGB 3 1 | pamdepth 255 | pamhue -huechange=60 | ppmhist
+pamseq -tupletype=RGB 3 1 | pamdepth 255 | ppmhist -sort=rgb
+pamseq -tupletype=RGB 3 1 | pamdepth 255 | pamhue -huechange=60 | ppmhist -sort=rgb
 
 
diff --git a/test/pamscale-reportonly.ok b/test/pamscale-reportonly.ok
index 00152411..bf5cde99 100644
--- a/test/pamscale-reportonly.ok
+++ b/test/pamscale-reportonly.ok
@@ -1,3 +1,4 @@
+Test 1
 227 149 3.000000 3.000000 681 447
 227 149 5.000000 5.000000 1135 745
 227 149 2.682819 2.684564 609 400
@@ -10,9 +11,10 @@
 227 149 2.819383 2.000000 640 298
 227 149 1.400881 2.684564 318 400
 227 149 1.000000 1.000000 227 149
-expected error
-expected error
-expected error
-expected error
-expected error
-expected error
+Test Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
+Expected failure 5 1
+Expected failure 6 1
diff --git a/test/pamscale-reportonly.test b/test/pamscale-reportonly.test
index 7205be2f..45a38687 100755
--- a/test/pamscale-reportonly.test
+++ b/test/pamscale-reportonly.test
@@ -2,6 +2,8 @@
 # This script tests: pamscale
 # Also requires:
 
+echo "Test 1"
+
 pamscale -reportonly 3 testimg.ppm
 pamscale -reportonly 5 testimg.ppm
 pamscale -reportonly -xysize 640 400 testimg.ppm
@@ -15,21 +17,35 @@ pamscale -reportonly -width=640 -yscale=2 testimg.ppm
 pamscale -reportonly -xscale=1.4 -height=400 testimg.ppm
 pamscale -reportonly -pixels=45000 testimg.ppm
 
-# expected error cases
+echo "Test Invalid"
+
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
+
+# Expected failure cases
+
 echo 1>&2
 echo "Invalid command-line argument combinations." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
-pamscale -reportonly -xsize=640 -ysize=400 -xscale=2 testimg.ppm || \
-  echo expected error
-pamscale -reportonly -xsize=640 -xscale=2 -yscale=3 testimg.ppm || \
-  echo expected error
-pamscale -reportonly -xsize=640 -ysize=400 -pixels=200000 testimg.ppm || \
-  echo expected error
-pamscale -reportonly -xsize=640 -ysize=400 -xysize 640 400 testimg.ppm || \
-  echo expected error
-pamscale -reportonly -xsize=640 -ysize=400 -xyfit  640 400 testimg.ppm || \
-  echo expected error
-pamscale -reportonly -xsize=640 -ysize=400 -xyfill 640 400 testimg.ppm || \
-  echo expected error
 
+pamscale -reportonly -xsize=640 -ysize=400 -xscale=2 testimg.ppm > \
+  ${test_out} \
+  || echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+pamscale -reportonly -xsize=640 -xscale=2 -yscale=3 testimg.ppm > \
+  ${test_out} \
+  || echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+pamscale -reportonly -xsize=640 -ysize=400 -pixels=200000 testimg.ppm \
+  > ${test_out} || \
+  echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+pamscale -reportonly -xsize=640 -ysize=400 -xysize 640 400 testimg.ppm \
+  > ${test_out} || \
+  echo -n "Expected failure 4"; test -s ${test_out}; echo " "$?
+pamscale -reportonly -xsize=640 -ysize=400 -xyfit  640 400 testimg.ppm \
+  > ${test_out} || \
+  echo -n "Expected failure 5"; test -s ${test_out}; echo " "$?
+pamscale -reportonly -xsize=640 -ysize=400 -xyfill 640 400 testimg.ppm \
+  > ${test_out} || \
+  echo -n "Expected failure 6"; test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/pamseq.ok b/test/pamseq.ok
index b0455449..654596fb 100644
--- a/test/pamseq.ok
+++ b/test/pamseq.ok
@@ -1,7 +1,7 @@
 Test 1
 3929266994 304
-Test 2
-Expected error 1
-Expected error 2
-Expected error 3
-Expected error 4
+Test Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
diff --git a/test/pamseq.test b/test/pamseq.test
index ea19013b..0681d396 100755
--- a/test/pamseq.test
+++ b/test/pamseq.test
@@ -6,20 +6,29 @@ echo "Test 1"
 
 pamseq 1 255 | cksum
 
-echo "Test 2"
+echo "Test Invalid"
 
 echo 1>&2
 echo "Invalid command-line argument combinations." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-pamseq 1 || echo "Expected error 1"
-pamseq 0 255 || echo "Expected error 2"
-pamseq 3 0   || echo "Expected error 3"
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
+
+pamseq 1 > ${test_out} || \
+   echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+pamseq 0 255 > ${test_out} || \
+   echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+pamseq 3 0   > ${test_out} || \
+   echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
 
 c64="0123456789012345678901234567890123456789012345678901234567890123"
 c256=${c64}${c64}${c64}${c64}
 
 # Tupletype string length=256
 
-pamseq -tupletype="${c256}" 3 15 || echo "Expected error 4"
+pamseq -tupletype="${c256}" 3 15 > ${test_out} || \
+   echo -n "Expected failure 4"; test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/pamsumm.ok b/test/pamsumm.ok
index 24ae23d2..63b5f6bd 100644
--- a/test/pamsumm.ok
+++ b/test/pamsumm.ok
@@ -8,8 +8,8 @@ Test 2
 15
 255
 106.164760
-Test 3
-Expected failure 1
-Expected failure 2
-the mean of all samples is 106.164760
-Expected failure 4
+Test Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
diff --git a/test/pamsumm.test b/test/pamsumm.test
index 882b1b14..5b4fdb17 100755
--- a/test/pamsumm.test
+++ b/test/pamsumm.test
@@ -17,14 +17,23 @@ for type in -sum -min -max -mean
   done
 
 
-echo "Test 3"
+echo "Test Invalid"
+
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
 
 echo 1>&2
 echo "Invalid command-line argument combinations." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-pamsumm -sum -min  testimg.ppm || echo "Expected failure 1"
-pamsumm -sum -max  testimg.ppm || echo "Expected failure 2"
-pamsumm -mean -max testimg.ppm || echo "Expected failure 3"
-pamsumm            testimg.ppm || echo "Expected failure 4"
+pamsumm -sum -min  testimg.ppm > ${test_out} || \
+   echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+pamsumm -sum -max  testimg.ppm > ${test_out} || \
+   echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+pamsumm -mean -max testimg.ppm > ${test_out} || \
+   echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+pamsumm            testimg.ppm > ${test_out} || \
+   echo -n "Expected failure 4"; test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/pbmmake.ok b/test/pbmmake.ok
index 354106f0..e39f4cf8 100644
--- a/test/pbmmake.ok
+++ b/test/pbmmake.ok
@@ -1,36 +1,29 @@
-Test 1.
+Test 1
 P11 10
 P11 11
 P11 10
-Test 2.
 P12 20000
 P12 21111
 P12 20110
-Test 2.
 P13 3000000000
 P13 3111111111
 P13 3010101010
-Test 2.
 P14 40000000000000000
 P14 41111111111111111
 P14 40101101001011010
-Test 2.
 P15 50000000000000000000000000
 P15 51111111111111111111111111
 P15 50101010101010101010101010
-Test 2.
 P16 6000000000000000000000000000000000000
 P16 6111111111111111111111111111111111111
 P16 6010101101010010101101010010101101010
-Test 2.
 P17 70000000000000000000000000000000000000000000000000
 P17 71111111111111111111111111111111111111111111111111
 P17 70101010101010101010101010101010101010101010101010
-Test 2.
 P18 80000000000000000000000000000000000000000000000000000000000000000
 P18 81111111111111111111111111111111111111111111111111111111111111111
 P18 80101010110101010010101011010101001010101101010100101010110101010
-Test 2.
+Test 2
 4058563256 45
 3969089344 105
 702117756 189
@@ -50,15 +43,12 @@ Test 2.
 1824232358 2931
 3651864954 3375
 3302595397 3849
-Test 3.
-Expected error 1
-Expected error 2
-Expected error 3
-Expected error 4
-Expected error 5
-Expected error 6
-Expected error 7
-Expected error 8
-P1
-1 1
-0
+Test Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
+Expected failure 5 1
+Expected failure 6 1
+Expected failure 7 1
+Expected failure 8 1
diff --git a/test/pbmmake.test b/test/pbmmake.test
index eb4be6ea..3f815617 100755
--- a/test/pbmmake.test
+++ b/test/pbmmake.test
@@ -2,7 +2,7 @@
 # This script tests: pbmmake
 # Also requires:
 
-echo "Test 1."
+echo "Test 1"
 
 for i in `seq 1 8`
 do
@@ -10,10 +10,10 @@ for color in -white -black -gray
 do
 pbmmake -plain $color $i $i | tr -d '\n'; echo
 done
+done
 
-echo "Test 2."
+echo "Test 2"
 
-done
 for i in `seq 8 5 98`
 do
  ( pbmmake -w $i $i ;
@@ -21,19 +21,31 @@ do
   pbmmake  -g $i $i ) | cksum
 done
 
-echo "Test 3."
+echo "Test Invalid"
 
 echo 1>&2
 echo "Invalid command-line argument combinations." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-pbmmake -b -w -plain 1 1 || echo "Expected error 1"
-pbmmake -b -g -plain 1 1 || echo "Expected error 2"
-pbmmake -white -gray -plain 1 1 || echo "Expected error 3"
-pbmmake -white -plain   || echo "Expected error 4"
-pbmmake -white -plain 1 || echo "Expected error 5"
-pbmmake -white -plain 1 0 || echo "Expected error 6"
-pbmmake -white -plain 0 1 || echo "Expected error 7"
-pbmmake -white -plain 1 1 1 || echo "Expected error 8"
-pbmmake -plain 1 1 ||  echo "Expected error 9"
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
+
+pbmmake -b -w -plain 1 1 > ${test_out} || \
+   echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+pbmmake -b -g -plain 1 1 > ${test_out} || \
+   echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+pbmmake -white -gray -plain 1 1 > ${test_out} || \
+   echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+pbmmake -white -plain   > ${test_out} || \
+   echo -n "Expected failure 4"; test -s ${test_out}; echo " "$?
+pbmmake -white -plain 1 > ${test_out} || \
+   echo -n "Expected failure 5"; test -s ${test_out}; echo " "$?
+pbmmake -white -plain 1 0 > ${test_out} || \
+   echo -n "Expected failure 6"; test -s ${test_out}; echo " "$?
+pbmmake -white -plain 0 1 > ${test_out} || \
+   echo -n "Expected failure 7"; test -s ${test_out}; echo " "$?
+pbmmake -white -plain 1 1 1 > ${test_out} || \
+   echo -n "Expected failure 8"; test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/pbmpage.ok b/test/pbmpage.ok
index b41d7cf3..8013f2f2 100644
--- a/test/pbmpage.ok
+++ b/test/pbmpage.ok
@@ -3,7 +3,7 @@ Test 1
 4142746975 4210813
 2347597649 4210813
 3453559794 4349933
-Test 2
-Expected error 1
-Expected error 2
-Expected error 3
+Test Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
diff --git a/test/pbmpage.test b/test/pbmpage.test
index 7cabcc7f..50570e3e 100755
--- a/test/pbmpage.test
+++ b/test/pbmpage.test
@@ -9,13 +9,21 @@ pbmpage 2     | cksum
 pbmpage 3     | cksum
 pbmpage -a4 2 | cksum
 
-echo "Test 2"
+echo "Test Invalid"
 
 echo 1>&2
 echo "Invalid command-line argument combinations." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-pbmpage -a3 1 || echo "Expected error 1"
-pbmpage 0 || echo "Expected error 2"
-pbmpage 4 || echo "Expected error 3"
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
+
+pbmpage -a3 1 > ${test_out} || \
+   echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+pbmpage 0 > ${test_out} || \
+   echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+pbmpage 4 > ${test_out} || \
+   echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/pbmtext-bdf.ok b/test/pbmtext-bdf.ok
index b1486493..eab8a4bd 100644
--- a/test/pbmtext-bdf.ok
+++ b/test/pbmtext-bdf.ok
@@ -1,4 +1,6 @@
+Test 1
 386826492 35
+Test 2
 1
 1
 1
@@ -17,5 +19,6 @@
 1
 1
 1
+Test 3
 0
 0
diff --git a/test/pbmtext-bdf.test b/test/pbmtext-bdf.test
index 50df7b75..b12c10bf 100755
--- a/test/pbmtext-bdf.test
+++ b/test/pbmtext-bdf.test
@@ -65,8 +65,10 @@ EOF
 
 # Test 1
 # This should succeed and produce 386826492 35
-pbmtext -font ${font_bdf} ABC | cksum
 
+echo "Test 1"
+
+pbmtext -font ${font_bdf} ABC | cksum
 
 # Test 2
 # These should all fail.  Writes 1 eightteen times.
@@ -75,6 +77,8 @@ echo "Test whether corrupted BDF font files are properly handled." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
+echo "Test 2"
+
 pbmtext -font ${font_bdf} BCD
 echo $?
 
@@ -154,10 +158,12 @@ for delete_line in 14 16 18 20
   done
 
 
-# Test 2
+# Test 3
 # These should succeed.  Warning messages will be displayed.
 # Writes 1 two times.
 
+echo "Test 3"
+
 for token in "CHARSET_ENCODING" "CHARSET_REGISTRY"
 do
   font_corrupt_bdf=${font_corrupt}.naked_${token}.bdf
diff --git a/test/pbmtext-iso88591.ok b/test/pbmtext-iso88591.ok
index 6cc1a856..b48fb277 100644
--- a/test/pbmtext-iso88591.ok
+++ b/test/pbmtext-iso88591.ok
@@ -1,4 +1,6 @@
+Test 1
 3806607098 5110
 3806607098 5110
+Test 2
 2858870527 192
 2858870527 192
diff --git a/test/pbmtext-iso88591.test b/test/pbmtext-iso88591.test
index bc5e83ab..96b286ac 100755
--- a/test/pbmtext-iso88591.test
+++ b/test/pbmtext-iso88591.test
@@ -2,45 +2,76 @@
 # This script tests: pbmtext
 # Also requires:
 
-# This test requires the following locale:
-#   LC_ALL en_US.iso88591
-# Skip this test if it is not available
+# This test requires the iconv command and an iso-8859-1 locale
+# Skip this test if they are not available
+
+LANG=C
+LC_ALL=C
+export LANG LC_ALL
 
 iconv /dev/null
 if [ $? -ne 0  ]
   then echo "iconv command not available." 1>&2
        echo "Skipping." 1>&2
-  exit 80;
+       exit 80;
 fi
 
-echo "A" | LC_ALL=en_US.iso88591 pbmtext -wchar > /dev/null
-if [ $? -ne 0  ]
-  then echo "LC_ALL could not be set to en_US.iso88591" 1>&2
+tmpdir=${tmpdir:-/tmp}
+iso88591_locale_list=${tmpdir}/iso88591_locale_list
+
+
+locale_to_test="en_US.iso88591"  # Initial value
+# Edit the above value if necessary
+  
+# Make a list of available locales which end in "iso88591"
+locale -a | grep "\.iso88591$" > ${iso88591_locale_list}
+
+# Hunt for a valid iso-8859-1 locale  
+# Submit each candidate to a trial pbmtext run until one that works is
+# encountered
+
+i=0
+until [ -z ${locale_to_test} ] || \
+  echo "A" | LC_ALL=${locale_to_test} pbmtext -wchar > /dev/null
+  do
+    let i=$(($i+1));
+    locale_to_test=`sed "$i"p -n  ${iso88591_locale_list}`;
+  done;
+
+rm ${iso88591_locale_list};
+if [ -z  ${locale_to_test} ]
+  then echo "No iso-8859-1 locale available." 1>&2
        echo "Skipping." 1>&2
-  exit 80;
-fi
+       exit 80;
+else
+       echo "Testing with locale set to ${locale_to_test}" 1>&2
+fi;
+
+locale_for_test=${locale_to_test};
+
 
 # Two rows
 # Should print 3806607098 5110 twice
-LC_ALL=C \
+
+echo "Test 1"
+
 awk 'BEGIN { for (i=32; i<=126;++i) printf("%c",i); print ""; \
              for (i=160;i<=255;++i) printf("%c",i); }' | \
     pbmtext -builtin bdf | cksum
 
-
-LC_ALL=C \
 awk 'BEGIN { for (i=32; i<=126;++i) printf("%c",i); print ""; \
              for (i=160;i<=255;++i) printf("%c",i); }' | \
-    LC_ALL=en_US.iso88591 pbmtext -builtin bdf -wchar | cksum
+    LC_ALL=${locale_for_test} pbmtext -builtin bdf -wchar | cksum
 
 
 # Two rows
 # Should print 2858870527 192 twice
-LC_ALL=C \
+
+echo "Test 2"
+
 awk 'BEGIN { for (i=32; i<=126;++i) printf("%c",i); print ""; \
              for (i=161;i<=255;++i) printf("%c",i); print "" }' | cksum
 
-LC_ALL=C \
 awk 'BEGIN { for (i=32; i<=126;++i) printf("%c",i); print ""; \
              for (i=161;i<=255;++i) printf("%c",i); print ""}' | \
-    LC_ALL=en_US.iso88591 pbmtext -builtin bdf -wchar -text-dump | cksum
\ No newline at end of file
+    LC_ALL=${locale_for_test} pbmtext -builtin bdf -wchar -text-dump | cksum
diff --git a/test/pbmtext-utf8.ok b/test/pbmtext-utf8.ok
index 588bf617..4bc7b00d 100644
--- a/test/pbmtext-utf8.ok
+++ b/test/pbmtext-utf8.ok
@@ -1,8 +1,24 @@
+Test 1
 2066913605 5110
 2066913605 5110
+Test 2
 2920616515 2301
 2920616515 2301
+Test 3
 0 0 0 0 : 0
+Test 4
  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
-0 1 : 1
+Test 5 Invalid
+9998
+989454365 52512
+9999
+Expected failure 1 1
+Expected failure 2 1
+Test 6 Invalid
+6-1: 0 1 : 1 1
+6-2: 0 1 : 1 1
+6-3: 0 1 : 1 1
+6-4: 0 1 : 1 1
+6-5: 0 1 : 1 1
+6-6: 0 1 : 1 1
diff --git a/test/pbmtext-utf8.test b/test/pbmtext-utf8.test
index cf495b7c..c92dd38a 100755
--- a/test/pbmtext-utf8.test
+++ b/test/pbmtext-utf8.test
@@ -2,68 +2,100 @@
 # This script tests: pbmtext
 # Also requires:
 
-# This test requires the en_US.utf8 locale
-# Skip this test if it is not available
+LANG=C
+LC_ALL=C
+export LANG LC_ALL
+
+
+# This test requires the iconv command and a working UTF-8 locale 
+# Skip this test if they are not available
 
 iconv /dev/null
 if [ $? -ne 0  ]
   then echo "iconv command not available." 1>&2
        echo "Skipping." 1>&2
-  exit 80;
+       exit 80;
 fi
 
-echo "A" | LC_ALL=en_US.utf8 pbmtext -wchar > /dev/null
-if [ $? -ne 0  ]
-  then echo "LC_ALL could not be set to en_US.utf8." 1>&2
+tmpdir=${tmpdir:-/tmp}
+utf_locale_list=${tmpdir}/utf_locale_list
+
+locale_to_test="en_US.utf8"  # Initial value
+# Edit the above value if necessary
+  
+# Make a list of available locales which end in "utf8"
+locale -a | grep "\.utf8$" > ${utf_locale_list}
+
+# Hunt for a valid utf8 locale  
+# Submit each candidate to a trial pbmtext run until one that works is
+# encountered
+
+i=0
+until [ -z ${locale_to_test} ] || \
+  echo "A" | LC_ALL=${locale_to_test} pbmtext -wchar > /dev/null
+    do
+      let i=$(($i+1));
+      locale_to_test=`sed "$i"p -n  ${utf_locale_list}`;
+    done;
+
+rm ${utf_locale_list};
+if [ -z  ${locale_to_test} ]
+  then echo "No utf-8 locale available." 1>&2
        echo "Skipping." 1>&2
-  exit 80;
-fi
+       exit 80;
+  else
+       echo "Testing with locale set to ${locale_to_test}" 1>&2
+fi;
+
+locale_for_test=${locale_to_test}
+
 
 # Test 1.
 # Two rows
 # Should print 2066913605 5110 twice
-LC_ALL=C \
+
+echo "Test 1"
+
 awk 'BEGIN { for (i=32; i<=126;++i) printf("%c",i); print ""; \
              for (i=161;i<=255;++i) printf("%c",i); }' | \
     pbmtext -builtin bdf | cksum
 
-LC_ALL=C \
 awk 'BEGIN { for (i=32; i<=126;++i) printf("%c",i); print ""; \
              for (i=161;i<=255;++i) printf("%c",i);  }' | \
     iconv -f iso8859-1 -t utf-8 | \
-    LC_ALL=en_US.utf8 pbmtext -builtin bdf -wchar | cksum
+    LC_ALL=${locale_for_test} pbmtext -builtin bdf -wchar | cksum
 
 
 # Test 2.
 # One row
 # Should print 2920616515 2301 twice
-LC_ALL=C \
+
+echo "Test 2"
+
 awk 'BEGIN { for (i=32; i<=126;++i) printf("%c",i); print "" }' | \
     pbmtext -builtin bdf | cksum
 
-LC_ALL=C \
 awk 'BEGIN { for (i=32; i<=126;++i) printf("%c",i);  print ""}' | \
-    LC_ALL=en_US.utf8 pbmtext -builtin bdf -wchar | cksum
+    LC_ALL=${locale_for_test} pbmtext -builtin bdf -wchar | cksum
 
-
-tmpdir=${tmpdir:-/tmp}
 output=${tmpdir}/output
 
 
 # Test 3.
 # Two rows
-# Output may be affected by locale.  Compare with cmp.
+# Compare with cmp.
 # Should print 0
-LC_ALL=C \
+
+echo "Test 3"
+
 awk 'BEGIN { for (i=32; i<=126;++i) printf("%c",i); print ""; \
              for (i=161;i<=255;++i) printf("%c",i); print "" }' | \
     iconv -f iso8859-1 -t utf-8 > ${output}
 
-LC_ALL=C \
 awk 'BEGIN { for (i=32; i<=126;++i) printf("%c",i); print ""; \
              for (i=161;i<=255;++i) printf("%c",i); print "" }' | \
     iconv -f iso8859-1 -t utf-8 | \
-    LC_ALL=en_US.utf8 pbmtext -builtin bdf -wchar -text-dump | \
+    LC_ALL=${locale_for_test} pbmtext -builtin bdf -wchar -text-dump | \
     cmp --quiet - ${output}
 
 echo ${PIPESTATUS[@]} ":" $?
@@ -71,25 +103,101 @@ rm ${output}
 
 
 # Test 4.
-# One row
+# One row  ASCII 7-bit range
 # Should print the following twice:
 # !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
-LC_ALL=C \
+
+echo "Test 4"
+
 awk 'BEGIN { for (i=32; i<=126;++i) printf("%c",i); print "" } '
 
-LC_ALL=C \
 awk 'BEGIN { for (i=32; i<=126;++i) printf("%c",i); print ""}' | \
-        LC_ALL=en_US.utf8 pbmtext -builtin bdf -wchar -text-dump
+        LC_ALL=${locale_for_test} pbmtext -builtin bdf -wchar -text-dump
+
+# Test 5.
+# Long input text
+
 
+echo "Test 5 Invalid"
 
-echo "Invalid utf-8 sequence as input." 1>&2
-echo "An error message should appear below the line." 1>&2
+long_txt=${tmpdir}/long.txt
+test_out=${tmpdir}/test_out
+
+head -c 4999 /dev/zero | tr '\0' '\276' | \
+  iconv -f iso-8859-1 -t utf-8 > ${long_txt}
+cat ${long_txt} | wc -c
+
+cat ${long_txt} | \
+  LC_ALL=${locale_for_test} pbmtext -nomargins -builtin fixed -wchar | cksum
+
+echo 1>&2
+echo "Test input text which exceeds length limit" 1>&2
+echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-# Test 5.
-# Invalid utf-8 sequence
-# Should print 1
-LC_ALL=C \
-awk 'BEGIN { for (i=128; i<=129;++i) printf("%c",i);  print ""}' | \
-        LC_ALL=en_US.utf8 pbmtext -builtin bdf -wchar -text-dump
-echo ${PIPESTATUS[@]} ":" $?
+echo -n "z" >> ${long_txt}
+cat ${long_txt} | wc -c
+
+cat ${long_txt} | \
+  LC_ALL=${locale_for_test} \
+  pbmtext -nomargins -builtin fixed -wchar > ${test_out} || \
+  echo -n "Expected failure 1";
+  test -s ${test_out}; echo " "$? 
+cat ${long_txt} | \
+  LC_ALL=${locale_for_test} \
+  pbmtext -nomargins -builtin fixed -wchar > ${test_out} || \
+  echo -n "Expected failure 2";
+  test -s ${test_out}; echo " "$?  
+
+rm ${long_txt}
+
+
+# Test 6.
+# Invalid utf-8 sequences
+# For each case output should be:
+# 6-x : 0 1 : 1 1
+
+echo "Invalid utf-8 sequences as input." 1>&2
+echo "Errors message should appear below the line." 1>&2
+echo "-----------------------------------------------------------" 1>&2
+
+echo "Test 6 Invalid"
+
+awk 'BEGIN { printf("%c%c",128,129);  print ""}' | \
+        LC_ALL=${locale_for_test} \
+        pbmtext -builtin bdf -wchar -text-dump > ${test_out} 
+  echo -n "6-1:" ${PIPESTATUS[@]} ":" $?
+  test -s ${test_out}; echo " "$?  
+  
+awk 'BEGIN { printf("ABC%c%c",192, 193);  print ""}' | \
+        LC_ALL=${locale_for_test} \
+        pbmtext -builtin bdf -wchar -text-dump > ${test_out} 
+  echo -n "6-2:" ${PIPESTATUS[@]} ":" $?
+  test -s ${test_out}; echo " "$?  
+
+awk 'BEGIN { printf("abcde%c%c", 254, 253);  print ""}' | \
+        LC_ALL=${locale_for_test} \
+        pbmtext -builtin bdf -wchar -text-dump > ${test_out} 
+  echo -n "6-3:" ${PIPESTATUS[@]} ":" $?
+  test -s ${test_out}; echo " "$?  
+  
+awk 'BEGIN { printf("abcdefg%c%c", 195, 15);  print ""}' | \
+        LC_ALL=${locale_for_test} \
+        pbmtext -builtin bdf -wchar -text-dump > ${test_out} 
+  echo -n "6-4:" ${PIPESTATUS[@]} ":" $?
+  test -s ${test_out}; echo " "$?  
+
+awk 'BEGIN { printf("123456789%c%c%c", 224, 143 ,0);  print ""}' | \
+        LC_ALL=${locale_for_test} \
+        pbmtext -builtin bdf -wchar -text-dump > ${test_out} 
+  echo -n "6-5:" ${PIPESTATUS[@]} ":" $?
+  test -s ${test_out}; echo " "$?  
+
+awk 'BEGIN { printf("abcdefg123ABCDEFG%c%c%c%c",247, 135, 135, 7);  print ""}' | \
+        LC_ALL=${locale_for_test} \
+        pbmtext -builtin bdf -wchar -text-dump > ${test_out} 
+  echo -n "6-6:" ${PIPESTATUS[@]} ":" $?
+  test -s ${test_out}; echo " "$? 
+  
+rm ${test_out}
+  
diff --git a/test/pbmtext.ok b/test/pbmtext.ok
index 96e351f9..68ed40d8 100644
--- a/test/pbmtext.ok
+++ b/test/pbmtext.ok
@@ -1,16 +1,39 @@
+Test 1
 3898818212 967
 3898818212 967
 2506052117 1354
 2506052117 1354
+Test 2
 1028079028 967
 1888680721 445
 1305436978 1018
+Test 3
 1028079028 967
 1028079028 967
 1305436978 1018
 1305436978 1018
+Test 4
 1647614653 2027
 1647614653 2027
 1647614653 2027
+Test 5
 2547645687 4564
 1174281741 5741
+Test 6 Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
+Expected failure 5 1
+Expected failure 6 1
+Expected failure 7 1
+Expected failure 8 1
+Test 7
+text length: 4999
+1854691667 52512
+1854691667 52512
+Test 8 Invalid
+text length: 5000
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
diff --git a/test/pbmtext.test b/test/pbmtext.test
index 38578636..fdecf453 100755
--- a/test/pbmtext.test
+++ b/test/pbmtext.test
@@ -5,6 +5,7 @@
 tmpdir=${tmpdir:-/tmp}
 
 # Test 1:
+echo "Test 1"
 
 # Should print 3898818212 967 twice
 
@@ -22,6 +23,7 @@ echo -n "For truth is always strange. Stranger than fiction. Lord Byron" | \
 text="The quick brown fog jumps over the lazy docs."
 
 # Test 2:
+echo "Test 2"
 
 for flags in "" "-nomargins" "-builtin fixed"
 do
@@ -33,6 +35,7 @@ temp_pbm=${tmpdir}/temp.pbm
 
 # Test 3: Check if image is produced unaltered when -width is specified
 # Should print 1028079028 967 twice, then 1305436978 1018 twice
+echo "Test 3"
 
 for flags in "" "-builtin fixed"
 do
@@ -71,13 +74,16 @@ _ PQRSTUVWXYZ[ _
 M ",/^_[\`jpqy| M
 EOF
 
+echo "Test 4"
+
 pbmtext -dump-sheet -builtin fixed | tee ${font_pbm}      | cksum
 cat ${fontRectangle_txt} | pbmtext -nom -builtin fixed    | cksum
 cat ${fontRectangle_txt} | pbmtext -nom -font ${font_pbm} | cksum
-rm ${fontRectangle_txt} ${font_pbm}
+rm ${fontRectangle_txt}
 
 
 # Test 5: Print all characters defined in the built-in bdf font
+echo "Test 5"
 
 # One long row
 # Should print 3233136020 4535
@@ -92,3 +98,78 @@ LC_ALL=C \
 awk 'BEGIN { for (i=32; i<=126;++i) printf("%c\n",i);
              for (i=160;i<=255;++i) printf("%c\n",i); }' | \
     pbmtext -nomargins -builtin bdf | cksum
+
+
+# Test 6
+
+echo 1>&2
+echo "Invalid font file specifications & command-line argument combinations." 1>&2
+echo "Error messages should appear below the line." 1>&2
+echo "-----------------------------------------------------------" 1>&2
+
+echo "Test 6 Invalid"
+
+test_out=${tmpdir}/test_out
+
+pbmtext -font=testgrid.pbm foo > ${test_out} || \
+  echo -n "Expected failure 1";
+  test -s ${test_out}; echo " "$?
+pbmtext -font=testimg.ppm  foo > ${test_out} || \
+  echo -n "Expected failure 2";
+  test -s ${test_out}; echo " "$?
+pbmtext -builtin=void      foo > ${test_out} || \
+  echo -n "Expected failure 3";  
+  test -s ${test_out}; echo " "$?
+pbmtext -font=${font_pbm} -builtin=fixed foo > ${test_out}  || \
+  echo -n "Expected failure 4";
+  test -s ${test_out}; echo " "$?  
+pbmtext -dry-run    -text-dump  foo > ${test_out} || \
+  echo -n "Expected failure 5";
+  test -s ${test_out}; echo " "$?
+pbmtext -dump-sheet -text-dump  foo > ${test_out} || \
+  echo -n "Expected failure 6";
+  test -s ${test_out}; echo " "$?
+pbmtext -dry-run    -dump-sheet foo > ${test_out} || \
+  echo -n "Expected failure 7";
+  test -s ${test_out}; echo " "$?
+pbmtext -wchar foo > ${test_out} || \
+  echo -n "Expected failure 8";
+  test -s ${test_out}; echo " "$?
+
+rm ${font_pbm}
+
+# Test 7
+# Text to render in very long single line
+
+echo "Test 7"
+
+long_txt=${tmpdir}/long.txt
+
+head -c 4999 /dev/zero | tr '\0' 'A' > ${long_txt}
+awk '{print "text length:", length($0)}' ${long_txt}
+
+pbmtext -nomargins -builtin fixed `cat ${long_txt}`  | cksum
+cat ${long_txt} | pbmtext -nomargins -builtin fixed  | cksum
+
+echo "Test 8 Invalid"
+
+echo -n "z" >> ${long_txt}
+awk '{print "text length:", length($0)}' ${long_txt}
+
+echo 1>&2
+echo "Test input text which exceeds length limit" 1>&2
+echo "Error messages should appear below the line." 1>&2
+echo "-----------------------------------------------------------" 1>&2
+
+pbmtext -nomargins -builtin fixed `cat ${long_txt}` > ${test_out}  || \
+  echo -n "Expected failure 1";
+  test -s ${test_out}; echo " "$?
+cat ${long_txt} | pbmtext -nomargins -builtin fixed > ${test_out}  || \
+  echo -n "Expected failure 2";
+  test -s ${test_out}; echo " "$?
+cat ${long_txt} | \
+  LC_ALL=C pbmtext -nomargins -builtin fixed -wchar > ${test_out}  || \
+  echo -n "Expected failure 3";
+  test -s ${test_out}; echo " "$?
+
+rm ${long_txt} ${test_out}
diff --git a/test/pbmupc.ok b/test/pbmupc.ok
index c5753609..f1b91e99 100644
--- a/test/pbmupc.ok
+++ b/test/pbmupc.ok
@@ -1,12 +1,12 @@
 Test 1
 2619309127 10172
-Test 2
-Exptected error 1
-Exptected error 2
-Exptected error 3
-Exptected error 4
-Exptected error 5
-Exptected error 6
-Exptected error 7
-Exptected error 8
-Exptected error 9
+Test Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
+Expected failure 5 1
+Expected failure 6 1
+Expected failure 7 1
+Expected failure 8 1
+Expected failure 9 1
diff --git a/test/pbmupc.test b/test/pbmupc.test
index aee380b0..fb9ec90e 100755
--- a/test/pbmupc.test
+++ b/test/pbmupc.test
@@ -9,19 +9,33 @@ do
 pbmupc $type 0 72890 00011
 done | cksum
 
-echo "Test 2"
+echo "Test Invalid"
+
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
 
 echo 1>&2
 echo "Invalid command-line argument combinations." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-pbmupc -s3 0 72890 00011     || echo "Exptected error 1"
-pbmupc -s1   72890 00011     || echo "Exptected error 2"
-pbmupc -s1 0 72890           || echo "Exptected error 3"
-pbmupc -s1 10 72890 00011    || echo "Exptected error 4"
-pbmupc -s1 0 172890 00011    || echo "Exptected error 5"
-pbmupc -s1 0   2890 00011    || echo "Exptected error 6"
-pbmupc -s1 0 72890 100011    || echo "Exptected error 7"
-pbmupc -s1 0 72890   0011    || echo "Exptected error 8"
-pbmupc -s1 0 72890 100011 1  || echo "Exptected error 9"
+pbmupc -s3 0 72890 00011     > ${test_out} || \
+   echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+pbmupc -s1   72890 00011     > ${test_out} || \
+   echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+pbmupc -s1 0 72890           > ${test_out} || \
+   echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+pbmupc -s1 10 72890 00011    > ${test_out} || \
+   echo -n "Expected failure 4"; test -s ${test_out}; echo " "$?
+pbmupc -s1 0 172890 00011    > ${test_out} || \
+   echo -n "Expected failure 5"; test -s ${test_out}; echo " "$?
+pbmupc -s1 0   2890 00011    > ${test_out} || \
+   echo -n "Expected failure 6"; test -s ${test_out}; echo " "$?
+pbmupc -s1 0 72890 100011    > ${test_out} || \
+   echo -n "Expected failure 7"; test -s ${test_out}; echo " "$?
+pbmupc -s1 0 72890   0011    > ${test_out} || \
+   echo -n "Expected failure 8"; test -s ${test_out}; echo " "$?
+pbmupc -s1 0 72890 100011 1  > ${test_out} || \
+   echo -n "Expected failure 9"; test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/pgmhist.ok b/test/pgmhist.ok
index 6d9dfbe5..3be73ff9 100644
--- a/test/pgmhist.ok
+++ b/test/pgmhist.ok
@@ -29,8 +29,8 @@ Test 2
 204
 230
 255
-Test 3
-Expected failure 1
-Expected failure 2
-Expected failure 3
-Expected failure 4
+Test Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
diff --git a/test/pgmhist.test b/test/pgmhist.test
index c566c5cb..3be74898 100755
--- a/test/pgmhist.test
+++ b/test/pgmhist.test
@@ -24,14 +24,23 @@ pgmramp -lr 256 1 | pgmhist -machine -quartile | \
 pgmramp -lr 256 1 | pgmhist -machine -decile   | \
   sed -e 's/  */ /g' -e 's/ *$//'
 
-echo "Test 3"
+echo "Test Invalid"
+
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
 
 echo 1>&2
 echo "Invalid command-line argument combinations." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-pgmhist -median   -quartile testgrid.pbm || echo "Expected failure 1"
-pgmhist -median   -decile   testgrid.pbm || echo "Expected failure 2"
-pgmhist -quartile -decile   testgrid.pbm || echo "Expected failure 3"
-pgmhist testimg.ppm || echo "Expected failure 4"
+pgmhist -median   -quartile testgrid.pbm > ${test_out} || \ 
+  echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+pgmhist -median   -decile   testgrid.pbm > ${test_out} || \
+  echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+pgmhist -quartile -decile   testgrid.pbm > ${test_out} || \
+  echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+pgmhist testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 4"; test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/pgmmake.ok b/test/pgmmake.ok
index 9a88b9a6..8b242822 100644
--- a/test/pgmmake.ok
+++ b/test/pgmmake.ok
@@ -1,12 +1,12 @@
-Test 1.
+Test 1
 3662611538 2513
 3109612402 5012
-Test 2.
-Expected error 1
-Expected error 2
-Expected error 3
-Expected error 4
-Expected error 5
-Expected error 6
-Expected error 7
-Expected error 8
+Test Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
+Expected failure 5 1
+Expected failure 6 1
+Expected failure 7 1
+Expected failure 8 1
diff --git a/test/pgmmake.test b/test/pgmmake.test
index 3823e36f..2fc63e72 100755
--- a/test/pgmmake.test
+++ b/test/pgmmake.test
@@ -2,25 +2,37 @@
 # This script tests: pgmmake
 # Also requires:
 
-echo "Test 1."
+echo "Test 1"
 
 pgmmake 1 50 50 | cksum
 pgmmake .2 50 100 -maxval=5 | cksum
 
 
-echo "Test 2."
+echo "Test Invalid"
 
 echo 1>&2
 echo "Invalid command-line argument combinations." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-pgmmake 100  5 5 || echo "Expected error 1"
-pgmmake 1.01 5 5 || echo "Expected error 2"
-pgmmake .5   5   || echo "Expected error 3"
-pgmmake .5       || echo "Expected error 4"
-pgmmake -maxval=5        5 5 || echo "Expected error 5"
-pgmmake -maxval=0     .5 5 5 || echo "Expected error 6"
-pgmmake -maxval=-1    .5 5 5 || echo "Expected error 7"
-pgmmake -maxval=65536 .5 5 5 || echo "Expected error 8"
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
 
+pgmmake 100  5 5 > ${test_out} || \
+   echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+pgmmake 1.01 5 5 > ${test_out} || \
+   echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+pgmmake .5   5   > ${test_out} || \
+   echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+pgmmake .5       > ${test_out} || \
+   echo -n "Expected failure 4"; test -s ${test_out}; echo " "$?
+pgmmake -maxval=5        5 5 > ${test_out} || \
+   echo -n "Expected failure 5"; test -s ${test_out}; echo " "$?
+pgmmake -maxval=0     .5 5 5 > ${test_out} || \
+   echo -n "Expected failure 6"; test -s ${test_out}; echo " "$?
+pgmmake -maxval=-1    .5 5 5 > ${test_out} || \
+   echo -n "Expected failure 7"; test -s ${test_out}; echo " "$?
+pgmmake -maxval=65536 .5 5 5 > ${test_out} || \
+   echo -n "Expected failure 8"; test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/pgmramp.ok b/test/pgmramp.ok
index 309f5773..de0d9206 100644
--- a/test/pgmramp.ok
+++ b/test/pgmramp.ok
@@ -41,9 +41,9 @@ Test 2
 807973067 65551
 Test 3
 886972785 131087
-Test 4
-Expected error: -lr -tb
-Expected error: -lr -rectangle
-Expected error: -rectangle -ellipse
-Expected error: insufficient parameters
-Expected error: excessive parameters
+Test Invalid
+Expected failure: -lr -tb 1
+Expected failure: -lr -rectangle 1
+Expected failure: -rectangle -ellipse 1
+Expected failure: insufficient parameters 1
+Expected failure: excessive parameters 1
diff --git a/test/pgmramp.test b/test/pgmramp.test
index bd63e10d..3ec73749 100755
--- a/test/pgmramp.test
+++ b/test/pgmramp.test
@@ -19,16 +19,26 @@ echo "Test 3"
 
 pgmramp -diagonal -maxval=510 256 256 | cksum
 
-echo "Test 4"
+echo "Test Invalid"
 
 echo 1>&2
 echo "Invalid command-line argument combinations." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
+
 for combination in "-lr -tb" "-lr -rectangle" "-rectangle -ellipse"
-do pgmramp $combination 10 10 || echo "Expected error: $combination"
+do pgmramp $combination 10 10 > ${test_out} || \
+   echo -n "Expected failure: $combination" ; test -s ${test_out}; echo " "$?
 done
 
-pgmramp -lr     1 || echo "Expected error: insufficient parameters"
-pgmramp -tb 1 1 1 || echo "Expected error: excessive parameters"
+pgmramp -lr     1 > ${test_out} || \
+  echo -n "Expected failure: insufficient parameters"; \
+  test -s ${test_out}; echo " "$?
+pgmramp -tb 1 1 1 > ${test_out} || \
+  echo -n "Expected failure: excessive parameters"; \
+  test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/pnmcolormap.ok b/test/pnmcolormap.ok
new file mode 100644
index 00000000..126dfea4
--- /dev/null
+++ b/test/pnmcolormap.ok
@@ -0,0 +1,16 @@
+P1
+2 1
+10
+P1
+2 1
+10
+P1
+2 1
+10
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
+Expected failure 5 1
+Expected failure 6 1
+Expected failure 7 1
diff --git a/test/pnmcolormap.test b/test/pnmcolormap.test
new file mode 100755
index 00000000..13be8a44
--- /dev/null
+++ b/test/pnmcolormap.test
@@ -0,0 +1,33 @@
+#! /bin/bash
+# This script tests: pnmcolormap
+# Also requires:
+
+pnmcolormap -plain -sort 2 testgrid.pbm
+pnmcolormap -plain -sort -square 2 testgrid.pbm 
+pnmcolormap -plain -sort all testgrid.pbm
+
+echo 1>&2
+echo "Invalid command-line arguments." 1>&2
+echo "Error messages should appear below the line." 1>&2
+echo "-----------------------------------------------------------" 1>&2
+
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
+
+pnmcolormap 0 testimg.ppm   > ${test_out} || \
+  echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+pnmcolormap -1 testimg.ppm  > ${test_out} || \
+  echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+pnmcolormap 0.1 testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+pnmcolormap -center -meancolor 16 testimg.ppm    > ${test_out} || \
+  echo -n "Expected failure 4"; test -s ${test_out}; echo " "$?
+pnmcolormap -center -meanpixel 16 testimg.ppm    > ${test_out} || \
+  echo -n "Expected failure 5"; test -s ${test_out}; echo " "$?
+pnmcolormap -meancolor -meanpixel 16 testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 6"; test -s ${test_out}; echo " "$?
+pnmcolormap -spreadbrightness -spreadluminosity 16 \
+  testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 7"; test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/pnmcrop1.ok b/test/pnmcrop1.ok
index 25bc52ce..d02d14b3 100644
--- a/test/pnmcrop1.ok
+++ b/test/pnmcrop1.ok
@@ -78,26 +78,26 @@ test.ppm
 -top
 1435955776 120765
 1435955776 120765
-Test 3
+Test Invalid
 -reportfull -reportsize
-expected failure
+Expected failure:  -reportfull -reportsize 1
 -reportfull -borderfile=testgrid.pbm
-expected failure
+Expected failure:  -reportfull -borderfile=testgrid.pbm 1
 -reportsize -borderfile=testgrid.pbm
-expected failure
+Expected failure:  -reportsize -borderfile=testgrid.pbm 1
 -black -white
-expected failure
+Expected failure:  -black -white 1
 -black -sides
-expected failure
+Expected failure:  -black -sides 1
 -white -bg-color=red
-expected failure
+Expected failure:  -white -bg-color=red 1
 -white -bg-corner=topleft
-expected failure
+Expected failure:  -white -bg-corner=topleft 1
 -white -bg-corner=top
-expected failure
+Expected failure:  -white -bg-corner=top 1
 -blank-image=pasturize
-expected failure
+Expected failure:  -blank-image=pasturize 1
 -bg-color=black -closeness=-1
-expected failure
+Expected failure:  -bg-color=black -closeness=-1 1
 -bg-color=black -closeness=101
-expected failure
+Expected failure:  -bg-color=black -closeness=101 1
diff --git a/test/pnmcrop1.test b/test/pnmcrop1.test
index 6b37da23..34c7534a 100755
--- a/test/pnmcrop1.test
+++ b/test/pnmcrop1.test
@@ -51,13 +51,15 @@ for input_file in ${test_pbm} ${test_ppm}
 rm ${test_pbm} ${test_ppm}
 
 # Test 3
+echo "Test Invalid"
+
+test_out=${tmpdir}/test_out
 
 echo 1>&2
 echo "Invalid command-line argument combinations." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-echo Test 3
 for option in "-reportfull -reportsize" \
               "-reportfull -borderfile=testgrid.pbm" \
               "-reportsize -borderfile=testgrid.pbm" \
@@ -71,5 +73,7 @@ for option in "-reportfull -reportsize" \
               "-bg-color=black -closeness=101"
     do
     echo ${option}
-    pnmcrop -reportfull ${option} testgrid.pbm || echo expected failure
+    pnmcrop -reportfull ${option} testgrid.pbm > ${test_out} || \
+        echo -n "Expected failure: " ${option}; test -s ${test_out}; echo " "$?
+        rm ${test_out} 
     done
diff --git a/test/pnmpsnr.ok b/test/pnmpsnr.ok
index e8b5ebc2..7042f86c 100644
--- a/test/pnmpsnr.ok
+++ b/test/pnmpsnr.ok
@@ -7,8 +7,8 @@ Test 2
 300.00 300.00 300.00
 match
 match
-Test 3
-Expected failure 1
-Expected failure 2
-Expected failure 3
-Expected failure 4
+Test Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
diff --git a/test/pnmpsnr.test b/test/pnmpsnr.test
index c6520002..7603459b 100755
--- a/test/pnmpsnr.test
+++ b/test/pnmpsnr.test
@@ -25,16 +25,23 @@ pnmpsnr  testimg.ppm  testimg.ppm -target=1000
 pnmpsnr  testimg.ppm  testimg.ppm -target1=1000 -target2=1000 -target3=1000
 
 
-echo "Test 3"
+echo "Test Invalid"
+
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
 
 echo 1>&2
 echo "Invalid command-line argument combinations." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-pnmpsnr ${b_pbm} ${w_pbm} ${b_pbm}     || echo "Expected failure 1"
-pnmpsnr ${b_pbm}                       || echo "Expected failure 2"
-pnmpsnr ${b_pbm} ${w_pbm} -target1=100 || echo "Expected failure 3"
-pnmpsnr                   -machine     || echo "Expected failure 4"
+pnmpsnr ${b_pbm} ${w_pbm} ${b_pbm}     > ${test_out} || \
+   echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+pnmpsnr ${b_pbm}                       > ${test_out} || \
+   echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+pnmpsnr ${b_pbm} ${w_pbm} -target1=100 > ${test_out} || \
+   echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+pnmpsnr                   -machine     > ${test_out} || \
+   echo -n "Expected failure 4"; test -s ${test_out}; echo " "$?
 
-rm ${b_pbm} ${w_pbm}
\ No newline at end of file
+rm ${b_pbm} ${w_pbm} ${test_out}
diff --git a/test/pnmquant.ok b/test/pnmquant.ok
new file mode 100644
index 00000000..407d42a3
--- /dev/null
+++ b/test/pnmquant.ok
@@ -0,0 +1,18 @@
+Test 1
+1 1
+1 1
+1 1
+1 1
+1 1
+1 1
+1 1
+1 1
+Test Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
+Expected failure 5 1
+Expected failure 6 1
+Expected failure 7 1
+Expected failure 8 1
diff --git a/test/pnmquant.test b/test/pnmquant.test
new file mode 100755
index 00000000..1154cf84
--- /dev/null
+++ b/test/pnmquant.test
@@ -0,0 +1,61 @@
+#! /bin/bash
+# This script tests: pnmquant
+# Also requires: ppmhist
+
+echo "Test 1"
+
+# Count colors in output image.
+
+pnmquant 256 testimg.ppm | ppmhist | \
+  awk 'NR==1 {print ($2 <= 256) , ($2 > 256 * 0.95)}' 
+
+pnmquant -center 256 testimg.ppm | ppmhist | \
+  awk 'NR==1 {print ($2 <= 256) , ($2 > 256 * 0.95)}' 
+
+pnmquant -spreadbrightness 256 testimg.ppm | ppmhist | \
+  awk 'NR==1 {print ($2 <= 256) , ($2 > 256 * 0.95)}' 
+
+pnmquant -spreadluminosity 128 testimg.ppm | ppmhist | \
+  awk 'NR==1 {print ($2 <= 128) , ($2 > 128 * 0.95)}' 
+
+pnmquant -floyd -randomseed=0 128 testimg.ppm | ppmhist | \
+  awk 'NR==1 {print ($2 <= 128) , ($2 > 128 * 0.95)}' 
+
+pnmquant 64 -meanpixel testimg.ppm | ppmhist | \
+  awk 'NR==1 {print ($2 <= 64) , ($2 > 64 * 0.9)}' 
+
+pnmquant 16 -meancolor testimg.ppm | ppmhist | \
+  awk 'NR==1 {print ($2 <= 16) , ($2 > 16 * 0.9)}' 
+
+
+pnmquant 2 testgrid.pbm | ppmhist | \
+  awk 'NR==1 {print ($2 <= 2) , ($2 == 2) }' 
+ 
+echo "Test Invalid"
+
+echo 1>&2
+echo "Invalid command-line arguments." 1>&2
+echo "Error messages should appear below the line." 1>&2
+echo "-----------------------------------------------------------" 1>&2
+
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
+
+pnmquant 0 testimg.ppm   > ${test_out} || \
+  echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+pnmquant testimg.ppm  > ${test_out} || \
+  echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+pnmquant 10.5 testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+pnmquant -center -meancolor 16 testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 4"; test -s ${test_out}; echo " "$?
+pnmquant -center -meanpixel 16 testimg.ppm    > ${test_out} || \
+  echo -n "Expected failure 5"; test -s ${test_out}; echo " "$?
+pnmquant -meancolor -meanpixel 16 testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 6"; test -s ${test_out}; echo " "$?
+pnmquant -spreadbrightness -spreadluminosity 16 testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 7"; test -s ${test_out}; echo " "$?
+pnmquant -floyd -nofloyd 16 testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 8"; test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/pnmremap1.ok b/test/pnmremap1.ok
index 07954684..23a9dddd 100644
--- a/test/pnmremap1.ok
+++ b/test/pnmremap1.ok
@@ -1 +1,7 @@
 3602410851 101482
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
+Expected failure 5 1
+Expected failure 6 1
diff --git a/test/pnmremap1.test b/test/pnmremap1.test
index d7c5189c..18debcb8 100755
--- a/test/pnmremap1.test
+++ b/test/pnmremap1.test
@@ -2,7 +2,6 @@
 # This script tests: pnmremap
 # Also requires: pamseq pamtopnm
 
-
 tmpdir=${tmpdir:-/tmp}
 palette=${tmpdir}/palette
 #palette255=${tmpdir}/palette255
@@ -24,3 +23,27 @@ pnmremap -mapfile=${palette} -floyd -norandom \
 # testimg.ppm | cksum
 
 rm ${palette} # ${palette255}
+
+echo 1>&2
+echo "Invalid command-line arguments." 1>&2
+echo "Error messages should appear below the line." 1>&2
+echo "-----------------------------------------------------------" 1>&2
+
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
+
+pnmremap -mapfile=/dev/null testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+pnmremap -mapfile=/dev/zero testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+pnmremap testimg.ppm                    > ${test_out} || \
+  echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+pnmremap -fs -nofs testimg.ppm          > ${test_out} || \
+  echo -n "Expected failure 4"; test -s ${test_out}; echo " "$?
+pnmremap -mapfile=testgrid.pbm -missingcolor=rgb:00/ff/00 testimg.ppm \
+ > ${test_out} || \
+  echo -n "Expected failure 5"; test -s ${test_out}; echo " "$?
+pnmremap -mapfile=testgrid.pbm -firstisdefault testimg.ppm > ${test_out} || \
+  echo -n "Expected failure 6"; test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/ppmforge-parameters.ok b/test/ppmforge-parameters.ok
index 50e68390..37d89ccd 100644
--- a/test/ppmforge-parameters.ok
+++ b/test/ppmforge-parameters.ok
@@ -2,9 +2,9 @@ Test 1
 256 256
 100 90
 90 90
-Test 2
-Expected failure 1
-Expected failure 2
-Expected failure 3
-Expected failure 4
-Expected failure 5
+Test Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
+Expected failure 5 1
diff --git a/test/ppmforge-parameters.test b/test/ppmforge-parameters.test
index 48c4ae4c..28a92916 100755
--- a/test/ppmforge-parameters.test
+++ b/test/ppmforge-parameters.test
@@ -15,15 +15,25 @@ ppmforge -night -width=99 -height=90 | pamfile -size
 # brought up to 100 in this case
 ppmforge -night -width=80 -height=90 | pamfile -size
 
-echo "Test 2"
+echo "Test Invalid"
+
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
 
 echo 1>&2
 echo "Invalid command-line arguments." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-ppmforge -night  -dimension=0  || echo "Expected failure 1"
-ppmforge -clouds -mesh=1.99    || echo "Expected failure 2"
-ppmforge -clouds -power=0      || echo "Expected failure 3"
-ppmforge         -ice=0        || echo "Expected failure 4"
-ppmforge         -glaciers=0   || echo "Expected failure 5"
+ppmforge -night  -dimension=0  > ${test_out} || \
+   echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+ppmforge -clouds -mesh=1.99    > ${test_out} || \
+   echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+ppmforge -clouds -power=0      > ${test_out} || \
+   echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+ppmforge         -ice=0        > ${test_out} || \
+   echo -n "Expected failure 4"; test -s ${test_out}; echo " "$?
+ppmforge         -glaciers=0   > ${test_out} || \
+   echo -n "Expected failure 5"; test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/ppmhist.ok b/test/ppmhist.ok
index 38b7770f..468bd317 100644
--- a/test/ppmhist.ok
+++ b/test/ppmhist.ok
@@ -19,7 +19,7 @@ Test 2
  Summary: 6 colors: 0 black, 0 white, 0 gray, 6 color
  Summary: 6 colors: 1 black, 0 white, 0 gray, 5 color
  Summary: 6 colors: 1 black, 1 white, 1 gray, 3 color
-Test 3
-Expected failure 1
-Expected failure 2
-Expected failure 3
+Test Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
diff --git a/test/ppmhist.test b/test/ppmhist.test
index c17bab5a..1983bd13 100755
--- a/test/ppmhist.test
+++ b/test/ppmhist.test
@@ -25,14 +25,21 @@ ppmpat -madras --color=rgb:00/00/00,rgb:31/58/a3,rgb:e9/5e/d4 25 25 | \
 ppmpat -madras --color=rgb:00/00/00,rgb:31/58/a3,rgb:ff/ff/ff 25 25 | \
   ppmhist | head -n1
 
-echo "Test 3"
+echo "Test Invalid"
+
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
 
 echo 1>&2
 echo "Invalid command-line argument combinations." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-ppmhist -hexcolor -float testimg.ppm || echo "Expected failure 1"
-ppmhist -hexcolor -map   testimg.ppm || echo "Expected failure 2"
-ppmhist -float    -map   testimg.ppm || echo "Expected failure 3"
+ppmhist -hexcolor -float testimg.ppm > ${test_out} || \
+   echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+ppmhist -hexcolor -map   testimg.ppm > ${test_out} || \
+   echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+ppmhist -float    -map   testimg.ppm > ${test_out} || \
+   echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
 
+rm ${test_out}
diff --git a/test/ppmmake.ok b/test/ppmmake.ok
index 8a2bedc7..6d559c8d 100644
--- a/test/ppmmake.ok
+++ b/test/ppmmake.ok
@@ -1,15 +1,15 @@
-Test 1.
+Test 1
 2477651508 15012
 4294967295 0
 2378991101 7513
-Test 2.
-Expected error 1
-Expected error 2
-Expected error 3
-Expected error 4
-Expected error 5
-Expected error 6
-Expected error 7
-Expected error 8
-Expected error 9
-Expected error 10
+Test Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
+Expected failure 5 1
+Expected failure 6 1
+Expected failure 7 1
+Expected failure 8 1
+Expected failure 9 1
+Expected failure 10 1
diff --git a/test/ppmmake.test b/test/ppmmake.test
index edd6f251..f28249c7 100755
--- a/test/ppmmake.test
+++ b/test/ppmmake.test
@@ -2,26 +2,41 @@
 # This script tests: ppmmake
 # Also requires:
 
-echo "Test 1."
+echo "Test 1"
 
 ppmmake rgb:ff/80/80 50 100 -maxval=5 | cksum
 ppmmake rgbi:0.5/1.0/0 2   | cksum
 ppmmake red 50 50  | cksum
 
-echo "Test 2."
+echo "Test Invalid"
+
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
 
 echo 1>&2
 echo "Invalid command-line argument combinations." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-ppmmake rgb:gg/00/00  2 2  || echo "Expected error 1"
-ppmmake rgb:ff/ff/00  2    || echo "Expected error 2"
-ppmmake rgbi:1.1/0/0  2 2  || echo "Expected error 3"
-ppmmake rgbi:1.0/.5   2 2  || echo "Expected error 4"
-ppmmake rainbow       2 2  || echo "Expected error 5"
-ppmmake               2 2  || echo "Expected error 6"
-ppmmake blue -maxval=0 2 2  || echo "Expected error 7"
-ppmmake blue -maxval=-1 2 2  || echo "Expected error 8"
-ppmmake blue -maxval=65536 2 2  || echo "Expected error 9"
-RGBDEF=/dev/null ppmmake red 2 2 || echo "Expected error 10"
+ppmmake rgb:gg/00/00  2 2  > ${test_out} || \
+   echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+ppmmake rgb:ff/ff/00  2    > ${test_out} || \
+   echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+ppmmake rgbi:1.1/0/0  2 2  > ${test_out} || \
+   echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+ppmmake rgbi:1.0/.5   2 2  > ${test_out} || \
+   echo -n "Expected failure 4"; test -s ${test_out}; echo " "$?
+ppmmake rainbow       2 2  > ${test_out} || \
+   echo -n "Expected failure 5"; test -s ${test_out}; echo " "$?
+ppmmake               2 2  > ${test_out} || \
+   echo -n "Expected failure 6"; test -s ${test_out}; echo " "$?
+ppmmake blue -maxval=0 2 2  > ${test_out} || \
+   echo -n "Expected failure 7"; test -s ${test_out}; echo " "$?
+ppmmake blue -maxval=-1 2 2  > ${test_out} || \
+   echo -n "Expected failure 8"; test -s ${test_out}; echo " "$?
+ppmmake blue -maxval=65536 2 2  > ${test_out} || \
+   echo -n "Expected failure 9"; test -s ${test_out}; echo " "$?
+RGBDEF=/dev/null ppmmake red 2 2 > ${test_out} || \
+   echo -n "Expected failure 10"; test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/ppmpat.ok b/test/ppmpat.ok
index 5493ba53..4a9cebd9 100644
--- a/test/ppmpat.ok
+++ b/test/ppmpat.ok
@@ -10,30 +10,30 @@ Test 5
 3057513592 661
 Test 6
 1861389287 661
-Test 7
-Expected failure 1
-Expected failure 2
-Expected failure 3
-Expected failure 4
-Expected failure 5
-Expected failure 6
-Expected failure 7
-Expected failure 8
-Expected failure 9
-Expected failure 10
-Expected failure 11
-Expected failure 12
-Expected failure 13
-Expected failure 14
-Expected failure 15
-Expected failure 16
-Expected failure 17
-Expected failure 18
-Expected failure 19
-Expected failure 20
-Expected failure 21
-Expected failure 22
-Expected failure 23
-Expected failure 24
-Expected failure 25
-Expected failure 26
+Test Invalid
+Expected failure 1 1
+Expected failure 2 1
+Expected failure 3 1
+Expected failure 4 1
+Expected failure 5 1
+Expected failure 6 1
+Expected failure 7 1
+Expected failure 8 1
+Expected failure 9 1
+Expected failure 10 1
+Expected failure 11 1
+Expected failure 12 1
+Expected failure 13 1
+Expected failure 14 1
+Expected failure 15 1
+Expected failure 16 1
+Expected failure 17 1
+Expected failure 18 1
+Expected failure 19 1
+Expected failure 20 1
+Expected failure 21 1
+Expected failure 22 1
+Expected failure 23 1
+Expected failure 24 1
+Expected failure 25 1
+Expected failure 26 1
diff --git a/test/ppmpat.test b/test/ppmpat.test
index c6647328..0a6127ca 100755
--- a/test/ppmpat.test
+++ b/test/ppmpat.test
@@ -27,23 +27,35 @@ echo "Test 6"
 ppmpat -argyle2 --color=rgb:00/00/00,rgb:ff/80/80,rgb:e0/e0/e0 12 18 | cksum
 
 # Test 7.
-echo "Test 7"
+echo "Test Invalid"
+
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
 
 echo 1>&2
 echo "Invalid command-line argument combinations." 1>&2
 echo "Error messages should appear below the line." 1>&2
 echo "-----------------------------------------------------------" 1>&2
 
-ppmpat -g2 -g3 10 10 || echo "Expected failure 1"
-ppmpat -madras -tartan 10 10 || echo "Expected failure 2"
-ppmpat -poles -squig 10 10 || echo "Expected failure 3"
-ppmpat -camo -anticamo 10 10 || echo "Expected failure 4"
-ppmpat -argyle1 -argyle2 10 10 || echo "Expected failure 5"
+ppmpat -g2 -g3 10 10 > ${test_out} || \
+   echo -n "Expected failure 1"; test -s ${test_out}; echo " "$?
+ppmpat -madras -tartan 10 10 > ${test_out} || \
+   echo -n "Expected failure 2"; test -s ${test_out}; echo " "$?
+ppmpat -poles -squig 10 10 > ${test_out} || \
+   echo -n "Expected failure 3"; test -s ${test_out}; echo " "$?
+ppmpat -camo -anticamo 10 10 > ${test_out} || \
+   echo -n "Expected failure 4"; test -s ${test_out}; echo " "$?
+ppmpat -argyle1 -argyle2 10 10 > ${test_out} || \
+   echo -n "Expected failure 5"; test -s ${test_out}; echo " "$?
 
-ppmpat 10 10 || echo "Expected failure 6"
-ppmpat -g2 10 || echo "Expected failure 7"
-ppmpat -g2 10 10 10 || echo "Expected failure 8"
-ppmpat -g2 10 || echo "Expected failure 9"
+ppmpat 10 10 > ${test_out} || \
+   echo -n "Expected failure 6"; test -s ${test_out}; echo " "$?
+ppmpat -g2 10 > ${test_out} || \
+   echo -n "Expected failure 7"; test -s ${test_out}; echo " "$?
+ppmpat -g2 10 10 10 > ${test_out} || \
+   echo -n "Expected failure 8"; test -s ${test_out}; echo " "$?
+ppmpat -g2 10 > ${test_out} || \
+   echo -n "Expected failure 9"; test -s ${test_out}; echo " "$?
 
 clist1="-color=rgb:00/00/00"
 clist2="-color=rgb:00/00/00,rgb:00/00/ff"
@@ -51,26 +63,45 @@ clist3="-color=rgb:00/00/00,rgb:00/00/ff,rgb:00/ff/ff"
 clist4="-color=rgb:00/00/00,rgb:00/00/ff,rgb:00/ff/ff,rgb:ff/ff/ff"
 
 # These patterns require exactly 2 colors 
-ppmpat -gingham2 ${clist1} 10 10 || echo "Expected failure 10"
-ppmpat -argyle1  ${clist1} 10 10 || echo "Expected failure 11"
-ppmpat -gingham2 ${clist3} 10 10 || echo "Expected failure 12"
-ppmpat -argyle1  ${clist3} 10 10 || echo "Expected failure 13"
+ppmpat -gingham2 ${clist1} 10 10 > ${test_out} || \
+   echo -n "Expected failure 10"; test -s ${test_out}; echo " "$?
+ppmpat -argyle1  ${clist1} 10 10 > ${test_out} || \
+   echo -n "Expected failure 11"; test -s ${test_out}; echo " "$?
+ppmpat -gingham2 ${clist3} 10 10 > ${test_out} || \
+   echo -n "Expected failure 12"; test -s ${test_out}; echo " "$?
+ppmpat -argyle1  ${clist3} 10 10 > ${test_out} || \
+   echo -n "Expected failure 13"; test -s ${test_out}; echo " "$?
 
 # These require exactly 3 colors 
-ppmpat -gingham3 ${clist2} 10 10 || echo "Expected failure 14"
-ppmpat -argyle2  ${clist2} 10 10 || echo "Expected failure 15"
-ppmpat -madras   ${clist2} 10 10 || echo "Expected failure 16"
-ppmpat -tartan   ${clist2} 10 10 || echo "Expected failure 17"
-ppmpat -gingham3 ${clist4} 10 10 || echo "Expected failure 18"
-ppmpat -argyle2  ${clist4} 10 10 || echo "Expected failure 19"
-ppmpat -madras   ${clist4} 10 10 || echo "Expected failure 20"
-ppmpat -tartan   ${clist4} 10 10 || echo "Expected failure 21"
+ppmpat -gingham3 ${clist2} 10 10 > ${test_out} || \
+   echo -n "Expected failure 14"; test -s ${test_out}; echo " "$?
+ppmpat -argyle2  ${clist2} 10 10 > ${test_out} || \
+   echo -n "Expected failure 15"; test -s ${test_out}; echo " "$?
+ppmpat -madras   ${clist2} 10 10 > ${test_out} || \
+   echo -n "Expected failure 16"; test -s ${test_out}; echo " "$?
+ppmpat -tartan   ${clist2} 10 10 > ${test_out} || \
+   echo -n "Expected failure 17"; test -s ${test_out}; echo " "$?
+ppmpat -gingham3 ${clist4} 10 10 > ${test_out} || \
+   echo -n "Expected failure 18"; test -s ${test_out}; echo " "$?
+ppmpat -argyle2  ${clist4} 10 10 > ${test_out} || \
+   echo -n "Expected failure 19"; test -s ${test_out}; echo " "$?
+ppmpat -madras   ${clist4} 10 10 > ${test_out} || \
+   echo -n "Expected failure 20"; test -s ${test_out}; echo " "$?
+ppmpat -tartan   ${clist4} 10 10 > ${test_out} || \
+   echo -n "Expected failure 21"; test -s ${test_out}; echo " "$?
 
 # These require at least 3 colors 
-ppmpat -squig    ${clist2} 10 10 || echo "Expected failure 22"
-ppmpat -camo     ${clist2} 10 10 || echo "Expected failure 23"
-ppmpat -anticamo ${clist2} 10 10 || echo "Expected failure 24"
+ppmpat -squig    ${clist2} 10 10 > ${test_out} || \
+   echo -n "Expected failure 22"; test -s ${test_out}; echo " "$?
+ppmpat -camo     ${clist2} 10 10 > ${test_out} || \
+   echo -n "Expected failure 23"; test -s ${test_out}; echo " "$?
+ppmpat -anticamo ${clist2} 10 10 > ${test_out} || \
+   echo -n "Expected failure 24"; test -s ${test_out}; echo " "$?
 
 # The squig pattern has an aspect ratio restriction 
-ppmpat -squig ${clist3} 10 250  || echo "Expected failure 25"
-ppmpat -squig ${clist3} 500 20  || echo "Expected failure 26"
+ppmpat -squig ${clist3} 10 250  > ${test_out} || \
+   echo -n "Expected failure 25"; test -s ${test_out}; echo " "$?
+ppmpat -squig ${clist3} 500 20  > ${test_out} || \
+   echo -n "Expected failure 26"; test -s ${test_out}; echo " "$?
+
+rm ${test_out}
diff --git a/test/ps-alt-roundtrip.ok b/test/ps-alt-roundtrip.ok
index 1cd73f75..2deba38d 100644
--- a/test/ps-alt-roundtrip.ok
+++ b/test/ps-alt-roundtrip.ok
@@ -1,3 +1,2 @@
 2425386270 41
-2425386270 41
 2916080186 235
diff --git a/test/ps-alt-roundtrip.test b/test/ps-alt-roundtrip.test
index d90c4ddb..af7f7222 100755
--- a/test/ps-alt-roundtrip.test
+++ b/test/ps-alt-roundtrip.test
@@ -1,5 +1,5 @@
 #! /bin/bash
-# This script tests: pbmtoepsi pbmtopsg3 pbmtolps psidtopgm pstopnm
+# This script tests: pbmtoepsi pbmtopsg3 psidtopgm pstopnm
 # Also requires: gs pnmcrop
 
 
@@ -10,12 +10,15 @@
 # We keep these tests separate from those for pnmtops and pstopnm
 # which are far more popular.
 #
-# pbmtopsg3 and pbmtolps produce output that require pstopnm for decoding.
+# pbmtopsg3 produces output that requires pstopnm for decoding.
+#
+# We used to test pbmtolps here, but moved it out when gs changed its
+# rendering formula.
 #
 # Failure message
 ## If ps-roundtrip.test succeeds and this test fails, it is most likely
 ## a problem with one of the alternate Postscipt utilities:
-## pbmtoepsi, pbmtopsg3, pbmtolps or psidtopgm.
+## pbmtoepsi, pbmtopsg3, or psidtopgm.
 ## If both tests fail it indicates a problem with pstopnm or gs.
 
 # pstopnm does not use libnetpbm functions for output.
@@ -33,18 +36,8 @@ pstopnm -xborder=0 -yborder=0 -llx=0 -lly=-16 -urx=14 \
 rm ${testgrid1_ps}
 
 
-# Test 2. Should print: 2425386270 41
-testgrid2_ps=${tmpdir}/testgrid2.ps
-
-pbmtolps -dpi 72 testgrid.pbm \
-     > ${testgrid2_ps} && \
-pstopnm -xborder=0 -yborder=0 -dpi=72 -stdout \
-    -quiet ${testgrid2_ps} -pbm | \
-  pnmcrop | cksum
-
-rm ${testgrid2_ps}
 
-# Test 3. Should print: 2916080186 235
+# Test 2. Should print: 2916080186 235
 # Output is pgm maxval=1 with black and white inverted.
 #
 testgrid_epsi=${tmpdir}/testgrid.epsi
diff --git a/urt/rle.h b/urt/rle.h
index 0766d22a..00717748 100644
--- a/urt/rle.h
+++ b/urt/rle.h
@@ -1,29 +1,29 @@
 /*
  * This software is copyrighted as noted below.  It may be freely copied,
- * modified, and redistributed, provided that the copyright notice is 
+ * modified, and redistributed, provided that the copyright notice is
  * preserved on all copies.
- * 
+ *
  * There is no warranty or other guarantee of fitness for this software,
  * it is provided solely "as is".  Bug reports or fixes may be sent
  * to the author, who may or may not act on them as he desires.
  *
  * You may not include this software in a program or other software product
- * without supplying the source, or without informing the end-user that the 
+ * without supplying the source, or without informing the end-user that the
  * source is available for no extra charge.
  *
  * If you modify this software, you should include a notice giving the
  * name of the person performing the modification, the date of modification,
  * and the reason for such modification.
  */
-/* 
+/*
  * rle.h - Global declarations for Utah Raster Toolkit RLE programs.
- * 
+ *
  * Author:  Todd W. Fuqua
  *      Computer Science Dept.
  *      University of Utah
  * Date:    Sun Jul 29 1984
  * Copyright (c) 1984 Todd W. Fuqua
- * 
+ *
  * $Id: rle.h,v 3.0.1.5 1992/04/30 14:05:56 spencer Exp $
  */
 
@@ -69,14 +69,6 @@ typedef unsigned short rle_map;
  */
 #define RLE_INIT_MAGIC  0x6487ED51L
 
-/*****************************************************************
- * TAG( RLE_CHECK_ALLOC )
- *
- * Test for allocation failure, scream and die if so.
- */
-#define RLE_CHECK_ALLOC( pgm, ptr, name )               \
-    ( !(ptr) ?  rle_alloc_error( pgm, name ) : 0 )
-
 /*
  * TAG( rle_hdr )
  *
@@ -103,10 +95,10 @@ typedef
         rle_map * cmap;       /* Pointer to color map array. */
         const char ** comments; /* Pointer to array of pointers to comments. */
         FILE *    rle_file;   /* Input or output file. */
-        /* 
+        /*
          * Bit map of channels to read/save.  Indexed by (channel mod 256).
          * Alpha channel sets bit 255.
-         * 
+         *
          * Indexing (0 <= c <= 255):
          *      bits[c/8] & (1 << (c%8))
          */
@@ -119,12 +111,12 @@ typedef
             char    bits[256/8];
             /* Set to magic pattern if following fields are initialized. */
             /* This gives a 2^(-32) chance of missing. */
-            long int is_init;   
+            long int is_init;
             /* Command, file name and image number for error messages. */
             const char *cmd;
             const char *file_name;
             int img_num;
-            /* 
+            /*
              * Local storage for rle_getrow & rle_putrow.
              * rle_getrow has
              *      scan_y  int     current Y scanline.
@@ -153,7 +145,7 @@ rle_hdr             /* End of typedef. */
 #endif
 ;
 
-/* 
+/*
  * TAG( rle_dflt_hdr )
  *
  * Global variable with possibly useful default values.
@@ -163,15 +155,6 @@ extern rle_hdr rle_dflt_hdr;
 
 /* Declare RLE library routines. */
 
-/* From rle_error.c. */
-/*****************************************************************
- * TAG( rle_alloc_error )
- * 
- * Print memory allocation error message and exit.
- */
-extern int rle_alloc_error( const char *pgm,
-                            const char *name );
-
 /*****************************************************************
  * TAG( rle_get_error )
  *
@@ -181,12 +164,12 @@ extern int rle_alloc_error( const char *pgm,
 extern int rle_get_error( int code,
                           const char *pgmname,
                           const char *fname );
-              
+
 /* From rle_getrow.c */
 
 /*****************************************************************
  * TAG( rle_debug )
- * 
+ *
  * Turn RLE debugging on or off.
  */
 extern void rle_debug( int on_off );
@@ -199,7 +182,7 @@ rle_get_setup(rle_hdr * const the_hdr);
  *
  * Call rle_get_setup.  If it returns an error code, call
  * rle_get_error to print the error message, then exit with the error
- * code. 
+ * code.
  */
 extern void rle_get_setup_ok( rle_hdr *the_hdr,
                               const char *prog_name,
@@ -210,7 +193,7 @@ extern void rle_get_setup_ok( rle_hdr *the_hdr,
  *
  * Read a scanline worth of data from an RLE file.
  */
-extern int rle_getrow( rle_hdr * the_hdr, 
+extern int rle_getrow( rle_hdr * the_hdr,
                        rle_pixel * scanline[] );
 
 /* From rle_getskip.c */
@@ -235,7 +218,7 @@ extern void rle_names( rle_hdr *the_hdr,
 
 /*****************************************************************
  * TAG( rle_hdr_cp )
- * 
+ *
  * Make a "safe" copy of a rle_hdr structure.
  */
 extern rle_hdr * rle_hdr_cp( rle_hdr *from_hdr,
@@ -243,14 +226,14 @@ extern rle_hdr * rle_hdr_cp( rle_hdr *from_hdr,
 
 /*****************************************************************
  * TAG( rle_hdr_init )
- * 
+ *
  * Initialize a rle_hdr structure.
  */
 extern rle_hdr * rle_hdr_init( rle_hdr *the_hdr );
 
 /*****************************************************************
  * TAG( rle_hdr_clear )
- * 
+ *
  */
 extern void rle_hdr_clear( rle_hdr *the_hdr );
 
@@ -326,7 +309,7 @@ extern int rle_row_alloc( rle_hdr * the_hdr,
 extern void rle_row_free( rle_hdr *the_hdr, rle_pixel **scanp );
 
 /* From buildmap.c. */
-/* 
+/*
  * buildmap - build a more usable colormap from data in the_hdr struct.
      */
 extern rle_pixel **buildmap( rle_hdr *the_hdr,
@@ -367,7 +350,7 @@ extern void bwdithermap( int levels, double gamma, int bwmap[],
  * TAG( ditherbw )
  * Dither a gray-scale value.
  */
-extern int ditherbw( int x, int y, int val, 
+extern int ditherbw( int x, int y, int val,
                      int divN[256], int modN[256], int magic[16][16] );
 /*****************************************************************
  * TAG( dithergb )
@@ -402,7 +385,7 @@ extern void float_to_exp( int count, float * floats, rle_pixel * pixels );
  * Open an input/output file with default.
  */
 FILE *
-rle_open_f(const char * prog_name, const char * file_name, 
+rle_open_f(const char * prog_name, const char * file_name,
            const char * mode);
 
 /*****************************************************************
@@ -412,16 +395,16 @@ rle_open_f(const char * prog_name, const char * file_name,
  */
 FILE *
 rle_open_f_noexit(const char * const prog_name,
-                  const char * const file_name, 
+                  const char * const file_name,
                   const char * const mode);
 
 /*****************************************************************
  * TAG( rle_close_f )
- * 
+ *
  * Close a file opened by rle_open_f.  If the file is stdin or stdout,
  * it will not be closed.
  */
-extern void 
+extern void
 rle_close_f( FILE *fd );
 
 /* From colorquant.c. */
diff --git a/urt/rle_error.c b/urt/rle_error.c
index 702c6e2d..801eee17 100644
--- a/urt/rle_error.c
+++ b/urt/rle_error.c
@@ -1,23 +1,23 @@
 /*
  * This software is copyrighted as noted below.  It may be freely copied,
- * modified, and redistributed, provided that the copyright notice is 
+ * modified, and redistributed, provided that the copyright notice is
  * preserved on all copies.
- * 
+ *
  * There is no warranty or other guarantee of fitness for this software,
  * it is provided solely "as is".  Bug reports or fixes may be sent
  * to the author, who may or may not act on them as he desires.
  *
  * You may not include this software in a program or other software product
- * without supplying the source, or without informing the end-user that the 
+ * without supplying the source, or without informing the end-user that the
  * source is available for no extra charge.
  *
  * If you modify this software, you should include a notice giving the
  * name of the person performing the modification, the date of modification,
  * and the reason for such modification.
  */
-/* 
+/*
  * rle_error.c - Error message stuff for URT.
- * 
+ *
  * Author:	Spencer W. Thomas
  * 		EECS Dept.
  * 		University of Michigan
@@ -31,38 +31,8 @@
 #include "rle.h"
 
 /*****************************************************************
- * TAG( rle_alloc_error )
- * 
- * Print memory allocation error message and exit.
- * Inputs:
- * 	pgm:		Name of this program.
- * 	name:		Name of memory trying to be allocated.
- * Outputs:
- * 	Prints message and exits.
- *
- * Returns int because it's used in a conditional expression.
- */
-int
-rle_alloc_error( pgm, name )
-CONST_DECL char *pgm, *name;
-{
-    if ( !name )
-	fprintf( stderr, "%s: memory allocation failed.\n", pgm );
-    else
-	fprintf( stderr, "%s: memory allocation failed (no space for %s).\n",
-		 pgm, name );
-
-    exit( RLE_NO_SPACE );
-
-    /* Will some compilers bitch about this because they know exit
-     * doesn't return??
-     */
-    return 0;
-}
-
-/*****************************************************************
  * TAG( rle_get_error )
- * 
+ *
  * Print an error message for the return code from rle_get_setup
  * Inputs:
  * 	code:		The return code from rle_get_setup.
@@ -74,44 +44,44 @@ CONST_DECL char *pgm, *name;
  */
 int
 rle_get_error( code, pgmname, fname )
-int code;
-CONST_DECL char *pgmname;
-CONST_DECL char *fname;
+    int code;
+    CONST_DECL char *pgmname;
+    CONST_DECL char *fname;
 {
     if (! fname || strcmp( fname, "-" ) == 0 )
-	fname = "Standard Input";
+        fname = "Standard Input";
 
     switch( code )
     {
     case RLE_SUCCESS:		/* success */
-	break;
+        break;
 
     case RLE_NOT_RLE:		/* Not an RLE file */
-	fprintf( stderr, "%s: %s is not an RLE file\n",
-		 pgmname, fname );
-	break;
+        fprintf( stderr, "%s: %s is not an RLE file\n",
+                 pgmname, fname );
+        break;
 
     case RLE_NO_SPACE:			/* malloc failed */
-	fprintf( stderr,
-		 "%s: Malloc failed reading header of file %s\n",
-		 pgmname, fname );
-	break;
+        fprintf( stderr,
+                 "%s: Malloc failed reading header of file %s\n",
+                 pgmname, fname );
+        break;
 
     case RLE_EMPTY:
-	fprintf( stderr, "%s: %s is an empty file\n",
-		 pgmname, fname );
-	break;
+        fprintf( stderr, "%s: %s is an empty file\n",
+                 pgmname, fname );
+        break;
 
     case RLE_EOF:
-	fprintf( stderr,
-		 "%s: RLE header of %s is incomplete (premature EOF)\n",
-		 pgmname, fname );
-	break;
+        fprintf( stderr,
+                 "%s: RLE header of %s is incomplete (premature EOF)\n",
+                 pgmname, fname );
+        break;
 
     default:
-	fprintf( stderr, "%s: Error encountered reading header of %s\n",
-		 pgmname, fname );
-	break;
+        fprintf( stderr, "%s: Error encountered reading header of %s\n",
+                 pgmname, fname );
+        break;
     }
     return code;
 }
diff --git a/urt/rle_getrow.c b/urt/rle_getrow.c
index 679811cc..ae220f5b 100644
--- a/urt/rle_getrow.c
+++ b/urt/rle_getrow.c
@@ -102,9 +102,13 @@ rle_get_setup(rle_hdr * const the_hdr) {
         rle_pixel * bg_color;
 
         MALLOCARRAY(the_hdr->bg_color, setup.h_ncolors);
+        if (!the_hdr->bg_color)
+            pm_error("Failed to allocation array for %u background colors",
+                     setup.h_ncolors);
         MALLOCARRAY(bg_color, 1 + (setup.h_ncolors / 2) * 2);
-        RLE_CHECK_ALLOC(the_hdr->cmd, the_hdr->bg_color && bg_color,
-                        "background color" );
+        if (!bg_color)
+            pm_error("Failed to allocation array for %u background colors",
+                     1+(setup.h_ncolors / 2) * 2);
         fread((char *)bg_color, 1, 1 + (setup.h_ncolors / 2) * 2, infile);
         for (i = 0; i < setup.h_ncolors; ++i)
             the_hdr->bg_color[i] = bg_color[i];
diff --git a/urt/rle_hdr.c b/urt/rle_hdr.c
index 1611324c..1edb7a3f 100644
--- a/urt/rle_hdr.c
+++ b/urt/rle_hdr.c
@@ -1,298 +1,286 @@
 /*
  * This software is copyrighted as noted below.  It may be freely copied,
- * modified, and redistributed, provided that the copyright notice is 
+ * modified, and redistributed, provided that the copyright notice is
  * preserved on all copies.
- * 
+ *
  * There is no warranty or other guarantee of fitness for this software,
  * it is provided solely "as is".  Bug reports or fixes may be sent
  * to the author, who may or may not act on them as he desires.
  *
  * You may not include this software in a program or other software product
- * without supplying the source, or without informing the end-user that the 
+ * without supplying the source, or without informing the end-user that the
  * source is available for no extra charge.
  *
  * If you modify this software, you should include a notice giving the
  * name of the person performing the modification, the date of modification,
  * and the reason for such modification.
  */
-/* 
+/*
  * rle_hdr.c - Functions to manipulate rle_hdr structures.
- * 
- * Author:	Spencer W. Thomas
- * 		EECS Dept.
- * 		University of Michigan
- * Date:	Mon May 20 1991
+ *
+ * Author:  Spencer W. Thomas
+ *      EECS Dept.
+ *      University of Michigan
+ * Date:    Mon May 20 1991
  * Copyright (c) 1991, University of Michigan
  */
 
 #include <string.h>
 
+#include "nstring.h"
+#include "mallocvar.h"
+
 #include "rle_config.h"
 #include "rle.h"
 
-/*****************************************************************
- * TAG( rle_names )
- *
+
+
+void
+rle_names(rle_hdr *    const hdrP,
+          const char * const pgmname,
+          const char * const fname,
+          int          const imgNum) {
+/*---------------------------------------------------------------------------- 
  * Load program and file names into header.
  * Inputs:
- * 	the_hdr:	Header to modify.
- * 	pgmname:	The program name.
- * 	fname:		The file name.
- * 	img_num:	Number of the image within the file.
+ *  hdrP:      Header to modify.
+ *  pgmname:   The program name.
+ *  fname:     The file name.
+ *  imgNum:    Number of the image within the file.
  * Outputs:
- * 	the_hdr:	Modified header.
- * Algorithm:
- * 	If values previously filled in (by testing is_init field),
- * 	free them.  Make copies of file name and program name,
- * 	modifying file name for standard i/o.  Set is_init field.
- */
-void
-rle_names( the_hdr, pgmname, fname, img_num )
-rle_hdr *the_hdr;
-CONST_DECL char *pgmname;
-CONST_DECL char *fname;
-int img_num;
-{
-#if 0
-    /* Can't do this because people do hdr1 = hdr2, which copies
-       the pointers. */
-
-    /* If filled in, free previous values. */
-    if ( the_hdr->is_init == RLE_INIT_MAGIC &&
-	 the_hdr->cmd != NULL && the_hdr->file_name != NULL )
-    {
-	if ( pgmname != the_hdr->cmd )
-	    free( the_hdr->cmd );
-	if ( fname != the_hdr->file_name )
-	    free( the_hdr->file_name );
-    }
-#endif
+ *  *hdrP:     Modified header.
+-----------------------------------------------------------------------------*/
+
+    /* Algorithm:
+       If values previously filled in (by testing is_init field),
+       free them.  Make copies of file name and program name,
+       modifying file name for standard i/o.  Set is_init field.
+    */
+    const char * newFname;
+    const char * newPgmname;
 
     /* Mark as filled in. */
-    the_hdr->is_init = RLE_INIT_MAGIC;
+    hdrP->is_init = RLE_INIT_MAGIC;
 
     /* Default file name for stdin/stdout. */
-    if ( fname == NULL || strcmp( fname, "-" ) == 0 || *fname == '\0' )
-	fname = "Standard I/O";
-    if ( pgmname == NULL )
-	pgmname = rle_dflt_hdr.cmd;
+    if (!fname || streq(fname, "-") || strlen(fname) == 0)
+        newFname = "Standard I/O";
+    else
+        newFname = fname;
+
+    if (pgmname)
+        newPgmname = pgmname;
+    else
+        newPgmname = rle_dflt_hdr.cmd;
 
     /* Fill in with copies of the strings. */
-    if ( the_hdr->cmd != pgmname )
-    {
-	char *tmp = (char *)malloc( strlen( pgmname ) + 1 );
-	RLE_CHECK_ALLOC( pgmname, tmp, 0 );
-	strcpy( tmp, pgmname );
-	the_hdr->cmd = tmp;
-    }
+    if (hdrP->cmd != newPgmname)
+        hdrP->cmd = pm_strdup(newPgmname);
 
-    if ( the_hdr->file_name != fname )
-    {
-	char *tmp = (char *)malloc( strlen( fname ) + 1 );
-	RLE_CHECK_ALLOC( pgmname, tmp, 0 );
-	strcpy( tmp, fname );
-	the_hdr->file_name = tmp;
-    }
+    if (hdrP->file_name != newFname)
+        hdrP->cmd = pm_strdup(newFname);
 
-    the_hdr->img_num = img_num;
+    hdrP->img_num = imgNum;
 }
 
 
+
 /* Used by rle_hdr_cp and rle_hdr_init to avoid recursion loops. */
-static int no_recurse = 0;
+static int noRecurse = 0;
 
-/*****************************************************************
- * TAG( rle_hdr_cp )
- * 
+
+
+rle_hdr *
+rle_hdr_cp(rle_hdr * const fromHdrP,
+           rle_hdr * const toHdrArgP) {
+/*----------------------------------------------------------------------------
  * Make a "safe" copy of a rle_hdr structure.
  * Inputs:
- * 	from_hdr:	Header to be copied.
+ *  *fromHdrP:   Header to be copied.
  * Outputs:
- * 	to_hdr:		Copy of from_hdr, with all memory referred to
- * 			by pointers copied.  Also returned as function
- * 			value.  If NULL, a static header is used.
+ *  *toHdrPd:    Copy of from_hdr, with all memory referred to
+ *               by pointers copied.  Also returned as function
+ *               value.  If NULL, a static header is used.
  * Assumptions:
- * 	It is safe to call rle_hdr_init on to_hdr.
- * Algorithm:
- * 	Initialize to_hdr, copy from_hdr to it, then copy the memory
- * 	referred to by all non-null pointers.
- */
-rle_hdr *
-rle_hdr_cp( from_hdr, to_hdr )
-rle_hdr *from_hdr, *to_hdr;
-{
-    static rle_hdr dflt_hdr;
-    CONST_DECL char *cmd, *file;
-    int num;
+ *  It is safe to call rle_hdr_init on *toHdrP.
+-----------------------------------------------------------------------------*/
+    /* Algorithm:
+       Initialize *toHdrP, copy *fromHdrP to it, then copy the memory
+       referred to by all non-null pointers.
+    */
+    static rle_hdr dfltHdr;
+    rle_hdr * toHdrP;
+    const char * cmd;
+    const char * file;
+    unsigned int num;
 
     /* Save command, file name, and image number if already initialized. */
-    if ( to_hdr &&  to_hdr->is_init == RLE_INIT_MAGIC )
-    {
-	cmd = to_hdr->cmd;
-	file = to_hdr->file_name;
-	num = to_hdr->img_num;
-    }
-    else
-    {
-	cmd = file = NULL;
-	num = 0;
+    if (toHdrArgP &&  toHdrArgP->is_init == RLE_INIT_MAGIC) {
+        cmd  = toHdrArgP->cmd;
+        file = toHdrArgP->file_name;
+        num  = toHdrArgP->img_num;
+    } else {
+        cmd = file = NULL;
+        num = 0;
     }
 
-    if ( !no_recurse )
-    {
-	no_recurse++;
-	rle_hdr_init( to_hdr );
-	no_recurse--;
+    if (!noRecurse) {
+        ++noRecurse;
+        rle_hdr_init(toHdrArgP);
+        --noRecurse;
     }
 
-    if ( to_hdr == NULL )
-	to_hdr = &dflt_hdr;
+    toHdrP = toHdrArgP ? toHdrArgP : &dfltHdr;
+
+    *toHdrP = *fromHdrP;
 
-    *to_hdr = *from_hdr;
+    if (toHdrP->bg_color) {
+        unsigned int i;
 
-    if ( to_hdr->bg_color )
-    {
-	int size = to_hdr->ncolors * sizeof(int);
-	to_hdr->bg_color = (int *)malloc( size );
-	RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->bg_color, "background color" );
-	memcpy( to_hdr->bg_color, from_hdr->bg_color, size );
+        MALLOCARRAY(toHdrP->bg_color, toHdrP->ncolors);
+        if (!toHdrP->bg_color)
+            pm_error("Failed to allocate array for %u background colors",
+                     toHdrP->ncolors);
+        for (i = 0; i < toHdrP->ncolors; ++i)
+            toHdrP->bg_color[i] = fromHdrP->bg_color[i];
     }
 
-    if ( to_hdr->cmap )
-    {
-	int size = to_hdr->ncmap * (1 << to_hdr->cmaplen) * sizeof(rle_map);
-	to_hdr->cmap = (rle_map *)malloc( size );
-	RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->cmap, "color map" );
-	memcpy( to_hdr->cmap, from_hdr->cmap, size );
+    if (toHdrP->cmap) {
+        size_t const size =
+            toHdrP->ncmap * (1 << toHdrP->cmaplen) * sizeof(rle_map);
+        toHdrP->cmap = malloc(size);
+        if (!toHdrP->cmap)
+            pm_error("Failed to allocate memory for %u color maps "
+                     "of length %u", toHdrP->ncmap, 1 << toHdrP->cmaplen);
+        memcpy(toHdrP->cmap, fromHdrP->cmap, size);
     }
 
     /* Only copy array of pointers, as the original comment memory
      * never gets overwritten.
      */
-    if ( to_hdr->comments )
-    {
-	int size = 0;
-	CONST_DECL char **cp;
-	for ( cp=to_hdr->comments; *cp; cp++ )
-	    size++;		/* Count the comments. */
-	/* Check if there are really any comments. */
-	if ( size )
-	{
-	    size++;		/* Copy the NULL pointer, too. */
-	    size *= sizeof(char *);
-	    to_hdr->comments = (CONST_DECL char **)malloc( size );
-	    RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->comments, "comments" );
-	    memcpy( to_hdr->comments, from_hdr->comments, size );
-	}
-	else
-	    to_hdr->comments = NULL;	/* Blow off empty comment list. */
+    if (toHdrP->comments) {
+        unsigned int  size;
+        const char ** cp;
+
+        /* Count the comments. */
+        for (cp = toHdrP->comments, size = 0; *cp; ++cp)
+            ++size;
+
+        /* Check if there are really any comments. */
+        if (size > 0) {
+            ++size;     /* Copy the NULL pointer, too. */
+            size *= sizeof(char *);
+            toHdrP->comments = malloc(size);
+            if (!toHdrP->comments)
+                pm_error("Failed to allocation %u bytes for comments", size);
+            memcpy(toHdrP->comments, fromHdrP->comments, size);
+        } else
+            toHdrP->comments = NULL;    /* Blow off empty comment list. */
     }
 
     /* Restore the names to their original values. */
-    to_hdr->cmd = cmd;
-    to_hdr->file_name = file;
+    toHdrP->cmd       = cmd;
+    toHdrP->file_name = file;
 
     /* Lines above mean nothing much happens if cmd and file are != NULL. */
-    rle_names( to_hdr, to_hdr->cmd, to_hdr->file_name, num );
+    rle_names(toHdrP, toHdrP->cmd, toHdrP->file_name, num);
 
-    return to_hdr;
+    return toHdrP;
 }
 
-/*****************************************************************
- * TAG( rle_hdr_clear )
- * 
+
+
+void
+rle_hdr_clear(rle_hdr * const hdrP) {
+/*----------------------------------------------------------------------------
  * Clear out the allocated memory pieces of a header.
  *
  * This routine is intended to be used internally by the library, to
  * clear a header before putting new data into it.  It clears all the
  * fields that would be set by reading in a new image header.
  * Therefore, it does not clear the program and file names.
- * 
+ *
  * Inputs:
- * 	the_hdr:	To be cleared.
+ *  hdrP:    To be cleared.
  * Outputs:
- * 	the_hdr:	After clearing.
+ *  *hdrP:   After clearing.
  * Assumptions:
- * 	If is_init field is RLE_INIT_MAGIC, the header has been
- * 	properly initialized.  This will fail every 2^(-32) times, on
- * 	average.
- * Algorithm:
- * 	Free memory and set to zero all pointers, except program and
- * 	file name.
- */
-void
-rle_hdr_clear( the_hdr )
-rle_hdr *the_hdr;
-{
+ *  If is_init field is RLE_INIT_MAGIC, the header has been
+ *  properly initialized.  This will fail every 2^(-32) times, on
+ *  average.
+-----------------------------------------------------------------------------*/
+    /* Algorithm:
+       Free memory and set to zero all pointers, except program and
+       file name.
+    */
+
     /* Try to free memory.  Assume if is_init is properly set that this
      * header has been previously initialized, therefore it is safe to
      * free memory.
      */
-    if ( the_hdr && the_hdr->is_init == RLE_INIT_MAGIC )
-    {
-	if ( the_hdr->bg_color )
-	    free( the_hdr->bg_color );
-	the_hdr->bg_color = 0;
-	if ( the_hdr->cmap )
-	    free( the_hdr->cmap );
-	the_hdr->cmap = 0;
-	/* Unfortunately, we don't know how to free the comment memory. */
-	if ( the_hdr->comments )
-	    free( the_hdr->comments );
-	the_hdr->comments = 0;
+    if (hdrP && hdrP->is_init == RLE_INIT_MAGIC) {
+        if (hdrP->bg_color )
+            free(hdrP->bg_color);
+        hdrP->bg_color = NULL;
+        if (hdrP->cmap )
+            free(hdrP->cmap);
+        hdrP->cmap = NULL;
+        /* Unfortunately, we don't know how to free the comment memory. */
+        if (hdrP->comments)
+            free(hdrP->comments);
+        hdrP->comments = NULL;
     }
 }
 
 
 
-/*****************************************************************
- * TAG( rle_hdr_init )
- * 
+rle_hdr *
+rle_hdr_init(rle_hdr * const hdrP) {
+/*----------------------------------------------------------------------------
  * Initialize a rle_hdr structure.
  * Inputs:
- * 	the_hdr:	Header to be initialized.
+ *  hdrP:    Header to be initialized.
  * Outputs:
- * 	the_hdr:	Initialized header.
+ *  *hdrP:   Initialized header.
  * Assumptions:
- * 	If the_hdr->is_init is RLE_INIT_MAGIC, the header has been
- * 	previously initialized.
- * 	If the_hdr is a copy of another rle_hdr structure, the copy
- * 	was made with rle_hdr_cp.
- * Algorithm:
- *  Fill in fields of rle_dflt_hdr that could not be set by the loader
- *	If the_hdr is rle_dflt_hdr, do nothing else
- *  Else:
- *	  If the_hdr is NULL, return a copy of rle_dflt_hdr in static storage
- * 	  If the_hdr->is_init is RLE_INIT_MAGIC, free all memory
- * 	     pointed to by non-null pointers.
- *    If this is a recursive call to rle_hdr_init, clear *the_hdr and
- *      return the_hdr.
- *    Else make a copy of rle_dflt_hdr and return its address.  Make the
- *      copy in static storage if the_hdr is NULL, and in the_hdr otherwise.
- */
-rle_hdr *
-rle_hdr_init( the_hdr )
-rle_hdr *the_hdr;
-{
-    rle_hdr *ret_hdr;
+ *  If hdrP->is_init is RLE_INIT_MAGIC, the header has been
+ *  previously initialized.
+ *  If the_hdr is a copy of another rle_hdr structure, the copy
+ *  was made with rle_hdr_cp.
+-----------------------------------------------------------------------------*/
+    /* Algorithm:
+       Fill in fields of rle_dflt_hdr that could not be set by the loader
+       If the_hdr is rle_dflt_hdr, do nothing else
+       Else:
+         If hdrP is NULL, return a copy of rle_dflt_hdr in static storage
+         If hdrP->is_init is RLE_INIT_MAGIC, free all memory
+            pointed to by non-null pointers.
+         If this is a recursive call to rle_hdr_init, clear *hdrP and
+           return hdrP.
+         Else make a copy of rle_dflt_hdr and return its address.  Make the
+           copy in static storage if hdrP is NULL, and in *hdrP otherwise.
+    */
+    rle_hdr * retval;
 
     rle_dflt_hdr.rle_file = stdout;
-    /* The rest of rle_dflt_hdr is set by the loader's data initialization */
 
-    if ( the_hdr == &rle_dflt_hdr )
-	return the_hdr;
+    /* The rest of rle_dflt_hdr is set by the loader's data initialization */
 
-    rle_hdr_clear( the_hdr );
+    if (hdrP == &rle_dflt_hdr)
+        retval = hdrP;
+    else {
+        rle_hdr_clear(hdrP);
 
-    /* Only call rle_hdr_cp if not called from there. */
-    if ( !no_recurse )
-    {
-	no_recurse++;
-	ret_hdr = rle_hdr_cp( &rle_dflt_hdr, the_hdr );
-	no_recurse--;
+        /* Call rle_hdr_cp only if not called from there. */
+        if (!noRecurse) {
+            ++noRecurse;
+            retval = rle_hdr_cp(&rle_dflt_hdr, hdrP);
+            --noRecurse;
+        } else
+            retval = hdrP;
     }
-    else
-	ret_hdr = the_hdr;
-
-    return ret_hdr;
+    return retval;
 }
+
+
+
diff --git a/version.mk b/version.mk
index d5b64dfc..52523535 100644
--- a/version.mk
+++ b/version.mk
@@ -1,3 +1,3 @@
 NETPBM_MAJOR_RELEASE = 10
 NETPBM_MINOR_RELEASE = 87
-NETPBM_POINT_RELEASE = 3
+NETPBM_POINT_RELEASE = 99