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.
|
// Copyright (c) Six Labors.
|
||||
// Licensed under the Six Labors Split License.
|
// 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; |
namespace SixLabors.ImageSharp.Formats.Cur; |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Provides Ico specific metadata information for the image.
|
/// Provides Cur specific metadata information for the image.
|
||||
/// </summary>
|
/// </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/>
|
/// <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/>
|
/// <inheritdoc/>
|
||||
IDeepCloneable IDeepCloneable.DeepClone() => this.DeepClone(); |
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.
|
// Copyright (c) Six Labors.
|
||||
// Licensed under the Six Labors Split License.
|
// 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; |
namespace SixLabors.ImageSharp.Formats.Ico; |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// Provides Ico specific metadata information for the image.
|
/// Provides Ico specific metadata information for the image.
|
||||
/// </summary>
|
/// </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/>
|
/// <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/>
|
/// <inheritdoc/>
|
||||
IDeepCloneable IDeepCloneable.DeepClone() => this.DeepClone(); |
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