Skip to content

Commit a94b8c4

Browse files
authored
Merge branch 'master' into add-Abgr32-pixel-type
2 parents 3ee73a8 + ecd3db2 commit a94b8c4

File tree

10 files changed

+348
-170
lines changed

10 files changed

+348
-170
lines changed

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
blank_issues_enabled: false
22
contact_links:
3-
- name: Ask a Question
4-
url: https://github.com/SixLabors/ImageSharp/discussions?discussions_q=category%3AQ%26A
5-
about: Ask a question about this project.
63
- name: Feature Request
74
url: https://github.com/SixLabors/ImageSharp/discussions?discussions_q=category%3AIdeas
85
about: Share ideas for new features for this project.

.github/ISSUE_TEMPLATE/oss-bug-report.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: "OSS : Bug Report"
3-
about: Create a report to help us improve the project.
3+
about: Create a report to help us improve the project. OSS Issues are not guaranteed to be triaged.
44
labels: needs triage
55

66
---

src/ImageSharp/Formats/Png/PngDecoder.cs

Lines changed: 107 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,37 +20,137 @@ public sealed class PngDecoder : IImageDecoder, IPngDecoderOptions, IImageInfoDe
2020
public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream)
2121
where TPixel : unmanaged, IPixel<TPixel>
2222
{
23-
var decoder = new PngDecoderCore(configuration, this);
23+
PngDecoderCore decoder = new(configuration, this);
2424
return decoder.Decode<TPixel>(configuration, stream);
2525
}
2626

2727
/// <inheritdoc />
28-
public Image Decode(Configuration configuration, Stream stream) => this.Decode<Rgba32>(configuration, stream);
28+
public Image Decode(Configuration configuration, Stream stream)
29+
{
30+
PngDecoderCore decoder = new(configuration, true);
31+
IImageInfo info = decoder.Identify(configuration, stream);
32+
stream.Position = 0;
33+
34+
PngMetadata meta = info.Metadata.GetPngMetadata();
35+
PngColorType color = meta.ColorType.GetValueOrDefault();
36+
PngBitDepth bits = meta.BitDepth.GetValueOrDefault();
37+
switch (color)
38+
{
39+
case PngColorType.Grayscale:
40+
if (bits == PngBitDepth.Bit16)
41+
{
42+
return !meta.HasTransparency
43+
? this.Decode<L16>(configuration, stream)
44+
: this.Decode<La32>(configuration, stream);
45+
}
46+
47+
return !meta.HasTransparency
48+
? this.Decode<L8>(configuration, stream)
49+
: this.Decode<La16>(configuration, stream);
50+
51+
case PngColorType.Rgb:
52+
if (bits == PngBitDepth.Bit16)
53+
{
54+
return !meta.HasTransparency
55+
? this.Decode<Rgb48>(configuration, stream)
56+
: this.Decode<Rgba64>(configuration, stream);
57+
}
58+
59+
return !meta.HasTransparency
60+
? this.Decode<Rgb24>(configuration, stream)
61+
: this.Decode<Rgba32>(configuration, stream);
62+
63+
case PngColorType.Palette:
64+
return this.Decode<Rgba32>(configuration, stream);
65+
66+
case PngColorType.GrayscaleWithAlpha:
67+
return (bits == PngBitDepth.Bit16)
68+
? this.Decode<La32>(configuration, stream)
69+
: this.Decode<La16>(configuration, stream);
70+
71+
case PngColorType.RgbWithAlpha:
72+
return (bits == PngBitDepth.Bit16)
73+
? this.Decode<Rgba64>(configuration, stream)
74+
: this.Decode<Rgba32>(configuration, stream);
75+
76+
default:
77+
return this.Decode<Rgba32>(configuration, stream);
78+
}
79+
}
2980

3081
/// <inheritdoc/>
3182
public Task<Image<TPixel>> DecodeAsync<TPixel>(Configuration configuration, Stream stream, CancellationToken cancellationToken)
3283
where TPixel : unmanaged, IPixel<TPixel>
3384
{
34-
var decoder = new PngDecoderCore(configuration, this);
85+
PngDecoderCore decoder = new(configuration, this);
3586
return decoder.DecodeAsync<TPixel>(configuration, stream, cancellationToken);
3687
}
3788

3889
/// <inheritdoc />
3990
public async Task<Image> DecodeAsync(Configuration configuration, Stream stream, CancellationToken cancellationToken)
40-
=> await this.DecodeAsync<Rgba32>(configuration, stream, cancellationToken)
41-
.ConfigureAwait(false);
91+
{
92+
PngDecoderCore decoder = new(configuration, true);
93+
IImageInfo info = await decoder.IdentifyAsync(configuration, stream, cancellationToken).ConfigureAwait(false);
94+
stream.Position = 0;
95+
96+
PngMetadata meta = info.Metadata.GetPngMetadata();
97+
PngColorType color = meta.ColorType.GetValueOrDefault();
98+
PngBitDepth bits = meta.BitDepth.GetValueOrDefault();
99+
switch (color)
100+
{
101+
case PngColorType.Grayscale:
102+
if (bits == PngBitDepth.Bit16)
103+
{
104+
return !meta.HasTransparency
105+
? await this.DecodeAsync<L16>(configuration, stream, cancellationToken).ConfigureAwait(false)
106+
: await this.DecodeAsync<La32>(configuration, stream, cancellationToken).ConfigureAwait(false);
107+
}
108+
109+
return !meta.HasTransparency
110+
? await this.DecodeAsync<L8>(configuration, stream, cancellationToken).ConfigureAwait(false)
111+
: await this.DecodeAsync<La16>(configuration, stream, cancellationToken).ConfigureAwait(false);
112+
113+
case PngColorType.Rgb:
114+
if (bits == PngBitDepth.Bit16)
115+
{
116+
return !meta.HasTransparency
117+
? await this.DecodeAsync<Rgb48>(configuration, stream, cancellationToken).ConfigureAwait(false)
118+
: await this.DecodeAsync<Rgba64>(configuration, stream, cancellationToken).ConfigureAwait(false);
119+
}
120+
121+
return !meta.HasTransparency
122+
? await this.DecodeAsync<Rgb24>(configuration, stream, cancellationToken).ConfigureAwait(false)
123+
: await this.DecodeAsync<Rgba32>(configuration, stream, cancellationToken).ConfigureAwait(false);
124+
125+
case PngColorType.Palette:
126+
return await this.DecodeAsync<Rgba32>(configuration, stream, cancellationToken).ConfigureAwait(false);
127+
128+
case PngColorType.GrayscaleWithAlpha:
129+
return (bits == PngBitDepth.Bit16)
130+
? await this.DecodeAsync<La32>(configuration, stream, cancellationToken).ConfigureAwait(false)
131+
: await this.DecodeAsync<La16>(configuration, stream, cancellationToken).ConfigureAwait(false);
132+
133+
case PngColorType.RgbWithAlpha:
134+
return (bits == PngBitDepth.Bit16)
135+
? await this.DecodeAsync<Rgba64>(configuration, stream, cancellationToken).ConfigureAwait(false)
136+
: await this.DecodeAsync<Rgba32>(configuration, stream, cancellationToken).ConfigureAwait(false);
137+
138+
default:
139+
return await this.DecodeAsync<Rgba32>(configuration, stream, cancellationToken).ConfigureAwait(false);
140+
}
141+
}
42142

43143
/// <inheritdoc/>
44144
public IImageInfo Identify(Configuration configuration, Stream stream)
45145
{
46-
var decoder = new PngDecoderCore(configuration, this);
146+
PngDecoderCore decoder = new(configuration, this);
47147
return decoder.Identify(configuration, stream);
48148
}
49149

50150
/// <inheritdoc/>
51151
public Task<IImageInfo> IdentifyAsync(Configuration configuration, Stream stream, CancellationToken cancellationToken)
52152
{
53-
var decoder = new PngDecoderCore(configuration, this);
153+
PngDecoderCore decoder = new(configuration, this);
54154
return decoder.IdentifyAsync(configuration, stream, cancellationToken);
55155
}
56156
}

0 commit comments

Comments
 (0)