📄 synthesis.cpp
字号:
else { while ((!out->is_active()) || (out->lnum != y_out_next)) { // Perform lifting steps until we produce the desired output row. kd_lifting_step *step = steps+(L_max-1); if (step->augend_parity == (y_in_next & 1)) horizontal_synthesis(augend); else augend.deactivate(); // does nothing if `augend' already inactive horizontal_synthesis(new_state); for (; step >= steps; step--) { if (augend.is_active()) perform_vertical_lifting_step(step); kd_line_cosets tmp = step->state; step->state = new_state; new_state = augend; augend = tmp; } } } y_out_next++; /* Finally, copy newly generated samples into `line', interleaving the even and odd sub-sequences and supplying any required upshift. */ c = x_out_min & 1; // Index of first coset to be interleaved. k = (line.get_width()+1)>>1; // May write one extra sample. if (!use_shorts) { // Working with 32-bit data kdu_sample32 *dp = line.get_buf32(); kdu_sample32 *sp1 = out->cosets[c].get_buf32() + ((x_out_min+1-c)>>1) - ((x_in_min+1-c)>>1); kdu_sample32 *sp2 = out->cosets[1-c].get_buf32() + ((x_out_min+c)>>1) - ((x_in_min+c)>>1); if (normalizing_upshift == 0) for (; k--; sp1++, sp2++, dp+=2) { dp[0] = *sp1; dp[1] = *sp2; } else { float scale = (float)(1<<normalizing_upshift); for (; k--; sp1++, sp2++, dp+=2) { dp[0].fval = sp1->fval*scale; dp[1].fval = sp2->fval*scale; } } } else { // Working with 16-bit data kdu_sample16 *dp = line.get_buf16(); kdu_sample16 *sp1 = out->cosets[c].get_buf16() + ((x_out_min+1-c)>>1) - ((x_in_min+1-c)>>1); kdu_sample16 *sp2 = out->cosets[1-c].get_buf16() + ((x_out_min+c)>>1) - ((x_in_min+c)>>1);#ifdef KDU_SIMD_OPTIMIZATIONS if (simd_exists) { if (normalizing_upshift == 0) simd_interleave(&(sp1->ival),&(sp2->ival),&(dp->ival),k); else simd_upshifted_interleave(&(sp1->ival),&(sp2->ival),&(dp->ival), k,normalizing_upshift); } else#endif // KDU_SIMD_OPTIMIZATIONS if (normalizing_upshift == 0) for (; k--; sp1++, sp2++, dp+=2) { dp[0] = *sp1; dp[1] = *sp2; } else for (; k--; sp1++, sp2++, dp+=2) { dp[0].ival = (*sp1).ival<<normalizing_upshift; dp[1].ival = (*sp2).ival<<normalizing_upshift; } }}/*****************************************************************************//* kd_synthesis::perform_vertical_lifting_step *//*****************************************************************************/void kd_synthesis::perform_vertical_lifting_step(kd_lifting_step *step){ assert(step->state.is_active() || new_state.is_active()); assert((!step->state) || (step->state.lnum==(augend.lnum-1))); assert((!new_state) || (new_state.lnum==(augend.lnum+1))); for (int c=0; c < 2; c++) // Walk through the two horizontal cosets if (!use_shorts) { // Processing 32-bit samples. kdu_sample32 *sp1 = step->state.cosets[c].get_buf32(); kdu_sample32 *sp2 = new_state.cosets[c].get_buf32(); if (sp1 == NULL) sp1 = sp2; if (sp2 == NULL) sp2 = sp1; kdu_sample32 *dp = augend.cosets[c].get_buf32(); int k = augend.cosets[c].get_width(); if (!reversible) { float lambda = step->lambda; for (; k--; sp1++, sp2++, dp++) dp->fval -= lambda*(sp1->fval+sp2->fval); } else { kdu_int32 downshift = step->downshift; kdu_int32 offset = (1<<downshift)>>1; kdu_int32 i_lambda = step->i_lambda; if (i_lambda == 1) for (; k--; sp1++, sp2++, dp++) dp->ival -= (offset+sp1->ival+sp2->ival)>>downshift; else if (i_lambda == -1) for (; k--; sp1++, sp2++, dp++) dp->ival -= (offset-sp1->ival-sp2->ival)>>downshift; else for (; k--; sp1++, sp2++, dp++) dp->ival -= (offset+i_lambda*(sp1->ival+sp2->ival))>>downshift; } } else { // Processing 16-bit samples. kdu_sample16 *sp1 = step->state.cosets[c].get_buf16(); kdu_sample16 *sp2 = new_state.cosets[c].get_buf16(); if (sp1 == NULL) sp1 = sp2; if (sp2 == NULL) sp2 = sp1; kdu_sample16 *dp = augend.cosets[c].get_buf16(); int k = augend.cosets[c].get_width();#ifdef KDU_SIMD_OPTIMIZATIONS if (simd_exists) { if (!reversible) simd_irrev_v_synth(&(sp1->ival),&(sp2->ival),&(dp->ival),k, step->fixpoint.i_lambda, step->fixpoint.remainder, step->fixpoint.pre_offset); else simd_rev_v_synth(&(sp1->ival),&(sp2->ival),&(dp->ival), k,step->downshift,step->i_lambda); } else#endif // KDU_SIMD_OPTIMIZATIONS if (!reversible) { kdu_int32 val, lambda = step->fixpoint.fix_lambda; for (; k--; sp1++, sp2++, dp++) { val = sp1->ival + sp2->ival; val *= lambda; dp->ival -= (kdu_int16)((val+(1<<15))>>16); } } else { kdu_int32 downshift = step->downshift; kdu_int32 offset = (1<<downshift)>>1; kdu_int32 val, i_lambda = step->i_lambda; if (i_lambda == 1) for (; k--; sp1++, sp2++, dp++) { val = offset+sp1->ival+sp2->ival; dp->ival -= (kdu_int16)(val>>downshift); } else if (i_lambda == -1) for (; k--; sp1++, sp2++, dp++) { val = offset-sp1->ival-sp2->ival; dp->ival -= (kdu_int16)(val>>downshift); } else for (; k--; sp1++, sp2++, dp++) { val = sp1->ival+sp2->ival; val = offset + i_lambda*val; dp->ival -= (kdu_int16)(val>>downshift); } } }}/*****************************************************************************//* kd_synthesis::horizontal_synthesis *//*****************************************************************************/void kd_synthesis::horizontal_synthesis(kd_line_cosets &line){ line.lnum = y_in_next; if (y_in_next > y_in_max) { // No more lines available. Signal this by returning with empty buffer. line.deactivate(); return; } if (!line) { line.activate(); line.lnum = y_in_next; } hor_low[line.lnum & 1].pull(line.cosets[0]); hor_high[line.lnum & 1].pull(line.cosets[1]); y_in_next++; if (unit_width) { // Special processing for this case. assert((low_width+high_width)==1); if (reversible && (x_in_min & 1)) { if (line.cosets[1].get_buf32() != NULL) line.cosets[1].get_buf32()->ival >>= 1; else line.cosets[1].get_buf16()->ival >>= 1; } return; } // Perform lifting steps. kd_lifting_step *step = steps + L_max-1; for (; step >= steps; step--) { int c = step->augend_parity; // Coset associated with augend. int k = line.cosets[c].get_width(); int k_src = line.cosets[1-c].get_width(); int extend_left = ((x_in_min & 1) == c)?1:0; if (!use_shorts) { // Processing 32-bit samples kdu_sample32 *sp=line.cosets[1-c].get_buf32(); sp[k_src] = sp[k_src-1]; // Achieves symmetric extension as required sp[-1] = sp[0]; sp -= extend_left; kdu_sample32 *dp=line.cosets[c].get_buf32(); if (!reversible) { float val, lambda = step->lambda, last_in = (sp++)->fval; while (k--) { val = last_in; last_in = (sp++)->fval; val += last_in; (dp++)->fval -= lambda*val; } } else { kdu_int32 downshift = step->downshift; kdu_int32 offset = (1<<downshift)>>1; kdu_int32 val, i_lambda = step->i_lambda, last_in = (sp++)->ival; if (i_lambda == 1) while (k--) { val = last_in; last_in = (sp++)->ival; val += last_in; (dp++)->ival -= (offset+val)>>downshift; } else if (i_lambda == -1) while (k--) { val = last_in; last_in = (sp++)->ival; val += last_in; (dp++)->ival -= (offset-val)>>downshift; } else while (k--) { val = last_in; last_in = (sp++)->ival; val += last_in; (dp++)->ival -= (offset+i_lambda*val)>>downshift; } } } else { // Processing 16-bit samples kdu_sample16 *sp=line.cosets[1-c].get_buf16(); sp[k_src] = sp[k_src-1]; // Achieves symmetric extension as required sp[-1] = sp[0]; sp -= extend_left; kdu_sample16 *dp=line.cosets[c].get_buf16();#ifdef KDU_SIMD_OPTIMIZATIONS if (simd_exists) { if (!reversible) simd_irrev_h_synth(&(sp->ival),&(dp->ival),k, step->fixpoint.i_lambda, step->fixpoint.remainder, step->fixpoint.pre_offset); else simd_rev_h_synth(&(sp->ival),&(dp->ival),k, step->downshift,step->i_lambda); } else#endif // KDU_SIMD_OPTIMIZATIONS if (!reversible) { kdu_int32 val, last_in = (sp++)->ival; kdu_int32 lambda = step->fixpoint.fix_lambda; while (k--) { val = last_in; last_in = (sp++)->ival; val += last_in; (dp++)->ival -= (kdu_int16)((val*lambda + (1<<15))>>16); } } else { kdu_int32 downshift = step->downshift; kdu_int32 offset = (1<<downshift)>>1; kdu_int32 val, i_lambda = step->i_lambda, last_in=(sp++)->ival; if (i_lambda == 1) while (k--) { val = last_in; last_in = (sp++)->ival; val += last_in; (dp++)->ival -= (kdu_int16)((offset+val)>>downshift); } else if (i_lambda == -1) while (k--) { val = last_in; last_in = (sp++)->ival; val += last_in; (dp++)->ival -= (kdu_int16)((offset-val)>>downshift); } else while (k--) { val = last_in; last_in = (sp++)->ival; val += last_in; (dp++)->ival -= (kdu_int16) ((offset+i_lambda*val)>>downshift); } } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -