📄 jpg2kmqdecoder.cpp
字号:
#include "stdafx.h"
#include ".\jpg2kmqdecoder.h"
#include "JPG2KMQEState.h"
long CJPG2KMQDecoder::m_pBarTable[47] =
{
0x5601, 0x3401, 0x1801, 0x0AC1, 0x0521, 0x0221,
0x5601, 0x5401, 0x4801, 0x3801, 0x3001, 0x2401, 0x1C01, 0x1601,
0x5601, 0x5401, 0x5101, 0x4801, 0x3801, 0x3401, 0x3001, 0x2801,
0x2401, 0x2201, 0x1C01, 0x1801, 0x1601, 0x1401, 0x1201, 0x1101,
0x0AC1, 0x09C1, 0x08A1, 0x0521, 0x0441, 0x02A1, 0x0221, 0x0141,
0x0111, 0x0085, 0x0049, 0x0025, 0x0015, 0x0009, 0x0005, 0x0001,
0x5601
};
CJPG2KMQETransition CJPG2KMQDecoder::m_TransitionTable[94];
void CJPG2KMQDecoder::InitializeTransitionTable()
{
int Sigma_mps[47] =
{
1, 2, 3, 4, 5,38, 7, 8, 9,10,11,12,13,29,15,16,17,18,19,20,21,22,23,24,
25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,45,46
};
int Sigma_lps[47] =
{
1, 6, 9,12,29,33, 6,14,14,14,17,18,20,21,14,14,15,16,17,18,19,19,20,21,
22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,46
};
for (long n=0; n < 94; n++)
{
long s, new_s;
int Sigma, new_Sigma;
s = n & 1;
Sigma = n >> 1;
// Build MPS transition state first.
new_Sigma = Sigma_mps[Sigma];
new_s = s; // No switch on MPS transition.
m_TransitionTable[n].m_mps.InitDecoder(new_Sigma,new_s);
// Now build the LPS transition state.
new_Sigma = Sigma_lps[Sigma];
new_s = s;
if ((m_pBarTable[Sigma] == 0x5601) && (Sigma != 46))
new_s = 1-s;
m_TransitionTable[n].m_lps.InitDecoder(new_Sigma,new_s);
}
}
void CJPG2KMQDecoder::Start(LPBYTE pBuffer, int nSegmentLength, int bMQSegment)
{
m_bActive = 1;
m_bMQSegment = bMQSegment;
m_pBufStart = m_pBufNext = pBuffer;
m_nSegmentLength = nSegmentLength;
m_OverwrittenBytes[0] = pBuffer[nSegmentLength];
m_OverwrittenBytes[1] = pBuffer[nSegmentLength+1];
pBuffer[nSegmentLength] = pBuffer[nSegmentLength+1] = 0xFF; // Force termination
m_bCheckedOut = 0;
if (bMQSegment)
{
m_nS = m_temp = m_C = m_t = 0;
FillLsbs();
m_C <<= m_t;
FillLsbs();
m_C <<= 7;
m_t -= 7;
m_A = MQD_A_MIN;
}
else
{
m_t=0; m_temp = 0;
}
}
/*****************************************************************************/
/* CJPG2KMQDecoder::finish*/
/*****************************************************************************/
int CJPG2KMQDecoder::Finish(int nCheckErterm)
{
int failure = false;
if (nCheckErterm && m_bMQSegment)
{ // Check correct termination of MQ segment.
if (m_pBufNext <= (m_pBufStart+m_nSegmentLength))
failure = true; // We never read the terminating marker code
else
{
m_nS++; // Include first FF of marker code as a synthesized FF.
if (m_t == 0)
{
m_nS++;
m_t = 8;
}
if ((m_nS < 2) || (m_nS > 3) || ((m_C>>(24-m_t)) != 0))
failure = true;
}
}
else if (nCheckErterm)
{ // Check correct termination of raw segment.
long x = 0x55;
if ((m_pBufNext < (m_pBufStart+m_nSegmentLength)) &&
(m_temp == 0xFF) && (m_t == 0))
{ // Last byte may have been created by bit stuff.
m_temp = *(m_pBufNext++);
m_t = 8;
x = 0x2A;
}
if ((m_pBufNext != (m_pBufStart+m_nSegmentLength)) ||
((m_temp & ~((-1)<<m_t)) != (x>>(8-m_t))))
failure = true;
}
m_pBufStart[m_nSegmentLength] = m_OverwrittenBytes[0];
m_pBufStart[m_nSegmentLength+1] = m_OverwrittenBytes[1];
m_bActive = false;
m_pBufStart = m_pBufNext = NULL;
return !failure;
}
void CJPG2KMQDecoder::FillLsbs()
{
if (m_temp == 0xFF)
{ // Need to check for termination
m_temp = *(m_pBufNext++);
if (m_temp > 0x8F)
{ // Termination marker found.
m_temp = 0xFF;
m_pBufNext--;
m_t = 8;
m_nS++; // Increment S for each synthesized FF after 1'st byte of marker
}
else
{ // Bit stuff found
m_temp <<= 1;
m_t = 7;
}
}
else
{
m_temp = *(m_pBufNext++);
m_t = 8;
}
m_C += m_temp;
}
/*
Direct implementation of the first version given in Section 17.1.1 of the
book by Taubman and Marcellin. The macro implements the second
version of the decoding algorithm, which is substantially less
fathomable.
*/
void CJPG2KMQDecoder::MQDecode(long &symbol, CJPG2KMQEState &state)
{
symbol = state.m_p_bar_mps & 1; // Set to MPS for now.
long shifted_p_bar = state.m_p_bar_mps - symbol;
m_A -= shifted_p_bar;
if (m_C >= shifted_p_bar)
{ // Upper sub-interval selected
m_C -= shifted_p_bar;
if (m_A < MQD_A_MIN)
{ // Need renormalization and perhaps conditional exchange
if (m_A < shifted_p_bar)
{ // Conditional exchange; LPS decoded
symbol = 1-symbol;
state = state.m_pTransition->m_lps;
}
else
{ // MPS decoded
state = state.m_pTransition->m_mps;
}
do {
if (m_t == 0)
FillLsbs();
m_A += m_A;
m_C += m_C;
m_t--;
} while (m_A < MQD_A_MIN);
}
}
else
{ // Lower sub-interval selected; renormalization is inevitable
if (m_A < shifted_p_bar)
{ // Conditional exchange; MPS decoded
state = state.m_pTransition->m_mps;
}
else
{ // LPS decoded
symbol = 1-symbol;
state = state.m_pTransition->m_lps;
}
m_A = shifted_p_bar;
do {
if (m_t == 0)
FillLsbs();
m_A += m_A;
m_C += m_C;
m_t--;
} while (m_A < MQD_A_MIN);
}
}
/*****************************************************************************/
/*CJPG2KMQDecoder::mq_decode_run*/
/*****************************************************************************/
void CJPG2KMQDecoder::MQDecodeRun(long &run)
{
CJPG2KMQEState state;
long symbol;
state.InitDecoder(46,0);
MQDecode(symbol,state);
run = symbol + symbol;
MQDecode(symbol,state);
run += symbol;
}
/*****************************************************************************/
/*CJPG2KMQDecoder::raw_decode*/
/*****************************************************************************/
void CJPG2KMQDecoder::RawDecode(long &symbol)
{
if (m_t == 0){
if (m_temp == 0xFF){
// Need to check for terminating marker, FFFF
m_temp = *(m_pBufNext++);
if (m_temp == 0xFF)
{
m_pBufNext--;
m_t = 8;
}
else
m_t = 7;
}
else{
m_temp = *(m_pBufNext++);
m_t = 8;
}
}
m_t--;
symbol = (m_temp>>m_t)&1;
}
void CJPG2KMQDecoder::FillLsbs(long &C,long &t,long &temp,LPBYTE &store,long &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;
}
void CJPG2KMQDecoder::MQDecode(long &symbol,CJPG2KMQEState &state,long &A,long &C,
long &D,long &t,long &temp,LPBYTE &store,long &S)
{
symbol = (state).m_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).m_p_bar_mps - symbol;
if (C >= 0) /* True if and only if C_active >= 0 */
{ /* Upper sub-interval selected; must have A < A_min. */
if (A < D)
{ /* Conditional exchange; LPS is decoded */
symbol = 1-symbol;
state = (state).m_pTransition->m_lps;
}
else
{ /* MPS is decoded */
state = (state).m_pTransition->m_mps;
}
}
else
{ /* Lower sub-interval selected */
C += D; /* Put back p_bar */
if (A < D)
{ /* Conditional exchange; MPS is decoded */
state = (state).m_pTransition->m_mps;
}
else
{ /* LPS is decoded. */
symbol = 1-symbol;
state = (state).m_pTransition->m_lps;
}
A = D; /* Remeber that D is p_bar here. */
}
do {
if (t == 0)
FillLsbs(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. */
}
}
void CJPG2KMQDecoder::MQDecodeRun(long &run,long &A,long &C,long &D,
long &t,long &temp,LPBYTE &store,long &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. */
if (A < 0x00560100)
run = 2;
}
else
{ /* Lower sub-interval selected */
C += 0x00560100; /* Put back p_bar */
if (A >= 0x00560100)
run = 2;
A = 0x00560100;
}
do {
if (t == 0)
FillLsbs(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. */
if (A < 0x00560100)
run++;
}
else
{ /* Lower sub-interval selected */
C += 0x00560100; /* Put back p_bar */
if (A >= 0x00560100)
run++;
A = 0x00560100;
}
do {
if (t == 0)
FillLsbs(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. */
}
}
void CJPG2KMQDecoder::RawDecode(long &symbol,long &t,long &temp,LPBYTE &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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -