about summary refs log tree commit diff
path: root/generator/ppmrough.c
diff options
context:
space:
mode:
Diffstat (limited to 'generator/ppmrough.c')
-rw-r--r--generator/ppmrough.c530
1 files changed, 283 insertions, 247 deletions
diff --git a/generator/ppmrough.c b/generator/ppmrough.c
index b21adedf..e749c9c2 100644
--- a/generator/ppmrough.c
+++ b/generator/ppmrough.c
@@ -15,6 +15,7 @@
 #include <sys/time.h>
 
 #include "pm_c_util.h"
+#include "mallocvar.h"
 #include "shhopt.h"
 #include "ppm.h"
 
@@ -22,274 +23,309 @@ static pixel** PIX;
 static pixval BG_RED, BG_GREEN, BG_BLUE;
 
 
-struct cmdlineInfo {
+struct CmdlineInfo {
   /* All the information the user supplied in the command line,
      in a form easy for the program to use.
   */
-  unsigned int left, right, top, bottom;
-  unsigned int width, height, var;
-  const char *bg_rgb;
-  const char *fg_rgb;
-  unsigned init;
-  unsigned int verbose;
+    unsigned int left, right, top, bottom;
+    unsigned int width, height, var;
+    const char * bg_rgb;
+    const char * fg_rgb;
+    unsigned int randomseed;
+    unsigned int randomseedSpec;
+    unsigned int verbose;
 };
 
 
 static void
-/*-------------------------------------------------------------------------- */
-   parseCommandLine(int argc, char ** argv, struct cmdlineInfo *cmdlineP)
-/*-------------------------------------------------------------------------- */
-{
-  optEntry *option_def = malloc(100*sizeof(optEntry));
-    /* Instructions to OptParseOptions2 on how to parse our options.    */
-  optStruct3 opt;
-
-  unsigned int option_def_index;
-
-  option_def_index = 0;   /* incremented by OPTENTRY */
-  OPTENT3(0, "width",   OPT_UINT,   &cmdlineP->width,   NULL, 0);
-  OPTENT3(0, "height",  OPT_UINT,   &cmdlineP->height,  NULL, 0);
-  OPTENT3(0, "left",    OPT_UINT,   &cmdlineP->left,    NULL, 0);
-  OPTENT3(0, "right",   OPT_UINT,   &cmdlineP->right,   NULL, 0);
-  OPTENT3(0, "top",     OPT_UINT,   &cmdlineP->top,     NULL, 0);
-  OPTENT3(0, "bottom",  OPT_UINT,   &cmdlineP->bottom,  NULL, 0);
-  OPTENT3(0, "bg",      OPT_STRING, &cmdlineP->bg_rgb,  NULL, 0);
-  OPTENT3(0, "fg",      OPT_STRING, &cmdlineP->fg_rgb,  NULL, 0);
-  OPTENT3(0, "var",     OPT_UINT,   &cmdlineP->var,     NULL, 0);
-  OPTENT3(0, "init",    OPT_UINT,   &cmdlineP->init,    NULL, 0);
-  OPTENT3(0, "verbose", OPT_FLAG,   NULL, &cmdlineP->verbose, 0);
-
-  /* Set the defaults */
-  cmdlineP->width = 100;
-  cmdlineP->height = 100;
-  cmdlineP->left = cmdlineP->right = cmdlineP->top = cmdlineP->bottom = -1;
-  cmdlineP->bg_rgb = NULL;
-  cmdlineP->fg_rgb = NULL;
-  cmdlineP->var = 10;
-
-  opt.opt_table = option_def;
-  opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
-  opt.allowNegNum = FALSE;  /* We have no parms that are negative numbers */
-
-  optParseOptions3(&argc, argv, opt, sizeof(opt), 0);
-
-  if (argc-1 != 0)
-    pm_error("There are no arguments.  You specified %d.", argc-1);
+parseCommandLine(int argc, const char ** argv,
+                 struct CmdlineInfo * const cmdlineP) {
+
+    optEntry * option_def;
+        /* Instructions to OptParseOptions2 on how to parse our options.    */
+    optStruct3 opt;
+
+    unsigned int option_def_index;
+
+    MALLOCARRAY(option_def, 100);
+
+    option_def_index = 0;   /* incremented by OPTENTRY */
+    OPTENT3(0, "width",       OPT_UINT,   &cmdlineP->width,   NULL, 0);
+    OPTENT3(0, "height",      OPT_UINT,   &cmdlineP->height,  NULL, 0);
+    OPTENT3(0, "left",        OPT_UINT,   &cmdlineP->left,    NULL, 0);
+    OPTENT3(0, "right",       OPT_UINT,   &cmdlineP->right,   NULL, 0);
+    OPTENT3(0, "top",         OPT_UINT,   &cmdlineP->top,     NULL, 0);
+    OPTENT3(0, "bottom",      OPT_UINT,   &cmdlineP->bottom,  NULL, 0);
+    OPTENT3(0, "bg",          OPT_STRING, &cmdlineP->bg_rgb,  NULL, 0);
+    OPTENT3(0, "fg",          OPT_STRING, &cmdlineP->fg_rgb,  NULL, 0);
+    OPTENT3(0, "var",         OPT_UINT,   &cmdlineP->var,     NULL, 0);
+    OPTENT3(0, "randomseed",  OPT_UINT,   &cmdlineP->randomseed,
+            &cmdlineP->randomseedSpec, 0);
+    OPTENT3(0, "init",        OPT_UINT,   &cmdlineP->randomseed,
+            &cmdlineP->randomseedSpec, 0);
+    OPTENT3(0, "verbose",     OPT_FLAG,   NULL, &cmdlineP->verbose, 0);
+
+    /* Set the defaults */
+    cmdlineP->width = 100;
+    cmdlineP->height = 100;
+    cmdlineP->left = cmdlineP->right = cmdlineP->top = cmdlineP->bottom = -1;
+    cmdlineP->bg_rgb = NULL;
+    cmdlineP->fg_rgb = NULL;
+    cmdlineP->var = 10;
+
+    opt.opt_table = option_def;
+    opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
+    opt.allowNegNum = FALSE;  /* We have no parms that are negative numbers */
+
+    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+
+    if (argc-1 != 0)
+        pm_error("There are no arguments.  You specified %d.", argc-1);
+
+    free(option_def);
 }
 
+
+
 static void
-/* ----------------------------------------- */
-   proc_left(int const r1, int const r2, int const c1, int const c2, 
-             unsigned int const var)
-/* ----------------------------------------- */
-{
-  int cm, rm, c;
-
-  if (r1 + 1 == r2)  return;
-  rm = (r1 + r2) >> 1;
-  cm = (c1 + c2) >> 1;
-  cm += (int)floor(((float)rand() / RAND_MAX - 0.5) * var + 0.5);
-
-  for (c = 0; c < cm; c++)
-    PPM_ASSIGN(PIX[rm][c], BG_RED, BG_GREEN, BG_BLUE);
-
-  proc_left(r1, rm, c1, cm, var);
-  proc_left(rm, r2, cm, c2, var);
+procLeft(int          const r1,
+         int          const r2,
+         int          const c1,
+         int          const c2, 
+         unsigned int const var) {
+
+    int cm, rm, c;
+
+    if (r1 + 1 == r2)  return;
+    rm = (r1 + r2) >> 1;
+    cm = (c1 + c2) >> 1;
+    cm += (int)floor(((float)rand() / RAND_MAX - 0.5) * var + 0.5);
+
+    for (c = 0; c < cm; c++)
+        PPM_ASSIGN(PIX[rm][c], BG_RED, BG_GREEN, BG_BLUE);
+
+    procLeft(r1, rm, c1, cm, var);
+    procLeft(rm, r2, cm, c2, var);
 }
 
+
+
 static void
-/* ------------------------------------------ */
-   proc_right(int const r1, int const r2, int const c1, int const c2,
-              unsigned int const width, unsigned int const var)
-/* ------------------------------------------ */
-{
-  int cm, rm, c;
-
-  if (r1 + 1 == r2)  return;
-  rm = (r1 + r2) >> 1;
-  cm = (c1 + c2) >> 1;
-  cm += (int)floor(((float)rand() / RAND_MAX - 0.5) * var + 0.5);
-
-  for (c = cm; c < width; c++)
-    PPM_ASSIGN(PIX[rm][c], BG_RED, BG_GREEN, BG_BLUE);
-
-  proc_right(r1, rm, c1, cm, width, var);
-  proc_right(rm, r2, cm, c2, width, var);
+procRight(int          const r1,
+          int          const r2,
+          int          const c1,
+          int          const c2,
+          unsigned int const width,
+          unsigned int const var) {
+
+    int cm, rm, c;
+
+    if (r1 + 1 == r2)  return;
+    rm = (r1 + r2) >> 1;
+    cm = (c1 + c2) >> 1;
+    cm += (int)floor(((float)rand() / RAND_MAX - 0.5) * var + 0.5);
+
+    for (c = cm; c < width; c++)
+        PPM_ASSIGN(PIX[rm][c], BG_RED, BG_GREEN, BG_BLUE);
+
+    procRight(r1, rm, c1, cm, width, var);
+    procRight(rm, r2, cm, c2, width, var);
 }
 
+
+
 static void
-/* ---------------------------------------- */
-   proc_top(int const c1, int const c2, int const r1, int const r2,
-            unsigned int const var)
-/* ---------------------------------------- */
-{
-  int rm, cm, r;
-
-  if (c1 + 1 == c2)  return;
-  cm = (c1 + c2) >> 1;
-  rm = (r1 + r2) >> 1;
-  rm += (int)floor(((float)rand() / RAND_MAX - 0.5) * var + 0.5);
-
-  for (r = 0; r < rm; r++)
-    PPM_ASSIGN(PIX[r][cm], BG_RED, BG_GREEN, BG_BLUE);
-
-  proc_top(c1, cm, r1, rm, var);
-  proc_top(cm, c2, rm, r2, var);
+procTop(int          const c1,
+        int          const c2,
+        int          const r1,
+        int          const r2,
+        unsigned int const var) {
+
+    int rm, cm, r;
+
+    if (c1 + 1 == c2)  return;
+    cm = (c1 + c2) >> 1;
+    rm = (r1 + r2) >> 1;
+    rm += (int)floor(((float)rand() / RAND_MAX - 0.5) * var + 0.5);
+
+    for (r = 0; r < rm; r++)
+        PPM_ASSIGN(PIX[r][cm], BG_RED, BG_GREEN, BG_BLUE);
+
+    procTop(c1, cm, r1, rm, var);
+    procTop(cm, c2, rm, r2, var);
 }
 
+
+
 static void
-/* ------------------------------------------- */
-   proc_bottom(int const c1, int const c2, int const r1, int const r2,
-               unsigned int const height, unsigned int const var)
-/* ------------------------------------------- */
-{
-  int rm, cm, r;
-
-  if (c1 + 1 == c2)  return;
-  cm = (c1 + c2) >> 1;
-  rm = (r1 + r2) >> 1;
-  rm += (int)floor(((float)rand() / RAND_MAX - 0.5) * var + 0.5);
-
-  for (r = rm; r < height; r++)
-    PPM_ASSIGN(PIX[r][cm], BG_RED, BG_GREEN, BG_BLUE);
-
-  proc_bottom(c1, cm, r1, rm, height, var);
-  proc_bottom(cm, c2, rm, r2, height, var);
+procBottom(int          const c1,
+           int          const c2,
+           int          const r1,
+           int          const r2,
+           unsigned int const height,
+           unsigned int const var) {
+
+    int rm, cm, r;
+
+    if (c1 + 1 == c2)  return;
+    cm = (c1 + c2) >> 1;
+    rm = (r1 + r2) >> 1;
+    rm += (int)floor(((float)rand() / RAND_MAX - 0.5) * var + 0.5);
+
+    for (r = rm; r < height; r++)
+        PPM_ASSIGN(PIX[r][cm], BG_RED, BG_GREEN, BG_BLUE);
+
+    procBottom(c1, cm, r1, rm, height, var);
+    procBottom(cm, c2, rm, r2, height, var);
 }
 
 
+
 int
-/* ============================ */
-   main(int argc, char* argv[])
-/* ============================ */
-{
-  struct cmdlineInfo cmdline;
-  pixel bgcolor, fgcolor;
-  pixval fg_red, fg_green, fg_blue;
-  int rows, cols, row;
-  int left, right, top, bottom;
-  int left_r1, left_r2, left_c1, left_c2;
-  int right_r1, right_r2, right_c1, right_c2;
-  int top_r1, top_r2, top_c1, top_c2;
-  int bottom_r1, bottom_r2, bottom_c1, bottom_c2;
-  unsigned init;
-  struct timeval tv;
-  int col;
-
-  ppm_init(&argc, argv);
-
-  parseCommandLine(argc, argv, &cmdline);
-
-  init = cmdline.init;
-  if (init == 0) {
-    gettimeofday(&tv, NULL);
-    srand((unsigned int)tv.tv_usec);
-  }
-  else
-    srand(init);
-
-  cols = cmdline.width;
-  rows = cmdline.height;
-  left = cmdline.left;
-  right = cmdline.right;
-  top = cmdline.top;
-  bottom = cmdline.bottom;
-
-  if (cmdline.bg_rgb)
-    bgcolor = ppm_parsecolor(cmdline.bg_rgb, PPM_MAXMAXVAL);
-  else
-    PPM_ASSIGN(bgcolor, 0, 0, 0);
-  BG_RED = PPM_GETR(bgcolor);
-  BG_GREEN = PPM_GETG(bgcolor);
-  BG_BLUE = PPM_GETB(bgcolor);
-
-  if (cmdline.fg_rgb)
-    fgcolor = ppm_parsecolor(cmdline.fg_rgb, PPM_MAXMAXVAL);
-  else
-    PPM_ASSIGN(fgcolor, PPM_MAXMAXVAL, PPM_MAXMAXVAL, PPM_MAXMAXVAL);
-  fg_red = PPM_GETR(fgcolor);
-  fg_green = PPM_GETG(fgcolor);
-  fg_blue = PPM_GETB(fgcolor);
-
-  if (cmdline.verbose) {
-    pm_message("width is %d, height is %d, variance is %d.", 
-               cols, rows, cmdline.var);
-    if (left >= 0) pm_message("ragged left border is required");
-    if (right >= 0) pm_message("ragged right border is required");
-    if (top >= 0) pm_message("ragged top border is required");
-    if (bottom >= 0) pm_message("ragged bottom border is required");
-    pm_message("background is %s", ppm_colorname(&bgcolor, PPM_MAXMAXVAL, 1));
-    pm_message("foreground is %s", ppm_colorname(&fgcolor, PPM_MAXMAXVAL, 1));
-    if (init >= 0) pm_message("srand() initialized with seed %u", init);
-  }
-
-  /* Allocate memory for the whole pixmap */
-  PIX = ppm_allocarray(cols, rows);
-
-  /* First, set all pixel to foreground color */
-  for (row = 0; row < rows; row++)
-    for (col = 0; col < cols; col++)
-      PPM_ASSIGN(PIX[row][col], fg_red, fg_green, fg_blue);
-
-  /* Make a ragged left border */
-  if (left >= 0) {
-    left_c1 = left_c2 = left;
-    left_r1 = 0;
-    left_r2 = rows - 1;
-    for (col = 0; col < left_c1; col++)
-      PPM_ASSIGN(PIX[left_r1][col], BG_RED, BG_GREEN, BG_BLUE);
-    for (col = 0; col < left_c2; col++)
-      PPM_ASSIGN(PIX[left_r2][col], BG_RED, BG_GREEN, BG_BLUE);
-
-    proc_left(left_r1, left_r2, left_c1, left_c2, cmdline.var);
-  }
-
-  /* Make a ragged right border */
-  if (right >= 0) {
-    right_c1 = right_c2 = cols - right - 1;
-    right_r1 = 0;
-    right_r2 = rows - 1;
-    for (col = right_c1; col < cols; col++)
-      PPM_ASSIGN(PIX[right_r1][col], BG_RED, BG_GREEN, BG_BLUE);
-    for (col = right_c2; col < cols; col++)
-      PPM_ASSIGN(PIX[right_r2][col], BG_RED, BG_GREEN, BG_BLUE);
-
-    proc_right(right_r1, right_r2, right_c1, right_c2, 
-               cmdline.width, cmdline.var);
-  }
-
-  /* Make a ragged top border */
-  if (top >= 0) {
-    top_r1 = top_r2 = top;
-    top_c1 = 0;
-    top_c2 = cols - 1;
-    for (row = 0; row < top_r1; row++)
-      PPM_ASSIGN(PIX[row][top_c1], BG_RED, BG_GREEN, BG_BLUE);
-    for (row = 0; row < top_r2; row++)
-      PPM_ASSIGN(PIX[row][top_c2], BG_RED, BG_GREEN, BG_BLUE);
-
-    proc_top(top_c1, top_c2, top_r1, top_r2, cmdline.var);
-  }
-
-  /* Make a ragged bottom border */
-  if (bottom >= 0) {
-    bottom_r1 = bottom_r2 = rows - bottom - 1;
-    bottom_c1 = 0;
-    bottom_c2 = cols - 1;
-    for (row = bottom_r1; row < rows; row++)
-      PPM_ASSIGN(PIX[row][bottom_c1], BG_RED, BG_GREEN, BG_BLUE);
-    for (row = bottom_r2; row < rows; row++)
-      PPM_ASSIGN(PIX[row][bottom_c2], BG_RED, BG_GREEN, BG_BLUE);
-
-    proc_bottom(bottom_c1, bottom_c2, bottom_r1, bottom_r2, 
-                cmdline.height, cmdline.var);
-  }
-
-  /* Write pixmap */
-  ppm_writeppm(stdout, PIX, cols, rows, PPM_MAXMAXVAL, 0);
-
-  ppm_freearray(PIX, rows);
-
-  pm_close(stdout);
-  exit(0);
+main(int argc, const char * argv[]) {
+
+    struct CmdlineInfo cmdline;
+    pixel bgcolor, fgcolor;
+    pixval fg_red, fg_green, fg_blue;
+    int rows, cols, row;
+    int left, right, top, bottom;
+
+    pm_proginit(&argc, argv);
+
+    parseCommandLine(argc, argv, &cmdline);
+
+    srand(cmdline.randomseedSpec ? cmdline.randomseed : pm_randseed());
+
+    cols = cmdline.width;
+    rows = cmdline.height;
+    left = cmdline.left;
+    right = cmdline.right;
+    top = cmdline.top;
+    bottom = cmdline.bottom;
+
+    if (cmdline.bg_rgb)
+        bgcolor = ppm_parsecolor(cmdline.bg_rgb, PPM_MAXMAXVAL);
+    else
+        PPM_ASSIGN(bgcolor, 0, 0, 0);
+    BG_RED = PPM_GETR(bgcolor);
+    BG_GREEN = PPM_GETG(bgcolor);
+    BG_BLUE = PPM_GETB(bgcolor);
+
+    if (cmdline.fg_rgb)
+        fgcolor = ppm_parsecolor(cmdline.fg_rgb, PPM_MAXMAXVAL);
+    else
+        PPM_ASSIGN(fgcolor, PPM_MAXMAXVAL, PPM_MAXMAXVAL, PPM_MAXMAXVAL);
+    fg_red = PPM_GETR(fgcolor);
+    fg_green = PPM_GETG(fgcolor);
+    fg_blue = PPM_GETB(fgcolor);
+
+    if (cmdline.verbose) {
+        pm_message("width is %d, height is %d, variance is %d.", 
+                   cols, rows, cmdline.var);
+        if (left >= 0)
+            pm_message("ragged left border is required");
+        if (right >= 0)
+            pm_message("ragged right border is required");
+        if (top >= 0)
+            pm_message("ragged top border is required");
+        if (bottom >= 0)
+            pm_message("ragged bottom border is required");
+        pm_message("background is %s",
+                   ppm_colorname(&bgcolor, PPM_MAXMAXVAL, 1));
+        pm_message("foreground is %s",
+                   ppm_colorname(&fgcolor, PPM_MAXMAXVAL, 1));
+        if (cmdline.randomseedSpec)
+            pm_message("srand() initialized with seed %u", cmdline.randomseed);
+    }
+
+    /* Allocate memory for the whole pixmap */
+    PIX = ppm_allocarray(cols, rows);
+
+    /* First, set all pixel to foreground color */
+    for (row = 0; row < rows; row++) {
+        unsigned int col;
+        for (col = 0; col < cols; ++col)
+            PPM_ASSIGN(PIX[row][col], fg_red, fg_green, fg_blue);
+    }
+    /* Make a ragged left border */
+    if (left >= 0) {
+        int const left_c1 = left;
+        int const left_c2 = left;
+        int const left_r1 = 0;
+        int const left_r2 = rows - 1;
+
+        unsigned int col;
+
+        for (col = 0; col < left_c1; ++col)
+            PPM_ASSIGN(PIX[left_r1][col], BG_RED, BG_GREEN, BG_BLUE);
+        for (col = 0; col < left_c2; ++col)
+            PPM_ASSIGN(PIX[left_r2][col], BG_RED, BG_GREEN, BG_BLUE);
+
+        procLeft(left_r1, left_r2, left_c1, left_c2, cmdline.var);
+    }
+
+    /* Make a ragged right border */
+    if (right >= 0) {
+        int const right_c1 = cols - right - 1;
+        int const right_c2 = cols - right - 1;
+        int const right_r1 = 0;
+        int const right_r2 = rows - 1;
+
+        unsigned int col;
+
+        for (col = right_c1; col < cols; col++)
+            PPM_ASSIGN(PIX[right_r1][col], BG_RED, BG_GREEN, BG_BLUE);
+        for (col = right_c2; col < cols; col++)
+            PPM_ASSIGN(PIX[right_r2][col], BG_RED, BG_GREEN, BG_BLUE);
+
+        procRight(right_r1, right_r2, right_c1, right_c2, 
+                   cmdline.width, cmdline.var);
+    }
+
+    /* Make a ragged top border */
+    if (top >= 0) {
+        int const top_r1 = top;
+        int const top_r2 = top;
+        int const top_c1 = 0;
+        int const top_c2 = cols - 1;
+
+        unsigned int row;
+
+        for (row = 0; row < top_r1; ++row)
+            PPM_ASSIGN(PIX[row][top_c1], BG_RED, BG_GREEN, BG_BLUE);
+        for (row = 0; row < top_r2; ++row)
+            PPM_ASSIGN(PIX[row][top_c2], BG_RED, BG_GREEN, BG_BLUE);
+
+        procTop(top_c1, top_c2, top_r1, top_r2, cmdline.var);
+    }
+
+    /* Make a ragged bottom border */
+    if (bottom >= 0) {
+        int const bottom_r1 = rows - bottom - 1;
+        int const bottom_r2 = rows - bottom - 1;
+        int const bottom_c1 = 0;
+        int const bottom_c2 = cols - 1;
+
+        unsigned int row;
+
+        for (row = bottom_r1; row < rows; ++row)
+            PPM_ASSIGN(PIX[row][bottom_c1], BG_RED, BG_GREEN, BG_BLUE);
+        for (row = bottom_r2; row < rows; ++row)
+            PPM_ASSIGN(PIX[row][bottom_c2], BG_RED, BG_GREEN, BG_BLUE);
+
+        procBottom(bottom_c1, bottom_c2, bottom_r1, bottom_r2, 
+                   cmdline.height, cmdline.var);
+    }
+
+    /* Write pixmap */
+    ppm_writeppm(stdout, PIX, cols, rows, PPM_MAXMAXVAL, 0);
+
+    ppm_freearray(PIX, rows);
+
+    pm_close(stdout);
+
+    return 0;
 }
+
+
+