Tesseract
3.02
|
#include <img.h>
Public Member Functions | |
IMAGE () | |
~IMAGE () | |
IMAGE & | operator= (IMAGE &source) |
inT8 | create (inT32 x, inT32 y, inT8 bits_per_pixel) |
inT8 | capture (uinT8 *pixels, inT32 x, inT32 y, inT8 bits_per_pixel) |
void | destroy () |
inT32 | get_xsize () |
inT32 | get_ysize () |
inT8 | get_bpp () |
inT8 | get_bps () |
BOOL8 | white_high () |
uinT8 | get_white_level () |
inT32 | get_res () |
void | set_res (inT32 resolution) |
uinT8 * | get_buffer () |
uinT8 | pixel (inT32 x, inT32 y) |
void | fast_get_line (inT32 x, inT32 y, inT32 width, IMAGELINE *linebuf) |
void | get_line (inT32 x, inT32 y, inT32 width, IMAGELINE *linebuf, inT32 margins) |
void | get_column (inT32 x, inT32 y, inT32 height, IMAGELINE *linebuf, inT32 margins) |
void | fast_put_line (inT32 x, inT32 y, inT32 width, IMAGELINE *linebuf) |
void | put_line (inT32 x, inT32 y, inT32 width, IMAGELINE *linebuf, inT32 margins) |
void | put_column (inT32 x, inT32 y, inT32 height, IMAGELINE *linebuf, inT32 margins) |
void | check_legal_access (inT32 x, inT32 y, inT32 xext) |
Pix * | ToPix () |
void | FromPix (const Pix *src_pix) |
void | convolver (inT32 win_width, inT32 win_height, void(*convolve)(uinT8 **pixels, uinT8 bytespp, inT32 win_wd, inT32 win_ht, uinT8 ret_white_value, uinT8 *result)) |
Friends | |
DLLSYM void | copy_sub_image (IMAGE *source, inT32 xstart, inT32 ystart, inT32 xext, inT32 yext, IMAGE *dest, inT32 xdest, inT32 ydest, BOOL8 adjust_grey) |
DLLSYM void | enlarge_sub_image (IMAGE *source, inT32 xstart, inT32 ystart, IMAGE *dest, inT32 xdest, inT32 ydest, inT32 xext, inT32 yext, inT32 scale, BOOL8 adjust_grey) |
DLLSYM void | fast_reduce_sub_image (IMAGE *source, inT32 xstart, inT32 ystart, inT32 xext, inT32 yext, IMAGE *dest, inT32 xdest, inT32 ydest, inT32 scale, BOOL8 adjust_grey) |
DLLSYM void | reduce_sub_image (IMAGE *source, inT32 xstart, inT32 ystart, inT32 xext, inT32 yext, IMAGE *dest, inT32 xdest, inT32 ydest, inT32 scale, BOOL8 adjust_grey) |
IMAGE::IMAGE | ( | ) |
Definition at line 72 of file imgs.cpp.
{ //construct an image bpp = 0; //all illegal fd = -1; image = NULL; photo_interp = 1; res = image_default_resolution; }
IMAGE::~IMAGE | ( | ) | [inline] |
capture raw image
pixels | pixels to capture |
x | x size required |
y | y size required |
bits_per_pixel | bpp required |
Definition at line 170 of file imgs.cpp.
{ destroy(); xdim = check_legal_image_size (x, y, bits_per_pixel); if (xdim < 0) return -1; xsize = x; ysize = y; bufheight = y; bpp = bits_per_pixel; bps = bpp == 24 ? 8 : bpp; photo_interp = 1; bytespp = (bpp + 7) / 8; image = pixels; //assign image area ymin = 0; ymax = bufheight; //read it all captured = TRUE; res = image_default_resolution; return 0; //success }
check coordinates
x | xcoord to check |
y | ycoord to check |
xext | extent |
Definition at line 1483 of file imgs.cpp.
{ 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 < ymin || y >= ymax) BADIMAGESEEK.error ("IMAGE::check_legal_access", ABORT, "(%d,%d)", x, y); }
void IMAGE::convolver | ( | inT32 | win_width, |
inT32 | win_height, | ||
void(*)(uinT8 **pixels, uinT8 bytespp, inT32 win_wd, inT32 win_ht, uinT8 ret_white_value, uinT8 *result) | convolve | ||
) |
Map function over window
win_width | Window width |
win_height | Window height |
convolve | Conv function |
Definition at line 1637 of file imgs.cpp.
{ 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++; } }
create blank image
x | x size required |
y | y size required |
bits_per_pixel | bpp required |
Definition at line 121 of file imgs.cpp.
{ uinT8 *pixels; //memory for image xdim = check_legal_image_size (x, y, bits_per_pixel); if (xdim < 0) return -1; pixels = (uinT8 *) alloc_big_zeros ((size_t) (xdim * y * sizeof (uinT8))); if (pixels == NULL) { MEMORY_OUT.error ("IMAGE::create", ABORT, "Size=(%d,%d)", xdim, y); return -1; } //allocate to image this->capture (pixels, x, y, bits_per_pixel); captured = FALSE; res = image_default_resolution; return 0; //success }
void IMAGE::destroy | ( | ) |
destroy image
Definition at line 150 of file imgs.cpp.
{ //get rid of image if (image != NULL && !captured) { free_big_mem(image); } image = NULL; if (fd >= 0) { close(fd); fd = -1; } bpp = 0; }
get image line
x | coord to start at |
y | line to get |
width | line to get |
linebuf | line to copy to |
Definition at line 977 of file imgs.cpp.
{ if (width > 0 && bpp > 4) { check_legal_access(x, y, width); //get pointer only linebuf->pixels = image + xdim * (ymax - 1 - y) + x * bytespp; } else //just copy it this->get_line (x, y, width, linebuf, 0); linebuf->bpp = bpp; }
void IMAGE::FromPix | ( | const Pix * | src_pix | ) |
Definition at line 1560 of file imgs.cpp.
{ // Leptonica doesn't const its inputs, but we don't change the input. Pix* pix = const_cast<Pix*>(src_pix); Pix* destroy_this_pix = NULL; int depth = pixGetDepth(pix); if (depth > 1 && depth < 8) { // Convert funny depths to 8 bit. destroy_this_pix = pixConvertTo8(pix, false); pix = destroy_this_pix; depth = pixGetDepth(pix); } int width = pixGetWidth(pix); int height = pixGetHeight(pix); const l_uint32* data = pixGetData(pix); this->create(width, height, depth == 32 ? 24 : depth); // For each line in the image, fill the IMAGELINE class and put it into the // destination image. Note that Tesseract stores images with the // bottom at y=0 and 0 is always black in grey and binary. IMAGELINE line; if (depth == 32) { line.init(width * 3); line.set_bpp(24); } else { line.init(width); } switch (depth) { case 1: // Binary images just flip the data bit. for (int y = height - 1 ; y >= 0; --y) { for (int x = 0; x < width; ++x) line.pixels[x] = GET_DATA_BIT((void *)data, x) ^ 1; this->put_line(0, y, width, &line, 0); data += pixGetWpl(pix); } break; case 8: // Greyscale just copies the bytes in the right order. for (int y = height - 1 ; y >= 0; --y) { for (int x = 0; x < width; ++x) line.pixels[x] = GET_DATA_BYTE((void *)data, x); this->put_line(0, y, width, &line, 0); data += pixGetWpl(pix); } break; case 32: // Put the colors in the correct places in the line buffer. for (int y = height - 1 ; y >= 0; --y) { for (int x = 0; x < width; ++x, ++data) { line[x][RED_PIX] = GET_DATA_BYTE((void *)data, COLOR_RED); line[x][GREEN_PIX] = GET_DATA_BYTE((void *)data, COLOR_GREEN); line[x][BLUE_PIX] = GET_DATA_BYTE((void *)data, COLOR_BLUE); } this->put_line(0, y, width, &line, 0); } break; default: tprintf("Cannot convert Pix to image with bpp = %d\n", depth); } if (destroy_this_pix != NULL) pixDestroy(&destroy_this_pix); }
inT8 IMAGE::get_bpp | ( | ) | [inline] |
inT8 IMAGE::get_bps | ( | ) | [inline] |
get image column
x | coord to start at |
y | line to get |
height | number of pixels to get |
linebuf | line to copy to |
margins | size of margins |
Definition at line 1104 of file imgs.cpp.
{ uinT8 *src; //source pointer uinT8 *dest; //destination pointer inT8 bit; //bit index inT8 pixperbyte; //pixels per byte uinT8 white; //white colour inT32 pixel; //pixel index //test coords this->check_legal_access (x, y, 1); //test coords this->check_legal_access (x, y + height - 1, 1); if (height > ysize - y) height = ysize - y; //clip to image linebuf->init (height * bytespp + margins * bytespp * 2); //start of line src = image + xdim * (ymax - 1 - y); dest = linebuf->line; //destination line linebuf->pixels = dest; white = (1 << bpp) - 1; //max value of pixel for (pixel = margins * bytespp; pixel > 0; pixel--) { *dest++ = white; //margins are white } if (height > 0) { if (bpp == 24) { src += x * bytespp; //offset for (; height > 0; --height) { *dest++ = *src; //copy bytes *dest++ = *(src + 1); *dest++ = *(src + 2); src -= xdim; } } else if (bpp > 4) { src += x; for (; height > 0; --height) { *dest++ = *src; //copy bytes src -= xdim; } } else if (bpp == 4) { src += x / 2; //offset on line if (x & 1) { for (; height > 0; --height) { //get coded nibble *dest++ = bpp4table[*src][1]; src -= xdim; } } else { for (; height > 0; --height) { //get coded nibble *dest++ = bpp4table[*src][0]; src -= xdim; } } } else if (bpp == 2) { pixperbyte = 4; src += x / 4; //offset on line bit = (inT8) (x % 4); //offset in byte for (; height > 0; --height) { //get coded bits *dest++ = bpp2table[*src][bit]; src -= xdim; } } else { pixperbyte = 8; src += x / 8; //offset on line bit = (inT8) (x % 8); //offset in byte for (; height > 0; --height) { //get coded bits *dest++ = bpp1table[*src][bit]; src -= xdim; } } } for (pixel = margins * bytespp; pixel > 0; pixel--) { *dest++ = white; //margins are white } }
get image line
x | coord to start at |
y | line to get |
width | line to get |
linebuf | line to copy to |
margins | size of margins |
Definition at line 1002 of file imgs.cpp.
{ uinT8 *src; // source pointer uinT8 *dest; // destination pointer const uinT8 *unpacksrc; // unpacking pointer inT8 bit; // bit index inT8 pixperbyte; // pixels per byte uinT8 white; // white colour inT32 pixel; // pixel index this->check_legal_access (x, y, width); if (width > xsize - x) width = xsize - x; //clip to image width *= bytespp; linebuf->init (width + margins * bytespp * 2); linebuf->bpp = bpp; //start of line src = image + xdim * (ymax - 1 - y); dest = linebuf->line; //destination line linebuf->pixels = dest; white = (1 << bpp) - 1; //max value of pixel for (pixel = margins * bytespp; pixel > 0; pixel--) { *dest++ = white; //margins are white } if (width > 0) { if (bpp > 4) { src += x; //offset //easy way memmove (dest, src, (unsigned) width); } else if (bpp == 4) { src += x / 2; //offset on line if (x & 1) { //get coded nibble *dest++ = bpp4table[*src++][1]; width--; } while (width >= 2) { //get coded bits unpacksrc = bpp4table[*src++]; *dest++ = *unpacksrc++; *dest++ = *unpacksrc++; //copy nibbles width -= 2; } if (width) { //get coded nibble *dest++ = bpp4table[*src++][0]; } } else if (bpp == 2) { pixperbyte = 4; src += x / 4; //offset on line bit = (inT8) (x % 4); //offset in byte width += bit; while (width > 0) { //until all done if (width < pixperbyte) //less on last byte pixperbyte = (inT8) width; //get coded bits unpacksrc = &bpp2table[*src++][bit]; for (; bit < pixperbyte; bit++) *dest++ = *unpacksrc++;//copy bytes width -= pixperbyte; bit = 0; } } else { pixperbyte = 8; src += x / 8; //offset on line bit = (inT8) (x % 8); //offset in byte width += bit; while (width > 0) { //until all done if (width < pixperbyte) //less on last byte pixperbyte = (inT8) width; //get coded bits unpacksrc = &bpp1table[*src++][bit]; for (; bit < pixperbyte; bit++) *dest++ = *unpacksrc++;//copy bytes width -= pixperbyte; bit = 0; } } } for (pixel = margins * bytespp; pixel > 0; pixel--) { *dest++ = white; //margins are white } }
inT32 IMAGE::get_res | ( | ) | [inline] |
uinT8 IMAGE::get_white_level | ( | ) | [inline] |
inT32 IMAGE::get_xsize | ( | ) | [inline] |
inT32 IMAGE::get_ysize | ( | ) | [inline] |
Definition at line 87 of file imgs.cpp.
{ destroy(); bpp = source.bpp; photo_interp = source.photo_interp; bps = source.bps; bytespp = (bpp + 7) / 8; lineskip = source.lineskip; //copy everything captured = source.captured; xsize = source.xsize; ysize = source.ysize; res = source.res; image = source.image; xdim = source.xdim; bufheight = source.bufheight; fd = source.fd; reader = source.reader; ymin = source.ymin; ymax = source.ymax; source.captured = TRUE; //source now captured source.fd = -1; return *this; }
access pixel
x | coord |
y | coord |
Definition at line 202 of file imgs.cpp.
{ if (x < 0) x = 0; //silently clip else if (x >= xsize) x = xsize - 1; if (y < 0) y = 0; else if (y >= ysize) y = ysize - 1; check_legal_access (x, y, 1); switch (bpp) { case 5: case 6: case 8: return image[(ymax - 1 - y) * xdim + x]; case 4: return bpp4table[image[(ymax - 1 - y) * xdim + x / 2]][x & 1]; case 2: return bpp2table[image[(ymax - 1 - y) * xdim + x / 4]][x & 3]; case 1: return bpp1table[image[(ymax - 1 - y) * xdim + x / 8]][x & 7]; default: tprintf ("Unexpected bits per pixel %d\n", bpp); return 0; } }
put image column
x | coord to start at |
y | line to put |
height | number of pixels to put |
linebuf | line to copy to |
margins | size of margins |
Definition at line 1370 of file imgs.cpp.
{ 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; } } }
put image line
x | coord to start at |
y | line to put |
width | number of pixels to put |
linebuf | line to copy from |
margins | size of margins |
Definition at line 1221 of file imgs.cpp.
{ 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 } } }
void IMAGE::set_res | ( | inT32 | resolution | ) | [inline] |
Pix * IMAGE::ToPix | ( | ) |
Methods to convert image types. Only available if Leptonica is available.
Definition at line 1500 of file imgs.cpp.
{ int width = this->get_xsize(); int height = this->get_ysize(); int bpp = this->get_bpp(); Pix* pix = pixCreate(width, height, bpp == 24 ? 32 : bpp); l_uint32* data = pixGetData(pix); IMAGELINE line; if (bpp == 24) { line.init(width * 3); line.set_bpp(24); } else { line.init(width); } switch (bpp) { case 1: for (int y = height - 1 ; y >= 0; --y) { this->get_line(0, y, width, &line, 0); for (int x = 0; x < width; ++x) { if (line.pixels[x]) CLEAR_DATA_BIT(data, x); else SET_DATA_BIT(data, x); } data += pixGetWpl(pix); } break; case 8: // Greyscale just copies the bytes in the right order. for (int y = height - 1 ; y >= 0; --y) { this->get_line(0, y, width, &line, 0); for (int x = 0; x < width; ++x) SET_DATA_BYTE(data, x, line.pixels[x]); data += pixGetWpl(pix); } break; case 24: // Put the colors in the correct places in the line buffer. for (int y = height - 1 ; y >= 0; --y) { this->get_line(0, y, width, &line, 0); for (int x = 0; x < width; ++x, ++data) { SET_DATA_BYTE(data, COLOR_RED, line[x][RED_PIX]); SET_DATA_BYTE(data, COLOR_GREEN, line[x][GREEN_PIX]); SET_DATA_BYTE(data, COLOR_BLUE, line[x][BLUE_PIX]); } } break; default: tprintf("Cannot convert image to Pix with bpp = %d\n", bpp); } return pix; }
BOOL8 IMAGE::white_high | ( | ) | [inline] |
DLLSYM void copy_sub_image | ( | IMAGE * | source, |
inT32 | xstart, | ||
inT32 | ystart, | ||
inT32 | xext, | ||
inT32 | yext, | ||
IMAGE * | dest, | ||
inT32 | xdest, | ||
inT32 | ydest, | ||
BOOL8 | adjust_grey | ||
) | [friend] |
Definition at line 269 of file imgs.cpp.
{ IMAGELINE copyline; //copy of line uinT8 *copy; //source pointer inT8 shift; //shift factor inT32 pixel; //pixel index inT32 y; //line index inT32 yoffset; //current adjusted offset inT32 bytesize; //no of bytes to copy inT32 srcppb; //pixels per byte BOOL8 aligned; 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) xext = dest->xsize - xdest; 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) yext = dest->ysize - ydest; if (xext <= 0 || yext <= 0) return; //nothing to do srcppb = 8 / source->bpp; //pixels per byte if (source->bpp == dest->bpp || !adjust_grey) shift = 0; //no adjustment else { shift = source->bps - dest->bps; if (shift < 0) shift = -shift; //keep positive } aligned = source->bpp == dest->bpp; if (aligned && srcppb != 0) { aligned = xstart % srcppb == 0 && xdest % srcppb == 0 && (xext % srcppb == 0 || xdest + xext == dest->xsize); } for (y = 0; y < yext; y++) { if (ystart >= ydest) yoffset = y; //top down else yoffset = yext - y - 1; //bottom up source->check_legal_access (xstart, ystart + yoffset, xext); dest->check_legal_access (xdest, ydest + yoffset, xext); if (aligned) { bytesize = COMPUTE_IMAGE_XDIM (xext, source->bpp); //get bytes per line if (srcppb == 0) //do cheap move memmove (dest->image + (dest->ymax - 1 - ydest - yoffset) * dest->xdim + xdest * 3, source->image + (source->ymax - 1 - ystart - yoffset) * source->xdim + xstart * 3, (unsigned) bytesize); else //do cheap move memmove (dest->image + (dest->ymax - 1 - ydest - yoffset) * dest->xdim + xdest / srcppb, source->image + (source->ymax - 1 - ystart - yoffset) * source->xdim + xstart / srcppb, (unsigned) bytesize); } else { if (shift == 0) { source->fast_get_line (xstart, ystart + yoffset, xext, ©line); } else if (source->bpp < dest->bpp) { source->get_line (xstart, ystart + yoffset, xext, ©line, 0); if (source->bpp <= shift && (source->bpp == 1 || source->bpp == 4)) { if (source->bpp == 1) { for (pixel = 0, copy = copyline.pixels; pixel < xext; pixel++, copy++) if (*copy) *copy = 0xff; } else { for (pixel = 0, copy = copyline.pixels; pixel < xext; pixel++, copy++) //scale up *copy = (*copy << shift) | *copy; } } else { for (pixel = 0, copy = copyline.pixels; pixel < xext; pixel++) *copy++ <<= shift; //scale up } } else { source->get_line (xstart, ystart + yoffset, xext, ©line, 0); if (source->bpp == 24) { for (pixel = 0, copy = copyline.pixels + 1; pixel < xext; pixel++) { *copy >>= shift; copy += 3; } } else { for (pixel = 0, copy = copyline.pixels; pixel < xext; pixel++) *copy++ >>= shift; //scale down } } dest->put_line (xdest, ydest + yoffset, xext, ©line, 0); } } }
DLLSYM void enlarge_sub_image | ( | IMAGE * | source, |
inT32 | xstart, | ||
inT32 | ystart, | ||
IMAGE * | dest, | ||
inT32 | xdest, | ||
inT32 | ydest, | ||
inT32 | xext, | ||
inT32 | yext, | ||
inT32 | scale, | ||
BOOL8 | adjust_grey | ||
) | [friend] |
Definition at line 397 of file imgs.cpp.
{ inT8 shift; //shift factor uinT8 pixel; //current pixel inT32 srcext; //source extent inT32 xoffset; //column index inT32 yoffset; //line index inT32 xindex, yindex; //index in super pixel inT32 startxindex; //initial x index inT32 xscale; //x scale factor 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; } }
DLLSYM void fast_reduce_sub_image | ( | IMAGE * | source, |
inT32 | xstart, | ||
inT32 | ystart, | ||
inT32 | xext, | ||
inT32 | yext, | ||
IMAGE * | dest, | ||
inT32 | xdest, | ||
inT32 | ydest, | ||
inT32 | scale, | ||
BOOL8 | adjust_grey | ||
) | [friend] |
Definition at line 515 of file imgs.cpp.
{ 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; }
DLLSYM void reduce_sub_image | ( | IMAGE * | source, |
inT32 | xstart, | ||
inT32 | ystart, | ||
inT32 | xext, | ||
inT32 | yext, | ||
IMAGE * | dest, | ||
inT32 | xdest, | ||
inT32 | ydest, | ||
inT32 | scale, | ||
BOOL8 | adjust_grey | ||
) | [friend] |
Definition at line 657 of file imgs.cpp.
{ 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; }