Exemplo n.º 1
0
 public void ToRgba32(ref Rgba32 dest)
 {
     dest.R = ColorNumerics.DownScaleFrom16BitTo8Bit(this.R);
     dest.G = ColorNumerics.DownScaleFrom16BitTo8Bit(this.G);
     dest.B = ColorNumerics.DownScaleFrom16BitTo8Bit(this.B);
     dest.A = byte.MaxValue;
 }
Exemplo n.º 2
0
 public Rgba64(Argb32 source)
 {
     this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
     this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
     this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
     this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
 }
Exemplo n.º 3
0
 public Rgba64(Bgr24 source)
 {
     this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
     this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
     this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
     this.A = ushort.MaxValue;
 }
Exemplo n.º 4
0
        /// <summary>
        /// Creates the quantized frame.
        /// </summary>
        /// <typeparam name="TPixel">The type of the pixel.</typeparam>
        /// <param name="options">The options.</param>
        /// <param name="image">The image.</param>
        public static IndexedImageFrame <TPixel> CreateQuantizedFrame <TPixel>(
            PngEncoderOptions options,
            Image <TPixel> image)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            if (options.ColorType != PngColorType.Palette)
            {
                return(null);
            }

            // Use the metadata to determine what quantization depth to use if no quantizer has been set.
            if (options.Quantizer is null)
            {
                byte bits      = (byte)options.BitDepth;
                var  maxColors = ColorNumerics.GetColorCountForBitDepth(bits);
                options.Quantizer = new WuQuantizer(new QuantizerOptions {
                    MaxColors = maxColors
                });
            }

            // Create quantized frame returning the palette and set the bit depth.
            using (IQuantizer <TPixel> frameQuantizer = options.Quantizer.CreatePixelSpecificQuantizer <TPixel>(image.GetConfiguration()))
            {
                ImageFrame <TPixel> frame = image.Frames.RootFrame;
                return(frameQuantizer.BuildPaletteAndQuantizeFrame(frame, frame.Bounds()));
            }
        }
Exemplo n.º 5
0
        public static int GetLuminance <TPixel>(TPixel sourcePixel)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            var vector = sourcePixel.ToVector4();

            return(ColorNumerics.GetBT709Luminance(ref vector, 256));
        }
Exemplo n.º 6
0
        public void FromL8(L8 source)
        {
            ushort rgb = ColorNumerics.UpscaleFrom8BitTo16Bit(source.PackedValue);

            this.R = rgb;
            this.G = rgb;
            this.B = rgb;
        }
Exemplo n.º 7
0
        public void FromLa16(La16 source)
        {
            ushort rgb = ColorNumerics.UpscaleFrom8BitTo16Bit(source.L);

            this.R = rgb;
            this.G = rgb;
            this.B = rgb;
        }
Exemplo n.º 8
0
        public void FromLa32(La32 source)
        {
            byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.L);

            this.R = rgb;
            this.G = rgb;
            this.B = rgb;
        }
Exemplo n.º 9
0
        public void FromL16(L16 source)
        {
            byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.PackedValue);

            this.R = rgb;
            this.G = rgb;
            this.B = rgb;
        }
Exemplo n.º 10
0
 private void RemovePixelsFromHistogram(ref Vector4 greyValuesBase, ref int histogramBase, int luminanceLevels, int length)
 {
     for (int idx = 0; idx < length; idx++)
     {
         int luminance = ColorNumerics.GetBT709Luminance(ref Unsafe.Add(ref greyValuesBase, idx), luminanceLevels);
         Unsafe.Add(ref histogramBase, luminance)--;
     }
 }
Exemplo n.º 11
0
        public void Encode_WithPngTransparentColorBehaviorClear_Works(PngColorType colorType)
        {
            // arrange
            var image   = new Image <Rgba32>(50, 50);
            var encoder = new PngEncoder()
            {
                TransparentColorMode = PngTransparentColorMode.Clear,
                ColorType            = colorType
            };
            Rgba32 rgba32 = Color.Blue;

            for (int y = 0; y < image.Height; y++)
            {
                System.Span <Rgba32> rowSpan = image.GetPixelRowSpan(y);

                // Half of the test image should be transparent.
                if (y > 25)
                {
                    rgba32.A = 0;
                }

                for (int x = 0; x < image.Width; x++)
                {
                    rowSpan[x].FromRgba32(rgba32);
                }
            }

            // act
            using var memStream = new MemoryStream();
            image.Save(memStream, encoder);

            // assert
            memStream.Position = 0;
            using var actual   = Image.Load <Rgba32>(memStream);
            Rgba32 expectedColor = Color.Blue;

            if (colorType == PngColorType.Grayscale || colorType == PngColorType.GrayscaleWithAlpha)
            {
                var luminance = ColorNumerics.Get8BitBT709Luminance(expectedColor.R, expectedColor.G, expectedColor.B);
                expectedColor = new Rgba32(luminance, luminance, luminance);
            }

            for (int y = 0; y < actual.Height; y++)
            {
                System.Span <Rgba32> rowSpan = actual.GetPixelRowSpan(y);

                if (y > 25)
                {
                    expectedColor = Color.Transparent;
                }

                for (int x = 0; x < actual.Width; x++)
                {
                    Assert.Equal(expectedColor, rowSpan[x]);
                }
            }
        }
Exemplo n.º 12
0
            public void Invoke(int y, Span <Vector4> span)
            {
                Span <TPixel> rowSpan = this.source.GetPixelRowSpan(y).Slice(this.startX, span.Length);

                PixelOperations <TPixel> .Instance.ToVector4(this.configuration, rowSpan, span, PixelConversionModifiers.Scale);

                ColorNumerics.Transform(span, ref Unsafe.AsRef(this.matrix));

                PixelOperations <TPixel> .Instance.FromVector4Destructive(this.configuration, span, rowSpan, PixelConversionModifiers.Scale);
            }
Exemplo n.º 13
0
        public void GetBT709Luminance_WithVector4(float x, float y, float z, int luminanceLevels, int expected)
        {
            // arrange
            var vector = new Vector4(x, y, z, 0.0f);

            // act
            int actual = ColorNumerics.GetBT709Luminance(ref vector, luminanceLevels);

            // assert
            Assert.Equal(expected, actual);
        }
Exemplo n.º 14
0
        public void L8_FromRgba32(byte rgb)
        {
            // Arrange
            L8   gray     = default;
            byte expected = ColorNumerics.Get8BitBT709Luminance(rgb, rgb, rgb);

            // Act
            gray.FromRgba32(new Rgba32(rgb, rgb, rgb));
            byte actual = gray.PackedValue;

            // Assert
            Assert.Equal(expected, actual);
        }
Exemplo n.º 15
0
        public void La16_FromRgba32(byte rgb)
        {
            // Arrange
            La16 gray     = default;
            byte expected = ColorNumerics.Get8BitBT709Luminance(rgb, rgb, rgb);

            // Act
            gray.FromRgba32(new Rgba32(rgb, rgb, rgb));
            byte actual = gray.L;

            // Assert
            Assert.Equal(expected, actual);
            Assert.Equal(255, gray.A);
        }
Exemplo n.º 16
0
        public void L16_FromRgba32()
        {
            // Arrange
            L16        gray      = default;
            const byte rgb       = 128;
            ushort     scaledRgb = ColorNumerics.UpscaleFrom8BitTo16Bit(rgb);
            ushort     expected  = ColorNumerics.Get16BitBT709Luminance(scaledRgb, scaledRgb, scaledRgb);

            // Act
            gray.FromRgba32(new Rgba32(rgb, rgb, rgb));
            ushort actual = gray.PackedValue;

            // Assert
            Assert.Equal(expected, actual);
        }
