diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2017-06-30 03:27:10 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2017-06-30 03:27:10 +0000 |
commit | 08d938dc6fc6b30e5da6733b52c97169c0d24f8a (patch) | |
tree | 92673cd6a5755fc209078cc6b6a42602defc0212 /editor/ppmcolormask.c | |
parent | e21f4e95d897c93a4779bf78c71f1341d164a222 (diff) | |
download | netpbm-mirror-08d938dc6fc6b30e5da6733b52c97169c0d24f8a.tar.gz netpbm-mirror-08d938dc6fc6b30e5da6733b52c97169c0d24f8a.tar.xz netpbm-mirror-08d938dc6fc6b30e5da6733b52c97169c0d24f8a.zip |
Copy Development as new Advanced
git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@3018 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'editor/ppmcolormask.c')
-rw-r--r-- | editor/ppmcolormask.c | 177 |
1 files changed, 114 insertions, 63 deletions
diff --git a/editor/ppmcolormask.c b/editor/ppmcolormask.c index 96be89a1..d9f68b68 100644 --- a/editor/ppmcolormask.c +++ b/editor/ppmcolormask.c @@ -20,23 +20,23 @@ #include "mallocvar.h" #include "nstring.h" #include "ppm.h" -#include "pbm.h" +#include "pam.h" -enum matchType { +typedef enum { MATCH_EXACT, MATCH_BK -}; +} MatchType; -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; - unsigned int colorCount; + unsigned int colorCt; struct { - enum matchType matchType; + MatchType matchType; union { - pixel color; /* matchType == MATCH_EXACT */ + tuplen color; /* matchType == MATCH_EXACT */ bk_color bkColor; /* matchType == MATCH_BK */ } u; } maskColor[16]; @@ -46,10 +46,23 @@ struct cmdlineInfo { static void +freeCmdline(struct CmdlineInfo * const cmdlineP) { + + unsigned int i; + + for (i = 0; i < cmdlineP->colorCt; ++ i) { + if (cmdlineP->maskColor[i].matchType == MATCH_EXACT) + free(cmdlineP->maskColor[i].u.color); + } +} + + + +static void parseColorOpt(const char * const colorOpt, - struct cmdlineInfo * const cmdlineP) { + struct CmdlineInfo * const cmdlineP) { - unsigned int colorCount; + unsigned int colorCt; char * colorOptWork; char * cursor; bool eol; @@ -58,34 +71,34 @@ parseColorOpt(const char * const colorOpt, cursor = &colorOptWork[0]; eol = FALSE; /* initial value */ - colorCount = 0; /* initial value */ - while (!eol && colorCount < ARRAY_SIZE(cmdlineP->maskColor)) { + colorCt = 0; /* initial value */ + while (!eol && colorCt < ARRAY_SIZE(cmdlineP->maskColor)) { const char * token; token = pm_strsep(&cursor, ","); if (token) { if (strneq(token, "bk:", 3)) { - cmdlineP->maskColor[colorCount].matchType = MATCH_BK; - cmdlineP->maskColor[colorCount].u.bkColor = + cmdlineP->maskColor[colorCt].matchType = MATCH_BK; + cmdlineP->maskColor[colorCt].u.bkColor = ppm_bk_color_from_name(&token[3]); } else { - cmdlineP->maskColor[colorCount].matchType = MATCH_EXACT; - cmdlineP->maskColor[colorCount].u.color = - ppm_parsecolor(token, PPM_MAXMAXVAL); + cmdlineP->maskColor[colorCt].matchType = MATCH_EXACT; + cmdlineP->maskColor[colorCt].u.color = + pnm_parsecolorn(token); } - ++colorCount; + ++colorCt; } else eol = TRUE; } free(colorOptWork); - cmdlineP->colorCount = colorCount; + cmdlineP->colorCt = colorCt; } static void -parseCommandLine(int argc, char ** argv, - struct cmdlineInfo *cmdlineP) { +parseCommandLine(int argc, const char ** argv, + struct CmdlineInfo *cmdlineP) { /*---------------------------------------------------------------------------- Note that many of the strings that this function returns in the *cmdlineP structure are actually in the supplied argv array. And @@ -110,7 +123,7 @@ parseCommandLine(int argc, char ** argv, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We may have 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 all of *cmdlineP. */ if (colorSpec) @@ -129,10 +142,9 @@ parseCommandLine(int argc, char ** argv, if (argc-1 < 1) pm_error("You must specify the -color option."); else { - cmdlineP->colorCount = 1; + cmdlineP->colorCt = 1; cmdlineP->maskColor[0].matchType = MATCH_EXACT; - cmdlineP->maskColor[0].u.color = - ppm_parsecolor(argv[1], PPM_MAXMAXVAL); + cmdlineP->maskColor[0].u.color = pnm_parsecolorn(argv[1]); if (argc - 1 < 2) cmdlineP->inputFilename = "-"; /* he wants stdin */ @@ -147,16 +159,47 @@ parseCommandLine(int argc, char ** argv, +static void +setupOutput(FILE * const fileP, + unsigned int const width, + unsigned int const height, + struct pam * const outPamP) { + + outPamP->size = sizeof(*outPamP); + outPamP->len = PAM_STRUCT_SIZE(tuple_type); + outPamP->file = fileP; + outPamP->format = RPBM_FORMAT; + outPamP->plainformat = 0; + outPamP->height = height; + outPamP->width = width; + outPamP->depth = 1; + outPamP->maxval = 1; + outPamP->bytes_per_sample = 1; + strcpy(outPamP->tuple_type, PAM_PBM_TUPLETYPE); +} + + + static bool -isBkColor(pixel const comparator, - pixval const maxval, - bk_color const comparand) { +isBkColor(tuple const comparator, + struct pam * const pamP, + bk_color const comparand) { + + pixel comparatorPixel; + bk_color comparatorBk; /* TODO: keep a cache of the bk color for each color in a colorhash_table. */ - bk_color const comparatorBk = ppm_bk_color_from_color(comparator, maxval); + assert(pamP->depth >= 3); + + PPM_ASSIGN(comparatorPixel, + comparator[PAM_RED_PLANE], + comparator[PAM_GRN_PLANE], + comparator[PAM_BLU_PLANE]); + + comparatorBk = ppm_bk_color_from_color(comparatorPixel, pamP->maxval); return comparatorBk == comparand; } @@ -164,86 +207,94 @@ isBkColor(pixel const comparator, static bool -colorIsInSet(pixel const color, - pixval const maxval, - struct cmdlineInfo const cmdline) { +colorIsInSet(tuple const color, + struct pam * const pamP, + struct CmdlineInfo const cmdline) { bool isInSet; unsigned int i; + tuple maskColorUnnorm; + + maskColorUnnorm = pnm_allocpamtuple(pamP); - for (i = 0, isInSet = FALSE; - i < cmdline.colorCount && !isInSet; ++i) { + for (i = 0, isInSet = FALSE; i < cmdline.colorCt && !isInSet; ++i) { assert(i < ARRAY_SIZE(cmdline.maskColor)); switch(cmdline.maskColor[i].matchType) { case MATCH_EXACT: - if (PPM_EQUAL(color, cmdline.maskColor[i].u.color)) + pnm_unnormalizetuple(pamP, + cmdline.maskColor[i].u.color, + maskColorUnnorm); + if (pnm_tupleequal(pamP, color, maskColorUnnorm)) isInSet = TRUE; break; case MATCH_BK: - if (isBkColor(color, maxval, cmdline.maskColor[i].u.bkColor)) + if (isBkColor(color, pamP, cmdline.maskColor[i].u.bkColor)) isInSet = TRUE; break; } } + + free(maskColorUnnorm); + return isInSet; } int -main(int argc, char *argv[]) { +main(int argc, const char *argv[]) { - struct cmdlineInfo cmdline; + struct CmdlineInfo cmdline; FILE * ifP; + struct pam inPam; + struct pam outPam; - /* Parameters of input image: */ - int rows, cols; - pixval maxval; - int format; - - ppm_init(&argc, argv); + pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); ifP = pm_openr(cmdline.inputFilename); - ppm_readppminit(ifP, &cols, &rows, &maxval, &format); - pbm_writepbminit(stdout, cols, rows, 0); + pnm_readpaminit(ifP, &inPam, PAM_STRUCT_SIZE(allocation_depth)); + + pnm_setminallocationdepth(&inPam, 3); + + setupOutput(stdout, inPam.width, inPam.height, &outPam); + + pnm_writepaminit(&outPam); { - pixel * const inputRow = ppm_allocrow(cols); - bit * const maskRow = pbm_allocrow(cols); + tuple * const inputRow = pnm_allocpamrow(&inPam); + tuple * const maskRow = pnm_allocpamrow(&outPam); unsigned int numPixelsMasked; unsigned int row; - for (row = 0, numPixelsMasked = 0; row < rows; ++row) { - int col; - ppm_readppmrow(ifP, inputRow, cols, maxval, format); - for (col = 0; col < cols; ++col) { - pixel thisColor; - /* Color of this pixel with same maxval as used in - 'cmdline' - */ - PPM_DEPTH(thisColor, inputRow[col], maxval, PPM_MAXMAXVAL); - if (colorIsInSet(thisColor, PPM_MAXMAXVAL, cmdline)) { - maskRow[col] = PBM_BLACK; + + for (row = 0, numPixelsMasked = 0; row < inPam.height; ++row) { + unsigned int col; + pnm_readpamrow(&inPam, inputRow); + pnm_makerowrgb(&inPam, inputRow); + for (col = 0; col < inPam.width; ++col) { + if (colorIsInSet(inputRow[col], &inPam, cmdline)) { + maskRow[col][0] = PAM_BLACK; ++numPixelsMasked; } else - maskRow[col] = PBM_WHITE; + maskRow[col][0] = PAM_BW_WHITE; } - pbm_writepbmrow(stdout, maskRow, cols, 0); + pnm_writepamrow(&outPam, maskRow); } if (cmdline.verbose) pm_message("%u pixels found matching %u requested colors", - numPixelsMasked, cmdline.colorCount); + numPixelsMasked, cmdline.colorCt); - pbm_freerow(maskRow); - ppm_freerow(inputRow); + pnm_freepamrow(maskRow); + pnm_freepamrow(inputRow); } + freeCmdline(&cmdline); pm_close(ifP); return 0; |