Files
core/ASCImageStudio3/ASCImageJpeg2000/ArithmeticCoder.h
Elen.Subbotina 70e623d70b восстановление
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@62634 954022d7-b5bf-4e40-9824-e11837661b57
2016-05-21 00:05:02 +03:00

549 lines
16 KiB
C

#pragma once
#include "Types.h"
#include "Utils.h"
//-------------------------------------------------------------------------------------------------------------------------------
// Äàííûé ìàññèâ ñîäåðæèò âñå âîçìîæíûå ñîñòîÿíèå (ñì. Annex C Table C-2)
static MQCoderState aoMQCoderStates[47 * 2] =
{
{ 0x5601, 0, &aoMQCoderStates[2], &aoMQCoderStates[3] },
{ 0x5601, 1, &aoMQCoderStates[3], &aoMQCoderStates[2] },
{ 0x3401, 0, &aoMQCoderStates[4], &aoMQCoderStates[12] },
{ 0x3401, 1, &aoMQCoderStates[5], &aoMQCoderStates[13] },
{ 0x1801, 0, &aoMQCoderStates[6], &aoMQCoderStates[18] },
{ 0x1801, 1, &aoMQCoderStates[7], &aoMQCoderStates[19] },
{ 0x0ac1, 0, &aoMQCoderStates[8], &aoMQCoderStates[24] },
{ 0x0ac1, 1, &aoMQCoderStates[9], &aoMQCoderStates[25] },
{ 0x0521, 0, &aoMQCoderStates[10], &aoMQCoderStates[58] },
{ 0x0521, 1, &aoMQCoderStates[11], &aoMQCoderStates[59] },
{ 0x0221, 0, &aoMQCoderStates[76], &aoMQCoderStates[66] },
{ 0x0221, 1, &aoMQCoderStates[77], &aoMQCoderStates[67] },
{ 0x5601, 0, &aoMQCoderStates[14], &aoMQCoderStates[13] },
{ 0x5601, 1, &aoMQCoderStates[15], &aoMQCoderStates[12] },
{ 0x5401, 0, &aoMQCoderStates[16], &aoMQCoderStates[28] },
{ 0x5401, 1, &aoMQCoderStates[17], &aoMQCoderStates[29] },
{ 0x4801, 0, &aoMQCoderStates[18], &aoMQCoderStates[28] },
{ 0x4801, 1, &aoMQCoderStates[19], &aoMQCoderStates[29] },
{ 0x3801, 0, &aoMQCoderStates[20], &aoMQCoderStates[28] },
{ 0x3801, 1, &aoMQCoderStates[21], &aoMQCoderStates[29] },
{ 0x3001, 0, &aoMQCoderStates[22], &aoMQCoderStates[34] },
{ 0x3001, 1, &aoMQCoderStates[23], &aoMQCoderStates[35] },
{ 0x2401, 0, &aoMQCoderStates[24], &aoMQCoderStates[36] },
{ 0x2401, 1, &aoMQCoderStates[25], &aoMQCoderStates[37] },
{ 0x1c01, 0, &aoMQCoderStates[26], &aoMQCoderStates[40] },
{ 0x1c01, 1, &aoMQCoderStates[27], &aoMQCoderStates[41] },
{ 0x1601, 0, &aoMQCoderStates[58], &aoMQCoderStates[42] },
{ 0x1601, 1, &aoMQCoderStates[59], &aoMQCoderStates[43] },
{ 0x5601, 0, &aoMQCoderStates[30], &aoMQCoderStates[29] },
{ 0x5601, 1, &aoMQCoderStates[31], &aoMQCoderStates[28] },
{ 0x5401, 0, &aoMQCoderStates[32], &aoMQCoderStates[28] },
{ 0x5401, 1, &aoMQCoderStates[33], &aoMQCoderStates[29] },
{ 0x5101, 0, &aoMQCoderStates[34], &aoMQCoderStates[30] },
{ 0x5101, 1, &aoMQCoderStates[35], &aoMQCoderStates[31] },
{ 0x4801, 0, &aoMQCoderStates[36], &aoMQCoderStates[32] },
{ 0x4801, 1, &aoMQCoderStates[37], &aoMQCoderStates[33] },
{ 0x3801, 0, &aoMQCoderStates[38], &aoMQCoderStates[34] },
{ 0x3801, 1, &aoMQCoderStates[39], &aoMQCoderStates[35] },
{ 0x3401, 0, &aoMQCoderStates[40], &aoMQCoderStates[36] },
{ 0x3401, 1, &aoMQCoderStates[41], &aoMQCoderStates[37] },
{ 0x3001, 0, &aoMQCoderStates[42], &aoMQCoderStates[38] },
{ 0x3001, 1, &aoMQCoderStates[43], &aoMQCoderStates[39] },
{ 0x2801, 0, &aoMQCoderStates[44], &aoMQCoderStates[38] },
{ 0x2801, 1, &aoMQCoderStates[45], &aoMQCoderStates[39] },
{ 0x2401, 0, &aoMQCoderStates[46], &aoMQCoderStates[40] },
{ 0x2401, 1, &aoMQCoderStates[47], &aoMQCoderStates[41] },
{ 0x2201, 0, &aoMQCoderStates[48], &aoMQCoderStates[42] },
{ 0x2201, 1, &aoMQCoderStates[49], &aoMQCoderStates[43] },
{ 0x1c01, 0, &aoMQCoderStates[50], &aoMQCoderStates[44] },
{ 0x1c01, 1, &aoMQCoderStates[51], &aoMQCoderStates[45] },
{ 0x1801, 0, &aoMQCoderStates[52], &aoMQCoderStates[46] },
{ 0x1801, 1, &aoMQCoderStates[53], &aoMQCoderStates[47] },
{ 0x1601, 0, &aoMQCoderStates[54], &aoMQCoderStates[48] },
{ 0x1601, 1, &aoMQCoderStates[55], &aoMQCoderStates[49] },
{ 0x1401, 0, &aoMQCoderStates[56], &aoMQCoderStates[50] },
{ 0x1401, 1, &aoMQCoderStates[57], &aoMQCoderStates[51] },
{ 0x1201, 0, &aoMQCoderStates[58], &aoMQCoderStates[52] },
{ 0x1201, 1, &aoMQCoderStates[59], &aoMQCoderStates[53] },
{ 0x1101, 0, &aoMQCoderStates[60], &aoMQCoderStates[54] },
{ 0x1101, 1, &aoMQCoderStates[61], &aoMQCoderStates[55] },
{ 0x0ac1, 0, &aoMQCoderStates[62], &aoMQCoderStates[56] },
{ 0x0ac1, 1, &aoMQCoderStates[63], &aoMQCoderStates[57] },
{ 0x09c1, 0, &aoMQCoderStates[64], &aoMQCoderStates[58] },
{ 0x09c1, 1, &aoMQCoderStates[65], &aoMQCoderStates[59] },
{ 0x08a1, 0, &aoMQCoderStates[66], &aoMQCoderStates[60] },
{ 0x08a1, 1, &aoMQCoderStates[67], &aoMQCoderStates[61] },
{ 0x0521, 0, &aoMQCoderStates[68], &aoMQCoderStates[62] },
{ 0x0521, 1, &aoMQCoderStates[69], &aoMQCoderStates[63] },
{ 0x0441, 0, &aoMQCoderStates[70], &aoMQCoderStates[64] },
{ 0x0441, 1, &aoMQCoderStates[71], &aoMQCoderStates[65] },
{ 0x02a1, 0, &aoMQCoderStates[72], &aoMQCoderStates[66] },
{ 0x02a1, 1, &aoMQCoderStates[73], &aoMQCoderStates[67] },
{ 0x0221, 0, &aoMQCoderStates[74], &aoMQCoderStates[68] },
{ 0x0221, 1, &aoMQCoderStates[75], &aoMQCoderStates[69] },
{ 0x0141, 0, &aoMQCoderStates[76], &aoMQCoderStates[70] },
{ 0x0141, 1, &aoMQCoderStates[77], &aoMQCoderStates[71] },
{ 0x0111, 0, &aoMQCoderStates[78], &aoMQCoderStates[72] },
{ 0x0111, 1, &aoMQCoderStates[79], &aoMQCoderStates[73] },
{ 0x0085, 0, &aoMQCoderStates[80], &aoMQCoderStates[74] },
{ 0x0085, 1, &aoMQCoderStates[81], &aoMQCoderStates[75] },
{ 0x0049, 0, &aoMQCoderStates[82], &aoMQCoderStates[76] },
{ 0x0049, 1, &aoMQCoderStates[83], &aoMQCoderStates[77] },
{ 0x0025, 0, &aoMQCoderStates[84], &aoMQCoderStates[78] },
{ 0x0025, 1, &aoMQCoderStates[85], &aoMQCoderStates[79] },
{ 0x0015, 0, &aoMQCoderStates[86], &aoMQCoderStates[80] },
{ 0x0015, 1, &aoMQCoderStates[87], &aoMQCoderStates[81] },
{ 0x0009, 0, &aoMQCoderStates[88], &aoMQCoderStates[82] },
{ 0x0009, 1, &aoMQCoderStates[89], &aoMQCoderStates[83] },
{ 0x0005, 0, &aoMQCoderStates[90], &aoMQCoderStates[84] },
{ 0x0005, 1, &aoMQCoderStates[91], &aoMQCoderStates[85] },
{ 0x0001, 0, &aoMQCoderStates[90], &aoMQCoderStates[86] },
{ 0x0001, 1, &aoMQCoderStates[91], &aoMQCoderStates[87] },
{ 0x5601, 0, &aoMQCoderStates[92], &aoMQCoderStates[92] },
{ 0x5601, 1, &aoMQCoderStates[93], &aoMQCoderStates[93] },
};
//-------------------------------------------------------------------------------------------------------------------------------
// Âñïîìîãàòåëüíûå ôóíêöèè
//-------------------------------------------------------------------------------------------------------------------------------
static void MQC_ByteOut(MQCoder *pMQCoder)
{
if ( *pMQCoder->pBufferPointer == 0xff )
{
pMQCoder->pBufferPointer++;
*pMQCoder->pBufferPointer = pMQCoder->nCregister >> 20;
pMQCoder->nCregister &= 0xfffff;
pMQCoder->nCt = 7;
}
else
{
if ( ( pMQCoder->nCregister & 0x8000000 ) == 0 ) // CHANGE
{
pMQCoder->pBufferPointer++;
*pMQCoder->pBufferPointer = pMQCoder->nCregister >> 19;
pMQCoder->nCregister &= 0x7ffff;
pMQCoder->nCt = 8;
}
else
{
(*pMQCoder->pBufferPointer)++;
if ( *pMQCoder->pBufferPointer == 0xff )
{
pMQCoder->nCregister &= 0x7ffffff;
pMQCoder->pBufferPointer++;
*pMQCoder->pBufferPointer = pMQCoder->nCregister >> 20;
pMQCoder->nCregister &= 0xfffff;
pMQCoder->nCt = 7;
}
else
{
pMQCoder->pBufferPointer++;
*pMQCoder->pBufferPointer = pMQCoder->nCregister >> 19;
pMQCoder->nCregister &= 0x7ffff;
pMQCoder->nCt = 8;
}
}
}
}
static void MQC_RenormE(MQCoder *pMQCoder)
{
do
{
pMQCoder->nAregister <<= 1;
pMQCoder->nCregister <<= 1;
pMQCoder->nCt--;
if ( 0 == pMQCoder->nCt )
{
MQC_ByteOut( pMQCoder );
}
} while ( (pMQCoder->nAregister & 0x8000) == 0 );
}
static void MQC_CodeMPS(MQCoder *pMQCoder)
{
pMQCoder->nAregister -= (*pMQCoder->ppCurContext)->nLPSValue;
if ( (pMQCoder->nAregister & 0x8000) == 0 )
{
if ( pMQCoder->nAregister < (*pMQCoder->ppCurContext)->nLPSValue )
{
pMQCoder->nAregister = (*pMQCoder->ppCurContext)->nLPSValue;
}
else
{
pMQCoder->nCregister += (*pMQCoder->ppCurContext)->nLPSValue;
}
*pMQCoder->ppCurContext = (*pMQCoder->ppCurContext)->pNextMPS;
MQC_RenormE( pMQCoder );
}
else
{
pMQCoder->nCregister += (*pMQCoder->ppCurContext)->nLPSValue;
}
}
static void MQC_CodeLPS(MQCoder *pMQCoder)
{
pMQCoder->nAregister -= (*pMQCoder->ppCurContext)->nLPSValue;
if ( pMQCoder->nAregister < (*pMQCoder->ppCurContext)->nLPSValue )
{
pMQCoder->nCregister += (*pMQCoder->ppCurContext)->nLPSValue;
}
else
{
pMQCoder->nAregister = (*pMQCoder->ppCurContext)->nLPSValue;
}
*pMQCoder->ppCurContext = (*pMQCoder->ppCurContext)->pNextLPS;
MQC_RenormE( pMQCoder );
}
static void MQC_SetBits(MQCoder *pMQCoder)
{
unsigned int nTempCode = pMQCoder->nCregister + pMQCoder->nAregister;
pMQCoder->nCregister |= 0xffff;
if ( pMQCoder->nCregister >= nTempCode )
{
pMQCoder->nCregister -= 0x8000;
}
}
static int MQC_MPSExchange(MQCoder *pMQCoder)
{
int nResult = 0;
if ( pMQCoder->nAregister < (*pMQCoder->ppCurContext)->nLPSValue )
{
nResult = 1 - (*pMQCoder->ppCurContext)->nMPS;
*pMQCoder->ppCurContext = (*pMQCoder->ppCurContext)->pNextLPS;
}
else
{
nResult = (*pMQCoder->ppCurContext)->nMPS;
*pMQCoder->ppCurContext = (*pMQCoder->ppCurContext)->pNextMPS;
}
return nResult;
}
static int MQC_LPSExchange(MQCoder *pMQCoder)
{
int nResult = 0;
if ( pMQCoder->nAregister < (*pMQCoder->ppCurContext)->nLPSValue )
{
pMQCoder->nAregister = (*pMQCoder->ppCurContext)->nLPSValue;
nResult = (*pMQCoder->ppCurContext)->nMPS;
*pMQCoder->ppCurContext = (*pMQCoder->ppCurContext)->pNextMPS;
}
else
{
pMQCoder->nAregister = (*pMQCoder->ppCurContext)->nLPSValue;
nResult = 1 - (*pMQCoder->ppCurContext)->nMPS;
*pMQCoder->ppCurContext = (*pMQCoder->ppCurContext)->pNextLPS;
}
return nResult;
}
static void MQC_ByteIn(MQCoder *pMQCoder)
{
if ( pMQCoder->pBufferPointer != pMQCoder->pEnd )
{
unsigned int nCode = 0;
if ( pMQCoder->pBufferPointer + 1 != pMQCoder->pEnd )
{
nCode = *(pMQCoder->pBufferPointer + 1);
}
else
{
nCode = 0xff;
}
if ( *pMQCoder->pBufferPointer == 0xff )
{
if ( nCode > 0x8f )
{
pMQCoder->nCregister += 0xff00;
pMQCoder->nCt = 8;
}
else
{
pMQCoder->pBufferPointer++;
pMQCoder->nCregister += nCode << 9;
pMQCoder->nCt = 7;
}
}
else
{
pMQCoder->pBufferPointer++;
pMQCoder->nCregister += nCode << 8;
pMQCoder->nCt = 8;
}
}
else
{
pMQCoder->nCregister += 0xff00;
pMQCoder->nCt = 8;
}
}
static void MQC_RenormD(MQCoder *pMQCoder)
{
do
{
if ( pMQCoder->nCt == 0 )
{
MQC_ByteIn( pMQCoder );
}
pMQCoder->nAregister <<= 1;
pMQCoder->nCregister <<= 1;
pMQCoder->nCt--;
} while ( pMQCoder->nAregister < 0x8000 );
}
//-------------------------------------------------------------------------------------------------------------------------------
// Îñíîâíûå ôóíêöèè
//-------------------------------------------------------------------------------------------------------------------------------
MQCoder* MQC_Create()
{
MQCoder *pCoder = (MQCoder*)Malloc(HEAP_ZERO_MEMORY, sizeof(MQCoder));
return pCoder;
}
void MQC_Destroy(MQCoder *pMQCoder)
{
RELEASEHEAP( pMQCoder );
}
int MQC_BytesCount(MQCoder *pMQCoder)
{
return pMQCoder->pBufferPointer - pMQCoder->pStart;
}
void MQC_ResetStates(MQCoder *pMQCoder)
{
for ( int nIndex = 0; nIndex < MQC_NUMCTXS; nIndex++ )
{
pMQCoder->pContexts[nIndex] = aoMQCoderStates;
}
}
void MQC_SetState(MQCoder *pMQCoder, int nContextIndex, int nMSB, int nProb)
{
pMQCoder->pContexts[nContextIndex] = &aoMQCoderStates[nMSB + (nProb << 1)];
}
void MQC_SetCurContext(MQCoder *pMQCoder, int nContextIndex)
{
pMQCoder->ppCurContext = &pMQCoder->pContexts[nContextIndex];
}
void MQC_InitEncoder(MQCoder *pMQCoder, unsigned char *pBufferPointer)
{
MQC_SetCurContext( pMQCoder, 0 );
pMQCoder->nAregister = 0x8000;
pMQCoder->nCregister = 0;
pMQCoder->pBufferPointer = pBufferPointer - 1;
pMQCoder->nCt = 12;
if ( *pMQCoder->pBufferPointer == 0xff )
{
pMQCoder->nCt = 13;
}
pMQCoder->pStart = pBufferPointer;
}
void MQC_Encode(MQCoder *pMQCoder, int nValue)
{
if ( (*pMQCoder->ppCurContext)->nMPS == nValue )
{
MQC_CodeMPS( pMQCoder );
}
else
{
MQC_CodeLPS( pMQCoder );
}
}
void MQC_Flush(MQCoder *pMQCoder)
{
MQC_SetBits( pMQCoder );
pMQCoder->nCregister <<= pMQCoder->nCt;
MQC_ByteOut( pMQCoder );
pMQCoder->nCregister <<= pMQCoder->nCt;
MQC_ByteOut( pMQCoder );
if ( *pMQCoder->pBufferPointer != 0xff )
{
pMQCoder->pBufferPointer++;
}
}
void MQC_BypassInitEncoder(MQCoder *pMQCoder)
{
// TO DO: Äàííàÿ ôóíêöèÿ íåïîëüíîñòüþ ïðîòåñòèðîâàíà
pMQCoder->nCregister = 0;
pMQCoder->nCt = 8;
/*
if ( *pMQCoder->bp == 0xff )
{
pMQCoder->ct = 7;
}
*/
}
void MQC_BypassEncoder(MQCoder *pMQCoder, int nValue)
{
// TO DO: Äàííàÿ ôóíêöèÿ íåïîëüíîñòüþ ïðîòåñòèðîâàíà
pMQCoder->nCt--;
pMQCoder->nCregister = pMQCoder->nCregister + (nValue << pMQCoder->nCt);
if ( pMQCoder->nCt == 0 )
{
pMQCoder->pBufferPointer++;
*pMQCoder->pBufferPointer = pMQCoder->nCregister;
pMQCoder->nCt = 8;
if ( *pMQCoder->pBufferPointer == 0xff )
{
pMQCoder->nCt = 7;
}
pMQCoder->nCregister = 0;
}
}
int MQC_BypassFlushEncoder(MQCoder *pMQCoder)
{
// TO DO: Äàííàÿ ôóíêöèÿ íåïîëüíîñòüþ ïðîòåñòèðîâàíà
unsigned char nBitPadding = 0;
if ( pMQCoder->nCt != 0 )
{
while ( pMQCoder->nCt > 0 )
{
pMQCoder->nCt--;
pMQCoder->nCregister += nBitPadding << pMQCoder->nCt;
nBitPadding = (nBitPadding + 1) & 0x01;
}
pMQCoder->pBufferPointer++;
*pMQCoder->pBufferPointer = pMQCoder->nCregister;
pMQCoder->nCt = 8;
pMQCoder->nCregister = 0;
}
return 1;
}
void MQC_ResetEncoder(MQCoder *pMQCoder)
{
MQC_ResetStates( pMQCoder );
MQC_SetState( pMQCoder, 18, 0, 46 );
MQC_SetState( pMQCoder, 0, 0, 3 );
MQC_SetState( pMQCoder, 1, 0, 4 );
}
int MQC_RestartEncoder(MQCoder *pMQCoder)
{
int nCorrection = 1;
int nLen = 27 - 15 - pMQCoder->nCt;
pMQCoder->nCregister <<= pMQCoder->nCt;
while ( nLen > 0 )
{
MQC_ByteOut( pMQCoder );
nLen -= pMQCoder->nCt;
pMQCoder->nCregister <<= pMQCoder->nCt;
}
MQC_ByteOut( pMQCoder );
return nCorrection;
}
void MQC_RestartInitEncoder(MQCoder *pMQCoder)
{
MQC_SetCurContext( pMQCoder, 0 );
pMQCoder->nAregister = 0x8000;
pMQCoder->nCregister = 0;
pMQCoder->nCt = 12;
pMQCoder->pBufferPointer--;
if ( *pMQCoder->pBufferPointer == 0xff )
{
pMQCoder->nCt = 13;
}
}
void MQC_ErtermEncoder(MQCoder *pMQCoder)
{
int nK = 11 - pMQCoder->nCt + 1;
while ( nK > 0 )
{
pMQCoder->nCregister <<= pMQCoder->nCt;
pMQCoder->nCt = 0;
MQC_ByteOut( pMQCoder );
nK -= pMQCoder->nCt;
}
if ( *pMQCoder->pBufferPointer != 0xff )
{
MQC_ByteOut( pMQCoder );
}
}
void MQC_SegMarkEncoder(MQCoder *pMQCoder)
{
MQC_SetCurContext( pMQCoder, 18 );
for ( int nIndex = 1; nIndex < 5; nIndex++ )
{
MQC_Encode( pMQCoder, nIndex % 2 );
}
}
void MQC_InitDecoder(MQCoder *pMQCoder, unsigned char *nBufferPointer, int nLen)
{
MQC_SetCurContext( pMQCoder, 0 );
pMQCoder->pStart = nBufferPointer;
pMQCoder->pEnd = nBufferPointer + nLen;
pMQCoder->pBufferPointer = nBufferPointer;
if ( 0 == nLen )
pMQCoder->nCregister = 0xff << 16;
else
pMQCoder->nCregister = *pMQCoder->pBufferPointer << 16;
MQC_ByteIn( pMQCoder );
pMQCoder->nCregister <<= 7;
pMQCoder->nCt -= 7;
pMQCoder->nAregister = 0x8000;
}
int MQC_Decode(MQCoder *pMQCoder)
{
int nResult = 0;
pMQCoder->nAregister -= (*pMQCoder->ppCurContext)->nLPSValue;
if ( (pMQCoder->nCregister >> 16) < (*pMQCoder->ppCurContext)->nLPSValue )
{
nResult = MQC_LPSExchange( pMQCoder );
MQC_RenormD( pMQCoder );
}
else
{
pMQCoder->nCregister -= (*pMQCoder->ppCurContext)->nLPSValue << 16;
if ( (pMQCoder->nAregister & 0x8000) == 0 )
{
nResult = MQC_MPSExchange( pMQCoder );
MQC_RenormD( pMQCoder );
}
else
{
nResult = (*pMQCoder->ppCurContext)->nMPS;
}
}
return nResult;
}