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() { }