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

📄 ebcot_send_bits.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    src++; dest++;
    dest->value = src->value;
    dest->lower_bound = src->lower_bound;
    dest->value_known = src->value_known;
  } while (src->parent != NULL);
  assert(dest->parent == NULL);
}

/*****************************************************************************/
/* STATIC                       tag_tree__encode                             */
/*****************************************************************************/

static int
  tag_tree__encode(tag_tree_node_ptr leaf, int threshold,
                   tag_buffer_ptr target)

 /* Encodes whether or not the `leaf' node's value is less than the supplied
    threshold.  In the process, values which are less than the threshold are
    explicitly coded.  Returns 1 if the value is less than the threshold and
    0 otherwise.  Encoded bits are pushed into the `target' tag stream
    manager, which collects the tag codes into bytes for outputting as
    a single block of tags later on. */

{
  tag_tree_node_ptr node;
  int lower_bound, result;

  assert(threshold > 0);
  result = 1; /* Prevent compiler warnings. */
  for (node=leaf; node->parent != NULL; node=node->parent)
    node->parent->child = node;
  for (lower_bound=0; node != NULL; node=node->child)
    {
      if (lower_bound > node->lower_bound)
        node->lower_bound = lower_bound;
      else
        lower_bound = node->lower_bound;
      assert(lower_bound <= node->value);
      while ((lower_bound < threshold) && (lower_bound < node->value))
        {
          tag_buffer__push_bit(target,0);
          lower_bound++;
        }
      result = lower_bound < threshold;
      if (result && !node->value_known)
        {
          tag_buffer__push_bit(target,1);
          node->value_known = 1;
        }
      node->lower_bound = lower_bound;
    }
  assert((result && (leaf->value < threshold)) ||
         ((!result) && (leaf->value >= threshold)));
  return(result);
}

/* ========================================================================= */
/* -------------------------- Layer/Packet Creation ------------------------ */
/* ========================================================================= */

/*****************************************************************************/
/* STATIC                  apply_weight_to_rd_threshold                      */
/*****************************************************************************/

static rd_slope_type
  apply_weight_to_rd_threshold(rd_slope_type threshold, float weight)

 /* This function effectively divides the RD-Slope threshold by the
    supplied `weight'.  Note, however, that the slope thresholds have
    a pseudo-logarithmic representation, so that the division operation
    is not entirely trivial. */

{
  std_short exponent, mantissa;
  float mant;

#define RD_MANT_OFFSET ((float)(1<<RD_SLOPE_MANTISSA_BITS))
#define RD_MANT_LIMIT (2.0F*RD_MANT_OFFSET)
#define MAX_RD_EXPONENT ((std_short)(1<<RD_SLOPE_EXPONENT_BITS)-1)
#define MAX_RD_MANTISSA ((std_short)(1<<RD_SLOPE_MANTISSA_BITS)-1)

  if (weight == 0.0F)
    return((MAX_RD_EXPONENT<<RD_SLOPE_MANTISSA_BITS) | MAX_RD_MANTISSA);
  if (threshold <= 0)
    return(threshold);
  exponent = (std_short)(threshold >> RD_SLOPE_MANTISSA_BITS);
  mantissa = (threshold & (std_short)(~((-1)<<RD_SLOPE_MANTISSA_BITS)));
  for (; weight > 1.0F; weight *= 0.5F)
    exponent--;

  mant = (RD_MANT_OFFSET + (float) mantissa) / weight;
  for (; mant >= RD_MANT_LIMIT; mant *= 0.5F)
    exponent++;
  if (exponent < 0)
    return(1); /* Smallest legal RD slope value. */
  if (exponent > MAX_RD_EXPONENT)
    {
      exponent = MAX_RD_EXPONENT;
      mantissa = MAX_RD_MANTISSA;
    }
  else
    {
      mantissa = (std_short)(mant-RD_MANT_OFFSET);
      if (mantissa > MAX_RD_MANTISSA)
        mantissa = MAX_RD_MANTISSA;
    }
  threshold = (rd_slope_type)
    ((exponent<<RD_SLOPE_MANTISSA_BITS) + mantissa);
  return(threshold);
}

/*****************************************************************************/
/* STATIC                         form_packet                                */
/*****************************************************************************/

static int
  form_packet(ebcot_precinct_info_ptr precinct, rd_slope_type rd_threshold,
              stream_out_ref stream, int simulation, int layer_idx,
              tag_buffer_ptr tags)

 /* This function forms a new layer in the bit-stream, composed of all
    coding passes from all code-blocks which fall within the scope of the
    supplied precinct, whose `rd_slope' value is greater than or equal to the
    `rd_threshold' value, and which have not already been included in a
    previous layer.  From the perspective of the `stream' object, the entity
    formed here is known as a "packet".
        If `simulation' is zero, the bit-stream formed in this way will
    be immediately pushed out to the supplied `stream' object.  Otherwise, if
    `simulation' is non-zero, nothing will be output, and the packet formation
    process will be simulated.  In either event, the `stream' object is
    used to determine the actual size of the packet, which can exceed the
    total number of bytes actually pushed into the packet, due to the
    inclusion of resync and other markers, over which we have no control
    here.
        `layer_idx' identifies the layer within the bit-stream for which
    a packet is being formed here.  The first layer should always have a
    `layer_idx' value of 0, which causes appropriate initialization steps
    to be applied.  Thereafter, the indices must increase consecutively.  The
    `layer_idx' value is used with each band-tile's inclusion tag tree in an
    interesting and elegant manner to implement an efficient coding of the
    point at which information from any given block is first included in the
    bit-stream.
        The `tags' argument supplies a `tag_buffer' object which is
    used to manage the buffering of tag bits for the packet head, during
    the packet formation process.
        The function returns the actual number of bytes which are required
    to represent the packet, regardless of whether the `simulation' flag
    is zero or non-zero.  Simulation by the `stream_out' object is required
    to be accurate to the byte!  Failure to achieve this may result in
    a cascade of problems. */

