예제 #1
0
        /// <summary>
        /// Takes in data, compresses it using LZFu. Returns the data as a byte array.
        /// </summary>
        /// <param name="data">Byte array containing data to be compressed.</param>
        /// <returns>Byte array containing the data that is compressed.</returns>
        internal byte[] Compress(byte[] data)
        {
            using (var inStream = new MemoryStream(data))
                using (var binaryReader = new BinaryReader(inStream))
                {
                    var positionData = new CompressionPositions {
                        WriteOffset = InitDictSize
                    };
                    var controlByte = 0;
                    var controlBit  = 1;
                    var tokenOffset = 0;

                    using (var outStream = new MemoryStream())
                        using (var tokenStream = new MemoryStream())
                        {
                            while (true)
                            {
                                int dictReference;
                                positionData = FindLongestMatch(_initialDictionary, binaryReader, positionData.WriteOffset);

                                if (binaryReader.PeekChar() < 0)
                                {
                                    controlByte  |= 1 << controlBit - 1;
                                    tokenOffset  += 2;
                                    dictReference = (positionData.WriteOffset & 0xFFF) << 4;
                                    var bytes = BitConverter.GetBytes((ushort)dictReference);
                                    Array.Reverse(bytes);
                                    tokenStream.Write(bytes, 0, 2);
                                    outStream.WriteByte((byte)controlByte);
                                    outStream.Write(tokenStream.ToArray(), 0, tokenOffset);
                                    break;
                                }

                                var readChar = binaryReader.ReadBytes(positionData.LongestMatchLength > 1
                            ? positionData.LongestMatchLength
                            : 1);
                                if (positionData.LongestMatchLength > 1)
                                {
                                    controlByte |= 1 << controlBit - 1;
                                    controlBit++;
                                    tokenOffset  += 2;
                                    dictReference = (positionData.DictionaryOffset & 0xFFF) << 4 |
                                                    (positionData.LongestMatchLength - 2) & 0xf;
                                    var bytes = BitConverter.GetBytes((ushort)dictReference);
                                    Array.Reverse(bytes);
                                    tokenStream.Write(bytes, 0, 2);
                                }
                                else
                                {
                                    if (positionData.LongestMatchLength == 0)
                                    {
                                        _initialDictionary[positionData.WriteOffset] = Convert.ToByte(readChar[0]);
                                        positionData.WriteOffset = (positionData.WriteOffset + 1) % MaxDictSize;
                                    }

                                    controlByte |= 0 << controlBit - 1;
                                    controlBit++;
                                    tokenOffset++;
                                    tokenStream.Write(readChar, 0, readChar.Length);
                                }

                                positionData.LongestMatchLength = 0;

                                if (controlBit > 8)
                                {
                                    outStream.WriteByte((byte)controlByte);
                                    outStream.Write(tokenStream.ToArray(), 0, tokenOffset);
                                    controlByte = 0;
                                    controlBit  = 1;
                                    tokenOffset = 0;
                                    tokenStream.SetLength(0);
                                }
                            }

                            var compSize = (uint)outStream.Length + 12;
                            var rawSize  = (uint)data.Length;
                            var crcValue = Crc32Calculator.CalculateCrc32(outStream.ToArray());

                            using (var resultStream = new MemoryStream())
                            {
                                resultStream.Write(BitConverter.GetBytes(compSize), 0, BitConverter.GetBytes(compSize).Length);
                                resultStream.Write(BitConverter.GetBytes(rawSize), 0, BitConverter.GetBytes(rawSize).Length);
                                resultStream.Write(Encoding.UTF8.GetBytes(CompType), 0,
                                                   Encoding.UTF8.GetBytes(CompType).Length);
                                resultStream.Write(BitConverter.GetBytes(crcValue), 0, BitConverter.GetBytes(crcValue).Length);
                                resultStream.Write(outStream.ToArray(), 0, outStream.ToArray().Length);
                                return(resultStream.ToArray());
                            }
                        }
                }
        }
