예제 #1
0
        /// <summary>
        /// TODO: Does not work with multi-buffer groups, should be specific to Resize.
        /// Copy <paramref name="columnCount"/> columns of <paramref name="buffer"/> inplace,
        /// from positions starting at <paramref name="sourceIndex"/> to positions at <paramref name="destIndex"/>.
        /// </summary>
        internal static unsafe void CopyColumns <T>(
            this Buffer2D <T> buffer,
            int sourceIndex,
            int destIndex,
            int columnCount)
            where T : struct
        {
            DebugGuard.NotNull(buffer, nameof(buffer));
            DebugGuard.MustBeGreaterThanOrEqualTo(sourceIndex, 0, nameof(sourceIndex));
            DebugGuard.MustBeGreaterThanOrEqualTo(destIndex, 0, nameof(sourceIndex));
            CheckColumnRegionsDoNotOverlap(buffer, sourceIndex, destIndex, columnCount);

            int  elementSize = Unsafe.SizeOf <T>();
            int  width       = buffer.Width * elementSize;
            int  sOffset     = sourceIndex * elementSize;
            int  dOffset     = destIndex * elementSize;
            long count       = columnCount * elementSize;

            Span <byte> span = MemoryMarshal.AsBytes(buffer.GetSingleMemory().Span);

            fixed(byte *ptr = span)
            {
                byte *basePtr = ptr;

                for (int y = 0; y < buffer.Height; y++)
                {
                    byte *sPtr = basePtr + sOffset;
                    byte *dPtr = basePtr + dOffset;

                    Buffer.MemoryCopy(sPtr, dPtr, count, count);

                    basePtr += width;
                }
            }
        }
예제 #2
0
        internal bool TryGetPaddedRowSpan(int y, int padding, out Span <T> paddedSpan)
        {
            DebugGuard.MustBeGreaterThanOrEqualTo(y, 0, nameof(y));
            DebugGuard.MustBeLessThan(y, this.Height, nameof(y));

            int stride = this.Width + padding;

            if (this.cachedMemory.Length > 0)
            {
                paddedSpan = this.cachedMemory.Span.Slice(y * this.Width);
                if (paddedSpan.Length < stride)
                {
                    return(false);
                }

                paddedSpan = paddedSpan.Slice(0, stride);
                return(true);
            }

            Memory <T> memory = this.FastMemoryGroup.GetRemainingSliceOfBuffer(y * (long)this.Width);

            if (memory.Length < stride)
            {
                paddedSpan = default;
                return(false);
            }

            paddedSpan = memory.Span.Slice(0, stride);
            return(true);
        }
예제 #3
0
        /// <summary>
        /// Applies the opactiy weighting for each pixel in a scanline to the target based on the pattern contained in the brush.
        /// </summary>
        /// <param name="scanlineBuffer">The a collection of opacity values between 0 and 1 to be merged with the brushed color value before being applied to the target.</param>
        /// <param name="scanlineWidth">The number of pixels effected by this scanline.</param>
        /// <param name="offset">The offset fromthe begining of <paramref name="scanlineBuffer" /> the opacity data starts.</param>
        /// <param name="x">The x position in the target pixel space that the start of the scanline data corresponds to.</param>
        /// <param name="y">The y position in  the target pixel space that whole scanline corresponds to.</param>
        /// <remarks>scanlineBuffer will be > scanlineWidth but provide and offset in case we want to share a larger buffer across runs.</remarks>
        internal virtual void Apply(float[] scanlineBuffer, int scanlineWidth, int offset, int x, int y)
        {
            DebugGuard.MustBeGreaterThanOrEqualTo(scanlineBuffer.Length, offset + scanlineWidth, nameof(scanlineWidth));

            using (Buffer <float> buffer = new Buffer <float>(scanlineBuffer))
            {
                BufferSpan <float> slice = buffer.Slice(offset);

                for (int xPos = 0; xPos < scanlineWidth; xPos++)
                {
                    int targetX = xPos + x;
                    int targetY = y;

                    float opacity = slice[xPos];
                    if (opacity > Constants.Epsilon)
                    {
                        Vector4 backgroundVector = this.Target[targetX, targetY].ToVector4();

                        Vector4 sourceVector = this[targetX, targetY].ToVector4();

                        Vector4 finalColor = Vector4BlendTransforms.PremultipliedLerp(backgroundVector, sourceVector, opacity);

                        TPixel packed = default(TPixel);
                        packed.PackFromVector4(finalColor);
                        this.Target[targetX, targetY] = packed;
                    }
                }
            }
        }
예제 #4
0
        public void MustBeGreaterThanOrEqualTo_IsLess_ThrowsNoException()
        {
            ArgumentOutOfRangeException exception = Assert.Throws <ArgumentOutOfRangeException>(
                () => DebugGuard.MustBeGreaterThanOrEqualTo(1, 2, "myParamName"));

            Assert.Equal("myParamName", exception.ParamName);
            Assert.Contains($"Value 1 must be greater than or equal to 2.", exception.Message);
        }
예제 #5
0
        public Span <T> GetRowSpan(int y)
        {
            DebugGuard.MustBeGreaterThanOrEqualTo(y, 0, nameof(y));
            DebugGuard.MustBeLessThan(y, this.Height, nameof(y));

            return(this.cachedMemory.Length > 0
                ? this.cachedMemory.Span.Slice(y * this.Width, this.Width)
                : this.GetRowMemorySlow(y).Span);
        }
예제 #6
0
        public BufferArea(Buffer2D <T> destinationBuffer, Rectangle rectangle)
        {
            DebugGuard.MustBeGreaterThanOrEqualTo(rectangle.X, 0, nameof(rectangle));
            DebugGuard.MustBeGreaterThanOrEqualTo(rectangle.Y, 0, nameof(rectangle));
            DebugGuard.MustBeLessThanOrEqualTo(rectangle.Width, destinationBuffer.Width, nameof(rectangle));
            DebugGuard.MustBeLessThanOrEqualTo(rectangle.Height, destinationBuffer.Height, nameof(rectangle));

            this.DestinationBuffer = destinationBuffer;
            this.Rectangle         = rectangle;
        }
예제 #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ArraySlice{T}"/> struct.
        /// </summary>
        /// <param name="data">The underlying data buffer.</param>
        /// <param name="start">The offset position in the underlying buffer this slice was created from.</param>
        /// <param name="length">The number of items in the slice.</param>
        public ArraySlice(T[] data, int start, int length)
        {
            DebugGuard.MustBeGreaterThanOrEqualTo(start, 0, nameof(start));
            DebugGuard.MustBeLessThanOrEqualTo(length, data.Length, nameof(length));
            DebugGuard.MustBeLessThanOrEqualTo(start + length, data.Length, nameof(this.data));

            this.data   = data;
            this.Start  = start;
            this.Length = length;
        }
예제 #8
0
        public Buffer2DRegion(Buffer2D <T> buffer, Rectangle rectangle)
        {
            DebugGuard.MustBeGreaterThanOrEqualTo(rectangle.X, 0, nameof(rectangle));
            DebugGuard.MustBeGreaterThanOrEqualTo(rectangle.Y, 0, nameof(rectangle));
            DebugGuard.MustBeLessThanOrEqualTo(rectangle.Width, buffer.Width, nameof(rectangle));
            DebugGuard.MustBeLessThanOrEqualTo(rectangle.Height, buffer.Height, nameof(rectangle));

            this.Buffer    = buffer;
            this.Rectangle = rectangle;
        }
예제 #9
0
        private static void AddVector(Span <uint> a, Span <uint> b, Span <uint> output, int count)
        {
            DebugGuard.MustBeGreaterThanOrEqualTo(a.Length, count, nameof(a.Length));
            DebugGuard.MustBeGreaterThanOrEqualTo(b.Length, count, nameof(b.Length));
            DebugGuard.MustBeGreaterThanOrEqualTo(output.Length, count, nameof(output.Length));

#if SUPPORTS_RUNTIME_INTRINSICS
            if (Avx2.IsSupported)
            {
                ref uint aRef      = ref MemoryMarshal.GetReference(a);
                ref uint bRef      = ref MemoryMarshal.GetReference(b);
예제 #10
0
        /// <summary>
        /// Gets a reference to the element at the specified position.
        /// </summary>
        /// <param name="x">The x coordinate (row)</param>
        /// <param name="y">The y coordinate (position at row)</param>
        /// <returns>A reference to the element.</returns>
        /// <exception cref="IndexOutOfRangeException">When index is out of range of the buffer.</exception>
        public ref T this[int x, int y]
        {
            [MethodImpl(InliningOptions.ShortMethod)]
            get
            {
                DebugGuard.MustBeGreaterThanOrEqualTo(x, 0, nameof(x));
                DebugGuard.MustBeGreaterThanOrEqualTo(y, 0, nameof(y));
                DebugGuard.MustBeLessThan(x, this.Width, nameof(x));
                DebugGuard.MustBeLessThan(y, this.Height, nameof(y));

                return(ref this.GetRowSpan(y)[x]);
            }
        }
예제 #11
0
        /// <summary>
        /// Gets the best makeup run length for a given run length
        /// </summary>
        /// <param name="runLength">A run length needing a makeup code</param>
        /// <returns>The makeup length for <paramref name="runLength"/>.</returns>
        protected uint GetBestFittingMakeupRunLength(uint runLength)
        {
            DebugGuard.MustBeGreaterThanOrEqualTo(runLength, MakeupRunLength[0], nameof(runLength));

            for (int i = 0; i < MakeupRunLength.Length - 1; i++)
            {
                if (MakeupRunLength[i] <= runLength && MakeupRunLength[i + 1] > runLength)
                {
                    return(MakeupRunLength[i]);
                }
            }

            return(MakeupRunLength[MakeupRunLength.Length - 1]);
        }
예제 #12
0
            internal Enumerator(ArraySlice <T> slice)
            {
                DebugGuard.NotNull(slice.data, nameof(slice.data));
                DebugGuard.MustBeGreaterThanOrEqualTo(slice.Start, 0, nameof(slice.Start));
                DebugGuard.MustBeGreaterThanOrEqualTo(slice.Length, 0, nameof(slice.Length));

                DebugGuard.MustBeLessThanOrEqualTo(
                    slice.Start + slice.Length,
                    slice.data.Length,
                    nameof(slice.data.Length));

                this.array   = slice.data;
                this.start   = slice.Start;
                this.end     = slice.Start + slice.Length;
                this.current = slice.Start - 1;
            }
예제 #13
0
        internal bool DangerousTryGetPaddedRowSpan(int y, int padding, out Span <T> paddedSpan)
        {
            DebugGuard.MustBeGreaterThanOrEqualTo(y, 0, nameof(y));
            DebugGuard.MustBeLessThan(y, this.Height, nameof(y));

            int stride = this.Width + padding;

            Span <T> slice = this.FastMemoryGroup.GetRemainingSliceOfBuffer(y * (long)this.Width);

            if (slice.Length < stride)
            {
                paddedSpan = default;
                return(false);
            }

            paddedSpan = slice.Slice(0, stride);
            return(true);
        }
예제 #14
0
파일: Adler32.cs 프로젝트: bixiu/BlueMine
        public void Update(byte[] buffer, int offset, int count)
        {
            DebugGuard.NotNull(buffer, nameof(buffer));
            DebugGuard.MustBeGreaterThanOrEqualTo(offset, 0, nameof(offset));
            DebugGuard.MustBeGreaterThanOrEqualTo(count, 0, nameof(count));
            DebugGuard.MustBeLessThan(offset, buffer.Length, nameof(offset));
            DebugGuard.MustBeLessThanOrEqualTo(offset + count, buffer.Length, nameof(count));

            // (By Per Bothner)
            uint s1 = this.checksum & 0xFFFF;
            uint s2 = this.checksum >> 16;

            while (count > 0)
            {
                // We can defer the modulo operation:
                // s1 maximally grows from 65521 to 65521 + 255 * 3800
                // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31
                int n = 3800;
                if (n > count)
                {
                    n = count;
                }

                count -= n;
                while (--n >= 0)
                {
                    s1 = s1 + (uint)(buffer[offset++] & 0xff);
                    s2 = s2 + s1;
                }

                s1 %= Base;
                s2 %= Base;
            }

            this.checksum = (s2 << 16) | s1;
        }
예제 #15
0
 internal Memory <T> GetSafeRowMemory(int y)
 {
     DebugGuard.MustBeGreaterThanOrEqualTo(y, 0, nameof(y));
     DebugGuard.MustBeLessThan(y, this.Height, nameof(y));
     return(this.FastMemoryGroup.View.GetBoundedMemorySlice(y * (long)this.Width, this.Width));
 }
예제 #16
0
 public void MustBeGreaterThanOrEqualTo_IsGreaterOrEqual_ThrowsNoException(int value, int min)
 {
     DebugGuard.MustBeGreaterThanOrEqualTo(value, min, "myParamName");
 }