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); } }
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); }
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); } }
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)); }
/// <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); } }
/// <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); } }
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); }
/// <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); } }