Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions src/Imghoard.Tests/ClientTests.cs

This file was deleted.

30 changes: 30 additions & 0 deletions src/Imghoard.Tests/Formatters/Base64FileFormatterTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Text;
using System.Text.Json;
using Imghoard.Models;
using Xunit;

namespace Imghoard.Tests.Formatters
{
public class Base64FileFormatterTest
{
[Fact]
public void FormatTest()
{
using var pixel = typeof(Base64FileFormatterTest).Assembly
.GetManifestResourceStream("Imghoard.Tests.Resources.BlackPixel.png");

var bytes = JsonSerializer.SerializeToUtf8Bytes(
new PostImage
{
Stream = pixel
},
ImghoardClient.JsonSerializerOptions
);

Assert.Equal(
@"{""Data"":""data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVR4nGNiAAAABgADNjd8qAAAAABJRU5ErkJggg==""}",
Encoding.UTF8.GetString(bytes)
);
}
}
}
12 changes: 9 additions & 3 deletions src/Imghoard.Tests/Imghoard.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
<ApplicationIcon />
<StartupObject />
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<None Remove="Resources\BlackPixel.png" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="Resources\BlackPixel.png" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
Expand Down
14 changes: 0 additions & 14 deletions src/Imghoard.Tests/Program.cs

This file was deleted.

Binary file added src/Imghoard.Tests/Resources/BlackPixel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
90 changes: 90 additions & 0 deletions src/Imghoard/Formatters/Base64FileFormatter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using System;
using System.Buffers;
using System.Buffers.Text;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Miki.Utils.Imaging.Headers;
using Miki.Utils.Imaging.Headers.Models;

namespace Imghoard.Formatters
{
internal sealed class Base64FileFormatter : JsonConverter<Stream>
{
public override Stream Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotSupportedException("Reading a Base64 stream is not supported.");
}

public override void Write(Utf8JsonWriter writer, Stream value, JsonSerializerOptions options)
{
byte[] data;

if (value is MemoryStream memoryStream)
{
data = memoryStream.ToArray();
}
else
{
// TODO: Check if this can be improved.
using var ms = new MemoryStream();
value.Position = 0;
value.CopyTo(ms);
data = ms.ToArray();
}

var (supported, name) = IsSupported(data);

if (!supported)
{
throw new NotSupportedException($"File extension {name} is not supported. Supported extensions: png, jpeg, gif.");
}

var prefix = $"data:image/{name};base64,";

var prefixLength = Encoding.UTF8.GetByteCount(prefix);
var encodingLength = Base64.GetMaxEncodedToUtf8Length(data.Length);
var length = prefixLength + encodingLength;

var destination = ArrayPool<byte>.Shared.Rent(length);
var span = destination.AsSpan();

try
{
Encoding.UTF8.GetBytes(prefix, span);

var status = Base64.EncodeToUtf8(data, span.Slice(prefixLength), out var consumed, out var written);
Debug.Assert(status == OperationStatus.Done);
Debug.Assert(consumed == data.Length);

writer.WriteStringValue(span.Slice(0, prefixLength + written));
}
finally
{
ArrayPool<byte>.Shared.Return(destination);
}
}

private static (bool supported, string name) IsSupported(byte[] image)
{
if (ImageHeaders.Validate(image, ImageType.Png))
{
return (true, "png");
}

if (ImageHeaders.Validate(image, ImageType.Jpeg))
{
return (true, "jpeg");
}

if (ImageHeaders.Validate(image, ImageType.Gif89a) || ImageHeaders.Validate(image, ImageType.Gif87a))
{
return (true, "gif");
}

return (false, null);
}
}
}
3 changes: 1 addition & 2 deletions src/Imghoard/Imghoard.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Miki.Net.Http" Version="2.1.0" />
<PackageReference Include="Miki.Utils.Imaging.Headers" Version="1.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="System.Drawing.Common" Version="4.5.1" />
<PackageReference Include="System.Text.Json" Version="4.6.0" />
</ItemGroup>

</Project>
Loading