From d4539222509b646d624df00e88ac3de00681a229 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 29 Jun 2022 22:32:33 +1000 Subject: [PATCH] Port Pbm decoder --- .../Formats/Gif/IGifDecoderOptions.cs | 23 ---- src/ImageSharp/Formats/Pbm/PbmDecoder.cs | 24 ++-- src/ImageSharp/Formats/Pbm/PbmDecoderCore.cs | 105 ++++++++++-------- .../Formats/Pbm/PbmDecoderOptions.cs | 14 +++ 4 files changed, 83 insertions(+), 83 deletions(-) delete mode 100644 src/ImageSharp/Formats/Gif/IGifDecoderOptions.cs create mode 100644 src/ImageSharp/Formats/Pbm/PbmDecoderOptions.cs diff --git a/src/ImageSharp/Formats/Gif/IGifDecoderOptions.cs b/src/ImageSharp/Formats/Gif/IGifDecoderOptions.cs deleted file mode 100644 index 56bb6d6519..0000000000 --- a/src/ImageSharp/Formats/Gif/IGifDecoderOptions.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Apache License, Version 2.0. - -using SixLabors.ImageSharp.Metadata; - -namespace SixLabors.ImageSharp.Formats.Gif -{ - /// - /// Decoder for generating an image out of a gif encoded stream. - /// - internal interface IGifDecoderOptions - { - /// - /// Gets a value indicating whether the metadata should be ignored when the image is being decoded. - /// - bool IgnoreMetadata { get; } - - /// - /// Gets the decoding mode for multi-frame images. - /// - FrameDecodingMode DecodingMode { get; } - } -} diff --git a/src/ImageSharp/Formats/Pbm/PbmDecoder.cs b/src/ImageSharp/Formats/Pbm/PbmDecoder.cs index 97a9cb7d75..90752a6374 100644 --- a/src/ImageSharp/Formats/Pbm/PbmDecoder.cs +++ b/src/ImageSharp/Formats/Pbm/PbmDecoder.cs @@ -26,29 +26,29 @@ namespace SixLabors.ImageSharp.Formats.Pbm /// /// The specification of these images is found at . /// - public sealed class PbmDecoder : IImageDecoder, IImageInfoDetector + public sealed class PbmDecoder : ImageDecoder { - /// - public Image Decode(Configuration configuration, Stream stream, CancellationToken cancellationToken) - where TPixel : unmanaged, IPixel + /// + public override Image DecodeSpecialized(PbmDecoderOptions options, Stream stream, CancellationToken cancellationToken) { - Guard.NotNull(stream, nameof(stream)); + PbmDecoderCore decoder = new(options); + Image image = decoder.Decode(options.GeneralOptions.Configuration, stream, cancellationToken); + + Resize(options.GeneralOptions, image); - var decoder = new PbmDecoderCore(configuration); - return decoder.Decode(configuration, stream, cancellationToken); + return image; } /// - public Image Decode(Configuration configuration, Stream stream, CancellationToken cancellationToken) - => this.Decode(configuration, stream, cancellationToken); + public override Image DecodeSpecialized(PbmDecoderOptions options, Stream stream, CancellationToken cancellationToken) + => this.DecodeSpecialized(options, stream, cancellationToken); /// - public IImageInfo Identify(Configuration configuration, Stream stream, CancellationToken cancellationToken) + public override IImageInfo IdentifySpecialized(PbmDecoderOptions options, Stream stream, CancellationToken cancellationToken) { Guard.NotNull(stream, nameof(stream)); - var decoder = new PbmDecoderCore(configuration); - return decoder.Identify(configuration, stream, cancellationToken); + return new PbmDecoderCore(options).Identify(options.GeneralOptions.Configuration, stream, cancellationToken); } } } diff --git a/src/ImageSharp/Formats/Pbm/PbmDecoderCore.cs b/src/ImageSharp/Formats/Pbm/PbmDecoderCore.cs index 749fc0292b..568c1ab4c9 100644 --- a/src/ImageSharp/Formats/Pbm/PbmDecoderCore.cs +++ b/src/ImageSharp/Formats/Pbm/PbmDecoderCore.cs @@ -14,48 +14,55 @@ namespace SixLabors.ImageSharp.Formats.Pbm /// /// Performs the PBM decoding operation. /// - internal sealed class PbmDecoderCore : IImageDecoderInternals + internal sealed class PbmDecoderCore : IImageDecoderInternals { private int maxPixelValue; /// - /// Initializes a new instance of the class. + /// The general configuration. /// - /// The configuration. - public PbmDecoderCore(Configuration configuration) => this.Configuration = configuration ?? Configuration.Default; + private readonly Configuration configuration; - /// - public Configuration Configuration { get; } + /// + /// The colortype to use + /// + private PbmColorType colorType; /// - /// Gets the colortype to use + /// The size of the pixel array /// - public PbmColorType ColorType { get; private set; } + private Size pixelSize; /// - /// Gets the size of the pixel array + /// The component data type /// - public Size PixelSize { get; private set; } + private PbmComponentType componentType; /// - /// Gets the component data type + /// The Encoding of pixels /// - public PbmComponentType ComponentType { get; private set; } + private PbmEncoding encoding; /// - /// Gets the Encoding of pixels + /// The decoded by this decoder instance. /// - public PbmEncoding Encoding { get; private set; } + private ImageMetadata metadata; /// - /// Gets the decoded by this decoder instance. + /// Initializes a new instance of the class. /// - public ImageMetadata Metadata { get; private set; } + /// The decoder options. + public PbmDecoderCore(PbmDecoderOptions options) + { + this.Options = options; + this.configuration = options.GeneralOptions.Configuration; + } /// - Size IImageDecoderInternals.Dimensions => this.PixelSize; + public PbmDecoderOptions Options { get; } - private bool NeedsUpscaling => this.ColorType != PbmColorType.BlackAndWhite && this.maxPixelValue is not 255 and not 65535; + /// + public Size Dimensions => this.pixelSize; /// public Image Decode(BufferedReadStream stream, CancellationToken cancellationToken) @@ -63,12 +70,12 @@ namespace SixLabors.ImageSharp.Formats.Pbm { this.ProcessHeader(stream); - var image = new Image(this.Configuration, this.PixelSize.Width, this.PixelSize.Height, this.Metadata); + var image = new Image(this.configuration, this.pixelSize.Width, this.pixelSize.Height, this.metadata); Buffer2D pixels = image.GetRootFramePixelBuffer(); this.ProcessPixels(stream, pixels); - if (this.NeedsUpscaling) + if (this.NeedsUpscaling()) { this.ProcessUpscaling(image); } @@ -82,8 +89,8 @@ namespace SixLabors.ImageSharp.Formats.Pbm this.ProcessHeader(stream); // BlackAndWhite pixels are encoded into a byte. - int bitsPerPixel = this.ComponentType == PbmComponentType.Short ? 16 : 8; - return new ImageInfo(new PixelTypeInfo(bitsPerPixel), this.PixelSize.Width, this.PixelSize.Height, this.Metadata); + int bitsPerPixel = this.componentType == PbmComponentType.Short ? 16 : 8; + return new ImageInfo(new PixelTypeInfo(bitsPerPixel), this.pixelSize.Width, this.pixelSize.Height, this.metadata); } /// @@ -104,33 +111,33 @@ namespace SixLabors.ImageSharp.Formats.Pbm { case '1': // Plain PBM format: 1 component per pixel, boolean value ('0' or '1'). - this.ColorType = PbmColorType.BlackAndWhite; - this.Encoding = PbmEncoding.Plain; + this.colorType = PbmColorType.BlackAndWhite; + this.encoding = PbmEncoding.Plain; break; case '2': // Plain PGM format: 1 component per pixel, in decimal text. - this.ColorType = PbmColorType.Grayscale; - this.Encoding = PbmEncoding.Plain; + this.colorType = PbmColorType.Grayscale; + this.encoding = PbmEncoding.Plain; break; case '3': // Plain PPM format: 3 components per pixel, in decimal text. - this.ColorType = PbmColorType.Rgb; - this.Encoding = PbmEncoding.Plain; + this.colorType = PbmColorType.Rgb; + this.encoding = PbmEncoding.Plain; break; case '4': // Binary PBM format: 1 component per pixel, 8 pixels per byte. - this.ColorType = PbmColorType.BlackAndWhite; - this.Encoding = PbmEncoding.Binary; + this.colorType = PbmColorType.BlackAndWhite; + this.encoding = PbmEncoding.Binary; break; case '5': // Binary PGM format: 1 components per pixel, in binary integers. - this.ColorType = PbmColorType.Grayscale; - this.Encoding = PbmEncoding.Binary; + this.colorType = PbmColorType.Grayscale; + this.encoding = PbmEncoding.Binary; break; case '6': // Binary PPM format: 3 components per pixel, in binary integers. - this.ColorType = PbmColorType.Rgb; - this.Encoding = PbmEncoding.Binary; + this.colorType = PbmColorType.Rgb; + this.encoding = PbmEncoding.Binary; break; case '7': // PAM image: sequence of images. @@ -144,52 +151,54 @@ namespace SixLabors.ImageSharp.Formats.Pbm stream.SkipWhitespaceAndComments(); int height = stream.ReadDecimal(); stream.SkipWhitespaceAndComments(); - if (this.ColorType != PbmColorType.BlackAndWhite) + if (this.colorType != PbmColorType.BlackAndWhite) { this.maxPixelValue = stream.ReadDecimal(); if (this.maxPixelValue > 255) { - this.ComponentType = PbmComponentType.Short; + this.componentType = PbmComponentType.Short; } else { - this.ComponentType = PbmComponentType.Byte; + this.componentType = PbmComponentType.Byte; } stream.SkipWhitespaceAndComments(); } else { - this.ComponentType = PbmComponentType.Bit; + this.componentType = PbmComponentType.Bit; } - this.PixelSize = new Size(width, height); - this.Metadata = new ImageMetadata(); - PbmMetadata meta = this.Metadata.GetPbmMetadata(); - meta.Encoding = this.Encoding; - meta.ColorType = this.ColorType; - meta.ComponentType = this.ComponentType; + this.pixelSize = new Size(width, height); + this.metadata = new ImageMetadata(); + PbmMetadata meta = this.metadata.GetPbmMetadata(); + meta.Encoding = this.encoding; + meta.ColorType = this.colorType; + meta.ComponentType = this.componentType; } private void ProcessPixels(BufferedReadStream stream, Buffer2D pixels) where TPixel : unmanaged, IPixel { - if (this.Encoding == PbmEncoding.Binary) + if (this.encoding == PbmEncoding.Binary) { - BinaryDecoder.Process(this.Configuration, pixels, stream, this.ColorType, this.ComponentType); + BinaryDecoder.Process(this.configuration, pixels, stream, this.colorType, this.componentType); } else { - PlainDecoder.Process(this.Configuration, pixels, stream, this.ColorType, this.ComponentType); + PlainDecoder.Process(this.configuration, pixels, stream, this.colorType, this.componentType); } } private void ProcessUpscaling(Image image) where TPixel : unmanaged, IPixel { - int maxAllocationValue = this.ComponentType == PbmComponentType.Short ? 65535 : 255; + int maxAllocationValue = this.componentType == PbmComponentType.Short ? 65535 : 255; float factor = maxAllocationValue / this.maxPixelValue; image.Mutate(x => x.Brightness(factor)); } + + private bool NeedsUpscaling() => this.colorType != PbmColorType.BlackAndWhite && this.maxPixelValue is not 255 and not 65535; } } diff --git a/src/ImageSharp/Formats/Pbm/PbmDecoderOptions.cs b/src/ImageSharp/Formats/Pbm/PbmDecoderOptions.cs new file mode 100644 index 0000000000..c0b8856504 --- /dev/null +++ b/src/ImageSharp/Formats/Pbm/PbmDecoderOptions.cs @@ -0,0 +1,14 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +namespace SixLabors.ImageSharp.Formats.Pbm +{ + /// + /// Configuration options for decoding Pbm images. + /// + public sealed class PbmDecoderOptions : ISpecializedDecoderOptions + { + /// + public DecoderOptions GeneralOptions { get; set; } = new(); + } +}