Skip to content

Commit 49cf55c

Browse files
authored
Merge branch 'SixLabors:main' into feat/ani
2 parents 1a51a5c + e20e47f commit 49cf55c

Some content is hidden

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

45 files changed

+468
-412
lines changed

src/ImageSharp/Formats/Gif/LzwDecoder.cs

Lines changed: 193 additions & 132 deletions
Large diffs are not rendered by default.

src/ImageSharp/Formats/Png/PngThrowHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public static void ThrowInvalidParameter(object value, string message, [CallerAr
4444
=> throw new NotSupportedException($"Invalid {name}. {message}. Was '{value}'.");
4545

4646
[DoesNotReturn]
47-
public static void ThrowInvalidParameter(object value1, object value2, string message, [CallerArgumentExpression(nameof(value1))] string name1 = "", [CallerArgumentExpression(nameof(value1))] string name2 = "")
47+
public static void ThrowInvalidParameter(object value1, object value2, string message, [CallerArgumentExpression(nameof(value1))] string name1 = "", [CallerArgumentExpression(nameof(value2))] string name2 = "")
4848
=> throw new NotSupportedException($"Invalid {name1} or {name2}. {message}. Was '{value1}' and '{value2}'.");
4949

5050
[DoesNotReturn]

src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,7 @@ private void DecodeTilesPlanar<TPixel>(
648648
}
649649

650650
/// <summary>
651-
/// Decodes the image data for Tiff's which arrange the pixel data in tiles and the chunky configuration.
651+
/// Decodes the image data for TIFFs which arrange the pixel data in tiles and the chunky configuration.
652652
/// </summary>
653653
/// <typeparam name="TPixel">The pixel format.</typeparam>
654654
/// <param name="frame">The image frame to decode into.</param>
@@ -674,28 +674,26 @@ private void DecodeTilesChunky<TPixel>(
674674
int width = pixels.Width;
675675
int height = pixels.Height;
676676
int bitsPerPixel = this.BitsPerPixel;
677-
678-
int bytesPerRow = RoundUpToMultipleOfEight(width * bitsPerPixel);
679677
int bytesPerTileRow = RoundUpToMultipleOfEight(tileWidth * bitsPerPixel);
680-
int uncompressedTilesSize = bytesPerTileRow * tileLength;
681-
using IMemoryOwner<byte> tileBuffer = this.memoryAllocator.Allocate<byte>(uncompressedTilesSize, AllocationOptions.Clean);
682-
using IMemoryOwner<byte> uncompressedPixelBuffer = this.memoryAllocator.Allocate<byte>(tilesDown * tileLength * bytesPerRow, AllocationOptions.Clean);
678+
679+
using IMemoryOwner<byte> tileBuffer = this.memoryAllocator.Allocate<byte>(bytesPerTileRow * tileLength, AllocationOptions.Clean);
683680
Span<byte> tileBufferSpan = tileBuffer.GetSpan();
684-
Span<byte> uncompressedPixelBufferSpan = uncompressedPixelBuffer.GetSpan();
685681

686682
using TiffBaseDecompressor decompressor = this.CreateDecompressor<TPixel>(frame.Width, bitsPerPixel);
687683
TiffBaseColorDecoder<TPixel> colorDecoder = this.CreateChunkyColorDecoder<TPixel>();
688684

689685
int tileIndex = 0;
690686
for (int tileY = 0; tileY < tilesDown; tileY++)
691687
{
692-
int remainingPixelsInRow = width;
688+
int rowStartY = tileY * tileLength;
689+
int rowEndY = Math.Min(rowStartY + tileLength, height);
690+
693691
for (int tileX = 0; tileX < tilesAcross; tileX++)
694692
{
695693
cancellationToken.ThrowIfCancellationRequested();
696694

697-
int uncompressedPixelBufferOffset = tileY * tileLength * bytesPerRow;
698695
bool isLastHorizontalTile = tileX == tilesAcross - 1;
696+
int remainingPixelsInRow = width - (tileX * tileWidth);
699697

700698
decompressor.Decompress(
701699
this.inputStream,
@@ -706,22 +704,21 @@ private void DecodeTilesChunky<TPixel>(
706704
cancellationToken);
707705

708706
int tileBufferOffset = 0;
709-
uncompressedPixelBufferOffset += bytesPerTileRow * tileX;
710707
int bytesToCopy = isLastHorizontalTile ? RoundUpToMultipleOfEight(bitsPerPixel * remainingPixelsInRow) : bytesPerTileRow;
711-
for (int y = 0; y < tileLength; y++)
708+
int rowWidth = Math.Min(tileWidth, remainingPixelsInRow);
709+
int left = tileX * tileWidth;
710+
711+
for (int y = rowStartY; y < rowEndY; y++)
712712
{
713-
Span<byte> uncompressedPixelRow = uncompressedPixelBufferSpan.Slice(uncompressedPixelBufferOffset, bytesToCopy);
714-
tileBufferSpan.Slice(tileBufferOffset, bytesToCopy).CopyTo(uncompressedPixelRow);
713+
// Decode the tile row directly into the pixel buffer.
714+
ReadOnlySpan<byte> tileRowSpan = tileBufferSpan.Slice(tileBufferOffset, bytesToCopy);
715+
colorDecoder.Decode(tileRowSpan, pixels, left, y, rowWidth, 1);
715716
tileBufferOffset += bytesPerTileRow;
716-
uncompressedPixelBufferOffset += bytesPerRow;
717717
}
718718

719-
remainingPixelsInRow -= tileWidth;
720719
tileIndex++;
721720
}
722721
}
723-
724-
colorDecoder.Decode(uncompressedPixelBufferSpan, pixels, 0, 0, width, height);
725722
}
726723

727724
private TiffBaseColorDecoder<TPixel> CreateChunkyColorDecoder<TPixel>()

tests/ImageSharp.Benchmarks/Bulk/FromRgba32Bytes.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,7 @@ public void OptimizedBulk()
6262
=> PixelOperations<TPixel>.Instance.FromRgba32Bytes(this.configuration, this.source.GetSpan(), this.destination.GetSpan(), this.Count);
6363
}
6464

65-
public class FromRgba32Bytes_ToRgba32 : FromRgba32Bytes<Rgba32>
66-
{
67-
}
65+
public class FromRgba32Bytes_ToRgba32 : FromRgba32Bytes<Rgba32>;
6866

6967
public class FromRgba32Bytes_ToBgra32 : FromRgba32Bytes<Bgra32>
7068
{

tests/ImageSharp.Benchmarks/Bulk/Vector4Factory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,5 @@ private static Vector4[] GenerateRandomVectorArray(Random rnd, int length, float
3030
}
3131

3232
private static float GetRandomFloat(Random rnd, float minVal, float maxVal)
33-
=> (float)rnd.NextDouble() * (maxVal - minVal) + minVal;
33+
=> ((float)rnd.NextDouble() * (maxVal - minVal)) + minVal;
3434
}

tests/ImageSharp.Benchmarks/Codecs/Bmp/DecodeBmp.cs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,24 @@ private string TestImageFullPath
1919

2020
[GlobalSetup]
2121
public void ReadImages()
22-
{
23-
if (this.bmpBytes == null)
24-
{
25-
this.bmpBytes = File.ReadAllBytes(this.TestImageFullPath);
26-
}
27-
}
22+
=> this.bmpBytes ??= File.ReadAllBytes(this.TestImageFullPath);
2823

2924
[Params(TestImages.Bmp.Car)]
3025
public string TestImage { get; set; }
3126

3227
[Benchmark(Baseline = true, Description = "System.Drawing Bmp")]
3328
public SDSize BmpSystemDrawing()
3429
{
35-
using var memoryStream = new MemoryStream(this.bmpBytes);
36-
using var image = SDImage.FromStream(memoryStream);
30+
using MemoryStream memoryStream = new(this.bmpBytes);
31+
using SDImage image = SDImage.FromStream(memoryStream);
3732
return image.Size;
3833
}
3934

4035
[Benchmark(Description = "ImageSharp Bmp")]
4136
public Size BmpImageSharp()
4237
{
43-
using var memoryStream = new MemoryStream(this.bmpBytes);
44-
using var image = Image.Load<Rgba32>(memoryStream);
38+
using MemoryStream memoryStream = new(this.bmpBytes);
39+
using Image<Rgba32> image = Image.Load<Rgba32>(memoryStream);
4540
return new Size(image.Width, image.Height);
4641
}
4742
}

tests/ImageSharp.Benchmarks/Codecs/Bmp/EncodeBmp.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs;
1212
[Config(typeof(Config.Short))]
1313
public class EncodeBmp
1414
{
15-
private Stream bmpStream;
15+
private FileStream bmpStream;
1616
private SDImage bmpDrawing;
1717
private Image<Rgba32> bmpCore;
1818

@@ -40,14 +40,14 @@ public void Cleanup()
4040
[Benchmark(Baseline = true, Description = "System.Drawing Bmp")]
4141
public void BmpSystemDrawing()
4242
{
43-
using var memoryStream = new MemoryStream();
43+
using MemoryStream memoryStream = new();
4444
this.bmpDrawing.Save(memoryStream, ImageFormat.Bmp);
4545
}
4646

4747
[Benchmark(Description = "ImageSharp Bmp")]
4848
public void BmpImageSharp()
4949
{
50-
using var memoryStream = new MemoryStream();
50+
using MemoryStream memoryStream = new();
5151
this.bmpCore.SaveAsBmp(memoryStream);
5252
}
5353
}

tests/ImageSharp.Benchmarks/Codecs/Gif/DecodeGif.cs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,24 @@ private string TestImageFullPath
1818
=> Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage);
1919

