diff --git a/.editorconfig b/.editorconfig
index 03036f8a53..33fd0577a8 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -75,7 +75,7 @@ indent_style = tab
[*.{cs,csx,cake,vb,vbx}]
# Default Severity for all .NET Code Style rules below
-dotnet_analyzer_diagnostic.severity = warning
+dotnet_analyzer_diagnostic.category-style.severity = warning
##########################################
# Language Rules
diff --git a/.gitignore b/.gitignore
index 475d6e76b0..769a40c6cc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -221,4 +221,5 @@ artifacts/
# Tests
**/Images/ActualOutput
**/Images/ReferenceOutput
+**/Images/Input/MemoryStress
.DS_Store
diff --git a/Directory.Build.props b/Directory.Build.props
index 3df93fcd40..b3e18e5a5a 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -18,13 +18,12 @@
-
-
- false
-
-
+
true
-
+
diff --git a/ImageSharp.sln b/ImageSharp.sln
index 83208994cb..bf1f3579c0 100644
--- a/ImageSharp.sln
+++ b/ImageSharp.sln
@@ -1,4 +1,3 @@
-
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28902.138
@@ -480,115 +479,43 @@ Global
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
- Debug|x64 = Debug|x64
- Debug|x86 = Debug|x86
Debug-InnerLoop|Any CPU = Debug-InnerLoop|Any CPU
- Debug-InnerLoop|x64 = Debug-InnerLoop|x64
- Debug-InnerLoop|x86 = Debug-InnerLoop|x86
Release|Any CPU = Release|Any CPU
- Release|x64 = Release|x64
- Release|x86 = Release|x86
Release-InnerLoop|Any CPU = Release-InnerLoop|Any CPU
- Release-InnerLoop|x64 = Release-InnerLoop|x64
- Release-InnerLoop|x86 = Release-InnerLoop|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug|x64.ActiveCfg = Debug|Any CPU
- {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug|x64.Build.0 = Debug|Any CPU
- {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug|x86.ActiveCfg = Debug|Any CPU
- {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug|x86.Build.0 = Debug|Any CPU
{2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug-InnerLoop|Any CPU.ActiveCfg = Debug-InnerLoop|Any CPU
{2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug-InnerLoop|Any CPU.Build.0 = Debug-InnerLoop|Any CPU
- {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug-InnerLoop|x64.ActiveCfg = Debug-InnerLoop|Any CPU
- {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug-InnerLoop|x64.Build.0 = Debug-InnerLoop|Any CPU
- {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug-InnerLoop|x86.ActiveCfg = Debug-InnerLoop|Any CPU
- {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Debug-InnerLoop|x86.Build.0 = Debug-InnerLoop|Any CPU
{2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release|Any CPU.Build.0 = Release|Any CPU
- {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release|x64.ActiveCfg = Release|Any CPU
- {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release|x64.Build.0 = Release|Any CPU
- {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release|x86.ActiveCfg = Release|Any CPU
- {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release|x86.Build.0 = Release|Any CPU
{2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release-InnerLoop|Any CPU.ActiveCfg = Release-InnerLoop|Any CPU
{2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release-InnerLoop|Any CPU.Build.0 = Release-InnerLoop|Any CPU
- {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release-InnerLoop|x64.ActiveCfg = Release-InnerLoop|Any CPU
- {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release-InnerLoop|x64.Build.0 = Release-InnerLoop|Any CPU
- {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release-InnerLoop|x86.ActiveCfg = Release-InnerLoop|Any CPU
- {2AA31A1F-142C-43F4-8687-09ABCA4B3A26}.Release-InnerLoop|x86.Build.0 = Release-InnerLoop|Any CPU
{EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug|x64.ActiveCfg = Debug|Any CPU
- {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug|x64.Build.0 = Debug|Any CPU
- {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug|x86.ActiveCfg = Debug|Any CPU
- {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug|x86.Build.0 = Debug|Any CPU
{EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug-InnerLoop|Any CPU.ActiveCfg = Debug-InnerLoop|Any CPU
{EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug-InnerLoop|Any CPU.Build.0 = Debug-InnerLoop|Any CPU
- {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug-InnerLoop|x64.ActiveCfg = Debug-InnerLoop|x64
- {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug-InnerLoop|x64.Build.0 = Debug-InnerLoop|x64
- {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug-InnerLoop|x86.ActiveCfg = Debug-InnerLoop|x86
- {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Debug-InnerLoop|x86.Build.0 = Debug-InnerLoop|x86
{EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release|Any CPU.Build.0 = Release|Any CPU
- {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release|x64.ActiveCfg = Release|Any CPU
- {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release|x64.Build.0 = Release|Any CPU
- {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release|x86.ActiveCfg = Release|Any CPU
- {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release|x86.Build.0 = Release|Any CPU
{EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release-InnerLoop|Any CPU.ActiveCfg = Release-InnerLoop|Any CPU
{EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release-InnerLoop|Any CPU.Build.0 = Release-InnerLoop|Any CPU
- {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release-InnerLoop|x64.ActiveCfg = Release-InnerLoop|x64
- {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release-InnerLoop|x64.Build.0 = Release-InnerLoop|x64
- {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release-InnerLoop|x86.ActiveCfg = Release-InnerLoop|x86
- {EA3000E9-2A91-4EC4-8A68-E566DEBDC4F6}.Release-InnerLoop|x86.Build.0 = Release-InnerLoop|x86
{2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug|x64.ActiveCfg = Debug|Any CPU
- {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug|x64.Build.0 = Debug|Any CPU
- {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug|x86.ActiveCfg = Debug|Any CPU
- {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug|x86.Build.0 = Debug|Any CPU
{2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug-InnerLoop|Any CPU.ActiveCfg = Debug-InnerLoop|Any CPU
{2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug-InnerLoop|Any CPU.Build.0 = Debug-InnerLoop|Any CPU
- {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug-InnerLoop|x64.ActiveCfg = Debug-InnerLoop|Any CPU
- {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug-InnerLoop|x64.Build.0 = Debug-InnerLoop|Any CPU
- {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug-InnerLoop|x86.ActiveCfg = Debug-InnerLoop|Any CPU
- {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Debug-InnerLoop|x86.Build.0 = Debug-InnerLoop|Any CPU
{2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release|Any CPU.Build.0 = Release|Any CPU
- {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release|x64.ActiveCfg = Release|Any CPU
- {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release|x64.Build.0 = Release|Any CPU
- {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release|x86.ActiveCfg = Release|Any CPU
- {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release|x86.Build.0 = Release|Any CPU
{2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release-InnerLoop|Any CPU.ActiveCfg = Release-InnerLoop|Any CPU
{2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release-InnerLoop|Any CPU.Build.0 = Release-InnerLoop|Any CPU
- {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release-InnerLoop|x64.ActiveCfg = Release-InnerLoop|Any CPU
- {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release-InnerLoop|x64.Build.0 = Release-InnerLoop|Any CPU
- {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release-InnerLoop|x86.ActiveCfg = Release-InnerLoop|Any CPU
- {2BF743D8-2A06-412D-96D7-F448F00C5EA5}.Release-InnerLoop|x86.Build.0 = Release-InnerLoop|Any CPU
{FC527290-2F22-432C-B77B-6E815726B02C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FC527290-2F22-432C-B77B-6E815726B02C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {FC527290-2F22-432C-B77B-6E815726B02C}.Debug|x64.ActiveCfg = Debug|Any CPU
- {FC527290-2F22-432C-B77B-6E815726B02C}.Debug|x64.Build.0 = Debug|Any CPU
- {FC527290-2F22-432C-B77B-6E815726B02C}.Debug|x86.ActiveCfg = Debug|Any CPU
- {FC527290-2F22-432C-B77B-6E815726B02C}.Debug|x86.Build.0 = Debug|Any CPU
{FC527290-2F22-432C-B77B-6E815726B02C}.Debug-InnerLoop|Any CPU.ActiveCfg = Debug-InnerLoop|Any CPU
{FC527290-2F22-432C-B77B-6E815726B02C}.Debug-InnerLoop|Any CPU.Build.0 = Debug-InnerLoop|Any CPU
- {FC527290-2F22-432C-B77B-6E815726B02C}.Debug-InnerLoop|x64.ActiveCfg = Debug-InnerLoop|Any CPU
- {FC527290-2F22-432C-B77B-6E815726B02C}.Debug-InnerLoop|x64.Build.0 = Debug-InnerLoop|Any CPU
- {FC527290-2F22-432C-B77B-6E815726B02C}.Debug-InnerLoop|x86.ActiveCfg = Debug-InnerLoop|Any CPU
- {FC527290-2F22-432C-B77B-6E815726B02C}.Debug-InnerLoop|x86.Build.0 = Debug-InnerLoop|Any CPU
{FC527290-2F22-432C-B77B-6E815726B02C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FC527290-2F22-432C-B77B-6E815726B02C}.Release|Any CPU.Build.0 = Release|Any CPU
- {FC527290-2F22-432C-B77B-6E815726B02C}.Release|x64.ActiveCfg = Release|Any CPU
- {FC527290-2F22-432C-B77B-6E815726B02C}.Release|x64.Build.0 = Release|Any CPU
- {FC527290-2F22-432C-B77B-6E815726B02C}.Release|x86.ActiveCfg = Release|Any CPU
- {FC527290-2F22-432C-B77B-6E815726B02C}.Release|x86.Build.0 = Release|Any CPU
{FC527290-2F22-432C-B77B-6E815726B02C}.Release-InnerLoop|Any CPU.ActiveCfg = Release-InnerLoop|Any CPU
{FC527290-2F22-432C-B77B-6E815726B02C}.Release-InnerLoop|Any CPU.Build.0 = Release-InnerLoop|Any CPU
- {FC527290-2F22-432C-B77B-6E815726B02C}.Release-InnerLoop|x64.ActiveCfg = Release-InnerLoop|Any CPU
- {FC527290-2F22-432C-B77B-6E815726B02C}.Release-InnerLoop|x64.Build.0 = Release-InnerLoop|Any CPU
- {FC527290-2F22-432C-B77B-6E815726B02C}.Release-InnerLoop|x86.ActiveCfg = Release-InnerLoop|Any CPU
- {FC527290-2F22-432C-B77B-6E815726B02C}.Release-InnerLoop|x86.Build.0 = Release-InnerLoop|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/shared-infrastructure b/shared-infrastructure
index 48e73f455f..9b94ebc4be 160000
--- a/shared-infrastructure
+++ b/shared-infrastructure
@@ -1 +1 @@
-Subproject commit 48e73f455f15eafefbe3175efc7433e5f277e506
+Subproject commit 9b94ebc4be9b7a8d7620c257e6ee485455973332
diff --git a/src/ImageSharp/Advanced/AotCompilerTools.cs b/src/ImageSharp/Advanced/AotCompilerTools.cs
index ea4cd1c8c4..be2e964fc0 100644
--- a/src/ImageSharp/Advanced/AotCompilerTools.cs
+++ b/src/ImageSharp/Advanced/AotCompilerTools.cs
@@ -12,6 +12,7 @@ using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Jpeg.Components;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Formats.Tga;
+using SixLabors.ImageSharp.Formats.Tiff;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
@@ -56,7 +57,7 @@ namespace SixLabors.ImageSharp.Advanced
/// necessary methods to complete the SaveAsGif call. That's it, otherwise you should NEVER need this method!!!
///
[Preserve]
- private static void SeedEverything()
+ private static void SeedPixelFormats()
{
try
{
@@ -199,6 +200,7 @@ namespace SixLabors.ImageSharp.Advanced
default(JpegEncoderCore).Encode(default, default, default);
default(PngEncoderCore).Encode(default, default, default);
default(TgaEncoderCore).Encode(default, default, default);
+ default(TiffEncoderCore).Encode(default, default, default);
}
///
@@ -214,6 +216,7 @@ namespace SixLabors.ImageSharp.Advanced
default(JpegDecoderCore).Decode(default, default, default);
default(PngDecoderCore).Decode(default, default, default);
default(TgaDecoderCore).Decode(default, default, default);
+ default(TiffDecoderCore).Decode(default, default, default);
}
///
@@ -229,6 +232,7 @@ namespace SixLabors.ImageSharp.Advanced
AotCompileImageEncoder();
AotCompileImageEncoder();
AotCompileImageEncoder();
+ AotCompileImageEncoder();
}
///
@@ -244,6 +248,7 @@ namespace SixLabors.ImageSharp.Advanced
AotCompileImageDecoder();
AotCompileImageDecoder();
AotCompileImageDecoder();
+ AotCompileImageDecoder();
}
///
diff --git a/src/ImageSharp/Common/ByteOrder.cs b/src/ImageSharp/Common/ByteOrder.cs
new file mode 100644
index 0000000000..cc38f1cdee
--- /dev/null
+++ b/src/ImageSharp/Common/ByteOrder.cs
@@ -0,0 +1,23 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+namespace SixLabors.ImageSharp
+{
+ ///
+ /// The byte order of the data stream.
+ ///
+ public enum ByteOrder
+ {
+ ///
+ /// The big-endian byte order (Motorola).
+ /// Most-significant byte comes first, and ends with the least-significant byte.
+ ///
+ BigEndian,
+
+ ///
+ /// The little-endian byte order (Intel).
+ /// Least-significant byte comes first and ends with the most-significant byte.
+ ///
+ LittleEndian
+ }
+}
diff --git a/src/ImageSharp/Common/Extensions/StreamExtensions.cs b/src/ImageSharp/Common/Extensions/StreamExtensions.cs
index f2367d488a..1193eccee3 100644
--- a/src/ImageSharp/Common/Extensions/StreamExtensions.cs
+++ b/src/ImageSharp/Common/Extensions/StreamExtensions.cs
@@ -4,7 +4,6 @@
using System;
using System.Buffers;
using System.IO;
-using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp
{
@@ -72,12 +71,6 @@ namespace SixLabors.ImageSharp
}
}
- public static void Read(this Stream stream, IManagedByteBuffer buffer)
- => stream.Read(buffer.Array, 0, buffer.Length());
-
- public static void Write(this Stream stream, IManagedByteBuffer buffer)
- => stream.Write(buffer.Array, 0, buffer.Length());
-
#if !SUPPORTS_SPAN_STREAM
// This is a port of the CoreFX implementation and is MIT Licensed:
// https://github.com/dotnet/corefx/blob/17300169760c61a90cab8d913636c1058a30a8c1/src/Common/src/CoreLib/System/IO/Stream.cs#L742
diff --git a/src/ImageSharp/Common/Helpers/DebugGuard.cs b/src/ImageSharp/Common/Helpers/DebugGuard.cs
index 9ef7c01c61..f56cb37a81 100644
--- a/src/ImageSharp/Common/Helpers/DebugGuard.cs
+++ b/src/ImageSharp/Common/Helpers/DebugGuard.cs
@@ -37,7 +37,7 @@ namespace SixLabors
/// has a different size than
///
[Conditional("DEBUG")]
- public static void MustBeSameSized(Span target, Span other, string parameterName)
+ public static void MustBeSameSized(ReadOnlySpan target, ReadOnlySpan other, string parameterName)
where T : struct
{
if (target.Length != other.Length)
@@ -57,7 +57,7 @@ namespace SixLabors
/// has less items than
///
[Conditional("DEBUG")]
- public static void MustBeSizedAtLeast(Span target, Span minSpan, string parameterName)
+ public static void MustBeSizedAtLeast(ReadOnlySpan target, ReadOnlySpan minSpan, string parameterName)
where T : struct
{
if (target.Length < minSpan.Length)
diff --git a/src/ImageSharp/Common/Helpers/Numerics.cs b/src/ImageSharp/Common/Helpers/Numerics.cs
index 0581993014..db65b84cca 100644
--- a/src/ImageSharp/Common/Helpers/Numerics.cs
+++ b/src/ImageSharp/Common/Helpers/Numerics.cs
@@ -23,6 +23,16 @@ namespace SixLabors.ImageSharp
private const int ShuffleAlphaControl = 0b_11_11_11_11;
#endif
+#if !SUPPORTS_BITOPERATIONS
+ private static ReadOnlySpan Log2DeBruijn => new byte[32]
+ {
+ 00, 09, 01, 10, 13, 21, 02, 29,
+ 11, 14, 16, 18, 22, 25, 03, 30,
+ 08, 12, 20, 28, 15, 17, 24, 07,
+ 19, 27, 23, 06, 26, 05, 04, 31
+ };
+#endif
+
///
/// Determine the Greatest CommonDivisor (GCD) of two numbers.
///
@@ -756,7 +766,7 @@ namespace SixLabors.ImageSharp
/// widening them to 32-bit integers and performing four additions.
///
///
- /// byte(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
+ /// byte(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
/// is widened and added onto as such:
///
/// accumulator += i32(1, 2, 3, 4);
@@ -825,5 +835,49 @@ namespace SixLabors.ImageSharp
return Sse2.ConvertToInt32(vsum);
}
#endif
+
+ ///
+ /// Calculates floored log of the specified value, base 2.
+ /// Note that by convention, input value 0 returns 0 since Log(0) is undefined.
+ ///
+ /// The value.
+ public static int Log2(uint value)
+ {
+#if SUPPORTS_BITOPERATIONS
+ return BitOperations.Log2(value);
+#else
+ return Log2SoftwareFallback(value);
+#endif
+ }
+
+#if !SUPPORTS_BITOPERATIONS
+ ///
+ /// Calculates floored log of the specified value, base 2.
+ /// Note that by convention, input value 0 returns 0 since Log(0) is undefined.
+ /// Bit hacking with deBruijn sequence, extremely fast yet does not use any intrinsics so will work on every platform/runtime.
+ ///
+ ///
+ /// Description of this bit hacking can be found here:
+ /// https://cstheory.stackexchange.com/questions/19524/using-the-de-bruijn-sequence-to-find-the-lceil-log-2-v-rceil-of-an-integer
+ ///
+ /// The value.
+ private static int Log2SoftwareFallback(uint value)
+ {
+ // No AggressiveInlining due to large method size
+ // Has conventional contract 0->0 (Log(0) is undefined) by default, no need for if checking
+
+ // Fill trailing zeros with ones, eg 00010010 becomes 00011111
+ value |= value >> 01;
+ value |= value >> 02;
+ value |= value >> 04;
+ value |= value >> 08;
+ value |= value >> 16;
+
+ // uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check
+ return Unsafe.AddByteOffset(
+ ref MemoryMarshal.GetReference(Log2DeBruijn),
+ (IntPtr)(int)((value * 0x07C4ACDDu) >> 27)); // uint|long -> IntPtr cast on 32-bit platforms does expensive overflow checks not needed here
+ }
+#endif
}
}
diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
index 4faf577fd9..b530a37e77 100644
--- a/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
+++ b/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
@@ -532,6 +532,7 @@ namespace SixLabors.ImageSharp
///
/// Performs a multiplication and an addition of the .
///
+ /// ret = (vm0 * vm1) + va
/// The vector to add to the intermediate result.
/// The first vector to multiply.
/// The second vector to multiply.
@@ -552,6 +553,30 @@ namespace SixLabors.ImageSharp
}
}
+ ///
+ /// Performs a multiplication and a substraction of the .
+ ///
+ /// ret = (vm0 * vm1) - vs
+ /// The vector to substract from the intermediate result.
+ /// The first vector to multiply.
+ /// The second vector to multiply.
+ /// The .
+ [MethodImpl(InliningOptions.ShortMethod)]
+ public static Vector256 MultiplySubstract(
+ in Vector256 vs,
+ in Vector256 vm0,
+ in Vector256 vm1)
+ {
+ if (Fma.IsSupported)
+ {
+ return Fma.MultiplySubtract(vm1, vm0, vs);
+ }
+ else
+ {
+ return Avx.Subtract(Avx.Multiply(vm0, vm1), vs);
+ }
+ }
+
///
/// as many elements as possible, slicing them down (keeping the remainder).
///
diff --git a/src/ImageSharp/Common/Helpers/UnitConverter.cs b/src/ImageSharp/Common/Helpers/UnitConverter.cs
index 4a6e6abcb6..efc0e0e152 100644
--- a/src/ImageSharp/Common/Helpers/UnitConverter.cs
+++ b/src/ImageSharp/Common/Helpers/UnitConverter.cs
@@ -30,6 +30,11 @@ namespace SixLabors.ImageSharp.Common.Helpers
///
private const double InchesInMeter = 1 / 0.0254D;
+ ///
+ /// The default resolution unit value.
+ ///
+ private const PixelResolutionUnit DefaultResolutionUnit = PixelResolutionUnit.PixelsPerInch;
+
///
/// Scales the value from centimeters to meters.
///
@@ -89,7 +94,50 @@ namespace SixLabors.ImageSharp.Common.Helpers
IExifValue resolution = profile.GetValue(ExifTag.ResolutionUnit);
// EXIF is 1, 2, 3 so we minus "1" off the result.
- return resolution is null ? default : (PixelResolutionUnit)(byte)(resolution.Value - 1);
+ return resolution is null ? DefaultResolutionUnit : (PixelResolutionUnit)(byte)(resolution.Value - 1);
+ }
+
+ ///
+ /// Sets the exif profile resolution values.
+ ///
+ /// The exif profile.
+ /// The resolution unit.
+ /// The horizontal resolution value.
+ /// The vertical resolution value.
+ [MethodImpl(InliningOptions.ShortMethod)]
+ public static void SetResolutionValues(ExifProfile exifProfile, PixelResolutionUnit unit, double horizontal, double vertical)
+ {
+ switch (unit)
+ {
+ case PixelResolutionUnit.AspectRatio:
+ case PixelResolutionUnit.PixelsPerInch:
+ case PixelResolutionUnit.PixelsPerCentimeter:
+ break;
+ case PixelResolutionUnit.PixelsPerMeter:
+ {
+ unit = PixelResolutionUnit.PixelsPerCentimeter;
+ horizontal = UnitConverter.MeterToCm(horizontal);
+ vertical = UnitConverter.MeterToCm(vertical);
+ }
+
+ break;
+ default:
+ unit = PixelResolutionUnit.PixelsPerInch;
+ break;
+ }
+
+ exifProfile.SetValue(ExifTag.ResolutionUnit, (ushort)(unit + 1));
+
+ if (unit == PixelResolutionUnit.AspectRatio)
+ {
+ exifProfile.RemoveValue(ExifTag.XResolution);
+ exifProfile.RemoveValue(ExifTag.YResolution);
+ }
+ else
+ {
+ exifProfile.SetValue(ExifTag.XResolution, new Rational(horizontal));
+ exifProfile.SetValue(ExifTag.YResolution, new Rational(vertical));
+ }
}
}
}
diff --git a/src/ImageSharp/Formats/Png/Zlib/Adler32.cs b/src/ImageSharp/Compression/Zlib/Adler32.cs
similarity index 99%
rename from src/ImageSharp/Formats/Png/Zlib/Adler32.cs
rename to src/ImageSharp/Compression/Zlib/Adler32.cs
index 534aba8f5a..9b3abd298b 100644
--- a/src/ImageSharp/Formats/Png/Zlib/Adler32.cs
+++ b/src/ImageSharp/Compression/Zlib/Adler32.cs
@@ -9,7 +9,7 @@ using System.Runtime.Intrinsics.X86;
#endif
#pragma warning disable IDE0007 // Use implicit type
-namespace SixLabors.ImageSharp.Formats.Png.Zlib
+namespace SixLabors.ImageSharp.Compression.Zlib
{
///
/// Calculates the 32 bit Adler checksum of a given buffer according to
diff --git a/src/ImageSharp/Formats/Png/Zlib/Crc32.Lut.cs b/src/ImageSharp/Compression/Zlib/Crc32.Lut.cs
similarity index 98%
rename from src/ImageSharp/Formats/Png/Zlib/Crc32.Lut.cs
rename to src/ImageSharp/Compression/Zlib/Crc32.Lut.cs
index 5007833539..059bd9f312 100644
--- a/src/ImageSharp/Formats/Png/Zlib/Crc32.Lut.cs
+++ b/src/ImageSharp/Compression/Zlib/Crc32.Lut.cs
@@ -1,7 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
-namespace SixLabors.ImageSharp.Formats.Png.Zlib
+namespace SixLabors.ImageSharp.Compression.Zlib
{
///
/// Contains precalulated tables for scalar calculations.
diff --git a/src/ImageSharp/Formats/Png/Zlib/Crc32.cs b/src/ImageSharp/Compression/Zlib/Crc32.cs
similarity index 99%
rename from src/ImageSharp/Formats/Png/Zlib/Crc32.cs
rename to src/ImageSharp/Compression/Zlib/Crc32.cs
index 6b19987cb1..0ba368df64 100644
--- a/src/ImageSharp/Formats/Png/Zlib/Crc32.cs
+++ b/src/ImageSharp/Compression/Zlib/Crc32.cs
@@ -9,7 +9,7 @@ using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
#endif
-namespace SixLabors.ImageSharp.Formats.Png.Zlib
+namespace SixLabors.ImageSharp.Compression.Zlib
{
///
/// Calculates the 32 bit Cyclic Redundancy Check (CRC) checksum of a given buffer
diff --git a/src/ImageSharp/Compression/Zlib/DeflateCompressionLevel.cs b/src/ImageSharp/Compression/Zlib/DeflateCompressionLevel.cs
new file mode 100644
index 0000000000..2edf76e7d5
--- /dev/null
+++ b/src/ImageSharp/Compression/Zlib/DeflateCompressionLevel.cs
@@ -0,0 +1,81 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+namespace SixLabors.ImageSharp.Compression.Zlib
+{
+ ///
+ /// Provides enumeration of available deflate compression levels.
+ ///
+ public enum DeflateCompressionLevel
+ {
+ ///
+ /// Level 0. Equivalent to .
+ ///
+ Level0 = 0,
+
+ ///
+ /// No compression. Equivalent to .
+ ///
+ NoCompression = Level0,
+
+ ///
+ /// Level 1. Equivalent to .
+ ///
+ Level1 = 1,
+
+ ///
+ /// Best speed compression level.
+ ///
+ BestSpeed = Level1,
+
+ ///
+ /// Level 2.
+ ///
+ Level2 = 2,
+
+ ///
+ /// Level 3.
+ ///
+ Level3 = 3,
+
+ ///
+ /// Level 4.
+ ///
+ Level4 = 4,
+
+ ///
+ /// Level 5.
+ ///
+ Level5 = 5,
+
+ ///
+ /// Level 6. Equivalent to .
+ ///
+ Level6 = 6,
+
+ ///
+ /// The default compression level. Equivalent to .
+ ///
+ DefaultCompression = Level6,
+
+ ///
+ /// Level 7.
+ ///
+ Level7 = 7,
+
+ ///
+ /// Level 8.
+ ///
+ Level8 = 8,
+
+ ///
+ /// Level 9. Equivalent to .
+ ///
+ Level9 = 9,
+
+ ///
+ /// Best compression level. Equivalent to .
+ ///
+ BestCompression = Level9,
+ }
+}
diff --git a/src/ImageSharp/Formats/Png/Zlib/DeflateThrowHelper.cs b/src/ImageSharp/Compression/Zlib/DeflateThrowHelper.cs
similarity index 96%
rename from src/ImageSharp/Formats/Png/Zlib/DeflateThrowHelper.cs
rename to src/ImageSharp/Compression/Zlib/DeflateThrowHelper.cs
index a5d129c92c..02590ca253 100644
--- a/src/ImageSharp/Formats/Png/Zlib/DeflateThrowHelper.cs
+++ b/src/ImageSharp/Compression/Zlib/DeflateThrowHelper.cs
@@ -4,7 +4,7 @@
using System;
using System.Runtime.CompilerServices;
-namespace SixLabors.ImageSharp.Formats.Png.Zlib
+namespace SixLabors.ImageSharp.Compression.Zlib
{
internal static class DeflateThrowHelper
{
diff --git a/src/ImageSharp/Formats/Png/Zlib/Deflater.cs b/src/ImageSharp/Compression/Zlib/Deflater.cs
similarity index 98%
rename from src/ImageSharp/Formats/Png/Zlib/Deflater.cs
rename to src/ImageSharp/Compression/Zlib/Deflater.cs
index 8389215813..7ff8342aac 100644
--- a/src/ImageSharp/Formats/Png/Zlib/Deflater.cs
+++ b/src/ImageSharp/Compression/Zlib/Deflater.cs
@@ -5,7 +5,7 @@ using System;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Memory;
-namespace SixLabors.ImageSharp.Formats.Png.Zlib
+namespace SixLabors.ImageSharp.Compression.Zlib
{
///
/// This class compresses input with the deflate algorithm described in RFC 1951.
@@ -222,7 +222,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// The number of compressed bytes added to the output, or 0 if either
/// or returns true or length is zero.
///
- public int Deflate(byte[] output, int offset, int length)
+ public int Deflate(Span output, int offset, int length)
{
int origLength = length;
diff --git a/src/ImageSharp/Formats/Png/Zlib/DeflaterConstants.cs b/src/ImageSharp/Compression/Zlib/DeflaterConstants.cs
similarity index 98%
rename from src/ImageSharp/Formats/Png/Zlib/DeflaterConstants.cs
rename to src/ImageSharp/Compression/Zlib/DeflaterConstants.cs
index ec224d748d..30bd75ffcd 100644
--- a/src/ImageSharp/Formats/Png/Zlib/DeflaterConstants.cs
+++ b/src/ImageSharp/Compression/Zlib/DeflaterConstants.cs
@@ -4,7 +4,7 @@
//
using System;
-namespace SixLabors.ImageSharp.Formats.Png.Zlib
+namespace SixLabors.ImageSharp.Compression.Zlib
{
///
/// This class contains constants used for deflation.
diff --git a/src/ImageSharp/Formats/Png/Zlib/DeflaterEngine.cs b/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs
similarity index 94%
rename from src/ImageSharp/Formats/Png/Zlib/DeflaterEngine.cs
rename to src/ImageSharp/Compression/Zlib/DeflaterEngine.cs
index 797f5d2101..506b0f2c1c 100644
--- a/src/ImageSharp/Formats/Png/Zlib/DeflaterEngine.cs
+++ b/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs
@@ -6,7 +6,7 @@ using System.Buffers;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Memory;
-namespace SixLabors.ImageSharp.Formats.Png.Zlib
+namespace SixLabors.ImageSharp.Compression.Zlib
{
///
/// Strategies for deflater
@@ -130,9 +130,9 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// This array contains the part of the uncompressed stream that
/// is of relevance. The current character is indexed by strstart.
///
- private IManagedByteBuffer windowMemoryOwner;
+ private IMemoryOwner windowMemoryOwner;
private MemoryHandle windowMemoryHandle;
- private readonly byte[] window;
+ private readonly Memory window;
private readonly byte* pinnedWindowPointer;
private int maxChain;
@@ -153,19 +153,19 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
// Create pinned pointers to the various buffers to allow indexing
// without bounds checks.
- this.windowMemoryOwner = memoryAllocator.AllocateManagedByteBuffer(2 * DeflaterConstants.WSIZE);
- this.window = this.windowMemoryOwner.Array;
- this.windowMemoryHandle = this.windowMemoryOwner.Memory.Pin();
+ this.windowMemoryOwner = memoryAllocator.Allocate(2 * DeflaterConstants.WSIZE);
+ this.window = this.windowMemoryOwner.Memory;
+ this.windowMemoryHandle = this.window.Pin();
this.pinnedWindowPointer = (byte*)this.windowMemoryHandle.Pointer;
this.headMemoryOwner = memoryAllocator.Allocate(DeflaterConstants.HASH_SIZE);
this.head = this.headMemoryOwner.Memory;
- this.headMemoryHandle = this.headMemoryOwner.Memory.Pin();
+ this.headMemoryHandle = this.head.Pin();
this.pinnedHeadPointer = (short*)this.headMemoryHandle.Pointer;
this.prevMemoryOwner = memoryAllocator.Allocate(DeflaterConstants.WSIZE);
this.prev = this.prevMemoryOwner.Memory;
- this.prevMemoryHandle = this.prevMemoryOwner.Memory.Pin();
+ this.prevMemoryHandle = this.prev.Pin();
this.pinnedPrevPointer = (short*)this.prevMemoryHandle.Pointer;
// We start at index 1, to avoid an implementation deficiency, that
@@ -303,7 +303,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
case DeflaterConstants.DEFLATE_STORED:
if (this.strstart > this.blockStart)
{
- this.huffman.FlushStoredBlock(this.window, this.blockStart, this.strstart - this.blockStart, false);
+ this.huffman.FlushStoredBlock(this.window.Span, this.blockStart, this.strstart - this.blockStart, false);
this.blockStart = this.strstart;
}
@@ -313,7 +313,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
case DeflaterConstants.DEFLATE_FAST:
if (this.strstart > this.blockStart)
{
- this.huffman.FlushBlock(this.window, this.blockStart, this.strstart - this.blockStart, false);
+ this.huffman.FlushBlock(this.window.Span, this.blockStart, this.strstart - this.blockStart, false);
this.blockStart = this.strstart;
}
@@ -327,7 +327,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
if (this.strstart > this.blockStart)
{
- this.huffman.FlushBlock(this.window, this.blockStart, this.strstart - this.blockStart, false);
+ this.huffman.FlushBlock(this.window.Span, this.blockStart, this.strstart - this.blockStart, false);
this.blockStart = this.strstart;
}
@@ -362,7 +362,10 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
more = this.inputEnd - this.inputOff;
}
- Buffer.BlockCopy(this.inputBuf, this.inputOff, this.window, this.strstart + this.lookahead, more);
+ Unsafe.CopyBlockUnaligned(
+ ref this.window.Span[this.strstart + this.lookahead],
+ ref this.inputBuf[this.inputOff],
+ unchecked((uint)more));
this.inputOff += more;
this.lookahead += more;
@@ -426,7 +429,11 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
private void SlideWindow()
{
- Unsafe.CopyBlockUnaligned(ref this.window[0], ref this.window[DeflaterConstants.WSIZE], DeflaterConstants.WSIZE);
+ Unsafe.CopyBlockUnaligned(
+ ref this.window.Span[0],
+ ref this.window.Span[DeflaterConstants.WSIZE],
+ DeflaterConstants.WSIZE);
+
this.matchStart -= DeflaterConstants.WSIZE;
this.strstart -= DeflaterConstants.WSIZE;
this.blockStart -= DeflaterConstants.WSIZE;
@@ -663,7 +670,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
lastBlock = false;
}
- this.huffman.FlushStoredBlock(this.window, this.blockStart, storedLength, lastBlock);
+ this.huffman.FlushStoredBlock(this.window.Span, this.blockStart, storedLength, lastBlock);
this.blockStart += storedLength;
return !(lastBlock || storedLength == 0);
}
@@ -683,7 +690,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
if (this.lookahead == 0)
{
// We are flushing everything
- this.huffman.FlushBlock(this.window, this.blockStart, this.strstart - this.blockStart, finish);
+ this.huffman.FlushBlock(this.window.Span, this.blockStart, this.strstart - this.blockStart, finish);
this.blockStart = this.strstart;
return false;
}
@@ -743,7 +750,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
if (this.huffman.IsFull())
{
bool lastBlock = finish && (this.lookahead == 0);
- this.huffman.FlushBlock(this.window, this.blockStart, this.strstart - this.blockStart, lastBlock);
+ this.huffman.FlushBlock(this.window.Span, this.blockStart, this.strstart - this.blockStart, lastBlock);
this.blockStart = this.strstart;
return !lastBlock;
}
@@ -771,7 +778,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
this.prevAvailable = false;
// We are flushing everything
- this.huffman.FlushBlock(this.window, this.blockStart, this.strstart - this.blockStart, finish);
+ this.huffman.FlushBlock(this.window.Span, this.blockStart, this.strstart - this.blockStart, finish);
this.blockStart = this.strstart;
return false;
}
@@ -846,7 +853,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
}
bool lastBlock = finish && (this.lookahead == 0) && !this.prevAvailable;
- this.huffman.FlushBlock(this.window, this.blockStart, len, lastBlock);
+ this.huffman.FlushBlock(this.window.Span, this.blockStart, len, lastBlock);
this.blockStart += len;
return !lastBlock;
}
diff --git a/src/ImageSharp/Formats/Png/Zlib/DeflaterHuffman.cs b/src/ImageSharp/Compression/Zlib/DeflaterHuffman.cs
similarity index 97%
rename from src/ImageSharp/Formats/Png/Zlib/DeflaterHuffman.cs
rename to src/ImageSharp/Compression/Zlib/DeflaterHuffman.cs
index 96b47fb24b..27a8d5671d 100644
--- a/src/ImageSharp/Formats/Png/Zlib/DeflaterHuffman.cs
+++ b/src/ImageSharp/Compression/Zlib/DeflaterHuffman.cs
@@ -7,7 +7,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory;
-namespace SixLabors.ImageSharp.Formats.Png.Zlib
+namespace SixLabors.ImageSharp.Compression.Zlib
{
///
/// Performs Deflate Huffman encoding.
@@ -41,11 +41,11 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
private Tree blTree;
// Buffer for distances
- private readonly IMemoryOwner distanceManagedBuffer;
+ private readonly IMemoryOwner distanceMemoryOwner;
private readonly short* pinnedDistanceBuffer;
private MemoryHandle distanceBufferHandle;
- private readonly IMemoryOwner literalManagedBuffer;
+ private readonly IMemoryOwner literalMemoryOwner;
private readonly short* pinnedLiteralBuffer;
private MemoryHandle literalBufferHandle;
@@ -65,12 +65,12 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
this.distTree = new Tree(memoryAllocator, DistanceNumber, 1, 15);
this.blTree = new Tree(memoryAllocator, BitLengthNumber, 4, 7);
- this.distanceManagedBuffer = memoryAllocator.Allocate(BufferSize);
- this.distanceBufferHandle = this.distanceManagedBuffer.Memory.Pin();
+ this.distanceMemoryOwner = memoryAllocator.Allocate(BufferSize);
+ this.distanceBufferHandle = this.distanceMemoryOwner.Memory.Pin();
this.pinnedDistanceBuffer = (short*)this.distanceBufferHandle.Pointer;
- this.literalManagedBuffer = memoryAllocator.Allocate(BufferSize);
- this.literalBufferHandle = this.literalManagedBuffer.Memory.Pin();
+ this.literalMemoryOwner = memoryAllocator.Allocate(BufferSize);
+ this.literalBufferHandle = this.literalMemoryOwner.Memory.Pin();
this.pinnedLiteralBuffer = (short*)this.literalBufferHandle.Pointer;
}
@@ -239,7 +239,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// Count of bytes to write
/// True if this is the last block
[MethodImpl(InliningOptions.ShortMethod)]
- public void FlushStoredBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock)
+ public void FlushStoredBlock(ReadOnlySpan stored, int storedOffset, int storedLength, bool lastBlock)
{
this.Pending.WriteBits((DeflaterConstants.STORED_BLOCK << 1) + (lastBlock ? 1 : 0), 3);
this.Pending.AlignToByte();
@@ -256,7 +256,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// Index of first byte to flush
/// Count of bytes to flush
/// True if this is the last block
- public void FlushBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock)
+ public void FlushBlock(ReadOnlySpan stored, int storedOffset, int storedLength, bool lastBlock)
{
this.literalTree.Frequencies[EofSymbol]++;
@@ -286,13 +286,13 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
+ this.extraBits;
int static_len = this.extraBits;
- ref byte staticLLengthRef = ref MemoryMarshal.GetReference(StaticLLength);
+ ref byte staticLLengthRef = ref MemoryMarshal.GetReference(StaticLLength);
for (int i = 0; i < LiteralNumber; i++)
{
static_len += this.literalTree.Frequencies[i] * Unsafe.Add(ref staticLLengthRef, i);
}
- ref byte staticDLengthRef = ref MemoryMarshal.GetReference(StaticDLength);
+ ref byte staticDLengthRef = ref MemoryMarshal.GetReference(StaticDLength);
for (int i = 0; i < DistanceNumber; i++)
{
static_len += this.distTree.Frequencies[i] * Unsafe.Add(ref staticDLengthRef, i);
@@ -419,9 +419,9 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
{
this.Pending.Dispose();
this.distanceBufferHandle.Dispose();
- this.distanceManagedBuffer.Dispose();
+ this.distanceMemoryOwner.Dispose();
this.literalBufferHandle.Dispose();
- this.literalManagedBuffer.Dispose();
+ this.literalMemoryOwner.Dispose();
this.literalTree.Dispose();
this.blTree.Dispose();
@@ -484,7 +484,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
private IMemoryOwner frequenciesMemoryOwner;
private MemoryHandle frequenciesMemoryHandle;
- private IManagedByteBuffer lengthsMemoryOwner;
+ private IMemoryOwner lengthsMemoryOwner;
private MemoryHandle lengthsMemoryHandle;
public Tree(MemoryAllocator memoryAllocator, int elements, int minCodes, int maxLength)
@@ -498,7 +498,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
this.frequenciesMemoryHandle = this.frequenciesMemoryOwner.Memory.Pin();
this.Frequencies = (short*)this.frequenciesMemoryHandle.Pointer;
- this.lengthsMemoryOwner = memoryAllocator.AllocateManagedByteBuffer(elements);
+ this.lengthsMemoryOwner = memoryAllocator.Allocate(elements);
this.lengthsMemoryHandle = this.lengthsMemoryOwner.Memory.Pin();
this.Length = (byte*)this.lengthsMemoryHandle.Pointer;
diff --git a/src/ImageSharp/Formats/Png/Zlib/DeflaterOutputStream.cs b/src/ImageSharp/Compression/Zlib/DeflaterOutputStream.cs
similarity index 85%
rename from src/ImageSharp/Formats/Png/Zlib/DeflaterOutputStream.cs
rename to src/ImageSharp/Compression/Zlib/DeflaterOutputStream.cs
index 5c5651996f..d949ddf38c 100644
--- a/src/ImageSharp/Formats/Png/Zlib/DeflaterOutputStream.cs
+++ b/src/ImageSharp/Compression/Zlib/DeflaterOutputStream.cs
@@ -2,10 +2,11 @@
// Licensed under the Apache License, Version 2.0.
using System;
+using System.Buffers;
using System.IO;
using SixLabors.ImageSharp.Memory;
-namespace SixLabors.ImageSharp.Formats.Png.Zlib
+namespace SixLabors.ImageSharp.Compression.Zlib
{
///
/// A special stream deflating or compressing the bytes that are
@@ -14,8 +15,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
internal sealed class DeflaterOutputStream : Stream
{
private const int BufferLength = 512;
- private IManagedByteBuffer memoryOwner;
- private readonly byte[] buffer;
+ private IMemoryOwner memoryOwner;
+ private readonly Memory buffer;
private Deflater deflater;
private readonly Stream rawStream;
private bool isDisposed;
@@ -29,8 +30,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
public DeflaterOutputStream(MemoryAllocator memoryAllocator, Stream rawStream, int compressionLevel)
{
this.rawStream = rawStream;
- this.memoryOwner = memoryAllocator.AllocateManagedByteBuffer(BufferLength);
- this.buffer = this.memoryOwner.Array;
+ this.memoryOwner = memoryAllocator.Allocate(BufferLength);
+ this.buffer = this.memoryOwner.Memory;
this.deflater = new Deflater(memoryAllocator, compressionLevel);
}
@@ -49,15 +50,9 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
///
public override long Position
{
- get
- {
- return this.rawStream.Position;
- }
+ get => this.rawStream.Position;
- set
- {
- throw new NotSupportedException();
- }
+ set => throw new NotSupportedException();
}
///
@@ -93,14 +88,14 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
{
while (flushing || !this.deflater.IsNeedingInput)
{
- int deflateCount = this.deflater.Deflate(this.buffer, 0, BufferLength);
+ int deflateCount = this.deflater.Deflate(this.buffer.Span, 0, BufferLength);
if (deflateCount <= 0)
{
break;
}
- this.rawStream.Write(this.buffer, 0, deflateCount);
+ this.rawStream.Write(this.buffer.Span.Slice(0, deflateCount));
}
if (!this.deflater.IsNeedingInput)
@@ -114,13 +109,13 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
this.deflater.Finish();
while (!this.deflater.IsFinished)
{
- int len = this.deflater.Deflate(this.buffer, 0, BufferLength);
+ int len = this.deflater.Deflate(this.buffer.Span, 0, BufferLength);
if (len <= 0)
{
break;
}
- this.rawStream.Write(this.buffer, 0, len);
+ this.rawStream.Write(this.buffer.Span.Slice(0, len));
}
if (!this.deflater.IsFinished)
diff --git a/src/ImageSharp/Formats/Png/Zlib/DeflaterPendingBuffer.cs b/src/ImageSharp/Compression/Zlib/DeflaterPendingBuffer.cs
similarity index 83%
rename from src/ImageSharp/Formats/Png/Zlib/DeflaterPendingBuffer.cs
rename to src/ImageSharp/Compression/Zlib/DeflaterPendingBuffer.cs
index f702a7eada..8f2c8d3987 100644
--- a/src/ImageSharp/Formats/Png/Zlib/DeflaterPendingBuffer.cs
+++ b/src/ImageSharp/Compression/Zlib/DeflaterPendingBuffer.cs
@@ -4,18 +4,19 @@
using System;
using System.Buffers;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory;
-namespace SixLabors.ImageSharp.Formats.Png.Zlib
+namespace SixLabors.ImageSharp.Compression.Zlib
{
///
/// Stores pending data for writing data to the Deflater.
///
internal sealed unsafe class DeflaterPendingBuffer : IDisposable
{
- private readonly byte[] buffer;
+ private readonly Memory buffer;
private readonly byte* pinnedBuffer;
- private IManagedByteBuffer bufferMemoryOwner;
+ private IMemoryOwner bufferMemoryOwner;
private MemoryHandle bufferMemoryHandle;
private int start;
@@ -29,9 +30,9 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// The memory allocator to use for buffer allocations.
public DeflaterPendingBuffer(MemoryAllocator memoryAllocator)
{
- this.bufferMemoryOwner = memoryAllocator.AllocateManagedByteBuffer(DeflaterConstants.PENDING_BUF_SIZE);
- this.buffer = this.bufferMemoryOwner.Array;
- this.bufferMemoryHandle = this.bufferMemoryOwner.Memory.Pin();
+ this.bufferMemoryOwner = memoryAllocator.Allocate(DeflaterConstants.PENDING_BUF_SIZE);
+ this.buffer = this.bufferMemoryOwner.Memory;
+ this.bufferMemoryHandle = this.buffer.Pin();
this.pinnedBuffer = (byte*)this.bufferMemoryHandle.Pointer;
}
@@ -70,9 +71,13 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// The offset of first byte to write.
/// The number of bytes to write.
[MethodImpl(InliningOptions.ShortMethod)]
- public void WriteBlock(byte[] block, int offset, int length)
+ public void WriteBlock(ReadOnlySpan block, int offset, int length)
{
- Unsafe.CopyBlockUnaligned(ref this.buffer[this.end], ref block[offset], unchecked((uint)length));
+ Unsafe.CopyBlockUnaligned(
+ ref this.buffer.Span[this.end],
+ ref MemoryMarshal.GetReference(block.Slice(offset)),
+ unchecked((uint)length));
+
this.end += length;
}
@@ -136,7 +141,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// The offset into output array.
/// The maximum number of bytes to store.
/// The number of bytes flushed.
- public int Flush(byte[] output, int offset, int length)
+ public int Flush(Span output, int offset, int length)
{
if (this.BitCount >= 8)
{
@@ -149,13 +154,19 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
{
length = this.end - this.start;
- Unsafe.CopyBlockUnaligned(ref output[offset], ref this.buffer[this.start], unchecked((uint)length));
+ Unsafe.CopyBlockUnaligned(
+ ref output[offset],
+ ref this.buffer.Span[this.start],
+ unchecked((uint)length));
this.start = 0;
this.end = 0;
}
else
{
- Unsafe.CopyBlockUnaligned(ref output[offset], ref this.buffer[this.start], unchecked((uint)length));
+ Unsafe.CopyBlockUnaligned(
+ ref output[offset],
+ ref this.buffer.Span[this.start],
+ unchecked((uint)length));
this.start += length;
}
diff --git a/src/ImageSharp/Formats/Png/Zlib/README.md b/src/ImageSharp/Compression/Zlib/README.md
similarity index 100%
rename from src/ImageSharp/Formats/Png/Zlib/README.md
rename to src/ImageSharp/Compression/Zlib/README.md
diff --git a/src/ImageSharp/Formats/Png/Zlib/ZlibDeflateStream.cs b/src/ImageSharp/Compression/Zlib/ZlibDeflateStream.cs
similarity index 89%
rename from src/ImageSharp/Formats/Png/Zlib/ZlibDeflateStream.cs
rename to src/ImageSharp/Compression/Zlib/ZlibDeflateStream.cs
index 06c6e3dea4..44883665ab 100644
--- a/src/ImageSharp/Formats/Png/Zlib/ZlibDeflateStream.cs
+++ b/src/ImageSharp/Compression/Zlib/ZlibDeflateStream.cs
@@ -4,9 +4,10 @@
using System;
using System.IO;
using System.Runtime.CompilerServices;
+using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Memory;
-namespace SixLabors.ImageSharp.Formats.Png.Zlib
+namespace SixLabors.ImageSharp.Compression.Zlib
{
///
/// Provides methods and properties for compressing streams by using the Zlib Deflate algorithm.
@@ -39,9 +40,19 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
///
/// The stream responsible for compressing the input stream.
///
- // private DeflateStream deflateStream;
private DeflaterOutputStream deflateStream;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The memory allocator to use for buffer allocations.
+ /// The stream to compress.
+ /// The compression level.
+ public ZlibDeflateStream(MemoryAllocator memoryAllocator, Stream stream, DeflateCompressionLevel level)
+ : this(memoryAllocator, stream, (PngCompressionLevel)level)
+ {
+ }
+
///
/// Initializes a new instance of the class.
///
diff --git a/src/ImageSharp/Formats/Png/Zlib/ZlibInflateStream.cs b/src/ImageSharp/Compression/Zlib/ZlibInflateStream.cs
similarity index 99%
rename from src/ImageSharp/Formats/Png/Zlib/ZlibInflateStream.cs
rename to src/ImageSharp/Compression/Zlib/ZlibInflateStream.cs
index 52ef0e85ba..f4b0543b84 100644
--- a/src/ImageSharp/Formats/Png/Zlib/ZlibInflateStream.cs
+++ b/src/ImageSharp/Compression/Zlib/ZlibInflateStream.cs
@@ -6,7 +6,7 @@ using System.IO;
using System.IO.Compression;
using SixLabors.ImageSharp.IO;
-namespace SixLabors.ImageSharp.Formats.Png.Zlib
+namespace SixLabors.ImageSharp.Compression.Zlib
{
///
/// Provides methods and properties for deframing streams from PNGs.
diff --git a/src/ImageSharp/Formats/Png/Zlib/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf b/src/ImageSharp/Compression/Zlib/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf
similarity index 100%
rename from src/ImageSharp/Formats/Png/Zlib/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf
rename to src/ImageSharp/Compression/Zlib/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf
diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs
index 062bcb229c..49b7aa79b0 100644
--- a/src/ImageSharp/Configuration.cs
+++ b/src/ImageSharp/Configuration.cs
@@ -10,6 +10,7 @@ using SixLabors.ImageSharp.Formats.Gif;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Formats.Tga;
+using SixLabors.ImageSharp.Formats.Tiff;
using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.Processing;
@@ -39,7 +40,7 @@ namespace SixLabors.ImageSharp
///
/// Initializes a new instance of the class.
///
- /// A collection of configuration modules to register
+ /// A collection of configuration modules to register.
public Configuration(params IConfigurationModule[] configurationModules)
{
if (configurationModules != null)
@@ -77,7 +78,7 @@ namespace SixLabors.ImageSharp
///
/// Gets or sets the size of the buffer to use when working with streams.
- /// Intitialized with by default.
+ /// Initialized with by default.
///
public int StreamProcessingBufferSize
{
@@ -94,9 +95,9 @@ namespace SixLabors.ImageSharp
}
///
- /// Gets a set of properties for the Congiguration.
+ /// Gets a set of properties for the Configuration.
///
- /// This can be used for storing global settings and defaults to be accessable to processors.
+ /// This can be used for storing global settings and defaults to be accessible to processors.
public IDictionary