예제 #1
0
        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;
                }
            }
        }
예제 #2
0
        //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, 
            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];
            uint hSize = (uint)(sizeof(int) * hLength);

            for (int y = rect.Top; y <= rect.GetBottom (); y++)
            {
                SetToZero(hb, hSize);
                SetToZero(hg, hSize);
                SetToZero(hr, hSize);

                int area = 0;
                int sum = 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)
                    {
                        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 = rect.Left; x <= rect.GetRight (); 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;
                }
            }
        }
예제 #3
0
		public void Invert (Gdk.Rectangle rect)
		{
			for (int y = rect.Y; y <= rect.GetBottom (); ++y) {
				for (int x = rect.X; x <= rect.GetRight (); ++x) {
					Invert (x, y);
				}
			}
		}
예제 #4
0
		private unsafe static 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.GetBottom (); ++y)
            {
                ColorBgra* ptr = surface.GetPointAddressUnchecked(0, y - rect.Top);
                int dy = 2 * y - h;

                for (int x = rect.Left; x <= rect.GetRight (); ++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;
                }
            }
        }
예제 #5
0
		public void Set (Gdk.Rectangle rect, bool newValue)
		{
			for (int y = rect.Y; y <= rect.GetBottom (); ++y) {
				for (int x = rect.X; x <= rect.GetRight (); ++x) {
					Set (x, y, newValue);
				}
			}
		}