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

📄 hplx_vert_analysis_by_convolution.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
        /* Remember the second to last low row */
        if ((self->branch_next_row_idx[0] == window->rows / 2 - 2) &&
            (!continued[0]))
          {
            for (n=0; n<self->cols; n++)
              self->ps_buf[n] = self->out_buf[0][n];
          }

        /* Rearrange the last low and high rows */
        else if ((self->branch_next_row_idx[0] == window->rows / 2 - 1) &&
                 (!continued[0]) && (!continued[1]))
          {
            for (n=0; n<self->cols; n++)
              {
                self->out_buf[1][n] = (self->out_buf[0][n] - 0.75F * bottom[n]
                                       - 0.25F * self->ps_buf[n]);
                self->out_buf[0][n] = bottom[n];
              }
          }
      }
    /* End PSE Stuff */

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

    for (b=0; b < base->vert_limit; b++)
      {
        if (continued[b])
          continue;

        /* LANL Even Length Begin */
        if ((oddoddcase || evenevencase) && !b &&
            (self->branch_next_row_idx[0] == self->branch_rows[0]-1)) {
          /* Postprocessing is required and the last or 2nd last lowpass row
             has just been generated */
          if (self->second_last_low_seen) {
            /* The 2nd last lowpass row has been stored. Apply the
               postprocessor and decrement the lowpass subband size
               and next index to the correct final values */
            analysis_end_filter(self->ps_buf, self->out_buf[0],
                                self->out_buf[0], self->ps_buf,
                                self->cols);
            self->final_high_ready = 1;
            self->branch_rows[b]--;
            self->branch_next_row_idx[b]--;
          } else {
            /* Store the 2nd last lowpass row and increment lowpass subband
               size and index of next row to be generated so that the last
               lowpass row will be generated on the next pass */
            for (n=0; n<self->cols; n++)
              self->ps_buf[n] = self->out_buf[0][n];
            self->second_last_low_seen = 1;
            self->branch_rows[b]++;
            self->branch_next_row_idx[b]++;
            continue;
          }
        }
        /* LANL Even Length End */

        /* LANL Even Length Begin */
        if ((oddoddcase || evenevencase) && b &&
            self->branch_next_row_idx[1] == self->branch_rows[1]-1) {
          /* Postprocessing is necessary and the last highpass row is required
             next. Ensure that this row has been constructed by the postprocessor,
             output the row, and increment the relevant row index to indicate
             that the final highpass row has been dealt with */
          assert(self->final_high_ready);
          base->branches[1]->push_line_float(base->branches[1],
                                             self->ps_buf,self->cols);
          self->branch_next_row_idx[1]++;
          continue;
        }
        /* LANL Even Length End */

        base->branches[b]->push_line_float(base->branches[b],
                                           self->out_buf[b],self->cols);
        self->branch_next_row_idx[b]++;
      }
  } while (!done);
}


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

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

