-
-
Notifications
You must be signed in to change notification settings - Fork 851
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add smart animated format conversion. #2588
Conversation
@antonfirsov @tocsoft I need your help if you have time? I'm seeing allocation cleanup failure reports on Linux/Mac and I can recreate them on my old MacBook. Thing is... I've touched nothing related to memory management nor does this test touch code I've changed with my PR. Is there any way to easily diagnose the cause? I tried using dotmemory Unit in Rider but it won't give the option to run the test in the manner that allows profiling memory. Running this test in isolation is enough to cause failure. EDIT.... OK. It was failing locally but now it suddenly isn't. Could it be a memory pressure thing triggered by my additional tests? EDIT... It was ME!! |
src/ImageSharp/Processing/Processors/Quantization/EuclideanPixelMap{TPixel}.cs
Show resolved
Hide resolved
src/ImageSharp/Processing/Processors/Quantization/EuclideanPixelMap{TPixel}.cs
Show resolved
Hide resolved
Forget this... I removed my local copy of the repo and did a clean checkout. Now everything works on the main branch.. strange
I tried running main first on my Mac. But not even there all tests go green.
SixLabors.ImageSharp.ImageFormatException
Microsoft.DotNet.RemoteExecutor.RemoteExecutionException |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code-wise LGTM.
To the implementation itself I can't say too much as I'm missing knowledge here.
/// </para> | ||
/// </remarks> | ||
private unsafe struct ColorDistanceCache : IDisposable | ||
{ | ||
private const int IndexRBits = 5; | ||
private const int IndexGBits = 5; | ||
private const int IndexBBits = 6; | ||
private const int IndexBBits = 5; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a test that unveils that "bug" (was this a bug?)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was something I just caught doing a visual test which is hard to test for.
The cache was only filled to a maximum value of ~96% which led to matching where it shouldn't. This led to transparent areas in the frame following deduplication. Originally, I was going to simply add more precision for a single component (blue) which fixed the issue, but I discovered that with the new index determinaiton code the cache fills to a maximum of ~98% and the problem simply went away.
Prerequisites
Description
Note: Most of the file changes here are new references images that were generated to cater for changes in the color distance calculator that improved lookup accuracy.
This PR adds some internal tooling that allows us to convert between animated image formats without the user having to specify the mechanics for each frame to ensure converting between formats returns an equivalent result.
For v4 I plan to update the metadata formats to introduce public bridging types and methods to create smart defaults when switching formats but for now I had to use an internal, non-extensible approach.
For v3.1 we will support bi-directional conversion between gif, png, and webp formats. Full color table mapping is performed between formats when present as well as duration, and disposal, blend modes where applicable.
Here's an example of an automatic conversion.
Gif (45.2KB)
Png (33.3KB)
In addition to the conversion functionality all 3 animated formats have been enhanced with shared methodology that allows the optimization of the frames to only include changed data. This prevents the potential explosion in file size (multi MBs) that can be caused when re-encoding the frames that are coalesced during decode.
This example from gifiddle demonstrates the active encoded area of a frame following that optimization.
For many gifs this actually leads to an improvement over the incoming file size. For example, the original of the gif above is 52.3KB