Browse Source

Merge remote-tracking branch 'upstream/master' into bigtiff

pull/1760/head
Ildar Khayrutdinov 4 years ago
parent
commit
105ed8a173
  1. 4
      .gitignore
  2. 2
      shared-infrastructure
  3. 1
      src/ImageSharp/Advanced/ParallelExecutionSettings.cs
  4. 3
      src/ImageSharp/Color/Color.Conversions.cs
  5. 2
      src/ImageSharp/Color/Color.WebSafePalette.cs
  6. 1
      src/ImageSharp/Color/Color.cs
  7. 2
      src/ImageSharp/ColorSpaces/CieLab.cs
  8. 2
      src/ImageSharp/ColorSpaces/CieLch.cs
  9. 2
      src/ImageSharp/ColorSpaces/CieLchuv.cs
  10. 2
      src/ImageSharp/ColorSpaces/CieLuv.cs
  11. 2
      src/ImageSharp/ColorSpaces/CieXyy.cs
  12. 2
      src/ImageSharp/ColorSpaces/CieXyz.cs
  13. 2
      src/ImageSharp/ColorSpaces/Cmyk.cs
  14. 2
      src/ImageSharp/ColorSpaces/Companding/GammaCompanding.cs
  15. 2
      src/ImageSharp/ColorSpaces/Companding/Rec2020Companding.cs
  16. 2
      src/ImageSharp/ColorSpaces/Companding/Rec709Companding.cs
  17. 2
      src/ImageSharp/ColorSpaces/Conversion/CieConstants.cs
  18. 4
      src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.HunterLab.cs
  19. 2
      src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Lms.cs
  20. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CIeLchToCieLabConverter.cs
  21. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzAndCieXyyConverter.cs
  22. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzAndHunterLabConverterBase.cs
  23. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzAndLmsConverter.cs
  24. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzToCieLabConverter.cs
  25. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzToCieLuvConverter.cs
  26. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzToHunterLabConverter.cs
  27. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzToLinearRgbConverter.cs
  28. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CmykAndRgbConverter.cs
  29. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/YCbCrAndRgbConverter.cs
  30. 2
      src/ImageSharp/ColorSpaces/Conversion/Implementation/IChromaticAdaptation.cs
  31. 2
      src/ImageSharp/ColorSpaces/Hsl.cs
  32. 2
      src/ImageSharp/ColorSpaces/Hsv.cs
  33. 2
      src/ImageSharp/ColorSpaces/HunterLab.cs
  34. 2
      src/ImageSharp/ColorSpaces/Illuminants.cs
  35. 2
      src/ImageSharp/ColorSpaces/Lms.cs
  36. 2
      src/ImageSharp/Common/Constants.cs
  37. 4
      src/ImageSharp/Common/Helpers/InliningOptions.cs
  38. 145
      src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
  39. 4
      src/ImageSharp/Common/Helpers/SimdUtils.Pack.cs
  40. 170
      src/ImageSharp/Compression/Zlib/Adler32.cs
  41. 180
      src/ImageSharp/Compression/Zlib/Crc32.cs
  42. 2
      src/ImageSharp/Formats/Bmp/BmpConfigurationModule.cs
  43. 2
      src/ImageSharp/Formats/Bmp/BmpConstants.cs
  44. 2
      src/ImageSharp/Formats/Bmp/BmpFormat.cs
  45. 2
      src/ImageSharp/Formats/Bmp/BmpMetadata.cs
  46. 2
      src/ImageSharp/Formats/Bmp/IBmpDecoderOptions.cs
  47. 2
      src/ImageSharp/Formats/Gif/GifConfigurationModule.cs
  48. 1
      src/ImageSharp/Formats/Gif/GifDecoderCore.cs
  49. 2
      src/ImageSharp/Formats/Gif/GifDisposalMethod.cs
  50. 2
      src/ImageSharp/Formats/Gif/GifFormat.cs
  51. 2
      src/ImageSharp/Formats/Gif/GifImageFormatDetector.cs
  52. 1
      src/ImageSharp/Formats/Gif/LzwEncoder.cs
  53. 2
      src/ImageSharp/Formats/Gif/Sections/GifGraphicControlExtension.cs
  54. 2
      src/ImageSharp/Formats/Gif/Sections/GifImageDescriptor.cs
  55. 2
      src/ImageSharp/Formats/Gif/Sections/GifLogicalScreenDescriptor.cs
  56. 2
      src/ImageSharp/Formats/Gif/Sections/IGifExtension.cs
  57. 2
      src/ImageSharp/Formats/IImageFormat.cs
  58. 2
      src/ImageSharp/Formats/Jpeg/Components/Decoder/AdobeMarker.cs
  59. 47
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykAvx2.cs
  60. 45
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykBasic.cs
  61. 34
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykVector8.cs
  62. 32
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScaleAvx2.cs
  63. 38
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScaleBasic.cs
  64. 40
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgbAvx2.cs
  65. 33
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgbBasic.cs
  66. 40
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgbVector8.cs
  67. 50
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrAvx2.cs
  68. 37
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrBasic.cs
  69. 52
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrVector4.cs
  70. 47
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrVector8.cs
  71. 64
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccKAvx2.cs
  72. 43
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccKBasic.cs
  73. 60
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccKVector8.cs
  74. 15
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.VectorizedJpegColorConverter.cs
  75. 156
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs
  76. 6
      src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanScanBuffer.cs
  77. 2
      src/ImageSharp/Formats/Jpeg/Components/Decoder/IJpegComponent.cs
  78. 2
      src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs
  79. 2
      src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegColorSpace.cs
  80. 1
      src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponent.cs
  81. 2
      src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegFileMarker.cs
  82. 64
      src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs
  83. 2
      src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffIndex.cs
  84. 2
      src/ImageSharp/Formats/Jpeg/Components/SizeExtensions.cs
  85. 2
      src/ImageSharp/Formats/Jpeg/IJpegDecoderOptions.cs
  86. 2
      src/ImageSharp/Formats/Jpeg/JpegConfigurationModule.cs
  87. 2
      src/ImageSharp/Formats/Jpeg/JpegDecoder.cs
  88. 2
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
  89. 2
      src/ImageSharp/Formats/Jpeg/JpegFormat.cs
  90. 2
      src/ImageSharp/Formats/Jpeg/JpegImageFormatDetector.cs
  91. 2
      src/ImageSharp/Formats/Png/Filters/NoneFilter.cs
  92. 2
      src/ImageSharp/Formats/Png/PngColorType.cs
  93. 2
      src/ImageSharp/Formats/Png/PngConfigurationModule.cs
  94. 2
      src/ImageSharp/Formats/Png/PngFilterMethod.cs
  95. 2
      src/ImageSharp/Formats/Png/PngFormat.cs
  96. 2
      src/ImageSharp/Formats/Png/PngImageFormatDetector.cs
  97. 2
      src/ImageSharp/Formats/Png/PngInterlaceMode.cs
  98. 1
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/DeflateTiffCompression.cs
  99. 2
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/JpegTiffCompression.cs
  100. 1
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanTiffCompression.cs

4
.gitignore

