private void BulkVectorConvert <TPixel>(Span <TPixel> destination, Span <TPixel> background, Span <TPixel> source, Span <float> amount)
            where TPixel : struct, IPixel <TPixel>
        {
            Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
            Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
            Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));

            using (IMemoryOwner <Vector4> buffer = Configuration.Default.MemoryAllocator.Allocate <Vector4>(destination.Length * 3))
            {
                Span <Vector4> destinationSpan = buffer.Slice(0, destination.Length);
                Span <Vector4> backgroundSpan  = buffer.Slice(destination.Length, destination.Length);
                Span <Vector4> sourceSpan      = buffer.Slice(destination.Length * 2, destination.Length);

                PixelOperations <TPixel> .Instance.ToVector4(background, backgroundSpan, destination.Length);

                PixelOperations <TPixel> .Instance.ToVector4(source, sourceSpan, destination.Length);

                for (int i = 0; i < destination.Length; i++)
                {
                    destinationSpan[i] = PorterDuffFunctions.Normal(backgroundSpan[i], sourceSpan[i], amount[i]);
                }

                PixelOperations <TPixel> .Instance.PackFromVector4(destinationSpan, destination, destination.Length);
            }
        }
        /// <summary>
        /// Blends 2 rows together
        /// </summary>
        /// <typeparam name="TPixelSrc">the pixel format of the source span</typeparam>
        /// <param name="configuration"><see cref="Configuration"/> to use internally</param>
        /// <param name="destination">the destination span</param>
        /// <param name="background">the background span</param>
        /// <param name="source">the source span</param>
        /// <param name="amount">
        /// A value between 0 and 1 indicating the weight of the second source vector.
        /// At amount = 0, "background" is returned, at amount = 1, "source" is returned.
        /// </param>
        public void Blend <TPixelSrc>(
            Configuration configuration,
            Span <TPixel> destination,
            ReadOnlySpan <TPixel> background,
            ReadOnlySpan <TPixelSrc> source,
            float amount)
            where TPixelSrc : unmanaged, IPixel <TPixelSrc>
        {
            Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
            Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
            Guard.MustBeBetweenOrEqualTo(amount, 0, 1, nameof(amount));

            using (IMemoryOwner <Vector4> buffer =
                       configuration.MemoryAllocator.Allocate <Vector4>(destination.Length * 3))
            {
                Span <Vector4> destinationSpan = buffer.Slice(0, destination.Length);
                Span <Vector4> backgroundSpan  = buffer.Slice(destination.Length, destination.Length);
                Span <Vector4> sourceSpan      = buffer.Slice(destination.Length * 2, destination.Length);

                ReadOnlySpan <TPixel> sourcePixels = background.Slice(0, background.Length);
                PixelOperations <TPixel> .Instance.ToVector4(configuration, sourcePixels, backgroundSpan, PixelConversionModifiers.Scale);

                ReadOnlySpan <TPixelSrc> sourcePixels1 = source.Slice(0, background.Length);
                PixelOperations <TPixelSrc> .Instance.ToVector4(configuration, sourcePixels1, sourceSpan, PixelConversionModifiers.Scale);

                this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount);

                Span <Vector4> sourceVectors = destinationSpan.Slice(0, background.Length);
                PixelOperations <TPixel> .Instance.FromVector4Destructive(configuration, sourceVectors, destination, PixelConversionModifiers.Scale);
            }
        }
