about summary refs log tree commit diff
path: root/generator/ppmpat.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2009-05-03 01:20:29 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2009-05-03 01:20:29 +0000
commit5444dd409430932c3a7e05558531578dde38d89c (patch)
tree7f2eb2a201159ae8f22292060958663e52c24e66 /generator/ppmpat.c
parent34f721e0f92ade7ab4e11bbab4968b6fd705aeff (diff)
downloadnetpbm-mirror-5444dd409430932c3a7e05558531578dde38d89c.tar.gz
netpbm-mirror-5444dd409430932c3a7e05558531578dde38d89c.tar.xz
netpbm-mirror-5444dd409430932c3a7e05558531578dde38d89c.zip
cleanup, fix a few bugs
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@911 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'generator/ppmpat.c')
-rw-r--r--generator/ppmpat.c1036
1 files changed, 571 insertions, 465 deletions
diff --git a/generator/ppmpat.c b/generator/ppmpat.c
index afefae0e..cfb027bf 100644
--- a/generator/ppmpat.c
+++ b/generator/ppmpat.c
@@ -14,6 +14,7 @@
 
 #include <assert.h>
 #include <math.h>
+#include <limits.h>
 
 #include "pm_c_util.h"
 #include "mallocvar.h"
@@ -30,8 +31,7 @@ typedef enum {
     PAT_POLES,
     PAT_SQUIG,
     PAT_CAMO,
-    PAT_ANTICAMO,
-    PAT_TEST
+    PAT_ANTICAMO
 } pattern;
 
 struct cmdlineInfo {
@@ -67,7 +67,6 @@ parseCommandLine(int argc, const char ** argv,
     unsigned int squig;
     unsigned int camo;
     unsigned int anticamo;
-    unsigned int test;
 
     MALLOCARRAY_NOFAIL(option_def, 100);
 
@@ -82,7 +81,6 @@ parseCommandLine(int argc, const char ** argv,
     OPTENT3(0, "squig",     OPT_FLAG,   NULL, &squig,      0);
     OPTENT3(0, "camo",      OPT_FLAG,   NULL, &camo,       0);
     OPTENT3(0, "anticamo",  OPT_FLAG,   NULL, &anticamo,   0);
-    OPTENT3(0, "test",      OPT_FLAG,   NULL, &test,       0);
 
     opt.opt_table = option_def;
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
@@ -99,8 +97,7 @@ parseCommandLine(int argc, const char ** argv,
         poles +
         squig +
         camo +
-        anticamo +
-        test;
+        anticamo;
 
     if (basePatternCount < 1)
         pm_error("You must specify a base pattern option such as -gingham2");
@@ -124,8 +121,6 @@ parseCommandLine(int argc, const char ** argv,
             cmdlineP->basePattern = PAT_CAMO;
         else if (anticamo)
             cmdlineP->basePattern = PAT_ANTICAMO;
-        else if (test)
-            cmdlineP->basePattern = PAT_TEST;
         else
             assert(false);  /* Every possibility is accounted for */
     }
@@ -135,13 +130,104 @@ parseCommandLine(int argc, const char ** argv,
     else {
         cmdlineP->width  = atoi(argv[1]);
         cmdlineP->height = atoi(argv[2]);
+
+        if (cmdlineP->width < 1)
+            pm_error("Width must be at least 1 pixel");
+        if (cmdlineP->height < 1)
+            pm_error("Height must be at least 1 pixel");
     }
 }
 
 
 
 static pixel
-random_anticamo_color(pixval const maxval) {
+randomColor(pixval const maxval) {
+
+    pixel p;
+
+    PPM_ASSIGN(p,
+               rand() % (maxval + 1),
+               rand() % (maxval + 1),
+               rand() % (maxval + 1)
+        );
+    
+    return p;
+}
+
+
+
+#define DARK_THRESH 0.25
+
+static pixel
+randomBrightColor(pixval const maxval) {
+
+    pixel p;
+
+    do {
+        p = randomColor(maxval);
+    } while (PPM_LUMIN(p) <= maxval * DARK_THRESH);
+
+    return p;
+}
+
+
+
+static pixel
+randomDarkColor(pixval const maxval) {
+
+    pixel p;
+
+    do {
+        p = randomColor(maxval);
+    } while (PPM_LUMIN(p) > maxval * DARK_THRESH);
+
+    return p;
+}
+
+
+
+static pixel
+averageTwoColors(pixel const p1,
+                 pixel const p2) {
+
+    pixel p;
+
+    PPM_ASSIGN(p,
+               (PPM_GETR(p1) + PPM_GETR(p2)) / 2,
+               (PPM_GETG(p1) + PPM_GETG(p2)) / 2,
+               (PPM_GETB(p1) + PPM_GETB(p2)) / 2);
+
+    return p;
+}
+
+
+
+static ppmd_drawproc average_drawproc;
+
+static void
+average_drawproc(pixel **     const pixels, 
+                 int          const cols, 
+                 int          const rows, 
+                 pixval       const maxval, 
+                 int          const col, 
+                 int          const row, 
+                 const void * const clientdata) {
+
+    if (col >= 0 && col < cols && row >= 0 && row < rows)
+        pixels[row][col] =
+            averageTwoColors(pixels[row][col], *((const pixel*) clientdata));
+}
+
+
+
+/*----------------------------------------------------------------------------
+   Camouflage stuff
+-----------------------------------------------------------------------------*/
+
+
+
+static pixel
+randomAnticamoColor(pixval const maxval) {
 
     int v1, v2, v3;
     pixel p;
@@ -189,17 +275,14 @@ random_anticamo_color(pixval const maxval) {
 
 
 
-/* Camouflage stuff. */
-
 static pixel
-random_camo_color(pixval const maxval) {
+randomCamoColor(pixval const maxval) {
 
-    int v1, v2, v3;
-    pixel p;
+    int const v1 = (maxval + 1 ) / 8;
+    int const v2 = (maxval + 1 ) / 4;
+    int const v3 = (maxval + 1 ) / 2;
 
-    v1 = (maxval + 1 ) / 8;
-    v2 = (maxval + 1 ) / 4;
-    v3 = (maxval + 1 ) / 2;
+    pixel p;
 
     switch (rand() % 10) {
     case 0:
@@ -241,6 +324,46 @@ rnduni(void) {
 
 
 
+static void
+clearBackground(pixel **     const pixels,
+                unsigned int const cols,
+                unsigned int const rows,
+                pixval       const maxval,
+                bool         const antiflag) {
+
+    pixel color;
+
+    if (antiflag)
+        color = randomAnticamoColor(maxval);
+    else
+        color = randomCamoColor(maxval);
+
+    ppmd_filledrectangle(
+        pixels, cols, rows, maxval, 0, 0, cols, rows, PPMD_NULLDRAWPROC,
+        &color);
+}
+
+
+static void
+camoFill(pixel **         const pixels,
+         unsigned int     const cols,
+         unsigned int     const rows,
+         pixval           const maxval,
+         struct fillobj * const fh,
+         bool             const antiflag) {
+         
+    pixel color;
+
+    if (antiflag)
+        color = randomAnticamoColor(maxval);
+    else
+        color = randomCamoColor(maxval);
+
+    ppmd_fill(pixels, cols, rows, maxval, fh, PPMD_NULLDRAWPROC, &color);
+}        
+
+
+
 #define BLOBRAD 50
 
 #define MIN_POINTS 7
@@ -255,63 +378,68 @@ rnduni(void) {
 
 
 static void
+computeXsYs(int *        const xs,
+            int *        const ys,
+            unsigned int const cols,
+            unsigned int const rows,
+            unsigned int const pointCt) {
+
+    unsigned int const cx = rand() % cols;
+    unsigned int const cy = rand() % rows;
+    double const a = rnduni() * (MAX_ELLIPSE_FACTOR - MIN_ELLIPSE_FACTOR) +
+        MIN_ELLIPSE_FACTOR;
+    double const b = rnduni() * (MAX_ELLIPSE_FACTOR - MIN_ELLIPSE_FACTOR) +
+        MIN_ELLIPSE_FACTOR;
+    double const theta = rnduni() * 2.0 * M_PI;
+    
+    unsigned int p;
+        
+    for (p = 0; p < pointCt; ++p) {
+        double const c = rnduni() * (MAX_POINT_FACTOR - MIN_POINT_FACTOR) +
+            MIN_POINT_FACTOR;
+        double const tx   = a * sin(p * 2.0 * M_PI / pointCt);
+        double const ty   = b * cos(p * 2.0 * M_PI / pointCt);
+        double const tang = atan2(ty, tx) + theta;
+        xs[p] = MAX(0, MIN(cols-1, cx + BLOBRAD * c * sin(tang)));
+        ys[p] = MAX(0, MIN(rows-1, cy + BLOBRAD * c * cos(tang)));
+    }
+}
+
+
+
+static void
 camo(pixel **     const pixels,
      unsigned int const cols,
      unsigned int const rows,
      pixval       const maxval,
      bool         const antiflag) {
 
-    pixel color;
-    int n, i, cx, cy;
-    struct fillobj * fh;
+    unsigned int const n = (rows * cols) / (BLOBRAD * BLOBRAD) * 5;
 
-    /* Clear background. */
-    if (antiflag)
-        color = random_anticamo_color( maxval );
-    else
-        color = random_camo_color( maxval );
+    unsigned int i;
 
-    ppmd_filledrectangle(
-        pixels, cols, rows, maxval, 0, 0, cols, rows, PPMD_NULLDRAWPROC,
-        &color);
+    clearBackground(pixels, cols, rows, maxval, antiflag);
 
-    n = (rows * cols) / (BLOBRAD * BLOBRAD) * 5;
     for (i = 0; i < n; ++i) {
-        int points, p, xs[MAX_POINTS], ys[MAX_POINTS], x0, y0;
-        float a, b, c, theta, tang, tx, ty;
-        
-        cx = rand() % cols;
-        cy = rand() % rows;
-        
-        points = rand() % ( MAX_POINTS - MIN_POINTS + 1 ) + MIN_POINTS;
-        a = rnduni() * (MAX_ELLIPSE_FACTOR - MIN_ELLIPSE_FACTOR) +
-            MIN_ELLIPSE_FACTOR;
-        b = rnduni() * (MAX_ELLIPSE_FACTOR - MIN_ELLIPSE_FACTOR) +
-            MIN_ELLIPSE_FACTOR;
-        theta = rnduni() * 2.0 * M_PI;
-        for (p = 0; p < points; ++p) {
-            tx = a * sin(p * 2.0 * M_PI / points);
-            ty = b * cos(p * 2.0 * M_PI / points);
-            tang = atan2(ty, tx) + theta;
-            c = rnduni() * (MAX_POINT_FACTOR - MIN_POINT_FACTOR) +
-                MIN_POINT_FACTOR;
-            xs[p] = cx + BLOBRAD * c * sin(tang);
-            ys[p] = cy + BLOBRAD * c * cos(tang);
-        }
-        x0 = (xs[0] + xs[points - 1]) / 2;
-        y0 = (ys[0] + ys[points - 1]) / 2;
+        unsigned int const pointCt =
+            rand() % (MAX_POINTS - MIN_POINTS + 1) + MIN_POINTS;
+
+        int xs[MAX_POINTS], ys[MAX_POINTS];
+        int x0, y0;
+        struct fillobj * fh;
+
+        computeXsYs(xs, ys, cols, rows, pointCt);
+
+        x0 = (xs[0] + xs[pointCt - 1]) / 2;
+        y0 = (ys[0] + ys[pointCt - 1]) / 2;
 
         fh = ppmd_fill_create();
 
         ppmd_polyspline(
-            pixels, cols, rows, maxval, x0, y0, points, xs, ys, x0, y0,
-            ppmd_fill_drawproc, fh );
+            pixels, cols, rows, maxval, x0, y0, pointCt, xs, ys, x0, y0,
+            ppmd_fill_drawproc, fh);
         
-        if (antiflag)
-            color = random_anticamo_color(maxval);
-        else
-            color = random_camo_color(maxval);
-        ppmd_fill(pixels, cols, rows, maxval, fh, PPMD_NULLDRAWPROC, &color);
+        camoFill(pixels, cols, rows, maxval, fh, antiflag);
         
         ppmd_fill_destroy(fh);
     }
@@ -319,455 +447,447 @@ camo(pixel **     const pixels,
 
 
 
-static pixel
-random_color(pixval const maxval) {
-
-    pixel p;
-
-    PPM_ASSIGN(p,
-               rand() % (maxval + 1),
-               rand() % (maxval + 1),
-               rand() % (maxval + 1)
-        );
-    
-    return p;
-}
-
-
-
-#define DARK_THRESH 0.25
-
-static pixel
-random_bright_color( pixval maxval )
-    {
-    pixel p;
-
-    do
-    {
-    p = random_color( maxval );
-    }
-    while ( PPM_LUMIN( p ) <= maxval * DARK_THRESH );
-
-    return p;
-    }
-
-static pixel
-random_dark_color( pixval maxval )
-    {
-    pixel p;
-
-    do
-    {
-    p = random_color( maxval );
-    }
-    while ( PPM_LUMIN( p ) > maxval * DARK_THRESH );
-
-    return p;
-    }
+/*----------------------------------------------------------------------------
+   Gingham stuff
+-----------------------------------------------------------------------------*/
 
-static pixel
-average_two_colors( p1, p2 )
-pixel p1, p2;
-    {
-    pixel p;
 
-    PPM_ASSIGN(
-    p, ( (int) PPM_GETR(p1) + (int) PPM_GETR(p2) ) / 2,
-    ( (int) PPM_GETG(p1) + (int) PPM_GETG(p2) ) / 2,
-    ( (int) PPM_GETB(p1) + (int) PPM_GETB(p2) ) / 2 );
-
-    return p;
-    }
-
-/* Gingham stuff. */
 
 static void
-average_drawproc(pixel** const pixels, 
-                 int const cols, 
-                 int const rows, 
-                 pixval const maxval, 
-                 int const col, 
-                 int const row, 
-                 const void* const clientdata )
-{
-    if ( col >= 0 && col < cols && row >= 0 && row < rows )
-        pixels[row][col] =
-            average_two_colors( pixels[row][col], *( (pixel*) clientdata ) );
-}
+gingham2(pixel **     const pixels,
+         unsigned int const cols,
+         unsigned int const rows,
+         pixval       const maxval) {
 
-static void
-gingham2( pixel** pixels, int cols, int rows, pixval maxval )
-{
-    pixel const backcolor = random_dark_color( maxval );
-    pixel const forecolor = random_bright_color( maxval );
-    int const colso2 = cols / 2;
-    int const rowso2 = rows / 2;
+    pixel const backcolor = randomDarkColor(maxval);
+    pixel const forecolor = randomBrightColor(maxval);
+    unsigned int const colso2 = cols / 2;
+    unsigned int const rowso2 = rows / 2;
 
     /* Warp. */
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 0, colso2, rows, PPMD_NULLDRAWPROC,
-        &backcolor );
+        &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, colso2, 0, cols - colso2, rows,
-        PPMD_NULLDRAWPROC, &forecolor );
+        PPMD_NULLDRAWPROC, &forecolor);
 
     /* Woof. */
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 0, cols, rowso2, average_drawproc,
-        &backcolor );
+        &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, rowso2, cols, rows - rowso2,
-        average_drawproc, &forecolor );
-    }
+        average_drawproc, &forecolor);
+}
+
+
 
 static void
-gingham3( pixel** pixels, int cols, int rows, pixval maxval )
-    {
-    int colso4, rowso4;
-    pixel backcolor, fore1color, fore2color;
+gingham3(pixel **     const pixels,
+         unsigned int const cols,
+         unsigned int const rows,
+         pixval       const maxval) {
+
+    unsigned int const colso4 = cols / 4;
+    unsigned int const rowso4 = rows / 4;
 
-    colso4 = cols / 4;
-    rowso4 = rows / 4;
-    backcolor = random_dark_color( maxval );
-    fore1color = random_bright_color( maxval );
-    fore2color = random_bright_color( maxval );
+    pixel const backcolor  = randomDarkColor(maxval);
+    pixel const fore1color = randomBrightColor(maxval);
+    pixel const fore2color = randomBrightColor(maxval);
 
     /* Warp. */
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 0, colso4, rows, PPMD_NULLDRAWPROC,
-        &backcolor );
+        &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, colso4, 0, colso4, rows, PPMD_NULLDRAWPROC,
-        &fore1color );
+        &fore1color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 2 * colso4, 0, colso4, rows,
-        PPMD_NULLDRAWPROC, &fore2color );
+        PPMD_NULLDRAWPROC, &fore2color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 3 * colso4, 0, cols - colso4, rows,
-        PPMD_NULLDRAWPROC, &fore1color );
+        PPMD_NULLDRAWPROC, &fore1color);
 
     /* Woof. */
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 0, cols, rowso4, average_drawproc,
-        &backcolor );
+        &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, rowso4, cols, rowso4, average_drawproc,
-        &fore1color );
+        &fore1color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 2 * rowso4, cols, rowso4,
-        average_drawproc, &fore2color );
+        average_drawproc, &fore2color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 3 * rowso4, cols, rows - rowso4,
-        average_drawproc, &fore1color );
-    }
+        average_drawproc, &fore1color);
+}
+
+
 
 static void
