Beispiel #1
0
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;
    }
}
Beispiel #2
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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]);
    }
}
Beispiel #6
0
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);
    }
}
Beispiel #7
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");
        }
    }
}