Browse Source

Merge branch 'main' into js/transform-metadata

pull/2946/head
James Jackson-South 1 year ago
parent
commit
27848d0e04
  1. 3
      .editorconfig
  2. 2
      shared-infrastructure
  3. 4
      src/ImageSharp/Advanced/ParallelRowIterator.Wrappers.cs
  4. 28
      src/ImageSharp/Advanced/ParallelRowIterator.cs
  5. 2
      src/ImageSharp/Color/Color.WebSafePalette.cs
  6. 2
      src/ImageSharp/Color/Color.WernerPalette.cs
  7. 6
      src/ImageSharp/Color/Color.cs
  8. 2
      src/ImageSharp/ColorProfiles/CieLab.cs
  9. 2
      src/ImageSharp/ColorProfiles/ColorProfileConverter.cs
  10. 2
      src/ImageSharp/ColorProfiles/Icc/Calculators/ColorTrcCalculator.cs
  11. 2
      src/ImageSharp/ColorProfiles/VonKriesChromaticAdaptation.cs
  12. 2
      src/ImageSharp/ColorProfiles/Y.cs
  13. 12
      src/ImageSharp/Common/Helpers/Numerics.cs
  14. 2
      src/ImageSharp/Common/Helpers/TolerantMath.cs
  15. 2
      src/ImageSharp/Configuration.cs
  16. 2
      src/ImageSharp/Formats/Bmp/BmpDecoder.cs
  17. 6
      src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
  18. 6
      src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
  19. 2
      src/ImageSharp/Formats/Bmp/BmpFormat.cs
  20. 2
      src/ImageSharp/Formats/Cur/CurFrameMetadata.cs
  21. 2
      src/ImageSharp/Formats/DecoderOptions.cs
  22. 11
      src/ImageSharp/Formats/Gif/GifDecoderCore.cs
  23. 2
      src/ImageSharp/Formats/Gif/GifEncoderCore.cs
  24. 2
      src/ImageSharp/Formats/Gif/GifFrameMetadata.cs
  25. 2
      src/ImageSharp/Formats/Ico/IcoFrameMetadata.cs
  26. 12
      src/ImageSharp/Formats/Icon/IconDecoderCore.cs
  27. 6
      src/ImageSharp/Formats/Icon/IconEncoderCore.cs
  28. 2
      src/ImageSharp/Formats/ImageFormatManager.cs
  29. 2
      src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs
  30. 8
      src/ImageSharp/Formats/Jpeg/Components/Block8x8F.ScaledCopy.cs
  31. 4
      src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKScalar.cs
  32. 2
      src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrScalar.cs
  33. 2
      src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKScalar.cs
  34. 2
      src/ImageSharp/Formats/Jpeg/Components/Encoder/ComponentProcessor.cs
  35. 2
      src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs
  36. 4
      src/ImageSharp/Formats/Jpeg/Components/Encoder/SpectralConverter{TPixel}.cs
  37. 6
      src/ImageSharp/Formats/Jpeg/Components/SizeExtensions.cs
  38. 2
      src/ImageSharp/Formats/Jpeg/JpegDecoder.cs
  39. 4
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
  40. 88
      src/ImageSharp/Formats/Jpeg/JpegEncoderCore.FrameConfig.cs
  41. 2
      src/ImageSharp/Formats/Jpeg/JpegFormat.cs
  42. 2
      src/ImageSharp/Formats/Pbm/PbmDecoderCore.cs
  43. 2
      src/ImageSharp/Formats/Png/PngDecoder.cs
  44. 8
      src/ImageSharp/Formats/Png/PngDecoderCore.cs
  45. 2
      src/ImageSharp/Formats/Png/PngDecoderOptions.cs
  46. 2
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  47. 2
      src/ImageSharp/Formats/Png/PngFormat.cs
  48. 4
      src/ImageSharp/Formats/Png/PngFrameMetadata.cs
  49. 2
      src/ImageSharp/Formats/Png/PngMetadata.cs
  50. 12
      src/ImageSharp/Formats/Png/PngScanlineProcessor.cs
  51. 2
      src/ImageSharp/Formats/Qoi/QoiFormat.cs
  52. 2
      src/ImageSharp/Formats/Tga/TgaDecoderCore.cs
  53. 2
      src/ImageSharp/Formats/Tga/TgaFormat.cs
  54. 2
      src/ImageSharp/Formats/Tga/TgaImageFormatDetector.cs
  55. 4
      src/ImageSharp/Formats/Tiff/Compression/Compressors/DeflateCompressor.cs
  56. 2
      src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsWriter.cs
  57. 4
      src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffJpegCompressor.cs
  58. 2
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs
  59. 2
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwString.cs
  60. 2
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/LzwTiffCompression.cs
  61. 2
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanTiffCompression.cs
  62. 2
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs
  63. 4
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/T6TiffCompression.cs
  64. 2
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/WebpTiffCompression.cs
  65. 5
      src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs
  66. 2
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero16TiffColor{TPixel}.cs
  67. 6
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero4TiffColor{TPixel}.cs
  68. 3
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZeroTiffColor{TPixel}.cs
  69. 3
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/CieLabPlanarTiffColor{TPixel}.cs
  70. 3
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/CieLabTiffColor{TPixel}.cs
  71. 2
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/CmykTiffColor{TPixel}.cs
  72. 3
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/PaletteTiffColor{TPixel}.cs
  73. 2
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb161616TiffColor{TPixel}.cs
  74. 4
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb16PlanarTiffColor{TPixel}.cs
  75. 5
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbFloat323232TiffColor{TPixel}.cs
  76. 3
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbPlanarTiffColor{TPixel}.cs
  77. 2
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba16161616TiffColor{TPixel}.cs
  78. 4
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba16PlanarTiffColor{TPixel}.cs
  79. 5
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbaFloat32323232TiffColor{TPixel}.cs
  80. 4
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero16TiffColor{TPixel}.cs
  81. 2
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero32FloatTiffColor{TPixel}.cs
  82. 6
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero4TiffColor{TPixel}.cs
  83. 2
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero8TiffColor{TPixel}.cs
  84. 2
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrConverter.cs
  85. 2
      src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
  86. 2
      src/ImageSharp/Formats/Tiff/TiffEncoderEntriesCollector.cs
  87. 6
      src/ImageSharp/Formats/Tiff/TiffFormat.cs
  88. 2
      src/ImageSharp/Formats/Tiff/Utils/TiffUtilities.cs
  89. 2
      src/ImageSharp/Formats/Tiff/Writers/TiffPaletteWriter{TPixel}.cs
  90. 2
      src/ImageSharp/Formats/Webp/AlphaDecoder.cs
  91. 4
      src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs
  92. 2
      src/ImageSharp/Formats/Webp/Chunks/WebpFrameData.cs
  93. 27
      src/ImageSharp/Formats/Webp/Lossless/BackwardReferenceEncoder.cs
  94. 8
      src/ImageSharp/Formats/Webp/Lossless/CostManager.cs
  95. 4
      src/ImageSharp/Formats/Webp/Lossless/CostModel.cs
  96. 2
      src/ImageSharp/Formats/Webp/Lossless/CrunchConfig.cs
  97. 25
      src/ImageSharp/Formats/Webp/Lossless/HistogramEncoder.cs
  98. 45
      src/ImageSharp/Formats/Webp/Lossless/PixOrCopy.cs
  99. 6
      src/ImageSharp/Formats/Webp/Lossless/PredictorEncoder.cs
  100. 29
      src/ImageSharp/Formats/Webp/Lossless/Vp8LBackwardRefs.cs

3
.editorconfig

@ -161,6 +161,9 @@ csharp_style_deconstructed_variable_declaration = true:warning
csharp_style_prefer_index_operator = true:warning csharp_style_prefer_index_operator = true:warning
csharp_style_prefer_range_operator = true:warning csharp_style_prefer_range_operator = true:warning
csharp_style_implicit_object_creation_when_type_is_apparent = true:error csharp_style_implicit_object_creation_when_type_is_apparent = true:error
# ReSharper inspection severities
resharper_arrange_object_creation_when_type_evident_highlighting = error
resharper_arrange_object_creation_when_type_not_evident_highlighting = error
# "Null" checking preferences # "Null" checking preferences
csharp_style_throw_expression = true:warning csharp_style_throw_expression = true:warning
csharp_style_conditional_delegate_call = true:warning csharp_style_conditional_delegate_call = true:warning

2
shared-infrastructure

@ -1 +1 @@
Subproject commit 5e13cde851a3d6e95d0dfdde2a57071f1efda9c3 Subproject commit 132a8232bd61471e9e9df727fb7a112800030327

4
src/ImageSharp/Advanced/ParallelRowIterator.Wrappers.cs

@ -139,7 +139,7 @@ public static partial class ParallelRowIterator
} }
int yMax = Math.Min(yMin + this.stepY, this.maxY); int yMax = Math.Min(yMin + this.stepY, this.maxY);
var rows = new RowInterval(yMin, yMax); RowInterval rows = new(yMin, yMax);
// Skip the safety copy when invoking a potentially impure method on a readonly field // Skip the safety copy when invoking a potentially impure method on a readonly field
Unsafe.AsRef(in this.operation).Invoke(in rows); Unsafe.AsRef(in this.operation).Invoke(in rows);
@ -185,7 +185,7 @@ public static partial class ParallelRowIterator
} }
int yMax = Math.Min(yMin + this.stepY, this.maxY); int yMax = Math.Min(yMin + this.stepY, this.maxY);
var rows = new RowInterval(yMin, yMax); RowInterval rows = new(yMin, yMax);
using IMemoryOwner<TBuffer> buffer = this.allocator.Allocate<TBuffer>(this.bufferLength); using IMemoryOwner<TBuffer> buffer = this.allocator.Allocate<TBuffer>(this.bufferLength);

28
src/ImageSharp/Advanced/ParallelRowIterator.cs

@ -26,7 +26,7 @@ public static partial class ParallelRowIterator
public static void IterateRows<T>(Configuration configuration, Rectangle rectangle, in T operation) public static void IterateRows<T>(Configuration configuration, Rectangle rectangle, in T operation)
where T : struct, IRowOperation where T : struct, IRowOperation
{ {
var parallelSettings = ParallelExecutionSettings.FromConfiguration(configuration); ParallelExecutionSettings parallelSettings = ParallelExecutionSettings.FromConfiguration(configuration);
IterateRows(rectangle, in parallelSettings, in operation); IterateRows(rectangle, in parallelSettings, in operation);
} }
@ -65,8 +65,8 @@ public static partial class ParallelRowIterator
} }
int verticalStep = DivideCeil(rectangle.Height, numOfSteps); int verticalStep = DivideCeil(rectangle.Height, numOfSteps);
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = numOfSteps }; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = numOfSteps };
var wrappingOperation = new RowOperationWrapper<T>(top, bottom, verticalStep, in operation); RowOperationWrapper<T> wrappingOperation = new(top, bottom, verticalStep, in operation);
Parallel.For( Parallel.For(
0, 0,
@ -88,7 +88,7 @@ public static partial class ParallelRowIterator
where T : struct, IRowOperation<TBuffer> where T : struct, IRowOperation<TBuffer>
where TBuffer : unmanaged where TBuffer : unmanaged
{ {
var parallelSettings = ParallelExecutionSettings.FromConfiguration(configuration); ParallelExecutionSettings parallelSettings = ParallelExecutionSettings.FromConfiguration(configuration);
IterateRows<T, TBuffer>(rectangle, in parallelSettings, in operation); IterateRows<T, TBuffer>(rectangle, in parallelSettings, in operation);
} }
@ -135,8 +135,8 @@ public static partial class ParallelRowIterator
} }
int verticalStep = DivideCeil(height, numOfSteps); int verticalStep = DivideCeil(height, numOfSteps);
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = numOfSteps }; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = numOfSteps };
var wrappingOperation = new RowOperationWrapper<T, TBuffer>(top, bottom, verticalStep, bufferLength, allocator, in operation); RowOperationWrapper<T, TBuffer> wrappingOperation = new(top, bottom, verticalStep, bufferLength, allocator, in operation);
Parallel.For( Parallel.For(
0, 0,
@ -156,7 +156,7 @@ public static partial class ParallelRowIterator
public static void IterateRowIntervals<T>(Configuration configuration, Rectangle rectangle, in T operation) public static void IterateRowIntervals<T>(Configuration configuration, Rectangle rectangle, in T operation)
where T : struct, IRowIntervalOperation where T : struct, IRowIntervalOperation
{ {
var parallelSettings = ParallelExecutionSettings.FromConfiguration(configuration); ParallelExecutionSettings parallelSettings = ParallelExecutionSettings.FromConfiguration(configuration);
IterateRowIntervals(rectangle, in parallelSettings, in operation); IterateRowIntervals(rectangle, in parallelSettings, in operation);
} }
@ -186,14 +186,14 @@ public static partial class ParallelRowIterator
// Avoid TPL overhead in this trivial case: // Avoid TPL overhead in this trivial case:
if (numOfSteps == 1) if (numOfSteps == 1)
{ {
var rows = new RowInterval(top, bottom); RowInterval rows = new(top, bottom);
Unsafe.AsRef(in operation).Invoke(in rows); Unsafe.AsRef(in operation).Invoke(in rows);
return; return;
} }
int verticalStep = DivideCeil(rectangle.Height, numOfSteps); int verticalStep = DivideCeil(rectangle.Height, numOfSteps);
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = numOfSteps }; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = numOfSteps };
var wrappingOperation = new RowIntervalOperationWrapper<T>(top, bottom, verticalStep, in operation); RowIntervalOperationWrapper<T> wrappingOperation = new(top, bottom, verticalStep, in operation);
Parallel.For( Parallel.For(
0, 0,
@ -215,7 +215,7 @@ public static partial class ParallelRowIterator
where T : struct, IRowIntervalOperation<TBuffer> where T : struct, IRowIntervalOperation<TBuffer>
where TBuffer : unmanaged where TBuffer : unmanaged
{ {
var parallelSettings = ParallelExecutionSettings.FromConfiguration(configuration); ParallelExecutionSettings parallelSettings = ParallelExecutionSettings.FromConfiguration(configuration);
IterateRowIntervals<T, TBuffer>(rectangle, in parallelSettings, in operation); IterateRowIntervals<T, TBuffer>(rectangle, in parallelSettings, in operation);
} }
@ -250,7 +250,7 @@ public static partial class ParallelRowIterator
// Avoid TPL overhead in this trivial case: // Avoid TPL overhead in this trivial case:
if (numOfSteps == 1) if (numOfSteps == 1)
{ {
var rows = new RowInterval(top, bottom); RowInterval rows = new(top, bottom);
using IMemoryOwner<TBuffer> buffer = allocator.Allocate<TBuffer>(bufferLength); using IMemoryOwner<TBuffer> buffer = allocator.Allocate<TBuffer>(bufferLength);
Unsafe.AsRef(in operation).Invoke(in rows, buffer.Memory.Span); Unsafe.AsRef(in operation).Invoke(in rows, buffer.Memory.Span);
@ -259,8 +259,8 @@ public static partial class ParallelRowIterator
} }
int verticalStep = DivideCeil(height, numOfSteps); int verticalStep = DivideCeil(height, numOfSteps);
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = numOfSteps }; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = numOfSteps };
var wrappingOperation = new RowIntervalOperationWrapper<T, TBuffer>(top, bottom, verticalStep, bufferLength, allocator, in operation); RowIntervalOperationWrapper<T, TBuffer> wrappingOperation = new(top, bottom, verticalStep, bufferLength, allocator, in operation);
Parallel.For( Parallel.For(
0, 0,

2
src/ImageSharp/Color/Color.WebSafePalette.cs

@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp;
/// </content> /// </content>
public partial struct Color public partial struct Color
{ {
private static readonly Lazy<Color[]> WebSafePaletteLazy = new Lazy<Color[]>(CreateWebSafePalette, true); private static readonly Lazy<Color[]> WebSafePaletteLazy = new(CreateWebSafePalette, true);
/// <summary> /// <summary>
/// Gets a collection of named, web safe colors as defined in the CSS Color Module Level 4. /// Gets a collection of named, web safe colors as defined in the CSS Color Module Level 4.

2
src/ImageSharp/Color/Color.WernerPalette.cs

@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp;
/// </content> /// </content>
public partial struct Color public partial struct Color
{ {
private static readonly Lazy<Color[]> WernerPaletteLazy = new Lazy<Color[]>(CreateWernerPalette, true); private static readonly Lazy<Color[]> WernerPaletteLazy = new(CreateWernerPalette, true);
/// <summary> /// <summary>
/// Gets a collection of colors as defined in the original second edition of Werner’s Nomenclature of Colours 1821. /// Gets a collection of colors as defined in the original second edition of Werner’s Nomenclature of Colours 1821.

6
src/ImageSharp/Color/Color.cs

@ -81,10 +81,10 @@ public readonly partial struct Color : IEquatable<Color>
PixelTypeInfo info = TPixel.GetPixelTypeInfo(); PixelTypeInfo info = TPixel.GetPixelTypeInfo();
if (info.ComponentInfo.HasValue && info.ComponentInfo.Value.GetMaximumComponentPrecision() <= (int)PixelComponentBitDepth.Bit32) if (info.ComponentInfo.HasValue && info.ComponentInfo.Value.GetMaximumComponentPrecision() <= (int)PixelComponentBitDepth.Bit32)
{ {
return new(source.ToScaledVector4()); return new Color(source.ToScaledVector4());
} }
return new(source); return new Color(source);
} }
/// <summary> /// <summary>
@ -120,7 +120,7 @@ public readonly partial struct Color : IEquatable<Color>
{ {
for (int i = 0; i < destination.Length; i++) for (int i = 0; i < destination.Length; i++)
{ {
destination[i] = new(source[i]); destination[i] = new Color(source[i]);
} }
} }
} }

2
src/ImageSharp/ColorProfiles/CieLab.cs

@ -182,7 +182,7 @@ public readonly struct CieLab : IProfileConnectingSpace<CieLab, CieXyz>
Vector3 wxyz = new(whitePoint.X, whitePoint.Y, whitePoint.Z); Vector3 wxyz = new(whitePoint.X, whitePoint.Y, whitePoint.Z);
Vector3 xyzr = new(xr, yr, zr); Vector3 xyzr = new(xr, yr, zr);
return new(xyzr * wxyz); return new CieXyz(xyzr * wxyz);
} }
/// <inheritdoc/> /// <inheritdoc/>

