diff --git a/src/ImageSharp/Advanced/AotCompiler.cs b/src/ImageSharp/Advanced/AotCompiler.cs
new file mode 100644
index 0000000000..1c7f12ef7b
--- /dev/null
+++ b/src/ImageSharp/Advanced/AotCompiler.cs
@@ -0,0 +1,103 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Processing.Processors.Dithering;
+using SixLabors.ImageSharp.Processing.Processors.Quantization;
+
+namespace SixLabors.ImageSharp.Advanced
+{
+ ///
+ /// Unlike traditional Mono/.NET, code on the iPhone is statically compiled ahead of time instead of being
+ /// compiled on demand by a JIT compiler. This means there are a few limitations with respect to generics,
+ /// these are caused because not every possible generic instantiation can be determined up front at compile time.
+ /// The Aot Compiler is designed to overcome the limitations of this compiler.
+ ///
+ public static class AotCompiler
+ {
+ ///
+ /// Seeds the compiler using the given pixel format.
+ ///
+ /// The pixel format.
+ public static void Seed()
+ where TPixel : struct, IPixel
+ {
+ // This is we actually call all the individual methods you need to seed.
+ AotCompileOctreeQuantizer();
+ AotCompileWuQuantizer();
+ AotCompileDithering();
+
+ // TODO: Do the discovery work to figure out what works and what doesn't.
+ }
+
+ ///
+ /// Seeds the compiler using the given pixel formats.
+ ///
+ /// The first pixel format.
+ /// The second pixel format.
+ public static void Seed()
+ where TPixel : struct, IPixel
+ where TPixel2 : struct, IPixel
+ {
+ Seed();
+ Seed();
+ }
+
+ ///
+ /// Seeds the compiler using the given pixel formats.
+ ///
+ /// The first pixel format.
+ /// The second pixel format.
+ /// The third pixel format.
+ public static void Seed()
+ where TPixel : struct, IPixel
+ where TPixel2 : struct, IPixel
+ where TPixel3 : struct, IPixel
+ {
+ Seed();
+ Seed();
+ }
+
+ ///
+ /// This method doesn't actually do anything but serves an important purpose...
+ /// If you are running ImageSharp on iOS and try to call SaveAsGif, it will throw an excepion:
+ /// "Attempting to JIT compile method... OctreeFrameQuantizer.ConstructPalette... while running in aot-only mode."
+ /// The reason this happens is the SaveAsGif method makes haevy use of generics, which are too confusing for the AoT
+ /// compiler used on Xamarin.iOS. It spins up the JIT compiler to try and figure it out, but that is an illegal op on
+ /// iOS so it bombs out.
+ /// If you are getting the above error, you need to call this method, which will pre-seed the AoT compiler with the
+ /// necessary methods to complete the SaveAsGif call. That's it, otherwise you should NEVER need this method!!!
+ ///
+ /// The pixel format.
+ private static void AotCompileOctreeQuantizer()
+ where TPixel : struct, IPixel
+ {
+ var test = new OctreeFrameQuantizer(new OctreeQuantizer(false));
+ test.AotGetPalette();
+ }
+
+ ///
+ /// This method pre-seeds the WuQuantizer in the AoT compiler for iOS.
+ ///
+ /// The pixel format.
+ private static void AotCompileWuQuantizer()
+ where TPixel : struct, IPixel
+ {
+ var test = new WuFrameQuantizer(new WuQuantizer(false));
+ test.QuantizeFrame(new ImageFrame(Configuration.Default, 1, 1));
+ test.AotGetPalette();
+ }
+
+ ///
+ /// This method pre-seeds the default dithering engine (FloydSteinbergDiffuser) in the AoT compiler for iOS.
+ ///
+ /// The pixel format.
+ private static void AotCompileDithering()
+ where TPixel : struct, IPixel
+ {
+ var test = new FloydSteinbergDiffuser();
+ TPixel pixel = default;
+ test.Dither(new ImageFrame(Configuration.Default, 1, 1), pixel, pixel, 0, 0, 0, 0, 0, 0);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Gif/ImageExtensions.cs b/src/ImageSharp/Formats/Gif/ImageExtensions.cs
index f1c2ae5fb5..3939299e90 100644
--- a/src/ImageSharp/Formats/Gif/ImageExtensions.cs
+++ b/src/ImageSharp/Formats/Gif/ImageExtensions.cs
@@ -38,47 +38,5 @@ namespace SixLabors.ImageSharp
public static void SaveAsGif(this Image source, Stream stream, GifEncoder encoder)
where TPixel : struct, IPixel
=> source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(GifFormat.Instance));
-
- ///
- /// This method doesn't actually do anything but serves an important purpose...
- /// If you are running ImageSharp on iOS and try to call SaveAsGif, it will throw an excepion:
- /// "Attempting to JIT compile method... OctreeFrameQuantizer.ConstructPalette... while running in aot-only mode."
- /// The reason this happens is the SaveAsGif method makes haevy use of generics, which are too confusing for the AoT
- /// compiler used on Xamarin.iOS. It spins up the JIT compiler to try and figure it out, but that is an illegal op on
- /// iOS so it bombs out.
- /// If you are getting the above error, you need to call this method, which will pre-seed the AoT compiler with the
- /// necessary methods to complete the SaveAsGif call. That's it, otherwise you should NEVER need this method!!!
- ///
- /// The pixel format.
- public static void AotCompileOctreeQuantizer()
- where TPixel : struct, IPixel
- {
- var test = new OctreeFrameQuantizer(new OctreeQuantizer(false));
- test.AotGetPalette();
- }
-
- ///
- /// This method pre-seeds the WuQuantizer in the AoT compiler for iOS.
- ///
- /// The pixel format.
- public static void AotCompileWuQuantizer()
- where TPixel : struct, IPixel
- {
- var test = new WuFrameQuantizer(new WuQuantizer(false));
- test.QuantizeFrame(new ImageFrame(Configuration.Default, 1, 1));
- test.AotGetPalette();
- }
-
- ///
- /// This method pre-seeds the default dithering engine (FloydSteinbergDiffuser) in the AoT compiler for iOS.
- ///
- /// The pixel format.
- public static void AotCompileDithering()
- where TPixel : struct, IPixel
- {
- var test = new FloydSteinbergDiffuser();
- TPixel pixel = default;
- test.Dither(new ImageFrame(Configuration.Default, 1, 1), pixel, pixel, 0, 0, 0, 0, 0, 0);
- }
}
}