예제 #1
0
        public static bool TryGetSoundData(int soundID, out byte[] data, out string name)
        {
            // Sounds.mul is exclusively locked by the legacy client, so we need to make sure this file is available
            // before attempting to play any sounds.
            if (!m_filesPrepared)
            {
                setupFiles();
            }

            data = null;
            name = null;

            if (!m_filesPrepared || soundID < 0)
            {
                return(false);
            }
            else
            {
                int  length, extra;
                bool is_patched;

                BinaryFileReader reader = m_Index.Seek(soundID, out length, out extra, out is_patched);
                int streamStart         = (int)reader.Position;
                int offset = (int)reader.Position;


                if ((offset < 0) || (length <= 0))
                {
                    if (!m_Translations.TryGetValue(soundID, out soundID))
                    {
                        return(false);
                    }


                    reader      = m_Index.Seek(soundID, out length, out extra, out is_patched);
                    streamStart = (int)reader.Position;
                    offset      = (int)reader.Position;
                }

                if ((offset < 0) || (length <= 0))
                {
                    return(false);
                }

                byte[] stringBuffer = new byte[40];
                data = new byte[length - 40];

                reader.Seek((long)(offset), SeekOrigin.Begin);
                stringBuffer = reader.ReadBytes(40);
                data         = reader.ReadBytes(length - 40);

                name = Encoding.ASCII.GetString(stringBuffer).Trim();
                int end = name.IndexOf("\0");
                name = name.Substring(0, end);
                Metrics.ReportDataRead((int)reader.Position - streamStart);

                return(true);
            }
        }
예제 #2
0
 /// <summary>
 /// Loads a DDS texture from an input stream.
 /// </summary>
 public static Texture2DInfo LoadDDSTexture(Stream inputStream, bool flipVertically = false)
 {
     using (var r = new BinaryFileReader(inputStream))
     {
         // Check the magic string.
         var magicString = r.ReadBytes(4);
         if (!"DDS ".EqualsASCIIBytes(magicString))
         {
             throw new FileFormatException($"Invalid DDS file magic string: \"{Encoding.ASCII.GetString(magicString)}\".");
         }
         // Deserialize the DDS file header.
         var header = new DDSHeader();
         header.Read(r);
         if ("DX10".EqualsASCIIBytes(header.ddspf.dwFourCC))
         {
             var header2 = new DDSHeader_DXT10();
             header2.Read(r);
         }
         // Figure out the texture format and load the texture data.
         ExtractDDSTextureFormatAndData(header, r, out var hasMipmaps, out var ddsMipmapLevelCount, out var textureFormat, out var bytesPerPixel, out var textureData);
         // Post-process the texture to generate missing mipmaps and possibly flip it vertically.
         PostProcessDDSTexture((int)header.dwWidth, (int)header.dwHeight, bytesPerPixel, hasMipmaps, (int)ddsMipmapLevelCount, textureData, flipVertically);
         return(new Texture2DInfo((int)header.dwWidth, (int)header.dwHeight, textureFormat, hasMipmaps, textureData));
     }
 }
예제 #3
0
        private static unsafe Skill LoadSkill(int index, BinaryFileReader reader)
        {
            var nameLength = _fileIndex.Index[index].Length - 2;
            var extra      = _fileIndex.Index[index].Extra;
            var set1       = new byte[1];
            var set2       = new byte[nameLength];
            var set3       = new byte[1];

            set1 = reader.ReadBytes(1);
            set2 = reader.ReadBytes(nameLength);
            set3 = reader.ReadBytes(1);
            var useBtn = ToBool(set1);
            var name   = ToString(set2);

            return(new Skill(new SkillVars(index, name, useBtn, extra, set3[0])));
        }
예제 #4
0
 internal static Bitmap LoadRawBitmap(Stream inputStream)
 {
     using (var r = new BinaryFileReader(inputStream))
     {
         var header       = r.ReadT <BitmapHeader>(0x10);
         var frameCount   = header.FrameCount;
         var frameOffsets = r.ReadTArray <BitmapFrameOffset>(frameCount * 0x08, frameCount);
         var frames       = new Texture2DInfo[frameCount];
         for (var i = 0; i < frameCount; i++)
         {
             r.Position = frameOffsets[i].Offset;
             var frame         = r.ReadT <BitmapFrame>(0x14);
             var frameHeight   = (int)frame.height;
             var sizeOfFrame   = 0x14 + frameHeight * 0x04;
             var frameDataSize = (int)(frameHeight * frame.width);
             var bitsPerPixel  = (int)((frameOffsets[i].Size - sizeOfFrame) / frameDataSize);
             var offsets       = r.ReadTArray <uint>(frameHeight * 0x04, frameHeight); // Offset to the data for each row relative to the start of the resource.
             if (offsets[0] == 0xCDCDCDCD)                                             //: unknownFrame
             {
                 continue;
             }
             r.Position = frameOffsets[i].Offset + offsets[0];
             var rawData = r.ReadBytes(frameDataSize * bitsPerPixel);
             frames[i] = bitsPerPixel == 1
                 ? new Texture2DInfo((int)frame.width, (int)frame.height, UnityEngine.TextureFormat.RGBA32, false, rawData).From8BitPallet(GetGlobal8BitPallet(), UnityEngine.TextureFormat.RGBA32)
                 : new Texture2DInfo((int)frame.width, (int)frame.height, UnityEngine.TextureFormat.RGBA32, false, rawData).FromABGR555();
         }
         return(new Bitmap
         {
             Header = header,
             Frames = frames,
         });
     }
 }
예제 #5
0
파일: LPK.cs 프로젝트: FreeReign/UltimaXNA
        public LPK(string path)
        {
            if (path == null || path == string.Empty)
                Logging.Fatal("Path to packed file system cannot be empty.");
            if (!System.IO.File.Exists(path))
                Logging.Fatal("Path to packed file system must exist");

            m_Reader = InterXLib.Serialize.OpenReader(path);
            m_Header = new LPKHeader(m_Reader);

            m_HashEntries = new LPKHashEntry[m_Header.Hashcount];
            if (m_Header.HashTableSizeCompressed != 0)
            {
                byte[] hash_table_compressed = m_Reader.ReadBytes((int)m_Header.HashTableSizeCompressed);
                byte[] hash_table = Compression.LZF.Decompress(hash_table_compressed, (int)m_Header.Hashcount * LPKHashEntry.SizeInBytes);
                using (MemoryStream mem_stream = new MemoryStream(hash_table))
                {
                    BinaryFileReader reader = new BinaryFileReader(mem_stream);
                    for (int i = 0; i < m_Header.Hashcount; i++)
                        m_HashEntries[i] = new LPKHashEntry(reader);
                }
            }
            else
            {
                for (int i = 0; i < m_Header.Hashcount; i++)
                    m_HashEntries[i] = new LPKHashEntry(m_Reader);
            }

            m_BlockEntries = new LPKBlockEntry[m_Header.BlockCount];
            if (m_Header.HashTableSizeCompressed != 0)
            {
                byte[] block_table_compressed = m_Reader.ReadBytes((int)m_Header.BlockTableSizeCompressed);
                byte[] block_table = Compression.LZF.Decompress(block_table_compressed, (int)m_Header.BlockCount * LPKBlockEntry.SizeInBytes);
                using (MemoryStream mem_stream = new MemoryStream(block_table))
                {
                    BinaryFileReader reader = new BinaryFileReader(mem_stream);
                    for (int i = 0; i < m_Header.BlockCount; i++)
                        m_BlockEntries[i] = new LPKBlockEntry(reader);
                }
            }
            else
            {
                for (int i = 0; i < m_Header.BlockCount; i++)
                    m_BlockEntries[i] = new LPKBlockEntry(m_Reader);
            }
        }
예제 #6
0
 public AI_WField(BinaryFileReader r, int dataSize)
 {
     Distance  = r.ReadInt16();
     Duration  = r.ReadInt16();
     TimeOfDay = r.ReadByte();
     Idle      = r.ReadBytes(8);
     Unknown   = r.ReadByte();
 }
예제 #7
0
        public unsafe AnimationFrame(GraphicsDevice graphics, uint[] palette, BinaryFileReader reader)
        {
            int xCenter = reader.ReadShort();
            int yCenter = reader.ReadShort();

            int width  = reader.ReadUShort();
            int height = reader.ReadUShort();

            // Fix for animations with no IO.
            if ((width == 0) || (height == 0))
            {
                m_Texture = null;
                return;
            }

            uint[] data = new uint[width * height];

            int header;

            int xBase = xCenter - 0x200;
            int yBase = (yCenter + height) - 0x200;

            fixed(uint *pData = data)
            {
                uint *dataRef = pData;
                int   delta   = width;

                int dataRead = 0;

                dataRef += xBase;
                dataRef += (yBase * delta);

                while ((header = reader.ReadInt()) != 0x7FFF7FFF)
                {
                    header ^= DoubleXor;

                    uint *cur = dataRef + ((((header >> 12) & 0x3FF) * delta) + ((header >> 22) & 0x3FF));
                    uint *end = cur + (header & 0xFFF);

                    int    filecounter = 0;
                    byte[] filedata    = reader.ReadBytes(header & 0xFFF);

                    while (cur < end)
                    {
                        *cur++ = palette[filedata[filecounter++]];
                    }

                    dataRead += header & 0xFFF;
                }

                Metrics.ReportDataRead(dataRead);
            }

            m_Center = new Microsoft.Xna.Framework.Point(xCenter, yCenter);

            m_Texture = new Texture2D(graphics, width, height);
            m_Texture.SetData <uint>(data);
        }
예제 #8
0
        private static unsafe Skill LoadSkill(int index, BinaryFileReader reader)
        {
            int nameLength = m_FileIndex.Index[index].length - 2;
            int extra      = m_FileIndex.Index[index].extra;

            byte[] set1 = new byte[1];
            byte[] set2 = new byte[nameLength];
            byte[] set3 = new byte[1];

            set1 = reader.ReadBytes(1);
            set2 = reader.ReadBytes(nameLength);
            set3 = reader.ReadBytes(1);

            bool   useBtn = SkillsData.ToBool(set1);
            string name   = SkillsData.ToString(set2);

            return(new Skill(new SkillVars(index, name, useBtn, extra, set3[0])));
        }
예제 #9
0
 internal static Texture2DInfo LoadRawTexture(Stream inputStream)
 {
     using (var r = new BinaryFileReader(inputStream))
     {
         var width         = r.ReadInt32();
         var height        = r.ReadInt32();
         var frameLength   = r.BaseStream.Length;
         var sizeOfFrame   = 20;
         var frameDataSize = height * width;
         var bitsPerPixel  = (int)((frameLength - sizeOfFrame) / frameDataSize);
         r.Position = frameLength - (width * height * bitsPerPixel);
         var rawData = r.ReadBytes(width * height * bitsPerPixel);
         return(bitsPerPixel == 1
             ? new Texture2DInfo(width, height, UnityEngine.TextureFormat.RGBA32, false, rawData).From8BitPallet(GetGlobal8BitPallet(), UnityEngine.TextureFormat.RGBA32)
             : new Texture2DInfo(width, height, UnityEngine.TextureFormat.RGBA32, false, rawData).FromABGR555());
     }
 }
예제 #10
0
 public Header(RecordGroup group, BinaryFileReader r, GameFormat format)
 {
     Group          = group;
     HeaderPosition = r.Position;
     Type           = r.ReadASCIIString(4);
     if (Type == "GRUP")
     {
         DataSize  = (uint)(r.ReadUInt32() - (format == GameFormat.TES4 ? 20 : 24));
         Label     = RecordGroup.ToLabel(Group.Depth == 0, r.ReadBytes(4));
         GroupType = (HeaderGroupType)r.ReadInt32();
         r.ReadUInt32(); // stamp | stamp + uknown
         if (format != GameFormat.TES4)
         {
             r.ReadUInt32(); // version + uknown
         }
         Position = r.Position;
         return;
     }
     DataSize = r.ReadUInt32();
     if (format == GameFormat.TES3)
     {
         r.ReadUInt32(); // unknown
     }
     Flags = (HeaderFlags)r.ReadUInt32();
     if (format == GameFormat.TES3)
     {
         Position = r.Position;
         return;
     }
     // tes4
     FormId = r.ReadUInt32();
     r.ReadUInt32();
     if (format == GameFormat.TES4)
     {
         Position = r.Position;
         return;
     }
     // tes5
     r.ReadUInt32();
     Position = r.Position;
 }
