diff --git a/src/ImageSharp/Formats/Png/PngDecoder.cs b/src/ImageSharp/Formats/Png/PngDecoder.cs index ea898b0506..5637d5c7bf 100644 --- a/src/ImageSharp/Formats/Png/PngDecoder.cs +++ b/src/ImageSharp/Formats/Png/PngDecoder.cs @@ -31,39 +31,82 @@ namespace SixLabors.ImageSharp.Formats.Png IImageInfo info = decoder.Identify(configuration, stream); stream.Position = 0; - switch (info.Metadata.GetPngMetadata().ColorType) + PngMetadata meta = info.Metadata.GetPngMetadata(); + PngColorType color = meta.ColorType.GetValueOrDefault(); + PngBitDepth bits = meta.BitDepth.GetValueOrDefault(); + return color switch { - default: - break; - } + PngColorType.Grayscale => (bits == PngBitDepth.Bit16) + ? this.Decode(configuration, stream) + : this.Decode(configuration, stream), - return this.Decode(configuration, stream); + PngColorType.Rgb => this.Decode(configuration, stream), + + PngColorType.Palette => this.Decode(configuration, stream), + + PngColorType.GrayscaleWithAlpha => (bits == PngBitDepth.Bit16) + ? this.Decode(configuration, stream) + : this.Decode(configuration, stream), + + PngColorType.RgbWithAlpha => (bits == PngBitDepth.Bit16) + ? this.Decode(configuration, stream) + : this.Decode(configuration, stream), + + _ => this.Decode(configuration, stream), + }; } /// public Task> DecodeAsync(Configuration configuration, Stream stream, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { - var decoder = new PngDecoderCore(configuration, this); + PngDecoderCore decoder = new(configuration, this); return decoder.DecodeAsync(configuration, stream, cancellationToken); } /// public async Task DecodeAsync(Configuration configuration, Stream stream, CancellationToken cancellationToken) - => await this.DecodeAsync(configuration, stream, cancellationToken) - .ConfigureAwait(false); + { + PngDecoderCore decoder = new(configuration, true); + IImageInfo info = await decoder.IdentifyAsync(configuration, stream, cancellationToken).ConfigureAwait(false); + stream.Position = 0; + + PngMetadata meta = info.Metadata.GetPngMetadata(); + PngColorType color = meta.ColorType.GetValueOrDefault(); + PngBitDepth bits = meta.BitDepth.GetValueOrDefault(); + return color switch + { + PngColorType.Grayscale => (bits == PngBitDepth.Bit16) + ? await this.DecodeAsync(configuration, stream, cancellationToken).ConfigureAwait(false) + : await this.DecodeAsync(configuration, stream, cancellationToken).ConfigureAwait(false), + + PngColorType.Rgb => await this.DecodeAsync(configuration, stream, cancellationToken).ConfigureAwait(false), + + PngColorType.Palette => await this.DecodeAsync(configuration, stream, cancellationToken).ConfigureAwait(false), + + PngColorType.GrayscaleWithAlpha => (bits == PngBitDepth.Bit16) + ? await this.DecodeAsync(configuration, stream, cancellationToken).ConfigureAwait(false) + : await this.DecodeAsync(configuration, stream, cancellationToken).ConfigureAwait(false), + + PngColorType.RgbWithAlpha => (bits == PngBitDepth.Bit16) + ? await this.DecodeAsync(configuration, stream, cancellationToken).ConfigureAwait(false) + : await this.DecodeAsync(configuration, stream, cancellationToken).ConfigureAwait(false), + + _ => await this.DecodeAsync(configuration, stream, cancellationToken).ConfigureAwait(false), + }; + } /// public IImageInfo Identify(Configuration configuration, Stream stream) { - var decoder = new PngDecoderCore(configuration, this); + PngDecoderCore decoder = new(configuration, this); return decoder.Identify(configuration, stream); } /// public Task IdentifyAsync(Configuration configuration, Stream stream, CancellationToken cancellationToken) { - var decoder = new PngDecoderCore(configuration, this); + PngDecoderCore decoder = new(configuration, this); return decoder.IdentifyAsync(configuration, stream, cancellationToken); } }