2
src/ImageSharp/ColorProfiles/ColorProfileConverter.cs

@ -12,7 +12,7 @@ public class ColorProfileConverter
/// Initializes a new instance of the <see cref="ColorProfileConverter"/> class. /// Initializes a new instance of the <see cref="ColorProfileConverter"/> class.
/// </summary> /// </summary>
public ColorProfileConverter() public ColorProfileConverter()
: this(new()) : this(new ColorConversionOptions())
{ {
} }

2
src/ImageSharp/ColorProfiles/Icc/Calculators/ColorTrcCalculator.cs

@ -58,7 +58,7 @@ internal class ColorTrcCalculator : IVector4Calculator
// when data to PCS, upstream process provides scaled XYZ // when data to PCS, upstream process provides scaled XYZ
// but input to calculator is descaled XYZ // but input to calculator is descaled XYZ
// (see DemoMaxICC IccCmm.cpp : CIccXformMatrixTRC::Apply) // (see DemoMaxICC IccCmm.cpp : CIccXformMatrixTRC::Apply)
xyz = new(CieXyz.FromScaledVector4(xyz).AsVector3Unsafe(), 1); xyz = new Vector4(CieXyz.FromScaledVector4(xyz).AsVector3Unsafe(), 1);
return this.curveCalculator.Calculate(xyz); return this.curveCalculator.Calculate(xyz);
} }
} }

2
src/ImageSharp/ColorProfiles/VonKriesChromaticAdaptation.cs

@ -31,7 +31,7 @@ public static class VonKriesChromaticAdaptation
if (from.Equals(to)) if (from.Equals(to))
{ {
return new(source.X, source.Y, source.Z); return new CieXyz(source.X, source.Y, source.Z);
} }
Vector3 sourceColorLms = Vector3.Transform(source.AsVector3Unsafe(), matrix); Vector3 sourceColorLms = Vector3.Transform(source.AsVector3Unsafe(), matrix);

2
src/ImageSharp/ColorProfiles/Y.cs

@ -92,7 +92,7 @@ public readonly struct Y : IColorProfile<Y, Rgb>
{ {
Matrix4x4 m = options.YCbCrTransform.Forward; Matrix4x4 m = options.YCbCrTransform.Forward;
float offset = options.YCbCrTransform.Offset.X; float offset = options.YCbCrTransform.Offset.X;
return new(Vector3.Dot(source.AsVector3Unsafe(), new Vector3(m.M11, m.M12, m.M13)) + offset); return new Y(Vector3.Dot(source.AsVector3Unsafe(), new Vector3(m.M11, m.M12, m.M13)) + offset);
} }
/// <inheritdoc/> /// <inheritdoc/>

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

@ -470,8 +470,8 @@ internal static class Numerics
where T : unmanaged where T : unmanaged
{ {
ref T sRef = ref MemoryMarshal.GetReference(span); ref T sRef = ref MemoryMarshal.GetReference(span);
var vmin = new Vector<T>(min); Vector<T> vmin = new(min);
var vmax = new Vector<T>(max); Vector<T> vmax = new(max);
nint n = (nint)(uint)span.Length / Vector<T>.Count; nint n = (nint)(uint)span.Length / Vector<T>.Count;
nint m = Modulo4(n); nint m = Modulo4(n);
@ -656,7 +656,7 @@ internal static class Numerics
return Sse.Shuffle(value.AsVector128(), value.AsVector128(), ShuffleAlphaControl).AsVector4(); return Sse.Shuffle(value.AsVector128(), value.AsVector128(), ShuffleAlphaControl).AsVector4();
} }
return new(value.W); return new Vector4(value.W);
} }
/// <summary> /// <summary>
@ -726,12 +726,12 @@ internal static class Numerics
ref Vector128<float> vectors128Ref = ref Unsafe.As<Vector4, Vector128<float>>(ref MemoryMarshal.GetReference(vectors)); ref Vector128<float> vectors128Ref = ref Unsafe.As<Vector4, Vector128<float>>(ref MemoryMarshal.GetReference(vectors));
ref Vector128<float> vectors128End = ref Unsafe.Add(ref vectors128Ref, (uint)vectors.Length); ref Vector128<float> vectors128End = ref Unsafe.Add(ref vectors128Ref, (uint)vectors.Length);
var v128_341 = Vector128.Create(341); Vector128<int> v128_341 = Vector128.Create(341);
Vector128<int> v128_negativeZero = Vector128.Create(-0.0f).AsInt32(); Vector128<int> v128_negativeZero = Vector128.Create(-0.0f).AsInt32();
Vector128<int> v128_one = Vector128.Create(1.0f).AsInt32(); Vector128<int> v128_one = Vector128.Create(1.0f).AsInt32();
var v128_13rd = Vector128.Create(1 / 3f); Vector128<float> v128_13rd = Vector128.Create(1 / 3f);
var v128_23rds = Vector128.Create(2 / 3f); Vector128<float> v128_23rds = Vector128.Create(2 / 3f);
while (Unsafe.IsAddressLessThan(ref vectors128Ref, ref vectors128End)) while (Unsafe.IsAddressLessThan(ref vectors128Ref, ref vectors128End))
{ {

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

@ -20,7 +20,7 @@ internal readonly struct TolerantMath
/// It is a field so it can be passed as an 'in' parameter. /// It is a field so it can be passed as an 'in' parameter.
/// Does not necessarily fit all use cases! /// Does not necessarily fit all use cases!
/// </summary> /// </summary>
public static readonly TolerantMath Default = new TolerantMath(1e-8); public static readonly TolerantMath Default = new(1e-8);
public TolerantMath(double epsilon) public TolerantMath(double epsilon)
{ {

2
src/ImageSharp/Configuration.cs

@ -122,7 +122,7 @@ public sealed class Configuration
/// <summary> /// <summary>
/// Gets or the <see cref="ImageFormatManager"/> that is currently in use. /// Gets or the <see cref="ImageFormatManager"/> that is currently in use.
/// </summary> /// </summary>
public ImageFormatManager ImageFormatsManager { get; private set; } = new ImageFormatManager(); public ImageFormatManager ImageFormatsManager { get; private set; } = new();
/// <summary> /// <summary>
/// Gets or sets the <see cref="Memory.MemoryAllocator"/> that is currently in use. /// Gets or sets the <see cref="Memory.MemoryAllocator"/> that is currently in use.

2
src/ImageSharp/Formats/Bmp/BmpDecoder.cs

@ -25,7 +25,7 @@ public sealed class BmpDecoder : SpecializedImageDecoder<BmpDecoderOptions>
Guard.NotNull(options, nameof(options)); Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream)); Guard.NotNull(stream, nameof(stream));
return new BmpDecoderCore(new() { GeneralOptions = options }).Identify(options.Configuration, stream, cancellationToken); return new BmpDecoderCore(new BmpDecoderOptions { GeneralOptions = options }).Identify(options.Configuration, stream, cancellationToken);
} }
/// <inheritdoc/> /// <inheritdoc/>

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

@ -220,7 +220,7 @@ internal sealed class BmpDecoderCore : ImageDecoderCore
protected override ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) protected override ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken)
{ {
this.ReadImageHeaders(stream, out _, out _); this.ReadImageHeaders(stream, out _, out _);
return new ImageInfo(new(this.infoHeader.Width, this.infoHeader.Height), this.metadata); return new ImageInfo(new Size(this.infoHeader.Width, this.infoHeader.Height), this.metadata);
} }
/// <summary> /// <summary>
@ -1270,7 +1270,7 @@ internal sealed class BmpDecoderCore : ImageDecoderCore
byte g = (byte)((temp & greenMask) >> rightShiftGreenMask); byte g = (byte)((temp & greenMask) >> rightShiftGreenMask);
byte b = (byte)((temp & blueMask) >> rightShiftBlueMask); byte b = (byte)((temp & blueMask) >> rightShiftBlueMask);
byte a = alphaMask != 0 ? (byte)((temp & alphaMask) >> rightShiftAlphaMask) : byte.MaxValue; byte a = alphaMask != 0 ? (byte)((temp & alphaMask) >> rightShiftAlphaMask) : byte.MaxValue;
pixelRow[x] = TPixel.FromRgba32(new(r, g, b, a)); pixelRow[x] = TPixel.FromRgba32(new Rgba32(r, g, b, a));
} }
offset += 4; offset += 4;
@ -1457,7 +1457,7 @@ internal sealed class BmpDecoderCore : ImageDecoderCore
this.bmpMetadata.InfoHeaderType = infoHeaderType; this.bmpMetadata.InfoHeaderType = infoHeaderType;
this.bmpMetadata.BitsPerPixel = (BmpBitsPerPixel)bitsPerPixel; this.bmpMetadata.BitsPerPixel = (BmpBitsPerPixel)bitsPerPixel;
this.Dimensions = new(this.infoHeader.Width, this.infoHeader.Height); this.Dimensions = new Size(this.infoHeader.Width, this.infoHeader.Height);
} }
/// <summary> /// <summary>

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

@ -655,7 +655,7 @@ internal sealed class BmpEncoderCore
CancellationToken cancellationToken) CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
using IQuantizer<TPixel> frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer<TPixel>(configuration, new QuantizerOptions() using IQuantizer<TPixel> frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer<TPixel>(configuration, new QuantizerOptions
{ {
MaxColors = 16, MaxColors = 16,
Dither = this.quantizer.Options.Dither, Dither = this.quantizer.Options.Dither,
@ -712,7 +712,7 @@ internal sealed class BmpEncoderCore
CancellationToken cancellationToken) CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
using IQuantizer<TPixel> frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer<TPixel>(configuration, new QuantizerOptions() using IQuantizer<TPixel> frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer<TPixel>(configuration, new QuantizerOptions
{ {
MaxColors = 4, MaxColors = 4,
Dither = this.quantizer.Options.Dither, Dither = this.quantizer.Options.Dither,
@ -778,7 +778,7 @@ internal sealed class BmpEncoderCore
CancellationToken cancellationToken) CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
using IQuantizer<TPixel> frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer<TPixel>(configuration, new QuantizerOptions() using IQuantizer<TPixel> frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer<TPixel>(configuration, new QuantizerOptions
{ {
MaxColors = 2, MaxColors = 2,
Dither = this.quantizer.Options.Dither, Dither = this.quantizer.Options.Dither,

2
src/ImageSharp/Formats/Bmp/BmpFormat.cs

@ -15,7 +15,7 @@ public sealed class BmpFormat : IImageFormat<BmpMetadata>
/// <summary> /// <summary>
/// Gets the shared instance. /// Gets the shared instance.
/// </summary> /// </summary>
public static BmpFormat Instance { get; } = new BmpFormat(); public static BmpFormat Instance { get; } = new();
/// <inheritdoc/> /// <inheritdoc/>
public string Name => "BMP"; public string Name => "BMP";

2
src/ImageSharp/Formats/Cur/CurFrameMetadata.cs

@ -148,7 +148,7 @@ public class CurFrameMetadata : IFormatFrameMetadata<CurFrameMetadata>
? (byte)0 ? (byte)0
: (byte)ColorNumerics.GetColorCountForBitDepth((int)this.BmpBitsPerPixel); : (byte)ColorNumerics.GetColorCountForBitDepth((int)this.BmpBitsPerPixel);
return new() return new IconDirEntry
{ {
Width = ClampEncodingDimension(this.EncodingWidth ?? size.Width), Width = ClampEncodingDimension(this.EncodingWidth ?? size.Width),
Height = ClampEncodingDimension(this.EncodingHeight ?? size.Height), Height = ClampEncodingDimension(this.EncodingHeight ?? size.Height),

2
src/ImageSharp/Formats/DecoderOptions.cs

@ -13,7 +13,7 @@ namespace SixLabors.ImageSharp.Formats;
/// </summary> /// </summary>
public sealed class DecoderOptions public sealed class DecoderOptions
{ {
private static readonly Lazy<DecoderOptions> LazyOptions = new(() => new()); private static readonly Lazy<DecoderOptions> LazyOptions = new(() => new DecoderOptions());
private uint maxFrames = int.MaxValue; private uint maxFrames = int.MaxValue;

11
src/ImageSharp/Formats/Gif/GifDecoderCore.cs

@ -267,7 +267,7 @@ internal sealed class GifDecoderCore : ImageDecoderCore
} }
return new ImageInfo( return new ImageInfo(
new(this.logicalScreenDescriptor.Width, this.logicalScreenDescriptor.Height), new Size(this.logicalScreenDescriptor.Width, this.logicalScreenDescriptor.Height),
this.metadata, this.metadata,
framesMetadata); framesMetadata);
} }
@ -305,7 +305,7 @@ internal sealed class GifDecoderCore : ImageDecoderCore
GifThrowHelper.ThrowInvalidImageContentException("Width or height should not be 0"); GifThrowHelper.ThrowInvalidImageContentException("Width or height should not be 0");
} }
this.Dimensions = new(this.imageDescriptor.Width, this.imageDescriptor.Height); this.Dimensions = new Size(this.imageDescriptor.Width, this.imageDescriptor.Height);
} }
/// <summary> /// <summary>
@ -414,6 +414,11 @@ internal sealed class GifDecoderCore : ImageDecoderCore
GifThrowHelper.ThrowInvalidImageContentException($"Gif comment length '{length}' exceeds max '{GifConstants.MaxCommentSubBlockLength}' of a comment data block"); GifThrowHelper.ThrowInvalidImageContentException($"Gif comment length '{length}' exceeds max '{GifConstants.MaxCommentSubBlockLength}' of a comment data block");
} }
if (length == -1)
{
GifThrowHelper.ThrowInvalidImageContentException("Unexpected end of stream while reading gif comment");
}
if (this.skipMetadata) if (this.skipMetadata)
{ {
stream.Seek(length, SeekOrigin.Current); stream.Seek(length, SeekOrigin.Current);
@ -592,7 +597,7 @@ internal sealed class GifDecoderCore : ImageDecoderCore
if (disposalMethod == FrameDisposalMode.RestoreToBackground) if (disposalMethod == FrameDisposalMode.RestoreToBackground)
{ {
this.restoreArea = Rectangle.Intersect(image.Bounds, new(descriptor.Left, descriptor.Top, descriptor.Width, descriptor.Height)); this.restoreArea = Rectangle.Intersect(image.Bounds, new Rectangle(descriptor.Left, descriptor.Top, descriptor.Width, descriptor.Height));
} }
if (colorTable.Length == 0) if (colorTable.Length == 0)

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

@ -113,7 +113,7 @@ internal sealed class GifEncoderCore
TransparentColorMode mode = this.transparentColorMode; TransparentColorMode mode = this.transparentColorMode;
// Create a new quantizer options instance augmenting the transparent color mode to match the encoder. // Create a new quantizer options instance augmenting the transparent color mode to match the encoder.
QuantizerOptions options = (this.encoder.Quantizer?.Options ?? new()).DeepClone(o => o.TransparentColorMode = mode); QuantizerOptions options = (this.encoder.Quantizer?.Options ?? new QuantizerOptions()).DeepClone(o => o.TransparentColorMode = mode);
if (globalQuantizer is null) if (globalQuantizer is null)
{ {

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

@ -94,7 +94,7 @@ public class GifFrameMetadata : IFormatFrameMetadata<GifFrameMetadata>
// If the color table is global and frame has no transparency. Consider it 'Source' also. // If the color table is global and frame has no transparency. Consider it 'Source' also.
blendSource |= this.ColorTableMode == FrameColorTableMode.Global && !this.HasTransparency; blendSource |= this.ColorTableMode == FrameColorTableMode.Global && !this.HasTransparency;
return new() return new FormatConnectingFrameMetadata
{ {
ColorTableMode = this.ColorTableMode, ColorTableMode = this.ColorTableMode,
Duration = TimeSpan.FromMilliseconds(this.FrameDelay * 10), Duration = TimeSpan.FromMilliseconds(this.FrameDelay * 10),

2
src/ImageSharp/Formats/Ico/IcoFrameMetadata.cs

@ -139,7 +139,7 @@ public class IcoFrameMetadata : IFormatFrameMetadata<IcoFrameMetadata>
? (byte)0 ? (byte)0
: (byte)ColorNumerics.GetColorCountForBitDepth((int)this.BmpBitsPerPixel); : (byte)ColorNumerics.GetColorCountForBitDepth((int)this.BmpBitsPerPixel);
return new() return new IconDirEntry
{ {
Width = ClampEncodingDimension(this.EncodingWidth ?? size.Width), Width = ClampEncodingDimension(this.EncodingWidth ?? size.Width),
Height = ClampEncodingDimension(this.EncodingHeight ?? size.Height), Height = ClampEncodingDimension(this.EncodingHeight ?? size.Height),

12
src/ImageSharp/Formats/Icon/IconDecoderCore.cs

@ -63,7 +63,7 @@ internal abstract class IconDecoderCore : ImageDecoderCore
// Since Windows Vista, the size of an image is determined from the BITMAPINFOHEADER structure or PNG image data // Since Windows Vista, the size of an image is determined from the BITMAPINFOHEADER structure or PNG image data
// which technically allows storing icons with larger than 256 pixels, but such larger sizes are not recommended by Microsoft. // which technically allows storing icons with larger than 256 pixels, but such larger sizes are not recommended by Microsoft.
this.Dimensions = new(Math.Max(this.Dimensions.Width, temp.Size.Width), Math.Max(this.Dimensions.Height, temp.Size.Height)); this.Dimensions = new Size(Math.Max(this.Dimensions.Width, temp.Size.Width), Math.Max(this.Dimensions.Height, temp.Size.Height));
} }
ImageMetadata metadata = new(); ImageMetadata metadata = new();
@ -208,7 +208,7 @@ internal abstract class IconDecoderCore : ImageDecoderCore
// Since Windows Vista, the size of an image is determined from the BITMAPINFOHEADER structure or PNG image data // Since Windows Vista, the size of an image is determined from the BITMAPINFOHEADER structure or PNG image data
// which technically allows storing icons with larger than 256 pixels, but such larger sizes are not recommended by Microsoft. // which technically allows storing icons with larger than 256 pixels, but such larger sizes are not recommended by Microsoft.
this.Dimensions = new(Math.Max(this.Dimensions.Width, frameInfo.Size.Width), Math.Max(this.Dimensions.Height, frameInfo.Size.Height)); this.Dimensions = new Size(Math.Max(this.Dimensions.Width, frameInfo.Size.Width), Math.Max(this.Dimensions.Height, frameInfo.Size.Height));
} }
// Copy the format specific metadata to the image. // Copy the format specific metadata to the image.
@ -222,7 +222,7 @@ internal abstract class IconDecoderCore : ImageDecoderCore
metadata.SetFormatMetadata(PngFormat.Instance, pngMetadata); metadata.SetFormatMetadata(PngFormat.Instance, pngMetadata);
} }
return new(this.Dimensions, metadata, frames); return new ImageInfo(this.Dimensions, metadata, frames);
} }
protected abstract void SetFrameMetadata( protected abstract void SetFrameMetadata(
@ -276,20 +276,20 @@ internal abstract class IconDecoderCore : ImageDecoderCore
height = Math.Max(height, entry.Height); height = Math.Max(height, entry.Height);
} }
this.Dimensions = new(width, height); this.Dimensions = new Size(width, height);
} }
private ImageDecoderCore GetDecoder(bool isPng) private ImageDecoderCore GetDecoder(bool isPng)
{ {
if (isPng) if (isPng)
{ {
return new PngDecoderCore(new() return new PngDecoderCore(new PngDecoderOptions
{ {
GeneralOptions = this.Options, GeneralOptions = this.Options,
}); });
} }
return new BmpDecoderCore(new() return new BmpDecoderCore(new BmpDecoderOptions
{ {
GeneralOptions = this.Options, GeneralOptions = this.Options,
ProcessedAlphaMask = true, ProcessedAlphaMask = true,

6
src/ImageSharp/Formats/Icon/IconEncoderCore.cs

@ -116,7 +116,7 @@ internal abstract class IconEncoderCore
[MemberNotNull(nameof(entries))] [MemberNotNull(nameof(entries))]
private void InitHeader(Image image) private void InitHeader(Image image)
{ {
this.fileHeader = new(this.iconFileType, (ushort)image.Frames.Count); this.fileHeader = new IconDir(this.iconFileType, (ushort)image.Frames.Count);
this.entries = this.iconFileType switch this.entries = this.iconFileType switch
{ {
IconFileType.ICO => IconFileType.ICO =>
@ -155,14 +155,14 @@ internal abstract class IconEncoderCore
count = 256; count = 256;
} }
return new WuQuantizer(new() return new WuQuantizer(new QuantizerOptions
{ {
MaxColors = count MaxColors = count
}); });
} }
// Don't dither if we have a palette. We want to preserve as much information as possible. // Don't dither if we have a palette. We want to preserve as much information as possible.
return new PaletteQuantizer(metadata.ColorTable.Value, new() { Dither = null }); return new PaletteQuantizer(metadata.ColorTable.Value, new QuantizerOptions { Dither = null });
} }
internal sealed class EncodingFrameMetadata internal sealed class EncodingFrameMetadata

2
src/ImageSharp/Formats/ImageFormatManager.cs

@ -161,7 +161,7 @@ public class ImageFormatManager
/// <summary> /// <summary>
/// Removes all the registered image format detectors. /// Removes all the registered image format detectors.
/// </summary> /// </summary>
public void ClearImageFormatDetectors() => this.imageFormatDetectors = new(); public void ClearImageFormatDetectors() => this.imageFormatDetectors = new ConcurrentBag<IImageFormatDetector>();
/// <summary> /// <summary>
/// Adds a new detector for detecting mime types. /// Adds a new detector for detecting mime types.

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

@ -140,7 +140,7 @@ internal partial struct Block8x8
/// <inheritdoc /> /// <inheritdoc />
public override string ToString() public override string ToString()
{ {
var sb = new StringBuilder(); StringBuilder sb = new();
sb.Append('['); sb.Append('[');
for (int i = 0; i < Size; i++) for (int i = 0; i < Size; i++)
{ {

8
src/ImageSharp/Formats/Jpeg/Components/Block8x8F.ScaledCopy.cs

@ -57,19 +57,19 @@ internal partial struct Block8x8F
ref Vector4 dTopLeft = ref Unsafe.As<Vector2, Vector4>(ref Unsafe.Add(ref destBase, offset)); ref Vector4 dTopLeft = ref Unsafe.As<Vector2, Vector4>(ref Unsafe.Add(ref destBase, offset));
ref Vector4 dBottomLeft = ref Unsafe.As<Vector2, Vector4>(ref Unsafe.Add(ref destBase, offset + destStride)); ref Vector4 dBottomLeft = ref Unsafe.As<Vector2, Vector4>(ref Unsafe.Add(ref destBase, offset + destStride));
var xyLeft = new Vector4(sLeft.X); Vector4 xyLeft = new(sLeft.X);
xyLeft.Z = sLeft.Y; xyLeft.Z = sLeft.Y;
xyLeft.W = sLeft.Y; xyLeft.W = sLeft.Y;
var zwLeft = new Vector4(sLeft.Z); Vector4 zwLeft = new(sLeft.Z);
zwLeft.Z = sLeft.W; zwLeft.Z = sLeft.W;
zwLeft.W = sLeft.W; zwLeft.W = sLeft.W;
var xyRight = new Vector4(sRight.X); Vector4 xyRight = new(sRight.X);
xyRight.Z = sRight.Y; xyRight.Z = sRight.Y;
xyRight.W = sRight.Y; xyRight.W = sRight.Y;
var zwRight = new Vector4(sRight.Z); Vector4 zwRight = new(sRight.Z);
zwRight.Z = sRight.W; zwRight.Z = sRight.W;
zwRight.W = sRight.W; zwRight.W = sRight.W;

4
src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.TiffYccKScalar.cs

@ -128,7 +128,7 @@ internal abstract partial class JpegColorConverterBase
ColorProfileConverter converter = new(); ColorProfileConverter converter = new();
Span<Cmyk> source = MemoryMarshal.Cast<float, Cmyk>(packed); Span<Cmyk> source = MemoryMarshal.Cast<float, Cmyk>(packed);
// YccK is not a defined ICC color space it's a JPEG-specific encoding used in Adobe-style CMYK JPEGs. // YccK is not a defined ICC color space it's a JPEG-specific encoding used in Adobe-style CMYK JPEGs.
// ICC profiles expect colorimetric CMYK values, so we must first convert YccK to CMYK using a hardcoded inverse transform. // ICC profiles expect colorimetric CMYK values, so we must first convert YccK to CMYK using a hardcoded inverse transform.
// This transform assumes Rec.601 YCbCr coefficients and an inverted K channel. // This transform assumes Rec.601 YCbCr coefficients and an inverted K channel.
// //
@ -144,7 +144,7 @@ internal abstract partial class JpegColorConverterBase
SourceIccProfile = profile, SourceIccProfile = profile,
TargetIccProfile = CompactSrgbV4Profile.Profile, TargetIccProfile = CompactSrgbV4Profile.Profile,
}; };
converter = new(options); converter = new ColorProfileConverter(options);
converter.Convert<Cmyk, Rgb>(source, destination); converter.Convert<Cmyk, Rgb>(source, destination);
UnpackDeinterleave3(MemoryMarshal.Cast<float, Vector3>(packed)[..source.Length], c0, c1, c2); UnpackDeinterleave3(MemoryMarshal.Cast<float, Vector3>(packed)[..source.Length], c0, c1, c2);

2
src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrScalar.cs

@ -91,7 +91,7 @@ internal abstract partial class JpegColorConverterBase
SourceIccProfile = profile, SourceIccProfile = profile,
TargetIccProfile = CompactSrgbV4Profile.Profile, TargetIccProfile = CompactSrgbV4Profile.Profile,
}; };
converter = new(options); converter = new ColorProfileConverter(options);
converter.Convert<Rgb, Rgb>(destination, destination); converter.Convert<Rgb, Rgb>(destination, destination);
UnpackDeinterleave3(MemoryMarshal.Cast<float, Vector3>(packed)[..source.Length], c0, c1, c2); UnpackDeinterleave3(MemoryMarshal.Cast<float, Vector3>(packed)[..source.Length], c0, c1, c2);

2
src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKScalar.cs

@ -116,7 +116,7 @@ internal abstract partial class JpegColorConverterBase
SourceIccProfile = profile, SourceIccProfile = profile,
TargetIccProfile = CompactSrgbV4Profile.Profile, TargetIccProfile = CompactSrgbV4Profile.Profile,
}; };
converter = new(options); converter = new ColorProfileConverter(options);
converter.Convert<Cmyk, Rgb>(source, destination); converter.Convert<Cmyk, Rgb>(source, destination);
UnpackDeinterleave3(MemoryMarshal.Cast<float, Vector3>(packed)[..source.Length], c0, c1, c2); UnpackDeinterleave3(MemoryMarshal.Cast<float, Vector3>(packed)[..source.Length], c0, c1, c2);

2
src/ImageSharp/Formats/Jpeg/Components/Encoder/ComponentProcessor.cs

@ -241,7 +241,7 @@ internal class ComponentProcessor : IDisposable
ref Vector<float> targetVectorRef = ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(target)); ref Vector<float> targetVectorRef = ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(target));
nuint count = target.VectorCount<float>(); nuint count = target.VectorCount<float>();
var multiplierVector = new Vector<float>(multiplier); Vector<float> multiplierVector = new(multiplier);
for (nuint i = 0; i < count; i++) for (nuint i = 0; i < count; i++)
{ {
Unsafe.Add(ref targetVectorRef, i) *= multiplierVector; Unsafe.Add(ref targetVectorRef, i) *= multiplierVector;

2
src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs

@ -409,7 +409,7 @@ internal class HuffmanScanEncoder
{ {
this.FlushRemainingBytes(); this.FlushRemainingBytes();
this.WriteRestart(restarts % 8); this.WriteRestart(restarts % 8);
foreach (var component in frame.Components) foreach (Component component in frame.Components)
{ {
component.DcPredictor = 0; component.DcPredictor = 0;
} }

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

@ -46,7 +46,7 @@ internal class SpectralConverter<TPixel> : SpectralConverter, IDisposable
// component processors from spectral to Rgb24 // component processors from spectral to Rgb24
const int blockPixelWidth = 8; const int blockPixelWidth = 8;
this.alignedPixelWidth = majorBlockWidth * blockPixelWidth; this.alignedPixelWidth = majorBlockWidth * blockPixelWidth;
var postProcessorBufferSize = new Size(this.alignedPixelWidth, this.pixelRowsPerStep); Size postProcessorBufferSize = new(this.alignedPixelWidth, this.pixelRowsPerStep);
this.componentProcessors = new ComponentProcessor[frame.Components.Length]; this.componentProcessors = new ComponentProcessor[frame.Components.Length];
for (int i = 0; i < this.componentProcessors.Length; i++) for (int i = 0; i < this.componentProcessors.Length; i++)
{ {
@ -119,7 +119,7 @@ internal class SpectralConverter<TPixel> : SpectralConverter, IDisposable
bLane.Slice(paddingStartIndex).Fill(bLane[paddingStartIndex - 1]); bLane.Slice(paddingStartIndex).Fill(bLane[paddingStartIndex - 1]);
// Convert from rgb24 to target pixel type // Convert from rgb24 to target pixel type
var values = new JpegColorConverterBase.ComponentValues(this.componentProcessors, y); JpegColorConverterBase.ComponentValues values = new(this.componentProcessors, y);
this.colorConverter.ConvertFromRgb(values, rLane, gLane, bLane); this.colorConverter.ConvertFromRgb(values, rLane, gLane, bLane);
} }

6
src/ImageSharp/Formats/Jpeg/Components/SizeExtensions.cs

@ -14,20 +14,20 @@ internal static class SizeExtensions
/// Multiplies 'a.Width' with 'b.Width' and 'a.Height' with 'b.Height'. /// Multiplies 'a.Width' with 'b.Width' and 'a.Height' with 'b.Height'.
/// TODO: Shouldn't we expose this as operator in SixLabors.Core? /// TODO: Shouldn't we expose this as operator in SixLabors.Core?
/// </summary> /// </summary>
public static Size MultiplyBy(this Size a, Size b) => new Size(a.Width * b.Width, a.Height * b.Height); public static Size MultiplyBy(this Size a, Size b) => new(a.Width * b.Width, a.Height * b.Height);
/// <summary> /// <summary>
/// Divides 'a.Width' with 'b.Width' and 'a.Height' with 'b.Height'. /// Divides 'a.Width' with 'b.Width' and 'a.Height' with 'b.Height'.
/// TODO: Shouldn't we expose this as operator in SixLabors.Core? /// TODO: Shouldn't we expose this as operator in SixLabors.Core?
/// </summary> /// </summary>
public static Size DivideBy(this Size a, Size b) => new Size(a.Width / b.Width, a.Height / b.Height); public static Size DivideBy(this Size a, Size b) => new(a.Width / b.Width, a.Height / b.Height);
/// <summary> /// <summary>
/// Divide Width and Height as real numbers and return the Ceiling. /// Divide Width and Height as real numbers and return the Ceiling.
/// </summary> /// </summary>
public static Size DivideRoundUp(this Size originalSize, int divX, int divY) public static Size DivideRoundUp(this Size originalSize, int divX, int divY)
{ {
var sizeVect = (Vector2)(SizeF)originalSize; Vector2 sizeVect = (Vector2)(SizeF)originalSize;
sizeVect /= new Vector2(divX, divY); sizeVect /= new Vector2(divX, divY);
sizeVect.X = MathF.Ceiling(sizeVect.X); sizeVect.X = MathF.Ceiling(sizeVect.X);
sizeVect.Y = MathF.Ceiling(sizeVect.Y); sizeVect.Y = MathF.Ceiling(sizeVect.Y);

2
src/ImageSharp/Formats/Jpeg/JpegDecoder.cs

@ -25,7 +25,7 @@ public sealed class JpegDecoder : SpecializedImageDecoder<JpegDecoderOptions>
Guard.NotNull(options, nameof(options)); Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream)); Guard.NotNull(stream, nameof(stream));
using JpegDecoderCore decoder = new(new() { GeneralOptions = options }); using JpegDecoderCore decoder = new(new JpegDecoderOptions { GeneralOptions = options });
return decoder.Identify(options.Configuration, stream, cancellationToken); return decoder.Identify(options.Configuration, stream, cancellationToken);
} }

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

@ -222,7 +222,7 @@ internal sealed class JpegDecoderCore : ImageDecoderCore, IRawJpegData
this.InitDerivedMetadataProperties(); this.InitDerivedMetadataProperties();
Size pixelSize = this.Frame.PixelSize; Size pixelSize = this.Frame.PixelSize;
return new ImageInfo(new(pixelSize.Width, pixelSize.Height), this.Metadata); return new ImageInfo(new Size(pixelSize.Width, pixelSize.Height), this.Metadata);
} }
/// <summary> /// <summary>
@ -1243,7 +1243,7 @@ internal sealed class JpegDecoderCore : ImageDecoderCore, IRawJpegData
} }
this.Frame = new JpegFrame(frameMarker, precision, frameWidth, frameHeight, componentCount); this.Frame = new JpegFrame(frameMarker, precision, frameWidth, frameHeight, componentCount);
this.Dimensions = new(frameWidth, frameHeight); this.Dimensions = new Size(frameWidth, frameHeight);
this.Metadata.GetJpegMetadata().Progressive = this.Frame.Progressive; this.Metadata.GetJpegMetadata().Progressive = this.Frame.Progressive;
remaining -= length; remaining -= length;