예제 #11
0
        public static byte[] GetData(int body, int action, int direction, int hue)
        {
            int       animIndex;
            FileIndex fileIndex;
            int       length, extra;
            bool      patched;

            if (body >= 0x1000)
            {
                return(null);
            }

            getIndexes(ref body, ref hue, action, direction, out animIndex, out fileIndex);
            BinaryFileReader reader = fileIndex.Seek(animIndex, out length, out extra, out patched);

            if (reader == null)
            {
                return(null);
            }

            return(reader.ReadBytes(length));
        }
예제 #12
0
        void ReadRecord(Record record, bool compressed)
        {
            //Log($"Recd: {record.Header.Type}");
            if (!compressed)
            {
                record.Read(_r, FilePath, Format);
                return;
            }
            var newDataSize = _r.ReadUInt32();
            var data        = _r.ReadBytes((int)record.Header.DataSize - 4);
            var newData     = new byte[newDataSize];

            using (var s = new MemoryStream(data))
                using (var gs = new InflaterInputStream(s))
                    gs.Read(newData, 0, newData.Length);
            // read record
            record.Header.Position = 0;
            record.Header.DataSize = newDataSize;
            using (var s = new MemoryStream(newData))
                using (var r = new BinaryFileReader(s))
                    record.Read(r, FilePath, Format);
        }
            //public int Gold;

            public NPDTField(BinaryFileReader r, int dataSize)
            {
                if (dataSize == 52)
                {
                    Level        = r.ReadInt16();
                    Strength     = r.ReadByte();
                    Intelligence = r.ReadByte();
                    Willpower    = r.ReadByte();
                    Agility      = r.ReadByte();
                    Speed        = r.ReadByte();
                    Endurance    = r.ReadByte();
                    Personality  = r.ReadByte();
                    Luck         = r.ReadByte();
                    Skills       = r.ReadBytes(27);
                    Reputation   = r.ReadByte();
                    Health       = r.ReadInt16();
                    SpellPts     = r.ReadInt16();
                    Fatigue      = r.ReadInt16();
                    Disposition  = r.ReadByte();
                    FactionId    = r.ReadByte();
                    Rank         = r.ReadByte();
                    Unknown1     = r.ReadByte();
                    Gold         = r.ReadInt32();
                }
                else
                {
                    Level       = r.ReadInt16();
                    Disposition = r.ReadByte();
                    FactionId   = r.ReadByte();
                    Rank        = r.ReadByte();
                    Unknown1    = r.ReadByte();
                    Unknown2    = r.ReadByte();
                    Unknown3    = r.ReadByte();
                    Gold        = r.ReadInt32();
                }
            }
예제 #14
0
        public unsafe AnimationFrame(int uniqueAnimationIndex, GraphicsDevice graphics, ushort[] palette, BinaryFileReader reader, SittingTransformation sitting)
        {
            m_AnimationIndex = uniqueAnimationIndex;
            int xCenter = reader.ReadShort();
            int yCenter = reader.ReadShort();
            int width   = reader.ReadUShort();
            int height  = reader.ReadUShort();

            // Fix for animations with no pixels.
            if ((width == 0) || (height == 0))
            {
                Texture = null;
                return;
            }
            if (sitting == SittingTransformation.StandSouth)
            {
                xCenter += 8;
                width   += 8;
                height  += 4;
            }
            ushort[] data = new ushort[width * height];
            // for sitting:
            // somewhere around the waist of a typical mobile animation, we take twelve rows of pixels,
            // discard every third, and shift every remaining row (total of eight) one pixel to the left
            // or right (depending on orientation), for a total skew of eight pixels.
            fixed(ushort *pData = data)
            {
                ushort *dataRef = pData;

                int dataRead = 0;

                int header;

                while ((header = reader.ReadInt()) != 0x7FFF7FFF)
                {
                    header ^= DoubleXor;
                    int x = ((header >> 22) & 0x3FF) + xCenter - 0x200;
                    int y = ((header >> 12) & 0x3FF) + yCenter + height - 0x200;
                    if (sitting == SittingTransformation.StandSouth)
                    {
                        const int skew_start = -17;
                        const int skew_end   = skew_start - 16;
                        int       iy         = y - height - yCenter;
                        if (iy > skew_start)
                        {
                            // pixels below the skew
                            x -= 8;
                            y -= 4;
                        }
                        else if (iy > skew_end)
                        {
                            // pixels within the skew
                            if ((iy - skew_end) % 4 == 0)
                            {
                                reader.Position += (header & 0xFFF);
                                continue;
                            }
                            x -= (iy - skew_end) / 2;
                            y -= (iy - skew_end) / 4;
                        }
                    }
                    ushort *cur         = dataRef + y * width + x;
                    ushort *end         = cur + (header & 0xFFF);
                    int     filecounter = 0;
                    byte[]  filedata    = reader.ReadBytes(header & 0xFFF);
                    while (cur < end)
                    {
                        *cur++ = palette[filedata[filecounter++]];
                    }
                    dataRead += header & 0xFFF;
                }
                Metrics.ReportDataRead(dataRead);
            }

            Center  = new Point(xCenter, yCenter);
            Texture = new Texture2D(graphics, width, height, false, SurfaceFormat.Bgra5551);
            Texture.SetData(data);
            m_Picking.Set(m_AnimationIndex, width, height, data);
        }
