public EffectEnvironmentParameters(ColorBgra primaryColor, ColorBgra secondaryColor, float brushWidth, PdnRegion selection)
 {
     this.primaryColor = primaryColor;
     this.secondaryColor = secondaryColor;
     this.brushWidth = brushWidth;
     this.selection = (PdnRegion)selection.Clone();
 }
		public override ColorBgra Apply (ColorBgra color)
		{
			// Adjust saturation
			var intensity = color.GetIntensityByte ();
			color.R = Utility.ClampToByte ((intensity * 1024 + (color.R - intensity) * sat_factor) >> 10);
			color.G = Utility.ClampToByte ((intensity * 1024 + (color.G - intensity) * sat_factor) >> 10);
			color.B = Utility.ClampToByte ((intensity * 1024 + (color.B - intensity) * sat_factor) >> 10);

			var hsvColor = (new RgbColor (color.R, color.G, color.B)).ToHsv ();
			int hue = hsvColor.Hue;

			hue += hue_delta;

			while (hue < 0)
				hue += 360;

			while (hue > 360)
				hue -= 360;

			hsvColor.Hue = hue;

			var rgbColor = hsvColor.ToRgb ();
			var newColor = ColorBgra.FromBgr ((byte)rgbColor.Blue, (byte)rgbColor.Green, (byte)rgbColor.Red);
			
			newColor = blend_op.Apply (newColor);
			newColor.A = color.A;

			return newColor;
		}
		//Saturation formula from RgbColor.cs, public HsvColor ToHsv()
		private int GetSaturation (ColorBgra color)
		{
			double min;
			double max;
			double delta;

			var r = (double)color.R / 255;
			var g = (double)color.G / 255;
			var b = (double)color.B / 255;

			double s;

			min = Math.Min (Math.Min (r, g), b);
			max = Math.Max (Math.Max (r, g), b);
			delta = max - min;

			if (max == 0 || delta == 0) {
				// R, G, and B must be 0, or all the same.
				// In this case, S is 0, and H is undefined.
				// Using H = 0 is as good as any...
				s = 0;
			} else {
				s = delta / max;
			}

			return (int)(s * 255);
		}
		protected override unsafe void Render (ColorBgra* src, ColorBgra* dst, int length)
		{
			var srcRowPtr = src;
			var dstRowPtr = dst;
			var dstRowEndPtr = dstRowPtr + length;

			if (divide == 0) {
				while (dstRowPtr < dstRowEndPtr) {
					var col = *srcRowPtr;
					var i = col.GetIntensityByte ();
					uint c = rgbTable[i];
					dstRowPtr->Bgra = (col.Bgra & 0xff000000) | c | (c << 8) | (c << 16);

					++dstRowPtr;
					++srcRowPtr;
				}
			} else {
				while (dstRowPtr < dstRowEndPtr) {
					var col = *srcRowPtr;
					var i = col.GetIntensityByte ();
					var shiftIndex = i * 256;

					col.R = rgbTable[shiftIndex + col.R];
					col.G = rgbTable[shiftIndex + col.G];
					col.B = rgbTable[shiftIndex + col.B];

					*dstRowPtr = col;
					++dstRowPtr;
					++srcRowPtr;
				}
			}
		}
        public static Document ResizeDocument(Document document, Size newSize, AnchorEdge edge, ColorBgra background)
        {
            Document newDoc = new Document(newSize.Width, newSize.Height);
            newDoc.ReplaceMetaDataFrom(document);

            for (int i = 0; i < document.Layers.Count; ++i)
            {
                Layer layer = (Layer)document.Layers[i];

                if (layer is BitmapLayer)
                {
                    Layer newLayer;

                    try
                    {
                        newLayer = ResizeLayer((BitmapLayer)layer, newSize, edge, background);
                    }

                    catch (OutOfMemoryException)
                    {
                        newDoc.Dispose();
                        throw;
                    }

                    newDoc.Layers.Add(newLayer);
                }
                else
                {
                    throw new InvalidOperationException("Canvas Size does not support Layers that are not BitmapLayers");
                }
            }

            return newDoc;
        }
		public unsafe override ColorBgra ApplyWithAlpha (ColorBgra src, int area, int sum, int* hb, int* hg, int* hr)
		{
			//each slot of the histgram can contain up to area * 255. This will overflow an int when area > 32k
			if (area < 32768) {
				int b = 0;
				int g = 0;
				int r = 0;

				for (int i = 1; i < 256; ++i) {
					b += i * hb[i];
					g += i * hg[i];
					r += i * hr[i];
				}

				int alpha = sum / area;
				int div = area * 255;

				return ColorBgra.FromBgraClamped (b / div, g / div, r / div, alpha);
			} else {	//use a long if an int will overflow.
				long b = 0;
				long g = 0;
				long r = 0;

				for (long i = 1; i < 256; ++i) {
					b += i * hb[i];
					g += i * hg[i];
					r += i * hr[i];
				}

				int alpha = sum / area;
				int div = area * 255;

				return ColorBgra.FromBgraClamped (b / div, g / div, r / div, alpha);
			}
		}
		public override unsafe ColorBgra Apply (ColorBgra color, int area, int* hb, int* hg, int* hr, int* ha)
		{
			var normalized = GetPercentileOfColor (color, area, hb, hg, hr, ha);
			var lerp = strength * (1 - 0.75 * color.GetIntensity ());

			return ColorBgra.Lerp (color, normalized, lerp);
		}
		public unsafe override void Apply (ColorBgra* src, ColorBgra* dst, int length)
		{
			while (length > 0) {
				int lhsA; { lhsA = ((*dst).A); };
				int rhsA; { rhsA = ((*src).A); };
				int y; { y = ((lhsA) * (255 - rhsA) + 0x80); y = ((((y) >> 8) + (y)) >> 8); }; int totalA = y + rhsA; uint ret; if (totalA == 0) { ret = 0; } else { int fB; int fG; int fR; { fB = ((*src).B); }; { fG = ((*src).G); }; { fR = ((*src).R); }; int x; { x = ((lhsA) * (rhsA) + 0x80); x = ((((x) >> 8) + (x)) >> 8); }; int z = rhsA - x; int masIndex = totalA * 3; uint taM = masTable[masIndex]; uint taA = masTable[masIndex + 1]; uint taS = masTable[masIndex + 2]; uint b = (uint)(((((long)((((*dst).B * y) + ((*src).B * z) + (fB * x)))) * taM) + taA) >> (int)taS); uint g = (uint)(((((long)((((*dst).G * y) + ((*src).G * z) + (fG * x)))) * taM) + taA) >> (int)taS); uint r = (uint)(((((long)((((*dst).R * y) + ((*src).R * z) + (fR * x)))) * taM) + taA) >> (int)taS); int a; { { a = ((lhsA) * (255 - (rhsA)) + 0x80); a = ((((a) >> 8) + (a)) >> 8); }; a += (rhsA); }; ret = b + (g << 8) + (r << 16) + ((uint)a << 24); }; dst->Bgra = ret; ++dst; ++src; --length;
			}
		}
		public override unsafe void Apply (ColorBgra* ptr, int length)
		{
			while (length > 0) {
				(*ptr)[channel] = set_value;
				++ptr;
				--length;
			}
		}
		/// <summary>
		/// Creates a new effect that will apply a polar inversion to an image.
		/// </summary>
		/// <param name="amount">Amount of inversion. Valid range is -4 - 4.</param>
		/// <param name="quality">Quality of the inversion. Valid range is 1 - 5.</param>
		/// <param name="centerOffset">Center of the inversion.</param>
		/// <param name="edgeBehavior">Edge behavior of the inversion.</param>
		/// <param name="primaryColor">Primary color of the inversion.</param>
		/// <param name="secondaryColor">Secondary color of the inversion.</param>
		public PolarInversionEffect (double amount = 0, int quality = 2, Point centerOffset = new Point (), WarpEdgeBehavior edgeBehavior = WarpEdgeBehavior.Reflect, ColorBgra primaryColor = new ColorBgra (), ColorBgra secondaryColor = new ColorBgra ())
			: base (quality, centerOffset, edgeBehavior, primaryColor, secondaryColor)
		{
			if (amount < -4 || amount > 4)
				throw new ArgumentOutOfRangeException ("amount");

			this.amount = amount;
		}
		public override unsafe void Apply (ColorBgra* ptr, int length)
		{
			while (length > 0) {
				ptr->Bgra |= 0xff000000;
				++ptr;
				--length;
			}
		}
		public unsafe override void Apply (ColorBgra* ptr, int length)
		{
			while (length > 0) {
				*ptr = set_color;
				++ptr;
				--length;
			}
		}
		public unsafe override void Apply (ColorBgra* src, ColorBgra* dst, int length)
		{
			while (length > 0) {
				*dst = set_color;
				++dst;
				--length;
			}
		}
		public unsafe override void Apply (ColorBgra* src, ColorBgra* dst, int length)
		{
			for (int i = 0; i < length; i++) {
				*dst = *src;
				dst++;
				src++;
			}
		}
		public override unsafe void Apply (ColorBgra* ptr, int length)
		{
			while (length > 0) {
				ptr->Bgra = (ptr->Bgra & 0x00ffffff) + add_value;
				++ptr;
				--length;
			}
		}
		public override unsafe void Apply (ColorBgra* src, ColorBgra* dst, int length)
		{
			while (length > 0) {
				dst->Bgra = (src->Bgra & 0x00ffffff) + add_value;
				++dst;
				++src;
				--length;
			}
		}
		public override unsafe void Apply (ColorBgra* src, ColorBgra* dst, int length)
		{
			while (length > 0) {
				dst->Bgra = src->Bgra | 0xff000000;
				++dst;
				++src;
				--length;
			}
		}
		public override unsafe void Apply (ColorBgra* src, ColorBgra* dst, int length)
		{
			while (length > 0) {
				*dst = *src;
				(*dst)[channel] = set_value;
				++dst;
				++src;
				--length;
			}
		}
		public override unsafe void Apply (ColorBgra* ptr, int length)
		{
			while (--length >= 0) {
				ptr->B = CurveB[ptr->B];
				ptr->G = CurveG[ptr->G];
				ptr->R = CurveR[ptr->R];

				++ptr;
			}
		}
		protected WarpEffect (int quality, Point centerOffset, WarpEdgeBehavior edgeBehavior, ColorBgra primaryColor, ColorBgra secondaryColor)
		{
			if (quality < 1 || quality > 5)
				throw new ArgumentOutOfRangeException ("quality");

			this.quality = quality;
			this.center_offset = centerOffset;
			this.edge_behavior = edgeBehavior;
			this.primary_color = primaryColor;
			this.secondary_color = secondaryColor;
		}
		public override ColorBgra Apply (ColorBgra color)
		{
			byte lumi = color.GetIntensityByte ();
			int diff = Curve[lumi] - lumi;

			return ColorBgra.FromBgraClamped (
			    color.B + diff,
			    color.G + diff,
			    color.R + diff,
			    color.A);
		}
		public unsafe override void Apply (ColorBgra* ptr, int length)
		{
			while (length > 0) {
				ptr->B = blue_levels[ptr->B];
				ptr->G = green_levels[ptr->G];
				ptr->R = red_levels[ptr->R];

				++ptr;
				--length;
			}
		}
		public override unsafe void Apply (ColorBgra* src, ColorBgra* dst, int length)
		{
			while (--length >= 0) {
				dst->B = CurveB[src->B];
				dst->G = CurveG[src->G];
				dst->R = CurveR[src->R];
				dst->A = src->A;

				++dst;
				++src;
			}
		}
		public override ColorBgra Apply (ColorBgra color)
		{
			int a = blend_color.A;
			int invA = 255 - a;

			int r = ((color.R * invA) + (blend_color.R * a)) / 256;
			int g = ((color.G * invA) + (blend_color.G * a)) / 256;
			int b = ((color.B * invA) + (blend_color.B * a)) / 256;
			byte a2 = ComputeAlpha (color.A, blend_color.A);

			return ColorBgra.FromBgra ((byte)b, (byte)g, (byte)r, a2);
		}
		public unsafe override void Apply (ColorBgra* src, ColorBgra* dst, int length)
		{
			while (length > 0) {
				dst->B = blue_levels[src->B];
				dst->G = green_levels[src->G];
				dst->R = red_levels[src->R];
				dst->A = src->A;

				++dst;
				++src;
				--length;
			}
		}
		public unsafe override void Apply (ColorBgra* ptr, int length)
		{
			while (length > 0) {
				var i = ptr->GetIntensityByte ();

				ptr->R = i;
				ptr->G = i;
				ptr->B = i;

				++ptr;
				--length;
			}
		}
		public LevelOp (ColorBgra in_lo, ColorBgra in_hi, float[] gamma, ColorBgra out_lo, ColorBgra out_hi)
		{
			colorInLow = in_lo;
			colorInHigh = in_hi;
			colorOutLow = out_lo;
			colorOutHigh = out_hi;

			if (gamma.Length != 3)
				throw new ArgumentException ("gamma", "gamma must be a float[3]");

			this.gamma = gamma;
			UpdateLookupTable ();
		}
		public unsafe override void Apply (ColorBgra* src, ColorBgra* dst, int length)
		{
			while (length > 0) {
				var i = src->GetIntensityByte ();

				dst->B = i;
				dst->G = i;
				dst->R = i;
				dst->A = src->A;

				++dst;
				++src;
				--length;
			}
		}
		/// <summary>
		/// Creates a new effect that will render clouds onto an image.
		/// </summary>
		/// <param name="scale">The relative size of the clouds. Valid range is 2 - 1000.</param>
		/// <param name="power">The power of the clouds. Valid range is 0 - 100.</param>
		/// <param name="seed">Seed value for random generator.</param>
		/// <param name="fromColor">Initial cloud color.</param>
		/// <param name="toColor">Final cloud color.</param>
		/// <param name="blendMode">Blend mode to use when applying clouds.</param>
		public CloudsEffect (int scale = 250, int power = 50, int seed = 0, ColorBgra fromColor = new ColorBgra (), ColorBgra toColor = new ColorBgra (), BlendMode blendMode = BlendMode.Normal)
		{
			if (scale < 2 || scale > 1000)
				throw new ArgumentOutOfRangeException ("scale");
			if (power < 0 || power > 100)
				throw new ArgumentOutOfRangeException ("radius");

			this.scale = scale;
			this.power = power;
			this.seed = seed;
			this.from_color = fromColor;
			this.to_color = toColor;
			this.blend_mode = blendMode;

			blend_op = Utility.GetBlendModeOp (blend_mode);
		}
		public override ColorBgra Apply (ColorBgra color)
		{
			// The higher the saturation, the more red it is
			var saturation = GetSaturation (color);

			// The higher the difference between the other colors, the more red it is
			var difference = color.R - Math.Max (color.B, color.G);

			// If it is within tolerence, and the saturation is high
			if ((difference > tolerence) && (saturation > 100)) {
				var i = 255.0 * color.GetIntensity ();
				var ib = (byte)(i * set_saturation); // adjust the red color for user inputted saturation
				return ColorBgra.FromBgra ((byte)color.B, (byte)color.G, ib, color.A);
			} else {
				return color;
			}
		}
Beispiel #31
0
        private static BitmapLayer ResizeLayer(BitmapLayer layer, int width, int height, ResamplingAlgorithm algorithm,
                                               int tileCount, Procedure progressCallback, ref bool pleaseStopMonitor)
        {
            Surface surface = new Surface(width, height);

            surface.Clear(ColorBgra.FromBgra(255, 255, 255, 0));

            PaintDotNet.Threading.ThreadPool threadPool = new PaintDotNet.Threading.ThreadPool();
            int rectCount;

            if (tileCount == 0)
            {
                rectCount = Processor.LogicalCpuCount;
            }
            else
            {
                rectCount = tileCount;
            }

            Rectangle[] rects = new Rectangle[rectCount];
            Utility.SplitRectangle(surface.Bounds, rects);

            FitSurfaceContext fsc = new FitSurfaceContext(surface, layer.Surface, rects, algorithm);

            if (progressCallback != null)
            {
                fsc.RenderedRect += progressCallback;
            }

            WaitCallback callback = new WaitCallback(fsc.FitSurface);

            for (int i = 0; i < rects.Length; ++i)
            {
                if (pleaseStopMonitor)
                {
                    break;
                }
                else
                {
                    threadPool.QueueUserWorkItem(callback, BoxedConstants.GetInt32(i));
                }
            }

            threadPool.Drain();
            threadPool.DrainExceptions();

            if (pleaseStopMonitor)
            {
                surface.Dispose();
                surface = null;
            }

            BitmapLayer newLayer;

            if (surface == null)
            {
                newLayer = null;
            }
            else
            {
                newLayer = new BitmapLayer(surface, true);
                newLayer.LoadProperties(layer.SaveProperties());
            }

            if (progressCallback != null)
            {
                fsc.RenderedRect -= progressCallback;
            }

            return(newLayer);
        }