88
src/ImageSharp/Formats/Jpeg/JpegEncoderCore.FrameConfig.cs

@ -13,15 +13,15 @@ internal sealed unsafe partial class JpegEncoderCore
{ {
private static JpegFrameConfig[] CreateFrameConfigs() private static JpegFrameConfig[] CreateFrameConfigs()
{ {
var defaultLuminanceHuffmanDC = new JpegHuffmanTableConfig(@class: 0, destIndex: 0, HuffmanSpec.LuminanceDC); JpegHuffmanTableConfig defaultLuminanceHuffmanDC = new(@class: 0, destIndex: 0, HuffmanSpec.LuminanceDC);
var defaultLuminanceHuffmanAC = new JpegHuffmanTableConfig(@class: 1, destIndex: 0, HuffmanSpec.LuminanceAC); JpegHuffmanTableConfig defaultLuminanceHuffmanAC = new(@class: 1, destIndex: 0, HuffmanSpec.LuminanceAC);
var defaultChrominanceHuffmanDC = new JpegHuffmanTableConfig(@class: 0, destIndex: 1, HuffmanSpec.ChrominanceDC); JpegHuffmanTableConfig defaultChrominanceHuffmanDC = new(@class: 0, destIndex: 1, HuffmanSpec.ChrominanceDC);
var defaultChrominanceHuffmanAC = new JpegHuffmanTableConfig(@class: 1, destIndex: 1, HuffmanSpec.ChrominanceAC); JpegHuffmanTableConfig defaultChrominanceHuffmanAC = new(@class: 1, destIndex: 1, HuffmanSpec.ChrominanceAC);
var defaultLuminanceQuantTable = new JpegQuantizationTableConfig(0, Quantization.LuminanceTable); JpegQuantizationTableConfig defaultLuminanceQuantTable = new(0, Quantization.LuminanceTable);
var defaultChrominanceQuantTable = new JpegQuantizationTableConfig(1, Quantization.ChrominanceTable); JpegQuantizationTableConfig defaultChrominanceQuantTable = new(1, Quantization.ChrominanceTable);
var yCbCrHuffmanConfigs = new JpegHuffmanTableConfig[] JpegHuffmanTableConfig[] yCbCrHuffmanConfigs = new JpegHuffmanTableConfig[]
{ {
defaultLuminanceHuffmanDC, defaultLuminanceHuffmanDC,
defaultLuminanceHuffmanAC, defaultLuminanceHuffmanAC,
@ -29,7 +29,7 @@ internal sealed unsafe partial class JpegEncoderCore
defaultChrominanceHuffmanAC, defaultChrominanceHuffmanAC,
}; };
var yCbCrQuantTableConfigs = new JpegQuantizationTableConfig[] JpegQuantizationTableConfig[] yCbCrQuantTableConfigs = new JpegQuantizationTableConfig[]
{ {
defaultLuminanceQuantTable, defaultLuminanceQuantTable,
defaultChrominanceQuantTable, defaultChrominanceQuantTable,
@ -38,77 +38,77 @@ internal sealed unsafe partial class JpegEncoderCore
return new JpegFrameConfig[] return new JpegFrameConfig[]
{ {
// YCbCr 4:4:4 // YCbCr 4:4:4
new JpegFrameConfig( new(
JpegColorSpace.YCbCr, JpegColorSpace.YCbCr,
JpegColorType.YCbCrRatio444, JpegColorType.YCbCrRatio444,
new JpegComponentConfig[] new JpegComponentConfig[]
{ {
new JpegComponentConfig(id: 1, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0), new(id: 1, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1), new(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1), new(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
}, },
yCbCrHuffmanConfigs, yCbCrHuffmanConfigs,
yCbCrQuantTableConfigs), yCbCrQuantTableConfigs),
// YCbCr 4:2:2 // YCbCr 4:2:2
new JpegFrameConfig( new(
JpegColorSpace.YCbCr, JpegColorSpace.YCbCr,
JpegColorType.YCbCrRatio422, JpegColorType.YCbCrRatio422,
new JpegComponentConfig[] new JpegComponentConfig[]
{ {
new JpegComponentConfig(id: 1, hsf: 2, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0), new(id: 1, hsf: 2, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1), new(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1), new(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
}, },
yCbCrHuffmanConfigs, yCbCrHuffmanConfigs,
yCbCrQuantTableConfigs), yCbCrQuantTableConfigs),
// YCbCr 4:2:0 // YCbCr 4:2:0
new JpegFrameConfig( new(
JpegColorSpace.YCbCr, JpegColorSpace.YCbCr,
JpegColorType.YCbCrRatio420, JpegColorType.YCbCrRatio420,
new JpegComponentConfig[] new JpegComponentConfig[]
{ {
new JpegComponentConfig(id: 1, hsf: 2, vsf: 2, quantIndex: 0, dcIndex: 0, acIndex: 0), new(id: 1, hsf: 2, vsf: 2, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1), new(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1), new(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
}, },
yCbCrHuffmanConfigs, yCbCrHuffmanConfigs,
yCbCrQuantTableConfigs), yCbCrQuantTableConfigs),
// YCbCr 4:1:1 // YCbCr 4:1:1
new JpegFrameConfig( new(
JpegColorSpace.YCbCr, JpegColorSpace.YCbCr,
JpegColorType.YCbCrRatio411, JpegColorType.YCbCrRatio411,
new JpegComponentConfig[] new JpegComponentConfig[]
{ {
new JpegComponentConfig(id: 1, hsf: 4, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0), new(id: 1, hsf: 4, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1), new(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1), new(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
}, },
yCbCrHuffmanConfigs, yCbCrHuffmanConfigs,
yCbCrQuantTableConfigs), yCbCrQuantTableConfigs),
// YCbCr 4:1:0 // YCbCr 4:1:0
new JpegFrameConfig( new(
JpegColorSpace.YCbCr, JpegColorSpace.YCbCr,
JpegColorType.YCbCrRatio410, JpegColorType.YCbCrRatio410,
new JpegComponentConfig[] new JpegComponentConfig[]
{ {
new JpegComponentConfig(id: 1, hsf: 4, vsf: 2, quantIndex: 0, dcIndex: 0, acIndex: 0), new(id: 1, hsf: 4, vsf: 2, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1), new(id: 2, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1), new(id: 3, hsf: 1, vsf: 1, quantIndex: 1, dcIndex: 1, acIndex: 1),
}, },
yCbCrHuffmanConfigs, yCbCrHuffmanConfigs,
yCbCrQuantTableConfigs), yCbCrQuantTableConfigs),
// Luminance // Luminance
new JpegFrameConfig( new(
JpegColorSpace.Grayscale, JpegColorSpace.Grayscale,
JpegColorType.Luminance, JpegColorType.Luminance,
new JpegComponentConfig[] new JpegComponentConfig[]
{ {
new JpegComponentConfig(id: 0, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0), new(id: 0, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
}, },
new JpegHuffmanTableConfig[] new JpegHuffmanTableConfig[]
{ {
@ -121,14 +121,14 @@ internal sealed unsafe partial class JpegEncoderCore
}), }),
// Rgb // Rgb
new JpegFrameConfig( new(
JpegColorSpace.RGB, JpegColorSpace.RGB,
JpegColorType.Rgb, JpegColorType.Rgb,
new JpegComponentConfig[] new JpegComponentConfig[]
{ {
new JpegComponentConfig(id: 82, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0), new(id: 82, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 71, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0), new(id: 71, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 66, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0), new(id: 66, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
}, },
new JpegHuffmanTableConfig[] new JpegHuffmanTableConfig[]
{ {
@ -144,15 +144,15 @@ internal sealed unsafe partial class JpegEncoderCore
}, },
// Cmyk // Cmyk
new JpegFrameConfig( new(
JpegColorSpace.Cmyk, JpegColorSpace.Cmyk,
JpegColorType.Cmyk, JpegColorType.Cmyk,
new JpegComponentConfig[] new JpegComponentConfig[]
{ {
new JpegComponentConfig(id: 1, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0), new(id: 1, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0), new(id: 2, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0), new(id: 3, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 4, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0), new(id: 4, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
}, },
new JpegHuffmanTableConfig[] new JpegHuffmanTableConfig[]
{ {
@ -168,15 +168,15 @@ internal sealed unsafe partial class JpegEncoderCore
}, },
// YccK // YccK
new JpegFrameConfig( new(
JpegColorSpace.Ycck, JpegColorSpace.Ycck,
JpegColorType.Ycck, JpegColorType.Ycck,
new JpegComponentConfig[] new JpegComponentConfig[]
{ {
new JpegComponentConfig(id: 1, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0), new(id: 1, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 2, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0), new(id: 2, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 3, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0), new(id: 3, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
new JpegComponentConfig(id: 4, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0), new(id: 4, hsf: 1, vsf: 1, quantIndex: 0, dcIndex: 0, acIndex: 0),
}, },
new JpegHuffmanTableConfig[] new JpegHuffmanTableConfig[]
{ {

2
src/ImageSharp/Formats/Jpeg/JpegFormat.cs

@ -15,7 +15,7 @@ public sealed class JpegFormat : IImageFormat<JpegMetadata>
/// <summary> /// <summary>
/// Gets the shared instance. /// Gets the shared instance.
/// </summary> /// </summary>
public static JpegFormat Instance { get; } = new JpegFormat(); public static JpegFormat Instance { get; } = new();
/// <inheritdoc/> /// <inheritdoc/>
public string Name => "JPEG"; public string Name => "JPEG";

2
src/ImageSharp/Formats/Pbm/PbmDecoderCore.cs

@ -80,7 +80,7 @@ internal sealed class PbmDecoderCore : ImageDecoderCore
{ {
this.ProcessHeader(stream); this.ProcessHeader(stream);
return new ImageInfo( return new ImageInfo(
new(this.pixelSize.Width, this.pixelSize.Height), new Size(this.pixelSize.Width, this.pixelSize.Height),
this.metadata); this.metadata);
} }

2
src/ImageSharp/Formats/Png/PngDecoder.cs

@ -25,7 +25,7 @@ public sealed class PngDecoder : SpecializedImageDecoder<PngDecoderOptions>
Guard.NotNull(options, nameof(options)); Guard.NotNull(options, nameof(options));
Guard.NotNull(stream, nameof(stream)); Guard.NotNull(stream, nameof(stream));
return new PngDecoderCore(new PngDecoderOptions() { GeneralOptions = options }).Identify(options.Configuration, stream, cancellationToken); return new PngDecoderCore(new PngDecoderOptions { GeneralOptions = options }).Identify(options.Configuration, stream, cancellationToken);
} }
/// <inheritdoc/> /// <inheritdoc/>

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

@ -248,7 +248,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore
break; break;
case PngChunkType.Data: case PngChunkType.Data:
pngMetadata.AnimateRootFrame = currentFrameControl != null; pngMetadata.AnimateRootFrame = currentFrameControl != null;
currentFrameControl ??= new((uint)this.header.Width, (uint)this.header.Height); currentFrameControl ??= new FrameControl((uint)this.header.Width, (uint)this.header.Height);
if (image is null) if (image is null)
{ {
this.InitializeImage(metadata, currentFrameControl.Value, out image); this.InitializeImage(metadata, currentFrameControl.Value, out image);
@ -433,7 +433,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore
} }
pngMetadata.AnimateRootFrame = currentFrameControl != null; pngMetadata.AnimateRootFrame = currentFrameControl != null;
currentFrameControl ??= new((uint)this.header.Width, (uint)this.header.Height); currentFrameControl ??= new FrameControl((uint)this.header.Width, (uint)this.header.Height);
if (framesMetadata.Count == 0) if (framesMetadata.Count == 0)
{ {
InitializeFrameMetadata(framesMetadata, currentFrameControl.Value); InitializeFrameMetadata(framesMetadata, currentFrameControl.Value);
@ -525,7 +525,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore
PngThrowHelper.ThrowInvalidHeader(); PngThrowHelper.ThrowInvalidHeader();
} }
return new ImageInfo(new(this.header.Width, this.header.Height), metadata, framesMetadata); return new ImageInfo(new Size(this.header.Width, this.header.Height), metadata, framesMetadata);
} }
finally finally
{ {
@ -1343,7 +1343,7 @@ internal sealed class PngDecoderCore : ImageDecoderCore
pngMetadata.InterlaceMethod = this.header.InterlaceMethod; pngMetadata.InterlaceMethod = this.header.InterlaceMethod;
this.pngColorType = this.header.ColorType; this.pngColorType = this.header.ColorType;
this.Dimensions = new(this.header.Width, this.header.Height); this.Dimensions = new Size(this.header.Width, this.header.Height);
} }
/// <summary> /// <summary>

2
src/ImageSharp/Formats/Png/PngDecoderOptions.cs

@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Formats.Png;
public sealed class PngDecoderOptions : ISpecializedDecoderOptions public sealed class PngDecoderOptions : ISpecializedDecoderOptions
{ {
/// <inheritdoc/> /// <inheritdoc/>
public DecoderOptions GeneralOptions { get; init; } = new DecoderOptions(); public DecoderOptions GeneralOptions { get; init; } = new();
/// <summary> /// <summary>
/// Gets the maximum memory in bytes that a zTXt, sPLT, iTXt, iCCP, or unknown chunk can occupy when decompressed. /// Gets the maximum memory in bytes that a zTXt, sPLT, iTXt, iCCP, or unknown chunk can occupy when decompressed.

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

@ -265,7 +265,7 @@ internal sealed class PngEncoderCore : IDisposable
{ {
// Use the previously derived global palette and a shared quantizer to // Use the previously derived global palette and a shared quantizer to
// quantize the subsequent frames. This allows us to cache the color matching resolution. // quantize the subsequent frames. This allows us to cache the color matching resolution.
paletteQuantizer ??= new( paletteQuantizer ??= new PaletteQuantizer<TPixel>(
this.configuration, this.configuration,
this.quantizer!.Options, this.quantizer!.Options,
previousPalette); previousPalette);

2
src/ImageSharp/Formats/Png/PngFormat.cs

@ -15,7 +15,7 @@ public sealed class PngFormat : IImageFormat<PngMetadata, PngFrameMetadata>
/// <summary> /// <summary>
/// Gets the shared instance. /// Gets the shared instance.
/// </summary> /// </summary>
public static PngFormat Instance { get; } = new PngFormat(); public static PngFormat Instance { get; } = new();
/// <inheritdoc/> /// <inheritdoc/>
public string Name => "PNG"; public string Name => "PNG";

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

@ -63,7 +63,7 @@ public class PngFrameMetadata : IFormatFrameMetadata<PngFrameMetadata>
public static PngFrameMetadata FromFormatConnectingFrameMetadata(FormatConnectingFrameMetadata metadata) public static PngFrameMetadata FromFormatConnectingFrameMetadata(FormatConnectingFrameMetadata metadata)
=> new() => new()
{ {
FrameDelay = new(metadata.Duration.TotalMilliseconds / 1000), FrameDelay = new Rational(metadata.Duration.TotalMilliseconds / 1000),
DisposalMode = GetMode(metadata.DisposalMode), DisposalMode = GetMode(metadata.DisposalMode),
BlendMode = metadata.BlendMode, BlendMode = metadata.BlendMode,
}; };
@ -77,7 +77,7 @@ public class PngFrameMetadata : IFormatFrameMetadata<PngFrameMetadata>
delay = 0; delay = 0;
} }
return new() return new FormatConnectingFrameMetadata
{ {
ColorTableMode = FrameColorTableMode.Global, ColorTableMode = FrameColorTableMode.Global,
Duration = TimeSpan.FromMilliseconds(delay * 1000), Duration = TimeSpan.FromMilliseconds(delay * 1000),

2
src/ImageSharp/Formats/Png/PngMetadata.cs

@ -130,7 +130,7 @@ public class PngMetadata : IFormatMetadata<PngMetadata>
4 => PngBitDepth.Bit4, 4 => PngBitDepth.Bit4,
_ => (bpc <= 8) ? PngBitDepth.Bit8 : PngBitDepth.Bit16, _ => (bpc <= 8) ? PngBitDepth.Bit8 : PngBitDepth.Bit16,
}; };
return new() return new PngMetadata
{ {
ColorType = color, ColorType = color,
BitDepth = bitDepth, BitDepth = bitDepth,

12
src/ImageSharp/Formats/Png/PngScanlineProcessor.cs

@ -133,7 +133,7 @@ internal static class PngScanlineProcessor
ushort l = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o, 2)); ushort l = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o, 2));
ushort a = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + 2, 2)); ushort a = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + 2, 2));
Unsafe.Add(ref rowSpanRef, (uint)x) = TPixel.FromLa32(new(l, a)); Unsafe.Add(ref rowSpanRef, (uint)x) = TPixel.FromLa32(new La32(l, a));
} }
} }
else else
@ -143,7 +143,7 @@ internal static class PngScanlineProcessor
{ {
byte l = Unsafe.Add(ref scanlineSpanRef, offset2); byte l = Unsafe.Add(ref scanlineSpanRef, offset2);
byte a = Unsafe.Add(ref scanlineSpanRef, offset2 + bytesPerSample); byte a = Unsafe.Add(ref scanlineSpanRef, offset2 + bytesPerSample);
Unsafe.Add(ref rowSpanRef, x) = TPixel.FromLa16(new(l, a)); Unsafe.Add(ref rowSpanRef, x) = TPixel.FromLa16(new La16(l, a));
offset2 += bytesPerPixel; offset2 += bytesPerPixel;
} }
} }
@ -239,7 +239,7 @@ internal static class PngScanlineProcessor
ushort r = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o, bytesPerSample)); ushort r = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o, bytesPerSample));
ushort g = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + bytesPerSample, bytesPerSample)); ushort g = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + bytesPerSample, bytesPerSample));
ushort b = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + (2 * bytesPerSample), bytesPerSample)); ushort b = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + (2 * bytesPerSample), bytesPerSample));
Unsafe.Add(ref rowSpanRef, x) = TPixel.FromRgb48(new(r, g, b)); Unsafe.Add(ref rowSpanRef, x) = TPixel.FromRgb48(new Rgb48(r, g, b));
} }
} }
else if (pixelOffset == 0 && increment == 1) else if (pixelOffset == 0 && increment == 1)
@ -258,7 +258,7 @@ internal static class PngScanlineProcessor
byte r = Unsafe.Add(ref scanlineSpanRef, (uint)o); byte r = Unsafe.Add(ref scanlineSpanRef, (uint)o);
byte g = Unsafe.Add(ref scanlineSpanRef, (uint)(o + bytesPerSample)); byte g = Unsafe.Add(ref scanlineSpanRef, (uint)(o + bytesPerSample));
byte b = Unsafe.Add(ref scanlineSpanRef, (uint)(o + (2 * bytesPerSample))); byte b = Unsafe.Add(ref scanlineSpanRef, (uint)(o + (2 * bytesPerSample)));
Unsafe.Add(ref rowSpanRef, x) = TPixel.FromRgb24(new(r, g, b)); Unsafe.Add(ref rowSpanRef, x) = TPixel.FromRgb24(new Rgb24(r, g, b));
} }
} }
@ -339,7 +339,7 @@ internal static class PngScanlineProcessor
ushort g = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + bytesPerSample, bytesPerSample)); ushort g = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + bytesPerSample, bytesPerSample));
ushort b = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + (2 * bytesPerSample), bytesPerSample)); ushort b = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + (2 * bytesPerSample), bytesPerSample));
ushort a = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + (3 * bytesPerSample), bytesPerSample)); ushort a = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + (3 * bytesPerSample), bytesPerSample));
Unsafe.Add(ref rowSpanRef, x) = TPixel.FromRgba64(new(r, g, b, a)); Unsafe.Add(ref rowSpanRef, x) = TPixel.FromRgba64(new Rgba64(r, g, b, a));
} }
} }
else if (pixelOffset == 0 && increment == 1) else if (pixelOffset == 0 && increment == 1)
@ -360,7 +360,7 @@ internal static class PngScanlineProcessor
byte g = Unsafe.Add(ref scanlineSpanRef, (uint)(o + bytesPerSample)); byte g = Unsafe.Add(ref scanlineSpanRef, (uint)(o + bytesPerSample));
byte b = Unsafe.Add(ref scanlineSpanRef, (uint)(o + (2 * bytesPerSample))); byte b = Unsafe.Add(ref scanlineSpanRef, (uint)(o + (2 * bytesPerSample)));
byte a = Unsafe.Add(ref scanlineSpanRef, (uint)(o + (3 * bytesPerSample))); byte a = Unsafe.Add(ref scanlineSpanRef, (uint)(o + (3 * bytesPerSample)));
Unsafe.Add(ref rowSpanRef, x) = TPixel.FromRgba32(new(r, g, b, a)); Unsafe.Add(ref rowSpanRef, x) = TPixel.FromRgba32(new Rgba32(r, g, b, a));
} }
} }
} }

