@@ -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