@ -223,3 +223,7 @@ artifacts/
**/Images/ReferenceOutput
**/Images/Input/MemoryStress
.DS_Store
#lfs
hooks/**
lfs/**

2
shared-infrastructure

@ -1 +1 @@
Subproject commit f48ab829167c42c69242ed0d303683232fbfccd1
Subproject commit a042aba176cdb840d800c6ed4cfe41a54fb7b1e3

1
src/ImageSharp/Advanced/ParallelExecutionSettings.cs

@ -3,7 +3,6 @@
using System;
using System.Threading.Tasks;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Advanced

3
src/ImageSharp/Color/Color.Conversions.cs

@ -3,7 +3,6 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp
@ -95,4 +94,4 @@ namespace SixLabors.ImageSharp
[MethodImpl(InliningOptions.ShortMethod)]
internal Vector4 ToVector4() => this.data.ToVector4();
}
}
}

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

@ -163,4 +163,4 @@ namespace SixLabors.ImageSharp
YellowGreen
};
}
}
}

1
src/ImageSharp/Color/Color.cs

@ -5,7 +5,6 @@ using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp

2
src/ImageSharp/ColorSpaces/CieLab.cs

@ -136,4 +136,4 @@ namespace SixLabors.ImageSharp.ColorSpaces
&& this.WhitePoint.Equals(other.WhitePoint);
}
}
}
}

2
src/ImageSharp/ColorSpaces/CieLch.cs

@ -162,4 +162,4 @@ namespace SixLabors.ImageSharp.ColorSpaces
return result;
}
}
}
}

2
src/ImageSharp/ColorSpaces/CieLchuv.cs

@ -157,4 +157,4 @@ namespace SixLabors.ImageSharp.ColorSpaces
return result;
}
}
}
}

2
src/ImageSharp/ColorSpaces/CieLuv.cs

@ -137,4 +137,4 @@ namespace SixLabors.ImageSharp.ColorSpaces
&& this.WhitePoint.Equals(other.WhitePoint);
}
}
}
}

2
src/ImageSharp/ColorSpaces/CieXyy.cs

@ -100,4 +100,4 @@ namespace SixLabors.ImageSharp.ColorSpaces
&& this.Yl.Equals(other.Yl);
}
}
}
}

2
src/ImageSharp/ColorSpaces/CieXyz.cs

@ -103,4 +103,4 @@ namespace SixLabors.ImageSharp.ColorSpaces
&& this.Z.Equals(other.Z);
}
}
}
}

2
src/ImageSharp/ColorSpaces/Cmyk.cs

@ -108,4 +108,4 @@ namespace SixLabors.ImageSharp.ColorSpaces
&& this.K.Equals(other.K);
}
}
}
}

2
src/ImageSharp/ColorSpaces/Companding/GammaCompanding.cs

@ -33,4 +33,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding
[MethodImpl(InliningOptions.ShortMethod)]
public static float Compress(float channel, float gamma) => MathF.Pow(channel, 1 / gamma);
}
}
}

2
src/ImageSharp/ColorSpaces/Companding/Rec2020Companding.cs

@ -38,4 +38,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding
public static float Compress(float channel)
=> channel < Beta ? 4.5F * channel : (Alpha * MathF.Pow(channel, 0.45F)) - AlphaMinusOne;
}
}
}

2
src/ImageSharp/ColorSpaces/Companding/Rec709Companding.cs

@ -34,4 +34,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Companding
public static float Compress(float channel)
=> channel < 0.018F ? 4.5F * channel : (1.099F * MathF.Pow(channel, 0.45F)) - 0.099F;
}
}
}

2
src/ImageSharp/ColorSpaces/Conversion/CieConstants.cs

@ -19,4 +19,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
/// </summary>
public const float Kappa = 903.2963F;
}
}
}

4
src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.HunterLab.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -429,4 +429,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
return this.ToHunterLab(xyzColor);
}
}
}
}

2
src/ImageSharp/ColorSpaces/Conversion/ColorSpaceConverter.Lms.cs

@ -424,4 +424,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
return this.ToLms(xyzColor);
}
}
}
}

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CIeLchToCieLabConverter.cs

@ -30,4 +30,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
return new CieLab(l, a, b, input.WhitePoint);
}
}
}
}

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzAndCieXyyConverter.cs

@ -51,4 +51,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
return new CieXyz(x, y, z);
}
}
}
}

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzAndHunterLabConverterBase.cs

@ -42,4 +42,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
return 100F * (70F / 218.11F) * (whitePoint.Y + whitePoint.Z);
}
}
}
}

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzAndLmsConverter.cs

@ -67,4 +67,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
return new CieXyz(vector);
}
}
}
}

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzToCieLabConverter.cs

@ -54,4 +54,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
return new CieLab(l, a, b, this.LabWhitePoint);
}
}
}
}

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzToCieLuvConverter.cs

@ -85,4 +85,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
private static float ComputeVp(in CieXyz input)
=> (9 * input.Y) / (input.X + (15 * input.Y) + (3 * input.Z));
}
}
}

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzToHunterLabConverter.cs

@ -64,4 +64,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
return new HunterLab(l, a, b, this.HunterLabWhitePoint);
}
}
}
}

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CieXyzToLinearRgbConverter.cs

@ -53,4 +53,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
return new LinearRgb(vector, this.TargetWorkingSpace);
}
}
}
}

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/CmykAndRgbConverter.cs

@ -48,4 +48,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
return new Cmyk(cmy.X, cmy.Y, cmy.Z, k.X);
}
}
}
}

2
src/ImageSharp/ColorSpaces/Conversion/Implementation/Converters/YCbCrAndRgbConverter.cs

@ -54,4 +54,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
return new YCbCr(y, cb, cr);
}
}
}
}

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

@ -36,4 +36,4 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion
CieXyz sourceWhitePoint,
in CieXyz destinationWhitePoint);
}
}
}

2
src/ImageSharp/ColorSpaces/Hsl.cs

@ -101,4 +101,4 @@ namespace SixLabors.ImageSharp.ColorSpaces
&& this.L.Equals(other.L);
}
}
}
}

2
src/ImageSharp/ColorSpaces/Hsv.cs

@ -99,4 +99,4 @@ namespace SixLabors.ImageSharp.ColorSpaces
&& this.V.Equals(other.V);
}
}
}
}

2
src/ImageSharp/ColorSpaces/HunterLab.cs

@ -135,4 +135,4 @@ namespace SixLabors.ImageSharp.ColorSpaces
&& this.WhitePoint.Equals(other.WhitePoint);
}
}
}
}

2
src/ImageSharp/ColorSpaces/Illuminants.cs

@ -69,4 +69,4 @@ namespace SixLabors.ImageSharp.ColorSpaces
/// </summary>
public static readonly CieXyz F11 = new CieXyz(1.00962F, 1F, 0.64350F);
}
}
}

2
src/ImageSharp/ColorSpaces/Lms.cs

@ -104,4 +104,4 @@ namespace SixLabors.ImageSharp.ColorSpaces
&& this.S.Equals(other.S);
}
}
}
}

2
src/ImageSharp/Common/Constants.cs

@ -18,4 +18,4 @@ namespace SixLabors.ImageSharp
/// </summary>
public static readonly float EpsilonSquared = Epsilon * Epsilon;
}
}
}

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

@ -12,6 +12,10 @@ namespace SixLabors.ImageSharp
/// </summary>
internal static class InliningOptions
{
/// <summary>
/// <see cref="MethodImplOptions.AggressiveInlining"/> regardless of the build conditions.
/// </summary>
public const MethodImplOptions AlwaysInline = MethodImplOptions.AggressiveInlining;
#if PROFILING
public const MethodImplOptions HotPath = MethodImplOptions.NoInlining;
public const MethodImplOptions ShortMethod = MethodImplOptions.NoInlining;

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

@ -537,7 +537,7 @@ namespace SixLabors.ImageSharp
/// <param name="vm0">The first vector to multiply.</param>
/// <param name="vm1">The second vector to multiply.</param>
/// <returns>The <see cref="Vector256{T}"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(InliningOptions.AlwaysInline)]
public static Vector256<float> MultiplyAdd(
in Vector256<float> va,
in Vector256<float> vm0,
@ -622,90 +622,89 @@ namespace SixLabors.ImageSharp
ReadOnlySpan<byte> source,
Span<float> dest)
{
if (Avx2.IsSupported)
fixed (byte* sourceBase = source)
{
VerifySpanInput(source, dest, Vector256<byte>.Count);
int n = dest.Length / Vector256<byte>.Count;
if (Avx2.IsSupported)
{
VerifySpanInput(source, dest, Vector256<byte>.Count);
byte* sourceBase = (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(source));
int n = dest.Length / Vector256<byte>.Count;
ref Vector256<float> destBase =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(dest));
ref Vector256<float> destBase =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(dest));
var scale = Vector256.Create(1 / (float)byte.MaxValue);
var scale = Vector256.Create(1 / (float)byte.MaxValue);
for (int i = 0; i < n; i++)
{
int si = Vector256<byte>.Count * i;
Vector256<int> i0 = Avx2.ConvertToVector256Int32(sourceBase + si);
Vector256<int> i1 = Avx2.ConvertToVector256Int32(sourceBase + si + Vector256<int>.Count);
Vector256<int> i2 = Avx2.ConvertToVector256Int32(sourceBase + si + (Vector256<int>.Count * 2));
Vector256<int> i3 = Avx2.ConvertToVector256Int32(sourceBase + si + (Vector256<int>.Count * 3));
Vector256<float> f0 = Avx.Multiply(scale, Avx.ConvertToVector256Single(i0));
Vector256<float> f1 = Avx.Multiply(scale, Avx.ConvertToVector256Single(i1));
Vector256<float> f2 = Avx.Multiply(scale, Avx.ConvertToVector256Single(i2));
Vector256<float> f3 = Avx.Multiply(scale, Avx.ConvertToVector256Single(i3));
ref Vector256<float> d = ref Unsafe.Add(ref destBase, i * 4);
d = f0;
Unsafe.Add(ref d, 1) = f1;
Unsafe.Add(ref d, 2) = f2;
Unsafe.Add(ref d, 3) = f3;
for (int i = 0; i < n; i++)
{
int si = Vector256<byte>.Count * i;
Vector256<int> i0 = Avx2.ConvertToVector256Int32(sourceBase + si);
Vector256<int> i1 = Avx2.ConvertToVector256Int32(sourceBase + si + Vector256<int>.Count);
Vector256<int> i2 = Avx2.ConvertToVector256Int32(sourceBase + si + (Vector256<int>.Count * 2));
Vector256<int> i3 = Avx2.ConvertToVector256Int32(sourceBase + si + (Vector256<int>.Count * 3));
Vector256<float> f0 = Avx.Multiply(scale, Avx.ConvertToVector256Single(i0));
Vector256<float> f1 = Avx.Multiply(scale, Avx.ConvertToVector256Single(i1));
Vector256<float> f2 = Avx.Multiply(scale, Avx.ConvertToVector256Single(i2));
Vector256<float> f3 = Avx.Multiply(scale, Avx.ConvertToVector256Single(i3));
ref Vector256<float> d = ref Unsafe.Add(ref destBase, i * 4);
d = f0;
Unsafe.Add(ref d, 1) = f1;
Unsafe.Add(ref d, 2) = f2;
Unsafe.Add(ref d, 3) = f3;
}
}
}
else
{
// Sse
VerifySpanInput(source, dest, Vector128<byte>.Count);
int n = dest.Length / Vector128<byte>.Count;
byte* sourceBase = (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(source));
else
{
// Sse
VerifySpanInput(source, dest, Vector128<byte>.Count);
ref Vector128<float> destBase =
ref Unsafe.As<float, Vector128<float>>(ref MemoryMarshal.GetReference(dest));
int n = dest.Length / Vector128<byte>.Count;
var scale = Vector128.Create(1 / (float)byte.MaxValue);
Vector128<byte> zero = Vector128<byte>.Zero;
ref Vector128<float> destBase =
ref Unsafe.As<float, Vector128<float>>(ref MemoryMarshal.GetReference(dest));
for (int i = 0; i < n; i++)
{
int si = Vector128<byte>.Count * i;
var scale = Vector128.Create(1 / (float)byte.MaxValue);
Vector128<byte> zero = Vector128<byte>.Zero;
Vector128<int> i0, i1, i2, i3;
if (Sse41.IsSupported)
{
i0 = Sse41.ConvertToVector128Int32(sourceBase + si);
i1 = Sse41.ConvertToVector128Int32(sourceBase + si + Vector128<int>.Count);
i2 = Sse41.ConvertToVector128Int32(sourceBase + si + (Vector128<int>.Count * 2));
i3 = Sse41.ConvertToVector128Int32(sourceBase + si + (Vector128<int>.Count * 3));
}
else
for (int i = 0; i < n; i++)
{
Vector128<byte> b = Sse2.LoadVector128(sourceBase + si);
Vector128<short> s0 = Sse2.UnpackLow(b, zero).AsInt16();
Vector128<short> s1 = Sse2.UnpackHigh(b, zero).AsInt16();
i0 = Sse2.UnpackLow(s0, zero.AsInt16()).AsInt32();
i1 = Sse2.UnpackHigh(s0, zero.AsInt16()).AsInt32();
i2 = Sse2.UnpackLow(s1, zero.AsInt16()).AsInt32();
i3 = Sse2.UnpackHigh(s1, zero.AsInt16()).AsInt32();
int si = Vector128<byte>.Count * i;
Vector128<int> i0, i1, i2, i3;
if (Sse41.IsSupported)
{
i0 = Sse41.ConvertToVector128Int32(sourceBase + si);
i1 = Sse41.ConvertToVector128Int32(sourceBase + si + Vector128<int>.Count);
i2 = Sse41.ConvertToVector128Int32(sourceBase + si + (Vector128<int>.Count * 2));
i3 = Sse41.ConvertToVector128Int32(sourceBase + si + (Vector128<int>.Count * 3));
}
else
{
Vector128<byte> b = Sse2.LoadVector128(sourceBase + si);
Vector128<short> s0 = Sse2.UnpackLow(b, zero).AsInt16();
Vector128<short> s1 = Sse2.UnpackHigh(b, zero).AsInt16();
i0 = Sse2.UnpackLow(s0, zero.AsInt16()).AsInt32();
i1 = Sse2.UnpackHigh(s0, zero.AsInt16()).AsInt32();
i2 = Sse2.UnpackLow(s1, zero.AsInt16()).AsInt32();
i3 = Sse2.UnpackHigh(s1, zero.AsInt16()).AsInt32();
}
Vector128<float> f0 = Sse.Multiply(scale, Sse2.ConvertToVector128Single(i0));
Vector128<float> f1 = Sse.Multiply(scale, Sse2.ConvertToVector128Single(i1));
Vector128<float> f2 = Sse.Multiply(scale, Sse2.ConvertToVector128Single(i2));
Vector128<float> f3 = Sse.Multiply(scale, Sse2.ConvertToVector128Single(i3));
ref Vector128<float> d = ref Unsafe.Add(ref destBase, i * 4);
d = f0;
Unsafe.Add(ref d, 1) = f1;
Unsafe.Add(ref d, 2) = f2;
Unsafe.Add(ref d, 3) = f3;
}
Vector128<float> f0 = Sse.Multiply(scale, Sse2.ConvertToVector128Single(i0));
Vector128<float> f1 = Sse.Multiply(scale, Sse2.ConvertToVector128Single(i1));
Vector128<float> f2 = Sse.Multiply(scale, Sse2.ConvertToVector128Single(i2));
Vector128<float> f3 = Sse.Multiply(scale, Sse2.ConvertToVector128Single(i3));
ref Vector128<float> d = ref Unsafe.Add(ref destBase, i * 4);
d = f0;
Unsafe.Add(ref d, 1) = f1;
Unsafe.Add(ref d, 2) = f2;
Unsafe.Add(ref d, 3) = f3;
}
}
}

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

@ -5,9 +5,7 @@ using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.PixelFormats;
#if SUPPORTS_RUNTIME_INTRINSICS
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
#endif
@ -203,4 +201,4 @@ namespace SixLabors.ImageSharp
}
}
}
}
}

170
src/ImageSharp/Compression/Zlib/Adler32.cs

@ -91,115 +91,117 @@ namespace SixLabors.ImageSharp.Compression.Zlib
int index = 0;
fixed (byte* bufferPtr = buffer)
fixed (byte* tapPtr = Tap1Tap2)
{
index += (int)blocks * BLOCK_SIZE;
var localBufferPtr = bufferPtr;
// _mm_setr_epi8 on x86
Vector128<sbyte> tap1 = Sse2.LoadVector128((sbyte*)tapPtr);
Vector128<sbyte> tap2 = Sse2.LoadVector128((sbyte*)(tapPtr + 0x10));
Vector128<byte> zero = Vector128<byte>.Zero;
var ones = Vector128.Create((short)1);
while (blocks > 0)
fixed (byte* tapPtr = Tap1Tap2)
{
uint n = NMAX / BLOCK_SIZE; /* The NMAX constraint. */
if (n > blocks)
{
n = blocks;
}
index += (int)blocks * BLOCK_SIZE;
var localBufferPtr = bufferPtr;
blocks -= n;
// _mm_setr_epi8 on x86
Vector128<sbyte> tap1 = Sse2.LoadVector128((sbyte*)tapPtr);
Vector128<sbyte> tap2 = Sse2.LoadVector128((sbyte*)(tapPtr + 0x10));
Vector128<byte> zero = Vector128<byte>.Zero;
var ones = Vector128.Create((short)1);
// Process n blocks of data. At most NMAX data bytes can be
// processed before s2 must be reduced modulo BASE.
Vector128<uint> v_ps = Vector128.CreateScalar(s1 * n);
Vector128<uint> v_s2 = Vector128.CreateScalar(s2);
Vector128<uint> v_s1 = Vector128<uint>.Zero;
do
while (blocks > 0)
{
// Load 32 input bytes.
Vector128<byte> bytes1 = Sse3.LoadDquVector128(localBufferPtr);
Vector128<byte> bytes2 = Sse3.LoadDquVector128(localBufferPtr + 0x10);
uint n = NMAX / BLOCK_SIZE; /* The NMAX constraint. */
if (n > blocks)
{
n = blocks;
}
// Add previous block byte sum to v_ps.
v_ps = Sse2.Add(v_ps, v_s1);
blocks -= n;
// Horizontally add the bytes for s1, multiply-adds the
// bytes by [ 32, 31, 30, ... ] for s2.
v_s1 = Sse2.Add(v_s1, Sse2.SumAbsoluteDifferences(bytes1, zero).AsUInt32());
Vector128<short> mad1 = Ssse3.MultiplyAddAdjacent(bytes1, tap1);
v_s2 = Sse2.Add(v_s2, Sse2.MultiplyAddAdjacent(mad1, ones).AsUInt32());
// Process n blocks of data. At most NMAX data bytes can be
// processed before s2 must be reduced modulo BASE.
Vector128<uint> v_ps = Vector128.CreateScalar(s1 * n);
Vector128<uint> v_s2 = Vector128.CreateScalar(s2);
Vector128<uint> v_s1 = Vector128<uint>.Zero;
v_s1 = Sse2.Add(v_s1, Sse2.SumAbsoluteDifferences(bytes2, zero).AsUInt32());
Vector128<short> mad2 = Ssse3.MultiplyAddAdjacent(bytes2, tap2);
v_s2 = Sse2.Add(v_s2, Sse2.MultiplyAddAdjacent(mad2, ones).AsUInt32());
do
{
// Load 32 input bytes.
Vector128<byte> bytes1 = Sse3.LoadDquVector128(localBufferPtr);
Vector128<byte> bytes2 = Sse3.LoadDquVector128(localBufferPtr + 0x10);
localBufferPtr += BLOCK_SIZE;
}
while (--n > 0);
// Add previous block byte sum to v_ps.
v_ps = Sse2.Add(v_ps, v_s1);
v_s2 = Sse2.Add(v_s2, Sse2.ShiftLeftLogical(v_ps, 5));
// Horizontally add the bytes for s1, multiply-adds the
// bytes by [ 32, 31, 30, ... ] for s2.
v_s1 = Sse2.Add(v_s1, Sse2.SumAbsoluteDifferences(bytes1, zero).AsUInt32());
Vector128<short> mad1 = Ssse3.MultiplyAddAdjacent(bytes1, tap1);
v_s2 = Sse2.Add(v_s2, Sse2.MultiplyAddAdjacent(mad1, ones).AsUInt32());
// Sum epi32 ints v_s1(s2) and accumulate in s1(s2).
const byte S2301 = 0b1011_0001; // A B C D -> B A D C
const byte S1032 = 0b0100_1110; // A B C D -> C D A B
v_s1 = Sse2.Add(v_s1, Sse2.SumAbsoluteDifferences(bytes2, zero).AsUInt32());
Vector128<short> mad2 = Ssse3.MultiplyAddAdjacent(bytes2, tap2);
v_s2 = Sse2.Add(v_s2, Sse2.MultiplyAddAdjacent(mad2, ones).AsUInt32());
v_s1 = Sse2.Add(v_s1, Sse2.Shuffle(v_s1, S1032));
localBufferPtr += BLOCK_SIZE;
}
while (--n > 0);
s1 += v_s1.ToScalar();
v_s2 = Sse2.Add(v_s2, Sse2.ShiftLeftLogical(v_ps, 5));
v_s2 = Sse2.Add(v_s2, Sse2.Shuffle(v_s2, S2301));
v_s2 = Sse2.Add(v_s2, Sse2.Shuffle(v_s2, S1032));
// Sum epi32 ints v_s1(s2) and accumulate in s1(s2).
const byte S2301 = 0b1011_0001; // A B C D -> B A D C
const byte S1032 = 0b0100_1110; // A B C D -> C D A B
s2 = v_s2.ToScalar();
v_s1 = Sse2.Add(v_s1, Sse2.Shuffle(v_s1, S1032));
// Reduce.
s1 %= BASE;
s2 %= BASE;
}
s1 += v_s1.ToScalar();
if (length > 0)
{
if (length >= 16)
{
s2 += s1 += localBufferPtr[0];
s2 += s1 += localBufferPtr[1];
s2 += s1 += localBufferPtr[2];
s2 += s1 += localBufferPtr[3];
s2 += s1 += localBufferPtr[4];
s2 += s1 += localBufferPtr[5];
s2 += s1 += localBufferPtr[6];
s2 += s1 += localBufferPtr[7];
s2 += s1 += localBufferPtr[8];
s2 += s1 += localBufferPtr[9];
s2 += s1 += localBufferPtr[10];
s2 += s1 += localBufferPtr[11];
s2 += s1 += localBufferPtr[12];
s2 += s1 += localBufferPtr[13];
s2 += s1 += localBufferPtr[14];
s2 += s1 += localBufferPtr[15];
v_s2 = Sse2.Add(v_s2, Sse2.Shuffle(v_s2, S2301));
v_s2 = Sse2.Add(v_s2, Sse2.Shuffle(v_s2, S1032));
localBufferPtr += 16;
length -= 16;
}
s2 = v_s2.ToScalar();
while (length-- > 0)
{
s2 += s1 += *localBufferPtr++;
// Reduce.
s1 %= BASE;
s2 %= BASE;
}
if (s1 >= BASE)
if (length > 0)
{
s1 -= BASE;
if (length >= 16)
{
s2 += s1 += localBufferPtr[0];
s2 += s1 += localBufferPtr[1];
s2 += s1 += localBufferPtr[2];
s2 += s1 += localBufferPtr[3];
s2 += s1 += localBufferPtr[4];
s2 += s1 += localBufferPtr[5];
s2 += s1 += localBufferPtr[6];
s2 += s1 += localBufferPtr[7];
s2 += s1 += localBufferPtr[8];
s2 += s1 += localBufferPtr[9];
s2 += s1 += localBufferPtr[10];
s2 += s1 += localBufferPtr[11];
s2 += s1 += localBufferPtr[12];
s2 += s1 += localBufferPtr[13];
s2 += s1 += localBufferPtr[14];
s2 += s1 += localBufferPtr[15];
localBufferPtr += 16;
length -= 16;
}
while (length-- > 0)
{
s2 += s1 += *localBufferPtr++;
}
if (s1 >= BASE)
{
s1 -= BASE;
}
s2 %= BASE;
}
s2 %= BASE;
return s1 | (s2 << 16);
}
return s1 | (s2 << 16);
}
}
#endif

180
src/ImageSharp/Compression/Zlib/Crc32.cs

@ -83,117 +83,119 @@ namespace SixLabors.ImageSharp.Compression.Zlib
int length = chunksize;
fixed (byte* bufferPtr = buffer)
fixed (ulong* k05PolyPtr = K05Poly)
{
byte* localBufferPtr = bufferPtr;
ulong* localK05PolyPtr = k05PolyPtr;
// There's at least one block of 64.
Vector128<ulong> x1 = Sse2.LoadVector128((ulong*)(localBufferPtr + 0x00));
Vector128<ulong> x2 = Sse2.LoadVector128((ulong*)(localBufferPtr + 0x10));
Vector128<ulong> x3 = Sse2.LoadVector128((ulong*)(localBufferPtr + 0x20));
Vector128<ulong> x4 = Sse2.LoadVector128((ulong*)(localBufferPtr + 0x30));
Vector128<ulong> x5;
x1 = Sse2.Xor(x1, Sse2.ConvertScalarToVector128UInt32(crc).AsUInt64());
// k1, k2
Vector128<ulong> x0 = Sse2.LoadVector128(localK05PolyPtr + 0x0);
localBufferPtr += 64;
length -= 64;
// Parallel fold blocks of 64, if any.
while (length >= 64)
fixed (ulong* k05PolyPtr = K05Poly)
{
x5 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x00);
Vector128<ulong> x6 = Pclmulqdq.CarrylessMultiply(x2, x0, 0x00);
Vector128<ulong> x7 = Pclmulqdq.CarrylessMultiply(x3, x0, 0x00);
Vector128<ulong> x8 = Pclmulqdq.CarrylessMultiply(x4, x0, 0x00);
x1 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x11);
x2 = Pclmulqdq.CarrylessMultiply(x2, x0, 0x11);
x3 = Pclmulqdq.CarrylessMultiply(x3, x0, 0x11);
x4 = Pclmulqdq.CarrylessMultiply(x4, x0, 0x11);
byte* localBufferPtr = bufferPtr;
ulong* localK05PolyPtr = k05PolyPtr;
Vector128<ulong> y5 = Sse2.LoadVector128((ulong*)(localBufferPtr + 0x00));
Vector128<ulong> y6 = Sse2.LoadVector128((ulong*)(localBufferPtr + 0x10));
Vector128<ulong> y7 = Sse2.LoadVector128((ulong*)(localBufferPtr + 0x20));
Vector128<ulong> y8 = Sse2.LoadVector128((ulong*)(localBufferPtr + 0x30));
// There's at least one block of 64.
Vector128<ulong> x1 = Sse2.LoadVector128((ulong*)(localBufferPtr + 0x00));
Vector128<ulong> x2 = Sse2.LoadVector128((ulong*)(localBufferPtr + 0x10));
Vector128<ulong> x3 = Sse2.LoadVector128((ulong*)(localBufferPtr + 0x20));
Vector128<ulong> x4 = Sse2.LoadVector128((ulong*)(localBufferPtr + 0x30));
Vector128<ulong> x5;
x1 = Sse2.Xor(x1, x5);
x2 = Sse2.Xor(x2, x6);
x3 = Sse2.Xor(x3, x7);
x4 = Sse2.Xor(x4, x8);
x1 = Sse2.Xor(x1, Sse2.ConvertScalarToVector128UInt32(crc).AsUInt64());
x1 = Sse2.Xor(x1, y5);
x2 = Sse2.Xor(x2, y6);
x3 = Sse2.Xor(x3, y7);
x4 = Sse2.Xor(x4, y8);
// k1, k2
Vector128<ulong> x0 = Sse2.LoadVector128(localK05PolyPtr + 0x0);
localBufferPtr += 64;
length -= 64;
}
// Fold into 128-bits.
// k3, k4
x0 = Sse2.LoadVector128(k05PolyPtr + 0x2);
x5 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x00);
x1 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x11);
x1 = Sse2.Xor(x1, x2);
x1 = Sse2.Xor(x1, x5);
// Parallel fold blocks of 64, if any.
while (length >= 64)
{
x5 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x00);
Vector128<ulong> x6 = Pclmulqdq.CarrylessMultiply(x2, x0, 0x00);
Vector128<ulong> x7 = Pclmulqdq.CarrylessMultiply(x3, x0, 0x00);
Vector128<ulong> x8 = Pclmulqdq.CarrylessMultiply(x4, x0, 0x00);
x1 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x11);
x2 = Pclmulqdq.CarrylessMultiply(x2, x0, 0x11);
x3 = Pclmulqdq.CarrylessMultiply(x3, x0, 0x11);
x4 = Pclmulqdq.CarrylessMultiply(x4, x0, 0x11);
Vector128<ulong> y5 = Sse2.LoadVector128((ulong*)(localBufferPtr + 0x00));
Vector128<ulong> y6 = Sse2.LoadVector128((ulong*)(localBufferPtr + 0x10));
Vector128<ulong> y7 = Sse2.LoadVector128((ulong*)(localBufferPtr + 0x20));
Vector128<ulong> y8 = Sse2.LoadVector128((ulong*)(localBufferPtr + 0x30));
x1 = Sse2.Xor(x1, x5);
x2 = Sse2.Xor(x2, x6);
x3 = Sse2.Xor(x3, x7);
x4 = Sse2.Xor(x4, x8);
x1 = Sse2.Xor(x1, y5);
x2 = Sse2.Xor(x2, y6);
x3 = Sse2.Xor(x3, y7);
x4 = Sse2.Xor(x4, y8);
localBufferPtr += 64;
length -= 64;
}
// Fold into 128-bits.
// k3, k4
x0 = Sse2.LoadVector128(k05PolyPtr + 0x2);
x5 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x00);
x1 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x11);
x1 = Sse2.Xor(x1, x3);
x1 = Sse2.Xor(x1, x5);
x5 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x00);
x1 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x11);
x1 = Sse2.Xor(x1, x4);
x1 = Sse2.Xor(x1, x5);
x5 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x00);
x1 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x11);
x1 = Sse2.Xor(x1, x2);
x1 = Sse2.Xor(x1, x5);
// Single fold blocks of 16, if any.
while (length >= 16)
{
x2 = Sse2.LoadVector128((ulong*)localBufferPtr);
x5 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x00);
x1 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x11);
x1 = Sse2.Xor(x1, x3);
x1 = Sse2.Xor(x1, x5);
x5 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x00);
x1 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x11);
x1 = Sse2.Xor(x1, x2);
x1 = Sse2.Xor(x1, x4);
x1 = Sse2.Xor(x1, x5);
localBufferPtr += 16;
length -= 16;
}
// Single fold blocks of 16, if any.
while (length >= 16)
{
x2 = Sse2.LoadVector128((ulong*)localBufferPtr);
x5 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x00);
x1 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x11);
x1 = Sse2.Xor(x1, x2);
x1 = Sse2.Xor(x1, x5);
// Fold 128 - bits to 64 - bits.
x2 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x10);
x3 = Vector128.Create(~0, 0, ~0, 0).AsUInt64(); // _mm_setr_epi32 on x86
x1 = Sse2.ShiftRightLogical128BitLane(x1, 8);
x1 = Sse2.Xor(x1, x2);
localBufferPtr += 16;
length -= 16;
}
// k5, k0
x0 = Sse2.LoadScalarVector128(localK05PolyPtr + 0x4);
// Fold 128 - bits to 64 - bits.
x2 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x10);
x3 = Vector128.Create(~0, 0, ~0, 0).AsUInt64(); // _mm_setr_epi32 on x86
x1 = Sse2.ShiftRightLogical128BitLane(x1, 8);
x1 = Sse2.Xor(x1, x2);
x2 = Sse2.ShiftRightLogical128BitLane(x1, 4);
x1 = Sse2.And(x1, x3);
x1 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x00);
x1 = Sse2.Xor(x1, x2);
// k5, k0
x0 = Sse2.LoadScalarVector128(localK05PolyPtr + 0x4);
// Barret reduce to 32-bits.
// polynomial
x0 = Sse2.LoadVector128(localK05PolyPtr + 0x6);
x2 = Sse2.ShiftRightLogical128BitLane(x1, 4);
x1 = Sse2.And(x1, x3);
x1 = Pclmulqdq.CarrylessMultiply(x1, x0, 0x00);
x1 = Sse2.Xor(x1, x2);
x2 = Sse2.And(x1, x3);
x2 = Pclmulqdq.CarrylessMultiply(x2, x0, 0x10);
x2 = Sse2.And(x2, x3);
x2 = Pclmulqdq.CarrylessMultiply(x2, x0, 0x00);
x1 = Sse2.Xor(x1, x2);
// Barret reduce to 32-bits.
// polynomial
x0 = Sse2.LoadVector128(localK05PolyPtr + 0x6);
crc = (uint)Sse41.Extract(x1.AsInt32(), 1);
return buffer.Length - chunksize == 0 ? crc : CalculateScalar(crc, buffer.Slice(chunksize));
x2 = Sse2.And(x1, x3);
x2 = Pclmulqdq.CarrylessMultiply(x2, x0, 0x10);
x2 = Sse2.And(x2, x3);
x2 = Pclmulqdq.CarrylessMultiply(x2, x0, 0x00);
x1 = Sse2.Xor(x1, x2);
crc = (uint)Sse41.Extract(x1.AsInt32(), 1);
return buffer.Length - chunksize == 0 ? crc : CalculateScalar(crc, buffer.Slice(chunksize));
}
}
}
#endif

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

