📄 imgs.cpp
字号:
UINT8 *src; //source pixels UINT8 *destpix; //dest pixels IMAGELINE copyline; //copy of line IMAGELINE bigline; //expanded line if (xstart < 0 || ystart < 0 || xdest < 0 || ydest < 0) return; if (xext <= 0) xext = dest->xsize; //default to all if (xext > source->xsize * scale - xstart) //clip to smallest xext = source->xsize * scale - xstart; if (xext > dest->xsize - xdest) xext = dest->xsize - xdest; if (yext <= 0) yext = dest->ysize; //default to all if (yext > source->ysize * scale - ystart) yext = source->ysize * scale - ystart; if (yext > dest->ysize - ydest) yext = dest->ysize - ydest; if (xext <= 0 || yext <= 0) return; //nothing to do xindex = xstart % scale; //offset in super pixel startxindex = xindex; yindex = ystart % scale; //no of source pixels srcext = (xext + xindex + scale - 1) / scale; xstart /= scale; //actual start ystart /= scale; if (adjust_grey) { shift = dest->bps - source->bps; } else shift = 0; //no adjustment bigline.init (xext * 3); bigline.bpp = dest->bpp == 24 ? source->bpp : dest->bpp; for (yoffset = 0; yoffset < yext; ystart++) { source->check_legal_access (xstart, ystart, srcext); dest->check_legal_access (xdest, ydest + yoffset, xext); source->fast_get_line (xstart, ystart, srcext, ©line); src = copyline.pixels; destpix = bigline.pixels; xscale = scale; //enlargement factor if (source->bpp == 24 && dest->bpp == 24) { for (xoffset = 0, xindex = startxindex; xoffset < xext; src += source->bytespp) { xoffset += xscale - xindex; if (xoffset > xext) xscale -= xoffset - xext; for (; xindex < xscale; xindex++) { *destpix++ = *src; *destpix++ = *(src + 1); *destpix++ = *(src + 2); } xindex = 0; } } else { if (source->bpp == 24) src++; for (xoffset = 0, xindex = startxindex; xoffset < xext; src += source->bytespp) { xoffset += xscale - xindex; if (xoffset > xext) //clip to dest limit xscale -= xoffset - xext; if (shift == 0) pixel = *src; else if (shift > 0) pixel = *src << shift; else pixel = *src >> (-shift); for (; xindex < xscale; xindex++) *destpix++ = pixel; //duplicate pixel xindex = 0; } } for (; yoffset < yext && yindex < scale; yindex++, yoffset++) { dest->put_line (xdest, ydest + yoffset, xext, &bigline, 0); } yindex = 0; }}/********************************************************************** * fast_reduce_sub_image * * Reduce a portion of one image to a portion of another image. * If the bpps are different, the position of the most significant * bit is preserved. * This is a fast but dirty version, which simply sub-samples. * It does not smooth as it reduces. **********************************************************************/DLLSYM void fast_reduce_sub_image( //reduce rectangle IMAGE *source, //source image INT32 xstart, //start coords INT32 ystart, INT32 xext, //extent to copy INT32 yext, IMAGE *dest, //destination image INT32 xdest, //destination coords INT32 ydest, INT32 scale, //reduction factor BOOL8 adjust_grey //shift to new bpp ) { INT8 shift; //shift factor INT32 xfactor; //run on x coord INT32 divisor; //total cell area INT32 xindex, yindex; //into averaging square INT32 xcoord; //current x coord INT32 destext; //destination size INT32 yoffset; //current adjusted offset UINT8 *pixel; //ptr to source pixels INT32 *sums; //ptr to sums array IMAGELINE copyline; //copy of line INT32 *linesums; //averaging sums if (xstart < 0 || ystart < 0 || xdest < 0 || ydest < 0) return; if (xext <= 0) xext = source->xsize; //default to all if (xext > source->xsize - xstart) //clip to smallest xext = source->xsize - xstart; if (xext > (dest->xsize - xdest) * scale) xext = (dest->xsize - xdest) * scale; if (yext <= 0) yext = source->ysize; //default to all if (yext > source->ysize - ystart) //clip to smallest yext = source->ysize - ystart; if (yext > (dest->ysize - ydest) * scale) yext = (dest->ysize - ydest) * scale; if (xext <= 0 || yext <= 0) return; //nothing to do xfactor = xext % scale; //left overs if (xfactor == 0) xfactor = scale; //destination pixels destext = (xext + scale - 1) / scale; if (adjust_grey) //shift factor shift = dest->bps - source->bps; else shift = 0; //no adjustment linesums = new INT32[destext * source->bytespp]; for (yoffset = 0; yoffset < yext; ydest++) { source->check_legal_access (xstart, ystart + yoffset, xext); dest->check_legal_access (xdest, ydest, destext); for (xindex = destext * source->bytespp - 1; xindex >= 0; xindex--) linesums[xindex] = 0; //zero sums for (yindex = 0; yindex < scale && ystart + yoffset < source->ysize; yindex += 3) { source->fast_get_line (xstart, ystart + yoffset, xext, ©line); pixel = copyline.pixels; //start of line if (source->bpp == 24) { for (xcoord = 1, sums = linesums; xcoord < destext; xcoord++, sums += 3) { for (xindex = 0; xindex < scale; xindex += 2) { *sums += *pixel++; *(sums + 1) += *pixel++; *(sums + 2) += *pixel++; pixel += 3; } if (scale & 1) pixel -= 3; //correct position } for (xindex = 0; xindex < xfactor; xindex += 2) { *sums += *pixel++; *(sums + 1) += *pixel++; *(sums + 2) += *pixel++; pixel += 3; } } else { for (xcoord = 1, sums = linesums; xcoord < destext; xcoord++, sums++) { for (xindex = 0; xindex < scale; xindex += 2) { *sums += *pixel; pixel += 2; } if (scale & 1) pixel--; //correct position } for (xindex = 0; xindex < xfactor; xindex += 2) { *sums += *pixel; pixel += 2; } } yoffset += 3; //every 3 lines } if (yindex > scale) yoffset -= yindex - scale; //back on right scale copyline.init (); //set pixels back to array copyline.bpp = source->bpp; pixel = copyline.pixels; //pixels in block divisor = ((yindex + 2) / 3) * ((scale + 1) / 2); if (shift <= 0) { divisor <<= (-shift); //do greyscale correction for (sums = linesums, xindex = (destext - 1) * source->bytespp; xindex > 0; xindex--) //turn to destination value *pixel++ = (UINT8) (*sums++ / divisor); for (xindex = source->bytespp; xindex > 0; xindex--) *pixel++ = *sums++ / (((yindex + 2) / 3) * ((xfactor + 1) / 2) << (-shift)); //lastone different } else { for (sums = linesums, xindex = (destext - 1) * source->bytespp; xindex > 0; xindex--) *pixel++ = (UINT8) ((*sums++ << shift) / divisor); //destination value for (xindex = source->bytespp; xindex > 0; xindex--) //last one different *pixel++ = (*(sums++) << shift) / (((yindex + 2) / 3) * ((xfactor + 1) / 2)); } //put in destination dest->put_line (xdest, ydest, destext, ©line, 0); } delete linesums;}/********************************************************************** * reduce_sub_image * * Reduce a portion of one image to a portion of another image. * If the bpps are different, the position of the most significant * bit is preserved. **********************************************************************/DLLSYM void reduce_sub_image( //reduce rectangle IMAGE *source, //source image INT32 xstart, //start coords INT32 ystart, INT32 xext, //extent to copy INT32 yext, IMAGE *dest, //destination image INT32 xdest, //destination coords INT32 ydest, INT32 scale, //reduction factor BOOL8 adjust_grey //shift to new bpp ) { INT8 shift; //shift factor INT32 xfactor; //run on x coord INT32 divisor; //total cell area INT32 div2; //total cell area divided by 2 INT32 xindex, yindex; //into averaging square INT32 xcoord; //current x coord INT32 destext; //destination size INT32 yoffset; //current adjusted offset UINT8 *pixel; //ptr to source pixels INT32 *sums; //ptr to sums array IMAGELINE copyline; //copy of line INT32 *linesums; //averaging sums if (xstart < 0 || ystart < 0 || xdest < 0 || ydest < 0) return; if (xext <= 0) xext = source->xsize; //default to all if (xext > source->xsize - xstart) //clip to smallest xext = source->xsize - xstart; if (xext > (dest->xsize - xdest) * scale) xext = (dest->xsize - xdest) * scale; if (yext <= 0) yext = source->ysize; //default to all if (yext > source->ysize - ystart) //clip to smallest yext = source->ysize - ystart; if (yext > (dest->ysize - ydest) * scale) yext = (dest->ysize - ydest) * scale; if (xext <= 0 || yext <= 0) return; //nothing to do xfactor = xext % scale; //left overs if (xfactor == 0) xfactor = scale; //destination pixels destext = (xext + scale - 1) / scale; if (adjust_grey) //shift factor shift = dest->bps - source->bps; else shift = 0; //no adjustment linesums = new INT32[destext * source->bytespp]; for (yoffset = 0; yoffset < yext; ydest++) { source->check_legal_access (xstart, ystart + yoffset, xext); dest->check_legal_access (xdest, ydest, destext); for (xindex = 0; xindex < (destext) * source->bytespp; xindex++) linesums[xindex] = 0; //zero sums for (yindex = 0; yindex < scale && ystart + yoffset < source->ysize; yindex++) { source->fast_get_line (xstart, ystart + yoffset, xext, ©line); pixel = copyline.pixels; //start of line if (source->bpp == 24) { for (xcoord = 1, sums = linesums; xcoord < destext; xcoord++, sums += 3) { for (xindex = 0; xindex < scale; xindex++) { *sums += *pixel++; *(sums + 1) += *pixel++; *(sums + 2) += *pixel++; } } for (xindex = 0; xindex < xfactor; xindex++) { *sums += *pixel++; *(sums + 1) += *pixel++; *(sums + 2) += *pixel++; } } else { for (xcoord = 1, sums = linesums; xcoord < destext; xcoord++, sums++) { for (xindex = 0; xindex < scale; xindex++) *sums += *pixel++; } for (xindex = 0; xindex < xfactor; xindex++) *sums += *pixel++; } yoffset++; //next line } copyline.init (); //set pixels back to array copyline.set_bpp (source->bpp); pixel = copyline.pixels; divisor = yindex * scale; if (divisor == 0) { tprintf ("Impossible:divisor=0!, yindex=%d, scale=%d, yoffset=%d,yext=%d\n", yindex, scale, yoffset, yext); break; } if (shift <= 0) { divisor <<= (-shift); //do greyscale correction div2 = divisor / 2; for (sums = linesums, xindex = (destext - 1) * source->bytespp; xindex > 0; xindex--) *pixel++ = (UINT8) ((div2 + *sums++) / divisor); //turn to destination value div2 = (yindex * xfactor << (-shift)) / 2; for (xindex = source->bytespp; xindex > 0; xindex--) *pixel++ = (UINT8) ((div2 + *sums++) / (yindex * xfactor << (-shift))); //lastone different } else { div2 = divisor / 2; for (sums = linesums, xindex = (destext - 1) * source->bytespp; xindex > 0; xindex--) *pixel++ = (UINT8) ((div2 + (*sums++ << shift)) / divisor); //destination value div2 = (yindex * xfactor) / 2; for (xindex = source->bytespp; xindex > 0; xindex--) *pixel++ = (UINT8) ((div2 + (*sums++ << shift)) / (yindex * xfactor)); //last one different } //put in destination dest->put_line (xdest, ydest, destext, ©line, 0); } delete linesums;}/********************************************************************** * invert_image * * Invert the given image (the slow way.) **********************************************************************/DLLSYM void invert_image( /*invert the image */ IMAGE *image /*image ot invert */ ) { UINT8 mask; //bit mask UINT8 bytespp; //bytes per pixel INT32 xsize, ysize; /*size of image */ INT32 xindex, yindex; /*index into image */ UINT8 *pixel; /*current pixel */ IMAGELINE line; /*line of image */ bytespp = image->get_bpp () == 24 ? 3 : 1; xsize = image->get_xsize (); /*find sizes */ ysize = image->get_ysize (); //pixel mask mask = (1 << image->get_bpp ()) - 1; /*do each line */ for (yindex = ysize - 1; yindex >= 0; yindex--) { image->fast_get_line (0, yindex, xsize, &line); for (pixel = line.pixels, xindex = xsize * bytespp; xindex > 0; xindex--) { *pixel = (*pixel) ^ mask; //invert image only ++pixel; } /*put it back */ image->fast_put_line (0, yindex, xsize, &line); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -