From 2132a7113d058f98ab84791fd1d26b243322d9a1 Mon Sep 17 00:00:00 2001
From: ds5678 <49847914+ds5678@users.noreply.github.com>
Date: Mon, 13 Jan 2025 17:25:38 -0800
Subject: [PATCH] Use StbImageWriteSharp instead of System.Drawing.Common *
Resolves #1631
---
...AssetRipper.Export.Modules.Textures.csproj | 1 -
.../DirectBitmap.cs | 4 +-
.../DirectBitmap`1.cs | 77 +++++--------------
.../EmptyDirectBitmap.cs | 2 +
4 files changed, 23 insertions(+), 61 deletions(-)
diff --git a/Source/AssetRipper.Export.Modules.Textures/AssetRipper.Export.Modules.Textures.csproj b/Source/AssetRipper.Export.Modules.Textures/AssetRipper.Export.Modules.Textures.csproj
index ec41b7a90..385913e40 100644
--- a/Source/AssetRipper.Export.Modules.Textures/AssetRipper.Export.Modules.Textures.csproj
+++ b/Source/AssetRipper.Export.Modules.Textures/AssetRipper.Export.Modules.Textures.csproj
@@ -19,7 +19,6 @@
-
diff --git a/Source/AssetRipper.Export.Modules.Textures/DirectBitmap.cs b/Source/AssetRipper.Export.Modules.Textures/DirectBitmap.cs
index d8a4e67cd..ee2680fbe 100644
--- a/Source/AssetRipper.Export.Modules.Textures/DirectBitmap.cs
+++ b/Source/AssetRipper.Export.Modules.Textures/DirectBitmap.cs
@@ -19,7 +19,7 @@ public abstract class DirectBitmap
ArgumentOutOfRangeException.ThrowIfNegative(height);
ArgumentOutOfRangeException.ThrowIfNegative(depth);
long byteSize = CalculateByteSize(width, height, depth, PixelSize);
- ArgumentOutOfRangeException.ThrowIfGreaterThan(byteSize, int.MaxValue);
+ ArgumentOutOfRangeException.ThrowIfGreaterThan(byteSize, Array.MaxLength);
Width = width;
Height = height;
Depth = depth;
@@ -47,6 +47,8 @@ public abstract class DirectBitmap
}
}
+ public abstract DirectBitmap GetLayer(int layer);
+
public abstract void FlipX();
public abstract void FlipY();
diff --git a/Source/AssetRipper.Export.Modules.Textures/DirectBitmap`1.cs b/Source/AssetRipper.Export.Modules.Textures/DirectBitmap`1.cs
index dcb9fcf85..4312d0001 100644
--- a/Source/AssetRipper.Export.Modules.Textures/DirectBitmap`1.cs
+++ b/Source/AssetRipper.Export.Modules.Textures/DirectBitmap`1.cs
@@ -2,11 +2,8 @@ using AssetRipper.TextureDecoder.Exr;
using AssetRipper.TextureDecoder.Rgb;
using AssetRipper.TextureDecoder.Rgb.Formats;
using StbImageWriteSharp;
-using System.Drawing;
-using System.Drawing.Imaging;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-using System.Runtime.Versioning;
namespace AssetRipper.Export.Modules.Textures;
@@ -28,6 +25,18 @@ public sealed class DirectBitmap : DirectBitmap
{
}
+ public override DirectBitmap GetLayer(int layer)
+ {
+ ArgumentOutOfRangeException.ThrowIfNegative(layer);
+ ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(layer, Depth);
+
+ int layerSize = Width * Height;
+ byte[] layerData = new byte[layerSize * PixelSize];
+ Buffer.BlockCopy(Data, layer * layerSize * PixelSize, layerData, 0, layerSize * PixelSize);
+
+ return new DirectBitmap(Width, Height, 1, layerData);
+ }
+
public override void FlipX()
{
int totalRows = Height * Depth;
@@ -89,10 +98,6 @@ public sealed class DirectBitmap : DirectBitmap
{
BmpWriter.WriteBmp(Data, Width, Height * Depth, stream);
}
- else if (OperatingSystem.IsWindows())
- {
- SaveUsingSystemDrawing(stream, ImageFormat.Bmp);
- }
else
{
GetDataAndComponentsForSaving(out byte[] data, out ColorComponents components);
@@ -119,33 +124,19 @@ public sealed class DirectBitmap : DirectBitmap
public override void SaveAsJpeg(Stream stream)
{
- if (OperatingSystem.IsWindows())
+ GetDataAndComponentsForSaving(out byte[] data, out ColorComponents components);
+ lock (imageWriter)
{
- SaveUsingSystemDrawing(stream, ImageFormat.Jpeg);
- }
- else
- {
- GetDataAndComponentsForSaving(out byte[] data, out ColorComponents components);
- lock (imageWriter)
- {
- imageWriter.WriteJpg(data, Width, Height * Depth, components, stream, default);
- }
+ imageWriter.WriteJpg(data, Width, Height * Depth, components, stream, default);
}
}
public override void SaveAsPng(Stream stream)
{
- if (OperatingSystem.IsWindows())
+ GetDataAndComponentsForSaving(out byte[] data, out ColorComponents components);
+ lock (imageWriter)
{
- SaveUsingSystemDrawing(stream, ImageFormat.Png);
- }
- else
- {
- GetDataAndComponentsForSaving(out byte[] data, out ColorComponents components);
- lock (imageWriter)
- {
- imageWriter.WritePng(data, Width, Height * Depth, components, stream);
- }
+ imageWriter.WritePng(data, Width, Height * Depth, components, stream);
}
}
@@ -181,36 +172,4 @@ public sealed class DirectBitmap : DirectBitmap
components = ColorComponents.RedGreenBlue;
}
}
-
- [SupportedOSPlatform("windows")]
- private void SaveUsingSystemDrawing(Stream stream, ImageFormat format)
- {
- GetData(this, out byte[] data, out int pixelSize, out PixelFormat pixelFormat);
- GCHandle bitsHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
- try
- {
- using Bitmap bitmap = new Bitmap(Width, Height * Depth, Width * pixelSize, pixelFormat, bitsHandle.AddrOfPinnedObject());
- bitmap.Save(stream, format);
- }
- finally
- {
- bitsHandle.Free();
- }
-
- static void GetData(DirectBitmap @this, out byte[] data, out int pixelSize, out PixelFormat pixelFormat)
- {
- if (typeof(TColor) == typeof(ColorBGRA32))
- {
- data = @this.Data;
- pixelSize = 4;
- pixelFormat = PixelFormat.Format32bppArgb;
- }
- else
- {
- RgbConverter.Convert(@this.Bits, @this.Width, @this.Height * @this.Depth, out data);
- pixelSize = 4;
- pixelFormat = PixelFormat.Format32bppArgb;
- }
- }
- }
}
diff --git a/Source/AssetRipper.Export.Modules.Textures/EmptyDirectBitmap.cs b/Source/AssetRipper.Export.Modules.Textures/EmptyDirectBitmap.cs
index d8cb4e091..bb49d9eb9 100644
--- a/Source/AssetRipper.Export.Modules.Textures/EmptyDirectBitmap.cs
+++ b/Source/AssetRipper.Export.Modules.Textures/EmptyDirectBitmap.cs
@@ -10,6 +10,8 @@ internal sealed class EmptyDirectBitmap : DirectBitmap
public override int PixelSize => 0;
+ public override EmptyDirectBitmap GetLayer(int layer) => this;
+
public override void FlipX()
{
}