// Section 2.4.1.3.14 private static void PackCompressedChunkSignature(byte[] Data, DecompressionState state, CompressedChunkHeader header) { UInt16 temp = (UInt16)(header.AsUInt16() & (ushort)0x8FFF); UInt16 result = (UInt16)(temp | (ushort)0x3000); header.SetFrom(result); }
// Section 2.4.1.3.16 private static void PackCompressedChunkFlag(byte[] Data, DecompressionState state, UInt16 CompressedFlag, CompressedChunkHeader header) { if (CompressedFlag != 0 && CompressedFlag != 1) { throw new ArgumentOutOfRangeException("CompressedFlag", "CompressedFlag must be 0 or 1"); } UInt16 temp1 = (UInt16)(header.AsUInt16() & (ushort)0x7FFF); UInt16 temp2 = (UInt16)(CompressedFlag << 15); UInt16 result = (UInt16)(temp1 | temp2); header.SetFrom(result); }
// Section 2.4.1.3.13 // page 66 private static void PackCompressedChunkSize(byte[] Data, DecompressionState state, UInt16 size, CompressedChunkHeader header) { if (size > 4098 || size < 3) { throw new ArgumentOutOfRangeException("size", "Size must be between 3 - 4098"); } UInt16 temp1 = (UInt16)(header.AsUInt16() & (ushort)(0xF000)); UInt16 temp2 = (UInt16)(size - 3); UInt16 result = (UInt16)(temp1 | temp2); header.SetFrom(result); }
// 2.4.1.3.7 Compressing a DecompressedChunk // page 62 private static void CompressDecompressedChunk(byte[] Data, CompressedBuffer resultBuffer, DecompressionState state) { var CompressedEnd = state.CompressedChunkStart + 4098; state.CompressedCurrent = state.CompressedChunkStart + 2; var DecompressedEnd = Math.Min(state.DecompressedChunkStart + 4096, state.DecompressedBufferEnd); while (state.DecompressedCurrent < DecompressedEnd && state.CompressedCurrent < CompressedEnd) { CompressTokenSequence(Data, resultBuffer, state, CompressedEnd, DecompressedEnd); } UInt16 CompressedFlag; if (state.DecompressedCurrent < DecompressedEnd) { CompressRawChunk(Data, resultBuffer, state, DecompressedEnd - 1); CompressedFlag = 0; } else { CompressedFlag = 1; } UInt16 size = Convert.ToUInt16(state.CompressedCurrent - state.CompressedChunkStart); var header = new CompressedChunkHeader(0x0000); PackCompressedChunkSize(Data, state, size, header); PackCompressedChunkFlag(Data, state, CompressedFlag, header); PackCompressedChunkSignature(Data, state, header); // SET the CompressedChunkHeader (section 2.4.1.1.5) located at CompressedChunkStart TO Header var bytes = BitConverter.GetBytes(header.AsUInt16()); resultBuffer.SetByte(state.CompressedChunkStart, bytes.First()); resultBuffer.SetByte(state.CompressedChunkStart + 1, bytes.Skip(1).Single()); }