Skip to content

Commit 057edd8

Browse files
Use the new metadata
1 parent 1d35251 commit 057edd8

File tree

7 files changed

+125
-128
lines changed

7 files changed

+125
-128
lines changed

src/ImageSharp/Color/Color.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public static Color FromPixel<TPixel>(TPixel pixel)
9494
{
9595
// Avoid boxing in case we can convert to Vector4 safely and efficiently
9696
PixelTypeInfo info = TPixel.GetPixelTypeInfo();
97-
if (info.ComponentInfo.HasValue && info.ComponentInfo.Value.GetMaximumComponentPrecision() <= (int)PixelComponentPrecision.Float)
97+
if (info.ComponentInfo.HasValue && info.ComponentInfo.Value.GetMaximumComponentPrecision() <= (int)PixelComponentBitDepth.Bit32)
9898
{
9999
return new(pixel.ToScaledVector4());
100100
}
@@ -118,7 +118,7 @@ public static void FromPixel<TPixel>(ReadOnlySpan<TPixel> source, Span<Color> de
118118

119119
// Avoid boxing in case we can convert to Vector4 safely and efficiently
120120
PixelTypeInfo info = TPixel.GetPixelTypeInfo();
121-
if (info.ComponentInfo.HasValue && info.ComponentInfo.Value.GetMaximumComponentPrecision() <= (int)PixelComponentPrecision.Float)
121+
if (info.ComponentInfo.HasValue && info.ComponentInfo.Value.GetMaximumComponentPrecision() <= (int)PixelComponentBitDepth.Bit32)
122122
{
123123
for (int i = 0; i < destination.Length; i++)
124124
{

src/ImageSharp/Formats/Png/PngBitDepth.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Six Labors.
1+
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
33

44
// Note the value assignment, This will allow us to add 1, 2, and 4 bit encoding when we support it.

src/ImageSharp/Formats/Png/PngEncoderCore.cs

Lines changed: 60 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,23 +1466,48 @@ private void SanitizeAndSetEncoderOptions<TPixel>(
14661466

14671467
// Use options, then check metadata, if nothing set there then we suggest
14681468
// a sensible default based upon the pixel format.
1469-
this.colorType = encoder.ColorType ?? pngMetadata.ColorType ?? SuggestColorType<TPixel>();
1470-
if (!encoder.FilterMethod.HasValue)
1469+
PngColorType? colorType = encoder.ColorType ?? pngMetadata.ColorType;
1470+
byte? bits = (byte?)(encoder.BitDepth ?? pngMetadata.BitDepth);
1471+
1472+
if (colorType is null || bits is null)
14711473
{
1472-
// Specification recommends default filter method None for paletted images and Paeth for others.
1473-
this.filterMethod = this.colorType is PngColorType.Palette ? PngFilterMethod.None : PngFilterMethod.Paeth;
1474+
PixelTypeInfo info = TPixel.GetPixelTypeInfo();
1475+
PixelComponentInfo? componentInfo = info.ComponentInfo;
1476+
1477+
colorType ??= SuggestColorType<TPixel>(in info);
1478+
1479+
if (bits is null)
1480+
{
1481+
// TODO: Update once we stop abusing PixelTypeInfo in decoders.
1482+
if (componentInfo.HasValue)
1483+
{
1484+
PixelComponentInfo c = componentInfo.Value;
1485+
bits = (byte)SuggestBitDepth<TPixel>(in c);
1486+
}
1487+
else
1488+
{
1489+
bits = (byte)PngBitDepth.Bit8;
1490+
}
1491+
}
14741492
}
14751493

14761494
// Ensure bit depth and color type are a supported combination.
14771495
// Bit8 is the only bit depth supported by all color types.
1478-
byte bits = (byte)(encoder.BitDepth ?? pngMetadata.BitDepth ?? SuggestBitDepth<TPixel>());
1479-
byte[] validBitDepths = PngConstants.ColorTypes[this.colorType];
1496+
byte[] validBitDepths = PngConstants.ColorTypes[colorType.Value];
14801497
if (Array.IndexOf(validBitDepths, bits) == -1)
14811498
{
14821499
bits = (byte)PngBitDepth.Bit8;
14831500
}
14841501

1485-
this.bitDepth = bits;
1502+
this.colorType = colorType.Value;
1503+
this.bitDepth = bits.Value;
1504+
1505+
if (!encoder.FilterMethod.HasValue)
1506+
{
1507+
// Specification recommends default filter method None for paletted images and Paeth for others.
1508+
this.filterMethod = this.colorType is PngColorType.Palette ? PngFilterMethod.None : PngFilterMethod.Paeth;
1509+
}
1510+
14861511
use16Bit = bits == (byte)PngBitDepth.Bit16;
14871512
bytesPerPixel = CalculateBytesPerPixel(this.colorType, use16Bit);
14881513

@@ -1611,53 +1636,44 @@ private static int CalculateBytesPerPixel(PngColorType? pngColorType, bool use16
16111636

16121637
/// <summary>
16131638
/// Returns a suggested <see cref="PngColorType"/> for the given <typeparamref name="TPixel"/>
1614-
/// This is not exhaustive but covers many common pixel formats.
16151639
/// </summary>
1640+
/// <param name="info">The pixel type info.</param>
16161641
/// <typeparam name="TPixel">The type of pixel format.</typeparam>
1617-
private static PngColorType SuggestColorType<TPixel>()
1642+
private static PngColorType SuggestColorType<TPixel>(in PixelTypeInfo info)
16181643
where TPixel : unmanaged, IPixel<TPixel>
1619-
=> default(TPixel) switch
1620-
{
1621-
A8 => PngColorType.GrayscaleWithAlpha,
1622-
Argb32 => PngColorType.RgbWithAlpha,
1623-
Bgr24 => PngColorType.Rgb,
1624-
Bgra32 => PngColorType.RgbWithAlpha,
1625-
L8 => PngColorType.Grayscale,
1626-
L16 => PngColorType.Grayscale,
1627-
La16 => PngColorType.GrayscaleWithAlpha,
1628-
La32 => PngColorType.GrayscaleWithAlpha,
1629-
Rgb24 => PngColorType.Rgb,
1630-
Rgba32 => PngColorType.RgbWithAlpha,
1631-
Rgb48 => PngColorType.Rgb,
1632-
Rgba64 => PngColorType.RgbWithAlpha,
1633-
RgbaVector => PngColorType.RgbWithAlpha,
1634-
_ => PngColorType.RgbWithAlpha
1644+
{
1645+
if (info.AlphaRepresentation == PixelAlphaRepresentation.None)
1646+
{
1647+
return info.ColorType switch
1648+
{
1649+
PixelColorType.Grayscale => PngColorType.Grayscale,
1650+
_ => PngColorType.Rgb,
1651+
};
1652+
}
1653+
1654+
return info.ColorType switch
1655+
{
1656+
PixelColorType.Grayscale | PixelColorType.Alpha or PixelColorType.Alpha => PngColorType.GrayscaleWithAlpha,
1657+
_ => PngColorType.RgbWithAlpha,
16351658
};
1659+
}
16361660

16371661
/// <summary>
16381662
/// Returns a suggested <see cref="PngBitDepth"/> for the given <typeparamref name="TPixel"/>
1639-
/// This is not exhaustive but covers many common pixel formats.
16401663
/// </summary>
1664+
/// <param name="info">The pixel type info.</param>
16411665
/// <typeparam name="TPixel">The type of pixel format.</typeparam>
1642-
private static PngBitDepth SuggestBitDepth<TPixel>()
1666+
private static PngBitDepth SuggestBitDepth<TPixel>(in PixelComponentInfo info)
16431667
where TPixel : unmanaged, IPixel<TPixel>
1644-
=> default(TPixel) switch
1645-
{
1646-
A8 => PngBitDepth.Bit8,
1647-
Argb32 => PngBitDepth.Bit8,
1648-
Bgr24 => PngBitDepth.Bit8,
1649-
Bgra32 => PngBitDepth.Bit8,
1650-
L8 => PngBitDepth.Bit8,
1651-
L16 => PngBitDepth.Bit16,
1652-
La16 => PngBitDepth.Bit8,
1653-
La32 => PngBitDepth.Bit16,
1654-
Rgb24 => PngBitDepth.Bit8,
1655-
Rgba32 => PngBitDepth.Bit8,
1656-
Rgb48 => PngBitDepth.Bit16,
1657-
Rgba64 => PngBitDepth.Bit16,
1658-
RgbaVector => PngBitDepth.Bit16,
1659-
_ => PngBitDepth.Bit8
1660-
};
1668+
{
1669+
int bits = info.GetMaximumComponentPrecision();
1670+
if (bits > (int)PixelComponentBitDepth.Bit8)
1671+
{
1672+
return PngBitDepth.Bit16;
1673+
}
1674+
1675+
return PngBitDepth.Bit8;
1676+
}
16611677

16621678
private unsafe struct ScratchBuffer
16631679
{
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
namespace SixLabors.ImageSharp.PixelFormats;
5+
6+
/// <summary>
7+
/// Provides enumeration of the precision in bits of individual components within a pixel format.
8+
/// </summary>
9+
public enum PixelComponentBitDepth
10+
{
11+
/// <summary>
12+
/// 1 bit per component.
13+
/// </summary>
14+
Bit1 = 1,
15+
16+
/// <summary>
17+
/// 2 bits per component.
18+
/// </summary>
19+
Bit2 = 2,
20+
21+
/// <summary>
22+
/// 4 bits per component.
23+
/// </summary>
24+
Bit4 = 4,
25+
26+
/// <summary>
27+
/// 8 bits per component.
28+
/// </summary>
29+
Bit8 = 8,
30+
31+
/// <summary>
32+
/// 16 bits per component.
33+
/// </summary>
34+
Bit16 = 16,
35+
36+
/// <summary>
37+
/// 32 bits per component.
38+
/// </summary>
39+
Bit32 = 32,
40+
41+
/// <summary>
42+
/// 64 bits per component.
43+
/// </summary>
44+
Bit64 = 64,
45+
46+
/// <summary>
47+
/// 128 bits per component.
48+
/// </summary>
49+
Bit128 = 128
50+
}

src/ImageSharp/PixelFormats/PixelComponentPrecision.cs

Lines changed: 0 additions & 70 deletions
This file was deleted.

src/ImageSharp/PixelFormats/PixelTypeInfo.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
using System.Runtime.CompilerServices;
55

66
// TODO: Review this type as it's used to represent 2 different things.
7-
// 1.The encoded image pixel format.
7+
// 1. The encoded image pixel format.
88
// 2. The pixel format of the decoded image.
9+
// Only the bits per pixel is used by the decoder, we should make it a property of the image metadata.
910
namespace SixLabors.ImageSharp.PixelFormats;
1011

1112
/// <summary>

tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -256,21 +256,21 @@ public void WorksWithAllBitDepthsAndExcludeAllFilter<TPixel>(TestImageProvider<T
256256
[Theory]
257257
[WithBlankImages(1, 1, PixelTypes.A8, PngColorType.GrayscaleWithAlpha, PngBitDepth.Bit8)]
258258
[WithBlankImages(1, 1, PixelTypes.Argb32, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
259-
[WithBlankImages(1, 1, PixelTypes.Bgr565, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
259+
[WithBlankImages(1, 1, PixelTypes.Bgr565, PngColorType.Rgb, PngBitDepth.Bit8)]
260260
[WithBlankImages(1, 1, PixelTypes.Bgra4444, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
261261
[WithBlankImages(1, 1, PixelTypes.Byte4, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
262-
[WithBlankImages(1, 1, PixelTypes.HalfSingle, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
263-
[WithBlankImages(1, 1, PixelTypes.HalfVector2, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
264-
[WithBlankImages(1, 1, PixelTypes.HalfVector4, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
265-
[WithBlankImages(1, 1, PixelTypes.NormalizedByte2, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
262+
[WithBlankImages(1, 1, PixelTypes.HalfSingle, PngColorType.Rgb, PngBitDepth.Bit16)]
263+
[WithBlankImages(1, 1, PixelTypes.HalfVector2, PngColorType.Rgb, PngBitDepth.Bit16)]
264+
[WithBlankImages(1, 1, PixelTypes.HalfVector4, PngColorType.RgbWithAlpha, PngBitDepth.Bit16)]
265+
[WithBlankImages(1, 1, PixelTypes.NormalizedByte2, PngColorType.Rgb, PngBitDepth.Bit8)]
266266
[WithBlankImages(1, 1, PixelTypes.NormalizedByte4, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
267-
[WithBlankImages(1, 1, PixelTypes.NormalizedShort4, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
268-
[WithBlankImages(1, 1, PixelTypes.Rg32, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
269-
[WithBlankImages(1, 1, PixelTypes.Rgba1010102, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
267+
[WithBlankImages(1, 1, PixelTypes.NormalizedShort4, PngColorType.RgbWithAlpha, PngBitDepth.Bit16)]
268+
[WithBlankImages(1, 1, PixelTypes.Rg32, PngColorType.Rgb, PngBitDepth.Bit16)]
269+
[WithBlankImages(1, 1, PixelTypes.Rgba1010102, PngColorType.RgbWithAlpha, PngBitDepth.Bit16)]
270270
[WithBlankImages(1, 1, PixelTypes.Rgba32, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
271271
[WithBlankImages(1, 1, PixelTypes.RgbaVector, PngColorType.RgbWithAlpha, PngBitDepth.Bit16)]
272-
[WithBlankImages(1, 1, PixelTypes.Short2, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
273-
[WithBlankImages(1, 1, PixelTypes.Short4, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]
272+
[WithBlankImages(1, 1, PixelTypes.Short2, PngColorType.Rgb, PngBitDepth.Bit16)]
273+
[WithBlankImages(1, 1, PixelTypes.Short4, PngColorType.RgbWithAlpha, PngBitDepth.Bit16)]
274274
[WithBlankImages(1, 1, PixelTypes.Rgb24, PngColorType.Rgb, PngBitDepth.Bit8)]
275275
[WithBlankImages(1, 1, PixelTypes.Bgr24, PngColorType.Rgb, PngBitDepth.Bit8)]
276276
[WithBlankImages(1, 1, PixelTypes.Bgra32, PngColorType.RgbWithAlpha, PngBitDepth.Bit8)]

0 commit comments

Comments
 (0)