예제 #1
0
        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;
                        }
                    }
                }
            }
        }
예제 #2
0
        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;
                    }
                }
            }
        }
예제 #3
0
        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;
                    }
                }
            }
        }
예제 #4
0
        public unsafe 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.GetBottom (); ++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.GetRight (); ++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;
                    }
                }
            }
        }
예제 #5
0
		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;
					}
				}
			}
		}