0666 nwnss: import compression codec helper providers
This commit is contained in:
@@ -204,7 +204,9 @@ add_library(nwnss SHARED
|
||||
comn/compression/nwAlgo.c
|
||||
nss/msg/switchboard.c
|
||||
comn/compression/cdcomp.c
|
||||
comn/compression/cdcompa.c
|
||||
comn/compression/cduncomp.c
|
||||
comn/compression/cduncompa.c
|
||||
comn/common/zPool.c
|
||||
library/misc/format.c
|
||||
comn/common/ndpIdBrokerShared.c
|
||||
|
||||
219
src/nwnss/comn/compression/cdcompa.c
Normal file
219
src/nwnss/comn/compression/cdcompa.c
Normal file
@@ -0,0 +1,219 @@
|
||||
/****************************************************************************
|
||||
|
|
||||
| (C) Copyright 1985, 1991, 1993, 1996-1999 Novell, Inc.
|
||||
| All Rights Reserved.
|
||||
|
|
||||
| This program is free software; you can redistribute it and/or
|
||||
| modify it under the terms of version 2 of the GNU General Public
|
||||
| License as published by the Free Software Foundation.
|
||||
|
|
||||
| This program is distributed in the hope that it will be useful,
|
||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
| GNU General Public License for more details.
|
||||
|
|
||||
| You should have received a copy of the GNU General Public License
|
||||
| along with this program; if not, contact Novell, Inc.
|
||||
|
|
||||
| To contact Novell about this file by physical or electronic mail,
|
||||
| you may find current contact information at www.novell.com
|
||||
|
|
||||
|***************************************************************************
|
||||
|
|
||||
| Netware file compression algorithm ported to NSS
|
||||
|
|
||||
|---------------------------------------------------------------------------
|
||||
|
|
||||
| $Author: taysom $
|
||||
| $Date: 2004-12-31 01:10:58 +0530 (Fri, 31 Dec 2004) $
|
||||
|
|
||||
| $RCSfile$
|
||||
| $Revision: 465 $
|
||||
|
|
||||
|---------------------------------------------------------------------------
|
||||
| Module Description:
|
||||
|
|
||||
+-------------------------------------------------------------------------*/
|
||||
|
||||
#include "nwAlgo.h"
|
||||
#include "cdcomp.h"
|
||||
|
||||
#define WRITE_BIT0( cd ) \
|
||||
cd->WriteBitIndex--; \
|
||||
if (!cd->WriteBitIndex) { \
|
||||
if (cd->WriteCurrentPointer == cd->WriteBufferEnd) \
|
||||
if ((ccode=CCDCompressFlushWriteBuffer(cd))!=0) \
|
||||
return(ccode); \
|
||||
*(LONG*)cd->WriteCurrentPointer = cd->WriteBitBuffer; \
|
||||
cd->WriteCurrentPointer += sizeof(cd->WriteBitBuffer); \
|
||||
cd->WriteBitIndex = 32; cd->WriteBitBuffer = 0; \
|
||||
} \
|
||||
cd->WriteBitBuffer >>= 1;
|
||||
|
||||
#define WRITE_BIT1( cd ) \
|
||||
cd->WriteBitIndex--; \
|
||||
if (!cd->WriteBitIndex) { \
|
||||
if (cd->WriteCurrentPointer == cd->WriteBufferEnd) \
|
||||
if ((ccode=CCDCompressFlushWriteBuffer(cd))!=0) \
|
||||
return(ccode); \
|
||||
*(LONG*)cd->WriteCurrentPointer = cd->WriteBitBuffer; \
|
||||
cd->WriteCurrentPointer += sizeof(cd->WriteBitBuffer); \
|
||||
cd->WriteBitIndex = 32; cd->WriteBitBuffer = 0; \
|
||||
} \
|
||||
cd->WriteBitBuffer >>= 1; \
|
||||
cd->WriteBitBuffer |= 0x80000000;
|
||||
|
||||
#define WRITE_BITS( cd, tw, len ) \
|
||||
data = tw; \
|
||||
for (i=0; i<len; i++) { \
|
||||
if (data & 1) { WRITE_BIT1( cd ) } \
|
||||
else { WRITE_BIT0( cp ) } \
|
||||
data >>= 1; \
|
||||
}
|
||||
|
||||
LONG
|
||||
CCDCheckSumBlock( LONG *data, LONG lengthInDwords )
|
||||
{
|
||||
LONG i, checkSum;
|
||||
|
||||
for (i=0, checkSum=0; i<lengthInDwords; i++, data++ )
|
||||
checkSum += *data;
|
||||
|
||||
return( checkSum );
|
||||
}
|
||||
|
||||
LONG
|
||||
CCDCheckSumBlock4KMinus1( LONG *data )
|
||||
{
|
||||
LONG checkSum;
|
||||
|
||||
checkSum = (~CCDCheckSumBlock( data, CD_SYSTEM_CACHE_BUFFER_LONGS - 1)) + 1;
|
||||
return( checkSum );
|
||||
}
|
||||
|
||||
LONG
|
||||
CCDCompressFlushWriteBuffer( compressData_tp cd )
|
||||
{
|
||||
LONG ccode;
|
||||
|
||||
if ( zStopCompression( cd->FileVolume ) ) return(COMPRESS_ERROR_ABORTED);
|
||||
|
||||
if ( cd->AbortCompression ) return( COMPRESS_ERROR_ABORTED );
|
||||
|
||||
*((LONG *)cd->WriteBufferEnd) =
|
||||
CCDCheckSumBlock4KMinus1( (LONG *)cd->WriteBufferBegin );
|
||||
|
||||
if ((ccode = NSSCCDReturnWriteCacheBlock( cd->WriteBufferHandle,
|
||||
cd->WriteHandle, CD_SYSTEM_SECTORS_PER_BUFFER, (LONG)0)) !=0)
|
||||
{
|
||||
cd->WriteBufferBegin = 0;
|
||||
return(ccode);
|
||||
}
|
||||
|
||||
cd->WriteBufferBegin = 0;
|
||||
|
||||
cd->WriteBlockNumber++;
|
||||
|
||||
if ((ccode = NSSCCDGetWriteCacheBlock( cd->WriteHandle,
|
||||
cd->WriteBlockNumber, (LONG)0, & cd->WriteCurrentPointer,
|
||||
& cd->WriteBufferHandle )) != 0)
|
||||
{
|
||||
return(ccode);
|
||||
}
|
||||
|
||||
cd->WriteBufferBegin = cd->WriteCurrentPointer;
|
||||
|
||||
cd->WriteBufferEnd = cd->WriteCurrentPointer + CD_SYSTEM_CACHE_BUFFER_SIZE - 4;
|
||||
|
||||
return((LONG)0);
|
||||
}
|
||||
|
||||
LONG CCDCompressWriteBits( compressData_tp cp, LONG length, LONG toWriteBits )
|
||||
{
|
||||
LONG data;
|
||||
LONG i;
|
||||
LONG ccode;
|
||||
|
||||
WRITE_BITS( cp, toWriteBits, length );
|
||||
|
||||
return((LONG)0);
|
||||
}
|
||||
|
||||
LONG CCDCompressWriteOneBit( compressData_tp cp )
|
||||
{
|
||||
LONG ccode;
|
||||
|
||||
WRITE_BIT1( cp )
|
||||
|
||||
return((LONG)0);
|
||||
}
|
||||
|
||||
LONG CCDCompressWriteZeroBit( compressData_tp cp )
|
||||
{
|
||||
LONG ccode;
|
||||
|
||||
WRITE_BIT0( cp )
|
||||
|
||||
return((LONG)0);
|
||||
}
|
||||
|
||||
LONG
|
||||
CCDCheckSumSwappedBlock( LONG *data, LONG lengthInDwords )
|
||||
{
|
||||
LONG i, checkSum;
|
||||
|
||||
for (i=0, checkSum=0; i<lengthInDwords; i++, data++ )
|
||||
checkSum += SWAP_LONG(*data);
|
||||
|
||||
return( checkSum );
|
||||
}
|
||||
|
||||
LONG
|
||||
CCDCheckSumSwappedBlock4K( LONG *data )
|
||||
{
|
||||
return( CCDCheckSumSwappedBlock( data, (LONG)CD_SYSTEM_CACHE_BUFFER_LONGS ));
|
||||
}
|
||||
|
||||
|
||||
LONG
|
||||
CCDCheckSumBlock4K( LONG *data )
|
||||
{
|
||||
return(CCDCheckSumBlock( data, CD_SYSTEM_CACHE_BUFFER_LONGS ));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CCDFreeShannonTree( compressNode_tp treePointer )
|
||||
{
|
||||
if (treePointer)
|
||||
{
|
||||
if (treePointer->left)
|
||||
CCDFreeShannonTree( treePointer->left );
|
||||
|
||||
if (treePointer->right)
|
||||
CCDFreeShannonTree( treePointer->right );
|
||||
|
||||
CD_FREE( treePointer );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CDCountTreeNodes( compressNode_tp treePointer, LONG *count )
|
||||
{
|
||||
if (treePointer->left)
|
||||
CDCountTreeNodes( treePointer->left, count );
|
||||
|
||||
if (treePointer->right)
|
||||
CDCountTreeNodes( treePointer->right, count );
|
||||
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
|
||||
LONG
|
||||
CCDCountTreeNodes( compressNode_tp treePointer, LONG *count )
|
||||
{
|
||||
*count = 0;
|
||||
CDCountTreeNodes( treePointer, count );
|
||||
return((LONG)0);
|
||||
}
|
||||
664
src/nwnss/comn/compression/cduncompa.c
Normal file
664
src/nwnss/comn/compression/cduncompa.c
Normal file
@@ -0,0 +1,664 @@
|
||||
/****************************************************************************
|
||||
|
|
||||
| (C) Copyright 1985, 1991, 1993, 1996-1999 Novell, Inc.
|
||||
| All Rights Reserved.
|
||||
|
|
||||
| This program is free software; you can redistribute it and/or
|
||||
| modify it under the terms of version 2 of the GNU General Public
|
||||
| License as published by the Free Software Foundation.
|
||||
|
|
||||
| This program is distributed in the hope that it will be useful,
|
||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
| GNU General Public License for more details.
|
||||
|
|
||||
| You should have received a copy of the GNU General Public License
|
||||
| along with this program; if not, contact Novell, Inc.
|
||||
|
|
||||
| To contact Novell about this file by physical or electronic mail,
|
||||
| you may find current contact information at www.novell.com
|
||||
|
|
||||
|***************************************************************************
|
||||
|
|
||||
| Netware file compression algorithm ported to NSS
|
||||
|
|
||||
|---------------------------------------------------------------------------
|
||||
|
|
||||
| $Author: vandana $
|
||||
| $Date: 2005-08-10 01:03:51 +0530 (Wed, 10 Aug 2005) $
|
||||
|
|
||||
| $RCSfile$
|
||||
| $Revision: 1177 $
|
||||
|
|
||||
|---------------------------------------------------------------------------
|
||||
| Module Description:
|
||||
|
|
||||
+-------------------------------------------------------------------------*/
|
||||
#include "nwAlgo.h"
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#define READ_BIT(ud, bit) \
|
||||
ud->BitBufferIndex--; \
|
||||
if (!ud->BitBufferIndex) { \
|
||||
if (ud->BitMapCurrentPointer == ud->BitMapCurrentEnd) \
|
||||
if ((ccode=CCDDecompressFillBitBuffer(ud))!=0) \
|
||||
return(ccode); \
|
||||
ud->BitBuffer = *ud->BitMapCurrentPointer; \
|
||||
ud->BitMapCurrentPointer++; \
|
||||
ud->BitBufferIndex = 32; \
|
||||
} \
|
||||
bit = (ud->BitBuffer & 0x1) ? 1 : 0; \
|
||||
ud->BitBuffer >>=1;
|
||||
|
||||
#define READ_BITS( ud, bits, len ) \
|
||||
bits = 0; \
|
||||
for(i=0; i<len; i++) { \
|
||||
READ_BIT( ud, bit ); \
|
||||
if (bit) bits |= (1 << i); \
|
||||
}
|
||||
|
||||
#define READ_BIT_HILO(ud, bit) \
|
||||
ud->BitBufferIndex--; \
|
||||
if (!ud->BitBufferIndex) { \
|
||||
if (ud->BitMapCurrentPointer == ud->BitMapCurrentEnd) \
|
||||
if ((ccode=CCDDecompressFillBitBufferHiLo(ud))!=0) \
|
||||
return(ccode); \
|
||||
ud->BitBuffer = SWAP_LONG(*ud->BitMapCurrentPointer); \
|
||||
ud->BitMapCurrentPointer++; \
|
||||
ud->BitBufferIndex = 32; \
|
||||
} \
|
||||
bit = (ud->BitBuffer & 0x1) ? 1 : 0; \
|
||||
ud->BitBuffer >>=1;
|
||||
|
||||
#define READ_BITS_HILO( ud, bits, len ) \
|
||||
bits = 0; \
|
||||
for(i=0; i<len; i++) { \
|
||||
READ_BIT_HILO( ud, bit ); \
|
||||
if (bit) bits |= (1 << i); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Warning! Don't replace this with memmove!
|
||||
* The Netware decompression algorithm uses this routine to copy bytes between
|
||||
* overlapping memory ranges. A side-effect of this copy is to duplicate some
|
||||
* of the src memory range bytes across the entire destination memory range.
|
||||
* This side-effect is EXPECTED by the Netware decompression algorithm.
|
||||
* For this to happen, the src address must be < dest address.
|
||||
*/
|
||||
STATIC void
|
||||
memmovePropagate(BYTE *src, BYTE *dest, LONG size)
|
||||
{
|
||||
SNINT i;
|
||||
SLONG mydiff = (dest - src);
|
||||
if ((mydiff > 0) && (size > mydiff))
|
||||
{
|
||||
NWALGO_DBG_PRINTF((NWALGO_DBG_COLOR, "memmove src=0x%p, dest=0x%p, diff=0x%lx, size=0x%lx\n",
|
||||
src, dest, mydiff, size));
|
||||
}
|
||||
for (i = 0; i < size; i++)
|
||||
dest[i] = src[i];
|
||||
}
|
||||
|
||||
extern LONG CCDCheckSumBlock( LONG *data, LONG length );
|
||||
extern LONG CCDCheckSumBlock4K( LONG *data );
|
||||
extern LONG CCDCheckSumBlock4KMinus1( LONG *data );
|
||||
extern LONG CCDCheckSumSwappedBlock( LONG *data, LONG length );
|
||||
extern LONG CCDCheckSumSwappedBlock4K( LONG *data );
|
||||
extern struct ScreenStruct *CompressScreen;
|
||||
|
||||
/* ******************************************************************** */
|
||||
|
||||
LONG
|
||||
CCDDecompressGetWriteBuffer( uncompressData_tp ud )
|
||||
{
|
||||
LONG ccode;
|
||||
decompressHoleMark_tp toFree;
|
||||
|
||||
if (ud->WriteEOFPointer != (BYTE *)-1 ) return(UNCOMPRESS_ERROR_WRITE_BEYOND_EOF);
|
||||
|
||||
if (ud->ThreadExitNow) return(UNCOMPRESS_ERROR_ABORTED);
|
||||
|
||||
if (ud->WriteCacheBufferCount < (UNCOMPRESS_WRITE_CACHE_BUFFER_RANGE-1))
|
||||
{
|
||||
ud->WriteCacheBufferCount++;
|
||||
ud->BytesInWriteCacheSoFar += CD_SYSTEM_CACHE_BUFFER_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
LONG handle;
|
||||
handle = ud->WriteCacheHandle[0];
|
||||
|
||||
/* mark this block since as tried once to return */
|
||||
ud->WriteCacheHandle[0] = 0;
|
||||
|
||||
if((ccode=NSSCCDReturnWriteCacheBlock( handle,
|
||||
ud->WriteHandle, CD_SYSTEM_SECTORS_PER_BUFFER, (LONG)0)) !=0)
|
||||
return(ccode);
|
||||
|
||||
ud->WriteCachePointers[0] = ud->WriteCachePointers[1];
|
||||
ud->WriteCacheBlockNumber[0] = ud->WriteCacheBlockNumber[1];
|
||||
ud->WriteCacheHandle[0] = ud->WriteCacheHandle[1];
|
||||
ud->WriteCacheBufferEnd[0] = ud->WriteCacheBufferEnd[1];
|
||||
|
||||
ud->WriteCachePointers[1] = ud->WriteCachePointers[2];
|
||||
ud->WriteCacheBlockNumber[1] = ud->WriteCacheBlockNumber[2];
|
||||
ud->WriteCacheHandle[1] = ud->WriteCacheHandle[2];
|
||||
ud->WriteCacheBufferEnd[1] = ud->WriteCacheBufferEnd[2];
|
||||
}
|
||||
|
||||
if (ud->HoleListHead)
|
||||
{
|
||||
while (ud->HoleListHead &&
|
||||
ud->HoleListHead->offset == (ud->WriteCacheNextBlockToGet << CD_SYSTEM_CACHE_BUFFER_SHIFT ))
|
||||
{
|
||||
ud->WriteCacheNextBlockToGet += (ud->HoleListHead->size >> CD_SYSTEM_CACHE_BUFFER_SHIFT );
|
||||
toFree = ud->HoleListHead;
|
||||
ud->HoleListHead = ud->HoleListHead->next;
|
||||
CD_FREE(toFree);
|
||||
}
|
||||
|
||||
/* This file can't be ended with a hole because ud->WriteFileSize is not 0 */
|
||||
CD_ASSERT ((ud->WriteCacheNextBlockToGet !=
|
||||
ud->decompressStatus.status.totalBlocksToDecompress));
|
||||
}
|
||||
|
||||
NSSCCDUpdateDecompressPosition( ud->WriteHandle,
|
||||
ud->WriteCacheNextBlockToGet << CD_SYSTEM_CACHE_BUFFER_SHIFT);
|
||||
|
||||
if ((ccode=NSSCCDGetWriteCacheBlock(ud->WriteHandle,
|
||||
ud->WriteCacheNextBlockToGet, (LONG)0,
|
||||
&ud->WriteCachePointers[ ud->WriteCacheBufferCount ],
|
||||
&ud->WriteCacheHandle[ ud->WriteCacheBufferCount ]))!=0)
|
||||
return(ccode);
|
||||
|
||||
ud->WriteCacheBlockNumber[ ud->WriteCacheBufferCount ] =
|
||||
ud->WriteCacheNextBlockToGet;
|
||||
|
||||
ud->WriteCacheNextBlockToGet++;
|
||||
|
||||
ud->WriteCacheBufferEnd[ ud->WriteCacheBufferCount ] =
|
||||
ud->WriteCachePointers[ ud->WriteCacheBufferCount ]
|
||||
+ CD_SYSTEM_CACHE_BUFFER_SIZE;
|
||||
|
||||
ud->WriteCurrentBufferEnd =
|
||||
ud->WriteCacheBufferEnd[ ud->WriteCacheBufferCount ];
|
||||
|
||||
ud->WriteCurrentBufferBegin = ud->WriteCurrentPointer =
|
||||
ud->WriteCachePointers[ ud->WriteCacheBufferCount ];
|
||||
|
||||
ud->WriteFileSize -= CD_SYSTEM_CACHE_BUFFER_SIZE;
|
||||
|
||||
if (ud->WriteFileSize <= CD_SYSTEM_CACHE_BUFFER_SIZE)
|
||||
ud->WriteEOFPointer = ud->WriteCurrentPointer + ud->WriteFileSize;
|
||||
|
||||
if (ud->ThreadExitNow) return(UNCOMPRESS_ERROR_ABORTED);
|
||||
|
||||
return((LONG)0);
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
|
||||
LONG
|
||||
CCDDecompressFillBitBuffer( uncompressData_tp ud )
|
||||
{
|
||||
LONG ccode, holeFlag, validBytes;
|
||||
|
||||
if (ud->ThreadExitNow) return(UNCOMPRESS_ERROR_ABORTED);
|
||||
|
||||
if (!ud->CompressedFileSize) return ( UNCOMPRESS_ERROR_CORRUPT_COMPRESSED_FILE );
|
||||
|
||||
if ((ccode = NSSCCDFreeReadAheadBuffer( ud->ReadCache )) != 0) return(ccode);
|
||||
|
||||
if ((ccode = NSSCCDGetReadAheadBuffer( ud->ReadCache,
|
||||
(BYTE **)&ud->BitMapCurrentPointer, &validBytes, &holeFlag )) != 0)
|
||||
return(ccode);
|
||||
|
||||
if (holeFlag) return( UNCOMPRESS_ERROR_INVALID_HOLES );
|
||||
|
||||
if (ud->CompressedFileSize < CD_SYSTEM_CACHE_BUFFER_SIZE)
|
||||
{
|
||||
if (CCDCheckSumBlock( ud->BitMapCurrentPointer,
|
||||
ud->CompressedFileSize >> 2 ))
|
||||
return( UNCOMPRESS_ERROR_CORRUPT_COMPRESSED_FILE );
|
||||
|
||||
ud->CompressedFileSize = 0;
|
||||
|
||||
ud->BitMapCurrentEnd = ud->BitMapCurrentPointer +
|
||||
(ud->CompressedFileSize >> 2) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( CCDCheckSumBlock4K( ud->BitMapCurrentPointer ) )
|
||||
return( UNCOMPRESS_ERROR_CORRUPT_COMPRESSED_FILE );
|
||||
|
||||
ud->CompressedFileSize -= CD_SYSTEM_CACHE_BUFFER_SIZE;
|
||||
|
||||
ud->BitMapCurrentEnd = ud->BitMapCurrentPointer +
|
||||
CD_SYSTEM_CACHE_BUFFER_LONGS - 1;
|
||||
}
|
||||
|
||||
return((LONG)0);
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
|
||||
LONG
|
||||
CCDDecompressFillBitBufferHiLo( uncompressData_tp ud )
|
||||
{
|
||||
LONG ccode, holeFlag, validBytes;
|
||||
/*LONG *lptr, i;*/
|
||||
|
||||
if (ud->ThreadExitNow) return(UNCOMPRESS_ERROR_ABORTED);
|
||||
|
||||
if (!ud->CompressedFileSize) return ( UNCOMPRESS_ERROR_CORRUPT_COMPRESSED_FILE );
|
||||
|
||||
if ((ccode = NSSCCDFreeReadAheadBuffer( ud->ReadCache )) != 0) return(ccode);
|
||||
|
||||
if ((ccode = NSSCCDGetReadAheadBuffer( ud->ReadCache,
|
||||
(BYTE **)&ud->BitMapCurrentPointer, &validBytes, &holeFlag )) != 0)
|
||||
return(ccode);
|
||||
|
||||
if (holeFlag) return( UNCOMPRESS_ERROR_INVALID_HOLES );
|
||||
|
||||
if (ud->CompressedFileSize < CD_SYSTEM_CACHE_BUFFER_SIZE)
|
||||
{
|
||||
if (CCDCheckSumBlock( ud->BitMapCurrentPointer,
|
||||
ud->CompressedFileSize >> 2 ))
|
||||
return( UNCOMPRESS_ERROR_CORRUPT_COMPRESSED_FILE );
|
||||
|
||||
ud->CompressedFileSize = 0;
|
||||
|
||||
ud->BitMapCurrentEnd = ud->BitMapCurrentPointer +
|
||||
(ud->CompressedFileSize >> 2) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( CCDCheckSumBlock4K( ud->BitMapCurrentPointer ) )
|
||||
return( UNCOMPRESS_ERROR_CORRUPT_COMPRESSED_FILE );
|
||||
|
||||
ud->CompressedFileSize -= CD_SYSTEM_CACHE_BUFFER_SIZE;
|
||||
|
||||
ud->BitMapCurrentEnd = ud->BitMapCurrentPointer +
|
||||
CD_SYSTEM_CACHE_BUFFER_LONGS - 1;
|
||||
}
|
||||
|
||||
return((LONG)0);
|
||||
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
|
||||
LONG
|
||||
CDReadShannonTreeHiLo(
|
||||
uncompressData_tp ud,
|
||||
uncompressNode_tpp parentPtr,
|
||||
uncompressNode_tpp allocPool,
|
||||
LONG *count )
|
||||
{
|
||||
LONG ccode;
|
||||
LONG bit,i;
|
||||
uncompressNode_tp prevChild;
|
||||
|
||||
if (!*count) return (UNCOMPRESS_ERROR_TREE_TOO_BIG);
|
||||
|
||||
*parentPtr = prevChild = *allocPool;
|
||||
|
||||
(*allocPool)++;
|
||||
|
||||
(*count)--;
|
||||
|
||||
READ_BIT_HILO( ud, bit )
|
||||
|
||||
if (bit)
|
||||
{
|
||||
READ_BITS_HILO( ud, prevChild->value, 8 )
|
||||
return((LONG)0);
|
||||
}
|
||||
|
||||
if ((ccode = CDReadShannonTreeHiLo( ud, &(prevChild->left), allocPool,
|
||||
count)) != 0)
|
||||
return(ccode);
|
||||
|
||||
if ((ccode = CDReadShannonTreeHiLo( ud, &(prevChild->right), allocPool,
|
||||
count)) != 0)
|
||||
return(ccode);
|
||||
|
||||
return((LONG)0);
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
|
||||
LONG
|
||||
CCDReadShannonTreeHiLo( uncompressData_tp ud, uncompressNode_tpp tree,
|
||||
LONG *nodeCount)
|
||||
{
|
||||
uncompressNode_tp hold;
|
||||
LONG ccode;
|
||||
|
||||
hold = *tree;
|
||||
|
||||
if ((ccode=CDReadShannonTreeHiLo( ud, tree, tree, nodeCount)) != 0)
|
||||
return( ccode );
|
||||
|
||||
*tree = hold;
|
||||
|
||||
return((LONG)0);
|
||||
}
|
||||
/* ******************************************************************** */
|
||||
|
||||
LONG
|
||||
CCDDecompressFileHiLo( uncompressData_tp ud )
|
||||
{
|
||||
LONG ccode, bit, length, offset, toCopy;
|
||||
long byteIndex;
|
||||
BYTE *previousStringPointer,i;
|
||||
uncompressNode_tp tree;
|
||||
|
||||
while ( ud->WriteCurrentPointer != ud->WriteEOFPointer )
|
||||
{
|
||||
READ_BIT_HILO( ud, bit );
|
||||
|
||||
if (bit)
|
||||
{
|
||||
tree = ud->DataTree;
|
||||
|
||||
while( tree->left )
|
||||
{
|
||||
READ_BIT_HILO( ud, bit );
|
||||
tree = bit ? tree->right : tree->left;
|
||||
}
|
||||
|
||||
if (ud->WriteCurrentPointer == ud->WriteCurrentBufferEnd)
|
||||
{
|
||||
if ((ccode = CCDDecompressGetWriteBuffer( ud )) != 0) return(ccode);
|
||||
}
|
||||
|
||||
*ud->WriteCurrentPointer = (BYTE)tree->value;
|
||||
|
||||
ud->WriteCurrentPointer ++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
tree = ud ->LengthTree;
|
||||
|
||||
while( tree->left )
|
||||
{
|
||||
READ_BIT_HILO( ud, bit );
|
||||
tree = bit ? tree->right : tree->left;
|
||||
}
|
||||
|
||||
if (tree->value == 0xFE)
|
||||
{
|
||||
READ_BITS_HILO( ud, length, 13 );
|
||||
}
|
||||
else
|
||||
{
|
||||
length = tree->value;
|
||||
}
|
||||
|
||||
READ_BITS_HILO(ud, offset, 5 );
|
||||
|
||||
|
||||
tree = ud->OffsetTree;
|
||||
|
||||
while( tree->left )
|
||||
{
|
||||
READ_BIT_HILO( ud, bit );
|
||||
tree = bit ? tree->right : tree->left;
|
||||
}
|
||||
|
||||
offset += ( tree->value << 5 );
|
||||
|
||||
if (((ud->WriteCurrentPointer - offset) < ud->WriteCurrentBufferBegin)
|
||||
|| ((ud->WriteCurrentPointer + length) >= ud->WriteCurrentBufferEnd))
|
||||
{
|
||||
byteIndex = ((ud->WriteCurrentPointer - ud->WriteCurrentBufferBegin)
|
||||
+ ud->BytesInWriteCacheSoFar) - offset;
|
||||
|
||||
if (byteIndex < 0) return(UNCOMPRESS_ERROR_INVALID_OFFSET);
|
||||
|
||||
ud->WritePreviousBufferIndex = byteIndex >> CD_SYSTEM_CACHE_BUFFER_SHIFT;
|
||||
|
||||
if (length > (CD_SYSTEM_CACHE_BUFFER_SIZE * 2))
|
||||
return( UNCOMPRESS_ERROR_INVALID_LENGTH );
|
||||
|
||||
previousStringPointer = ud->WriteCachePointers[ ud->WritePreviousBufferIndex ]
|
||||
+ (byteIndex & CD_SYSTEM_CACHE_BUFFER_MASK) ;
|
||||
|
||||
ud->WritePreviousBufferEnd = ud->WriteCacheBufferEnd[ ud->WritePreviousBufferIndex ];
|
||||
|
||||
toCopy = length;
|
||||
|
||||
while (length)
|
||||
{
|
||||
if (ud->WriteCurrentPointer == ud->WriteCurrentBufferEnd)
|
||||
{
|
||||
if (ud->WriteCacheBufferCount == (UNCOMPRESS_WRITE_CACHE_BUFFER_RANGE-1))
|
||||
ud->WritePreviousBufferIndex--;
|
||||
|
||||
if ((ccode = CCDDecompressGetWriteBuffer( ud )) != 0)
|
||||
return( ccode );
|
||||
}
|
||||
|
||||
if (previousStringPointer == ud->WritePreviousBufferEnd)
|
||||
{
|
||||
ud->WritePreviousBufferIndex ++;
|
||||
ud->WritePreviousBufferEnd = ud->WriteCacheBufferEnd[ ud->WritePreviousBufferIndex ];
|
||||
previousStringPointer = ud->WriteCachePointers[ ud->WritePreviousBufferIndex ];
|
||||
}
|
||||
|
||||
if (toCopy > (ud->WritePreviousBufferEnd - previousStringPointer ))
|
||||
toCopy = ud->WritePreviousBufferEnd - previousStringPointer ;
|
||||
|
||||
if (toCopy > (ud->WriteCurrentBufferEnd - ud->WriteCurrentPointer))
|
||||
toCopy = ud->WriteCurrentBufferEnd - ud->WriteCurrentPointer;
|
||||
|
||||
memmovePropagate(previousStringPointer, ud->WriteCurrentPointer, toCopy);
|
||||
|
||||
previousStringPointer += toCopy;
|
||||
ud->WriteCurrentPointer += toCopy;
|
||||
|
||||
length -= toCopy;
|
||||
toCopy = length;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
memmovePropagate(ud->WriteCurrentPointer - offset, ud->WriteCurrentPointer, length);
|
||||
|
||||
ud->WriteCurrentPointer += length;
|
||||
|
||||
}
|
||||
|
||||
return((LONG)0);
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
|
||||
LONG
|
||||
CDReadShannonTree(
|
||||
uncompressData_tp ud,
|
||||
uncompressNode_tpp parentPtr,
|
||||
uncompressNode_tpp allocPool,
|
||||
LONG *count )
|
||||
{
|
||||
LONG ccode;
|
||||
LONG bit,i;
|
||||
uncompressNode_tp prevChild;
|
||||
|
||||
if (!*count) return ( UNCOMPRESS_ERROR_TREE_TOO_BIG );
|
||||
|
||||
*parentPtr = prevChild = *allocPool;
|
||||
|
||||
(*allocPool)++;
|
||||
|
||||
(*count)--;
|
||||
|
||||
READ_BIT( ud, bit )
|
||||
|
||||
if (bit)
|
||||
{
|
||||
READ_BITS( ud, prevChild->value, 8 )
|
||||
return((LONG)0);
|
||||
}
|
||||
|
||||
if ((ccode = CDReadShannonTree( ud, &(prevChild->left), allocPool, count)) != 0)
|
||||
return(ccode);
|
||||
|
||||
if ((ccode = CDReadShannonTree( ud, &(prevChild->right), allocPool, count)) != 0)
|
||||
return(ccode);
|
||||
|
||||
return((LONG)0);
|
||||
}
|
||||
/* ******************************************************************** */
|
||||
|
||||
LONG
|
||||
CCDReadShannonTree( uncompressData_tp ud, uncompressNode_tpp tree,
|
||||
LONG *nodeCount)
|
||||
{
|
||||
uncompressNode_tp hold;
|
||||
LONG ccode;
|
||||
|
||||
hold = *tree;
|
||||
|
||||
if ((ccode=CDReadShannonTree( ud, tree, tree, nodeCount)) != 0)
|
||||
return(ccode );
|
||||
|
||||
*tree = hold;
|
||||
|
||||
return((LONG)0);
|
||||
}
|
||||
|
||||
/* ******************************************************************** */
|
||||
|
||||
LONG
|
||||
CCDDecompressFile( uncompressData_tp ud )
|
||||
{
|
||||
LONG ccode, bit, length, offset, toCopy;
|
||||
long byteIndex;
|
||||
BYTE *previousStringPointer,i;
|
||||
uncompressNode_tp tree;
|
||||
|
||||
/* unCompPrintTree( ud->DataTree, 0 ); */
|
||||
|
||||
while ( ud->WriteCurrentPointer != ud->WriteEOFPointer )
|
||||
{
|
||||
READ_BIT( ud, bit );
|
||||
|
||||
if (bit)
|
||||
{
|
||||
tree = ud->DataTree;
|
||||
|
||||
while( tree->left )
|
||||
{
|
||||
READ_BIT( ud, bit );
|
||||
tree = bit ? tree->right : tree->left;
|
||||
}
|
||||
|
||||
if (ud->WriteCurrentPointer == ud->WriteCurrentBufferEnd)
|
||||
{
|
||||
if ((ccode = CCDDecompressGetWriteBuffer( ud )) != 0) return(ccode);
|
||||
}
|
||||
|
||||
*ud->WriteCurrentPointer = (BYTE)tree->value;
|
||||
|
||||
ud->WriteCurrentPointer ++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
tree = ud ->LengthTree;
|
||||
|
||||
while( tree->left )
|
||||
{
|
||||
READ_BIT( ud, bit );
|
||||
tree = bit ? tree->right : tree->left;
|
||||
}
|
||||
|
||||
if (tree->value == 0xFE)
|
||||
{
|
||||
/* length cannot exceed 8196 because only 13 bits */
|
||||
READ_BITS( ud, length, 13 );
|
||||
}
|
||||
else
|
||||
{
|
||||
length = tree->value;
|
||||
}
|
||||
|
||||
|
||||
READ_BITS(ud, offset, 5 );
|
||||
|
||||
tree = ud->OffsetTree;
|
||||
|
||||
while( tree->left )
|
||||
{
|
||||
READ_BIT( ud, bit );
|
||||
tree = bit ? tree->right : tree->left;
|
||||
}
|
||||
|
||||
offset += ( tree->value << 5 );
|
||||
|
||||
if (((ud->WriteCurrentPointer - offset) < ud->WriteCurrentBufferBegin)
|
||||
|| ((ud->WriteCurrentPointer + length) >= ud->WriteCurrentBufferEnd))
|
||||
{
|
||||
byteIndex = ((ud->WriteCurrentPointer - ud->WriteCurrentBufferBegin)
|
||||
+ ud->BytesInWriteCacheSoFar) - offset;
|
||||
|
||||
if (byteIndex < 0) return( UNCOMPRESS_ERROR_INVALID_OFFSET );
|
||||
|
||||
ud->WritePreviousBufferIndex = byteIndex >> CD_SYSTEM_CACHE_BUFFER_SHIFT;
|
||||
|
||||
previousStringPointer = ud->WriteCachePointers[ ud->WritePreviousBufferIndex ]
|
||||
+ (byteIndex & CD_SYSTEM_CACHE_BUFFER_MASK) ;
|
||||
|
||||
ud->WritePreviousBufferEnd = ud->WriteCacheBufferEnd[ ud->WritePreviousBufferIndex ];
|
||||
|
||||
toCopy = length;
|
||||
|
||||
while (length)
|
||||
{
|
||||
if (ud->WriteCurrentPointer == ud->WriteCurrentBufferEnd)
|
||||
{
|
||||
if (ud->WriteCacheBufferCount == (UNCOMPRESS_WRITE_CACHE_BUFFER_RANGE-1))
|
||||
ud->WritePreviousBufferIndex--;
|
||||
|
||||
if ((ccode = CCDDecompressGetWriteBuffer( ud )) != 0)
|
||||
return( ccode );
|
||||
}
|
||||
|
||||
if (previousStringPointer == ud->WritePreviousBufferEnd)
|
||||
{
|
||||
ud->WritePreviousBufferIndex ++;
|
||||
previousStringPointer = ud->WriteCachePointers[ ud->WritePreviousBufferIndex ];
|
||||
ud->WritePreviousBufferEnd = ud->WriteCacheBufferEnd[ ud->WritePreviousBufferIndex ];
|
||||
}
|
||||
|
||||
if (toCopy > (ud->WritePreviousBufferEnd - previousStringPointer ))
|
||||
toCopy = ud->WritePreviousBufferEnd - previousStringPointer ;
|
||||
|
||||
if (toCopy > (ud->WriteCurrentBufferEnd - ud->WriteCurrentPointer))
|
||||
toCopy = ud->WriteCurrentBufferEnd - ud->WriteCurrentPointer;
|
||||
|
||||
memmovePropagate(previousStringPointer, ud->WriteCurrentPointer, toCopy);
|
||||
|
||||
previousStringPointer += toCopy;
|
||||
ud->WriteCurrentPointer += toCopy;
|
||||
|
||||
length -= toCopy;
|
||||
toCopy = length;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
memmovePropagate( ud->WriteCurrentPointer - offset, ud->WriteCurrentPointer, length);
|
||||
|
||||
ud->WriteCurrentPointer += length;
|
||||
}
|
||||
|
||||
return((LONG)0);
|
||||
}
|
||||
/* ******************************************************************** */
|
||||
Reference in New Issue
Block a user