about summary refs log tree commit diff
path: root/other
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2019-09-07 21:18:02 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2019-09-07 21:18:02 +0000
commit8606c4e85e16ff97366511b472b96d993dd2711a (patch)
tree4ac297804a6bbdbc557f3a893340b7f3433aa431 /other
parentf9432b1fc13edfa2d84780a759aec0ffb5ac8e9f (diff)
downloadnetpbm-mirror-8606c4e85e16ff97366511b472b96d993dd2711a.tar.gz
netpbm-mirror-8606c4e85e16ff97366511b472b96d993dd2711a.tar.xz
netpbm-mirror-8606c4e85e16ff97366511b472b96d993dd2711a.zip
cleanup
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@3674 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'other')
-rw-r--r--other/pnmcolormap.c490
1 files changed, 273 insertions, 217 deletions
diff --git a/other/pnmcolormap.c b/other/pnmcolormap.c
index 7b644572..7da3122b 100644
--- a/other/pnmcolormap.c
+++ b/other/pnmcolormap.c
@@ -34,36 +34,41 @@
 #include "pam.h"
 #include "pammap.h"
 
-enum methodForLargest {LARGE_NORM, LARGE_LUM};
+enum MethodForLargest {LARGE_NORM, LARGE_LUM};
 
-enum methodForRep {REP_CENTER_BOX, REP_AVERAGE_COLORS, REP_AVERAGE_PIXELS};
+enum MethodForRep {REP_CENTER_BOX, REP_AVERAGE_COLORS, REP_AVERAGE_PIXELS};
 
-enum methodForSplit {SPLIT_MAX_PIXELS, SPLIT_MAX_COLORS, SPLIT_MAX_SPREAD};
+enum MethodForSplit {SPLIT_MAX_PIXELS, SPLIT_MAX_COLORS, SPLIT_MAX_SPREAD};
 
