Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

374 lines
7.8 KiB

/************************************************************************
* *
* CJDECOMP.CPP *
* *
* Copyright (C) Microsoft Corporation 1994 *
* All Rights reserved. *
* *
* This module is used for Hall decompression -- author's name is John, *
* hence the John structures and names *
* *
************************************************************************/
#include "stdafx.h"
#pragma hdrstop
#include "hall.h"
#include "forage.h"
#include <io.h> // For Zeck Debug code
#include <fcntl.h>
void STDCALL DestroyJPhrase(UINT lpCCompressTable)
{
CCompressTable *pTable = (CCompressTable *) lpCCompressTable;
if (pTable)
delete pTable;
}
void* STDCALL LoadJohnTables(HFS hfs)
{
JINDEXHDR jHdr;
PBYTE pbImage;
int cbImage;
PBYTE pbIndex;
LONG cbIndex;
HF hfImage;
HF hfIndex;
CCompressTable *pNew;
LONG cb;
PBYTE pbZeck;
DWORD cbCompressed;
int cbUncompressed;
hfImage = HfOpenHfs((FSHR *)hfs, txtHallPhraseImage, FS_OPEN_READ_ONLY);
if (!hfImage)
return 0;
hfIndex = HfOpenHfs((FSHR *) hfs, txtHallPhraseIndex, FS_OPEN_READ_ONLY);
ASSERT(hfIndex);
if (!hfIndex) {
RcCloseHf(hfImage);
return 0;
}
LcbReadHf(hfIndex, &jHdr, sizeof(jHdr));
ASSERT(jHdr.iVersion == 1);
cbIndex = jHdr.cbIndex;
cbCompressed = jHdr.cbImageCompressed;
cbUncompressed = jHdr.cbImageUncompressed;
cb = cbUncompressed;
pbIndex = (PBYTE) lcMalloc(jHdr.cbIndex);
pbImage = (PBYTE) lcMalloc(jHdr.cbImageUncompressed);
LcbReadHf(hfIndex, pbIndex, cbIndex);
if (jHdr.cbImageCompressed < jHdr.cbImageUncompressed) {
pbZeck = (PBYTE) lcMalloc(jHdr.cbImageCompressed);
LcbReadHf(hfImage, pbZeck, jHdr.cbImageCompressed);
cbImage = LcbUncompressZeck(pbZeck, pbImage, cbCompressed);
ASSERT(cbImage == cbUncompressed);
lcFree(pbZeck);
}
else
LcbReadHf(hfImage, pbImage, jHdr.cbImageUncompressed);
LcbReadHf(hfIndex, pbIndex, cbIndex);
RcCloseHf(hfImage);
RcCloseHf(hfIndex);
pNew = CCompressTable::NewCompressTable(pbImage, jHdr.cbImageUncompressed,
pbIndex, cbIndex);
lcFree(pbIndex);
return pNew;
}
int STDCALL DecompressJPhrase(PSTR pbText, INT cbComp, PSTR pbDecomp, VOID *lpCCompressTable)
{
static int iNumber = 0;
CCompressTable *pTable = (CCompressTable *) lpCCompressTable;
iNumber++;
ASSERT(pTable);
return(pTable->DeCompressString(pbText, pbDecomp, cbComp));
}
// acLeadingZeroes gives the low order zeroes before the first
// one bit in a byte value.
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
};
BYTE acOneBits[16] =
{
0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4
};
CCompressTable* STDCALL CCompressTable::NewCompressTable(PBYTE pbImage, LONG cbImage, PBYTE pbIndex, LONG cbIndex)
{
CCompressTable *pct = new CCompressTable();
JBITHDR jIHdr;
int iWeightCount;
int base;
int ii;
int cb;
ASSERT(pct);
pct->m_pTableImage = pbImage;
pct->m_pWeights = NULL;
jIHdr = *((JBITHDR *) pbIndex);
ASSERT(jIHdr.Magic == 'J');
base = (int) jIHdr.cBits;
iWeightCount = (int) jIHdr.cCount;
pbIndex += sizeof(jIHdr);
PWEIGHTS pWeights = (PWEIGHTS) LocalAlloc(LMEM_FIXED, sizeof(WEIGHT) * iWeightCount);
CJCode JCode(base, iWeightCount, (LPSTR) pbIndex);
for (ii = 0; ii < iWeightCount; ii++)
{
cb = JCode.GetNextDelta();
pWeights[ii].cb = cb;
pWeights[ii].pb = (LPSTR) pbImage;
pbImage += cb;
}
JCode.NextFlagBits();
for (ii = 0; ii < iWeightCount; ii++)
{
pWeights[ii].bSymbol = JCode.IsSymbol();
}
pct->m_pWeights = pWeights;
return(pct);
}
CCompressTable::~CCompressTable()
{
if (m_pWeights)
lcFree(m_pWeights);
if (m_pTableImage)
lcFree(m_pTableImage);
}
INT STDCALL 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++ = ' ';
}
CopyMemory(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++ = ' ';
}
CopyMemory( 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;
CopyMemory( 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);
}
CJCode::CJCode( int base, int cCount, LPSTR pv)
{
m_base = base;
m_cCount = cCount;
m_pData = (DWORD *) pv;
m_cCurrent = 0;
m_pDataCurrent = m_pData;
m_iLeft = BITS_AVAIL;
m_fBasisMask = ((DWORD)(~0)) >> (32 - m_base);
}
void CJCode::NextFlagBits()
{
if (m_iLeft != BITS_AVAIL)
{
m_pDataCurrent++;
m_iLeft = BITS_AVAIL;
}
}
BOOL CJCode::IsSymbol()
{
BOOL bSymbol = 0x00000001 & *m_pDataCurrent;
*m_pDataCurrent >>= 1;
m_iLeft--;
if (m_iLeft == 0)
{
NextFlagBits();
}
return(bSymbol);
}
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);
}