mirror of https://github.com/SixLabors/ImageSharp
committed by
GitHub
179 changed files with 4556 additions and 2501 deletions
@ -1,20 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.Formats.Bmp; |
|||
using SixLabors.ImageSharp.Metadata; |
|||
|
|||
namespace SixLabors.ImageSharp; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="ImageMetadata"/> type.
|
|||
/// </summary>
|
|||
public static partial class MetadataExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the bmp format specific metadata for the image.
|
|||
/// </summary>
|
|||
/// <param name="metadata">The metadata this method extends.</param>
|
|||
/// <returns>The <see cref="BmpMetadata"/>.</returns>
|
|||
public static BmpMetadata GetBmpMetadata(this ImageMetadata metadata) => metadata.GetFormatMetadata(BmpFormat.Instance); |
|||
} |
|||
@ -1,16 +1,183 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.Formats.Bmp; |
|||
using SixLabors.ImageSharp.Formats.Icon; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Cur; |
|||
|
|||
/// <summary>
|
|||
/// Provides Ico specific metadata information for the image.
|
|||
/// Provides Cur specific metadata information for the image.
|
|||
/// </summary>
|
|||
public class CurMetadata : IDeepCloneable<CurMetadata>, IDeepCloneable |
|||
public class CurMetadata : IFormatMetadata<CurMetadata> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="CurMetadata"/> class.
|
|||
/// </summary>
|
|||
public CurMetadata() |
|||
{ |
|||
} |
|||
|
|||
private CurMetadata(CurMetadata other) |
|||
{ |
|||
this.Compression = other.Compression; |
|||
this.HotspotX = other.HotspotX; |
|||
this.HotspotY = other.HotspotY; |
|||
this.EncodingWidth = other.EncodingWidth; |
|||
this.EncodingHeight = other.EncodingHeight; |
|||
this.BmpBitsPerPixel = other.BmpBitsPerPixel; |
|||
|
|||
if (other.ColorTable?.Length > 0) |
|||
{ |
|||
this.ColorTable = other.ColorTable.Value.ToArray(); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the frame compressions format. Derived from the root frame.
|
|||
/// </summary>
|
|||
public IconFrameCompression Compression { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the horizontal coordinates of the hotspot in number of pixels from the left. Derived from the root frame.
|
|||
/// </summary>
|
|||
public ushort HotspotX { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the vertical coordinates of the hotspot in number of pixels from the top. Derived from the root frame.
|
|||
/// </summary>
|
|||
public ushort HotspotY { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the encoding width. <br />
|
|||
/// Can be any number between 0 and 255. Value 0 means a frame height of 256 pixels or greater. Derived from the root frame.
|
|||
/// </summary>
|
|||
public byte EncodingWidth { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the encoding height. <br />
|
|||
/// Can be any number between 0 and 255. Value 0 means a frame height of 256 pixels or greater. Derived from the root frame.
|
|||
/// </summary>
|
|||
public byte EncodingHeight { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the number of bits per pixel.<br/>
|
|||
/// Used when <see cref="Compression"/> is <see cref="IconFrameCompression.Bmp"/>
|
|||
/// </summary>
|
|||
public BmpBitsPerPixel BmpBitsPerPixel { get; set; } = BmpBitsPerPixel.Bit32; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the color table, if any. Derived from the root frame.<br/>
|
|||
/// The underlying pixel format is represented by <see cref="Bgr24"/>.
|
|||
/// </summary>
|
|||
public ReadOnlyMemory<Color>? ColorTable { get; set; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public CurMetadata DeepClone() => new(); |
|||
public static CurMetadata FromFormatConnectingMetadata(FormatConnectingMetadata metadata) |
|||
{ |
|||
int bpp = metadata.PixelTypeInfo.BitsPerPixel; |
|||
BmpBitsPerPixel bbpp = bpp switch |
|||
{ |
|||
1 => BmpBitsPerPixel.Bit1, |
|||
2 => BmpBitsPerPixel.Bit2, |
|||
<= 4 => BmpBitsPerPixel.Bit4, |
|||
<= 8 => BmpBitsPerPixel.Bit8, |
|||
<= 16 => BmpBitsPerPixel.Bit16, |
|||
<= 24 => BmpBitsPerPixel.Bit24, |
|||
_ => BmpBitsPerPixel.Bit32 |
|||
}; |
|||
|
|||
IconFrameCompression compression = IconFrameCompression.Bmp; |
|||
if (bbpp is BmpBitsPerPixel.Bit32) |
|||
{ |
|||
compression = IconFrameCompression.Png; |
|||
} |
|||
|
|||
return new CurMetadata |
|||
{ |
|||
BmpBitsPerPixel = bbpp, |
|||
Compression = compression, |
|||
ColorTable = compression == IconFrameCompression.Bmp ? metadata.ColorTable : null |
|||
}; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public PixelTypeInfo GetPixelTypeInfo() |
|||
{ |
|||
int bpp = (int)this.BmpBitsPerPixel; |
|||
PixelComponentInfo info; |
|||
PixelColorType color; |
|||
PixelAlphaRepresentation alpha = PixelAlphaRepresentation.None; |
|||
|
|||
if (this.Compression is IconFrameCompression.Png) |
|||
{ |
|||
bpp = 32; |
|||
info = PixelComponentInfo.Create(4, bpp, 8, 8, 8, 8); |
|||
color = PixelColorType.RGB | PixelColorType.Alpha; |
|||
alpha = PixelAlphaRepresentation.Unassociated; |
|||
} |
|||
else |
|||
{ |
|||
switch (this.BmpBitsPerPixel) |
|||
{ |
|||
case BmpBitsPerPixel.Bit1: |
|||
info = PixelComponentInfo.Create(1, bpp, 1); |
|||
color = PixelColorType.Binary; |
|||
break; |
|||
case BmpBitsPerPixel.Bit2: |
|||
info = PixelComponentInfo.Create(1, bpp, 2); |
|||
color = PixelColorType.Indexed; |
|||
break; |
|||
case BmpBitsPerPixel.Bit4: |
|||
info = PixelComponentInfo.Create(1, bpp, 4); |
|||
color = PixelColorType.Indexed; |
|||
break; |
|||
case BmpBitsPerPixel.Bit8: |
|||
info = PixelComponentInfo.Create(1, bpp, 8); |
|||
color = PixelColorType.Indexed; |
|||
break; |
|||
|
|||
// Could be 555 with padding but 565 is more common in newer bitmaps and offers
|
|||
// greater accuracy due to extra green precision.
|
|||
case BmpBitsPerPixel.Bit16: |
|||
info = PixelComponentInfo.Create(3, bpp, 5, 6, 5); |
|||
color = PixelColorType.RGB; |
|||
break; |
|||
case BmpBitsPerPixel.Bit24: |
|||
info = PixelComponentInfo.Create(3, bpp, 8, 8, 8); |
|||
color = PixelColorType.RGB; |
|||
break; |
|||
case BmpBitsPerPixel.Bit32 or _: |
|||
info = PixelComponentInfo.Create(4, bpp, 8, 8, 8, 8); |
|||
color = PixelColorType.RGB | PixelColorType.Alpha; |
|||
alpha = PixelAlphaRepresentation.Unassociated; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
return new PixelTypeInfo(bpp) |
|||
{ |
|||
AlphaRepresentation = alpha, |
|||
ComponentInfo = info, |
|||
ColorType = color |
|||
}; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public FormatConnectingMetadata ToFormatConnectingMetadata() |
|||
=> new() |
|||
{ |
|||
EncodingType = this.Compression == IconFrameCompression.Bmp && this.BmpBitsPerPixel <= BmpBitsPerPixel.Bit8 |
|||
? EncodingType.Lossy |
|||
: EncodingType.Lossless, |
|||
PixelTypeInfo = this.GetPixelTypeInfo(), |
|||
ColorTable = this.ColorTable |
|||
}; |
|||
|
|||
/// <inheritdoc/>
|
|||
IDeepCloneable IDeepCloneable.DeepClone() => this.DeepClone(); |
|||
|
|||
/// <inheritdoc/>
|
|||
public CurMetadata DeepClone() => new(this); |
|||
} |
|||
|
|||
@ -1,45 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using System.Diagnostics.CodeAnalysis; |
|||
using SixLabors.ImageSharp.Formats.Cur; |
|||
using SixLabors.ImageSharp.Metadata; |
|||
|
|||
namespace SixLabors.ImageSharp; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="ImageMetadata"/> type.
|
|||
/// </summary>
|
|||
public static partial class MetadataExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the Icon format specific metadata for the image.
|
|||
/// </summary>
|
|||
/// <param name="source">The metadata this method extends.</param>
|
|||
/// <returns>The <see cref="CurMetadata"/>.</returns>
|
|||
public static CurMetadata GetCurMetadata(this ImageMetadata source) |
|||
=> source.GetFormatMetadata(CurFormat.Instance); |
|||
|
|||
/// <summary>
|
|||
/// Gets the Icon format specific metadata for the image frame.
|
|||
/// </summary>
|
|||
/// <param name="source">The metadata this method extends.</param>
|
|||
/// <returns>The <see cref="CurFrameMetadata"/>.</returns>
|
|||
public static CurFrameMetadata GetCurMetadata(this ImageFrameMetadata source) |
|||
=> source.GetFormatMetadata(CurFormat.Instance); |
|||
|
|||
/// <summary>
|
|||
/// Gets the Icon format specific metadata for the image frame.
|
|||
/// </summary>
|
|||
/// <param name="source">The metadata this method extends.</param>
|
|||
/// <param name="metadata">
|
|||
/// When this method returns, contains the metadata associated with the specified frame,
|
|||
/// if found; otherwise, the default value for the type of the metadata parameter.
|
|||
/// This parameter is passed uninitialized.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// <see langword="true"/> if the Icon frame metadata exists; otherwise, <see langword="false"/>.
|
|||
/// </returns>
|
|||
public static bool TryGetCurMetadata(this ImageFrameMetadata source, [NotNullWhen(true)] out CurFrameMetadata? metadata) |
|||
=> source.TryGetFormatMetadata(CurFormat.Instance, out metadata); |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats; |
|||
|
|||
/// <summary>
|
|||
/// Provides a way to specify the type of encoding to be used.
|
|||
/// </summary>
|
|||
public enum EncodingType |
|||
{ |
|||
/// <summary>
|
|||
/// Lossless encoding, which compresses data without any loss of information.
|
|||
/// </summary>
|
|||
Lossless, |
|||
|
|||
/// <summary>
|
|||
/// Lossy encoding, which compresses data by discarding some of it.
|
|||
/// </summary>
|
|||
Lossy |
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats; |
|||
|
|||
/// <summary>
|
|||
/// A metadata format designed to allow conversion between different image format frames.
|
|||
/// </summary>
|
|||
public class FormatConnectingFrameMetadata |
|||
{ |
|||
/// <summary>
|
|||
/// Gets information about the encoded pixel type if any.
|
|||
/// </summary>
|
|||
public PixelTypeInfo? PixelTypeInfo { get; init; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the frame color table if any.
|
|||
/// </summary>
|
|||
public ReadOnlyMemory<Color>? ColorTable { get; init; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the frame color table mode.
|
|||
/// </summary>
|
|||
public FrameColorTableMode ColorTableMode { get; init; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the duration of the frame.
|
|||
/// </summary>
|
|||
public TimeSpan Duration { get; init; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the frame alpha blending mode.
|
|||
/// </summary>
|
|||
public FrameBlendMode BlendMode { get; init; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the frame disposal mode.
|
|||
/// </summary>
|
|||
public FrameDisposalMode DisposalMode { get; init; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the encoding width. <br />
|
|||
/// Used for formats that require a specific frame size.
|
|||
/// </summary>
|
|||
public int? EncodingWidth { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the encoding height. <br />
|
|||
/// Used for formats that require a specific frame size.
|
|||
/// </summary>
|
|||
public int? EncodingHeight { get; set; } |
|||
} |
|||
@ -0,0 +1,70 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats; |
|||
|
|||
/// <summary>
|
|||
/// A metadata format designed to allow conversion between different image formats.
|
|||
/// </summary>
|
|||
public class FormatConnectingMetadata |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the encoding type.
|
|||
/// </summary>
|
|||
public EncodingType EncodingType { get; init; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the quality to use when <see cref="EncodingType"/> is <see cref="EncodingType.Lossy"/>.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// The value is usually between 1 and 100. Defaults to 100.
|
|||
/// </remarks>
|
|||
public int Quality { get; init; } = 100; |
|||
|
|||
/// <summary>
|
|||
/// Gets information about the encoded pixel type.
|
|||
/// </summary>
|
|||
public PixelTypeInfo PixelTypeInfo { get; init; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the shared color table if any.
|
|||
/// </summary>
|
|||
public ReadOnlyMemory<Color>? ColorTable { get; init; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the shared color table mode.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// Defaults to <see cref="FrameColorTableMode.Global"/>.
|
|||
/// </remarks>
|
|||
public FrameColorTableMode ColorTableMode { get; init; } = FrameColorTableMode.Global; |
|||
|
|||
/// <summary>
|
|||
/// Gets the default background color of the canvas when animating.
|
|||
/// This color may be used to fill the unused space on the canvas around the frames,
|
|||
/// as well as the transparent pixels of the first frame.
|
|||
/// The background color is also used when the disposal mode is <see cref="FrameDisposalMode.RestoreToBackground"/>.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// Defaults to <see cref="Color.Transparent"/>.
|
|||
/// </remarks>
|
|||
public Color BackgroundColor { get; init; } = Color.Transparent; |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of times any animation is repeated.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// 0 means to repeat indefinitely, count is set as repeat n-1 times. Defaults to 1.
|
|||
/// </remarks>
|
|||
public ushort RepeatCount { get; init; } = 1; |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether the root frame is shown as part of the animated sequence.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// Defaults to <see langword="true"/>.
|
|||
/// </remarks>
|
|||
public bool AnimateRootFrame { get; init; } = true; |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats; |
|||
|
|||
/// <summary>
|
|||
/// Provides a way to specify how the current frame should be blended with the previous frame in the animation sequence.
|
|||
/// </summary>
|
|||
public enum FrameBlendMode |
|||
{ |
|||
/// <summary>
|
|||
/// Do not blend. Render the current frame on the canvas by overwriting the rectangle covered by the current frame.
|
|||
/// </summary>
|
|||
Source = 0, |
|||
|
|||
/// <summary>
|
|||
/// Blend the current frame with the previous frame in the animation sequence within the rectangle covered
|
|||
/// by the current frame.
|
|||
/// If the current has any transparent areas, the corresponding areas of the previous frame will be visible
|
|||
/// through these transparent regions.
|
|||
/// </summary>
|
|||
Over = 1 |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats; |
|||
|
|||
/// <summary>
|
|||
/// Provides a way to specify how the color table is used by the frame.
|
|||
/// </summary>
|
|||
public enum FrameColorTableMode |
|||
{ |
|||
/// <summary>
|
|||
/// The frame uses the shared color table specified by the image metadata.
|
|||
/// </summary>
|
|||
Global, |
|||
|
|||
/// <summary>
|
|||
/// The frame uses a color table specified by the frame metadata.
|
|||
/// </summary>
|
|||
Local |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats; |
|||
|
|||
/// <summary>
|
|||
/// Provides a way to specify how the current frame should be disposed of before rendering the next frame.
|
|||
/// </summary>
|
|||
public enum FrameDisposalMode |
|||
{ |
|||
/// <summary>
|
|||
/// No disposal specified.
|
|||
/// The decoder is not required to take any action.
|
|||
/// </summary>
|
|||
Unspecified = 0, |
|||
|
|||
/// <summary>
|
|||
/// Do not dispose. The current frame is not disposed of, or in other words, not cleared or altered when moving to
|
|||
/// the next frame. This means that the next frame is drawn over the current frame, and if the next frame contains
|
|||
/// transparency, the previous frame will be visible through these transparent areas.
|
|||
/// </summary>
|
|||
DoNotDispose = 1, |
|||
|
|||
/// <summary>
|
|||
/// Restore to background color. When transitioning to the next frame, the area occupied by the current frame is
|
|||
/// filled with the background color specified in the image metadata.
|
|||
/// This effectively erases the current frame by replacing it with the background color before the next frame is displayed.
|
|||
/// </summary>
|
|||
RestoreToBackground = 2, |
|||
|
|||
/// <summary>
|
|||
/// Restore to previous. This method restores the area affected by the current frame to what it was before the
|
|||
/// current frame was displayed. It essentially "undoes" the current frame, reverting to the state of the image
|
|||
/// before the frame was displayed, then the next frame is drawn. This is useful for animations where only a small
|
|||
/// part of the image changes from frame to frame.
|
|||
/// </summary>
|
|||
RestoreToPrevious = 3 |
|||
} |
|||
@ -1,20 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Gif; |
|||
|
|||
/// <summary>
|
|||
/// Provides enumeration for the available color table modes.
|
|||
/// </summary>
|
|||
public enum GifColorTableMode |
|||
{ |
|||
/// <summary>
|
|||
/// A single color table is calculated from the first frame and reused for subsequent frames.
|
|||
/// </summary>
|
|||
Global, |
|||
|
|||
/// <summary>
|
|||
/// A unique color table is calculated for each frame.
|
|||
/// </summary>
|
|||
Local |
|||
} |
|||
@ -1,37 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Gif; |
|||
|
|||
/// <summary>
|
|||
/// Provides enumeration for instructing the decoder what to do with the last image
|
|||
/// in an animation sequence.
|
|||
/// <see href="http://www.w3.org/Graphics/GIF/spec-gif89a.txt"/> section 23
|
|||
/// </summary>
|
|||
public enum GifDisposalMethod |
|||
{ |
|||
/// <summary>
|
|||
/// No disposal specified.
|
|||
/// The decoder is not required to take any action.
|
|||
/// </summary>
|
|||
Unspecified = 0, |
|||
|
|||
/// <summary>
|
|||
/// Do not dispose.
|
|||
/// The graphic is to be left in place.
|
|||
/// </summary>
|
|||
NotDispose = 1, |
|||
|
|||
/// <summary>
|
|||
/// Restore to background color.
|
|||
/// The area used by the graphic must be restored to the background color.
|
|||
/// </summary>
|
|||
RestoreToBackground = 2, |
|||
|
|||
/// <summary>
|
|||
/// Restore to previous.
|
|||
/// The decoder is required to restore the area overwritten by the
|
|||
/// graphic with what was there prior to rendering the graphic.
|
|||
/// </summary>
|
|||
RestoreToPrevious = 3 |
|||
} |
|||
@ -1,105 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using System.Diagnostics.CodeAnalysis; |
|||
using SixLabors.ImageSharp.Formats; |
|||
using SixLabors.ImageSharp.Formats.Gif; |
|||
using SixLabors.ImageSharp.Metadata; |
|||
|
|||
namespace SixLabors.ImageSharp; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="ImageMetadata"/> type.
|
|||
/// </summary>
|
|||
public static partial class MetadataExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the gif format specific metadata for the image.
|
|||
/// </summary>
|
|||
/// <param name="source">The metadata this method extends.</param>
|
|||
/// <returns>The <see cref="GifMetadata"/>.</returns>
|
|||
public static GifMetadata GetGifMetadata(this ImageMetadata source) |
|||
=> source.GetFormatMetadata(GifFormat.Instance); |
|||
|
|||
/// <summary>
|
|||
/// Gets the gif format specific metadata for the image.
|
|||
/// </summary>
|
|||
/// <param name="source">The metadata this method extends.</param>
|
|||
/// <param name="metadata">
|
|||
/// When this method returns, contains the metadata associated with the specified image,
|
|||
/// if found; otherwise, the default value for the type of the metadata parameter.
|
|||
/// This parameter is passed uninitialized.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// <see langword="true"/> if the gif metadata exists; otherwise, <see langword="false"/>.
|
|||
/// </returns>
|
|||
public static bool TryGetGifMetadata(this ImageMetadata source, [NotNullWhen(true)] out GifMetadata? metadata) |
|||
=> source.TryGetFormatMetadata(GifFormat.Instance, out metadata); |
|||
|
|||
/// <summary>
|
|||
/// Gets the gif format specific metadata for the image frame.
|
|||
/// </summary>
|
|||
/// <param name="source">The metadata this method extends.</param>
|
|||
/// <returns>The <see cref="GifFrameMetadata"/>.</returns>
|
|||
public static GifFrameMetadata GetGifMetadata(this ImageFrameMetadata source) |
|||
=> source.GetFormatMetadata(GifFormat.Instance); |
|||
|
|||
/// <summary>
|
|||
/// Gets the gif format specific metadata for the image frame.
|
|||
/// </summary>
|
|||
/// <param name="source">The metadata this method extends.</param>
|
|||
/// <param name="metadata">
|
|||
/// When this method returns, contains the metadata associated with the specified frame,
|
|||
/// if found; otherwise, the default value for the type of the metadata parameter.
|
|||
/// This parameter is passed uninitialized.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// <see langword="true"/> if the gif frame metadata exists; otherwise, <see langword="false"/>.
|
|||
/// </returns>
|
|||
public static bool TryGetGifMetadata(this ImageFrameMetadata source, [NotNullWhen(true)] out GifFrameMetadata? metadata) |
|||
=> source.TryGetFormatMetadata(GifFormat.Instance, out metadata); |
|||
|
|||
internal static AnimatedImageMetadata ToAnimatedImageMetadata(this GifMetadata source) |
|||
{ |
|||
Color background = Color.Transparent; |
|||
if (source.GlobalColorTable != null) |
|||
{ |
|||
background = source.GlobalColorTable.Value.Span[source.BackgroundColorIndex]; |
|||
} |
|||
|
|||
return new() |
|||
{ |
|||
ColorTable = source.GlobalColorTable, |
|||
ColorTableMode = source.ColorTableMode == GifColorTableMode.Global ? FrameColorTableMode.Global : FrameColorTableMode.Local, |
|||
RepeatCount = source.RepeatCount, |
|||
BackgroundColor = background, |
|||
}; |
|||
} |
|||
|
|||
internal static AnimatedImageFrameMetadata ToAnimatedImageFrameMetadata(this GifFrameMetadata source) |
|||
{ |
|||
// For most scenarios we would consider the blend method to be 'Over' however if a frame has a disposal method of 'RestoreToBackground' or
|
|||
// has a local palette with 256 colors and is not transparent we should use 'Source'.
|
|||
bool blendSource = source.DisposalMethod == GifDisposalMethod.RestoreToBackground || (source.LocalColorTable?.Length == 256 && !source.HasTransparency); |
|||
|
|||
// If the color table is global and frame has no transparency. Consider it 'Source' also.
|
|||
blendSource |= source.ColorTableMode == GifColorTableMode.Global && !source.HasTransparency; |
|||
|
|||
return new() |
|||
{ |
|||
ColorTable = source.LocalColorTable, |
|||
ColorTableMode = source.ColorTableMode == GifColorTableMode.Global ? FrameColorTableMode.Global : FrameColorTableMode.Local, |
|||
Duration = TimeSpan.FromMilliseconds(source.FrameDelay * 10), |
|||
DisposalMode = GetMode(source.DisposalMethod), |
|||
BlendMode = blendSource ? FrameBlendMode.Source : FrameBlendMode.Over, |
|||
}; |
|||
} |
|||
|
|||
private static FrameDisposalMode GetMode(GifDisposalMethod method) => method switch |
|||
{ |
|||
GifDisposalMethod.NotDispose => FrameDisposalMode.DoNotDispose, |
|||
GifDisposalMethod.RestoreToBackground => FrameDisposalMode.RestoreToBackground, |
|||
GifDisposalMethod.RestoreToPrevious => FrameDisposalMode.RestoreToPrevious, |
|||
_ => FrameDisposalMode.Unspecified, |
|||
}; |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats; |
|||
|
|||
/// <summary>
|
|||
/// An interface that provides metadata for a specific image format frames.
|
|||
/// </summary>
|
|||
public interface IFormatFrameMetadata : IDeepCloneable |
|||
{ |
|||
/// <summary>
|
|||
/// Converts the metadata to a <see cref="FormatConnectingFrameMetadata"/> instance.
|
|||
/// </summary>
|
|||
/// <returns>The <see cref="FormatConnectingFrameMetadata"/>.</returns>
|
|||
FormatConnectingFrameMetadata ToFormatConnectingFrameMetadata(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// An interface that provides metadata for a specific image format frames.
|
|||
/// </summary>
|
|||
/// <typeparam name="TSelf">The metadata type implementing this interface.</typeparam>
|
|||
public interface IFormatFrameMetadata<TSelf> : IFormatFrameMetadata, IDeepCloneable<TSelf> |
|||
where TSelf : class, IFormatFrameMetadata |
|||
{ |
|||
/// <summary>
|
|||
/// Creates a new instance of the <typeparamref name="TSelf"/> class from the given <see cref="FormatConnectingFrameMetadata"/>.
|
|||
/// </summary>
|
|||
/// <param name="metadata">The <see cref="FormatConnectingFrameMetadata"/>.</param>
|
|||
/// <returns>The <typeparamref name="TSelf"/>.</returns>
|
|||
#pragma warning disable CA1000 // Do not declare static members on generic types
|
|||
static abstract TSelf FromFormatConnectingFrameMetadata(FormatConnectingFrameMetadata metadata); |
|||
#pragma warning restore CA1000 // Do not declare static members on generic types
|
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats; |
|||
|
|||
/// <summary>
|
|||
/// An interface that provides metadata for a specific image format.
|
|||
/// </summary>
|
|||
public interface IFormatMetadata : IDeepCloneable |
|||
{ |
|||
/// <summary>
|
|||
/// Converts the metadata to a <see cref="PixelTypeInfo"/> instance.
|
|||
/// </summary>
|
|||
/// <returns>The pixel type info.</returns>
|
|||
PixelTypeInfo GetPixelTypeInfo(); |
|||
|
|||
/// <summary>
|
|||
/// Converts the metadata to a <see cref="FormatConnectingMetadata"/> instance.
|
|||
/// </summary>
|
|||
/// <returns>The <see cref="FormatConnectingMetadata"/>.</returns>
|
|||
FormatConnectingMetadata ToFormatConnectingMetadata(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// An interface that provides metadata for a specific image format.
|
|||
/// </summary>
|
|||
/// <typeparam name="TSelf">The metadata type implementing this interface.</typeparam>
|
|||
public interface IFormatMetadata<TSelf> : IFormatMetadata, IDeepCloneable<TSelf> |
|||
where TSelf : class, IFormatMetadata |
|||
{ |
|||
/// <summary>
|
|||
/// Creates a new instance of the <typeparamref name="TSelf"/> class from the given <see cref="FormatConnectingMetadata"/>.
|
|||
/// </summary>
|
|||
/// <param name="metadata">The <see cref="FormatConnectingMetadata"/>.</param>
|
|||
/// <returns>The <typeparamref name="TSelf"/>.</returns>
|
|||
#pragma warning disable CA1000 // Do not declare static members on generic types
|
|||
static abstract TSelf FromFormatConnectingMetadata(FormatConnectingMetadata metadata); |
|||
#pragma warning restore CA1000 // Do not declare static members on generic types
|
|||
} |
|||
@ -1,50 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.IO; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats; |
|||
|
|||
/// <summary>
|
|||
/// Abstraction for shared internals for XXXDecoderCore implementations to be used with <see cref="ImageDecoderUtilities"/>.
|
|||
/// </summary>
|
|||
internal interface IImageDecoderInternals |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the general decoder options.
|
|||
/// </summary>
|
|||
DecoderOptions Options { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the dimensions of the image being decoded.
|
|||
/// </summary>
|
|||
Size Dimensions { get; } |
|||
|
|||
/// <summary>
|
|||
/// Decodes the image from the specified stream.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
/// <param name="stream">The stream, where the image should be decoded from. Cannot be null.</param>
|
|||
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
|
|||
/// <exception cref="ArgumentNullException"><paramref name="stream"/> is null.</exception>
|
|||
/// <returns>The decoded image.</returns>
|
|||
/// <remarks>
|
|||
/// Cancellable synchronous method. In case of cancellation,
|
|||
/// an <see cref="OperationCanceledException"/> shall be thrown which will be handled on the call site.
|
|||
/// </remarks>
|
|||
Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken cancellationToken) |
|||
where TPixel : unmanaged, IPixel<TPixel>; |
|||
|
|||
/// <summary>
|
|||
/// Reads the raw image information from the specified stream.
|
|||
/// </summary>
|
|||
/// <param name="stream">The <see cref="BufferedReadStream"/> containing image data.</param>
|
|||
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
|
|||
/// <returns>The <see cref="ImageInfo"/>.</returns>
|
|||
/// <remarks>
|
|||
/// Cancellable synchronous method. In case of cancellation,
|
|||
/// an <see cref="OperationCanceledException"/> shall be thrown which will be handled on the call site.
|
|||
/// </remarks>
|
|||
ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken); |
|||
} |
|||
@ -1,22 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats; |
|||
|
|||
/// <summary>
|
|||
/// Abstraction for shared internals for ***DecoderCore implementations.
|
|||
/// </summary>
|
|||
internal interface IImageEncoderInternals |
|||
{ |
|||
/// <summary>
|
|||
/// Encodes the image.
|
|||
/// </summary>
|
|||
/// <param name="image">The image.</param>
|
|||
/// <param name="stream">The stream.</param>
|
|||
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
|
|||
/// <typeparam name="TPixel">The pixel type.</typeparam>
|
|||
void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken) |
|||
where TPixel : unmanaged, IPixel<TPixel>; |
|||
} |
|||
@ -1,16 +1,171 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.Formats.Bmp; |
|||
using SixLabors.ImageSharp.Formats.Icon; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Ico; |
|||
|
|||
/// <summary>
|
|||
/// Provides Ico specific metadata information for the image.
|
|||
/// </summary>
|
|||
public class IcoMetadata : IDeepCloneable<IcoMetadata>, IDeepCloneable |
|||
public class IcoMetadata : IFormatMetadata<IcoMetadata> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IcoMetadata"/> class.
|
|||
/// </summary>
|
|||
public IcoMetadata() |
|||
{ |
|||
} |
|||
|
|||
private IcoMetadata(IcoMetadata other) |
|||
{ |
|||
this.Compression = other.Compression; |
|||
this.EncodingWidth = other.EncodingWidth; |
|||
this.EncodingHeight = other.EncodingHeight; |
|||
this.BmpBitsPerPixel = other.BmpBitsPerPixel; |
|||
|
|||
if (other.ColorTable?.Length > 0) |
|||
{ |
|||
this.ColorTable = other.ColorTable.Value.ToArray(); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the frame compressions format. Derived from the root frame.
|
|||
/// </summary>
|
|||
public IconFrameCompression Compression { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the encoding width. <br />
|
|||
/// Can be any number between 0 and 255. Value 0 means a frame height of 256 pixels or greater. Derived from the root frame.
|
|||
/// </summary>
|
|||
public byte EncodingWidth { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the encoding height. <br />
|
|||
/// Can be any number between 0 and 255. Value 0 means a frame height of 256 pixels or greater. Derived from the root frame.
|
|||
/// </summary>
|
|||
public byte EncodingHeight { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the number of bits per pixel.<br/>
|
|||
/// Used when <see cref="Compression"/> is <see cref="IconFrameCompression.Bmp"/>
|
|||
/// </summary>
|
|||
public BmpBitsPerPixel BmpBitsPerPixel { get; set; } = BmpBitsPerPixel.Bit32; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the color table, if any. Derived from the root frame.<br/>
|
|||
/// The underlying pixel format is represented by <see cref="Bgr24"/>.
|
|||
/// </summary>
|
|||
public ReadOnlyMemory<Color>? ColorTable { get; set; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public static IcoMetadata FromFormatConnectingMetadata(FormatConnectingMetadata metadata) |
|||
{ |
|||
int bpp = metadata.PixelTypeInfo.BitsPerPixel; |
|||
BmpBitsPerPixel bbpp = bpp switch |
|||
{ |
|||
1 => BmpBitsPerPixel.Bit1, |
|||
2 => BmpBitsPerPixel.Bit2, |
|||
<= 4 => BmpBitsPerPixel.Bit4, |
|||
<= 8 => BmpBitsPerPixel.Bit8, |
|||
<= 16 => BmpBitsPerPixel.Bit16, |
|||
<= 24 => BmpBitsPerPixel.Bit24, |
|||
_ => BmpBitsPerPixel.Bit32 |
|||
}; |
|||
|
|||
IconFrameCompression compression = IconFrameCompression.Bmp; |
|||
if (bbpp is BmpBitsPerPixel.Bit32) |
|||
{ |
|||
compression = IconFrameCompression.Png; |
|||
} |
|||
|
|||
return new IcoMetadata |
|||
{ |
|||
BmpBitsPerPixel = bbpp, |
|||
Compression = compression, |
|||
ColorTable = compression == IconFrameCompression.Bmp ? metadata.ColorTable : null |
|||
}; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public PixelTypeInfo GetPixelTypeInfo() |
|||
{ |
|||
int bpp = (int)this.BmpBitsPerPixel; |
|||
PixelComponentInfo info; |
|||
PixelColorType color; |
|||
PixelAlphaRepresentation alpha = PixelAlphaRepresentation.None; |
|||
|
|||
if (this.Compression is IconFrameCompression.Png) |
|||
{ |
|||
bpp = 32; |
|||
info = PixelComponentInfo.Create(4, bpp, 8, 8, 8, 8); |
|||
color = PixelColorType.RGB | PixelColorType.Alpha; |
|||
alpha = PixelAlphaRepresentation.Unassociated; |
|||
} |
|||
else |
|||
{ |
|||
switch (this.BmpBitsPerPixel) |
|||
{ |
|||
case BmpBitsPerPixel.Bit1: |
|||
info = PixelComponentInfo.Create(1, bpp, 1); |
|||
color = PixelColorType.Binary; |
|||
break; |
|||
case BmpBitsPerPixel.Bit2: |
|||
info = PixelComponentInfo.Create(1, bpp, 2); |
|||
color = PixelColorType.Indexed; |
|||
break; |
|||
case BmpBitsPerPixel.Bit4: |
|||
info = PixelComponentInfo.Create(1, bpp, 4); |
|||
color = PixelColorType.Indexed; |
|||
break; |
|||
case BmpBitsPerPixel.Bit8: |
|||
info = PixelComponentInfo.Create(1, bpp, 8); |
|||
color = PixelColorType.Indexed; |
|||
break; |
|||
|
|||
// Could be 555 with padding but 565 is more common in newer bitmaps and offers
|
|||
// greater accuracy due to extra green precision.
|
|||
case BmpBitsPerPixel.Bit16: |
|||
info = PixelComponentInfo.Create(3, bpp, 5, 6, 5); |
|||
color = PixelColorType.RGB; |
|||
break; |
|||
case BmpBitsPerPixel.Bit24: |
|||
info = PixelComponentInfo.Create(3, bpp, 8, 8, 8); |
|||
color = PixelColorType.RGB; |
|||
break; |
|||
case BmpBitsPerPixel.Bit32 or _: |
|||
info = PixelComponentInfo.Create(4, bpp, 8, 8, 8, 8); |
|||
color = PixelColorType.RGB | PixelColorType.Alpha; |
|||
alpha = PixelAlphaRepresentation.Unassociated; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
return new PixelTypeInfo(bpp) |
|||
{ |
|||
AlphaRepresentation = alpha, |
|||
ComponentInfo = info, |
|||
ColorType = color |
|||
}; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public IcoMetadata DeepClone() => new(); |
|||
public FormatConnectingMetadata ToFormatConnectingMetadata() |
|||
=> new() |
|||
{ |
|||
EncodingType = this.Compression == IconFrameCompression.Bmp && this.BmpBitsPerPixel <= BmpBitsPerPixel.Bit8 |
|||
? EncodingType.Lossy |
|||
: EncodingType.Lossless, |
|||
PixelTypeInfo = this.GetPixelTypeInfo(), |
|||
ColorTable = this.ColorTable |
|||
}; |
|||
|
|||
/// <inheritdoc/>
|
|||
IDeepCloneable IDeepCloneable.DeepClone() => this.DeepClone(); |
|||
|
|||
/// <inheritdoc/>
|
|||
public IcoMetadata DeepClone() => new(this); |
|||
} |
|||
|
|||
@ -1,45 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using System.Diagnostics.CodeAnalysis; |
|||
using SixLabors.ImageSharp.Formats.Ico; |
|||
using SixLabors.ImageSharp.Metadata; |
|||
|
|||
namespace SixLabors.ImageSharp; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="ImageMetadata"/> type.
|
|||
/// </summary>
|
|||
public static partial class MetadataExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the Ico format specific metadata for the image.
|
|||
/// </summary>
|
|||
/// <param name="source">The metadata this method extends.</param>
|
|||
/// <returns>The <see cref="IcoMetadata"/>.</returns>
|
|||
public static IcoMetadata GetIcoMetadata(this ImageMetadata source) |
|||
=> source.GetFormatMetadata(IcoFormat.Instance); |
|||
|
|||
/// <summary>
|
|||
/// Gets the Ico format specific metadata for the image frame.
|
|||
/// </summary>
|
|||
/// <param name="source">The metadata this method extends.</param>
|
|||
/// <returns>The <see cref="IcoFrameMetadata"/>.</returns>
|
|||
public static IcoFrameMetadata GetIcoMetadata(this ImageFrameMetadata source) |
|||
=> source.GetFormatMetadata(IcoFormat.Instance); |
|||
|
|||
/// <summary>
|
|||
/// Gets the Ico format specific metadata for the image frame.
|
|||
/// </summary>
|
|||
/// <param name="source">The metadata this method extends.</param>
|
|||
/// <param name="metadata">
|
|||
/// When this method returns, contains the metadata associated with the specified frame,
|
|||
/// if found; otherwise, the default value for the type of the metadata parameter.
|
|||
/// This parameter is passed uninitialized.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// <see langword="true"/> if the Ico frame metadata exists; otherwise, <see langword="false"/>.
|
|||
/// </returns>
|
|||
public static bool TryGetIcoMetadata(this ImageFrameMetadata source, [NotNullWhen(true)] out IcoFrameMetadata? metadata) |
|||
=> source.TryGetFormatMetadata(IcoFormat.Instance, out metadata); |
|||
} |
|||
@ -0,0 +1,127 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.IO; |
|||
using SixLabors.ImageSharp.Memory; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats; |
|||
|
|||
/// <summary>
|
|||
/// The base class for all stateful image decoders.
|
|||
/// </summary>
|
|||
internal abstract class ImageDecoderCore |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ImageDecoderCore"/> class.
|
|||
/// </summary>
|
|||
/// <param name="options">The general decoder options.</param>
|
|||
protected ImageDecoderCore(DecoderOptions options) |
|||
=> this.Options = options; |
|||
|
|||
/// <summary>
|
|||
/// Gets the general decoder options.
|
|||
/// </summary>
|
|||
public DecoderOptions Options { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the dimensions of the image being decoded.
|
|||
/// </summary>
|
|||
public Size Dimensions { get; protected internal set; } |
|||
|
|||
/// <summary>
|
|||
/// Reads the raw image information from the specified stream.
|
|||
/// </summary>
|
|||
/// <param name="configuration">The shared configuration.</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="ImageInfo" />.</returns>
|
|||
/// <exception cref="InvalidImageContentException">Thrown if the encoded image contains errors.</exception>
|
|||
public ImageInfo Identify( |
|||
Configuration configuration, |
|||
Stream stream, |
|||
CancellationToken cancellationToken) |
|||
{ |
|||
using BufferedReadStream bufferedReadStream = new(configuration, stream, cancellationToken); |
|||
|
|||
try |
|||
{ |
|||
return this.Identify(bufferedReadStream, cancellationToken); |
|||
} |
|||
catch (InvalidMemoryOperationException ex) |
|||
{ |
|||
throw new InvalidImageContentException(this.Dimensions, ex); |
|||
} |
|||
catch (Exception) |
|||
{ |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
/// <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="configuration">The shared configuration.</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="InvalidImageContentException">Thrown if the encoded image contains errors.</exception>
|
|||
public Image<TPixel> Decode<TPixel>( |
|||
Configuration configuration, |
|||
Stream stream, |
|||
CancellationToken cancellationToken) |
|||
where TPixel : unmanaged, IPixel<TPixel> |
|||
{ |
|||
// Test may pass a BufferedReadStream in order to monitor EOF hits, if so, use the existing instance.
|
|||
BufferedReadStream bufferedReadStream = |
|||
stream as BufferedReadStream ?? new BufferedReadStream(configuration, stream, cancellationToken); |
|||
|
|||
try |
|||
{ |
|||
return this.Decode<TPixel>(bufferedReadStream, cancellationToken); |
|||
} |
|||
catch (InvalidMemoryOperationException ex) |
|||
{ |
|||
throw new InvalidImageContentException(this.Dimensions, ex); |
|||
} |
|||
catch (Exception) |
|||
{ |
|||
throw; |
|||
} |
|||
finally |
|||
{ |
|||
if (bufferedReadStream != stream) |
|||
{ |
|||
bufferedReadStream.Dispose(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Reads the raw image information from the specified stream.
|
|||
/// </summary>
|
|||
/// <param name="stream">The <see cref="BufferedReadStream"/> containing image data.</param>
|
|||
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
|
|||
/// <returns>The <see cref="ImageInfo"/>.</returns>
|
|||
/// <remarks>
|
|||
/// Cancellable synchronous method. In case of cancellation,
|
|||
/// an <see cref="OperationCanceledException"/> shall be thrown which will be handled on the call site.
|
|||
/// </remarks>
|
|||
protected abstract ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken); |
|||
|
|||
/// <summary>
|
|||
/// Decodes the image from the specified stream.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
/// <param name="stream">The stream, where the image should be decoded from. Cannot be null.</param>
|
|||
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
|
|||
/// <exception cref="ArgumentNullException"><paramref name="stream"/> is null.</exception>
|
|||
/// <returns>The decoded image.</returns>
|
|||
/// <remarks>
|
|||
/// Cancellable synchronous method. In case of cancellation, an <see cref="OperationCanceledException"/> shall
|
|||
/// be thrown which will be handled on the call site.
|
|||
/// </remarks>
|
|||
protected abstract Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken cancellationToken) |
|||
where TPixel : unmanaged, IPixel<TPixel>; |
|||
} |
|||
@ -1,81 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.IO; |
|||
using SixLabors.ImageSharp.Memory; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats; |
|||
|
|||
/// <summary>
|
|||
/// Utility methods for <see cref="IImageDecoderInternals"/>.
|
|||
/// </summary>
|
|||
internal static class ImageDecoderUtilities |
|||
{ |
|||
internal static ImageInfo Identify( |
|||
this IImageDecoderInternals decoder, |
|||
Configuration configuration, |
|||
Stream stream, |
|||
CancellationToken cancellationToken) |
|||
{ |
|||
using BufferedReadStream bufferedReadStream = new(configuration, stream, cancellationToken); |
|||
|
|||
try |
|||
{ |
|||
return decoder.Identify(bufferedReadStream, cancellationToken); |
|||
} |
|||
catch (InvalidMemoryOperationException ex) |
|||
{ |
|||
throw new InvalidImageContentException(decoder.Dimensions, ex); |
|||
} |
|||
catch (Exception) |
|||
{ |
|||
throw; |
|||
} |
|||
} |
|||
|
|||
internal static Image<TPixel> Decode<TPixel>( |
|||
this IImageDecoderInternals decoder, |
|||
Configuration configuration, |
|||
Stream stream, |
|||
CancellationToken cancellationToken) |
|||
where TPixel : unmanaged, IPixel<TPixel> |
|||
=> decoder.Decode<TPixel>(configuration, stream, DefaultLargeImageExceptionFactory, cancellationToken); |
|||
|
|||
internal static Image<TPixel> Decode<TPixel>( |
|||
this IImageDecoderInternals decoder, |
|||
Configuration configuration, |
|||
Stream stream, |
|||
Func<InvalidMemoryOperationException, Size, InvalidImageContentException> largeImageExceptionFactory, |
|||
CancellationToken cancellationToken) |
|||
where TPixel : unmanaged, IPixel<TPixel> |
|||
{ |
|||
// Test may pass a BufferedReadStream in order to monitor EOF hits, if so, use the existing instance.
|
|||
BufferedReadStream bufferedReadStream = stream as BufferedReadStream ?? new BufferedReadStream(configuration, stream, cancellationToken); |
|||
|
|||
try |
|||
{ |
|||
return decoder.Decode<TPixel>(bufferedReadStream, cancellationToken); |
|||
} |
|||
catch (InvalidMemoryOperationException ex) |
|||
{ |
|||
throw largeImageExceptionFactory(ex, decoder.Dimensions); |
|||
} |
|||
catch (Exception) |
|||
{ |
|||
throw; |
|||
} |
|||
finally |
|||
{ |
|||
if (bufferedReadStream != stream) |
|||
{ |
|||
bufferedReadStream.Dispose(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private static InvalidImageContentException DefaultLargeImageExceptionFactory( |
|||
InvalidMemoryOperationException memoryOperationException, |
|||
Size dimensions) => |
|||
new(dimensions, memoryOperationException); |
|||
} |
|||
@ -1,21 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using System.Text; |
|||
using SixLabors.ImageSharp.Formats.Jpeg; |
|||
using SixLabors.ImageSharp.Metadata; |
|||
|
|||
namespace SixLabors.ImageSharp; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="ImageMetadata"/> type.
|
|||
/// </summary>
|
|||
public static partial class MetadataExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the jpeg format specific metadata for the image.
|
|||
/// </summary>
|
|||
/// <param name="metadata">The metadata this method extends.</param>
|
|||
/// <returns>The <see cref="JpegMetadata"/>.</returns>
|
|||
public static JpegMetadata GetJpegMetadata(this ImageMetadata metadata) => metadata.GetFormatMetadata(JpegFormat.Instance); |
|||
} |
|||
@ -1,25 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Pbm; |
|||
|
|||
/// <summary>
|
|||
/// Configuration options for use during PBM encoding.
|
|||
/// </summary>
|
|||
internal interface IPbmEncoderOptions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the encoding of the pixels.
|
|||
/// </summary>
|
|||
PbmEncoding? Encoding { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the Color type of the resulting image.
|
|||
/// </summary>
|
|||
PbmColorType? ColorType { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the Data Type of the pixel components.
|
|||
/// </summary>
|
|||
PbmComponentType? ComponentType { get; } |
|||
} |
|||
@ -1,20 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.Formats.Pbm; |
|||
using SixLabors.ImageSharp.Metadata; |
|||
|
|||
namespace SixLabors.ImageSharp; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="ImageMetadata"/> type.
|
|||
/// </summary>
|
|||
public static partial class MetadataExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the pbm format specific metadata for the image.
|
|||
/// </summary>
|
|||
/// <param name="metadata">The metadata this method extends.</param>
|
|||
/// <returns>The <see cref="PbmMetadata"/>.</returns>
|
|||
public static PbmMetadata GetPbmMetadata(this ImageMetadata metadata) => metadata.GetFormatMetadata(PbmFormat.Instance); |
|||
} |
|||
@ -1,84 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using System.Diagnostics.CodeAnalysis; |
|||
using SixLabors.ImageSharp.Formats; |
|||
using SixLabors.ImageSharp.Formats.Png; |
|||
using SixLabors.ImageSharp.Metadata; |
|||
|
|||
namespace SixLabors.ImageSharp; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="ImageMetadata"/> type.
|
|||
/// </summary>
|
|||
public static partial class MetadataExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the png format specific metadata for the image.
|
|||
/// </summary>
|
|||
/// <param name="source">The metadata this method extends.</param>
|
|||
/// <returns>The <see cref="PngMetadata"/>.</returns>
|
|||
public static PngMetadata GetPngMetadata(this ImageMetadata source) => source.GetFormatMetadata(PngFormat.Instance); |
|||
|
|||
/// <summary>
|
|||
/// Gets the png format specific metadata for the image.
|
|||
/// </summary>
|
|||
/// <param name="source">The metadata this method extends.</param>
|
|||
/// <param name="metadata">The metadata.</param>
|
|||
/// <returns>
|
|||
/// <see langword="true"/> if the png metadata exists; otherwise, <see langword="false"/>.
|
|||
/// </returns>
|
|||
public static bool TryGetPngMetadata(this ImageMetadata source, [NotNullWhen(true)] out PngMetadata? metadata) |
|||
=> source.TryGetFormatMetadata(PngFormat.Instance, out metadata); |
|||
|
|||
/// <summary>
|
|||
/// Gets the png format specific metadata for the image frame.
|
|||
/// </summary>
|
|||
/// <param name="source">The metadata this method extends.</param>
|
|||
/// <returns>The <see cref="PngFrameMetadata"/>.</returns>
|
|||
public static PngFrameMetadata GetPngMetadata(this ImageFrameMetadata source) => source.GetFormatMetadata(PngFormat.Instance); |
|||
|
|||
/// <summary>
|
|||
/// Gets the png format specific metadata for the image frame.
|
|||
/// </summary>
|
|||
/// <param name="source">The metadata this method extends.</param>
|
|||
/// <param name="metadata">The metadata.</param>
|
|||
/// <returns>
|
|||
/// <see langword="true"/> if the png frame metadata exists; otherwise, <see langword="false"/>.
|
|||
/// </returns>
|
|||
public static bool TryGetPngMetadata(this ImageFrameMetadata source, [NotNullWhen(true)] out PngFrameMetadata? metadata) |
|||
=> source.TryGetFormatMetadata(PngFormat.Instance, out metadata); |
|||
|
|||
internal static AnimatedImageMetadata ToAnimatedImageMetadata(this PngMetadata source) |
|||
=> new() |
|||
{ |
|||
ColorTable = source.ColorTable, |
|||
ColorTableMode = FrameColorTableMode.Global, |
|||
RepeatCount = (ushort)Numerics.Clamp(source.RepeatCount, 0, ushort.MaxValue), |
|||
}; |
|||
|
|||
internal static AnimatedImageFrameMetadata ToAnimatedImageFrameMetadata(this PngFrameMetadata source) |
|||
{ |
|||
double delay = source.FrameDelay.ToDouble(); |
|||
if (double.IsNaN(delay)) |
|||
{ |
|||
delay = 0; |
|||
} |
|||
|
|||
return new() |
|||
{ |
|||
ColorTableMode = FrameColorTableMode.Global, |
|||
Duration = TimeSpan.FromMilliseconds(delay * 1000), |
|||
DisposalMode = GetMode(source.DisposalMethod), |
|||
BlendMode = source.BlendMethod == PngBlendMethod.Source ? FrameBlendMode.Source : FrameBlendMode.Over, |
|||
}; |
|||
} |
|||
|
|||
private static FrameDisposalMode GetMode(PngDisposalMethod method) => method switch |
|||
{ |
|||
PngDisposalMethod.DoNotDispose => FrameDisposalMode.DoNotDispose, |
|||
PngDisposalMethod.RestoreToBackground => FrameDisposalMode.RestoreToBackground, |
|||
PngDisposalMethod.RestoreToPrevious => FrameDisposalMode.RestoreToPrevious, |
|||
_ => FrameDisposalMode.Unspecified, |
|||
}; |
|||
} |
|||
@ -1,22 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Png; |
|||
|
|||
/// <summary>
|
|||
/// Specifies whether the frame is to be alpha blended into the current output buffer content,
|
|||
/// or whether it should completely replace its region in the output buffer.
|
|||
/// </summary>
|
|||
public enum PngBlendMethod |
|||
{ |
|||
/// <summary>
|
|||
/// All color components of the frame, including alpha, overwrite the current contents of the frame's output buffer region.
|
|||
/// </summary>
|
|||
Source, |
|||
|
|||
/// <summary>
|
|||
/// The frame should be composited onto the output buffer based on its alpha, using a simple OVER operation as
|
|||
/// described in the "Alpha Channel Processing" section of the PNG specification [PNG-1.2].
|
|||
/// </summary>
|
|||
Over |
|||
} |
|||
@ -1,25 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Png; |
|||
|
|||
/// <summary>
|
|||
/// Specifies how the output buffer should be changed at the end of the delay (before rendering the next frame).
|
|||
/// </summary>
|
|||
public enum PngDisposalMethod |
|||
{ |
|||
/// <summary>
|
|||
/// No disposal is done on this frame before rendering the next; the contents of the output buffer are left as is.
|
|||
/// </summary>
|
|||
DoNotDispose, |
|||
|
|||
/// <summary>
|
|||
/// The frame's region of the output buffer is to be cleared to fully transparent black before rendering the next frame.
|
|||
/// </summary>
|
|||
RestoreToBackground, |
|||
|
|||
/// <summary>
|
|||
/// The frame's region of the output buffer is to be reverted to the previous contents before rendering the next frame.
|
|||
/// </summary>
|
|||
RestoreToPrevious |
|||
} |
|||
@ -1,20 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.Formats.Qoi; |
|||
using SixLabors.ImageSharp.Metadata; |
|||
|
|||
namespace SixLabors.ImageSharp; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="ImageMetadata"/> type.
|
|||
/// </summary>
|
|||
public static partial class MetadataExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the qoi format specific metadata for the image.
|
|||
/// </summary>
|
|||
/// <param name="metadata">The metadata this method extends.</param>
|
|||
/// <returns>The <see cref="QoiMetadata"/>.</returns>
|
|||
public static QoiMetadata GetQoiMetadata(this ImageMetadata metadata) => metadata.GetFormatMetadata(QoiFormat.Instance); |
|||
} |
|||
@ -1,20 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.Formats.Tga; |
|||
using SixLabors.ImageSharp.Metadata; |
|||
|
|||
namespace SixLabors.ImageSharp; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="ImageMetadata"/> type.
|
|||
/// </summary>
|
|||
public static partial class MetadataExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the tga format specific metadata for the image.
|
|||
/// </summary>
|
|||
/// <param name="metadata">The metadata this method extends.</param>
|
|||
/// <returns>The <see cref="TgaMetadata"/>.</returns>
|
|||
public static TgaMetadata GetTgaMetadata(this ImageMetadata metadata) => metadata.GetFormatMetadata(TgaFormat.Instance); |
|||
} |
|||
@ -1,27 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using SixLabors.ImageSharp.Formats.Tiff; |
|||
using SixLabors.ImageSharp.Metadata; |
|||
|
|||
namespace SixLabors.ImageSharp; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="ImageMetadata"/> type.
|
|||
/// </summary>
|
|||
public static partial class MetadataExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the tiff format specific metadata for the image.
|
|||
/// </summary>
|
|||
/// <param name="metadata">The metadata this method extends.</param>
|
|||
/// <returns>The <see cref="TiffMetadata"/>.</returns>
|
|||
public static TiffMetadata GetTiffMetadata(this ImageMetadata metadata) => metadata.GetFormatMetadata(TiffFormat.Instance); |
|||
|
|||
/// <summary>
|
|||
/// Gets the tiff format specific metadata for the image frame.
|
|||
/// </summary>
|
|||
/// <param name="metadata">The metadata this method extends.</param>
|
|||
/// <returns>The <see cref="TiffFrameMetadata"/>.</returns>
|
|||
public static TiffFrameMetadata GetTiffMetadata(this ImageFrameMetadata metadata) => metadata.GetFormatMetadata(TiffFormat.Instance); |
|||
} |
|||
@ -1,75 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
using System.Diagnostics.CodeAnalysis; |
|||
using SixLabors.ImageSharp.Formats; |
|||
using SixLabors.ImageSharp.Formats.Webp; |
|||
using SixLabors.ImageSharp.Metadata; |
|||
|
|||
namespace SixLabors.ImageSharp; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods for the <see cref="ImageMetadata"/> type.
|
|||
/// </summary>
|
|||
public static partial class MetadataExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the webp format specific metadata for the image.
|
|||
/// </summary>
|
|||
/// <param name="metadata">The metadata this method extends.</param>
|
|||
/// <returns>The <see cref="WebpMetadata"/>.</returns>
|
|||
public static WebpMetadata GetWebpMetadata(this ImageMetadata metadata) => metadata.GetFormatMetadata(WebpFormat.Instance); |
|||
|
|||
/// <summary>
|
|||
/// Gets the webp format specific metadata for the image.
|
|||
/// </summary>
|
|||
/// <param name="source">The metadata this method extends.</param>
|
|||
/// <param name="metadata">The metadata.</param>
|
|||
/// <returns>
|
|||
/// <see langword="true"/> if the webp metadata exists; otherwise, <see langword="false"/>.
|
|||
/// </returns>
|
|||
public static bool TryGetWebpMetadata(this ImageMetadata source, [NotNullWhen(true)] out WebpMetadata? metadata) |
|||
=> source.TryGetFormatMetadata(WebpFormat.Instance, out metadata); |
|||
|
|||
/// <summary>
|
|||
/// Gets the webp format specific metadata for the image frame.
|
|||
/// </summary>
|
|||
/// <param name="metadata">The metadata this method extends.</param>
|
|||
/// <returns>The <see cref="WebpFrameMetadata"/>.</returns>
|
|||
public static WebpFrameMetadata GetWebpMetadata(this ImageFrameMetadata metadata) => metadata.GetFormatMetadata(WebpFormat.Instance); |
|||
|
|||
/// <summary>
|
|||
/// Gets the webp format specific metadata for the image frame.
|
|||
/// </summary>
|
|||
/// <param name="source">The metadata this method extends.</param>
|
|||
/// <param name="metadata">The metadata.</param>
|
|||
/// <returns>
|
|||
/// <see langword="true"/> if the webp frame metadata exists; otherwise, <see langword="false"/>.
|
|||
/// </returns>
|
|||
public static bool TryGetWebpFrameMetadata(this ImageFrameMetadata source, [NotNullWhen(true)] out WebpFrameMetadata? metadata) |
|||
=> source.TryGetFormatMetadata(WebpFormat.Instance, out metadata); |
|||
|
|||
internal static AnimatedImageMetadata ToAnimatedImageMetadata(this WebpMetadata source) |
|||
=> new() |
|||
{ |
|||
ColorTableMode = FrameColorTableMode.Global, |
|||
RepeatCount = source.RepeatCount, |
|||
BackgroundColor = source.BackgroundColor |
|||
}; |
|||
|
|||
internal static AnimatedImageFrameMetadata ToAnimatedImageFrameMetadata(this WebpFrameMetadata source) |
|||
=> new() |
|||
{ |
|||
ColorTableMode = FrameColorTableMode.Global, |
|||
Duration = TimeSpan.FromMilliseconds(source.FrameDelay), |
|||
DisposalMode = GetMode(source.DisposalMethod), |
|||
BlendMode = source.BlendMethod == WebpBlendMethod.Over ? FrameBlendMode.Over : FrameBlendMode.Source, |
|||
}; |
|||
|
|||
private static FrameDisposalMode GetMode(WebpDisposalMethod method) => method switch |
|||
{ |
|||
WebpDisposalMethod.RestoreToBackground => FrameDisposalMode.RestoreToBackground, |
|||
WebpDisposalMethod.DoNotDispose => FrameDisposalMode.DoNotDispose, |
|||
_ => FrameDisposalMode.DoNotDispose, |
|||
}; |
|||
} |
|||
@ -1,22 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Webp; |
|||
|
|||
/// <summary>
|
|||
/// Indicates how transparent pixels of the current frame are to be blended with corresponding pixels of the previous canvas.
|
|||
/// </summary>
|
|||
public enum WebpBlendMethod |
|||
{ |
|||
/// <summary>
|
|||
/// Do not blend. After disposing of the previous frame,
|
|||
/// render the current frame on the canvas by overwriting the rectangle covered by the current frame.
|
|||
/// </summary>
|
|||
Source = 0, |
|||
|
|||
/// <summary>
|
|||
/// Use alpha blending. After disposing of the previous frame, render the current frame on the canvas using alpha-blending.
|
|||
/// If the current frame does not have an alpha channel, assume alpha value of 255, effectively replacing the rectangle.
|
|||
/// </summary>
|
|||
Over = 1, |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Six Labors Split License.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Webp; |
|||
|
|||
/// <summary>
|
|||
/// Provides enumeration of the various webp color types.
|
|||
/// </summary>
|
|||
public enum WebpColorType |
|||
{ |
|||
/// <summary>
|
|||
/// Yuv (luminance, blue chroma, red chroma) as defined in the ITU-R Rec. BT.709 specification.
|
|||
/// </summary>
|
|||
Yuv, |
|||
|
|||
/// <summary>
|
|||
/// Rgb color space.
|
|||
/// </summary>
|
|||
Rgb, |
|||
|
|||
/// <summary>
|
|||
/// Rgba color space.
|
|||
/// </summary>
|
|||
Rgba |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue