jpg2kmqencoder.h
来自「JPEG里MQ算术编码测试程序 编解码器 C」· C头文件 代码 · 共 214 行
H
214 行
#pragma once
#include "common.h"
class CJPG2KMQEState;
class CJPG2KMQETransition;
class CJPG2KMQEncoder
{
public:
CJPG2KMQEncoder(void)
{
m_bActive = 0;
m_pBufStart = m_pBufNext = NULL;
m_pPrev = m_pNext = NULL;
}
~CJPG2KMQEncoder(void);
/*
开始一个新的MQ或RAW码字段节。在开始的时候,pBuffer指向第一个码字节
写的位置。然而,小心的是,MQ码字段需要访问pBuffer前面的位置。
在这个位置的值是临时保存的,并且仅仅在Terminate成员调用的时候恢复。
为了允许访问pBuffer[-1],调用者应该注意分配码字空间。
这个buffer应该足够容纳压缩的输出。如果用户决定buffer需要增加,
使用augment_buffer函数。这个策略允许缓冲区的大小测试和潜在的
函数调用从时间关键的代码中删除。
*/
void Start(LPBYTE pBuffer, int bMQSegment);
/*
返回字start调用以后当前对象使用的buffer数量。
函数主要用来判断是否需要判断缓冲区重建;这里不是尝试判断截断长度。
*/
int GetBytesUsed()
{
return (int)(m_pBufNext - m_pBufStart);
}
/*
如果需要增加缓冲区大小的时候使用该函数。
首先你必须创建新的缓冲区并且复制缓冲区的内容到新的缓冲区中,然后
为使用该缓冲区的每个MQ Encoder调用该函数。
对象将更改其内部指针。pOldHandle和pNewHandle指针应该原来缓冲区和新
分配的缓冲区的开始位置。
*/
void AugmentBuffer(LPBYTE pOldHandle, LPBYTE pNewHandle)
{
if (m_pBufStart == NULL)
return; // Encoder finished working with buffer
m_pBufStart += (pNewHandle-pOldHandle);
m_pBufNext += (pNewHandle-pOldHandle);
}
/*
在超过当前编码过程时候,使用这个函数来连续编码段。
这在拥有同一个码字段的编码对象之间安装内部引用,从而便于
后来的截断点的计算。
*/
void Continues(CJPG2KMQEncoder *pPrev)
{
*this = *pPrev;
m_pPrev = pPrev; pPrev->m_pNext = this;
pPrev->m_bActive = 0;
}
/*
该函数产生这个对象产生的额外码字节,在连续链表上先前对象的连续点。
如果可能,函数为这个对象调用截断点优化算法,并且为那些没有截断点
的在连续列表中的对象也调用这个算法。
对于那些活动的对象或到目前位置产生少于5个额外字节的其他对象连续的
对象不能使用该算法。
如果截断点不可能,final参数设置为false并且函数返回一个合理的较低的
bound,其实是在连续点之前的放入的字节数量(或缓冲区的开始)。返回
值应该是非负的。
*/
int GetIncrementalLength(int &bFinal)
{
if(!m_bTruncationPointFound)
{
CJPG2KMQEncoder * pScanAhead = this;
while (pScanAhead->m_pNext != NULL)
pScanAhead = pScanAhead->m_pNext;
CJPG2KMQEncoder *pScanBack = pScanAhead;
for (; pScanBack != NULL; pScanBack=pScanBack->m_pPrev)
{
if (pScanBack->m_bTruncationPointFound)
break;
if ((!pScanBack->m_bActive) &&
((pScanAhead->m_pBufNext - pScanBack->m_pBufNext) >= 5))
pScanBack->FindTruncationPoint(pScanAhead->m_pBufNext);
}
}
bFinal = m_bTruncationPointFound;
if (m_pPrev == NULL)
return (int)(m_pBufNext - m_pBufStart);
else
return (int)(m_pBufNext - m_pPrev->m_pBufNext);
}
LPBYTE Terminate(int bOptimal);
/*
在一个码字段的最后一个元素上调用该函数。目的是复位段中的所有
对象来准备后面调用Start函数。
*/
void Finish()
{
CJPG2KMQEncoder *pScan, *pNextScan;
for (pScan=this; pScan != NULL; pScan = pNextScan)
{
pNextScan = pScan->m_pPrev;
pScan->m_pNext = pScan->m_pPrev = NULL;
pScan->m_bTruncationPointFound = false;
pScan->m_pBufStart = pScan->m_pBufNext = NULL;
}
}
public: // Functions to check out state information for use with fast macros
inline void CheckOut(long &A, long &C,long &t, long &temp, LPBYTE &ppStore)
{ // Use this form for MQ codeword segments.
A = this->m_A;
C = this->m_C;
t = this->m_t;
temp = this->m_temp;
ppStore = this->m_pBufNext;
}
inline void CheckOut(long &t, long &temp, LPBYTE &ppStore)
{ // Use this form for raw codeword segments.
m_bCheckedOut = 1;
t = this->m_t;
temp = this->m_temp;
ppStore = this->m_pBufNext;
}
inline void CheckIn(long A, long C,long t, long temp, LPBYTE ppStore)
{ // Use this form for MQ codeword segments.
m_bCheckedOut = 0;
this->m_A = A;
this->m_C = C;
this->m_t = t;
this->m_temp = temp;
this->m_pBufNext = ppStore;
}
inline void CheckIn(long t, long temp, LPBYTE ppStore)
{ // Use this form for raw codeword segments.
m_bCheckedOut = 0;
this->m_t = t;
this->m_temp = temp;
this->m_pBufNext = ppStore;
}
public:
/* Note that symbol must be 0 or KDU_INT32_MIN */
void MQEncode(long symbol, CJPG2KMQEState &state);
//instead of macro
void MQEncode(long &lps_p_bar,CJPG2KMQEState &state,long &A,
long &C,long &t,long &temp,LPBYTE &store);
//instead of macro
void MQEncodeRun(long &run,long &A,long &C,long &t,long &temp,LPBYTE &store);
// Encodes a 2 bit run length, MSB first
void MQEncodeRun(long run);
/* Note that symbol must be 0 or 1. */
void RawEncode(long symbol);
//instead of macro
void RawEncode(long &symbol,long &t,long &temp,LPBYTE &store);
private:
/* Used by the `MQEncode' member function. */
void TransferByte();
void TransferByte(long &C,long &t,long &temp,LPBYTE &store);
public: // Probability estimation state machine.
static long m_pBarTable[47]; // Normalized LPS probabilities
static CJPG2KMQETransition m_TransitionTable[94]; // See def'n of `mqe_transition'
static void InitializeTransitionTable();
private: // Internal functions
/*
这个函数在Terminate中自动被调用来为连续的码字段检查最优的截断点。
(也可以用到非连续的码字段上来检查最小的段长度)。这个函数在
GetFinalLength中也被调用。
pLimit参数指向已经终止的码字段最后一个字节后面;仅仅访问该位置
前的访问是合法的。
*/
void FindTruncationPoint(LPBYTE plimit);
private:
long m_A; // Only the least significant 16 bits of A are used
long m_C; // Holds a 28 bit number (including the carry bit)
long m_t; // This is "t_bar" in the book
long m_temp; // This is "T_bar" in the book
LPBYTE m_pBufStart;
LPBYTE m_pBufNext;
BYTE m_nOverwrittenByte;
int m_bCheckedOut;
int m_bMQSegment;
int m_bActive;
int m_bTruncationPointFound;
CJPG2KMQEncoder *m_pPrev; // Point from which coding continues in same segment
CJPG2KMQEncoder *m_pNext; // Point to which coding continues in next segment
};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?