Merge branch 'ncrush' of github.com:awakecoding/FreeRDP into ncrush

This commit is contained in:
Marc-André Moreau 2014-03-31 14:48:59 -04:00
commit 73087f1025
3 changed files with 894 additions and 4 deletions

View File

@ -33,9 +33,14 @@ struct _NCRUSH_CONTEXT
BYTE* HistoryPtr;
UINT32 HistoryOffset;
UINT32 HistoryEndOffset;
UINT32 HistoryBufferSize;
BYTE HistoryBuffer[65536];
UINT32 HistoryBufferFence;
UINT32 OffsetCache[4];
UINT16 HashTable[65536];
UINT16 MatchTable[65536];
BYTE HuffTableLOM[4096];
BYTE HuffTableCopyOffset[1024];
};
typedef struct _NCRUSH_CONTEXT NCRUSH_CONTEXT;

View File

@ -920,6 +920,304 @@ const BYTE HuffLengthLEC[294] =
13 /* 293 */
};
const BYTE HuffCodeLEC[294] =
{
0x4, /* 0 */
0x0, /* 1 */
0x24, /* 2 */
0x0, /* 3 */
0x14, /* 4 */
0x0, /* 5 */
0x11, /* 6 */
0x0, /* 7 */
0x51, /* 8 */
0x0, /* 9 */
0x31, /* 10 */
0x0, /* 11 */
0x71, /* 12 */
0x0, /* 13 */
0x9, /* 14 */
0x0, /* 15 */
0x49, /* 16 */
0x0, /* 17 */
0x29, /* 18 */
0x0, /* 19 */
0x69, /* 20 */
0x0, /* 21 */
0x15, /* 22 */
0x0, /* 23 */
0x95, /* 24 */
0x0, /* 25 */
0x55, /* 26 */
0x0, /* 27 */
0xD5, /* 28 */
0x0, /* 29 */
0x35, /* 30 */
0x0, /* 31 */
0xB5, /* 32 */
0x0, /* 33 */
0x75, /* 34 */
0x0, /* 35 */
0x1D, /* 36 */
0x0, /* 37 */
0xF5, /* 38 */
0x0, /* 39 */
0x1D, /* 40 */
0x1, /* 41 */
0x9D, /* 42 */
0x0, /* 43 */
0x9D, /* 44 */
0x1, /* 45 */
0x5D, /* 46 */
0x0, /* 47 */
0xD, /* 48 */
0x0, /* 49 */
0x8D, /* 50 */
0x0, /* 51 */
0x5D, /* 52 */
0x1, /* 53 */
0xDD, /* 54 */
0x0, /* 55 */
0xDD, /* 56 */
0x1, /* 57 */
0x3D, /* 58 */
0x0, /* 59 */
0x3D, /* 60 */
0x1, /* 61 */
0xBD, /* 62 */
0x0, /* 63 */
0x4D, /* 64 */
0x0, /* 65 */
0xBD, /* 66 */
0x1, /* 67 */
0x7D, /* 68 */
0x0, /* 69 */
0x6B, /* 70 */
0x0, /* 71 */
0x7D, /* 72 */
0x1, /* 73 */
0xFD, /* 74 */
0x0, /* 75 */
0xFD, /* 76 */
0x1, /* 77 */
0x3, /* 78 */
0x0, /* 79 */
0x3, /* 80 */
0x1, /* 81 */
0x83, /* 82 */
0x0, /* 83 */
0x83, /* 84 */
0x1, /* 85 */
0x6B, /* 86 */
0x2, /* 87 */
0x43, /* 88 */
0x0, /* 89 */
0x6B, /* 90 */
0x1, /* 91 */
0x6B, /* 92 */
0x3, /* 93 */
0xEB, /* 94 */
0x0, /* 95 */
0x43, /* 96 */
0x1, /* 97 */
0xC3, /* 98 */
0x0, /* 99 */
0xEB, /* 100 */
0x2, /* 101 */
0xC3, /* 102 */
0x1, /* 103 */
0xEB, /* 104 */
0x1, /* 105 */
0x23, /* 106 */
0x0, /* 107 */
0xEB, /* 108 */
0x3, /* 109 */
0x23, /* 110 */
0x1, /* 111 */
0xA3, /* 112 */
0x0, /* 113 */
0xA3, /* 114 */
0x1, /* 115 */
0x1B, /* 116 */
0x0, /* 117 */
0x1B, /* 118 */
0x2, /* 119 */
0x63, /* 120 */
0x0, /* 121 */
0x1B, /* 122 */
0x1, /* 123 */
0x63, /* 124 */
0x1, /* 125 */
0xE3, /* 126 */
0x0, /* 127 */
0xCD, /* 128 */
0x0, /* 129 */
0xE3, /* 130 */
0x1, /* 131 */
0x13, /* 132 */
0x0, /* 133 */
0x13, /* 134 */
0x1, /* 135 */
0x93, /* 136 */
0x0, /* 137 */
0x1B, /* 138 */
0x3, /* 139 */
0x9B, /* 140 */
0x0, /* 141 */
0x9B, /* 142 */
0x2, /* 143 */
0x93, /* 144 */
0x1, /* 145 */
0x53, /* 146 */
0x0, /* 147 */
0x9B, /* 148 */
0x1, /* 149 */
0x9B, /* 150 */
0x3, /* 151 */
0x5B, /* 152 */
0x0, /* 153 */
0x5B, /* 154 */
0x2, /* 155 */
0x5B, /* 156 */
0x1, /* 157 */
0x5B, /* 158 */
0x3, /* 159 */
0x53, /* 160 */
0x1, /* 161 */
0xD3, /* 162 */
0x0, /* 163 */
0xDB, /* 164 */
0x0, /* 165 */
0xDB, /* 166 */
0x2, /* 167 */
0xDB, /* 168 */
0x1, /* 169 */
0xDB, /* 170 */
0x3, /* 171 */
0x3B, /* 172 */
0x0, /* 173 */
0x3B, /* 174 */
0x2, /* 175 */
0x3B, /* 176 */
0x1, /* 177 */
0xD3, /* 178 */
0x1, /* 179 */
0x3B, /* 180 */
0x3, /* 181 */
0xBB, /* 182 */
0x0, /* 183 */
0xBB, /* 184 */
0x2, /* 185 */
0xBB, /* 186 */
0x1, /* 187 */
0xBB, /* 188 */
0x3, /* 189 */
0x7B, /* 190 */
0x0, /* 191 */
0x2D, /* 192 */
0x0, /* 193 */
0x7B, /* 194 */
0x2, /* 195 */
0x7B, /* 196 */
0x1, /* 197 */
0x7B, /* 198 */
0x3, /* 199 */
0xFB, /* 200 */
0x0, /* 201 */
0xFB, /* 202 */
0x2, /* 203 */
0xFB, /* 204 */
0x1, /* 205 */
0xFB, /* 206 */
0x3, /* 207 */
0x7, /* 208 */
0x0, /* 209 */
0x7, /* 210 */
0x2, /* 211 */
0x7, /* 212 */
0x1, /* 213 */
0x7, /* 214 */
0x3, /* 215 */
0x87, /* 216 */
0x0, /* 217 */
0x87, /* 218 */
0x2, /* 219 */
0x87, /* 220 */
0x1, /* 221 */
0x87, /* 222 */
0x3, /* 223 */
0x33, /* 224 */
0x0, /* 225 */
0x47, /* 226 */
0x0, /* 227 */
0x47, /* 228 */
0x2, /* 229 */
0x47, /* 230 */
0x1, /* 231 */
0x47, /* 232 */
0x3, /* 233 */
0xC7, /* 234 */
0x0, /* 235 */
0xC7, /* 236 */
0x2, /* 237 */
0xC7, /* 238 */
0x1, /* 239 */
0x33, /* 240 */
0x1, /* 241 */
0xC7, /* 242 */
0x3, /* 243 */
0x27, /* 244 */
0x0, /* 245 */
0x27, /* 246 */
0x2, /* 247 */
0x27, /* 248 */
0x1, /* 249 */
0x27, /* 250 */
0x3, /* 251 */
0xA7, /* 252 */
0x0, /* 253 */
0xB3, /* 254 */
0x0, /* 255 */
0x19, /* 256 */
0x0, /* 257 */
0xB3, /* 258 */
0x1, /* 259 */
0x73, /* 260 */
0x0, /* 261 */
0xA7, /* 262 */
0x2, /* 263 */
0x73, /* 264 */
0x1, /* 265 */
0xA7, /* 266 */
0x1, /* 267 */
0xA7, /* 268 */
0x3, /* 269 */
0x67, /* 270 */
0x0, /* 271 */
0xF3, /* 272 */
0x0, /* 273 */
0x67, /* 274 */
0x2, /* 275 */
0x67, /* 276 */
0x1, /* 277 */
0x67, /* 278 */
0x3, /* 279 */
0xE7, /* 280 */
0x0, /* 281 */
0xE7, /* 282 */
0x2, /* 283 */
0xE7, /* 284 */
0x1, /* 285 */
0xE7, /* 286 */
0x3, /* 287 */
0xF3, /* 288 */
0x1, /* 289 */
0x17, /* 290 */
0x0, /* 291 */
0x17, /* 292 */
0x2 /* 293 */
};
const BYTE HuffLengthLOM[32] =
{
4, /* 0 */
@ -956,6 +1254,42 @@ const BYTE HuffLengthLOM[32] =
9 /* 31 */
};
const UINT16 HuffCodeLOM[32] =
{
0x0001, /* 0 */
0x0000, /* 1 */
0x0002, /* 2 */
0x0009, /* 3 */
0x0006, /* 4 */
0x0005, /* 5 */
0x000D, /* 6 */
0x000B, /* 7 */
0x0003, /* 8 */
0x001B, /* 9 */
0x0007, /* 10 */
0x0017, /* 11 */
0x0037, /* 12 */
0x000F, /* 13 */
0x004F, /* 14 */
0x006F, /* 15 */
0x002F, /* 16 */
0x00EF, /* 17 */
0x001F, /* 18 */
0x005F, /* 19 */
0x015F, /* 20 */
0x009F, /* 21 */
0x00DF, /* 22 */
0x01DF, /* 23 */
0x003F, /* 24 */
0x013F, /* 25 */
0x00BF, /* 26 */
0x01BF, /* 27 */
0x007F, /* 28 */
0x017F, /* 29 */
0x00FF, /* 30 */
0x01FF /* 31 */
};
UINT32 CopyOffsetBitsLUT[32] =
{
0x0, /* 0 */
@ -1113,11 +1447,22 @@ UINT32 LOMBaseLUT[30] =
} \
} \
#define NCrushWriteBits(_bits, _nbits) \
accumulator |= _bits << offset; \
offset += _nbits; \
if (offset >= 16) { \
*DstPtr++ = accumulator & 0xFF; \
*DstPtr++ = (accumulator >> 8) & 0xFF; \
accumulator >>= 16; \
offset -= 16; \
}
int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize, UINT32 flags)
{
UINT32 index;
UINT32 bits;
UINT32 nbits;
UINT32 offset;
BYTE* SrcPtr;
BYTE* SrcEnd;
UINT16 Mask;
@ -1374,16 +1719,554 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BY
return 1;
}
int ncrush_hash_table_add(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, UINT32 HistoryOffset)
{
BYTE* SrcPtr;
UINT32 Hash;
UINT32 Offset;
UINT32 EndOffset;
SrcPtr = pSrcData;
Offset = HistoryOffset;
EndOffset = Offset + SrcSize - 8;
while (Offset < EndOffset)
{
Hash = ncrush->HashTable[*((UINT16*) SrcPtr)];
ncrush->HashTable[*((UINT16*) SrcPtr)] = Offset;
ncrush->MatchTable[Offset] = Hash;
SrcPtr++;
Offset++;
}
return 1;
}
int ncrush_find_match_length(BYTE* Ptr1, BYTE* Ptr2, BYTE* HistoryPtr)
{
BYTE val1, val2;
BYTE* Ptr = Ptr1;
do
{
if (Ptr1 > HistoryPtr)
break;
val1 = *Ptr1++;
val2 = *Ptr2++;
}
while (val1 == val2);
return Ptr1 - (Ptr + 1);
}
int ncrush_find_best_match(NCRUSH_CONTEXT* ncrush, UINT32 HistoryOffset, UINT32* pCopyOffset)
{
int i, j;
int Length;
int MatchLength;
BYTE* MatchPtr;
UINT16 Offset;
UINT16 _Offset;
UINT16 CopyOffset;
BYTE* HistoryBuffer;
if (!ncrush->MatchTable[HistoryOffset])
return -1;
i = 4;
MatchLength = 2;
Offset = HistoryOffset;
HistoryBuffer = (BYTE*) ncrush->HistoryBuffer;
ncrush->MatchTable[0] = HistoryOffset;
CopyOffset = ncrush->MatchTable[HistoryOffset];
_Offset = ncrush->MatchTable[Offset];
MatchPtr = &HistoryBuffer[MatchLength];
while (--i < 0)
{
j = 0;
if (j == 0)
{
Offset = ncrush->MatchTable[_Offset];
if (MatchPtr[_Offset] == HistoryBuffer[HistoryOffset + MatchLength])
{
Offset = _Offset;
j++;
}
}
if (j == 1)
{
_Offset = ncrush->MatchTable[Offset];
if (MatchPtr[Offset] == HistoryBuffer[HistoryOffset + MatchLength])
{
j++;
}
}
if (j == 2)
{
Offset = ncrush->MatchTable[_Offset];
if (MatchPtr[_Offset] == HistoryBuffer[HistoryOffset + MatchLength])
{
Offset = _Offset;
j++;
}
}
if (j == 3)
{
_Offset = ncrush->MatchTable[Offset];
if (MatchPtr[Offset] == HistoryBuffer[HistoryOffset + MatchLength])
{
j++;
}
}
if (j == 4)
{
Offset = ncrush->MatchTable[_Offset];
if (MatchPtr[_Offset] == HistoryBuffer[HistoryOffset + MatchLength])
{
Offset = _Offset;
j++;
}
}
if (j == 5)
{
_Offset = ncrush->MatchTable[Offset];
if (MatchPtr[Offset] == HistoryBuffer[HistoryOffset + MatchLength])
{
j++;
}
}
if (j && (Offset != (HistoryOffset && Offset)))
{
Length = ncrush_find_match_length(&HistoryBuffer[HistoryOffset + 2],
&HistoryBuffer[Offset + 2], ncrush->HistoryPtr) + 2;
if (Length < 2)
return -1;
if ((Length <= MatchLength)
|| (MatchLength = Length, CopyOffset = Offset,
&HistoryBuffer[HistoryOffset + 2] < ncrush->HistoryPtr)
&& (Length <= 16))
{
_Offset = ncrush->MatchTable[Offset];
MatchPtr = &HistoryBuffer[MatchLength];
continue;
}
break;
}
}
ncrush->MatchTable[0] = 0;
*pCopyOffset = CopyOffset;
return MatchLength;
}
int ncrush_move_encoder_windows(NCRUSH_CONTEXT* ncrush, BYTE* HistoryPtr)
{
int i, j;
int NewHash;
int NewMatch;
UINT32 HistoryOffset;
if (HistoryPtr < &ncrush->HistoryBuffer[32768])
return -1;
if (HistoryPtr > &ncrush->HistoryBuffer[65536])
return -1;
CopyMemory(ncrush->HistoryBuffer, HistoryPtr - 32768, 32768);
HistoryOffset = HistoryPtr - 32768 - ncrush->HistoryBuffer;
for (i = 0; i < 65536; i += 4)
{
NewHash = ncrush->HashTable[i + 0] - HistoryOffset;
ncrush->HashTable[i + 0] = (NewHash <= 0) ? 0 : NewHash;
NewHash = ncrush->HashTable[i + 1] - HistoryOffset;
ncrush->HashTable[i + 1] = (NewHash <= 0) ? 0 : NewHash;
NewHash = ncrush->HashTable[i + 2] - HistoryOffset;
ncrush->HashTable[i + 2] = (NewHash <= 0) ? 0 : NewHash;
NewHash = ncrush->HashTable[i + 3] - HistoryOffset;
ncrush->HashTable[i + 3] = (NewHash <= 0) ? 0 : NewHash;
}
for (j = 0; j < 32768; j += 4)
{
NewMatch = ncrush->MatchTable[HistoryOffset + j + 0] - HistoryOffset;
ncrush->MatchTable[j + 0] = (NewMatch <= 0) ? 0 : NewMatch;
NewMatch = ncrush->MatchTable[HistoryOffset + j + 1] - HistoryOffset;
ncrush->MatchTable[j + 1] = (NewMatch <= 0) ? 0 : NewMatch;
NewMatch = ncrush->MatchTable[HistoryOffset + j + 2] - HistoryOffset;
ncrush->MatchTable[j + 2] = (NewMatch <= 0) ? 0 : NewMatch;
NewMatch = ncrush->MatchTable[HistoryOffset + j + 3] - HistoryOffset;
ncrush->MatchTable[j + 3] = (NewMatch <= 0) ? 0 : NewMatch;
}
ZeroMemory(&ncrush->MatchTable[32768], 65536);
return 1;
}
int ncrush_compress(NCRUSH_CONTEXT* ncrush, BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData, UINT32* pDstSize, UINT32* pFlags)
{
BYTE Literal;
BYTE* SrcPtr;
BYTE* DstPtr;
UINT32 bits;
UINT32 offset;
UINT16 Mask;
UINT32 MaskedBits;
UINT32 accumulator;
BYTE* SrcEndPtr;
BYTE* DstEndPtr;
BYTE* HistoryPtr;
int MatchIndex;
UINT32 IndexLEC;
UINT32 IndexLOM;
UINT32 BitLength;
UINT32 CopyOffset;
UINT32 OldCopyOffset;
UINT32* OffsetCache;
UINT32 OffsetCacheIndex;
UINT32 HistoryOffset;
BYTE* HistoryBuffer;
UINT32 HistoryBufferSize;
BYTE* HistoryBufferEndPtr;
UINT32 CopyOffsetIndex;
UINT32 CopyOffsetBits;
HistoryBuffer = ncrush->HistoryBuffer;
if (SrcSize + ncrush->HistoryOffset >= 65529)
{
if (ncrush->HistoryOffset == (ncrush->HistoryBufferSize + 1))
{
ncrush->HistoryOffset = 0;
ncrush->HistoryPtr = HistoryBuffer;
*pFlags = 0;
}
else
{
ncrush_move_encoder_windows(ncrush, &HistoryBuffer[ncrush->HistoryOffset]);
HistoryPtr = &HistoryBuffer[32768];
ncrush->HistoryPtr = &HistoryBuffer[32768];
ncrush->HistoryOffset = 32768;
*pFlags = PACKET_AT_FRONT;
}
}
else
{
*pFlags = 0;
}
bits = 0;
offset = 0;
accumulator = 0;
DstPtr = pDstData;
SrcPtr = pSrcData;
SrcEndPtr = &pSrcData[SrcSize];
DstEndPtr = &pDstData[SrcSize - 1];
OffsetCache = ncrush->OffsetCache;
HistoryPtr = &HistoryBuffer[ncrush->HistoryOffset];
HistoryBufferEndPtr = &HistoryBuffer[65536];
HistoryBufferSize = ncrush->HistoryBufferSize;
CopyOffset = 0;
ncrush_hash_table_add(ncrush, pSrcData, SrcSize, HistoryPtr - HistoryBuffer);
CopyMemory(HistoryPtr, pSrcData, SrcSize);
ncrush->HistoryPtr = HistoryPtr + SrcSize;
while (SrcPtr < (SrcEndPtr - 2))
{
MatchIndex = 0;
HistoryOffset = HistoryPtr - HistoryBuffer;
if (ncrush->HistoryPtr && (HistoryPtr > ncrush->HistoryPtr))
return -1;
if (HistoryOffset >= 65536)
return -1;
if (ncrush->MatchTable[HistoryOffset])
{
CopyOffset = 0;
MatchIndex = ncrush_find_best_match(ncrush, HistoryOffset, &CopyOffset);
if (MatchIndex == -1)
return -1;
}
if ( MatchIndex )
CopyOffset = (HistoryBufferSize - 1) & (HistoryPtr - &HistoryBuffer[CopyOffset]);
if ((MatchIndex == 2) && (CopyOffset >= 64))
MatchIndex = 0;
if (!MatchIndex)
{
/* Literal */
Literal = *SrcPtr++;
HistoryPtr++;
if ((DstPtr + 2) > DstEndPtr)
{
ncrush_context_reset(ncrush);
*pFlags = PACKET_FLUSHED;
return 1;
}
BitLength = HuffLengthLEC[Literal];
IndexLEC = HuffCodeLEC[Literal];
if (BitLength > 15)
return -1;
NCrushWriteBits(IndexLEC, BitLength);
}
else
{
HistoryPtr += MatchIndex;
SrcPtr += MatchIndex;
if (!MatchIndex)
return -1;
if ((DstPtr + 8) > DstEndPtr)
{
ncrush_context_reset(ncrush);
*pFlags = PACKET_FLUSHED;
return 1;
}
OffsetCacheIndex = 5;
if ((CopyOffset == OffsetCache[0]) || (CopyOffset == OffsetCache[1]) ||
(CopyOffset == OffsetCache[2]) || (CopyOffset == OffsetCache[3]))
{
if (CopyOffset == OffsetCache[3])
{
OldCopyOffset = OffsetCache[3];
OffsetCache[3] = OffsetCache[0];
OffsetCache[0] = OldCopyOffset;
OffsetCacheIndex = 3;
}
else
{
if (CopyOffset == OffsetCache[2])
{
OldCopyOffset = OffsetCache[2];
OffsetCache[2] = OffsetCache[0];
OffsetCache[0] = OldCopyOffset;
OffsetCacheIndex = 2;
}
else
{
if (CopyOffset == OffsetCache[1])
{
OldCopyOffset = OffsetCache[1];
OffsetCache[1] = OffsetCache[0];
OffsetCache[0] = OldCopyOffset;
OffsetCacheIndex = 1;
}
else
{
if (CopyOffset == OffsetCache[0])
{
OffsetCacheIndex = 0;
}
}
}
}
}
else
{
OffsetCache[3] = OffsetCache[2];
OffsetCache[2] = OffsetCache[1];
OffsetCache[1] = OffsetCache[0];
OffsetCache[0] = CopyOffset;
}
if (OffsetCacheIndex > 4)
{
/* CopyOffset not in OffsetCache */
if (CopyOffset >= 256)
bits = (CopyOffset >> 7) | 0x100;
else
bits = CopyOffset;
CopyOffsetIndex = ncrush->HuffTableCopyOffset[bits];
CopyOffsetBits = CopyOffsetBitsLUT[CopyOffsetIndex];
BitLength = HuffLengthLEC[CopyOffsetIndex + 257];
IndexLEC = *((UINT16*)&HuffCodeLEC[2 * (CopyOffsetIndex + 257)]);
if (BitLength > 15)
return -1;
if (CopyOffsetBits > 18)
return -1;
NCrushWriteBits(IndexLEC, BitLength);
Mask = ((1 << CopyOffsetBits) - 1);
MaskedBits = CopyOffset & Mask;
NCrushWriteBits(MaskedBits, CopyOffsetBits);
if ((MatchIndex - 2) >= 768)
IndexLOM = 28;
else
IndexLOM = ncrush->HuffTableCopyOffset[MatchIndex + 1022];
BitLength = HuffLengthLOM[IndexLOM];
IndexLOM = LOMBitsLUT[IndexLOM];
NCrushWriteBits(HuffCodeLOM[IndexLOM], BitLength);
Mask = ((1 << IndexLOM) - 1);
MaskedBits = (MatchIndex - 2) & Mask;
NCrushWriteBits(MaskedBits, IndexLOM);
if ((MaskedBits + LOMBaseLUT[IndexLOM]) != MatchIndex)
return -1;
}
else
{
/* CopyOffset in OffsetCache */
BitLength = HuffLengthLEC[OffsetCacheIndex + 289];
IndexLEC = *((UINT16*)&HuffCodeLEC[2 * (OffsetCacheIndex + 289)]);
if (BitLength >= 15)
return -1;
NCrushWriteBits(IndexLEC, BitLength);
if ((MatchIndex - 2) >= 768)
IndexLOM = 28;
else
IndexLOM = ncrush->HuffTableCopyOffset[MatchIndex + 1022];
BitLength = HuffLengthLOM[IndexLOM];
IndexLOM = LOMBitsLUT[IndexLOM];
NCrushWriteBits(HuffCodeLOM[IndexLOM], BitLength);
Mask = ((1 << IndexLOM) - 1);
MaskedBits = (MatchIndex - 2) & Mask;
NCrushWriteBits(MaskedBits, IndexLOM);
if ((MaskedBits + LOMBaseLUT[IndexLOM]) != MatchIndex)
return -1;
}
}
if (HistoryPtr >= HistoryBufferEndPtr)
return -1;
}
while (SrcPtr < SrcEndPtr)
{
if (DstPtr + 2 > DstEndPtr)
{
ncrush_context_reset(ncrush);
*pFlags = PACKET_FLUSHED;
return 1;
}
Literal = *SrcPtr++;
HistoryPtr++;
BitLength = HuffLengthLEC[Literal];
IndexLEC = HuffCodeLEC[Literal];
if (BitLength > 15)
return -1;
NCrushWriteBits(IndexLEC, BitLength);
}
if ((DstPtr + 4) >= DstEndPtr)
{
ncrush_context_reset(ncrush);
*pFlags = PACKET_FLUSHED;
return 1;
}
*DstPtr++ = accumulator & 0xFF;
*DstPtr++ = (accumulator >> 8) & 0xFF;
*pDstSize = DstPtr - pDstData;
ncrush->HistoryOffset = HistoryPtr - HistoryBuffer;
if (ncrush->HistoryOffset >= ncrush->HistoryBufferSize)
return -1;
return 1;
}
void ncrush_generate_tables(NCRUSH_CONTEXT *context)
{
int i, j, k;
k = 0;
for (i = 0; i < 28; i++)
{
for (j = 0; j < 1 << LOMBitsLUT[i]; j++)
{
context->HuffTableLOM[k++ + 2] = i;
}
}
k = 0;
for (i = 0; i < 16; i++)
{
for (j = 0; j < 1 << CopyOffsetBitsLUT[i]; j++)
{
context->HuffTableCopyOffset[k++] = i;
}
}
k /= 128;
for (i = 16; i < 32; i++)
{
for (j = 0; j < 1 << (CopyOffsetBitsLUT[i] - 7); j++)
{
context->HuffTableCopyOffset[k++ + 256] = i;
}
}
}
void ncrush_context_reset(NCRUSH_CONTEXT* ncrush)
{
ZeroMemory(&(ncrush->HistoryBuffer), sizeof(ncrush->HistoryBuffer));
ZeroMemory(&(ncrush->OffsetCache), sizeof(ncrush->OffsetCache));
ZeroMemory(&(ncrush->MatchTable), sizeof(ncrush->MatchTable));
ZeroMemory(&(ncrush->HashTable), sizeof(ncrush->HashTable));
ncrush->HistoryOffset = 0;
ncrush->HistoryPtr = &(ncrush->HistoryBuffer[ncrush->HistoryOffset]);
}
@ -1401,11 +2284,15 @@ NCRUSH_CONTEXT* ncrush_context_new(BOOL Compressor)
ZeroMemory(&(ncrush->OffsetCache), sizeof(ncrush->OffsetCache));
ncrush->HistoryEndOffset = 65535;
ncrush->HistoryBufferSize = 65536;
ZeroMemory(&(ncrush->HistoryBuffer), sizeof(ncrush->HistoryBuffer));
ncrush->HistoryBufferFence = 0xABABABAB;
ncrush->HistoryOffset = 0;
ncrush->HistoryPtr = &(ncrush->HistoryBuffer[ncrush->HistoryOffset]);
ncrush_generate_tables(ncrush);
}
return ncrush;

View File

@ -96,10 +96,8 @@ int test_NCrushDecompressBells()
int TestFreeRDPCodecNCrush(int argc, char* argv[])
{
//test_NCrushCompressBells();
test_NCrushDecompressBells();
//BitDump(TEST_BELLS_NCRUSH, (sizeof(TEST_BELLS_NCRUSH) - 1) * 8, 0);
test_NCrushCompressBells();
//test_NCrushDecompressBells();
return 0;
}