コード例 #1
0
        public unsafe static Image ApplyBlur(Bitmap bmp, int radius, bool expand)
        {
            if (expand)
            {
                bmp = (Bitmap)Core.AddCanvas(bmp, radius);
            }

            Bitmap bmp2 = new Bitmap(bmp.Width, bmp.Height);

            using (BitmapCache src = new BitmapCache(bmp, ImageLockMode.ReadWrite))
                using (BitmapCache dst = new BitmapCache(bmp2, ImageLockMode.ReadWrite))
                {
                    int[] w    = CreateGaussianBlurRow(radius);
                    int   wlen = w.Length;

                    Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);

                    if (rect.Height >= 1 && rect.Width >= 1)
                    {
                        for (int y = rect.Top; y < rect.Bottom; ++y)
                        {
                            long *waSums = stackalloc long[wlen];
                            long *wcSums = stackalloc long[wlen];
                            long *aSums  = stackalloc long[wlen];
                            long *bSums  = stackalloc long[wlen];
                            long *gSums  = stackalloc long[wlen];
                            long *rSums  = stackalloc long[wlen];
                            long  waSum  = 0;
                            long  wcSum  = 0;
                            long  aSum   = 0;
                            long  bSum   = 0;
                            long  gSum   = 0;
                            long  rSum   = 0;

                            ColorBgra *dstPtr = dst.GetPointAddress(rect.Left, y);

                            for (int wx = 0; wx < wlen; ++wx)
                            {
                                int srcX = rect.Left + wx - radius;
                                waSums[wx] = 0;
                                wcSums[wx] = 0;
                                aSums[wx]  = 0;
                                bSums[wx]  = 0;
                                gSums[wx]  = 0;
                                rSums[wx]  = 0;

                                if (srcX >= 0 && srcX < src.BitmapSize.Width)
                                {
                                    for (int wy = 0; wy < wlen; ++wy)
                                    {
                                        int srcY = y + wy - radius;

                                        if (srcY >= 0 && srcY < src.BitmapSize.Height)
                                        {
                                            ColorBgra c  = src.GetPoint(srcX, srcY);
                                            int       wp = w[wy];

                                            waSums[wx] += wp;
                                            wp         *= c.A + (c.A >> 7);
                                            wcSums[wx] += wp;
                                            wp        >>= 8;

                                            aSums[wx] += wp * c.A;
                                            bSums[wx] += wp * c.B;
                                            gSums[wx] += wp * c.G;
                                            rSums[wx] += wp * c.R;
                                        }
                                    }

                                    int wwx = w[wx];
                                    waSum += wwx * waSums[wx];
                                    wcSum += wwx * wcSums[wx];
                                    aSum  += wwx * aSums[wx];
                                    bSum  += wwx * bSums[wx];
                                    gSum  += wwx * gSums[wx];
                                    rSum  += wwx * rSums[wx];
                                }
                            }

                            wcSum >>= 8;

                            if (waSum == 0 || wcSum == 0)
                            {
                                dstPtr->Bgra = 0;
                            }
                            else
                            {
                                int alpha = (int)(aSum / waSum);
                                int blue  = (int)(bSum / wcSum);
                                int green = (int)(gSum / wcSum);
                                int red   = (int)(rSum / wcSum);

                                dstPtr->Bgra = ColorBgra.BgraToUInt32(blue, green, red, alpha);
                            }

                            ++dstPtr;

                            for (int x = rect.Left + 1; x < rect.Right; ++x)
                            {
                                for (int i = 0; i < wlen - 1; ++i)
                                {
                                    waSums[i] = waSums[i + 1];
                                    wcSums[i] = wcSums[i + 1];
                                    aSums[i]  = aSums[i + 1];
                                    bSums[i]  = bSums[i + 1];
                                    gSums[i]  = gSums[i + 1];
                                    rSums[i]  = rSums[i + 1];
                                }

                                waSum = 0;
                                wcSum = 0;
                                aSum  = 0;
                                bSum  = 0;
                                gSum  = 0;
                                rSum  = 0;

                                int wx;
                                for (wx = 0; wx < wlen - 1; ++wx)
                                {
                                    long wwx = (long)w[wx];
                                    waSum += wwx * waSums[wx];
                                    wcSum += wwx * wcSums[wx];
                                    aSum  += wwx * aSums[wx];
                                    bSum  += wwx * bSums[wx];
                                    gSum  += wwx * gSums[wx];
                                    rSum  += wwx * rSums[wx];
                                }

                                wx = wlen - 1;

                                waSums[wx] = 0;
                                wcSums[wx] = 0;
                                aSums[wx]  = 0;
                                bSums[wx]  = 0;
                                gSums[wx]  = 0;
                                rSums[wx]  = 0;

                                int srcX = x + wx - radius;

                                if (srcX >= 0 && srcX < src.BitmapSize.Width)
                                {
                                    for (int wy = 0; wy < wlen; ++wy)
                                    {
                                        int srcY = y + wy - radius;

                                        if (srcY >= 0 && srcY < src.BitmapSize.Height)
                                        {
                                            ColorBgra c  = src.GetPoint(srcX, srcY);
                                            int       wp = w[wy];

                                            waSums[wx] += wp;
                                            wp         *= c.A + (c.A >> 7);
                                            wcSums[wx] += wp;
                                            wp        >>= 8;

                                            aSums[wx] += wp * (long)c.A;
                                            bSums[wx] += wp * (long)c.B;
                                            gSums[wx] += wp * (long)c.G;
                                            rSums[wx] += wp * (long)c.R;
                                        }
                                    }

                                    int wr = w[wx];
                                    waSum += (long)wr * waSums[wx];
                                    wcSum += (long)wr * wcSums[wx];
                                    aSum  += (long)wr * aSums[wx];
                                    bSum  += (long)wr * bSums[wx];
                                    gSum  += (long)wr * gSums[wx];
                                    rSum  += (long)wr * rSums[wx];
                                }

                                wcSum >>= 8;

                                if (waSum == 0 || wcSum == 0)
                                {
                                    dstPtr->Bgra = 0;
                                }
                                else
                                {
                                    int alpha = (int)(aSum / waSum);
                                    int blue  = (int)(bSum / wcSum);
                                    int green = (int)(gSum / wcSum);
                                    int red   = (int)(rSum / wcSum);

                                    dstPtr->Bgra = ColorBgra.BgraToUInt32(blue, green, red, alpha);
                                }

                                ++dstPtr;
                            }
                        }
                    }
                }

            return(bmp2);
        }
