public unsafe CairoSurfaceWrapper (Cairo.ImageSurface surface)
		{
			this.surface = surface;
			this.data_ptr = (ColorBgra*)surface.DataPtr;
			height = surface.Height;
			width = surface.Width;
		}
Пример #2
0
        public BitVector2DSurfaceAdapter(ImageSurface surface)
        {
            if (surface == null)
                throw new ArgumentNullException ("surface");

            this.surface = surface;
            src_width = surface.Width;
            src_height = surface.Height;
            src_data_ptr = (ColorBgra*)surface.DataPtr;
        }
		public unsafe override void BeginUpdate ()
		{
			Interlocked.Increment (ref lock_count);

			if (lock_count > 1)
				return;

			bitmap_data = surface.LockBits (new System.Drawing.Rectangle (0, 0, surface.Width, surface.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
			data_ptr = (ColorBgra*)bitmap_data.Scan0;
		}
Пример #4
0
        internal static unsafe void Rotate90CW(ref Surface surface)
        {
            Surface temp = null;

            try
            {
                int newWidth  = surface.Height;
                int newHeight = surface.Width;

                temp = new Surface(newWidth, newHeight);

                int lastColumn = newWidth - 1;

                for (int y = 0; y < newWidth; y++)
                {
                    ColorBgra *srcPtr = surface.GetRowPointerUnchecked(y);
                    ColorBgra *dstPtr = temp.GetPointPointerUnchecked(lastColumn - y, 0);

                    for (int x = 0; x < newHeight; x++)
                    {
                        *dstPtr = *srcPtr;

                        srcPtr++;
                        dstPtr += newWidth;
                    }
                }

                surface.Dispose();
                surface = temp;
                temp    = null;
            }
            finally
            {
                temp?.Dispose();
            }
        }
Пример #5
0
        ///////////////////////////////////////////////////////////////////////////////
        //
        // The color-conversion formulas come from the Colour Space Conversions FAQ:
        //     http://www.poynton.com/PDFs/coloureq.pdf
        //
        // RGB --> CMYK                              CMYK --> RGB
        // ---------------------------------------   --------------------------------------------
        // Black   = minimum(1-Red,1-Green,1-Blue)   Red   = 1-minimum(1,Cyan*(1-Black)+Black)
        // Cyan    = (1-Red-Black)/(1-Black)         Green = 1-minimum(1,Magenta*(1-Black)+Black)
        // Magenta = (1-Green-Black)/(1-Black)       Blue  = 1-minimum(1,Yellow*(1-Black)+Black)
        // Yellow  = (1-Blue-Black)/(1-Black)
        //
        ///////////////////////////////////////////////////////////////////////////////

        private static unsafe void SetPDNRowCmyk(ColorBgra *pDest, ColorBgra *pDestEnd,
                                                 int idxSrc, DecodeContext context)
        {
            while (pDest < pDestEnd)
            {
                // CMYK values are stored as complements, presumably to allow for some
                // measure of compatibility with RGB-only applications.
                var C = 255 - context.Channels[0].ImageData[idxSrc];
                var M = 255 - context.Channels[1].ImageData[idxSrc];
                var Y = 255 - context.Channels[2].ImageData[idxSrc];
                var K = 255 - context.Channels[3].ImageData[idxSrc];

                int nRed   = 255 - Math.Min(255, C * (255 - K) / 255 + K);
                int nGreen = 255 - Math.Min(255, M * (255 - K) / 255 + K);
                int nBlue  = 255 - Math.Min(255, Y * (255 - K) / 255 + K);

                pDest->R = (byte)nRed;
                pDest->G = (byte)nGreen;
                pDest->B = (byte)nBlue;

                pDest++;
                idxSrc += context.ByteDepth;
            }
        }
Пример #6
0
        public void Apply(Surface dst, Surface lhs, Surface rhs)
        {
            if (dst.Size != lhs.Size)
            {
                throw new ArgumentException("dst.Size != lhs.Size");
            }

            if (lhs.Size != rhs.Size)
            {
                throw new ArgumentException("lhs.Size != rhs.Size");
            }

            unsafe
            {
                for (int y = 0; y < dst.Height; ++y)
                {
                    ColorBgra *dstPtr = dst.GetRowAddressUnchecked(y);
                    ColorBgra *lhsPtr = lhs.GetRowAddressUnchecked(y);
                    ColorBgra *rhsPtr = lhs.GetRowAddressUnchecked(y);

                    Apply(dstPtr, lhsPtr, rhsPtr, dst.Width);
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Check for non-transparent pixels in a row, or portion of a row.
        /// Expands the size of the image rectangle if any were found.
        /// </summary>
        /// <returns>True if non-transparent pixels were found, false otherwise.</returns>
        unsafe private static bool ExpandImageRectangle(Surface surface, int y,
                                                        int xStart, int xEnd, ref Util.RectanglePosition rectPos)
        {
            bool fPixelFound = false;

            ColorBgra *rowStart = surface.GetRowAddress(y);
            ColorBgra *pixel    = rowStart + xStart;

            for (int x = xStart; x < xEnd; x++)
            {
                if (pixel->A > 0)
                {
                    // Expand the rectangle to include the specified point.
                    if (x < rectPos.Left)
                    {
                        rectPos.Left = x;
                    }
                    if (x > rectPos.Right)
                    {
                        rectPos.Right = x;
                    }
                    if (y < rectPos.Top)
                    {
                        rectPos.Top = y;
                    }
                    if (y > rectPos.Bottom)
                    {
                        rectPos.Bottom = y;
                    }
                    fPixelFound = true;
                }
                pixel++;
            }

            return(fPixelFound);
        }
Пример #8
0
 /// <summary>
 /// Add a given color value to the octree
 /// </summary>
 /// <param name="pixel"></param>
 public void AddColor(ColorBgra *pixel)
 {
     // Check if this request is for the same color as the last
     if (this._previousColor == pixel->Bgra)
     {
         // If so, check if I have a previous node setup. This will only ocurr if the first color in the image
         // happens to be black, with an alpha component of zero.
         if (null == this._previousNode)
         {
             this._previousColor = pixel->Bgra;
             this._root.AddColor(pixel, this._maxColorBits, 0, this);
         }
         else
         {
             // Just update the previous node
             this._previousNode.Increment(pixel);
         }
     }
     else
     {
         this._previousColor = pixel->Bgra;
         this._root.AddColor(pixel, this._maxColorBits, 0, this);
     }
 }
 public unsafe override void Apply(ColorBgra *dst, ColorBgra *lhs, ColorBgra *rhs, int length)
 {
     PlatformMemory.Copy(dst, rhs, (ulong)length * (ulong)ColorBgra.SizeOf);
 }
Пример #10
0
        public unsafe override void Render(EffectConfigToken properties, RenderArgs dstArgs, RenderArgs srcArgs, 
            Rectangle[] rois, int startIndex, int length)
        {
            TwoAmountsConfigToken token = (TwoAmountsConfigToken)properties;
            int brushSize = token.Amount1;
            byte smoothness = (byte)token.Amount2;
            Surface src = srcArgs.Surface;
            Surface dst = dstArgs.Surface;
            int width = src.Width;
            int height = src.Height;

            int arrayLens = 1 + smoothness;
            int* intensityCount = stackalloc int[arrayLens];
            uint* avgRed = stackalloc uint[arrayLens];
            uint* avgGreen = stackalloc uint[arrayLens];
            uint* avgBlue = stackalloc uint[arrayLens];
            uint* avgAlpha = stackalloc uint[arrayLens];

            byte maxIntensity = smoothness;

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

                int rectTop = rect.Top;
                int rectBottom = rect.Bottom;
                int rectLeft = rect.Left;
                int rectRight = rect.Right;

                for (int y = rectTop; y < rectBottom; ++y)
                {
                    ColorBgra *dstPtr = dst.GetPointAddress(rect.Left, y);

                    int top = y - brushSize;
                    int bottom = y + brushSize + 1;

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

                    if (bottom > height)
                    {
                        bottom = height;
                    }

                    for (int x = rectLeft; x < rectRight; ++x)
                    {
                        int left = x - brushSize;
                        int right = x + brushSize + 1;

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

                        if (right > width)
                        {
                            right = width;
                        }

                        for (int i = 0; i < arrayLens; ++i)
                        {
                            intensityCount[i] = 0;
                            avgRed[i] = 0;
                            avgGreen[i] = 0;
                            avgBlue[i] = 0;
                            avgAlpha[i] = 0;
                        }

                        int numInt = 0;

                        for (int j = top; j < bottom; ++j)
                        {
                            ColorBgra *srcPtr = src.GetPointAddress(left, j);

                            for (int i = left; i < right; ++i)
                            {
                                byte intensity = (byte)((srcPtr->GetIntensityByte() * maxIntensity) / 255);
                                ++intensityCount[intensity];
                                ++numInt;

                                avgRed[intensity] += srcPtr->R;
                                avgGreen[intensity] += srcPtr->G;
                                avgBlue[intensity] += srcPtr->B;
                                avgAlpha[intensity] += srcPtr->A;

                                ++srcPtr;
                            }
                        }

                        byte chosenIntensity = 0;
                        int maxInstance = 0;

                        for (int i = 0; i <= maxIntensity; ++i)
                        {
                            if (intensityCount[i] > maxInstance)
                            {
                                chosenIntensity = (byte)i;
                                maxInstance = intensityCount[i];
                            }
                        }

                        byte R = (byte)(avgRed[chosenIntensity] / maxInstance);
                        byte G = (byte)(avgGreen[chosenIntensity] / maxInstance);
                        byte B = (byte)(avgBlue[chosenIntensity] / maxInstance);
                        byte A = (byte)(avgAlpha[chosenIntensity] / maxInstance);

                        *dstPtr = ColorBgra.FromBgra(B, G, R, A);
                        ++dstPtr;
                    }
                }
            }
        }
Пример #11
0
        public unsafe override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
        {
            float twist = Data.Amount;

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

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

            int     aaLevel   = Data.Antialias;
            int     aaSamples = aaLevel * aaLevel + 1;
            PointD *aaPoints  = stackalloc PointD[aaSamples];

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

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

            int        src_width    = src.Width;
            ColorBgra *src_data_ptr = (ColorBgra *)src.DataPtr;

            foreach (var rect in rois)
            {
                for (int y = rect.Top; y < rect.Bottom; y++)
                {
                    float      j      = y - hh;
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);
                    ColorBgra *srcPtr = src.GetPointAddressUnchecked(src_data_ptr, src_width, rect.Left, y);

                    for (int x = rect.Left; x < rect.Right; x++)
                    {
                        float i = x - hw;

                        if (i * i + j * j > (maxrad + 1) * (maxrad + 1))
                        {
                            *dstPtr = *srcPtr;
                        }
                        else
                        {
                            int b = 0;
                            int g = 0;
                            int r = 0;
                            int a = 0;

                            for (int p = 0; p < aaSamples; ++p)
                            {
                                float  u     = i + (float)aaPoints[p].X;
                                float  v     = j + (float)aaPoints[p].Y;
                                double rad   = Math.Sqrt(u * u + v * v);
                                double theta = Math.Atan2(v, u);

                                double t = 1 - rad / maxrad;

                                t = (t < 0) ? 0 : (t * t * t);

                                theta += (t * twist) / 100;

                                ColorBgra sample = src.GetPointUnchecked(src_data_ptr, src_width,
                                                                         (int)(hw + (float)(rad * Math.Cos(theta))),
                                                                         (int)(hh + (float)(rad * Math.Sin(theta))));

                                b += sample.B;
                                g += sample.G;
                                r += sample.R;
                                a += sample.A;
                            }

                            *dstPtr = ColorBgra.FromBgra(
                                (byte)(b / aaSamples),
                                (byte)(g / aaSamples),
                                (byte)(r / aaSamples),
                                (byte)(a / aaSamples));
                        }

                        ++dstPtr;
                        ++srcPtr;
                    }
                }
            }
        }
Пример #12
0
        protected override unsafe Gdk.Rectangle OnMouseMove(Context g, Color strokeColor, ImageSurface surface,
                                                            int x, int y, int lastX, int lastY)
        {
            int rad = (int)(g.LineWidth / 2.0 + 0.5);

            if (rad < 2)
            {
                rad = 2;
            }

            Gdk.Rectangle surface_rect = new Gdk.Rectangle(0, 0, surface.Width, surface.Height);
            Gdk.Rectangle brush_rect   = new Gdk.Rectangle(x - rad, y - rad, 2 * rad, 2 * rad);
            Gdk.Rectangle dest_rect    = Gdk.Rectangle.Intersect(surface_rect, brush_rect);

            if ((dest_rect.Width > 1) && (dest_rect.Height > 1))
            {
                //Allow Clipping through a temporary surface
                ImageSurface tmp_surface = new ImageSurface(Format.Argb32, dest_rect.Width, dest_rect.Height);

                using (Context g2 = new Context(tmp_surface)) {
                    g2.Operator = Operator.Source;
                    g2.SetSourceSurface(surface, -dest_rect.Left, -dest_rect.Top);
                    g2.Rectangle(new Rectangle(0, 0, dest_rect.Width, dest_rect.Height));
                    g2.Fill();
                }

                //Flush to make sure all drawing operations are finished
                tmp_surface.Flush();
                ColorBgra[,] tmp = new ColorBgra[dest_rect.Width, dest_rect.Height];

                for (int iy = 0; iy < dest_rect.Height; iy++)
                {
                    ColorBgra *srcRowPtr = tmp_surface.GetPointAddressUnchecked(0, iy);
                    for (int ix = 0; ix < dest_rect.Width; ix++)
                    {
                        tmp[ix, iy] = (*srcRowPtr).ToStraightAlpha();
                        srcRowPtr++;
                    }
                }

                for (int iy = 1; iy < dest_rect.Height - 1; iy++)
                {
                    ColorBgra *dstRowPtr = tmp_surface.GetPointAddressUnchecked(1, iy);
                    int        dy        = dest_rect.Top + iy - y;
                    for (int ix = 1; ix < dest_rect.Width - 1; ix++)
                    {
                        int dx = dest_rect.Left + ix - x;

                        if ((dx * dx + dy * dy) < rad * rad)
                        {
                            ColorBgra col = ColorBgra.Black;
                            col.R = (byte)((2 * tmp[ix, iy].R + tmp[ix - 1, iy].R + tmp[ix + 1, iy].R + tmp[ix, iy - 1].R + tmp[ix, iy + 1].R + 3) / 6);
                            col.G = (byte)((2 * tmp[ix, iy].G + tmp[ix - 1, iy].G + tmp[ix + 1, iy].G + tmp[ix, iy - 1].G + tmp[ix, iy + 1].G + 3) / 6);
                            col.B = (byte)((2 * tmp[ix, iy].B + tmp[ix - 1, iy].B + tmp[ix + 1, iy].B + tmp[ix, iy - 1].B + tmp[ix, iy + 1].B + 3) / 6);
                            col.A = (byte)((2 * tmp[ix, iy].A + tmp[ix - 1, iy].A + tmp[ix + 1, iy].A + tmp[ix, iy - 1].A + tmp[ix, iy + 1].A + 3) / 6);
                            *dstRowPtr = col.ToPremultipliedAlpha();
                        }
                        dstRowPtr++;
                    }
                }

                //Draw the final result on the surface
                g.Operator = Operator.Source;
                g.SetSourceSurface(tmp_surface, dest_rect.Left, dest_rect.Top);
                g.Rectangle(new Rectangle(dest_rect.Left, dest_rect.Top, dest_rect.Width, dest_rect.Height));
                g.Fill();
            }
            return(Gdk.Rectangle.Zero);
        }
Пример #13
0
        public unsafe override void Render(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois)
        {
            foreach (Gdk.Rectangle rect in rois)
            {
                for (int y = rect.Top; y <= rect.GetBottom(); y++)
                {
                    ColorBgra *srcRowPtr    = src.GetPointAddressUnchecked(rect.Left, y);
                    ColorBgra *dstRowPtr    = dest.GetPointAddressUnchecked(rect.Left, y);
                    ColorBgra *dstRowEndPtr = dstRowPtr + rect.Width;

                    int dither = y & 1;
                    while (dstRowPtr < dstRowEndPtr)
                    {
                        ColorBgra col = (*srcRowPtr).ToStraightAlpha();

                        dither++;
                        int r = col.R, g = col.G, b = col.B;;

                        if ((dither & 1) == 0)
                        {
                            r += 2;
                            g += 2;
                            b += 2;
                            if (r > 255)
                            {
                                r = 255;
                            }
                            if (g > 255)
                            {
                                g = 255;
                            }
                            if (b > 255)
                            {
                                b = 255;
                            }
                        }
                        else
                        {
                            r -= 2;
                            g -= 2;
                            b -= 2;
                            if (r < 0)
                            {
                                r = 0;
                            }
                            if (g < 0)
                            {
                                g = 0;
                            }
                            if (b < 0)
                            {
                                b = 0;
                            }
                        }
                        col.R = (byte)r;
                        col.G = (byte)g;
                        col.B = (byte)b;
                        *dstRowPtr = col.ToPremultipliedAlpha();
                        ++dstRowPtr;
                        ++srcRowPtr;
                    }
                }
            }
        }
Пример #14
0
        protected unsafe override void OnMouseMove(object o, Gtk.MotionNotifyEventArgs args, Cairo.PointD point)
        {
            Document doc = PintaCore.Workspace.ActiveDocument;

            ColorBgra old_color;
            ColorBgra new_color;

            if (mouse_button == 1)
            {
                old_color = PintaCore.Palette.PrimaryColor.ToColorBgra();
                new_color = PintaCore.Palette.SecondaryColor.ToColorBgra();
            }
            else if (mouse_button == 3)
            {
                old_color = PintaCore.Palette.SecondaryColor.ToColorBgra();
                new_color = PintaCore.Palette.PrimaryColor.ToColorBgra();
            }
            else
            {
                last_point = point_empty;
                return;
            }

            int x = (int)point.X;
            int y = (int)point.Y;

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

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

            ImageSurface surf      = doc.CurrentUserLayer.Surface;
            ImageSurface tmp_layer = doc.ToolLayer.Surface;

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

            roi         = PintaCore.Workspace.ClampToImageSize(roi);
            myTolerance = (int)(Tolerance * 256);

            tmp_layer.Flush();

            ColorBgra *tmp_data_ptr  = (ColorBgra *)tmp_layer.DataPtr;
            int        tmp_width     = tmp_layer.Width;
            ColorBgra *surf_data_ptr = (ColorBgra *)surf.DataPtr;
            int        surf_width    = surf.Width;

            // The stencil lets us know if we've already checked this
            // pixel, providing a nice perf boost
            // Maybe this should be changed to a BitVector2DSurfaceAdapter?
            for (int i = roi.X; i <= roi.GetRight(); i++)
            {
                for (int j = roi.Y; j <= roi.GetBottom(); j++)
                {
                    if (stencil[i, j])
                    {
                        continue;
                    }

                    if (IsColorInTolerance(new_color, surf.GetColorBgraUnchecked(surf_data_ptr, surf_width, i, j)))
                    {
                        *tmp_layer.GetPointAddressUnchecked(tmp_data_ptr, tmp_width, i, j) = AdjustColorDifference(new_color, old_color, surf.GetColorBgraUnchecked(surf_data_ptr, surf_width, i, j));
                    }

                    stencil[i, j] = true;
                }
            }

            tmp_layer.MarkDirty();

            using (Context g = new Context(surf)) {
                g.AppendPath(doc.Selection.SelectionPath);
                g.FillRule = FillRule.EvenOdd;
                g.Clip();

                g.Antialias = UseAntialiasing ? Antialias.Subpixel : Antialias.None;

                g.MoveTo(last_point.X, last_point.Y);
                g.LineTo(x, y);

                g.LineWidth = BrushWidth;
                g.LineJoin  = LineJoin.Round;
                g.LineCap   = LineCap.Round;

                g.SetSource(tmp_layer);

                g.Stroke();
            }

            doc.Workspace.Invalidate(roi);

            last_point = new Point(x, y);
        }
Пример #15
0
        protected unsafe override void OnMouseDown(QueuedToolEventArgs le)
        {
            SmudgeEventArgs e = le as SmudgeEventArgs;

            lastmouse = e.Location;
            if (e.Button == MouseButtons.Left)
            {
                mousedown = true;

                using (Surface brushsource = e.Brush.GetSurface(e.BrushWidth))
                {
                    brushheight       = brushsource.Height;
                    brushwidth        = brushsource.Width;
                    brushsize         = new Size(brushwidth, brushheight);
                    brushcenteroffset = new Size(brushwidth / 2, brushheight / 2);
                    spacing           = GetSpacing(brushsize, e.Quality);
                    int brusharea = brushwidth * brushheight;

                    brush = new float[brusharea * 4];
                    Point srcpt = Point.Subtract(e.Location, new Size(brushwidth / 2, brushheight / 2));
                    strengthmask = new float[brusharea];

                    float strength = (float)(Math.Pow(e.Strength, .25) / 255.0);

                    fixed(float *_strmask = strengthmask)
                    {
                        float *strmask = _strmask;

                        ColorBgra *voidstar = (ColorBgra *)brushsource.Scan0.VoidStar;

                        for (int i = 0; i < brushsource.Scan0.Length; i += 4)
                        {
                            *strmask = voidstar->A * strength;
                            ++voidstar;
                            ++strmask;
                        }
                    }

                    //fill the brush buffer by copying the surface where we clicked into the buffer
                    fixed(float *brshptrpin = brush)
                    {
                        float *brshptr = brshptrpin;

                        ColorBgra *ptr0 = (ColorBgra *)Surface.Scan0.VoidStar;

                        for (int y = 0; y < brushheight; ++y)
                        {
                            int        srcy   = Clamp(srcpt.Y + y, 0, srfcHeight - 1);
                            ColorBgra *ptrrow = ptr0 + srfcWidth * srcy;
                            for (int x = 0; x < brushwidth; ++x)
                            {
                                int        srcx = Clamp(srcpt.X + x, 0, srfcWidth - 1);
                                ColorBgra *ptr  = ptrrow + srcx;

                                brshptr[B] = ptr->B;
                                brshptr[G] = ptr->G;
                                brshptr[R] = ptr->R;
                                brshptr[A] = ptr->A;

                                brshptr += 4;
                            }
                        }
                    }
                }
            }
        }
Пример #16
0
        public unsafe override void Render(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois)
        {
            // Glow backgound
            glowEffect.Data.Radius     = 6;
            glowEffect.Data.Brightness = -(Data.Coloring - 50) * 2;
            glowEffect.Data.Contrast   = -(Data.Coloring - 50) * 2;

            this.glowEffect.Render(src, dest, rois);

            // Create black outlines by finding the edges of objects
            foreach (Gdk.Rectangle roi in rois)
            {
                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 > dest.Height)
                    {
                        bottom = dest.Height;
                    }

                    ColorBgra *srcPtr = src.GetPointAddress(roi.X, y);
                    ColorBgra *dstPtr = dest.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 > dest.Width)
                        {
                            right = dest.Width;
                        }

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

                        int        src_width   = src.Width;
                        ColorBgra *src_dataptr = (ColorBgra *)src.DataPtr;

                        for (int v = top; v < bottom; v++)
                        {
                            ColorBgra *pRow = src.GetRowAddressUnchecked(src_dataptr, src_width, 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(
                            Utility.ClampToByte(b),
                            Utility.ClampToByte(g),
                            Utility.ClampToByte(r));

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

                        // Adjust Brightness and Contrast
                        if (topLayer.R > (Data.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;
                    }
                }
            }
        }
Пример #17
0
        protected unsafe override void OnRender(Rectangle[] renderRects, int startIndex, int length)
        {
            Surface   dst    = DstArgs.Surface;
            Surface   src    = SrcArgs.Surface;
            Rectangle bounds = SrcArgs.Bounds;

            dst.CopySurface(src, renderRects);

            foreach (Rectangle rect in renderRects)
            {
                for (
                    double xoffset = 0, yoffset = 0;
                    xoffset <= DistanceX && yoffset <= DistanceY;
                    xoffset += SpacingX, yoffset += SpacingY)
                {
                    float xdirectedoffset = -(float)xoffset * DirectionX;
                    float ydirectedoffset = -(float)yoffset * DirectionY;

                    if (IsCancelRequested)
                    {
                        return;
                    }

                    for (int y = rect.Top; y < rect.Bottom; ++y)
                    {
                        float srcy = y + ydirectedoffset;
                        if (!(bounds.Top <= srcy && srcy < bounds.Bottom))
                        {
                            continue;
                        }
                        ColorBgra *dstptr = dst.GetPointAddressUnchecked(rect.Left, y);
                        ColorBgra *srcptr = src.GetPointAddressUnchecked(0, (int)srcy);

                        for (int x = rect.Left; x < rect.Right; ++x)
                        {
                            float srcx = x + xdirectedoffset;
                            if (!(bounds.Left <= srcx && srcx < bounds.Right))
                            {
                                ++dstptr;
                                continue;
                            }

                            ColorBgra srcpixel;
                            if (Bilinear)
                            {
                                srcpixel = src.GetBilinearSample(srcx, srcy);
                            }
                            else
                            {
                                srcpixel = *(srcptr + (int)srcx);
                            }

                            if (Fade)
                            {
                                srcpixel.A = (byte)((srcpixel.A) * (1 - xoffset / DistanceX));
                            }

                            *dstptr = blendOp.Apply(srcpixel, *dstptr);
                            ++dstptr;
                        }
                    }
                }
            }
        }
		public unsafe ColorBgraArrayWrapper (ColorBgra* data, int width, int height)
		{
			data_ptr = data;
			this.height = height;
			this.width = width;
		}
Пример #19
0
        public unsafe override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
        {
            if (Data.Amount == 0)
            {
                // Copy src to dest
                return;
            }

            int        src_width    = src.Width;
            ColorBgra *src_data_ptr = (ColorBgra *)src.DataPtr;
            int        dst_width    = dst.Width;
            ColorBgra *dst_data_ptr = (ColorBgra *)dst.DataPtr;

            Gdk.Rectangle src_bounds = src.GetBounds();

            long w   = dst.Width;
            long h   = dst.Height;
            long fox = (long)(dst.Width * Data.Offset.X * 32768.0);
            long foy = (long)(dst.Height * Data.Offset.Y * 32768.0);
            long fcx = fox + (w << 15);
            long fcy = foy + (h << 15);
            long fz  = Data.Amount;

            const int n = 64;

            foreach (Gdk.Rectangle rect in rois)
            {
                for (int y = rect.Top; y <= rect.GetBottom(); ++y)
                {
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(dst_data_ptr, dst_width, rect.Left, y);
                    ColorBgra *srcPtr = src.GetPointAddressUnchecked(src_data_ptr, src_width, rect.Left, y);

                    for (int x = rect.Left; x <= rect.GetRight(); ++x)
                    {
                        long fx = (x << 16) - fcx;
                        long fy = (y << 16) - fcy;

                        int sr = 0;
                        int sg = 0;
                        int sb = 0;
                        int sa = 0;
                        int sc = 0;

                        sr += srcPtr->R * srcPtr->A;
                        sg += srcPtr->G * srcPtr->A;
                        sb += srcPtr->B * srcPtr->A;
                        sa += srcPtr->A;
                        ++sc;

                        for (int i = 0; i < n; ++i)
                        {
                            fx -= ((fx >> 4) * fz) >> 10;
                            fy -= ((fy >> 4) * fz) >> 10;

                            int u = (int)(fx + fcx + 32768 >> 16);
                            int v = (int)(fy + fcy + 32768 >> 16);

                            if (src_bounds.Contains(u, v))
                            {
                                ColorBgra *srcPtr2 = src.GetPointAddressUnchecked(src_data_ptr, src_width, u, v);

                                sr += srcPtr2->R * srcPtr2->A;
                                sg += srcPtr2->G * srcPtr2->A;
                                sb += srcPtr2->B * srcPtr2->A;
                                sa += srcPtr2->A;
                                ++sc;
                            }
                        }

                        if (sa != 0)
                        {
                            *dstPtr = ColorBgra.FromBgra(
                                Utility.ClampToByte(sb / sa),
                                Utility.ClampToByte(sg / sa),
                                Utility.ClampToByte(sr / sa),
                                Utility.ClampToByte(sa / sc));
                        }
                        else
                        {
                            dstPtr->Bgra = 0;
                        }

                        ++srcPtr;
                        ++dstPtr;
                    }
                }
            }
        }
        protected override unsafe Gdk.Rectangle OnMouseMove(Context g, Color strokeColor, ImageSurface surface,
                                                            int x, int y, int lastX, int lastY)
        {
            int rad = (int)(g.LineWidth / 2.0) + 1;

            Gdk.Rectangle surface_rect = new Gdk.Rectangle(0, 0, surface.Width, surface.Height);
            Gdk.Rectangle brush_rect   = new Gdk.Rectangle(x - rad, y - rad, 2 * rad, 2 * rad);
            Gdk.Rectangle dest_rect    = Gdk.Rectangle.Intersect(surface_rect, brush_rect);

            //Initialize lookup table when first used (to prevent slower startup of the application)
            if (lut_factor == null)
            {
                lut_factor = new byte[LUT_Resolution + 1, LUT_Resolution + 1];

                for (int dy = 0; dy < LUT_Resolution + 1; dy++)
                {
                    for (int dx = 0; dx < LUT_Resolution + 1; dx++)
                    {
                        double d = Math.Sqrt(dx * dx + dy * dy) / LUT_Resolution;
                        if (d > 1.0)
                        {
                            lut_factor [dx, dy] = 0;
                        }
                        else
                        {
                            lut_factor [dx, dy] = (byte)(Math.Cos(Math.Sqrt(d) * Math.PI / 2.0) * 255.0);
                        }
                    }
                }
            }

            if ((dest_rect.Width > 0) && (dest_rect.Height > 0))
            {
                //Allow Clipping through a temporary surface
                ImageSurface tmp_surface = new ImageSurface(Format.Argb32, dest_rect.Width, dest_rect.Height);

                using (Context g2 = new Context(tmp_surface)) {
                    g2.Operator = Operator.Source;
                    g2.SetSourceSurface(surface, -dest_rect.Left, -dest_rect.Top);
                    g2.Rectangle(new Rectangle(0, 0, dest_rect.Width, dest_rect.Height));
                    g2.Fill();
                }

                //Flush to make sure all drawing operations are finished
                tmp_surface.Flush();


                int mean_r = 0, mean_g = 0, mean_b = 0;
                int max_diff_r = 1, max_diff_g = 1, max_diff_b = 1;
                int sz = 0;

                byte[,] factors = new byte[dest_rect.Right - dest_rect.Left, dest_rect.Bottom - dest_rect.Top];

                for (int iy = dest_rect.Top; iy < dest_rect.Bottom; iy++)
                {
                    ColorBgra *srcRowPtr = tmp_surface.GetPointAddressUnchecked(0, iy - dest_rect.Top);
                    for (int ix = dest_rect.Left; ix < dest_rect.Right; ix++)
                    {
                        ColorBgra col = (*srcRowPtr).ToStraightAlpha();
                        int       dx  = ((ix - x) * LUT_Resolution) / rad;
                        if (dx < 0)
                        {
                            dx = -dx;
                        }
                        int dy = ((iy - y) * LUT_Resolution) / rad;
                        if (dy < 0)
                        {
                            dy = -dy;
                        }

                        int factor = lut_factor[dx, dy];
                        sz     += factor;
                        mean_r += col.R * factor;
                        mean_g += col.G * factor;
                        mean_b += col.B * factor;
                        srcRowPtr++;
                    }
                }
                if (sz > 0)
                {
                    mean_r /= sz;
                    mean_g /= sz;
                    mean_b /= sz;
                }

                for (int iy = dest_rect.Top; iy < dest_rect.Bottom; iy++)
                {
                    ColorBgra *srcRowPtr = tmp_surface.GetPointAddressUnchecked(0, iy - dest_rect.Top);
                    for (int ix = dest_rect.Left; ix < dest_rect.Right; ix++)
                    {
                        ColorBgra col = (*srcRowPtr).ToStraightAlpha();
                        int       dr  = col.R - mean_r;
                        int       dg  = col.G - mean_g;
                        int       db  = col.B - mean_b;

                        if (dr < 0)
                        {
                            dr = -dr;
                        }
                        if (dg < 0)
                        {
                            dg = -dg;
                        }
                        if (db < 0)
                        {
                            db = -db;
                        }

                        if (dr > max_diff_r)
                        {
                            max_diff_r = dr;
                        }
                        if (dg > max_diff_g)
                        {
                            max_diff_g = dg;
                        }
                        if (db > max_diff_b)
                        {
                            max_diff_b = db;
                        }
                        srcRowPtr++;
                    }
                }

                for (int iy = dest_rect.Top; iy < dest_rect.Bottom; iy++)
                {
                    ColorBgra *srcRowPtr = tmp_surface.GetPointAddressUnchecked(0, iy - dest_rect.Top);
                    int        dy        = ((iy - y) * LUT_Resolution) / rad;
                    if (dy < 0)
                    {
                        dy = -dy;
                    }

                    for (int ix = dest_rect.Left; ix < dest_rect.Right; ix++)
                    {
                        ColorBgra col = (*srcRowPtr).ToStraightAlpha();
                        int       dx  = ((ix - x) * LUT_Resolution) / rad;
                        if (dx < 0)
                        {
                            dx = -dx;
                        }

                        int dr = ((col.R - mean_r) * 2 * LUT_Resolution) / max_diff_r;
                        int dg = ((col.G - mean_g) * 2 * LUT_Resolution) / max_diff_g;
                        int db = ((col.B - mean_b) * 2 * LUT_Resolution) / max_diff_b;

                        if (dr < 0)
                        {
                            dr = -dr;
                        }
                        if (dg < 0)
                        {
                            dg = -dg;
                        }
                        if (db < 0)
                        {
                            db = -db;
                        }

                        if (dr > LUT_Resolution)
                        {
                            dr = LUT_Resolution;
                        }
                        if (dg > LUT_Resolution)
                        {
                            dg = LUT_Resolution;
                        }
                        if (db > LUT_Resolution)
                        {
                            db = LUT_Resolution;
                        }

                        int factor;

                        if ((max_diff_r > 32) || (max_diff_g > 32) || (max_diff_b > 32))
                        {
                            factor = lut_factor[dx, dy] * lut_factor[dg, (dr + db) / 2];
                            col.A  = (byte)((col.A * (0xFFFF - factor)) / 0xFFFF);
                        }
                        else
                        {
                            factor = lut_factor[dx, dy];
                            col.A  = (byte)((col.A * (0xFF - factor)) / 0xFF);
                        }

                        *srcRowPtr = col.ToPremultipliedAlpha();
                        srcRowPtr++;
                    }
                }
                //Draw the final result on the surface
                g.Operator = Operator.Source;
                g.SetSourceSurface(tmp_surface, dest_rect.Left, dest_rect.Top);
                g.Rectangle(new Rectangle(dest_rect.Left, dest_rect.Top, dest_rect.Width, dest_rect.Height));
                g.Fill();
            }
            return(Gdk.Rectangle.Zero);
        }
Пример #21
0
        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;
                        }
                    }
                }
            }
        }