-madras( pixel** pixels, int cols, int rows, pixval maxval )
-    {
-    int cols2, rows2, cols3, rows3, cols12, rows12, cols6a, rows6a, cols6b,
-    rows6b;
-    pixel backcolor, fore1color, fore2color;
-
-    cols2 = cols * 2 / 44;
-    rows2 = rows * 2 / 44;
-    cols3 = cols * 3 / 44;
-    rows3 = rows * 3 / 44;
-    cols12 = cols - 10 * cols2 - 4 * cols3;
-    rows12 = rows - 10 * rows2 - 4 * rows3;
-    cols6a = cols12 / 2;
-    rows6a = rows12 / 2;
-    cols6b = cols12 - cols6a;
-    rows6b = rows12 - rows6a;
-    backcolor = random_dark_color( maxval );
-    fore1color = random_bright_color( maxval );
-    fore2color = random_bright_color( maxval );
+madras(pixel **     const pixels,
+       unsigned int const cols,
+       unsigned int const rows,
+       pixval       const maxval) {
+
+    unsigned int const cols2  = cols * 2 / 44;
+    unsigned int const rows2  = rows * 2 / 44;
+    unsigned int const cols3  = cols * 3 / 44;
+    unsigned int const rows3  = rows * 3 / 44;
+    unsigned int const cols12 = cols - 10 * cols2 - 4 * cols3;
+    unsigned int const rows12 = rows - 10 * rows2 - 4 * rows3;
+    unsigned int const cols6a = cols12 / 2;
+    unsigned int const rows6a = rows12 / 2;
+    unsigned int const cols6b = cols12 - cols6a;
+    unsigned int const rows6b = rows12 - rows6a;
+    pixel const backcolor  = randomDarkColor(maxval);
+    pixel const fore1color = randomBrightColor(maxval);
+    pixel const fore2color = randomBrightColor(maxval);
 
     /* Warp. */
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 0, cols2, rows, PPMD_NULLDRAWPROC,
-        &backcolor );
+        &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, cols2, 0, cols3, rows, PPMD_NULLDRAWPROC,
-        &fore1color );
+        &fore1color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, cols2 + cols3, 0, cols2, rows,
-        PPMD_NULLDRAWPROC, &backcolor );
+        PPMD_NULLDRAWPROC, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 2 * cols2 + cols3, 0, cols2, rows,
-        PPMD_NULLDRAWPROC, &fore2color );
+        PPMD_NULLDRAWPROC, &fore2color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 3 * cols2 + cols3, 0, cols2, rows,
-        PPMD_NULLDRAWPROC, &backcolor );
+        PPMD_NULLDRAWPROC, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 4 * cols2 + cols3, 0, cols6a, rows,
-        PPMD_NULLDRAWPROC, &fore1color );
+        PPMD_NULLDRAWPROC, &fore1color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 4 * cols2 + cols3 + cols6a, 0, cols2, rows,
-        PPMD_NULLDRAWPROC, &backcolor );
+        PPMD_NULLDRAWPROC, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 5 * cols2 + cols3 + cols6a, 0, cols3, rows,
-        PPMD_NULLDRAWPROC, &fore2color );
+        PPMD_NULLDRAWPROC, &fore2color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 5 * cols2 + 2 * cols3 + cols6a, 0, cols2,
-        rows, PPMD_NULLDRAWPROC, &backcolor );
+        rows, PPMD_NULLDRAWPROC, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 6 * cols2 + 2 * cols3 + cols6a, 0, cols3,
-        rows, PPMD_NULLDRAWPROC, &fore2color );
+        rows, PPMD_NULLDRAWPROC, &fore2color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 6 * cols2 + 3 * cols3 + cols6a, 0, cols2,
-        rows, PPMD_NULLDRAWPROC, &backcolor );
+        rows, PPMD_NULLDRAWPROC, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 7 * cols2 + 3 * cols3 + cols6a, 0, cols6b,
-        rows, PPMD_NULLDRAWPROC, &fore1color );
+        rows, PPMD_NULLDRAWPROC, &fore1color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 7 * cols2 + 3 * cols3 + cols6a + cols6b, 0,
-        cols2, rows, PPMD_NULLDRAWPROC, &backcolor );
+        cols2, rows, PPMD_NULLDRAWPROC, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 8 * cols2 + 3 * cols3 + cols6a + cols6b, 0,
-        cols2, rows, PPMD_NULLDRAWPROC, &fore2color );
+        cols2, rows, PPMD_NULLDRAWPROC, &fore2color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 9 * cols2 + 3 * cols3 + cols6a + cols6b, 0,
-        cols2, rows, PPMD_NULLDRAWPROC, &backcolor );
+        cols2, rows, PPMD_NULLDRAWPROC, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 10 * cols2 + 3 * cols3 + cols6a + cols6b, 
-        0, cols3, rows, PPMD_NULLDRAWPROC, &fore1color );
+        0, cols3, rows, PPMD_NULLDRAWPROC, &fore1color);
 
     /* Woof. */
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 0, cols, rows2, average_drawproc,
-        &backcolor );
+        &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, rows2, cols, rows3, average_drawproc,
-        &fore2color );
+        &fore2color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, rows2 + rows3, cols, rows2,
-        average_drawproc, &backcolor );
+        average_drawproc, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 2 * rows2 + rows3, cols, rows2,
-        average_drawproc, &fore1color );
+        average_drawproc, &fore1color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 3 * rows2 + rows3, cols, rows2,
-        average_drawproc, &backcolor );
+        average_drawproc, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 4 * rows2 + rows3, cols, rows6a,
-        average_drawproc, &fore2color );
+        average_drawproc, &fore2color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 4 * rows2 + rows3 + rows6a, cols, rows2,
-        average_drawproc, &backcolor );
+        average_drawproc, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 5 * rows2 + rows3 + rows6a, cols, rows3,
-        average_drawproc, &fore1color );
+        average_drawproc, &fore1color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 5 * rows2 + 2 * rows3 + rows6a, cols,
-        rows2, average_drawproc, &backcolor );
+        rows2, average_drawproc, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 6 * rows2 + 2 * rows3 + rows6a, cols,
-        rows3, average_drawproc, &fore1color );
+        rows3, average_drawproc, &fore1color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 6 * rows2 + 3 * rows3 + rows6a, cols,
-        rows2, average_drawproc, &backcolor );
+        rows2, average_drawproc, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 7 * rows2 + 3 * rows3 + rows6a, cols,
-        rows6b, average_drawproc, &fore2color );
+        rows6b, average_drawproc, &fore2color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 7 * rows2 + 3 * rows3 + rows6a + rows6b,
-        cols, rows2, average_drawproc, &backcolor );
+        cols, rows2, average_drawproc, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 8 * rows2 + 3 * rows3 + rows6a + rows6b,
-        cols, rows2, average_drawproc, &fore1color );
+        cols, rows2, average_drawproc, &fore1color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 9 * rows2 + 3 * rows3 + rows6a + rows6b,
-        cols, rows2, average_drawproc, &backcolor );
+        cols, rows2, average_drawproc, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 
         10 * rows2 + 3 * rows3 + rows6a + rows6b,
