📄 ebcot_receive_bits.c
字号:
/*****************************************************************************//* Copyright 1998, Hewlett-Packard Company *//* All rights reserved *//* File: "ebcot_receive_bits.c" *//* Description: Unpacks the bit-stream for the EBCOT decoder and simulates *//* bit-stream parsing to the best of its ability. *//* Author: David Taubman *//* Affiliation: Hewlett-Packard and *//* The University of New South Wales, Australia *//* Version: VM6.0 *//* Last Revised: 19 January, 2000 *//*****************************************************************************//*****************************************************************************//* Modified by David Taubman to support new termination methods for parallel *//* coding options. Copyright 1999 by Hewlett-Packard Company with all *//* rights reserved for the modified parts. *//*****************************************************************************//*****************************************************************************//* Modified to combine entropy coders *//* Copyright 1999 Science Applications International Corporation (SAIC). *//* Copyright 1999 University of Arizona, Arizona Board of Regents. *//* All Rights Reservedi for modified parts. *//*****************************************************************************//*****************************************************************************//* Modified by David Taubman to support interface modifications, arbitrary *//* changes in coding parameters from component to component and from tile *//* to tile, packet partitions, rich packet sequencing conventions and to *//* support the full generality of PART-1 of the JPEG2000 *//* standard, and to support most anticipated generality of PART-2. Changes *//* are too numerous to flag individually within the code, which in some *//* places has been completely rewritten. All changes copyrighted by HP with *//* all rights reserved for the modified parts. *//*****************************************************************************/#include <local_services.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include <ifc.h>#include "ebcot_decoder.h"#include "ebcot_receive_bits.h"#ifdef REPORT_LENGTH_SIGNALLING_COSTint ebcot_total_length_signalling_bits = 0;int ebcot_total_length_signalled_passes = 0;#endif /* REPORT_LENGTH_SIGNALLING_COST *//* ========================================================================= *//* ------------------------------- Tag Buffering --------------------------- *//* ========================================================================= *//*****************************************************************************//* STATIC create_tag_buffer *//*****************************************************************************/static tag_buffer_ptr create_tag_buffer(void){ tag_buffer_ptr result; result = (tag_buffer_ptr) local_malloc(EBCOT_MEM_KEY,sizeof(tag_buffer)); memset(result,0,sizeof(tag_buffer)); result->byte = 0; result->available_bits = 0; result->retrieved_bytes = 0; result->last_byte_ff = 0; return(result);}/*****************************************************************************//* MACRO tag_buffer__pull_bit *//*****************************************************************************/#define tag_buffer__pull_bit(_buffer,_val) \ /* tag_buffer_ptr _buffer, int/short/byte _val. */ \ { \ if (_buffer->available_bits == 0) \ { \ if (!(_buffer->stream->pull_head_bytes(_buffer->stream, \ &(_buffer->byte),1))) \ longjmp(_buffer->except,1); \ _buffer->available_bits = 8; \ _buffer->last_byte_ff = (_buffer->byte == 0xFF); \ _buffer->retrieved_bytes++; \ } \ _val = (std_byte)((_buffer->byte >> 7) & 1); \ _buffer->byte <<= 1; \ _buffer->available_bits--; \ if ((_buffer->available_bits == 0) && (_buffer->last_byte_ff)) \ { /* Pull the next bit (it should be a zero, but allow corruption) */ \ _buffer->last_byte_ff = 0; \ if (_buffer->stream->pull_head_bytes(_buffer->stream, \ &(_buffer->byte),1)) \ { \ _buffer->available_bits = 7; \ _buffer->retrieved_bytes++; \ _buffer->byte <<= 1; \ } \ } \ }/*****************************************************************************//* STATIC tag_buffer__pull_bits *//*****************************************************************************/static std_int tag_buffer__pull_bits(tag_buffer_ptr buffer, int num_bits) /* This function retrieves `num_bits' bits from the tag buffer and returns them as the least significant bits of the returned 32-bit word. The least significant bit of the returned word is the last of the `num_bits' retrieved. The `num_bits' value must not exceed 31. */{ std_int result; int n; assert(num_bits <= 31); result = 0; while (num_bits > 0) { if (buffer->available_bits == 0) { if (!(buffer->stream->pull_head_bytes(buffer->stream, &(buffer->byte),1))) longjmp(buffer->except,1); buffer->available_bits = 8; buffer->last_byte_ff = (buffer->byte == 0xFF); buffer->retrieved_bytes++; } n = num_bits; if (n > buffer->available_bits) { n = buffer->available_bits; num_bits -= n; buffer->available_bits = 0; } else { num_bits = 0; buffer->available_bits -= n; } while (n--) { result = (result << 1) | ((buffer->byte >> 7) & 1); buffer->byte <<= 1; } if ((buffer->available_bits == 0) && (buffer->last_byte_ff)) { /* Pull the next bit (it should be a zero, but allow corruption) */ buffer->last_byte_ff = 0; if (buffer->stream->pull_head_bytes(buffer->stream, &(buffer->byte),1)) { buffer->available_bits = 7; buffer->retrieved_bytes++; buffer->byte <<= 1; } } } return(result);}/*****************************************************************************//* STATIC tag_buffer__reset *//*****************************************************************************/static void tag_buffer__reset(tag_buffer_ptr buffer, stream_in_ref stream){ buffer->byte = 0; buffer->available_bits = 0; buffer->retrieved_bytes = 0; buffer->last_byte_ff = 0; buffer->stream = stream;}/*****************************************************************************//* MACRO tag_buffer__try *//*****************************************************************************/#define tag_buffer__try(_buffer) (setjmp(_buffer->except)==0)/*****************************************************************************//* STATIC tag_buffer__destroy *//*****************************************************************************/static void tag_buffer__destroy(tag_buffer_ptr buffer){ local_free(buffer);}/* ========================================================================= *//* -------------------------------- Tag Trees ------------------------------ *//* ========================================================================= *//*****************************************************************************//* STATIC tag_tree__reset *//*****************************************************************************/static void tag_tree__reset(tag_tree_node_ptr tree) /* Resets all values and lower bounds for the supplied tree. */{ tree--; do { tree++; tree->value = INT_MAX; tree->lower_bound = 0; tree->child = NULL; } while (tree->parent != NULL);}/*****************************************************************************//* STATIC tag_tree__decode *//*****************************************************************************/static int tag_tree__decode(tag_tree_node_ptr leaf, int threshold, tag_buffer_ptr target) /* Retrieves and decodes sufficient tag bits to determine 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 completely decoded and may be retrieved later by directly accessing the `value' field of `leaf'. Values which are greater than or equal to the threshold remain unknown. The function returns 1 if the leaf's value is less than the threshold and 0 otherwise. */{ tag_tree_node_ptr node; int result, bit, lower_bound; assert(threshold > 0); 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__pull_bit(target,bit); if (bit) node->value = lower_bound; else lower_bound++; } node->lower_bound = lower_bound; } result = (leaf->value < threshold); return(result);}/* ========================================================================= *//* ------------------------ Packet Recovery Functions ---------------------- *//* ========================================================================= *//*****************************************************************************//* STATIC mark_termination_points *//*****************************************************************************/static void mark_termination_points(ebcot_pass_info_ptr passes, int insignificant_msbs, int max_passes, int terminate_each_pass, int full_effort_msbs){ int pass_idx; int n; pass_idx = insignificant_msbs * PASSES_PER_BITPLANE; for (n=0; n < pass_idx; n++) passes[n].terminated = 0; for (n=0; pass_idx < max_passes; pass_idx++, n++) { if (n == PASSES_PER_BITPLANE) { n = 0; full_effort_msbs--; } passes[pass_idx].terminated = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -