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

📄 hplx_hor_analysis_by_convolution.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
      taps = self->branch_taps[b];

      /* LANL Even Length Begin */
      /* Apply offsets corrected for all cases */
      sp = in_buf + offset;
      for (n=(width+1-offset)>>1; n > 0; n--, sp+=2, dp++)
        {
          for (sum=0.0F, k=-neg; k <= pos; k++)
            sum += sp[k] * taps[k];
          *dp = sum;
        }
      /* LANL Even Length End */
    }

  /**** Start Point Symmetric SSWT ****/
  /* Data rearrangement is required for even length input data */
  if ((base->usePsExtension) && ((width % 2) == 0))
  {
    float* low  = branch_bufs[0];
    float* high = branch_bufs[1];

    assert(width >= 4);
    high[width / 2 - 1] = (low[width / 2 - 1] - 0.75F * in_buf[width - 1]
                           - 0.25F * low[width / 2 - 2]);
    low[width / 2 - 1]  = in_buf[width - 1];
  }
  /**** End Point Symmetric SSWT ****/

  /* LANL Even Length Begin */
  /* Apply (L,L) -> (L',H') postprocessing at right end of output when
     required */
  if (self->even_taps) {
    if (width%2 && first_sample_odd) /* Odd length, odd offset case */
      analysis_end_filter(&branch_bufs[0][(width-1)/2-1],
                          &branch_bufs[0][(width-1)/2-1],
                          &branch_bufs[1][(width-1)/2]);
    if (!(width%2) && !first_sample_odd) /* Even length, even offset case */
      analysis_end_filter(&branch_bufs[0][width/2-1],
                          &branch_bufs[0][width/2-1],
                          &branch_bufs[1][width/2-1]);
  }
  /* LANL Even Length End */

}


/* ========================================================================= */
/* ------------------ 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_hor_analysis_by_convolution_ref self =
    (hplx_hor_analysis_by_convolution_ref) base;
  frame_info frame;
  int kernel_type;
  int b;

  /* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
  int xnum, num_levels, factor, hor_offset, hor_subsampling;
 
  info->get_fixed_tile_info(info, base->component_idx,
                            0, &xnum, NULL, NULL,
                            &hor_subsampling, NULL,
                            &hor_offset, NULL, &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__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 (self->extend=0, b=0; b < base->horiz_limit; b++)
    {
      if (self->branch_neg_supports[b] > self->extend)
        self->extend = self->branch_neg_supports[b];
      if (self->branch_pos_supports[b] > self->extend)
        self->extend = 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);
    }
  info->get_level_info(info,base->component_idx,base->level_idx,
                       NULL,NULL,&frame,NULL);
  if (frame.hor_ssodwt)
    local_error("Single sample overlap mode cannot be used with convolution "
                "implementations of the Wavelet transform.");
  self->tile_width = dims->cols;
  self->first_idx = dims->left_col;
  self->in_buf = (float *)
    local_malloc(XFORM_HBUF_KEY,
                 sizeof(float)*(self->tile_width+2*self->extend));
  self->in_buf += self->extend;
  for (b=0; b < base->horiz_limit; b++)
    {
      canvas_dims branch_dims, branch_frame_dims;
      int left, right;

      branch_dims = *dims;
      if (base->horiz_limit > 1) {
        left = branch_dims.left_col;
        right = left + branch_dims.cols - 1;

        /* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
        if(base->otlpf_convention) {
          int twidth;
          twidth=right-left+1;
          twidth=(twidth+1-b)>>1;
          left = info->next_otlpf_sub_band(b, left, factor, xnum, hor_offset, hor_subsampling);
          right = left + twidth - 1;
        }
                  else {
          left = (left+1-b)>>1;
          right = (right-b)>>1;
        }
        /* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */

        branch_dims.left_col = left;
        branch_dims.cols = right+1-left;
      }
      branch_frame_dims = *frame_dims;
      if (base->horiz_limit > 1) {
        branch_frame_dims.cols >>= 1;
        branch_frame_dims.left_col = (branch_frame_dims.left_col+1-b)>>1;
      }
      /* LANL Even Length Begin */
      /* Modified offset computations in the convolution can overrun
         the previous buffer size by one sample. There may be a more
         elegant solution to this problem, but this one appears to
         be adequate. */
      self->branch_bufs[b] = (float *)
        local_malloc(XFORM_HBUF_KEY,sizeof(float)*(branch_dims.cols+1));
      /* LANL Even Length End */
      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_hor_analysis_by_convolution_ref self =
    (hplx_hor_analysis_by_convolution_ref) base;
  float *dp;
  int n, b, first_sample_odd, band_width;

  assert(base->use_floats); /* In the future, we might like to implement
                               fixed-point convolution. */
  assert(width == self->tile_width);
  if (width == 0)
    return;

  /* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
  if(!base->otlpf_convention)
    first_sample_odd = self->first_idx & 1;
  else
    first_sample_odd =0;
  /** always treat it as if it were even. **/
  /* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */

  first_sample_odd = self->first_idx & 1;
  if (base->horiz_limit == 2) {
    for (dp=self->in_buf, n=width; n > 0; n--)
      *(dp++) = (float)(*(line_buf++));
    perform_1d_analysis(self,self->in_buf,self->branch_bufs,
                        width,first_sample_odd);

    /* Push the results out to next stage. */

    for (b=0; b < base->horiz_limit; b++)
      {
        band_width = (width + 1 - (b ^ first_sample_odd)) >> 1;
        base->branches[b]->push_line_float(base->branches[b],
                                           self->branch_bufs[b],band_width);
      }
  }
  else {
    for (dp = self->branch_bufs[0], n=width; n > 0; n--)
      *(dp++) = (float) *(line_buf++);
    band_width = width;
    base->branches[0]->push_line_float(base->branches[0],
                                       self->branch_bufs[0], band_width);
  }
}

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

