Browse Source

Remove other obsolete conditions and warnings

pull/2189/head
James Jackson-South 4 years ago
parent
commit
6fc84a82f6
  1. 2
      shared-infrastructure
  2. 4
      src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs
  3. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/VonKriesChromaticAdaptation.cs
  4. 2
      src/ImageSharp/Common/Helpers/HexConverter.cs
  5. 4
      src/ImageSharp/Compression/Zlib/DeflaterOutputStream.cs
  6. 2
      src/ImageSharp/Compression/Zlib/DeflaterPendingBuffer.cs
  7. 6
      src/ImageSharp/Diagnostics/MemoryDiagnostics.cs
  8. 12
      src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
  9. 4
      src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
  10. 16
      src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs
  11. 2
      src/ImageSharp/Formats/Gif/GifEncoderCore.cs
  12. 2
      src/ImageSharp/Formats/Gif/Sections/GifImageDescriptor.cs
  13. 2
      src/ImageSharp/Formats/Gif/Sections/GifNetscapeLoopingApplicationExtension.cs
  14. 4
      src/ImageSharp/Formats/Gif/Sections/GifXmpApplicationExtension.cs
  15. 2
      src/ImageSharp/Formats/ImageFormatManager.cs
  16. 2
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs
  17. 2
      src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs
  18. 16
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
  19. 6
      src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs
  20. 16
      src/ImageSharp/Formats/Pbm/PlainEncoder.cs
  21. 4
      src/ImageSharp/Formats/Png/Chunks/PhysicalChunkData.cs
  22. 4
      src/ImageSharp/Formats/Png/Filters/NoneFilter.cs
  23. 167
      src/ImageSharp/Formats/Png/PngDecoderCore.cs
  24. 16
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  25. 4
      src/ImageSharp/Formats/Png/PngHeader.cs
  26. 4
      src/ImageSharp/Formats/Tga/TgaDecoderCore.cs
  27. 2
      src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs
  28. 2
      src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsWriter.cs
  29. 2
      src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffCcittCompressor.cs
  30. 6
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/CcittReferenceScanline.cs
  31. 4
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs
  32. 2
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs
  33. 18
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/T6TiffCompression.cs
  34. 2
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs
  35. 4
      src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs
  36. 2
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero24TiffColor{TPixel}.cs
  37. 2
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb242424TiffColor{TPixel}.cs
  38. 2
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb24PlanarTiffColor{TPixel}.cs
  39. 2
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba24242424TiffColor{TPixel}.cs
  40. 2
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba24PlanarTiffColor{TPixel}.cs
  41. 2
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero24TiffColor{TPixel}.cs
  42. 4
      src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter{TPixel}.cs
  43. 2
      src/ImageSharp/Formats/Tiff/Writers/TiffCompositeColorWriter{TPixel}.cs
  44. 6
      src/ImageSharp/Formats/Tiff/Writers/TiffPaletteWriter{TPixel}.cs
  45. 2
      src/ImageSharp/Formats/Webp/BitReader/BitReaderBase.cs
  46. 4
      src/ImageSharp/Formats/Webp/BitWriter/BitWriterBase.cs
  47. 4
      src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs
  48. 6
      src/ImageSharp/Formats/Webp/Lossless/BackwardReferenceEncoder.cs
  49. 10
      src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs
  50. 2
      src/ImageSharp/Formats/Webp/Lossless/NearLosslessEnc.cs
  51. 30
      src/ImageSharp/Formats/Webp/Lossless/PredictorEncoder.cs
  52. 50
      src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs
  53. 14
      src/ImageSharp/Formats/Webp/Lossless/Vp8LHashChain.cs
  54. 26
      src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs
  55. 2
      src/ImageSharp/Formats/Webp/Lossy/QuantEnc.cs
  56. 28
      src/ImageSharp/Formats/Webp/Lossy/Vp8EncIterator.cs
  57. 2
      src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs
  58. 72
      src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs
  59. 4
      src/ImageSharp/Formats/Webp/WebpAnimationDecoder.cs
  60. 2
      src/ImageSharp/Formats/Webp/WebpImageFormatDetector.cs
  61. 4
      src/ImageSharp/IO/ChunkedMemoryStream.cs
  62. 2
      src/ImageSharp/Image.LoadPixelData.cs
  63. 2
      src/ImageSharp/ImageFrame.LoadPixelData.cs
  64. 2
      src/ImageSharp/IndexedImageFrame{TPixel}.cs
  65. 24
      src/ImageSharp/Memory/Allocators/Internals/Gen2GcCallback.cs
  66. 10
      src/ImageSharp/Memory/Allocators/Internals/UniformUnmanagedMemoryPool.cs
  67. 10
      src/ImageSharp/Memory/Allocators/UniformUnmanagedMemoryPoolMemoryAllocator.cs
  68. 2
      src/ImageSharp/Memory/Buffer2D{T}.cs
  69. 2
      src/ImageSharp/Memory/ByteMemoryManager{T}.cs
  70. 6
      src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupExtensions.cs
  71. 2
      src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs
  72. 2
      src/ImageSharp/Memory/MemoryOwnerExtensions.cs
  73. 21
      src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs
  74. 51
      src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs
  75. 8
      src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs
  76. 2
      src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.Primitives.cs
  77. 2
      src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Primitives.cs
  78. 2
      src/ImageSharp/Metadata/Profiles/IPTC/IptcValue.cs
  79. 12
      src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs
  80. 14
      src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs
  81. 2
      src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs
  82. 6
      src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs
  83. 4
      src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs
  84. 18
      src/ImageSharp/Processing/Processors/Convolution/BokehBlurProcessor{TPixel}.cs
  85. 4
      src/ImageSharp/Processing/Processors/Convolution/Convolution2DRowOperation{TPixel}.cs
  86. 16
      src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs
  87. 4
      src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs
  88. 4
      src/ImageSharp/Processing/Processors/Convolution/KernelSamplingMap.cs
  89. 2
      src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs
  90. 4
      src/ImageSharp/Processing/Processors/Filters/OpaqueProcessor{TPixel}.cs
  91. 10
      src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor{TPixel}.cs
  92. 2
      src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs
  93. 4
      src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs
  94. 4
      src/ImageSharp/Processing/Processors/Transforms/CropProcessor{TPixel}.cs
  95. 2
      src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWorker.cs
  96. 12
      tests/ImageSharp.Tests/Helpers/RuntimeEnvironmentTests.cs
  97. 14
      tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedMemoryPoolTests.Trim.cs
  98. 2
      tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedPoolMemoryAllocatorTests.cs
  99. 2
      tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs
  100. 48
      tests/ImageSharp.Tests/Primitives/ColorMatrixTests.cs

2
shared-infrastructure

@ -1 +1 @@
Subproject commit e12c30b3b1427815cffa22ac95c77ba29f65fe5a
Subproject commit 86af5a82198c21ce6889370428eb97d1fa7b41ff

4
src/ImageSharp/ColorSpaces/Companding/SRgbCompanding.cs

@ -89,7 +89,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding
if (Numerics.Modulo2(vectors.Length) != 0)
{
// Vector4 fits neatly in pairs. Any overlap has to be equal to 1.
Expand(ref MemoryMarshal.GetReference(vectors.Slice(vectors.Length - 1)));
Expand(ref MemoryMarshal.GetReference(vectors[^1..]));
}
}
else
@ -112,7 +112,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding
if (Numerics.Modulo2(vectors.Length) != 0)
{
// Vector4 fits neatly in pairs. Any overlap has to be equal to 1.
Compress(ref MemoryMarshal.GetReference(vectors.Slice(vectors.Length - 1)));
Compress(ref MemoryMarshal.GetReference(vectors[^1..]));
}
}
else

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/VonKriesChromaticAdaptation.cs

@ -75,7 +75,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
if (sourceWhitePoint.Equals(destinationWhitePoint))
{
source.CopyTo(destination.Slice(0, count));
source.CopyTo(destination[..count]);
return;
}

2
src/ImageSharp/Common/Helpers/HexConverter.cs

@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.Common.Helpers
{
// Slightly better performance in the loop below, allows us to skip a bounds check
// while still supporting output buffers that are larger than necessary
bytes = bytes.Slice(0, chars.Length / 2);
bytes = bytes[..(chars.Length / 2)];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]

4
src/ImageSharp/Compression/Zlib/DeflaterOutputStream.cs

@ -95,7 +95,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib
break;
}
this.rawStream.Write(this.buffer.Span.Slice(0, deflateCount));
this.rawStream.Write(this.buffer.Span[..deflateCount]);
}
if (!this.deflater.IsNeedingInput)
@ -115,7 +115,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib
break;
}
this.rawStream.Write(this.buffer.Span.Slice(0, len));
this.rawStream.Write(this.buffer.Span[..len]);
}
if (!this.deflater.IsFinished)

2
src/ImageSharp/Compression/Zlib/DeflaterPendingBuffer.cs

@ -75,7 +75,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib
{
Unsafe.CopyBlockUnaligned(
ref this.buffer.Span[this.end],
ref MemoryMarshal.GetReference(block.Slice(offset)),
ref MemoryMarshal.GetReference(block[offset..]),
unchecked((uint)length));
this.end += length;

6
src/ImageSharp/Diagnostics/MemoryDiagnostics.cs

@ -85,16 +85,10 @@ namespace SixLabors.ImageSharp.Diagnostics
}
// Schedule on the ThreadPool, to avoid user callback messing up the finalizer thread.
#if NETSTANDARD2_1 || NETCOREAPP2_1_OR_GREATER
ThreadPool.QueueUserWorkItem(
stackTrace => undisposedAllocation?.Invoke(stackTrace),
allocationStackTrace,
preferLocal: false);
#else
ThreadPool.QueueUserWorkItem(
stackTrace => undisposedAllocation?.Invoke((string)stackTrace),
allocationStackTrace);
#endif
}
}
}

12
src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs

@ -597,7 +597,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
this.stream.Read(run, 0, run.Length);
run.AsSpan().CopyTo(buffer.Slice(count));
run.AsSpan().CopyTo(buffer[count..]);
count += run.Length;
@ -676,7 +676,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
this.stream.Read(run, 0, run.Length);
run.AsSpan().CopyTo(buffer.Slice(start: uncompressedPixels * 3));
run.AsSpan().CopyTo(buffer[(uncompressedPixels * 3)..]);
uncompressedPixels += length;
@ -891,7 +891,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
int offset = 0;
for (int x = 0; x < width; x++)
{
short temp = BinaryPrimitives.ReadInt16LittleEndian(bufferSpan.Slice(offset));
short temp = BinaryPrimitives.ReadInt16LittleEndian(bufferSpan[offset..]);
// Rescale values, so the values range from 0 to 255.
int r = (redMaskBits == 5) ? GetBytesFrom5BitValue((temp & redMask) >> rightShiftRedMask) : GetBytesFrom6BitValue((temp & redMask) >> rightShiftRedMask);
@ -1122,7 +1122,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
int offset = 0;
for (int x = 0; x < width; x++)
{
uint temp = BinaryPrimitives.ReadUInt32LittleEndian(bufferSpan.Slice(offset));
uint temp = BinaryPrimitives.ReadUInt32LittleEndian(bufferSpan[offset..]);
if (unusualBitMask)
{
@ -1246,7 +1246,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
var bitfieldsBuffer = new byte[12];
this.stream.Read(bitfieldsBuffer, 0, 12);
Span<byte> data = bitfieldsBuffer.AsSpan();
this.infoHeader.RedMask = BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4));
this.infoHeader.RedMask = BinaryPrimitives.ReadInt32LittleEndian(data[..4]);
this.infoHeader.GreenMask = BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4));
this.infoHeader.BlueMask = BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4));
}
@ -1255,7 +1255,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
var bitfieldsBuffer = new byte[16];
this.stream.Read(bitfieldsBuffer, 0, 16);
Span<byte> data = bitfieldsBuffer.AsSpan();
this.infoHeader.RedMask = BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4));
this.infoHeader.RedMask = BinaryPrimitives.ReadInt32LittleEndian(data[..4]);
this.infoHeader.GreenMask = BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4));
this.infoHeader.BlueMask = BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4));
this.infoHeader.AlphaMask = BinaryPrimitives.ReadInt32LittleEndian(data.Slice(12, 4));

4
src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs

@ -257,7 +257,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
stream.Write(iccProfileData);
BinaryPrimitives.WriteInt32LittleEndian(buffer, streamPositionAfterImageData);
stream.Position = BmpFileHeader.Size + 112;
stream.Write(buffer.Slice(0, 4));
stream.Write(buffer[..4]);
}
}
@ -618,7 +618,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
where TPixel : unmanaged, IPixel<TPixel>
{
int quantizedColorBytes = quantizedColorPalette.Length * 4;
PixelOperations<TPixel>.Instance.ToBgra32(this.configuration, quantizedColorPalette, MemoryMarshal.Cast<byte, Bgra32>(colorPalette.Slice(0, quantizedColorBytes)));
PixelOperations<TPixel>.Instance.ToBgra32(this.configuration, quantizedColorPalette, MemoryMarshal.Cast<byte, Bgra32>(colorPalette[..quantizedColorBytes]));
Span<uint> colorPaletteAsUInt = MemoryMarshal.Cast<byte, uint>(colorPalette);
for (int i = 0; i < colorPaletteAsUInt.Length; i++)
{

16
src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs

@ -308,7 +308,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// <returns>The parsed header.</returns>
/// <seealso href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd183372.aspx"/>
public static BmpInfoHeader ParseCore(ReadOnlySpan<byte> data) => new(
headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)),
headerSize: BinaryPrimitives.ReadInt32LittleEndian(data[..4]),
width: BinaryPrimitives.ReadUInt16LittleEndian(data.Slice(4, 2)),
height: BinaryPrimitives.ReadUInt16LittleEndian(data.Slice(6, 2)),
planes: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(8, 2)),
@ -322,7 +322,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// <returns>The parsed header.</returns>
/// <seealso href="https://www.fileformat.info/format/os2bmp/egff.htm"/>
public static BmpInfoHeader ParseOs22Short(ReadOnlySpan<byte> data) => new(
headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)),
headerSize: BinaryPrimitives.ReadInt32LittleEndian(data[..4]),
width: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4)),
height: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4)),
planes: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(12, 2)),
@ -335,7 +335,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// <returns>The parsed header.</returns>
/// <seealso href="http://www.fileformat.info/format/bmp/egff.htm"/>
public static BmpInfoHeader ParseV3(ReadOnlySpan<byte> data) => new(
headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)),
headerSize: BinaryPrimitives.ReadInt32LittleEndian(data[..4]),
width: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4)),
height: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4)),
planes: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(12, 2)),
@ -356,7 +356,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// <returns>The parsed header.</returns>
/// <seealso href="https://forums.adobe.com/message/3272950#3272950"/>
public static BmpInfoHeader ParseAdobeV3(ReadOnlySpan<byte> data, bool withAlpha = true) => new(
headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)),
headerSize: BinaryPrimitives.ReadInt32LittleEndian(data[..4]),
width: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4)),
height: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4)),
planes: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(12, 2)),
@ -383,7 +383,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
public static BmpInfoHeader ParseOs2Version2(ReadOnlySpan<byte> data)
{
var infoHeader = new BmpInfoHeader(
headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)),
headerSize: BinaryPrimitives.ReadInt32LittleEndian(data[..4]),
width: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4)),
height: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4)),
planes: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(12, 2)),
@ -430,7 +430,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// <returns>The parsed header.</returns>
/// <seealso href="http://www.fileformat.info/format/bmp/egff.htm"/>
public static BmpInfoHeader ParseV4(ReadOnlySpan<byte> data) => new(
headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)),
headerSize: BinaryPrimitives.ReadInt32LittleEndian(data[..4]),
width: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4)),
height: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4)),
planes: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(12, 2)),
@ -482,7 +482,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
public void WriteV3Header(Span<byte> buffer)
{
buffer.Clear();
BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(0, 4), SizeV3);
BinaryPrimitives.WriteInt32LittleEndian(buffer[..4], SizeV3);
BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(4, 4), this.Width);
BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(8, 4), this.Height);
BinaryPrimitives.WriteInt16LittleEndian(buffer.Slice(12, 2), this.Planes);
@ -502,7 +502,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
public void WriteV4Header(Span<byte> buffer)
{
buffer.Clear();
BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(0, 4), SizeV4);
BinaryPrimitives.WriteInt32LittleEndian(buffer[..4], SizeV4);
BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(4, 4), this.Width);
BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(8, 4), this.Height);
BinaryPrimitives.WriteInt16LittleEndian(buffer.Slice(12, 2), this.Planes);

2
src/ImageSharp/Formats/Gif/GifEncoderCore.cs

@ -448,7 +448,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
extensionBuffer[0] = GifConstants.ExtensionIntroducer;
extensionBuffer[1] = extension.Label;
extension.WriteTo(extensionBuffer.Slice(2));
extension.WriteTo(extensionBuffer[2..]);
extensionBuffer[extensionSize + 2] = GifConstants.Terminator;

2
src/ImageSharp/Formats/Gif/Sections/GifImageDescriptor.cs

@ -71,7 +71,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
{
buffer[0] = GifConstants.ImageDescriptorLabel;
ref GifImageDescriptor dest = ref Unsafe.As<byte, GifImageDescriptor>(ref MemoryMarshal.GetReference(buffer.Slice(1)));
ref GifImageDescriptor dest = ref Unsafe.As<byte, GifImageDescriptor>(ref MemoryMarshal.GetReference(buffer[1..]));
dest = this;
}

2
src/ImageSharp/Formats/Gif/Sections/GifNetscapeLoopingApplicationExtension.cs

@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
public static GifNetscapeLoopingApplicationExtension Parse(ReadOnlySpan<byte> buffer)
{
ushort repeatCount = BinaryPrimitives.ReadUInt16LittleEndian(buffer.Slice(0, 2));
ushort repeatCount = BinaryPrimitives.ReadUInt16LittleEndian(buffer[..2]);
return new GifNetscapeLoopingApplicationExtension(repeatCount);
}

4
src/ImageSharp/Formats/Gif/Sections/GifXmpApplicationExtension.cs

