Browse Source

Merge branch 'main' into sn/collection-expressions

pull/3167/head
James Jackson-South 2 weeks ago
committed by GitHub
parent
commit
c43ec2b676
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      .gitattributes
  2. 37
      .github/workflows/build-and-test.yml
  3. 4
      .github/workflows/code-coverage.yml
  4. 8
      Directory.Build.props
  5. 2
      README.md
  6. 18
      global.json
  7. 2
      shared-infrastructure
  8. 4
      src/ImageSharp/Common/Extensions/StreamExtensions.cs
  9. 42
      src/ImageSharp/Common/Helpers/Numerics.cs
  10. 6
      src/ImageSharp/Common/Helpers/SimdUtils.Shuffle.cs
  11. 4
      src/ImageSharp/Common/Helpers/SimdUtils.cs
  12. 6
      src/ImageSharp/Formats/Exr/Compression/Decompressors/B44ExrCompression.cs
  13. 4
      src/ImageSharp/Formats/Exr/Compression/ExrBaseDecompressor.cs
  14. 16
      src/ImageSharp/Formats/Exr/ExrDecoderCore.cs
  15. 8
      src/ImageSharp/Formats/Exr/ExrEncoderCore.cs
  16. 4
      src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs
  17. 4
      src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs
  18. 6
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
  19. 6
      src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
  20. 6
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  21. 6
      src/ImageSharp/Formats/Tga/TgaEncoderCore.cs
  22. 4
      src/ImageSharp/Formats/Tiff/Compression/Compressors/T6BitCompressor.cs
  23. 6
      src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffLzwEncoder.cs
  24. 6
      src/ImageSharp/Formats/Tiff/README.md
  25. 18
      src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
  26. 4
      src/ImageSharp/Formats/Tiff/Writers/TiffStreamWriter.cs
  27. 12
      src/ImageSharp/Formats/Webp/AlphaDecoder.cs
  28. 4
      src/ImageSharp/Formats/Webp/BitWriter/BitWriterBase.cs
  29. 4
      src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs
  30. 4
      src/ImageSharp/Formats/Webp/Lossless/BackwardReferenceEncoder.cs
  31. 6
      src/ImageSharp/Formats/Webp/Lossless/ColorSpaceTransformUtils.cs
  32. 2
      src/ImageSharp/Formats/Webp/Lossless/CostModel.cs
  33. 2
      src/ImageSharp/Formats/Webp/Lossless/HistogramEncoder.cs
  34. 8
      src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs
  35. 4
      src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs
  36. 2
      src/ImageSharp/Formats/Webp/Lossless/NearLosslessEnc.cs
  37. 10
      src/ImageSharp/Formats/Webp/Lossless/PredictorEncoder.cs
  38. 8
      src/ImageSharp/Formats/Webp/Lossless/Vp8LBitEntropy.cs
  39. 16
      src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs
  40. 10
      src/ImageSharp/Formats/Webp/Lossless/Vp8LHistogram.cs
  41. 4
      src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs
  42. 50
      src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs
  43. 2
      src/ImageSharp/Formats/Webp/Lossy/Vp8EncIterator.cs
  44. 2
      src/ImageSharp/Formats/Webp/Lossy/Vp8EncProba.cs
  45. 28
      src/ImageSharp/Formats/Webp/Lossy/Vp8Encoding.cs
  46. 2
      src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs
  47. 2
      src/ImageSharp/Formats/Webp/Lossy/Vp8SegmentInfo.cs
  48. 10
      src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs
  49. 8
      src/ImageSharp/ImageSharp.csproj
  50. 2
      src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs
  51. 12
      src/ImageSharp/Processing/Processors/Transforms/Resamplers/CubicResampler.cs
  52. 2
      src/ImageSharp/Processing/Processors/Transforms/Resamplers/WelchResampler.cs
  53. 3
      tests/Directory.Build.targets
  54. 4
      tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj
  55. 4
      tests/ImageSharp.PublicApi.Tests/ImageSharp.PublicApi.Tests.csproj
  56. 4
      tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj
  57. 8
      tests/ImageSharp.Tests.ProfilingSandbox/Program.cs
  58. 1
      tests/ImageSharp.Tests/ColorProfiles/Icc/ColorProfileConverterTests.Icc.cs
  59. 2
      tests/ImageSharp.Tests/ColorProfiles/RgbAndHslConversionTest.cs
  60. 2
      tests/ImageSharp.Tests/Common/NumericsTests.cs
  61. 1
      tests/ImageSharp.Tests/Common/SimdUtilsTests.cs
  62. 1
      tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs
  63. 1
      tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs
  64. 1
      tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs
  65. 1
      tests/ImageSharp.Tests/Formats/Jpg/HuffmanScanEncoderTests.cs
  66. 1
      tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
  67. 1
      tests/ImageSharp.Tests/Formats/Jpg/ParseStreamTests.cs
  68. 1
      tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.AccurateDCT.cs
  69. 1
      tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.FastFloatingPointDCT.cs
  70. 1
      tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.StandardIntegerDCT.cs
  71. 2
      tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs
  72. 1
      tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs
  73. 1
      tests/ImageSharp.Tests/Formats/Jpg/SpectralToPixelConversionTests.cs
  74. 1
      tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs
  75. 2
      tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.LLM_FloatingPoint_DCT.cs
  76. 1
      tests/ImageSharp.Tests/Formats/Jpg/Utils/VerifyJpeg.cs
  77. 1
      tests/ImageSharp.Tests/Formats/Png/PngEncoderFilterTests.cs
  78. 8
      tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
  79. 1
      tests/ImageSharp.Tests/Helpers/ParallelRowIteratorTests.cs
  80. 10
      tests/ImageSharp.Tests/IO/LocalFileSystemTests.cs
  81. 1
      tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs
  82. 5
      tests/ImageSharp.Tests/ImageSharp.Tests.csproj
  83. 2
      tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedMemoryPoolTests.cs
  84. 502
      tests/ImageSharp.Tests/Metadata/Profiles/Exif/Values/ExifValuesTests.cs
  85. 6
      tests/ImageSharp.Tests/PixelFormats/L8Tests.cs
  86. 6
      tests/ImageSharp.Tests/PixelFormats/La16Tests.cs
  87. 3
      tests/ImageSharp.Tests/PixelFormats/PixelOperations/Generated/PixelOperationsTests.Specialized.Generated.cs
  88. 1
      tests/ImageSharp.Tests/PixelFormats/PixelOperations/Generated/_Common.ttinclude
  89. 82
      tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs
  90. 2
      tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs
  91. 4
      tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs
  92. 118
      tests/ImageSharp.Tests/Processing/Processors/Quantization/QuantizerTests.cs
  93. 1
      tests/ImageSharp.Tests/Processing/Processors/Transforms/AffineTransformTests.cs
  94. 1
      tests/ImageSharp.Tests/Processing/Processors/Transforms/ProjectiveTransformTests.cs
  95. 1
      tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs
  96. 12
      tests/ImageSharp.Tests/Processing/Processors/Transforms/RotateTests.cs
  97. 1
      tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveProfilingBenchmarks.cs
  98. 1
      tests/ImageSharp.Tests/ProfilingBenchmarks/ResizeProfilingBenchmarks.cs
  99. 2
      tests/ImageSharp.Tests/Quantization/AlphaAssociationQuantizerTests.cs
  100. 33
      tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs

1
.gitattributes

@ -110,6 +110,7 @@
###############################################################################
# Handle image files by git lfs
###############################################################################
*.pdf filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
*.jpeg filter=lfs diff=lfs merge=lfs -text
*.bmp filter=lfs diff=lfs merge=lfs -text

37
.github/workflows/build-and-test.yml

@ -64,48 +64,48 @@ jobs:
matrix:
options:
- os: ubuntu-latest
framework: net10.0
sdk: 10.0.x
framework: net11.0
sdk: 11.0.x
sdk-preview: true
runtime: -x64
codecov: false
- os: macos-26
framework: net10.0
sdk: 10.0.x
framework: net11.0
sdk: 11.0.x
sdk-preview: true
runtime: -x64
codecov: false
- os: windows-latest
framework: net10.0
sdk: 10.0.x
framework: net11.0
sdk: 11.0.x
sdk-preview: true
runtime: -x64
codecov: false
- os: ubuntu-22.04-arm
framework: net10.0
sdk: 10.0.x
framework: net11.0
sdk: 11.0.x
sdk-preview: true
runtime: -x64
codecov: false
- os: ubuntu-latest
framework: net8.0
sdk: 8.0.x
framework: net10.0
sdk: 10.0.x
runtime: -x64
codecov: false
- os: macos-26
framework: net8.0
sdk: 8.0.x
framework: net10.0
sdk: 10.0.x
runtime: -x64
codecov: false
- os: windows-latest
framework: net8.0
sdk: 8.0.x
framework: net10.0
sdk: 10.0.x
runtime: -x64
codecov: false
- os: ubuntu-22.04-arm
framework: net8.0
sdk: 8.0.x
framework: net10.0
sdk: 10.0.x
runtime: -x64
codecov: false
@ -169,14 +169,15 @@ jobs:
uses: actions/setup-dotnet@v6
with:
dotnet-version: |
8.0.x
10.0.x
- name: DotNet Setup Preview
if: ${{ matrix.options.sdk-preview == true }}
uses: actions/setup-dotnet@v6
with:
dotnet-quality: preview
dotnet-version: |
10.0.x
11.0.x
- name: DotNet Build
if: ${{ matrix.options.sdk-preview != true }}

4
.github/workflows/code-coverage.yml

@ -11,7 +11,7 @@ jobs:
matrix:
options:
- os: ubuntu-latest
framework: net8.0
framework: net10.0
runtime: -x64
codecov: true
@ -70,7 +70,7 @@ jobs:
uses: actions/setup-dotnet@v6
with:
dotnet-version: |
8.0.x
10.0.x
- name: DotNet Build
shell: pwsh

8
Directory.Build.props

@ -21,14 +21,6 @@
<!-- Import the shared global .props file -->
<Import Project="$(MSBuildThisFileDirectory)shared-infrastructure\msbuild\props\SixLabors.Global.props" />
<PropertyGroup Condition="'$(TargetFramework)' == 'net8.0' OR '$(TargetFramework)' == 'net9.0'">
<LangVersion>12.0</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net10.0'">
<LangVersion>14.0</LangVersion>
</PropertyGroup>
<!--
Ensure all custom build configurations based upon "Release" are optimized.
This is easier than setting each project individually.

2
README.md

