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.
This commit is contained in:
Frank Bossen
2014-09-30 10:24:52 -04:00
parent 41ebea736d
commit 83d6a8e643
4 changed files with 144 additions and 15 deletions

18
cjpeg.c
View File

@@ -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);

View File

@@ -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,12 +741,19 @@ 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;
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++) {

View File

@@ -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
}
};

View File

@@ -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
}
};