From afcbdab8ff13554afb5c9ef5c682d2c57ed3a780 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Fri, 5 Jul 2019 01:03:49 +0000 Subject: cleanup git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@3650 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- converter/pbm/pbmtolps.c | 277 +++++++++++++++++++++++++++-------------------- 1 file changed, 157 insertions(+), 120 deletions(-) (limited to 'converter/pbm') diff --git a/converter/pbm/pbmtolps.c b/converter/pbm/pbmtolps.c index dcc5badd..e9577ec8 100644 --- a/converter/pbm/pbmtolps.c +++ b/converter/pbm/pbmtolps.c @@ -1,27 +1,29 @@ -/* - * pbmtolps -- convert a Portable BitMap into Postscript. The - * output Postscript uses lines instead of the image operator to - * generate a (device dependent) picture which will be imaged - * much faster. - * - * The Postscript path length is constrained to be at most 1000 - * points so that no limits are overrun on the Apple Laserwriter - * and (presumably) no other printers. The typical limit is 1500. - * See "4.4 Path Construction" and "Appendix B: Implementation Limits" - * in: PostScript Language Reference Manual - * https://www.adobe.com/content/dam/acom/en/devnet/actionscript/ - * articles/psrefman.pdf - * - * To do: - * make sure encapsulated format is correct - * repitition of black-white strips - * make it more device independent (is this possible?) - * - * Author: - * George Phillips - * Department of Computer Science - * University of British Columbia - */ +/*============================================================================= + pbmtolps +=============================================================================== + + Convert a PBM image to Postscript. The output Postscript uses lines instead + of the image operator to generate a (device dependent) picture which will be + imaged much faster. + + The Postscript path length is constrained to be at most 1000 vertices so that + no limits are overrun on the Apple Laserwriter and (presumably) no other + printers. The typical limit is 1500. See "4.4 Path Construction" and + "Appendix B: Implementation Limits" in: PostScript Language Reference Manual + https://www.adobe.com/content/dam/acom/en/devnet/actionscript/ + articles/psrefman.pdf + + To do: + make sure encapsulated format is correct + repetition of black-white strips + make it more device independent (is this possible?) + + Author: + George Phillips + Department of Computer Science + University of British Columbia +=============================================================================*/ +#include #include "pm_c_util.h" #include "mallocvar.h" @@ -30,9 +32,9 @@ #include "pbm.h" -static float const MaxDPI = 5000; -static float const MinDPI = 10; -static unsigned int const MaxPathPoints = 1000; +static float const MAX_DPI = 5000; +static float const MIN_DPI = 10; +static unsigned int const MAX_PATH_VERTICES = 1000; struct CmdlineInfo { @@ -49,6 +51,15 @@ struct CmdlineInfo { +static void +validateDpi(float const dpi) { + + if (dpi > MAX_DPI || dpi < MIN_DPI) + pm_error("Specified DPI value out of range (%f)", dpi); +} + + + static void parseCommandLine(int argc, const char ** const argv, @@ -78,24 +89,26 @@ parseCommandLine(int argc, pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + if (cmdlineP->dpiSpec) + validateDpi(cmdlineP->dpi); + else + cmdlineP->dpi = 300; + if (argc-1 < 1) cmdlineP->inputFileName = "-"; else { if (argc-1 > 1) pm_error("Program takes zero or one argument (filename). You " - "specified %d", argc-1); - else - cmdlineP->inputFileName = argv[1]; + "specified %u", argc-1); + else + cmdlineP->inputFileName = argv[1]; } if (cmdlineP->inputFileName[0] == '-' && cmdlineP->inputFileName[1] == '\0') - cmdlineP->inputFileSpec = FALSE; - else - cmdlineP->inputFileSpec = TRUE; - - if (cmdlineP->dpiSpec == FALSE) - cmdlineP->dpi = 300; + cmdlineP->inputFileSpec = false; + else + cmdlineP->inputFileSpec = true; free(option_def); } @@ -114,103 +127,127 @@ validateLineWidth(float const sc_cols, static void -validateDpi(float const dpi) { - if (dpi > MaxDPI || dpi < MinDPI) - pm_error("Specified DPI value out of range (%f)", dpi); -} +doRaster(FILE * const ifP, + unsigned int const cols, + unsigned int const rows, + int const format, + FILE * const ofP) { + bit * bitrow; + unsigned int row; + unsigned int vertexCt; + /* Number of vertices drawn since last stroke command */ + bitrow = pbm_allocrow(cols); -int -main(int argc, const char *argv[]) { - FILE* fp; - bit* bits; - int row; - int col; - int rows; - int cols; - int format; - int white; - int black; - float sc_rows; - float sc_cols; - struct CmdlineInfo cmdline; - const char* psName; - unsigned int pointCnt; + for (row = 0, vertexCt = 0; row < rows; ++row) { + unsigned int col; + bool firstRun; - pm_proginit(&argc, argv); - - parseCommandLine(argc, argv, &cmdline); - - if (cmdline.dpi) - validateDpi(cmdline.dpi); + firstRun = true; /* initial value */ - fp = pm_openr(cmdline.inputFileName); - pbm_readpbminit(fp, &cols, &rows, &format); + pbm_readpbmrow(ifP, bitrow, cols, format); - sc_rows = (float) rows / cmdline.dpi * 72.0; - sc_cols = (float) cols / cmdline.dpi * 72.0; - - if (cmdline.lineWidthSpec) - validateLineWidth(sc_cols, sc_rows, cmdline.lineWidth); - - bits = pbm_allocrow(cols); - psName = cmdline.inputFileSpec ? cmdline.inputFileName : "noname"; - - puts("%!PS-Adobe-2.0 EPSF-2.0"); - puts("%%Creator: pbmtolps"); - printf("%%%%Title: %s\n", psName); - printf("%%%%BoundingBox: %d %d %d %d\n", - (int)(305.5 - sc_cols / 2.0), - (int)(395.5 - sc_rows / 2.0), - (int)(306.5 + sc_cols / 2.0), - (int)(396.5 + sc_rows / 2.0)); - puts("%%EndComments"); - puts("%%EndProlog"); - puts("gsave"); - - printf("%f %f translate\n", 306.0 - sc_cols / 2.0, 396.0 + sc_rows / 2.0); - printf("72 %f div dup neg scale\n", cmdline.dpi); - if (cmdline.lineWidthSpec) - printf("%f setlinewidth\n", cmdline.lineWidth); - puts("/a { 0 rmoveto 0 rlineto } def"); - puts("/m { currentpoint stroke newpath moveto } def"); - puts("newpath 0 0 moveto"); - - pointCnt = 0; - for (row = 0; row < rows; row++) { - bool firstRun = TRUE; /* Initial value */ - - pbm_readpbmrow(fp, bits, cols, format); /* output white-strip + black-strip sequences */ + for (col = 0; col < cols; ) { - - for (white = 0; col < cols && bits[col] == PBM_WHITE; col++) - white++; - for (black = 0; col < cols && bits[col] == PBM_BLACK; col++) - black++; - - if (black != 0) { - if (pointCnt > MaxPathPoints) { - printf("m "); - pointCnt = 0; - } - - if (firstRun == TRUE) { - printf ("%d %d moveto %d 0 rlineto\n", white, row, black); - firstRun = FALSE; + unsigned int whiteCt; + unsigned int blackCt; + + for (whiteCt = 0; col < cols && bitrow[col] == PBM_WHITE; ++col) + ++whiteCt; + for (blackCt = 0; col < cols && bitrow[col] == PBM_BLACK; ++col) + ++blackCt; + + if (blackCt > 0) { + if (vertexCt > MAX_PATH_VERTICES) { + printf("m "); + vertexCt = 0; } - else - printf("%d %d a\n", black, white); - pointCnt += 2; + if (firstRun) { + printf("%u %u moveto %u 0 rlineto\n", + whiteCt, row, blackCt); + firstRun = false; + } else + printf("%u %u a\n", blackCt, whiteCt); + + vertexCt += 2; } } } - puts("stroke grestore showpage"); - puts("%%Trailer"); + pbm_freerow(bitrow); +} + + + +static void +pbmtolps(FILE * const ifP, + FILE * const ofP, + struct CmdlineInfo const cmdline) { + + const char * const psName = + cmdline.inputFileSpec ? cmdline.inputFileName : "noname"; + + int rows; + int cols; + int format; + float scRows; + float scCols; + + pbm_readpbminit(ifP, &cols, &rows, &format); + + scRows = (float) rows / cmdline.dpi * 72.0; + scCols = (float) cols / cmdline.dpi * 72.0; + + if (cmdline.lineWidthSpec) + validateLineWidth(scCols, scRows, cmdline.lineWidth); + + fputs("%!PS-Adobe-2.0 EPSF-2.0\n", ofP); + fputs("%%Creator: pbmtolps\n", ofP); + fprintf(ofP, "%%%%Title: %s\n", psName); + fprintf(ofP, "%%%%BoundingBox: %d %d %d %d\n", + (int)(305.5 - scCols / 2.0), + (int)(395.5 - scRows / 2.0), + (int)(306.5 + scCols / 2.0), + (int)(396.5 + scRows / 2.0)); + fputs("%%EndComments\n", ofP); + fputs("%%EndProlog\n", ofP); + fputs("gsave\n", ofP); + + fprintf(ofP, "%f %f translate\n", + 306.0 - scCols / 2.0, 396.0 + scRows / 2.0); + fprintf(ofP, "72 %f div dup neg scale\n", cmdline.dpi); + + if (cmdline.lineWidthSpec) + fprintf(ofP, "%f setlinewidth\n", cmdline.lineWidth); + + fputs("/a { 0 rmoveto 0 rlineto } def\n", ofP); + fputs("/m { currentpoint stroke newpath moveto } def\n", ofP); + fputs("newpath 0 0 moveto\n", ofP); + + doRaster(ifP, cols, rows, format, ofP); + + fputs("stroke grestore showpage\n", ofP); + fputs("%%Trailer\n", ofP); +} + + + +int +main(int argc, const char *argv[]) { + FILE * ifP; + struct CmdlineInfo cmdline; + + pm_proginit(&argc, argv); + + parseCommandLine(argc, argv, &cmdline); + + ifP = pm_openr(cmdline.inputFileName); + + pbmtolps(ifP, stdout, cmdline); - pm_close(fp); + pm_close(ifP); - exit(0); + return 0; } -- cgit 1.4.1