diff --git a/UIX.RenderApi.OpenGL/UIX.RenderApi.OpenGL.csproj b/UIX.RenderApi.OpenGL/UIX.RenderApi.OpenGL.csproj
index 431887e..4fcf15c 100644
--- a/UIX.RenderApi.OpenGL/UIX.RenderApi.OpenGL.csproj
+++ b/UIX.RenderApi.OpenGL/UIX.RenderApi.OpenGL.csproj
@@ -11,16 +11,16 @@
-
-
-
-
+
+
+
+
diff --git a/UIX.RenderApi/Microsoft/Iris/Render/Bitmaps/BitmapInformation.cs b/UIX.RenderApi/Microsoft/Iris/Render/Bitmaps/BitmapInformation.cs
new file mode 100644
index 0000000..889fd39
--- /dev/null
+++ b/UIX.RenderApi/Microsoft/Iris/Render/Bitmaps/BitmapInformation.cs
@@ -0,0 +1,25 @@
+// Based on Microsoft.Iris.Render.Extensions.BitmapInformation
+
+using System;
+using Microsoft.Iris.Render.Extensions;
+using Microsoft.Iris.Render.Internal;
+
+namespace Microsoft.Iris.Render.Bitmaps;
+
+public abstract class BitmapInformation : IDisposable
+{
+ public ImageInformation ImageInfo { get; protected set; }
+
+ public abstract HRESULT LoadFile(string filename, ImageRequirements req);
+
+ public abstract HRESULT LoadResource(string moduleName, string resourceId, ImageRequirements req);
+
+ public abstract HRESULT LoadBuffer(IntPtr pvSrc, int cbSize, ImageRequirements req);
+
+ public abstract HRESULT LoadRaw(Size sizeActualPxl, int nStride, SurfaceFormat nFormat, nint pvData,
+ ImageRequirements req);
+
+ public abstract HRESULT LoadHeader(IntPtr pvSrc, int cbSize, ImageRequirements req);
+
+ public abstract void Dispose();
+}
\ No newline at end of file
diff --git a/UIX.RenderApi/Microsoft/Iris/Render/Bitmaps/ImageSharpBitmapInformation.cs b/UIX.RenderApi/Microsoft/Iris/Render/Bitmaps/ImageSharpBitmapInformation.cs
new file mode 100644
index 0000000..ff2a3cb
--- /dev/null
+++ b/UIX.RenderApi/Microsoft/Iris/Render/Bitmaps/ImageSharpBitmapInformation.cs
@@ -0,0 +1,127 @@
+using System;
+using System.IO;
+using Microsoft.Iris.Render.Extensions;
+using Microsoft.Iris.Render.Internal;
+using SixLabors.ImageSharp;
+using SixLabors.ImageSharp.Processing;
+
+namespace Microsoft.Iris.Render.Bitmaps;
+
+public sealed class ImageSharpBitmapInformation : BitmapInformation
+{
+ private Image _image;
+
+ public override HRESULT LoadFile(string filename, ImageRequirements req) =>
+ Try(() => _LoadFile(filename, req));
+
+ public override HRESULT LoadResource(string moduleName, string resourceId, ImageRequirements req) =>
+ Try(() => _LoadResource(moduleName, resourceId, req));
+
+ public override HRESULT LoadBuffer(nint pvSrc, int cbSize, ImageRequirements req) =>
+ Try(() => _LoadBuffer(pvSrc, cbSize, req));
+
+ public override HRESULT LoadRaw(Size sizeActualPxl, int nStride, SurfaceFormat nFormat, IntPtr pvData, ImageRequirements req) =>
+ Try(() => _LoadRaw(sizeActualPxl, nStride, nFormat, pvData, req));
+
+ public override HRESULT LoadHeader(nint pvSrc, int cbSize, ImageRequirements req) =>
+ Try(() => _LoadHeader(pvSrc, cbSize, req));
+
+ public override void Dispose()
+ {
+ _image?.Dispose();
+ _image = null;
+ }
+
+ private void _LoadFile(string filename, ImageRequirements req)
+ {
+ _image = Image.Load(filename);
+
+ ApplyImageTransitions(req);
+ UpdateImageInfo(_image);
+ }
+
+ private void _LoadResource(string moduleName, string resourceId, ImageRequirements req)
+ {
+ throw new NotImplementedException();
+ }
+
+ private unsafe void _LoadBuffer(nint pvSrc, int cbSize, ImageRequirements req)
+ {
+ ReadOnlySpan fileBuffer = new(pvSrc.ToPointer(), cbSize);
+ _image = Image.Load(fileBuffer).Clone(_ => {});
+
+ ApplyImageTransitions(req);
+ UpdateImageInfo(_image);
+ }
+
+ private void _LoadRaw(Size sizeActualPxl, int nStride, SurfaceFormat nFormat, IntPtr pvData, ImageRequirements req)
+ {
+ throw new NotImplementedException();
+ }
+
+ private unsafe void _LoadHeader(nint pvSrc, int cbSize, ImageRequirements req)
+ {
+ ReadOnlySpan fileBuffer = new(pvSrc.ToPointer(), cbSize);
+ var imageInfo = Image.Identify(fileBuffer);
+
+ UpdateImageInfo(imageInfo);
+ }
+
+ private void ApplyImageTransitions(ImageRequirements req)
+ {
+ if (req.Flippable)
+ _image.Mutate(x => x.Flip(FlipMode.Horizontal));
+ }
+
+ private void UpdateImageInfo(Image image) => UpdateImageInfo(new ImageInfo(image.Size, image.Metadata));
+
+ private void UpdateImageInfo(ImageInfo imageInfo)
+ {
+ Size imageSize = new(imageInfo.Width, imageInfo.Height);
+
+ // TODO: Read pixel data format
+ SurfaceFormat format = SurfaceFormat.None;
+
+ ImageInfo = new ImageInformation
+ {
+ Header = new ImageHeader
+ {
+ sizeActualPxl = imageSize,
+ sizeOriginalPxl = imageSize,
+ nStride = imageInfo.PixelType.BitsPerPixel / 8,
+ nFormat = format
+ },
+ Data = default
+ };
+ }
+
+ private static HRESULT Try(Action action)
+ {
+ try
+ {
+ action();
+ }
+ catch (FileNotFoundException)
+ {
+ return 0x80070002;
+ }
+ catch (ArgumentNullException)
+ {
+ return 0x80004003;
+ }
+ catch (ArgumentException)
+ {
+ return 0x80070057;
+ }
+ catch (NotImplementedException)
+ {
+ return 0x80004001;
+ }
+ catch
+ {
+ return HRESULT.E_FAIL;
+ }
+
+ return HRESULT.S_OK;
+ }
+}
\ No newline at end of file
diff --git a/UIX.RenderApi/Microsoft/Iris/Render/Bitmaps/SpBitmapInformation.cs b/UIX.RenderApi/Microsoft/Iris/Render/Bitmaps/SpBitmapInformation.cs
new file mode 100644
index 0000000..910836e
--- /dev/null
+++ b/UIX.RenderApi/Microsoft/Iris/Render/Bitmaps/SpBitmapInformation.cs
@@ -0,0 +1,136 @@
+// Based on decompilation with JetBrains decompiler
+// Type: Microsoft.Iris.Render.Extensions.BitmapInformation
+// Assembly: UIX.RenderApi, Version=4.8.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217
+// MVID: D47658B8-A8EA-43D6-8837-ECE823BFFFC1
+// Assembly location: C:\Program Files\Zune\UIX.RenderApi.dll
+
+using System;
+using Microsoft.Iris.Render.Extensions;
+using Microsoft.Iris.Render.Internal;
+using Microsoft.Iris.Render.Protocol;
+
+namespace Microsoft.Iris.Render.Bitmaps;
+
+internal sealed class SpBitmapInformation : BitmapInformation
+{
+ public HSpBitmap hBitmap;
+
+ public override HRESULT LoadFile(string filename, ImageRequirements req)
+ {
+ var nOptions = ExtensionsApi.BitmapOptions.Decode;
+ if (req.Flippable)
+ nOptions |= ExtensionsApi.BitmapOptions.Flip;
+
+ var hresult = ExtensionsApi.SpBitmapLoadFile(filename, req, nOptions,
+ out hBitmap, out var imageInformation);
+
+ if (hresult.IsSuccess())
+ {
+ ImageInfo = imageInformation;
+ }
+ else
+ {
+ ImageInfo = default;
+ hBitmap = default;
+ }
+
+ return hresult;
+ }
+
+ public override HRESULT LoadResource(string moduleName, string resourceId, ImageRequirements req)
+ {
+ var hinst = ModuleManager.Instance.LoadModule(moduleName);
+ if (hinst == Win32Api.HINSTANCE.NULL)
+ return 0x80070006;
+
+ var nOptions = ExtensionsApi.BitmapOptions.Decode;
+ if (req.Flippable)
+ nOptions |= ExtensionsApi.BitmapOptions.Flip;
+
+ var hresult = ExtensionsApi.SpBitmapLoadResource(hinst, resourceId, 10, req, nOptions,
+ out hBitmap, out var imageInformation);
+
+ if (hresult.IsSuccess())
+ {
+ ImageInfo = imageInformation;
+ }
+ else
+ {
+ ImageInfo = default;
+ hBitmap = default;
+ }
+
+ return hresult;
+ }
+
+ public override HRESULT LoadBuffer(IntPtr pvSrc, int cbSize, ImageRequirements req)
+ {
+ var nOptions = ExtensionsApi.BitmapOptions.Decode;
+ if (req.Flippable)
+ nOptions |= ExtensionsApi.BitmapOptions.Flip;
+
+ var hresult = ExtensionsApi.SpBitmapLoadBuffer(pvSrc, (uint)cbSize, req, nOptions,
+ out hBitmap, out var imageInformation);
+
+ if (hresult.IsSuccess())
+ {
+ ImageInfo = imageInformation;
+ }
+ else
+ {
+ ImageInfo = default;
+ hBitmap = default;
+ }
+
+ return hresult;
+ }
+
+ public override HRESULT LoadRaw(Size sizeActualPxl, int nStride, SurfaceFormat nFormat, IntPtr pvData, ImageRequirements req)
+ {
+ var nOptions = ExtensionsApi.BitmapOptions.Decode;
+ if (req.Flippable)
+ nOptions |= ExtensionsApi.BitmapOptions.Flip;
+
+ var hresult = ExtensionsApi.SpBitmapLoadRaw(sizeActualPxl, nStride, nFormat, pvData, req, nOptions,
+ out hBitmap, out var imageInformation);
+
+ if (hresult.IsSuccess())
+ {
+ ImageInfo = imageInformation;
+ }
+ else
+ {
+ ImageInfo = default;
+ hBitmap = default;
+ }
+
+ return hresult;
+ }
+
+ public override HRESULT LoadHeader(IntPtr pvSrc, int cbSize, ImageRequirements req)
+ {
+ var hresult = ExtensionsApi.SpBitmapLoadBuffer(pvSrc, (uint)cbSize, req, ExtensionsApi.BitmapOptions.None,
+ out hBitmap, out var imageInformation);
+
+ if (hresult.IsSuccess())
+ {
+ ImageInfo = imageInformation;
+ }
+ else
+ {
+ ImageInfo = default;
+ hBitmap = default;
+ }
+
+ return hresult;
+ }
+
+ public override void Dispose()
+ {
+ if (hBitmap == HSpBitmap.NULL)
+ return;
+
+ EngineApi.IFC(ExtensionsApi.SpBitmapDelete(hBitmap));
+ hBitmap = HSpBitmap.NULL;
+ }
+}
\ No newline at end of file
diff --git a/UIX.RenderApi/Microsoft/Iris/Render/Extensions/BitmapInformation.cs b/UIX.RenderApi/Microsoft/Iris/Render/Extensions/BitmapInformation.cs
deleted file mode 100644
index 6102a63..0000000
--- a/UIX.RenderApi/Microsoft/Iris/Render/Extensions/BitmapInformation.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Decompiled with JetBrains decompiler
-// Type: Microsoft.Iris.Render.Extensions.BitmapInformation
-// Assembly: UIX.RenderApi, Version=4.8.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217
-// MVID: D47658B8-A8EA-43D6-8837-ECE823BFFFC1
-// Assembly location: C:\Program Files\Zune\UIX.RenderApi.dll
-
-using Microsoft.Iris.Render.Protocol;
-using System;
-
-namespace Microsoft.Iris.Render.Extensions
-{
- public class BitmapInformation : IDisposable
- {
- public ImageInformation imageInfo;
- internal HSpBitmap hBitmap;
-
- public void Dispose() => ReleaseData();
-
- private void ReleaseData()
- {
- if (hBitmap == HSpBitmap.NULL)
- return;
-
- EngineApi.IFC(ExtensionsApi.SpBitmapDelete(hBitmap));
- hBitmap = HSpBitmap.NULL;
- }
- }
-}
diff --git a/UIX.RenderApi/Microsoft/Iris/Render/Extensions/ImageCacheItem.cs b/UIX.RenderApi/Microsoft/Iris/Render/Extensions/ImageCacheItem.cs
index 8b08fd0..340aed8 100644
--- a/UIX.RenderApi/Microsoft/Iris/Render/Extensions/ImageCacheItem.cs
+++ b/UIX.RenderApi/Microsoft/Iris/Render/Extensions/ImageCacheItem.cs
@@ -6,6 +6,7 @@
using System;
using System.Collections;
+using Microsoft.Iris.Render.Bitmaps;
namespace Microsoft.Iris.Render.Extensions
{
@@ -254,7 +255,7 @@ namespace Microsoft.Iris.Render.Extensions
return false;
m_info = bitmapInfo;
- SetSize(m_info.imageInfo.Header.sizeActualPxl);
+ SetSize(m_info.ImageInfo.Header.sizeActualPxl);
return true;
}
diff --git a/UIX.RenderApi/Microsoft/Iris/Render/Extensions/ImageLoader.cs b/UIX.RenderApi/Microsoft/Iris/Render/Extensions/ImageLoader.cs
index 035fcfa..69d6401 100644
--- a/UIX.RenderApi/Microsoft/Iris/Render/Extensions/ImageLoader.cs
+++ b/UIX.RenderApi/Microsoft/Iris/Render/Extensions/ImageLoader.cs
@@ -8,11 +8,21 @@ using Microsoft.Iris.Render.Common;
using Microsoft.Iris.Render.Internal;
using System;
using System.Runtime.InteropServices;
+using Microsoft.Iris.Render.Bitmaps;
namespace Microsoft.Iris.Render.Extensions
{
public static class ImageLoader
{
+ private static BitmapInformation CreateBitmapInformation()
+ {
+#if WINDOWS
+ return new SpBitmapInformation();
+#else
+ return new ImageSharpBitmapInformation();
+#endif
+ }
+
public static bool LoadHeader(IntPtr rgData, int length, out ImageHeader header) =>
LoadHeader(rgData, length, new ImageRequirements(), out header);
@@ -26,17 +36,16 @@ namespace Microsoft.Iris.Render.Extensions
Debug2.Validate(length > 0, typeof(ArgumentOutOfRangeException), "Must provide non-zero length data to load");
Debug2.Validate(req != null, typeof(ArgumentNullException), "Must provide valid ImageRequirements");
- var bitmapInformation = new BitmapInformation();
- var hresult = new HRESULT(-1);
+ var bitmapInformation = CreateBitmapInformation();
+ HRESULT hresult = -1;
try
{
- hresult = ExtensionsApi.SpBitmapLoadBuffer(rgData, (uint)length, req, ExtensionsApi.BitmapOptions.None,
- out bitmapInformation.hBitmap, out bitmapInformation.imageInfo);
+ hresult = bitmapInformation.LoadBuffer(rgData, length, req);
header = !hresult.IsSuccess()
? new ImageHeader()
- : bitmapInformation.imageInfo.Header;
+ : bitmapInformation.ImageInfo.Header;
}
finally
{
@@ -65,14 +74,9 @@ namespace Microsoft.Iris.Render.Extensions
AntialiasEdges = antialiasEdges,
MaximumSize = maxSize
};
-
- var nOptions = ExtensionsApi.BitmapOptions.Decode;
- if (flipRTL)
- nOptions |= ExtensionsApi.BitmapOptions.Flip;
-
- var bitmapInformation = new BitmapInformation();
- var hresult = ExtensionsApi.SpBitmapLoadFile(filename, req, nOptions,
- out bitmapInformation.hBitmap, out bitmapInformation.imageInfo);
+
+ var bitmapInformation = CreateBitmapInformation();
+ var hresult = bitmapInformation.LoadFile(filename, req);
if (!hresult.IsSuccess())
{
bitmapInfo = null;
@@ -80,10 +84,10 @@ namespace Microsoft.Iris.Render.Extensions
}
var loadSuccess = image.LoadContent(
- SurfaceFormatInfo.ToImageFormat(bitmapInformation.imageInfo.Header.nFormat),
- bitmapInformation.imageInfo.Header.sizeActualPxl,
- bitmapInformation.imageInfo.Header.nStride,
- bitmapInformation.imageInfo.Data.rgData);
+ SurfaceFormatInfo.ToImageFormat(bitmapInformation.ImageInfo.Header.nFormat),
+ bitmapInformation.ImageInfo.Header.sizeActualPxl,
+ bitmapInformation.ImageInfo.Header.nStride,
+ bitmapInformation.ImageInfo.Data.rgData);
if (loadSuccess)
{
@@ -119,20 +123,8 @@ namespace Microsoft.Iris.Render.Extensions
MaximumSize = maxSize
};
- var hinst = ModuleManager.Instance.LoadModule(moduleName);
- if (hinst == Win32Api.HINSTANCE.NULL)
- {
- bitmapInfo = null;
- return false;
- }
-
- var nOptions = ExtensionsApi.BitmapOptions.Decode;
- if (flipRTL)
- nOptions |= ExtensionsApi.BitmapOptions.Flip;
-
- var bitmapInformation = new BitmapInformation();
- var hresult = ExtensionsApi.SpBitmapLoadResource(hinst, resourceID, 10, req, nOptions,
- out bitmapInformation.hBitmap, out bitmapInformation.imageInfo);
+ var bitmapInformation = CreateBitmapInformation();
+ var hresult = bitmapInformation.LoadResource(moduleName, resourceID, req);
if (hresult.IsError())
{
bitmapInfo = null;
@@ -140,10 +132,10 @@ namespace Microsoft.Iris.Render.Extensions
}
var loadSuccess = image.LoadContent(
- SurfaceFormatInfo.ToImageFormat(bitmapInformation.imageInfo.Header.nFormat),
- bitmapInformation.imageInfo.Header.sizeActualPxl,
- bitmapInformation.imageInfo.Header.nStride,
- bitmapInformation.imageInfo.Data.rgData);
+ SurfaceFormatInfo.ToImageFormat(bitmapInformation.ImageInfo.Header.nFormat),
+ bitmapInformation.ImageInfo.Header.sizeActualPxl,
+ bitmapInformation.ImageInfo.Header.nStride,
+ bitmapInformation.ImageInfo.Data.rgData);
if (loadSuccess)
{
@@ -180,13 +172,8 @@ namespace Microsoft.Iris.Render.Extensions
MaximumSize = maxSize
};
- var nOptions = ExtensionsApi.BitmapOptions.Decode;
- if (flipRTL)
- nOptions |= ExtensionsApi.BitmapOptions.Flip;
-
- var bitmapInformation = new BitmapInformation();
- var hresult = ExtensionsApi.SpBitmapLoadBuffer(buffer, (uint)length, req, nOptions,
- out bitmapInformation.hBitmap, out bitmapInformation.imageInfo);
+ var bitmapInformation = CreateBitmapInformation();
+ var hresult = bitmapInformation.LoadBuffer(buffer, length, req);
if (!hresult.IsSuccess())
{
bitmapInfo = null;
@@ -194,10 +181,10 @@ namespace Microsoft.Iris.Render.Extensions
}
var loadSuccess = image.LoadContent(
- SurfaceFormatInfo.ToImageFormat(bitmapInformation.imageInfo.Header.nFormat),
- bitmapInformation.imageInfo.Header.sizeActualPxl,
- bitmapInformation.imageInfo.Header.nStride,
- bitmapInformation.imageInfo.Data.rgData);
+ SurfaceFormatInfo.ToImageFormat(bitmapInformation.ImageInfo.Header.nFormat),
+ bitmapInformation.ImageInfo.Header.sizeActualPxl,
+ bitmapInformation.ImageInfo.Header.nStride,
+ bitmapInformation.ImageInfo.Data.rgData);
if (loadSuccess)
{
@@ -236,13 +223,8 @@ namespace Microsoft.Iris.Render.Extensions
MaximumSize = maxSize
};
- var nOptions = ExtensionsApi.BitmapOptions.Decode;
- if (flipRTL)
- nOptions |= ExtensionsApi.BitmapOptions.Flip;
-
- var bitmapInformation = new BitmapInformation();
- var hresult = ExtensionsApi.SpBitmapLoadRaw(imageSize, stride, format, buffer, req, nOptions,
- out bitmapInformation.hBitmap, out bitmapInformation.imageInfo);
+ var bitmapInformation = CreateBitmapInformation();
+ var hresult = bitmapInformation.LoadRaw(imageSize, stride, format, buffer, req);
if (!hresult.IsSuccess())
{
bitmapInfo = null;
@@ -250,10 +232,10 @@ namespace Microsoft.Iris.Render.Extensions
}
var loadSuccess = image.LoadContent(
- SurfaceFormatInfo.ToImageFormat(bitmapInformation.imageInfo.Header.nFormat),
- bitmapInformation.imageInfo.Header.sizeActualPxl,
- bitmapInformation.imageInfo.Header.nStride,
- bitmapInformation.imageInfo.Data.rgData);
+ SurfaceFormatInfo.ToImageFormat(bitmapInformation.ImageInfo.Header.nFormat),
+ bitmapInformation.ImageInfo.Header.sizeActualPxl,
+ bitmapInformation.ImageInfo.Header.nStride,
+ bitmapInformation.ImageInfo.Data.rgData);
if (loadSuccess)
{
diff --git a/UIX.RenderApi/Microsoft/Iris/Render/Internal/HRESULT.cs b/UIX.RenderApi/Microsoft/Iris/Render/Internal/HRESULT.cs
index 7c7077e..14ccdee 100644
--- a/UIX.RenderApi/Microsoft/Iris/Render/Internal/HRESULT.cs
+++ b/UIX.RenderApi/Microsoft/Iris/Render/Internal/HRESULT.cs
@@ -8,31 +8,39 @@ using System.Runtime.InteropServices;
namespace Microsoft.Iris.Render.Internal
{
- internal struct HRESULT
+ public struct HRESULT
{
- public int hr;
+ internal int hr;
public HRESULT(int hr) => this.hr = hr;
public static bool operator ==(HRESULT hrA, HRESULT hrB) => hrA.hr == hrB.hr;
public static bool operator !=(HRESULT hrA, HRESULT hrB) => hrA.hr != hrB.hr;
+
+ public static implicit operator HRESULT(int hr) => new(hr);
+ public static implicit operator HRESULT(uint hr) => new(unchecked((int)hr));
+ public static implicit operator int(HRESULT hr) => hr.Int;
- public override bool Equals(object oCompare) => oCompare is HRESULT hresult && this.hr == hresult.hr;
+ public override bool Equals(object oCompare) => oCompare is HRESULT hresult && hr == hresult.hr;
- public override int GetHashCode() => this.hr;
+ public override int GetHashCode() => hr;
- public bool IsError() => this.hr < 0;
+ public bool IsError() => hr < 0;
- public bool IsSuccess() => this.hr >= 0;
+ public bool IsSuccess() => hr >= 0;
public void HandleError()
{
- if (!this.IsError())
+ if (!IsError())
return;
- Marshal.ThrowExceptionForHR(this.hr);
+
+ Marshal.ThrowExceptionForHR(hr);
}
- public int Int => this.hr;
+ public int Int => hr;
+
+ public static HRESULT S_OK => new(0);
+ public static HRESULT E_FAIL => 0x80004005;
}
}
diff --git a/UIX.RenderApi/UIX.RenderApi.csproj b/UIX.RenderApi/UIX.RenderApi.csproj
index 36eadfb..43bf858 100644
--- a/UIX.RenderApi/UIX.RenderApi.csproj
+++ b/UIX.RenderApi/UIX.RenderApi.csproj
@@ -8,6 +8,12 @@
false
true
- true
+ ./sixlabors-sample.lic
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UIX.RenderApi/sixlabors-sample.lic b/UIX.RenderApi/sixlabors-sample.lic
new file mode 100644
index 0000000..26c704d
--- /dev/null
+++ b/UIX.RenderApi/sixlabors-sample.lic
@@ -0,0 +1 @@
+Id=ctm_01k4a0m3dxnya9epg35rqqxs29;Kind=Community;ExpiryDateUtc=2026-12-03T09:33:00.1566670Z;Key=M+2oIq6h6sAag2H476SNAgeI8LUHBYIhPnTHNzADw2WBuJ9+KYC8ouKV6kgbg78CuxMC2FbgnNUcHvvIT/s8Qg==
\ No newline at end of file