{
  ebcot_precinct_band_info_ptr pband;
  ebcot_block_info_ptr block, bpp;
  int b, r, c, k, pos, tag_val;
  int first_new_pass, prev_bytes, extra_passes, block_bytes;
  int packet_bytes, body_bytes, head_bytes, body_parts;
  rd_slope_type wtd_rd_threshold;

  body_bytes = body_parts = 0;
  tag_buffer__reset(tags);

  if (precinct->level_idx == 4)
    body_bytes = 0;

  tag_buffer__push_bit(tags,1); /* Indicates that the packet is non-empty. */
  for (b=precinct->min_band; b <= precinct->max_band; b++)
    {
      pband = precinct->bands + b;
      if (!pband->valid_band)
        continue;
      if (pband->total_blocks == 0)
        continue; /* Empty precinct for this subband. */
      if (pband->band->vpw_weight >= 0.0F) /* David T VPW fix. */
        wtd_rd_threshold =
          apply_weight_to_rd_threshold(rd_threshold,pband->band->vpw_weight);
      else
        wtd_rd_threshold = rd_threshold;
      body_parts += pband->total_blocks;
      if (layer_idx == 0)
        { /* Initialize for first layer. */
          for (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++)
              block->byte_count_bits = 3;
          tag_tree__reset(pband->inclusion_tree);
          tag_tree__reset(pband->insignificant_msbs_tree);
        }

      /* Next, determine the number of coding passes to include in
         this packet for every code block subband and update
         the tag trees, as necessary. */

      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++)
          {
            if (layer_idx == 0)
              {
                tag_tree__set_value(pband->insignificant_msbs_tree+pos,
                                    block->insignificant_msbs);
                block->old_passes = block->num_passes = 0;
              }
            else
              block->old_passes = block->num_passes;
            for (k=block->old_passes; k < block->max_passes; k++)
              {
                rd_slope_type rd;

                if ((rd = block->passes[k].rd_slope) <= 0)
                  continue;
                if (rd >= wtd_rd_threshold)
                  block->num_passes = k+1;
                else
                  break;
              }
            if (block->num_passes && !block->old_passes) /* First inclusion. */
              tag_tree__set_value(pband->inclusion_tree+pos,layer_idx);
          }

      /* Now generate all tag information for the subband. */

      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++)
          {
            /* Generate inclusion information. */

            extra_passes = block->num_passes - block->old_passes;
            if (block->old_passes == 0)
              { /* Not previously included. */
                tag_tree__encode(pband->inclusion_tree+pos,layer_idx+1,tags);
              }
            else
              { /* Block has already been included in a previous layer. */
                int inclusion_bit;

                inclusion_bit = (extra_passes == 0)?0:1;
                tag_buffer__push_bit(tags,inclusion_bit);
              }
            if (extra_passes == 0)
              continue;

            /* Generate `insignificant_msbs' information, if necessary. */
            
            if (block->old_passes == 0)
              {
                k = 1;
                while (!tag_tree__encode(pband->insignificant_msbs_tree+pos,k,
                                         tags))
                  k++;
              }
          
            /* Now determine the number of new passes. */

            if (block->old_passes == 0)
              {
                first_new_pass = block->insignificant_msbs*PASSES_PER_BITPLANE;
                prev_bytes = 0;
                extra_passes -= first_new_pass;
              }
            else
              {
                first_new_pass = block->old_passes;
                prev_bytes = block->passes[first_new_pass-1].cumulative_bytes;
              }
            block_bytes =
              block->passes[block->num_passes-1].cumulative_bytes - prev_bytes;
            assert((extra_passes >= 1) && (block_bytes > 0));
            body_bytes += block_bytes;

            /* Generate tag information for the number of new passes. */

            k = extra_passes - 1;
            tag_val = (k > 0)?1:0;
            tag_buffer__push_bit(tags,tag_val);
            if (tag_val)
              {
                k -= tag_val;
                tag_val = (k > 0)?1:0;
                tag_buffer__push_bit(tags,tag_val);
                if (tag_val)
                  {
                    k -= tag_val;
                    tag_val = (k > 2)?3:k;
                    tag_buffer__push_bits(tags,tag_val,2);
                    if (tag_val==3)
                      {
                        k -= tag_val;
                        tag_val = (k > 31)?31:k;
                        tag_buffer__push_bits(tags,tag_val,5);
                        if (tag_val==31)
                          {
                            k -= tag_val;
                            tag_val = k;
                            assert(tag_val < 128);
                            tag_buffer__push_bits(tags,tag_val,7);
                          }
                      }
                  }
              }

            /* First run the code which increments beta to a suitable
               value first. */

            {
              int tmp_extra_passes = extra_passes;
              int tmp_first_new_pass = first_new_pass;
              int tmp_prev_bytes = prev_bytes;

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

                  for (k=0; k < (tmp_extra_passes-1); k++)
                    if (block->passes[tmp_first_new_pass+k].terminated)
                      break;
                  signal_bytes =
                    block->passes[tmp_first_new_pass+k].cumulative_bytes -
                      tmp_prev_bytes;
                  k++; /* Get number of new passes covered by length. */

⌨️ 快捷键说明

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