📄 imgs.cpp
字号:
INT32 margins //margins in buffer ) { UINT8 *src; //source pointer UINT8 *dest; //destination pointer INT8 bit; //bit index UINT8 pixel; //collected bits INT8 pixperbyte; //pixels in a byte INT8 bytesperpix; //in source this->check_legal_access (x, y, width); if (width > xsize - x) width = xsize - x; //clip to image if (width <= 0) return; //nothing to do //source line src = linebuf->pixels + margins; //start of line dest = image + xdim * (ymax - 1 - y); if (linebuf->bpp == 24) { src++; bytesperpix = 3; } else bytesperpix = 1; if (bpp == 24 && linebuf->bpp == 24) { dest += x * bytespp; width *= bytespp; memmove (dest, src - 1, (unsigned) width); } else if (bpp == 24) { src--; dest += x * bytespp; while (width > 0) { pixel = *src++; *dest++ = pixel; *dest++ = pixel; *dest++ = pixel; width--; } } else if (bpp > 4) { dest += x; //offset if (linebuf->bpp == 24) { while (width > 0) { *dest++ = *src; src += 3; width--; } } else //easy way memmove (dest, src, (unsigned) width); } else if (bpp == 4) { dest += x / 2; //offset on line if (x & 1) { *dest &= 0xf0; //clean odd byte *dest++ |= *src & 0x0f; //and copy it src += bytesperpix; width--; } while (width >= 2) { pixel = *src << 4; //left pixel src += bytesperpix; pixel |= *src & 0x0f; //right pixel src += bytesperpix; *dest++ = pixel; width -= 2; } if (width) { *dest &= 0x0f; //clean odd byte *dest |= *src << 4; } } else if (bpp == 2) { pixperbyte = 4; dest += x / 4; //offset on line bit = (INT8) (x % 4); //offset in byte width += bit; pixel = *dest >> (8 - bit - bit); while (width >= 4) { //until all done for (; bit < 4; bit++) { pixel <<= 2; //make space for new one pixel |= *src & 3; src += bytesperpix; } *dest++ = pixel; //new pixel width -= 4; bit = 0; } if (width > 0) { //until all done for (bit = 0; bit < width; bit++) { pixel <<= 2; //make space for new one pixel |= *src & 3; src += bytesperpix; } pixel <<= (8 - bit - bit); //shift rest //keep trainling bits pixel |= *dest & ((1 << (8 - bit - bit)) - 1); *dest++ = pixel; //new pixel } } else { pixperbyte = 8; dest += x / 8; //offset on line bit = (INT8) (x % 8); //offset in byte width += bit; pixel = *dest >> (8 - bit); while (width >= 8) { //until all done for (; bit < 8; bit++) { pixel <<= 1; //make space for new one pixel |= *src & 1; src += bytesperpix; } *dest++ = pixel; //new pixel width -= 8; bit = 0; } width -= bit; if (width > 0) { //until all done while (width > 0) { pixel <<= 1; //make space for new one pixel |= *src & 1; src += bytesperpix; bit++; width--; } pixel <<= (8 - bit); //shift rest //keep trainling bits pixel |= *dest & ((1 << (8 - bit)) - 1); *dest++ = pixel; //new pixel } }}/********************************************************************** * put_column * * Put the supplied column buffer into the image. * The image is converted from 8bpp by simple assignment. **********************************************************************/void IMAGE::put_column( //put image column INT32 x, //coord to start at INT32 y, //line to get INT32 height, //no of pixels to get IMAGELINE *linebuf, //line to copy to INT32 margins //margins in buffer ) { UINT8 *src; //source pointer UINT8 *dest; //destination pointer INT8 bit; //bit index UINT8 pixel; //collected bits INT8 bytesperpix; //in source this->check_legal_access (x, y, 1); this->check_legal_access (x, y + height - 1, 1); if (height > ysize - y) height = ysize - y; //clip to image if (height <= 0) return; //nothing to do //source line src = linebuf->pixels + margins; //start of line dest = image + xdim * (ymax - 1 - y); if (linebuf->bpp == 24) { src++; bytesperpix = 3; } else bytesperpix = 1; if (bpp == 24 && linebuf->bpp == 24) { dest += x * bytesperpix; src--; for (; height > 0; --height) { *dest = *src++; *(dest + 1) = *src++; *(dest + 2) = *src++; dest -= xdim; } } else if (bpp == 24) { src--; dest += x * bytesperpix; for (; height > 0; --height) { pixel = *src++; *dest = pixel; *(dest + 1) = pixel; *(dest + 2) = pixel; dest -= xdim; } } else if (bpp > 4) { dest += x; //offset for (; height > 0; --height) { *dest = *src; src += bytesperpix; dest -= xdim; } } else if (bpp == 4) { dest += x / 2; //offset on line if (x & 1) { for (; height > 0; --height) { *dest &= 0xf0; //clean odd byte *dest |= *src & 0x0f; //and copy it src += bytesperpix; dest -= xdim; } } else { for (; height > 0; --height) { *dest &= 0x0f; //clean odd byte *dest |= *src << 4; src += bytesperpix; dest -= xdim; } } } else if (bpp == 2) { dest += x / 4; //offset on line bit = (INT8) (x % 4); //offset in byte bit = 6 - bit - bit; //bit shift pixel = ~(3 << bit); //mask for (; height > 0; --height) { //change 2 bits *dest = (*dest & pixel) | ((*src & 3) << bit); src += bytesperpix; dest -= xdim; } } else { dest += x / 8; //offset on line bit = (INT8) (x % 8); //offset in byte bit = 7 - bit; pixel = ~(1 << bit); for (; height > 0; --height) { //change 1 bit *dest = (*dest & pixel) | ((*src & 1) << bit); src += bytesperpix; dest -= xdim; } }}/********************************************************************** * check_legal_access * * Check that x,y are within the bounds of the image. * Call bufread if necessary to get the image into memory. **********************************************************************/void IMAGE::check_legal_access( //check coords are legal INT32 x, //coords to check INT32 y, INT32 xext //xextent ) { if (x < 0 || x >= xsize || y < 0 || y >= ysize || x + xext > xsize) BADIMAGECOORDS.error ("IMAGE::check_legal_access", ABORT, "(%d+%d,%d)", x, xext, y); if (y >= ymax) BADIMAGESEEK.error ("IMAGE::check_legal_access", ABORT, "(%d,%d)", x, y); if (y < ymin) bufread(y); //read some more}/************************************************************************* * convolver() * * Calls the specified function for each pixel in the image, passing in an m x n * window of the image, centred on the pixel. The convolution function returns * a new value for the pixel, based on the window. * * At the edges of the image, the window is padded to white pixels. *************************************************************************/voidIMAGE::convolver ( //Map fn over windowINT32 win_width, //Window widthINT32 win_height, //Window heightvoid (*convolve) ( //Conv FunctionUINT8 ** pixels, //Of windowUINT8 bytespp, //1 or 3 for colourINT32 win_wd, //Window widthINT32 win_ht, //Window heightUINT8 ret_white_value, //White value to RETURNUINT8 * result) //Ptr to result pix) { IMAGELINE new_row; //Replacement pixels IMAGELINE *old_rows; //Rows being processed INT32 oldest_imline; //Next imline to replace UINT8 **window; //ptrs to pixel rows UINT8 **winmax; //ptrs to pixel rows UINT8 **win; //ptrs to pixel rows INT32 current_row; //Row being calculated INT32 current_col; //Col being calculated INT32 row = 0; //Next row to get INT32 i, j; UINT8 *pix; UINT8 *max; INT32 xmargin = win_width / 2; INT32 ymargin = win_height / 2; UINT8 white = get_white_level (); const UINT8 max_white = 255; float white_scale = (float) 255 / get_white_level (); if (((win_width % 2) == 0) || ((win_height % 2) == 0) || (win_height < 3) || (win_width < 3) || (win_height > ysize / 2) || (win_width > xsize / 2)) BADWINDOW.error ("IMAGE::convolver", ABORT, "(%d x %d)", win_width, win_height); new_row.init (xsize * bytespp); new_row.set_bpp (bpp); old_rows = new IMAGELINE[win_height]; for (i = 0; i < win_height; i++) { old_rows[i].init ((xsize + 2 * xmargin) * bytespp); old_rows[i].set_bpp (bpp); } window = (UINT8 **) alloc_mem (win_height * sizeof (UINT8 *)); winmax = window + win_height; /* Make bottom border */ for (oldest_imline = 0; oldest_imline < ymargin; oldest_imline++) { pix = old_rows[oldest_imline].pixels; max = pix + (xsize + 2 * xmargin) * bytespp; while (pix < max) *pix++ = max_white; } /* Initialise remaining rows but one*/ for (; oldest_imline < win_height - 1; oldest_imline++) { get_line (0, row++, xsize, &old_rows[oldest_imline], xmargin); if (max_white != white) { pix = old_rows[oldest_imline].pixels; max = pix + (xsize + 2 * xmargin) * bytespp; while (pix < max) { *pix = (UINT8) (*pix * white_scale); ++pix; } } } /* Image Processing */ for (current_row = 0; current_row < ysize;) { /* Get next row and re-initialise window array */ if (row < ysize) { get_line (0, row++, xsize, &old_rows[oldest_imline], xmargin); if (max_white != white) { pix = old_rows[oldest_imline].pixels; max = pix + (xsize + 2 * xmargin) * bytespp; while (pix < max) { *pix = (UINT8) (*pix * white_scale); ++pix; } } } else { pix = old_rows[oldest_imline].pixels; max = pix + (xsize + 2 * xmargin) * bytespp; while (pix < max) *pix++ = max_white; } oldest_imline++; if (oldest_imline >= win_height) oldest_imline = 0; /* Process line */ pix = new_row.pixels; for (current_col = 0; current_col < xsize;) { /* Set up window ptrs */ if (current_col == 0) { j = oldest_imline; for (i = 0; i < win_height; i++) { window[i] = old_rows[j++].pixels; if (j >= win_height) j = 0; } } else { for (win = window; win < winmax; (*win++) += bytespp); //Move along rows } convolve(window, bytespp, win_width, win_height, white, pix); pix += bytespp; current_col++; } put_line (0, current_row, xsize, &new_row, 0); new_row.init (); new_row.set_bpp (bpp); current_row++; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -