📄 mq_decoder.h
字号:
/* ========================================================================= *//* Note: although in-lining is preferable, most compilers fail to realize the full speed potential of macros. These are critical to the overall system throughput and also to the size of the code fragment which gets executed inside the coding pass loops. *//*****************************************************************************//* MACRO _mqd_fill_lsbs_ *//*****************************************************************************/ /* Implements the Fill-LSBs procedure described in Section 12.1.3 of the book by Taubman and Marcellin. The implementation differs only in that we can be certain that the codeword segment will be terminated by a marker code in the range 0xFF90 through 0xFFFF. This is because a synthetic marker is temporarily inserted at the end of the segment. */#define _mqd_fill_lsbs_(C,t,temp,store,S) \ { \ t = 8; \ if (temp == 0xFF) \ { /* Only need to check for termination inside here. */ \ temp = *(store++); \ if (temp > 0x8F) /* Termination marker: remain here indefinitely. */ \ { temp = 0xFF; store--; S++; } \ else \ { t = 7; C += temp; } /* This way, we add two copies of `temp' */ \ } \ else \ temp = *(store++); \ C += temp; \ }/*****************************************************************************//* MACRO _mq_decode_ *//*****************************************************************************/ /* Implementation of the CDP (Common Decoding Path) optimized algorithm suggested in Section 17.1.1 of the book by Taubman and Marcellin. The idea is that D accumulates the p_bar quantities associated with consecutive CDP symbols, whose subtraction from both A and C is delayed until the next non-CDP symbol occurs. C_min holds the minimum of C and (A-2^15), from the point when the last non-CDP symbol was coded. Thus, so long as D <= C_min, an MPS is decoded without renormalization (and hence without conditional exchange either). On return, `symbol' holds either 1 or 0. */ /* If your compiler and architecture support the allocation of registers for critical variables, it is recommended that `symbol', `state', `D', `A' and `C' be allocated registers, in that order. */#define _mq_decode_(symbol,state,A,C,D,t,temp,store,S) \ { \ symbol = (state).p_bar_mps; \ D -= symbol; symbol &= 1; D += symbol; \ if (D < 0) \ { /* Non-CDP decoding follows. Renormalization is inevitable. */ \ A += D; C += D; \ D = (state).p_bar_mps - symbol; \ if (C >= 0) /* True if and only if C_active >= 0 */ \ { /* Upper sub-interval selected; must have A < A_min. */ \ assert (A < MQD_A_MIN); \ if (A < D) \ { /* Conditional exchange; LPS is decoded */ \ symbol = 1-symbol; \ state = (state).transition->lps; \ } \ else \ { /* MPS is decoded */ \ state = (state).transition->mps; \ } \ } \ else \ { /* Lower sub-interval selected */ \ C += D; /* Put back p_bar */ \ if (A < D) \ { /* Conditional exchange; MPS is decoded */ \ state = (state).transition->mps; \ } \ else \ { /* LPS is decoded. */ \ symbol = 1-symbol; \ state = (state).transition->lps; \ } \ A = D; /* Remeber that D is p_bar here. */ \ } \ assert(A < MQD_A_MIN); /* Need renormalization */ \ do { \ if (t == 0) \ _mqd_fill_lsbs_(C,t,temp,store,S); \ A += A; C += C; t--; \ } while (A < MQD_A_MIN); \ D = A-MQD_A_MIN; \ if (C < D) \ D = C; \ A -= D; C -= D; /* We will add D back again at the next non-CDP. */ \ } \ }/*****************************************************************************//* MACRO _mq_decode_run_ *//*****************************************************************************/ /* Specialization of _mq_decode_ to the case where the state is equal to the special non-adaptive MQ coder state (last state in transition table); decodes two symbols to recover a 2-bit run length, with the first symbol forming the most significant bit of the run. */#define _mq_decode_run_(run,A,C,D,t,temp,store,S) \ { \ run = 0; \ D -= 0x00560100; \ if (D < 0) \ { /* Non-CDP decoding follows. Renormalization is inevitable. */ \ A += D; C += D; \ if (C >= 0) /* True if and only if C_active >= 0 */ \ { /* Upper sub-interval selected; must have A < A_min. */ \ assert (A < MQD_A_MIN); \ if (A < 0x00560100) \ run = 2; \ } \ else \ { /* Lower sub-interval selected */ \ C += 0x00560100; /* Put back p_bar */ \ if (A >= 0x00560100) \ run = 2; \ A = 0x00560100; \ } \ assert(A < MQD_A_MIN); /* Need renormalization */ \ do { \ if (t == 0) \ _mqd_fill_lsbs_(C,t,temp,store,S); \ A += A; C += C; t--; \ } while (A < MQD_A_MIN); \ D = A-MQD_A_MIN; \ if (C < D) \ D = C; \ A -= D; C -= D; /* We will add D back again at the next non-CDP. */ \ } \ D -= 0x00560100; \ if (D < 0) \ { /* Non-CDP decoding follows. Renormalization is inevitable. */ \ A += D; C += D; \ if (C >= 0) /* True if and only if C_active >= 0 */ \ { /* Upper sub-interval selected; must have A < A_min. */ \ assert (A < MQD_A_MIN); \ if (A < 0x00560100) \ run++; \ } \ else \ { /* Lower sub-interval selected */ \ C += 0x00560100; /* Put back p_bar */ \ if (A >= 0x00560100) \ run++; \ A = 0x00560100; \ } \ assert(A < MQD_A_MIN); /* Need renormalization */ \ do { \ if (t == 0) \ _mqd_fill_lsbs_(C,t,temp,store,S); \ A += A; C += C; t--; \ } while (A < MQD_A_MIN); \ D = A-MQD_A_MIN; \ if (C < D) \ D = C; \ A -= D; C -= D; /* We will add D back again at the next non-CDP. */ \ } \ }/*****************************************************************************//* MACRO _raw_decode_ *//*****************************************************************************/#define _raw_decode_(symbol,t,temp,store) \ { \ if (t == 0) \ { \ t = 8; \ if (temp == 0xFF) \ { /* Need to check for terminating marker (we use FFFF). */ \ temp = *(store++); \ if (temp == 0xFF) \ store--; \ else \ t = 7; \ } \ else \ temp = *(store++); \ } \ t--; \ symbol = (temp>>t) & 1; \ }#endif // MQ_DECODER_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -