Blob Blame Raw


#include "tscannerutil.h"

#include <cstring>

#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, /* *bytein,*/ *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; //rin->bit_offs;
	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;
		break;
	case (0 << 2) + 1:
		u00 = u1;
		v00 = v1 + sv;
		dudy = 1;
		dvdx = -1;
		break;
	case (0 << 2) + 2:
		u00 = u1 + su;
		v00 = v1 + sv;
		dudx = -1;
		dvdy = -1;
		break;
	case (0 << 2) + 3:
		u00 = u1 + su;
		v00 = v1;
		dudy = -1;
		dvdx = 1;
		break;
	case (1 << 2) + 0:
		u00 = u1 + su;
		v00 = v1;
		dudx = -1;
		dvdy = 1;
		break;
	case (1 << 2) + 1:
		u00 = u1 + su;
		v00 = v1 + sv;
		dudy = -1;
		dvdx = -1;
		break;
	case (1 << 2) + 2:
		u00 = u1;
		v00 = v1 + sv;
		dudx = 1;
		dvdy = -1;
		break;
	case (1 << 2) + 3:
		u00 = u1;
		v00 = v1;
		dudy = 1;
		dvdx = 1;
		break;
	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;
			}
		}
}
};