Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

mrcf.c File Reference

#include "ntrtlp.h"
#include <stdio.h>

Go to the source code of this file.

Classes

struct  _MRCF_BIT_IO
struct  _MDSIGNATURE

Defines

#define wBACKPOINTERMAX   (4415)
#define MD_STAMP   0x5344
#define MASK_VALID_mds   0x0300
#define minimum(a, b)   (a < b ? a : b)

Typedefs

typedef _MRCF_BIT_IO MRCF_BIT_IO
typedef MRCF_BIT_IOPMRCF_BIT_IO
typedef _MDSIGNATURE MDSIGNATURE
typedef MDSIGNATUREPMDSIGNATURE

Functions

VOID MrcfSetBitBuffer (PUCHAR pb, ULONG cb, PMRCF_BIT_IO BitIo)
VOID MrcfFillBitBuffer (PMRCF_BIT_IO BitIo)
USHORT MrcfReadBit (PMRCF_BIT_IO BitIo)
USHORT MrcfReadNBits (LONG cbits, PMRCF_BIT_IO BitIo)
NTSTATUS RtlDecompressBufferMrcf (OUT PUCHAR UncompressedBuffer, IN ULONG UncompressedBufferSize, IN PUCHAR CompressedBuffer, IN ULONG CompressedBufferSize, OUT PULONG FinalUncompressedSize)


Define Documentation

#define MASK_VALID_mds   0x0300
 

Definition at line 94 of file mrcf.c.

Referenced by RtlDecompressBufferMrcf().

#define MD_STAMP   0x5344
 

Definition at line 93 of file mrcf.c.

Referenced by RtlDecompressBufferMrcf().

#define minimum a,
 )     (a < b ? a : b)
 

Definition at line 101 of file mrcf.c.

Referenced by MrcfReadNBits().

#define wBACKPOINTERMAX   (4415)
 

Definition at line 53 of file mrcf.c.

Referenced by RtlDecompressBufferMrcf().


Typedef Documentation

typedef struct _MDSIGNATURE MDSIGNATURE
 

typedef struct _MRCF_BIT_IO MRCF_BIT_IO
 

typedef MDSIGNATURE* PMDSIGNATURE
 

Definition at line 91 of file mrcf.c.

Referenced by RtlDecompressBufferMrcf().

typedef MRCF_BIT_IO* PMRCF_BIT_IO
 

Definition at line 47 of file mrcf.c.


Function Documentation

VOID MrcfFillBitBuffer PMRCF_BIT_IO  BitIo  ) 
 

Definition at line 541 of file mrcf.c.

References _MRCF_BIT_IO::abitsBB, ASSERT, ASSERTMSG, _MRCF_BIT_IO::cbBB, _MRCF_BIT_IO::cbitsBB, FALSE, _MRCF_BIT_IO::pbBB, and USHORT.

Referenced by MrcfReadBit(), and MrcfReadNBits().

00547 : 00548 00549 Fill abitsBB from static bit buffer 00550 00551 Arguments: 00552 00553 BitIo - Supplies a pointer to the bit buffer statics 00554 00555 Return Value: 00556 00557 None. 00558 00559 --*/ 00560 00561 { 00562 ASSERT((BitIo->cbitsBB) == 0); 00563 00564 switch (BitIo->cbBB) { 00565 00566 case 0: 00567 00568 ASSERTMSG("no bits left in coded buffer!", FALSE); 00569 00570 break; 00571 00572 case 1: 00573 00574 // 00575 // Get last byte and adjust count 00576 // 00577 00578 BitIo->cbitsBB = 8; 00579 BitIo->abitsBB = *(BitIo->pbBB)++; 00580 BitIo->cbBB--; 00581 00582 break; 00583 00584 default: 00585 00586 // 00587 // Get word and adjust count 00588 // 00589 00590 BitIo->cbitsBB = 16; 00591 BitIo->abitsBB = *((USHORT *)(BitIo->pbBB))++; 00592 BitIo->cbBB -= 2; 00593 00594 break; 00595 } 00596 }

USHORT MrcfReadBit PMRCF_BIT_IO  BitIo  ) 
 

Definition at line 387 of file mrcf.c.

References _MRCF_BIT_IO::abitsBB, _MRCF_BIT_IO::cbitsBB, MrcfFillBitBuffer(), and USHORT.

Referenced by RtlDecompressBufferMrcf().

00393 : 00394 00395 Get next bit from bit buffer 00396 00397 Arguments: 00398 00399 BitIo - Supplies a pointer to the bit buffer statics 00400 00401 Return Value: 00402 00403 USHORT - Returns next bit (0 or 1) 00404 00405 --*/ 00406 00407 { 00408 USHORT bit; 00409 00410 // 00411 // Check if no bits available 00412 // 00413 00414 if ((BitIo->cbitsBB) == 0) { 00415 00416 MrcfFillBitBuffer(BitIo); 00417 } 00418 00419 // 00420 // Decrement the bit count 00421 // get the bit, remove it, and return the bit 00422 // 00423 00424 (BitIo->cbitsBB)--; 00425 bit = (BitIo->abitsBB) & 1; 00426 (BitIo->abitsBB) >>= 1; 00427 00428 return bit; 00429 }

USHORT MrcfReadNBits LONG  cbits,
PMRCF_BIT_IO  BitIo
 

Definition at line 437 of file mrcf.c.

References _MRCF_BIT_IO::abitsBB, ASSERT, _MRCF_BIT_IO::cbitsBB, minimum, MrcfFillBitBuffer(), and USHORT.

Referenced by RtlDecompressBufferMrcf().

00444 : 00445 00446 Get next N bits from bit buffer 00447 00448 Arguments: 00449 00450 cbits - count of bits to get 00451 00452 BitIo - Supplies a pointer to the bit buffer statics 00453 00454 Return Value: 00455 00456 USHORT - Returns next cbits bits. 00457 00458 --*/ 00459 00460 { 00461 ULONG abits; // Bits to return 00462 LONG cbitsPart; // Partial count of bits 00463 ULONG cshift; // Shift count 00464 ULONG mask; // Mask 00465 00466 // 00467 // Largest number of bits we should read at one time is 12 bits for 00468 // a 12-bit offset. The largest length field component that we 00469 // read is 8 bits. If this routine were used for some other purpose, 00470 // it can support up to 15 (NOT 16) bit reads, due to how the masking 00471 // code works. 00472 // 00473 00474 ASSERT(cbits <= 12); 00475 00476 // 00477 // No shift and no bits yet 00478 // 00479 00480 cshift = 0; 00481 abits = 0; 00482 00483 while (cbits > 0) { 00484 00485 // 00486 // If not bits available get some bits 00487 // 00488 00489 if ((BitIo->cbitsBB) == 0) { 00490 00491 MrcfFillBitBuffer(BitIo); 00492 } 00493 00494 // 00495 // Number of bits we can read 00496 // 00497 00498 cbitsPart = minimum((BitIo->cbitsBB), cbits); 00499 00500 // 00501 // Mask for bits we want, extract and store them 00502 // 00503 00504 mask = (1 << cbitsPart) - 1; 00505 abits |= ((BitIo->abitsBB) & mask) << cshift; 00506 00507 // 00508 // Remember the next chunk of bits 00509 // 00510 00511 cshift = cbitsPart; 00512 00513 // 00514 // Update bit buffer, move remaining bits down and 00515 // update count of bits left 00516 // 00517 00518 (BitIo->abitsBB) >>= cbitsPart; 00519 (BitIo->cbitsBB) -= cbitsPart; 00520 00521 // 00522 // Update count of bits left to read 00523 // 00524 00525 cbits -= cbitsPart; 00526 } 00527 00528 // 00529 // Return requested bits 00530 // 00531 00532 return (USHORT)abits; 00533 }

VOID MrcfSetBitBuffer PUCHAR  pb,
ULONG  cb,
PMRCF_BIT_IO  BitIo
 

Definition at line 347 of file mrcf.c.

References _MRCF_BIT_IO::abitsBB, _MRCF_BIT_IO::cbBB, _MRCF_BIT_IO::cbBBInitial, _MRCF_BIT_IO::cbitsBB, and _MRCF_BIT_IO::pbBB.

Referenced by RtlDecompressBufferMrcf().

00355 : 00356 00357 Set statics with coded buffer pointer and length 00358 00359 Arguments: 00360 00361 pb - pointer to compressed data buffer 00362 00363 cb - length of compressed data buffer 00364 00365 BitIo - Supplies a pointer to the bit buffer statics 00366 00367 Return Value: 00368 00369 None. 00370 00371 --*/ 00372 00373 { 00374 BitIo->pbBB = pb; 00375 BitIo->cbBB = cb; 00376 BitIo->cbBBInitial = cb; 00377 BitIo->cbitsBB = 0; 00378 BitIo->abitsBB = 0; 00379 }

NTSTATUS RtlDecompressBufferMrcf OUT PUCHAR  UncompressedBuffer,
IN ULONG  UncompressedBufferSize,
IN PUCHAR  CompressedBuffer,
IN ULONG  CompressedBufferSize,
OUT PULONG  FinalUncompressedSize
 

Definition at line 132 of file mrcf.c.

References ASSERT, ASSERTMSG, MASK_VALID_mds, MD_STAMP, MrcfReadBit(), MrcfReadNBits(), MrcfSetBitBuffer(), PMDSIGNATURE, TRUE, USHORT, and wBACKPOINTERMAX.

00142 : 00143 00144 This routine decompresses a buffer of StandardCompressed or MaxCompressed 00145 data. 00146 00147 Arguments: 00148 00149 UncompressedBuffer - buffer to receive uncompressed data 00150 00151 UncompressedBufferSize - length of UncompressedBuffer 00152 00153 NOTE: UncompressedBufferSize must be the EXACT length of the uncompressed 00154 data, as Decompress uses this information to detect 00155 when decompression is complete. If this value is 00156 incorrect, Decompress may crash! 00157 00158 CompressedBuffer - buffer containing compressed data 00159 00160 CompressedBufferSize - length of CompressedBuffer 00161 00162 WorkSpace - pointer to a private work area for use by this operation 00163 00164 Return Value: 00165 00166 ULONG - Returns the size of the decompressed data in bytes. Returns 0 if 00167 there was an error in the decompress. 00168 00169 --*/ 00170 00171 { 00172 MRCF_BIT_IO WorkSpace; 00173 00174 ULONG cbMatch; // Length of match string 00175 ULONG i; // Index in UncompressedBuffer to receive decoded data 00176 ULONG iMatch; // Index in UncompressedBuffer of matched string 00177 ULONG k; // Number of bits in length string 00178 ULONG off; // Offset from i in UncompressedBuffer of match string 00179 USHORT x; // Current bit being examined 00180 ULONG y; 00181 00182 // 00183 // verify that compressed data starts with proper signature 00184 // 00185 00186 if (CompressedBufferSize < sizeof(MDSIGNATURE) || // Must have signature 00187 ((PMDSIGNATURE)CompressedBuffer)->sigStamp != MD_STAMP || // Stamp must be OK 00188 ((PMDSIGNATURE)CompressedBuffer)->sigType & (~MASK_VALID_mds)) { // Type must be OK 00189 00190 *FinalUncompressedSize = 0; 00191 return STATUS_BAD_COMPRESSION_BUFFER; 00192 } 00193 00194 // 00195 // Skip over the valid signature 00196 // 00197 00198 CompressedBufferSize -= sizeof(MDSIGNATURE); 00199 CompressedBuffer += sizeof(MDSIGNATURE); 00200 00201 // 00202 // Set up for decompress, start filling UncompressedBuffer at front 00203 // 00204 00205 i = 0; 00206 00207 // 00208 // Set statics to save parm passing 00209 // 00210 00211 MrcfSetBitBuffer(CompressedBuffer,CompressedBufferSize,&WorkSpace); 00212 00213 while (TRUE) { 00214 00215 y = MrcfReadNBits(2,&WorkSpace); 00216 00217 // 00218 // Check if next 7 bits are a byte 00219 // 1 if 128..255 (0x80..0xff), 2 if 0..127 (0x00..0x7f) 00220 // 00221 00222 if (y == 1 || y == 2) { 00223 00224 ASSERTMSG("Don't exceed expected length ", i<UncompressedBufferSize); 00225 00226 UncompressedBuffer[i] = (UCHAR)((y == 1 ? 0x80 : 0) | MrcfReadNBits(7,&WorkSpace)); 00227 00228 i++; 00229 00230 } else { 00231 00232 // 00233 // Have match sequence 00234 // 00235 00236 // 00237 // Get the offset 00238 // 00239 00240 if (y == 0) { 00241 00242 // 00243 // next 6 bits are offset 00244 // 00245 00246 off = MrcfReadNBits(6,&WorkSpace); 00247 00248 ASSERTMSG("offset 0 is invalid ", off != 0); 00249 00250 } else { 00251 00252 x = MrcfReadBit(&WorkSpace); 00253 00254 if (x == 0) { 00255 00256 // 00257 // next 8 bits are offset-64 (0x40) 00258 // 00259 00260 off = MrcfReadNBits(8, &WorkSpace) + 64; 00261 00262 } else { 00263 00264 // 00265 // next 12 bits are offset-320 (0x140) 00266 // 00267 00268 off = MrcfReadNBits(12, &WorkSpace) + 320; 00269 00270 if (off == wBACKPOINTERMAX) { 00271 00272 // 00273 // EOS marker 00274 // 00275 00276 if (i >= UncompressedBufferSize) { 00277 00278 // 00279 // Done with entire buffer 00280 // 00281 00282 *FinalUncompressedSize = i; 00283 return STATUS_SUCCESS; 00284 00285 } else { 00286 00287 // 00288 // More to do 00289 // Done with a 512-byte chunk 00290 // 00291 00292 continue; 00293 } 00294 } 00295 } 00296 } 00297 00298 ASSERTMSG("Don't exceed expected length ", i<UncompressedBufferSize); 00299 ASSERTMSG("Cannot match before start of uncoded buffer! ", off <= i); 00300 00301 // 00302 // Get the length - logarithmically encoded 00303 // 00304 00305 for (k=0; (x=MrcfReadBit(&WorkSpace)) == 0; k++) { NOTHING; } 00306 00307 ASSERT(k <= 8); 00308 00309 if (k == 0) { 00310 00311 // 00312 // All matches at least 2 chars long 00313 // 00314 00315 cbMatch = 2; 00316 00317 } else { 00318 00319 cbMatch = (1 << k) + 1 + MrcfReadNBits(k, &WorkSpace); 00320 } 00321 00322 ASSERTMSG("Don't exceed buffer size ", (i - off + cbMatch - 1) <= UncompressedBufferSize); 00323 00324 // 00325 // Copy the matched string 00326 // 00327 00328 iMatch = i - off; 00329 00330 while ( (cbMatch > 0) && (i<UncompressedBufferSize) ) { 00331 00332 UncompressedBuffer[i++] = UncompressedBuffer[iMatch++]; 00333 cbMatch--; 00334 } 00335 00336 ASSERTMSG("Should have copied it all ", cbMatch == 0); 00337 } 00338 } 00339 }


Generated on Sat May 15 19:44:48 2004 for test by doxygen 1.3.7