/// <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; } } }
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); }
/// <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; } } } }
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); }
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); }
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; }
/// <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; }
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; }
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);
/// <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]); } }
/// <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]); }
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; }
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); }
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; }
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)); }
public void MustBeGreaterThanOrEqualTo_IsGreaterOrEqual_ThrowsNoException(int value, int min) { DebugGuard.MustBeGreaterThanOrEqualTo(value, min, "myParamName"); }