Example #3
0
        private int ReadImpl(Span <byte> buffer)
        {
            this.EnsureNotDisposed();

            if (this.readChunk is null)
            {
                if (this.memoryChunk is null)
                {
                    return(0);
                }

                this.readChunk  = this.memoryChunk;
                this.readOffset = 0;
            }

            IMemoryOwner <byte> chunkBuffer = this.readChunk.Buffer;
            int chunkSize = this.readChunk.Length;

            if (this.readChunk.Next is null)
            {
                chunkSize = this.writeOffset;
            }

            int bytesRead = 0;
            int offset    = 0;
            int count     = buffer.Length;

            while (count > 0)
            {
                if (this.readOffset == chunkSize)
                {
                    // Exit if no more chunks are currently available
                    if (this.readChunk.Next is null)
                    {
                        break;
                    }

                    this.readChunk  = this.readChunk.Next;
                    this.readOffset = 0;
                    chunkBuffer     = this.readChunk.Buffer;
                    chunkSize       = this.readChunk.Length;
                    if (this.readChunk.Next is null)
                    {
                        chunkSize = this.writeOffset;
                    }
                }

                int readCount = Math.Min(count, chunkSize - this.readOffset);
                chunkBuffer.Slice(this.readOffset, readCount).CopyTo(buffer.Slice(offset));
                offset          += readCount;
                count           -= readCount;
                this.readOffset += readCount;
                bytesRead       += readCount;
            }

            return(bytesRead);
        }
Example #4
0
        private IMemoryOwner <byte> GetBytes(string text)
        {
            Debug.Assert(text != null);

            int length = s_utf8noBom.GetMaxByteCount(text.Length); // Utf8 is 1-4 bpc

            IMemoryOwner <byte> rented = _pool.Rent(length);

            length = s_utf8noBom.GetBytes(text, rented.Memory.Span);

            return(rented.Slice(0, length));
        }
        /// <summary>
        /// Blends 2 rows together
        /// </summary>
        /// <typeparam name="TPixelSrc">the pixel format of the source span</typeparam>
        /// <param name="memoryManager">memory manager to use internally</param>
        /// <param name="destination">the destination span</param>
        /// <param name="background">the background span</param>
        /// <param name="source">the source span</param>
        /// <param name="amount">
        /// A span with values between 0 and 1 indicating the weight of the second source vector.
        /// At amount = 0, "from" is returned, at amount = 1, "to" is returned.
        /// </param>
        public void Blend <TPixelSrc>(MemoryAllocator memoryManager, Span <TPixel> destination, ReadOnlySpan <TPixel> background, ReadOnlySpan <TPixelSrc> source, ReadOnlySpan <float> amount)
            where TPixelSrc : struct, IPixel <TPixelSrc>
        {
            Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
            Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
            Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));

            using (IMemoryOwner <Vector4> buffer = memoryManager.Allocate <Vector4>(destination.Length * 3))
            {
                Span <Vector4> destinationSpan = buffer.Slice(0, destination.Length);
                Span <Vector4> backgroundSpan  = buffer.Slice(destination.Length, destination.Length);
                Span <Vector4> sourceSpan      = buffer.Slice(destination.Length * 2, destination.Length);

                PixelOperations <TPixel> .Instance.ToScaledVector4(background, backgroundSpan, destination.Length);

                PixelOperations <TPixelSrc> .Instance.ToScaledVector4(source, sourceSpan, destination.Length);

                this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount);

                PixelOperations <TPixel> .Instance.PackFromScaledVector4(destinationSpan, destination, destination.Length);
            }
        }
Example #6
0
        public static void MemoryPool_byte_WrapSlice_start_noop()
        {
            MemoryPool <byte> pool = MemoryPool <byte> .Shared;

            IMemoryOwner <byte> owner1 = pool.Rent(99);
            IMemoryOwner <byte> owner2 = owner1.Slice(10);

            Assert.False(ReferenceEquals(owner1, owner2));

            IMemoryOwner <byte> owner3 = pool.Rent(0);
            IMemoryOwner <byte> owner4 = owner3.Slice(0);

            Assert.True(ReferenceEquals(owner3, owner4));
        }