@ -55,11 +55,11 @@ namespace SixLabors.ImageSharp.Formats.Gif
// Write "XMP DataXMP"
ReadOnlySpan<byte> idBytes = GifConstants.XmpApplicationIdentificationBytes;
idBytes.CopyTo(buffer.Slice(bytesWritten));
idBytes.CopyTo(buffer[bytesWritten..]);
bytesWritten += idBytes.Length;
// XMP Data itself
this.Data.CopyTo(buffer.Slice(bytesWritten));
this.Data.CopyTo(buffer[bytesWritten..]);
bytesWritten += this.Data.Length;
// Write the Magic Trailer

2
src/ImageSharp/Formats/ImageFormatManager.cs

@ -101,7 +101,7 @@ namespace SixLabors.ImageSharp.Formats
if (extension[0] == '.')
{
extension = extension.Substring(1);
extension = extension[1..];
}
return this.imageFormats.FirstOrDefault(x => x.FileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase));

2
src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs

@ -89,7 +89,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
public static bool IsProfile(ReadOnlySpan<byte> bytesToCheck, ReadOnlySpan<byte> profileIdentifier)
{
return bytesToCheck.Length >= profileIdentifier.Length
&& bytesToCheck.Slice(0, profileIdentifier.Length).SequenceEqual(profileIdentifier);
&& bytesToCheck[..profileIdentifier.Length].SequenceEqual(profileIdentifier);
}
}
}

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

@ -162,7 +162,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
{
Span<TPixel> proxyRow = this.paddedProxyPixelRow.GetSpan();
PixelOperations<TPixel>.Instance.PackFromRgbPlanes(this.configuration, r, g, b, proxyRow);
proxyRow.Slice(0, width).CopyTo(this.pixelBuffer.DangerousGetRowSpan(yy));
proxyRow[..width].CopyTo(this.pixelBuffer.DangerousGetRowSpan(yy));
}
}

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

@ -810,7 +810,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
remaining = 0;
}
if (ProfileResolver.IsProfile(this.temp, ProfileResolver.XmpMarker.Slice(0, ExifMarkerLength)))
if (ProfileResolver.IsProfile(this.temp, ProfileResolver.XmpMarker[..ExifMarkerLength]))
{
const int remainingXmpMarkerBytes = XmpMarkerLength - ExifMarkerLength;
if (remaining < remainingXmpMarkerBytes || this.IgnoreMetadata)
@ -912,13 +912,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
while (blockDataSpan.Length > 12)
{
if (!ProfileResolver.IsProfile(blockDataSpan.Slice(0, 4), ProfileResolver.AdobeImageResourceBlockMarker))
if (!ProfileResolver.IsProfile(blockDataSpan[..4], ProfileResolver.AdobeImageResourceBlockMarker))
{
return;
}
blockDataSpan = blockDataSpan.Slice(4);
Span<byte> imageResourceBlockId = blockDataSpan.Slice(0, 2);
blockDataSpan = blockDataSpan[4..];
Span<byte> imageResourceBlockId = blockDataSpan[..2];
if (ProfileResolver.IsProfile(imageResourceBlockId, ProfileResolver.AdobeIptcMarker))
{
int resourceBlockNameLength = ReadImageResourceNameLength(blockDataSpan);
@ -942,7 +942,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
break;
}
blockDataSpan = blockDataSpan.Slice(dataStartIdx + resourceDataSize);
blockDataSpan = blockDataSpan[(dataStartIdx + resourceDataSize)..];
}
}
}
@ -1322,9 +1322,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
using (IMemoryOwner<byte> buffer = this.Configuration.MemoryAllocator.Allocate<byte>(totalBufferSize))
{
Span<byte> bufferSpan = buffer.GetSpan();
Span<byte> huffmanLengthsSpan = bufferSpan.Slice(0, codeLengthsByteSize);
Span<byte> huffmanLengthsSpan = bufferSpan[..codeLengthsByteSize];
Span<byte> huffmanValuesSpan = bufferSpan.Slice(codeLengthsByteSize, codeValuesMaxByteSize);
Span<uint> tableWorkspace = MemoryMarshal.Cast<byte, uint>(bufferSpan.Slice(codeLengthsByteSize + codeValuesMaxByteSize));
Span<uint> tableWorkspace = MemoryMarshal.Cast<byte, uint>(bufferSpan[(codeLengthsByteSize + codeValuesMaxByteSize)..]);
for (int i = 2; i < remaining;)
{
@ -1367,7 +1367,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
tableType,
tableIndex,
huffmanLengthsSpan,
huffmanValuesSpan.Slice(0, codeLengthSum),
huffmanValuesSpan[..codeLengthSum],
tableWorkspace);
}
}

6
src/ImageSharp/Formats/Pbm/PbmEncoderCore.cs

@ -145,17 +145,17 @@ namespace SixLabors.ImageSharp.Formats.Pbm
buffer[1] = signature;
buffer[2] = NewLine;
Utf8Formatter.TryFormat(pixelSize.Width, buffer.Slice(written), out int bytesWritten);
Utf8Formatter.TryFormat(pixelSize.Width, buffer[written..], out int bytesWritten);
written += bytesWritten;
buffer[written++] = Space;
Utf8Formatter.TryFormat(pixelSize.Height, buffer.Slice(written), out bytesWritten);
Utf8Formatter.TryFormat(pixelSize.Height, buffer[written..], out bytesWritten);
written += bytesWritten;
buffer[written++] = NewLine;
if (this.colorType != PbmColorType.BlackAndWhite)
{
int maxPixelValue = this.componentType == PbmComponentType.Short ? 65535 : 255;
Utf8Formatter.TryFormat(maxPixelValue, buffer.Slice(written), out bytesWritten);
Utf8Formatter.TryFormat(maxPixelValue, buffer[written..], out bytesWritten);
written += bytesWritten;
buffer[written++] = NewLine;
}

16
src/ImageSharp/Formats/Pbm/PlainEncoder.cs

@ -94,7 +94,7 @@ namespace SixLabors.ImageSharp.Formats.Pbm
int written = 0;
for (int x = 0; x < width; x++)
{
Utf8Formatter.TryFormat(rowSpan[x].PackedValue, plainSpan.Slice(written), out int bytesWritten, DecimalFormat);
Utf8Formatter.TryFormat(rowSpan[x].PackedValue, plainSpan[written..], out int bytesWritten, DecimalFormat);
written += bytesWritten;
plainSpan[written++] = Space;
}
@ -127,7 +127,7 @@ namespace SixLabors.ImageSharp.Formats.Pbm
int written = 0;
for (int x = 0; x < width; x++)
{
Utf8Formatter.TryFormat(rowSpan[x].PackedValue, plainSpan.Slice(written), out int bytesWritten, DecimalFormat);
Utf8Formatter.TryFormat(rowSpan[x].PackedValue, plainSpan[written..], out int bytesWritten, DecimalFormat);
written += bytesWritten;
plainSpan[written++] = Space;
}
@ -160,13 +160,13 @@ namespace SixLabors.ImageSharp.Formats.Pbm
int written = 0;
for (int x = 0; x < width; x++)
{
Utf8Formatter.TryFormat(rowSpan[x].R, plainSpan.Slice(written), out int bytesWritten, DecimalFormat);
Utf8Formatter.TryFormat(rowSpan[x].R, plainSpan[written..], out int bytesWritten, DecimalFormat);
written += bytesWritten;
plainSpan[written++] = Space;
Utf8Formatter.TryFormat(rowSpan[x].G, plainSpan.Slice(written), out bytesWritten, DecimalFormat);
Utf8Formatter.TryFormat(rowSpan[x].G, plainSpan[written..], out bytesWritten, DecimalFormat);
written += bytesWritten;
plainSpan[written++] = Space;
Utf8Formatter.TryFormat(rowSpan[x].B, plainSpan.Slice(written), out bytesWritten, DecimalFormat);
Utf8Formatter.TryFormat(rowSpan[x].B, plainSpan[written..], out bytesWritten, DecimalFormat);
written += bytesWritten;
plainSpan[written++] = Space;
}
@ -199,13 +199,13 @@ namespace SixLabors.ImageSharp.Formats.Pbm
int written = 0;
for (int x = 0; x < width; x++)
{
Utf8Formatter.TryFormat(rowSpan[x].R, plainSpan.Slice(written), out int bytesWritten, DecimalFormat);
Utf8Formatter.TryFormat(rowSpan[x].R, plainSpan[written..], out int bytesWritten, DecimalFormat);
written += bytesWritten;
plainSpan[written++] = Space;
Utf8Formatter.TryFormat(rowSpan[x].G, plainSpan.Slice(written), out bytesWritten, DecimalFormat);
Utf8Formatter.TryFormat(rowSpan[x].G, plainSpan[written..], out bytesWritten, DecimalFormat);
written += bytesWritten;
plainSpan[written++] = Space;
Utf8Formatter.TryFormat(rowSpan[x].B, plainSpan.Slice(written), out bytesWritten, DecimalFormat);
Utf8Formatter.TryFormat(rowSpan[x].B, plainSpan[written..], out bytesWritten, DecimalFormat);
written += bytesWritten;
plainSpan[written++] = Space;
}

4
src/ImageSharp/Formats/Png/Chunks/PhysicalChunkData.cs

@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Chunks
/// <returns>The parsed PhysicalChunkData.</returns>
public static PhysicalChunkData Parse(ReadOnlySpan<byte> data)
{
uint hResolution = BinaryPrimitives.ReadUInt32BigEndian(data.Slice(0, 4));
uint hResolution = BinaryPrimitives.ReadUInt32BigEndian(data[..4]);
uint vResolution = BinaryPrimitives.ReadUInt32BigEndian(data.Slice(4, 4));
byte unit = data[8];
@ -102,7 +102,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Chunks
/// <param name="buffer">The buffer.</param>
public void WriteTo(Span<byte> buffer)
{
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(0, 4), this.XAxisPixelsPerUnit);
BinaryPrimitives.WriteUInt32BigEndian(buffer[..4], this.XAxisPixelsPerUnit);
BinaryPrimitives.WriteUInt32BigEndian(buffer.Slice(4, 4), this.YAxisPixelsPerUnit);
buffer[8] = this.UnitSpecifier;
}

4
src/ImageSharp/Formats/Png/Filters/NoneFilter.cs

@ -23,8 +23,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
{
// Insert a byte before the data.
result[0] = 0;
result = result.Slice(1);
scanline.Slice(0, Math.Min(scanline.Length, result.Length)).CopyTo(result);
result = result[1..];
scanline[..Math.Min(scanline.Length, result.Length)].CopyTo(result);
}
}
}

167
src/ImageSharp/Formats/Png/PngDecoderCore.cs

