Skip to content

Commit

Permalink
Add BlurHashSharp.ImageSharp project and throw on invalid component c…
Browse files Browse the repository at this point in the history
…ount
  • Loading branch information
Bond-009 committed Sep 5, 2024
1 parent d31e591 commit f9899cd
Show file tree
Hide file tree
Showing 11 changed files with 325 additions and 41 deletions.
30 changes: 30 additions & 0 deletions BlurHashSharp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -92,12 +96,38 @@ 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}
{2422C8A8-5121-4BA4-8B8F-F8D00C659E98} = {22515C2C-F86B-404F-A0B0-60F0B8FE9B8C}
{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
72 changes: 72 additions & 0 deletions src/BlurHashSharp.ImageSharp/BlurHashEncoder.cs
Original file line number Diff line number Diff line change
@@ -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;

/// <summary>
/// The BlurHash encoder for use with the SkiaSharp image library.
/// </summary>
public static class BlurHashEncoder
{
private static readonly Lazy<Configuration> 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
};

/// <summary>
/// Encodes the BlurHash representation of the image.
/// </summary>
/// <param name="xComponent">The number x components.</param>
/// <param name="yComponent">The number y components.</param>
/// <param name="filename">The path to an encoded image on the file system.</param>
/// <returns>BlurHash representation of the image.</returns>
public static string Encode(int xComponent, int yComponent, string filename)
{
using var image = Image.Load<Rgb24>(DecoderOptions, filename);
return EncodeInternal(xComponent, yComponent, image);
}

/// <summary>
/// Encodes the BlurHash representation of the image.
/// </summary>
/// <param name="xComponent">The number x components.</param>
/// <param name="yComponent">The number y components.</param>
/// <param name="stream">The IO stream of an encoded image.</param>
/// <returns>BlurHash representation of the image.</returns>
public static string Encode(int xComponent, int yComponent, Stream stream)
{
using var image = Image.Load<Rgb24>(DecoderOptions, stream);
return EncodeInternal(xComponent, yComponent, image);
}

private static string EncodeInternal(int xComponent, int yComponent, Image<Rgb24> image)
{
var bytesPerRow = image.Width * (image.PixelType.BitsPerPixel / 8);
Span<byte> buffer;
if (image.DangerousTryGetSinglePixelMemory(out Memory<Rgb24> 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);
}
}
32 changes: 32 additions & 0 deletions src/BlurHashSharp.ImageSharp/BlurHashSharp.ImageSharp.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

<PropertyGroup>
<Authors>Bond_009</Authors>
<Version>1.3.3</Version>
<PackageTags>BlurHash;image;bitmap;imagesharp</PackageTags>
<Description>BlurHash encoder for use with the ImageSharp image library.</Description>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RepositoryUrl>https://github.com/Bond-009/BlurHashSharp</RepositoryUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>

<ItemGroup>
<None Include="../../README.md" Pack="true" PackagePath="/"/>
</ItemGroup>

<ItemGroup>
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="../BlurHashSharp/BlurHashSharp.csproj" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion src/BlurHashSharp.SkiaSharp/BlurHashSharp.SkiaSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<PropertyGroup>
<Authors>Bond_009</Authors>
<Version>1.3.2</Version>
<Version>1.3.3</Version>
<PackageTags>BlurHash;image;bitmap;skiasharp</PackageTags>
<Description>BlurHash encoder for use with the SkiaSharp image library.</Description>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand Down
2 changes: 1 addition & 1 deletion src/BlurHashSharp/BlurHashSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<PropertyGroup>
<Authors>Bond_009</Authors>
<Version>1.3.2</Version>
<Version>1.3.3</Version>
<PackageTags>BlurHash;image;bitmap</PackageTags>
<Description>BlurHash encoder for working with raw bitmaps in memory.</Description>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand Down
17 changes: 15 additions & 2 deletions src/BlurHashSharp/CoreBlurHashEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -55,6 +65,9 @@ static int ThrowPixelFormatArgumentException()
_ => ThrowPixelFormatArgumentException()
};

int totalComponents = xComponents * yComponents;
int factorsLen = totalComponents * 3;

float[] rented = ArrayPool<float>.Shared.Rent(factorsLen + height + width);
try
{
Expand Down
Loading

0 comments on commit f9899cd

Please sign in to comment.