16 Commits

Author SHA1 Message Date
themixedupstuff 7bbb738199 Remove the artifact which doesn't work. 2026-05-29 20:50:31 +03:00
themixedupstuff 89d6b5f236 Syntax 2026-05-29 20:12:01 +03:00
themixedupstuff 8621e10a73 ADd project packing to the build native script. 2026-05-29 20:02:54 +03:00
themixedupstuff e18001f926 Add optional version suffix. 2026-05-29 19:52:42 +03:00
themixedupstuff 80e696d24a Add $PWD because something changed in the way nuget evaluates cmdline args. 2026-05-29 19:45:39 +03:00
themixedupstuff a9eacca2ff Don't forget the action version. 2026-05-29 19:37:02 +03:00
themixedupstuff 2a0622af8d Fix build.yaml syntax. 2026-05-29 19:35:27 +03:00
themixedupstuff 774cfb5c21 Add artifact upload to the build script (useful for nuget.org) 2026-05-29 19:34:25 +03:00
themixedupstuff 2f54c0408a Create new redistributable packages. 2026-05-29 19:28:07 +03:00
themixedupstuff f0bb106e41 Update all submodules to the latest version. 2026-05-19 13:56:23 +03:00
themixedupstuff 432446689c Fix typo in build_native.sh 2026-04-14 23:30:46 +03:00
themixedupstuff 1afdc8ffb9 Update build scripts. 2026-04-14 23:27:05 +03:00
themixedupstuff 2f418866a4 Create a small demo application for StbImage. 2026-04-04 12:31:38 +03:00
themixedupstuff 776719648e Moved ReFuel.StbImage into its own subfolder. 2026-04-01 23:28:15 +03:00
themixedupstuff b7983c96b2 [v2.1.0] Bump version number.
Build / build (push) Successful in 1m58s
2024-11-18 20:55:49 +03:00
themixedupstuff cb75b7c244 Made Callbacks a public field in StbiStreamWrapper.cs
Build / build (push) Successful in 1m55s
2024-11-18 20:47:28 +03:00
28 changed files with 497 additions and 133 deletions
+7
View File
@@ -2,6 +2,12 @@ name: Build
run-name: Building with docker container.
on:
workflow_dispatch:
inputs:
version_suffix:
description: "Optional version suffix."
required: false
type: string
default: -rc.1
push:
tags:
- '*'
@@ -15,6 +21,7 @@ jobs:
REFUEL_API_KEY: "${{secrets.REFUEL_API_KEY}}"
NUGET_USER_NAME: "${{vars.NUGET_USER_NAME}}"
NUGET_INDEX: "${{vars.NUGET_INDEX}}"
VersionSuffix: "${{inputs.version_suffix}}"
volumes:
- ${{ gitea.workspace }}:/home/refuel/src
steps:
+2
View File
@@ -1,6 +1,8 @@
[submodule "stb"]
path = stb
url = https://github.com/nothings/stb.git
branch = master
[submodule "docker-cross-compiler"]
path = docker-cross-compiler
url = https://git.mixedup.dev/ReFuel/docker-cross-compiler
branch = stable
+1 -1
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.5)
project(rf_stbi LANGUAGES C VERSION 1.0)
+209
View File
@@ -0,0 +1,209 @@
/*
* ReFuel.StbImage.Viewer - A simple image viewer demo for ReFuel.StbImage.
* ------------------------------------------------------------------------
*
* Pass an image file as path (or drag and drop over the executable or window) to view
* of the file formats stb_image supports. Otherwise the default embedded image will be
* shown.
*
* The demo uses OpenGL2.1 for brevity sake - I did not feel like writing a shader program
* for this demo. It is very easy to port this demo to modern OpenGL if desired. Just
* replace the FFP calls with the equivalent programmable pipeline calls (glVertexAttribPointer,
* glUseShader and its friends).
*/
using System.Reflection;
using System.Runtime.InteropServices;
using OpenTK.Graphics.OpenGL;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
using OpenTK.Windowing.Desktop;
using ReFuel.Stb;
NativeWindow window = new NativeWindow(new NativeWindowSettings()
{
Profile = ContextProfile.Any,
APIVersion = new Version(2, 1),
Title = "ReFuel StbImage Viewer",
AutoLoadBindings = true,
Flags = ContextFlags.Default,
});
bool quit = false;
int texture = 0;
int imageWidth = 0, imageHeight = 0;
// This flag is important for OpenGL users, as texture coordinate systems
// are the opposite of what most image formats use. Y is up not down.
// Does not matter for DX, for example.
StbImage.FlipVerticallyOnLoad = true;
Vertex[] vertices = new Vertex[]
{
new Vertex(-1, -1, 0, 0),
new Vertex(1, -1, 1, 0),
new Vertex(1, 1, 1, 1),
new Vertex(-1, -1, 0, 0),
new Vertex(1, 1, 1, 1),
new Vertex(-1, 1, 0, 1),
};
LoadImage(args.Length > 0 ? args[0] : null);
GL.ClearColor(Color4.Black);
GL.Enable(EnableCap.Texture2D);
GL.Enable(EnableCap.Blend);
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); // conventional blending function.
GL.EnableClientState(ArrayCap.VertexArray);
GL.EnableClientState(ArrayCap.TextureCoordArray);
GL.EnableClientState(ArrayCap.ColorArray);
window.Closing += (_) => quit = true;
window.FramebufferResize += (_) => {
ResizeImage();
Paint();
};
window.FileDrop += (args) =>
LoadImage(
args.FileNames
.Select(x => new FileInfo(x))
.FirstOrDefault(x => x.Exists)?.FullName);
window.WindowState = WindowState.Normal;
while (!quit)
{
NativeWindow.ProcessWindowEvents(true);
Paint();
};
void Paint()
{
GL.Clear(ClearBufferMask.ColorBufferBit);
GL.Viewport(0, 0, window.FramebufferSize.X, window.FramebufferSize.Y);
GL.BindTexture(TextureTarget.Texture2D, texture);
unsafe
{
fixed (Vertex* pvert = vertices)
{
// We have to do it this way because the garbage collector may
// move the vertex data at any time. The OpenGL client will
// handle streaming the data at the glDrawArrays call, unlike
// the modern method.
GL.VertexPointer(2, VertexPointerType.Float, 32, (nint)(&pvert->X));
GL.TexCoordPointer(2, TexCoordPointerType.Float, 32, (nint)(&pvert->U));
GL.ColorPointer(4, ColorPointerType.Float, 32, (nint)(&pvert->Color));
GL.DrawArrays(PrimitiveType.Triangles, 0, vertices.Length);
}
}
window.Context.SwapBuffers();
}
void ResizeImage()
{
// Regenerates the vertex positions to maintain the aspect ratio and fill the window.
float windowAspect = (float)window.FramebufferSize.X / window.FramebufferSize.Y;
float imageAspect = (float)imageWidth / imageHeight;
float ratio = imageAspect / windowAspect;
float widthNDC, heightNDC;
if (ratio > 1)
{
widthNDC = 2.0f;
heightNDC = 2.0f / ratio;
}
else
{
heightNDC = 2.0f;
widthNDC = 2.0f * ratio;
}
vertices[0].X = -widthNDC / 2; vertices[0].Y = -heightNDC / 2;
vertices[1].X = widthNDC / 2; vertices[1].Y = -heightNDC / 2;
vertices[2].X = widthNDC / 2; vertices[2].Y = heightNDC / 2;
vertices[3].X = -widthNDC / 2; vertices[3].Y = -heightNDC / 2;
vertices[4].X = widthNDC / 2; vertices[4].Y = heightNDC / 2;
vertices[5].X = -widthNDC / 2; vertices[5].Y = heightNDC / 2;
}
void LoadImage(string? path)
{
// Load the given image, or the default if the path is null, or any other error happens.
StbImage? image = null;
if (path != null && File.Exists(path))
{
try
{
using Stream str = File.OpenRead(path);
StbImage.TryLoad(out image, str);
}
catch
{
// Ignore
}
}
if (image == null)
{
using Stream str = Assembly.GetExecutingAssembly().GetManifestResourceStream("default.png")!;
image = StbImage.Load(str);
}
// Boilerplate code for creating a new OpenGL texture.
GL.DeleteTexture(texture);
texture = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, texture);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, image.Width, image.Height, 0, image.Format switch
{
StbiImageFormat.Grey => PixelFormat.Red,
StbiImageFormat.GreyAlpha => PixelFormat.Rg,
StbiImageFormat.Rgb => PixelFormat.Rgb,
StbiImageFormat.Rgba => PixelFormat.Rgba,
_ => throw new Exception()
}, image.IsFloat ? PixelType.Float : PixelType.UnsignedByte, image.ImagePointer);
// Generate mipmaps for better minification.
GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
// Enable them.
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
// Set texture wrap mode to clamp to border to prevent bleeding on the image edges.
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToBorder);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToBorder);
// For R or RA format images, we need to set the swizzle mask.
switch (image.Format)
{
case StbiImageFormat.Grey:
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleR, (int)TextureSwizzle.Red);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleG, (int)TextureSwizzle.Red);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleB, (int)TextureSwizzle.Red);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleA, (int)TextureSwizzle.One);
break;
case StbiImageFormat.GreyAlpha:
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleR, (int)TextureSwizzle.Red);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleG, (int)TextureSwizzle.Red);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleA, (int)TextureSwizzle.Green);
// Yes the last channel is green, we uploaded the texture with the Rg color format.
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleB, (int)TextureSwizzle.Red);
break;
}
imageWidth = image.Width;
imageHeight = image.Height;
ResizeImage();
image.Dispose();
}
// Vertex struct for convenience. Padded to 32 bytes for memory alignment.
[StructLayout(LayoutKind.Sequential, Size = 32)]
struct Vertex(float x, float y, float u, float v)
{
public float X = x, Y = y, U = u, V = v;
public Color4 Color = Color4.White;
}
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ReFuel.StbImage" Version="2.1.0"/>
<PackageReference Include="OpenTK" Version="4.9.4" />
<EmbeddedResource Include="../rf_stbimage.png" LogicalName="default.png"/>
</ItemGroup>
</Project>
-93
View File
@@ -1,93 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<RuntimeIdentifiers>linux-arm;linux-arm64;linux-x64;win-x86;win-x64;osx-arm64;osx-x64</RuntimeIdentifiers>
<RootNamespace>ReFuel.Stb</RootNamespace>
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup>
<!-- Nuget Properties. -->
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageId>ReFuel.StbImage</PackageId>
<Version>2.0.2-rc.1</Version>
<Authors>STBI Authors, H. Utku Maden</Authors>
<Description>
A C# wrapper for the ubiquitous stb_image.h and stb_image_write.h library.
</Description>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
<PackageIcon>images\icon.png</PackageIcon>
<PackageProjectUrl>https://refuel.mixedup.dev/docs/ReFuel.StbImage.html</PackageProjectUrl>
<RepositoryUrl>https://git.mixedup.dev/ReFuel/ReFuel.StbImage</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>stb; stb_image; stbi; image; load; save; read; write</PackageTags>
<PackageReleaseNotes># 2.0.2
* Fixed calling convention of unmanaged function pointers. (Thanks NogginBops!)
* Allocating a GC handle to StbiStreamWrapper class and passing it as userdata into stbi in order to prevent
the object from being prematurely collected by the garbage collector when optimizations are enabled in Release mode.
# 2.0.1
* Enabled optimizations across the board for native and managed assemblies.
# 2.0.0
* Exposed stbi_image_write.h
* Moved native function calls to ReFuel.Stb.Native</PackageReleaseNotes>
</PropertyGroup>
<!--
Because the .net build system is garbage of the purest quality, I need
to specify each runtime directory by itself or it won't be picked up as a
native specific to each platform and won't be included in the deps.json file
that determines a lot of load paths for projects.
-->
<ItemGroup>
<Content Include="*.md" Pack="true" PackagePath="/" />
<None Include="rf_stbimage.png" Pack="true" PackagePath="images\icon.png" />
<Content Include="runtimes/linux-arm/native/*.so">
<PackagePath>runtimes/linux-arm/native/</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="runtimes/linux-arm64/native/*.so">
<PackagePath>runtimes/linux-arm64/native/</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory>PreserveNewest/</CopyToOutputDirectory>
</Content>
<Content Include="runtimes/linux-x64/native/*.so">
<PackagePath>runtimes/linux-x64/native/</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="runtimes/linux-x86/native/*.so">
<PackagePath>runtimes/linux-x86/native/</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="runtimes/win-x64/native/*.dll">
<PackagePath>runtimes/win-x64/native/</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="runtimes/win-x86/native/*.dll">
<PackagePath>runtimes/win-x86/native/</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="runtimes/osx-x64/native/*.dylib">
<PackagePath>runtimes/osx-x64/native/</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="runtimes/osx-arm64/native/*.dylib">
<PackagePath>runtimes/osx-arm64/native/</PackagePath>
<Pack>true</Pack>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../etc/ReFuel.StbImage.Common.props"/>
<PropertyGroup>
<!-- Nuget Properties. -->
<Version>1.0.0$(VersionSuffix)</Version>
<PackageReleaseNotes>* Initial release.</PackageReleaseNotes>
<NoBuild>true</NoBuild>
<IncludeBuildOutput>false</IncludeBuildOutput>
<NuspecFile>../etc/native.nuspec</NuspecFile>
<NuspecProperties>version=$(Version);rid=linux-arm;dllname=libstbi.so</NuspecProperties>
</PropertyGroup>
</Project>
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../etc/ReFuel.StbImage.Common.props"/>
<PropertyGroup>
<!-- Nuget Properties. -->
<Version>1.0.0$(VersionSuffix)</Version>
<PackageReleaseNotes>* Initial release.</PackageReleaseNotes>
<NoBuild>true</NoBuild>
<IncludeBuildOutput>false</IncludeBuildOutput>
<NuspecFile>../etc/native.nuspec</NuspecFile>
<NuspecProperties>version=$(Version);rid=linux-arm64;dllname=libstbi.so</NuspecProperties>
</PropertyGroup>
</Project>
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../etc/ReFuel.StbImage.Common.props"/>
<PropertyGroup>
<!-- Nuget Properties. -->
<Version>1.0.0$(VersionSuffix)</Version>
<PackageReleaseNotes>* Initial release.</PackageReleaseNotes>
<NoBuild>true</NoBuild>
<IncludeBuildOutput>false</IncludeBuildOutput>
<NuspecFile>../etc/native.nuspec</NuspecFile>
<NuspecProperties>version=$(Version);rid=linux-x64;dllname=libstbi.so</NuspecProperties>
</PropertyGroup>
</Project>
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../etc/ReFuel.StbImage.Common.props"/>
<PropertyGroup>
<!-- Nuget Properties. -->
<Version>1.0.0$(VersionSuffix)</Version>
<PackageReleaseNotes>* Initial release.</PackageReleaseNotes>
<NoBuild>true</NoBuild>
<IncludeBuildOutput>false</IncludeBuildOutput>
<NuspecFile>../etc/native.nuspec</NuspecFile>
<NuspecProperties>version=$(Version);rid=osx-arm64;dllname=libstbi.dylib</NuspecProperties>
</PropertyGroup>
</Project>
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../etc/ReFuel.StbImage.Common.props"/>
<PropertyGroup>
<!-- Nuget Properties. -->
<Version>1.0.0$(VersionSuffix)</Version>
<PackageReleaseNotes>* Initial release.</PackageReleaseNotes>
<NoBuild>true</NoBuild>
<IncludeBuildOutput>false</IncludeBuildOutput>
<NuspecFile>../etc/native.nuspec</NuspecFile>
<NuspecProperties>version=$(Version);rid=osx-x64;dllname=libstbi.dylib</NuspecProperties>
</PropertyGroup>
</Project>
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../etc/ReFuel.StbImage.Common.props"/>
<PropertyGroup>
<!-- Nuget Properties. -->
<Version>1.0.0$(VersionSuffix)</Version>
<PackageReleaseNotes>* Initial release.</PackageReleaseNotes>
<NoBuild>true</NoBuild>
<IncludeBuildOutput>false</IncludeBuildOutput>
<NuspecFile>../etc/native.nuspec</NuspecFile>
<NuspecProperties>version=$(Version);rid=win-x64;dllname=libstbi.dll</NuspecProperties>
</PropertyGroup>
</Project>
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../etc/ReFuel.StbImage.Common.props"/>
<PropertyGroup>
<!-- Nuget Properties. -->
<Version>1.0.0$(VersionSuffix)</Version>
<PackageReleaseNotes>* Initial release.</PackageReleaseNotes>
<NoBuild>true</NoBuild>
<IncludeBuildOutput>false</IncludeBuildOutput>
<NuspecFile>../etc/native.nuspec</NuspecFile>
<NuspecProperties>version=$(Version);rid=win-x86;dllname=libstbi.dll</NuspecProperties>
</PropertyGroup>
</Project>
+33 -7
View File
@@ -3,20 +3,46 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReFuel.StbImage", "ReFuel.StbImage.csproj", "{413ACBF4-3851-416F-B2A2-F7157EC306B2}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReFuel.StbImage", "ReFuel.StbImage\ReFuel.StbImage.csproj", "{EB001CC8-6821-4579-BD5D-27C56A3C121E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReFuel.StbImage.Viewer", "ReFuel.StbImage.Viewer\ReFuel.StbImage.Viewer.csproj", "{4CFB8D5B-8CE9-46EE-A34B-0D61693BDE50}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EB001CC8-6821-4579-BD5D-27C56A3C121E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EB001CC8-6821-4579-BD5D-27C56A3C121E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EB001CC8-6821-4579-BD5D-27C56A3C121E}.Debug|x64.ActiveCfg = Debug|Any CPU
{EB001CC8-6821-4579-BD5D-27C56A3C121E}.Debug|x64.Build.0 = Debug|Any CPU
{EB001CC8-6821-4579-BD5D-27C56A3C121E}.Debug|x86.ActiveCfg = Debug|Any CPU
{EB001CC8-6821-4579-BD5D-27C56A3C121E}.Debug|x86.Build.0 = Debug|Any CPU
{EB001CC8-6821-4579-BD5D-27C56A3C121E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EB001CC8-6821-4579-BD5D-27C56A3C121E}.Release|Any CPU.Build.0 = Release|Any CPU
{EB001CC8-6821-4579-BD5D-27C56A3C121E}.Release|x64.ActiveCfg = Release|Any CPU
{EB001CC8-6821-4579-BD5D-27C56A3C121E}.Release|x64.Build.0 = Release|Any CPU
{EB001CC8-6821-4579-BD5D-27C56A3C121E}.Release|x86.ActiveCfg = Release|Any CPU
{EB001CC8-6821-4579-BD5D-27C56A3C121E}.Release|x86.Build.0 = Release|Any CPU
{4CFB8D5B-8CE9-46EE-A34B-0D61693BDE50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4CFB8D5B-8CE9-46EE-A34B-0D61693BDE50}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4CFB8D5B-8CE9-46EE-A34B-0D61693BDE50}.Debug|x64.ActiveCfg = Debug|Any CPU
{4CFB8D5B-8CE9-46EE-A34B-0D61693BDE50}.Debug|x64.Build.0 = Debug|Any CPU
{4CFB8D5B-8CE9-46EE-A34B-0D61693BDE50}.Debug|x86.ActiveCfg = Debug|Any CPU
{4CFB8D5B-8CE9-46EE-A34B-0D61693BDE50}.Debug|x86.Build.0 = Debug|Any CPU
{4CFB8D5B-8CE9-46EE-A34B-0D61693BDE50}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4CFB8D5B-8CE9-46EE-A34B-0D61693BDE50}.Release|Any CPU.Build.0 = Release|Any CPU
{4CFB8D5B-8CE9-46EE-A34B-0D61693BDE50}.Release|x64.ActiveCfg = Release|Any CPU
{4CFB8D5B-8CE9-46EE-A34B-0D61693BDE50}.Release|x64.Build.0 = Release|Any CPU
{4CFB8D5B-8CE9-46EE-A34B-0D61693BDE50}.Release|x86.ActiveCfg = Release|Any CPU
{4CFB8D5B-8CE9-46EE-A34B-0D61693BDE50}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{413ACBF4-3851-416F-B2A2-F7157EC306B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{413ACBF4-3851-416F-B2A2-F7157EC306B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{413ACBF4-3851-416F-B2A2-F7157EC306B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{413ACBF4-3851-416F-B2A2-F7157EC306B2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
+43
View File
@@ -0,0 +1,43 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../etc/ReFuel.StbImage.Common.props"/>
<PropertyGroup>
<!-- <TargetFrameworks>net6.0;net8.0;net10.0</TargetFrameworks> -->
<RuntimeIdentifiers>linux-arm;linux-arm64;linux-x64;win-x86;win-x64;osx-arm64;osx-x64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup>
<!-- Nuget Properties. -->
<PackageId>ReFuel.StbImage</PackageId>
<Version>2.1.1$(VersionSuffix)</Version>
<Description>
A C# wrapper for the ubiquitous stb_image.h and stb_image_write.h library.
</Description>
<PackageReleaseNotes>
# 2.1.1
* Move redistributables to their own packages which can be updated incrementally as required.
# 2.1.0 (ABI BRAKING)
* Fixed calling convention of unmanaged function pointers. (Thanks NogginBops!)
* Modified StbiStreamWrapper in order to fixed backing delegates of function pointers from being prematurely collected
by release mode JIT and the GC. StbiStreamWrapper.Callbacks is now a readonly field. (ABI BREAKING)
# 2.0.1
* Enabled optimizations across the board for native and managed assemblies.
# 2.0.0
* Exposed stbi_image_write.h
* Moved native function calls to ReFuel.Stb.Native</PackageReleaseNotes>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ReFuel.StbImage.redis.linux-arm" Version="1.0.*"/>
<PackageReference Include="ReFuel.StbImage.redis.linux-arm64" Version="1.0.*"/>
<PackageReference Include="ReFuel.StbImage.redis.linux-x64" Version="1.0.*"/>
<PackageReference Include="ReFuel.StbImage.redis.osx-arm64" Version="1.0.*"/>
<PackageReference Include="ReFuel.StbImage.redis.osx-x64" Version="1.0.*"/>
<PackageReference Include="ReFuel.StbImage.redis.win-x64" Version="1.0.*"/>
<PackageReference Include="ReFuel.StbImage.redis.win-x86" Version="1.0.*"/>
</ItemGroup>
</Project>
+10 -8
View File
@@ -209,19 +209,19 @@ namespace ReFuel.Stb
{
int x, y, iFormat;
StbiStreamWrapper wrapper = new StbiStreamWrapper(stream, true);
GCHandle gch = GCHandle.Alloc(wrapper, GCHandleType.Normal);
wrapper.CreateCallbacks(out stbi_io_callbacks cb);
stream.Position = 0;
IntPtr imagePtr;
fixed (stbi_io_callbacks* cb = &wrapper.Callbacks)
{
if (asFloat)
{
imagePtr = (IntPtr)Stbi.loadf_from_callbacks(&cb, (void*)(IntPtr)gch, &x, &y, &iFormat, (int)format);
imagePtr = (IntPtr)Stbi.loadf_from_callbacks(cb, null, &x, &y, &iFormat, (int)format);
}
else
{
imagePtr = (IntPtr)Stbi.load_from_callbacks(&cb, (void*)(IntPtr)gch, &x, &y, &iFormat, (int)format);
imagePtr = (IntPtr)Stbi.load_from_callbacks(cb, null, &x, &y, &iFormat, (int)format);
}
}
gch.Free();
if (imagePtr != IntPtr.Zero)
{
@@ -319,10 +319,12 @@ namespace ReFuel.Stb
{
int x, y, iFormat;
StbiStreamWrapper wrapper = new StbiStreamWrapper(stream, true);
wrapper.CreateCallbacks(out stbi_io_callbacks cb);
int result;
stream.Position = 0;
int result = Stbi.info_from_callbacks(&cb, null, &x, &y, &iFormat);
fixed (stbi_io_callbacks* cb = &wrapper.Callbacks)
{
result = Stbi.info_from_callbacks(cb, null, &x, &y, &iFormat);
}
width = x;
height = y;
View File
@@ -32,11 +32,12 @@ namespace ReFuel.Stb
public unsafe delegate int StbiEofProc(void *userdata);
/// <summary>
/// An easy to use stream wrapper for use with STBI image load functions.
/// 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;
public readonly stbi_io_callbacks Callbacks;
private readonly Stream _stream;
private readonly bool _keepOpen;
private bool _isDisposed;
@@ -45,8 +46,6 @@ namespace ReFuel.Stb
private StbiSkipProc _skipCb;
private StbiEofProc _eofCb;
public ref readonly stbi_io_callbacks Callbacks => ref _callbacks;
public StbiStreamWrapper(Stream stream, bool keepOpen = false)
{
if (stream == null) throw new ArgumentNullException(nameof(stream));
@@ -58,18 +57,10 @@ namespace ReFuel.Stb
_skipCb = SkipCb;
_eofCb = EofCb;
_callbacks = default;
_callbacks.read = Marshal.GetFunctionPointerForDelegate<StbiReadProc>(_readCb);
_callbacks.skip = Marshal.GetFunctionPointerForDelegate<StbiSkipProc>(_skipCb);
_callbacks.eof = Marshal.GetFunctionPointerForDelegate<StbiEofProc>(_eofCb);
}
public void CreateCallbacks(out stbi_io_callbacks cb)
{
cb = default;
cb.read = Marshal.GetFunctionPointerForDelegate<StbiReadProc>(_readCb);
cb.skip = Marshal.GetFunctionPointerForDelegate<StbiSkipProc>(_skipCb);
cb.eof = Marshal.GetFunctionPointerForDelegate<StbiEofProc>(_eofCb);
Callbacks = default;
Callbacks.read = Marshal.GetFunctionPointerForDelegate<StbiReadProc>(_readCb);
Callbacks.skip = Marshal.GetFunctionPointerForDelegate<StbiSkipProc>(_skipCb);
Callbacks.eof = Marshal.GetFunctionPointerForDelegate<StbiEofProc>(_eofCb);
}
private int ReadCb(void *userdata, byte* buffer, int count)
View File
+16 -1
View File
@@ -1,4 +1,19 @@
#!/bin/bash
cd $(dirname "$0")
./docker-cross-compiler/sh/build_native.sh .
# Add the local directory as a .NET package source.
dotnet nuget add source -n ReFuel.StbImage $PWD/bin
# Build each architecture in its own subfolder.
DST=$PWD ./docker-cross-compiler/sh/build_native.sh $PWD linux-arm64
DST=$PWD ./docker-cross-compiler/sh/build_native.sh $PWD linux-arm
DST=$PWD ./docker-cross-compiler/sh/build_native.sh $PWD linux-x64
DST=$PWD ./docker-cross-compiler/sh/build_native.sh $PWD osx-arm64
DST=$PWD ./docker-cross-compiler/sh/build_native.sh $PWD osx-x64
DST=$PWD ./docker-cross-compiler/sh/build_native.sh $PWD win-x64
DST=$PWD ./docker-cross-compiler/sh/build_native.sh $PWD win-x86
for d in ReFuel.StbImage.redis*; do
dotnet pack "$d"
done
dotnet build -c Release
+30
View File
@@ -0,0 +1,30 @@
<Project>
<PropertyGroup>
<!--Properties for packages.-->
<TargetFrameworks>net6.0;net8.0;net10.0</TargetFrameworks>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<RootNamespace>ReFuel.Stb</RootNamespace>
<Optimize>true</Optimize>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageOutputPath>$(MSBuildThisFileDirectory)../bin</PackageOutputPath>
<!--Supresses warnings for the nuget packages with only native assemlies.-->
<NoWarn>$(NoWarn);NU5128</NoWarn>
<Authors>STBI Authors, H. Utku Maden</Authors>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
<PackageIcon>images\icon.png</PackageIcon>
<PackageProjectUrl>https://refuel.mixedup.dev/docs/ReFuel.StbImage.html</PackageProjectUrl>
<RepositoryUrl>https://github.com/ReFuelGameEngine/ReFuel.StbImage</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>stb; stb_image; stbi; image; load; save; read; write</PackageTags>
</PropertyGroup>
<ItemGroup>
<Content Include="../*.md" Pack="true" PackagePath="/" />
<None Include="../rf_stbimage.png" Pack="true" PackagePath="images\icon.png" />
</ItemGroup>
</Project>
+20
View File
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
<metadata>
<id>ReFuel.StbImage.redis.$rid$</id>
<version>$version$</version>
<authors>STB Authors, H. Utku Maden</authors>
<license type="expression">MIT</license>
<readme>README.md</readme>
<icon>images\icon.png</icon>
<description>Native dependencies for ReFuel.StbImage</description>
<repository type="git" url="https://github.com/ReFuelGameEngine/ReFuel.StbImage" />
</metadata>
<files>
<file src="..\runtimes\$rid$\native\$dllname$" target="runtimes\$rid$\native\$dllname$" />
<file src="..\README.md" target="README.md"/>
<file src="..\LICENSE.md" target="LICENSE.md"/>
<file src="..\rf_stbimage.png" target="images\icon.png"/>
</files>
</package>
+1 -1
View File
@@ -24,4 +24,4 @@ dotnet nuget add source \
-n ReFuel -u "$NUGET_USER_NAME" -p "$REFUEL_API_KEY" \
--store-password-in-clear-text \
"$NUGET_INDEX"
dotnet nuget push -s ReFuel bin/*/*.nupkg
dotnet nuget push -s ReFuel bin/*.nupkg
+1 -1
Submodule stb updated: f7f20f39fe...31c1ad3745