Example #7
0
        /// <summary>
        /// Blends 2 rows together
        /// </summary>
        /// <typeparam name="TPixelSrc">the pixel format of the source span</typeparam>
        /// <param name="configuration"><see cref="Configuration"/> to use internally</param>
        /// <param name="destination">the destination span</param>
        /// <param name="background">the background span</param>
        /// <param name="source">the source span</param>
        /// <param name="amount">
        /// A value between 0 and 1 indicating the weight of the second source vector.
        /// At amount = 0, "from" is returned, at amount = 1, "to" is returned.
        /// </param>
        public void Blend <TPixelSrc>(
            Configuration configuration,
            Span <TPixel> destination,
            ReadOnlySpan <TPixel> background,
            ReadOnlySpan <TPixelSrc> source,
            float amount)
            where TPixelSrc : struct, IPixel <TPixelSrc>
        {
            Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
            Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
            Guard.MustBeBetweenOrEqualTo(amount, 0, 1, nameof(amount));

            using (IMemoryOwner <Vector4> buffer =
                       configuration.MemoryAllocator.Allocate <Vector4>(destination.Length * 3))
            {
                Span <Vector4> destinationSpan = buffer.Slice(0, destination.Length);
                Span <Vector4> backgroundSpan  = buffer.Slice(destination.Length, destination.Length);
                Span <Vector4> sourceSpan      = buffer.Slice(destination.Length * 2, destination.Length);

                PixelOperations <TPixel> .Instance.ToScaledVector4(
                    configuration,
                    background.Slice(0, background.Length),
                    backgroundSpan);

                PixelOperations <TPixelSrc> .Instance.ToScaledVector4(
                    configuration,
                    source.Slice(0, background.Length),
                    sourceSpan);

                this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount);

                PixelOperations <TPixel> .Instance.FromScaledVector4(
                    configuration,
                    destinationSpan.Slice(0, background.Length),
                    destination);
            }
        }
Example #8
0
            /// <inheritdoc />
            public override void Blend(MemoryAllocator memoryManager, Span <TPixel> destination, Span <TPixel> background, Span <TPixel> source, Span <float> amount)
            {
                Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
                Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
                Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));

                using (IMemoryOwner <Vector4> buffer = memoryManager.Allocate <Vector4>(destination.Length * 3))
                {
                    Span <Vector4> destinationSpan = buffer.Slice(0, destination.Length);
                    Span <Vector4> backgroundSpan  = buffer.Slice(destination.Length, destination.Length);
                    Span <Vector4> sourceSpan      = buffer.Slice(destination.Length * 2, destination.Length);

                    PixelOperations <TPixel> .Instance.ToVector4(background, backgroundSpan, destination.Length);

                    PixelOperations <TPixel> .Instance.ToVector4(source, sourceSpan, destination.Length);

                    for (int i = 0; i < destination.Length; i++)
                    {
                        destinationSpan[i] = PorterDuffFunctions.Xor(backgroundSpan[i], sourceSpan[i], amount[i]);
                    }

                    PixelOperations <TPixel> .Instance.PackFromVector4(destinationSpan, destination, destination.Length);
                }
            }
Example #9
0
        public static void MemoryPool_byte_WrapSlice_start()
        {
            MemoryPool <byte> pool = MemoryPool <byte> .Shared;

            IMemoryOwner <byte> owner1 = pool.Rent(99);

            Assert.True(owner1.Memory.Length > 99);

            IMemoryOwner <byte> owner2 = owner1.Slice(23);

            Assert.Equal(owner1.Memory.Length - 23, owner2.Memory.Length);

            owner2.Dispose();
            Assert.Throws <ObjectDisposedException>(() => owner1.Memory.Length);
        }
Example #10
0
        /// <summary>
        /// Writes the 24bit color palette to the stream.
        /// </summary>
        /// <typeparam name="TPixel">The pixel format.</typeparam>
        /// <param name="stream">The <see cref="Stream"/> to write to.</param>
        /// <param name="pixels">The <see cref="Buffer2D{TPixel}"/> containing pixel data.</param>
        private void Write24Bit <TPixel>(Stream stream, Buffer2D <TPixel> pixels)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            int width = pixels.Width;
            int rowBytesWithoutPadding = width * 3;

            using IMemoryOwner <byte> row = this.AllocateRow(width, 3);
            Span <byte> rowSpan           = row.GetSpan();

            for (int y = pixels.Height - 1; y >= 0; y--)
            {
                Span <TPixel> pixelSpan = pixels.DangerousGetRowSpan(y);
                PixelOperations <TPixel> .Instance.ToBgr24Bytes(
                    this.configuration,
                    pixelSpan,
                    row.Slice(0, rowBytesWithoutPadding),
                    width);

                stream.Write(rowSpan);
            }
        }