From 83d6a8e6434ab892b636b0c8f0019dee2bc2e3f9 Mon Sep 17 00:00:00 2001 From: Frank Bossen Date: Tue, 30 Sep 2014 10:24:52 -0400 Subject: [PATCH] Add new quantization tables New quantization tables tuned for PSNR-HVS are added. Per-coefficient lambda weights are now derived based on the quantization table entries. --- cjpeg.c | 18 +++++++-------- jcdctmgr.c | 13 +++++++++-- jcparam.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- rdswitch.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 144 insertions(+), 15 deletions(-) diff --git a/cjpeg.c b/cjpeg.c index 94b1aecb..c6ec4486 100644 --- a/cjpeg.c +++ b/cjpeg.c @@ -508,29 +508,29 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv, } else if (keymatch(arg, "tune-psnr", 6)) { cinfo->quant_tbl_master_idx = 1; - cinfo->lambda_log_scale1 = 9.0; + cinfo->lambda_log_scale1 = 9.25; cinfo->lambda_log_scale2 = 0.0; cinfo->use_lambda_weight_tbl = FALSE; jpeg_set_quality(cinfo, 75, TRUE); } else if (keymatch(arg, "tune-ssim", 6)) { cinfo->quant_tbl_master_idx = 1; - cinfo->lambda_log_scale1 = 12.0; - cinfo->lambda_log_scale2 = 13.5; + cinfo->lambda_log_scale1 = 11.25; + cinfo->lambda_log_scale2 = 12.75; cinfo->use_lambda_weight_tbl = FALSE; jpeg_set_quality(cinfo, 75, TRUE); } else if (keymatch(arg, "tune-ms-ssim", 6)) { - cinfo->quant_tbl_master_idx = 0; - cinfo->lambda_log_scale1 = 14.25; - cinfo->lambda_log_scale2 = 12.75; + cinfo->quant_tbl_master_idx = 2; + cinfo->lambda_log_scale1 = 12.25; + cinfo->lambda_log_scale2 = 13.25; cinfo->use_lambda_weight_tbl = TRUE; jpeg_set_quality(cinfo, 75, TRUE); } else if (keymatch(arg, "tune-hvs-psnr", 6)) { - cinfo->quant_tbl_master_idx = 0; - cinfo->lambda_log_scale1 = 16.0; - cinfo->lambda_log_scale2 = 15.5; + cinfo->quant_tbl_master_idx = 4; + cinfo->lambda_log_scale1 = 13.75; + cinfo->lambda_log_scale2 = 15.25; cinfo->use_lambda_weight_tbl = TRUE; jpeg_set_quality(cinfo, 75, TRUE); diff --git a/jcdctmgr.c b/jcdctmgr.c index 6cab5ab5..249fd83e 100644 --- a/jcdctmgr.c +++ b/jcdctmgr.c @@ -704,6 +704,8 @@ quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *dctbl, c_derived_tbl *actb float *accumulated_dc_cost[3]; int *dc_cost_backtrack[3]; JCOEF *dc_candidate[3]; + int mode = 1; + float lambda_table[DCTSIZE2]; Ss = cinfo->Ss; Se = cinfo->Se; @@ -739,13 +741,20 @@ quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *dctbl, c_derived_tbl *actb } } } + norm = 0.0; for (i = 1; i < DCTSIZE2; i++) { norm += qtbl->quantval[i] * qtbl->quantval[i]; } norm /= 63.0; - - lambda_base = 1.0 / norm; + + if (mode == 1) { + lambda_base = 1.0; + lambda_tbl = lambda_table; + for (i = 0; i < DCTSIZE2; i++) + lambda_table[i] = 1.0 / (qtbl->quantval[i] * qtbl->quantval[i]); + } else + lambda_base = 1.0 / norm; for (bi = 0; bi < num_blocks; bi++) { diff --git a/jcparam.c b/jcparam.c index ef8826a0..5cb1281d 100644 --- a/jcparam.c +++ b/jcparam.c @@ -70,7 +70,7 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, * The spec says that the values given produce "good" quality, and * when divided by 2, "very good" quality. */ -static const unsigned int std_luminance_quant_tbl[][DCTSIZE2] = { +static const unsigned int std_luminance_quant_tbl[5][DCTSIZE2] = { { 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, @@ -90,9 +90,39 @@ static const unsigned int std_luminance_quant_tbl[][DCTSIZE2] = { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 + }, + { + 12, 17, 20, 21, 30, 34, 56, 63, + 18, 20, 20, 26, 28, 51, 61, 55, + 19, 20, 21, 26, 33, 58, 69, 55, + 26, 26, 26, 30, 46, 87, 86, 66, + 31, 33, 36, 40, 46, 96, 100, 73, + 40, 35, 46, 62, 81, 100, 111, 91, + 46, 66, 76, 86, 102, 121, 120, 101, + 68, 90, 90, 96, 113, 102, 105, 103 + }, + { + 11, 15, 17, 19, 29, 40, 55, 62, + 16, 16, 18, 24, 33, 59, 60, 56, + 16, 19, 22, 29, 43, 59, 69, 58, + 22, 22, 30, 43, 59, 89, 81, 65, + 27, 35, 47, 75, 69, 115, 105, 78, + 49, 45, 59, 70, 85, 106, 113, 93, + 52, 67, 78, 89, 103, 123, 120, 102, + 71, 92, 96, 98, 112, 100, 103, 99 + }, + { + 9, 10, 12, 14, 27, 32, 51, 62, + 11, 12, 14, 19, 27, 44, 59, 73, + 12, 14, 18, 25, 42, 59, 79, 78, + 17, 18, 25, 42, 61, 92, 87, 92, + 23, 28, 42, 75, 79, 112, 112, 99, + 40, 42, 59, 84, 88, 124, 132, 111, + 42, 64, 78, 95, 105, 126, 125, 99, + 70, 75, 100, 102, 116, 100, 107, 98 } }; -static const unsigned int std_chrominance_quant_tbl[][DCTSIZE2] = { +static const unsigned int std_chrominance_quant_tbl[5][DCTSIZE2] = { { 17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, @@ -112,6 +142,36 @@ static const unsigned int std_chrominance_quant_tbl[][DCTSIZE2] = { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 + }, + { + 8, 12, 15, 15, 86, 96, 96, 98, + 13, 13, 15, 26, 90, 96, 99, 98, + 12, 15, 18, 96, 99, 99, 99, 99, + 17, 16, 90, 96, 99, 99, 99, 99, + 96, 96, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99 + }, + { + 8, 14, 17, 21, 90, 98, 98, 99, + 14, 15, 17, 46, 92, 93, 90, 97, + 16, 21, 44, 94, 96, 96, 98, 98, + 27, 31, 84, 85, 96, 96, 98, 98, + 31, 92, 96, 94, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99 + }, + { + 9, 10, 17, 19, 62, 89, 91, 97, + 12, 13, 18, 29, 84, 91, 88, 98, + 14, 19, 29, 93, 95, 95, 98, 97, + 20, 26, 84, 88, 95, 95, 98, 94, + 26, 86, 91, 93, 97, 99, 98, 99, + 99, 100, 98, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 97, 97, 99, 99, 99, 99, 97, 99 } }; diff --git a/rdswitch.c b/rdswitch.c index f63d6ebe..02b5af80 100644 --- a/rdswitch.c +++ b/rdswitch.c @@ -279,7 +279,7 @@ bogus: * The spec says that the values given produce "good" quality, and * when divided by 2, "very good" quality. */ -static const unsigned int std_luminance_quant_tbl[][DCTSIZE2] = { +static const unsigned int std_luminance_quant_tbl[5][DCTSIZE2] = { { 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, @@ -299,9 +299,39 @@ static const unsigned int std_luminance_quant_tbl[][DCTSIZE2] = { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 + }, + { + 12, 17, 20, 21, 30, 34, 56, 63, + 18, 20, 20, 26, 28, 51, 61, 55, + 19, 20, 21, 26, 33, 58, 69, 55, + 26, 26, 26, 30, 46, 87, 86, 66, + 31, 33, 36, 40, 46, 96, 100, 73, + 40, 35, 46, 62, 81, 100, 111, 91, + 46, 66, 76, 86, 102, 121, 120, 101, + 68, 90, 90, 96, 113, 102, 105, 103 + }, + { + 11, 15, 17, 19, 29, 40, 55, 62, + 16, 16, 18, 24, 33, 59, 60, 56, + 16, 19, 22, 29, 43, 59, 69, 58, + 22, 22, 30, 43, 59, 89, 81, 65, + 27, 35, 47, 75, 69, 115, 105, 78, + 49, 45, 59, 70, 85, 106, 113, 93, + 52, 67, 78, 89, 103, 123, 120, 102, + 71, 92, 96, 98, 112, 100, 103, 99 + }, + { + 9, 10, 12, 14, 27, 32, 51, 62, + 11, 12, 14, 19, 27, 44, 59, 73, + 12, 14, 18, 25, 42, 59, 79, 78, + 17, 18, 25, 42, 61, 92, 87, 92, + 23, 28, 42, 75, 79, 112, 112, 99, + 40, 42, 59, 84, 88, 124, 132, 111, + 42, 64, 78, 95, 105, 126, 125, 99, + 70, 75, 100, 102, 116, 100, 107, 98 } }; -static const unsigned int std_chrominance_quant_tbl[][DCTSIZE2] = { +static const unsigned int std_chrominance_quant_tbl[5][DCTSIZE2] = { { 17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, @@ -321,6 +351,36 @@ static const unsigned int std_chrominance_quant_tbl[][DCTSIZE2] = { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 + }, + { + 8, 12, 15, 15, 86, 96, 96, 98, + 13, 13, 15, 26, 90, 96, 99, 98, + 12, 15, 18, 96, 99, 99, 99, 99, + 17, 16, 90, 96, 99, 99, 99, 99, + 96, 96, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99 + }, + { + 8, 14, 17, 21, 90, 98, 98, 99, + 14, 15, 17, 46, 92, 93, 90, 97, + 16, 21, 44, 94, 96, 96, 98, 98, + 27, 31, 84, 85, 96, 96, 98, 98, + 31, 92, 96, 94, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99 + }, + { + 9, 10, 17, 19, 62, 89, 91, 97, + 12, 13, 18, 29, 84, 91, 88, 98, + 14, 19, 29, 93, 95, 95, 98, 97, + 20, 26, 84, 88, 95, 95, 98, 94, + 26, 86, 91, 93, 97, 99, 98, 99, + 99, 100, 98, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, + 97, 97, 99, 99, 99, 99, 97, 99 } };