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

📄 ebcot_send_bits.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                  tmp_prev_bytes += signal_bytes;
                  tmp_extra_passes -= k;
                  tmp_first_new_pass += k;
                  for (num_bits=block->byte_count_bits; k > 1; k>>=1)
                    num_bits++;
                  while (signal_bytes >= (1<<num_bits))
                    {
                      num_bits++;
                      block->byte_count_bits++;
                      tag_buffer__push_bit(tags,1);
                    }
                  if (num_bits > 16)
                    local_error("Too many code bytes in a single bit-stream "
                                "layer for one or more blocks!  Use smaller "
                                "code blocks or more layers (SNR "
                                "progressive)!");
                }
              tag_buffer__push_bit(tags,0);
            }

            /* Generate tag information for the number of bytes between
               successive termination and/or truncation points within
               this new number of passes. */

            while (extra_passes > 0)
              {
                int signal_bytes, num_bits;

                for (k=0; k < (extra_passes-1); k++)
                  if (block->passes[first_new_pass+k].terminated)
                    break;
                signal_bytes =
                  block->passes[first_new_pass+k].cumulative_bytes-prev_bytes;
                k++; /* Get number of new passes covered by length. */
                prev_bytes += signal_bytes;
                extra_passes -= k;
                first_new_pass += k;
                for (num_bits=block->byte_count_bits; k > 1; k>>=1)
                  num_bits++;
                assert (signal_bytes < (1<<num_bits));
                tag_buffer__push_bits(tags,signal_bytes,num_bits);
              }
          }
    }

  head_bytes = tag_buffer__flush(tags);
  stream->start_packet(stream,layer_idx,head_bytes,body_bytes,body_parts,
                       simulation);
  tag_buffer__output(tags,stream);

  /* Now send the code bytes themselves, for each block for which
     information is being included. */

  for (b=precinct->min_band; b <= precinct->max_band; b++)
    {
      pband = precinct->bands + b;
      if (!pband->valid_band)
        continue;
      for (pos=0, bpp=pband->blocks,
           r=pband->blocks_high; r > 0; r--, bpp += pband->block_row_gap)
        for (block=bpp, c=pband->blocks_wide; c > 0; c--, block++, pos++)
          {
            int offset, remaining;
            dst_heap_unit_ptr heap;
            std_byte *buf;

            if (block->num_passes <= block->old_passes)
              continue;
            block_bytes = block->passes[block->num_passes-1].cumulative_bytes;
            offset = 0;
            if ((k=block->old_passes) > 0)
              offset = block->passes[k-1].cumulative_bytes;
            block_bytes -= offset;
            assert(block_bytes > 0);
            heap = block->first_unit;
            remaining = (DST_HEAP_WORDS - block->first_pos) << 2;
            buf = ((std_byte *) heap->words) + DST_HEAP_BYTES - remaining;
            while (offset > 0)
              {
                if (remaining >= offset)
                  {
                    buf += offset;
                    remaining -= offset;
                    offset = 0;
                  }
                else
                  {
                    offset -= remaining;
                    heap = heap->next;
                    remaining = DST_HEAP_BYTES;
                    buf = (std_byte *)(heap->words);
                  }
              }
            while (block_bytes > 0)
              {
                if (remaining >= block_bytes)
                  {
                    stream->push_body_bytes(stream,buf,block_bytes);
                    block_bytes = 0;
                  }
                else
                  {
                    stream->push_body_bytes(stream,buf,remaining);
                    block_bytes -= remaining;
                    heap = heap->next;
                    remaining = DST_HEAP_BYTES;
                    buf = (std_byte *)(heap->words);
                  }
              }
          }
    }

  packet_bytes = stream->end_packet(stream);
  return(packet_bytes);
}

/*****************************************************************************/
/* STATIC                    optimize_bitstream_layer                        */
/*****************************************************************************/