예제 #2
0
        /// <summary>
        /// Takes in data, compresses it using LZFu. Returns the data as a byte array.
        /// </summary>
        /// <param name="data">Byte array containing data to be compressed.</param>
        /// <returns>Byte array containing the data that is compressed.</returns>
        static internal byte[] Compress(byte[] data)
        {
            var builder = new StringBuilder();

            builder.Append(@"{\rtf1\ansi\mac\deff0\deftab720{\fonttbl;}");
            builder.Append(@"{\f0\fnil \froman \fswiss \fmodern \fscript ");
            builder.Append(@"\fdecor MS Sans SerifSymbolArialTimes New RomanCourier{\colortbl\red0\green0\blue0");
            builder.Append("\r\n");
            builder.Append(@"\par \pard\plain\f0\fs20\b\i\u\tab\tx");
            InitialDictionary = Encoding.UTF8.GetBytes(builder.ToString());
            Array.Resize(ref InitialDictionary, MAX_DICT_SIZE);

            var positionData = new CompressionPositions()
            {
                WriteOffset = INIT_DICT_SIZE
            };
            var inStream     = new MemoryStream(data);
            var binaryReader = new BinaryReader(inStream);
            var controlByte  = 0;
            var controlBit   = 1;
            var tokenOffset  = 0;

            using (MemoryStream outStream = new MemoryStream())
                using (MemoryStream tokenStream = new MemoryStream())
                {
                    while (true)
                    {
                        var dictReference = 0;
                        positionData = FindLongestMatch(InitialDictionary, binaryReader, positionData.WriteOffset);
                        byte[] readChar;

                        if (binaryReader.PeekChar() < 0)
                        {
                            controlByte |= 1 << controlBit - 1;
                            controlBit++;
                            tokenOffset  += 2;
                            dictReference = (positionData.WriteOffset & 0xFFF) << 4;
                            var bytes = BitConverter.GetBytes((ushort)dictReference);
                            Array.Reverse(bytes);
                            tokenStream.Write(bytes, 0, 2);
                            outStream.WriteByte((byte)controlByte);
                            outStream.Write(tokenStream.ToArray(), 0, tokenOffset);
                            break;
                        }

                        readChar = binaryReader.ReadBytes(positionData.LongestMatchLength > 1 ? positionData.LongestMatchLength : 1);
                        if (positionData.LongestMatchLength > 1)
                        {
                            controlByte |= 1 << controlBit - 1;
                            controlBit++;
                            tokenOffset  += 2;
                            dictReference = (positionData.DictionaryOffset & 0xFFF) << 4 | (positionData.LongestMatchLength - 2) & 0xf;
                            var bytes = BitConverter.GetBytes((ushort)dictReference);
                            Array.Reverse(bytes);
                            tokenStream.Write(bytes, 0, 2);
                        }
                        else
                        {
                            if (positionData.LongestMatchLength == 0)
                            {
                                InitialDictionary[positionData.WriteOffset] = Convert.ToByte(readChar[0]);
                                positionData.WriteOffset = (positionData.WriteOffset + 1) % MAX_DICT_SIZE;
                            }
                            controlByte |= 0 << controlBit - 1;
                            controlBit++;
                            tokenOffset++;
                            tokenStream.Write(readChar, 0, readChar.Length);
                        }

                        positionData.LongestMatchLength = 0;
                        if (controlBit > 8)
                        {
                            outStream.WriteByte((byte)controlByte);
                            outStream.Write(tokenStream.ToArray(), 0, tokenOffset);
                            controlByte = 0;
                            controlBit  = 1;
                            tokenOffset = 0;
                            tokenStream.SetLength(0);
                        }
                    }

                    var compSize = (uint)outStream.Length + 12;
                    var rawSize  = (uint)data.Length;
                    var crcValue = Crc32Calculator.CalculateCrc32(outStream.ToArray());

                    using (var resultStream = new MemoryStream())
                    {
                        resultStream.Write(BitConverter.GetBytes(compSize), 0, BitConverter.GetBytes(compSize).Length);
                        resultStream.Write(BitConverter.GetBytes(rawSize), 0, BitConverter.GetBytes(rawSize).Length);
                        resultStream.Write(Encoding.UTF8.GetBytes(COMP_TYPE), 0, Encoding.UTF8.GetBytes(COMP_TYPE).Length);
                        resultStream.Write(BitConverter.GetBytes(crcValue), 0, BitConverter.GetBytes(crcValue).Length);
                        resultStream.Write(outStream.ToArray(), 0, outStream.ToArray().Length);
                        return(resultStream.ToArray());
                    }
                }
        }