Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add smart animated format conversion. #2588

Merged
merged 28 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
328e046
Wire up connectors and gif encoder
JimBobSquarePants Nov 15, 2023
a486558
Complete Webp and add tests
JimBobSquarePants Nov 17, 2023
7f4b457
Default loop count should be 1
JimBobSquarePants Nov 17, 2023
aea44fa
Merge branch 'main' into js/animation-synergy
JimBobSquarePants Nov 20, 2023
958c9c9
Deduper works
JimBobSquarePants Nov 21, 2023
a42f6b6
Enable dedup for png
JimBobSquarePants Nov 23, 2023
cc0727b
Add dedup to webp
JimBobSquarePants Nov 23, 2023
4b852e6
Update tests, fix issues
JimBobSquarePants Nov 24, 2023
4f8ea7f
Tweak bounds clamping
JimBobSquarePants Nov 24, 2023
78b1cad
Merge branch 'main' into js/animation-synergy
JimBobSquarePants Nov 25, 2023
c306c56
Use correct buffer dimensions
JimBobSquarePants Nov 25, 2023
6cda7b0
Fix scanline lengths
JimBobSquarePants Nov 26, 2023
90fa817
Update PngDecoderCore.cs
JimBobSquarePants Nov 26, 2023
4029b15
Remove duplicate condition check
JimBobSquarePants Nov 26, 2023
44b0311
Remove "new"
JimBobSquarePants Nov 26, 2023
55e69c7
Try disabling new high memory tests on failing platforms.
JimBobSquarePants Nov 26, 2023
a6f96f7
Optimize and fix deduper
JimBobSquarePants Nov 28, 2023
6bfabe9
Reduce memory pressure on gif decoder tests
JimBobSquarePants Nov 28, 2023
9677be0
More memory pressure reductions
JimBobSquarePants Nov 28, 2023
35d55b5
More memory pressure reduction
JimBobSquarePants Nov 28, 2023
e35e9a8
Reduce memory usage in pixel map
JimBobSquarePants Nov 29, 2023
5da17f3
Enable Sse2, simplify
JimBobSquarePants Nov 29, 2023
10cd3d5
Update AnimationUtilities.cs
JimBobSquarePants Nov 29, 2023
f4dc0fc
Disable Sse2 for now.
JimBobSquarePants Nov 29, 2023
43c8614
Fix Sse2 offset
JimBobSquarePants Nov 29, 2023
cf4106b
Add note
JimBobSquarePants Nov 29, 2023
3424efa
Merge branch 'main' into js/animation-synergy
JimBobSquarePants Nov 29, 2023
3b759a5
Merge branch 'main' into js/animation-synergy
JimBobSquarePants Nov 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
Expand Down Expand Up @@ -656,6 +657,36 @@ public static Vector128<byte> BlendVariable(Vector128<byte> left, Vector128<byte
return AdvSimd.BitwiseSelect(signedMask, right.AsInt16(), left.AsInt16()).AsByte();
}

/// <summary>
/// Blend packed 32-bit unsigned integers from <paramref name="left"/> and <paramref name="right"/> using <paramref name="mask"/>.
/// The high bit of each corresponding <paramref name="mask"/> byte determines the selection.
/// If the high bit is set the element of <paramref name="left"/> is selected.
/// The element of <paramref name="right"/> is selected otherwise.
/// </summary>
/// <param name="left">The left vector.</param>
/// <param name="right">The right vector.</param>
/// <param name="mask">The mask vector.</param>
/// <returns>The <see cref="Vector256{T}"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<uint> BlendVariable(Vector128<uint> left, Vector128<uint> right, Vector128<uint> mask)
=> BlendVariable(left.AsByte(), right.AsByte(), mask.AsByte()).AsUInt32();

/// <summary>
/// Count the number of leading zero bits in a mask.
/// Similar in behavior to the x86 instruction LZCNT.
/// </summary>
/// <param name="value">The value.</param>
public static ushort LeadingZeroCount(ushort value)
=> (ushort)(BitOperations.LeadingZeroCount(value) - 16);

/// <summary>
/// Count the number of trailing zero bits in an integer value.
/// Similar in behavior to the x86 instruction TZCNT.
/// </summary>
/// <param name="value">The value.</param>
public static ushort TrailingZeroCount(ushort value)
=> (ushort)(BitOperations.TrailingZeroCount(value << 16) - 16);

/// <summary>
/// <see cref="ByteToNormalizedFloat"/> as many elements as possible, slicing them down (keeping the remainder).
/// </summary>
Expand Down
93 changes: 93 additions & 0 deletions src/ImageSharp/Formats/AnimatedImageFrameMetadata.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

namespace SixLabors.ImageSharp.Formats;
internal class AnimatedImageFrameMetadata
{
/// <summary>
/// Gets or sets the frame color table.
/// </summary>
public ReadOnlyMemory<Color>? ColorTable { get; set; }

/// <summary>
/// Gets or sets the frame color table mode.
/// </summary>
public FrameColorTableMode ColorTableMode { get; set; }

/// <summary>
/// Gets or sets the duration of the frame.
/// </summary>
public TimeSpan Duration { get; set; }

/// <summary>
/// Gets or sets the frame alpha blending mode.
/// </summary>
public FrameBlendMode BlendMode { get; set; }

/// <summary>
/// Gets or sets the frame disposal mode.
/// </summary>
public FrameDisposalMode DisposalMode { get; set; }
}

#pragma warning disable SA1201 // Elements should appear in the correct order
internal enum FrameBlendMode
#pragma warning restore SA1201 // Elements should appear in the correct order
{
/// <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
}

internal 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
}

internal 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
}
32 changes: 32 additions & 0 deletions src/ImageSharp/Formats/AnimatedImageMetadata.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

namespace SixLabors.ImageSharp.Formats;
internal class AnimatedImageMetadata
{
/// <summary>
/// Gets or sets the shared color table.
/// </summary>
public ReadOnlyMemory<Color>? ColorTable { get; set; }

/// <summary>
/// Gets or sets the shared color table mode.
/// </summary>
public FrameColorTableMode ColorTableMode { get; set; }

/// <summary>
/// Gets or sets 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>
public Color BackgroundColor { get; set; }

/// <summary>
/// Gets or sets the number of times any animation is repeated.
/// <remarks>
/// 0 means to repeat indefinitely, count is set as repeat n-1 times. Defaults to 1.
/// </remarks>
/// </summary>
public ushort RepeatCount { get; set; }
}