static rd_slope_type
  optimize_bitstream_layer(ebcot_encoder_ref self, stream_out_ref stream,
                           int layer_idx, rd_slope_type max_rd_threshold,
                           tag_buffer_ptr tags, int max_cumulative_bytes,
                           int previous_cumulative_bytes)

 /* This function implements the rate-distortion optimization algorithm.
    It saves the state of any previously generated quality 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_packet' directly with this threshold
    to actually generate the packets which constitute 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.  The `stream' object must be supplied, because the
    actual size of a packet can only be reliably computed with the aid
    of its interface functions, since additional error correction and/or
    detection codes may be added at the bit-stream level. */

{
  int tnum, tpart, c, n, b, p, actual_bytes;
  ebcot_tile_ptr tile;
  ebcot_component_info_ptr comp_info;
  ebcot_level_info_ptr lev;
  ebcot_band_info_ptr band;
  ebcot_precinct_info_ptr precinct;
  ebcot_precinct_band_info_ptr pband;
  ebcot_block_info_ptr block;
  rd_slope_type min_rd_threshold, rd_threshold;
  std_short max_exponent, exponent;

  
  std_int  max_mantissa; /* added by W. Zeng, for vpw fix  */

  if (layer_idx > 0)
    { /* Start by saving the state of the tag trees. */
      for (tnum=0; tnum < self->num_tiles; 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;
                        }
                    }
                }
            }
        }
    }

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

  max_exponent = (1<<RD_SLOPE_EXPONENT_BITS) - 1;
  /* Begin W. Zeng vpw fix */
  if (self->vpw_info == NULL)
    {
      for (exponent=max_exponent; exponent > 0; exponent--)
        if (self->rd_slope_rates[exponent] >= max_cumulative_bytes)
          break;
      min_rd_threshold = exponent << RD_SLOPE_MANTISSA_BITS;
      if ((min_rd_threshold >= max_rd_threshold) && (exponent > 0))
        {
          exponent--;
          min_rd_threshold = exponent << RD_SLOPE_MANTISSA_BITS;
        }
    }
  else
    { /**** using vpw ****/
      max_mantissa = (1<<RD_SLOPE_MANTISSA_BITS) - 1;
      max_rd_threshold = (max_exponent << RD_SLOPE_MANTISSA_BITS) + 
                         max_mantissa;
      min_rd_threshold= 0;
    }
  /* End W. Zeng vpw fix */

  /* 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_cumulative_bytes;
    for (tnum=0; tnum < self->num_tiles; tnum++)
      {
        tile = self->tiles + tnum;
        if (layer_idx == 0)
          for (tpart=0; tpart < tile->num_tparts; tpart++)
            actual_bytes +=
              stream->write_tpart_header(stream,tnum,tile->num_tparts,
                                         tpart,1,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 (p=0; p < lev->total_precincts; p++)
                  {
                    precinct = lev->precincts + p;
                    actual_bytes +=
                      form_packet(precinct,rd_threshold,stream,1,
                                  layer_idx,tags);
                  }
              }
          }
      }
    if (actual_bytes > max_cumulative_bytes)
      min_rd_threshold = rd_threshold;
    else
      max_rd_threshold = rd_threshold;
    rd_threshold = (rd_slope_type)
      ((((std_int) min_rd_threshold) + ((std_int) max_rd_threshold) + 1) >> 1);
    if (layer_idx > 0)
      { /* Finish up by restoring the state to that of the previous layer. */
        for (tnum=0; tnum < self->num_tiles; 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 begin */
/*****************************************************************************/
/* STATIC                    set_buffer_threshold                            */
/*****************************************************************************/

static rd_slope_type
  set_buffer_threshold(ebcot_encoder_ref self, stream_out_ref stream,
                       int layer_idx, rd_slope_type max_rd_threshold,
                       tag_buffer_ptr tags,
                       int max_buffer_size_bytes,
                       int previous_buffer_size_bytes,

⌨️ 快捷键说明

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