Beispiel #32
0
        public static unsafe ColorBgra GetPercentile(int percentile, int area, int *hb, int *hg, int *hr, int *ha)
        {
            int minCount = area * percentile / 100;

            int b      = 0;
            int bCount = 0;

            while (b < 255 && hb[b] == 0)
            {
                ++b;
            }

            while (b < 255 && bCount < minCount)
            {
                bCount += hb[b];
                ++b;
            }

            int g      = 0;
            int gCount = 0;

            while (g < 255 && hg[g] == 0)
            {
                ++g;
            }

            while (g < 255 && gCount < minCount)
            {
                gCount += hg[g];
                ++g;
            }

            int r      = 0;
            int rCount = 0;

            while (r < 255 && hr[r] == 0)
            {
                ++r;
            }

            while (r < 255 && rCount < minCount)
            {
                rCount += hr[r];
                ++r;
            }

            int a      = 0;
            int aCount = 0;

            while (a < 255 && ha[a] == 0)
            {
                ++a;
            }

            while (a < 255 && aCount < minCount)
            {
                aCount += ha[a];
                ++a;
            }

            return(ColorBgra.FromBgra((byte)b, (byte)g, (byte)r, (byte)a));
        }
Beispiel #33
0
        public unsafe override void Render(
            Surface src,
            Surface dst,
            PixelFarm.Drawing.Rectangle[] rois,
            int startIndex, int length)
        {
            RotateZoomEffectConfigToken token = (RotateZoomEffectConfigToken)Parameters;

            RotateZoomEffectConfigToken.RzInfo rzInfo = token.ComputedOnce;
            //Rectangle bounds = this.EnvironmentParameters.GetSelection(dstArgs.Bounds).GetBoundsInt();

            Rectangle bounds = SelectionBounds;

            bounds.Intersect(dst.Bounds);


            //PdnRegion selection = this.EnvironmentParameters.GetSelection(src.Bounds);
            Rectangle srcBounds = src.Bounds;
            int       srcMaxX   = srcBounds.Width - 1;
            int       srcMaxY   = srcBounds.Height - 1;

            float dsxdx   = rzInfo.dsxdx;
            float dsydx   = rzInfo.dsydx;
            float dszdx   = rzInfo.dszdx;
            float dsxdy   = rzInfo.dsxdy;
            float dsydy   = rzInfo.dsydy;
            float dszdy   = rzInfo.dszdy;
            float zoom    = token.Zoom;
            uint  srcMask = token.SourceAsBackground ? 0xffffffff : 0;

            bool  tile    = token.Tile;
            float divZ    = 0.5f * (float)Math.Sqrt(dst.Width * dst.Width + dst.Height * dst.Height);
            float centerX = (float)dst.Width / 2.0f;
            float centerY = (float)dst.Height / 2.0f;
            float tx      = (token.Offset.X) * dst.Width / 2.0f;
            float ty      = (token.Offset.Y) * dst.Height / 2.0f;

            uint tilingMask = tile ? 0xffffffff : 0;

            for (int i = startIndex; i < startIndex + length; ++i)
            {
                Rectangle rect = rois[i];

                float cx = rzInfo.startX;
                float cy = rzInfo.startY;
                float cz = rzInfo.startZ;

                float mcl = ((rect.Left - tx) - dst.Width / 2.0f);
                cx += dsxdx * mcl;
                cy += dsydx * mcl;
                cz += dszdx * mcl;

                float mct = ((rect.Top - ty) - dst.Height / 2.0f);
                cx += dsxdy * mct;
                cy += dsydy * mct;
                cz += dszdy * mct;

                for (int y = rect.Top; y < rect.Bottom; ++y)
                {
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);
                    ColorBgra *srcPtr = src.GetPointAddressUnchecked(rect.Left, y);

                    float rx = cx;
                    float ry = cy;
                    float rz = cz;

                    for (int x = rect.Left; x < rect.Right; ++x)
                    {
                        if (rz > -divZ)
                        {
                            float div = divZ / (zoom * (divZ + rz));
                            float u   = (rx * div) + centerX;
                            float v   = (ry * div) + centerY;

                            if (tile || (u >= -1 && v >= -1 && u <= srcBounds.Width && v <= srcBounds.Height))
                            {
                                unchecked
                                {
                                    int  iu        = (int)Math.Floor(u);
                                    uint sxfrac    = (uint)(256 * (u - (float)iu));
                                    uint sxfracinv = 256 - sxfrac;

                                    int  iv        = (int)Math.Floor(v);
                                    uint syfrac    = (uint)(256 * (v - (float)iv));
                                    uint syfracinv = 256 - syfrac;

                                    uint wul = (uint)(sxfracinv * syfracinv);
                                    uint wur = (uint)(sxfrac * syfracinv);
                                    uint wll = (uint)(sxfracinv * syfrac);
                                    uint wlr = (uint)(sxfrac * syfrac);

                                    uint inBoundsMaskLeft   = tilingMask;
                                    uint inBoundsMaskTop    = tilingMask;
                                    uint inBoundsMaskRight  = tilingMask;
                                    uint inBoundsMaskBottom = tilingMask;

                                    int sx = iu;
                                    if (sx < 0)
                                    {
                                        sx = srcMaxX + ((sx + 1) % srcBounds.Width);
                                    }
                                    else if (sx > srcMaxX)
                                    {
                                        sx = sx % srcBounds.Width;
                                    }
                                    else
                                    {
                                        inBoundsMaskLeft = 0xffffffff;
                                    }

                                    int sy = iv;
                                    if (sy < 0)
                                    {
                                        sy = srcMaxY + ((sy + 1) % srcBounds.Height);
                                    }
                                    else if (sy > srcMaxY)
                                    {
                                        sy = sy % srcBounds.Height;
                                    }
                                    else
                                    {
                                        inBoundsMaskTop = 0xffffffff;
                                    }

                                    int sleft = sx;
                                    int sright;

                                    if (sleft == srcMaxX)
                                    {
                                        sright            = 0;
                                        inBoundsMaskRight = (iu == -1) ? 0xffffffff : tilingMask;
                                    }
                                    else
                                    {
                                        sright            = sleft + 1;
                                        inBoundsMaskRight = inBoundsMaskLeft & 0xffffffff;
                                    }

                                    int stop = sy;
                                    int sbottom;

                                    if (stop == srcMaxY)
                                    {
                                        sbottom            = 0;
                                        inBoundsMaskBottom = (iv == -1) ? 0xffffffff : tilingMask;
                                    }
                                    else
                                    {
                                        sbottom            = stop + 1;
                                        inBoundsMaskBottom = inBoundsMaskTop & 0xffffffff;
                                    }

                                    uint      maskUL = inBoundsMaskLeft & inBoundsMaskTop;
                                    ColorBgra cul    = ColorBgra.FromUInt32(src.GetPointUnchecked(sleft, stop).Bgra & maskUL);

                                    uint      maskUR = inBoundsMaskRight & inBoundsMaskTop;
                                    ColorBgra cur    = ColorBgra.FromUInt32(src.GetPointUnchecked(sright, stop).Bgra & maskUR);

                                    uint      maskLL = inBoundsMaskLeft & inBoundsMaskBottom;
                                    ColorBgra cll    = ColorBgra.FromUInt32(src.GetPointUnchecked(sleft, sbottom).Bgra & maskLL);

                                    uint      maskLR = inBoundsMaskRight & inBoundsMaskBottom;
                                    ColorBgra clr    = ColorBgra.FromUInt32(src.GetPointUnchecked(sright, sbottom).Bgra & maskLR);

                                    ColorBgra c = ColorBgra.BlendColors4W16IP(cul, wul, cur, wur, cll, wll, clr, wlr);

                                    if (c.A == 255 || !token.SourceAsBackground)
                                    {
                                        dstPtr->Bgra = c.Bgra;
                                    }
                                    else
                                    {
                                        *dstPtr = PaintFx.UserBlendOps.NormalBlendOp.ApplyStatic(*srcPtr, c);
                                    }
                                }
                            }
                            else
                            {
                                if (srcMask != 0)
                                {
                                    dstPtr->Bgra = srcPtr->Bgra;
                                }
                                else
                                {
                                    dstPtr->Bgra = 0;
                                }
                            }
                        }
                        else
                        {
                            if (srcMask != 0)
                            {
                                dstPtr->Bgra = srcPtr->Bgra;
                            }
                            else
                            {
                                dstPtr->Bgra = 0;
                            }
                        }

                        rx += dsxdx;
                        ry += dsydx;
                        rz += dszdx;

                        ++dstPtr;
                        ++srcPtr;
                    }

                    cx += dsxdy;
                    cy += dsydy;
                    cz += dszdy;
                }
            }
        }
