ebcot_send_bits.c

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

C
1,604
字号
                       int tnum_start, int tnum_end,
                       int pnum_start, int pnum_end,
                       int last_tnum_header_written)

 /* This function helps implement a reduced memory buffer by determining a
    rate-distortion slope threshold to use in truncating bit-plane passes from
    entropy encoded quantized indices.  The method for determining which passes
    to truncate is based on the optimize_bitstream_layer() routine.  The main 
    iterative loop is still the same, but the element_idx start and end 
    parameters for this routine specify a window of elements which should be 
    included in the reduced memory buffer. */

{
  ebcot_tile_ptr tile;
  ebcot_component_info_ptr comp_info;
  ebcot_level_info_ptr lev;
  ebcot_precinct_info_ptr precinct;
  ebcot_precinct_band_info_ptr pband;
  ebcot_band_info_ptr band;
  ebcot_block_info_ptr block;
  ebcot_sequence_ptr seq;
  rd_slope_type min_rd_threshold, rd_threshold;
  int c, n, b, p;
  int tnum, pnum_end2;
  int actual_bytes;

  min_rd_threshold = 0;

  /* Start by saving the state of the tag trees. */
  if (layer_idx != 0)
    { /* Start by saving the state of the tag trees. */
      for (tnum=tnum_start; tnum <= tnum_end; tnum++)
        {
          tile = self->tiles + tnum;
          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 (p=0; p < lev->total_precincts; p++)
                    {
                      precinct = lev->precincts + p;
                      for (b=precinct->min_band; b <= precinct->max_band; b++)
                        {
                          pband = precinct->bands + b;
                          if (!pband->valid_band)
                            continue;
                          tag_tree__copy(pband->inclusion_tree,
                                         pband->inclusion_tree_copy);
                          tag_tree__copy(pband->insignificant_msbs_tree,
                                         pband->insignificant_msbs_tree_copy);
                        }
                    }
                  for (b=lev->min_band; b <= lev->max_band; b++)
                    {
                      band = lev->bands + b;
                      if (!band->valid_band)
                        continue;
                      for (block=band->blocks,
                           p=band->total_blocks; p > 0; p--, block++)
                        {
                          block->old_passes = block->num_passes;
                          block->old_byte_count_bits = block->byte_count_bits;
                        }
                    }
                }
            }
        }
    }

  /* Now for the main iterative loop. */

  rd_threshold = (rd_slope_type)
    ((((std_int) min_rd_threshold) + ((std_int) max_rd_threshold) + 1) >> 1);
  do {
    actual_bytes = previous_buffer_size_bytes;
    for (tnum = tnum_start; tnum <= tnum_end; tnum++) {
      tile = self->tiles + tnum;
      pnum_end2 = pnum_end;
      if (tnum < tnum_end)
        pnum_end2 = tile->total_packets - 1;
      if ((tnum > last_tnum_header_written) && (layer_idx == 0))
        {
          int tpart;

          for (tpart=0; tpart < tile->num_tparts; tpart++)
            actual_bytes +=
              stream->write_tpart_header(stream,tnum,tile->num_tparts,
                                         tpart,1,0);
        }
      for (p=pnum_start; p <= pnum_end2; p++) {
        seq = tile->packet_sequence + p;
        if (seq->layer_idx != layer_idx)
          continue;
        precinct = seq->precinct;
        actual_bytes +=
          form_packet(precinct,rd_threshold,stream,1,layer_idx,tags);
      }
    }
    if (actual_bytes > max_buffer_size_bytes)
      min_rd_threshold = rd_threshold;
    else
      max_rd_threshold = rd_threshold;

    /* Avoid potential infinite loop if min_rd_threshold is too large */
    /* Not sure this is actually needed. */
    if (min_rd_threshold == max_rd_threshold) min_rd_threshold >>= 1;

    rd_threshold = (rd_slope_type)
      ((((std_int) min_rd_threshold) + ((std_int) max_rd_threshold) + 1) >> 1);

    /* Finish up by restoring the state to that of the previous layer. */
    if (layer_idx != 0) {
      for (tnum=tnum_start; tnum <= tnum_end; tnum++) {
        tile = self->tiles + tnum;
        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 (p=0; p < lev->total_precincts; p++) {
              precinct = lev->precincts + p;
              for (b=precinct->min_band; b <= precinct->max_band; b++) {
                pband = precinct->bands + b;
                if (!pband->valid_band)
                  continue;
                tag_tree__copy(pband->inclusion_tree_copy,
                               pband->inclusion_tree);
                tag_tree__copy(pband->insignificant_msbs_tree_copy,
                               pband->insignificant_msbs_tree);
              }
            }
            for (b=lev->min_band; b <= lev->max_band; b++) {
              band = lev->bands + b;
              if (!band->valid_band)
                continue;
              for (block=band->blocks,
                   p=band->total_blocks; p > 0; p--, block++) {
                block->num_passes = block->old_passes;
                block->byte_count_bits=block->old_byte_count_bits;
              }
            }
          }
        }
      }
    }
  } while (rd_threshold < max_rd_threshold);

  return(rd_threshold);
}
/* CRIL Technology/SAIC Scan Buffer end */


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

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

static rd_slope_type
  estimate_layer_threshold(int target_bytes, std_int *rd_slope_rates,
                           ebcot_layer_info_ptr last_layer)

 /* 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 `rd_slope_rates' array contains summary information collected while
    encoding the code blocks (see definition of `ebcot_encoder' in
    "ebcot_encoder.h" for more information on this).  Secondly, the
    `last_layer' 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. */

{
  std_short max_exponent, max_mantissa, exponent, mantissa, n1, n2;
  rd_slope_type last_threshold;
  double t1, t2, r1, r2, r, t;

  max_exponent = (1<<RD_SLOPE_EXPONENT_BITS) - 1;
  max_mantissa = (1<<RD_SLOPE_MANTISSA_BITS) - 1;

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

  last_threshold = last_layer->rd_threshold;
  for (n1=max_exponent-1;
       (n1 >= 0) && ((n1<<RD_SLOPE_MANTISSA_BITS) >= last_threshold);
       n1--);
  n1++;
  n2 = n1-1;
  /* Begin David T fix. */
  if ((n2 >= 0) && (rd_slope_rates[n1] != rd_slope_rates[n2]))
    { /* Can hope for a reasonable estimate of the error due to linear
	     interpolation.  We will use this error to refine our estimates. */
      double offset;

      n2 = n1-1;
      r = (double)(last_layer->actual_cumulative_bytes);
      r1 = (double)(rd_slope_rates[n1]);
      r2 = (double)(rd_slope_rates[n2]);
      if (r1 == 0.0) /* Take care of pathological cases. */
        { r1 += 1.0 + r2; r += 1.0 + r2; r2 += 1.0 + r2; }
      r1 = log(r1); r2 = log(r2); r = log(r); /* log of all rates. */
      t1 = (double) n1; /* log_2 of first slope threshold. */
      t2 = (double) n2; /* log_2 of second slope threshold. */
      t = ((double)(last_threshold>>RD_SLOPE_MANTISSA_BITS)) +
        log(((double)(last_threshold & max_mantissa)) /
            ((double)(max_mantissa+1)) + 1.0) /
        log(2.0); /* log_2 of last slope threshold. */
      offset = r - (r1 + (t-t1)*(r2-r1)/(t2-t1));
      if (offset > 0.0)
        { /* Actual rate tends to be higher than that predicted from the
             `rd_slope_rates' table presumably as a result of overhead.
             Factor this overhead into a new lower target rate which does
             not include the overhead. */
          r = (double) target_bytes;
          r = log(r) - offset;
          target_bytes = (int) exp(r);
        }
    }
  /* End David T fix. */

  /* 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 (rd_slope_rates[n2] > target_bytes)
      break;
  if (n2 == max_exponent)
    n2 = max_exponent-1;
  n1 = n2+1;
  /* Begin David T fix. */
  if ((n2 < 0) || (rd_slope_rates[n1] == rd_slope_rates[n2]))
    return(n1<<RD_SLOPE_MANTISSA_BITS);
  /* End David T fix. */

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

  r = (double) target_bytes;
  r1 = (double)(rd_slope_rates[n1]);
  r2 = (double)(rd_slope_rates[n2]);
  if (r1 == 0.0) /* Take care of pathological cases. */
    { r1 += 1.0 + r2; r += 1.0 + r2; r2 += 1.0 + r2; }
  r1 = log(r1); r2 = log(r2); r = log(r); /* log of all rates. */

  t1 = (double) n1; /* log_2 of first slope threshold. */
  t2 = (double) n2; /* log_2 of second slope threshold. */
  t = t1 + (r-r1)*(t2-t1)/(r2-r1);

  /* Finally, convert back to an `rd_slope_type' representation. */

  exponent = (std_short) floor(t);
  t -= (double) exponent; /* This gives log_2(1+2^(-Mbits)*`mantissa'). */
  t = exp(t * log(2.0));
  t -= 1.0;
  t *= (double)(max_mantissa+1);
  mantissa = (std_short) floor(t+0.5);
  if (mantissa < 0)
    mantissa = 0;
  if (mantissa > max_mantissa)
    {
      assert(mantissa == (max_mantissa+1));
      mantissa = 0;
      exponent++;
    }
  assert((exponent >= 0) && (exponent <= max_exponent));
  return((exponent << RD_SLOPE_MANTISSA_BITS) + mantissa);
}

/* CRIL Technology/SAIC Scan Buffer begin */
/*****************************************************************************/
/* STATIC                     scan_element_filled                            */
/*****************************************************************************/

int scan_element_filled(ebcot_encoder_ref self)

 /* This function checks to see if enough coder blocks have been processed to
    fill up a scan element.  If not, 0 is returned.  If so, then this function
    checks to see if enough scan elements have been processed to fill up the
    reduced memory buffer.  If not, value 1 is returned.  If enough scan
    elements are available, value 2 is returned. */

{

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

  tile = self->tiles + self->current_tile_idx;
  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;
        if (band->scan_buffer_lines < band->max_scan_buffer_lines) {
          return(0);
        }
      }
    }
  }

  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->scan_buffer_lines -= band->max_scan_buffer_lines;
        if (self->buffer_end == (self->num_scan_elements - 2)) {
          band->max_scan_buffer_lines = band->dims.rows -
            (self->buffer_end + 1) * band->max_scan_buffer_lines;

⌨️ 快捷键说明

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