Пример #22
0
 public virtual void Apply(ColorBgra *dst, ColorBgra *src, int length)
 {
     throw new NotImplementedException("Derived class must implement Apply(ColorBgra*,ColorBgra*,int)");
 }
Пример #23
0
        float remainingSpace; //keeps track of spacing
        protected unsafe override void OnMouseMove(QueuedToolEventArgs le)
        {
            SmudgeEventArgs e         = le as SmudgeEventArgs;
            int             jittermax = (int)(e.Jitter * e.BrushWidth);

            Rectangle invrect = new Rectangle(lastmouse.X - brushwidth / 2, lastmouse.Y - brushheight / 2, brushwidth, brushheight);

            invrect = Rectangle.Union(invrect, new Rectangle(e.X - brushwidth / 2, e.Y - brushheight / 2, brushwidth, brushheight));
            invrect.Inflate(jittermax, jittermax);

            if (e.Button == MouseButtons.Left && mousedown)
            {
                float dist = Distance(lastmouse, e.Location);

                ColorBgra *ptr0 = (ColorBgra *)Surface.Scan0.VoidStar;

                float f;
                for (f = remainingSpace; f < dist && !IsAborted; f += spacing)
                {
                    PointF currentpoint = Lerp(lastmouse, e.Location, f / dist);

                    if (jittermax > 0)
                    {
                        currentpoint.X += r.Next(-jittermax, jittermax);
                        currentpoint.Y += r.Next(-jittermax, jittermax);
                    }
                    Point     dstpt       = Point.Subtract(new Point((int)currentpoint.X, (int)currentpoint.Y), brushcenteroffset);
                    Rectangle dstRect     = new Rectangle(dstpt, brushsize);
                    Rectangle clippedRect = Rectangle.Intersect(dstRect, Surface.Bounds);

                    fixed(float *brshpin = brush,
                          _strmask       = strengthmask)
                    {
                        float *brshptr = brshpin,
                              strmask  = _strmask;

                        int maxy = dstpt.Y + dstRect.Height;
                        int maxx = dstpt.X + dstRect.Width;

                        for (int y = dstpt.Y; y < maxy; ++y)
                        {
                            int        dsty   = Clamp(y, 0, srfcHeight - 1);
                            ColorBgra *ptrrow = ptr0 + srfcWidth * dsty;
                            for (int x = dstpt.X; x < maxx; ++x)
                            {
                                int        dstx    = Clamp(x, 0, srfcWidth - 1);
                                ColorBgra *srfcptr = ptrrow + dstx;

                                float invstr = 1.0f - *strmask;

                                //eliminate fringing from 0-alpha
                                //this officially makes us awesomer than Photoshop
                                if (brshptr[A] == 0.0f)
                                {
                                    brshptr[B] = srfcptr->B;
                                    brshptr[G] = srfcptr->G;
                                    brshptr[R] = srfcptr->R;
                                }
                                else if (srfcptr->A == 0)
                                {
                                    srfcptr->B = (byte)(brshptr[B]);
                                    srfcptr->G = (byte)(brshptr[G]);
                                    srfcptr->R = (byte)(brshptr[R]);
                                }

                                //blend the surface into the brush buffer, then copy it back onto the surface
                                brshptr[B] = (brshptr[B] * *strmask + srfcptr->B * invstr);
                                srfcptr->B = (byte)(brshptr[B] + 0.5f);

                                brshptr[G] = (brshptr[G] * *strmask + srfcptr->G * invstr);
                                srfcptr->G = (byte)(brshptr[G] + 0.5f);

                                brshptr[R] = (brshptr[R] * *strmask + srfcptr->R * invstr);
                                srfcptr->R = (byte)(brshptr[R] + 0.5f);

                                brshptr[A] = (brshptr[A] * *strmask + srfcptr->A * invstr);
                                srfcptr->A = (byte)(brshptr[A] + 0.5f);

                                brshptr += 4;
                                ++strmask;
                            }
                        }
                    }
                }
                remainingSpace = f - dist;
            }
            OnInvalidated(invrect);
            lastmouse = e.Location;
        }
