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

📄 ebcot_receive_bits.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************/
/* 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 + -