about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2024-03-30 18:31:01 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2024-03-30 18:31:01 +0000
commit81c59f730dacf62c927eb57dcadeecffe8b8daea (patch)
treea67cc5906891e0965c3a9d8cea80deacbc7f1930
parent19387d1be30e80e8c4e865bfe053aed1094ca8af (diff)
downloadnetpbm-mirror-81c59f730dacf62c927eb57dcadeecffe8b8daea.tar.gz
netpbm-mirror-81c59f730dacf62c927eb57dcadeecffe8b8daea.tar.xz
netpbm-mirror-81c59f730dacf62c927eb57dcadeecffe8b8daea.zip
promote Development to Advanced
git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@4897 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r--analyzer/pamfile.c4
-rw-r--r--analyzer/pamfind.c4
-rw-r--r--analyzer/pamgetcolor.c4
-rw-r--r--analyzer/pamslice.c2
-rw-r--r--analyzer/pamsumm.c4
-rw-r--r--analyzer/pamtable.c4
-rw-r--r--analyzer/pamtilt.c2
-rw-r--r--analyzer/pgmhist.c2
-rw-r--r--analyzer/pgmtexture.c4
-rw-r--r--analyzer/pnmhistmap.c4
-rw-r--r--analyzer/pnmpsnr.c4
-rw-r--r--analyzer/ppmhist.c2
-rwxr-xr-xbuildtools/makeman4
-rw-r--r--converter/other/bmptopnm.c6
-rw-r--r--converter/other/fitstopnm.c5
-rw-r--r--converter/other/giftopnm.c7
-rw-r--r--converter/other/hdifftopam.c36
-rw-r--r--converter/other/infotopam.c633
-rw-r--r--converter/other/pamtogif.c364
-rw-r--r--converter/other/pamtopdbimg.c6
-rw-r--r--converter/other/pamtopng.c2
-rw-r--r--converter/other/pamtopnm.c6
-rw-r--r--converter/other/pamtoqoi.c6
-rw-r--r--converter/other/pamtosrf.c6
-rw-r--r--converter/other/pamtotga.c2
-rw-r--r--converter/other/pamtotiff.c2
-rw-r--r--converter/other/pamtowinicon.c2
-rw-r--r--converter/other/pdbimgtopam.c6
-rw-r--r--converter/other/pgmtopbm.c6
-rw-r--r--converter/other/pgmtoppm.c7
-rw-r--r--converter/other/pngtopam.c6
-rw-r--r--converter/other/pnmtojpeg.c6
-rw-r--r--converter/other/pnmtopng.c6
-rw-r--r--converter/other/pnmtops.c2
-rw-r--r--converter/other/pnmtorle.c6
-rw-r--r--converter/other/qoitopam.c6
-rw-r--r--converter/other/rasttopnm.c6
-rw-r--r--converter/other/sgitopnm.c6
-rw-r--r--converter/other/srftopam.c6
-rw-r--r--converter/other/tifftopnm.c4
-rw-r--r--converter/other/winicontopam.c2
-rw-r--r--converter/other/xwdtopnm.c6
-rw-r--r--converter/other/yuy2topam.c5
-rw-r--r--converter/pbm/g3topbm.c3
-rw-r--r--converter/pbm/pbmtoepsi.c20
-rw-r--r--converter/pbm/pbmtoepson.c7
-rw-r--r--converter/pbm/pbmtoescp2.c9
-rw-r--r--converter/pbm/pbmtog3.c6
-rw-r--r--converter/pbm/pbmtolj.c6
-rw-r--r--converter/pbm/pbmtolps.c4
-rw-r--r--converter/pbm/pbmtomacp.c3
-rw-r--r--converter/pbm/pbmtomda.c4
-rw-r--r--converter/pbm/pbmtoxbm.c4
-rw-r--r--converter/pbm/pi3topbm.c3
-rw-r--r--converter/pbm/pktopbm.c4
-rw-r--r--converter/pgm/rawtopgm.c4
-rw-r--r--converter/pgm/sbigtopgm.c4
-rw-r--r--converter/ppm/411toppm.c4
-rw-r--r--converter/ppm/pcxtoppm.c12
-rw-r--r--converter/ppm/picttoppm.c3
-rw-r--r--converter/ppm/ppmtoarbtxt.c4
-rw-r--r--converter/ppm/ppmtoascii.c3
-rw-r--r--converter/ppm/ppmtobmp.c9
-rw-r--r--converter/ppm/ppmtogif.c7
-rw-r--r--converter/ppm/ppmtoicr.c10
-rw-r--r--converter/ppm/ppmtopcx.c9
-rw-r--r--converter/ppm/ppmtosixel.c2
-rw-r--r--converter/ppm/ppmtospu.c7
-rw-r--r--converter/ppm/ppmtoterm.c8
-rw-r--r--converter/ppm/ppmtowinicon.c60
-rw-r--r--converter/ppm/ppmtoxpm.c10
-rw-r--r--converter/ppm/winicontoppm.c9
-rw-r--r--converter/ppm/ximtoppm.c6
-rw-r--r--converter/ppm/yuvtoppm.c3
-rw-r--r--doc/HISTORY35
-rw-r--r--editor/pambackground.c2
-rw-r--r--editor/pamcut.c259
-rw-r--r--editor/pamditherbw.c97
-rw-r--r--editor/pammasksharpen.c2
-rw-r--r--editor/pamscale.c5
-rw-r--r--generator/pamseq.c4
-rw-r--r--lib/colorname.c80
-rw-r--r--lib/libpamcolor.c51
-rw-r--r--lib/libpbm3.c18
-rw-r--r--lib/libpm.c11
-rw-r--r--lib/libppmcmap.c13
-rw-r--r--lib/libppmcolor.c81
-rw-r--r--lib/rgb.txt10
-rw-r--r--lib/util/shhopt.c649
-rw-r--r--lib/util/shhopt.h7
-rw-r--r--other/pamarith.c2
-rw-r--r--other/pambayer.c4
-rw-r--r--other/pamchannel.c4
-rw-r--r--other/pamdepth.c4
-rw-r--r--other/pamexec.c6
-rw-r--r--other/pamlookup.c2
-rw-r--r--other/pampick.c6
-rw-r--r--other/pamsplit.c6
-rw-r--r--other/pamstack.c4
-rw-r--r--other/pamsummcol.c2
-rw-r--r--other/pamunlookup.c2
-rw-r--r--other/pnmcolormap.c6
-rw-r--r--other/ppmsvgalib.c7
-rwxr-xr-xtest/Execute-Tests2
-rwxr-xr-xtest/pamarith.test258
-rw-r--r--test/pambrighten.ok24
-rwxr-xr-xtest/pambrighten.test56
-rwxr-xr-xtest/pamcat1.test84
-rwxr-xr-xtest/pamchannel.test19
-rwxr-xr-xtest/pamcrater.test34
-rw-r--r--test/pamcut.ok100
-rwxr-xr-xtest/pamcut.test302
-rwxr-xr-xtest/pamdepth.test16
-rwxr-xr-xtest/pamditherbw.test80
-rwxr-xr-xtest/pamfile.test32
-rwxr-xr-xtest/pamfind.test33
-rwxr-xr-xtest/pamfunc.test150
-rw-r--r--test/pamgauss.ok3
-rwxr-xr-xtest/pamgauss.test42
-rwxr-xr-xtest/pamhue.test15
-rwxr-xr-xtest/pamrecolor.test45
-rwxr-xr-xtest/pamrestack.test38
-rwxr-xr-xtest/pamscale-reportonly.test49
-rwxr-xr-xtest/pamseq.test33
-rwxr-xr-xtest/pamshuffle.test22
-rwxr-xr-xtest/pamstack.test27
-rwxr-xr-xtest/pamsumm.test33
-rw-r--r--test/pamtable.ok3
-rwxr-xr-xtest/pamtable.test17
-rwxr-xr-xtest/pbmclean.test13
-rwxr-xr-xtest/pbmmake.test57
-rw-r--r--test/pbmnoise-parameters.ok4
-rwxr-xr-xtest/pbmnoise-parameters.test164
-rwxr-xr-xtest/pbmpage.test24
-rwxr-xr-xtest/pbmpscale.test25
-rwxr-xr-xtest/pbmtopgm.test31
-rwxr-xr-xtest/pgmhist.test33
-rw-r--r--test/pgmmake.ok13
-rwxr-xr-xtest/pgmmake.test62
-rw-r--r--test/pgmnoise-parameters.ok2
-rwxr-xr-xtest/pgmnoise-parameters.test38
-rw-r--r--test/pgmramp.ok12
-rwxr-xr-xtest/pgmramp.test27
-rwxr-xr-xtest/pnmcat.test84
-rwxr-xr-xtest/pnmcolormap.test51
-rw-r--r--test/pnmindex.ok16
-rwxr-xr-xtest/pnmindex.test72
-rwxr-xr-xtest/pnmpsnr.test33
-rwxr-xr-xtest/pnmtile.test32
-rw-r--r--test/ppmbrighten.ok8
-rwxr-xr-xtest/ppmbrighten.test21
-rwxr-xr-xtest/ppmforge-parameters.test52
-rwxr-xr-xtest/ppmhist.test27
-rw-r--r--test/ppmmake.ok10
-rwxr-xr-xtest/ppmmake.test76
-rwxr-xr-xtest/ppmpat.test163
-rw-r--r--test/ppmtomitsu.ok12
-rwxr-xr-xtest/ppmtomitsu.test30
-rw-r--r--test/test-invalid.inc16
-rw-r--r--test/test1.infobin0 -> 989 bytes
-rw-r--r--test/test2.infobin0 -> 16230 bytes
-rw-r--r--version.mk4
162 files changed, 2334 insertions, 3234 deletions
diff --git a/analyzer/pamfile.c b/analyzer/pamfile.c
index 1cf764e2..80674710 100644
--- a/analyzer/pamfile.c
+++ b/analyzer/pamfile.c
@@ -40,7 +40,7 @@ parseCommandLine(int argc, const char ** argv,
    was passed to as as the argv array.
 -----------------------------------------------------------------------------*/
     optEntry * option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
+        /* Instructions to pm_optParseOptions4 on how to parse our options.
          */
     optStruct3 opt;
 
@@ -60,7 +60,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others */
 
     cmdlineP->inputFilespec = (const char **)&argv[1];
diff --git a/analyzer/pamfind.c b/analyzer/pamfind.c
index 15ca9e85..fb98aea3 100644
--- a/analyzer/pamfind.c
+++ b/analyzer/pamfind.c
@@ -23,7 +23,7 @@ parsedCommandLine(int                 argc,
                   const char ** const argv) {
 
     optEntry * option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
+        /* Instructions to OptParseOptions4 on how to parse our options.
          */
     optStruct3 opt;
 
@@ -46,7 +46,7 @@ parsedCommandLine(int                 argc,
     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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
 
     if (targetSpec + colorSpec > 1)
         pm_error("You cannot specify both -target and -color");
diff --git a/analyzer/pamgetcolor.c b/analyzer/pamgetcolor.c
index 2bd3050c..e7e9160d 100644
--- a/analyzer/pamgetcolor.c
+++ b/analyzer/pamgetcolor.c
@@ -250,7 +250,7 @@ parsedCommandLine(int                 argc,
                   const char ** const argv) {
 
     optEntry * option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
+        /* Instructions to OptParseOptions4 on how to parse our options.
          */
     optStruct3 opt;
 
@@ -273,7 +273,7 @@ parsedCommandLine(int                 argc,
     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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
 
     if (!infileSpec)
         cmdLine.infile = "-";
diff --git a/analyzer/pamslice.c b/analyzer/pamslice.c
index 5bdbea10..9d236441 100644
--- a/analyzer/pamslice.c
+++ b/analyzer/pamslice.c
@@ -50,7 +50,7 @@ parseCommandLine(int argc, char ** const argv,
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
     optEntry *option_def = malloc(100*sizeof(optEntry));
-        /* Instructions to OptParseOptions2 on how to parse our options.
+        /* Instructions to OptParseOptions3 on how to parse our options.
          */
     optStruct3 opt;
 
diff --git a/analyzer/pamsumm.c b/analyzer/pamsumm.c
index 03ff6749..e6c5aca8 100644
--- a/analyzer/pamsumm.c
+++ b/analyzer/pamsumm.c
@@ -32,7 +32,7 @@ parseCommandLine(int argc, const char ** const argv,
                  struct CmdlineInfo * const cmdlineP) {
 
     optEntry * option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
+        /* Instructions to OptParseOptions4 on how to parse our options.
          */
     optStruct3 opt;
 
@@ -55,7 +55,7 @@ parseCommandLine(int argc, const char ** const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (sumSpec + minSpec + maxSpec + meanSpec > 1)
diff --git a/analyzer/pamtable.c b/analyzer/pamtable.c
index acd027a6..333eff69 100644
--- a/analyzer/pamtable.c
+++ b/analyzer/pamtable.c
@@ -33,7 +33,7 @@ parseCommandLine(int argc, const char ** const argv,
                  struct CmdlineInfo * const cmdlineP) {
 
     optEntry * option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
+        /* Instructions to OptParseOptions4 on how to parse our options.
          */
     optStruct3 opt;
 
@@ -53,7 +53,7 @@ parseCommandLine(int argc, const char ** const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (tuple && cmdlineP->hex)
diff --git a/analyzer/pamtilt.c b/analyzer/pamtilt.c
index 2898d30f..031c4206 100644
--- a/analyzer/pamtilt.c
+++ b/analyzer/pamtilt.c
@@ -76,7 +76,7 @@ parseCommandLine(int argc, const char ** const argv,
     opt.opt_table = option_def;
     opt.short_allowed = FALSE;          /* no short options used */
     opt.allowNegNum = FALSE;            /* don't allow negative values */
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
 
     if (cmdlineP->hstep < 1)
         pm_error("-hstep must be at least 1 column.");
diff --git a/analyzer/pgmhist.c b/analyzer/pgmhist.c
index a85f0649..3b0b9b95 100644
--- a/analyzer/pgmhist.c
+++ b/analyzer/pgmhist.c
@@ -64,7 +64,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (cmdlineP->median + cmdlineP->quartile + cmdlineP->decile > 1)
diff --git a/analyzer/pgmtexture.c b/analyzer/pgmtexture.c
index 8a1678e2..938f9ef8 100644
--- a/analyzer/pgmtexture.c
+++ b/analyzer/pgmtexture.c
@@ -31,8 +31,6 @@ parseCommandLine(int argc, const char ** const argv,
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
     optEntry * option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
-         */
     optStruct3 opt;
     unsigned int option_def_index;
 
@@ -47,7 +45,7 @@ parseCommandLine(int argc, const char ** const argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = TRUE;  /* We may have parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (!dSpec)
diff --git a/analyzer/pnmhistmap.c b/analyzer/pnmhistmap.c
index e51bbb24..3c943db9 100644
--- a/analyzer/pnmhistmap.c
+++ b/analyzer/pnmhistmap.c
@@ -59,7 +59,7 @@ parseCommandLine(int argc, const char ** argv,
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
     optEntry *option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
+        /* Instructions to pm_optParseOptions4 on how to parse our options.
          */
     optStruct3 opt;
 
@@ -92,7 +92,7 @@ parseCommandLine(int argc, const char ** argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We may have parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (!lvalSpec)
diff --git a/analyzer/pnmpsnr.c b/analyzer/pnmpsnr.c
index 6543c542..031b714e 100644
--- a/analyzer/pnmpsnr.c
+++ b/analyzer/pnmpsnr.c
@@ -95,7 +95,7 @@ parseCommandLine(int argc, const char ** argv,
    was passed to as as the argv array.
 -----------------------------------------------------------------------------*/
     optEntry * option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
+        /* Instructions to pm_optParseOptions4 on how to parse our options.
          */
     optStruct3 opt;
 
@@ -123,7 +123,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others */
 
     if (argc-1 < 2)
diff --git a/analyzer/ppmhist.c b/analyzer/ppmhist.c
index 62345fa1..4bafe73c 100644
--- a/analyzer/ppmhist.c
+++ b/analyzer/ppmhist.c
@@ -69,7 +69,7 @@ parseCommandLine(int argc, const char ** argv,
     /* Set defaults */
     sort_type = "frequency";
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
     free(option_def);
 
diff --git a/buildtools/makeman b/buildtools/makeman
index 641ef856..6e4bb52b 100755
--- a/buildtools/makeman
+++ b/buildtools/makeman
@@ -183,7 +183,7 @@ def makeman(name, file, indoc):
     indoc = indoc.replace("&#174;", r"\*R")
     indoc = indoc.replace("&copy;", r"\(co")
     # Turn anchors into .UN tags
-    indoc = re.sub('(?i)<A NAME *= *"#?([a-zA-Z_][a-zA-Z_0-9.-]+)">(?:&nbsp;)*</A>\s*', ".UN \\1\n", indoc)
+    indoc = re.sub(r'(?i)<A NAME *= *"#?([a-zA-Z_][a-zA-Z_0-9.-]+)">(?:&nbsp;)*</A>\s*', ".UN \\1\n", indoc)
     # Strip off the index trailer
     trailer = re.compile('<HR */*>.*', re.DOTALL | re.IGNORECASE)
     indoc = re.sub(trailer, "", indoc)
@@ -218,7 +218,7 @@ def makeman(name, file, indoc):
     indoc = re.sub("(?i) *</DD>", "", indoc)
     # Process unordered lists -- just turn them into .TPs
     indoc = re.sub("(?i)</?[UO]L *(COMPACT)?>", "", indoc)
-    indoc = re.sub("(?i) *<LI>", ".IP \(bu\n", indoc)
+    indoc = re.sub("(?i) *<LI>", r".IP \(bu\n", indoc)
     indoc = re.sub("(?i) *</LI>", "", indoc)
     # No-print tags
     indoc = re.sub("<!--no_print-->.*", "", indoc)
diff --git a/converter/other/bmptopnm.c b/converter/other/bmptopnm.c
index eed428de..091d948a 100644
--- a/converter/other/bmptopnm.c
+++ b/converter/other/bmptopnm.c
@@ -140,9 +140,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the file spec array we return is stored in the storage that
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
-    optEntry * option_def;
-        /* Instructions to OptParseOptions2 on how to parse our options.
-         */
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -156,7 +154,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc-1 == 0)
diff --git a/converter/other/fitstopnm.c b/converter/other/fitstopnm.c
index ca621164..90bd16f1 100644
--- a/converter/other/fitstopnm.c
+++ b/converter/other/fitstopnm.c
@@ -88,8 +88,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the strings we return are stored in the storage that
    was passed to us as the argv array.  We also trash *argv.
 --------------------------------------------------------------------------*/
-    optEntry * option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options. */
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int imageSpec;
@@ -121,7 +120,7 @@ parseCommandLine(int argc, const char ** argv,
 
     /* Set some defaults the lazy way (using multiple setting of variables) */
 
-    pm_optParseOptions3(&argc, (char**)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (imageSpec) {
diff --git a/converter/other/giftopnm.c b/converter/other/giftopnm.c
index c1c79e26..55d7ccc6 100644
--- a/converter/other/giftopnm.c
+++ b/converter/other/giftopnm.c
@@ -113,10 +113,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the file spec array we return is stored in the storage that
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
-    optEntry * option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
-
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int alphaSpec, imageSpec;
@@ -144,7 +141,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     free(option_def);
diff --git a/converter/other/hdifftopam.c b/converter/other/hdifftopam.c
index 7464bb1a..1b058a78 100644
--- a/converter/other/hdifftopam.c
+++ b/converter/other/hdifftopam.c
@@ -10,15 +10,16 @@
 #include <stdio.h>
 
 #include "pm_c_util.h"
-#include "pam.h"
-#include "shhopt.h"
+#include "mallocvar.h"
 #include "nstring.h"
+#include "shhopt.h"
+#include "pam.h"
 
-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;  /* Filespecs of input files */
+    const char * inputFileNm;  /* Names of input files */
     unsigned int pnm;
     unsigned int verbose;
 };
@@ -26,19 +27,19 @@ struct cmdlineInfo {
 
 
 static void
-parseCommandLine(int argc, char ** argv,
-                 struct cmdlineInfo * const cmdlineP) {
+parseCommandLine(int argc, const char ** const argv,
+                 struct CmdlineInfo * const cmdlineP) {
 /*----------------------------------------------------------------------------
    Note that the file spec array we return is stored in the storage that
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def = malloc( 100*sizeof( optEntry ) );
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int option_def_index;
 
+    MALLOCARRAY_NOFAIL(option_def, 100);
+
     option_def_index = 0;   /* incremented by OPTENTRY */
     OPTENT3(0, "pnm",       OPT_FLAG,    NULL, &cmdlineP->pnm,      0);
     OPTENT3(0, "verbose",   OPT_FLAG,    NULL, &cmdlineP->verbose,  0);
@@ -47,13 +48,13 @@ 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_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc-1 < 1)
-        cmdlineP->inputFilespec = "-";
+        cmdlineP->inputFileNm = "-";
     else if (argc-1 == 1)
-        cmdlineP->inputFilespec = argv[1];
+        cmdlineP->inputFileNm = argv[1];
     else
         pm_error("Too many arguments.");
 }
@@ -88,20 +89,21 @@ static void
 
 
 int
-main(int argc, char *argv[]) {
-    FILE *ifP;
-    struct cmdlineInfo cmdline;
+main(int argc, const char ** argv) {
+
+    FILE * ifP;
+    struct CmdlineInfo cmdline;
     struct pam diffpam, outpam;
     unsigned int row;
     tuple * diffrow;
     tuple * outrow;
     tuple * prevrow;
 
-    pnm_init(&argc, argv);
+    pm_proginit(&argc, argv);
 
     parseCommandLine(argc, argv, &cmdline);
 
-    ifP = pm_openr(cmdline.inputFilespec);
+    ifP = pm_openr(cmdline.inputFileNm);
 
     pnm_readpaminit(ifP, &diffpam, PAM_STRUCT_SIZE(tuple_type));
 
diff --git a/converter/other/infotopam.c b/converter/other/infotopam.c
index 3467891c..e9ce4d04 100644
--- a/converter/other/infotopam.c
+++ b/converter/other/infotopam.c
@@ -29,10 +29,10 @@
  *
  * The icon data has the following format:
  *
- *   BIT-PLANE planes, each with HEIGHT rows of (WIDTH +15) / 16 * 2 bytes
- *   length.
+ *   BIT-PLANE planes, each with HEIGHT rows WIDTH bits long, rounded up to
+ *   a multiple of 2 bytes.
  *
- * So if you have a 9x3x2 icon, the icon data will look like this:
+ * So if you have a 9x3x2 icon, the icon data looks like this:
  *
  *   aaaa aaaa a000 0000
  *   aaaa aaaa a000 0000
@@ -45,9 +45,128 @@
  * bit-plane, and '0' is padding.  Thanks again to Ben Hutchings for his
  * very helpful post!
  *
- * This program uses code from "sidplay" and an older "infotoxpm" program I
- * wrote, both of which are released under GPL.
+ *-----------------------------------------------------------------------------
+ * The following specification for the DiskObject header is from
+ * http://amigadev.elowar.com/read/ADCD_2.1/Libraries_Manual_guide/node0241.html
+ * on 2024.03.14.
  *
+ * The DiskObject C structure is defined in the include file
+ * <workbench/workbench.h>.  For a complete listing, see the Amiga ROM Kernel
+ * Reference Manual: Includes and Autodocs.  The DiskObject structure contains
+ * the following elements:
+ *
+ *     struct DiskObject {
+ *         UWORD              do_Magic;    magic number at start of file
+ *         UWORD              do_Version;  so we can change structure
+ *         struct Gadget      do_Gadget;   a copy of in core gadget
+ *         UBYTE              do_Type;
+ *         char              *do_DefaultTool;
+ *         char             **do_ToolTypes;
+ *         LONG               do_CurrentX;
+ *         LONG               do_CurrentY;
+ *         struct DrawerData *do_DrawerData;
+ *         char              *do_ToolWindow;  applies only to tools
+ *         LONG               do_StackSize;   applies only to tools
+ *     };
+ *
+ * do_Magic
+ *
+ *     A magic number that the icon library looks for to make sure that the
+ *     file it is reading really contains an icon.  It should be the manifest
+ *     constant WB_DISKMAGIC.  PutDiskObject() will put this value in the
+ *     structure, and GetDiskObject() will not believe that a file is really
+ *     an icon unless this value is correct.
+ *
+ * do_Version
+ *
+ *     This provides a way to enhance the .info file in an upwardly-compatible
+ *     way.  It should be WB_DISKVERSION.  The icon library will set this value
+ *     for you and will not believe weird values.
+ *
+ * do_Gadget
+ *
+ *     This contains all the imagery for the icon. See the "Gadget Structure"
+ *     section below for more details.
+ *
+ * do_Type
+ *
+ *     The type of the icon; can be set to any of the following values.
+ *
+ *         WBDISK     The root of a disk
+ *         WBDRAWER   A directory on the disk
+ *         WBTOOL     An executable program
+ *         WBPROJECT  A data file
+ *         WBGARBAGE  The Trashcan directory
+ *         WBKICK     A Kickstart disk
+ *         WBAPPICON  Any object not directly associated with a filing system
+ *                    object, such as a print spooler (new in Release 2).
+ *
+ * do_DefaultTool
+ *
+ *     Default tools are used for project and disk icons.  For projects (data
+ *     files), the default tool is the program Workbench runs when the project
+ *     is activated.  Any valid AmigaDOS path may be entered in this field
+ *     such as "SYS:myprogram", "df0:mypaint", "myeditor" or ":work/mytool".
+ *
+ *     For disk icons, the default tool is the diskcopy program
+ *     ("SYS:System/DiskCopy") that will be used when this disk is the source
+ *     of a copy.
+ *
+ * do_ToolTypes
+ *
+ *     This is an array of free-format strings.  Workbench does not enforce
+ *     any rules on these strings, but they are useful for passing
+ *     environment information.  See the section on "The Tool Types Array"
+ *     below for more information.
+ *
+ * do_CurrentX, do_CurrentY
+ *
+ *     Drawers have a virtual coordinate system.  The user can scroll around
+ *     in this system using the scroll gadgets on the window that opens when
+ *     the drawer is activated.  Each icon in the drawer has a position in
+ *     the coordinate system.  CurrentX and CurrentY contain the icon's
+ *     current position in the drawer.  Picking a position for a newly
+ *     created icon can be tricky.  NO_ICON_POSITION is a system constant
+ *     for do_CurrentX and do_CurrentY that instructs Workbench to pick a
+ *     reasonable place for the icon.  Workbench will place the icon in an
+ *     unused region of the drawer.  If there is no space in the drawers
+ *     window, the icon will be placed just to the right of the visible
+ *     region.
+ *
+ * do_DrawerData
+ *
+ *     If the icon is associated with a directory (WBDISK, WBDRAWER,
+ *     WBGARBAGE), it needs a DrawerData structure to go with it.  This
+ *     structure contains an Intuition NewWindow structure (see the
+ *     "Intuition Windows" chapter for more information):
+ *
+ *         struct DrawerData {
+ *              struct NewWindow dd_NewWindow; structure to open window
+ *              LONG             dd_CurrentX;  current x coordinate of origin
+ *              LONG             dd_CurrentY;  current y coordinate of origin
+ *         };
+ *
+ *     Workbench uses this to hold the current window position and size of
+ *     the window so it will reopen in the same place.
+ *
+ * do_ToolWindow
+ *
+ *     This field is reserved for future use.
+ *
+ * do_StackSize
+ *
+ *     This is the size of the stack (in bytes) used for running the tool.
+ *     If this is NULL, then Workbench will use a reasonable default stack
+ *     size (currently 4K bytes).
+ *
+ *     When a tool is run via the default tool mechanism (i.e., a project
+ *     was activated, not the tool itself), Workbench uses the stack size
+ *     specified in the project's .info file and the tool's .info file is
+ *     ignored.
+ *
+ *-------------------------------------------------------------------------
+ * This program uses code from "sidplay" and an older "infotoxpm" program
+ * Richard Griswold wrote, both of which are offered under GPL.
  *-------------------------------------------------------------------------
  *
  * This program is free software; you can redistribute it and/or
@@ -65,42 +184,51 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
-#include "pm_c_util.h"
-#include "pam.h"
-#include "shhopt.h"
-#include "mallocvar.h"
-
-#include <errno.h>
-#include <stdio.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
+#include <stdio.h>
 
+#include "pm_c_util.h"
+#include "mallocvar.h"
+#include "nstring.h"
+#include "shhopt.h"
+#include "pam.h"
 
-/* Struct to hold miscellaneous icon information */
-typedef struct IconInfo_ {
-    const char  *name;        /* Icon file name */
-    FILE        *fp;          /* Input file pointer */
 
-    bool         forceColor;  /* Convert 1 bitplane icon to color icon */
-    unsigned int numColors;   /* Number of colors to override */
-    bool         selected;    /* Converting selected (second) icon */
+typedef struct CmdlineInfo_ {
+    const char  * inputFileNm;
+    unsigned int  forcecolor;
+    pixel         colors[4];   /* Colors to use for converted icons */
+    unsigned int  selected;
+    unsigned int  verbose;
+} CmdlineInfo;
 
-    bool         drawerData;  /* Icon has drawer data */
-    unsigned int version;     /* Icon version */
-    unsigned int width;       /* Width in pixels */
-    unsigned int height;      /* Height in pixels */
-    unsigned int depth;       /* Bits of color per pixel */
-    pixel        colors[4];   /* Colors to use for converted icons */
-    unsigned char *icon;      /* Completed icon */
+typedef struct IconInfo_ {
+    /* Miscellaneous icon information */
+    FILE *          ifP;            /* Input file */
+    bool            hasDrawerData;  /* Icon has drawer data */
+    unsigned int    version;        /* Icon version */
+    unsigned int    width;          /* Width in pixels */
+    unsigned int    height;         /* Height in pixels */
+    unsigned int    depth;          /* Bits of color per pixel */
+    unsigned int    bpwidth;
+        /* Bitplane width; Width of each row in icon, including padding */
+    unsigned char * icon;           /* Completed icon */
 
 } IconInfo;
 
-/* Header for each icon image */
 typedef struct IconHeader_ { /* 20 bytes */
-    unsigned char pad0[4];        /* Padding (always seems to be zero) */
+    /* Text of header for one icon image */
+    unsigned char type[4];
+        /* Reverse engineered.  This always seems to be 0x00000000 in
+           icon headers, but we've seen 0x00000010 in some 51-byte object
+           we don't understand.
+        */
     unsigned char iconWidth[2];   /* Width (usually equal to Gadget width) */
     unsigned char iconHeight[2];
-    /* Height (usually equal to Gadget height -1) */
+        /* Height (usually equal to Gadget height -1) */
     unsigned char bpp[2];         /* Bits per pixel */
     unsigned char pad1[10];       /* ??? */
 } IconHeader;
@@ -110,6 +238,7 @@ typedef struct IconHeader_ { /* 20 bytes */
  * http://www.geocities.com/SiliconValley/Lakes/5147/sidplay/linux.html
  */
 typedef struct DiskObject_ { /* 78 bytes (including Gadget struct) */
+    /* Text of Info Disk Object header */
     unsigned char magic[2];         /* Magic number at the start of the file */
     unsigned char version[2];       /* Object version number */
     unsigned char gadget[44];       /* Copy of in memory gadget (44 by */
@@ -127,139 +256,140 @@ typedef struct DiskObject_ { /* 78 bytes (including Gadget struct) */
 
 
 static void
-parseCommandLine( int              argc,
-                  char *           argv[],
-                  IconInfo * const infoP ) {
-
-    unsigned int numColorArgs,  /* Number of arguments for overriding colors */
-        colorIdx,      /* Color index */
-        i;             /* Argument index */
-    const char  * const colors[4] = {
-        /* Pixel colors based on original Amiga colors */
-        "#0055AA",    /*   Blue      0,  85, 170 */
-        "#FFFFFF",    /*   White   255, 255, 255 */
-        "#000020",    /*   Black     0,   0,  32 */
-        "#FF8A00"     /*   Orange  255, 138,   0 */
-    };
-
-    /* Option entry variables */
-    optEntry     *option_def;
-    optStruct3    opt;
-    unsigned int  option_def_index;
-    unsigned int numColorsSpec, forceColorSpec, selectedSpec;
+parseCommandLine(int                 argc,
+                 const char **       argv,
+                 CmdlineInfo * const cmdlineP) {
+
+    unsigned int   argIdx;
+    optEntry     * option_def;
+    optStruct3     opt;
+    unsigned int   option_def_index;
+    unsigned int   numcolorsSpec;
+    unsigned int   numcolors;
 
     MALLOCARRAY_NOFAIL(option_def, 100);
 
     /* Set command line options */
     option_def_index = 0;   /* Incremented by OPTENT3 */
-    OPTENT3(0, "forcecolor", OPT_FLAG, NULL, &forceColorSpec, 0);
-    OPTENT3(0, "numcolors",  OPT_UINT, &infoP->numColors, &numColorsSpec, 0);
-    OPTENT3(0, "selected",   OPT_FLAG, NULL, &selectedSpec,   0);
-
-    /* Initialize the iconInfo struct */
-    infoP->name = NULL;
-    infoP->fp = NULL;
-    infoP->drawerData = FALSE;
-    infoP->version = 0;
-    infoP->width = 0;
-    infoP->height = 0;
-    infoP->depth = 0;
-    infoP->icon = NULL;
-    for ( colorIdx = 0; colorIdx < 4; colorIdx++ )
-        infoP->colors[colorIdx] =
-            ppm_parsecolor( (char*) colors[colorIdx], 0xFF );
-
-    /* Initialize option structure */
+    OPTENT3(0, "forcecolor", OPT_FLAG, NULL,       &cmdlineP->forcecolor,
+            0);
+    OPTENT3(0, "numcolors",  OPT_UINT, &numcolors, &numcolorsSpec,
+            0);
+    OPTENT3(0, "selected",   OPT_FLAG, NULL,       &cmdlineP->selected,
+            0);
+    OPTENT3(0, "verbose",    OPT_FLAG, NULL,       &cmdlineP->verbose,
+            0);
+
     opt.opt_table     = option_def;
-    opt.short_allowed = FALSE;  /* No short (old-fashioned) options */
-    opt.allowNegNum   = FALSE;  /* No negative number parameters */
-
-    /* Parse the command line */
-    pm_optParseOptions3( &argc, argv, opt, sizeof( opt ), 0 );
-
-    infoP->forceColor = forceColorSpec;
-    infoP->selected = selectedSpec;
-    if (!numColorsSpec)
-        infoP->numColors = 0;
-
-    /* Get colors and file name */
-    numColorArgs = infoP->numColors * 2;
-    if ( ( argc - 1 != numColorArgs ) && ( argc - 1 != numColorArgs + 1 ) ) {
-        pm_error( "Wrong number of arguments for number of colors.  "
-                  "For %u colors, you need %u color arguments, "
-                  "with possibly one more argument for the input file name.",
-                  infoP->numColors, numColorArgs );
-    }
+    opt.short_allowed = false;  /* No short (old-fashioned) options */
+    opt.allowNegNum   = false;  /* No negative number parameters */
+
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
+
+    {
+        const char * const colors[4] = {
+            /* Pixel colors based on original Amiga colors */
+            "#0055AA",    /*   Blue      0,  85, 170 */
+            "#FFFFFF",    /*   White   255, 255, 255 */
+            "#000020",    /*   Black     0,   0,  32 */
+            "#FF8A00"     /*   Orange  255, 138,   0 */
+        };
+
+        unsigned int colorArgCt;
+            /* Number of arguments for overriding colors */
 
-    /* Convert color arguments */
-    for ( i = 1; i < numColorArgs; i += 2 ) {
-        char *       endptr;        /* End pointer for strtol() */
         unsigned int colorIdx;
 
-        /* Get color index from argument */
-        colorIdx = strtoul( argv[i], &endptr, 0 );
+        if (numcolorsSpec) {
+            colorArgCt = numcolors * 2;
+            if (argc-1 < colorArgCt) {
+                pm_error("Insufficient arguments for %u color "
+                         "specifications.  Need at least %u arguments",
+                         numcolors, colorArgCt);
+            }
+        } else
+            colorArgCt = 0;
 
-        if ( *endptr != '\0' ) {
-            pm_error( "'%s' is not a valid color index", argv[i] );
-        }
+        /* Initialize palette to defaults */
+        for (colorIdx = 0; colorIdx < 4; ++colorIdx)
+            cmdlineP->colors[colorIdx] =
+                ppm_parsecolor(colors[colorIdx], 0xFF);
 
-        /* Check color index range (current 0 to 3) */
-        if ( ( colorIdx < 0 ) || ( colorIdx > 3 ) ) {
-            pm_error( "%u is not a valid color index (minimum 0, maximum 3)",
-                      colorIdx );
-        }
+        /* Convert color arguments */
+        for (argIdx = 1; argIdx < colorArgCt; argIdx += 2) {
+            char *       endptr;        /* End pointer for strtol() */
+            unsigned int colorIdx;
+
+            /* Get color index from argument */
+            colorIdx = strtoul(argv[argIdx], &endptr, 0);
+
+            if (*endptr != '\0') {
+                pm_error("'%s' is not a valid color index", argv[argIdx]);
+            }
+
+            if ((colorIdx < 0) || (colorIdx > 3)) {
+                pm_error(
+                    "%u is not a valid color index (minimum 0, maximum 3)",
+                    colorIdx);
+            }
 
-        /* Convert the color for this color index */
-        infoP->colors[colorIdx] = ppm_parsecolor( argv[i+1], 0xFF );
+            cmdlineP->colors[colorIdx] = ppm_parsecolor(argv[argIdx+1], 0xFF);
+        }
     }
 
-    /* Set file name */
-    if ( i > argc-1 )
-        infoP->name = "-";  /* Read from standard input */
+    if (argIdx > argc-1)
+        cmdlineP->inputFileNm = "-";  /* Read from standard input */
     else
-        infoP->name = argv[i];
+        cmdlineP->inputFileNm = argv[argIdx];
 }
 
 
 
 static void
-getDiskObject( IconInfo * const infoP ) {
-/*-------------------------------------------------------------------------
- * Get fields from disk object portion of info file
- *-------------------------------------------------------------------------*/
+readDiskObjectHeader(FILE *         const ifP,
+                     unsigned int * const versionP,
+                     bool *         const hasDrawerDataP) {
+/*---------------------------------------------------------------------------
+  Read disk object header from file *ifP; validate it and return its contents.
+----------------------------------------------------------------------------*/
     DiskObject  dobj;      /* Disk object structure */
-    size_t      bytesRead;
+    size_t      bytesReadCt;
 
     /* Read the disk object header */
-    bytesRead = fread( &dobj, 1, sizeof(dobj), infoP->fp );
-    if (ferror(infoP->fp))
-        pm_error("Cannot read disk object header for file '%s'.  "
+    bytesReadCt = fread(&dobj, 1, sizeof(dobj), ifP);
+    if (ferror(ifP))
+        pm_error("Cannot read disk object header.  "
                  "fread() errno = %d (%s)",
-                 infoP->name, errno, strerror(errno));
-    else if (bytesRead != sizeof(dobj))
-        pm_error("Cannot read entire disk object header for file '%s'.  "
+                 errno, strerror(errno));
+    else if (bytesReadCt != sizeof(dobj))
+        pm_error("Cannot read entire disk object header.  "
                  "Only read 0x%X of 0x%X bytes",
-                 infoP->name, (unsigned)bytesRead, (unsigned)sizeof(dobj));
+                 (unsigned)bytesReadCt, (unsigned)sizeof(dobj));
 
-    /* Check magic number */
+    /* Validate magic number */
     if ((dobj.magic[0] != 0xE3) && (dobj.magic[1] != 0x10))
-        pm_error("Wrong magic number for file '%s'.  "
+        pm_error("Wrong magic number in icon file.  "
                  "Expected 0xE310, but got 0x%X%X",
-                 infoP->name, dobj.magic[0], dobj.magic[1]);
+                 dobj.magic[0], dobj.magic[1]);
+
+    *versionP = (dobj.version[0] <<  8) + (dobj.version[1]);
 
-    /* Set version info and have drawer data flag */
-    infoP->version     = (dobj.version[0]     <<  8) +
-        (dobj.version[1]           );
-    infoP->drawerData  = (dobj.pDrawerData[0] << 24) +
+    *hasDrawerDataP =
+        (dobj.pDrawerData[0] << 24) +
         (dobj.pDrawerData[1] << 16) +
         (dobj.pDrawerData[2] <<  8) +
-        (dobj.pDrawerData[3]      ) ? TRUE : FALSE;
+        (dobj.pDrawerData[3]      )
+        > 0;
 }
 
 
 
 static void
-getIconHeader(IconInfo * const infoP) {
+readIconHeader(FILE *         const ifP,
+               unsigned int * const widthP,
+               unsigned int * const heightP,
+               unsigned int * const depthP,
+               unsigned int * const bpwidthP) {
 /*-------------------------------------------------------------------------
  * Get fields from icon header portion of info file
  *-------------------------------------------------------------------------*/
@@ -267,25 +397,37 @@ getIconHeader(IconInfo * const infoP) {
     size_t      bytesRead;
 
     /* Read icon header */
-    bytesRead = fread(&ihead, 1, sizeof(ihead), infoP->fp);
-    if (ferror(infoP->fp))
-        pm_error("Cannot read icon header for file '%s'.  "
-                 "fread() errno = %d (%s)",
-                 infoP->name, errno, strerror(errno));
+    bytesRead = fread(&ihead, 1, sizeof(ihead), ifP);
+    if (ferror(ifP))
+        pm_error("Failed to read icon header.  fread() errno = %d (%s)",
+                 errno, strerror(errno));
     else if (bytesRead != sizeof(ihead))
-        pm_error("Cannot read the entire icon header for file '%s'.  "
-                 "Only read 0x%X of 0x%X bytes",
-                 infoP->name, (unsigned)bytesRead, (unsigned)sizeof(ihead));
+        pm_error("Failed to read the entire icon header.  "
+                 "Read only %u of %u bytes",
+                 (unsigned)bytesRead, (unsigned)sizeof(ihead));
+
+    if (!memeq(ihead.type, "\0\0\0\0", 4)) {
+        pm_message("Unrecognized object where icon header expected.  "
+                   "First 4 bytes are 0x%02x%02x%02x%02x.  We expect "
+                   "0x00000000",
+                   ihead.type[0], ihead.type[1], ihead.type[2], ihead.type[3]);
+    }
 
-    /* Get icon width, height, and bitplanes */
-    infoP->width  = (ihead.iconWidth[0]  << 8) + ihead.iconWidth[1];
-    infoP->height = (ihead.iconHeight[0] << 8) + ihead.iconHeight[1];
-    infoP->depth  = (ihead.bpp[0]        << 8) + ihead.bpp[1];
+    *widthP  = (ihead.iconWidth[0]  << 8) + ihead.iconWidth[1];
+    *heightP = (ihead.iconHeight[0] << 8) + ihead.iconHeight[1];
+    *depthP  = (ihead.bpp[0]        << 8) + ihead.bpp[1];
 
-    /* Check number of bit planes */
-    if ((infoP->depth > 2) || (infoP->depth < 1))
-        pm_error("We don't know how to interpret %u bitplanes file '%s'.  ",
-                 infoP->depth, infoP->name);
+    if (*widthP < 1)
+        pm_error("Invalid width value in icon header: %u", *widthP);
+
+    if (*heightP < 1)
+        pm_error("Invalid height value in icon header: %u", *heightP);
+
+    if (*depthP > 2 || *depthP < 1)
+        pm_error("We don't know how to interpret file with %u bitplanes.  ",
+                 *depthP);
+
+    *bpwidthP = ROUNDUP(*widthP, 16);
 }
 
 
@@ -298,17 +440,16 @@ addBitplane(unsigned char * const icon,
    Add bitplane to existing icon image
 -----------------------------------------------------------------------------*/
     unsigned int i;
-    unsigned int j;
-
-    for (i = j = 0; i < bpsize; ++i, j += 8) {
-        icon[j+0] = (icon[j+0] << 1) | ((buff[i] >> 7) & 0x01);
-        icon[j+1] = (icon[j+1] << 1) | ((buff[i] >> 6) & 0x01);
-        icon[j+2] = (icon[j+2] << 1) | ((buff[i] >> 5) & 0x01);
-        icon[j+3] = (icon[j+3] << 1) | ((buff[i] >> 4) & 0x01);
-        icon[j+4] = (icon[j+4] << 1) | ((buff[i] >> 3) & 0x01);
-        icon[j+5] = (icon[j+5] << 1) | ((buff[i] >> 2) & 0x01);
-        icon[j+6] = (icon[j+6] << 1) | ((buff[i] >> 1) & 0x01);
-        icon[j+7] = (icon[j+7] << 1) | ((buff[i] >> 0) & 0x01);
+
+    for (i = 0; i < bpsize; ++i) {
+        icon[(i*8)+0] = (icon[(i*8)+0] << 1) | ((buff[i] >> 7) & 0x01);
+        icon[(i*8)+1] = (icon[(i*8)+1] << 1) | ((buff[i] >> 6) & 0x01);
+        icon[(i*8)+2] = (icon[(i*8)+2] << 1) | ((buff[i] >> 5) & 0x01);
+        icon[(i*8)+3] = (icon[(i*8)+3] << 1) | ((buff[i] >> 4) & 0x01);
+        icon[(i*8)+4] = (icon[(i*8)+4] << 1) | ((buff[i] >> 3) & 0x01);
+        icon[(i*8)+5] = (icon[(i*8)+5] << 1) | ((buff[i] >> 2) & 0x01);
+        icon[(i*8)+6] = (icon[(i*8)+6] << 1) | ((buff[i] >> 1) & 0x01);
+        icon[(i*8)+7] = (icon[(i*8)+7] << 1) | ((buff[i] >> 0) & 0x01);
     }
 }
 
@@ -392,156 +533,134 @@ readIconData(FILE *           const fileP,
 
 
 static void
-writeIconData( IconInfo *   const infoP,
-               struct pam * const pamP ) {
+writeRaster(IconInfo *    const infoP,
+            struct pam *  const pamP,
+            bool          const wantColor,
+            const pixel * const colors) {
 /*-------------------------------------------------------------------------
- * Write icon data to file
- *-------------------------------------------------------------------------*/
-    unsigned int const bpwidth = ( ( infoP->width + 15 ) / 16 ) * 16;
-        /* Bitplane width; Width of each row in icon, including padding */
+  Write out raster of PAM image described by *pamP.
 
-    tuple * row;      /* Output row */
+  'wantColor' means the user wants the PAM to be tuple type RGB, regardless
+  of the input image type.
 
-    /* Allocate row */
-    row = pnm_allocpamrow( pamP );
+  'colors' is the palette.  It has 4 entries, one for each of the possible
+  color indices in the input icon raster.
+--------------------------------------------------------------------------*/
+    unsigned int row;
+    tuple * tuplerow;      /* Output row */
 
-    /* Write icon image to output file */
-    /* Put if check outside for loop to reduce number of times check is made */
-    if ( infoP->depth == 1 ) {
-        if ( infoP->forceColor ) {
-            /* Convert 1 bitplane icon into color PAM */
-            unsigned int i;
-            for ( i = 0; i < infoP->height; ++i ) {
-                unsigned int j;
-                for ( j = 0; j < infoP->width; ++j ) {
+    tuplerow = pnm_allocpamrow(pamP);
+
+    for (row = 0; row < infoP->height; ++row) {
+        unsigned int col;
+
+        for (col = 0; col < infoP->width; ++col) {
+            if (infoP->depth == 1) {
+                if (wantColor) {
                     /* 1 is black and 0 is white */
                     unsigned int colorIdx =
-                        infoP->icon[ i * bpwidth + j ] ? 2 : 1;
-                    row[j][PAM_RED_PLANE] =
-                        PPM_GETR( infoP->colors[colorIdx] );
-                    row[j][PAM_GRN_PLANE] =
-                        PPM_GETG( infoP->colors[colorIdx] );
-                    row[j][PAM_BLU_PLANE] =
-                        PPM_GETB( infoP->colors[colorIdx] );
-                }
-                pnm_writepamrow( pamP, row );
-            }
-        } else {
-            /* Convert 1 bitplane icon into bitmap PAM */
-            unsigned int i;
-            for ( i = 0; i < infoP->height; ++i ) {
-                unsigned int j;
-                for ( j = 0; j < infoP->width; j++ ) {
+                        infoP->icon[row * infoP->bpwidth + col] ? 2 : 1;
+
+                    tuplerow[col][PAM_RED_PLANE] = PPM_GETR(colors[colorIdx]);
+                    tuplerow[col][PAM_GRN_PLANE] = PPM_GETG(colors[colorIdx]);
+                    tuplerow[col][PAM_BLU_PLANE] = PPM_GETB(colors[colorIdx]);
+                } else {
                     /* 1 is black and 0 is white */
-                    row[j][0] = infoP->icon[ i * bpwidth + j ] ? 0 : 1;
+                    tuplerow[col][0] =
+                        infoP->icon[row * infoP->bpwidth + col] ? 0 : 1;
                 }
-                pnm_writepamrow( pamP, row );
+            } else {
+                unsigned int const colorIdx =
+                    infoP->icon[row * infoP->bpwidth + col];
+                tuplerow[col][PAM_RED_PLANE] = PPM_GETR(colors[colorIdx]);
+                tuplerow[col][PAM_GRN_PLANE] = PPM_GETG(colors[colorIdx]);
+                tuplerow[col][PAM_BLU_PLANE] = PPM_GETB(colors[colorIdx]);
             }
         }
-    } else {
-        /* Convert color icon into color PAM */
-        unsigned int i;
-        for ( i = 0; i < infoP->height; ++i ) {
-            unsigned int j;
-            for ( j = 0; j < infoP->width; ++j ) {
-                unsigned int const colorIdx = infoP->icon[ i * bpwidth + j ];
-                row[j][PAM_RED_PLANE] = PPM_GETR( infoP->colors[colorIdx] );
-                row[j][PAM_GRN_PLANE] = PPM_GETG( infoP->colors[colorIdx] );
-                row[j][PAM_BLU_PLANE] = PPM_GETB( infoP->colors[colorIdx] );
-            }
-            pnm_writepamrow( pamP, row );
-        }
+        pnm_writepamrow(pamP, tuplerow);
     }
 
-    /* Clean up allocated memory */
-    pnm_freepamrow( row );
+    pnm_freepamrow(tuplerow);
 }
 
 
 
 int
-main( int argc,
-      char *argv[] ) {
+main(int argc, const char **argv) {
 
-    IconInfo    info;    /* Miscellaneous icon information */
-    struct pam  pam;     /* PAM header */
-    int         skip;    /* Bytes to skip to read next icon header */
+    CmdlineInfo  cmdline;
+    IconInfo     info;      /* Miscellaneous icon information */
+    struct pam   pam;       /* PAM header */
 
-    /* Init PNM library */
-    pnm_init( &argc, argv );
+    pm_proginit(&argc, argv);
 
-    /* Parse command line arguments */
-    parseCommandLine( argc, argv, &info );
+    parseCommandLine(argc, argv, &cmdline);
 
-    /* Open input file */
-    info.fp = pm_openr( info.name );
+    info.ifP = pm_openr(cmdline.inputFileNm);
 
-    /* Read disk object header */
-    getDiskObject( &info );
+    readDiskObjectHeader(info.ifP, &info.version, &info.hasDrawerData);
 
     /* Skip drawer data, if any */
-    if ( info.drawerData ) {
-        skip = 56;   /* Draw data size */
-        if ( fseek( info.fp, skip, SEEK_CUR ) < 0 )
-            pm_error( "Cannot skip header information in file '%s'.  "
-                      "fseek() errno = %d (%s)",
-                      info.name, errno, strerror( errno ) );
-    }
+    if (info.hasDrawerData) {
+        unsigned int const skipCt = 56;   /* Draw data size */
 
-    /* Get dimensions for first icon */
-    getIconHeader( &info );
+        int rc;
 
-    /* Skip ahead to next header if converting second icon */
-    if ( info.selected ) {
-        skip = info.height * ( ( ( info.width + 15 ) / 16 ) * 2 ) * info.depth;
+        rc = fseek(info.ifP, skipCt, SEEK_CUR);
+        if (rc < 0) {
+            pm_error("Failed to skip header information in input file.  "
+                     "fseek() errno = %d (%s)",
+                     errno, strerror(errno));
+        }
+    }
 
-        if ( fseek( info.fp, skip, SEEK_CUR ) < 0 )
-            pm_error( "Cannot skip to next icon in file '%s'.  "
-                      "fseek() errno = %d (%s)",
-                      info.name, errno, strerror( errno ) );
+    /* Read header of first icon */
+    readIconHeader(info.ifP, &info.width, &info.height, &info.depth,
+                   &info.bpwidth);
 
-        /* Get dimensions for second icon */
-        getIconHeader( &info );
-    }
+    readIconData(info.ifP, info.width, info.height, info.depth, &info.icon);
 
-    /* Read icon data */
-    readIconData( info.fp, info.width, info.height, info.depth, &info.icon );
+    if (cmdline.selected) {
+        /* He wants the second icon, so update info.width, etc.  to be for the
+           second icon.
+        */
+        readIconHeader(info.ifP, &info.width, &info.height, &info.depth,
+                       &info.bpwidth);
 
-    /* Print icon info */
-    pm_message( "converting %s, version %d, %s icon: %d X %d X %d",
-                info.name, info.version, info.selected ? "second" : "first",
-                info.width, info.height, info.depth );
+        readIconData(info.ifP, info.width, info.height, info.depth,
+                     &info.icon);
+    }
 
-    /* Write PAM header */
-    pam.size   = sizeof( pam );
-    pam.len    = PAM_STRUCT_SIZE( tuple_type );
+    if (cmdline.verbose) {
+        pm_message("Version %u .info file, %s icon: %uW x %uH x %u deep",
+                   info.version, cmdline.selected ? "second" : "first",
+                   info.width, info.height, info.depth);
+    }
+    pam.size   = sizeof(pam);
+    pam.len    = PAM_STRUCT_SIZE(tuple_type);
     pam.file   = stdout;
     pam.height = info.height;
     pam.width  = info.width;
     pam.format = PAM_FORMAT;
 
-    if ( ( info.depth == 1 ) && ( info.forceColor == FALSE ) ) {
+    if ((info.depth == 1) && !cmdline.forcecolor) {
         pam.depth  = 1;
         pam.maxval = 1;
-        strcpy( pam.tuple_type, "BLACKANDWHITE" );
+        strcpy(pam.tuple_type, "BLACKANDWHITE");
     } else {
         pam.depth  = 3;
         pam.maxval = 0xFF;
-        strcpy( pam.tuple_type, "RGB" );
+        strcpy(pam.tuple_type, "RGB");
     }
-    pnm_writepaminit( &pam );
+    pnm_writepaminit(&pam);
 
-    /* Write icon data */
-    writeIconData( &info, &pam );
+    writeRaster(&info, &pam, cmdline.forcecolor, cmdline.colors);
 
-    free( info.icon );
-
-    /* Close input file and return */
-    pm_close( pam.file );
-    pm_close( info.fp );
+    free(info.icon);
+    pm_close(pam.file);
+    pm_close(info.ifP);
 
     return 0;
 }
 
 
-
diff --git a/converter/other/pamtogif.c b/converter/other/pamtogif.c
index 11e9bdcd..c41c778c 100644
--- a/converter/other/pamtogif.c
+++ b/converter/other/pamtogif.c
@@ -118,7 +118,7 @@ pamAlphaPlane(struct pam * const pamP) {
 
 
 static void
-parseCommandLine(int argc, char ** argv,
+parseCommandLine(int argc, const char ** argv,
                  struct CmdlineInfo * const cmdlineP) {
 /*----------------------------------------------------------------------------
    Parse the program arguments (given by argc and argv) into a form
@@ -172,7 +172,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_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc-1 == 0)
@@ -212,9 +212,9 @@ Putword(int const w, FILE * const fp) {
 
 
 static int
-closestColor(tuple         const color,
-             struct pam *  const pamP,
-             struct Cmap * const cmapP) {
+closestColor(tuple               const color,
+             struct pam *        const pamP,
+             const struct Cmap * const cmapP) {
 /*----------------------------------------------------------------------------
    Return the colormap index of the color in the colormap *cmapP
    that is closest to the color 'color', whose format is specified by
@@ -316,7 +316,7 @@ rowReader_destroy(RowReader * const rdrP) {
 
 
 static void
-rowReaderSkipRows(RowReader *  const rdrP,
+rowReader_skipRows(RowReader *  const rdrP,
                   unsigned int const rowCount,
                   bool *       const eofP) {
 /*----------------------------------------------------------------------------
@@ -347,7 +347,7 @@ rowReaderSkipRows(RowReader *  const rdrP,
 
 
 static void
-rowReaderGotoNextInterlaceRow(RowReader * const rdrP) {
+rowReader_gotoNextInterlaceRow(RowReader * const rdrP) {
 /*----------------------------------------------------------------------------
   Position reader to the next row in the interlace pattern, assuming it
   is now positioned immediately after the current row.
@@ -363,16 +363,16 @@ rowReaderGotoNextInterlaceRow(RowReader * const rdrP) {
 
     switch (rdrP->pass) {
     case MULT8PLUS0:
-        rowReaderSkipRows(rdrP, 7, &endOfPass);
+        rowReader_skipRows(rdrP, 7, &endOfPass);
         break;
     case MULT8PLUS4:
-        rowReaderSkipRows(rdrP, 7, &endOfPass);
+        rowReader_skipRows(rdrP, 7, &endOfPass);
         break;
     case MULT4PLUS2:
-        rowReaderSkipRows(rdrP, 3, &endOfPass);
+        rowReader_skipRows(rdrP, 3, &endOfPass);
         break;
     case MULT2PLUS1:
-        rowReaderSkipRows(rdrP, 1, &endOfPass);
+        rowReader_skipRows(rdrP, 1, &endOfPass);
         break;
     }
 
@@ -387,15 +387,15 @@ rowReaderGotoNextInterlaceRow(RowReader * const rdrP) {
         switch (rdrP->pass) {
         case MULT8PLUS0:
             rdrP->pass = MULT8PLUS4;
-            rowReaderSkipRows(rdrP, 4, &endOfPass);
+            rowReader_skipRows(rdrP, 4, &endOfPass);
             break;
         case MULT8PLUS4:
             rdrP->pass = MULT4PLUS2;
-            rowReaderSkipRows(rdrP, 2, &endOfPass);
+            rowReader_skipRows(rdrP, 2, &endOfPass);
             break;
         case MULT4PLUS2:
             rdrP->pass = MULT2PLUS1;
-            rowReaderSkipRows(rdrP, 1, &endOfPass);
+            rowReader_skipRows(rdrP, 1, &endOfPass);
             break;
         case MULT2PLUS1:
             rdrP->eof = TRUE;
@@ -407,7 +407,7 @@ rowReaderGotoNextInterlaceRow(RowReader * const rdrP) {
 
 
 static void
-rowReaderGotoNextStraightRow(RowReader * const rdrP) {
+rowReader_gotoNextStraightRow(RowReader * const rdrP) {
 /*----------------------------------------------------------------------------
   Position reader to the next row in a straight, non-interlace
   pattern, assuming the file is now positioned immediately after the
@@ -434,19 +434,19 @@ rowReader_read(RowReader * const rdrP,
     ++rdrP->nextRow;
 
     if (rdrP->interlace)
-        rowReaderGotoNextInterlaceRow(rdrP);
+        rowReader_gotoNextInterlaceRow(rdrP);
     else
-        rowReaderGotoNextStraightRow(rdrP);
+        rowReader_gotoNextStraightRow(rdrP);
 }
 
 
 
 static unsigned int
-gifPixel(struct pam *   const pamP,
-         tuple          const tuple,
-         unsigned int   const alphaPlane,
-         sample         const alphaThreshold,
-         struct Cmap *  const cmapP) {
+gifPixel(struct pam *        const pamP,
+         tuple               const tuple,
+         unsigned int        const alphaPlane,
+         sample              const alphaThreshold,
+         const struct Cmap * const cmapP) {
 /*----------------------------------------------------------------------------
    Return the colormap index of the tuple 'tuple', whose format is described
    by *pamP, using colormap *cmapP.
@@ -1270,89 +1270,6 @@ writePixelUncompressed(LzwCompressor * const lzwP,
 
 
 static void
-writeRaster(struct pam *  const pamP,
-            RowReader *   const rowReaderP,
-            unsigned int  const alphaPlane,
-            unsigned int  const alphaThreshold,
-            struct Cmap * const cmapP,
-            unsigned int  const initBits,
-            FILE *        const ofP,
-            bool          const lzw,
-            bool          const noclear) {
-/*----------------------------------------------------------------------------
-   Write the raster to file 'ofP'.
-
-   Get the raster to write from 'rowReaderP', which gives tuples whose
-   format is described by 'pamP'.
-
-   'alphaPlane' is the number of the plane in the tuples supplied by
-   'rowReaderP' that we should use for transparency information, and
-   'alphaThreshold' is the value in that plane below which we should consider
-   the pixel transparent for GIF purposes.
-
-   'alphaPlane' is zero to indicate we should not use any plane as an alpha
-   plane (so it's not possible to specify Plane 0 as alpha).
-
-   Use the colormap 'cmapP' to generate the raster ('rowReaderP' gives
-   pixel values as RGB samples; the GIF raster is colormap indices).
-
-   Write the raster using LZW compression, or uncompressed depending
-   on 'lzw'.
-
-   If 'noclear', don't use any GIF clear codes in the output; i.e. don't
-   recompute the string table from current input.  Once the string table gets
-   to maximum size, just keep using that table for the rest of the image.
------------------------------------------------------------------------------*/
-    LzwCompressor * lzwP;
-    tuple * tuplerow;
-    unsigned int nRowsDone;
-        /* Number of rows we have read so far from the the input (the
-           last of which is the one we're working on now).  Note that
-           in case of interlace, this is not the same thing as the row
-           number of the current row.
-        */
-
-    lzwP = lzw_create(ofP, initBits, lzw, noclear, pamP->height * pamP->width);
-
-    tuplerow = pnm_allocpamrow(pamP);
-
-    lzw_clearBlock(lzwP);
-
-    nRowsDone = 0;
-
-    while (nRowsDone < pamP->height) {
-        unsigned int col;
-
-        rowReader_read(rowReaderP, tuplerow);
-
-        for (col = 0; col < pamP->width; ++col) {
-            unsigned int const colorIndex =
-                gifPixel(pamP, tuplerow[col], alphaPlane, alphaThreshold,
-                         cmapP);
-
-                /* The value for the pixel in the GIF image.  I.e. the colormap
-                   index.
-                */
-            if (lzw)
-                lzw_encodePixel(lzwP, colorIndex);
-            else
-                writePixelUncompressed(lzwP, colorIndex);
-        }
-        ++nRowsDone;
-    }
-    /* Gif is no good with no pixels; fortunately, that's impossible: */
-    assert(nRowsDone > 0);
-
-    lzw_flush(lzwP);
-
-    pnm_freepamrow(tuplerow);
-
-    lzw_destroy(lzwP);
-}
-
-
-
-static void
 writeGlobalColorMap(FILE *              const ofP,
                     const struct Cmap * const cmapP,
                     unsigned int        const bitsPerPixel) {
@@ -1404,6 +1321,23 @@ writeGlobalColorMap(FILE *              const ofP,
 
 
 static void
+reportImageInfo(bool         const interlace,
+                unsigned int const background,
+                unsigned int const bitsPerPixel) {
+
+    if (verbose) {
+        if (interlace)
+            pm_message("interlaced");
+        else
+            pm_message("not interlaced");
+        pm_message("Background color index = %u", background);
+        pm_message("%u bits per pixel", bitsPerPixel);
+    }
+}
+
+
+
+static void
 writeGifHeader(FILE *              const ofP,
                unsigned int        const width,
                unsigned int        const height,
@@ -1460,6 +1394,15 @@ writeGifHeader(FILE *              const ofP,
 
 
 static void
+writeImageSeparator(FILE * const ofP) {
+
+    fputc(',', ofP);
+
+}
+
+
+
+static void
 writeImageHeader(FILE *       const ofP,
                  unsigned int const leftOffset,
                  unsigned int const topOffset,
@@ -1486,42 +1429,110 @@ writeImageHeader(FILE *       const ofP,
 
 
 static void
-reportImageInfo(bool         const interlace,
-                unsigned int const background,
-                unsigned int const bitsPerPixel) {
+writeRaster(struct pam *        const pamP,
+            RowReader *         const rowReaderP,
+            unsigned int        const alphaPlane,
+            unsigned int        const alphaThreshold,
+            const struct Cmap * const cmapP,
+            unsigned int        const initBits,
+            FILE *              const ofP,
+            bool                const lzw,
+            bool                const noclear) {
+/*----------------------------------------------------------------------------
+   Write the raster to file 'ofP'.
 
-    if (verbose) {
-        if (interlace)
-            pm_message("interlaced");
-        else
-            pm_message("not interlaced");
-        pm_message("Background color index = %u", background);
-        pm_message("%u bits per pixel", bitsPerPixel);
+   Get the raster to write from 'rowReaderP', which gives tuples whose
+   format is described by 'pamP'.
+
+   'alphaPlane' is the number of the plane in the tuples supplied by
+   'rowReaderP' that we should use for transparency information, and
+   'alphaThreshold' is the value in that plane below which we should consider
+   the pixel transparent for GIF purposes.
+
+   'alphaPlane' is zero to indicate we should not use any plane as an alpha
+   plane (so it's not possible to specify Plane 0 as alpha).
+
+   Use the colormap 'cmapP' to generate the raster ('rowReaderP' gives
+   pixel values as RGB samples; the GIF raster is colormap indices).
+
+   Write the raster using LZW compression, or uncompressed depending
+   on 'lzw'.
+
+   If 'noclear', don't use any GIF clear codes in the output; i.e. don't
+   recompute the string table from current input.  Once the string table gets
+   to maximum size, just keep using that table for the rest of the image.
+-----------------------------------------------------------------------------*/
+    LzwCompressor * lzwP;
+    tuple * tuplerow;
+    unsigned int nRowsDone;
+        /* Number of rows we have read so far from the the input (the
+           last of which is the one we're working on now).  Note that
+           in case of interlace, this is not the same thing as the row
+           number of the current row.
+        */
+
+    lzwP = lzw_create(ofP, initBits, lzw, noclear, pamP->height * pamP->width);
+
+    tuplerow = pnm_allocpamrow(pamP);
+
+    lzw_clearBlock(lzwP);
+
+    nRowsDone = 0;
+
+    while (nRowsDone < pamP->height) {
+        unsigned int col;
+
+        rowReader_read(rowReaderP, tuplerow);
+
+        for (col = 0; col < pamP->width; ++col) {
+            unsigned int const colorIndex =
+                gifPixel(pamP, tuplerow[col], alphaPlane, alphaThreshold,
+                         cmapP);
+
+                /* The value for the pixel in the GIF image.  I.e. the colormap
+                   index.
+                */
+            if (lzw)
+                lzw_encodePixel(lzwP, colorIndex);
+            else
+                writePixelUncompressed(lzwP, colorIndex);
+        }
+        ++nRowsDone;
     }
+    /* Gif is no good with no pixels; fortunately, that's impossible: */
+    assert(nRowsDone > 0);
+
+    lzw_flush(lzwP);
+
+    pnm_freepamrow(tuplerow);
+
+    lzw_destroy(lzwP);
 }
 
 
 
 static void
-gifEncode(struct pam *  const pamP,
-          FILE *        const ofP,
-          pm_filepos    const rasterPos,
-          bool          const gInterlace,
-          int           const background,
-          unsigned int  const bitsPerPixel,
-          struct Cmap * const cmapP,
-          char          const comment[],
-          float         const aspect,
-          bool          const lzw,
-          bool          const noclear,
-          bool          const usingAlpha) {
-/*----------------------------------------------------------------------------
-   'usingAlpha' means use the alpha (transparency) plane, if there is one, to
-   determine which GIF pixels are transparent.  When this is true, the
-   colormap *cmapP must contain a transparent entry.
------------------------------------------------------------------------------*/
-    unsigned int const leftOffset = 0;
-    unsigned int const topOffset  = 0;
+writeEndOfImage(FILE * const ofP) {
+
+    /* An empty block marks the end of a series of blocks */
+
+    fputc(0, ofP);
+}
+
+
+
+static void
+writeGifImage(FILE *              const ofP,
+              unsigned int        const leftOffset,
+              unsigned int        const topOffset,
+              struct pam *        const pamP,
+              pm_filepos          const rasterPos,
+              bool                const gInterlace,
+              unsigned int        const bitsPerPixel,
+              bool                const lzw,
+              bool                const noclear,
+              bool                const usingAlpha,
+              const struct Cmap * const cmapP) {
 
     unsigned int const initCodeSize = bitsPerPixel <= 1 ? 2 : bitsPerPixel;
         /* The initial code size */
@@ -1535,6 +1546,52 @@ gifEncode(struct pam *  const pamP,
 
     RowReader * rowReaderP;
 
+    writeImageSeparator(ofP);
+
+    writeImageHeader(ofP, leftOffset, topOffset, pamP->width, pamP->height,
+                     gInterlace, initCodeSize);
+
+    rowReaderP = rowReader_create(pamP, rasterPos, gInterlace);
+
+    writeRaster(pamP, rowReaderP, alphaPlane, alphaThreshold,
+                cmapP, initCodeSize + 1, ofP, lzw, noclear);
+
+    rowReader_destroy(rowReaderP);
+
+    writeEndOfImage(ofP);
+}
+
+
+
+static void
+writeGifStreamTerminator(FILE * const ofP) {
+
+    fputc(';', ofP);
+}
+
+
+
+static void
+writeGif(struct pam *        const pamP,
+         FILE *              const ofP,
+         pm_filepos          const rasterPos,
+         bool                const gInterlace,
+         int                 const background,
+         unsigned int        const bitsPerPixel,
+         const struct Cmap * const cmapP,
+         char                const comment[],
+         float               const aspect,
+         bool                const lzw,
+         bool                const noclear,
+         bool                const usingAlpha) {
+/*----------------------------------------------------------------------------
+   'usingAlpha' means use the alpha (transparency) plane, if there is one, to
+   determine which GIF pixels are transparent.  When this is true, the
+   colormap *cmapP must contain a transparent entry.
+-----------------------------------------------------------------------------*/
+    unsigned int const leftOffset = 0;
+    unsigned int const topOffset  = 0;
+
     reportImageInfo(gInterlace, background, bitsPerPixel);
 
     if (pamP->width > 65535)
@@ -1548,33 +1605,18 @@ gifEncode(struct pam *  const pamP,
     writeGifHeader(ofP, pamP->width, pamP->height, background,
                    bitsPerPixel, cmapP, comment, aspect);
 
-    /* Write an Image separator */
-    fputc(',', ofP);
+    writeGifImage(ofP, leftOffset, topOffset, pamP, rasterPos,
+                  gInterlace, bitsPerPixel, lzw, noclear, usingAlpha,
+                  cmapP);
 
-    writeImageHeader(ofP, leftOffset, topOffset, pamP->width, pamP->height,
-                     gInterlace, initCodeSize);
-
-    rowReaderP = rowReader_create(pamP, rasterPos, gInterlace);
-
-    /* Write the actual raster */
-
-    writeRaster(pamP, rowReaderP, alphaPlane, alphaThreshold,
-                cmapP, initCodeSize + 1, ofP, lzw, noclear);
-
-    rowReader_destroy(rowReaderP);
-
-    /* Write out a zero length data block (to end the series) */
-    fputc(0, ofP);
-
-    /* Write the GIF file terminator */
-    fputc(';', ofP);
+    writeGifStreamTerminator(ofP);
 }
 
 
 
 static void
 reportTransparent(enum TransparencyType const transType,
-                  struct Cmap *         const cmapP) {
+                  const struct Cmap *   const cmapP) {
 
     if (verbose) {
         switch (transType) {
@@ -1985,7 +2027,8 @@ destroyCmap(struct Cmap * const cmapP) {
 
 
 int
-main(int argc, char *argv[]) {
+main(int argc, const char ** argv) {
+
     struct CmdlineInfo cmdline;
     FILE * ifP;
     struct pam pam;
@@ -2000,7 +2043,7 @@ main(int argc, char *argv[]) {
            TRANS_ALPHA.
         */
 
-    pnm_init(&argc, argv);
+    pm_proginit(&argc, argv);
 
     parseCommandLine(argc, argv, &cmdline);
 
@@ -2033,11 +2076,10 @@ main(int argc, char *argv[]) {
 
     computeTransparent(transType, cmdline.transparent, fakeTransparent, &cmap);
 
-    /* All set, let's do it. */
-    gifEncode(&pam, stdout, rasterPos,
-              cmdline.interlace, 0, bitsPerPixel, &cmap, cmdline.comment,
-              cmdline.aspect, !cmdline.nolzw, cmdline.noclear,
-              transType==TRANS_ALPHA);
+    writeGif(&pam, stdout, rasterPos,
+             cmdline.interlace, 0, bitsPerPixel, &cmap, cmdline.comment,
+             cmdline.aspect, !cmdline.nolzw, cmdline.noclear,
+             transType==TRANS_ALPHA);
 
     destroyCmap(&cmap);
 
diff --git a/converter/other/pamtopdbimg.c b/converter/other/pamtopdbimg.c
index da0f5064..1ed08f9f 100644
--- a/converter/other/pamtopdbimg.c
+++ b/converter/other/pamtopdbimg.c
@@ -73,9 +73,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the strings we return are stored in the storage that
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;  /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -105,7 +103,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
 
diff --git a/converter/other/pamtopng.c b/converter/other/pamtopng.c
index 24eb1ca2..51203df5 100644
--- a/converter/other/pamtopng.c
+++ b/converter/other/pamtopng.c
@@ -218,7 +218,7 @@ parseCommandLine (int                  argc,
     opt.allowNegNum = false;  /* we have no parms that are negative numbers */
 
     /* uses and sets argc, argv, and some of *cmdlineP and others */
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
 
     if (cmdlineP->chromaSpec)
         parseChromaOpt(chroma, &cmdlineP->chroma);
diff --git a/converter/other/pamtopnm.c b/converter/other/pamtopnm.c
index 11e34b45..45ab1beb 100644
--- a/converter/other/pamtopnm.c
+++ b/converter/other/pamtopnm.c
@@ -33,9 +33,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the file spec array we return is stored in the storage that
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
-    optEntry * option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -49,7 +47,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc-1 == 0)
diff --git a/converter/other/pamtoqoi.c b/converter/other/pamtoqoi.c
index e3f87ae0..a188cca9 100644
--- a/converter/other/pamtoqoi.c
+++ b/converter/other/pamtoqoi.c
@@ -71,9 +71,7 @@ parseCommandLine(int                  argc,
    Note that the strings we return are stored in the storage that
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
-    optEntry * option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -86,7 +84,7 @@ parseCommandLine(int                  argc,
     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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc-1 < 1)
diff --git a/converter/other/pamtosrf.c b/converter/other/pamtosrf.c
index b62b19df..eb2d44bd 100644
--- a/converter/other/pamtosrf.c
+++ b/converter/other/pamtosrf.c
@@ -45,9 +45,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the strings we return are stored in the storage that
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
-  optEntry *option_def;
-      /* Instructions to pm_optParseOptions3 on how to parse our options.
-       */
+  optEntry * option_def;   /* Used by OPTENT3 */
   optStruct3 opt;
 
   unsigned int option_def_index;
@@ -62,7 +60,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+  pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
       /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
   if (argc-1 < 1)
diff --git a/converter/other/pamtotga.c b/converter/other/pamtotga.c
index f596a313..c0fb524a 100644
--- a/converter/other/pamtotga.c
+++ b/converter/other/pamtotga.c
@@ -82,7 +82,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdline_p and others. */
 
     if (cmap + cmap16 + mono + rgb > 1)
diff --git a/converter/other/pamtotiff.c b/converter/other/pamtotiff.c
index 4f25d93a..584cb840 100644
--- a/converter/other/pamtotiff.c
+++ b/converter/other/pamtotiff.c
@@ -236,7 +236,7 @@ parseCommandLine(int                 argc,
     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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
     /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (none + packbits + lzw + g3 + g4 + flate + adobeflate > 1)
diff --git a/converter/other/pamtowinicon.c b/converter/other/pamtowinicon.c
index 14b29f34..4d73ccdf 100644
--- a/converter/other/pamtowinicon.c
+++ b/converter/other/pamtowinicon.c
@@ -47,7 +47,7 @@ parseCommandLine(int argc, const char **argv,
     opt3.short_allowed = false;
     opt3.allowNegNum   = false;
 
-    pm_optParseOptions3(&argc, (char **)argv, opt3, sizeof(opt3), 0);
+    pm_optParseOptions4(&argc, argv, opt3, sizeof(opt3), 0);
 
     if (pngthresholdSpec) {
         if (UINT_MAX / cmdlineP->pngthreshold < cmdlineP->pngthreshold)
diff --git a/converter/other/pdbimgtopam.c b/converter/other/pdbimgtopam.c
index 4c064630..55a2ec70 100644
--- a/converter/other/pdbimgtopam.c
+++ b/converter/other/pdbimgtopam.c
@@ -64,9 +64,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the strings we return are stored in the storage that
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -85,7 +83,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (!notefileSpec)
diff --git a/converter/other/pgmtopbm.c b/converter/other/pgmtopbm.c
index d5f67a06..b71904d8 100644
--- a/converter/other/pgmtopbm.c
+++ b/converter/other/pgmtopbm.c
@@ -47,9 +47,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the file spec array we return is stored in the storage that
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -83,7 +81,7 @@ parseCommandLine(int argc, const char ** argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We may have parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (floydOpt + thresholdOpt + hilbertOpt + dither8Opt +
diff --git a/converter/other/pgmtoppm.c b/converter/other/pgmtoppm.c
index dea6c4ca..822ddac7 100644
--- a/converter/other/pgmtoppm.c
+++ b/converter/other/pgmtoppm.c
@@ -48,9 +48,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the strings we return are stored in the storage that
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -74,8 +72,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
-        /* Uses and sets argc, argv, and some of *cmdlineP and others. */
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
 
     if (!mapSpec)
         cmdlineP->map = NULL;
diff --git a/converter/other/pngtopam.c b/converter/other/pngtopam.c
index a700364f..acb04599 100644
--- a/converter/other/pngtopam.c
+++ b/converter/other/pngtopam.c
@@ -73,9 +73,7 @@ parseCommandLine(int                  argc,
    Note that the strings we return are stored in the storage that
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
-    optEntry * option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -109,7 +107,7 @@ parseCommandLine(int                  argc,
     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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
 
diff --git a/converter/other/pnmtojpeg.c b/converter/other/pnmtojpeg.c
index 99efa734..b80860e7 100644
--- a/converter/other/pnmtojpeg.c
+++ b/converter/other/pnmtojpeg.c
@@ -212,9 +212,7 @@ parseCommandLine(const int argc, const char ** argv,
    On the other hand, unlike other option processing functions, we do
    not change argv at all.
 -----------------------------------------------------------------------------*/
-    optEntry * option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     int i;  /* local loop variable */
@@ -285,7 +283,7 @@ parseCommandLine(const int argc, const 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(&argcParse, (char **)argvParse, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argcParse, argvParse, opt, sizeof(opt), 0);
 
     if (!qualitySpec)
         cmdlineP->quality = -1;  /* unspecified */
diff --git a/converter/other/pnmtopng.c b/converter/other/pnmtopng.c
index 08647045..10b586b0 100644
--- a/converter/other/pnmtopng.c
+++ b/converter/other/pnmtopng.c
@@ -284,9 +284,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the strings we return are stored in the storage that
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -383,7 +381,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
 
diff --git a/converter/other/pnmtops.c b/converter/other/pnmtops.c
index d2577dd6..3dd0be79 100644
--- a/converter/other/pnmtops.c
+++ b/converter/other/pnmtops.c
@@ -264,7 +264,7 @@ parseCommandLine(int argc, const char ** argv,
     opt.short_allowed = FALSE;
     opt.allowNegNum = FALSE;
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
 
     if (cmdlineP->mustturn && noturn)
         pm_error("You cannot specify both -turn and -noturn");
diff --git a/converter/other/pnmtorle.c b/converter/other/pnmtorle.c
index a75ab218..e8a37d9b 100644
--- a/converter/other/pnmtorle.c
+++ b/converter/other/pnmtorle.c
@@ -71,9 +71,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the file spec array we return is stored in the storage that
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
-    optEntry * option_def;
-    /* Instructions to pm_optParseOptions3 on how to parse our options. */
-
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -92,7 +90,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     free(option_def);
diff --git a/converter/other/qoitopam.c b/converter/other/qoitopam.c
index 51dfd1e8..68182aa3 100644
--- a/converter/other/qoitopam.c
+++ b/converter/other/qoitopam.c
@@ -74,9 +74,7 @@ parseCommandLine(int                  argc,
    Note that the strings we return are stored in the storage that
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
-    optEntry * option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -89,7 +87,7 @@ parseCommandLine(int                  argc,
     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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc-1 < 1)
diff --git a/converter/other/rasttopnm.c b/converter/other/rasttopnm.c
index 7f6015a3..bc199ef7 100644
--- a/converter/other/rasttopnm.c
+++ b/converter/other/rasttopnm.c
@@ -37,9 +37,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the file spec array we return is stored in the storage that
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
-    optEntry * option_def;
-        /* Instructions to OptParseOptions2 on how to parse our options.
-         */
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -59,7 +57,7 @@ parseCommandLine(int argc, const char ** argv,
     OPTENT3(0,   "dumpcolormap", OPT_FLAG,   NULL,
             &cmdlineP->dumpcolormap,   0);
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc-1 == 0)
diff --git a/converter/other/sgitopnm.c b/converter/other/sgitopnm.c
index 4bacc411..09bdc669 100644
--- a/converter/other/sgitopnm.c
+++ b/converter/other/sgitopnm.c
@@ -56,9 +56,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the strings we return are stored in the storage that
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
-    optEntry * option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -78,7 +76,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     free(option_def);
diff --git a/converter/other/srftopam.c b/converter/other/srftopam.c
index 78d535fb..857d6d92 100644
--- a/converter/other/srftopam.c
+++ b/converter/other/srftopam.c
@@ -46,9 +46,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the strings we return are stored in the storage that
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def;
-    /* Instructions to pm_optParseOptions3 on how to parse our options.
-     */
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -63,7 +61,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
     /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc-1 < 1)
diff --git a/converter/other/tifftopnm.c b/converter/other/tifftopnm.c
index 44b3461b..0fbbaad0 100644
--- a/converter/other/tifftopnm.c
+++ b/converter/other/tifftopnm.c
@@ -105,8 +105,8 @@ parseCommandLine(int argc, const char ** const argv,
    sometimes, one of these strings is actually just a suffix of an entry
    in argv!
 -----------------------------------------------------------------------------*/
+    optEntry * option_def;
     optStruct3 opt;
-    optEntry *option_def;
     unsigned int option_def_index;
     unsigned int alphaSpec;
 
@@ -130,7 +130,7 @@ parseCommandLine(int argc, const char ** const argv,
     OPTENT3(0,   "alphaout",
             OPT_STRING, &cmdlineP->alphaFilename, &alphaSpec,  0);
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
 
     if (argc - 1 == 0)
         cmdlineP->inputFilename = strdup("-");  /* he wants stdin */
diff --git a/converter/other/winicontopam.c b/converter/other/winicontopam.c
index bb39bf60..b0dbbc07 100644
--- a/converter/other/winicontopam.c
+++ b/converter/other/winicontopam.c
@@ -86,7 +86,7 @@ parseCommandLine(int argc, const char **argv,
     opt3.short_allowed = false;
     opt3.allowNegNum   = false;
 
-    pm_optParseOptions3(&argc, (char **)argv, opt3, sizeof(opt3), 0);
+    pm_optParseOptions4(&argc, argv, opt3, sizeof(opt3), 0);
 
     if (cmdlineP->allimages && cmdlineP->imageSpec)
         pm_error("You cannot specify both -allimages and -image");
diff --git a/converter/other/xwdtopnm.c b/converter/other/xwdtopnm.c
index 810d302a..5f8a56c9 100644
--- a/converter/other/xwdtopnm.c
+++ b/converter/other/xwdtopnm.c
@@ -95,9 +95,7 @@ parseCommandLine(int argc, const char ** argv,
    sometimes, one of these strings is actually just a suffix of an entry
    in argv!
 -----------------------------------------------------------------------------*/
-    optEntry * option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;   /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -115,7 +113,7 @@ parseCommandLine(int argc, const char ** argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We may have parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, (char **) argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc - 1 == 0)
diff --git a/converter/other/yuy2topam.c b/converter/other/yuy2topam.c
index b4742bf5..8416d393 100644
--- a/converter/other/yuy2topam.c
+++ b/converter/other/yuy2topam.c
@@ -44,8 +44,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the strings we return are stored in the storage that
    was passed to us as the argv array.  We also trash *argv.
 --------------------------------------------------------------------------*/
-    optEntry * option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options. */
+    optEntry * option_def; /* Used by OPTENT3 */
     optStruct3 opt;
 
     unsigned int widthSpec, heightSpec;
@@ -63,7 +62,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (!widthSpec)
diff --git a/converter/pbm/g3topbm.c b/converter/pbm/g3topbm.c
index 56462768..80b7b37d 100644
--- a/converter/pbm/g3topbm.c
+++ b/converter/pbm/g3topbm.c
@@ -96,7 +96,6 @@ parseCommandLine(int argc, const char ** const argv,
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
     optEntry * option_def;  /* malloc'ed */
-        /* Instructions to OptParseOptions3 on how to parse our options.  */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -126,7 +125,7 @@ parseCommandLine(int argc, const char ** const argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We may have parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, (char**)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (widthSpec && paper_sizeSpec)
diff --git a/converter/pbm/pbmtoepsi.c b/converter/pbm/pbmtoepsi.c
index 7ffd6103..bfa87032 100644
--- a/converter/pbm/pbmtoepsi.c
+++ b/converter/pbm/pbmtoepsi.c
@@ -26,14 +26,15 @@
 */
 
 #include "pm_c_util.h"
-#include "pbm.h"
+#include "mallocvar.h"
 #include "shhopt.h"
+#include "pbm.h"
 
-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 *inputFileName;
+    const char * inputFileName;
 
     unsigned int dpiX;     /* horiz component of DPI option */
     unsigned int dpiY;     /* vert component of DPI option */
@@ -80,21 +81,20 @@ parseDpi(char *         const dpiOpt,
 
 static void
 parseCommandLine(int argc, const char ** const argv,
-                 struct cmdlineInfo * const cmdlineP) {
+                 struct CmdlineInfo * const cmdlineP) {
 /*----------------------------------------------------------------------------
    Note that the file spec array we return is stored in the storage that
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def = malloc(100*sizeof(optEntry));
-        /* Instructions to OptParseOptions2 on how to parse our options.
-         */
+    optEntry * option_def;
     optStruct3 opt;
-
     unsigned int option_def_index;
 
     char * dpiOpt;
     unsigned int dpiOptSpec;
 
+    MALLOCARRAY_NOFAIL(option_def, 100);
+
     option_def_index = 0;   /* incremented by OPTENTRY */
     OPTENT3(0, "bbonly",     OPT_FLAG,   NULL, &cmdlineP->bbonly,        0);
     OPTENT3(0, "verbose",    OPT_FLAG,   NULL, &cmdlineP->verbose,       0);
@@ -104,7 +104,7 @@ parseCommandLine(int argc, const char ** const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
 
@@ -235,7 +235,7 @@ eightPixels(bit ** const bits,
 int
 main(int argc, const char * argv[]) {
 
-    struct cmdlineInfo cmdline;
+    struct CmdlineInfo cmdline;
     FILE * ifP;
     bit ** bits;
     int rows, cols;
diff --git a/converter/pbm/pbmtoepson.c b/converter/pbm/pbmtoepson.c
index 69742368..293167ac 100644
--- a/converter/pbm/pbmtoepson.c
+++ b/converter/pbm/pbmtoepson.c
@@ -55,11 +55,8 @@ parseCommandLine(int                  argc,
    Note that the strings we return are stored in the storage that
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;
     optStruct3 opt;
-
     unsigned int option_def_index;
 
     char * protocol;
@@ -82,7 +79,7 @@ parseCommandLine(int                  argc,
     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);
+    pm_optParseOptions4( &argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
 
diff --git a/converter/pbm/pbmtoescp2.c b/converter/pbm/pbmtoescp2.c
index 54a77e44..d4d98388 100644
--- a/converter/pbm/pbmtoescp2.c
+++ b/converter/pbm/pbmtoescp2.c
@@ -49,12 +49,15 @@ parseCommandLine(int argc, const char ** argv,
                  struct CmdlineInfo *cmdlineP) {
 
     optStruct3 opt;
-    unsigned int option_def_index = 0;
-    optEntry * option_def = malloc(100*sizeof(optEntry));
+    unsigned int option_def_index;
+    optEntry * option_def;
 
     unsigned int compressSpec, resolutionSpec, stripeHeightSpec,
                  rawSpec, formfeedSpec;
 
+    MALLOCARRAY(option_def, 100);
+
+    option_def_index = 0;
     opt.opt_table = option_def;
     opt.short_allowed = FALSE;
     opt.allowNegNum = FALSE;
@@ -69,7 +72,7 @@ parseCommandLine(int argc, const char ** argv,
     OPTENT3(0, "formfeed",     OPT_FLAG,    NULL,
             &formfeedSpec,    0);
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
 
     if (argc-1 > 1)
         pm_error("Too many arguments: %d.  "
diff --git a/converter/pbm/pbmtog3.c b/converter/pbm/pbmtog3.c
index 48de8885..ac190d22 100644
--- a/converter/pbm/pbmtog3.c
+++ b/converter/pbm/pbmtog3.c
@@ -57,11 +57,11 @@ parseCommandLine(int argc, const char ** const argv,
     optEntry * option_def;
         /* Instructions to OptParseOptions2 on how to parse our options.  */
     optStruct3 opt;
+    unsigned int option_def_index;
+
     unsigned int nofixedwidth;
     unsigned int align8, align16;
 
-    unsigned int option_def_index;
-
     MALLOCARRAY_NOFAIL(option_def, 100);
 
     option_def_index = 0;   /* incremented by OPTENTRY */
@@ -84,7 +84,7 @@ parseCommandLine(int argc, const char ** const argv,
     opt.short_allowed = false;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = true;  /* We may have parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     free(option_def);
diff --git a/converter/pbm/pbmtolj.c b/converter/pbm/pbmtolj.c
index 1936544f..1805206b 100644
--- a/converter/pbm/pbmtolj.c
+++ b/converter/pbm/pbmtolj.c
@@ -67,11 +67,9 @@ parseCommandLine(int argc, const char ** argv,
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
     optEntry *option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
-         */
     optStruct3 opt;
-
     unsigned int option_def_index;
+
     unsigned int dpiSpec, copiesSpec, compressSpec;
 
     MALLOCARRAY(option_def, 100);
@@ -96,7 +94,7 @@ parseCommandLine(int argc, const char ** argv,
     opt.short_allowed = false;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = false;  /* We may have parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc-1 == 0)
diff --git a/converter/pbm/pbmtolps.c b/converter/pbm/pbmtolps.c
index 2c6b01a0..e1e057f8 100644
--- a/converter/pbm/pbmtolps.c
+++ b/converter/pbm/pbmtolps.c
@@ -69,9 +69,7 @@ parseCommandLine(int                        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);
@@ -86,7 +84,7 @@ parseCommandLine(int                        argc,
     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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (cmdlineP->dpiSpec)
diff --git a/converter/pbm/pbmtomacp.c b/converter/pbm/pbmtomacp.c
index 5fa54ad6..0a6dcf93 100644
--- a/converter/pbm/pbmtomacp.c
+++ b/converter/pbm/pbmtomacp.c
@@ -73,7 +73,6 @@ parseCommandLine(int                        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 norleSpec;
@@ -98,7 +97,7 @@ parseCommandLine(int                        argc,
     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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     cmdlineP->norle = norleSpec;
diff --git a/converter/pbm/pbmtomda.c b/converter/pbm/pbmtomda.c
index 2ed862fc..f684276f 100644
--- a/converter/pbm/pbmtomda.c
+++ b/converter/pbm/pbmtomda.c
@@ -46,8 +46,6 @@ parseCommandLine(int argc, const char ** argv,
    was passed to as as the argv array.
 -----------------------------------------------------------------------------*/
     optEntry * option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -62,7 +60,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others */
 
     if (argc-1 < 1)
diff --git a/converter/pbm/pbmtoxbm.c b/converter/pbm/pbmtoxbm.c
index 4bd33dd8..a452d6fa 100644
--- a/converter/pbm/pbmtoxbm.c
+++ b/converter/pbm/pbmtoxbm.c
@@ -61,8 +61,6 @@ parseCommandLine(int                 argc,
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
     optEntry * option_def;
-    /* Instructions to pm_optParseOptions3 on how to parse our options. */
-
     optStruct3 opt;
     unsigned int option_def_index;
     unsigned int x10, x11, nameSpec;
@@ -78,7 +76,7 @@ parseCommandLine(int                 argc,
     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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (!nameSpec)
diff --git a/converter/pbm/pi3topbm.c b/converter/pbm/pi3topbm.c
index 82665f6c..36ff4127 100644
--- a/converter/pbm/pi3topbm.c
+++ b/converter/pbm/pi3topbm.c
@@ -56,7 +56,6 @@ parseCommandLine(int argc,
 --------------------------------------------------------------------------*/
     optEntry * option_def;
     optStruct3 opt;
-        /* Instructions to pm_optParseOptions3 on how to parse our options. */
     unsigned int option_def_index;
 
     MALLOCARRAY_NOFAIL(option_def, 100);
@@ -68,7 +67,7 @@ parseCommandLine(int argc,
     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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc-1 < 1)
diff --git a/converter/pbm/pktopbm.c b/converter/pbm/pktopbm.c
index c45af082..201b046a 100644
--- a/converter/pbm/pktopbm.c
+++ b/converter/pbm/pktopbm.c
@@ -52,8 +52,6 @@ parseCommandLine(int argc, const char ** argv,
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
     optEntry * option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -80,7 +78,7 @@ parseCommandLine(int argc, const char ** argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We may have parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (characterSpec) {
diff --git a/converter/pgm/rawtopgm.c b/converter/pgm/rawtopgm.c
index 7eb68694..a90bbf46 100644
--- a/converter/pgm/rawtopgm.c
+++ b/converter/pgm/rawtopgm.c
@@ -45,8 +45,6 @@ parseCommandLine(int argc, const char ** argv,
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
     optEntry * option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
-         */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -85,7 +83,7 @@ parseCommandLine(int argc, const char ** argv,
     opt.short_allowed = false;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = false;  /* We may have parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc-1 == 0) {
diff --git a/converter/pgm/sbigtopgm.c b/converter/pgm/sbigtopgm.c
index 8b28f740..c56d5eae 100644
--- a/converter/pgm/sbigtopgm.c
+++ b/converter/pgm/sbigtopgm.c
@@ -46,8 +46,6 @@ parseCommandLine(int argc, const char ** argv,
    was passed to as as the argv array.
 -----------------------------------------------------------------------------*/
     optEntry * option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -60,7 +58,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others */
 
     if (argc-1 < 1)
diff --git a/converter/ppm/411toppm.c b/converter/ppm/411toppm.c
index a50e5145..9d338fa7 100644
--- a/converter/ppm/411toppm.c
+++ b/converter/ppm/411toppm.c
@@ -86,8 +86,6 @@ parseCommandLine(int argc, const char ** argv,
 -----------------------------------------------------------------------------*/
 
     optEntry * option_def;
-        /* Instructions to OptParseOptions2 on how to parse our options.
-         */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -106,7 +104,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (cmdlineP->width <= 0)
diff --git a/converter/ppm/pcxtoppm.c b/converter/ppm/pcxtoppm.c
index 05e09d73..f06dd4e8 100644
--- a/converter/ppm/pcxtoppm.c
+++ b/converter/ppm/pcxtoppm.c
@@ -87,13 +87,13 @@ parseCommandLine(int argc, const char ** argv,
    Note that the strings we return are stored in the storage that
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def = malloc( 100*sizeof( optEntry ) );
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;
     optStruct3 opt;
 
     unsigned int option_def_index;
 
+    MALLOCARRAY_NOFAIL(option_def, 100);
+
     option_def_index = 0;   /* incremented by OPTENT3 */
     OPTENT3(0, "stdpalette",     OPT_FLAG,   NULL,
             &cmdlineP->stdpalette,    0 );
@@ -101,10 +101,10 @@ parseCommandLine(int argc, const char ** argv,
             &cmdlineP->verbose,       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 */
+    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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdline_p and others. */
 
     if (argc-1 < 1)
diff --git a/converter/ppm/picttoppm.c b/converter/ppm/picttoppm.c
index 8ca553bd..fc73a92c 100644
--- a/converter/ppm/picttoppm.c
+++ b/converter/ppm/picttoppm.c
@@ -78,7 +78,6 @@ parseCommandLine(int argc,
 --------------------------------------------------------------------------*/
     optEntry * option_def;
     optStruct3 opt;
-        /* Instructions to pm_optParseOptions3 on how to parse our options. */
 
     unsigned int option_def_index;
 
@@ -102,7 +101,7 @@ parseCommandLine(int argc,
     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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (!fontdirSpec)
diff --git a/converter/ppm/ppmtoarbtxt.c b/converter/ppm/ppmtoarbtxt.c
index cb2c388b..a8d7a004 100644
--- a/converter/ppm/ppmtoarbtxt.c
+++ b/converter/ppm/ppmtoarbtxt.c
@@ -62,8 +62,6 @@ parseCommandLine(int argc, const char ** argv,
    in argv!
 -----------------------------------------------------------------------------*/
     optEntry * option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
-         */
     optStruct3 opt;
 
     unsigned int hdSpec, tlSpec;
@@ -84,7 +82,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
     free(option_def);
 
     if (!hdSpec)
diff --git a/converter/ppm/ppmtoascii.c b/converter/ppm/ppmtoascii.c
index 524bcd2c..b7c6669d 100644
--- a/converter/ppm/ppmtoascii.c
+++ b/converter/ppm/ppmtoascii.c
@@ -102,7 +102,6 @@ parseCommandLine(int argc, const char **argv,
                  struct cmdlineInfo * const cmdlineP) {
 
     optEntry * option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -118,7 +117,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (dim1x2Spec && dim2x4Spec)
diff --git a/converter/ppm/ppmtobmp.c b/converter/ppm/ppmtobmp.c
index 8590c5ef..ed44b83a 100644
--- a/converter/ppm/ppmtobmp.c
+++ b/converter/ppm/ppmtobmp.c
@@ -17,6 +17,7 @@
 #define _BSD_SOURCE 1    /* Make sure strdup() is in string.h */
 #define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */
 
+#include <stdbool.h>
 #include <assert.h>
 #include <string.h>
 
@@ -87,8 +88,6 @@ parseCommandLine(int argc, const char ** argv,
    in argv!
 -----------------------------------------------------------------------------*/
     optEntry * option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
-         */
     optStruct3 opt;
 
     unsigned int windowsSpec, os2Spec, mapfileSpec;
@@ -106,10 +105,10 @@ parseCommandLine(int argc, const char ** argv,
             &mapfileSpec,             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 */
+    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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
 
     if (windowsSpec && os2Spec)
         pm_error("Can't specify both -windows and -os2 options.");
diff --git a/converter/ppm/ppmtogif.c b/converter/ppm/ppmtogif.c
index 0564b7b4..b50a934d 100644
--- a/converter/ppm/ppmtogif.c
+++ b/converter/ppm/ppmtogif.c
@@ -14,6 +14,7 @@
 #define _BSD_SOURCE   /* Make sure strdup() is in string.h */
 #define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */
 
+#include <stdbool.h>
 #include <assert.h>
 #include <string.h>
 #include <stdio.h>
@@ -144,10 +145,10 @@ parseCommandLine(int argc, const char ** argv,
         */
 
     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 */
+    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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (latex2htmlhack)
diff --git a/converter/ppm/ppmtoicr.c b/converter/ppm/ppmtoicr.c
index de21fc68..2c9fd3a1 100644
--- a/converter/ppm/ppmtoicr.c
+++ b/converter/ppm/ppmtoicr.c
@@ -50,9 +50,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the file spec array we return is stored in the storage that
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -75,10 +73,10 @@ parseCommandLine(int argc, const char ** argv,
             &rleSpec,        0);
 
     opt.opt_table = option_def;
-    opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
-    opt.allowNegNum = FALSE;  /* We may have parms that are negative numbers */
+    opt.short_allowed = false;  /* We have no short (old-fashioned) options */
+    opt.allowNegNum = false;  /* We may have parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (!expandSpec)
diff --git a/converter/ppm/ppmtopcx.c b/converter/ppm/ppmtopcx.c
index 5b7e1003..68ad4db0 100644
--- a/converter/ppm/ppmtopcx.c
+++ b/converter/ppm/ppmtopcx.c
@@ -17,6 +17,7 @@
 ** http://bespin.org/~qz/pc-gpe/pcx.txt
 ** http://web.archive.org/web/20100206055706/http://www.qzx.com/pc-gpe/pcx.txt
 */
+#include <stdbool.h>
 #include <assert.h>
 
 #include "pm_c_util.h"
@@ -83,8 +84,6 @@ parseCommandLine(int argc, const char ** argv,
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
     optEntry * option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -112,10 +111,10 @@ parseCommandLine(int argc, const char ** argv,
     OPTENT3(0, "ypos",  OPT_INT, &cmdlineP->ypos, &yposSpec,   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 */
+    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 );
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0 );
         /* Uses and sets argc, argv, and some of *cmdline_p and others. */
 
     if (!xposSpec)
diff --git a/converter/ppm/ppmtosixel.c b/converter/ppm/ppmtosixel.c
index 4fdf6a66..24454214 100644
--- a/converter/ppm/ppmtosixel.c
+++ b/converter/ppm/ppmtosixel.c
@@ -102,7 +102,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     cmdlineP->charWidth = opt7Bit ? CHARWIDTH_7BIT : CHARWIDTH_8BIT;
diff --git a/converter/ppm/ppmtospu.c b/converter/ppm/ppmtospu.c
index df0fb970..4ba70f02 100644
--- a/converter/ppm/ppmtospu.c
+++ b/converter/ppm/ppmtospu.c
@@ -5,6 +5,7 @@
  *  Copyright (C) 1990, Steve Belczyk
  */
 
+#include <stdbool.h>
 #include <assert.h>
 #include <stdio.h>
 
@@ -56,10 +57,10 @@ parseCommandLine(int argc, const char ** argv,
             NULL,                       &d4Spec, 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 */
+    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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
 
diff --git a/converter/ppm/ppmtoterm.c b/converter/ppm/ppmtoterm.c
index 6e41a8cb..b1d94fa2 100644
--- a/converter/ppm/ppmtoterm.c
+++ b/converter/ppm/ppmtoterm.c
@@ -19,6 +19,7 @@
 **
 */
 
+#include <stdbool.h>
 #include <assert.h>
 #include <string.h>
 
@@ -43,7 +44,6 @@ parseCommandLine(int argc, const char ** argv,
                  struct cmdlineInfo * const cmdlineP) {
 
     optEntry * option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -54,10 +54,10 @@ parseCommandLine(int argc, const char ** argv,
     OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 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 */
+    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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc-1 < 1)
diff --git a/converter/ppm/ppmtowinicon.c b/converter/ppm/ppmtowinicon.c
index bd478b1e..2d8ddaf7 100644
--- a/converter/ppm/ppmtowinicon.c
+++ b/converter/ppm/ppmtowinicon.c
@@ -10,6 +10,7 @@
 ** implied warranty.
 */
 
+#include <stdbool.h>
 #include <assert.h>
 #include <math.h>
 #include <string.h>
@@ -57,9 +58,7 @@ parseCommandLine(int                  argc,
    Note that the strings we return are stored in the storage that
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -79,10 +78,10 @@ parseCommandLine(int                  argc,
             &cmdlineP->verbose,            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 */
+    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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (!outputSpec)
@@ -272,14 +271,14 @@ fillInRaster1(u1 **           const rowData,
 
     for (row = 0; row <rows; ++row) {
         u1 * thisRow;  /* malloc'ed */
-        unsigned int byteOn;
-        unsigned int bitOn;
+        unsigned int byteSeq;
+        unsigned int bitOnMask;
 
         MALLOCARRAY_NOFAIL(thisRow, xByteCt);
-        memset (thisRow, 0, xByteCt);
+        memset(thisRow, 0, xByteCt);  /* initial value */
         rowData[rows - row - 1] = thisRow;
-        byteOn =   0;  /* initial value */
-        bitOn  = 128;  /* initial value */
+        byteSeq   = 0;    /* initial value */
+        bitOnMask = 0x80; /* initial value */
 
         if (pa) {
             unsigned int col;
@@ -291,16 +290,19 @@ fillInRaster1(u1 **           const rowData,
                    Unless the hashing function changes, 0's black.
                 */
                 int const value = ppm_lookupcolor(cht, &pa[row][col]);
+
+                assert(byteSeq < xByteCt);
+
                 if (!value) {
                     /* leave black. */
                 } else {
-                    thisRow[byteOn] |= bitOn;
+                    thisRow[byteSeq] |= bitOnMask;
                 }
-                if (bitOn == 1) {
-                    ++byteOn;
-                    bitOn = 128;
+                if (bitOnMask == 0x1) {
+                    ++byteSeq;
+                    bitOnMask = 0x80;
                 } else {
-                    bitOn >>= 1;
+                    bitOnMask >>= 1;
                 }
             }
         } else {
@@ -323,15 +325,15 @@ fillInRaster4(u1 **           const rowData,
 
     for (row = 0; row < rows; ++row) {
         u1 * thisRow;
-        unsigned int byteOn;
-        unsigned int nibble;   /* high nibble = 1, low nibble = 0; */
+        unsigned int byteSeq;
+        unsigned int nibbleSig;   /* high nibble = 1, low nibble = 0; */
 
         MALLOCARRAY_NOFAIL(thisRow, xByteCt);
 
         memset(thisRow, 0, xByteCt);
         rowData[rows - row - 1] = thisRow;
-        byteOn = 0;  /* initial value */
-        nibble = 1;  /* initial value */
+        byteSeq   = 0;  /* initial value */
+        nibbleSig = 1;  /* initial value */
 
         if (pa) {
             unsigned int col;
@@ -339,16 +341,18 @@ fillInRaster4(u1 **           const rowData,
             for (col = 0; col < cols; ++col) {
                 int value;
 
+                assert(byteSeq < xByteCt);
+
                 value = ppm_lookupcolor(cht, &pa[row][col]);  /* init value */
                 /* Shift it, if we're putting it in the high nibble. */
-                if (nibble)
+                if (nibbleSig == 1)
                     value <<= 4;
-                thisRow[byteOn] |= value;
-                if (nibble == 1)
-                    nibble = 0;
+                thisRow[byteSeq] |= value;
+                if (nibbleSig == 1)
+                    nibbleSig = 0;
                 else {
-                    nibble = 1;
-                    ++byteOn;
+                    nibbleSig = 1;
+                    ++byteSeq;
                 }
             }
         } else {
@@ -372,8 +376,10 @@ fillInRaster8(u1 **           const rowData,
     for (row = 0; row < rows; ++row) {
         u1 * thisRow;  /* malloc'ed */
 
+        assert(cols <= xByteCt);
+
         MALLOCARRAY_NOFAIL(thisRow, xByteCt);
-        memset (thisRow, 0, xByteCt);
+        memset(thisRow, 0, xByteCt);
         rowData[rows - row - 1] = thisRow;
         if (pa) {
             unsigned int col;
diff --git a/converter/ppm/ppmtoxpm.c b/converter/ppm/ppmtoxpm.c
index 2167acb2..4a3336b0 100644
--- a/converter/ppm/ppmtoxpm.c
+++ b/converter/ppm/ppmtoxpm.c
@@ -97,9 +97,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the file spec array we return is stored in the storage that
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -125,10 +123,10 @@ parseCommandLine(int argc, const char ** argv,
     cmdlineP->rgb = NULL;      /* no rgb file specified */
 
     opt.opt_table = option_def;
-    opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
-    opt.allowNegNum = FALSE;  /* We may have parms that are negative numbers */
+    opt.short_allowed = false;  /* We have no short (old-fashioned) options */
+    opt.allowNegNum = false;  /* We may have parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc-1 == 0)
diff --git a/converter/ppm/winicontoppm.c b/converter/ppm/winicontoppm.c
index 54bc0809..f7847df5 100644
--- a/converter/ppm/winicontoppm.c
+++ b/converter/ppm/winicontoppm.c
@@ -18,6 +18,7 @@
 #define _BSD_SOURCE 1      /* Make sure strdup() is in string.h */
 #define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */
 
+#include <stdbool.h>
 #include <math.h>
 #include <string.h>
 #include <assert.h>
@@ -66,8 +67,6 @@ parseCommandLine (int argc, const char ** argv,
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
     optEntry * option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -87,10 +86,10 @@ parseCommandLine (int argc, const char ** argv,
             &cmdlineP->verbose,        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 */
+    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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc-1 < 1)
diff --git a/converter/ppm/ximtoppm.c b/converter/ppm/ximtoppm.c
index b82463c3..c5ba7e80 100644
--- a/converter/ppm/ximtoppm.c
+++ b/converter/ppm/ximtoppm.c
@@ -57,10 +57,10 @@ parseCommandLine(int argc, const char ** argv,
             &cmdlineP->alphaFilename, &alphaoutSpec, 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 */
+    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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and all of *cmdlineP. */
 
     if (!alphaoutSpec)
diff --git a/converter/ppm/yuvtoppm.c b/converter/ppm/yuvtoppm.c
index 87f541e5..5ee250e2 100644
--- a/converter/ppm/yuvtoppm.c
+++ b/converter/ppm/yuvtoppm.c
@@ -43,7 +43,6 @@ parseCommandLine(int argc, const char ** argv,
                  struct CmdlineInfo * const cmdlineP) {
 
     optEntry * option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options */
     optStruct3 opt;
     unsigned int option_def_index;
 
@@ -55,7 +54,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc-1 < 2)
diff --git a/doc/HISTORY b/doc/HISTORY
index 3a79d9b8..7416a4ba 100644
--- a/doc/HISTORY
+++ b/doc/HISTORY
@@ -4,20 +4,41 @@ Netpbm.
 CHANGE HISTORY 
 --------------
 
-24.03.11 BJH  Release 11.05.03
+24.03.30 BJH  Release 11.06.00
 
-              infotopam: fix incorrect output -- columns always in wrong
-              place.  Always broken.  (infotopam was new in Netpbm 10.22 (May
-              2004)).
+              pamcut: add -reportonly.
+
+              infotopam: Add input validation.
+
+              infotopam: Remove input file name from messages.  Add -verbose
+              and issue informational message only if it is specified.
+
+              libnetpbm: Don't ignore garbage at the end of a color specifier
+              (e.g. rgbi:0/.5/1xyz).
 
-24.01.28 BJH  Release 11.05.02
+              color database: change names of "Spring Green", "Lamp Black",
+              and "light grey" to "SpringGreen", "LampBlack", and "LightGrey"
+              to be consistent with other color names.
+
+              pamcut: fix incorrect output when rectangle to cut is entirely
+              above the input image.  Invisible junk after image.  Always
+              broken.  (The ability to cut outside the input image was new in
+              pamcut's predecessor pnmcut in Netpbm 9.7 (August 2000).
+
+              pamcut: fix incorrect output with PBM input when rectangle to
+              cut is entirely below the input image.  Invisible junk after
+              image.  Broken in Netpbm 10.44 (September 2008).
 
               ppmtowinicon: fix array overrun with 4 and 8 bits per pixel.
               Broken in Netpbm 11.05 (December 2023).
 
-23.12.28 BJH  Release 11.05.01
+              infotopam: fix incorrect output -- columns always in wrong
+              place.  Always broken.  (infotopam was new in Netpbm 10.22 (May
+              2004)).
+
+              pamseq: fix typo in error message.
 
-              Fix typo in ppmforge test case.
+              build: makeman: fix warning about backslashes in strings.
 
 23.12.28 BJH  Release 11.05.00
 
diff --git a/editor/pambackground.c b/editor/pambackground.c
index 218f5b7e..2aed88c1 100644
--- a/editor/pambackground.c
+++ b/editor/pambackground.c
@@ -22,7 +22,7 @@ parseCommandLine(int argc, const char ** const argv,
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
     optEntry *option_def;
-        /* Instructions to OptParseOptions2 on how to parse our options.
+        /* Instructions to OptParseOptions3 on how to parse our options.
          */
     optStruct3 opt;
 
diff --git a/editor/pamcut.c b/editor/pamcut.c
index 7870fd70..b6190098 100644
--- a/editor/pamcut.c
+++ b/editor/pamcut.c
@@ -74,6 +74,7 @@ struct CmdlineInfo {
     unsigned int heightSpec;
     unsigned int height;
     unsigned int pad;
+    unsigned int reportonly;
     unsigned int verbose;
 };
 
@@ -185,6 +186,8 @@ parseCommandLine(int argc, const char ** const argv,
     OPTENT3(0,   "height",     OPT_UINT,   &cmdlineP->height,
             &cmdlineP->heightSpec,      0);
     OPTENT3(0,   "pad",        OPT_FLAG,   NULL, &cmdlineP->pad,           0);
+    OPTENT3(0,   "reportonly", OPT_FLAG,   NULL,
+            &cmdlineP->reportonly, 0);
     OPTENT3(0,   "verbose",    OPT_FLAG,   NULL, &cmdlineP->verbose,       0);
 
     opt.opt_table = option_def;
@@ -318,6 +321,55 @@ near(Location     const loc,
 
 
 static void
+computeCutBoundsOneDim(unsigned int const origSz,
+                       Location     const nearArg,
+                       Location     const farArg,
+                       bool         const dimSpec,
+                       unsigned int const dimArg,
+                       int *        const nearLocP,
+                       int *        const farLocP) {
+/*----------------------------------------------------------------------------
+   Do one dimension (vertical or horizontal) of the function of
+   'computeCutBounds'.
+-----------------------------------------------------------------------------*/
+    if (dimSpec)
+        assert(dimArg > 0);
+
+    if (nearArg.locType == LOCTYPE_NONE) {
+        if (farArg.locType == LOCTYPE_NONE) {
+            *nearLocP = 0;
+            if (dimSpec)
+                *farLocP = 0 + (int)dimArg - 1;
+            else
+                *farLocP = (int)origSz - 1;
+        } else {
+            *farLocP = near(farArg, origSz);
+            if (dimSpec)
+                *nearLocP = near(farArg, origSz) - (int)dimArg + 1;
+            else
+                *nearLocP = 0;
+        }
+    } else {
+        *nearLocP = near(nearArg, origSz);
+        if (farArg.locType == LOCTYPE_NONE) {
+            if (dimSpec)
+                *farLocP = near(nearArg, origSz) + (int)dimArg - 1;
+            else
+                *farLocP = (int)origSz - 1;
+        } else {
+            if (dimSpec) {
+                pm_error("You may not specify left, right, and width "
+                         "or top, bottom, and height.  "
+                         "Choose at most two of each of these sets.");
+            } else
+                *farLocP = near(farArg, origSz);
+        }
+    }
+}
+
+
+
+static void
 computeCutBounds(unsigned int const cols,
                  unsigned int const rows,
                  Location     const leftArg,
@@ -341,75 +393,11 @@ computeCutBounds(unsigned int const cols,
    *botrowP.  Any of these can be outside the image, including by being
    negative.
 -----------------------------------------------------------------------------*/
-    /* Find left and right bounds */
+    computeCutBoundsOneDim(cols, leftArg, rghtArg, widthSpec,  widthArg,
+                           leftColP, rghtColP);
 
-    if (widthSpec)
-        assert(widthArg > 0);
-
-    if (leftArg.locType == LOCTYPE_NONE) {
-        if (rghtArg.locType == LOCTYPE_NONE) {
-            *leftColP = 0;
-            if (widthSpec)
-                *rghtColP = 0 + (int)widthArg - 1;
-            else
-                *rghtColP = (int)cols - 1;
-        } else {
-            *rghtColP = near(rghtArg, cols);
-            if (widthSpec)
-                *leftColP = near(rghtArg, cols) - (int)widthArg + 1;
-            else
-                *leftColP = 0;
-        }
-    } else {
-        *leftColP = near(leftArg, cols);
-        if (rghtArg.locType == LOCTYPE_NONE) {
-            if (widthSpec)
-                *rghtColP = near(leftArg, cols) + (int)widthArg - 1;
-            else
-                *rghtColP = (int)cols - 1;
-        } else {
-            if (widthSpec) {
-                pm_error("You may not specify left, right, and width.  "
-                         "Choose at most two of these.");
-            } else
-                *rghtColP = near(rghtArg, cols);
-        }
-    }
-
-    /* Find top and bottom bounds */
-
-    if (heightSpec)
-        assert(heightArg > 0);
-
-    if (topArg.locType == LOCTYPE_NONE) {
-        if (botArg.locType == LOCTYPE_NONE) {
-            *topRowP = 0;
-            if (heightSpec)
-                *botRowP = 0 + (int)heightArg - 1;
-            else
-                *botRowP = (int)rows - 1;
-        } else {
-            *botRowP = near(botArg, rows);
-            if (heightSpec)
-                *topRowP = near(botArg, rows) - (int)heightArg + 1;
-            else
-                *topRowP = 0;
-        }
-    } else {
-        *topRowP = near(topArg, rows);
-        if (botArg.locType == LOCTYPE_NONE) {
-            if (heightSpec)
-                *botRowP = near(topArg, rows) + (int)heightArg - 1;
-            else
-                *botRowP = (int)rows - 1;
-        } else {
-            if (heightSpec) {
-                pm_error("You may not specify top, bottom, and height.  "
-                         "Choose at most two of these.");
-            } else
-                *botRowP = near(botArg, rows);
-        }
-    }
+    computeCutBoundsOneDim(rows, topArg,  botArg,  heightSpec, heightArg,
+                           topRowP,  botRowP);
 }
 
 
@@ -466,6 +454,46 @@ rejectOutOfBounds(unsigned int const cols,
 
 
 static void
+reportCuts(int          const leftCol,
+           int          const rghtCol,
+           int          const topRow,
+           int          const botRow,
+           unsigned int const oldWidth,
+           unsigned int const oldHeight) {
+
+    /* N.B. column and row numbers can be outside the input image, even
+       negative, which implies padding is required.
+    */
+
+    unsigned int const newWidth  = rghtCol - leftCol + 1;
+    unsigned int const newHeight = botRow  - topRow  + 1;
+
+    assert (rghtCol >= leftCol);
+    assert (botRow  >= topRow );
+
+    printf("%d %d %d %d %u %u %u %u\n",
+           leftCol, rghtCol, topRow, botRow,
+           oldWidth, oldHeight, newWidth, newHeight);
+}
+
+
+
+static void
+drainRaster(const struct pam * const inpamP) {
+/*----------------------------------------------------------------------------
+   Read through the input image described by *inpamP, which is positioned
+   to the raster, so the input stream is properly positioned for whatever
+   is next.
+-----------------------------------------------------------------------------*/
+    unsigned int row;
+
+    for (row = 0; row < inpamP->height; ++row)
+        pnm_readpamrow(inpamP, NULL);
+}
+
+
+
+static void
 writeBlackRows(const struct pam * const outpamP,
                int                const rows) {
 /*----------------------------------------------------------------------------
@@ -495,7 +523,7 @@ writeBlackRows(const struct pam * const outpamP,
 
 
 
-struct rowCutter {
+typedef struct {
 /*----------------------------------------------------------------------------
    This is an object that gives you pointers you can use to effect the
    horizontal cutting and padding of a row just by doing one
@@ -537,7 +565,7 @@ struct rowCutter {
     tuple * copyTuples;
     tuple blackTuple;
     tuple discardTuple;
-};
+} RowCutter;
 
 
 
@@ -554,13 +582,13 @@ struct rowCutter {
 
 
 static void
-createRowCutter(const struct pam *  const inpamP,
-                const struct pam *  const outpamP,
-                int                 const leftcol,
-                int                 const rightcol,
-                struct rowCutter ** const rowCutterPP) {
+createRowCutter(const struct pam * const inpamP,
+                const struct pam * const outpamP,
+                int                const leftcol,
+                int                const rightcol,
+                RowCutter **       const rowCutterPP) {
 
-    struct rowCutter * rowCutterP;
+    RowCutter * rowCutterP;
     tuple * inputPointers;
     tuple * outputPointers;
     tuple * copyTuples;
@@ -624,7 +652,7 @@ createRowCutter(const struct pam *  const inpamP,
 
 
 static void
-destroyRowCutter(struct rowCutter * const rowCutterP) {
+destroyRowCutter(RowCutter * const rowCutterP) {
 
     pnm_freepamrow(rowCutterP->copyTuples);
     pnm_freepamtuple(rowCutterP->blackTuple);
@@ -645,12 +673,12 @@ extractRowsGen(const struct pam * const inpamP,
                int                const toprow,
                int                const bottomrow) {
 
-    struct rowCutter * rowCutterP;
+    RowCutter * rowCutterP;
     int row;
 
     /* Write out top padding */
-    if (0 - toprow > 0)
-        writeBlackRows(outpamP, 0 - toprow);
+    if (toprow < 0)
+        writeBlackRows(outpamP, MIN(0, bottomrow+1) - toprow);
 
     createRowCutter(inpamP, outpamP, leftcol, rightcol, &rowCutterP);
 
@@ -671,14 +699,15 @@ extractRowsGen(const struct pam * const inpamP,
     destroyRowCutter(rowCutterP);
 
     /* Write out bottom padding */
-    if ((bottomrow - (inpamP->height-1)) > 0)
-        writeBlackRows(outpamP, bottomrow - (inpamP->height-1));
+    if (bottomrow >= inpamP->height)
+        writeBlackRows(outpamP, bottomrow - MAX(inpamP->height, toprow) + 1);
+
 }
 
 
 
 static void
-makeBlackPBMRow(unsigned char * const bitrow,
+makeBlackPbmRow(unsigned char * const bitrow,
                 unsigned int    const cols) {
 
     unsigned int const colByteCnt = pbm_packed_bytes(cols);
@@ -695,14 +724,14 @@ makeBlackPBMRow(unsigned char * const bitrow,
 
 
 static void
-extractRowsPBM(const struct pam * const inpamP,
+extractRowsPbm(const struct pam * const inpamP,
                const struct pam * const outpamP,
                int                const leftcol,
                int                const rightcol,
                int                const toprow,
                int                const bottomrow) {
 
-    unsigned char * bitrow;
+    unsigned char * bitrow;   /* read/write buffer */
     int             readOffset, writeOffset;
     int             row;
     unsigned int    totalWidth;
@@ -730,17 +759,16 @@ extractRowsPBM(const struct pam * const inpamP,
     }
 
     bitrow = pbm_allocrow_packed(totalWidth);
+      /* Initialize row buffer to all black for top and side padding */
 
-    if (toprow < 0 || leftcol < 0 || rightcol >= inpamP->width){
-        makeBlackPBMRow(bitrow, totalWidth);
-        if (toprow < 0) {
-            int row;
-            for (row=0; row < 0 - toprow; ++row)
-                pbm_writepbmrow_packed(outpamP->file, bitrow,
-                                       outpamP->width, 0);
-        }
+    /* Write out top padding */
+    if (toprow < 0) {
+        makeBlackPbmRow(bitrow, outpamP->width);
+        for (row = toprow; row < MIN(0, bottomrow+1); ++row)
+            pbm_writepbmrow_packed(outpamP->file, bitrow, outpamP->width, 0);
     }
 
+    makeBlackPbmRow(bitrow, totalWidth);
     for (row = 0; row < inpamP->height; ++row){
         if (row >= toprow && row <= bottomrow) {
             pbm_readpbmrow_bitoffset(inpamP->file, bitrow, inpamP->width,
@@ -757,12 +785,13 @@ extractRowsPBM(const struct pam * const inpamP,
             pnm_readpamrow(inpamP, NULL);    /* read and discard */
     }
 
-    if (bottomrow - (inpamP->height-1) > 0) {
-        int row;
-        makeBlackPBMRow(bitrow, outpamP->width);
-        for (row = 0; row < bottomrow - (inpamP->height-1); ++row)
-            pbm_writepbmrow_packed(outpamP->file, bitrow, outpamP->width, 0);
+    /* Write out bottom padding */
+    if (bottomrow >= inpamP->height) {
+        makeBlackPbmRow(bitrow, outpamP->width);
+        for (row = MAX(inpamP->height, toprow); row < bottomrow+1; ++row)
+             pbm_writepbmrow_packed(outpamP->file, bitrow, outpamP->width, 0);
     }
+
     pbm_freerow_packed(bitrow);
 }
 
@@ -797,23 +826,31 @@ cutOneImage(FILE *             const ifP,
                    toprow, leftcol, bottomrow, rightcol);
     }
 
-    outpam = inpam;    /* Initial value -- most fields should be same */
-    outpam.file   = ofP;
-    outpam.width  = rightcol - leftcol + 1;
-    outpam.height = bottomrow - toprow + 1;
-
-    pnm_writepaminit(&outpam);
-
-    if (PNM_FORMAT_TYPE(outpam.format) == PBM_TYPE)
-        extractRowsPBM(&inpam, &outpam, leftcol, rightcol, toprow, bottomrow);
-    else
-        extractRowsGen(&inpam, &outpam, leftcol, rightcol, toprow, bottomrow);
+    if (cmdline.reportonly) {
+        reportCuts(leftcol, rightcol, toprow, bottomrow,
+                   inpam.width, inpam.height);
+        drainRaster(&inpam);
+    } else {
+        outpam = inpam;    /* Initial value -- most fields should be same */
+        outpam.file   = ofP;
+        outpam.width  = rightcol - leftcol + 1;
+        outpam.height = bottomrow - toprow + 1;
+
+        pnm_writepaminit(&outpam);
+
+        if (PNM_FORMAT_TYPE(outpam.format) == PBM_TYPE)
+            extractRowsPbm(&inpam, &outpam,
+                           leftcol, rightcol, toprow, bottomrow);
+        else
+            extractRowsGen(&inpam, &outpam,
+                           leftcol, rightcol, toprow, bottomrow);
+    }
 }
 
 
 
 int
-main(int argc, const char *argv[]) {
+main(int argc, const char ** const argv) {
 
     FILE * const ofP = stdout;
 
@@ -838,3 +875,5 @@ main(int argc, const char *argv[]) {
 
     return 0;
 }
+
+
diff --git a/editor/pamditherbw.c b/editor/pamditherbw.c
index 694b2c21..4de14b43 100644
--- a/editor/pamditherbw.c
+++ b/editor/pamditherbw.c
@@ -22,26 +22,26 @@
 #include "pm_gamma.h"
 
 
-enum halftone {QT_FS,
+enum Halftone {QT_FS,
                QT_ATKINSON,
                QT_THRESH,
                QT_DITHER8,
                QT_CLUSTER,
                QT_HILBERT};
 
-enum ditherType {DT_REGULAR, DT_CLUSTER};
+enum DitherType {DT_REGULAR, DT_CLUSTER};
 
 static sample blackSample = (sample) PAM_BLACK;
 static sample whiteSample = (sample) PAM_BW_WHITE;
 static tuple  const blackTuple = &blackSample;
 static tuple  const whiteTuple = &whiteSample;
 
-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;
-    enum halftone halftone;
+    const char *  inputFileNm;
+    enum Halftone halftone;
     unsigned int  clumpSize;
         /* Defined only for halftone == QT_HILBERT */
     unsigned int  clusterRadius;
@@ -55,13 +55,13 @@ struct cmdlineInfo {
 
 
 static void
-parseCommandLine(int argc, char ** argv,
-                 struct cmdlineInfo *cmdlineP) {
+parseCommandLine(int argc, const char ** const argv,
+                 struct CmdlineInfo * const cmdlineP) {
 /*----------------------------------------------------------------------------
    Note that the file spec array we return is stored in the storage that
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def;
+    optEntry * option_def;
         /* Instructions to pm_optParseOptions3 on how to parse our options.
          */
     optStruct3 opt;
@@ -98,7 +98,7 @@ parseCommandLine(int argc, char ** argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We may have 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 *cmdlineP and others. */
 
     free(option_def);
@@ -160,9 +160,9 @@ parseCommandLine(int argc, char ** argv,
                  "non-option argument:  the file name",
                  argc-1);
     else if (argc-1 == 1)
-        cmdlineP->inputFilespec = argv[1];
+        cmdlineP->inputFileNm = argv[1];
     else
-        cmdlineP->inputFilespec = "-";
+        cmdlineP->inputFileNm = "-";
 }
 
 
@@ -173,15 +173,15 @@ makeOutputPam(unsigned int const width,
 
     struct pam outpam;
 
-    outpam.size = sizeof(outpam);
-    outpam.len = PAM_STRUCT_SIZE(tuple_type);
-    outpam.file = stdout;
-    outpam.format = PAM_FORMAT;
-    outpam.plainformat = 0;
-    outpam.height = height;
-    outpam.width = width;
-    outpam.depth = 1;
-    outpam.maxval = 1;
+    outpam.size             = sizeof(outpam);
+    outpam.len              = PAM_STRUCT_SIZE(tuple_type);
+    outpam.file             = stdout;
+    outpam.format           = PAM_FORMAT;
+    outpam.plainformat      = 0;
+    outpam.height           = height;
+    outpam.width            = width;
+    outpam.depth            = 1;
+    outpam.maxval           = 1;
     outpam.bytes_per_sample = 1;
     strcpy(outpam.tuple_type, "BLACKANDWHITE");
 
@@ -471,12 +471,12 @@ doHilbert(FILE *       const ifP,
 
 
 
-struct converter {
-    void (*convertRow)(struct converter * const converterP,
+struct Converter {
+    void (*convertRow)(struct Converter * const converterP,
                        unsigned int       const row,
                        tuplen                   grayrow[],
                        tuple                    bitrow[]);
-    void (*destroy)(struct converter * const converterP);
+    void (*destroy)(struct Converter * const converterP);
     unsigned int cols;
     void * stateP;
 };
@@ -505,7 +505,7 @@ struct fsState {
 
 
 static void
-fsConvertRow(struct converter * const converterP,
+fsConvertRow(struct Converter * const converterP,
              unsigned int       const row,
              tuplen                   grayrow[],
              tuple                    bitrow[]) {
@@ -576,7 +576,7 @@ fsConvertRow(struct converter * const converterP,
 
 
 static void
-fsDestroy(struct converter * const converterP) {
+fsDestroy(struct Converter * const converterP) {
 
     struct fsState * const stateP = converterP->stateP;
 
@@ -588,14 +588,14 @@ fsDestroy(struct converter * const converterP) {
 
 
 
-static struct converter
+static struct Converter
 createFsConverter(struct pam * const graypamP,
                   float        const threshFraction,
                   bool         const randomseedSpec,
                   unsigned int const randomseed) {
 
     struct fsState * stateP;
-    struct converter converter;
+    struct Converter converter;
 
     converter.cols       = graypamP->width;
     converter.convertRow = &fsConvertRow;
@@ -655,7 +655,7 @@ struct atkinsonState {
 
 
 static void
-moveAtkinsonErrorWindowDown(struct converter * const converterP) {
+moveAtkinsonErrorWindowDown(struct Converter * const converterP) {
 
     struct atkinsonState * const stateP = converterP->stateP;
 
@@ -676,7 +676,7 @@ moveAtkinsonErrorWindowDown(struct converter * const converterP) {
 
 
 static void
-atkinsonConvertRow(struct converter * const converterP,
+atkinsonConvertRow(struct Converter * const converterP,
                    unsigned int       const row,
                    tuplen                   grayrow[],
                    tuple                    bitrow[]) {
@@ -721,7 +721,7 @@ atkinsonConvertRow(struct converter * const converterP,
 
 
 static void
-atkinsonDestroy(struct converter * const converterP) {
+atkinsonDestroy(struct Converter * const converterP) {
 
     struct atkinsonState * const stateP = converterP->stateP;
 
@@ -735,14 +735,14 @@ atkinsonDestroy(struct converter * const converterP) {
 
 
 
-static struct converter
+static struct Converter
 createAtkinsonConverter(struct pam * const graypamP,
                         float        const threshFraction,
                         bool         const randomseedSpec,
                         unsigned int const randomseed) {
 
     struct atkinsonState * stateP;
-    struct converter converter;
+    struct Converter converter;
     unsigned int relRow;
 
     converter.cols       = graypamP->width;
@@ -787,7 +787,7 @@ struct threshState {
 
 
 static void
-threshConvertRow(struct converter * const converterP,
+threshConvertRow(struct Converter * const converterP,
                  unsigned int       const row,
                  tuplen                   grayrow[],
                  tuple                    bitrow[]) {
@@ -803,18 +803,18 @@ threshConvertRow(struct converter * const converterP,
 
 
 static void
-threshDestroy(struct converter * const converterP) {
+threshDestroy(struct Converter * const converterP) {
     free(converterP->stateP);
 }
 
 
 
-static struct converter
+static struct Converter
 createThreshConverter(struct pam * const graypamP,
                       float        const threshFraction) {
 
     struct threshState * stateP;
-    struct converter converter;
+    struct Converter converter;
 
     MALLOCVAR_NOFAIL(stateP);
 
@@ -838,7 +838,7 @@ struct clusterState {
 
 
 static void
-clusterConvertRow(struct converter * const converterP,
+clusterConvertRow(struct Converter * const converterP,
                   unsigned int       const row,
                   tuplen                   grayrow[],
                   tuple                    bitrow[]) {
@@ -859,7 +859,7 @@ clusterConvertRow(struct converter * const converterP,
 
 
 static void
-clusterDestroy(struct converter * const converterP) {
+clusterDestroy(struct Converter * const converterP) {
 
     struct clusterState * const stateP = converterP->stateP;
     unsigned int const diameter = 2 * stateP->radius;
@@ -876,9 +876,9 @@ clusterDestroy(struct converter * const converterP) {
 
 
 
-static struct converter
+static struct Converter
 createClusterConverter(struct pam *    const graypamP,
-                       enum ditherType const ditherType,
+                       enum DitherType const ditherType,
                        unsigned int    const radius) {
 
     /* TODO: We create a floating point normalized, gamma-adjusted
@@ -891,7 +891,7 @@ createClusterConverter(struct pam *    const graypamP,
     int const clusterNormalizer = radius * radius * 2;
     unsigned int const diameter = 2 * radius;
 
-    struct converter converter;
+    struct Converter converter;
     struct clusterState * stateP;
     unsigned int row;
 
@@ -946,21 +946,21 @@ createClusterConverter(struct pam *    const graypamP,
 
 
 int
-main(int argc, char *argv[]) {
+main(int argc, const char ** const argv) {
 
-    struct cmdlineInfo cmdline;
-    FILE* ifP;
+    struct CmdlineInfo cmdline;
+    FILE * ifP;
 
-    pgm_init(&argc, argv);
+    pm_proginit(&argc, argv);
 
     parseCommandLine(argc, argv, &cmdline);
 
-    ifP = pm_openr(cmdline.inputFilespec);
+    ifP = pm_openr(cmdline.inputFileNm);
 
     if (cmdline.halftone == QT_HILBERT)
         doHilbert(ifP, cmdline.clumpSize);
     else {
-        struct converter converter;
+        struct Converter converter;
         struct pam graypam;
         struct pam bitpam;
         tuplen * grayrow;
@@ -1022,3 +1022,6 @@ main(int argc, char *argv[]) {
 
     return 0;
 }
+
+
+
diff --git a/editor/pammasksharpen.c b/editor/pammasksharpen.c
index 1e3dee32..51bdedd9 100644
--- a/editor/pammasksharpen.c
+++ b/editor/pammasksharpen.c
@@ -24,7 +24,7 @@ parseCommandLine(int argc, const char ** const argv,
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
     optEntry *option_def;
-        /* Instructions to OptParseOptions2 on how to parse our options.
+        /* Instructions to OptParseOptions3 on how to parse our options.
          */
     optStruct3 opt;
 
diff --git a/editor/pamscale.c b/editor/pamscale.c
index 410cd94a..8a51b2be 100644
--- a/editor/pamscale.c
+++ b/editor/pamscale.c
@@ -636,7 +636,6 @@ parseCommandLine(int argc,
 --------------------------------------------------------------------------*/
     optEntry * option_def;
     optStruct3 opt;
-        /* Instructions to pm_optParseOptions3 on how to parse our options. */
 
     unsigned int option_def_index;
     unsigned int xyfit, xyfill;
@@ -675,7 +674,7 @@ parseCommandLine(int argc,
     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);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
     /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (cmdlineP->nomix && filterSpec)
@@ -2251,7 +2250,7 @@ pamscale(FILE *             const ifP,
 
 
 int
-main(int argc, const char **argv ) {
+main(int argc, const char ** const argv) {
 
     struct CmdlineInfo cmdline;
     FILE * ifP;
diff --git a/generator/pamseq.c b/generator/pamseq.c
index 998b7ea5..71905a67 100644
--- a/generator/pamseq.c
+++ b/generator/pamseq.c
@@ -281,7 +281,7 @@ imageWidth(unsigned int   const depth,
    given that the minimum and maximum sample values in Plane P are min[P] and
    max[P] and the samples step by step[P].
 
-   E.g. in the sample case of min 0, max 4, and step 1 everywhere, with
+   E.g. in the example case of min 0, max 4, and step 1 everywhere, with
    depth 2,  We return 5*5 = 25.
 -----------------------------------------------------------------------------*/
     unsigned int product;
@@ -294,7 +294,7 @@ imageWidth(unsigned int   const depth,
             ROUNDUP((max[plane] - min[plane] + 1), step[plane])/step[plane];
 
         if (INT_MAX / valueCtThisPlane < product)
-            pm_error("Uncomputably large number of pixels (greater than %u",
+            pm_error("Uncomputably large number of pixels (greater than %u)",
                      INT_MAX);
 
         product *= valueCtThisPlane;
diff --git a/lib/colorname.c b/lib/colorname.c
index fe580cb9..3e51055c 100644
--- a/lib/colorname.c
+++ b/lib/colorname.c
@@ -16,13 +16,14 @@
 #define _BSD_SOURCE 1      /* Make sure strdup() is in string.h */
 #define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */
 
-#include "netpbm/pm_c_util.h"
+#include <stdbool.h>
 #include <ctype.h>
 #include <string.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <math.h>
 
+#include "netpbm/pm_c_util.h"
 #include "netpbm/nstring.h"
 #include "netpbm/mallocvar.h"
 
@@ -68,7 +69,7 @@ openColornameFileSearch(const char * const searchPath,
         bool eol;
 
         cursor = &buffer[0];
-        eol = FALSE;    /* initial value */
+        eol = false;    /* initial value */
         *filePP = NULL;  /* initial value */
         while (!eol && !*filePP) {
             const char * token;
@@ -76,7 +77,7 @@ openColornameFileSearch(const char * const searchPath,
             if (token) {
                 *filePP = fopen(token, "r");
             } else
-                eol = TRUE;
+                eol = true;
         }
         free(buffer);
     } else
@@ -86,7 +87,8 @@ openColornameFileSearch(const char * const searchPath,
 
 
 FILE *
-pm_openColornameFile(const char * const fileName, const int must_open) {
+pm_openColornameFile(const char * const fileName,
+                     int          const mustOpen) {
 /*----------------------------------------------------------------------------
    Open the colorname dictionary file.  Its file name is 'fileName', unless
    'fileName' is NULL.  In that case, its file name is the value of the
@@ -94,19 +96,19 @@ pm_openColornameFile(const char * const fileName, const int must_open) {
    if that environment variable is not set, it is the first file found,
    if any, in the search path RGB_DB_PATH.
 
-   'must_open' is a logical: we must get the file open or die.  If
-   'must_open' is true and we can't open the file (e.g. it doesn't
-   exist), exit the program with an error message.  If 'must_open' is
+   'mustOpen' is a logical: we must get the file open or die.  If
+   'mustOpen' is true and we can't open the file (e.g. it doesn't
+   exist), exit the program with an error message.  If 'mustOpen' is
    false and we can't open the file, just return a null pointer.
 -----------------------------------------------------------------------------*/
-    FILE *f;
+    FILE * fileP;
 
     if (fileName == NULL) {
         const char * rgbdef = getenv(RGBENV);
         if (rgbdef) {
             /* The environment variable is set */
-            f = fopen(rgbdef, "r");
-            if (f == NULL && must_open)
+            fileP = fopen(rgbdef, "r");
+            if (fileP == NULL && mustOpen)
                 pm_error("Can't open the color names dictionary file "
                          "named %s, per the %s environment variable.  "
                          "errno = %d (%s)",
@@ -115,9 +117,9 @@ pm_openColornameFile(const char * const fileName, const int must_open) {
             /* The environment variable isn't set, so try the hardcoded
                default color name dictionary locations.
             */
-            openColornameFileSearch(RGB_DB_PATH, &f);
+            openColornameFileSearch(RGB_DB_PATH, &fileP);
 
-            if (f == NULL && must_open) {
+            if (fileP == NULL && mustOpen) {
                 pm_error("can't open color names dictionary file from the "
                          "path '%s' "
                          "and Environment variable %s not set.  Set %s to "
@@ -127,20 +129,20 @@ pm_openColornameFile(const char * const fileName, const int must_open) {
             }
         }
     } else {
-        f = fopen(fileName, "r");
-        if (f == NULL && must_open)
+        fileP = fopen(fileName, "r");
+        if (fileP == NULL && mustOpen)
             pm_error("Can't open the color names dictionary file '%s'.  "
                      "errno = %d (%s)", fileName, errno, strerror(errno));
 
     }
     lineNo = 0;
-    return(f);
+    return fileP;
 }
 
 
 
 struct colorfile_entry
-pm_colorget(FILE * const f) {
+pm_colorget(FILE * const fileP) {
 /*----------------------------------------------------------------------------
    Get next color entry from the color name dictionary file 'f'.
 
@@ -155,20 +157,18 @@ pm_colorget(FILE * const f) {
     struct colorfile_entry retval;
     char * rc;
 
-    gotOne = FALSE;  /* initial value */
-    eof = FALSE;
-    while (!gotOne && !eof) {
+    for (gotOne = false, eof = false; !gotOne && !eof; ) {
         lineNo++;
-        rc = fgets(buf, sizeof(buf), f);
+        rc = fgets(buf, sizeof(buf), fileP);
         if (rc == NULL)
-            eof = TRUE;
+            eof = true;
         else {
             if (buf[0] != '#' && buf[0] != '\n' && buf[0] != '!' &&
                 buf[0] != '\0') {
                 if (sscanf(buf, "%ld %ld %ld %[^\n]",
                            &retval.r, &retval.g, &retval.b, colorname)
                     == 4 )
-                    gotOne = TRUE;
+                    gotOne = true;
                 else {
                     if (buf[strlen(buf)-1] == '\n')
                         buf[strlen(buf)-1] = '\0';
@@ -191,14 +191,27 @@ pm_colorget(FILE * const f) {
 void
 pm_parse_dictionary_namen(char   const colorname[],
                           tuplen const color) {
+/*----------------------------------------------------------------------------
+   Return as *tuplen a tuple of type RGB that represents the color named
+   'colorname'.  This is an actual name, like "pink", not just a color
+   specification, like "rgb:0/0/0".
+
+   If the color name is unknown, abort the program.  If there are two entries
+   in the dictionary for the same color name, use the first one.
+
+   We use the Netpbm color dictionary used by 'pm_openColornamefile'.
 
-    FILE * fP;
+   Caller must ensure there is enough memory at 'tuplen' for at least 3
+   samples.  We set the first 3 samples of the tuple value and ignore any
+   others.
+-----------------------------------------------------------------------------*/
+    FILE * fileP;
     bool gotit;
     bool colorfileExhausted;
     struct colorfile_entry colorfileEntry;
     char * canoncolor;
 
-    fP = pm_openColornameFile(NULL, TRUE);  /* exits if error */
+    fileP = pm_openColornameFile(NULL, true);  /* exits if error */
     canoncolor = strdup(colorname);
 
     if (!canoncolor)
@@ -207,18 +220,18 @@ pm_parse_dictionary_namen(char   const colorname[],
 
     pm_canonstr(canoncolor);
 
-    for(gotit = FALSE, colorfileExhausted = FALSE;
+    for (gotit = false, colorfileExhausted = false;
         !gotit && !colorfileExhausted; ) {
 
-        colorfileEntry = pm_colorget(fP);
+        colorfileEntry = pm_colorget(fileP);
         if (colorfileEntry.colorname) {
             pm_canonstr(colorfileEntry.colorname);
             if (streq(canoncolor, colorfileEntry.colorname))
-                gotit = TRUE;
+                gotit = true;
         } else
-            colorfileExhausted = TRUE;
+            colorfileExhausted = true;
     }
-    fclose(fP);
+    fclose(fileP);
 
     if (!gotit)
         pm_error("unknown color '%s'", colorname);
@@ -237,7 +250,15 @@ pm_parse_dictionary_name(char    const colorname[],
                          pixval  const maxval,
                          int     const closeOk,
                          pixel * const colorP) {
+/*----------------------------------------------------------------------------
+   Same as 'pm_parse_dictionary_name' except return the color as a
+   pixel value of type 'pixel', with a maxval of 'maxval'.
 
+   We round the color to the nearest one that can be represented with the
+   resolution indicated by 'maxval' (rounding each component independently).
+   Iff rounding is necessary and 'closeOK' is false, we issue an informational
+   message about the rounding.
+-----------------------------------------------------------------------------*/
     double const epsilon = 1.0/65536.0;
 
     tuplen color;
@@ -271,4 +292,3 @@ pm_parse_dictionary_name(char    const colorname[],
 }
 
 
-
diff --git a/lib/libpamcolor.c b/lib/libpamcolor.c
index cc68fe1a..831057ab 100644
--- a/lib/libpamcolor.c
+++ b/lib/libpamcolor.c
@@ -130,21 +130,29 @@ isNormal(samplen const arg) {
 static void
 parseNewDecX11(const char * const colorname,
                tuplen       const color) {
-
+/*----------------------------------------------------------------------------
+   Return as *colorP the color specified by the new-style decimal specifier
+   colorname[] (e.g. "rgbi:0/.5/1").
+-----------------------------------------------------------------------------*/
+    char invalidExtra;
     int rc;
 
-    rc = sscanf(colorname, "rgbi:%f/%f/%f",
+    rc = sscanf(colorname, "rgbi:%f/%f/%f%c",
                 &color[PAM_RED_PLANE],
                 &color[PAM_GRN_PLANE],
-                &color[PAM_BLU_PLANE]);
+                &color[PAM_BLU_PLANE],
+                &invalidExtra);
 
     if (rc != 3)
-        pm_error("invalid color specifier '%s'", colorname);
+        pm_error("invalid rgbi: color specifier '%s' - "
+                 "does not have form rgbi:n/n/n "
+                 "(where n is floating point number)",
+                 colorname);
 
     if (!(isNormal(color[PAM_RED_PLANE]) &&
           isNormal(color[PAM_GRN_PLANE]) &&
           isNormal(color[PAM_BLU_PLANE]))) {
-        pm_error("invalid color specifier '%s' - "
+        pm_error("invalid rgbi: color specifier '%s' - "
                  "values must be between 0.0 and 1.0", colorname);
     }
 }
@@ -154,16 +162,21 @@ parseNewDecX11(const char * const colorname,
 static void
 parseInteger(const char * const colorname,
              tuplen       const color) {
-
+/*----------------------------------------------------------------------------
+   Return as *colorP the color specified by the integer specifier
+   colorname[] (e.g. "rgb-255/10/20/30").
+-----------------------------------------------------------------------------*/
     unsigned int maxval;
     unsigned int r, g, b;
+    char invalidExtra;
     int rc;
 
-    rc = sscanf(colorname, "rgb-%u:%u/%u/%u", &maxval, &r, &g, &b);
+    rc = sscanf(colorname, "rgb-%u:%u/%u/%u%c",
+                &maxval, &r, &g, &b, &invalidExtra);
 
     if (rc != 4)
-        pm_error("invalid color specifier '%s'.  "
-                 "If it starts with \"rgb-\", then it must have the format "
+        pm_error("invalid rgb- color specifier '%s' - "
+                 "Does not have form "
                  "rgb-<MAXVAL>:<RED>:<GRN>:<BLU>, "
                  "where <MAXVAL>, <RED>, <GRN>, and <BLU> are "
                  "unsigned integers",
@@ -200,7 +213,7 @@ parseOldX11(const char * const colorname,
             tuplen       const color) {
 /*----------------------------------------------------------------------------
    Return as *colorP the color specified by the old X11 style color
-   specififier colorname[] (e.g. #554055).
+   specifier colorname[] (e.g. #554055).
 -----------------------------------------------------------------------------*/
     if (!pm_strishex(&colorname[1]))
         pm_error("Non-hexadecimal characters in #-type color specification");
@@ -276,21 +289,29 @@ parseOldX11(const char * const colorname,
 static void
 parseOldX11Dec(const char* const colorname,
                tuplen      const color) {
-
+/*----------------------------------------------------------------------------
+   Return as *colorP the color specified by the old X11 style decimal color
+   specifier colorname[] (e.g. 0,.5,1).
+-----------------------------------------------------------------------------*/
+    char invalidExtra;
     int rc;
 
-    rc = sscanf(colorname, "%f,%f,%f",
+    rc = sscanf(colorname, "%f,%f,%f%c",
                 &color[PAM_RED_PLANE],
                 &color[PAM_GRN_PLANE],
-                &color[PAM_BLU_PLANE]);
+                &color[PAM_BLU_PLANE],
+                &invalidExtra);
 
     if (rc != 3)
-        pm_error("invalid color specifier '%s'", colorname);
+        pm_error("invalid old-style X11 decimal color specifier '%s' - "
+                 "does not have form n,n,n (where n is a floating point "
+                 "decimal number",
+                 colorname);
 
     if (!(isNormal(color[PAM_RED_PLANE]) &&
           isNormal(color[PAM_GRN_PLANE]) &&
           isNormal(color[PAM_BLU_PLANE]))) {
-        pm_error("invalid color specifier '%s' - "
+        pm_error("invalid old-style X11 decimal color specifier '%s' - "
                  "values must be between 0.0 and 1.0", colorname);
     }
 }
diff --git a/lib/libpbm3.c b/lib/libpbm3.c
index 5d4e614b..b566202f 100644
--- a/lib/libpbm3.c
+++ b/lib/libpbm3.c
@@ -324,7 +324,15 @@ pbm_writepbmrow_packed(FILE *                const fileP,
                        const unsigned char * const packedBits,
                        int                   const cols,
                        int                   const forceplain) {
+/*----------------------------------------------------------------------------
+   Write to file *fileP the PBM row 'cols' columns wide in packed bit buffer
+   'packedBits'.
+
+   Write it in PBM plain format iff 'forceplain' is nonzero.
 
+   In raw format, the don't-care bits at the end of the row are the same as
+   in the input buffer.
+-----------------------------------------------------------------------------*/
     if (!forceplain && !pm_plain_output)
         writePackedRawRow(fileP, packedBits, cols);
     else {
@@ -385,10 +393,14 @@ pbm_writepbmrow_bitoffset(FILE *          const fileP,
                           int             const format,
                           unsigned int    const offset) {
 /*----------------------------------------------------------------------------
-   Write PBM row from a packed bit buffer 'packedBits, starting at the
-   specified offset 'offset' in the buffer.
+   Write to file *fileP the tail of the PBM row 'cols' columns wide in packed
+   bit buffer 'packedBits'.  Start at column 'offset' of the row.
+
+   Write it in PBM raw format.
+
+   Make any don't-care bits at the end of the row written zero.
 
-   We destroy the buffer.
+   We destroy the contents of the buffer.
 -----------------------------------------------------------------------------*/
     unsigned int const rsh = offset % 8;
     unsigned int const lsh = (8 - rsh) % 8;
diff --git a/lib/libpm.c b/lib/libpm.c
index d1fc6c42..4dd19b70 100644
--- a/lib/libpm.c
+++ b/lib/libpm.c
@@ -706,7 +706,16 @@ pm_proginit(int *         const argcP,
    find.  We remove the common options from argv[], updating *argcP
    accordingly.
 
-   This includes calling pm_init() to initialize the Netpbm libraries.
+   This includes calling 'pm_init' to initialize the Netpbm libraries.
+
+   argv[] is intended to be the program's POSIX arguments (as passed to the
+   program's main function).  But note that POSIX arguments are modifiable and
+   as such, the conventional way to declare them in a program is with "char
+   **", as opposed to pm_proginit's "const char **".  To avoid a compiler
+   warning, the program has to use the unconventional "const char **" type in
+   the declaration of its main function.  (Alternatively, it can just cast it
+   to const char ** later).  'pm_proginit' does not modify any argument
+   strings.
 -----------------------------------------------------------------------------*/
     const char * const progname = pm_arg0toprogname(argv[0]);
         /* points to static memory in this library */
diff --git a/lib/libppmcmap.c b/lib/libppmcmap.c
index 0f6439ae..24302c6a 100644
--- a/lib/libppmcmap.c
+++ b/lib/libppmcmap.c
@@ -784,17 +784,23 @@ int
 ppm_findclosestcolor(const pixel * const colormap,
                      int           const ncolors,
                      const pixel * const pP) {
+/*----------------------------------------------------------------------------
+  The index in colormap[] (which has 'ncolors' entries) of the color that is
+  closest to color *pP.
 
-    /* Search colormap for closest match.       */
+  Where two entries in colormap[] are identical, return the lesser of their
+  two indices.
 
-    int i;
+  Iff there are no colors in the amp ('ncolors' is zero), return -1.
+-----------------------------------------------------------------------------*/
+    unsigned int i;
     int ind;
     unsigned int bestDist;
 
     bestDist = UINT_MAX;
     ind = -1;
 
-    for(i = 0; i < ncolors && bestDist > 0; ++i) {
+    for (i = 0; i < ncolors && bestDist > 0; ++i) {
         unsigned int const dist = PPM_DISTANCE(*pP, colormap[i]);
 
         if (dist < bestDist ) {
@@ -806,6 +812,7 @@ ppm_findclosestcolor(const pixel * const colormap,
 }
 
 
+
 void
 ppm_colorrowtomapfile(FILE *ofp, pixel *colormap, int ncolors, pixval maxval)
 {
diff --git a/lib/libppmcolor.c b/lib/libppmcolor.c
index c0a88dc2..baa1d568 100644
--- a/lib/libppmcolor.c
+++ b/lib/libppmcolor.c
@@ -9,6 +9,7 @@
 ** implied warranty.
 */
 
+#include <stdbool.h>
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
@@ -46,7 +47,7 @@ pixel
 ppm_parsecolor(const char * const colorname,
                pixval       const maxval) {
 
-    return ppm_parsecolor2(colorname, maxval, TRUE);
+    return ppm_parsecolor2(colorname, maxval, true);
 }
 
 
@@ -57,7 +58,7 @@ ppm_colorname(const pixel * const colorP,
               int           const hexok)   {
 
     int r, g, b;
-    FILE * f;
+    FILE * fileP;
     static char colorname[200];
         /* Null string means no suitable name so far */
 
@@ -71,17 +72,17 @@ ppm_colorname(const pixel * const colorP,
         b = (int) PPM_GETB(*colorP) * 255 / (int) maxval;
     }
 
-    f = pm_openColornameFile(NULL, !hexok);
+    fileP = pm_openColornameFile(NULL, !hexok);
 
-    if (!f)
+    if (!fileP)
         STRSCPY(colorname, "");
     else {
         int bestDiff;
         bool eof;
 
-        for (bestDiff = 32767, eof = FALSE;
+        for (bestDiff = 32767, eof = false;
              !eof && bestDiff > 0; ) {
-            struct colorfile_entry const ce = pm_colorget(f);
+            struct colorfile_entry const ce = pm_colorget(fileP);
             if (ce.colorname)  {
                 int const thisDiff =
                     abs(r - (int)ce.r) +
@@ -93,9 +94,9 @@ ppm_colorname(const pixel * const colorP,
                     STRSCPY(colorname, ce.colorname);
                 }
             } else
-                eof = TRUE;
+                eof = true;
         }
-        fclose(f);
+        fclose(fileP);
 
         if (bestDiff == 32767) {
             /* Color file contain no entries, so we can't even pick a close
@@ -246,15 +247,12 @@ readOpenColorFile(FILE *          const colorFileP,
     unsigned int nColorsDone;
     bool done;
 
-    nColorsDone = 0;
-    done = FALSE;
-    *errorP = NULL;
+    for (nColorsDone = 0, done = false, *errorP = NULL; !done && !*errorP; ) {
 
-    while (!done && !*errorP) {
         struct colorfile_entry const ce = pm_colorget(colorFileP);
 
         if (!ce.colorname)
-            done = TRUE;
+            done = true;
         else
             processColorfileEntry(ce, cht, colornames, colors,
                                   &nColorsDone, errorP);
@@ -284,7 +282,7 @@ readColorFile(const char *    const fileName,
    to colornames[], colors[], and 'cht'.  Return as *nColorsP the number
    of colors in it.
 
-   If the file is not openable (e.g. not file by that name exists), abort the
+   If the file is not openable (e.g. no file by that name exists), abort the
    program if 'mustOpen' is true; otherwise, return values indicating a
    dictionary with no colors.
 
@@ -318,19 +316,25 @@ static void
 readcolordict(const char *      const fileName,
               bool              const mustOpen,
               unsigned int *    const nColorsP,
-              const char ***    const colornamesP,
+              const char ***    const colorNamesP,
               pixel **          const colorsP,
               colorhash_table * const chtP,
               const char **     const errorP) {
+/*----------------------------------------------------------------------------
+  Same as 'ppm_readcolordict' except that a) if we fail, we return a message
+  as *errorP instead of issuing a message; and b) we always return all three
+  return values.
+-----------------------------------------------------------------------------*/
+    const char ** colorNames;
+        /* List of all the color names in the dictionary */
 
-    const char ** colornames;
-
-    colornames = allocColorNames();
+    colorNames = allocColorNames();
 
-    if (colornames == NULL)
+    if (colorNames == NULL)
         pm_asprintf(errorP, "Unable to allocate space for colorname table.");
     else {
         pixel * colors;
+            /* colors[i] is the color that goes with name colorNames[i] */
 
         MALLOCARRAY(colors, MAXCOLORNAMES);
 
@@ -338,6 +342,7 @@ readcolordict(const char *      const fileName,
             pm_asprintf(errorP, "Unable to allocate space for color table.");
         else {
             colorhash_table cht;
+                /* Hash table mapping colorNames[] to colors[] */
 
             cht = allocColorHash();
 
@@ -345,7 +350,7 @@ readcolordict(const char *      const fileName,
                 pm_asprintf(errorP, "Unable to allocate space for color hash");
             else {
                 readColorFile(fileName, mustOpen,
-                              nColorsP, colornames, colors, cht,
+                              nColorsP, colorNames, colors, cht,
                               errorP);
 
                 if (*errorP)
@@ -359,9 +364,9 @@ readcolordict(const char *      const fileName,
                 *colorsP = colors;
         }
         if (*errorP)
-            free(colornames);
+            free(colorNames);
         else
-            *colornamesP = colornames;
+            *colorNamesP = colorNames;
     }
 }
 
@@ -371,7 +376,7 @@ void
 ppm_readcolordict(const char *      const fileName,
                   int               const mustOpen,
                   unsigned int *    const nColorsP,
-                  const char ***    const colornamesP,
+                  const char ***    const colorNamesP,
                   pixel **          const colorsP,
                   colorhash_table * const chtP) {
 /*----------------------------------------------------------------------------
@@ -382,8 +387,8 @@ ppm_readcolordict(const char *      const fileName,
 
    Return as *nColorsP the number of colors in the dictionary.
 
-   Return as *colornamesP the names of those colors.  *colornamesP is a
-   malloced array that Caller must free with ppm_freecolornames().
+   Return as *colorNamesP the names of those colors.  *colorNamesP is a
+   malloced array that Caller must free with ppm_freecolorNames().
    The first *nColorsP entries are valid; *chtP contains indices into this
    array.
 
@@ -391,18 +396,18 @@ ppm_readcolordict(const char *      const fileName,
    MAXCOLORS with the first elements filled in and the rest undefined.
 
    Return as *chtP a color hash table mapping each color in the dictionary
-   to the index into *colornamesP for the name of the color.
+   to the index into *colorNamesP for the name of the color.
 
-   Each of 'nColorsP, 'colornamesP', and 'colorsP' may be null, in which case
+   Each of 'nColorsP, 'colorNamesP', and 'colorsP' may be null, in which case
    we do not return the corresponding information (or allocate memory for it).
 -----------------------------------------------------------------------------*/
     colorhash_table cht;
-    const char ** colornames;
+    const char ** colorNames;
     pixel * colors;
     unsigned int nColors;
     const char * error;
 
-    readcolordict(fileName, mustOpen, &nColors, &colornames, &colors, &cht,
+    readcolordict(fileName, mustOpen, &nColors, &colorNames, &colors, &cht,
                   &error);
 
     if (error) {
@@ -414,10 +419,10 @@ ppm_readcolordict(const char *      const fileName,
             *chtP = cht;
         else
             ppm_freecolorhash(cht);
-        if (colornamesP)
-            *colornamesP = colornames;
+        if (colorNamesP)
+            *colorNamesP = colorNames;
         else
-            ppm_freecolornames(colornames);
+            ppm_freecolornames(colorNames);
         if (colorsP)
             *colorsP = colors;
         else
@@ -433,23 +438,23 @@ void
 ppm_readcolornamefile(const char *      const fileName,
                       int               const mustOpen,
                       colorhash_table * const chtP,
-                      const char ***    const colornamesP) {
+                      const char ***    const colorNamesP) {
 
-    ppm_readcolordict(fileName, mustOpen, NULL, colornamesP, NULL, chtP);
+    ppm_readcolordict(fileName, mustOpen, NULL, colorNamesP, NULL, chtP);
 }
 
 
 
 void
-ppm_freecolornames(const char ** const colornames) {
+ppm_freecolornames(const char ** const colorNames) {
 
     unsigned int i;
 
     for (i = 0; i < MAXCOLORNAMES; ++i)
-        if (colornames[i])
-            free((char *)colornames[i]);
+        if (colorNames[i])
+            free((char *)colorNames[i]);
 
-    free(colornames);
+    free(colorNames);
 }
 
 
diff --git a/lib/rgb.txt b/lib/rgb.txt
index 28231080..c0887fea 100644
--- a/lib/rgb.txt
+++ b/lib/rgb.txt
@@ -2,6 +2,10 @@
 # order.  Some color names are defined multiple times, and sometimes
 # with different colors.  Many colors have multiple names.
 
+# When Netpbm interprets this dictionary, it recognizes the first definition
+# of a particular color name and the first definition of a particular color
+# definition.  (That means the function is not reversible).
+
 # - Netpbm originals
 # - Crayola crayons, as determined by John Thomas at Tektronix
 # - Hollasch at Microsoft Research
@@ -35,7 +39,7 @@
 255 255   0 Yellow
 255 138   0 Orange
 159 211   0 GreenYellow
-  0 255 159 Spring Green
+  0 255 159 SpringGreen
   0 138 255 SkyBlue
 148   0 211 Violet
 255   0 148 VioletRed
@@ -143,7 +147,7 @@
 128 128 105 WarmGrey
   0   0   0 Black
  41  36  33 IvoryBlack
- 46  71  59 Lamp Black
+ 46  71  59 LampBlack
 227  38  54 AlizarinCrimson
 156 102  31 Brick
 227  23  13 CadmiumRedDeep
@@ -335,7 +339,7 @@
 112 128 144 SlateGray
 119 136 153 LightSlateGray
 119 136 153 LightSlateGrey
-211 211 211 light grey
+211 211 211 LightGrey
 100 149 237 CornflowerBlue
 132 112 255 LightSlateBlue
   0 191 255 DeepSkyBlue
diff --git a/lib/util/shhopt.c b/lib/util/shhopt.c
index 32d0916d..5c74efdb 100644
--- a/lib/util/shhopt.c
+++ b/lib/util/shhopt.c
@@ -34,30 +34,22 @@
 #include "token.h"
 #include "shhopt.h"
 
-/*-----------------------------------------------------------------------+
-|  PRIVATE DATA                                                          |
-+-----------------------------------------------------------------------*/
+
 
 static void optFatalFunc(const char *, ...);
 static void (*optFatal)(const char *format, ...) = optFatalFunc;
 
-/*-----------------------------------------------------------------------+
-|  PRIVATE FUNCTIONS                                                     |
-+-----------------------------------------------------------------------*/
 
-/*------------------------------------------------------------------------
- |  NAME          optFatalFunc
- |
- |  FUNCTION      Show given message and abort the program.
- |
- |  INPUT         format, ...
- |                        Arguments used as with printf().
- |
- |  RETURNS       Never returns. The program is aborted.
- */
+
 static void
-optFatalFunc(const char *format, ...)
-{
+optFatalFunc(const char * const format, ...) {
+/*----------------------------------------------------------------------------
+  FUNCTION      Show given message and abort the program.
+
+  INPUT         Arguments used as with printf().
+
+  RETURNS       Never returns. The program is aborted.
+-----------------------------------------------------------------------------*/
     va_list ap;
 
     fflush(stdout);
@@ -68,21 +60,20 @@ optFatalFunc(const char *format, ...)
     exit(99);
 }
 
-/*------------------------------------------------------------------------
- |  NAME          optStructCount
- |
- |  FUNCTION      Get number of options in a optStruct.
- |
- |  INPUT         opt     array of possible options.
- |
- |  RETURNS       Number of options in the given array.
- |
- |  DESCRIPTION   Count elements in an optStruct-array. The structure must
- |                be ended using an element of type OPT_END.
- */
+
+
 static int
-optStructCount(const optEntry opt[])
-{
+optStructCount(const optEntry * const opt) {
+/*--------------------------------------------------------------------------
+  FUNCTION      Get number of options in a optStruct.
+
+  INPUT         opt     array of possible options.
+
+  RETURNS       Number of options in the given array.
+
+  DESCRIPTION   Count elements in an optStruct-array. The structure must
+                 be ended using an element of type OPT_END.
+----------------------------------------------------------------------------*/
     int ret = 0;
 
     while (opt[ret].type != OPT_END && ret < 500)
@@ -94,31 +85,29 @@ optStructCount(const optEntry opt[])
 
 enum Shortlong {SL_SHORT, SL_LONG};
 
-
 static void
 optMatch(optEntry       const opt[],
          const char *   const targetOpt,
          enum Shortlong const shortLong,
          bool *         const foundP,
-         int *          const optIndexP) {
+         unsigned int * const optIndexP) {
 /*------------------------------------------------------------------------
- |  FUNCTION      Find a matching option.
- |
- |  INPUT         opt        array of valid option names.
- |                targetOpt  option string to match, without `-' or `--'.
- |                           e.g. "verbose" or "height=5"
- |                shortLong  whether to match short option or long
- |
- |  RETURNS       *foundP     there is a matching option class the table
- !                *optIndexP  index in the option class table
- |                            meaningless if *foundP is false
- |
- |  DESCRIPTION   Short options are matched from the first character in
- |                the given string.
- |
- |                Where multiple entries in opt[] match, return the first.
- */
+   FUNCTION      Find a matching option.
 
+   INPUT         opt        array of valid option names.
+                 targetOpt  option string to match, without `-' or `--'.
+                            e.g. "verbose" or "height=5"
+                 shortLong  whether to match short option or long
+
+   RETURNS       *foundP     there is a matching option class the table
+                 *optIndexP  index in the option class table
+                             meaningless if *foundP is false
+
+   DESCRIPTION   Short options are matched from the first character in
+                 the given string.
+
+                 Where multiple entries in opt[] match, return the first.
+--------------------------------------------------------------------------*/
     unsigned int const optCt = optStructCount(opt);
 
     unsigned int q;
@@ -161,19 +150,17 @@ optMatch(optEntry       const opt[],
 
 
 
-/*------------------------------------------------------------------------
- |  NAME          optString
- |
- |  FUNCTION      Return a (static) string with the option name.
- |
- |  INPUT         opt     the option to stringify.
- |                lng     is it a long option?
- |
- |  RETURNS       Pointer to static string.
- */
 static char *
-optString(const optEntry opte, int lng)
-{
+optString(optEntry const opte,
+          int      const lng) {
+/*--------------------------------------------------------------------------
+   FUNCTION      Return a (static) string with the option name.
+
+   INPUT         opt     the option to stringify.
+                 lng     is it a long option?
+
+   RETURNS       Pointer to static string.
+--------------------------------------------------------------------------*/
     static char ret[31];
 
     if (lng) {
@@ -190,7 +177,7 @@ optString(const optEntry opte, int lng)
 
 
 static optEntry
-optStructToEntry(const optStruct opt) {
+optStructToEntry(optStruct const opt) {
 /*----------------------------------------------------------------------------
    Return the information in 'opt' (an optStruct type) as an optEntry type.
    optEntry is newer and has an additional field.
@@ -204,13 +191,13 @@ optStructToEntry(const optStruct opt) {
     opte.specified = NULL;
     opte.flags     = opt.flags;
 
-    return(opte);
+    return opte;
 }
 
 
 
 static optEntry *
-optStructTblToEntryTbl(const optStruct optStructTable[]) {
+optStructTblToEntryTbl(const optStruct * const optStructTable) {
 /*----------------------------------------------------------------------------
    Return a table of optEntry types containing the information in the
    input table of optStruct types.
@@ -239,18 +226,15 @@ optStructTblToEntryTbl(const optStruct optStructTable[]) {
 
 
 
-/*------------------------------------------------------------------------
- |  NAME          optNeedsArgument
- |
- |  FUNCTION      Check if an option requires an argument.
- |
- |  INPUT         opt     the option to check.
- |
- |  RETURNS       Boolean value.
- */
 static int
-optNeedsArgument(const optEntry opt)
-{
+optNeedsArgument(const optEntry opt) {
+/*--------------------------------------------------------------------------
+   FUNCTION      Check if an option requires an argument.
+
+   INPUT         opt     the option to check.
+
+   RETURNS       Boolean value.
+---------------------------------------------------------------------------*/
     return opt.type == OPT_STRING
         || opt.type == OPT_INT
         || opt.type == OPT_UINT
@@ -262,26 +246,28 @@ optNeedsArgument(const optEntry opt)
         ;
 }
 
-/*------------------------------------------------------------------------
- |  NAME          argvRemove
- |
- |  FUNCTION      Remove an entry from an argv-array.
- |
- |  INPUT         argc    pointer to number of options.
- |                argv    array of option-/argument-strings.
- |                i       index of option to remove.
- |
- |  OUTPUT        argc    new argument count.
- |                argv    array with given argument removed.
- */
+
+
 static void
-argvRemove(int *argc, char *argv[], int i)
-{
-    if (i >= *argc)
-        return;
-    while (i++ < *argc)
-        argv[i - 1] = argv[i];
-    --*argc;
+argvRemove(int *         const argcP,
+           const char ** const argv,
+           unsigned int  const n) {
+/*------------------------------------------------------------------------
+   INPUT         argc    pointer to number of options.
+                 argv    array of option-/argument-strings.
+                 n       index of option to remove.
+
+   OUTPUT        argc    new argument count.
+                 argv    array with given argument removed.
+--------------------------------------------------------------------------*/
+    if (n < *argcP) {
+        unsigned int i;
+
+        for (i = n; i++ < *argcP; )
+            argv[i - 1] = argv[i];
+
+        --*argcP;
+    }
 }
 
 
@@ -398,21 +384,20 @@ parseStringList(const char *   const listText,
 
 
 
-/*------------------------------------------------------------------------
- |  NAME          optExecute
- |
- |  FUNCTION      Perform the action of an option.
- |
- |  INPUT         opt     element in array of defined options that
- |                        applies to this option
- |                arg     argument to option, if it applies.
- |                lng     was the option given as a long option?
- |
- |  RETURNS       Nothing. Aborts in case of error.
- */
 static void
-optExecute(optEntry  const opt, char *arg, int lng)
-{
+optExecute(optEntry     const opt,
+           const char * const arg,
+           int          const lng) {
+/*--------------------------------------------------------------------------
+   FUNCTION      Perform the action of an option.
+
+   INPUT         opt     element in array of defined options that
+                         applies to this option
+                 arg     argument to option, if it applies.
+                 lng     was the option given as a long option?
+
+   RETURNS       Nothing. Aborts in case of error.
+----------------------------------------------------------------------------*/
     if (opt.specified)
         *opt.specified = 1;
 
@@ -424,7 +409,7 @@ optExecute(optEntry  const opt, char *arg, int lng)
 
     case OPT_STRING:
         if (opt.arg)
-            *((char **) opt.arg) = arg;
+            *((const char **) opt.arg) = arg;
         break;
 
     case OPT_INT:
@@ -518,64 +503,50 @@ optExecute(optEntry  const opt, char *arg, int lng)
 
 
 
-/*-----------------------------------------------------------------------+
-|  PUBLIC FUNCTIONS                                                      |
-+-----------------------------------------------------------------------*/
-
-/*------------------------------------------------------------------------
- |  NAME          optSetFatalFunc
- |
+void
+pm_optSetFatalFunc(void (*f)(const char *, ...)) {
+/*--------------------------------------------------------------------------
  |  FUNCTION      Set function used to display error message and exit.
  |
- |  SYNOPSIS      #include "shhopt.h"
- |                void optSetFatalFunc(void (*f)(const char *, ...));
- |
  |  INPUT         f       function accepting printf()'like parameters,
  |                        that _must_ abort the program.
- */
-void
-pm_optSetFatalFunc(void (*f)(const char *, ...)) {
-
+----------------------------------------------------------------------------*/
     optFatal = f;
 }
 
 
 
-/*------------------------------------------------------------------------
- |  NAME          pm_optParseOptions
- |
- |  FUNCTION      Parse commandline options.
- |
- |  SYNOPSIS      #include "shhopt.h"
- |                void pm_optParseOptions(int *argc, char *argv[],
- |                                     optStruct opt[], int allowNegNum);
- |
- |  INPUT         argc    Pointer to number of options.
- |                argv    Array of option-/argument-strings.
- |                opt     Array of possible options.
- |                allowNegNum
- |                        a negative number is not to be taken as
- |                        an option.
- |
- |  OUTPUT        argc    new argument count.
- |                argv    array with arguments removed.
- |
- |  RETURNS       Nothing. Aborts in case of error.
- |
- |  DESCRIPTION   This function checks each option in the argv-array
- |                against strings in the opt-array, and `executes' any
- |                matching action. Any arguments to the options are
- |                extracted and stored in the variables or passed to
- |                functions pointed to by entries in opt.
- |
- |                Options and arguments used are removed from the argv-
- |                array, and argc is decreased accordingly.
- |
- |                Any error leads to program abortion.
- */
 void
-pm_optParseOptions(int *argc, char *argv[], optStruct opt[], int allowNegNum)
-{
+pm_optParseOptions(int *       const argcP,
+                   char **     const argv,
+                   optStruct * const opt,
+                   int         const allowNegNum) {
+/*------------------------------------------------------------------------
+   FUNCTION      Parse commandline options.
+
+   INPUT         argc    Pointer to number of options.
+                 argv    Array of option-/argument-strings.
+                 opt     Array of possible options.
+                 allowNegNum
+                         a negative number is not to be taken as
+                         an option.
+
+   OUTPUT        argc    new argument count.
+                 argv    array with arguments removed.
+
+   RETURNS       Nothing. Aborts in case of error.
+
+   DESCRIPTION   This function checks each option in the argv-array
+                 against strings in the opt-array, and `executes' any
+                 matching action. Any arguments to the options are
+                 extracted and stored in the variables or passed to
+                 functions pointed to by entries in opt.
+
+                 Options and arguments used are removed from the argv-
+                 array, and argc is decreased accordingly.
+
+                 Any error leads to program abortion.
+----------------------------------------------------------------------------*/
     int ai;        /* argv index. */
     int optarg;    /* argv index of option argument, or -1 if none. */
     int done;
@@ -583,23 +554,23 @@ pm_optParseOptions(int *argc, char *argv[], optStruct opt[], int allowNegNum)
     char * o;        /* pointer to an option character */
     char * p;
 
-    optEntry *opt_table;  /* malloc'ed array */
+    optEntry * optTable;  /* malloc'ed array */
 
-    opt_table = optStructTblToEntryTbl(opt);
-    if (opt_table == NULL)
+    optTable = optStructTblToEntryTbl(opt);
+    if (optTable == NULL)
         optFatal("Memory allocation failed (trying to allocate space for "
                  "new-format option table)");
 
     /*
      *  Loop through all arguments.
      */
-    for (ai = 0; ai < *argc; ) {
+    for (ai = 0; ai < *argcP; ) {
         /*
          *  "--" indicates that the rest of the argv-array does not
          *  contain options.
          */
         if (streq(argv[ai], "--")) {
-            argvRemove(argc, argv, ai);
+            argvRemove(argcP, (const char **)argv, ai);
             break;
         }
 
@@ -608,10 +579,10 @@ pm_optParseOptions(int *argc, char *argv[], optStruct opt[], int allowNegNum)
             continue;
         } else if (strneq(argv[ai], "--", 2)) {
             bool found;
-            int mi;
+            unsigned int mi;
             /* long option */
             /* find matching option */
-            optMatch(opt_table, argv[ai] + 2, SL_LONG, &found, &mi);
+            optMatch(optTable, argv[ai] + 2, SL_LONG, &found, &mi);
             if (!found)
                 optFatal("unrecognized option `%s'", argv[ai]);
 
@@ -622,24 +593,24 @@ pm_optParseOptions(int *argc, char *argv[], optStruct opt[], int allowNegNum)
 
             /* does this option take an argument? */
             optarg = -1;
-            if (optNeedsArgument(opt_table[mi])) {
+            if (optNeedsArgument(optTable[mi])) {
                 /* option needs an argument. find it. */
                 if (!arg) {
-                    if ((optarg = ai + 1) == *argc)
+                    if ((optarg = ai + 1) == *argcP)
                         optFatal("option `%s' requires an argument",
-                                 optString(opt_table[mi], 1));
+                                 optString(optTable[mi], 1));
                     arg = argv[optarg];
                 }
             } else {
                 if (arg)
                     optFatal("option `%s' doesn't allow an argument",
-                             optString(opt_table[mi], 1));
+                             optString(optTable[mi], 1));
             }
-            optExecute(opt_table[mi], arg, 1);
+            optExecute(optTable[mi], arg, 1);
             /* remove option and any argument from the argv-array. */
             if (optarg >= 0)
-                argvRemove(argc, argv, ai);
-            argvRemove(argc, argv, ai);
+                argvRemove(argcP, (const char **)argv, ai);
+            argvRemove(argcP, (const char **)argv, ai);
         } else if (*argv[ai] == '-') {
             /* A dash by itself is not considered an option. */
             if (argv[ai][1] == '\0') {
@@ -652,47 +623,49 @@ pm_optParseOptions(int *argc, char *argv[], optStruct opt[], int allowNegNum)
             optarg = -1;
             while (*o && !done) {
                 bool found;
-                int mi;
+                unsigned int mi;
                 /* find matching option */
-                optMatch(opt_table, o, SL_SHORT, &found, &mi);
+                optMatch(optTable, o, SL_SHORT, &found, &mi);
                 if (!found)
                     optFatal("unrecognized option `-%c'", *o);
 
                 /* does this option take an argument? */
                 optarg = -1;
                 arg = NULL;
-                if (optNeedsArgument(opt_table[mi])) {
+                if (optNeedsArgument(optTable[mi])) {
                     /* option needs an argument. find it. */
                     arg = o + 1;
                     if (!*arg) {
-                        if ((optarg = ai + 1) == *argc)
+                        if ((optarg = ai + 1) == *argcP)
                             optFatal("option `%s' requires an argument",
-                                     optString(opt_table[mi], 0));
+                                     optString(optTable[mi], 0));
                         arg = argv[optarg];
                     }
                     done = 1;
                 }
                 /* perform the action of this option. */
-                optExecute(opt_table[mi], arg, 0);
+                optExecute(optTable[mi], arg, 0);
                 ++o;
             }
             /* remove option and any argument from the argv-array. */
             if (optarg >= 0)
-                argvRemove(argc, argv, ai);
-            argvRemove(argc, argv, ai);
+                argvRemove(argcP, (const char **)argv, ai);
+            argvRemove(argcP, (const char **)argv, ai);
         } else {
             /* a non-option argument */
             ++ai;
         }
     }
-    free(opt_table);
+    free(optTable);
 }
 
 
 static void
-parse_short_option_token(char *argv[], const int argc, const int ai,
-                         const optEntry opt_table[],
-                         int * const tokens_consumed_p) {
+parseShortOptionToken(const char **    const argv,
+                      int              const argc,
+                      int              const ai,
+                      const optEntry * const optTable,
+                      unsigned int *   const tokensConsumedP) {
 /*----------------------------------------------------------------------------
    Parse a cluster of short options, e.g. -walne .
 
@@ -702,43 +675,43 @@ parse_short_option_token(char *argv[], const int argc, const int ai,
    argv[] and argc describe the whole program argument set.  'ai' is the
    index of the argument that is the short option cluster.
 -----------------------------------------------------------------------------*/
-    char *o;  /* A short option character */
-    char *arg;
-    unsigned char processed_arg;  /* boolean */
+    const char * optP;  /* A short option character */
+    const char * arg;   /* The argument of the short option */
+    bool processedArg;
         /* We processed an argument to one of the one-character options.
            This necessarily means there are no more options in this token
            to process.
            */
 
-    *tokens_consumed_p = 1;  /* initial assumption */
+    *tokensConsumedP = 1;  /* initial assumption */
 
-    o = argv[ai] + 1;
-    processed_arg = 0;  /* initial value */
-    while (*o && !processed_arg) {
-        bool found;
-        int mi;   /* index into option table */
-                /* find matching option */
-                optMatch(opt_table, o, SL_SHORT, &found, &mi);
-                if (!found)
-                    optFatal("unrecognized option `-%c'", *o);
+    for (optP = argv[ai] + 1, processedArg = false;
+         *optP && !processedArg; ) {
 
-                /* does this option take an argument? */
-                if (optNeedsArgument(opt_table[mi])) {
-                    /* option needs an argument. find it. */
-                    arg = o + 1;
-                    if (!*arg) {
+        bool found;
+        unsigned int mi;   /* index into option table */
+        /* find matching option */
+        optMatch(optTable, optP, SL_SHORT, &found, &mi);
+        if (!found)
+            optFatal("unrecognized option `-%c'", *optP);
+
+        /* does this option take an argument? */
+        if (optNeedsArgument(optTable[mi])) {
+            /* option needs an argument. find it. */
+            arg = optP + 1;
+            if (!*arg) {
                 if (ai + 1 >= argc)
-                            optFatal("option `%s' requires an argument",
-                                     optString(opt_table[mi], 0));
-                        arg = argv[ai+1];
-            (*tokens_consumed_p)++;
-                    }
-                    processed_arg = 1;
-                } else
+                    optFatal("option `%s' requires an argument",
+                             optString(optTable[mi], 0));
+                arg = argv[ai+1];
+                ++*tokensConsumedP;
+            }
+            processedArg = 1;
+        } else
             arg = NULL;
-                /* perform the action of this option. */
-                optExecute(opt_table[mi], arg, 0);
-                ++o;
+        /* perform the action of this option. */
+        optExecute(optTable[mi], arg, 0);
+        ++optP;
     }
 }
 
@@ -784,12 +757,12 @@ fatalUnrecognizedLongOption(const char * const optionName,
 
 
 static void
-parse_long_option(char *   const argv[],
-                  int      const argc,
-                  int      const ai,
-                  int      const namepos,
-                  optEntry const opt_table[],
-                  int *    const tokens_consumed_p) {
+parseLongOption(const char **    const argv,
+                int              const argc,
+                int              const ai,
+                int              const namepos,
+                const optEntry * const optTable,
+                unsigned int *   const tokensConsumedP) {
 /*----------------------------------------------------------------------------
    Parse a long option, e.g. -verbose or --verbose.
 
@@ -799,104 +772,68 @@ parse_long_option(char *   const argv[],
    argv[] and argc describe the whole program argument set.  'ai' is the
    index of the argument that is the long option.
 -----------------------------------------------------------------------------*/
-    char *equals_arg;
+    char * equalsArg;
       /* The argument of an option, included in the same token, after a
          "=".  NULL if no "=" in the token.
          */
-    char *arg;     /* The argument of an option; NULL if none */
+    const char * arg;     /* The argument of an option; NULL if none */
     bool found;
-    int mi;    /* index into option table */
+    unsigned int mi;    /* index into option table */
 
     /* The current token is an option, and its name starts at
        Index 'namepos' in the argument.
     */
-    *tokens_consumed_p = 1;  /* initial assumption */
+    *tokensConsumedP = 1;  /* initial assumption */
     /* find matching option */
-    optMatch(opt_table, &argv[ai][namepos], SL_LONG, &found, &mi);
+    optMatch(optTable, &argv[ai][namepos], SL_LONG, &found, &mi);
     if (!found)
-        fatalUnrecognizedLongOption(argv[ai], opt_table);
+        fatalUnrecognizedLongOption(argv[ai], optTable);
 
     /* possibly locate the argument to this option. */
     {
-        char *p;
+        char * p;
         if ((p = strchr(argv[ai], '=')) != NULL)
-            equals_arg = p + 1;
+            equalsArg = p + 1;
         else
-            equals_arg = NULL;
+            equalsArg = NULL;
     }
     /* does this option take an argument? */
-    if (optNeedsArgument(opt_table[mi])) {
+    if (optNeedsArgument(optTable[mi])) {
         /* option needs an argument. find it. */
-        if (equals_arg)
-            arg = equals_arg;
+        if (equalsArg)
+            arg = equalsArg;
         else {
             if (ai + 1 == argc)
                 optFatal("option `%s' requires an argument",
-                         optString(opt_table[mi], 1));
+                         optString(optTable[mi], 1));
             arg = argv[ai+1];
-            (*tokens_consumed_p)++;
+            ++*tokensConsumedP;
         }
     } else {
-        if (equals_arg)
+        if (equalsArg)
             optFatal("option `%s' doesn't allow an argument, but you "
                      "have specified it in the form name=value",
-                     optString(opt_table[mi], 1));
+                     optString(optTable[mi], 1));
         else
             arg = NULL;
     }
     /* perform the action of this option. */
-    optExecute(opt_table[mi], arg, 1);
+    optExecute(optTable[mi], arg, 1);
 }
 
 
 
-/*------------------------------------------------------------------------
- |  NAME          pm_optParseOptions2
- |
- |  FUNCTION      Parse commandline options.
- |
- |  SYNOPSIS      #include "shhopt.h"
- |                void pm_optParseOptions2(int *argc, char *argv[],
- |                                      optStruct2 opt, unsigned long flags);
- |
- |  INPUT         argc    Pointer to number of options.
- |                argv    Array of option-/argument-strings.
- |                opt     Structure describing option syntax.
- |                flags   Result is undefined if not zero.
- |                        For future expansion.
- |
- |  OUTPUT        argc    new argument count.
- |                argv    array with arguments removed.
- |
- |  RETURNS       Nothing. Aborts in case of error.
- |
- |  DESCRIPTION   This function checks each option in the argv-array
- |                against strings in the opt-array, and `executes' any
- |                matching action. Any arguments to the options are
- |                extracted and stored in the variables or passed to
- |                functions pointed to by entries in opt.
- |
- |                This differs from pm_optParseOptions in that it accepts
- |                long options with just one hyphen and doesn't accept
- |                any short options.  It also has accommodations for
- |                future expansion.
- |
- |                Options and arguments used are removed from the argv-
- |                array, and argc is decreased accordingly.
- |
- |                Any error leads to program abortion.
- */
 void
-pm_optParseOptions2(int * const argc_p, char *argv[], const optStruct2 opt,
-                 const unsigned long flags)
+pm_optParseOptions2(int *         const argcP,
+                    char **       const argv,
+                    optStruct2    const opt,
+                    unsigned long const flags) {
 /*----------------------------------------------------------------------------
    This does the same thing as pm_optParseOptions3(), except that there is no
    "specified" return value.
 
    This function exists for backward compatibility.
 -----------------------------------------------------------------------------*/
-
-{
     optStruct3 opt3;
 
     opt3.short_allowed = opt.short_allowed;
@@ -907,7 +844,7 @@ pm_optParseOptions2(int * const argc_p, char *argv[], const optStruct2 opt,
         optFatal("Memory allocation failed (trying to allocate space for "
                  "new-format option table)");
 
-    pm_optParseOptions3(argc_p, argv, opt3, sizeof(opt3), flags);
+    pm_optParseOptions3(argcP, argv, opt3, sizeof(opt3), flags);
 
     free(opt3.opt_table);
 }
@@ -916,120 +853,132 @@ pm_optParseOptions2(int * const argc_p, char *argv[], const optStruct2 opt,
 
 
 static void
-zero_specified(optEntry opt_table[]) {
+zeroSpecified(const optEntry * const optTable) {
 /*----------------------------------------------------------------------------
    Set all the "number of times specified" return values identified in the
-   option table opt_table[] to zero.
+   option table opttable[] to zero.
 -----------------------------------------------------------------------------*/
     unsigned int i;
 
-    for (i = 0; opt_table[i].type != OPT_END; i++) {
-        if (opt_table[i].specified)
-            *(opt_table[i].specified) = 0;
+    for (i = 0; optTable[i].type != OPT_END; ++i) {
+        if (optTable[i].specified)
+            *(optTable[i].specified) = 0;
     }
 }
 
 
 
-/*------------------------------------------------------------------------
- |  NAME          pm_optParseOptions3
- |
- |  FUNCTION      Parse commandline options.
- |
- |  INPUT         argc    Pointer to number of options.
- |                argv    Array of option-/argument-strings.
- |                opt     Structure describing option syntax.
- |                optStructSize
- |                        Size of "opt" (since the caller may be older
- |                        than this function, it may be using a structure
- |                        with fewer fields than exist today.  We use this
- |                        parameter to handle those older callers).
- |                flags   Result is undefined if not zero.
- |                        For future expansion.
- |
- |  OUTPUT        argc    new argument count.
- |                argv    array with arguments removed.
- |
- |                Areas pointed to by pointers in 'opt' get updated with
- |                option values and counts.
- |
- |  RETURNS       Nothing. Aborts in case of error.
- |
- |  DESCRIPTION   This function checks each option in the argv-array
- |                against strings in the opt-array, and `executes' any
- |                matching action. Any arguments to the options are
- |                extracted and stored in the variables or passed to
- |                functions pointed to by entries in opt.
- |
- |                This differs from pm_optParseOptions in that it accepts
- |                long options with just one hyphen and doesn't accept
- |                any short options.  It also has accommodations for
- |                future expansion.
- |
- |                Options and arguments used are removed from the argv-
- |                array, and argc is decreased accordingly.
- |
- |                Any error leads to program abortion.
- */
 void
-pm_optParseOptions3(int * const argc_p, char *argv[], const optStruct3 opt,
-                 const unsigned int optStructSize, const unsigned long flags)
-{
-    int  ai;        /* argv index. */
-    int tokens_consumed;
-    unsigned char no_more_options;  /* boolean */
+pm_optParseOptions3(int *         const argcP,
+                    char **       const argv,
+                    optStruct3    const opt,
+                    unsigned int  const optStructSz,
+                    unsigned long const flags) {
+/*----------------------------------------------------------------------------
+  Same as 'pm_optParseOptions4', except argv has type char ** instead of const
+  char **.  This function does not modify the argv[] strings; it exists for
+  backward compatibility with programs that pass an argv of type char ** .
+-----------------------------------------------------------------------------*/
+    pm_optParseOptions4(argcP, (const char **)argv, opt, optStructSz, flags);
+}
+
+
+
+void
+pm_optParseOptions4(int *         const argcP,
+                    const char ** const argv,
+                    optStruct3    const opt,
+                    unsigned int  const optStructSize,
+                    unsigned long const flags) {
+/*---------------------------------------------------------------------------
+   FUNCTION      Parse commandline options.
+
+   INPUT         argc    Pointer to number of options.
+                 argv    Array of option-/argument-strings.
+                 opt     Structure describing option syntax.
+                 optStructSize
+                         Size of "opt" (since the caller may be older
+                         than this function, it may be using a structure
+                         with fewer fields than exist today.  We use this
+                         parameter to handle those older callers).
+                 flags   Result is undefined if not zero.
+                         For future expansion.
+
+   OUTPUT        argc    new argument count.
+                 argv    array with arguments removed.
+
+                 Areas pointed to by pointers in 'opt' get updated with
+                 option values and counts.
+
+   RETURNS       Nothing. Aborts in case of error.
+
+   DESCRIPTION   This function checks each option in the argv-array
+                 against strings in the opt-array, and `executes' any
+                 matching action. Any arguments to the options are
+                 extracted and stored in the variables or passed to
+                 functions pointed to by entries in opt.
+
+                 This differs from pm_optParseOptions in that it accepts
+                 long options with just one hyphen and doesn't accept
+                 any short options.  It also has accommodations for
+                 future expansion.
+
+                 Options and arguments used are removed from the argv-
+                 array, and argc is decreased accordingly.
+
+                 Any error leads to program abortion.
+----------------------------------------------------------------------------*/
+    unsigned int ai;        /* argv index. */
+    unsigned int tokensConsumed;
+    bool noMoreOptions;
         /* We've encountered the "no more options" token */
 
-    zero_specified(opt.opt_table);
+    zeroSpecified(opt.opt_table);
 
-    /*
-     *  Loop through all arguments.
-     */
-    no_more_options = 0;  /* initial value */
-    for (ai = 0; ai < *argc_p; ) {
-        if (no_more_options)
+    for (ai = 0, noMoreOptions = false; ai < *argcP; ) {
+        if (noMoreOptions)
             /* Can't be an option -- there aren't any more */
-            ai++;
+            ++ai;
         else if (argv[ai][0] != '-')
             /* Can't be an option -- doesn't start with a dash */
-            ai++;
+            ++ai;
         else {
             /* It starts with a dash -- could be an option */
             if (argv[ai][1] == '\0') {
                 /* A dash by itself is not considered an option. */
                 ++ai;
-                tokens_consumed = 0;
+                tokensConsumed = 0;
             } else if (opt.allowNegNum && ISDIGIT(argv[ai][1])) {
                 /* It's a negative number parameter, not an option */
                 ++ai;
-                tokens_consumed = 0;
+                tokensConsumed = 0;
             } else if (argv[ai][1] == '-') {
                 /* It starts with -- */
                 if (argv[ai][2] == '\0') {
                     /* The entire thing is "--".  That means no more options */
-                    tokens_consumed = 1;
-                    no_more_options = 1;
+                    tokensConsumed = 1;
+                    noMoreOptions  = true;
                 } else
                     /* It's an option that starts with "--" */
-                    parse_long_option(argv, *argc_p, ai, 2,
-                                      opt.opt_table, &tokens_consumed);
+                    parseLongOption(argv, *argcP, ai, 2,
+                                    opt.opt_table, &tokensConsumed);
             } else {
                 if (opt.short_allowed) {
                     /* It's a cluster of (one or more) short options */
-                    parse_short_option_token(argv, *argc_p, ai,
-                                             opt.opt_table, &tokens_consumed);
+                    parseShortOptionToken(argv, *argcP, ai,
+                                          opt.opt_table, &tokensConsumed);
                 } else {
                     /* It's a long option that starts with "-" */
-                    parse_long_option(argv, *argc_p, ai, 1,
-                                      opt.opt_table, &tokens_consumed);
+                    parseLongOption(argv, *argcP, ai, 1,
+                                    opt.opt_table, &tokensConsumed);
                 }
 
             }
             /* remove option and any argument from the argv-array. */
             {
-                int i;
-                for (i = 0; i < tokens_consumed; i++)
-                    argvRemove(argc_p, argv, ai);
+                unsigned int i;
+                for (i = 0; i < tokensConsumed; ++i)
+                    argvRemove(argcP, argv, ai);
             }
         }
     }
@@ -1049,3 +998,5 @@ pm_optDestroyNameValueList(struct optNameValue * const list) {
 
     free(list);
 }
+
+
diff --git a/lib/util/shhopt.h b/lib/util/shhopt.h
index 27adc144..26d375e4 100644
--- a/lib/util/shhopt.h
+++ b/lib/util/shhopt.h
@@ -261,6 +261,13 @@ pm_optParseOptions3(int * const argc_p, char *argv[], const optStruct3 opt,
                  const unsigned int optStructSize, const unsigned long flags);
 
 void
+pm_optParseOptions4(int *         const argcP,
+                    const char ** const argv,
+                    optStruct3    const opt,
+                    unsigned int  const optStructSize,
+                    unsigned long const flags);
+
+void
 pm_optDestroyNameValueList(struct optNameValue * const list);
 
 #ifdef __cplusplus
diff --git a/other/pamarith.c b/other/pamarith.c
index 31f52a59..05ba5327 100644
--- a/other/pamarith.c
+++ b/other/pamarith.c
@@ -112,7 +112,7 @@ parseCommandLine(int argc, const char ** const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (addSpec + subtractSpec + multiplySpec + divideSpec + differenceSpec +
diff --git a/other/pambayer.c b/other/pambayer.c
index 599dc11e..1d5522f9 100644
--- a/other/pambayer.c
+++ b/other/pambayer.c
@@ -55,8 +55,6 @@ parseCommandLine(int argc, const char ** argv,
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
     optEntry * option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -75,7 +73,7 @@ parseCommandLine(int argc, const char ** argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We may have parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     free(option_def);
diff --git a/other/pamchannel.c b/other/pamchannel.c
index 0b9c3947..95fdc088 100644
--- a/other/pamchannel.c
+++ b/other/pamchannel.c
@@ -43,8 +43,6 @@ parseCommandLine(int argc, const char ** argv,
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
     optEntry *option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
     optStruct3 opt;
     extern struct pam pam;  /* Just so we can look at field sizes */
 
@@ -63,7 +61,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (!infileSpec)
diff --git a/other/pamdepth.c b/other/pamdepth.c
index 4349f5ea..4425fcf2 100644
--- a/other/pamdepth.c
+++ b/other/pamdepth.c
@@ -36,8 +36,6 @@ parseCommandLine(int argc, const char ** argv,
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
     optEntry * option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -52,7 +50,7 @@ parseCommandLine(int argc, const char ** argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We may have parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc-1 < 1)
diff --git a/other/pamexec.c b/other/pamexec.c
index cbde81ac..b615790c 100644
--- a/other/pamexec.c
+++ b/other/pamexec.c
@@ -68,9 +68,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the pointers we place into *cmdlineP are sometimes to storage
    in the argv array.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -85,7 +83,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (argc-1 < 1)
diff --git a/other/pamlookup.c b/other/pamlookup.c
index 23a113c3..9682a65e 100644
--- a/other/pamlookup.c
+++ b/other/pamlookup.c
@@ -67,7 +67,7 @@ parseCommandLine(int argc, const char ** const argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We may have parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc,argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (!lookupfileSpec)
diff --git a/other/pampick.c b/other/pampick.c
index 67d42fc5..d831fcbb 100644
--- a/other/pampick.c
+++ b/other/pampick.c
@@ -98,9 +98,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the pointers we place into *cmdlineP are sometimes to storage
    in the argv array.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -119,7 +117,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     initUintSet(&cmdlineP->imageSeqList, argc-1);
diff --git a/other/pamsplit.c b/other/pamsplit.c
index 8c7aff11..1c1ab3d4 100644
--- a/other/pamsplit.c
+++ b/other/pamsplit.c
@@ -41,9 +41,7 @@ parseCommandLine(int argc, const char ** argv,
    Note that the pointers we place into *cmdlineP are sometimes to storage
    in the argv array.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;
     optStruct3 opt;
 
     unsigned int padnameSpec;
@@ -60,7 +58,7 @@ parseCommandLine(int argc, const 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, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (!padnameSpec)
diff --git a/other/pamstack.c b/other/pamstack.c
index 533795ca..1c005f4c 100644
--- a/other/pamstack.c
+++ b/other/pamstack.c
@@ -53,8 +53,6 @@ parseCommandLine(int argc, const char ** argv,
    was passed to us as the argv array.
 -----------------------------------------------------------------------------*/
     optEntry * option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
     optStruct3 opt;
     extern struct pam pam;  /* Just so we can look at field sizes */
 
@@ -73,7 +71,7 @@ parseCommandLine(int argc, const char ** argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We may have parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (!tupletypeSpec)
diff --git a/other/pamsummcol.c b/other/pamsummcol.c
index 673eaf57..ec0d2085 100644
--- a/other/pamsummcol.c
+++ b/other/pamsummcol.c
@@ -21,7 +21,7 @@ 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 * inputFilespec;  /* Filespec of input file */
     enum function function;
     unsigned int verbose;
 };
diff --git a/other/pamunlookup.c b/other/pamunlookup.c
index defa7b1f..a835ebd8 100644
--- a/other/pamunlookup.c
+++ b/other/pamunlookup.c
@@ -61,7 +61,7 @@ parseCommandLine(int argc, const char ** const argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We may have parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
     if (!lookupfileSpec)
diff --git a/other/pnmcolormap.c b/other/pnmcolormap.c
index 97e56654..f59a1a0d 100644
--- a/other/pnmcolormap.c
+++ b/other/pnmcolormap.c
@@ -111,9 +111,7 @@ parseCommandLine (int argc, const char ** argv,
    Note that the strings we return are stored in the storage that
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def;
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;
     optStruct3 opt;
 
     unsigned int option_def_index;
@@ -154,7 +152,7 @@ parseCommandLine (int argc, const 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, (char **)argv, opt, sizeof(opt), 0 );
+    pm_optParseOptions4( &argc, argv, opt, sizeof(opt), 0 );
         /* Uses and sets argc, argv, and some of *cmdline_p and others. */
 
 
diff --git a/other/ppmsvgalib.c b/other/ppmsvgalib.c
index 97cef286..e106280b 100644
--- a/other/ppmsvgalib.c
+++ b/other/ppmsvgalib.c
@@ -20,6 +20,7 @@
 #include "pm_c_util.h"
 #include "ppm.h"
 #include "shhopt.h"
+#include "mallocvar.h"
 
 struct cmdlineInfo {
     /* All the information the user supplied in the command line,
@@ -45,15 +46,15 @@ parseCommandLine (int argc, char ** argv,
    Note that the strings we return are stored in the storage that
    was passed to us as the argv array.  We also trash *argv.
 -----------------------------------------------------------------------------*/
-    optEntry *option_def = malloc( 100*sizeof( optEntry ) );
-        /* Instructions to pm_optParseOptions3 on how to parse our options.
-         */
+    optEntry * option_def;
     optStruct3 opt;
 
     unsigned int option_def_index;
 
     unsigned int modeSpec;
 
+    MALLOCARRAY(option_def, 100);
+
     option_def_index = 0;   /* incremented by OPTENT3 */
     OPTENT3(0,   "mode",         OPT_UINT,
             &cmdlineP->mode,   &modeSpec, 0);
diff --git a/test/Execute-Tests b/test/Execute-Tests
index 3c231d98..c86121dc 100755
--- a/test/Execute-Tests
+++ b/test/Execute-Tests
@@ -50,7 +50,7 @@ esac
 # invoke, the list of tests to run ('Test-Order'), and *.ok files that
 # indicate the expected results of tests.
 
-srcdir=$(dirname $0)
+export srcdir=$(dirname $0)
 
 # Set tmpdir, which is used in some of the test scripts.  By default
 # this is created by mktemp.  The user can override and specify tmpdir,
diff --git a/test/pamarith.test b/test/pamarith.test
index 03ce7317..20c4039d 100755
--- a/test/pamarith.test
+++ b/test/pamarith.test
@@ -116,142 +116,68 @@ for image in maze.pbm ${input1_ppm}
 
 rm ${input1_ppm}
 
-echo "Invalid command-line argument combinations." 1>&2
-echo "Error messages should appear below the line." 1>&2
-echo "-----------------------------------------------------------" 1>&2
-
 echo "Test Invalid"
 
-test_out=${tmpdir}/test_out
+. ${srcdir}/test-invalid.inc
 
 # multiple functions
 
-pamarith -add -subtract testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -multiply -divide testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -difference -minimum testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -maximum -mean testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -compare -and testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -compare -equal testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 6 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -or -nand testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 7 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -nor -xor testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 8 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -shiftleft -shiftright testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 9 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamarith -add -subtract testimg.ppm testimg.ppm"
+invCmd "pamarith -multiply -divide testimg.ppm testimg.ppm"
+invCmd "pamarith -difference -minimum testimg.ppm testimg.ppm"
+invCmd "pamarith -maximum -mean testimg.ppm testimg.ppm"
+invCmd "pamarith -compare -and testimg.ppm testimg.ppm"
+invCmd "pamarith -compare -equal testimg.ppm testimg.ppm"
+invCmd "pamarith -or -nand testimg.ppm testimg.ppm"
+invCmd "pamarith -nor -xor testimg.ppm testimg.ppm"
+invCmd "pamarith -shiftleft -shiftright testimg.ppm testimg.ppm"
 
 # -add does not take a value
 
-pamarith -add=1 testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 10 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamarith -add=1 testimg.ppm testimg.ppm"
 
 # No function
 
-pamarith -plain testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 11 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 12 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamarith -plain testimg.ppm testimg.ppm"
+invCmd "pamarith testimg.ppm testimg.ppm"
 
 # Just one input image file
 
-pamarith -add testimg.ppm > ${test_out} || \
-  printf "Expected failure 13 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamarith -add testimg.ppm"
 
 # No input image file
 
-pamarith -add > ${test_out} || \
-  printf "Expected failure 14 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamarith -add"
 
 # Input images with different depth (number of planes)
 
-pamchannel -infile testimg.ppm 0 1 | \
-  pamarith -add testimg.ppm - > ${test_out} || \
-  printf "Expected failure 15 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+input1_pam=${tmpdir}/input1.pam
 
-# Input images with different x/y dimensions
+pamchannel -infile testimg.ppm 0 1 > ${input1_pam}
+invCmd "pamarith -add testimg.ppm ${input1_pam}"
+rm ${input1_pam}
 
-pamarith -add testimg.ppm testgrid.pbm > ${test_out} || \
-  printf "Expected failure 16 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamenlarge -xscale=2 testgrid.pbm | \
-  pamarith -add testgrid.pbm - > ${test_out} || \
-  printf "Expected failure 17 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+# Input images with different x/y dimensions
 
-pamenlarge -yscale=3 testgrid.pbm | \
-  pamarith -add testgrid.pbm - > ${test_out} || \
-  printf "Expected failure 18 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamarith -add testimg.ppm testgrid.pbm"
 
-# Invalid usage of -closeness
+input1_pbm=${tmpdir}/input1.pbm
+input2_pbm=${tmpdir}/input2.pbm
 
-pamarith -equal -closeness=100.1 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 19 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+pamenlarge -xscale=2 testgrid.pbm > ${input1_pbm}
+invCmd "pamarith -add testgrid.pbm ${input1_pbm}"
+rm ${input1_pbm}
 
-pamarith -equal -closeness=-10 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 20 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+pamenlarge -yscale=3 testgrid.pbm > ${input2_pbm}
+invCmd "pamarith -add testgrid.pbm ${input2_pbm}"
+rm ${input2_pbm}
 
-pamarith -closeness -equal testgrid.pbm > ${test_out} || \
-  printf "Expected failure 21 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+# Invalid usage of -closeness
 
-pamarith -compare -closeness=10 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 22 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamarith -equal -closeness=100.1 testgrid.pbm"
+invCmd "pamarith -equal -closeness=-10 testgrid.pbm"
+invCmd "pamarith -closeness -equal testgrid.pbm"
+invCmd "pamarith -compare -closeness=10 testgrid.pbm"
 
 # Bit string functions
 # Create PGM test input
@@ -266,67 +192,21 @@ pgmmake -maxval=8191 1.0 3 1 > ${input5_pgm}
 
 # Bit string functions - Maxval must match
 
-pamarith -and ${input3_pgm} ${input5_pgm} > ${test_out} || \
-  printf "Expected failure 23 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -or ${input3_pgm} ${input5_pgm} > ${test_out} || \
-  printf "Expected failure 24 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -nand ${input3_pgm} ${input5_pgm} > ${test_out} || \
-  printf "Expected failure 25 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -nor ${input3_pgm} ${input5_pgm} > ${test_out} || \
-  printf "Expected failure 26 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -xor ${input3_pgm} ${input5_pgm} > ${test_out} || \
-  printf "Expected failure 27 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamarith -and ${input3_pgm} ${input5_pgm}"
+invCmd "pamarith -or ${input3_pgm} ${input5_pgm}"
+invCmd "pamarith -nand ${input3_pgm} ${input5_pgm}"
+invCmd "pamarith -nor ${input3_pgm} ${input5_pgm}"
+invCmd "pamarith -xor ${input3_pgm} ${input5_pgm}"
 
 # Bit string functions - Maxval must be 2^n -1
 
-pamarith -and ${input4_pgm} ${input4_pgm} > ${test_out} || \
-  printf "Expected failure 28 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -or ${input4_pgm} ${input4_pgm} > ${test_out} || \
-  printf "Expected failure 29 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -nand ${input4_pgm} ${input4_pgm} > ${test_out} || \
-  printf "Expected failure 30 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -nor ${input4_pgm} ${input4_pgm} > ${test_out} || \
-  printf "Expected failure 31 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -xor ${input4_pgm} ${input4_pgm} > ${test_out} || \
-  printf "Expected failure 32 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -shiftleft ${input4_pgm} ${input4_pgm} > ${test_out} || \
-  printf "Expected failure 33 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -shiftright ${input4_pgm} ${input4_pgm} > ${test_out} || \
-  printf "Expected failure 34 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamarith -and ${input4_pgm} ${input4_pgm}"
+invCmd "pamarith -or ${input4_pgm} ${input4_pgm}"
+invCmd "pamarith -nand ${input4_pgm} ${input4_pgm}"
+invCmd "pamarith -nor ${input4_pgm} ${input4_pgm}"
+invCmd "pamarith -xor ${input4_pgm} ${input4_pgm}"
+invCmd "pamarith -shiftleft ${input4_pgm} ${input4_pgm}"
+invCmd "pamarith -shiftright ${input4_pgm} ${input4_pgm}"
 
 rm ${input3_pgm} ${input4_pgm} ${input5_pgm}
 
@@ -334,45 +214,15 @@ rm ${input3_pgm} ${input4_pgm} ${input5_pgm}
 # Only the functions that are commutative and associative allow
 # three or more inputs.
 
-pamarith -subtract testimg.ppm testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 35 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -divide testimg.ppm testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 36 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -compare testimg.ppm testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 37 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -difference testimg.ppm testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 38 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -shiftleft testimg.ppm testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 39 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -shiftright testimg.ppm testimg.ppm testimg.ppm > ${test_out} || \
-  printf "Expected failure 40 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamarith -subtract testimg.ppm testimg.ppm testimg.ppm"
+invCmd "pamarith -divide testimg.ppm testimg.ppm testimg.ppm"
+invCmd "pamarith -compare testimg.ppm testimg.ppm testimg.ppm"
+invCmd "pamarith -difference testimg.ppm testimg.ppm testimg.ppm"
+invCmd "pamarith -shiftleft testimg.ppm testimg.ppm testimg.ppm"
+invCmd "pamarith -shiftright testimg.ppm testimg.ppm testimg.ppm"
 
 # Currently -equal and -mean do not allow more than two input images.
 # These two cases should be removed once improvements are made.
 
-pamarith -equal testgrid.pbm testgrid.pbm testgrid.pbm > ${test_out} || \
-  printf "Expected failure 41 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamarith -mean testgrid.pbm  testgrid.pbm testgrid.pbm > ${test_out} || \
-  printf "Expected failure 42 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamarith -equal testgrid.pbm testgrid.pbm testgrid.pbm"
+invCmd "pamarith -mean testgrid.pbm  testgrid.pbm testgrid.pbm"
diff --git a/test/pambrighten.ok b/test/pambrighten.ok
index 6c58b4c9..8dc9e71e 100644
--- a/test/pambrighten.ok
+++ b/test/pambrighten.ok
@@ -78,19 +78,11 @@ Test 4: Should print 3990234518 268 six times
 3990234518 268
 3990234518 268
 3990234518 268
-Test Error: Should print 1 six times
-1
-1
-1
-1
-1
-1
-Test Error: Should print 99 followed by 1, four times
-99
-1
-99
-1
-99
-1
-99
-1
+Test Invalid
+Expected failure 1 (no output)
+Expected failure 2 (no output)
+Expected failure 3 (no output)
+Expected failure 4 (no output)
+Expected failure 5 (no output)
+Expected failure 6 (no output)
+Expected failure 7 (no output)
diff --git a/test/pambrighten.test b/test/pambrighten.test
index 00e405dd..d79ad583 100755
--- a/test/pambrighten.test
+++ b/test/pambrighten.test
@@ -10,7 +10,7 @@ cat > ${input_ppm} << EOF
 P3
 8 1
 255
-0 0 0 0 0 100 0 100 0 0 100 100 100 0 0 100 0 100 100 100 0 100 100 100 
+0 0 0 0 0 100 0 100 0 0 100 100 100 0 0 100 0 100 100 100 0 100 100 100
 EOF
 
 # Test 1
@@ -50,50 +50,14 @@ pambrighten -s +200 ${input_pgm} | cksum
 
 rm ${input_pgm}
 
+echo "Test Invalid"
 
-# Test 2
-# These should all fail.
+. ${srcdir}/test-invalid.inc
 
-echo "Invalid command-line argument combinations." 1>&2
-echo "Error messages should appear below the line." 1>&2
-echo "-----------------------------------------------------------" 1>&2
-
-echo "Test Error: Should print 1 six times"
-
-output_ppm=${tmpdir}/output.ppm
-
-pambrighten -v -120 testimg.ppm > ${output_ppm}
-echo $?
-test -s ${output_ppm}
-echo $?
-pambrighten -s -120 testimg.ppm > ${output_ppm}
-echo $?
-test -s ${output_ppm}
-echo $?
-pambrighten 10 testimg.ppm > ${output_ppm}
-echo $?
-test -s ${output_ppm}
-echo $?
-
-
-echo "Test Error: Should print 99 followed by 1, four times"
-
-pambrighten -s 1.20 testimg.ppm > ${output_ppm}
-echo $?
-test -s ${output_ppm}
-echo $?
-pambrighten -v 10.5 testimg.ppm > ${output_ppm}
-echo $?
-test -s ${output_ppm}
-echo $?
-pambrighten -v testimg.ppm > ${output_ppm}
-echo $?
-test -s ${output_ppm}
-echo $?
-pambrighten -s testimg.ppm > ${output_ppm}
-echo $?
-test -s ${output_ppm}
-echo $?
-
-
-rm -f ${output_ppm}
+invCmd "pambrighten -v -120 testimg.ppm"
+invCmd "pambrighten -s -120 testimg.ppm"
+invCmd "pambrighten 10 testimg.ppm"
+invCmd "pambrighten -s 1.20 testimg.ppm"
+invCmd "pambrighten -v 10.5 testimg.ppm"
+invCmd "pambrighten -v testimg.ppm"
+invCmd "pambrighten -s testimg.ppm"
diff --git a/test/pamcat1.test b/test/pamcat1.test
index 902ef6d7..9480228c 100755
--- a/test/pamcat1.test
+++ b/test/pamcat1.test
@@ -187,82 +187,26 @@ rm ${seq2_4h_pam} ${seq2_4v_pam} ${seq2_4v3_pam} ${seq2_4h4_pam}
 
 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
+. ${srcdir}/test-invalid.inc
 
 # direction not specified
-pamcat testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamcat testgrid.pbm testimg.ppm"
 
 # both directions specified
-pamcat -topbottom -leftright testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamcat -topbottom -leftright testgrid.pbm testimg.ppm"
 
 # both pad colors specified
-pamcat -topbottom -white -black testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-# justification parameters overspecified
-pamcat -lr -jtop -jbottom testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcat -lr -jtop -jcenter testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcat -lr -jcenter -jbottom testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 6 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcat -tb -jleft -jright testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 7 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcat -tb -jleft -jcenter testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 8 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcat -tb -jcenter -jright testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 9 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-# justification parameter in the wrong direction
-pamcat -lr -jleft    testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 10 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcat -lr -jright   testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 11 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcat -tb -jtop     testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 12 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcat -tb -jbottom  testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 13 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamcat -topbottom -white -black testgrid.pbm testimg.ppm"
+invCmd "pamcat -lr -jtop -jbottom testgrid.pbm testimg.ppm"
+invCmd "pamcat -lr -jtop -jcenter testgrid.pbm testimg.ppm"
+invCmd "pamcat -lr -jcenter -jbottom testgrid.pbm testimg.ppm"
+invCmd "pamcat -tb -jleft -jright testgrid.pbm testimg.ppm"
+invCmd "pamcat -tb -jleft -jcenter testgrid.pbm testimg.ppm"
+invCmd "pamcat -tb -jcenter -jright testgrid.pbm testimg.ppm"
+invCmd "pamcat -lr -jleft    testgrid.pbm testimg.ppm"
+invCmd "pamcat -lr -jright   testgrid.pbm testimg.ppm"
+invCmd "pamcat -tb -jtop     testgrid.pbm testimg.ppm"
+invCmd "pamcat -tb -jbottom  testgrid.pbm testimg.ppm"
 
 # more than one input image from standard input
 cat testgrid.pbm | pamcat -lr - - testimg.ppm > ${test_out} || \
diff --git a/test/pamchannel.test b/test/pamchannel.test
index 2f772bf9..f3399343 100755
--- a/test/pamchannel.test
+++ b/test/pamchannel.test
@@ -41,17 +41,8 @@ test_out=${tmpdir}/test_out
 
 echo "Test Invalid"
 
-pamchannel  -infile testgrid.pbm 1 > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamchannel  -infile testimg.ppm 3 > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamtopam testimg.ppm | pamchannel -infile=- 4 > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
+
+invCmd "pamchannel  -infile testgrid.pbm 1"
+invCmd "pamchannel  -infile testimg.ppm 3"
+invCmd "pamtopam testimg.ppm | pamchannel -infile=- 4"
diff --git a/test/pamcrater.test b/test/pamcrater.test
index 1b4ffd54..5362bde3 100755
--- a/test/pamcrater.test
+++ b/test/pamcrater.test
@@ -52,33 +52,17 @@ pamshadedrelief ${test100_pam} > ${testshaded_pam}
   pamcut -top=$((128 - 99)) -height=1  ${testshaded_pam} | cksum
 ) | uniq -c | awk '{print $1}'
 
-rm ${testshaded_pam} ${test100_pam} ${test150_pam}
+rm ${testshaded_pam} ${test150_pam}
 
 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
-
-pamcrater -width 0 > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcrater -height 0 > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcrater -number 0 > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcrater -test -radius=10 | pamshadedrelief -gamma 0 > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
+
+invCmd "pamcrater -width 0"
+invCmd "pamcrater -height 0"
+invCmd "pamcrater -number 0"
+invCmd "pamshadedrelief -gamma 0 ${test100_pam}"
+
+rm ${test100_pam}
diff --git a/test/pamcut.ok b/test/pamcut.ok
index 60919865..18ed88e8 100644
--- a/test/pamcut.ok
+++ b/test/pamcut.ok
@@ -1,23 +1,91 @@
-Test 1.  Should print 2958909756 124815
+Test 1a.  Should print 0 259 0 159 227 149 260 160 twice
+0 259 0 159 227 149 260 160
+0 259 0 159 227 149 260 160
+Test 1b.  Should print 2958909756 124815
 2958909756 124815
-Test 2.  Should print 1550940962 10933
-1550940962 10933
-Test 3.  Should print 708474423 14 twice
+Test 2a.  Should print 120 159 120 159 227 149 40 40 three times
+120 159 120 159 227 149 40 40
+120 159 120 159 227 149 40 40
+120 159 120 159 227 149 40 40
+Test 2b.  Should print 3876978825 4813 twice
+3876978825 4813
+3876978825 4813
+Test 3a.  Should print 5 5 5 5 227 149 1 1 three times
+5 5 5 5 227 149 1 1
+5 5 5 5 227 149 1 1
+5 5 5 5 227 149 1 1
+Test 3b.  Should print 708474423 14
 708474423 14
-708474423 14
-Test 4.  Should print 659346598 80124 four times
-659346598 80124
-659346598 80124
-659346598 80124
+Test 4a.  Should print 10 216 10 138 227 149 207 129 five times
+10 216 10 138 227 149 207 129
+10 216 10 138 227 149 207 129
+10 216 10 138 227 149 207 129
+10 216 10 138 227 149 207 129
+10 216 10 138 227 149 207 129
+Test 4b.  Should print 659346598 80124
 659346598 80124
-Test 5. Should print 281226646 481 five times
+Test 5a. Should print 0 56 0 58 57 59 57 59 five times
+0 56 0 58 57 59 57 59
+0 56 0 58 57 59 57 59
+0 56 0 58 57 59 57 59
+0 56 0 58 57 59 57 59
+0 56 0 58 57 59 57 59
+Test 5b. Should print 281226646 481 twice
 281226646 481
 281226646 481
-281226646 481
-281226646 481
-281226646 481
-Test 6.  Should print 3412257956 129
+Test 6a.  Should print 5 34 5 34 50 50 30 30
+5 34 5 34 50 50 30 30
+Test 6b.  Should print 3412257956 129
 3412257956 129
+Test 7.  Should print 284857390 12 sixteen times
+284857390 12
+284857390 12
+284857390 12
+284857390 12
+284857390 12
+284857390 12
+284857390 12
+284857390 12
+284857390 12
+284857390 12
+284857390 12
+284857390 12
+284857390 12
+284857390 12
+284857390 12
+284857390 12
+Test 8.  Should print 3125257619 29 four times
+3125257619 29
+3125257619 29
+3125257619 29
+3125257619 29
+Test 9.  Should print 3338453023 36 sixteen times
+3338453023 36
+3338453023 36
+3338453023 36
+3338453023 36
+3338453023 36
+3338453023 36
+3338453023 36
+3338453023 36
+3338453023 36
+3338453023 36
+3338453023 36
+3338453023 36
+3338453023 36
+3338453023 36
+3338453023 36
+3338453023 36
+Test 10.  Should print 3957742883 302 four times
+3957742883 302
+3957742883 302
+3957742883 302
+3957742883 302
+Test 11.  Should print 1576602925 8 four times
+1576602925 8
+1576602925 8
+1576602925 8
+1576602925 8
 Test Invalid
 Expected failure 1 (no output)
 Expected failure 2 (no output)
@@ -28,9 +96,11 @@ Expected failure 6 (no output)
 Expected failure 7 (no output)
 Expected failure 8 (no output)
 Expected failure 9 (no output)
-Expected failure 6 (no output)
 Expected failure 10 (no output)
 Expected failure 11 (no output)
 Expected failure 12 (no output)
 Expected failure 13 (no output)
 Expected failure 14 (no output)
+Expected failure 15 (no output)
+Expected failure 16 (no output)
+Expected failure 17 (no output)
diff --git a/test/pamcut.test b/test/pamcut.test
index 7cda5bce..7d60e1cd 100755
--- a/test/pamcut.test
+++ b/test/pamcut.test
@@ -1,134 +1,226 @@
 #! /bin/sh
-# This script tests: pamcut pbmmake
-# Also requires: pamfile
+# This script tests: pamcut
+# Also requires:  pbmmake pgmmake pamfile pnmpad pamflip
 
-echo "Test 1.  Should print 2958909756 124815"
+tmpdir=${tmpdir:-/tmp}
+
+echo "Test 1a.  Should print 0 259 0 159 227 149 260 160 twice"
+
+pamcut -left 0 -right 259 -top 0 -bottom 159 \
+      -pad -reportonly testimg.ppm
+pamcut  -left 0 -top 0 -width 260 -height 160 \
+      -pad -reportonly testimg.ppm
+
+echo "Test 1b.  Should print 2958909756 124815"
+
+pamcut -left 0 -top 0 -width 260 -height 160 \
+ -pad testimg.ppm | cksum
+
+echo "Test 2a.  Should print 120 159 120 159 227 149 40 40 three times"
+
+pamcut -left 120 -right 159 -top 120 -bottom 159 \
+ -pad -reportonly testimg.ppm
+pamcut -right 159 -bottom 159 -width 40 -height 40 \
+ -pad -reportonly testimg.ppm
+pamcut -left 120 -top 120 -width 40 -height 40 \
+ -pad -reportonly testimg.ppm
 
-pamcut -top 0 -left 0 -width 260 -height 160 \
-  -pad testimg.ppm | cksum
+echo "Test 2b.  Should print 3876978825 4813 twice"
 
-echo "Test 2.  Should print 1550940962 10933"
+pamcut -left 120 -right 159 -top 120 -bottom 159 \
+ -pad testimg.ppm | cksum
+pamcut -left 120 -top 120 -width 40  \
+ -pad testimg.ppm | pnmpad -black -bottom 11 | cksum
 
-pamcut -top 200 -left 120 -width 40 -height 40 \
-  -pad testimg.ppm | cksum
+echo "Test 3a.  Should print 5 5 5 5 227 149 1 1 three times"
 
-echo "Test 3.  Should print 708474423 14 twice"
+pamcut -top 5 -left 5 -bottom 5 -right 5 -reportonly testimg.ppm
+pamcut -width 1 -height 1 -bottom 5 -right 5 -reportonly testimg.ppm
+pamcut -cropleft 5 -croptop 5 -width 1 -height 1 -reportonly testimg.ppm
+
+echo "Test 3b.  Should print 708474423 14"
 
 pamcut -top 5 -left 5 -bottom 5 -right 5 testimg.ppm | cksum
-pamcut -width 1 -height 1 -bottom 5 -right 5 testimg.ppm | cksum
 
-echo "Test 4.  Should print 659346598 80124 four times"
+echo "Test 4a.  Should print 10 216 10 138 227 149 207 129 five times"
+
+pamcut -croptop 10 -cropleft 10 -cropbottom 10 -cropright 10 \
+      -reportonly testimg.ppm 
+pamcut -cropbottom 10 -cropright 10 -width 207 -height 129  \
+      -reportonly testimg.ppm 
+pamcut -top 10 -left 10 -bottom 138 -right 216 -reportonly testimg.ppm
+pamcut -top 10 -left 10 -bottom -11 -right -11 -reportonly testimg.ppm 
+pamcut -top 10 -left 10 -width 207 -height 129 -reportonly testimg.ppm 
+
+echo "Test 4b.  Should print 659346598 80124"
 
-pamcut -croptop 10 -cropleft 10 -cropbottom 10 -cropright 10 testimg.ppm | \
-  cksum
-pamcut -top 10 -left 10 -bottom 138 -right 216 testimg.ppm | cksum
-pamcut -top 10 -left 10 -bottom -11 -right -11 testimg.ppm | cksum
 pamcut -top 10 -left 10 -width 207 -height 129 testimg.ppm | cksum
 
-echo "Test 5. Should print 281226646 481 five times"
+echo "Test 5a. Should print 0 56 0 58 57 59 57 59 five times"
 
 mazesize=$(pamfile -size maze.pbm)
 width=$(echo ${mazesize} | cut -d " " -f 1)
 height=$(echo ${mazesize} | cut -d " " -f 2)
- 
+
+pamcut -croptop 0 -cropleft 0 -cropbottom 0 -cropright 0 \
+      -reportonly maze.pbm
+pamcut -top 0 -left 0 \
+      -bottom $((${height} -1)) -right $((${width} -1)) \
+       -reportonly maze.pbm
+pamcut -top 0 -left 0 -bottom -1 -right -1 -reportonly maze.pbm 
+pamcut -top 0 -left 0 -width ${width} -height ${height} \
+      -reportonly maze.pbm
+pamcut -reportonly maze.pbm 
+
+echo "Test 5b. Should print 281226646 481 twice"
+
 pamcut -croptop 0 -cropleft 0 -cropbottom 0 -cropright 0 maze.pbm | \
-  cksum
-pamcut -top 0 -left 0 -bottom $((${height} -1)) -right $((${width} -1)) \
-  maze.pbm | cksum
-pamcut -top 0 -left 0 -bottom -1 -right -1 maze.pbm | cksum
-pamcut -top 0 -left 0 -width ${width} -height ${height} maze.pbm | cksum
+ cksum
 pamcut maze.pbm | cksum
- 
-echo "Test 6.  Should print 3412257956 129"
 
-pbmmake -g 50 50 | pamcut 5 5 30 30 | cksum
+test50_pbm=${tmpdir}/test50.pbm
 
+echo "Test 6a.  Should print 5 34 5 34 50 50 30 30"
 
-echo "Test Invalid"
+pbmmake -g 50 50 | tee ${test50_pbm} | pamcut -reportonly 5 5 30 30
 
-tmpdir=${tmpdir:-/tmp}
-test_out=${tmpdir}/test_out
+echo "Test 6b.  Should print 3412257956 129"
+
+pamcut 5 5 30 30 ${test50_pbm} | cksum
+
+rm  ${test50_pbm}
+
+echo "Test 7.  Should print 284857390 12 sixteen times"
+
+test1_pbm=${tmpdir}/test1.pbm
+
+pbmmake -b 1 1 > ${test1_pbm}
+
+# pbmmake -b 5 5 | cksum
+
+pamcut  -pad -cropleft=6 -croptop=6 -width=5 -height=5 ${test1_pbm} | cksum
+pamcut  -pad -cropright=6 -croptop=6 -width=5 -height=5 ${test1_pbm} | cksum
+pamcut  -pad -cropleft=6 -cropbottom=6 -width=5 -height=5 ${test1_pbm} | cksum
+pamcut  -pad -cropright=6 -cropbottom=6 -width=5 -height=5 ${test1_pbm} | cksum
+
+pamcut  -pad -cropleft=6 -width=5 -height=5 ${test1_pbm} | cksum
+pamcut  -pad -croptop=6 -width=5 -height=5 ${test1_pbm} | cksum
+pamcut  -pad -cropbottom=6 -width=5 -height=5 ${test1_pbm} | cksum
+pamcut  -pad -cropright=6 -width=5 -height=5 ${test1_pbm} | cksum
+
+pamcut  -pad -cropleft=7 -croptop=7 -width=5 -height=5 ${test1_pbm} | cksum
+pamcut  -pad -cropright=7 -croptop=7 -width=5 -height=5 ${test1_pbm} | cksum
+pamcut  -pad -cropleft=7 -cropbottom=7 -width=5 -height=5 ${test1_pbm} | cksum
+pamcut  -pad -cropright=7 -cropbottom=7 -width=5 -height=5 ${test1_pbm} | cksum
+
+pamcut  -pad -cropleft=17 -width=5 -height=5 ${test1_pbm} | cksum
+pamcut  -pad -croptop=17 -width=5 -height=5 ${test1_pbm} | cksum
+pamcut  -pad -cropbottom=17 -width=5 -height=5 ${test1_pbm} | cksum
+pamcut  -pad -cropright=17 -width=5 -height=5 ${test1_pbm} | cksum
+
+
+echo "Test 8.  Should print 3125257619 29 four times"
 
-echo 1>&2
-echo "Invalid command-line argument combinations." 1>&2
-echo "Error messages should appear below the line." 1>&2
-echo "-----------------------------------------------------------" 1>&2
+test3_pbm=${tmpdir}/test3.pbm
+
+pbmmake -g 3 3 > ${test3_pbm}
+
+pamcut -pad -cropleft=10  -croptop=10    -width=10 -height=10 ${test3_pbm} | cksum
+pamcut  -pad -cropright=10 -croptop=10 -width=10 -height=10    ${test3_pbm} |\
+   pamflip -lr | cksum
+pamcut  -pad -cropleft=10  -cropbottom=10 -width=10 -height=10 ${test3_pbm} |\
+   pamflip -tb | cksum
+pamcut  -pad -cropright=10 -cropbottom=10 -width=10 -height=10 ${test3_pbm} |\
+   pamflip -r180 | cksum
+
+rm ${test3_pbm}
+
+echo "Test 9.  Should print 3338453023 36 sixteen times"
+
+testb_pgm=${tmpdir}/testb.pgm
+
+pgmmake 0.0 1 1 > ${testb_pgm}
+
+# pgmmake 0.0 5 5 | cksum
+
+pamcut  -pad -cropleft=6 -croptop=6 -width=5 -height=5 ${testb_pgm} | cksum
+pamcut  -pad -cropright=6 -croptop=6 -width=5 -height=5 ${testb_pgm} | cksum
+pamcut  -pad -cropleft=6 -cropbottom=6 -width=5 -height=5 ${testb_pgm} | cksum
+pamcut  -pad -cropright=6 -cropbottom=6 -width=5 -height=5 ${testb_pgm} | cksum
+
+pamcut  -pad -cropleft=6 -width=5 -height=5 ${testb_pgm} | cksum
+pamcut  -pad -croptop=6 -width=5 -height=5 ${testb_pgm} | cksum
+pamcut  -pad -cropbottom=6 -width=5 -height=5 ${testb_pgm} | cksum
+pamcut  -pad -cropright=6 -width=5 -height=5 ${testb_pgm} | cksum
+
+pamcut  -pad -cropleft=7 -croptop=7 -width=5 -height=5 ${testb_pgm} | cksum
+pamcut  -pad -cropright=7 -croptop=7 -width=5 -height=5 ${testb_pgm} | cksum
+pamcut  -pad -cropleft=7 -cropbottom=7 -width=5 -height=5 ${testb_pgm} | cksum
+pamcut  -pad -cropright=7 -cropbottom=7 -width=5 -height=5 ${testb_pgm} | cksum
+
+pamcut  -pad -cropleft=17 -width=5 -height=5 ${testb_pgm} | cksum
+pamcut  -pad -croptop=17 -width=5 -height=5 ${testb_pgm} | cksum
+pamcut  -pad -cropbottom=17 -width=5 -height=5 ${testb_pgm} | cksum
+pamcut  -pad -cropright=17 -width=5 -height=5 ${testb_pgm} | cksum
+
+rm  ${testb_pgm}
+
+echo "Test 10.  Should print 3957742883 302 four times"
+
+testg_pgm=${tmpdir}/testg.pgm
+
+pgmmake 0.5 2 2 > ${testg_pgm}
+
+# pgmmake 0.0 17 17 | cksum
+
+pamcut -pad -cropleft=17  -croptop=17    -width=17 -height=17 ${testg_pgm} |  cksum
+pamcut -pad -cropright=17 -croptop=17    -width=17 -height=17 ${testg_pgm} | \
+    pamflip -lr | cksum
+pamcut -pad -cropleft=17  -cropbottom=17 -width=17 -height=17 ${testg_pgm} | \
+    pamflip -tb | cksum
+pamcut -pad -cropright=17 -cropbottom=17 -width=17 -height=17 ${testg_pgm} |\
+    pamflip -r180 | cksum
+
+rm  ${testg_pgm}
+
+echo "Test 11.  Should print 1576602925 8 four times"
+
+test5_pbm=${tmpdir}/test5.pbm
+
+pbmmake -g 5 5 > ${test5_pbm}
+
+cat ${test1_pbm} | cksum
+pamcut -pad -left=6 -right=6 -top=6 -bottom 6 ${test5_pbm} | cksum
+pamcut -pad -left=-6 -right=-6 -top=-6 -bottom -6 ${test5_pbm} | cksum
+pamcut -pad -left=101 -right=101 -top=1001 -bottom 1001 ${test5_pbm} | cksum
+
+rm ${test1_pbm} ${test5_pbm}
+
+echo "Test Invalid"
+
+. ${srcdir}/test-invalid.inc
 
 # overspecification
-pamcut -left=1 -right=1 -width=14 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcut -top=1 -bottom=1 -height=16 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcut -right=1 -cropright=1 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcut -top=1 -croptop=1 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcut -bottom=1 -cropbottom=1 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcut -left=1 -cropleft=1 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 6 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-# excessive cropping
-pamcut -cropleft=7 -cropright=8 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 7 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcut -left=7 -right=6 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 8 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcut -croptop=8 -cropbottom=8 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 9 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcut -top=10 -bottom=9 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 6 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamcut -left=1 -right=1 -width=14 testgrid.pbm"
+invCmd "pamcut -top=1 -bottom=1 -height=16 testgrid.pbm"
+invCmd "pamcut -right=1 -cropright=1 testgrid.pbm"
+invCmd "pamcut -top=1 -croptop=1 testgrid.pbm"
+invCmd "pamcut -bottom=1 -cropbottom=1 testgrid.pbm"
+invCmd "pamcut -left=1 -cropleft=1 testgrid.pbm"
+
+# excessive amounts
+invCmd "pamcut -cropleft=14 testgrid.pbm"
+invCmd "pamcut -cropleft=7 -cropright=8 testgrid.pbm"
+invCmd "pamcut -left=7 -right=6 testgrid.pbm"
+invCmd "pamcut -croptop=16 testgrid.pbm"
+invCmd "pamcut -croptop=8 -cropbottom=8 testgrid.pbm"
+invCmd "pamcut -top=10 -bottom=9 testgrid.pbm"
 
 # pad absent
-pamcut -cropleft=1 -width=14 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 10 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcut -croptop=1  -height=16 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 11 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamcut -cropleft=1 -width=14 testgrid.pbm"
+invCmd "pamcut -croptop=1  -height=16 testgrid.pbm"
 
 # legacy style: insufficient number of positional parameters
-pamcut 5 testimg.ppm > ${test_out} || \
-  printf "Expected failure 12 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcut 5 4 testimg.ppm > ${test_out} || \
-  printf "Expected failure 13 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamcut 5 5 30 testimg.ppm > ${test_out} || \
-  printf "Expected failure 14 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamcut 5 testimg.ppm"
+invCmd "pamcut 5 4 testimg.ppm"
+invCmd "pamcut 5 5 30 testimg.ppm"
diff --git a/test/pamdepth.test b/test/pamdepth.test
index d97992a1..e938a630 100755
--- a/test/pamdepth.test
+++ b/test/pamdepth.test
@@ -24,17 +24,7 @@ pamdepth 255 testimg.ppm | cmp -s - testimg.ppm
 # Test Invalid
 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
+. ${srcdir}/test-invalid.inc
 
-pamdepth 0 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamdepth 65536 testimg.ppm > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamdepth 0 testgrid.pbm"
+invCmd "pamdepth 65536 testimg.ppm"
diff --git a/test/pamditherbw.test b/test/pamditherbw.test
index ea3e803f..76bcdbd7 100755
--- a/test/pamditherbw.test
+++ b/test/pamditherbw.test
@@ -39,71 +39,19 @@ 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} > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamditherbw -floyd -atkinson    ${test_red} > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamditherbw -dither8  -cluster3 ${test_red} > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamditherbw -cluster3 -cluster4 ${test_red} > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamditherbw -cluster3 -cluster8 ${test_red} > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamditherbw -cluster4 -cluster8 ${test_red} > ${test_out} || \
-  printf "Expected failure 6 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamditherbw -hilbert -threshold ${test_red} > ${test_out} || \
-  printf "Expected failure 7 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamditherbw -clump=8            ${test_red} > ${test_out} || \
-  printf "Expected failure 8 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamditherbw -fs -clump=8        ${test_red} > ${test_out} || \
-  printf "Expected failure 9 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamditherbw -hilbert -clump=1   ${test_red} > ${test_out} || \
-  printf "Expected failure 10 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamditherbw -th -value=-1       ${test_red} > ${test_out} || \
-  printf "Expected failure 11 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamditherbw -th -value=1.1      ${test_red} > ${test_out} || \
-  printf "Expected failure 12 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
+
+invCmd "pamditherbw -fs -atkinson       ${test_red}"
+invCmd "pamditherbw -floyd -atkinson    ${test_red}"
+invCmd "pamditherbw -dither8  -cluster3 ${test_red}"
+invCmd "pamditherbw -cluster3 -cluster4 ${test_red}"
+invCmd "pamditherbw -cluster3 -cluster8 ${test_red}"
+invCmd "pamditherbw -cluster4 -cluster8 ${test_red}"
+invCmd "pamditherbw -hilbert -threshold ${test_red}"
+invCmd "pamditherbw -clump=8            ${test_red}"
+invCmd "pamditherbw -fs -clump=8        ${test_red}"
+invCmd "pamditherbw -hilbert -clump=1   ${test_red}"
+invCmd "pamditherbw -th -value=-1       ${test_red}"
+invCmd "pamditherbw -th -value=1.1      ${test_red}"
 
 rm ${test_red}
diff --git a/test/pamfile.test b/test/pamfile.test
index 7be061ef..d605326d 100755
--- a/test/pamfile.test
+++ b/test/pamfile.test
@@ -22,25 +22,13 @@ cat testgrid.pbm testimg.ppm testgrid.pbm | pamfile -machine
 
 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 > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfile -count -machine testimg.ppm > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-head -n1 testimg.ppm | pamfile > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
+
+invCmd "pamfile -size -machine  testimg.ppm"
+invCmd "pamfile -count -machine testimg.ppm"
+
+head1_ppm=${tmpdir}/head1.ppm
+
+head -n1 testimg.ppm > ${head1_ppm}
+invCmd "pamfile  ${head1_ppm}"
+rm ${head1_ppm}
diff --git a/test/pamfind.test b/test/pamfind.test
index e7c9707f..079e35f4 100755
--- a/test/pamfind.test
+++ b/test/pamfind.test
@@ -31,34 +31,11 @@ comm -12 ${sorted0_res}  ${sorted1_res} |
 
 rm ${sorted0_res} ${sorted1_res}
 
-# Test 4
-
-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
-
 echo "Test Invalid"
 
-pamfind -color=black -target=1,1,1 testimg.ppm > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfind -target=0,0 testimg.ppm > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfind -target=0,0,0,0 testimg.ppm > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
 
-pamfind testimg.ppm > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamfind -color=black -target=1,1,1 testimg.ppm"
+invCmd "pamfind -target=0,0 testimg.ppm"
+invCmd "pamfind -target=0,0,0,0 testimg.ppm"
+invCmd "pamfind testimg.ppm"
diff --git a/test/pamfunc.test b/test/pamfunc.test
index 21f69247..b1b9edfc 100755
--- a/test/pamfunc.test
+++ b/test/pamfunc.test
@@ -84,130 +84,32 @@ pamfunc -xormask  0x1 maze.pbm | pamfunc -xormask 0x1 | cksum
 pamfunc -shiftleft  0 maze.pbm | cksum
 pamfunc -shiftright 0 maze.pbm | cksum
 
-echo "Invalid command-line argument combinations." 1>&2
-echo "Error messages should appear below the line." 1>&2
-echo "-----------------------------------------------------------" 1>&2
 
 echo "Test Invalid"
 
-test_out=${tmpdir}/test_out
-
-pamfunc -multiplier testimg.ppm > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -multiplier=-1 testimg.ppm > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -divisor testimg.ppm > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -divisor=-20 testimg.ppm > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -adder testimg.ppm > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -adder 0.5 testimg.ppm > ${test_out} || \
-  printf "Expected failure 6 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -subtractor testimg.ppm > ${test_out} || \
-  printf "Expected failure 7 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -subtractor 0.1 testimg.ppm > ${test_out} || \
-  printf "Expected failure 8 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -multiplier=1 -divisor=2 testimg.ppm > ${test_out} || \
-  printf "Expected failure 9 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -adder=2 -subtractor=3 testimg.ppm > ${test_out} || \
-  printf "Expected failure 10 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -min testimg.ppm > ${test_out} || \
-  printf "Expected failure 11 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -max testimg.ppm > ${test_out} || \
-  printf "Expected failure 12 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -andmask testimg.ppm > ${test_out} || \
-  printf "Expected failure 13 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -ormask testimg.ppm > ${test_out} || \
-  printf "Expected failure 14 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -xormask testimg.ppm > ${test_out} || \
-  printf "Expected failure 15 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -not 1 testimg.ppm > ${test_out} || \
-  printf "Expected failure 16 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -min=1 -max=2 testimg.ppm > ${test_out} || \
-  printf "Expected failure 17 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -andmask=1 -ormask=0 testimg.ppm > ${test_out} || \
-  printf "Expected failure 18 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -andmask=0xffff testimg.ppm > ${test_out} || \
-  printf "Expected failure 19 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -shiftleft testimg.ppm > ${test_out} || \
-  printf "Expected failure 20 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -shiftright testimg.ppm > ${test_out} || \
-  printf "Expected failure 21 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -changemaxval testimg.ppm > ${test_out} || \
-  printf "Expected failure 22 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -shiftleft=1 -shiftright=1 testimg.ppm > ${test_out} || \
-  printf "Expected failure 23 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamfunc -multiplier=0.5 -changemaxval=65535 testimg.ppm > ${test_out} || \
-  printf "Expected failure 24 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
+
+invCmd "pamfunc -multiplier testimg.ppm"
+invCmd "pamfunc -multiplier=-1 testimg.ppm"
+invCmd "pamfunc -divisor testimg.ppm"
+invCmd "pamfunc -divisor=-20 testimg.ppm"
+invCmd "pamfunc -adder testimg.ppm"
+invCmd "pamfunc -adder 0.5 testimg.ppm"
+invCmd "pamfunc -subtractor testimg.ppm"
+invCmd "pamfunc -subtractor 0.1 testimg.ppm"
+invCmd "pamfunc -multiplier=1 -divisor=2 testimg.ppm"
+invCmd "pamfunc -adder=2 -subtractor=3 testimg.ppm"
+invCmd "pamfunc -min testimg.ppm"
+invCmd "pamfunc -max testimg.ppm"
+invCmd "pamfunc -andmask testimg.ppm"
+invCmd "pamfunc -ormask testimg.ppm"
+invCmd "pamfunc -xormask testimg.ppm"
+invCmd "pamfunc -not 1 testimg.ppm"
+invCmd "pamfunc -min=1 -max=2 testimg.ppm"
+invCmd "pamfunc -andmask=1 -ormask=0 testimg.ppm"
+invCmd "pamfunc -andmask=0xffff testimg.ppm"
+invCmd "pamfunc -shiftleft testimg.ppm"
+invCmd "pamfunc -shiftright testimg.ppm"
+invCmd "pamfunc -changemaxval testimg.ppm"
+invCmd "pamfunc -shiftleft=1 -shiftright=1 testimg.ppm"
+invCmd "pamfunc -multiplier=0.5 -changemaxval=65535 testimg.ppm"
diff --git a/test/pamgauss.ok b/test/pamgauss.ok
index cc4d1465..98d97312 100644
--- a/test/pamgauss.ok
+++ b/test/pamgauss.ok
@@ -89,3 +89,6 @@ Expected failure 2 (no output)
 Expected failure 3 (no output)
 Expected failure 4 (no output)
 Expected failure 5 (no output)
+Expected failure 6 (no output)
+Expected failure 7 (no output)
+Expected failure 8 (no output)
diff --git a/test/pamgauss.test b/test/pamgauss.test
index b15ccbf0..34b6630a 100755
--- a/test/pamgauss.test
+++ b/test/pamgauss.test
@@ -19,35 +19,13 @@ pamgauss 3 3 -sigma=0.5 -tupletype="GRAYSCALE" | pamfile
 
 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
-
-pamgauss 3 3               > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamgauss 3 3   -sigma=0    > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamgauss 3 3   -sigma=-1.5 > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamgauss 3     -sigma=0.5  > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamgauss 3 3 3 -sigma=0.5  > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
+
+invCmd "pamgauss       -sigma=0.5 "
+invCmd "pamgauss 0 5   -sigma=0.5 "
+invCmd "pamgauss 5 0   -sigma=0.5"
+invCmd "pamgauss 3 3              "
+invCmd "pamgauss 3 3   -sigma=0   "
+invCmd "pamgauss 3 3   -sigma=-1.5"
+invCmd "pamgauss 3     -sigma=0.5 "
+invCmd "pamgauss 3 3 3 -sigma=0.5 "
diff --git a/test/pamhue.test b/test/pamhue.test
index ca7a7d82..ce148a45 100755
--- a/test/pamhue.test
+++ b/test/pamhue.test
@@ -34,15 +34,6 @@ pamhue -huechange=360 testimg.ppm | cmp -s - testimg.ppm
 
 echo "Test Invalid"
 
-tmpdir=${tmpdir:-/tmp}
-test_out=${tmpdir}/test_out
-
-echo 1>&2
-echo "Omission of mandatory argument." 1>&2
-echo "An error message should appear below the line." 1>&2
-echo "-----------------------------------------------------------" 1>&2
-
-pamhue testimg.ppm  > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
+
+invCmd "pamhue testimg.ppm "
diff --git a/test/pamrecolor.test b/test/pamrecolor.test
index 4d75f2cc..b5674776 100755
--- a/test/pamrecolor.test
+++ b/test/pamrecolor.test
@@ -16,47 +16,16 @@ echo "Test 2. Should produce 3500040755 101532 twice"
 pamrecolor --targetcolor=rgb:80/80/80 testimg.ppm | cksum
 pamrecolor --colorspace=ntsc --targetcolor=rgb:80/80/80 testimg.ppm | cksum
 
+. ${srcdir}/test-invalid.inc
 
-test_out=${tmpdir}/test_out
 truncated_file=${tmpdir}/truncated.txt
 echo P6 > ${truncated_file}
 
-echo 1>&2
-echo "Invalid command-line argument combinations." 1>&2
-echo "Error messages should appear below the line." 1>&2
-echo "-----------------------------------------------------------" 1>&2
-
-pamrecolor --targetcolor=rgb:00/11/22 \
-           --colorfile=${base1_pgm} testimg.ppm > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamrecolor --rmult=0.3  --gmult=0.3  --bmult=0.3 \
-           --colorfile=${base1_pgm} testimg.ppm > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamrecolor --colorspace=void \
-           --targetcolor=rgb:80/80/80 testimg.ppm > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamrecolor --targetcolor=vague testimg.ppm > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamrecolor --colorfile=${truncated_file} testimg.ppm > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamrecolor --rmult=0.2989 --gmult=0.5866 testimg.ppm > ${test_out} || \
-  printf "Expected failure 6 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamrecolor --targetcolor=rgb:00/11/22 --colorfile=${base_pgm} testimg.ppm"
+invCmd "pamrecolor --rmult=0.3  --gmult=0.3  --bmult=0.3 --colorfile=${base_pgm} testimg.ppm"
+invCmd "pamrecolor --colorspace=void --targetcolor=rgb:80/80/80 testimg.ppm"
+invCmd "pamrecolor --targetcolor=vague testimg.ppm"
+invCmd "pamrecolor --colorfile=${truncated_file} testimg.ppm"
+invCmd "pamrecolor --rmult=0.2989 --gmult=0.5866 testimg.ppm"
 
 rm ${base_pgm} ${truncated_file}
diff --git a/test/pamrestack.test b/test/pamrestack.test
index 776fe91b..c91830e4 100755
--- a/test/pamrestack.test
+++ b/test/pamrestack.test
@@ -58,34 +58,10 @@ pamrestack \
 test_out=${tmpdir}/test_out
 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
-
-pamrestack testgrid.pbm maze.pbm > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamrestack -abort \
-  -width=$((pixels * 2 + 1 )) maze.pbm > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamrestack -crop \
-  -width=$((pixels * 2 + 1)) maze.pbm > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamrestack -width=0 maze.pbm > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamrestack -width maze.pbm > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
+
+invCmd "pamrestack testgrid.pbm maze.pbm"
+invCmd "pamrestack -abort -width=$((pixels * 2 + 1 )) maze.pbm"
+invCmd "pamrestack -crop -width=$((pixels * 2 + 1)) maze.pbm"
+invCmd "pamrestack -width=0 maze.pbm"
+invCmd "pamrestack -width maze.pbm"
diff --git a/test/pamscale-reportonly.test b/test/pamscale-reportonly.test
index 2bf1030a..39745809 100755
--- a/test/pamscale-reportonly.test
+++ b/test/pamscale-reportonly.test
@@ -19,48 +19,13 @@ pamscale -reportonly -pixels=45000 testimg.ppm
 
 echo "Test Invalid"
 
-tmpdir=${tmpdir:-/tmp}
-test_out=${tmpdir}/test_out
+. ${srcdir}/test-invalid.inc
 
 # 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 > \
-  ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamscale -reportonly -xsize=640 -xscale=2 -yscale=3 testimg.ppm > \
-  ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamscale -reportonly -xsize=640 -ysize=400 -pixels=200000 testimg.ppm \
-  > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamscale -reportonly -xsize=640 -ysize=400 -xysize 640 400 testimg.ppm \
-  > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamscale -reportonly -xsize=640 -ysize=400 -xyfit  640 400 testimg.ppm \
-  > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamscale -reportonly -xsize=640 -ysize=400 -xyfill 640 400 testimg.ppm \
-  > ${test_out} || \
-  printf "Expected failure 6 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamscale -reportonly -xsize=640 -ysize=400 -xscale=2 testimg.ppm"
+invCmd "pamscale -reportonly -xsize=640 -xscale=2 -yscale=3 testimg.ppm"
+invCmd "pamscale -reportonly -xsize=640 -ysize=400 -pixels=200000 testimg.ppm"
+invCmd "pamscale -reportonly -xsize=640 -ysize=400 -xysize 640 400 testimg.ppm"
+invCmd "pamscale -reportonly -xsize=640 -ysize=400 -xyfit  640 400 testimg.ppm"
+invCmd "pamscale -reportonly -xsize=640 -ysize=400 -xyfill 640 400 testimg.ppm"
diff --git a/test/pamseq.test b/test/pamseq.test
index 61fbfac7..894e8d6d 100755
--- a/test/pamseq.test
+++ b/test/pamseq.test
@@ -8,35 +8,14 @@ pamseq 1 255 | cksum
 
 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
+. ${srcdir}/test-invalid.inc
 
-tmpdir=${tmpdir:-/tmp}
-test_out=${tmpdir}/test_out
-
-pamseq 1 > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamseq 0 255 > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamseq 3 0   > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamseq 1"
+invCmd "pamseq 0 255"
+invCmd "pamseq 3 0"
 
+# Tupletype string length=256
 c64="0123456789012345678901234567890123456789012345678901234567890123"
 c256=${c64}${c64}${c64}${c64}
 
-# Tupletype string length=256
-
-pamseq -tupletype="${c256}" 3 15 > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamseq -tupletype=${c256} 3 15"
diff --git a/test/pamshuffle.test b/test/pamshuffle.test
index 700631cb..371b65a5 100755
--- a/test/pamshuffle.test
+++ b/test/pamshuffle.test
@@ -46,22 +46,8 @@ rm ${out1_pam}
 test_out=${tmpdir}/test_out
 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
+. ${srcdir}/test-invalid.inc
 
-pamshuffle testimg.ppm testgrid.pbm > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamshuffle -randomseed -column testgrid.pbm > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamshuffle -randomseed=null testgrid.pbm > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamshuffle testimg.ppm testgrid.pbm"
+invCmd "pamshuffle -randomseed -column testgrid.pbm"
+invCmd "pamshuffle -randomseed=null testgrid.pbm"
diff --git a/test/pamstack.test b/test/pamstack.test
index 7c375b12..6374c4bd 100755
--- a/test/pamstack.test
+++ b/test/pamstack.test
@@ -93,33 +93,16 @@ s2=$(pamstack -firstmaxval ${std_pgm} | pamfile)
 
 test "$s0" = "$s1" && echo "true" || echo "false"
 test "$s0" = "$s2" && echo "true" || echo "false"
-  
+
 
 # Test Invalid
 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
-
-test_out=${tmpdir}/test_out
-
-pamstack testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamstack ${i1_pgm} ${std_pgm} > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
 
-pamstack -lcmmaxval -firstmaxval testgrid.pbm testgrid.pbm > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pamstack testgrid.pbm testimg.ppm"
+invCmd "pamstack ${i1_pgm} ${std_pgm}"
+invCmd "pamstack -lcmmaxval -firstmaxval testgrid.pbm testgrid.pbm"
 
-  
 rm ${i1_pgm} ${i2_pgm} ${i7_pgm} ${i31_pgm} ${std_pgm} ${max_pgm}
 
diff --git a/test/pamsumm.test b/test/pamsumm.test
index 6fef5972..eb41ee36 100755
--- a/test/pamsumm.test
+++ b/test/pamsumm.test
@@ -26,30 +26,9 @@ for type in -sum -min -max -mean
 
 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 > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamsumm -sum -max  testimg.ppm > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamsumm -mean -max testimg.ppm > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pamsumm            testimg.ppm > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
+
+invCmd "pamsumm -sum -min  testimg.ppm"
+invCmd "pamsumm -sum -max  testimg.ppm"
+invCmd "pamsumm -mean -max testimg.ppm"
+invCmd "pamsumm            testimg.ppm"
diff --git a/test/pamtable.ok b/test/pamtable.ok
index 5d69ffb7..b63a74c2 100644
--- a/test/pamtable.ok
+++ b/test/pamtable.ok
@@ -122,5 +122,4 @@ Test 8
 65535     0     0|    0     0 65535|    0     0 65535|    0 65535     0
 
 Test Invalid
-Should print: Expected failure (no output)
-Expected failure (no output)
+Expected failure 1 (no output)
diff --git a/test/pamtable.test b/test/pamtable.test
index 740b2199..d42187f9 100755
--- a/test/pamtable.test
+++ b/test/pamtable.test
@@ -46,17 +46,10 @@ for maxval in 9 10 9999 10000 65535
 
 echo "Test Invalid"
 
-test_out=${tmpdir}/test.out
+. ${srcdir}/test-invalid.inc
 
-echo 1>&2
-echo "Invalid command-line argument combinations." 1>&2
-echo "Error messages should appear below the line." 1>&2
-echo "-----------------------------------------------------------" 1>&2
+input1_pam=${tmpdir}/input1.pam
 
-echo "Should print: Expected failure (no output)"
-
-pamseq -tupletype="void" 1 1 | pamtable -tuple -hex > \
-  ${test_out} || \
-  printf "Expected failure "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+pamseq -tupletype="void" 1 1 > ${input1_pam}
+invCmd "pamtable -tuple -hex ${input1_pam}"
+rm ${input1_pam}
diff --git a/test/pbmclean.test b/test/pbmclean.test
index 9d59a5a6..64ed6df0 100755
--- a/test/pbmclean.test
+++ b/test/pbmclean.test
@@ -37,17 +37,8 @@ rm ${sheet_pbm}
 
 echo "Test Invalid"
 
-test_out=${tmpdir}/test_out
-
-echo 1>&2
-echo "Invalid command-line argument combination." 1>&2
-echo "An error message should appear below the line." 1>&2
-echo "-----------------------------------------------------------" 1>&2
+. ${srcdir}/test-invalid.inc
 
 # overspecification
-pbmclean -black -white -min=1 -extended testgrid.pbm > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
+invCmd "pbmclean -black -white -min=1 -extended testgrid.pbm"
 # note that without -extended the above is valid.
diff --git a/test/pbmmake.test b/test/pbmmake.test
index 52765747..32153f95 100755
--- a/test/pbmmake.test
+++ b/test/pbmmake.test
@@ -20,54 +20,17 @@ for size in 8 13 18 23 28 33 38 43 48 53 58 63 68 73 78 83 88 93 98
   ( pbmmake -w ${size} ${size} ;
     pbmmake -b ${size} ${size} ;
     pbmmake -g ${size} ${size} ) | cksum
-  done
+done
 
 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
-
-pbmmake -b -w -plain 1 1 > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmmake -b -g -plain 1 1 > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmmake -white -gray -plain 1 1 > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmmake -white -plain   > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmmake -white -plain 1 > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmmake -white -plain 1 0 > ${test_out} || \
-  printf "Expected failure 6 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmmake -white -plain 0 1 > ${test_out} || \
-  printf "Expected failure 7 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
 
-pbmmake -white -plain 1 1 1 > ${test_out} || \
-  printf "Expected failure 8 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pbmmake -b -w -plain 1 1"
+invCmd "pbmmake -b -g -plain 1 1"
+invCmd "pbmmake -white -gray -plain 1 1"
+invCmd "pbmmake -white -plain"
+invCmd "pbmmake -white -plain 1"
+invCmd "pbmmake -white -plain 1 0"
+invCmd "pbmmake -white -plain 0 1"
+invCmd 'pbmmake -white -plain 1 1 1'
diff --git a/test/pbmnoise-parameters.ok b/test/pbmnoise-parameters.ok
index d430f0f1..640b438d 100644
--- a/test/pbmnoise-parameters.ok
+++ b/test/pbmnoise-parameters.ok
@@ -16,7 +16,6 @@ Expected failure 14 (no output)
 Expected failure 15 (no output)
 Expected failure 16 (no output)
 Expected failure 17 (no output)
-Expected failure 17 (no output)
 Expected failure 18 (no output)
 Expected failure 19 (no output)
 Expected failure 20 (no output)
@@ -24,3 +23,6 @@ Expected failure 21 (no output)
 Expected failure 22 (no output)
 Expected failure 23 (no output)
 Expected failure 24 (no output)
+Expected failure 25 (no output)
+Expected failure 26 (no output)
+Expected failure 27 (no output)
diff --git a/test/pbmnoise-parameters.test b/test/pbmnoise-parameters.test
index 0d9319cc..d0e04ebf 100755
--- a/test/pbmnoise-parameters.test
+++ b/test/pbmnoise-parameters.test
@@ -2,142 +2,42 @@
 # This script tests: pbmnoise
 # Also requires:
 
-echo "Invalid command-line argument combinations." 1>&2
-echo "Error messages should appear below the line." 1>&2
-echo "-----------------------------------------------------------" 1>&2
-
 echo "Test Invalid"
 
-test_out=${tmpdir}/test_out
+. ${srcdir}/test-invalid.inc
 
 # Invalid -ratio arguments
 
-pbmnoise -ratio       100 100 > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise -ratio 0     1  100 > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise -ratio=1.1   100 100 > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-  
-pbmnoise -ratio=-1    100 100 > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise -ratio=half  100 100 > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise -ratio=0/1/1 100 100 > ${test_out} || \
-  printf "Expected failure 6 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise -ratio=-1/2  100 100 > ${test_out} || \
-  printf "Expected failure 7 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise -ratio=1/0   100 100 > ${test_out} || \
-  printf "Expected failure 8 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise -ratio=/2    100 100 > ${test_out} || \
-  printf "Expected failure 9 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise -ratio=4/2   100 100 > ${test_out} || \
-  printf "Expected failure 10 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise -ratio=6/    100 100 > ${test_out} || \
-  printf "Expected failure 11 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise -ratio=1.0/2.0 100 100 > ${test_out} || \
-  printf "Expected failure 12 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-# denominator must be power of 2  
-pbmnoise -ratio=3/9   100 100 > ${test_out} || \
-  printf "Expected failure 13 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise -ratio=a/2   100 100 > ${test_out} || \
-  printf "Expected failure 14 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-
-pbmnoise -ratio=2/a  100 100 > ${test_out} || \
-        printf "Expected failure 15 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise -ratio=1/-2  100 100 > ${test_out} || \
-        printf "Expected failure 16 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pbmnoise -ratio       100 100"
+invCmd "pbmnoise -ratio 0     1  100"
+invCmd "pbmnoise -ratio=1.1   100 100"
+invCmd "pbmnoise -ratio=-1    100 100"
+invCmd "pbmnoise -ratio=half  100 100"
+invCmd "pbmnoise -ratio=0/1/1 100 100"
+invCmd "pbmnoise -ratio=-1/2  100 100"
+invCmd "pbmnoise -ratio=1/0   100 100"
+invCmd "pbmnoise -ratio=/2    100 100"
+invCmd "pbmnoise -ratio=4/2   100 100"
+invCmd "pbmnoise -ratio=6/    100 100"
+invCmd "pbmnoise -ratio=1.0/2.0 100 100"
+
+# denominator must be power of 2
+invCmd "pbmnoise -ratio=3/9  100 100"
+invCmd "pbmnoise -ratio=a/2  100 100"
+invCmd "pbmnoise -ratio=2/a  100 100"
+invCmd "pbmnoise -ratio=1/-2 100 100"
 
 # Denominator must be 65536 or less
-pbmnoise -ratio=1/65537 100 100 > ${test_out} || \
-  printf "Expected failure 17 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise -ratio=1/131072 100 100 > ${test_out} || \
-  printf "Expected failure 17 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise -endian=large 100 100 > ${test_out} || \
-  printf "Expected failure 18 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise -randomseed 100 100 > ${test_out} || \
-  printf "Expected failure 19 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise -randomseed=-1 100 100 > ${test_out} || \
-  printf "Expected failure 20 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise -randomseed=0.1 100 100 > ${test_out} || \
-  printf "Expected failure 21 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise > ${test_out} || \
-  printf "Expected failure 22 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise 100 > ${test_out} || \
-  printf "Expected failure 23 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmnoise 100 200 300 > ${test_out} || \
-  printf "Expected failure 24 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-  
+invCmd "pbmnoise -ratio=1/65537 100 100"
+invCmd "pbmnoise -ratio=1/131072 100 100"
+
+# Other
+invCmd "pbmnoise"
+invCmd "pbmnoise 100"
+invCmd "pbmnoise 100 0"
+invCmd "pbmnoise 0 100"
+invCmd "pbmnoise 100 200 300"
+invCmd "pbmnoise -endian=large 100 100"
+invCmd "pbmnoise -randomseed 100 100"
+invCmd "pbmnoise -randomseed=-1 100 100"
+invCmd "pbmnoise -randomseed=0.1 100 100"
diff --git a/test/pbmpage.test b/test/pbmpage.test
index ee3dc25c..9cb46e22 100755
--- a/test/pbmpage.test
+++ b/test/pbmpage.test
@@ -11,25 +11,9 @@ pbmpage -a4 2 | cksum
 
 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
+. ${srcdir}/test-invalid.inc
 
-tmpdir=${tmpdir:-/tmp}
-test_out=${tmpdir}/test_out
+invCmd "pbmpage -a3 1"
+invCmd "pbmpage 0"
+invCmd "pbmpage 4"
 
-pbmpage -a3 1 > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmpage 0 > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmpage 4 > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
diff --git a/test/pbmpscale.test b/test/pbmpscale.test
index 65ab6467..b99561f6 100755
--- a/test/pbmpscale.test
+++ b/test/pbmpscale.test
@@ -25,27 +25,10 @@ pbmtext -nomargin "9" | pbmpscale 9 | cksum
 echo "Test 10. Should print 3327221668 2111"
 pbmtext -nomargin "10" | pbmpscale 10 | cksum
 
-tmpdir=${tmpdir:-/tmp}
-test_out=${tmpdir}/test_out
-
 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
-
-pbmpscale testgrid.pbm > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmpscale 0 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
 
-pbmpscale 2 3 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pbmpscale testgrid.pbm"
+invCmd "pbmpscale 0 testgrid.pbm"
+invCmd "pbmpscale 2 3 testgrid.pbm"
diff --git a/test/pbmtopgm.test b/test/pbmtopgm.test
index f2c5cf1f..19378bb6 100755
--- a/test/pbmtopgm.test
+++ b/test/pbmtopgm.test
@@ -9,30 +9,9 @@ pbmtopgm -plain 1 1 testgrid.pbm
 
 echo "Test Invalid"
 
-tmpdir=${tmpdir:-/tmp}
-test_out=${tmpdir}/test_out
+. ${srcdir}/test-invalid.inc
 
-echo 1>&2
-echo "Invalid command-line argument combinations." 1>&2
-echo "Error messages should appear below the line." 1>&2
-echo "-----------------------------------------------------------" 1>&2
-
-pbmtopgm 5 0 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmtopgm 0 9 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmtopgm 15 5 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pbmtopgm 5 17 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pbmtopgm 5 0 testgrid.pbm"
+invCmd "pbmtopgm 0 9 testgrid.pbm"
+invCmd "pbmtopgm 15 5 testgrid.pbm"
+invCmd "pbmtopgm 5 17 testgrid.pbm"
diff --git a/test/pgmhist.test b/test/pgmhist.test
index a47ab71e..5c458a57 100755
--- a/test/pgmhist.test
+++ b/test/pgmhist.test
@@ -26,30 +26,9 @@ pgmramp -lr 256 1 | pgmhist -machine -decile   | \
 
 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 > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pgmhist -median   -decile   testgrid.pbm > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pgmhist -quartile -decile   testgrid.pbm > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pgmhist testimg.ppm > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
+
+invCmd "pgmhist -median   -quartile testgrid.pbm"
+invCmd "pgmhist -median   -decile   testgrid.pbm"
+invCmd "pgmhist -quartile -decile   testgrid.pbm"
+invCmd "pgmhist testimg.ppm"
diff --git a/test/pgmmake.ok b/test/pgmmake.ok
index ac9b968c..9460162d 100644
--- a/test/pgmmake.ok
+++ b/test/pgmmake.ok
@@ -1,4 +1,16 @@
 Test 1
+P2
+1 1
+255
+0
+P2
+1 1
+255
+255
+P2
+1 1
+2
+1
 3662611538 2513
 3109612402 5012
 Test Invalid
@@ -10,3 +22,4 @@ Expected failure 5 (no output)
 Expected failure 6 (no output)
 Expected failure 7 (no output)
 Expected failure 8 (no output)
+Expected failure 9 (no output)
diff --git a/test/pgmmake.test b/test/pgmmake.test
index 80997d07..d8e248d4 100755
--- a/test/pgmmake.test
+++ b/test/pgmmake.test
@@ -4,56 +4,22 @@
 
 echo "Test 1"
 
+pgmmake -plain 0 1 1
+pgmmake -plain 1 1 1
+pgmmake -plain -maxval=2 0.5 1 1
 pgmmake 1 50 50 | cksum
 pgmmake .2 50 100 -maxval=5 | cksum
 
-
 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
-
-pgmmake 100  5 5 > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pgmmake 1.01 5 5 > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pgmmake .5   5   > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pgmmake .5       > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pgmmake -maxval=5        5 5 > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pgmmake -maxval=0     .5 5 5 > ${test_out} || \
-  printf "Expected failure 6 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pgmmake -maxval=-1    .5 5 5 > ${test_out} || \
-  printf "Expected failure 7 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pgmmake -maxval=65536 .5 5 5 > ${test_out} || \
-  printf "Expected failure 8 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
+
+invCmd "pgmmake"
+invCmd "pgmmake 100  5 5"
+invCmd "pgmmake 1.01 5 5"
+invCmd "pgmmake .5   5"
+invCmd "pgmmake .5"
+invCmd "pgmmake -maxval=5        5 5"
+invCmd "pgmmake -maxval=0     .5 5 5"
+invCmd "pgmmake -maxval=-1    .5 5 5"
+invCmd "pgmmake -maxval=65536 .5 5 5"
diff --git a/test/pgmnoise-parameters.ok b/test/pgmnoise-parameters.ok
index 10a05cfa..1e321f00 100644
--- a/test/pgmnoise-parameters.ok
+++ b/test/pgmnoise-parameters.ok
@@ -1,5 +1,7 @@
+Test Invalid
 Expected failure 1 (no output)
 Expected failure 2 (no output)
 Expected failure 3 (no output)
 Expected failure 4 (no output)
 Expected failure 5 (no output)
+Expected failure 6 (no output)
diff --git a/test/pgmnoise-parameters.test b/test/pgmnoise-parameters.test
index 79c068d8..871aacf9 100755
--- a/test/pgmnoise-parameters.test
+++ b/test/pgmnoise-parameters.test
@@ -2,35 +2,13 @@
 # This script tests: pgmnoise
 # Also requires:
 
-tmpdir=${tmpdir:-/tmp}
-test_out=${tmpdir}/test_out
+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
+. ${srcdir}/test-invalid.inc
 
-pgmnoise -maxval=255  -randomseed=1 > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pgmnoise 100 -randomseed=1 > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pgmnoise 100 0 -randomseed=1 > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pgmnoise 0 100 -randomseed=1 > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pgmnoise 100 100 100 -randomseed=1 > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pgmnoise"
+invCmd "pgmnoise -maxval=255  -randomseed=1"
+invCmd "pgmnoise 100 -randomseed=1"
+invCmd "pgmnoise 100 0 -randomseed=1"
+invCmd "pgmnoise 0 100 -randomseed=1"
+invCmd "pgmnoise 100 100 100 -randomseed=1"
diff --git a/test/pgmramp.ok b/test/pgmramp.ok
index 69e3a6e5..71f92b13 100644
--- a/test/pgmramp.ok
+++ b/test/pgmramp.ok
@@ -42,8 +42,10 @@ Test 2
 Test 3
 886972785 131087
 Test Invalid
-Expected failure: -lr -tb (no output)
-Expected failure: -lr -rectangle (no output)
-Expected failure: -rectangle -ellipse (no output)
-Expected failure: insufficient parameters (no output)
-Expected failure: excessive parameters (no output)
+Expected failure 1 (no output)
+Expected failure 2 (no output)
+Expected failure 3 (no output)
+Expected failure 4 (no output)
+Expected failure 5 (no output)
+Expected failure 6 (no output)
+Expected failure 7 (no output)
diff --git a/test/pgmramp.test b/test/pgmramp.test
index d2e34885..84fe02ca 100755
--- a/test/pgmramp.test
+++ b/test/pgmramp.test
@@ -21,27 +21,16 @@ pgmramp -diagonal -maxval=510 256 256 | cksum
 
 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
+. ${srcdir}/test-invalid.inc
 
-tmpdir=${tmpdir:-/tmp}
-test_out=${tmpdir}/test_out
 
 for combination in "-lr -tb" "-lr -rectangle" "-rectangle -ellipse"
-do pgmramp $combination 10 10 > ${test_out} || \
-  printf "Expected failure: $combination "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-done
+  do
+    invCmd "pgmramp ${combination} 10 10"
+  done
 
-pgmramp -lr     1 > ${test_out} || \
-  printf "Expected failure: insufficient parameters "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pgmramp -lr 10 0"
+invCmd "pgmramp -lr 0 10"
+invCmd "pgmramp -lr 1"
+invCmd "pgmramp -tb 1 1 1"
 
-pgmramp -tb 1 1 1 > ${test_out} || \
-  printf "Expected failure: excessive parameters "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
diff --git a/test/pnmcat.test b/test/pnmcat.test
index 02fefd38..8779638b 100755
--- a/test/pnmcat.test
+++ b/test/pnmcat.test
@@ -59,7 +59,7 @@ cat ${diag_pgm} | pnmcat -tb -plain | sed 's/ *$//'
 
 rm ${diag_pgm}
 
-pgmramp -diag 8 8 -maxval 7 | ppmtoppm > ${diag_ppm} 
+pgmramp -diag 8 8 -maxval 7 | ppmtoppm > ${diag_ppm}
 
 echo "Test 7.  Should print 2097565808 394 twice"
 pnmcat -lr -black ${diag_ppm} ${diag_ppm} | tee ${diag2lr_ppm} | cksum
@@ -70,7 +70,7 @@ pnmcat -tb ${diag_ppm} ${diag_ppm} | tee ${diag2tb_ppm} | cksum
 
 echo "Test 9.  Should print 4288335051 586 three times"
 pnmcat -lr ${diag_ppm} ${diag_ppm} ${diag_ppm} | cksum
-pnmcat -lr ${diag_ppm}  ${diag2lr_ppm} | cksum 
+pnmcat -lr ${diag_ppm}  ${diag2lr_ppm} | cksum
 cat ${diag2lr_ppm} | pnmcat -lr - ${diag_ppm} | cksum
 
 echo "Test 10.  Should print 642720605 586 three times"
@@ -100,82 +100,30 @@ rm ${diag_ppm}
 
 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
+. ${srcdir}/test-invalid.inc
 
 # direction not specified
-pnmcat testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pnmcat testgrid.pbm testimg.ppm"
 
 # both directions specified
-pnmcat -topbottom -leftright testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pnmcat -topbottom -leftright testgrid.pbm testimg.ppm"
 
 # both pad colors specified
-pnmcat -topbottom -white -black testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pnmcat -topbottom -white -black testgrid.pbm testimg.ppm"
 
 # justification parameters overspecified
-pnmcat -lr -jtop -jbottom testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmcat -lr -jtop -jcenter testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmcat -lr -jcenter -jbottom testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 6 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmcat -tb -jleft -jright testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 7 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmcat -tb -jleft -jcenter testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 8 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmcat -tb -jcenter -jright testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 9 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pnmcat -lr -jtop -jbottom testgrid.pbm testimg.ppm"
+invCmd "pnmcat -lr -jtop -jcenter testgrid.pbm testimg.ppm"
+invCmd "pnmcat -lr -jcenter -jbottom testgrid.pbm testimg.ppm"
+invCmd "pnmcat -tb -jleft -jright testgrid.pbm testimg.ppm"
+invCmd "pnmcat -tb -jleft -jcenter testgrid.pbm testimg.ppm"
+invCmd "pnmcat -tb -jcenter -jright testgrid.pbm testimg.ppm"
 
 # justification parameter in the wrong direction
-pnmcat -lr -jleft    testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 10 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmcat -lr -jright   testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 11 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmcat -tb -jtop     testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 12 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmcat -tb -jbottom  testgrid.pbm testimg.ppm > ${test_out} || \
-  printf "Expected failure 13 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pnmcat -lr -jleft    testgrid.pbm testimg.ppm"
+invCmd "pnmcat -lr -jright   testgrid.pbm testimg.ppm"
+invCmd "pnmcat -tb -jtop     testgrid.pbm testimg.ppm"
+invCmd "pnmcat -tb -jbottom  testgrid.pbm testimg.ppm"
 
 # more than one input image from standard input
 cat testgrid.pbm | pnmcat -lr - - testimg.ppm > ${test_out} || \
diff --git a/test/pnmcolormap.test b/test/pnmcolormap.test
index b34a0360..953dece3 100755
--- a/test/pnmcolormap.test
+++ b/test/pnmcolormap.test
@@ -32,49 +32,16 @@ pnmcolormap -center 64 testimg.ppm | cmp -s ${map} - && echo ok || echo bad
 pnmcolormap -spreadbrightness 64 testimg.ppm | cmp -s ${map} - && echo ok || echo bad
 pnmcolormap -splitpixelct 64 testimg.ppm | cmp -s ${map} - && echo ok || echo bad
 rm ${map}
+
 echo
 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
-
-pnmcolormap 0 testimg.ppm   > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmcolormap -1 testimg.ppm  > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmcolormap 0.1 testimg.ppm > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmcolormap -center -meancolor 16 testimg.ppm    > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmcolormap -center -meanpixel 16 testimg.ppm    > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmcolormap -meancolor -meanpixel 16 testimg.ppm > ${test_out} || \
-  printf "Expected failure 6 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
 
-pnmcolormap -spreadbrightness -spreadluminosity 16 \
-  testimg.ppm > ${test_out} || \
-  printf "Expected failure 7 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "pnmcolormap 0 testimg.ppm  "
+invCmd "pnmcolormap -1 testimg.ppm "
+invCmd "pnmcolormap 0.1 testimg.ppm"
+invCmd "pnmcolormap -center -meancolor 16 testimg.ppm   "
+invCmd "pnmcolormap -center -meanpixel 16 testimg.ppm   "
+invCmd "pnmcolormap -meancolor -meanpixel 16 testimg.ppm"
+invCmd "pnmcolormap -spreadbrightness -spreadluminosity 16 testimg.ppm"
diff --git a/test/pnmindex.ok b/test/pnmindex.ok
index 15d01639..6155428d 100644
--- a/test/pnmindex.ok
+++ b/test/pnmindex.ok
@@ -7,12 +7,18 @@ Test 3. Should print 3099638253 5290
 3099638253 5290
 Test 4. Should print 1397700642 3160
 1397700642 3160
-Test 5. Should print 2303488589 28514
-2303488589 28514
-Test 6. Should print 1706277976 100455
-1706277976 100455
-Test 7. Should print 801388440 100455
+Test 5. Should print 243472565 28514
+243472565 28514
+Test 6. Should print 801388440 100455
 801388440 100455
+Test 7. Should print 256 twice
+256
+256
+Test 8. Should print 100 twice
+100
+100
+Test 9. Should print match
+match
 Test Invalid
 Expected failure 1 (no output)
 Expected failure 2 (no output)
diff --git a/test/pnmindex.test b/test/pnmindex.test
index 51e61532..174f60bd 100755
--- a/test/pnmindex.test
+++ b/test/pnmindex.test
@@ -1,7 +1,10 @@
 #! /bin/sh
 # This script tests: pnmindex
 # Also requires: pamcat pamscale pbmtext pnmcolormap pnmindex
-# Also requires: pnminvert pnmquant pnmremap 
+# Also requires: pnminvert pnmquant pnmremap
+
+tmpdir=${tmpdir:-/tmp}
+pnmindex256_ppm=${tmpdir}/pnmindex256.ppm
 
 echo "Test 1. Should print 3391481002 889"
 pnmindex maze.pbm | cksum
@@ -17,44 +20,41 @@ echo "Test 4. Should print 1397700642 3160"
 pnmindex -size 20 -across=3 testgrid.pbm testgrid.pbm testgrid.pbm \
          testgrid.pbm testgrid.pbm testgrid.pbm | cksum
 
-echo "Test 5. Should print 2303488589 28514"
-pnmindex testimg.ppm | cksum
-
-echo "Test 6. Should print 1706277976 100455"
-pnmindex -size 50 -across=2 testimg.ppm testimg.ppm testimg.ppm \
-         testimg.ppm testimg.ppm testimg.ppm | cksum
+echo "Test 5. Should print 243472565 28514"
+pnmindex -noquant testimg.ppm | cksum
 
-echo "Test 7. Should print 801388440 100455"
+echo "Test 6. Should print 801388440 100455"
 pnmindex -size 50 -across=2 -noquant testimg.ppm testimg.ppm testimg.ppm \
-         testimg.ppm testimg.ppm testimg.ppm | cksum
+         testimg.ppm testimg.ppm testimg.ppm | tee ${pnmindex256_ppm} | cksum
+
+echo "Test 7. Should print 256 twice"
+pnmindex testimg.ppm | ppmhist -nomap -noheader | wc -l
+pnmindex -colors 256 testimg.ppm | ppmhist -nomap -noheader | wc -l
+
+echo "Test 8. Should print 100 twice"
+pnmindex -colors 100 testimg.ppm | ppmhist -nomap -noheader | wc -l
+pnmindex -colors 100 testimg.ppm testimg.ppm | ppmhist -nomap -noheader | wc -l
+
+
+echo "Test 9. Should print match"
+pnmindex -size 50 -across=2 -quant -colors=256 testimg.ppm testimg.ppm testimg.ppm \
+         testimg.ppm testimg.ppm testimg.ppm |\
+    pnmpsnr -rgb -target1=41.31 -target2=40.76 -target3=40.71 ${pnmindex256_ppm} -
 
 
 echo "Test Invalid"
 
-test_out=${tmpdir}/test_out
-n=1
-
-# define function
-invalidCmd () { $1 > ${test_out} && printf "Unexpected success $n " || \
-  printf "Expected failure $n "
-  test -s ${test_out} && echo "(unexpected output)" || echo "(no output)"
-  rm -f ${test_out}
-  n=$(($n + 1)); }
-
-echo 1>&2
-echo "Invalid command-line arguments." 1>&2
-echo "Error messages should appear below the line." 1>&2
-echo "-----------------------------------------------------------" 1>&2
-
-invalidCmd "pnmindex -size -1 testgrid.pbm"
-invalidCmd "pnmindex -size  0 testgrid.pbm"
-invalidCmd "pnmindex -size    testgrid.pbm"
-invalidCmd "pnmindex -across -1 testgrid.pbm"
-invalidCmd "pnmindex -across  0 testgrid.pbm"
-invalidCmd "pnmindex -across    testgrid.pbm"
-invalidCmd "pnmindex -colors -1 testgrid.pbm"
-invalidCmd "pnmindex -colors  0 testgrid.pbm"
-invalidCmd "pnmindex -colors    testgrid.pbm"
-invalidCmd "pnmindex -quant -noquant testgrid.pbm"
-invalidCmd "pnmindex -colors 100 -noquant testgrid.pbm"
-invalidCmd "pnmindex"
+. ${srcdir}/test-invalid.inc
+
+invCmd "pnmindex -size -1 testgrid.pbm"
+invCmd "pnmindex -size  0 testgrid.pbm"
+invCmd "pnmindex -size    testgrid.pbm"
+invCmd "pnmindex -across -1 testgrid.pbm"
+invCmd "pnmindex -across  0 testgrid.pbm"
+invCmd "pnmindex -across    testgrid.pbm"
+invCmd "pnmindex -colors -1 testgrid.pbm"
+invCmd "pnmindex -colors  0 testgrid.pbm"
+invCmd "pnmindex -colors    testgrid.pbm"
+invCmd "pnmindex -quant -noquant testgrid.pbm"
+invCmd "pnmindex -colors 100 -noquant testgrid.pbm"
+invCmd "pnmindex"
diff --git a/test/pnmpsnr.test b/test/pnmpsnr.test
index efabe9aa..6ea05aed 100755
--- a/test/pnmpsnr.test
+++ b/test/pnmpsnr.test
@@ -27,32 +27,11 @@ pnmpsnr  testimg.ppm  testimg.ppm -target1=1000 -target2=1000 -target3=1000
 
 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}     > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmpsnr ${b_pbm}                       > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmpsnr ${b_pbm} ${w_pbm} -target1=100 > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmpsnr                   -machine     > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
+
+invCmd "pnmpsnr ${b_pbm} ${w_pbm} ${b_pbm}    "
+invCmd "pnmpsnr ${b_pbm}                      "
+invCmd "pnmpsnr ${b_pbm} ${w_pbm} -target1=100"
+invCmd "pnmpsnr                   -machine    "
 
 rm ${b_pbm} ${w_pbm}
diff --git a/test/pnmtile.test b/test/pnmtile.test
index 74bae013..35addbec 100755
--- a/test/pnmtile.test
+++ b/test/pnmtile.test
@@ -21,29 +21,9 @@ echo ${PIPESTATUS[@]} ":" $?
 
 rm ${testimg2_ppm} ${testimg4_ppm}
 
-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
-
-pnmtile 100 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmtile 100 0 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmtile 0 100 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-pnmtile 100 100 100 testgrid.pbm > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
+
+invCmd "pnmtile 100 testgrid.pbm"
+invCmd "pnmtile 100 0 testgrid.pbm"
+invCmd "pnmtile 0 100 testgrid.pbm"
+invCmd "pnmtile 100 100 100 testgrid.pbm"
diff --git a/test/ppmbrighten.ok b/test/ppmbrighten.ok
index 3895dbd0..95c90d24 100644
--- a/test/ppmbrighten.ok
+++ b/test/ppmbrighten.ok
@@ -4,8 +4,6 @@ Test 2: Should print 295150171 101484
 295150171 101484
 Test 3: Should print 1
 1
-Test Error: Should print 1 four times
-1
-1
-1
-1
+Test Invalid
+Expected failure 1 (no output)
+Expected failure 2 (no output)
diff --git a/test/ppmbrighten.test b/test/ppmbrighten.test
index e346d1d0..8ae1d744 100755
--- a/test/ppmbrighten.test
+++ b/test/ppmbrighten.test
@@ -1,6 +1,6 @@
 #! /bin/sh
 # This script tests: ppmbrighten
-# Also requires: pnmnorm pambrighten pamsumm 
+# Also requires: pnmnorm pambrighten pamsumm
 
 # Failure message
 ## Ppmbrighten is sensitive to subtle differences in floating point math.
@@ -20,22 +20,11 @@ echo "Test 3: Should print 1"
 ppmbrighten -v 100 -normalize testimg.ppm | pamsumm --mean | \
  awk '{print ($NF > 132.0) && ($NF < 132.2)}'
 
-echo "Invalid command-line argument combinations." 1>&2
-echo "Error messages should appear below the line." 1>&2
-echo "-----------------------------------------------------------" 1>&2
 
-echo "Test Error: Should print 1 four times"
+echo "Test Invalid"
 
-tmpdir=${tmpdir:-/tmp}
-output_ppm=${tmpdir}/output.ppm
+. ${srcdir}/test-invalid.inc
 
-pambrighten -v -120 testimg.ppm > ${output_ppm}
-echo $?
-test -s ${output_ppm}
-echo $?
-pambrighten -s -120 testimg.ppm > ${output_ppm}
-echo $?
-test -s ${output_ppm}
-echo $?
+invCmd "pambrighten -v -120 testimg.ppm"
+invCmd "pambrighten -s -120 testimg.ppm"
 
-rm ${output_ppm}
diff --git a/test/ppmforge-parameters.test b/test/ppmforge-parameters.test
index ba436bf0..0525e7af 100755
--- a/test/ppmforge-parameters.test
+++ b/test/ppmforge-parameters.test
@@ -5,61 +5,31 @@
 echo "Test 1: Should print 256 256"
 
 # Default size is 256 256
-ppmforge -night | pamfile -size
+ppmforge -night -seed=1 | pamfile -size
 
 echo "Test 2: Should print 40 30"
 
 # Width is adjusted if not even
 # becomes 40 in this case
-ppmforge -night -width=39 -height=30 | pamfile -size
+ppmforge -night -seed=1 -width=39 -height=30 | pamfile -size
 
 echo "Test 3: Should print 90 90"
 
 # Width is adjusted if smaller than height
 # brought up to 90 in this case
-ppmforge -night -width=80 -height=90 | pamfile -size
+ppmforge -night -seed=1 -width=80 -height=90 | pamfile -size
 
 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
+. ${srcdir}/test-invalid.inc
 
-ppmforge -night  -dimension=0  > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmforge  -dimension=10  > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmforge  -dimension=-1  > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmforge -clouds -mesh=1.99    > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmforge -clouds -power=0      > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmforge         -ice=-1       > ${test_out} || \
-  printf "Expected failure 6 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmforge         -glaciers=-1  > ${test_out} || \
-  printf "Expected failure 7 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "ppmforge -seed=0 -night -dimension=0"
+invCmd "ppmforge -seed=0 -dimension=10"
+invCmd "ppmforge -seed=0 -dimension=-1"
+invCmd "ppmforge -seed=0 -clouds -mesh=1.99"
+invCmd "ppmforge -seed=0 -clouds -power=0"
+invCmd "ppmforge -seed=0 -ice=-1"
+invCmd "ppmforge -seed=0 -glaciers=-1"
diff --git a/test/ppmhist.test b/test/ppmhist.test
index 27ae9cea..1e814eb7 100755
--- a/test/ppmhist.test
+++ b/test/ppmhist.test
@@ -27,25 +27,8 @@ ppmpat -madras --color=rgb:00/00/00,rgb:31/58/a3,rgb:ff/ff/ff 25 25 | \
 
 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 > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmhist -hexcolor -map   testimg.ppm > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmhist -float    -map   testimg.ppm > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
+
+invCmd "ppmhist -hexcolor -float testimg.ppm"
+invCmd "ppmhist -hexcolor -map   testimg.ppm"
+invCmd "ppmhist -float    -map   testimg.ppm"
diff --git a/test/ppmmake.ok b/test/ppmmake.ok
index 0231874f..e365bd9e 100644
--- a/test/ppmmake.ok
+++ b/test/ppmmake.ok
@@ -1,6 +1,14 @@
 Test 1
+P3
+1 1
+5
+0 0 0
+P3
+1 1
+65535
+65535 65535 65535
 2477651508 15012
-4294967295 0
+135932096 23
 2378991101 7513
 Test Invalid
 Expected failure 1 (no output)
diff --git a/test/ppmmake.test b/test/ppmmake.test
index fb7bf74a..295e0bf4 100755
--- a/test/ppmmake.test
+++ b/test/ppmmake.test
@@ -4,66 +4,24 @@
 
 echo "Test 1"
 
-ppmmake rgb:ff/80/80 50 100 -maxval=5 | cksum
-ppmmake rgbi:0.5/1.0/0 2   | cksum
+ppmmake -maxval=5 -plain rgb:00/00/00 1 1
+ppmmake -maxval=65535 -plain rgb:ff/ff/ff 1 1
+ppmmake -maxval=5 rgb:ff/80/80 50 100 | cksum
+ppmmake rgbi:0.5/1.0/0 2 2 | cksum
 ppmmake red 50 50  | cksum
 
 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  > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmmake rgb:ff/ff/00  2    > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmmake rgbi:1.1/0/0  2 2  > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmmake rgbi:1.0/.5   2 2  > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmmake rainbow       2 2  > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmmake               2 2  > ${test_out} || \
-  printf "Expected failure 6 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmmake blue -maxval=0 2 2  > ${test_out} || \
-  printf "Expected failure 7 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmmake blue -maxval=-1 2 2  > ${test_out} || \
-  printf "Expected failure 8 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmmake blue -maxval=65536 2 2  > ${test_out} || \
-  printf "Expected failure 9 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-RGBDEF=/dev/null ppmmake red 2 2 > ${test_out} || \
-  printf "Expected failure 10 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
+
+invCmd "ppmmake rgb:gg/00/00  2 2"
+invCmd "ppmmake rgb:ff/ff/00  2"
+invCmd "ppmmake rgbi:1.1/0/0  2 2"
+invCmd "ppmmake rgbi:1.0/.5   2 2"
+invCmd "ppmmake rainbow       2 2"
+invCmd "ppmmake               2 2"
+invCmd "ppmmake blue -maxval=0 2 2"
+invCmd "ppmmake blue -maxval=-1 2 2"
+invCmd "ppmmake blue -maxval=65536 2 2"
+export  RGBDEF=/dev/null
+invCmd "ppmmake red 2 2"
diff --git a/test/ppmpat.test b/test/ppmpat.test
index 48c2460f..00f8421e 100755
--- a/test/ppmpat.test
+++ b/test/ppmpat.test
@@ -41,58 +41,17 @@ ppmpat -argyle2 --color=rgb:00/00/00,rgb:ff/80/80,rgb:e0/e0/e0 12 18 | cksum
 
 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 > ${test_out} || \
-  printf "Expected failure 1 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -madras -tartan 10 10 > ${test_out} || \
-  printf "Expected failure 2 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -poles -squig 10 10 > ${test_out} || \
-  printf "Expected failure 3 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -camo -anticamo 10 10 > ${test_out} || \
-  printf "Expected failure 4 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -argyle1 -argyle2 10 10 > ${test_out} || \
-  printf "Expected failure 5 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat 10 10 > ${test_out} || \
-  printf "Expected failure 6 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -g2 10 > ${test_out} || \
-  printf "Expected failure 7 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -g2 10 10 10 > ${test_out} || \
-  printf "Expected failure 8 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -g2 10 > ${test_out} || \
-  printf "Expected failure 9 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+. ${srcdir}/test-invalid.inc
+
+invCmd "ppmpat -g2 -g3 10 10"
+invCmd "ppmpat -madras -tartan 10 10"
+invCmd "ppmpat -poles -squig 10 10"
+invCmd "ppmpat -camo -anticamo 10 10"
+invCmd "ppmpat -argyle1 -argyle2 10 10"
+invCmd "ppmpat 10 10"
+invCmd "ppmpat -g2 10"
+invCmd "ppmpat -g2 10 10 10"
+invCmd "ppmpat -g2 10"
 
 clist1="-color=rgb:00/00/00"
 clist2="-color=rgb:00/00/00,rgb:00/00/ff"
@@ -100,90 +59,24 @@ 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 > ${test_out} || \
-  printf "Expected failure 10 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -argyle1  ${clist1} 10 10 > ${test_out} || \
-  printf "Expected failure 11 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -gingham2 ${clist3} 10 10 > ${test_out} || \
-  printf "Expected failure 12 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -argyle1  ${clist3} 10 10 > ${test_out} || \
-  printf "Expected failure 13 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "ppmpat -gingham2 ${clist1} 10 10"
+invCmd "ppmpat -argyle1  ${clist1} 10 10"
+invCmd "ppmpat -gingham2 ${clist3} 10 10"
+invCmd "ppmpat -argyle1  ${clist3} 10 10"
 
 # These require exactly 3 colors
-ppmpat -gingham3 ${clist2} 10 10 > ${test_out} || \
-  printf "Expected failure 14 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -argyle2  ${clist2} 10 10 > ${test_out} || \
-  printf "Expected failure 15 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -madras   ${clist2} 10 10 > ${test_out} || \
-  printf "Expected failure 16 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -tartan   ${clist2} 10 10 > ${test_out} || \
-  printf "Expected failure 17 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -gingham3 ${clist4} 10 10 > ${test_out} || \
-  printf "Expected failure 18 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -argyle2  ${clist4} 10 10 > ${test_out} || \
-  printf "Expected failure 19 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -madras   ${clist4} 10 10 > ${test_out} || \
-  printf "Expected failure 20 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -tartan   ${clist4} 10 10 > ${test_out} || \
-  printf "Expected failure 21 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-# These require at least 3 colors
-ppmpat -squig    ${clist2} 10 10 > ${test_out} || \
-  printf "Expected failure 22 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -camo     ${clist2} 10 10 > ${test_out} || \
-  printf "Expected failure 23 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -anticamo ${clist2} 10 10 > ${test_out} || \
-  printf "Expected failure 24 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "ppmpat -gingham3 ${clist2} 10 10"
+invCmd "ppmpat -argyle2  ${clist2} 10 10"
+invCmd "ppmpat -madras   ${clist2} 10 10"
+invCmd "ppmpat -tartan   ${clist2} 10 10"
+invCmd "ppmpat -gingham3 ${clist4} 10 10"
+invCmd "ppmpat -argyle2  ${clist4} 10 10"
+invCmd "ppmpat -madras   ${clist4} 10 10"
+invCmd "ppmpat -tartan   ${clist4} 10 10"
+invCmd "ppmpat -squig    ${clist2} 10 10"
+invCmd "ppmpat -camo     ${clist2} 10 10"
+invCmd "ppmpat -anticamo ${clist2} 10 10"
 
 # The squig pattern has an aspect ratio restriction
-ppmpat -squig ${clist3} 10 250  > ${test_out} || \
-  printf "Expected failure 25 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
-
-ppmpat -squig ${clist3} 500 20  > ${test_out} || \
-  printf "Expected failure 26 "
-  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
-  rm -f ${test_out}
+invCmd "ppmpat -squig ${clist3} 10 250"
+invCmd "ppmpat -squig ${clist3} 500 20"
diff --git a/test/ppmtomitsu.ok b/test/ppmtomitsu.ok
index 951189d4..812b2ffa 100644
--- a/test/ppmtomitsu.ok
+++ b/test/ppmtomitsu.ok
@@ -1,14 +1,14 @@
-Test 0. Should print 458455366 101484
-458455366 101484
+Test 0. Should print 668243897 101532
+668243897 101532
 Test 1. Should print 3110813682 101562
 3110813682 101562
-Test 2. Should print 4168174994 34399
-4168174994 34399
+Test 2. Should print 825518840 34209
+825518840 34209
 Test 3. Should print 3201293405 310
 3201293405 310
 Test 4. Should print 3354679572 752
 3354679572 752
 Test 5. Should print 3999654426 101549
 3999654426 101549
-Test 6. Should print 4201246884 101549
-4201246884 101549
+Test 6. Should print 3103038403 101549
+3103038403 101549
diff --git a/test/ppmtomitsu.test b/test/ppmtomitsu.test
index ce4bbf56..31cd936f 100755
--- a/test/ppmtomitsu.test
+++ b/test/ppmtomitsu.test
@@ -1,31 +1,31 @@
 #! /bin/sh
 # This script tests: ppmtomitsu
-# Also requires: pnmcolormap pnmremap
+# Also requires: pamseq pamdepth
 
 tmpdir=${tmpdir:-/tmp}
-testimg100_ppm=${tmpdir}/testimg100.ppm
+testimg216_ppm=${tmpdir}/testimg216.ppm
 
-echo "Test 0. Should print 458455366 101484"
-# equivalent to: Pnmquant 100 testimg.ppm
-pnmcolormap 100 testimg.ppm | pnmremap -nofloyd -mapfile=- testimg.ppm |\
- tee ${testimg100_ppm} | cksum
+echo "Test 0. Should print 668243897 101532"
+
+pamseq 3 5 -tupletype=RGB | pamdepth 255 | pnmremap -nofloyd -mapfile=- testimg.ppm |\
+  tee ${testimg216_ppm} | cksum
 
 echo "Test 1. Should print 3110813682 101562"
-ppmtomitsu testimg.ppm | cksum 
+ppmtomitsu testimg.ppm | cksum
 
-echo "Test 2. Should print 4168174994 34399"
-ppmtomitsu ${testimg100_ppm} | cksum 
+echo "Test 2. Should print 825518840 34209"
+ppmtomitsu ${testimg216_ppm} | cksum
 
 echo "Test 3. Should print 3201293405 310"
-ppmtomitsu testgrid.pbm | cksum 
+ppmtomitsu testgrid.pbm | cksum
 
 echo "Test 4. Should print 3354679572 752"
-ppmtomitsu -tiny testgrid.pbm | cksum 
+ppmtomitsu -tiny testgrid.pbm | cksum
 
 echo "Test 5. Should print 3999654426 101549"
-ppmtomitsu -tiny testimg.ppm | cksum 
+ppmtomitsu -tiny testimg.ppm | cksum
 
-echo "Test 6. Should print 4201246884 101549"
-ppmtomitsu -tiny ${testimg100_ppm} | cksum 
+echo "Test 6. Should print 3103038403 101549"
+ppmtomitsu -tiny ${testimg216_ppm} | cksum
 
-rm ${testimg100_ppm}
+rm ${testimg216_ppm}
diff --git a/test/test-invalid.inc b/test/test-invalid.inc
new file mode 100644
index 00000000..e24cfd3f
--- /dev/null
+++ b/test/test-invalid.inc
@@ -0,0 +1,16 @@
+echo 1>&2
+echo "Invalid command-line argument combination(s)." 1>&2
+echo "Error message(s) should appear below the line." 1>&2
+echo "-----------------------------------------------------------" 1>&2
+
+tmpdir=${tmpdir:-/tmp}
+test_out=${tmpdir}/test_out
+
+# define function
+invCmd () { $1 > ${test_out} && \
+  printf "Unexpected success ${testcnt} " || printf "Expected failure ${testcnt} "
+  test -s ${test_out} && echo "unexpected output" || echo "(no output)"
+  rm -f ${test_out}
+  testcnt=$(($testcnt +1)); }
+
+testcnt=1
diff --git a/test/test1.info b/test/test1.info
new file mode 100644
index 00000000..5510d8e8
--- /dev/null
+++ b/test/test1.info
Binary files differdiff --git a/test/test2.info b/test/test2.info
new file mode 100644
index 00000000..7ddb5a6b
--- /dev/null
+++ b/test/test2.info
Binary files differdiff --git a/version.mk b/version.mk
index 6b1c99ac..8ee96d13 100644
--- a/version.mk
+++ b/version.mk
@@ -1,3 +1,3 @@
 NETPBM_MAJOR_RELEASE = 11
-NETPBM_MINOR_RELEASE = 5
-NETPBM_POINT_RELEASE = 3
+NETPBM_MINOR_RELEASE = 6
+NETPBM_POINT_RELEASE = 0