@ -4,7 +4,6 @@
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Runtime.CompilerServices;
@ -164,10 +163,10 @@ namespace SixLabors.ImageSharp.Formats.Png
this.ReadHeaderChunk(pngMetadata, chunk.Data.GetSpan());
break;
case PngChunkType.Physical:
this.ReadPhysicalChunk(metadata, chunk.Data.GetSpan());
ReadPhysicalChunk(metadata, chunk.Data.GetSpan());
break;
case PngChunkType.Gamma:
this.ReadGammaChunk(pngMetadata, chunk.Data.GetSpan());
ReadGammaChunk(pngMetadata, chunk.Data.GetSpan());
break;
case PngChunkType.Data:
if (image is null)
@ -203,7 +202,7 @@ namespace SixLabors.ImageSharp.Formats.Png
{
byte[] exifData = new byte[chunk.Length];
chunk.Data.GetSpan().CopyTo(exifData);
this.MergeOrSetExifProfile(metadata, new ExifProfile(exifData), replaceExistingKeys: true);
MergeOrSetExifProfile(metadata, new ExifProfile(exifData), replaceExistingKeys: true);
}
break;
@ -269,7 +268,7 @@ namespace SixLabors.ImageSharp.Formats.Png
break;
}
this.ReadPhysicalChunk(metadata, chunk.Data.GetSpan());
ReadPhysicalChunk(metadata, chunk.Data.GetSpan());
break;
case PngChunkType.Gamma:
if (this.colorMetadataOnly)
@ -278,7 +277,7 @@ namespace SixLabors.ImageSharp.Formats.Png
break;
}
this.ReadGammaChunk(pngMetadata, chunk.Data.GetSpan());
ReadGammaChunk(pngMetadata, chunk.Data.GetSpan());
break;
case PngChunkType.Data:
@ -340,7 +339,7 @@ namespace SixLabors.ImageSharp.Formats.Png
{
byte[] exifData = new byte[chunk.Length];
chunk.Data.GetSpan().CopyTo(exifData);
this.MergeOrSetExifProfile(metadata, new ExifProfile(exifData), replaceExistingKeys: true);
MergeOrSetExifProfile(metadata, new ExifProfile(exifData), replaceExistingKeys: true);
}
break;
@ -429,7 +428,7 @@ namespace SixLabors.ImageSharp.Formats.Png
/// </summary>
/// <param name="metadata">The metadata to read to.</param>
/// <param name="data">The data containing physical data.</param>
private void ReadPhysicalChunk(ImageMetadata metadata, ReadOnlySpan<byte> data)
private static void ReadPhysicalChunk(ImageMetadata metadata, ReadOnlySpan<byte> data)
{
var physicalChunk = PhysicalChunkData.Parse(data);
@ -446,7 +445,7 @@ namespace SixLabors.ImageSharp.Formats.Png
/// </summary>
/// <param name="pngMetadata">The metadata to read to.</param>
/// <param name="data">The data containing physical data.</param>
private void ReadGammaChunk(PngMetadata pngMetadata, ReadOnlySpan<byte> data)
private static void ReadGammaChunk(PngMetadata pngMetadata, ReadOnlySpan<byte> data)
{
if (data.Length < 4)
{
@ -749,7 +748,7 @@ namespace SixLabors.ImageSharp.Formats.Png
Span<TPixel> rowSpan = pixels.PixelBuffer.DangerousGetRowSpan(this.currentRow);
// Trim the first marker byte from the buffer
ReadOnlySpan<byte> trimmed = defilteredScanline.Slice(1, defilteredScanline.Length - 1);
ReadOnlySpan<byte> trimmed = defilteredScanline[1..];
// Convert 1, 2, and 4 bit pixel data into the 8 bit equivalent.
IMemoryOwner<byte> buffer = null;
@ -841,7 +840,7 @@ namespace SixLabors.ImageSharp.Formats.Png
where TPixel : unmanaged, IPixel<TPixel>
{
// Trim the first marker byte from the buffer
ReadOnlySpan<byte> trimmed = defilteredScanline.Slice(1, defilteredScanline.Length - 1);
ReadOnlySpan<byte> trimmed = defilteredScanline[1..];
// Convert 1, 2, and 4 bit pixel data into the 8 bit equivalent.
IMemoryOwner<byte> buffer = null;
@ -941,7 +940,7 @@ namespace SixLabors.ImageSharp.Formats.Png
{
if (this.header.BitDepth == 16)
{
ushort rc = BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(0, 2));
ushort rc = BinaryPrimitives.ReadUInt16LittleEndian(alpha[..2]);
ushort gc = BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(2, 2));
ushort bc = BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(4, 2));
@ -963,7 +962,7 @@ namespace SixLabors.ImageSharp.Formats.Png
{
if (this.header.BitDepth == 16)
{
pngMetadata.TransparentL16 = new L16(BinaryPrimitives.ReadUInt16LittleEndian(alpha.Slice(0, 2)));
pngMetadata.TransparentL16 = new L16(BinaryPrimitives.ReadUInt16LittleEndian(alpha[..2]));
}
else
{
@ -1014,13 +1013,13 @@ namespace SixLabors.ImageSharp.Formats.Png
return;
}
ReadOnlySpan<byte> keywordBytes = data.Slice(0, zeroIndex);
if (!this.TryReadTextKeyword(keywordBytes, out string name))
ReadOnlySpan<byte> keywordBytes = data[..zeroIndex];
if (!TryReadTextKeyword(keywordBytes, out string name))
{
return;
}
string value = PngConstants.Encoding.GetString(data.Slice(zeroIndex + 1));
string value = PngConstants.Encoding.GetString(data[(zeroIndex + 1)..]);
if (!this.TryReadTextChunkMetadata(baseMetadata, name, value))
{
@ -1042,7 +1041,7 @@ namespace SixLabors.ImageSharp.Formats.Png
}
int zeroIndex = data.IndexOf((byte)0);
if (zeroIndex < PngConstants.MinTextKeywordLength || zeroIndex > PngConstants.MaxTextKeywordLength)
if (zeroIndex is < PngConstants.MinTextKeywordLength or > PngConstants.MaxTextKeywordLength)
{
return;
}
@ -1054,13 +1053,13 @@ namespace SixLabors.ImageSharp.Formats.Png
return;
}
ReadOnlySpan<byte> keywordBytes = data.Slice(0, zeroIndex);
if (!this.TryReadTextKeyword(keywordBytes, out string name))
ReadOnlySpan<byte> keywordBytes = data[..zeroIndex];
if (!TryReadTextKeyword(keywordBytes, out string name))
{
return;
}
ReadOnlySpan<byte> compressedData = data.Slice(zeroIndex + 2);
ReadOnlySpan<byte> compressedData = data[(zeroIndex + 2)..];
if (this.TryUncompressTextData(compressedData, PngConstants.Encoding, out string uncompressed) &&
!this.TryReadTextChunkMetadata(baseMetadata, name, uncompressed))
@ -1105,19 +1104,19 @@ namespace SixLabors.ImageSharp.Formats.Png
ReadOnlySpan<char> dataSpan = data.AsSpan();
dataSpan = dataSpan.TrimStart();
if (!StringEqualsInsensitive(dataSpan.Slice(0, 4), "exif".AsSpan()))
if (!StringEqualsInsensitive(dataSpan[..4], "exif".AsSpan()))
{
// "exif" identifier is missing from the beginning of the text chunk
return false;
}
// Skip to the data length
dataSpan = dataSpan.Slice(4).TrimStart();
dataSpan = dataSpan[4..].TrimStart();
int dataLengthEnd = dataSpan.IndexOf('\n');
int dataLength = ParseInt32(dataSpan.Slice(0, dataSpan.IndexOf('\n')));
int dataLength = ParseInt32(dataSpan[..dataSpan.IndexOf('\n')]);
// Skip to the hex-encoded data
dataSpan = dataSpan.Slice(dataLengthEnd).Trim();
dataSpan = dataSpan[dataLengthEnd..].Trim();
// Sequence of bytes for the exif header ("Exif" ASCII and two zero bytes).
// This doesn't actually allocate.
@ -1142,15 +1141,15 @@ namespace SixLabors.ImageSharp.Formats.Png
tempExifBuf = new byte[exifHeader.Length];
}
HexConverter.HexStringToBytes(dataSpan.Slice(0, exifHeader.Length * 2), tempExifBuf);
if (!tempExifBuf.AsSpan().Slice(0, exifHeader.Length).SequenceEqual(exifHeader))
HexConverter.HexStringToBytes(dataSpan[..(exifHeader.Length * 2)], tempExifBuf);
if (!tempExifBuf.AsSpan()[..exifHeader.Length].SequenceEqual(exifHeader))
{
// Exif header in the hex data is not valid
return false;
}
// Skip over the exif header we just tested
dataSpan = dataSpan.Slice(exifHeader.Length * 2);
dataSpan = dataSpan[(exifHeader.Length * 2)..];
dataLength -= exifHeader.Length;
// Load the hex-encoded data, one line at a time
@ -1161,12 +1160,12 @@ namespace SixLabors.ImageSharp.Formats.Png
int newlineIndex = dataSpan.IndexOf('\n');
if (newlineIndex != -1)
{
lineSpan = dataSpan.Slice(0, newlineIndex);
lineSpan = dataSpan[..newlineIndex];
}
i += HexConverter.HexStringToBytes(lineSpan, exifBlob.AsSpan().Slice(i));
i += HexConverter.HexStringToBytes(lineSpan, exifBlob.AsSpan()[i..]);
dataSpan = dataSpan.Slice(newlineIndex + 1);
dataSpan = dataSpan[(newlineIndex + 1)..];
}
}
catch
@ -1174,7 +1173,7 @@ namespace SixLabors.ImageSharp.Formats.Png
return false;
}
this.MergeOrSetExifProfile(metadata, new ExifProfile(exifBlob), replaceExistingKeys: false);
MergeOrSetExifProfile(metadata, new ExifProfile(exifBlob), replaceExistingKeys: false);
return true;
}
@ -1198,13 +1197,13 @@ namespace SixLabors.ImageSharp.Formats.Png
return;
}
ReadOnlySpan<byte> keywordBytes = data.Slice(0, zeroIndex);
if (!this.TryReadTextKeyword(keywordBytes, out string name))
ReadOnlySpan<byte> keywordBytes = data[..zeroIndex];
if (!TryReadTextKeyword(keywordBytes, out string name))
{
return;
}
ReadOnlySpan<byte> compressedData = data.Slice(zeroIndex + 2);
ReadOnlySpan<byte> compressedData = data[(zeroIndex + 2)..];
if (this.TryUncompressZlibData(compressedData, out byte[] iccpProfileBytes))
{
@ -1222,29 +1221,27 @@ namespace SixLabors.ImageSharp.Formats.Png
{
fixed (byte* compressedDataBase = compressedData)
{
using (IMemoryOwner<byte> destBuffer = this.memoryAllocator.Allocate<byte>(this.Configuration.StreamProcessingBufferSize))
using (var memoryStreamOutput = new MemoryStream(compressedData.Length))
using (var memoryStreamInput = new UnmanagedMemoryStream(compressedDataBase, compressedData.Length))
using (var bufferedStream = new BufferedReadStream(this.Configuration, memoryStreamInput))
using (var inflateStream = new ZlibInflateStream(bufferedStream))
using IMemoryOwner<byte> destBuffer = this.memoryAllocator.Allocate<byte>(this.Configuration.StreamProcessingBufferSize);
using var memoryStreamOutput = new MemoryStream(compressedData.Length);
using var memoryStreamInput = new UnmanagedMemoryStream(compressedDataBase, compressedData.Length);
using var bufferedStream = new BufferedReadStream(this.Configuration, memoryStreamInput);
using var inflateStream = new ZlibInflateStream(bufferedStream);
Span<byte> destUncompressedData = destBuffer.GetSpan();
if (!inflateStream.AllocateNewBytes(compressedData.Length, false))
{
Span<byte> destUncompressedData = destBuffer.GetSpan();
if (!inflateStream.AllocateNewBytes(compressedData.Length, false))
{
uncompressedBytesArray = Array.Empty<byte>();
return false;
}
int bytesRead = inflateStream.CompressedStream.Read(destUncompressedData, 0, destUncompressedData.Length);
while (bytesRead != 0)
{
memoryStreamOutput.Write(destUncompressedData.Slice(0, bytesRead));
bytesRead = inflateStream.CompressedStream.Read(destUncompressedData, 0, destUncompressedData.Length);
}
uncompressedBytesArray = Array.Empty<byte>();
return false;
}
uncompressedBytesArray = memoryStreamOutput.ToArray();
return true;
int bytesRead = inflateStream.CompressedStream.Read(destUncompressedData, 0, destUncompressedData.Length);
while (bytesRead != 0)
{
memoryStreamOutput.Write(destUncompressedData[..bytesRead]);
bytesRead = inflateStream.CompressedStream.Read(destUncompressedData, 0, destUncompressedData.Length);
}
uncompressedBytesArray = memoryStreamOutput.ToArray();
return true;
}
}
@ -1256,31 +1253,14 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <param name="span2">The second <see cref="Span{T}"/> to compare.</param>
/// <returns>True if the spans were identical, false otherwise.</returns>
private static bool StringEqualsInsensitive(ReadOnlySpan<char> span1, ReadOnlySpan<char> span2)
{
#pragma warning disable IDE0022 // Use expression body for methods
#if NETSTANDARD2_1 || NETCOREAPP2_1_OR_GREATER
return span1.Equals(span2, StringComparison.OrdinalIgnoreCase);
#else
return span1.ToString().Equals(span2.ToString(), StringComparison.OrdinalIgnoreCase);
#endif
#pragma warning restore IDE0022 // Use expression body for methods
}
=> span1.Equals(span2, StringComparison.OrdinalIgnoreCase);
/// <summary>
/// int.Parse() a ReadOnlySpan&lt;char&gt;, with a fallback for older frameworks.
/// </summary>
/// <param name="span">The <see cref="int"/> to parse.</param>
/// <returns>The parsed <see cref="int"/>.</returns>
private static int ParseInt32(ReadOnlySpan<char> span)
{
#pragma warning disable IDE0022 // Use expression body for methods
#if NETSTANDARD2_1 || NETCOREAPP2_1_OR_GREATER
return int.Parse(span);
#else
return int.Parse(span.ToString());
#endif
#pragma warning restore IDE0022 // Use expression body for methods
}
private static int ParseInt32(ReadOnlySpan<char> span) => int.Parse(span);
/// <summary>
/// Sets the <see cref="ExifProfile"/> in <paramref name="metadata"/> to <paramref name="newProfile"/>,
@ -1291,7 +1271,7 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <param name="replaceExistingKeys">If <paramref name="metadata"/> already contains an <see cref="ExifProfile"/>,
/// controls whether existing exif tags in <paramref name="metadata"/> will be overwritten with any conflicting
/// tags from <paramref name="newProfile"/>.</param>
private void MergeOrSetExifProfile(ImageMetadata metadata, ExifProfile newProfile, bool replaceExistingKeys)
private static void MergeOrSetExifProfile(ImageMetadata metadata, ExifProfile newProfile, bool replaceExistingKeys)
{
if (metadata.ExifProfile is null)
{
@ -1331,13 +1311,13 @@ namespace SixLabors.ImageSharp.Formats.Png
PngMetadata pngMetadata = metadata.GetPngMetadata();
int zeroIndexKeyword = data.IndexOf((byte)0);
if (zeroIndexKeyword < PngConstants.MinTextKeywordLength || zeroIndexKeyword > PngConstants.MaxTextKeywordLength)
if (zeroIndexKeyword is < PngConstants.MinTextKeywordLength or > PngConstants.MaxTextKeywordLength)
{
return;
}
byte compressionFlag = data[zeroIndexKeyword + 1];
if (!(compressionFlag == 0 || compressionFlag == 1))
if (compressionFlag is not (0 or 1))
{
return;
}
@ -1350,7 +1330,7 @@ namespace SixLabors.ImageSharp.Formats.Png
}
int langStartIdx = zeroIndexKeyword + 3;
int languageLength = data.Slice(langStartIdx).IndexOf((byte)0);
int languageLength = data[langStartIdx..].IndexOf((byte)0);
if (languageLength < 0)
{
return;
@ -1359,11 +1339,11 @@ namespace SixLabors.ImageSharp.Formats.Png
string language = PngConstants.LanguageEncoding.GetString(data.Slice(langStartIdx, languageLength));
int translatedKeywordStartIdx = langStartIdx + languageLength + 1;
int translatedKeywordLength = data.Slice(translatedKeywordStartIdx).IndexOf((byte)0);
int translatedKeywordLength = data[translatedKeywordStartIdx..].IndexOf((byte)0);
string translatedKeyword = PngConstants.TranslatedEncoding.GetString(data.Slice(translatedKeywordStartIdx, translatedKeywordLength));
ReadOnlySpan<byte> keywordBytes = data.Slice(0, zeroIndexKeyword);
if (!this.TryReadTextKeyword(keywordBytes, out string keyword))
ReadOnlySpan<byte> keywordBytes = data[..zeroIndexKeyword];
if (!TryReadTextKeyword(keywordBytes, out string keyword))
{
return;
}
@ -1371,21 +1351,21 @@ namespace SixLabors.ImageSharp.Formats.Png
int dataStartIdx = translatedKeywordStartIdx + translatedKeywordLength + 1;
if (compressionFlag == 1)
{
ReadOnlySpan<byte> compressedData = data.Slice(dataStartIdx);
ReadOnlySpan<byte> compressedData = data[dataStartIdx..];
if (this.TryUncompressTextData(compressedData, PngConstants.TranslatedEncoding, out string uncompressed))
{
pngMetadata.TextData.Add(new PngTextData(keyword, uncompressed, language, translatedKeyword));
}
}
else if (this.IsXmpTextData(keywordBytes))
else if (IsXmpTextData(keywordBytes))
{
var xmpProfile = new XmpProfile(data.Slice(dataStartIdx).ToArray());
var xmpProfile = new XmpProfile(data[dataStartIdx..].ToArray());
metadata.XmpProfile = xmpProfile;
}
else
{
string value = PngConstants.TranslatedEncoding.GetString(data.Slice(dataStartIdx));
string value = PngConstants.TranslatedEncoding.GetString(data[dataStartIdx..]);
pngMetadata.TextData.Add(new PngTextData(keyword, value, language, translatedKeyword));
}
}
@ -1620,14 +1600,14 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <param name="keywordBytes">The keyword bytes.</param>
/// <param name="name">The name.</param>
/// <returns>True, if the keyword could be read and is valid.</returns>
private bool TryReadTextKeyword(ReadOnlySpan<byte> keywordBytes, out string name)
private static bool TryReadTextKeyword(ReadOnlySpan<byte> keywordBytes, out string name)
{
name = string.Empty;
// Keywords shall contain only printable Latin-1.
foreach (byte c in keywordBytes)
{
if (!((c >= 32 && c <= 126) || (c >= 161 && c <= 255)))
if (c is not ((>= 32 and <= 126) or (>= 161 and <= 255)))
{
return false;
}
@ -1635,21 +1615,12 @@ namespace SixLabors.ImageSharp.Formats.Png
// Keywords should not be empty or have leading or trailing whitespace.
name = PngConstants.Encoding.GetString(keywordBytes);
if (string.IsNullOrWhiteSpace(name) || name.StartsWith(" ") || name.EndsWith(" "))
{
return false;
}
return true;
return !string.IsNullOrWhiteSpace(name) && !name.StartsWith(" ") && !name.EndsWith(" ");
}
private bool IsXmpTextData(ReadOnlySpan<byte> keywordBytes) => keywordBytes.SequenceEqual(PngConstants.XmpKeyword);
private static bool IsXmpTextData(ReadOnlySpan<byte> keywordBytes) => keywordBytes.SequenceEqual(PngConstants.XmpKeyword);
private void SwapScanlineBuffers()
{
IMemoryOwner<byte> temp = this.previousScanline;
this.previousScanline = this.scanline;
this.scanline = temp;
}
=> (this.scanline, this.previousScanline) = (this.previousScanline, this.scanline);
}
}

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

@ -694,7 +694,7 @@ namespace SixLabors.ImageSharp.Formats.Png
int bytesWritten = PngConstants.XmpKeyword.Length;
// Write the iTxt header (all zeros in this case).
Span<byte> iTxtHeader = payload.Slice(bytesWritten);
Span<byte> iTxtHeader = payload[bytesWritten..];
iTxtHeader[4] = 0;
iTxtHeader[3] = 0;
iTxtHeader[2] = 0;
@ -703,7 +703,7 @@ namespace SixLabors.ImageSharp.Formats.Png
bytesWritten += 5;
// And the XMP data itself.
xmpData.CopyTo(payload.Slice(bytesWritten));
xmpData.CopyTo(payload[bytesWritten..]);
this.WriteChunk(stream, PngChunkType.InternationalText, payload);
}
}
@ -731,7 +731,7 @@ namespace SixLabors.ImageSharp.Formats.Png
int bytesWritten = ColorProfileName.Length;
outputBytes[bytesWritten++] = 0; // Null separator.
outputBytes[bytesWritten++] = 0; // Compression.
compressedData.CopyTo(outputBytes.Slice(bytesWritten));
compressedData.CopyTo(outputBytes[bytesWritten..]);
this.WriteChunk(stream, PngChunkType.EmbeddedColorProfile, outputBytes);
}
}
@ -792,13 +792,13 @@ namespace SixLabors.ImageSharp.Formats.Png
}
outputBytes[bytesWritten++] = 0;
languageTag.CopyTo(outputBytes.Slice(bytesWritten));
languageTag.CopyTo(outputBytes[bytesWritten..]);
bytesWritten += languageTag.Length;
outputBytes[bytesWritten++] = 0;
translatedKeyword.CopyTo(outputBytes.Slice(bytesWritten));
translatedKeyword.CopyTo(outputBytes[bytesWritten..]);
bytesWritten += translatedKeyword.Length;
outputBytes[bytesWritten++] = 0;
textBytes.CopyTo(outputBytes.Slice(bytesWritten));
textBytes.CopyTo(outputBytes[bytesWritten..]);
this.WriteChunk(stream, PngChunkType.InternationalText, outputBytes);
}
}
@ -816,7 +816,7 @@ namespace SixLabors.ImageSharp.Formats.Png
int bytesWritten = textData.Keyword.Length;
outputBytes[bytesWritten++] = 0; // Null separator.
outputBytes[bytesWritten++] = 0; // Compression.
compressedData.CopyTo(outputBytes.Slice(bytesWritten));
compressedData.CopyTo(outputBytes[bytesWritten..]);
this.WriteChunk(stream, PngChunkType.CompressedText, outputBytes);
}
}
@ -830,7 +830,7 @@ namespace SixLabors.ImageSharp.Formats.Png
PngConstants.Encoding.GetBytes(textData.Keyword).CopyTo(outputBytes);
int bytesWritten = textData.Keyword.Length;
outputBytes[bytesWritten++] = 0;
PngConstants.Encoding.GetBytes(textData.Value).CopyTo(outputBytes.Slice(bytesWritten));
PngConstants.Encoding.GetBytes(textData.Value).CopyTo(outputBytes[bytesWritten..]);
this.WriteChunk(stream, PngChunkType.Text, outputBytes);
}
}

4
src/ImageSharp/Formats/Png/PngHeader.cs

@ -116,7 +116,7 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <param name="buffer">The buffer to write to.</param>
public void WriteTo(Span<byte> buffer)
{
BinaryPrimitives.WriteInt32BigEndian(buffer.Slice(0, 4), this.Width);
BinaryPrimitives.WriteInt32BigEndian(buffer[..4], this.Width);
BinaryPrimitives.WriteInt32BigEndian(buffer.Slice(4, 4), this.Height);
buffer[8] = this.BitDepth;
@ -134,7 +134,7 @@ namespace SixLabors.ImageSharp.Formats.Png
public static PngHeader Parse(ReadOnlySpan<byte> data)
{
return new PngHeader(
width: BinaryPrimitives.ReadInt32BigEndian(data.Slice(0, 4)),
width: BinaryPrimitives.ReadInt32BigEndian(data[..4]),
height: BinaryPrimitives.ReadInt32BigEndian(data.Slice(4, 4)),
bitDepth: data[8],
colorType: (PngColorType)data[9],

4
src/ImageSharp/Formats/Tga/TgaDecoderCore.cs

@ -772,7 +772,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
int bufferIdx = uncompressedPixels * bytesPerPixel;
for (int i = 0; i < runLength + 1; i++, uncompressedPixels++)
{
pixel.AsSpan().CopyTo(buffer.Slice(bufferIdx));
pixel.AsSpan().CopyTo(buffer[bufferIdx..]);
bufferIdx += bytesPerPixel;
}
}
@ -784,7 +784,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
for (int i = 0; i < runLength + 1; i++, uncompressedPixels++)
{
this.currentStream.Read(pixel, 0, bytesPerPixel);
pixel.AsSpan().CopyTo(buffer.Slice(bufferIdx));
pixel.AsSpan().CopyTo(buffer[bufferIdx..]);
bufferIdx += bytesPerPixel;
}
}

2
src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs

@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors
{
Span<byte> row = rows.Slice(i * this.BytesPerRow, this.BytesPerRow);
int size = PackBitsWriter.PackBits(row, span);
this.Output.Write(span.Slice(0, size));
this.Output.Write(span[..size]);
}
}

2
src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsWriter.cs

@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors
int literalRunStart = end - literalRunLength;
sbyte runLength = (sbyte)(literalRunLength - 1);
compressedRowSpan[compressedRowPos] = (byte)runLength;
rowSpan.Slice(literalRunStart, literalRunLength).CopyTo(compressedRowSpan.Slice(compressedRowPos + 1));
rowSpan.Slice(literalRunStart, literalRunLength).CopyTo(compressedRowSpan[(compressedRowPos + 1)..]);
}
private static void WriteRun(ReadOnlySpan<byte> rowSpan, int start, int runLength, Span<byte> compressedRowSpan, int compressedRowPos)

2
src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffCcittCompressor.cs

