|
|
@ -14,23 +14,28 @@ namespace SixLabors.ImageSharp.Formats.Png |
|
|
internal static class PngEncoderOptionsHelpers |
|
|
internal static class PngEncoderOptionsHelpers |
|
|
{ |
|
|
{ |
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// Adjusts the options.
|
|
|
/// Adjusts the options based upon the given metadata.
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
/// <param name="options">The options.</param>
|
|
|
/// <param name="options">The options.</param>
|
|
|
/// <param name="pngMetadata">The PNG metadata.</param>
|
|
|
/// <param name="pngMetadata">The PNG metadata.</param>
|
|
|
/// <param name="use16Bit">if set to <c>true</c> [use16 bit].</param>
|
|
|
/// <param name="use16Bit">if set to <c>true</c> [use16 bit].</param>
|
|
|
/// <param name="bytesPerPixel">The bytes per pixel.</param>
|
|
|
/// <param name="bytesPerPixel">The bytes per pixel.</param>
|
|
|
public static void AdjustOptions( |
|
|
public static void AdjustOptions<TPixel>( |
|
|
PngEncoderOptions options, |
|
|
PngEncoderOptions options, |
|
|
PngMetadata pngMetadata, |
|
|
PngMetadata pngMetadata, |
|
|
out bool use16Bit, |
|
|
out bool use16Bit, |
|
|
out int bytesPerPixel) |
|
|
out int bytesPerPixel) |
|
|
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
{ |
|
|
{ |
|
|
// Always take the encoder options over the metadata values.
|
|
|
// Always take the encoder options over the metadata values.
|
|
|
options.Gamma = options.Gamma ?? pngMetadata.Gamma; |
|
|
options.Gamma ??= pngMetadata.Gamma; |
|
|
options.ColorType = options.ColorType ?? pngMetadata.ColorType; |
|
|
|
|
|
options.BitDepth = options.BitDepth ?? pngMetadata.BitDepth; |
|
|
// Use options, then check metadata, if nothing set there then we suggest
|
|
|
options.InterlaceMethod = options.InterlaceMethod ?? pngMetadata.InterlaceMethod; |
|
|
// a sensible default based upon the pixel format.
|
|
|
|
|
|
options.ColorType ??= pngMetadata.ColorType ?? SuggestColorType<TPixel>(); |
|
|
|
|
|
options.BitDepth ??= pngMetadata.BitDepth ?? SuggestBitDepth<TPixel>(); |
|
|
|
|
|
|
|
|
|
|
|
options.InterlaceMethod ??= pngMetadata.InterlaceMethod; |
|
|
|
|
|
|
|
|
use16Bit = options.BitDepth == PngBitDepth.Bit16; |
|
|
use16Bit = options.BitDepth == PngBitDepth.Bit16; |
|
|
bytesPerPixel = CalculateBytesPerPixel(options.ColorType, use16Bit); |
|
|
bytesPerPixel = CalculateBytesPerPixel(options.ColorType, use16Bit); |
|
|
@ -129,24 +134,68 @@ namespace SixLabors.ImageSharp.Formats.Png |
|
|
/// <returns>Bytes per pixel.</returns>
|
|
|
/// <returns>Bytes per pixel.</returns>
|
|
|
private static int CalculateBytesPerPixel(PngColorType? pngColorType, bool use16Bit) |
|
|
private static int CalculateBytesPerPixel(PngColorType? pngColorType, bool use16Bit) |
|
|
{ |
|
|
{ |
|
|
switch (pngColorType) |
|
|
return pngColorType switch |
|
|
{ |
|
|
{ |
|
|
case PngColorType.Grayscale: |
|
|
PngColorType.Grayscale => use16Bit ? 2 : 1, |
|
|
return use16Bit ? 2 : 1; |
|
|
PngColorType.GrayscaleWithAlpha => use16Bit ? 4 : 2, |
|
|
|
|
|
PngColorType.Palette => 1, |
|
|
|
|
|
PngColorType.Rgb => use16Bit ? 6 : 3, |
|
|
|
|
|
|
|
|
case PngColorType.GrayscaleWithAlpha: |
|
|
// PngColorType.RgbWithAlpha
|
|
|
return use16Bit ? 4 : 2; |
|
|
_ => use16Bit ? 8 : 4, |
|
|
|
|
|
}; |
|
|
case PngColorType.Palette: |
|
|
} |
|
|
return 1; |
|
|
|
|
|
|
|
|
|
|
|
case PngColorType.Rgb: |
|
|
/// <summary>
|
|
|
return use16Bit ? 6 : 3; |
|
|
/// Returns a suggested <see cref="PngColorType"/> for the given <typeparamref name="TPixel"/>
|
|
|
|
|
|
/// This is not exhaustive but covers many common pixel formats.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private static PngColorType SuggestColorType<TPixel>() |
|
|
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
|
|
{ |
|
|
|
|
|
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, |
|
|
|
|
|
_ => PngColorType.RgbWithAlpha |
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// PngColorType.RgbWithAlpha
|
|
|
/// <summary>
|
|
|
default: |
|
|
/// Returns a suggested <see cref="PngBitDepth"/> for the given <typeparamref name="TPixel"/>
|
|
|
return use16Bit ? 8 : 4; |
|
|
/// This is not exhaustive but covers many common pixel formats.
|
|
|
} |
|
|
/// </summary>
|
|
|
|
|
|
private static PngBitDepth SuggestBitDepth<TPixel>() |
|
|
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
|
|
{ |
|
|
|
|
|
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, |
|
|
|
|
|
_ => PngBitDepth.Bit8 |
|
|
|
|
|
}; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|