-        cols, rows3, average_drawproc, &fore2color );
-    }
+        cols, rows3, average_drawproc, &fore2color);
+}
+
+
 
 static void
-tartan( pixel** pixels, int cols, int rows, pixval maxval )
-    {
-    int cols1, rows1, cols3, rows3, cols10, rows10, cols5a, rows5a, cols5b,
-    rows5b;
-    pixel backcolor, fore1color, fore2color;
-
-    cols1 = cols / 22;
-    rows1 = rows / 22;
-    cols3 = cols * 3 / 22;
-    rows3 = rows * 3 / 22;
-    cols10 = cols - 3 * cols1 - 3 * cols3;
-    rows10 = rows - 3 * rows1 - 3 * rows3;
-    cols5a = cols10 / 2;
-    rows5a = rows10 / 2;
-    cols5b = cols10 - cols5a;
-    rows5b = rows10 - rows5a;
-    backcolor = random_dark_color( maxval );
-    fore1color = random_bright_color( maxval );
-    fore2color = random_bright_color( maxval );
+tartan(pixel **     const pixels,
+       unsigned int const cols,
+       unsigned int const rows,
+       pixval       const maxval) {
+
+    unsigned int const cols1  = cols / 22;
+    unsigned int const rows1  = rows / 22;
+    unsigned int const cols3  = cols * 3 / 22;
+    unsigned int const rows3  = rows * 3 / 22;
+    unsigned int const cols10 = cols - 3 * cols1 - 3 * cols3;
+    unsigned int const rows10 = rows - 3 * rows1 - 3 * rows3;
+    unsigned int const cols5a = cols10 / 2;
+    unsigned int const rows5a = rows10 / 2;
+    unsigned int const cols5b = cols10 - cols5a;
+    unsigned int const rows5b = rows10 - rows5a;
+    pixel const backcolor  = randomDarkColor(maxval);
+    pixel const fore1color = randomBrightColor(maxval);
+    pixel const fore2color = randomBrightColor(maxval);
 
     /* Warp. */
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 0, cols5a, rows, PPMD_NULLDRAWPROC,
-        &backcolor );
+        &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, cols5a, 0, cols1, rows, PPMD_NULLDRAWPROC,
-        &fore1color );
+        &fore1color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, cols5a + cols1, 0, cols5b, rows,
         PPMD_NULLDRAWPROC, &backcolor );
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, cols10 + cols1, 0, cols3, rows,
-        PPMD_NULLDRAWPROC, &fore2color );
+        PPMD_NULLDRAWPROC, &fore2color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, cols10 + cols1 + cols3, 0, cols1, rows,
-        PPMD_NULLDRAWPROC, &backcolor );
+        PPMD_NULLDRAWPROC, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, cols10 + 2 * cols1 + cols3, 0, cols3, rows,
-        PPMD_NULLDRAWPROC, &fore2color );
+        PPMD_NULLDRAWPROC, &fore2color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, cols10 + 2 * cols1 + 2 * cols3, 0, cols1,
-        rows, PPMD_NULLDRAWPROC, (char*) &backcolor );
+        rows, PPMD_NULLDRAWPROC, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, cols10 + 3 * cols1 + 2 * cols3, 0, cols3,
-        rows, PPMD_NULLDRAWPROC, &fore2color );
+        rows, PPMD_NULLDRAWPROC, &fore2color);
 
     /* Woof. */
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 0, cols, rows5a, average_drawproc,
-        &backcolor );
+        &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, rows5a, cols, rows1, average_drawproc,
-        &fore1color );
+        &fore1color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, rows5a + rows1, cols, rows5b,
-        average_drawproc, &backcolor );
+        average_drawproc, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, rows10 + rows1, cols, rows3,
-        average_drawproc, &fore2color );
+        average_drawproc, &fore2color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, rows10 + rows1 + rows3, cols, rows1,
-        average_drawproc, &backcolor );
+        average_drawproc, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, rows10 + 2 * rows1 + rows3, cols, rows3,
-        average_drawproc, &fore2color );
+        average_drawproc, &fore2color);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, rows10 + 2 * rows1 + 2 * rows3, cols,
-        rows1, average_drawproc, &backcolor );
+        rows1, average_drawproc, &backcolor);
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, rows10 + 3 * rows1 + 2 * rows3, cols,
-        rows3, average_drawproc, &fore2color );
-    }
+        rows3, average_drawproc, &fore2color);
+}
+
+
+
+/*----------------------------------------------------------------------------
+   Poles stuff
+-----------------------------------------------------------------------------*/
+
 