-typedef struct box* boxVector;
-struct box {
-    int ind;
-    int colors;
-    int sum;
+struct Box {
+    unsigned int index;
+    unsigned int colorCt;
+    unsigned int sum;
     unsigned int maxdim;
         /* which dimension has the largest spread.  RGB plane number. */
     sample       spread;
         /* spread in dimension 'maxdim' */
 };
 
-struct cmdlineInfo {
+struct BoxVector {
+    struct Box * box;  /* malloc'ed array */
+    unsigned int boxCt;
+    unsigned int capacity;
+};
+
+struct CmdlineInfo {
     /* All the information the user supplied in the command line,
        in a form easy for the program to use.
     */
-    const char *inputFilespec;  /* Filespec of input file */
+    const char * inputFileNm;  /* Name of input file */
     unsigned int allcolors;  /* boolean: select all colors from the input */
     unsigned int newcolors;
         /* Number of colors argument; meaningless if allcolors true */
-    enum methodForLargest methodForLargest;
+    enum MethodForLargest methodForLargest;
         /* -spreadintensity/-spreadluminosity options */
-    enum methodForRep methodForRep;
+    enum MethodForRep methodForRep;
         /* -center/-meancolor/-meanpixel options */
-    enum methodForSplit methodForSplit;
+    enum MethodForSplit methodForSplit;
         /* -splitpixelct/-splitcolorct/-splitspread options */
     unsigned int sort;
     unsigned int square;
@@ -73,8 +78,8 @@ struct cmdlineInfo {
 
 
 static void
-parseCommandLine (int argc, char ** argv,
-                  struct cmdlineInfo *cmdlineP) {
+parseCommandLine (int argc, const char ** argv,
+                  struct CmdlineInfo *cmdlineP) {
 /*----------------------------------------------------------------------------
    parse program command line described in Unix standard form by argc
    and argv.  Return the information in the options as *cmdlineP.
@@ -126,7 +131,7 @@ parseCommandLine (int argc, char ** argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We have no parms that are negative numbers */
 
-    pm_optParseOptions3( &argc, argv, opt, sizeof(opt), 0 );
+    pm_optParseOptions3( &argc, (char **)argv, opt, sizeof(opt), 0 );
         /* Uses and sets argc, argv, and some of *cmdline_p and others. */
 
 
@@ -163,9 +168,9 @@ parseCommandLine (int argc, char ** argv,
                  "You specified %d arguments.", argc-1);
     else {
         if (argc-1 < 2)
-            cmdlineP->inputFilespec = "-";
+            cmdlineP->inputFileNm = "-";
         else
-            cmdlineP->inputFilespec = argv[2];
+            cmdlineP->inputFileNm = argv[2];
 
         if (argc-1 < 1)
             pm_error("You must specify the number of colors in the "
@@ -210,8 +215,13 @@ compareplane(const void * const arg1,
     const struct tupleint * const * const comparandPP  = arg1;
     const struct tupleint * const * const comparatorPP = arg2;
 
-    return (*comparandPP)->tuple[compareplanePlane] -
-        (*comparatorPP)->tuple[compareplanePlane];
+    sample const comparandSample  = (*comparandPP) ->tuple[compareplanePlane];
+    sample const comparatorSample = (*comparatorPP)->tuple[compareplanePlane];
+
+    return
+        comparandSample < comparatorSample ? -1 :
+        comparandSample > comparatorSample ? 1 :
+        0;
 }
 
 
@@ -221,8 +231,16 @@ static qsort_comparison_fn sumcompare;
 #endif
 
 static int
-sumcompare(const void * const b1, const void * const b2) {
-    return(((boxVector)b2)->sum - ((boxVector)b1)->sum);
+sumcompare(const void * const arg1,
+           const void * const arg2) {
+
+    struct Box * const comparandP  = (struct Box *)arg1;
+    struct Box * const comparatorP = (struct Box *)arg2;
+
+    return
+        comparatorP->sum < comparandP->sum ? -1 :
+        comparatorP->sum > comparandP->sum ? 1 :
+        0;
 }
 
 
@@ -232,8 +250,16 @@ static qsort_comparison_fn colcompare;
 #endif
 
 static int
-colcompare(const void * const b1, const void * const b2) {
-      return(((boxVector)b2)->colors - ((boxVector)b1)->colors);
+colcompare(const void * const arg1,
+           const void * const arg2) {
+
+    struct Box * const comparandP  = (struct Box *)arg1;
+    struct Box * const comparatorP = (struct Box *)arg2;
+
+    return
+        comparatorP->colorCt < comparandP->colorCt ? -1 :
+        comparatorP->colorCt > comparandP->colorCt ? 1 :
+        0;
 }
 
 
@@ -243,35 +269,34 @@ static qsort_comparison_fn spreadcompare;
 #endif
 
 static int
-spreadcompare(const void * const b1, const void * const b2) {
+spreadcompare(const void * const arg1,
+              const void * const arg2) {
 
-    boxVector const box1P = (boxVector)(b1);
-    boxVector const box2P = (boxVector)(b2);
+    struct Box * const comparandP  = (struct Box *)arg1;
+    struct Box * const comparatorP = (struct Box *)arg2;
 
     return
-        box2P->spread > box1P->spread ? 1 :
-        box2P->spread < box1P->spread ? -1 :
+        comparatorP->spread < comparandP->spread ? -1 :
+        comparatorP->spread > comparandP->spread ? 1 :
         0;
 }
 
 
 
 static void
-sortBoxes(boxVector           const bv,
-          unsigned int        const boxCt,
-          enum methodForSplit const methodForSplit) {
+sortBoxes(struct BoxVector *  const boxVectorP,
+          enum MethodForSplit const methodForSplit) {
+
+    qsort_comparison_fn * comparisonFn;
 
     switch (methodForSplit){
-      case SPLIT_MAX_PIXELS:
-        qsort((char*) bv, boxCt, sizeof(struct box), sumcompare);
-        break;
-      case SPLIT_MAX_COLORS:
-        qsort((char*) bv, boxCt, sizeof(struct box), colcompare);
-        break;
-      case SPLIT_MAX_SPREAD:
-        qsort((char*) bv, boxCt, sizeof(struct box), spreadcompare);
-        break;
+    case SPLIT_MAX_PIXELS: comparisonFn = &sumcompare;    break;
+    case SPLIT_MAX_COLORS: comparisonFn = &colcompare;    break;
+    case SPLIT_MAX_SPREAD: comparisonFn = &spreadcompare; break;
     }
+
+    qsort((char*) &boxVectorP->box[0], boxVectorP->boxCt, sizeof(struct Box),
+          comparisonFn);
 }
 
 
@@ -282,48 +307,6 @@ sortBoxes(boxVector           const bv,
 ** Display", SIGGRAPH '82 Proceedings, page 297.
 */
 
-static tupletable2
-newColorMap(unsigned int const newcolors,
-            unsigned int const depth) {
-
-    tupletable2 colormap;
-    unsigned int i;
-    struct pam pam;
-
-    pam.depth = depth;
-
-    colormap.table = pnm_alloctupletable(&pam, newcolors);
-
-    for (i = 0; i < newcolors; ++i) {
-        unsigned int plane;
-        for (plane = 0; plane < depth; ++plane)
-            colormap.table[i]->tuple[plane] = 0;
-    }
-    colormap.size = newcolors;
-
-    return colormap;
-}
-
-
-
-static boxVector
-newBoxVector(int const colors, int const sum, int const newcolors) {
-
-    boxVector bv;
-    MALLOCARRAY(bv, newcolors);
-    if (bv == NULL)
-        pm_error("out of memory allocating box vector table");
-
-    /* Set up the initial box. */
-    bv[0].ind = 0;
-    bv[0].colors = colors;
-    bv[0].sum = sum;
-
-    return bv;
-}
-
-
-
 static void
 findBoxBoundaries(tupletable2  const colorfreqtable,
                   unsigned int const depth,
@@ -332,8 +315,8 @@ findBoxBoundaries(tupletable2  const colorfreqtable,
                   sample             minval[],
                   sample             maxval[]) {
 /*----------------------------------------------------------------------------
-  Go through the box finding the minimum and maximum of each
-  component - the boundaries of the box.
+  Go through the box finding the minimum and maximum of each component - the
+  boundaries of the box.
 -----------------------------------------------------------------------------*/
     unsigned int plane;
     unsigned int i;
@@ -418,6 +401,100 @@ findPlaneWithLargestSpreadByLuminosity(sample         const minval[],
 
 
 static void
+computeBoxSpread(const struct Box *    const boxP,
+                 tupletable2           const colorfreqtable,
+                 unsigned int          const depth,
+                 enum MethodForLargest const methodForLargest,
+                 unsigned int *        const planeWithLargestP,
+                 sample *              const spreadP
+                 ) {
+/*----------------------------------------------------------------------------
+  Find the spread in the dimension in which it is greatest.
+
+  Return as *planeWithLargestP the number of that plane and as *spreadP the
+  spread in that plane.
+-----------------------------------------------------------------------------*/
+    sample * minval;  /* malloc'ed array */
+    sample * maxval;  /* malloc'ed array */
+
+    MALLOCARRAY_NOFAIL(minval, depth);
+    MALLOCARRAY_NOFAIL(maxval, depth);
+
+    findBoxBoundaries(colorfreqtable, depth, boxP->index, boxP->colorCt,
+                      minval, maxval);
+
+    switch (methodForLargest) {
+    case LARGE_NORM:
+        findPlaneWithLargestSpreadByNorm(minval, maxval, depth,
+                                         planeWithLargestP, spreadP);
+        break;
+    case LARGE_LUM:
+        findPlaneWithLargestSpreadByLuminosity(minval, maxval, depth,
+                                               planeWithLargestP, spreadP);
+        break;
+    }
+    free(minval); free(maxval);
+}
+
+
+
+static unsigned int
+freqTotal(tupletable2 const freqtable) {
+
+    unsigned int i;
+    unsigned int sum;
+
+    for (i = 0, sum = 0; i < freqtable.size; ++i)
+        sum += freqtable.table[i]->value;
+
+    return sum;
+}
+
+
+
+static struct BoxVector
+newBoxVector(tupletable2           const colorfreqtable,
+             unsigned int          const capacity,
+             unsigned int          const depth,
+             enum MethodForLargest const methodForLargest) {
+
+    unsigned int const colorCt = colorfreqtable.size;
+    unsigned int const sum     = freqTotal(colorfreqtable);
+
+    struct BoxVector boxVector;
+
+    MALLOCARRAY(boxVector.box, capacity);
+
+    if (!boxVector.box)
+        pm_error("out of memory allocating box vector table");
+
+    /* Set up the initial box. */
+    boxVector.box[0].index   = 0;
+    boxVector.box[0].colorCt = colorCt;
+    boxVector.box[0].sum     = sum;
+
+    computeBoxSpread(&boxVector.box[0], colorfreqtable, depth,
+                     methodForLargest,
+                     &boxVector.box[0].maxdim,
+                     &boxVector.box[0].spread);
+
+    boxVector.boxCt    = 1;
+    boxVector.capacity = capacity;
+
+    return boxVector;
+}
+
+
+
+static void
+destroyBoxVector(struct BoxVector const boxVector) {
+
+    free(boxVector.box);
+}
+
+
+
+static void
 centerBox(int          const boxStart,
           int          const boxSize,
           tupletable2  const colorfreqtable,
@@ -443,6 +520,30 @@ centerBox(int          const boxStart,
 
 
 
+static tupletable2
+newColorMap(unsigned int const colorCt,
+            unsigned int const depth) {
+
+    tupletable2 colormap;
+    unsigned int i;
+    struct pam pam;
+
+    pam.depth = depth;
+
+    colormap.table = pnm_alloctupletable(&pam, colorCt);
+
+    for (i = 0; i < colorCt; ++i) {
+        unsigned int plane;
+        for (plane = 0; plane < depth; ++plane)
+            colormap.table[i]->tuple[plane] = 0;
+    }
+    colormap.size = colorCt;
+
+    return colormap;
+}
+
+
+
 static void
 averageColors(int          const boxStart,
               int          const boxSize,
@@ -502,12 +603,11 @@ averagePixels(int          const boxStart,
 
 
 static tupletable2
-colormapFromBv(unsigned int      const newcolors,
-               boxVector         const bv,
-               unsigned int      const boxes,
+colormapFromBv(unsigned int      const colorCt,
+               struct BoxVector  const boxVector,
                tupletable2       const colorfreqtable,
                unsigned int      const depth,
-               enum methodForRep const methodForRep) {
+               enum MethodForRep const methodForRep) {
     /*
     ** Ok, we've got enough boxes.  Now choose a representative color for
     ** each box.  There are a number of possible ways to make this choice.
@@ -517,23 +617,29 @@ colormapFromBv(unsigned int      const newcolors,
     ** method is to average all the pixels in the box.
     */
     tupletable2 colormap;
-    unsigned int bi;
+    unsigned int boxIdx;
 
-    colormap = newColorMap(newcolors, depth);
+    colormap = newColorMap(colorCt, depth);
 
-    for (bi = 0; bi < boxes; ++bi) {
+    for (boxIdx = 0; boxIdx < boxVector.boxCt; ++boxIdx) {
         switch (methodForRep) {
         case REP_CENTER_BOX:
-            centerBox(bv[bi].ind, bv[bi].colors, colorfreqtable, depth,
-                      colormap.table[bi]->tuple);
+            centerBox(boxVector.box[boxIdx].index,
+                      boxVector.box[boxIdx].colorCt,
+                      colorfreqtable, depth,
+                      colormap.table[boxIdx]->tuple);
             break;
         case REP_AVERAGE_COLORS:
-            averageColors(bv[bi].ind, bv[bi].colors, colorfreqtable, depth,
-                          colormap.table[bi]->tuple);
+            averageColors(boxVector.box[boxIdx].index,
+                          boxVector.box[boxIdx].colorCt,
+                          colorfreqtable, depth,
+                          colormap.table[boxIdx]->tuple);
             break;
         case REP_AVERAGE_PIXELS:
-            averagePixels(bv[bi].ind, bv[bi].colors, colorfreqtable, depth,
-                          colormap.table[bi]->tuple);
+            averagePixels(boxVector.box[boxIdx].index,
+                          boxVector.box[boxIdx].colorCt,
+                          colorfreqtable, depth,
+                          colormap.table[boxIdx]->tuple);
             break;
         default:
             pm_error("Internal error: invalid value of methodForRep: %d",
@@ -545,126 +651,77 @@ colormapFromBv(unsigned int      const newcolors,
 
 
 
-static unsigned int
-freqTotal(tupletable2 const freqtable) {
-
-    unsigned int i;
-    unsigned int sum;
-
-    sum = 0;
-
-    for (i = 0; i < freqtable.size; ++i)
-        sum += freqtable.table[i]->value;
-
-    return sum;
-}
-
-
-
 static void
-computeBoxSpread(const struct box *    const boxP,
-                 tupletable2           const colorfreqtable,
-                 unsigned int          const depth,
-                 enum methodForLargest const methodForLargest,
-                 unsigned int *        const planeWithLargestP,
-                 sample *              const spreadP
-                 ) {
-/*----------------------------------------------------------------------------
-  Find the spread in the dimension in which it is greatest.
-
-  Return as *planeWithLargestP the number of that plane and as *spreadP the
-  spread in that plane.
------------------------------------------------------------------------------*/
-    sample * minval;  /* malloc'ed array */
-    sample * maxval;  /* malloc'ed array */
-
-    MALLOCARRAY_NOFAIL(minval, depth);
-    MALLOCARRAY_NOFAIL(maxval, depth);
-
-    findBoxBoundaries(colorfreqtable, depth, boxP->ind, boxP->colors,
-                      minval, maxval);
-
-    switch (methodForLargest) {
-    case LARGE_NORM:
-        findPlaneWithLargestSpreadByNorm(minval, maxval, depth,
-                                         planeWithLargestP, spreadP);
-        break;
-    case LARGE_LUM:
-        findPlaneWithLargestSpreadByLuminosity(minval, maxval, depth,
-                                               planeWithLargestP, spreadP);
-        break;
-    }
-    free(minval); free(maxval);
-}
-
-
-
-static void
-splitBox(boxVector             const bv,
-         unsigned int *        const boxesP,
-         unsigned int          const bi,
+splitBox(struct BoxVector *    const boxVectorP,
+         unsigned int          const boxIdx,
          tupletable2           const colorfreqtable,
          unsigned int          const depth,
-         enum methodForLargest const methodForLargest,
-         enum methodForSplit   const methodForSplit) {
+         enum MethodForLargest const methodForLargest,
+         enum MethodForSplit   const methodForSplit) {
 /*----------------------------------------------------------------------------
-   Split Box 'bi' in the box vector bv (so that bv contains one more box
-   than it did as input).  Split it so that each new box represents about
-   half of the pixels in the distribution given by 'colorfreqtable' for
-   the colors in the original box, but with distinct colors in each of the
-   two new boxes.
+   Split Box 'boxIdx' in the box vector 'boxVector' (so that bv contains one
+   more box than it did as input).  Split it so that each new box represents
+   about half of the pixels in the distribution given by 'colorfreqtable' for
+   the colors in the original box, but with distinct colors in each of the two
+   new boxes.
 
    Assume the box contains at least two colors.
 -----------------------------------------------------------------------------*/
-    unsigned int const boxStart = bv[bi].ind;
-    unsigned int const boxSize  = bv[bi].colors;
-    unsigned int const sm       = bv[bi].sum;
+    unsigned int const boxStart = boxVectorP->box[boxIdx].index;
+    unsigned int const boxSize  = boxVectorP->box[boxIdx].colorCt;
+    unsigned int const sum      = boxVectorP->box[boxIdx].sum;
 
     unsigned int medianIndex;
     int lowersum;
         /* Number of pixels whose value is "less than" the median */
 
 
-    /* TODO: I think this sort should go after creating a box,
-       not before splitting.  Because you need the sort to use
-       the REP_CENTER_BOX method of choosing a color to
-       represent the final boxes
+    /* Perhaps this sort should go after creating a box, not before splitting.
+       Because you need the sort to use the REP_CENTER_BOX method of choosing
+       a color to represent the final boxes
     */
 
     /* Set the gross global variable 'compareplanePlane' as a
        parameter to compareplane(), which is called by qsort().
     */
-    compareplanePlane = bv[bi].maxdim;
+    compareplanePlane = boxVectorP->box[boxIdx].maxdim;
     qsort((char*) &colorfreqtable.table[boxStart], boxSize,
           sizeof(colorfreqtable.table[boxStart]),
           compareplane);
 
     {
-        /* Now find the median based on the counts, so that about half
-           the pixels (not colors, pixels) are in each subdivision.  */
-
+        /* Find the median based on the counts, so that about half the pixels
+           (not colors, pixels) are in each subdivision.
+        */
         unsigned int i;
 
         lowersum = colorfreqtable.table[boxStart]->value; /* initial value */
-        for (i = 1; i < boxSize - 1 && lowersum < sm/2; ++i) {
+        for (i = 1; i < boxSize - 1 && lowersum < sum/2; ++i) {
             lowersum += colorfreqtable.table[boxStart + i]->value;
         }
         medianIndex = i;
     }
     /* Split the box, and sort to bring the biggest boxes to the top.  */
-    bv[bi].colors = medianIndex;
-    bv[bi].sum = lowersum;
-    computeBoxSpread(&bv[bi], colorfreqtable, depth, methodForLargest,
-                     &bv[bi].maxdim, &bv[bi].spread);
-
-    bv[*boxesP].ind = boxStart + medianIndex;
-    bv[*boxesP].colors = boxSize - medianIndex;
-    bv[*boxesP].sum = sm - lowersum;
-    computeBoxSpread(&bv[*boxesP], colorfreqtable, depth, methodForLargest,
-                     &bv[*boxesP].maxdim, &bv[*boxesP].spread);
-    ++(*boxesP);
-
-    sortBoxes(bv, *boxesP, methodForSplit);
+    {
+        struct Box * const oldBoxP = &boxVectorP->box[boxIdx];
+
+        oldBoxP->colorCt = medianIndex;
+        oldBoxP->sum     = lowersum;
+        computeBoxSpread(oldBoxP, colorfreqtable, depth, methodForLargest,
+                         &oldBoxP->maxdim, &oldBoxP->spread);
+    }
+    {
+        struct Box * const newBoxP = &boxVectorP->box[boxVectorP->boxCt];
+
+        newBoxP->index   = boxStart + medianIndex;
+        newBoxP->colorCt = boxSize - medianIndex;
+        newBoxP->sum     = sum - lowersum;
+        computeBoxSpread(newBoxP, colorfreqtable, depth, methodForLargest,
+                         &newBoxP->maxdim, &newBoxP->spread);
+        ++boxVectorP->boxCt;
+    }
+
+    sortBoxes(boxVectorP, methodForSplit);
 }
 
 
@@ -672,13 +729,13 @@ splitBox(boxVector             const bv,
 static void
 mediancut(tupletable2           const colorfreqtable,
           unsigned int          const depth,
-          int                   const newcolors,
-          enum methodForLargest const methodForLargest,
-          enum methodForRep     const methodForRep,
-          enum methodForSplit   const methodForSplit,
+          int                   const newcolorCt,
+          enum MethodForLargest const methodForLargest,
+          enum MethodForRep     const methodForRep,
+          enum MethodForSplit   const methodForSplit,
           tupletable2 *         const colormapP) {
 /*----------------------------------------------------------------------------
-   Compute a set of only 'newcolors' colors that best represent an
+   Compute a set of only 'newcolorCt' colors that best represent an
    image whose pixels are summarized by the histogram
    'colorfreqtable'.  Each tuple in that table has depth 'depth'.
    colorfreqtable.table[i] tells the number of pixels in the subject image
@@ -686,37 +743,36 @@ mediancut(tupletable2           const colorfreqtable,
 
    As a side effect, sort 'colorfreqtable'.
 -----------------------------------------------------------------------------*/
-    boxVector bv;
-    unsigned int bi;
-    unsigned int boxes;
+    struct BoxVector boxVector;
     bool multicolorBoxesExist;
         /* There is at least one box that contains at least 2 colors; ergo,
            there is more splitting we can do.
         */
 
-    bv = newBoxVector(colorfreqtable.size, freqTotal(colorfreqtable),
-                      newcolors);
+    boxVector = newBoxVector(colorfreqtable, newcolorCt, depth,
+                             methodForLargest);
 
-    computeBoxSpread(&bv[0], colorfreqtable, depth, methodForLargest,
-                     &bv[0].maxdim, &bv[0].spread);
-
-    boxes = 1;
     multicolorBoxesExist = (colorfreqtable.size > 1);
 
-    /* Main loop: split boxes until we have enough. */
-    while (boxes < newcolors && multicolorBoxesExist) {
-        /* Find the first splittable box. */
-        for (bi = 0; bi < boxes && bv[bi].colors < 2; ++bi);
-        if (bi >= boxes)
+    /* Split boxes until we have enough. */
+    while (boxVector.boxCt < newcolorCt && multicolorBoxesExist) {
+        unsigned int boxIdx;
+
+        for (boxIdx = 0;
+             boxIdx < boxVector.boxCt && boxVector.box[boxIdx].colorCt < 2;
+             ++boxIdx);
+            /* Find the first splittable box. */
+
+        if (boxIdx >= boxVector.boxCt)
             multicolorBoxesExist = FALSE;
         else
-            splitBox(bv, &boxes, bi, colorfreqtable, depth,
+            splitBox(&boxVector, boxIdx, colorfreqtable, depth,
                      methodForLargest, methodForSplit);
     }
-    *colormapP = colormapFromBv(newcolors, bv, boxes, colorfreqtable, depth,
-                                methodForRep);
+    *colormapP = colormapFromBv(newcolorCt, boxVector, colorfreqtable,
+                                depth, methodForRep);
 
-    free(bv);
+    destroyBoxVector(boxVector);
 }
 
 
@@ -844,9 +900,9 @@ static void
 computeColorMapFromInput(FILE *                const ifP,
                          bool                  const allColors,
                          int                   const reqColors,
-                         enum methodForLargest const methodForLargest,
-                         enum methodForRep     const methodForRep,
-                         enum methodForSplit   const methodForSplit,
+                         enum MethodForLargest const methodForLargest,
+                         enum MethodForRep     const methodForRep,
+                         enum MethodForSplit   const methodForSplit,
                          int *                 const formatP,
                          struct pam *          const freqPamP,
                          tupletable2 *         const colormapP) {
@@ -1039,9 +1095,9 @@ colormapToImage(int                const format,
 
 
 int
-main(int argc, char * argv[] ) {
+main(int argc, const char * argv[] ) {
 
-    struct cmdlineInfo cmdline;
+    struct CmdlineInfo cmdline;
     FILE * ifP;
     int format;
     struct pam colormapPam;
@@ -1049,11 +1105,11 @@ main(int argc, char * argv[] ) {
     tuple ** colormapRaster;
     tupletable2 colormap;
 
-    pnm_init(&argc, argv);
+    pm_proginit(&argc, argv);
 
     parseCommandLine(argc, argv, &cmdline);
 
-    ifP = pm_openr(cmdline.inputFilespec);
+    ifP = pm_openr(cmdline.inputFileNm);
 
     computeColorMapFromInput(ifP,
                              cmdline.allcolors, cmdline.newcolors,