diff --git a/build.gradle.kts b/build.gradle.kts index a7eddc6e..524e6eec 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,6 +29,8 @@ val kotlinTargetJdkVersion: String by rootProject val targetJavaVersion = jdkVersion.toInt() +val overrunMarshalVersion: String by rootProject + group = projGroupId version = projVersion @@ -128,7 +130,6 @@ subprojects { apply(plugin = "java-library") apply(plugin = "idea") apply(plugin = "me.champeau.jmh") - apply(plugin = "org.jetbrains.kotlin.jvm") group = projGroupId version = projVersion @@ -136,16 +137,19 @@ subprojects { repositories { mavenCentral() - maven { url = uri("https://maven.aliyun.com/repository/central") } // temporary maven repositories - maven { url = uri("https://s01.oss.sonatype.org/content/repositories/releases") } maven { url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots") } + maven { url = uri("https://s01.oss.sonatype.org/content/repositories/releases") } + maven { url = uri("https://maven.aliyun.com/repository/central") } } + val annotationProcessor by configurations + val api by configurations val compileOnly by configurations val implementation by configurations dependencies { compileOnly("org.jetbrains:annotations:24.1.0") + api("io.github.over-run:marshal:$overrunMarshalVersion") if (project.name != "core") { implementation(project(":core")) } diff --git a/gradle.properties b/gradle.properties index 63bd1d6d..a975d463 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,4 +19,5 @@ jdkEarlyAccessDoc=jdk22 kotlinTargetJdkVersion=21 projModules=core, glfw, nfd, joml, opengl, stb +overrunMarshalVersion=0.1.0-alpha.8-jdk22 overrunPlatformVersion=1.0.0 diff --git a/modules/overrungl.core/src/main/java/module-info.java b/modules/overrungl.core/src/main/java/module-info.java index 67406362..4a96b9fe 100644 --- a/modules/overrungl.core/src/main/java/module-info.java +++ b/modules/overrungl.core/src/main/java/module-info.java @@ -30,6 +30,7 @@ overrungl.opengl, overrungl.stb; + requires transitive io.github.overrun.marshal; requires io.github.overrun.platform; requires static org.jetbrains.annotations; } diff --git a/modules/overrungl.stb/src/generator/kotlin/overrungl/stb/STBGenerator.kt b/modules/overrungl.stb/src/generator/kotlin/overrungl/stb/STBGenerator.kt deleted file mode 100644 index 9220e645..00000000 --- a/modules/overrungl.stb/src/generator/kotlin/overrungl/stb/STBGenerator.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2023 Overrun Organization - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - */ - -package overrungl.stb - -class Function { -} - -class STBClass { - private val functions = ArrayList() - - operator fun String.invoke(name: String) { - } - - fun generate() { - TODO() - } -} - -operator fun String.invoke(block: STBClass.() -> Unit) { - STBClass().also(block).generate() -} - -fun vorbis() { - "STBVorbis" { - "stb_vorbis_get_info"("getInfo") - } -} - -/** - * @author squid233 - * @since 0.1.0 - */ -fun main() { - vorbis() -} diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/Handles.java b/modules/overrungl.stb/src/main/java/overrungl/stb/Handles.java index f05aad0d..8dad2a09 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/Handles.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/Handles.java @@ -34,7 +34,7 @@ * @since 0.1.0 */ final class Handles { - private static final SymbolLookup lookup; + static final SymbolLookup lookup; static { final Supplier lib = () -> RuntimeHelper.load("stb", "stb", OverrunGL.STB_VERSION); diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBEasyFont.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBEasyFont.java index 37763b1b..a8271a22 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBEasyFont.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBEasyFont.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2023 Overrun Organization + * Copyright (c) 2023-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,16 +16,12 @@ package overrungl.stb; -import overrungl.NativeType; -import overrungl.internal.Checks; -import overrungl.internal.RuntimeHelper; -import overrungl.util.MemoryStack; +import org.jetbrains.annotations.Nullable; +import overrun.marshal.Downcall; +import overrun.marshal.gen.Entrypoint; +import overrun.marshal.gen.Sized; import java.lang.foreign.MemorySegment; -import java.lang.invoke.MethodHandle; - -import static overrungl.FunctionDescriptors.*; -import static overrungl.stb.Handles.*; /** * Easy-to-deploy, @@ -44,9 +40,9 @@ * to make work on modern APIs, and that's your problem. * {@snippet lang = java: * import java.lang.foreign.Arena; - * static MemorySegment buffer = Arena.ofAuto().allocate(99999); + * static MemorySegment buffer = Arena.ofAuto().allocate(99999); // ~500 chars * void printString(float x, float y, String text, float r, float g, float b) { - * int numQuads = STBEasyFont.print(x, y, text, MemorySegment.NULL, buffer, (int) buffer.byteSize()); + * int numQuads = STBEasyFont.INSTANCE.print(x, y, text, MemorySegment.NULL, buffer, (int) buffer.byteSize()); * GL10.color3f(r, g, b); * GL11.enableClientState(GL.VERTEX_ARRAY); * GL11.vertexPointer(2, GL.FLOAT, 16, buffer); @@ -58,25 +54,17 @@ * @author squid233 * @since 0.1.0 */ -public final class STBEasyFont { - private static final MethodHandle - stb_easy_font_get_spacing = downcall("stb_easy_font_get_spacing", F), - stb_easy_font_spacing = downcall("stb_easy_font_spacing", FV), - stb_easy_font_print = downcall("stb_easy_font_print", FFPPPII), - stb_easy_font_width = downcall("stb_easy_font_width", fd_PI), - stb_easy_font_height = downcall("stb_easy_font_height", fd_PI); - - private STBEasyFont() { - //no instance - } +interface STBEasyFont { + /** + * The instance of STBEasyFont. + */ + STBEasyFont INSTANCE = Downcall.load(Handles.lookup); - public static float getSpacing() { - try { - return (float) stb_easy_font_get_spacing.invokeExact(); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + /** + * {@return spacing} + */ + @Entrypoint("stb_easy_font_get_spacing") + float getSpacing(); /** * Use positive values to expand the space between characters, @@ -91,13 +79,8 @@ public static float getSpacing() { * * @param spacing spacing */ - public static void setSpacing(float spacing) { - try { - stb_easy_font_spacing.invokeExact(spacing); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stb_easy_font_spacing") + void setSpacing(float spacing); /** * Takes a string (which can contain '\n') and fills out a @@ -126,47 +109,55 @@ public static void setSpacing(float spacing) { * If your API doesn't draw quads, build a reusable index * list that allows you to render quads as indexed triangles. * - * @param x x - * @param y y - * @param text text - * @param color If you pass in NULL for color, it becomes 255,255,255,255. - * @param vertexBuffer vertex buffer - * @param vbufSize buffer size + * @param x x + * @param y y + * @param text text + * @param color If you pass in NULL for color, it becomes 255,255,255,255. + * @param vertex_buffer vertex buffer + * @param vbuf_size buffer size * @return the number of quads. */ - public static int nprint(float x, float y, @NativeType("char*") MemorySegment text, @NativeType("unsigned char[4]") MemorySegment color, @NativeType("void*") MemorySegment vertexBuffer, int vbufSize) { - try { - return (int) stb_easy_font_print.invokeExact(x, y, text, color, vertexBuffer, vbufSize); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stb_easy_font_print") + int print(float x, float y, MemorySegment text, MemorySegment color, MemorySegment vertex_buffer, int vbuf_size); /** * Takes a string (which can contain '\n') and fills out a * vertex buffer with renderable data to draw the string. + * Output data assumes increasing x is rightwards, increasing y + * is downwards. + *

+ * The vertex data is divided into quads, i.e. there are four + * vertices in the vertex buffer for each quad. + *

+ * The vertices are stored in an interleaved format: + *

    + *
  1. x:float
  2. + *
  3. y:float
  4. + *
  5. z:float
  6. + *
  7. color:uint8[4]
  8. + *
+ *

+ * You can ignore z and color if you get them from elsewhere. + * This format was chosen in the hopes it would make it + * easier for you to reuse existing vertex-buffer-drawing code. + *

+ * If the buffer isn't large enough, it will truncate. + * Expect it to use an average of ~270 bytes per character. + *

+ * If your API doesn't draw quads, build a reusable index + * list that allows you to render quads as indexed triangles. * - * @param x x - * @param y y - * @param text text - * @param color If you pass in NULL for color, it becomes 255,255,255,255. - * @param vertexBuffer vertex buffer - * @param vbufSize buffer size + * @param x x + * @param y y + * @param text text + * @param color If you pass in NULL for color, it becomes 255,255,255,255. + * @param vertex_buffer vertex buffer + * @param vbuf_size buffer size * @return the number of quads. - * @see #nprint(float, float, MemorySegment, MemorySegment, MemorySegment, int) nprint + * @see #print(float, float, MemorySegment, MemorySegment, MemorySegment, int) print */ - public static int print(float x, float y, String text, byte[] color, @NativeType("void*") MemorySegment vertexBuffer, int vbufSize) { - if (color != null && RuntimeHelper.CHECKS) { - Checks.arraySize(color, 4); - } - final MemoryStack stack = MemoryStack.stackGet(); - final long stackPointer = stack.getPointer(); - try { - return nprint(x, y, stack.allocateFrom(text), color == null ? MemorySegment.NULL : stack.bytes(color), vertexBuffer, vbufSize); - } finally { - stack.setPointer(stackPointer); - } - } + @Entrypoint("stb_easy_font_print") + int print(float x, float y, String text, @Sized(4) byte @Nullable [] color, MemorySegment vertex_buffer, int vbuf_size); /** * Takes a string and returns the horizontal size (which can vary if 'text' has newlines). @@ -174,30 +165,18 @@ public static int print(float x, float y, String text, byte[] color, @NativeType * @param text the text. * @return the size. */ - public static int nwidth(@NativeType("char*") MemorySegment text) { - try { - return (int) stb_easy_font_width.invokeExact(text); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stb_easy_font_width") + int width(MemorySegment text); /** * Takes a string and returns the horizontal size (which can vary if 'text' has newlines). * * @param text the text. * @return the size. - * @see #nwidth(MemorySegment) nwidth + * @see #width(MemorySegment) width */ - public static int width(String text) { - final MemoryStack stack = MemoryStack.stackGet(); - final long stackPointer = stack.getPointer(); - try { - return nwidth(stack.allocateFrom(text)); - } finally { - stack.setPointer(stackPointer); - } - } + @Entrypoint("stb_easy_font_width") + int width(String text); /** * Takes a string and returns the vertical size (which can vary if 'text' has newlines). @@ -205,28 +184,16 @@ public static int width(String text) { * @param text the text. * @return the size. */ - public static int nheight(@NativeType("char*") MemorySegment text) { - try { - return (int) stb_easy_font_height.invokeExact(text); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stb_easy_font_height") + int height(MemorySegment text); /** * Takes a string and returns the vertical size (which can vary if 'text' has newlines). * * @param text the text. * @return the size. - * @see #nheight(MemorySegment) nheight + * @see #height(MemorySegment) height */ - public static int height(String text) { - final MemoryStack stack = MemoryStack.stackGet(); - final long stackPointer = stack.getPointer(); - try { - return nheight(stack.allocateFrom(text)); - } finally { - stack.setPointer(stackPointer); - } - } + @Entrypoint("stb_easy_font_height") + int height(String text); } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBIIoCallbacks.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBIIoCallbacks.java index 31a7b13c..e7eac67b 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBIIoCallbacks.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBIIoCallbacks.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2022-2023 Overrun Organization + * Copyright (c) 2022-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,25 +16,20 @@ package overrungl.stb; -import overrungl.Callback; -import overrungl.internal.RuntimeHelper; -import overrungl.Struct; +import overrun.marshal.Upcall; +import overrun.marshal.struct.Struct; +import overrun.marshal.struct.StructHandle; import java.lang.foreign.*; -import java.lang.foreign.MemoryLayout.PathElement; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.lang.invoke.VarHandle; /** * The IO callback of STB image. *

Layout

*

  * struct stbi_io_callbacks {
- *     int (*{@link #read() read})(void* user, char* data, int size);
- *     void (*{@link #skip() skip})(void* user, int n);
- *     int (*{@link #eof() eof})(void* user);
+ *     int (*{@link #read})(void* user, char* data, int size);
+ *     void (*{@link #skip})(void* user, int n);
+ *     int (*{@link #eof})(void* user);
  * }
* * @author squid233 @@ -49,18 +44,55 @@ public final class STBIIoCallbacks extends Struct { ValueLayout.ADDRESS.withName("skip"), ValueLayout.ADDRESS.withName("eof") ); - private static final VarHandle - pRead = LAYOUT.varHandle(PathElement.groupElement("read")), - pSkip = LAYOUT.varHandle(PathElement.groupElement("skip")), - pEof = LAYOUT.varHandle(PathElement.groupElement("eof")); + /** + * the read callback + */ + public final StructHandle.Upcall read = StructHandle.ofUpcall(this, "read", Read::wrap); + /** + * the skip callback + */ + public final StructHandle.Upcall skip = StructHandle.ofUpcall(this, "skip", Skip::wrap); + /** + * the eof callback + */ + public final StructHandle.Upcall eof = StructHandle.ofUpcall(this, "eof", Eof::wrap); + + /** + * Creates a struct with the given layout. + * + * @param segment the segment + * @param elementCount the element count + */ + public STBIIoCallbacks(MemorySegment segment, long elementCount) { + super(segment, elementCount, LAYOUT); + } + + /** + * Allocates a struct with the given layout. + * + * @param allocator the allocator + * @param elementCount the element count + */ + public STBIIoCallbacks(SegmentAllocator allocator, long elementCount) { + super(allocator, elementCount, LAYOUT); + } + + /** + * Creates a struct with the given layout. + * + * @param segment the segment + */ + public STBIIoCallbacks(MemorySegment segment) { + super(segment, LAYOUT); + } /** - * Create a {@code stbi_io_callbacks} instance. + * Allocates a struct with the given layout. * - * @param address the address. + * @param allocator the allocator */ - public STBIIoCallbacks(MemorySegment address) { - super(address, LAYOUT); + public STBIIoCallbacks(SegmentAllocator allocator) { + super(allocator, LAYOUT); } /** @@ -70,9 +102,11 @@ public STBIIoCallbacks(MemorySegment address) { * @since 0.1.0 */ @FunctionalInterface - public interface Read extends Callback { - FunctionDescriptor DESC = FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.JAVA_INT); - MethodType MTYPE = DESC.toMethodType(); + public interface Read extends Upcall { + /** + * the type + */ + Type TYPE = Upcall.type(); /** * Fill {@code data} with {@code size} bytes. @@ -91,18 +125,25 @@ public interface Read extends Callback { * @param size byte size to fill * @return number of bytes actually read */ + @Stub default int ninvoke(MemorySegment user, MemorySegment data, int size) { - return invoke(user.reinterpret(Long.MAX_VALUE), data.reinterpret(size)); + return invoke(user, data.reinterpret(size)); } @Override - default FunctionDescriptor descriptor() { - return DESC; + default MemorySegment stub(Arena arena) { + return TYPE.of(arena, this); } - @Override - default MethodHandle handle(MethodHandles.Lookup lookup) throws NoSuchMethodException, IllegalAccessException { - return lookup.findVirtual(Read.class, "ninvoke", MTYPE); + @Wrapper + static Read wrap(Arena arena, MemorySegment stub) { + return TYPE.wrap(stub, handle -> (user, data) -> { + try { + return (int) handle.invokeExact(user, data, Math.toIntExact(data.byteSize())); + } catch (Throwable e) { + throw new RuntimeException(e); + } + }); } } @@ -113,17 +154,11 @@ default MethodHandle handle(MethodHandles.Lookup lookup) throws NoSuchMethodExce * @since 0.1.0 */ @FunctionalInterface - public interface Skip extends Callback { - FunctionDescriptor DESC = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.JAVA_INT); - MethodType MTYPE = DESC.toMethodType(); - + public interface Skip extends Upcall { /** - * Skip the next {@code n} bytes, or “unget” the last {@code -n} bytes if negative - * - * @param user userdata - * @param n byte size to skip + * the type */ - void invoke(MemorySegment user, int n); + Type TYPE = Upcall.type(); /** * Skip the next {@code n} bytes, or “unget” the last {@code -n} bytes if negative @@ -131,18 +166,24 @@ public interface Skip extends Callback { * @param user userdata * @param n byte size to skip */ - default void ninvoke(MemorySegment user, int n) { - invoke(user.reinterpret(Long.MAX_VALUE), n); - } + @Stub + void invoke(MemorySegment user, int n); + @Override - default FunctionDescriptor descriptor() { - return DESC; + default MemorySegment stub(Arena arena) { + return TYPE.of(arena, this); } - @Override - default MethodHandle handle(MethodHandles.Lookup lookup) throws NoSuchMethodException, IllegalAccessException { - return lookup.findVirtual(Skip.class, "ninvoke", MTYPE); + @Wrapper + static Skip wrap(Arena arena, MemorySegment stub) { + return TYPE.wrap(stub, handle -> (user, n) -> { + try { + handle.invokeExact(user, n); + } catch (Throwable e) { + throw new RuntimeException(e); + } + }); } } @@ -153,108 +194,34 @@ default MethodHandle handle(MethodHandles.Lookup lookup) throws NoSuchMethodExce * @since 0.1.0 */ @FunctionalInterface - public interface Eof extends Callback { - FunctionDescriptor DESC = FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS); - MethodType MTYPE = DESC.toMethodType(); - + public interface Eof extends Upcall { /** - * {@return nonzero if we are at end of file/data} - * - * @param user userdata + * the type */ - int invoke(MemorySegment user); + Type TYPE = Upcall.type(); /** * {@return nonzero if we are at end of file/data} * * @param user userdata */ - default int ninvoke(MemorySegment user) { - return invoke(user.reinterpret(Long.MAX_VALUE)); - } + @Stub + int invoke(MemorySegment user); @Override - default FunctionDescriptor descriptor() { - return DESC; + default MemorySegment stub(Arena arena) { + return TYPE.of(arena, this); } - @Override - default MethodHandle handle(MethodHandles.Lookup lookup) throws NoSuchMethodException, IllegalAccessException { - return lookup.findVirtual(Eof.class, "ninvoke", MTYPE); + @Wrapper + static Eof wrap(Arena arena, MemorySegment segment) { + return TYPE.wrap(segment, handle -> user -> { + try { + return (int) handle.invokeExact(user); + } catch (Throwable e) { + throw new RuntimeException(e); + } + }); } } - - /** - * {@return the elements size of this struct in bytes} - */ - public static long sizeof() { - return LAYOUT.byteSize(); - } - - /** - * Creates a {@code stbi_io_callbacks} instance with the given allocator. - * - * @param allocator the allocator - * @return the instance - */ - public static STBIIoCallbacks create(SegmentAllocator allocator) { - return new STBIIoCallbacks(allocator.allocate(LAYOUT)); - } - - /** - * {@return the read callback} - */ - public MemorySegment read() { - return (MemorySegment) pRead.get(segment()); - } - - /** - * {@return the skip callback} - */ - public MemorySegment skip() { - return (MemorySegment) pSkip.get(segment()); - } - - /** - * {@return the eof callback} - */ - public MemorySegment eof() { - return (MemorySegment) pEof.get(segment()); - } - - /** - * Sets the read callback. - * - * @param arena the arena of the callback. - * @param read the read callback - * @return this - */ - public STBIIoCallbacks read(Arena arena, Read read) { - pRead.set(segment(), read.address(arena)); - return this; - } - - /** - * Sets the skip callback. - * - * @param arena the arena of the callback. - * @param skip the skip callback - * @return this - */ - public STBIIoCallbacks skip(Arena arena, Skip skip) { - pSkip.set(segment(), skip.address(arena)); - return this; - } - - /** - * Sets the eof callback. - * - * @param arena the arena of the callback. - * @param eof the eof callback - * @return this - */ - public STBIIoCallbacks eof(Arena arena, Eof eof) { - pEof.set(segment(), eof.address(arena)); - return this; - } } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBIRColorspace.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBIRColorspace.java deleted file mode 100644 index e910e968..00000000 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBIRColorspace.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022-2023 Overrun Organization - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - */ - -package overrungl.stb; - -/** - * The STB image resizer color-space - * - * @author squid233 - * @since 0.1.0 - */ -public enum STBIRColorspace { - LINEAR, - SRGB, - MAX_COLORSPACES -} diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBIRDatatype.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBIRDatatype.java index c1a26499..4280e70e 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBIRDatatype.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBIRDatatype.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2022-2023 Overrun Organization + * Copyright (c) 2022-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,16 +16,33 @@ package overrungl.stb; +import overrun.marshal.CEnum; + /** * The STB image resizer datatype * * @author squid233 * @since 0.1.0 */ -public enum STBIRDatatype { - UINT8, - UINT16, - UINT32, - FLOAT, - MAX_TYPES +public enum STBIRDatatype implements CEnum { + UINT8(0), + UINT8_SRGB(1), + /** + * alpha channel, when present, should also be SRGB (this is very unusual) + */ + UINT8_SRGB_ALPHA(2), + UINT16(3), + FLOAT(4), + HALF_FLOAT(5); + + private final int value; + + STBIRDatatype(int value) { + this.value = value; + } + + @Override + public int value() { + return value; + } } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBIREdge.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBIREdge.java index d215a251..bf412ff9 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBIREdge.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBIREdge.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2022-2023 Overrun Organization + * Copyright (c) 2022-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,17 +16,22 @@ package overrungl.stb; +import overrun.marshal.CEnum; + /** * The STB image resizer edge * * @author squid233 * @since 0.1.0 */ -public enum STBIREdge { - CLAMP(1), - REFLECT(2), - WRAP(3), - ZERO(4); +public enum STBIREdge implements CEnum { + CLAMP(0), + REFLECT(1), + /** + * this edge mode is slower and uses more memory + */ + WRAP(2), + ZERO(3); private final int value; @@ -34,10 +39,8 @@ public enum STBIREdge { this.value = value; } - /** - * {@return the enum value} - */ - public int getValue() { + @Override + public int value() { return value; } } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBIRFilter.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBIRFilter.java index 876a622b..4053bbda 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBIRFilter.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBIRFilter.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2022-2023 Overrun Organization + * Copyright (c) 2022-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,13 +16,15 @@ package overrungl.stb; +import overrun.marshal.CEnum; + /** * The STB image resizer filter * * @author squid233 * @since 0.1.0 */ -public enum STBIRFilter { +public enum STBIRFilter implements CEnum { /** * use same filter type that easy-to-use API chooses */ @@ -46,7 +48,15 @@ public enum STBIRFilter { /** * Mitchell-Netrevalli filter with B=1/3, C=1/3 */ - MITCHELL(5); + MITCHELL(5), + /** + * Simple point sampling + */ + POINT_SAMPLE(6), + /** + * User callback specified + */ + OTHER(7); private final int value; @@ -54,10 +64,8 @@ public enum STBIRFilter { this.value = value; } - /** - * {@return the enum value} - */ - public int getValue() { + @Override + public int value() { return value; } } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBIRPixelLayout.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBIRPixelLayout.java new file mode 100644 index 00000000..1e697624 --- /dev/null +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBIRPixelLayout.java @@ -0,0 +1,84 @@ +/* + * MIT License + * + * Copyright (c) 2024 Overrun Organization + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + */ + +package overrungl.stb; + +import overrun.marshal.CEnum; + +/** + * stbir_pixel_layout specifies:
+ * number of channels
+ * order of channels
+ * whether color is premultiplied by alpha + * + * @author squid233 + * @since 0.1.0 + */ +public enum STBIRPixelLayout implements CEnum { + _1CHANNEL(1), + _2CHANNEL(2), + /** + * 3-chan, with order specified (for channel flipping) + */ + RGB(3), + /** + * 3-chan, with order specified (for channel flipping) + */ + BGR(0), + _4CHANNEL(5), + /** + * alpha formats, where alpha is NOT premultiplied into color channels + */ + RGBA(4), + BGRA(6), + ARGB(7), + ABGR(8), + RA(9), + AR(10), + /** + * alpha formats, where alpha is premultiplied into color channels + */ + RGBA_PM(11), + BGRA_PM(12), + ARGB_PM(13), + ABGR_PM(14), + RA_PM(15), + AR_PM(16), + /** + * alpha formats, where NO alpha weighting is applied at all! + * these are just synonyms for the _PM flags (which also do + * no alpha weighting). These names just make it more clear + * for some folks). + */ + RGBA_NO_AW(11), + BGRA_NO_AW(12), + ARGB_NO_AW(13), + ABGR_NO_AW(14), + RA_NO_AW(15), + AR_NO_AW(16), + ; + + private final int value; + + STBIRPixelLayout(int value) { + this.value = value; + } + + @Override + public int value() { + return value; + } +} diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBIWriteFunc.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBIWriteFunc.java index eced09bf..7590654c 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBIWriteFunc.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBIWriteFunc.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2022-2023 Overrun Organization + * Copyright (c) 2022-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,14 +16,10 @@ package overrungl.stb; -import overrungl.Callback; +import overrun.marshal.Upcall; -import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; -import java.lang.foreign.ValueLayout; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; /** * The write-callback. @@ -32,23 +28,21 @@ * @since 0.1.0 */ @FunctionalInterface -public interface STBIWriteFunc extends Callback { - FunctionDescriptor DESC = FunctionDescriptor.ofVoid(ValueLayout.ADDRESS, ValueLayout.ADDRESS, ValueLayout.JAVA_INT); - MethodType MTYPE = DESC.toMethodType(); +public interface STBIWriteFunc extends Upcall { + /** + * the type + */ + Type TYPE = Upcall.type(); void invoke(MemorySegment context, MemorySegment data); + @Stub default void ninvoke(MemorySegment context, MemorySegment data, int size) { invoke(context, data.reinterpret(size)); } @Override - default FunctionDescriptor descriptor() { - return DESC; - } - - @Override - default MethodHandle handle(MethodHandles.Lookup lookup) throws NoSuchMethodException, IllegalAccessException { - return lookup.findVirtual(STBIWriteFunc.class, "ninvoke", MTYPE); + default MemorySegment stub(Arena arena) { + return TYPE.of(arena, this); } } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBImage.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBImage.java index f0bae4b9..0fa0fb59 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBImage.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBImage.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2022-2023 Overrun Organization + * Copyright (c) 2022-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -17,17 +17,14 @@ package overrungl.stb; import org.jetbrains.annotations.Nullable; -import overrungl.internal.RuntimeHelper; -import overrungl.util.MemoryStack; +import overrun.marshal.Downcall; +import overrun.marshal.MemoryStack; +import overrun.marshal.Unmarshal; +import overrun.marshal.gen.*; -import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; import java.lang.foreign.SegmentAllocator; -import java.lang.invoke.MethodHandle; - -import static java.lang.foreign.ValueLayout.*; -import static overrungl.FunctionDescriptors.*; -import static overrungl.stb.Handles.*; +import java.lang.foreign.ValueLayout; /** * The STB image reader. @@ -35,748 +32,326 @@ * @author squid233 * @since 0.1.0 */ -public final class STBImage { - private static final MethodHandle - stbi_convert_iphone_png_to_rgb = downcall("stbi_convert_iphone_png_to_rgb", IV), - stbi_convert_iphone_png_to_rgb_thread = downcall("stbi_convert_iphone_png_to_rgb_thread", IV), - stbi_failure_reason = downcall("stbi_failure_reason", p), - stbi_hdr_to_ldr_gamma = downcall("stbi_hdr_to_ldr_gamma", FV), - stbi_hdr_to_ldr_scale = downcall("stbi_hdr_to_ldr_scale", FV), - stbi_image_free = downcall("stbi_image_free", PV), - stbi_info = downcall("stbi_info", PPPPI), - stbi_info_from_callbacks = downcall("stbi_info_from_callbacks", PPPPPI), - stbi_info_from_file = downcall("stbi_info_from_file", PPPPI), - stbi_info_from_memory = downcall("stbi_info_from_memory", PIPPPI), - stbi_is_16_bit = downcall("stbi_is_16_bit", fd_PI), - stbi_is_16_bit_from_callbacks = downcall("stbi_is_16_bit_from_callbacks", PPI), - stbi_is_16_bit_from_file = downcall("stbi_is_16_bit_from_file", fd_PI), - stbi_is_16_bit_from_memory = downcall("stbi_is_16_bit_from_memory", PII), - stbi_is_hdr = downcall("stbi_is_hdr", fd_PI), - stbi_is_hdr_from_callbacks = downcall("stbi_is_hdr_from_callbacks", PPI), - stbi_is_hdr_from_file = downcall("stbi_is_hdr_from_file", fd_PI), - stbi_is_hdr_from_memory = downcall("stbi_is_hdr_from_memory", PII), - stbi_ldr_to_hdr_gamma = downcall("stbi_ldr_to_hdr_gamma", FV), - stbi_ldr_to_hdr_scale = downcall("stbi_ldr_to_hdr_scale", FV), - stbi_load = downcall("stbi_load", PPPPIp), - stbi_load_16 = downcall("stbi_load_16", PPPPIp), - stbi_load_16_from_callbacks = downcall("stbi_load_16_from_callbacks", PPPPPIp), - stbi_load_16_from_memory = downcall("stbi_load_16_from_memory", PIPPPIp), - stbi_load_from_callbacks = downcall("stbi_load_from_callbacks", PPPPPIp), - stbi_load_from_file = downcall("stbi_load_from_file", PPPPIp), - stbi_load_from_file_16 = downcall("stbi_load_from_file_16", PPPPIp), - stbi_load_from_memory = downcall("stbi_load_from_memory", PIPPPIp), - stbi_load_gif_from_memory = downcall("stbi_load_gif_from_memory", PIPPPPPIp), - stbi_loadf = downcall("stbi_loadf", PPPPIp), - stbi_loadf_from_callbacks = downcall("stbi_loadf_from_callbacks", PPPPPIp), - stbi_loadf_from_file = downcall("stbi_loadf_from_file", PPPPIp), - stbi_loadf_from_memory = downcall("stbi_loadf_from_memory", PIPPPIp), - stbi_set_flip_vertically_on_load = downcall("stbi_set_flip_vertically_on_load", IV), - stbi_set_flip_vertically_on_load_thread = downcall("stbi_set_flip_vertically_on_load_thread", IV), - stbi_set_unpremultiply_on_load = downcall("stbi_set_unpremultiply_on_load", IV), - stbi_set_unpremultiply_on_load_thread = downcall("stbi_set_unpremultiply_on_load_thread", IV), - stbi_zlib_decode_buffer = downcall("stbi_zlib_decode_buffer", PIPII), - stbi_zlib_decode_malloc = downcall("stbi_zlib_decode_malloc", PIPp), - stbi_zlib_decode_malloc_guesssize = downcall("stbi_zlib_decode_malloc_guesssize", PIIPp), - stbi_zlib_decode_malloc_guesssize_headerflag = downcall("stbi_zlib_decode_malloc_guesssize_headerflag", PIIPIp), - stbi_zlib_decode_noheader_buffer = downcall("stbi_zlib_decode_noheader_buffer", PIPII), - stbi_zlib_decode_noheader_malloc = downcall("stbi_zlib_decode_noheader_malloc", PIPp); - +public interface STBImage { + /** + * The instance of STBImage. + */ + STBImage INSTANCE = Downcall.load(Handles.lookup); // only used for desiredChannels /** * Image channels */ - public static final int - DEFAULT = 0, + int DEFAULT = 0, GREY = 1, GREY_ALPHA = 2, RGB = 3, RGB_ALPHA = 4; - private STBImage() { - throw new IllegalStateException("Do not construct instance"); - } + @Entrypoint("stbi_convert_iphone_png_to_rgb") + void convertIphonePngToRgb(@Convert(Type.INT) boolean shouldConvert); - public static void convertIphonePngToRgb(boolean shouldConvert) { - try { - stbi_convert_iphone_png_to_rgb.invokeExact(shouldConvert ? 1 : 0); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } - - public static void convertIphonePngToRgbThread(boolean shouldConvert) { - try { - stbi_convert_iphone_png_to_rgb_thread.invokeExact(shouldConvert ? 1 : 0); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_convert_iphone_png_to_rgb_thread") + void convertIphonePngToRgbThread(@Convert(Type.INT) boolean shouldConvert); - public static MemorySegment nfailureReason() { - try { - return (MemorySegment) stbi_failure_reason.invokeExact(); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_failure_reason") + MemorySegment nfailureReason(); + @Entrypoint("stbi_failure_reason") @Nullable - public static String failureReason() { - var pReason = nfailureReason(); - return RuntimeHelper.isNullptr(pReason) ? null : pReason.getString(0); - } + @SizedSeg(Unmarshal.STR_SIZE) + String failureReason(); - public static void hdrToLdrGamma(float gamma) { - try { - stbi_hdr_to_ldr_gamma.invokeExact(gamma); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_hdr_to_ldr_gamma") + void hdrToLdrGamma(float gamma); - public static void hdrToLdrScale(float scale) { - try { - stbi_hdr_to_ldr_scale.invokeExact(scale); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_hdr_to_ldr_scale") + void hdrToLdrScale(float scale); - public static void free(MemorySegment retValFromLoad) { - try { - stbi_image_free.invokeExact(retValFromLoad); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_image_free") + void free(MemorySegment retValFromLoad); - public static boolean ninfo(MemorySegment filename, MemorySegment x, MemorySegment y, MemorySegment comp) { - try { - return (int) stbi_info.invokeExact(filename, x, y, comp) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_info") + boolean ninfo(MemorySegment filename, MemorySegment x, MemorySegment y, MemorySegment comp); - public static boolean info(String filename, int[] x, int[] y, int[] comp) { - final MemoryStack stack = MemoryStack.stackGet(); - final long stackPointer = stack.getPointer(); - try { - var px = stack.allocate(JAVA_INT); - var py = stack.allocate(JAVA_INT); - var pc = stack.allocate(JAVA_INT); - boolean b = ninfo(stack.allocateFrom(filename), px, py, pc); - x[0] = px.get(JAVA_INT, 0); - y[0] = py.get(JAVA_INT, 0); - comp[0] = pc.get(JAVA_INT, 0); - return b; - } finally { - stack.setPointer(stackPointer); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_info") + boolean info(String filename, @Ref int[] x, @Ref int[] y, @Ref int[] comp); - public static boolean ninfoFromCallbacks(MemorySegment clbk, MemorySegment user, MemorySegment x, MemorySegment y, MemorySegment comp) { - try { - return (int) stbi_info_from_callbacks.invokeExact(clbk, user, x, y, comp) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_info_from_callbacks") + boolean ninfoFromCallbacks(MemorySegment clbk, MemorySegment user, MemorySegment x, MemorySegment y, MemorySegment comp); - public static boolean infoFromCallbacks(STBIIoCallbacks clbk, MemorySegment user, int[] x, int[] y, int[] comp) { - var stack = MemoryStack.stackGet(); - long stackPointer = stack.getPointer(); - try { - var px = stack.callocInt(); - var py = stack.callocInt(); - var pc = stack.callocInt(); - boolean b = ninfoFromCallbacks(clbk.address(), user, px, py, pc); - x[0] = px.get(JAVA_INT, 0); - y[0] = py.get(JAVA_INT, 0); - comp[0] = pc.get(JAVA_INT, 0); - return b; - } finally { - stack.setPointer(stackPointer); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_info_from_callbacks") + boolean infoFromCallbacks(STBIIoCallbacks clbk, MemorySegment user, @Ref int[] x, @Ref int[] y, @Ref int[] comp); - public static boolean ninfoFromFile(MemorySegment f, MemorySegment x, MemorySegment y, MemorySegment comp) { - try { - return (int) stbi_info_from_file.invokeExact(f, x, y, comp) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_info_from_file") + boolean ninfoFromFile(MemorySegment f, MemorySegment x, MemorySegment y, MemorySegment comp); - public static boolean infoFromFile(MemorySegment f, int[] x, int[] y, int[] comp) { - var stack = MemoryStack.stackGet(); - long stackPointer = stack.getPointer(); - try { - var px = stack.callocInt(); - var py = stack.callocInt(); - var pc = stack.callocInt(); - boolean b = ninfoFromFile(f, px, py, pc); - x[0] = px.get(JAVA_INT, 0); - y[0] = py.get(JAVA_INT, 0); - comp[0] = pc.get(JAVA_INT, 0); - return b; - } finally { - stack.setPointer(stackPointer); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_info_from_file") + boolean infoFromFile(MemorySegment f, @Ref int[] x, @Ref int[] y, @Ref int[] comp); - public static boolean ninfoFromMemory(MemorySegment buffer, int len, MemorySegment x, MemorySegment y, MemorySegment comp) { - try { - return (int) stbi_info_from_memory.invokeExact(buffer, len, x, y, comp) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_info_from_memory") + boolean ninfoFromMemory(MemorySegment buffer, int len, MemorySegment x, MemorySegment y, MemorySegment comp); - public static boolean infoFromMemory(MemorySegment buffer, MemorySegment x, MemorySegment y, MemorySegment comp) { - return ninfoFromMemory(buffer, (int) buffer.byteSize(), x, y, comp); + @Skip + default boolean infoFromMemory(MemorySegment buffer, MemorySegment x, MemorySegment y, MemorySegment comp) { + return ninfoFromMemory(buffer, Math.toIntExact(buffer.byteSize()), x, y, comp); } - public static boolean infoFromMemory(SegmentAllocator allocator, byte[] buffer, int[] x, int[] y, int[] comp) { - var stack = MemoryStack.stackGet(); - long stackPointer = stack.getPointer(); - try { - var px = stack.callocInt(); - var py = stack.callocInt(); - var pc = stack.callocInt(); - boolean b = infoFromMemory(allocator.allocateFrom(JAVA_BYTE, buffer), px, py, pc); - x[0] = px.get(JAVA_INT, 0); - y[0] = py.get(JAVA_INT, 0); - comp[0] = pc.get(JAVA_INT, 0); - return b; - } finally { - stack.setPointer(stackPointer); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_info_from_memory") + boolean infoFromMemory(SegmentAllocator allocator, int len, byte[] buffer, @Ref int[] x, @Ref int[] y, @Ref int[] comp); - public static boolean nis16Bit(MemorySegment filename) { - try { - return (int) stbi_is_16_bit.invokeExact(filename) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Skip + default boolean infoFromMemory(SegmentAllocator allocator, byte[] buffer, @Ref int[] x, @Ref int[] y, @Ref int[] comp) { + return infoFromMemory(allocator, buffer.length, buffer, x, y, comp); } - public static boolean is16Bit(String filename) { - final MemoryStack stack = MemoryStack.stackGet(); - final long stackPointer = stack.getPointer(); - try { - return nis16Bit(stack.allocateFrom(filename)); - } finally { - stack.setPointer(stackPointer); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_is_16_bit") + boolean nis16Bit(MemorySegment filename); - public static boolean nis16BitFromCallbacks(MemorySegment clbk, MemorySegment user) { - try { - return (int) stbi_is_16_bit_from_callbacks.invokeExact(clbk, user) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_is_16_bit") + boolean nis16Bit(String filename); - public static boolean is16BitFromCallbacks(STBIIoCallbacks clbk, MemorySegment user) { - return nis16BitFromCallbacks(clbk.address(), user); - } + @Convert(Type.INT) + @Entrypoint("stbi_is_16_bit_from_callbacks") + boolean nis16BitFromCallbacks(MemorySegment clbk, MemorySegment user); - public static boolean is16BitFromFile(MemorySegment f) { - try { - return (int) stbi_is_16_bit_from_file.invokeExact(f) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_is_16_bit_from_callbacks") + boolean nis16BitFromCallbacks(STBIIoCallbacks clbk, MemorySegment user); - public static boolean nis16BitFromMemory(MemorySegment buffer, int len) { - try { - return (int) stbi_is_16_bit_from_memory.invokeExact(buffer, len) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_is_16_bit_from_file") + boolean nis16BitFromFile(MemorySegment f); - public static boolean is16BitFromMemory(MemorySegment buffer) { - return nis16BitFromMemory(buffer, (int) buffer.byteSize()); - } + @Convert(Type.INT) + @Entrypoint("stbi_is_16_bit_from_memory") + boolean nis16BitFromMemory(MemorySegment buffer, int len); - public static boolean is16BitFromMemory(SegmentAllocator allocator, byte[] buffer) { - return is16BitFromMemory(allocator.allocateFrom(JAVA_BYTE, buffer)); + @Skip + default boolean is16BitFromMemory(MemorySegment buffer) { + return nis16BitFromMemory(buffer, Math.toIntExact(buffer.byteSize())); } - public static boolean nisHdr(MemorySegment filename) { - try { - return (int) stbi_is_hdr.invokeExact(filename) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_is_16_bit_from_memory") + boolean is16BitFromMemory(SegmentAllocator allocator, byte[] buffer, int len); - public static boolean isHdr(String filename) { - final MemoryStack stack = MemoryStack.stackGet(); - final long stackPointer = stack.getPointer(); - try { - return nisHdr(stack.allocateFrom(filename)); - } finally { - stack.setPointer(stackPointer); - } + @Skip + default boolean is16BitFromMemory(SegmentAllocator allocator, byte[] buffer) { + return is16BitFromMemory(allocator, buffer, buffer.length); } - public static boolean nisHdrFromCallbacks(MemorySegment clbk, MemorySegment user) { - try { - return (int) stbi_is_hdr_from_callbacks.invokeExact(clbk, user) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_is_hdr") + boolean isHdr(MemorySegment filename); - public static boolean isHdrFromCallbacks(STBIIoCallbacks clbk, MemorySegment user) { - return nisHdrFromCallbacks(clbk.address(), user); - } + @Convert(Type.INT) + @Entrypoint("stbi_is_hdr") + boolean isHdr(String filename); - public static boolean isHdrFromFile(MemorySegment f) { - try { - return (int) stbi_is_hdr_from_file.invokeExact(f) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_is_hdr_from_callbacks") + boolean nisHdrFromCallbacks(MemorySegment clbk, MemorySegment user); - public static boolean nisHdrFromMemory(MemorySegment buffer, int len) { - try { - return (int) stbi_is_hdr_from_memory.invokeExact(buffer, len) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_is_hdr_from_callbacks") + boolean isHdrFromCallbacks(STBIIoCallbacks clbk, MemorySegment user); - public static boolean isHdrFromMemory(MemorySegment buffer) { - return nisHdrFromMemory(buffer, (int) buffer.byteSize()); - } + @Convert(Type.INT) + @Entrypoint("stbi_is_hdr_from_file") + boolean isHdrFromFile(MemorySegment f); - public static boolean isHdrFromMemory(SegmentAllocator allocator, byte[] buffer) { - return isHdrFromMemory(allocator.allocateFrom(JAVA_BYTE, buffer)); - } + @Convert(Type.INT) + @Entrypoint("stbi_is_hdr_from_memory") + boolean nisHdrFromMemory(MemorySegment buffer, int len); - public static void ldrToHdrGamma(float gamma) { - try { - stbi_ldr_to_hdr_gamma.invokeExact(gamma); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Skip + default boolean isHdrFromMemory(MemorySegment buffer) { + return nisHdrFromMemory(buffer, Math.toIntExact(buffer.byteSize())); } - public static void ldrToHdrScale(float scale) { - try { - stbi_ldr_to_hdr_scale.invokeExact(scale); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_is_hdr_from_memory") + boolean isHdrFromMemory(SegmentAllocator allocator, byte[] buffer, int len); - public static MemorySegment nload(MemorySegment filename, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { - try { - return (MemorySegment) stbi_load.invokeExact(filename, x, y, channelsInFile, desiredChannels); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Skip + default boolean isHdrFromMemory(SegmentAllocator allocator, byte[] buffer) { + return isHdrFromMemory(allocator, buffer, buffer.length); } - public static MemorySegment load(String filename, int[] x, int[] y, int[] channelsInFile, int desiredChannels) { - final MemoryStack stack = MemoryStack.stackGet(); - final long stackPointer = stack.getPointer(); - try { - var px = stack.allocate(JAVA_INT); - var py = stack.allocate(JAVA_INT); - var pc = stack.allocate(JAVA_INT); - var addr = nload(stack.allocateFrom(filename), px, py, pc, desiredChannels); - x[0] = px.get(JAVA_INT, 0); - y[0] = py.get(JAVA_INT, 0); - channelsInFile[0] = pc.get(JAVA_INT, 0); - return addr; - } finally { - stack.setPointer(stackPointer); - } - } + @Entrypoint("stbi_ldr_to_hdr_gamma") + void ldrToHdrGamma(float gamma); - public static MemorySegment nload16(MemorySegment filename, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { - try { - return (MemorySegment) stbi_load_16.invokeExact(filename, x, y, channelsInFile, desiredChannels); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_ldr_to_hdr_scale") + void ldrToHdrScale(float scale); - public static MemorySegment load16(String filename, int[] x, int[] y, int[] channelsInFile, int desiredChannels) { - final MemoryStack stack = MemoryStack.stackGet(); - final long stackPointer = stack.getPointer(); - try { - var px = stack.allocate(JAVA_INT); - var py = stack.allocate(JAVA_INT); - var pc = stack.allocate(JAVA_INT); - var addr = nload16(stack.allocateFrom(filename), px, py, pc, desiredChannels); - x[0] = px.get(JAVA_INT, 0); - y[0] = py.get(JAVA_INT, 0); - channelsInFile[0] = pc.get(JAVA_INT, 0); - return addr; - } finally { - stack.setPointer(stackPointer); - } - } + @Entrypoint("stbi_load") + MemorySegment nload(MemorySegment filename, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels); - public static MemorySegment nload16FromCallbacks(MemorySegment clbk, MemorySegment user, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { - try { - return (MemorySegment) stbi_load_16_from_callbacks.invokeExact(clbk, user, x, y, channelsInFile, desiredChannels); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_load") + MemorySegment load(String filename, @Ref int[] x, @Ref int[] y, @Ref int[] channelsInFile, int desiredChannels); - public static MemorySegment load16FromCallbacks(STBIIoCallbacks clbk, MemorySegment user, int[] x, int[] y, int[] channelsInFile, int desiredChannels) { - var stack = MemoryStack.stackGet(); - long stackPointer = stack.getPointer(); - try { - var px = stack.callocInt(); - var py = stack.callocInt(); - var pc = stack.callocInt(); - var addr = nload16FromCallbacks(clbk.address(), user, px, py, pc, desiredChannels); - x[0] = px.get(JAVA_INT, 0); - y[0] = py.get(JAVA_INT, 0); - channelsInFile[0] = pc.get(JAVA_INT, 0); - return addr; - } finally { - stack.setPointer(stackPointer); - } - } + @Entrypoint("stbi_load_16") + MemorySegment nload16(MemorySegment filename, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels); - public static MemorySegment nload16FromMemory(MemorySegment buffer, int len, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { - try { - return (MemorySegment) stbi_load_16_from_memory.invokeExact(buffer, len, x, y, channelsInFile, desiredChannels); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_load_16") + MemorySegment load16(String filename, @Ref int[] x, @Ref int[] y, @Ref int[] channelsInFile, int desiredChannels); - public static MemorySegment load16FromMemory(MemorySegment buffer, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { - return nload16FromMemory(buffer, (int) buffer.byteSize(), x, y, channelsInFile, desiredChannels); - } + @Entrypoint("stbi_load_16_from_callbacks") + MemorySegment nload16FromCallbacks(MemorySegment clbk, MemorySegment user, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels); - public static MemorySegment load16FromMemory(SegmentAllocator allocator, byte[] buffer, int[] x, int[] y, int[] channelsInFile, int desiredChannels) { - var px = allocator.allocate(JAVA_INT); - var py = allocator.allocate(JAVA_INT); - var pc = allocator.allocate(JAVA_INT); - var addr = load16FromMemory(allocator.allocateFrom(JAVA_BYTE, buffer), px, py, pc, desiredChannels); - x[0] = px.get(JAVA_INT, 0); - y[0] = py.get(JAVA_INT, 0); - channelsInFile[0] = pc.get(JAVA_INT, 0); - return addr; - } + @Entrypoint("stbi_load_16_from_callbacks") + MemorySegment load16FromCallbacks(STBIIoCallbacks clbk, MemorySegment user, @Ref int[] x, @Ref int[] y, @Ref int[] channelsInFile, int desiredChannels); - public static MemorySegment nloadFromCallbacks(MemorySegment clbk, MemorySegment user, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { - try { - return (MemorySegment) stbi_load_from_callbacks.invokeExact(clbk, user, x, y, channelsInFile, desiredChannels); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_load_16_from_memory") + MemorySegment nload16FromMemory(MemorySegment buffer, int len, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels); - public static MemorySegment loadFromCallbacks(STBIIoCallbacks clbk, MemorySegment user, int[] x, int[] y, int[] channelsInFile, int desiredChannels) { - var stack = MemoryStack.stackGet(); - long stackPointer = stack.getPointer(); - try { - var px = stack.callocInt(); - var py = stack.callocInt(); - var pc = stack.callocInt(); - var addr = nloadFromCallbacks(clbk.address(), user, px, py, pc, desiredChannels); - x[0] = px.get(JAVA_INT, 0); - y[0] = py.get(JAVA_INT, 0); - channelsInFile[0] = pc.get(JAVA_INT, 0); - return addr; - } finally { - stack.setPointer(stackPointer); - } + @Skip + default MemorySegment load16FromMemory(MemorySegment buffer, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { + return nload16FromMemory(buffer, Math.toIntExact(buffer.byteSize()), x, y, channelsInFile, desiredChannels); } - public static MemorySegment nloadFromFile(MemorySegment f, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { - try { - return (MemorySegment) stbi_load_from_file.invokeExact(f, x, y, channelsInFile, desiredChannels); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_load_16_from_memory") + MemorySegment load16FromMemory(SegmentAllocator allocator, int len, byte[] buffer, @Ref int[] x, @Ref int[] y, @Ref int[] channelsInFile, int desiredChannels); - public static MemorySegment loadFromFile(MemorySegment f, int[] x, int[] y, int[] channelsInFile, int desiredChannels) { - var stack = MemoryStack.stackGet(); - long stackPointer = stack.getPointer(); - try { - var px = stack.callocInt(); - var py = stack.callocInt(); - var pc = stack.callocInt(); - var addr = nloadFromFile(f, px, py, pc, desiredChannels); - x[0] = px.get(JAVA_INT, 0); - y[0] = py.get(JAVA_INT, 0); - channelsInFile[0] = pc.get(JAVA_INT, 0); - return addr; - } finally { - stack.setPointer(stackPointer); - } + @Skip + default MemorySegment load16FromMemory(SegmentAllocator allocator, byte[] buffer, @Ref int[] x, @Ref int[] y, @Ref int[] channelsInFile, int desiredChannels) { + return load16FromMemory(allocator, buffer.length, buffer, x, y, channelsInFile, desiredChannels); } - public static MemorySegment nloadFromFile16(MemorySegment f, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { - try { - return (MemorySegment) stbi_load_from_file_16.invokeExact(f, x, y, channelsInFile, desiredChannels); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_load_from_callbacks") + MemorySegment nloadFromCallbacks(MemorySegment clbk, MemorySegment user, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels); - public static MemorySegment loadFromFile16(MemorySegment f, int[] x, int[] y, int[] channelsInFile, int desiredChannels) { - var stack = MemoryStack.stackGet(); - long stackPointer = stack.getPointer(); - try { - var px = stack.callocInt(); - var py = stack.callocInt(); - var pc = stack.callocInt(); - var addr = nloadFromFile16(f, px, py, pc, desiredChannels); - x[0] = px.get(JAVA_INT, 0); - y[0] = py.get(JAVA_INT, 0); - channelsInFile[0] = pc.get(JAVA_INT, 0); - return addr; - } finally { - stack.setPointer(stackPointer); - } - } + @Entrypoint("stbi_load_from_callbacks") + MemorySegment loadFromCallbacks(STBIIoCallbacks clbk, MemorySegment user, @Ref int[] x, @Ref int[] y, @Ref int[] channelsInFile, int desiredChannels); - public static MemorySegment nloadFromMemory(MemorySegment buffer, int len, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { - try { - return (MemorySegment) stbi_load_from_memory.invokeExact(buffer, len, x, y, channelsInFile, desiredChannels); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_load_from_file") + MemorySegment nloadFromFile(MemorySegment f, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels); - public static MemorySegment loadFromMemory(MemorySegment buffer, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { - return nloadFromMemory(buffer, (int) buffer.byteSize(), x, y, channelsInFile, desiredChannels); - } + @Entrypoint("stbi_load_from_file") + MemorySegment loadFromFile(MemorySegment f, @Ref int[] x, @Ref int[] y, @Ref int[] channelsInFile, int desiredChannels); - public static MemorySegment loadFromMemory(SegmentAllocator allocator, byte[] buffer, int[] x, int[] y, int[] channelsInFile, int desiredChannels) { - var px = allocator.allocate(JAVA_INT); - var py = allocator.allocate(JAVA_INT); - var pc = allocator.allocate(JAVA_INT); - var addr = nloadFromMemory(allocator.allocateFrom(JAVA_BYTE, buffer), buffer.length, px, py, pc, desiredChannels); - x[0] = px.get(JAVA_INT, 0); - y[0] = py.get(JAVA_INT, 0); - channelsInFile[0] = pc.get(JAVA_INT, 0); - return addr; - } + @Entrypoint("stbi_load_from_file_16") + MemorySegment nloadFromFile16(MemorySegment f, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels); - public static MemorySegment nloadGifFromMemory(MemorySegment buffer, int len, MemorySegment delays, MemorySegment x, MemorySegment y, MemorySegment z, MemorySegment comp, int reqComp) { - try { - return (MemorySegment) stbi_load_gif_from_memory.invokeExact(buffer, len, delays, x, y, z, comp, reqComp); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_load_from_file_16") + MemorySegment loadFromFile16(MemorySegment f, @Ref int[] x, @Ref int[] y, @Ref int[] channelsInFile, int desiredChannels); - public static MemorySegment loadGifFromMemory(MemorySegment buffer, MemorySegment delays, MemorySegment x, MemorySegment y, MemorySegment z, MemorySegment comp, int reqComp) { - return nloadGifFromMemory(buffer, (int) buffer.byteSize(), delays, x, y, z, comp, reqComp); - } + @Entrypoint("stbi_load_from_memory") + MemorySegment nloadFromMemory(MemorySegment buffer, int len, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels); - public static MemorySegment loadGifFromMemory(SegmentAllocator allocator, byte[] buffer, int[][] delays, int[] x, int[] y, int[] z, int[] comp, int reqComp) { - var pd = allocator.allocate(ADDRESS); - var px = allocator.allocate(JAVA_INT); - var py = allocator.allocate(JAVA_INT); - var pz = allocator.allocate(JAVA_INT); - var pc = allocator.allocate(JAVA_INT); - var addr = loadGifFromMemory(allocator.allocateFrom(JAVA_BYTE, buffer), pd, px, py, pz, pc, reqComp); - x[0] = px.get(JAVA_INT, 0); - y[0] = py.get(JAVA_INT, 0); - final int layers = pz.get(JAVA_INT, 0); - z[0] = layers; - comp[0] = pc.get(JAVA_INT, 0); - delays[0] = RuntimeHelper.toArray(pd.get(ADDRESS.withTargetLayout(MemoryLayout.sequenceLayout(layers, JAVA_INT)), 0), new int[layers]); - return addr; + @Skip + default MemorySegment loadFromMemory(MemorySegment buffer, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { + return nloadFromMemory(buffer, Math.toIntExact(buffer.byteSize()), x, y, channelsInFile, desiredChannels); } - public static MemorySegment nloadf(MemorySegment filename, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { - try { - return (MemorySegment) stbi_loadf.invokeExact(filename, x, y, channelsInFile, desiredChannels); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_load_from_memory") + MemorySegment loadFromMemory(SegmentAllocator allocator, int len, byte[] buffer, @Ref int[] x, @Ref int[] y, @Ref int[] channelsInFile, int desiredChannels); - public static MemorySegment loadf(String filename, int[] x, int[] y, int[] channelsInFile, int desiredChannels) { - final MemoryStack stack = MemoryStack.stackGet(); - final long stackPointer = stack.getPointer(); - try { - var px = stack.allocate(JAVA_INT); - var py = stack.allocate(JAVA_INT); - var pc = stack.allocate(JAVA_INT); - var addr = nloadf(stack.allocateFrom(filename), px, py, pc, desiredChannels); - x[0] = px.get(JAVA_INT, 0); - y[0] = py.get(JAVA_INT, 0); - channelsInFile[0] = pc.get(JAVA_INT, 0); - return addr; - } finally { - stack.setPointer(stackPointer); - } + @Skip + default MemorySegment loadFromMemory(SegmentAllocator allocator, byte[] buffer, @Ref int[] x, @Ref int[] y, @Ref int[] channelsInFile, int desiredChannels) { + return loadFromMemory(allocator, buffer.length, buffer, x, y, channelsInFile, desiredChannels); } - public static MemorySegment nloadfFromCallbacks(MemorySegment clbk, MemorySegment user, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { - try { - return (MemorySegment) stbi_loadf_from_callbacks.invokeExact(clbk, user, x, y, channelsInFile, desiredChannels); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Entrypoint("stbi_load_gif_from_memory") + MemorySegment nloadGifFromMemory(MemorySegment buffer, int len, MemorySegment delays, MemorySegment x, MemorySegment y, MemorySegment z, MemorySegment comp, int reqComp); + + @Skip + default MemorySegment loadGifFromMemory(MemorySegment buffer, MemorySegment delays, MemorySegment x, MemorySegment y, MemorySegment z, MemorySegment comp, int reqComp) { + return nloadGifFromMemory(buffer, Math.toIntExact(buffer.byteSize()), delays, x, y, z, comp, reqComp); } - public static MemorySegment loadfFromCallbacks(STBIIoCallbacks clbk, MemorySegment user, int[] x, int[] y, int[] channelsInFile, int desiredChannels) { - var stack = MemoryStack.stackGet(); - long stackPointer = stack.getPointer(); - try { - var px = stack.callocInt(); - var py = stack.callocInt(); - var pc = stack.callocInt(); - var addr = nloadfFromCallbacks(clbk.address(), user, px, py, pc, desiredChannels); - x[0] = px.get(JAVA_INT, 0); - y[0] = py.get(JAVA_INT, 0); - channelsInFile[0] = pc.get(JAVA_INT, 0); + @Skip + default MemorySegment loadGifFromMemory(SegmentAllocator allocator, byte[] buffer, @Ref int[][] delays, @Ref int[] x, @Ref int[] y, @Ref int[] z, @Ref int[] comp, int reqComp) { + try (MemoryStack stack = MemoryStack.stackPush()) { + var pd = stack.allocate(ValueLayout.ADDRESS); + var px = stack.ints(x); + var py = stack.ints(y); + var pz = stack.ints(z); + var pc = stack.ints(comp); + var addr = loadGifFromMemory(allocator.allocateFrom(ValueLayout.JAVA_BYTE, buffer), pd, px, py, pz, pc, reqComp); + Unmarshal.copy(px, x); + Unmarshal.copy(py, y); + Unmarshal.copy(pz, z); + Unmarshal.copy(pc, comp); + final int layers = z[0]; + final int[] refDelays = new int[layers]; + Unmarshal.copy(pd.get(ValueLayout.ADDRESS, 0L).reinterpret(layers), refDelays); + delays[0] = refDelays; return addr; - } finally { - stack.setPointer(stackPointer); } } - public static MemorySegment nloadfFromFile(MemorySegment f, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { - try { - return (MemorySegment) stbi_loadf_from_file.invokeExact(f, x, y, channelsInFile, desiredChannels); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_loadf") + MemorySegment nloadf(MemorySegment filename, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels); - public static MemorySegment loadfFromFile(MemorySegment f, int[] x, int[] y, int[] channelsInFile, int desiredChannels) { - var stack = MemoryStack.stackGet(); - long stackPointer = stack.getPointer(); - try { - var px = stack.callocInt(); - var py = stack.callocInt(); - var pc = stack.callocInt(); - var addr = nloadfFromFile(f, px, py, pc, desiredChannels); - x[0] = px.get(JAVA_INT, 0); - y[0] = py.get(JAVA_INT, 0); - channelsInFile[0] = pc.get(JAVA_INT, 0); - return addr; - } finally { - stack.setPointer(stackPointer); - } - } + @Entrypoint("stbi_loadf") + MemorySegment loadf(String filename, int[] x, int[] y, int[] channelsInFile, int desiredChannels); - public static MemorySegment nloadfFromMemory(MemorySegment buffer, int len, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { - try { - return (MemorySegment) stbi_loadf_from_memory.invokeExact(buffer, len, x, y, channelsInFile, desiredChannels); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_loadf_from_callbacks") + MemorySegment nloadfFromCallbacks(MemorySegment clbk, MemorySegment user, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels); - public static MemorySegment loadfFromMemory(MemorySegment buffer, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { - return nloadfFromMemory(buffer, (int) buffer.byteSize(), x, y, channelsInFile, desiredChannels); - } + @Entrypoint("stbi_loadf_from_callbacks") + MemorySegment loadfFromCallbacks(STBIIoCallbacks clbk, MemorySegment user, @Ref int[] x, @Ref int[] y, @Ref int[] channelsInFile, int desiredChannels); - public static MemorySegment loadfFromMemory(SegmentAllocator allocator, byte[] buffer, int[] x, int[] y, int[] channelsInFile, int desiredChannels) { - var px = allocator.allocate(JAVA_INT); - var py = allocator.allocate(JAVA_INT); - var pc = allocator.allocate(JAVA_INT); - var addr = nloadfFromMemory(allocator.allocateFrom(JAVA_BYTE, buffer), buffer.length, px, py, pc, desiredChannels); - x[0] = px.get(JAVA_INT, 0); - y[0] = py.get(JAVA_INT, 0); - channelsInFile[0] = pc.get(JAVA_INT, 0); - return addr; - } + @Entrypoint("stbi_loadf_from_file") + MemorySegment nloadfFromFile(MemorySegment f, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels); - public static void setFlipVerticallyOnLoad(boolean shouldFlip) { - try { - stbi_set_flip_vertically_on_load.invokeExact(shouldFlip ? 1 : 0); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_loadf_from_file") + MemorySegment loadfFromFile(MemorySegment f, @Ref int[] x, @Ref int[] y, @Ref int[] channelsInFile, int desiredChannels); - public static void setFlipVerticallyOnLoadThread(boolean shouldFlip) { - try { - stbi_set_flip_vertically_on_load_thread.invokeExact(shouldFlip ? 1 : 0); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_loadf_from_memory") + MemorySegment nloadfFromMemory(MemorySegment buffer, int len, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels); - public static void setUnpremultiplyOnLoad(boolean shouldUnpremultiply) { - try { - stbi_set_unpremultiply_on_load.invokeExact(shouldUnpremultiply ? 1 : 0); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Skip + default MemorySegment loadfFromMemory(MemorySegment buffer, MemorySegment x, MemorySegment y, MemorySegment channelsInFile, int desiredChannels) { + return nloadfFromMemory(buffer, Math.toIntExact(buffer.byteSize()), x, y, channelsInFile, desiredChannels); } - public static void setUnpremultiplyOnLoadThread(boolean shouldUnpremultiply) { - try { - stbi_set_unpremultiply_on_load_thread.invokeExact(shouldUnpremultiply ? 1 : 0); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_loadf_from_memory") + MemorySegment loadfFromMemory(SegmentAllocator allocator, int len, byte[] buffer, @Ref int[] x, @Ref int[] y, @Ref int[] channelsInFile, int desiredChannels); - public static int zlibDecodeBuffer(MemorySegment obuffer, int olen, MemorySegment ibuffer, int ilen) { - try { - return (int) stbi_zlib_decode_buffer.invokeExact(obuffer, olen, ibuffer, ilen); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } + @Skip + default MemorySegment loadfFromMemory(SegmentAllocator allocator, byte[] buffer, @Ref int[] x, @Ref int[] y, @Ref int[] channelsInFile, int desiredChannels) { + return loadfFromMemory(allocator, buffer.length, buffer, x, y, channelsInFile, desiredChannels); } - public static MemorySegment zlibDecodeMalloc(MemorySegment buffer, int len, MemorySegment outLen) { - try { - return (MemorySegment) stbi_zlib_decode_malloc.invokeExact(buffer, len, outLen); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_set_flip_vertically_on_load") + void setFlipVerticallyOnLoad(@Convert(Type.INT) boolean shouldFlip); - public static MemorySegment zlibDecodeMallocGuesssize(MemorySegment buffer, int len, int initialSize, MemorySegment outLen) { - try { - return (MemorySegment) stbi_zlib_decode_malloc_guesssize.invokeExact(buffer, len, initialSize, outLen); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_set_flip_vertically_on_load_thread") + void setFlipVerticallyOnLoadThread(@Convert(Type.INT) boolean shouldFlip); - public static MemorySegment zlibDecodeMallocGuesssizeHeaderflag(MemorySegment buffer, int len, int initialSize, MemorySegment outLen, int parseHeader) { - try { - return (MemorySegment) stbi_zlib_decode_malloc_guesssize_headerflag.invokeExact(buffer, len, initialSize, outLen, parseHeader); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_set_unpremultiply_on_load") + void nsetUnpremultiplyOnLoad(@Convert(Type.INT) boolean shouldUnpremultiply); - public static int zlibDecodeNoHeaderBuffer(MemorySegment obuffer, int olen, MemorySegment ibuffer, int ilen) { - try { - return (int) stbi_zlib_decode_noheader_buffer.invokeExact(obuffer, olen, ibuffer, ilen); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_set_unpremultiply_on_load_thread") + void nsetUnpremultiplyOnLoadThread(@Convert(Type.INT) boolean shouldUnpremultiply); - public static MemorySegment zlibDecodeNoheaderMalloc(MemorySegment buffer, int len, MemorySegment outLen) { - try { - return (MemorySegment) stbi_zlib_decode_noheader_malloc.invokeExact(buffer, len, outLen); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_zlib_decode_buffer") + int zlibDecodeBuffer(MemorySegment obuffer, int olen, MemorySegment ibuffer, int ilen); + + @Entrypoint("stbi_zlib_decode_malloc") + MemorySegment zlibDecodeMalloc(MemorySegment buffer, int len, MemorySegment outLen); + + @Entrypoint("stbi_zlib_decode_malloc_guesssize") + MemorySegment zlibDecodeMallocGuesssize(MemorySegment buffer, int len, int initialSize, MemorySegment outLen); + + @Entrypoint("stbi_zlib_decode_malloc_guesssize_headerflag") + MemorySegment zlibDecodeMallocGuesssizeHeaderflag(MemorySegment buffer, int len, int initialSize, MemorySegment outLen, int parseHeader); + + @Entrypoint("stbi_zlib_decode_noheader_buffer") + int zlibDecodeNoHeaderBuffer(MemorySegment obuffer, int olen, MemorySegment ibuffer, int ilen); + + @Entrypoint("stbi_zlib_decode_noheader_malloc") + MemorySegment zlibDecodeNoheaderMalloc(MemorySegment buffer, int len, MemorySegment outLen); } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBImageResize.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBImageResize.java deleted file mode 100644 index 1b2aa331..00000000 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBImageResize.java +++ /dev/null @@ -1,367 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2022-2023 Overrun Organization - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - */ - -package overrungl.stb; - -import overrungl.internal.RuntimeHelper; - -import java.lang.foreign.MemorySegment; -import java.lang.foreign.SegmentAllocator; -import java.lang.invoke.MethodHandle; - -import static java.lang.foreign.ValueLayout.*; -import static overrungl.FunctionDescriptors.*; -import static overrungl.stb.Handles.downcall; - -/** - * The STB image resizer. - * - * @author squid233 - * @since 0.1.0 - */ -public final class STBImageResize { - private static final MethodHandle - stbir_resize = downcall("stbir_resize", PIIIPIIIIIIIIIIIIPI), - stbir_resize_float = downcall("stbir_resize_float", PIIIPIIIII), - stbir_resize_float_generic = downcall("stbir_resize_float_generic", PIIIPIIIIIIIIIPI), - stbir_resize_region = downcall("stbir_resize_region", PIIIPIIIIIIIIIIIIPFFFFI), - stbir_resize_subpixel = downcall("stbir_resize_subpixel", PIIIPIIIIIIIIIIIIPFFFFI), - stbir_resize_uint16_generic = downcall("stbir_resize_uint16_generic", PIIIPIIIIIIIIIPI), - stbir_resize_uint8 = downcall("stbir_resize_uint8", PIIIPIIIII), - stbir_resize_uint8_generic = downcall("stbir_resize_uint8_generic", PIIIPIIIIIIIIIPI), - stbir_resize_uint8_srgb = downcall("stbir_resize_uint8_srgb", PIIIPIIIIIII), - stbir_resize_uint8_srgb_edgemode = downcall("stbir_resize_uint8_srgb_edgemode", PIIIPIIIIIIII); - - private STBImageResize() { - throw new IllegalStateException("Do not construct instance"); - } - - public static boolean resizeUint8(MemorySegment inputPixels, int inputW, int inputH, int inputStrideInBytes, - MemorySegment outputPixels, int outputW, int outputH, int outputStrideInBytes, - int numChannels) { - try { - return (int) stbir_resize_uint8.invokeExact(inputPixels, inputW, inputH, inputStrideInBytes, - outputPixels, outputW, outputH, outputStrideInBytes, - numChannels) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } - - public static boolean resizeUint8(SegmentAllocator allocator, - byte[] inputPixels, int inputW, int inputH, int inputStrideInBytes, - byte[] outputPixels, int outputW, int outputH, int outputStrideInBytes, - int numChannels) { - var seg = allocator.allocateFrom(JAVA_BYTE, outputPixels); - boolean b = resizeUint8(allocator.allocateFrom(JAVA_BYTE, inputPixels), inputW, inputH, inputStrideInBytes, - seg, outputW, outputH, outputStrideInBytes, - numChannels); - RuntimeHelper.toArray(seg, outputPixels); - return b; - } - - public static boolean resizeFloat(MemorySegment inputPixels, int inputW, int inputH, int inputStrideInBytes, - MemorySegment outputPixels, int outputW, int outputH, int outputStrideInBytes, - int numChannels) { - try { - return (int) stbir_resize_float.invokeExact(inputPixels, inputW, inputH, inputStrideInBytes, - outputPixels, outputW, outputH, outputStrideInBytes, - numChannels) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } - - public static boolean resizeFloat(SegmentAllocator allocator, - float[] inputPixels, int inputW, int inputH, int inputStrideInBytes, - float[] outputPixels, int outputW, int outputH, int outputStrideInBytes, - int numChannels) { - var seg = allocator.allocateFrom(JAVA_FLOAT, outputPixels); - boolean b = resizeFloat(allocator.allocateFrom(JAVA_FLOAT, inputPixels), inputW, inputH, inputStrideInBytes, - seg, outputW, outputH, outputStrideInBytes, - numChannels); - RuntimeHelper.toArray(seg, outputPixels); - return b; - } - - public static boolean resizeUint8Srgb(MemorySegment inputPixels, int inputW, int inputH, int inputStrideInBytes, - MemorySegment outputPixels, int outputW, int outputH, int outputStrideInBytes, - int numChannels, int alphaChannel, int flags) { - try { - return (int) stbir_resize_uint8_srgb.invokeExact(inputPixels, inputW, inputH, inputStrideInBytes, - outputPixels, outputW, outputH, outputStrideInBytes, - numChannels, alphaChannel, flags) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } - - public static boolean resizeUint8Srgb(SegmentAllocator allocator, - byte[] inputPixels, int inputW, int inputH, int inputStrideInBytes, - byte[] outputPixels, int outputW, int outputH, int outputStrideInBytes, - int numChannels, int alphaChannel, int flags) { - var seg = allocator.allocateFrom(JAVA_BYTE, outputPixels); - boolean b = resizeUint8Srgb(allocator.allocateFrom(JAVA_BYTE, inputPixels), inputW, inputH, inputStrideInBytes, - seg, outputW, outputH, outputStrideInBytes, - numChannels, alphaChannel, flags); - RuntimeHelper.toArray(seg, outputPixels); - return b; - } - - public static boolean resizeUint8SrgbEdgemode(MemorySegment inputPixels, int inputW, int inputH, int inputStrideInBytes, - MemorySegment outputPixels, int outputW, int outputH, int outputStrideInBytes, - int numChannels, int alphaChannel, int flags, - int edgeWrapMode) { - try { - return (int) stbir_resize_uint8_srgb_edgemode.invokeExact(inputPixels, inputW, inputH, inputStrideInBytes, - outputPixels, outputW, outputH, outputStrideInBytes, - numChannels, alphaChannel, flags, - edgeWrapMode) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } - - public static boolean resizeUint8SrgbEdgemode(SegmentAllocator allocator, - byte[] inputPixels, int inputW, int inputH, int inputStrideInBytes, - byte[] outputPixels, int outputW, int outputH, int outputStrideInBytes, - int numChannels, int alphaChannel, int flags, - STBIREdge edgeWrapMode) { - var seg = allocator.allocateFrom(JAVA_BYTE, outputPixels); - boolean b = resizeUint8SrgbEdgemode(allocator.allocateFrom(JAVA_BYTE, inputPixels), inputW, inputH, inputStrideInBytes, - seg, outputW, outputH, outputStrideInBytes, - numChannels, alphaChannel, flags, - edgeWrapMode.getValue()); - RuntimeHelper.toArray(seg, outputPixels); - return b; - } - - public static boolean resizeUint8Generic(MemorySegment inputPixels, int inputW, int inputH, int inputStrideInBytes, - MemorySegment outputPixels, int outputW, int outputH, int outputStrideInBytes, - int numChannels, int alphaChannel, int flags, - int edgeWrapMode, int filter, int space, - MemorySegment allocContext) { - try { - return (int) stbir_resize_uint8_generic.invokeExact(inputPixels, inputW, inputH, inputStrideInBytes, - outputPixels, outputW, outputH, outputStrideInBytes, - numChannels, alphaChannel, flags, - edgeWrapMode, filter, space, - allocContext) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } - - public static boolean resizeUint8Generic(SegmentAllocator allocator, - byte[] inputPixels, int inputW, int inputH, int inputStrideInBytes, - byte[] outputPixels, int outputW, int outputH, int outputStrideInBytes, - int numChannels, int alphaChannel, int flags, - STBIREdge edgeWrapMode, STBIRFilter filter, STBIRColorspace space, - MemorySegment allocContext) { - var seg = allocator.allocateFrom(JAVA_BYTE, outputPixels); - boolean b = resizeUint8Generic(allocator.allocateFrom(JAVA_BYTE, inputPixels), inputW, inputH, inputStrideInBytes, - seg, outputW, outputH, outputStrideInBytes, - numChannels, alphaChannel, flags, - edgeWrapMode.getValue(), filter.getValue(), space.ordinal(), - allocContext); - RuntimeHelper.toArray(seg, outputPixels); - return b; - } - - public static boolean resizeUint16Generic(MemorySegment inputPixels, int inputW, int inputH, int inputStrideInBytes, - MemorySegment outputPixels, int outputW, int outputH, int outputStrideInBytes, - int numChannels, int alphaChannel, int flags, - int edgeWrapMode, int filter, int space, - MemorySegment allocContext) { - try { - return (int) stbir_resize_uint16_generic.invokeExact(inputPixels, inputW, inputH, inputStrideInBytes, - outputPixels, outputW, outputH, outputStrideInBytes, - numChannels, alphaChannel, flags, - edgeWrapMode, filter, space, - allocContext) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } - - public static boolean resizeUint16Generic(SegmentAllocator allocator, - short[] inputPixels, int inputW, int inputH, int inputStrideInBytes, - short[] outputPixels, int outputW, int outputH, int outputStrideInBytes, - int numChannels, int alphaChannel, int flags, - STBIREdge edgeWrapMode, STBIRFilter filter, STBIRColorspace space, - MemorySegment allocContext) { - var seg = allocator.allocateFrom(JAVA_SHORT, outputPixels); - boolean b = resizeUint16Generic(allocator.allocateFrom(JAVA_SHORT, inputPixels), inputW, inputH, inputStrideInBytes, - seg, outputW, outputH, outputStrideInBytes, - numChannels, alphaChannel, flags, - edgeWrapMode.getValue(), filter.getValue(), space.ordinal(), - allocContext); - RuntimeHelper.toArray(seg, outputPixels); - return b; - } - - public static boolean resizeFloatGeneric(MemorySegment inputPixels, int inputW, int inputH, int inputStrideInBytes, - MemorySegment outputPixels, int outputW, int outputH, int outputStrideInBytes, - int numChannels, int alphaChannel, int flags, - int edgeWrapMode, int filter, int space, - MemorySegment allocContext) { - try { - return (int) stbir_resize_float_generic.invokeExact(inputPixels, inputW, inputH, inputStrideInBytes, - outputPixels, outputW, outputH, outputStrideInBytes, - numChannels, alphaChannel, flags, - edgeWrapMode, filter, space, - allocContext) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } - - public static boolean resizeFloatGeneric(SegmentAllocator allocator, - float[] inputPixels, int inputW, int inputH, int inputStrideInBytes, - float[] outputPixels, int outputW, int outputH, int outputStrideInBytes, - int numChannels, int alphaChannel, int flags, - STBIREdge edgeWrapMode, STBIRFilter filter, STBIRColorspace space, - MemorySegment allocContext) { - var seg = allocator.allocateFrom(JAVA_FLOAT, outputPixels); - boolean b = resizeFloatGeneric(allocator.allocateFrom(JAVA_FLOAT, inputPixels), inputW, inputH, inputStrideInBytes, - seg, outputW, outputH, outputStrideInBytes, - numChannels, alphaChannel, flags, - edgeWrapMode.getValue(), filter.getValue(), space.ordinal(), - allocContext); - RuntimeHelper.toArray(seg, outputPixels); - return b; - } - - public static boolean resize(MemorySegment inputPixels, int inputW, int inputH, int inputStrideInBytes, - MemorySegment outputPixels, int outputW, int outputH, int outputStrideInBytes, - int datatype, - int numChannels, int alphaChannel, int flags, - int edgeModeHorizontal, int edgeModeVertical, - int filterHorizontal, int filterVertical, - int space, MemorySegment allocContext) { - try { - return (int) stbir_resize.invokeExact(inputPixels, inputW, inputH, inputStrideInBytes, - outputPixels, outputW, outputH, outputStrideInBytes, - datatype, - numChannels, alphaChannel, flags, - edgeModeHorizontal, edgeModeVertical, - filterHorizontal, filterVertical, - space, allocContext) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } - - public static boolean resize(MemorySegment inputPixels, int inputW, int inputH, int inputStrideInBytes, - MemorySegment outputPixels, int outputW, int outputH, int outputStrideInBytes, - STBIRDatatype datatype, - int numChannels, int alphaChannel, int flags, - STBIREdge edgeModeHorizontal, STBIREdge edgeModeVertical, - STBIRFilter filterHorizontal, STBIRFilter filterVertical, - STBIRColorspace space, MemorySegment allocContext) { - return resize(inputPixels, inputW, inputH, inputStrideInBytes, - outputPixels, outputW, outputH, outputStrideInBytes, - datatype.ordinal(), - numChannels, alphaChannel, flags, - edgeModeHorizontal.getValue(), edgeModeVertical.getValue(), - filterHorizontal.getValue(), filterVertical.getValue(), - space.ordinal(), allocContext); - } - - public static boolean resizeSubpixel(MemorySegment inputPixels, int inputW, int inputH, int inputStrideInBytes, - MemorySegment outputPixels, int outputW, int outputH, int outputStrideInBytes, - int datatype, - int numChannels, int alphaChannel, int flags, - int edgeModeHorizontal, int edgeModeVertical, - int filterHorizontal, int filterVertical, - int space, MemorySegment allocContext, - float xScale, float yScale, - float xOffset, float yOffset) { - try { - return (int) stbir_resize_subpixel.invokeExact(inputPixels, inputW, inputH, inputStrideInBytes, - outputPixels, outputW, outputH, outputStrideInBytes, - datatype, - numChannels, alphaChannel, flags, - edgeModeHorizontal, edgeModeVertical, - filterHorizontal, filterVertical, - space, allocContext, - xScale, yScale, - xOffset, yOffset) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } - - public static boolean resizeSubpixel(MemorySegment inputPixels, int inputW, int inputH, int inputStrideInBytes, - MemorySegment outputPixels, int outputW, int outputH, int outputStrideInBytes, - STBIRDatatype datatype, - int numChannels, int alphaChannel, int flags, - STBIREdge edgeModeHorizontal, STBIREdge edgeModeVertical, - STBIRFilter filterHorizontal, STBIRFilter filterVertical, - STBIRColorspace space, MemorySegment allocContext, - float xScale, float yScale, - float xOffset, float yOffset) { - return resizeSubpixel(inputPixels, inputW, inputH, inputStrideInBytes, - outputPixels, outputW, outputH, outputStrideInBytes, - datatype.ordinal(), - numChannels, alphaChannel, flags, - edgeModeHorizontal.getValue(), edgeModeVertical.getValue(), - filterHorizontal.getValue(), filterVertical.getValue(), - space.ordinal(), allocContext, - xScale, yScale, - xOffset, yOffset); - } - - public static boolean resizeRegion(MemorySegment inputPixels, int inputW, int inputH, int inputStrideInBytes, - MemorySegment outputPixels, int outputW, int outputH, int outputStrideInBytes, - int datatype, - int numChannels, int alphaChannel, int flags, - int edgeModeHorizontal, int edgeModeVertical, - int filterHorizontal, int filterVertical, - int space, MemorySegment allocContext, - float s0, float t0, float s1, float t1) { - try { - return (int) stbir_resize_region.invokeExact(inputPixels, inputW, inputH, inputStrideInBytes, - outputPixels, outputW, outputH, outputStrideInBytes, - datatype, - numChannels, alphaChannel, flags, - edgeModeHorizontal, edgeModeVertical, - filterHorizontal, filterVertical, - space, allocContext, - s0, t0, s1, t1) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } - - public static boolean resizeRegion(MemorySegment inputPixels, int inputW, int inputH, int inputStrideInBytes, - MemorySegment outputPixels, int outputW, int outputH, int outputStrideInBytes, - STBIRDatatype datatype, - int numChannels, int alphaChannel, int flags, - STBIREdge edgeModeHorizontal, STBIREdge edgeModeVertical, - STBIRFilter filterHorizontal, STBIRFilter filterVertical, - STBIRColorspace space, MemorySegment allocContext, - float s0, float t0, float s1, float t1) { - return resizeRegion(inputPixels, inputW, inputH, inputStrideInBytes, - outputPixels, outputW, outputH, outputStrideInBytes, - datatype.ordinal(), - numChannels, alphaChannel, flags, - edgeModeHorizontal.getValue(), edgeModeVertical.getValue(), - filterHorizontal.getValue(), filterVertical.getValue(), - space.ordinal(), allocContext, - s0, t0, s1, t1); - } -} diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBImageResize2.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBImageResize2.java new file mode 100644 index 00000000..fd229e71 --- /dev/null +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBImageResize2.java @@ -0,0 +1,101 @@ +/* + * MIT License + * + * Copyright (c) 2024 Overrun Organization + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + */ + +package overrungl.stb; + +import overrun.marshal.Downcall; +import overrun.marshal.gen.Entrypoint; +import overrungl.NativeType; + +import java.lang.foreign.MemorySegment; + +/** + * The STB image resizer. + * + * @author squid233 + * @since 0.1.0 + */ +public interface STBImageResize2 { + /** + * The instance of STBImageResize2. + */ + STBImageResize2 INSTANCE = Downcall.load(Handles.lookup); + + //=============================================================== + // Simple-complexity API + // + // If output_pixels is NULL (0), then we will allocate the buffer and return it to you. + //-------------------------------- + + @Entrypoint("stbir_resize_uint8_srgb") + MemorySegment resizeUint8Srgb(@NativeType("const unsigned char *") MemorySegment input_pixels, int input_w, int input_h, int input_stride_in_bytes, + @NativeType("unsigned char *") MemorySegment output_pixels, int output_w, int output_h, int output_stride_in_bytes, + STBIRPixelLayout pixel_type); + + @Entrypoint("stbir_resize_uint8_linear") + @NativeType("unsigned char *") + MemorySegment resizeUint8Linear(@NativeType("const unsigned char *") MemorySegment input_pixels, int input_w, int input_h, int input_stride_in_bytes, + @NativeType("unsigned char *") MemorySegment output_pixels, int output_w, int output_h, int output_stride_in_bytes, + STBIRPixelLayout pixel_type); + + @Entrypoint("stbir_resize_uint8_linear") + @NativeType("float *") + MemorySegment resizeFloatLinear(@NativeType("const float *") MemorySegment input_pixels, int input_w, int input_h, int input_stride_in_bytes, + @NativeType("float *") MemorySegment output_pixels, int output_w, int output_h, int output_stride_in_bytes, + STBIRPixelLayout pixel_type); + + //=============================================================== + // Medium-complexity API + // + // This extends the easy-to-use API as follows: + // + // * Can specify the datatype - U8, U8_SRGB, U16, FLOAT, HALF_FLOAT + // * Edge wrap can selected explicitly + // * Filter can be selected explicitly + //-------------------------------- + + // medium api + @Entrypoint("stbir_resize") + @NativeType("void *") + MemorySegment resize(@NativeType("const void *") MemorySegment input_pixels , int input_w , int input_h, int input_stride_in_bytes, + @NativeType("void *") MemorySegment output_pixels, int output_w, int output_h, int output_stride_in_bytes, + STBIRPixelLayout pixel_layout, STBIRDatatype data_type, + STBIREdge edge, STBIRFilter filter ); + + //=============================================================== + // Extended-complexity API + // + // This API exposes all resize functionality. + // + // * Separate filter types for each axis + // * Separate edge modes for each axis + // * Separate input and output data types + // * Can specify regions with subpixel correctness + // * Can specify alpha flags + // * Can specify a memory callback + // * Can specify a callback data type for pixel input and output + // * Can be threaded for a single resize + // * Can be used to resize many frames without recalculating the sampler info + // + // Use this API as follows: + // 1) Call the stbir_resize_init function on a local STBIR_RESIZE structure + // 2) Call any of the stbir_set functions + // 3) Optionally call stbir_build_samplers() if you are going to resample multiple times + // with the same input and output dimensions (like resizing video frames) + // 4) Resample by calling stbir_resize_extended(). + // 5) Call stbir_free_samplers() if you called stbir_build_samplers() + //-------------------------------- +} diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBImageWrite.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBImageWrite.java index 22902258..3a46b267 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBImageWrite.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBImageWrite.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2022-2023 Overrun Organization + * Copyright (c) 2022-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,17 +16,15 @@ package overrungl.stb; -import overrungl.internal.RuntimeHelper; -import overrungl.util.MemoryStack; +import overrun.marshal.Downcall; +import overrun.marshal.gen.Convert; +import overrun.marshal.gen.Entrypoint; +import overrun.marshal.gen.Skip; +import overrun.marshal.gen.Type; import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; import java.lang.foreign.SegmentAllocator; -import java.lang.invoke.MethodHandle; - -import static java.lang.foreign.ValueLayout.*; -import static overrungl.FunctionDescriptors.*; -import static overrungl.stb.Handles.*; /** * The STB image writer. @@ -34,261 +32,128 @@ * @author squid233 * @since 0.1.0 */ -public final class STBImageWrite { - private static final MethodHandle - stbi_flip_vertically_on_write = downcall("stbi_flip_vertically_on_write", IV), - stbi_get_write_force_png_filter = downcall("stbi_get_write_force_png_filter", I), - stbi_get_write_png_compression_level = downcall("stbi_get_write_png_compression_level", I), - stbi_get_write_tga_with_rle = downcall("stbi_get_write_tga_with_rle", I), - stbi_set_write_force_png_filter = downcall("stbi_set_write_force_png_filter", IV), - stbi_set_write_png_compression_level = downcall("stbi_set_write_png_compression_level", IV), - stbi_set_write_tga_with_rle = downcall("stbi_set_write_tga_with_rle", IV), - stbi_write_bmp = downcall("stbi_write_bmp", PIIIPI), - stbi_write_bmp_to_func = downcall("stbi_write_bmp_to_func", PPIIIP), - stbi_write_hdr = downcall("stbi_write_hdr", PIIIPI), - stbi_write_hdr_to_func = downcall("stbi_write_hdr_to_func", PPIIIP), - stbi_write_jpg = downcall("stbi_write_jpg", PIIIPII), - stbi_write_jpg_to_func = downcall("stbi_write_jpg_to_func", PPIIIPI), - stbi_write_png = downcall("stbi_write_png", PIIIPII), - stbi_write_png_to_func = downcall("stbi_write_png_to_func", PPIIIPI), - stbi_write_png_to_mem = downcall("stbi_write_png_to_mem", PIIIIPp), - stbi_write_tga = downcall("stbi_write_tga", PIIIP), - stbi_write_tga_to_func = downcall("stbi_write_tga_to_func", PPIIIP), - stbi_zlib_compress = downcall("stbi_zlib_compress", PIPIp); - - private STBImageWrite() { - throw new IllegalStateException("Do not construct instance"); - } +public interface STBImageWrite { + /** + * The instance of STBImageWrite. + */ + STBImageWrite INSTANCE = Downcall.load(Handles.lookup); - public static boolean getWriteTgaWithRle() { - try { - return (int) stbi_get_write_tga_with_rle.invokeExact() != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_get_write_tga_with_rle") + boolean getWriteTgaWithRle(); - public static int getWritePngCompressionLevel() { - try { - return (int) stbi_get_write_png_compression_level.invokeExact(); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_get_write_png_compression_level") + int getWritePngCompressionLevel(); - public static int getWriteForcePngFilter() { - try { - return (int) stbi_get_write_force_png_filter.invokeExact(); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_get_write_force_png_filter") + int getWriteForcePngFilter(); - public static void setWriteTgaWithRle(boolean rle) { - try { - stbi_set_write_tga_with_rle.invokeExact(rle ? 1 : 0); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_set_write_tga_with_rle") + void setWriteTgaWithRle(@Convert(Type.INT) boolean rle); - public static void setWritePngCompressionLevel(int level) { - try { - stbi_set_write_png_compression_level.invokeExact(level); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_set_write_png_compression_level") + void setWritePngCompressionLevel(int level); - public static void setWriteForcePngFilter(int filter) { - try { - stbi_set_write_force_png_filter.invokeExact(filter); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_set_write_force_png_filter") + void setWriteForcePngFilter(int filter); - public static boolean npng(MemorySegment filename, int w, int h, int comp, MemorySegment data, int strideInBytes) { - try { - return (int) stbi_write_png.invokeExact(filename, w, h, comp, data, strideInBytes) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_write_png") + boolean npng(MemorySegment filename, int w, int h, int comp, MemorySegment data, int strideInBytes); - public static boolean nbmp(MemorySegment filename, int w, int h, int comp, MemorySegment data) { - try { - return (int) stbi_write_bmp.invokeExact(filename, w, h, comp, data) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_write_bmp") + boolean nbmp(MemorySegment filename, int w, int h, int comp, MemorySegment data); - public static boolean ntga(MemorySegment filename, int w, int h, int comp, MemorySegment data) { - try { - return (int) stbi_write_tga.invokeExact(filename, w, h, comp, data) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_write_tga") + boolean ntga(MemorySegment filename, int w, int h, int comp, MemorySegment data); - public static boolean nhdr(MemorySegment filename, int w, int h, int comp, MemorySegment data) { - try { - return (int) stbi_write_hdr.invokeExact(filename, w, h, comp, data) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_write_hdr") + boolean nhdr(MemorySegment filename, int w, int h, int comp, MemorySegment data); - public static boolean njpg(MemorySegment filename, int x, int y, int comp, MemorySegment data, int quality) { - try { - return (int) stbi_write_jpg.invokeExact(filename, x, y, comp, data, quality) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_write_jpg") + boolean njpg(MemorySegment filename, int x, int y, int comp, MemorySegment data, int quality); - public static boolean png(String filename, int w, int h, int comp, MemorySegment data, int strideInBytes) { - final MemoryStack stack = MemoryStack.stackGet(); - final long stackPointer = stack.getPointer(); - try { - return npng(stack.allocateFrom(filename), w, h, comp, data, strideInBytes); - } finally { - stack.setPointer(stackPointer); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_write_png") + boolean png(String filename, int w, int h, int comp, MemorySegment data, int strideInBytes); - public static boolean bmp(String filename, int w, int h, int comp, MemorySegment data) { - final MemoryStack stack = MemoryStack.stackGet(); - final long stackPointer = stack.getPointer(); - try { - return nbmp(stack.allocateFrom(filename), w, h, comp, data); - } finally { - stack.setPointer(stackPointer); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_write_bmp") + boolean bmp(String filename, int w, int h, int comp, MemorySegment data); - public static boolean tga(String filename, int w, int h, int comp, MemorySegment data) { - final MemoryStack stack = MemoryStack.stackGet(); - final long stackPointer = stack.getPointer(); - try { - return ntga(stack.allocateFrom(filename), w, h, comp, data); - } finally { - stack.setPointer(stackPointer); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_write_tga") + boolean tga(String filename, int w, int h, int comp, MemorySegment data); - public static boolean hdr(SegmentAllocator allocator, String filename, int w, int h, int comp, float[] data) { - return nhdr(allocator.allocateFrom(filename), w, h, comp, allocator.allocateFrom(JAVA_FLOAT, data)); - } + @Convert(Type.INT) + @Entrypoint("stbi_write_hdr") + boolean hdr(SegmentAllocator allocator, String filename, int w, int h, int comp, float[] data); - public static boolean jpg(String filename, int x, int y, int comp, MemorySegment data, int quality) { - final MemoryStack stack = MemoryStack.stackGet(); - final long stackPointer = stack.getPointer(); - try { - return njpg(stack.allocateFrom(filename), x, y, comp, data, quality); - } finally { - stack.setPointer(stackPointer); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_write_jpg") + boolean jpg(String filename, int x, int y, int comp, MemorySegment data, int quality); - public static boolean npngToFunc(MemorySegment func, MemorySegment context, int w, int h, int comp, MemorySegment data, int strideInBytes) { - try { - return (int) stbi_write_png_to_func.invokeExact(func, context, w, h, comp, data, strideInBytes) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_write_png_to_func") + boolean npngToFunc(MemorySegment func, MemorySegment context, int w, int h, int comp, MemorySegment data, int strideInBytes); - public static boolean nbmpToFunc(MemorySegment func, MemorySegment context, int w, int h, int comp, MemorySegment data) { - try { - return (int) stbi_write_bmp_to_func.invokeExact(func, context, w, h, comp, data) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_write_bmp_to_func") + boolean nbmpToFunc(MemorySegment func, MemorySegment context, int w, int h, int comp, MemorySegment data); - public static boolean ntgaToFunc(MemorySegment func, MemorySegment context, int w, int h, int comp, MemorySegment data) { - try { - return (int) stbi_write_tga_to_func.invokeExact(func, context, w, h, comp, data) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_write_tga_to_func") + boolean ntgaToFunc(MemorySegment func, MemorySegment context, int w, int h, int comp, MemorySegment data); - public static boolean nhdrToFunc(MemorySegment func, MemorySegment context, int w, int h, int comp, MemorySegment data) { - try { - return (int) stbi_write_hdr_to_func.invokeExact(func, context, w, h, comp, data) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_write_hdr_to_func") + boolean nhdrToFunc(MemorySegment func, MemorySegment context, int w, int h, int comp, MemorySegment data); - public static boolean njpgToFunc(MemorySegment func, MemorySegment context, int x, int y, int comp, MemorySegment data, int quality) { - try { - return (int) stbi_write_jpg_to_func.invokeExact(func, context, x, y, comp, data, quality) != 0; - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Convert(Type.INT) + @Entrypoint("stbi_write_jpg_to_func") + boolean njpgToFunc(MemorySegment func, MemorySegment context, int x, int y, int comp, MemorySegment data, int quality); - public static boolean pngToFunc(Arena arena, STBIWriteFunc func, MemorySegment context, int w, int h, int comp, MemorySegment data, int strideInBytes) { - return npngToFunc(func.address(arena), context, w, h, comp, data, strideInBytes); - } + @Convert(Type.INT) + @Entrypoint("stbi_write_png_to_func") + boolean pngToFunc(Arena arena, STBIWriteFunc func, MemorySegment context, int w, int h, int comp, MemorySegment data, int strideInBytes); - public static boolean bmpToFunc(Arena arena, STBIWriteFunc func, MemorySegment context, int w, int h, int comp, MemorySegment data) { - return nbmpToFunc(func.address(arena), context, w, h, comp, data); - } + @Convert(Type.INT) + @Entrypoint("stbi_write_bmp_to_func") + boolean bmpToFunc(Arena arena, STBIWriteFunc func, MemorySegment context, int w, int h, int comp, MemorySegment data); - public static boolean tgaToFunc(Arena arena, STBIWriteFunc func, MemorySegment context, int w, int h, int comp, MemorySegment data) { - return ntgaToFunc(func.address(arena), context, w, h, comp, data); - } + @Convert(Type.INT) + @Entrypoint("stbi_write_tga_to_func") + boolean tgaToFunc(Arena arena, STBIWriteFunc func, MemorySegment context, int w, int h, int comp, MemorySegment data); - public static boolean hdrToFunc(Arena arena, STBIWriteFunc func, MemorySegment context, int w, int h, int comp, float[] data) { - return nhdrToFunc(func.address(arena), context, w, h, comp, arena.allocateFrom(JAVA_FLOAT, data)); - } + @Convert(Type.INT) + @Entrypoint("stbi_write_hdr_to_func") + boolean hdrToFunc(Arena arena, STBIWriteFunc func, MemorySegment context, int w, int h, int comp, float[] data); - public static boolean jpgToFunc(Arena arena, STBIWriteFunc func, MemorySegment context, int x, int y, int comp, MemorySegment data, int quality) { - return njpgToFunc(func.address(arena), context, x, y, comp, data, quality); - } + @Convert(Type.INT) + @Entrypoint("stbi_write_jpg_to_func") + boolean jpgToFunc(Arena arena, STBIWriteFunc func, MemorySegment context, int x, int y, int comp, MemorySegment data, int quality); - public static void flipVerticallyOnWrite(boolean flip) { - try { - stbi_flip_vertically_on_write.invokeExact(flip ? 1 : 0); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_flip_vertically_on_write") + void flipVerticallyOnWrite(@Convert(Type.INT) boolean flip); - public static MemorySegment npngToMem(MemorySegment pixels, int strideInBytes, int x, int y, int n, MemorySegment outLen) { - try { - return (MemorySegment) stbi_write_png_to_mem.invokeExact(pixels, strideInBytes, x, y, n, outLen); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_write_png_to_mem") + MemorySegment npngToMem(MemorySegment pixels, int strideInBytes, int x, int y, int n, MemorySegment outLen); - public static byte[] pngToMem(SegmentAllocator allocator, byte[] pixels, int strideInBytes, int x, int y, int n, int[] outLen) { - var pl = allocator.allocate(JAVA_INT); - var p = npngToMem(allocator.allocateFrom(JAVA_BYTE, pixels), strideInBytes, x, y, n, pl); - final int len = pl.get(JAVA_INT, 0); - outLen[0] = len; - return RuntimeHelper.toArray(p, new byte[len]); - } + @Entrypoint("stbi_write_png_to_mem") + byte[] pngToMem(SegmentAllocator allocator, byte[] pixels, int strideInBytes, int x, int y, int n, int[] outLen); - public static MemorySegment nzlibCompress(MemorySegment data, int dataLen, MemorySegment outLen, int quality) { - try { - return (MemorySegment) stbi_zlib_compress.invokeExact(data, dataLen, outLen, quality); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + @Entrypoint("stbi_zlib_compress") + MemorySegment nzlibCompress(MemorySegment data, int dataLen, MemorySegment outLen, int quality); + + @Entrypoint("stbi_zlib_compress") + byte[] zlibCompress(SegmentAllocator allocator, byte[] data, int dataLen, int[] outLen, int quality); - public static byte[] zlibCompress(SegmentAllocator allocator, byte[] data, int[] outLen, int quality) { - var pl = allocator.allocate(JAVA_INT); - var p = nzlibCompress(allocator.allocateFrom(JAVA_BYTE, data), data.length, pl, quality); - final int len = pl.get(JAVA_INT, 0); - outLen[0] = len; - return RuntimeHelper.toArray(p, new byte[len]); + @Skip + default byte[] zlibCompress(SegmentAllocator allocator, byte[] data, int[] outLen, int quality) { + return zlibCompress(allocator, data, data.length, outLen, quality); } } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBPerlin.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBPerlin.java index 2ddb9e66..6f9aac62 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBPerlin.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBPerlin.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2023 Overrun Organization + * Copyright (c) 2023-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,10 +16,7 @@ package overrungl.stb; -import java.lang.invoke.MethodHandle; - -import static overrungl.FunctionDescriptors.*; -import static overrungl.stb.Handles.*; +import overrun.marshal.Downcall; /** * The STB perlin noise generator. @@ -27,18 +24,11 @@ * @author squid233 * @since 0.1.0 */ -public final class STBPerlin { - private static final MethodHandle - stb_perlin_noise3 = downcall("stb_perlin_noise3", FFFIIIF), - stb_perlin_noise3_seed = downcall("stb_perlin_noise3_seed", FFFIIIIF), - stb_perlin_ridge_noise3 = downcall("stb_perlin_ridge_noise3", FFFFFFIF), - stb_perlin_fbm_noise3 = downcall("stb_perlin_fbm_noise3", FFFFFIF), - stb_perlin_turbulence_noise3 = downcall("stb_perlin_turbulence_noise3", FFFFFIF), - stb_perlin_noise3_wrap_nonpow2 = downcall("stb_perlin_noise3_wrap_nonpow2", FFFIIIBF); - - private STBPerlin() { - throw new IllegalStateException("Do not construct instance"); - } +public interface STBPerlin { + /** + * The instance of STBPerlin. + */ + STBPerlin INSTANCE = Downcall.load(Handles.lookup); /** * This function computes a random value at the coordinate (x,y,z).
@@ -61,13 +51,7 @@ private STBPerlin() { * @param wrapZ wrap z * @return the value */ - public static float noise3(float x, float y, float z, int wrapX, int wrapY, int wrapZ) { - try { - return (float) stb_perlin_noise3.invokeExact(x, y, z, wrapX, wrapY, wrapZ); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + float noise3(float x, float y, float z, int wrapX, int wrapY, int wrapZ); /** * As {@link #noise3}, but 'seed' selects from multiple different variations of the @@ -83,13 +67,7 @@ public static float noise3(float x, float y, float z, int wrapX, int wrapY, int * @param seed the seed * @return the value */ - public static float noise3seed(float x, float y, float z, int wrapX, int wrapY, int wrapZ, int seed) { - try { - return (float) stb_perlin_noise3_seed.invokeExact(x, y, z, wrapX, wrapY, wrapZ, seed); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + float noise3seed(float x, float y, float z, int wrapX, int wrapY, int wrapZ, int seed); /** * Three common fractal noise functions are included, which produce @@ -106,13 +84,7 @@ public static float noise3seed(float x, float y, float z, int wrapX, int wrapY, * @param octaves = 6 -- number of "octaves" of noise3() to sum * @return the value */ - public static float ridgeNoise3(float x, float y, float z, float lacunarity, float gain, float offset, int octaves) { - try { - return (float) stb_perlin_ridge_noise3.invokeExact(x, y, z, lacunarity, gain, offset, octaves); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + float ridgeNoise3(float x, float y, float z, float lacunarity, float gain, float offset, int octaves); /** * Three common fractal noise functions are included, which produce @@ -128,13 +100,7 @@ public static float ridgeNoise3(float x, float y, float z, float lacunarity, flo * @param octaves = 6 -- number of "octaves" of noise3() to sum * @return the value */ - public static float fbmNoise3(float x, float y, float z, float lacunarity, float gain, int octaves) { - try { - return (float) stb_perlin_fbm_noise3.invokeExact(x, y, z, lacunarity, gain, octaves); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + float fbmNoise3(float x, float y, float z, float lacunarity, float gain, int octaves); /** * Three common fractal noise functions are included, which produce @@ -150,19 +116,18 @@ public static float fbmNoise3(float x, float y, float z, float lacunarity, float * @param octaves = 6 -- number of "octaves" of noise3() to sum * @return the value */ - public static float turbulenceNoise3(float x, float y, float z, float lacunarity, float gain, int octaves) { - try { - return (float) stb_perlin_turbulence_noise3.invokeExact(x, y, z, lacunarity, gain, octaves); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + float turbulenceNoise3(float x, float y, float z, float lacunarity, float gain, int octaves); - public static float noise3wrapNonpow2(float x, float y, float z, int wrapX, int wrapY, int wrapZ, byte seed) { - try { - return (float) stb_perlin_noise3_wrap_nonpow2.invokeExact(x, y, z, wrapX, wrapY, wrapZ, seed); - } catch (Throwable e) { - throw new AssertionError("should not reach here", e); - } - } + /** + * {@return noise3wrapNonpow2} + * + * @param x x + * @param y y + * @param z z + * @param wrapX wrapX + * @param wrapY wrapY + * @param wrapZ wrapZ + * @param seed seed + */ + float noise3wrapNonpow2(float x, float y, float z, int wrapX, int wrapY, int wrapZ, byte seed); } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTAlignedQuad.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTAlignedQuad.java index 0cd1257b..16ad091c 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTAlignedQuad.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTAlignedQuad.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2023 Overrun Organization + * Copyright (c) 2023-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,13 +16,13 @@ package overrungl.stb; -import overrungl.Struct; +import overrun.marshal.struct.Struct; +import overrun.marshal.struct.StructHandle; import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; import java.lang.foreign.SegmentAllocator; import java.lang.foreign.StructLayout; -import java.lang.invoke.VarHandle; import static java.lang.foreign.ValueLayout.JAVA_FLOAT; @@ -31,8 +31,8 @@ *

  * typedef struct
  * {
- *    float {@link #x0() x0},{@link #y0() y0},{@link #s0() s0},{@link #t0() t0}; // top-left
- *    float {@link #x1() x1},{@link #y1() y1},{@link #s1() s1},{@link #t1() t1}; // bottom-right
+ *    float {@link #x0},{@link #y0},{@link #s0},{@link #t0}; // top-left
+ *    float {@link #x1},{@link #y1},{@link #s1},{@link #t1}; // bottom-right
  * } stbtt_aligned_quad;
  * 
* @@ -53,60 +53,74 @@ public final class STBTTAlignedQuad extends Struct { JAVA_FLOAT.withName("s1"), JAVA_FLOAT.withName("t1") ); - private static final VarHandle - x0 = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("x0")), - y0 = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("y0")), - s0 = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("s0")), - t0 = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("t0")), - x1 = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("x1")), - y1 = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("y1")), - s1 = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("s1")), - t1 = LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("t1")); - - public STBTTAlignedQuad(MemorySegment address) { - super(address, LAYOUT); - } - /** - * {@return the elements size of this struct in bytes} + * x0 */ - public static long sizeof() { - return LAYOUT.byteSize(); - } - - public static STBTTAlignedQuad create(SegmentAllocator allocator) { - return new STBTTAlignedQuad(allocator.allocate(LAYOUT)); - } - - public float x0() { - return (float) x0.get(segment()); - } - - public float y0() { - return (float) y0.get(segment()); - } - - public float s0() { - return (float) s0.get(segment()); - } - - public float t0() { - return (float) t0.get(segment()); - } + public final StructHandle.Float x0 = StructHandle.ofFloat(this, "x0"); + /** + * y0 + */ + public final StructHandle.Float y0 = StructHandle.ofFloat(this, "y0"); + /** + * s0 + */ + public final StructHandle.Float s0 = StructHandle.ofFloat(this, "s0"); + /** + * t0 + */ + public final StructHandle.Float t0 = StructHandle.ofFloat(this, "t0"); + /** + * x1 + */ + public final StructHandle.Float x1 = StructHandle.ofFloat(this, "x1"); + /** + * y1 + */ + public final StructHandle.Float y1 = StructHandle.ofFloat(this, "y1"); + /** + * s1 + */ + public final StructHandle.Float s1 = StructHandle.ofFloat(this, "s1"); + /** + * t1 + */ + public final StructHandle.Float t1 = StructHandle.ofFloat(this, "t1"); - public float x1() { - return (float) x1.get(segment()); + /** + * Creates a struct with the given layout. + * + * @param segment the segment + * @param elementCount the element count + */ + public STBTTAlignedQuad(MemorySegment segment, long elementCount) { + super(segment, elementCount, LAYOUT); } - public float y1() { - return (float) y1.get(segment()); + /** + * Allocates a struct with the given layout. + * + * @param allocator the allocator + * @param elementCount the element count + */ + public STBTTAlignedQuad(SegmentAllocator allocator, long elementCount) { + super(allocator, elementCount, LAYOUT); } - public float s1() { - return (float) s1.get(segment()); + /** + * Creates a struct with the given layout. + * + * @param segment the segment + */ + public STBTTAlignedQuad(MemorySegment segment) { + super(segment, LAYOUT); } - public float t1() { - return (float) t1.get(segment()); + /** + * Allocates a struct with the given layout. + * + * @param allocator the allocator + */ + public STBTTAlignedQuad(SegmentAllocator allocator) { + super(allocator, LAYOUT); } } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTBakedChar.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTBakedChar.java index cdd44e92..61b2d652 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTBakedChar.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTBakedChar.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2023 Overrun Organization + * Copyright (c) 2023-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,14 +16,13 @@ package overrungl.stb; -import overrungl.ArrayPointer; -import overrungl.Struct; +import overrun.marshal.struct.Struct; +import overrun.marshal.struct.StructHandle; import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; import java.lang.foreign.SegmentAllocator; import java.lang.foreign.StructLayout; -import java.lang.invoke.VarHandle; import static java.lang.foreign.ValueLayout.*; @@ -32,15 +31,15 @@ *

  * typedef struct
  * {
- *    unsigned short {@link #x0() x0},{@link #y0() y0},{@link #x1() x1},{@link #y1() y1}; // coordinates of bbox in bitmap
- *    float {@link #xoff() xoff},{@link #yoff() yoff},{@link #xadvance() xadvance};
+ *    unsigned short {@link #x0},{@link #y0},{@link #x1},{@link #y1}; // coordinates of bbox in bitmap
+ *    float {@link #xoff},{@link #yoff},{@link #xadvance};
  * } stbtt_bakedchar;
  * 
* * @author squid233 * @since 0.1.0 */ -public sealed class STBTTBakedChar extends Struct { +public final class STBTTBakedChar extends Struct { /** * The struct layout. */ @@ -53,75 +52,70 @@ public sealed class STBTTBakedChar extends Struct { JAVA_FLOAT.withName("yoff"), JAVA_FLOAT.withName("xadvance") ); - private static final VarHandle - x0 = LAYOUT.varHandle(PathElement.groupElement("x0")), - y0 = LAYOUT.varHandle(PathElement.groupElement("y0")), - x1 = LAYOUT.varHandle(PathElement.groupElement("x1")), - y1 = LAYOUT.varHandle(PathElement.groupElement("y1")), - xoff = LAYOUT.varHandle(PathElement.groupElement("xoff")), - yoff = LAYOUT.varHandle(PathElement.groupElement("yoff")), - xadvance = LAYOUT.varHandle(PathElement.groupElement("xadvance")); - - protected STBTTBakedChar(MemorySegment address, MemoryLayout layout) { - super(address, layout); - } - - public STBTTBakedChar(MemorySegment address) { - super(address, LAYOUT); - } - /** - * {@return the elements size of this struct in bytes} + * x0 */ - public static long sizeof() { - return LAYOUT.byteSize(); - } - - public static Buffer create(SegmentAllocator allocator, long count) { - return new Buffer(allocator.allocateArray(LAYOUT, count), count); - } - - public short x0() { - return (short) x0.get(segment()); - } - - public short y0() { - return (short) y0.get(segment()); - } - - public short x1() { - return (short) x1.get(segment()); - } - - public short y1() { - return (short) y1.get(segment()); - } + public final StructHandle.Short x0 = StructHandle.ofShort(this, "x0"); + /** + * y0 + */ + public final StructHandle.Short y0 = StructHandle.ofShort(this, "y0"); + /** + * x1 + */ + public final StructHandle.Short x1 = StructHandle.ofShort(this, "x1"); + /** + * y1 + */ + public final StructHandle.Short y1 = StructHandle.ofShort(this, "y1"); + /** + * xoff + */ + public final StructHandle.Float xoff = StructHandle.ofFloat(this, "xoff"); + /** + * yoff + */ + public final StructHandle.Float yoff = StructHandle.ofFloat(this, "yoff"); + /** + * xadvance + */ + public final StructHandle.Float xadvance = StructHandle.ofFloat(this, "xadvance"); - public float xoff() { - return (float) xoff.get(segment()); + /** + * Creates a struct with the given layout. + * + * @param segment the segment + * @param elementCount the element count + */ + public STBTTBakedChar(MemorySegment segment, long elementCount) { + super(segment, elementCount, LAYOUT); } - public float yoff() { - return (float) yoff.get(segment()); + /** + * Allocates a struct with the given layout. + * + * @param allocator the allocator + * @param elementCount the element count + */ + public STBTTBakedChar(SegmentAllocator allocator, long elementCount) { + super(allocator, elementCount, LAYOUT); } - public float xadvance() { - return (float) xadvance.get(segment()); + /** + * Creates a struct with the given layout. + * + * @param segment the segment + */ + public STBTTBakedChar(MemorySegment segment) { + super(segment, LAYOUT); } /** - * @author squid233 - * @since 0.1.0 + * Allocates a struct with the given layout. + * + * @param allocator the allocator */ - public static final class Buffer extends STBTTBakedChar implements ArrayPointer { - private final VarHandle pChar = layout().varHandle(PathElement.sequenceElement()); - - public Buffer(MemorySegment address, long elementCount) { - super(address, MemoryLayout.sequenceLayout(elementCount, LAYOUT)); - } - - public STBTTBakedChar get(long index) { - return new STBTTBakedChar((MemorySegment) pChar.get(segment(), index)); - } + public STBTTBakedChar(SegmentAllocator allocator) { + super(allocator, LAYOUT); } } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTKerningEntry.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTKerningEntry.java index 5620f22e..65c90b45 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTKerningEntry.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTKerningEntry.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2023 Overrun Organization + * Copyright (c) 2023-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,31 +16,26 @@ package overrungl.stb; -import overrungl.ArrayPointer; -import overrungl.Struct; +import overrun.marshal.struct.Struct; +import overrun.marshal.struct.StructHandle; -import java.lang.foreign.MemoryLayout; -import java.lang.foreign.MemoryLayout.PathElement; -import java.lang.foreign.MemorySegment; -import java.lang.foreign.StructLayout; -import java.lang.foreign.ValueLayout; -import java.lang.invoke.VarHandle; +import java.lang.foreign.*; /** *

Layout

*

  * typedef struct stbtt_kerningentry
  * {
- *    int {@link #glyph1() glyph1}; // use stbtt_FindGlyphIndex
- *    int {@link #glyph2() glyph2};
- *    int {@link #advance() advance};
+ *    int {@link #glyph1}; // use stbtt_FindGlyphIndex
+ *    int {@link #glyph2};
+ *    int {@link #advance};
  * } stbtt_kerningentry;
  * 
* * @author squid233 * @since 0.1.0 */ -public sealed class STBTTKerningEntry extends Struct { +public final class STBTTKerningEntry extends Struct { /** * The struct layout. */ @@ -49,51 +44,54 @@ public sealed class STBTTKerningEntry extends Struct { ValueLayout.JAVA_INT.withName("glyph2"), ValueLayout.JAVA_INT.withName("advance") ); - private static final VarHandle - glyph1 = LAYOUT.varHandle(PathElement.groupElement("glyph1")), - glyph2 = LAYOUT.varHandle(PathElement.groupElement("glyph2")), - advance = LAYOUT.varHandle(PathElement.groupElement("advance")); - - protected STBTTKerningEntry(MemorySegment address, MemoryLayout layout) { - super(address, layout); - } - - public STBTTKerningEntry(MemorySegment address) { - super(address, LAYOUT); - } - /** - * {@return the elements size of this struct in bytes} + * glyph1 */ - public static long sizeof() { - return LAYOUT.byteSize(); - } + public final StructHandle.Int glyph1 = StructHandle.ofInt(this, "glyph1"); + /** + * glyph2 + */ + public final StructHandle.Int glyph2 = StructHandle.ofInt(this, "glyph2"); + /** + * advance + */ + public final StructHandle.Int advance = StructHandle.ofInt(this, "advance"); - public int glyph1() { - return (int) glyph1.get(segment()); + /** + * Creates a struct with the given layout. + * + * @param segment the segment + * @param elementCount the element count + */ + public STBTTKerningEntry(MemorySegment segment, long elementCount) { + super(segment, elementCount, LAYOUT); } - public int glyph2() { - return (int) glyph2.get(segment()); + /** + * Allocates a struct with the given layout. + * + * @param allocator the allocator + * @param elementCount the element count + */ + public STBTTKerningEntry(SegmentAllocator allocator, long elementCount) { + super(allocator, elementCount, LAYOUT); } - public int advance() { - return (int) advance.get(segment()); + /** + * Creates a struct with the given layout. + * + * @param segment the segment + */ + public STBTTKerningEntry(MemorySegment segment) { + super(segment, LAYOUT); } /** - * @author squid233 - * @since 0.1.0 + * Allocates a struct with the given layout. + * + * @param allocator the allocator */ - public static final class Buffer extends STBTTKerningEntry implements ArrayPointer { - private final VarHandle pEntry = layout().varHandle(PathElement.sequenceElement()); - - public Buffer(MemorySegment address, long elementCount) { - super(address, MemoryLayout.sequenceLayout(elementCount, LAYOUT)); - } - - public STBTTKerningEntry get(long index) { - return new STBTTKerningEntry((MemorySegment) pEntry.get(segment(), index)); - } + public STBTTKerningEntry(SegmentAllocator allocator) { + super(allocator, LAYOUT); } } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTPackRange.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTPackRange.java index 6b150060..58719212 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTPackRange.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTPackRange.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2023 Overrun Organization + * Copyright (c) 2023-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,15 +16,16 @@ package overrungl.stb; -import overrungl.ArrayPointer; -import overrungl.Struct; -import overrungl.internal.RuntimeHelper; +import overrun.marshal.Marshal; +import overrun.marshal.Unmarshal; +import overrun.marshal.struct.Struct; +import overrun.marshal.struct.StructHandle; +import overrun.marshal.struct.StructHandleView; import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; import java.lang.foreign.SegmentAllocator; import java.lang.foreign.StructLayout; -import java.lang.invoke.VarHandle; import static java.lang.foreign.ValueLayout.*; @@ -33,273 +34,98 @@ *

  * typedef struct
  * {
- *    float {@link #fontSize() font_size};
- *    int {@link #firstUnicodeCodepointInRange() first_unicode_codepoint_in_range};  // if non-zero, then the chars are continuous, and this is the first codepoint
- *    int *{@link #arrayOfUnicodeCodepoints() array_of_unicode_codepoints};       // if non-zero, then this is an array of unicode codepoints
- *    int {@link #numChars() num_chars};
- *    stbtt_packedchar *{@link #chardataForRange() chardata_for_range}; // output
- *    unsigned char h_oversample, v_oversample; // don't set these, they're used internally
+ *    float {@link #fontSize font_size};
+ *    int {@link #firstUnicodeCodepointInRange first_unicode_codepoint_in_range};  // if non-zero, then the chars are continuous, and this is the first codepoint
+ *    int *{@link #arrayOfUnicodeCodepoints array_of_unicode_codepoints};       // if non-zero, then this is an array of unicode codepoints
+ *    int {@link #numChars num_chars};
+ *    stbtt_packedchar *{@link #chardataForRange chardata_for_range}; // output
+ *    unsigned char {@link #hOversample h_oversample}, {@link #vOversample v_oversample}; // don't set these, they're used internally
  * } stbtt_pack_range;
  * 
* * @author squid233 * @since 0.1.0 */ -public sealed class STBTTPackRange extends Struct { +public final class STBTTPackRange extends Struct { /** * The struct layout. */ public static final StructLayout LAYOUT = MemoryLayout.structLayout( JAVA_FLOAT.withName("font_size"), JAVA_INT.withName("first_unicode_codepoint_in_range"), - ADDRESS.withTargetLayout(MemoryLayout.sequenceLayout(JAVA_INT)).withName("array_of_unicode_codepoints"), + ADDRESS.withTargetLayout(MemoryLayout.sequenceLayout(0L, JAVA_INT)).withName("array_of_unicode_codepoints"), JAVA_INT.withName("num_chars"), - ADDRESS.withTargetLayout(MemoryLayout.sequenceLayout(STBTTPackedChar.LAYOUT)).withName("chardata_for_range"), + MemoryLayout.paddingLayout(4L), + ADDRESS.withTargetLayout(MemoryLayout.sequenceLayout(0L, STBTTPackedChar.LAYOUT)).withName("chardata_for_range"), JAVA_BYTE.withName("h_oversample"), - JAVA_BYTE.withName("v_oversample") + JAVA_BYTE.withName("v_oversample"), + MemoryLayout.paddingLayout(6L) ); - private static final VarHandle - font_size = LAYOUT.varHandle(PathElement.groupElement("font_size")), - first_unicode_codepoint_in_range = LAYOUT.varHandle(PathElement.groupElement("first_unicode_codepoint_in_range")), - array_of_unicode_codepoints = LAYOUT.varHandle(PathElement.groupElement("array_of_unicode_codepoints")), - num_chars = LAYOUT.varHandle(PathElement.groupElement("num_chars")), - chardata_for_range = LAYOUT.varHandle(PathElement.groupElement("chardata_for_range")); - - protected STBTTPackRange(MemorySegment address, MemoryLayout layout) { - super(address, layout); - } - - public STBTTPackRange(MemorySegment address) { - super(address, LAYOUT); - } - /** - * {@return the elements size of this struct in bytes} + * font_size */ - public static long sizeof() { - return LAYOUT.byteSize(); - } - - public static STBTTPackRange create(SegmentAllocator allocator) { - return new STBTTPackRange(allocator.allocate(LAYOUT)); - } - - public static Buffer create(SegmentAllocator allocator, long count) { - return new Buffer(allocator.allocateArray(LAYOUT, count), count); - } - - public STBTTPackRange fontSize(float fontSize) { - font_size.set(segment(), fontSize); - return this; - } - - public STBTTPackRange firstUnicodeCodepointInRange(int firstUnicodeCodepointInRange) { - first_unicode_codepoint_in_range.set(segment(), firstUnicodeCodepointInRange); - return this; - } - - public STBTTPackRange narrayOfUnicodeCodepoints(MemorySegment arrayOfUnicodeCodepoints) { - array_of_unicode_codepoints.set(segment(), arrayOfUnicodeCodepoints); - return this; - } - - public STBTTPackRange arrayOfUnicodeCodepoints(SegmentAllocator allocator, int[] arrayOfUnicodeCodepoints) { - return narrayOfUnicodeCodepoints(allocator.allocateArray(JAVA_INT, arrayOfUnicodeCodepoints)); - } - - public STBTTPackRange numChars(int numChars) { - num_chars.set(segment(), numChars); - return this; - } - - public STBTTPackRange nchardataForRange(MemorySegment chardataForRange) { - chardata_for_range.set(segment(), chardataForRange); - return this; - } - - public STBTTPackRange chardataForRange(STBTTPackedChar.Buffer chardataForRange) { - return nchardataForRange(chardataForRange.address()) - .numChars(Math.toIntExact(chardataForRange.elementCount())); - } - - public float fontSize() { - return (float) font_size.get(segment()); - } - - public int firstUnicodeCodepointInRange() { - return (int) first_unicode_codepoint_in_range.get(segment()); - } - - public MemorySegment narrayOfUnicodeCodepoints() { - return (MemorySegment) array_of_unicode_codepoints.get(segment()); - } - - public int[] arrayOfUnicodeCodepoints() { - final MemorySegment seg = narrayOfUnicodeCodepoints(); - if (RuntimeHelper.isNullptr(seg)) return null; - return RuntimeHelper.toArray(seg, new int[numChars()]); - } + public final StructHandle.Float fontSize = StructHandle.ofFloat(this, "font_size"); + /** + * first_unicode_codepoint_in_range + */ + public final StructHandle.Int firstUnicodeCodepointInRange = StructHandle.ofInt(this, "first_unicode_codepoint_in_range"); + /** + * array_of_unicode_codepoints + */ + public final StructHandle.Array arrayOfUnicodeCodepoints = StructHandle.ofArray(this, "array_of_unicode_codepoints", Marshal::marshal, Unmarshal::unmarshalAsIntArray); + /** + * num_chars + */ + public final StructHandle.Int numChars = StructHandle.ofInt(this, "num_chars"); + /** + * chardata_for_range + */ + public final StructHandle.Array chardataForRange = StructHandle.ofArray(this, "chardata_for_range", Marshal::marshal, + segment -> Unmarshal.unmarshal(ADDRESS, segment, STBTTPackedChar[]::new, s -> new STBTTPackedChar(s.get(ADDRESS.withTargetLayout(STBTTPackedChar.LAYOUT), 0L), 1L))); + /** + * h_oversample + */ + public final StructHandleView.Byte hOversample = StructHandle.ofByte(this, "h_oversample"); + /** + * v_oversample + */ + public final StructHandleView.Byte vOversample = StructHandle.ofByte(this, "v_oversample"); - public int numChars() { - return (int) num_chars.get(segment()); + /** + * Creates a struct with the given layout. + * + * @param segment the segment + * @param elementCount the element count + */ + public STBTTPackRange(MemorySegment segment, long elementCount) { + super(segment, elementCount, LAYOUT); } - public MemorySegment nchardataForRange() { - return (MemorySegment) chardata_for_range.get(segment()); + /** + * Allocates a struct with the given layout. + * + * @param allocator the allocator + * @param elementCount the element count + */ + public STBTTPackRange(SegmentAllocator allocator, long elementCount) { + super(allocator, elementCount, LAYOUT); } - public STBTTPackedChar.Buffer chardataForRange() { - return new STBTTPackedChar.Buffer(nchardataForRange(), numChars()); + /** + * Creates a struct with the given layout. + * + * @param segment the segment + */ + public STBTTPackRange(MemorySegment segment) { + super(segment, LAYOUT); } /** - * @author squid233 - * @since 0.1.0 + * Allocates a struct with the given layout. + * + * @param allocator the allocator */ - public static final class Buffer extends STBTTPackRange implements ArrayPointer { - private final VarHandle - font_size = layout().varHandle(PathElement.sequenceElement(), PathElement.groupElement("font_size")), - first_unicode_codepoint_in_range = layout().varHandle(PathElement.sequenceElement(), PathElement.groupElement("first_unicode_codepoint_in_range")), - array_of_unicode_codepoints = layout().varHandle(PathElement.sequenceElement(), PathElement.groupElement("array_of_unicode_codepoints")), - num_chars = layout().varHandle(PathElement.sequenceElement(), PathElement.groupElement("num_chars")), - chardata_for_range = layout().varHandle(PathElement.sequenceElement(), PathElement.groupElement("chardata_for_range")); - - public Buffer(MemorySegment address, long elementCount) { - super(address, MemoryLayout.sequenceLayout(elementCount, LAYOUT)); - } - - public Buffer fontSize(long index, float fontSize) { - font_size.set(segment(), index, fontSize); - return this; - } - - public Buffer firstUnicodeCodepointInRange(long index, int firstUnicodeCodepointInRange) { - first_unicode_codepoint_in_range.set(segment(), index, firstUnicodeCodepointInRange); - return this; - } - - public Buffer narrayOfUnicodeCodepoints(long index, MemorySegment arrayOfUnicodeCodepoints) { - array_of_unicode_codepoints.set(segment(), index, arrayOfUnicodeCodepoints); - return this; - } - - public Buffer arrayOfUnicodeCodepoints(long index, SegmentAllocator allocator, int[] arrayOfUnicodeCodepoints) { - return narrayOfUnicodeCodepoints(index, allocator.allocateArray(JAVA_INT, arrayOfUnicodeCodepoints)); - } - - public Buffer numChars(long index, int numChars) { - num_chars.set(segment(), index, numChars); - return this; - } - - public Buffer nchardataForRange(long index, MemorySegment chardataForRange) { - chardata_for_range.set(segment(), index, chardataForRange); - return this; - } - - public Buffer chardataForRange(long index, STBTTPackedChar.Buffer chardataForRange) { - return nchardataForRange(index, chardataForRange.address()) - .numChars(index, Math.toIntExact(chardataForRange.elementCount())); - } - - @Override - public Buffer fontSize(float fontSize) { - return fontSize(0, fontSize); - } - - @Override - public Buffer firstUnicodeCodepointInRange(int firstUnicodeCodepointInRange) { - return firstUnicodeCodepointInRange(0, firstUnicodeCodepointInRange); - } - - @Override - public Buffer narrayOfUnicodeCodepoints(MemorySegment arrayOfUnicodeCodepoints) { - return narrayOfUnicodeCodepoints(0, arrayOfUnicodeCodepoints); - } - - @Override - public Buffer arrayOfUnicodeCodepoints(SegmentAllocator allocator, int[] arrayOfUnicodeCodepoints) { - return arrayOfUnicodeCodepoints(0, allocator, arrayOfUnicodeCodepoints); - } - - @Override - public Buffer numChars(int numChars) { - return numChars(0, numChars); - } - - @Override - public Buffer nchardataForRange(MemorySegment chardataForRange) { - return nchardataForRange(0, chardataForRange); - } - - @Override - public Buffer chardataForRange(STBTTPackedChar.Buffer chardataForRange) { - return chardataForRange(0, chardataForRange); - } - - public float fontSizeAt(long index) { - return (float) font_size.get(segment(), index); - } - - public int firstUnicodeCodepointInRangeAt(long index) { - return (int) first_unicode_codepoint_in_range.get(segment(), index); - } - - public MemorySegment narrayOfUnicodeCodepointsAt(long index) { - return (MemorySegment) array_of_unicode_codepoints.get(segment(), index); - } - - public int[] arrayOfUnicodeCodepointsAt(long index) { - final MemorySegment seg = narrayOfUnicodeCodepointsAt(index); - if (RuntimeHelper.isNullptr(seg)) return null; - return RuntimeHelper.toArray(seg, new int[numChars()]); - } - - public int numCharsAt(long index) { - return (int) num_chars.get(segment(), index); - } - - public MemorySegment nchardataForRangeAt(long index) { - return (MemorySegment) chardata_for_range.get(segment(), index); - } - - public STBTTPackedChar.Buffer chardataForRangeAt(long index) { - return new STBTTPackedChar.Buffer(nchardataForRangeAt(index), numCharsAt(index)); - } - - @Override - public float fontSize() { - return fontSizeAt(0); - } - - @Override - public int firstUnicodeCodepointInRange() { - return firstUnicodeCodepointInRangeAt(0); - } - - @Override - public MemorySegment narrayOfUnicodeCodepoints() { - return narrayOfUnicodeCodepointsAt(0); - } - - @Override - public int[] arrayOfUnicodeCodepoints() { - return arrayOfUnicodeCodepointsAt(0); - } - - @Override - public int numChars() { - return numCharsAt(0); - } - - @Override - public MemorySegment nchardataForRange() { - return nchardataForRangeAt(0); - } - - @Override - public STBTTPackedChar.Buffer chardataForRange() { - return chardataForRangeAt(0); - } + public STBTTPackRange(SegmentAllocator allocator) { + super(allocator, LAYOUT); } } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTPackedChar.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTPackedChar.java index cfc8a96d..d71d9bd9 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTPackedChar.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTPackedChar.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2023 Overrun Organization + * Copyright (c) 2023-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,14 +16,13 @@ package overrungl.stb; -import overrungl.ArrayPointer; -import overrungl.Struct; +import overrun.marshal.struct.Struct; +import overrun.marshal.struct.StructHandle; import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; import java.lang.foreign.SegmentAllocator; import java.lang.foreign.StructLayout; -import java.lang.invoke.VarHandle; import static java.lang.foreign.ValueLayout.*; @@ -32,16 +31,16 @@ *

  * typedef struct
  * {
- *    unsigned short {@link #x0() x0},{@link #y0() y0},{@link #x1() x1},{@link #y1() y1}; // coordinates of bbox in bitmap
- *    float {@link #xoff() xoff},{@link #yoff() yoff},{@link #xadvance() xadvance};
- *    float {@link #xoff2() xoff2},{@link #yoff2() yoff2};
+ *    unsigned short {@link #x0},{@link #y0},{@link #x1},{@link #y1}; // coordinates of bbox in bitmap
+ *    float {@link #xoff},{@link #yoff},{@link #xadvance};
+ *    float {@link #xoff2},{@link #yoff2};
  * } stbtt_packedchar;
  * 
* * @author squid233 * @since 0.1.0 */ -public sealed class STBTTPackedChar extends Struct { +public final class STBTTPackedChar extends Struct { /** * The struct layout. */ @@ -56,86 +55,78 @@ public sealed class STBTTPackedChar extends Struct { JAVA_FLOAT.withName("xoff2"), JAVA_FLOAT.withName("yoff2") ); - private static final VarHandle - x0 = LAYOUT.varHandle(PathElement.groupElement("x0")), - y0 = LAYOUT.varHandle(PathElement.groupElement("y0")), - x1 = LAYOUT.varHandle(PathElement.groupElement("x1")), - y1 = LAYOUT.varHandle(PathElement.groupElement("y1")), - xoff = LAYOUT.varHandle(PathElement.groupElement("xoff")), - yoff = LAYOUT.varHandle(PathElement.groupElement("yoff")), - xadvance = LAYOUT.varHandle(PathElement.groupElement("xadvance")), - xoff2 = LAYOUT.varHandle(PathElement.groupElement("xoff2")), - yoff2 = LAYOUT.varHandle(PathElement.groupElement("yoff2")); - - protected STBTTPackedChar(MemorySegment address, MemoryLayout layout) { - super(address, layout); - } - - public STBTTPackedChar(MemorySegment address) { - super(address, LAYOUT); - } - /** - * {@return the elements size of this struct in bytes} + * x0 */ - public static long sizeof() { - return LAYOUT.byteSize(); - } - - public static Buffer create(SegmentAllocator allocator, long count) { - return new Buffer(allocator.allocateArray(LAYOUT, count), count); - } - - public short x0() { - return (short) x0.get(segment()); - } - - public short y0() { - return (short) y0.get(segment()); - } - - public short x1() { - return (short) x1.get(segment()); - } - - public short y1() { - return (short) y1.get(segment()); - } - - public float xoff() { - return (float) xoff.get(segment()); - } - - public float yoff() { - return (float) yoff.get(segment()); - } + public final StructHandle.Short x0 = StructHandle.ofShort(this, "x0"); + /** + * y0 + */ + public final StructHandle.Short y0 = StructHandle.ofShort(this, "y0"); + /** + * x1 + */ + public final StructHandle.Short x1 = StructHandle.ofShort(this, "x1"); + /** + * y1 + */ + public final StructHandle.Short y1 = StructHandle.ofShort(this, "y1"); + /** + * xoff + */ + public final StructHandle.Float xoff = StructHandle.ofFloat(this, "xoff"); + /** + * yoff + */ + public final StructHandle.Float yoff = StructHandle.ofFloat(this, "yoff"); + /** + * xadvance + */ + public final StructHandle.Float xadvance = StructHandle.ofFloat(this, "xadvance"); + /** + * xoff2 + */ + public final StructHandle.Float xoff2 = StructHandle.ofFloat(this, "xoff2"); + /** + * yoff2 + */ + public final StructHandle.Float yoff2 = StructHandle.ofFloat(this, "yoff2"); - public float xadvance() { - return (float) xadvance.get(segment()); + /** + * Creates a struct with the given layout. + * + * @param segment the segment + * @param elementCount the element count + */ + public STBTTPackedChar(MemorySegment segment, long elementCount) { + super(segment, elementCount, LAYOUT); } - public float xoff2() { - return (float) xoff2.get(segment()); + /** + * Allocates a struct with the given layout. + * + * @param allocator the allocator + * @param elementCount the element count + */ + public STBTTPackedChar(SegmentAllocator allocator, long elementCount) { + super(allocator, elementCount, LAYOUT); } - public float yoff2() { - return (float) yoff2.get(segment()); + /** + * Creates a struct with the given layout. + * + * @param segment the segment + */ + public STBTTPackedChar(MemorySegment segment) { + super(segment, LAYOUT); } /** - * @author squid233 - * @since 0.1.0 + * Allocates a struct with the given layout. + * + * @param allocator the allocator */ - public static final class Buffer extends STBTTPackedChar implements ArrayPointer { - private final VarHandle pChar; - - public Buffer(MemorySegment address, long elementCount) { - super(address, MemoryLayout.sequenceLayout(elementCount, LAYOUT)); - pChar = layout().varHandle(PathElement.sequenceElement()); - } - - public STBTTPackedChar get(long index) { - return new STBTTPackedChar((MemorySegment) pChar.get(segment(), index)); - } + public STBTTPackedChar(SegmentAllocator allocator) { + super(allocator, LAYOUT); } } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTVertex.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTVertex.java index 1a951946..ad2c4c67 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTVertex.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBTTVertex.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2023 Overrun Organization + * Copyright (c) 2023-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,22 +16,24 @@ package overrungl.stb; -import overrungl.Struct; +import overrun.marshal.struct.Struct; +import overrun.marshal.struct.StructHandle; import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; import java.lang.foreign.StructLayout; -import java.lang.invoke.VarHandle; -import static java.lang.foreign.ValueLayout.*; +import static java.lang.foreign.ValueLayout.JAVA_BYTE; +import static java.lang.foreign.ValueLayout.JAVA_SHORT; /** *

Layout

*

  * typedef struct
  * {
- *    stbtt_vertex_type {@link #x() x},{@link #y() y},{@link #cx() cx},{@link #cy() cy},{@link #cx1() cx1},{@link #cy1() cy1};
- *    unsigned char {@link #type() type},{@link #padding() padding};
+ *    stbtt_vertex_type {@link #x},{@link #y},{@link #cx},{@link #cy},{@link #cx1},{@link #cy1};
+ *    unsigned char {@link #type},{@link #padding};
  * } stbtt_vertex;
  * 
* @@ -51,57 +53,76 @@ public final class STBTTVertex extends Struct { JAVA_SHORT.withName("cy1"), JAVA_BYTE.withName("type"), JAVA_BYTE.withName("padding") - ); - private static final VarHandle - x = LAYOUT.varHandle(PathElement.groupElement("x")), - y = LAYOUT.varHandle(PathElement.groupElement("y")), - cx = LAYOUT.varHandle(PathElement.groupElement("cx")), - cy = LAYOUT.varHandle(PathElement.groupElement("cy")), - cx1 = LAYOUT.varHandle(PathElement.groupElement("cx1")), - cy1 = LAYOUT.varHandle(PathElement.groupElement("cy1")), - type = LAYOUT.varHandle(PathElement.groupElement("type")), - padding = LAYOUT.varHandle(PathElement.groupElement("padding")); - - public STBTTVertex(MemorySegment address) { - super(address, LAYOUT); - } + ); /** - * {@return the elements size of this struct in bytes} + * x */ - public static long sizeof() { - return LAYOUT.byteSize(); - } - - public short x() { - return (short) x.get(segment()); - } - - public short y() { - return (short) y.get(segment()); - } - - public short cx() { - return (short) cx.get(segment()); - } - - public short cy() { - return (short) cy.get(segment()); - } + public final StructHandle.Short x = StructHandle.ofShort(this, "x"); + /** + * y + */ + public final StructHandle.Short y = StructHandle.ofShort(this, "y"); + /** + * cx + */ + public final StructHandle.Short cx = StructHandle.ofShort(this, "cx"); + /** + * cy + */ + public final StructHandle.Short cy = StructHandle.ofShort(this, "cy"); + /** + * cx1 + */ + public final StructHandle.Short cx1 = StructHandle.ofShort(this, "cx1"); + /** + * cy1 + */ + public final StructHandle.Short cy1 = StructHandle.ofShort(this, "cy1"); + /** + * type + */ + public final StructHandle.Byte type = StructHandle.ofByte(this, "type"); + /** + * padding + */ + public final StructHandle.Byte padding = StructHandle.ofByte(this, "padding"); - public short cx1() { - return (short) cx1.get(segment()); + /** + * Creates a struct with the given layout. + * + * @param segment the segment + * @param elementCount the element count + */ + public STBTTVertex(MemorySegment segment, long elementCount) { + super(segment, elementCount, LAYOUT); } - public short cy1() { - return (short) cy1.get(segment()); + /** + * Allocates a struct with the given layout. + * + * @param allocator the allocator + * @param elementCount the element count + */ + public STBTTVertex(SegmentAllocator allocator, long elementCount) { + super(allocator, elementCount, LAYOUT); } - public byte type() { - return (byte) type.get(segment()); + /** + * Creates a struct with the given layout. + * + * @param segment the segment + */ + public STBTTVertex(MemorySegment segment) { + super(segment, LAYOUT); } - public byte padding() { - return (byte) padding.get(segment()); + /** + * Allocates a struct with the given layout. + * + * @param allocator the allocator + */ + public STBTTVertex(SegmentAllocator allocator) { + super(allocator, LAYOUT); } } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBVorbis.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBVorbis.java index db468985..22ad0104 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBVorbis.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBVorbis.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2023 Overrun Organization + * Copyright (c) 2023-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,7 +26,6 @@ import static overrungl.FunctionDescriptors.*; import static overrungl.stb.Handles.downcall; -import static overrungl.stb.Handles.initialize; /** * @author squid233 @@ -41,7 +40,6 @@ public final class STBVorbis { stb_vorbis_get_samples_float, stb_vorbis_get_samples_short_interleaved, stb_vorbis_get_samples_short; static { - initialize(); create(); } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBVorbisAlloc.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBVorbisAlloc.java index d3899d87..f3a132cf 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBVorbisAlloc.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBVorbisAlloc.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2023 Overrun Organization + * Copyright (c) 2023-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,13 +16,13 @@ package overrungl.stb; -import overrungl.Struct; +import overrun.marshal.struct.Struct; +import overrun.marshal.struct.StructHandle; import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; import java.lang.foreign.SegmentAllocator; import java.lang.foreign.StructLayout; -import java.lang.invoke.VarHandle; import static java.lang.foreign.ValueLayout.*; @@ -50,8 +50,8 @@ *

  * typedef struct
  * {
- *    char *{@link #allocBuffer() alloc_buffer};
- *    int   {@link #allocBufferLength() alloc_buffer_length_in_bytes};
+ *    char *{@link #allocBuffer alloc_buffer};
+ *    int   {@link #allocBufferLengthInBytes alloc_buffer_length_in_bytes};
  * } stb_vorbis_alloc;
  * 
* @@ -63,47 +63,53 @@ public final class STBVorbisAlloc extends Struct { * The struct layout. */ public static final StructLayout LAYOUT = MemoryLayout.structLayout( - ADDRESS.withTargetLayout(MemoryLayout.sequenceLayout(JAVA_BYTE)).withName("alloc_buffer"), + ADDRESS.withTargetLayout(MemoryLayout.sequenceLayout(0L, JAVA_BYTE)).withName("alloc_buffer"), JAVA_INT.withName("alloc_buffer_length_in_bytes") ); - private static final VarHandle - ppAllocBuffer = LAYOUT.varHandle(PathElement.groupElement("alloc_buffer")), - pAllocBufferLengthInBytes = LAYOUT.varHandle(PathElement.groupElement("alloc_buffer_length_in_bytes")); + /** + * alloc_buffer + */ + public final StructHandle.Address allocBuffer = StructHandle.ofAddress(this, "alloc_buffer"); + /** + * alloc_buffer_length_in_bytes + */ + public final StructHandle.Int allocBufferLengthInBytes = StructHandle.ofInt(this, "alloc_buffer_length_in_bytes"); /** - * Creates a {@code STBVorbisAlloc} instance. + * Creates a struct with the given layout. * - * @param address the address. + * @param segment the segment + * @param elementCount the element count */ - public STBVorbisAlloc(MemorySegment address) { - super(address, LAYOUT); + public STBVorbisAlloc(MemorySegment segment, long elementCount) { + super(segment, elementCount, LAYOUT); } /** - * Creates a {@code STBVorbisAlloc} instance with the given allocator. + * Allocates a struct with the given layout. * - * @param allocator the allocator. - * @return the allocator. + * @param allocator the allocator + * @param elementCount the element count */ - public static STBVorbisAlloc create(SegmentAllocator allocator) { - return new STBVorbisAlloc(allocator.allocate(LAYOUT)); - } - - public STBVorbisAlloc allocBuffer(MemorySegment allocBuffer) { - ppAllocBuffer.set(segment(), allocBuffer); - return this; - } - - public STBVorbisAlloc allocBufferLength(int allocBufferLength) { - pAllocBufferLengthInBytes.set(segment(), allocBufferLength); - return this; + public STBVorbisAlloc(SegmentAllocator allocator, long elementCount) { + super(allocator, elementCount, LAYOUT); } - public MemorySegment allocBuffer() { - return (MemorySegment) ppAllocBuffer.get(segment()); + /** + * Creates a struct with the given layout. + * + * @param segment the segment + */ + public STBVorbisAlloc(MemorySegment segment) { + super(segment, LAYOUT); } - public int allocBufferLength() { - return (int) pAllocBufferLengthInBytes.get(segment()); + /** + * Allocates a struct with the given layout. + * + * @param allocator the allocator + */ + public STBVorbisAlloc(SegmentAllocator allocator) { + super(allocator, LAYOUT); } } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBVorbisComment.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBVorbisComment.java index 2e4ad25b..ea364879 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBVorbisComment.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBVorbisComment.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2023 Overrun Organization + * Copyright (c) 2023-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,13 +16,15 @@ package overrungl.stb; -import overrungl.Struct; -import overrungl.internal.RuntimeHelper; +import overrun.marshal.Marshal; +import overrun.marshal.Unmarshal; +import overrun.marshal.struct.Struct; +import overrun.marshal.struct.StructHandle; import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; import java.lang.foreign.StructLayout; -import java.lang.invoke.VarHandle; import static java.lang.foreign.ValueLayout.*; @@ -31,10 +33,10 @@ *

  * typedef struct
  * {
- *    char *{@link #vendor() vendor};
+ *    char *{@link #vendor vendor};
  *
- *    int {@link #commentListLength() comment_list_length};
- *    char **{@link #commentList() comment_list};
+ *    int {@link #commentListLength comment_list_length};
+ *    char **{@link #commentList comment_list};
  * } stb_vorbis_comment;
  * 
* @@ -46,41 +48,58 @@ public final class STBVorbisComment extends Struct { * The struct layout. */ public static final StructLayout LAYOUT = MemoryLayout.structLayout( - ADDRESS.withTargetLayout(MemoryLayout.sequenceLayout(JAVA_BYTE)).withName("vendor"), + ADDRESS.withTargetLayout(MemoryLayout.sequenceLayout(0L, JAVA_BYTE)).withName("vendor"), JAVA_INT.withName("comment_list_length"), - ADDRESS.withTargetLayout(ADDRESS.withTargetLayout(MemoryLayout.sequenceLayout(JAVA_BYTE))).withName("comment_list") + ADDRESS.withTargetLayout(ADDRESS.withTargetLayout(MemoryLayout.sequenceLayout(Unmarshal.STR_SIZE, JAVA_BYTE))).withName("comment_list") ); - private static final VarHandle - vendor = LAYOUT.varHandle(PathElement.groupElement("vendor")), - comment_list_length = LAYOUT.varHandle(PathElement.groupElement("comment_list_length")), - comment_list = LAYOUT.varHandle(PathElement.groupElement("comment_list")); - - public STBVorbisComment(MemorySegment address) { - super(address, LAYOUT); - } - - public String vendor() { - return nvendor().getUtf8String(0); - } + /** + * vendor + */ + public final StructHandle.Array vendor = StructHandle.ofArray(this, "vendor", Marshal::marshal, Unmarshal::unmarshalAsByteArray); + /** + * comment_list_length + */ + public final StructHandle.Int commentListLength = StructHandle.ofInt(this, "comment_list_length"); + /** + * comment_list + */ + public final StructHandle.Array commentList = StructHandle.ofArray(this, "comment_list", Marshal::marshal, Unmarshal::unmarshalAsStringArray); - public int commentListLength() { - return (int) comment_list_length.get(segment()); + /** + * Creates a struct with the given layout. + * + * @param segment the segment + * @param elementCount the element count + */ + public STBVorbisComment(MemorySegment segment, long elementCount) { + super(segment, elementCount, LAYOUT); } - public String[] commentList() { - final MemorySegment list = ncommentList(); - String[] arr = new String[commentListLength()]; - for (int i = 0; i < arr.length; i++) { - arr[i] = list.getAtIndex(RuntimeHelper.ADDRESS_UNBOUNDED, i).getUtf8String(0); - } - return arr; + /** + * Allocates a struct with the given layout. + * + * @param allocator the allocator + * @param elementCount the element count + */ + public STBVorbisComment(SegmentAllocator allocator, long elementCount) { + super(allocator, elementCount, LAYOUT); } - public MemorySegment nvendor() { - return (MemorySegment) vendor.get(segment()); + /** + * Creates a struct with the given layout. + * + * @param segment the segment + */ + public STBVorbisComment(MemorySegment segment) { + super(segment, LAYOUT); } - public MemorySegment ncommentList() { - return (MemorySegment) comment_list.get(segment()); + /** + * Allocates a struct with the given layout. + * + * @param allocator the allocator + */ + public STBVorbisComment(SegmentAllocator allocator) { + super(allocator, LAYOUT); } } diff --git a/modules/overrungl.stb/src/main/java/overrungl/stb/STBVorbisInfo.java b/modules/overrungl.stb/src/main/java/overrungl/stb/STBVorbisInfo.java index 1f12673b..32778b44 100644 --- a/modules/overrungl.stb/src/main/java/overrungl/stb/STBVorbisInfo.java +++ b/modules/overrungl.stb/src/main/java/overrungl/stb/STBVorbisInfo.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2023 Overrun Organization + * Copyright (c) 2023-2024 Overrun Organization * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -16,13 +16,13 @@ package overrungl.stb; -import overrungl.Struct; +import overrun.marshal.struct.Struct; +import overrun.marshal.struct.StructHandle; import java.lang.foreign.MemoryLayout; -import java.lang.foreign.MemoryLayout.PathElement; import java.lang.foreign.MemorySegment; +import java.lang.foreign.SegmentAllocator; import java.lang.foreign.StructLayout; -import java.lang.invoke.VarHandle; import static java.lang.foreign.ValueLayout.JAVA_INT; @@ -31,14 +31,14 @@ *

  * typedef struct
  * {
- *    unsigned int {@link #sampleRate() sample_rate};
- *    int {@link #channels() channels};
+ *    unsigned int {@link #sampleRate sample_rate};
+ *    int {@link #channels channels};
  *
- *    unsigned int {@link #setupMemoryRequired() setup_memory_required};
- *    unsigned int {@link #setupTempMemoryRequired() setup_temp_memory_required};
- *    unsigned int {@link #tempMemoryRequired() temp_memory_required};
+ *    unsigned int {@link #setupMemoryRequired setup_memory_required};
+ *    unsigned int {@link #setupTempMemoryRequired setup_temp_memory_required};
+ *    unsigned int {@link #tempMemoryRequired temp_memory_required};
  *
- *    int {@link #maxFrameSize() max_frame_size};
+ *    int {@link #maxFrameSize max_frame_size};
  * } stb_vorbis_info;
  * 
* @@ -57,39 +57,66 @@ public final class STBVorbisInfo extends Struct { JAVA_INT.withName("temp_memory_required"), JAVA_INT.withName("max_frame_size") ); - private static final VarHandle - sample_rate = LAYOUT.varHandle(PathElement.groupElement("sample_rate")), - channels = LAYOUT.varHandle(PathElement.groupElement("channels")), - setup_memory_required = LAYOUT.varHandle(PathElement.groupElement("setup_memory_required")), - setup_temp_memory_required = LAYOUT.varHandle(PathElement.groupElement("setup_temp_memory_required")), - temp_memory_required = LAYOUT.varHandle(PathElement.groupElement("temp_memory_required")), - max_frame_size = LAYOUT.varHandle(PathElement.groupElement("max_frame_size")); - - public STBVorbisInfo(MemorySegment address) { - super(address, LAYOUT); - } - - public int sampleRate() { - return (int) sample_rate.get(segment()); - } - - public int channels() { - return (int) channels.get(segment()); - } + /** + * sample_rate + */ + public final StructHandle.Int sampleRate = StructHandle.ofInt(this, "sample_rate"); + /** + * channels + */ + public final StructHandle.Int channels = StructHandle.ofInt(this, "channels"); + /** + * setup_memory_required + */ + public final StructHandle.Int setupMemoryRequired = StructHandle.ofInt(this, "setup_memory_required"); + /** + * setup_temp_memory_required + */ + public final StructHandle.Int setupTempMemoryRequired = StructHandle.ofInt(this, "setup_temp_memory_required"); + /** + * temp_memory_required + */ + public final StructHandle.Int tempMemoryRequired = StructHandle.ofInt(this, "temp_memory_required"); + /** + * max_frame_size + */ + public final StructHandle.Int maxFrameSize = StructHandle.ofInt(this, "max_frame_size"); - public int setupMemoryRequired() { - return (int) setup_memory_required.get(segment()); + /** + * Creates a struct with the given layout. + * + * @param segment the segment + * @param elementCount the element count + */ + public STBVorbisInfo(MemorySegment segment, long elementCount) { + super(segment, elementCount, LAYOUT); } - public int setupTempMemoryRequired() { - return (int) setup_temp_memory_required.get(segment()); + /** + * Allocates a struct with the given layout. + * + * @param allocator the allocator + * @param elementCount the element count + */ + public STBVorbisInfo(SegmentAllocator allocator, long elementCount) { + super(allocator, elementCount, LAYOUT); } - public int tempMemoryRequired() { - return (int) temp_memory_required.get(segment()); + /** + * Creates a struct with the given layout. + * + * @param segment the segment + */ + public STBVorbisInfo(MemorySegment segment) { + super(segment, LAYOUT); } - public int maxFrameSize() { - return (int) max_frame_size.get(segment()); + /** + * Allocates a struct with the given layout. + * + * @param allocator the allocator + */ + public STBVorbisInfo(SegmentAllocator allocator) { + super(allocator, LAYOUT); } } diff --git a/modules/samples/src/test/java/overrungl/demo/glfw/GLFWWindowIconTest.java b/modules/samples/src/test/java/overrungl/demo/glfw/GLFWWindowIconTest.java index fb7f580d..adb97763 100644 --- a/modules/samples/src/test/java/overrungl/demo/glfw/GLFWWindowIconTest.java +++ b/modules/samples/src/test/java/overrungl/demo/glfw/GLFWWindowIconTest.java @@ -66,10 +66,11 @@ private void init(Arena arena) { CheckUtil.checkNotNullptr(window, "Failed to create the GLFW window"); try { + final STBImage stbImage = STBImage.INSTANCE; var px = arena.allocate(JAVA_INT); var py = arena.allocate(JAVA_INT); var pc = arena.allocate(JAVA_INT); - var data = STBImage.loadFromMemory( + var data = stbImage.loadFromMemory( IOUtil.ioResourceToSegment(arena, "image.png", 256), px, py, pc, STBImage.RGB_ALPHA ); @@ -77,7 +78,7 @@ private void init(Arena arena) { .width(px.get(JAVA_INT, 0)) .height(py.get(JAVA_INT, 0)) .pixels(data)); - STBImage.free(data); + stbImage.free(data); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/modules/samples/src/test/java/overrungl/demo/opengl/GL15Test.java b/modules/samples/src/test/java/overrungl/demo/opengl/GL15Test.java index 6b3b2d92..768103ba 100644 --- a/modules/samples/src/test/java/overrungl/demo/opengl/GL15Test.java +++ b/modules/samples/src/test/java/overrungl/demo/opengl/GL15Test.java @@ -112,10 +112,11 @@ private void load(Arena arena) { GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST); GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST); try { + final STBImage stbImage = STBImage.INSTANCE; var px = arena.allocate(JAVA_INT); var py = arena.allocate(JAVA_INT); var pc = arena.allocate(JAVA_INT); - var data = STBImage.loadFromMemory( + var data = stbImage.loadFromMemory( IOUtil.ioResourceToSegment(arena, "image.png", 256, 128), px, py, pc, STBImage.RGB ); @@ -128,7 +129,7 @@ private void load(Arena arena) { GL.RGB, GL.UNSIGNED_BYTE, data); - STBImage.free(data); + stbImage.free(data); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/modules/samples/src/test/java/overrungl/demo/opengl/GL30Test.java b/modules/samples/src/test/java/overrungl/demo/opengl/GL30Test.java index b47a87f7..5d3cee9b 100644 --- a/modules/samples/src/test/java/overrungl/demo/opengl/GL30Test.java +++ b/modules/samples/src/test/java/overrungl/demo/opengl/GL30Test.java @@ -107,10 +107,11 @@ private void load(Arena arena) { GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST); GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST); try (MemoryStack stack = MemoryStack.stackPush()) { + final STBImage stbImage = STBImage.INSTANCE; var px = stack.allocate(JAVA_INT); var py = stack.allocate(JAVA_INT); var pc = stack.allocate(JAVA_INT); - var data = STBImage.loadFromMemory( + var data = stbImage.loadFromMemory( IOUtil.ioResourceToSegment(arena, "image.png", 256), px, py, pc, STBImage.RGB ); @@ -123,7 +124,7 @@ private void load(Arena arena) { GL.RGB, GL.UNSIGNED_BYTE, data); - STBImage.free(data); + stbImage.free(data); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/modules/samples/src/test/java/overrungl/demo/stb/STBPerlinTest.java b/modules/samples/src/test/java/overrungl/demo/stb/STBPerlinTest.java index 28897d9f..ad725aec 100644 --- a/modules/samples/src/test/java/overrungl/demo/stb/STBPerlinTest.java +++ b/modules/samples/src/test/java/overrungl/demo/stb/STBPerlinTest.java @@ -18,13 +18,12 @@ import overrungl.stb.STBImage; import overrungl.stb.STBImageWrite; +import overrungl.stb.STBPerlin; import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; import java.lang.foreign.ValueLayout; -import static overrungl.stb.STBPerlin.*; - /** * Tests STBPerlin and STBImageWrite * @@ -42,10 +41,11 @@ private static void write(Arena arena, float[][] noise, String fileName) { buf.set(ValueLayout.JAVA_BYTE, y * HEIGHT + x, (byte) ((noise[y][x] + 1f) * .5f * 255f)); } } - STBImageWrite.png(fileName, WIDTH, HEIGHT, STBImage.GREY, buf, WIDTH); + STBImageWrite.INSTANCE.png(fileName, WIDTH, HEIGHT, STBImage.GREY, buf, WIDTH); } public static void main(String[] args) { + final STBPerlin stbPerlin = STBPerlin.INSTANCE; try (Arena arena = Arena.ofConfined()) { float[][] noise3 = new float[HEIGHT][WIDTH]; float[][] noise3seed = new float[HEIGHT][WIDTH]; @@ -54,11 +54,11 @@ public static void main(String[] args) { float[][] turbulenceNoise3 = new float[HEIGHT][WIDTH]; for (int y = 0; y < HEIGHT; y++) { for (int x = 0; x < WIDTH; x++) { - noise3[y][x] = noise3(x / 256f, y / 256f, 0, 0, 0, 0); - noise3seed[y][x] = noise3seed(x / 256f, y / 256f, 0, 0, 0, 0, 0b10101010); - fbmNoise3[y][x] = fbmNoise3(x / 256f, y / 256f, 0, 2.0f, 0.5f, 6); - ridgeNoise3[y][x] = ridgeNoise3(x / 256f, y / 256f, 0, 2.0f, 0.5f, 1.0f, 6); - turbulenceNoise3[y][x] = turbulenceNoise3(x / 256f, y / 256f, 0, 2.0f, 0.5f, 6); + noise3[y][x] = stbPerlin.noise3(x / 256f, y / 256f, 0, 0, 0, 0); + noise3seed[y][x] = stbPerlin.noise3seed(x / 256f, y / 256f, 0, 0, 0, 0, 0b10101010); + fbmNoise3[y][x] = stbPerlin.fbmNoise3(x / 256f, y / 256f, 0, 2.0f, 0.5f, 6); + ridgeNoise3[y][x] = stbPerlin.ridgeNoise3(x / 256f, y / 256f, 0, 2.0f, 0.5f, 1.0f, 6); + turbulenceNoise3[y][x] = stbPerlin.turbulenceNoise3(x / 256f, y / 256f, 0, 2.0f, 0.5f, 6); } } write(arena, noise3, "noise3.png");