static void writeBlackRows(const struct pam * const outpamP, int const rows) { /*---------------------------------------------------------------------------- Write out 'rows' rows of black tuples of the image described by *outpamP. Unless our input image is PBM, PGM, or PPM, or PAM equivalent, we don't really know what "black" means, so this is just something arbitrary in that case. -----------------------------------------------------------------------------*/ tuple blackTuple; tuple * blackRow; int col; pnm_createBlackTuple(outpamP, &blackTuple); MALLOCARRAY_NOFAIL(blackRow, outpamP->width); for (col = 0; col < outpamP->width; ++col) blackRow[col] = blackTuple; pnm_writepamrowmult(outpamP, blackRow, rows); free(blackRow); pnm_freepamtuple(blackTuple); }
static void writeOutput(const struct pam * const inpamP, const unsigned char * const * const pi) { tuple black, white; tuple * outputTuplerow; /* This is not a normal tuplerow; it is just pointers to either 'black' or 'white' */ unsigned int row; struct pam outpam; initOutpam(inpamP, &outpam); allocateOutputPointerRow(outpam.width, &outputTuplerow); pnm_createBlackTuple(&outpam, &black); createWhiteTuple(&outpam, &white); pnm_writepaminit(&outpam); for (row = 0; row < outpam.height; ++row) { unsigned int col; for (col = 0; col < outpam.width; ++col) outputTuplerow[col] = pi[row][col] == PT_BG ? white : black; pnm_writepamrow(&outpam, outputTuplerow); } pnm_freepamtuple(white); pnm_freepamtuple(black); free(outputTuplerow); }
/* Draw a pair of guide boxes. */ static void drawguides(int const guidesize, const struct pam * const outPamP, double const eyesep, unsigned int const dpi, double const depthOfField) { int const far = separation(0, eyesep, dpi, depthOfField); /* Space between the two guide boxes. */ int const width = outPamP->width; /* Width of the output image */ tuple *outrow; /* One row of output data */ tuple blackTuple; int col; pnm_createBlackTuple(outPamP, &blackTuple); outrow = pnm_allocpamrow(outPamP); /* Leave some blank rows before the guides. */ makeWhiteRow(outPamP, outrow); writeRowCopies(outPamP, outrow, guidesize); /* Draw the guides. */ if ((width - far + guidesize)/2 < 0 || (width + far - guidesize)/2 >= width) pm_message("warning: the guide boxes are completely out of bounds " "at %d DPI", dpi); else if ((width - far - guidesize)/2 < 0 || (width + far + guidesize)/2 >= width) pm_message("warning: the guide boxes are partially out of bounds " "at %d DPI", dpi); for (col = (width - far - guidesize)/2; col < (width - far + guidesize)/2; ++col) if (col >= 0 && col < width) pnm_assigntuple(outPamP, outrow[col], blackTuple); for (col = (width + far - guidesize)/2; col < (width + far + guidesize)/2; ++col) if (col >= 0 && col < width) pnm_assigntuple(outPamP, outrow[col], blackTuple); writeRowCopies(outPamP,outrow, guidesize); /* Leave some blank rows after the guides. */ makeWhiteRow(outPamP, outrow); writeRowCopies(outPamP, outrow, guidesize); pnm_freerow(outrow); }
static void createRowCutter(const struct pam * const inpamP, const struct pam * const outpamP, int const leftcol, int const rightcol, struct rowCutter ** const rowCutterPP) { struct rowCutter * rowCutterP; tuple * inputPointers; tuple * outputPointers; tuple * copyTuples; tuple blackTuple; tuple discardTuple; int col; assert(inpamP->depth >= outpamP->depth); /* Entry condition. If this weren't true, we could not simply treat an input tuple as an output tuple. */ copyTuples = pnm_allocpamrow(outpamP); discardTuple = pnm_allocpamtuple(inpamP); pnm_createBlackTuple(outpamP, &blackTuple); MALLOCARRAY_NOFAIL(inputPointers, inpamP->width); MALLOCARRAY_NOFAIL(outputPointers, outpamP->width); /* Put in left padding */ for (col = leftcol; col < 0 && col-leftcol < outpamP->width; ++col) outputPointers[col-leftcol] = blackTuple; /* Put in extracted columns */ for (col = MAX(leftcol, 0); col <= MIN(rightcol, inpamP->width-1); ++col) { int const outcol = col - leftcol; inputPointers[col] = outputPointers[outcol] = copyTuples[outcol]; } /* Put in right padding */ for (col = MIN(rightcol, inpamP->width-1) + 1; col <= rightcol; ++col) { if (col - leftcol >= 0) { outputPointers[col-leftcol] = blackTuple; } } /* Direct input pixels that are getting cut off to the discard tuple */ for (col = 0; col < MIN(leftcol, inpamP->width); ++col) inputPointers[col] = discardTuple; for (col = MAX(0, rightcol + 1); col < inpamP->width; ++col) inputPointers[col] = discardTuple; MALLOCVAR_NOFAIL(rowCutterP); rowCutterP->inputWidth = inpamP->width; rowCutterP->outputWidth = outpamP->width; rowCutterP->inputPointers = inputPointers; rowCutterP->outputPointers = outputPointers; rowCutterP->copyTuples = copyTuples; rowCutterP->discardTuple = discardTuple; rowCutterP->blackTuple = blackTuple; *rowCutterPP = rowCutterP; }