コード例 #2
0
ファイル: GaussianBlurEffect.cs プロジェクト: xiexin36/Pinta
        public unsafe override void Render(ImageSurface src, ImageSurface dest, Gdk.Rectangle[] rois)
        {
            if (Data.Radius == 0)
            {
                // Copy src to dest
                return;
            }

            int r = Data.Radius;

            int[] w    = CreateGaussianBlurRow(r);
            int   wlen = w.Length;

            int   localStoreSize = wlen * 6 * sizeof(long);
            byte *localStore     = stackalloc byte[localStoreSize];
            byte *p = localStore;

            long *waSums = (long *)p;

            p += wlen * sizeof(long);

            long *wcSums = (long *)p;

            p += wlen * sizeof(long);

            long *aSums = (long *)p;

            p += wlen * sizeof(long);

            long *bSums = (long *)p;

            p += wlen * sizeof(long);

            long *gSums = (long *)p;

            p += wlen * sizeof(long);

            long *rSums = (long *)p;

            p += wlen * sizeof(long);

            // Cache these for a massive performance boost
            int        src_width    = src.Width;
            int        src_height   = src.Height;
            ColorBgra *src_data_ptr = (ColorBgra *)src.DataPtr;

            foreach (Gdk.Rectangle rect in rois)
            {
                if (rect.Height >= 1 && rect.Width >= 1)
                {
                    for (int y = rect.Top; y <= rect.GetBottom(); ++y)
                    {
                        //Memory.SetToZero (localStore, (ulong)localStoreSize);

                        long waSum = 0;
                        long wcSum = 0;
                        long aSum  = 0;
                        long bSum  = 0;
                        long gSum  = 0;
                        long rSum  = 0;

                        ColorBgra *dstPtr = dest.GetPointAddressUnchecked(rect.Left, y);

                        for (int wx = 0; wx < wlen; ++wx)
                        {
                            int srcX = rect.Left + wx - r;
                            waSums[wx] = 0;
                            wcSums[wx] = 0;
                            aSums[wx]  = 0;
                            bSums[wx]  = 0;
                            gSums[wx]  = 0;
                            rSums[wx]  = 0;

                            if (srcX >= 0 && srcX < src_width)
                            {
                                for (int wy = 0; wy < wlen; ++wy)
                                {
                                    int srcY = y + wy - r;

                                    if (srcY >= 0 && srcY < src_height)
                                    {
                                        ColorBgra c  = src.GetPointUnchecked(src_data_ptr, src_width, srcX, srcY);
                                        int       wp = w[wy];

                                        waSums[wx] += wp;
                                        wp         *= c.A + (c.A >> 7);
                                        wcSums[wx] += wp;
                                        wp        >>= 8;

                                        aSums[wx] += wp * c.A;
                                        bSums[wx] += wp * c.B;
                                        gSums[wx] += wp * c.G;
                                        rSums[wx] += wp * c.R;
                                    }
                                }

                                int wwx = w[wx];
                                waSum += wwx * waSums[wx];
                                wcSum += wwx * wcSums[wx];
                                aSum  += wwx * aSums[wx];
                                bSum  += wwx * bSums[wx];
                                gSum  += wwx * gSums[wx];
                                rSum  += wwx * rSums[wx];
                            }
                        }

                        wcSum >>= 8;

                        if (waSum == 0 || wcSum == 0)
                        {
                            dstPtr->Bgra = 0;
                        }
                        else
                        {
                            int alpha = (int)(aSum / waSum);
                            int blue  = (int)(bSum / wcSum);
                            int green = (int)(gSum / wcSum);
                            int red   = (int)(rSum / wcSum);

                            dstPtr->Bgra = ColorBgra.BgraToUInt32(blue, green, red, alpha);
                        }

                        ++dstPtr;

                        for (int x = rect.Left + 1; x <= rect.GetRight(); ++x)
                        {
                            for (int i = 0; i < wlen - 1; ++i)
                            {
                                waSums[i] = waSums[i + 1];
                                wcSums[i] = wcSums[i + 1];
                                aSums[i]  = aSums[i + 1];
                                bSums[i]  = bSums[i + 1];
                                gSums[i]  = gSums[i + 1];
                                rSums[i]  = rSums[i + 1];
                            }

                            waSum = 0;
                            wcSum = 0;
                            aSum  = 0;
                            bSum  = 0;
                            gSum  = 0;
                            rSum  = 0;

                            int wx;
                            for (wx = 0; wx < wlen - 1; ++wx)
                            {
                                long wwx = (long)w[wx];
                                waSum += wwx * waSums[wx];
                                wcSum += wwx * wcSums[wx];
                                aSum  += wwx * aSums[wx];
                                bSum  += wwx * bSums[wx];
                                gSum  += wwx * gSums[wx];
                                rSum  += wwx * rSums[wx];
                            }

                            wx = wlen - 1;

                            waSums[wx] = 0;
                            wcSums[wx] = 0;
                            aSums[wx]  = 0;
                            bSums[wx]  = 0;
                            gSums[wx]  = 0;
                            rSums[wx]  = 0;

                            int srcX = x + wx - r;

                            if (srcX >= 0 && srcX < src_width)
                            {
                                for (int wy = 0; wy < wlen; ++wy)
                                {
                                    int srcY = y + wy - r;

                                    if (srcY >= 0 && srcY < src_height)
                                    {
                                        ColorBgra c  = src.GetPointUnchecked(src_data_ptr, src_width, srcX, srcY);
                                        int       wp = w[wy];

                                        waSums[wx] += wp;
                                        wp         *= c.A + (c.A >> 7);
                                        wcSums[wx] += wp;
                                        wp        >>= 8;

                                        aSums[wx] += wp * (long)c.A;
                                        bSums[wx] += wp * (long)c.B;
                                        gSums[wx] += wp * (long)c.G;
                                        rSums[wx] += wp * (long)c.R;
                                    }
                                }

                                int wr = w[wx];
                                waSum += (long)wr * waSums[wx];
                                wcSum += (long)wr * wcSums[wx];
                                aSum  += (long)wr * aSums[wx];
                                bSum  += (long)wr * bSums[wx];
                                gSum  += (long)wr * gSums[wx];
                                rSum  += (long)wr * rSums[wx];
                            }

                            wcSum >>= 8;

                            if (waSum == 0 || wcSum == 0)
                            {
                                dstPtr->Bgra = 0;
                            }
                            else
                            {
                                int alpha = (int)(aSum / waSum);
                                int blue  = (int)(bSum / wcSum);
                                int green = (int)(gSum / wcSum);
                                int red   = (int)(rSum / wcSum);

                                dstPtr->Bgra = ColorBgra.BgraToUInt32(blue, green, red, alpha);
                            }

                            ++dstPtr;
                        }
                    }
                }
            }
        }
コード例 #3
0
        public override void Render(Surface src, Surface dst, Rectangle[] rois, int startIndex, int length)
        {
            unsafe
            {
                if (this.radius == 0)
                {
                    for (int ri = startIndex; ri < startIndex + length; ++ri)
                    {
                        dst.CopySurface(src, rois[ri].Location, rois[ri]);
                    }

                    return;
                }


                int   r    = this.radius;
                int[] w    = CreateGaussianBlurRow(r);
                int   wlen = w.Length;

                int   localStoreSize = wlen * 6 * sizeof(long);
                byte *localStore     = stackalloc byte[localStoreSize];
                byte *p = localStore;

                long *waSums = (long *)p;
                p += wlen * sizeof(long);

                long *wcSums = (long *)p;
                p += wlen * sizeof(long);

                long *aSums = (long *)p;
                p += wlen * sizeof(long);

                long *bSums = (long *)p;
                p += wlen * sizeof(long);

                long *gSums = (long *)p;
                p += wlen * sizeof(long);

                long *rSums = (long *)p;
                p += wlen * sizeof(long);

                ulong arraysLength = (ulong)(sizeof(long) * wlen);

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

                    if (rect.Height >= 1 && rect.Width >= 1)
                    {
                        for (int y = rect.Top; y < rect.Bottom; ++y)
                        {
                            PlatformMemory.SetToZero(localStore, (ulong)localStoreSize);

                            long waSum = 0;
                            long wcSum = 0;
                            long aSum  = 0;
                            long bSum  = 0;
                            long gSum  = 0;
                            long rSum  = 0;

                            ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);

                            for (int wx = 0; wx < wlen; ++wx)
                            {
                                int srcX = rect.Left + wx - r;
                                waSums[wx] = 0;
                                wcSums[wx] = 0;
                                aSums[wx]  = 0;
                                bSums[wx]  = 0;
                                gSums[wx]  = 0;
                                rSums[wx]  = 0;

                                if (srcX >= 0 && srcX < src.Width)
                                {
                                    for (int wy = 0; wy < wlen; ++wy)
                                    {
                                        int srcY = y + wy - r;

                                        if (srcY >= 0 && srcY < src.Height)
                                        {
                                            ColorBgra c  = src.GetPointUnchecked(srcX, srcY);
                                            int       wp = w[wy];

                                            waSums[wx] += wp;
                                            wp         *= c.A + (c.A >> 7);
                                            wcSums[wx] += wp;
                                            wp        >>= 8;

                                            aSums[wx] += wp * c.A;
                                            bSums[wx] += wp * c.B;
                                            gSums[wx] += wp * c.G;
                                            rSums[wx] += wp * c.R;
                                        }
                                    }

                                    int wwx = w[wx];
                                    waSum += wwx * waSums[wx];
                                    wcSum += wwx * wcSums[wx];
                                    aSum  += wwx * aSums[wx];
                                    bSum  += wwx * bSums[wx];
                                    gSum  += wwx * gSums[wx];
                                    rSum  += wwx * rSums[wx];
                                }
                            }

                            wcSum >>= 8;

                            if (waSum == 0 || wcSum == 0)
                            {
                                dstPtr->Bgra = 0;
                            }
                            else
                            {
                                int alpha = (int)(aSum / waSum);
                                int blue  = (int)(bSum / wcSum);
                                int green = (int)(gSum / wcSum);
                                int red   = (int)(rSum / wcSum);

                                dstPtr->Bgra = ColorBgra.BgraToUInt32(blue, green, red, alpha);
                            }

                            ++dstPtr;

                            for (int x = rect.Left + 1; x < rect.Right; ++x)
                            {
                                for (int i = 0; i < wlen - 1; ++i)
                                {
                                    waSums[i] = waSums[i + 1];
                                    wcSums[i] = wcSums[i + 1];
                                    aSums[i]  = aSums[i + 1];
                                    bSums[i]  = bSums[i + 1];
                                    gSums[i]  = gSums[i + 1];
                                    rSums[i]  = rSums[i + 1];
                                }

                                waSum = 0;
                                wcSum = 0;
                                aSum  = 0;
                                bSum  = 0;
                                gSum  = 0;
                                rSum  = 0;

                                int wx;
                                for (wx = 0; wx < wlen - 1; ++wx)
                                {
                                    long wwx = (long)w[wx];
                                    waSum += wwx * waSums[wx];
                                    wcSum += wwx * wcSums[wx];
                                    aSum  += wwx * aSums[wx];
                                    bSum  += wwx * bSums[wx];
                                    gSum  += wwx * gSums[wx];
                                    rSum  += wwx * rSums[wx];
                                }

                                wx = wlen - 1;

                                waSums[wx] = 0;
                                wcSums[wx] = 0;
                                aSums[wx]  = 0;
                                bSums[wx]  = 0;
                                gSums[wx]  = 0;
                                rSums[wx]  = 0;

                                int srcX = x + wx - r;

                                if (srcX >= 0 && srcX < src.Width)
                                {
                                    for (int wy = 0; wy < wlen; ++wy)
                                    {
                                        int srcY = y + wy - r;

                                        if (srcY >= 0 && srcY < src.Height)
                                        {
                                            ColorBgra c  = src.GetPointUnchecked(srcX, srcY);
                                            int       wp = w[wy];

                                            waSums[wx] += wp;
                                            wp         *= c.A + (c.A >> 7);
                                            wcSums[wx] += wp;
                                            wp        >>= 8;

                                            aSums[wx] += wp * (long)c.A;
                                            bSums[wx] += wp * (long)c.B;
                                            gSums[wx] += wp * (long)c.G;
                                            rSums[wx] += wp * (long)c.R;
                                        }
                                    }

                                    int wr = w[wx];
                                    waSum += (long)wr * waSums[wx];
                                    wcSum += (long)wr * wcSums[wx];
                                    aSum  += (long)wr * aSums[wx];
                                    bSum  += (long)wr * bSums[wx];
                                    gSum  += (long)wr * gSums[wx];
                                    rSum  += (long)wr * rSums[wx];
                                }

                                wcSum >>= 8;

                                if (waSum == 0 || wcSum == 0)
                                {
                                    dstPtr->Bgra = 0;
                                }
                                else
                                {
                                    int alpha = (int)(aSum / waSum);
                                    int blue  = (int)(bSum / wcSum);
                                    int green = (int)(gSum / wcSum);
                                    int red   = (int)(rSum / wcSum);

                                    dstPtr->Bgra = ColorBgra.BgraToUInt32(blue, green, red, alpha);
                                }

                                ++dstPtr;
                            }
                        }
                    }
                }
            }
        }
コード例 #4
0
        private unsafe void OnRenderImpl <TMaskSampler>(ISurface <ColorBgra> dstContent, PointInt32 renderOffset, ref TMaskSampler baseMaskSampler) where TMaskSampler : IMaskSampler
        {
            if (Interlocked.Exchange(ref this.isLazyDeltaSelectionMaskFirstTimePrefetched, 1) == 0)
            {
                this.lazyDeltaSelectionMask.EnsureEvaluated();
            }
            else if (Interlocked.Exchange(ref this.isLazyFinalSelectionMaskFirstTimePrefetched, 1) == 0)
            {
                this.lazyFinalSelectionMask.EnsureEvaluated();
            }
            base.ThrowIfCancellationRequested();
            int        width   = dstContent.Width;
            int        height  = dstContent.Height;
            ColorBgra *bgraPtr = (ColorBgra *)dstContent.Scan0;
            int        stride  = dstContent.Stride;
            int        num4    = stride - (width * 4);
            RectInt32  bounds  = new RectInt32(renderOffset.X, renderOffset.Y, width, height);
            uint       num6    = this.changes.BackFillColor.Bgra;

            using (ISurface <ColorAlpha8> surface = alpha8Allocator.Allocate(width, height, AllocationOptions.ZeroFillNotRequired))
            {
                base.ThrowIfCancellationRequested();
                this.sourceTx.Render(dstContent, surface, renderOffset);
                base.ThrowIfCancellationRequested();
                using (ISurface <ColorAlpha8> surface2 = this.lazyFinalSelectionMask.Value.UseTileOrToSurface(bounds))
                {
                    base.ThrowIfCancellationRequested();
                    ColorBgra *pointAddress = this.activeLayer.Surface.GetPointAddress(renderOffset.X, renderOffset.Y);
                    int        num7         = this.activeLayer.Surface.Stride - (width * 4);
                    byte *     numPtr       = (byte *)surface2.Scan0;
                    int        num8         = surface2.Stride - bounds.Width;
                    byte *     numPtr2      = (byte *)surface.Scan0;
                    int        num9         = surface.Stride - bounds.Width;
                    ColorBgra *bgraPtr3     = bgraPtr + width;
                    baseMaskSampler.Initialize();
                    for (int i = 0; i < height; i++)
                    {
                        for (ColorBgra *bgraPtr4 = bgraPtr3 - width; bgraPtr4 < bgraPtr3; bgraPtr4++)
                        {
                            byte next  = baseMaskSampler.GetNext();
                            byte num12 = numPtr[0];
                            byte num13 = numPtr2[0];
                            byte num14 = Math.Min(num13, num12);
                            if (num14 == 0)
                            {
                                byte frac = (byte)(0xff - next);
                                if (frac == 0)
                                {
                                    bgraPtr4->Bgra = num6;
                                }
                                else
                                {
                                    ColorBgra bgra = pointAddress[0];
                                    if (frac != 0xff)
                                    {
                                        bgra.A = ByteUtil.FastScale(bgra.A, frac);
                                    }
                                    bgraPtr4->Bgra = bgra.Bgra;
                                }
                            }
                            else if (num14 != 0xff)
                            {
                                byte      num16 = Math.Min((byte)(0xff - num14), (byte)(0xff - next));
                                ColorBgra bgra2 = bgraPtr4[0];
                                ColorBgra bgra3 = pointAddress[0];
                                ushort    d     = (ushort)((bgra3.A * num16) + (bgra2.A * num14));
                                if (d == 0)
                                {
                                    bgraPtr4->Bgra = num6;
                                }
                                else
                                {
                                    int  num18 = UInt16Util.FastDivideBy255((ushort)((bgra3.A * num16) + (bgra2.A * num14)));
                                    uint num19 = UInt32Util.FastDivideByUInt16((uint)(((bgra3.A * num16) * bgra3.B) + ((bgra2.A * num14) * bgra2.B)), d);
                                    uint num20 = UInt32Util.FastDivideByUInt16((uint)(((bgra3.A * num16) * bgra3.G) + ((bgra2.A * num14) * bgra2.G)), d);
                                    uint num21 = UInt32Util.FastDivideByUInt16((uint)(((bgra3.A * num16) * bgra3.R) + ((bgra2.A * num14) * bgra2.R)), d);
                                    bgraPtr4->Bgra = ColorBgra.BgraToUInt32((byte)num19, (byte)num20, (byte)num21, (byte)num18);
                                }
                            }
                            pointAddress++;
                            numPtr++;
                            numPtr2++;
                        }
                        pointAddress += num7;
                        baseMaskSampler.MoveToNextRow();
                        numPtr   += num8;
                        numPtr2  += num9;
                        bgraPtr3 += stride;
                        base.ThrowIfCancellationRequested();
                    }
                }
            }
        }
コード例 #5
0
ファイル: BlurEffect.cs プロジェクト: vip57884381/Paint.Net
        public override unsafe void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length)
        {
            AmountEffectConfigToken bect = (AmountEffectConfigToken)parameters;

            Surface dst = dstArgs.Surface;
            Surface src = srcArgs.Surface;

            int r = bect.Amount;

            int[] w    = CreateGaussianBlurRow(bect.Amount);
            int   wlen = w.Length;

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

                if (rect.Height >= 1 && rect.Width >= 1)
                {
                    for (int y = rect.Top; y < rect.Bottom; ++y)
                    {
                        long *     waSums = stackalloc long[wlen];
                        long *     wcSums = stackalloc long[wlen];
                        long *     aSums  = stackalloc long[wlen];
                        long *     bSums  = stackalloc long[wlen];
                        long *     gSums  = stackalloc long[wlen];
                        long *     rSums  = stackalloc long[wlen];
                        long       waSum  = 0;
                        long       wcSum  = 0;
                        long       aSum   = 0;
                        long       bSum   = 0;
                        long       gSum   = 0;
                        long       rSum   = 0;
                        ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);

                        for (int wx = 0; wx < wlen; ++wx)
                        {
                            int srcX = rect.Left + wx - r;
                            waSums[wx] = 0;
                            wcSums[wx] = 0;
                            aSums[wx]  = 0;
                            bSums[wx]  = 0;
                            gSums[wx]  = 0;
                            rSums[wx]  = 0;

                            if (srcX >= 0 && srcX < src.Width)
                            {
                                for (int wy = 0; wy < wlen; ++wy)
                                {
                                    int srcY = y + wy - r;

                                    if (srcY >= 0 && srcY < src.Height)
                                    {
                                        ColorBgra c  = src.GetPointUnchecked(srcX, srcY);
                                        int       wp = w[wy];

                                        waSums[wx] += wp;
                                        wp         *= c.A + (c.A >> 7);
                                        wcSums[wx] += wp;
                                        wp        >>= 8;

                                        aSums[wx] += wp * c.A;
                                        bSums[wx] += wp * c.B;
                                        gSums[wx] += wp * c.G;
                                        rSums[wx] += wp * c.R;
                                    }
                                }

                                int wwx = w[wx];
                                waSum += wwx * waSums[wx];
                                wcSum += wwx * wcSums[wx];
                                aSum  += wwx * aSums[wx];
                                bSum  += wwx * bSums[wx];
                                gSum  += wwx * gSums[wx];
                                rSum  += wwx * rSums[wx];
                            }
                        }

                        wcSum >>= 8;

                        if (waSum == 0 || wcSum == 0)
                        {
                            dstPtr->Bgra = 0;
                        }
                        else
                        {
                            int alpha = (int)(aSum / waSum);
                            int blue  = (int)(bSum / wcSum);
                            int green = (int)(gSum / wcSum);
                            int red   = (int)(rSum / wcSum);

                            dstPtr->Bgra = ColorBgra.BgraToUInt32(blue, green, red, alpha);
                        }

                        ++dstPtr;

                        for (int x = rect.Left + 1; x < rect.Right; ++x)
                        {
                            for (int i = 0; i < wlen - 1; ++i)
                            {
                                waSums[i] = waSums[i + 1];
                                wcSums[i] = wcSums[i + 1];
                                aSums[i]  = aSums[i + 1];
                                bSums[i]  = bSums[i + 1];
                                gSums[i]  = gSums[i + 1];
                                rSums[i]  = rSums[i + 1];
                            }

                            waSum = 0;
                            wcSum = 0;
                            aSum  = 0;
                            bSum  = 0;
                            gSum  = 0;
                            rSum  = 0;

                            int wx;
                            for (wx = 0; wx < wlen - 1; ++wx)
                            {
                                long wwx = (long)w[wx];
                                waSum += wwx * waSums[wx];
                                wcSum += wwx * wcSums[wx];
                                aSum  += wwx * aSums[wx];
                                bSum  += wwx * bSums[wx];
                                gSum  += wwx * gSums[wx];
                                rSum  += wwx * rSums[wx];
                            }

                            wx = wlen - 1;

                            waSums[wx] = 0;
                            wcSums[wx] = 0;
                            aSums[wx]  = 0;
                            bSums[wx]  = 0;
                            gSums[wx]  = 0;
                            rSums[wx]  = 0;

                            int srcX = x + wx - r;

                            if (srcX >= 0 && srcX < src.Width)
                            {
                                for (int wy = 0; wy < wlen; ++wy)
                                {
                                    int srcY = y + wy - r;

                                    if (srcY >= 0 && srcY < src.Height)
                                    {
                                        ColorBgra c  = src.GetPointUnchecked(srcX, srcY);
                                        int       wp = w[wy];

                                        waSums[wx] += wp;
                                        wp         *= c.A + (c.A >> 7);
                                        wcSums[wx] += wp;
                                        wp        >>= 8;

                                        aSums[wx] += wp * (long)c.A;
                                        bSums[wx] += wp * (long)c.B;
                                        gSums[wx] += wp * (long)c.G;
                                        rSums[wx] += wp * (long)c.R;
                                    }
                                }

                                int wr = w[wx];
                                waSum += (long)wr * waSums[wx];
                                wcSum += (long)wr * wcSums[wx];
                                aSum  += (long)wr * aSums[wx];
                                bSum  += (long)wr * bSums[wx];
                                gSum  += (long)wr * gSums[wx];
                                rSum  += (long)wr * rSums[wx];
                            }

                            wcSum >>= 8;

                            if (waSum == 0 || wcSum == 0)
                            {
                                dstPtr->Bgra = 0;
                            }
                            else
                            {
                                int alpha = (int)(aSum / waSum);
                                int blue  = (int)(bSum / wcSum);
                                int green = (int)(gSum / wcSum);
                                int red   = (int)(rSum / wcSum);

                                dstPtr->Bgra = ColorBgra.BgraToUInt32(blue, green, red, alpha);
                            }

                            ++dstPtr;
                        }
                    }
                }
            }
        }
コード例 #6
0
        private unsafe void RenderRectangle(Surface dst, Surface src, Rectangle rect)
        {
            double shadowFactor = (double)(Token.GetProperty <Int32Property>("ShadowEffect.Alpha").Value) / 255.0;

            // The blurring algorithm was stolen directly from the BlurEffect code.  I couldn't
            // use it directly because the source image must be transformed prior to applying
            // the blur effect. Also, I gradually increase the blur radius from one end
            // of the shadow to the other, which the blur effect code doesn't support either.
            if (rect.Height >= 1 && rect.Width >= 1)
            {
                // For each row in the rectangle
                for (int y = rect.Top; y < rect.Bottom; ++y)
                {
                    double     radius = invertedYcoordinate(y, src.Height) / (double)rowsPerBlurRadius;
                    int[]      w      = CreateGaussianBlurRow(radius);
                    int        wlen   = w.Length;
                    int        r      = (wlen - 1) / 2;
                    long[]     waSums = new long[wlen];
                    long[]     aSums  = new long[wlen];
                    long       waSum  = 0;
                    long       aSum   = 0;
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);

                    // For each item in the gaussian blur row
                    for (int wx = 0; wx < wlen; ++wx)
                    {
                        int srcX = rect.Left + wx - r;
                        waSums[wx] = 0;
                        aSums[wx]  = 0;

                        if (srcX >= 0 && srcX < src.Width)
                        {
                            for (int wy = 0; wy < wlen; ++wy)
                            {
                                int srcY = y + wy - r;

                                if (srcY >= 0 && srcY < src.Height)
                                {
                                    ColorBgra c  = getShadowPixel(srcX, srcY, src, shadowFactor, (int)Token.GetProperty <DoubleProperty>("ShadowEffect.ShadowAngle").Value, (int)Token.GetProperty <DoubleProperty>("ShadowEffect.ShadowDepthAngle").Value);
                                    int       wp = w[wy];

                                    waSums[wx] += wp;
                                    aSums[wx]  += wp * c.A;
                                }
                            }

                            int wwx = w[wx];
                            waSum += wwx * waSums[wx];
                            aSum  += wwx * aSums[wx];
                        }
                    }

                    if (waSum == 0)
                    {
                        dstPtr->Bgra = 0;
                    }
                    else
                    {
                        dstPtr->Bgra = ColorBgra.BgraToUInt32(0, 0, 0, (int)(aSum / waSum));
                    }

                    ++dstPtr;

                    for (int x = rect.Left + 1; x < rect.Right; ++x)
                    {
                        ColorBgra OrginalImage = src[x, y];

                        for (int i = 0; i < wlen - 1; ++i)
                        {
                            waSums[i] = waSums[i + 1];
                            aSums[i]  = aSums[i + 1];
                        }

                        waSum = 0;
                        aSum  = 0;

                        int wx;
                        for (wx = 0; wx < wlen - 1; ++wx)
                        {
                            long wwx = (long)w[wx];
                            waSum += wwx * waSums[wx];
                            aSum  += wwx * aSums[wx];
                        }

                        wx = wlen - 1;

                        waSums[wx] = 0;
                        aSums[wx]  = 0;

                        int srcX = x + wx - r;

                        if (srcX >= 0 && srcX < src.Width)
                        {
                            for (int wy = 0; wy < wlen; ++wy)
                            {
                                int srcY = y + wy - r;

                                if (srcY >= 0 && srcY < src.Height)
                                {
                                    ColorBgra c  = getShadowPixel(srcX, srcY, src, shadowFactor, (int)Token.GetProperty <DoubleProperty>("ShadowEffect.ShadowAngle").Value, (int)Token.GetProperty <DoubleProperty>("ShadowEffect.ShadowDepthAngle").Value);
                                    int       wp = w[wy];

                                    waSums[wx] += wp;
                                    aSums[wx]  += wp * (long)c.A;
                                }
                            }

                            int wr = w[wx];
                            waSum += (long)wr * waSums[wx];
                            aSum  += (long)wr * aSums[wx];
                        }

                        ColorBgra Shadow = new ColorBgra();
                        if (waSum == 0)
                        {
                            Shadow = ColorBgra.FromBgra(0, 0, 0, 0);
                        }
                        else
                        {
                            Shadow = ColorBgra.FromBgra(0, 0, 0, (byte)(aSum / waSum));
                        }

                        if (Token.GetProperty <BooleanProperty>("ShadowEffect.OriginalImage").Value)
                        {
                            dstPtr->Bgra = (uint)normalOp.Apply(Shadow, OrginalImage);
                        }
                        else
                        {
                            dstPtr->Bgra = (uint)Shadow;
                        }

                        ++dstPtr;
                    }
                }
            }
        }
