summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Bitmap.cs105
-rw-r--r--OnekoOnline.csproj7
2 files changed, 46 insertions, 66 deletions
diff --git a/Bitmap.cs b/Bitmap.cs
index 4cd44d7..fc6fa40 100644
--- a/Bitmap.cs
+++ b/Bitmap.cs
@@ -1,14 +1,13 @@
using System.Buffers.Binary;
using System.IO.Compression;
-using System.Numerics;
using Raylib_cs;
namespace OnekoOnline;
class Bitmap : IDisposable
{
- public readonly int Width;
- public readonly int Height;
+ public int Width => Texture.Width;
+ public int Height => Texture.Height;
public readonly Texture2D Texture;
readonly byte[] SerializedData;
@@ -16,63 +15,50 @@ class Bitmap : IDisposable
const int MaxWidth = 256;
const int MaxHeight = 256;
- public Bitmap(Image img, int MaxW = 256, int MaxH = 256)
+ public Bitmap(Image img, int MaxW = MaxWidth, int MaxH = MaxHeight)
{
- Width = img.Width;
- Height = img.Height;
//Crop image if too big
- if (Width > MaxW || Height > MaxH) Raylib.ImageCrop(ref img, new Rectangle(0f, 0f, MaxW, MaxH));
+ if (img.Width > MaxW || img.Height > MaxH) {
+ Raylib.ImageCrop(ref img, new Rectangle(0f, 0f, MaxW, MaxH));
+ }
+ Raylib.ImageFormat(ref img, PixelFormat.UncompressedR8G8B8A8);
Texture = Raylib.LoadTextureFromImage(img);
//Get Data for Serialization
- Color[] colors = new Color[Width*Height];
- int i = 0;
- for (int x = 0; x < Width; x++) {
- for (int y = 0; y < Height; y++) {
- colors[i] = Raylib.GetImageColor(img, x, y);
- i++;
- }
+ int imgSize = Raylib.GetPixelDataSize(img.Width, img.Height, PixelFormat.UncompressedR8G8B8A8);
+ Span<byte> imgData;
+ unsafe {
+ imgData = new(img.Data, imgSize);
}
+ using MemoryStream stream = new();
- byte[] data = new byte[(colors.Length*4) + (sizeof(short)*2)];
- BinaryPrimitives.WriteInt16LittleEndian(data.AsSpan(0, sizeof(short)), (short)Width);
- BinaryPrimitives.WriteInt16LittleEndian(data.AsSpan(sizeof(short), sizeof(short)), (short)Height);
- int position = sizeof(short)*2;
- for (int c = 0; c < colors.Length; c++) {
- data[position] = colors[c].R;
- data[position+1] = colors[c].G;
- data[position+2] = colors[c].B;
- data[position+3] = colors[c].A;
- position += 4;
- }
+ //Write width and height before compressed data
+ Span<byte> WidthHeight = stackalloc byte[4];
+ BinaryPrimitives.WriteInt16LittleEndian(WidthHeight, (short)Width);
+ BinaryPrimitives.WriteInt16LittleEndian(WidthHeight[2..], (short)Height);
+ stream.Write(WidthHeight);
- using MemoryStream stream = new();
using DeflateStream compressor = new(stream, CompressionLevel.Optimal);
- compressor.Write(data);
+ compressor.Write(imgData);
compressor.Close();
SerializedData = stream.ToArray();
Raylib.UnloadImage(img);
}
- Bitmap(Image img, byte[] serializedData)
+ Bitmap(Texture2D tex, byte[] serializedData)
{
- Width = img.Width;
- Height = img.Height;
SerializedData = serializedData;
-
- Texture = Raylib.LoadTextureFromImage(img);
- Raylib.UnloadImage(img);
+ Texture = tex;
}
public static Bitmap FromFile(string path, int MaxW = MaxWidth, int MaxH = MaxHeight)
{
if (!File.Exists(path) || new FileInfo(path).Length > 40000 || !path.Contains(".png"))
- return new Bitmap(Raylib.GenImageChecked(32, 32, 4, 4, Color.Black, Color.Pink));
+ return new Bitmap(Raylib.GenImageChecked(32, 32, 4, 4, Color.Black, Color.Pink));
- byte[] memory = File.ReadAllBytes(path);
- return FromPNGMemory(memory, MaxW, MaxH);
+ return new Bitmap(Raylib.LoadImage(path), MaxW, MaxH);
}
public static Bitmap FromPNGMemory(byte[] memory, int MaxW = MaxWidth, int MaxH = MaxHeight)
@@ -82,40 +68,33 @@ class Bitmap : IDisposable
public static Bitmap Deserialize(ReadOnlySpan<byte> span, int MaxW = MaxWidth, int MaxH = MaxHeight, byte[]? fallbackImage = null)
{
- byte[] compressed = span.ToArray();
- byte[] data;
+ int width = BinaryPrimitives.ReadInt16LittleEndian(span[..2]);
+ int height = BinaryPrimitives.ReadInt16LittleEndian(span.Slice(2, 2));
+
+ bool Invalid = width <=0 || height <= 0 || width > MaxW || height > MaxH;
+ width = Math.Clamp(width, 1, MaxW);
+ height = Math.Clamp(height, 1, MaxH);
+
+ //If the width and height are somehow wrong, then no use in loading the rest.
+ if (Invalid && fallbackImage != null) return FromPNGMemory(fallbackImage, MaxW, MaxH);
+ Image img = Raylib.GenImageChecked(width, height, 4, 4, Color.Pink, Color.Black);
+ Raylib.ImageFormat(ref img, PixelFormat.UncompressedR8G8B8A8);
+ if (Invalid) return new Bitmap(img);
+
+ byte[] compressed = span[4..].ToArray();
+ byte[] data = new byte[Raylib.GetPixelDataSize(width, height, PixelFormat.UncompressedR8G8B8A8)];
{
using MemoryStream input = new(compressed);
- using MemoryStream output = new();
using DeflateStream decompressor = new(input, CompressionMode.Decompress);
- decompressor.CopyTo(output);
- data = output.ToArray();
+ decompressor.ReadExactly(data);
}
- int width = BinaryPrimitives.ReadInt16LittleEndian(data.AsSpan(0, sizeof(short)));
- int height = BinaryPrimitives.ReadInt16LittleEndian(data.AsSpan(sizeof(short), sizeof(short)));
+ Texture2D tex = Raylib.LoadTextureFromImage(img);
+ Raylib.UpdateTexture(tex, data);
- bool TooBig = width > MaxW || height > MaxH;
- if (TooBig) {
- width = Math.Clamp(width, 0, MaxW);
- height = Math.Clamp(height, 0, MaxH);
- if (fallbackImage != null) return FromPNGMemory(fallbackImage, MaxW, MaxH);
- }
-
- Image img = Raylib.GenImageChecked(width, height, 4, 4, Color.Pink, Color.Black);
-
- if (TooBig) return new Bitmap(img);
-
- int i = sizeof(short)*2;
- for (int x = 0; x < width; x++) {
- for (int y = 0; y < height; y++) {
- Color color = new(data[i], data[i+1], data[i+2], data[i+3]);
- Raylib.ImageDrawPixel(ref img, x, y, color);
- i += 4;
- }
- }
+ Raylib.UnloadImage(img);
- return new Bitmap(img, compressed);
+ return new Bitmap(tex, compressed);
}
public byte[] Serialize()
diff --git a/OnekoOnline.csproj b/OnekoOnline.csproj
index 2e9f999..c0eb221 100644
--- a/OnekoOnline.csproj
+++ b/OnekoOnline.csproj
@@ -4,17 +4,18 @@
<OutputType>Exe</OutputType>
- <TargetFramework>net8.0</TargetFramework>
+ <TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>true</PublishAot>
<StripSymbols>true</StripSymbols>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
- <PackageReference Include="LiteNetLib" Version="1.2.0" />
- <PackageReference Include="Raylib-cs" Version="6.0.0" />
+ <PackageReference Include="LiteNetLib" Version="1.3.1" />
+ <PackageReference Include="Raylib-cs" Version="7.0.1" />
<EmbeddedResource Include="nekos\oneko.png" />
<EmbeddedResource Include="misc\cursor.png" />