Пример #24
0
        public override void Render(Surface src, Surface dst, Rectangle[] rois, int startIndex, int length)
        {
            long w   = dst.Width;
            long h   = dst.Height;
            long fox = (long)(dst.Width * offsetX * 32768.0);
            long foy = (long)(dst.Height * offsetY * 32768.0);
            long fcx = fox + (w << 15);
            long fcy = foy + (h << 15);
            long fz  = this.amount;


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

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

                        for (int x = rect.Left; x < rect.Right; ++x)
                        {
                            long fx = (x << 16) - fcx;
                            long fy = (y << 16) - fcy;

                            int sr = 0;
                            int sg = 0;
                            int sb = 0;
                            int sa = 0;
                            int sc = 0;

                            sr += srcPtr->R * srcPtr->A;
                            sg += srcPtr->G * srcPtr->A;
                            sb += srcPtr->B * srcPtr->A;
                            sa += srcPtr->A;
                            ++sc;

                            for (int i = 0; i < n; ++i)
                            {
                                fx -= ((fx >> 4) * fz) >> 10;
                                fy -= ((fy >> 4) * fz) >> 10;

                                int u = (int)(fx + fcx + 32768 >> 16);
                                int v = (int)(fy + fcy + 32768 >> 16);

                                if (src.IsVisible(u, v))
                                {
                                    ColorBgra *srcPtr2 = src.GetPointAddressUnchecked(u, v);

                                    sr += srcPtr2->R * srcPtr2->A;
                                    sg += srcPtr2->G * srcPtr2->A;
                                    sb += srcPtr2->B * srcPtr2->A;
                                    sa += srcPtr2->A;
                                    ++sc;
                                }
                            }

                            if (sa != 0)
                            {
                                *dstPtr = ColorBgra.FromBgra(
                                    PixelUtils.ClampToByte(sb / sa),
                                    PixelUtils.ClampToByte(sg / sa),
                                    PixelUtils.ClampToByte(sr / sa),
                                    PixelUtils.ClampToByte(sa / sc));
                            }
                            else
                            {
                                dstPtr->Bgra = 0;
                            }

                            ++srcPtr;
                            ++dstPtr;
                        }
                    }
                }
            }
        }
