Exemplo n.º 1
0
static void
computehashrecoverable(struct pam *   const pamP,
                       tuple **       const tupleArray, 
                       unsigned int   const maxsize, 
                       sample         const newMaxval,
                       unsigned int * const sizeP,
                       tuplehash *    const tuplefreqhashP,
                       tuple **       const rowbufferP,
                       tuple *        const colorP) {
/*----------------------------------------------------------------------------
   This is computetuplefreqhash(), only it leaves a trail so that if it
   happens to longjmp out because of a failed memory allocation, the
   setjmp'er can cleanup whatever it had done so far.
-----------------------------------------------------------------------------*/
    unsigned int row;
    struct pam freqPam;
    bool full;

    freqPam = *pamP;
    freqPam.maxval = newMaxval;

    *tuplefreqhashP = pnm_createtuplehash();
    *sizeP = 0;   /* initial value */
    
    *rowbufferP = pnm_allocpamrow(pamP);
    
    *colorP = pnm_allocpamtuple(&freqPam);
    
    full = FALSE;  /* initial value */
    
    /* Go through the entire raster, building a hash table of
       tuple values. 
    */
    for (row = 0; row < pamP->height && !full; ++row) {
        int col;
        const tuple * tuplerow;  /* The row of tuples we are processing */
        
        if (tupleArray)
            tuplerow = tupleArray[row];
        else {
            pnm_readpamrow(pamP, *rowbufferP);
            tuplerow = *rowbufferP;
        }
        for (col = 0; col < pamP->width && !full; ++col) {
            pnm_scaletuple(pamP, *colorP, tuplerow[col], freqPam.maxval);
            addColorOccurrenceToHash(
                *colorP, *tuplefreqhashP, &freqPam, maxsize, sizeP, &full);
        }
    }

    pnm_freepamtuple(*colorP); *colorP = NULL;
    pnm_freepamrow(*rowbufferP); *rowbufferP = NULL;

    if (full) {
        pnm_destroytuplehash(*tuplefreqhashP);
        *tuplefreqhashP = NULL;
    }
}
Exemplo n.º 2
0
static void
convertRowPsFilter(struct pam *     const pamP,
                   tuple *          const tuplerow,
                   struct bmepsoe * const bmepsoeP) {

    unsigned int const psMaxval = 255;
    unsigned int col;

    tuple scaledTuple;
    
    scaledTuple = pnm_allocpamtuple(pamP);

    for (col = 0; col < pamP->width; ++col) {
        unsigned int plane;
        pnm_scaletuple(pamP, scaledTuple, tuplerow[col], psMaxval);
        
        for (plane = 0; plane < pamP->depth; ++plane)
            outputBmepsSample(bmepsoeP, scaledTuple[plane]);
    }
    pnm_freepamtuple(scaledTuple);
}
Exemplo n.º 3
0
static void
putMapEntry(struct pam * const pamP, 
            tuple        const value, 
            int          const size) {

    if (size == 15 || size == 16) {
        /* 5 bits each of red, green, and blue.  Watch for byte order */

        tuple const tuple31 = pnm_allocpamtuple(pamP);

        pnm_scaletuple(pamP, tuple31, value, 31);
        {
            int const mapentry = 
                tuple31[PAM_BLU_PLANE] << 0 |
                tuple31[PAM_GRN_PLANE] << 5 |
                tuple31[PAM_RED_PLANE] << 10;
            
            putchar(mapentry % 256);
            putchar(mapentry / 256);
        }
        pnm_freepamtuple(tuple31);
    } else if (size == 8)
        putchar(pnm_scalesample(value[0], 
                                pamP->maxval, TGA_MAXVAL));
    else {
        /* Must be 24 or 32 */
        putchar(pnm_scalesample(value[PAM_BLU_PLANE], 
                                pamP->maxval, TGA_MAXVAL));
        putchar(pnm_scalesample(value[PAM_GRN_PLANE], 
                                pamP->maxval, TGA_MAXVAL));
        putchar(pnm_scalesample(value[PAM_RED_PLANE], 
                                    pamP->maxval, TGA_MAXVAL));
        if (size == 32)
            putchar(pnm_scalesample(value[PAM_TRN_PLANE], 
                                    pamP->maxval, TGA_MAXVAL));
    }
}
Exemplo n.º 4
0
static void
convertRowDither(struct pam *            const inpamP,
                 struct pam *            const outpamP,
                 tuple                   const inrow[],
                 depthAdjustment         const depthAdjustment,
                 tupletable              const colormap,
                 struct colormapFinder * const colorFinderP,
                 tuplehash               const colorhash, 
                 bool *                  const usehashP,
                 tuple                   const defaultColor,
                 struct fserr *          const fserrP,
                 tuple                         outrow[],
                 unsigned int *          const missingCountP) {
/*----------------------------------------------------------------------------
  Like convertRow(), compute outrow[] from inrow[], replacing each pixel with
  the new colors.  Do a Floyd-Steinberg dither, using and updating the error
  accumulator *fserrP.

  Return the number of pixels that were not matched in the color map as
  *missingCountP.

  *colorFinderP is a color finder based on 'colormap' -- it tells us what
  index of 'colormap' corresponds to a certain color.
-----------------------------------------------------------------------------*/
    tuple const ditheredTuple = pnm_allocpamtuple(inpamP);
        /* The input tuple we're converting, adjusted by the dither */
    tuple const normTuple = pnm_allocpamtuple(outpamP);
        /* Same as above, normalized to the maxval of the output file /
           colormap.
        */
    unsigned int missingCount;
    int col;

    floydInitRow(inpamP, fserrP);

    missingCount = 0;  /* initial value */
    
    for (col = fserrP->begCol; col != fserrP->endCol; col += fserrP->step) {
        bool missing;

        floydAdjustColor(inpamP, inrow[col], ditheredTuple, fserrP, col);

        /* Convert tuple to the form of those in the colormap */
        assert(outpamP->allocation_depth >= inpamP->depth);
        pnm_scaletuple(inpamP, normTuple, ditheredTuple, outpamP->maxval);
        adjustDepthTuple(normTuple, depthAdjustment);

        mapTuple(outpamP, normTuple, defaultColor,
                 colormap, colorFinderP,
                 colorhash, usehashP, outrow[col], &missing);

        if (missing)
            ++missingCount;

        /* Convert tuple back to the form of the input, where dithering
           takes place.
        */
        pnm_scaletuple(outpamP, normTuple, outrow[col], inpamP->maxval);
        inverseAdjustDepthTuple(normTuple, depthAdjustment);

        floydPropagateErr(inpamP, fserrP, col, inrow[col], normTuple);
    }

    floydSwitchDir(inpamP, fserrP);

    pnm_freepamtuple(normTuple);
    pnm_freepamtuple(ditheredTuple);

    *missingCountP = missingCount;
}