@ -16,4 +16,4 @@ namespace SixLabors.ImageSharp.Formats.Bmp
configuration.ImageFormatsManager.AddImageFormatDetector(new BmpImageFormatDetector());
}
}
}
}

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

@ -56,4 +56,4 @@ namespace SixLabors.ImageSharp.Formats.Bmp
public const int Pointer = 0x5450;
}
}
}
}

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

@ -34,4 +34,4 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// <inheritdoc/>
public BmpMetadata CreateDefaultFormatMetadata() => new BmpMetadata();
}
}
}

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

@ -40,4 +40,4 @@ namespace SixLabors.ImageSharp.Formats.Bmp
// TODO: Colors used once we support encoding palette bmps.
}
}
}

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

@ -13,4 +13,4 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// </summary>
RleSkippedPixelHandling RleSkippedPixelHandling { get; }
}
}
}

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

@ -16,4 +16,4 @@ namespace SixLabors.ImageSharp.Formats.Gif
configuration.ImageFormatsManager.AddImageFormatDetector(new GifImageFormatDetector());
}
}
}
}

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

@ -8,7 +8,6 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.Metadata;

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

@ -35,4 +35,4 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// </summary>
RestoreToPrevious = 3
}
}
}

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

@ -37,4 +37,4 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// <inheritdoc/>
public GifFrameMetadata CreateDefaultFormatFrameMetadata() => new GifFrameMetadata();
}
}
}

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

@ -30,4 +30,4 @@ namespace SixLabors.ImageSharp.Formats.Gif
header[5] == 0x61; // a
}
}
}
}

1
src/ImageSharp/Formats/Gif/LzwEncoder.cs

@ -6,7 +6,6 @@ using System.Buffers;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Gif

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

@ -103,4 +103,4 @@ namespace SixLabors.ImageSharp.Formats.Gif
return value;
}
}
}
}

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

@ -113,4 +113,4 @@ namespace SixLabors.ImageSharp.Formats.Gif
return value;
}
}
}
}

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

@ -130,4 +130,4 @@ namespace SixLabors.ImageSharp.Formats.Gif
return value;
}
}
}
}

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

@ -22,4 +22,4 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// <returns>The number of bytes written to the buffer.</returns>
int WriteTo(Span<byte> buffer);
}
}
}

2
src/ImageSharp/Formats/IImageFormat.cs

@ -60,4 +60,4 @@ namespace SixLabors.ImageSharp.Formats
/// <returns>The <typeparamref name="TFormatFrameMetadata"/>.</returns>
TFormatFrameMetadata CreateDefaultFormatFrameMetadata();
}
}
}

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

@ -107,4 +107,4 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
this.ColorTransform);
}
}
}
}

47
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykAvx2.cs

@ -22,60 +22,39 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
protected override void ConvertCoreVectorized(in ComponentValues values, Span<Vector4> result)
protected override void ConvertCoreVectorizedInplace(in ComponentValues values)
{
#if SUPPORTS_RUNTIME_INTRINSICS
ref Vector256<float> cBase =
ref Vector256<float> c0Base =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component0));
ref Vector256<float> mBase =
ref Vector256<float> c1Base =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component1));
ref Vector256<float> yBase =
ref Vector256<float> c2Base =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component2));
ref Vector256<float> kBase =
ref Vector256<float> c3Base =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component3));
ref Vector256<float> resultBase =
ref Unsafe.As<Vector4, Vector256<float>>(ref MemoryMarshal.GetReference(result));
// Used for the color conversion
var scale = Vector256.Create(1 / this.MaximumValue);
var one = Vector256.Create(1F);
// Used for packing
ref byte control = ref MemoryMarshal.GetReference(HwIntrinsics.PermuteMaskEvenOdd8x32);
Vector256<int> vcontrol = Unsafe.As<byte, Vector256<int>>(ref control);
int n = result.Length / 8;
for (int i = 0; i < n; i++)
nint n = values.Component0.Length / 8;
for (nint i = 0; i < n; i++)
{
Vector256<float> k = Avx2.PermuteVar8x32(Unsafe.Add(ref kBase, i), vcontrol);
Vector256<float> c = Avx2.PermuteVar8x32(Unsafe.Add(ref cBase, i), vcontrol);
Vector256<float> m = Avx2.PermuteVar8x32(Unsafe.Add(ref mBase, i), vcontrol);
Vector256<float> y = Avx2.PermuteVar8x32(Unsafe.Add(ref yBase, i), vcontrol);
ref Vector256<float> c = ref Unsafe.Add(ref c0Base, i);
ref Vector256<float> m = ref Unsafe.Add(ref c1Base, i);
ref Vector256<float> y = ref Unsafe.Add(ref c2Base, i);
Vector256<float> k = Unsafe.Add(ref c3Base, i);
k = Avx.Multiply(k, scale);
c = Avx.Multiply(Avx.Multiply(c, k), scale);
m = Avx.Multiply(Avx.Multiply(m, k), scale);
y = Avx.Multiply(Avx.Multiply(y, k), scale);
Vector256<float> cmLo = Avx.UnpackLow(c, m);
Vector256<float> yoLo = Avx.UnpackLow(y, one);
Vector256<float> cmHi = Avx.UnpackHigh(c, m);
Vector256<float> yoHi = Avx.UnpackHigh(y, one);
ref Vector256<float> destination = ref Unsafe.Add(ref resultBase, i * 4);
destination = Avx.Shuffle(cmLo, yoLo, 0b01_00_01_00);
Unsafe.Add(ref destination, 1) = Avx.Shuffle(cmLo, yoLo, 0b11_10_11_10);
Unsafe.Add(ref destination, 2) = Avx.Shuffle(cmHi, yoHi, 0b01_00_01_00);
Unsafe.Add(ref destination, 3) = Avx.Shuffle(cmHi, yoHi, 0b11_10_11_10);
}
#endif
}
protected override void ConvertCore(in ComponentValues values, Span<Vector4> result) =>
FromCmykBasic.ConvertCore(values, result, this.MaximumValue);
protected override void ConvertCoreInplace(in ComponentValues values) =>
FromCmykBasic.ConvertCoreInplace(values, this.MaximumValue);
}
}
}

45
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykBasic.cs

@ -15,38 +15,27 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
public override void ConvertToRgba(in ComponentValues values, Span<Vector4> result)
{
ConvertCore(values, result, this.MaximumValue);
}
public override void ConvertToRgbInplace(in ComponentValues values) =>
ConvertCoreInplace(values, this.MaximumValue);
internal static void ConvertCore(in ComponentValues values, Span<Vector4> result, float maxValue)
internal static void ConvertCoreInplace(in ComponentValues values, float maxValue)
{
ReadOnlySpan<float> cVals = values.Component0;
ReadOnlySpan<float> mVals = values.Component1;
ReadOnlySpan<float> yVals = values.Component2;
ReadOnlySpan<float> kVals = values.Component3;
var v = new Vector4(0, 0, 0, 1F);
var maximum = 1 / maxValue;
var scale = new Vector4(maximum, maximum, maximum, 1F);
Span<float> c0 = values.Component0;
Span<float> c1 = values.Component1;
Span<float> c2 = values.Component2;
Span<float> c3 = values.Component3;
for (int i = 0; i < result.Length; i++)
float scale = 1 / maxValue;
for (int i = 0; i < c0.Length; i++)
{
float c = cVals[i];
float m = mVals[i];
float y = yVals[i];
float k = kVals[i] / maxValue;
v.X = c * k;
v.Y = m * k;
v.Z = y * k;
v.W = 1F;
v *= scale;
result[i] = v;
float c = c0[i];
float m = c1[i];
float y = c2[i];
float k = c3[i] / maxValue;
c0[i] = c * k * scale;
c1[i] = m * k * scale;
c2[i] = y * k * scale;
}
}
}

34
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykVector8.cs

@ -18,7 +18,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
protected override void ConvertCoreVectorized(in ComponentValues values, Span<Vector4> result)
protected override void ConvertCoreVectorizedInplace(in ComponentValues values)
{
ref Vector<float> cBase =
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component0));
@ -29,43 +29,25 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
ref Vector<float> kBase =
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component3));
ref Vector4Octet resultBase =
ref Unsafe.As<Vector4, Vector4Octet>(ref MemoryMarshal.GetReference(result));
Vector4Pair cc = default;
Vector4Pair mm = default;
Vector4Pair yy = default;
ref Vector<float> ccRefAsVector = ref Unsafe.As<Vector4Pair, Vector<float>>(ref cc);
ref Vector<float> mmRefAsVector = ref Unsafe.As<Vector4Pair, Vector<float>>(ref mm);
ref Vector<float> yyRefAsVector = ref Unsafe.As<Vector4Pair, Vector<float>>(ref yy);
var scale = new Vector<float>(1 / this.MaximumValue);
// Walking 8 elements at one step:
int n = result.Length / 8;
for (int i = 0; i < n; i++)
nint n = values.Component0.Length / 8;
for (nint i = 0; i < n; i++)
{
Vector<float> c = Unsafe.Add(ref cBase, i);
Vector<float> m = Unsafe.Add(ref mBase, i);
Vector<float> y = Unsafe.Add(ref yBase, i);
ref Vector<float> c = ref Unsafe.Add(ref cBase, i);
ref Vector<float> m = ref Unsafe.Add(ref mBase, i);
ref Vector<float> y = ref Unsafe.Add(ref yBase, i);
Vector<float> k = Unsafe.Add(ref kBase, i) * scale;
c = (c * k) * scale;
m = (m * k) * scale;
y = (y * k) * scale;
ccRefAsVector = c;
mmRefAsVector = m;
yyRefAsVector = y;
// Collect (c0,c1...c8) (m0,m1...m8) (y0,y1...y8) vector values in the expected (r0,g0,g1,1), (r1,g1,g2,1) ... order:
ref Vector4Octet destination = ref Unsafe.Add(ref resultBase, i);
destination.Pack(ref cc, ref mm, ref yy);
}
}
protected override void ConvertCore(in ComponentValues values, Span<Vector4> result) =>
FromCmykBasic.ConvertCore(values, result, this.MaximumValue);
protected override void ConvertCoreInplace(in ComponentValues values) =>
FromCmykBasic.ConvertCoreInplace(values, this.MaximumValue);
}
}
}

32
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScaleAvx2.cs