2020
[GlobalSetup]
21-
public void ReadImages()
22-
{
23-
if (this.gifBytes == null)
24-
{
25-
this.gifBytes = File.ReadAllBytes(this.TestImageFullPath);
26-
}
27-
}
21+
public void ReadImages() => this.gifBytes ??= File.ReadAllBytes(this.TestImageFullPath);
2822

2923
[Params(TestImages.Gif.Cheers)]
3024
public string TestImage { get; set; }
3125

3226
[Benchmark(Baseline = true, Description = "System.Drawing Gif")]
3327
public SDSize GifSystemDrawing()
3428
{
35-
using var memoryStream = new MemoryStream(this.gifBytes);
36-
using var image = SDImage.FromStream(memoryStream);
29+
using MemoryStream memoryStream = new(this.gifBytes);
30+
using SDImage image = SDImage.FromStream(memoryStream);
3731
return image.Size;
3832
}
3933

4034
[Benchmark(Description = "ImageSharp Gif")]
4135
public Size GifImageSharp()
4236
{
43-
using var memoryStream = new MemoryStream(this.gifBytes);
44-
using var image = Image.Load<Rgba32>(memoryStream);
37+
using MemoryStream memoryStream = new(this.gifBytes);
38+
using Image<Rgba32> image = Image.Load<Rgba32>(memoryStream);
4539
return new Size(image.Width, image.Height);
4640
}
4741
}

