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

📄 hplx_vert_synthesis_by_lifting.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
        { /* 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 = self->steps + n;
          step_gain = step->dc_gain / current_gain;
          current_gain = step->dc_gain;
          step->dc_gain = step_gain;
        }
    }

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

  self->rows_left_in_tile = dims->rows;
  self->first_row_idx_in_frame = dims->top_row;
  self->heap.buffer_length = dims->cols;
  for (n=0; n < self->num_buffering_stages; n++)
    self->buffering_stages[n].base.cols = dims->cols;
  info->get_level_info(info,base->component_idx,base->level_idx,
                       NULL,NULL,&frame,NULL);
  if (frame.vert_ssodwt)
    {
      int uses_overlap;

      /* First check that filters use overlap. */
      for (uses_overlap=0, n=0; n < self->num_steps; n++)
        if (((n & 1)==0) && (self->steps[n].pos_support > 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 for the frame dimensions and location. */
      self->frame_rows = frame_dims->rows;
      self->frame_ref = frame_dims->top_row;
      self->first_frame_rows = frame_dims->rows -
        ((dims->top_row - frame_dims->top_row) & (frame_dims->rows - 1));
      if (self->first_frame_rows >= dims->rows)
        {
          self->first_frame_rows = dims->rows;
          self->num_frames = 1;
        }
      else
        self->num_frames = 2 +
          (dims->rows - self->first_frame_rows - 1) / frame_dims->rows;
    }
  else
    {
      self->num_frames = 1;
      self->frame_rows = self->first_frame_rows = dims->rows;
      self->frame_ref = dims->top_row;
    }

  /* Now perform branch initialization. */

  for (b=0; b < base->vert_limit; b++)
    {
      canvas_dims branch_dims, branch_frame_dims;
      int top, bottom;

      self->buffering_stages[b].base.num_users++;
        /* The process which pulls even and odd rows from the first two
           buffering stages is understood as an additional user. */
      branch_dims = *dims;
      if (base->vert_limit > 1) {
        top = branch_dims.top_row;
        bottom = top + branch_dims.rows - 1;
        top = (top+1-b)>>1;
        bottom = (bottom-b)>>1;
        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;
      }
      base->branches[b]->initialize(base->branches[b],info,
                                    &branch_dims,&branch_frame_dims);
    }
  start_vertical_frame(self,NULL);
}

/*****************************************************************************/
/*                               __pull_line_fixed                           */
/*****************************************************************************/

static void
  __pull_line_fixed(hplx_synthesis_stage_ref base, ifc_int *line_buf,
                    int width)
{
  hplx_vert_synthesis_by_lifting_ref self =
    (hplx_vert_synthesis_by_lifting_ref) base;
  hplx_buffering_stage_ptr stage;
  hplx_row_buffer_state_ptr buf;
  int n, next_row_idx;

  if (base->vert_limit > 1) {
    next_row_idx = self->current_frame_rows - self->rows_left_in_frame +
      (self->first_row_idx_in_frame & 1);
    stage = &(self->buffering_stages[1-(next_row_idx&1)].base);
    assert(stage->cols == width);
    if (width == 0)
      return;
    assert(self->rows_left_in_frame > 0);
    if (self->buffering_stages[next_row_idx&1].base.rows == 0)
      { /* Signals of length < 2 must be treated specially. */
        self->rows_left_in_frame--;
        assert((self->rows_left_in_frame == 0) &&
               (self->current_frame_rows == 1));

        /* Fix for single sample discrepancy between VM8.5 and FDIS */
        if (!stage->skip_last)
          {
            base->branches[next_row_idx&1]->pull_line_fixed(
                               base->branches[next_row_idx&1],line_buf,width);
            if ((self->current_frame_rows == 1) &&
                (self->first_row_idx_in_frame & 1))
              {
                ifc_int *sp;

                for (sp=line_buf, n=width; n > 0; n--)
                  {
                    *(sp++) >>= 1;
                  }
              }
          }

        self->frame_idx++;
        if (self->frame_idx < self->num_frames)
          {
            start_vertical_frame(self,NULL);
            if (stage->special_first)
              __pull_line_fixed(base,line_buf,width);
          }
        return;
      }

     /* Find index of next row in relevant sub-sequence, relative to first
        row in that subsequence. */
    next_row_idx = (next_row_idx >> 1) - stage->missing_first_row;
    assert(next_row_idx >= 0);
    hplx_lift_stage__get_rows(stage,next_row_idx,1,&buf);
    hplx_lift_stage__release_row(stage,next_row_idx);
    if (buf->float_buf != NULL)
      {
        float *sp, val;
        ifc_int *dp;

        for (dp=line_buf, sp=buf->float_buf, n=width; n > 0; n--)
          {
            val = *(sp++);
            *(dp++) = (ifc_int)((val<0.0F)?(val-0.5F):(val+0.5F));
          }
      }
    else
      {
        ifc_int *sp, *dp;

        for (dp=line_buf, sp=buf->int_buf, n=width; n > 0; n--)
          *(dp++) = *(sp++);
      }

    /* Advance frame counters and move onto next frame if necessary. */

    self->rows_left_in_frame--;
    if (self->rows_left_in_frame == 0)
      {
        self->frame_idx++;
        if (self->frame_idx < self->num_frames)
          {
            start_vertical_frame(self,buf);
            if (stage->special_first)
              {
                if (self->current_frame_rows == 1)
                  { /* This frame consists only in the overlap row. */
                    self->rows_left_in_frame = 0;
                    self->frame_idx++;
                    assert(self->frame_idx == self->num_frames);
                  }
                else
                  __pull_line_fixed(base,line_buf,width);
              }
          }
      }
  }
  else {
    if (base->use_floats) {
      ifc_int *dp;
      float *sp, *tmp_buf;

      tmp_buf = (float *) local_malloc(XFORM_MEM_KEY, width*sizeof(float));
      base->branches[0]->pull_line_float(base->branches[0],tmp_buf,width);
      for (dp=line_buf, sp=tmp_buf, n=width; n > 0; n--)
        *(dp++) = (ifc_int) *(sp++);
      local_free(tmp_buf);
    }
    else {
      base->branches[0]->pull_line_fixed(base->branches[0],line_buf,width);
    }
  }

}

/*****************************************************************************/
/*                               __pull_line_float                           */
/*****************************************************************************/

static void
  __pull_line_float(hplx_synthesis_stage_ref base, float *line_buf,
                    int width)
{
  hplx_vert_synthesis_by_lifting_ref self =
    (hplx_vert_synthesis_by_lifting_ref) base;
  hplx_buffering_stage_ptr stage;
  hplx_row_buffer_state_ptr buf;
  float *sp, *dp;
  int n, next_row_idx;

  if (base->vert_limit > 1) {
    next_row_idx = self->current_frame_rows - self->rows_left_in_frame +
      (self->first_row_idx_in_frame & 1);
    stage = &(self->buffering_stages[1-(next_row_idx&1)].base);
    assert(stage->cols == width);
    if (width == 0)
      return;
    assert(self->rows_left_in_frame > 0);
    if (self->buffering_stages[next_row_idx&1].base.rows == 0)
      { /* Signals of length < 2 must be treated specially. */
        self->rows_left_in_frame--;
        assert((self->rows_left_in_frame == 0) &&
               (self->current_frame_rows == 1));
        if (!stage->skip_last)
          base->branches[next_row_idx&1]->pull_line_float(
                                base->branches[next_row_idx&1],line_buf,width);
        self->frame_idx++;
        if (self->frame_idx < self->num_frames)
          {
            start_vertical_frame(self,NULL);
            if (stage->special_first)
              __pull_line_float(base,line_buf,width);
          }
        return;
      }

    /* Find index of next row in relevant sub-sequence, relative to first
       row in that subsequence. */
    next_row_idx = (next_row_idx >> 1) - stage->missing_first_row;
    assert(next_row_idx >= 0);
    hplx_lift_stage__get_rows(stage,next_row_idx,1,&buf);
    hplx_lift_stage__release_row(stage,next_row_idx);
    for (dp=line_buf, sp=buf->float_buf, n=width; n > 0; n--)
      *(dp++) = *(sp++);

    /* Advance frame counters and move onto next frame if necessary. */

    self->rows_left_in_frame--;
    if (self->rows_left_in_frame == 0)
      {
        self->frame_idx++;
        if (self->frame_idx < self->num_frames)
          {
            start_vertical_frame(self,buf);
            if (stage->special_first)
              {
                if (self->current_frame_rows == 1)
                  { /* This frame consists only in the overlap row. */
                    self->rows_left_in_frame = 0;
                    self->frame_idx++;
                    assert(self->frame_idx == self->num_frames);
                  }
                else
                  __pull_line_float(base,line_buf,width);
              }
          }
      }
  }
  else{
    base->branches[0]->pull_line_float(base->branches[0],line_buf,width);
  }

}

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

static void
  __terminate(hplx_synthesis_stage_ref base)
{
  hplx_vert_synthesis_by_lifting_ref self =
    (hplx_vert_synthesis_by_lifting_ref) base;
  hplx_row_buffer_state_ptr buf;
  hplx_buffering_stage_ptr stage;
  int b, n, num_buffers;

  if (self->steps != NULL)
    local_free(self->steps);
  if (self->buffering_stages != NULL)
    {
      for (n=0; n < self->num_buffering_stages; n++)
        {
          stage = &(self->buffering_stages[n].base);
          if (stage->row_buffers != NULL)
            {
              num_buffers = stage->next_row_idx - stage->min_row_idx;
              for (b=0; b < num_buffers; b++)
                hplx_lift_heap__return_buffer(stage->heap,
                                              stage->row_buffers[b]);
              local_free(stage->row_buffers);
            }
        }
      local_free(self->buffering_stages);
    }
  while ((buf=self->heap.head) != NULL)
    {
      self->heap.head = buf->next;
      if (buf->float_buf != NULL)
        local_free(buf->float_buf);
      if (buf->int_buf != NULL)
        local_free(buf->int_buf);
      local_free(buf);
    }
  for (b=0; b < base->vert_limit; b++)
    base->branches[b]->terminate(base->branches[b]);
  local_free(self);
}

/*****************************************************************************/
/* EXTERN             create_hplx_vert_synthesis_by_lifting                  */
/*****************************************************************************/

hplx_synthesis_stage_ref
  create_hplx_vert_synthesis_by_lifting(void)
{
  hplx_vert_synthesis_by_lifting_ref result;

  result = (hplx_vert_synthesis_by_lifting_ref)
    local_malloc(XFORM_MEM_KEY,sizeof(hplx_vert_synthesis_by_lifting_obj));
  result->base.initialize = __initialize;
  result->base.pull_line_fixed = __pull_line_fixed;
  result->base.pull_line_float = __pull_line_float;
  result->base.terminate = __terminate;
  return((hplx_synthesis_stage_ref) result);
}

⌨️ 快捷键说明

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