2
src/ImageSharp/Formats/Qoi/QoiFormat.cs

@ -15,7 +15,7 @@ public sealed class QoiFormat : IImageFormat<QoiMetadata>
/// <summary> /// <summary>
/// Gets the shared instance. /// Gets the shared instance.
/// </summary> /// </summary>
public static QoiFormat Instance { get; } = new QoiFormat(); public static QoiFormat Instance { get; } = new();
/// <inheritdoc/> /// <inheritdoc/>
public string DefaultMimeType => "image/qoi"; public string DefaultMimeType => "image/qoi";

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

@ -639,7 +639,7 @@ internal sealed class TgaDecoderCore : ImageDecoderCore
{ {
this.ReadFileHeader(stream); this.ReadFileHeader(stream);
return new ImageInfo( return new ImageInfo(
new(this.fileHeader.Width, this.fileHeader.Height), new Size(this.fileHeader.Width, this.fileHeader.Height),
this.metadata); this.metadata);
} }

2
src/ImageSharp/Formats/Tga/TgaFormat.cs

@ -11,7 +11,7 @@ public sealed class TgaFormat : IImageFormat<TgaMetadata>
/// <summary> /// <summary>
/// Gets the shared instance. /// Gets the shared instance.
/// </summary> /// </summary>
public static TgaFormat Instance { get; } = new TgaFormat(); public static TgaFormat Instance { get; } = new();
/// <inheritdoc/> /// <inheritdoc/>
public string Name => "TGA"; public string Name => "TGA";

2
src/ImageSharp/Formats/Tga/TgaImageFormatDetector.cs

@ -34,7 +34,7 @@ public sealed class TgaImageFormatDetector : IImageFormatDetector
} }
// The third byte is the image type. // The third byte is the image type.
var imageType = (TgaImageType)header[2]; TgaImageType imageType = (TgaImageType)header[2];
if (!imageType.IsValid()) if (!imageType.IsValid())
{ {
return false; return false;

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

@ -11,7 +11,7 @@ internal sealed class DeflateCompressor : TiffBaseCompressor
{ {
private readonly DeflateCompressionLevel compressionLevel; private readonly DeflateCompressionLevel compressionLevel;
private readonly MemoryStream memoryStream = new MemoryStream(); private readonly MemoryStream memoryStream = new();
public DeflateCompressor(Stream output, MemoryAllocator allocator, int width, int bitsPerPixel, TiffPredictor predictor, DeflateCompressionLevel compressionLevel) public DeflateCompressor(Stream output, MemoryAllocator allocator, int width, int bitsPerPixel, TiffPredictor predictor, DeflateCompressionLevel compressionLevel)
: base(output, allocator, width, bitsPerPixel, predictor) : base(output, allocator, width, bitsPerPixel, predictor)
@ -29,7 +29,7 @@ internal sealed class DeflateCompressor : TiffBaseCompressor
public override void CompressStrip(Span<byte> rows, int height) public override void CompressStrip(Span<byte> rows, int height)
{ {
this.memoryStream.Seek(0, SeekOrigin.Begin); this.memoryStream.Seek(0, SeekOrigin.Begin);
using (var stream = new ZlibDeflateStream(this.Allocator, this.memoryStream, this.compressionLevel)) using (ZlibDeflateStream stream = new(this.Allocator, this.memoryStream, this.compressionLevel))
{ {
if (this.Predictor == TiffPredictor.Horizontal) if (this.Predictor == TiffPredictor.Horizontal)
{ {

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

@ -101,7 +101,7 @@ internal static class PackBitsWriter
private static int FindRunLength(ReadOnlySpan<byte> rowSpan, int startPos, int maxRunLength) private static int FindRunLength(ReadOnlySpan<byte> rowSpan, int startPos, int maxRunLength)
{ {
var startByte = rowSpan[startPos]; byte startByte = rowSpan[startPos];
int count = 1; int count = 1;
for (int i = startPos + 1; i < rowSpan.Length; i++) for (int i = startPos + 1; i < rowSpan.Length; i++)
{ {

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

@ -29,8 +29,8 @@ internal class TiffJpegCompressor : TiffBaseCompressor
int pixelCount = rows.Length / 3; int pixelCount = rows.Length / 3;
int width = pixelCount / height; int width = pixelCount / height;
using var memoryStream = new MemoryStream(); using MemoryStream memoryStream = new();
var image = Image.LoadPixelData<Rgb24>(rows, width, height); Image<Rgb24> image = Image.LoadPixelData<Rgb24>(rows, width, height);
image.Save(memoryStream, new JpegEncoder() image.Save(memoryStream, new JpegEncoder()
{ {
ColorType = JpegColorType.Rgb ColorType = JpegColorType.Rgb

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

@ -54,7 +54,7 @@ internal sealed class DeflateTiffCompression : TiffBaseDecompressor
protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span<byte> buffer, CancellationToken cancellationToken) protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span<byte> buffer, CancellationToken cancellationToken)
{ {
long pos = stream.Position; long pos = stream.Position;
using (var deframeStream = new ZlibInflateStream( using (ZlibInflateStream deframeStream = new(
stream, stream,
() => () =>
{ {

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

@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors;
/// </summary> /// </summary>
public class LzwString public class LzwString
{ {
private static readonly LzwString Empty = new LzwString(0, 0, 0, null); private static readonly LzwString Empty = new(0, 0, 0, null);
private readonly LzwString previous; private readonly LzwString previous;
private readonly byte value; private readonly byte value;

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

@ -48,7 +48,7 @@ internal sealed class LzwTiffCompression : TiffBaseDecompressor
/// <inheritdoc/> /// <inheritdoc/>
protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span<byte> buffer, CancellationToken cancellationToken) protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span<byte> buffer, CancellationToken cancellationToken)
{ {
var decoder = new TiffLzwDecoder(stream); TiffLzwDecoder decoder = new(stream);
decoder.DecodePixels(buffer); decoder.DecodePixels(buffer);
if (this.Predictor == TiffPredictor.Horizontal) if (this.Predictor == TiffPredictor.Horizontal)

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

@ -41,7 +41,7 @@ internal sealed class ModifiedHuffmanTiffCompression : TiffBaseDecompressor
/// <inheritdoc/> /// <inheritdoc/>
protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span<byte> buffer, CancellationToken cancellationToken) protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span<byte> buffer, CancellationToken cancellationToken)
{ {
var bitReader = new ModifiedHuffmanBitReader(stream, this.FillOrder, byteCount); ModifiedHuffmanBitReader bitReader = new(stream, this.FillOrder, byteCount);
buffer.Clear(); buffer.Clear();
nint bitsWritten = 0; nint bitsWritten = 0;

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

@ -60,7 +60,7 @@ internal sealed class T4TiffCompression : TiffBaseDecompressor
} }
bool eolPadding = this.faxCompressionOptions.HasFlag(FaxCompressionOptions.EolPadding); bool eolPadding = this.faxCompressionOptions.HasFlag(FaxCompressionOptions.EolPadding);
var bitReader = new T4BitReader(stream, this.FillOrder, byteCount, eolPadding); T4BitReader bitReader = new(stream, this.FillOrder, byteCount, eolPadding);
buffer.Clear(); buffer.Clear();
nint bitsWritten = 0; nint bitsWritten = 0;

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

@ -57,9 +57,9 @@ internal sealed class T6TiffCompression : TiffBaseDecompressor
Span<byte> scanLine = scanLineBuffer.GetSpan()[..this.width]; Span<byte> scanLine = scanLineBuffer.GetSpan()[..this.width];
Span<byte> referenceScanLineSpan = scanLineBuffer.GetSpan().Slice(this.width, this.width); Span<byte> referenceScanLineSpan = scanLineBuffer.GetSpan().Slice(this.width, this.width);
var bitReader = new T6BitReader(stream, this.FillOrder, byteCount); T6BitReader bitReader = new(stream, this.FillOrder, byteCount);
var referenceScanLine = new CcittReferenceScanline(this.isWhiteZero, this.width); CcittReferenceScanline referenceScanLine = new(this.isWhiteZero, this.width);
nint bitsWritten = 0; nint bitsWritten = 0;
for (int y = 0; y < height; y++) for (int y = 0; y < height; y++)
{ {

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

@ -32,7 +32,7 @@ internal class WebpTiffCompression : TiffBaseDecompressor
/// <inheritdoc/> /// <inheritdoc/>
protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span<byte> buffer, CancellationToken cancellationToken) protected override void Decompress(BufferedReadStream stream, int byteCount, int stripHeight, Span<byte> buffer, CancellationToken cancellationToken)
{ {
using WebpDecoderCore decoder = new(new WebpDecoderOptions() { GeneralOptions = this.options }); using WebpDecoderCore decoder = new(new WebpDecoderOptions { GeneralOptions = this.options });
using Image<Rgb24> image = decoder.Decode<Rgb24>(this.options.Configuration, stream, cancellationToken); using Image<Rgb24> image = decoder.Decode<Rgb24>(this.options.Configuration, stream, cancellationToken);
CopyImageBytesToBuffer(buffer, image.Frames.RootFrame.PixelBuffer); CopyImageBytesToBuffer(buffer, image.Frames.RootFrame.PixelBuffer);
} }

5
src/ImageSharp/Formats/Tiff/Compression/TiffDecompressorsFactory.cs

@ -1,6 +1,7 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors; using SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors;
using SixLabors.ImageSharp.Formats.Tiff.Constants; using SixLabors.ImageSharp.Formats.Tiff.Constants;
using SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation; using SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation;
@ -64,11 +65,11 @@ internal static class TiffDecompressorsFactory
case TiffDecoderCompressionType.Jpeg: case TiffDecoderCompressionType.Jpeg:
DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression"); DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression");
return new JpegTiffCompression(new() { GeneralOptions = options }, allocator, width, bitsPerPixel, metadata, jpegTables, photometricInterpretation); return new JpegTiffCompression(new JpegDecoderOptions { GeneralOptions = options }, allocator, width, bitsPerPixel, metadata, jpegTables, photometricInterpretation);
case TiffDecoderCompressionType.OldJpeg: case TiffDecoderCompressionType.OldJpeg:
DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression"); DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression");
return new OldJpegTiffCompression(new() { GeneralOptions = options }, allocator, width, bitsPerPixel, metadata, oldJpegStartOfImageMarker, photometricInterpretation); return new OldJpegTiffCompression(new JpegDecoderOptions { GeneralOptions = options }, allocator, width, bitsPerPixel, metadata, oldJpegStartOfImageMarker, photometricInterpretation);
case TiffDecoderCompressionType.Webp: case TiffDecoderCompressionType.Webp:
DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression"); DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression");

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

@ -47,7 +47,7 @@ internal class BlackIsZero16TiffColor<TPixel> : TiffBaseColorDecoder<TPixel>
ushort intensity = TiffUtilities.ConvertToUShortBigEndian(data.Slice(offset, 2)); ushort intensity = TiffUtilities.ConvertToUShortBigEndian(data.Slice(offset, 2));
offset += 2; offset += 2;
pixelRow[x] = TPixel.FromL16(new(intensity)); pixelRow[x] = TPixel.FromL16(new L16(intensity));
} }
} }
else else

6
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero4TiffColor{TPixel}.cs

@ -25,14 +25,14 @@ internal class BlackIsZero4TiffColor<TPixel> : TiffBaseColorDecoder<TPixel>
for (int x = left; x < left + width - 1;) for (int x = left; x < left + width - 1;)
{ {
byte byteData = data[offset++]; byte byteData = data[offset++];
pixelRowSpan[x++] = TPixel.FromL8(new((byte)(((byteData & 0xF0) >> 4) * 17))); pixelRowSpan[x++] = TPixel.FromL8(new L8((byte)(((byteData & 0xF0) >> 4) * 17)));
pixelRowSpan[x++] = TPixel.FromL8(new((byte)((byteData & 0x0F) * 17))); pixelRowSpan[x++] = TPixel.FromL8(new L8((byte)((byteData & 0x0F) * 17)));
} }
if (isOddWidth) if (isOddWidth)
{ {
byte byteData = data[offset++]; byte byteData = data[offset++];
pixelRowSpan[left + width - 1] = TPixel.FromL8(new((byte)(((byteData & 0xF0) >> 4) * 17))); pixelRowSpan[left + width - 1] = TPixel.FromL8(new L8((byte)(((byteData & 0xF0) >> 4) * 17)));
} }
} }
} }

3
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZeroTiffColor{TPixel}.cs

@ -1,6 +1,7 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
using System.Numerics;
using SixLabors.ImageSharp.Formats.Tiff.Utils; using SixLabors.ImageSharp.Formats.Tiff.Utils;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -35,7 +36,7 @@ internal class BlackIsZeroTiffColor<TPixel> : TiffBaseColorDecoder<TPixel>
{ {
int value = bitReader.ReadBits(this.bitsPerSample0); int value = bitReader.ReadBits(this.bitsPerSample0);
float intensity = value / this.factor; float intensity = value / this.factor;
pixelRow[x] = TPixel.FromScaledVector4(new(intensity, intensity, intensity, 1f)); pixelRow[x] = TPixel.FromScaledVector4(new Vector4(intensity, intensity, intensity, 1f));
} }
bitReader.NextRow(); bitReader.NextRow();

3
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/CieLabPlanarTiffColor{TPixel}.cs

@ -2,6 +2,7 @@
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
using System.Buffers; using System.Buffers;
using System.Numerics;
using SixLabors.ImageSharp.ColorProfiles; using SixLabors.ImageSharp.ColorProfiles;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -34,7 +35,7 @@ internal class CieLabPlanarTiffColor<TPixel> : TiffBasePlanarColorDecoder<TPixel
{ {
CieLab lab = new((l[offset] & 0xFF) * 100f * Inv255, (sbyte)a[offset], (sbyte)b[offset]); CieLab lab = new((l[offset] & 0xFF) * 100f * Inv255, (sbyte)a[offset], (sbyte)b[offset]);
Rgb rgb = ColorProfileConverter.Convert<CieLab, Rgb>(in lab); Rgb rgb = ColorProfileConverter.Convert<CieLab, Rgb>(in lab);
pixelRow[x] = TPixel.FromScaledVector4(new(rgb.R, rgb.G, rgb.B, 1.0f)); pixelRow[x] = TPixel.FromScaledVector4(new Vector4(rgb.R, rgb.G, rgb.B, 1.0f));
offset++; offset++;
} }

3
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/CieLabTiffColor{TPixel}.cs

@ -1,6 +1,7 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
using System.Numerics;
using SixLabors.ImageSharp.ColorProfiles; using SixLabors.ImageSharp.ColorProfiles;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -30,7 +31,7 @@ internal class CieLabTiffColor<TPixel> : TiffBaseColorDecoder<TPixel>
float l = (data[offset] & 0xFF) * 100f * Inv255; float l = (data[offset] & 0xFF) * 100f * Inv255;
CieLab lab = new(l, (sbyte)data[offset + 1], (sbyte)data[offset + 2]); CieLab lab = new(l, (sbyte)data[offset + 1], (sbyte)data[offset + 2]);
Rgb rgb = ColorProfileConverter.Convert<CieLab, Rgb>(in lab); Rgb rgb = ColorProfileConverter.Convert<CieLab, Rgb>(in lab);
pixelRow[x] = TPixel.FromScaledVector4(new(rgb.R, rgb.G, rgb.B, 1f)); pixelRow[x] = TPixel.FromScaledVector4(new Vector4(rgb.R, rgb.G, rgb.B, 1f));
offset += 3; offset += 3;
} }

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

@ -47,7 +47,7 @@ internal class CmykTiffColor<TPixel> : TiffBaseColorDecoder<TPixel>
{ {
Cmyk cmyk = new(data[offset] * Inv255, data[offset + 1] * Inv255, data[offset + 2] * Inv255, data[offset + 3] * Inv255); Cmyk cmyk = new(data[offset] * Inv255, data[offset + 1] * Inv255, data[offset + 2] * Inv255, data[offset + 3] * Inv255);
Rgb rgb = ColorProfileConverter.Convert<Cmyk, Rgb>(in cmyk); Rgb rgb = ColorProfileConverter.Convert<Cmyk, Rgb>(in cmyk);
pixelRow[x] = TPixel.FromScaledVector4(new(rgb.R, rgb.G, rgb.B, 1.0f)); pixelRow[x] = TPixel.FromScaledVector4(new Vector4(rgb.R, rgb.G, rgb.B, 1.0f));
offset += 4; offset += 4;
} }

3
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/PaletteTiffColor{TPixel}.cs

@ -1,6 +1,7 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
using System.Numerics;
using SixLabors.ImageSharp.Formats.Tiff.Utils; using SixLabors.ImageSharp.Formats.Tiff.Utils;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -63,7 +64,7 @@ internal class PaletteTiffColor<TPixel> : TiffBaseColorDecoder<TPixel>
float r = colorMap[rOffset + i] * InvMax; float r = colorMap[rOffset + i] * InvMax;
float g = colorMap[gOffset + i] * InvMax; float g = colorMap[gOffset + i] * InvMax;
float b = colorMap[bOffset + i] * InvMax; float b = colorMap[bOffset + i] * InvMax;
palette[i] = TPixel.FromScaledVector4(new(r, g, b, 1f)); palette[i] = TPixel.FromScaledVector4(new Vector4(r, g, b, 1f));
} }
return palette; return palette;

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

@ -48,7 +48,7 @@ internal class Rgb161616TiffColor<TPixel> : TiffBaseColorDecoder<TPixel>
ushort b = TiffUtilities.ConvertToUShortBigEndian(data.Slice(offset, 2)); ushort b = TiffUtilities.ConvertToUShortBigEndian(data.Slice(offset, 2));
offset += 2; offset += 2;
pixelRow[x] = TPixel.FromRgb48(new(r, g, b)); pixelRow[x] = TPixel.FromRgb48(new Rgb48(r, g, b));
} }
} }
else else

4
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb16PlanarTiffColor{TPixel}.cs

@ -44,7 +44,7 @@ internal class Rgb16PlanarTiffColor<TPixel> : TiffBasePlanarColorDecoder<TPixel>
offset += 2; offset += 2;
pixelRow[x] = TPixel.FromRgb48(new(r, g, b)); pixelRow[x] = TPixel.FromRgb48(new Rgb48(r, g, b));
} }
} }
else else
@ -57,7 +57,7 @@ internal class Rgb16PlanarTiffColor<TPixel> : TiffBasePlanarColorDecoder<TPixel>
offset += 2; offset += 2;
pixelRow[x] = TPixel.FromRgb48(new(r, g, b)); pixelRow[x] = TPixel.FromRgb48(new Rgb48(r, g, b));
} }
} }
} }

5
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbFloat323232TiffColor{TPixel}.cs

@ -1,6 +1,7 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
using System.Numerics;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -50,7 +51,7 @@ internal class RgbFloat323232TiffColor<TPixel> : TiffBaseColorDecoder<TPixel>
float b = BitConverter.ToSingle(buffer); float b = BitConverter.ToSingle(buffer);
offset += 4; offset += 4;
pixelRow[x] = TPixel.FromScaledVector4(new(r, g, b, 1f)); pixelRow[x] = TPixel.FromScaledVector4(new Vector4(r, g, b, 1f));
} }
} }
else else
@ -66,7 +67,7 @@ internal class RgbFloat323232TiffColor<TPixel> : TiffBaseColorDecoder<TPixel>
float b = BitConverter.ToSingle(data.Slice(offset, 4)); float b = BitConverter.ToSingle(data.Slice(offset, 4));
offset += 4; offset += 4;
pixelRow[x] = TPixel.FromScaledVector4(new(r, g, b, 1f)); pixelRow[x] = TPixel.FromScaledVector4(new Vector4(r, g, b, 1f));
} }
} }
} }

3
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbPlanarTiffColor{TPixel}.cs

