diff options
Diffstat (limited to 'generator')
-rw-r--r-- | generator/pbmmake.c | 16 | ||||
-rw-r--r-- | generator/pbmtext.c | 206 | ||||
-rw-r--r-- | generator/pbmtextps.c | 57 | ||||
-rw-r--r-- | generator/pgmnoise.c | 21 | ||||
-rw-r--r-- | generator/pgmramp.c | 31 |
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; } + + + |