📄 ebcot_lite_encode_passes.c
字号:
/*****************************************************************************//* Copyright 1998, Hewlett-Packard Company *//* All rights reserved *//* File: "ebcot_lite_encode_passes.c" *//* Description: Entropy coding passes for EBCOT (lite) *//* Author: David Taubman *//* Affiliation: Hewlett-Packard and *//* The University of New South Wales, Australia *//* Version: VM5.0 *//* Last Revised: 10 August, 1999 *//*****************************************************************************//*****************************************************************************//* Modified to incorporate MQ-coder by Mitsubishi Electric Corp. *//* Copyright 1999, Mitsubishi Electric Corp. *//* All rights reserved for modified parts *//*****************************************************************************//*****************************************************************************//* Modified by David Taubman to improve implementation efficiency. Copyright *//* 1999 by Hewlett-Packard Company with all rights reserved for the modified *//* parts. *//*****************************************************************************//*****************************************************************************//* Modified to combine entropy coders *//* Copyright 1999 Science Applications International Corporation (SAIC). *//* Copyright 1999 University of Arizona, Arizona Board of Regents. *//* All Rights Reservedi for modified parts. *//*****************************************************************************//*****************************************************************************//* Modified by David Taubman to include masking-sensitive distortion *//* calculations for R-D optimization (`-Cvis' option). Material identified *//* by "David T Cvis mod" comments has been added by David Taubman; it is *//* copyrighted by the University of New South Wales (Copyright 1999) with *//* all rights reserved for the modified parts. *//*****************************************************************************/#include <local_services.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include <ifc.h>#include "ebcot_common.h"#include "ebcot_encoder.h"/* ========================================================================= *//* --------------------------- Internal Functions -------------------------- *//* ========================================================================= *//*****************************************************************************//* STATIC first_pass_func *//*****************************************************************************/static void /* David T Cvis mod */ first_pass_func(block_master_ptr master) /* This function must be applied once, at the start of each quantization layer (bit plane). It looks for all samples whose context word has the IS_REFINED flag turned off. These samples are brought up to date with the current bit plane, while all other samples simply have their IS_REFINED flag turned off in preparation for future passes. Note that bringing samples up to date with the current bit plane never involves magnitude refinement. */{ register std_short *cp; register ifc_int *dp; register int i; register std_short ctxt; register ifc_int mask; register dst_arith_state_ptr state; register ifc_int val, symbol; register std_int areg, creg; register dst_context_state_ptr csp; std_short ct; ifc_int lsb, shift, sign; std_byte *zc_lut; ifc_int mse_upshift, mse_downshift; distortion_cell_ptr cell; /* David T Cvis mod */ int cell_gap; /* David T Cvis mod */ int eighth_cols, stripe_gap, r, c; std_short *mse_lut, non_causal; dst_context_state_ptr csp_base; state = &(master->coder_state); if (!state->mqe.active) dst_arith_coder__activate(state); assert((master->bit_idx > 0) && ((master->interleaved_row_gap & 3) == 0)); shift = master->bit_idx; lsb = 1 << shift; mask = (ifc_int)(MAX_IFC_INT & ((-1)<<shift)); mse_lut = master->initial_mse_lut; mse_downshift = shift - (MSE_LUT_BITS-1); mse_upshift = (mse_downshift<0)?-mse_downshift:0; mse_downshift += mse_upshift; areg = state->mqe.areg; creg = state->mqe.creg; ct = state->mqe.ct; csp_base = state->contexts; zc_lut = master->zc_lut; non_causal = 1 - master->causal; eighth_cols = (master->width+7)>>3; stripe_gap = master->interleaved_row_gap; cell_gap = master->d_cell_row_gap; /* David T Cvis mod */ cp = master->interleaved_context_buffer; dp = master->interleaved_sample_buffer; ctxt = 0; /* Suppress compiler warnings. */ cell = master->d_cells; /* David T Cvis mod */ for (r=0; r < master->stripes; r++, dp+=stripe_gap-(eighth_cols<<5), cp+=stripe_gap-(eighth_cols<<5), cell += ((r&1)?0:cell_gap)-eighth_cols) /* David T Cvis mod */ for (c=eighth_cols; c > 0; c--, cell++) /* David T Cvis mod */ { for (i=8; i > 0; i--, dp+=4, cp+=4) { if ((((std_int *) cp)[0] | ((std_int *) cp)[1]) == 0) { /* Special processing to reduce average symbol count. */ symbol = 0; if (dp[0] & mask) { ctxt = 0; symbol = 1; } else if (dp[1] & mask) { ctxt = 1; symbol = 1; } else if (dp[2] & mask) { ctxt = 2; symbol = 1; } else if (dp[3] & mask) { ctxt = 3; symbol = 1; } csp = csp_base + AGG_OFFSET; dst_emit_symbol(areg,creg,ct,state,symbol,csp); if (!symbol) continue; else { /* Send the run-length, stored in `ctxt', and jump into the appropriate location in the regular coding procedure. */ csp = csp_base + UNI_OFFSET; symbol = ctxt & 2; dst_emit_symbol(areg,creg,ct,state,symbol,csp); symbol = ctxt & 1; dst_emit_symbol(areg,creg,ct,state,symbol,csp); switch (ctxt) { case 0: ctxt = cp[0]; val = dp[0]; goto new_sig0; case 1: ctxt = cp[1]; val = dp[1]; goto new_sig1; case 2: ctxt = cp[2]; val = dp[2]; goto new_sig2; case 3: ctxt = cp[3]; val = dp[3]; goto new_sig3; } } } ctxt = cp[0]; if (ctxt & IS_REFINED) cp[0] = ctxt & ~IS_REFINED; else if (!(ctxt & (SELF_SIG | OUT_OF_BOUNDS))) { val = dp[0]; symbol = (val & mask); csp = csp_base + (ZC_OFFSET + zc_lut[ctxt & ZC_MASK]); dst_emit_symbol(areg,creg,ct,state,symbol,csp); if (symbol) { /* New significant value; update contexts & code sign */new_sig0: sign = val & MIN_IFC_INT; /* Save sign bit. */ val &= MAX_IFC_INT; val >>= mse_downshift; val <<= mse_upshift; assert(val == (val & MSE_LUT_MASK)); cell->delta_mse += mse_lut[val]; /* David T Cvis mod */ symbol = ebcot_sc_lut[(ctxt>>SIGN_POS)&0x00FF]; csp = csp_base + SC_OFFSET + (symbol & 0x000F); symbol &= MIN_IFC_INT; symbol ^= sign; dst_emit_symbol(areg,creg,ct,state,symbol,csp); cp[0] = ctxt | SELF_SIG; cp[(-stripe_gap+3)-4] |= (non_causal << BR_POS); cp[(-stripe_gap+3)+4] |= (non_causal << BL_POS); cp[1-4] |= TR_SIG; cp[1+4] |= TL_SIG; if (sign) { /* Negative sample. */ cp[4] |= CL_SIG | H_NVE_SIG; cp[-4] |= CR_SIG | H_NVE_SIG; cp[(-stripe_gap+3)]|= (non_causal << BC_POS) | (non_causal << V_NVE_POS); cp[1] |= TC_SIG | V_NVE_SIG; } else { /* Positive sample. */ cp[4] |= CL_SIG | H_PVE_SIG; cp[-4] |= CR_SIG | H_PVE_SIG; cp[(-stripe_gap+3)]|= (non_causal << BC_POS) | (non_causal << V_PVE_POS); cp[1] |= TC_SIG | V_PVE_SIG; } } } ctxt = cp[1]; if (ctxt & IS_REFINED) cp[1] = ctxt & ~IS_REFINED; else if (!(ctxt & (SELF_SIG | OUT_OF_BOUNDS))) { val = dp[1]; symbol = (val & mask); csp = csp_base + (ZC_OFFSET + zc_lut[ctxt & ZC_MASK]); dst_emit_symbol(areg,creg,ct,state,symbol,csp); if (symbol) { /* New significant value; update contexts & code sign */new_sig1: sign = val & MIN_IFC_INT; /* Save sign bit. */ val &= MAX_IFC_INT; val >>= mse_downshift; val <<= mse_upshift; assert(val == (val & MSE_LUT_MASK)); cell->delta_mse += mse_lut[val]; /* David T Cvis mod */ symbol = ebcot_sc_lut[(ctxt>>SIGN_POS)&0x00FF]; csp = csp_base + SC_OFFSET + (symbol & 0x000F); symbol &= MIN_IFC_INT; symbol ^= sign; dst_emit_symbol(areg,creg,ct,state,symbol,csp); cp[1] = ctxt | SELF_SIG; cp[0-4] |= BR_SIG; cp[0+4] |= BL_SIG; cp[2-4] |= TR_SIG; cp[2+4] |= TL_SIG; if (sign) { /* Negative sample. */ cp[1+4] |= CL_SIG | H_NVE_SIG; cp[1-4] |= CR_SIG | H_NVE_SIG; cp[0] |= BC_SIG | V_NVE_SIG; cp[2] |= TC_SIG | V_NVE_SIG; } else { /* Positive sample. */ cp[1+4] |= CL_SIG | H_PVE_SIG; cp[1-4] |= CR_SIG | H_PVE_SIG; cp[0] |= BC_SIG | V_PVE_SIG; cp[2] |= TC_SIG | V_PVE_SIG; } } } ctxt = cp[2]; if (ctxt & IS_REFINED) cp[2] = ctxt & ~IS_REFINED; else if (!(ctxt & (SELF_SIG | OUT_OF_BOUNDS))) { val = dp[2]; symbol = (val & mask); csp = csp_base + (ZC_OFFSET + zc_lut[ctxt & ZC_MASK]); dst_emit_symbol(areg,creg,ct,state,symbol,csp); if (symbol) { /* New significant value; update contexts & code sign */new_sig2: sign = val & MIN_IFC_INT; /* Save sign bit. */ val &= MAX_IFC_INT; val >>= mse_downshift; val <<= mse_upshift; assert(val == (val & MSE_LUT_MASK)); cell->delta_mse += mse_lut[val]; /* David T Cvis mod */ symbol = ebcot_sc_lut[(ctxt>>SIGN_POS)&0x00FF]; csp = csp_base + SC_OFFSET + (symbol & 0x000F); symbol &= MIN_IFC_INT; symbol ^= sign; dst_emit_symbol(areg,creg,ct,state,symbol,csp); cp[2] = ctxt | SELF_SIG; cp[1-4] |= BR_SIG; cp[1+4] |= BL_SIG; cp[3-4] |= TR_SIG; cp[3+4] |= TL_SIG; if (sign) { /* Negative sample. */ cp[2+4] |= CL_SIG | H_NVE_SIG; cp[2-4] |= CR_SIG | H_NVE_SIG; cp[1] |= BC_SIG | V_NVE_SIG; cp[3] |= TC_SIG | V_NVE_SIG; } else { /* Positive sample. */ cp[2+4] |= CL_SIG | H_PVE_SIG; cp[2-4] |= CR_SIG | H_PVE_SIG; cp[1] |= BC_SIG | V_PVE_SIG;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -