Skip to content

Commit 2a13a71

Browse files
Merge branch 'main' into ImageInfo.FrameMetadataCollection-not-populated-correctly-for-animated-png-images
2 parents 9569449 + b6c4bb8 commit 2a13a71

File tree

98 files changed

+1060
-674
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+1060
-674
lines changed

src/ImageSharp/Advanced/AotCompilerTools.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ internal static class AotCompilerTools
5454
/// <remarks>
5555
/// This method doesn't actually do anything but serves an important purpose...
5656
/// If you are running ImageSharp on iOS and try to call SaveAsGif, it will throw an exception:
57-
/// "Attempting to JIT compile method... OctreeFrameQuantizer.ConstructPalette... while running in aot-only mode."
57+
/// "Attempting to JIT compile method... HexadecatreeQuantizer.ConstructPalette... while running in aot-only mode."
5858
/// The reason this happens is the SaveAsGif method makes heavy use of generics, which are too confusing for the AoT
5959
/// compiler used on Xamarin.iOS. It spins up the JIT compiler to try and figure it out, but that is an illegal op on
6060
/// iOS so it bombs out.
@@ -479,7 +479,7 @@ private static void AotCompileResampler<TPixel, TResampler>()
479479
private static void AotCompileQuantizers<TPixel>()
480480
where TPixel : unmanaged, IPixel<TPixel>
481481
{
482-
AotCompileQuantizer<TPixel, OctreeQuantizer>();
482+
AotCompileQuantizer<TPixel, HexadecatreeQuantizer>();
483483
AotCompileQuantizer<TPixel, PaletteQuantizer>();
484484
AotCompileQuantizer<TPixel, WebSafePaletteQuantizer>();
485485
AotCompileQuantizer<TPixel, WernerPaletteQuantizer>();
@@ -523,10 +523,8 @@ private static void AotCompilePixelSamplingStrategys<TPixel>()
523523
private static void AotCompilePixelMaps<TPixel>()
524524
where TPixel : unmanaged, IPixel<TPixel>
525525
{
526-
default(EuclideanPixelMap<TPixel, HybridCache>).GetClosestColor(default, out _);
527526
default(EuclideanPixelMap<TPixel, AccurateCache>).GetClosestColor(default, out _);
528527
default(EuclideanPixelMap<TPixel, CoarseCache>).GetClosestColor(default, out _);
529-
default(EuclideanPixelMap<TPixel, NullCache>).GetClosestColor(default, out _);
530528
}
531529

532530
/// <summary>
@@ -551,8 +549,8 @@ private static void AotCompileDither<TPixel, TDither>()
551549
where TPixel : unmanaged, IPixel<TPixel>
552550
where TDither : struct, IDither
553551
{
554-
OctreeQuantizer<TPixel> octree = default;
555-
default(TDither).ApplyQuantizationDither<OctreeQuantizer<TPixel>, TPixel>(ref octree, default, default, default);
552+
HexadecatreeQuantizer<TPixel> hexadecatree = default;
553+
default(TDither).ApplyQuantizationDither<HexadecatreeQuantizer<TPixel>, TPixel>(ref hexadecatree, default, default, default);
556554

557555
PaletteQuantizer<TPixel> palette = default;
558556
default(TDither).ApplyQuantizationDither<PaletteQuantizer<TPixel>, TPixel>(ref palette, default, default, default);

src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ internal static void ByteToNormalizedFloatReduce(
752752
/// Implementation is based on MagicScaler code:
753753
/// https://github.com/saucecontrol/PhotoSauce/blob/b5811908041200488aa18fdfd17df5fc457415dc/src/MagicScaler/Magic/Processors/ConvertersFloat.cs#L80-L182
754754
/// </remarks>
755-
internal static unsafe void ByteToNormalizedFloat(
755+
internal static void ByteToNormalizedFloat(
756756
ReadOnlySpan<byte> source,
757757
Span<float> destination)
758758
{
@@ -1172,8 +1172,10 @@ internal static void UnpackToRgbPlanesAvx2Reduce(
11721172
Vector256<byte> rgb, rg, bx;
11731173
Vector256<float> r, g, b;
11741174

1175+
// Each iteration consumes 8 Rgb24 pixels (24 bytes) but starts with a 32-byte load,
1176+
// so we need 3 extra pixels of addressable slack beyond the vectorized chunk.
11751177
const int bytesPerRgbStride = 24;
1176-
nuint count = (uint)source.Length / 8;
1178+
nuint count = source.Length > 3 ? (uint)(source.Length - 3) / 8 : 0;
11771179
for (nuint i = 0; i < count; i++)
11781180
{
11791181
rgb = Avx2.PermuteVar8x32(Unsafe.AddByteOffset(ref rgbByteSpan, (uint)(bytesPerRgbStride * i)).AsUInt32(), extractToLanesMask).AsByte();
@@ -1193,10 +1195,10 @@ internal static void UnpackToRgbPlanesAvx2Reduce(
11931195
}
11941196

11951197
int sliceCount = (int)(count * 8);
1196-
redChannel = redChannel.Slice(sliceCount);
1197-
greenChannel = greenChannel.Slice(sliceCount);
1198-
blueChannel = blueChannel.Slice(sliceCount);
1199-
source = source.Slice(sliceCount);
1198+
redChannel = redChannel[sliceCount..];
1199+
greenChannel = greenChannel[sliceCount..];
1200+
blueChannel = blueChannel[sliceCount..];
1201+
source = source[sliceCount..];
12001202
}
12011203
}
12021204
}

src/ImageSharp/Formats/Bmp/BmpEncoder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public sealed class BmpEncoder : QuantizingImageEncoder
1313
/// <summary>
1414
/// Initializes a new instance of the <see cref="BmpEncoder"/> class.
1515
/// </summary>
16-
public BmpEncoder() => this.Quantizer = KnownQuantizers.Octree;
16+
public BmpEncoder() => this.Quantizer = KnownQuantizers.Hexadecatree;
1717

1818
/// <summary>
1919
/// Gets the number of bits per pixel.

src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public BmpEncoderCore(BmpEncoder encoder, MemoryAllocator memoryAllocator)
116116
this.bitsPerPixel = encoder.BitsPerPixel;
117117

118118
// TODO: Use a palette quantizer if supplied.
119-
this.quantizer = encoder.Quantizer ?? KnownQuantizers.Octree;
119+
this.quantizer = encoder.Quantizer ?? KnownQuantizers.Hexadecatree;
120120
this.pixelSamplingStrategy = encoder.PixelSamplingStrategy;
121121
this.transparentColorMode = encoder.TransparentColorMode;
122122
this.infoHeaderType = encoder.SupportTransparency ? BmpInfoHeaderType.WinVersion4 : BmpInfoHeaderType.WinVersion3;

src/ImageSharp/Formats/Gif/GifEncoderCore.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken
117117

118118
if (globalQuantizer is null)
119119
{
120-
// Is this a gif with color information. If so use that, otherwise use octree.
120+
// Is this a gif with color information. If so use that, otherwise use the adaptive hexadecatree quantizer.
121121
if (gifMetadata.ColorTableMode == FrameColorTableMode.Global && gifMetadata.GlobalColorTable?.Length > 0)
122122
{
123123
int ti = GetTransparentIndex(quantized, frameMetadata);
@@ -132,12 +132,12 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken
132132
}
133133
else
134134
{
135-
globalQuantizer = new OctreeQuantizer(options);
135+
globalQuantizer = new HexadecatreeQuantizer(options);
136136
}
137137
}
138138
else
139139
{
140-
globalQuantizer = new OctreeQuantizer(options);
140+
globalQuantizer = new HexadecatreeQuantizer(options);
141141
}
142142
}
143143

src/ImageSharp/Formats/Jpeg/Components/Encoder/SpectralConverter{TPixel}.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ private void ConvertStride(int spectralStep)
114114
Span<TPixel> sourceRow = this.pixelBuffer.DangerousGetRowSpan(srcIndex);
115115
PixelOperations<TPixel>.Instance.UnpackIntoRgbPlanes(rLane, gLane, bLane, sourceRow);
116116

117-
rLane.Slice(paddingStartIndex).Fill(rLane[paddingStartIndex - 1]);
118-
gLane.Slice(paddingStartIndex).Fill(gLane[paddingStartIndex - 1]);
119-
bLane.Slice(paddingStartIndex).Fill(bLane[paddingStartIndex - 1]);
117+
rLane.Slice(paddingStartIndex, paddedPixelsCount).Fill(rLane[paddingStartIndex - 1]);
118+
gLane.Slice(paddingStartIndex, paddedPixelsCount).Fill(gLane[paddingStartIndex - 1]);
119+
bLane.Slice(paddingStartIndex, paddedPixelsCount).Fill(bLane[paddingStartIndex - 1]);
120120

121121
// Convert from rgb24 to target pixel type
122122
JpegColorConverterBase.ComponentValues values = new(this.componentProcessors, y);

src/ImageSharp/Formats/Tiff/TiffEncoder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class TiffEncoder : QuantizingImageEncoder
1515
/// <summary>
1616
/// Initializes a new instance of the <see cref="TiffEncoder"/> class.
1717
/// </summary>
18-
public TiffEncoder() => this.Quantizer = KnownQuantizers.Octree;
18+
public TiffEncoder() => this.Quantizer = KnownQuantizers.Hexadecatree;
1919

2020
/// <summary>
2121
/// Gets the number of bits per pixel.

src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public TiffEncoderCore(TiffEncoder encoder, Configuration configuration)
7171
this.configuration = configuration;
7272
this.memoryAllocator = configuration.MemoryAllocator;
7373
this.PhotometricInterpretation = encoder.PhotometricInterpretation;
74-
this.quantizer = encoder.Quantizer ?? KnownQuantizers.Octree;
74+
this.quantizer = encoder.Quantizer ?? KnownQuantizers.Hexadecatree;
7575
this.pixelSamplingStrategy = encoder.PixelSamplingStrategy;
7676
this.BitsPerPixel = encoder.BitsPerPixel;
7777
this.HorizontalPredictor = encoder.HorizontalPredictor;

src/ImageSharp/Processing/Extensions/Quantization/QuantizeExtensions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ namespace SixLabors.ImageSharp.Processing;
1212
public static class QuantizeExtensions
1313
{
1414
/// <summary>
15-
/// Applies quantization to the image using the <see cref="OctreeQuantizer"/>.
15+
/// Applies quantization to the image using the <see cref="HexadecatreeQuantizer"/>.
1616
/// </summary>
1717
/// <param name="source">The current image processing context.</param>
1818
/// <returns>The <see cref="IImageProcessingContext"/>.</returns>
1919
public static IImageProcessingContext Quantize(this IImageProcessingContext source) =>
20-
Quantize(source, KnownQuantizers.Octree);
20+
Quantize(source, KnownQuantizers.Hexadecatree);
2121

2222
/// <summary>
2323
/// Applies quantization to the image.
@@ -29,15 +29,15 @@ public static IImageProcessingContext Quantize(this IImageProcessingContext sour
2929
source.ApplyProcessor(new QuantizeProcessor(quantizer));
3030

3131
/// <summary>
32-
/// Applies quantization to the image using the <see cref="OctreeQuantizer"/>.
32+
/// Applies quantization to the image using the <see cref="HexadecatreeQuantizer"/>.
3333
/// </summary>
3434
/// <param name="source">The current image processing context.</param>
3535
/// <param name="rectangle">
3636
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
3737
/// </param>
3838
/// <returns>The <see cref="IImageProcessingContext"/>.</returns>
3939
public static IImageProcessingContext Quantize(this IImageProcessingContext source, Rectangle rectangle) =>
40-
Quantize(source, KnownQuantizers.Octree, rectangle);
40+
Quantize(source, KnownQuantizers.Hexadecatree, rectangle);
4141

4242
/// <summary>
4343
/// Applies quantization to the image.

src/ImageSharp/Processing/KnownQuantizers.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
// Copyright (c) Six Labors.
1+
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
33

44
using SixLabors.ImageSharp.Processing.Processors.Quantization;
55

66
namespace SixLabors.ImageSharp.Processing;
77

88
/// <summary>
9-
/// Contains reusable static instances of known quantizing algorithms
9+
/// Contains reusable static instances of known quantizing algorithms.
1010
/// </summary>
1111
public static class KnownQuantizers
1212
{
1313
/// <summary>
14-
/// Gets the adaptive Octree quantizer. Fast with good quality.
14+
/// Gets the adaptive hexadecatree quantizer. Fast with good quality.
1515
/// </summary>
16-
public static IQuantizer Octree { get; } = new OctreeQuantizer();
16+
public static IQuantizer Hexadecatree { get; } = new HexadecatreeQuantizer();
1717

1818
/// <summary>
1919
/// Gets the Xiaolin Wu's Color Quantizer which generates high quality output.

0 commit comments

Comments
 (0)