mirror of https://github.com/SixLabors/ImageSharp
42 changed files with 524 additions and 437 deletions
@ -1,14 +0,0 @@ |
|||||
// Copyright (c) Six Labors.
|
|
||||
// Licensed under the Six Labors Split License.
|
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Formats.Gif |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Configuration options for decoding Gif images.
|
|
||||
/// </summary>
|
|
||||
public sealed class GifDecoderOptions : ISpecializedDecoderOptions |
|
||||
{ |
|
||||
/// <inheritdoc/>
|
|
||||
public DecoderOptions GeneralOptions { get; set; } = new(); |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,39 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Six Labors Split License.
|
||||
|
|
||||
|
using System.IO; |
||||
|
using System.Threading; |
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Formats |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The base class for all specialized image decoders.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The type of specialized options.</typeparam>
|
||||
|
public interface IImageDecoderSpecialized<T> : IImageDecoder |
||||
|
where T : ISpecializedDecoderOptions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Decodes the image from the specified stream to an <see cref="Image{TPixel}"/> of a specific pixel type.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
||||
|
/// <param name="options">The specialized decoder options.</param>
|
||||
|
/// <param name="stream">The <see cref="Stream"/> containing image data.</param>
|
||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
|
||||
|
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
||||
|
/// <exception cref="ImageFormatException">Thrown if the encoded image contains errors.</exception>
|
||||
|
public Image<TPixel> DecodeSpecialized<TPixel>(T options, Stream stream, CancellationToken cancellationToken) |
||||
|
where TPixel : unmanaged, IPixel<TPixel>; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Decodes the image from the specified stream to an <see cref="Image"/> of a specific pixel type.
|
||||
|
/// </summary>
|
||||
|
/// <param name="options">The specialized decoder options.</param>
|
||||
|
/// <param name="stream">The <see cref="Stream"/> containing image data.</param>
|
||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
|
||||
|
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
||||
|
/// <exception cref="ImageFormatException">Thrown if the encoded image contains errors.</exception>
|
||||
|
public Image DecodeSpecialized(T options, Stream stream, CancellationToken cancellationToken); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,65 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Six Labors Split License.
|
||||
|
|
||||
|
using System.IO; |
||||
|
using System.Threading; |
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
using SixLabors.ImageSharp.Processing; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Formats |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The base class for all image decoders.
|
||||
|
/// </summary>
|
||||
|
public abstract class ImageDecoder : IImageInfoDetector, IImageDecoder |
||||
|
{ |
||||
|
/// <inheritdoc/>
|
||||
|
public abstract IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken); |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public abstract Image<TPixel> Decode<TPixel>(DecoderOptions options, Stream stream, CancellationToken cancellationToken) |
||||
|
where TPixel : unmanaged, IPixel<TPixel>; |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public abstract Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Performs a resize operation against the decoded image. If the target size is not set, or the image size
|
||||
|
/// already matches the target size, the image is untouched.
|
||||
|
/// </summary>
|
||||
|
/// <param name="options">The decoder options.</param>
|
||||
|
/// <param name="image">The decoded image.</param>
|
||||
|
protected static void Resize(DecoderOptions options, Image image) |
||||
|
{ |
||||
|
if (ShouldResize(options, image)) |
||||
|
{ |
||||
|
ResizeOptions resizeOptions = new() |
||||
|
{ |
||||
|
Size = options.TargetSize.Value, |
||||
|
Sampler = KnownResamplers.Box, |
||||
|
Mode = ResizeMode.Max |
||||
|
}; |
||||
|
|
||||
|
image.Mutate(x => x.Resize(resizeOptions)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Determines whether the decoded image should be resized.
|
||||
|
/// </summary>
|
||||
|
/// <param name="options">The decoder options.</param>
|
||||
|
/// <param name="image">The decoded image.</param>
|
||||
|
/// <returns><see langword="true"/> if the image should be resized, otherwise; <see langword="false"/>.</returns>
|
||||
|
private static bool ShouldResize(DecoderOptions options, Image image) |
||||
|
{ |
||||
|
if (options.TargetSize is null) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
Size targetSize = options.TargetSize.Value; |
||||
|
Size currentSize = image.Size(); |
||||
|
return currentSize.Width != targetSize.Width && currentSize.Height != targetSize.Height; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,82 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Six Labors Split License.
|
||||
|
|
||||
|
using System.IO; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Formats |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Extensions methods for <see cref="IImageDecoderSpecialized{T}"/>.
|
||||
|
/// </summary>
|
||||
|
public static class ImageDecoderSpecializedExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Decodes the image from the specified stream to an <see cref="Image{TPixel}"/> of a specific pixel type.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The type of specialized options.</typeparam>
|
||||
|
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
||||
|
/// <param name="decoder">The decoder.</param>
|
||||
|
/// <param name="options">The specialized decoder options.</param>
|
||||
|
/// <param name="stream">The <see cref="Stream"/> containing image data.</param>
|
||||
|
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
||||
|
/// <exception cref="ImageFormatException">Thrown if the encoded image contains errors.</exception>
|
||||
|
public static Image<TPixel> DecodeSpecialized<T, TPixel>(this IImageDecoderSpecialized<T> decoder, T options, Stream stream) |
||||
|
where T : ISpecializedDecoderOptions |
||||
|
where TPixel : unmanaged, IPixel<TPixel> |
||||
|
=> decoder.DecodeSpecialized<TPixel>(options, stream, default); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Decodes the image from the specified stream to an <see cref="Image"/> of a specific pixel type.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The type of specialized options.</typeparam>
|
||||
|
/// <param name="decoder">The decoder.</param>
|
||||
|
/// <param name="options">The specialized decoder options.</param>
|
||||
|
/// <param name="stream">The <see cref="Stream"/> containing image data.</param>
|
||||
|
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
||||
|
/// <exception cref="ImageFormatException">Thrown if the encoded image contains errors.</exception>
|
||||
|
public static Image DecodeSpecialized<T>(this IImageDecoderSpecialized<T> decoder, T options, Stream stream) |
||||
|
where T : ISpecializedDecoderOptions |
||||
|
=> decoder.DecodeSpecialized(options, stream, default); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Decodes the image from the specified stream to an <see cref="Image{TPixel}"/> of a specific pixel type.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The type of specialized options.</typeparam>
|
||||
|
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
||||
|
/// <param name="decoder">The decoder.</param>
|
||||
|
/// <param name="options">The specialized decoder options.</param>
|
||||
|
/// <param name="stream">The <see cref="Stream"/> containing image data.</param>
|
||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
|
||||
|
/// <returns>A <see cref="Task{Image}"/> representing the asynchronous operation.</returns>
|
||||
|
/// <exception cref="ImageFormatException">Thrown if the encoded image contains errors.</exception>
|
||||
|
public static Task<Image<TPixel>> DecodeSpecializedAsync<T, TPixel>(this IImageDecoderSpecialized<T> decoder, T options, Stream stream, CancellationToken cancellationToken = default) |
||||
|
where T : ISpecializedDecoderOptions |
||||
|
where TPixel : unmanaged, IPixel<TPixel> |
||||
|
=> Image.WithSeekableStreamAsync( |
||||
|
options.GeneralOptions, |
||||
|
stream, |
||||
|
(s, ct) => decoder.DecodeSpecialized<TPixel>(options, s, ct), |
||||
|
cancellationToken); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Decodes the image from the specified stream to an <see cref="Image"/> of a specific pixel type.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The type of specialized options.</typeparam>
|
||||
|
/// <param name="decoder">The decoder.</param>
|
||||
|
/// <param name="options">The specialized decoder options.</param>
|
||||
|
/// <param name="stream">The <see cref="Stream"/> containing image data.</param>
|
||||
|
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
|
||||
|
/// <returns>A <see cref="Task{Image}"/> representing the asynchronous operation.</returns>
|
||||
|
/// <exception cref="ImageFormatException">Thrown if the encoded image contains errors.</exception>
|
||||
|
public static Task<Image> DecodeSpecializedAsync<T>(this IImageDecoderSpecialized<T> decoder, T options, Stream stream, CancellationToken cancellationToken = default) |
||||
|
where T : ISpecializedDecoderOptions |
||||
|
=> Image.WithSeekableStreamAsync( |
||||
|
options.GeneralOptions, |
||||
|
stream, |
||||
|
(s, ct) => decoder.DecodeSpecialized(options, s, ct), |
||||
|
cancellationToken); |
||||
|
} |
||||
|
} |
||||
@ -1,119 +0,0 @@ |
|||||
// Copyright (c) Six Labors.
|
|
||||
// Licensed under the Six Labors Split License.
|
|
||||
|
|
||||
using System.IO; |
|
||||
using System.Threading; |
|
||||
using SixLabors.ImageSharp.PixelFormats; |
|
||||
using SixLabors.ImageSharp.Processing; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Formats |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The base class for all image decoders.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="T">The type of specialized decoder options.</typeparam>
|
|
||||
public abstract class ImageDecoder<T> : IImageInfoDetector, IImageDecoder |
|
||||
where T : class, ISpecializedDecoderOptions, new() |
|
||||
{ |
|
||||
/// <inheritdoc/>
|
|
||||
public IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
T specializedOptions = new() { GeneralOptions = options }; |
|
||||
return this.IdentifySpecialized(specializedOptions, stream, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public Image<TPixel> Decode<TPixel>(DecoderOptions options, Stream stream, CancellationToken cancellationToken) |
|
||||
where TPixel : unmanaged, IPixel<TPixel> |
|
||||
{ |
|
||||
T specializedOptions = new() { GeneralOptions = options }; |
|
||||
Image<TPixel> image = this.DecodeSpecialized<TPixel>(specializedOptions, stream, cancellationToken); |
|
||||
|
|
||||
Resize(options, image); |
|
||||
|
|
||||
return image; |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc/>
|
|
||||
public Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
T specializedOptions = new() { GeneralOptions = options }; |
|
||||
Image image = this.DecodeSpecialized(specializedOptions, stream, cancellationToken); |
|
||||
|
|
||||
Resize(options, image); |
|
||||
|
|
||||
return image; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Reads the raw image information from the specified stream.
|
|
||||
/// </summary>
|
|
||||
/// <param name="options">The specialized decoder options.</param>
|
|
||||
/// <param name="stream">The <see cref="Stream"/> containing image data.</param>
|
|
||||
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
|
|
||||
/// <returns>The <see cref="IImageInfo"/> object.</returns>
|
|
||||
/// <exception cref="ImageFormatException">Thrown if the encoded image contains errors.</exception>
|
|
||||
public abstract IImageInfo IdentifySpecialized(T options, Stream stream, CancellationToken cancellationToken); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Decodes the image from the specified stream to an <see cref="Image{TPixel}"/> of a specific pixel type.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
||||
/// <param name="options">The specialized decoder options.</param>
|
|
||||
/// <param name="stream">The <see cref="Stream"/> containing image data.</param>
|
|
||||
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
/// <exception cref="ImageFormatException">Thrown if the encoded image contains errors.</exception>
|
|
||||
public abstract Image<TPixel> DecodeSpecialized<TPixel>(T options, Stream stream, CancellationToken cancellationToken) |
|
||||
where TPixel : unmanaged, IPixel<TPixel>; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Decodes the image from the specified stream to an <see cref="Image"/> of a specific pixel type.
|
|
||||
/// </summary>
|
|
||||
/// <param name="options">The specialized decoder options.</param>
|
|
||||
/// <param name="stream">The <see cref="Stream"/> containing image data.</param>
|
|
||||
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
|
|
||||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|
||||
/// <exception cref="ImageFormatException">Thrown if the encoded image contains errors.</exception>
|
|
||||
public abstract Image DecodeSpecialized(T options, Stream stream, CancellationToken cancellationToken); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Performs a resize operation against the decoded image. If the target size is not set, or the image size
|
|
||||
/// already matches the target size, the image is untouched.
|
|
||||
/// </summary>
|
|
||||
/// <param name="options">The decoder options.</param>
|
|
||||
/// <param name="image">The decoded image.</param>
|
|
||||
protected static void Resize(DecoderOptions options, Image image) |
|
||||
{ |
|
||||
if (ShouldResize(options, image)) |
|
||||
{ |
|
||||
ResizeOptions resizeOptions = new() |
|
||||
{ |
|
||||
Size = options.TargetSize.Value, |
|
||||
Sampler = KnownResamplers.Box, |
|
||||
Mode = ResizeMode.Max |
|
||||
}; |
|
||||
|
|
||||
image.Mutate(x => x.Resize(resizeOptions)); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Determines whether the decoded image should be resized.
|
|
||||
/// </summary>
|
|
||||
/// <param name="options">The decoder options.</param>
|
|
||||
/// <param name="image">The decoded image.</param>
|
|
||||
/// <returns><see langword="true"/> if the image should be resized, otherwise; <see langword="false"/>.</returns>
|
|
||||
private static bool ShouldResize(DecoderOptions options, Image image) |
|
||||
{ |
|
||||
if (options.TargetSize is null) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
Size targetSize = options.TargetSize.Value; |
|
||||
Size currentSize = image.Size(); |
|
||||
return currentSize.Width != targetSize.Width && currentSize.Height != targetSize.Height; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,27 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Six Labors Split License.
|
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Formats.Jpeg |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Provides enumeration for resize modes taken during decoding.
|
||||
|
/// Applicable only when <see cref="DecoderOptions.TargetSize"/> has a value.
|
||||
|
/// </summary>
|
||||
|
public enum JpegDecoderResizeMode |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Both <see cref="IdctOnly"/> and <see cref="ScaleOnly"/>.
|
||||
|
/// </summary>
|
||||
|
Combined, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// IDCT-only to nearest block scale.
|
||||
|
/// </summary>
|
||||
|
IdctOnly, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Opt-out the IDCT part and only Resize. Can be useful in case of quality concerns.
|
||||
|
/// </summary>
|
||||
|
ScaleOnly |
||||
|
} |
||||
|
} |
||||
@ -1,14 +0,0 @@ |
|||||
// Copyright (c) Six Labors.
|
|
||||
// Licensed under the Six Labors Split License.
|
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Formats.Pbm |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Configuration options for decoding Pbm images.
|
|
||||
/// </summary>
|
|
||||
public sealed class PbmDecoderOptions : ISpecializedDecoderOptions |
|
||||
{ |
|
||||
/// <inheritdoc/>
|
|
||||
public DecoderOptions GeneralOptions { get; set; } = new(); |
|
||||
} |
|
||||
} |
|
||||
@ -1,14 +0,0 @@ |
|||||
// Copyright (c) Six Labors.
|
|
||||
// Licensed under the Six Labors Split License.
|
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Formats.Png |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Configuration options for decoding Png images.
|
|
||||
/// </summary>
|
|
||||
public sealed class PngDecoderOptions : ISpecializedDecoderOptions |
|
||||
{ |
|
||||
/// <inheritdoc/>
|
|
||||
public DecoderOptions GeneralOptions { get; set; } = new(); |
|
||||
} |
|
||||
} |
|
||||
@ -1,14 +0,0 @@ |
|||||
// Copyright (c) Six Labors.
|
|
||||
// Licensed under the Six Labors Split License.
|
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Formats.Tga |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Configuration options for decoding Tga images.
|
|
||||
/// </summary>
|
|
||||
public sealed class TgaDecoderOptions : ISpecializedDecoderOptions |
|
||||
{ |
|
||||
/// <inheritdoc/>
|
|
||||
public DecoderOptions GeneralOptions { get; set; } = new(); |
|
||||
} |
|
||||
} |
|
||||
@ -1,14 +0,0 @@ |
|||||
// Copyright (c) Six Labors.
|
|
||||
// Licensed under the Six Labors Split License.
|
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Formats.Tiff |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Configuration options for decoding Tiff images.
|
|
||||
/// </summary>
|
|
||||
public sealed class TiffDecoderOptions : ISpecializedDecoderOptions |
|
||||
{ |
|
||||
/// <inheritdoc/>
|
|
||||
public DecoderOptions GeneralOptions { get; set; } = new(); |
|
||||
} |
|
||||
} |
|
||||
@ -1,14 +0,0 @@ |
|||||
// Copyright (c) Six Labors.
|
|
||||
// Licensed under the Six Labors Split License.
|
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Formats.Webp |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Configuration options for decoding Webp images.
|
|
||||
/// </summary>
|
|
||||
public sealed class WebpDecoderOptions : ISpecializedDecoderOptions |
|
||||
{ |
|
||||
/// <inheritdoc/>
|
|
||||
public DecoderOptions GeneralOptions { get; set; } = new(); |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue