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

📄 std_kernel_info.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
            pos = k;
        }
    }
  neg = -neg;
  high->neg_support = pos;
  high->pos_support = neg;
  high->taps = (float *)
    local_malloc(INFO_MEM_KEY,sizeof(float)*(neg+pos+1));
  taps = high->taps + high->neg_support;
  for (n=-neg; n <= pos; n++)
    {
      if (n & 1)
        taps[-n] = odd_buf_0[64+((n-1)>>1)];
      else
        taps[-n] = odd_buf_1[64+(n>>1)];
    }
  high->int_rdx = -1;
  high->int_taps = NULL;
}

/*****************************************************************************/
/* STATIC                       construct_kernel_path                        */
/*****************************************************************************/

static char *
  construct_kernel_path(char *kernels_dir, char *branch, int kernel_idx)

 /* This function dynamically allocates a string buffer to hold the
    concatenation of the `kernels_dir', `branch', and "kernel-xxx" path
    names, where `xxx' stands for the value of `kernel_idx'.  The function
    automatically adjusts the separators within this final path name to
    reflect the appropriate usage on the host platform (WIN32 or UNIX). */

{
  char *path, *cp;
  char sep, alt_sep;

  if (kernels_dir == NULL)
    local_error("Unable to load user-defined kernels until the "
                "`kernels_dir' path can be established!  This may be done "
                "via the `-Fdir' argument or by defining the "
                "JP2_KERNELS_DIR environment variable.");

#ifdef WIN32
  sep = '\\';
  alt_sep = '/';
#else
  sep = '/';
  alt_sep = '\\';
#endif /* WIN32 */
  path = (char *) local_malloc(INFO_MEM_KEY,
                      strlen(kernels_dir)+strlen(branch)+strlen("kernel-")+8);
  strcpy(path,kernels_dir);
  cp = path + strlen(path);
  if ((cp > path) && (cp[-1] != sep) && (cp[-1] != alt_sep))
    *(cp++) = sep;
  sprintf(cp,"%s/kernel-%03d",branch,kernel_idx);
  for (cp=path; *cp != '\0'; cp++)
    if (*cp == alt_sep)
      *cp = sep;
  return(path);
}

/*****************************************************************************/
/* STATIC                     read_float_lifting_kernel                      */
/*****************************************************************************/

static void
  read_float_lifting_kernel(int kernel_idx, std_lifting_info_ptr lifting,
                            char *kernels_dir)

 /* Reads floating-point lifting coefficients from the file identified by
    the `kernel_idx' value, which must lie in the range 0 to 255.  The
    file format is as follows:  The first line should contain a sequence
    of positive integers, identifying the support of each lifting step.
    The support of the first prediction step appears first, followed by
    the support of the first update step, the support of the second predict
    step and so forth.  The number of integers on this line identifies the
    total number of lifting steps. Trailing zeros on this line will
    automatically be discarded for compatibility with the VM2.1 format.
        This first line should be followed by the filter taps (impulse
    response order) for each lifting step in sequence, with all taps for
    a given lifting step appearing on the same line of text.
        The remainder of the file is discarded, thereby ensuring that the
    VM2.1 files will be correctly read.
        The lifting coefficients are rounded to INFO__LIFTING_FRACTION
    fractional bits so that they can be saved losslessly in the codestream.
    As a result, the implementation of the W9X7 filter will be slightly
    different if used as a built-in filter, as opposed to a user-defined
    filter.  In addition to the INFO__LIFTING_FRACTION fractional bits,
    each lifting coefficient is represented using 2 non-fractional magnitude
    bits and a sign bit. */

{
  FILE *fp;
  char line[257], *filename, *cp, *next_cp;
  int num_steps = 0, supports[9];
  std_tap_info_ptr taps;
  int n, i;
  double frac_scale;

  frac_scale = (double)(1<<INFO__LIFTING_FRACTION);
  filename = construct_kernel_path(kernels_dir,"float_lifting",kernel_idx);
  if ((fp=fopen(filename,"r")) == NULL)
    local_error("Unable to open the user-defined lifting filter "
                "file, \"%s\"!",filename);
  if ((fgets(line,256,fp) == NULL) ||
      ((num_steps =
        sscanf(line,"%d %d %d %d %d %d %d %d %d",
               supports+0,supports+1,supports+2,supports+3,supports+4,
               supports+5,supports+6,supports+7,supports+8)) < 1) ||
       (num_steps > INFO__MAX_LIFTING_STEPS))
    local_error("Unable to parse the user-defined lifting steps "
                "from file, \"%s\"!  The first line of the file must "
                "define the supports of 1 to %d lifting steps.",
                filename,INFO__MAX_LIFTING_STEPS);

  while (supports[num_steps-1] == 0)
    {
      if (num_steps == 1)
        local_error("Unable to parse the user-defined lifting steps "
                    "from file, \"%s\"!  The first line of the file must "
                    "define the supports of 1 to 8 lifting steps.",
                    filename);
      num_steps--;
    }
  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;
      if (supports[n] > 7)
        local_error("Unable to represent lifting kernels with more than "
                    "7 taps per liftint step!");
      taps->neg_support = (supports[n] - ((n&1)?0:1)) >> 1;
      taps->pos_support = (supports[n] - ((n&1)?1:0)) >> 1;
      taps->taps = (float *)
        local_malloc(INFO_MEM_KEY,sizeof(float)*supports[n]);
      if (fgets(line,256,fp) == NULL)
        local_error("Syntax error in user-defined lifting filter "
                    "file, \"%s\"!  Tap values missing for one or more "
                    "lifting steps.",filename);
      cp = line;
      next_cp = NULL;
      while ((*cp == ' ') || (*cp == '\t'))
        cp++;
      for (i=supports[n]-1; i >= 0; i--)
        {
          taps->taps[i] = (float) strtod(cp,&next_cp);
          if (next_cp == cp)
            local_error("Syntax error in user-defined lifting filter "
                        "file, \"%s\"!  Insufficient tap values supplied "
                        "for lifting step %d out of %d.",filename,
                        supports[n]-i,supports[n]);
          cp = next_cp;
          taps->taps[i] = (float) /* Restrict number of fraction bits. */
            (floor(0.5 + taps->taps[i] * frac_scale) / frac_scale);
        }
      taps->int_rdx = 0;
      taps->int_taps = NULL;
    }

  fclose(fp);
  local_free(filename);
}

