📄 ebcot_encoder.c
字号:
{ dst_arith_state_ptr state; std_int areg, creg, symbol, n; std_short ct; dst_context_state_ptr csp; state = &(master->coder_state); assert(state->mqe.active); areg = state->mqe.areg; creg = state->mqe.creg; ct = state->mqe.ct; csp = state->contexts + UNI_OFFSET; for (n=3; n >= 0; n--) { symbol = n & 1; dst_emit_symbol(areg,creg,ct,state,symbol,csp); } state->mqe.areg = areg; state->mqe.creg = creg; state->mqe.ct = ct;}/*****************************************************************************//* STATIC encode_block *//*****************************************************************************/static void encode_block(ebcot_encoder_ref self, ebcot_component_info_ptr comp, ifc_int *sample_buffer, ebcot_band_info_ptr band, ebcot_block_info_ptr info) /* Encodes a single block of sample values. The actual dimensions of the block may be found in the `info' structure. The `sample_buffer' array contains the samples organized in lexicographical fashion. The function modifies the `info' structure to reflect the locations of the code words and the rate distortion information associated with the coding operation. It also updates state information in the `band' structure. */{ block_master_ptr master = &(comp->master); double delta_wmse, scale_wmse, wmse_factor, wmse_boost; int bitplane_idx, last_bitplane, pass_idx, extra_lsbs; int n, significant, msb_first, first_lossless_pass; int i, j, cells_wide, cells_high, cell_gap; /* David T Cvis mod */ distortion_cell_ptr cell; /* David T Cvis mod */ int last_bytes, last_terminated_bytes, next_terminated_bytes; dst_heap_unit_ptr heap; int heap_pos; clock_t cpu_time; next_terminated_bytes = 0; /* Suppress compiler warnings. */ cpu_time = 1; /* prevent warnings from compiler. */ if (self->cpu_time >= 0) cpu_time = clock(); /* Check to see if this is the first block being coded for the subband. */ if (info->passes == NULL) allocate_pass_info(band); /* Check ROI information and determine the actual number of extra LSB's. */ extra_lsbs = band->extra_lsbs; wmse_boost = 1.0; if (band->roi != NULL) { int boost_delta, min_boost; if (master->roi_mask == NULL) master->roi_mask = (std_byte **) local_malloc(EBCOT_MEM_KEY,sizeof(std_byte *)*master->max_height); boost_delta = band->roi->check_roi(band->roi,band->component_idx,band->level_idx, band->band_idx,info->rows,info->cols, info->top_row,info->left_col, &min_boost,master->roi_mask); wmse_boost = (double)(1<<min_boost); wmse_boost *= wmse_boost; assert((boost_delta >= 0) && (boost_delta <= band->max_roi_boost)); extra_lsbs -= boost_delta; /* Need to code more LSB's to accommodate the downshifted sample values. */ if (boost_delta) apply_roi_boost_mask(sample_buffer,info->rows,info->cols, master->sample_row_gap,boost_delta, master->roi_mask,band->roi_implicit); } while (extra_lsbs < 1) { /* Can't code all LSB's from least significant region. */ extra_lsbs++; wmse_boost *= 4.0; } /* Determine the number of passes to encode. */ { int max_planes; max_planes = IMPLEMENTATION_PRECISION - 1 - extra_lsbs; if (max_planes > (IMPLEMENTATION_PRECISION-2)) max_planes = IMPLEMENTATION_PRECISION-2; if (max_planes > (IMPLEMENTATION_PRECISION-2)) max_planes = IMPLEMENTATION_PRECISION-2; info->max_passes = 1 + PASSES_PER_BITPLANE*(max_planes-1); first_lossless_pass = -1; if (band->lossless) { first_lossless_pass = info->max_passes - PASSES_PER_BITPLANE; if (first_lossless_pass < 0) first_lossless_pass = 0; } } /* Set up per-block fields. */ master->zc_lut = band->zc_lut; master->bit_idx = IMPLEMENTATION_PRECISION-2; master->initial_mse_lut = ebcot_initial_mse_lut; master->refinement_mse_lut = ebcot_refinement_mse_lut; master->height = info->rows; master->width = info->cols; master->stripes = (master->height+3)>>2; assert((master->height <= master->max_height) && (master->width <= master->max_width) && (master->stripes <= master->max_stripes)); /* Prepare buffers. */ master->block_mag = interleave_sample_buffer(master,sample_buffer); reset_block_contexts(master); /* Begin David T Cvis mod */ cells_wide = (master->width+7)>>3; cells_high = (master->height+7)>>3; cell_gap = master->d_cell_row_gap - cells_wide; if (master->exploit_visual_masking) { ifc_int *tmp_buf; tmp_buf = sample_buffer; /* Reuse the `sample_buffer' storage since we have now safely copied its contents to the interleaved sample buffer for coding. */ if (band->band_idx == LL_BAND) { /* Compute masking strength based upon high-pass filtered version of signal. */ tmp_buf = comp->sample_buffer_heap_mgr->get_buffer( comp->sample_buffer_heap_mgr); compute_ll_band_local_activity(sample_buffer,tmp_buf,master->height, master->width,master->sample_row_gap); } compute_visibility_factors(master,tmp_buf,band->nominal_range, band->fully_masked_sensitivity_reduction, master->max_masked_sensitivity_reduction); if (band->band_idx == LL_BAND) comp->sample_buffer_heap_mgr->return_buffer( comp->sample_buffer_heap_mgr,tmp_buf); } else for (cell=master->d_cells, j=cells_high; j--; cell+=cell_gap) for (i=cells_wide; i--; cell++) cell->visibility_factor = 1.0F; /* End David T Cvis mod */ /* Prepare for arithmetic code word generation. */ if (band->heap_tail == NULL) { band->next_heap_pos = 0; band->heap_head = band->heap_tail = self->code_heap_mgr->get_unit(self->code_heap_mgr); band->heap_tail->next = NULL; } heap = band->heap_tail; heap_pos = band->next_heap_pos; dst_arith_coder__initialize(&(master->coder_state),EBCOT_TOTAL_CONTEXTS, master->contexts,heap,heap_pos, self->code_heap_mgr, master->error_resilient_termination); dst_arith_coder__model_init(&(master->coder_state),initial_mq_contexts);#ifdef DST_LOG_SYMBOLS master->coder_state.symbol_log = start_symbol_log(band,info);#endif /* DST_LOG_SYMBOLS */ /* Perform the coding passes. */ wmse_factor = (double)(1<<extra_lsbs); scale_wmse = band->step_wmse / (wmse_factor*wmse_factor); scale_wmse *= (1.0 / 64.0); /* Avoid overflow for at least 4 highest frequency resolution levels. */ wmse_factor = (double)(1<<master->bit_idx); scale_wmse *= wmse_factor * wmse_factor; scale_wmse *= 1.0 / ((double)(1<<13)); scale_wmse *= wmse_boost; last_bitplane = master->bit_idx - extra_lsbs; info->insignificant_msbs = 0; master->first_bit_idx = -1; for (delta_wmse=0.0, pass_idx=0, bitplane_idx=0, significant=0; bitplane_idx <= last_bitplane; bitplane_idx++, master->bit_idx--, scale_wmse*=0.25) { assert(master->bit_idx > 0); if (!significant) { significant = (master->block_mag >> master->bit_idx) & 1; if (significant) { /* Significant for the first time. */ master->first_bit_idx = master->bit_idx; mark_termination_points(info->passes,info->insignificant_msbs, info->max_passes, master->terminate_each_pass, master->full_effort_msbs); } } if (!significant) info->insignificant_msbs++; for (n=0; n < PASSES_PER_BITPLANE; n++, pass_idx++) { block_coding_pass_func pass_function; if (pass_idx == info->max_passes) { bitplane_idx = last_bitplane; break; } if (pass_idx == first_lossless_pass) { /* Switch to MSE LUT's which correctly estimate distortion reduction when processing the LSB of a lossless sample value representation. */ master->initial_mse_lut = ebcot_lossless_initial_mse_lut; master->refinement_mse_lut = ebcot_lossless_refinement_mse_lut; } if (significant) { pass_function = band->pass_funcs[n]; if (master->reset) dst_arith_coder__model_init(&(master->coder_state), initial_mq_contexts); /* Begin David T Cvis mod */ for (cell=master->d_cells, j=cells_high; j--; cell+=cell_gap) for (i=cells_wide; i--; cell++) cell->delta_mse = 0; pass_function(master); for (cell=master->d_cells, j=cells_high; j--; cell+=cell_gap) for (i=cells_wide; i--; cell++) { double wmse_inc; wmse_inc = (double)(cell->delta_mse); wmse_inc *= scale_wmse; if (n == 0) wmse_inc *= 4.0; wmse_inc *= cell->visibility_factor; delta_wmse += wmse_inc; } /* End David T Cvis mod */ if (master->segmark && (n==0)) insert_segment_marker(master); master->saved_states[pass_idx] = master->coder_state; if (info->passes[pass_idx].terminated) info->passes[pass_idx].cumulative_bytes = dst_arith_coder__deactivate(&(master->coder_state), master->easy_termination); } else info->passes[pass_idx].cumulative_bytes = 0; master->cumulative_wmse[pass_idx] = delta_wmse; } } dst_arith_coder__flush(&(master->coder_state));#ifdef DST_LOG_SYMBOLS fclose(master->coder_state.symbol_log); master->coder_state.symbol_log = NULL;#endif /* DST_LOG_SYMBOLS */ /* Update state information in `info' and `band' to reflect operations. */ info->first_unit = heap; info->first_pos = heap_pos; last_bytes = 0; last_terminated_bytes = 0; for (n=info->insignificant_msbs*PASSES_PER_BITPLANE; n < pass_idx; n++) if (info->passes[n].terminated) break; if (n < pass_idx) next_terminated_bytes = info->passes[n].cumulative_bytes; for (n=info->insignificant_msbs*PASSES_PER_BITPLANE; n < pass_idx; n++) { if (!info->passes[n].terminated) { info->passes[n].cumulative_bytes = dst_arith_coder__get_minimum_bytes(master->saved_states+n, heap,heap_pos, last_terminated_bytes, next_terminated_bytes); } else { int m; assert(next_terminated_bytes == (int) info->passes[n].cumulative_bytes); last_terminated_bytes = next_terminated_bytes; for (m=n+1; m < pass_idx; m++) if (info->passes[m].terminated) { next_terminated_bytes = info->passes[m].cumulative_bytes; break; } } assert(last_bytes <= info->passes[n].cumulative_bytes); last_bytes = info->passes[n].cumulative_bytes; } assert(last_bytes <= (master->coder_state.saved_words<<2)); compute_rd_slopes(pass_idx,master->cumulative_wmse, info->passes,self->rd_slope_rates); /* SAIC TCQ begin */ /* Force last three bit-planes to be included at same time */ if (master->include_all_passes && (pass_idx > 0) && significant) { info->passes[pass_idx-2].rd_slope = -1; info->passes[pass_idx-3].rd_slope = -1; } /* SAIC TCQ begin */ /* SAIC TCQ begin mods */ /* Force inclusion of all bitplane passes */ if ((band->lossless || master->include_all_passes) && (pass_idx > 0) && (info->passes[pass_idx-1].rd_slope <= 0) && significant) { /* Must include all significant coding passes in lossless mode to comply with the JPEG2000 standard, even if the last pass is not required to achieve 0 distortion under the assumption that the dequantizer will round to the midpoint of the quantization thresholds. This requirement is introduced to avoid dependence on the dequantizer's rounding strategy. */ info->passes[pass_idx-1].rd_slope = 1; /* Least desirable legal slope. */ /* Now make sure we have not violated the requirement that slopes for points on the convex hull be strictly decreasing and have strictly increasing lengths. */ for (n=pass_idx-2; n >= 0; n--) if (info->passes[n].rd_slope > 0) { /* Otherwise not on the convex hull. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -