⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hplx_vert_synthesis_by_convolution.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
  /* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */

  for (dp=line_buf, n=self->cols; n > 0; n--)
    *(dp++) = 0.0F; /* We will be accumulating the impact of the two subbands
                       into this buffer. */
  for (b=0; b < base->vert_limit; b++, kernel++)
    { /* Walk through the two subbands which contribute to the output. */
      window = self->branch_windows + b;
      neg = kernel->neg_support;
      pos = kernel->pos_support;
      support = neg + pos + 1;

      /* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
      if(!base->otlpf_convention) {
        /* LANL Even Length Begin */
        /* Correct row index computation for even length filters */
        if (self->even_taps) {
          min_row_idx = ((self->next_row_idx-self->first_row_idx)>>1) - neg;
          min_row_idx -= (1-b)>>1;
        }
        else {
          min_row_idx = (self->next_row_idx>>1) - neg;
          min_row_idx -= (self->first_row_idx+1-b)>>1;
        }
        /* LANL Even Length End */
      }
      else min_row_idx = ((self->next_row_idx-self->first_row_idx)>>1) - neg;
 
      /* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */

      sign_flips[b] = NULL;
      if (self->even_taps && b)
        sign_flips[b] = self->sign_flips_buffer;

      /* LANL Even Length Begin */
      /* Modify effective filter alignment to give desired filter centres */
      if ((oddevencase || evenevencase) && (self->next_row_idx%2))
        min_row_idx++;
       if (window->top_extension_special)
         window->rows++;
      /* LANL Even Length End */

      while ((source[b] =
              hplx_rolling_buffer__get_rows(window,min_row_idx,
                                            support,sign_flips[b],b,0,
                                            base->usePsExtension,
                                            self->ps_low_buf)) == NULL)
        { /* Need to advance the moving window. */
          dp = hplx_rolling_buffer__advance(window);

          /* LANL Even Length Begin */
          if (b && window->lookahead_final_seen &&
              (self->next_high_lookahead < self->high_lookahead_rows)) {
            /* Need to take the next highpass row from the lookahead buffer */
            for (k = 0; k < window->cols; k++)
              dp[k] = window->ps_buf[1][self->next_high_lookahead][k];
            self->next_high_lookahead++;
          } else
            if (!b && self->extra_right_low_ready) {
              /* Need to take the final lowpass row from self->ps_low_buf */
              self->extra_right_low_ready = 0;
              for (k = 0; k < window->cols; k++)
                dp[k] = self->ps_low_buf[k];
            } else
          /* LANL Even Length End */

          base->branches[b]->pull_line_float(base->branches[b],dp,
                                             self->cols);
        }

      /* LANL Even Length Begin */
      if ((evenevencase || oddoddcase) &&
          (window->next_row_idx == window->rows)) {
        /* One of the windows has reached the last incoming row
           in the odd/odd or even/even case */
        int delta = evenevencase?1:0;
        if (b && !window->lookahead_final_seen) {
          /* We have reached the final highpass row for the first time */
          window->lookahead_final_seen = 1;
          /* Store final highpass row for later use and return it to its
             "original" (prior to analysis postprocessing) state */
          for (k = 0; k < window->cols; k++) {
            self->ps_high_buf[k] = dp[k];
            dp[k] = 0.0;
          }
          window->rows--;
          window->next_row_idx--;
        }


        if (!b && !window->lookahead_final_seen) {
          /* We have reached the final lowpass row for the first time */
          hplx_rolling_buffer_ptr hwindow;

          hwindow = self->branch_windows + 1;
          window->lookahead_final_seen = 1;

          if (hwindow->lookahead_final_seen) {
            /* We have already seen the final highpass row. Undo
               (L,L) -> (L',H') postprocessing at bottom end of tile,
               taking the final highpass row from self->ps_high_buf */
            synthesis_end_filter(dp, self->ps_high_buf,
                                 dp, self->ps_low_buf, self->cols);
            self->extra_right_low_ready = 1;
            window->rows++;
          } else {
            /* We need to read the remaining highpass rows into
               a lookahead buffer */
            for (n=0; n <hwindow->rows-hwindow->next_row_idx+delta; n++) {
              base->branches[1]->pull_line_float(base->branches[1],
                                                 hwindow->ps_buf[1][n],
                                                 self->cols);
            }

            self->next_high_lookahead = 0;
            self->high_lookahead_rows = n;
            hwindow->lookahead_final_seen = 1;

            /* Undo (L,L) -> (L',H') postprocessing at bottom end of tile,
             taking the final highpass row from the end of the lookahead
             buffer */
            synthesis_end_filter(dp, hwindow->ps_buf[1][n-1],
                                 dp, self->ps_low_buf, self->cols);

            self->extra_right_low_ready = 1;
            window->rows++;
            hwindow->rows--;

            /* The symmetric extensions need to be recomputed when
               the window simultaneously contains rows past the top
               boundary of the tile and the row resulting from
               undoing the (L,L) -> (L',H') postprocessing */
            while ((source[b] =
                    hplx_rolling_buffer__get_rows(window,min_row_idx,
                                                  support,sign_flips[b],b,0,
                                                  base->usePsExtension,
                                                  self->ps_low_buf)) == NULL)
              {
                dp = hplx_rolling_buffer__advance(window);
                self->extra_right_low_ready = 0;
                for (k = 0; k < window->cols; k++)
                  dp[k] = self->ps_low_buf[k];
              }
          }
        }
      }

      /* Apply filter alignment correction for odd asymmetric extensions
         at the top of the tile */
      if (window->top_extension_special)
        window->rows--;
      /* LANL Even Length End */

    }
  kernel -= 2;

  /*
   * Perform the required data rearrangement for every column, only when doing
   * the row.
   */

  if (base->usePsExtension)
    {
      int reorderLow, reorderHigh;

      reorderLow  = -1;
      reorderHigh = -1;

      /* Remember the second to last row as soon as it appears */
      if (2 * window->rows ==
          (self->next_row_idx-self->first_row_idx) + 3 +
          2*kernel[0].pos_support)
        {
          int row = kernel[0].neg_support + kernel[0].pos_support;

          for (n=0; n<self->cols; n++)
            self->ps_prev_buf[n] = source[0][row][n];
        }

      /* When the last low row first appears, reorder */
      if (2 * window->rows ==
          (self->next_row_idx-self->first_row_idx) + 1 +
          2*kernel[0].pos_support)
        {
          int lastHigh = kernel[1].neg_support + kernel[1].pos_support;

          reorderLow = kernel[0].neg_support + kernel[0].pos_support;
          for (n=0; n<self->cols; n++)
            {
              self->ps_low_buf[n] = source[0][reorderLow][n];
              source[0][reorderLow][n] = (source[1][lastHigh][n]
                                          + 0.75F * source[0][reorderLow][n]
                                          + 0.25F * self->ps_prev_buf[n]);
            }
        }

      /* When the last high row first appears, reorder */
      if (2 * window->rows ==
          (self->next_row_idx-self->first_row_idx) + 1 +
          2*kernel[1].pos_support)
        {
          reorderHigh = kernel[1].neg_support + kernel[1].pos_support;
          for (n=0; n<self->cols; n++)
            {
              self->ps_high_buf[n] = source[1][reorderHigh][n];
              source[1][reorderHigh][n] = 0;
            }
        }
    }

  /*
   * Split this operation into two passes, so that point symmetric extension
   * related data rearrangement can occur.
   */

  for (b=0; b < base->vert_limit; b++, kernel++)
    {
      neg = kernel->neg_support;
      pos = kernel->pos_support;
      support = neg + pos + 1;
      taps = kernel->taps - neg;

      if (sign_flips[b] != NULL)
        {
          for (n=0; n < support; n++)
            self->taps_copy[n] = (sign_flips[b][n])?(-taps[n]):(taps[n]);
          taps = self->taps_copy;
        }
      for (dp=line_buf, n=0; n < self->cols; n++)
        {
          for (sum=0.0F, k=0; k < support; k++)
            sum += taps[k] * source[b][k][n];
          *(dp++) += sum;
        }
    }
}