예제 #15
0
        private static Texture2D InternalReadTexture(GraphicsDevice device, BinaryFileReader reader, List<Encoder> encoders)
        {
            SurfaceFormat format = (SurfaceFormat)reader.ReadInt();
            int width = reader.ReadInt(), height = reader.ReadInt(), mip_levels = reader.ReadInt();

            Texture2D texture = new Texture2D(device, width, height, (mip_levels > 1), format);
            for (int i = 0; i < mip_levels; i++)
            {
                int data_count = reader.ReadInt();
                byte[] data = reader.ReadBytes(data_count);
                texture.SetData<byte>(data);
            }
            return texture;
        }
        /// <summary>
        /// Reads a binary STL file filtered by a provided filter.
        /// </summary>
        /// <param name="file">The mesh file.</param>
        /// <param name="filter">The provided filtered.</param>
        /// <returns>The DMTModel that obeys to the filter condition.</returns>
        public List <DMTModel> ReadFile(File file, IDMTModelFilter filter)
        {
            if (file.Exists == false)
            {
                throw new DMTFileException(DMTFileError.FileDoesNotExist);
            }

            var blocksIn  = new List <DMTTriangleBlock>();
            var blocksOut = new List <DMTTriangleBlock>();
            var blockIn   = new DMTTriangleBlock();
            var blockOut  = new DMTTriangleBlock();
            var objReader = new BinaryFileReader(file);

            try
            {
                //Read first 80 characters (bytes) and ignore them
                objReader.ReadBytes(80);

                //Read the next 4 bytes to get an unsigned integer of number of triangles
                var intNoOfFacets = objReader.ReadUInteger();

                //Now keep reading until the end of the file
                var mapPointVertexIndexBlockIn  = new Dictionary <Point, int>();
                var mapPointVertexIndexBlockOut = new Dictionary <Point, int>();
                var point1Index = -1;
                var point2Index = -1;
                var point3Index = -1;
                for (uint intCounter = 0; intCounter <= intNoOfFacets - 1; intCounter++)
                {
                    //Read 3 32bit floating point numbers - triangle normal
                    // We do not keep the normals in memory, they take too much space
                    objReader.ReadSingle();
                    objReader.ReadSingle();
                    objReader.ReadSingle();

                    //Read 3 32bit floating point numbers - vertex 1 X/Y/Z
                    var objPoint1 = new Point();
                    objPoint1.X = objReader.ReadSingle();
                    objPoint1.Y = objReader.ReadSingle();
                    objPoint1.Z = objReader.ReadSingle();

                    //Read 3 32bit floating point numbers - vertex 2 X/Y/Z
                    var objPoint2 = new Point();
                    objPoint2.X = objReader.ReadSingle();
                    objPoint2.Y = objReader.ReadSingle();
                    objPoint2.Z = objReader.ReadSingle();

                    //Read 3 32bit floating point numbers - vertex 3 X/Y/Z
                    var objPoint3 = new Point();
                    objPoint3.X = objReader.ReadSingle();
                    objPoint3.Y = objReader.ReadSingle();
                    objPoint3.Z = objReader.ReadSingle();

                    if (filter.CanAddTriangle(objPoint1, objPoint2, objPoint3))
                    {
                        AddTriangle(mapPointVertexIndexBlockIn, blockIn, objPoint1, objPoint2, objPoint3);
                    }
                    else
                    {
                        AddTriangle(mapPointVertexIndexBlockOut, blockOut, objPoint1, objPoint2, objPoint3);
                    }

                    //Read 16 bit number
                    objReader.ReadUInt16();
                }

                blockIn.DoVerticesHaveNormals  = false;
                blockOut.DoVerticesHaveNormals = false;
                blocksIn.Add(blockIn);
                blocksOut.Add(blockOut);

                var modelWithinFilter  = new DMTModel();
                var modelOutsideFilter = new DMTModel();
                modelWithinFilter.TriangleBlocks.AddRange(blocksIn);
                modelOutsideFilter.TriangleBlocks.AddRange(blocksOut);
                var result = new List <DMTModel>();
                result.Add(modelWithinFilter);
                result.Add(modelOutsideFilter);
                return(result);
            }
            finally
            {
                objReader.Close();
            }
        }