コード例 #7
0
        private unsafe void RenderContent(ISurface <ColorBgra> dstContent, PointInt32 renderOffset)
        {
            int        width         = dstContent.Width;
            int        height        = dstContent.Height;
            int        stride        = dstContent.Stride;
            int        num4          = stride - (width * 4);
            RectInt32  num5          = RectInt32.Intersect(this.srcCoverageBounds, new RectInt32(0, 0, this.contentWidth, this.contentHeight));
            int        left          = num5.Left;
            int        top           = num5.Top;
            int        right         = num5.Right;
            int        bottom        = num5.Bottom;
            long       num10         = (this.srcOffsetOriginXFp + (renderOffset.X * this.srcOffsetDxDxFp)) + (renderOffset.Y * this.srcOffsetDxDyFp);
            long       num11         = (this.srcOffsetOriginYFp + (renderOffset.X * this.srcOffsetDyDxFp)) + (renderOffset.Y * this.srcOffsetDyDyFp);
            ColorBgra *bgraPtr       = this.contentScan0;
            int        contentStride = this.contentStride;
            ColorBgra *bgraPtr2      = (ColorBgra *)dstContent.Scan0;
            ColorBgra *bgraPtr3      = bgraPtr2 + width;

            for (int i = 0; i < height; i++)
            {
                uint num16;
                int  num17;
                base.ThrowIfCancellationRequested();
                long       num14    = num10;
                long       num15    = num11;
                ColorBgra *bgraPtr4 = bgraPtr3 - width;
                int        num18    = (int)((long)((bgraPtr3 - bgraPtr4) / sizeof(ColorBgra)));
                int        num19    = (int)(num14 >> 0x18);
                int        num20    = (int)(num15 >> 0x18);
                int        num21    = ((num19 >= left) && (num19 < right)) ? 1 : 0;
                int        num22    = ((num20 >= top) && (num20 < bottom)) ? 1 : 0;
                int        num23    = ((num19 >= (left - 1)) && (num19 < (right - 1))) ? 1 : 0;
                int        num24    = ((num20 >= (top - 1)) && (num20 < (bottom - 1))) ? 1 : 0;
                long       num25    = num14 + (this.srcOffsetDxDxFp * num18);
                long       num26    = num15 + (this.srcOffsetDyDxFp * num18);
                int        num27    = (int)(num25 >> 0x18);
                int        num28    = (int)(num26 >> 0x18);
                int        num29    = ((num27 >= left) && (num27 < right)) ? 1 : 0;
                int        num30    = ((num28 >= top) && (num28 < bottom)) ? 1 : 0;
                int        num31    = ((num27 >= (left - 1)) && (num27 < (right - 1))) ? 1 : 0;
                int        num32    = ((num28 >= (top - 1)) && (num28 < (bottom - 1))) ? 1 : 0;
                if ((((((((num21 + num22) + num23) + num24) + num29) + num30) + num31) + num32) == 8)
                {
                    num17 = num18;
                }
                else
                {
                    num17 = 0;
                }
                while ((bgraPtr4 < bgraPtr3) && (num17 > 0))
                {
                    num16 = 0;
                    int         num33 = (int)(num14 >> 0x18);
                    int         num34 = (int)(num15 >> 0x18);
                    int         num35 = 0x100 - (((int)(num14 & 0xffffffL)) >> 0x10);
                    int         num36 = 0x100 - (((int)(num15 & 0xffffffL)) >> 0x10);
                    int         num37 = (num35 * num36) >> 8;
                    int         num38 = ((0x100 - num35) * num36) >> 8;
                    int         num39 = (num35 * (0x100 - num36)) >> 8;
                    int         num40 = ((0x100 - num35) * (0x100 - num36)) >> 8;
                    int         num41 = num37;
                    int         num42 = num38;
                    int         num43 = num39;
                    int         num44 = num40;
                    ushort      d     = (ushort)(((num41 + num42) + num43) + num44);
                    long        num46 = (num34 * contentStride) + (num33 * 4);
                    ColorBgra32 bgra  = *((ColorBgra32 *)(bgraPtr + num46));
                    ColorBgra32 bgra2 = *((ColorBgra32 *)(bgraPtr + (num46 + 4L)));
                    ColorBgra32 bgra3 = *((ColorBgra32 *)(bgraPtr + (num46 + contentStride)));
                    ColorBgra32 bgra4 = *((ColorBgra32 *)(bgraPtr + ((num46 + contentStride) + 4L)));
                    int         num47 = bgra.A * num41;
                    int         num48 = bgra2.A * num42;
                    int         num49 = bgra3.A * num43;
                    int         num50 = bgra4.A * num44;
                    ushort      n     = (ushort)(((num47 + num48) + num49) + num50);
                    if (n != 0)
                    {
                        uint num52 = UInt32Util.FastDivideByUInt16(n, d);
                        uint num53 = UInt32Util.FastDivideByUInt16((uint)((((num47 * bgra.B) + (num48 * bgra2.B)) + (num49 * bgra3.B)) + (num50 * bgra4.B)), n);
                        uint num54 = UInt32Util.FastDivideByUInt16((uint)((((num47 * bgra.G) + (num48 * bgra2.G)) + (num49 * bgra3.G)) + (num50 * bgra4.G)), n);
                        uint num55 = UInt32Util.FastDivideByUInt16((uint)((((num47 * bgra.R) + (num48 * bgra2.R)) + (num49 * bgra3.R)) + (num50 * bgra4.R)), n);
                        num16 = ColorBgra.BgraToUInt32((byte)num53, (byte)num54, (byte)num55, (byte)num52);
                    }
                    bgraPtr4->Bgra = num16;
                    num14         += this.srcOffsetDxDxFp;
                    num15         += this.srcOffsetDyDxFp;
                    bgraPtr4++;
                    num17--;
                }
                while (bgraPtr4 < bgraPtr3)
                {
                    num16 = 0;
                    int num56 = (int)(num14 >> 0x18);
                    int num57 = (int)(num15 >> 0x18);
                    int num58 = ((num56 >= left) && (num56 < right)) ? 1 : 0;
                    int num59 = ((num57 >= top) && (num57 < bottom)) ? 1 : 0;
                    int num60 = ((num56 >= (left - 1)) && (num56 < (right - 1))) ? 1 : 0;
                    int num61 = ((num57 >= (top - 1)) && (num57 < (bottom - 1))) ? 1 : 0;
                    int num62 = num59 * num58;
                    int num63 = num59 * num60;
                    int num64 = num61 * num58;
                    int num65 = num61 * num60;
                    if ((((num62 + num63) + num64) + num65) != 0)
                    {
                        int         num67 = 0x100 - (((int)(num14 & 0xffffffL)) >> 0x10);
                        int         num68 = 0x100 - (((int)(num15 & 0xffffffL)) >> 0x10);
                        int         num69 = (num67 * num68) >> 8;
                        int         num70 = ((0x100 - num67) * num68) >> 8;
                        int         num71 = (num67 * (0x100 - num68)) >> 8;
                        int         num72 = ((0x100 - num67) * (0x100 - num68)) >> 8;
                        int         num73 = num62 * num69;
                        int         num74 = num63 * num70;
                        int         num75 = num64 * num71;
                        int         num76 = num65 * num72;
                        ushort      num77 = (ushort)(((num73 + num74) + num75) + num76);
                        long        num78 = (num57 * contentStride) + (num56 * 4);
                        ColorBgra32 bgra5 = *((ColorBgra32 *)(bgraPtr + (num78 * num62)));
                        ColorBgra32 bgra6 = *((ColorBgra32 *)(bgraPtr + ((num78 + 4L) * num63)));
                        ColorBgra32 bgra7 = *((ColorBgra32 *)(bgraPtr + ((num78 + contentStride) * num64)));
                        ColorBgra32 bgra8 = *((ColorBgra32 *)(bgraPtr + (((num78 + contentStride) + 4L) * num65)));
                        int         num79 = bgra5.A * num73;
                        int         num80 = bgra6.A * num74;
                        int         num81 = bgra7.A * num75;
                        int         num82 = bgra8.A * num76;
                        ushort      num83 = (ushort)(((num79 + num80) + num81) + num82);
                        if (num83 != 0)
                        {
                            uint num84 = UInt32Util.FastDivideByUInt16(num83, num77);
                            uint num85 = UInt32Util.FastDivideByUInt16((uint)((((num79 * bgra5.B) + (num80 * bgra6.B)) + (num81 * bgra7.B)) + (num82 * bgra8.B)), num83);
                            uint num86 = UInt32Util.FastDivideByUInt16((uint)((((num79 * bgra5.G) + (num80 * bgra6.G)) + (num81 * bgra7.G)) + (num82 * bgra8.G)), num83);
                            uint num87 = UInt32Util.FastDivideByUInt16((uint)((((num79 * bgra5.R) + (num80 * bgra6.R)) + (num81 * bgra7.R)) + (num82 * bgra8.R)), num83);
                            num16 = ColorBgra.BgraToUInt32((byte)num85, (byte)num86, (byte)num87, (byte)num84);
                        }
                    }
                    bgraPtr4->Bgra = num16;
                    num14         += this.srcOffsetDxDxFp;
                    num15         += this.srcOffsetDyDxFp;
                    bgraPtr4++;
                }
                num10    += this.srcOffsetDxDyFp;
                num11    += this.srcOffsetDyDyFp;
                bgraPtr3 += stride;
            }
        }
