|
|
#include "stdafx.h"
#pragma hdrstop
#include "ctable.h"
// acLeadingZeroes gives the low order zeroes before the first
// one bit in a byte value.
extern char bCharTypes[];
BYTE acLeadingZeroes[256] = { 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 };
// Count of one leading one bits in lower half byte, going right to left.
BYTE acOneBits[16] = { 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4 };
CCompressTable *CCompressTable::NewCompressTable(HGLOBAL hImage, LONG cbImage, HGLOBAL hIndex, LONG cbIndex) { CCompressTable *pct = new CCompressTable();
JBITHDR jIHdr; int iWeightCount; int base; LPSTR lpIndex = (LPSTR) GlobalLock(hIndex); int ii; char *hlpImage; LPSTR lpImage; BOOL bSkip = (cbImage > (64L * 1024L)) ? TRUE : FALSE; int cb;
ASSERT(pct);
pct->m_hImage = hImage;
hlpImage = (char *) GlobalLock(hImage); lpImage = (LPSTR) hlpImage;
jIHdr = *((JBITHDR *) lpIndex); ASSERT(jIHdr.Magic == 'J');
base = (int) jIHdr.cBits; iWeightCount = (int) jIHdr.cCount; lpIndex += sizeof(jIHdr);
//
// This must be less than 64K.
//
pct->m_hWeight = GlobalAlloc(GMEM_FIXED, sizeof(WEIGHT) * iWeightCount);
PWEIGHTS pWeights = (PWEIGHTS) GlobalLock(pct->m_hWeight);
CJCode JCode(base, iWeightCount, (LPSTR) lpIndex);
for (ii = 0; ii < iWeightCount; ii++) { cb = JCode.GetNextDelta(); pWeights[ii].cb = cb; pWeights[ii].pb = (LPSTR) lpImage; if (bCharTypes[*(pWeights[ii].pb)] & SYMBOL_CHAR) pWeights[ii].bSymbol = TRUE; else pWeights[ii].bSymbol = FALSE;
lpImage += cb; if ((lpImage - ((LPSTR) hlpImage)) > (63L * 1024L)) { if (bSkip) { cb = ((LPSTR) hlpImage) - (LPSTR) (63L * 1024L); hlpImage += (63L * 1024L); lpImage = (LPSTR) hlpImage + cb; } } }
pct->m_pWeights = pWeights;
return(pct); }
INT CCompressTable::DeCompressString(LPSTR pbComp, LPSTR pbDecomp, int cbComp) { LPSTR pbLimit = pbComp + cbComp; LPSTR pbStartDecomp = pbDecomp; BYTE bCode; BOOL bPrevTokenSymbol = FALSE; BOOL bNextTokenSymbol = FALSE;
int iIndex; int cb;
while(pbComp < pbLimit) { bCode = *pbComp++; switch( acOneBits[0x0f & bCode]) { case NDX_LOW_CLASS: bCode >>= 1; iIndex = ((int) bCode) & 0x00ff;
ASSERT(iIndex > -1); bNextTokenSymbol = m_pWeights[iIndex].bSymbol; if (bNextTokenSymbol && bPrevTokenSymbol) { *pbDecomp++ = ' '; } memcpy( pbDecomp, m_pWeights[iIndex].pb, m_pWeights[iIndex].cb); pbDecomp += m_pWeights[iIndex].cb;
break;
case NDX_MEDIUM_CLASS: bCode >>= 2; iIndex = ((int) bCode) & 0x00ff; iIndex <<= 8; bCode = *pbComp++; iIndex |= bCode; iIndex += 128;
ASSERT(iIndex > -1); bNextTokenSymbol = m_pWeights[iIndex].bSymbol; if (bNextTokenSymbol && bPrevTokenSymbol) { *pbDecomp++ = ' '; } memcpy( pbDecomp, m_pWeights[iIndex].pb, m_pWeights[iIndex].cb); pbDecomp += m_pWeights[iIndex].cb;
break;
case LITERAL_CLASS: bNextTokenSymbol = FALSE; bCode >>= 3; cb = (((int) bCode) & 0x00ff) + 1; memcpy( pbDecomp, pbComp, cb); pbDecomp += cb; pbComp += cb;
break;
case SPACES_CLASS: bNextTokenSymbol = FALSE; bCode >>= 4; cb = (((int) bCode) & 0x00ff) + 1; ASSERT(cb > 0);
while (cb--) { *pbDecomp++ = ' '; }
break;
case NULL_CLASS: bNextTokenSymbol = FALSE; bCode >>= 4; cb = (((int) bCode) & 0x00ff) + 1; ASSERT(cb > 0);
while (cb--) { *pbDecomp++ = 0x00; } break; } bPrevTokenSymbol = bNextTokenSymbol; } return( pbDecomp - pbStartDecomp); } CCompressTable::~CCompressTable() { GlobalUnlock(m_hWeight); GlobalFree(m_hWeight); GlobalUnlock(m_hImage); GlobalFree(m_hImage); }
CJCode::CJCode( int base, int cCount, LPSTR pv) { m_base = base; m_cCount = cCount; m_pData = (DWORD FAR *) pv; m_cCurrent = 0; m_pDataCurrent = m_pData; m_iLeft = BITS_AVAIL; m_fBasisMask = ((DWORD)(~0)) >> (32 - m_base); }
int CJCode::GetBits() { BYTE byte; int iBits;
byte = (BYTE) (~(0x000000ff & *m_pDataCurrent)); iBits = acLeadingZeroes[byte];
if (iBits == 8) { *m_pDataCurrent >>= iBits; m_iLeft -= 8; return(iBits + GetBits()); }
if (iBits < m_iLeft) { *m_pDataCurrent >>= iBits + 1; m_iLeft -= iBits + 1; return(iBits); }
ASSERT(!(iBits > m_iLeft));
m_iLeft = BITS_AVAIL; m_pDataCurrent++; return(iBits + GetBits());
} int CJCode::GetNextDelta() { DWORD dwCode = 0; int iBits; int iDelta; DWORD dwTmp;
iDelta = 0;
iBits = GetBits();
dwCode = *m_pDataCurrent & m_fBasisMask;
if (m_iLeft >= m_base) { *m_pDataCurrent >>= m_base; m_iLeft -= m_base; } else { m_pDataCurrent++; dwTmp = *m_pDataCurrent & (((DWORD) ~0) >> (32 - m_base + m_iLeft)); dwTmp <<= m_iLeft; dwCode |= dwTmp; *m_pDataCurrent >>= m_base - m_iLeft;
m_iLeft = BITS_AVAIL - m_base + m_iLeft; }
iDelta = iBits << m_base; iDelta |= dwCode; return(iDelta + 1);
}
|