about summary refs log tree commit diff
path: root/generator
diff options
context:
space:
mode:
Diffstat (limited to 'generator')
-rw-r--r--generator/pamcrater.c5
-rw-r--r--generator/pamgauss.c7
-rw-r--r--generator/pamgradient.c11
-rw-r--r--generator/pamseq.c29
-rw-r--r--generator/pbmtext.c28
-rw-r--r--generator/pbmupc.c437
-rw-r--r--generator/pgmkernel.c29
-rw-r--r--generator/ppmforge.c191
-rw-r--r--generator/ppmpat.c8
9 files changed, 389 insertions, 356 deletions
diff --git a/generator/pamcrater.c b/generator/pamcrater.c
index b8ceafa5..8f0e422d 100644
--- a/generator/pamcrater.c
+++ b/generator/pamcrater.c
@@ -163,7 +163,6 @@ parseCommandLine(int argc, const char ** const argv,
 
 
 
-static double const arand       = 32767.0;  /* Random number parameters */
 static double const CdepthPower = 1.5;      /* Crater depth power factor */
 static double const DepthBias2  = 0.5;      /* Square of depth bias */
 
@@ -175,7 +174,7 @@ cast(double             const high,
 /*----------------------------------------------------------------------------
    A random number in the range [0, 'high'].
 -----------------------------------------------------------------------------*/
-    return high * ((pm_rand(randStP) & 0x7FFF) / arand);
+  return high * ((double) pm_rand(randStP) / randStP->max);
 }
 
 
@@ -222,7 +221,6 @@ terrainModP(struct pam * const pamP,
 
 
 
-
 static sample
 terrainMod(struct pam * const pamP,
            tuple **     const terrain,
@@ -522,3 +520,4 @@ main(int argc, const char ** argv) {
 }
 
 
+
diff --git a/generator/pamgauss.c b/generator/pamgauss.c
index 3697fdc7..5553e757 100644
--- a/generator/pamgauss.c
+++ b/generator/pamgauss.c
@@ -106,8 +106,8 @@ parseCommandLine(int argc, const char ** argv,
         pm_error("Only two arguments allowed: width and height.  "
                  "You specified %d", argc-1);
     else {
-        cmdlineP->width = atoi(argv[1]);
-        cmdlineP->height = atoi(argv[2]);
+        cmdlineP->width  = pm_parse_width(argv[1]);
+        cmdlineP->height = pm_parse_height(argv[2]);
         if (cmdlineP->width <= 0)
             pm_error("width argument must be a positive number.  You "
                      "specified '%s'", argv[1]);
@@ -347,3 +347,6 @@ main(int argc, const char **argv) {
 
     return 0;
 }
+
+
+
diff --git a/generator/pamgradient.c b/generator/pamgradient.c
index 526efdae..bbbaad30 100644
--- a/generator/pamgradient.c
+++ b/generator/pamgradient.c
@@ -53,8 +53,8 @@ parseCommandLine(int argc, const char **argv,
     else {
         if (cmdlineP->maxval > PAM_OVERALL_MAXVAL)
             pm_error("The value you specified for -maxval (%u) is too big.  "
-                     "Max allowed is %u", cmdlineP->maxval,
-                     PAM_OVERALL_MAXVAL);
+                     "Max allowed is %lu", cmdlineP->maxval,
+                     (unsigned long int) PAM_OVERALL_MAXVAL);
 
         if (cmdlineP->maxval < 1)
             pm_error("You cannot specify 0 for -maxval");
@@ -68,8 +68,8 @@ parseCommandLine(int argc, const char **argv,
         cmdlineP->colorTopRight    = pnm_parsecolor(argv[2], cmdlineP->maxval);
         cmdlineP->colorBottomLeft  = pnm_parsecolor(argv[3], cmdlineP->maxval);
         cmdlineP->colorBottomRight = pnm_parsecolor(argv[4], cmdlineP->maxval);
-        cmdlineP->cols = atoi(argv[5]);
-        cmdlineP->rows = atoi(argv[6]);
+        cmdlineP->cols = pm_parse_width(argv[5]);
+        cmdlineP->rows = pm_parse_height(argv[6]);
         if (cmdlineP->cols <= 0)
             pm_error("width argument must be a positive number.  You "
                      "specified '%s'", argv[5]);
@@ -211,3 +211,6 @@ main(int argc, const char *argv[]) {
 
     return 0;
 }
+
+
+
diff --git a/generator/pamseq.c b/generator/pamseq.c
index 4c00e2a5..998b7ea5 100644
--- a/generator/pamseq.c
+++ b/generator/pamseq.c
@@ -192,18 +192,29 @@ parseCommandLine(int argc, const char ** argv,
         pm_error("Only two argumeents allowed: depth and maxval.  "
                  "You specified %d", argc-1);
     else {
-        cmdlineP->depth = atoi(argv[1]);
-        cmdlineP->maxval = atoi(argv[2]);
-        if (cmdlineP->depth <= 0)
+        const char * error;
+        unsigned int depth, maxval;
+
+        pm_string_to_uint(argv[1], &depth, &error);
+        if (error) {
+            pm_error("'%s' is invalid as an image depth.  %s", argv[1], error);
+            pm_strfree(error);
+        }
+        else if (depth <= 0)
             pm_error("depth argument must be a positive number.  You "
                      "specified '%s'", argv[1]);
-        if (cmdlineP->maxval <= 0)
-            pm_error("maxval argument must be a positive number.  You "
-                     "specified '%s'", argv[2]);
-        if (cmdlineP->maxval > PNM_OVERALLMAXVAL)
+        else
+            cmdlineP->depth = depth;
+
+        maxval = pm_parse_maxval(argv[2]);
+
+        if (maxval > PAM_OVERALL_MAXVAL)
             pm_error("The maxval you specified (%u) is too big.  "
-                     "Maximum is %u", (unsigned int) cmdlineP->maxval,
-                     PNM_OVERALLMAXVAL);
+                     "Maximum is %lu", maxval, PAM_OVERALL_MAXVAL);
+        else
+            cmdlineP->maxval = maxval;
+
+
         if (pm_maxvaltobits(cmdlineP->maxval) +
             pm_maxvaltobits(cmdlineP->depth-1) > sizeof(unsigned int)*8)
             pm_error("The maxval (%u) and depth (%u) you specified result "
diff --git a/generator/pbmtext.c b/generator/pbmtext.c
index a4566d12..6d4ab8c5 100644
--- a/generator/pbmtext.c
+++ b/generator/pbmtext.c
@@ -1,4 +1,4 @@
-/* pbmtext.c - render text into a bitmap
+/* pbmtext.c - render text into a PBM
 **
 ** Copyright (C) 1991 by Jef Poskanzer.
 **
@@ -81,8 +81,13 @@ textFmCmdLine(int argc, const char ** argv) {
     text[0] = '\0';
 
     for (i = 1, totaltextsize = 0; i < argc; ++i) {
-        if (i > 1) {
+        if (i > 1)
             strcat(text, " ");
+
+        if (strlen(argv[i]) > MAXLINECHARS) { /* avoid arithmetic overflow */
+            pm_error("Command line argument %u is %u characters.  "
+                     "Cannot process longer than %u",
+                     i, (unsigned) strlen(argv[i]), (unsigned) MAXLINECHARS);
         }
         totaltextsize += strlen(argv[i]) + (i > 1 ? 1 : 0);
         if (totaltextsize > MAXLINECHARS)
@@ -1105,7 +1110,7 @@ getText(PM_WCHAR             const cmdlineText[],
 
         unsigned int const lineBufTerm = LINEBUFSIZE - 1;
 
-        unsigned int maxlines;
+        unsigned int textArraySz;
             /* Maximum number of lines for which we currently have space in
                the text array
             */
@@ -1122,12 +1127,12 @@ getText(PM_WCHAR             const cmdlineText[],
         buf[lineBufTerm] = L'\1';  /* Initialize to non-zero value */
                                    /* to detect input overrun */
 
-        maxlines = 50;  /* initial value */
-        MALLOCARRAY(textArray, maxlines);
+        textArraySz = 50;  /* initial value */
+        MALLOCARRAY(textArray, textArraySz);
 
         if (!textArray)
             pm_error("Unable to allocate memory for a buffer for up to %u "
-                     "lines of text", maxlines);
+                     "lines of text", textArraySz);
 
         for (lineCount = 0, eof = false; !eof; ) {
             const char * error;
@@ -1143,9 +1148,13 @@ getText(PM_WCHAR             const cmdlineText[],
                             "is longer than %u characters. "
                             "Cannot process",
                             lineCount, (unsigned int) MAXLINECHARS);
-                    if (lineCount >= maxlines) {
-                        maxlines *= 2;
-                        REALLOCARRAY(textArray, maxlines);
+                    if (lineCount >= textArraySz) {
+                        if (textArraySz > UINT_MAX/2)
+                            pm_error("Too many lines of input for "
+                                     "computation (more than %u)",
+                                     textArraySz);
+                        textArraySz *= 2;
+                        REALLOCARRAY(textArray, textArraySz);
                         if (textArray == NULL)
                             pm_error("out of memory");
                     }
@@ -1564,4 +1573,3 @@ main(int argc, const char *argv[]) {
 }
 
 
-
diff --git a/generator/pbmupc.c b/generator/pbmupc.c
index 9d9e6721..28ccffb7 100644
--- a/generator/pbmupc.c
+++ b/generator/pbmupc.c
@@ -26,146 +26,29 @@
 #define SHORT_HEIGHT ( 8 * LINES_WIDTH )
 #define TALL_HEIGHT ( SHORT_HEIGHT + DIGIT_HEIGHT / 2 )
 
-static int alldig ARGS(( char* cp ));
-static void putdigit ARGS(( int d, bit** bits, int row0, int col0 ));
-static int addlines ARGS(( int d, bit** bits, int row0, int col0, int height, bit color ));
-static int rect ARGS(( bit** bits, int row0, int col0, int height, int width, bit color ));
-
-int
-main( argc, argv )
-    int argc;
-    char* argv[];
-    {
-    register bit** bits;
-    int argn, style, rows, cols, row, digrow, col, digcolofs;
-    char* typecode;
-    char* manufcode;
-    char* prodcode;
-    int sum, p, lc0, lc1, lc2, lc3, lc4, rc0, rc1, rc2, rc3, rc4;
-    const char* const usage = "[-s1|-s2] <type> <manufac> <product>";
 
 
-    pbm_init( &argc, argv );
-
-    argn = 1;
-    style = 1;
-
-    /* Check for flags. */
-    while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
-        {
-        if ( pm_keymatch( argv[argn], "-s1", 3 ) )
-            style = 1;
-        else if ( pm_keymatch( argv[argn], "-s2", 3 ) )
-            style = 2;
-        else
-            pm_usage( usage );
-        argn++;
-        }
-
-    if ( argn + 3 < argc )
-        pm_usage( usage );
-    typecode = argv[argn];
-    manufcode = argv[argn + 1];
-    prodcode = argv[argn + 2];
-    argn += 3;
+static int
+alldig(const char * const cp) {
 
-    if ( argn != argc )
-        pm_usage( usage );
+    unsigned int i;
 
-    if ( strlen( typecode ) != 1 || ( ! alldig( typecode ) ) ||
-         strlen( manufcode ) != 5 || ( ! alldig ( manufcode ) ) ||
-         strlen( prodcode ) != 5 || ( ! alldig ( prodcode ) ) )
-        pm_error(
-            "type code must be one digit, and\n    manufacturer and product codes must be five digits" );
-    p = typecode[0] - '0';
-    lc0 = manufcode[0] - '0';
-    lc1 = manufcode[1] - '0';
-    lc2 = manufcode[2] - '0';
-    lc3 = manufcode[3] - '0';
-    lc4 = manufcode[4] - '0';
-    rc0 = prodcode[0] - '0';
-    rc1 = prodcode[1] - '0';
-    rc2 = prodcode[2] - '0';
-    rc3 = prodcode[3] - '0';
-    rc4 = prodcode[4] - '0';
-    sum = ( 10 - ( ( ( p + lc1 + lc3 + rc0 + rc2 + rc4 ) * 3 + lc0 + lc2 + lc4 + rc1 + rc3 ) % 10 ) ) % 10;
-
-    rows = 2 * MARGIN + SHORT_HEIGHT + DIGIT_HEIGHT;
-    cols = 2 * MARGIN + 12 * LINES_WIDTH + 11 * LINE1_WIDTH;
-    bits = pbm_allocarray( cols, rows );
+    for (i = 0; cp[i] != '\0'; ++i)
+        if (cp[i] < '0' || cp[i] > '9')
+            return 0;
 
-    (void) rect( bits, 0, 0, rows, cols, PBM_WHITE );
+    return 1;
+}
 
-    row = MARGIN;
-    digrow = row + SHORT_HEIGHT;
-    col = MARGIN;
-    digcolofs = ( LINES_WIDTH - DIGIT_WIDTH ) / 2;
-
-    if ( style == 1 )
-        putdigit( p, bits, digrow, col - DIGIT_WIDTH - LINE1_WIDTH );
-    else if ( style == 2 )
-        putdigit(
-            p, bits, row + SHORT_HEIGHT / 2, col - DIGIT_WIDTH - LINE1_WIDTH );
-    col = rect( bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_BLACK );
-    col = rect( bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_WHITE );
-    col = rect( bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_BLACK );
-    col = addlines( p, bits, row, col, TALL_HEIGHT, PBM_WHITE );
-    putdigit( lc0, bits, digrow, col + digcolofs );
-    col = addlines( lc0, bits, row, col, SHORT_HEIGHT, PBM_WHITE );
-    putdigit( lc1, bits, digrow, col + digcolofs );
-    col = addlines( lc1, bits, row, col, SHORT_HEIGHT, PBM_WHITE );
-    putdigit( lc2, bits, digrow, col + digcolofs );
-    col = addlines( lc2, bits, row, col, SHORT_HEIGHT, PBM_WHITE );
-    putdigit( lc3, bits, digrow, col + digcolofs );
-    col = addlines( lc3, bits, row, col, SHORT_HEIGHT, PBM_WHITE );
-    putdigit( lc4, bits, digrow, col + digcolofs );
-    col = addlines( lc4, bits, row, col, SHORT_HEIGHT, PBM_WHITE );
-    col = rect( bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_WHITE );
-    col = rect( bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_BLACK );
-    col = rect( bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_WHITE );
-    col = rect( bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_BLACK );
-    col = rect( bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_WHITE );
-    putdigit( rc0, bits, digrow, col + digcolofs );
-    col = addlines( rc0, bits, row, col, SHORT_HEIGHT, PBM_BLACK );
-    putdigit( rc1, bits, digrow, col + digcolofs );
-    col = addlines( rc1, bits, row, col, SHORT_HEIGHT, PBM_BLACK );
-    putdigit( rc2, bits, digrow, col + digcolofs );
-    col = addlines( rc2, bits, row, col, SHORT_HEIGHT, PBM_BLACK );
-    putdigit( rc3, bits, digrow, col + digcolofs );
-    col = addlines( rc3, bits, row, col, SHORT_HEIGHT, PBM_BLACK );
-    putdigit( rc4, bits, digrow, col + digcolofs );
-    col = addlines( rc4, bits, row, col, SHORT_HEIGHT, PBM_BLACK );
-    col = addlines( sum, bits, row, col, TALL_HEIGHT, PBM_BLACK );
-    col = rect( bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_BLACK );
-    col = rect( bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_WHITE );
-    col = rect( bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_BLACK );
-    if ( style == 1 )
-        putdigit( sum, bits, digrow, col + LINE1_WIDTH );
-
-    pbm_writepbm( stdout, bits, cols, rows, 0 );
-    pm_close( stdout );
-
-    exit( 0 );
-    }
 
-static int
-alldig( cp )
-    char* cp;
-    {
-    for ( ; *cp != '\0'; cp++ )
-        if ( *cp < '0' || *cp > '9' )
-            return 0;
-    return 1;
-    }
 
 static void
-putdigit( d, bits, row0, col0 )
-    int d;
-    bit** bits;
-    int row0, col0;
-    {
-    int row, col;
-    static bit digits[10][DIGIT_HEIGHT][DIGIT_WIDTH] = {
+putDigit(int          const d,
+         bit **       const bits,
+         unsigned int const row0,
+         unsigned int const col0) {
+
+    static bit const digits[10][DIGIT_HEIGHT][DIGIT_WIDTH] = {
         /* 0 */
         {
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
@@ -428,100 +311,252 @@ putdigit( d, bits, row0, col0 )
         }
     };
 
-    for ( row = 0; row < DIGIT_HEIGHT; row++ )
-        for ( col = 0; col < DIGIT_WIDTH; col++ )
+    unsigned int row;
+
+    for (row = 0; row < DIGIT_HEIGHT; ++row) {
+        unsigned int col;
+
+        for (col = 0; col < DIGIT_WIDTH; ++col)
             bits[row0 + row][col0 + col] = digits[d][row][col];
     }
+}
 
-static int
-addlines( int d, bit** bits, int row0, int col0, int height, bit color )
-    {
-    switch ( d )
-        {
-        case 0:
-        col0 = rect( bits, row0, col0, height, LINE3_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE2_WIDTH, 1 - color );
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, 1 - color );
+
+
+static unsigned int
+rect(bit ** const bits,
+     unsigned int const row0,
+     unsigned int const col0,
+     unsigned int const height,
+     unsigned int const width,
+     bit          const color) {
+
+    unsigned int row;
+
+    for (row = row0; row < row0 + height; ++row) {
+        unsigned int col;
+
+        for (col = col0; col < col0 + width; ++col)
+            bits[row][col] = color;
+    }
+    return col0 + width;
+}
+
+
+
+static unsigned int
+addLines(int          const d,
+         bit **       const bits,
+         unsigned int const row0,
+         unsigned int const startCol,
+         unsigned int const height,
+         bit          const color) {
+
+    unsigned int col0;
+
+    col0 = startCol;  /* initial value */
+
+    switch (d) {
+    case 0:
+        col0 = rect(bits, row0, col0, height, LINE3_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE2_WIDTH, 1 - color);
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, 1 - color);
         break;
 
-        case 1:
-        col0 = rect( bits, row0, col0, height, LINE2_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE2_WIDTH, 1 - color );
-        col0 = rect( bits, row0, col0, height, LINE2_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, 1 - color );
+    case 1:
+        col0 = rect(bits, row0, col0, height, LINE2_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE2_WIDTH, 1 - color);
+        col0 = rect(bits, row0, col0, height, LINE2_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, 1 - color);
         break;
 
-        case 2:
-        col0 = rect( bits, row0, col0, height, LINE2_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, 1 - color );
-        col0 = rect( bits, row0, col0, height, LINE2_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE2_WIDTH, 1 - color );
+    case 2:
+        col0 = rect(bits, row0, col0, height, LINE2_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, 1 - color);
+        col0 = rect(bits, row0, col0, height, LINE2_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE2_WIDTH, 1 - color);
         break;
 
-        case 3:
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE4_WIDTH, 1 - color );
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, 1 - color );
+    case 3:
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE4_WIDTH, 1 - color);
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, 1 - color);
         break;
 
-        case 4:
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, 1 - color );
-        col0 = rect( bits, row0, col0, height, LINE3_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE2_WIDTH, 1 - color );
+    case 4:
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, 1 - color);
+        col0 = rect(bits, row0, col0, height, LINE3_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE2_WIDTH, 1 - color);
         break;
 
-        case 5:
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE2_WIDTH, 1 - color );
-        col0 = rect( bits, row0, col0, height, LINE3_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, 1 - color );
+    case 5:
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE2_WIDTH, 1 - color);
+        col0 = rect(bits, row0, col0, height, LINE3_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, 1 - color);
         break;
 
-        case 6:
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, 1 - color );
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE4_WIDTH, 1 - color );
+    case 6:
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, 1 - color);
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE4_WIDTH, 1 - color);
         break;
 
-        case 7:
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE3_WIDTH, 1 - color );
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE2_WIDTH, 1 - color );
+    case 7:
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE3_WIDTH, 1 - color);
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE2_WIDTH, 1 - color);
         break;
 