@ -511,7 +511,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors
// Write the compressed data to the stream.
int bytesToWrite = this.bitPosition != 0 ? this.bytePosition + 1 : this.bytePosition;
this.Output.Write(compressedData.Slice(0, bytesToWrite));
this.Output.Write(compressedData[..bytesToWrite]);
}
/// <summary>

6
src/ImageSharp/Formats/Tiff/Compression/Decompressors/CcittReferenceScanline.cs

@ -100,7 +100,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
offset = a0;
}
ReadOnlySpan<byte> searchSpace = this.scanLine.Slice(offset);
ReadOnlySpan<byte> searchSpace = this.scanLine[offset..];
byte searchByte = (byte)~a0Byte;
int index = searchSpace.IndexOf(searchByte);
if (index < 0)
@ -120,7 +120,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
return this.scanLine.Length;
}
searchSpace = searchSpace.Slice(index);
searchSpace = searchSpace[index..];
offset += index;
index = searchSpace.IndexOf((byte)~searchByte);
if (index < 0)
@ -143,7 +143,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
byte searchByte = (byte)~this.scanLine[b1];
int offset = b1 + 1;
ReadOnlySpan<byte> searchSpace = this.scanLine.Slice(offset);
ReadOnlySpan<byte> searchSpace = this.scanLine[offset..];
int index = searchSpace.IndexOf(searchByte);
if (index == -1)
{

4
src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs

@ -105,7 +105,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
{
Span<Rgb24> pixelRowSpan = pixelBuffer.DangerousGetRowSpan(y);
Span<byte> rgbBytes = MemoryMarshal.AsBytes(pixelRowSpan);
rgbBytes.CopyTo(buffer.Slice(offset));
rgbBytes.CopyTo(buffer[offset..]);
offset += rgbBytes.Length;
}
}
@ -117,7 +117,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
{
Span<L8> pixelRowSpan = pixelBuffer.DangerousGetRowSpan(y);
Span<byte> rgbBytes = MemoryMarshal.AsBytes(pixelRowSpan);
rgbBytes.CopyTo(buffer.Slice(offset));
rgbBytes.CopyTo(buffer[offset..]);
offset += rgbBytes.Length;
}
}

2
src/ImageSharp/Formats/Tiff/Compression/Decompressors/PackBitsTiffCompression.cs

@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
TiffThrowHelper.ThrowImageFormatException("Tiff packbits compression error: not enough data.");
}
compressedData.Slice(literalOffset, literalLength).CopyTo(buffer.Slice(decompressedOffset));
compressedData.Slice(literalOffset, literalLength).CopyTo(buffer[decompressedOffset..]);
compressedOffset += literalLength + 1;
decompressedOffset += literalLength;

18
src/ImageSharp/Formats/Tiff/Compression/Decompressors/T6TiffCompression.cs

@ -55,7 +55,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
buffer.Clear();
using System.Buffers.IMemoryOwner<byte> scanLineBuffer = this.Allocator.Allocate<byte>(this.width * 2);
Span<byte> scanLine = scanLineBuffer.GetSpan().Slice(0, this.width);
Span<byte> scanLine = scanLineBuffer.GetSpan()[..this.width];
Span<byte> referenceScanLineSpan = scanLineBuffer.GetSpan().Slice(this.width, this.width);
var bitReader = new T6BitReader(stream, this.FillOrder, byteCount);
@ -154,7 +154,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
case CcittTwoDimensionalCodeType.Pass:
int b2 = referenceScanline.FindB2(b1);
scanline.Slice(unpacked, b2 - unpacked).Fill(fillByte);
scanline[unpacked..b2].Fill(fillByte);
unpacked = b2;
a0 = b2;
break;
@ -189,7 +189,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
case CcittTwoDimensionalCodeType.Vertical0:
a1 = b1;
scanline.Slice(unpacked, a1 - unpacked).Fill(fillByte);
scanline[unpacked..a1].Fill(fillByte);
unpacked = a1;
a0 = a1;
fillByte = (byte)~fillByte;
@ -198,7 +198,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
case CcittTwoDimensionalCodeType.VerticalR1:
a1 = b1 + 1;
scanline.Slice(unpacked, a1 - unpacked).Fill(fillByte);
scanline[unpacked..a1].Fill(fillByte);
unpacked = a1;
a0 = a1;
fillByte = (byte)~fillByte;
@ -207,7 +207,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
case CcittTwoDimensionalCodeType.VerticalR2:
a1 = b1 + 2;
scanline.Slice(unpacked, a1 - unpacked).Fill(fillByte);
scanline[unpacked..a1].Fill(fillByte);
unpacked = a1;
a0 = a1;
fillByte = (byte)~fillByte;
@ -216,7 +216,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
case CcittTwoDimensionalCodeType.VerticalR3:
a1 = b1 + 3;
scanline.Slice(unpacked, a1 - unpacked).Fill(fillByte);
scanline[unpacked..a1].Fill(fillByte);
unpacked = a1;
a0 = a1;
fillByte = (byte)~fillByte;
@ -225,7 +225,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
case CcittTwoDimensionalCodeType.VerticalL1:
a1 = b1 - 1;
scanline.Slice(unpacked, a1 - unpacked).Fill(fillByte);
scanline[unpacked..a1].Fill(fillByte);
unpacked = a1;
a0 = a1;
fillByte = (byte)~fillByte;
@ -234,7 +234,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
case CcittTwoDimensionalCodeType.VerticalL2:
a1 = b1 - 2;
scanline.Slice(unpacked, a1 - unpacked).Fill(fillByte);
scanline[unpacked..a1].Fill(fillByte);
unpacked = a1;
a0 = a1;
fillByte = (byte)~fillByte;
@ -243,7 +243,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
case CcittTwoDimensionalCodeType.VerticalL3:
a1 = b1 - 3;
scanline.Slice(unpacked, a1 - unpacked).Fill(fillByte);
scanline[unpacked..a1].Fill(fillByte);
unpacked = a1;
a0 = a1;
fillByte = (byte)~fillByte;

2
src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs

@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
{
Span<Rgb24> pixelRowSpan = pixelBuffer.DangerousGetRowSpan(y);
Span<byte> rgbBytes = MemoryMarshal.AsBytes(pixelRowSpan);
rgbBytes.CopyTo(buffer.Slice(offset));
rgbBytes.CopyTo(buffer[offset..]);
offset += rgbBytes.Length;
}
}

4
src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs

@ -235,7 +235,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression
for (int y = 0; y < height; y++)
{
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
Span<Rgb24> rowRgb = MemoryMarshal.Cast<byte, Rgb24>(rowBytes).Slice(0, width);
Span<Rgb24> rowRgb = MemoryMarshal.Cast<byte, Rgb24>(rowBytes)[..width];
ref Rgb24 rowRgbBase = ref MemoryMarshal.GetReference(rowRgb);
byte r = rowRgbBase.R;
byte g = rowRgbBase.G;
@ -260,7 +260,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression
for (int y = 0; y < height; y++)
{
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount);
Span<Rgba32> rowRgb = MemoryMarshal.Cast<byte, Rgba32>(rowBytes).Slice(0, width);
Span<Rgba32> rowRgb = MemoryMarshal.Cast<byte, Rgba32>(rowBytes)[..width];
ref Rgba32 rowRgbBase = ref MemoryMarshal.GetReference(rowRgb);
byte r = rowRgbBase.R;
byte g = rowRgbBase.G;

2
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero24TiffColor{TPixel}.cs

@ -31,7 +31,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
Span<byte> buffer = stackalloc byte[4];
int bufferStartIdx = this.isBigEndian ? 1 : 0;
Span<byte> bufferSpan = buffer.Slice(bufferStartIdx);
Span<byte> bufferSpan = buffer[bufferStartIdx..];
int offset = 0;
for (int y = top; y < top + height; y++)
{

2
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb242424TiffColor{TPixel}.cs

@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
Span<byte> buffer = stackalloc byte[4];
int bufferStartIdx = this.isBigEndian ? 1 : 0;
Span<byte> bufferSpan = buffer.Slice(bufferStartIdx);
Span<byte> bufferSpan = buffer[bufferStartIdx..];
for (int y = top; y < top + height; y++)
{
Span<TPixel> pixelRow = pixels.DangerousGetRowSpan(y).Slice(left, width);

2
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb24PlanarTiffColor{TPixel}.cs

@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
Span<byte> redData = data[0].GetSpan();
Span<byte> greenData = data[1].GetSpan();
Span<byte> blueData = data[2].GetSpan();
Span<byte> bufferSpan = buffer.Slice(bufferStartIdx);
Span<byte> bufferSpan = buffer[bufferStartIdx..];
int offset = 0;
for (int y = top; y < top + height; y++)

2
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba24242424TiffColor{TPixel}.cs

@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
Span<byte> buffer = stackalloc byte[4];
int bufferStartIdx = this.isBigEndian ? 1 : 0;
Span<byte> bufferSpan = buffer.Slice(bufferStartIdx);
Span<byte> bufferSpan = buffer[bufferStartIdx..];
for (int y = top; y < top + height; y++)
{
Span<TPixel> pixelRow = pixels.DangerousGetRowSpan(y).Slice(left, width);

2
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba24PlanarTiffColor{TPixel}.cs

@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
Span<byte> greenData = data[1].GetSpan();
Span<byte> blueData = data[2].GetSpan();
Span<byte> alphaData = data[3].GetSpan();
Span<byte> bufferSpan = buffer.Slice(bufferStartIdx);
Span<byte> bufferSpan = buffer[bufferStartIdx..];
bool hasAssociatedAlpha = this.extraSamplesType.HasValue && this.extraSamplesType == TiffExtraSampleType.AssociatedAlphaData;
int offset = 0;

2
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero24TiffColor{TPixel}.cs

@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
int bufferStartIdx = this.isBigEndian ? 1 : 0;
const uint maxValue = 0xFFFFFF;
Span<byte> bufferSpan = buffer.Slice(bufferStartIdx);
Span<byte> bufferSpan = buffer[bufferStartIdx..];
int offset = 0;
for (int y = top; y < top + height; y++)
{

4
src/ImageSharp/Formats/Tiff/Writers/TiffBiColorWriter{TPixel}.cs

@ -55,7 +55,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Writers
grayRowIdx++;
}
compressor.CompressStrip(pixelAsGraySpan.Slice(0, stripPixels), height);
compressor.CompressStrip(pixelAsGraySpan[..stripPixels], height);
});
}
else
@ -76,7 +76,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Writers
{
int bitIndex = 0;
int byteIndex = 0;
Span<byte> outputRow = rows.Slice(outputRowIdx * this.BytesPerRow);
Span<byte> outputRow = rows[(outputRowIdx * this.BytesPerRow)..];
Span<TPixel> pixelsBlackWhiteRow = blackWhiteBuffer.DangerousGetRowSpan(row);
PixelOperations<TPixel>.Instance.ToL8Bytes(this.Configuration, pixelsBlackWhiteRow, pixelAsGraySpan, width);
for (int x = 0; x < this.Image.Width; x++)

2
src/ImageSharp/Formats/Tiff/Writers/TiffCompositeColorWriter{TPixel}.cs

@ -31,7 +31,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Writers
this.rowBuffer.Clear();
Span<byte> outputRowSpan = this.rowBuffer.GetSpan().Slice(0, this.BytesPerRow * height);
Span<byte> outputRowSpan = this.rowBuffer.GetSpan()[..(this.BytesPerRow * height)];
int width = this.Image.Width;
using IMemoryOwner<TPixel> stripPixelBuffer = this.MemoryAllocator.Allocate<TPixel>(height * width);

6
src/ImageSharp/Formats/Tiff/Writers/TiffPaletteWriter{TPixel}.cs

@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Writers
}
}
compressor.CompressStrip(rows4bit.Slice(0, idx4bitRows), height);
compressor.CompressStrip(rows4bit[..idx4bitRows], height);
}
else
{
@ -99,7 +99,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Writers
indexedPixelsRowIdx++;
}
compressor.CompressStrip(indexedPixels.Slice(0, stripPixels), height);
compressor.CompressStrip(indexedPixels[..stripPixels], height);
}
}
@ -119,7 +119,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Writers
int quantizedColorBytes = quantizedColors.Length * 3 * 2;
// In the ColorMap, black is represented by 0, 0, 0 and white is represented by 65535, 65535, 65535.
Span<Rgb48> quantizedColorRgb48 = MemoryMarshal.Cast<byte, Rgb48>(colorPalette.Slice(0, quantizedColorBytes));
Span<Rgb48> quantizedColorRgb48 = MemoryMarshal.Cast<byte, Rgb48>(colorPalette[..quantizedColorBytes]);
PixelOperations<TPixel>.Instance.ToRgb48(this.Configuration, quantizedColors, quantizedColorRgb48);
// It can happen that the quantized colors are less than the expected maximum per channel.

2
src/ImageSharp/Formats/Webp/BitReader/BitReaderBase.cs

@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitReader
{
this.Data = memoryAllocator.Allocate<byte>(bytesToRead);
Span<byte> dataSpan = this.Data.Memory.Span;
input.Read(dataSpan.Slice(0, bytesToRead), 0, bytesToRead);
input.Read(dataSpan[..bytesToRead], 0, bytesToRead);
}
protected virtual void Dispose(bool disposing)

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

@ -258,9 +258,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter
BinaryPrimitives.WriteUInt32LittleEndian(buf, flags);
stream.Write(buf);
BinaryPrimitives.WriteUInt32LittleEndian(buf, width - 1);
stream.Write(buf.Slice(0, 3));
stream.Write(buf[..3]);
BinaryPrimitives.WriteUInt32LittleEndian(buf, height - 1);
stream.Write(buf.Slice(0, 3));
stream.Write(buf[..3]);
}
}
}

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

@ -215,7 +215,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter
{
if (this.PutBit(s >= 2, p[0]))
{
p = p.Slice(1);
p = p[1..];
}
this.PutBit(s & 1, p[1]);
@ -711,7 +711,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter
Span<byte> vp8ChunkHeader = stackalloc byte[WebpConstants.ChunkHeaderSize];
WebpConstants.Vp8MagicBytes.AsSpan().CopyTo(vp8ChunkHeader);
BinaryPrimitives.WriteUInt32LittleEndian(vp8ChunkHeader.Slice(4), size);
BinaryPrimitives.WriteUInt32LittleEndian(vp8ChunkHeader[4..], size);
stream.Write(vp8ChunkHeader);
}

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

