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.c526
1 files changed, 332 insertions, 194 deletions
diff --git a/generator/ppmrough.c b/generator/ppmrough.c
index c87a0364..d9f1bb65 100644
--- a/generator/ppmrough.c
+++ b/generator/ppmrough.c
@@ -16,11 +16,10 @@
 
 #include "pm_c_util.h"
 #include "mallocvar.h"
+#include "rand.h"
 #include "shhopt.h"
 #include "ppm.h"
 
-static pixel** PIX;
-static pixval BG_RED, BG_GREEN, BG_BLUE;
 
 
 struct CmdlineInfo {
@@ -28,9 +27,12 @@ struct CmdlineInfo {
      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 int leftSpec, rightSpec, topSpec, bottomSpec;
+    unsigned int width;
+    unsigned int height;
+    unsigned int var;
+    const char * bg;  /* Null if not specified */
+    const char * fg;  /* Null if not specified */
     unsigned int randomseed;
     unsigned int randomseedSpec;
     unsigned int verbose;
@@ -42,6 +44,8 @@ static void
 parseCommandLine(int argc, const char ** argv,
                  struct CmdlineInfo * const cmdlineP) {
 
+    unsigned int widthSpec, heightSpec, bgSpec, fgSpec, varSpec;
+
     optEntry * option_def;
         /* Instructions to OptParseOptions2 on how to parse our options.    */
     optStruct3 opt;
@@ -51,28 +55,30 @@ parseCommandLine(int argc, const char ** argv,
     MALLOCARRAY_NOFAIL(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, "width",       OPT_UINT,   &cmdlineP->width,
+            &widthSpec, 0);
+    OPTENT3(0, "height",      OPT_UINT,   &cmdlineP->height,
+            &heightSpec, 0);
+    OPTENT3(0, "left",        OPT_UINT,   &cmdlineP->left,
+            &cmdlineP->leftSpec, 0);
+    OPTENT3(0, "right",       OPT_UINT,   &cmdlineP->right,
+            &cmdlineP->rightSpec, 0);
+    OPTENT3(0, "top",         OPT_UINT,   &cmdlineP->top,
+            &cmdlineP->topSpec, 0);
+    OPTENT3(0, "bottom",      OPT_UINT,   &cmdlineP->bottom,
+            &cmdlineP->bottomSpec, 0);
+    OPTENT3(0, "bg",          OPT_STRING, &cmdlineP->bg,
+            &bgSpec, 0);
+    OPTENT3(0, "fg",          OPT_STRING, &cmdlineP->fg,
+            &fgSpec, 0);
+    OPTENT3(0, "var",         OPT_UINT,   &cmdlineP->var,
+            &varSpec, 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;
+    OPTENT3(0, "verbose",     OPT_FLAG,   NULL,
+            &cmdlineP->verbose, 0);
 
     opt.opt_table = option_def;
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
@@ -80,6 +86,26 @@ parseCommandLine(int argc, const char ** argv,
 
     pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
 
+    if (!widthSpec)
+        cmdlineP->width = 100;
+    if (!heightSpec)
+        cmdlineP->height = 100;
+    if (!bgSpec)
+        cmdlineP->bg = NULL;
+    if (!fgSpec)
+        cmdlineP->fg = NULL;
+    if (!varSpec)
+        cmdlineP->var = 10;
+
+    if (cmdlineP->topSpec && cmdlineP->top > cmdlineP->height)
+        pm_error("-top value too large.  Max is %u", cmdlineP->height);
+    if (cmdlineP->bottomSpec && cmdlineP->bottom > cmdlineP->height)
+        pm_error("-bottom value too large.  Max is %u", cmdlineP->height);
+    if (cmdlineP->leftSpec && cmdlineP->left > cmdlineP->width)
+        pm_error("-left value too large.  Max is %u", cmdlineP->width);
+    if (cmdlineP->rightSpec && cmdlineP->right > cmdlineP->width)
+        pm_error("-right value too large.  Max is %u", cmdlineP->width);
+
     if (argc-1 != 0)
         pm_error("There are no arguments.  You specified %d.", argc-1);
 
@@ -88,240 +114,353 @@ parseCommandLine(int argc, const char ** argv,
 
 
 
-static void
-procLeft(int          const r1,
-         int          const r2,
-         int          const c1,
-         int          const c2,
-         unsigned int const var) {
+static int
+mean(int const a,
+     int const b) {
 
-    int cm, rm, c;
+    return (a + b) / 2;
+}
 
-    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
+reportParameters(struct CmdlineInfo const cmdline,
+                 pixel              const bgcolor,
+                 pixel              const fgcolor) {
+
+    pm_message("width is %d, height is %d, variance is %d.",
+               cmdline.width, cmdline.height, cmdline.var);
+    if (cmdline.leftSpec)
+        pm_message("ragged left border is required");
+    if (cmdline.rightSpec)
+        pm_message("ragged right border is required");
+    if (cmdline.topSpec)
+        pm_message("ragged top border is required");
+    if (cmdline.bottomSpec)
+        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("pm_rand() initialized with seed %u",
+                   cmdline.randomseed);
 }
 
 
 
 static void
-procRight(int          const r1,
-          int          const r2,
-          int          const c1,
-          int          const c2,
-          unsigned int const width,
-          unsigned int const var) {
+makeAllForegroundColor(pixel **     const pixels,
+                       unsigned int const rows,
+                       unsigned int const cols,
+                       pixel        const fgcolor) {
 
-    int cm, rm, c;
+    pixval const r = PPM_GETR(fgcolor);
+    pixval const g = PPM_GETG(fgcolor);
+    pixval const b = PPM_GETB(fgcolor);
 
-    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);
+    unsigned int row;
 
-    for (c = cm; c < width; c++)
-        PPM_ASSIGN(PIX[rm][c], BG_RED, BG_GREEN, BG_BLUE);
+    for (row = 0; row < rows; ++row) {
+        unsigned int col;
 
-    procRight(r1, rm, c1, cm, width, var);
-    procRight(rm, r2, cm, c2, width, var);
+        for (col = 0; col < cols; ++col)
+            PPM_ASSIGN(pixels[row][col], r, g, b);
+    }
 }
 
 
 
 static void
-procTop(int          const c1,
-        int          const c2,
-        int          const r1,
-        int          const r2,
-        unsigned int const var) {
+procLeft(pixel **           const pixels,
+         int                const r1,
+         int                const r2,
+         int                const c1,
+         int                const c2,
+         unsigned int       const width,
+         unsigned int       const var,
+         pixel              const bgcolor,
+         struct pm_randSt * const randStP) {
+
+    if (r1 + 1 != r2) {
+        int const rm = mean(r1, r2);
+        int const cm = mean(c1, c2) +
+            (int)floor(((float)pm_drand(randStP) - 0.5) * var + 0.5);
+
+        unsigned int c;
+
+        for (c = 0; c < MIN(width, MAX(0, cm)); ++c)
+            pixels[rm][c] = bgcolor;
+
+        procLeft(pixels, r1, rm, c1, cm, width, var, bgcolor, randStP);
+        procLeft(pixels, rm, r2, cm, c2, width, var, bgcolor, randStP);
+    }
+}
 
-    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);
+static void
+procRight(pixel **           const pixels,
+          int                const r1,
+          int                const r2,
+          int                const c1,
+          int                const c2,
+          unsigned int       const width,
+          unsigned int       const var,
+          pixel              const bgcolor,
+          struct pm_randSt * const randStP) {
+
+    if (r1 + 1 != r2) {
+        int const rm = mean(r1, r2);
+        int const cm = mean(c1, c2) +
+            (int)floor(((float)pm_drand(randStP) - 0.5) * var + 0.5);
+
+        unsigned int c;
+
+        for (c = MAX(0, cm); c < width; ++c)
+            pixels[rm][c] = bgcolor;
+
+        procRight(pixels, r1, rm, c1, cm, width, var, bgcolor, randStP);
+        procRight(pixels, rm, r2, cm, c2, width, var, bgcolor, randStP);
+    }
+}
 
-    procTop(c1, cm, r1, rm, var);
-    procTop(cm, c2, rm, r2, var);
+
+
+static void
+procTop(pixel **           const pixels,
+        int                const c1,
+        int                const c2,
+        int                const r1,
+        int                const r2,
+        unsigned int       const height,
+        unsigned int       const var,
+        pixel              const bgcolor,
+        struct pm_randSt * const randStP) {
+
+    if (c1 + 1 != c2) {
+        int const cm = mean(c1, c2);
+        int const rm = mean(r1, r2) +
+            (int)floor(((float)pm_drand(randStP) - 0.5) * var + 0.5);
+
+        unsigned int r;
+
+        for (r = 0; r < MIN(height, MAX(0, rm)); ++r)
+            pixels[r][cm] = bgcolor;
+
+        procTop(pixels, c1, cm, r1, rm, height, var, bgcolor, randStP);
+        procTop(pixels, cm, c2, rm, r2, height, var, bgcolor, randStP);
+    }
 }
 
 
 
 static void
-procBottom(int          const c1,
-           int          const c2,
-           int          const r1,
-           int          const r2,
-           unsigned int const height,
-           unsigned int const var) {
+procBottom(pixel **           const pixels,
+           int                const c1,
+           int                const c2,
+           int                const r1,
+           int                const r2,
+           unsigned int       const height,
+           unsigned int       const var,
+           pixel              const bgcolor,
+           struct pm_randSt * const randStP) {
+
+    if (c1 + 1 != c2) {
+        int const cm = mean(c1, c2);
+        int const rm = mean(r1, r2) +
+            (int)floor(((float)pm_drand(randStP) - 0.5) * var + 0.5);
+
+        unsigned int r;
+
+        for (r = MAX(0, rm); r < height; ++r)
+            pixels[r][cm] = bgcolor;
+
+        procBottom(pixels, c1, cm, r1, rm, height, var, bgcolor, randStP);
+        procBottom(pixels, cm, c2, rm, r2, height, var, bgcolor, randStP);
+    }
+}
 
-    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);
+static void
+makeRaggedLeftBorder(pixel **           const pixels,
+                     unsigned int       const rows,
+                     unsigned int       const cols,
+                     bool               const leftSpec,
+                     unsigned int       const left,
+                     unsigned int       const var,
+                     pixel              const bgcolor,
+                     struct pm_randSt * const randStP) {
+
+    if (leftSpec) {
+        int const leftC1 = left;
+        int const leftC2 = left;
+        int const leftR1 = 0;
+        int const leftR2 = rows - 1;
+
+        unsigned int col;
 
-    procBottom(c1, cm, r1, rm, height, var);
-    procBottom(cm, c2, rm, r2, height, var);
+        for (col = 0; col < leftC1; ++col)
+            pixels[leftR1][col] = bgcolor;
+        for (col = 0; col < leftC2; ++col)
+            pixels[leftR2][col] = bgcolor;
+
+        procLeft(pixels, leftR1, leftR2, leftC1, leftC2, cols, var,
+                 bgcolor, randStP);
+    }
 }
 
 
 
-int
-main(int argc, const char * argv[]) {
+static void
+makeRaggedRightBorder(pixel **           const pixels,
+                      unsigned int       const rows,
+                      unsigned int       const cols,
+                      bool               const rightSpec,
+                      unsigned int       const right,
+                      unsigned int       const width,
+                      unsigned int       const var,
+                      pixel              const bgcolor,
+                      struct pm_randSt * const randStP) {
+
+    if (rightSpec) {
+        int const rightC1 = cols - right - 1;
+        int const rightC2 = cols - right - 1;
+        int const rightR1 = 0;
+        int const rightR2 = rows - 1;
 
-    struct CmdlineInfo cmdline;
-    pixel bgcolor, fgcolor;
-    pixval fg_red, fg_green, fg_blue;
-    int rows, cols, row;
-    int left, right, top, bottom;
+        unsigned int col;
 
-    pm_proginit(&argc, argv);
+        for (col = rightC1; col < cols; ++col)
+            pixels[rightR1][col] = bgcolor;
+        for (col = rightC2; col < cols; ++col)
+            pixels[rightR2][col] = bgcolor;
 
-    parseCommandLine(argc, argv, &cmdline);
+        procRight(pixels, rightR1, rightR2, rightC1, rightC2, width, var,
+                  bgcolor, randStP);
+    }
+}
 
-    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);
+static void
+makeRaggedTopBorder(pixel **           const pixels,
+                    unsigned int       const rows,
+                    unsigned int       const cols,
+                    bool               const topSpec,
+                    unsigned int       const top,
+                    unsigned int       const var,
+                    pixel              const bgcolor,
+                    struct pm_randSt * const randStP) {
+
+    if (topSpec) {
+        unsigned int const topR1 = top;
+        unsigned int const topR2 = top;
+        unsigned int const topC1 = 0;
+        unsigned int const topC2 = cols - 1;
 
-    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);
-    }
+        unsigned int row;
 
-    /* Allocate memory for the whole pixmap */
-    PIX = ppm_allocarray(cols, rows);
+        for (row = 0; row < topR1; ++row)
+            pixels[row][topC1] = bgcolor;
+        for (row = 0; row < topR2; ++row)
+            pixels[row][topC2] = bgcolor;
 
-    /* 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);
+        procTop(pixels, topC1, topC2, topR1, topR2, rows,
+                var, bgcolor, randStP);
     }
-    /* 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);
+static void
+makeRaggedBottomBorder(pixel **            const pixels,
+                       unsigned int        const rows,
+                       unsigned int        const cols,
+                       bool                const bottomSpec,
+                       unsigned int        const bottom,
+                       unsigned int        const height,
+                       unsigned int        const var,
+                       pixel               const bgcolor,
+                       struct pm_randSt *  const randStP) {
+
+    if (bottomSpec) {
+        unsigned int const bottomR1 = rows - bottom - 1;
+        unsigned int const bottomR2 = rows - bottom - 1;
+        unsigned int const bottomC1 = 0;
+        unsigned int const bottomC2 = cols - 1;
+
+        unsigned int row;
+
+        for (row = bottomR1; row < rows; ++row)
+            pixels[row][bottomC1] = bgcolor;
+        for (row = bottomR2; row < rows; ++row)
+            pixels[row][bottomC2] = bgcolor;
+
+        procBottom(pixels, bottomC1, bottomC2, bottomR1, bottomR2,
+                   height, var, bgcolor, randStP);
     }
+}
 
-    /* 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);
+int
+main(int argc, const char ** const argv) {
 
-        procRight(right_r1, right_r2, right_c1, right_c2,
-                   cmdline.width, cmdline.var);
-    }
+    struct CmdlineInfo cmdline;
+    pixel bgcolor, fgcolor;
+    struct pm_randSt randSt;
+    static pixel** pixels;
 
-    /* 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;
+    pm_proginit(&argc, argv);
 
-        unsigned int row;
+    parseCommandLine(argc, argv, &cmdline);
 
-        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);
+    pm_randinit(&randSt);
+    pm_srand(&randSt,
+             cmdline.randomseedSpec ? cmdline.randomseed : pm_randseed());
 
-        procTop(top_c1, top_c2, top_r1, top_r2, cmdline.var);
-    }
+    if (cmdline.bg)
+        bgcolor = ppm_parsecolor(cmdline.bg, PPM_MAXMAXVAL);
+    else
+        PPM_ASSIGN(bgcolor, 0, 0, 0);
+
+    if (cmdline.fg)
+        fgcolor = ppm_parsecolor(cmdline.fg, PPM_MAXMAXVAL);
+    else
+        PPM_ASSIGN(fgcolor, PPM_MAXMAXVAL, PPM_MAXMAXVAL, PPM_MAXMAXVAL);
 
-    /* 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;
+    if (cmdline.verbose)
+        reportParameters(cmdline, bgcolor, fgcolor);
 
-        unsigned int row;
+    pixels = ppm_allocarray(cmdline.width, cmdline.height);
 
-        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);
+    makeAllForegroundColor(pixels, cmdline.height, cmdline.width, fgcolor);
 
-        procBottom(bottom_c1, bottom_c2, bottom_r1, bottom_r2,
-                   cmdline.height, cmdline.var);
-    }
+    makeRaggedLeftBorder(pixels, cmdline.height, cmdline.width,
+                         cmdline.leftSpec, cmdline.left,
+                         cmdline.var, bgcolor, &randSt);
+
+    makeRaggedRightBorder(pixels, cmdline.height, cmdline.width,
+                          cmdline.rightSpec, cmdline.right,
+                          cmdline.width, cmdline.var, bgcolor, &randSt);
+
+    makeRaggedTopBorder(pixels, cmdline.height, cmdline.width,
+                        cmdline.topSpec, cmdline.top,
+                        cmdline.var, bgcolor, &randSt);
+
+    makeRaggedBottomBorder(pixels, cmdline.height, cmdline.width,
+                           cmdline.bottomSpec, cmdline.bottom,
+                           cmdline.height, cmdline.var, bgcolor, &randSt);
+
+    pm_randterm(&randSt);
 
     /* Write pixmap */
-    ppm_writeppm(stdout, PIX, cols, rows, PPM_MAXMAXVAL, 0);
+    ppm_writeppm(stdout, pixels, cmdline.width, cmdline.height,
+                 PPM_MAXMAXVAL, 0);
 
-    ppm_freearray(PIX, rows);
+    ppm_freearray(pixels, cmdline.height);
 
     pm_close(stdout);
 
@@ -329,4 +468,3 @@ main(int argc, const char * argv[]) {
 }
 
 
-