⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gperotate.cpp

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

	if (!pParms->pDst->IsRotate())
	{
		if (pParms->yPositive)
		{
			dst.RowIncrement = pParms->pDst->Stride();
			dst.RowPtr       = (unsigned char*)pParms->pDst->Buffer() + pParms->pDst->Stride() * (pParms->prclDst->top + dstYStartSkip);
		}
		else
		{
			dst.RowIncrement = -pParms->pDst->Stride();
			dst.RowPtr       = (unsigned char*)pParms->pDst->Buffer() + pParms->pDst->Stride() * (pParms->prclDst->bottom - 1 - dstYStartSkip);
		}

		if (pParms->xPositive)
		{
			dst.BytesPerAccess  = dst.Bpp/8;
			dst.RowPtr         += dst.BytesPerAccess * (pParms->prclDst->left + dstXStartSkip);
		}
		else
		{
			dst.BytesPerAccess  = -dst.Bpp/8;
			dst.RowPtr         -= dst.BytesPerAccess * (pParms->prclDst->right - 1 - dstXStartSkip);
		}

		dst.IsRotate   = 0;
		dst.Mask       = (2 << (dst.Bpp - 1)) - 1;
		dst.CacheState = 0;  // so it is not marked as dirty
	}
	else
	{
		dst.InitPixelIterator((GPESurfRotate *)pParms->pDst, pParms->xPositive, pParms->yPositive, pParms->prclDst,
		                      dstXStartSkip, dstYStartSkip);
	}

	// Initialize the first source iterator (src0)
	PixelIteratorRotate src0;

	src0.InitPixelIterator(pParms->pSrc, pParms->xPositive, pParms->yPositive, pParms->prclSrc,
	                       srcXStartSkip, srcYStartSkip-1);

	// Initialize the second source iterator (src1)
	PixelIteratorRotate src1;

	src1.InitPixelIterator(pParms->pSrc, pParms->xPositive, pParms->yPositive, pParms->prclSrc,
	                       srcXStartSkip, srcYStartSkip);

	// Compensate for srcXStartSkip and srcYStartSkip.
	srcHeight -= srcYStartSkip;
	srcWidth  -= srcXStartSkip;

	// Force a read of the first row.
	int ystepOverflow = 1;

	for (int y = 0, SrcYPixels = 0; y < height; y++)
	{
		bool IsSrc0Valid;
		bool IsSrc1Valid;

		// Initialize the dst row pointer to the next line.
		if (dst.IsRotate)
		{
			dst.CurrentCoord  = dst.RowCoord;
			dst.RowCoord.y   += dst.RowIncrement;
		}
		else
		{
			dst.Ptr     = dst.RowPtr;
			dst.RowPtr += dst.RowIncrement;
		}

		// Initialize u0 and u1
		int u1 = ystep >> 8;
		int u0 = 256 - u1;

		// Check to see if we need to advance to the next row, or go back to
		// the beginning of the current source row.
		if (!ystepOverflow)
		{
			SrcYPixels--;
			if (!src0.IsRotate)
			{
				src0.RowPtr -= src0.RowIncrement;
				src1.RowPtr -= src0.RowIncrement;
			}
			else
			{
				src0.RowCoord.y -= src0.RowIncrement;
				src1.RowCoord.y -= src1.RowIncrement;
			}
		}

		// Initialize the source row pointers to the next line.
		if (src0.RowPtr)
		{
			src0.Ptr     = src0.RowPtr;
			src0.RowPtr += src0.RowIncrement;
			src1.Ptr     = src1.RowPtr;
			src1.RowPtr += src1.RowIncrement;
		}
		else if (src0.OrigPtr)
		{
			src0.CurrentCoord  = src0.RowCoord;
			src0.RowCoord.y   += src0.RowIncrement;
			src1.CurrentCoord  = src1.RowCoord;
			src1.RowCoord.y   += src1.RowIncrement;
		}

		if (SrcYPixels == 0)
		{
			IsSrc0Valid = false;
		}
		else
		{
			IsSrc0Valid = true;
		}

		if (SrcYPixels < srcHeight)
		{
			IsSrc1Valid = true;
		}
		else
		{
			IsSrc1Valid = false;
		}

		SrcYPixels++;

		if (src0.RowPtr)
		{
			if (!src0.Is24Bit && IsSrc0Valid)
			{
				src0.Cache      = *(unsigned long *)src0.Ptr;
				src0.CacheState = src0.CacheStateNewRow;
			}

			if (!src1.Is24Bit && IsSrc1Valid)
			{
				src1.Cache      = *(unsigned long *)src1.Ptr;
				src1.CacheState = src1.CacheStateNewRow;
			}
		}

		for (int x = 0, SrcXPixels = 0; x < width;)
		{
			// Save the old values of src0 and src1.
			unsigned long OldSrc0Value = src0.Value;
			unsigned long OldSrc1Value = src1.Value;

			// Only increment the src0 and src1 pointers if we haven't hit the
			// end of a row.
			if (SrcXPixels < srcWidth)
			{
				SrcXPixels++;

				// Get the next src0 pixel.
				if (IsSrc0Valid)
				{
					if (src0.Ptr)
					{
						if (src0.Is24Bit)
						{
							src0.Value  = (*src0.Ptr) + (*(src0.Ptr+1) << 8) + (*(src0.Ptr+2) << 16);
							src0.Ptr   += src0.BytesPerAccess;
						}
						else
						{
							if (!(src0.CacheState & 0x00FF00))
							{
								src0.Ptr        += src0.BytesPerAccess;
								src0.CacheState  = src0.CacheStateNewDWord;
								src0.Cache       = *(unsigned long *)src0.Ptr;
							}

							src0.Value       = src0.Cache >> ((src0.CacheState >> 16) ^ src0.MaskShiftXor);
							src0.CacheState += src0.CacheStateIncrement;
						}
					}
					else
					{
						switch (src0.Bpp)
						{
						case 8:
							src0.Value = *(unsigned char *)src0.GetPtr();
							break;
						case 16:
							src0.Value = *(unsigned short *)src0.GetPtr();
							break;
						case 32:
							src0.Value = *(unsigned long *)src0.GetPtr();
							break;
						case 24:
							{
								unsigned char * ptr = src0.GetPtr();
								src0.Value = (*ptr) | (*(ptr+1) << 8) + (*(ptr+2) << 16);
								break;
							}
						}

						src0.CurrentCoord.x += src0.ColIncrement;
					}

					src0.Value &= src0.Mask;

					if (pParms->pLookup)
					{
						src0.Value = (pParms->pLookup)[src0.Value];
					}

					if (pParms->pConvert)
					{
						src0.Value = (pParms->pColorConverter->*(pParms->pConvert))(src0.Value);
					}
				}

				// Get the next src1 pixel (if needed).
				if (IsSrc1Valid)
				{
					if (src1.Ptr)
					{
						if (src1.Is24Bit)
						{
							src1.Value  = (*src1.Ptr) + (*(src1.Ptr+1) << 8) + (*(src1.Ptr+2) << 16);
							src1.Ptr   += src1.BytesPerAccess;
						}
						else
						{
							if (!(src1.CacheState & 0x00FF00))
							{
								src1.Ptr        += src1.BytesPerAccess;
								src1.CacheState  = src1.CacheStateNewDWord;
								src1.Cache       = *(unsigned long *)src1.Ptr;
							}

							src1.Value       = src1.Cache >> ((src1.CacheState >> 16) ^ src1.MaskShiftXor);
							src1.CacheState += src1.CacheStateIncrement;
						}
					}
					else
					{
						switch (src1.Bpp)
						{
						case 8:
							src1.Value = *(unsigned char *)src1.GetPtr();
							break;
						case 16:
							src1.Value = *(unsigned short *)src1.GetPtr();
							break;
						case 32:
							src1.Value = *(unsigned long *)src1.GetPtr();
							break;
						case 24:
							{
								unsigned char * ptr = src1.GetPtr();
								src1.Value = (*ptr) | (*(ptr+1) << 8) + (*(ptr+2) << 16);
								break;
							}
						}

						src1.CurrentCoord.x += src1.ColIncrement;
					}

					src1.Value &= src1.Mask;

					if (pParms->pLookup)
					{
						src1.Value = (pParms->pLookup)[src1.Value];
					}

					if (pParms->pConvert)
					{
						src1.Value = (pParms->pColorConverter->*(pParms->pConvert))(src1.Value);
					}
				}
				else
				{
					src1.Value = src0.Value;
				}

				if (!IsSrc0Valid)
				{
					src0.Value = src1.Value;
				}
			}

			// If this is the first pixel read set the old values to this pixel
			if (SrcXPixels == 1)
			{
				OldSrc0Value = src0.Value;
				OldSrc1Value = src1.Value;
			}

			// Combine the pixels according to this algorithm:
			//   s0       = OldSrc0Value * u0 + OldSrc1Value * u1;
			//   s1       =   src0.Value * u0 +   src1.Value * u1;
			//   SrcValue =           s0 * v0 +           s1 * v1;

			unsigned long s0;
			unsigned long s1;

			if (OldSrc0Value == OldSrc1Value)
			{
				s0 = OldSrc0Value;
			}
			else
			{
				unsigned long A00aa00gg;
				unsigned long A00rr00bb;

				A00aa00gg  = ((OldSrc0Value & g_BilinearMasks[3]) >> g_BilinearShifts[3]) << 16;
				A00aa00gg |=  (OldSrc0Value & g_BilinearMasks[1]) >> g_BilinearShifts[1];
				A00rr00bb  = ((OldSrc0Value & g_BilinearMasks[0]) >> g_BilinearShifts[0]) << 16;
				A00rr00bb |=  (OldSrc0Value & g_BilinearMasks[2]) >> g_BilinearShifts[2];

				unsigned long B00aa00gg;
				unsigned long B00rr00bb;

				B00aa00gg  = ((OldSrc1Value & g_BilinearMasks[3]) >> g_BilinearShifts[3]) << 16;
				B00aa00gg |=  (OldSrc1Value & g_BilinearMasks[1]) >> g_BilinearShifts[1];
				B00rr00bb  = ((OldSrc1Value & g_BilinearMasks[0]) >> g_BilinearShifts[0]) << 16;
				B00rr00bb |=  (OldSrc1Value & g_BilinearMasks[2]) >> g_BilinearShifts[2];

				unsigned long Caaaagggg;
				unsigned long Crrrrbbbb;
				unsigned long Caarrggbb;

				Caaaagggg = A00aa00gg * u0 + B00aa00gg * u1;
				Crrrrbbbb = (A00rr00bb * u0 + B00rr00bb * u1) >> 8;
				Caarrggbb = (Caaaagggg & 0xFF00FF00) | (Crrrrbbbb & 0x00FF00FF);

				s0 = (((Caarrggbb & 0x00FF0000) >> 16) << g_BilinearShifts[0])
				     | (((Caarrggbb & 0x0000FF00) >> 8) << g_BilinearShifts[1])
				     | ((Caarrggbb & 0x000000FF) << g_BilinearShifts[2])
				     | (((Caarrggbb & 0xFF000000) >> 24) << g_BilinearShifts[3]);
			}

			if (src0.Value == src1.Value)
			{
				s1 = src0.Value;
			}
			else
			{
				unsigned long A00aa00gg;
				unsigned long A00rr00bb;

				A00aa00gg  = ((src0.Value & g_BilinearMasks[3]) >> g_BilinearShifts[3]) << 16;
				A00aa00gg |=  (src0.Value & g_BilinearMasks[1]) >> g_BilinearShifts[1];
				A00rr00bb  = ((src0.Value & g_BilinearMasks[0]) >> g_BilinearShifts[0]) << 16;
				A00rr00bb |=  (src0.Value & g_BilinearMasks[2]) >> g_BilinearShifts[2];

				unsigned long B00aa00gg;
				unsigned long B00rr00bb;

				B00aa00gg  = ((src1.Value & g_BilinearMasks[3]) >> g_BilinearShifts[3]) << 16;
				B00aa00gg |=  (src1.Value & g_BilinearMasks[1]) >> g_BilinearShifts[1];
				B00rr00bb  = ((src1.Value & g_BilinearMasks[0]) >> g_BilinearShifts[0]) << 16;
				B00rr00bb |=  (src1.Value & g_BilinearMasks[2]) >> g_BilinearShifts[2];

				unsigned long Caaaagggg;
				unsigned long Crrrrbbbb;
				unsigned long Caarrggbb;

				Caaaagggg = A00aa00gg * u0 + B00aa00gg * u1;
				Crrrrbbbb = (A00rr00bb * u0 + B00rr00bb * u1) >> 8;
				Caarrggbb = (Caaaagggg & 0xFF00FF00) | (Crrrrbbbb & 0x00FF00FF);

				s1 = (((Caarrggbb & 0x00FF0000) >> 16) << g_BilinearShifts[0])
				     | (((Caarrggbb & 0x0000FF00) >> 8) << g_BilinearShifts[1])
				     | ((Caarrggbb & 0x000000FF) << g_BilinearShifts[2])
				     | (((Caarrggbb & 0xFF000000) >> 24) << g_BilinearShifts[3]);
		}

			int xstepOverflow = 0;

			// Loop through all pixels that can be drawn without changing
			// s0 or s1, being careful not to write too many pixels.
			while (!xstepOverflow
			       && x < width)
			{
				// x only gets incremented here.
				x++;

				// Initialize v0 and v1
				int v1 = xstep >> 8;
				int v0 = 256 - v1;

				// Compute the SrcValue.
				unsigned long SrcValue;

				// See if we can take a short cut.
				if (s0 == s1)
				{
					SrcValue = s0;
				}
				else
				{
					unsigned long A00aa00gg;
					unsigned long A00rr00bb;

					A00aa00gg  = ((s0 & g_BilinearMasks[3]) >> g_BilinearShifts[3]) << 16;
					A00aa00gg |=  (s0 & g_BilinearMasks[1]) >> g_BilinearShifts[1];
					A00rr00bb  = ((s0 & g_BilinearMasks[0]) >> g_BilinearShifts[0]) << 16;
					A00rr00bb |=  (s0 & g_BilinearMasks[2]) >> g_BilinearShifts[2];

					unsigned long B00aa00gg;
					unsigned long B00rr00bb;

					B00aa00gg  = ((s1 & g_BilinearMasks[3]) >> g_BilinearShifts[3]) << 16;
					B00aa00gg |=  (s1 & g_BilinearMasks[1]) >> g_BilinearShifts[1];
					B00rr00bb  = ((s1 & g_BilinearMasks[0]) >> g_BilinearShifts[0]) << 16;
					B00rr00bb |=  (s1 & g_BilinearMasks[2]) >> g_BilinearShifts[2];

					unsigned long Caaaagggg;
					unsigned long Crrrrbbbb;
					unsigned long Caarrggbb;

					Caaaagggg = A00aa00gg * v0 + B00aa00gg * v1;
					Crrrrbbbb = (A00rr00bb * v0 + B00rr00bb * v1) >> 8;
					Caarrggbb = (Caaaagggg & 0xFF00FF00) | (Crrrrbbbb & 0x00FF00FF);

					SrcValue = (((Caarrggbb & 0x00FF0000) >> 16) << g_BilinearShifts[0])
					           | (((Caarrggbb & 0x0000FF00) >> 8) << g_BilinearShifts[1])
					           | ((Caarrggbb & 0x000000FF) << g_BilinearShifts[2])
					           | (((Caarrggbb & 0xFF000000) >> 24) << g_BilinearShifts[3]);
				}

				// Advance the "x pointer"
				xstep += xratio;
				xstepOverflow = xstep & (~FIX16_MASK);
				xstep &= FIX16_MASK;

				// Check to see if a destination read is required.
				if (dstMatters)
				{
					if (dst.IsRotate)
					{
						switch (dst.Bpp)
						{
						case 16:
							*(unsigned short *)&dst.Value = *(unsigned short *)dst.GetPtr();
							break;
						case 32:
							*(unsigned long *)&dst.Value = *(unsigned long *)dst.GetPtr();
							break;
						case 24:
							{
								unsigned char *ptr = dst.GetPtr();
								dst.Value = (*ptr) + (*(ptr+1) << 8) + (*(ptr+2) << 16);
								break;
							}
						}
					}
					else
					{
						switch (dst.Bpp)
						{
						case 16:
							*(unsigned short *)&dst.Value = *(unsigned short *)dst.Ptr;
		

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -