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

📄 ebcot_receive_bits.c

📁 JPEG2000 EBCOT算法源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************/
/* File name: "ebcot_receive_bits.c"                                         */
/* Author: David Taubman                                                     */
/* Copyright 1998, Hewlett-Packard Company                                   */
/* All rights reserved                                                       */
/*****************************************************************************/
#include <stdlib.h>
#include <assert.h>
#include <local_heap.h>
#include "ebcot_decoder.h"
#include "ebcot_receive_bits.h"


/* ========================================================================= */
/* ------------------------------- Tag Buffering --------------------------- */
/* ========================================================================= */

/*****************************************************************************/
/* STATIC                        create_tag_buffer                           */
/*****************************************************************************/

static tag_buffer_ptr
  create_tag_buffer(bitstream_source_ref source, jmp_buf *except)
{
  tag_buffer_ptr result;

  result = (tag_buffer_ptr) local_malloc(sizeof(tag_buffer));
  result->byte = 0;
  result->available_bits = 0;
  result->retrieved_bytes = 0;
  result->source = source;
  result->except = except;
  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->source->pull_bytes(_buffer->source,                   \
                                          &(_buffer->byte),1)))              \
          longjmp(*(_buffer->except),1);                                     \
        _buffer->available_bits = 8;                                         \
        _buffer->retrieved_bytes++;                                          \
      }                                                                      \
    _val = (std_byte)((_buffer->byte >> 7) & 1);                             \
    _buffer->byte <<= 1;                                                     \
    _buffer->available_bits--;                                               \
  }

/*****************************************************************************/
/* 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->source->pull_bytes(buffer->source,&(buffer->byte),1)))
            longjmp(*(buffer->except),1);
          buffer->available_bits = 8;
          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;
        }
    }
  return(result);
}

/*****************************************************************************/
/* STATIC                        tag_buffer__reset                           */
/*****************************************************************************/

static void
  tag_buffer__reset(tag_buffer_ptr buffer)
{
  buffer->byte = 0;
  buffer->available_bits = 0;
  buffer->retrieved_bytes = 0;
}

/*****************************************************************************/
/* STATIC                       tag_buffer__destroy                          */
/*****************************************************************************/

static void
  tag_buffer__destroy(tag_buffer_ptr buffer)
{
  local_free(buffer);
}

/* ========================================================================= */
/* -------------------------------- Tag Trees ------------------------------ */
/* ========================================================================= */

/*****************************************************************************/
/* STATIC                        create_tag_tree                             */
/*****************************************************************************/

static tag_tree_node_ptr
  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;
  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(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);
}

/*****************************************************************************/
/* 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);
}

/* ========================================================================= */
/* ------------------------ Bitstream Layer Management --------------------- */
/* ========================================================================= */

/*****************************************************************************/
/* STATIC                    recover_bitstream_layer                         */
/*****************************************************************************/

static int
  recover_bitstream_layer(level_info_ptr level, int layer_idx,
                          tag_buffer_ptr tags, bitstream_source_ref input,
                          codeword_heap_ref code_mgr)

 /* This function recovers a new layer from the bit-stream, where the
    new layer is known to represent code blocks from the indicated
    resolution level.  The function updates all relevant fields of the
    affected `block_info' structures in preparation for coding.  It
    returns the number of bytes which were retrieved from the bit-stream.
    If the bit-stream terminates prematurely, while tag information for
    the new layer is being recovered, the function will not explicitly
    return, but control will be returned to the point at which the
    `except' information was installed in the `tags' object.  The fact that
    the function has no opportunity does not create any problems in this
    case, since none of the information recovered while reading tags is
    of any use without the code bytes themselves, which follow, so the

⌨️ 快捷键说明

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