public void Encode(Stream input, Stream output) { _initialRead = true; _codeByte = 0; var matches = _matchParser.ParseMatches(input); foreach (var match in matches) { if (input.Position < match.Position) { WriteRawData(input, output, match.Position - input.Position); } if (_initialRead) { _initialRead = false; } WriteMatchData(input, output, match); } if (input.Position < input.Length) { WriteRawData(input, output, input.Length - input.Position); } // Write ending match flag output.WriteByte(0x11); output.WriteByte(0); output.WriteByte(0); }
internal void WriteCompressedData(Stream input, Stream output) { var matches = _matchParser.ParseMatches(input).ToArray(); int bufferedBlocks = 0, blockBufferLength = 1, lzIndex = 0; byte[] blockBuffer = new byte[8 * 4 + 1]; while (input.Position < input.Length) { if (bufferedBlocks >= 8) { WriteBlockBuffer(output, blockBuffer, blockBufferLength); bufferedBlocks = 0; blockBufferLength = 1; } if (lzIndex < matches.Length && input.Position == matches[lzIndex].Position) { blockBufferLength = WriteCompressedBlockToBuffer(matches[lzIndex], blockBuffer, blockBufferLength, bufferedBlocks); input.Position += matches[lzIndex++].Length; } else { blockBuffer[blockBufferLength++] = (byte)input.ReadByte(); } bufferedBlocks++; } WriteBlockBuffer(output, blockBuffer, blockBufferLength); }
public void Encode(Stream input, Stream output) { var originalOutputPosition = output.Position; output.Position += 6; var block = new Block(); var matches = _matchParser.ParseMatches(input); foreach (var match in matches) { // Compress raw data if (input.Position < match.Position) { CompressRawData(input, output, block, (int)(match.Position - input.Position)); } // Compress match CompressMatchData(input, output, block, match); } // Compress raw data if (input.Position < input.Length) { CompressRawData(input, output, block, (int)(input.Length - input.Position)); } WriteAndResetBuffer(output, block); // Write header information WriteHeaderData(input, output, originalOutputPosition); }
public void Encode(Stream input, Stream output) { var block = new Block(); output.Position += 9; var matches = _matchParser.ParseMatches(input); foreach (var match in matches) { if (input.Position < match.Position) { WriteRawData(input, output, block, match.Position - input.Position); } WriteMatchData(input, output, block, match); } if (input.Position < input.Length) { WriteRawData(input, output, block, input.Length - input.Position); } if (block.flagCount > 0) { WriteAndResetBuffer(output, block); } WriteHeaderData(output, (int)input.Length); }
public void Encode(Stream input, Stream output) { if (input.Length > 0xFFFFFF) { throw new InvalidOperationException("Data to compress is too long."); } var compressionHeader = new byte[] { 0x30, (byte)(input.Length & 0xFF), (byte)((input.Length >> 8) & 0xFF), (byte)((input.Length >> 16) & 0xFF) }; output.Write(compressionHeader, 0, 4); _buffer = new byte[0x80]; var matches = _matchParser.ParseMatches(input); foreach (var match in matches) { if (input.Position < match.Position) { // If we have unmatched data before the match, create enough uncompressed blocks HandleUncompressedData(input, output, (int)(match.Position - input.Position)); } // Write matched data as compressed block var rleValue = (byte)input.ReadByte(); HandleCompressedBlock(output, rleValue, match.Length); input.Position += match.Length - 1; } // If there is unmatched data left after last match, handle as uncompressed block if (input.Position < input.Length) { HandleUncompressedData(input, output, (int)(input.Length - input.Position)); } }
public void Encode(Stream input, Stream output) { var buffer = new byte[0x80]; var matches = _matchParser.ParseMatches(input); foreach (var match in matches) { if (input.Position < match.Position) { // If we have unmatched data before the match, create enough uncompressed blocks HandleUncompressedData(input, output, buffer, (int)(match.Position - input.Position)); } // Write matched data as compressed block var rleValue = (byte)input.ReadByte(); HandleCompressedBlock(output, rleValue, match.Length); input.Position += match.Length - 1; } // If there is unmatched data left after last match, handle as uncompressed block if (input.Position < input.Length) { HandleUncompressedData(input, output, buffer, (int)(input.Length - input.Position)); } }
public void Encode(Stream input, Stream output) { var block = new Block(); var start = Encoding.ASCII.GetBytes("Wp16"); output.Write(start, 0, 4); output.Write(((int)input.Length).GetArrayLittleEndian(), 0, 4); var matches = _matchParser.ParseMatches(input); foreach (var match in matches) { // Compress raw data if (input.Position < match.Position) { CompressRawData(input, output, block, (int)(match.Position - input.Position)); } // Compress match CompressMatchData(input, output, block, match); } // Compress raw data if (input.Position < input.Length) { CompressRawData(input, output, block, (int)(input.Length - input.Position)); } if (block.flagPosition > 0) { WriteAndResetBuffer(output, block); } }
public void Encode(Stream input, Stream output) { var block = new Block(); var matches = _matchParser.ParseMatches(input); foreach (var match in matches) { if (input.Position < match.Position) { WriteRawData(input, output, block, match.Position - input.Position); } if (block.initialRead) { block.initialRead = false; } WriteMatchData(input, output, block, match); } if (input.Position < input.Length) { WriteRawData(input, output, block, input.Length - input.Position); } // Write ending match flag output.WriteByte(0x11); output.WriteByte(0); output.WriteByte(0); }
public void Encode(Stream input, Stream output) { _buffer = new byte[1 + 8 * 2]; _bufferLength = 1; _flagCount = 0; output.Position += 9; var matches = _matchParser.ParseMatches(input); foreach (var match in matches) { if (input.Position < match.Position - _matchParser.FindOptions.PreBufferSize) { WriteRawData(input, output, match.Position - _matchParser.FindOptions.PreBufferSize - input.Position); } WriteMatchData(input, output, match); } if (input.Position < input.Length) { WriteRawData(input, output, input.Length - input.Position); } WriteAndResetBuffer(output); WriteHeaderData(output, (int)input.Length); }
public void Encode(Stream input, Stream output) { var matches = _matchParser.ParseMatches(input).ToArray(); var compressedLength = PreCalculateCompressedLength(input.Length, matches); var block = new Block(); using (var inputReverseStream = new ReverseStream(input, input.Length)) using (var reverseOutputStream = new ReverseStream(output, compressedLength)) { foreach (var match in matches) { while (match.Position > inputReverseStream.Position) { if (block.codeBlockPosition == 0) { WriteAndResetBuffer(reverseOutputStream, block); } block.codeBlockPosition--; block.buffer[block.bufferLength++] = (byte)inputReverseStream.ReadByte(); } var byte1 = ((byte)(match.Length - 3) << 4) | (byte)((match.Displacement - 3) >> 8); var byte2 = match.Displacement - 3; if (block.codeBlockPosition == 0) { WriteAndResetBuffer(reverseOutputStream, block); } block.codeBlock |= (byte)(1 << --block.codeBlockPosition); block.buffer[block.bufferLength++] = (byte)byte1; block.buffer[block.bufferLength++] = (byte)byte2; inputReverseStream.Position += match.Length; } // Write any data after last match, to the buffer while (inputReverseStream.Position < inputReverseStream.Length) { if (block.codeBlockPosition == 0) { WriteAndResetBuffer(reverseOutputStream, block); } block.codeBlockPosition--; block.buffer[block.bufferLength++] = (byte)inputReverseStream.ReadByte(); } // Flush remaining buffer to stream WriteAndResetBuffer(reverseOutputStream, block); output.Position = compressedLength; WriteFooterInformation(input, output); } }
public void Encode(Stream input, Stream output) { var block = new Block(); var matches = _matchParser.ParseMatches(input).ToArray(); var rawValueTree = CreateRawValueTree(input, matches); block.rawValueDictionary = rawValueTree.GetHuffCodes().ToDictionary(node => node.Item1, node => node.Item2); block.countIndexes = GetCountIndexes(matches, input.Length); var countIndexValueTree = CreateIndexValueTree(block); block.countIndexDictionary = countIndexValueTree.GetHuffCodes().ToDictionary(node => node.Item1, node => node.Item2); block.dispIndexes = GetDispIndexes(matches); var dispIndexTree = CreateDisplacementIndexTree(block); block.dispIndexDictionary = dispIndexTree.GetHuffCodes().ToDictionary(node => node.Item1, node => node.Item2); using var bw = new BitWriter(output, BitOrder.LeastSignificantBitFirst, 1, ByteOrder.LittleEndian); // Without obfuscation bw.WriteByte(0x02); WriteTreeNode(bw, rawValueTree, 8); WriteTreeNode(bw, countIndexValueTree, 6); WriteTreeNode(bw, dispIndexTree, 5); var countPosition = 0; var displacementPosition = 0; foreach (var match in matches) { // Compress raw data if (input.Position < match.Position) { CompressRawData(input, bw, block, (int)(match.Position - input.Position), ref countPosition); } // Compress match CompressMatchData(input, bw, block, match, ref countPosition, ref displacementPosition); } // Compress raw data if (input.Position < input.Length) { CompressRawData(input, bw, block, (int)(input.Length - input.Position), ref countPosition); } // Write final 0 index foreach (var bit in block.countIndexDictionary[block.countIndexes.Last()]) { bw.WriteBit(bit - '0'); } }
public void Encode(Stream input, Stream output) { var bitLayoutStream = new MemoryStream(); var compressedTableStream = new MemoryStream(); var uncompressedTableStream = new MemoryStream(); using var bitLayoutWriter = new BitWriter(bitLayoutStream, BitOrder.MostSignificantBitFirst, 1, ByteOrder.BigEndian); using var bwCompressed = new BinaryWriter(compressedTableStream, Encoding.ASCII, true); using var bwUncompressed = new BinaryWriter(uncompressedTableStream, Encoding.ASCII, true); var matches = _matchParser.ParseMatches(input); foreach (var match in matches) { // Write any data before the match, to the uncompressed table while (input.Position < match.Position) { bitLayoutWriter.WriteBit(1); bwUncompressed.Write((byte)input.ReadByte()); } // Write match data to the compressed table var firstByte = (byte)((match.Displacement - 1) >> 8); var secondByte = (byte)(match.Displacement - 1); if (match.Length < 0x12) { // Since minimum _length should be 3 for Yay0, we get a minimum matchLength of 1 in this case firstByte |= (byte)((match.Length - 2) << 4); } else { // Yes, we do write the _length for a match into the uncompressed data stream, if it's >=0x12 bwUncompressed.Write((byte)(match.Length - 0x12)); } bitLayoutWriter.WriteBit(0); bwCompressed.Write(firstByte); bwCompressed.Write(secondByte); input.Position += match.Length; } // Write any data after last match, to the uncompressed table while (input.Position < input.Length) { bitLayoutWriter.WriteBit(1); bwUncompressed.Write((byte)input.ReadByte()); } bitLayoutWriter.Flush(); WriteCompressedData(input, output, bitLayoutStream, compressedTableStream, uncompressedTableStream); }
public void Encode(Stream input, Stream output) { var decompressedSize = CreateVlc((int)input.Length); var unk1 = CreateVlc(0x19); var unk2 = CreateVlc(0); output.Write(decompressedSize, 0, decompressedSize.Length); output.Write(unk1, 0, unk1.Length); output.Write(unk2, 0, unk2.Length); var matches = _matchParser.ParseMatches(input).ToArray(); WriteCompressedData(input, output, matches); }
public void Encode(Stream input, Stream output) { if (input.Length > 0xFFFFFF) { throw new InvalidOperationException("Data to compress is too long."); } var compressionHeader = new byte[] { 0x11, (byte)(input.Length & 0xFF), (byte)((input.Length >> 8) & 0xFF), (byte)((input.Length >> 16) & 0xFF) }; output.Write(compressionHeader, 0, 4); var matches = _matchParser.ParseMatches(input).ToArray(); WriteCompressedData(input, output, matches); }
public void Encode(Stream input, Stream output) { var bitLayoutStream = new MemoryStream(); var compressedTableStream = new MemoryStream(); var uncompressedTableStream = new MemoryStream(); using var bitLayoutWriter = new BitWriter(bitLayoutStream, BitOrder.MsbFirst, 1, ByteOrder.BigEndian); using var bwCompressed = new BinaryWriter(compressedTableStream, Encoding.ASCII, true); using var bwUncompressed = new BinaryWriter(uncompressedTableStream, Encoding.ASCII, true); var matches = _matchParser.ParseMatches(input); foreach (var match in matches) { // Write any data before the match, to the uncompressed table while (input.Position < match.Position) { bitLayoutWriter.WriteBit(1); bwUncompressed.Write((byte)input.ReadByte()); } // Write match data to the compressed table var firstByte = (byte)((byte)((match.Length - 3) << 4) | (byte)((match.Displacement - 1) >> 8)); var secondByte = (byte)(match.Displacement - 1); bitLayoutWriter.WriteBit(0); bwCompressed.Write(firstByte); bwCompressed.Write(secondByte); input.Position += match.Length; } // Write any data after last match, to the uncompressed table while (input.Position < input.Length) { bitLayoutWriter.WriteBit(1); bwUncompressed.Write((byte)input.ReadByte()); } bitLayoutWriter.Flush(); WriteCompressedData(input, output, bitLayoutStream, compressedTableStream, uncompressedTableStream); }
public void Encode(Stream input, Stream output) { output.Position += 0xC; var matches = _matchParser.ParseMatches(input); foreach (var match in matches) { if (input.Position < match.Position) { WriteRawData(input, output, match.Position - input.Position); } WriteMatchData(input, output, match); } if (input.Position < input.Length) { WriteRawData(input, output, input.Length - input.Position); } }
public void Encode(Stream input, Stream output) { _flagBuffer = 0; _flagPosition = 0; _buffer = new byte[32 * 2]; // at max 32 matches, one match is 2 bytes _bufferLength = 0; var start = Encoding.ASCII.GetBytes("Wp16"); output.Write(start, 0, 4); output.Write(((int)input.Length).GetArrayLittleEndian(), 0, 4); var matches = _matchParser.ParseMatches(input); foreach (var match in matches) { // Compress raw data if (input.Position < match.Position) { CompressRawData(input, output, (int)(match.Position - input.Position)); } // Compress match CompressMatchData(input, output, match); } // Compress raw data if (input.Position < input.Length) { CompressRawData(input, output, (int)(input.Length - input.Position)); } if (_flagPosition > 0) { WriteAndResetBuffer(output); } }
public void Encode(Stream input, Stream output) { var originalOutputPosition = output.Position; output.Position += 6; _codeBlock = 0; _codeBlockPosition = 0; _buffer = new byte[4 * 3]; // each buffer can be at max 4 triplets of uncompressed data; a triplet is 3 bytes _bufferLength = 0; var matches = _matchParser.ParseMatches(input); foreach (var match in matches) { // Compress raw data if (input.Position < match.Position) { CompressRawData(input, output, (int)(match.Position - input.Position)); } // Compress match CompressMatchData(input, output, match); } // Compress raw data if (input.Position < input.Length) { CompressRawData(input, output, (int)(input.Length - input.Position)); } WriteAndResetBuffer(output); // Write header information WriteHeaderData(input, output, originalOutputPosition); }
public void Encode(Stream input, Stream output) { var matches = _matchParser.ParseMatches(input); foreach (var match in matches) { // Compress raw data if (input.Position < match.Position) { CompressRawData(input, output, (int)(match.Position - input.Position)); } // Compress match CompressMatchData(input, output, match); } // Compress raw data if (input.Position < input.Length) { CompressRawData(input, output, (int)(input.Length - input.Position)); } output.Write(new byte[3], 0, 3); }
public void Encode(Stream input, Stream output) { var matches = _matchParser.ParseMatches(input).ToArray(); var compressedLength = PrecalculateCompressedLength(input.Length, matches); _codeBlock = 0; _codeBlockPosition = 8; // We write all data backwards into the buffer; starting from last element down to first // We have 8 blocks; A block can be at max 2 bytes, defining a match _buffer = new byte[8 * 2]; _bufferLength = 0; using (var inputReverseStream = new ReverseStream(input, input.Length)) using (var reverseOutputStream = new ReverseStream(output, compressedLength)) { foreach (var match in matches) { while (match.Position > inputReverseStream.Position) { if (_codeBlockPosition == 0) { WriteAndResetBuffer(reverseOutputStream); } _codeBlockPosition--; _buffer[_bufferLength++] = (byte)inputReverseStream.ReadByte(); } var byte1 = ((byte)(match.Length - 3) << 4) | (byte)((match.Displacement - 3) >> 8); var byte2 = match.Displacement - 3; if (_codeBlockPosition == 0) { WriteAndResetBuffer(reverseOutputStream); } _codeBlock |= (byte)(1 << --_codeBlockPosition); _buffer[_bufferLength++] = (byte)byte1; _buffer[_bufferLength++] = (byte)byte2; inputReverseStream.Position += match.Length; } // Write any data after last match, to the buffer while (inputReverseStream.Position < inputReverseStream.Length) { if (_codeBlockPosition == 0) { WriteAndResetBuffer(reverseOutputStream); } _codeBlockPosition--; _buffer[_bufferLength++] = (byte)inputReverseStream.ReadByte(); } // Flush remaining buffer to stream WriteAndResetBuffer(reverseOutputStream); output.Position = compressedLength; WriteFooterInformation(input, output); } }
public void Encode(Stream input, Stream output) { var matches = _matchParser.ParseMatches(input).ToArray(); WriteCompressedData(input, output, matches); }
public void Encode(Stream input, Stream output) { var originalOutputPosition = output.Position; output.Position += 0x10; _codeBlock = 0; _codeBlockPosition = 0; _buffer = new byte[8 * 2]; // each buffer can be at max 8 pairs of compressed matches; a compressed match is 2 bytes _bufferLength = 0; var matches = _matchParser.ParseMatches(input); foreach (var match in matches) { // Write any data before the match, to the uncompressed table while (input.Position < match.Position - _matchParser.FindOptions.PreBufferSize) { if (_codeBlockPosition == 8) { WriteAndResetBuffer(output); } _codeBlock |= (byte)(1 << _codeBlockPosition++); _buffer[_bufferLength++] = (byte)input.ReadByte(); } // Write match data to the buffer var bufferPosition = (match.Position - match.Displacement) % WindowBufferLength; var firstByte = (byte)bufferPosition; var secondByte = (byte)(((bufferPosition >> 2) & 0xC0) | (byte)(match.Length - 3)); if (_codeBlockPosition == 8) { WriteAndResetBuffer(output); } _codeBlockPosition++; // Since a match is flagged with a 0 bit, we don't need a bit shift and just increase the position _buffer[_bufferLength++] = firstByte; _buffer[_bufferLength++] = secondByte; input.Position += match.Length; } // Write any data after last match, to the buffer while (input.Position < input.Length) { if (_codeBlockPosition == 8) { WriteAndResetBuffer(output); } _codeBlock |= (byte)(1 << _codeBlockPosition++); _buffer[_bufferLength++] = (byte)input.ReadByte(); } // Flush remaining buffer to stream WriteAndResetBuffer(output); // Write header information WriteHeaderData(input, output, originalOutputPosition); }
public void Encode(Stream input, Stream output) { var originalOutputPosition = output.Position; output.Position += 0x10; _codeBlock = 0; _codeBlockPosition = 8; _buffer = new byte[8 * 3]; // each buffer can be at max 8 pairs of compressed matches; a compressed match can be at max 3 bytes _bufferLength = 0; var matches = _matchParser.ParseMatches(input); foreach (var match in matches) { // Write any data before the match, to the buffer while (input.Position < match.Position) { if (_codeBlockPosition == 0) { WriteAndResetBuffer(output); } _codeBlock |= (byte)(1 << --_codeBlockPosition); _buffer[_bufferLength++] = (byte)input.ReadByte(); } // Write match data to the buffer var firstByte = (byte)((match.Displacement - 1) >> 8); var secondByte = (byte)(match.Displacement - 1); if (match.Length < 0x12) { // Since minimum _length should be 3 for Yay0, we get a minimum matchLength of 1 in this case firstByte |= (byte)((match.Length - 2) << 4); } if (_codeBlockPosition == 0) { WriteAndResetBuffer(output); } _codeBlockPosition--; // Since a match is flagged with a 0 bit, we don't need a bit shift and just decrease the position _buffer[_bufferLength++] = firstByte; _buffer[_bufferLength++] = secondByte; if (match.Length >= 0x12) { _buffer[_bufferLength++] = (byte)(match.Length - 0x12); } input.Position += match.Length; } // Write any data after last match, to the buffer while (input.Position < input.Length) { if (_codeBlockPosition == 0) { WriteAndResetBuffer(output); } _codeBlock |= (byte)(1 << --_codeBlockPosition); _buffer[_bufferLength++] = (byte)input.ReadByte(); } // Flush remaining buffer to stream WriteAndResetBuffer(output); // Write header information WriteHeaderData(input, output, originalOutputPosition); }