예제 #17
0
        public unsafe AnimationFrame(int uniqueAnimationIndex, object graphics, ushort[] palette, BinaryFileReader r, SittingTransformation sitting)
        {
            _animationIndex = uniqueAnimationIndex;
            int xCenter = r.ReadInt16();
            int yCenter = r.ReadInt16();
            int width   = r.ReadUInt16();
            int height  = r.ReadUInt16();

            // Fix for animations with no pixels.
            if (width == 0 || height == 0)
            {
                Texture = null;
                return;
            }
            if (sitting == SittingTransformation.StandSouth)
            {
                xCenter += 8;
                width   += 8;
                height  += 4;
            }
            var data = new byte[width * height * 4];

            // for sitting:
            // somewhere around the waist of a typical mobile animation, we take twelve rows of pixels,
            // discard every third, and shift every remaining row (total of eight) one pixel to the left
            // or right (depending on orientation), for a total skew of eight pixels.
            fixed(byte *pData = data)
            {
                ushort *dataRef  = (ushort *)pData;
                var     dataRead = 0;
                int     header;

                while ((header = r.ReadInt32()) != 0x7FFF7FFF)
                {
                    header ^= DoubleXor;
                    var x = ((header >> 22) & 0x3FF) + xCenter - 0x200;
                    var y = ((header >> 12) & 0x3FF) + yCenter + height - 0x200;
                    if (sitting == SittingTransformation.StandSouth)
                    {
                        const int skew_start = -17;
                        const int skew_end   = skew_start - 16;
                        var       iy         = y - height - yCenter;
                        if (iy > skew_start)
                        {
                            // pixels below the skew
                            x -= 8;
                            y -= 4;
                        }
                        else if (iy > skew_end)
                        {
                            // pixels within the skew
                            if ((iy - skew_end) % 4 == 0)
                            {
                                r.Position += header & 0xFFF;
                                continue;
                            }
                            x -= (iy - skew_end) / 2;
                            y -= (iy - skew_end) / 4;
                        }
                    }
                    ushort *cur         = dataRef + y * width + x;
                    ushort *end         = cur + (header & 0xFFF);
                    var     filecounter = 0;
                    var     filedata    = r.ReadBytes(header & 0xFFF);
                    while (cur < end)
                    {
                        *cur++ = palette[filedata[filecounter++]];
                    }
                    dataRead += header & 0xFFF;
                }
                Metrics.ReportDataRead(dataRead);
            }

            Center  = new Vector2Int(xCenter, yCenter);
            Texture = new Texture2DInfo(width, height, TextureFormat.BGRA32, false, data);
            _picking.Set(_animationIndex, width, height, data);
        }
예제 #18
0
 public static UNKNField ReadUNKN(this BinaryFileReader r, int length) => new UNKNField
 {
     Value = r.ReadBytes(length)
 };
예제 #19
0
 public static BYTVField ReadBYTV(this BinaryFileReader r, int length) => new BYTVField
 {
     Value = r.ReadBytes(length)
 };
