about summary refs log tree commit diff
path: root/generator/ppmpat.c
diff options
context:
space:
mode:
Diffstat (limited to 'generator/ppmpat.c')
-rw-r--r--generator/ppmpat.c435
1 files changed, 250 insertions, 185 deletions
diff --git a/generator/ppmpat.c b/generator/ppmpat.c
index 908c200f..2fd2088d 100644
--- a/generator/ppmpat.c
+++ b/generator/ppmpat.c
@@ -23,8 +23,9 @@
 
 #include "pm_c_util.h"
 #include "mallocvar.h"
-#include "shhopt.h"
 #include "nstring.h"
+#include "rand.h"
+#include "shhopt.h"
 #include "ppm.h"
 #include "ppmdraw.h"
 
@@ -223,9 +224,9 @@ parseCommandLine(int argc, const char ** argv,
     OPTENT3(0, "spiro1",        OPT_FLAG,   NULL,
             &spiro1,     0);
     OPTENT3(0, "spiro2",        OPT_FLAG,   NULL,
-            &spiro1,     0);
+            &spiro2,     0);
     OPTENT3(0, "spiro3",        OPT_FLAG,   NULL,
-            &spiro1,     0);
+            &spiro3,     0);
 #else
     spiro1 = spiro2 = spiro3 = 0;
 #endif