@ -2,6 +2,7 @@
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
using System.Buffers; using System.Buffers;
using System.Numerics;
using SixLabors.ImageSharp.Formats.Tiff.Utils; using SixLabors.ImageSharp.Formats.Tiff.Utils;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -62,7 +63,7 @@ internal class RgbPlanarTiffColor<TPixel> : TiffBasePlanarColorDecoder<TPixel>
float g = gBitReader.ReadBits(this.bitsPerSampleG) / this.gFactor; float g = gBitReader.ReadBits(this.bitsPerSampleG) / this.gFactor;
float b = bBitReader.ReadBits(this.bitsPerSampleB) / this.bFactor; float b = bBitReader.ReadBits(this.bitsPerSampleB) / this.bFactor;
pixelRow[x] = TPixel.FromScaledVector4(new(r, g, b, 1f)); pixelRow[x] = TPixel.FromScaledVector4(new Vector4(r, g, b, 1f));
} }
rBitReader.NextRow(); rBitReader.NextRow();

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

@ -67,7 +67,7 @@ internal class Rgba16161616TiffColor<TPixel> : TiffBaseColorDecoder<TPixel>
pixelRow[x] = hasAssociatedAlpha pixelRow[x] = hasAssociatedAlpha
? TiffUtilities.ColorFromRgba64Premultiplied<TPixel>(r, g, b, a) ? TiffUtilities.ColorFromRgba64Premultiplied<TPixel>(r, g, b, a)
: TPixel.FromRgba64(new(r, g, b, a)); : TPixel.FromRgba64(new Rgba64(r, g, b, a));
} }
} }
else else

4
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgba16PlanarTiffColor{TPixel}.cs

@ -56,7 +56,7 @@ internal class Rgba16PlanarTiffColor<TPixel> : TiffBasePlanarColorDecoder<TPixel
pixelRow[x] = hasAssociatedAlpha pixelRow[x] = hasAssociatedAlpha
? TiffUtilities.ColorFromRgba64Premultiplied<TPixel>(r, g, b, a) ? TiffUtilities.ColorFromRgba64Premultiplied<TPixel>(r, g, b, a)
: TPixel.FromRgba64(new(r, g, b, a)); : TPixel.FromRgba64(new Rgba64(r, g, b, a));
} }
} }
else else
@ -72,7 +72,7 @@ internal class Rgba16PlanarTiffColor<TPixel> : TiffBasePlanarColorDecoder<TPixel
pixelRow[x] = hasAssociatedAlpha pixelRow[x] = hasAssociatedAlpha
? TiffUtilities.ColorFromRgba64Premultiplied<TPixel>(r, g, b, a) ? TiffUtilities.ColorFromRgba64Premultiplied<TPixel>(r, g, b, a)
: TPixel.FromRgba64(new(r, g, b, a)); : TPixel.FromRgba64(new Rgba64(r, g, b, a));
} }
} }
} }

5
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbaFloat32323232TiffColor{TPixel}.cs

@ -1,6 +1,7 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
using System.Numerics;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -55,7 +56,7 @@ internal class RgbaFloat32323232TiffColor<TPixel> : TiffBaseColorDecoder<TPixel>
float a = BitConverter.ToSingle(buffer); float a = BitConverter.ToSingle(buffer);
offset += 4; offset += 4;
pixelRow[x] = TPixel.FromScaledVector4(new(r, g, b, a)); pixelRow[x] = TPixel.FromScaledVector4(new Vector4(r, g, b, a));
} }
} }
else else
@ -74,7 +75,7 @@ internal class RgbaFloat32323232TiffColor<TPixel> : TiffBaseColorDecoder<TPixel>
float a = BitConverter.ToSingle(data.Slice(offset, 4)); float a = BitConverter.ToSingle(data.Slice(offset, 4));
offset += 4; offset += 4;
pixelRow[x] = TPixel.FromScaledVector4(new(r, g, b, a)); pixelRow[x] = TPixel.FromScaledVector4(new Vector4(r, g, b, a));
} }
} }
} }

4
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero16TiffColor{TPixel}.cs

@ -36,7 +36,7 @@ internal class WhiteIsZero16TiffColor<TPixel> : TiffBaseColorDecoder<TPixel>
ushort intensity = (ushort)(ushort.MaxValue - TiffUtilities.ConvertToUShortBigEndian(data.Slice(offset, 2))); ushort intensity = (ushort)(ushort.MaxValue - TiffUtilities.ConvertToUShortBigEndian(data.Slice(offset, 2)));
offset += 2; offset += 2;
pixelRow[x] = TPixel.FromL16(new(intensity)); pixelRow[x] = TPixel.FromL16(new L16(intensity));
} }
} }
else else
@ -46,7 +46,7 @@ internal class WhiteIsZero16TiffColor<TPixel> : TiffBaseColorDecoder<TPixel>
ushort intensity = (ushort)(ushort.MaxValue - TiffUtilities.ConvertToUShortLittleEndian(data.Slice(offset, 2))); ushort intensity = (ushort)(ushort.MaxValue - TiffUtilities.ConvertToUShortLittleEndian(data.Slice(offset, 2)));
offset += 2; offset += 2;
pixelRow[x] = TPixel.FromL16(new(intensity)); pixelRow[x] = TPixel.FromL16(new L16(intensity));
} }
} }
} }

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

@ -40,7 +40,7 @@ internal class WhiteIsZero32FloatTiffColor<TPixel> : TiffBaseColorDecoder<TPixel
float intensity = 1.0f - BitConverter.ToSingle(buffer); float intensity = 1.0f - BitConverter.ToSingle(buffer);
offset += 4; offset += 4;
pixelRow[x] = TPixel.FromScaledVector4(new(intensity, intensity, intensity, 1f)); pixelRow[x] = TPixel.FromScaledVector4(new Vector4(intensity, intensity, intensity, 1f));
} }
} }
else else

6
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero4TiffColor{TPixel}.cs

@ -25,14 +25,14 @@ internal class WhiteIsZero4TiffColor<TPixel> : TiffBaseColorDecoder<TPixel>
for (int x = left; x < left + width - 1;) for (int x = left; x < left + width - 1;)
{ {
byte byteData = data[offset++]; byte byteData = data[offset++];
pixelRowSpan[x++] = TPixel.FromL8(new((byte)((15 - ((byteData & 0xF0) >> 4)) * 17))); pixelRowSpan[x++] = TPixel.FromL8(new L8((byte)((15 - ((byteData & 0xF0) >> 4)) * 17)));
pixelRowSpan[x++] = TPixel.FromL8(new((byte)((15 - (byteData & 0x0F)) * 17))); pixelRowSpan[x++] = TPixel.FromL8(new L8((byte)((15 - (byteData & 0x0F)) * 17)));
} }
if (isOddWidth) if (isOddWidth)
{ {
byte byteData = data[offset++]; byte byteData = data[offset++];
pixelRowSpan[left + width - 1] = TPixel.FromL8(new((byte)((15 - ((byteData & 0xF0) >> 4)) * 17))); pixelRowSpan[left + width - 1] = TPixel.FromL8(new L8((byte)((15 - ((byteData & 0xF0) >> 4)) * 17)));
} }
} }
} }

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

@ -23,7 +23,7 @@ internal class WhiteIsZero8TiffColor<TPixel> : TiffBaseColorDecoder<TPixel>
for (int x = 0; x < pixelRow.Length; x++) for (int x = 0; x < pixelRow.Length; x++)
{ {
byte intensity = (byte)(byte.MaxValue - data[offset++]); byte intensity = (byte)(byte.MaxValue - data[offset++]);
pixelRow[x] = TPixel.FromL8(new(intensity)); pixelRow[x] = TPixel.FromL8(new L8(intensity));
} }
} }
} }

2
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/YCbCrConverter.cs

@ -107,7 +107,7 @@ internal class YCbCrConverter
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba32 Convert(float y, float cb, float cr) public Rgba32 Convert(float y, float cb, float cr)
{ {
var pixel = default(Rgba32); Rgba32 pixel = default(Rgba32);
pixel.R = RoundAndClampTo8Bit((cr * this.cr2R) + y); pixel.R = RoundAndClampTo8Bit((cr * this.cr2R) + y);
pixel.G = RoundAndClampTo8Bit((this.y2G * y) + (this.cr2G * cr) + (this.cb2G * cb)); pixel.G = RoundAndClampTo8Bit((this.y2G * y) + (this.cr2G * cr) + (this.cb2G * cb));
pixel.B = RoundAndClampTo8Bit((cb * this.cb2B) + y); pixel.B = RoundAndClampTo8Bit((cb * this.cb2B) + y);

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

@ -228,7 +228,7 @@ internal class TiffDecoderCore : ImageDecoderCore
ImageMetadata metadata = TiffDecoderMetadataCreator.Create(framesMetadata, this.skipMetadata, reader.ByteOrder, reader.IsBigTiff); ImageMetadata metadata = TiffDecoderMetadataCreator.Create(framesMetadata, this.skipMetadata, reader.ByteOrder, reader.IsBigTiff);
return new ImageInfo(new(width, height), metadata, framesMetadata); return new ImageInfo(new Size(width, height), metadata, framesMetadata);
} }
/// <summary> /// <summary>

2
src/ImageSharp/Formats/Tiff/TiffEncoderEntriesCollector.cs

@ -16,7 +16,7 @@ internal class TiffEncoderEntriesCollector
{ {
private const string SoftwareValue = "ImageSharp"; private const string SoftwareValue = "ImageSharp";
public List<IExifValue> Entries { get; } = new List<IExifValue>(); public List<IExifValue> Entries { get; } = new();
public void ProcessMetadata(Image image, bool skipMetadata) public void ProcessMetadata(Image image, bool skipMetadata)
=> new MetadataProcessor(this).Process(image, skipMetadata); => new MetadataProcessor(this).Process(image, skipMetadata);

6
src/ImageSharp/Formats/Tiff/TiffFormat.cs

@ -17,7 +17,7 @@ public sealed class TiffFormat : IImageFormat<TiffMetadata, TiffFrameMetadata>
/// <summary> /// <summary>
/// Gets the shared instance. /// Gets the shared instance.
/// </summary> /// </summary>
public static TiffFormat Instance { get; } = new TiffFormat(); public static TiffFormat Instance { get; } = new();
/// <inheritdoc/> /// <inheritdoc/>
public string Name => "TIFF"; public string Name => "TIFF";
@ -32,8 +32,8 @@ public sealed class TiffFormat : IImageFormat<TiffMetadata, TiffFrameMetadata>
public IEnumerable<string> FileExtensions => TiffConstants.FileExtensions; public IEnumerable<string> FileExtensions => TiffConstants.FileExtensions;
/// <inheritdoc/> /// <inheritdoc/>
public TiffMetadata CreateDefaultFormatMetadata() => new TiffMetadata(); public TiffMetadata CreateDefaultFormatMetadata() => new();
/// <inheritdoc/> /// <inheritdoc/>
public TiffFrameMetadata CreateDefaultFormatFrameMetadata() => new TiffFrameMetadata(); public TiffFrameMetadata CreateDefaultFormatFrameMetadata() => new();
} }

2
src/ImageSharp/Formats/Tiff/Utils/TiffUtilities.cs

@ -45,7 +45,7 @@ internal static class TiffUtilities
return TPixel.FromRgba64(default); return TPixel.FromRgba64(default);
} }
return TPixel.FromRgba64(new((ushort)(r / a), (ushort)(g / a), (ushort)(b / a), a)); return TPixel.FromRgba64(new Rgba64((ushort)(r / a), (ushort)(g / a), (ushort)(b / a), a));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]

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

@ -44,7 +44,7 @@ internal sealed class TiffPaletteWriter<TPixel> : TiffBaseColorWriter<TPixel>
this.colorPaletteBytes = this.colorPaletteSize * 2; this.colorPaletteBytes = this.colorPaletteSize * 2;
using IQuantizer<TPixel> frameQuantizer = quantizer.CreatePixelSpecificQuantizer<TPixel>( using IQuantizer<TPixel> frameQuantizer = quantizer.CreatePixelSpecificQuantizer<TPixel>(
this.Configuration, this.Configuration,
new QuantizerOptions() new QuantizerOptions
{ {
MaxColors = this.maxColors MaxColors = this.maxColors
}); });

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

