コード例 #1
0
ファイル: PencilSketchEffect.cs プロジェクト: msiyer/Pinta
		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;
					}
				}
			}
		}
コード例 #2
0
ファイル: MotionBlurEffect.cs プロジェクト: msiyer/Pinta
		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;
					}
				}
			}
		}
コード例 #3
0
ファイル: BulgeEffect.cs プロジェクト: msiyer/Pinta
		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;
					}
				}
			}
		}
コード例 #4
0
ファイル: GlowEffect.cs プロジェクト: msiyer/Pinta
		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);
				}
			}
		}
コード例 #5
0
ファイル: HistogramRGB.cs プロジェクト: msiyer/Pinta
        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;
                }
            }
        }
コード例 #6
0
ファイル: FragmentEffect.cs プロジェクト: msiyer/Pinta
		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;
					}
				}
			}
		}
コード例 #7
0
		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;
						}
					}
				}
			}
		}
コード例 #8
0
ファイル: BaseEffect.cs プロジェクト: RudoCris/Pinta
        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);
            }
        }
コード例 #9
0
        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;
                    }
                }
            }
        }
コード例 #10
0
ファイル: UnaryPixelOp.cs プロジェクト: deckarep/Pinta
 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);
     }
 }
コード例 #11
0
ファイル: LocalHistogramEffect.cs プロジェクト: msiyer/Pinta
        //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;
                }
            }
		}
コード例 #12
0
ファイル: AddNoiseEffect.cs プロジェクト: msiyer/Pinta
		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;
					}
				}
			}
		}
コード例 #13
0
 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;
 }
コード例 #14
0
ファイル: CloudsEffect.cs プロジェクト: sandyarmstrong/Pinta
        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;
                }
            }
        }
コード例 #15
0
ファイル: TwistEffect.cs プロジェクト: sandyarmstrong/Pinta
        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;
                    }
                }
            }
        }
コード例 #16
0
        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;
                }
            }
        }
コード例 #17
0
        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;
                        }
                    }
                }
            }
        }
コード例 #18
0
ファイル: UnaryPixelOp.cs プロジェクト: RudoCris/Pinta
        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);
            }
        }
コード例 #19
0
ファイル: GaussianBlurEffect.cs プロジェクト: bodicsek/Pinta
        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;
                        }
                    }
                }
            }
        }
コード例 #20
0
ファイル: LocalHistogramEffect.cs プロジェクト: msiyer/Pinta
        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;
                }
            }
        }
コード例 #21
0
        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;
                    }
                }
            }
        }
コード例 #22
0
ファイル: ZoomBlurEffect.cs プロジェクト: RudoCris/Pinta
        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;
                    }
                }
            }
        }
コード例 #23
0
ファイル: TileEffect.cs プロジェクト: jobernolte/Pinta
        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));
                    }
                }
            }
        }
コード例 #24
0
ファイル: WarpEffect.cs プロジェクト: jobernolte/Pinta
        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;
                    }
                }
            }
        }
コード例 #25
0
ファイル: OilPaintingEffect.cs プロジェクト: xxgreg/Pinta
        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;
                    }
                }
            }
        }
コード例 #26
0
        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;
                    }
                }
            }
        }
コード例 #27
0
        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;
                        }
                    }
                }
            }
        }
コード例 #28
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;
					}
				}
			}
		}