[v1.0.0] Create Quik.StbImage nuget package.
Some checks failed
Build / build (push) Failing after 1m3s

Make more shell scripts.

Fix removed old function.

Add a workflow.

Add docker-compose.yaml version.

Update .gitea/workflows/build.yaml

Trying to see if this helps.

Add executable bit to shell scripts.

Where did my files go?

Fix executable bit of higher repository.

Change build scripts slightly to maybe fix CI?

Update .gitea/workflows/build.yaml

List all files in home directory of the runner.

Another silly push.

List stuff.

YEss another useless push.

Yet another attempt to fix CI builds.

This is getting out of hand.

Chnage build script.

Use unencrypted storage for the key because Nuget is nuget.
This commit is contained in:
H. Utku Maden 2024-03-19 22:02:20 +03:00
parent 067e0bdd03
commit bb5b3c638d
20 changed files with 685 additions and 1 deletions

1
.gitattributes vendored Normal file

@ -0,0 +1 @@
*.sh text eof=lf

@ -0,0 +1,25 @@
name: Build
run-name: Building docker container.
on:
workflow_dispatch:
push:
branches: stable
jobs:
build:
runs-on: ubuntu-latest
container:
image: git.mixedup.dev/quik/docker-cross-compiler
env:
QUIK_API_KEY: "${{secrets.QUIK_API_KEY}}"
volumes:
- ${{ gitea.workspace }}:/home/quik/src
steps:
- name: Check repository out.
uses: actions/checkout@v3
with:
submodules: recursive
- name: Run Build Script
run: "./build_native.sh"
- name: Publish Package
run: "./publish.sh"

6
.gitignore vendored Normal file

@ -0,0 +1,6 @@
**/bin
**/obj
**/out
**/runtimes
**/.vs*
**/.atom

11
CMakeLists.txt Normal file

@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.0)
project(quik_stbi LANGUAGES C VERSION 1.0)
add_compile_options(-static-libgcc)
add_library(stbi SHARED "quik_stbi.c")
install(
TARGETS stbi
RUNTIME DESTINATION .
LIBRARY DESTINATION .)

@ -0,0 +1,12 @@
using System;
namespace Quik.Stb.Image
{
[AttributeUsage(System.AttributeTargets.All, Inherited = false, AllowMultiple = true)]
internal sealed class NativeTypeNameAttribute : System.Attribute
{
public NativeTypeNameAttribute(string typename)
{
}
}
}

@ -1 +1 @@
Subproject commit 11bb72a464215693d5a3a6896b25e568cc6e3313
Subproject commit d9c98b5cdc37b2ba1855c8fa9ce0fac8266b0f89

61
Quik.StbImage.csproj Normal file

@ -0,0 +1,61 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>disable</Nullable>
<LangVersion>7.3</LangVersion>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<RuntimeIdentifiers>linux-arm;linux-arm64;linux-x64;win-x86;win-x64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup>
<!-- Nuget Properties. -->
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageId>Quik.StbImage</PackageId>
<Version>1.0.0</Version>
<Authors>STBI Authors, H. Utku Maden</Authors>
<Description>
A C# wrapper for the ubiquitous Stb Image library.
</Description>
</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="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>
</ItemGroup>
</Project>

25
Quik.StbImage.sln Normal file

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.002.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Quik.StbImage", "Quik.StbImage.csproj", "{C808B4BC-C3AF-4682-8EDA-EAAC780800C3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C808B4BC-C3AF-4682-8EDA-EAAC780800C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C808B4BC-C3AF-4682-8EDA-EAAC780800C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C808B4BC-C3AF-4682-8EDA-EAAC780800C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C808B4BC-C3AF-4682-8EDA-EAAC780800C3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B04E5FBA-41E6-4B0B-BC31-F996BE353F5A}
EndGlobalSection
EndGlobal

144
StbImage.cs Normal file

