diff --git a/terranmon.txt b/terranmon.txt index f53f5df..b045469 100644 --- a/terranmon.txt +++ b/terranmon.txt @@ -901,10 +901,10 @@ transmission capability, and region-of-interest coding. - frame count of 0 is used to denote not-finalised video stream uint8 Wavelet Filter Type: - 0 = 5/3 reversible (LGT 5/3, JPEG 2000 standard) - - 1 = 9/7 irreversible (CDF 9/7, slight modification of JPEG 2000) + - 1 = 9/7 irreversible (CDF 9/7, slight modification of JPEG 2000, default choice) - 2 = CDF 13/7 (experimental) - 16 = DD-4 (Four-point interpolating Deslauriers-Dubuc; experimental) - - 255 = Haar (experimental) + - 255 = Haar (demonstration purpose only) uint8 Decomposition Levels: number of DWT levels (1-6+) uint8 Quantiser Index for Y channel (1: lossless, 255: potato) uint8 Quantiser Index for Co channel (1: lossless, 255: potato) @@ -917,7 +917,7 @@ transmission capability, and region-of-interest coding. uint8 Video Flags - bit 0 = has alpha channel - bit 1 = is NTSC framerate - - bit 2 = is lossless mode + - bit 2 = is lossless mode (shorthand for `-q 5 -Q1,1,1 -w 0`) - bit 3 = has region-of-interest coding (for still images only) uint8 Encoder quality level (stored with bias of 1 (q0=1); used to derive anisotropy value) uint8 File Role diff --git a/tsvm_core/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt b/tsvm_core/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt index b71729a..7ef36cd 100644 --- a/tsvm_core/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt +++ b/tsvm_core/src/net/torvald/tsvm/GraphicsJSR223Delegate.kt @@ -3950,8 +3950,8 @@ class GraphicsJSR223Delegate(private val vm: VM) { return subbands } - var ANISOTROPY_MULT = floatArrayOf(1.8f, 1.6f, 1.4f, 1.2f, 1.0f, 1.0f) - var ANISOTROPY_BIAS = floatArrayOf(0.2f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f) + var ANISOTROPY_MULT = floatArrayOf(2.0f, 1.8f, 1.6f, 1.4f, 1.2f, 1.0f) + var ANISOTROPY_BIAS = floatArrayOf(0.4f, 0.2f, 0.1f, 0.0f, 0.0f, 0.0f) var ANISOTROPY_MULT_CHROMA = floatArrayOf(6.6f, 5.5f, 4.4f, 3.3f, 2.2f, 1.1f) var ANISOTROPY_BIAS_CHROMA = floatArrayOf(1.0f, 0.8f, 0.6f, 0.4f, 0.2f, 0.0f) @@ -5314,6 +5314,18 @@ class GraphicsJSR223Delegate(private val vm: VM) { // Biorthogonal 13/7 inverse lifting (undo forward steps in reverse order) // Must exactly reverse the operations from the forward transform (simplified to match 5/3 structure) + val K = 1.230174105f + + // Step 1: Undo scaling - s[i] /= K, d[i] *= K + for (i in 0 until half) { + temp[i] /= K // Low-pass coefficients + } + for (i in 0 until length / 2) { + if (half + i < length) { + temp[half + i] *= K // High-pass coefficients + } + } + // Step 2: Undo update step (reverse of encoder step 2) for (i in 0 until half) { val leftIdx = half + i - 1 diff --git a/video_encoder/encoder_tav.c b/video_encoder/encoder_tav.c index 7e3b065..c2f297b 100644 --- a/video_encoder/encoder_tav.c +++ b/video_encoder/encoder_tav.c @@ -152,8 +152,8 @@ static const int QUALITY_CG[] = {240, 180, 120, 60, 30, 5}; //static const int QUALITY_CG[] = {120, 60, 30, 15, 10, 4}; // psychovisual tuning parameters -static const float ANISOTROPY_MULT[] = {1.8f, 1.6f, 1.4f, 1.2f, 1.0f, 1.0f}; -static const float ANISOTROPY_BIAS[] = {0.2f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f}; +static const float ANISOTROPY_MULT[] = {2.0f, 1.8f, 1.6f, 1.4f, 1.2f, 1.0f}; +static const float ANISOTROPY_BIAS[] = {0.4f, 0.2f, 0.1f, 0.0f, 0.0f, 0.0f}; static const float ANISOTROPY_MULT_CHROMA[] = {6.6f, 5.5f, 4.4f, 3.3f, 2.2f, 1.1f}; static const float ANISOTROPY_BIAS_CHROMA[] = {1.0f, 0.8f, 0.6f, 0.4f, 0.2f, 0.0f}; @@ -668,6 +668,9 @@ static void dwt_dd4_forward_1d(float *data, int length) { static void dwt_bior137_forward_1d(float *data, int length) { if (length < 2) return; + const float K = 1.230174105f; + + float *temp = malloc(length * sizeof(float)); int half = (length + 1) / 2; @@ -693,6 +696,16 @@ static void dwt_bior137_forward_1d(float *data, int length) { temp[i] = data[2 * i] + update; } + // Step 5: Scaling - s[i] *= K, d[i] /= K + for (int i = 0; i < half; i++) { + temp[i] *= K; // Low-pass coefficients + } + for (int i = 0; i < length / 2; i++) { + if (half + i < length) { + temp[half + i] /= K; // High-pass coefficients + } + } + memcpy(data, temp, length * sizeof(float)); free(temp); } @@ -2757,6 +2770,18 @@ int main(int argc, char *argv[]) { enc->quantiser_cg = enc->quantiser_co; } + // disable perceptual tuning if wavelet filter is not CDF 9/7 + if (enc->wavelet_filter != WAVELET_9_7_IRREVERSIBLE) { + enc->perceptual_tuning = 0; + + // halve the quantiser if wavelet filter is not CDF 9/7 && not CDF 13/7 + if (enc->wavelet_filter != WAVELET_BIORTHOGONAL_13_7) { + enc->quantiser_y = CLAMP(enc->quantiser_y >> 1, 1, 255); + enc->quantiser_co = CLAMP(enc->quantiser_co >> 1, 1, 255); + enc->quantiser_cg = CLAMP(enc->quantiser_cg >> 1, 1, 255); + } + } + if ((!enc->input_file && !enc->test_mode) || !enc->output_file) { fprintf(stderr, "Error: Input and output files must be specified\n"); show_usage(argv[0]);