/*****************************************************************************/
/* STATIC                       read_int_lifting_kernel                      */
/*****************************************************************************/

static void
  read_int_lifting_kernel(int kernel_idx, std_lifting_info_ptr lifting,
                          char *kernels_dir)

 /* Reads fixed-point lifting coefficients from the file identified by
    the `kernel_idx' value, which must lie in the range 0 to 255.  The
    file format is as follows:  The first line should contain a sequence
    of positive integers, identifying the support of each lifting step.
    The support of the first prediction step appears first, followed by
    the support of the first update step, the support of the second predict
    step and so forth.  The number of integers on this line identifies the
    total number of lifting steps.  Trailing zeros on this line will
    automatically be discarded for compatibility with the VM2.1 format.
        This first line should be followed by the filter taps (impulse
    response order) for each lifting step in sequence, with all taps for
    a given lifting step appearing on the same line of text.  The tap values
    should be expressed as integers and the line on which they appear should
    contain a trailing integer expressing the amount by which the integer
    tap values should be downshifted to recover their floating-point
    equivalents.
        The remainder of the file is discarded, thereby ensuring that the
    VM2.1 files will be correctly read. */

{
  FILE *fp;
  char line[257], *filename, *cp, *next_cp;
  int num_steps = 0, supports[9];
  std_tap_info_ptr taps;
  int n, i;

  filename = construct_kernel_path(kernels_dir,"int_lifting",kernel_idx);
  if ((fp=fopen(filename,"r")) == NULL)
    local_error("Unable to open the user-defined lifting filter "
                "file, \"%s\"!",filename);
  if ((fgets(line,256,fp) == NULL) ||
      ((num_steps =
        sscanf(line,"%d %d %d %d %d %d %d %d %d",
               supports+0,supports+1,supports+2,supports+3,supports+4,
               supports+5,supports+6,supports+7,supports+8)) < 1) ||
       (num_steps > INFO__MAX_LIFTING_STEPS))
    local_error("Unable to parse the user-defined lifting steps "
                "from file, \"%s\"!  The first line of the file must "
                "define the supports of 1 to %d lifting steps.",
                filename,INFO__MAX_LIFTING_STEPS);

  while (supports[num_steps-1] == 0)
    {
      if (num_steps == 1)
        local_error("Unable to parse the user-defined lifting steps "
                    "from file, \"%s\"!  The first line of the file must "
                    "define the supports of 1 to 8 lifting steps.",
                    filename);
      num_steps--;
    }
  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;
      if (supports[n] > 7)
        local_error("Unable to represent lifting kernels with more than "
                    "7 taps per liftint step!");
      taps->neg_support = (supports[n] - ((n&1)?0:1)) >> 1;
      taps->pos_support = (supports[n] - ((n&1)?1:0)) >> 1;
      taps->taps = (float *)
        local_malloc(INFO_MEM_KEY,sizeof(float)*supports[n]);
      taps->int_taps = (int *)
        local_malloc(INFO_MEM_KEY,sizeof(int)*supports[n]);
      if (fgets(line,256,fp) == NULL)
        local_error("Syntax error in user-defined lifting filter "
                    "file, \"%s\"!  Tap values missing for one or more "
                    "lifting steps.",filename);
      cp = line;
      next_cp = NULL;
      while ((*cp == ' ') || (*cp == '\t'))
        cp++;
      for (i=supports[n]-1; i >= 0; i--)
        {
          taps->int_taps[i] = (int) strtol(cp,&next_cp,10);
          if (next_cp == cp)
            local_error("Syntax error in user-defined lifting filter "
                        "file, \"%s\"!  Insufficient tap values supplied "
                        "for lifting step %d out of %d.",filename,
                        supports[n]-i,supports[n]);
          cp = next_cp;
        }
      if ((sscanf(cp,"%d",&(taps->int_rdx)) < 1) ||
          (taps->int_rdx < 0))
        local_error("Syntax error in user-defined lifting filter "
                    "file, \"%s\"!  No integer shift found at the "
                    "end of the line of taps for lifting step %d "
                    "out of %d.",filename,supports[n]-1,supports[n]);
      for (i=0; i < supports[n]; i++)
        taps->taps[i] =
          ((float)(taps->int_taps[i])) / ((float)(1<<taps->int_rdx));
    }
  fclose(fp);
  local_free(filename);
}

/*****************************************************************************/
/* STATIC                      get_float_lifting_kernel                      */
/*****************************************************************************/

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

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

{
  int kernel_idx, n, i;
  int num_steps = 0, step_supports[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_float_lifting_kernel(kernel_idx,lifting,kernels_dir);
  else
    { /* Built-in kernel. */
      if (strcmp(id,"W9X7") == 0)
        {
          num_steps = 4;
          step_supports[0] = step_supports[1] = 2;

⌨️ 快捷键说明

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