Exemplo n.º 17
0
        public OctreeQuantizer(Configuration configuration, QuantizerOptions options)
        {
            Guard.NotNull(configuration, nameof(configuration));
            Guard.NotNull(options, nameof(options));

            this.Configuration = configuration;
            this.Options       = options;

            this.maxColors    = this.Options.MaxColors;
            this.octree       = new Octree(Numerics.Clamp(ColorNumerics.GetBitsNeededForColorDepth(this.maxColors), 1, 8));
            this.paletteOwner = configuration.MemoryAllocator.Allocate <TPixel>(this.maxColors, AllocationOptions.Clean);
            this.palette      = default;
            this.pixelMap     = default;
            this.isDithering  = !(this.Options.Dither is null);
            this.isDisposed   = false;
        }
Exemplo n.º 18
0
        private void EncodeLocal <TPixel>(Image <TPixel> image, IndexedImageFrame <TPixel> quantized, Stream stream)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            ImageFrame <TPixel> previousFrame = null;
            GifFrameMetadata    previousMeta  = null;

            for (int i = 0; i < image.Frames.Count; i++)
            {
                ImageFrame <TPixel> frame         = image.Frames[i];
                ImageFrameMetadata  metadata      = frame.Metadata;
                GifFrameMetadata    frameMetadata = metadata.GetGifMetadata();
                if (quantized is null)
                {
                    // Allow each frame to be encoded at whatever color depth the frame designates if set.
                    if (previousFrame != null && previousMeta.ColorTableLength != frameMetadata.ColorTableLength &&
                        frameMetadata.ColorTableLength > 0)
                    {
                        var options = new QuantizerOptions
                        {
                            Dither      = this.quantizer.Options.Dither,
                            DitherScale = this.quantizer.Options.DitherScale,
                            MaxColors   = frameMetadata.ColorTableLength
                        };

                        using IQuantizer <TPixel> frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer <TPixel>(this.configuration, options);
                        quantized = frameQuantizer.BuildPaletteAndQuantizeFrame(frame, frame.Bounds());
                    }
                    else
                    {
                        using IQuantizer <TPixel> frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer <TPixel>(this.configuration);
                        quantized = frameQuantizer.BuildPaletteAndQuantizeFrame(frame, frame.Bounds());
                    }
                }

                this.bitDepth = ColorNumerics.GetBitsNeededForColorDepth(quantized.Palette.Length);
                this.WriteGraphicalControlExtension(frameMetadata, this.GetTransparentIndex(quantized), stream);
                this.WriteImageDescriptor(frame, true, stream);
                this.WriteColorTable(quantized, stream);
                this.WriteImageData(quantized, stream);

                quantized.Dispose();
                quantized     = null; // So next frame can regenerate it
                previousFrame = frame;
                previousMeta  = frameMetadata;
            }
        }
Exemplo n.º 19
0
        public void La32_ToRgba32(ushort input)
        {
            // Arrange
            ushort expected = ColorNumerics.DownScaleFrom16BitTo8Bit(input);
            var    gray     = new La32(input, ushort.MaxValue);

            // Act
            Rgba32 actual = default;

            gray.ToRgba32(ref actual);

            // Assert
            Assert.Equal(expected, actual.R);
            Assert.Equal(expected, actual.G);
            Assert.Equal(expected, actual.B);
            Assert.Equal(byte.MaxValue, actual.A);
        }
