public Byte[] GetBytes() { Int32 n = GetByteCount(); if (n == -1) { return(null); } Byte[] buf = new Byte[n]; if (n == 0) { return(buf); } Int32 MAX_BITS = mData[2] & 0x1f; Boolean BLOCK_MODE = ((mData[2] & 0x80) != 0); n = 1 << MAX_BITS; mPrefixCode = new Int32[n]; mSuffixByte = new Byte[n]; for (Int32 i = 0; i < 256; i++) { mPrefixCode[i] = -1; mSuffixByte[i] = (Byte)i; } Int32 block_offset = 3; BitReaderL R = new BitReaderL(mData, block_offset); Int32 code_size = 9; Int32 code_max = (1 << code_size) - 1; Int32 next_free = (BLOCK_MODE) ? 257 : 256; Int32 code = R.Next(code_size); n = 0; Byte b = Put(buf, ref n, code); // first code gets output without adding anything to dictionary Int32 prev_code = code; while ((code = R.Next(code_size)) != -1) { if ((code == 256) && BLOCK_MODE) { // start reading a new block, with code size reset to 9 R = new BitReaderL(mData, block_offset = NextBlockOffset(block_offset, R.Offset, code_size)); code_max = (1 << (code_size = 9)) - 1; next_free = 256; // use 256 instead of 257 so next code isn't (usably) added to dictionary continue; } if (code == next_free) { // special case: the last byte of this code is the same as the first byte of the previous code mLength[code] = mLength[prev_code] + 1; mPrefixCode[code] = prev_code; mSuffixByte[code] = b; } b = Put(buf, ref n, code); if (next_free <= code_max) { // add a new code to dictionary for prev_code plus the first byte of current code mLength[next_free] = mLength[prev_code] + 1; mPrefixCode[next_free] = prev_code; mSuffixByte[next_free] = b; if ((next_free == code_max) && (code_size < MAX_BITS)) { // start reading a new block, with code size increased by 1 R = new BitReaderL(mData, block_offset = NextBlockOffset(block_offset, R.Offset, code_size)); code_max = (1 << ++code_size) - 1; } next_free++; } prev_code = code; } return(buf); }
public Int32 GetByteCount() { if (mSize != -2) { return(mSize); } if (!HasHeader(mData)) { return(mSize = -1); } Int32 MAX_BITS = mData[2] & 0x1f; if (MAX_BITS > 24) { return(mSize = -1); // current BitReader only handles up to 24-bit code words } if ((mData[2] & 0x60) != 0) { return(mSize = -1); // unsupported flag bits } Boolean BLOCK_MODE = ((mData[2] & 0x80) != 0); Int32 n = 1 << MAX_BITS; mLength = new Int32[n]; for (Int32 i = 0; i < 256; i++) { mLength[i] = 1; } Int32 block_offset = 3; BitReaderL R = new BitReaderL(mData, block_offset); Int32 code_size = 9; Int32 code_max = (1 << code_size) - 1; Int32 next_free = (BLOCK_MODE) ? 257 : 256; Int32 code = R.Next(code_size); if (code == -1) { return(mSize = 0); // valid 0-byte output } n = 1; // first code is always for 1 byte, so start count at 1 Int32 prev_code = code; while ((code = R.Next(code_size)) != -1) { if ((code == 256) && BLOCK_MODE) { // start reading a new block, with code size reset to 9 R = new BitReaderL(mData, block_offset = NextBlockOffset(block_offset, R.Offset, code_size)); code_max = (1 << (code_size = 9)) - 1; next_free = 256; // use 256 instead of 257 so next code isn't (usably) added to dictionary continue; } if (code > next_free) { return(mSize = -1); // invalid or corrupt input } if (next_free <= code_max) { // new dictionary entries are always 1 byte longer than the previously received one. mLength[next_free] = mLength[prev_code] + 1; if ((next_free == code_max) && (code_size < MAX_BITS)) { // start reading a new block, with code size increased by 1 R = new BitReaderL(mData, block_offset = NextBlockOffset(block_offset, R.Offset, code_size)); code_max = (1 << ++code_size) - 1; } next_free++; } n += mLength[code]; prev_code = code; } return(mSize = n); }