From 0f33c0c6e3c94be707ae0c4fbdf544e80713fc6d Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 11 Mar 2026 20:23:01 +0100 Subject: [PATCH 01/10] Remove unused import --- .../src/main/java/org/khronos/ktx/KtxAstcParams.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/java_binding/src/main/java/org/khronos/ktx/KtxAstcParams.java b/interface/java_binding/src/main/java/org/khronos/ktx/KtxAstcParams.java index b12def5180..b706b9a1f6 100644 --- a/interface/java_binding/src/main/java/org/khronos/ktx/KtxAstcParams.java +++ b/interface/java_binding/src/main/java/org/khronos/ktx/KtxAstcParams.java @@ -6,8 +6,6 @@ package org.khronos.ktx; -import java.util.Arrays; - /** * Structure for passing extended parameters to * {@link KtxTexture2#compressAstcEx(KtxAstcParams)}.
From 52ce29b4ed2f3a4c69e408ac73c189fc47fd9a82 Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 11 Mar 2026 20:23:37 +0100 Subject: [PATCH 02/10] Add HDR supercompression scheme --- .../org/khronos/ktx/KtxSupercmpScheme.java | 57 +++++++++++-------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/interface/java_binding/src/main/java/org/khronos/ktx/KtxSupercmpScheme.java b/interface/java_binding/src/main/java/org/khronos/ktx/KtxSupercmpScheme.java index 7771b85f29..1f3e95aeab 100644 --- a/interface/java_binding/src/main/java/org/khronos/ktx/KtxSupercmpScheme.java +++ b/interface/java_binding/src/main/java/org/khronos/ktx/KtxSupercmpScheme.java @@ -34,32 +34,39 @@ public class KtxSupercmpScheme { */ public static final int ZLIB = 3; - /** - * Returns a string representation of the given supercompression scheme - * - * @param n The supercompression scheme - * @return A string representation of the given supercompression scheme - */ - public static String stringFor(int n) { - switch (n) { - case NONE: - return "NONE"; - case BASIS_LZ: - return "BASIS_LZ"; - case ZSTD: - return "ZSTD"; - case ZLIB: - return "ZLIB"; - } - return "[Unknown KtxSupercmpScheme]"; - } + /** + * UASTC HDR 6x6 Intermediate supercompression. + */ + public static final int UASTC_HDR_6X6_INTERMEDIATE = 4; - /** - * Private constructor to prevent instantiation - */ - private KtxSupercmpScheme() { - // Prevent instantiation - } + /** + * Returns a string representation of the given supercompression scheme + * + * @param n The supercompression scheme + * @return A string representation of the given supercompression scheme + */ + public static String stringFor(int n) { + switch (n) { + case NONE: + return "NONE"; + case BASIS_LZ: + return "BASIS_LZ"; + case ZSTD: + return "ZSTD"; + case ZLIB: + return "ZLIB"; + case UASTC_HDR_6X6_INTERMEDIATE: + return "UASTC_HDR_6X6_INTERMEDIATE"; + } + return "[Unknown KtxSupercmpScheme]"; + } + + /** + * Private constructor to prevent instantiation + */ + private KtxSupercmpScheme() { + // Prevent instantiation + } } From a346aa6b7dbabd1c9e7673b1bde848ef2c845b99 Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 11 Mar 2026 20:23:50 +0100 Subject: [PATCH 03/10] Add HDR transcode formats --- .../org/khronos/ktx/KtxTranscodeFormat.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/interface/java_binding/src/main/java/org/khronos/ktx/KtxTranscodeFormat.java b/interface/java_binding/src/main/java/org/khronos/ktx/KtxTranscodeFormat.java index 2975dbd79a..e232361509 100644 --- a/interface/java_binding/src/main/java/org/khronos/ktx/KtxTranscodeFormat.java +++ b/interface/java_binding/src/main/java/org/khronos/ktx/KtxTranscodeFormat.java @@ -146,7 +146,27 @@ public class KtxTranscodeFormat { * Automatically selects BC1_RGB or BC3_RGBA according to presence of alpha. */ public static final int BC1_OR_3 = 23; + + /** + * 48bpp RGB half (16-bits/component, 3 components) + */ + public static final int RGBA_HALF = 25; + /** + * HDR, RGBA (currently UASTC HDR 4x4 encoders are only RGB), unsigned + */ + public static final int ASTC_HDR_4x4_RGBA = 29; + + /** + * HDR, RGBA (currently UASTC HDR 4x4 encoders are only RGB), unsigned + */ + public static final int ASTC_HDR_6x6_RGBA = 30; + + /** + * HDR, RGB only, unsigned + */ + public static final int BC6HU = 31; + public static final int NOSELECTION = 0x7fffffff; /** @@ -177,6 +197,10 @@ public static String stringFor(int n) { case RGBA4444: return "RGBA4444"; case ETC: return "ETC"; case BC1_OR_3: return "BC1_OR_3"; + case RGBA_HALF: return "RGBA_HALF"; + case ASTC_HDR_4x4_RGBA: return "ASTC_HDR_4x4_RGBA"; + case ASTC_HDR_6x6_RGBA: return "ASTC_HDR_6x6_RGBA"; + case BC6HU: return "BC6HU"; case NOSELECTION: return "NOSELECTION"; } return "[Unknown KtxTranscodeFormat]"; From 978380611a41797c2784042654b142926d1c5d4a Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 11 Mar 2026 20:24:48 +0100 Subject: [PATCH 04/10] Add basis codec options (enum) --- .../java/org/khronos/ktx/KtxBasisCodec.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 interface/java_binding/src/main/java/org/khronos/ktx/KtxBasisCodec.java diff --git a/interface/java_binding/src/main/java/org/khronos/ktx/KtxBasisCodec.java b/interface/java_binding/src/main/java/org/khronos/ktx/KtxBasisCodec.java new file mode 100644 index 0000000000..7a3fe420c8 --- /dev/null +++ b/interface/java_binding/src/main/java/org/khronos/ktx/KtxBasisCodec.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2026, Khronos Group and Contributors + * SPDX-License-Identifier: Apache-2.0 + */ +package org.khronos.ktx; + +/** + * Options specifying basis codec.
+ *
+ * These constants can be passed to the {@link KtxBasisParams#setCodec(int)} + * function. + */ +public class KtxBasisCodec { + /** + * None + */ + public static final int NONE = 0; + + /** + * BasisLZ + */ + public static final int ETC1S = 1; + + /** + * UASTC + */ + public static final int UASTC_LDR = 2; + + /** + * UASTC_HDR_4X4 + */ + public static final int UASTC_HDR_4X4 = 3; + + /** + * UASTC_HDR_6X6i + */ + public static final int UASTC_HDR_6X6_INTERMEDIATE = 4; + + /** + * Returns a string representation of the given basis codec + * + * @param n The basis codec + * @return A string representation of the given basis codec + */ + public static String stringFor(int n) { + switch (n) { + case NONE: + return "NONE"; + case ETC1S: + return "ETC1S"; + case UASTC_LDR: + return "UASTC_LDR"; + case UASTC_HDR_4X4: + return "UASTC_HDR_4X4"; + case UASTC_HDR_6X6_INTERMEDIATE: + return "UASTC_HDR_6X6_INTERMEDIATE"; + } + return "[Unknown KtxBasisCodec]"; + } + + /** + * Private constructor to prevent instantiation + */ + private KtxBasisCodec() { + // Prevent instantiation + } + +} From 2ee05d0dbacbd46a403d08b0096a2a0704fb7fa3 Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 11 Mar 2026 20:25:03 +0100 Subject: [PATCH 05/10] Use basis codec options in tests --- .../test/java/org/khronos/ktx/test/KtxTexture2Test.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/interface/java_binding/src/test/java/org/khronos/ktx/test/KtxTexture2Test.java b/interface/java_binding/src/test/java/org/khronos/ktx/test/KtxTexture2Test.java index 5699293ac5..d420ae9a28 100644 --- a/interface/java_binding/src/test/java/org/khronos/ktx/test/KtxTexture2Test.java +++ b/interface/java_binding/src/test/java/org/khronos/ktx/test/KtxTexture2Test.java @@ -20,6 +20,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.khronos.ktx.KtxBasisCodec; import org.khronos.ktx.KtxBasisParams; import org.khronos.ktx.KtxTextureCreateStorage; import org.khronos.ktx.KtxErrorCode; @@ -486,7 +487,7 @@ public void testInputSwizzleBasisEx() throws IOException { // the former G channel becomes the B channel // the former A channel remains the A channel KtxBasisParams inputParams = new KtxBasisParams(); - inputParams.setCodec(1); + inputParams.setCodec(KtxBasisCodec.ETC1S); inputParams.setInputSwizzle(new char[] { 'b', 'r', 'g', 'a' }); inputTexture.compressBasisEx(inputParams); @@ -519,7 +520,7 @@ public void testInputSwizzleBasisEx() throws IOException { // Apply basis compression to the reference, without swizzling KtxBasisParams goldParams = new KtxBasisParams(); - goldParams.setCodec(1); + goldParams.setCodec(KtxBasisCodec.ETC1S); goldTexture.compressBasisEx(goldParams); // Transcode the reference texture to RGBA32 @@ -550,7 +551,7 @@ public void testSupercompressionZstd() throws IOException { // Apply default UASTC compression KtxBasisParams p = new KtxBasisParams(); - p.setCodec(2); + p.setCodec(KtxBasisCodec.UASTC_LDR); t.compressBasisEx(p); // The supercompression scheme should be NONE here @@ -584,7 +585,7 @@ public void testSupercompressionZLIB() throws IOException { // Apply default UASTC compression KtxBasisParams p = new KtxBasisParams(); - p.setCodec(2); + p.setCodec(KtxBasisCodec.UASTC_LDR); t.compressBasisEx(p); // The supercompression scheme should be NONE here From 2536df4313ca872be4e4842b57f5125e2485c738 Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 11 Mar 2026 20:25:16 +0100 Subject: [PATCH 06/10] Update path for Java 8 compatibility --- .../test/java/org/khronos/ktx/test/KtxTestLibraryLoader.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/java_binding/src/test/java/org/khronos/ktx/test/KtxTestLibraryLoader.java b/interface/java_binding/src/test/java/org/khronos/ktx/test/KtxTestLibraryLoader.java index 686dd68282..3a1655200a 100644 --- a/interface/java_binding/src/test/java/org/khronos/ktx/test/KtxTestLibraryLoader.java +++ b/interface/java_binding/src/test/java/org/khronos/ktx/test/KtxTestLibraryLoader.java @@ -9,6 +9,7 @@ import java.io.File; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Locale; import org.junit.jupiter.api.extension.BeforeAllCallback; @@ -64,7 +65,7 @@ private static String findKtxJniLibraryName() { return null; } - Path ktxPath = Path.of(ktxDir); + Path ktxPath = Paths.get(ktxDir); if (!ktxPath.isAbsolute() || !Files.exists(ktxPath) || !Files.isDirectory(ktxPath)) { System.out.println( "KTXTestLibraryLoader: The value of the LIBKTX_BINARY_DIR environment variable is invalid: " From dd826eda548b3e319f91a066a1788b957f01ed32 Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 11 Mar 2026 20:25:31 +0100 Subject: [PATCH 07/10] Add new basis params --- .../java/org/khronos/ktx/KtxBasisParams.java | 235 ++++++++++++++++-- 1 file changed, 221 insertions(+), 14 deletions(-) diff --git a/interface/java_binding/src/main/java/org/khronos/ktx/KtxBasisParams.java b/interface/java_binding/src/main/java/org/khronos/ktx/KtxBasisParams.java index 5149017008..7537c51c8e 100644 --- a/interface/java_binding/src/main/java/org/khronos/ktx/KtxBasisParams.java +++ b/interface/java_binding/src/main/java/org/khronos/ktx/KtxBasisParams.java @@ -6,8 +6,6 @@ package org.khronos.ktx; -import java.util.Arrays; - /** * Structure for passing parameters to {@link KtxTexture2#compressBasisEx(KtxBasisParams)}.
*
@@ -48,9 +46,9 @@ public class KtxBasisParams { private int threadCount; /** - * Encoding speed vs. quality tradeoff + * ETC1S compression effort level. */ - private int compressionLevel; + private int etc1sCompressionLevel; /** * Compression quality @@ -142,6 +140,41 @@ public class KtxBasisParams { */ private boolean uastcRDONoMultithreading; + /** + * The UASTC HDR 4x4 compressor's level + */ + private int uastcHDRQuality; + + /** + * Allow the UASTC HDR 4x4 encoder to try varying the CEM 11 selectors + */ + private boolean uastcHDRUberMode; + + /** + * Try to find better quantized CEM 7/11 endpoint values (slower) + */ + private boolean uastcHDRUltraQuant; + + /** + * Whether ASTC HDR 4x4 quality is favored + */ + private boolean uastcHDRFavorAstc; + + /** + * Whether the input image's gamut is Rec. 2020 vs. the default Rec. 709 + */ + private boolean rec2020; + + /** + * Enables rate distortion optimization + */ + private float uastcHDRLambda; + + /** + * Controls the 6x6 HDR intermediate mode encoder performance + */ + private int uastcHDRLevel; + /** * Returns the used codec. * @@ -230,28 +263,32 @@ public void setThreadCount(int threadCount) { } /** - * Returns the encoding speed versus quality tradeoff. + * Returns the ETC1S compression effort level. * - * See {@link #setCompressionLevel(int)} + * See {@link #setEtc1sCompressionLevel(int)} * * @return The compression level */ - public int getCompressionLevel() { - return compressionLevel; + public int getEtc1sCompressionLevel() { + return etc1sCompressionLevel; } /** - * Set the encoding speed versus quality tradeoff.
+ * Set the ETC1S compression effort level.
*
- * The range is [0,5]. Higher values are slower, but give higher quality. - * There is no default. Callers must explicitly set this value. Callers + * Range is [0,6]. Higher values are much slower, but give slightly + * higher quality. Higher levels are intended for video. This + * parameter controls numerous internal encoding speed vs. compression + * efficiency/performance tradeoffs. Note this is NOT the same as the + * ETC1S quality level, and most users shouldn't change this. There + * is no default. Callers must explicitly set this value. Callers * can use {@link #ETC1S_DEFAULT_COMPRESSION_LEVEL} as a default value. * Currently this is 2. * - * @param compressionLevel The compression level + * @param etc1sCompressionLevel The compression level */ - public void setCompressionLevel(int compressionLevel) { - this.compressionLevel = compressionLevel; + public void setEtc1sCompressionLevel(int etc1sCompressionLevel) { + this.etc1sCompressionLevel = etc1sCompressionLevel; } /** @@ -690,4 +727,174 @@ public boolean isUastcRDONoMultithreading() { public void setUastcRDONoMultithreading(boolean uastcRDONoMultithreading) { this.uastcRDONoMultithreading = uastcRDONoMultithreading; } + + /** + * Returns the HRD 4x4 compressor level. + * + * See {@link #setUastcHDRQuality(int)} + * + * @return The setting + */ + public int getUastcHDRQuality() { + return uastcHDRQuality; + } + + /** + * Set the HRD 4x4 compressor level.
+ *
+ * UASTC HDR 4x4: Sets the UASTC HDR 4x4 compressor's level. Valid + * range is [0,4] - higher=slower but higher quality. HDR default=1. + * Level 0=fastest/lowest quality, 3=highest practical setting, + * 4=exhaustive + * + * @param uastcHDRQuality The quality + */ + public void setUastcHDRQuality(int uastcHDRQuality) { + this.uastcHDRQuality = uastcHDRQuality; + } + + /** + * Returns the UASTC uber mode. + * + * See {@link #setUastcHDRUberMode(boolean)} + * + * @return The setting + */ + public boolean isUastcHDRUberMode() { + return uastcHDRUberMode; + } + + /** + * Set the UASTC uber mode.
+ *
+ * UASTC HDR 4x4: Allow the UASTC HDR 4x4 encoder to try varying the + * CEM 11 selectors more for slightly higher quality (slower). + * This may negatively impact BC6H quality, however. + * + * @param uastcHDRUberMode The setting + */ + public void setUastcHDRUberMode(boolean uastcHDRUberMode) { + this.uastcHDRUberMode = uastcHDRUberMode; + } + + /** + * Returns the ultra quantization mode. + * + * See {@link #setUastcHDRUltraQuant(boolean)} + * + * @return The setting + */ + public boolean isUastcHDRUltraQuant() { + return uastcHDRUltraQuant; + } + + /** + * Set the ultra quantization mode.
+ *
+ * ASTC HDR 4x4: Try to find better quantized CEM 7/11 endpoint values + * (slower) + * + * @param uastcHDRUltraQuant The setting + */ + public void setUastcHDRUltraQuant(boolean uastcHDRUltraQuant) { + this.uastcHDRUltraQuant = uastcHDRUltraQuant; + } + + /** + * Returns whether to favor ASTC HDR 4x4 quality. + * + * See {@link #setUastcHDRFavorAstc(boolean)} + * + * @return The setting + */ + public boolean isUastcHDRFavorAstc() { + return uastcHDRFavorAstc; + } + + /** + * Set whether to favor ASTC HDR 4x4 quality.
+ *
+ * UASTC HDR 4x4: By default the UASTC HDR 4x4 encoder tries to + * strike a balance or even slightly favor BC6H quality. If this + * option is specified, ASTC HDR 4x4 quality is favored instead. + * + * @param uastcHDRFavorAstc The setting + */ + public void setUastcHDRFavorAstc(boolean uastcHDRFavorAstc) { + this.uastcHDRFavorAstc = uastcHDRFavorAstc; + } + + /** + * Returns whether the input image is Rec. 2020. + * + * See {@link #setRec2020(boolean)} + * + * @return The setting + */ + public boolean isRec2020() { + return rec2020; + } + + /** + * Set whether the input image is Rec. 2020.
+ *
+ * UASTC HDR 6x6i specific option: The input image's gamut is Rec. + * 2020 vs. the default Rec. 709 - for accurate colorspace error + * calculations. + * + * @param rec2020 The setting. + */ + public void setRec2020(boolean rec2020) { + this.rec2020 = rec2020; + } + + /** + * Returns whether rate distortion optimization (RDO) is enabled. + * + * See {@link #setUastcHDRLambda(float)} + * + * @return The setting + */ + public float getUastcHDRLambda() { + return uastcHDRLambda; + } + + /** + * Set whether rate distortion optimization (RDO) is enabled.
+ *
+ * UASTC HDR 6x6i specific option: Enables rate distortion + * optimization (RDO). The higher this value, the lower the quality, + * but the smaller the file size. Try 100-20000, or higher values + * on some images. + * + * @param uastcHDRLambda The setting + */ + public void setUastcHDRLambda(float uastcHDRLambda) { + this.uastcHDRLambda = uastcHDRLambda; + } + + /** + * Returns the HDR encoder tradeoff. + * + * See {@link #setUastcHDRLevel(int)} + * + * @return The setting + */ + public int getUastcHDRLevel() { + return uastcHDRLevel; + } + + /** + * Returns the HDR encoder tradeoff.
+ *
+ * UASTC HDR 6x6i specific option: Controls the 6x6 HDR intermediate + * mode encoder performance vs. max quality tradeoff. X may range + * from [0,12]. Default level is 2. + * + * @param uastcHDRLevel The setting + */ + public void setUastcHDRLevel(int uastcHDRLevel) { + this.uastcHDRLevel = uastcHDRLevel; + } + } From 50cf2b5e54016018c1311f1428c7bbb63c01c22d Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 1 Apr 2026 14:17:22 +0200 Subject: [PATCH 08/10] Add ktxBasisParams fields in JNI --- .../java_binding/src/main/cpp/libktx-jni.cpp | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/interface/java_binding/src/main/cpp/libktx-jni.cpp b/interface/java_binding/src/main/cpp/libktx-jni.cpp index 955507a34e..3bf2a0cfc2 100644 --- a/interface/java_binding/src/main/cpp/libktx-jni.cpp +++ b/interface/java_binding/src/main/cpp/libktx-jni.cpp @@ -75,6 +75,13 @@ jfieldID KtxBasisParams_uastcRDOMaxSmoothBlockErrorScale_field; // "F" jfieldID KtxBasisParams_uastcRDOMaxSmoothBlockStdDev_field; // "F" jfieldID KtxBasisParams_uastcRDODontFavorSimplerModes_field; // "Z" jfieldID KtxBasisParams_uastcRDONoMultithreading_field; // "Z" +jfieldID KtxBasisParams_uastcHDRQuality_field; // "I" +jfieldID KtxBasisParams_uastcHDRUberMode_field; // "Z" +jfieldID KtxBasisParams_uastcHDRUltraQuant_field; // "Z" +jfieldID KtxBasisParams_uastcHDRFavorAstc_field; // "Z" +jfieldID KtxBasisParams_rec2020_field; // "Z" +jfieldID KtxBasisParams_uastcHDRLambda_field; // "F" +jfieldID KtxBasisParams_uastcHDRLevel_field; // "I" /** @@ -155,7 +162,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *) if (!initField(env, cls, KtxBasisParams_verbose_field, "verbose", "Z")) return JNI_ERR; if (!initField(env, cls, KtxBasisParams_noSSE_field, "noSSE", "Z")) return JNI_ERR; if (!initField(env, cls, KtxBasisParams_threadCount_field, "threadCount", "I")) return JNI_ERR; - if (!initField(env, cls, KtxBasisParams_etc1sCompressionLevel_field, "compressionLevel", "I")) return JNI_ERR; + if (!initField(env, cls, KtxBasisParams_etc1sCompressionLevel_field, "etc1sCompressionLevel", "I")) return JNI_ERR; if (!initField(env, cls, KtxBasisParams_qualityLevel_field, "qualityLevel", "I")) return JNI_ERR; if (!initField(env, cls, KtxBasisParams_maxEndpoints_field, "maxEndpoints", "I")) return JNI_ERR; if (!initField(env, cls, KtxBasisParams_endpointRDOThreshold_field, "endpointRDOThreshold", "F")) return JNI_ERR; @@ -174,6 +181,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *) if (!initField(env, cls, KtxBasisParams_uastcRDOMaxSmoothBlockStdDev_field, "uastcRDOMaxSmoothBlockStdDev", "F")) return JNI_ERR; if (!initField(env, cls, KtxBasisParams_uastcRDODontFavorSimplerModes_field, "uastcRDODontFavorSimplerModes", "Z")) return JNI_ERR; if (!initField(env, cls, KtxBasisParams_uastcRDONoMultithreading_field, "uastcRDONoMultithreading", "Z")) return JNI_ERR; + if (!initField(env, cls, KtxBasisParams_uastcHDRQuality_field, "uastcHDRQuality", "I")) return JNI_ERR; + if (!initField(env, cls, KtxBasisParams_uastcHDRUberMode_field, "uastcHDRUberMode", "Z")) return JNI_ERR; + if (!initField(env, cls, KtxBasisParams_uastcHDRUltraQuant_field, "uastcHDRUltraQuant", "Z")) return JNI_ERR; + if (!initField(env, cls, KtxBasisParams_uastcHDRFavorAstc_field, "uastcHDRFavorAstc", "Z")) return JNI_ERR; + if (!initField(env, cls, KtxBasisParams_rec2020_field, "rec2020", "Z")) return JNI_ERR; + if (!initField(env, cls, KtxBasisParams_uastcHDRLambda_field, "uastcHDRLambda", "F")) return JNI_ERR; + if (!initField(env, cls, KtxBasisParams_uastcHDRLevel_field, "uastcHDRLevel", "I")) return JNI_ERR; return JNI_VERSION_1_4; } @@ -320,6 +334,14 @@ bool copy_ktx_basis_params(JNIEnv *env, jobject params, ktxBasisParams &out) out.uastcRDOMaxSmoothBlockStdDev = env->GetFloatField(params, KtxBasisParams_uastcRDOMaxSmoothBlockStdDev_field); out.uastcRDODontFavorSimplerModes = env->GetBooleanField(params, KtxBasisParams_uastcRDODontFavorSimplerModes_field); out.uastcRDONoMultithreading = env->GetBooleanField(params, KtxBasisParams_uastcRDONoMultithreading_field); + out.uastcHDRQuality = env->GetIntField(params, KtxBasisParams_uastcHDRQuality_field); + out.uastcRDONoMultithreading = env->GetBooleanField(params, KtxBasisParams_uastcRDONoMultithreading_field); + out.uastcHDRUberMode = env->GetBooleanField(params, KtxBasisParams_uastcHDRUberMode_field); + out.uastcHDRUltraQuant = env->GetBooleanField(params, KtxBasisParams_uastcHDRUltraQuant_field); + out.uastcHDRFavorAstc = env->GetBooleanField(params, KtxBasisParams_uastcRDONoMultithreading_field); + out.rec2020 = env->GetBooleanField(params, KtxBasisParams_rec2020_field); + out.uastcHDRLambda = env->GetFloatField(params, KtxBasisParams_uastcHDRLambda_field); + out.uastcHDRLevel = env->GetIntField(params, KtxBasisParams_uastcHDRLevel_field); return true; } From ff2f864a8faca8baf66ab4b57eb62223bd7d684f Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 1 Apr 2026 14:59:23 +0200 Subject: [PATCH 09/10] Minor comment about data types --- interface/java_binding/src/main/cpp/libktx-jni.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/interface/java_binding/src/main/cpp/libktx-jni.cpp b/interface/java_binding/src/main/cpp/libktx-jni.cpp index 3bf2a0cfc2..bb2a15092a 100644 --- a/interface/java_binding/src/main/cpp/libktx-jni.cpp +++ b/interface/java_binding/src/main/cpp/libktx-jni.cpp @@ -27,7 +27,19 @@ jmethodID Buffer_hasArray_method; // "()Z" jmethodID Buffer_array_method; // "()Ljava/lang/Object;" // The field IDs of the Java classes -// The comment indicates their signature/type +// The comment indicates their signature/type: +// Z boolean +// B byte +// C char +// S short +// I int +// J long +// F float +// D double +// L fully-qualified-class; fully-qualified-class +// [ type type[] +// ( arg-types ) ret-type method type + jfieldID KtxTexture_instance_field; // "J" From c6eed3a3d15f166088a3e86edd771b083a8bd4c7 Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 1 Apr 2026 15:02:04 +0200 Subject: [PATCH 10/10] Add HDR-related functions in KtxTexture2 --- .../java_binding/src/main/cpp/KtxTexture2.cpp | 34 +++++++++++++++++++ .../java/org/khronos/ktx/KtxTexture2.java | 25 ++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/interface/java_binding/src/main/cpp/KtxTexture2.cpp b/interface/java_binding/src/main/cpp/KtxTexture2.cpp index 46fe928d10..05c48b310c 100644 --- a/interface/java_binding/src/main/cpp/KtxTexture2.cpp +++ b/interface/java_binding/src/main/cpp/KtxTexture2.cpp @@ -8,6 +8,17 @@ #include #include "libktx-jni.h" +extern "C" JNIEXPORT jint JNICALL Java_org_khronos_ktx_KtxTexture2_getTransferFunction(JNIEnv *env, jobject thiz) +{ + ktxTexture2 *texture = get_ktx2_texture(env, thiz); + if (texture == NULL) + { + ThrowDestroyed(env); + return 0; + } + return ktxTexture2_GetTransferFunction_e(texture); +} + extern "C" JNIEXPORT jint JNICALL Java_org_khronos_ktx_KtxTexture2_getOETF(JNIEnv *env, jobject thiz) { ktxTexture2 *texture = get_ktx2_texture(env, thiz); @@ -41,6 +52,29 @@ extern "C" JNIEXPORT jboolean JNICALL Java_org_khronos_ktx_KtxTexture2_needsTran return ktxTexture2_NeedsTranscoding(texture); } +extern "C" JNIEXPORT jboolean JNICALL Java_org_khronos_ktx_KtxTexture2_isTranscodable(JNIEnv *env, jobject thiz) +{ + ktxTexture2 *texture = get_ktx2_texture(env, thiz); + if (texture == NULL) + { + ThrowDestroyed(env); + return false; + } + return ktxTexture2_IsTranscodable(texture); +} + +extern "C" JNIEXPORT jboolean JNICALL Java_org_khronos_ktx_KtxTexture2_isHDR(JNIEnv *env, jobject thiz) +{ + ktxTexture2 *texture = get_ktx2_texture(env, thiz); + if (texture == NULL) + { + ThrowDestroyed(env); + return false; + } + return ktxTexture2_IsHDR(texture); +} + + extern "C" JNIEXPORT jint JNICALL Java_org_khronos_ktx_KtxTexture2_getVkFormat(JNIEnv *env, jobject thiz) { ktxTexture2 *texture = get_ktx2_texture(env, thiz); diff --git a/interface/java_binding/src/main/java/org/khronos/ktx/KtxTexture2.java b/interface/java_binding/src/main/java/org/khronos/ktx/KtxTexture2.java index 4ff85adf99..fab7eb4e8e 100644 --- a/interface/java_binding/src/main/java/org/khronos/ktx/KtxTexture2.java +++ b/interface/java_binding/src/main/java/org/khronos/ktx/KtxTexture2.java @@ -40,6 +40,17 @@ protected KtxTexture2(long instance) { * * @return The transfer function. */ + public native int getTransferFunction(); + + /** + * Returns the the opto-electrical transfer function of the images.
+ *
+ * This is one of the constants in {@link KhrDfTransfer}. + * + * @return The transfer function. + * @deprecated Only for backward compatibility. + * Use {@link #getTransferFunction()} instead. + */ public native int getOETF(); /** @@ -56,6 +67,20 @@ protected KtxTexture2(long instance) { */ public native boolean needsTranscoding(); + /** + * Query if the images require transcoding or can be used directly. + * + * @return Whether the images require transcoding + */ + public native boolean isTranscodable(); + + /** + * Query if the images are in an HDR format. + * + * @return If the images are in an HDR format. + */ + public native boolean isHDR(); + /** * Return the {@link VkFormat} of this texture *