-        case 8:
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE2_WIDTH, 1 - color );
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE3_WIDTH, 1 - color );
+    case 8:
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE2_WIDTH, 1 - color);
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE3_WIDTH, 1 - color);
         break;
 
-        case 9:
-        col0 = rect( bits, row0, col0, height, LINE3_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, 1 - color );
-        col0 = rect( bits, row0, col0, height, LINE1_WIDTH, color );
-        col0 = rect( bits, row0, col0, height, LINE2_WIDTH, 1 - color );
+    case 9:
+        col0 = rect(bits, row0, col0, height, LINE3_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, 1 - color);
+        col0 = rect(bits, row0, col0, height, LINE1_WIDTH, color);
+        col0 = rect(bits, row0, col0, height, LINE2_WIDTH, 1 - color);
         break;
 
-        default:
-        pm_error( "can't happen" );
-        }
+    default:
+        pm_error("INTERNAL ERROR: invalid digit passed to 'addlines'");
+    }
 
     return col0;
-    }
+}
+
+
+
+int
+main(int argc, const char ** argv) {
+
+    const char* const usage = "[-s1|-s2] <type> <manufac> <product>";
+
+    bit ** bits;
+    int argn, style, rows, cols, row, digrow, col, digcolofs;
+    const char * typecode;
+    const char * manufcode;
+    const char * prodcode;
+    int sum, p, lc0, lc1, lc2, lc3, lc4, rc0, rc1, rc2, rc3, rc4;
+
+    pm_proginit(&argc, argv);
+
+    argn = 1;
+    style = 1;
+
+    /* Check for flags. */
+    while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
+        {
+        if ( pm_keymatch( argv[argn], "-s1", 3 ) )
+            style = 1;
+        else if ( pm_keymatch( argv[argn], "-s2", 3 ) )
+            style = 2;
+        else
+            pm_usage( usage );
+        argn++;
+        }
+
+    if ( argn + 3 < argc )
+        pm_usage( usage );
+    typecode = argv[argn];
+    manufcode = argv[argn + 1];
+    prodcode = argv[argn + 2];
+    argn += 3;
+
+    if ( argn != argc )
+        pm_usage( usage );
+
+    if ( strlen( typecode ) != 1 || ( ! alldig( typecode ) ) ||
+         strlen( manufcode ) != 5 || ( ! alldig ( manufcode ) ) ||
+         strlen( prodcode ) != 5 || ( ! alldig ( prodcode ) ) )
+        pm_error(
+            "type code must be one digit, and\n    manufacturer and product codes must be five digits" );
+    p = typecode[0] - '0';
+    lc0 = manufcode[0] - '0';
+    lc1 = manufcode[1] - '0';
+    lc2 = manufcode[2] - '0';
+    lc3 = manufcode[3] - '0';
+    lc4 = manufcode[4] - '0';
+    rc0 = prodcode[0] - '0';
+    rc1 = prodcode[1] - '0';
+    rc2 = prodcode[2] - '0';
+    rc3 = prodcode[3] - '0';
+    rc4 = prodcode[4] - '0';
+    sum = (10 -
+           (((p + lc1 + lc3 + rc0 + rc2 + rc4 ) * 3 +
+             lc0 + lc2 + lc4 + rc1 + rc3)
+            % 10)
+        )
+        % 10;
+
+    rows = 2 * MARGIN + SHORT_HEIGHT + DIGIT_HEIGHT;
+    cols = 2 * MARGIN + 12 * LINES_WIDTH + 11 * LINE1_WIDTH;
+    bits = pbm_allocarray(cols, rows);
+
+    rect(bits, 0, 0, rows, cols, PBM_WHITE);
+
+    row = MARGIN;
+    digrow = row + SHORT_HEIGHT;
+    col = MARGIN;
+    digcolofs = (LINES_WIDTH - DIGIT_WIDTH) / 2;
+
+    if (style == 1)
+        putDigit(p, bits, digrow, col - DIGIT_WIDTH - LINE1_WIDTH);
+    else if (style == 2)
+        putDigit(
+            p, bits, row + SHORT_HEIGHT / 2, col - DIGIT_WIDTH - LINE1_WIDTH);
+
+    col = rect(bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_BLACK);
+    col = rect(bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_WHITE);
+    col = rect(bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_BLACK);
+    col = addLines(p, bits, row, col, TALL_HEIGHT, PBM_WHITE);
+    putDigit(lc0, bits, digrow, col + digcolofs);
+    col = addLines(lc0, bits, row, col, SHORT_HEIGHT, PBM_WHITE);
+    putDigit(lc1, bits, digrow, col + digcolofs);
+    col = addLines(lc1, bits, row, col, SHORT_HEIGHT, PBM_WHITE);
+    putDigit(lc2, bits, digrow, col + digcolofs);
+    col = addLines(lc2, bits, row, col, SHORT_HEIGHT, PBM_WHITE);
+    putDigit(lc3, bits, digrow, col + digcolofs);
+    col = addLines(lc3, bits, row, col, SHORT_HEIGHT, PBM_WHITE);
+    putDigit(lc4, bits, digrow, col + digcolofs);
+    col = addLines(lc4, bits, row, col, SHORT_HEIGHT, PBM_WHITE);
+    col = rect(bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_WHITE);
+    col = rect(bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_BLACK);
+    col = rect(bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_WHITE);
+    col = rect(bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_BLACK);
+    col = rect(bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_WHITE);
+    putDigit(rc0, bits, digrow, col + digcolofs);
+    col = addLines(rc0, bits, row, col, SHORT_HEIGHT, PBM_BLACK);
+    putDigit(rc1, bits, digrow, col + digcolofs);
+    col = addLines(rc1, bits, row, col, SHORT_HEIGHT, PBM_BLACK);
+    putDigit(rc2, bits, digrow, col + digcolofs);
+    col = addLines(rc2, bits, row, col, SHORT_HEIGHT, PBM_BLACK);
+    putDigit(rc3, bits, digrow, col + digcolofs);
+    col = addLines(rc3, bits, row, col, SHORT_HEIGHT, PBM_BLACK);
+    putDigit(rc4, bits, digrow, col + digcolofs);
+    col = addLines(rc4, bits, row, col, SHORT_HEIGHT, PBM_BLACK);
+    col = addLines(sum, bits, row, col, TALL_HEIGHT, PBM_BLACK);
+    col = rect(bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_BLACK);
+    col = rect(bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_WHITE);
+    col = rect(bits, row, col, TALL_HEIGHT, LINE1_WIDTH, PBM_BLACK);
+    if (style == 1)
+        putDigit(sum, bits, digrow, col + LINE1_WIDTH);
+
+    pbm_writepbm(stdout, bits, cols, rows, 0);
+
+    pm_close(stdout );
+
+    exit(0);
+}
+
 
-static int
-rect( bit** bits, int row0, int col0, int height, int width, bit color )
-    {
-    int row, col;
 
-    for ( row = row0; row < row0 + height; row++ )
-        for ( col = col0; col < col0 + width; col++ )
-            bits[row][col] = color;
-    return col0 + width;
-    }
diff --git a/generator/pgmkernel.c b/generator/pgmkernel.c
index cbae0882..8d99a76d 100644
--- a/generator/pgmkernel.c
+++ b/generator/pgmkernel.c
@@ -20,7 +20,7 @@
 #include "shhopt.h"
 #include "mallocvar.h"
 #include "pgm.h"
-
+#include "nstring.h"
 
 
 struct CmdlineInfo {
@@ -89,20 +89,30 @@ parseCommandLine(int argc, const char ** argv,
     if (argc-1 < 1)
         pm_error("Need at least one argument: size of (square) kernel");
     else if (argc-1 == 1) {
-        if (atoi(argv[1]) <= 0)
+        unsigned int dimension;
+        const char * error;
+
+        pm_string_to_uint(argv[1], &dimension, &error);
+        if (error) {
+            pm_error("'%s' is invalid as an image width/height.  %s", argv[1], error);
+            pm_strfree(error);
+        }
+        if (dimension <= 0)
             pm_error("Dimension must be a positive number.  "
                      "You specified '%s'", argv[1]);
-        cmdlineP->cols = atoi(argv[1]);
-        cmdlineP->rows = atoi(argv[1]);
+        cmdlineP->cols = cmdlineP->rows = dimension;
+
     } else if (argc-1 == 2) {
-        if (atoi(argv[1]) <= 0)
+        unsigned int const width  = pm_parse_width(argv[1]);
+        unsigned int const height = pm_parse_height(argv[2]);
+        if (width <= 0)
             pm_error("Width must be a positive number.  "
                      "You specified '%s'", argv[1]);
-        if (atoi(argv[2]) <= 0)
+        if (height <= 0)
             pm_error("Height must be a positive number.  "
                      "You specified '%s'", argv[2]);
-        cmdlineP->cols = atoi(argv[1]);
-        cmdlineP->rows = atoi(argv[2]);
+        cmdlineP->cols = width;
+        cmdlineP->rows = height;
     } else
         pm_error("At most two arguments allowed.  "
                  "You specified %u", argc-1);
@@ -243,3 +253,6 @@ main(int argc, const char * argv[]) {
 
     return 0;
 }
+
+
+
diff --git a/generator/ppmforge.c b/generator/ppmforge.c
index 47f9390e..e32d2b59 100644
--- a/generator/ppmforge.c
+++ b/generator/ppmforge.c
@@ -90,6 +90,7 @@ struct CmdlineInfo {
     float        ice;
     int          saturation;
     unsigned int seed;
+    unsigned int seedSpec;
     int          stars;
     unsigned int starsSpec;
     unsigned int width;
@@ -335,76 +336,38 @@ fourn(double *    const data,
         nprev *= n;
     }
 }
-#undef SWAP
 
 
-struct Gauss {
-    struct pm_randSt randSt;
-    unsigned int     nrand;          /* Gauss() sample count */
-    double           arand;
-    double           gaussadd;
-    double           gaussfac;
-};
-
 
-
-static void
-initgauss(struct Gauss * const gaussP,
-          unsigned int   const seed) {
+static double
+cast(double             const low,
+     double             const high,
+     struct pm_randSt * const randStP) {
 /*----------------------------------------------------------------------------
-  Initialize random number generators.
-
-  As given in Peitgen & Saupe, page 77.
+   A random number in the range ['low', 'high'].
 -----------------------------------------------------------------------------*/
-    gaussP->nrand = 4;
-
-    /* Range of random generator */
-    gaussP->arand    = pow(2.0, 15.0) - 1.0;
-    gaussP->gaussadd = sqrt(3.0 * gaussP->nrand);
-    gaussP->gaussfac = 2 * gaussP->gaussadd / (gaussP->nrand * gaussP->arand);
+    return (low + (high - low) * pm_drand(randStP));
 
-    pm_randinit(&gaussP->randSt);
-    pm_srand(&gaussP->randSt, seed);
 }
 
 
 
 static double
-gauss(struct Gauss * const gaussP) {
+randPhase(struct pm_randSt * const randStP) {
 /*----------------------------------------------------------------------------
-  A Gaussian random number.
-
-  As given in Peitgen & Saupe, page 77.
+   A random number in the range [0, 2 * PI).
 -----------------------------------------------------------------------------*/
-    unsigned int i;
-    double sum;
-
-    for (i = 1, sum = 0.0; i <= gaussP->nrand; ++i) {
-        sum += (pm_rand(&gaussP->randSt) & 0x7FFF);
-    }
-    return gaussP->gaussfac * sum - gaussP->gaussadd;
-}
-
-
-
-static double
-cast(double         const low,
-     double         const high,
-     struct Gauss * const gaussP) {
-
-    return
-        low +
-        ((high-low) * ((pm_rand(&gaussP->randSt) & 0x7FFF) / gaussP->arand));
+     return (2.0 * M_PI * pm_drand1(randStP));
 
 }
 
 
 
 static void
-spectralsynth(double **      const aP,
-              unsigned int   const n,
-              double         const h,
-              struct Gauss * const gaussP) {
+spectralsynth(double **          const aP,
+              unsigned int       const n,
+              double             const h,
+              struct pm_randSt * const randStP) {
 /*----------------------------------------------------------------------------
   Spectrally synthesized fractal motion in two dimensions.
 
@@ -428,10 +391,9 @@ spectralsynth(double **      const aP,
 
     for (i = 0; i <= n / 2; i++) {
         for (j = 0; j <= n / 2; j++) {
-            phase = 2 * M_PI * ((pm_rand(&gaussP->randSt) & 0x7FFF) /
-                                gaussP->arand);
+            phase = randPhase(randStP);
             if (i != 0 || j != 0) {
-                rad = pow((double) (i*i + j*j), -(h + 1) / 2) * gauss(gaussP);
+                rad = pow( (double) (i*i + j*j), - (h + 1) / 2) * pm_gaussrand(randStP);
             } else {
                 rad = 0;
             }
@@ -450,9 +412,8 @@ spectralsynth(double **      const aP,
     Imag(a, n / 2, n / 2) = 0;
     for (i = 1; i <= n / 2 - 1; i++) {
         for (j = 1; j <= n / 2 - 1; j++) {
-            phase = 2 * M_PI * ((pm_rand(&gaussP->randSt) & 0x7FFF) /
-                                gaussP->arand);
-            rad = pow((double) (i * i + j * j), -(h + 1) / 2) * gauss(gaussP);
+            phase = randPhase(randStP);
+            rad = pow((double) (i * i + j * j), -(h + 1) / 2) * pm_gaussrand(randStP);
             rcos = rad * cos(phase);
             rsin = rad * sin(phase);
             Real(a, i, n - j) = rcos;
@@ -507,11 +468,11 @@ temprgb(double   const temp,
 
 static void
 etoile(pixel *        const pix,
-       struct Gauss * const gaussP) {
+       struct pm_randSt * const randStP) {
 /*----------------------------------------------------------------------------
     Set a pixel in the starry sky.
 -----------------------------------------------------------------------------*/
-    if ((pm_rand(&gaussP->randSt) % 1000) < starfraction) {
+    if ((pm_rand(randStP) % 1000) < starfraction) {
         double const starQuality   = 0.5;
             /* Brightness distribution exponent */
         double const starIntensity = 8;
@@ -520,7 +481,7 @@ etoile(pixel *        const pix,
             /* Tint distribution exponent */
         double const v =
             MIN(255.0,
-                starIntensity * pow(1 / (1 - cast(0, 0.9999, gaussP)),
+                starIntensity * pow(1 / (1 - cast(0, 0.9999, randStP)),
                                     (double) starQuality));
 
         /* We make a special case for star color  of zero in order to
@@ -538,8 +499,8 @@ etoile(pixel *        const pix,
             double r, g, b;
 
             temp = 5500 + starcolor *
-                pow(1 / (1 - cast(0, 0.9999, gaussP)), starTintExp) *
-                ((pm_rand(&gaussP->randSt) & 7) ? -1 : 1);
+                pow(1 / (1 - cast(0, 0.9999, randStP)), starTintExp) *
+                ((pm_rand(randStP) & 7) ? -1 : 1);
 
             /* Constrain temperature to a reasonable value: >= 2600K
                (S Cephei/R Andromedae), <= 28,000 (Spica). */
@@ -606,18 +567,18 @@ makeCp(const double * const a,
 
 
 static void
-createPlanetStuff(bool             const clouds,
-                  const double *   const a,
-                  unsigned int     const n,
-                  double **        const uP,
-                  double **        const u1P,
-                  unsigned int **  const bxfP,
-                  unsigned int **  const bxcP,
-                  unsigned char ** const cpP,
-                  Vector *         const sunvecP,
-                  unsigned int     const cols,
-                  pixval           const maxval,
-                  struct Gauss *   const gaussP) {
+createPlanetStuff(bool               const clouds,
+                  const double *     const a,
+                  unsigned int       const n,
+                  double **          const uP,
+                  double **          const u1P,
+                  unsigned int **    const bxfP,
+                  unsigned int **    const bxcP,
+                  unsigned char **   const cpP,
+                  Vector *           const sunvecP,
+                  unsigned int       const cols,
+                  pixval             const maxval,
+                  struct pm_randSt * const randStP) {
 
     double *u, *u1;
     unsigned int *bxf, *bxc;
@@ -627,8 +588,8 @@ createPlanetStuff(bool             const clouds,
 
     /* Compute incident light direction vector. */
 
-    shang = hourspec ? hourangle : cast(0, 2 * M_PI, gaussP);
-    siang = inclspec ? inclangle : cast(-M_PI * 0.12, M_PI * 0.12, gaussP);
+    shang = hourspec ? hourangle : randPhase(randStP);
+    siang = inclspec ? inclangle : cast(-M_PI * 0.12, M_PI * 0.12, randStP);
 
     sunvecP->x = sin(shang) * cos(siang);
     sunvecP->y = sin(siang);
@@ -636,7 +597,7 @@ createPlanetStuff(bool             const clouds,
 
     /* Allow only 25% of random pictures to be crescents */
 
-    if (!hourspec && ((pm_rand(&gaussP->randSt) % 100) < 75)) {
+    if (!hourspec && ((pm_rand(randStP) % 100) < 75)) {
         flipped = (sunvecP->z < 0);
         sunvecP->z = fabs(sunvecP->z);
     } else
@@ -693,9 +654,9 @@ createPlanetStuff(bool             const clouds,
 
 
 static void
-generateStarrySkyRow(pixel *        const pixels,
-                     unsigned int   const cols,
-                     struct Gauss * const gaussP) {
+generateStarrySkyRow(pixel *            const pixels,
+                     unsigned int       const cols,
+                     struct pm_randSt * const randStP) {
 /*----------------------------------------------------------------------------
   Generate a starry sky.  Note  that no FFT is performed;
   the output is  generated  directly  from  a  power  law
@@ -704,7 +665,7 @@ generateStarrySkyRow(pixel *        const pixels,
     unsigned int j;
 
     for (j = 0; j < cols; ++j)
-        etoile(pixels + j, gaussP);
+        etoile(pixels + j, randStP);
 }
 
 
@@ -910,22 +871,22 @@ limbDarken(int *          const irP,
 
 
 static void
-generatePlanetRow(pixel *         const pixelrow,
-                  unsigned int    const row,
-                  unsigned int    const rows,
-                  unsigned int    const cols,
-                  double          const t,
-                  double          const t1,
-                  double *        const u,
-                  double *        const u1,
-                  unsigned char * const cp,
-                  unsigned int *  const bxc,
-                  unsigned int *  const bxf,
-                  int             const byc,
-                  int             const byf,
-                  Vector          const sunvec,
-                  pixval          const maxval,
-                  struct Gauss *  const gaussP) {
+generatePlanetRow(pixel *            const pixelrow,
+                  unsigned int       const row,
+                  unsigned int       const rows,
+                  unsigned int       const cols,
+                  double             const t,
+                  double             const t1,
+                  double *           const u,
+                  double *           const u1,
+                  unsigned char *    const cp,
+                  unsigned int *     const bxc,
+                  unsigned int *     const bxf,
+                  int                const byc,
+                  int                const byf,
+                  Vector             const sunvec,
+                  pixval             const maxval,
+                  struct pm_randSt * const randStP) {
 
     unsigned int const StarClose = 2;
 
@@ -968,25 +929,25 @@ generatePlanetRow(pixel *         const pixelrow,
     /* Left stars */
 
     for (col = 0; (int)col < (int)(cols/2 - (lcos + StarClose)); ++col)
-        etoile(&pixelrow[col], gaussP);
+        etoile(&pixelrow[col], randStP);
 
     /* Right stars */
 
     for (col = cols/2 + (lcos + StarClose); col < cols; ++col)
-        etoile(&pixelrow[col], gaussP);
+        etoile(&pixelrow[col], randStP);
 }
 
 
 
 static void
-genplanet(bool           const stars,
-          bool           const clouds,
-          const double * const a,
-          unsigned int   const cols,
-          unsigned int   const rows,
-          unsigned int   const n,
-          unsigned int   const rseed,
-          struct Gauss * const gaussP) {
+genplanet(bool                const stars,
+          bool                const clouds,
+          const double *      const a,
+          unsigned int        const cols,
+          unsigned int        const rows,
+          unsigned int        const n,
+          unsigned int        const rseed,
+          struct pm_randSt *  const randStP) {
 /*----------------------------------------------------------------------------
   Generate planet from elevation array.
 
@@ -1016,13 +977,13 @@ genplanet(bool           const stars,
                    clouds ? "clouds" : "planet",
                    rseed, fracdim, powscale, meshsize);
         createPlanetStuff(clouds, a, n, &u, &u1, &bxf, &bxc, &cp, &sunvec,
-                          cols, maxval, gaussP);
+                          cols, maxval, randStP);
     }
 
     pixelrow = ppm_allocrow(cols);
     for (row = 0; row < rows; ++row) {
         if (stars)
-            generateStarrySkyRow(pixelrow, cols, gaussP);
+            generateStarrySkyRow(pixelrow, cols, randStP);
         else {
             double const by = (n - 1) * uprj(row, rows);
             int    const byf = floor(by) * n;
@@ -1039,7 +1000,7 @@ genplanet(bool           const stars,
                                   t, t1, u, u1, cp, bxc, bxf, byc, byf,
                                   sunvec,
                                   maxval,
-                                  gaussP);
+                                  randStP);
         }
         ppm_writeppmrow(stdout, pixelrow, cols, maxval, FALSE);
     }
@@ -1144,15 +1105,16 @@ planet(unsigned int const cols,
 -----------------------------------------------------------------------------*/
     double * a;
     bool error;
-    struct Gauss gauss;
+    struct pm_randSt randSt;
 
-    initgauss(&gauss, rseed);
+    pm_randinit(&randSt);
+    pm_srand(&randSt, rseed);
 
     if (stars) {
         a = NULL;
         error = FALSE;
     } else {
-        spectralsynth(&a, meshsize, 3.0 - fracdim, &gauss);
+        spectralsynth(&a, meshsize, 3.0 - fracdim, &randSt);
         if (!a) {
             error = TRUE;
         } else {
@@ -1164,7 +1126,7 @@ planet(unsigned int const cols,
         }
     }
     if (!error)
-        genplanet(stars, clouds, a, cols, rows, meshsize, rseed, &gauss);
+        genplanet(stars, clouds, a, cols, rows, meshsize, rseed, &randSt);
 
     if (a != NULL)
         free(a);
@@ -1213,3 +1175,4 @@ main(int argc, const char ** argv) {
 }
 
 
+
diff --git a/generator/ppmpat.c b/generator/ppmpat.c
index 170bfc58..2f71914e 100644
--- a/generator/ppmpat.c
+++ b/generator/ppmpat.c
@@ -344,8 +344,8 @@ parseCommandLine(int argc, const char ** argv,
         pm_error("You must specify 2 non-option arguments: width and height "
                  "in pixels.  You specified %u", argc-1);
     else {
-        cmdlineP->width  = atoi(argv[1]);
-        cmdlineP->height = atoi(argv[2]);
+        cmdlineP->width  = pm_parse_width(argv[1]);
+        cmdlineP->height = pm_parse_height(argv[2]);
 
         if (cmdlineP->width < 1)
             pm_error("Width must be at least 1 pixel");
@@ -438,9 +438,6 @@ randomDarkColor(struct pm_randSt * const randStP,
 
 
 
-
-
-
 static void
 nextColor(ColorTable * const colorTableP) {
 /*----------------------------------------------------------------------------
@@ -1654,3 +1651,4 @@ main(int argc, const char ** argv) {
 }
 
 
+