Beispiel #34
0
        private void Draw(DrawingArea drawingarea1, Color tool_color, Cairo.PointD point, bool first_pixel)
        {
            int x = (int)point.X;
            int y = (int)point.Y;

            if (last_point.Equals(point_empty))
            {
                last_point = new Point(x, y);

                if (!first_pixel)
                {
                    return;
                }
            }

            Document doc = PintaCore.Workspace.ActiveDocument;

            if (doc.Workspace.PointInCanvas(point))
            {
                surface_modified = true;
            }

            ImageSurface surf = doc.CurrentUserLayer.Surface;

            if (first_pixel && doc.Workspace.PointInCanvas(point))
            {
                // Does Cairo really not support a single-pixel-long single-pixel-wide line?
                surf.Flush();
                int       shiftedX = (int)point.X;
                int       shiftedY = (int)point.Y;
                ColorBgra source   = surf.GetColorBgraUnchecked(shiftedX, shiftedY);
                source = UserBlendOps.NormalBlendOp.ApplyStatic(source, tool_color.ToColorBgra());
                surf.SetColorBgra(source, shiftedX, shiftedY);
                surf.MarkDirty();
            }
            else
            {
                using (Context g = new Context(surf)) {
                    g.AppendPath(doc.Selection.SelectionPath);
                    g.FillRule = FillRule.EvenOdd;
                    g.Clip();

                    g.Antialias = Antialias.None;

                    // Adding 0.5 forces cairo into the correct square:
                    // See https://bugs.launchpad.net/bugs/672232
                    g.MoveTo(last_point.X + 0.5, last_point.Y + 0.5);
                    g.LineTo(x + 0.5, y + 0.5);

                    g.Color     = tool_color;
                    g.LineWidth = 1;
                    g.LineCap   = LineCap.Square;

                    g.Stroke();
                }
            }

            Gdk.Rectangle r = GetRectangleFromPoints(last_point, new Point(x, y));

            doc.Workspace.Invalidate(doc.ClampToImageSize(r));

            last_point = new Point(x, y);
        }
Beispiel #35
0
        unsafe public override void Render(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.GetBottom();
                int rectLeft   = rect.Left;
                int rectRight  = rect.GetRight();

                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;
                        }
                    }
                }
            }
        }
Beispiel #36
0
        unsafe public override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
        {
            int w = dst.Width;
            int h = dst.Height;

            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.GetBottom(); y++)
                {
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(dst_dataptr, dst_width, rect.Left, y);

                    for (int x = rect.Left; x <= rect.GetRight(); 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.GetBottom(); y++)
                    {
                        ColorBgra *dstPtr = dst.GetPointAddressUnchecked(dst_dataptr, dst_width, rect.Left, y);

                        for (int x = rect.Left; x <= rect.GetRight(); ++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;
                        }
                    }
                }
            }
        }
