From e179a15f33573560b9fa804a422f7083100b0d96 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Thu, 16 Oct 2025 02:35:53 +0900 Subject: [PATCH] TAV: more experiments --- .../torvald/tsvm/GraphicsJSR223Delegate.kt | 68 ++++++++++++++++++- video_encoder/encoder_tav.c | 64 +++++++++++++++++ 2 files changed, 131 insertions(+), 1 deletion(-) diff --git a/tsvm_core/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt b/tsvm_core/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt index ecd96f4..bf0366a 100644 --- a/tsvm_core/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt +++ b/tsvm_core/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt @@ -5974,7 +5974,7 @@ class GraphicsJSR223Delegate(private val vm: VM) { } } - // Simple reconstruction (revert to working version) + // Simple reconstruction for (i in 0 until length) { if (i % 2 == 0) { // Even positions: low-pass coefficients @@ -5991,6 +5991,72 @@ class GraphicsJSR223Delegate(private val vm: VM) { } } + fun tavApplyDWT97IintInverse1D(data: FloatArray, length: Int) { + if (data.size < 2) return + if (length < 2) return + + val half = (length + 1) / 2 + val temp = FloatArray(length) + for (i in 0 until length) temp[i] = data[i] + + val SHIFT = 16 + val ROUND = 1L shl (SHIFT - 1) + + val A = -103949L // α + val B = -3472L // β + val G = 57862L // γ + val D = 29066L // δ + val K_FP = 80542L // ≈ 1.230174105 * 2^16 + val Ki_FP = 53283L // ≈ (1/1.230174105) * 2^16 + + fun rn(x: Long): Float = if (x >= 0) ((x + ROUND) shr SHIFT).toInt().toFloat() + else (-(((-x) + ROUND) shr SHIFT)).toInt().toFloat() + + // Undo scaling + for (i in 0 until half) + temp[i] = rn(Ki_FP * temp[i].toLong()) // s /= K + for (i in 0 until length / 2) + if (half + i < length) + temp[half + i] = rn(K_FP * temp[half + i].toLong()) // d *= K + + // Undo δ + for (i in 0 until half) { + val d = if (half + i < length) temp[half + i] else 0f + val dp = if (i > 0 && half + i - 1 < length) temp[half + i - 1] else d + temp[i] -= rn(D * (dp + d).toLong()) + } + + // Undo γ + for (i in 0 until length / 2) { + val s = temp[i] + val sn = if (i + 1 < half) temp[i + 1] else s + temp[half + i] -= rn(G * (s + sn).toLong()) + } + + // Undo β + for (i in 0 until half) { + val d = if (half + i < length) temp[half + i] else 0f + val dp = if (i > 0 && half + i - 1 < length) temp[half + i - 1] else d + temp[i] -= rn(B * (dp + d).toLong()) + } + + // Undo α + for (i in 0 until length / 2) { + val s = temp[i] + val sn = if (i + 1 < half) temp[i + 1] else s + temp[half + i] -= rn(A * (s + sn).toLong()) + } + + // Merge back to original layout + for (i in 0 until length) { + data[i] = if ((i and 1) == 0) temp[i / 2] + else { + val idx = i / 2 + if (half + idx < length) temp[half + idx] else 0f + } + } + } + private fun tavApplyDWT53Inverse1D(data: FloatArray, length: Int) { if (length < 2) return diff --git a/video_encoder/encoder_tav.c b/video_encoder/encoder_tav.c index 6f46a7c..4545e28 100644 --- a/video_encoder/encoder_tav.c +++ b/video_encoder/encoder_tav.c @@ -1059,6 +1059,70 @@ static void dwt_97_forward_1d(float *data, int length) { free(temp); } +// 1D DWT using lifting scheme for 9/7 integer-reversible filter +static void dwt_97_iint_forward_1d(float *data, int length) { + if (length < 2) return; + float *temp = malloc(length * sizeof(float)); + int half = (length + 1) / 2; + + for (int i = 0; i < half; ++i) temp[i] = data[2*i]; + for (int i = 0; i < length/2; ++i) temp[half + i] = data[2*i + 1]; + + const int SHIFT = 16; + const int64_t ROUND = 1LL << (SHIFT - 1); + const int64_t A = -103949; // α + const int64_t B = -3472; // β + const int64_t G = 57862; // γ + const int64_t D = 29066; // δ + const int64_t K_FP = 80542; // ≈ 1.230174105 * 2^16 + const int64_t Ki_FP = 53283; // ≈ (1/1.230174105) * 2^16 + + #define RN(x) (((x)>=0)?(((x)+ROUND)>>SHIFT):(-((-(x)+ROUND)>>SHIFT))) + + // Predict α + for (int i = 0; i < length/2; ++i) { + int s = temp[i]; + int sn = (i+10 && half+i-10 && half+i-1> SHIFT); // s * K + } + for (int i = 0; i < length/2; ++i) { + if (half + i < length) { + temp[half + i] = (((int64_t)temp[half + i] * Ki_FP + ROUND) >> SHIFT); // d / K + } + } + + memcpy(data, temp, length * sizeof(float)); + free(temp); + #undef RN +} + + // Four-point interpolating Deslauriers-Dubuc (DD-4) wavelet forward 1D transform // Uses four-sample prediction kernel: w[-1]=-1/16, w[0]=9/16, w[1]=9/16, w[2]=-1/16 static void dwt_dd4_forward_1d(float *data, int length) {