about summary refs log tree commit diff
path: root/editor/specialty
diff options
context:
space:
mode:
Diffstat (limited to 'editor/specialty')
-rw-r--r--editor/specialty/pampaintspill.c32
-rw-r--r--editor/specialty/ppmshift.c124
-rw-r--r--editor/specialty/ppmspread.c206
3 files changed, 221 insertions, 141 deletions
diff --git a/editor/specialty/pampaintspill.c b/editor/specialty/pampaintspill.c
index c7994723..5cd482d5 100644
--- a/editor/specialty/pampaintspill.c
+++ b/editor/specialty/pampaintspill.c
@@ -45,11 +45,11 @@
 
 #include "mallocvar.h"
 #include "nstring.h"
+#include "rand.h"
 #include "shhopt.h"
 #include "pam.h"
 #include "pammap.h"
 
-
 static time_t const timeUpdateDelta = 30;
     /* Seconds between progress updates */
 static int const    minUpdates = 4;
@@ -67,6 +67,8 @@ struct cmdlineInfo {
     unsigned int all;
     float        power;
     unsigned int downsample;
+    unsigned int randomseedSpec;
+    unsigned int randomseed;
 };
 
 struct coords {
@@ -98,16 +100,18 @@ parseCommandLine(int argc, const char ** const argv,
     MALLOCARRAY_NOFAIL(option_def, 100);
     option_def_index = 0;          /* Incremented by OPTENTRY */
 
-    OPTENT3(0, "bgcolor",    OPT_STRING, &cmdlineP->bgcolor,    
+    OPTENT3(0, "bgcolor",    OPT_STRING, &cmdlineP->bgcolor,
             &bgcolorSpec, 0);
     OPTENT3(0, "wrap",       OPT_FLAG,   NULL,
             &cmdlineP->wrap,       0);
     OPTENT3(0, "all",        OPT_FLAG,   NULL,
             &cmdlineP->all,        0);
-    OPTENT3(0, "power",      OPT_FLOAT,  &cmdlineP->power,      
+    OPTENT3(0, "power",      OPT_FLOAT,  &cmdlineP->power,
             &powerSpec, 0);
-    OPTENT3(0, "downsample", OPT_UINT,   &cmdlineP->downsample, 
+    OPTENT3(0, "downsample", OPT_UINT,   &cmdlineP->downsample,
             &downsampleSpec, 0);
+    OPTENT3(0, "randomseed", OPT_UINT,   &cmdlineP->randomseed,
+            &cmdlineP->randomseedSpec, 0);
 
     opt.opt_table = option_def;
     opt.short_allowed = 0;
@@ -223,7 +227,9 @@ locatePaintSources(struct pam *            const pamP,
                    tuple **                const tuples,
                    tuple                   const bgColor,
                    unsigned int            const downsample,
-                   struct paintSourceSet * const paintSourcesP) {
+                   struct paintSourceSet * const paintSourcesP,
+                   bool                    const randomseedSpec,
+                   unsigned int            const randomseed) {
 /*--------------------------------------------------------------------
   Construct a list of all pixel coordinates in the input image that
   represent a non-background color.
@@ -248,21 +254,24 @@ locatePaintSources(struct pam *            const pamP,
     pm_message("Image contains %u background + %u non-background pixels",
                pamP->width * pamP->height - paintSources.size,
                paintSources.size);
-    
+
     /* Reduce the number of paint sources to reduce execution time. */
     if (downsample > 0 && downsample < paintSources.size) {
+        struct pm_randSt randSt;
         unsigned int i;
 
-        srand(pm_randseed());
+        pm_randinit(&randSt);
+        pm_srand2(&randSt, randomseedSpec, randomseed);
 
         for (i = 0; i < downsample; ++i) {
             unsigned int const swapIdx =
-                i + rand() % (paintSources.size - i);
+                i + pm_rand(&randSt) % (paintSources.size - i);
             struct coords const swapVal = paintSources.list[i];
 
             paintSources.list[i] = paintSources.list[swapIdx];
             paintSources.list[swapIdx] = swapVal;
         }
+        pm_randterm(&randSt);
         paintSources.size = downsample;
     }
 
@@ -426,7 +435,7 @@ produceOutputImage(struct pam *          const pamP,
     for (row = 0; row < pamP->height; ++row) {
         struct coords   target;
         double        * newColor;
-        
+
         MALLOCARRAY(newColor, pamP->depth);
 
         target.y = row;
@@ -484,7 +493,8 @@ main(int argc, const char *argv[]) {
                pnm_colorname(&inPam, bgColor, PAM_COLORNAME_HEXOK));
 
     locatePaintSources(&inPam, inTuples, bgColor, cmdline.downsample,
-                       &paintSources);
+                       &paintSources,
+                       cmdline.randomseedSpec, cmdline.randomseed);
 
     produceOutputImage(&inPam, inTuples, bgColor, paintSources, distFunc,
                        cmdline.power, cmdline.all, &outTuples);
@@ -498,3 +508,5 @@ main(int argc, const char *argv[]) {
 
     return 0;
 }
+
+
diff --git a/editor/specialty/ppmshift.c b/editor/specialty/ppmshift.c
index cdb0f173..27cbb78c3 100644
--- a/editor/specialty/ppmshift.c
+++ b/editor/specialty/ppmshift.c
@@ -12,11 +12,11 @@
 #include <stdbool.h>
 
 #include "mallocvar.h"
+#include "rand.h"
 #include "shhopt.h"
 #include "ppm.h"
 
 
-
 struct CmdlineInfo {
     /* All the information the user supplied in the command line,
        in a form easy for the program to use.
@@ -24,6 +24,7 @@ struct CmdlineInfo {
     const char * inputFileName;
 
     unsigned int shift;
+    unsigned int seedSpec;
     unsigned int seed;
 };
 
@@ -42,8 +43,6 @@ parseCommandLine(int argc, const char ** const argv,
 
     unsigned int option_def_index;
 
-    unsigned int seedSpec;
-
     MALLOCARRAY(option_def, 100);
 
     opt.opt_table = option_def;
@@ -52,14 +51,11 @@ parseCommandLine(int argc, const char ** const argv,
 
     option_def_index = 0;   /* incremented by OPTENT3 */
     OPTENT3(0,   "seed",            OPT_UINT,     &cmdlineP->seed,
-            &seedSpec,         0);
+            &cmdlineP->seedSpec,         0);
 
     pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
-    if (!seedSpec)
-        cmdlineP->seed = pm_randseed();
-
     if (argc-1 < 1)
         pm_error("You must specify the shift factor as an argument");
     else {
@@ -84,6 +80,62 @@ parseCommandLine(int argc, const char ** const argv,
 
 
 
+static void
+shiftRow(pixel *            const srcrow,
+         unsigned int       const cols,
+         unsigned int       const shift,
+         pixel *            const destrow,
+         struct pm_randSt * const randStP) {
+
+    /* the range by which a line is shifted lays in the range from */
+    /* -shift/2 .. +shift/2 pixels; however, within this range it is */
+    /* randomly chosen */
+
+    pixel * pP;
+    pixel * pP2;
+    int nowshift;
+
+    if (shift != 0)
+        nowshift = (pm_rand(randStP) % (shift+1)) - ((shift+1) / 2);
+    else
+        nowshift = 0;
+
+    pP  = &srcrow[0];
+    pP2 = &destrow[0];
+
+    /* if the shift value is less than zero, we take the original
+       pixel line and copy it into the destination line translated
+       to the left by x pixels. The empty pixels on the right end
+       of the destination line are filled up with the pixel that
+       is the right-most in the original pixel line.
+    */
+    if (nowshift < 0) {
+        unsigned int col;
+        pP += abs(nowshift);
+        for (col = 0; col < cols; ++col) {
+            PPM_ASSIGN(*pP2, PPM_GETR(*pP), PPM_GETG(*pP), PPM_GETB(*pP));
+            ++pP2;
+            if (col < (cols + nowshift) - 1)
+                ++pP;
+        }
+    } else {
+        unsigned int col;
+        /* The shift value is 0 or positive, so fill the first
+           <nowshift> pixels of the destination line with the
+           first pixel from the source line, and copy the rest of
+           the source line to the dest line
+        */
+        for (col = 0; col < cols; ++col) {
+            PPM_ASSIGN(*pP2, PPM_GETR(*pP), PPM_GETG(*pP), PPM_GETB(*pP));
+            ++pP2;
+            if (col >= nowshift)
+                ++pP;
+        }
+    }
+}
+
+
+
 int
 main(int argc, const char ** argv) {
 
@@ -95,13 +147,15 @@ main(int argc, const char ** argv) {
     pixel * destrow;
     unsigned int row;
     unsigned int shift;
+    struct pm_randSt randSt;
 
     /* parse in 'default' parameters */
     pm_proginit(&argc, argv);
 
     parseCommandLine(argc, argv, &cmdline);
 
-    srand(cmdline.seed);
+    pm_randinit(&randSt);
+    pm_srand2(&randSt, cmdline.seedSpec, cmdline.seed);
 
     ifP = pm_openr(cmdline.inputFileName);
 
@@ -115,67 +169,23 @@ main(int argc, const char ** argv) {
     } else
         shift = cmdline.shift;
 
-    srcrow = ppm_allocrow(cols);
-
+    srcrow  = ppm_allocrow(cols);
     destrow = ppm_allocrow(cols);
 
     ppm_writeppminit(stdout, cols, rows, maxval, 0);
 
-    /** now do the shifting **/
-    /* the range by which a line is shifted lays in the range from */
-    /* -shift/2 .. +shift/2 pixels; however, within this range it is */
-    /* randomly chosen */
     for (row = 0; row < rows; ++row) {
-        pixel * pP;
-        pixel * pP2;
-        unsigned int nowshift;
-
-        if (shift != 0)
-            nowshift = (rand() % (shift+1)) - ((shift+1) / 2);
-        else
-            nowshift = 0;
-
         ppm_readppmrow(ifP, srcrow, cols, maxval, format);
 
-        pP  = &srcrow[0];
-        pP2 = &destrow[0];
-
-        /* if the shift value is less than zero, we take the original
-           pixel line and copy it into the destination line translated
-           to the left by x pixels. The empty pixels on the right end
-           of the destination line are filled up with the pixel that
-           is the right-most in the original pixel line.
-        */
-        if (nowshift < 0) {
-            unsigned int col;
-            pP += abs(nowshift);
-            for (col = 0; col < cols; ++col) {
-                PPM_ASSIGN(*pP2, PPM_GETR(*pP), PPM_GETG(*pP), PPM_GETB(*pP));
-                ++pP2;
-                if (col < (cols + nowshift) - 1)
-                    ++pP;
-            }
-        } else {
-            unsigned int col;
-            /* The shift value is 0 or positive, so fill the first
-               <nowshift> pixels of the destination line with the
-               first pixel from the source line, and copy the rest of
-               the source line to the dest line
-            */
-            for (col = 0; col < cols; ++col) {
-                PPM_ASSIGN(*pP2, PPM_GETR(*pP), PPM_GETG(*pP), PPM_GETB(*pP));
-                ++pP2;
-                if (col >= nowshift)
-                    ++pP;
-            }
-        }
+        shiftRow(srcrow, cols, shift, destrow, &randSt);
 
         ppm_writeppmrow(stdout, destrow, cols, maxval, 0);
     }
 
-    pm_close(ifP);
-    ppm_freerow(srcrow);
     ppm_freerow(destrow);
+    ppm_freerow(srcrow);
+    pm_close(ifP);
+    pm_randterm(&randSt);
 
     return 0;
 }
diff --git a/editor/specialty/ppmspread.c b/editor/specialty/ppmspread.c
index 6753f4fe..7b9558e3 100644
--- a/editor/specialty/ppmspread.c
+++ b/editor/specialty/ppmspread.c
@@ -10,102 +10,158 @@
 
 #include <string.h>
 
+#include "nstring.h"
+#include "rand.h"
+#include "shhopt.h"
 #include "ppm.h"
 
 
+struct CmdlineInfo {
+    /* This structure represents all of the information the user
+       supplied in the command line but in a form that's easy for the
+       program to use.
+    */
+    const char * inputFilename;  /* '-' if stdin */
+    unsigned int spread;
+    unsigned int randomseedSpec;
+    unsigned int randomseed;
+};
+
+
+
+static void
+parseCommandLine(int argc, const char ** const argv,
+                 struct CmdlineInfo * const cmdlineP ) {
+
+    optEntry     * option_def;
+        /* Instructions to OptParseOptions3 on how to parse our options */
+    optStruct3     opt;
+    unsigned int   option_def_index;
+
+    MALLOCARRAY_NOFAIL(option_def, 100);
+    option_def_index = 0;          /* Incremented by OPTENTRY */
+
+    OPTENT3(0, "randomseed", OPT_UINT,   &cmdlineP->randomseed,
+            &cmdlineP->randomseedSpec, 0);
+
+    opt.opt_table = option_def;
+    opt.short_allowed = 0;
+    opt.allowNegNum = 1;
+
+    pm_optParseOptions3( &argc, (char **)argv, opt, sizeof(opt), 0 );
+
+    if (argc-1 < 1)
+        pm_error("You must specify the spread factor as an argument");
+    else {
+        const char * error;
+        pm_string_to_uint(argv[1], &cmdlineP->spread, &error);
+
+        if (error)
+            pm_error("Spread factor '%s' is not an unsigned integer.  %s",
+                     argv[1], error);
+
+        if (argc-1 < 2)
+            cmdlineP->inputFilename = "-";
+        else {
+            cmdlineP->inputFilename = argv[2];
+            if (argc-1 >2)
+                pm_error("Too many arguments: %u.  "
+                         "The only possible arguments are "
+                         "the spread factor and the optional input file name",
+                         argc-1);
+        }
+    }
+}
+
+
+
+static void
+spreadRow(pixel **           const srcarray,
+          unsigned int       const cols,
+          unsigned int       const rows,
+          unsigned int       const spread,
+          unsigned int       const row,
+          pixel **           const destarray,
+          struct pm_randSt * const randStP) {
+
+    unsigned int col;
+
+    for (col = 0; col < cols; ++col) {
+        pixel const p = srcarray[row][col];
+
+        int const xdis = (pm_rand(randStP) % (spread + 1) )
+            - ((spread + 1) / 2);
+        int const ydis = (pm_rand(randStP) % (spread + 1))
+            - ((spread + 1) / 2);
+
+        int const xnew = col + xdis;
+        int const ynew = row + ydis;
+
+        /* only set the displaced pixel if it's within the bounds
+           of the image
+        */
+        if (xnew >= 0 && xnew < cols && ynew >= 0 && ynew < rows) {
+            /* Displacing a pixel is accomplished by swapping it
+               with another pixel in its vicinity.
+            */
+            pixel const p2 = srcarray[ynew][xnew];
+                /* Original value of second pixel */
+
+            /* Set second pixel to new value */
+            PPM_ASSIGN(destarray[ynew][xnew],
+                       PPM_GETR(p), PPM_GETG(p), PPM_GETB(p));
+
+            /* Set first pixel to (old) value of second */
+            PPM_ASSIGN(destarray[row][col],
+                       PPM_GETR(p2), PPM_GETG(p2), PPM_GETB(p2));
+        } else {
+            /* Displaced pixel is out of bounds; leave the old pixel there.
+            */
+            PPM_ASSIGN(destarray[row][col],
+                       PPM_GETR(p), PPM_GETG(p), PPM_GETB(p));
+        }
+    }
+}
+
+
 
 int
-main(int    argc,
-     char * argv[]) {
+main(int          argc,
+     const char * argv[]) {
 
+    struct CmdlineInfo cmdline;
     FILE * ifP;
-    int argn, rows, cols;
+    int rows, cols;
     unsigned int row;
-    pixel ** destarray, ** srcarray;
-    pixel * pP;
-    pixel * pP2;
+    pixel ** destarray;
+    pixel ** srcarray;
     pixval maxval;
-    pixval r1, g1, b1;
-    int amount;
-    const char * const usage = "amount [ppmfile]\n        amount: # of pixels to displace a pixel by at most\n";
-
-    /* parse in 'default' parameters */
-    ppm_init(&argc, argv);
-
-    argn = 1;
-
-    /* parse in amount & seed */
-    if (argn == argc)
-        pm_usage(usage);
-    if (sscanf(argv[argn], "%d", &amount) != 1)
-        pm_usage(usage);
-    if (amount < 0)
-        pm_error("amount should be a positive number");
-    ++argn;
-
-    /* parse in filename (if present, stdin otherwise) */
-    if (argn != argc)
-    {
-        ifP = pm_openr(argv[argn]);
-        ++argn;
-    }
-    else
-        ifP = stdin;
+    struct pm_randSt randSt;
 
-    if (argn != argc)
-        pm_usage(usage);
+    pm_proginit(&argc, argv);
+
+    parseCommandLine(argc, argv, &cmdline);
+
+    ifP = pm_openr(cmdline.inputFilename);
 
     srcarray = ppm_readppm(ifP, &cols, &rows, &maxval);
 
     destarray = ppm_allocarray(cols, rows);
 
+    pm_randinit(&randSt);
+    pm_srand2(&randSt, cmdline.randomseedSpec, cmdline.randomseed);
+
     /* clear out the buffer */
     for (row = 0; row < rows; ++row)
         memset(destarray[row], 0, cols * sizeof(pixel));
 
-    srand(pm_randseed());
-
-    /* start displacing pixels */
+    /* Displace pixels */
     for (row = 0; row < rows; ++row) {
-        unsigned int col;
-        pP = &srcarray[row][0];
-
-        for (col = 0; col < cols; ++col) {
-            int const xdis = (rand() % (amount+1)) - ((amount+1) / 2);
-            int const ydis = (rand() % (amount+1)) - ((amount+1) / 2);
+        spreadRow(srcarray, cols, rows, cmdline.spread, row,
+                  destarray, &randSt);
 
-            int const xnew = col + xdis;
-            int const ynew = row + ydis;
-
-            /* only set the displaced pixel if it's within the bounds
-               of the image
-            */
-            if (xnew >= 0 && xnew < cols && ynew >= 0 && ynew < rows) {
-                /* displacing a pixel is accomplished by swapping it
-                   with another pixel in its vicinity - so, first
-                   store other pixel's RGB
-                */
-                pP2 = &srcarray[ynew][xnew];
-                r1 = PPM_GETR(*pP2);
-                g1 = PPM_GETG(*pP2);
-                b1 = PPM_GETB(*pP2);
-                /* set second pixel to new value */
-                pP2 = &destarray[ynew][xnew];
-                PPM_ASSIGN(*pP2, PPM_GETR(*pP), PPM_GETG(*pP), PPM_GETB(*pP));
-                
-                /* now, set first pixel to (old) value of second */
-                pP2 = &destarray[row][col];
-                PPM_ASSIGN(*pP2, r1, g1, b1);
-            } else {
-                /* displaced pixel is out of bounds; leave the old
-                   pixel there
-                */
-                pP2 = &destarray[row][col];
-                PPM_ASSIGN(*pP2, PPM_GETR(*pP), PPM_GETG(*pP), PPM_GETB(*pP));
-            }
-            ++pP;
-        }
     }
+    pm_randterm(&randSt);
 
     ppm_writeppm(stdout, destarray, cols, rows, maxval, 0);
 
@@ -115,3 +171,5 @@ main(int    argc,
 
     return 0;
 }
+
+