Beispiel #37
0
        public unsafe override ColorBgra Apply(ColorBgra src, int area, int *hb, int *hg, int *hr, int *ha)
        {
            int minCount1 = area * (100 - this.intensity) / 200;
            int minCount2 = area * (100 + this.intensity) / 200;

            int bCount = 0;
            int b1     = 0;

            while (b1 < 255 && hb[b1] == 0)
            {
                ++b1;
            }

            while (b1 < 255 && bCount < minCount1)
            {
                bCount += hb[b1];
                ++b1;
            }

            int b2 = b1;

            while (b2 < 255 && bCount < minCount2)
            {
                bCount += hb[b2];
                ++b2;
            }

            int gCount = 0;
            int g1     = 0;

            while (g1 < 255 && hg[g1] == 0)
            {
                ++g1;
            }

            while (g1 < 255 && gCount < minCount1)
            {
                gCount += hg[g1];
                ++g1;
            }

            int g2 = g1;

            while (g2 < 255 && gCount < minCount2)
            {
                gCount += hg[g2];
                ++g2;
            }

            int rCount = 0;
            int r1     = 0;

            while (r1 < 255 && hr[r1] == 0)
            {
                ++r1;
            }

            while (r1 < 255 && rCount < minCount1)
            {
                rCount += hr[r1];
                ++r1;
            }

            int r2 = r1;

            while (r2 < 255 && rCount < minCount2)
            {
                rCount += hr[r2];
                ++r2;
            }

            int aCount = 0;
            int a1     = 0;

            while (a1 < 255 && hb[a1] == 0)
            {
                ++a1;
            }

            while (a1 < 255 && aCount < minCount1)
            {
                aCount += ha[a1];
                ++a1;
            }

            int a2 = a1;

            while (a2 < 255 && aCount < minCount2)
            {
                aCount += ha[a2];
                ++a2;
            }

            return(ColorBgra.FromBgra(
                       (byte)(255 - (b2 - b1)),
                       (byte)(255 - (g2 - g1)),
                       (byte)(255 - (r2 - r1)),
                       (byte)(a2)));
        }
        public unsafe void RenderColorDifferenceEffect(
            double[][] weights,
            RenderArgs dstArgs,
            RenderArgs srcArgs,
            Rectangle[] rois,
            int startIndex,
            int length)
        {
            Surface dst = dstArgs.Surface;
            Surface src = srcArgs.Surface;

            for (int i = startIndex; i < startIndex + length; ++i)
            {
                Rectangle rect = rois[i];

                // loop through each line of target rectangle
                for (int y = rect.Top; y < rect.Bottom; ++y)
                {
                    int fyStart = 0;
                    int fyEnd   = 3;

                    if (y == src.Bounds.Top)
                    {
                        fyStart = 1;
                    }
                    if (y == src.Bounds.Bottom - 1)
                    {
                        fyEnd = 2;
                    }

                    // loop through each point in the line
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);

                    for (int x = rect.Left; x < rect.Right; ++x)
                    {
                        int fxStart = 0;
                        int fxEnd   = 3;

                        if (x == src.Bounds.Left)
                        {
                            fxStart = 1;
                        }

                        if (x == src.Bounds.Right - 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(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;
                    }
                }
            }
        }
Beispiel #39
0
        public override void Render(Surface src, Surface dest, Rectangle[] rois, int startIndex, int length)
        {
            unsafe
            {
                int    w          = dest.Width;
                int    h          = dest.Height;
                double invH       = 1.0 / h;
                double invZoom    = 1.0 / this.zoom;
                double invQuality = 1.0 / this.quality;
                double aspect     = (double)h / (double)w;
                int    count      = this.quality * this.quality + 1;
                double invCount   = 1.0 / (double)count;

                for (int ri = startIndex; ri < startIndex + length; ++ri)
                {
                    Rectangle rect = rois[ri];

                    for (int y = rect.Top; y < rect.Bottom; y++)
                    {
                        ColorBgra *dstPtr = dest.GetPointAddressUnchecked(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 + this.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 = this.factor * j;


                                b += PixelUtils.ClampToByte(c - 768);
                                g += PixelUtils.ClampToByte(c - 512);
                                r += PixelUtils.ClampToByte(c - 256);
                                a += PixelUtils.ClampToByte(c - 0);
                            }

                            *dstPtr = ColorBgra.FromBgra(
                                PixelUtils.ClampToByte(b / count),
                                PixelUtils.ClampToByte(g / count),
                                PixelUtils.ClampToByte(r / count),
                                PixelUtils.ClampToByte(a / count));

                            ++dstPtr;
                        }
                    }
                }
            }
        }
        public override void Render(Surface src, Surface dst, Rectangle[] rois, int startIndex, int length)
        {
            unsafe
            {
                // Glow backgound
                glowRenderer.Render(src, dst, rois, startIndex, length);

                // Create black outlines by finding the edges of objects

                for (int i = startIndex; i < startIndex + length; ++i)
                {
                    Rectangle roi = rois[i];

                    for (int y = roi.Top; y < roi.Bottom; ++y)
                    {
                        int top    = y - radius;
                        int bottom = y + radius + 1;

                        if (top < 0)
                        {
                            top = 0;
                        }

                        if (bottom > dst.Height)
                        {
                            bottom = dst.Height;
                        }

                        ColorBgra *srcPtr = src.GetPointAddress(roi.X, y);
                        ColorBgra *dstPtr = src.GetPointAddress(roi.X, y);

                        for (int x = roi.Left; x < roi.Right; ++x)
                        {
                            int left  = x - radius;
                            int right = x + radius + 1;

                            if (left < 0)
                            {
                                left = 0;
                            }

                            if (right > dst.Width)
                            {
                                right = dst.Width;
                            }

                            int r = 0;
                            int g = 0;
                            int b = 0;

                            for (int v = top; v < bottom; v++)
                            {
                                ColorBgra *pRow = src.GetRowAddress(v);
                                int        j    = v - y + radius;

                                for (int u = left; u < right; u++)
                                {
                                    int i1 = u - x + radius;
                                    int w  = conv[j][i1];

                                    ColorBgra *pRef = pRow + u;

                                    r += pRef->R * w;
                                    g += pRef->G * w;
                                    b += pRef->B * w;
                                }
                            }

                            ColorBgra topLayer = ColorBgra.FromBgr(
                                PixelUtils.ClampToByte(b),
                                PixelUtils.ClampToByte(g),
                                PixelUtils.ClampToByte(r));

                            // Desaturate
                            topLayer = this.desaturateOp.Apply(topLayer);

                            // Adjust Brightness and Contrast
                            if (topLayer.R > (this.inkOutline * 255 / 100))
                            {
                                topLayer = ColorBgra.FromBgra(255, 255, 255, topLayer.A);
                            }
                            else
                            {
                                topLayer = ColorBgra.FromBgra(0, 0, 0, topLayer.A);
                            }

                            // Change Blend Mode to Darken
                            ColorBgra myPixel = this.darkenOp.Apply(topLayer, *dstPtr);
                            *         dstPtr  = myPixel;

                            ++srcPtr;
                            ++dstPtr;
                        }
                    }
                }
            }
        }
Beispiel #41
0
        private unsafe static void RenderClouds(Surface surface, 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;
                }
            }
        }
Beispiel #42
0
 public ColorEventArgs(ColorBgra color)
 {
     this.color = color;
 }
Beispiel #43
0
 /// <summary>
 /// Returns a Point3D object where X = R, Y = G, & Z = B. Alpha is ignored.
 /// </summary>
 /// <returns></returns>
 public static Point3D ToPoint3D(this ColorBgra colorBgra)
 {
     return(new Point3D(colorBgra.R, colorBgra.G, colorBgra.B));
 }
Beispiel #44
0
 /// <summary>
 /// Returns a Point3D object where X = R, Y = G, & Z = B. Alpha is ignored.
 /// </summary>
 /// <returns></returns>
 public static ColorBgra FromPoint3D(Point3D point)
 {
     return(ColorBgra.FromBgr(Utility.ClampToByte(point.Z),
                              Utility.ClampToByte(point.Y), Utility.ClampToByte(point.X)));
 }
Beispiel #45
0
            public void Create(Point seed, Surface src, RectangleRef[] limits, ColorBgra color, float Tolerance, ClusterClearEffectPlugin controller, bool[,] safePoints)
            {
                Ranges.Clear();
                int xL = seed.X;

                while (xL >= 0 && ColorUtils.RGBPercentage(color, src[xL, seed.Y]) <= Tolerance)
                {
                    --xL;
                }
                ++xL;
                int xR   = seed.X + 1;
                int maxR = src.Width;

                while (xR < maxR && ColorUtils.RGBPercentage(color, src[xR, seed.Y]) <= Tolerance)
                {
                    ++xR;
                }
                --xR;
                Ranges.Add(new RectangleRef(xL, seed.Y, xR - xL + 1, 1));

                Stack <ScanRange> scanRanges = new Stack <ScanRange>();

                scanRanges.Push(new ScanRange(xL, xR, seed.Y, 1));
                scanRanges.Push(new ScanRange(xL, xR, seed.Y, -1));
                int       xMin = 0;
                int       xMax = src.Width - 1;
                int       yMin = 0;
                int       yMax = src.Height - 1;
                ScanRange r;
                int       sleft;
                int       sright;

                while (scanRanges.Count != 0)
                {
                    if (controller.IsCancelRequested)
                    {
                        return;
                    }
                    r = scanRanges.Pop();
                    //scan left
                    for (sleft = r.left - 1; sleft >= xMin && ColorUtils.RGBPercentage(color, src[sleft, r.y]) <= Tolerance; --sleft)
                    {
                        safePoints[sleft, r.y] = true;
                    }
                    ++sleft;

                    //scan right
                    for (sright = r.right + 1; sright <= xMax && ColorUtils.RGBPercentage(color, src[sright, r.y]) <= Tolerance; ++sright)
                    {
                        safePoints[sright, r.y] = true;
                    }
                    --sright;
                    Ranges.Add(new RectangleRef(sleft, r.y, sright - sleft, 1));

                    //scan in same direction vertically
                    bool rangeFound = false;
                    int  rangeStart = 0;
                    int  newy       = r.y + r.direction;
                    if (newy >= yMin && newy <= yMax)
                    {
                        xL = sleft;
                        while (xL <= sright)
                        {
                            for (; xL <= sright; ++xL)
                            {
                                if (ColorUtils.RGBPercentage(color, src[xL, newy]) <= Tolerance)
                                {
                                    safePoints[xL, newy] = true;
                                    rangeFound           = true;
                                    rangeStart           = xL++;
                                    break;
                                }
                            }
                            for (; xL <= sright; ++xL)
                            {
                                if (ColorUtils.RGBPercentage(color, src[xL, newy]) > Tolerance)
                                {
                                    break;
                                }
                                safePoints[xL, newy] = true;
                            }
                            if (rangeFound)
                            {
                                rangeFound = false;
                                scanRanges.Push(new ScanRange(rangeStart, xL - 1, newy, r.direction));
                            }
                        }
                    }

                    //scan opposite direction vertically
                    newy = r.y - r.direction;
                    if (newy >= yMin && newy <= yMax)
                    {
                        xL = sleft;
                        while (xL < r.left)
                        {
                            for (; xL < r.left; ++xL)
                            {
                                if (ColorUtils.RGBPercentage(color, src[xL, newy]) <= Tolerance)
                                {
                                    safePoints[xL, newy] = true;
                                    rangeFound           = true;
                                    rangeStart           = xL++;
                                    break;
                                }
                            }
                            for (; xL < r.left; ++xL)
                            {
                                if (ColorUtils.RGBPercentage(color, src[xL, newy]) > Tolerance)
                                {
                                    break;
                                }
                                safePoints[xL, newy] = true;
                            }
                            if (rangeFound)
                            {
                                rangeFound = false;
                                scanRanges.Push(new ScanRange(rangeStart, xL - 1, newy, -r.direction));
                            }
                        }
                        xL = r.right + 1;
                        while (xL <= sright)
                        {
                            for (; xL <= sright; ++xL)
                            {
                                if (ColorUtils.RGBPercentage(color, src[xL, newy]) <= Tolerance)
                                {
                                    safePoints[xL, newy] = true;
                                    rangeFound           = true;
                                    rangeStart           = xL++;
                                    break;
                                }
                            }
                            for (; xL <= sright; ++xL)
                            {
                                if (ColorUtils.RGBPercentage(color, src[xL, newy]) > Tolerance)
                                {
                                    break;
                                }
                                safePoints[xL, newy] = true;
                            }
                            if (rangeFound)
                            {
                                rangeFound = false;
                                scanRanges.Push(new ScanRange(rangeStart, xL - 1, newy, -r.direction));
                            }
                        }
                    }
                }
                CompressRanges();
            }
Beispiel #46
0
 public virtual unsafe ColorBgra Apply(ColorBgra src, int area, int *hb, int *hg, int *hr, int *ha)
 {
     return(src);
 }
Beispiel #47
0
        public unsafe override ColorBgra Apply(ColorBgra src, int area, int *hb, int *hg, int *hr, int *ha)
        {
            ColorBgra median = GetPercentile(50, area, hb, hg, hr, ha);

            return(ColorBgra.Lerp(src, median, -0.5f));
        }
Beispiel #48
0
        public override void Render(Surface src, Surface dst, Rectangle[] rois, int startIndex, int length)
        {
            ColorBgra colTransparent = ColorBgra.Transparent;

            unsafe
            {
                int     aaSampleCount = quality * quality;
                PointF *aaPoints      = stackalloc PointF[aaSampleCount];
                PixelUtils.GetRgssOffsets(aaPoints, aaSampleCount, quality);
                ColorBgra *samples = stackalloc ColorBgra[aaSampleCount];

                TransformData td;

                for (int n = startIndex; n < startIndex + length; ++n)
                {
                    Rectangle rect = rois[n];

                    for (int y = rect.Top; y < rect.Bottom; y++)
                    {
                        ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);

                        double relativeY = y - this.yCenterOffset;

                        for (int x = rect.Left; x < rect.Right; x++)
                        {
                            double relativeX = x - this.xCenterOffset;

                            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 + this.xCenterOffset);
                                float sampleY = (float)(td.Y + this.yCenterOffset);

                                ColorBgra sample = colPrimary;

                                if (IsOnSurface(src, sampleX, sampleY))
                                {
                                    sample = src.GetBilinearSample(sampleX, sampleY);
                                }
                                else
                                {
                                    switch (this.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[x, y];
                                        break;

                                    default:
                                        break;
                                    }
                                }

                                samples[sampleCount] = sample;
                                ++sampleCount;
                            }

                            *dstPtr = ColorBgra.Blend(samples, sampleCount);
                            ++dstPtr;
                        }
                    }
                }
            }
        }
Beispiel #49
0
        public unsafe override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
        {
            var selection = PintaCore.LivePreview.RenderBounds;

            this.defaultRadius  = Math.Min(selection.Width, selection.Height) * 0.5;
            this.defaultRadius2 = this.defaultRadius * this.defaultRadius;

            var x_center_offset = selection.Left + (selection.Width * (1.0 + Data.CenterOffset.X) * 0.5);
            var y_center_offset = selection.Top + (selection.Height * (1.0 + Data.CenterOffset.Y) * 0.5);

            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.GetBottom(); y++)
                {
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);

                    double relativeY = y - y_center_offset;

                    for (int x = rect.Left; x <= rect.GetRight(); x++)
                    {
                        double relativeX = x - x_center_offset;

                        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 + x_center_offset);
                            float sampleY = (float)(td.Y + y_center_offset);

                            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.GetColorBgraUnchecked(x, y);
                                    break;

                                default:

                                    break;
                                }
                            }

                            samples[sampleCount] = sample;
                            ++sampleCount;
                        }

                        *dstPtr = ColorBgra.Blend(samples, sampleCount);
                        ++dstPtr;
                    }
                }
            }
        }
Beispiel #50
0
        public unsafe void RenderConvolutionFilter(int[][] weights, int offset, RenderArgs dstArgs, RenderArgs srcArgs,
                                                   Rectangle[] rois, int startIndex, int length)
        {
            int weightsWidth  = weights[0].Length;
            int weightsHeight = weights.Length;

            int fYOffset = -(weightsHeight / 2);
            int fXOffset = -(weightsWidth / 2);

            // we cache the beginning and ending horizontal indices into the weights matrix
            // for every source pixel X location
            // i.e. for src[x,y], where we're concerned with x, what weight[x,y] horizontal
            // extent should we worry about?
            // this way we end up with less branches and faster code (hopefully?!)
            FExtent fxExtent = GetFExtent(srcArgs.Surface.Width, weightsWidth);
            FExtent fyExtent = GetFExtent(srcArgs.Surface.Height, weightsHeight);

            for (int ri = startIndex; ri < startIndex + length; ++ri)
            {
                Rectangle roi = rois[ri];

                for (int y = roi.Top; y < roi.Bottom; ++y)
                {
                    ColorBgra *dstPixel = dstArgs.Surface.GetPointAddressUnchecked(roi.Left, y);
                    int        fyStart  = fyExtent.fStarts[y];
                    int        fyEnd    = fyExtent.fEnds[y];

                    for (int x = roi.Left; x < roi.Right; ++x)
                    {
                        int redSum      = 0;
                        int greenSum    = 0;
                        int blueSum     = 0;
                        int alphaSum    = 0;
                        int colorFactor = 0;
                        int alphaFactor = 0;
                        int fxStart     = fxExtent.fStarts[x];
                        int fxEnd       = fxExtent.fEnds[x];

                        for (int fy = fyStart; fy < fyEnd; ++fy)
                        {
                            int srcY  = y + fy + fYOffset;
                            int srcX1 = x + fXOffset + fxStart;

                            ColorBgra *srcPixel = srcArgs.Surface.GetPointAddressUnchecked(srcX1, srcY);
                            int[]      wRow     = weights[fy];

                            for (int fx = fxStart; fx < fxEnd; ++fx)
                            {
                                int srcX   = fx + srcX1;
                                int weight = wRow[fx];

                                ColorBgra c = *srcPixel;

                                alphaFactor += weight;
                                weight       = weight * (c.A + (c.A >> 7));
                                colorFactor += weight;
                                weight     >>= 8;

                                redSum   += c.R * weight;
                                blueSum  += c.B * weight;
                                greenSum += c.G * weight;
                                alphaSum += c.A * weight;

                                ++srcPixel;
                            }
                        }

                        colorFactor /= 256;

                        if (colorFactor != 0)
                        {
                            redSum   /= colorFactor;
                            greenSum /= colorFactor;
                            blueSum  /= colorFactor;
                        }
                        else
                        {
                            redSum   = 0;
                            greenSum = 0;
                            blueSum  = 0;
                        }

                        if (alphaFactor != 0)
                        {
                            alphaSum /= alphaFactor;
                        }
                        else
                        {
                            alphaSum = 0;
                        }

                        redSum   += offset;
                        greenSum += offset;
                        blueSum  += offset;
                        alphaSum += offset;

                        #region clamp values to [0,255]
                        if (redSum < 0)
                        {
                            redSum = 0;
                        }
                        else if (redSum > 255)
                        {
                            redSum = 255;
                        }

                        if (greenSum < 0)
                        {
                            greenSum = 0;
                        }
                        else if (greenSum > 255)
                        {
                            greenSum = 255;
                        }

                        if (blueSum < 0)
                        {
                            blueSum = 0;
                        }
                        else if (blueSum > 255)
                        {
                            blueSum = 255;
                        }

                        if (alphaSum < 0)
                        {
                            alphaSum = 0;
                        }
                        else if (alphaSum > 255)
                        {
                            alphaSum = 255;
                        }
                        #endregion

                        *dstPixel = ColorBgra.FromBgra((byte)blueSum, (byte)greenSum, (byte)redSum, (byte)alphaSum);
                        ++dstPixel;
                    }
                }
            }
        }
