| |
| |
| #include "tscannerutil.h" |
| |
| #ifdef LINUX |
| #include <cstring> |
| #endif |
| |
| #define BUFBYTE(X, Y, BUF, BYTEWRAP, BITOFFS) \ |
| (((UCHAR *)(BUF))[(((X) + (BITOFFS)) >> 3) + (Y) * (BYTEWRAP)]) |
| |
| #define GET_BIT(X, Y, BUF, BYTEWRAP, BITOFFS) \ |
| ((BUFBYTE(X, Y, BUF, BYTEWRAP, BITOFFS) >> (7 - (((X) + (BITOFFS)) & 7))) & (UCHAR)1) |
| |
| namespace TScannerUtil |
| { |
| |
| struct EP { |
| unsigned char r, g, b; |
| }; |
| |
| |
| |
| void copyRGBBufferToTRaster32(unsigned char *rgbBuffer, |
| int rgbLx, int rgbLy, |
| const TRaster32P &rout, bool internal) |
| { |
| if (internal) { |
| TPixelRGBM32 *dst = rout->pixels(); |
| EP *src = (EP *)(rgbBuffer + (rgbLx * rgbLy - 1) * 3); |
| const int w = rout->getWrap(); |
| |
| for (int x = 0; x < rout->getLx(); ++x) { |
| dst = rout->pixels() + x; |
| for (int y = 0; y < rout->getLy(); ++y) { |
| dst->r = src->r; |
| dst->g = src->g; |
| dst->b = src->b; |
| dst->m = 0xff; |
| dst += w; |
| --src; |
| } |
| } |
| } else { |
| unsigned char *index = rgbBuffer; |
| unsigned char *end = index + (rgbLx * rgbLy * 3); |
| TPixel32 *outPix = rout->pixels(); |
| while (index < end) { |
| outPix->r = (int)*index; |
| index++; |
| outPix->g = (int)*index; |
| index++; |
| outPix->b = (int)*index; |
| index++; |
| outPix->m = 255; |
| outPix++; |
| } |
| rout->yMirror(); |
| } |
| } |
| |
| |
| |
| void copyRGBBufferToTRasterGR8(unsigned char *rgbBuffer, int rgbLx, int rgbLy, int rgbWrap, |
| const TRasterGR8P &rout) |
| { |
| TPixelGR8 *dst = rout->pixels(); |
| EP *src = (EP *)(rgbBuffer + (rgbLx * rgbLy - 1) * 3); |
| const int w = rout->getWrap(); |
| |
| for (int x = 0; x < rout->getLx(); ++x) { |
| dst = rout->pixels() + x; |
| for (int y = 0; y < rout->getLy(); ++y) { |
| *dst = TPixelGR8::from(TPixelRGBM32(src->r, src->g, src->b)); |
| dst += w; |
| --src; |
| } |
| } |
| } |
| |
| |
| |
| void copyGR8BufferToTRasterGR8(unsigned char *gr8Buffer, |
| int rgbLx, int rgbLy, |
| const TRasterGR8P &rout, bool internal) |
| { |
| if (internal) { |
| unsigned char *dst = rout->getRawData(); |
| unsigned char *src = (gr8Buffer + rgbLx * rgbLy - 1); |
| const int w = rout->getWrap(); |
| |
| for (int x = 0; x < rout->getLx(); ++x) { |
| dst = rout->getRawData() + x; |
| for (int y = 0; y < rout->getLy(); ++y) { |
| *dst = (*src); |
| dst += w; |
| --src; |
| } |
| } |
| } else { |
| memcpy(rout->getRawData(), gr8Buffer, rgbLx * rgbLy); |
| rout->yMirror(); |
| } |
| } |
| |
| |
| |
| void copyGR8BufferToTRasterBW(unsigned char *gr8Buffer, |
| int rgbLx, int rgbLy, |
| const TRasterGR8P &rout, bool internal, float thres) |
| { |
| if (internal) { |
| unsigned char *dst = rout->getRawData(); |
| unsigned char *src = (gr8Buffer + rgbLx * rgbLy - 1); |
| const int w = rout->getWrap(); |
| |
| for (int x = 0; x < rout->getLx(); ++x) { |
| dst = rout->getRawData() + x; |
| for (int y = 0; y < rout->getLy(); ++y) { |
| if (*src < thres) |
| *dst = 0; |
| else |
| *dst = 255; |
| dst += w; |
| --src; |
| } |
| } |
| } else { |
| memcpy(rout->getRawData(), gr8Buffer, rgbLx * rgbLy); |
| rout->yMirror(); |
| } |
| } |
| |
| |
| |
| void copyBWBufferToTRasterGR8(const unsigned char *buffer, |
| int rgbLx, int rgbLy, |
| const TRasterGR8P &rout, bool isBW, bool internal) |
| { |
| if (0) |
| assert(0); |
| else { |
| int i = 0; |
| UCHAR *pix = rout->getRawData(); |
| const unsigned char *byte; |
| while (i < rgbLx * rgbLy) { |
| int bytePos = i / 8; |
| int bitPos = i % 8; |
| byte = buffer + bytePos; |
| bool bit = (*byte) >> (7 - bitPos); |
| if (isBW) |
| *pix = (bit ? 255 : 0); |
| else |
| *pix = (bit ? 0 : 255); |
| |
| pix++; |
| i++; |
| } |
| rout->yMirror(); |
| } |
| } |
| |
| |
| |
| void copy90BWBufferToRasGR8(unsigned char *bwBuffer, int bwLx, int bwLy, int bwWrap, bool isBW, |
| TRasterGR8P &rout, int mirror, int ninety) |
| { |
| int x1 = 0; |
| int y1 = 0; |
| int x2 = bwLx - 1; |
| int y2 = bwLy - 1; |
| int newx = 0; |
| int newy = 0; |
| |
| UCHAR *bufin, *bufout, *byteout; |
| int bytewrapin, bitoffsin, wrapout; |
| int value_for_0, value_for_1; |
| int u, v, lu, lv, su, sv, u00, v00, u0, v0, dudy, dvdy, dudx, dvdx; |
| int x, y, lx, ly; |
| int u1, v1, u2, v2; |
| |
| mirror &= 1; |
| ninety &= 3; |
| |
| if (!ninety && !mirror) { |
| assert(0); |
| return; |
| } |
| |
| if (isBW) { |
| value_for_0 = 0; |
| value_for_1 = 255; |
| } else { |
| value_for_0 = 255; |
| value_for_1 = 0; |
| } |
| |
| u1 = x1; |
| v1 = y1; |
| u2 = x2; |
| v2 = y2; |
| |
| su = u2 - u1; |
| sv = v2 - v1; |
| lu = u2 - u1 + 1; |
| lv = v2 - v1 + 1; |
| |
| if (ninety & 1) { |
| lx = lv; |
| ly = lu; |
| } else { |
| lx = lu; |
| ly = lv; |
| } |
| |
| bufin = bwBuffer; |
| bytewrapin = (bwWrap + 7) >> 3; |
| bitoffsin = 0; |
| bufout = rout->getRawData(); |
| wrapout = rout->getWrap(); |
| |
| dudx = 0; |
| dudy = 0; |
| dvdx = 0; |
| dvdy = 0; |
| |
| switch ((mirror << 2) + ninety) { |
| CASE(0 << 2) + 0 : u00 = u1; |
| v00 = v1; |
| dudx = 1; |
| dvdy = 1; |
| CASE(0 << 2) + 1 : u00 = u1; |
| v00 = v1 + sv; |
| dudy = 1; |
| dvdx = -1; |
| CASE(0 << 2) + 2 : u00 = u1 + su; |
| v00 = v1 + sv; |
| dudx = -1; |
| dvdy = -1; |
| CASE(0 << 2) + 3 : u00 = u1 + su; |
| v00 = v1; |
| dudy = -1; |
| dvdx = 1; |
| CASE(1 << 2) + 0 : u00 = u1 + su; |
| v00 = v1; |
| dudx = -1; |
| dvdy = 1; |
| CASE(1 << 2) + 1 : u00 = u1 + su; |
| v00 = v1 + sv; |
| dudy = -1; |
| dvdx = -1; |
| CASE(1 << 2) + 2 : u00 = u1; |
| v00 = v1 + sv; |
| dudx = 1; |
| dvdy = -1; |
| CASE(1 << 2) + 3 : u00 = u1; |
| v00 = v1; |
| dudy = 1; |
| dvdx = 1; |
| DEFAULT: |
| abort(); |
| u00 = v00 = dudy = dvdx = 0; |
| } |
| |
| if (dudx) |
| for (u0 = u00, v0 = v00, y = newy; y < newy + ly; v0 += dvdy, y++) { |
| u = u0; |
| v = v0; |
| byteout = bufout + newx + y * wrapout; |
| for (x = newx; x < newx + lx; u += dudx, x++) { |
| if (GET_BIT(u, v, bufin, bytewrapin, bitoffsin)) |
| *byteout++ = value_for_1; |
| else |
| *byteout++ = value_for_0; |
| } |
| } |
| else |
| for (u0 = u00, v0 = v00, y = newy; y < newy + ly; u0 += dudy, y++) { |
| u = u0; |
| v = v0; |
| byteout = bufout + newx + y * wrapout; |
| for (x = newx; x < newx + lx; v += dvdx, x++) { |
| if (GET_BIT(u, v, bufin, bytewrapin, bitoffsin)) |
| *byteout++ = value_for_1; |
| else |
| *byteout++ = value_for_0; |
| } |
| } |
| } |
| }; |
| |