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; }