public override unsafe void Render( EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, System.Drawing.Rectangle[] rois, int startIndex, int length) { // First we blur the source, and write the result to the destination surface // Then we apply Brightness/Contrast with the input as the dst, and the output as the dst // Third, we apply the Screen blend operation so that dst = dst OVER src ThreeAmountsConfigToken token = (ThreeAmountsConfigToken)parameters; AmountEffectConfigToken blurToken = new AmountEffectConfigToken(token.Amount1); this.blurEffect.Render(blurToken, dstArgs, srcArgs, rois, startIndex, length); BrightnessAndContrastAdjustmentConfigToken bcToken = new BrightnessAndContrastAdjustmentConfigToken(token.Amount2, token.Amount3); this.bcAdjustment.Render(bcToken, dstArgs, dstArgs, rois, startIndex, length); for (int i = startIndex; i < startIndex + length; ++i) { Rectangle roi = rois[i]; for (int y = roi.Top; y < roi.Bottom; ++y) { ColorBgra *dstPtr = dstArgs.Surface.GetPointAddressUnchecked(roi.Left, y); ColorBgra *srcPtr = srcArgs.Surface.GetPointAddressUnchecked(roi.Left, y); screenBlendOp.Apply(dstPtr, srcPtr, dstPtr, roi.Width); } } }
public unsafe override void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length) { AmountEffectConfigToken token = (AmountEffectConfigToken)parameters; foreach (Rectangle rect in rois) { RenderRect(token.Amount, srcArgs.Surface, dstArgs.Surface, rect); } }
public unsafe override void Render( EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, System.Drawing.Rectangle[] rois, int startIndex, int length) { AmountEffectConfigToken token = (AmountEffectConfigToken)parameters; float bulge = token.Amount; Surface dst = dstArgs.Surface; Surface src = srcArgs.Surface; float hw = dst.Width / 2.0f; float hh = dst.Height / 2.0f; float maxrad = Math.Min(hw, hh); float maxrad2 = maxrad * maxrad; float amt = token.Amount / 100.0f; for (int n = startIndex; n < startIndex + length; ++n) { Rectangle rect = rois[n]; for (int y = rect.Top; y < rect.Bottom; y++) { ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y); ColorBgra *srcPtr = src.GetPointAddressUnchecked(rect.Left, y); float v = y - hh; for (int x = rect.Left; x < rect.Right; x++) { float u = x - hw; float r = (float)Math.Sqrt(u * u + v * v); float rscale; rscale = (1.0f - (r / maxrad)); if (rscale > 0) { rscale = 1 - amt * rscale * rscale; float xp = u * rscale; float yp = v * rscale; *dstPtr = src.GetBilinearSampleWrapped(xp + hw, yp + hh); } else { *dstPtr = *srcPtr; } ++dstPtr; ++srcPtr; } } } }
public unsafe override void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length) { AmountEffectConfigToken aecd = (AmountEffectConfigToken)parameters; for (int i = startIndex; i < startIndex + length; ++i) { Rectangle rect = rois[i]; for (int y = rect.Top; y < rect.Bottom; ++y) { int yEnd = y + 1; for (int x = rect.Left; x < rect.Right; ++x) { Rectangle cellRect = GetCellBox(x, y, aecd.Amount); cellRect.Intersect(dstArgs.Bounds); ColorBgra color = ComputeCellColor(x, y, srcArgs, aecd.Amount); int xEnd = Math.Min(rect.Right, cellRect.Right); yEnd = Math.Min(rect.Bottom, cellRect.Bottom); for (int y2 = y; y2 < yEnd; ++y2) { ColorBgra *ptr = dstArgs.Surface.GetPointAddressUnchecked(x, y2); for (int x2 = x; x2 < xEnd; ++x2) { ptr->Bgra = color.Bgra; ++ptr; } } x = xEnd - 1; } y = yEnd - 1; } } }
protected override void InitialInitToken() { theEffectToken = new AmountEffectConfigToken(this.sliderInitialValue); }
public unsafe override void Render(EffectConfigToken token, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length) { AmountEffectConfigToken realToken = (AmountEffectConfigToken)token; Surface src = srcArgs.Surface; Surface dst = dstArgs.Surface; int width = src.Width; int height = src.Height; int r = realToken.Amount; Random localRandom = this.random; int * intensityCount = stackalloc int[256]; uint *avgRed = stackalloc uint[256]; uint *avgGreen = stackalloc uint[256]; uint *avgBlue = stackalloc uint[256]; uint *avgAlpha = stackalloc uint[256]; byte *intensityChoices = stackalloc byte[(1 + (r * 2)) * (1 + (r * 2))]; for (int ri = startIndex; ri < startIndex + length; ++ri) { Rectangle rect = rois[ri]; int rectTop = rect.Top; int rectBottom = rect.Bottom; int rectLeft = rect.Left; int rectRight = rect.Right; for (int y = rectTop; y < rectBottom; ++y) { ColorBgra *dstPtr = dst.GetPointAddress(rect.Left, y); int top = y - r; int bottom = y + r + 1; if (top < 0) { top = 0; } if (bottom > height) { bottom = height; } for (int x = rectLeft; x < rectRight; ++x) { int intensityChoicesIndex = 0; for (int i = 0; i < 256; ++i) { intensityCount[i] = 0; avgRed[i] = 0; avgGreen[i] = 0; avgBlue[i] = 0; avgAlpha[i] = 0; } int left = x - r; int right = x + r + 1; if (left < 0) { left = 0; } if (right > width) { right = width; } for (int j = top; j < bottom; ++j) { if (j < 0 || j >= height) { continue; } ColorBgra *srcPtr = src.GetPointAddressUnchecked(left, j); for (int i = left; i < right; ++i) { byte intensity = srcPtr->GetIntensityByte(); intensityChoices[intensityChoicesIndex] = intensity; ++intensityChoicesIndex; ++intensityCount[intensity]; avgRed[intensity] += srcPtr->R; avgGreen[intensity] += srcPtr->G; avgBlue[intensity] += srcPtr->B; avgAlpha[intensity] += srcPtr->A; ++srcPtr; } } int randNum; lock (localRandom) { randNum = localRandom.Next(intensityChoicesIndex); } byte chosenIntensity = intensityChoices[randNum]; byte R = (byte)(avgRed[chosenIntensity] / intensityCount[chosenIntensity]); byte G = (byte)(avgGreen[chosenIntensity] / intensityCount[chosenIntensity]); byte B = (byte)(avgBlue[chosenIntensity] / intensityCount[chosenIntensity]); byte A = (byte)(avgAlpha[chosenIntensity] / intensityCount[chosenIntensity]); *dstPtr = ColorBgra.FromBgra(B, G, R, A); ++dstPtr; // prepare the array for the next loop iteration for (int i = 0; i < intensityChoicesIndex; ++i) { intensityChoices[i] = 0; } } } } }
protected AmountEffectConfigToken(AmountEffectConfigToken copyMe) : base(copyMe) { this.amount = copyMe.amount; }
public override unsafe void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length) { AmountEffectConfigToken bect = (AmountEffectConfigToken)parameters; Surface dst = dstArgs.Surface; Surface src = srcArgs.Surface; int r = bect.Amount; int[] w = CreateGaussianBlurRow(bect.Amount); int wlen = w.Length; for (int ri = startIndex; ri < startIndex + length; ++ri) { Rectangle rect = rois[ri]; if (rect.Height >= 1 && rect.Width >= 1) { for (int y = rect.Top; y < rect.Bottom; ++y) { long * waSums = stackalloc long[wlen]; long * wcSums = stackalloc long[wlen]; long * aSums = stackalloc long[wlen]; long * bSums = stackalloc long[wlen]; long * gSums = stackalloc long[wlen]; long * rSums = stackalloc long[wlen]; long waSum = 0; long wcSum = 0; long aSum = 0; long bSum = 0; long gSum = 0; long rSum = 0; ColorBgra *dstPtr = dst.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(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.GetPointUnchecked(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 unsafe override void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length) { AmountEffectConfigToken token = (AmountEffectConfigToken)parameters; int w = dstArgs.Bounds.Width; int h = dstArgs.Bounds.Height; int fcx = w << 15; int fcy = h << 15; int fr = (int)((double)token.Amount * Math.PI * 65536.0 / 181.0); int strideSrc = srcArgs.Surface.Stride; int strideDst = dstArgs.Surface.Stride; ColorBgra *srcPtr = srcArgs.Surface.GetRowAddressUnchecked(0); ColorBgra *dstPtr = dstArgs.Surface.GetRowAddressUnchecked(0); for (int r = startIndex; r < startIndex + length; ++r) { Rectangle rect = rois[r]; for (int y = rect.Top; y < rect.Bottom; ++y) { ColorBgra *dstRow = (ColorBgra *)(strideDst * y + (byte *)dstPtr); for (int x = rect.Left; x < rect.Right; ++x) { int fx = (x << 16) - fcx; int fy = (y << 16) - fcy; const int n = 64; int fsr = fr / n; int sr = 0; int sg = 0; int sb = 0; int sa = 0; int sc = 0; ColorBgra *src = x + (ColorBgra *)((byte *)srcPtr + strideSrc * y); sr += src->R * src->A; sg += src->G * src->A; sb += src->B * src->A; sa += src->A; ++sc; int ox1 = fx; int ox2 = fx; int oy1 = fy; int oy2 = fy; for (int i = 0; i < n; ++i) { int u; int v; Rotate(ref ox1, ref oy1, fsr); Rotate(ref ox2, ref oy2, -fsr); u = ox1 + fcx + 32768 >> 16; v = oy1 + fcy + 32768 >> 16; if (u > 0 && v > 0 && u < w && v < h) { src = u + (ColorBgra *)((byte *)srcPtr + strideSrc * v); sr += src->R * src->A; sg += src->G * src->A; sb += src->B * src->A; sa += src->A; ++sc; } u = ox2 + fcx + 32768 >> 16; v = oy2 + fcy + 32768 >> 16; if (u > 0 && v > 0 && u < w && v < h) { src = u + (ColorBgra *)((byte *)srcPtr + strideSrc * v); sr += src->R * src->A; sg += src->G * src->A; sb += src->B * src->A; sa += src->A; ++sc; } } if (sa > 0) { dstRow[x] = ColorBgra.FromBgra( Utility.ClampToByte(sb / sa), Utility.ClampToByte(sg / sa), Utility.ClampToByte(sr / sa), Utility.ClampToByte(sa / sc) ); } else { dstRow[x].Bgra = 0; } } } } }
public unsafe override void Render( EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, System.Drawing.Rectangle[] rois, int startIndex, int length) { // First we blur the source, and write the result to the destination surface // Then we apply Brightness/Contrast with the input as the dst, and the output as the dst // Third, we apply the Screen blend operation so that dst = dst OVER src ThreeAmountsConfigToken token = (ThreeAmountsConfigToken)parameters; AmountEffectConfigToken blurToken = new AmountEffectConfigToken(token.Amount1); this.blurEffect.Render(blurToken, dstArgs, srcArgs, rois, startIndex, length); BrightnessAndContrastAdjustmentConfigToken bcToken = new BrightnessAndContrastAdjustmentConfigToken(token.Amount2, token.Amount3); this.bcAdjustment.Render(bcToken, dstArgs, dstArgs, rois, startIndex, length); for (int i = startIndex; i < startIndex + length; ++i) { Rectangle roi = rois[i]; for (int y = roi.Top; y < roi.Bottom; ++y) { ColorBgra* dstPtr = dstArgs.Surface.GetPointAddressUnchecked(roi.Left, y); ColorBgra* srcPtr = srcArgs.Surface.GetPointAddressUnchecked(roi.Left, y); screenBlendOp.Apply(dstPtr, srcPtr, dstPtr, roi.Width); } } }
public unsafe override void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length) { AmountEffectConfigToken token = (AmountEffectConfigToken)parameters; Surface dst = dstArgs.Surface; Surface src = srcArgs.Surface; long w = dst.Width; long h = dst.Height; long fcx = w << 15; long fcy = h << 15; long fz = token.Amount; for (int r = startIndex; r < startIndex + length; ++r) { Rectangle rect = rois[r]; for (int y = rect.Top; y < rect.Bottom; ++y) { ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y); ColorBgra *srcPtr = src.GetPointAddressUnchecked(rect.Left, y); for (int x = rect.Left; x < rect.Right; ++x) { long fx = (x << 16) - fcx; long fy = (y << 16) - fcy; const int n = 64; int sr = 0; int sg = 0; int sb = 0; int sa = 0; int sc = 0; sr += srcPtr->R * srcPtr->A; sg += srcPtr->G * srcPtr->A; sb += srcPtr->B * srcPtr->A; sa += srcPtr->A; ++sc; for (int i = 0; i < n; ++i) { fx -= ((fx >> 4) * fz) >> 10; fy -= ((fy >> 4) * fz) >> 10; int u = (int)(fx + fcx + 32768 >> 16); int v = (int)(fy + fcy + 32768 >> 16); ColorBgra *srcPtr2 = src.GetPointAddressUnchecked(u, v); sr += srcPtr2->R * srcPtr2->A; sg += srcPtr2->G * srcPtr2->A; sb += srcPtr2->B * srcPtr2->A; sa += srcPtr2->A; ++sc; } if (sa != 0) { *dstPtr = ColorBgra.FromBgra( Utility.ClampToByte(sb / sa), Utility.ClampToByte(sg / sa), Utility.ClampToByte(sr / sa), Utility.ClampToByte(sa / sc)); } else { dstPtr->Bgra = 0; } ++srcPtr; ++dstPtr; } } } }