Beispiel #51
0
        protected override void OnPaint(PaintEventArgs e)
        {
            e.Graphics.CompositingMode = CompositingMode.SourceOver;
            int scaledSwatchSize = UI.ScaleWidth(this.unscaledSwatchSize);
            int swatchColumns = this.ClientSize.Width / scaledSwatchSize;

            Point mousePt = Control.MousePosition;
            mousePt = PointToClient(mousePt);
            int activeIndex = MouseXYToColorIndex(mousePt.X, mousePt.Y);

            for (int i = 0; i < this.colors.Count; ++i)
            {
                ColorBgra c = this.colors[i];

                int swatchX = i % swatchColumns;
                int swatchY = i / swatchColumns;

                Rectangle swatchRect = new Rectangle(
                    swatchX * scaledSwatchSize,
                    swatchY * scaledSwatchSize,
                    scaledSwatchSize,
                    scaledSwatchSize);

                PushButtonState state;

                if (this.mouseDown)
                {
                    if (i == this.mouseDownIndex)
                    {
                        state = PushButtonState.Pressed;
                    }
                    else
                    {
                        state = PushButtonState.Normal;
                    }
                }
                else if (i == activeIndex)
                {
                    state = PushButtonState.Hot;
                }
                else
                {
                    state = PushButtonState.Normal;
                }

                bool drawOutline;

                switch (state)
                {
                    case PushButtonState.Hot:
                        drawOutline = true;
                        break;

                    case PushButtonState.Pressed:
                        drawOutline = false;
                        break;

                    case PushButtonState.Default:
                    case PushButtonState.Disabled:
                    case PushButtonState.Normal:
                        drawOutline = false;
                        break;

                    default:
                        throw new InvalidEnumArgumentException();
                }

                Utility.DrawColorRectangle(e.Graphics, swatchRect, c.ToColor(), drawOutline);
            }

            if (this.blinkHighlight)
            {
                int period = (Math.Abs(Environment.TickCount) / blinkInterval) % 2;
                Color color;

                switch (period)
                {
                    case 0:
                        color = SystemColors.Window;
                        break;

                    case 1:
                        color = SystemColors.Highlight;
                        break;

                    default:
                        throw new InvalidOperationException();
                }

                using (Pen pen = new Pen(color))
                {
                    e.Graphics.DrawRectangle(pen, new Rectangle(0, 0, Width - 1, Height - 1));
                }
            }

            base.OnPaint(e);
        }
        private void Render(Surface dst, Surface src, Rectangle rect)
        {
            Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();

            Size margin = new Size
            {
                Width  = Math.Min(this.horMargin, this.trimmedSurface.Width / 2),
                Height = Math.Min(this.verMargin, this.trimmedSurface.Height / 2)
            };

            Size effectiveTileSize = new Size(this.trimmedSurface.Width - margin.Width, this.trimmedSurface.Height - margin.Height);

            int maxHorLoops = (selection.Width - margin.Width) / effectiveTileSize.Width;
            int maxVerLoops = (selection.Height - margin.Height) / effectiveTileSize.Height;

            Size sheetSize = new Size
            {
                Width  = maxHorLoops * effectiveTileSize.Width + margin.Width,
                Height = maxVerLoops * effectiveTileSize.Height + margin.Height
            };

            PointF offsetForCenter = new PointF((selection.Width - sheetSize.Width) / 2f, (selection.Height - sheetSize.Height) / 2f);

            Rectangle sheetRect = new Rectangle
            {
                X    = (int)Math.Round(selection.X + offsetForCenter.X + (this.position.First * offsetForCenter.X)),
                Y    = (int)Math.Round(selection.Y + offsetForCenter.Y + (this.position.Second * offsetForCenter.Y)),
                Size = sheetSize
            };

            for (int y = rect.Top; y < rect.Bottom; y++)
            {
                if (this.IsCancelRequested)
                {
                    return;
                }
                for (int x = rect.Left; x < rect.Right; x++)
                {
                    if (!sheetRect.Contains(x, y))
                    {
                        dst[x, y] = ColorBgra.Transparent;
                        continue;
                    }

                    int xLoop         = (x - sheetRect.X) / effectiveTileSize.Width;
                    int xOffset       = xLoop * margin.Width + x - sheetRect.X;
                    int xOverlapStart = effectiveTileSize.Width * xLoop + sheetRect.X;

                    int yLoop         = (y - sheetRect.Y) / effectiveTileSize.Height;
                    int yOffset       = yLoop * margin.Height + y - sheetRect.Y;
                    int yOverlapStart = effectiveTileSize.Height * yLoop + sheetRect.Y;

                    if (xLoop > 0 && yLoop > 0 &&
                        x >= xOverlapStart && x < xOverlapStart + margin.Width &&
                        y >= yOverlapStart && y < yOverlapStart + margin.Height)
                    {
                        if (xLoop < maxHorLoops && yLoop < maxVerLoops)
                        {
                            ColorBgra colorA = this.normalOp.Apply(
                                this.trimmedSurface.GetBilinearSampleWrapped(xOffset - margin.Width, yOffset),
                                this.trimmedSurface.GetBilinearSampleWrapped(xOffset, yOffset));
                            ColorBgra colorB = this.normalOp.Apply(
                                this.trimmedSurface.GetBilinearSampleWrapped(xOffset, yOffset - margin.Height),
                                colorA);
                            dst[x, y] = this.normalOp.Apply(
                                this.trimmedSurface.GetBilinearSampleWrapped(xOffset - margin.Width, yOffset - margin.Height),
                                colorB);
                        }
                        else if (xLoop < maxHorLoops)
                        {
                            dst[x, y] = this.normalOp.Apply(
                                this.trimmedSurface.GetBilinearSampleWrapped(xOffset - margin.Width, yOffset - margin.Height),
                                this.trimmedSurface.GetBilinearSampleWrapped(xOffset, yOffset - margin.Height));
                        }
                        else if (yLoop < maxVerLoops)
                        {
                            dst[x, y] = this.normalOp.Apply(
                                this.trimmedSurface.GetBilinearSampleWrapped(xOffset - margin.Width, yOffset - margin.Height),
                                this.trimmedSurface.GetBilinearSampleWrapped(xOffset - margin.Width, yOffset));
                        }
                        else
                        {
                            dst[x, y] = this.trimmedSurface.GetBilinearSampleWrapped(xOffset - margin.Width, yOffset - margin.Height);
                        }
                    }
                    else if (xLoop > 0 && x >= xOverlapStart && x < xOverlapStart + margin.Width)
                    {
                        dst[x, y] = (xLoop < maxHorLoops) ?
                                    this.normalOp.Apply(
                            this.trimmedSurface.GetBilinearSampleWrapped(xOffset - margin.Width, yOffset),
                            this.trimmedSurface.GetBilinearSampleWrapped(xOffset, yOffset)) :
                                    this.trimmedSurface.GetBilinearSampleWrapped(xOffset - margin.Width, yOffset);
                    }
                    else if (yLoop > 0 && y >= yOverlapStart && y < yOverlapStart + margin.Height)
                    {
                        dst[x, y] = (yLoop < maxVerLoops) ?
                                    this.normalOp.Apply(
                            this.trimmedSurface.GetBilinearSampleWrapped(xOffset, yOffset - margin.Height),
                            this.trimmedSurface.GetBilinearSampleWrapped(xOffset, yOffset)) :
                                    this.trimmedSurface.GetBilinearSampleWrapped(xOffset, yOffset - margin.Height);
                    }
                    else
                    {
                        dst[x, y] = this.trimmedSurface.GetBilinearSampleWrapped(xOffset, yOffset);
                    }
                }
            }
        }
Beispiel #53
0
		private void DrawChannel(Context g, ColorBgra color, int channel, long max, float mean)
        {
			Rectangle rect = Allocation.ToCairoRectangle ();
			Histogram histogram = Histogram;
			
            int l = (int)rect.X;
            int t = (int)rect.Y;
			int r = (int)(rect.X + rect.Width);
            int b = (int)(rect.Y + rect.Height);
			
            int entries = histogram.Entries;
            long[] hist = histogram.HistogramValues [channel];
			
            ++max;

            if (FlipHorizontal) {
                Utility.Swap(ref l, ref r);
            }

            if (!FlipVertical) {
                Utility.Swap(ref t, ref b);
            }

            PointD[] points = new PointD[entries + 2];

            points[entries] = new PointD (Utility.Lerp (l, r, -1), Utility.Lerp (t, b, 20));
            points[entries + 1] = new PointD (Utility.Lerp (l, r, -1), Utility.Lerp (b, t, 20));
			
            for (int i = 0; i < entries; i += entries - 1) {
                points[i] = new PointD (
                    Utility.Lerp (l, r, (float)hist[i] / (float)max),
                    Utility.Lerp (t, b, (float)i / (float)entries));
				
				CheckPoint (rect, points [i]);
            }

            long sum3 = hist[0] + hist[1];
            
            for (int i = 1; i < entries - 1; ++i) {
                sum3 += hist[i + 1];

                points[i] = new PointD(
                    Utility.Lerp(l, r, (float)(sum3) / (float)(max * 3.1f)),
                    Utility.Lerp(t, b, (float)i / (float)entries));
			
				CheckPoint (rect, points [i]);
                sum3 -= hist[i - 1];
            }

            byte intensity = selected[channel] ? (byte)96 : (byte)32;
            ColorBgra pen_color = ColorBgra.Blend (ColorBgra.Black, color, intensity);
            ColorBgra brush_color = color;
           	brush_color.A = intensity;
			
			g.LineWidth = 1;
			
			g.Rectangle (rect);
			g.Clip ();
			g.DrawPolygonal (points, pen_color.ToCairoColor ());
			g.FillPolygonal (points, brush_color.ToCairoColor ());
        }
Beispiel #54
0
        public override void Render(Surface src, Surface dst, Rectangle[] rois, int start, int len)
        {
            //TODO: review here
            unsafe
            {
                for (int i = start; i < start + len; ++i)
                {
                    Rectangle rect = rois[i];

                    // loop through each line of target rectangle
                    for (int y = rect.Top; y < rect.Bottom; ++y)
                    {
                        int fyStart = 0;
                        int fyEnd   = 3;

                        if (y == src.Bounds.Top)
                        {
                            fyStart = 1;
                        }

                        if (y == src.Bounds.Bottom - 1)
                        {
                            fyEnd = 2;
                        }

                        // loop through each point in the line
                        ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);

                        for (int x = rect.Left; x < rect.Right; ++x)
                        {
                            int fxStart = 0;
                            int fxEnd   = 3;

                            if (x == src.Bounds.Left)
                            {
                                fxStart = 1;
                            }

                            if (x == src.Bounds.Right - 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(x - 1 + fx, y - 1 + fy);
                                    double    intensity = (double)c.GetIntensityByte();
                                    sum += weight * intensity;
                                }
                            }

                            int iSum = (int)sum + 128;

                            if (iSum > 255)
                            {
                                iSum = 255;
                            }
                            else if (iSum < 0)
                            {
                                iSum = 0;
                            }

                            *dstPtr = ColorBgra.FromBgra((byte)iSum, (byte)iSum, (byte)iSum, 255);

                            ++dstPtr;
                        }
                    }
                }
            }
        }
Beispiel #55
0
 /// <summary>
 /// Returns a Vector3D object where X = R, Y = G, & Z = B. Alpha is ignored.
 /// </summary>
 /// <returns></returns>
 public static Vector3D ToVector3D(this ColorBgra colorBgra)
 {
     return(new Vector3D(colorBgra.R, colorBgra.G, colorBgra.B));
 }
Beispiel #56
0
 //same as Aply, except the histogram is alpha-weighted instead of keeping a separate alpha channel histogram.
 public virtual unsafe ColorBgra ApplyWithAlpha(ColorBgra src, int area, int sum, int *hb, int *hg, int *hr)
 {
     return(src);
 }
Beispiel #57
0
 /// <summary>
 /// Returns a Vector3D object where X = other.R - colorBgra.R,
 /// Y = other.G - colorBgra.G, & Z = other.B - colorBgra.B. Alpha is ignored.
 /// </summary>
 /// <returns></returns>
 public static Vector3D ToVector3D(this ColorBgra colorBgra, ColorBgra other)
 {
     return(other.ToPoint3D() - colorBgra.ToPoint3D());
 }
Beispiel #58
0
        public static float GetHue(this ColorBgra colorBgra)
        {
            Color colorArgb = colorBgra.ToColor();

            return(colorArgb.GetHue());
        }
Beispiel #59
0
        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.Bottom; ++y)
                {
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);

                    for (int x = rect.Left; x < rect.Right; ++x)
                    {
                        int sampleCount = 0;

                        PointD a = new PointD((float)x + points[0].X, (float)y + points[0].Y);
                        PointD b = new PointD((float)x + points[points.Length - 1].X, (float)y + points[points.Length - 1].Y);

                        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;
                    }
                }
            }
        }
Beispiel #60
0
        public unsafe override void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, System.Drawing.Rectangle[] rois, int startIndex, int length)
        {
            TwoAmountsConfigToken token = (TwoAmountsConfigToken)parameters;

            float   twist = token.Amount1;
            Surface dst   = dstArgs.Surface;
            Surface src   = srcArgs.Surface;

            float hw     = dst.Width / 2.0f;
            float hh     = dst.Height / 2.0f;
            float maxrad = Math.Min(hw, hh);

            twist = twist * twist * Math.Sign(twist);

            int     aaLevel   = token.Amount2;
            int     aaSamples = aaLevel * aaLevel + 1;
            PointF *aaPoints  = stackalloc PointF[aaSamples];

            for (int i = 0; i < aaSamples; ++i)
            {
                PointF pt = new PointF(
                    ((i * aaLevel) / (float)aaSamples),
                    i / (float)aaSamples);

                pt.X       -= (int)pt.X;
                aaPoints[i] = pt;
            }

            for (int n = startIndex; n < startIndex + length; ++n)
            {
                Rectangle rect = rois[n];
                for (int y = rect.Top; y < rect.Bottom; y++)
                {
                    float      j      = y - hh;
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);
                    ColorBgra *srcPtr = src.GetPointAddressUnchecked(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 + aaPoints[p].X;
                                float  v     = j + 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(
                                    (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;
                    }
                }
            }
        }