📄 ebcot_receive_bits.c
字号:
int elts, new_elts, next_rows, next_cols, r, c; elts = 0; next_rows = rows; next_cols = cols; do { new_elts = next_rows*next_cols; elts += new_elts; next_rows = (1+next_rows)>>1; next_cols = (1+next_cols)>>1; } while (new_elts > 1); result = node = (tag_tree_node_ptr) local_malloc(EBCOT_MEM_KEY,sizeof(tag_tree_node)*(size_t) elts); do { elts = rows*cols; parents = node + elts; if (elts == 1) parents = NULL; next_rows = (1+rows)>>1; next_cols = (1+cols)>>1; for (r=0; r < rows; r++) for (c=0; c < cols; c++, node++) { node->value = INT_MAX; node->lower_bound = 0; node->child = NULL; node->parent = NULL; if (parents != NULL) node->parent = parents + ((r>>1)*next_cols + (c>>1)); } rows = next_rows; cols = next_cols; } while (elts > 1); return(result);}/*****************************************************************************//* EXTERN ebcot_get_packet_head_and_body *//*****************************************************************************/void ebcot_get_packet_head_and_body(ebcot_decoder_ref self, ebcot_packet_info_ptr packet, block_master_ptr master, int layer_idx) /* Note: the function computes several properties of corrupted packets which are not currently used, but could come in handy later. These are `trailing_useless_bytes' (the total number of bytes recovered from the packet, which cannot and will not be used by the decompressor due to corruption) and `min_packet_bytes' (the minimum number of bytes from the packet which will be useful to the decoder). The sum of these two quantities is equal to the total number of bytes recovered from the packet; the actual packet size may be slightly larger due to the inclusion of error correction codes. */{ dst_codeword_heap_ref code_mgr = self->code_heap_mgr; stream_in_ref stream = self->stream; tag_buffer_ptr tags; int useless_packet, packet_body_corrupted; int min_packet_bytes, trailing_useless_bytes; int packet_non_empty, new_passes; ebcot_packet_band_info_ptr pband; ebcot_block_info_ptr bpp, block; int b, r, c, pos; assert(layer_idx == packet->included_layers); if (layer_idx == 0) { /* Initialize various quantities. */ for (b=packet->min_band; b <= packet->max_band; b++) { pband = packet->bands + b; tag_tree__reset(pband->inclusion_tree); tag_tree__reset(pband->insignificant_msbs_tree); 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++) { block->num_passes = 0; block->num_signalled_passes = 0; block->total_bytes = 0; block->new_passes = 0; block->insignificant_msbs = 0; block->byte_count_bits = 3; /* Minimum number of bits for signalling byte counts. */ } } } tags = create_tag_buffer(); tag_buffer__reset(tags,stream); packet_non_empty = 0; if (tag_buffer__try(tags)) { tag_buffer__pull_bit(tags,packet_non_empty); if (packet_non_empty) recover_packet_head(self,packet,master,layer_idx,tags); } else packet->packet_loss_encountered = 1; min_packet_bytes = tags->retrieved_bytes; if (packet->packet_loss_encountered || !packet_non_empty) { tag_buffer__destroy(tags); trailing_useless_bytes = INT_MAX; useless_packet = 1; return; } /* If we get here then the packet appears to be uncorrupted so far and the `new_passes' fields of all code blocks identify the number of new passes which are being added. We now try to read all the relevant block code bytes from the packet's body. */ useless_packet = 0; packet_body_corrupted = 0; trailing_useless_bytes = 0; 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++) { std_byte *wp; dst_heap_unit_ptr unit; int num_bytes, pulled_bytes, remaining_bytes, recovered_bytes; new_passes = block->new_passes; if (new_passes <= 0) continue; unit = block->first_unit; if (unit == NULL) { remaining_bytes = 0; wp = NULL; } else { remaining_bytes = DST_HEAP_BYTES; wp = (std_byte *)(unit->words); } num_bytes = block->total_signalled_bytes; /* Skip over these. */ while (num_bytes > 0) { if (num_bytes > remaining_bytes) { unit = unit->next; num_bytes -= remaining_bytes; remaining_bytes = DST_HEAP_BYTES; wp = (std_byte *)(unit->words); } else { wp += num_bytes; remaining_bytes -= num_bytes; num_bytes = 0; } } num_bytes = block->passes[block->num_signalled_passes].layer_bytes; recovered_bytes = 0; if (num_bytes == 0) { /* Length information for block must have been corrupted. Cannot signal non-zero number of passes and a length of zero! */ packet_body_corrupted = 1; } while ((num_bytes > 0) && (!packet_body_corrupted)) { 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); remaining_bytes = DST_HEAP_BYTES; wp = (std_byte *)(unit->words); } if (num_bytes > remaining_bytes) { pulled_bytes = stream->pull_body_bytes(stream,wp,remaining_bytes); recovered_bytes += pulled_bytes; if (pulled_bytes < remaining_bytes) { /* Corruption or truncation detected in the body at least. Assume for now that the head is OK so that we will continue to update the signalled quantities but not `num_passes' and `total_bytes'. */ packet_body_corrupted = 1; break; } num_bytes -= remaining_bytes; remaining_bytes = 0; wp = NULL; } else { pulled_bytes = stream->pull_body_bytes(stream,wp,num_bytes); recovered_bytes += pulled_bytes; if (pulled_bytes < num_bytes) { /* Corruption or truncation detected in the body at least. Assume for now that the head is OK so that we will continue to update the signalled quantities but not `num_passes' and `total_bytes'. */ packet_body_corrupted = 1; break; } wp += num_bytes; remaining_bytes -= num_bytes; num_bytes = 0; } } if (packet_body_corrupted) { /* There will be no more updating of the `num_passes' and `total_bytes' fields from now on. */ trailing_useless_bytes += recovered_bytes; if (min_packet_bytes == tags->retrieved_bytes) useless_packet = 1; } else if (block->num_signalled_passes == block->num_passes) { assert(num_bytes == 0); block->num_passes += block->new_passes; block->total_bytes += recovered_bytes; } block->total_signalled_bytes += recovered_bytes; block->num_signalled_passes += block->new_passes; block->new_passes = 0; min_packet_bytes += recovered_bytes; } } tag_buffer__destroy(tags);}/*****************************************************************************//* EXTERN ebcot_parse_to_length *//*****************************************************************************/void ebcot_parse_to_length(ebcot_decoder_ref self, int max_bytes){ int tnum, layer, max_layers, c, n, p; ebcot_tile_ptr tile; ebcot_component_info_ptr comp_info; ebcot_level_info_ptr lev; ebcot_packet_info_ptr packet; if (self->actual_bytes <= max_bytes) return; max_layers = 0; for (tnum=0; tnum < self->num_tiles; tnum++) { tile = self->tiles + tnum; if (tile->num_layers > max_layers) max_layers = tile->num_layers; } if (max_layers == 1) local_printf(0,76,"\nWarning: the bit-stream which is being parsed " "down to satisfy the supplied bit-rate constraint " "is not SNR scalable (i.e. no tile has more than one " "quality layer)!! This means " "that whole blocks will be discarded , starting from " "the high frequency subbands and working down. This " "is probably not what you want!"); for (layer=max_layers-1; layer >= 0; layer--) { for (tnum=self->num_tiles-1; tnum >= 0; tnum--) { tile = self->tiles + tnum; if (tile->num_layers <= layer) continue; /* Nothing to remove from this tile. */ for (c=tile->max_components-1; c >= 0; c--) { comp_info = tile->components + c; for (n=comp_info->num_levels; n >= 0; n--) { lev = comp_info->levels + n; for (p=lev->total_packets-1; p >= 0; p--) { packet = lev->packets + p; parse_packet(self,packet,layer,max_bytes); if (self->actual_bytes <= max_bytes) return; } } } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -