Ejemplo n.º 1
0
            internal byte [] Decompress(byte [] DataToDecompress, bool VerifyCheckSum)
            {
                MD5CryptoServiceProvider md5CryptoServiceProvider_HashOfDecompressedData = null;

                BitArray bitArray_CompressedData = null;

                MemoryStream memoryStream_DecompressedData = new MemoryStream(),
                             memoryStream_CompressedData   = new MemoryStream(DataToDecompress);

                PrefixCodes_obj = new PrefixCodes(false);

                UInt64 uInt64_TotalDecompressedSize = 0;

                int int_CurrentPositionInBitArray = 0, int_CurrentLiteralPosition = 0,
                    int_RLEBytesCount = 0, int_SizeOfLiteralsBlock = 0, int_SizeOfMetaDataBlock = 0;

                byte [] byteArray_StoredLiteralsBlock = null, byteArray_MetaData = null,
                byteArray_LiteralsBlock    = null, byteArray_StoredHashOfDecompressedData = new byte[16],
                byteArray_DecompressedData = null, byteArray_ComputedHashOfDecompressedData = new byte[16];

                byte byte_UnusedBitsCount = 0, byte_StoredLiteral = 0,
                     byte_LiteralsFormat = 0, byte_IsCheckSumExist = 0;

                /*
                 *  8 bytes for Total Decompressed Size (UInt64)
                 *  1 byte - Hash Flag
                 *	16 bytes of Decompressed Data MD5 Hash
                 *  4 bytes for Literals Block Length (int)
                 *  X bytes Literals Block
                 *  4 bytes for Meta Data Block Length (int)
                 *  X bytes Meta Data Block	(UnUseds bits count and then Meta Data)
                 */

                uInt64_TotalDecompressedSize = BitConverter.ToUInt64(memoryStream_CompressedData.ToArray(), 0);

                memoryStream_CompressedData.Position += 8;

                byte_IsCheckSumExist = (byte)memoryStream_CompressedData.ReadByte();

                if (byte_IsCheckSumExist == 1)
                {
                    memoryStream_CompressedData.Read(byteArray_StoredHashOfDecompressedData, 0, byteArray_StoredHashOfDecompressedData.Length);
                }

                byte_LiteralsFormat = (byte)memoryStream_CompressedData.ReadByte();


                int_SizeOfLiteralsBlock = BitConverter.ToInt32(memoryStream_CompressedData.ToArray(), (int)memoryStream_CompressedData.Position);
                memoryStream_CompressedData.Position += 4;

                byteArray_StoredLiteralsBlock = new byte[int_SizeOfLiteralsBlock];

                memoryStream_CompressedData.Read(byteArray_StoredLiteralsBlock, 0, byteArray_StoredLiteralsBlock.Length);

                int_SizeOfMetaDataBlock = BitConverter.ToInt32(memoryStream_CompressedData.ToArray(), (int)memoryStream_CompressedData.Position);
                memoryStream_CompressedData.Position += 4;

                byteArray_MetaData = new byte[int_SizeOfMetaDataBlock];

                memoryStream_CompressedData.Read(byteArray_MetaData, 0, byteArray_MetaData.Length);

                bitArray_CompressedData = new BitArray(byteArray_MetaData);

                byte_UnusedBitsCount = (byte)byteArray_MetaData[0];


                switch (byte_LiteralsFormat)
                {
                case 0:
                    byteArray_LiteralsBlock = byteArray_StoredLiteralsBlock;
                    break;

                case 1:
                    byteArray_LiteralsBlock = PrefixCodes_obj.DecompressUsingNonAdaptivePrefixCodesMethod(byteArray_StoredLiteralsBlock);
                    break;

                case 2:
                    byteArray_LiteralsBlock = PrefixCodes_obj.DecompressUsingAdaptivePrefixCodesMethod(byteArray_StoredLiteralsBlock);
                    break;
                }

                for (int_CurrentPositionInBitArray = 8, int_CurrentLiteralPosition = 0;
                     int_CurrentPositionInBitArray < bitArray_CompressedData.Length - byte_UnusedBitsCount;
                     )
                {
                    byte_StoredLiteral = byteArray_LiteralsBlock[int_CurrentLiteralPosition++];

                    if (bitArray_CompressedData[int_CurrentPositionInBitArray++] == true)
                    {
                        PrefixCodesSupportForDistancesAndRLE.ConvertPrefixCodesCodeToDecimal(ref bitArray_CompressedData, int_CurrentPositionInBitArray);

                        int_RLEBytesCount             = PrefixCodesSupportForDistancesAndRLE.DecodedPrefixCodesCode[0];
                        int_CurrentPositionInBitArray = PrefixCodesSupportForDistancesAndRLE.DecodedPrefixCodesCode[1];

                        int_RLEBytesCount += 2;

                        for (int int_CycleCount = 0; int_CycleCount != int_RLEBytesCount; int_CycleCount++)
                        {
                            memoryStream_DecompressedData.WriteByte(byte_StoredLiteral);
                        }

                        continue;
                    }

                    else
                    {
                        memoryStream_DecompressedData.WriteByte(byte_StoredLiteral);
                    }
                }

                byteArray_DecompressedData = memoryStream_DecompressedData.ToArray();

                #region Verification for right hash

                md5CryptoServiceProvider_HashOfDecompressedData = new MD5CryptoServiceProvider();

                byteArray_ComputedHashOfDecompressedData = md5CryptoServiceProvider_HashOfDecompressedData.ComputeHash(byteArray_DecompressedData, 0, byteArray_DecompressedData.Length);

                #endregion

                if (uInt64_TotalDecompressedSize != (ulong)byteArray_DecompressedData.LongLength)
                {
                    throw new CommonEnvironment.WrongDecompressedSizeException();
                }

                if (byte_IsCheckSumExist == 1 && VerifyCheckSum == true)
                {
                    md5CryptoServiceProvider_HashOfDecompressedData = new MD5CryptoServiceProvider();

                    byteArray_ComputedHashOfDecompressedData = md5CryptoServiceProvider_HashOfDecompressedData.ComputeHash(memoryStream_DecompressedData.ToArray(), 0, (int)memoryStream_DecompressedData.Position);

                    if (commonEnvironment_obj.IsBytesArraysEquals(ref byteArray_ComputedHashOfDecompressedData, ref byteArray_StoredHashOfDecompressedData) == false)
                    {
                        throw new CommonEnvironment.WrongDecompressedDataHashException();
                    }
                }

                return(byteArray_DecompressedData);
            }
