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

📄 ebcot_receive_bits.c

📁 关于视频压缩的jpeg2000压缩算法,C编写
💻 C
📖 第 1 页 / 共 3 页
字号:
      if (terminate_each_pass ||          ((full_effort_msbs <= 0) &&           ((n==0) || (n==(PASSES_PER_BITPLANE-1)))))        passes[pass_idx].terminated = 1;    }}/*****************************************************************************//* STATIC                      recover_packet_head                           *//*****************************************************************************/static void  recover_packet_head(ebcot_decoder_ref self,                      ebcot_packet_info_ptr packet,                      block_master_ptr master,                      int layer_idx, tag_buffer_ptr tags) /* This function does quite a bit of the work of the function    `ebcot_get_packet_head_and_body'.  It recovers the header information    for the packet, filling in the `new_passes' field of each relevant block,    as well as the relevant entries in the `passes' array for the    corresponding blocks.  The caller should use this information to update    the `num_passes', `num_signalled_passes' and `total_bytes' fields for all    affected blocks and to recover the code bytes themselves.  Upon entry,    the packet has been started and the initial bit of the header has already    been read to determine whether or not the packet contains any information.    If a problem is detected in the packet header, the function may not    actually return, but this exception will be caught by the caller as a    false return from `tag_buffer__try'. */{  ebcot_packet_band_info_ptr pband;  ebcot_block_info_ptr bpp, block;  int new_passes, save_new_passes, tag_val;  int b, r, c, k, pos;  for (b=packet->min_band; b <= packet->max_band; b++)    {      pband = packet->bands + b;      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++)          {            /* Recover inclusion information. */            if (block->num_signalled_passes == 0)              { /* Not previously included. */                tag_val =                  tag_tree__decode(pband->inclusion_tree+pos,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_signalled_passes == 0)              {                k = 1;                while (!tag_tree__decode(pband->insignificant_msbs_tree+pos,k,                                         tags))                  k++;                block->insignificant_msbs = k-1;                /* Begin David T ER fix */                if ((block->insignificant_msbs*PASSES_PER_BITPLANE) >=                    block->max_passes)                  { /* An error has occurred in the packet head; everything                       from now on must be corrupt. */                    packet->packet_loss_encountered = 1;                    return;                  }                /* End David T ER fix */                mark_termination_points(block->passes,                                        block->insignificant_msbs,                                        block->max_passes,                                        master->terminate_each_pass,                                        master->full_effort_msbs);              }            /* Now recover information about the number of new passes. */                        if (block->num_signalled_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;                          }                      }                  }              }            if ((block->num_signalled_passes + new_passes) > block->max_passes)              { /* Must be due to corruption in bit-stream. */                new_passes = block->max_passes - block->num_signalled_passes;              }            save_new_passes = new_passes;            if (new_passes > 0)              { /* Recover the number of bytes between successive termination                   and/or truncation points within these new passes. */                ebcot_pass_info_ptr layer_start_pass, seg_start_pass, scan;                int bytes_from_layer_start, num_bits;                                    layer_start_pass = seg_start_pass =                  block->passes + block->num_signalled_passes;                if (block->num_signalled_passes == 0)                  {                    k = block->insignificant_msbs * PASSES_PER_BITPLANE;                    seg_start_pass += k;                    new_passes -= k;                  }                bytes_from_layer_start = 0;                while (new_passes > 0)                  {                    scan = seg_start_pass;                    for (k=0; k < (new_passes-1); k++, scan++)                      if (scan->terminated)                        break;                    k++; /* Get number of new passes covered by length. */                    new_passes -= k;#ifdef REPORT_LENGTH_SIGNALLING_COST                    ebcot_total_length_signalled_passes += k;#endif /* REPORT_LENGTH_SIGNALLING_COST */                    /* Now for comma code identifying any required increment                       in `byte_count_bits'. */                    do {                      tag_buffer__pull_bit(tags,tag_val);#ifdef REPORT_LENGTH_SIGNALLING_COST                      ebcot_total_length_signalling_bits++;#endif /* REPORT_LENGTH_SIGNALLING_COST */                      if (tag_val)                        block->byte_count_bits++;                    } while (tag_val);                    for (num_bits=block->byte_count_bits; k > 1; k>>=1)                      num_bits++;                    if (num_bits > 16)                      { /* Packet is corrupt. */                        packet->packet_loss_encountered = 1;                        return;                      }#ifdef REPORT_LENGTH_SIGNALLING_COST                    ebcot_total_length_signalling_bits += num_bits;#endif /* REPORT_LENGTH_SIGNALLING_COST */                    tag_val = tag_buffer__pull_bits(tags,num_bits);                    bytes_from_layer_start += tag_val;                    if (scan->terminated)                      scan->special_length =                        (std_ushort) bytes_from_layer_start;                    seg_start_pass = scan+1;                  }                scan = layer_start_pass;                scan->layer_idx = (std_ushort) layer_idx;                scan->layer_bytes = (std_ushort) bytes_from_layer_start;                for (scan++; scan < seg_start_pass; scan++)                  {                    scan->layer_idx = (std_ushort) layer_idx;                    scan->layer_bytes = 0;                  }              }            block->new_passes = save_new_passes;          }      }}/*****************************************************************************//* STATIC                          parse_packet                              *//*****************************************************************************/static void  parse_packet(ebcot_decoder_ref self, ebcot_packet_info_ptr packet,               int layer_idx, int max_bytes) /* This function pares down the size of a packet in order to satisfy the    constraint imposed by the `max_bytes' bound.  It should be    invoked packet by packet, starting with the least interesting packets,    until the constraint is satisfied.  The function always removes whole    code bytes at a time, adjusting the `self->actual_bytes' count to    reflect the number of bytes which should be saved if this task were    performed by a separate bit-stream parsing tool.  The actual number of    bytes which would be saved if the bit-stream were parsed correctly might    actually be somewhat more than that which is estimated by this function,    because we cannot correctly account for the saving in error detection    and/or correction codes which might be incurred at the bit-stream level.    If error resilience features are not utilized, then the simulation    of real bit-stream parsing should be accurate. */{  ebcot_packet_band_info_ptr pband;  ebcot_block_info_ptr block;  dst_heap_unit_ptr prev, scan;  int stripped_bytes, min_stripped_bytes, keeping_partial_packet;  int num_bytes, b, r, c, k;  min_stripped_bytes = self->actual_bytes - max_bytes;  assert(min_stripped_bytes > 0);  if (layer_idx >= packet->included_layers)    return;  keeping_partial_packet = 0;  stripped_bytes = 0;  for (b=packet->max_band;       (b >= packet->min_band) && (!keeping_partial_packet);       b--)    {      pband = packet->bands + b;      for (r=pband->blocks_high-1; (r >= 0) && (!keeping_partial_packet); r--)        for (c=pband->blocks_wide-1; c >= 0; c--)          {            block = pband->blocks + (c + r*pband->block_row_gap);            k = block->num_passes;            if ((k <= 0) || (block->passes[k-1].layer_idx < layer_idx))              continue;            if (stripped_bytes >= min_stripped_bytes)              {                keeping_partial_packet = 1;                break;              }            do {              k--;              assert(layer_idx == block->passes[k].layer_idx);            } while ((num_bytes=block->passes[k].layer_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 -= DST_HEAP_BYTES;            if (prev == NULL)              {                assert(block->total_bytes == 0);                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);              }          }    }  if (keeping_partial_packet)    self->actual_bytes -= stripped_bytes;  else    { /* Remove entire packet. */      packet->included_layers--;      assert(packet->included_layers == layer_idx);      assert(packet->layer_bytes[layer_idx] >= stripped_bytes);      self->actual_bytes -= packet->layer_bytes[layer_idx];    }}/* ========================================================================= *//* ---------------------------- External Functions ------------------------- *//* ========================================================================= *//*****************************************************************************//* EXTERN                     ebcot_create_tag_tree                          *//*****************************************************************************/tag_tree_node_ptr  ebcot_create_tag_tree(int rows, int cols) /* Creates a tag-tree with an array of `rows'*`cols' leaf nodes, returning    a pointer to the top-left hand corner leaf node (the leaf nodes appear    at the head of the returned array, in scan-line order). */{  tag_tree_node_ptr result, node, parents;

⌨️ 快捷键说明

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