📄 analysis.cpp
字号:
dp1->fval = sp[0].fval * scale; dp2->fval = sp[1].fval * scale; } } } else { // Working with 16-bit data kdu_sample16 *sp = line.get_buf16(); kdu_sample16 *dp1 = in->cosets[c].get_buf16(); kdu_sample16 *dp2 = in->cosets[1-c].get_buf16(); if (normalizing_downshift == 0) for (; k--; sp+=2, dp1++, dp2++) { *dp1 = sp[0]; *dp2 = sp[1]; } else { kdu_int16 offset = (kdu_int16)((1<<normalizing_downshift)>>1); for (; k--; sp+=2, dp1++, dp2++) { dp1->ival = (sp[0].ival+offset) >> normalizing_downshift; dp2->ival = (sp[1].ival+offset) >> normalizing_downshift; } } } // Perform the transformation if (unit_height) { // No transform performed in this special case. if (reversible && (in->lnum & 1)) { // Need to double the integer sample values. if (!use_shorts) { // Working with 32-bit data kdu_sample32 *dp; for (c=0; c < 2; c++) for (dp=in->cosets[c].get_buf32(), k=in->cosets[c].get_width(); k--; dp++) dp->ival <<= 1; } else { // Working with 16-bit data kdu_sample16 *dp; for (c=0; c < 2; c++) for (dp=in->cosets[c].get_buf16(), k=in->cosets[c].get_width(); k--; dp++) dp->ival <<= 1; } } horizontal_analysis(*in); } else { // Need to perform the vertical transform. int n; kd_line_cosets tmp; kd_lifting_step *step; if (in == &augend) { if (y_next <= y_max) return; // Still waiting for the row after augend new_state.deactivate(); // We have received the last line. } do { // Loop runs multiple times only to flush the pipe after last line if (in == NULL) { // There is no more input; must be flushing the pipe. augend.deactivate(); new_state.deactivate(); } in = NULL; // Just use it to flag the flushing condition if we loop // Run the vertical analysis network for (n=0; n < L_max; n++) { step = steps + n; if (augend.is_active()) perform_vertical_lifting_step(step); tmp = step->state; step->state = new_state; new_state = augend; augend = tmp; } // Push newly generated subband lines down the pipe. if (new_state.is_active()) horizontal_analysis(new_state); if (augend.is_active()) horizontal_analysis(augend); } while((y_next > y_max) && (output_rows_remaining > 0)); }}/*****************************************************************************//* kd_analysis::perform_vertical_lifting_step *//*****************************************************************************/void kd_analysis::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(); 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_analysis::horizontal_analysis *//*****************************************************************************/void kd_analysis::horizontal_analysis(kd_line_cosets &line){ assert(output_rows_remaining > 0); assert((low_width == line.cosets[0].get_width()) && (high_width == line.cosets[1].get_width())); output_rows_remaining--; if (unit_width) { // Special processing for this case. assert((low_width+high_width)==1); if (reversible && (x_min & 1)) { if (!use_shorts) line.cosets[1].get_buf32()->ival <<= 1; else line.cosets[1].get_buf16()->ival <<= 1; } if (low_width) hor_low[line.lnum & 1].push(line.cosets[0]); else hor_high[line.lnum & 1].push(line.cosets[1]); return; } // Perform lifting steps. for (int n=0; n < L_max; n++) { kd_lifting_step *step = steps + n; 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_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(); 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); } } } } // Push subband lines out. hor_low[line.lnum & 1].push(line.cosets[0]); hor_high[line.lnum & 1].push(line.cosets[1]);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -