public static unsafe void Copy <T>(BufferSpan <T> source, BufferSpan <T> destination, int count) where T : struct { DebugGuard.MustBeLessThanOrEqualTo(count, source.Length, nameof(count)); DebugGuard.MustBeLessThanOrEqualTo(count, destination.Length, nameof(count)); ref byte srcRef = ref Unsafe.As <T, byte>(ref source.DangerousGetPinnableReference());
/// <summary> /// Returns a reference to specified element of the span. /// </summary> /// <param name="index">The index</param> /// <returns>The reference to the specified element</returns> public ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { DebugGuard.MustBeLessThan(index, this.Length, nameof(index)); ref T startRef = ref this.DangerousGetPinnableReference();
/// <summary> /// Initializes a new instance of the <see cref="ImageMetaData"/> class /// by making a copy from other metadata. /// </summary> /// <param name="other"> /// The other <see cref="ImageMetaData"/> to create this instance from. /// </param> internal ImageMetaData(ImageMetaData other) { DebugGuard.NotNull(other, nameof(other)); this.HorizontalResolution = other.HorizontalResolution; this.VerticalResolution = other.VerticalResolution; this.Quality = other.Quality; this.FrameDelay = other.FrameDelay; this.DisposalMethod = other.DisposalMethod; this.RepeatCount = other.RepeatCount; foreach (ImageProperty property in other.Properties) { this.Properties.Add(new ImageProperty(property)); } if (other.ExifProfile != null) { this.ExifProfile = new ExifProfile(other.ExifProfile); } else { this.ExifProfile = null; } }
/// <summary> /// Initializes a new instance of the <see cref="ImageProperty"/> class /// by making a copy from another property. /// </summary> /// <param name="other"> /// The other <see cref="ImageProperty"/> to create this instance from. /// </param> internal ImageProperty(ImageProperty other) { DebugGuard.NotNull(other, nameof(other)); this.Name = other.Name; this.Value = other.Value; }
/// <summary> /// Initializes a new instance of the <see cref="ImageFrameMetaData"/> class /// by making a copy from other metadata. /// </summary> /// <param name="other"> /// The other <see cref="ImageFrameMetaData"/> to create this instance from. /// </param> internal ImageFrameMetaData(ImageFrameMetaData other) { DebugGuard.NotNull(other, nameof(other)); this.FrameDelay = other.FrameDelay; this.DisposalMethod = other.DisposalMethod; }
private static void GuardArrayAndPointer(T[] array, void *pointerToArray) { DebugGuard.NotNull(array, nameof(array)); DebugGuard.IsFalse( pointerToArray == (void *)0, nameof(pointerToArray), "pointerToArray should not be null pointer!"); }
public BufferPointer(T[] array, void *pointerToArray) { DebugGuard.NotNull(array, nameof(array)); this.Array = array; this.Offset = 0; this.PointerAtOffset = (IntPtr)pointerToArray; }
public BufferPointer(T[] array, void *pointerToArray, int offset) { DebugGuard.NotNull(array, nameof(array)); this.Array = array; this.Offset = offset; this.PointerAtOffset = (IntPtr)pointerToArray + (Unsafe.SizeOf <T>() * offset); }
/// <summary> /// Returns a reference to specified element of the buffer. /// </summary> /// <param name="index">The index</param> /// <returns>The reference to the specified element</returns> public ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { DebugGuard.MustBeLessThan(index, this.Length, nameof(index)); return(ref this.Array[index]); } }
/// <summary> /// SIMD optimized bulk implementation of <see cref="IPixel.PackFromVector4(Vector4)"/> /// that works only with `count` divisible by <see cref="Vector{UInt32}.Count"/>. /// </summary> /// <param name="sourceColors">The <see cref="BufferSpan{T}"/> to the source colors.</param> /// <param name="destVectors">The <see cref="BufferSpan{T}"/> to the dstination vectors.</param> /// <param name="count">The number of pixels to convert.</param> /// <remarks> /// Implementation adapted from: /// <see> /// <cref>http://stackoverflow.com/a/5362789</cref> /// </see> /// TODO: We can replace this implementation in the future using new Vector API-s: /// <see> /// <cref>https://github.com/dotnet/corefx/issues/15957</cref> /// </see> /// </remarks> internal static unsafe void ToVector4SimdAligned( BufferSpan <Color> sourceColors, BufferSpan <Vector4> destVectors, int count) { if (!Vector.IsHardwareAccelerated) { throw new InvalidOperationException( "Color.BulkOperations.ToVector4SimdAligned() should not be called when Vector.IsHardwareAccelerated == false!"); } int vecSize = Vector <uint> .Count; DebugGuard.IsTrue( count % vecSize == 0, nameof(count), "Argument 'count' should divisible by Vector<uint>.Count!"); Vector <float> bVec = new Vector <float>(256.0f / 255.0f); Vector <float> magicFloat = new Vector <float>(32768.0f); Vector <uint> magicInt = new Vector <uint>(1191182336); // reinterpreded value of 32768.0f Vector <uint> mask = new Vector <uint>(255); int unpackedRawCount = count * 4; uint *src = (uint *)sourceColors.PointerAtOffset; uint *srcEnd = src + count; using (PinnedBuffer <uint> tempBuf = new PinnedBuffer <uint>( unpackedRawCount + Vector <uint> .Count)) { uint * tPtr = (uint *)tempBuf.Pointer; uint[] temp = tempBuf.Array; float[] fTemp = Unsafe.As <float[]>(temp); UnpackedRGBA *dst = (UnpackedRGBA *)tPtr; for (; src < srcEnd; src++, dst++) { // This call is the bottleneck now: dst->Load(*src); } for (int i = 0; i < unpackedRawCount; i += vecSize) { Vector <uint> vi = new Vector <uint>(temp, i); vi &= mask; vi |= magicInt; Vector <float> vf = Vector.AsVectorSingle(vi); vf = (vf - magicFloat) * bVec; vf.CopyTo(fTemp, i); } BufferSpan.Copy <uint>(tempBuf, (BufferSpan <byte>)destVectors, unpackedRawCount); } }
public BufferSpan(T[] array, int start) { GuardArray(array); DebugGuard.MustBeLessThanOrEqualTo(start, array.Length, nameof(start)); this.Array = array; this.Length = array.Length - start; this.Start = start; }
public BufferSpan(T[] array, void *pointerToArray, int start) { GuardArrayAndPointer(array, pointerToArray); DebugGuard.MustBeLessThanOrEqualTo(start, array.Length, nameof(start)); this.Array = array; this.Length = array.Length - start; this.Start = start; this.PointerAtOffset = (IntPtr)pointerToArray + (Unsafe.SizeOf <T>() * start); }
/// <summary> /// Returns a reference to specified element of the span. /// </summary> /// <param name="index">The index</param> /// <returns>The reference to the specified element</returns> public ref T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { DebugGuard.MustBeLessThan(index, this.Length, nameof(index)); byte *ptr = (byte *)this.PointerAtOffset + BufferSpan.SizeOf <T>(index); return(ref Unsafe.AsRef <T>(ptr)); } }
public BufferSpan <T> Slice(int start) { DebugGuard.MustBeLessThan(start, this.Length, nameof(start)); BufferSpan <T> result = default(BufferSpan <T>); result.Array = this.Array; result.Start = this.Start + start; result.PointerAtOffset = this.PointerAtOffset + (Unsafe.SizeOf <T>() * start); result.Length = this.Length - start; return(result); }
public void Clear(int count) { DebugGuard.MustBeLessThanOrEqualTo(count, this.Length, nameof(count)); if (count < 256) { Unsafe.InitBlock((void *)this.PointerAtOffset, 0, BufferSpan.USizeOf <T>(count)); } else { System.Array.Clear(this.Array, this.Start, count); } }
/// <summary> /// Reads and returns the collection of EXIF values. /// </summary> /// <param name="data">The data.</param> /// <returns> /// The <see cref="Collection{ExifValue}"/>. /// </returns> public Collection <ExifValue> Read(Span <byte> data) { DebugGuard.NotNull(data, nameof(data)); var result = new Collection <ExifValue>(); this.exifData = data; if (this.GetString(4) == "Exif") { if (this.GetShort() != 0) { return(result); } this.startIndex = 6; } else { this.currentIndex = 0; } this.isLittleEndian = this.GetString(2) == "II"; if (this.GetShort() != 0x002A) { return(result); } uint ifdOffset = this.GetLong(); this.AddValues(result, ifdOffset); uint thumbnailOffset = this.GetLong(); this.GetThumbnail(thumbnailOffset); if (this.exifOffset != 0) { this.AddValues(result, this.exifOffset); } if (this.gpsOffset != 0) { this.AddValues(result, this.gpsOffset); } return(result); }
/// <summary> /// SIMD optimized bulk implementation of <see cref="IPixel.PackFromVector4(Vector4)"/> /// that works only with `count` divisible by <see cref="Vector{UInt32}.Count"/>. /// </summary> /// <param name="sourceColors">The <see cref="Span{T}"/> to the source colors.</param> /// <param name="destVectors">The <see cref="Span{T}"/> to the dstination vectors.</param> /// <param name="count">The number of pixels to convert.</param> /// <remarks> /// Implementation adapted from: /// <see> /// <cref>http://stackoverflow.com/a/5362789</cref> /// </see> /// TODO: We can replace this implementation in the future using new Vector API-s: /// <see> /// <cref>https://github.com/dotnet/corefx/issues/15957</cref> /// </see> /// </remarks> internal static void ToVector4SimdAligned(Span <Rgba32> sourceColors, Span <Vector4> destVectors, int count) { if (!Vector.IsHardwareAccelerated) { throw new InvalidOperationException( "Rgba32.PixelOperations.ToVector4SimdAligned() should not be called when Vector.IsHardwareAccelerated == false!"); } DebugGuard.IsTrue( count % Vector <uint> .Count == 0, nameof(count), "Argument 'count' should divisible by Vector<uint>.Count!"); Vector <float> bVec = new Vector <float>(256.0f / 255.0f); Vector <float> magicFloat = new Vector <float>(32768.0f); Vector <uint> magicInt = new Vector <uint>(1191182336); // reinterpreded value of 32768.0f Vector <uint> mask = new Vector <uint>(255); int unpackedRawCount = count * 4; ref uint sourceBase = ref Unsafe.As <Rgba32, uint>(ref sourceColors.DangerousGetPinnableReference());
/// <summary> /// Copies the properties from the other <see cref="IImageBase"/>. /// </summary> /// <param name="other"> /// The other <see cref="IImageBase"/> to copy the properties from. /// </param> protected void CopyProperties(IImageBase other) { DebugGuard.NotNull(other, nameof(other)); this.Configuration = other.Configuration; }
public static ref Rgb24 GetRgb24(this Span <byte> bytes, int offset) { DebugGuard.MustBeLessThan(offset + 2, bytes.Length, nameof(offset)); return(ref Unsafe.As <byte, Rgb24>(ref bytes[offset])); }