Ejemplo n.º 2
0
            /// <summary>
            /// Compress input byte array using RLE algorithm.
            /// </summary>
            ///
            /// <returns>
            /// An Compressed array of bytes with length > 0.
            /// </returns>
            ///
            /// <param name="DataToCompress">
            /// The input data to compress using RLE algorithm.
            /// </param>/
            ///
            /// <param name="AddCheckSum">
            /// Indicating whether add to compressed data MD5 Hash check sum.
            /// </param>
            ///
            /// <example> This sample shows how to compress byte array.
            /// <code>
            /// //Initializes a new instance of the RLE class with a compression parameter:
            /// //PrefixCodesCompression enum value that indicate use PrefixCode to compress
            /// //single uncompressed bytes or store bytes uncompressed
            /// YakSys.Compression.ICompression compressionObj =
            /// new YakSys.Compression.RLE(PrefixCodesCompression.NonAdaptive);
            ///
            /// FileStream fileStream_DataFile = File.Open("test.dat");
            ///
            /// byte [] byteArray_DataToCompress = new byte[fileStream_DataFile.Length],
            /// byte [] byteArray_CompressedData = null;
            ///
            /// fileStream_DataFile.Read(byteArray_DataToCompress, 0, byteArray_DataToCompress.Length);
            ///
            /// //Compress the data with adding MD5 hash check sum
            /// byteArray_CompressedData = compressionObj.Compress(byteArray_DataToCompress, true);
            ///
            /// fileStream_DataFile.Close();
            ///
            /// </code>
            /// </example>
            ///
            public byte [] Compress(byte [] DataToCompress, bool AddCheckSum)
            {
                if (DataToCompress == null)
                {
                    throw new CommonEnvironment.CompressedDataArrayIsNullReferenceException();
                }
                if (DataToCompress.Length == 0)
                {
                    throw new CommonEnvironment.CompressedDataHasZeroLengthException();
                }

                BitArray bitArray_CurrentPrefixCodesCode = null;

                MemoryStream memoryStream_SavedLiterals  = new MemoryStream(),
                             memoryStream_MetaData       = new MemoryStream(),
                             memoryStream_CompressedData = new MemoryStream();

                PrefixCodes_obj = new PrefixCodes(false);

                byte [] byteArray_HashOfDecompressedData = null, byteArray_CompressedData = null,
                byteArray_CompressedLiterals = null, byteArray_CompressedBlock = null;

                memoryStream_MetaData.Position = 1;

                int int_CurrentPositionInBitArray = 0;

                for (int int_CurrentPositionInData = 0; int_CurrentPositionInData < DataToCompress.Length;)
                {
                    CalculateRLEBytesCount(ref DataToCompress, int_CurrentPositionInData);

                    memoryStream_SavedLiterals.WriteByte(DataToCompress[int_CurrentPositionInData++]);

                    if (bitArray_MetaData.Length <= int_CurrentPositionInBitArray + 1000)
                    {
                        bitArray_MetaData.Length += 100000;
                    }

                    if (int_RLEBytesFounded >= 2)
                    {
                        int_CurrentPositionInData += int_RLEBytesFounded - 1;

                        bitArray_MetaData[int_CurrentPositionInBitArray++] = true;

                        bitArray_CurrentPrefixCodesCode = (BitArray)PrefixCodesSupportForDistancesAndRLE.arrayList_MapOfPrefixCodes[int_RLEBytesFounded - 2];

                        foreach (bool bool_CurrentPrefixCodesBit in bitArray_CurrentPrefixCodesCode)
                        {
                            bitArray_MetaData[int_CurrentPositionInBitArray++] = bool_CurrentPrefixCodesBit;
                        }

                        if (int_CurrentPositionInBitArray % 8 == 0)
                        {
                            bitArray_MetaData.Length = int_CurrentPositionInBitArray;

                            byteArray_CompressedBlock = new byte[int_CurrentPositionInBitArray / 8];

                            bitArray_MetaData.CopyTo(byteArray_CompressedBlock, 0);

                            memoryStream_MetaData.Write(byteArray_CompressedBlock, 0, byteArray_CompressedBlock.Length);

                            bitArray_MetaData = new BitArray(10000);

                            int_CurrentPositionInBitArray = 0;
                        }

                        continue;
                    }

                    bitArray_MetaData[int_CurrentPositionInBitArray++] = false;
                }

                /*
                 *  first 45 bytes Empty for System Data Information
                 *  8 bytes for Total Decompressed Size (UInt64)
                 *	1 byte to Hash Flag + 16 bytes of Decompressed Data MD5 Hash
                 *  4 bytes for Literals Block Length (int)
                 *  X bytes Literals Block
                 *  4 bytes for Meta Data Block Length (int)
                 *  X bytes Meta Data Block	(UnUseds bits count and then Meta Data)
                 */

                memoryStream_CompressedData.Position = 45;

                #region Total Decompressed Size

                memoryStream_CompressedData.Write(BitConverter.GetBytes((UInt64)DataToCompress.Length), 0, 8);

                #endregion

                #region Hash Of Decompressed Data

                if (AddCheckSum)
                {
                    MD5CryptoServiceProvider md5CryptoServiceProvider_HashOfDecompressedData = null;

                    md5CryptoServiceProvider_HashOfDecompressedData = new MD5CryptoServiceProvider();

                    byteArray_HashOfDecompressedData = md5CryptoServiceProvider_HashOfDecompressedData.ComputeHash(DataToCompress, 0, DataToCompress.Length);

                    memoryStream_CompressedData.WriteByte(1);

                    memoryStream_CompressedData.Write(byteArray_HashOfDecompressedData, 0, byteArray_HashOfDecompressedData.Length);
                }
                else
                {
                    memoryStream_CompressedData.WriteByte(0);
                }

                #endregion

                #region Post processing and Writing saved literals into Compressed memory Stream

                int int_StaticPrefixCodesCompressedLiteralsSize = PrefixCodes_obj.DataAnalyzer(memoryStream_SavedLiterals.ToArray(), false);

                if (PrefixCodes_Settings == PrefixCodesCompression.DoNotUse || int_StaticPrefixCodesCompressedLiteralsSize >= memoryStream_SavedLiterals.ToArray().Length)
                {
                    memoryStream_CompressedData.WriteByte(0);                     // 0 is uncompressed

                    memoryStream_CompressedData.Write(BitConverter.GetBytes(memoryStream_SavedLiterals.ToArray().Length), 0, 4);

                    memoryStream_CompressedData.Write(memoryStream_SavedLiterals.ToArray(), 0, memoryStream_SavedLiterals.ToArray().Length);
                }
                else
                {
                    if (PrefixCodes_Settings == PrefixCodesCompression.NonAdaptive)
                    {
                        memoryStream_CompressedData.WriteByte(1);                         // 1 is PrefixCodes Non Adaptive
                        PrefixCodes_obj.DataAnalyzer(memoryStream_SavedLiterals.ToArray(), false);
                        byteArray_CompressedLiterals = PrefixCodes_obj.CompressUsingNonAdaptivePrefixCodesMethod(memoryStream_SavedLiterals.ToArray());
                    }
                    if (PrefixCodes_Settings == PrefixCodesCompression.Adaptive)
                    {
                        memoryStream_CompressedData.WriteByte(2);                         // 2 is PrefixCodes Adaptive
                        PrefixCodes_obj.DataAnalyzer(memoryStream_SavedLiterals.ToArray(), true);
                        byteArray_CompressedLiterals = PrefixCodes_obj.CompressUsingAdaptivePrefixCodesMethod(memoryStream_SavedLiterals.ToArray());
                    }

                    memoryStream_CompressedData.Write(BitConverter.GetBytes(byteArray_CompressedLiterals.Length), 0, 4);

                    memoryStream_CompressedData.Write(byteArray_CompressedLiterals, 0, byteArray_CompressedLiterals.Length);
                }

                #endregion

                #region Write unuseds bits count

                bitArray_MetaData.Length = int_CurrentPositionInBitArray;

                new CommonEnvironment().AddUnusedsBitsCountInfo(bitArray_MetaData, memoryStream_MetaData);

                #endregion

                #region Write Meta Data and Meta Data Size

                memoryStream_CompressedData.Write(BitConverter.GetBytes((int)memoryStream_MetaData.ToArray().Length), 0, 4);

                memoryStream_CompressedData.Write(memoryStream_MetaData.ToArray(), 0, memoryStream_MetaData.ToArray().Length);

                #endregion

                byteArray_CompressedData = memoryStream_CompressedData.ToArray();

                memoryStream_CompressedData.Close();
                memoryStream_SavedLiterals.Close();
                memoryStream_MetaData.Close();

                commonEnvironment_obj.AddSystemInformation(ref byteArray_CompressedData, 2);

                return(byteArray_CompressedData);
            }