FSO.Files.FAR3.Decompresser.Decompress C# (CSharp) Method

Decompress() public method

Decompresses data and returns it as an uncompressed array of bytes.
public Decompress ( byte Data ) : byte[]
Data byte The data to decompress.
return byte[]
        public byte[] Decompress(byte[] Data)
        {
            MemoryStream MemData = new MemoryStream(Data);
            BinaryReader Reader = new BinaryReader(MemData);

            if (Data.Length > 6)
            {
                byte[] DecompressedData = new byte[(int)m_DecompressedSize];
                int DataPos = 0;

                int Pos = 0;
                long Control1 = 0;

                while (Control1 != 0xFC && Pos < Data.Length)
                {
                    Control1 = Data[Pos];
                    Pos++;

                    if (Pos == Data.Length)
                        break;

                    if (Control1 >= 0 && Control1 <= 127)
                    {
                        // 0x00 - 0x7F
                        long control2 = Data[Pos];
                        Pos++;
                        long numberOfPlainText = (Control1 & 0x03);
                        ArrayCopy2(Data, Pos, ref DecompressedData, DataPos, numberOfPlainText);
                        DataPos += (int)numberOfPlainText;
                        Pos += (int)numberOfPlainText;

                        if (DataPos == (DecompressedData.Length))
                            break;

                        int offset = (int)(((Control1 & 0x60) << 3) + (control2) + 1);
                        long numberToCopyFromOffset = ((Control1 & 0x1C) >> 2) + 3;
                        OffsetCopy(ref DecompressedData, offset, DataPos, numberToCopyFromOffset);
                        DataPos += (int)numberToCopyFromOffset;

                        if (DataPos == (DecompressedData.Length))
                            break;
                    }
                    else if ((Control1 >= 128 && Control1 <= 191))
                    {
                        // 0x80 - 0xBF
                        long control2 = Data[Pos];
                        Pos++;
                        long control3 = Data[Pos];
                        Pos++;

                        long numberOfPlainText = (control2 >> 6) & 0x03;
                        ArrayCopy2(Data, Pos, ref DecompressedData, DataPos, numberOfPlainText);
                        DataPos += (int)numberOfPlainText;
                        Pos += (int)numberOfPlainText;

                        if (DataPos == (DecompressedData.Length))
                            break;

                        int offset = (int)(((control2 & 0x3F) << 8) + (control3) + 1);
                        long numberToCopyFromOffset = (Control1 & 0x3F) + 4;
                        OffsetCopy(ref DecompressedData, offset, DataPos, numberToCopyFromOffset);
                        DataPos += (int)numberToCopyFromOffset;

                        if (DataPos == (DecompressedData.Length))
                            break;
                    }
                    else if (Control1 >= 192 && Control1 <= 223)
                    {
                        // 0xC0 - 0xDF
                        long numberOfPlainText = (Control1 & 0x03);
                        long control2 = Data[Pos];
                        Pos++;
                        long control3 = Data[Pos];
                        Pos++;
                        long control4 = Data[Pos];
                        Pos++;
                        ArrayCopy2(Data, Pos, ref DecompressedData, DataPos, numberOfPlainText);
                        DataPos += (int)numberOfPlainText;
                        Pos += (int)numberOfPlainText;

                        if (DataPos == (DecompressedData.Length))
                            break;

                        int offset = (int)(((Control1 & 0x10) << 12) + (control2 << 8) + (control3) + 1);
                        long numberToCopyFromOffset = ((Control1 & 0x0C) << 6) + (control4) + 5;
                        OffsetCopy(ref DecompressedData, offset, DataPos, numberToCopyFromOffset);
                        DataPos += (int)numberToCopyFromOffset;

                        if (DataPos == (DecompressedData.Length))
                            break;
                    }
                    else if (Control1 >= 224 && Control1 <= 251)
                    {
                        // 0xE0 - 0xFB
                        long numberOfPlainText = ((Control1 & 0x1F) << 2) + 4;
                        ArrayCopy2(Data, Pos, ref DecompressedData, DataPos, numberOfPlainText);
                        DataPos += (int)numberOfPlainText;
                        Pos += (int)numberOfPlainText;

                        if (DataPos == (DecompressedData.Length))
                            break;
                    }
                    else
                    {
                        long numberOfPlainText = (Control1 & 0x03);
                        ArrayCopy2(Data, Pos, ref DecompressedData, DataPos, numberOfPlainText);

                        DataPos += (int)numberOfPlainText;
                        Pos += (int)numberOfPlainText;

                        if (DataPos == (DecompressedData.Length))
                            break;
                    }
                }

                return DecompressedData;
            }

            //No data to decompress
            return Data;
        }

Usage Example

Ejemplo n.º 1
0
        /// <summary>
        /// Gets an entry's data from a Far3Entry instance.
        /// </summary>
        /// <param name="Entry">The Far3Entry instance.</param>
        /// <returns>The entry's data.</returns>
        public byte[] GetEntry(Far3Entry Entry)
        {
            lock (m_Reader)
            {
                m_Reader.BaseStream.Seek((long)Entry.DataOffset, SeekOrigin.Begin);

                isReadingSomething = true;

                if (Entry.IsCompressed == 0x01)
                {
                    m_Reader.ReadBytes(9);
                    uint   Filesize      = m_Reader.ReadUInt32();
                    ushort CompressionID = m_Reader.ReadUInt16();

                    if (CompressionID == 0xFB10)
                    {
                        byte[] Dummy            = m_Reader.ReadBytes(3);
                        uint   DecompressedSize = (uint)((Dummy[0] << 0x10) | (Dummy[1] << 0x08) | +Dummy[2]);

                        Decompresser Dec = new Decompresser();
                        Dec.CompressedSize   = Filesize;
                        Dec.DecompressedSize = DecompressedSize;

                        byte[] DecompressedData = Dec.Decompress(m_Reader.ReadBytes((int)Filesize));
                        //m_Reader.Close();

                        isReadingSomething = false;

                        return(DecompressedData);
                    }
                    else
                    {
                        m_Reader.BaseStream.Seek((m_Reader.BaseStream.Position - 15), SeekOrigin.Begin);

                        byte[] Data = m_Reader.ReadBytes((int)Entry.DecompressedFileSize);
                        //m_Reader.Close();

                        isReadingSomething = false;

                        return(Data);
                    }
                }
                else
                {
                    byte[] Data = m_Reader.ReadBytes((int)Entry.DecompressedFileSize);
                    //m_Reader.Close();

                    isReadingSomething = false;

                    return(Data);
                }
            }

            throw new FAR3Exception("FAR3Entry didn't exist in archive - FAR3Archive.GetEntry()");
        }
All Usage Examples Of FSO.Files.FAR3.Decompresser::Decompress