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

📄 ebcot_vpw.c

📁 JPEG2000实现的源码
💻 C
字号:
/*****************************************************************************/
/* Copyright 1998, Hewlett-Packard Company                                   */
/* All rights reserved                                                       */
/* File: "ebcot_vpw.c"                                                       */
/* Description: Implements visually progressive weighting functionality.     */
/* Author: David Taubman                                                     */
/* Affiliation: Hewlett-Packard and                                          */
/*              The University of New South Wales, Australia                 */
/* Acknowledgements: Based on the ideas developed by Jin Li and Shawmin Lei  */
/*                   at Sharp Labs, U.S.A.                                   */
/* Version: VM8.0                                                            */
/* Last Revised: 20 July, 2000                                               */
/*****************************************************************************/

/*****************************************************************************/
/* Modified by David Taubman to support interface modifications, arbitrary   */
/* changes in coding parameters from component to component and from tile    */
/* to tile, packet partitions, rich packet sequencing conventions and to     */
/* support the full generality of PART-1 of the JPEG2000                     */
/* standard, and to support most anticipated generality of PART-2.  Changes  */
/* are too numerous to flag individually within the code, which in some      */
/* places has been completely rewritten.  All changes copyrighted by HP with */
/* all rights reserved for the modified parts.                               */
/*****************************************************************************/

/*****************************************************************************/
/* Modified for general wavelet decompositions.                              */
/* Copyright 2000 Science Applications International Corporation (SAIC).     */
/* Copyright 1995 University of Arizona, Arizona Board of Regents.           */
/* All Rights Reserved for modified parts.                                   */
/*****************************************************************************/

#include <local_services.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include <ifc.h>
#include "ebcot_encoder.h"
#include "ebcot_vpw.h"

/* ========================================================================= */
/* -------------------------- Internal Functions --------------------------- */
/* ========================================================================= */

/*****************************************************************************/
/* STATIC                        is_blank_line                               */
/*****************************************************************************/

static int
  is_blank_line(char *line)
{
  while ((*line == ' ') || (*line == '\t') || (*line == '\n') ||
         (*line == '\r'))
    line++;
  return((*line == '\0') || (*line == '#'));
}

/*****************************************************************************/
/* STATIC                 apply_factors_to_bands_in_level                    */
/*****************************************************************************/

static void
  apply_factors_to_bands_in_level(ebcot_level_info_ptr lev, float *factors)

 /* Applies the factors in the supplied array to the subbands in the
    supplied resolution level.  The `factors' array is organized as 16 rows
    of 4 entries each.  The first row (first four entries) identifies the
    scale factors for the major orientation.  The next 3 rows identify
    the scale factors for the minor orientation and the last 12 rows identify
    the scale factors for the most minor orientation.  This may be
    understood easily with reference to the comments at the beginning of
    this file under the heading, "File Format for Specifying Quantization
    Scale Factors" in "std_forward_info.c". */

{
  int b, d, orient, max_hp_descent, hp_descent, idx;
  ebcot_band_info_ptr band;
  float fact;

  max_hp_descent = lev->max_hp_descent;

  for (b=lev->min_band; b <= lev->max_band; b++)
    {
      band = lev->bands + b;
      if (!band->valid_band)
        continue;

      /* SAIC General Decomp. Begin mods */
      hp_descent = band->vert_hp_descent;
      /* SAIC General Decomp. End mods */

      if (b == LL_BAND)
        fact = factors[0];
      else
        for (idx=0, fact=1.0F, d=max_hp_descent-1; 
             d >= max_hp_descent-hp_descent; d--)
          {
            orient = (b>>(d+d)) & 3;
            idx = 4*idx + orient;
            assert(idx < 64);
            fact *= factors[idx];
          }
      band->vpw_weight *= fact*fact;
    }
}

/*****************************************************************************/
/* STATIC                   parse_weight_factor_file                         */
/*****************************************************************************/

static void
  parse_weight_factor_file(int num_components,
                           ebcot_component_info_ptr components,
                           char *filename)

 /* This function essentially mimics the `parse_quantization_factor_file'
    function found in "std_forward_info.c". */

{
  FILE *fp;
  char line[257], *ch1, *ch2;
  int min_c, max_c, c, n, d, have_line, levels_left;
  float level_factors[64];
  ebcot_component_info_ptr comp_info;
  ebcot_level_info_ptr lev;

  if ((fp = fopen(filename,"r")) == NULL)
    local_error("Unable to open the supplied file, \"%s\"!",filename);
  have_line = 0;
  while (have_line || (fgets(line,256,fp) != NULL))
    {
      have_line = 0;
      if (is_blank_line(line))
        continue;
      if ((ch2 = strchr(line,')')) != NULL)
        *ch2 = '\0';
      for (ch1=line; *ch1 != '\0'; ch1++)
        if (*ch1 == '(')
          break;
      if ((*ch1 == '\0') || (ch2 == NULL) ||
          (sscanf(ch1+1,"%d %d",&min_c,&max_c) != 2) ||
          (min_c < 1) || (max_c < min_c))
        local_error("Badly formed segment header line in file, "
                    "\"%s\"!  Must contain a range of component "
                    "indices (all >= 1), enclosed in parentheses!",filename);
      if (max_c > num_components)
        max_c = num_components;
      min_c--; max_c--;
      /* Check for accidental use of old syntax. */
      if (sscanf(ch2+1,"%f",&(level_factors[0])) == 1)
        local_error("The syntax and interpretation of quantization factor "
                    "files used by `-Fweights', `-Fsteps' and other "
                    "band-specific weighting arguments has changed!  "
                    "Factors are now specified starting from the highest "
                    "resolution level rather than the lowest; see the "
                    "comments at the start of file \"std_forward_info.c\" "
                    "for a description of the new syntax and interpretation.");
      for (d=0; d < 64; d++)
        level_factors[d] = 1.0F;
      n = 0;
      while (fgets(line,256,fp) != NULL)
        {
          if (is_blank_line(line))
            continue;
          if (strchr(line,'(') != NULL)
            { /* Found start of new segment. */
              have_line = 1;
              break;
            }
          for (d=0; d < 64; d++)
            level_factors[d] = 1.0F;
          d = 0;
          do {
            if (sscanf(line,"%f %f %f %f",
                       &(level_factors[4*d+LL_BAND]),
                       &(level_factors[4*d+HL_BAND]),
                       &(level_factors[4*d+LH_BAND]),
                       &(level_factors[4*d+HH_BAND])) != 4)
              local_error("Malformed level block encountered "
                          "within quantization factor file, \"%s\"!  "
                          "Need 1, 4 or 16 lines of factors, with "
                          "four factors on each line!",filename);
            if (fgets(line,256,fp) == NULL)
              line[0] = '\0';
            d++;
          } while ((d < 16) && !is_blank_line(line));
          if ((!is_blank_line(line)) || ((d != 1) && (d != 4) && (d != 16)))
            local_error("Malformed level block encountered "
                        "within quantization factor file, \"%s\"!  "
                        "Need 1, 4 or 16 lines of factors, with "
                        "three factors on the first line and 4 on "
                        "any additional lines!  Level blocks must "
                        "be separated by blank lines.",filename);
          for (c=min_c; c <= max_c; c++)
            {
              comp_info = components + c;
              if (n <= comp_info->num_levels)
                {
                  lev = comp_info->levels + comp_info->num_levels - n;
                  apply_factors_to_bands_in_level(lev,level_factors);
                }
            }
          n++;
        }
      /* Apply last set of factors to any remaining levels. */
      do {
        levels_left = 0;
        for (c=min_c; c <= max_c; c++)
          {
            comp_info = components + c;
            if (n <= comp_info->num_levels)
              {
                levels_left = 1;
                lev = comp_info->levels + comp_info->num_levels - n;
                apply_factors_to_bands_in_level(lev,level_factors);
              }
          }
        n++;
      } while (levels_left);
    }
  fclose(fp);
}

/*****************************************************************************/
/* STATIC                      load_new_weights                              */
/*****************************************************************************/

static void
  load_new_weights(ebcot_tile_ptr tile, ebcot_vpw_rate_info_ptr vpw)

 /* This function loads a visual progressive weighting file identified
    by `vpw' and sets the relevant weights into each `ebcot_band_info'
    structure's `vpw_weight' field.  The file format is exactly the same as
    that of the other quantization and WMSE weight specification files and
    is detailed in the comments appearing at the beginning of the
    "std_forward_info.c" source file.  If `vpw' is NULL, the weights are
    all reset to unity. */

{
  int c, n, b;
  ebcot_component_info_ptr comp_info;
  ebcot_level_info_ptr lev;
  ebcot_band_info_ptr band;

  /* First reset all the `vpw_weight' fields. */

  for (c=0; c < tile->num_components; c++)
    {
      comp_info = tile->components + c;
      for (n=0; n <= comp_info->num_levels; n++)
        {
          lev = comp_info->levels + n;
          for (b=lev->min_band; b <= lev->max_band; b++)
            {
              band = lev->bands + b;
              if (!band->valid_band)
                continue;
              band->vpw_weight = (vpw != NULL)?(1.0F):(-1.0F);
            }
        }
    }
  if (vpw != NULL)
    parse_weight_factor_file(tile->num_components,tile->components,
                             vpw->filename);
}


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

/*****************************************************************************/
/* EXTERN                      create_ebcot_vpw                              */
/*****************************************************************************/

ebcot_vpw_info_ptr
  create_ebcot_vpw(int argc, char *argv[])
{
  ebcot_vpw_info_ptr vpw;
  ebcot_vpw_rate_info_ptr elt, scan, prev;
  float rate;

  vpw = (ebcot_vpw_info_ptr)
    local_malloc(EBCOT_MEM_KEY,sizeof(ebcot_vpw_info));
  assert(argc > 0);
  do {
    if ((argc < 2) ||
        (sscanf(argv[0],"%f",&rate) == 0) || (rate <= 0.0F))
      local_error("The `-Cpvw' argument must be followed by one or more "
                  "pairs of rate/filename pairs, with strictly positive "
                  "maximum bit-rates for each visual weights file!");
    elt = (ebcot_vpw_rate_info_ptr)
      local_malloc(EBCOT_MEM_KEY,sizeof(ebcot_vpw_rate_info));
    elt->max_rate = rate;
    elt->filename = (char *)
      local_malloc(EBCOT_MEM_KEY,1+strlen(argv[1]));
    strcpy(elt->filename,argv[1]);
    argv += 2; argc -= 2;
    for (prev=NULL, scan=vpw->list; scan != NULL; prev=scan, scan=scan->next)
      if (scan->max_rate > rate)
        break;
    elt->next = scan;
    if (prev == NULL)
      vpw->list = elt;
    else
      prev->next = elt;
  } while (argc > 0);
  return(vpw);
}

/*****************************************************************************/
/* EXTERN                    ebcot_vpw__complete                             */
/*****************************************************************************/

void
  ebcot_vpw__complete(ebcot_vpw_info_ptr vpw, int rows, int cols,
                      int header_bytes)
{
  ebcot_vpw_rate_info_ptr elt;

  assert(vpw->loaded_entry == NULL);
  for (elt=vpw->list; elt != NULL; elt=elt->next)
    elt->max_cumulative_bytes =
      ((int)(elt->max_rate*0.125*((double)(rows*cols)))) - header_bytes;
}

/*****************************************************************************/
/* EXTERN                    ebcot_vpw__terminate                            */
/*****************************************************************************/

void
  ebcot_vpw__terminate(ebcot_vpw_info_ptr vpw)
{
  ebcot_vpw_rate_info_ptr elt;

  while ((elt=vpw->list) != NULL)
    {
      vpw->list = elt->next;
      local_free(elt->filename);
      local_free(elt);
    }
  local_free(vpw);
}

/*****************************************************************************/
/* EXTERN                ebcot_vpw__set_layer_weights                        */
/*****************************************************************************/

void
  ebcot_vpw__set_layer_weights(ebcot_vpw_info_ptr vpw,
                               ebcot_encoder_ref self,
                               int max_cumulative_bytes)
{
  int tnum;
  ebcot_vpw_rate_info_ptr elt;

  for (elt=vpw->list; elt != NULL; elt=elt->next)
    if (elt->max_cumulative_bytes >= max_cumulative_bytes)
      break;

  if (elt != vpw->loaded_entry)
    for (tnum=0; tnum < self->num_tiles; tnum++)
      load_new_weights(self->tiles+tnum,elt);
  vpw->loaded_entry = elt;
}

⌨️ 快捷键说明

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