Пример #25
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;
                        }
                    }
                }
            }
        }
Пример #26
0
        public unsafe override void Render(Surface dst, System.Drawing.Point offset)
        {
            if (OwnerList.ScaleFactor < new ScaleFactor(2, 1))
            {
                return;
            }

            int[] d2SLookupX = OwnerList.Dst2SrcLookupX;
            int[] d2SLookupY = OwnerList.Dst2SrcLookupY;
            int[] s2DLookupX = OwnerList.Src2DstLookupX;
            int[] s2DLookupY = OwnerList.Src2DstLookupY;

            ColorBgra[] blackAndWhite = new ColorBgra[2] {
                ColorBgra.White, ColorBgra.Black
            };

            // draw horizontal lines
            int sTop    = d2SLookupY[offset.Y];
            int sBottom = d2SLookupY[offset.Y + dst.Height];

            for (int srcY = sTop; srcY <= sBottom; ++srcY)
            {
                int dstY   = s2DLookupY[srcY];
                int dstRow = dstY - offset.Y;

                if (dst.IsRowVisible(dstRow))
                {
                    ColorBgra *dstRowPtr    = dst.GetRowAddress(dstRow);
                    ColorBgra *dstRowEndPtr = dstRowPtr + dst.Width;

                    dstRowPtr += offset.X & 1;

                    while (dstRowPtr < dstRowEndPtr)
                    {
                        *dstRowPtr = ColorBgra.Black;
                        dstRowPtr += 2;
                    }
                }
            }

            // draw vertical lines
            int sLeft  = d2SLookupX[offset.X];
            int sRight = d2SLookupX[offset.X + dst.Width];

            for (int srcX = sLeft; srcX <= sRight; ++srcX)
            {
                int dstX   = s2DLookupX[srcX];
                int dstCol = dstX - offset.X;

                if (dst.IsColumnVisible(dstX - offset.X))
                {
                    byte *dstColPtr    = (byte *)dst.GetPointAddress(dstCol, 0);
                    byte *dstColEndPtr = dstColPtr + dst.Stride * dst.Height;

                    dstColPtr += (offset.Y & 1) * dst.Stride;

                    while (dstColPtr < dstColEndPtr)
                    {
                        *((ColorBgra *)dstColPtr) = ColorBgra.Black;
                        dstColPtr += 2 * dst.Stride;
                    }
                }
            }
        }
