static void addToColorMap(unsigned int const seqNum, unsigned int const colorNumber, pixel * const colors, int * const ptab, char colorspec[], int const isTransparent, int * const transparentP) { /*---------------------------------------------------------------------------- Add the color named by colorspec[] to the colormap contained in 'colors' and 'ptab', as the color associated with XPM color number 'colorNumber', which is the seqNum'th color in the XPM color map. Iff 'transparent', set *transparentP to the colormap index that corresponds to this color. -----------------------------------------------------------------------------*/ if (ptab == NULL) { /* Index into table. */ colors[colorNumber] = ppm_parsecolor(colorspec, (pixval) PPM_MAXMAXVAL); if (isTransparent) *transparentP = colorNumber; } else { /* Set up linear search table. */ colors[seqNum] = ppm_parsecolor(colorspec, (pixval) PPM_MAXMAXVAL); ptab[seqNum] = colorNumber; if (isTransparent) *transparentP = seqNum; } }
static void getSpecifiedMissingColor(struct pam * const pamP, const char * const colorName, tuple * const specColorP) { tuple specColor; specColor = pnm_allocpamtuple(pamP); if (colorName) { pixel const color = ppm_parsecolor(colorName, pamP->maxval); if (pamP->depth == 3) { specColor[PAM_RED_PLANE] = PPM_GETR(color); specColor[PAM_GRN_PLANE] = PPM_GETG(color); specColor[PAM_BLU_PLANE] = PPM_GETB(color); } else if (pamP->depth == 1) { specColor[0] = ppm_luminosity(color); } else { pm_error("You may not use -missing with a colormap that is not " "of depth 1 or 3. Yours has depth %u", pamP->depth); } } *specColorP = specColor; }
static void parseColorOpt(const char * const colorOpt, struct cmdlineInfo * const cmdlineP) { unsigned int colorCount; char * colorOptWork; char * cursor; bool eol; colorOptWork = strdup(colorOpt); cursor = &colorOptWork[0]; eol = FALSE; /* initial value */ colorCount = 0; /* initial value */ while (!eol && colorCount < 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 = ppm_bk_color_from_name(&token[3]); } else { cmdlineP->maskColor[colorCount].matchType = MATCH_EXACT; cmdlineP->maskColor[colorCount].u.color = ppm_parsecolor(token, PPM_MAXMAXVAL); } ++colorCount; } else eol = TRUE; } free(colorOptWork); cmdlineP->colorCount = colorCount; }
static style interpretStyle(const char * const styleAttr) { style style; char * buffer; char * p; buffer = strdup(styleAttr); if (buffer == NULL) pm_error("Could not get memory for a buffer to parse style attribute"); p = &buffer[0]; while (p) { const char * const token = strsepN(&p, ";"); const char * strippedToken; const char * p; char * buffer; for (p = &token[0]; isspace(*p); ++p); strippedToken = p; buffer = strdup(strippedToken); if (strlen(strippedToken) > 0) { char * const colonPos = strchr(buffer, ':'); if (colonPos == NULL) pm_error("There is no colon in the attribute specification " "'%s' in the 'style' attribute of a <path> " "element.", strippedToken); else { const char * const value = colonPos + 1; const char * const name = &buffer[0]; *colonPos = '\0'; if (streq(name, "fill")) { style.fillColor = ppm_parsecolor(value, OUTPUT_MAXVAL); } else if (streq(name, "stroke")) { if (!streq(value, "none")) pm_error("Value of 'stroke' attribute in the 'style' " "attribute of a <path> element is '%s'. We " "understand only 'none'", value); } else pm_error("Unrecognized attribute '%s' " "in the 'style' attribute " "of a <path> element", name); } } free(buffer); } free(buffer); return style; }
static void parseCommandLine(int argc, char ** argv, struct cmdlineInfo * const cmdlineP) { /*---------------------------------------------------------------------------- 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. Note that some string information we return as *cmdlineP is in the storage argv[] points to. -----------------------------------------------------------------------------*/ optEntry * option_def; /* Instructions to OptParseOptions3 on how to parse our options. */ optStruct3 opt; unsigned int maxvalSpec; unsigned int option_def_index; MALLOCARRAY(option_def, 100); option_def_index = 0; /* incremented by OPTENTRY */ OPTENT3(0, "maxval", OPT_UINT, &cmdlineP->maxval, &maxvalSpec, 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 (!maxvalSpec) cmdlineP->maxval = PPM_MAXMAXVAL; else { if (cmdlineP->maxval > PPM_OVERALLMAXVAL) pm_error("The value you specified for -maxval (%u) is too big. " "Max allowed is %u", cmdlineP->maxval, PPM_OVERALLMAXVAL); if (cmdlineP->maxval < 1) pm_error("You cannot specify 0 for -maxval"); } if (argc-1 < 3) pm_error("Need 3 arguments: color, width, height."); else if (argc-1 > 3) pm_error("Only 3 arguments allowed: color, width, height. " "You specified %d", argc-1); else { cmdlineP->color = ppm_parsecolor(argv[1], cmdlineP->maxval); cmdlineP->cols = atoi(argv[2]); cmdlineP->rows = atoi(argv[3]); if (cmdlineP->cols <= 0) pm_error("width argument must be a positive number. You " "specified '%s'", argv[2]); if (cmdlineP->rows <= 0) pm_error("height argument must be a positive number. You " "specified '%s'", argv[3]); } }
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; 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); } }
static void readXpm1Header(FILE * const stream, int * const widthP, int * const heightP, int * const chars_per_pixelP, int * const ncolorsP, pixel ** const colorsP, int ** const ptabP) { /*---------------------------------------------------------------------------- Read the header of the XPM file on stream 'stream'. Assume the getline() stream is presently positioned to the beginning of the file and it is a Version 1 XPM file. Leave the stream positioned after the header. Return the information from the header the same as for readXpm3Header. -----------------------------------------------------------------------------*/ char line[MAX_LINE+1], str1[MAX_LINE+1], str2[MAX_LINE+1]; char *t1; char *t2; int format; unsigned int v; int i, j; bool processedStaticChar; /* We have read up to and interpreted the "static char..." line */ *widthP = *heightP = *ncolorsP = *chars_per_pixelP = format = -1; /* Read the initial defines. */ processedStaticChar = FALSE; while (!processedStaticChar) { getline(line, sizeof(line), stream); if (sscanf(line, "#define %s %d", str1, &v) == 2) { char *t1; if ((t1 = strrchr(str1, '_')) == NULL) t1 = str1; else ++t1; if (STREQ(t1, "format")) format = v; else if (STREQ(t1, "width")) *widthP = v; else if (STREQ(t1, "height")) *heightP = v; else if (STREQ(t1, "ncolors")) *ncolorsP = v; else if (STREQ(t1, "pixel")) *chars_per_pixelP = v; } else if (!strncmp(line, "static char", 11)) { if ((t1 = strrchr(line, '_')) == NULL) t1 = line; else ++t1; processedStaticChar = TRUE; } } /* File is positioned to "static char" line, which is in line[] and t1 points to position of last "_" in the line, or the beginning of the line if there is no "_" */ if (format == -1) pm_error("missing or invalid format"); if (format != 1) pm_error("can't handle XPM version %d", format); if (*widthP == -1) pm_error("missing or invalid width"); if (*heightP == -1) pm_error("missing or invalid height"); if (*ncolorsP == -1) pm_error("missing or invalid ncolors"); if (*chars_per_pixelP == -1) pm_error("missing or invalid *chars_per_pixelP"); if (*chars_per_pixelP > 2) pm_message("WARNING: *chars_per_pixelP > 2 uses a lot of memory"); /* If there's a monochrome color table, skip it. */ if (!strncmp(t1, "mono", 4)) { for (;;) { getline(line, sizeof(line), stream); if (!strncmp(line, "static char", 11)) break; } } /* Allocate space for color table. */ if (*chars_per_pixelP <= 2) { /* Up to two chars per pixel, we can use an indexed table. */ v = 1; for (i = 0; i < *chars_per_pixelP; ++i) v *= 256; *colorsP = ppm_allocrow(v); *ptabP = NULL; } else { /* Over two chars per pixel, we fall back on linear search. */ *colorsP = ppm_allocrow(*ncolorsP); MALLOCARRAY(*ptabP, *ncolorsP); if (*ptabP == NULL) pm_error("Unable to allocate memory for %d colors", *ncolorsP); } /* Read color table. */ for (i = 0; i < *ncolorsP; ++i) { getline(line, sizeof(line), stream); if ((t1 = strchr(line, '"')) == NULL) pm_error("D error scanning color table"); if ((t2 = strchr(t1 + 1, '"')) == NULL) pm_error("E error scanning color table"); if (t2 - t1 - 1 != *chars_per_pixelP) pm_error("wrong number of chars per pixel in color table"); strncpy(str1, t1 + 1, t2 - t1 - 1); str1[t2 - t1 - 1] = '\0'; if ((t1 = strchr(t2 + 1, '"')) == NULL) pm_error("F error scanning color table"); if ((t2 = strchr(t1 + 1, '"')) == NULL) pm_error("G error scanning color table"); strncpy(str2, t1 + 1, t2 - t1 - 1); str2[t2 - t1 - 1] = '\0'; v = 0; for (j = 0; j < *chars_per_pixelP; ++j) v = (v << 8) + str1[j]; if (*chars_per_pixelP <= 2) /* Index into table. */ (*colorsP)[v] = ppm_parsecolor(str2, (pixval) PPM_MAXMAXVAL); else { /* Set up linear search table. */ (*colorsP)[i] = ppm_parsecolor(str2, (pixval) PPM_MAXMAXVAL); (*ptabP)[i] = v; } } /* Position to first line of raster (which is the line after "static char ..."). */ for (;;) { getline(line, sizeof(line), stream); if (strncmp(line, "static char", 11) == 0) break; } }
static void parseCommandLine(int argc, 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 sometimes, one of these strings is actually just a suffix of an entry in argv! -----------------------------------------------------------------------------*/ optEntry * option_def; /* Instructions to OptParseOptions3 on how to parse our options. */ optStruct3 opt; unsigned int option_def_index; const char * colorOpt; unsigned int colorSpec; MALLOCARRAY_NOFAIL(option_def, 100); option_def_index = 0; /* incremented by OPTENT3 */ OPTENT3(0, "color", OPT_STRING, &colorOpt, &colorSpec, 0); OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); opt.opt_table = option_def; 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); /* Uses and sets argc, argv, and all of *cmdlineP. */ if (colorSpec) parseColorOpt(colorOpt, cmdlineP); if (colorSpec) { if (argc-1 < 1) cmdlineP->inputFilename = "-"; /* he wants stdin */ else if (argc-1 == 1) cmdlineP->inputFilename = argv[1]; else pm_error("Too many arguments. When you specify -color, " "the only argument accepted is the optional input " "file name."); } else { if (argc-1 < 1) pm_error("You must specify the -color option."); else { cmdlineP->colorCount = 1; cmdlineP->maskColor[0].matchType = MATCH_EXACT; cmdlineP->maskColor[0].u.color = ppm_parsecolor(argv[1], PPM_MAXMAXVAL); if (argc - 1 < 2) cmdlineP->inputFilename = "-"; /* he wants stdin */ else if (argc-1 == 2) cmdlineP->inputFilename = argv[2]; else pm_error("Too many arguments. The only arguments accepted " "are the mask color and optional input file name"); } } }