Beispiel #1
0
        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());
Beispiel #2
0
 /// <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();
Beispiel #3
0
        /// <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;
            }
        }
Beispiel #4
0
        /// <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;
        }
Beispiel #5
0
        /// <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;
        }
Beispiel #6
0
 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!");
 }
Beispiel #7
0
        public BufferPointer(T[] array, void *pointerToArray)
        {
            DebugGuard.NotNull(array, nameof(array));

            this.Array           = array;
            this.Offset          = 0;
            this.PointerAtOffset = (IntPtr)pointerToArray;
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
 /// <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]);
     }
 }
Beispiel #10
0
            /// <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);
                }
            }
Beispiel #11
0
        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;
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        /// <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));
            }
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        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);
            }
        }
Beispiel #16
0
        /// <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);
        }
Beispiel #17
0
            /// <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());
Beispiel #18
0
        /// <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;
        }
Beispiel #19
0
        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]));
        }