コード例 #8
0
        protected unsafe override void RenderLine(ISurface src, ISurface dest, Rectangle rect)
        {
            if (radius == 0)
            {
                // Copy src to dest
                return;
            }

            int r    = radius;
            int wlen = w.Length;

            int   localStoreSize = wlen * 6 * sizeof(long);
            byte *localStore     = stackalloc byte[localStoreSize];
            byte *p = localStore;

            long *waSums = (long *)p;

            p += wlen * sizeof(long);

            long *wcSums = (long *)p;

            p += wlen * sizeof(long);

            long *aSums = (long *)p;

            p += wlen * sizeof(long);

            long *bSums = (long *)p;

            p += wlen * sizeof(long);

            long *gSums = (long *)p;

            p += wlen * sizeof(long);

            long *rSums = (long *)p;

            p += wlen * sizeof(long);

            int src_width  = src.Width;
            int src_height = src.Height;

            if (rect.Height >= 1 && rect.Width >= 1)
            {
                for (int y = rect.Top; y <= rect.Bottom; ++y)
                {
                    //Memory.SetToZero (localStore, (ulong)localStoreSize);

                    long waSum = 0;
                    long wcSum = 0;
                    long aSum  = 0;
                    long bSum  = 0;
                    long gSum  = 0;
                    long rSum  = 0;

                    ColorBgra *dstPtr = dest.GetPointAddress(rect.Left, y);

                    for (int wx = 0; wx < wlen; ++wx)
                    {
                        int srcX = rect.Left + wx - r;
                        waSums[wx] = 0;
                        wcSums[wx] = 0;
                        aSums[wx]  = 0;
                        bSums[wx]  = 0;
                        gSums[wx]  = 0;
                        rSums[wx]  = 0;

                        if (srcX >= 0 && srcX < src_width)
                        {
                            for (int wy = 0; wy < wlen; ++wy)
                            {
                                int srcY = y + wy - r;

                                if (srcY >= 0 && srcY < src_height)
                                {
                                    ColorBgra c  = src.GetPoint(srcX, srcY);
                                    int       wp = w[wy];

                                    waSums[wx] += wp;
                                    wp         *= c.A + (c.A >> 7);
                                    wcSums[wx] += wp;
                                    wp        >>= 8;

                                    aSums[wx] += wp * c.A;
                                    bSums[wx] += wp * c.B;
                                    gSums[wx] += wp * c.G;
                                    rSums[wx] += wp * c.R;
                                }
                            }

                            int wwx = w[wx];
                            waSum += wwx * waSums[wx];
                            wcSum += wwx * wcSums[wx];
                            aSum  += wwx * aSums[wx];
                            bSum  += wwx * bSums[wx];
                            gSum  += wwx * gSums[wx];
                            rSum  += wwx * rSums[wx];
                        }
                    }

                    wcSum >>= 8;

                    if (waSum == 0 || wcSum == 0)
                    {
                        dstPtr->Bgra = 0;
                    }
                    else
                    {
                        int alpha = (int)(aSum / waSum);
                        int blue  = (int)(bSum / wcSum);
                        int green = (int)(gSum / wcSum);
                        int red   = (int)(rSum / wcSum);

                        dstPtr->Bgra = ColorBgra.BgraToUInt32(blue, green, red, alpha);
                    }

                    ++dstPtr;

                    for (int x = rect.Left + 1; x <= rect.Right; ++x)
                    {
                        for (int i = 0; i < wlen - 1; ++i)
                        {
                            waSums[i] = waSums[i + 1];
                            wcSums[i] = wcSums[i + 1];
                            aSums[i]  = aSums[i + 1];
                            bSums[i]  = bSums[i + 1];
                            gSums[i]  = gSums[i + 1];
                            rSums[i]  = rSums[i + 1];
                        }

                        waSum = 0;
                        wcSum = 0;
                        aSum  = 0;
                        bSum  = 0;
                        gSum  = 0;
                        rSum  = 0;

                        int wx;
                        for (wx = 0; wx < wlen - 1; ++wx)
                        {
                            long wwx = (long)w[wx];
                            waSum += wwx * waSums[wx];
                            wcSum += wwx * wcSums[wx];
                            aSum  += wwx * aSums[wx];
                            bSum  += wwx * bSums[wx];
                            gSum  += wwx * gSums[wx];
                            rSum  += wwx * rSums[wx];
                        }

                        wx = wlen - 1;

                        waSums[wx] = 0;
                        wcSums[wx] = 0;
                        aSums[wx]  = 0;
                        bSums[wx]  = 0;
                        gSums[wx]  = 0;
                        rSums[wx]  = 0;

                        int srcX = x + wx - r;

                        if (srcX >= 0 && srcX < src_width)
                        {
                            for (int wy = 0; wy < wlen; ++wy)
                            {
                                int srcY = y + wy - r;

                                if (srcY >= 0 && srcY < src_height)
                                {
                                    ColorBgra c  = src.GetPoint(srcX, srcY);
                                    int       wp = w[wy];

                                    waSums[wx] += wp;
                                    wp         *= c.A + (c.A >> 7);
                                    wcSums[wx] += wp;
                                    wp        >>= 8;

                                    aSums[wx] += wp * (long)c.A;
                                    bSums[wx] += wp * (long)c.B;
                                    gSums[wx] += wp * (long)c.G;
                                    rSums[wx] += wp * (long)c.R;
                                }
                            }

                            int wr = w[wx];
                            waSum += (long)wr * waSums[wx];
                            wcSum += (long)wr * wcSums[wx];
                            aSum  += (long)wr * aSums[wx];
                            bSum  += (long)wr * bSums[wx];
                            gSum  += (long)wr * gSums[wx];
                            rSum  += (long)wr * rSums[wx];
                        }

                        wcSum >>= 8;

                        if (waSum == 0 || wcSum == 0)
                        {
                            dstPtr->Bgra = 0;
                        }
                        else
                        {
                            int alpha = (int)(aSum / waSum);
                            int blue  = (int)(bSum / wcSum);
                            int green = (int)(gSum / wcSum);
                            int red   = (int)(rSum / wcSum);

                            dstPtr->Bgra = ColorBgra.BgraToUInt32(blue, green, red, alpha);
                        }

                        ++dstPtr;
                    }
                }
            }
        }
