std_kernel_info.c

来自「JPEG2000实现的源码」· C语言 代码 · 共 905 行 · 第 1/3 页

C
905
字号
          step_supports[2] = step_supports[3] = 2;
          step_taps[0] = p1_9x7_taps;
          step_taps[1] = u1_9x7_taps;
          step_taps[2] = p2_9x7_taps;
          step_taps[3] = u2_9x7_taps;
        }
      else if (strcmp(id,"W5X3") == 0)
        {
          num_steps = 2;
          step_supports[0] = step_supports[1] = 2;
          step_taps[0] = p1_5x3_taps;
          step_taps[1] = u1_5x3_taps;
        }
      else
        local_error("Unrecognized Wavelet kernel identifier, \"%s\", "
                    "supplied via `-Fkernels'!",id);
      result = 0;
      assert(num_steps <= 8);
      lifting->num_steps = num_steps;
      lifting->steps = (std_tap_info_ptr)
        local_malloc(INFO_MEM_KEY,sizeof(std_tap_info)*num_steps);
      for (n=0; n < num_steps; n++)
        {
          taps = lifting->steps + n;
          taps->neg_support = (step_supports[n] - ((n&1)?0:1)) >> 1;
          taps->pos_support = (step_supports[n] - ((n&1)?1:0)) >> 1;
          taps->taps = (float *)
            local_malloc(INFO_MEM_KEY,sizeof(float)*step_supports[n]);
          for (i=0; i < step_supports[n]; i++)
            taps->taps[i] = (float)((step_taps[n])[step_supports[n]-1-i]);
          taps->int_rdx = -1;
          taps->int_taps = NULL;
        }
    }
  lifting->lp_scale = lifting->hp_scale = 1.0F;
  return(result);
}

/*****************************************************************************/
/* STATIC                       get_int_lifting_kernel                       */
/*****************************************************************************/

static int
  get_int_lifting_kernel(char *id, char *kernels_dir,
                         std_lifting_info_ptr lifting)

 /* Loads the contents of the `lifting' structure to reflect the
    reversible lifting implementation of the Wavelet kernel identified
    by the `id' string.  The kernel scaling factors are set to 1.0. */

{
  int kernel_idx, n, i;
  int num_steps = 0, step_supports[8], step_rdx[8];
  double *step_taps[8];
  std_tap_info_ptr taps;
  int result;

  result = 1;
  if ((sscanf(id,"%d",&kernel_idx) == 1) &&
      (kernel_idx >= 0) && (kernel_idx <= 255))
    read_int_lifting_kernel(kernel_idx,lifting,kernels_dir);
  else
    { /* Built-in kernel. */
      if (strcmp(id,"W9X7") == 0)
        local_error("No built-in reversible lifting steps available "
                    "for W9X7 kernel at the present time!  You will need "
                    "to resort to a user-defined kernel file.");
      else if (strcmp(id,"W5X3") == 0)
        {
          num_steps = 2;
          step_supports[0] = step_supports[1] = 2;
          step_taps[0] = p1_5x3_taps; step_rdx[0] = p1_5X3_rdx;
          step_taps[1] = u1_5x3_taps; step_rdx[1] = u1_5X3_rdx;
        }
      else
        local_error("Unrecognized Wavelet kernel identifier, \"%s\", "
                    "supplied via `-Fkernels'!",id);
      result = 0;
      assert(num_steps <= 8);
      lifting->num_steps = num_steps;
      lifting->steps = (std_tap_info_ptr)
        local_malloc(INFO_MEM_KEY,sizeof(std_tap_info)*num_steps);
      for (n=0; n < num_steps; n++)
        {
          float scale;

          taps = lifting->steps + n;
          taps->neg_support = (step_supports[n] - ((n&1)?0:1)) >> 1;
          taps->pos_support = (step_supports[n] - ((n&1)?1:0)) >> 1;
          taps->int_rdx = step_rdx[n];
          scale = (float)(1<<taps->int_rdx);
          taps->taps = (float *)
            local_malloc(INFO_MEM_KEY,sizeof(float)*step_supports[n]);
          taps->int_taps = (int *)
            local_malloc(INFO_MEM_KEY,sizeof(int)*step_supports[n]);
          for (i=0; i < step_supports[n]; i++)
            {
              taps->int_taps[i] = (int)
                floor((step_taps[n])[step_supports[n]-1-i] * scale + 0.5);
              taps->taps[i] = ((float)(taps->int_taps[i])) / scale;
            }
        }
    }
  lifting->lp_scale = lifting->hp_scale = 1.0F;
  return(result);
}

/* ========================================================================= */
/* -------------------------- External Functions --------------------------- */
/* ========================================================================= */

/*****************************************************************************/
/* EXTERN                      std_load_kernel                               */
/*****************************************************************************/

int
  std_load_kernel(char *id, char *kernels_dir, std_kernel_info_ptr kernel)
{
  int result;

  if (kernel->kernel_type == INFO__INT_LIFTING)
    {
      result =
        get_int_lifting_kernel(id,kernels_dir,&(kernel->lifting));
      get_convolution_from_lifting(&(kernel->lifting),
                                   kernel->low,kernel->high);
    }
  else
    {
      result =
        get_float_lifting_kernel(id,kernels_dir,&(kernel->lifting));

      get_convolution_from_lifting(&(kernel->lifting),
                                   kernel->low,kernel->high);
      kernel->lifting.lp_scale = normalize_convolution_taps(kernel->low);
      kernel->lifting.hp_scale = normalize_convolution_taps(kernel->high);
    }
  get_synthesis_from_analysis(kernel->low,kernel->high);
  return(result);
}

/*****************************************************************************/
/* EXTERN                   std_user_defined_summary                         */
/*****************************************************************************/

std_user_defined_ptr
  std_user_defined_summary(std_kernel_info_ptr kernel)
{
  std_lifting_info_ptr lifting;
  std_user_defined_ptr result;
  int reversible, s, t;

  lifting = &(kernel->lifting);
  reversible = (kernel->kernel_type == INFO__INT_LIFTING);
  result = (std_user_defined_ptr) local_malloc(INFO_MEM_KEY,sizeof(std_user_defined));
  result->next = NULL;
  result->num_steps = lifting->num_steps;
  for (s=0; s < result->num_steps; s++)
    {
      int support;

      support = lifting->steps[s].neg_support+lifting->steps[s].pos_support+1;
      result->step_supports[s] = support;
      if (reversible)
        {
          result->downshifts[s] = lifting->steps[s].int_rdx;
          for (t=0; t < support; t++)
            result->taps[s][t] = lifting->steps[s].int_taps[support-1-t];
        }
      else
        {
          result->downshifts[s] = INFO__LIFTING_FRACTION;
          for (t=0; t < support; t++)
            result->taps[s][t] = (int)
              floor(0.5 + lifting->steps[s].taps[support-1-t] *
                    (double)(1<<INFO__LIFTING_FRACTION));
        }
    }
  return(result);
}

/*****************************************************************************/
/* EXTERN                     std_translate_kernel                           */
/*****************************************************************************/

