diff --git a/BlurHashSharp.sln b/BlurHashSharp.sln
index 3a7ef93..2917211 100644
--- a/BlurHashSharp.sln
+++ b/BlurHashSharp.sln
@@ -19,6 +19,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benches", "benches", "{16AA
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlurHashSharp.Benches", "benches\BlurHashSharp.Benches\BlurHashSharp.Benches.csproj", "{E34874CB-32B1-402D-8E3C-071676468135}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlurHashSharp.ImageSharp", "src\BlurHashSharp.ImageSharp\BlurHashSharp.ImageSharp.csproj", "{32A419EF-8029-4033-BE24-122C83E211F8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlurHashSharp.ImageSharp.Tests", "tests\BlurHashSharp.ImageSharp.Tests\BlurHashSharp.ImageSharp.Tests.csproj", "{C6E91964-A3A2-467A-B202-C1367D484D69}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -92,6 +96,30 @@ Global
{E34874CB-32B1-402D-8E3C-071676468135}.Release|x64.Build.0 = Release|Any CPU
{E34874CB-32B1-402D-8E3C-071676468135}.Release|x86.ActiveCfg = Release|Any CPU
{E34874CB-32B1-402D-8E3C-071676468135}.Release|x86.Build.0 = Release|Any CPU
+ {32A419EF-8029-4033-BE24-122C83E211F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {32A419EF-8029-4033-BE24-122C83E211F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {32A419EF-8029-4033-BE24-122C83E211F8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {32A419EF-8029-4033-BE24-122C83E211F8}.Debug|x64.Build.0 = Debug|Any CPU
+ {32A419EF-8029-4033-BE24-122C83E211F8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {32A419EF-8029-4033-BE24-122C83E211F8}.Debug|x86.Build.0 = Debug|Any CPU
+ {32A419EF-8029-4033-BE24-122C83E211F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {32A419EF-8029-4033-BE24-122C83E211F8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {32A419EF-8029-4033-BE24-122C83E211F8}.Release|x64.ActiveCfg = Release|Any CPU
+ {32A419EF-8029-4033-BE24-122C83E211F8}.Release|x64.Build.0 = Release|Any CPU
+ {32A419EF-8029-4033-BE24-122C83E211F8}.Release|x86.ActiveCfg = Release|Any CPU
+ {32A419EF-8029-4033-BE24-122C83E211F8}.Release|x86.Build.0 = Release|Any CPU
+ {C6E91964-A3A2-467A-B202-C1367D484D69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C6E91964-A3A2-467A-B202-C1367D484D69}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C6E91964-A3A2-467A-B202-C1367D484D69}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C6E91964-A3A2-467A-B202-C1367D484D69}.Debug|x64.Build.0 = Debug|Any CPU
+ {C6E91964-A3A2-467A-B202-C1367D484D69}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C6E91964-A3A2-467A-B202-C1367D484D69}.Debug|x86.Build.0 = Debug|Any CPU
+ {C6E91964-A3A2-467A-B202-C1367D484D69}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C6E91964-A3A2-467A-B202-C1367D484D69}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C6E91964-A3A2-467A-B202-C1367D484D69}.Release|x64.ActiveCfg = Release|Any CPU
+ {C6E91964-A3A2-467A-B202-C1367D484D69}.Release|x64.Build.0 = Release|Any CPU
+ {C6E91964-A3A2-467A-B202-C1367D484D69}.Release|x86.ActiveCfg = Release|Any CPU
+ {C6E91964-A3A2-467A-B202-C1367D484D69}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{680BD7F7-37FA-44B3-8297-91C6EF00A870} = {22515C2C-F86B-404F-A0B0-60F0B8FE9B8C}
@@ -99,5 +127,7 @@ Global
{EA7DE5B7-8A37-4BF1-B10A-7CE7B982CD8A} = {AA9B09A6-896C-4CB8-8B56-7AA05697B218}
{B075D075-93C4-4A19-8657-773593308FD4} = {AA9B09A6-896C-4CB8-8B56-7AA05697B218}
{E34874CB-32B1-402D-8E3C-071676468135} = {16AA13F8-F18E-4C4D-98B9-B45E9E659E5B}
+ {32A419EF-8029-4033-BE24-122C83E211F8} = {22515C2C-F86B-404F-A0B0-60F0B8FE9B8C}
+ {C6E91964-A3A2-467A-B202-C1367D484D69} = {AA9B09A6-896C-4CB8-8B56-7AA05697B218}
EndGlobalSection
EndGlobal
diff --git a/src/BlurHashSharp.ImageSharp/BlurHashEncoder.cs b/src/BlurHashSharp.ImageSharp/BlurHashEncoder.cs
new file mode 100644
index 0000000..2d19823
--- /dev/null
+++ b/src/BlurHashSharp.ImageSharp/BlurHashEncoder.cs
@@ -0,0 +1,72 @@
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using SixLabors.ImageSharp;
+using SixLabors.ImageSharp.Formats;
+using SixLabors.ImageSharp.PixelFormats;
+
+namespace BlurHashSharp.ImageSharp;
+
+///
+/// The BlurHash encoder for use with the SkiaSharp image library.
+///
+public static class BlurHashEncoder
+{
+ private static readonly Lazy Lazy = new(() =>
+ {
+ var config = Configuration.Default.Clone();
+ config.PreferContiguousImageBuffers = true;
+ return config;
+ });
+
+ private static Configuration Configuration => Lazy.Value;
+
+ private static DecoderOptions DecoderOptions =>
+ new DecoderOptions()
+ {
+ Configuration = Configuration
+ };
+
+ ///
+ /// Encodes the BlurHash representation of the image.
+ ///
+ /// The number x components.
+ /// The number y components.
+ /// The path to an encoded image on the file system.
+ /// BlurHash representation of the image.
+ public static string Encode(int xComponent, int yComponent, string filename)
+ {
+ using var image = Image.Load(DecoderOptions, filename);
+ return EncodeInternal(xComponent, yComponent, image);
+ }
+
+ ///
+ /// Encodes the BlurHash representation of the image.
+ ///
+ /// The number x components.
+ /// The number y components.
+ /// The IO stream of an encoded image.
+ /// BlurHash representation of the image.
+ public static string Encode(int xComponent, int yComponent, Stream stream)
+ {
+ using var image = Image.Load(DecoderOptions, stream);
+ return EncodeInternal(xComponent, yComponent, image);
+ }
+
+ private static string EncodeInternal(int xComponent, int yComponent, Image image)
+ {
+ var bytesPerRow = image.Width * (image.PixelType.BitsPerPixel / 8);
+ Span buffer;
+ if (image.DangerousTryGetSinglePixelMemory(out Memory memory))
+ {
+ buffer = MemoryMarshal.AsBytes(memory.Span);
+ }
+ else
+ {
+ buffer = new byte[image.Height * bytesPerRow];
+ image.CopyPixelDataTo(buffer);
+ }
+
+ return CoreBlurHashEncoder.Encode(xComponent, yComponent, image.Width, image.Height, buffer, bytesPerRow, PixelFormat.RGB888);
+ }
+}
diff --git a/src/BlurHashSharp.ImageSharp/BlurHashSharp.ImageSharp.csproj b/src/BlurHashSharp.ImageSharp/BlurHashSharp.ImageSharp.csproj
new file mode 100644
index 0000000..d2a689b
--- /dev/null
+++ b/src/BlurHashSharp.ImageSharp/BlurHashSharp.ImageSharp.csproj
@@ -0,0 +1,32 @@
+
+
+
+ net6.0
+ true
+ enable
+ true
+
+
+
+ Bond_009
+ 1.3.3
+ BlurHash;image;bitmap;imagesharp
+ BlurHash encoder for use with the ImageSharp image library.
+ MIT
+ https://github.com/Bond-009/BlurHashSharp
+ README.md
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BlurHashSharp.SkiaSharp/BlurHashSharp.SkiaSharp.csproj b/src/BlurHashSharp.SkiaSharp/BlurHashSharp.SkiaSharp.csproj
index 5df586b..463a2d6 100644
--- a/src/BlurHashSharp.SkiaSharp/BlurHashSharp.SkiaSharp.csproj
+++ b/src/BlurHashSharp.SkiaSharp/BlurHashSharp.SkiaSharp.csproj
@@ -9,7 +9,7 @@
Bond_009
- 1.3.2
+ 1.3.3
BlurHash;image;bitmap;skiasharp
BlurHash encoder for use with the SkiaSharp image library.
MIT
diff --git a/src/BlurHashSharp/BlurHashSharp.csproj b/src/BlurHashSharp/BlurHashSharp.csproj
index 6a166c1..aec5f56 100644
--- a/src/BlurHashSharp/BlurHashSharp.csproj
+++ b/src/BlurHashSharp/BlurHashSharp.csproj
@@ -10,7 +10,7 @@
Bond_009
- 1.3.2
+ 1.3.3
BlurHash;image;bitmap
BlurHash encoder for working with raw bitmaps in memory.
MIT
diff --git a/src/BlurHashSharp/CoreBlurHashEncoder.cs b/src/BlurHashSharp/CoreBlurHashEncoder.cs
index e6e2c22..b0810ea 100644
--- a/src/BlurHashSharp/CoreBlurHashEncoder.cs
+++ b/src/BlurHashSharp/CoreBlurHashEncoder.cs
@@ -43,8 +43,18 @@ public static string Encode(
static int ThrowPixelFormatArgumentException()
=> throw new ArgumentException("Invalid pixel format.", nameof(pixelFormat));
- int totalComponents = xComponents * yComponents;
- int factorsLen = totalComponents * 3;
+ static int ThrowComponentArgumentOutOfRangeException(string paramName)
+ => throw new ArgumentOutOfRangeException(paramName, "Invalid number of components.");
+
+ if (xComponents < 1 || xComponents > 9)
+ {
+ ThrowComponentArgumentOutOfRangeException(nameof(xComponents));
+ }
+
+ if (yComponents < 1 || yComponents > 9)
+ {
+ ThrowComponentArgumentOutOfRangeException(nameof(yComponents));
+ }
int bytesPerPixel = pixelFormat switch
{
@@ -55,6 +65,9 @@ static int ThrowPixelFormatArgumentException()
_ => ThrowPixelFormatArgumentException()
};
+ int totalComponents = xComponents * yComponents;
+ int factorsLen = totalComponents * 3;
+
float[] rented = ArrayPool.Shared.Rent(factorsLen + height + width);
try
{
diff --git a/tests/BlurHashSharp.ImageSharp.Tests/BlurHashEncoderTests.cs b/tests/BlurHashSharp.ImageSharp.Tests/BlurHashEncoderTests.cs
new file mode 100644
index 0000000..213ae27
--- /dev/null
+++ b/tests/BlurHashSharp.ImageSharp.Tests/BlurHashEncoderTests.cs
@@ -0,0 +1,114 @@
+using System;
+using System.IO;
+using Xunit;
+
+namespace BlurHashSharp.ImageSharp.Tests;
+
+public sealed class BlurHashEncoderTests
+{
+ [Theory]
+ [InlineData("samples.ffmpeg.org/image-samples/delete_node_large.png", 4, 4, "UCL;mj%N?W~p?axsWEM}-,t6IbRn?bWEoct6")]
+ [InlineData("samples.ffmpeg.org/image-samples/digital-applications.png", 4, 4, "UORVqmDPaxMzn,ayofRj?]kDx[tPxuofV[oy")]
+ [InlineData("samples.ffmpeg.org/image-samples/ball.png", 4, 4, "U#M+8hyB}_-XyBkBrwjI~ErxIno{,_jIo{oy")]
+ [InlineData("samples.ffmpeg.org/image-samples/add_node_small.png", 4, 4, "UEKx6z%N?W~ot9-.t7D+%F-:N3D+?bj]oft6")]
+ [InlineData("samples.ffmpeg.org/image-samples/delete_node_small.png", 4, 4, "UIL4y*t9%F~o%Nxsa#Rk%J%LN1M}-;a#j@t6")]
+ [InlineData("samples.ffmpeg.org/image-samples/change_label_large.png", 4, 4, "UBMQ*N%NW7_2~pxtWFM}RhWF-;xs-;RjfPog")]
+ [InlineData("samples.ffmpeg.org/image-samples/open_large.png", 4, 4, "UIJkl}?ct0a%~m?ZN2ogoaD*oefSxwt2t1WC")]
+ [InlineData("samples.ffmpeg.org/image-samples/right_triangle.png", 4, 4, "UMC*tR??MkRYbLWEodkB8-RU%ZtNx]a#V^kB")]
+ [InlineData("samples.ffmpeg.org/image-samples/progress.png", 4, 4, "UREC3ZtI?J%4D#oPM_s;4,IUImM{X3xuogRi")]
+ [InlineData("samples.ffmpeg.org/image-samples/delete_member_small.png", 4, 4, "UMKBRS%Mt7N3?ZxsRkt5WEa$j=%K~o%LWFa#")]
+ [InlineData("samples.ffmpeg.org/image-samples/money-256.png", 4, 4, "UcP6:N^+oLIU8^V?j]oy?HD$WCkD-;RjWBR+")]
+ [InlineData("samples.ffmpeg.org/image-samples/delete_method_large.png", 4, 4, "UELXV;?aW9-;_0%KRpoet1WFxuRk~qWEIUfR")]
+ [InlineData("samples.ffmpeg.org/image-samples/money-2.bmp", 4, 4, "UT6a:iomawatW5fSfOfSokW6fSj^j|avfQfO")]
+ [InlineData("samples.ffmpeg.org/image-samples/test.png", 4, 4, "UVRysgof%Mayayayj[j[~qfQIUofxuofWBWB")]
+ [InlineData("samples.ffmpeg.org/image-samples/screen.png", 4, 4, "UTPQ8B4o4o00ohRkozt7E3axRjxuN1WAoeof")]
+ [InlineData("samples.ffmpeg.org/image-samples/money-256.bmp", 4, 4, "UcP6:N^+oLIU8^V?j]oy?HD$WCkD-;RjWBR+")]
+ [InlineData("samples.ffmpeg.org/image-samples/component.png", 4, 4, "UcNQ?E$m[4=P{FKHKHs;{FnmNrr^[NwikCnm")]
+ [InlineData("samples.ffmpeg.org/image-samples/money.jpg", 4, 4, "UcP6:N^+j[IU8^V?j]oz?HD$WCkD-;RjWBWC")]
+ [InlineData("samples.ffmpeg.org/image-samples/mail.png", 4, 4, "UeO43P%MpL-=~DozRnaeEmkDVqV?x_V@oatR")]
+ [InlineData("samples.ffmpeg.org/image-samples/14121200.jpg", 4, 4, "UTHLSTwb-;IT?dRPt8IUsiNGs:Rj9bM{xbof")]
+ [InlineData("samples.ffmpeg.org/image-samples/methods_large.png", 4, 4, "UHKUZ#-;avj_~nt7N0of%DIW-:xt%MRjofWD")]
+ [InlineData("samples.ffmpeg.org/image-samples/add_component_large.png", 4, 4, "UCKUZw-;~n%M~oxtD+Rj_0xtIWt6?aj]ogt7")]
+ [InlineData("samples.ffmpeg.org/image-samples/delete_component_small.png", 4, 4, "UEIrEhN3^~-=~oxs9HRj~n-:IVxs~oxuogt7")]
+ [InlineData("samples.ffmpeg.org/image-samples/money-256-rle.bmp", 4, 4, "UcP6:N^+oLIU8^V?j]oy?HD$WCkD-;RjWBR+")]
+ [InlineData("samples.ffmpeg.org/image-samples/dither.jpg", 4, 4, "U@KcPS}Uq]n4VonnogkCIcWTt6oexooMV]WC")]
+ [InlineData("samples.ffmpeg.org/image-samples/add_method_large.png", 4, 4, "UELN.F?bav-;_0%LWGWBoZWFxuM|~qa#IUj[")]
+ [InlineData("samples.ffmpeg.org/image-samples/opened_node.png", 4, 4, "UmQ;JC$m+k,LkWbFogbG:bnmKabF{rsDR%r_")]
+ [InlineData("samples.ffmpeg.org/image-samples/forsaken.jpg", 4, 4, "UCCYq6#79FI:00tRt7oyDiNZ?bog-=WB55NG")]
+ [InlineData("samples.ffmpeg.org/image-samples/sspline.BMP", 4, 4, "ULNv*+ystTJ-R8M{kVxapyQ,ROogF2xDi_Rk")]
+ [InlineData("samples.ffmpeg.org/image-samples/delete_component_large.png", 4, 4, "UDKd}W%M~m-;~ot6D+WB_0xtIWxt-;fSogt7")]
+ [InlineData("samples.ffmpeg.org/image-samples/logo.bmp", 4, 4, "UkTP*dmlh0mRujeTgheTgNe.e.gNwxeTf+g3")]
+ [InlineData("samples.ffmpeg.org/image-samples/authentica.jpg", 4, 4, "UJ9@S5M{WB%MRjj[WBj[00WBofj[xufQofj[")]
+ [InlineData("samples.ffmpeg.org/image-samples/off_l16.bmp", 4, 4, "UK6w=zm2i*gGl5iMe+gFakcDf9e=a,b_g3i_")]
+ [InlineData("samples.ffmpeg.org/image-samples/fujifilm-finepix40i.jpg", 4, 4, "ULF~BYR5oa01s:%24.kC9ZNHNHx]MxRjx]bI")]
+ [InlineData("samples.ffmpeg.org/image-samples/magick.png", 4, 4, "UPRC-@~q-;9F-oD%kD%M%3oJD%xv%NM{t7t7")]
+ [InlineData("samples.ffmpeg.org/image-samples/money-24bit.png", 4, 4, "UcP6:N^+oLIU8^V?j]oy?HD$WCkD-;RjWBR+")]
+ [InlineData("samples.ffmpeg.org/image-samples/change_label_small.png", 4, 4, "UJLXV:xvW8_2~p%KWFWFj;og-:WB%MWBxtRk")]
+ [InlineData("samples.ffmpeg.org/image-samples/logo.png", 4, 4, "UPDHzGs:5Onnsqj@WUa#0xag=#k9t6azj[ju")]
+ [InlineData("samples.ffmpeg.org/image-samples/run_large.png", 4, 4, "UcM$[P-6e9-8*{ayofayhgWCt6Rk[Uj@W=of")]
+ [InlineData("samples.ffmpeg.org/image-samples/run_small.png", 4, 4, "ULJb2M%ND,-;t7WBocj?02RjxrRi-,j?RlWA")]
+ [InlineData("samples.ffmpeg.org/image-samples/corbis.png", 4, 4, "UISFz|rBv|xu~pRjRjax?vT1SiWBWX%Lt7WB")]
+ [InlineData("samples.ffmpeg.org/image-samples/delete_member_large.png", 4, 4, "UHLXV;-;fMog?Zt6Rpt7Rij[xtt7~pt8M{fO")]
+ [InlineData("samples.ffmpeg.org/image-samples/right_triangle_option.png", 4, 4, "UHGTNmNN%M_N?vt7WBfk_2x@IURR%#ogt7kB")]
+ [InlineData("samples.ffmpeg.org/image-samples/appligent.jpg", 4, 4, "UKRD7jNZxuxu~WRjNGs;~DRjRjay4.xaxaa{")]
+ [InlineData("samples.ffmpeg.org/image-samples/save_large.png", 4, 4, "UTI=M:oeIWj^~pt7D%M_RjWB%Kt7D$Rj?axu")]
+ [InlineData("samples.ffmpeg.org/image-samples/examples.jpg", 4, 4, "UJN^h]IUxaVtoetRx]of~qRQbbko%2xujZRj")]
+ [InlineData("samples.ffmpeg.org/image-samples/open_small.png", 4, 4, "UKIrEg_2j;M~~n-:RpWExtM|xtt8xwoft2oc")]
+ [InlineData("samples.ffmpeg.org/image-samples/earth2.jpg", 4, 4, "UVE3I:M~IVIp0eNI%1xt=}t5NGax57t3Woog")]
+ [InlineData("samples.ffmpeg.org/image-samples/home.png", 4, 4, "UoMaRyxuTd-p~En+W;ozX.kCn4f8O;ofV?V@")]
+ [InlineData("samples.ffmpeg.org/image-samples/convert.png", 4, 4, "UOHLl6RkRjj[~qj[M{ay_2RkWBayt7azt7WB")]
+ [InlineData("samples.ffmpeg.org/image-samples/add_member_small.png", 4, 4, "UKJ[I|-;t7D;-.%LRlawM|ogobxs~o%LWFWC")]
+ [InlineData("samples.ffmpeg.org/image-samples/magick_small.png", 4, 4, "UWQvn3~px]D*-oD%ozxuxbs.D*xu%gM{xut7")]
+ [InlineData("samples.ffmpeg.org/image-samples/add_method_small.png", 4, 4, "UKJ*uQ?bM~j_?Z-:a$j=WAofxtax~pxtIWRk")]
+ [InlineData("samples.ffmpeg.org/image-samples/ellipsis.png", 4, 4, "UTL;me-;fQ-;~qt7fQt7RjayfQay%Mj[fQj[")]
+ [InlineData("samples.ffmpeg.org/image-samples/original.png", 4, 4, "U~SWcEnighnixGj[a|jtdBbbnObbW;fQjtfQ")]
+ [InlineData("samples.ffmpeg.org/image-samples/methods_small.png", 4, 4, "UIJRdr?aN0%N~nj^M}WCRifS?YxsxuRit7oe")]
+ [InlineData("samples.ffmpeg.org/image-samples/money-16.bmp", 4, 4, "UbP6:N?bflIU4mRiflt7?bD$WBog-;RjWBWB")]
+ [InlineData("samples.ffmpeg.org/image-samples/add_component_small.png", 4, 4, "UBIY6DWI~m%O~o-.4qIU~m_1IVoa~p-:t8a#")]
+ [InlineData("samples.ffmpeg.org/image-samples/add_node_large.png", 4, 4, "UBL#2=-=?X~o-;%KWFIW-+xtIbRl_3Rloct7")]
+ [InlineData("samples.ffmpeg.org/image-samples/make_small.png", 4, 4, "UIKni4-:~n?c-;j[t7of~nt7D+aw?cj[WBof")]
+ [InlineData("samples.ffmpeg.org/image-samples/delete_method_small.png", 4, 4, "UMK1%v-;M}t9_1-.a$t6obayxsoe~pt7IWWD")]
+ [InlineData("samples.ffmpeg.org/image-samples/save_small.png", 4, 4, "UIG+Umt34qM|~pt74o9F%MogW9Ri00IU-;%M")]
+ [InlineData("samples.ffmpeg.org/image-samples/TEST24rle.BMP", 4, 4, "UqFYHsjXKBXBI:j]M_adR%a#xDoINhjYs%f,")]
+ [InlineData("samples.ffmpeg.org/image-samples/deliverance800.jpg", 4, 4, "UB8=NK%iV].9oz%N%Nt7x^xvt7og?wogWAxv")]
+ [InlineData("samples.ffmpeg.org/image-samples/add_member_large.png", 4, 4, "UHLN.F-;oZRl?YxsRpofRioet7t7~pxuRjoc")]
+ [InlineData("samples.ffmpeg.org/image-samples/make_large.png", 4, 4, "UFL4y$%M~n?b?aj[WEj[~ot6D*WC-;j[j@of")]
+ [InlineData("samples.ffmpeg.org/image-samples/closed_node.png", 4, 4, "UnQ;bsTb+R{r,Kf6fkoM+Rr_KHS0,xjbjZoM")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/4_directions.gif", 4, 4, "UG9tIut409IZt4j@WDaz09WD-*j@IZazj@WD")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/top_title_green_frog.gif", 4, 4, "ULM*Ba~S4?^%~VNKxsR+D$M}xsIVD$IVxtWB")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/creatures_001.gif", 4, 4, "UA5=gf%b8*91xqt4RmM$s,n*WXbZy8kBR9V]")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/3d_book2.gif", 4, 4, "UYC?r^-;9FIUofRjM{t700IU%MxuWBxuxuRj")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/2_computers.gif", 4, 4, "U78z.9bF~ot6-?ayRkazIRayM^WU-waxxnj=")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/houses_002.gif", 4, 4, "UcM@7ixuTc?a$3oekrR+TJofwKWB.mWXZ#xZ")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/1.gif", 4, 4, "U~DKySj[fPj[?wj[f6j[-ffPfQfP$|fQfQfQ")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/7up.gif", 4, 4, "UwPjDU-;~qIUx]ofM{Rj-;RjIUtRxaRjoft7")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/2c-button_green_blue2.gif", 4, 4, "U31NdMVAQSpQQUp8Z}f3aJfgk8aepwZ@kYfS")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/8ball.gif", 4, 4, "UJAc#lt700M{EjfRWBWV4TWB_3xuRjayxuof")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/Accident.gif", 4, 4, "UFSs50D%IUM{~qj[ayf7%M%Mxuxut7WBWBay")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/truckbut.gif", 4, 4, "UA3w59baD-j@Dnf7%Ia|upe:NIfjYKf*oejZ")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/Astronaut1.gif", 4, 4, "UAB3._IU9F-;WBIUIUxu00t7tRRj8_xuxuRj")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/3D.gif", 4, 4, "UB6i:OR*1a$kS1oLspS11asp]:NZ$kS1NZ$j")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/2c_button-yellow_red.gif", 4, 4, "UDBeNgtg1Li}AFaNI?WDR,WWn*WW=uowxXfj")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/red_Dot.gif", 4, 4, "UwRxr^%2*J?bv#WBtlt7yqogm,jY?vt7nig3")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/bettie-gifs-3.gif", 4, 4, "UWI;YV4.0KS2E2oft7ae%LaeaeozE1WV%2j[")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/bank.gif", 4, 4, "UzPP+Qjt_Nay%gj[jZayofofayaeM{WAayoz")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/Big_counter.gif", 4, 4, "UFECwdRjM{t7~qayM{of?bj[%Mj[WBay%Mof")]
+ [InlineData("samples.ffmpeg.org/image-samples/GIF/cliff-gifs-trc-32c.gif", 4, 4, "UrKuXW}Ya0XAxxoNn%f5jDWAW=fRohj]jYju")]
+ [InlineData("samples.ffmpeg.org/image-samples/bmp-files/test1.bmp", 4, 4, "U47Y|Hipebi:p3eJeJeJebd+ebe1p2eJeJeJ")]
+ [InlineData("samples.ffmpeg.org/image-samples/bmp-files/8bpp-rle.bmp", 4, 4, "U64.9MI$V%i.RstKn#rqM;s$XKo#o7r?WHOs")]
+ [InlineData("samples.ffmpeg.org/image-samples/bmp-files/rmoney.bmp", 4, 4, "UcP6,G^+oLIU4mV?j]oz?HD$WCkD-;RjWBR+")]
+ [InlineData("samples.ffmpeg.org/image-samples/bmp-files/testcompress8.bmp", 4, 4, "UUCQ3=VU|_U;Un^QW~%#x]WTs.V|WGofX4bv")]
+ [InlineData("samples.ffmpeg.org/image-samples/bmp-files/test32.bmp", 4, 4, "UMGSM;ORNC+I_N$[+Hq.tlt2nOaRtRX5ayWG")]
+ [InlineData("samples.ffmpeg.org/image-samples/bmp-files/test24.bmp", 4, 4, "UMGSM;ORNC+I_N$[+Hq.tlt2nOaRtRX5ayWG")]
+ [InlineData("samples.ffmpeg.org/image-samples/bmp-files/test4.bmp", 4, 4, "UdE3PEr9{zh[Um^QW$%#x]R%s:WFW=baW.X8")]
+ [InlineData("samples.ffmpeg.org/image-samples/bmp-files/test8.bmp", 4, 4, "UUCQ3=VU|_U;Un^QW~%#x]WTs.V|WGofX4bv")]
+ [InlineData("samples.ffmpeg.org/image-samples/ART/6-BOATS.png", 4, 4, "UA8;Z6?wp0o#9GIptRxvxt-;j?WXtSWAj@ae")]
+ [InlineData("samples.ffmpeg.org/image-samples/ART/8257_p_t_477x480_image02.png", 4, 4, "UOJtSIN0Ipi]~q%Lad9FI[xtkBMx%MM{t7xZ")]
+ [InlineData("samples.ffmpeg.org/image-samples/ART/8266_p_t_640x480_image01.png", 4, 4, "UPF~:fI801Ri4mxv-;kC00WYs+ozMwayRloe")]
+
+ public void Encode_Success(string relPath, int xComponent, int yComponent, string expectedResult)
+ {
+ string absPath = Path.Join(Environment.GetEnvironmentVariable("FFMPEG_SAMPLES_PATH"), relPath);
+ Assert.Equal(expectedResult, BlurHashEncoder.Encode(xComponent, yComponent, absPath));
+ }
+}
diff --git a/tests/BlurHashSharp.ImageSharp.Tests/BlurHashSharp.ImageSharp.Tests.csproj b/tests/BlurHashSharp.ImageSharp.Tests/BlurHashSharp.ImageSharp.Tests.csproj
new file mode 100644
index 0000000..65e0482
--- /dev/null
+++ b/tests/BlurHashSharp.ImageSharp.Tests/BlurHashSharp.ImageSharp.Tests.csproj
@@ -0,0 +1,21 @@
+
+
+
+ net8.0
+ enable
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/BlurHashSharp.SkiaSharp.Tests/BlurHashSharp.SkiaSharp.Tests.csproj b/tests/BlurHashSharp.SkiaSharp.Tests/BlurHashSharp.SkiaSharp.Tests.csproj
index 2a800df..b479a71 100644
--- a/tests/BlurHashSharp.SkiaSharp.Tests/BlurHashSharp.SkiaSharp.Tests.csproj
+++ b/tests/BlurHashSharp.SkiaSharp.Tests/BlurHashSharp.SkiaSharp.Tests.csproj
@@ -2,7 +2,9 @@
net8.0
+ enable
false
+ true
@@ -13,7 +15,6 @@
-
diff --git a/tests/BlurHashSharp.Tests/BlurHashSharp.Tests.csproj b/tests/BlurHashSharp.Tests/BlurHashSharp.Tests.csproj
index 8912e27..8874972 100644
--- a/tests/BlurHashSharp.Tests/BlurHashSharp.Tests.csproj
+++ b/tests/BlurHashSharp.Tests/BlurHashSharp.Tests.csproj
@@ -2,7 +2,9 @@
net8.0
+ enable
false
+ true
diff --git a/tests/BlurHashSharp.Tests/CoreBlurHashEncoderTests.cs b/tests/BlurHashSharp.Tests/CoreBlurHashEncoderTests.cs
index 4657612..5b17725 100644
--- a/tests/BlurHashSharp.Tests/CoreBlurHashEncoderTests.cs
+++ b/tests/BlurHashSharp.Tests/CoreBlurHashEncoderTests.cs
@@ -1,43 +1,42 @@
-using System.Collections;
-using System.Collections.Generic;
+using System;
using Xunit;
-namespace BlurHashSharp.Tests
-{
- public class CoreBlurHashEncoderTests
- {
- public class LinearTosRGBRoundTripTestData : IEnumerable