@ -60,7 +60,7 @@ internal class AlphaDecoder : IDisposable
if (this.Compressed) if (this.Compressed)
{ {
Vp8LBitReader bitReader = new Vp8LBitReader(data); Vp8LBitReader bitReader = new(data);
this.LosslessDecoder = new WebpLosslessDecoder(bitReader, memoryAllocator, configuration); this.LosslessDecoder = new WebpLosslessDecoder(bitReader, memoryAllocator, configuration);
this.LosslessDecoder.DecodeImageStream(this.Vp8LDec, width, height, true); this.LosslessDecoder.DecodeImageStream(this.Vp8LDec, width, height, true);

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

@ -399,7 +399,7 @@ internal class Vp8BitWriter : BitWriterBase
int mbSize = this.enc.Mbw * this.enc.Mbh; int mbSize = this.enc.Mbw * this.enc.Mbh;
int expectedSize = (int)((uint)mbSize * 7 / 8); int expectedSize = (int)((uint)mbSize * 7 / 8);
Vp8BitWriter bitWriterPartZero = new Vp8BitWriter(expectedSize, this.enc); Vp8BitWriter bitWriterPartZero = new(expectedSize, this.enc);
// Partition #0 with header and partition sizes. // Partition #0 with header and partition sizes.
uint size0 = bitWriterPartZero.GeneratePartition0(); uint size0 = bitWriterPartZero.GeneratePartition0();
@ -545,7 +545,7 @@ internal class Vp8BitWriter : BitWriterBase
// Writes the partition #0 modes (that is: all intra modes) // Writes the partition #0 modes (that is: all intra modes)
private void CodeIntraModes() private void CodeIntraModes()
{ {
Vp8EncIterator it = new Vp8EncIterator(this.enc); Vp8EncIterator it = new(this.enc);
int predsWidth = this.enc.PredsWidth; int predsWidth = this.enc.PredsWidth;
do do

2
src/ImageSharp/Formats/Webp/Chunks/WebpFrameData.cs

@ -124,7 +124,7 @@ internal readonly struct WebpFrameData
{ {
Span<byte> buffer = stackalloc byte[4]; Span<byte> buffer = stackalloc byte[4];
return new( return new WebpFrameData(
dataSize: WebpChunkParsingUtils.ReadChunkSize(stream, buffer), dataSize: WebpChunkParsingUtils.ReadChunkSize(stream, buffer),
x: WebpChunkParsingUtils.ReadUInt24LittleEndian(stream, buffer) * 2, x: WebpChunkParsingUtils.ReadUInt24LittleEndian(stream, buffer) * 2,
y: WebpChunkParsingUtils.ReadUInt24LittleEndian(stream, buffer) * 2, y: WebpChunkParsingUtils.ReadUInt24LittleEndian(stream, buffer) * 2,

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

@ -149,9 +149,8 @@ internal static class BackwardReferenceEncoder
} }
// Find the cacheBits giving the lowest entropy. // Find the cacheBits giving the lowest entropy.
for (int idx = 0; idx < refs.Refs.Count; idx++) foreach (PixOrCopy v in refs)
{ {
PixOrCopy v = refs.Refs[idx];
if (v.IsLiteral()) if (v.IsLiteral())
{ {
uint pix = bgra[pos++]; uint pix = bgra[pos++];
@ -387,7 +386,7 @@ internal static class BackwardReferenceEncoder
colorCache = new ColorCache(cacheBits); colorCache = new ColorCache(cacheBits);
} }
backwardRefs.Refs.Clear(); backwardRefs.Clear();
for (int ix = 0; ix < chosenPathSize; ix++) for (int ix = 0; ix < chosenPathSize; ix++)
{ {
int len = chosenPath[ix]; int len = chosenPath[ix];
@ -479,7 +478,7 @@ internal static class BackwardReferenceEncoder
colorCache = new ColorCache(cacheBits); colorCache = new ColorCache(cacheBits);
} }
refs.Refs.Clear(); refs.Clear();
for (int i = 0; i < pixCount;) for (int i = 0; i < pixCount;)
{ {
// Alternative #1: Code the pixels starting at 'i' using backward reference. // Alternative #1: Code the pixels starting at 'i' using backward reference.
@ -734,7 +733,7 @@ internal static class BackwardReferenceEncoder
colorCache = new ColorCache(cacheBits); colorCache = new ColorCache(cacheBits);
} }
refs.Refs.Clear(); refs.Clear();
// Add first pixel as literal. // Add first pixel as literal.
AddSingleLiteral(bgra[0], useColorCache, colorCache, refs); AddSingleLiteral(bgra[0], useColorCache, colorCache, refs);
@ -779,10 +778,9 @@ internal static class BackwardReferenceEncoder
private static void BackwardRefsWithLocalCache(ReadOnlySpan<uint> bgra, int cacheBits, Vp8LBackwardRefs refs) private static void BackwardRefsWithLocalCache(ReadOnlySpan<uint> bgra, int cacheBits, Vp8LBackwardRefs refs)
{ {
int pixelIndex = 0; int pixelIndex = 0;
ColorCache colorCache = new ColorCache(cacheBits); ColorCache colorCache = new(cacheBits);
for (int idx = 0; idx < refs.Refs.Count; idx++) foreach (ref PixOrCopy v in refs)
{ {
PixOrCopy v = refs.Refs[idx];
if (v.IsLiteral()) if (v.IsLiteral())
{ {
uint bgraLiteral = v.BgraOrDistance; uint bgraLiteral = v.BgraOrDistance;
@ -790,9 +788,7 @@ internal static class BackwardReferenceEncoder
if (ix >= 0) if (ix >= 0)
{ {
// Color cache contains bgraLiteral // Color cache contains bgraLiteral
v.Mode = PixOrCopyMode.CacheIdx; v = PixOrCopy.CreateCacheIdx(ix);
v.BgraOrDistance = (uint)ix;
v.Len = 1;
} }
else else
{ {
@ -814,14 +810,13 @@ internal static class BackwardReferenceEncoder
private static void BackwardReferences2DLocality(int xSize, Vp8LBackwardRefs refs) private static void BackwardReferences2DLocality(int xSize, Vp8LBackwardRefs refs)
{ {
using List<PixOrCopy>.Enumerator c = refs.Refs.GetEnumerator(); foreach (ref PixOrCopy v in refs)
while (c.MoveNext())
{ {
if (c.Current.IsCopy()) if (v.IsCopy())
{ {
int dist = (int)c.Current.BgraOrDistance; int dist = (int)v.BgraOrDistance;
int transformedDist = DistanceToPlaneCode(xSize, dist); int transformedDist = DistanceToPlaneCode(xSize, dist);
c.Current.BgraOrDistance = (uint)transformedDist; v = PixOrCopy.CreateCopy((uint)transformedDist, v.Len);
} }
} }
} }

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

@ -17,7 +17,7 @@ internal sealed class CostManager : IDisposable
private const int FreeIntervalsStartCount = 25; private const int FreeIntervalsStartCount = 25;
private readonly Stack<CostInterval> freeIntervals = new Stack<CostInterval>(FreeIntervalsStartCount); private readonly Stack<CostInterval> freeIntervals = new(FreeIntervalsStartCount);
public CostManager(MemoryAllocator memoryAllocator, IMemoryOwner<ushort> distArray, int pixCount, CostModel costModel) public CostManager(MemoryAllocator memoryAllocator, IMemoryOwner<ushort> distArray, int pixCount, CostModel costModel)
{ {
@ -49,7 +49,7 @@ internal sealed class CostManager : IDisposable
} }
// Fill in the cache intervals. // Fill in the cache intervals.
var cur = new CostCacheInterval() CostCacheInterval cur = new()
{ {
Start = 0, Start = 0,
End = 1, End = 1,
@ -62,7 +62,7 @@ internal sealed class CostManager : IDisposable
double costVal = this.CostCache[i]; double costVal = this.CostCache[i];
if (costVal != cur.Cost) if (costVal != cur.Cost)
{ {
cur = new CostCacheInterval() cur = new CostCacheInterval
{ {
Start = i, Start = i,
Cost = costVal Cost = costVal
@ -258,7 +258,7 @@ internal sealed class CostManager : IDisposable
} }
else else
{ {
intervalNew = new CostInterval() { Cost = cost, Start = start, End = end, Index = position }; intervalNew = new CostInterval { Cost = cost, Start = start, End = end, Index = position };
} }
this.PositionOrphanInterval(intervalNew, intervalIn); this.PositionOrphanInterval(intervalNew, intervalIn);

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

@ -40,9 +40,9 @@ internal class CostModel
using OwnedVp8LHistogram histogram = OwnedVp8LHistogram.Create(this.memoryAllocator, cacheBits); using OwnedVp8LHistogram histogram = OwnedVp8LHistogram.Create(this.memoryAllocator, cacheBits);
// The following code is similar to HistogramCreate but converts the distance to plane code. // The following code is similar to HistogramCreate but converts the distance to plane code.
for (int i = 0; i < backwardRefs.Refs.Count; i++) foreach (PixOrCopy v in backwardRefs)
{ {
histogram.AddSinglePixOrCopy(backwardRefs.Refs[i], true, xSize); histogram.AddSinglePixOrCopy(in v, true, xSize);
} }
ConvertPopulationCountTableToBitEstimates(histogram.NumCodes(), histogram.Literal, this.Literal); ConvertPopulationCountTableToBitEstimates(histogram.NumCodes(), histogram.Literal, this.Literal);

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

@ -7,5 +7,5 @@ internal class CrunchConfig
{ {
public EntropyIx EntropyIdx { get; set; } public EntropyIx EntropyIdx { get; set; }
public List<CrunchSubConfig> SubConfigs { get; } = new List<CrunchSubConfig>(); public List<CrunchSubConfig> SubConfigs { get; } = new();
} }

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

@ -109,12 +109,11 @@ internal static class HistogramEncoder
{ {
int x = 0, y = 0; int x = 0, y = 0;
int histoXSize = LosslessUtils.SubSampleSize(xSize, histoBits); int histoXSize = LosslessUtils.SubSampleSize(xSize, histoBits);
using List<PixOrCopy>.Enumerator backwardRefsEnumerator = backwardRefs.Refs.GetEnumerator();
while (backwardRefsEnumerator.MoveNext()) foreach (PixOrCopy v in backwardRefs)
{ {
PixOrCopy v = backwardRefsEnumerator.Current;
int ix = ((y >> histoBits) * histoXSize) + (x >> histoBits); int ix = ((y >> histoBits) * histoXSize) + (x >> histoBits);
histograms[ix].AddSinglePixOrCopy(v, false); histograms[ix].AddSinglePixOrCopy(in v, false);
x += v.Len; x += v.Len;
while (x >= xSize) while (x >= xSize)
{ {
@ -217,7 +216,7 @@ internal static class HistogramEncoder
clusterMappings[idx] = (ushort)idx; clusterMappings[idx] = (ushort)idx;
} }
List<int> indicesToRemove = new(); List<int> indicesToRemove = [];
Vp8LStreaks stats = new(); Vp8LStreaks stats = new();
Vp8LBitEntropy bitsEntropy = new(); Vp8LBitEntropy bitsEntropy = new();
for (int idx = 0; idx < histograms.Count; idx++) for (int idx = 0; idx < histograms.Count; idx++)
@ -345,7 +344,7 @@ internal static class HistogramEncoder
// Priority list of histogram pairs. Its size impacts the quality of the compression and the speed: // Priority list of histogram pairs. Its size impacts the quality of the compression and the speed:
// the smaller the faster but the worse for the compression. // the smaller the faster but the worse for the compression.
List<HistogramPair> histoPriorityList = new(); List<HistogramPair> histoPriorityList = [];
const int maxSize = 9; const int maxSize = 9;
// Fill the initial mapping. // Fill the initial mapping.
@ -465,7 +464,7 @@ internal static class HistogramEncoder
} }
} }
HistoListUpdateHead(histoPriorityList, p); HistoListUpdateHead(histoPriorityList, p, j);
j++; j++;
} }
@ -480,7 +479,7 @@ internal static class HistogramEncoder
int histoSize = histograms.Count(h => h != null); int histoSize = histograms.Count(h => h != null);
// Priority list of histogram pairs. // Priority list of histogram pairs.
List<HistogramPair> histoPriorityList = new(); List<HistogramPair> histoPriorityList = [];
int maxSize = histoSize * histoSize; int maxSize = histoSize * histoSize;
Vp8LStreaks stats = new(); Vp8LStreaks stats = new();
Vp8LBitEntropy bitsEntropy = new(); Vp8LBitEntropy bitsEntropy = new();
@ -525,7 +524,7 @@ internal static class HistogramEncoder
} }
else else
{ {
HistoListUpdateHead(histoPriorityList, p); HistoListUpdateHead(histoPriorityList, p, i);
i++; i++;
} }
} }
@ -647,7 +646,7 @@ internal static class HistogramEncoder
histoList.Add(pair); histoList.Add(pair);
HistoListUpdateHead(histoList, pair); HistoListUpdateHead(histoList, pair, histoList.Count - 1);
return pair.CostDiff; return pair.CostDiff;
} }
@ -674,13 +673,11 @@ internal static class HistogramEncoder
/// <summary> /// <summary>
/// Check whether a pair in the list should be updated as head or not. /// Check whether a pair in the list should be updated as head or not.
/// </summary> /// </summary>
private static void HistoListUpdateHead(List<HistogramPair> histoList, HistogramPair pair) private static void HistoListUpdateHead(List<HistogramPair> histoList, HistogramPair pair, int idx)
{ {
if (pair.CostDiff < histoList[0].CostDiff) if (pair.CostDiff < histoList[0].CostDiff)
{ {
// Replace the best pair. histoList[idx] = histoList[0];
int oldIdx = histoList.IndexOf(pair);
histoList[oldIdx] = histoList[0];
histoList[0] = pair; histoList[0] = pair;
} }
} }

45
src/ImageSharp/Formats/Webp/Lossless/PixOrCopy.cs

@ -6,37 +6,24 @@ using System.Diagnostics;
namespace SixLabors.ImageSharp.Formats.Webp.Lossless; namespace SixLabors.ImageSharp.Formats.Webp.Lossless;
[DebuggerDisplay("Mode: {Mode}, Len: {Len}, BgraOrDistance: {BgraOrDistance}")] [DebuggerDisplay("Mode: {Mode}, Len: {Len}, BgraOrDistance: {BgraOrDistance}")]
internal sealed class PixOrCopy internal readonly struct PixOrCopy
{ {
public PixOrCopyMode Mode { get; set; } public readonly PixOrCopyMode Mode;
public readonly ushort Len;
public ushort Len { get; set; } public readonly uint BgraOrDistance;
public uint BgraOrDistance { get; set; } private PixOrCopy(PixOrCopyMode mode, ushort len, uint bgraOrDistance)
public static PixOrCopy CreateCacheIdx(int idx) =>
new PixOrCopy
{
Mode = PixOrCopyMode.CacheIdx,
BgraOrDistance = (uint)idx,
Len = 1
};
public static PixOrCopy CreateLiteral(uint bgra) =>
new PixOrCopy
{
Mode = PixOrCopyMode.Literal,
BgraOrDistance = bgra,
Len = 1
};
public static PixOrCopy CreateCopy(uint distance, ushort len) =>
new PixOrCopy
{ {
Mode = PixOrCopyMode.Copy, this.Mode = mode;
BgraOrDistance = distance, this.Len = len;
Len = len this.BgraOrDistance = bgraOrDistance;
}; }
public static PixOrCopy CreateCacheIdx(int idx) => new(PixOrCopyMode.CacheIdx, 1, (uint)idx);
public static PixOrCopy CreateLiteral(uint bgra) => new(PixOrCopyMode.Literal, 1, bgra);
public static PixOrCopy CreateCopy(uint distance, ushort len) => new(PixOrCopyMode.Copy, len, distance);
public int Literal(int component) => (int)(this.BgraOrDistance >> (component * 8)) & 0xFF; public int Literal(int component) => (int)(this.BgraOrDistance >> (component * 8)) & 0xFF;

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

@ -122,8 +122,8 @@ internal static unsafe class PredictorEncoder
int tileYSize = LosslessUtils.SubSampleSize(height, bits); int tileYSize = LosslessUtils.SubSampleSize(height, bits);
int[] accumulatedRedHisto = new int[256]; int[] accumulatedRedHisto = new int[256];
int[] accumulatedBlueHisto = new int[256]; int[] accumulatedBlueHisto = new int[256];
var prevX = default(Vp8LMultipliers); Vp8LMultipliers prevX = default(Vp8LMultipliers);
var prevY = default(Vp8LMultipliers); Vp8LMultipliers prevY = default(Vp8LMultipliers);
for (int tileY = 0; tileY < tileYSize; tileY++) for (int tileY = 0; tileY < tileYSize; tileY++)
{ {
for (int tileX = 0; tileX < tileXSize; tileX++) for (int tileX = 0; tileX < tileXSize; tileX++)
@ -856,7 +856,7 @@ internal static unsafe class PredictorEncoder
int tileHeight = allYMax - tileYOffset; int tileHeight = allYMax - tileYOffset;
Span<uint> tileArgb = argb[((tileYOffset * xSize) + tileXOffset)..]; Span<uint> tileArgb = argb[((tileYOffset * xSize) + tileXOffset)..];
var bestTx = default(Vp8LMultipliers); Vp8LMultipliers bestTx = default(Vp8LMultipliers);
GetBestGreenToRed(tileArgb, xSize, scratch, tileWidth, tileHeight, prevX, prevY, quality, accumulatedRedHisto, ref bestTx); GetBestGreenToRed(tileArgb, xSize, scratch, tileWidth, tileHeight, prevX, prevY, quality, accumulatedRedHisto, ref bestTx);

29
src/ImageSharp/Formats/Webp/Lossless/Vp8LBackwardRefs.cs

@ -1,21 +1,28 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
using System.Buffers;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Webp.Lossless; namespace SixLabors.ImageSharp.Formats.Webp.Lossless;
internal class Vp8LBackwardRefs internal class Vp8LBackwardRefs : IDisposable
{ {
public Vp8LBackwardRefs(int pixels) => this.Refs = new List<PixOrCopy>(pixels); private readonly IMemoryOwner<PixOrCopy> refs;
private int count;
public Vp8LBackwardRefs(MemoryAllocator memoryAllocator, int pixels)
{
this.refs = memoryAllocator.Allocate<PixOrCopy>(pixels);
this.count = 0;
}
public void Add(PixOrCopy pixOrCopy) => this.refs.Memory.Span[this.count++] = pixOrCopy;
/// <summary> public void Clear() => this.count = 0;
/// Gets or sets the common block-size.
/// </summary>
public int BlockSize { get; set; }
/// <summary> public Span<PixOrCopy>.Enumerator GetEnumerator() => this.refs.Slice(0, this.count).GetEnumerator();
/// Gets the backward references.
/// </summary>
public List<PixOrCopy> Refs { get; }
public void Add(PixOrCopy pixOrCopy) => this.Refs.Add(pixOrCopy); /// <inheritdoc/>
public void Dispose() => this.refs.Dispose();
} }

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

Loading…
Cancel
Save