static void
  __initialize(hplx_analysis_stage_ref base, forward_info_ref info,
               canvas_dims_ptr dims, canvas_dims_ptr frame_dims)
{
  hplx_vert_analysis_by_convolution_ref self =
    (hplx_vert_analysis_by_convolution_ref) base;
  frame_info frame;
  hplx_rolling_buffer_ptr window;
  int kernel_type, neg, pos;
  int b, n;

  /* 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 */

  /* LANL Even Length Begin */
  /* Flags required for postprocessing for even length filters */
  self->second_last_low_seen = 0;
  self->final_high_ready = 0;
  /* LANL Even Length End */

  if (base->sso_ext)
    local_error("SSO-DWT style extensions are implemented only in lifting; "
                "you have opted for a convolution-style implementation!");
  window = &(self->window);
  kernel_type =
    info->get_kernel_type(info,base->direction,INFO__ANALYSIS,
                          base->component_idx,base->level_idx,
                          self->branch_neg_supports,
                          self->branch_pos_supports,
                          self->branch_neg_supports+1,
                          self->branch_pos_supports+1);
  assert(kernel_type == INFO__CONVOLUTION);
  info->get_convolution_taps(info,base->direction,base->component_idx,
                             base->level_idx,self->branch_taps,
                             self->branch_taps+1);
  self->even_taps =
    ((self->branch_neg_supports[0]+self->branch_pos_supports[0]) & 1);
  for (neg=pos=0, b=0; b < base->vert_limit; b++)
    {
      if (self->branch_neg_supports[b] > neg)
        neg = self->branch_neg_supports[b];
      if (self->branch_pos_supports[b] > pos)
        pos = self->branch_pos_supports[b];
      check_kernel_symmetry(self->branch_neg_supports[b],
                            self->branch_pos_supports[b],
                            self->branch_taps[b],
                            self->even_taps,b);
    }

  window->cols = dims->cols;
  window->rows = dims->rows;
  window->window_rows = neg+pos+1;
  window->buffer = (float **)
    local_malloc(XFORM_MEM_KEY,sizeof(float *)*window->window_rows);
  for (n=0; n < window->window_rows; n++)
    {
      assert(window->buffer[n] == NULL);
      window->buffer[n] = (float *)
        local_malloc(XFORM_VBUF_KEY,sizeof(float)*window->cols);
    }
  window->receiving_buf = (float **)
    local_malloc(XFORM_MEM_KEY,sizeof(float *)*window->window_rows);
  if (base->usePsExtension)
    for (b=0; b < base->vert_limit; b++)
      if (window->ps_buf[b] == NULL)
        {
          int y;

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

          for (y = 0; y < window->window_rows; y++)
            window->ps_buf[b][y] = (float *)
              local_malloc(XFORM_MEM_KEY,sizeof(float)*window->cols);
        }
  window->bottom_extension_odd = window->top_extension_odd = !self->even_taps;
  window->bottom_extension_special = 0;
  info->get_level_info(info,base->component_idx,base->level_idx,
                       NULL,NULL,&frame,NULL);
  if (frame.vert_ssodwt)
    local_error("Single sample overlap mode cannot be used with convolution "
                "implementations of the Wavelet transform.");
  self->cols = dims->cols;
  self->first_row_idx = dims->top_row;
  self->out_buf[0] = (float *)
    local_malloc(XFORM_HBUF_KEY,sizeof(float)*self->cols);
  self->out_buf[1] = (float *)
    local_malloc(XFORM_HBUF_KEY,sizeof(float)*self->cols);
  self->ps_buf = (float *)
    local_malloc(XFORM_HBUF_KEY,sizeof(float)*self->cols);
  for (b=0; b < base->vert_limit; b++)
    {
      canvas_dims branch_dims, branch_frame_dims;
      int top, bottom;

      branch_dims = *dims;
      if (base->vert_limit > 1) {
        top = branch_dims.top_row;
        bottom = top + branch_dims.rows - 1;

        /* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
        if(base->otlpf_convention) {
          int   twidth;
          twidth=bottom-top+1;
          twidth=(twidth+1-b)>>1;
          top=info->next_otlpf_sub_band(b, top, factor, ynum, vert_offset, vert_subsampling);
          bottom=top+twidth-1;
        }
        else {
          top = (top+1-b)>>1;
          bottom = (bottom-b)>>1;
        }
        /* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */

        branch_dims.top_row = top;
        branch_dims.rows = bottom+1-top;
      }
      branch_frame_dims = *frame_dims;
      if (base->vert_limit > 1) {
        branch_frame_dims.rows >>= 1;
        branch_frame_dims.top_row = (branch_frame_dims.top_row+1-b)>>1;
      }
      self->branch_rows[b] = branch_dims.rows;
      base->branches[b]->initialize(base->branches[b],info,
                                    &branch_dims,&branch_frame_dims);
    }
}

/*****************************************************************************/
/*                               __push_line_fixed                           */
/*****************************************************************************/

static void
  __push_line_fixed(hplx_analysis_stage_ref base, ifc_int *line_buf,
                    int width)
{
  hplx_vert_analysis_by_convolution_ref self =
    (hplx_vert_analysis_by_convolution_ref) base;
  float *dp;
  int n;

  assert(base->use_floats); /* In the future, we might like to implement
                               convolution in fixed-point also. */
  assert(width == self->cols);
  if (width == 0)
    return;
  if (base->vert_limit == 2) {
    dp = hplx_rolling_buffer__advance(&(self->window));
    for (n=width; n > 0; n--)
      *(dp++) = (float)(*(line_buf++));
    complete_push_line(base);
  }
  else {
    for (dp = self->out_buf[0], n=width; n > 0; n--)
      *(dp++) = (float) *(line_buf++);
    base->branches[0]->push_line_float(base->branches[0], self->out_buf[0],self->cols);
    self->branch_next_row_idx[0]++;
  }
}

/*****************************************************************************/
/*                               __push_line_float                           */
/*****************************************************************************/

static void
  __push_line_float(hplx_analysis_stage_ref base, float *line_buf,
                    int width)
{
  hplx_vert_analysis_by_convolution_ref self =
    (hplx_vert_analysis_by_convolution_ref) base;
  float *dp;
  int n;

  assert(base->use_floats);
  assert(width == self->cols);
  if (width == 0)
    return;
  if (base->vert_limit == 2) {
    dp = hplx_rolling_buffer__advance(&(self->window));
    for (n=width; n > 0; n--)
      *(dp++) = *(line_buf++);
    complete_push_line(base);
  }
  else {
    for (dp = self->out_buf[0], n=width; n > 0; n--)
      *(dp++) = *(line_buf++);
    base->branches[0]->push_line_float(base->branches[0], self->out_buf[0],self->cols);
    self->branch_next_row_idx[0]++;
  }
}

/*****************************************************************************/
/* STATIC                         __terminate                                */
/*****************************************************************************/

static void
  __terminate(hplx_analysis_stage_ref base)
{
  hplx_vert_analysis_by_convolution_ref self =
    (hplx_vert_analysis_by_convolution_ref) base;
  int b, n;

  if (self->window.buffer != NULL)
    {
      for (n=0; n < self->window.window_rows; n++)
        if (self->window.buffer[n] != NULL)
          local_free(self->window.buffer[n]);
      local_free(self->window.buffer);
    }
  if (self->window.receiving_buf != NULL)
    local_free(self->window.receiving_buf);
  if (base->usePsExtension)
    for (b=0; b < base->vert_limit; b++)
      {
        for (n = 0; n < self->window.window_rows; n++)
          local_free(self->window.ps_buf[b][n]);
        local_free(self->window.ps_buf[b]);
      }
  if (self->out_buf[0] != NULL)
    local_free(self->out_buf[0]);
  if (self->out_buf[1] != NULL)
    local_free(self->out_buf[1]);
  if (self->ps_buf != NULL)
    local_free(self->ps_buf);
  for (b=0; b < base->vert_limit; b++)
    base->branches[b]->terminate(base->branches[b]);
  local_free(self);
}

/*****************************************************************************/
/* EXTERN            create_hplx_vert_analysis_by_convolution                */
/*****************************************************************************/

hplx_analysis_stage_ref
  create_hplx_vert_analysis_by_convolution(void)
{
  hplx_vert_analysis_by_convolution_ref result;

  result = (hplx_vert_analysis_by_convolution_ref)
    local_malloc(XFORM_MEM_KEY,sizeof(hplx_vert_analysis_by_convolution_obj));
  result->base.initialize = __initialize;
  result->base.push_line_fixed = __push_line_fixed;
  result->base.push_line_float = __push_line_float;
  result->base.terminate = __terminate;
  return((hplx_analysis_stage_ref) result);
}

⌨️ 快捷键说明

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