public unsafe override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois) { Gdk.Point[] pointOffsets = RecalcPointOffsets(Data.Fragments, Data.Rotation, Data.Distance); int poLength = pointOffsets.Length; Gdk.Point *pointOffsetsPtr = stackalloc Gdk.Point[poLength]; for (int i = 0; i < poLength; ++i) { pointOffsetsPtr[i] = pointOffsets[i]; } ColorBgra *samples = stackalloc ColorBgra[poLength]; // Cache these for a massive performance boost int src_width = src.Width; int src_height = src.Height; ColorBgra *src_data_ptr = (ColorBgra *)src.DataPtr; foreach (Gdk.Rectangle rect in rois) { for (int y = rect.Top; y <= rect.GetBottom(); y++) { ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y); for (int x = rect.Left; x <= rect.GetRight(); x++) { int sampleCount = 0; for (int i = 0; i < poLength; ++i) { int u = x - pointOffsetsPtr[i].X; int v = y - pointOffsetsPtr[i].Y; if (u >= 0 && u < src_width && v >= 0 && v < src_height) { samples[sampleCount] = src.GetPointUnchecked(src_data_ptr, src_width, u, v); ++sampleCount; } } *dstPtr = ColorBgra.Blend(samples, sampleCount); ++dstPtr; } } } }
public unsafe override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois) { float twist = Data.Amount; float hw = dst.Width / 2.0f; float hh = dst.Height / 2.0f; float maxrad = Math.Min(hw, hh); twist = twist * twist * Math.Sign(twist); int aaLevel = Data.Antialias; int aaSamples = aaLevel * aaLevel + 1; PointD *aaPoints = stackalloc PointD[aaSamples]; for (int i = 0; i < aaSamples; ++i) { PointD pt = new PointD( ((i * aaLevel) / (float)aaSamples), i / (float)aaSamples); pt.X -= (int)pt.X; aaPoints[i] = pt; } int src_width = src.Width; ColorBgra *src_data_ptr = (ColorBgra *)src.DataPtr; foreach (var rect in rois) { for (int y = rect.Top; y < rect.Bottom; y++) { float j = y - hh; ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y); ColorBgra *srcPtr = src.GetPointAddressUnchecked(src_data_ptr, src_width, rect.Left, y); for (int x = rect.Left; x < rect.Right; x++) { float i = x - hw; if (i * i + j * j > (maxrad + 1) * (maxrad + 1)) { *dstPtr = *srcPtr; } else { int b = 0; int g = 0; int r = 0; int a = 0; for (int p = 0; p < aaSamples; ++p) { float u = i + (float)aaPoints[p].X; float v = j + (float)aaPoints[p].Y; double rad = Math.Sqrt(u * u + v * v); double theta = Math.Atan2(v, u); double t = 1 - rad / maxrad; t = (t < 0) ? 0 : (t * t * t); theta += (t * twist) / 100; ColorBgra sample = src.GetPointUnchecked(src_data_ptr, src_width, (int)(hw + (float)(rad * Math.Cos(theta))), (int)(hh + (float)(rad * Math.Sin(theta)))); b += sample.B; g += sample.G; r += sample.R; a += sample.A; } *dstPtr = ColorBgra.FromBgra( (byte)(b / aaSamples), (byte)(g / aaSamples), (byte)(r / aaSamples), (byte)(a / aaSamples)); } ++dstPtr; ++srcPtr; } } } }
public unsafe void RenderColorDifferenceEffect(double[][] weights, ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois) { Gdk.Rectangle src_rect = src.GetBounds(); // Cache these for a massive performance boost int src_width = src.Width; ColorBgra *src_data_ptr = (ColorBgra *)src.DataPtr; foreach (Gdk.Rectangle rect in rois) { // loop through each line of target rectangle for (int y = rect.Y; y < rect.Y + rect.Height; ++y) { int fyStart = 0; int fyEnd = 3; if (y == src_rect.Y) { fyStart = 1; } if (y == src_rect.Y + src_rect.Height - 1) { fyEnd = 2; } // loop through each point in the line ColorBgra *dstPtr = dest.GetPointAddressUnchecked(rect.X, y); for (int x = rect.X; x < rect.X + rect.Width; ++x) { int fxStart = 0; int fxEnd = 3; if (x == src_rect.X) { fxStart = 1; } if (x == src_rect.X + src_rect.Width - 1) { fxEnd = 2; } // loop through each weight double rSum = 0.0; double gSum = 0.0; double bSum = 0.0; for (int fy = fyStart; fy < fyEnd; ++fy) { for (int fx = fxStart; fx < fxEnd; ++fx) { double weight = weights[fy][fx]; ColorBgra c = src.GetPointUnchecked(src_data_ptr, src_width, x - 1 + fx, y - 1 + fy); rSum += weight * (double)c.R; gSum += weight * (double)c.G; bSum += weight * (double)c.B; } } int iRsum = (int)rSum; int iGsum = (int)gSum; int iBsum = (int)bSum; if (iRsum > 255) { iRsum = 255; } if (iGsum > 255) { iGsum = 255; } if (iBsum > 255) { iBsum = 255; } if (iRsum < 0) { iRsum = 0; } if (iGsum < 0) { iGsum = 0; } if (iBsum < 0) { iBsum = 0; } *dstPtr = ColorBgra.FromBgra((byte)iBsum, (byte)iGsum, (byte)iRsum, 255); ++dstPtr; } } } }
public unsafe override void Render(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois) { if (Data.Radius == 0) { // Copy src to dest return; } int r = Data.Radius; int[] w = CreateGaussianBlurRow(r); 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); // Cache these for a massive performance boost int src_width = src.Width; int src_height = src.Height; ColorBgra *src_data_ptr = (ColorBgra *)src.DataPtr; foreach (Gdk.Rectangle rect in rois) { if (rect.Height >= 1 && rect.Width >= 1) { for (int y = rect.Top; y <= rect.GetBottom(); ++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.GetPointAddressUnchecked(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.GetPointUnchecked(src_data_ptr, src_width, 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.GetRight(); ++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.GetPointUnchecked(src_data_ptr, src_width, 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; } } } } }
public static unsafe ColorBgra GetBilinearSampleWrapped(this ImageSurface src, ColorBgra *srcDataPtr, int srcWidth, int srcHeight, float x, float y) { if (!Utility.IsNumber(x) || !Utility.IsNumber(y)) { return(ColorBgra.Transparent); } float u = x; float v = y; unchecked { int iu = (int)Math.Floor(u); uint sxfrac = (uint)(256 * (u - (float)iu)); uint sxfracinv = 256 - sxfrac; int iv = (int)Math.Floor(v); uint syfrac = (uint)(256 * (v - (float)iv)); uint syfracinv = 256 - syfrac; uint wul = (uint)(sxfracinv * syfracinv); uint wur = (uint)(sxfrac * syfracinv); uint wll = (uint)(sxfracinv * syfrac); uint wlr = (uint)(sxfrac * syfrac); int sx = iu; if (sx < 0) { sx = (srcWidth - 1) + ((sx + 1) % srcWidth); } else if (sx > (srcWidth - 1)) { sx = sx % srcWidth; } int sy = iv; if (sy < 0) { sy = (srcHeight - 1) + ((sy + 1) % srcHeight); } else if (sy > (srcHeight - 1)) { sy = sy % srcHeight; } int sleft = sx; int sright; if (sleft == (srcWidth - 1)) { sright = 0; } else { sright = sleft + 1; } int stop = sy; int sbottom; if (stop == (srcHeight - 1)) { sbottom = 0; } else { sbottom = stop + 1; } ColorBgra cul = src.GetPointUnchecked(srcDataPtr, srcWidth, sleft, stop); ColorBgra cur = src.GetPointUnchecked(srcDataPtr, srcWidth, sright, stop); ColorBgra cll = src.GetPointUnchecked(srcDataPtr, srcWidth, sleft, sbottom); ColorBgra clr = src.GetPointUnchecked(srcDataPtr, srcWidth, sright, sbottom); ColorBgra c = ColorBgra.BlendColors4W16IP(cul, wul, cur, wur, cll, wll, clr, wlr); return(c); } }
unsafe public override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois) { double[,] weights = Weights; var srcWidth = src.Width; var srcHeight = src.Height; ColorBgra *src_data_ptr = (ColorBgra *)src.DataPtr; foreach (var rect in rois) { // loop through each line of target rectangle for (int y = rect.Top; y < rect.Bottom; ++y) { int fyStart = 0; int fyEnd = 3; if (y == 0) { fyStart = 1; } if (y == srcHeight - 1) { fyEnd = 2; } // loop through each point in the line ColorBgra *dstPtr = dst.GetPointAddress(rect.Left, y); for (int x = rect.Left; x < rect.Right; ++x) { int fxStart = 0; int fxEnd = 3; if (x == 0) { fxStart = 1; } if (x == srcWidth - 1) { fxEnd = 2; } // loop through each weight double sum = 0.0; for (int fy = fyStart; fy < fyEnd; ++fy) { for (int fx = fxStart; fx < fxEnd; ++fx) { double weight = weights[fy, fx]; ColorBgra c = src.GetPointUnchecked(src_data_ptr, srcWidth, x - 1 + fx, y - 1 + fy); double intensity = (double)c.GetIntensityByte(); sum += weight * intensity; } } int iSum = (int)sum; iSum += 128; if (iSum > 255) { iSum = 255; } if (iSum < 0) { iSum = 0; } *dstPtr = ColorBgra.FromBgra((byte)iSum, (byte)iSum, (byte)iSum, 255); ++dstPtr; } } } }