@ -22,42 +22,26 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
protected override void ConvertCoreVectorized(in ComponentValues values, Span<Vector4> result)
protected override void ConvertCoreVectorizedInplace(in ComponentValues values)
{
#if SUPPORTS_RUNTIME_INTRINSICS
ref Vector256<float> gBase =
ref Vector256<float> c0Base =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component0));
ref Vector256<float> resultBase =
ref Unsafe.As<Vector4, Vector256<float>>(ref MemoryMarshal.GetReference(result));
// Used for the color conversion
var scale = Vector256.Create(1 / this.MaximumValue);
var one = Vector256.Create(1F);
// Used for packing
ref byte control = ref MemoryMarshal.GetReference(HwIntrinsics.PermuteMaskEvenOdd8x32);
Vector256<int> vcontrol = Unsafe.As<byte, Vector256<int>>(ref control);
int n = result.Length / 8;
for (int i = 0; i < n; i++)
nint n = values.Component0.Length / 8;
for (nint i = 0; i < n; i++)
{
Vector256<float> g = Avx.Multiply(Unsafe.Add(ref gBase, i), scale);
g = Avx2.PermuteVar8x32(g, vcontrol);
ref Vector256<float> destination = ref Unsafe.Add(ref resultBase, i * 4);
destination = Avx.Blend(Avx.Permute(g, 0b00_00_00_00), one, 0b1000_1000);
Unsafe.Add(ref destination, 1) = Avx.Blend(Avx.Shuffle(g, g, 0b01_01_01_01), one, 0b1000_1000);
Unsafe.Add(ref destination, 2) = Avx.Blend(Avx.Shuffle(g, g, 0b10_10_10_10), one, 0b1000_1000);
Unsafe.Add(ref destination, 3) = Avx.Blend(Avx.Shuffle(g, g, 0b11_11_11_11), one, 0b1000_1000);
ref Vector256<float> c0 = ref Unsafe.Add(ref c0Base, i);
c0 = Avx.Multiply(c0, scale);
}
#endif
}
protected override void ConvertCore(in ComponentValues values, Span<Vector4> result) =>
FromGrayscaleBasic.ConvertCore(values, result, this.MaximumValue);
protected override void ConvertCoreInplace(in ComponentValues values) =>
FromGrayscaleBasic.ScaleValues(values.Component0, this.MaximumValue);
}
}
}

38
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScaleBasic.cs

@ -17,25 +17,35 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
public override void ConvertToRgba(in ComponentValues values, Span<Vector4> result)
{
ConvertCore(values, result, this.MaximumValue);
}
public override void ConvertToRgbInplace(in ComponentValues values) =>
ScaleValues(values.Component0, this.MaximumValue);
internal static void ConvertCore(in ComponentValues values, Span<Vector4> result, float maxValue)
internal static void ScaleValues(Span<float> values, float maxValue)
{
var maximum = 1 / maxValue;
var scale = new Vector4(maximum, maximum, maximum, 1F);
Span<Vector4> vecValues = MemoryMarshal.Cast<float, Vector4>(values);
ref float sBase = ref MemoryMarshal.GetReference(values.Component0);
ref Vector4 dBase = ref MemoryMarshal.GetReference(result);
var scaleVector = new Vector4(1 / maxValue);
for (int i = 0; i < result.Length; i++)
for (int i = 0; i < vecValues.Length; i++)
{
var v = new Vector4(Unsafe.Add(ref sBase, i));
v.W = 1f;
v *= scale;
Unsafe.Add(ref dBase, i) = v;
vecValues[i] *= scaleVector;
}
values = values.Slice(vecValues.Length * 4);
if (!values.IsEmpty)
{
float scaleValue = 1f / maxValue;
values[0] *= scaleValue;
if ((uint)values.Length > 1)
{
values[1] *= scaleValue;
if ((uint)values.Length > 2)
{
values[2] *= scaleValue;
}
}
}
}
}

40
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgbAvx2.cs

@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
protected override void ConvertCoreVectorized(in ComponentValues values, Span<Vector4> result)
protected override void ConvertCoreVectorizedInplace(in ComponentValues values)
{
#if SUPPORTS_RUNTIME_INTRINSICS
ref Vector256<float> rBase =
@ -32,41 +32,23 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
ref Vector256<float> bBase =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component2));
ref Vector256<float> resultBase =
ref Unsafe.As<Vector4, Vector256<float>>(ref MemoryMarshal.GetReference(result));
// Used for the color conversion
var scale = Vector256.Create(1 / this.MaximumValue);
var one = Vector256.Create(1F);
// Used for packing
ref byte control = ref MemoryMarshal.GetReference(HwIntrinsics.PermuteMaskEvenOdd8x32);
Vector256<int> vcontrol = Unsafe.As<byte, Vector256<int>>(ref control);
int n = result.Length / 8;
for (int i = 0; i < n; i++)
nint n = values.Component0.Length / 8;
for (nint i = 0; i < n; i++)
{
Vector256<float> r = Avx.Multiply(Avx2.PermuteVar8x32(Unsafe.Add(ref rBase, i), vcontrol), scale);
Vector256<float> g = Avx.Multiply(Avx2.PermuteVar8x32(Unsafe.Add(ref gBase, i), vcontrol), scale);
Vector256<float> b = Avx.Multiply(Avx2.PermuteVar8x32(Unsafe.Add(ref bBase, i), vcontrol), scale);
Vector256<float> rgLo = Avx.UnpackLow(r, g);
Vector256<float> boLo = Avx.UnpackLow(b, one);
Vector256<float> rgHi = Avx.UnpackHigh(r, g);
Vector256<float> boHi = Avx.UnpackHigh(b, one);
ref Vector256<float> destination = ref Unsafe.Add(ref resultBase, i * 4);
destination = Avx.Shuffle(rgLo, boLo, 0b01_00_01_00);
Unsafe.Add(ref destination, 1) = Avx.Shuffle(rgLo, boLo, 0b11_10_11_10);
Unsafe.Add(ref destination, 2) = Avx.Shuffle(rgHi, boHi, 0b01_00_01_00);
Unsafe.Add(ref destination, 3) = Avx.Shuffle(rgHi, boHi, 0b11_10_11_10);
ref Vector256<float> r = ref Unsafe.Add(ref rBase, i);
ref Vector256<float> g = ref Unsafe.Add(ref gBase, i);
ref Vector256<float> b = ref Unsafe.Add(ref bBase, i);
r = Avx.Multiply(r, scale);
g = Avx.Multiply(g, scale);
b = Avx.Multiply(b, scale);
}
#endif
}
protected override void ConvertCore(in ComponentValues values, Span<Vector4> result) =>
FromRgbBasic.ConvertCore(values, result, this.MaximumValue);
protected override void ConvertCoreInplace(in ComponentValues values) =>
FromRgbBasic.ConvertCoreInplace(values, this.MaximumValue);
}
}
}

33
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgbBasic.cs

@ -3,6 +3,7 @@
using System;
using System.Numerics;
using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
@ -15,36 +16,16 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
public override void ConvertToRgba(in ComponentValues values, Span<Vector4> result)
public override void ConvertToRgbInplace(in ComponentValues values)
{
ConvertCore(values, result, this.MaximumValue);
ConvertCoreInplace(values, this.MaximumValue);
}
internal static void ConvertCore(in ComponentValues values, Span<Vector4> result, float maxValue)
internal static void ConvertCoreInplace(ComponentValues values, float maxValue)
{
ReadOnlySpan<float> rVals = values.Component0;
ReadOnlySpan<float> gVals = values.Component1;
ReadOnlySpan<float> bVals = values.Component2;
var v = new Vector4(0, 0, 0, 1);
var maximum = 1 / maxValue;
var scale = new Vector4(maximum, maximum, maximum, 1F);
for (int i = 0; i < result.Length; i++)
{
float r = rVals[i];
float g = gVals[i];
float b = bVals[i];
v.X = r;
v.Y = g;
v.Z = b;
v *= scale;
result[i] = v;
}
FromGrayscaleBasic.ScaleValues(values.Component0, maxValue);
FromGrayscaleBasic.ScaleValues(values.Component1, maxValue);
FromGrayscaleBasic.ScaleValues(values.Component2, maxValue);
}
}
}

40
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgbVector8.cs

@ -18,50 +18,32 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
protected override void ConvertCoreVectorized(in ComponentValues values, Span<Vector4> result)
protected override void ConvertCoreVectorizedInplace(in ComponentValues values)
{
ref Vector<float> rBase =
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component0));
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component0));
ref Vector<float> gBase =
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component1));
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component1));
ref Vector<float> bBase =
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component2));
ref Vector4Octet resultBase =
ref Unsafe.As<Vector4, Vector4Octet>(ref MemoryMarshal.GetReference(result));
Vector4Pair rr = default;
Vector4Pair gg = default;
Vector4Pair bb = default;
ref Vector<float> rrRefAsVector = ref Unsafe.As<Vector4Pair, Vector<float>>(ref rr);
ref Vector<float> ggRefAsVector = ref Unsafe.As<Vector4Pair, Vector<float>>(ref gg);
ref Vector<float> bbRefAsVector = ref Unsafe.As<Vector4Pair, Vector<float>>(ref bb);
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component2));
var scale = new Vector<float>(1 / this.MaximumValue);
// Walking 8 elements at one step:
int n = result.Length / 8;
for (int i = 0; i < n; i++)
nint n = values.Component0.Length / 8;
for (nint i = 0; i < n; i++)
{
Vector<float> r = Unsafe.Add(ref rBase, i);
Vector<float> g = Unsafe.Add(ref gBase, i);
Vector<float> b = Unsafe.Add(ref bBase, i);
ref Vector<float> r = ref Unsafe.Add(ref rBase, i);
ref Vector<float> g = ref Unsafe.Add(ref gBase, i);
ref Vector<float> b = ref Unsafe.Add(ref bBase, i);
r *= scale;
g *= scale;
b *= scale;
rrRefAsVector = r;
ggRefAsVector = g;
bbRefAsVector = b;
// Collect (r0,r1...r8) (g0,g1...g8) (b0,b1...b8) vector values in the expected (r0,g0,g1,1), (r1,g1,g2,1) ... order:
ref Vector4Octet destination = ref Unsafe.Add(ref resultBase, i);
destination.Pack(ref rr, ref gg, ref bb);
}
}
protected override void ConvertCore(in ComponentValues values, Span<Vector4> result) =>
FromRgbBasic.ConvertCore(values, result, this.MaximumValue);
protected override void ConvertCoreInplace(in ComponentValues values) =>
FromRgbBasic.ConvertCoreInplace(values, this.MaximumValue);
}
}
}

50
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrAvx2.cs

@ -23,19 +23,16 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
protected override void ConvertCoreVectorized(in ComponentValues values, Span<Vector4> result)
protected override void ConvertCoreVectorizedInplace(in ComponentValues values)
{
#if SUPPORTS_RUNTIME_INTRINSICS
ref Vector256<float> yBase =
#if SUPPORTS_RUNTIME_INTRINSICS
ref Vector256<float> c0Base =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component0));
ref Vector256<float> cbBase =
ref Vector256<float> c1Base =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component1));
ref Vector256<float> crBase =
ref Vector256<float> c2Base =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component2));
ref Vector256<float> resultBase =
ref Unsafe.As<Vector4, Vector256<float>>(ref MemoryMarshal.GetReference(result));
// Used for the color conversion
var chromaOffset = Vector256.Create(-this.HalfValue);
var scale = Vector256.Create(1 / this.MaximumValue);
@ -50,19 +47,19 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
Vector256<int> vcontrol = Unsafe.As<byte, Vector256<int>>(ref control);
// Walking 8 elements at one step:
int n = result.Length / 8;
for (int i = 0; i < n; i++)
nint n = values.Component0.Length / 8;
for (nint i = 0; i < n; i++)
{
// y = yVals[i];
// cb = cbVals[i] - 128F;
// cr = crVals[i] - 128F;
Vector256<float> y = Unsafe.Add(ref yBase, i);
Vector256<float> cb = Avx.Add(Unsafe.Add(ref cbBase, i), chromaOffset);
Vector256<float> cr = Avx.Add(Unsafe.Add(ref crBase, i), chromaOffset);
ref Vector256<float> c0 = ref Unsafe.Add(ref c0Base, i);
ref Vector256<float> c1 = ref Unsafe.Add(ref c1Base, i);
ref Vector256<float> c2 = ref Unsafe.Add(ref c2Base, i);
y = Avx2.PermuteVar8x32(y, vcontrol);
cb = Avx2.PermuteVar8x32(cb, vcontrol);
cr = Avx2.PermuteVar8x32(cr, vcontrol);
Vector256<float> y = c0;
Vector256<float> cb = Avx.Add(c1, chromaOffset);
Vector256<float> cr = Avx.Add(c2, chromaOffset);
// r = y + (1.402F * cr);
// g = y - (0.344136F * cb) - (0.714136F * cr);
@ -72,30 +69,19 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
Vector256<float> g = HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(y, cb, gCbMult), cr, gCrMult);
Vector256<float> b = HwIntrinsics.MultiplyAdd(y, cb, bCbMult);
// TODO: We should be saving to RGBA not Vector4
r = Avx.Multiply(Avx.RoundToNearestInteger(r), scale);
g = Avx.Multiply(Avx.RoundToNearestInteger(g), scale);
b = Avx.Multiply(Avx.RoundToNearestInteger(b), scale);
Vector256<float> vte = Avx.UnpackLow(r, b);
Vector256<float> vto = Avx.UnpackLow(g, va);
ref Vector256<float> destination = ref Unsafe.Add(ref resultBase, i * 4);
destination = Avx.UnpackLow(vte, vto);
Unsafe.Add(ref destination, 1) = Avx.UnpackHigh(vte, vto);
vte = Avx.UnpackHigh(r, b);
vto = Avx.UnpackHigh(g, va);
Unsafe.Add(ref destination, 2) = Avx.UnpackLow(vte, vto);
Unsafe.Add(ref destination, 3) = Avx.UnpackHigh(vte, vto);
c0 = r;
c1 = g;
c2 = b;
}
#endif
}
protected override void ConvertCore(in ComponentValues values, Span<Vector4> result) =>
FromYCbCrBasic.ConvertCore(values, result, this.MaximumValue, this.HalfValue);
protected override void ConvertCoreInplace(in ComponentValues values) =>
FromYCbCrBasic.ConvertCoreInplace(values, this.MaximumValue, this.HalfValue);
}
}
}

