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

📄 hplx_hor_analysis_by_lifting.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
  __initialize(hplx_analysis_stage_ref base, forward_info_ref info,
               canvas_dims_ptr dims, canvas_dims_ptr frame_dims)
{
  hplx_hor_analysis_by_lifting_ref self =
    (hplx_hor_analysis_by_lifting_ref) base;
  frame_info frame;
  int b, n;

  /* Begin by determining the Wavelet kernels and derivative properties. */

  self->kernel_type =
    info->get_kernel_type(info,base->direction,INFO__ANALYSIS,
                          base->component_idx,base->level_idx,NULL,NULL,
                          NULL,NULL);
  if (self->kernel_type == INFO__INT_LIFTING)
    {
      self->num_steps =
        info->get_int_steps(info,base->direction,base->component_idx,
                            base->level_idx,self->neg_supports,
                            self->pos_supports,self->int_taps,
                            self->int_downshifts);
    }
  else if (self->kernel_type == INFO__FLOAT_LIFTING)
    {
      self->num_steps =
        info->get_float_steps(info,base->direction,base->component_idx,
                              base->level_idx,self->neg_supports,
                              self->pos_supports,self->float_taps,
                              self->branch_scale,self->branch_scale+1);
    }
  else
    assert(0);
  for (n=0; n < self->num_steps; n++)
    {
      if (self->neg_supports[n] > self->neg_extend)
        self->neg_extend = self->neg_supports[n];
      if (self->pos_supports[n] > self->pos_extend)
        self->pos_extend = self->pos_supports[n];
    }
  if (self->kernel_type == INFO__FLOAT_LIFTING)
    { /* Compute DC gains associated with the output of each update lifting
         step, i.e. the 1'st, 3'rd, ... lifting steps. */
      float current_gain, source_gain, step_gain;
      int k;

      for (n=0; n < self->num_steps; n++)
        {
          current_gain = (n>=2)?(self->step_dc_gains[n-2]):1.0F;
          source_gain = (n>=1)?(self->step_dc_gains[n-1]):1.0F;
          step_gain = 0.0F;
          for (k=-self->neg_supports[n]; k <= self->pos_supports[n]; k++)
            step_gain += (self->float_taps[n])[k];
          self->step_dc_gains[n] = current_gain + step_gain*source_gain;
        }
      for (current_gain=1.0F, n=1; n < self->num_steps; n+=2)
        { /* This step ensures that the update lifting steps identify
             the incremental DC gain relative to the output of the previous
             update step, rather than the absolute DC gain at the end of
             each step. */
          step_gain = self->step_dc_gains[n] / current_gain;
          current_gain = self->step_dc_gains[n];
          self->step_dc_gains[n] = step_gain;
        }
    }

  /* Now determine tile and frame dimensions and attributes. */

  self->tile_width = dims->cols;
  self->first_idx = dims->left_col;
  info->get_level_info(info,base->component_idx,base->level_idx,
                       NULL,NULL,&frame,NULL);
  if (frame.hor_ssodwt)
    {
      int uses_overlap;
     
      /* First check that filters have some overlap. */

      for (uses_overlap=0, n=0; n < self->num_steps; n++)
        if (((n & 1)==0) && (self->pos_supports[n] > 0))
          uses_overlap = 1; /* Prediction step uses overlapping boundary */
      if (!uses_overlap)
        local_error("The 1-sample overlap method has no effect whatsoever "
                    "if all update steps in the lifting implementation of "
                    "the filter have only two taps!  The method was designed "
                    "for use with odd length filters.");

      /* Now set up frame dimensions. */

      self->frame_cols = frame_dims->cols;
      self->frame_ref = frame_dims->left_col;
      self->first_frame_cols = self->frame_cols -
        ((self->first_idx - self->frame_ref) & (self->frame_cols - 1));
      if (self->first_frame_cols >= self->tile_width)
        {
          self->first_frame_cols = self->tile_width;
          self->num_frames = 1;
        }
      else
        self->num_frames = 2 +
          (self->tile_width - self->first_frame_cols - 1) / self->frame_cols;
    }
  else
    { /* No frames, set frame dimensions to refer to the entire tile. */
      self->num_frames = 1;
      self->frame_cols = self->first_frame_cols = self->tile_width;
      self->frame_ref = self->first_idx;
    }

  /* Finally, perform branch-specific initialization. */

  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;
        left = (left+1-b)>>1;
        right = (right-b)>>1;
        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;
      }
      if (self->kernel_type == INFO__INT_LIFTING)
        {
          self->branch_buf_int[b] = (ifc_int *)
            local_malloc(XFORM_HBUF_KEY,sizeof(ifc_int)*
                     (branch_dims.cols+self->neg_extend+self->pos_extend+1));
          self->branch_buf_int[b] += self->neg_extend;
        }
      else if (self->kernel_type == INFO__FLOAT_LIFTING)
        {
          self->branch_buf_float[b] = (float *)
            local_malloc(XFORM_HBUF_KEY,sizeof(float)*
                     (branch_dims.cols+self->neg_extend+self->pos_extend+1));
          self->branch_buf_float[b] += self->neg_extend;
        }
      else
        assert(0);
      base->branches[b]->initialize(base->branches[b],info,
                                    &branch_dims,&branch_frame_dims);
    }
}

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

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

  assert(base->use_floats);
  assert(width == self->tile_width);
  if (width == 0)
    return;
  assert(self->kernel_type == INFO__FLOAT_LIFTING);
  first_sample_odd = self->first_idx & 1;
  if (base->horiz_limit > 1) {
    for (b=0; b < base->horiz_limit; b++)
      { /* Split input into even and odd sub-sequences. */
        float *sp, *dp;
  
        for (sp=line_buf+b, dp=self->branch_buf_float[b^first_sample_odd],
             n=(width+1-b)>>1; n > 0; n--, sp+=2, dp++)
          *dp = *sp;
      }
    perform_1d_float_lifting(self);
    for (b=0; b < base->horiz_limit; b++)
      base->branches[b]->push_line_float(base->branches[b],
                                         self->branch_buf_float[b],
                                         (width+1-(b^first_sample_odd))>>1);
  }
  else {
    float *sp, *dp;

    for (sp=line_buf, dp=self->branch_buf_float[0], n=width; n > 0; n--, sp++, dp++)
      *dp = *sp;
    base->branches[0]->push_line_float(base->branches[0],
                                       self->branch_buf_float[0], width);
  }
}

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

static void
  __push_line_fixed(hplx_analysis_stage_ref base, ifc_int *line_buf,
                    int width)
{
  hplx_hor_analysis_by_lifting_ref self =
    (hplx_hor_analysis_by_lifting_ref) base;
  int n, b, first_sample_odd;

  assert(width == self->tile_width);
  if (width == 0)
    return;
  first_sample_odd = self->first_idx & 1;
  if (self->kernel_type == INFO__FLOAT_LIFTING)
    {
      assert(base->use_floats);
      if (base->horiz_limit > 1) {
        for (b=0; b < base->horiz_limit; b++)
          { /* Split input into even and odd sub-sequences. */
            ifc_int *sp;
            float *dp;
  
            for (sp=line_buf+b, dp=self->branch_buf_float[b^first_sample_odd],
                  n=(width+1-b)>>1; n > 0; n--, sp+=2, dp++)
              *dp = (float) *sp;
          }
        perform_1d_float_lifting(self);
        for (b=0; b < base->horiz_limit; b++)
          base->branches[b]->push_line_float(base->branches[b],
                                             self->branch_buf_float[b],
                                             (width+1-(b^first_sample_odd))>>1);
        }
        else {
          ifc_int *sp;
          float *dp;

          for (sp=line_buf, dp = self->branch_buf_float[0], n=width; n > 0; n--)
            *(dp++) = (float) *(sp++);
          base->branches[0]->push_line_float(base->branches[0],
                                             self->branch_buf_float[0], width);
        }
    }
  else if (self->kernel_type == INFO__INT_LIFTING)
    {
      assert(!base->use_floats);
        if (base->horiz_limit > 1) {
          for (b=0; b < base->horiz_limit; b++)
            { /* Split input into even and odd sub-sequences. */
              ifc_int *sp, *dp;
    
              for (sp=line_buf+b, dp=self->branch_buf_int[b^first_sample_odd],
                    n=(width+1-b)>>1; n > 0; n--, sp+=2, dp++)
                *dp = *sp;
            }
          perform_1d_int_lifting(self);
          for (b=0; b < base->horiz_limit; b++)
            base->branches[b]->push_line_fixed(base->branches[b],
                                               self->branch_buf_int[b],
                                               (width+1-(b^first_sample_odd))>>1);
        }
        else {
          ifc_int *sp, *dp;

          for (sp=line_buf, dp=self->branch_buf_int[0], n=width; n > 0; n--, sp++, dp++)
            *dp = *sp;
          base->branches[0]->push_line_fixed(base->branches[0],
                                             self->branch_buf_int[0], width);
        }
    }
  else
    assert(0);
}

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

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

  for (b=0; b < base->horiz_limit; b++)
    {
      if (self->branch_buf_float[b] != NULL)
        local_free(self->branch_buf_float[b]-self->neg_extend);
      if (self->branch_buf_int[b] != NULL)
        local_free(self->branch_buf_int[b]-self->neg_extend);
      if (self->frame_work_buf_float[b] != NULL)
        local_free(self->frame_work_buf_float[b]-self->neg_extend);
      if (self->frame_work_buf_int[b] != NULL)
        local_free(self->frame_work_buf_int[b]-self->neg_extend);
      base->branches[b]->terminate(base->branches[b]);
    }
  local_free(self);
}

/*****************************************************************************/
/* EXTERN              create_hplx_hor_analysis_by_lifting                   */
/*****************************************************************************/

hplx_analysis_stage_ref
  create_hplx_hor_analysis_by_lifting(void)
{
  hplx_hor_analysis_by_lifting_ref result;

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