static xel background2Corners(FILE * const ifP, int const cols, pixval const maxval, int const format) { /*---------------------------------------------------------------------------- Look at just the top row of pixels and determine the background color from the top corners; often this is enough to accurately determine the background color. Expect the file to be positioned to the start of the raster, and leave it positioned arbitrarily. ----------------------------------------------------------------------------*/ xel *xelrow; xel background; /* our return value */ xelrow = pnm_allocrow(cols); pnm_readpnmrow(ifP, xelrow, cols, maxval, format); background = pnm_backgroundxelrow(xelrow, cols, maxval, format); pnm_freerow(xelrow); return background; }
static void getGenImgInfo(struct imgInfo const img[], unsigned int const nfiles, xel * const newxelrow, unsigned int const newrows, xelval const newmaxval, int const newformat, enum justification const justification, enum backcolor const backcolor, struct imgGen2 ** const img2P) { struct imgGen2 * img2; unsigned int i; MALLOCARRAY_NOFAIL(img2, nfiles); for (i = 0; i < nfiles; ++i) { switch (justification) { /* Determine top padding */ case JUST_MIN: img2[i].padtop = 0; break; case JUST_MAX: img2[i].padtop = newrows - img[i].rows; break; case JUST_CENTER: img2[i].padtop = (newrows - img[i].rows) / 2; break; } img2[i].inrow = (i == 0 ? &newxelrow[0] : img2[i-1].inrow + img[i-1].cols); if (img[i].rows == newrows) /* no padding */ img2[i].xelrow = NULL; else { /* Determine pad color */ switch (backcolor){ case BACK_AUTO: img2[i].xelrow = pnm_allocrow(img[i].cols); pnm_readpnmrow(img[i].ifP, img2[i].xelrow, img[i].cols, img[i].maxval, img[i].format); pnm_promoteformatrow(img2[i].xelrow, img[i].cols, img[i].maxval, img[i].format, newmaxval, newformat); img2[i].background = pnm_backgroundxelrow( img2[i].xelrow, img[i].cols, newmaxval, newformat); break; case BACK_BLACK: img2[i].xelrow = NULL; img2[i].background = pnm_blackxel(newmaxval, newformat); break; case BACK_WHITE: img2[i].xelrow = NULL; img2[i].background = pnm_whitexel(newmaxval, newformat); break; } } } *img2P = img2; }
static xel backgroundColor(const char * const backgroundColorName, xel * const topRow, int const cols, xelval const maxval, int const format) { xel retval; if (backgroundColorName) { retval = pnm_parsecolorxel(backgroundColorName, maxval, format); } else retval = pnm_backgroundxelrow(topRow, cols, maxval, format); return retval; }
int main(int argc, char * argv[]) { FILE* ifp; xel* xelrow; xel* newxelrow; xel bgxel; int rows, cols, format; int newformat, newcols; int row; xelval maxval, newmaxval; double shearfac; struct cmdline_info cmdline; pnm_init( &argc, argv ); parse_command_line( argc, argv, &cmdline ); ifp = pm_openr( cmdline.input_filespec ); pnm_readpnminit( ifp, &cols, &rows, &maxval, &format ); xelrow = pnm_allocrow( cols ); /* Promote PBM files to PGM. */ if ( !cmdline.noantialias && PNM_FORMAT_TYPE(format) == PBM_TYPE ) { newformat = PGM_TYPE; newmaxval = PGM_MAXMAXVAL; pm_message( "promoting from PBM to PGM - " "use -noantialias to avoid this" ); } else { newformat = format; newmaxval = maxval; } shearfac = tan( cmdline.angle ); if ( shearfac < 0.0 ) shearfac = -shearfac; if(rows * shearfac >= INT_MAX-1) pm_error("image too large"); overflow_add(rows * shearfac, cols+1); newcols = rows * shearfac + cols + 0.999999; pnm_writepnminit( stdout, newcols, rows, newmaxval, newformat, 0 ); newxelrow = pnm_allocrow( newcols ); bgxel = pnm_backgroundxelrow( xelrow, cols, newmaxval, format ); for ( row = 0; row < rows; ++row ) { double shearCols; pnm_readpnmrow( ifp, xelrow, cols, newmaxval, format ); if ( cmdline.angle > 0.0 ) shearCols = row * shearfac; else shearCols = ( rows - row ) * shearfac; shear_row(xelrow, cols, newxelrow, newcols, shearCols, format, bgxel, !cmdline.noantialias); pnm_writepnmrow( stdout, newxelrow, newcols, newmaxval, newformat, 0 ); } pm_close( ifp ); pm_close( stdout ); exit( 0 ); }
static void concatenateTopBottomGen(FILE * const ofP, unsigned int const nfiles, int const newcols, int const newrows, xelval const newmaxval, int const newformat, enum justification const justification, struct imgInfo const img[], enum backcolor const backcolor) { xel * const newxelrow = pnm_allocrow(newcols); xel * inrow; unsigned int padleft; unsigned int i; unsigned int row, startRow; xel background, backgroundPrev; bool backChange; /* The background color is different from that of the previous input image. */ switch (backcolor) { case BACK_AUTO: /* do nothing now, determine at start of each image */ break; case BACK_BLACK: background = pnm_blackxel(newmaxval, newformat); break; case BACK_WHITE: background = pnm_whitexel(newmaxval, newformat); break; } for ( i = 0; i < nfiles; ++i, backgroundPrev = background) { if (img[i].cols == newcols) { /* no padding */ startRow = 0; backChange = FALSE; inrow = newxelrow; } else { /* Calculate left padding amount */ switch (justification) { case JUST_MIN: padleft = 0; break; case JUST_MAX: padleft = newcols - img[i].cols; break; case JUST_CENTER: padleft = (newcols - img[i].cols) / 2; break; } if (backcolor == BACK_AUTO) { /* Determine background color */ startRow = 1; inrow = &newxelrow[padleft]; pnm_readpnmrow(img[i].ifP, inrow, img[i].cols, img[i].maxval, img[i].format); pnm_promoteformatrow(inrow, img[i].cols, img[i].maxval, img[i].format, newmaxval, newformat); background = pnm_backgroundxelrow( inrow, img[i].cols, newmaxval, newformat); backChange = i==0 || !PNM_EQUAL(background, backgroundPrev); } else { /* background color is constant: black or white */ startRow = 0; inrow = &newxelrow[padleft]; backChange = (i==0); } if (backChange || (i > 0 && img[i-1].cols > img[i].cols)) { unsigned int col; for (col = 0; col < padleft; ++col) newxelrow[col] = background; for (col = padleft + img[i].cols; col < newcols; ++col) newxelrow[col] = background; } } if (startRow == 1) /* Top row already read for auto background color determination. Write it out. */ pnm_writepnmrow(ofP, newxelrow, newcols, newmaxval, newformat, 0); for (row = startRow; row < img[i].rows; ++row) { pnm_readpnmrow(img[i].ifP, inrow, img[i].cols, img[i].maxval, img[i].format); pnm_promoteformatrow( inrow, img[i].cols, img[i].maxval, img[i].format, newmaxval, newformat); pnm_writepnmrow(ofP, newxelrow, newcols, newmaxval, newformat, 0); } } pnm_freerow(newxelrow); }