@ -0,0 +1,144 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace Quik.Stb
{
/// <summary>
/// A class that encompasses all features of stb_image.h in a safe way.
/// </summary>
public unsafe class StbImage : IDisposable
{
private bool isDisposed = false;
/// <summary>
/// Pointer to the image.
/// </summary>
public IntPtr ImagePointer { get; }
/// <summary>
/// Width of the image.
/// </summary>
public int Width { get; }
/// <summary>
/// Height of the image.
/// </summary>
/// <value></value>
public int Height { get; }
/// <summary>
/// Internal image format.
/// </summary>
public StbiImageFormat Format { get; }
public bool IsFloat { get; }
private StbImage(IntPtr image, int x, int y, StbiImageFormat format, bool isFloat)
{
ImagePointer = image;
Width = x;
Height = y;
Format = format;
IsFloat = isFloat;
}
~StbImage()
{
Dispose(false);
}
public void Dispose() => Dispose(true);
private void Dispose(bool disposing)
{
if (isDisposed) return;
if (disposing)
{
GC.SuppressFinalize(this);
}
Stbi.image_free(ImagePointer.ToPointer());
isDisposed = true;
}
/// <summary>
/// Set to flip the y-axis of loaded images on load.
/// </summary>
public static bool FlipVerticallyOnLoad { set => Stbi.set_flip_vertically_on_load(1); }
/// <summary>
/// Set to unpremultiply images on load.
/// </summary>
/// <remarks>
/// According to the stb_image documentation, only iPhone PNG images
/// can come with premultiplied alpha.
/// </remarks>
public static bool UnpremultiplyOnLoad { set => Stbi.set_unpremultiply_on_load(1); }
/// <summary>
/// Try loading an image, without raising exceptions.
/// </summary>
/// <param name="image">The resulting image.</param>
/// <param name="stream">Source stream.</param>
/// <param name="format">The desired image format.</param>
/// <returns>True on success.</returns>
public static bool TryLoad(out StbImage image, Stream stream, StbiImageFormat format = StbiImageFormat.Default, bool isFloat = false)
{
int x, y, iFormat;
StbiStreamWrapper wrapper = new StbiStreamWrapper(stream, true);
wrapper.CreateCallbacks(out stbi_io_callbacks cb);
stream.Position = 0;
IntPtr imagePtr;
if (isFloat)
{
imagePtr = (IntPtr)Stbi.loadf_from_callbacks(&cb, null, &x, &y, &iFormat, (int)format);
}
else
{
imagePtr = (IntPtr)Stbi.load_from_callbacks(&cb, null, &x, &y, &iFormat, (int)format);
}
if (imagePtr != IntPtr.Zero)
{
image = new StbImage(imagePtr, x, y, (StbiImageFormat)iFormat, isFloat);
return true;
}
else
{
image = null;
return false;
}
}
/// <summary>
/// Load an image.
/// </summary>
/// <param name="stream">The stream to load from.</param>
/// <param name="format">The desired image format.</param>
/// <returns>The image object.</returns>
public static StbImage Load(Stream stream, StbiImageFormat format = StbiImageFormat.Default, bool isFloat = false)
{
if (TryLoad(out StbImage image, stream, format, isFloat))
{
return image;
}
string reason = Marshal.PtrToStringUTF8((IntPtr)Stbi.failure_reason());
throw new Exception($"Failed to load image: {reason}");
}
public bool IsLoadable(Stream stream)
{
int x, y, iFormat;
StbiStreamWrapper wrapper = new StbiStreamWrapper(stream, true);
wrapper.CreateCallbacks(out stbi_io_callbacks cb);
stream.Position = 0;
int result = Stbi.info_from_callbacks(&cb, null, &x, &y, &iFormat);
return result != 0;
}
}
}

65
Stbi.Manual.cs Normal file

@ -0,0 +1,65 @@
using System;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Reflection;
namespace Quik.Stb
{
public unsafe static partial class Stbi
{
private delegate void FailedAssertProc(byte *expression, byte *file, int line, byte *function);
private static readonly string[] LibraryNames = new string[]
{
//FIXME: This is wrong on so many levels, but, i need to do this
// in order to get a change of this running.
"runtimes/win-x64/native/libstbi.dll",
"runtimes/win-x86/native/libstbi.dll",
"runtimes/linux-arm/native/libstbi.so",
"runtimes/linux-arm64/native/libstbi.so",
"runtimes/linux-x64/native/libstbi.so",
"runtimes/native/libstbi.dylib",
"libstbi.dll",
"libstbi.so",
"libstbi.dylib",
};
static Stbi()
{
NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), Resolver);
// quik_stbi_failed_assert_store(Marshal.GetFunctionPointerForDelegate<FailedAssertProc>(FailedAssert));
}
private static IntPtr Resolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
{
if (libraryName != "stbi")
return IntPtr.Zero;
foreach (string name in LibraryNames)
{
if (NativeLibrary.TryLoad(name, assembly, searchPath, out IntPtr handle))
{
return handle;
}
}
return NativeLibrary.Load(libraryName);
}
private static void FailedAssert(byte *expression, byte *file, int line, byte *function)
{
string expr = expression == null ? string.Empty : Marshal.PtrToStringUTF8((IntPtr)expression);
string f = file == null ? string.Empty : Marshal.PtrToStringUTF8((IntPtr)file);
string func = function == null ? string.Empty : Marshal.PtrToStringUTF8((IntPtr)function);
Exception ex = new Exception("Assert failed in native stbi code.");
ex.Data.Add("Expression", expr);
ex.Data.Add("File", f);
ex.Data.Add("Line", line);
ex.Data.Add("Function", func);
throw ex;
}
}
}