/* ========================================================================= */
/* ------------------ Implementation of Interface Functions ---------------- */
/* ========================================================================= */

/*****************************************************************************/
/* STATIC                         __initialize                               */
/*****************************************************************************/

static void
  __initialize(hplx_synthesis_stage_ref base, reverse_info_ref info,
               canvas_dims_ptr dims, canvas_dims_ptr frame_dims)
{
  hplx_vert_synthesis_by_convolution_ref self =
    (hplx_vert_synthesis_by_convolution_ref) base;
  frame_info frame;
  hplx_rolling_buffer_ptr window;
  int branch_neg_supports[2], branch_pos_supports[2];
  float *branch_taps[2];
  int kernel_type;
  int b, n, bb, neg, pos;
  int first_row_odd;

  /* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
  int ynum, num_levels, factor, vert_offset, vert_subsampling;
 
  info->get_fixed_tile_info(info, base->component_idx,
                            0, NULL, &ynum, NULL,
                            NULL, &vert_subsampling,
                            NULL, &vert_offset, &num_levels, NULL,NULL);
 
  factor = 1 << (num_levels - base->component_idx);
  /* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */

  if (base->sso_ext)
    local_error("SSO-DWT style extensions are implemented only in lifting; "
                "you have opted for a convolution-style implementation!");
  kernel_type =
    info->get_kernel_type(info,base->direction,INFO__SYNTHESIS,
                          base->component_idx,base->level_idx,
                          branch_neg_supports,branch_pos_supports,
                          branch_neg_supports+1,branch_pos_supports+1);
  assert(kernel_type == INFO__CONVOLUTION);
  info->get_convolution_taps(info,base->direction,base->component_idx,
                             base->level_idx,branch_taps,branch_taps+1);
  self->even_taps = ((branch_neg_supports[0]+branch_pos_supports[0]) & 1);
  for (b=0; b < base->vert_limit; b++)
    {
      create_polyphase_kernel(self->branch_to_even+b,b,0,
                              branch_neg_supports[b],branch_pos_supports[b],
                              branch_taps[b]);
      create_polyphase_kernel(self->branch_to_odd+b,b,1,
                              branch_neg_supports[b],branch_pos_supports[b],
                              branch_taps[b]);
      window = self->branch_windows + b;
      neg = self->branch_to_even[b].neg_support;
      if (self->branch_to_odd[b].neg_support > neg)
        neg = self->branch_to_odd[b].neg_support;
      pos = self->branch_to_even[b].pos_support;
      if (self->branch_to_odd[b].pos_support > pos)
        pos = self->branch_to_odd[b].pos_support;
      window->cols = dims->cols;
      window->window_rows = neg+pos+1;
      window->buffer = (float **)
        local_malloc(XFORM_VBUF_KEY,sizeof(float *)*window->window_rows);
      for (n=0; n < window->window_rows; n++)
        window->buffer[n] = (float *)
          local_malloc(XFORM_VBUF_KEY,sizeof(float)*window->cols);
      window->receiving_buf = (float **)
        local_malloc(XFORM_VBUF_KEY,sizeof(float *)*window->window_rows);
      if (base->usePsExtension)
        for (bb=0; bb < base->vert_limit; bb++)
          {
            int y;

            window->ps_buf[bb] = (float **)
              local_malloc(XFORM_MEM_KEY,sizeof(float *)*window->window_rows);

            for (y = 0; y < window->window_rows; y++)
              window->ps_buf[bb][y] = (float *)
                local_malloc(XFORM_MEM_KEY,sizeof(float)*window->cols);
          }
    }
  if (self->even_taps)
    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -