📄 block_encoder.cpp
字号:
cword = *cp; if (!(cword & (CLEANUP_MEMBER_MASK<<0))) { // Process first row of stripe column (row 0) state_ref = states+KAPPA_SIG_BASE+sig_lut[cword & NBRHD_MASK]; val = sp[0]<<shift; sym = val & KDU_INT32_MIN; _mq_enc_(coder,sym,*state_ref); if (val >= 0) // New magnitude bit was 0, so still insignificant goto row_1;row_0_significant: // Compute distortion change val = (val>>(31-DISTORTION_LSBS)) & (SIGNIFICANCE_DISTORTIONS-1); distortion_change += distortion_lut[val]; // Encode sign bit sym = cword & ((CHI_BIT>>3) | (SIGMA_CC_BIT>>3) | (CHI_BIT<<3) | (SIGMA_CC_BIT<<3)); sym >>= 1; // Shift down so that top sigma bit has address 0 sym |= (cp[-1] & ((CHI_BIT<<0) | (SIGMA_CC_BIT<<0))) >> (1+1); sym |= (cp[ 1] & ((CHI_BIT<<0) | (SIGMA_CC_BIT<<0))) >> (1-1); sym |= (sym >> (CHI_POS-1-SIGMA_CC_POS)); // Interleave chi & sigma val = sign_lut[sym & 0x000000FF]; state_ref = states + KAPPA_SIGN_BASE + (val>>1); sym = val << 31; // Get sign flipping to `sym' val = sp[0] & KDU_INT32_MIN; // Get the sign bit sym ^= val; // Moves flipped sign bit into `sym' _mq_enc_(coder,sym,*state_ref); // Broadcast neighbourhood context changes; sign bit is in `val' cp[-1] |= (SIGMA_CR_BIT<<0); cp[1] |= (SIGMA_CL_BIT<<0); if (val < 0) { cword |= (SIGMA_CC_BIT<<0) | (CHI_BIT<<0); if (!causal) { cp[-context_row_gap-1] |= (SIGMA_BR_BIT<<9); cp[-context_row_gap ] |= (SIGMA_BC_BIT<<9) | NEXT_CHI_BIT; cp[-context_row_gap+1] |= (SIGMA_BL_BIT<<9); } } else { cword |= (SIGMA_CC_BIT<<0); if (!causal) { cp[-context_row_gap-1] |= (SIGMA_BR_BIT<<9); cp[-context_row_gap ] |= (SIGMA_BC_BIT<<9); cp[-context_row_gap+1] |= (SIGMA_BL_BIT<<9); } } }row_1: if (!(cword & (CLEANUP_MEMBER_MASK<<3))) { // Process second row of stripe column (row 1) state_ref = states+KAPPA_SIG_BASE+sig_lut[(cword>>3) & NBRHD_MASK]; val = sp[width]<<shift; sym = val & KDU_INT32_MIN; _mq_enc_(coder,sym,*state_ref); if (val >= 0) // New magnitude bit was 0, so still insignificant goto row_2;row_1_significant: // Compute distortion change val = (val>>(31-DISTORTION_LSBS)) & (SIGNIFICANCE_DISTORTIONS-1); distortion_change += distortion_lut[val]; // Encode sign bit sym = cword & ((CHI_BIT<<0) | (SIGMA_CC_BIT<<0) | (CHI_BIT<<6) | (SIGMA_CC_BIT<<6)); sym >>= 4; // Shift down so that top sigma bit has address 0 sym |= (cp[-1] & ((CHI_BIT<<3) | (SIGMA_CC_BIT<<3))) >> (4+1); sym |= (cp[ 1] & ((CHI_BIT<<3) | (SIGMA_CC_BIT<<3))) >> (4-1); sym |= (sym >> (CHI_POS-1-SIGMA_CC_POS)); // Interleave chi & sigma val = sign_lut[sym & 0x000000FF]; state_ref = states + KAPPA_SIGN_BASE + (val>>1); sym = val << 31; // Get sign flipping to `sym' val = sp[width] & KDU_INT32_MIN; // Get the sign bit sym ^= val; // Moves flipped sign bit into `sym' _mq_enc_(coder,sym,*state_ref); // Broadcast neighbourhood context changes; sign bit is in `val' cp[-1] |= (SIGMA_CR_BIT<<3); cp[1] |= (SIGMA_CL_BIT<<3); cword |= (SIGMA_CC_BIT<<3); val = (kdu_int32)(((kdu_uint32) val)>>(31-(CHI_POS+3))); // SRL cword |= val; }row_2: if (!(cword & (CLEANUP_MEMBER_MASK<<6))) { // Process third row of stripe column (row 2) state_ref = states+KAPPA_SIG_BASE+sig_lut[(cword>>6) & NBRHD_MASK]; val = sp[width_by2]<<shift; sym = val & KDU_INT32_MIN; _mq_enc_(coder,sym,*state_ref); if (val >= 0) // New magnitude bit was 0, so still insignificant goto row_3;row_2_significant: // Compute distortion change val = (val>>(31-DISTORTION_LSBS)) & (SIGNIFICANCE_DISTORTIONS-1); distortion_change += distortion_lut[val]; // Encode sign bit sym = cword & ((CHI_BIT<<3) | (SIGMA_CC_BIT<<3) | (CHI_BIT<<9) | (SIGMA_CC_BIT<<9)); sym >>= 7; // Shift down so that top sigma bit has address 0 sym |= (cp[-1] & ((CHI_BIT<<6) | (SIGMA_CC_BIT<<6))) >> (7+1); sym |= (cp[ 1] & ((CHI_BIT<<6) | (SIGMA_CC_BIT<<6))) >> (7-1); sym |= (sym >> (CHI_POS-1-SIGMA_CC_POS)); // Interleave chi & sigma val = sign_lut[sym & 0x000000FF]; state_ref = states + KAPPA_SIGN_BASE + (val>>1); sym = val << 31; // Get sign flipping to `sym' val = sp[width_by2] & KDU_INT32_MIN; // Get the sign bit sym ^= val; // Moves flipped sign bit into `sym' _mq_enc_(coder,sym,*state_ref); // Broadcast neighbourhood context changes; sign bit is in `val' cp[-1] |= (SIGMA_CR_BIT<<6); cp[1] |= (SIGMA_CL_BIT<<6); cword |= (SIGMA_CC_BIT<<6); val = (kdu_int32)(((kdu_uint32) val)>>(31-(CHI_POS+6))); // SRL cword |= val; }row_3: if (!(cword & (CLEANUP_MEMBER_MASK<<9))) { // Process fourth row of stripe column (row 3) state_ref = states+KAPPA_SIG_BASE+sig_lut[(cword>>9) & NBRHD_MASK]; val = sp[width_by3]<<shift; sym = val & KDU_INT32_MIN; _mq_enc_(coder,sym,*state_ref); if (val >= 0) // New magnitude bit was 0, so still insignificant goto done;row_3_significant: // Compute distortion change val = (val>>(31-DISTORTION_LSBS)) & (SIGNIFICANCE_DISTORTIONS-1); distortion_change += distortion_lut[val]; // Decode sign bit sym = cword & ((CHI_BIT<<6) | (SIGMA_CC_BIT<<6) | 0 | (SIGMA_CC_BIT<<12)); sym >>= 10; // Shift down so that top sigma bit has address 0 if (cword < 0) // Use the fact that NEXT_CHI_BIT = 31 sym |= CHI_BIT<<(12-10); sym |= (cp[-1] & ((CHI_BIT<<9) | (SIGMA_CC_BIT<<9))) >> (10+1); sym |= (cp[ 1] & ((CHI_BIT<<9) | (SIGMA_CC_BIT<<9))) >> (10-1); sym |= (sym >> (CHI_POS-1-SIGMA_CC_POS)); // Interleave chi & sigma val = sign_lut[sym & 0x000000FF]; state_ref = states + KAPPA_SIGN_BASE + (val>>1); sym = val << 31; // Get sign flipping to `sym' val = sp[width_by3] & KDU_INT32_MIN; // Get the sign bit sym ^= val; // Moves flipped sign bit into `sym' _mq_enc_(coder,sym,*state_ref); // Broadcast neighbourhood context changes; sign bit is in `val' cp[context_row_gap-1] |= SIGMA_TR_BIT; cp[context_row_gap+1] |= SIGMA_TL_BIT; cp[-1] |= (SIGMA_CR_BIT<<9); cp[1] |= (SIGMA_CL_BIT<<9); if (val < 0) { cp[context_row_gap ] |= SIGMA_TC_BIT | PREV_CHI_BIT; cword |= (SIGMA_CC_BIT<<9) | (CHI_BIT<<9); } else { cp[context_row_gap ] |= SIGMA_TC_BIT; cword |= (SIGMA_CC_BIT<<9); } }done: cword |= (cword << (MU_POS - SIGMA_CC_POS)) & ((MU_BIT<<0)|(MU_BIT<<3)|(MU_BIT<<6)|(MU_BIT<<9)); cword &= ~((PI_BIT<<0)|(PI_BIT<<3)|(PI_BIT<<6)|(PI_BIT<<9)); *cp = cword; } _mq_check_in_(coder); return distortion_change;}/* ========================================================================= *//* Distortion-Length Slope Calculating Functions *//* ========================================================================= *//*****************************************************************************//* INLINE slope_to_log *//*****************************************************************************/static inline kdu_uint16 slope_to_log(double lambda){ double max_slope = pow(2.0,32.0); // Maximum slope we can reprsent double log_scale = 256.0 / log(2.0); // Convert log values to 8.8 fixed point double log_slope = lambda / max_slope; log_slope = (log_slope > 1.0)?1.0:log_slope; log_slope = (log(log_slope) * log_scale) + (double)(1<<16); if (log_slope > (double) 0xFFFF) return 0xFFFF; else if (log_slope < 2.0) return 2; else return (kdu_uint16) log_slope;}/*****************************************************************************//* INLINE slope_from_log *//*****************************************************************************/static inline double slope_from_log(kdu_uint16 slope){ double max_slope = pow(2.0,32.0); double log_scale = log(2.0) / 256.0; double log_slope = ((double) slope) - ((double)(1<<16)); log_slope *= log_scale; return exp(log_slope) * max_slope;}/*****************************************************************************//* STATIC find_convex_hull *//*****************************************************************************/static void find_convex_hull(int pass_lengths[], double pass_wmse_changes[], kdu_uint16 pass_slopes[], int num_passes){ int z; for (z=0; z < num_passes; z++) { /* Find the value, lambda(z), defined in equation (8.4) of the book by Taubman and Marcellin. Every coding pass which contributes to the convex hull set has this value for its distortion-length slope; however, not all coding passes which have a positive lambda(z) value actually contribute to the convex hull. The points which do not contribute are weeded out next. */ double lambda_z = -1.0; // Marks initial condition. double delta_L = 0.0, delta_D = 0.0; int t; for (t=z; t >= 0; t--) { delta_L += (double) pass_lengths[t]; delta_D += pass_wmse_changes[t]; if (delta_D <= 0.0) break; else if ((delta_L > 0.0) && ((lambda_z < 0.0) || ((delta_L*lambda_z) > delta_D))) lambda_z = delta_D / delta_L; } if (lambda_z <= 0.0) pass_slopes[z] = 0; else pass_slopes[z] = slope_to_log(lambda_z); } /* Now weed out the non-contributing passes. */ for (z=0; z < num_passes; z++) { for (int t=z+1; t < num_passes; t++) if (pass_slopes[t] >= pass_slopes[z]) { pass_slopes[z] = 0; break; } }}/* ========================================================================= *//* kdu_block_encoder *//* ========================================================================= *//*****************************************************************************//* kdu_block_encoder::kdu_block_encoder *//*****************************************************************************/kdu_block_encoder::kdu_block_encoder(){ state = new kd_block_encoder;}/* ========================================================================= *//* kd_block_encoder *//* ========================================================================= *//*****************************************************************************//* kd_block_encoder::encode *//*****************************************************************************/void kd_block_encoder::encode(kdu_block *block, bool reversible, double msb_wmse,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -