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

📄 ebcot_send_bits.c

📁 JPEG2000 EBCOT算法源码
💻 C
📖 第 1 页 / 共 3 页
字号:
  optimize_bitstream_layer(the_encoder_ref self, int layer_idx,
                           std_int max_rd_threshold,
                           tag_buffer_ptr tags,
                           int max_cumulative_bytes,
                           int previous_cumulative_bytes,
                           int include_makeup_passes)

 /* This function implements the rate-distortion optimization algorithm.
    It saves the state of any previously generated bit-stream layers and
    then invokes `form_bitstream_layer' as often as necessary to find the
    smallest rate-distortion threshold such that the total number of bytes
    required to represent the layer does not exceed `max_cumulative_bytes'
    minus `previous_cumulative_bytes'.  It then restores the state of any
    previously generated bit-stream layers and returns the threshold.  The
    caller must invoke `form_bitstream_layer' directly with this threshold
    to actually generate the new bit-stream layer.  In the extreme case, this
    function can be used to generate all bit-stream layers.  Normally,
    however, it will be used only to generate a small number of layers which
    are of special interest, while any intervening layers can be generated
    directly from some approximate threshold values.
        If `include_makeup_passes' is non-zero (true), the function sets the
    `makeup_layer' of each code block to the `layer_idx' value and it also
    sets the `makeup_passes' value to reflect any additional coding passes
    which can be included to make up the final rate. */

{
  int comp_idx, n, b, m, actual_bytes;
  level_info_ptr lev;
  band_info_ptr band;
  block_info_ptr block;
  std_int min_rd_threshold, rd_threshold;

  if (layer_idx > 0)
    { /* Start by saving the state of the tag trees. */
      for (comp_idx=0; comp_idx < self->num_components; comp_idx++)
        for (lev=self->components[comp_idx].levels,
             n=self->num_levels; n >= 0; n--, lev++)
          for (b=lev->min_band; b <= lev->max_band; b++)
            {
              band = lev->bands + b;
              band->byte_count_bits_copy = band->byte_count_bits;
              tag_tree__copy(band->inclusion_tree,band->inclusion_tree_copy);
              tag_tree__copy(band->insignificant_msbs_tree,
                             band->insignificant_msbs_tree_copy);
              for (block=band->blocks, m=band->band_blocks;
                   m > 0; m--, block++)
                block->old_passes = block->num_passes;
            }
    }

  /* Estimate `min_rd_threshold' from summary information collected during
     compression. */

  for (n=30; n > 0; n--)
    if (self->master.slope_rates[n] >= max_cumulative_bytes)
      break;
  min_rd_threshold = (std_int)(1<<n);
  if (min_rd_threshold >= max_rd_threshold)
    min_rd_threshold = (min_rd_threshold+1)>>1;

  /* Now for the main iterative loop. */

  rd_threshold = (min_rd_threshold+max_rd_threshold+1)>>1;
  if (rd_threshold > (min_rd_threshold<<1))
    rd_threshold = (min_rd_threshold<<1);
  do {
    actual_bytes = previous_cumulative_bytes;
    for (n=0; n <= self->num_levels; n++)
      for (comp_idx=0; comp_idx < self->num_components; comp_idx++)
        {
          lev = self->components[comp_idx].levels + n;
          if (lev->min_band <= lev->max_band)
            actual_bytes +=
              form_bitstream_layer(lev,rd_threshold,NULL,layer_idx,0,tags);
        }
    if (actual_bytes > max_cumulative_bytes)
      min_rd_threshold = rd_threshold;
    else
      max_rd_threshold = rd_threshold;
    rd_threshold = (min_rd_threshold + max_rd_threshold + 1)>>1;
    if (layer_idx > 0)
      { /* Finish up by restoring the state to that of the previous layer. */
        for (comp_idx=0; comp_idx < self->num_components; comp_idx++)
          for (lev=self->components[comp_idx].levels,
               n=self->num_levels; n >= 0; n--, lev++)
            for (b=lev->min_band; b <= lev->max_band; b++)
              {
                band = lev->bands + b;
                band->byte_count_bits = band->byte_count_bits_copy;
                tag_tree__copy(band->inclusion_tree_copy,band->inclusion_tree);
                tag_tree__copy(band->insignificant_msbs_tree_copy,
                               band->insignificant_msbs_tree);
                for (block=band->blocks, m=band->band_blocks;
                     m > 0; m--, block++)
                  block->num_passes = block->old_passes;
              }
      }
  } while (rd_threshold < max_rd_threshold);

  if (include_makeup_passes)
    {
      int remaining_bytes, new_bytes;

      /* Set up the pass counts for the `rd_threshold' being returned. */

      actual_bytes = previous_cumulative_bytes;
      for (n=0; n <= self->num_levels; n++)
        for (comp_idx=0; comp_idx < self->num_components; comp_idx++)
          {
            lev = self->components[comp_idx].levels + n;
            if (lev->min_band <= lev->max_band)
              actual_bytes +=
                form_bitstream_layer(lev,rd_threshold,NULL,layer_idx,0,tags);
          }

      /* Add makeup passes to absorb any remaining spare bytes. */

      remaining_bytes = max_cumulative_bytes - actual_bytes;
      assert(remaining_bytes >= 0);
      while (remaining_bytes > 0)
        {
          new_bytes = add_best_makeup_pass(self,layer_idx,remaining_bytes);
          if (new_bytes == 0)
            break;
          remaining_bytes -= new_bytes;
        }

      /* Finish up by restoring the state to that of the previous layer. */

      for (comp_idx=0; comp_idx < self->num_components; comp_idx++)
        for (lev=self->components[comp_idx].levels,
             n=self->num_levels; n >= 0; n--, lev++)
          for (b=lev->min_band; b <= lev->max_band; b++)
            {
              band = lev->bands + b;
              band->byte_count_bits = band->byte_count_bits_copy;
              tag_tree__copy(band->inclusion_tree_copy,band->inclusion_tree);
              tag_tree__copy(band->insignificant_msbs_tree_copy,
                             band->insignificant_msbs_tree);
              for (block=band->blocks, m=band->band_blocks;
                   m > 0; m--, block++)
                block->num_passes = block->old_passes;
            }
    }
  return(rd_threshold);
}

/* ========================================================================= */
/* --------------------------- Threshold Estimation ------------------------ */
/* ========================================================================= */

/*****************************************************************************/
/* STATIC                    estimate_layer_threshold                        */
/*****************************************************************************/

static std_int
  estimate_layer_threshold(int target_bytes, std_int *slope_rates,
                           bitstream_layer_info_ptr info)

 /* This function attempts to estimate a rate-distortion threshold which will
    achieve a target number of code bytes close to the supplied `target_bytes'
    value.  It uses information of two types in order to do this.  First,
    the `slope_rates' array contains summary information collected while
    encoding the code blocks (see definition of `block_master' in
    "ebcot_encoder.h" for more information on this).  Secondly, the `info'
    structure contains the rate-distortion threshold and the actual number
    of bytes written to the bit-stream up to and including the last generated
    bit-stream layer. */

{
  int n1, n2;
  double t1, t2, r1, r2, r, t, offset;

  /* Find the smallest index into the `slope_rates' table which yields a
     larger threshold than that used in the last layer. */

  for (n1=29; (n1 >= 0) && ((1<<n1) >= info->rd_threshold); n1--);
  n1++;

  /* Use this point to estimate the offset (in the log-domain) between the
     actual bit-rate and the interpolator estimated bit-rates, where the
     interpolator is taken from `n1' to `n1'-1. */

  if (n1 == 0)
    n1++;
  n2 = n1-1;
  t1 = (double)(1<<n1); r1 = (double)(slope_rates[n1]);
  t2 = (double)(1<<n2); r2 = (double)(slope_rates[n2]);
  r = (double)(info->actual_cumulative_bytes);
  t = (double)(info->rd_threshold);
  if (r1 == 0.0) /* Take care of pathological cases. */
    { r1 += 1.0 + r2; r += 1.0 + r2; r2 += 1.0 + r2; }
  t1 = log(t1); t2 = log(t2); t = log(t);
  r1 = log(r1); r2 = log(r2); r = log(r);
  offset = r - (r1 + (t-t1)*(r2-r1)/(t2-t1));

  /* Now use the offset to correct the target bit-rate. */

  r = (double) target_bytes;
  r = log(r) - offset;
  target_bytes = (int) exp(r);

  /* Now find the two adjacent indices into the `slope_rates' table whose
     rates are closest to the target bit-rate. */

  for (n2=n1; n2 >= 0; n2--)
    if (slope_rates[n2] > target_bytes)
      break;
  if (n2 == 30)
    n2 = 29;
  n1 = n2+1;

  /* Finally, use linear interpolation to estimate the rate-distortion
     threshold. */

  t1 = (double)(1<<n1); r1 = (double)(slope_rates[n1]);
  t2 = (double)(1<<n2); r2 = (double)(slope_rates[n2]);
  if (r1 == 0.0) /* Take care of pathological cases. */
    { r1 += 1.0 + r2; r += 1.0 + r2; r2 += 1.0 + r2; }
  if (r2 == r1)
    r2 += 1.0;
  t1 = log(t1); t2 = log(t2); r1 = log(r1); r2 = log(r2);
  t = t1 + (r-r1)*(t2-t1)/(r2-r1);
  t = exp(t);
  return((std_int) t);
}

/* ========================================================================= */
/* ---------------------------- Start and Finish --------------------------- */
/* ========================================================================= */

/*****************************************************************************/
/* STATIC                   start_bitstream_creation                         */
/*****************************************************************************/

static void
  start_bitstream_creation(the_encoder_ref self)
{
  level_info_ptr lev;
  band_info_ptr band;
  int comp_idx, n, b;

  for (comp_idx=0; comp_idx < self->num_components; comp_idx++)
    for (lev=self->components[comp_idx].levels,
          n=0; n <= self->num_levels; n++, lev++)
      for (b=lev->min_band; b <= lev->max_band; b++)
        {
          band = lev->bands + b;
          band->inclusion_tree =
            create_tag_tree(band->blocks_high,band->blocks_wide);
          band->insignificant_msbs_tree =
            create_tag_tree(band->blocks_high,band->blocks_wide);
          band->inclusion_tree_copy =
            create_tag_tree(band->blocks_high,band->blocks_wide);
          band->insignificant_msbs_tree_copy =
            create_tag_tree(band->blocks_high,band->blocks_wide);
        }
}

/*****************************************************************************/
/* STATIC                  finish_bitstream_creation                         */
/*****************************************************************************/

static void
  finish_bitstream_creation(the_encoder_ref self)
{
  level_info_ptr lev;
  band_info_ptr band;
  int comp_idx, n, b;

  for (comp_idx=0; comp_idx < self->num_components; comp_idx++)
    for (lev=self->components[comp_idx].levels,
          n=0; n <= self->num_levels; n++, lev++)
      for (b=lev->min_band; b <= lev->max_band; b++)
        {
          band = lev->bands + b;
          local_free(band->inclusion_tree);
          local_free(band->insignificant_msbs_tree);
          local_free(band->inclusion_tree_copy);
          local_free(band->insignificant_msbs_tree_copy);
        }
}

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

/*****************************************************************************/
/* EXTERN                      ebcot_send_bit_stream                         */
/*****************************************************************************/

void
  ebcot_send_bit_stream(the_encoder_ref self)
{
  std_int rd_threshold;
  int comp_idx, layer_idx, max_bytes, actual_bytes, n, include_makeup_passes;
  bitstream_layer_info_ptr info;
  level_info_ptr lev;
  tag_buffer_ptr tags;
  bitstream_sink_ref output;

  start_bitstream_creation(self);
  tags = create_tag_buffer();
  rd_threshold = 1<<30;
  info = self->layer_info;
  output = self->output;
  if ((self->profile & PROFILE__RESOLUTION_PROGRESSIVE) &&
      (self->bitstream_layers > 1))
    output = NULL; /* Cannot generate the bit-stream at the same time as
                      estimating RD thresholds. */
  actual_bytes = 0;
  for (layer_idx=0; layer_idx < self->bitstream_layers; layer_idx++, info++)
    {
      include_makeup_passes = (layer_idx==(self->bitstream_layers-1));
      max_bytes = info->max_cumulative_bytes;
      if (info->optimize)
        rd_threshold =
          optimize_bitstream_layer(self,layer_idx,rd_threshold,tags,
                                   max_bytes,actual_bytes,
                                   include_makeup_passes);
      else
        {
          assert(layer_idx > 0);
          rd_threshold =
            estimate_layer_threshold(max_bytes,self->master.slope_rates,
                                     info-1);
        }
      for (n=0; n <= self->num_levels; n++)
        for (comp_idx=0; comp_idx < self->num_components; comp_idx++)
          {
            lev = self->components[comp_idx].levels + n;
            if (lev->min_band <= lev->max_band)
              actual_bytes +=
                form_bitstream_layer(lev,rd_threshold,output,layer_idx,
                                     include_makeup_passes,tags);
          }
      info->rd_threshold = rd_threshold;
      info->actual_cumulative_bytes = actual_bytes;
    }

  /* The bit-stream might not yet have been generated. */

  if (output == NULL)
    {
      assert(self->profile & PROFILE__RESOLUTION_PROGRESSIVE);
      output = self->output;
      actual_bytes = 0;
      for (n=0; n <= self->num_levels; n++)
        for (comp_idx=0; comp_idx < self->num_components; comp_idx++)
          {
            lev = self->components[comp_idx].levels + n;
            if (lev->min_band <= lev->max_band)
              for (info=self->layer_info, layer_idx=0;
                   layer_idx < self->bitstream_layers; layer_idx++, info++)
                {
                  include_makeup_passes =
                    (layer_idx==(self->bitstream_layers-1));
                  rd_threshold = info->rd_threshold;
                  actual_bytes +=
                    form_bitstream_layer(lev,rd_threshold,output,layer_idx,
                                         include_makeup_passes,tags);
                }
          }
    }

  tag_buffer__destroy(tags);
  finish_bitstream_creation(self);
}

⌨️ 快捷键说明

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