From 67ed1e8e515949052c7714d0822a4d5aaeb5a8cc Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 10 Dec 2006 18:58:01 +0000 Subject: clean up, fix maxval problem git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@166 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- converter/other/pgmtoppm.c | 342 ++++++++++++++++++++++++++++----------------- 1 file changed, 214 insertions(+), 128 deletions(-) (limited to 'converter') diff --git a/converter/other/pgmtoppm.c b/converter/other/pgmtoppm.c index c695ddd5..cface024 100644 --- a/converter/other/pgmtoppm.c +++ b/converter/other/pgmtoppm.c @@ -11,143 +11,229 @@ */ #include + +#include "mallocvar.h" +#include "shhopt.h" #include "ppm.h" -int -main( argc, argv ) - int argc; - char* argv[]; - { - FILE* ifp; - gray* grayrow; - register gray* gP; - pixel p; - pixel* pixelrow; - register pixel* pP; - pixel** mappixels; - int argn, rows, cols, format, maprows, mapcols, mapmaxcolor, row; - register int col; - gray maxval; +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; +}; + + + +static void +parseCommandLine(int argc, 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. + + If command line is internally inconsistent (invalid options, etc.), + issue error message to stderr and abort program. + + Note that the strings we return are stored in the storage that + was passed to us as the argv array. We also trash *argv. +-----------------------------------------------------------------------------*/ + optEntry *option_def; + /* Instructions to optParseOptions3 on how to parse our options. + */ + optStruct3 opt; + + unsigned int option_def_index; + + unsigned int mapSpec; + + MALLOCARRAY_NOFAIL(option_def, 100); + + option_def_index = 0; /* incremented by OPTENT3 */ + OPTENT3(0, "map", OPT_STRING, &cmdlineP->map, + &mapSpec, 0); + + opt.opt_table = option_def; + opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ + opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + + optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + + if (!mapSpec) + cmdlineP->map = NULL; + + if (mapSpec) { + /* No color argument; only argument is file name */ + if (argc-1 < 1) + cmdlineP->inputFilename = "-"; + else { + cmdlineP->inputFilename = argv[1]; + if (argc-1 > 1) + pm_error("With -map option, there is at most one argument: " + "the file name. You specified %u", argc-1); + } + } else { + /* Arguments are color or color range and file name */ + if (argc-1 < 1) { + cmdlineP->colorBlack = "black"; + cmdlineP->colorWhite = "white"; + } else { + char * buffer = strdup(argv[1]); + char * hyphenPos = strchr(buffer, '-'); + if (hyphenPos) { + *hyphenPos = '\0'; + cmdlineP->colorBlack = buffer; + cmdlineP->colorWhite = hyphenPos+1; + } else { + cmdlineP->colorBlack = "black"; + cmdlineP->colorWhite = 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); + } +} + + + +static void +convertWithMap(FILE * const ifP, + unsigned int const cols, + unsigned int const rows, + gray const maxval, + int const format, + const char * const mapFileName, + FILE * const ofP, + gray * const grayrow, + pixel * const pixelrow) { + + unsigned int row; + FILE * mapFileP; + int mapcols, maprows; pixval mapmaxval; - char* color0; - char* color1; + pixel ** mappixels; + unsigned int mapmaxcolor; + + mapFileP = pm_openr(mapFileName); + mappixels = ppm_readppm(mapFileP, &mapcols, &maprows, &mapmaxval); + pm_close(mapFileP); + mapmaxcolor = maprows * mapcols - 1; + + ppm_writeppminit(ofP, cols, rows, mapmaxval, 0); + + for (row = 0; row < rows; ++row) { + unsigned int col; + + pgm_readpgmrow(ifP, grayrow, cols, maxval, format); + + for (col = 0; col < cols; ++col) { + unsigned int c; + if (maxval == mapmaxcolor) + c = grayrow[col]; + else + c = grayrow[col] * mapmaxcolor / maxval; + pixelrow[col] = mappixels[c / mapcols][c % mapcols]; + } + ppm_writeppmrow(ofP, pixelrow, cols, mapmaxval, 0); + } + ppm_freearray(mappixels, maprows); +} + + + +static void +convertLinear(FILE * const ifP, + unsigned int const cols, + unsigned int const rows, + gray const maxval, + int const format, + const char * const colorNameBlack, + const char * const colorNameWhite, + FILE * const ofP, + gray * const grayrow, + pixel * const pixelrow) { + + pixel colorBlack, colorWhite; pixval red0, grn0, blu0, red1, grn1, blu1; - const char* const usage = " [pgmfile]\n , [pgmfile]\n -map mapfile [pgmfile]"; - - - ppm_init( &argc, argv ); - - argn = 1; - mappixels = (pixel**) 0; - - if ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) - { - if ( pm_keymatch( argv[argn], "-map", 2 ) ) - { - ++argn; - if ( argn == argc ) - pm_usage( usage ); - ifp = pm_openr( argv[argn] ); - mappixels = ppm_readppm( ifp, &mapcols, &maprows, &mapmaxval ); - pm_close( ifp ); - mapmaxcolor = maprows * mapcols - 1; - } - else - pm_usage( usage ); - ++argn; - } - - if ( mappixels == (pixel**) 0 ) - { - if ( argn == argc ) - pm_usage( usage ); - color0 = argv[argn]; - ++argn; - } - - if ( argn != argc ) - { - ifp = pm_openr( argv[argn] ); - ++argn; - } - else - ifp = stdin; + unsigned int row; + + ppm_writeppminit(ofP, cols, rows, maxval, 0); + + colorBlack = ppm_parsecolor(colorNameBlack, maxval); + colorWhite = ppm_parsecolor(colorNameWhite, maxval); + + red0 = PPM_GETR(colorBlack); + grn0 = PPM_GETG(colorBlack); + blu0 = PPM_GETB(colorBlack); + red1 = PPM_GETR(colorWhite); + grn1 = PPM_GETG(colorWhite); + blu1 = PPM_GETB(colorWhite); + + for (row = 0; row < rows; ++row) { + unsigned int col; + + pgm_readpgmrow(ifP, grayrow, cols, maxval, format); + + for (col = 0; col < cols; ++col) { + gray const input = grayrow[col]; + PPM_ASSIGN( + pixelrow[col], + (red0 * (maxval - input) + red1 * input) / maxval, + (grn0 * (maxval - input) + grn1 * input) / maxval, + (blu0 * (maxval - input) + blu1 * input) / maxval); + } + ppm_writeppmrow(ofP, pixelrow, cols, maxval, 0); + } +} + - if ( argn != argc ) - pm_usage( usage ); - pgm_readpgminit( ifp, &cols, &rows, &maxval, &format ); - grayrow = pgm_allocrow( cols ); - if ( mappixels == (pixel**) 0 ) - ppm_writeppminit( stdout, cols, rows, (pixval) maxval, 0 ); +int +main(int argc, + char * argv[]) { + + FILE * ifP; + struct cmdlineInfo cmdline; + gray * grayrow; + pixel * pixelrow; + int rows, cols, format; + gray maxval; + + ppm_init(&argc, argv); + + parseCommandLine(argc, argv, &cmdline); + + ifP = pm_openr(cmdline.inputFilename); + + pgm_readpgminit(ifP, &cols, &rows, &maxval, &format); + grayrow = pgm_allocrow(cols); + pixelrow = ppm_allocrow(cols); + + if (cmdline.map) + convertWithMap(ifP, cols, rows, maxval, format, cmdline.map, + stdout, grayrow, pixelrow); else - ppm_writeppminit( stdout, cols, rows, mapmaxval, 0 ); - pixelrow = ppm_allocrow( cols ); - - if ( mappixels == (pixel**) 0 ) - { - color1 = strchr( color0, '-' ); - if ( color1 == 0 ) - { - color1 = color0; - red0 = 0; - grn0 = 0; - blu0 = 0; - } - else - { - *color1 = '\0'; - ++color1; - p = ppm_parsecolor( color0, (pixval) maxval ); - red0 = PPM_GETR( p ); - grn0 = PPM_GETG( p ); - blu0 = PPM_GETB( p ); - } - p = ppm_parsecolor( color1, (pixval) maxval ); - red1 = PPM_GETR( p ); - grn1 = PPM_GETG( p ); - blu1 = PPM_GETB( p ); - } - - for ( row = 0; row < rows; ++row ) - { - pgm_readpgmrow( ifp, grayrow, cols, maxval, format ); - - if ( mappixels == (pixel**) 0 ) - { - for ( col = 0, gP = grayrow, pP = pixelrow; - col < cols; - ++col, ++gP, ++pP ) - PPM_ASSIGN( - *pP, - ( red0 * ( maxval - *gP ) + red1 * *gP ) / maxval, - ( grn0 * ( maxval - *gP ) + grn1 * *gP ) / maxval, - ( blu0 * ( maxval - *gP ) + blu1 * *gP ) / maxval ); - - } - else - { - register int c; - - for ( col = 0, gP = grayrow, pP = pixelrow; - col < cols; - ++col, ++gP, ++pP ) - { - if ( maxval == mapmaxcolor ) - c = *gP; - else - c = *gP * mapmaxcolor / maxval; - *pP = mappixels[c / mapcols][c % mapcols]; - } - } - - ppm_writeppmrow( stdout, pixelrow, cols, (pixval) maxval, 0 ); - } - - pm_close( ifp ); + convertLinear(ifP, cols, rows, maxval, format, + cmdline.colorBlack, cmdline.colorWhite, stdout, + grayrow, pixelrow); + + ppm_freerow(pixelrow); + pgm_freerow(grayrow); + pm_close(ifP); /* If the program failed, it previously aborted with nonzero completion code, via various function calls. */ return 0; - } +} -- cgit 1.4.1