Пример #27
0
        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;
                    }
                }
            }
        }
Пример #28
0
        public unsafe void Render(Surface src, Surface dst, Rectangle[] rois, int start, int len)
        {
            int width  = src.Width;
            int height = src.Height;

            int arrayLens = 1 + this.coarseness;

            int localStoreSize = arrayLens * 5 * sizeof(int);

            byte *localStore = stackalloc byte[localStoreSize];
            byte *p          = localStore;

            int *intensityCount = (int *)p;

            p += arrayLens * sizeof(int);

            uint *avgRed = (uint *)p;

            p += arrayLens * sizeof(uint);

            uint *avgGreen = (uint *)p;

            p += arrayLens * sizeof(uint);

            uint *avgBlue = (uint *)p;

            p += arrayLens * sizeof(uint);

            uint *avgAlpha = (uint *)p;

            p += arrayLens * sizeof(uint);

            byte maxIntensity = this.coarseness;

            //TODO: review here
            for (int r = start; r < start + len; ++r)
            {
                Rectangle rect = rois[r];

                int rectTop    = rect.Top;
                int rectBottom = rect.Bottom;
                int rectLeft   = rect.Left;
                int rectRight  = rect.Right;

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

                    int top    = y - brushSize;
                    int bottom = y + brushSize + 1;

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

                    if (bottom > height)
                    {
                        bottom = height;
                    }

                    for (int x = rectLeft; x < rectRight; ++x)
                    {
                        PlatformMemory.SetToZero(localStore, (ulong)localStoreSize);

                        int left  = x - brushSize;
                        int right = x + brushSize + 1;

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

                        if (right > width)
                        {
                            right = width;
                        }

                        int numInt = 0;

                        for (int j = top; j < bottom; ++j)
                        {
                            ColorBgra *srcPtr = src.GetPointAddressUnchecked(left, j);

                            for (int i = left; i < right; ++i)
                            {
                                byte intensity = PixelUtils.FastScaleByteByByte(srcPtr->GetIntensityByte(), maxIntensity);

                                ++intensityCount[intensity];
                                ++numInt;

                                avgRed[intensity]   += srcPtr->R;
                                avgGreen[intensity] += srcPtr->G;
                                avgBlue[intensity]  += srcPtr->B;
                                avgAlpha[intensity] += srcPtr->A;

                                ++srcPtr;
                            }
                        }

                        byte chosenIntensity = 0;
                        int  maxInstance     = 0;

                        for (int i = 0; i <= maxIntensity; ++i)
                        {
                            if (intensityCount[i] > maxInstance)
                            {
                                chosenIntensity = (byte)i;
                                maxInstance     = intensityCount[i];
                            }
                        }

                        // TODO: correct handling of alpha values?

                        byte R = (byte)(avgRed[chosenIntensity] / maxInstance);
                        byte G = (byte)(avgGreen[chosenIntensity] / maxInstance);
                        byte B = (byte)(avgBlue[chosenIntensity] / maxInstance);
                        byte A = (byte)(avgAlpha[chosenIntensity] / maxInstance);

                        *dstPtr = ColorBgra.FromBgra(B, G, R, A);
                        ++dstPtr;
                    }
                }
            }
        }
            public override unsafe void Apply(ColorBgra *dst, ColorBgra *src, int length)
            {
                while (length > 0)
                {
                    int h = 0;
                    int s = 0;
                    int v = 0;

                    int max = (src->R > src->G) ? src->R : src->G;
                    if (max < src->B)
                    {
                        max = src->B;
                    }

                    v = max;
                    int NewV = CurveV[v];

                    if (NewV == 0) // if the target Value is zero, there is no point calculating Saturation or Hue ...
                    {
                        dst->B = 0;
                        dst->G = 0;
                        dst->R = 0;
                    }
                    else
                    {
                        int min = (src->R < src->G) ? src->R : src->G;
                        if (min > src->B)
                        {
                            min = src->B;
                        }
                        int delta = max - min;

                        if (delta > 0)
                        {
                            s = CommonUtil.IntDiv(255 * delta, max);
                        }

                        int NewS = CurveS[s];

                        if (NewS == 0) // if the target saturation is zero, then there is no point calculating a hue
                        {
                            dst->B = (byte)NewV;
                            dst->G = (byte)NewV;
                            dst->R = (byte)NewV;
                        }
                        else
                        {
                            if (src->R == max) // Between Yellow and Magenta
                            {
                                h = CommonUtil.IntDiv(255 * (src->G - src->B), delta);
                            }
                            else if (src->G == max) // Between Cyan and Yellow
                            {
                                h = 512 + CommonUtil.IntDiv(255 * (src->B - src->R), delta);
                            }
                            else // Between Magenta and Cyan
                            {
                                h = 1024 + CommonUtil.IntDiv(255 * (src->R - src->G), delta);
                            }

                            if (h < 0)
                            {
                                h += 1536;
                            }

                            h = CommonUtil.IntDiv(h, 6);
                        }
                        int NewH = CurveH[h];

                        if ((NewH == h) && (NewS == s))
                        {
                            dst->B = (byte)(CommonUtil.IntDiv(src->B * NewV, v));
                            dst->G = (byte)(CommonUtil.IntDiv(src->G * NewV, v));
                            dst->R = (byte)(CommonUtil.IntDiv(src->R * NewV, v));
                        }
                        else
                        {
                            NewH *= 6;
                            int fractionalSector = (NewH & 0xff);
                            int sectorNumber     = (NewH >> 8);


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

                            //// Assign the fractional colors to r, g, and b
                            //// based on the sector the angle is in.
                            switch (sectorNumber)
                            {
                            case 0:
                                dst->R = (byte)NewV;
                                int tmp0 = ((NewS * (255 - fractionalSector)) + 128) >> 8;
                                dst->G = (byte)(((NewV * (255 - tmp0)) + 128) >> 8);
                                dst->B = (byte)(((NewV * (255 - NewS)) + 128) >> 8);
                                break;

                            case 1:
                                int tmp1 = ((NewS * fractionalSector) + 128) >> 8;
                                dst->R = (byte)(((NewV * (255 - tmp1)) + 128) >> 8);
                                dst->G = (byte)NewV;
                                dst->B = (byte)(((NewV * (255 - NewS)) + 128) >> 8);
                                break;

                            case 2:
                                dst->R = (byte)(((NewV * (255 - NewS)) + 128) >> 8);
                                dst->G = (byte)NewV;
                                int tmp2 = ((NewS * (255 - fractionalSector)) + 128) >> 8;
                                dst->B = (byte)(((NewV * (255 - tmp2)) + 128) >> 8);
                                break;

                            case 3:
                                dst->R = (byte)(((NewV * (255 - NewS)) + 128) >> 8);
                                int tmp3 = ((NewS * fractionalSector) + 128) >> 8;
                                dst->G = (byte)(((NewV * (255 - tmp3)) + 128) >> 8);
                                dst->B = (byte)NewV;
                                break;

                            case 4:
                                int tmp4 = ((NewS * (255 - fractionalSector)) + 128) >> 8;
                                dst->R = (byte)(((NewV * (255 - tmp4)) + 128) >> 8);
                                dst->G = (byte)(((NewV * (255 - NewS)) + 128) >> 8);
                                dst->B = (byte)NewV;
                                break;

                            case 5:
                                dst->R = (byte)NewV;
                                dst->G = (byte)(((NewV * (255 - NewS)) + 128) >> 8);
                                int tmp5 = ((NewS * fractionalSector) + 128) >> 8;
                                dst->B = (byte)(((NewV * (255 - tmp5)) + 128) >> 8);
                                break;
                            }
                        }
                    }

                    dst->A = src->A;

                    ++dst;
                    ++src;
                    --length;
                }
            }