174
Stbi.cs Normal file

@ -0,0 +1,174 @@
using System;
using System.Runtime.InteropServices;
using Quik.Stb.Image;
namespace Quik.Stb
{
[NativeTypeName("unsigned int")]
public enum StbiEnum : uint
{
STBI_default = 0,
STBI_grey = 1,
STBI_grey_alpha = 2,
STBI_rgb = 3,
STBI_rgb_alpha = 4,
}
public partial struct stbi_io_callbacks
{
[NativeTypeName("int (*)(void *, char *, int)")]
public IntPtr read;
[NativeTypeName("void (*)(void *, int)")]
public IntPtr skip;
[NativeTypeName("int (*)(void *)")]
public IntPtr eof;
}
public static unsafe partial class Stbi
{
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load_from_memory", ExactSpelling = true)]
[return: NativeTypeName("stbi_uc *")]
public static extern byte* load_from_memory([NativeTypeName("const stbi_uc *")] byte* buffer, int len, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load_from_callbacks", ExactSpelling = true)]
[return: NativeTypeName("stbi_uc *")]
public static extern byte* load_from_callbacks([NativeTypeName("const stbi_io_callbacks *")] stbi_io_callbacks* clbk, void* user, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load", ExactSpelling = true)]
[return: NativeTypeName("stbi_uc *")]
public static extern byte* load([NativeTypeName("const char *")] sbyte* filename, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load_from_file", ExactSpelling = true)]
[return: NativeTypeName("stbi_uc *")]
public static extern byte* load_from_file([NativeTypeName("FILE *")] void* f, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load_gif_from_memory", ExactSpelling = true)]
[return: NativeTypeName("stbi_uc *")]
public static extern byte* load_gif_from_memory([NativeTypeName("const stbi_uc *")] byte* buffer, int len, int** delays, int* x, int* y, int* z, int* comp, int req_comp);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load_16_from_memory", ExactSpelling = true)]
[return: NativeTypeName("stbi_us *")]
public static extern ushort* load_16_from_memory([NativeTypeName("const stbi_uc *")] byte* buffer, int len, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load_16_from_callbacks", ExactSpelling = true)]
[return: NativeTypeName("stbi_us *")]
public static extern ushort* load_16_from_callbacks([NativeTypeName("const stbi_io_callbacks *")] stbi_io_callbacks* clbk, void* user, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load_16", ExactSpelling = true)]
[return: NativeTypeName("stbi_us *")]
public static extern ushort* load_16([NativeTypeName("const char *")] sbyte* filename, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_load_from_file_16", ExactSpelling = true)]
[return: NativeTypeName("stbi_us *")]
public static extern ushort* load_from_file_16([NativeTypeName("FILE *")] void* f, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_loadf_from_memory", ExactSpelling = true)]
public static extern float* loadf_from_memory([NativeTypeName("const stbi_uc *")] byte* buffer, int len, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_loadf_from_callbacks", ExactSpelling = true)]
public static extern float* loadf_from_callbacks([NativeTypeName("const stbi_io_callbacks *")] stbi_io_callbacks* clbk, void* user, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_loadf", ExactSpelling = true)]
public static extern float* loadf([NativeTypeName("const char *")] sbyte* filename, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_loadf_from_file", ExactSpelling = true)]
public static extern float* loadf_from_file([NativeTypeName("FILE *")] void* f, int* x, int* y, int* channels_in_file, int desired_channels);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_hdr_to_ldr_gamma", ExactSpelling = true)]
public static extern void hdr_to_ldr_gamma(float gamma);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_hdr_to_ldr_scale", ExactSpelling = true)]
public static extern void hdr_to_ldr_scale(float scale);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_ldr_to_hdr_gamma", ExactSpelling = true)]
public static extern void ldr_to_hdr_gamma(float gamma);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_ldr_to_hdr_scale", ExactSpelling = true)]
public static extern void ldr_to_hdr_scale(float scale);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_is_hdr_from_callbacks", ExactSpelling = true)]
public static extern int is_hdr_from_callbacks([NativeTypeName("const stbi_io_callbacks *")] stbi_io_callbacks* clbk, void* user);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_is_hdr_from_memory", ExactSpelling = true)]
public static extern int is_hdr_from_memory([NativeTypeName("const stbi_uc *")] byte* buffer, int len);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_is_hdr", ExactSpelling = true)]
public static extern int is_hdr([NativeTypeName("const char *")] sbyte* filename);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_is_hdr_from_file", ExactSpelling = true)]
public static extern int is_hdr_from_file([NativeTypeName("FILE *")] void* f);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_failure_reason", ExactSpelling = true)]
[return: NativeTypeName("const char *")]
public static extern sbyte* failure_reason();
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_image_free", ExactSpelling = true)]
public static extern void image_free(void* retval_from_stbi_load);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_info_from_memory", ExactSpelling = true)]
public static extern int info_from_memory([NativeTypeName("const stbi_uc *")] byte* buffer, int len, int* x, int* y, int* comp);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_info_from_callbacks", ExactSpelling = true)]
public static extern int info_from_callbacks([NativeTypeName("const stbi_io_callbacks *")] stbi_io_callbacks* clbk, void* user, int* x, int* y, int* comp);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_is_16_bit_from_memory", ExactSpelling = true)]
public static extern int is_16_bit_from_memory([NativeTypeName("const stbi_uc *")] byte* buffer, int len);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_is_16_bit_from_callbacks", ExactSpelling = true)]
public static extern int is_16_bit_from_callbacks([NativeTypeName("const stbi_io_callbacks *")] stbi_io_callbacks* clbk, void* user);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_info", ExactSpelling = true)]
public static extern int info([NativeTypeName("const char *")] sbyte* filename, int* x, int* y, int* comp);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_info_from_file", ExactSpelling = true)]
public static extern int info_from_file([NativeTypeName("FILE *")] void* f, int* x, int* y, int* comp);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_is_16_bit", ExactSpelling = true)]
public static extern int is_16_bit([NativeTypeName("const char *")] sbyte* filename);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_is_16_bit_from_file", ExactSpelling = true)]
public static extern int is_16_bit_from_file([NativeTypeName("FILE *")] void* f);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_set_unpremultiply_on_load", ExactSpelling = true)]
public static extern void set_unpremultiply_on_load(int flag_true_if_should_unpremultiply);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_convert_iphone_png_to_rgb", ExactSpelling = true)]
public static extern void convert_iphone_png_to_rgb(int flag_true_if_should_convert);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_set_flip_vertically_on_load", ExactSpelling = true)]
public static extern void set_flip_vertically_on_load(int flag_true_if_should_flip);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_set_unpremultiply_on_load_thread", ExactSpelling = true)]
public static extern void set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_convert_iphone_png_to_rgb_thread", ExactSpelling = true)]
public static extern void convert_iphone_png_to_rgb_thread(int flag_true_if_should_convert);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_set_flip_vertically_on_load_thread", ExactSpelling = true)]
public static extern void set_flip_vertically_on_load_thread(int flag_true_if_should_flip);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_zlib_decode_malloc_guesssize", ExactSpelling = true)]
[return: NativeTypeName("char *")]
public static extern sbyte* zlib_decode_malloc_guesssize([NativeTypeName("const char *")] sbyte* buffer, int len, int initial_size, int* outlen);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_zlib_decode_malloc_guesssize_headerflag", ExactSpelling = true)]
[return: NativeTypeName("char *")]
public static extern sbyte* zlib_decode_malloc_guesssize_headerflag([NativeTypeName("const char *")] sbyte* buffer, int len, int initial_size, int* outlen, int parse_header);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_zlib_decode_malloc", ExactSpelling = true)]
[return: NativeTypeName("char *")]
public static extern sbyte* zlib_decode_malloc([NativeTypeName("const char *")] sbyte* buffer, int len, int* outlen);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_zlib_decode_buffer", ExactSpelling = true)]
public static extern int zlib_decode_buffer([NativeTypeName("char *")] sbyte* obuffer, int olen, [NativeTypeName("const char *")] sbyte* ibuffer, int ilen);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_zlib_decode_noheader_malloc", ExactSpelling = true)]
[return: NativeTypeName("char *")]
public static extern sbyte* zlib_decode_noheader_malloc([NativeTypeName("const char *")] sbyte* buffer, int len, int* outlen);
[DllImport("stbi", CallingConvention = CallingConvention.Cdecl, EntryPoint = "stbi_zlib_decode_noheader_buffer", ExactSpelling = true)]
public static extern int zlib_decode_noheader_buffer([NativeTypeName("char *")] sbyte* obuffer, int olen, [NativeTypeName("const char *")] sbyte* ibuffer, int ilen);
}
}

11
StbiImageFormat.cs Normal file

@ -0,0 +1,11 @@
namespace Quik.Stb
{
public enum StbiImageFormat
{
Default = (int)StbiEnum.STBI_default,
Grey = (int)StbiEnum.STBI_grey,
GreyAlpha = (int)StbiEnum.STBI_grey_alpha,
Rgb = (int)StbiEnum.STBI_rgb,
Rgba = (int)StbiEnum.STBI_rgb_alpha
}
}

60
StbiStreamWrapper.cs Normal file

@ -0,0 +1,60 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace Quik.Stb
{
public unsafe class StbiStreamWrapper : IDisposable
{
private Stream _stream;
private bool _keepOpen;
private bool _isDisposed;
private delegate int ReadProc(void *userdata, byte* buffer, int count);
private delegate void SkipProc(void *userdata, int count);
private delegate int Eof(void *userdata);
public StbiStreamWrapper(Stream stream, bool keepOpen = false)
{
if (stream == null) throw new ArgumentNullException(nameof(stream));
_stream = stream;
_keepOpen = keepOpen;
}
public void CreateCallbacks(out stbi_io_callbacks cb)
{
cb = default;
cb.read = Marshal.GetFunctionPointerForDelegate<ReadProc>(ReadCb);
cb.skip = Marshal.GetFunctionPointerForDelegate<SkipProc>(SkipCb);
cb.eof = Marshal.GetFunctionPointerForDelegate<Eof>(EofCb);
}
private int ReadCb(void *userdata, byte* buffer, int count)
{
Span<byte> bytes = new Span<byte>(buffer, count);
return _stream.Read(bytes);
}
private void SkipCb(void *userdata, int count)
{
_stream.Seek(count, SeekOrigin.Current);
}
private int EofCb(void *userdata)
{
if (!_stream.CanRead || _stream.Position == _stream.Length)
return 1;
return 0;
}
public void Dispose()
{
if (_isDisposed) return;
if (!_keepOpen) _stream.Dispose();
_isDisposed = true;
}
}
}

11
build_ci_cd.sh Normal file

@ -0,0 +1,11 @@
#!/bin/bash
cd $(dirname "$0")
if [ -z "$QUIK_API_KEY" ]
then
echo "Please define QUIK_API_KEY"
exit 1
fi
pwd
docker-compose run build && docker-compose run publish

4
build_native.sh Executable file

@ -0,0 +1,4 @@
#!/bin/bash
cd $(dirname "$0")
./Quik.Common/sh/quik_build_native.sh .
dotnet build

30
clangsharp.rsp Normal file

@ -0,0 +1,30 @@
-x
c
-l
stbi
--config
compatible-codegen
single-file
exclude-fnptr-codegen
generate-aggressive-inlining
generate-setslastsystemerror-attribute
unix-types
--include-directory
../lib
--include-directory
../Quik.StbImage
--include-directory
/usr/lib/llvm-14/lib/clang/14.0.6/include
--file
../Quik.StbImage.redist/quik_stbi.h
../lib/stb/stb_image.h
--methodClassName
Stbi
--namespace
Quik.Stb
--output
Stbi.cs
--prefixStrip
stbi_
--with-type
FILE=void

16
docker-compose.yaml Normal file

@ -0,0 +1,16 @@
version: "2"
services:
build:
image: git.mixedup.dev/quik/docker-cross-compiler
command: "/home/quik/src/build_native.sh"
volumes:
- .:/home/quik/src
publish:
image: git.mixedup.dev/quik/docker-cross-compiler
command: "/home/quik/src/publish.sh"
environment:
QUIK_API_KEY: ${QUIK_API_KEY}
volumes:
- .:/home/quik/src

14
publish.sh Executable file

@ -0,0 +1,14 @@
#!/bin/bash
cd $(dirname "$0")
if [ -z "$QUIK_API_KEY" ]
then
echo "Please define QUIK_API_KEY"
exit 1
fi
dotnet nuget add source \
-n QUIK -u themixedupstuff -p "$QUIK_API_KEY" \
--store-password-in-clear-text \
https://git.mixedup.dev/api/packages/QUIK/nuget/index.json
dotnet nuget push -s QUIK bin/*/*.nupkg

4
quik_stbi.c Normal file

@ -0,0 +1,4 @@
#include "quik_stbi.h"
#define STB_IMAGE_IMPLEMENTATION 1
#include "stb/stb_image.h"

10
quik_stbi.h Normal file

@ -0,0 +1,10 @@
#ifndef _QUIK_STBI_H_
#define _QUIK_STBI_H_
#include "Quik.Common/include/quik_common.h"
#define STBIDEF QEXTERN
#include "stb/stb_image.h"
#endif