static void
  __push_line_float(hplx_analysis_stage_ref base, float *line_buf,
                    int width)
{
  hplx_hor_analysis_by_convolution_ref self =
    (hplx_hor_analysis_by_convolution_ref) base;
  float *dp;
  int n, b, band_width, first_sample_odd;

  assert(base->use_floats); /* In the future, we might like to implement
                               fixed-point convolution. */
  assert(width == self->tile_width);
  if (width == 0)
    return;

  /* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
  if(!base->otlpf_convention)
    first_sample_odd = self->first_idx & 1;
  else
    first_sample_odd =0;
  /** always treat it as if it were even. **/
  /* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */

  if (base->horiz_limit == 2) {
    for (dp=self->in_buf, n=width; n > 0; n--)
      *(dp++) = *(line_buf++);
    perform_1d_analysis(self,self->in_buf,self->branch_bufs,
                        width,first_sample_odd);

    /* Push the results out to next stage. */

    for (b=0; b < base->horiz_limit; b++)
      {
        band_width = (width + 1 - (b ^ first_sample_odd)) >> 1;
        base->branches[b]->push_line_float(base->branches[b],
                                           self->branch_bufs[b],band_width);
      }
  }
  else {
    for (dp = self->branch_bufs[0], n=width; n > 0; n--)
      *(dp++) = *(line_buf++);
    band_width = width;
    base->branches[0]->push_line_float(base->branches[0],
                                       self->branch_bufs[0], band_width);
  }
}

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

static void
  __terminate(hplx_analysis_stage_ref base)
{
  hplx_hor_analysis_by_convolution_ref self =
    (hplx_hor_analysis_by_convolution_ref) base;
  int b;

  if (self->in_buf != NULL)
    local_free(self->in_buf - self->extend);
  for (b=0; b < base->horiz_limit; b++)
    {
      if (self->branch_bufs[b] != NULL)
        local_free(self->branch_bufs[b]);
      base->branches[b]->terminate(base->branches[b]);
    }
  local_free(self);
}

/*****************************************************************************/
/* EXTERN            create_hplx_hor_analysis_by_convolution                 */
/*****************************************************************************/

hplx_analysis_stage_ref
  create_hplx_hor_analysis_by_convolution(void)
{
  hplx_hor_analysis_by_convolution_ref result;

  result = (hplx_hor_analysis_by_convolution_ref)
    local_malloc(XFORM_MEM_KEY,sizeof(hplx_hor_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 + -