about summary refs log tree commit diff
path: root/generator
diff options
context:
space:
mode:
Diffstat (limited to 'generator')
-rw-r--r--generator/pbmmake.c16
-rw-r--r--generator/pbmtext.c206
-rw-r--r--generator/pbmtextps.c57
-rw-r--r--generator/pgmnoise.c21
-rw-r--r--generator/pgmramp.c31
5 files changed, 217 insertions, 114 deletions
diff --git a/generator/pbmmake.c b/generator/pbmmake.c
index 600440f0..0352d007 100644
--- a/generator/pbmmake.c
+++ b/generator/pbmmake.c
@@ -61,7 +61,7 @@ parseCommandLine(int argc, char ** argv,
 
     if (blackOpt + whiteOpt + grayOpt > 1)
         pm_error("You can specify only one of -black, -white, and -gray");
-    
+
     if (blackOpt)
         cmdlineP->color = COLOR_BLACK;
     else if (whiteOpt)
@@ -83,8 +83,8 @@ parseCommandLine(int argc, char ** argv,
 
 
 
-static void 
-writeGrayRaster(unsigned int const cols, 
+static void
+writeGrayRaster(unsigned int const cols,
                 unsigned int const rows,
                 FILE *       const ofP) {
 
@@ -96,7 +96,7 @@ writeGrayRaster(unsigned int const cols,
     bitrow0 = pbm_allocrow_packed(cols);
     bitrow1 = pbm_allocrow_packed(cols);
 
-    for (i=0; i <= lastCol; ++i) { 
+    for (i=0; i <= lastCol; ++i) {
         bitrow0[i] = (PBM_WHITE*0xaa) | (PBM_BLACK*0x55);
         bitrow1[i] = (PBM_WHITE*0x55) | (PBM_BLACK*0xaa);
         /* 0xaa = 10101010 ; 0x55 = 01010101 */
@@ -119,7 +119,7 @@ writeGrayRaster(unsigned int const cols,
     pbm_freerow(bitrow1);
 }
 
-    
+
 
 static void
 writeSingleColorRaster(unsigned int const cols,
@@ -134,7 +134,7 @@ writeSingleColorRaster(unsigned int const cols,
 
     bitrow0 = pbm_allocrow_packed(cols);
 
-    for (i = 0; i <= lastCol; ++i) 
+    for (i = 0; i <= lastCol; ++i)
         bitrow0[i] = color*0xff;
 
     if (color != 0)
@@ -161,7 +161,7 @@ main(int argc, char * argv[]) {
     parseCommandLine(argc, argv, &cmdline);
 
     pbm_writepbminit(stdout, cmdline.width, cmdline.height, 0);
-    
+
     if (cmdline.color == COLOR_GRAY)
         writeGrayRaster(cmdline.width, cmdline.height, stdout);
     else {
@@ -169,6 +169,6 @@ main(int argc, char * argv[]) {
         writeSingleColorRaster(cmdline.width, cmdline.height, color, stdout);
     }
     pm_close(stdout);
-    
+
     return 0;
 }
diff --git a/generator/pbmtext.c b/generator/pbmtext.c
index 0fe8ad6a..7d9f7cf7 100644
--- a/generator/pbmtext.c
+++ b/generator/pbmtext.c
@@ -828,55 +828,140 @@ truncateText(struct Text    const inputText,
 
 
 static void
-fgetNarrowWideString(PM_WCHAR *    const widestring,
-                     unsigned int  const size,
-                     FILE *        const ifP,
-                     const char ** const errorP) {
-/*----------------------------------------------------------------------------
-  Return the next line from file *ifP, up to 'size' characters, as
-  *widestring.
+fgetWideString(PM_WCHAR *    const widestring,
+               unsigned int  const size,
+               FILE *        const ifP,
+               bool *        const eofP,
+               const char ** const errorP) {
 
-  Return error if we can't read the file, or file is at EOF.
------------------------------------------------------------------------------*/
-    int wideCode;
-        /* Width orientation for *ifP: positive means wide, negative means
-           byte, zero means undecided.
-        */
+    wchar_t * rc;
 
     assert(widestring);
     assert(size > 0);
 
-    wideCode = fwide(ifP, 0);
-    if (wideCode > 0) {
-        /* *ifP is wide-oriented */
-        wchar_t * rc;
-        rc = fgetws(widestring, size, ifP);
-        if (rc == NULL)
+    rc = fgetws(widestring, size, ifP);
+
+    if (rc == NULL) {
+        if (feof(ifP)) {
+            *eofP   = true;
+            *errorP = NULL;
+        } else if (ferror(ifP) && errno == EILSEQ)
             pm_asprintf(errorP,
-                        "fgetws() of max %u bytes failed or end of stream",
-                        size);
+                        "fgetws(): conversion error: sequence is "
+                        "invalid for locale '%s'",
+                        setlocale(LC_CTYPE, NULL));
         else
-            *errorP = NULL;
+            pm_asprintf(errorP,
+                        "fgetws() of max %u bytes failed",
+                        size);
     } else {
-        char * bufNarrow;
-        char * rc;
+        *eofP   = false;
+        *errorP = NULL;
+    }
+}
 
-        MALLOCARRAY_NOFAIL(bufNarrow, MAXLINECHARS+1);
 
-        rc = fgets(bufNarrow, size, ifP);
-        if (rc == NULL)
-            pm_asprintf(errorP, "EOF or error reading file");
-        else {
-            size_t cnt;
 
-            for (cnt = 0; cnt < size && bufNarrow[cnt] != '\0'; ++cnt)
-                widestring[cnt] = (PM_WCHAR)(unsigned char) bufNarrow[cnt];
+static void
+fgetNarrowString(PM_WCHAR *    const widestring,
+                 unsigned int  const size,
+                 FILE *        const ifP,
+                 bool *        const eofP,
+                 const char ** const errorP) {
+
+    char * bufNarrow;
+    char * rc;
 
-            widestring[cnt] = L'\0';
+    assert(widestring);
+    assert(size > 0);
+
+    MALLOCARRAY_NOFAIL(bufNarrow, MAXLINECHARS+1);
+
+    rc = fgets(bufNarrow, size, ifP);
+
+    if (rc == NULL) {
+        if (feof(ifP)) {
+            *eofP   = true;
             *errorP = NULL;
-        }
-        free(bufNarrow);
+        } else
+            pm_asprintf(errorP, "Error reading file");
+    } else {
+        size_t cnt;
+
+        for (cnt = 0; cnt < size && bufNarrow[cnt] != '\0'; ++cnt)
+            widestring[cnt] = (PM_WCHAR)(unsigned char) bufNarrow[cnt];
+
+        widestring[cnt] = L'\0';
+
+        *eofP   = false;
+        *errorP = NULL;
     }
+    free(bufNarrow);
+}
+
+
+
+static void
+fgetNarrowWideString(PM_WCHAR *    const widestring,
+                     unsigned int  const size,
+                     FILE *        const ifP,
+                     bool *        const eofP,
+                     const char ** const errorP) {
+/*----------------------------------------------------------------------------
+  Return the next line from file *ifP, as *widestring.
+
+  Lines are delimited by newline characters and EOF.
+
+  'size' is the size in characters of the buffer at *widestring.  If the line
+  to which the file is positioned is longer than that minus 1, we consider it
+  to be only that long and consider the next character of the actual line to
+  be the first character of the next line.  We leave the file positioned
+  to that character.
+
+  Return *eofP == true iff we encounter end of file (and therefore don't read
+  a line).
+
+  If we can't read the file (or sense EOF), return as *errorP a text
+  explanation of why; otherwise, return *errorP = NULL.
+
+  The line we return is null-terminated.  But it also includes any embedded
+  null characters that are within the line in the file.  It is not strictly
+  possible for Caller to tell whether a null character in *widestring comes
+  from the file or is the one we put there, so Caller should just ignore any
+  null character and anything after it.  It is also not possible for Caller to
+  tell if we trunctaed the actual line because of 'size' if there is a null
+  character in the line.  This means there just isn't any way to get
+  reasonable behavior from this function if the input file contains null
+  characters (but at least the damage is limited to presenting arbitrary text
+  as the contents of the file - the program won't crash).
+
+  Null characters never appear within normal text (including wide-character
+  text).  If there is one in the input file, it is probably because the input
+  is corrupted.
+
+  The line we return may or may not end in a newline character.  It ends in a
+  newline character unless it doesn't fit in 'size' characters or it is the
+  last line in the file and doesn't end in newline.
+-----------------------------------------------------------------------------*/
+    /* The limitations described above with respect to null characters in
+       *ifP are derived from the same limitations in POSIX 'fgets' and
+       'fgetws'.  To avoid them, we would have to read *ifP one character
+       at a time with 'fgetc' and 'fgetwc'.
+    */
+
+    int const wideCode = fwide(ifP, 0);
+        /* Width orientation for *ifP: positive means wide, negative means
+           byte, zero means undecided.
+        */
+
+    assert(widestring);
+    assert(size > 0);
+
+    if (wideCode > 0)
+        /* *ifP is wide-oriented */
+        fgetWideString(widestring, size, ifP, eofP, errorP);
+    else
+        fgetNarrowString(widestring, size, ifP, eofP, errorP);
 }
 
 
@@ -898,6 +983,10 @@ getText(PM_WCHAR       const cmdlineText[],
    But we return text as only renderable characters - characters in *fontP -
    with control characters interpreted or otherwise fixed, according to
    'fixMode'.
+
+   If *inputTextP indicates Standard Input and Standard Input contains null
+   characters, we will truncate lines or consider a single line to be multiple
+   lines.
 -----------------------------------------------------------------------------*/
     struct Text inputText;
 
@@ -934,30 +1023,31 @@ getText(PM_WCHAR       const cmdlineText[],
 
         for (lineCount = 0, eof = false; !eof; ) {
             const char * error;
-            fgetNarrowWideString(buf, MAXLINECHARS, stdin, &error);
-            if (error) {
-                /* We're lazy, so we treat any error as EOF */
-                pm_strfree(error);
-                eof = true;
-            } else {
-                if (wcslen(buf) + 1 >= MAXLINECHARS)
-                    pm_error(
-                        "Line %u (starting at zero) of input text "
-                        "is longer than %u characters."
-                        "Cannot process",
-                        lineCount, (unsigned int) MAXLINECHARS-1);
-                if (lineCount >= maxlines) {
-                    maxlines *= 2;
-                    REALLOCARRAY(textArray, maxlines);
-                    if (textArray == NULL)
+            fgetNarrowWideString(buf, MAXLINECHARS, stdin, &eof, &error);
+            if (error)
+                pm_error("Unable to read line %u from file.  %s",
+                         lineCount, error);
+            else {
+                if (!eof) {
+                    if (wcslen(buf) + 1 >= MAXLINECHARS)
+                        pm_error(
+                            "Line %u (starting at zero) of input text "
+                            "is longer than %u characters."
+                            "Cannot process",
+                            lineCount, (unsigned int) MAXLINECHARS-1);
+                    if (lineCount >= maxlines) {
+                        maxlines *= 2;
+                        REALLOCARRAY(textArray, maxlines);
+                        if (textArray == NULL)
+                            pm_error("out of memory");
+                    }
+                    fixControlChars(buf, fontP,
+                                    (const PM_WCHAR **)&textArray[lineCount],
+                                    fixMode);
+                    if (textArray[lineCount] == NULL)
                         pm_error("out of memory");
+                    ++lineCount;
                 }
-                fixControlChars(buf, fontP,
-                                (const PM_WCHAR **)&textArray[lineCount],
-                                fixMode);
-                if (textArray[lineCount] == NULL)
-                    pm_error("out of memory");
-                ++lineCount;
             }
         }
         inputText.textArray = textArray;
@@ -1305,7 +1395,7 @@ main(int argc, const char *argv[]) {
         char * newLocale;
         newLocale = setlocale(LC_ALL, "");
         if (!newLocale)
-            pm_error("Failed to set locale (LC_ALL) from environemt");
+            pm_error("Failed to set locale (LC_ALL) from environment");
 
         /* Orient standard input stream to wide */
         fwide(stdin,  1);
diff --git a/generator/pbmtextps.c b/generator/pbmtextps.c
index 68df2b15..f543618d 100644
--- a/generator/pbmtextps.c
+++ b/generator/pbmtextps.c
@@ -25,9 +25,8 @@
  * http://partners.adobe.com/public/developer/ps/index_specs.html
  */
 
-#define _DEFAULT_SOURCE /* New name for SVID & BSD source defines */
-#define _XOPEN_SOURCE   /* Make sure popen() is in stdio.h */
-#define _BSD_SOURCE     /* Make sure stdrup() is in string.h */
+#define _XOPEN_SOURCE 500
+  /* Make sure popen() is in stdio.h, strdup() is in string.h */
 #include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -54,11 +53,11 @@ validateFontName(const char * const name) {
     unsigned int idx;
 
     for (idx = 0; name[idx] != '\0'; ++idx) {
-        char const c = name[idx]; 
+        char const c = name[idx];
 
         if (c < 32 || c > 125)
             pm_error("Invalid character in font name");
-        else 
+        else
             switch (c) {
               case '[':   case ']':   case '(':   case ')':
               case '{':   case '}':   case '/':   case '\\':
@@ -85,7 +84,7 @@ asciiHexEncode(char *          const inbuff,
     unsigned int idx;
 
     for (idx = 0; inbuff[idx] != '\0'; ++idx) {
-        unsigned int const item = (unsigned char) inbuff[idx]; 
+        unsigned int const item = (unsigned char) inbuff[idx];
 
         outbuff[idx*2]   = hexits[item >> 4];
         outbuff[idx*2+1] = hexits[item & 0xF];
@@ -127,7 +126,7 @@ buildTextFromArgs(int           const argc,
             if (text == NULL)
                 pm_error("out of memory");
             strcat(text, " ");
-        } 
+        }
         totalTextSize += strlen(argv[i]);
         text = realloc(text, totalTextSize);
         if (text == NULL)
@@ -135,7 +134,7 @@ buildTextFromArgs(int           const argc,
         strcat(text, argv[i]);
     }
 
-    { 
+    {
         char * asciiHexText;
 
         MALLOCARRAY(asciiHexText, totalTextSize * 2);
@@ -263,7 +262,7 @@ parseCommandLine(int argc, const char ** argv,
     if (cropSpec == TRUE) {
         if (ascentSpec || descentSpec ||
             leftmarginSpec || rightmarginSpec ||
-            topmarginSpec || bottommarginSpec || 
+            topmarginSpec || bottommarginSpec ||
             cmdlineP->pad)
               pm_error("-crop cannot be specified with -ascent, -descent, "
                        "-leftmargin, -rightmargin, "
@@ -346,7 +345,7 @@ postscriptProgram(struct CmdlineInfo const cmdline) {
         "  {/padbottom 0 def /padtop 0 def}\n"
         "  ifelse\n"
         "setfont\n";
-    
+
     const char * const psFixed2 =
         "0 0 moveto\n"
         "textstring false charpath flattenpath pathbbox\n"
@@ -359,7 +358,7 @@ postscriptProgram(struct CmdlineInfo const cmdline) {
         "/xorigin leftmargin BBleft max def\n"
         "/width xorigin BBright add rightmargin add def\n"
         "/height ascent BBtop max padtop max topmargin add yorigin add def\n";
-    
+
     const char * const psFixed3 =
         "<</PageSize [width height]>> setpagedevice\n"
         "xorigin yorigin moveto\n"
@@ -369,7 +368,7 @@ postscriptProgram(struct CmdlineInfo const cmdline) {
         "  textstring true charpath stroke}\n"
         "  ifelse\n"
         "showpage\n";
-    
+
     const char * const psFixed4 =
         "verbose\n"
         "  {xorigin yorigin moveto\n"
@@ -383,7 +382,7 @@ postscriptProgram(struct CmdlineInfo const cmdline) {
         "       {pop (anonymous)}\n"
         "       ifelse]  ==}\n"
         "  if";
-    
+
     const char * retval;
     const char * psVariable;
 
@@ -399,27 +398,27 @@ postscriptProgram(struct CmdlineInfo const cmdline) {
                 psFixed1, psFixed2, psFixed3, psFixed4);
 
     pm_strfree(psVariable);
-        
+
     return retval;
 }
 
 
 
 static const char **
-gsArgList(const char *       const outputFilename, 
+gsArgList(const char *       const outputFilename,
           struct CmdlineInfo const cmdline) {
 
     unsigned int const maxArgCt = 50;
-    
+
     const char ** retval;
     unsigned int argCt;  /* Number of arguments in 'retval' so far */
 
     if (cmdline.res <= 0)
          pm_error("Resolution (dpi) must be positive.");
-    
+
     if (cmdline.fontsize <= 0)
          pm_error("Font size must be positive.");
-  
+
     MALLOCARRAY_NOFAIL(retval, maxArgCt+2);
 
     argCt = 0;  /* initial value */
@@ -491,7 +490,7 @@ reportMetrics(float const  width,
               float const  BBoxright,
               float const  BBoxtop) {
 
-    pm_message("-- Metrics in points.  Bottom left is (0,0) --");  
+    pm_message("-- Metrics in points.  Bottom left is (0,0) --");
     pm_message("Width:   %f", width);
     pm_message("Height:  %f", height);
     pm_message("Ascent:  %f", ascent);
@@ -537,7 +536,7 @@ acceptGSoutput(int             const pipetosuckFd,
     widthHeightReported   = FALSE; /* Initial value */
     ascentDescentReported = FALSE; /* Initial value */
     BBoxReported          = FALSE; /* Initial value */
-    
+
     MALLOCARRAY_NOFAIL(lineBuff, lineBuffSize);
 
     while (fgets(lineBuff, lineBuffSize, inFileP) != NULL) {
@@ -567,7 +566,7 @@ acceptGSoutput(int             const pipetosuckFd,
     }
 
     if (fontnameReported) {
-        fontname[strlen(fontname)-1] = 0; 
+        fontname[strlen(fontname)-1] = 0;
         reportFontName(fontname);
 
         if (widthHeightReported && ascentDescentReported && BBoxReported)
@@ -581,7 +580,7 @@ acceptGSoutput(int             const pipetosuckFd,
 
 
 static void
-executeProgram(const char *       const psProgram, 
+executeProgram(const char *       const psProgram,
                const char *       const outputFname,
                struct CmdlineInfo const cmdline) {
 
@@ -633,19 +632,19 @@ writePbm(const char * const fileName,
     FILE * ifP;
     int format;
     int cols, rows, row ;
-    unsigned char * bitrow; 
-    
+    unsigned char * bitrow;
+
     ifP = pm_openr(fileName);
     pbm_readpbminit(ifP, &cols, &rows, &format);
 
     if (cols == 0 || rows == 0 || cols > INT_MAX - 10 || rows > INT_MAX - 10)
         pm_error("Abnormal output from gs program.  "
                  "width x height = %u x %u", cols, rows);
-               
-    pbm_writepbminit(ofP, cols, rows, 0);           
-               
+
+    pbm_writepbminit(ofP, cols, rows, 0);
+
     bitrow = pbm_allocrow_packed(cols);
-    
+
     for (row = 0; row < rows; ++row) {
         pbm_readpbmrow_packed(ifP, bitrow, cols, format);
         pbm_writepbmrow_packed(ofP, bitrow, cols, 0);
@@ -699,7 +698,7 @@ dumpPsProgram(struct CmdlineInfo const cmdline) {
 
 
 
-int 
+int
 main(int argc, const char *argv[]) {
 
     struct CmdlineInfo cmdline;
diff --git a/generator/pgmnoise.c b/generator/pgmnoise.c
index 442edc59..40d0e189 100644
--- a/generator/pgmnoise.c
+++ b/generator/pgmnoise.c
@@ -56,7 +56,7 @@ parseCommandLine(int argc, const char ** const argv,
 
     if (maxvalSpec) {
         if (cmdlineP->maxval > PGM_OVERALLMAXVAL)
-            pm_error("Maxval too large: %u.  Maximu is %u", 
+            pm_error("Maxval too large: %u.  Maximu is %u",
                      cmdlineP->maxval, PGM_OVERALLMAXVAL);
         else if (cmdlineP->maxval == 0)
             pm_error("Maxval must not be zero");
@@ -70,7 +70,7 @@ parseCommandLine(int argc, const char ** const argv,
     else {
         int const width  = atoi(argv[1]);
         int const height = atoi(argv[2]);
-        
+
         if (width <= 0)
             pm_error("Width must be positive, not %d", width);
         else
@@ -90,12 +90,12 @@ randPool(unsigned int const digits) {
 /*----------------------------------------------------------------------------
   Draw 'digits' bits from pool of random bits.  If the number of random bits
   in pool is insufficient, call rand() and add 31 bits to it.
-  
+
   'digits' must be at most 16.
 
   We assume that each call to rand() generates 31 bits, or RAND_MAX ==
   2147483647.
-  
+
   The underlying logic is flexible and endian-free.  The above conditions
   can be relaxed.
 -----------------------------------------------------------------------------*/
@@ -114,7 +114,7 @@ randPool(unsigned int const digits) {
         hold >>= digits;
         len   -= digits;
     } else {              /* Load another 31 bits into hold */
-        hold    = rand(); 
+        hold    = rand();
         retval |= (hold << len);
         hold >>=  (digits - len);
         len = 31 - digits + len;
@@ -164,11 +164,11 @@ pgmnoise(FILE *       const ofP,
             unsigned int col;
             for (col = 0; col < cols; ++col)
                 destrow[col] = randPool(bitLen);
-        } 
-        else { 
+        }
+        else {
             unsigned int col;
             for (col = 0; col < cols; ++col)
-                destrow[col] = rand() % (maxval + 1); 
+                destrow[col] = rand() % (maxval + 1);
         }
         pgm_writepgmrow(ofP, destrow, cols, maxval, 0);
     }
@@ -181,7 +181,7 @@ pgmnoise(FILE *       const ofP,
 int
 main(int          argc,
      const char * argv[]) {
-    
+
     struct cmdlineInfo cmdline;
 
     pm_proginit(&argc, argv);
@@ -194,3 +194,6 @@ main(int          argc,
 
     return 0;
 }
+
+
+
diff --git a/generator/pgmramp.c b/generator/pgmramp.c
index 225542fe..db32b9f0 100644
--- a/generator/pgmramp.c
+++ b/generator/pgmramp.c
@@ -35,7 +35,7 @@ static void
 parseCommandLine(int argc, char ** argv,
                  struct cmdlineInfo * const cmdlineP) {
 /*----------------------------------------------------------------------------
-  Convert program invocation arguments (argc,argv) into a format the 
+  Convert program invocation arguments (argc,argv) into a format the
   program can use easily, struct cmdlineInfo.  Validate arguments along
   the way and exit program with message if invalid.
 
@@ -111,12 +111,23 @@ parseCommandLine(int argc, char ** argv,
 
 
 
+static int
+diffu(unsigned int const subtrahend,
+      unsigned int const subtractor) {
+
+    return (int)subtrahend - (int)subtractor;
+
+    /* (Not the conventional terminology, but better) */
+}
+
+
+
 int
 main(int argc, char *argv[]) {
 
     struct cmdlineInfo cmdline;
     gray *grayrow;
-    int rowso2, colso2;
+    unsigned int rowso2, colso2;
     unsigned int row;
 
     pgm_init( &argc, argv );
@@ -149,20 +160,17 @@ main(int argc, char *argv[]) {
                         MAX((float) cmdline.cols + cmdline.rows-2, 1);
                 break;
             case RT_RECT: {
-                float const r = fabs((int)(rowso2 - row)) / rowso2;
-                float const c = fabs((int)(colso2 - col)) / colso2;
+                float const r = fabs((float)diffu(rowso2, row)) / rowso2;
+                float const c = fabs((float)diffu(colso2, col)) / colso2;
                 grayrow[col] =
                     cmdline.maxval - (r + c) / 2.0 * cmdline.maxval;
             } break;
 
             case RT_ELLIP: {
-                float const r = fabs((int)(rowso2 - row)) / rowso2;
-                float const c = fabs((int)(colso2 - col)) / colso2;
-                float v;
+                float const r = fabs((float)diffu(rowso2, row)) / rowso2;
+                float const c = fabs((float)diffu(colso2, col)) / colso2;
+                float const v = MAX(0.0f, MIN(1.0f, SQR(r) + SQR(c)));
 
-                v = r * r + c * c;
-                if ( v < 0.0 ) v = 0.0;
-                else if ( v > 1.0 ) v = 1.0;
                 grayrow[col] = cmdline.maxval - v * cmdline.maxval;
             } break;
             }
@@ -174,3 +182,6 @@ main(int argc, char *argv[]) {
     pm_close(stdout);
     return 0;
 }
+
+
+