Пример #30
0
 public unsafe override void Apply(ColorBgra *dst, ColorBgra *src, int length)
 {
     Memory.Copy(dst, src, (ulong)length * (ulong)ColorBgra.SizeOf);
 }
Пример #31
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 / _zoom;
                double invQuality = 1.0 / _quality;
                double aspect     = (double)h / (double)w;
                int    count      = _quality * _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 + _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 = _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;
                        }
                    }
                }
            }
        }
Пример #32
0
        public unsafe override void Render(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois)
        {
            int width  = src.Width;
            int height = src.Height;

            int arrayLens = 1 + Data.Coarseness;

            int localStoreSize = arrayLens * 5 * sizeof(int);

            byte *localStore = stackalloc byte[localStoreSize];
            byte *p          = localStore;

            int *intensityCount = (int *)p;

            p += arrayLens * sizeof(int);

            uint *avgRed = (uint *)p;

            p += arrayLens * sizeof(uint);

            uint *avgGreen = (uint *)p;

            p += arrayLens * sizeof(uint);

            uint *avgBlue = (uint *)p;

            p += arrayLens * sizeof(uint);

            uint *avgAlpha = (uint *)p;

            p += arrayLens * sizeof(uint);

            byte maxIntensity = (byte)Data.Coarseness;

            foreach (Gdk.Rectangle rect in rois)
            {
                int rectTop    = rect.Top;
                int rectBottom = rect.GetBottom();
                int rectLeft   = rect.Left;
                int rectRight  = rect.GetRight();

                ColorBgra *dst_dataptr = (ColorBgra *)dest.DataPtr;
                int        dst_width   = dest.Width;
                ColorBgra *src_dataptr = (ColorBgra *)src.DataPtr;
                int        src_width   = src.Width;

                for (int y = rectTop; y <= rectBottom; ++y)
                {
                    ColorBgra *dstPtr = dest.GetPointAddressUnchecked(dst_dataptr, dst_width, rect.Left, y);

                    int top    = y - Data.BrushSize;
                    int bottom = y + Data.BrushSize + 1;

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

                    if (bottom > height)
                    {
                        bottom = height;
                    }

                    for (int x = rectLeft; x <= rectRight; ++x)
                    {
                        SetToZero(localStore, (ulong)localStoreSize);

                        int left  = x - Data.BrushSize;
                        int right = x + Data.BrushSize + 1;

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

                        if (right > width)
                        {
                            right = width;
                        }

                        int numInt = 0;

                        for (int j = top; j < bottom; ++j)
                        {
                            ColorBgra *srcPtr = src.GetPointAddressUnchecked(src_dataptr, src_width, left, j);

                            for (int i = left; i < right; ++i)
                            {
                                byte intensity = Utility.FastScaleByteByByte(srcPtr->GetIntensityByte(), maxIntensity);

                                ++intensityCount[intensity];
                                ++numInt;

                                avgRed[intensity]   += srcPtr->R;
                                avgGreen[intensity] += srcPtr->G;
                                avgBlue[intensity]  += srcPtr->B;
                                avgAlpha[intensity] += srcPtr->A;

                                ++srcPtr;
                            }
                        }

                        byte chosenIntensity = 0;
                        int  maxInstance     = 0;

                        for (int i = 0; i <= maxIntensity; ++i)
                        {
                            if (intensityCount[i] > maxInstance)
                            {
                                chosenIntensity = (byte)i;
                                maxInstance     = intensityCount[i];
                            }
                        }

                        // TODO: correct handling of alpha values?

                        byte R = (byte)(avgRed[chosenIntensity] / maxInstance);
                        byte G = (byte)(avgGreen[chosenIntensity] / maxInstance);
                        byte B = (byte)(avgBlue[chosenIntensity] / maxInstance);
                        byte A = (byte)(avgAlpha[chosenIntensity] / maxInstance);

                        *dstPtr = ColorBgra.FromBgra(B, G, R, A);
                        ++dstPtr;
                    }
                }
            }
        }