37
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrBasic.cs

@ -15,35 +15,26 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
public override void ConvertToRgba(in ComponentValues values, Span<Vector4> result)
{
ConvertCore(values, result, this.MaximumValue, this.HalfValue);
}
public override void ConvertToRgbInplace(in ComponentValues values)
=> ConvertCoreInplace(values, this.MaximumValue, this.HalfValue);
internal static void ConvertCore(in ComponentValues values, Span<Vector4> result, float maxValue, float halfValue)
internal static void ConvertCoreInplace(in ComponentValues values, float maxValue, float halfValue)
{
// TODO: We can optimize a lot here with Vector<float> and SRCS.Unsafe()!
ReadOnlySpan<float> yVals = values.Component0;
ReadOnlySpan<float> cbVals = values.Component1;
ReadOnlySpan<float> crVals = values.Component2;
var v = new Vector4(0, 0, 0, 1);
Span<float> c0 = values.Component0;
Span<float> c1 = values.Component1;
Span<float> c2 = values.Component2;
var scale = new Vector4(1 / maxValue, 1 / maxValue, 1 / maxValue, 1F);
var scale = 1 / maxValue;
for (int i = 0; i < result.Length; i++)
for (int i = 0; i < c0.Length; i++)
{
float y = yVals[i];
float cb = cbVals[i] - halfValue;
float cr = crVals[i] - halfValue;
v.X = MathF.Round(y + (1.402F * cr), MidpointRounding.AwayFromZero);
v.Y = MathF.Round(y - (0.344136F * cb) - (0.714136F * cr), MidpointRounding.AwayFromZero);
v.Z = MathF.Round(y + (1.772F * cb), MidpointRounding.AwayFromZero);
v *= scale;
float y = c0[i];
float cb = c1[i] - halfValue;
float cr = c2[i] - halfValue;
result[i] = v;
c0[i] = MathF.Round(y + (1.402F * cr), MidpointRounding.AwayFromZero) * scale;
c1[i] = MathF.Round(y - (0.344136F * cb) - (0.714136F * cr), MidpointRounding.AwayFromZero) * scale;
c2[i] = MathF.Round(y + (1.772F * cb), MidpointRounding.AwayFromZero) * scale;
}
}
}

52
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrVector4.cs

@ -20,58 +20,54 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
protected override bool IsAvailable => SimdUtils.HasVector4;
protected override void ConvertCoreVectorized(in ComponentValues values, Span<Vector4> result)
protected override void ConvertCoreVectorizedInplace(in ComponentValues values)
{
// TODO: Find a way to properly run & test this path on AVX2 PC-s! (Have I already mentioned that Vector<T> is terrible?)
DebugGuard.IsTrue(result.Length % 8 == 0, nameof(result), "result.Length should be divisible by 8!");
DebugGuard.IsTrue(values.Component0.Length % 8 == 0, nameof(values), "Length should be divisible by 8!");
ref Vector4Pair yBase =
ref Vector4Pair c0Base =
ref Unsafe.As<float, Vector4Pair>(ref MemoryMarshal.GetReference(values.Component0));
ref Vector4Pair cbBase =
ref Vector4Pair c1Base =
ref Unsafe.As<float, Vector4Pair>(ref MemoryMarshal.GetReference(values.Component1));
ref Vector4Pair crBase =
ref Vector4Pair c2Base =
ref Unsafe.As<float, Vector4Pair>(ref MemoryMarshal.GetReference(values.Component2));
ref Vector4Octet resultBase =
ref Unsafe.As<Vector4, Vector4Octet>(ref MemoryMarshal.GetReference(result));
var chromaOffset = new Vector4(-this.HalfValue);
var maxValue = this.MaximumValue;
// Walking 8 elements at one step:
int n = result.Length / 8;
nint n = values.Component0.Length / 8;
for (int i = 0; i < n; i++)
for (nint i = 0; i < n; i++)
{
// y = yVals[i];
Vector4Pair y = Unsafe.Add(ref yBase, i);
ref Vector4Pair c0 = ref Unsafe.Add(ref c0Base, i);
// cb = cbVals[i] - halfValue);
Vector4Pair cb = Unsafe.Add(ref cbBase, i);
cb.AddInplace(chromaOffset);
ref Vector4Pair c1 = ref Unsafe.Add(ref c1Base, i);
c1.AddInplace(chromaOffset);
// cr = crVals[i] - halfValue;
Vector4Pair cr = Unsafe.Add(ref crBase, i);
cr.AddInplace(chromaOffset);
ref Vector4Pair c2 = ref Unsafe.Add(ref c2Base, i);
c2.AddInplace(chromaOffset);
// r = y + (1.402F * cr);
Vector4Pair r = y;
Vector4Pair tmp = cr;
Vector4Pair r = c0;
Vector4Pair tmp = c2;
tmp.MultiplyInplace(1.402F);
r.AddInplace(ref tmp);
// g = y - (0.344136F * cb) - (0.714136F * cr);
Vector4Pair g = y;
tmp = cb;
Vector4Pair g = c0;
tmp = c1;
tmp.MultiplyInplace(-0.344136F);
g.AddInplace(ref tmp);
tmp = cr;
tmp = c2;
tmp.MultiplyInplace(-0.714136F);
g.AddInplace(ref tmp);
// b = y + (1.772F * cb);
Vector4Pair b = y;
tmp = cb;
Vector4Pair b = c0;
tmp = c1;
tmp.MultiplyInplace(1.772F);
b.AddInplace(ref tmp);
@ -79,14 +75,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
g.RoundAndDownscalePreVector8(maxValue);
b.RoundAndDownscalePreVector8(maxValue);
// Collect (r0,r1...r8) (g0,g1...g8) (b0,b1...b8) vector values in the expected (r0,g0,g1,1), (r1,g1,g2,1) ... order:
ref Vector4Octet destination = ref Unsafe.Add(ref resultBase, i);
destination.Pack(ref r, ref g, ref b);
c0 = r;
c1 = g;
c2 = b;
}
}
protected override void ConvertCore(in ComponentValues values, Span<Vector4> result) =>
FromYCbCrBasic.ConvertCore(values, result, this.MaximumValue, this.HalfValue);
protected override void ConvertCoreInplace(in ComponentValues values)
=> FromYCbCrBasic.ConvertCoreInplace(values, this.MaximumValue, this.HalfValue);
}
}
}

47
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrVector8.cs

@ -19,41 +19,32 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
protected override void ConvertCoreVectorized(in ComponentValues values, Span<Vector4> result)
protected override void ConvertCoreVectorizedInplace(in ComponentValues values)
{
ref Vector<float> yBase =
ref Vector<float> c0Base =
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component0));
ref Vector<float> cbBase =
ref Vector<float> c1Base =
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component1));
ref Vector<float> crBase =
ref Vector<float> c2Base =
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component2));
ref Vector4Octet resultBase =
ref Unsafe.As<Vector4, Vector4Octet>(ref MemoryMarshal.GetReference(result));
var chromaOffset = new Vector<float>(-this.HalfValue);
// Walking 8 elements at one step:
int n = result.Length / 8;
Vector4Pair rr = default;
Vector4Pair gg = default;
Vector4Pair bb = default;
ref Vector<float> rrRefAsVector = ref Unsafe.As<Vector4Pair, Vector<float>>(ref rr);
ref Vector<float> ggRefAsVector = ref Unsafe.As<Vector4Pair, Vector<float>>(ref gg);
ref Vector<float> bbRefAsVector = ref Unsafe.As<Vector4Pair, Vector<float>>(ref bb);
nint n = values.Component0.Length / 8;
var scale = new Vector<float>(1 / this.MaximumValue);
for (int i = 0; i < n; i++)
for (nint i = 0; i < n; i++)
{
// y = yVals[i];
// cb = cbVals[i] - 128F;
// cr = crVals[i] - 128F;
Vector<float> y = Unsafe.Add(ref yBase, i);
Vector<float> cb = Unsafe.Add(ref cbBase, i) + chromaOffset;
Vector<float> cr = Unsafe.Add(ref crBase, i) + chromaOffset;
ref Vector<float> c0 = ref Unsafe.Add(ref c0Base, i);
ref Vector<float> c1 = ref Unsafe.Add(ref c1Base, i);
ref Vector<float> c2 = ref Unsafe.Add(ref c2Base, i);
Vector<float> y = Unsafe.Add(ref c0Base, i);
Vector<float> cb = Unsafe.Add(ref c1Base, i) + chromaOffset;
Vector<float> cr = Unsafe.Add(ref c2Base, i) + chromaOffset;
// r = y + (1.402F * cr);
// g = y - (0.344136F * cb) - (0.714136F * cr);
@ -70,18 +61,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
g *= scale;
b *= scale;
rrRefAsVector = r;
ggRefAsVector = g;
bbRefAsVector = b;
// Collect (r0,r1...r8) (g0,g1...g8) (b0,b1...b8) vector values in the expected (r0,g0,g1,1), (r1,g1,g2,1) ... order:
ref Vector4Octet destination = ref Unsafe.Add(ref resultBase, i);
destination.Pack(ref rr, ref gg, ref bb);
c0 = r;
c1 = g;
c2 = b;
}
}
protected override void ConvertCore(in ComponentValues values, Span<Vector4> result) =>
FromYCbCrBasic.ConvertCore(values, result, this.MaximumValue, this.HalfValue);
protected override void ConvertCoreInplace(in ComponentValues values) =>
FromYCbCrBasic.ConvertCoreInplace(values, this.MaximumValue, this.HalfValue);
}
}
}

64
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccKAvx2.cs

@ -22,52 +22,42 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
protected override void ConvertCoreVectorized(in ComponentValues values, Span<Vector4> result)
protected override void ConvertCoreVectorizedInplace(in ComponentValues values)
{
#if SUPPORTS_RUNTIME_INTRINSICS
ref Vector256<float> yBase =
ref Vector256<float> c0Base =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component0));
ref Vector256<float> cbBase =
ref Vector256<float> c1Base =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component1));
ref Vector256<float> crBase =
ref Vector256<float> c2Base =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component2));
ref Vector256<float> kBase =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component3));
ref Vector256<float> resultBase =
ref Unsafe.As<Vector4, Vector256<float>>(ref MemoryMarshal.GetReference(result));
// Used for the color conversion
var chromaOffset = Vector256.Create(-this.HalfValue);
var scale = Vector256.Create(1 / this.MaximumValue);
var scale = Vector256.Create(1 / (this.MaximumValue * this.MaximumValue));
var max = Vector256.Create(this.MaximumValue);
var rCrMult = Vector256.Create(1.402F);
var gCbMult = Vector256.Create(-0.344136F);
var gCrMult = Vector256.Create(-0.714136F);
var bCbMult = Vector256.Create(1.772F);
// Used for packing.
var va = Vector256.Create(1F);
ref byte control = ref MemoryMarshal.GetReference(HwIntrinsics.PermuteMaskEvenOdd8x32);
Vector256<int> vcontrol = Unsafe.As<byte, Vector256<int>>(ref control);
// Walking 8 elements at one step:
int n = result.Length / 8;
for (int i = 0; i < n; i++)
nint n = values.Component0.Length / 8;
for (nint i = 0; i < n; i++)
{
// y = yVals[i];
// cb = cbVals[i] - 128F;
// cr = crVals[i] - 128F;
// k = kVals[i] / 256F;
Vector256<float> y = Unsafe.Add(ref yBase, i);
Vector256<float> cb = Avx.Add(Unsafe.Add(ref cbBase, i), chromaOffset);
Vector256<float> cr = Avx.Add(Unsafe.Add(ref crBase, i), chromaOffset);
Vector256<float> k = Avx.Divide(Unsafe.Add(ref kBase, i), max);
y = Avx2.PermuteVar8x32(y, vcontrol);
cb = Avx2.PermuteVar8x32(cb, vcontrol);
cr = Avx2.PermuteVar8x32(cr, vcontrol);
k = Avx2.PermuteVar8x32(k, vcontrol);
ref Vector256<float> c0 = ref Unsafe.Add(ref c0Base, i);
ref Vector256<float> c1 = ref Unsafe.Add(ref c1Base, i);
ref Vector256<float> c2 = ref Unsafe.Add(ref c2Base, i);
Vector256<float> y = c0;
Vector256<float> cb = Avx.Add(c1, chromaOffset);
Vector256<float> cr = Avx.Add(c2, chromaOffset);
Vector256<float> scaledK = Avx.Multiply(Unsafe.Add(ref kBase, i), scale);
// r = y + (1.402F * cr);
// g = y - (0.344136F * cb) - (0.714136F * cr);
@ -82,29 +72,19 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
g = Avx.Subtract(max, Avx.RoundToNearestInteger(g));
b = Avx.Subtract(max, Avx.RoundToNearestInteger(b));
r = Avx.Multiply(Avx.Multiply(r, k), scale);
g = Avx.Multiply(Avx.Multiply(g, k), scale);
b = Avx.Multiply(Avx.Multiply(b, k), scale);
Vector256<float> vte = Avx.UnpackLow(r, b);
Vector256<float> vto = Avx.UnpackLow(g, va);
ref Vector256<float> destination = ref Unsafe.Add(ref resultBase, i * 4);
destination = Avx.UnpackLow(vte, vto);
Unsafe.Add(ref destination, 1) = Avx.UnpackHigh(vte, vto);
vte = Avx.UnpackHigh(r, b);
vto = Avx.UnpackHigh(g, va);
r = Avx.Multiply(r, scaledK);
g = Avx.Multiply(g, scaledK);
b = Avx.Multiply(b, scaledK);
Unsafe.Add(ref destination, 2) = Avx.UnpackLow(vte, vto);
Unsafe.Add(ref destination, 3) = Avx.UnpackHigh(vte, vto);
c0 = r;
c1 = g;
c2 = b;
}
#endif
}
protected override void ConvertCore(in ComponentValues values, Span<Vector4> result) =>
FromYccKBasic.ConvertCore(values, result, this.MaximumValue, this.HalfValue);
protected override void ConvertCoreInplace(in ComponentValues values) =>
FromYccKBasic.ConvertCoreInplace(values, this.MaximumValue, this.HalfValue);
}
}
}

43
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccKBasic.cs

@ -15,39 +15,30 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
public override void ConvertToRgba(in ComponentValues values, Span<Vector4> result)
{
ConvertCore(values, result, this.MaximumValue, this.HalfValue);
}
public override void ConvertToRgbInplace(in ComponentValues values) =>
ConvertCoreInplace(values, this.MaximumValue, this.HalfValue);
internal static void ConvertCore(in ComponentValues values, Span<Vector4> result, float maxValue, float halfValue)
internal static void ConvertCoreInplace(in ComponentValues values, float maxValue, float halfValue)
{
// TODO: We can optimize a lot here with Vector<float> and SRCS.Unsafe()!
ReadOnlySpan<float> yVals = values.Component0;
ReadOnlySpan<float> cbVals = values.Component1;
ReadOnlySpan<float> crVals = values.Component2;
ReadOnlySpan<float> kVals = values.Component3;
Span<float> c0 = values.Component0;
Span<float> c1 = values.Component1;
Span<float> c2 = values.Component2;
Span<float> c3 = values.Component3;
var v = new Vector4(0, 0, 0, 1F);
var maximum = 1 / maxValue;
var scale = new Vector4(maximum, maximum, maximum, 1F);
var scale = 1 / (maxValue * maxValue);
for (int i = 0; i < result.Length; i++)
for (int i = 0; i < values.Component0.Length; i++)
{
float y = yVals[i];
float cb = cbVals[i] - halfValue;
float cr = crVals[i] - halfValue;
float k = kVals[i] / maxValue;
v.X = (maxValue - MathF.Round(y + (1.402F * cr), MidpointRounding.AwayFromZero)) * k;
v.Y = (maxValue - MathF.Round(y - (0.344136F * cb) - (0.714136F * cr), MidpointRounding.AwayFromZero)) * k;
v.Z = (maxValue - MathF.Round(y + (1.772F * cb), MidpointRounding.AwayFromZero)) * k;
v.W = 1F;
v *= scale;
result[i] = v;
float y = c0[i];
float cb = c1[i] - halfValue;
float cr = c2[i] - halfValue;
float scaledK = c3[i] * scale;
c0[i] = (maxValue - MathF.Round(y + (1.402F * cr), MidpointRounding.AwayFromZero)) * scaledK;
c1[i] = (maxValue - MathF.Round(y - (0.344136F * cb) - (0.714136F * cr), MidpointRounding.AwayFromZero)) * scaledK;
c2[i] = (maxValue - MathF.Round(y + (1.772F * cb), MidpointRounding.AwayFromZero)) * scaledK;
}
}
}

60
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccKVector8.cs

@ -18,46 +18,39 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
protected override void ConvertCoreVectorized(in ComponentValues values, Span<Vector4> result)
protected override void ConvertCoreVectorizedInplace(in ComponentValues values)
{
ref Vector<float> yBase =
ref Vector<float> c0Base =
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component0));
ref Vector<float> cbBase =
ref Vector<float> c1Base =
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component1));
ref Vector<float> crBase =
ref Vector<float> c2Base =
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component2));
ref Vector<float> kBase =
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component3));
ref Vector4Octet resultBase =
ref Unsafe.As<Vector4, Vector4Octet>(ref MemoryMarshal.GetReference(result));
var chromaOffset = new Vector<float>(-this.HalfValue);
// Walking 8 elements at one step:
int n = result.Length / 8;
Vector4Pair rr = default;
Vector4Pair gg = default;
Vector4Pair bb = default;
ref Vector<float> rrRefAsVector = ref Unsafe.As<Vector4Pair, Vector<float>>(ref rr);
ref Vector<float> ggRefAsVector = ref Unsafe.As<Vector4Pair, Vector<float>>(ref gg);
ref Vector<float> bbRefAsVector = ref Unsafe.As<Vector4Pair, Vector<float>>(ref bb);
nint n = values.Component0.Length / 8;
var scale = new Vector<float>(1 / this.MaximumValue);
var max = new Vector<float>(this.MaximumValue);
var scale = new Vector<float>(1f) / (max * max);
for (int i = 0; i < n; i++)
for (nint i = 0; i < n; i++)
{
// y = yVals[i];
// cb = cbVals[i] - 128F;
// cr = crVals[i] - 128F;
// k = kVals[i] / 256F;
Vector<float> y = Unsafe.Add(ref yBase, i);
Vector<float> cb = Unsafe.Add(ref cbBase, i) + chromaOffset;
Vector<float> cr = Unsafe.Add(ref crBase, i) + chromaOffset;
Vector<float> k = Unsafe.Add(ref kBase, i) / max;
ref Vector<float> c0 = ref Unsafe.Add(ref c0Base, i);
ref Vector<float> c1 = ref Unsafe.Add(ref c1Base, i);
ref Vector<float> c2 = ref Unsafe.Add(ref c2Base, i);
Vector<float> y = c0;
Vector<float> cb = c1 + chromaOffset;
Vector<float> cr = c2 + chromaOffset;
Vector<float> scaledK = Unsafe.Add(ref kBase, i) * scale;
// r = y + (1.402F * cr);
// g = y - (0.344136F * cb) - (0.714136F * cr);
@ -67,25 +60,18 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
Vector<float> g = y - (cb * new Vector<float>(0.344136F)) - (cr * new Vector<float>(0.714136F));
Vector<float> b = y + (cb * new Vector<float>(1.772F));
r = (max - r.FastRound()) * k;
g = (max - g.FastRound()) * k;
b = (max - b.FastRound()) * k;
r *= scale;
g *= scale;
b *= scale;
rrRefAsVector = r;
ggRefAsVector = g;
bbRefAsVector = b;
r = (max - r.FastRound()) * scaledK;
g = (max - g.FastRound()) * scaledK;
b = (max - b.FastRound()) * scaledK;
// Collect (r0,r1...r8) (g0,g1...g8) (b0,b1...b8) vector values in the expected (r0,g0,g1,1), (r1,g1,g2,1) ... order:
ref Vector4Octet destination = ref Unsafe.Add(ref resultBase, i);
destination.Pack(ref rr, ref gg, ref bb);
c0 = r;
c1 = g;
c2 = b;
}
}
protected override void ConvertCore(in ComponentValues values, Span<Vector4> result) =>
FromYccKBasic.ConvertCore(values, result, this.MaximumValue, this.HalfValue);
protected override void ConvertCoreInplace(in ComponentValues values) =>
FromYccKBasic.ConvertCoreInplace(values, this.MaximumValue, this.HalfValue);
}
}
}

15
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.VectorizedJpegColorConverter.cs

@ -18,10 +18,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
this.vectorSize = vectorSize;
}
public sealed override void ConvertToRgba(in ComponentValues values, Span<Vector4> result)
public override void ConvertToRgbInplace(in ComponentValues values)
{
int remainder = result.Length % this.vectorSize;
int simdCount = result.Length - remainder;
int length = values.Component0.Length;
int remainder = values.Component0.Length % this.vectorSize;
int simdCount = length - remainder;
if (simdCount > 0)
{
// This implementation is actually AVX specific.
@ -32,15 +33,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
"This converter can be used only on architecture having 256 byte floating point SIMD registers!");
}
this.ConvertCoreVectorized(values.Slice(0, simdCount), result.Slice(0, simdCount));
this.ConvertCoreVectorizedInplace(values.Slice(0, simdCount));
}
this.ConvertCore(values.Slice(simdCount, remainder), result.Slice(simdCount, remainder));
this.ConvertCoreInplace(values.Slice(simdCount, remainder));
}
protected abstract void ConvertCoreVectorized(in ComponentValues values, Span<Vector4> result);
protected virtual void ConvertCoreVectorizedInplace(in ComponentValues values) => throw new NotImplementedException();
protected abstract void ConvertCore(in ComponentValues values, Span<Vector4> result);
protected virtual void ConvertCoreInplace(in ComponentValues values) => throw new NotImplementedException();
}
}
}

156
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs

@ -76,11 +76,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
}
/// <summary>
/// He implementation of the conversion.
/// Converts planar jpeg component values in <paramref name="values"/> to RGB color space inplace.
/// </summary>
/// <param name="values">The input as a stack-only <see cref="ComponentValues"/> struct</param>
/// <param name="result">The destination buffer of <see cref="Vector4"/> values</param>
public abstract void ConvertToRgba(in ComponentValues values, Span<Vector4> result);
/// <param name="values">The input/ouptut as a stack-only <see cref="ComponentValues"/> struct</param>
public abstract void ConvertToRgbInplace(in ComponentValues values);
/// <summary>
/// Returns the <see cref="JpegColorConverter"/>s for all supported colorspaces and precisions.
@ -181,22 +180,22 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
/// <summary>
/// The component 0 (eg. Y)
/// </summary>
public readonly ReadOnlySpan<float> Component0;
public readonly Span<float> Component0;
/// <summary>
/// The component 1 (eg. Cb)
/// The component 1 (eg. Cb). In case of grayscale, it points to <see cref="Component0"/>.
/// </summary>
public readonly ReadOnlySpan<float> Component1;
public readonly Span<float> Component1;
/// <summary>
/// The component 2 (eg. Cr)
/// The component 2 (eg. Cr). In case of grayscale, it points to <see cref="Component0"/>.
/// </summary>
public readonly ReadOnlySpan<float> Component2;
public readonly Span<float> Component2;
/// <summary>
/// The component 4
/// </summary>
public readonly ReadOnlySpan<float> Component3;
public readonly Span<float> Component3;
/// <summary>
/// Initializes a new instance of the <see cref="ComponentValues"/> struct.
@ -208,30 +207,19 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
this.ComponentCount = componentBuffers.Count;
this.Component0 = componentBuffers[0].GetRowSpan(row);
this.Component1 = Span<float>.Empty;
this.Component2 = Span<float>.Empty;
this.Component3 = Span<float>.Empty;
if (this.ComponentCount > 1)
{
this.Component1 = componentBuffers[1].GetRowSpan(row);
if (this.ComponentCount > 2)
{
this.Component2 = componentBuffers[2].GetRowSpan(row);
if (this.ComponentCount > 3)
{
this.Component3 = componentBuffers[3].GetRowSpan(row);
}
}
}
// In case of grayscale, Component1 and Component2 point to Component0 memory area
this.Component1 = this.ComponentCount > 1 ? componentBuffers[1].GetRowSpan(row) : this.Component0;
this.Component2 = this.ComponentCount > 2 ? componentBuffers[2].GetRowSpan(row) : this.Component0;
this.Component3 = this.ComponentCount > 3 ? componentBuffers[3].GetRowSpan(row) : Span<float>.Empty;
}
private ComponentValues(
internal ComponentValues(
int componentCount,
ReadOnlySpan<float> c0,
ReadOnlySpan<float> c1,
ReadOnlySpan<float> c2,
ReadOnlySpan<float> c3)
Span<float> c0,
Span<float> c1,
Span<float> c2,
Span<float> c3)
{
this.ComponentCount = componentCount;
this.Component0 = c0;
@ -242,111 +230,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
public ComponentValues Slice(int start, int length)
{
ReadOnlySpan<float> c0 = this.Component0.Slice(start, length);
ReadOnlySpan<float> c1 = this.ComponentCount > 1 ? this.Component1.Slice(start, length) : ReadOnlySpan<float>.Empty;
ReadOnlySpan<float> c2 = this.ComponentCount > 2 ? this.Component2.Slice(start, length) : ReadOnlySpan<float>.Empty;
ReadOnlySpan<float> c3 = this.ComponentCount > 3 ? this.Component3.Slice(start, length) : ReadOnlySpan<float>.Empty;
Span<float> c0 = this.Component0.Slice(start, length);
Span<float> c1 = this.Component1.Length > 0 ? this.Component1.Slice(start, length) : Span<float>.Empty;
Span<float> c2 = this.Component2.Length > 0 ? this.Component2.Slice(start, length) : Span<float>.Empty;
Span<float> c3 = this.Component3.Length > 0 ? this.Component3.Slice(start, length) : Span<float>.Empty;
return new ComponentValues(this.ComponentCount, c0, c1, c2, c3);
}
}
internal struct Vector4Octet
{
#pragma warning disable SA1132 // Do not combine fields
public Vector4 V0, V1, V2, V3, V4, V5, V6, V7;
/// <summary>
/// Pack (r0,r1...r7) (g0,g1...g7) (b0,b1...b7) vector values as (r0,g0,b0,1), (r1,g1,b1,1) ...
/// </summary>
public void Pack(ref Vector4Pair r, ref Vector4Pair g, ref Vector4Pair b)
{
this.V0.X = r.A.X;
this.V0.Y = g.A.X;
this.V0.Z = b.A.X;
this.V0.W = 1f;
this.V1.X = r.A.Y;
this.V1.Y = g.A.Y;
this.V1.Z = b.A.Y;
this.V1.W = 1f;
this.V2.X = r.A.Z;
this.V2.Y = g.A.Z;
this.V2.Z = b.A.Z;
this.V2.W = 1f;
this.V3.X = r.A.W;
this.V3.Y = g.A.W;
this.V3.Z = b.A.W;
this.V3.W = 1f;
this.V4.X = r.B.X;
this.V4.Y = g.B.X;
this.V4.Z = b.B.X;
this.V4.W = 1f;
this.V5.X = r.B.Y;
this.V5.Y = g.B.Y;
this.V5.Z = b.B.Y;
this.V5.W = 1f;
this.V6.X = r.B.Z;
this.V6.Y = g.B.Z;
this.V6.Z = b.B.Z;
this.V6.W = 1f;
this.V7.X = r.B.W;
this.V7.Y = g.B.W;
this.V7.Z = b.B.W;
this.V7.W = 1f;
}
/// <summary>
/// Pack (g0,g1...g7) vector values as (g0,g0,g0,1), (g1,g1,g1,1) ...
/// </summary>
public void Pack(ref Vector4Pair g)
{
this.V0.X = g.A.X;
this.V0.Y = g.A.X;
this.V0.Z = g.A.X;
this.V0.W = 1f;
this.V1.X = g.A.Y;
this.V1.Y = g.A.Y;
this.V1.Z = g.A.Y;
this.V1.W = 1f;
this.V2.X = g.A.Z;
this.V2.Y = g.A.Z;
this.V2.Z = g.A.Z;
this.V2.W = 1f;
this.V3.X = g.A.W;
this.V3.Y = g.A.W;
this.V3.Z = g.A.W;
this.V3.W = 1f;
this.V4.X = g.B.X;
this.V4.Y = g.B.X;
this.V4.Z = g.B.X;
this.V4.W = 1f;
this.V5.X = g.B.Y;
this.V5.Y = g.B.Y;
this.V5.Z = g.B.Y;
this.V5.W = 1f;
this.V6.X = g.B.Z;
this.V6.Y = g.B.Z;
this.V6.Z = g.B.Z;
this.V6.W = 1f;
this.V7.X = g.B.W;
this.V7.Y = g.B.W;
this.V7.Z = g.B.W;
this.V7.W = 1f;
}
}
}
}

