Move native calls to Stb.Native

This commit is contained in:
H. Utku Maden 2024-06-19 11:31:51 +03:00
parent e7d7f5f826
commit 9b21bb837b
6 changed files with 62 additions and 12 deletions

@ -1,3 +1,4 @@
using ReFuel.Stb.Native;
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;

@ -1,14 +1,16 @@
using System;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Reflection;
namespace ReFuel.Stb
namespace ReFuel.Stb.Native
{
/// <summary>
/// Direct access to the native STBI function calls.
/// </summary>
public unsafe static partial class Stbi
{
private delegate void FailedAssertProc(byte *expression, byte *file, int line, byte *function);
private static IntPtr stbiHandle;
private static readonly string[] LibraryNames = new string[]
{
@ -29,22 +31,33 @@ namespace ReFuel.Stb
static Stbi()
{
NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), Resolver);
// Dummy call to fail_reason so we have a handle to STBI.
failure_reason();
// Load global address pointers.
_tga_with_rle_ptr = (int*)NativeLibrary.GetExport(stbiHandle, "stbi_write_tga_with_rle");
_png_compression_level_ptr = (int*)NativeLibrary.GetExport(stbiHandle, "stbi_write_png_compression_level");
_force_png_filter_ptr = (int*)NativeLibrary.GetExport(stbiHandle, "stbi_write_force_png_filter");
}
private static IntPtr Resolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
{
if (libraryName != "stbi")
return IntPtr.Zero;
else if (stbiHandle != IntPtr.Zero)
return stbiHandle;
foreach (string name in LibraryNames)
{
if (NativeLibrary.TryLoad(name, assembly, searchPath, out IntPtr handle))
if (NativeLibrary.TryLoad(name, assembly, searchPath, out stbiHandle))
{
return handle;
return stbiHandle;
}
}
return NativeLibrary.Load(libraryName);
return stbiHandle = NativeLibrary.Load(libraryName);
}
}
}

@ -1,7 +1,7 @@
using System;
using System.Runtime.InteropServices;
namespace ReFuel.Stb
namespace ReFuel.Stb.Native
{
public enum StbiEnum : uint
{

@ -1,5 +1,10 @@
using ReFuel.Stb.Native;
namespace ReFuel.Stb
{
/// <summary>
/// Enumeration of supported STBI image formats.
/// </summary>
public enum StbiImageFormat
{
Default = (int)StbiEnum.STBI_default,

@ -1,13 +1,34 @@
using ReFuel.Stb.Native;
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace ReFuel.Stb
{
/// <summary>
/// Pointer to STBI stream read function.
/// </summary>
/// <param name="userdata">User provided userdata pointer.</param>
/// <param name="buffer">C array to read into.</param>
/// <param name="count">Size of the C array in bytes.</param>
/// <returns>The number of bytes read from the stream.</returns>
public unsafe delegate int StbiReadProc(void *userdata, byte* buffer, int count);
/// <summary>
/// Pointer to STBI stream skip function.
/// </summary>
/// <param name="userdata">User provided userdata pointer.</param>
/// <param name="count">Number of bytes to skip.</param>
public unsafe delegate void StbiSkipProc(void *userdata, int count);
/// <summary>
/// Pointer to STBI stream end of file function.
/// </summary>
/// <param name="userdata">User provided userdata pointer.</param>
/// <returns>Non-zero value if the end of the stream has been reached.</returns>
public unsafe delegate int StbiEofProc(void *userdata);
/// <summary>
/// An easy to use stream wrapper for use with STBI image load functions.
/// </summary>
public unsafe class StbiStreamWrapper : IDisposable
{
private readonly stbi_io_callbacks _callbacks;
@ -74,7 +95,11 @@ namespace ReFuel.Stb
}
}
internal struct StbiWriteStreamWrapper
/// <summary>
/// An easy to use stream wrapper for STBI image write functions.
/// </summary>
/// <remarks>Keep struct alive for the duration of the write operation.</remarks>
public struct StbiWriteStreamWrapper
{
private readonly Stream _stream;
private readonly StbiWriteProc _cb;

@ -1,15 +1,21 @@
using System;
using System.Runtime.InteropServices;
namespace ReFuel.Stb
namespace ReFuel.Stb.Native
{
/// <summary>
/// Procedure to STBI image write function.
/// </summary>
/// <param name="context">User provided context pointer.</param>
/// <param name="data">C Array of data to write.</param>
/// <param name="size">Size of the C array in bytes.</param>
public unsafe delegate void StbiWriteProc(void* context, void* data, int size);
public unsafe partial class Stbi
{
private static readonly int* _tga_with_rle_ptr;
private static readonly int* _png_compression_level_ptr;
private static readonly int* _forced_png_filter_ptr;
private static readonly int* _force_png_filter_ptr;
public static int write_tga_with_rle
{
@ -25,8 +31,8 @@ namespace ReFuel.Stb
public static int write_force_png_filter
{
get => *_forced_png_filter_ptr;
set => *_forced_png_filter_ptr = value;
get => *_force_png_filter_ptr;
set => *_force_png_filter_ptr = value;
}
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_write_png_to_func")]