void
  std_translate_kernel(char *id, std_user_defined_ptr user,
                       std_kernel_info_ptr kernel)
{
  int reversible, n, k;
  std_lifting_info_ptr lifting;
  std_tap_info_ptr taps;
  int num_steps = 0, step_supports[8], step_rdx[8];
  double *step_taps[8];
  double taps_buf[8][7];

  /* First fill out the `num_steps', `step_supports', `step_rdx' and
     `step_taps' local variables. */

  reversible = (kernel->kernel_type == INFO__INT_LIFTING);
  if (id != NULL)
    { /* Built-in kernel. */
      if (strcmp(id,"W9X7") == 0)
        {
          if (reversible)
            local_error("Cannot use the W9X7 kernel with a reversible "
                        "decomposition!");
          num_steps = 4;
          step_supports[0] = step_supports[1] = 2;
          step_supports[2] = step_supports[3] = 2;
          step_taps[0] = p1_9x7_taps;
          step_taps[1] = u1_9x7_taps;
          step_taps[2] = p2_9x7_taps;
          step_taps[3] = u2_9x7_taps;
        }
      else if (strcmp(id,"W5X3") == 0)
        {
          num_steps = 2;
          step_supports[0] = step_supports[1] = 2;
          step_taps[0] = p1_5x3_taps; step_rdx[0] = p1_5X3_rdx;
          step_taps[1] = u1_5x3_taps; step_rdx[1] = u1_5X3_rdx;
        }
      else
        assert(0);
    }
  else
    { /* User defined kernel. */
      num_steps = user->num_steps;
      assert(num_steps <= 8);
      for (n=0; n < num_steps; n++)
        {
          double scale;

          step_supports[n] = user->step_supports[n];
          step_rdx[n] = user->downshifts[n];
          scale = (double)(1<<step_rdx[n]);
          scale = 1.0 / scale;
          assert(step_supports[n] < 8);
          for (k=0; k < step_supports[n]; k++)
            taps_buf[n][k] = ((double)(user->taps[n][k])) * scale;
          step_taps[n] = &(taps_buf[n][0]);
        }
    }

  /* Now convert the information in `num_steps', `step_supports',
     `step_rdx' and `step_taps' into a complete kernel specifier. */
  
  lifting = &(kernel->lifting);
  if (reversible)
    {
      lifting->num_steps = num_steps;
      lifting->steps = (std_tap_info_ptr)
        local_malloc(INFO_MEM_KEY,sizeof(std_tap_info)*num_steps);
      for (n=0; n < num_steps; n++)
        {
          float scale;

          taps = lifting->steps + n;
          taps->neg_support = (step_supports[n] - ((n&1)?0:1)) >> 1;
          taps->pos_support = (step_supports[n] - ((n&1)?1:0)) >> 1;
          taps->int_rdx = step_rdx[n];
          scale = (float)(1<<taps->int_rdx);
          taps->taps = (float *)
            local_malloc(INFO_MEM_KEY,sizeof(float)*step_supports[n]);
          taps->int_taps = (int *)
            local_malloc(INFO_MEM_KEY,sizeof(int)*step_supports[n]);
          for (k=0; k < step_supports[n]; k++)
            {
              taps->int_taps[k] = (int)
                floor((step_taps[n])[step_supports[n]-1-k] * scale + 0.5);
              taps->taps[k] = ((float)(taps->int_taps[k])) / scale;
            }
        }
      kernel->lifting.lp_scale = kernel->lifting.hp_scale = 1.0F;
      get_convolution_from_lifting(lifting,kernel->low,kernel->high);
    }
  else
    {
      lifting->num_steps = num_steps;
      lifting->steps = (std_tap_info_ptr)
        local_malloc(INFO_MEM_KEY,sizeof(std_tap_info)*num_steps);
      for (n=0; n < num_steps; n++)
        {
          taps = lifting->steps + n;
          taps->neg_support = (step_supports[n] - ((n&1)?0:1)) >> 1;
          taps->pos_support = (step_supports[n] - ((n&1)?1:0)) >> 1;
          taps->taps = (float *)
            local_malloc(INFO_MEM_KEY,sizeof(float)*step_supports[n]);
          for (k=0; k < step_supports[n]; k++)
            taps->taps[k] = (float)((step_taps[n])[step_supports[n]-1-k]);
          taps->int_rdx = -1;
          taps->int_taps = NULL;
        }
      kernel->lifting.lp_scale = kernel->lifting.hp_scale = 1.0F;
      get_convolution_from_lifting(lifting,kernel->low,kernel->high);
      kernel->lifting.lp_scale = normalize_convolution_taps(kernel->low);
      kernel->lifting.hp_scale = normalize_convolution_taps(kernel->high);
    }
  get_synthesis_from_analysis(kernel->low,kernel->high);
}

⌨️ 快捷键说明

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