Exemplo n.º 20
0
        /// <summary>
        /// Calculates the bit depth value.
        /// </summary>
        /// <typeparam name="TPixel">The type of the pixel.</typeparam>
        /// <param name="options">The options.</param>
        /// <param name="quantizedFrame">The quantized frame.</param>
        public static byte CalculateBitDepth <TPixel>(
            PngEncoderOptions options,
            IndexedImageFrame <TPixel> quantizedFrame)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            byte bitDepth;

            if (options.ColorType == PngColorType.Palette)
            {
                byte quantizedBits = (byte)Numerics.Clamp(ColorNumerics.GetBitsNeededForColorDepth(quantizedFrame.Palette.Length), 1, 8);
                byte bits          = Math.Max((byte)options.BitDepth, quantizedBits);

                // Png only supports in four pixel depths: 1, 2, 4, and 8 bits when using the PLTE chunk
                // We check again for the bit depth as the bit depth of the color palette from a given quantizer might not
                // be within the acceptable range.
                if (bits == 3)
                {
                    bits = 4;
                }
                else if (bits >= 5 && bits <= 7)
                {
                    bits = 8;
                }

                bitDepth = bits;
            }
            else
            {
                bitDepth = (byte)options.BitDepth;
            }

            if (Array.IndexOf(PngConstants.ColorTypes[options.ColorType.Value], bitDepth) == -1)
            {
                throw new NotSupportedException("Bit depth is not supported or not valid.");
            }

            return(bitDepth);
        }
Exemplo n.º 21
0
 public void FromRgba64(Rgba64 source)
 {
     this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
     this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
     this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
 }
Exemplo n.º 22
0
 public void FromArgb32(Argb32 source)
 {
     this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
     this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
     this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
 }
Exemplo n.º 23
0
 public void FromRgb24(Rgb24 source)
 {
     this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
     this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
     this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
 }
Exemplo n.º 24
0
        /// <summary>
        /// Encodes the image to the specified stream from the <see cref="Image{TPixel}"/>.
        /// </summary>
        /// <typeparam name="TPixel">The pixel format.</typeparam>
        /// <param name="image">The <see cref="Image{TPixel}"/> to encode from.</param>
        /// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param>
        /// <param name="cancellationToken">The token to request cancellation.</param>
        public void Encode <TPixel>(Image <TPixel> image, Stream stream, CancellationToken cancellationToken)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            Guard.NotNull(image, nameof(image));
            Guard.NotNull(stream, nameof(stream));

            ImageMetadata metadata    = image.Metadata;
            GifMetadata   gifMetadata = metadata.GetGifMetadata();

            this.colorTableMode ??= gifMetadata.ColorTableMode;
            bool useGlobalTable = this.colorTableMode == GifColorTableMode.Global;

            // Quantize the image returning a palette.
            IndexedImageFrame <TPixel> quantized;

            using (IQuantizer <TPixel> frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer <TPixel>(this.configuration))
            {
                if (useGlobalTable)
                {
                    frameQuantizer.BuildPalette(this.pixelSamplingStrategy, image);
                    quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds());
                }
                else
                {
                    quantized = frameQuantizer.BuildPaletteAndQuantizeFrame(image.Frames.RootFrame, image.Bounds());
                }
            }

            // Get the number of bits.
            this.bitDepth = ColorNumerics.GetBitsNeededForColorDepth(quantized.Palette.Length);

            // Write the header.
            this.WriteHeader(stream);

            // Write the LSD.
            int index = this.GetTransparentIndex(quantized);

            this.WriteLogicalScreenDescriptor(metadata, image.Width, image.Height, index, useGlobalTable, stream);

            if (useGlobalTable)
            {
                this.WriteColorTable(quantized, stream);
            }

            // Write the comments.
            this.WriteComments(gifMetadata, stream);

            // Write application extension to allow additional frames.
            if (image.Frames.Count > 1)
            {
                this.WriteApplicationExtension(stream, gifMetadata.RepeatCount);
            }

            if (useGlobalTable)
            {
                this.EncodeGlobal(image, quantized, index, stream);
            }
            else
            {
                this.EncodeLocal(image, quantized, stream);
            }

            // Clean up.
            quantized.Dispose();

            // TODO: Write extension etc
            stream.WriteByte(GifConstants.EndIntroducer);
        }