コード例 #9
0
        /// <summary>
        /// Creates the shadow of the source image
        /// </summary>
        /// <param name="dst">Describes the destination surface.</param>
        /// <param name="src">Describes the source surface.</param>
        /// <param name="rect">The rectangle that describes the region of interest.</param>
        /// <param name="configuration"></param>
        ///
        private unsafe void RenderRectangle(Surface dst, Surface src, Rectangle rect, ShadowEffectConfiguration configuration)
        {
            double shadowFactor = configuration.Opacity / ShadowEffectProperties.MaxOpacity;

            //
            // The blurring algorithm was stolen directly from the BlurEffect code.  I couldn't
            // use it directly because the source image must be transformed prior to applying
            // the blur effect. Also, I gradually increase the blur radius from one end
            // of the shadow to the other, which the blur effect code doesn't support either.
            //
            if (rect.Height >= 1 && rect.Width >= 1)
            {
                // For each row in the rectangle
                for (int y = rect.Top; y < rect.Bottom; ++y)
                {
                    //
                    // Shadow Diffusion - The blur radius increases the further the row is from the bottom
                    // Diffusion Factor - [0-100] How much the shadow is diffused.  0 = None, 100 = Max
                    //
                    double blurRadius = 0;
                    if (configuration.DiffusionFactor > 0)
                    {
                        // diffusion factor of 50 = 5 rows/blur_radius
                        double rowsPerBlurRadius = 250.0 / (double)configuration.DiffusionFactor;
                        blurRadius = invertedYcoordinate(y, src.Height) / rowsPerBlurRadius;
                    }

                    int[]      w      = CreateGaussianBlurRow(blurRadius);
                    int        wlen   = w.Length;
                    int        r      = (wlen - 1) / 2;
                    long[]     waSums = new long[wlen];
                    long[]     aSums  = new long[wlen];
                    long       waSum  = 0;
                    long       aSum   = 0;
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);

                    // For each item in the gaussian blur row
                    for (int wx = 0; wx < wlen; ++wx)
                    {
                        int srcX = rect.Left + wx - r;
                        waSums[wx] = 0;
                        aSums[wx]  = 0;

                        if (srcX >= 0 && srcX < src.Width)
                        {
                            for (int wy = 0; wy < wlen; ++wy)
                            {
                                int srcY = y + wy - r;

                                if (srcY >= 0 && srcY < src.Height)
                                {
                                    ColorBgra c  = getShadowPixel(srcX, srcY, src, shadowFactor, configuration.Angle, configuration.DepthAngle);
                                    int       wp = w[wy];

                                    waSums[wx] += wp;
                                    aSums[wx]  += wp * c.A;
                                }
                            }

                            int wwx = w[wx];
                            waSum += wwx * waSums[wx];
                            aSum  += wwx * aSums[wx];
                        }
                    }

                    if (waSum == 0)
                    {
                        dstPtr->Bgra = 0;
                    }
                    else
                    {
                        dstPtr->Bgra = ColorBgra.BgraToUInt32(0, 0, 0, (int)(aSum / waSum));
                    }

                    ++dstPtr;

                    for (int x = rect.Left + 1; x < rect.Right; ++x)
                    {
                        ColorBgra OrginalImage = src[x, y];

                        for (int i = 0; i < wlen - 1; ++i)
                        {
                            waSums[i] = waSums[i + 1];
                            aSums[i]  = aSums[i + 1];
                        }

                        waSum = 0;
                        aSum  = 0;

                        int wx;
                        for (wx = 0; wx < wlen - 1; ++wx)
                        {
                            long wwx = (long)w[wx];
                            waSum += wwx * waSums[wx];
                            aSum  += wwx * aSums[wx];
                        }

                        wx = wlen - 1;

                        waSums[wx] = 0;
                        aSums[wx]  = 0;

                        int srcX = x + wx - r;

                        if (srcX >= 0 && srcX < src.Width)
                        {
                            for (int wy = 0; wy < wlen; ++wy)
                            {
                                int srcY = y + wy - r;

                                if (srcY >= 0 && srcY < src.Height)
                                {
                                    ColorBgra c  = getShadowPixel(srcX, srcY, src, shadowFactor, configuration.Angle, configuration.DepthAngle);
                                    int       wp = w[wy];

                                    waSums[wx] += wp;
                                    aSums[wx]  += wp * (long)c.A;
                                }
                            }

                            int wr = w[wx];
                            waSum += (long)wr * waSums[wx];
                            aSum  += (long)wr * aSums[wx];
                        }

                        ColorBgra Shadow = new ColorBgra();
                        if (waSum == 0)
                        {
                            Shadow = ColorBgra.FromBgra(0, 0, 0, 0);
                        }
                        else
                        {
                            Shadow = ColorBgra.FromBgra(0, 0, 0, (byte)(aSum / waSum));
                        }

                        if (configuration.KeepOriginalImage)
                        {
                            dstPtr->Bgra = (uint)_normalOp.Apply(Shadow, OrginalImage);
                        }
                        else
                        {
                            dstPtr->Bgra = (uint)Shadow;
                        }

                        ++dstPtr;
                    }
                }
            }
        }