📄 mq_decoder.h
字号:
/*****************************************************************************/// File: mq_decoder.h [scope = CORESYS/CODING]// Version: Kakadu, V2.2// Author: David Taubman// Last Revised: 20 June, 2001/*****************************************************************************/// Copyright 2001, David Taubman, The University of New South Wales (UNSW)// The copyright owner is Unisearch Ltd, Australia (commercial arm of UNSW)// Neither this copyright statement, nor the licensing details below// may be removed from this file or dissociated from its contents./*****************************************************************************/// Licensee: Book Owner// License number: 99999// The Licensee has been granted a NON-COMMERCIAL license to the contents of// this source file, said Licensee being the owner of a copy of the book,// "JPEG2000: Image Compression Fundamentals, Standards and Practice," by// Taubman and Marcellin (Kluwer Academic Publishers, 2001). A brief summary// of the license appears below. This summary is not to be relied upon in// preference to the full text of the license agreement, which was accepted// upon breaking the seal of the compact disc accompanying the above-mentioned// book.// 1. The Licensee has the right to Non-Commercial Use of the Kakadu software,// Version 2.2, including distribution of one or more Applications built// using the software, provided such distribution is not for financial// return.// 2. The Licensee has the right to personal use of the Kakadu software,// Version 2.2.// 3. The Licensee has the right to distribute Reusable Code (including// source code and dynamically or statically linked libraries) to a Third// Party, provided the Third Party possesses a license to use the Kakadu// software, Version 2.2, and provided such distribution is not for// financial return./******************************************************************************Description: Defines interfaces for the low-level binary symbol operations associatedwith the MQ decoder. Includes, interfaces to support the arithetic coder bypassmode as well. Also includes macros which may be used as substitutes for thedecoding functions. Both the macros and the functions achieve the sameresult, although the macro implementation is more carefully tuned for speed,while the function implementation is somewhat more dydactic.******************************************************************************/#ifndef MQ_DECODER_H#define MQ_DECODER_H#include <assert.h>#include "kdu_messaging.h"// Defined here:struct mqd_state;struct mqd_transition;class mq_decoder;/* ========================================================================= *//* Constants *//* ========================================================================= */#define MQD_A_MIN ((kdu_int32)(1<<23)) // Lower bound for A register./* ========================================================================= *//* Class and Structure Definitions *//* ========================================================================= *//*****************************************************************************//* mqd_state *//*****************************************************************************/struct mqd_state { public: // Member functions void init(int Sigma, kdu_int32 s); // Inline implementation appears later /* `Sigma' is in the range 0 to 46 and `s' is the MPS identity. */ public: // Data kdu_int32 p_bar_mps; // Holds `p_bar' * 2^8 + `s' (`s' is the MPS: 0 or 1) mqd_transition *transition; }; /* Notes: This structure manages the state of the probability estimation state machine for a single coding context. The representation is redundant, of course, since all that is required is the value of `Sigma', in the range 0 to 46, and the value of MPS, `s' (0 or 1). However, this expanded representation avoids unnecessary de-referencing steps by the MQ decoder and so can significantly increase throughput. The `transition' pointer holds the address of the entry in `mq_decoder::transition_table' which corresponds to this element. There are 92 entries in the transition table, whose indices have the form `idx'=2*`Sigma'+s. If renormalization occurs while decoding an MPS, the state is updated according to state=state.transition->mps; if renormalization occurs while decoding an LPS, the state is updated according to state=state.transition->lps. The transition table is carefully constructed to ensure that all information is mapped correctly by this simple operation. *//*****************************************************************************//* mqd_transition *//*****************************************************************************/struct mqd_transition { /* See the definition of `mqd_state' for an explanation of this structure. */ mqd_state mps; mqd_state lps; };/*****************************************************************************//* mq_decoder *//*****************************************************************************/class mq_decoder { /* This object can be used for both MQ and raw codeword segments. */ public: // Member functions mq_decoder() { active = false; buf_start = buf_next = NULL; } void start(kdu_byte *start, int segment_length, bool MQ_segment); /* Start decoding a new MQ or raw codeword segment. On entry, `buffer' points to the first byte of the segment and `segment_length' indicates the total number of bytes in the segment. Note that the buffer must be long enough to accommodate 2 extra bytes beyond the stated length. During start up, the values of these 2 extra bytes are stored internally and overwritten with a termination marker. This has the effect of halving the number of tests which must be performed while consuming bytes. The original values of these two bytes are restored by `finish' call. */ bool finish(bool check_erterm=false); /* Each `start' call should be matched by a `finish' call. The function returns true, unless an error condition was detected. There is no way to detect an error unless we can assume something about the termination policy used by the encoder. When the predictable termination policy (ERTERM mode switch) has been used by the encoder, the `check_erterm' argument may be set to true and the function will perform the relevant tests. */ public: // Functions to check out state information for use with fast macros void check_out(kdu_int32 &A, kdu_int32 &C, kdu_int32 &D, kdu_int32 &t, kdu_int32 &temp, kdu_byte * &store, int &S) { // Use this form for MQ codeword segments. assert(active && (!checked_out) && MQ_segment); checked_out = true; A = this->A; C = this->C; D = A-MQD_A_MIN; D = (C<D)?C:D; A -= D; C -= D; t = this->t; temp = this->temp; store = this->buf_next; S = this->S; } void check_out(kdu_int32 &t, kdu_int32 &temp, kdu_byte * &store) { // Use this form for raw codeword segments. assert(active && (!checked_out) && !MQ_segment); checked_out = true; t = this->t; temp = this->temp; store = this->buf_next; } void check_in(kdu_int32 A, kdu_int32 C, kdu_int32 D, kdu_int32 t, kdu_int32 temp, kdu_byte *store, int S) { // Use this form for MQ codeword segments. assert(active && checked_out && MQ_segment); checked_out = false; this->A = A+D; this->C = C+D; this->t = t; this->temp = temp; this->buf_next = store; this->S = S; } void check_in(kdu_int32 t, kdu_int32 temp, kdu_byte *store) { // Use this form for raw codeword segments. assert(active && checked_out && !MQ_segment); checked_out = false; this->t = t; this->temp = temp; this->buf_next = store; } public: // Encoding functions. Note: use macros for the highest throughput void mq_decode(kdu_int32 &symbol, mqd_state &state); void mq_decode_run(kdu_int32 &run); // Decodes 2 bit run length, MSB first void raw_decode(kdu_int32 &symbol); private: void fill_lsbs(); /* Used by the `mq_decode' member function. */ public: // Probability estimation state machine. static kdu_int32 p_bar_table[47]; // Normalized LPS probabilities static mqd_transition transition_table[94]; // See defn of `mqd_transition' private: // Data kdu_int32 A; // The 8 MSB's and 8 LSB's of this word are guaranteed to be 0 kdu_int32 C; // The 8 MSB's of this word are guaranteed to be 0 kdu_int32 t; // This is "t_bar" in the book kdu_int32 temp; // This is "T_bar" in the book kdu_byte *buf_start, *buf_next; int S; // Number of synthesized FF's bool checked_out; bool MQ_segment; bool active; int segment_length; kdu_byte overwritten_bytes[2]; };/*****************************************************************************//* INLINE mqd_state::init *//*****************************************************************************/inline void mqd_state::init(int Sigma, kdu_int32 s){ assert((Sigma >= 0) && (Sigma <= 46) && (s == (s&1))); p_bar_mps = (mq_decoder::p_bar_table[Sigma] << 8) + s; transition = mq_decoder::transition_table + ((Sigma<<1) + s);}/* ========================================================================= *//* Fast Decoding Macros */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -