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

📄 ebcot_receive_bits.c

📁 JPEG2000 EBCOT算法源码
💻 C
📖 第 1 页 / 共 3 页
字号:
          while ((tmp=block->first_unit) != NULL)
            {
              block->first_unit = tmp->next;
              self->code_heap_mgr->return_unit(self->code_heap_mgr,tmp);
            }
        }
    }
  return(stripped_bytes);
}

/*****************************************************************************/
/* STATIC                     parse_bitstream_layer                          */
/*****************************************************************************/

static int
  parse_bitstream_layer(level_info_ptr level, int layer_idx,
                        the_decoder_ref self)

 /* This function parses the information recovered from the bit-stream to
    satisfy the constraint imposed by the `self->max_levels' bound.  It
    should be invoked on each layer in turn, starting from the bitstream
    layer with the highest index; within each layer, it should be applied to
    each resolution level in turn, starting from the highest resolution level.
    At each resolution, it should be applied to each image component (usually
    colour components), starting from the component with the highest index.
    The function returns -1 if the constraint is already satisfied;
    otherwise, it returns the non-negative number of bytes which were parsed
    out, including all tag bytes which are now redundant.  The function always
    removes whole code blocks at a time, until enough bytes have been saved
    or the entire layer has been removed.  If the whole layer is removed, the
    tag bytes for the level are also removed. */

{
  int stripped_bytes, min_stripped_bytes, num_bytes, b, m, k;
  band_info_ptr band;
  block_info_ptr block;
  heap_unit_ptr prev, scan;

  stripped_bytes = 0;
  min_stripped_bytes = self->actual_bytes - self->max_bytes;
  if (min_stripped_bytes <= 0)
    return(-1); /* Constraint satisfied. */
  if (layer_idx >= level->bitstream_layers)
    return(0); /* Bit-stream was probably truncated. */

  m = 1; /* Avoid compiler warnings. */
  for (b=level->max_band; b >= level->min_band; b--)
    {
      band = level->bands + b;
      for (m=band->band_blocks, block=band->blocks+m-1;
           (m > 0) && (stripped_bytes < min_stripped_bytes);
           m--, block--)
        if (((k=block->num_passes) > 0) &&
            (block->passes[k-1].layer_idx >= layer_idx))
          {
            do {
              k--;
              assert(layer_idx == block->passes[k].layer_idx);
            } while ((num_bytes=block->passes[k].num_bytes) == 0);
            block->num_passes = k;
            block->total_bytes -= num_bytes;
            assert(block->total_bytes >= 0);
            stripped_bytes += num_bytes;


            for (prev=NULL, scan=block->first_unit,
                 num_bytes=block->total_bytes; num_bytes > 0;
                 prev=scan, scan=scan->next)
              num_bytes -= HEAP_BYTES;
            if (prev == NULL)
              block->first_unit = NULL;
            else
              prev->next = NULL;
            while ((prev=scan) != NULL)
              {
                scan=prev->next;
                self->code_heap_mgr->return_unit(self->code_heap_mgr,prev);
              }
          }
      for (; m > 0; m--, block--)
        if (block->total_bytes > 0)
          break;
    }
  if (m == 0)
    { /* Entire layer stripped out. */
      num_bytes = level->layer_tag_bytes[layer_idx];
      level->bitstream_layers = layer_idx;
      stripped_bytes += num_bytes;
      if (self->profile & PROFILE__RESOLUTION_PROGRESSIVE)
        { /* Can't just discard arbitrary layers from a particular resolution
             level, since the decoder would have no way of knowing they were
             discarded and would not correctly interpret lower layers of
             higher frequency subbands.  Generally need to mark the layer as
             empty by setting the first bit of a single-byte tag to 0. */
          if (level->level_idx < (self->max_levels-1))
            { /* Can't just drop the layer altogether without corrupting
                 the interpretation of layers which might not be dropped in
                 higher resolution levels of the parsed bit-stream. */
              stripped_bytes -= 1; /* Allow a single byte to mark the layer
                                      as empty (first bit equals 0). */
              if (level->level_idx == 0)
                { /* Get all the single byte markers back again, because the
                     total number of bit-stream layers identified in the
                     header of the parsed bit-stream can be decremented. */
                  stripped_bytes += self->max_levels-1;
                }
            }
        }
    }
  return(stripped_bytes);
}

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

/*****************************************************************************/
/* STATIC                   start_bitstream_recovery                         */
/*****************************************************************************/

static void
  start_bitstream_recovery(the_decoder_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);
        }
}

/*****************************************************************************/
/* STATIC                  finish_bitstream_recovery                         */
/*****************************************************************************/

static void
  finish_bitstream_recovery(the_decoder_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);
        }
}

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

/*****************************************************************************/
/* EXTERN                      ebcot_load_bit_stream                         */
/*****************************************************************************/

void
  ebcot_load_bit_stream(the_decoder_ref self)
{
  tag_buffer_ptr tags;
  jmp_buf except;
  int comp_idx, n, layer;
  level_info_ptr lev;
  codeword_heap_ref code_mgr;
  bitstream_source_ref input;

  self->actual_bytes = 0;
  start_bitstream_recovery(self);
  if (setjmp(except) == 0)
    {
      input = self->input;
      code_mgr = self->code_heap_mgr;
      tags = create_tag_buffer(input,&except);
      if (self->profile & PROFILE__RESOLUTION_PROGRESSIVE)
        {
          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 (layer=0; layer < self->bitstream_layers; layer++)
                    self->actual_bytes +=
                      recover_bitstream_layer(lev,layer,tags,input,code_mgr);
              }
        }
      else
        { /* SNR, rather than Resolution order. */
          for (layer=0; layer < self->bitstream_layers; layer++)
            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)
                    self->actual_bytes +=
                      recover_bitstream_layer(lev,layer,tags,input,code_mgr);
                }
        }
    }
  tag_buffer__destroy(tags);
  finish_bitstream_recovery(self);
}

/*****************************************************************************/
/* EXTERN                      ebcot_parse_bit_stream                        */
/*****************************************************************************/

void
  ebcot_parse_bit_stream(the_decoder_ref self)
{
  int comp_idx, n, layer, stripped_bytes;
  level_info_ptr lev;

  /* First, strip out all redundant components and resolution levels. */

  for (comp_idx=self->max_components;
       comp_idx < self->num_components; comp_idx++)
    for (n=0; n <= self->num_levels; n++)
      {
        lev = self->components[comp_idx].levels + n;
        if (lev->min_band <= lev->max_band)
          self->actual_bytes -= parse_out_level(lev,self);
      }
  for (n=self->max_levels; 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)
          self->actual_bytes -= parse_out_level(lev,self);
      }

  /* Now parse out layers and/or blocks until the rate target is achieved. */

  for (layer=self->bitstream_layers-1; layer >= 0; layer--)
    {
      for (n=self->num_levels; n >= 0; n--)
        for (comp_idx=self->max_components-1; comp_idx >= 0; comp_idx--)
          {
            lev = self->components[comp_idx].levels + n;
            if (lev->min_band <= lev->max_band)
              {
                if ((stripped_bytes =
                     parse_bitstream_layer(lev,layer,self)) < 0)
                  return;
                else
                  self->actual_bytes -= stripped_bytes;
              }
          }
    }
}

⌨️ 快捷键说明

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