diff options
Diffstat (limited to 'converter/other/pgmtoppm.c')
-rw-r--r-- | converter/other/pgmtoppm.c | 147 |
1 files changed, 100 insertions, 47 deletions
diff --git a/converter/other/pgmtoppm.c b/converter/other/pgmtoppm.c index 62a388c2..dea6c4ca 100644 --- a/converter/other/pgmtoppm.c +++ b/converter/other/pgmtoppm.c @@ -17,24 +17,27 @@ #include "pm_c_util.h" #include "mallocvar.h" +#include "nstring.h" #include "shhopt.h" #include "ppm.h" -struct cmdlineInfo { +struct CmdlineInfo { /* All the information the user supplied in the command line, in a form easy for the program to use. */ const char * inputFilename; /* '-' if stdin */ const char * map; - const char * colorBlack; - const char * colorWhite; + const char * colorBlack; /* malloc'ed */ + /* The color to which the user says to map black */ + const char * colorWhite; /* malloc'ed */ + /* The color to which the user says to map white */ }; static void -parseCommandLine(int argc, char ** argv, - struct cmdlineInfo * const cmdlineP) { +parseCommandLine(int argc, const char ** argv, + struct CmdlineInfo * const cmdlineP) { /*---------------------------------------------------------------------------- parse program command line described in Unix standard form by argc and argv. Return the information in the options as *cmdlineP. @@ -52,11 +55,18 @@ parseCommandLine(int argc, char ** argv, unsigned int option_def_index; - unsigned int mapSpec; + unsigned int blackSpec, whiteSpec, mapSpec; + + const char * blackOpt; + const char * whiteOpt; MALLOCARRAY_NOFAIL(option_def, 100); option_def_index = 0; /* incremented by OPTENT3 */ + OPTENT3(0, "black", OPT_STRING, &blackOpt, + &blackSpec, 0); + OPTENT3(0, "white", OPT_STRING, &whiteOpt, + &whiteSpec, 0); OPTENT3(0, "map", OPT_STRING, &cmdlineP->map, &mapSpec, 0); @@ -64,13 +74,20 @@ parseCommandLine(int argc, char ** argv, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ - pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (!mapSpec) cmdlineP->map = NULL; if (mapSpec) { + if (blackSpec || whiteSpec) + pm_error("You may not specify -black or -white " + "together with -map"); + + cmdlineP->colorBlack = NULL; + cmdlineP->colorWhite = NULL; + /* No color argument; only argument is file name */ if (argc-1 < 1) cmdlineP->inputFilename = "-"; @@ -81,41 +98,77 @@ parseCommandLine(int argc, char ** argv, "the file name. You specified %u", argc-1); } } else { - /* Arguments are color or color range and file name */ - /* For defaults, we use "rgbi:..." instead of the simpler "black" - and "white" so that we don't have unnecessary dependency on a - color dictionary being available. + /* For default colors, we use "rgbi:..." instead of the simpler + "black" and "white" so that we don't have an unnecessary dependency + on a color dictionary being available. */ - if (argc-1 < 1) { - cmdlineP->colorBlack = "rgbi:0/0/0"; - cmdlineP->colorWhite = "rgbi:1/1/1"; + if (blackSpec || whiteSpec) { + cmdlineP->colorBlack = + pm_strdup(blackSpec ? blackOpt : "rgbi:0/0/0"); + cmdlineP->colorWhite = + pm_strdup(whiteSpec ? whiteOpt : "rgbi:1/1/1"); + + /* The only possibly argument is input file name */ + if (argc-1 < 1) + cmdlineP->inputFilename = "-"; + else { + cmdlineP->inputFilename = argv[1]; + if (argc-1 > 1) + pm_error("Whten you specify -black or -white, " + "there can be at most one non-option arguments: " + "the file name. " + "You specified %u", argc-1); + } } else { - char * buffer = strdup(argv[1]); - char * hyphenPos = strchr(buffer, '-'); - if (hyphenPos) { - *hyphenPos = '\0'; - cmdlineP->colorBlack = buffer; - cmdlineP->colorWhite = hyphenPos+1; + /* Arguments are color or color range and optional file name */ + + if (argc-1 < 1) { + cmdlineP->colorBlack = pm_strdup("rgbi:0/0/0"); + cmdlineP->colorWhite = pm_strdup("rgbi:1/1/1"); } else { - cmdlineP->colorBlack = "rgbi:0/0/0"; - cmdlineP->colorWhite = buffer; + char * buffer = strdup(argv[1]); + if (!buffer) + pm_error("Out of memory allocating tiny buffer"); + char * hyphenPos = strchr(buffer, '-'); + if (hyphenPos) { + *hyphenPos = '\0'; + cmdlineP->colorBlack = pm_strdup(buffer); + cmdlineP->colorWhite = pm_strdup(hyphenPos+1); + } else { + cmdlineP->colorBlack = pm_strdup("rgbi:0/0/0"); + cmdlineP->colorWhite = pm_strdup(buffer); + } + free(buffer); } - } - if (argc-1 < 2) - cmdlineP->inputFilename = "-"; - else - cmdlineP->inputFilename = argv[2]; - if (argc-1 > 2) - pm_error("Program takes at most 2 arguments: " - "color name/range and input file name. " - "You specified %u", argc-1); + if (argc-1 < 2) + cmdlineP->inputFilename = "-"; + else { + cmdlineP->inputFilename = argv[2]; + + if (argc-1 > 2) + pm_error("Program takes at most 2 arguments: " + "color name/range and input file name. " + "You specified %u", argc-1); + } + } } } static void +freeCommandLine(struct CmdlineInfo const cmdline) { + + if (cmdline.colorBlack) + pm_strfree(cmdline.colorBlack); + if (cmdline.colorWhite) + pm_strfree(cmdline.colorWhite); +} + + + +static void convertWithMap(FILE * const ifP, unsigned int const cols, unsigned int const rows, @@ -172,21 +225,19 @@ convertLinear(FILE * const ifP, gray * const grayrow, pixel * const pixelrow) { - pixel colorBlack, colorWhite; - pixval red0, grn0, blu0, red1, grn1, blu1; - unsigned int row; + pixel const colorBlack = ppm_parsecolor(colorNameBlack, maxval); + pixel const colorWhite = ppm_parsecolor(colorNameWhite, maxval); - ppm_writeppminit(ofP, cols, rows, maxval, 0); + pixval const red0 = PPM_GETR(colorBlack); + pixval const grn0 = PPM_GETG(colorBlack); + pixval const blu0 = PPM_GETB(colorBlack); + pixval const red1 = PPM_GETR(colorWhite); + pixval const grn1 = PPM_GETG(colorWhite); + pixval const blu1 = PPM_GETB(colorWhite); - colorBlack = ppm_parsecolor(colorNameBlack, maxval); - colorWhite = ppm_parsecolor(colorNameWhite, maxval); + unsigned int row; - red0 = PPM_GETR(colorBlack); - grn0 = PPM_GETG(colorBlack); - blu0 = PPM_GETB(colorBlack); - red1 = PPM_GETR(colorWhite); - grn1 = PPM_GETG(colorWhite); - blu1 = PPM_GETB(colorWhite); + ppm_writeppminit(ofP, cols, rows, maxval, 0); for (row = 0; row < rows; ++row) { unsigned int col; @@ -208,17 +259,17 @@ convertLinear(FILE * const ifP, int -main(int argc, - char * argv[]) { +main(int argc, + const char * argv[]) { FILE * ifP; - struct cmdlineInfo cmdline; + struct CmdlineInfo cmdline; gray * grayrow; pixel * pixelrow; int rows, cols, format; gray maxval; - ppm_init(&argc, argv); + pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); @@ -240,6 +291,8 @@ main(int argc, pgm_freerow(grayrow); pm_close(ifP); + freeCommandLine(cmdline); + /* If the program failed, it previously aborted with nonzero completion code, via various function calls. */ |