예제 #20
0
        static void Test()
        {
            BinaryFileReader reader = new BinaryFileReader(@"D:\PlayGround\SOD_Data\h3ab_bmp.lod");

            reader.Skip(8);
            uint count = reader.ReadUInt32();

            Console.WriteLine("Total count: " + count);

            List <FileInfo> fileList = new List <FileInfo>();

            reader.Seek(92);
            for (int fileIndex = 0; fileIndex < count; fileIndex++)
            {
                byte[] buffer = new byte[16];
                for (int i = 0; i < 16; i++)
                {
                    buffer[i] = reader.ReadByte();
                }
                string filename = System.Text.Encoding.ASCII.GetString(buffer);

                filename = filename.Substring(0, filename.IndexOf('\0'));
                uint offset      = reader.ReadUInt32();
                uint size        = reader.ReadUInt32();
                uint placeholder = reader.ReadUInt32();
                uint csize       = reader.ReadUInt32();

                Console.WriteLine(string.Format("[{4}] filename:{0} offset:{1} size:{2} csize:{3}", filename, offset, size, csize, fileIndex));

                FileInfo info = new FileInfo();
                info.FileName = filename;
                info.Offset   = offset;
                info.Size     = size;
                info.CSize    = csize;

                fileList.Add(info);
            }

            Directory.CreateDirectory(@".\output\");

            Directory.CreateDirectory(@".\output\extracted\");

            for (int fileIndex = 0; fileIndex < count; fileIndex++)
            {
                FileInfo info = fileList[fileIndex];

                reader.Seek(info.Offset);
                byte[] content;
                string filename = @".\output\" + info.FileName;
                if (info.CSize > 0)
                {
                    filename = filename + ".zip";
                    content  = reader.ReadBytes((int)info.CSize);
                }
                else
                {
                    content = reader.ReadBytes((int)info.Size);
                }

                using (var fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
                {
                    fs.Write(content, 0, content.Length);
                }

                //// Thread.Sleep(500);
                Console.WriteLine("Finished writing file " + filename);

                if (filename.EndsWith(".h3c"))
                {
                    /*
                     * //ZipFile.ExtractToDirectory(filename, @"D:\Temp\ab.h3c");
                     * int length = 100000;
                     * byte[] data = new byte[length];
                     * for (int i = 0; i < length; i++)
                     * {
                     *  data[i] = System.Convert.ToByte(i % 100 + i % 50);
                     * }
                     *
                     * byte[] o;
                     * //serialization into memory stream
                     * IFormatter formatter = new BinaryFormatter();
                     *
                     * using (FileStream decompressedFileStream = File.Create(filename + ".origin"))
                     * {
                     *  using (FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read))
                     *  {
                     *      using (GZipStream decompressionStream = new GZipStream(file, CompressionMode.Decompress, true))
                     *      {
                     *          int dstreamlength = 0;
                     *          while(decompressionStream.ReadByte() >= 0)
                     *          {
                     *              dstreamlength++;
                     *          }
                     *
                     *          Console.WriteLine("GZip Decompressed length: " + dstreamlength);
                     *
                     *          ///DecompressFile(@".\output\extracted\", decompressionStream);
                     *          // decompressionStream.CopyTo(decompressedFileStream);///
                     *
                     *          Console.WriteLine("Decompressed: {0}", filename);
                     *      }
                     *
                     *
                     *      file.Seek(0, SeekOrigin.Begin);
                     *      var oo = formatter.Deserialize(decompressedFileStream);
                     *      o = (byte[])oo;
                     *
                     *  }
                     * }
                     */
                }

                if (info.CSize > 0)
                {
                    ////ZipFile.ExtractToDirectory(filename, @"D:\Temp");
                    //// ZipFile.ExtractToDirectory(filename, filename.Substring(0, 5));



                    using (FileStream decompressedFileStream = File.Create(filename + ".origin"))
                    {
                        using (FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read))
                        {
                            using (DeflateStream decompressionStream = new DeflateStream(file, CompressionMode.Decompress, true))
                            {
                                decompressionStream.CopyTo(decompressedFileStream);
                                Console.WriteLine("Decompressed: {0}", filename);
                            }

                            /*
                             * using (GZipStream decompressionStream = new GZipStream(file, CompressionMode.Decompress, false))
                             * {
                             *  decompressionStream.CopyTo(decompressedFileStream);
                             *  Console.WriteLine("Decompressed: {0}", filename);
                             * }
                             */
                        }
                    }
                }
            }
        }