@ -252,7 +252,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
BackwardReferencesHashChainDistanceOnly(xSize, ySize, memoryAllocator, bgra, cacheBits, hashChain, refsSrc, distArrayBuffer);
int chosenPathSize = TraceBackwards(distArray, distArraySize);
Span<ushort> chosenPath = distArray.Slice(distArraySize - chosenPathSize);
Span<ushort> chosenPath = distArray[(distArraySize - chosenPathSize)..];
BackwardReferencesHashChainFollowChosenPath(bgra, cacheBits, chosenPath, chosenPathSize, hashChain, refsDst);
}
@ -741,8 +741,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
while (i < pixelCount)
{
int maxLen = LosslessUtils.MaxFindCopyLength(pixelCount - i);
int rleLen = LosslessUtils.FindMatchLength(bgra.Slice(i), bgra.Slice(i - 1), 0, maxLen);
int prevRowLen = i < xSize ? 0 : LosslessUtils.FindMatchLength(bgra.Slice(i), bgra.Slice(i - xSize), 0, maxLen);
int rleLen = LosslessUtils.FindMatchLength(bgra[i..], bgra[(i - 1)..], 0, maxLen);
int prevRowLen = i < xSize ? 0 : LosslessUtils.FindMatchLength(bgra[i..], bgra[(i - xSize)..], 0, maxLen);
if (rleLen >= prevRowLen && rleLen >= MinLength)
{
refs.Add(PixOrCopy.CreateCopy(1, (ushort)rleLen));

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

@ -402,7 +402,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
BitsUsed = len,
Value = (uint)sorted[symbol++]
};
ReplicateValue(table.Slice(key), step, tableSize, huffmanCode);
ReplicateValue(table[key..], step, tableSize, huffmanCode);
key = GetNextKey(key, len);
}
@ -426,7 +426,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
{
if ((key & mask) != low)
{
tableSpan = tableSpan.Slice(tableSize);
tableSpan = tableSpan[tableSize..];
tablePos += tableSize;
tableBits = NextTableBitSize(counts, len, rootBits);
tableSize = 1 << tableBits;
@ -444,7 +444,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
BitsUsed = len - rootBits,
Value = (uint)sorted[symbol++]
};
ReplicateValue(tableSpan.Slice(key >> rootBits), step, tableSize, huffmanCode);
ReplicateValue(tableSpan[(key >> rootBits)..], step, tableSize, huffmanCode);
key = GetNextKey(key, len);
}
}
@ -576,8 +576,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
{
if (tree[0].PoolIndexLeft >= 0)
{
SetBitDepths(pool.Slice(tree[0].PoolIndexLeft), pool, bitDepths, level + 1);
SetBitDepths(pool.Slice(tree[0].PoolIndexRight), pool, bitDepths, level + 1);
SetBitDepths(pool[tree[0].PoolIndexLeft..], pool, bitDepths, level + 1);
SetBitDepths(pool[tree[0].PoolIndexRight..], pool, bitDepths, level + 1);
}
else
{

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

@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
Span<uint> prevRow = copyBuffer;
Span<uint> currRow = copyBuffer.Slice(xSize, xSize);
Span<uint> nextRow = copyBuffer.Slice(xSize * 2, xSize);
argbSrc.Slice(0, xSize).CopyTo(currRow);
argbSrc[..xSize].CopyTo(currRow);
argbSrc.Slice(xSize, xSize).CopyTo(nextRow);
int srcOffset = 0;

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

@ -230,8 +230,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
// to allow the top right pixel to point to the leftmost pixel of the next row
// when at the right edge.
Span<uint> upperRow = argbScratch;
Span<uint> currentRow = upperRow.Slice(width + 1);
Span<byte> maxDiffs = MemoryMarshal.Cast<uint, byte>(currentRow.Slice(width + 1));
Span<uint> currentRow = upperRow[(width + 1)..];
Span<byte> maxDiffs = MemoryMarshal.Cast<uint, byte>(currentRow[(width + 1)..]);
float bestDiff = MaxDiffCost;
int bestMode = 0;
uint[] residuals = new uint[1 << WebpConstants.MaxTransformBits];
@ -250,7 +250,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
// in all cases (wrapping to the leftmost pixel of the next row if it does
// not exist).
Span<uint> src = argb.Slice(((startY - 1) * width) + contextStartX, maxX + haveLeft + 1);
Span<uint> dst = currentRow.Slice(contextStartX);
Span<uint> dst = currentRow[contextStartX..];
src.CopyTo(dst);
}
@ -267,14 +267,14 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
// not exist in the currentRow).
int offset = (y * width) + contextStartX;
Span<uint> src = argb.Slice(offset, maxX + haveLeft + (y + 1 < height ? 1 : 0));
Span<uint> dst = currentRow.Slice(contextStartX);
Span<uint> dst = currentRow[contextStartX..];
src.CopyTo(dst);
if (nearLossless)
{
if (maxQuantization > 1 && y >= 1 && y + 1 < height)
{
MaxDiffsForRow(contextWidth, width, argb, offset, maxDiffs.Slice(contextStartX), usedSubtractGreen);
MaxDiffsForRow(contextWidth, width, argb, offset, maxDiffs[contextStartX..], usedSubtractGreen);
}
}
@ -589,10 +589,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
// to allow the top right pixel to point to the leftmost pixel of the next row
// when at the right edge.
Span<uint> upperRow = argbScratch;
Span<uint> currentRow = upperRow.Slice(width + 1);
Span<byte> currentMaxDiffs = MemoryMarshal.Cast<uint, byte>(currentRow.Slice(width + 1));
Span<uint> currentRow = upperRow[(width + 1)..];
Span<byte> currentMaxDiffs = MemoryMarshal.Cast<uint, byte>(currentRow[(width + 1)..]);
Span<byte> lowerMaxDiffs = currentMaxDiffs.Slice(width);
Span<byte> lowerMaxDiffs = currentMaxDiffs[width..];
Span<short> scratch = stackalloc short[8];
for (int y = 0; y < height; y++)
{
@ -604,7 +604,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
if (lowEffort)
{
PredictBatch(PredLowEffort, 0, y, width, currentRow, upperRow, argb.Slice(y * width), scratch);
PredictBatch(PredLowEffort, 0, y, width, currentRow, upperRow, argb[(y * width)..], scratch);
}
else
{
@ -645,7 +645,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
transparentColorMode,
usedSubtractGreen,
nearLossless,
argb.Slice((y * width) + x),
argb[((y * width) + x)..],
scratch);
x = xEnd;
@ -820,14 +820,14 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
{
int xScan = GetMin(maxTileSize, xSize - tileX);
int yScan = GetMin(maxTileSize, ySize - tileY);
argb = argb.Slice((tileY * xSize) + tileX);
argb = argb[((tileY * xSize) + tileX)..];
while (yScan-- > 0)
{
LosslessUtils.TransformColor(colorTransform, argb, xScan);
if (argb.Length > xSize)
{
argb = argb.Slice(xSize);
argb = argb[xSize..];
}
}
}
@ -853,7 +853,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
int allYMax = GetMin(tileYOffset + maxTileSize, ySize);
int tileWidth = allXMax - tileXOffset;
int tileHeight = allYMax - tileYOffset;
Span<uint> tileArgb = argb.Slice((tileYOffset * xSize) + tileXOffset);
Span<uint> tileArgb = argb[((tileYOffset * xSize) + tileXOffset)..];
var bestTx = default(Vp8LMultipliers);
@ -954,7 +954,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
int greenToRed,
int[] accumulatedRedHisto)
{
Span<int> histo = scratch.Slice(0, 256);
Span<int> histo = scratch[..256];
histo.Clear();
ColorSpaceTransformUtils.CollectColorRedTransforms(argb, stride, tileWidth, tileHeight, greenToRed, histo);
@ -992,7 +992,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
int redToBlue,
int[] accumulatedBlueHisto)
{
Span<int> histo = scratch.Slice(0, 256);
Span<int> histo = scratch[..256];
histo.Clear();
ColorSpaceTransformUtils.CollectColorBlueTransforms(argb, stride, tileWidth, tileHeight, greenToBlue, redToBlue, histo);

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

@ -1105,24 +1105,24 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
AddSingle(
pix,
histo.Slice((int)HistoIx.HistoAlpha * 256),
histo.Slice((int)HistoIx.HistoRed * 256),
histo.Slice((int)HistoIx.HistoGreen * 256),
histo.Slice((int)HistoIx.HistoBlue * 256));
histo[..],
histo[((int)HistoIx.HistoRed * 256)..],
histo[((int)HistoIx.HistoGreen * 256)..],
histo[((int)HistoIx.HistoBlue * 256)..]);
AddSingle(
pixDiff,
histo.Slice((int)HistoIx.HistoAlphaPred * 256),
histo.Slice((int)HistoIx.HistoRedPred * 256),
histo.Slice((int)HistoIx.HistoGreenPred * 256),
histo.Slice((int)HistoIx.HistoBluePred * 256));
histo[((int)HistoIx.HistoAlphaPred * 256)..],
histo[((int)HistoIx.HistoRedPred * 256)..],
histo[((int)HistoIx.HistoGreenPred * 256)..],
histo[((int)HistoIx.HistoBluePred * 256)..]);
AddSingleSubGreen(
pix,
histo.Slice((int)HistoIx.HistoRedSubGreen * 256),
histo.Slice((int)HistoIx.HistoBlueSubGreen * 256));
histo[((int)HistoIx.HistoRedSubGreen * 256)..],
histo[((int)HistoIx.HistoBlueSubGreen * 256)..]);
AddSingleSubGreen(
pixDiff,
histo.Slice((int)HistoIx.HistoRedPredSubGreen * 256),
histo.Slice((int)HistoIx.HistoBluePredSubGreen * 256));
histo[((int)HistoIx.HistoRedPredSubGreen * 256)..],
histo[((int)HistoIx.HistoBluePredSubGreen * 256)..]);
// Approximate the palette by the entropy of the multiplicative hash.
uint hash = HashPix(pix);
@ -1213,8 +1213,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
new[] { (byte)HistoIx.HistoRedPredSubGreen, (byte)HistoIx.HistoBluePredSubGreen },
new[] { (byte)HistoIx.HistoRed, (byte)HistoIx.HistoBlue }
};
Span<uint> redHisto = histo.Slice(256 * histoPairs[(int)minEntropyIx][0]);
Span<uint> blueHisto = histo.Slice(256 * histoPairs[(int)minEntropyIx][1]);
Span<uint> redHisto = histo[(256 * histoPairs[(int)minEntropyIx][0])..];
Span<uint> blueHisto = histo[(256 * histoPairs[(int)minEntropyIx][1])..];
for (int i = 1; i < 256; i++)
{
if ((redHisto[i] | blueHisto[i]) != 0)
@ -1245,14 +1245,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
return false;
}
#if NET5_0_OR_GREATER
var paletteSlice = palette.Slice(0, this.PaletteSize);
Span<uint> paletteSlice = palette[..this.PaletteSize];
paletteSlice.Sort();
#else
uint[] paletteArray = palette.Slice(0, this.PaletteSize).ToArray();
Array.Sort(paletteArray);
paletteArray.CopyTo(palette);
#endif
if (PaletteHasNonMonotonousDeltas(palette, this.PaletteSize))
{
@ -1352,8 +1346,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
}
BundleColorMap(tmpRow, width, xBits, dst);
src = src.Slice(srcStride);
dst = dst.Slice(dstStride);
src = src[srcStride..];
dst = dst[dstStride..];
}
}
else
@ -1449,8 +1443,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
LosslessUtils.BundleColorMap(tmpRow, width, xBits, dst);
src = src.Slice(srcStride);
dst = dst.Slice(dstStride);
src = src[srcStride..];
dst = dst[dstStride..];
}
}
@ -1474,8 +1468,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
LosslessUtils.BundleColorMap(tmpRow, width, xBits, dst);
src = src.Slice(srcStride);
dst = dst.Slice(dstStride);
src = src[srcStride..];
dst = dst[dstStride..];
}
}
@ -1484,7 +1478,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
/// </summary>
private static void PrepareMapToPalette(Span<uint> palette, int numColors, uint[] sorted, uint[] idxMap)
{
palette.Slice(0, numColors).CopyTo(sorted);
palette[..numColors].CopyTo(sorted);
Array.Sort(sorted, PaletteCompareColorsForSort);
for (int i = 0; i < numColors; i++)
{

14
src/ImageSharp/Formats/Webp/Lossless/Vp8LHashChain.cs

@ -125,7 +125,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
else
{
// Just move one pixel forward.
hashCode = GetPixPairHash64(bgra.Slice(pos));
hashCode = GetPixPairHash64(bgra[pos..]);
chain[pos] = hashToFirstIndex[(int)hashCode];
hashToFirstIndex[(int)hashCode] = pos++;
bgraComp = bgraCompNext;
@ -133,7 +133,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
}
// Process the penultimate pixel.
chain[pos] = hashToFirstIndex[(int)GetPixPairHash64(bgra.Slice(pos))];
chain[pos] = hashToFirstIndex[(int)GetPixPairHash64(bgra[pos..])];
// Find the best match interval at each pixel, defined by an offset to the
// pixel and a length. The right-most pixel cannot match anything to the right
@ -157,7 +157,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
// Heuristic: use the comparison with the above line as an initialization.
if (basePosition >= (uint)xSize)
{
currLength = LosslessUtils.FindMatchLength(bgra.Slice(bgraStart - xSize), bgra.Slice(bgraStart), bestLength, maxLen);
currLength = LosslessUtils.FindMatchLength(bgra[(bgraStart - xSize)..], bgra[bgraStart..], bestLength, maxLen);
if (currLength > bestLength)
{
bestLength = currLength;
@ -168,7 +168,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
}
// Heuristic: compare to the previous pixel.
currLength = LosslessUtils.FindMatchLength(bgra.Slice(bgraStart - 1), bgra.Slice(bgraStart), bestLength, maxLen);
currLength = LosslessUtils.FindMatchLength(bgra[(bgraStart - 1)..], bgra[bgraStart..], bestLength, maxLen);
if (currLength > bestLength)
{
bestLength = currLength;
@ -184,7 +184,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
}
}
uint bestBgra = bgra.Slice(bgraStart)[bestLength];
uint bestBgra = bgra[bgraStart..][bestLength];
for (; pos >= minPos && (--iter > 0); pos = chain[pos])
{
@ -193,12 +193,12 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
continue;
}
currLength = LosslessUtils.VectorMismatch(bgra.Slice(pos), bgra.Slice(bgraStart), maxLen);
currLength = LosslessUtils.VectorMismatch(bgra[pos..], bgra[bgraStart..], maxLen);
if (bestLength < currLength)
{
bestLength = currLength;
bestDistance = (uint)(basePosition - pos);
bestBgra = bgra.Slice(bgraStart)[bestLength];
bestBgra = bgra[bgraStart..][bestLength];
// Stop if we have reached a good enough length.
if (bestLength >= lengthMax)

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

@ -199,8 +199,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
Span<TPixel> pixelRow = pixels.DangerousGetRowSpan(y);
PixelOperations<TPixel>.Instance.FromBgra32Bytes(
this.configuration,
rowAsBytes.Slice(0, bytesPerRow),
pixelRow.Slice(0, width),
rowAsBytes[..bytesPerRow],
pixelRow[..width],
width);
}
}
@ -441,7 +441,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
}
// TODO: Avoid allocation.
hTreeGroup.HTrees.Add(huffmanTable.Slice(0, size).ToArray());
hTreeGroup.HTrees.Add(huffmanTable[..size].ToArray());
HuffmanCode huffTableZero = huffmanTable[0];
if (isTrivialLiteral && LiteralMap[j] == 1)
@ -450,7 +450,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
}
totalSize += huffTableZero.BitsUsed;
huffmanTable = huffmanTable.Slice(size);
huffmanTable = huffmanTable[size..];
if (j <= HuffIndex.Alpha)
{
@ -862,14 +862,14 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
private uint ReadSymbol(Span<HuffmanCode> table)
{
uint val = (uint)this.bitReader.PrefetchBits();
Span<HuffmanCode> tableSpan = table.Slice((int)(val & HuffmanUtils.HuffmanTableMask));
Span<HuffmanCode> tableSpan = table[(int)(val & HuffmanUtils.HuffmanTableMask)..];
int nBits = tableSpan[0].BitsUsed - HuffmanUtils.HuffmanTableBits;
if (nBits > 0)
{
this.bitReader.AdvanceBitPosition(HuffmanUtils.HuffmanTableBits);
val = (uint)this.bitReader.PrefetchBits();
tableSpan = tableSpan.Slice((int)tableSpan[0].Value);
tableSpan = tableSpan.Slice((int)val & ((1 << nBits) - 1));
tableSpan = tableSpan[(int)tableSpan[0].Value..];
tableSpan = tableSpan[((int)val & ((1 << nBits) - 1))..];
}
this.bitReader.AdvanceBitPosition(tableSpan[0].BitsUsed);
@ -949,14 +949,14 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
{
// no overlap.
Span<uint> src = pixelData.Slice(start, length);
Span<uint> dest = pixelData.Slice(decodedPixels);
Span<uint> dest = pixelData[decodedPixels..];
src.CopyTo(dest);
}
else
{
// There is overlap between the backward reference distance and the pixels to copy.
Span<uint> src = pixelData.Slice(start);
Span<uint> dest = pixelData.Slice(decodedPixels);
Span<uint> src = pixelData[start..];
Span<uint> dest = pixelData[decodedPixels..];
for (int i = 0; i < length; i++)
{
dest[i] = src[i];
@ -977,12 +977,12 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
if (dist >= length)
{
// no overlap.
data.Slice(pos - dist, length).CopyTo(data.Slice(pos));
data.Slice(pos - dist, length).CopyTo(data[pos..]);
}
else
{
Span<byte> dst = data.Slice(pos);
Span<byte> src = data.Slice(pos - dist);
Span<byte> dst = data[pos..];
Span<byte> src = data[(pos - dist)..];
for (int i = 0; i < length; i++)
{
dst[i] = src[i];

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

@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
Span<short> tmpLevels = new short[16];
do
{
int numBlocks = 1;
const int numBlocks = 1;
rdi4.Clear();
int mode;
int bestMode = -1;

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

@ -288,9 +288,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
{
int yStartIdx = ((this.Y * yStride) + this.X) * 16;
int uvStartIdx = ((this.Y * uvStride) + this.X) * 8;
Span<byte> ySrc = y.Slice(yStartIdx);
Span<byte> uSrc = u.Slice(uvStartIdx);
Span<byte> vSrc = v.Slice(uvStartIdx);
Span<byte> ySrc = y[yStartIdx..];
Span<byte> uSrc = u[uvStartIdx..];
Span<byte> vSrc = v[uvStartIdx..];
int w = Math.Min(width - (this.X * 16), 16);
int h = Math.Min(height - (this.Y * 16), 16);
int uvw = (w + 1) >> 1;
@ -331,9 +331,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
vLeft[0] = v[uvStartIdx - 1 - uvStride];
}
this.ImportLine(y.Slice(yStartIdx - 1), yStride, yLeft.Slice(1), h, 16);
this.ImportLine(u.Slice(uvStartIdx - 1), uvStride, uLeft.Slice(1), uvh, 8);
this.ImportLine(v.Slice(uvStartIdx - 1), uvStride, vLeft.Slice(1), uvh, 8);
this.ImportLine(y[(yStartIdx - 1)..], yStride, yLeft[1..], h, 16);
this.ImportLine(u[(uvStartIdx - 1)..], uvStride, uLeft[1..], uvh, 8);
this.ImportLine(v[(uvStartIdx - 1)..], uvStride, vLeft[1..], uvh, 8);
}
Span<byte> yTop = this.YTop.AsSpan(this.yTopIdx, 16);
@ -344,9 +344,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
}
else
{
this.ImportLine(y.Slice(yStartIdx - yStride), 1, yTop, w, 16);
this.ImportLine(u.Slice(uvStartIdx - uvStride), 1, this.UvTop.AsSpan(this.uvTopIdx, 8), uvw, 8);
this.ImportLine(v.Slice(uvStartIdx - uvStride), 1, this.UvTop.AsSpan(this.uvTopIdx + 8, 8), uvw, 8);
this.ImportLine(y[(yStartIdx - yStride)..], 1, yTop, w, 16);
this.ImportLine(u[(uvStartIdx - uvStride)..], 1, this.UvTop.AsSpan(this.uvTopIdx, 8), uvw, 8);
this.ImportLine(v[(uvStartIdx - uvStride)..], 1, this.UvTop.AsSpan(this.uvTopIdx + 8, 8), uvw, 8);
}
}
@ -490,8 +490,8 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
Span<byte> preds = this.Preds.AsSpan(this.predIdx);
for (int y = 0; y < 4; y++)
{
preds.Slice(0, 4).Fill((byte)mode);
preds = preds.Slice(this.predsWidth);
preds[..4].Fill((byte)mode);
preds = preds[this.predsWidth..];
}
this.CurrentMacroBlockInfo.MacroBlockType = Vp8MacroBlockType.I16X16;
@ -679,7 +679,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
public bool RotateI4(Span<byte> yuvOut)
{
Span<byte> blk = yuvOut.Slice(WebpLookupTables.Vp8Scan[this.I4]);
Span<byte> blk = yuvOut[WebpLookupTables.Vp8Scan[this.I4]..];
Span<byte> top = this.I4Boundary.AsSpan();
int topOffset = this.I4BoundaryIdx;
int i;
@ -830,7 +830,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
for (int i = 0; i < h; i++)
{
// memcpy(dst, src, w);
src.Slice(srcIdx, w).CopyTo(dst.Slice(dstIdx));
src.Slice(srcIdx, w).CopyTo(dst[dstIdx..]);
if (w < size)
{
// memset(dst + w, dst[w - 1], size - w);
@ -844,7 +844,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
for (int i = h; i < size; i++)
{
// memcpy(dst, dst - BPS, size);
dst.Slice(dstIdx - WebpConstants.Bps, size).CopyTo(dst.Slice(dstIdx));
dst.Slice(dstIdx - WebpConstants.Bps, size).CopyTo(dst[dstIdx..]);
dstIdx += WebpConstants.Bps;
}
}

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

@ -382,7 +382,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
(uint)width,
(uint)height,
hasAlpha,
alphaData.Slice(0, alphaDataSize),
alphaData[..alphaDataSize],
this.alphaCompression && alphaCompressionSucceeded);
}

72
src/ImageSharp/Formats/Webp/Lossy/WebpLossyDecoder.cs

@ -252,7 +252,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
}
top.CopyTo(modes);
modes = modes.Slice(4);
modes = modes[4..];
left[y] = (byte)yMode;
}
}
@ -290,9 +290,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
const int vOff = uOff + 16;
Span<byte> yuv = dec.YuvBuffer.Memory.Span;
Span<byte> yDst = yuv.Slice(yOff);
Span<byte> uDst = yuv.Slice(uOff);
Span<byte> vDst = yuv.Slice(vOff);
Span<byte> yDst = yuv[yOff..];
Span<byte> uDst = yuv[uOff..];
Span<byte> vDst = yuv[vOff..];
// Initialize left-most block.
int end = 16 * WebpConstants.Bps;
@ -349,17 +349,17 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
{
int srcIdx = (i * WebpConstants.Bps) + 12 + yOff;
int dstIdx = (i * WebpConstants.Bps) - 4 + yOff;
yuv.Slice(srcIdx, 4).CopyTo(yuv.Slice(dstIdx));
yuv.Slice(srcIdx, 4).CopyTo(yuv[dstIdx..]);
}
for (int i = -1; i < 8; i++)
{
int srcIdx = (i * WebpConstants.Bps) + 4 + uOff;
int dstIdx = (i * WebpConstants.Bps) - 4 + uOff;
yuv.Slice(srcIdx, 4).CopyTo(yuv.Slice(dstIdx));
yuv.Slice(srcIdx, 4).CopyTo(yuv[dstIdx..]);
srcIdx = (i * WebpConstants.Bps) + 4 + vOff;
dstIdx = (i * WebpConstants.Bps) - 4 + vOff;
yuv.Slice(srcIdx, 4).CopyTo(yuv.Slice(dstIdx));
yuv.Slice(srcIdx, 4).CopyTo(yuv[dstIdx..]);
}
}
@ -369,15 +369,15 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
uint bits = block.NonZeroY;
if (mby > 0)
{
topYuv.Y.CopyTo(yuv.Slice(yOff - WebpConstants.Bps));
topYuv.U.CopyTo(yuv.Slice(uOff - WebpConstants.Bps));
topYuv.V.CopyTo(yuv.Slice(vOff - WebpConstants.Bps));
topYuv.Y.CopyTo(yuv[(yOff - WebpConstants.Bps)..]);
topYuv.U.CopyTo(yuv[(uOff - WebpConstants.Bps)..]);
topYuv.V.CopyTo(yuv[(vOff - WebpConstants.Bps)..]);
}
// Predict and add residuals.
if (block.IsI4x4)
{
Span<byte> topRight = yuv.Slice(yOff - WebpConstants.Bps + 16);
Span<byte> topRight = yuv[(yOff - WebpConstants.Bps + 16)..];
if (mby > 0)
{
if (mbx >= dec.MbWidth - 1)
@ -396,14 +396,14 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
}
// Replicate the top-right pixels below.
Span<uint> topRightUint = MemoryMarshal.Cast<byte, uint>(yuv.Slice(yOff - WebpConstants.Bps + 16));
Span<uint> topRightUint = MemoryMarshal.Cast<byte, uint>(yuv[(yOff - WebpConstants.Bps + 16)..]);
topRightUint[WebpConstants.Bps] = topRightUint[2 * WebpConstants.Bps] = topRightUint[3 * WebpConstants.Bps] = topRightUint[0];
// Predict and add residuals for all 4x4 blocks in turn.
for (int n = 0; n < 16; ++n, bits <<= 2)
{
int offset = yOff + WebpConstants.Scan[n];
Span<byte> dst = yuv.Slice(offset);
Span<byte> dst = yuv[offset..];
byte lumaMode = block.Modes[n];
switch (lumaMode)
{
@ -475,7 +475,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
{
for (int n = 0; n < 16; ++n, bits <<= 2)
{
this.DoTransform(bits, coeffs.AsSpan(n * 16), yDst.Slice(WebpConstants.Scan[n]), this.scratch);
this.DoTransform(bits, coeffs.AsSpan(n * 16), yDst[WebpConstants.Scan[n]..], this.scratch);
}
}
}
@ -527,19 +527,19 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
}
// Transfer reconstructed samples from yuv_buffer cache to final destination.
Span<byte> yOut = dec.CacheY.Memory.Span.Slice(dec.CacheYOffset + (mbx * 16));
Span<byte> uOut = dec.CacheU.Memory.Span.Slice(dec.CacheUvOffset + (mbx * 8));
Span<byte> vOut = dec.CacheV.Memory.Span.Slice(dec.CacheUvOffset + (mbx * 8));
Span<byte> yOut = dec.CacheY.Memory.Span[(dec.CacheYOffset + (mbx * 16))..];
Span<byte> uOut = dec.CacheU.Memory.Span[(dec.CacheUvOffset + (mbx * 8))..];
Span<byte> vOut = dec.CacheV.Memory.Span[(dec.CacheUvOffset + (mbx * 8))..];
for (int j = 0; j < 16; j++)
{
yDst.Slice(j * WebpConstants.Bps, Math.Min(16, yOut.Length)).CopyTo(yOut.Slice(j * dec.CacheYStride));
yDst.Slice(j * WebpConstants.Bps, Math.Min(16, yOut.Length)).CopyTo(yOut[(j * dec.CacheYStride)..]);
}
for (int j = 0; j < 8; j++)
{
int jUvStride = j * dec.CacheUvStride;
uDst.Slice(j * WebpConstants.Bps, Math.Min(8, uOut.Length)).CopyTo(uOut.Slice(jUvStride));
vDst.Slice(j * WebpConstants.Bps, Math.Min(8, vOut.Length)).CopyTo(vOut.Slice(jUvStride));
uDst.Slice(j * WebpConstants.Bps, Math.Min(8, uOut.Length)).CopyTo(uOut[jUvStride..]);
vDst.Slice(j * WebpConstants.Bps, Math.Min(8, vOut.Length)).CopyTo(vOut[jUvStride..]);
}
}
}
@ -649,9 +649,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
}
else
{
io.Y = dec.CacheY.Memory.Span.Slice(dec.CacheYOffset);
io.U = dec.CacheU.Memory.Span.Slice(dec.CacheUvOffset);
io.V = dec.CacheV.Memory.Span.Slice(dec.CacheUvOffset);
io.Y = dec.CacheY.Memory.Span[dec.CacheYOffset..];
io.U = dec.CacheU.Memory.Span[dec.CacheUvOffset..];
io.V = dec.CacheV.Memory.Span[dec.CacheUvOffset..];
}
if (!isLastRow)
@ -696,7 +696,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
int bpp = 3;
int bufferStride = bpp * io.Width;
int dstStartIdx = io.MbY * bufferStride;
Span<byte> dst = buf.Slice(dstStartIdx);
Span<byte> dst = buf[dstStartIdx..];
int yEnd = io.MbY + io.MbH;
int mbw = io.MbW;
int uvw = (mbw + 1) / 2;
@ -711,7 +711,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
else
{
// We can finish the left-over line from previous call.
YuvConversion.UpSample(tmpYBuffer, curY, topU, topV, curU, curV, buf.Slice(dstStartIdx - bufferStride), dst, mbw, uvBuffer);
YuvConversion.UpSample(tmpYBuffer, curY, topU, topV, curU, curV, buf[(dstStartIdx - bufferStride)..], dst, mbw, uvBuffer);
numLinesOut++;
}
@ -722,21 +722,21 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
{
topU = curU;
topV = curV;
curU = curU.Slice(io.UvStride);
curV = curV.Slice(io.UvStride);
YuvConversion.UpSample(curY.Slice(io.YStride), curY.Slice(ioStride2), topU, topV, curU, curV, dst.Slice(bufferStride), dst.Slice(bufferStride2), mbw, uvBuffer);
curY = curY.Slice(ioStride2);
dst = dst.Slice(bufferStride2);
curU = curU[io.UvStride..];
curV = curV[io.UvStride..];
YuvConversion.UpSample(curY[io.YStride..], curY[ioStride2..], topU, topV, curU, curV, dst[bufferStride..], dst[bufferStride2..], mbw, uvBuffer);
curY = curY[ioStride2..];
dst = dst[bufferStride2..];
}
// Move to last row.
curY = curY.Slice(io.YStride);
curY = curY[io.YStride..];
if (yEnd < io.Height)
{
// Save the unfinished samples for next call (as we're not done yet).
curY.Slice(0, mbw).CopyTo(tmpYBuffer);
curU.Slice(0, uvw).CopyTo(tmpUBuffer);
curV.Slice(0, uvw).CopyTo(tmpVBuffer);
curY[..mbw].CopyTo(tmpYBuffer);
curU[..uvw].CopyTo(tmpUBuffer);
curV[..uvw].CopyTo(tmpVBuffer);
// The upsampler leaves a row unfinished behind (except for the very last row).
numLinesOut--;
@ -746,7 +746,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
// Process the very last row of even-sized picture.
if ((yEnd & 1) == 0)
{
YuvConversion.UpSample(curY, default, curU, curV, curU, curV, dst.Slice(bufferStride), default, mbw, uvBuffer);
YuvConversion.UpSample(curY, default, curU, curV, curU, curV, dst[bufferStride..], default, mbw, uvBuffer);
}
}
@ -1149,7 +1149,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
dec.Vp8BitReaders[p] = new Vp8BitReader(this.bitReader.Data, (uint)pSize, partStart);
partStart += pSize;
sizeLeft -= pSize;
sz = sz.Slice(3);
sz = sz[3..];
}
dec.Vp8BitReaders[lastPart] = new Vp8BitReader(this.bitReader.Data, (uint)sizeLeft, partStart);

