about summary refs log tree commit diff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/pamaltsat.c10
-rw-r--r--editor/pamcut.c120
-rw-r--r--editor/pamdice.c158
-rw-r--r--editor/pamditherbw.c386
-rw-r--r--editor/pamlevels.c2
-rw-r--r--editor/pamperspective.c2
-rw-r--r--editor/pamthreshold.c31
-rw-r--r--editor/pamundice.c459
-rw-r--r--editor/pgmmedian.c26
-rw-r--r--editor/pnmcat.c33
-rw-r--r--editor/pnmconvol.c6
-rw-r--r--editor/pnmcrop.c2
-rw-r--r--editor/pnmgamma.c2
-rw-r--r--editor/pnmnlfilt.c113
-rw-r--r--editor/pnmnorm.c6
-rwxr-xr-xeditor/pnmquantall1
-rw-r--r--editor/pnmshear.c74
-rw-r--r--editor/pnmstitch.c6
-rwxr-xr-xeditor/ppmshadow2
-rw-r--r--editor/specialty/pampaintspill.c4
-rw-r--r--editor/specialty/pampop9.c3
-rw-r--r--editor/specialty/pgmabel.c18
22 files changed, 861 insertions, 603 deletions
diff --git a/editor/pamaltsat.c b/editor/pamaltsat.c
index 6d9b91e0..3bff55bd 100644
--- a/editor/pamaltsat.c
+++ b/editor/pamaltsat.c
@@ -160,7 +160,7 @@ typedef double (binsearchFunc)(double       const x,
 
 /* The binary-search function. Returns such <x> from [<min>, <max>] that
    monotonically increasing function func(x, data) equals <value> within
-   precision <prec>. <dataP> is an arbitary parameter to <func>. */
+   precision <prec>. <dataP> is an arbitrary parameter to <func>. */
 static double
 binsearch(binsearchFunc       func,
           const void  * const dataP,
@@ -299,7 +299,7 @@ typedef struct {
     TupleD *        tupsatP;
         /* saturated color                            */
     double *        intRatioP;
-        /* ratio of orignal and saturated intensities */
+        /* ratio of original and saturated intensities */
 } MaxLogSatInfo;
 
 
@@ -346,7 +346,7 @@ getMaxLogSat(LinSampleInfo * const siP,
 /*  Discarding return value (maximum saturation) because upon completion of
     binsearch() info.tupsatP will contain the saturated color. The target value
     of maximum channel intensity is decreased by PREC in order to avoid
-    overlow. */
+    overflow. */
     binsearch(binsearchMaxLogSat, &info, PREC, 1.0, upperLimit, 1.0 - PREC);
 }
 
@@ -399,11 +399,11 @@ saturateSpectrum(LinSampleInfo * const siP,
     else {
         double const km1 =
             (1.0 - siP->intensity)/(siP->maxval - siP->intensity);
-            /* Maximum saturation factor that keeps maximum layer intesity
+            /* Maximum saturation factor that keeps maximum layer intensity
                within range
             */
         double const km2 = siP->intensity/(siP->intensity - sample[siP->minl]);
-            /* Maximum saturation factor  that keeps minimum layer intesity
+            /* Maximum saturation factor  that keeps minimum layer intensity
                within range
             */
 
diff --git a/editor/pamcut.c b/editor/pamcut.c
index db5b5b3d..1fc9d9b2 100644
--- a/editor/pamcut.c
+++ b/editor/pamcut.c
@@ -17,6 +17,7 @@
 #include "pam.h"
 #include "shhopt.h"
 #include "mallocvar.h"
+#include "nstring.h"
 
 #define UNSPEC INT_MAX
     /* UNSPEC is the value we use for an argument that is not specified
@@ -35,10 +36,10 @@ typedef struct {
 
            If LOCTYPE_NONE: Meaningless
 
-           If LOCTYPE_FROMFAR: Number of colums from the far edge of the image
+           If LOCTYPE_FROMFAR: Number of columns from the far edge of the image
            (right or bottom).  Last column/row is 1.
 
-           If LOCTYPE_FROMNEAR: Number of colums from the near edge of the
+           If LOCTYPE_FROMNEAR: Number of columns from the near edge of the
            image (left or top).  First column/row is 0.
         */
 } Location;
@@ -79,6 +80,73 @@ struct CmdlineInfo {
 
 
 static void
+parseLegacyLocationArgs(const char **        const argv,
+                        struct CmdlineInfo * const cmdlineP) {
+
+    int leftArg, topArg, widthArg, heightArg;
+
+    {
+        const char * error;
+        pm_string_to_int(argv[1], &leftArg,   &error);
+        if (error)
+            pm_error("Invalid number for left column argument.  %s", error);
+    }
+    {
+        const char * error;
+        pm_string_to_int(argv[2], &topArg,    &error);
+        if (error)
+            pm_error("Invalid number for top row argument.  %s",     error);
+    }
+    {
+        const char * error;
+        pm_string_to_int(argv[3], &widthArg,  &error);
+        if (error)
+            pm_error("Invalid number for width argument.  %s",       error);
+    }
+    {
+        const char * error;
+        pm_string_to_int(argv[4], &heightArg, &error);
+        if (error)
+            pm_error("Invalid number for height argument.  %s",      error);
+    }
+
+    if (leftArg < 0) {
+        cmdlineP->leftLoc.locType = LOCTYPE_FROMFAR;
+        cmdlineP->leftLoc.n       = -leftArg;
+    } else {
+        cmdlineP->leftLoc.locType = LOCTYPE_FROMNEAR;
+        cmdlineP->leftLoc.n       = leftArg;
+    }
+    if (topArg < 0) {
+        cmdlineP->topLoc.locType = LOCTYPE_FROMFAR;
+        cmdlineP->topLoc.n       = -topArg;
+    } else {
+        cmdlineP->topLoc.locType = LOCTYPE_FROMNEAR;
+        cmdlineP->topLoc.n       = topArg;
+    }
+    if (widthArg > 0) {
+        cmdlineP->width = widthArg;
+        cmdlineP->widthSpec = 1;
+        cmdlineP->rghtLoc.locType = LOCTYPE_NONE;
+    } else {
+        cmdlineP->widthSpec = 0;
+        cmdlineP->rghtLoc.locType = LOCTYPE_FROMFAR;
+        cmdlineP->rghtLoc.n = -(widthArg - 1);
+    }
+    if (heightArg > 0) {
+        cmdlineP->height = heightArg;
+        cmdlineP->heightSpec = 1;
+        cmdlineP->botLoc.locType = LOCTYPE_NONE;
+    } else {
+        cmdlineP->heightSpec = 0;
+        cmdlineP->botLoc.locType = LOCTYPE_FROMFAR;
+        cmdlineP->botLoc.n = -(heightArg - 1);
+    }
+}
+
+
+
+static void
 parseCommandLine(int argc, const char ** const argv,
                  struct CmdlineInfo * const cmdlineP) {
 /*----------------------------------------------------------------------------
@@ -156,51 +224,9 @@ parseCommandLine(int argc, const char ** const argv,
         break;
     }
 
-    if (haveLegacyLocationArgs) {
-        int leftArg, topArg, widthArg, heightArg;
-
-        if (sscanf(argv[1], "%d", &leftArg) != 1)
-            pm_error("Invalid number for left column argument");
-        if (sscanf(argv[2], "%d", &topArg) != 1)
-            pm_error("Invalid number for right column argument");
-        if (sscanf(argv[3], "%d", &widthArg) != 1)
-            pm_error("Invalid number for width argument");
-        if (sscanf(argv[4], "%d", &heightArg) != 1)
-            pm_error("Invalid number for height argument");
-
-        if (leftArg < 0) {
-            cmdlineP->leftLoc.locType = LOCTYPE_FROMFAR;
-            cmdlineP->leftLoc.n       = -leftArg;
-        } else {
-            cmdlineP->leftLoc.locType = LOCTYPE_FROMNEAR;
-            cmdlineP->leftLoc.n       = leftArg;
-        }
-        if (topArg < 0) {
-            cmdlineP->topLoc.locType = LOCTYPE_FROMFAR;
-            cmdlineP->topLoc.n       = -topArg;
-        } else {
-            cmdlineP->topLoc.locType = LOCTYPE_FROMNEAR;
-            cmdlineP->topLoc.n       = topArg;
-        }
-        if (widthArg > 0) {
-            cmdlineP->width = widthArg;
-            cmdlineP->widthSpec = 1;
-            cmdlineP->rghtLoc.locType = LOCTYPE_NONE;
-        } else {
-            cmdlineP->widthSpec = 0;
-            cmdlineP->rghtLoc.locType = LOCTYPE_FROMFAR;
-            cmdlineP->rghtLoc.n = -(widthArg - 1);
-        }
-        if (heightArg > 0) {
-            cmdlineP->height = heightArg;
-            cmdlineP->heightSpec = 1;
-            cmdlineP->botLoc.locType = LOCTYPE_NONE;
-        } else {
-            cmdlineP->heightSpec = 0;
-            cmdlineP->botLoc.locType = LOCTYPE_FROMFAR;
-            cmdlineP->botLoc.n = -(heightArg - 1);
-        }
-    } else {
+    if (haveLegacyLocationArgs)
+        parseLegacyLocationArgs(argv, cmdlineP);
+    else {
         if (leftSpec && cropleftSpec)
             pm_error("You cannot specify both -left and -cropleft");
         if (leftSpec) {
diff --git a/editor/pamdice.c b/editor/pamdice.c
index 32881129..9063c4bd 100644
--- a/editor/pamdice.c
+++ b/editor/pamdice.c
@@ -17,34 +17,30 @@
 #include "nstring.h"
 #include "mallocvar.h"
 
-#define MAXFILENAMELEN 80
-    /* Maximum number of characters we accept in filenames */
-
-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;  /* '-' if stdin */
-    const char * outstem; 
-        /* null-terminated string, max MAXFILENAMELEN-10 characters */
+    const char * outstem;
     unsigned int sliceVertically;    /* boolean */
     unsigned int sliceHorizontally;  /* boolean */
     unsigned int width;    /* Meaningless if !sliceVertically */
     unsigned int height;   /* Meaningless if !sliceHorizontally */
-    unsigned int hoverlap; 
+    unsigned int hoverlap;
         /* Meaningless if !sliceVertically.  Guaranteed < width */
-    unsigned int voverlap; 
+    unsigned int voverlap;
         /* Meaningless if !sliceHorizontally.  Guaranteed < height */
     unsigned int verbose;
 };
 
 
 static void
-parseCommandLine(int argc, char ** argv,
-                 struct cmdlineInfo * const cmdlineP ) {
+parseCommandLine(int argc, const char ** argv,
+                 struct CmdlineInfo * const cmdlineP) {
 /*----------------------------------------------------------------------------
    parse program command line described in Unix standard form by argc
-   and argv.  Return the information in the options as *cmdlineP.  
+   and argv.  Return the information in the options as *cmdlineP.
 
    If command line is internally inconsistent (invalid options, etc.),
    issue error message to stderr and abort program.
@@ -52,18 +48,18 @@ 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;
+    optEntry * option_def;
         /* Instructions to pm_optParseOptions3 on how to parse our options.
          */
     optStruct3 opt;
-    
+
     unsigned int outstemSpec, hoverlapSpec, voverlapSpec;
     unsigned int option_def_index;
 
     MALLOCARRAY_NOFAIL(option_def, 100);
 
     option_def_index = 0;   /* incremented by OPTENT3 */
-    OPTENT3(0, "width",       OPT_UINT,    &cmdlineP->width,       
+    OPTENT3(0, "width",       OPT_UINT,    &cmdlineP->width,
             &cmdlineP->sliceVertically,       0);
     OPTENT3(0, "height",      OPT_UINT,    &cmdlineP->height,
             &cmdlineP->sliceHorizontally,     0);
@@ -80,7 +76,7 @@ parseCommandLine(int argc, char ** argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We have no parms that are negative numbers */
 
-    pm_optParseOptions3( &argc, argv, opt, sizeof(opt), 0 );
+    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdline_p and others. */
 
     if (cmdlineP->sliceVertically) {
@@ -114,9 +110,11 @@ parseCommandLine(int argc, char ** argv,
         cmdlineP->inputFileName = "-";
     else if (argc-1 == 1)
         cmdlineP->inputFileName = argv[1];
-    else 
-        pm_error("Progam takes at most 1 parameter: the file specification.  "
+    else
+        pm_error("Program takes at most 1 parameter: the file specification.  "
                  "You specified %u", argc-1);
+
+    free(option_def);
 }
 
 
@@ -133,7 +131,7 @@ divup(unsigned int const dividend,
 
 
 static void
-computeSliceGeometry(struct cmdlineInfo const cmdline,
+computeSliceGeometry(struct CmdlineInfo const cmdline,
                      struct pam         const inpam,
                      bool               const verbose,
                      unsigned int *     const nHorizSliceP,
@@ -146,20 +144,30 @@ computeSliceGeometry(struct cmdlineInfo const cmdline,
 /*----------------------------------------------------------------------------
    Compute the geometry of the slices, both common slices and possibly
    smaller remainder slices at the top and right.
+
+   We return the following.
+
+   *nHorizSliceP is the number of horizontal slices.  *sliceHeightP is the
+   height of every slice except possibly the bottom one.  *bottomSliceHeightP
+   is the height of the bottom slice.
+
+   *nVertSliceP is the number of vertical slices.  *sliceWidthP is the width
+   of every slice except possibly the rightmost one.  *rightSliceWidthP is the
+   width of the rightmost slice.
 -----------------------------------------------------------------------------*/
     if (cmdline.sliceHorizontally) {
         if (cmdline.height >= inpam.height)
             *nHorizSliceP = 1;
         else
-            *nHorizSliceP = 1 + divup(inpam.height - cmdline.height, 
+            *nHorizSliceP = 1 + divup(inpam.height - cmdline.height,
                                       cmdline.height - cmdline.voverlap);
         *sliceHeightP = cmdline.height;
 
-        *bottomSliceHeightP = 
-            inpam.height - (*nHorizSliceP-1) * (cmdline.height - cmdline.voverlap);
+        *bottomSliceHeightP = inpam.height -
+            (*nHorizSliceP-1) * (cmdline.height - cmdline.voverlap);
     } else {
-        *nHorizSliceP = 1;
-        *sliceHeightP = inpam.height;
+        *nHorizSliceP       = 1;
+        *sliceHeightP       = inpam.height;
         *bottomSliceHeightP = inpam.height;
     }
 
@@ -167,14 +175,14 @@ computeSliceGeometry(struct cmdlineInfo const cmdline,
         if (cmdline.width >= inpam.width)
             *nVertSliceP = 1;
         else
-            *nVertSliceP = 1 + divup(inpam.width - cmdline.width, 
+            *nVertSliceP = 1 + divup(inpam.width - cmdline.width,
                                      cmdline.width - cmdline.hoverlap);
         *sliceWidthP = cmdline.width;
-        *rightSliceWidthP = 
-            inpam.width - (*nVertSliceP-1) * (cmdline.width - cmdline.hoverlap);
+        *rightSliceWidthP = inpam.width -
+            (*nVertSliceP-1) * (cmdline.width - cmdline.hoverlap);
     } else {
-        *nVertSliceP = 1;
-        *sliceWidthP = inpam.width;
+        *nVertSliceP      = 1;
+        *sliceWidthP      = inpam.width;
         *rightSliceWidthP = inpam.width;
     }
 
@@ -185,7 +193,7 @@ computeSliceGeometry(struct cmdlineInfo const cmdline,
                    *nVertSliceP, *nHorizSliceP,
                    *sliceWidthP, *sliceHeightP);
         if (*rightSliceWidthP != *sliceWidthP)
-            pm_message("Right vertical slice is only %u wide", 
+            pm_message("Right vertical slice is only %u wide",
                        *rightSliceWidthP);
         if (*bottomSliceHeightP != *sliceHeightP)
             pm_message("Bottom horizontal slice is only %u high",
@@ -212,7 +220,7 @@ ndigits(unsigned int const arg) {
 
 
 static void
-computeOutputFilenameFormat(int           const format, 
+computeOutputFilenameFormat(int           const format,
                             unsigned int  const nHorizSlice,
                             unsigned int  const nVertSlice,
                             const char ** const filenameFormatP) {
@@ -226,7 +234,7 @@ computeOutputFilenameFormat(int           const format,
     case PAM_TYPE: filenameSuffix = "pam"; break;
     default:       filenameSuffix = "";    break;
     }
-    
+
     pm_asprintf(filenameFormatP, "%%s_%%0%uu_%%0%uu.%s",
                 ndigits(nHorizSlice), ndigits(nVertSlice), filenameSuffix);
 
@@ -237,16 +245,16 @@ computeOutputFilenameFormat(int           const format,
 
 
 static void
-openOutStreams(struct pam   const inpam, 
-               struct pam         outpam[],
-               unsigned int const horizSlice, 
+openOutStreams(struct pam   const inpam,
+               struct pam * const outpam,
+               unsigned int const horizSlice,
                unsigned int const nHorizSlice,
                unsigned int const nVertSlice,
-               unsigned int const sliceHeight, 
+               unsigned int const sliceHeight,
                unsigned int const sliceWidth,
                unsigned int const rightSliceWidth,
                unsigned int const hOverlap,
-               char         const outstem[]) {
+               const char * const outstem) {
 /*----------------------------------------------------------------------------
    Open the output files for a single horizontal slice (there's one file
    for each vertical slice) and write the Netpbm headers to them.  Also
@@ -268,34 +276,37 @@ openOutStreams(struct pam   const inpam,
         else {
             outpam[vertSlice] = inpam;
             outpam[vertSlice].file = pm_openw(filename);
-            
-            outpam[vertSlice].width = 
+
+            outpam[vertSlice].width =
                 vertSlice < nVertSlice-1 ? sliceWidth : rightSliceWidth;
-            
+
             outpam[vertSlice].height = sliceHeight;
-            
+
             pnm_writepaminit(&outpam[vertSlice]);
 
             pm_strfree(filename);
         }
-    }        
+    }
     pm_strfree(filenameFormat);
 }
 
 
 
 static void
-closeOutFiles(struct pam pam[], unsigned int const nVertSlice) {
+closeOutFiles(struct pam * const pam,
+              unsigned int const nVertSlice) {
 
     unsigned int vertSlice;
-    
+
     for (vertSlice = 0; vertSlice < nVertSlice; ++vertSlice)
         pm_close(pam[vertSlice].file);
 }
 
+
+
 static void
-sliceRow(tuple              inputRow[], 
-         struct pam         outpam[], 
+sliceRow(tuple *      const inputRow,
+         struct pam * const outpam,
          unsigned int const nVertSlice,
          unsigned int const hOverlap) {
 /*----------------------------------------------------------------------------
@@ -306,14 +317,15 @@ sliceRow(tuple              inputRow[],
    'hOverlap', which is meaningful only when nVertSlice is greater than 1,
    is the amount by which slices overlap each other.
 -----------------------------------------------------------------------------*/
-    tuple * outputRow;
-    unsigned int vertSlice;
     unsigned int const sliceWidth = outpam[0].width;
-    unsigned int const stride = 
+    unsigned int const stride =
         nVertSlice > 1 ? sliceWidth - hOverlap : sliceWidth;
 
-    for (vertSlice = 0, outputRow = inputRow; 
-         vertSlice < nVertSlice; 
+    tuple *      outputRow;
+    unsigned int vertSlice;
+
+    for (vertSlice = 0, outputRow = inputRow;
+         vertSlice < nVertSlice;
          outputRow += stride, ++vertSlice) {
         pnm_writepamrow(&outpam[vertSlice], outputRow);
     }
@@ -331,15 +343,15 @@ sliceRow(tuple              inputRow[],
 struct inputWindow {
     unsigned int windowSize;
     unsigned int firstRowInWindow;
-    struct pam pam;
-    tuple ** rows;
+    struct pam   pam;
+    tuple **     rows;
 };
 
 static void
 initInput(struct inputWindow * const inputWindowP,
           struct pam *         const pamP,
           unsigned int         const windowSize) {
-    
+
     struct pam allocPam;  /* Just for allocating the window array */
     unsigned int i;
 
@@ -348,7 +360,7 @@ initInput(struct inputWindow * const inputWindowP,
 
     allocPam = *pamP;
     allocPam.height = windowSize;
-    
+
     inputWindowP->rows = pnm_allocpamarray(&allocPam);
 
     inputWindowP->firstRowInWindow = 0;
@@ -369,6 +381,8 @@ termInputWindow(struct inputWindow * const inputWindowP) {
     pnm_freepamarray(inputWindowP->rows, &freePam);
 }
 
+
+
 static tuple *
 getInputRow(struct inputWindow * const inputWindowP,
             unsigned int         const row) {
@@ -391,7 +405,7 @@ getInputRow(struct inputWindow * const inputWindowP,
         /* Read in the new last row in the window */
         inputWindowP->rows[i] = oldRow0;  /* Reuse the memory */
         pnm_readpamrow(&inputWindowP->pam, inputWindowP->rows[i]);
-    }        
+    }
 
     return inputWindowP->rows[row - inputWindowP->firstRowInWindow];
 }
@@ -418,10 +432,10 @@ allocOutpam(unsigned int  const nVertSlice,
 
 
 int
-main(int argc, char ** argv) {
+main(int argc, const char ** argv) {
 
-    struct cmdlineInfo cmdline;
-    FILE    *ifP;
+    struct CmdlineInfo cmdline;
+    FILE    * ifP;
     struct pam inpam;
     unsigned int horizSlice;
         /* Number of the current horizontal slice.  Slices are numbered
@@ -431,7 +445,7 @@ main(int argc, char ** argv) {
         /* Width in pam columns of each vertical slice, except
            the rightmost slice, which may be narrower.  If we aren't slicing
            vertically, that means one slice, i.e. the slice width
-           is the image width.  
+           is the image width.
         */
     unsigned int rightSliceWidth;
         /* Width in pam columns of the rightmost vertical slice. */
@@ -439,23 +453,23 @@ main(int argc, char ** argv) {
         /* Height in pam rows of each horizontal slice, except
            the bottom slice, which may be shorter.  If we aren't slicing
            horizontally, that means one slice, i.e. the slice height
-           is the image height.  
+           is the image height.
         */
     unsigned int bottomSliceHeight;
         /* Height in pam rows of the bottom horizontal slice. */
     unsigned int nHorizSlice;
     unsigned int nVertSlice;
     struct inputWindow inputWindow;
-    
+
     struct pam * outpam;
-        /* malloc'ed.  outpam[x] is the pam structure that controls
+        /* malloc'ed array.  outpam[x] is the pam structure that controls
            the current horizontal slice of vertical slice x.
         */
 
-    pnm_init(&argc, argv);
-    
+    pm_proginit(&argc, argv);
+
     parseCommandLine(argc, argv, &cmdline);
-        
+
     ifP = pm_openr(cmdline.inputFileName);
 
     pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type));
@@ -465,28 +479,29 @@ main(int argc, char ** argv) {
                          &nVertSlice, &sliceWidth, &rightSliceWidth);
 
     allocOutpam(nVertSlice, &outpam);
-    
-    initInput(&inputWindow, &inpam, 
+
+    initInput(&inputWindow, &inpam,
               nHorizSlice > 1 ? cmdline.voverlap + 1 : 1);
 
     for (horizSlice = 0; horizSlice < nHorizSlice; ++horizSlice) {
-        unsigned int const thisSliceFirstRow = 
+        unsigned int const thisSliceFirstRow =
             horizSlice > 0 ? horizSlice * (sliceHeight - cmdline.voverlap) : 0;
             /* Note that 'cmdline.voverlap' is not defined when there is only
                one horizontal slice
             */
-        unsigned int const thisSliceHeight = 
+        unsigned int const thisSliceHeight =
             horizSlice < nHorizSlice-1 ? sliceHeight : bottomSliceHeight;
 
         unsigned int row;
 
-        openOutStreams(inpam, outpam, horizSlice, nHorizSlice, nVertSlice, 
+        openOutStreams(inpam, outpam, horizSlice, nHorizSlice, nVertSlice,
                        thisSliceHeight, sliceWidth, rightSliceWidth,
                        cmdline.hoverlap, cmdline.outstem);
 
         for (row = 0; row < thisSliceHeight; ++row) {
             tuple * const inputRow =
                 getInputRow(&inputWindow, thisSliceFirstRow + row);
+
             sliceRow(inputRow, outpam, nVertSlice, cmdline.hoverlap);
         }
         closeOutFiles(outpam, nVertSlice);
@@ -500,3 +515,6 @@ main(int argc, char ** argv) {
 
     return 0;
 }
+
+
+
diff --git a/editor/pamditherbw.c b/editor/pamditherbw.c
index 4b192e6e..ae91a26f 100644
--- a/editor/pamditherbw.c
+++ b/editor/pamditherbw.c
@@ -42,7 +42,7 @@ struct cmdlineInfo {
     enum halftone halftone;
     unsigned int  clumpSize;
         /* Defined only for halftone == QT_HILBERT */
-    unsigned int  clusterRadius;  
+    unsigned int  clusterRadius;
         /* Defined only for halftone == QT_CLUSTER */
     float         threshval;
     unsigned int  randomseed;
@@ -85,9 +85,9 @@ parseCommandLine(int argc, char ** argv,
     OPTENT3(0, "c4",        OPT_FLAG,  NULL, &cluster4Opt,  0);
     OPTENT3(0, "cluster8",  OPT_FLAG,  NULL, &cluster8Opt,  0);
     OPTENT3(0, "c8",        OPT_FLAG,  NULL, &cluster8Opt,  0);
-    OPTENT3(0, "value",     OPT_FLOAT, &cmdlineP->threshval, 
+    OPTENT3(0, "value",     OPT_FLOAT, &cmdlineP->threshval,
             &valueSpec, 0);
-    OPTENT3(0, "clump",     OPT_UINT,  &cmdlineP->clumpSize, 
+    OPTENT3(0, "clump",     OPT_UINT,  &cmdlineP->clumpSize,
             &clumpSpec, 0);
     OPTENT3(0,   "randomseed",   OPT_UINT,    &cmdlineP->randomseed,
             &cmdlineP->randomseedSpec,      0);
@@ -101,10 +101,10 @@ parseCommandLine(int argc, char ** argv,
 
     free(option_def);
 
-    if (floydOpt + atkinsonOpt + thresholdOpt + hilbertOpt + dither8Opt + 
+    if (floydOpt + atkinsonOpt + thresholdOpt + hilbertOpt + dither8Opt +
         cluster3Opt + cluster4Opt + cluster8Opt == 0)
         cmdlineP->halftone = QT_FS;
-    else if (floydOpt + atkinsonOpt + thresholdOpt + dither8Opt + 
+    else if (floydOpt + atkinsonOpt + thresholdOpt + hilbertOpt + dither8Opt +
         cluster3Opt + cluster4Opt + cluster8Opt > 1)
         pm_error("Cannot specify more than one halftoning type");
     else {
@@ -135,7 +135,7 @@ parseCommandLine(int argc, char ** argv,
         } else if (cluster8Opt) {
             cmdlineP->halftone = QT_CLUSTER;
             cmdlineP->clusterRadius = 8;
-        } else 
+        } else
             pm_error("INTERNAL ERROR.  No halftone option");
     }
 
@@ -190,152 +190,211 @@ makeOutputPam(unsigned int const width,
 
 /* Hilbert curve tracer */
 
-#define MAXORD 18
+typedef struct {
+    unsigned int x;
+    unsigned int y;
+} Point;
+
 
-struct Hil {
-    int order;
-    int ord;
+
+typedef struct {
+    bool firstPointDone;
+    unsigned int order;
+    unsigned int ord;
+        /* Meaningful only when 'firstPointDone' is true */
     int turn;
     int dx;
     int dy;
     int x;
     int y;
-    int stage[MAXORD];
-    int width;
-    int height;
-};
+    int stage[sizeof(unsigned int)*8];
+        /* One entry for every bit in the height or width, each of which
+           is an unsigned int
+        */
+    unsigned int width;
+    unsigned int height;
+} Hilbert;
 
-static void 
-initHilbert(int          const w, 
-            int          const h,
-            struct Hil * const hilP) {
+static void
+hilbert_init(Hilbert *    const hilP,
+             unsigned int const width,
+             unsigned int const height) {
 /*----------------------------------------------------------------------------
-  Initialize the Hilbert curve tracer 
+  Initialize the Hilbert curve tracer
 -----------------------------------------------------------------------------*/
-    int big, ber;
-    hilP->width = w;
-    hilP->height = h;
-    big = w > h ? w : h;
-    for (ber = 2, hilP->order = 1; ber < big; ber <<= 1, hilP->order++);
-    if (hilP->order > MAXORD)
-        pm_error("Sorry, hilbert order is too large");
-    hilP->ord = hilP->order;
-    hilP->order--;
+    unsigned int const maxDim = MAX(width, height);
+
+    unsigned int order;
+
+    hilP->width  = width;
+    hilP->height = height;
+    {
+        unsigned int ber;
+        for (ber = 2, order = 0; ber < maxDim; ber <<= 1, ++order);
+    }
+    assert(order + 1 <= ARRAY_SIZE(hilP->stage));
+    hilP->order = order;
+    hilP->firstPointDone = false;
 }
 
 
 
-static bool
-hilbert(int *        const px,
-        int *        const py,
-        struct Hil * const hilP) {
-/*----------------------------------------------------------------------------
-  Return non-zero if got another point
------------------------------------------------------------------------------*/
-    int temp;
-    if (hilP->ord > hilP->order) {
-        /* have to do first point */
-
-        hilP->ord--;
-        hilP->stage[hilP->ord] = 0;
-        hilP->turn = -1;
-        hilP->dy = 1;
-        hilP->dx = hilP->x = hilP->y = 0;
-        *px = *py = 0;
-        return true;
-    }
+static void
+hilbert_doFirstPoint(Hilbert * const hilbertP,
+                     bool *    const gotPointP,
+                     Point *   const pointP) {
+
+    hilbertP->ord = hilbertP->order;
+    hilbertP->stage[hilbertP->ord] = 0;
+    hilbertP->turn = -1;
+    hilbertP->dy = 1;
+    hilbertP->dx = hilbertP->x = hilbertP->y = 0;
+    hilbertP->firstPointDone = true;
+
+    pointP->x = 0; pointP->y = 0;
+    *gotPointP = true;
+}
+
+
+
+static void
+hilbert_advanceStateMachine(Hilbert * const hilbertP,
+                            bool *    const gotPointP,
+                            Point *   const pointP) {
 
-    /* Operate the state machine */
     for(;;)  {
-        switch (hilP->stage[hilP->ord]) {
-        case 0:
-            hilP->turn = -hilP->turn;
-            temp = hilP->dy;
-            hilP->dy = -hilP->turn * hilP->dx;
-            hilP->dx = hilP->turn * temp;
-            if (hilP->ord > 0) {
-                hilP->stage[hilP->ord] = 1;
-                hilP->ord--;
-                hilP->stage[hilP->ord]=0;
+        switch (hilbertP->stage[hilbertP->ord]) {
+        case 0: {
+            int const origDy = hilbertP->dy;
+
+            hilbertP->turn = -hilbertP->turn;
+            hilbertP->dy = -hilbertP->turn * hilbertP->dx;
+            hilbertP->dx = hilbertP->turn * origDy;
+            if (hilbertP->ord > 0) {
+                hilbertP->stage[hilbertP->ord] = 1;
+                --hilbertP->ord;
+                hilbertP->stage[hilbertP->ord]=0;
                 continue;
             }
-        case 1:
-            hilP->x += hilP->dx;
-            hilP->y += hilP->dy;
-            if (hilP->x < hilP->width && hilP->y < hilP->height) {
-                hilP->stage[hilP->ord] = 2;
-                *px = hilP->x;
-                *py = hilP->y;
-                return true;
+        }
+        case 1: {
+            hilbertP->x += hilbertP->dx;
+            hilbertP->y += hilbertP->dy;
+            if (hilbertP->x < hilbertP->width &&
+                hilbertP->y < hilbertP->height) {
+
+                hilbertP->stage[hilbertP->ord] = 2;
+
+                pointP->x = hilbertP->x;
+                pointP->y = hilbertP->y;
+                *gotPointP = true;
+                return;
             }
-        case 2:
-            hilP->turn = -hilP->turn;
-            temp = hilP->dy;
-            hilP->dy = -hilP->turn * hilP->dx;
-            hilP->dx = hilP->turn * temp;
-            if (hilP->ord > 0) { 
+        }
+        case 2: {
+            int const origDy = hilbertP->dy;
+
+            hilbertP->turn = -hilbertP->turn;
+            hilbertP->dy = -hilbertP->turn * hilbertP->dx;
+            hilbertP->dx = hilbertP->turn * origDy;
+            if (hilbertP->ord > 0) {
                 /* recurse */
 
-                hilP->stage[hilP->ord] = 3;
-                hilP->ord--;
-                hilP->stage[hilP->ord]=0;
+                hilbertP->stage[hilbertP->ord] = 3;
+                --hilbertP->ord;
+                hilbertP->stage[hilbertP->ord]=0;
                 continue;
             }
-        case 3:
-            hilP->x += hilP->dx;
-            hilP->y += hilP->dy;
-            if (hilP->x < hilP->width && hilP->y < hilP->height) {
-                hilP->stage[hilP->ord] = 4;
-                *px = hilP->x;
-                *py = hilP->y;
-                return true;
+        }
+        case 3: {
+            hilbertP->x += hilbertP->dx;
+            hilbertP->y += hilbertP->dy;
+            if (hilbertP->x < hilbertP->width &&
+                hilbertP->y < hilbertP->height) {
+
+                hilbertP->stage[hilbertP->ord] = 4;
+
+                pointP->x = hilbertP->x;
+                pointP->y = hilbertP->y;
+                *gotPointP = true;
+                return;
             }
-        case 4:
-            if (hilP->ord > 0) {
+        }
+        case 4: {
+            if (hilbertP->ord > 0) {
                 /* recurse */
-                hilP->stage[hilP->ord] = 5;
-                hilP->ord--;
-                hilP->stage[hilP->ord]=0;
+                hilbertP->stage[hilbertP->ord] = 5;
+                --hilbertP->ord;
+                hilbertP->stage[hilbertP->ord]=0;
                 continue;
             }
-        case 5:
-            temp = hilP->dy;
-            hilP->dy = -hilP->turn * hilP->dx;
-            hilP->dx = hilP->turn * temp;
-            hilP->turn = -hilP->turn;
-            hilP->x += hilP->dx;
-            hilP->y += hilP->dy;
-            if (hilP->x < hilP->width && hilP->y < hilP->height) {
-                hilP->stage[hilP->ord] = 6;
-                *px = hilP->x;
-                *py = hilP->y;
-                return true;
+        }
+        case 5: {
+            int const origDy = hilbertP->dy;
+
+            hilbertP->dy = -hilbertP->turn * hilbertP->dx;
+            hilbertP->dx = hilbertP->turn * origDy;
+            hilbertP->turn = -hilbertP->turn;
+            hilbertP->x += hilbertP->dx;
+            hilbertP->y += hilbertP->dy;
+            if (hilbertP->x < hilbertP->width &&
+                hilbertP->y < hilbertP->height) {
+
+                hilbertP->stage[hilbertP->ord] = 6;
+
+                pointP->x = hilbertP->x;
+                pointP->y = hilbertP->y;
+                *gotPointP = true;
+                return;
             }
-        case 6:
-            if (hilP->ord > 0) {
+        }
+        case 6: {
+            if (hilbertP->ord > 0) {
                 /* recurse */
-                hilP->stage[hilP->ord] = 7;
-                hilP->ord--;
-                hilP->stage[hilP->ord]=0;
+                hilbertP->stage[hilbertP->ord] = 7;
+                --hilbertP->ord;
+                hilbertP->stage[hilbertP->ord]=0;
                 continue;
             }
-        case 7:
-            temp = hilP->dy;
-            hilP->dy = -hilP->turn * hilP->dx;
-            hilP->dx = hilP->turn * temp;
-            hilP->turn = -hilP->turn;
+        }
+        case 7: {
+            int const origDy = hilbertP->dy;
+
+            hilbertP->dy = -hilbertP->turn * hilbertP->dx;
+            hilbertP->dx = hilbertP->turn * origDy;
+            hilbertP->turn = -hilbertP->turn;
             /* Return from a recursion */
-            if (hilP->ord < hilP->order)
-                hilP->ord++;
-            else
-                return false;
+            if (hilbertP->ord < hilbertP->order)
+                ++hilbertP->ord;
+            else {
+                *gotPointP = false;
+                return;
+            }
+        }
         }
     }
 }
 
 
 
-static void 
+static void
+hilbert_trace(Hilbert * const hilbertP,
+              bool *    const gotPointP,
+              Point *   const pointP) {
+/*----------------------------------------------------------------------------
+  ...
+  Return *gotPointP true iff we got another point
+-----------------------------------------------------------------------------*/
+    if (!hilbertP->firstPointDone) {
+        hilbert_doFirstPoint(hilbertP, gotPointP, pointP);
+    } else {
+        hilbert_advanceStateMachine(hilbertP, gotPointP, pointP);
+    }
+}
+
+
+
+static void
 doHilbert(FILE *       const ifP,
           unsigned int const clumpSize) {
 /*----------------------------------------------------------------------------
@@ -356,10 +415,10 @@ doHilbert(FILE *       const ifP,
     tuple ** grays;
     tuple ** bits;
 
-    struct Hil hil;
+    Hilbert hilbert;
 
     int end;
-    int *x,*y;
+    Point * point;
     int sum;
 
     grays = pnm_readpam(ifP, &graypam, PAM_STRUCT_SIZE(tuple_type));
@@ -368,11 +427,11 @@ doHilbert(FILE *       const ifP,
 
     bits = pnm_allocpamarray(&bitpam);
 
-    MALLOCARRAY(x, clumpSize);
-    MALLOCARRAY(y, clumpSize);
-    if (x == NULL  || y == NULL)
-        pm_error("out of memory");
-    initHilbert(graypam.width, graypam.height, &hil);
+    MALLOCARRAY(point, clumpSize);
+    if (!point)
+        pm_error("Unable to get memory for clump of %u points", clumpSize);
+
+    hilbert_init(&hilbert, graypam.width, graypam.height);
 
     sum = 0;
     end = clumpSize;
@@ -380,19 +439,20 @@ doHilbert(FILE *       const ifP,
     while (end == clumpSize) {
         unsigned int i;
         /* compute the next cluster co-ordinates along hilbert path */
-        for (i = 0; i < end; i++) {
+        for (i = 0; i < end; ++i) {
             bool gotPoint;
-            gotPoint = hilbert(&x[i], &y[i], &hil);
+            hilbert_trace(&hilbert, &gotPoint, &point[i]);
             if (!gotPoint)
                 end = i;    /* we reached the end */
         }
         /* sum levels */
-        for (i = 0; i < end; i++)
-            sum += grays[y[i]][x[i]][0];
+        for (i = 0; i < end; ++i)
+            sum += grays[point[i].y][point[i].x][0];
         /* dither half and half along path */
-        for (i = 0; i < end; i++) {
-            unsigned int const row = y[i];
-            unsigned int const col = x[i];
+        for (i = 0; i < end; ++i) {
+            unsigned int const row = point[i].y;
+            unsigned int const col = point[i].x;
+
             if (sum >= graypam.maxval) {
                 bits[row][col][0] = 1;
                 sum -= graypam.maxval;
@@ -400,7 +460,7 @@ doHilbert(FILE *       const ifP,
                 bits[row][col][0] = 0;
         }
     }
-    free(x);    free(y); 
+    free(point);
     pnm_writepam(&bitpam, bits);
 
     pnm_freepamarray(bits, &bitpam);
@@ -412,7 +472,7 @@ doHilbert(FILE *       const ifP,
 struct converter {
     void (*convertRow)(struct converter * const converterP,
                        unsigned int       const row,
-                       tuplen                   grayrow[], 
+                       tuplen                   grayrow[],
                        tuple                    bitrow[]);
     void (*destroy)(struct converter * const converterP);
     unsigned int cols;
@@ -423,11 +483,11 @@ struct converter {
 
 struct fsState {
     float * thiserr;
-        /* thiserr[N] is the power from previous pixels to include in 
+        /* thiserr[N] is the power from previous pixels to include in
            future column N of the current row.
         */
     float * nexterr;
-        /* nexterr[N] is the power from previous pixels to include in 
+        /* nexterr[N] is the power from previous pixels to include in
            future column N of the next row.
         */
     bool fs_forward;
@@ -455,7 +515,7 @@ fsConvertRow(struct converter * const converterP,
 
     unsigned int limitcol;
     unsigned int col;
-    
+
     for (col = 0; col < converterP->cols + 2; ++col)
         nexterr[col] = 0.0;
 
@@ -494,18 +554,18 @@ fsConvertRow(struct converter * const converterP,
             nexterr[col    ] += (accum * 3) / 16;
             nexterr[col + 1] += (accum * 5) / 16;
             nexterr[col + 2] += (accum * 1) / 16;
-            
+
             ++col;
         } else {
             thiserr[col    ] += (accum * 7) / 16;
             nexterr[col + 2] += (accum * 3) / 16;
             nexterr[col + 1] += (accum * 5) / 16;
             nexterr[col    ] += (accum * 1) / 16;
-            
+
             --col;
         }
     } while (col != limitcol);
-    
+
     stateP->thiserr = nexterr;
     stateP->nexterr = thiserr;
     stateP->fs_forward = ! stateP->fs_forward;
@@ -584,7 +644,7 @@ struct atkinsonState {
 
 static void
 moveAtkinsonErrorWindowDown(struct converter * const converterP) {
-                            
+
     struct atkinsonState * const stateP = converterP->stateP;
 
     float * const oldError0 = stateP->error[0];
@@ -628,7 +688,7 @@ atkinsonConvertRow(struct converter * const converterP,
             accum -= stateP->white;
         } else
             bitrow[col] = blackTuple;
-        
+
         /* Forward to future output pixels 3/4 of the power from current
            input pixel and the power forwarded from previous input
            pixels to the current pixel, less any power we put into the
@@ -642,7 +702,7 @@ atkinsonConvertRow(struct converter * const converterP,
         error[1][col+1] += accum/8;
         error[2][col  ] += accum/8;
     }
-    
+
     moveAtkinsonErrorWindowDown(converterP);
 }
 
@@ -670,7 +730,7 @@ createAtkinsonConverter(struct pam * const graypamP,
     struct atkinsonState * stateP;
     struct converter converter;
     unsigned int relRow;
-    
+
     converter.cols       = graypamP->width;
     converter.convertRow = &atkinsonConvertRow;
     converter.destroy    = &atkinsonDestroy;
@@ -710,7 +770,7 @@ threshConvertRow(struct converter * const converterP,
                  unsigned int       const row,
                  tuplen                   grayrow[],
                  tuple                    bitrow[]) {
-    
+
     struct threshState * const stateP = converterP->stateP;
 
     unsigned int col;
@@ -740,7 +800,7 @@ createThreshConverter(struct pam * const graypamP,
     converter.cols       = graypamP->width;
     converter.convertRow = &threshConvertRow;
     converter.destroy    = &threshDestroy;
-    
+
     stateP->threshval    = threshFraction;
     converter.stateP     = stateP;
 
@@ -768,7 +828,7 @@ clusterConvertRow(struct converter * const converterP,
     unsigned int col;
 
     for (col = 0; col < converterP->cols; ++col) {
-        float const threshold = 
+        float const threshold =
             stateP->clusterMatrix[row % diameter][col % diameter];
         bitrow[col] =
             grayrow[col][0] > threshold ? whiteTuple : blackTuple;
@@ -789,7 +849,7 @@ clusterDestroy(struct converter * const converterP) {
         free(stateP->clusterMatrix[row]);
 
     free(stateP->clusterMatrix);
-    
+
     free(stateP);
 }
 
@@ -799,14 +859,14 @@ static struct converter
 createClusterConverter(struct pam *    const graypamP,
                        enum ditherType const ditherType,
                        unsigned int    const radius) {
-    
+
     /* TODO: We create a floating point normalized, gamma-adjusted
-       dither matrix from the old integer dither matrices that were 
+       dither matrix from the old integer dither matrices that were
        developed for use with integer arithmetic.  We really should
        just change the literal values in dither.h instead of computing
        the matrix from the integer literal values here.
     */
-    
+
     int const clusterNormalizer = radius * radius * 2;
     unsigned int const diameter = 2 * radius;
 
@@ -827,16 +887,16 @@ createClusterConverter(struct pam *    const graypamP,
         unsigned int col;
 
         MALLOCARRAY_NOFAIL(stateP->clusterMatrix[row], diameter);
-        
+
         for (col = 0; col < diameter; ++col) {
             switch (ditherType) {
-            case DT_REGULAR: 
+            case DT_REGULAR:
                 switch (radius) {
-                case 8: 
-                    stateP->clusterMatrix[row][col] = 
+                case 8:
+                    stateP->clusterMatrix[row][col] =
                         pm_gamma709((float)dither8[row][col] / 256);
                     break;
-                default: 
+                default:
                     pm_error("INTERNAL ERROR: invalid radius");
                 }
                 break;
@@ -849,13 +909,13 @@ createClusterConverter(struct pam *    const graypamP,
                 default:
                     pm_error("INTERNAL ERROR: invalid radius");
                 }
-                stateP->clusterMatrix[row][col] = 
+                stateP->clusterMatrix[row][col] =
                     pm_gamma709((float)val / clusterNormalizer);
             }
             break;
             }
         }
-    }            
+    }
 
     converter.stateP = stateP;
 
@@ -891,7 +951,7 @@ main(int argc, char *argv[]) {
         pnm_readpaminit(ifP, &graypam, PAM_STRUCT_SIZE(tuple_type));
 
         bitpam = makeOutputPam(graypam.width, graypam.height);
-        
+
         pnm_writepaminit(&bitpam);
 
         switch (cmdline.halftone) {
@@ -904,15 +964,15 @@ main(int argc, char *argv[]) {
         case QT_THRESH:
             converter = createThreshConverter(&graypam, cmdline.threshval);
             break;
-        case QT_DITHER8: 
-            converter = createClusterConverter(&graypam, DT_REGULAR, 8); 
+        case QT_DITHER8:
+            converter = createClusterConverter(&graypam, DT_REGULAR, 8);
             break;
-        case QT_CLUSTER: 
-            converter = createClusterConverter(&graypam, 
-                                               DT_CLUSTER, 
+        case QT_CLUSTER:
+            converter = createClusterConverter(&graypam,
+                                               DT_CLUSTER,
                                                cmdline.clusterRadius);
             break;
-        case QT_HILBERT: 
+        case QT_HILBERT:
                 pm_error("INTERNAL ERROR: halftone is QT_HILBERT where it "
                          "shouldn't be.");
                 break;
@@ -925,7 +985,7 @@ main(int argc, char *argv[]) {
             pnm_readpamrown(&graypam, grayrow);
 
             converter.convertRow(&converter, row, grayrow, bitrow);
-            
+
             pnm_writepamrow(&bitpam, bitrow);
         }
         free(bitrow);
diff --git a/editor/pamlevels.c b/editor/pamlevels.c
index fbbb2c0b..a282751a 100644
--- a/editor/pamlevels.c
+++ b/editor/pamlevels.c
@@ -482,7 +482,7 @@ pamlevels(CmdlineInfo const cmdline) {
 static void
 freeCmdLineInfo(CmdlineInfo cmdline) {
 /*----------------------------------------------------------------------------
-  Free any memory that has been dynamically allcoated in <cmdline>.
+  Free any memory that has been dynamically allocated in <cmdline>.
 -----------------------------------------------------------------------------*/
     TransSet * const xxP = &cmdline.xlats;
 
diff --git a/editor/pamperspective.c b/editor/pamperspective.c
index a206b57f..a8b1cf8f 100644
--- a/editor/pamperspective.c
+++ b/editor/pamperspective.c
@@ -804,7 +804,7 @@ static void determine_world_parallelogram (world_data *const world,
   yw_lr = world->yi_lr * zw_lr;
 
   /* Now we introduce the margin. There are several ways the margin can be
-     defined. margin_spec keeps track of wether one of them has yet been
+     defined. margin_spec keeps track of whether one of them has yet been
      used. As long as margin_spec==FALSE, the variables top_margin to
      bottom_margin are not initialized! */
 
diff --git a/editor/pamthreshold.c b/editor/pamthreshold.c
index 8d28bc4a..809d76d9 100644
--- a/editor/pamthreshold.c
+++ b/editor/pamthreshold.c
@@ -73,7 +73,7 @@ initRange(struct range * const rangeP) {
     rangeP->max = 0.0;
 }
 
-          
+
 
 static void
 addToRange(struct range * const rangeP,
@@ -89,7 +89,7 @@ static float
 spread(struct range const range) {
 
     assert(range.max >= range.min);
-    
+
     return range.max - range.min;
 }
 
@@ -120,12 +120,12 @@ parseGeometry(const char *   const wxl,
 
 
 static void
-parseCommandLine(int                 argc, 
+parseCommandLine(int                 argc,
                  char **             argv,
                  struct cmdlineInfo *cmdlineP ) {
 /*----------------------------------------------------------------------------
    Parse program command line described in Unix standard form by argc
-   and argv.  Return the information in the options as *cmdlineP.  
+   and argv.  Return the information in the options as *cmdlineP.
 
    If command line is internally inconsistent (invalid options, etc.),
    issue error message to stderr and abort program.
@@ -145,7 +145,7 @@ parseCommandLine(int                 argc,
     MALLOCARRAY_NOFAIL(option_def, 100);
 
     /* define the options */
-    OPTENT3(0, "simple",    OPT_FLAG,   NULL,               
+    OPTENT3(0, "simple",    OPT_FLAG,   NULL,
             &cmdlineP->simple,      0);
     OPTENT3(0, "local",     OPT_STRING, &localOpt,
             &localSpec,             0);
@@ -155,7 +155,7 @@ parseCommandLine(int                 argc,
             &thresholdSpec,         0);
     OPTENT3(0, "contrast",  OPT_FLOAT,  &cmdlineP->contrast,
             &contrastSpec,          0);
-    OPTENT3(0, "verbose",    OPT_FLAG,   NULL,               
+    OPTENT3(0, "verbose",    OPT_FLAG,   NULL,
             &cmdlineP->verbose,     0);
 
     /* set the defaults */
@@ -216,8 +216,8 @@ parseCommandLine(int                 argc,
         cmdlineP->inputFileName = "-";
     else if (argc-1 == 1)
         cmdlineP->inputFileName = argv[1];
-    else 
-        pm_error("Progam takes at most 1 parameter: the file name.  "
+    else
+        pm_error("Program takes at most 1 parameter: the file name.  "
                  "You specified %d", argc-1);
 }
 
@@ -389,7 +389,7 @@ computeGlobalThreshold(struct pam *         const inpamP,
        of the "k-means clustering algorithm."
 
        The article claims it's proven to converge, by the way.
-       We have an interation limit just as a safety net.
+       We have an iteration limit just as a safety net.
 
        This code originally implemented a rather different algorithm,
        while nonetheless carrying the comment that it implemented the
@@ -524,7 +524,7 @@ thresholdLocalRow(struct pam *       const inpamP,
         getLocalThreshold(inrows, inpamP->width, col, localWidth, windowHeight,
                           cmdline.threshold, minSpread, globalThreshold,
                           &threshold);
-        
+
         thresholdPixel(outpamP, inrow[col], outrow[col], threshold);
     }
 }
@@ -569,12 +569,12 @@ thresholdLocal(struct pam *       const inpamP,
     unsigned int oddLocalWidth;
     unsigned int oddLocalHeight;
     unsigned int i;
-    
+
     /* use a subimage with odd width and height to have a middle pixel */
 
     if (cmdline.width % 2 == 0)
         oddLocalWidth = cmdline.width + 1;
-    else 
+    else
         oddLocalWidth = cmdline.width;
     if (cmdline.height % 2 == 0)
         oddLocalHeight = cmdline.height + 1;
@@ -616,7 +616,7 @@ thresholdLocal(struct pam *       const inpamP,
                           outpamP, outrow);
 
         pnm_writepamrow(outpamP, outrow);
-        
+
         /* read next image line if available and necessary */
         if (row + windowHeight / 2 >= nextRowToRead &&
             nextRowToRead < inpamP->height)
@@ -655,7 +655,7 @@ thresholdIterative(struct pam * const inpamP,
 int
 main(int argc, char **argv) {
 
-    FILE * ifP; 
+    FILE * ifP;
     struct cmdlineInfo cmdline;
     struct pam inpam, outpam;
     int eof;  /* No more images in input stream */
@@ -711,3 +711,6 @@ main(int argc, char **argv) {
 
     return 0;
 }
+
+
+
diff --git a/editor/pamundice.c b/editor/pamundice.c
index dbe0a8df..60360f17 100644
--- a/editor/pamundice.c
+++ b/editor/pamundice.c
@@ -18,30 +18,28 @@
 #include "nstring.h"
 #include "mallocvar.h"
 
-#define MAXFILENAMELEN 80
-    /* Maximum number of characters we accept in filenames */
-
-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 * inputFilePattern;
-        /* null-terminated string, max MAXFILENAMELEN-10 characters */
     unsigned int across;
     unsigned int down;
-    unsigned int hoverlap; 
-    unsigned int voverlap; 
+    unsigned int hoverlap;
+    unsigned int voverlap;
+    const char * listfile;
+    unsigned int listfileSpec;
     unsigned int verbose;
 };
 
 
 
 static void
-parseCommandLine(int argc, char ** argv,
-                 struct cmdlineInfo * const cmdlineP ) {
+parseCommandLine(int argc, const char ** argv,
+                 struct CmdlineInfo * const cmdlineP ) {
 /*----------------------------------------------------------------------------
    parse program command line described in Unix standard form by argc
-   and argv.  Return the information in the options as *cmdlineP.  
+   and argv.  Return the information in the options as *cmdlineP.
 
    If command line is internally inconsistent (invalid options, etc.),
    issue error message to stderr and abort program.
@@ -53,7 +51,7 @@ parseCommandLine(int argc, char ** argv,
         /* Instructions to pm_optParseOptions3 on how to parse our options.
          */
     optStruct3 opt;
-    
+
     unsigned int acrossSpec, downSpec;
     unsigned int hoverlapSpec, voverlapSpec;
     unsigned int option_def_index;
@@ -69,6 +67,8 @@ parseCommandLine(int argc, char ** argv,
             &hoverlapSpec,                    0);
     OPTENT3(0, "voverlap",    OPT_UINT,    &cmdlineP->voverlap,
             &voverlapSpec,                    0);
+    OPTENT3(0, "listfile",    OPT_STRING,  &cmdlineP->listfile,
+            &cmdlineP->listfileSpec,          0);
     OPTENT3(0, "verbose",     OPT_FLAG,    NULL,
             &cmdlineP->verbose,               0);
 
@@ -76,13 +76,19 @@ parseCommandLine(int argc, char ** argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We have no parms that are negative numbers */
 
-    pm_optParseOptions3( &argc, argv, opt, sizeof(opt), 0 );
+    pm_optParseOptions3( &argc, (char **)argv, opt, sizeof(opt), 0 );
         /* Uses and sets argc, argv, and some of *cmdline_p and others. */
 
-    if (!acrossSpec)
+    if (acrossSpec) {
+        if (cmdlineP->across == 0)
+            pm_error ("-across value must be positive");
+    } else
         cmdlineP->across = 1;
-    
-    if (!downSpec)
+
+    if (downSpec) {
+        if (cmdlineP->down == 0)
+            pm_error ("-down value must be positive");
+    } else
         cmdlineP->down = 1;
 
     if (!hoverlapSpec)
@@ -91,16 +97,23 @@ parseCommandLine(int argc, char ** argv,
     if (!voverlapSpec)
         cmdlineP->voverlap = 0;
 
-    if (argc-1 < 1)
-        pm_error("You must specify one argument: the input file name "
-                 "pattern (e.g. 'myimage%%2a%%2d.pnm')");
-    else {
-        cmdlineP->inputFilePattern = argv[1];
-
-        if (argc-1 > 1)
-            pm_error("Progam takes at most one parameter: input file name.  "
-                     "You specified %u", argc-1);
+    if (cmdlineP->listfileSpec) {
+        if (argc-1 > 0)
+            pm_error("Program takes no parameters when -listfile is "
+                     "specified.  You specified %u", argc-1);
+        else
+            cmdlineP->inputFilePattern = NULL;
+    } else {
+        if (argc-1 < 1)
+            pm_error("You must specify one argument, the input file name "
+                     "pattern (e.g. 'myimage%%2a%%2d.pnm'), or -listfile");
+        else if (argc-1 > 1)
+            pm_error("Program takes at most one parameter: "
+                     "the input file name pattern.  You specified %u", argc-1);
+        else
+            cmdlineP->inputFilePattern = argv[1];
     }
+    free(option_def);
 }
 
 
@@ -128,7 +141,7 @@ buffer_init(struct buffer * const bufferP) {
 
 static void
 buffer_term(struct buffer * const bufferP) {
-    
+
     free(bufferP->string);
 }
 
@@ -184,7 +197,7 @@ getPrecision(const char *   const pattern,
     inCursor = startInCursor;  /* Start right after the '%' */
 
     precision = 0;
-                
+
     while (isdigit(pattern[inCursor])) {
         precision = 10 * precision + digitValue(pattern[inCursor]);
         ++inCursor;
@@ -202,13 +215,24 @@ getPrecision(const char *   const pattern,
 
 
 
+typedef struct {
+    /* Context of % substitutions as we progress through a file name pattern */
+    bool downSub;
+        /* There has been a %d (down) substitution */
+    bool acrossSub;
+        /* There has been a %a (across) substitution */
+} SubstContext;
+
+
+
 static void
 doSubstitution(const char *    const pattern,
                unsigned int    const startInCursor,
                unsigned int    const rank,
                unsigned int    const file,
                struct buffer * const bufferP,
-               unsigned int *  const newInCursorP) {
+               unsigned int *  const newInCursorP,
+               SubstContext *  const substContextP) {
 
     unsigned int inCursor;
 
@@ -219,7 +243,7 @@ doSubstitution(const char *    const pattern,
         ++inCursor;
     } else {
         unsigned int precision;
-        
+
         getPrecision(pattern, inCursor, &precision, &inCursor);
 
         if (pattern[inCursor] == '\0')
@@ -232,16 +256,28 @@ doSubstitution(const char *    const pattern,
 
             switch (pattern[inCursor]) {
             case 'a':
-                pm_asprintf(&substString, "%0*u", precision, file);
-                pm_asprintf(&desc, "file (across)");
+                if (substContextP->acrossSub)
+                    pm_error("Format specifier 'a' appears more than "
+                             "once in input file pattern '%s'", pattern);
+                else {
+                    pm_asprintf(&substString, "%0*u", precision, file);
+                    pm_asprintf(&desc, "file (across)");
+                    substContextP->acrossSub = true;
+                }
                 break;
             case 'd':
-                pm_asprintf(&substString, "%0*u", precision, rank);
-                pm_asprintf(&desc, "rank (down)");
+                if (substContextP->downSub)
+                    pm_error("Format specifier 'd' appears more than "
+                             "once in input file pattern '%s'", pattern);
+                else {
+                    pm_asprintf(&substString, "%0*u", precision, rank);
+                    pm_asprintf(&desc, "rank (down)");
+                    substContextP->downSub = true;
+                }
                 break;
             default:
                 pm_error("Unknown format specifier '%c' in input file "
-                         "pattern '%s'.  Recognized format specifier s are "
+                         "pattern '%s'.  Recognized format specifiers are "
                          "'%%a' (across) and '%%d (down)'",
                          pattern[inCursor], pattern);
             }
@@ -252,7 +288,7 @@ doSubstitution(const char *    const pattern,
                          desc, (unsigned)strlen(substString), precision);
             else
                 buffer_addString(bufferP, substString);
-            
+
             pm_strfree(desc);
             pm_strfree(substString);
 
@@ -268,25 +304,32 @@ static void
 computeInputFileName(const char *  const pattern,
                      unsigned int  const rank,
                      unsigned int  const file,
-                     const char ** const fileNameP) {
+                     const char ** const fileNameP,
+                     bool *        const rankFileIndependentP) {
 
     struct buffer buffer;
     unsigned int inCursor;
+    SubstContext substContext;
 
     buffer_init(&buffer);
 
     inCursor = 0;
+    substContext.downSub   = 0;
+    substContext.acrossSub = 0;
 
     while (pattern[inCursor] != '\0') {
         if (pattern[inCursor] == '%') {
             ++inCursor;
 
-            doSubstitution(pattern, inCursor, rank, file, &buffer, &inCursor);
+            doSubstitution(pattern, inCursor, rank, file, &buffer, &inCursor,
+                           &substContext);
 
         } else
             buffer_addChar(&buffer, pattern[inCursor++]);
     }
 
+    *rankFileIndependentP = !substContext.downSub && !substContext.acrossSub;
+
     pm_asprintf(fileNameP, "%s", buffer.string);
 
     buffer_term(&buffer);
@@ -295,8 +338,127 @@ computeInputFileName(const char *  const pattern,
 
 
 
+
+static void
+createInFileListFmFile(const char  *  const listFile,
+                       unsigned int   const nRank,
+                       unsigned int   const nFile,
+                       const char *** const inputFileListP) {
+
+    FILE * const lfP = pm_openr(listFile);
+    unsigned int const fileCt = nRank * nFile;
+
+    const char ** inputFileList;
+    unsigned int fileSeq;
+
+    MALLOCARRAY_NOFAIL(inputFileList, nRank * nFile);
+
+    for (fileSeq = 0; fileSeq < fileCt; ) {
+        int eof;
+        size_t lineLen;
+        char * buf = NULL;   /* initial value */
+        size_t bufferSz = 0; /* initial value */
+
+        pm_getline(lfP, &buf, &bufferSz, &eof, &lineLen);
+
+        if (eof)
+            pm_error("Premature EOF reading list file.  "
+                     "Read %u files.  Should be %u.", fileSeq, fileCt);
+        else if (lineLen > 0) {
+            inputFileList[fileSeq] = buf;
+            ++fileSeq;
+        }
+    }
+    pm_close(lfP);
+
+    *inputFileListP = inputFileList;
+
+}
+
+
+
+static void
+createInFileListFmPattern(const char  *  const pattern,
+                          unsigned int   const nRank,
+                          unsigned int   const nFile,
+                          const char *** const inputFileListP) {
+
+    const char ** inputFileList;
+    unsigned int rank, file;
+    bool warnedSingleFile;
+
+    MALLOCARRAY_NOFAIL(inputFileList, nRank * nFile);
+
+    for (rank = 0, warnedSingleFile = false; rank < nRank ; ++rank) {
+         for (file = 0; file < nFile ; ++file) {
+             const unsigned int idx = rank * nFile + file;
+
+             bool fileNmIsRankFileIndependent;
+
+             computeInputFileName(pattern, rank, file, &inputFileList[idx],
+                                  &fileNmIsRankFileIndependent);
+
+             if (fileNmIsRankFileIndependent && !warnedSingleFile) {
+                 pm_message("Warning: No grid location (%%a/%%d) specified "
+                            "in input file pattern '%s'.  "
+                            "Input is single file", pattern);
+                 warnedSingleFile = true;
+             }
+         }
+    }
+    *inputFileListP = inputFileList;
+}
+
+
+
+static void
+destroyInFileList(const char ** const inputFileList,
+                  unsigned int  const nRank,
+                  unsigned int  const nFile) {
+
+    unsigned int const fileCt = nRank * nFile;
+
+    unsigned int fileSeq;
+
+    for (fileSeq = 0; fileSeq < fileCt; ++fileSeq)
+        pm_strfree(inputFileList[fileSeq]);
+
+    free(inputFileList);
+}
+
+
+
+typedef struct {
+    unsigned int nRank;  /* Number of images in the vertical direction */
+    unsigned int nFile;  /* Number of images in the horizontal direction */
+    unsigned int hoverlap;    /* horizontal overlap */
+    unsigned int voverlap;    /* vertical overlap */
+    const char ** list;  /* List (1-dimensional array) of filenames */
+                         /* Row-major, top to bottom, left to right */
+} InputFiles;
+
+
+
+static const char *
+inputFileName(InputFiles     const inputFiles,
+              unsigned int   const rank,
+              unsigned int   const file) {
+/*----------------------------------------------------------------------------
+    A selected entry from "inputFiles.list" based on "rank" and "file".
+
+    Currently we assume that the list is a one-dimensional represetation
+    of an array, row-major, top to bottom and left to right in each row.
+----------------------------------------------------------------------------*/
+    assert(rank < inputFiles.nRank);
+    assert(file < inputFiles.nFile);
+
+    return inputFiles.list[rank * inputFiles.nFile + file];
+}
+
+
+
 static void
-getCommonInfo(const char *   const inputFilePattern,
+getCommonInfo(InputFiles     const inputFiles,
               int *          const formatP,
               unsigned int * const depthP,
               sample *       const maxvalP,
@@ -306,16 +468,12 @@ getCommonInfo(const char *   const inputFilePattern,
    among all input images and the output image.  I.e. everything except
    width and height.
 -----------------------------------------------------------------------------*/
-    const char * fileName;
-        /* Name of top left input image */
     FILE * ifP;
         /* Top left input image stream */
     struct pam inpam00;
         /* Description of top left input image */
 
-    computeInputFileName(inputFilePattern, 0, 0, &fileName);
-
-    ifP = pm_openr(fileName);
+    ifP = pm_openr(inputFileName(inputFiles, 0, 0));
 
     pnm_readpaminit(ifP, &inpam00, PAM_STRUCT_SIZE(tuple_type));
 
@@ -325,40 +483,19 @@ getCommonInfo(const char *   const inputFilePattern,
     strcpy(tupleType, inpam00.tuple_type);
 
     pm_close(ifP);
-
-    pm_strfree(fileName);
 }
 
 
 
-static FILE *
-openInputImage(const char * const inputFilePattern,
-               unsigned int const rank,
-               unsigned int const file) {
-
-    FILE * retval;
-    const char * fileName;
-        
-    computeInputFileName(inputFilePattern, rank, file, &fileName);
-
-    retval = pm_openr(fileName);
-    
-    pm_strfree(fileName);
-
-    return retval;
-}
-
-               
-
 static void
-getImageInfo(const char * const inputFilePattern,
+getImageInfo(InputFiles   const inputFiles,
              unsigned int const rank,
              unsigned int const file,
              struct pam * const pamP) {
 
     FILE * ifP;
 
-    ifP = openInputImage(inputFilePattern, rank, file);
+    ifP = pm_openr(inputFileName(inputFiles, rank, file));
 
     pnm_readpaminit(ifP, pamP, PAM_STRUCT_SIZE(tuple_type));
 
@@ -369,76 +506,70 @@ getImageInfo(const char * const inputFilePattern,
 
 
 static void
-getOutputWidth(const char * const inputFilePattern,
-               unsigned int const nFile,
-               unsigned int const hoverlap,
-               int *        const widthP) {
+getOutputWidth(InputFiles const inputFiles,
+               int *      const widthP) {
 /*----------------------------------------------------------------------------
-   Get the output width by adding up the widths of all 'nFile' images of
-   the top rank, and allowing for overlap of 'hoverlap' pixels.
+   Get the output width by adding up the widths of all 'inputFiles.nFile'
+   images of the top rank, and allowing for overlap of 'inputFiles.hoverlap'
+   pixels.
 -----------------------------------------------------------------------------*/
-    unsigned int totalWidth;
+    double       totalWidth;
     unsigned int file;
 
-    for (file = 0, totalWidth = 0; file < nFile; ++file) {
+    for (file = 0, totalWidth = 0; file < inputFiles.nFile; ++file) {
         struct pam inpam;
 
-        getImageInfo(inputFilePattern, 0, file, &inpam);
+        getImageInfo(inputFiles, 0, file, &inpam);
 
-        if (inpam.width < hoverlap)
+        if (inpam.width < inputFiles.hoverlap)
             pm_error("Rank 0, file %u image has width %u, "
                      "which is less than the horizontal overlap of %u pixels",
-                     file, inpam.width, hoverlap);
+                     file, inpam.width, inputFiles.hoverlap);
         else {
             totalWidth += inpam.width;
 
-            if (file < nFile-1)
-                totalWidth -= hoverlap;
+            if (file < inputFiles.nFile-1)
+                totalWidth -= inputFiles.hoverlap;
         }
     }
-    *widthP = totalWidth;
+    *widthP = (int) totalWidth;
 }
 
 
 
 static void
-getOutputHeight(const char *  const inputFilePattern,
-                unsigned int  const nRank,
-                unsigned int  const voverlap,
-                int *         const heightP) {
+getOutputHeight(InputFiles const inputFiles,
+                int *      const heightP) {
 /*----------------------------------------------------------------------------
-   Get the output height by adding up the widths of all 'nRank' images of
-   the left file, and allowing for overlap of 'voverlap' pixels.
+   Get the output height by adding up the widths of all 'inputFiles.nRank'
+   images of the left file, and allowing for overlap of 'inputFiles.voverlap'
+   pixels.
 -----------------------------------------------------------------------------*/
-    unsigned int totalHeight;
+    double       totalHeight;
     unsigned int rank;
 
-    for (rank = 0, totalHeight = 0; rank < nRank; ++rank) {
+    for (rank = 0, totalHeight = 0; rank < inputFiles.nRank; ++rank) {
         struct pam inpam;
 
-        getImageInfo(inputFilePattern, rank, 0, &inpam);
+        getImageInfo(inputFiles, rank, 0, &inpam);
 
-        if (inpam.height < voverlap)
+        if (inpam.height < inputFiles.voverlap)
             pm_error("Rank %u, file 0 image has height %u, "
                      "which is less than the vertical overlap of %u pixels",
-                     rank, inpam.height, voverlap);
-        
+                     rank, inpam.height, inputFiles.voverlap);
+
         totalHeight += inpam.height;
-        
-        if (rank < nRank-1)
-            totalHeight -= voverlap;
+
+        if (rank < inputFiles.nRank-1)
+            totalHeight -= inputFiles.voverlap;
     }
-    *heightP = totalHeight;
+    *heightP = (int) totalHeight;
 }
 
 
 
 static void
-initOutpam(const char * const inputFilePattern,
-           unsigned int const nFile,
-           unsigned int const nRank,
-           unsigned int const hoverlap,
-           unsigned int const voverlap,
+initOutpam(InputFiles   const inputFiles,
            FILE *       const ofP,
            bool         const verbose,
            struct pam * const outpamP) {
@@ -447,10 +578,10 @@ initOutpam(const char * const inputFilePattern,
    *outpamP.
 
    Do this by examining the top rank and left file of the input images,
-   which are in files named by 'inputFilePattern', 'nFile', and 'nRank'.
+   which are in 'inputFiles.list'.
 
-   In computing dimensions, assume 'hoverlap' pixels of horizontal
-   overlap and 'voverlap' pixels of vertical overlap.
+   In computing dimensions, assume 'inputFiles.hoverlap' pixels of horizontal
+   overlap and 'inputFiles.voverlap' pixels of vertical overlap.
 
    We overlook any inconsistencies among the images.  E.g. if two images
    have different depths, we just return one of them.  If two images in
@@ -459,23 +590,23 @@ initOutpam(const char * const inputFilePattern,
    Therefore, Caller must check all the input images to make sure they are
    consistent with the information we return.
 -----------------------------------------------------------------------------*/
-    assert(nFile >= 1);
-    assert(nRank >= 1);
+    assert(inputFiles.nFile >= 1);
+    assert(inputFiles.nRank >= 1);
 
     outpamP->size        = sizeof(*outpamP);
     outpamP->len         = PAM_STRUCT_SIZE(tuple_type);
     outpamP->file        = ofP;
     outpamP->plainformat = 0;
-    
-    getCommonInfo(inputFilePattern, &outpamP->format, &outpamP->depth,
+
+    getCommonInfo(inputFiles, &outpamP->format, &outpamP->depth,
                   &outpamP->maxval, outpamP->tuple_type);
 
-    getOutputWidth(inputFilePattern, nFile, hoverlap, &outpamP->width);
+    getOutputWidth(inputFiles,  &outpamP->width);
 
-    getOutputHeight(inputFilePattern, nRank, voverlap, &outpamP->height);
+    getOutputHeight(inputFiles, &outpamP->height);
 
     if (verbose) {
-        pm_message("Output width = %u pixels", outpamP->width);
+        pm_message("Output width = %u pixels",  outpamP->width);
         pm_message("Output height = %u pixels", outpamP->height);
     }
 }
@@ -485,53 +616,50 @@ initOutpam(const char * const inputFilePattern,
 static void
 openInStreams(struct pam         inpam[],
               unsigned int const rank,
-              unsigned int const fileCount,
-              char         const inputFilePattern[]) {
+              InputFiles   const inputFiles) {
 /*----------------------------------------------------------------------------
    Open the input files for a single horizontal slice (there's one file
    for each vertical slice) and read the Netpbm headers from them.  Return
    the pam structures to describe each as inpam[].
 
-   Open the files for horizontal slice number 'rank', assuming there are
-   'fileCount' vertical slices (so open 'fileCount' files).  Use
-   inputFilePattern[] with each rank and file number to compute the name of
-   each file.
+   Open the files for horizontal slice number 'rank', as described by
+   'inputFiles'.
 -----------------------------------------------------------------------------*/
     unsigned int file;
 
-    for (file = 0; file < fileCount; ++file) {
-        FILE * const ifP = openInputImage(inputFilePattern, rank, file);
+    for (file = 0; file < inputFiles.nFile; ++file) {
+        FILE * const ifP = pm_openr(inputFileName(inputFiles, rank, file));
 
         pnm_readpaminit(ifP, &inpam[file], PAM_STRUCT_SIZE(tuple_type));
-    }        
+    }
 }
 
 
 
 static void
 closeInFiles(struct pam         pam[],
-             unsigned int const fileCount) {
+             unsigned int const fileCt) {
 /*----------------------------------------------------------------------------
-   Close the 'fileCount' input file streams represented by pam[].
+   Close the 'fileCt' input file streams represented by pam[].
 -----------------------------------------------------------------------------*/
-    unsigned int file;
-    
-    for (file = 0; file < fileCount; ++file)
-        pm_close(pam[file].file);
+    unsigned int fileSeq;
+
+    for (fileSeq = 0; fileSeq < fileCt; ++fileSeq)
+        pm_close(pam[fileSeq].file);
 }
 
 
 
 static void
-assembleRow(tuple              outputRow[], 
-            struct pam         inpam[], 
-            unsigned int const fileCount,
+assembleRow(tuple              outputRow[],
+            struct pam         inpam[],
+            unsigned int const fileCt,
             unsigned int const hOverlap) {
 /*----------------------------------------------------------------------------
-   Assemble the row outputRow[] from the 'fileCount' input files
+   Assemble the row outputRow[] from the 'fileCt' input files
    described out inpam[].
 
-   'hOverlap', which is meaningful only when fileCount is greater than 1,
+   'hOverlap', which is meaningful only when 'fileCt' is greater than 1,
    is the amount by which files overlap each other.  We assume every
    input image is at least that wide.
 
@@ -539,19 +667,17 @@ assembleRow(tuple              outputRow[],
    entire assembly.
 -----------------------------------------------------------------------------*/
     tuple * inputRow;
-    unsigned int file;
+    unsigned int fileSeq;
 
-    for (file = 0, inputRow = &outputRow[0]; 
-         file < fileCount; 
-         ++file) {
+    for (fileSeq = 0, inputRow = &outputRow[0]; fileSeq < fileCt; ++fileSeq) {
 
-        unsigned int const overlap = file == fileCount - 1 ? 0 : hOverlap;
+        unsigned int const overlap = fileSeq == fileCt - 1 ? 0 : hOverlap;
 
-        assert(hOverlap <= inpam[file].width);
+        assert(hOverlap <= inpam[fileSeq].width);
 
-        pnm_readpamrow(&inpam[file], inputRow);
+        pnm_readpamrow(&inpam[fileSeq], inputRow);
 
-        inputRow += inpam[file].width - overlap;
+        inputRow += inpam[fileSeq].width - overlap;
     }
 }
 
@@ -574,6 +700,7 @@ allocInpam(unsigned int  const rankCount,
 
 
 
+
 static void
 verifyRankFileAttributes(struct pam *       const inpam,
                          unsigned int       const nFile,
@@ -622,7 +749,7 @@ verifyRankFileAttributes(struct pam *       const inpam,
                      rank, file, inpamP->height, inpam[0].height);
         else {
             totalWidth += inpamP->width;
-        
+
             if (file < nFile-1)
                 totalWidth -= hoverlap;
         }
@@ -637,11 +764,7 @@ verifyRankFileAttributes(struct pam *       const inpam,
 
 static void
 assembleTiles(struct pam * const outpamP,
-              const char * const inputFilePattern,
-              unsigned int const nFile,
-              unsigned int const nRank,
-              unsigned int const hoverlap,
-              unsigned int const voverlap,
+              InputFiles   const inputFiles,
               struct pam         inpam[],
               tuple *      const tuplerow) {
 
@@ -649,12 +772,17 @@ assembleTiles(struct pam * const outpamP,
         /* Number of the current rank (horizontal slice).  Ranks are numbered
            sequentially starting at 0.
         */
-    
+
+    unsigned int const nRank    = inputFiles.nRank;
+    unsigned int const nFile    = inputFiles.nFile;
+    unsigned int const hoverlap = inputFiles.hoverlap;
+    unsigned int const voverlap = inputFiles.voverlap;
+
     for (rank = 0; rank < nRank; ++rank) {
         unsigned int row;
         unsigned int rankHeight;
 
-        openInStreams(inpam, rank, nFile, inputFilePattern);
+        openInStreams(inpam, rank, inputFiles);
 
         verifyRankFileAttributes(inpam, nFile, outpamP, hoverlap, rank);
 
@@ -672,36 +800,47 @@ assembleTiles(struct pam * const outpamP,
 
 
 int
-main(int argc, char ** argv) {
+main(int argc, const char ** argv) {
 
-    struct cmdlineInfo cmdline;
+    struct CmdlineInfo cmdline;
+    InputFiles inputFiles;
     struct pam outpam;
     struct pam * inpam;
         /* malloc'ed.  inpam[x] is the pam structure that controls the
-           current rank of file x. 
+           current rank of file x.
         */
     tuple * tuplerow;
 
-    pnm_init(&argc, argv);
-    
+    pm_proginit(&argc, argv);
+
     parseCommandLine(argc, argv, &cmdline);
-        
+
     allocInpam(cmdline.across, &inpam);
 
-    initOutpam(cmdline.inputFilePattern, cmdline.across, cmdline.down,
-               cmdline.hoverlap, cmdline.voverlap, stdout, cmdline.verbose,
-               &outpam);
-    
+    if (cmdline.listfileSpec)
+        createInFileListFmFile(cmdline.listfile,
+                               cmdline.down, cmdline.across,
+                               &inputFiles.list);
+    else
+        createInFileListFmPattern(cmdline.inputFilePattern,
+                                  cmdline.down, cmdline.across,
+                                  &inputFiles.list);
+
+    inputFiles.nFile    = cmdline.across;
+    inputFiles.nRank    = cmdline.down;
+    inputFiles.hoverlap = cmdline.hoverlap;
+    inputFiles.voverlap = cmdline.voverlap;
+
+    initOutpam(inputFiles, stdout, cmdline.verbose, &outpam);
+
     tuplerow = pnm_allocpamrow(&outpam);
 
     pnm_writepaminit(&outpam);
 
-    assembleTiles(&outpam,
-                  cmdline.inputFilePattern, cmdline.across, cmdline.down,
-                  cmdline.hoverlap, cmdline.voverlap, inpam, tuplerow);
+    assembleTiles(&outpam, inputFiles, inpam, tuplerow);
 
     pnm_freepamrow(tuplerow);
-
+    destroyInFileList(inputFiles.list, inputFiles.nRank, inputFiles.nFile);
     free(inpam);
 
     return 0;
diff --git a/editor/pgmmedian.c b/editor/pgmmedian.c
index 4648af68..cdd94629 100644
--- a/editor/pgmmedian.c
+++ b/editor/pgmmedian.c
@@ -1,4 +1,4 @@
-/* 
+/*
 ** Version 1.0  September 28, 1996
 **
 ** Copyright (C) 1996 by Mike Burns <burns@cac.psu.edu>
@@ -15,11 +15,11 @@
 
 /* References
 ** ----------
-** The select k'th value implementation is based on Algorithm 489 by 
+** The select k'th value implementation is based on Algorithm 489 by
 ** Robert W. Floyd from the "Collected Algorithms from ACM" Volume II.
 **
 ** The histogram sort is based is described in the paper "A Fast Two-
-** Dimensional Median Filtering Algorithm" in "IEEE Transactions on 
+** Dimensional Median Filtering Algorithm" in "IEEE Transactions on
 ** Acoustics, Speech, and Signal Processing" Vol. ASSP-27, No. 1, February
 ** 1979.  The algorithm I more closely followed is found in "Digital
 ** Image Processing Algorithms" by Ioannis Pitas.
@@ -189,12 +189,11 @@ selectMedian(FILE *       const ifP,
     unsigned int const numValues = crows * ccols;
 
     unsigned int col;
-    gray * garray;
-        /* Array of the currenty gray values */
+    gray * garray;  /* Array of the currently gray values */
     int * parray;
     int * subcol;
     gray ** rowptr;
-    
+
     garray = pgm_allocrow(numValues);
 
     MALLOCARRAY(rowptr, crows);
@@ -212,7 +211,7 @@ selectMedian(FILE *       const ifP,
         int crow;
         int rownum, irow, temprow;
         unsigned int col;
-    
+
         pgm_readpgmrow(ifP, grays[row % crows], cols, maxval, format);
 
         /* Rotate pointers to rows, so rows can be accessed in order. */
@@ -334,7 +333,7 @@ histogramSortMedian(FILE *       const ifP,
                 for (mdn = 0; ltmdn <= median; ++mdn)
                     ltmdn += hist[mdn];
                 --mdn;
-                if (ltmdn > median) 
+                if (ltmdn > median)
                     ltmdn -= hist[mdn];
 
                 grayrow[col] = mdn;
@@ -374,7 +373,7 @@ histogramSortMedian(FILE *       const ifP,
                         ++mdn;
                     }
                     --mdn;
-                    if (ltmdn > median) 
+                    if (ltmdn > median)
                         ltmdn -= hist[mdn];
                 }
                 grayrow[col] = mdn;
@@ -410,7 +409,7 @@ main(int    argc,
     pgm_init(&argc, argv);
 
     parseCommandLine(argc, argv, &cmdline);
-    
+
     ifP = pm_openr(cmdline.inputFileName);
 
     ccolso2 = cmdline.width / 2;
@@ -446,7 +445,7 @@ main(int    argc,
     case SELECT_MEDIAN:
         selectMedian(ifP, cmdline.width, cmdline.height, cols, rows, median);
         break;
-        
+
     case HISTOGRAM_SORT_MEDIAN:
         histogramSortMedian(ifP, cmdline.width, cmdline.height,
                             cols, rows, median);
@@ -454,7 +453,7 @@ main(int    argc,
     case MEDIAN_UNSPECIFIED:
         pm_error("INTERNAL ERROR: median unspecified");
     }
-    
+
     pm_close(ifP);
     pm_close(stdout);
 
@@ -463,3 +462,6 @@ main(int    argc,
 
     return 0;
 }
+
+
+
diff --git a/editor/pnmcat.c b/editor/pnmcat.c
index a26dcf3e..565ecceb 100644
--- a/editor/pnmcat.c
+++ b/editor/pnmcat.c
@@ -358,9 +358,9 @@ getPbmImageInfo(struct imgInfo        const img[],
         case JUST_MAX:    img2[i].padtop = newrows - img[i].rows;       break;
         case JUST_CENTER: img2[i].padtop = (newrows - img[i].rows) / 2; break;
         }
-        
+
         img2[i].offset = (i == 0) ? 0 : img2[i-1].offset + img[i-1].cols;
-        
+
         if (img[i].rows == newrows)  /* no padding */
             img2[i].proberow = NULL;
         else {                   /* determine pad color for image i */
@@ -414,13 +414,13 @@ concatenateLeftRightPbm(FILE *             const ofP,
                         unsigned int       const newcols,
                         unsigned int       const newrows,
                         enum justification const justification,
-                        struct imgInfo     const img[],   
+                        struct imgInfo     const img[],
                         enum backcolor     const backcolor) {
 
     unsigned char * const outrow = pbm_allocrow_packed(newcols);
         /* We use just one outrow.  All padding and image data (with the
-           exeption of following img2.proberow) goes directly into this
-           packed PBM row. 
+           exception of following img2.proberow) goes directly into this
+           packed PBM row.
         */
 
     struct imgInfoPbm2 * img2;
@@ -496,7 +496,7 @@ concatenateTopBottomPbm(FILE *             const ofP,
 
     unsigned int i;
     unsigned int row, startRow;
-    
+
     outrow[pbm_packed_bytes(newcols)-1] = 0x00;
 
     switch (backcolor){
@@ -525,7 +525,7 @@ concatenateTopBottomPbm(FILE *             const ofP,
                 bit bgBit;
 
                 startRow = 1;
-                
+
                 pbm_readpbmrow_bitoffset(img[i].ifP,
                                          outrow, img[i].cols, img[i].format,
                                          padleft);
@@ -544,23 +544,23 @@ concatenateTopBottomPbm(FILE *             const ofP,
 
             if (backChange || (i > 0 && img[i-1].cols > img[i].cols)) {
                 unsigned int const padright = newcols - padleft - img[i].cols;
-                
+
                 if (padleft > 0)
                     padFillBitrow(outrow, background, padleft, 0);
-                
-                if (padright > 0)            
+
+                if (padright > 0)
                     padFillBitrow(outrow, background, padright,
                                   padleft + img[i].cols);
-                
+
             }
         }
-            
+
         if (startRow == 1)
             /* Top row already read for auto background color
                determination.  Write it out.
             */
             pbm_writepbmrow_packed(ofP, outrow, newcols, 0);
-        
+
         for (row = startRow; row < img[i].rows; ++row) {
             pbm_readpbmrow_bitoffset(img[i].ifP, outrow, img[i].cols,
                                      img[i].format, padleft);
@@ -685,7 +685,7 @@ concatenateLeftRightGen(FILE *             const ofP,
                 unsigned int col;
                 for (col = 0; col < img[i].cols; ++col)
                     img2[i].inrow[col] = img2[i].xelrow[col];
-                
+
                 free(img2[i].xelrow);
             } else if (row >= img2[i].padtop &&
                        row < img2[i].padtop + img[i].rows) {
@@ -745,7 +745,7 @@ concatenateTopBottomGen(FILE *             const ofP,
             startRow = 0;
             backChange = FALSE;
             inrow = newxelrow;
-        } else { /* Calculate left padding amount */ 
+        } else { /* Calculate left padding amount */
             switch (justification) {
             case JUST_MIN:    padleft = 0;                            break;
             case JUST_MAX:    padleft = newcols - img[i].cols;        break;
@@ -869,3 +869,6 @@ main(int           argc,
 
     return 0;
 }
+
+
+
diff --git a/editor/pnmconvol.c b/editor/pnmconvol.c
index b1d8e025..fcd52bea 100644
--- a/editor/pnmconvol.c
+++ b/editor/pnmconvol.c
@@ -1314,7 +1314,7 @@ computeInitialColumnSums(struct pam *              const pamP,
                          sample **                 const convColumnSum) {
 /*----------------------------------------------------------------------------
   Add up the sum of each column of window[][], whose rows are described
-  by *inpamP.  The window's height is that of tthe convolution kernel
+  by *inpamP.  The window's height is that of the convolution kernel
   *convKernelP.
 
   Return it as convColumnSum[][].
@@ -1854,7 +1854,7 @@ convolveHorizontalRowPlane(struct pam *              const pamP,
                            pamP->maxval);
         } else if (col == ccolso2) {
             unsigned int const leftcol = 0;
-                /* Window is up againt left edge of image */
+                /* Window is up against left edge of image */
 
             {
                 unsigned int ccol;
@@ -2019,7 +2019,7 @@ convolveVerticalRowPlane(struct pam *              const pamP,
 
             if (col == ccolso2) {
                 unsigned int const leftcol = 0;
-                    /* Convolution window is againt left edge of image */
+                    /* Convolution window is against left edge of image */
 
                 unsigned int ccol;
 
diff --git a/editor/pnmcrop.c b/editor/pnmcrop.c
index 6ef1c280..5e74190f 100644
--- a/editor/pnmcrop.c
+++ b/editor/pnmcrop.c
@@ -1136,7 +1136,7 @@ extremeCrops(struct CmdlineInfo const cmdline,
         pm_message("Input image has no distinction between "
                    "border and content");
 
-    /* We can't just pick a representive pixel, say top-left corner.
+    /* We can't just pick a representative pixel, say top-left corner.
        If -top and/or -bottom was specified but not -left and -right,
        the output should be one row, not a single pixel.
 
diff --git a/editor/pnmgamma.c b/editor/pnmgamma.c
index b357b0d8..1fdf20eb 100644
--- a/editor/pnmgamma.c
+++ b/editor/pnmgamma.c
@@ -602,7 +602,7 @@ createGammaTables(enum transferFunction const transferFunction,
     if (*rtableP == NULL || *gtableP == NULL || *btableP == NULL)
         pm_error("Can't get memory to make gamma transfer tables");
 
-    /* Build the gamma corection tables. */
+    /* Build the gamma correction tables. */
     switch (transferFunction) {
     case XF_BT709RAMP: {
         buildBt709Gamma(*rtableP, maxval, newMaxval, rgamma);
diff --git a/editor/pnmnlfilt.c b/editor/pnmnlfilt.c
index f55a67bd..bcb3680d 100644
--- a/editor/pnmnlfilt.c
+++ b/editor/pnmnlfilt.c
@@ -59,9 +59,9 @@ struct cmdlineInfo {
 };
 
 
-static void 
-parseCommandLine(int argc, 
-                 char ** argv, 
+static void
+parseCommandLine(int argc,
+                 char ** argv,
                  struct cmdlineInfo  * const cmdlineP) {
 
     if (argc-1 < 2)
@@ -75,9 +75,9 @@ parseCommandLine(int argc,
 
     if (sscanf( argv[2], "%lf", &cmdlineP->radius ) != 1)
         pm_error("Invalid radius (2nd) argument '%s'.  "
-                 "Must be a decimal number", 
+                 "Must be a decimal number",
                  argv[2]);
-    
+
     if ((cmdlineP->alpha > -0.1 && cmdlineP->alpha < 0.0) ||
         (cmdlineP->alpha > 0.5 && cmdlineP->alpha < 1.0))
         pm_error( "Alpha must be in range 0.0 <= alpha <= 0.5 "
@@ -118,11 +118,11 @@ parseCommandLine(int argc,
    this value.
 */
 
-#define MXIVAL PPM_MAXMAXVAL   
+#define MXIVAL PPM_MAXMAXVAL
 
-xelval omaxval; 
+xelval omaxval;
     /* global so that pixel processing code can get at it quickly */
-int noisevariance;      
+int noisevariance;
     /* global so that pixel processing code can get at it quickly */
 
 /*
@@ -157,7 +157,7 @@ static  xelval maxval;
 /* round and scale floating point to scaled integer */
 #define ROUNDSCALE(x) ((int)(((x) * (double)SCALE) + 0.5))
 /* round and un-scale scaled integer value */
-#define RUNSCALE(x) (((x) + (1 << (SCALEB-1))) >> SCALEB) 
+#define RUNSCALE(x) (((x) + (1 << (SCALEB-1))) >> SCALEB)
 /* rounded un-scale */
 #define UNSCALE(x) ((x) >> SCALEB)
 
@@ -194,9 +194,9 @@ int AVEDIV[7 * NOCSVAL];                /* divide by 7 to give average value */
 int SQUARE[2 * NOCSVAL];                /* scaled square lookup table */
 
 /* ************************************************** *
-   Hexagon intersecting square area functions 
-   Compute the area of the intersection of a triangle 
-   and a rectangle 
+   Hexagon intersecting square area functions
+   Compute the area of the intersection of a triangle
+   and a rectangle
    ************************************************** */
 
 /* Triangle orientation is per geometric axes (not graphical axies) */
@@ -210,7 +210,7 @@ int SQUARE[2 * NOCSVAL];                /* scaled square lookup table */
 
 #define SWAPI(a,b) (t = a, a = -b, b = -t)
 
-static double 
+static double
 triang_area(double rx0, double ry0, double rx1, double ry1,
             double tx0, double ty0, double tx1, double ty1,
             int tt) {
@@ -250,7 +250,7 @@ triang_area(double rx0, double ry0, double rx1, double ry1,
     a = tx0 - b * ty0;
     d = (ty1 - ty0)/(tx1 - tx0);
     c = ty0 - d * tx0;
-    
+
     /* compute top or right intersection */
     tt = 0;
     ly1 = ry1;
@@ -278,7 +278,7 @@ triang_area(double rx0, double ry0, double rx1, double ry1,
             return (rx1 - rx0) * (ry1 - ry0);
         tt |= 2;        /* bottom intersection */
     }
-    
+
     if (tt == 0) {
         /* top and left intersection */
         /* rectangle minus triangle */
@@ -293,7 +293,7 @@ triang_area(double rx0, double ry0, double rx1, double ry1,
         return ((rx1 - lx1) * (ry1 - ry0))
             + (0.5 * (lx1 - lx0) * (ry1 - ry0));
     } else {
-        /* tt == 3 */ 
+        /* tt == 3 */
         /* right and bottom intersection */
         /* triangle */
         return (0.5 * (rx1 - lx0) * (ly1 - ry0));
@@ -303,7 +303,7 @@ triang_area(double rx0, double ry0, double rx1, double ry1,
 
 
 static double
-rectang_area(double rx0, double ry0, double rx1, double ry1, 
+rectang_area(double rx0, double ry0, double rx1, double ry1,
              double tx0, double ty0, double tx1, double ty1) {
 /* Compute rectangle area */
 /* rx0,ry0,rx1,ry1:  rectangle boundaries */
@@ -326,7 +326,7 @@ rectang_area(double rx0, double ry0, double rx1, double ry1,
 
 
 
-static double 
+static double
 hex_area(double sx, double sy, double hx, double hy, double d) {
 /* compute the area of overlap of a hexagon diameter d, */
 /* centered at hx,hy, with a unit square of center sx,sy. */
@@ -384,7 +384,7 @@ setupSquare(void) {
 
     for (i=0; i < (2 * NOCSVAL); ++i) {
         /* compute square and rescale by (val >> (2 * SCALEB + 2)) table */
-        int const val = CSCTOSC(i - NOCSVAL); 
+        int const val = CSCTOSC(i - NOCSVAL);
         /* NOCSVAL offset to cope with -ve input values */
         SQUARE[i] = (val * val) >> (2 * SCALEB + 2);
     }
@@ -414,7 +414,7 @@ setup1(double   const alpha,
 
         *mmeanscaleP = *meanscaleP = maxscale/noinmean;
         if (alpha == 0.0) {
-            /* mean filter */ 
+            /* mean filter */
             *alpharangeP = 0;
             *alphafractionP = 0.0;            /* not used */
         } else if (alpha < (1.0/6.0)) {
@@ -438,9 +438,9 @@ setup1(double   const alpha,
         double const noinmean = 7.0;
         *alpharangeP = 5;                 /* edge enhancement function */
         *mmeanscaleP = *meanscaleP = maxscale;  /* compute scaled hex values */
-        *alphafractionP = 1.0/noinmean;   
+        *alphafractionP = 1.0/noinmean;
             /* Set up 1:1 division lookup - not used */
-        *noisevarianceP = sqr(alphaNormalized * omaxval) / 8.0;    
+        *noisevarianceP = sqr(alphaNormalized * omaxval) / 8.0;
             /* estimate of noise variance */
     } else if (alpha >= -0.9 && alpha <= -0.1) {
         /* edge enhancement function */
@@ -449,7 +449,7 @@ setup1(double   const alpha,
         *alpharangeP = 4;                 /* edge enhancement function */
         *meanscaleP = maxscale * (-posAlpha/((1.0 - posAlpha) * 7.0));
             /* mean of 7 and scaled by -posAlpha/(1-posAlpha) */
-        *mmeanscaleP = maxscale * (1.0/(1.0 - posAlpha) + *meanscaleP);    
+        *mmeanscaleP = maxscale * (1.0/(1.0 - posAlpha) + *meanscaleP);
             /* middle pixel has 1/(1-posAlpha) as well */
         *alphafractionP = 0.0;    /* not used */
     } else {
@@ -481,18 +481,18 @@ setupPixelWeightingTables(double const radius,
                           double const mmeanscale) {
 
     /* Setup pixel weighting tables - note we pre-compute mean
-       division here too. 
+       division here too.
     */
-    double const hexhoff = radius/2;      
+    double const hexhoff = radius/2;
         /* horizontal offset of vertical hex centers */
-    double const hexvoff = 3.0 * radius/sqrt(12.0); 
+    double const hexvoff = 3.0 * radius/sqrt(12.0);
         /* vertical offset of vertical hex centers */
 
     double const tabscale  = meanscale  / (radius * hexvoff);
     double const mtabscale = mmeanscale / (radius * hexvoff);
 
     /* scale tables to normalize by hexagon area, and number of
-       hexes used in mean 
+       hexes used in mean
     */
     double const v0 =
         hex_area(0.0,  0.0, hexhoff, hexvoff, radius) * tabscale;
@@ -538,7 +538,7 @@ setupPixelWeightingTables(double const radius,
 
 
 /* Table initialization function - return alpha range */
-static int 
+static int
 atfilt_setup(double const alpha,
              double const radius,
              double const maxscale) {
@@ -546,7 +546,7 @@ atfilt_setup(double const alpha,
     int alpharange;                 /* alpha range value 0 - 5 */
     double meanscale;               /* scale for finding mean */
     double mmeanscale;              /* scale for finding mean - midle hex */
-    double alphafraction;   
+    double alphafraction;
         /* fraction of next largest/smallest to subtract from sum */
 
     setup1(alpha, radius, maxscale,
@@ -562,7 +562,7 @@ atfilt_setup(double const alpha,
 
 
 
-static int 
+static int
 atfilt0(int * p) {
 /* Core pixel processing function - hand it 3x3 pixels and return result. */
 /* Mean filter */
@@ -586,7 +586,7 @@ atfilt0(int * p) {
         else if (xx < small) \
             small = xx; }
 
-static int 
+static int
 atfilt1(int * p) {
 /* Mean of 5 - 7 middle values */
 /* 'p' is 9 pixel values from 3x3 neighbors */
@@ -635,7 +635,7 @@ atfilt1(int * p) {
     }
 
 
-static int 
+static int
 atfilt2(int *p) {
 /* Mean of 3 - 5 middle values */
 /* 'p' is 9 pixel values from 3x3 neighbors */
@@ -708,10 +708,10 @@ atfilt2(int *p) {
                         small2 = xx; \
                                          }}
 
-static int 
+static int
 atfilt3(int *p) {
 /* Mean of 1 - 3 middle values. If only 1 value, then this is a median
-   filter. 
+   filter.
 */
 /* 'p' is pixel values from 3x3 neighbors */
     int h0,h1,h2,h3,h4,h5,h6;       /* hexagon values    2 3   */
@@ -737,12 +737,12 @@ atfilt3(int *p) {
     CHECK(h5);
     CHECK(h6);
     /* Compute mean of middle 1-3 values */
-    return  UNSCALE(h0 -big0 -big1 -small0 -small1 
+    return  UNSCALE(h0 -big0 -big1 -small0 -small1
                     -ALFRAC[(big2 + small2)>>SCALEB]);
 }
 #undef CHECK
 
-static int 
+static int
 atfilt4(int *p) {
 /* Edge enhancement */
 /* notice we use the global omaxval */
@@ -765,7 +765,7 @@ atfilt4(int *p) {
     return hav;
 }
 
-static int 
+static int
 atfilt5(int *p) {
 /* Optimal estimation - do smoothing in inverse proportion */
 /* to the local variance. */
@@ -786,19 +786,19 @@ atfilt5(int *p) {
     h6 = V0[p[0]] + V1[p[7]] + V2[p[8]] + V3[p[1]];
     mean = h0 + h1 + h2 + h3 + h4 + h5 + h6;
     mean = AVEDIV[SCTOCSC(mean)];   /* compute scaled mean by dividing by 7 */
-    temp = (h1 - mean); variance = SQUARE[NOCSVAL + SCTOCSC(temp)];  
+    temp = (h1 - mean); variance = SQUARE[NOCSVAL + SCTOCSC(temp)];
         /* compute scaled variance */
-    temp = (h2 - mean); variance += SQUARE[NOCSVAL + SCTOCSC(temp)]; 
+    temp = (h2 - mean); variance += SQUARE[NOCSVAL + SCTOCSC(temp)];
         /* and rescale to keep */
-    temp = (h3 - mean); variance += SQUARE[NOCSVAL + SCTOCSC(temp)]; 
+    temp = (h3 - mean); variance += SQUARE[NOCSVAL + SCTOCSC(temp)];
         /* within 32 bit limits */
     temp = (h4 - mean); variance += SQUARE[NOCSVAL + SCTOCSC(temp)];
     temp = (h5 - mean); variance += SQUARE[NOCSVAL + SCTOCSC(temp)];
     temp = (h6 - mean); variance += SQUARE[NOCSVAL + SCTOCSC(temp)];
-    temp = (h0 - mean); variance += SQUARE[NOCSVAL + SCTOCSC(temp)];   
+    temp = (h0 - mean); variance += SQUARE[NOCSVAL + SCTOCSC(temp)];
     /* (temp = h0 - mean) */
     if (variance != 0)      /* avoid possible divide by 0 */
-        temp = mean + (variance * temp) / (variance + noisevariance);   
+        temp = mean + (variance * temp) / (variance + noisevariance);
             /* optimal estimate */
     else temp = h0;
     if (temp < 0)
@@ -811,17 +811,17 @@ atfilt5(int *p) {
 
 
 
-static void 
+static void
 do_one_frame(FILE * const ifP) {
 
     pnm_writepnminit( stdout, cols, rows, omaxval, oformat, 0 );
-    
+
     if ( PNM_FORMAT_TYPE(oformat) == PPM_TYPE ) {
         int pr[9],pg[9],pb[9];          /* 3x3 neighbor pixel values */
         int r,g,b;
 
         for ( row = 0; row < rows; row++ ) {
-            int po,no;           /* offsets for left and right colums in 3x3 */
+            int po,no;          /* offsets for left and right columns in 3x3 */
             xel *ip0, *ip1, *ip2, *op;
 
             if (row == 0) {
@@ -897,14 +897,14 @@ do_one_frame(FILE * const ifP) {
         promote = ( PNM_FORMAT_TYPE(format) != PNM_FORMAT_TYPE(oformat) );
 
         for ( row = 0; row < rows; row++ ) {
-            int po,no;          /* offsets for left and right colums in 3x3 */
+            int po,no;          /* offsets for left and right columns in 3x3 */
             xel *ip0, *ip1, *ip2, *op;
 
             if (row == 0) {
                 irow0 = irow1;
                 pnm_readpnmrow( ifP, irow1, cols, maxval, format );
                 if ( promote )
-                    pnm_promoteformatrow( irow1, cols, maxval, 
+                    pnm_promoteformatrow( irow1, cols, maxval,
                                           format, maxval, oformat );
             }
             if (row == (rows-1))
@@ -912,7 +912,7 @@ do_one_frame(FILE * const ifP) {
             else {
                 pnm_readpnmrow( ifP, irow2, cols, maxval, format );
                 if ( promote )
-                    pnm_promoteformatrow( irow2, cols, maxval, 
+                    pnm_promoteformatrow( irow2, cols, maxval,
                                           format, maxval, oformat );
             }
 
@@ -955,7 +955,7 @@ do_one_frame(FILE * const ifP) {
 
 
 static void
-verifySame(unsigned int const imageSeq, 
+verifySame(unsigned int const imageSeq,
            int const imageCols, int const imageRows,
            xelval const imageMaxval, int const imageFormat,
            int const cols, int const rows,
@@ -1000,16 +1000,16 @@ main(int argc, char *argv[]) {
     ifP = pm_openr(cmdline.inputFileName);
 
     pnm_readpnminit(ifP, &cols, &rows, &maxval, &format);
-        
-    if (maxval > MXIVAL) 
+
+    if (maxval > MXIVAL)
         pm_error("The maxval of the input image (%d) is too large.\n"
-                 "This program's limit is %d.", 
+                 "This program's limit is %d.",
                  maxval, MXIVAL);
-        
+
     oformat = PNM_FORMAT_TYPE(format);
     /* force output to max precision without forcing new 2-byte format */
     omaxval = MIN(maxval, PPM_MAXMAXVAL);
-        
+
     atfunc = atfuncs[atfilt_setup(cmdline.alpha, cmdline.radius,
                                   (double)omaxval/(double)maxval)];
 
@@ -1038,7 +1038,7 @@ main(int argc, char *argv[]) {
             int imageFormat;
 
             ++imageSeq;
-            pnm_readpnminit(ifP, &imageCols, &imageRows, 
+            pnm_readpnminit(ifP, &imageCols, &imageRows,
                             &imageMaxval, &imageFormat);
             verifySame(imageSeq,
                        imageCols, imageRows, imageMaxval, imageFormat,
@@ -1054,3 +1054,6 @@ main(int argc, char *argv[]) {
 
     return 0;
 }
+
+
+
diff --git a/editor/pnmnorm.c b/editor/pnmnorm.c
index 2f9a6b20..e0fe0e35 100644
--- a/editor/pnmnorm.c
+++ b/editor/pnmnorm.c
@@ -274,7 +274,8 @@ minimumValue(const unsigned int * const hist,
             foundOne = true;
         else {
             if (i == highest)
-                pm_error("INTERNAL ERROR in '%s'.  No pixels", __FUNCTION__);
+                pm_error("INTERNAL ERROR in function 'minimumValue'.  "
+                         "No pixels");
             else
                 ++i;
         }
@@ -296,7 +297,8 @@ maximumValue(const unsigned int * const hist,
             foundOne = true;
         else {
             if (i == 0)
-                pm_error("INTERNAL ERROR in '%s'.  No pixels", __FUNCTION__);
+                pm_error("INTERNAL ERROR in function 'maximumValue'.  "
+                         "No pixels");
             else
                 --i;
         }
diff --git a/editor/pnmquantall b/editor/pnmquantall
index d268227d..aea6cc84 100755
--- a/editor/pnmquantall
+++ b/editor/pnmquantall
@@ -205,7 +205,6 @@ if (!defined($colorMapFh)) {
 if (!$progError) {
     makeColorMap(\@fileNames, $newColorCt, $colorMapFileName, \$progError);
 }
-print ("got color map\n");
 if (!$progError) {
     remapFiles(\@fileNames, $colorMapFileName, $ext, \$progError);
 }
diff --git a/editor/pnmshear.c b/editor/pnmshear.c
index c705c261..45d74c6f 100644
--- a/editor/pnmshear.c
+++ b/editor/pnmshear.c
@@ -54,7 +54,7 @@ parseCommandLine(int argc, const char ** argv,
     OPTENT3(0, "noantialias",      OPT_FLAG,  NULL, &cmdlineP->noantialias, 0);
     OPTENT3(0, "background",       OPT_STRING, &cmdlineP->background,
             &backgroundSpec, 0);
-    
+
     opt.opt_table = option_def;
     opt.short_allowed = FALSE;
     opt.allowNegNum = TRUE;
@@ -106,21 +106,21 @@ makeNewXel(xel *  const outputXelP,
     switch (PNM_FORMAT_TYPE(format)) {
     case PPM_TYPE:
         PPM_ASSIGN(*outputXelP,
-                   (fracnew0 * PPM_GETR(prevXel) 
-                    + omfracnew0 * PPM_GETR(curXel) 
+                   (fracnew0 * PPM_GETR(prevXel)
+                    + omfracnew0 * PPM_GETR(curXel)
                     + HALFSCALE) / SCALE,
-                   (fracnew0 * PPM_GETG(prevXel) 
-                    + omfracnew0 * PPM_GETG(curXel) 
+                   (fracnew0 * PPM_GETG(prevXel)
+                    + omfracnew0 * PPM_GETG(curXel)
                     + HALFSCALE) / SCALE,
-                   (fracnew0 * PPM_GETB(prevXel) 
-                    + omfracnew0 * PPM_GETB(curXel) 
+                   (fracnew0 * PPM_GETB(prevXel)
+                    + omfracnew0 * PPM_GETB(curXel)
                     + HALFSCALE) / SCALE );
         break;
-        
+
     default:
         PNM_ASSIGN1(*outputXelP,
-                    (fracnew0 * PNM_GET1(prevXel) 
-                     + omfracnew0 * PNM_GET1(curXel) 
+                    (fracnew0 * PNM_GET1(prevXel)
+                     + omfracnew0 * PNM_GET1(curXel)
                      + HALFSCALE) / SCALE );
         break;
     }
@@ -130,9 +130,9 @@ makeNewXel(xel *  const outputXelP,
 
 static void
 shearRow(xel *        const xelrow,
-         unsigned int const cols, 
+         unsigned int const cols,
          xel *        const newxelrow,
-         unsigned int const newcols, 
+         unsigned int const newcols,
          double       const shearCols,
          int          const format,
          xel          const bgxel,
@@ -140,7 +140,7 @@ shearRow(xel *        const xelrow,
 /*----------------------------------------------------------------------------
    Shear the row 'xelrow' by 'shearCols' columns, and return the result as
    'newxelrow'.  They are 'cols' and 'newcols' columns wide, respectively.
-   
+
    Fill in the part of the output row that doesn't contain image data with
    'bgxel'.
 
@@ -152,14 +152,14 @@ shearRow(xel *        const xelrow,
     unsigned int const intShearCols = (unsigned int) shearCols;
 
     assert(shearCols >= 0.0);
-        
+
     if (antialias) {
         const long fracnew0 = (shearCols - intShearCols) * SCALE;
         const long omfracnew0 = SCALE - fracnew0;
 
         unsigned int col;
         xel prevXel;
-            
+
         for (col = 0; col < newcols; ++col)
             newxelrow[col] = bgxel;
 
@@ -170,7 +170,7 @@ shearRow(xel *        const xelrow,
                        format);
             prevXel = xelrow[col];
         }
-        if (fracnew0 > 0) 
+        if (fracnew0 > 0)
             /* Need to add a column for what's left over */
             makeNewXel(&newxelrow[intShearCols + cols],
                        bgxel, prevXel, fracnew0, omfracnew0, format);
@@ -197,7 +197,7 @@ backgroundColor(const char * const backgroundColorName,
 
     if (backgroundColorName) {
         retval = pnm_parsecolorxel(backgroundColorName, maxval, format);
-    } else 
+    } else
         retval = pnm_backgroundxelrow(topRow, cols, maxval, format);
 
     return retval;
@@ -212,10 +212,13 @@ main(int argc, const char * argv[]) {
     xel * xelrow;
     xel * newxelrow;
     xel bgxel;
-    int rows, cols, format; 
-    int newformat, newcols; 
-    int row;
-    xelval maxval, newmaxval;
+    int rows, cols;
+    int format;
+    unsigned int newcols;
+    int newformat;
+    unsigned int row;
+    xelval maxval;
+    xelval newmaxval;
     double shearfac;
     double newcolsD;
 
@@ -230,6 +233,16 @@ main(int argc, const char * argv[]) {
     pnm_readpnminit(ifP, &cols, &rows, &maxval, &format);
     xelrow = pnm_allocrow(cols);
 
+    shearfac = tan(cmdline.angle);
+
+    newcolsD = (double) rows * fabs(shearfac) + cols + 0.999999;
+    if (newcolsD > INT_MAX-2)
+        pm_error("angle is too close to +/-90 degrees; "
+                 "output image too wide for computation");
+    else
+        newcols = (unsigned int) newcolsD;
+
+
     /* Promote PBM files to PGM. */
     if (!cmdline.noantialias && PNM_FORMAT_TYPE(format) == PBM_TYPE) {
         newformat = PGM_TYPE;
@@ -241,18 +254,9 @@ main(int argc, const char * argv[]) {
         newmaxval = maxval;
     }
 
-    shearfac = fabs(tan(cmdline.angle));
-
-    newcolsD = (double) rows * shearfac + cols + 0.999999;
-    if (newcolsD > INT_MAX-2)
-        pm_error("angle is too close to +/-90 degrees; "
-                 "output image too wide for computation");
-    else
-        newcols = (int) newcolsD;
-
     pnm_writepnminit(stdout, newcols, rows, newmaxval, newformat, 0);
     newxelrow = pnm_allocrow(newcols);
-    
+
     for (row = 0; row < rows; ++row) {
         double shearCols;
 
@@ -262,17 +266,17 @@ main(int argc, const char * argv[]) {
             bgxel = backgroundColor(cmdline.background,
                                     xelrow, cols, newmaxval, format);
 
-        if (cmdline.angle > 0.0)
+        if (shearfac > 0.0)
             shearCols = row * shearfac;
         else
-            shearCols = (rows - row) * shearfac;
+            shearCols = (rows - row) * -shearfac;
 
-        shearRow(xelrow, cols, newxelrow, newcols, 
+        shearRow(xelrow, cols, newxelrow, newcols,
                  shearCols, format, bgxel, !cmdline.noantialias);
 
         pnm_writepnmrow(stdout, newxelrow, newcols, newmaxval, newformat, 0);
     }
-    
+
     pm_close(ifP);
     pm_close(stdout);
 
diff --git a/editor/pnmstitch.c b/editor/pnmstitch.c
index eae5e1b9..4c4c708a 100644
--- a/editor/pnmstitch.c
+++ b/editor/pnmstitch.c
@@ -20,7 +20,7 @@
  * otherwise) arising in any way out of the use of this software, even if
  * advised of the possibility of such damage.
  *
- * Any restrictions or encumberances added to this source code or derivitives,
+ * Any restrictions or encumberances added to this source code or derivatives,
  * is prohibited.
  *
  *  Name: pnmstitch.c
@@ -1116,7 +1116,7 @@ OutputAlloc(Output     * const me,
 static void
 StraightThroughDeAlloc(Output * me)
 {
-    /* Trick the proper freeing of resouces on the Output Image */
+    /* Trick the proper freeing of resources on the Output Image */
     me->image->pam.height = 1;
     OutputDeAlloc(me);
 } /* StraightThroughDeAlloc() - end */
@@ -1131,7 +1131,7 @@ StraightThroughAlloc(Output     * const me,
     if (OutputAlloc(me, file, width, height, prototype) == FALSE) {
         StraightThroughDeAlloc(me);
     }
-    /* Trick the proper allocation of resouces on the Output Image */
+    /* Trick the proper allocation of resources on the Output Image */
     me->image->pam.height = 1;
     me->image->tuple = pnm_allocpamarray(&me->image->pam);
     if (me->image->tuple == (tuple **)NULL) {
diff --git a/editor/ppmshadow b/editor/ppmshadow
index ae6b1b0f..c07c03b0 100755
--- a/editor/ppmshadow
+++ b/editor/ppmshadow
@@ -89,7 +89,7 @@ sub imageDimensions($) {
 sub backgroundColor($) {
     my ($fileName) = @_;
 #-----------------------------------------------------------------------------
-#  Return the color of the backround of the image in the file named $fileName.
+#  Return the color of the background of the image in the file named $fileName.
 #-----------------------------------------------------------------------------
     # We call the color of the top left pixel the background color.
 
diff --git a/editor/specialty/pampaintspill.c b/editor/specialty/pampaintspill.c
index eb1888f7..c7994723 100644
--- a/editor/specialty/pampaintspill.c
+++ b/editor/specialty/pampaintspill.c
@@ -281,7 +281,7 @@ euclideanDistanceSqr(const struct coords * const p0,
                      unsigned int          const width,
                      unsigned int          const height) {
 /*----------------------------------------------------------------------------
-   Return the square of the Euclidian distance between p0 and p1.
+   Return the square of the Euclidean distance between p0 and p1.
 -----------------------------------------------------------------------------*/
     double const deltax = (double) (int) (p1->x - p0->x);
     double const deltay = (double) (int) (p1->y - p0->y);
@@ -299,7 +299,7 @@ euclideanDistanceTorusSqr(const struct coords * const p0,
                           unsigned int          const width,
                           unsigned int          const height) {
 /*----------------------------------------------------------------------------
-   Return the square of the Euclidian distance between p0 and p1, assuming
+   Return the square of the Euclidean distance between p0 and p1, assuming
    it's a toroidal surface on which the top row curves around to meet the
    bottom and the left column to the right.
 -----------------------------------------------------------------------------*/
diff --git a/editor/specialty/pampop9.c b/editor/specialty/pampop9.c
index d6c61e4f..b92c7d6b 100644
--- a/editor/specialty/pampop9.c
+++ b/editor/specialty/pampop9.c
@@ -25,9 +25,6 @@
 
 #include "pam.h"
 
-static const char * const copyright = 
-  "(c) Robert Tinsley 2003 (http://www.thepoacher.net/contact)";
-
 static const char *usagestr = "pnmfile|- xtiles ytiles xdelta ydelta";
 
 int main(int argc, char *argv[])
diff --git a/editor/specialty/pgmabel.c b/editor/specialty/pgmabel.c
index 1a6e481f..aa748f88 100644
--- a/editor/specialty/pgmabel.c
+++ b/editor/specialty/pgmabel.c
@@ -44,7 +44,7 @@ static const char* const version="$VER: pgmabel 1.009 (24 Jan 2002)";
 #include "pgm.h"
 
 #ifndef PID2          /*  PI/2 (on AMIGA always defined) */
-#define PID2    1.57079632679489661923  
+#define PID2    1.57079632679489661923
 #endif
 
 
@@ -59,7 +59,7 @@ static double *aldl, *ardl;                /* pointer for weighting factors */
 **      xr    <-  array of the calculated elements of the row
 **      adl   <-  pre-calculated surface coefficient for each segment
 */
-static double 
+static double
 Sum ( int n, double *xr, int N, double *adl)
 {
     int k;
@@ -79,7 +79,7 @@ Sum ( int n, double *xr, int N, double *adl)
 **      R, N  <-  indizes of the coefficient
 **      r     <-  radial position of the center of the surface
 */
-static double 
+static double
 dr ( int R, double r,  int N)
 {
     double a;
@@ -95,7 +95,7 @@ dr ( int R, double r,  int N)
 **        N    <-  width of the array
 **        adl  <-  array with pre-calculated weighting factors
 */
-static void 
+static void
 abel ( float *y, int N, double *adl)
 {
     register int n;
@@ -127,7 +127,7 @@ abel ( float *y, int N, double *adl)
 /* ----------------------------------------------------------------------------
 ** printing a help message if Option -h(elp) is chosen
 */
-static void 
+static void
 help()
 {
     pm_message("-----------------------------------------------------------------");
@@ -143,7 +143,7 @@ help()
     pm_message("|   verbose : output of useful data                             |");
     pm_message("|   pgmfile : Name of a pgmfile (optional)                      |");
     pm_message("|                                                               |");
-    pm_message("| for further information please contact the manpage            |"); 
+    pm_message("| for further information please contact the manpage            |");
     pm_message("-----------------------------------------------------------------");
     pm_message("%s",version);     /* telling the version      */
     exit(-1);                     /* retur-code for no result */
@@ -268,11 +268,11 @@ int main( argc, argv )
     }
     for (col = 0; col < (cols-midcol); ++col)      /* factors for right side */
     {
-        for (tc = 0; tc < (cols-midcol); ++tc) 
+        for (tc = 0; tc < (cols-midcol); ++tc)
             ardl[col*(cols-midcol)+tc] = dr(col,tc+0.5,cols-midcol);
     }
 
-    /* abel-transformation for each row splitted in right and left side      */
+    /* abel-transformation for each row split into right and left side      */
     for ( row = 0; row < rows ; ++row )
     {
         pgm_readpgmrow( ifp, grayorig, cols, maxval, format );
@@ -309,3 +309,5 @@ int main( argc, argv )
     exit( 0 );                       /* end of procedure                     */
 }
 
+
+