Pinta.ImageManipulation.Effects.GaussianBlurEffect.RenderLine C# (CSharp) Method

RenderLine() protected method

protected RenderLine ( ISurface src, ISurface dest, Rectangle rect ) : void
src ISurface
dest ISurface
rect Rectangle
return void
		protected unsafe override void RenderLine (ISurface src, ISurface dest, Rectangle rect)
		{
			if (radius == 0) {
				// Copy src to dest
				return;
			}

			int r = radius;
			int wlen = w.Length;

			int localStoreSize = wlen * 6 * sizeof (long);
			byte* localStore = stackalloc byte[localStoreSize];
			byte* p = localStore;

			long* waSums = (long*)p;
			p += wlen * sizeof (long);

			long* wcSums = (long*)p;
			p += wlen * sizeof (long);

			long* aSums = (long*)p;
			p += wlen * sizeof (long);

			long* bSums = (long*)p;
			p += wlen * sizeof (long);

			long* gSums = (long*)p;
			p += wlen * sizeof (long);

			long* rSums = (long*)p;
			p += wlen * sizeof (long);

			int src_width = src.Width;
			int src_height = src.Height;

				if (rect.Height >= 1 && rect.Width >= 1) {
					for (int y = rect.Top; y <= rect.Bottom; ++y) {
						//Memory.SetToZero (localStore, (ulong)localStoreSize);

						long waSum = 0;
						long wcSum = 0;
						long aSum = 0;
						long bSum = 0;
						long gSum = 0;
						long rSum = 0;

						ColorBgra* dstPtr = dest.GetPointAddress (rect.Left, y);

						for (int wx = 0; wx < wlen; ++wx) {
							int srcX = rect.Left + wx - r;
							waSums[wx] = 0;
							wcSums[wx] = 0;
							aSums[wx] = 0;
							bSums[wx] = 0;
							gSums[wx] = 0;
							rSums[wx] = 0;

							if (srcX >= 0 && srcX < src_width) {
								for (int wy = 0; wy < wlen; ++wy) {
									int srcY = y + wy - r;

									if (srcY >= 0 && srcY < src_height) {
										ColorBgra c = src.GetPoint (srcX, srcY);
										int wp = w[wy];

										waSums[wx] += wp;
										wp *= c.A + (c.A >> 7);
										wcSums[wx] += wp;
										wp >>= 8;

										aSums[wx] += wp * c.A;
										bSums[wx] += wp * c.B;
										gSums[wx] += wp * c.G;
										rSums[wx] += wp * c.R;
									}
								}

								int wwx = w[wx];
								waSum += wwx * waSums[wx];
								wcSum += wwx * wcSums[wx];
								aSum += wwx * aSums[wx];
								bSum += wwx * bSums[wx];
								gSum += wwx * gSums[wx];
								rSum += wwx * rSums[wx];
							}
						}

						wcSum >>= 8;

						if (waSum == 0 || wcSum == 0) {
							dstPtr->Bgra = 0;
						} else {
							int alpha = (int)(aSum / waSum);
							int blue = (int)(bSum / wcSum);
							int green = (int)(gSum / wcSum);
							int red = (int)(rSum / wcSum);

							dstPtr->Bgra = ColorBgra.BgraToUInt32 (blue, green, red, alpha);
						}

						++dstPtr;

						for (int x = rect.Left + 1; x <= rect.Right; ++x) {
							for (int i = 0; i < wlen - 1; ++i) {
								waSums[i] = waSums[i + 1];
								wcSums[i] = wcSums[i + 1];
								aSums[i] = aSums[i + 1];
								bSums[i] = bSums[i + 1];
								gSums[i] = gSums[i + 1];
								rSums[i] = rSums[i + 1];
							}

							waSum = 0;
							wcSum = 0;
							aSum = 0;
							bSum = 0;
							gSum = 0;
							rSum = 0;

							int wx;
							for (wx = 0; wx < wlen - 1; ++wx) {
								long wwx = (long)w[wx];
								waSum += wwx * waSums[wx];
								wcSum += wwx * wcSums[wx];
								aSum += wwx * aSums[wx];
								bSum += wwx * bSums[wx];
								gSum += wwx * gSums[wx];
								rSum += wwx * rSums[wx];
							}

							wx = wlen - 1;

							waSums[wx] = 0;
							wcSums[wx] = 0;
							aSums[wx] = 0;
							bSums[wx] = 0;
							gSums[wx] = 0;
							rSums[wx] = 0;

							int srcX = x + wx - r;

							if (srcX >= 0 && srcX < src_width) {
								for (int wy = 0; wy < wlen; ++wy) {
									int srcY = y + wy - r;

									if (srcY >= 0 && srcY < src_height) {
										ColorBgra c = src.GetPoint (srcX, srcY);
										int wp = w[wy];

										waSums[wx] += wp;
										wp *= c.A + (c.A >> 7);
										wcSums[wx] += wp;
										wp >>= 8;

										aSums[wx] += wp * (long)c.A;
										bSums[wx] += wp * (long)c.B;
										gSums[wx] += wp * (long)c.G;
										rSums[wx] += wp * (long)c.R;
									}
								}

								int wr = w[wx];
								waSum += (long)wr * waSums[wx];
								wcSum += (long)wr * wcSums[wx];
								aSum += (long)wr * aSums[wx];
								bSum += (long)wr * bSums[wx];
								gSum += (long)wr * gSums[wx];
								rSum += (long)wr * rSums[wx];
							}

							wcSum >>= 8;

							if (waSum == 0 || wcSum == 0) {
								dstPtr->Bgra = 0;
							} else {
								int alpha = (int)(aSum / waSum);
								int blue = (int)(bSum / wcSum);
								int green = (int)(gSum / wcSum);
								int red = (int)(rSum / wcSum);

								dstPtr->Bgra = ColorBgra.BgraToUInt32 (blue, green, red, alpha);
							}

							++dstPtr;
						}
					}
			}
		}
		#endregion