public unsafe override void Render (ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois) { bacAdjustment.Data.Brightness = -Data.ColorRange; bacAdjustment.Data.Contrast = -Data.ColorRange; bacAdjustment.Render (src, dest, rois); blurEffect.Data.Radius = Data.PencilTipSize; blurEffect.Render (src, dest, rois); invertEffect.Render (dest, dest, rois); desaturateOp.Apply (dest, dest, rois); ColorBgra* dst_dataptr = (ColorBgra*)dest.DataPtr; int dst_width = dest.Width; ColorBgra* src_dataptr = (ColorBgra*)src.DataPtr; int src_width = src.Width; foreach (Gdk.Rectangle roi in rois) { for (int y = roi.Top; y <= roi.GetBottom (); ++y) { ColorBgra* srcPtr = src.GetPointAddressUnchecked (src_dataptr, src_width, roi.X, y); ColorBgra* dstPtr = dest.GetPointAddressUnchecked (dst_dataptr, dst_width, roi.X, y); for (int x = roi.Left; x <= roi.GetRight (); ++x) { ColorBgra srcGrey = desaturateOp.Apply (*srcPtr); ColorBgra sketched = colorDodgeOp.Apply (srcGrey, *dstPtr); *dstPtr = sketched; ++srcPtr; ++dstPtr; } } } }
public unsafe override void Render (ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois) { PointD start = new PointD (0, 0); double theta = ((double)(Data.Angle + 180) * 2 * Math.PI) / 360.0; double alpha = (double)Data.Distance; PointD end = new PointD ((float)alpha * Math.Cos (theta), (float)(-alpha * Math.Sin (theta))); if (Data.Centered) { start.X = -end.X / 2.0f; start.Y = -end.Y / 2.0f; end.X /= 2.0f; end.Y /= 2.0f; } PointD[] points = new PointD[((1 + Data.Distance) * 3) / 2]; if (points.Length == 1) { points[0] = new PointD (0, 0); } else { for (int i = 0; i < points.Length; ++i) { float frac = (float)i / (float)(points.Length - 1); points[i] = Utility.Lerp (start, end, frac); } } ColorBgra* samples = stackalloc ColorBgra[points.Length]; ColorBgra* src_dataptr = (ColorBgra*)src.DataPtr; int src_width = src.Width; int src_height = src.Height; 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 j = 0; j < points.Length; ++j) { PointD pt = new PointD (points[j].X + (float)x, points[j].Y + (float)y); if (pt.X >= 0 && pt.Y >= 0 && pt.X <= (src_width - 1) && pt.Y <= (src_height - 1)) { samples[sampleCount] = src.GetBilinearSample (src_dataptr, src_width, src_height, (float)pt.X, (float)pt.Y); ++sampleCount; } } *dstPtr = ColorBgra.Blend (samples, sampleCount); ++dstPtr; } } } }
unsafe public override void Render (ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois) { float bulge = (float)Data.Amount; float hw = dst.Width / 2f; float hh = dst.Height / 2f; float maxrad = Math.Min (hw, hh); float amt = bulge / 100f; hh = hh + (float)Data.Offset.Y * hh; hw = hw + (float)Data.Offset.X * hw; 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); ColorBgra* srcPtr = src.GetPointAddressUnchecked (src_data_ptr, src_width, rect.Left, y); float v = y - hh; for (int x = rect.Left; x <= rect.GetRight (); x++) { float u = x - hw; float r = (float)Math.Sqrt (u * u + v * v); float rscale1 = (1f - (r / maxrad)); if (rscale1 > 0) { float rscale2 = 1 - amt * rscale1 * rscale1; float xp = u * rscale2; float yp = v * rscale2; *dstPtr = src.GetBilinearSampleClamped (src_data_ptr, src_width, src_height, xp + hw, yp + hh); } else { *dstPtr = *srcPtr; } ++dstPtr; ++srcPtr; } } } }
public unsafe override void Render (ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois) { blurEffect.Data.Radius = Data.Radius; blurEffect.Render (src, dest, rois); contrastEffect.Data.Brightness = Data.Brightness; contrastEffect.Data.Contrast = Data.Contrast; contrastEffect.Render (dest, dest, rois); foreach (Gdk.Rectangle roi in rois) { for (int y = roi.Top; y <= roi.GetBottom (); ++y) { ColorBgra* dstPtr = dest.GetPointAddressUnchecked (roi.Left, y); ColorBgra* srcPtr = src.GetPointAddressUnchecked (roi.Left, y); screenBlendOp.Apply (dstPtr, srcPtr, dstPtr, roi.Width); } } }
protected override unsafe void AddSurfaceRectangleToHistogram(ImageSurface surface, Gdk.Rectangle rect) { long[] histogramB = histogram[0]; long[] histogramG = histogram[1]; long[] histogramR = histogram[2]; int rect_right = rect.GetRight (); for (int y = rect.Y; y <= rect.GetBottom (); ++y) { ColorBgra* ptr = surface.GetPointAddressUnchecked(rect.X, y); for (int x = rect.X; x <= rect_right; ++x) { ++histogramB[ptr->B]; ++histogramG[ptr->G]; ++histogramR[ptr->R]; ++ptr; } } }
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 dest, Gdk.Rectangle[] rois) { if (!table_calculated) Calculate (); foreach (Gdk.Rectangle rect in rois) { for (int y = rect.Top; y <= rect.GetBottom (); y++) { ColorBgra* srcRowPtr = src.GetPointAddressUnchecked (rect.Left, y); ColorBgra* dstRowPtr = dest.GetPointAddressUnchecked (rect.Left, y); ColorBgra* dstRowEndPtr = dstRowPtr + rect.Width; if (divide == 0) { while (dstRowPtr < dstRowEndPtr) { ColorBgra col = *srcRowPtr; int i = col.GetIntensityByte (); uint c = rgbTable[i]; dstRowPtr->Bgra = (col.Bgra & 0xff000000) | c | (c << 8) | (c << 16); ++dstRowPtr; ++srcRowPtr; } } else { while (dstRowPtr < dstRowEndPtr) { ColorBgra col = *srcRowPtr; int i = col.GetIntensityByte (); int shiftIndex = i * 256; col.R = rgbTable[shiftIndex + col.R]; col.G = rgbTable[shiftIndex + col.G]; col.B = rgbTable[shiftIndex + col.B]; *dstRowPtr = col; ++dstRowPtr; ++srcRowPtr; } } } } }
protected unsafe virtual void RenderEffect(ImageSurface src, ImageSurface dst, Gdk.Rectangle roi) { ColorBgra* src_data_ptr = (ColorBgra*)src.DataPtr; int src_width = src.Width; ColorBgra* dst_data_ptr = (ColorBgra*)dst.DataPtr; int dst_width = dst.Width; for (int y = roi.Y; y < roi.Bottom; ++y) { ColorBgra* srcPtr = src.GetPointAddressUnchecked (src_data_ptr, src_width, roi.X, y); ColorBgra* dstPtr = dst.GetPointAddressUnchecked (dst_data_ptr, dst_width, roi.X, y); RenderLine (srcPtr, dstPtr, roi.Width); } }
public unsafe override void RenderEffect(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois) { const double jr = 0.3125; const double ji = 0.03; int w = dst.Width; int h = dst.Height; double invH = 1.0 / h; double invZoom = 1.0 / Data.Zoom; double invQuality = 1.0 / Data.Quality; double aspect = (double)h / (double)w; int count = Data.Quality * Data.Quality + 1; double invCount = 1.0 / (double)count; double angleTheta = (Data.Angle * Math.PI * 2) / 360.0; ColorBgra* dst_dataptr = (ColorBgra*)dst.DataPtr; int dst_width = dst.Width; foreach (Gdk.Rectangle rect in rois) { for (int y = rect.Top; y < rect.Bottom; y++) { ColorBgra* dstPtr = dst.GetPointAddressUnchecked (dst_dataptr, dst_width, rect.Left, y); for (int x = rect.Left; x < rect.Right; x++) { int r = 0; int g = 0; int b = 0; int a = 0; for (double i = 0; i < count; i++) { double u = (2.0 * x - w + (i * invCount)) * invH; double v = (2.0 * y - h + ((i * invQuality) % 1)) * invH; double radius = Math.Sqrt ((u * u) + (v * v)); double radiusP = radius; double theta = Math.Atan2 (v, u); double thetaP = theta + angleTheta; double uP = radiusP * Math.Cos (thetaP); double vP = radiusP * Math.Sin (thetaP); double jX = (uP - vP * aspect) * invZoom; double jY = (vP + uP * aspect) * invZoom; double j = Julia (jX, jY, jr, ji); double c = Data.Factor * j; b += Utility.ClampToByte (c - 768); g += Utility.ClampToByte (c - 512); r += Utility.ClampToByte (c - 256); a += Utility.ClampToByte (c - 0); } *dstPtr = ColorBgra.FromBgra (Utility.ClampToByte (b / count), Utility.ClampToByte (g / count), Utility.ClampToByte (r / count), Utility.ClampToByte (a / count)); ++dstPtr; } } } }
public void Apply(ImageSurface dst, ImageSurface src, Gdk.Rectangle roi) { for (int y = roi.Y; y < roi.Bottom; ++y) { ColorBgra* dstPtr = dst.GetPointAddressUnchecked (roi.X, y); ColorBgra* srcPtr = src.GetPointAddressUnchecked (roi.X, y); Apply (dstPtr, srcPtr, roi.Width); } }
//same as RenderRect, except the histogram is alpha-weighted instead of keeping a separate alpha channel histogram. public unsafe void RenderRectWithAlpha( int rad, ImageSurface src, ImageSurface dst, Rectangle rect) { int width = src.Width; int height = src.Height; int* leadingEdgeX = stackalloc int[rad + 1]; int stride = src.Stride / sizeof(ColorBgra); // approximately (rad + 0.5)^2 int cutoff = ((rad * 2 + 1) * (rad * 2 + 1) + 2) / 4; for (int v = 0; v <= rad; ++v) { for (int u = 0; u <= rad; ++u) { if (u * u + v * v <= cutoff) { leadingEdgeX[v] = u; } } } const int hLength = 256; int* hb = stackalloc int[hLength]; int* hg = stackalloc int[hLength]; int* hr = stackalloc int[hLength]; for (int y = (int)rect.Y; y < rect.Y + rect.Height; y++) { MemorySetToZero (hb, hLength); MemorySetToZero (hg, hLength); MemorySetToZero (hr, hLength); int area = 0; int sum = 0; ColorBgra* ps = src.GetPointAddressUnchecked((int)rect.X, y); ColorBgra* pd = dst.GetPointAddressUnchecked((int)rect.X, y); // assert: v + y >= 0 int top = -Math.Min(rad, y); // assert: v + y <= height - 1 int bottom = Math.Min(rad, height - 1 - y); // assert: u + x >= 0 int left = -Math.Min(rad, (int)rect.X); // assert: u + x <= width - 1 int right = Math.Min(rad, width - 1 - (int)rect.Y); for (int v = top; v <= bottom; ++v) { ColorBgra* psamp = src.GetPointAddressUnchecked((int)rect.Y + left, y + v); for (int u = left; u <= right; ++u) { byte w = psamp->A; if ((u * u + v * v) <= cutoff) { ++area; sum += w; hb[psamp->B] += w; hg[psamp->G] += w; hr[psamp->R] += w; } ++psamp; } } for (int x = (int)rect.X; x < rect.X + rect.Width; x++) { *pd = ApplyWithAlpha(*ps, area, sum, hb, hg, hr); // assert: u + x >= 0 left = -Math.Min(rad, x); // assert: u + x <= width - 1 right = Math.Min(rad + 1, width - 1 - x); // Subtract trailing edge top half int v = -1; while (v >= top) { int u = leadingEdgeX[-v]; if (-u >= left) { break; } --v; } while (v >= top) { int u = leadingEdgeX[-v]; ColorBgra* p = unchecked(ps + (v * stride)) - u; byte w = p->A; hb[p->B] -= w; hg[p->G] -= w; hr[p->R] -= w; sum -= w; --area; --v; } // add leading edge top half v = -1; while (v >= top) { int u = leadingEdgeX[-v]; if (u + 1 <= right) { break; } --v; } while (v >= top) { int u = leadingEdgeX[-v]; ColorBgra* p = unchecked(ps + (v * stride)) + u + 1; byte w = p->A; hb[p->B] += w; hg[p->G] += w; hr[p->R] += w; sum += w; ++area; --v; } // Subtract trailing edge bottom half v = 0; while (v <= bottom) { int u = leadingEdgeX[v]; if (-u >= left) { break; } ++v; } while (v <= bottom) { int u = leadingEdgeX[v]; ColorBgra* p = ps + v * stride - u; byte w = p->A; hb[p->B] -= w; hg[p->G] -= w; hr[p->R] -= w; sum -= w; --area; ++v; } // add leading edge bottom half v = 0; while (v <= bottom) { int u = leadingEdgeX[v]; if (u + 1 <= right) { break; } ++v; } while (v <= bottom) { int u = leadingEdgeX[v]; ColorBgra* p = ps + v * stride + u + 1; byte w = p->A; hb[p->B] += w; hg[p->G] += w; hr[p->R] += w; sum += w; ++area; ++v; } ++ps; ++pd; } } }
public unsafe override void Render (ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois) { this.intensity = Data.Intensity; this.colorSaturation = Data.ColorSaturation; this.coverage = 0.01 * Data.Coverage; int dev = this.intensity * this.intensity / 4; int sat = this.colorSaturation * 4096 / 100; if (threadRand == null) { threadRand = new Random (unchecked (System.Threading.Thread.CurrentThread.GetHashCode () ^ unchecked ((int)DateTime.Now.Ticks))); } Random localRand = threadRand; int[] localLookup = lookup; foreach (Gdk.Rectangle rect in rois) { for (int y = rect.Top; y <= rect.GetBottom (); ++y) { ColorBgra* srcPtr = src.GetPointAddressUnchecked (rect.Left, y); ColorBgra* dstPtr = dst.GetPointAddressUnchecked (rect.Left, y); for (int x = 0; x < rect.Width; ++x) { if (localRand.NextDouble () > this.coverage) { *dstPtr = *srcPtr; } else { int r; int g; int b; int i; r = localLookup[localRand.Next (tableSize)]; g = localLookup[localRand.Next (tableSize)]; b = localLookup[localRand.Next (tableSize)]; i = (4899 * r + 9618 * g + 1867 * b) >> 14; r = i + (((r - i) * sat) >> 12); g = i + (((g - i) * sat) >> 12); b = i + (((b - i) * sat) >> 12); dstPtr->R = Utility.ClampToByte (srcPtr->R + ((r * dev + 32768) >> 16)); dstPtr->G = Utility.ClampToByte (srcPtr->G + ((g * dev + 32768) >> 16)); dstPtr->B = Utility.ClampToByte (srcPtr->B + ((b * dev + 32768) >> 16)); dstPtr->A = srcPtr->A; } ++srcPtr; ++dstPtr; } } } }
private unsafe bool ProcessGradientLine(byte startAlpha, byte endAlpha, int y, Rectangle rect, ImageSurface surface, ColorBgra* src_data_ptr, int src_width) { var pixelPtr = surface.GetPointAddressUnchecked(src_data_ptr, src_width, rect.Left, y); var right = rect.GetRight (); if (alphaOnly && alphaBlending) { for (var x = rect.Left; x <= right; ++x) { var lerpByte = ComputeByteLerp(x, y); var lerpAlpha = lerpAlphas[lerpByte]; var resultAlpha = Utility.FastScaleByteByByte(pixelPtr->A, lerpAlpha); pixelPtr->A = resultAlpha; ++pixelPtr; } } else if (alphaOnly && !alphaBlending) { for (var x = rect.Left; x <= right; ++x) { var lerpByte = ComputeByteLerp(x, y); var lerpAlpha = lerpAlphas[lerpByte]; pixelPtr->A = lerpAlpha; ++pixelPtr; } } else if (!alphaOnly && (alphaBlending && (startAlpha != 255 || endAlpha != 255))) { // If we're doing all color channels, and we're doing alpha blending, and if alpha blending is necessary for (var x = rect.Left; x <= right; ++x) { var lerpByte = ComputeByteLerp(x, y); var lerpColor = lerpColors[lerpByte]; var result = normalBlendOp.Apply(*pixelPtr, lerpColor); *pixelPtr = result; ++pixelPtr; } //if (!this.alphaOnly && !this.alphaBlending) // or sC.A == 255 && eC.A == 255 } else { for (var x = rect.Left; x <= right; ++x) { var lerpByte = ComputeByteLerp(x, y); var lerpColor = lerpColors[lerpByte]; *pixelPtr = lerpColor; ++pixelPtr; } } return true; }
private static unsafe void RenderClouds(ImageSurface surface, Gdk.Rectangle rect, int scale, byte seed, double power, ColorBgra colorFrom, ColorBgra colorTo) { int w = surface.Width; int h = surface.Height; for (int y = rect.Top; y < rect.Bottom; ++y) { ColorBgra* ptr = surface.GetPointAddressUnchecked(rect.Left, y); int dy = 2 * y - h; for (int x = rect.Left; x < rect.Right; ++x) { int dx = 2 * x - w; double val = 0; double mult = 1; int div = scale; for (int i = 0; i < 12 && mult > 0.03 && div > 0; ++i) { double dxr = 65536 + (double)dx / (double)div; double dyr = 65536 + (double)dy / (double)div; int dxd = (int)dxr; int dyd = (int)dyr; dxr -= dxd; dyr -= dyd; double noise = Noise( unchecked((byte)dxd), unchecked((byte)dyd), dxr, //(double)dxr / div, dyr, //(double)dyr / div, (byte)(seed ^ i)); val += noise * mult; div /= 2; mult *= power; } *ptr = ColorBgra.Lerp(colorFrom, colorTo, (val + 1) / 2); ++ptr; } } }
public unsafe override void RenderEffect(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 override void RenderEffect(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois) { var cellSize = Data.CellSize; Gdk.Rectangle src_bounds = src.GetBounds (); Gdk.Rectangle dest_bounds = dest.GetBounds (); foreach (var rect in rois) { for (int y = rect.Top; y < rect.Bottom; ++y) { int yEnd = y + 1; for (int x = rect.Left; x < rect.Right; ++x) { var cellRect = GetCellBox (x, y, cellSize); cellRect.Intersect (dest_bounds); var color = ComputeCellColor (x, y, src, cellSize, src_bounds); int xEnd = Math.Min (rect.Right, cellRect.Right); yEnd = Math.Min (rect.Bottom, cellRect.Bottom); for (int y2 = y; y2 < yEnd; ++y2) { ColorBgra* ptr = dest.GetPointAddressUnchecked (x, y2); for (int x2 = x; x2 < xEnd; ++x2) { ptr->Bgra = color.Bgra; ++ptr; } } x = xEnd - 1; } y = yEnd - 1; } } }
public unsafe override void RenderEffect(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois) { int width = src.Width; int height = src.Height; int r = Data.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))]; int src_width = src.Width; ColorBgra* src_data_ptr = (ColorBgra*)src.DataPtr; foreach (var rect in rois) { 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 (src_data_ptr, src_width, 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; } } } } }
public void Apply(ImageSurface dst, ImageSurface src, Gdk.Rectangle roi) { ColorBgra* src_data_ptr = (ColorBgra*)src.DataPtr; int src_width = src.Width; ColorBgra* dst_data_ptr = (ColorBgra*)dst.DataPtr; int dst_width = dst.Width; for (int y = roi.Y; y < roi.Bottom; ++y) { ColorBgra* dstPtr = dst.GetPointAddressUnchecked (dst_data_ptr, dst_width, roi.X, y); ColorBgra* srcPtr = src.GetPointAddressUnchecked (src_data_ptr, src_width, roi.X, y); Apply (dstPtr, srcPtr, roi.Width); } }
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 unsafe void RenderRect( int rad, ImageSurface src, ImageSurface dst, Gdk.Rectangle rect) { int width = src.Width; int height = src.Height; int* leadingEdgeX = stackalloc int[rad + 1]; int stride = src.Stride / sizeof(ColorBgra); // approximately (rad + 0.5)^2 int cutoff = ((rad * 2 + 1) * (rad * 2 + 1) + 2) / 4; for (int v = 0; v <= rad; ++v) { for (int u = 0; u <= rad; ++u) { if (u * u + v * v <= cutoff) { leadingEdgeX[v] = u; } } } const int hLength = 256; int* hb = stackalloc int[hLength]; int* hg = stackalloc int[hLength]; int* hr = stackalloc int[hLength]; int* ha = stackalloc int[hLength]; uint hSize = (uint)(sizeof(int) * hLength); for (int y = rect.Top; y <= rect.GetBottom (); ++y) { SetToZero(hb, hSize); SetToZero(hg, hSize); SetToZero(hr, hSize); SetToZero(ha, hSize); int area = 0; ColorBgra* ps = src.GetPointAddressUnchecked(rect.Left, y); ColorBgra* pd = dst.GetPointAddressUnchecked(rect.Left, y); // assert: v + y >= 0 int top = -Math.Min(rad, y); // assert: v + y <= height - 1 int bottom = Math.Min(rad, height - 1 - y); // assert: u + x >= 0 int left = -Math.Min(rad, rect.Left); // assert: u + x <= width - 1 int right = Math.Min(rad, width - 1 - rect.Left); for (int v = top; v <= bottom; ++v) { ColorBgra* psamp = src.GetPointAddressUnchecked(rect.Left + left, y + v); for (int u = left; u <= right; ++u) { if ((u * u + v * v) <= cutoff) { ++area; ++hb[psamp->B]; ++hg[psamp->G]; ++hr[psamp->R]; ++ha[psamp->A]; } ++psamp; } } for (int x = rect.Left; x <= rect.GetRight (); x++) { *pd = Apply(*ps, area, hb, hg, hr, ha); // assert: u + x >= 0 left = -Math.Min(rad, x); // assert: u + x <= width - 1 right = Math.Min(rad + 1, width - 1 - x); // Subtract trailing edge top half int v = -1; while (v >= top) { int u = leadingEdgeX[-v]; if (-u >= left) { break; } --v; } while (v >= top) { int u = leadingEdgeX[-v]; ColorBgra* p = unchecked(ps + (v * stride)) - u; --hb[p->B]; --hg[p->G]; --hr[p->R]; --ha[p->A]; --area; --v; } // add leading edge top half v = -1; while (v >= top) { int u = leadingEdgeX[-v]; if (u + 1 <= right) { break; } --v; } while (v >= top) { int u = leadingEdgeX[-v]; ColorBgra* p = unchecked(ps + (v * stride)) + u + 1; ++hb[p->B]; ++hg[p->G]; ++hr[p->R]; ++ha[p->A]; ++area; --v; } // Subtract trailing edge bottom half v = 0; while (v <= bottom) { int u = leadingEdgeX[v]; if (-u >= left) { break; } ++v; } while (v <= bottom) { int u = leadingEdgeX[v]; ColorBgra* p = ps + v * stride - u; --hb[p->B]; --hg[p->G]; --hr[p->R]; --ha[p->A]; --area; ++v; } // add leading edge bottom half v = 0; while (v <= bottom) { int u = leadingEdgeX[v]; if (u + 1 <= right) { break; } ++v; } while (v <= bottom) { int u = leadingEdgeX[v]; ColorBgra* p = ps + v * stride + u + 1; ++hb[p->B]; ++hg[p->G]; ++hr[p->R]; ++ha[p->A]; ++area; ++v; } ++ps; ++pd; } } }
public unsafe override void RenderEffect(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois) { if (Data.Angle == 0) { // Copy src to dest return; } int w = dst.Width; int h = dst.Height; int fcx = (w << 15) + (int)(Data.Offset.X * (w << 15)); int fcy = (h << 15) + (int)(Data.Offset.Y * (h << 15)); int n = (Data.Quality * Data.Quality) * (30 + Data.Quality * Data.Quality); int fr = (int)(Data.Angle * Math.PI * 65536.0 / 181.0); foreach (Gdk.Rectangle rect in rois) { 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) { int fx = (x << 16) - fcx; int fy = (y << 16) - fcy; int fsr = fr / n; 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; int ox1 = fx; int ox2 = fx; int oy1 = fy; int oy2 = fy; ColorBgra* src_dataptr = (ColorBgra*)src.DataPtr; int src_width = src.Width; for (int i = 0; i < n; ++i) { Rotate (ref ox1, ref oy1, fsr); Rotate (ref ox2, ref oy2, -fsr); int u1 = ox1 + fcx + 32768 >> 16; int v1 = oy1 + fcy + 32768 >> 16; if (u1 > 0 && v1 > 0 && u1 < w && v1 < h) { ColorBgra* sample = src.GetPointAddressUnchecked (src_dataptr, src_width, u1, v1); sr += sample->R * sample->A; sg += sample->G * sample->A; sb += sample->B * sample->A; sa += sample->A; ++sc; } int u2 = ox2 + fcx + 32768 >> 16; int v2 = oy2 + fcy + 32768 >> 16; if (u2 > 0 && v2 > 0 && u2 < w && v2 < h) { ColorBgra* sample = src.GetPointAddressUnchecked (src_dataptr, src_width, u2, v2); sr += sample->R * sample->A; sg += sample->G * sample->A; sb += sample->B * sample->A; sa += sample->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; } ++dstPtr; ++srcPtr; } } } }
public unsafe override void RenderEffect(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois) { if (Data.Amount == 0) { // Copy src to dest return; } int src_width = src.Width; ColorBgra* src_data_ptr = (ColorBgra*)src.DataPtr; int dst_width = dst.Width; ColorBgra* dst_data_ptr = (ColorBgra*)dst.DataPtr; Gdk.Rectangle src_bounds = src.GetBounds (); long w = dst.Width; long h = dst.Height; long fox = (long)(dst.Width * Data.Offset.X * 32768.0); long foy = (long)(dst.Height * Data.Offset.Y * 32768.0); long fcx = fox + (w << 15); long fcy = foy + (h << 15); long fz = Data.Amount; const int n = 64; foreach (Gdk.Rectangle rect in rois) { for (int y = rect.Top; y < rect.Bottom; ++y) { ColorBgra* dstPtr = dst.GetPointAddressUnchecked (dst_data_ptr, dst_width, rect.Left, y); ColorBgra* srcPtr = src.GetPointAddressUnchecked (src_data_ptr, src_width, rect.Left, y); for (int x = rect.Left; x < rect.Right; ++x) { long fx = (x << 16) - fcx; long fy = (y << 16) - fcy; 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); if (src_bounds.Contains (u, v)) { ColorBgra* srcPtr2 = src.GetPointAddressUnchecked (src_data_ptr, src_width, 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; } } } }
public unsafe override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois) { int width = dst.Width; int height = dst.Height; float hw = width / 2f; float hh = height / 2f; float sin = (float)Math.Sin (Data.Rotation * Math.PI / 180.0); float cos = (float)Math.Cos (Data.Rotation * Math.PI / 180.0); float scale = (float)Math.PI / Data.TileSize; float intensity = Data.Intensity; intensity = intensity * intensity / 10 * Math.Sign (intensity); int aaLevel = 4; int aaSamples = aaLevel * aaLevel + 1; PointD* aaPoints = stackalloc PointD[aaSamples]; for (int i = 0; i < aaSamples; ++i) { double x = (i * aaLevel) / (double)aaSamples; double y = i / (double)aaSamples; x -= (int)x; // RGSS + rotation to maximize AA quality aaPoints[i] = new PointD ((double)(cos * x + sin * y), (double)(cos * y - sin * x)); } 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); for (int x = rect.Left; x < rect.Right; x++) { int b = 0; int g = 0; int r = 0; int a = 0; float i = x - hw; for (int p = 0; p < aaSamples; ++p) { PointD pt = aaPoints[p]; float u = i + (float)pt.X; float v = j - (float)pt.Y; float s = cos * u + sin * v; float t = -sin * u + cos * v; s += intensity * (float)Math.Tan (s * scale); t += intensity * (float)Math.Tan (t * scale); u = cos * s - sin * t; v = sin * s + cos * t; int xSample = (int)(hw + u); int ySample = (int)(hh + v); xSample = (xSample + width) % width; // This makes it a little faster if (xSample < 0) { xSample = (xSample + width) % width; } ySample = (ySample + height) % height; // This makes it a little faster if (ySample < 0) { ySample = (ySample + height) % height; } ColorBgra sample = *src.GetPointAddressUnchecked (src_data_ptr, src_width, xSample, ySample); 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)); } } } }
public unsafe override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois) { ColorBgra colPrimary = PintaCore.Palette.PrimaryColor.ToColorBgra (); ColorBgra colSecondary = PintaCore.Palette.SecondaryColor.ToColorBgra (); ColorBgra colTransparent = ColorBgra.Transparent; int aaSampleCount = Data.Quality * Data.Quality; Cairo.PointD* aaPoints = stackalloc Cairo.PointD[aaSampleCount]; Utility.GetRgssOffsets (aaPoints, aaSampleCount, Data.Quality); ColorBgra* samples = stackalloc ColorBgra[aaSampleCount]; TransformData td; foreach (Gdk.Rectangle rect in rois) { for (int y = rect.Top; y < rect.Bottom; y++) { ColorBgra* dstPtr = dst.GetPointAddressUnchecked (rect.Left, y); double relativeY = y - Data.CenterOffset.Y; for (int x = rect.Left; x < rect.Right; x++) { double relativeX = x - Data.CenterOffset.X; int sampleCount = 0; for (int p = 0; p < aaSampleCount; ++p) { td.X = relativeX + aaPoints[p].X; td.Y = relativeY - aaPoints[p].Y; InverseTransform (ref td); float sampleX = (float)(td.X + Data.CenterOffset.X); float sampleY = (float)(td.Y + Data.CenterOffset.Y); ColorBgra sample = colPrimary; if (IsOnSurface (src, sampleX, sampleY)) { sample = src.GetBilinearSample (sampleX, sampleY); } else { switch (Data.EdgeBehavior) { case WarpEdgeBehavior.Clamp: sample = src.GetBilinearSampleClamped (sampleX, sampleY); break; case WarpEdgeBehavior.Wrap: sample = src.GetBilinearSampleWrapped (sampleX, sampleY); break; case WarpEdgeBehavior.Reflect: sample = src.GetBilinearSampleClamped (ReflectCoord (sampleX, src.Width), ReflectCoord (sampleY, src.Height)); break; case WarpEdgeBehavior.Primary: sample = colPrimary; break; case WarpEdgeBehavior.Secondary: sample = colSecondary; break; case WarpEdgeBehavior.Transparent: sample = colTransparent; break; case WarpEdgeBehavior.Original: sample = src.GetColorBgra (x, y); break; default: break; } } samples[sampleCount] = sample; ++sampleCount; } *dstPtr = ColorBgra.Blend (samples, sampleCount); ++dstPtr; } } } }
public unsafe override void RenderEffect(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois) { int width = src.Width; int height = src.Height; int arrayLens = 1 + Data.Coarseness; int localStoreSize = arrayLens * 5 * sizeof (int); byte* localStore = stackalloc byte[localStoreSize]; byte* p = localStore; int* intensityCount = (int*)p; p += arrayLens * sizeof (int); uint* avgRed = (uint*)p; p += arrayLens * sizeof (uint); uint* avgGreen = (uint*)p; p += arrayLens * sizeof (uint); uint* avgBlue = (uint*)p; p += arrayLens * sizeof (uint); uint* avgAlpha = (uint*)p; p += arrayLens * sizeof (uint); byte maxIntensity = (byte)Data.Coarseness; foreach (Gdk.Rectangle rect in rois) { int rectTop = rect.Top; int rectBottom = rect.Bottom; int rectLeft = rect.Left; int rectRight = rect.Right; ColorBgra* dst_dataptr = (ColorBgra*)dest.DataPtr; int dst_width = dest.Width; ColorBgra* src_dataptr = (ColorBgra*)src.DataPtr; int src_width = src.Width; for (int y = rectTop; y < rectBottom; ++y) { ColorBgra* dstPtr = dest.GetPointAddressUnchecked (dst_dataptr, dst_width, rect.Left, y); int top = y - Data.BrushSize; int bottom = y + Data.BrushSize + 1; if (top < 0) { top = 0; } if (bottom > height) { bottom = height; } for (int x = rectLeft; x < rectRight; ++x) { SetToZero (localStore, (ulong)localStoreSize); int left = x - Data.BrushSize; int right = x + Data.BrushSize + 1; if (left < 0) { left = 0; } if (right > width) { right = width; } int numInt = 0; for (int j = top; j < bottom; ++j) { ColorBgra* srcPtr = src.GetPointAddressUnchecked (src_dataptr, src_width, left, j); for (int i = left; i < right; ++i) { byte intensity = Utility.FastScaleByteByByte (srcPtr->GetIntensityByte (), maxIntensity); ++intensityCount[intensity]; ++numInt; avgRed[intensity] += srcPtr->R; avgGreen[intensity] += srcPtr->G; avgBlue[intensity] += srcPtr->B; avgAlpha[intensity] += srcPtr->A; ++srcPtr; } } byte chosenIntensity = 0; int maxInstance = 0; for (int i = 0; i <= maxIntensity; ++i) { if (intensityCount[i] > maxInstance) { chosenIntensity = (byte)i; maxInstance = intensityCount[i]; } } // TODO: correct handling of alpha values? byte R = (byte)(avgRed[chosenIntensity] / maxInstance); byte G = (byte)(avgGreen[chosenIntensity] / maxInstance); byte B = (byte)(avgBlue[chosenIntensity] / maxInstance); byte A = (byte)(avgAlpha[chosenIntensity] / maxInstance); *dstPtr = ColorBgra.FromBgra (B, G, R, A); ++dstPtr; } } } }
public unsafe override void RenderEffect(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois) { Calculate (); for (int y = 0; y < src.Height; y++) { ColorBgra* srcRowPtr = src.GetPointAddressUnchecked (0, y); ColorBgra* dstRowPtr = dest.GetPointAddressUnchecked (0, y); ColorBgra* dstRowEndPtr = dstRowPtr + dest.Width; if (divide == 0) { while (dstRowPtr < dstRowEndPtr) { ColorBgra col = *srcRowPtr; int i = col.GetIntensityByte (); uint c = rgbTable[i]; dstRowPtr->Bgra = (col.Bgra & 0xff000000) | c | (c << 8) | (c << 16); ++dstRowPtr; ++srcRowPtr; } } else { while (dstRowPtr < dstRowEndPtr) { ColorBgra col = *srcRowPtr; int i = col.GetIntensityByte (); int shiftIndex = i * 256; col.R = rgbTable[shiftIndex + col.R]; col.G = rgbTable[shiftIndex + col.G]; col.B = rgbTable[shiftIndex + col.B]; *dstRowPtr = col; ++dstRowPtr; ++srcRowPtr; } } } }
public unsafe override void RenderEffect(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois) { int w = dst.Width; int h = dst.Height; double wDiv2 = (double)w / 2; double hDiv2 = (double)h / 2; double invH = 1.0 / h; double zoom = 1 + zoomFactor * Data.Zoom; double invZoom = 1.0 / zoom; double invQuality = 1.0 / (double)Data.Quality; int count = Data.Quality * Data.Quality + 1; double invCount = 1.0 / (double)count; double angleTheta = (Data.Angle * 2 * Math.PI) / 360; ColorBgra* dst_dataptr = (ColorBgra*)dst.DataPtr; int dst_width = dst.Width; foreach (Gdk.Rectangle rect in rois) { for (int y = rect.Top; y < rect.Bottom; y++) { ColorBgra* dstPtr = dst.GetPointAddressUnchecked (dst_dataptr, dst_width, rect.Left, y); for (int x = rect.Left; x < rect.Right; x++) { int r = 0; int g = 0; int b = 0; int a = 0; for (double i = 0; i < count; i++) { double u = (2.0 * x - w + (i * invCount)) * invH; double v = (2.0 * y - h + ((i * invQuality) % 1)) * invH; double radius = Math.Sqrt ((u * u) + (v * v)); double radiusP = radius; double theta = Math.Atan2 (v, u); double thetaP = theta + angleTheta; double uP = radiusP * Math.Cos (thetaP); double vP = radiusP * Math.Sin (thetaP); double m = Mandelbrot ((uP * invZoom) + this.xOffset, (vP * invZoom) + this.yOffset, Data.Factor); double c = 64 + Data.Factor * m; r += Utility.ClampToByte (c - 768); g += Utility.ClampToByte (c - 512); b += Utility.ClampToByte (c - 256); a += Utility.ClampToByte (c - 0); } *dstPtr = ColorBgra.FromBgra (Utility.ClampToByte (b / count), Utility.ClampToByte (g / count), Utility.ClampToByte (r / count), Utility.ClampToByte (a / count)); ++dstPtr; } } if (Data.InvertColors) { for (int y = rect.Top; y < rect.Bottom; y++) { ColorBgra* dstPtr = dst.GetPointAddressUnchecked (dst_dataptr, dst_width, rect.Left, y); for (int x = rect.Left; x < rect.Right; ++x) { ColorBgra c = *dstPtr; c.B = (byte)(255 - c.B); c.G = (byte)(255 - c.G); c.R = (byte)(255 - c.R); *dstPtr = c; ++dstPtr; } } } } }
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; } } } }