4
src/ImageSharp/Formats/Webp/WebpAnimationDecoder.cs

@ -294,8 +294,8 @@ namespace SixLabors.ImageSharp.Formats.Webp
for (int y = frameY; y < frameY + frameHeight; y++)
{
Span<TPixel> framePixelRow = imageFramePixels.DangerousGetRowSpan(y);
Span<TPixel> decodedPixelRow = decodedImage.DangerousGetRowSpan(decodedRowIdx++).Slice(0, frameWidth);
decodedPixelRow.TryCopyTo(framePixelRow.Slice(frameX));
Span<TPixel> decodedPixelRow = decodedImage.DangerousGetRowSpan(decodedRowIdx++)[..frameWidth];
decodedPixelRow.TryCopyTo(framePixelRow[frameX..]);
}
}

2
src/ImageSharp/Formats/Webp/WebpImageFormatDetector.cs

@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp.Formats.Webp
/// </summary>
/// <param name="header">The header bytes.</param>
/// <returns>True, if its a valid RIFF FourCC.</returns>
private bool IsRiffContainer(ReadOnlySpan<byte> header) => header.Slice(0, 4).SequenceEqual(WebpConstants.RiffFourCc);
private bool IsRiffContainer(ReadOnlySpan<byte> header) => header[..4].SequenceEqual(WebpConstants.RiffFourCc);
/// <summary>
/// Checks if 'WEBP' is present in the header.

4
src/ImageSharp/IO/ChunkedMemoryStream.cs

@ -286,7 +286,7 @@ namespace SixLabors.ImageSharp.IO
}
int readCount = Math.Min(count, chunkSize - this.readOffset);
chunkBuffer.Slice(this.readOffset, readCount).CopyTo(buffer.Slice(offset));
chunkBuffer.Slice(this.readOffset, readCount).CopyTo(buffer[offset..]);
offset += readCount;
count -= readCount;
this.readOffset += readCount;
@ -382,7 +382,7 @@ namespace SixLabors.ImageSharp.IO
}
int copyCount = Math.Min(count, chunkSize - this.writeOffset);
buffer.Slice(offset, copyCount).CopyTo(chunkBuffer.Slice(this.writeOffset));
buffer.Slice(offset, copyCount).CopyTo(chunkBuffer[this.writeOffset..]);
offset += copyCount;
count -= copyCount;

2
src/ImageSharp/Image.LoadPixelData.cs

@ -130,7 +130,7 @@ namespace SixLabors.ImageSharp
Guard.MustBeGreaterThanOrEqualTo(data.Length, count, nameof(data));
var image = new Image<TPixel>(configuration, width, height);
data = data.Slice(0, count);
data = data[..count];
data.CopyTo(image.Frames.RootFrame.PixelBuffer.FastMemoryGroup);
return image;

2
src/ImageSharp/ImageFrame.LoadPixelData.cs

@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp
var image = new ImageFrame<TPixel>(configuration, width, height);
data = data.Slice(0, count);
data = data[..count];
data.CopyTo(image.PixelBuffer.FastMemoryGroup);
return image;

2
src/ImageSharp/IndexedImageFrame{TPixel}.cs

@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp
// Copy the palette over. We want the lifetime of this frame to be independant of any palette source.
this.paletteOwner = configuration.MemoryAllocator.Allocate<TPixel>(palette.Length);
palette.Span.CopyTo(this.paletteOwner.GetSpan());
this.Palette = this.paletteOwner.Memory.Slice(0, palette.Length);
this.Palette = this.paletteOwner.Memory[..palette.Length];
}
/// <summary>

24
src/ImageSharp/Memory/Allocators/Internals/Gen2GcCallback.cs

@ -1,9 +1,8 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
// Port of BCL internal utility:
// https://github.com/dotnet/runtime/blob/57bfe474518ab5b7cfe6bf7424a79ce3af9d6657/src/libraries/System.Private.CoreLib/src/System/Gen2GcCallback.cs
#if NETCOREAPP3_1_OR_GREATER
using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
@ -20,10 +19,7 @@ namespace SixLabors.ImageSharp.Memory.Internals
private readonly Func<object, bool> callback1;
private GCHandle weakTargetObj;
private Gen2GcCallback(Func<bool> callback)
{
this.callback0 = callback;
}
private Gen2GcCallback(Func<bool> callback) => this.callback0 = callback;
private Gen2GcCallback(Func<object, bool> callback, object targetObj)
{
@ -92,24 +88,24 @@ namespace SixLabors.ImageSharp.Memory.Internals
/// Schedule 'callback' to be called in the next GC. If the callback returns true it is
/// rescheduled for the next Gen 2 GC. Otherwise the callbacks stop.
/// </summary>
public static void Register(Func<bool> callback)
{
public static void Register(Func<bool> callback) =>
// Create a unreachable object that remembers the callback function and target object.
_ = new Gen2GcCallback(callback);
}
/// <summary>
/// <para>
/// Schedule 'callback' to be called in the next GC. If the callback returns true it is
/// rescheduled for the next Gen 2 GC. Otherwise the callbacks stop.
///
/// </para>
/// <para>
/// NOTE: This callback will be kept alive until either the callback function returns false,
/// or the target object dies.
/// </para>
/// </summary>
public static void Register(Func<object, bool> callback, object targetObj)
{
public static void Register(Func<object, bool> callback, object targetObj) =>
// Create a unreachable object that remembers the callback function and target object.
_ = new Gen2GcCallback(callback, targetObj);
}
}
}
#endif

10
src/ImageSharp/Memory/Allocators/Internals/UniformUnmanagedMemoryPool.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System;
@ -40,9 +40,7 @@ namespace SixLabors.ImageSharp.Memory.Internals
if (trimSettings.Enabled)
{
UpdateTimer(trimSettings, this);
#if NETCOREAPP3_1_OR_GREATER
Gen2GcCallback.Register(s => ((UniformUnmanagedMemoryPool)s).Trim(), this);
#endif
this.lastTrimTimestamp = Stopwatch.ElapsedMilliseconds;
}
}
@ -326,14 +324,8 @@ namespace SixLabors.ImageSharp.Memory.Internals
private bool IsHighMemoryPressure()
{
#if NETCOREAPP3_1_OR_GREATER
GCMemoryInfo memoryInfo = GC.GetGCMemoryInfo();
return memoryInfo.MemoryLoadBytes >= memoryInfo.HighMemoryLoadThresholdBytes * this.trimSettings.HighPressureThresholdRate;
#else
// We don't have high pressure detection triggering full trimming on other platforms,
// to counterpart this, the maximum pool size is small.
return false;
#endif
}
public class TrimSettings

10
src/ImageSharp/Memory/Allocators/UniformUnmanagedMemoryPoolMemoryAllocator.cs

@ -4,7 +4,6 @@
using System;
using System.Buffers;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory.Internals;
namespace SixLabors.ImageSharp.Memory
@ -73,11 +72,9 @@ namespace SixLabors.ImageSharp.Memory
this.nonPoolAllocator = new UnmanagedMemoryAllocator(unmanagedBufferSizeInBytes);
}
#if NETCOREAPP3_1_OR_GREATER
// This delegate allows overriding the method returning the available system memory,
// so we can test our workaround for https://github.com/dotnet/runtime/issues/65466
internal static Func<long> GetTotalAvailableMemoryBytes { get; set; } = () => GC.GetGCMemoryInfo().TotalAvailableMemoryBytes;
#endif
/// <inheritdoc />
protected internal override int GetBufferCapacityInBytes() => this.poolBufferSizeInBytes;
@ -151,11 +148,9 @@ namespace SixLabors.ImageSharp.Memory
private static long GetDefaultMaxPoolSizeBytes()
{
#if NETCOREAPP3_1_OR_GREATER
// On 64 bit .NET Core 3.1+, set the pool size to a portion of the total available memory.
// There is a bug in GC.GetGCMemoryInfo() on .NET 5 + 32 bit, making TotalAvailableMemoryBytes unreliable:
// On 64 bit set the pool size to a portion of the total available memory.
// https://github.com/dotnet/runtime/issues/55126#issuecomment-876779327
if (Environment.Is64BitProcess || !RuntimeInformation.FrameworkDescription.StartsWith(".NET 5.0"))
if (Environment.Is64BitProcess)
{
long total = GetTotalAvailableMemoryBytes();
@ -165,7 +160,6 @@ namespace SixLabors.ImageSharp.Memory
return total / 8;
}
}
#endif
// Stick to a conservative value of 128 Megabytes on other platforms and 32 bit .NET 5.0:
return 128 * OneMegabyte;

