-
-
Notifications
You must be signed in to change notification settings - Fork 851
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2844 from SixLabors/js/normalize-transparency-enc…
…oding Normalize Encoder Transparency Handling For Alpha Aware Image Formats
- Loading branch information
Showing
81 changed files
with
1,737 additions
and
847 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// Copyright (c) Six Labors. | ||
// Licensed under the Six Labors Split License. | ||
|
||
namespace SixLabors.ImageSharp.Formats; | ||
|
||
/// <summary> | ||
/// Acts as a base encoder for all formats that are aware of and can handle alpha transparency. | ||
/// </summary> | ||
public abstract class AlphaAwareImageEncoder : ImageEncoder | ||
{ | ||
/// <summary> | ||
/// Gets or initializes the mode that determines how transparent pixels are handled during encoding. | ||
/// </summary> | ||
public TransparentColorMode TransparentColorMode { get; init; } | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// Copyright (c) Six Labors. | ||
// Licensed under the Six Labors Split License. | ||
|
||
using System.Buffers; | ||
using System.Numerics; | ||
using System.Runtime.Intrinsics; | ||
using SixLabors.ImageSharp.Memory; | ||
using SixLabors.ImageSharp.PixelFormats; | ||
|
||
namespace SixLabors.ImageSharp.Formats; | ||
|
||
/// <summary> | ||
/// Provides utilities for encoding images. | ||
/// </summary> | ||
internal static class EncodingUtilities | ||
{ | ||
public static bool ShouldClearTransparentPixels<TPixel>(TransparentColorMode mode) | ||
where TPixel : unmanaged, IPixel<TPixel> | ||
=> mode == TransparentColorMode.Clear && | ||
TPixel.GetPixelTypeInfo().AlphaRepresentation == PixelAlphaRepresentation.Unassociated; | ||
|
||
/// <summary> | ||
/// Convert transparent pixels, to pixels represented by <paramref name="color"/>, which can yield | ||
/// to better compression in some cases. | ||
/// </summary> | ||
/// <typeparam name="TPixel">The type of the pixel.</typeparam> | ||
/// <param name="clone">The cloned <see cref="ImageFrame{TPixel}"/> where the transparent pixels will be changed.</param> | ||
/// <param name="color">The color to replace transparent pixels with.</param> | ||
public static void ClearTransparentPixels<TPixel>(ImageFrame<TPixel> clone, Color color) | ||
where TPixel : unmanaged, IPixel<TPixel> | ||
{ | ||
Buffer2DRegion<TPixel> buffer = clone.PixelBuffer.GetRegion(); | ||
ClearTransparentPixels(clone.Configuration, ref buffer, color); | ||
} | ||
|
||
/// <summary> | ||
/// Convert transparent pixels, to pixels represented by <paramref name="color"/>, which can yield | ||
/// to better compression in some cases. | ||
/// </summary> | ||
/// <typeparam name="TPixel">The type of the pixel.</typeparam> | ||
/// <param name="configuration">The configuration.</param> | ||
/// <param name="clone">The cloned <see cref="Buffer2DRegion{T}"/> where the transparent pixels will be changed.</param> | ||
/// <param name="color">The color to replace transparent pixels with.</param> | ||
public static void ClearTransparentPixels<TPixel>( | ||
Configuration configuration, | ||
ref Buffer2DRegion<TPixel> clone, | ||
Color color) | ||
where TPixel : unmanaged, IPixel<TPixel> | ||
{ | ||
using IMemoryOwner<Vector4> vectors = configuration.MemoryAllocator.Allocate<Vector4>(clone.Width); | ||
Span<Vector4> vectorsSpan = vectors.GetSpan(); | ||
Vector4 replacement = color.ToScaledVector4(); | ||
for (int y = 0; y < clone.Height; y++) | ||
{ | ||
Span<TPixel> span = clone.DangerousGetRowSpan(y); | ||
PixelOperations<TPixel>.Instance.ToVector4(configuration, span, vectorsSpan, PixelConversionModifiers.Scale); | ||
ClearTransparentPixelRow(vectorsSpan, replacement); | ||
PixelOperations<TPixel>.Instance.FromVector4Destructive(configuration, vectorsSpan, span, PixelConversionModifiers.Scale); | ||
} | ||
} | ||
|
||
private static void ClearTransparentPixelRow( | ||
Span<Vector4> vectorsSpan, | ||
Vector4 replacement) | ||
{ | ||
if (Vector128.IsHardwareAccelerated) | ||
{ | ||
Vector128<float> replacement128 = replacement.AsVector128(); | ||
|
||
for (int i = 0; i < vectorsSpan.Length; i++) | ||
{ | ||
ref Vector4 v = ref vectorsSpan[i]; | ||
Vector128<float> v128 = v.AsVector128(); | ||
|
||
// Do `vector == 0` | ||
Vector128<float> mask = Vector128.Equals(v128, Vector128<float>.Zero); | ||
|
||
// Replicate the result for W to all elements (is AllBitsSet if the W was 0 and Zero otherwise) | ||
mask = Vector128.Shuffle(mask, Vector128.Create(3, 3, 3, 3)); | ||
|
||
// Use the mask to select the replacement vector | ||
// (replacement & mask) | (v128 & ~mask) | ||
v = Vector128.ConditionalSelect(mask, replacement128, v128).AsVector4(); | ||
} | ||
} | ||
else | ||
{ | ||
for (int i = 0; i < vectorsSpan.Length; i++) | ||
{ | ||
if (vectorsSpan[i].W == 0F) | ||
{ | ||
vectorsSpan[i] = replacement; | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.