6
src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanScanBuffer.cs

@ -80,7 +80,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
[MethodImpl(InliningOptions.ShortMethod)]
public bool HasBadMarker() => this.Marker != JpegConstants.Markers.XFF && !this.HasRestartMarker();
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(InliningOptions.AlwaysInline)]
public void FillBuffer()
{
// Attempt to load at least the minimum number of required bits into the buffer.
@ -130,7 +130,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
[MethodImpl(InliningOptions.ShortMethod)]
public int PeekBits(int nbits) => (int)ExtractBits(this.data, this.remainingBits - nbits, nbits);
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(InliningOptions.AlwaysInline)]
private static ulong ExtractBits(ulong value, int offset, int size) => (value >> offset) & (ulong)((1 << size) - 1);
[MethodImpl(InliningOptions.ShortMethod)]
@ -207,7 +207,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
}
}
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(InliningOptions.AlwaysInline)]
private int ReadStream()
{
int value = this.badData ? 0 : this.stream.ReadByte();

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

@ -45,4 +45,4 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
/// </summary>
Buffer2D<Block8x8> SpectralBlocks { get; }
}
}
}

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

@ -125,4 +125,4 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
this.YDensity);
}
}
}
}

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

@ -20,4 +20,4 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
YCbCr
}
}
}

1
src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponent.cs

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0.
using System;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder

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

@ -66,4 +66,4 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
return this.Marker.ToString("X");
}
}
}
}

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

@ -22,7 +22,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
private JpegColorConverter colorConverter;
private IMemoryOwner<Vector4> rgbaBuffer;
// private IMemoryOwner<Vector4> rgbaBuffer;
private IMemoryOwner<byte> rgbBuffer;
private IMemoryOwner<TPixel> paddedProxyPixelRow;
private Buffer2D<TPixel> pixelBuffer;
@ -40,23 +43,20 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
private bool Converted => this.pixelRowCounter >= this.pixelBuffer.Height;
public Buffer2D<TPixel> PixelBuffer
public Buffer2D<TPixel> GetPixelBuffer()
{
get
if (!this.Converted)
{
if (!this.Converted)
{
int steps = (int)Math.Ceiling(this.pixelBuffer.Height / (float)this.pixelRowsPerStep);
int steps = (int)Math.Ceiling(this.pixelBuffer.Height / (float)this.pixelRowsPerStep);
for (int step = 0; step < steps; step++)
{
this.cancellationToken.ThrowIfCancellationRequested();
this.ConvertNextStride(step);
}
for (int step = 0; step < steps; step++)
{
this.cancellationToken.ThrowIfCancellationRequested();
this.ConvertNextStride(step);
}
return this.pixelBuffer;
}
return this.pixelBuffer;
}
/// <inheritdoc/>
@ -72,7 +72,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
this.pixelRowsPerStep = this.blockRowsPerStep * blockPixelHeight;
// pixel buffer for resulting image
this.pixelBuffer = allocator.Allocate2D<TPixel>(frame.PixelWidth, frame.PixelHeight, AllocationOptions.Clean);
this.pixelBuffer = allocator.Allocate2D<TPixel>(frame.PixelWidth, frame.PixelHeight);
this.paddedProxyPixelRow = allocator.Allocate<TPixel>(frame.PixelWidth + 3);
// component processors from spectral to Rgba32
var postProcessorBufferSize = new Size(c0.SizeInBlocks.Width * 8, this.pixelRowsPerStep);
@ -83,7 +84,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
}
// single 'stride' rgba32 buffer for conversion between spectral and TPixel
this.rgbaBuffer = allocator.Allocate<Vector4>(frame.PixelWidth);
// this.rgbaBuffer = allocator.Allocate<Vector4>(frame.PixelWidth);
this.rgbBuffer = allocator.Allocate<byte>(frame.PixelWidth * 3);
// color converter from Rgba32 to TPixel
this.colorConverter = this.GetColorConverter(frame, jpegData);
@ -115,7 +117,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
}
}
this.rgbaBuffer?.Dispose();
this.rgbBuffer?.Dispose();
this.paddedProxyPixelRow?.Dispose();
}
private void ConvertNextStride(int spectralStep)
@ -129,17 +132,38 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
buffers[i] = this.componentProcessors[i].ColorBuffer;
}
int width = this.pixelBuffer.Width;
for (int yy = this.pixelRowCounter; yy < maxY; yy++)
{
int y = yy - this.pixelRowCounter;
var values = new JpegColorConverter.ComponentValues(buffers, y);
this.colorConverter.ConvertToRgba(values, this.rgbaBuffer.GetSpan());
Span<TPixel> destRow = this.pixelBuffer.GetRowSpan(yy);
this.colorConverter.ConvertToRgbInplace(values);
values = values.Slice(0, width); // slice away Jpeg padding
// TODO: Investigate if slicing is actually necessary
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.configuration, this.rgbaBuffer.GetSpan().Slice(0, destRow.Length), destRow);
Span<byte> r = this.rgbBuffer.Slice(0, width);
Span<byte> g = this.rgbBuffer.Slice(width, width);
Span<byte> b = this.rgbBuffer.Slice(width * 2, width);
SimdUtils.NormalizedFloatToByteSaturate(values.Component0, r);
SimdUtils.NormalizedFloatToByteSaturate(values.Component1, g);
SimdUtils.NormalizedFloatToByteSaturate(values.Component2, b);
// PackFromRgbPlanes expects the destination to be padded, so try to get padded span containing extra elements from the next row.
// If we can't get such a padded row because we are on a MemoryGroup boundary or at the last row,
// pack pixels to a temporary, padded proxy buffer, then copy the relevant values to the destination row.
if (this.pixelBuffer.TryGetPaddedRowSpan(yy, 3, out Span<TPixel> destRow))
{
PixelOperations<TPixel>.Instance.PackFromRgbPlanes(this.configuration, r, g, b, destRow);
}
else
{
Span<TPixel> proxyRow = this.paddedProxyPixelRow.GetSpan();
PixelOperations<TPixel>.Instance.PackFromRgbPlanes(this.configuration, r, g, b, proxyRow);
proxyRow.Slice(0, width).CopyTo(this.pixelBuffer.GetRowSpan(yy));
}
}
this.pixelRowCounter += this.pixelRowsPerStep;

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

@ -32,4 +32,4 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
// ReSharper restore UnusedMember.Local
}
}
}

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

@ -48,4 +48,4 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
public static Size DivideRoundUp(this Size originalSize, Size divisor) =>
DivideRoundUp(originalSize, divisor.Width, divisor.Height);
}
}
}

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

@ -13,4 +13,4 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// </summary>
bool IgnoreMetadata { get; }
}
}
}

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

@ -16,4 +16,4 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
configuration.ImageFormatsManager.AddImageFormatDetector(new JpegImageFormatDetector());
}
}
}
}

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

@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// <inheritdoc />
public Image Decode(Configuration configuration, Stream stream)
=> this.Decode<Rgba32>(configuration, stream);
=> this.Decode<Rgb24>(configuration, stream);
/// <inheritdoc/>
public Task<Image<TPixel>> DecodeAsync<TPixel>(Configuration configuration, Stream stream, CancellationToken cancellationToken)

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

@ -185,7 +185,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
this.InitIptcProfile();
this.InitDerivedMetadataProperties();
return new Image<TPixel>(this.Configuration, spectralConverter.PixelBuffer, this.Metadata);
return new Image<TPixel>(this.Configuration, spectralConverter.GetPixelBuffer(), this.Metadata);
}
/// <inheritdoc/>

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

@ -34,4 +34,4 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// <inheritdoc/>
public JpegMetadata CreateDefaultFormatMetadata() => new JpegMetadata();
}
}
}

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

@ -59,4 +59,4 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
header[0] == 0xFF && // 255
header[1] == 0xD8; // 216
}
}
}

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

@ -27,4 +27,4 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
scanline.Slice(0, Math.Min(scanline.Length, result.Length)).CopyTo(result);
}
}
}
}

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

@ -33,4 +33,4 @@ namespace SixLabors.ImageSharp.Formats.Png
/// </summary>
RgbWithAlpha = 6
}
}
}

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

@ -16,4 +16,4 @@ namespace SixLabors.ImageSharp.Formats.Png
configuration.ImageFormatsManager.AddImageFormatDetector(new PngImageFormatDetector());
}
}
}
}

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

@ -43,4 +43,4 @@ namespace SixLabors.ImageSharp.Formats.Png
/// </summary>
Adaptive,
}
}
}

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

@ -34,4 +34,4 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <inheritdoc/>
public PngMetadata CreateDefaultFormatMetadata() => new PngMetadata();
}
}
}

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

@ -25,4 +25,4 @@ namespace SixLabors.ImageSharp.Formats.Png
return header.Length >= this.HeaderSize && BinaryPrimitives.ReadUInt64BigEndian(header) == PngConstants.HeaderValue;
}
}
}
}

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

@ -18,4 +18,4 @@ namespace SixLabors.ImageSharp.Formats.Png
/// </summary>
Adam7 = 1
}
}
}

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

@ -3,7 +3,6 @@
using System;
using System.IO.Compression;
using SixLabors.ImageSharp.Compression.Zlib;
using SixLabors.ImageSharp.Formats.Tiff.Constants;
using SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation;

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

@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
scanDecoder.ResetInterval = 0;
jpegDecoder.ParseStream(stream, scanDecoder, CancellationToken.None);
CopyImageBytesToBuffer(buffer, spectralConverter.PixelBuffer);
CopyImageBytesToBuffer(buffer, spectralConverter.GetPixelBuffer());
}
else
{

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

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0.
using System;
using SixLabors.ImageSharp.Formats.Tiff.Constants;
using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Memory;

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

Loading…
Cancel
Save