Esempio n. 1
0
//------------------------------------------------
inline void setMatteAndYMirror(const TRaster32P &ras)
{
	ras->lock();
	TPixel32 *upRow = ras->pixels();
	TPixel32 *dwRow = ras->pixels(ras->getLy() - 1);
	int hLy = (int)(ras->getLy() / 2. + 0.5); //piccola pessimizzazione...
	int wrap = ras->getWrap();
	int lx = ras->getLx();
	TPixel32 *upPix = 0;
	TPixel32 *lastPix = ras->pixels(hLy);
	while (upPix < lastPix) {
		upPix = upRow;
		TPixel32 *dwPix = dwRow;
		TPixel32 *endPix = upPix + lx;
		while (upPix < endPix) {
			TPixel32 tmpPix(upPix->r, upPix->g, upPix->b, 0xff);
			*upPix = *dwPix;
			upPix->m = 0xff;
			*dwPix = tmpPix;
			++upPix;
			++dwPix;
		}
		upRow += wrap;
		dwRow -= wrap;
	}
	ras->unlock();
}
Esempio n. 2
0
FullColorAreaFiller::FullColorAreaFiller(const TRaster32P &ras)
    : m_ras(ras)
    , m_bounds(ras->getBounds())
    , m_pixels(ras->pixels())
    , m_wrap(ras->getWrap())
    , m_color(0) {
  m_ras->lock();
}
Esempio n. 3
0
void TRop::brush(
	TRaster32P ras,
	const TPoint &aa,
	const TPoint &bb,
	int radius,
	const TPixel32 &col)
{

	TPoint a = aa;
	TPoint b = bb;
	if (a.y > b.y)
		tswap(a, b); //  a e' piu' in basso di b

	int lx = ras->getLx();
	int ly = ras->getLy();
	ras->lock();

	// ----- radius = 0
	if (radius == 0) {
		//  k = +1/-1 se il rettangolo e' inclinato positivamente (0<=m)/negativamente (m<0)
		//  (se k<0 viene fatta una riflessione sulle ascisse prima di tornare alle
		//  coordinate "di schermo")
		int k = 1;
		int dy = b.y - a.y;
		int dx = b.x - a.x;
		if (dx < 0) {
			dx = -dx;
			k = -1;
		}

		assert(dx >= 0);
		assert(dy >= 0);

		double m; //  m sara' definita solo per dx!=0)
		if (dx > 0) {
			m = dy / (double)dx;
		}
		//double length = sqrt(dx*dx + dy*dy);
		const int alpha = dy, beta = -dx;
		const int incE = alpha;
		const int incNE = alpha + beta;
		const int incN = beta;

		//  N.B. le coordinate sono relative ad un sist. di rif. con l'origine in a
		//  l'eq. della retta e' alpha * x + beta * y = 0

		int yMin = tmax(a.y, 0) - a.y;		//  clipping y + cambio  riferimento
		int yMax = tmin(b.y, ly - 1) - a.y; //  (trasporto dell'origine in a)
		if (dx > 0 && m <= 1) {
			//  midpoint algorithm
			TPoint segm;
			if (dy == 0) //  segmento orizzontale: inizializza segm
			{
				segm.x = 0;
				segm.y = yMin;
			} else //  0<m<=1 :  inizializza segm
			{
				segm.x = tceil((yMin - 0.5) / m);
				segm.y = yMin;
			}

			int dSegm = tfloor(alpha * (segm.x + 1) + beta * (segm.y + 0.5));
			while (segm.y <= yMax) {
				int count = 0;					  //  i trati orizzontali di segm vengono disegnati in "blocco"
				while (dSegm < 0 && segm.x <= dx) //  Est:  segm.x<=dx evita il ciclo
				{								  //  infinito quando m=0 (incE=0)
					dSegm = dSegm + incE;
					segm.x++;
					count++;
				}
				//  NordEst
				int xMin, xMax;
				if (k > 0) {
					xMin = tmax(a.x + segm.x - count, a.x, 0); //  clipping x + ritorno alle
					xMax = tmin(a.x + segm.x, b.x, lx - 1);	//  coordinate "di schermo"

				} else {
					xMin = tmax(a.x - segm.x, a.x - dx, 0);			//  clipping x + riflessione + ritorno
					xMax = tmin(a.x - segm.x + count, a.x, lx - 1); //  alle  coordinate "di schermo"
				}

				TPixel32 *p = ras->pixels(segm.y + a.y) + xMin;
				TPixel32 *q = p + (xMax - xMin);

				while (p <= q)
					*p++ = col;

				dSegm = dSegm + incNE;
				segm.x++;
				segm.y++;
			}
		} else //  m>1 oppure segmento verticale
		{
			//  midpoint algorithm
			TPoint segm;
			if (dx == 0) //  segmento verticale: inizializza segm
			{
				segm.x = 0;
				segm.y = yMin;
			} else //  m>1 :  inizializza segm
			{
				segm.x = tround(yMin / m);
				segm.y = yMin;
			}

			int dSegm = tfloor(alpha * (segm.x + 0.5) + beta * (segm.y + 1));
			while (segm.y <= yMax) {
				int xMin, xMax;
				if (k > 0) {
					xMin = tmax(a.x + segm.x, 0);	  //  clipping x + ritorno alle
					xMax = tmin(a.x + segm.x, lx - 1); //  coordinate "di schermo"

				} else {
					xMin = tmax(a.x - segm.x, 0);	  //  clipping x + riflessione + ritorno
					xMax = tmin(a.x - segm.x, lx - 1); //  alle  coordinate "di schermo"
				}

				TPixel32 *p = ras->pixels(segm.y + a.y) + xMin;
				TPixel32 *q = p + (xMax - xMin);

				while (p <= q)
					*p++ = col;

				if (dSegm <= 0) //  NordEst
				{
					dSegm = dSegm + incNE;
					segm.x++;
				} else //  Nord
				{
					dSegm = dSegm + incN;
				}
				segm.y++;
			}
		}
		ras->unlock();
		return;
	}

	HalfCord halfCord(radius);

	int x, y;

	// ----- punti iniziali coincidenti: disegna un cerchio
	if (a == b) {
		int yMin = tmax(a.y - radius, 0);	  //  clipping y
		int yMax = tmin(a.y + radius, ly - 1); //  clipping y
		for (y = yMin; y <= yMax; y++) {
			int deltay = abs(y - a.y);
			int xMin = tmax(a.x - halfCord.getCord(deltay), 0);		 //  clipping x
			int xMax = tmin(a.x + halfCord.getCord(deltay), lx - 1); //  clipping x
			TPixel32 *p = ras->pixels(y) + xMin;
			TPixel32 *q = p + (xMax - xMin);
			while (p <= q)
				*p++ = col;
		}
		ras->unlock();
		return;
	}

	// -----  rettangolo orizzontale (a.y = b.y, a.x != b.x)
	if (a.y == b.y) {
		int yMin = tmax((a.y - radius), 0);		 //  clipping y
		int yMax = tmin((a.y + radius), ly - 1); //  clipping y
		int xLeft = tmin(a.x, b.x);
		int xRight = tmax(a.x, b.x);
		for (y = yMin; y <= yMax; y++) {
			int deltay = abs(y - a.y);
			int xMin = tmax(xLeft - halfCord.getCord(deltay), 0);		//  clipping x
			int xMax = tmin(xRight + halfCord.getCord(deltay), lx - 1); //  clipping x
			TPixel32 *p = ras->pixels(y) + xMin;
			TPixel32 *q = p + (xMax - xMin);
			while (p <= q)
				*p++ = col;
		}
		ras->unlock();
		return;
	}

	// -----  rettangolo verticale (a.x = b.x, a.y != b.y)
	if (a.x == b.x) {

		int xMin = tmax(a.x - radius, 0);	  //  clipping x
		int xMax = tmin(a.x + radius, lx - 1); //  clipping x
		for (x = xMin; x <= xMax; x++) {
			int deltax = abs(x - a.x);
			int yMin = tmax(a.y - halfCord.getCord(deltax), 0);		 //  clipping y
			int yMax = tmin(b.y + halfCord.getCord(deltax), ly - 1); //  clipping y
			if (yMin <= yMax) {
				TPixel32 *p = ras->pixels(yMin) + x;
				TPixel32 *q = ras->pixels(yMax) + x;
				int wrap = ras->getWrap();
				while (p <= q) {
					*p = col;
					p += wrap;
				}
			}
		}
		ras->unlock();
		return;
	}

	// -----  rettangolo inclinato
	//	k = +1/-1 se il rettangolo e' inclinato positivamente/negativamente
	int k = 1;
	int dx = b.x - a.x;
	if (dx < 0) {
		dx = -dx;
		k = -1;
	}
	int dy = b.y - a.y;

	assert(dx > 0);
	assert(dy > 0);

	double length = sqrt((double)(dx * dx + dy * dy));
	const double m = dy / (double)dx;

	//punto di tangenza superiore nel sistema di riferimento del cerchio
	TPointD up(-radius * dy / length, radius * dx / length);

	//semi-ampiezza orizzontale delle "calotte" circolari
	int halfAmplCap = tfloor(-up.x);

	//  A meno di intersezioni relative tra le diverse zone:

	//  le scanline della "calotta" circolare superiore sono (b.y+cutExt,b.y+radius]
	//  le scanline del trapezoide circolare superiore sono [b.y-cutIn,b.y+cutExt]
	//  le scanline del parallelogramma sono (a.y+cutIn,b.y-cutIn)
	//  le scanline del trapezoide circolare inferiore sono [a.y-cutExt,a.y+cutIn]
	//  le scanline della "calotta" circolare inferiore sono [a.y-radius,a.y-cutExt)
	int cutExt, cutIn;

	// vertici del parallelogramma
	TPointD rightUp;
	TPointD rightDown;
	TPointD leftUp;
	TPointD leftDown;
	double mParall; //coeff. angolare parallelogramma

	//  NOTA BENE:  halfAmplCap=0 <=> (radius=0 (caso a parte) , 1)
	if (radius > 1) {
		for (cutExt = radius; cutExt >= 0 && halfCord.getCord(cutExt) <= halfAmplCap; cutExt--)
			;
		cutIn = cutExt; //  vedi else successivo
		rightUp.x = dx + halfCord.getCord(cutIn);
		rightUp.y = dy - cutIn;
		rightDown.x = halfCord.getCord(cutIn);
		rightDown.y = -cutIn;
		leftUp.x = dx - halfCord.getCord(cutIn);
		leftUp.y = dy + cutIn;
		leftDown.x = -halfCord.getCord(cutIn);
		leftDown.y = cutIn;
		mParall = dy / (double)dx;
	} else //  N.B. cutExt != cutIn solo quando radius=1
	{
		cutExt = radius; //  radius=1 => halfAmplCap=0 (non ci sono mai le "calotte" circolari)
		cutIn = 0;		 //  anche per radius=1 il limite "interno" dei trapezoidi circolari e' < radius
		rightUp.x = dx - up.x;
		rightUp.y = dy - up.y;
		rightDown.x = -up.x;
		rightDown.y = -up.y;
		leftUp.x = dx + up.x;
		leftUp.y = dy + up.y;
		leftDown.x = up.x;
		leftDown.y = up.y;
		mParall = m;
	}
	// -----  riempie "calotte" circolari

	// -----  riempie "calotta" circolare inferiore
	int yMin = tmax(a.y - radius, 0);		   //  clipping y
	int yMax = tmin(a.y - cutExt - 1, ly - 1); //  clipping y
	for (y = yMin; y <= yMax; y++) {
		int r = halfCord.getCord(a.y - y);
		int xMin = tmax(a.x - r, 0);	  //  clipping x
		int xMax = tmin(a.x + r, lx - 1); //  clipping x
		TPixel32 *p = ras->pixels(y) + xMin;
		TPixel32 *q = p + (xMax - xMin);
		while (p <= q)
			*p++ = col;
	}
	// -----  riempie "calotta" circolare superiore
	yMin = tmax(b.y + cutExt + 1, 0);  //  clipping y
	yMax = tmin(b.y + radius, ly - 1); //  clipping y
	for (y = yMin; y <= yMax; y++) {
		int r = halfCord.getCord(y - b.y);
		int xMin = tmax(b.x - r, 0);	  //  clipping x
		int xMax = tmin(b.x + r, lx - 1); //  clipping x
		TPixel32 *p = ras->pixels(y) + xMin;
		TPixel32 *q = p + (xMax - xMin);
		while (p <= q)
			*p++ = col;
	}
	// -----  riempie trapezoidi

	// (se k<0 viene fatta una riflessione sulle ascisse prima di tornare alle
	// coordinate "di schermo")

	//  limite destro assoluto delle scanline trapezoide:
	int xSegmMax = tround(dx - up.x); //  coordinata x del punto di tangenza inferiore sul cerchio superiore

	//  limite sinistro assoluto delle scanline:
	int xSegmMin = tround(up.x); //  coordinata x del punto di tangenza superiore sul cerchio inferiore

	// -----  riempie trapezoide inferiore

	// N.B. le coordinate sono relative ad un sist. di rif. con l'origine sul centro
	// del cerchio inferiore

	yMin = tmax(a.y - cutExt, 0) - a.y;						 //  clipping y
	yMax = tmin(a.y + cutIn, b.y - cutIn - 1, ly - 1) - a.y; //  clipping y

	// l'eq. della retta e' alpha * x + beta * y + gammaRight = 0
	const int alpha = dy, beta = -dx;
	const double gammaRight = rightDown.y * dx - rightDown.x * dy;
	const int incE = alpha;
	const int incNE = alpha + beta;
	const int incN = beta;

	if (m <= 1) {
		//  midpoint algorithm; le scanline vengono disegnate solo
		//  sul NordEst. L'ultima scanline non viene disegnata
		TPoint segmRight(tceil((yMin + 0.5 - rightDown.y) / mParall + rightDown.x) - 1, yMin);
		int dSegmRight = tfloor(alpha * (segmRight.x + 1) + beta * (segmRight.y + 0.5) + gammaRight);
		while (segmRight.y <= yMax) {
			if (dSegmRight < 0) //  Est
			{
				dSegmRight = dSegmRight + incE;
				segmRight.x++;
			} else //  NordEst
			{
				int xMin, xMax;
				if (k > 0) {
					xMin = tmax(a.x - halfCord.getCord(abs(segmRight.y)), 0); //  clipping x
					xMax = tmin(a.x + tmin(segmRight.x, xSegmMax), lx - 1);   //  clipping x
				} else {
					xMin = tmax(a.x - tmin(segmRight.x, xSegmMax), 0);			   //  clipping x + ritorno alle
					xMax = tmin(a.x + halfCord.getCord(abs(segmRight.y)), lx - 1); //   coordinate "di schermo"
				}
				TPixel32 *p = ras->pixels(segmRight.y + a.y) + xMin;
				TPixel32 *q = p + (xMax - xMin);
				while (p <= q)
					*p++ = col;

				dSegmRight = dSegmRight + incNE;
				segmRight.x++;
				segmRight.y++;
			}
		}
	} else //  m>1
	{
		//  midpoint algorithm; le scanline vengono disegnate sempre
		TPoint segmRight(tround((yMin - rightDown.y) / mParall + rightDown.x), yMin);
		int dSegmRight = tfloor(alpha * (segmRight.x + 0.5) + beta * (segmRight.y + 1) + gammaRight);
		while (segmRight.y <= yMax) {
			int xMin, xMax;
			if (k > 0) {
				xMin = tmax(a.x - halfCord.getCord(abs(segmRight.y)), 0); //  clipping x
				xMax = tmin(a.x + segmRight.x, lx - 1);					  //  clipping x
			} else {
				xMin = tmax(a.x - segmRight.x, 0);							   //  clipping x + ritorno alle coordinate
				xMax = tmin(a.x + halfCord.getCord(abs(segmRight.y)), lx - 1); //  "di schermo"
			}
			TPixel32 *p = ras->pixels(segmRight.y + a.y) + xMin;
			TPixel32 *q = p + (xMax - xMin);
			while (p <= q)
				*p++ = col;

			if (dSegmRight <= 0) //  NordEst
			{
				dSegmRight = dSegmRight + incNE;
				segmRight.x++;
			} else //  Nord
			{
				dSegmRight = dSegmRight + incN;
			}
			segmRight.y++;
		}
	}

	// -----  riempie trapezoide superiore

	//  N.B. le coordinate sono relative ad un sist. di rif. con l'origine sul centro
	//  del cerchio superiore
	yMin = tmax(b.y - cutIn, a.y + cutIn + 1, 0) - b.y; //  clipping y
	yMax = tmin(b.y + cutExt, ly - 1) - b.y;			//  clipping y

	//   l'eq. della retta e' alpha * x + beta * y + gammaLeft = 0
	const double gammaLeft = leftDown.y * dx - leftDown.x * dy;

	if (m <= 1) {
		//  midpoint algorithm; le scanline vengono disegnate solo
		//  sul NordEst. L'ultima scanline non viene disegnata
		TPoint segmLeft(tceil((yMin - 0.5 - leftDown.y) / mParall + leftDown.x), yMin);
		int dSegmLeft = tfloor(alpha * (segmLeft.x + 1) + beta * (segmLeft.y + 0.5) + gammaLeft);
		while (segmLeft.y <= yMax) {
			int xMin, xMax;
			if (k > 0) {
				xMin = tmax(b.x + tmax(segmLeft.x, xSegmMin - dx), 0);		  //  clipping x
				xMax = tmin(b.x + halfCord.getCord(abs(segmLeft.y)), lx - 1); //  clipping x
			} else {
				xMin = tmax(b.x - halfCord.getCord(abs(segmLeft.y)), 0);	//  clipping x + ritorno alle
				xMax = tmin(b.x - tmax(segmLeft.x, xSegmMin - dx), lx - 1); //   coordinate "di schermo"
			}
			TPixel32 *p = ras->pixels(segmLeft.y + b.y) + xMin;
			TPixel32 *q = p + (xMax - xMin);

			while (p <= q)
				*p++ = col;
			while (dSegmLeft < 0) {
				dSegmLeft = dSegmLeft + incE;
				segmLeft.x++;
			}
			dSegmLeft = dSegmLeft + incNE;
			segmLeft.x++;
			segmLeft.y++;
		}
	} else //  m>1
	{
		//  midpoint algorithm; le scanline vengono disegnate sempre
		TPoint segmLeft(tround((yMin - leftDown.y) / mParall + leftDown.x), yMin);
		int dSegmLeft = tfloor(alpha * (segmLeft.x + 0.5) + beta * (segmLeft.y + 1) + gammaLeft);
		while (segmLeft.y <= yMax) {
			int xMin, xMax;
			if (k > 0) {
				xMin = tmax(b.x + segmLeft.x, 0);							  //  clipping x
				xMax = tmin(b.x + halfCord.getCord(abs(segmLeft.y)), lx - 1); //  clipping x
			} else {
				xMin = tmax(b.x - halfCord.getCord(abs(segmLeft.y)), 0); //  clipping x + ritorno alle
				xMax = tmin(b.x - segmLeft.x, lx - 1);					 //   coordinate "di schermo"
			}
			TPixel32 *p = ras->pixels(segmLeft.y + b.y) + xMin;
			TPixel32 *q = p + (xMax - xMin);

			while (p <= q)
				*p++ = col;

			if (dSegmLeft <= 0) //  NordEst
			{
				dSegmLeft = dSegmLeft + incNE;
				segmLeft.x++;
			} else //  Nord
			{
				dSegmLeft = dSegmLeft + incN;
			}
			segmLeft.y++;
		}
	}

	// -----  parallelogramma (in alternativa a "parallelogrammoide circolare")

	// N.B. le coordinate sono relative ad un sist. di rif. con l'origine sul centro
	// del cerchio inferiore

	//  retta destra di equaz.   alpha * x + beta * y + gammaRight = 0
	//  retta sinistra di equaz. alpha * x + beta * y + gammaLeft = 0

	yMin = tmax(a.y + cutIn + 1, 0) - a.y;		//clipping y
	yMax = tmin(b.y - cutIn - 1, ly - 1) - a.y; //clipping y
	if (m <= 1) {
		//  midpoint algorithm; le scanline vengono disegnate solo
		//  sul NordEst. L'ultima scanline non viene disegnata
		TPoint segmRight(tceil((yMin + 0.5 - rightDown.y) / mParall + rightDown.x) - 1, yMin);
		TPoint segmLeft = TPoint(tceil((yMin - 0.5 - leftDown.y) / mParall + leftDown.x), yMin);
		int dSegmRight = tfloor(alpha * (segmRight.x + 1) + beta * (segmRight.y + 0.5) + gammaRight);
		int dSegmLeft = tfloor(alpha * (segmLeft.x + 1) + beta * (segmLeft.y + 0.5) + gammaLeft);
		while (segmRight.y <= yMax) {
			if (dSegmRight < 0) //  segmRight a Est
			{
				dSegmRight = dSegmRight + incE;
				segmRight.x++;
			} else //  segmRight a NordEst
			{
				int xMin, xMax;
				if (k > 0) {
					xMin = tmax(a.x + tmax(segmLeft.x, xSegmMin), 0);		//  clipping x
					xMax = tmin(a.x + tmin(segmRight.x, xSegmMax), lx - 1); //  clipping x
				} else {
					xMin = tmax(a.x - tmin(segmRight.x, xSegmMax), 0);	 //  clipping x + ritorno alle
					xMax = tmin(a.x - tmax(segmLeft.x, xSegmMin), lx - 1); //   coordinate "di schermo"
				}

				TPixel32 *p = ras->pixels(segmRight.y + a.y) + xMin;
				TPixel32 *q = p + (xMax - xMin);

				while (p <= q)
					*p++ = col;

				dSegmRight = dSegmRight + incNE;
				segmRight.x++;
				segmRight.y++;

				while (dSegmLeft < 0) //  segmLeft a Est
				{
					dSegmLeft = dSegmLeft + incE;
					segmLeft.x++;
				}
				//  segmLeft a NordEst
				dSegmLeft = dSegmLeft + incNE;
				segmLeft.x++;
				segmLeft.y++;
			}
		}
	} else //  m>1
	{
		//  midpoint algorithm; le scanline vengono disegnate sempre
		TPoint segmRight(tround((yMin - rightDown.y) / mParall + rightDown.x), yMin);
		TPoint segmLeft(tround((yMin - leftDown.y) / mParall + leftDown.x), yMin);
		int dSegmRight = tfloor(alpha * (segmRight.x + 0.5) + beta * (segmRight.y + 1) + gammaRight);
		int dSegmLeft = tfloor(alpha * (segmLeft.x + 0.5) + beta * (segmLeft.y + 1) + gammaLeft);
		while (segmRight.y <= yMax) {
			int xMin, xMax;
			if (k > 0) {
				xMin = tmax(a.x + segmLeft.x, 0);		//  clipping x
				xMax = tmin(a.x + segmRight.x, lx - 1); //  clipping x
			} else {
				xMin = tmax(a.x - segmRight.x, 0);	 //  clipping x + ritorno alle
				xMax = tmin(a.x - segmLeft.x, lx - 1); //   coordinate "di schermo"
			}

			TPixel32 *p = ras->pixels(segmRight.y + a.y) + xMin;
			TPixel32 *q = p + (xMax - xMin);

			while (p <= q)
				*p++ = col;

			if (dSegmRight <= 0) //  segmRight a NordEst
			{
				dSegmRight = dSegmRight + incNE;
				segmRight.x++;
			} else //  segmRight a Nord
			{
				dSegmRight = dSegmRight + incN;
			}
			segmRight.y++;

			if (dSegmLeft <= 0) //  segmLeft a NordEst
			{
				dSegmLeft = dSegmLeft + incNE;
				segmLeft.x++;
			} else //  segmLeft a Nord
			{
				dSegmLeft = dSegmLeft + incN;
			}
		}
	}

	// ----  parallelogrammoide circolare (in alternativa a parallelogramma)

	// N.B. coordinate di schermo (riflessione per k<0 )

	yMin = tmax(b.y - cutIn, 0);
	yMax = tmin(a.y + cutIn, ly - 1);
	for (y = yMin; y <= yMax; y++) {
		int xMin, xMax;
		if (k > 0) {
			xMin = tmax(a.x - halfCord.getCord(abs(y - a.y)), 0);	  //  clipping x
			xMax = tmin(b.x + halfCord.getCord(abs(b.y - y)), lx - 1); //  clipping x
		} else {
			xMin = tmax(b.x - halfCord.getCord(abs(b.y - y)), 0);	  //  clipping x + ritorno alle
			xMax = tmin(a.x + halfCord.getCord(abs(y - a.y)), lx - 1); //   coordinate "di schermo"
		}
		TPixel32 *p = ras->pixels(y) + xMin;
		TPixel32 *q = p + (xMax - xMin);
		while (p <= q)
			*p++ = col;
	}
	ras->unlock();
}
Esempio n. 4
0
void Convert2Tlv::doFill(TRasterCM32P &rout, const TRaster32P &rin)
{
	//prima passata: si filla  solo partendo da pixel senza inchiostro, senza antialiasing(tone==255)
	for (int i = 0; i < rin->getLy(); i++) {
		TPixel *pixin = rin->pixels(i);
		TPixelCM32 *pixout = rout->pixels(i);
		for (int j = 0; j < rin->getLx(); j++, pixin++, pixout++) {
			if (!(pixout->getTone() == 255 && pixout->getPaint() == 0 && pixin->m == 255))
				continue;

			std::map<TPixel, int>::const_iterator it;
			int paintIndex;
			if ((it = m_colorMap.find(*pixin)) == m_colorMap.end()) {
				if (m_colorTolerance > 0)
					it = findNearestColor(*pixin);
				// if (it==colorMap.end() && (int)colorMap.size()>origColorCount) //se non l'ho trovato tra i colori origari, lo cerco in quelli nuovi, ma in questo caso deve essere esattamente uguale(tolerance = 0)
				//	 it  = findNearestColor(*pixin, colorMap, colorTolerance, origColorCount, colorMap.size()-1);

				if (it == m_colorMap.end() && m_lastIndex < 4096) {
					m_colorMap[*pixin] = ++m_lastIndex;
					paintIndex = m_lastIndex;
				} else if (it != m_colorMap.end()) {
					m_colorMap[*pixin] = it->second;
					paintIndex = it->second;
				}
			} else
				paintIndex = it->second;
			FillParameters params;
			params.m_p = TPoint(j, i);
			params.m_styleId = paintIndex;
			params.m_emptyOnly = true;
			fill(rout, params);
			//if (*((ULONG *)rout->getRawData())!=0xff)
			//  {
			//  int cavolo=0;
			//  }
		}
	}

	//seconda passata: se son rimasti pixel antialiasati non fillati, si fillano, cercando nelle vicinanze un pixel di paint puro per capire il colore da usare
	for (int i = 0; i < rin->getLy(); i++) {
		TPixel *pixin = rin->pixels(i);
		TPixelCM32 *pixout = rout->pixels(i);
		for (int j = 0; j < rin->getLx(); j++, pixin++, pixout++) {
			if (!(pixout->getTone() > 0 && pixout->getTone() < 255 && pixout->getPaint() == 0 && pixin->m == 255))
				continue;

			TPoint p = getClosestPurePaint(rout, i, j);
			if (p.x == -1)
				continue;

			//pixout->setPaint( paintIndex);
			FillParameters params;
			params.m_p = TPoint(j, i);
			params.m_styleId = (rout->pixels(p.y) + p.x)->getPaint();
			params.m_emptyOnly = true;

			fill(rout, params);
		}
	}

	//infine, si filla di trasparente lo sfondo, percorrendo il bordo, nel caso di trasbordamenti di colore
	TPixelCM32 *pixCm;
	TPixel *pix;

	pixCm = rout->pixels(0);
	pix = rin->pixels(0);
	FillParameters params;
	params.m_styleId = 0;

	for (int i = 0; i < rout->getLx(); i++, pixCm++, pix++)
		if (pixCm->getTone() == 255 && pixCm->getPaint() != 0 && pix->m == 0) {
			params.m_p = TPoint(i, 0);
			fill(rout, params);
		}

	pixCm = rout->pixels(rout->getLy() - 1);
	pix = rin->pixels(rout->getLy() - 1);
	for (int i = 0; i < rout->getLx(); i++, pixCm++, pix++)
		if (pixCm->getTone() == 255 && pixCm->getPaint() != 0 && pix->m == 0) {
			params.m_p = TPoint(i, rout->getLy() - 1);
			fill(rout, params);
		}
	int wrapCM = rout->getWrap();
	int wrap = rin->getWrap();

	pixCm = rout->pixels(0);
	pix = rin->pixels(0);
	for (int i = 0; i < rin->getLy(); i++, pixCm += wrapCM, pix += wrap)
		if (pixCm->getTone() == 255 && pixCm->getPaint() != 0 && pix->m == 0) {
			params.m_p = TPoint(0, i);
			fill(rout, params);
		}
	pixCm = rout->pixels(0) + rout->getLx() - 1;
	pix = rin->pixels(0) + rin->getLx() - 1;
	for (int i = 0; i < rin->getLy(); i++, pixCm += wrapCM, pix += wrap)
		if (pixCm->getTone() == 255 && pixCm->getPaint() != 0 && pix->m == 0) {
			params.m_p = TPoint(rout->getLx() - 1, i);
			fill(rout, params);
		}
}
Esempio n. 5
0
void TLevelReader3gp::load(const TRasterP &rasP, int frameIndex, const TPoint &pos, int shrinkX, int shrinkY)
{
	TRaster32P ras = rasP;

	{
		QMutexLocker sl(&m_mutex);
		ras->lock();
		if (m_IOError != QTNoError)
			goto error;

		Rect rect;
		rect.right = pos.x + ras->getLx();
		rect.left = pos.x;
		rect.bottom = pos.y + ras->getLy();
		rect.top = pos.y;

		GWorldPtr offscreenGWorld;
		OSErr err;

#if defined TNZ_MACHINE_CHANNEL_ORDER_BGRM
		OSType pixelFormat = k32BGRAPixelFormat;
#elif defined TNZ_MACHINE_CHANNEL_ORDER_MRGB
		OSType pixelFormat = k32ARGBPixelFormat;
#endif

		err = QTNewGWorldFromPtr(
			&offscreenGWorld, pixelFormat,
			&rect, 0, 0, 0, ras->getRawData(), ras->getWrap() * 4);

		if (err != noErr) {
			m_IOError = QTUnableToCreateResource;
			goto error;
		}

		SetMovieBox(m_movie, &rect);
		err = GetMoviesError();
		if (err != noErr) {
			m_IOError = QTUnableToSetMovieBox;
#if 0
    DisposeGWorld(offscreenGWorld);
#endif
			goto error;
		}

#if 0
  SetMovieGWorld(m_movie, offscreenGWorld, GetGWorldDevice(offscreenGWorld));
#endif
		err = GetMoviesError();
		if (err != noErr) {
			m_IOError = QTUnableToSetMovieGWorld;
#if 0
    DisposeGWorld(offscreenGWorld);
#endif
			goto error;
		}

		TimeValue currentTime = currentTimes[frameIndex];

		SetMovieTimeValue(m_movie, currentTime);

		err = GetMoviesError();
		if (err != noErr) {
			m_IOError = QTUnableToSetTimeValue;
#if 0
    DisposeGWorld(offscreenGWorld);
#endif
			goto error;
		}

		err = UpdateMovie(m_movie);
		if (err != noErr) {
			m_IOError = QTUnableToUpdateMovie;
#if 0
    DisposeGWorld(offscreenGWorld);
#endif
			goto error;
		}

		MoviesTask(m_movie, 0);
		err = GetMoviesError();
		if (err != noErr) {
			m_IOError = QTUnableToDoMovieTask;
#if 0
    DisposeGWorld(offscreenGWorld);
#endif
			goto error;
		}

		SetMovieGWorld(m_movie, 0, 0);
#if 0
  DisposeGWorld(offscreenGWorld);
#endif
		ras->unlock();
	}

	if (m_depth != 32) {
		setMatteAndYMirror(rasP);
	} else {
		rasP->yMirror();
	}

	return;

error:
	ras->unlock();
	throw TImageException(m_path, buildQTErrorString(m_IOError));
}
Esempio n. 6
0
void tglDraw(const TRectD &rect, const TRaster32P &tex, bool blending)
{
	CHECK_ERRORS_BY_GL;
	glPushAttrib(GL_ALL_ATTRIB_BITS);
	if (blending) {
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	}

	unsigned int texWidth = 1;
	unsigned int texHeight = 1;

	while (texWidth < (unsigned int)tex->getLx())
		texWidth = texWidth << 1;

	while (texHeight < (unsigned int)tex->getLy())
		texHeight = texHeight << 1;

	double lwTex = 1.0;
	double lhTex = 1.0;

	TRaster32P texture;
	unsigned int texLx = (unsigned int)tex->getLx();
	unsigned int texLy = (unsigned int)tex->getLy();

	if (texWidth != texLx ||
		texHeight != texLy) {
		texture = TRaster32P(texWidth, texHeight);
		texture->fill(TPixel32(0, 0, 0, 0));
		texture->copy(tex);
		lwTex = (texLx) / (double)(texWidth);
		lhTex = (texLy) / (double)(texHeight);
		if (lwTex > 1.0)
			lwTex = 1.0;
		if (lhTex > 1.0)
			lhTex = 1.0;
	} else
		texture = tex;
	GLenum fmt =
#ifdef TNZ_MACHINE_CHANNEL_ORDER_BGRM
		GL_BGRA_EXT;
#elif TNZ_MACHINE_CHANNEL_ORDER_MBGR
		GL_ABGR_EXT;
#elif TNZ_MACHINE_CHANNEL_ORDER_RGBM
		GL_RGBA;
#elif TNZ_MACHINE_CHANNEL_ORDER_MRGB
		GL_BGRA;
#else
//   Error  PLATFORM NOT SUPPORTED
#error "unknown channel order!"
#endif

	// Generate a texture id and bind it.
	GLuint texId;
	glGenTextures(1, &texId);

	glBindTexture(GL_TEXTURE_2D, texId);

	glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->getWrap());

	texture->lock();
	glTexImage2D(GL_TEXTURE_2D,
				 0,
				 4,
				 texWidth,
				 texHeight,
				 0,
				 fmt,
#ifdef TNZ_MACHINE_CHANNEL_ORDER_MRGB
				 GL_UNSIGNED_INT_8_8_8_8_REV,
#else
				 GL_UNSIGNED_BYTE,
#endif
				 texture->getRawData());

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	glEnable(GL_TEXTURE_2D);

	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

	double rectLx = rect.getLx();
	double rectLy = rect.getLy();

	tglColor(TPixel32(0, 0, 0, 0));

	glPushMatrix();

	glTranslated(rect.x0, rect.y0, 0.0);
	glBegin(GL_POLYGON);

	glTexCoord2d(0, 0);
	tglVertex(TPointD(0.0, 0.0));

	glTexCoord2d(lwTex, 0);
	tglVertex(TPointD(rectLx, 0.0));

	glTexCoord2d(lwTex, lhTex);
	tglVertex(TPointD(rectLx, rectLy));

	glTexCoord2d(0, lhTex);
	tglVertex(TPointD(0.0, rectLy));

	glEnd();
	glDisable(GL_TEXTURE_2D);

	glPopMatrix();
	glPopAttrib();

	// Delete texture
	glDeleteTextures(1, &texId);

	texture->unlock();
}