tests/ImageSharp.Benchmarks/Codecs/Gif/EncodeGif.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs;
1616
public class EncodeGif
1717
{
1818
// System.Drawing needs this.
19-
private Stream bmpStream;
19+
private FileStream bmpStream;
2020
private SDImage bmpDrawing;
2121
private Image<Rgba32> bmpCore;
2222

2323
// Try to get as close to System.Drawing's output as possible
24-
private readonly GifEncoder encoder = new GifEncoder
24+
private readonly GifEncoder encoder = new()
2525
{
2626
Quantizer = new WebSafePaletteQuantizer(new QuantizerOptions { Dither = KnownDitherings.Bayer4x4 })
2727
};
@@ -53,14 +53,14 @@ public void Cleanup()
5353
[Benchmark(Baseline = true, Description = "System.Drawing Gif")]
5454
public void GifSystemDrawing()
5555
{
56-
using var memoryStream = new MemoryStream();
56+
using MemoryStream memoryStream = new();
5757
this.bmpDrawing.Save(memoryStream, ImageFormat.Gif);
5858
}
5959

6060
[Benchmark(Description = "ImageSharp Gif")]
6161
public void GifImageSharp()
6262
{
63-
using var memoryStream = new MemoryStream();
63+
using MemoryStream memoryStream = new();
6464
this.bmpCore.SaveAsGif(memoryStream, this.encoder);
6565
}
6666
}

tests/ImageSharp.Benchmarks/Codecs/Gif/EncodeGifMultiple.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public void EncodeGifImageSharp()
2222
=> this.ForEachImageSharpImage((img, ms) =>
2323
{
2424
// Try to get as close to System.Drawing's output as possible
25-
var options = new GifEncoder
25+
GifEncoder options = new()
2626
{
2727
Quantizer = new WebSafePaletteQuantizer(new QuantizerOptions { Dither = KnownDitherings.Bayer4x4 })
2828
};

0 commit comments

Comments
 (0)