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

📄 dst_arith_decoder.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************/
/* Copyright 1998, Hewlett-Packard Company                                   */
/* All rights reserved                                                       */
/* File: "dst_arith_decoder.c"                                               */
/* Description: Implementation of non-macro arithmetic decoder functions     */
/* Author: David Taubman                                                     */
/* Affiliation: Hewlett-Packard and                                          */
/*              The University of New South Wales, Australia                 */
/* Version: VM7.0                                                            */
/* Last Revised: 24 March, 2000                                              */
/*****************************************************************************/

/*****************************************************************************/
/* Modified to incorporate MQ-coder by Mitsubishi Electric Corp.             */
/* Copyright 1999, Mitsubishi Electric Corp.                                 */
/* All rights reserved for modified parts                                    */
/*****************************************************************************/

/*****************************************************************************/
/* Modified to speed up MQ-decoder                                           */
/* Copyright 1999 Science Applications International Corporation (SAIC).     */
/* All Rights Reserved for modified parts.                                   */
/*****************************************************************************/

/*****************************************************************************/
/* Modifications tagged with comment lines or delimiters involving the       */
/* string, "David T mod" or "mod by David T", have been made by David        */
/* Taubman; they are copyrighted by Hewlett-Packard Company with all rights  */
/* reserved for the modified parts.                                          */
/*****************************************************************************/

/*****************************************************************************/
/* Substantially modified by David Taubman to support flexible termination   */
/* of code stream segments and error resilience capabilities.  Copyright     */
/* 1999 by Hewlett-Packard Company with all rights reserved for the modified */
/* parts.                                                                    */
/*****************************************************************************/

/*****************************************************************************/
/* Modified by David Taubman to avoid the need for byte stuffing when resync */
/* markers are in use.  This simplifies the code and substantially improves  */
/* the usefulness of the system for applications requiring error resilience. */
/* Changes are as follows: a) changed SOT marker to lie within intra-packet  */
/* marker range 0xFF90 through 0xFFFF; b) introduced an MQ-like bit-stuffing */
/* policy in packet heads; c) introduced an MQ-like bit-stuffing policy in   */
/* the raw bit-stream segments generated by the entropy coder in lazy mode;  */
/* d) modified error resilient termination policy for raw bit-stream         */
/* to fill unused bits with the simpler code 0101... instead of 1010...;     */
/* e) eliminated the use of byte-stuffing with resync markers.  In the new   */
/* code, none of the packet segments (packet head, MQ segments and raw       */
/* segments) may contain any two byte sequence in the range 0xFF90 through   */
/* 0xFFFF; moreover, no segment can terminate with a 0xFF, so that the       */
/* entire packet is guaranteed to be free of two byte sequences in the above */
/* range.  All delimiting markers from the codestream (i.e. SOT, RESYNC and  */
/* EOC) are guaranteed to lie within that range.                             */
/* Copyright 1999 by Hewlett-Packard Company with all                        */
/* rights reserved for the modified parts.                                   */
/*****************************************************************************/

#include <local_services.h>
#include <assert.h>
#include <stdio.h>
#include "dst_arith_decoder.h"


/* ========================================================================= */
/* --------------------------- Private Macros ------------------------------ */
/* ========================================================================= */

/*****************************************************************************/
/* MACRO                         get_byte                                    */
/*****************************************************************************/

#define get_byte(_state)                                               \
  {                                                                    \
    if (_state->current_lsb == 0)                                      \
      {                                                                \
        _state->word = dst_arith_coder__input_word(_state);            \
        _state->current_lsb = 32;                                      \
      }                                                                \
    _state->current_lsb -= 8;                                          \
    assert(_state->current_lsb >= 0);                                  \
    _state->mqd.buffer =                                               \
     (_state->word >> _state->current_lsb) & 0x00FF;                   \
  }


/* ========================================================================= */
/* ------------------------- Internal Functions ---------------------------- */
/* ========================================================================= */

/*****************************************************************************/
/* STATIC                        dec_preload                                 */
/*****************************************************************************/

static void
  dec_preload(dst_arith_state_ptr state, mqd_var_ptr mqd)

 /* creg initialize : 15bit load */

{
  int preload = S_DR_PRELOAD;

  mqd->creg = dst_arith_coder__bytein(mqd->creg,&(mqd->ct),state);
                                      /* Set buffer <- memory */
  mqd->creg = dst_arith_coder__bytein(mqd->creg,&(mqd->ct),state);
                                      /* 1st byte -> creg.B */
  mqd->creg <<= mqd->ct;
  preload -= mqd->ct;
  mqd->creg = dst_arith_coder__bytein(mqd->creg,&(mqd->ct),state);
                                      /* 2nd byte -> creg.B */
  mqd->creg <<= preload;
  mqd->ct -= preload;
  if(mqd->ct == 0)
    mqd->creg = dst_arith_coder__bytein(mqd->creg,&(mqd->ct),state);
}

/*****************************************************************************/
/* STATIC                         init_dec                                   */
/*****************************************************************************/

static void
  init_dec(mqd_var_ptr mqd)
{
  mqd->areg = DEC_HALF;
  mqd->creg = LONG_ZERO;
  mqd->buffer = LONG_ZERO;
  mqd->ct = 0;
  mqd->nextct = NEXTBITS_NML;
  mqd->converted_doublets = 0;
  mqd->active = 0;
}

/*****************************************************************************/
/* STATIC                     check_mq_erterm_bits                           */
/*****************************************************************************/

static int
  check_mq_erterm_bits(dst_arith_state_ptr state, std_int last_byte)
{
  int approximate_er_bits;
  int ct, next_ct, converted_doublets, bits_left, spare_bits;
  unsigned long creg;
  std_int offset, min_last_byte, max_last_byte;

  /* Load required MQ state variables. */

  ct = state->mqd.ct;
  next_ct = state->mqd.nextct;
  creg = state->mqd.creg;
  converted_doublets = state->mqd.converted_doublets;

  /* Perform checks at the byte level and determine number of bits
     contained in the terminating byte beyond the MSB of the C register. */

  if (converted_doublets == 1)
    { /* Terminating byte != FF and MSB of C register must be in one of
         7 most significant bits of the terminating byte. */
      if ((ct == 8) || (next_ct != 8))
        return(-1);
      bits_left = ct;
    }
  else if (converted_doublets == 2)
    {
      if (ct == 8)
        { /* Terminating byte != FF and MSB of C register must be in LSB
             of the terminating byte. */
          if (next_ct != 7)
            return(-1);
          bits_left = 0;
        }
      else
        { /* Terminating byte must be FF. */
          last_byte = 0x00FF;
          if (ct == 8)
            return(-1);
          if (next_ct == 7)
            bits_left = ct;
          else
            {
              bits_left = 0;
              if (ct != 7)
                return(-1);
            }
        }
    }
  else
    return(-1);
  
  /* Now compute the lower and upper bounds on the terminating byte and
     hence the number of spare bits in the code space. */

  creg >>= (31-bits_left);
  offset = (std_int) creg; /* This is the quantity added to the minimum value
                              for the terminating byte by the encoder. */
  if (offset != 0)
    return(-1);
  min_last_byte = last_byte - offset;
  max_last_byte = min_last_byte + (1<<bits_left) - 1;
  if (max_last_byte > 255)
    max_last_byte = 255;
  spare_bits = 8;
  while (((1<<spare_bits)-1) > (max_last_byte-min_last_byte))
    spare_bits--;

  /* Estimate the number of bits of error detection code space and return
     this value.  Note that the number of bits of effective error detection
     code space is equal to -log_2 of the probability that an error would
     have violated the length-based checks above, plus the number of spare
     bits.  To estimate the first quantity more carefully we would need
     to know the number of symbols actually decoded.  Instead, as a place
     holder, we currently assume that approximately half the number of
     bits used to signal the segment length are effective as error detection
     bits. */

  approximate_er_bits = 0;
  while ((1<<approximate_er_bits) < state->current_segment_bytes)
    approximate_er_bits++;
  approximate_er_bits >>= 1;
  approximate_er_bits += spare_bits;
  return(approximate_er_bits);
}

/*****************************************************************************/
/* STATIC                     check_raw_erterm_bits                          */
/*****************************************************************************/

static int
  check_raw_erterm_bits(dst_arith_state_ptr state)
{
  int spare_bits, approximate_er_bits;
  std_int code;

  /* Check for correct padding bits in a partially used terminating byte */

  spare_bits = 0;
  while (state->current_lsb & 7)
    {
      state->current_lsb--;
      code = (state->word >> state->current_lsb) & 1;
      spare_bits++;
      if (code == (spare_bits & 1))
        return(-1);
    }

  /* Now check that we have at least consumed all necessary bytes.  Note
     that trailing FF's may have been discarded by the encoder so we might
     have read past the end of the available bytes; however, there should
     be no excuse for reading too few bytes, with one exception: if the
     last bit consumed was the final bit in an FF, the encoder was allowed
     to insert a non-FF byte as the last byte in the raw bit-stream --
     simplifies some encoder implementations. */

  if (!state->final_segment_word_consumed)
    {
      int unused_bytes;

      unused_bytes = state->bytes_left_in_segment -
        (state->bytes_in_word - (state->current_lsb >> 3));
      if (unused_bytes > 0)
        {
          if (((state->word >> state->current_lsb) & 0x00FF) == 0x00FF)
            unused_bytes--;
          if (unused_bytes > 0)
            return(-1);
        }
    }

  /* Estimate the number of bits of error detection code space and return
     this value.  Note that the number of bits of effective error detection
     code space is equal to -log_2 of the probability that an error would
     have violated the length-based checks above, plus the number of spare
     bits.  For the first quantity, we currently estimate that approximately
     half the number of bits used to signal the segment length are effective
     as error detection bits. */

  approximate_er_bits = 0;
  while ((1<<approximate_er_bits) < state->current_segment_bytes)
    approximate_er_bits++;
  approximate_er_bits >>= 1;
  approximate_er_bits += spare_bits;
  return(approximate_er_bits);
}


/* ========================================================================= */

⌨️ 快捷键说明

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