📄 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: VM9.0 */
/* Last Revised: 26 April, 2001 */
/*****************************************************************************/
/*****************************************************************************/
/* 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 Reserved 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. */
/*****************************************************************************/
/*****************************************************************************/
/* Modified by David Taubman to implement changes in Tokyo between CD and */
/* FCD for Part-1 of the standard. Copyrighted by HP with all rights */
/* reserved for the modified parts. */
/*****************************************************************************/
/*****************************************************************************/
/* Modified for general wavelet decompositions. */
/* Copyright 2000 Science Applications International Corporation (SAIC). */
/* Copyright 1995 University of Arizona, Arizona Board of Regents. */
/* All Rights Reserved for 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_COST
int 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. */
{
if (tree == NULL)
return;
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--;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -