internal static void FromVector4 <TPixel>(
                Configuration configuration,
                PixelOperations <TPixel> pixelOperations,
                ReadOnlySpan <Vector4> sourceVectors,
                Span <TPixel> destPixels,
                bool scaled)
                where TPixel : struct, IPixel <TPixel>
            {
                Guard.NotNull(configuration, nameof(configuration));
                Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels));

                int count = sourceVectors.Length;

                // Not worth for small buffers:
                if (count < Vector4ConversionThreshold)
                {
                    FromVector4Fallback(sourceVectors, destPixels, scaled);

                    return;
                }

                // For the opposite direction it's not easy to implement the trick used in RunRgba32CompatibleToVector4Conversion,
                // so let's allocate a temporary buffer as usually:
                using (IMemoryOwner <Rgba32> tempBuffer = configuration.MemoryAllocator.Allocate <Rgba32>(count))
                {
                    Span <Rgba32> tempSpan = tempBuffer.Memory.Span;

                    SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(
                        MemoryMarshal.Cast <Vector4, float>(sourceVectors),
                        MemoryMarshal.Cast <Rgba32, byte>(tempSpan));

                    pixelOperations.FromRgba32(configuration, tempSpan, destPixels);
                }
            }
Example #2
0
            /// <inheritdoc />
            internal override void PackFromVector4(ReadOnlySpan <Vector4> sourceVectors, Span <Rgba32> destinationColors, int count)
            {
                GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count);

                sourceVectors     = sourceVectors.Slice(0, count);
                destinationColors = destinationColors.Slice(0, count);

                SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(
                    MemoryMarshal.Cast <Vector4, float>(sourceVectors),
                    MemoryMarshal.Cast <Rgba32, byte>(destinationColors));
            }
Example #3
0
            /// <inheritdoc />
            internal override void FromVector4(
                Configuration configuration,
                ReadOnlySpan <Vector4> sourceVectors,
                Span <Rgba32> destPixels)
            {
                Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels));

                destPixels = destPixels.Slice(0, sourceVectors.Length);

                SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(
                    MemoryMarshal.Cast <Vector4, float>(sourceVectors),
                    MemoryMarshal.Cast <Rgba32, byte>(destPixels));
            }
Example #4
0
            /// <inheritdoc />
            internal override void FromVector4Destructive(
                Configuration configuration,
                Span <Vector4> sourceVectors,
                Span <Rgba32> destPixels,
                PixelConversionModifiers modifiers)
            {
                Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels));

                destPixels = destPixels.Slice(0, sourceVectors.Length);
                Vector4Converters.ApplyBackwardConversionModifiers(sourceVectors, modifiers);
                SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(
                    MemoryMarshal.Cast <Vector4, float>(sourceVectors),
                    MemoryMarshal.Cast <Rgba32, byte>(destPixels));
            }
Example #5
0
        public void BulkConvertNormalizedFloatToByteClampOverflows(int count)
        {
            TestImpl_BulkConvertNormalizedFloatToByteClampOverflows(count, (s, d) => SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(s.Span, d.Span));

            // For small values, let's stress test the implementation a bit:
            if (count > 0 && count < 10)
            {
                for (int i = 0; i < 20; i++)
                {
                    TestImpl_BulkConvertNormalizedFloatToByteClampOverflows(
                        count,
                        (s, d) => SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(s.Span, d.Span),
                        i + 42);
                }
            }
        }
Example #6
0
        public void BulkConvertNormalizedFloatToByteClampOverflows(int seed, int count)
        {
            if (this.SkipOnNonAvx2())
            {
                return;
            }

            float[] orig = new Random(seed).GenerateRandomRoundedFloatArray(count, -50, 444);
            float[] normalized = orig.Select(f => f / 255f).ToArray();

            byte[] dest = new byte[count];

            SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(normalized, dest);

            byte[] expected = orig.Select(f => (byte)Clamp255(f)).ToArray();

            Assert.Equal(expected, dest);
        }
            internal static void FromVector4 <TPixel>(
                Configuration configuration,
                PixelOperations <TPixel> pixelOperations,
                Span <Vector4> sourceVectors,
                Span <TPixel> destPixels,
                PixelConversionModifiers modifiers)
                where TPixel : unmanaged, IPixel <TPixel>
            {
                Guard.NotNull(configuration, nameof(configuration));
                Guard.DestinationShouldNotBeTooShort(sourceVectors, destPixels, nameof(destPixels));

                int count = sourceVectors.Length;

                // Not worth for small buffers:
                if (count < Vector4ConversionThreshold)
                {
                    Default.UnsafeFromVector4(sourceVectors, destPixels, modifiers);

                    return;
                }

                // TODO: Investigate optimized 1-pass approach!
                ApplyBackwardConversionModifiers(sourceVectors, modifiers);

                // For the opposite direction it's not easy to implement the trick used in RunRgba32CompatibleToVector4Conversion,
                // so let's allocate a temporary buffer as usually:
                using (IMemoryOwner <Rgba32> tempBuffer = configuration.MemoryAllocator.Allocate <Rgba32>(count))
                {
                    Span <Rgba32> tempSpan = tempBuffer.Memory.Span;

                    SimdUtils.BulkConvertNormalizedFloatToByteClampOverflows(
                        MemoryMarshal.Cast <Vector4, float>(sourceVectors),
                        MemoryMarshal.Cast <Rgba32, byte>(tempSpan));

                    pixelOperations.FromRgba32(configuration, tempSpan, destPixels);
                }
            }