Пример #33
0
 /// <summary>
 /// Process the pixel in the first pass of the algorithm
 /// </summary>
 /// <param name="pixel">The pixel to quantize</param>
 /// <remarks>
 /// This function need only be overridden if your quantize algorithm needs two passes,
 /// such as an Octree quantizer.
 /// </remarks>
 protected override void InitialQuantizePixel(ColorBgra *pixel)
 {
     _octree.AddColor(pixel);
 }
Пример #34
0
        public unsafe void Render(Surface surface, Rectangle[] rois, int startIndex, int length)
        {
            byte startAlpha;
            byte endAlpha;

            if (this.alphaOnly)
            {
                ComputeAlphaOnlyValuesFromColors(this.startColor, this.endColor, out startAlpha, out endAlpha);
            }
            else
            {
                startAlpha = this.startColor.A;
                endAlpha   = this.endColor.A;
            }

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

                if (this.startPoint == this.endPoint)
                {
                    // Start and End point are the same ... fill with solid color.
                    for (int y = rect.Top; y < rect.Bottom; ++y)
                    {
                        ColorBgra *pixelPtr = surface.GetPointAddress(rect.Left, y);

                        for (int x = rect.Left; x < rect.Right; ++x)
                        {
                            ColorBgra result;

                            if (this.alphaOnly && this.alphaBlending)
                            {
                                byte resultAlpha = (byte)Utility.FastDivideShortByByte((ushort)(pixelPtr->A * endAlpha), 255);
                                result   = *pixelPtr;
                                result.A = resultAlpha;
                            }
                            else if (this.alphaOnly && !this.alphaBlending)
                            {
                                result   = *pixelPtr;
                                result.A = endAlpha;
                            }
                            else if (!this.alphaOnly && this.alphaBlending)
                            {
                                result = this.normalBlendOp.Apply(*pixelPtr, this.endColor);
                            }
                            else //if (!this.alphaOnly && !this.alphaBlending)
                            {
                                result = this.endColor;
                            }

                            *pixelPtr = result;
                            ++pixelPtr;
                        }
                    }
                }
                else
                {
                    for (int y = rect.Top; y < rect.Bottom; ++y)
                    {
                        ColorBgra *pixelPtr = surface.GetPointAddress(rect.Left, y);

                        if (this.alphaOnly && this.alphaBlending)
                        {
                            for (int x = rect.Left; x < rect.Right; ++x)
                            {
                                float lerpUnbounded = ComputeUnboundedLerp(x, y);
                                float lerpBounded   = BoundLerp(lerpUnbounded);
                                byte  lerpByte      = (byte)(lerpBounded * 255.0f);
                                byte  lerpAlpha     = this.lerpAlphas[lerpByte];
                                byte  resultAlpha   = (byte)Utility.FastScaleByteByByte(pixelPtr->A, lerpAlpha);
                                pixelPtr->A = resultAlpha;
                                ++pixelPtr;
                            }
                        }
                        else if (this.alphaOnly && !this.alphaBlending)
                        {
                            for (int x = rect.Left; x < rect.Right; ++x)
                            {
                                float lerpUnbounded = ComputeUnboundedLerp(x, y);
                                float lerpBounded   = BoundLerp(lerpUnbounded);
                                byte  lerpByte      = (byte)(lerpBounded * 255.0f);
                                byte  lerpAlpha     = this.lerpAlphas[lerpByte];
                                pixelPtr->A = lerpAlpha;
                                ++pixelPtr;
                            }
                        }
                        else if (!this.alphaOnly && (this.alphaBlending && (startAlpha != 255 || endAlpha != 255)))
                        {
                            // If we're doing all color channels, and we're doing alpha blending, and if alpha blending is necessary
                            for (int x = rect.Left; x < rect.Right; ++x)
                            {
                                float     lerpUnbounded = ComputeUnboundedLerp(x, y);
                                float     lerpBounded   = BoundLerp(lerpUnbounded);
                                byte      lerpByte      = (byte)(lerpBounded * 255.0f);
                                ColorBgra lerpColor     = this.lerpColors[lerpByte];
                                ColorBgra result        = this.normalBlendOp.Apply(*pixelPtr, lerpColor);
                                *         pixelPtr      = result;
                                ++pixelPtr;
                            }
                        }
                        else //if (!this.alphaOnly && !this.alphaBlending) // or sC.A == 255 && eC.A == 255
                        {
                            for (int x = rect.Left; x < rect.Right; ++x)
                            {
                                float     lerpUnbounded = ComputeUnboundedLerp(x, y);
                                float     lerpBounded   = BoundLerp(lerpUnbounded);
                                byte      lerpByte      = (byte)(lerpBounded * 255.0f);
                                ColorBgra lerpColor     = this.lerpColors[lerpByte];
                                *         pixelPtr      = lerpColor;
                                ++pixelPtr;
                            }
                        }
                    }
                }
            }

            AfterRender();
        }