public void Clear(int count) { if (count < 256) { Unsafe.InitBlock((void *)this.PointerAtOffset, 0, BufferPointer.USizeOf <T>(count)); } else { System.Array.Clear(this.Array, this.Offset, count); } }
/// <summary> /// Bulk version of <see cref="IPixel.ToZyxBytes(byte[], int)"/>. /// </summary> /// <param name="sourceColors">The <see cref="BufferPointer{T}"/> to the source colors.</param> /// <param name="destBytes">The <see cref="BufferPointer{T}"/> to the destination bytes.</param> /// <param name="count">The number of pixels to convert.</param> internal virtual void ToZyxBytes(BufferPointer <TColor> sourceColors, BufferPointer <byte> destBytes, int count) { byte *sp = (byte *)sourceColors; byte[] dest = destBytes.Array; for (int i = destBytes.Offset; i < destBytes.Offset + (count * 3); i += 3) { TColor c = Unsafe.Read <TColor>(sp); c.ToZyxBytes(dest, i); sp += ColorSize; } }
/// <inheritdoc /> internal override unsafe void PackFromZyxwBytes(BufferPointer <byte> sourceBytes, BufferPointer <Color> destColors, int count) { byte *source = (byte *)sourceBytes; byte *destination = (byte *)destColors; for (int x = 0; x < count; x++) { Unsafe.Write(destination, (uint)(*(source + 2) << 0 | *(source + 1) << 8 | *source << 16 | *(source + 3) << 24)); source += 4; destination += 4; } }
/// <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="BufferPointer{T}"/> to the source colors.</param> /// <param name="destVectors">The <see cref="BufferPointer{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( BufferPointer <Color> sourceColors, BufferPointer <Vector4> destVectors, int count) { 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); } BufferPointer.Copy <uint>(tempBuf, (BufferPointer <byte>)destVectors, unpackedRawCount); } }
public static unsafe void Copy <T>(BufferPointer <byte> source, BufferPointer <T> destination, int countInDest) where T : struct { int byteCount = SizeOf <T>(countInDest); if (byteCount > (int)ByteCountThreshold) { Marshal.Copy(source.Array, source.Offset, destination.PointerAtOffset, byteCount); } else { Unsafe.CopyBlock((void *)destination.PointerAtOffset, (void *)source.PointerAtOffset, (uint)byteCount); } }
/// <inheritdoc /> internal override unsafe void ToZyxBytes(BufferPointer <Color> sourceColors, BufferPointer <byte> destBytes, int count) { byte *source = (byte *)sourceColors; byte *destination = (byte *)destBytes; for (int x = 0; x < count; x++) { *destination = *(source + 2); *(destination + 1) = *(source + 1); *(destination + 2) = *(source + 0); source += 4; destination += 3; } }
/// <summary> /// Bulk version of <see cref="IPixel.ToVector4()"/>. /// </summary> /// <param name="sourceColors">The <see cref="BufferPointer{T}"/> to the source colors.</param> /// <param name="destVectors">The <see cref="BufferPointer{T}"/> to the destination vectors.</param> /// <param name="count">The number of pixels to convert.</param> internal virtual void ToVector4( BufferPointer <TColor> sourceColors, BufferPointer <Vector4> destVectors, int count) { byte * sp = (byte *)sourceColors; Vector4 *dp = (Vector4 *)destVectors.PointerAtOffset; for (int i = 0; i < count; i++) { TColor c = Unsafe.Read <TColor>(sp); *dp = c.ToVector4(); sp += ColorSize; dp++; } }
/// <summary> /// Bulk version of <see cref="IPixel.PackFromBytes(byte, byte, byte, byte)"/> that converts data in <see cref="ComponentOrder.Xyz"/>. /// </summary> /// <param name="sourceBytes">The <see cref="BufferPointer{T}"/> to the source bytes.</param> /// <param name="destColors">The <see cref="BufferPointer{T}"/> to the destination colors.</param> /// <param name="count">The number of pixels to convert.</param> internal virtual void PackFromXyzBytes( BufferPointer <byte> sourceBytes, BufferPointer <TColor> destColors, int count) { byte *sp = (byte *)sourceBytes; byte *dp = (byte *)destColors.PointerAtOffset; for (int i = 0; i < count; i++) { TColor c = default(TColor); c.PackFromBytes(sp[0], sp[1], sp[2], 255); Unsafe.Write(dp, c); sp += 3; dp += ColorSize; } }
/// <summary> /// Bulk version of <see cref="IPixel.PackFromVector4(Vector4)"/> /// </summary> /// <param name="sourceVectors">The <see cref="BufferPointer{T}"/> to the source vectors.</param> /// <param name="destColors">The <see cref="BufferPointer{T}"/> to the destination colors.</param> /// <param name="count">The number of pixels to convert.</param> internal virtual void PackFromVector4( BufferPointer <Vector4> sourceVectors, BufferPointer <TColor> destColors, int count) { Vector4 *sp = (Vector4 *)sourceVectors.PointerAtOffset; byte * dp = (byte *)destColors; for (int i = 0; i < count; i++) { Vector4 v = Unsafe.Read <Vector4>(sp); TColor c = default(TColor); c.PackFromVector4(v); Unsafe.Write(dp, c); sp++; dp += ColorSize; } }
public static unsafe void Copy <T>(BufferPointer <byte> source, BufferPointer <T> destination, int countInDest) where T : struct { Unsafe.CopyBlock((void *)source.PointerAtOffset, (void *)destination.PointerAtOffset, USizeOf <T>(countInDest)); }
public static void Copy <T>(BufferPointer <T> source, BufferPointer <byte> destination, int countInSource) where T : struct { CopyImpl(source, destination, countInSource); }
/// <inheritdoc /> internal override void ToXyzwBytes(BufferPointer <Color> sourceColors, BufferPointer <byte> destBytes, int count) { BufferPointer.Copy(sourceColors, destBytes, count); }
/// <inheritdoc /> internal override void PackFromXyzwBytes(BufferPointer <byte> sourceBytes, BufferPointer <Color> destColors, int count) { BufferPointer.Copy(sourceBytes, destColors, count); }