2
src/ImageSharp/Memory/Buffer2D{T}.cs

@ -120,7 +120,7 @@ namespace SixLabors.ImageSharp.Memory
return false;
}
paddedSpan = slice.Slice(0, stride);
paddedSpan = slice[..stride];
return true;
}

2
src/ImageSharp/Memory/ByteMemoryManager{T}.cs

@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Memory
// We need to adjust the offset into the wrapped byte segment,
// as the input index refers to the target-cast memory of T.
// We just have to shift this index by the byte size of T.
return this.memory.Slice(elementIndex * Unsafe.SizeOf<T>()).Pin();
return this.memory[(elementIndex * Unsafe.SizeOf<T>())..].Pin();
}
/// <inheritdoc/>

6
src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupExtensions.cs

@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.Memory
cur.GetSpan(fwd).CopyTo(target);
cur.Forward(fwd);
target = target.Slice(fwd);
target = target[fwd..];
position += fwd;
}
}
@ -102,9 +102,9 @@ namespace SixLabors.ImageSharp.Memory
while (!source.IsEmpty)
{
int fwd = Math.Min(cur.LookAhead(), source.Length);
source.Slice(0, fwd).CopyTo(cur.GetSpan(fwd));
source[..fwd].CopyTo(cur.GetSpan(fwd));
cur.Forward(fwd);
source = source.Slice(fwd);
source = source[fwd..];
}
}

2
src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs

@ -285,7 +285,7 @@ namespace SixLabors.ImageSharp.Memory
{
long bufferIdx = Math.DivRem(start, this.BufferLength, out long bufferStart);
Memory<T> memory = this[(int)bufferIdx];
return memory.Span.Slice((int)bufferStart);
return memory.Span[(int)bufferStart..];
}
public static bool CanSwapContent(MemoryGroup<T> target, MemoryGroup<T> source) =>

2
src/ImageSharp/Memory/MemoryOwnerExtensions.cs

@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp.Memory
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Span<T> Slice<T>(this IMemoryOwner<T> buffer, int start)
{
return buffer.GetSpan().Slice(start);
return buffer.GetSpan()[start..];
}
/// <summary>

21
src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs

@ -57,7 +57,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
{
if (TryDetect(buffer, out CharacterCode code))
{
string text = GetEncoding(code).GetString(buffer.Slice(CharacterCodeBytesLength));
string text = GetEncoding(code).GetString(buffer[CharacterCodeBytesLength..]);
encodedString = new EncodedString(code, text);
return true;
}
@ -74,30 +74,13 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
GetCodeBytes(encodedString.Code).CopyTo(destination);
string text = encodedString.Text;
int count = Write(GetEncoding(encodedString.Code), text, destination.Slice(CharacterCodeBytesLength));
int count = Write(GetEncoding(encodedString.Code), text, destination[CharacterCodeBytesLength..]);
return CharacterCodeBytesLength + count;
}
public static unsafe int Write(Encoding encoding, string value, Span<byte> destination)
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER || NET
=> encoding.GetBytes(value.AsSpan(), destination);
#else
{
if (value.Length == 0)
{
return 0;
}
fixed (char* c = value)
{
fixed (byte* b = destination)
{
return encoding.GetBytes(c, value.Length, b, destination.Length);
}
}
}
#endif
private static bool TryDetect(ReadOnlySpan<byte> buffer, out CharacterCode code)
{

51
src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs

@ -150,7 +150,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
foreach ((ulong Offset, ExifDataType DataType, ulong NumberOfComponents, ExifValue Exif) tag in this.BigValues)
{
ulong size = tag.NumberOfComponents * ExifDataTypes.GetSize(tag.DataType);
this.ReadBigValue(values, tag, buf.Slice(0, (int)size));
this.ReadBigValue(values, tag, buf[..(int)size]);
}
}
else
@ -160,7 +160,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
foreach ((ulong Offset, ExifDataType DataType, ulong NumberOfComponents, ExifValue Exif) tag in this.BigValues)
{
ulong size = tag.NumberOfComponents * ExifDataTypes.GetSize(tag.DataType);
this.ReadBigValue(values, tag, buf.Slice(0, (int)size));
this.ReadBigValue(values, tag, buf[..(int)size]);
}
}
@ -247,13 +247,13 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
if (nullCharIndex > -1)
{
buffer = buffer.Slice(0, nullCharIndex);
buffer = buffer[..nullCharIndex];
}
return encoding.GetString(buffer);
}
private byte ConvertToByte(ReadOnlySpan<byte> buffer) => buffer[0];
private static byte ConvertToByte(ReadOnlySpan<byte> buffer) => buffer[0];
private object ConvertValue(ExifDataType dataType, ReadOnlySpan<byte> buffer, bool isArray)
{
@ -272,7 +272,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
case ExifDataType.Undefined:
if (!isArray)
{
return this.ConvertToByte(buffer);
return ConvertToByte(buffer);
}
return buffer.ToArray();
@ -414,7 +414,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
}
else
{
object value = this.ConvertValue(dataType, offsetBuffer.Slice(0, (int)size), numberOfComponents > 1 || exifValue.IsArray);
object value = this.ConvertValue(dataType, offsetBuffer[..(int)size], numberOfComponents > 1 || exifValue.IsArray);
this.Add(values, exifValue, value);
}
}
@ -443,31 +443,14 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
numberOfComponents = 8 / ExifDataTypes.GetSize(dataType);
}
// The StripOffsets, StripByteCounts, TileOffsets, and TileByteCounts tags are allowed to have the datatype TIFF_LONG8 in BigTIFF.
// Old datatypes TIFF_LONG, and TIFF_SHORT where allowed in the TIFF 6.0 specification, are still valid in BigTIFF, too.
// Likewise, tags that point to other IFDs, like e.g. the SubIFDs tag, are now allowed to have the datatype TIFF_IFD8 in BigTIFF.
// Again, the old datatypes TIFF_IFD, and the hardly recommendable TIFF_LONG, are still valid, too.
// https://www.awaresystems.be/imaging/tiff/bigtiff.html
ExifValue exifValue;
switch (tag)
{
case ExifTagValue.StripOffsets:
exifValue = new ExifLong8Array(ExifTagValue.StripOffsets);
break;
case ExifTagValue.StripByteCounts:
exifValue = new ExifLong8Array(ExifTagValue.StripByteCounts);
break;
case ExifTagValue.TileOffsets:
exifValue = new ExifLong8Array(ExifTagValue.TileOffsets);
break;
case ExifTagValue.TileByteCounts:
exifValue = new ExifLong8Array(ExifTagValue.TileByteCounts);
break;
default:
exifValue = ExifValues.Create(tag) ?? ExifValues.Create(tag, dataType, numberOfComponents);
break;
}
ExifValue exifValue = tag switch
{
ExifTagValue.StripOffsets => new ExifLong8Array(ExifTagValue.StripOffsets),
ExifTagValue.StripByteCounts => new ExifLong8Array(ExifTagValue.StripByteCounts),
ExifTagValue.TileOffsets => new ExifLong8Array(ExifTagValue.TileOffsets),
ExifTagValue.TileByteCounts => new ExifLong8Array(ExifTagValue.TileByteCounts),
_ => ExifValues.Create(tag) ?? ExifValues.Create(tag, dataType, numberOfComponents),
};
if (exifValue is null)
{
this.AddInvalidTag(new UnkownExifTag(tag));
@ -488,7 +471,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
}
else
{
object value = this.ConvertValue(dataType, offsetBuffer.Slice(0, (int)size), numberOfComponents > 1 || exifValue.IsArray);
object value = this.ConvertValue(dataType, offsetBuffer[..(int)size], numberOfComponents > 1 || exifValue.IsArray);
this.Add(values, exifValue, value);
}
}
@ -644,7 +627,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
return default;
}
uint numerator = this.ConvertToUInt32(buffer.Slice(0, 4));
uint numerator = this.ConvertToUInt32(buffer[..4]);
uint denominator = this.ConvertToUInt32(buffer.Slice(4, 4));
return new Rational(numerator, denominator, false);
@ -671,7 +654,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
return default;
}
int numerator = this.ConvertToInt32(buffer.Slice(0, 4));
int numerator = this.ConvertToInt32(buffer[..4]);
int denominator = this.ConvertToInt32(buffer.Slice(4, 4));
return new SignedRational(numerator, denominator, false);

8
src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs

@ -367,13 +367,13 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
private static void WriteRational(Span<byte> destination, in Rational value)
{
BinaryPrimitives.WriteUInt32LittleEndian(destination.Slice(0, 4), value.Numerator);
BinaryPrimitives.WriteUInt32LittleEndian(destination[..4], value.Numerator);
BinaryPrimitives.WriteUInt32LittleEndian(destination.Slice(4, 4), value.Denominator);
}
private static void WriteSignedRational(Span<byte> destination, in SignedRational value)
{
BinaryPrimitives.WriteInt32LittleEndian(destination.Slice(0, 4), value.Numerator);
BinaryPrimitives.WriteInt32LittleEndian(destination[..4], value.Numerator);
BinaryPrimitives.WriteInt32LittleEndian(destination.Slice(4, 4), value.Denominator);
}
@ -435,11 +435,11 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
if (ExifUcs2StringHelpers.IsUcs2Tag((ExifTagValue)(ushort)exifValue.Tag))
{
return offset + ExifUcs2StringHelpers.Write((string)value, destination.Slice(offset));
return offset + ExifUcs2StringHelpers.Write((string)value, destination[offset..]);
}
else if (value is EncodedString encodedString)
{
return offset + ExifEncodedStringHelpers.Write(encodedString, destination.Slice(offset));
return offset + ExifEncodedStringHelpers.Write(encodedString, destination[offset..]);
}
if (exifValue.IsArray)

2
src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.Primitives.cs

@ -108,7 +108,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
int pos = value.IndexOf('\0');
if (pos >= 0)
{
value = value.Substring(0, pos);
value = value[..pos];
}
return value;

2
src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Primitives.cs

@ -213,7 +213,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
lengthAdjust = 1;
}
value = value.Substring(0, Math.Min(length - lengthAdjust, value.Length));
value = value[..Math.Min(length - lengthAdjust, value.Length)];
byte[] textData = Encoding.ASCII.GetBytes(value);
int actualLength = Math.Min(length - lengthAdjust, textData.Length);

2
src/ImageSharp/Metadata/Profiles/IPTC/IptcValue.cs

@ -101,7 +101,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Iptc
byte[] valueBytes;
if (this.Strict && value.Length > maxLength)
{
string cappedValue = value.Substring(0, maxLength);
string cappedValue = value[..maxLength];
valueBytes = this.encoding.GetBytes(cappedValue);
// It is still possible that the bytes of the string exceed the limit.

12
src/ImageSharp/PixelFormats/PixelBlender{TPixel}.cs

@ -58,14 +58,14 @@ namespace SixLabors.ImageSharp.PixelFormats
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
Span<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
ReadOnlySpan<TPixel> sourcePixels = background.Slice(0, background.Length);
ReadOnlySpan<TPixel> sourcePixels = background[..];
PixelOperations<TPixel>.Instance.ToVector4(configuration, sourcePixels, backgroundSpan, PixelConversionModifiers.Scale);
ReadOnlySpan<TPixelSrc> sourcePixels1 = source.Slice(0, background.Length);
ReadOnlySpan<TPixelSrc> sourcePixels1 = source[..background.Length];
PixelOperations<TPixelSrc>.Instance.ToVector4(configuration, sourcePixels1, sourceSpan, PixelConversionModifiers.Scale);
this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount);
Span<Vector4> sourceVectors = destinationSpan.Slice(0, background.Length);
Span<Vector4> sourceVectors = destinationSpan[..background.Length];
PixelOperations<TPixel>.Instance.FromVector4Destructive(configuration, sourceVectors, destination, PixelConversionModifiers.Scale);
}
}
@ -120,14 +120,14 @@ namespace SixLabors.ImageSharp.PixelFormats
Span<Vector4> backgroundSpan = buffer.Slice(destination.Length, destination.Length);
Span<Vector4> sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
ReadOnlySpan<TPixel> sourcePixels = background.Slice(0, background.Length);
ReadOnlySpan<TPixel> sourcePixels = background[..];
PixelOperations<TPixel>.Instance.ToVector4(configuration, sourcePixels, backgroundSpan, PixelConversionModifiers.Scale);
ReadOnlySpan<TPixelSrc> sourcePixels1 = source.Slice(0, background.Length);
ReadOnlySpan<TPixelSrc> sourcePixels1 = source[..background.Length];
PixelOperations<TPixelSrc>.Instance.ToVector4(configuration, sourcePixels1, sourceSpan, PixelConversionModifiers.Scale);
this.BlendFunction(destinationSpan, backgroundSpan, sourceSpan, amount);
Span<Vector4> sourceVectors = destinationSpan.Slice(0, background.Length);
Span<Vector4> sourceVectors = destinationSpan[..background.Length];
PixelOperations<TPixel>.Instance.FromVector4Destructive(configuration, sourceVectors, destination, PixelConversionModifiers.Scale);
}
}

14
src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs

@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <param name="source">The <see cref="Rgb24"/>.</param>
/// <returns>The <see cref="Color"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public static implicit operator Color(Rgb24 source) => new Color(source);
public static implicit operator Color(Rgb24 source) => new(source);
/// <summary>
/// Converts a <see cref="Color"/> to <see cref="Rgb24"/>.
@ -210,17 +210,7 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source)
{
#if NETSTANDARD2_0
// See https://github.com/SixLabors/ImageSharp/issues/1275
this.R = source.R;
this.G = source.G;
this.B = source.B;
#else
this = source.Rgb;
#endif
}
public void FromRgba32(Rgba32 source) => this = source.Rgb;
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]

2
src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs

@ -517,7 +517,7 @@ namespace SixLabors.ImageSharp.PixelFormats
{
if (hex[0] == '#')
{
hex = hex.Substring(1);
hex = hex[1..];
}
if (hex.Length == 8)

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

@ -134,9 +134,9 @@ namespace SixLabors.ImageSharp.PixelFormats
int remainder = sourcePixels.Length - endOfCompleteSlices;
if (remainder > 0)
{
ReadOnlySpan<TSourcePixel> s = sourcePixels.Slice(endOfCompleteSlices);
Span<TPixel> d = destinationPixels.Slice(endOfCompleteSlices);
vectorSpan = vectorSpan.Slice(0, remainder);
ReadOnlySpan<TSourcePixel> s = sourcePixels[endOfCompleteSlices..];
Span<TPixel> d = destinationPixels[endOfCompleteSlices..];
vectorSpan = vectorSpan[..remainder];
PixelOperations<TSourcePixel>.Instance.ToVector4(configuration, s, vectorSpan, PixelConversionModifiers.Scale);
this.FromVector4Destructive(configuration, vectorSpan, d, PixelConversionModifiers.Scale);
}

4
src/ImageSharp/PixelFormats/Utils/Vector4Converters.RgbaCompatible.cs

@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils
// Using the last quarter of 'destVectors' as a temporary buffer to avoid allocation:
int countWithoutLastItem = count - 1;
ReadOnlySpan<TPixel> reducedSource = sourcePixels.Slice(0, countWithoutLastItem);
ReadOnlySpan<TPixel> reducedSource = sourcePixels[..countWithoutLastItem];
Span<Rgba32> lastQuarterOfDestBuffer = MemoryMarshal.Cast<Vector4, Rgba32>(destVectors).Slice((3 * count) + 1, countWithoutLastItem);
pixelOperations.ToRgba32(configuration, reducedSource, lastQuarterOfDestBuffer);
@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils
// but we are always reading/writing at different positions:
SimdUtils.ByteToNormalizedFloat(
MemoryMarshal.Cast<Rgba32, byte>(lastQuarterOfDestBuffer),
MemoryMarshal.Cast<Vector4, float>(destVectors.Slice(0, countWithoutLastItem)));
MemoryMarshal.Cast<Vector4, float>(destVectors[..countWithoutLastItem]));
destVectors[countWithoutLastItem] = sourcePixels[countWithoutLastItem].ToVector4();

18
src/ImageSharp/Processing/Processors/Convolution/BokehBlurProcessor{TPixel}.cs

@ -295,8 +295,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
[MethodImpl(InliningOptions.ShortMethod)]
public void Invoke(int y, Span<Vector4> span)
{
Span<TPixel> targetRowSpan = this.targetPixels.DangerousGetRowSpan(y).Slice(this.bounds.X);
PixelOperations<TPixel>.Instance.ToVector4(this.configuration, targetRowSpan.Slice(0, span.Length), span, PixelConversionModifiers.Premultiply);
Span<TPixel> targetRowSpan = this.targetPixels.DangerousGetRowSpan(y)[this.bounds.X..];
PixelOperations<TPixel>.Instance.ToVector4(this.configuration, targetRowSpan[..span.Length], span, PixelConversionModifiers.Premultiply);
ref Vector4 baseRef = ref MemoryMarshal.GetReference(span);
for (int x = 0; x < this.bounds.Width; x++)
@ -335,9 +335,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
[MethodImpl(InliningOptions.ShortMethod)]
public void Invoke(int y, Span<Vector4> span)
{
Span<TPixel> targetRowSpan = this.targetPixels.DangerousGetRowSpan(y).Slice(this.bounds.X);
Span<TPixel> targetRowSpan = this.targetPixels.DangerousGetRowSpan(y)[this.bounds.X..];
PixelOperations<TPixel>.Instance.ToVector4(this.configuration, targetRowSpan.Slice(0, span.Length), span, PixelConversionModifiers.Premultiply);
PixelOperations<TPixel>.Instance.ToVector4(this.configuration, targetRowSpan[..span.Length], span, PixelConversionModifiers.Premultiply);
Numerics.CubePowOnXYZ(span);
@ -378,8 +378,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
Vector4 low = Vector4.Zero;
var high = new Vector4(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
Span<TPixel> targetPixelSpan = this.targetPixels.DangerousGetRowSpan(y).Slice(this.bounds.X);
Span<Vector4> sourceRowSpan = this.sourceValues.DangerousGetRowSpan(y).Slice(this.bounds.X);
Span<TPixel> targetPixelSpan = this.targetPixels.DangerousGetRowSpan(y)[this.bounds.X..];
Span<Vector4> sourceRowSpan = this.sourceValues.DangerousGetRowSpan(y)[this.bounds.X..];
ref Vector4 sourceRef = ref MemoryMarshal.GetReference(sourceRowSpan);
for (int x = 0; x < this.bounds.Width; x++)
@ -391,7 +391,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
v.Z = MathF.Pow(clamp.Z, this.inverseGamma);
}
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.configuration, sourceRowSpan.Slice(0, this.bounds.Width), targetPixelSpan, PixelConversionModifiers.Premultiply);
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.configuration, sourceRowSpan[..this.bounds.Width], targetPixelSpan, PixelConversionModifiers.Premultiply);
}
}
@ -428,9 +428,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
Numerics.Clamp(MemoryMarshal.Cast<Vector4, float>(sourceRowSpan), 0, float.PositiveInfinity);
Numerics.CubeRootOnXYZ(sourceRowSpan);
Span<TPixel> targetPixelSpan = this.targetPixels.DangerousGetRowSpan(y).Slice(this.bounds.X);
Span<TPixel> targetPixelSpan = this.targetPixels.DangerousGetRowSpan(y)[this.bounds.X..];
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.configuration, sourceRowSpan.Slice(0, this.bounds.Width), targetPixelSpan, PixelConversionModifiers.Premultiply);
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.configuration, sourceRowSpan[..this.bounds.Width], targetPixelSpan, PixelConversionModifiers.Premultiply);
}
}
}

