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

📄 ebcot_receive_bits.c

📁 JPEG2000 EBCOT算法源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    bit-stream might as well have terminated at the beginning of the
    layer.
        `layer_idx' identifies the layer within the bit-stream which is
    being retrieved 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 be strictly increasing.  The `layer_idx'
    value is used with each band'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 whose
    `tag_buffer__pull_bit' and `tag_buffer__pull_bits' functions should
    be used to recover tag bits associated with the layer. */

{
  int b, m, k, tag_val, new_passes, something_new;
  band_info_ptr band;
  block_info_ptr block;
  int actual_bytes;

  tag_buffer__reset(tags);
  if (layer_idx == 0)
    { /* Initialize various quantities. */
      level->bitstream_layers = 0;
      for (b=level->min_band; b <= level->max_band; b++)
        {
          band = level->bands + b;
          band->byte_count_bits = 3; /* Minimum number of bits for
                                        signalling byte counts. */
          tag_tree__reset(band->inclusion_tree);
          tag_tree__reset(band->insignificant_msbs_tree);
          for (block=band->blocks, m=0; m < band->band_blocks; m++, block++)
            {
              block->num_passes = 0;
              block->total_bytes = 0;
              block->new_passes = 0;
              block->insignificant_msbs = 0;
            }
        }
    }
  tag_buffer__pull_bit(tags,tag_val);
  if (!tag_val)
    return(1);

  for (b=level->min_band; b <= level->max_band; b++)
    {
      band = level->bands + b;
      something_new = 0;
      for (block=band->blocks, m=0; m < band->band_blocks; m++, block++)
        {
          /* Recover inclusion information. */

          if (block->num_passes == 0)
            { /* Not previously included. */
              tag_val =
                tag_tree__decode(band->inclusion_tree+m,layer_idx+1,tags);
            }
          else
            { /* Block has already been included in a previous layer. */
              tag_buffer__pull_bit(tags,tag_val);
            }
          if (!tag_val)
            continue;

          /* Recover `insignificant_msbs' information, if necessary. */

          if (block->num_passes == 0)
            {
              k = 1;
              while (!tag_tree__decode(band->insignificant_msbs_tree+m,k,tags))
                k++;
              block->insignificant_msbs = k-1;
            }

          /* Now recover information about the number of new passes. */

          if (block->num_passes == 0)
            new_passes = block->insignificant_msbs * PASSES_PER_BITPLANE + 1;
          else
            new_passes = 1;
          tag_buffer__pull_bit(tags,tag_val);
          if (tag_val)
            {
              new_passes++;
              tag_buffer__pull_bit(tags,tag_val);
              if (tag_val)
                {
                  new_passes++;
                  tag_val = tag_buffer__pull_bits(tags,2);
                  new_passes += tag_val;
                  if (tag_val == 3)
                    {
                      tag_val = tag_buffer__pull_bits(tags,5);
                      new_passes += tag_val;
                      if (tag_val == 31)
                        {
                          tag_val = tag_buffer__pull_bits(tags,7);
                          new_passes += tag_val;
                        }
                    }
                }
            }
          assert((block->num_passes+new_passes) <= block->max_passes);
          block->new_passes = new_passes;
          something_new = 1;
        }
      if (something_new)
        {
          int num_bits;

          /* Recover the number of bits which will be used to signal the
             number of new bytes for each included block. */

          num_bits = band->byte_count_bits;
          do {
            tag_buffer__pull_bit(tags,tag_val);
            num_bits++;
          } while (tag_val);
          num_bits--;
          band->byte_count_bits = num_bits;
          assert(num_bits <= 16);

          /* Recover the number of new bytes for each included block. */

          for (block=band->blocks, m=0; m < band->band_blocks; m++, block++)
            if ((new_passes=block->new_passes) > 0)
              {
                k = new_passes;
                if (block->num_passes == 0)
                  k -= block->insignificant_msbs * PASSES_PER_BITPLANE;
                for (num_bits=band->byte_count_bits; k > 1; k=(k+1)>>1)
                  num_bits++;
                tag_val = tag_buffer__pull_bits(tags,num_bits);
                k = block->num_passes;
                block->passes[k].num_bytes = (std_ushort) tag_val;
                block->passes[k].layer_idx = (std_ushort) layer_idx;
                for (new_passes--, k++; new_passes > 0; new_passes--, k++)
                  {
                    block->passes[k].num_bytes = 0;
                    block->passes[k].layer_idx = (std_ushort) layer_idx;
                  }
              }
        }
    }
  assert(level->bitstream_layers == layer_idx);
  level->layer_tag_bytes[layer_idx] = tags->retrieved_bytes;
  level->bitstream_layers = layer_idx + 1;

  /* Now go ahead and recover the code bytes themselves. */

  actual_bytes = tags->retrieved_bytes;
  for (b=level->min_band; b <= level->max_band; b++)
    {
      band = level->bands + b;
      for (block=band->blocks, m=0; m < band->band_blocks; m++, block++)
        if ((new_passes = block->new_passes) > 0)
          {
            std_byte *wp;
            heap_unit_ptr unit;
            int num_bytes, remaining_bytes;

            unit = block->first_unit;
            if (unit == NULL)
              { remaining_bytes = 0; wp = NULL; }
            else
              { remaining_bytes = HEAP_BYTES; wp = (std_byte *)(unit->words); }
            num_bytes = block->total_bytes; /* Must skip over these. */
            while (num_bytes > 0)
              {
                if (num_bytes > remaining_bytes)
                  {
                    unit = unit->next;
                    num_bytes -= remaining_bytes;
                    remaining_bytes = HEAP_BYTES;
                    wp = (std_byte *)(unit->words);
                  }
                else
                  {
                    wp += num_bytes;
                    remaining_bytes -= num_bytes;
                    num_bytes = 0;
                  }
              }
            tag_val = block->passes[block->num_passes].num_bytes;
            num_bytes = tag_val; /* Must read these in. */
            while (num_bytes > 0)
              {
                if (remaining_bytes == 0)
                  { /* Allocate new unit. */
                    if (unit == NULL)
                      block->first_unit = unit = code_mgr->get_unit(code_mgr);
                    else
                      unit = unit->next = code_mgr->get_unit(code_mgr);
                    unit->next = NULL;
                    remaining_bytes = HEAP_BYTES;
                    wp = (std_byte *)(unit->words);
                  }
                if (num_bytes > remaining_bytes)
                  {
                    if (input->pull_bytes(input,wp,remaining_bytes) <
                        remaining_bytes)
                      return(actual_bytes); /* End of bit-stream. */
                    num_bytes -= remaining_bytes;
                    remaining_bytes = 0;
                    wp = NULL;
                  }
                else
                  {
                    if (input->pull_bytes(input,wp,num_bytes) < num_bytes)
                      return(actual_bytes); /* End of bit-stream. */
                    wp += num_bytes;
                    remaining_bytes -= num_bytes;
                    num_bytes = 0;
                  }
              }
            block->total_bytes += tag_val;
            block->num_passes += new_passes;
            block->new_passes = 0;
            actual_bytes += tag_val;
          }
    }
  return(actual_bytes);
}

/*****************************************************************************/
/* STATIC                        parse_out_level                             */
/*****************************************************************************/

static int
  parse_out_level(level_info_ptr level, the_decoder_ref self)

 /* The purpose of this function is to simulate complete removal of the
    indicated resolution level from the bit-stream and to report the number
    of bytes which are saved in this way.  A resolution level might need
    to be removed from the bit-stream either because it belongs to an
    image component which is not required or because it contains subbands
    whose frequencies exceed the desired reconstruction resolution.  In
    the former case, all subbands are completely removed from the level.
    If the level contains the DC subband and belongs to an included
    image component, however, then only the three AC subbands are removed. */

{
  int stripped_bytes;
  int remove_dc, k, b, m;
  band_info_ptr band;
  block_info_ptr block;
  heap_unit_ptr tmp;

  remove_dc = (level->component_idx >= self->max_components);
  stripped_bytes = 0;
  if ((level->min_band > 0) || remove_dc)
    { /* Can remove all tag bytes for the level. */
      for (k=0; k < level->bitstream_layers; k++)
        stripped_bytes += level->layer_tag_bytes[k];
      level->bitstream_layers = 0;
    }
  for (b=level->min_band; b <= level->max_band; b++)
    {
      if ((b==0) && !remove_dc)
        continue;
      band = level->bands + b;
      for (block=band->blocks, m=band->band_blocks; m > 0; m--, block++)
        {
          stripped_bytes += block->total_bytes;
          block->total_bytes = 0;
          block->num_passes = 0;

⌨️ 快捷键说明

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