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