diff --git a/jccoefct.c b/jccoefct.c index 9c7162f9..0861d036 100644 --- a/jccoefct.c +++ b/jccoefct.c @@ -360,10 +360,9 @@ compress_trellis_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) JBLOCKROW thisblockrow, lastblockrow; JBLOCKARRAY buffer_dst; - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { c_derived_tbl actbl_data; c_derived_tbl *actbl = &actbl_data; - compptr = cinfo->cur_comp_info[ci]; jpeg_make_c_derived_tbl(cinfo, FALSE, compptr->ac_tbl_no, &actbl); @@ -398,7 +397,7 @@ compress_trellis_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) */ for (block_row = 0; block_row < block_rows; block_row++) { thisblockrow = buffer[block_row]; - quantize_trellis(cinfo, actbl, thisblockrow, buffer_dst[block_row], blocks_across, cinfo->quant_tbl_ptrs[compptr->quant_tbl_no]); + quantize_trellis(cinfo, actbl, thisblockrow, buffer_dst[block_row], blocks_across, cinfo->quant_tbl_ptrs[compptr->quant_tbl_no], cinfo->norm_src[compptr->quant_tbl_no], cinfo->norm_coef[compptr->quant_tbl_no]); if (ndummy > 0) { /* Create dummy blocks at the right edge of the image. */ @@ -435,6 +434,7 @@ compress_trellis_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) } } } + /* NB: compress_output will increment iMCU_row_num if successful. * A suspension return will result in redoing all the work above next time. */ diff --git a/jcdctmgr.c b/jcdctmgr.c index 629b0053..833b55fd 100644 --- a/jcdctmgr.c +++ b/jcdctmgr.c @@ -576,7 +576,7 @@ static const float jpeg_lambda_weights_csf_luma[64] = { GLOBAL(void) quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *actbl, JBLOCKROW coef_blocks, JBLOCKROW src, JDIMENSION num_blocks, - JQUANT_TBL * qtbl) + JQUANT_TBL * qtbl, double *norm_src, double *norm_coef) { int i, j, k; float accumulated_zero_dist[DCTSIZE2]; @@ -821,6 +821,15 @@ quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *actbl, JBLOCKROW coef_bloc free(block_run_start); free(requires_eob); } + + if (cinfo->trellis_q_opt) { + for (bi = 0; bi < num_blocks; bi++) { + for (i = 1; i < DCTSIZE2; i++) { + norm_src[i] += src[bi][i] * coef_blocks[bi][i]; + norm_coef[i] += 8 * coef_blocks[bi][i] * coef_blocks[bi][i]; + } + } + } } /* diff --git a/jchuff.h b/jchuff.h index bdbc4a1e..ac469dab 100644 --- a/jchuff.h +++ b/jchuff.h @@ -50,4 +50,4 @@ EXTERN(void) jpeg_gen_optimal_table EXTERN(void) quantize_trellis JPP((j_compress_ptr cinfo, c_derived_tbl *actbl, JBLOCKROW coef_blocks, JBLOCKROW src, JDIMENSION num_blocks, - JQUANT_TBL * qtbl)); + JQUANT_TBL * qtbl, double *norm_src, double *norm_coef)); diff --git a/jcmaster.c b/jcmaster.c index f448ec41..bf3bd7ec 100644 --- a/jcmaster.c +++ b/jcmaster.c @@ -550,6 +550,16 @@ prepare_for_pass (j_compress_ptr cinfo) master->pub.call_pass_startup = FALSE; break; case trellis_pass: + if (master->pass_number%(cinfo->num_components*(cinfo->use_scans_in_trellis?4:2)) == 1 && cinfo->trellis_q_opt) { + int i, j; + + for (i = 0; i < NUM_QUANT_TBLS; i++) { + for (j = 1; j < DCTSIZE2; j++) { + cinfo->norm_src[i][j] = 0.0; + cinfo->norm_coef[i][j] = 0.0; + } + } + } (*cinfo->entropy->start_pass) (cinfo, TRUE); (*cinfo->coef->start_pass) (cinfo, JBUF_REQUANT); master->pub.call_pass_startup = FALSE; @@ -838,6 +848,20 @@ finish_pass_master (j_compress_ptr cinfo) break; case trellis_pass: master->pass_type = (cinfo->optimize_scans || master->pass_number < master->pass_number_scan_opt_base-1) ? huff_opt_pass : output_pass; + + if ((master->pass_number+1)%(cinfo->num_components*(cinfo->use_scans_in_trellis?4:2)) == 0 && cinfo->trellis_q_opt) { + int i, j; + + for (i = 0; i < NUM_QUANT_TBLS; i++) { + for (j = 1; j < DCTSIZE2; j++) { + if (cinfo->norm_coef[i][j] != 0.0) { + int q = (int)(cinfo->norm_src[i][j] / cinfo->norm_coef[i][j] + 0.5); + if (q > 254) q = 254; + if (q < 1) q = 1; + } + } + } + } break; } diff --git a/jcparam.c b/jcparam.c index 883f9262..afe21026 100644 --- a/jcparam.c +++ b/jcparam.c @@ -433,6 +433,7 @@ jpeg_set_defaults (j_compress_ptr cinfo) cinfo->use_scans_in_trellis = FALSE; cinfo->trellis_freq_split = 8; cinfo->trellis_num_loops = 1; + cinfo->trellis_q_opt = FALSE; } diff --git a/jpeglib.h b/jpeglib.h index 23c3c846..5f6e2b0c 100644 --- a/jpeglib.h +++ b/jpeglib.h @@ -384,7 +384,11 @@ struct jpeg_compress_struct { boolean use_lambda_weight_tbl; /* TRUE=use lambda weighting table */ boolean use_scans_in_trellis; /* TRUE=use scans in trellis optimization */ boolean trellis_passes; /* TRUE=currently doing trellis-related passes */ + boolean trellis_q_opt; /* TRUE=optimize quant table in trellis loop */ + double norm_src[NUM_QUANT_TBLS][DCTSIZE2]; + double norm_coef[NUM_QUANT_TBLS][DCTSIZE2]; + int trellis_freq_split; /* splitting point for frequency in trellis quantization */ int trellis_num_loops; /* number of trellis loops */