4
src/ImageSharp/Processing/Processors/Convolution/Convolution2DRowOperation{TPixel}.cs

@ -67,7 +67,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
// Span is 3x bounds.
int boundsX = this.bounds.X;
int boundsWidth = this.bounds.Width;
Span<Vector4> sourceBuffer = span.Slice(0, boundsWidth);
Span<Vector4> sourceBuffer = span[..boundsWidth];
Span<Vector4> targetYBuffer = span.Slice(boundsWidth, boundsWidth);
Span<Vector4> targetXBuffer = span.Slice(boundsWidth * 2, boundsWidth);
@ -133,7 +133,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
// Span is 3x bounds.
int boundsX = this.bounds.X;
int boundsWidth = this.bounds.Width;
Span<Vector4> sourceBuffer = span.Slice(0, boundsWidth);
Span<Vector4> sourceBuffer = span[..boundsWidth];
Span<Vector4> targetYBuffer = span.Slice(boundsWidth, boundsWidth);
Span<Vector4> targetXBuffer = span.Slice(boundsWidth * 2, boundsWidth);

16
src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs

@ -166,8 +166,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
int boundsWidth = this.bounds.Width;
int kernelSize = this.kernel.Length;
Span<Vector4> sourceBuffer = span.Slice(0, this.bounds.Width);
Span<Vector4> targetBuffer = span.Slice(this.bounds.Width);
Span<Vector4> sourceBuffer = span[..this.bounds.Width];
Span<Vector4> targetBuffer = span[this.bounds.Width..];
// Clear the target buffer for each row run.
targetBuffer.Clear();
@ -228,8 +228,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
int boundsWidth = this.bounds.Width;
int kernelSize = this.kernel.Length;
Span<Vector4> sourceBuffer = span.Slice(0, this.bounds.Width);
Span<Vector4> targetBuffer = span.Slice(this.bounds.Width);
Span<Vector4> sourceBuffer = span[..this.bounds.Width];
Span<Vector4> targetBuffer = span[this.bounds.Width..];
// Clear the target buffer for each row run.
targetBuffer.Clear();
@ -327,8 +327,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
int boundsWidth = this.bounds.Width;
int kernelSize = this.kernel.Length;
Span<Vector4> sourceBuffer = span.Slice(0, this.bounds.Width);
Span<Vector4> targetBuffer = span.Slice(this.bounds.Width);
Span<Vector4> sourceBuffer = span[..this.bounds.Width];
Span<Vector4> targetBuffer = span[this.bounds.Width..];
ref int sampleRowBase = ref Unsafe.Add(ref MemoryMarshal.GetReference(this.map.GetRowOffsetSpan()), (y - this.bounds.Y) * kernelSize);
@ -392,8 +392,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
int boundsWidth = this.bounds.Width;
int kernelSize = this.kernel.Length;
Span<Vector4> sourceBuffer = span.Slice(0, this.bounds.Width);
Span<Vector4> targetBuffer = span.Slice(this.bounds.Width);
Span<Vector4> sourceBuffer = span[..this.bounds.Width];
Span<Vector4> targetBuffer = span[this.bounds.Width..];
ref int sampleRowBase = ref Unsafe.Add(ref MemoryMarshal.GetReference(this.map.GetRowOffsetSpan()), (y - this.bounds.Y) * kernelSize);

4
src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs

@ -114,8 +114,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
// Span is 2x bounds.
int boundsX = this.bounds.X;
int boundsWidth = this.bounds.Width;
Span<Vector4> sourceBuffer = span.Slice(0, this.bounds.Width);
Span<Vector4> targetBuffer = span.Slice(this.bounds.Width);
Span<Vector4> sourceBuffer = span[..this.bounds.Width];
Span<Vector4> targetBuffer = span[this.bounds.Width..];
ref Vector4 targetRowRef = ref MemoryMarshal.GetReference(span);
Span<TPixel> targetRowSpan = this.targetPixels.DangerousGetRowSpan(y).Slice(boundsX, boundsWidth);

4
src/ImageSharp/Processing/Processors/Convolution/KernelSamplingMap.cs

@ -110,8 +110,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
switch (borderMode)
{
case BorderWrappingMode.Repeat:
Numerics.Clamp(span.Slice(0, affectedSize), min, max);
Numerics.Clamp(span.Slice(span.Length - affectedSize), min, max);
Numerics.Clamp(span[..affectedSize], min, max);
Numerics.Clamp(span[^affectedSize..], min, max);
break;
case BorderWrappingMode.Mirror:
var min2dec = min + min - 1;

2
src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs

@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering
for (int y = bounds.Top; y < bounds.Bottom; y++)
{
ReadOnlySpan<TPixel> sourceRow = sourceBuffer.DangerousGetRowSpan(y).Slice(bounds.X, bounds.Width);
Span<byte> destRow = destination.GetWritablePixelRowSpanUnsafe(y - bounds.Y).Slice(0, sourceRow.Length);
Span<byte> destRow = destination.GetWritablePixelRowSpanUnsafe(y - bounds.Y)[..sourceRow.Length];
for (int x = 0; x < sourceRow.Length; x++)
{

4
src/ImageSharp/Processing/Processors/Filters/OpaqueProcessor{TPixel}.cs

@ -51,8 +51,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters
[MethodImpl(InliningOptions.ShortMethod)]
public void Invoke(int y, Span<Vector4> span)
{
Span<TPixel> targetRowSpan = this.target.DangerousGetRowSpan(y).Slice(this.bounds.X);
PixelOperations<TPixel>.Instance.ToVector4(this.configuration, targetRowSpan.Slice(0, span.Length), span, PixelConversionModifiers.Scale);
Span<TPixel> targetRowSpan = this.target.DangerousGetRowSpan(y)[this.bounds.X..];
PixelOperations<TPixel>.Instance.ToVector4(this.configuration, targetRowSpan[..span.Length], span, PixelConversionModifiers.Scale);
ref Vector4 baseRef = ref MemoryMarshal.GetReference(span);
for (int x = 0; x < this.bounds.Width; x++)

10
src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor{TPixel}.cs

@ -107,12 +107,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
}
/// <inheritdoc/>
#if NETSTANDARD2_0
// https://github.com/SixLabors/ImageSharp/issues/1204
[MethodImpl(MethodImplOptions.NoOptimization)]
#else
[MethodImpl(InliningOptions.ShortMethod)]
#endif
public void Invoke(int y)
{
ref int histogramBase = ref MemoryMarshal.GetReference(this.histogramBuffer.GetSpan());
@ -156,12 +151,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
}
/// <inheritdoc/>
#if NETSTANDARD2_0
// https://github.com/SixLabors/ImageSharp/issues/1204
[MethodImpl(MethodImplOptions.NoOptimization)]
#else
[MethodImpl(InliningOptions.ShortMethod)]
#endif
public void Invoke(int y)
{
ref int cdfBase = ref MemoryMarshal.GetReference(this.cdfBuffer.GetSpan());

2
src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs

@ -108,7 +108,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
}
this.octree.Palletize(paletteSpan, max, ref paletteIndex);
ReadOnlyMemory<TPixel> result = this.paletteOwner.Memory.Slice(0, paletteSpan.Length);
ReadOnlyMemory<TPixel> result = this.paletteOwner.Memory[..paletteSpan.Length];
// When called multiple times by QuantizerUtilities.BuildPalette
// this prevents memory churn caused by reallocation.

4
src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs

@ -127,7 +127,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
this.BuildCube();
// Slice again since maxColors has been updated since the buffer was created.
Span<TPixel> paletteSpan = this.paletteOwner.GetSpan().Slice(0, this.maxColors);
Span<TPixel> paletteSpan = this.paletteOwner.GetSpan()[..this.maxColors];
ReadOnlySpan<Moment> momentsSpan = this.momentsOwner.GetSpan();
for (int k = 0; k < paletteSpan.Length; k++)
{
@ -142,7 +142,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
}
}
ReadOnlyMemory<TPixel> result = this.paletteOwner.Memory.Slice(0, paletteSpan.Length);
ReadOnlyMemory<TPixel> result = this.paletteOwner.Memory[..paletteSpan.Length];
if (this.isDithering)
{
// When called multiple times by QuantizerUtilities.BuildPalette

4
src/ImageSharp/Processing/Processors/Transforms/CropProcessor{TPixel}.cs

@ -86,9 +86,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
[MethodImpl(InliningOptions.ShortMethod)]
public void Invoke(int y)
{
Span<TPixel> sourceRow = this.source.DangerousGetRowSpan(y).Slice(this.bounds.Left);
Span<TPixel> sourceRow = this.source.DangerousGetRowSpan(y)[this.bounds.Left..];
Span<TPixel> targetRow = this.destination.DangerousGetRowSpan(y - this.bounds.Top);
sourceRow.Slice(0, this.bounds.Width).CopyTo(targetRow);
sourceRow[..this.bounds.Width].CopyTo(targetRow);
}
}
}

2
src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeWorker.cs

@ -102,7 +102,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
[MethodImpl(InliningOptions.ShortMethod)]
public Span<Vector4> GetColumnSpan(int x, int startY)
=> this.transposedFirstPassBuffer.DangerousGetRowSpan(x).Slice(startY - this.currentWindow.Min);
=> this.transposedFirstPassBuffer.DangerousGetRowSpan(x)[(startY - this.currentWindow.Min)..];
public void Initialize()
=> this.CalculateFirstPassValues(this.currentWindow);

12
tests/ImageSharp.Tests/Helpers/RuntimeEnvironmentTests.cs

@ -4,22 +4,12 @@
using System.Runtime.InteropServices;
using Xunit;
#pragma warning disable IDE0022 // Use expression body for methods
namespace SixLabors.ImageSharp.Tests.Helpers
{
public class RuntimeEnvironmentTests
{
[Fact]
public void CanDetectNetCore()
{
#if NET5_0_OR_GREATER
Assert.False(RuntimeEnvironment.IsNetCore);
#elif NETCOREAPP
Assert.True(RuntimeEnvironment.IsNetCore);
#else
Assert.False(RuntimeEnvironment.IsNetCore);
#endif
}
public void CanDetectNetCore() => Assert.False(RuntimeEnvironment.IsNetCore);
[Fact]
public void CanDetectOSPlatform()

14
tests/ImageSharp.Tests/Memory/Allocators/UniformUnmanagedMemoryPoolTests.Trim.cs

@ -1,11 +1,9 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using Microsoft.DotNet.RemoteExecutor;
using SixLabors.ImageSharp.Memory.Internals;
@ -109,7 +107,6 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators
}
}
#if NETCOREAPP3_1_OR_GREATER
public static readonly bool Is32BitProcess = !Environment.Is64BitProcess;
private static readonly List<byte[]> PressureArrays = new();
@ -121,21 +118,21 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators
static void RunTest()
{
Assert.False(Environment.Is64BitProcess);
const int OneMb = 1 << 20;
const int oneMb = 1 << 20;
var trimSettings = new UniformUnmanagedMemoryPool.TrimSettings { HighPressureThresholdRate = 0.2f };
GCMemoryInfo memInfo = GC.GetGCMemoryInfo();
int highLoadThreshold = (int)(memInfo.HighMemoryLoadThresholdBytes / OneMb);
int highLoadThreshold = (int)(memInfo.HighMemoryLoadThresholdBytes / oneMb);
highLoadThreshold = (int)(trimSettings.HighPressureThresholdRate * highLoadThreshold);
var pool = new UniformUnmanagedMemoryPool(OneMb, 16, trimSettings);
var pool = new UniformUnmanagedMemoryPool(oneMb, 16, trimSettings);
pool.Return(pool.Rent(16));
Assert.Equal(16, UnmanagedMemoryHandle.TotalOutstandingHandles);
for (int i = 0; i < highLoadThreshold; i++)
{
byte[] array = new byte[OneMb];
byte[] array = new byte[oneMb];
TouchPage(array);
PressureArrays.Add(array);
}
@ -163,7 +160,6 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators
}
}
}
#endif
}
}
}

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

@ -380,7 +380,6 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators
}
}
#if NETCOREAPP3_1_OR_GREATER
[Fact]
public void Issue2001_NegativeMemoryReportedByGc()
{
@ -393,6 +392,5 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators
_ = MemoryAllocator.Create();
}
}
#endif
}
}

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

@ -20,13 +20,11 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
[Trait("Category", "PixelFormats")]
public partial class PixelOperationsTests
{
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter
[Theory]
[WithBlankImages(1, 1, PixelTypes.All)]
public void GetGlobalInstance<T>(TestImageProvider<T> _)
where T : unmanaged, IPixel<T> => Assert.NotNull(PixelOperations<T>.Instance);
}
#pragma warning restore SA1313 // Parameter names should begin with lower-case letter
public abstract class PixelOperationsTests<TPixel> : MeasureFixture
where TPixel : unmanaged, IPixel<TPixel>

48
tests/ImageSharp.Tests/Primitives/ColorMatrixTests.cs

@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Tests.Primitives
{
public class ColorMatrixTests
{
private readonly ApproximateFloatComparer approximateFloatComparer = new ApproximateFloatComparer(1e-6f);
private readonly ApproximateFloatComparer approximateFloatComparer = new(1e-6f);
[Fact]
public void ColorMatrixIdentityIsCorrect()
@ -47,8 +47,8 @@ namespace SixLabors.ImageSharp.Tests.Primitives
[Fact]
public void ColorMatrixMultiply()
{
ColorMatrix value1 = this.CreateAllTwos();
ColorMatrix value2 = this.CreateAllThrees();
ColorMatrix value1 = CreateAllTwos();
ColorMatrix value2 = CreateAllThrees();
var m = default(ColorMatrix);
@ -88,35 +88,34 @@ namespace SixLabors.ImageSharp.Tests.Primitives
[Fact]
public void ColorMatrixMultiplyScalar()
{
ColorMatrix m = this.CreateAllTwos();
Assert.Equal(this.CreateAllFours(), m * 2, this.approximateFloatComparer);
ColorMatrix m = CreateAllTwos();
Assert.Equal(CreateAllFours(), m * 2, this.approximateFloatComparer);
}
[Fact]
public void ColorMatrixSubtract()
{
ColorMatrix m = this.CreateAllOnes() + this.CreateAllTwos();
Assert.Equal(this.CreateAllThrees(), m);
ColorMatrix m = CreateAllOnes() + CreateAllTwos();
Assert.Equal(CreateAllThrees(), m);
}
[Fact]
public void ColorMatrixNegate()
{
ColorMatrix m = this.CreateAllOnes() * -1F;
Assert.Equal(m, -this.CreateAllOnes());
ColorMatrix m = CreateAllOnes() * -1F;
Assert.Equal(m, -CreateAllOnes());
}
[Fact]
public void ColorMatrixAdd()
{
ColorMatrix m = this.CreateAllOnes() + this.CreateAllTwos();
Assert.Equal(this.CreateAllThrees(), m);
ColorMatrix m = CreateAllOnes() + CreateAllTwos();
Assert.Equal(CreateAllThrees(), m);
}
[Fact]
public void ColorMatrixHashCode()
{
#if NETCOREAPP2_1
ColorMatrix m = KnownFilterMatrices.CreateBrightnessFilter(.5F);
HashCode hash = default;
hash.Add(m.M11);
@ -141,7 +140,6 @@ namespace SixLabors.ImageSharp.Tests.Primitives
hash.Add(m.M54);
Assert.Equal(hash.ToHashCode(), m.GetHashCode());
#endif
}
[Fact]
@ -163,9 +161,8 @@ namespace SixLabors.ImageSharp.Tests.Primitives
Assert.Equal(expected, m.ToString());
}
private ColorMatrix CreateAllOnes()
{
return new ColorMatrix
private static ColorMatrix CreateAllOnes()
=> new()
{
M11 = 1F,
M12 = 1F,
@ -188,11 +185,9 @@ namespace SixLabors.ImageSharp.Tests.Primitives
M53 = 1F,
M54 = 1F
};
}
private ColorMatrix CreateAllTwos()
{
return new ColorMatrix
private static ColorMatrix CreateAllTwos()
=> new()
{
M11 = 2F,
M12 = 2F,
@ -215,11 +210,9 @@ namespace SixLabors.ImageSharp.Tests.Primitives
M53 = 2F,
M54 = 2F
};
}
private ColorMatrix CreateAllThrees()
{
return new ColorMatrix
private static ColorMatrix CreateAllThrees()
=> new()
{
M11 = 3F,
M12 = 3F,
@ -242,11 +235,9 @@ namespace SixLabors.ImageSharp.Tests.Primitives
M53 = 3F,
M54 = 3F
};
}
private ColorMatrix CreateAllFours()
{
return new ColorMatrix
private static ColorMatrix CreateAllFours()
=> new()
{
M11 = 4F,
M12 = 4F,
@ -269,6 +260,5 @@ namespace SixLabors.ImageSharp.Tests.Primitives
M53 = 4F,
M54 = 4F
};
}
}
}

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

Loading…
Cancel
Save