@ -36,7 +36,7 @@ Support the efforts of the development of the Six Labors projects.
## Documentation
- [Detailed documentation](https://sixlabors.github.io/docs/) for the ImageSharp API is available. This includes additional conceptual documentation to help you get started.
- Our [Samples Repository](https://github.com/SixLabors/Samples/tree/main/ImageSharp) is also available containing buildable code samples demonstrating common activities.
- Our [Samples Repository](https://github.com/SixLabors/Samples/tree/main/SixLabors.Samples.ImageSharp) is also available containing buildable code samples demonstrating common activities.
## Questions

18
global.json

@ -0,0 +1,18 @@
// Pins the .NET SDK to major version 10 or later for all SixLabors repositories.
// The build copies this file to consuming repositories together with .editorconfig and
// the other shared config files (see msbuild/targets/SixLabors.Src.targets).
{
"sdk": {
// The floor, not an exact build: resolution never selects an SDK below major 10.
"version": "10.0.0",
// Select the newest installed SDK at or above the floor. This spans feature bands,
// minor versions, and major versions, so a machine with only stable 10.0.x SDKs
// resolves the newest of those, and a machine with a newer SDK resolves that instead.
"rollForward": "latestMajor",
// Let the CLI and Visual Studio select preview SDKs when one is installed.
// Machines and CI lanes without a preview SDK are unaffected.
"allowPrerelease": true
}
}

2
shared-infrastructure

@ -1 +1 @@
Subproject commit 20f15a2d47bba9d8375b5fd34fac283336ec9a5e
Subproject commit 52fc1c3e87a755b2b17ce77e8cd22ec4bea17bcb

4
src/ImageSharp/Common/Extensions/StreamExtensions.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers;
@ -17,7 +17,7 @@ internal static class StreamExtensions
/// <param name="buffer">The buffer.</param>
/// <param name="offset">The offset within the buffer to begin writing.</param>
/// <param name="count">The number of bytes to write to the stream.</param>
public static void Write(this Stream stream, Span<byte> buffer, int offset, int count)
public static void Write(this Stream stream, ReadOnlySpan<byte> buffer, int offset, int count)
=> stream.Write(buffer.Slice(offset, count));
/// <summary>

42
src/ImageSharp/Common/Helpers/Numerics.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Numerics;
@ -939,20 +939,10 @@ internal static class Numerics
/// <typeparam name="TVector">The type of the vector.</typeparam>
/// <param name="span">The given span.</param>
/// <returns>Count of vectors that safely fit into the span.</returns>
public static nuint VectorCount<TVector>(this Span<byte> span)
public static nuint VectorCount<TVector>(this ReadOnlySpan<byte> span)
where TVector : struct
=> (uint)span.Length / (uint)Vector<TVector>.Count;
/// <summary>
/// Gets the count of vectors that safely fit into the given span.
/// </summary>
/// <typeparam name="TVector">The type of the vector.</typeparam>
/// <param name="span">The given span.</param>
/// <returns>Count of vectors that safely fit into the span.</returns>
public static nuint Vector128Count<TVector>(this Span<byte> span)
where TVector : struct
=> (uint)span.Length / (uint)Vector128<TVector>.Count;
/// <summary>
/// Gets the count of vectors that safely fit into the given span.
/// </summary>
@ -963,16 +953,6 @@ internal static class Numerics
where TVector : struct
=> (uint)span.Length / (uint)Vector128<TVector>.Count;
/// <summary>
/// Gets the count of vectors that safely fit into the given span.
/// </summary>
/// <typeparam name="TVector">The type of the vector.</typeparam>
/// <param name="span">The given span.</param>
/// <returns>Count of vectors that safely fit into the span.</returns>
public static nuint Vector256Count<TVector>(this Span<byte> span)
where TVector : struct
=> (uint)span.Length / (uint)Vector256<TVector>.Count;
/// <summary>
/// Gets the count of vectors that safely fit into the given span.
/// </summary>
@ -983,16 +963,6 @@ internal static class Numerics
where TVector : struct
=> (uint)span.Length / (uint)Vector256<TVector>.Count;
/// <summary>
/// Gets the count of vectors that safely fit into the given span.
/// </summary>
/// <typeparam name="TVector">The type of the vector.</typeparam>
/// <param name="span">The given span.</param>
/// <returns>Count of vectors that safely fit into the span.</returns>
public static nuint Vector512Count<TVector>(this Span<byte> span)
where TVector : struct
=> (uint)span.Length / (uint)Vector512<TVector>.Count;
/// <summary>
/// Gets the count of vectors that safely fit into the given span.
/// </summary>
@ -1009,7 +979,7 @@ internal static class Numerics
/// <typeparam name="TVector">The type of the vector.</typeparam>
/// <param name="span">The given span.</param>
/// <returns>Count of vectors that safely fit into the span.</returns>
public static nuint VectorCount<TVector>(this Span<float> span)
public static nuint VectorCount<TVector>(this ReadOnlySpan<float> span)
where TVector : struct
=> (uint)span.Length / (uint)Vector<TVector>.Count;
@ -1019,7 +989,7 @@ internal static class Numerics
/// <typeparam name="TVector">The type of the vector.</typeparam>
/// <param name="span">The given span.</param>
/// <returns>Count of vectors that safely fit into the span.</returns>
public static nuint Vector128Count<TVector>(this Span<float> span)
public static nuint Vector128Count<TVector>(this ReadOnlySpan<float> span)
where TVector : struct
=> (uint)span.Length / (uint)Vector128<TVector>.Count;
@ -1029,7 +999,7 @@ internal static class Numerics
/// <typeparam name="TVector">The type of the vector.</typeparam>
/// <param name="span">The given span.</param>
/// <returns>Count of vectors that safely fit into the span.</returns>
public static nuint Vector256Count<TVector>(this Span<float> span)
public static nuint Vector256Count<TVector>(this ReadOnlySpan<float> span)
where TVector : struct
=> (uint)span.Length / (uint)Vector256<TVector>.Count;
@ -1049,7 +1019,7 @@ internal static class Numerics
/// <typeparam name="TVector">The type of the vector.</typeparam>
/// <param name="span">The given span.</param>
/// <returns>Count of vectors that safely fit into the span.</returns>
public static nuint Vector512Count<TVector>(this Span<float> span)
public static nuint Vector512Count<TVector>(this ReadOnlySpan<float> span)
where TVector : struct
=> (uint)span.Length / (uint)Vector512<TVector>.Count;

6
src/ImageSharp/Common/Helpers/SimdUtils.Shuffle.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Diagnostics;
@ -464,7 +464,7 @@ internal static partial class SimdUtils
}
[Conditional("DEBUG")]
internal static void VerifyShuffle4SpanInput<T>(ReadOnlySpan<T> source, Span<T> destination)
internal static void VerifyShuffle4SpanInput<T>(ReadOnlySpan<T> source, ReadOnlySpan<T> destination)
where T : struct
{
DebugGuard.IsTrue(
@ -479,7 +479,7 @@ internal static partial class SimdUtils
}
[Conditional("DEBUG")]
private static void VerifyShuffle3SpanInput<T>(ReadOnlySpan<T> source, Span<T> destination)
private static void VerifyShuffle3SpanInput<T>(ReadOnlySpan<T> source, ReadOnlySpan<T> destination)
where T : struct
{
DebugGuard.IsTrue(

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

@ -72,7 +72,7 @@ internal static partial class SimdUtils
}
[Conditional("DEBUG")]
private static void DebugVerifySpanInput(ReadOnlySpan<byte> source, Span<float> dest, int shouldBeDivisibleBy)
private static void DebugVerifySpanInput(ReadOnlySpan<byte> source, ReadOnlySpan<float> dest, int shouldBeDivisibleBy)
{
DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!");
DebugGuard.IsTrue(
@ -82,7 +82,7 @@ internal static partial class SimdUtils
}
[Conditional("DEBUG")]
private static void DebugVerifySpanInput(ReadOnlySpan<float> source, Span<byte> destination, int shouldBeDivisibleBy)
private static void DebugVerifySpanInput(ReadOnlySpan<float> source, ReadOnlySpan<byte> destination, int shouldBeDivisibleBy)
{
DebugGuard.IsTrue(source.Length == destination.Length, nameof(source), "Input spans must be of same length!");
DebugGuard.IsTrue(

6
src/ImageSharp/Formats/Exr/Compression/Decompressors/B44ExrCompression.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers;
@ -141,7 +141,7 @@ internal class B44ExrCompression : ExrBaseDecompressor
/// </summary>
/// <param name="b">The source byte data to unpack.</param>
/// <param name="s">Destintation buffer.</param>
private static void Unpack14(Span<byte> b, Span<ushort> s)
private static void Unpack14(ReadOnlySpan<byte> b, Span<ushort> s)
{
s[0] = (ushort)((b[0] << 8) | b[1]);
@ -185,7 +185,7 @@ internal class B44ExrCompression : ExrBaseDecompressor
/// </summary>
/// <param name="b">The source byte data to unpack.</param>
/// <param name="s">The destination buffer.</param>
private static void Unpack3(Span<byte> b, Span<ushort> s)
private static void Unpack3(ReadOnlySpan<byte> b, Span<ushort> s)
{
s[0] = (ushort)((b[0] << 8) | b[1]);

4
src/ImageSharp/Formats/Exr/Compression/ExrBaseDecompressor.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.IO.Compression;
@ -98,7 +98,7 @@ internal abstract class ExrBaseDecompressor : ExrBaseCompression
/// <param name="source">The source data.</param>
/// <param name="unCompressedBytes">The uncompressed bytes.</param>
/// <param name="output">The output to write to.</param>
protected static void Interleave(Span<byte> source, uint unCompressedBytes, Span<byte> output)
protected static void Interleave(ReadOnlySpan<byte> source, uint unCompressedBytes, Span<byte> output)
{
int sourceOffset = 0;
int offset0 = 0;

16
src/ImageSharp/Formats/Exr/ExrDecoderCore.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
@ -320,7 +320,7 @@ internal sealed class ExrDecoderCore : ImageDecoderCore
private static int ReadFloatChannelData(
BufferedReadStream stream,
ExrChannelInfo channel,
Span<byte> decompressedPixelData,
ReadOnlySpan<byte> decompressedPixelData,
Span<float> redPixelData,
Span<float> greenPixelData,
Span<float> bluePixelData,
@ -371,7 +371,7 @@ internal sealed class ExrDecoderCore : ImageDecoderCore
private int ReadUnsignedIntChannelData(
BufferedReadStream stream,
ExrChannelInfo channel,
Span<byte> decompressedPixelData,
ReadOnlySpan<byte> decompressedPixelData,
Span<uint> redPixelData,
Span<uint> greenPixelData,
Span<uint> bluePixelData,
@ -414,7 +414,7 @@ internal sealed class ExrDecoderCore : ImageDecoderCore
/// <param name="pixelData">The pixel data as float.</param>
/// <param name="width">The width in pixel of a row.</param>
/// <returns>The bytes read.</returns>
private static int ReadChannelData(ExrChannelInfo channel, Span<byte> decompressedPixelData, Span<float> pixelData, int width) => channel.PixelType switch
private static int ReadChannelData(ExrChannelInfo channel, ReadOnlySpan<byte> decompressedPixelData, Span<float> pixelData, int width) => channel.PixelType switch
{
ExrPixelType.Half => ReadPixelRowChannelHalfSingle(decompressedPixelData, pixelData, width),
ExrPixelType.Float => ReadPixelRowChannelSingle(decompressedPixelData, pixelData, width),
@ -429,7 +429,7 @@ internal sealed class ExrDecoderCore : ImageDecoderCore
/// <param name="pixelData">The pixel data as uint.</param>
/// <param name="width">The width in pixels.</param>
/// <returns>The bytes read.</returns>
private static int ReadChannelData(ExrChannelInfo channel, Span<byte> decompressedPixelData, Span<uint> pixelData, int width) => channel.PixelType switch
private static int ReadChannelData(ExrChannelInfo channel, ReadOnlySpan<byte> decompressedPixelData, Span<uint> pixelData, int width) => channel.PixelType switch
{
ExrPixelType.UnsignedInt => ReadPixelRowChannelUnsignedInt(decompressedPixelData, pixelData, width),
_ => 0,
@ -442,7 +442,7 @@ internal sealed class ExrDecoderCore : ImageDecoderCore
/// <param name="channelData">The channel data as float.</param>
/// <param name="width">The width of a row in pixels.</param>
/// <returns>The bytes read.</returns>
private static int ReadPixelRowChannelHalfSingle(Span<byte> decompressedPixelData, Span<float> channelData, int width)
private static int ReadPixelRowChannelHalfSingle(ReadOnlySpan<byte> decompressedPixelData, Span<float> channelData, int width)
{
int offset = 0;
for (int x = 0; x < width; x++)
@ -462,7 +462,7 @@ internal sealed class ExrDecoderCore : ImageDecoderCore
/// <param name="channelData">The pixel data as float.</param>
/// <param name="width">The width in pixels of a row.</param>
/// <returns>The bytes read.</returns>
private static int ReadPixelRowChannelSingle(Span<byte> decompressedPixelData, Span<float> channelData, int width)
private static int ReadPixelRowChannelSingle(ReadOnlySpan<byte> decompressedPixelData, Span<float> channelData, int width)
{
int offset = 0;
for (int x = 0; x < width; x++)
@ -482,7 +482,7 @@ internal sealed class ExrDecoderCore : ImageDecoderCore
/// <param name="channelData">The uint pixel data.</param>
/// <param name="width">The width of a row in pixels.</param>
/// <returns>The bytes read.</returns>
private static int ReadPixelRowChannelUnsignedInt(Span<byte> decompressedPixelData, Span<uint> channelData, int width)
private static int ReadPixelRowChannelUnsignedInt(ReadOnlySpan<byte> decompressedPixelData, Span<uint> channelData, int width)
{
int offset = 0;
for (int x = 0; x < width; x++)

8
src/ImageSharp/Formats/Exr/ExrEncoderCore.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers;
@ -364,7 +364,7 @@ internal sealed class ExrEncoderCore
/// <param name="blueBuffer">The blue channel buffer.</param>
/// <param name="greenBuffer">The green channel buffer.</param>
/// <param name="redBuffer">The red channel buffer.</param>
private static void WriteSingleRow(Span<byte> buffer, int width, Span<float> alphaBuffer, Span<float> blueBuffer, Span<float> greenBuffer, Span<float> redBuffer)
private static void WriteSingleRow(Span<byte> buffer, int width, ReadOnlySpan<float> alphaBuffer, ReadOnlySpan<float> blueBuffer, ReadOnlySpan<float> greenBuffer, ReadOnlySpan<float> redBuffer)
{
int offset = 0;
for (int x = 0; x < width; x++)
@ -401,7 +401,7 @@ internal sealed class ExrEncoderCore
/// <param name="blueBuffer">The blue channel buffer.</param>
/// <param name="greenBuffer">The green channel buffer.</param>
/// <param name="redBuffer">The red channel buffer.</param>
private static void WriteHalfSingleRow(Span<byte> buffer, int width, Span<float> alphaBuffer, Span<float> blueBuffer, Span<float> greenBuffer, Span<float> redBuffer)
private static void WriteHalfSingleRow(Span<byte> buffer, int width, ReadOnlySpan<float> alphaBuffer, ReadOnlySpan<float> blueBuffer, ReadOnlySpan<float> greenBuffer, ReadOnlySpan<float> redBuffer)
{
int offset = 0;
for (int x = 0; x < width; x++)
@ -438,7 +438,7 @@ internal sealed class ExrEncoderCore
/// <param name="blueBuffer">The blue channel buffer.</param>
/// <param name="greenBuffer">The green channel buffer.</param>
/// <param name="redBuffer">The red channel buffer.</param>
private static void WriteUnsignedIntRow(Span<byte> buffer, int width, Span<uint> alphaBuffer, Span<uint> blueBuffer, Span<uint> greenBuffer, Span<uint> redBuffer)
private static void WriteUnsignedIntRow(Span<byte> buffer, int width, ReadOnlySpan<uint> alphaBuffer, ReadOnlySpan<uint> blueBuffer, ReadOnlySpan<uint> greenBuffer, ReadOnlySpan<uint> redBuffer)
{
int offset = 0;
for (int x = 0; x < width; x++)

4
src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Numerics;
@ -129,7 +129,7 @@ internal partial struct Block8x8
/// <summary>
/// Cast and copy <see cref="Size"/> <see cref="int"/>-s from the beginning of 'source' span.
/// </summary>
public void LoadFrom(Span<int> source)
public void LoadFrom(ReadOnlySpan<int> source)
{
for (int i = 0; i < Size; i++)
{

4
src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Numerics;
@ -115,7 +115,7 @@ internal partial struct Block8x8F : IEquatable<Block8x8F>
/// Load raw 32bit floating point data from source
/// </summary>
/// <param name="source">Source</param>
public unsafe void LoadFrom(Span<int> source)
public unsafe void LoadFrom(ReadOnlySpan<int> source)
{
fixed (Vector4* ptr = &this.V0L)
{

6
src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
@ -1126,7 +1126,7 @@ internal sealed class JpegDecoderCore : ImageDecoderCore, IRawJpegData
/// <param name="blockDataSpan">The span holding the block resource data.</param>
/// <returns>The length of the name.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
private static int ReadImageResourceNameLength(Span<byte> blockDataSpan)
private static int ReadImageResourceNameLength(ReadOnlySpan<byte> blockDataSpan)
{
byte nameLength = blockDataSpan[2];
int nameDataSize = nameLength == 0 ? 2 : nameLength;
@ -1145,7 +1145,7 @@ internal sealed class JpegDecoderCore : ImageDecoderCore, IRawJpegData
/// <param name="resourceBlockNameLength">The length of the block name.</param>
/// <returns>The block length.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
private static int ReadResourceDataLength(Span<byte> blockDataSpan, int resourceBlockNameLength)
private static int ReadResourceDataLength(ReadOnlySpan<byte> blockDataSpan, int resourceBlockNameLength)
=> BinaryPrimitives.ReadInt32BigEndian(blockDataSpan.Slice(2 + resourceBlockNameLength, 4));
/// <summary>

6
src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
@ -620,7 +620,7 @@ internal sealed unsafe partial class JpegEncoderCore
/// </summary>
/// <param name="components">The collecction of component configuration items.</param>
/// <param name="buffer">Temporary buffer.</param>
private void WriteStartOfScan(Span<JpegComponentConfig> components, Span<byte> buffer) =>
private void WriteStartOfScan(ReadOnlySpan<JpegComponentConfig> components, Span<byte> buffer) =>
this.WriteStartOfScan(components, buffer, 0x00, 0x3f);
/// <summary>
@ -630,7 +630,7 @@ internal sealed unsafe partial class JpegEncoderCore
/// <param name="buffer">Temporary buffer.</param>
/// <param name="spectralStart">Start of spectral selection</param>
/// <param name="spectralEnd">End of spectral selection</param>
private void WriteStartOfScan(Span<JpegComponentConfig> components, Span<byte> buffer, byte spectralStart, byte spectralEnd)
private void WriteStartOfScan(ReadOnlySpan<JpegComponentConfig> components, Span<byte> buffer, byte spectralStart, byte spectralEnd)
{
// Write the SOS (Start Of Scan) marker "\xff\xda" followed by 12 bytes:
// - the marker length "\x00\x0c",

6
src/ImageSharp/Formats/Png/PngEncoderCore.cs

@ -1541,7 +1541,7 @@ internal sealed class PngEncoderCore : IDisposable
/// <param name="stream">The <see cref="Stream"/> to write to.</param>
/// <param name="type">The type of chunk to write.</param>
/// <param name="data">The <see cref="T:byte[]"/> containing data.</param>
private void WriteChunk(Stream stream, PngChunkType type, Span<byte> data)
private void WriteChunk(Stream stream, PngChunkType type, ReadOnlySpan<byte> data)
=> this.WriteChunk(stream, type, data, 0, data.Length);
/// <summary>
@ -1552,7 +1552,7 @@ internal sealed class PngEncoderCore : IDisposable
/// <param name="data">The <see cref="Span{Byte}"/> containing data.</param>
/// <param name="offset">The position to offset the data at.</param>
/// <param name="length">The of the data to write.</param>
private void WriteChunk(Stream stream, PngChunkType type, Span<byte> data, int offset, int length)
private void WriteChunk(Stream stream, PngChunkType type, ReadOnlySpan<byte> data, int offset, int length)
{
Span<byte> buffer = stackalloc byte[8];
@ -1584,7 +1584,7 @@ internal sealed class PngEncoderCore : IDisposable
/// <param name="data">The <see cref="Span{Byte}"/> containing data.</param>
/// <param name="offset">The position to offset the data at.</param>
/// <param name="length">The of the data to write.</param>
private void WriteFrameDataChunk(Stream stream, uint sequenceNumber, Span<byte> data, int offset, int length)
private void WriteFrameDataChunk(Stream stream, uint sequenceNumber, ReadOnlySpan<byte> data, int offset, int length)
{
Span<byte> buffer = stackalloc byte[12];

6
src/ImageSharp/Formats/Tga/TgaEncoderCore.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers;
@ -268,7 +268,7 @@ internal sealed class TgaEncoderCore
/// <param name="pixelRow">A pixel row of the image to encode.</param>
/// <param name="xStart">X coordinate to start searching for the same pixels.</param>
/// <returns>The number of equal pixels.</returns>
private static byte FindEqualPixels<TPixel>(Span<TPixel> pixelRow, int xStart)
private static byte FindEqualPixels<TPixel>(ReadOnlySpan<TPixel> pixelRow, int xStart)
where TPixel : unmanaged, IPixel<TPixel>
{
byte equalPixelCount = 0;
@ -301,7 +301,7 @@ internal sealed class TgaEncoderCore
/// <param name="pixelRow">A pixel row of the image to encode.</param>
/// <param name="xStart">X coordinate to start searching for the unequal pixels.</param>
/// <returns>The number of equal pixels.</returns>
private static byte FindUnEqualPixels<TPixel>(Span<TPixel> pixelRow, int xStart)
private static byte FindUnEqualPixels<TPixel>(ReadOnlySpan<TPixel> pixelRow, int xStart)
where TPixel : unmanaged, IPixel<TPixel>
{
byte unEqualPixelCount = 0;

4
src/ImageSharp/Formats/Tiff/Compression/Compressors/T6BitCompressor.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
@ -148,7 +148,7 @@ internal sealed class T6BitCompressor : TiffCcittCompressor
/// <returns>The index of the first pixel at or after <paramref name="startIndex"/>
/// that does not match <paramref name="color"/>, or the length of <paramref name="row"/>,
/// whichever comes first.</returns>
private static uint FindRunEnd(Span<byte> row, uint startIndex, byte? color = null)
private static uint FindRunEnd(ReadOnlySpan<byte> row, uint startIndex, byte? color = null)
{
if (startIndex >= row.Length)
{

6
src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffLzwEncoder.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers;
@ -104,7 +104,7 @@ internal sealed class TiffLzwEncoder : IDisposable
/// </summary>
/// <param name="data">The data to compress.</param>
/// <param name="stream">The stream to write to.</param>
public void Encode(Span<byte> data, Stream stream)
public void Encode(ReadOnlySpan<byte> data, Stream stream)
{
this.Reset();
@ -214,7 +214,7 @@ internal sealed class TiffLzwEncoder : IDisposable
this.bufferPosition = 0;
}
private byte ReadNextByte(Span<byte> data) => data[this.bufferPosition++];
private byte ReadNextByte(ReadOnlySpan<byte> data) => data[this.bufferPosition++];
private void IncreaseCodeSizeOrResetIfNeeded(Stream stream)
{

6
src/ImageSharp/Formats/Tiff/README.md

@ -2,9 +2,9 @@
## References
- TIFF
- [TIFF 6.0 Specification](http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf),(http://www.npes.org/pdf/TIFF-v6.pdf)
- [TIFF Supplement 1](http://partners.adobe.com/public/developer/en/tiff/TIFFPM6.pdf)
- [TIFF Supplement 2](http://partners.adobe.com/public/developer/en/tiff/TIFFphotoshop.pdf)
- [TIFF 6.0 Specification](https://download.osgeo.org/libtiff/doc/TIFF6.pdf)
- [TIFF Supplement 1](https://download.osgeo.org/libtiff/doc/TIFFPM6.pdf)
- [TIFF Supplement 2](https://download.osgeo.org/libtiff/doc/TIFFphotoshop.pdf)
- [TIFF Supplement 3](http://chriscox.org/TIFFTN3d1.pdf)
- [TIFF-F/FX Extension (RFC2301)](http://www.ietf.org/rfc/rfc2301.txt)
- [TIFF/EP Extension (Wikipedia)](https://en.wikipedia.org/wiki/TIFF/EP)

18
src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
@ -440,8 +440,8 @@ internal class TiffDecoderCore : ImageDecoderCore
int width,
int height,
int rowsPerStrip,
Span<ulong> stripOffsets,
Span<ulong> stripByteCounts,
ReadOnlySpan<ulong> stripOffsets,
ReadOnlySpan<ulong> stripByteCounts,
CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel>
{
@ -518,8 +518,8 @@ internal class TiffDecoderCore : ImageDecoderCore
int width,
int height,
int rowsPerStrip,
Span<ulong> stripOffsets,
Span<ulong> stripByteCounts,
ReadOnlySpan<ulong> stripOffsets,
ReadOnlySpan<ulong> stripByteCounts,
CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel>
{
@ -670,8 +670,8 @@ internal class TiffDecoderCore : ImageDecoderCore
int tileLength,
int tilesAcross,
int tilesDown,
Span<ulong> tileOffsets,
Span<ulong> tileByteCounts,
ReadOnlySpan<ulong> tileOffsets,
ReadOnlySpan<ulong> tileByteCounts,
CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel>
{
@ -780,8 +780,8 @@ internal class TiffDecoderCore : ImageDecoderCore
int tileLength,
int tilesAcross,
int tilesDown,
Span<ulong> tileOffsets,
Span<ulong> tileByteCounts,
ReadOnlySpan<ulong> tileOffsets,
ReadOnlySpan<ulong> tileByteCounts,
CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel>
{

4
src/ImageSharp/Formats/Tiff/Writers/TiffStreamWriter.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers.Binary;
@ -103,7 +103,7 @@ internal sealed class TiffStreamWriter : IDisposable
/// Writes an array of bytes to the current stream, padded to four-bytes.
/// </summary>
/// <param name="value">The bytes to write.</param>
public void WritePadded(Span<byte> value)
public void WritePadded(ReadOnlySpan<byte> value)
{
this.BaseStream.Write(value);

12
src/ImageSharp/Formats/Webp/AlphaDecoder.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers;
@ -275,7 +275,7 @@ internal class AlphaDecoder : IDisposable
Vp8LTransform transform,
int yStart,
int yEnd,
Span<byte> src,
ReadOnlySpan<byte> src,
Span<byte> dst)
{
int bitsPerPixel = 8 >> transform.Bits;
@ -311,7 +311,7 @@ internal class AlphaDecoder : IDisposable
}
}
private static void HorizontalUnfilter(Span<byte> prev, Span<byte> input, Span<byte> dst, int width)
private static void HorizontalUnfilter(ReadOnlySpan<byte> prev, Span<byte> input, Span<byte> dst, int width)
{
if (Vector128.IsHardwareAccelerated && width >= 9)
{
@ -368,7 +368,7 @@ internal class AlphaDecoder : IDisposable
}
}
private static void GradientUnfilter(Span<byte> prev, Span<byte> input, Span<byte> dst, int width)
private static void GradientUnfilter(ReadOnlySpan<byte> prev, Span<byte> input, Span<byte> dst, int width)
{
if (prev.IsEmpty)
{
@ -424,7 +424,7 @@ internal class AlphaDecoder : IDisposable
return true;
}
private static void MapAlpha(Span<byte> src, Span<uint> colorMap, Span<byte> dst, int yStart, int yEnd, int width)
private static void MapAlpha(ReadOnlySpan<byte> src, ReadOnlySpan<uint> colorMap, Span<byte> dst, int yStart, int yEnd, int width)
{
int offset = 0;
for (int y = yStart; y < yEnd; y++)
@ -448,7 +448,7 @@ internal class AlphaDecoder : IDisposable
}
[MethodImpl(InliningOptions.ShortMethod)]
private static void ExtractGreen(Span<uint> argb, Span<byte> alpha, int size)
private static void ExtractGreen(ReadOnlySpan<uint> argb, Span<byte> alpha, int size)
{
for (int i = 0; i < size; i++)
{

4
src/ImageSharp/Formats/Webp/BitWriter/BitWriterBase.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Formats.Webp.Chunks;
@ -177,7 +177,7 @@ internal abstract class BitWriterBase
/// <param name="stream">The stream to write to.</param>
/// <param name="dataBytes">The alpha channel data bytes.</param>
/// <param name="alphaDataIsCompressed">Indicates, if the alpha channel data is compressed.</param>
public static void WriteAlphaChunk(Stream stream, Span<byte> dataBytes, bool alphaDataIsCompressed)
public static void WriteAlphaChunk(Stream stream, ReadOnlySpan<byte> dataBytes, bool alphaDataIsCompressed)
{
long pos = RiffHelper.BeginWriteChunk(stream, (uint)WebpChunkType.Alpha);
byte flags = 0;

4
src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers.Binary;
@ -223,7 +223,7 @@ internal class Vp8BitWriter : BitWriterBase
}
}
public int PutI4Mode(int mode, Span<byte> prob)
public int PutI4Mode(int mode, ReadOnlySpan<byte> prob)
{
if (this.PutBit(mode != B_DC_PRED, prob[0]))
{

4
src/ImageSharp/Formats/Webp/Lossless/BackwardReferenceEncoder.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers;
@ -375,7 +375,7 @@ internal static class BackwardReferenceEncoder
return chosenPathSize;
}
private static void BackwardReferencesHashChainFollowChosenPath(ReadOnlySpan<uint> bgra, int cacheBits, Span<ushort> chosenPath, int chosenPathSize, Vp8LHashChain hashChain, Vp8LBackwardRefs backwardRefs)
private static void BackwardReferencesHashChainFollowChosenPath(ReadOnlySpan<uint> bgra, int cacheBits, ReadOnlySpan<ushort> chosenPath, int chosenPathSize, Vp8LHashChain hashChain, Vp8LBackwardRefs backwardRefs)
{
bool useColorCache = cacheBits > 0;
ColorCache? colorCache = null;

6
src/ImageSharp/Formats/Webp/Lossless/ColorSpaceTransformUtils.cs

@ -17,7 +17,7 @@ internal static class ColorSpaceTransformUtils
const int span = 16;
Span<ushort> values = stackalloc ushort[span];
// These shuffle masks are safe for use with Avx2.Shuffle because all indices are within their respective 128-bit lanes (0–15 for the low mask, 16–31 for the high mask),
// These shuffle masks are safe for use with Avx2.Shuffle because all indices are within their respective 128-bit lanes (0-15 for the low mask, 16-31 for the high mask),
// and all disabled lanes are set to 0xFF to zero those bytes per the vpshufb specification. This guarantees lane-local shuffling with no cross-lane violations.
Vector256<byte> collectColorBlueTransformsShuffleLowMask256 = Vector256.Create(255, 2, 255, 6, 255, 10, 255, 14, 255, 255, 255, 255, 255, 255, 255, 255, 255, 18, 255, 22, 255, 26, 255, 30, 255, 255, 255, 255, 255, 255, 255, 255);
Vector256<byte> collectColorBlueTransformsShuffleHighMask256 = Vector256.Create(255, 255, 255, 255, 255, 255, 255, 255, 255, 2, 255, 6, 255, 10, 255, 14, 255, 255, 255, 255, 255, 255, 255, 255, 255, 18, 255, 22, 255, 26, 255, 30);
@ -121,7 +121,7 @@ internal static class ColorSpaceTransformUtils
}
}
private static void CollectColorBlueTransformsScalar(Span<uint> bgra, int stride, int tileWidth, int tileHeight, int greenToBlue, int redToBlue, Span<int> histo)
private static void CollectColorBlueTransformsScalar(ReadOnlySpan<uint> bgra, int stride, int tileWidth, int tileHeight, int greenToBlue, int redToBlue, Span<int> histo)
{
int pos = 0;
while (tileHeight-- > 0)
@ -230,7 +230,7 @@ internal static class ColorSpaceTransformUtils
}
}
private static void CollectColorRedTransformsScalar(Span<uint> bgra, int stride, int tileWidth, int tileHeight, int greenToRed, Span<int> histo)
private static void CollectColorRedTransformsScalar(ReadOnlySpan<uint> bgra, int stride, int tileWidth, int tileHeight, int greenToRed, Span<int> histo)
{
int pos = 0;
while (tileHeight-- > 0)

2
src/ImageSharp/Formats/Webp/Lossless/CostModel.cs

@ -74,7 +74,7 @@ internal class CostModel
public double GetLiteralCost(uint v) => this.Alpha[v >> 24] + this.Red[(v >> 16) & 0xff] + this.Literal[(v >> 8) & 0xff] + this.Blue[v & 0xff];
private static void ConvertPopulationCountTableToBitEstimates(int numSymbols, Span<uint> populationCounts, double[] output)
private static void ConvertPopulationCountTableToBitEstimates(int numSymbols, ReadOnlySpan<uint> populationCounts, double[] output)
{
uint sum = 0;
int nonzeros = 0;

2
src/ImageSharp/Formats/Webp/Lossless/HistogramEncoder.cs

@ -196,7 +196,7 @@ internal static class HistogramEncoder
private static void HistogramCombineEntropyBin(
Vp8LHistogramSet histograms,
Span<ushort> clusters,
ReadOnlySpan<ushort> clusters,
Span<ushort> clusterMappings,
Vp8LHistogram curCombo,
ReadOnlySpan<ushort> binMap,

8
src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs

@ -159,7 +159,7 @@ internal static class HuffmanUtils
/// <param name="histogramSize">The size of the histogram.</param>
/// <param name="treeDepthLimit">The tree depth limit.</param>
/// <param name="bitDepths">How many bits are used for the symbol.</param>
public static void GenerateOptimalTree(Span<HuffmanTree> tree, Span<uint> histogram, int histogramSize, int treeDepthLimit, byte[] bitDepths)
public static void GenerateOptimalTree(Span<HuffmanTree> tree, ReadOnlySpan<uint> histogram, int histogramSize, int treeDepthLimit, byte[] bitDepths)
{
uint countMin;
int treeSizeOrig = 0;
@ -445,7 +445,7 @@ internal static class HuffmanUtils
return totalSize;
}
private static int CodeRepeatedZeros(int repetitions, Span<HuffmanTreeToken> tokens)
private static int CodeRepeatedZeros(int repetitions, ReadOnlySpan<HuffmanTreeToken> tokens)
{
int pos = 0;
while (repetitions >= 1)
@ -487,7 +487,7 @@ internal static class HuffmanUtils
return pos;
}
private static int CodeRepeatedValues(int repetitions, Span<HuffmanTreeToken> tokens, int value, int prevValue)
private static int CodeRepeatedValues(int repetitions, ReadOnlySpan<HuffmanTreeToken> tokens, int value, int prevValue)
{
int pos = 0;
@ -565,7 +565,7 @@ internal static class HuffmanUtils
}
}
private static void SetBitDepths(Span<HuffmanTree> tree, Span<HuffmanTree> pool, byte[] bitDepths, int level)
private static void SetBitDepths(ReadOnlySpan<HuffmanTree> tree, Span<HuffmanTree> pool, byte[] bitDepths, int level)
{
if (tree[0].PoolIndexLeft >= 0)
{

4
src/ImageSharp/Formats/Webp/Lossless/LosslessUtils.cs

@ -98,7 +98,7 @@ internal static unsafe class LosslessUtils
if (Vector256.IsHardwareAccelerated && pixelData.Length >= 8)
{
// The `255` values disable the write for alpha (A), since 0x80 is set in the control byte (high bit set).
// Each byte index is within its respective 128-bit lane (0–15 and 16–31), so this is safe for per-lane shuffle.
// Each byte index is within its respective 128-bit lane (0-15 and 16-31), so this is safe for per-lane shuffle.
// The high bits are not set for the index bytes, and the values are always < 16 per lane, satisfying AVX2 lane rules.
Vector256<byte> addGreenToBlueAndRedMask = Vector256.Create(1, 255, 1, 255, 5, 255, 5, 255, 9, 255, 9, 255, 13, 255, 13, 255, 17, 255, 17, 255, 21, 255, 21, 255, 25, 255, 25, 255, 29, 255, 29, 255);
nuint numPixels = (uint)pixelData.Length;
@ -675,7 +675,7 @@ internal static unsafe class LosslessUtils
/// <summary>
/// Bundles multiple (1, 2, 4 or 8) pixels into a single pixel.
/// </summary>
public static void BundleColorMap(Span<byte> row, int width, int xBits, Span<uint> dst)
public static void BundleColorMap(ReadOnlySpan<byte> row, int width, int xBits, Span<uint> dst)
{
int x;
if (xBits > 0)

2
src/ImageSharp/Formats/Webp/Lossless/NearLosslessEnc.cs

@ -99,7 +99,7 @@ internal static class NearLosslessEnc
return biased & ~mask;
}
private static bool IsSmooth(Span<uint> prevRow, Span<uint> currRow, Span<uint> nextRow, int ix, int limit) =>
private static bool IsSmooth(ReadOnlySpan<uint> prevRow, ReadOnlySpan<uint> currRow, ReadOnlySpan<uint> nextRow, int ix, int limit) =>
IsNear(currRow[ix], currRow[ix - 1], limit) && // Check that all pixels in 4-connected neighborhood are smooth.
IsNear(currRow[ix], currRow[ix + 1], limit) &&
IsNear(currRow[ix], prevRow[ix], limit) &&

10
src/ImageSharp/Formats/Webp/Lossless/PredictorEncoder.cs

@ -205,7 +205,7 @@ internal static unsafe class PredictorEncoder
TransparentColorMode transparentColorMode,
bool usedSubtractGreen,
bool nearLossless,
Span<uint> modes,
ReadOnlySpan<uint> modes,
Span<short> scratch)
{
const int numPredModes = 14;
@ -334,7 +334,7 @@ internal static unsafe class PredictorEncoder
int height,
Span<uint> upperRowSpan,
Span<uint> currentRowSpan,
Span<byte> maxDiffs,
ReadOnlySpan<byte> maxDiffs,
int mode,
int xStart,
int xEnd,
@ -575,7 +575,7 @@ internal static unsafe class PredictorEncoder
int width,
int height,
int bits,
Span<uint> modes,
ReadOnlySpan<uint> modes,
Span<uint> argbScratch,
Span<uint> argb,
int maxQuantization,
@ -746,7 +746,7 @@ internal static unsafe class PredictorEncoder
}
#pragma warning restore SA1503 // Braces should not be omitted
private static void MaxDiffsForRow(int width, int stride, Span<uint> argb, int offset, Span<byte> maxDiffs, bool usedSubtractGreen)
private static void MaxDiffsForRow(int width, int stride, ReadOnlySpan<uint> argb, int offset, Span<byte> maxDiffs, bool usedSubtractGreen)
{
if (width <= 2)
{
@ -1058,7 +1058,7 @@ internal static unsafe class PredictorEncoder
}
[MethodImpl(InliningOptions.ShortMethod)]
private static float PredictionCostSpatial(Span<int> counts, int weight0, double expVal)
private static float PredictionCostSpatial(ReadOnlySpan<int> counts, int weight0, double expVal)
{
int significantSymbols = 256 >> 4;
double expDecayFactor = 0.6;

8
src/ImageSharp/Formats/Webp/Lossless/Vp8LBitEntropy.cs

@ -100,7 +100,7 @@ internal class Vp8LBitEntropy
return this.Entropy < minLimit ? minLimit : this.Entropy;
}
public void BitsEntropyUnrefined(Span<uint> array, int n)
public void BitsEntropyUnrefined(ReadOnlySpan<uint> array, int n)
{
this.Init();
@ -125,7 +125,7 @@ internal class Vp8LBitEntropy
/// <summary>
/// Get the entropy for the distribution 'X'.
/// </summary>
public void BitsEntropyUnrefined(Span<uint> x, int length, Vp8LStreaks stats)
public void BitsEntropyUnrefined(ReadOnlySpan<uint> x, int length, Vp8LStreaks stats)
{
int i;
int iPrev = 0;
@ -147,7 +147,7 @@ internal class Vp8LBitEntropy
this.Entropy += LosslessUtils.FastSLog2(this.Sum);
}
public void GetCombinedEntropyUnrefined(Span<uint> x, Span<uint> y, int length, Vp8LStreaks stats)
public void GetCombinedEntropyUnrefined(ReadOnlySpan<uint> x, ReadOnlySpan<uint> y, int length, Vp8LStreaks stats)
{
int i;
int iPrev = 0;
@ -169,7 +169,7 @@ internal class Vp8LBitEntropy
this.Entropy += LosslessUtils.FastSLog2(this.Sum);
}
public void GetEntropyUnrefined(Span<uint> x, int length, Vp8LStreaks stats)
public void GetEntropyUnrefined(ReadOnlySpan<uint> x, int length, Vp8LStreaks stats)
{
int i;
int iPrev = 0;

16
src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs

@ -812,7 +812,7 @@ internal class Vp8LEncoder : IDisposable
this.EncodeImageNoHuffman(this.TransformData.GetSpan(), this.HashChain, this.Refs[0], this.Refs[1], transformWidth, transformHeight, this.quality, lowEffort);
}
private void EncodeImageNoHuffman(Span<uint> bgra, Vp8LHashChain hashChain, Vp8LBackwardRefs refsTmp1, Vp8LBackwardRefs refsTmp2, int width, int height, uint quality, bool lowEffort)
private void EncodeImageNoHuffman(ReadOnlySpan<uint> bgra, Vp8LHashChain hashChain, Vp8LBackwardRefs refsTmp1, Vp8LBackwardRefs refsTmp2, int width, int height, uint quality, bool lowEffort)
{
int cacheBits = 0;
ushort[] histogramSymbols = new ushort[1]; // Only one tree, one symbol.
@ -1044,7 +1044,7 @@ internal class Vp8LEncoder : IDisposable
int width,
int histoBits,
Vp8LBackwardRefs backwardRefs,
Span<ushort> histogramSymbols,
ReadOnlySpan<ushort> histogramSymbols,
HuffmanTreeCode[] huffmanCodes)
{
int histoXSize = histoBits > 0 ? LosslessUtils.SubSampleSize(width, histoBits) : 1;
@ -1457,7 +1457,7 @@ internal class Vp8LEncoder : IDisposable
}
}
private static void ApplyPaletteFor(int width, int height, Span<uint> palette, int hashIdx, Span<uint> src, int srcStride, Span<uint> dst, int dstStride, Span<byte> tmpRow, uint[] buffer, int xBits)
private static void ApplyPaletteFor(int width, int height, ReadOnlySpan<uint> palette, int hashIdx, Span<uint> src, int srcStride, Span<uint> dst, int dstStride, Span<byte> tmpRow, uint[] buffer, int xBits)
{
uint prevPix = palette[0];
uint prevIdx = 0;
@ -1494,7 +1494,7 @@ internal class Vp8LEncoder : IDisposable
}
}
private static void ApplyPaletteForWithIdxMap(int width, int height, Span<uint> palette, Span<uint> src, int srcStride, Span<uint> dst, int dstStride, Span<byte> tmpRow, uint[] idxMap, int xBits, uint[] paletteSorted, int paletteSize)
private static void ApplyPaletteForWithIdxMap(int width, int height, ReadOnlySpan<uint> palette, Span<uint> src, int srcStride, Span<uint> dst, int dstStride, Span<byte> tmpRow, uint[] idxMap, int xBits, uint[] paletteSorted, int paletteSize)
{
uint prevPix = palette[0];
uint prevIdx = 0;
@ -1590,7 +1590,7 @@ internal class Vp8LEncoder : IDisposable
/// <param name="palette">The palette.</param>
/// <param name="numColors">Number of colors in the palette.</param>
/// <returns>True, if the palette has no monotonous deltas.</returns>
private static bool PaletteHasNonMonotonousDeltas(Span<uint> palette, int numColors)
private static bool PaletteHasNonMonotonousDeltas(ReadOnlySpan<uint> palette, int numColors)
{
const uint predict = 0x000000;
byte signFound = 0x00;
@ -1619,6 +1619,7 @@ internal class Vp8LEncoder : IDisposable
return (signFound & (signFound << 1)) != 0; // two consequent signs.
}
#pragma warning disable CA1517 // False positive: https://github.com/dotnet/sdk/issues/53388
/// <summary>
/// Find greedily always the closest color of the predicted color to minimize
/// deltas in the palette. This reduces storage needs since the palette is stored with delta encoding.
@ -1647,6 +1648,7 @@ internal class Vp8LEncoder : IDisposable
predict = palette[i];
}
}
#pragma warning restore CA1517
private static void GetHuffBitLengthsAndCodes(Vp8LHistogramSet histogramImage, HuffmanTreeCode[] huffmanCodes)
{
@ -1762,7 +1764,7 @@ internal class Vp8LEncoder : IDisposable
/// <summary>
/// Bundles multiple (1, 2, 4 or 8) pixels into a single pixel.
/// </summary>
private static void BundleColorMap(Span<byte> row, int width, int xBits, Span<uint> dst)
private static void BundleColorMap(ReadOnlySpan<byte> row, int width, int xBits, Span<uint> dst)
{
int x;
if (xBits > 0)
@ -1836,7 +1838,7 @@ internal class Vp8LEncoder : IDisposable
}
[MethodImpl(InliningOptions.ShortMethod)]
private static uint SearchColorGreedy(Span<uint> palette, uint color)
private static uint SearchColorGreedy(ReadOnlySpan<uint> palette, uint color)
{
if (color == palette[0])
{

10
src/ImageSharp/Formats/Webp/Lossless/Vp8LHistogram.cs

@ -441,8 +441,8 @@ internal abstract unsafe class Vp8LHistogram
}
private static double GetCombinedEntropy(
Span<uint> x,
Span<uint> y,
ReadOnlySpan<uint> x,
ReadOnlySpan<uint> y,
int length,
bool isXUsed,
bool isYUsed,
@ -494,7 +494,7 @@ internal abstract unsafe class Vp8LHistogram
return bitEntropy.BitsEntropyRefine() + stats.FinalHuffmanCost();
}
private static double ExtraCostCombined(Span<uint> x, Span<uint> y, int length)
private static double ExtraCostCombined(ReadOnlySpan<uint> x, ReadOnlySpan<uint> y, int length)
{
double cost = 0.0d;
for (int i = 2; i < length - 2; i++)
@ -509,7 +509,7 @@ internal abstract unsafe class Vp8LHistogram
/// <summary>
/// Get the symbol entropy for the distribution 'population'.
/// </summary>
private double PopulationCost(Span<uint> population, int length, ref uint trivialSym, int isUsedIndex, Vp8LStreaks stats, Vp8LBitEntropy bitEntropy)
private double PopulationCost(ReadOnlySpan<uint> population, int length, ref uint trivialSym, int isUsedIndex, Vp8LStreaks stats, Vp8LBitEntropy bitEntropy)
{
bitEntropy.Init();
stats.Clear();
@ -523,7 +523,7 @@ internal abstract unsafe class Vp8LHistogram
return bitEntropy.BitsEntropyRefine() + stats.FinalHuffmanCost();
}
private static double ExtraCost(Span<uint> population, int length)
private static double ExtraCost(ReadOnlySpan<uint> population, int length)
{
double cost = 0.0d;
for (int i = 2; i < length - 2; i++)

4
src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs

@ -339,7 +339,7 @@ internal sealed class WebpLosslessDecoder
}
}
private static void AdvanceByOne(ref int col, ref int row, int width, ColorCache colorCache, ref int decodedPixels, Span<uint> pixelData, ref int lastCached)
private static void AdvanceByOne(ref int col, ref int row, int width, ColorCache colorCache, ref int decodedPixels, ReadOnlySpan<uint> pixelData, ref int lastCached)
{
col++;
decodedPixels++;
@ -826,7 +826,7 @@ internal sealed class WebpLosslessDecoder
decoder.Metadata.HuffmanMask = numBits == 0 ? ~0 : (1 << numBits) - 1;
}
private uint ReadPackedSymbols(Span<HTreeGroup> group, Span<uint> pixelData, int decodedPixels)
private uint ReadPackedSymbols(ReadOnlySpan<HTreeGroup> group, Span<uint> pixelData, int decodedPixels)
{
uint val = (uint)(this.bitReader.PrefetchBits() & (HuffmanUtils.HuffmanPackedTableSize - 1));
HuffmanCode code = group[0].PackedTable[val];

50
src/ImageSharp/Formats/Webp/Lossy/LossyUtils.cs

@ -123,7 +123,7 @@ internal static class LossyUtils
}
[MethodImpl(InliningOptions.ShortMethod)]
public static int Vp8_SseNxN(Span<byte> a, Span<byte> b, int w, int h)
public static int Vp8_SseNxN(ReadOnlySpan<byte> a, ReadOnlySpan<byte> b, int w, int h)
{
int count = 0;
int offset = 0;
@ -285,7 +285,7 @@ internal static class LossyUtils
return Math.Abs(sum2 - sum1) >> 5;
}
public static void DC16(Span<byte> dst, Span<byte> yuv, int offset)
public static void DC16(Span<byte> dst, ReadOnlySpan<byte> yuv, int offset)
{
int offsetMinus1 = offset - 1;
int offsetMinusBps = offset - WebpConstants.Bps;
@ -313,7 +313,7 @@ internal static class LossyUtils
}
}
public static void HE16(Span<byte> dst, Span<byte> yuv, int offset)
public static void HE16(Span<byte> dst, ReadOnlySpan<byte> yuv, int offset)
{
// horizontal
offset--;
@ -327,7 +327,7 @@ internal static class LossyUtils
}
}
public static void DC16NoTop(Span<byte> dst, Span<byte> yuv, int offset)
public static void DC16NoTop(Span<byte> dst, ReadOnlySpan<byte> yuv, int offset)
{
// DC with top samples not available.
int dc = 8;
@ -340,7 +340,7 @@ internal static class LossyUtils
Put16(dc >> 4, dst);
}
public static void DC16NoLeft(Span<byte> dst, Span<byte> yuv, int offset)
public static void DC16NoLeft(Span<byte> dst, ReadOnlySpan<byte> yuv, int offset)
{
// DC with left samples not available.
int dc = 8;
@ -357,7 +357,7 @@ internal static class LossyUtils
public static void DC16NoTopLeft(Span<byte> dst) =>
Put16(0x80, dst); // DC with no top and left samples.
public static void DC8uv(Span<byte> dst, Span<byte> yuv, int offset)
public static void DC8uv(Span<byte> dst, ReadOnlySpan<byte> yuv, int offset)
{
int dc0 = 8;
int offsetMinus1 = offset - 1;
@ -388,7 +388,7 @@ internal static class LossyUtils
}
}
public static void HE8uv(Span<byte> dst, Span<byte> yuv, int offset)
public static void HE8uv(Span<byte> dst, ReadOnlySpan<byte> yuv, int offset)
{
// horizontal
offset--;
@ -403,7 +403,7 @@ internal static class LossyUtils
}
}
public static void DC8uvNoTop(Span<byte> dst, Span<byte> yuv, int offset)
public static void DC8uvNoTop(Span<byte> dst, ReadOnlySpan<byte> yuv, int offset)
{
// DC with no top samples.
int dc0 = 4;
@ -418,7 +418,7 @@ internal static class LossyUtils
Put8x8uv((byte)(dc0 >> 3), dst);
}
public static void DC8uvNoLeft(Span<byte> dst, Span<byte> yuv, int offset)
public static void DC8uvNoLeft(Span<byte> dst, ReadOnlySpan<byte> yuv, int offset)
{
// DC with no left samples.
int offsetMinusBps = offset - WebpConstants.Bps;
@ -436,7 +436,7 @@ internal static class LossyUtils
public static void DC8uvNoTopLeft(Span<byte> dst) =>
Put8x8uv(0x80, dst); // DC with nothing.
public static void DC4(Span<byte> dst, Span<byte> yuv, int offset)
public static void DC4(Span<byte> dst, ReadOnlySpan<byte> yuv, int offset)
{
int dc = 4;
int offsetMinusBps = offset - WebpConstants.Bps;
@ -457,7 +457,7 @@ internal static class LossyUtils
[MethodImpl(InliningOptions.ShortMethod)]
public static void TM4(Span<byte> dst, Span<byte> yuv, int offset) => TrueMotion(dst, yuv, offset, 4);
public static void VE4(Span<byte> dst, Span<byte> yuv, int offset, Span<byte> vals)
public static void VE4(Span<byte> dst, ReadOnlySpan<byte> yuv, int offset, Span<byte> vals)
{
// vertical
int topOffset = offset - WebpConstants.Bps;
@ -472,7 +472,7 @@ internal static class LossyUtils
}
}
public static void HE4(Span<byte> dst, Span<byte> yuv, int offset)
public static void HE4(Span<byte> dst, ReadOnlySpan<byte> yuv, int offset)
{
// horizontal
int offsetMinusOne = offset - 1;
@ -491,7 +491,7 @@ internal static class LossyUtils
BinaryPrimitives.WriteUInt32BigEndian(dst[(3 * WebpConstants.Bps)..], val);
}
public static void RD4(Span<byte> dst, Span<byte> yuv, int offset)
public static void RD4(Span<byte> dst, ReadOnlySpan<byte> yuv, int offset)
{
// Down-right
int offsetMinusOne = offset - 1;
@ -528,7 +528,7 @@ internal static class LossyUtils
Dst(dst, 3, 0, Avg3(d, c, b));
}
public static void VR4(Span<byte> dst, Span<byte> yuv, int offset)
public static void VR4(Span<byte> dst, ReadOnlySpan<byte> yuv, int offset)
{
// Vertical-Right
int offsetMinusOne = offset - 1;
@ -565,7 +565,7 @@ internal static class LossyUtils
Dst(dst, 3, 1, Avg3(b, c, d));
}
public static void LD4(Span<byte> dst, Span<byte> yuv, int offset)
public static void LD4(Span<byte> dst, ReadOnlySpan<byte> yuv, int offset)
{
// Down-Left
byte a = yuv[offset - WebpConstants.Bps];
@ -600,7 +600,7 @@ internal static class LossyUtils
Dst(dst, 3, 3, Avg3(g, h, h));
}
public static void VL4(Span<byte> dst, Span<byte> yuv, int offset)
public static void VL4(Span<byte> dst, ReadOnlySpan<byte> yuv, int offset)
{
// Vertical-Left
byte a = yuv[offset - WebpConstants.Bps];
@ -636,7 +636,7 @@ internal static class LossyUtils
Dst(dst, 3, 3, Avg3(f, g, h));
}
public static void HD4(Span<byte> dst, Span<byte> yuv, int offset)
public static void HD4(Span<byte> dst, ReadOnlySpan<byte> yuv, int offset)
{
// Horizontal-Down
byte i = yuv[offset - 1];
@ -672,7 +672,7 @@ internal static class LossyUtils
Dst(dst, 1, 3, Avg3(l, k, j));
}
public static void HU4(Span<byte> dst, Span<byte> yuv, int offset)
public static void HU4(Span<byte> dst, ReadOnlySpan<byte> yuv, int offset)
{
// Horizontal-Up
byte i = yuv[offset - 1];
@ -705,7 +705,7 @@ internal static class LossyUtils
/// <summary>
/// Paragraph 14.3: Implementation of the Walsh-Hadamard transform inversion.
/// </summary>
public static void TransformWht(Span<short> input, Span<short> output, Span<int> scratch)
public static void TransformWht(ReadOnlySpan<short> input, Span<short> output, Span<int> scratch)
{
Span<int> tmp = scratch[..16];
tmp.Clear();
@ -746,7 +746,7 @@ internal static class LossyUtils
/// Returns the weighted sum of the absolute value of transformed coefficients.
/// w[] contains a row-major 4 by 4 symmetric matrix.
/// </summary>
public static int TTransform(Span<byte> input, Span<ushort> w, Span<int> scratch)
public static int TTransform(ReadOnlySpan<byte> input, Span<ushort> w, Span<int> scratch)
{
int sum = 0;
Span<int> tmp = scratch[..16];
@ -1249,7 +1249,7 @@ internal static class LossyUtils
}
}
public static void TransformDc(Span<short> src, Span<byte> dst)
public static void TransformDc(ReadOnlySpan<short> src, Span<byte> dst)
{
int dc = src[0] + 4;
for (int j = 0; j < 4; j++)
@ -1262,7 +1262,7 @@ internal static class LossyUtils
}
// Simplified transform when only src[0], src[1] and src[4] are non-zero
public static void TransformAc3(Span<short> src, Span<byte> dst)
public static void TransformAc3(ReadOnlySpan<short> src, Span<byte> dst)
{
int a = src[0] + 4;
int c4 = Mul2(src[4]);
@ -2133,7 +2133,7 @@ internal static class LossyUtils
}
[MethodImpl(InliningOptions.ShortMethod)]
private static bool NeedsFilter(Span<byte> p, int offset, int step, int t)
private static bool NeedsFilter(ReadOnlySpan<byte> p, int offset, int step, int t)
{
int p1 = p[offset + (-2 * step)];
int p0 = p[offset - step];
@ -2142,7 +2142,7 @@ internal static class LossyUtils
return (4 * WebpLookupTables.Abs0(p0 - q0)) + WebpLookupTables.Abs0(p1 - q1) <= t;
}
private static bool NeedsFilter2(Span<byte> p, int offset, int step, int t, int it)
private static bool NeedsFilter2(ReadOnlySpan<byte> p, int offset, int step, int t, int it)
{
int step2 = 2 * step;
int step3 = 3 * step;
@ -2357,7 +2357,7 @@ internal static class LossyUtils
=> Vector128_.SubtractSaturate(q, p) | Vector128_.SubtractSaturate(p, q);
[MethodImpl(InliningOptions.ShortMethod)]
private static bool Hev(Span<byte> p, int offset, int step, int thresh)
private static bool Hev(ReadOnlySpan<byte> p, int offset, int step, int thresh)
{
int p1 = p[offset - (2 * step)];
int p0 = p[offset - step];

2
src/ImageSharp/Formats/Webp/Lossy/Vp8EncIterator.cs

@ -854,7 +854,7 @@ internal class Vp8EncIterator
}
}
private static void ImportLine(Span<byte> src, int srcStride, Span<byte> dst, int len, int totalLen)
private static void ImportLine(ReadOnlySpan<byte> src, int srcStride, Span<byte> dst, int len, int totalLen)
{
int i;
int srcIdx = 0;

2
src/ImageSharp/Formats/Webp/Lossy/Vp8EncProba.cs

@ -234,7 +234,7 @@ internal class Vp8EncProba
private static int CalcSkipProba(long nb, long total) => (int)(total != 0 ? (total - nb) * 255 / total : 255);
private static int VariableLevelCost(int level, Span<byte> probas)
private static int VariableLevelCost(int level, ReadOnlySpan<byte> probas)
{
int pattern = WebpLookupTables.Vp8LevelCodes[level - 1][0];
int bits = WebpLookupTables.Vp8LevelCodes[level - 1][1];

28
src/ImageSharp/Formats/Webp/Lossy/Vp8Encoding.cs

@ -599,7 +599,7 @@ internal static unsafe class Vp8Encoding
Unsafe.As<short, Vector128<short>>(ref Unsafe.Add(ref outputRef, 8)) = d2f3.AsInt16();
}
public static void FTransformWht(Span<short> input, Span<short> output, Span<int> scratch)
public static void FTransformWht(ReadOnlySpan<short> input, Span<short> output, Span<int> scratch)
{
Span<int> tmp = scratch[..16];
@ -679,7 +679,7 @@ internal static unsafe class Vp8Encoding
// Left samples are top[-5 .. -2], top_left is top[-1], top are
// located at top[0..3], and top right is top[4..7]
public static void EncPredLuma4(Span<byte> dst, Span<byte> top, int topOffset, Span<byte> vals)
public static void EncPredLuma4(Span<byte> dst, ReadOnlySpan<byte> top, int topOffset, Span<byte> vals)
{
Dc4(dst[I4DC4..], top, topOffset);
Tm4(dst[I4TM4..], top, topOffset);
@ -764,7 +764,7 @@ internal static unsafe class Vp8Encoding
}
}
private static void DcMode(Span<byte> dst, Span<byte> left, Span<byte> top, int size, int round, int shift)
private static void DcMode(Span<byte> dst, Span<byte> left, ReadOnlySpan<byte> top, int size, int round, int shift)
{
int dc = 0;
int j;
@ -813,7 +813,7 @@ internal static unsafe class Vp8Encoding
Fill(dst, dc, size);
}
private static void Dc4(Span<byte> dst, Span<byte> top, int topOffset)
private static void Dc4(Span<byte> dst, ReadOnlySpan<byte> top, int topOffset)
{
uint dc = 4;
int i;
@ -825,7 +825,7 @@ internal static unsafe class Vp8Encoding
Fill(dst, (int)(dc >> 3), 4);
}
private static void Tm4(Span<byte> dst, Span<byte> top, int topOffset)
private static void Tm4(Span<byte> dst, ReadOnlySpan<byte> top, int topOffset)
{
Span<byte> clip = Clip1.AsSpan(255 - top[topOffset - 1]);
for (int y = 0; y < 4; y++)
@ -840,7 +840,7 @@ internal static unsafe class Vp8Encoding
}
}
private static void Ve4(Span<byte> dst, Span<byte> top, int topOffset, Span<byte> vals)
private static void Ve4(Span<byte> dst, ReadOnlySpan<byte> top, int topOffset, Span<byte> vals)
{
// vertical
vals[0] = LossyUtils.Avg3(top[topOffset - 1], top[topOffset], top[topOffset + 1]);
@ -853,7 +853,7 @@ internal static unsafe class Vp8Encoding
}
}
private static void He4(Span<byte> dst, Span<byte> top, int topOffset)
private static void He4(Span<byte> dst, ReadOnlySpan<byte> top, int topOffset)
{
// horizontal
byte x = top[topOffset - 1];
@ -872,7 +872,7 @@ internal static unsafe class Vp8Encoding
BinaryPrimitives.WriteUInt32BigEndian(dst[(3 * WebpConstants.Bps)..], val);
}
private static void Rd4(Span<byte> dst, Span<byte> top, int topOffset)
private static void Rd4(Span<byte> dst, ReadOnlySpan<byte> top, int topOffset)
{
byte x = top[topOffset - 1];
byte i = top[topOffset - 2];
@ -907,7 +907,7 @@ internal static unsafe class Vp8Encoding
LossyUtils.Dst(dst, 3, 0, LossyUtils.Avg3(d, c, b));
}
private static void Vr4(Span<byte> dst, Span<byte> top, int topOffset)
private static void Vr4(Span<byte> dst, ReadOnlySpan<byte> top, int topOffset)
{
byte x = top[topOffset - 1];
byte i = top[topOffset - 2];
@ -942,7 +942,7 @@ internal static unsafe class Vp8Encoding
LossyUtils.Dst(dst, 3, 1, LossyUtils.Avg3(b, c, d));
}
private static void Ld4(Span<byte> dst, Span<byte> top, int topOffset)
private static void Ld4(Span<byte> dst, ReadOnlySpan<byte> top, int topOffset)
{
byte a = top[topOffset + 0];
byte b = top[topOffset + 1];
@ -976,7 +976,7 @@ internal static unsafe class Vp8Encoding
LossyUtils.Dst(dst, 3, 3, LossyUtils.Avg3(g, h, h));
}
private static void Vl4(Span<byte> dst, Span<byte> top, int topOffset)
private static void Vl4(Span<byte> dst, ReadOnlySpan<byte> top, int topOffset)
{
byte a = top[topOffset + 0];
byte b = top[topOffset + 1];
@ -1011,7 +1011,7 @@ internal static unsafe class Vp8Encoding
LossyUtils.Dst(dst, 3, 3, LossyUtils.Avg3(f, g, h));
}
private static void Hd4(Span<byte> dst, Span<byte> top, int topOffset)
private static void Hd4(Span<byte> dst, ReadOnlySpan<byte> top, int topOffset)
{
byte x = top[topOffset - 1];
byte i = top[topOffset - 2];
@ -1046,7 +1046,7 @@ internal static unsafe class Vp8Encoding
LossyUtils.Dst(dst, 1, 3, LossyUtils.Avg3(l, k, j));
}
private static void Hu4(Span<byte> dst, Span<byte> top, int topOffset)
private static void Hu4(Span<byte> dst, ReadOnlySpan<byte> top, int topOffset)
{
byte i = top[topOffset - 2];
byte j = top[topOffset - 3];
@ -1088,7 +1088,7 @@ internal static unsafe class Vp8Encoding
private static byte Clip8b(int v) => (v & ~0xff) == 0 ? (byte)v : v < 0 ? (byte)0 : (byte)255;
[MethodImpl(InliningOptions.ShortMethod)]
private static void Store(Span<byte> dst, Span<byte> reference, int x, int y, int v) => dst[x + (y * WebpConstants.Bps)] = LossyUtils.Clip8B(reference[x + (y * WebpConstants.Bps)] + (v >> 3));
private static void Store(Span<byte> dst, ReadOnlySpan<byte> reference, int x, int y, int v) => dst[x + (y * WebpConstants.Bps)] = LossyUtils.Clip8B(reference[x + (y * WebpConstants.Bps)] + (v >> 3));
[MethodImpl(InliningOptions.ShortMethod)]
private static int Mul(int a, int b) => (a * b) >> 16;

2
src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs

@ -235,7 +235,7 @@ internal class Vp8Residual
}
[MethodImpl(InliningOptions.ShortMethod)]
private static int LevelCost(Span<ushort> table, int level)
private static int LevelCost(ReadOnlySpan<ushort> table, int level)
=> WebpLookupTables.Vp8LevelFixedCosts[level] + table[level > WebpConstants.MaxVariableLevel ? WebpConstants.MaxVariableLevel : level];
private static int RecordStats(int bit, Vp8StatsArray statsArr, int idx)

2
src/ImageSharp/Formats/Webp/Lossy/Vp8SegmentInfo.cs

@ -67,7 +67,7 @@ internal class Vp8SegmentInfo
public int LambdaMode { get; set; }
public void StoreMaxDelta(Span<short> dcs)
public void StoreMaxDelta(ReadOnlySpan<short> dcs)
{
// We look at the first three AC coefficients to determine what is the average
// delta between each sub-4x4 block.

10
src/ImageSharp/Formats/Webp/Lossy/YuvConversion.cs

@ -39,7 +39,7 @@ internal static class YuvConversion
}
}
private static void UpSampleScalar(Span<byte> topY, Span<byte> bottomY, Span<byte> topU, Span<byte> topV, Span<byte> curU, Span<byte> curV, Span<byte> topDst, Span<byte> bottomDst, int len)
private static void UpSampleScalar(ReadOnlySpan<byte> topY, ReadOnlySpan<byte> bottomY, ReadOnlySpan<byte> topU, ReadOnlySpan<byte> topV, ReadOnlySpan<byte> curU, ReadOnlySpan<byte> curV, Span<byte> topDst, Span<byte> bottomDst, int len)
{
const int xStep = 3;
int lastPixelPair = (len - 1) >> 1;
@ -346,7 +346,7 @@ internal static class YuvConversion
/// <param name="y">The destination span for y.</param>
/// <param name="width">The width.</param>
[MethodImpl(InliningOptions.ShortMethod)]
public static void ConvertRgbaToY(Span<Bgra32> rowSpan, Span<byte> y, int width)
public static void ConvertRgbaToY(ReadOnlySpan<Bgra32> rowSpan, Span<byte> y, int width)
{
for (int x = 0; x < width; x++)
{
@ -361,7 +361,7 @@ internal static class YuvConversion
/// <param name="u">The destination span for u.</param>
/// <param name="v">The destination span for v.</param>
/// <param name="width">The width.</param>
public static void ConvertRgbaToUv(Span<ushort> rgb, Span<byte> u, Span<byte> v, int width)
public static void ConvertRgbaToUv(ReadOnlySpan<ushort> rgb, Span<byte> u, Span<byte> v, int width)
{
int rgbIdx = 0;
for (int i = 0; i < width; i += 1, rgbIdx += 4)
@ -372,7 +372,7 @@ internal static class YuvConversion
}
}
public static void AccumulateRgb(Span<Bgra32> rowSpan, Span<Bgra32> nextRowSpan, Span<ushort> dst, int width)
public static void AccumulateRgb(ReadOnlySpan<Bgra32> rowSpan, ReadOnlySpan<Bgra32> nextRowSpan, Span<ushort> dst, int width)
{
Bgra32 bgra0;
Bgra32 bgra1;
@ -416,7 +416,7 @@ internal static class YuvConversion
}
}
public static void AccumulateRgba(Span<Bgra32> rowSpan, Span<Bgra32> nextRowSpan, Span<ushort> dst, int width)
public static void AccumulateRgba(ReadOnlySpan<Bgra32> rowSpan, ReadOnlySpan<Bgra32> nextRowSpan, Span<ushort> dst, int width)
{
Bgra32 bgra0;
Bgra32 bgra1;

8
src/ImageSharp/ImageSharp.csproj

@ -23,19 +23,19 @@
</PropertyGroup>
<PropertyGroup>
<!--Bump to v4.0 prior to tagged release.-->
<MinVerMinimumMajorMinor>4.0</MinVerMinimumMajorMinor>
<!--Bump to v5.0 prior to tagged release.-->
<MinVerMinimumMajorMinor>5.0</MinVerMinimumMajorMinor>
</PropertyGroup>
<Choose>
<When Condition="$(SIXLABORS_TESTING_PREVIEW) == true">
<PropertyGroup>
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
<TargetFrameworks>net10.0;net11.0</TargetFrameworks>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks>net10.0</TargetFrameworks>
</PropertyGroup>
</Otherwise>
</Choose>

2
src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs

@ -412,7 +412,7 @@ public partial class PixelOperations<TPixel>
}
[MethodImpl(InliningOptions.ShortMethod)]
internal static void GuardUnpackIntoRgbPlanes(Span<float> redChannel, Span<float> greenChannel, Span<float> blueChannel, ReadOnlySpan<TPixel> source)
internal static void GuardUnpackIntoRgbPlanes(ReadOnlySpan<float> redChannel, Span<float> greenChannel, Span<float> blueChannel, ReadOnlySpan<TPixel> source)
{
Guard.IsTrue(greenChannel.Length == redChannel.Length, nameof(greenChannel), "Channels must be of same size!");
Guard.IsTrue(blueChannel.Length == redChannel.Length, nameof(blueChannel), "Channels must be of same size!");

12
src/ImageSharp/Processing/Processors/Transforms/Resamplers/CubicResampler.cs

@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms;
/// Cubic filters contain a collection of different filters of varying B-Spline and
/// Cardinal values. With these two values you can generate any smoothly fitting
/// (continuious first derivative) piece-wise cubic filter.
/// <see href="http://www.imagemagick.org/Usage/filter/#cubic_bc"/>
/// <see href="https://usage.imagemagick.org/filter/#cubic_bc"/>
/// <see href="https://www.cs.utexas.edu/~fussell/courses/cs384g-fall2013/lectures/mitchell/Mitchell.pdf"/>
/// </summary>
public readonly struct CubicResampler : IResampler
@ -39,23 +39,19 @@ public readonly struct CubicResampler : IResampler
/// <summary>
/// The function implements the Robidoux algorithm.
/// <see href="http://www.imagemagick.org/Usage/filter/#robidoux"/>
/// <see href="https://usage.imagemagick.org/filter/#robidoux"/>
/// </summary>
public static readonly CubicResampler Robidoux = new(2, .37821575509399867F, .31089212245300067F);
/// <summary>
/// The function implements the Robidoux Sharp algorithm.
/// <see href="http://www.imagemagick.org/Usage/filter/#robidoux"/>
/// <see href="https://usage.imagemagick.org/filter/#robidoux"/>
/// </summary>
public static readonly CubicResampler RobidouxSharp = new(2, .2620145123990142F, .3689927438004929F);
/// <summary>
/// The function implements the spline algorithm.
/// <see href="http://www.imagemagick.org/Usage/filter/#cubic_bc"/>
/// </summary>
/// <summary>
/// The function implements the Robidoux Sharp algorithm.
/// <see href="http://www.imagemagick.org/Usage/filter/#robidoux"/>
/// <see href="https://usage.imagemagick.org/filter/#cubic_bc"/>
/// </summary>
public static readonly CubicResampler Spline = new(2, 1, 0);

2
src/ImageSharp/Processing/Processors/Transforms/Resamplers/WelchResampler.cs

@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms;
/// <summary>
/// The function implements the welch algorithm.
/// <see href="http://www.imagemagick.org/Usage/filter/"/>
/// <see href="https://usage.imagemagick.org/filter/"/>
/// </summary>
public readonly struct WelchResampler : IResampler
{

3
tests/Directory.Build.targets

@ -23,9 +23,8 @@
Magick.NET 14.15.0 disables WebP-compressed TIFF support on Windows.
https://github.com/ImageMagick/tiff/commit/978181b6c999ee013f1b6df0a010d8c550d378cf
-->
<PackageReference Update="Magick.NET-Q16-AnyCPU" Version="14.14.0" />
<PackageReference Update="Magick.NET-Q16-AnyCPU" Version="14.16.0" />
<PackageReference Update="Microsoft.DotNet.RemoteExecutor" Version="10.0.0-beta.25563.105" />
<PackageReference Update="Microsoft.DotNet.XUnitExtensions" Version="8.0.0-beta.23580.1" />
<PackageReference Update="Moq" Version="4.20.72" />
<PackageReference Update="NetVips" Version="3.0.0" />
<PackageReference Update="NetVips.Native" Version="8.16.0" />

4
tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj

@ -39,12 +39,12 @@
<Choose>
<When Condition="$(SIXLABORS_TESTING_PREVIEW) == true">
<PropertyGroup>
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
<TargetFrameworks>net10.0;net11.0</TargetFrameworks>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks>net10.0</TargetFrameworks>
</PropertyGroup>
</Otherwise>
</Choose>

4
tests/ImageSharp.PublicApi.Tests/ImageSharp.PublicApi.Tests.csproj

@ -10,12 +10,12 @@
<Choose>
<When Condition="$(SIXLABORS_TESTING_PREVIEW) == true">
<PropertyGroup>
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
<TargetFrameworks>net10.0;net11.0</TargetFrameworks>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks>net10.0</TargetFrameworks>
</PropertyGroup>
</Otherwise>
</Choose>

4
tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj

@ -18,12 +18,12 @@
<Choose>
<When Condition="$(SIXLABORS_TESTING_PREVIEW) == true">
<PropertyGroup>
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
<TargetFrameworks>net10.0;net11.0</TargetFrameworks>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks>net10.0</TargetFrameworks>
</PropertyGroup>
</Otherwise>
</Choose>

8
tests/ImageSharp.Tests.ProfilingSandbox/Program.cs

@ -4,7 +4,7 @@
using SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations;
using SixLabors.ImageSharp.Tests.ProfilingBenchmarks;
using SixLabors.ImageSharp.Tests.ProfilingSandbox;
using Xunit.Abstractions;
using Xunit;
// in this file, comments are used for disabling stuff for local execution
#pragma warning disable SA1515
@ -32,7 +32,13 @@ static void RunToVector4ProfilingTest()
sealed class ConsoleOutput : ITestOutputHelper
{
public void Write(string message) => Console.Write(message);
public void Write(string format, params object[] args) => Console.Write(format, args);
public void WriteLine(string message) => Console.WriteLine(message);
public void WriteLine(string format, params object[] args) => Console.WriteLine(format, args);
public string Output { get; }
}

1
tests/ImageSharp.Tests/ColorProfiles/Icc/ColorProfileConverterTests.Icc.cs

@ -6,7 +6,6 @@ using SixLabors.ImageSharp.ColorProfiles;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
using Wacton.Unicolour;
using Wacton.Unicolour.Icc;
using Xunit.Abstractions;
using Rgb = SixLabors.ImageSharp.ColorProfiles.Rgb;
namespace SixLabors.ImageSharp.Tests.ColorProfiles.Icc;

2
tests/ImageSharp.Tests/ColorProfiles/RgbAndHslConversionTest.cs

@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
/// <remarks>
/// Test data generated using:
/// <see href="http://www.colorhexa.com"/>
/// <see href="http://www.rapidtables.com/convert/color/hsl-to-rgb"/>
/// <see href="https://www.rapidtables.com/convert/color/hsl-to-rgb.html"/>
/// </remarks>
[Trait("Color", "Conversion")]
public class RgbAndHslConversionTest

2
tests/ImageSharp.Tests/Common/NumericsTests.cs

@ -1,8 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Common;
public class NumericsTests

1
tests/ImageSharp.Tests/Common/SimdUtilsTests.cs

@ -9,7 +9,6 @@ using System.Runtime.Intrinsics.X86;
using SixLabors.ImageSharp.Common.Helpers;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Common;

1
tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs

@ -7,7 +7,6 @@ using System.Runtime.Intrinsics;
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using SixLabors.ImageSharp.Tests.TestUtilities;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs

@ -4,7 +4,6 @@
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using SixLabors.ImageSharp.Tests.TestUtilities;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs

@ -4,7 +4,6 @@
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using SixLabors.ImageSharp.Tests.TestUtilities;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/HuffmanScanEncoderTests.cs

@ -2,7 +2,6 @@
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs

@ -9,7 +9,6 @@ using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/ParseStreamTests.cs

@ -6,7 +6,6 @@ using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.AccurateDCT.cs

@ -3,7 +3,6 @@
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.FastFloatingPointDCT.cs

@ -4,7 +4,6 @@
// ReSharper disable InconsistentNaming
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.StandardIntegerDCT.cs

@ -3,7 +3,6 @@
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

2
tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs

@ -1,8 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs

@ -9,7 +9,6 @@ using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/SpectralToPixelConversionTests.cs

@ -7,7 +7,6 @@ using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Formats.Jpg;

1
tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs

@ -6,7 +6,6 @@ using System.Text;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.PixelFormats;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;

2
tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.LLM_FloatingPoint_DCT.cs

@ -5,8 +5,6 @@ using System.Numerics;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;

1
tests/ImageSharp.Tests/Formats/Jpg/Utils/VerifyJpeg.cs

@ -3,7 +3,6 @@
using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder;
using SixLabors.ImageSharp.PixelFormats;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils;

1
tests/ImageSharp.Tests/Formats/Png/PngEncoderFilterTests.cs

@ -6,7 +6,6 @@
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Formats.Png.Filters;
using SixLabors.ImageSharp.Tests.TestUtilities;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Formats.Png;

8
tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs

@ -200,14 +200,14 @@ public partial class PngEncoderTests
return;
}
foreach (object[] filterMethod in PngFilterMethods)
foreach (TheoryDataRow<PngFilterMethod> filterMethod in PngFilterMethods)
{
foreach (PngInterlaceMode interlaceMode in InterlaceMode)
{
TestPngEncoderCore(
provider,
pngColorType,
(PngFilterMethod)filterMethod[0],
filterMethod.Data,
pngBitDepth,
interlaceMode,
appendPngColorType: true,
@ -236,14 +236,14 @@ public partial class PngEncoderTests
public void WorksWithAllBitDepthsAndExcludeAllFilter<TPixel>(TestImageProvider<TPixel> provider, PngColorType pngColorType, PngBitDepth pngBitDepth)
where TPixel : unmanaged, IPixel<TPixel>
{
foreach (object[] filterMethod in PngFilterMethods)
foreach (TheoryDataRow<PngFilterMethod> filterMethod in PngFilterMethods)
{
foreach (PngInterlaceMode interlaceMode in InterlaceMode)
{
TestPngEncoderCore(
provider,
pngColorType,
(PngFilterMethod)filterMethod[0],
filterMethod.Data,
pngBitDepth,
interlaceMode,
appendPngColorType: true,

1
tests/ImageSharp.Tests/Helpers/ParallelRowIteratorTests.cs

@ -7,7 +7,6 @@ using Castle.Core.Configuration;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Helpers;

10
tests/ImageSharp.Tests/IO/LocalFileSystemTests.cs

@ -50,7 +50,12 @@ public class LocalFileSystemTests
await using (FileStream stream = (FileStream)fs.OpenReadAsynchronous(path))
using (StreamReader reader = new(stream))
{
// .NET 11 reports IsAsync false for regular files on Unix: https://github.com/dotnet/runtime/pull/125220
#if NET11_0_OR_GREATER
Assert.Equal(OperatingSystem.IsWindows(), stream.IsAsync);
#else
Assert.True(stream.IsAsync);
#endif
Assert.True(stream.CanRead);
Assert.False(stream.CanWrite);
@ -105,7 +110,12 @@ public class LocalFileSystemTests
await using (FileStream stream = (FileStream)fs.CreateAsynchronous(path))
await using (StreamWriter writer = new(stream))
{
// .NET 11 reports IsAsync false for regular files on Unix: https://github.com/dotnet/runtime/pull/125220
#if NET11_0_OR_GREATER
Assert.Equal(OperatingSystem.IsWindows(), stream.IsAsync);
#else
Assert.True(stream.IsAsync);
#endif
Assert.True(stream.CanRead);
Assert.True(stream.CanWrite);

1
tests/ImageSharp.Tests/Image/ImageTests.Decode_Cancellation.cs

@ -3,6 +3,7 @@
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Tests.TestUtilities;
using XUnit;
namespace SixLabors.ImageSharp.Tests;

5
tests/ImageSharp.Tests/ImageSharp.Tests.csproj

@ -12,12 +12,12 @@
<Choose>
<When Condition="$(SIXLABORS_TESTING_PREVIEW) == true">
<PropertyGroup>
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
<TargetFrameworks>net10.0;net11.0</TargetFrameworks>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks>net10.0</TargetFrameworks>
</PropertyGroup>
</Otherwise>
</Choose>
@ -45,7 +45,6 @@
<PackageReference Include="BenchmarkDotNet" Version="0.13.0" />
<PackageReference Include="Magick.NET-Q16-AnyCPU" />
<PackageReference Include="Microsoft.DotNet.RemoteExecutor" />
<PackageReference Include="Microsoft.DotNet.XUnitExtensions" />
<PackageReference Include="Moq" />
<PackageReference Include="runtime.osx.10.10-x64.CoreCompat.System.Drawing" Condition="'$(IsOSX)'=='true'" />
<PackageReference Include="SharpZipLib" />

2
tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedMemoryPoolTests.cs

@ -5,7 +5,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.DotNet.RemoteExecutor;
using SixLabors.ImageSharp.Memory.Internals;
using Xunit.Abstractions;
using XUnit;
namespace SixLabors.ImageSharp.Tests.Memory.Allocators;

502
tests/ImageSharp.Tests/Metadata/Profiles/Exif/Values/ExifValuesTests.cs

@ -11,329 +11,329 @@ public class ExifValuesTests
{
public static TheoryData<ExifTag> ByteTags => new()
{
{ ExifTag.FaxProfile },
{ ExifTag.ModeNumber },
{ ExifTag.GPSAltitudeRef }
(ExifTag)ExifTag.FaxProfile,
(ExifTag)ExifTag.ModeNumber,
(ExifTag)ExifTag.GPSAltitudeRef
};
public static TheoryData<ExifTag> ByteArrayTags => new()
{
{ ExifTag.ClipPath },
{ ExifTag.VersionYear },
{ ExifTag.XMP },
{ ExifTag.CFAPattern2 },
{ ExifTag.TIFFEPStandardID },
{ ExifTag.GPSVersionID },
(ExifTag)ExifTag.ClipPath,
(ExifTag)ExifTag.VersionYear,
(ExifTag)ExifTag.XMP,
(ExifTag)ExifTag.CFAPattern2,
(ExifTag)ExifTag.TIFFEPStandardID,
(ExifTag)ExifTag.GPSVersionID,
};
public static TheoryData<ExifTag> DoubleArrayTags => new()
{
{ ExifTag.PixelScale },
{ ExifTag.IntergraphMatrix },
{ ExifTag.ModelTiePoint },
{ ExifTag.ModelTransform }
(ExifTag)ExifTag.PixelScale,
(ExifTag)ExifTag.IntergraphMatrix,
(ExifTag)ExifTag.ModelTiePoint,
(ExifTag)ExifTag.ModelTransform
};
public static TheoryData<ExifTag> LongTags => new()
{
{ ExifTag.SubfileType },
{ ExifTag.SubIFDOffset },
{ ExifTag.GPSIFDOffset },
{ ExifTag.T4Options },
{ ExifTag.T6Options },
{ ExifTag.XClipPathUnits },
{ ExifTag.YClipPathUnits },
{ ExifTag.ProfileType },
{ ExifTag.CodingMethods },
{ ExifTag.T82ptions },
{ ExifTag.JPEGInterchangeFormat },
{ ExifTag.JPEGInterchangeFormatLength },
{ ExifTag.MDFileTag },
{ ExifTag.StandardOutputSensitivity },
{ ExifTag.RecommendedExposureIndex },
{ ExifTag.ISOSpeed },
{ ExifTag.ISOSpeedLatitudeyyy },
{ ExifTag.ISOSpeedLatitudezzz },
{ ExifTag.FaxRecvParams },
{ ExifTag.FaxRecvTime },
{ ExifTag.ImageNumber },
(ExifTag)ExifTag.SubfileType,
(ExifTag)ExifTag.SubIFDOffset,
(ExifTag)ExifTag.GPSIFDOffset,
(ExifTag)ExifTag.T4Options,
(ExifTag)ExifTag.T6Options,
(ExifTag)ExifTag.XClipPathUnits,
(ExifTag)ExifTag.YClipPathUnits,
(ExifTag)ExifTag.ProfileType,
(ExifTag)ExifTag.CodingMethods,
(ExifTag)ExifTag.T82ptions,
(ExifTag)ExifTag.JPEGInterchangeFormat,
(ExifTag)ExifTag.JPEGInterchangeFormatLength,
(ExifTag)ExifTag.MDFileTag,
(ExifTag)ExifTag.StandardOutputSensitivity,
(ExifTag)ExifTag.RecommendedExposureIndex,
(ExifTag)ExifTag.ISOSpeed,
(ExifTag)ExifTag.ISOSpeedLatitudeyyy,
(ExifTag)ExifTag.ISOSpeedLatitudezzz,
(ExifTag)ExifTag.FaxRecvParams,
(ExifTag)ExifTag.FaxRecvTime,
(ExifTag)ExifTag.ImageNumber,
};
public static TheoryData<ExifTag> LongArrayTags => new()
{
{ ExifTag.FreeOffsets },
{ ExifTag.FreeByteCounts },
{ ExifTag.ColorResponseUnit },
{ ExifTag.SMinSampleValue },
{ ExifTag.SMaxSampleValue },
{ ExifTag.JPEGQTables },
{ ExifTag.JPEGDCTables },
{ ExifTag.JPEGACTables },
{ ExifTag.StripRowCounts },
{ ExifTag.IntergraphRegisters }
(ExifTag)ExifTag.FreeOffsets,
(ExifTag)ExifTag.FreeByteCounts,
(ExifTag)ExifTag.ColorResponseUnit,
(ExifTag)ExifTag.SMinSampleValue,
(ExifTag)ExifTag.SMaxSampleValue,
(ExifTag)ExifTag.JPEGQTables,
(ExifTag)ExifTag.JPEGDCTables,
(ExifTag)ExifTag.JPEGACTables,
(ExifTag)ExifTag.StripRowCounts,
(ExifTag)ExifTag.IntergraphRegisters
};
public static TheoryData<ExifTag> NumberTags => new()
{
{ ExifTag.ImageWidth },
{ ExifTag.ImageLength },
{ ExifTag.TileWidth },
{ ExifTag.TileLength },
{ ExifTag.BadFaxLines },
{ ExifTag.ConsecutiveBadFaxLines },
{ ExifTag.PixelXDimension },
{ ExifTag.PixelYDimension }
(ExifTag)ExifTag.ImageWidth,
(ExifTag)ExifTag.ImageLength,
(ExifTag)ExifTag.TileWidth,
(ExifTag)ExifTag.TileLength,
(ExifTag)ExifTag.BadFaxLines,
(ExifTag)ExifTag.ConsecutiveBadFaxLines,
(ExifTag)ExifTag.PixelXDimension,
(ExifTag)ExifTag.PixelYDimension
};
public static TheoryData<ExifTag> NumberArrayTags => new()
{
{ ExifTag.StripOffsets },
{ ExifTag.StripByteCounts },
{ ExifTag.TileByteCounts },
{ ExifTag.TileOffsets },
{ ExifTag.ImageLayer }
(ExifTag)ExifTag.StripOffsets,
(ExifTag)ExifTag.StripByteCounts,
(ExifTag)ExifTag.TileByteCounts,
(ExifTag)ExifTag.TileOffsets,
(ExifTag)ExifTag.ImageLayer
};
public static TheoryData<ExifTag> RationalTags => new()
{
{ ExifTag.XPosition },
{ ExifTag.YPosition },
{ ExifTag.XResolution },
{ ExifTag.YResolution },
{ ExifTag.BatteryLevel },
{ ExifTag.ExposureTime },
{ ExifTag.FNumber },
{ ExifTag.MDScalePixel },
{ ExifTag.CompressedBitsPerPixel },
{ ExifTag.ApertureValue },
{ ExifTag.MaxApertureValue },
{ ExifTag.SubjectDistance },
{ ExifTag.FocalLength },
{ ExifTag.FlashEnergy2 },
{ ExifTag.FocalPlaneXResolution2 },
{ ExifTag.FocalPlaneYResolution2 },
{ ExifTag.ExposureIndex2 },
{ ExifTag.Humidity },
{ ExifTag.Pressure },
{ ExifTag.Acceleration },
{ ExifTag.FlashEnergy },
{ ExifTag.FocalPlaneXResolution },
{ ExifTag.FocalPlaneYResolution },
{ ExifTag.ExposureIndex },
{ ExifTag.DigitalZoomRatio },
{ ExifTag.GPSAltitude },
{ ExifTag.GPSDOP },
{ ExifTag.GPSSpeed },
{ ExifTag.GPSTrack },
{ ExifTag.GPSImgDirection },
{ ExifTag.GPSDestBearing },
{ ExifTag.GPSDestDistance },
{ ExifTag.GPSHPositioningError },
(ExifTag)ExifTag.XPosition,
(ExifTag)ExifTag.YPosition,
(ExifTag)ExifTag.XResolution,
(ExifTag)ExifTag.YResolution,
(ExifTag)ExifTag.BatteryLevel,
(ExifTag)ExifTag.ExposureTime,
(ExifTag)ExifTag.FNumber,
(ExifTag)ExifTag.MDScalePixel,
(ExifTag)ExifTag.CompressedBitsPerPixel,
(ExifTag)ExifTag.ApertureValue,
(ExifTag)ExifTag.MaxApertureValue,
(ExifTag)ExifTag.SubjectDistance,
(ExifTag)ExifTag.FocalLength,
(ExifTag)ExifTag.FlashEnergy2,
(ExifTag)ExifTag.FocalPlaneXResolution2,
(ExifTag)ExifTag.FocalPlaneYResolution2,
(ExifTag)ExifTag.ExposureIndex2,
(ExifTag)ExifTag.Humidity,
(ExifTag)ExifTag.Pressure,
(ExifTag)ExifTag.Acceleration,
(ExifTag)ExifTag.FlashEnergy,
(ExifTag)ExifTag.FocalPlaneXResolution,
(ExifTag)ExifTag.FocalPlaneYResolution,
(ExifTag)ExifTag.ExposureIndex,
(ExifTag)ExifTag.DigitalZoomRatio,
(ExifTag)ExifTag.GPSAltitude,
(ExifTag)ExifTag.GPSDOP,
(ExifTag)ExifTag.GPSSpeed,
(ExifTag)ExifTag.GPSTrack,
(ExifTag)ExifTag.GPSImgDirection,
(ExifTag)ExifTag.GPSDestBearing,
(ExifTag)ExifTag.GPSDestDistance,
(ExifTag)ExifTag.GPSHPositioningError,
};
public static TheoryData<ExifTag> RationalArrayTags => new()
{
{ ExifTag.WhitePoint },
{ ExifTag.PrimaryChromaticities },
{ ExifTag.YCbCrCoefficients },
{ ExifTag.ReferenceBlackWhite },
{ ExifTag.GPSLatitude },
{ ExifTag.GPSLongitude },
{ ExifTag.GPSTimestamp },
{ ExifTag.GPSDestLatitude },
{ ExifTag.GPSDestLongitude },
{ ExifTag.LensSpecification }
(ExifTag)ExifTag.WhitePoint,
(ExifTag)ExifTag.PrimaryChromaticities,
(ExifTag)ExifTag.YCbCrCoefficients,
(ExifTag)ExifTag.ReferenceBlackWhite,
(ExifTag)ExifTag.GPSLatitude,
(ExifTag)ExifTag.GPSLongitude,
(ExifTag)ExifTag.GPSTimestamp,
(ExifTag)ExifTag.GPSDestLatitude,
(ExifTag)ExifTag.GPSDestLongitude,
(ExifTag)ExifTag.LensSpecification
};
public static TheoryData<ExifTag> ShortTags => new()
{
{ ExifTag.OldSubfileType },
{ ExifTag.Compression },
{ ExifTag.PhotometricInterpretation },
{ ExifTag.Thresholding },
{ ExifTag.CellWidth },
{ ExifTag.CellLength },
{ ExifTag.FillOrder },
{ ExifTag.Orientation },
{ ExifTag.SamplesPerPixel },
{ ExifTag.PlanarConfiguration },
{ ExifTag.Predictor },
{ ExifTag.GrayResponseUnit },
{ ExifTag.ResolutionUnit },
{ ExifTag.CleanFaxData },
{ ExifTag.InkSet },
{ ExifTag.NumberOfInks },
{ ExifTag.DotRange },
{ ExifTag.Indexed },
{ ExifTag.OPIProxy },
{ ExifTag.JPEGProc },
{ ExifTag.JPEGRestartInterval },
{ ExifTag.YCbCrPositioning },
{ ExifTag.Rating },
{ ExifTag.RatingPercent },
{ ExifTag.ExposureProgram },
{ ExifTag.Interlace },
{ ExifTag.SelfTimerMode },
{ ExifTag.SensitivityType },
{ ExifTag.MeteringMode },
{ ExifTag.LightSource },
{ ExifTag.FocalPlaneResolutionUnit2 },
{ ExifTag.SensingMethod2 },
{ ExifTag.Flash },
{ ExifTag.ColorSpace },
{ ExifTag.FocalPlaneResolutionUnit },
{ ExifTag.SensingMethod },
{ ExifTag.CustomRendered },
{ ExifTag.ExposureMode },
{ ExifTag.WhiteBalance },
{ ExifTag.FocalLengthIn35mmFilm },
{ ExifTag.SceneCaptureType },
{ ExifTag.GainControl },
{ ExifTag.Contrast },
{ ExifTag.Saturation },
{ ExifTag.Sharpness },
{ ExifTag.SubjectDistanceRange },
{ ExifTag.GPSDifferential }
(ExifTag)ExifTag.OldSubfileType,
(ExifTag)ExifTag.Compression,
(ExifTag)ExifTag.PhotometricInterpretation,
(ExifTag)ExifTag.Thresholding,
(ExifTag)ExifTag.CellWidth,
(ExifTag)ExifTag.CellLength,
(ExifTag)ExifTag.FillOrder,
(ExifTag)ExifTag.Orientation,
(ExifTag)ExifTag.SamplesPerPixel,
(ExifTag)ExifTag.PlanarConfiguration,
(ExifTag)ExifTag.Predictor,
(ExifTag)ExifTag.GrayResponseUnit,
(ExifTag)ExifTag.ResolutionUnit,
(ExifTag)ExifTag.CleanFaxData,
(ExifTag)ExifTag.InkSet,
(ExifTag)ExifTag.NumberOfInks,
(ExifTag)ExifTag.DotRange,
(ExifTag)ExifTag.Indexed,
(ExifTag)ExifTag.OPIProxy,
(ExifTag)ExifTag.JPEGProc,
(ExifTag)ExifTag.JPEGRestartInterval,
(ExifTag)ExifTag.YCbCrPositioning,
(ExifTag)ExifTag.Rating,
(ExifTag)ExifTag.RatingPercent,
(ExifTag)ExifTag.ExposureProgram,
(ExifTag)ExifTag.Interlace,
(ExifTag)ExifTag.SelfTimerMode,
(ExifTag)ExifTag.SensitivityType,
(ExifTag)ExifTag.MeteringMode,
(ExifTag)ExifTag.LightSource,
(ExifTag)ExifTag.FocalPlaneResolutionUnit2,
(ExifTag)ExifTag.SensingMethod2,
(ExifTag)ExifTag.Flash,
(ExifTag)ExifTag.ColorSpace,
(ExifTag)ExifTag.FocalPlaneResolutionUnit,
(ExifTag)ExifTag.SensingMethod,
(ExifTag)ExifTag.CustomRendered,
(ExifTag)ExifTag.ExposureMode,
(ExifTag)ExifTag.WhiteBalance,
(ExifTag)ExifTag.FocalLengthIn35mmFilm,
(ExifTag)ExifTag.SceneCaptureType,
(ExifTag)ExifTag.GainControl,
(ExifTag)ExifTag.Contrast,
(ExifTag)ExifTag.Saturation,
(ExifTag)ExifTag.Sharpness,
(ExifTag)ExifTag.SubjectDistanceRange,
(ExifTag)ExifTag.GPSDifferential
};
public static TheoryData<ExifTag> ShortArrayTags => new()
{
{ ExifTag.BitsPerSample },
{ ExifTag.MinSampleValue },
{ ExifTag.MaxSampleValue },
{ ExifTag.GrayResponseCurve },
{ ExifTag.ColorMap },
{ ExifTag.ExtraSamples },
{ ExifTag.PageNumber },
{ ExifTag.TransferFunction },
{ ExifTag.HalftoneHints },
{ ExifTag.SampleFormat },
{ ExifTag.TransferRange },
{ ExifTag.DefaultImageColor },
{ ExifTag.JPEGLosslessPredictors },
{ ExifTag.JPEGPointTransforms },
{ ExifTag.YCbCrSubsampling },
{ ExifTag.CFARepeatPatternDim },
{ ExifTag.IntergraphPacketData },
{ ExifTag.ISOSpeedRatings },
{ ExifTag.SubjectArea },
{ ExifTag.SubjectLocation }
(ExifTag)ExifTag.BitsPerSample,
(ExifTag)ExifTag.MinSampleValue,
(ExifTag)ExifTag.MaxSampleValue,
(ExifTag)ExifTag.GrayResponseCurve,
(ExifTag)ExifTag.ColorMap,
(ExifTag)ExifTag.ExtraSamples,
(ExifTag)ExifTag.PageNumber,
(ExifTag)ExifTag.TransferFunction,
(ExifTag)ExifTag.HalftoneHints,
(ExifTag)ExifTag.SampleFormat,
(ExifTag)ExifTag.TransferRange,
(ExifTag)ExifTag.DefaultImageColor,
(ExifTag)ExifTag.JPEGLosslessPredictors,
(ExifTag)ExifTag.JPEGPointTransforms,
(ExifTag)ExifTag.YCbCrSubsampling,
(ExifTag)ExifTag.CFARepeatPatternDim,
(ExifTag)ExifTag.IntergraphPacketData,
(ExifTag)ExifTag.ISOSpeedRatings,
(ExifTag)ExifTag.SubjectArea,
(ExifTag)ExifTag.SubjectLocation
};
public static TheoryData<ExifTag> SignedRationalTags => new()
{
{ ExifTag.ShutterSpeedValue },
{ ExifTag.BrightnessValue },
{ ExifTag.ExposureBiasValue },
{ ExifTag.AmbientTemperature },
{ ExifTag.WaterDepth },
{ ExifTag.CameraElevationAngle }
(ExifTag)ExifTag.ShutterSpeedValue,
(ExifTag)ExifTag.BrightnessValue,
(ExifTag)ExifTag.ExposureBiasValue,
(ExifTag)ExifTag.AmbientTemperature,
(ExifTag)ExifTag.WaterDepth,
(ExifTag)ExifTag.CameraElevationAngle
};
public static TheoryData<ExifTag> SignedRationalArrayTags => new()
{
{ ExifTag.Decode }
(ExifTag)ExifTag.Decode
};
public static TheoryData<ExifTag> SignedShortArrayTags => new()
{
{ ExifTag.TimeZoneOffset }
(ExifTag)ExifTag.TimeZoneOffset
};
public static TheoryData<ExifTag> StringTags => new()
{
{ ExifTag.ImageDescription },
{ ExifTag.Make },
{ ExifTag.Model },
{ ExifTag.Software },
{ ExifTag.DateTime },
{ ExifTag.Artist },
{ ExifTag.HostComputer },
{ ExifTag.Copyright },
{ ExifTag.DocumentName },
{ ExifTag.PageName },
{ ExifTag.InkNames },
{ ExifTag.TargetPrinter },
{ ExifTag.ImageID },
{ ExifTag.MDLabName },
{ ExifTag.MDSampleInfo },
{ ExifTag.MDPrepDate },
{ ExifTag.MDPrepTime },
{ ExifTag.MDFileUnits },
{ ExifTag.SEMInfo },
{ ExifTag.SpectralSensitivity },
{ ExifTag.DateTimeOriginal },
{ ExifTag.DateTimeDigitized },
{ ExifTag.SubsecTime },
{ ExifTag.SubsecTimeOriginal },
{ ExifTag.SubsecTimeDigitized },
{ ExifTag.RelatedSoundFile },
{ ExifTag.FaxSubaddress },
{ ExifTag.OffsetTime },
{ ExifTag.OffsetTimeOriginal },
{ ExifTag.OffsetTimeDigitized },
{ ExifTag.SecurityClassification },
{ ExifTag.ImageHistory },
{ ExifTag.ImageUniqueID },
{ ExifTag.OwnerName },
{ ExifTag.SerialNumber },
{ ExifTag.LensMake },
{ ExifTag.LensModel },
{ ExifTag.LensSerialNumber },
{ ExifTag.GDALMetadata },
{ ExifTag.GDALNoData },
{ ExifTag.GPSLatitudeRef },
{ ExifTag.GPSLongitudeRef },
{ ExifTag.GPSSatellites },
{ ExifTag.GPSStatus },
{ ExifTag.GPSMeasureMode },
{ ExifTag.GPSSpeedRef },
{ ExifTag.GPSTrackRef },
{ ExifTag.GPSImgDirectionRef },
{ ExifTag.GPSMapDatum },
{ ExifTag.GPSDestLatitudeRef },
{ ExifTag.GPSDestLongitudeRef },
{ ExifTag.GPSDestBearingRef },
{ ExifTag.GPSDestDistanceRef },
{ ExifTag.GPSDateStamp },
(ExifTag)ExifTag.ImageDescription,
(ExifTag)ExifTag.Make,
(ExifTag)ExifTag.Model,
(ExifTag)ExifTag.Software,
(ExifTag)ExifTag.DateTime,
(ExifTag)ExifTag.Artist,
(ExifTag)ExifTag.HostComputer,
(ExifTag)ExifTag.Copyright,
(ExifTag)ExifTag.DocumentName,
(ExifTag)ExifTag.PageName,
(ExifTag)ExifTag.InkNames,
(ExifTag)ExifTag.TargetPrinter,
(ExifTag)ExifTag.ImageID,
(ExifTag)ExifTag.MDLabName,
(ExifTag)ExifTag.MDSampleInfo,
(ExifTag)ExifTag.MDPrepDate,
(ExifTag)ExifTag.MDPrepTime,
(ExifTag)ExifTag.MDFileUnits,
(ExifTag)ExifTag.SEMInfo,
(ExifTag)ExifTag.SpectralSensitivity,
(ExifTag)ExifTag.DateTimeOriginal,
(ExifTag)ExifTag.DateTimeDigitized,
(ExifTag)ExifTag.SubsecTime,
(ExifTag)ExifTag.SubsecTimeOriginal,
(ExifTag)ExifTag.SubsecTimeDigitized,
(ExifTag)ExifTag.RelatedSoundFile,
(ExifTag)ExifTag.FaxSubaddress,
(ExifTag)ExifTag.OffsetTime,
(ExifTag)ExifTag.OffsetTimeOriginal,
(ExifTag)ExifTag.OffsetTimeDigitized,
(ExifTag)ExifTag.SecurityClassification,
(ExifTag)ExifTag.ImageHistory,
(ExifTag)ExifTag.ImageUniqueID,
(ExifTag)ExifTag.OwnerName,
(ExifTag)ExifTag.SerialNumber,
(ExifTag)ExifTag.LensMake,
(ExifTag)ExifTag.LensModel,
(ExifTag)ExifTag.LensSerialNumber,
(ExifTag)ExifTag.GDALMetadata,
(ExifTag)ExifTag.GDALNoData,
(ExifTag)ExifTag.GPSLatitudeRef,
(ExifTag)ExifTag.GPSLongitudeRef,
(ExifTag)ExifTag.GPSSatellites,
(ExifTag)ExifTag.GPSStatus,
(ExifTag)ExifTag.GPSMeasureMode,
(ExifTag)ExifTag.GPSSpeedRef,
(ExifTag)ExifTag.GPSTrackRef,
(ExifTag)ExifTag.GPSImgDirectionRef,
(ExifTag)ExifTag.GPSMapDatum,
(ExifTag)ExifTag.GPSDestLatitudeRef,
(ExifTag)ExifTag.GPSDestLongitudeRef,
(ExifTag)ExifTag.GPSDestBearingRef,
(ExifTag)ExifTag.GPSDestDistanceRef,
(ExifTag)ExifTag.GPSDateStamp,
};
public static TheoryData<ExifTag> UndefinedTags => new()
{
{ ExifTag.FileSource },
{ ExifTag.SceneType }
(ExifTag)ExifTag.FileSource,
(ExifTag)ExifTag.SceneType
};
public static TheoryData<ExifTag> UndefinedArrayTags => new()
{
{ ExifTag.JPEGTables },
{ ExifTag.OECF },
{ ExifTag.ExifVersion },
{ ExifTag.ComponentsConfiguration },
{ ExifTag.MakerNote },
{ ExifTag.FlashpixVersion },
{ ExifTag.SpatialFrequencyResponse },
{ ExifTag.SpatialFrequencyResponse2 },
{ ExifTag.Noise },
{ ExifTag.CFAPattern },
{ ExifTag.DeviceSettingDescription },
{ ExifTag.ImageSourceData },
(ExifTag)ExifTag.JPEGTables,
(ExifTag)ExifTag.OECF,
(ExifTag)ExifTag.ExifVersion,
(ExifTag)ExifTag.ComponentsConfiguration,
(ExifTag)ExifTag.MakerNote,
(ExifTag)ExifTag.FlashpixVersion,
(ExifTag)ExifTag.SpatialFrequencyResponse,
(ExifTag)ExifTag.SpatialFrequencyResponse2,
(ExifTag)ExifTag.Noise,
(ExifTag)ExifTag.CFAPattern,
(ExifTag)ExifTag.DeviceSettingDescription,
(ExifTag)ExifTag.ImageSourceData,
};
public static TheoryData<ExifTag> EncodedStringTags => new()
{
{ ExifTag.UserComment },
{ ExifTag.GPSProcessingMethod },
{ ExifTag.GPSAreaInformation }
(ExifTag)ExifTag.UserComment,
(ExifTag)ExifTag.GPSProcessingMethod,
(ExifTag)ExifTag.GPSAreaInformation
};
public static TheoryData<ExifTag> Ucs2StringTags => new()
{
{ ExifTag.XPTitle },
{ ExifTag.XPComment },
{ ExifTag.XPAuthor },
{ ExifTag.XPKeywords },
{ ExifTag.XPSubject },
(ExifTag)ExifTag.XPTitle,
(ExifTag)ExifTag.XPComment,
(ExifTag)ExifTag.XPAuthor,
(ExifTag)ExifTag.XPKeywords,
(ExifTag)ExifTag.XPSubject,
};
[Theory]

6
tests/ImageSharp.Tests/PixelFormats/L8Tests.cs

@ -12,7 +12,11 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats;
public class L8Tests
{
public static readonly TheoryData<byte> LuminanceData
= new() { 0, 1, 2, 3, 5, 13, 31, 71, 73, 79, 83, 109, 127, 128, 131, 199, 250, 251, 254, 255 };
=
[
(byte)0, (byte)1, (byte)2, (byte)3, (byte)5, (byte)13, (byte)31, (byte)71, (byte)73, (byte)79, (byte)83,
(byte)109, (byte)127, (byte)128, (byte)131, (byte)199, (byte)250, (byte)251, (byte)254, (byte)255
];
[Theory]
[InlineData(0)]

6
tests/ImageSharp.Tests/PixelFormats/La16Tests.cs

@ -12,7 +12,11 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats;
public class La16Tests
{
public static readonly TheoryData<byte> LuminanceData
= new() { 0, 1, 2, 3, 5, 13, 31, 71, 73, 79, 83, 109, 127, 128, 131, 199, 250, 251, 254, 255 };
=
[
(byte)0, (byte)1, (byte)2, (byte)3, (byte)5, (byte)13, (byte)31, (byte)71, (byte)73, (byte)79, (byte)83,
(byte)109, (byte)127, (byte)128, (byte)131, (byte)199, (byte)250, (byte)251, (byte)254, (byte)255
];
[Theory]
[InlineData(0, 0)]

3
tests/ImageSharp.Tests/PixelFormats/PixelOperations/Generated/PixelOperationsTests.Specialized.Generated.cs

@ -5,13 +5,12 @@
using SixLabors.ImageSharp.PixelFormats;
using Xunit;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations;
public partial class PixelOperationsTests
{
public partial class A8_OperationsTests : PixelOperationsTests<A8>
{
public A8_OperationsTests(ITestOutputHelper output)

1
tests/ImageSharp.Tests/PixelFormats/PixelOperations/Generated/_Common.ttinclude

@ -10,7 +10,6 @@
using SixLabors.ImageSharp.PixelFormats;
using Xunit;
using Xunit.Abstractions;
<#+
private static readonly string[] UnassociatedAlphaPixelTypes =
[

82
tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs

@ -10,7 +10,6 @@ using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.Common;
using SixLabors.ImageSharp.Tests.TestUtilities;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations;
@ -318,46 +317,47 @@ public abstract class PixelOperationsTests<TPixel> : MeasureFixture
(s, d) => this.Operations.ToVector4(this.Configuration, s, d.GetSpan()));
}
public static readonly TheoryData<object> Generic_To_Data = new()
{
new TestPixel<A8>(),
new TestPixel<Abgr32>(),
new TestPixel<Abgr32P>(),
new TestPixel<Argb32>(),
new TestPixel<Argb32P>(),
new TestPixel<Bgr24>(),
new TestPixel<Bgr565>(),
new TestPixel<Bgra32>(),
new TestPixel<Bgra32P>(),
new TestPixel<Bgra4444>(),
new TestPixel<Bgra5551>(),
new TestPixel<Byte4>(),
new TestPixel<HalfSingle>(),
new TestPixel<HalfVector2>(),
new TestPixel<HalfVector4>(),
new TestPixel<HalfVector4P>(),
new TestPixel<L16>(),
new TestPixel<L8>(),
new TestPixel<La16>(),
new TestPixel<La32>(),
new TestPixel<NormalizedByte2>(),
new TestPixel<NormalizedByte4>(),
new TestPixel<NormalizedByte4P>(),
new TestPixel<NormalizedShort2>(),
new TestPixel<NormalizedShort4>(),
new TestPixel<Rg32>(),
new TestPixel<Rgb24>(),
new TestPixel<Rgb48>(),
new TestPixel<Rgba1010102>(),
new TestPixel<Rgba32>(),
new TestPixel<Rgba32P>(),
new TestPixel<Rgba64>(),
new TestPixel<RgbaHalf>(),
new TestPixel<RgbaHalfP>(),
new TestPixel<RgbaVector>(),
new TestPixel<Short2>(),
new TestPixel<Short4>(),
};
public static readonly TheoryData<object> Generic_To_Data = new(
new object[]
{
new TestPixel<A8>(),
new TestPixel<Abgr32>(),
new TestPixel<Abgr32P>(),
new TestPixel<Argb32>(),
new TestPixel<Argb32P>(),
new TestPixel<Bgr24>(),
new TestPixel<Bgr565>(),
new TestPixel<Bgra32>(),
new TestPixel<Bgra32P>(),
new TestPixel<Bgra4444>(),
new TestPixel<Bgra5551>(),
new TestPixel<Byte4>(),
new TestPixel<HalfSingle>(),
new TestPixel<HalfVector2>(),
new TestPixel<HalfVector4>(),
new TestPixel<HalfVector4P>(),
new TestPixel<L16>(),
new TestPixel<L8>(),
new TestPixel<La16>(),
new TestPixel<La32>(),
new TestPixel<NormalizedByte2>(),
new TestPixel<NormalizedByte4>(),
new TestPixel<NormalizedByte4P>(),
new TestPixel<NormalizedShort2>(),
new TestPixel<NormalizedShort4>(),
new TestPixel<Rg32>(),
new TestPixel<Rgb24>(),
new TestPixel<Rgb48>(),
new TestPixel<Rgba1010102>(),
new TestPixel<Rgba32>(),
new TestPixel<Rgba32P>(),
new TestPixel<Rgba64>(),
new TestPixel<RgbaHalf>(),
new TestPixel<RgbaHalfP>(),
new TestPixel<RgbaVector>(),
new TestPixel<Short2>(),
new TestPixel<Short4>(),
});
[Theory]
[MemberData(nameof(Generic_To_Data))]

2
tests/ImageSharp.Tests/Processing/Processors/Convolution/BokehBlurTest.cs

@ -8,7 +8,7 @@ using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Convolution;
using SixLabors.ImageSharp.Tests.TestUtilities;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using Xunit.Abstractions;
using Xunit.Sdk;
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Convolution;

4
tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs

@ -43,8 +43,8 @@ public class DitherTests
public static readonly TheoryData<IDither> DefaultInstanceDitherers
= new()
{
default(ErrorDither),
default(OrderedDither)
(IDither)default(ErrorDither),
(IDither)default(OrderedDither)
};
private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.05f);

118
tests/ImageSharp.Tests/Processing/Processors/Quantization/QuantizerTests.cs

@ -78,75 +78,75 @@ public class QuantizerTests
KnownQuantizers.WebSafe,
KnownQuantizers.Werner,
KnownQuantizers.Wu,
new HexadecatreeQuantizer(NoDitherOptions),
new WebSafePaletteQuantizer(NoDitherOptions),
new WernerPaletteQuantizer(NoDitherOptions),
new WuQuantizer(NoDitherOptions),
new HexadecatreeQuantizer(OrderedDitherOptions),
new WebSafePaletteQuantizer(OrderedDitherOptions),
new WernerPaletteQuantizer(OrderedDitherOptions),
new WuQuantizer(OrderedDitherOptions)
(IQuantizer)new HexadecatreeQuantizer(NoDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(NoDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(NoDitherOptions),
(IQuantizer)new WuQuantizer(NoDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(OrderedDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(OrderedDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(OrderedDitherOptions),
(IQuantizer)new WuQuantizer(OrderedDitherOptions)
};
public static readonly TheoryData<IQuantizer> DitherScaleQuantizers
= new()
{
new HexadecatreeQuantizer(Diffuser0_ScaleDitherOptions),
new WebSafePaletteQuantizer(Diffuser0_ScaleDitherOptions),
new WernerPaletteQuantizer(Diffuser0_ScaleDitherOptions),
new WuQuantizer(Diffuser0_ScaleDitherOptions),
new HexadecatreeQuantizer(Diffuser0_25_ScaleDitherOptions),
new WebSafePaletteQuantizer(Diffuser0_25_ScaleDitherOptions),
new WernerPaletteQuantizer(Diffuser0_25_ScaleDitherOptions),
new WuQuantizer(Diffuser0_25_ScaleDitherOptions),
new HexadecatreeQuantizer(Diffuser0_5_ScaleDitherOptions),
new WebSafePaletteQuantizer(Diffuser0_5_ScaleDitherOptions),
new WernerPaletteQuantizer(Diffuser0_5_ScaleDitherOptions),
new WuQuantizer(Diffuser0_5_ScaleDitherOptions),
new HexadecatreeQuantizer(Diffuser0_75_ScaleDitherOptions),
new WebSafePaletteQuantizer(Diffuser0_75_ScaleDitherOptions),
new WernerPaletteQuantizer(Diffuser0_75_ScaleDitherOptions),
new WuQuantizer(Diffuser0_75_ScaleDitherOptions),
new HexadecatreeQuantizer(DiffuserDitherOptions),
new WebSafePaletteQuantizer(DiffuserDitherOptions),
new WernerPaletteQuantizer(DiffuserDitherOptions),
new WuQuantizer(DiffuserDitherOptions),
new HexadecatreeQuantizer(Ordered0_ScaleDitherOptions),
new WebSafePaletteQuantizer(Ordered0_ScaleDitherOptions),
new WernerPaletteQuantizer(Ordered0_ScaleDitherOptions),
new WuQuantizer(Ordered0_ScaleDitherOptions),
new HexadecatreeQuantizer(Ordered0_25_ScaleDitherOptions),
new WebSafePaletteQuantizer(Ordered0_25_ScaleDitherOptions),
new WernerPaletteQuantizer(Ordered0_25_ScaleDitherOptions),
new WuQuantizer(Ordered0_25_ScaleDitherOptions),
new HexadecatreeQuantizer(Ordered0_5_ScaleDitherOptions),
new WebSafePaletteQuantizer(Ordered0_5_ScaleDitherOptions),
new WernerPaletteQuantizer(Ordered0_5_ScaleDitherOptions),
new WuQuantizer(Ordered0_5_ScaleDitherOptions),
new HexadecatreeQuantizer(Ordered0_75_ScaleDitherOptions),
new WebSafePaletteQuantizer(Ordered0_75_ScaleDitherOptions),
new WernerPaletteQuantizer(Ordered0_75_ScaleDitherOptions),
new WuQuantizer(Ordered0_75_ScaleDitherOptions),
new HexadecatreeQuantizer(OrderedDitherOptions),
new WebSafePaletteQuantizer(OrderedDitherOptions),
new WernerPaletteQuantizer(OrderedDitherOptions),
new WuQuantizer(OrderedDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(Diffuser0_ScaleDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(Diffuser0_ScaleDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(Diffuser0_ScaleDitherOptions),
(IQuantizer)new WuQuantizer(Diffuser0_ScaleDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(Diffuser0_25_ScaleDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(Diffuser0_25_ScaleDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(Diffuser0_25_ScaleDitherOptions),
(IQuantizer)new WuQuantizer(Diffuser0_25_ScaleDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(Diffuser0_5_ScaleDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(Diffuser0_5_ScaleDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(Diffuser0_5_ScaleDitherOptions),
(IQuantizer)new WuQuantizer(Diffuser0_5_ScaleDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(Diffuser0_75_ScaleDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(Diffuser0_75_ScaleDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(Diffuser0_75_ScaleDitherOptions),
(IQuantizer)new WuQuantizer(Diffuser0_75_ScaleDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(DiffuserDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(DiffuserDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(DiffuserDitherOptions),
(IQuantizer)new WuQuantizer(DiffuserDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(Ordered0_ScaleDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(Ordered0_ScaleDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(Ordered0_ScaleDitherOptions),
(IQuantizer)new WuQuantizer(Ordered0_ScaleDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(Ordered0_25_ScaleDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(Ordered0_25_ScaleDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(Ordered0_25_ScaleDitherOptions),
(IQuantizer)new WuQuantizer(Ordered0_25_ScaleDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(Ordered0_5_ScaleDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(Ordered0_5_ScaleDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(Ordered0_5_ScaleDitherOptions),
(IQuantizer)new WuQuantizer(Ordered0_5_ScaleDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(Ordered0_75_ScaleDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(Ordered0_75_ScaleDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(Ordered0_75_ScaleDitherOptions),
(IQuantizer)new WuQuantizer(Ordered0_75_ScaleDitherOptions),
(IQuantizer)new HexadecatreeQuantizer(OrderedDitherOptions),
(IQuantizer)new WebSafePaletteQuantizer(OrderedDitherOptions),
(IQuantizer)new WernerPaletteQuantizer(OrderedDitherOptions),
(IQuantizer)new WuQuantizer(OrderedDitherOptions),
};
public static readonly TheoryData<IDither> DefaultInstanceDitherers
= new()
{
default(ErrorDither),
default(OrderedDither)
(IDither)default(ErrorDither),
(IDither)default(OrderedDither)
};
private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.05F);

1
tests/ImageSharp.Tests/Processing/Processors/Transforms/AffineTransformTests.cs

@ -7,7 +7,6 @@ using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Transforms;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Processing.Transforms;

1
tests/ImageSharp.Tests/Processing/Processors/Transforms/ProjectiveTransformTests.cs

@ -9,7 +9,6 @@ using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Transforms;
using SixLabors.ImageSharp.Tests.TestUtilities;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms;

1
tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs

@ -4,7 +4,6 @@
using System.Text;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Transforms;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms;

12
tests/ImageSharp.Tests/Processing/Processors/Transforms/RotateTests.cs

@ -12,20 +12,16 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms;
[GroupOutput("Transforms")]
public class RotateTests
{
public static readonly TheoryData<float> RotateAngles
= new()
{
50, -50, 170, -170
};
public static readonly TheoryData<float> RotateAngles = [50f, -50f, 170f, -170f];
public static readonly TheoryData<RotateMode> RotateEnumValues
= new()
{
=
[
RotateMode.None,
RotateMode.Rotate90,
RotateMode.Rotate180,
RotateMode.Rotate270
};
];
[Theory]
[WithTestPatternImages(nameof(RotateAngles), 100, 50, PixelTypes.Rgba32)]

1
tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveProfilingBenchmarks.cs

@ -3,7 +3,6 @@
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Processing;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks;

1
tests/ImageSharp.Tests/ProfilingBenchmarks/ResizeProfilingBenchmarks.cs

@ -3,7 +3,6 @@
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks;

2
tests/ImageSharp.Tests/Quantization/AlphaAssociationQuantizerTests.cs

@ -12,7 +12,7 @@ public class AlphaAssociationQuantizerTests
{
public static TheoryData<IDither?> Dithers { get; } = new()
{
null,
(IDither?)null,
KnownDitherings.Bayer4x4,
KnownDitherings.FloydSteinberg
};

33
tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs

@ -3,6 +3,7 @@
using System.Reflection;
using Xunit.Sdk;
using Xunit.v3;
namespace SixLabors.ImageSharp.Tests;
@ -42,11 +43,22 @@ public abstract class ImageDataAttributeBase : DataAttribute
/// </summary>
public Type MemberType { get; set; }
/// <inheritdoc/>
public override bool SupportsDiscoveryEnumeration() => true;
/// <inheritdoc/>
public override ValueTask<IReadOnlyCollection<ITheoryDataRow>> GetData(MethodInfo testMethod, DisposalTracker disposalTracker)
{
IEnumerable<object[]> rows = this.GetDataRows(testMethod);
IReadOnlyCollection<ITheoryDataRow> result = rows.Select(row => ConvertDataRow(row)).ToList();
return new ValueTask<IReadOnlyCollection<ITheoryDataRow>>(result);
}
/// <summary>Returns the data to be used to test the theory.</summary>
/// <param name="testMethod">The method that is being tested</param>
/// <returns>One or more sets of theory data. Each invocation of the test method
/// is represented by a single object array.</returns>
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
private IEnumerable<object[]> GetDataRows(MethodInfo testMethod)
{
IEnumerable<object[]> addedRows = Enumerable.Empty<object[]>().ToArray();
if (!string.IsNullOrWhiteSpace(this.MemberName))
@ -59,11 +71,22 @@ public abstract class ImageDataAttributeBase : DataAttribute
object obj = accessor();
if (obj is IEnumerable<object> memberItems)
{
addedRows = memberItems.Select(x => x as object[]);
if (addedRows.Any(x => x == null))
// In xunit.v3, TheoryData<T> yields ITheoryDataRow, not object[].
// Call GetData to unpack the row's values.
addedRows = memberItems.Select(x =>
{
addedRows = memberItems.Select(x => new[] { x });
}
if (x is ITheoryDataRow row)
{
return row.GetData();
}
if (x is object[] array)
{
return array;
}
return [x];
});
}
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save