diff --git a/src/ImageSharp/Formats/Png/PngEncoderOptionsHelpers.cs b/src/ImageSharp/Formats/Png/PngEncoderOptionsHelpers.cs
index a5a45a684d..6196792480 100644
--- a/src/ImageSharp/Formats/Png/PngEncoderOptionsHelpers.cs
+++ b/src/ImageSharp/Formats/Png/PngEncoderOptionsHelpers.cs
@@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.Formats.Png
internal static class PngEncoderOptionsHelpers
{
///
- /// Adjusts the options.
+ /// Adjusts the options based upon the given metadata.
///
/// The options.
/// The PNG metadata.
@@ -28,12 +28,12 @@ namespace SixLabors.ImageSharp.Formats.Png
where TPixel : struct, IPixel
{
// Always take the encoder options over the metadata values.
- options.Gamma = options.Gamma ?? pngMetadata.Gamma;
+ options.Gamma ??= pngMetadata.Gamma;
- options.ColorType = options.ColorType ?? SuggestColorType() ?? pngMetadata.ColorType;
- options.BitDepth = options.BitDepth ?? SuggestBitDepth() ?? pngMetadata.BitDepth;
+ options.ColorType ??= SuggestColorType() ?? pngMetadata.ColorType;
+ options.BitDepth ??= SuggestBitDepth() ?? pngMetadata.BitDepth;
- options.InterlaceMethod = options.InterlaceMethod ?? pngMetadata.InterlaceMethod;
+ options.InterlaceMethod ??= pngMetadata.InterlaceMethod;
use16Bit = options.BitDepth == PngBitDepth.Bit16;
bytesPerPixel = CalculateBytesPerPixel(options.ColorType, use16Bit);
@@ -132,100 +132,68 @@ namespace SixLabors.ImageSharp.Formats.Png
/// Bytes per pixel.
private static int CalculateBytesPerPixel(PngColorType? pngColorType, bool use16Bit)
{
- switch (pngColorType)
+ return pngColorType switch
{
- case PngColorType.Grayscale:
- return use16Bit ? 2 : 1;
-
- case PngColorType.GrayscaleWithAlpha:
- return use16Bit ? 4 : 2;
-
- case PngColorType.Palette:
- return 1;
-
- case PngColorType.Rgb:
- return use16Bit ? 6 : 3;
+ PngColorType.Grayscale => use16Bit ? 2 : 1,
+ PngColorType.GrayscaleWithAlpha => use16Bit ? 4 : 2,
+ PngColorType.Palette => 1,
+ PngColorType.Rgb => use16Bit ? 6 : 3,
// PngColorType.RgbWithAlpha
- default:
- return use16Bit ? 8 : 4;
- }
+ _ => use16Bit ? 8 : 4,
+ };
}
///
- /// Comes up with the appropriate PngColorType for some kinds of
- /// IPixel. This is not exhaustive because not all options have
- /// reasonable defaults
+ /// Returns a suggested for the given
+ /// This is not exhaustive but covers many common pixel formats.
///
private static PngColorType? SuggestColorType()
- where TPixel : struct, IPixel
+ where TPixel : struct, IPixel
{
- Type tPixel = typeof(TPixel);
-
- if (tPixel == typeof(Alpha8))
- {
- return PngColorType.GrayscaleWithAlpha;
- }
-
- if (tPixel == typeof(Argb32))
- {
- return PngColorType.RgbWithAlpha;
- }
-
- if (tPixel == typeof(Rgb24))
- {
- return PngColorType.Rgb;
- }
-
- if (tPixel == typeof(Gray16))
- {
- return PngColorType.Grayscale;
- }
-
- if (tPixel == typeof(Gray8))
- {
- return PngColorType.Grayscale;
- }
-
- return default;
+ return typeof(TPixel) switch
+ {
+ Type t when t == typeof(A8) => PngColorType.GrayscaleWithAlpha,
+ Type t when t == typeof(Argb32) => PngColorType.RgbWithAlpha,
+ Type t when t == typeof(Bgr24) => PngColorType.Rgb,
+ Type t when t == typeof(Bgra32) => PngColorType.RgbWithAlpha,
+ Type t when t == typeof(L8) => PngColorType.Grayscale,
+ Type t when t == typeof(L16) => PngColorType.Grayscale,
+ Type t when t == typeof(La16) => PngColorType.GrayscaleWithAlpha,
+ Type t when t == typeof(La32) => PngColorType.GrayscaleWithAlpha,
+ Type t when t == typeof(Rgb24) => PngColorType.Rgb,
+ Type t when t == typeof(Rgba32) => PngColorType.RgbWithAlpha,
+ Type t when t == typeof(Rgb48) => PngColorType.Rgb,
+ Type t when t == typeof(Rgba64) => PngColorType.RgbWithAlpha,
+ Type t when t == typeof(RgbaVector) => PngColorType.RgbWithAlpha,
+ _ => default(PngColorType?)
+ };
}
///
- /// Comes up with the appropriate PngBitDepth for some kinds of
- /// IPixel. This is not exhaustive because not all options have
- /// reasonable defaults
+ /// Returns a suggested for the given
+ /// This is not exhaustive but covers many common pixel formats.
///
private static PngBitDepth? SuggestBitDepth()
- where TPixel : struct, IPixel
+ where TPixel : struct, IPixel
{
- Type tPixel = typeof(TPixel);
-
- if (tPixel == typeof(Alpha8))
- {
- return PngBitDepth.Bit8;
- }
-
- if (tPixel == typeof(Argb32))
- {
- return PngBitDepth.Bit8;
- }
-
- if (tPixel == typeof(Rgb24))
- {
- return PngBitDepth.Bit8;
- }
-
- if (tPixel == typeof(Gray16))
- {
- return PngBitDepth.Bit16;
- }
-
- if (tPixel == typeof(Gray8))
- {
- return PngBitDepth.Bit8;
- }
-
- return default;
+ return typeof(TPixel) switch
+ {
+ Type t when t == typeof(A8) => PngBitDepth.Bit8,
+ Type t when t == typeof(Argb32) => PngBitDepth.Bit8,
+ Type t when t == typeof(Bgr24) => PngBitDepth.Bit8,
+ Type t when t == typeof(Bgra32) => PngBitDepth.Bit8,
+ Type t when t == typeof(L8) => PngBitDepth.Bit8,
+ Type t when t == typeof(L16) => PngBitDepth.Bit16,
+ Type t when t == typeof(La16) => PngBitDepth.Bit8,
+ Type t when t == typeof(La32) => PngBitDepth.Bit16,
+ Type t when t == typeof(Rgb24) => PngBitDepth.Bit8,
+ Type t when t == typeof(Rgba32) => PngBitDepth.Bit8,
+ Type t when t == typeof(Rgb48) => PngBitDepth.Bit16,
+ Type t when t == typeof(Rgba64) => PngBitDepth.Bit16,
+ Type t when t == typeof(RgbaVector) => PngBitDepth.Bit16,
+ _ => default(PngBitDepth?)
+ };
}
}
}
diff --git a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
index cacb3e42fe..1fa131c914 100644
--- a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
@@ -202,46 +202,51 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
}
[Theory]
- // does the following make sense? Or is it supposed to encode a 16bpp with two 8bit channels?
- [WithBlankImages(1, 1, PixelTypes.Alpha8, PngColorType.GrayscaleWithAlpha, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.A8, PngColorType.GrayscaleWithAlpha, PngBitDepth.Bit8)]
[WithBlankImages(1, 1, PixelTypes.Argb32, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
- // [WithBlankImages(1, 1, PixelTypes.Bgr565, Can't reasonably be inferred)]
- // [WithBlankImages(1, 1, PixelTypes.Bgra4444, Can't reasonably be inferred)]
- // [WithBlankImages(1, 1, PixelTypes.Byte4, I'm not sure)]
- // [WithBlankImages(1, 1, PixelTypes.HalfSingle, I'm not sure)]
- // [WithBlankImages(1, 1, PixelTypes.HalfVector2, I'm not sure)]
- // [WithBlankImages(1, 1, PixelTypes.HalfVector4, I'm not sure)]
- // [WithBlankImages(1, 1, PixelTypes.NormalizedByte2, I'm not sure)]
- // [WithBlankImages(1, 1, PixelTypes.NormalizedByte4, I'm not sure)]
- // [WithBlankImages(1, 1, PixelTypes.NormalizedShort4, I'm not sure)]
- // [WithBlankImages(1, 1, PixelTypes.Rg32, I'm not sure)]
- // [WithBlankImages(1, 1, PixelTypes.Rgba1010102, I'm not sure)]
- // [WithBlankImages(1, 1, PixelTypes.Rgba32, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
- // [WithBlankImages(1, 1, PixelTypes.Rgba64, PngColorType.RgbWithAlpha, PngBitDepth.Bit16)]
- // [WithBlankImages(1, 1, PixelTypes.RgbaVector, I'm not sure)]
- // [WithBlankImages(1, 1, PixelTypes.Short2, I'm not sure)]
- // [WithBlankImages(1, 1, PixelTypes.Short4, I'm not sure)]
+ [WithBlankImages(1, 1, PixelTypes.Bgr565, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.Bgra4444, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.Byte4, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.HalfSingle, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.HalfVector2, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.HalfVector4, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.NormalizedByte2, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.NormalizedByte4, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.NormalizedShort4, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.Rg32, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.Rgba1010102, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.Rgba32, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.RgbaVector, PngColorType.RgbWithAlpha, PngBitDepth.Bit16)]
+ [WithBlankImages(1, 1, PixelTypes.Short2, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.Short4, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
[WithBlankImages(1, 1, PixelTypes.Rgb24, PngColorType.Rgb, PngBitDepth.Bit8)]
- // [WithBlankImages(1, 1, PixelTypes.Bgr24, I'm not sure)]
- // [WithBlankImages(1, 1, PixelTypes.Bgra32, I'm not sure)]
+ [WithBlankImages(1, 1, PixelTypes.Bgr24, PngColorType.Rgb, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.Bgra32, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
[WithBlankImages(1, 1, PixelTypes.Rgb48, PngColorType.Rgb, PngBitDepth.Bit16)]
- // [WithBlankImages(1, 1, PixelTypes.Bgra5551, I'm not sure)]
- [WithBlankImages(1, 1, PixelTypes.Gray8, PngColorType.Grayscale, PngBitDepth.Bit8)]
- [WithBlankImages(1, 1, PixelTypes.Gray16, PngColorType.Grayscale, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.Rgba64, PngColorType.RgbWithAlpha, PngBitDepth.Bit16)]
+ [WithBlankImages(1, 1, PixelTypes.Bgra5551, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.L8, PngColorType.Grayscale, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.L16, PngColorType.Grayscale, PngBitDepth.Bit16)]
+ [WithBlankImages(1, 1, PixelTypes.La16, PngColorType.GrayscaleWithAlpha, PngBitDepth.Bit8)]
+ [WithBlankImages(1, 1, PixelTypes.La32, PngColorType.GrayscaleWithAlpha, PngBitDepth.Bit16)]
public void InfersColorTypeAndBitDepth(TestImageProvider provider, PngColorType pngColorType, PngBitDepth pngBitDepth)
where TPixel : struct, IPixel
{
- Stream stream = new MemoryStream();
- PngEncoder encoder = new PngEncoder();
- encoder.Encode(provider.GetImage(), stream);
+ using (Stream stream = new MemoryStream())
+ {
+ var encoder = new PngEncoder();
+ encoder.Encode(provider.GetImage(), stream);
- stream.Seek(0, SeekOrigin.Begin);
+ stream.Seek(0, SeekOrigin.Begin);
- PngDecoder decoder = new PngDecoder();
+ var decoder = new PngDecoder();
- Image image = decoder.Decode(Configuration.Default, stream);
+ Image image = decoder.Decode(Configuration.Default, stream);
- Assert.True(image is Image);
+ PngMetadata metadata = image.Metadata.GetPngMetadata();
+ Assert.Equal(pngColorType, metadata.ColorType);
+ Assert.Equal(pngBitDepth, metadata.BitDepth);
+ }
}
[Theory]
diff --git a/tests/ImageSharp.Tests/TestUtilities/PixelTypes.cs b/tests/ImageSharp.Tests/TestUtilities/PixelTypes.cs
index c795563134..eb8860eb6f 100644
--- a/tests/ImageSharp.Tests/TestUtilities/PixelTypes.cs
+++ b/tests/ImageSharp.Tests/TestUtilities/PixelTypes.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Six Labors and contributors.
+// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@@ -62,11 +62,15 @@ namespace SixLabors.ImageSharp.Tests
L8 = 1 << 23,
- Gray16 = 1 << 24,
+ L16 = 1 << 24,
+
+ La16 = 1 << 25,
+
+ La32 = 1 << 26,
// TODO: Add multi-flag entries by rules defined in PackedPixelConverterHelper
// "All" is handled as a separate, individual case instead of using bitwise OR
All = 30
}
-}
\ No newline at end of file
+}