Example #1
0
static void
ditherImage(struct pam *           const inpamP,
            const scaler *         const scalerP,
            unsigned int           const dithPower,
            struct colorResolution const colorRes,
            struct pam *           const outpamP,
            tuple ***              const outTuplesP) {

    unsigned int const dithDim = 1 << dithPower;
    unsigned int const ditherMatrixArea = SQR(dithDim);

    unsigned int const modMask = (dithDim - 1);
       /* And this into N to compute N % dithDim cheaply, since we
          know (though the compiler doesn't) that dithDim is a power of 2
       */
    unsigned int ** const ditherMatrix = dithMatrix(dithPower);

    tuple * inrow;
    tuple ** outTuples;
    unsigned int row; 
    struct pam ditherPam;
        /* Describes the tuples that ditherRow() sees */

    assert(dithPower < sizeof(unsigned int) * 8);
    assert(UINT_MAX / dithDim >= dithDim);
    
    validateNoDitherOverflow(ditherMatrixArea, inpamP, colorRes);

    inrow = pnm_allocpamrow(inpamP);

    outTuples = pnm_allocpamarray(outpamP);

    /* We will modify the input to promote it to depth 3 */
    ditherPam = *inpamP;
    ditherPam.depth = 3;

    for (row = 0; row < inpamP->height; ++row) {
        pnm_readpamrow(inpamP, inrow);

        pnm_makerowrgb(inpamP, inrow);

        ditherRow(&ditherPam, inrow, scalerP, ditherMatrix, ditherMatrixArea,
                  colorRes, row, modMask,
                  outpamP, outTuples[row]);
    }
    free(ditherMatrix);
    pnm_freepamrow(inrow);
    *outTuplesP = outTuples;
}
  // finds a vertical step using a FIR filter, looking for 1 and 2 step intervals between neighboring cols
  void findVerticalStep(Mat &src, int col, int fsize, int thresh)
  {
    char fbuf[fsize];
    char fbufn[fsize];
    for (int i=0; i<fsize; i++) {fbuf[i] = 0; fbufn[i] = 0;} // init
    int tot = 0, totn = 0;	// total number of responses
    int ind = 0;		// end of FIR
    int out = 0, outn = 0;

    int rows = src.rows;
    for (int i=0; i<rows; i++)
      {
	short* Mi = src.ptr<short>(i);
	int diff = Mi[col+1] - Mi[col];
	if (diff < 3 && diff > 0)
	  {
	    tot++;
	    fbuf[ind] = diff;
	  }
	if (diff > -3 && diff < 0)
	  {
	    totn++;
	    fbufn[ind] = diff;
	  }

	if (++ind >= fsize) ind = 0;
	if (fbuf[ind]!=0) tot--; // fall off the back
	if (fbufn[ind]!=0) totn--; // fall off the back
	fbuf[ind] = 0;		// reset
	fbufn[ind] = 0;		// reset
	//	std::cout << Mi[col] << " " << Mi[col+1] << " " << tot << std::endl;
	if (tot > thresh)
	  {
	    ditherRow(src, col, i-fsize+tot);
	    out++;
	  }
	if (totn > thresh)
	  {
	    ditherRowN(src, col, i-fsize+tot);
	    outn++;
	  }

      }    
    //    if (out > 0 || outn > 0) std::cout << col << " " << out << " " << outn << std::endl;
  }