-/* Poles stuff. */
 
 #define MAXPOLES 500
 
+
+
 static void
-poles( pixel** pixels, int cols, int rows, pixval maxval )
-    {
-    int poles, i, xs[MAXPOLES], ys[MAXPOLES], col, row;
-    pixel colors[MAXPOLES];
+placeAndColorPolesRandomly(int *        const xs,
+                           int *        const ys,
+                           pixel *      const colors,
+                           unsigned int const cols,
+                           unsigned int const rows,
+                           pixval       const maxval,
+                           unsigned int const poleCt) {
 
-    poles = cols * rows / 30000;
+    unsigned int i;
 
-    /* Place and color poles randomly. */
-    for ( i = 0; i < poles; ++i )
-    {
-    xs[i] = rand() % cols;
-    ys[i] = rand() % rows;
-    colors[i] = random_bright_color( maxval );
+    for (i = 0; i < poleCt; ++i) {
+        xs[i] = rand() % cols;
+        ys[i] = rand() % rows;
+        colors[i] = randomBrightColor(maxval);
     }
+}
 
-    /* Now interpolate points. */
-    for ( row = 0; row < rows; ++row )
-    for ( col = 0; col < cols; ++col )
-        {
-        register long dist1, dist2, newdist, r, g, b;
-        pixel color1, color2;
 
-        /* Find two closest poles. */
-        dist1 = dist2 = 2000000000;
-        for ( i = 0; i < poles; ++i )
-        {
-        newdist = ( col - xs[i] ) * ( col - xs[i] ) +
-              ( row - ys[i] ) * ( row - ys[i] );
-        if ( newdist < dist1 )
-            {
-            dist1 = newdist;
-            color1 = colors[i];
-            }
-        else if ( newdist < dist2 )
-            {
-            dist2 = newdist;
-            color2 = colors[i];
-            }
-        }
 
-        /* And assign interpolated color. */
-        newdist = dist1 + dist2;
-        r = PPM_GETR(color1)*dist2/newdist + PPM_GETR(color2)*dist1/newdist;
-        g = PPM_GETG(color1)*dist2/newdist + PPM_GETG(color2)*dist1/newdist;
-        b = PPM_GETB(color1)*dist2/newdist + PPM_GETB(color2)*dist1/newdist;
-        PPM_ASSIGN( pixels[row][col], r, g, b );
+static void
+assignInterpolatedColor(pixel * const resultP,
+                        pixel   const color1,
+                        long    const dist1,
+                        pixel   const color2,
+                        long    const dist2) {
+
+    long const sum = dist1 + dist2;
+
+    pixval const r = PPM_GETR(color1)*dist2/sum + PPM_GETR(color2)*dist1/sum;
+    pixval const g = PPM_GETG(color1)*dist2/sum + PPM_GETG(color2)*dist1/sum;
+    pixval const b = PPM_GETB(color1)*dist2/sum + PPM_GETB(color2)*dist1/sum;
+
+    PPM_ASSIGN(*resultP, r, g, b);
+}
+
+
+
+static void
+poles(pixel **     const pixels,
+      unsigned int const cols,
+      unsigned int const rows,
+      pixval       const maxval) {
+
+    unsigned int const poleCt = cols * rows / 30000;
+    
+    int xs[MAXPOLES], ys[MAXPOLES];
+    pixel colors[MAXPOLES];
+    unsigned int row;
+
+    placeAndColorPolesRandomly(xs, ys, colors, cols, rows, maxval, poleCt);
+
+    /* Interpolate points */
+
+    for (row = 0; row < rows; ++row) {
+        unsigned int col;
+        for (col = 0; col < cols; ++col) {
+            long dist1, dist2;
+            pixel color1, color2;
+            unsigned int i;
+
+            /* Find two closest poles. */
+            dist1 = dist2 = 2000000000;
+            for (i = 0; i < poleCt; ++i) {
+                long const newdist =
+                    (col - xs[i]) * (col - xs[i]) +
+                    (row - ys[i]) * (row - ys[i]);
+                if (newdist < dist1) {
+                    dist1 = newdist;
+                    color1 = colors[i];
+                } else if (newdist < dist2) {
+                    dist2 = newdist;
+                    color2 = colors[i];
+                }
+            }
+            assignInterpolatedColor(&pixels[row][col],
+                                    color1, dist1, color2, dist2);
         }
     }
+}
 
-/* Squig stuff. */
+
+
+/*----------------------------------------------------------------------------
+   Squig stuff
+-----------------------------------------------------------------------------*/
 
 #define SQUIGS 5
 #define SQ_POINTS 7
 #define SQ_MAXCIRCLE_POINTS 5000
 
-static int sq_radius, sq_circlecount;
+static int sq_circlecount;
 static pixel sq_colors[SQ_MAXCIRCLE_POINTS];
-static int sq_xoffs[SQ_MAXCIRCLE_POINTS], sq_yoffs[SQ_MAXCIRCLE_POINTS];
+static ppmd_point sq_offs[SQ_MAXCIRCLE_POINTS];
 
-static void
-sq_measurecircle_drawproc(pixel** const pixels, 
-                          int const cols, 
-                          int const rows, 
-                          pixval const maxval, 
-                          int const col, 
-                          int const row, 
-                          const void* const clientdata)
-{
-    sq_xoffs[sq_circlecount] = col;
-    sq_yoffs[sq_circlecount] = row;
-    ++sq_circlecount;
+
+
+static ppmd_point
+vectorSum(ppmd_point const a,
+          ppmd_point const b) {
+
+    return ppmd_makePoint(a.x + b.x, a.y + b.y);
 }
 
+
+
+static ppmd_drawprocp sqMeasureCircleDrawproc;
+
 static void
-sq_rainbowcircle_drawproc(pixel** const pixels, 
-                          int const cols, 
-                          int const rows, 
-                          pixval const maxval, 
-                          int const col, 
-                          int const row, 
-                          const void* const clientdata )
-{
-    int i;
+sqMeasureCircleDrawproc(pixel**      const pixels, 
+                        unsigned int const cols, 
+                        unsigned int const rows, 
+                        pixval       const maxval, 
+                        ppmd_point   const p,
+                        const void * const clientdata) {
+
+    sq_offs[sq_circlecount++] = p;
+}
 
-    for ( i = 0; i < sq_circlecount; ++i )
-    ppmd_point_drawproc(
-        pixels, cols, rows, maxval, col + sq_xoffs[i], row + sq_yoffs[i],
-        &(sq_colors[i]) );
-    }
 
 
+static ppmd_drawprocp sqRainbowCircleDrawproc;
 
 static void
-sq_assign_colors(int     const circlecount,
-                 pixval  const maxval,
-                 pixel * const colors) {
+sqRainbowCircleDrawproc(pixel **     const pixels, 
+                        unsigned int const cols, 
+                        unsigned int const rows, 
+                        pixval       const maxval, 
+                        ppmd_point   const p,
+                        const void * const clientdata) {
 
-    pixel rc1, rc2, rc3;
-    float cco3;
     unsigned int i;
 
-    rc1 = random_bright_color(maxval);
-    rc2 = random_bright_color(maxval);
-    rc3 = random_bright_color(maxval);
-    cco3 = (circlecount - 1) / 3.0;
+    for (i = 0; i < sq_circlecount; ++i)
+        ppmd_point_drawprocp(
+            pixels, cols, rows, maxval, vectorSum(p, sq_offs[i]),
+            &sq_colors[i]);
+}
+
+
+
+static void
+sqAssignColors(unsigned int const circlecount,
+               pixval       const maxval,
+               pixel *      const colors) {
+
+    pixel const rc1 = randomBrightColor(maxval);
+    pixel const rc2 = randomBrightColor(maxval);
+    pixel const rc3 = randomBrightColor(maxval);
+    float const cco3 = (circlecount - 1) / 3.0;
+
+    unsigned int i;
 
     for (i = 0; i < circlecount ; ++i) {
         if (i < cco3) {
@@ -805,168 +925,158 @@ sq_assign_colors(int     const circlecount,
 }
 
 
+
 static void
-squig( pixel** pixels, int cols, int rows, pixval maxval )
-    {
+clearImageToBlack(pixel **     const pixels,
+                  unsigned int const cols,
+                  unsigned int const rows,
+                  pixval       const maxval) {
+
     pixel color;
-    int i, j, xc[SQ_POINTS], yc[SQ_POINTS], x0, y0, x1, y1, x2, y2, x3, y3;
 
-    /* Clear image to black. */
-    PPM_ASSIGN( color, 0, 0, 0 );
+    PPM_ASSIGN(color, 0, 0, 0);
+
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 0, cols, rows, PPMD_NULLDRAWPROC,
-        &color );
+        &color);
+}
 
-    /* Draw the squigs. */
-    (void) ppmd_setlinetype( PPMD_LINETYPE_NODIAGS );
-    (void) ppmd_setlineclip( 0 );
-    for ( i = SQUIGS; i > 0; --i )
-    {
-    /* Measure circle. */
-    sq_radius = ( cols + rows ) / 2 / ( 25 + i * 2 );
-    sq_circlecount = 0;
-    ppmd_circle(
-        pixels, cols, rows, maxval, 0, 0, sq_radius,
-        sq_measurecircle_drawproc, NULL );
-    sq_assign_colors( sq_circlecount, maxval, sq_colors );
-
-    /* Choose wrap-around point. */
-    switch ( rand() % 4 )
-        {
-        case 0:
-        x1 = rand() % cols;
-        y1 = 0;
-        if ( x1 < cols / 2 )
-        xc[0] = rand() % ( x1 * 2 );
+
+
+static void
+chooseWrapAroundPoint(unsigned int const cols,
+                      unsigned int const rows,
+                      ppmd_point * const pFirstP,
+                      ppmd_point * const pLastP,
+                      ppmd_point * const p0P,
+                      ppmd_point * const p1P,
+                      ppmd_point * const p2P,
+                      ppmd_point * const p3P) {
+                      
+    switch (rand() % 4) {
+    case 0:
+        p1P->x = rand() % cols;
+        p1P->y = 0;
+        if (p1P->x < cols / 2)
+            pFirstP->x = rand() % (p1P->x * 2 + 1);
         else
-        xc[0] = cols - 1 - rand() % ( ( cols - x1 ) * 2 );
-        yc[0] = rand() % rows;
-        x2 = x1;
-        y2 = rows - 1;
-        xc[SQ_POINTS - 1] = 2 * x2 - xc[0];
-        yc[SQ_POINTS - 1] = y2 - yc[0];
-        x0 = xc[SQ_POINTS - 1];
-        y0 = yc[SQ_POINTS - 1] - rows;
-        x3 = xc[0];
-        y3 = yc[0] + rows;
+            pFirstP->x = cols - 1 - rand() % ((cols - p1P->x) * 2);
+        pFirstP->y = rand() % rows;
+        p2P->x = p1P->x;
+        p2P->y = rows - 1;
+        pLastP->x = 2 * p2P->x - pFirstP->x;
+        pLastP->y = p2P->y - pFirstP->y;
+        p0P->x = pLastP->x;
+        p0P->y = pLastP->y - rows;
+        p3P->x = pFirstP->x;
+        p3P->y = pFirstP->y + rows;
         break;
 
-        case 1:
-        x2 = rand() % cols;
-        y2 = 0;
-        if ( x2 < cols / 2 )
-        xc[SQ_POINTS - 1] = rand() % ( x2 * 2 );
+    case 1:
+        p2P->x = rand() % cols;
+        p2P->y = 0;
+        if (p2P->x < cols / 2)
+            pLastP->x = rand() % (p2P->x * 2 + 1);
         else
-        xc[SQ_POINTS - 1] = cols - 1 - rand() % ( ( cols - x2 ) * 2 );
-        yc[SQ_POINTS - 1] = rand() % rows;
-        x1 = x2;
-        y1 = rows - 1;
-        xc[0] = 2 * x1 - xc[SQ_POINTS - 1];
-        yc[0] = y1 - yc[SQ_POINTS - 1];
-        x0 = xc[SQ_POINTS - 1];
-        y0 = yc[SQ_POINTS - 1] + rows;
-        x3 = xc[0];
-        y3 = yc[0] - rows;
+            pLastP->x = cols - 1 - rand() % ((cols - p2P->x) * 2);
+        pLastP->y = rand() % rows;
+        p1P->x = p2P->x;
+        p1P->y = rows - 1;
+        pFirstP->x = 2 * p1P->x - pLastP->x;
+        pFirstP->y = p1P->y - pLastP->y;
+        p0P->x = pLastP->x;
+        p0P->y = pLastP->y + rows;
+        p3P->x = pFirstP->x;
+        p3P->y = pFirstP->y - rows;
         break;
 
-        case 2:
-        x1 = 0;
-        y1 = rand() % rows;
-        xc[0] = rand() % cols;
-        if ( y1 < rows / 2 )
-        yc[0] = rand() % ( y1 * 2 );
+    case 2:
+        p1P->x = 0;
+        p1P->y = rand() % rows;
+        pFirstP->x = rand() % cols;
+        if (p1P->y < rows / 2)
+            pFirstP->y = rand() % (p1P->y * 2 + 1);
         else
-        yc[0] = rows - 1 - rand() % ( ( rows - y1 ) * 2 );
-        x2 = cols - 1;
-        y2 = y1;
-        xc[SQ_POINTS - 1] = x2 - xc[0];
-        yc[SQ_POINTS - 1] = 2 * y2 - yc[0];
-        x0 = xc[SQ_POINTS - 1] - cols;
-        y0 = yc[SQ_POINTS - 1];
-        x3 = xc[0] + cols;
-        y3 = yc[0];
+            pFirstP->y = rows - 1 - rand() % ((rows - p1P->y) * 2);
+        p2P->x = cols - 1;
+        p2P->y = p1P->y;
+        pLastP->x = p2P->x - pFirstP->x;
+        pLastP->y = 2 * p2P->y - pFirstP->y;
+        p0P->x = pLastP->x - cols;
+        p0P->y = pLastP->y;
+        p3P->x = pFirstP->x + cols;
+        p3P->y = pFirstP->y;
         break;
 
-        case 3:
-        x2 = 0;
-        y2 = rand() % rows;
-        xc[SQ_POINTS - 1] = rand() % cols;
-        if ( y2 < rows / 2 )
-        yc[SQ_POINTS - 1] = rand() % ( y2 * 2 );
+    case 3:
+        p2P->x = 0;
+        p2P->y = rand() % rows;
+        pLastP->x = rand() % cols;
+        if (p2P->y < rows / 2)
+            pLastP->y = rand() % (p2P->y * 2 + 1);
         else
-        yc[SQ_POINTS - 1] = rows - 1 - rand() % ( ( rows - y2 ) * 2 );
-        x1 = cols - 1;
-        y1 = y2;
-        xc[0] = x1 - xc[SQ_POINTS - 1];
-        yc[0] = 2 * y1 - yc[SQ_POINTS - 1];
-        x0 = xc[SQ_POINTS - 1] + cols;
-        y0 = yc[SQ_POINTS - 1];
-        x3 = xc[0] - cols;
-        y3 = yc[0];
+            pLastP->y = rows - 1 - rand() % ((rows - p2P->y) * 2);
+        p1P->x = cols - 1;
+        p1P->y = p2P->y;
+        pFirstP->x = p1P->x - pLastP->x;
+        pFirstP->y = 2 * p1P->y - pLastP->y;
+        p0P->x = pLastP->x + cols;
+        p0P->y = pLastP->y;
+        p3P->x = pFirstP->x - cols;
+        p3P->y = pFirstP->y;
         break;
-        }
-
-    for ( j = 1; j < SQ_POINTS - 1; ++j )
-        {
-        xc[j] = ( rand() % ( cols - 2 * sq_radius ) ) + sq_radius;
-        yc[j] = ( rand() % ( rows - 2 * sq_radius ) ) + sq_radius;
-        }
-
-    ppmd_line(
-        pixels, cols, rows, maxval, x0, y0, x1, y1,
-        sq_rainbowcircle_drawproc, NULL );
-    ppmd_polyspline(
-        pixels, cols, rows, maxval, x1, y1, SQ_POINTS, xc, yc, x2, y2,
-        sq_rainbowcircle_drawproc, NULL );
-    ppmd_line(
-        pixels, cols, rows, maxval, x2, y2, x3, y3,
-        sq_rainbowcircle_drawproc, NULL );
-    }
     }
+}
 
 
 
-/* Test pattern.  Just a place to put ppmdraw exercises. */
-
 static void
-test(pixel **     const pixels,
-     unsigned int const cols,
-     unsigned int const rows,
-     pixval       const maxval) {
+squig(pixel **     const pixels,
+      unsigned int const cols,
+      unsigned int const rows,
+      pixval       const maxval) {
 
-    pixel color;
-    struct fillobj * fh;
+    int i;
+    
+    clearImageToBlack(pixels, cols, rows, maxval);
 
-    /* Clear image to black. */
-    PPM_ASSIGN( color, 0, 0, 0 );
-    ppmd_filledrectangle(
-        pixels, cols, rows, maxval, 0, 0, cols, rows, PPMD_NULLDRAWPROC,
-        &color);
+    /* Draw the squigs. */
+    ppmd_setlinetype(PPMD_LINETYPE_NODIAGS);
+    ppmd_setlineclip(0);
+    for (i = SQUIGS; i > 0; --i) {
+        unsigned int const radius = (cols + rows) / 2 / (25 + i * 2);
+
+        ppmd_point c[SQ_POINTS];
+        ppmd_point p0, p1, p2, p3;
+        sq_circlecount = 0;
+        ppmd_circlep(pixels, cols, rows, maxval,
+                     ppmd_makePoint(0, 0), radius,
+                     sqMeasureCircleDrawproc, NULL);
+        sqAssignColors(sq_circlecount, maxval, sq_colors);
+
+        chooseWrapAroundPoint(cols, rows, &c[0], &c[SQ_POINTS-1],
+                              &p0, &p1, &p2, &p3);
 
-    fh = ppmd_fill_create();
-
-    ppmd_line(pixels, cols, rows, maxval, 
-              cols/8, rows/8, cols/2, rows/4, ppmd_fill_drawproc, fh);
-    ppmd_line(pixels, cols, rows, maxval, 
-              cols/2, rows/4, cols-cols/8, rows/8, ppmd_fill_drawproc, fh);
-    ppmd_line(pixels, cols, rows, maxval, 
-              cols-cols/8, rows/8, cols/2, rows/2, ppmd_fill_drawproc, fh);
-    ppmd_spline3(pixels, cols, rows, maxval, 
-                 cols/2, rows/2, cols/2-cols/16, rows/2-rows/10, 
-                 cols/2-cols/8, rows/2, ppmd_fill_drawproc, fh);
-    ppmd_spline3(pixels, cols, rows, maxval, 
-                 cols/2-cols/8, rows/2, cols/4+cols/16, rows/2+rows/10, 
-                 cols/4, rows/2, ppmd_fill_drawproc, fh);
-    ppmd_line(pixels, cols, rows, maxval, 
-              cols/4, rows/2, cols/8, rows/2, ppmd_fill_drawproc, fh);
-    ppmd_line(pixels, cols, rows, maxval, 
-              cols/8, rows/2, cols/8, rows/8, ppmd_fill_drawproc, fh);
-
-    PPM_ASSIGN(color, maxval, maxval, maxval);
-    ppmd_fill(pixels, cols, rows, maxval, fh, PPMD_NULLDRAWPROC, &color);
+        {
+            /* Do the middle points */
+            unsigned int j;
 
-    ppmd_fill_destroy(fh);
+            for (j = 1; j < SQ_POINTS - 1; ++j) {
+                c[j].x = (rand() % (cols - 2 * radius)) + radius;
+                c[j].y = (rand() % (rows - 2 * radius)) + radius;
+            }
+        }
 
+        ppmd_linep(
+            pixels, cols, rows, maxval, p0, p1,
+            sqRainbowCircleDrawproc, NULL);
+        ppmd_polysplinep(
+            pixels, cols, rows, maxval, p1, SQ_POINTS, c, p2,
+            sqRainbowCircleDrawproc, NULL);
+        ppmd_linep(
+            pixels, cols, rows, maxval, p2, p3,
+            sqRainbowCircleDrawproc, NULL);
+    }
 }
 
 
@@ -1017,10 +1127,6 @@ main(int argc, const char ** argv) {
         camo(pixels, cmdline.width, cmdline.height, PPM_MAXMAXVAL, 1);
         break;
 
-    case PAT_TEST:
-        test(pixels, cmdline.width, cmdline.height, PPM_MAXMAXVAL);
-        break;
-
     default:
         pm_error("can't happen!");
     }