@@ -339,14 +340,15 @@ validateComputableDimensions(unsigned int const cols,
 
 
 static pixel
-randomColor(pixval const maxval) {
+randomColor(struct pm_randSt * const randStP,
+            pixval             const maxval) {
 
     pixel p;
 
     PPM_ASSIGN(p,
-               rand() % (maxval + 1),
-               rand() % (maxval + 1),
-               rand() % (maxval + 1)
+               pm_rand(randStP) % (maxval + 1),
+               pm_rand(randStP) % (maxval + 1),
+               pm_rand(randStP) % (maxval + 1)
         );
 
     return p;
@@ -354,15 +356,18 @@ randomColor(pixval const maxval) {
 
 
 
-#define DARK_THRESH 0.25
+static double const DARK_THRESH = 0.25;
+
+
 
 static pixel
-randomBrightColor(pixval const maxval) {
+randomBrightColor(struct pm_randSt * const randStP,
+                  pixval             const maxval) {
 
     pixel p;
 
     do {
-        p = randomColor(maxval);
+        p = randomColor(randStP, maxval);
     } while (PPM_LUMIN(p) <= maxval * DARK_THRESH);
 
     return p;
@@ -371,12 +376,13 @@ randomBrightColor(pixval const maxval) {
 
 
 static pixel
-randomDarkColor(pixval const maxval) {
+randomDarkColor(struct pm_randSt * const randStP,
+                pixval             const maxval) {
 
     pixel p;
 
     do {
-        p = randomColor(maxval);
+        p = randomColor(randStP, maxval);
     } while (PPM_LUMIN(p) > maxval * DARK_THRESH);
 
     return p;
@@ -448,7 +454,8 @@ nextColorBg(ColorTable * const colorTableP) {
 
 
 static pixel
-randomAnticamoColor(pixval const maxval) {
+randomAnticamoColor(struct pm_randSt * const randStP,
+                    pixval             const maxval) {
 
     int v1, v2, v3;
     pixel p;
@@ -457,37 +464,49 @@ randomAnticamoColor(pixval const maxval) {
     v2 = (maxval + 1) / 2;
     v3 = 3 * v1;
 
-    switch (rand() % 15) {
+    switch (pm_rand(randStP) % 15) {
     case 0: case 1:
-        PPM_ASSIGN(p, rand() % v1 + v3, rand() % v2, rand() % v2);
+        PPM_ASSIGN(p, pm_rand(randStP) % v1 + v3,
+                      pm_rand(randStP) % v2,
+                      pm_rand(randStP) % v2);
         break;
 
     case 2:
     case 3:
-        PPM_ASSIGN(p, rand() % v2, rand() % v1 + v3, rand() % v2);
+        PPM_ASSIGN(p, pm_rand(randStP) % v2,
+                      pm_rand(randStP) % v1 + v3,
+                      pm_rand(randStP) % v2);
         break;
 
     case 4:
     case 5:
-        PPM_ASSIGN(p, rand() % v2, rand() % v2, rand() % v1 + v3);
+        PPM_ASSIGN(p, pm_rand(randStP) % v2,
+                      pm_rand(randStP) % v2,
+                      pm_rand(randStP) % v1 + v3);
         break;
 
     case 6:
     case 7:
     case 8:
-        PPM_ASSIGN(p, rand() % v2, rand() % v1 + v3, rand() % v1 + v3);
+        PPM_ASSIGN(p, pm_rand(randStP) % v2,
+                      pm_rand(randStP) % v1 + v3,
+                      pm_rand(randStP) % v1 + v3);
         break;
 
     case 9:
     case 10:
     case 11:
-        PPM_ASSIGN(p, rand() % v1 + v3, rand() % v2, rand() % v1 + v3);
+        PPM_ASSIGN(p, pm_rand(randStP) % v1 + v3,
+                      pm_rand(randStP) % v2,
+                      pm_rand(randStP) % v1 + v3);
         break;
 
     case 12:
     case 13:
     case 14:
-        PPM_ASSIGN(p, rand() % v1 + v3, rand() % v1 + v3, rand() % v2);
+        PPM_ASSIGN(p, pm_rand(randStP) % v1 + v3,
+                      pm_rand(randStP) % v1 + v3,
+                      pm_rand(randStP) % v2);
         break;
     }
 
@@ -497,7 +516,8 @@ randomAnticamoColor(pixval const maxval) {
 
 
 static pixel
-randomCamoColor(pixval const maxval) {
+randomCamoColor(struct pm_randSt * const randStP,
+                pixval             const maxval) {
 
     int const v1 = (maxval + 1 ) / 8;
     int const v2 = (maxval + 1 ) / 4;
@@ -505,31 +525,39 @@ randomCamoColor(pixval const maxval) {
 
     pixel p;
 
-    switch (rand() % 10) {
+    switch (pm_rand(randStP) % 10) {
     case 0:
     case 1:
     case 2:
         /* light brown */
-        PPM_ASSIGN(p, rand() % v3 + v3, rand() % v3 + v2, rand() % v3 + v2);
+        PPM_ASSIGN(p, pm_rand(randStP) % v3 + v3,
+                      pm_rand(randStP) % v3 + v2,
+                      pm_rand(randStP) % v3 + v2);
         break;
 
     case 3:
     case 4:
     case 5:
         /* dark green */
-        PPM_ASSIGN(p, rand() % v2, rand() % v2 + 3 * v1, rand() % v2);
+        PPM_ASSIGN(p, pm_rand(randStP) % v2,
+                      pm_rand(randStP) % v2 + 3 * v1,
+                      pm_rand(randStP) % v2);
         break;
 
     case 6:
     case 7:
         /* brown */
-        PPM_ASSIGN(p, rand() % v2 + v2, rand() % v2, rand() % v2);
+        PPM_ASSIGN(p, pm_rand(randStP) % v2 + v2,
+                      pm_rand(randStP) % v2,
+                      pm_rand(randStP) % v2);
         break;
 
     case 8:
     case 9:
         /* dark brown */
-        PPM_ASSIGN(p, rand() % v1 + v1, rand() % v1, rand() % v1);
+        PPM_ASSIGN(p, pm_rand(randStP) % v1 + v1,
+                      pm_rand(randStP) % v1,
+                      pm_rand(randStP) % v1);
         break;
     }
 
@@ -539,28 +567,30 @@ randomCamoColor(pixval const maxval) {
 
 
 static float
-rnduni(void) {
-    return rand() % 32767 / 32767.0;
+rnduni(struct pm_randSt * const randStP) {
+
+    return pm_rand(randStP) % 32767 / 32767.0;
 }
 
 
 
 static void
-clearBackgroundCamo(pixel **     const pixels,
-                    unsigned int const cols,
-                    unsigned int const rows,
-                    pixval       const maxval,
-                    ColorTable * const colorTableP,
-                    bool         const antiflag) {
+clearBackgroundCamo(pixel **           const pixels,
+                    unsigned int       const cols,
+                    unsigned int       const rows,
+                    pixval             const maxval,
+                    ColorTable *       const colorTableP,
+                    struct pm_randSt * const randStP,
+                    bool               const antiflag) {
 
     pixel color;
 
     if (colorTableP->count > 0) {
         color = colorTableP->color[0];
     } else if (antiflag)
-        color = randomAnticamoColor(maxval);
+        color = randomAnticamoColor(randStP, maxval);
     else
-        color = randomCamoColor(maxval);
+        color = randomCamoColor(randStP,maxval);
 
     ppmd_filledrectangle(
         pixels, cols, rows, maxval, 0, 0, cols, rows, PPMD_NULLDRAWPROC,
@@ -570,13 +600,14 @@ clearBackgroundCamo(pixel **     const pixels,
 
 
 static void
-camoFill(pixel **         const pixels,
-         unsigned int     const cols,
-         unsigned int     const rows,
-         pixval           const maxval,
-         struct fillobj * const fh,
-         ColorTable     * const colorTableP,
-         bool             const antiflag) {
+camoFill(pixel **           const pixels,
+         unsigned int       const cols,
+         unsigned int       const rows,
+         pixval             const maxval,
+         struct fillobj *   const fh,
+         ColorTable     *   const colorTableP,
+         struct pm_randSt * const randStP,
+         bool               const antiflag) {
 
     pixel color;
 
@@ -585,9 +616,9 @@ camoFill(pixel **         const pixels,
         color = colorTableP->color[colorTableP->index];
         nextColorBg(colorTableP);
     } else if (antiflag)
-        color = randomAnticamoColor(maxval);
+        color = randomAnticamoColor(randStP, maxval);
     else
-        color = randomCamoColor(maxval);
+        color = randomCamoColor(randStP, maxval);
 
     ppmd_fill(pixels, cols, rows, maxval, fh, PPMD_NULLDRAWPROC, &color);
 }
@@ -608,25 +639,29 @@ camoFill(pixel **         const pixels,
 
 
 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;
+computeXsYs(int *              const xs,
+            int *              const ys,
+            unsigned int       const cols,
+            unsigned int       const rows,
+            unsigned int       const pointCt,
+            struct pm_randSt * const randStP) {
+
+    unsigned int const cx = pm_rand(randStP) % cols;
+    unsigned int const cy = pm_rand(randStP) % rows;
+    double const a = rnduni(randStP) *
+                       (MAX_ELLIPSE_FACTOR - MIN_ELLIPSE_FACTOR) +
+                        MIN_ELLIPSE_FACTOR;
+    double const b = rnduni(randStP) *
+                       (MAX_ELLIPSE_FACTOR - MIN_ELLIPSE_FACTOR) +
+                        MIN_ELLIPSE_FACTOR;
+    double const theta = rnduni(randStP) * 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 c = rnduni(randStP) *
+                           (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;
@@ -638,18 +673,20 @@ computeXsYs(int *        const xs,
 
 
 static void
-camo(pixel **     const pixels,
-     unsigned int const cols,
-     unsigned int const rows,
-     ColorTable * const colorTableP,
-     pixval       const maxval,
-     bool         const antiflag) {
+camo(pixel **           const pixels,
+     unsigned int       const cols,
+     unsigned int       const rows,
+     ColorTable *       const colorTableP,
+     struct pm_randSt * const randStP,
+     pixval             const maxval,
+     bool               const antiflag) {
 
     unsigned int const n = (rows * cols) / SQR(BLOBRAD) * 5;
 
     unsigned int i;
 
-    clearBackgroundCamo(pixels, cols, rows, maxval, colorTableP, antiflag);
+    clearBackgroundCamo(pixels, cols, rows, maxval,
+                        colorTableP, randStP, antiflag);
 
     if (colorTableP->count > 0) {
         assert(colorTableP->count > 1);
@@ -658,13 +695,13 @@ camo(pixel **     const pixels,
 
     for (i = 0; i < n; ++i) {
         unsigned int const pointCt =
-            rand() % (MAX_POINTS - MIN_POINTS + 1) + MIN_POINTS;
+            pm_rand(randStP) % (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);
+        computeXsYs(xs, ys, cols, rows, pointCt, randStP);
 
         x0 = (xs[0] + xs[pointCt - 1]) / 2;
         y0 = (ys[0] + ys[pointCt - 1]) / 2;
@@ -675,7 +712,8 @@ camo(pixel **     const pixels,
             pixels, cols, rows, maxval, x0, y0, pointCt, xs, ys, x0, y0,
             ppmd_fill_drawproc, fh);
 
-        camoFill(pixels, cols, rows, maxval, fh, colorTableP, antiflag);
+        camoFill(pixels, cols, rows, maxval, fh,
+                 colorTableP, randStP, antiflag);
 
         ppmd_fill_destroy(fh);
     }
@@ -688,17 +726,20 @@ camo(pixel **     const pixels,
 -----------------------------------------------------------------------------*/
 
 static void
-gingham2(pixel **     const pixels,
-         unsigned int const cols,
-         unsigned int const rows,
-         ColorTable   const colorTable,
-         pixval       const maxval) {
+gingham2(pixel **           const pixels,
+         unsigned int       const cols,
+         unsigned int       const rows,
+         ColorTable         const colorTable,
+         struct pm_randSt * const randStP,
+         pixval             const maxval) {
 
     bool  const colorSpec = (colorTable.count > 0);
     pixel const backcolor = colorSpec ?
-                            colorTable.color[0] : randomDarkColor(maxval);
+                              colorTable.color[0] :
+                              randomDarkColor(randStP, maxval);
     pixel const forecolor = colorSpec ?
-                            colorTable.color[1] : randomBrightColor(maxval);
+                              colorTable.color[1] :
+                              randomBrightColor(randStP, maxval);
     unsigned int const colso2 = cols / 2;
     unsigned int const rowso2 = rows / 2;
 
@@ -722,19 +763,23 @@ gingham2(pixel **     const pixels,
 
 
 static void
-gingham3(pixel **     const pixels,
-         unsigned int const cols,
-         unsigned int const rows,
-         ColorTable   const colorTable,
-         pixval       const maxval) {
+gingham3(pixel **           const pixels,
+         unsigned int       const cols,
+         unsigned int       const rows,
+         ColorTable         const colorTable,
+         struct pm_randSt * const randStP,
+         pixval             const maxval) {
 
     bool  const colorSpec = (colorTable.count > 0);
-    pixel const backcolor = colorSpec ?
-                            colorTable.color[0] : randomDarkColor(maxval);
+    pixel const backcolor  = colorSpec ?
+                               colorTable.color[0] :
+                               randomDarkColor(randStP, maxval);
     pixel const fore1color = colorSpec ?
-                            colorTable.color[1] : randomBrightColor(maxval);
+                               colorTable.color[1] :
+                               randomBrightColor(randStP, maxval);
     pixel const fore2color = colorSpec ?
-                            colorTable.color[2] : randomBrightColor(maxval);
+                               colorTable.color[2] :
+                               randomBrightColor(randStP, maxval);
     unsigned int const colso4 = cols / 4;
     unsigned int const rowso4 = rows / 4;
 
@@ -770,19 +815,23 @@ gingham3(pixel **     const pixels,
 
 
 static void
-madras(pixel **     const pixels,
-       unsigned int const cols,
-       unsigned int const rows,
-       ColorTable   const colorTable,
-       pixval       const maxval) {
+madras(pixel **           const pixels,
+       unsigned int       const cols,
+       unsigned int       const rows,
+       ColorTable         const colorTable,
+       struct pm_randSt * const randStP,
+       pixval             const maxval) {
 
     bool  const colorSpec = (colorTable.count > 0);
-    pixel const backcolor = colorSpec ?
-                            colorTable.color[0] : randomDarkColor(maxval);
+    pixel const backcolor  = colorSpec ?
+                               colorTable.color[0] :
+                               randomDarkColor(randStP, maxval);
     pixel const fore1color = colorSpec ?
-                            colorTable.color[1] : randomBrightColor(maxval);
+                               colorTable.color[1] :
+                               randomBrightColor(randStP, maxval);
     pixel const fore2color = colorSpec ?
-                            colorTable.color[2] : randomBrightColor(maxval);
+                               colorTable.color[2] :
+                               randomBrightColor(randStP, maxval);
     unsigned int const cols2  = cols * 2 / 44;
     unsigned int const rows2  = rows * 2 / 44;
     unsigned int const cols3  = cols * 3 / 44;
@@ -899,19 +948,23 @@ madras(pixel **     const pixels,
 
 
 static void
-tartan(pixel **     const pixels,
-       unsigned int const cols,
-       unsigned int const rows,
-       ColorTable   const colorTable,
-       pixval       const maxval) {
+tartan(pixel **           const pixels,
+       unsigned int       const cols,
+       unsigned int       const rows,
+       ColorTable         const colorTable,
+       struct pm_randSt * const randStP,
+       pixval             const maxval) {
 
     bool  const colorSpec = (colorTable.count > 0);
-    pixel const backcolor = colorSpec ?
-                            colorTable.color[0] : randomDarkColor(maxval);
+    pixel const backcolor  = colorSpec ?
+                               colorTable.color[0] :
+                               randomDarkColor(randStP, maxval);
     pixel const fore1color = colorSpec ?
-                            colorTable.color[1] : randomBrightColor(maxval);
+                               colorTable.color[1] :
+                               randomBrightColor(randStP, maxval);
     pixel const fore2color = colorSpec ?
-                            colorTable.color[2] : randomBrightColor(maxval);
+                               colorTable.color[2] :
+                               randomBrightColor(randStP, maxval);
     unsigned int const cols1  = cols / 22;
     unsigned int const rows1  = rows / 22;
     unsigned int const cols3  = cols * 3 / 22;
@@ -1013,14 +1066,15 @@ argyle(pixel **     const pixels,
        unsigned int const cols,
        unsigned int const rows,
        ColorTable   const colorTable,
+       struct pm_randSt * const randStP,
        pixval       const maxval,
        bool         const stripes) {
 
     bool  const colorSpec = (colorTable.count > 0);
     pixel const backcolor = colorSpec ?
-        colorTable.color[0] : randomDarkColor(maxval);
+        colorTable.color[0] : randomDarkColor(randStP, maxval);
     pixel const forecolor = colorSpec ?
-        colorTable.color[1] : randomBrightColor(maxval);
+        colorTable.color[1] : randomBrightColor(randStP, maxval);
 
     /* Fill canvas with background to start */
     ppmd_filledrectangle(
@@ -1032,7 +1086,8 @@ argyle(pixel **     const pixels,
     if (stripes) {
          /* Connect corners with thin stripes */
          pixel const stripecolor =
-             colorSpec ? colorTable.color[2] : randomBrightColor(maxval);
+             colorSpec ? colorTable.color[2] :
+                         randomBrightColor(randStP, maxval);
 
          ppmd_line(pixels, cols, rows, maxval, 0, 0, cols-1, rows-1,
               PPMD_NULLDRAWPROC, (char *) &stripecolor);
@@ -1049,32 +1104,33 @@ argyle(pixel **     const pixels,
 
 
 
-#define MAXPOLES 500
+static unsigned int const MAXPOLES = 500;
 
 
 
 static void
-placeAndColorPolesRandomly(int *        const xs,
-                           int *        const ys,
-                           pixel *      const colors,
-                           unsigned int const cols,
-                           unsigned int const rows,
-                           pixval       const maxval,
-                           ColorTable * const colorTableP,
-                           unsigned int const poleCt) {
+placeAndColorPolesRandomly(int *              const xs,
+                           int *              const ys,
+                           pixel *            const colors,
+                           unsigned int       const cols,
+                           unsigned int       const rows,
+                           pixval             const maxval,
+                           ColorTable *       const colorTableP,
+                           struct pm_randSt * const randStP,
+                           unsigned int       const poleCt) {
 
     unsigned int i;
 
     for (i = 0; i < poleCt; ++i) {
 
-        xs[i] = rand() % cols;
-        ys[i] = rand() % rows;
+        xs[i] = pm_rand(randStP) % cols;
+        ys[i] = pm_rand(randStP) % rows;
 
         if (colorTableP->count > 0) {
             colors[i] = colorTableP->color[colorTableP->index];
             nextColor(colorTableP);
         } else
-            colors[i] = randomBrightColor(maxval);
+            colors[i] = randomBrightColor(randStP, maxval);
     }
 }
 
@@ -1104,11 +1160,12 @@ assignInterpolatedColor(pixel * const resultP,
 
 
 static void
-poles(pixel **     const pixels,
-      unsigned int const cols,
-      unsigned int const rows,
-      ColorTable * const colorTableP,
-      pixval       const maxval) {
+poles(pixel **           const pixels,
+      unsigned int       const cols,
+      unsigned int       const rows,
+      ColorTable *       const colorTableP,
+      struct pm_randSt * const randStP,
+      pixval             const maxval) {
 
     unsigned int const poleCt = MAX(2, MIN(MAXPOLES, cols * rows / 30000));
 
@@ -1117,7 +1174,7 @@ poles(pixel **     const pixels,
     unsigned int row;
 
     placeAndColorPolesRandomly(xs, ys, colors, cols, rows, maxval,
-                               colorTableP, poleCt);
+                               colorTableP, randStP, poleCt);
 
     /* Interpolate points */
 
@@ -1236,11 +1293,12 @@ sqRainbowCircleDrawproc(pixel **     const pixels,
 
 
 static void
-chooseSqPoleColors(ColorTable * const colorTableP,
-                   pixval       const maxval,
-                   pixel *      const color1P,
-                   pixel *      const color2P,
-                   pixel *      const color3P) {
+chooseSqPoleColors(ColorTable *       const colorTableP,
+                   pixval             const maxval,
+                   pixel *            const color1P,
+                   pixel *            const color2P,
+                   pixel *            const color3P,
+                   struct pm_randSt * const randStP) {
 
     if (colorTableP->count > 0) {
         *color1P = colorTableP->color[colorTableP->index];
@@ -1250,19 +1308,20 @@ chooseSqPoleColors(ColorTable * const colorTableP,
         *color3P = colorTableP->color[colorTableP->index];
         nextColor(colorTableP);
     } else {
-        *color1P = randomBrightColor(maxval);
-        *color2P = randomBrightColor(maxval);
-        *color3P = randomBrightColor(maxval);
+        *color1P = randomBrightColor(randStP, maxval);
+        *color2P = randomBrightColor(randStP, maxval);
+        *color3P = randomBrightColor(randStP, maxval);
     }
 }
 
 
 
 static void
-sqAssignColors(unsigned int const circlecount,
-               pixval       const maxval,
-               ColorTable * const colorTableP,
-               pixel *      const colors) {
+sqAssignColors(unsigned int       const circlecount,
+               pixval             const maxval,
+               ColorTable *       const colorTableP,
+               pixel *            const colors,
+               struct pm_randSt * const randStP) {
 
     float const cco3 = (circlecount - 1) / 3.0;
 
@@ -1271,7 +1330,7 @@ sqAssignColors(unsigned int const circlecount,
     pixel rc3;
     unsigned int i;
 
-    chooseSqPoleColors(colorTableP, maxval, &rc1, &rc2, &rc3);
+    chooseSqPoleColors(colorTableP, maxval, &rc1, &rc2, &rc3, randStP);
 
     for (i = 0; i < circlecount; ++i) {
         if (i < cco3) {
@@ -1333,24 +1392,25 @@ clearBackgroundSquig(pixel **     const pixels,
 
 
 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) {
+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,
+                      struct pm_randSt * const randStP) {
+
+    switch (pm_rand(randStP) % 4) {
     case 0:
-        p1P->x = rand() % cols;
+        p1P->x = pm_rand(randStP) % cols;
         p1P->y = 0;
         if (p1P->x < cols / 2)
-            pFirstP->x = rand() % (p1P->x * 2 + 1);
+            pFirstP->x = pm_rand(randStP) % (p1P->x * 2 + 1);
         else
-            pFirstP->x = cols - 1 - rand() % ((cols - p1P->x) * 2);
-        pFirstP->y = rand() % rows;
+            pFirstP->x = cols - 1 - pm_rand(randStP) % ((cols - p1P->x) * 2);
+        pFirstP->y = pm_rand(randStP) % rows;
         p2P->x = p1P->x;
         p2P->y = rows - 1;
         pLastP->x = 2 * p2P->x - pFirstP->x;
@@ -1362,13 +1422,13 @@ chooseWrapAroundPoint(unsigned int const cols,
         break;
 
     case 1:
-        p2P->x = rand() % cols;
+        p2P->x = pm_rand(randStP) % cols;
         p2P->y = 0;
         if (p2P->x < cols / 2)
-            pLastP->x = rand() % (p2P->x * 2 + 1);
+            pLastP->x = pm_rand(randStP) % (p2P->x * 2 + 1);
         else
-            pLastP->x = cols - 1 - rand() % ((cols - p2P->x) * 2);
-        pLastP->y = rand() % rows;
+            pLastP->x = cols - 1 - pm_rand(randStP) % ((cols - p2P->x) * 2);
+        pLastP->y = pm_rand(randStP) % rows;
         p1P->x = p2P->x;
         p1P->y = rows - 1;
         pFirstP->x = 2 * p1P->x - pLastP->x;
@@ -1381,12 +1441,12 @@ chooseWrapAroundPoint(unsigned int const cols,
 
     case 2:
         p1P->x = 0;
-        p1P->y = rand() % rows;
-        pFirstP->x = rand() % cols;
+        p1P->y = pm_rand(randStP) % rows;
+        pFirstP->x = pm_rand(randStP) % cols;
         if (p1P->y < rows / 2)
-            pFirstP->y = rand() % (p1P->y * 2 + 1);
+            pFirstP->y = pm_rand(randStP) % (p1P->y * 2 + 1);
         else
-            pFirstP->y = rows - 1 - rand() % ((rows - p1P->y) * 2);
+            pFirstP->y = rows - 1 - pm_rand(randStP) % ((rows - p1P->y) * 2);
         p2P->x = cols - 1;
         p2P->y = p1P->y;
         pLastP->x = p2P->x - pFirstP->x;
@@ -1399,12 +1459,12 @@ chooseWrapAroundPoint(unsigned int const cols,
 
     case 3:
         p2P->x = 0;
-        p2P->y = rand() % rows;
-        pLastP->x = rand() % cols;
+        p2P->y = pm_rand(randStP) % rows;
+        pLastP->x = pm_rand(randStP) % cols;
         if (p2P->y < rows / 2)
-            pLastP->y = rand() % (p2P->y * 2 + 1);
+            pLastP->y = pm_rand(randStP) % (p2P->y * 2 + 1);
         else
-            pLastP->y = rows - 1 - rand() % ((rows - p2P->y) * 2);
+            pLastP->y = rows - 1 - pm_rand(randStP) % ((rows - p2P->y) * 2);
         p1P->x = cols - 1;
         p1P->y = p2P->y;
         pFirstP->x = p1P->x - pLastP->x;
@@ -1420,11 +1480,12 @@ chooseWrapAroundPoint(unsigned int const cols,
 
 
 static void
-squig(pixel **     const pixels,
-      unsigned int const cols,
-      unsigned int const rows,
-      ColorTable * const colorTableP,
-      pixval       const maxval) {
+squig(pixel **           const pixels,
+      unsigned int       const cols,
+      unsigned int       const rows,
+      ColorTable *       const colorTableP,
+      struct pm_randSt * const randStP,
+      pixval             const maxval) {
 
     int i;
 
@@ -1453,10 +1514,11 @@ squig(pixel **     const pixels,
         ppmd_circlep(pixels, cols, rows, maxval,
                      ppmd_makePoint(0, 0), radius,
                      sqMeasureCircleDrawproc, &sqClientData);
-        sqAssignColors(squig.circleCt, maxval, colorTableP, squig.color);
+        sqAssignColors(squig.circleCt, maxval, colorTableP, squig.color,
+                       randStP);
 
         chooseWrapAroundPoint(cols, rows, &c[0], &c[SQ_POINTS-1],
-                              &p0, &p1, &p2, &p3);
+                              &p0, &p1, &p2, &p3, randStP);
 
         {
             /* Do the middle points */
@@ -1466,8 +1528,8 @@ squig(pixel **     const pixels,
               /* validateSquigAspect() assures that
                  cols - 2 * radius, rows -2 * radius are positive
               */
-                c[j].x = (rand() % (cols - 2 * radius)) + radius;
-                c[j].y = (rand() % (rows - 2 * radius)) + radius;
+                c[j].x = (pm_rand(randStP) % (cols - 2 * radius)) + radius;
+                c[j].y = (pm_rand(randStP) % (rows - 2 * radius)) + radius;
             }
         }
 
@@ -1490,6 +1552,7 @@ main(int argc, const char ** argv) {
 
     struct CmdlineInfo cmdline;
     pixel ** pixels;
+    struct pm_randSt randSt;
 
     pm_proginit(&argc, argv);
 
@@ -1497,65 +1560,68 @@ main(int argc, const char ** argv) {
 
     validateComputableDimensions(cmdline.width, cmdline.height);
 
-    srand(cmdline.randomseedSpec ? cmdline.randomseed : pm_randseed());
+    pm_randinit(&randSt);
+    pm_srand2(&randSt, cmdline.randomseedSpec, cmdline.randomseed);
 
     pixels = ppm_allocarray(cmdline.width, cmdline.height);
 
     switch (cmdline.basePattern) {
     case PAT_GINGHAM2:
         gingham2(pixels, cmdline.width, cmdline.height,
-                 cmdline.colorTable, PPM_MAXMAXVAL);
+                 cmdline.colorTable, &randSt, PPM_MAXMAXVAL);
         break;
 
     case PAT_GINGHAM3:
         gingham3(pixels, cmdline.width, cmdline.height,
-                 cmdline.colorTable, PPM_MAXMAXVAL);
+                 cmdline.colorTable, &randSt, PPM_MAXMAXVAL);
         break;
 
     case PAT_MADRAS:
         madras(pixels, cmdline.width, cmdline.height,
-               cmdline.colorTable, PPM_MAXMAXVAL);
+               cmdline.colorTable, &randSt, PPM_MAXMAXVAL);
         break;
 
     case PAT_TARTAN:
         tartan(pixels, cmdline.width, cmdline.height,
-               cmdline.colorTable, PPM_MAXMAXVAL);
+               cmdline.colorTable, &randSt, PPM_MAXMAXVAL);
         break;
 
     case PAT_ARGYLE1:
         argyle(pixels, cmdline.width, cmdline.height,
-               cmdline.colorTable, PPM_MAXMAXVAL, FALSE);
+               cmdline.colorTable, &randSt, PPM_MAXMAXVAL, FALSE);
         break;
 
     case PAT_ARGYLE2:
         argyle(pixels, cmdline.width, cmdline.height,
-               cmdline.colorTable, PPM_MAXMAXVAL, TRUE);
+               cmdline.colorTable, &randSt, PPM_MAXMAXVAL, TRUE);
         break;
 
     case PAT_POLES:
         poles(pixels, cmdline.width, cmdline.height,
-              &cmdline.colorTable, PPM_MAXMAXVAL);
+              &cmdline.colorTable, &randSt, PPM_MAXMAXVAL);
         break;
 
     case PAT_SQUIG:
         squig(pixels, cmdline.width, cmdline.height,
-              &cmdline.colorTable, PPM_MAXMAXVAL);
+              &cmdline.colorTable, &randSt, PPM_MAXMAXVAL);
         break;
 
     case PAT_CAMO:
         camo(pixels, cmdline.width, cmdline.height,
-             &cmdline.colorTable, PPM_MAXMAXVAL, 0);
+             &cmdline.colorTable, &randSt, PPM_MAXMAXVAL, 0);
         break;
 
     case PAT_ANTICAMO:
         camo(pixels, cmdline.width, cmdline.height,
-             &cmdline.colorTable, PPM_MAXMAXVAL, 1);
+             &cmdline.colorTable, &randSt, PPM_MAXMAXVAL, 1);
         break;
 
     default:
         pm_error("can't happen!");
     }
 
+    pm_randterm(&randSt);
+
     ppm_writeppm(stdout, pixels, cmdline.width, cmdline.height,
                  PPM_MAXMAXVAL, 0);
 
@@ -1567,4 +1633,3 @@ main(int argc, const char ** argv) {
 }
 
 
-